]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/openswan-2.4.9.kernel-2.6-klips.patch
Applied "check on BER decoding" security fix
[people/pmueller/ipfire-2.x.git] / src / patches / openswan-2.4.9.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/crypto/ciphers/aes/test_main.c Mon Feb 9 13:51:03 2004
119 @@ -0,0 +1,41 @@
120 +#include <stdio.h>
121 +#include <string.h>
122 +#include <sys/types.h>
123 +#include "aes_cbc.h"
124 +#define AES_BLOCK_SIZE 16
125 +#define KEY_SIZE 128 /* bits */
126 +#define KEY "1234567890123456"
127 +#define STR "hola guaso como estaisss ... 012"
128 +#define STRSZ (sizeof(STR)-1)
129 +
130 +#define EMT_AESCBC_BLKLEN AES_BLOCK_SIZE
131 +#define AES_CONTEXT_T aes_context
132 +#define EMT_ESPAES_KEY_SZ 16
133 +int pretty_print(const unsigned char *buf, int count) {
134 + int i=0;
135 + for (;i<count;i++) {
136 + if (i%8==0) putchar(' ');
137 + if (i%16==0) putchar('\n');
138 + printf ("%02hhx ", buf[i]);
139 + }
140 + putchar('\n');
141 + return i;
142 +}
143 +//#define SIZE STRSZ/2
144 +#define SIZE STRSZ
145 +int main() {
146 + int ret;
147 + char buf0[SIZE+1], buf1[SIZE+1];
148 + char IV[AES_BLOCK_SIZE]="\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0";
149 + aes_context ac;
150 + AES_set_key(&ac, KEY, KEY_SIZE);
151 + //pretty_print((char *)&ac.aes_e_key, sizeof(ac.aes_e_key));
152 + memset(buf0, 0, sizeof (buf0));
153 + memset(buf1, 0, sizeof (buf1));
154 + ret=AES_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1);
155 + pretty_print(buf0, SIZE);
156 + printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0);
157 + ret=AES_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0);
158 + printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1);
159 + return 0;
160 +}
161 --- /dev/null Tue Mar 11 13:02:56 2003
162 +++ linux/crypto/ciphers/aes/test_main_mac.c Mon Feb 9 13:51:03 2004
163 @@ -0,0 +1,30 @@
164 +#include <stdio.h>
165 +#include <sys/types.h>
166 +#include <string.h>
167 +#include "aes.h"
168 +#include "aes_xcbc_mac.h"
169 +#define STR "Hola guasssso c|mo estais ...012"
170 +void print_hash(const __u8 *hash) {
171 + printf("%08x %08x %08x %08x\n",
172 + *(__u32*)(&hash[0]),
173 + *(__u32*)(&hash[4]),
174 + *(__u32*)(&hash[8]),
175 + *(__u32*)(&hash[12]));
176 +}
177 +int main(int argc, char *argv[]) {
178 + aes_block key= { 0xdeadbeef, 0xceedcaca, 0xcafebabe, 0xff010204 };
179 + __u8 hash[16];
180 + char *str = argv[1];
181 + aes_context_mac ctx;
182 + if (str==NULL) {
183 + fprintf(stderr, "pasame el str\n");
184 + return 255;
185 + }
186 + AES_xcbc_mac_set_key(&ctx, (__u8 *)&key, sizeof(key));
187 + AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
188 + print_hash(hash);
189 + str[2]='x';
190 + AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
191 + print_hash(hash);
192 + return 0;
193 +}
194 --- /dev/null Tue Mar 11 13:02:56 2003
195 +++ linux/include/crypto/aes.h Mon Feb 9 13:51:03 2004
196 @@ -0,0 +1,97 @@
197 +// I retain copyright in this code but I encourage its free use provided
198 +// that I don't carry any responsibility for the results. I am especially
199 +// happy to see it used in free and open source software. If you do use
200 +// it I would appreciate an acknowledgement of its origin in the code or
201 +// the product that results and I would also appreciate knowing a little
202 +// about the use to which it is being put. I am grateful to Frank Yellin
203 +// for some ideas that are used in this implementation.
204 +//
205 +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
206 +//
207 +// This is an implementation of the AES encryption algorithm (Rijndael)
208 +// designed by Joan Daemen and Vincent Rijmen. This version is designed
209 +// to provide both fixed and dynamic block and key lengths and can also
210 +// run with either big or little endian internal byte order (see aes.h).
211 +// It inputs block and key lengths in bytes with the legal values being
212 +// 16, 24 and 32.
213 +
214 +/*
215 + * Modified by Jari Ruusu, May 1 2001
216 + * - Fixed some compile warnings, code was ok but gcc warned anyway.
217 + * - Changed basic types: byte -> unsigned char, word -> u_int32_t
218 + * - Major name space cleanup: Names visible to outside now begin
219 + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
220 + * - Removed C++ and DLL support as part of name space cleanup.
221 + * - Eliminated unnecessary recomputation of tables. (actual bug fix)
222 + * - Merged precomputed constant tables to aes.c file.
223 + * - Removed data alignment restrictions for portability reasons.
224 + * - Made block and key lengths accept bit count (128/192/256)
225 + * as well byte count (16/24/32).
226 + * - Removed all error checks. This change also eliminated the need
227 + * to preinitialize the context struct to zero.
228 + * - Removed some totally unused constants.
229 + */
230 +
231 +#ifndef _AES_H
232 +#define _AES_H
233 +
234 +#if defined(__linux__) && defined(__KERNEL__)
235 +# include <linux/types.h>
236 +#else
237 +# include <sys/types.h>
238 +#endif
239 +
240 +// CONFIGURATION OPTIONS (see also aes.c)
241 +//
242 +// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
243 +// leave this undefined for dynamically variable block size (this will
244 +// result in much slower code).
245 +// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
246 +// left undefined a slower version providing variable block length is compiled
247 +
248 +#define AES_BLOCK_SIZE 16
249 +
250 +// The number of key schedule words for different block and key lengths
251 +// allowing for method of computation which requires the length to be a
252 +// multiple of the key length
253 +//
254 +// Nk = 4 6 8
255 +// -------------
256 +// Nb = 4 | 60 60 64
257 +// 6 | 96 90 96
258 +// 8 | 120 120 120
259 +
260 +#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
261 +#define AES_KS_LENGTH 120
262 +#define AES_RC_LENGTH 29
263 +#else
264 +#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
265 +#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
266 +#endif
267 +
268 +typedef struct
269 +{
270 + u_int32_t aes_Nkey; // the number of words in the key input block
271 + u_int32_t aes_Nrnd; // the number of cipher rounds
272 + u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
273 + u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
274 +#if !defined(AES_BLOCK_SIZE)
275 + u_int32_t aes_Ncol; // the number of columns in the cipher state
276 +#endif
277 +} aes_context;
278 +
279 +// THE CIPHER INTERFACE
280 +
281 +#if !defined(AES_BLOCK_SIZE)
282 +extern void aes_set_blk(aes_context *, const int);
283 +#endif
284 +extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
285 +extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
286 +extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
287 +
288 +// The block length inputs to aes_set_block and aes_set_key are in numbers
289 +// of bytes or bits. The calls to subroutines must be made in the above
290 +// order but multiple calls can be made without repeating earlier calls
291 +// if their parameters have not changed.
292 +
293 +#endif // _AES_H
294 --- /dev/null Tue Mar 11 13:02:56 2003
295 +++ linux/include/crypto/aes_cbc.h Mon Feb 9 13:51:03 2004
296 @@ -0,0 +1,4 @@
297 +/* Glue header */
298 +#include "aes.h"
299 +int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
300 +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);
301 --- /dev/null Tue Mar 11 13:02:56 2003
302 +++ linux/include/crypto/aes_xcbc_mac.h Mon Feb 9 13:51:03 2004
303 @@ -0,0 +1,12 @@
304 +#ifndef _AES_XCBC_MAC_H
305 +#define _AES_XCBC_MAC_H
306 +
307 +typedef u_int32_t aes_block[4];
308 +typedef struct {
309 + aes_context ctx_k1;
310 + aes_block k2;
311 + aes_block k3;
312 +} aes_context_mac;
313 +int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen);
314 +int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]);
315 +#endif /* _AES_XCBC_MAC_H */
316 --- /dev/null Tue Mar 11 13:02:56 2003
317 +++ linux/include/crypto/cbc_generic.h Mon Feb 9 13:51:03 2004
318 @@ -0,0 +1,110 @@
319 +#ifndef _CBC_GENERIC_H
320 +#define _CBC_GENERIC_H
321 +/*
322 + * CBC macro helpers
323 + *
324 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
325 + *
326 + * This program is free software; you can redistribute it and/or modify it
327 + * under the terms of the GNU General Public License as published by the
328 + * Free Software Foundation; either version 2 of the License, or (at your
329 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
330 + *
331 + * This program is distributed in the hope that it will be useful, but
332 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
333 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
334 + * for more details.
335 + *
336 + */
337 +
338 +/*
339 + * Heavily inspired in loop_AES
340 + */
341 +#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \
342 +int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
343 + int ret=ilen, pos; \
344 + const u_int32_t *iv_i; \
345 + if ((ilen) % 16) return 0; \
346 + if (encrypt) { \
347 + pos=0; \
348 + while(pos<ilen) { \
349 + if (pos==0) \
350 + iv_i=(const u_int32_t*) iv; \
351 + else \
352 + iv_i=(const u_int32_t*) (out-16); \
353 + *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
354 + *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
355 + *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \
356 + *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \
357 + enc_func(ctx, (addr_type) out, (addr_type) out); \
358 + in+=16; \
359 + out+=16; \
360 + pos+=16; \
361 + } \
362 + } else { \
363 + pos=ilen-16; \
364 + in+=pos; \
365 + out+=pos; \
366 + while(pos>=0) { \
367 + dec_func(ctx, (const addr_type) in, (addr_type) out); \
368 + if (pos==0) \
369 + iv_i=(const u_int32_t*) (iv); \
370 + else \
371 + iv_i=(const u_int32_t*) (in-16); \
372 + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
373 + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
374 + *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \
375 + *((u_int32_t *)(&out[12])) ^= iv_i[3]; \
376 + in-=16; \
377 + out-=16; \
378 + pos-=16; \
379 + } \
380 + } \
381 + return ret; \
382 +}
383 +#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \
384 +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
385 + int ret=ilen, pos; \
386 + const u_int32_t *iv_i; \
387 + if ((ilen) % 8) return 0; \
388 + if (encrypt) { \
389 + pos=0; \
390 + while(pos<ilen) { \
391 + if (pos==0) \
392 + iv_i=(const u_int32_t*) iv; \
393 + else \
394 + iv_i=(const u_int32_t*) (out-8); \
395 + *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
396 + *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
397 + enc_func(ctx, (addr_type)out, (addr_type)out); \
398 + in+=8; \
399 + out+=8; \
400 + pos+=8; \
401 + } \
402 + } else { \
403 + pos=ilen-8; \
404 + in+=pos; \
405 + out+=pos; \
406 + while(pos>=0) { \
407 + dec_func(ctx, (const addr_type)in, (addr_type)out); \
408 + if (pos==0) \
409 + iv_i=(const u_int32_t*) (iv); \
410 + else \
411 + iv_i=(const u_int32_t*) (in-8); \
412 + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
413 + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
414 + in-=8; \
415 + out-=8; \
416 + pos-=8; \
417 + } \
418 + } \
419 + return ret; \
420 +}
421 +#define CBC_DECL(name, ctx_type) \
422 +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt)
423 +/*
424 +Eg.:
425 +CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
426 +CBC_DECL(AES_cbc_encrypt, aes_context);
427 +*/
428 +#endif /* _CBC_GENERIC_H */
429 --- /dev/null Tue Mar 11 13:02:56 2003
430 +++ linux/include/crypto/des.h Mon Feb 9 13:51:03 2004
431 @@ -0,0 +1,298 @@
432 +/* crypto/des/des.org */
433 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
434 + * All rights reserved.
435 + *
436 + * This package is an SSL implementation written
437 + * by Eric Young (eay@cryptsoft.com).
438 + * The implementation was written so as to conform with Netscapes SSL.
439 + *
440 + * This library is free for commercial and non-commercial use as long as
441 + * the following conditions are aheared to. The following conditions
442 + * apply to all code found in this distribution, be it the RC4, RSA,
443 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
444 + * included with this distribution is covered by the same copyright terms
445 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
446 + *
447 + * Copyright remains Eric Young's, and as such any Copyright notices in
448 + * the code are not to be removed.
449 + * If this package is used in a product, Eric Young should be given attribution
450 + * as the author of the parts of the library used.
451 + * This can be in the form of a textual message at program startup or
452 + * in documentation (online or textual) provided with the package.
453 + *
454 + * Redistribution and use in source and binary forms, with or without
455 + * modification, are permitted provided that the following conditions
456 + * are met:
457 + * 1. Redistributions of source code must retain the copyright
458 + * notice, this list of conditions and the following disclaimer.
459 + * 2. Redistributions in binary form must reproduce the above copyright
460 + * notice, this list of conditions and the following disclaimer in the
461 + * documentation and/or other materials provided with the distribution.
462 + * 3. All advertising materials mentioning features or use of this software
463 + * must display the following acknowledgement:
464 + * "This product includes cryptographic software written by
465 + * Eric Young (eay@cryptsoft.com)"
466 + * The word 'cryptographic' can be left out if the rouines from the library
467 + * being used are not cryptographic related :-).
468 + * 4. If you include any Windows specific code (or a derivative thereof) from
469 + * the apps directory (application code) you must include an acknowledgement:
470 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
471 + *
472 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
473 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
474 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
475 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
476 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
477 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
478 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
479 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
480 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
481 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
482 + * SUCH DAMAGE.
483 + *
484 + * The licence and distribution terms for any publically available version or
485 + * derivative of this code cannot be changed. i.e. this code cannot simply be
486 + * copied and put under another distribution licence
487 + * [including the GNU Public Licence.]
488 + */
489 +
490 +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
491 + *
492 + * Always modify des.org since des.h is automatically generated from
493 + * it during SSLeay configuration.
494 + *
495 + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
496 + */
497 +
498 +#ifndef HEADER_DES_H
499 +#define HEADER_DES_H
500 +
501 +#ifdef __cplusplus
502 +extern "C" {
503 +#endif
504 +
505 +
506 +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
507 + * %20 speed up (longs are 8 bytes, int's are 4). */
508 +/* Must be unsigned int on ia64/Itanium or DES breaks badly */
509 +
510 +#ifdef __KERNEL__
511 +#include <linux/types.h>
512 +#else
513 +#include <sys/types.h>
514 +#endif
515 +
516 +#ifndef DES_LONG
517 +#define DES_LONG u_int32_t
518 +#endif
519 +
520 +typedef unsigned char des_cblock[8];
521 +typedef struct { des_cblock ks; } des_key_schedule[16];
522 +
523 +#define DES_KEY_SZ (sizeof(des_cblock))
524 +#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
525 +
526 +#define DES_ENCRYPT 1
527 +#define DES_DECRYPT 0
528 +
529 +#define DES_CBC_MODE 0
530 +#define DES_PCBC_MODE 1
531 +
532 +#define des_ecb2_encrypt(i,o,k1,k2,e) \
533 + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
534 +
535 +#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
536 + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
537 +
538 +#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
539 + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
540 +
541 +#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
542 + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
543 +
544 +#define C_Block des_cblock
545 +#define Key_schedule des_key_schedule
546 +#ifdef KERBEROS
547 +#define ENCRYPT DES_ENCRYPT
548 +#define DECRYPT DES_DECRYPT
549 +#endif
550 +#define KEY_SZ DES_KEY_SZ
551 +#define string_to_key des_string_to_key
552 +#define read_pw_string des_read_pw_string
553 +#define random_key des_random_key
554 +#define pcbc_encrypt des_pcbc_encrypt
555 +#define set_key des_set_key
556 +#define key_sched des_key_sched
557 +#define ecb_encrypt des_ecb_encrypt
558 +#define cbc_encrypt des_cbc_encrypt
559 +#define ncbc_encrypt des_ncbc_encrypt
560 +#define xcbc_encrypt des_xcbc_encrypt
561 +#define cbc_cksum des_cbc_cksum
562 +#define quad_cksum des_quad_cksum
563 +
564 +/* For compatibility with the MIT lib - eay 20/05/92 */
565 +typedef des_key_schedule bit_64;
566 +#define des_fixup_key_parity des_set_odd_parity
567 +#define des_check_key_parity check_parity
568 +
569 +extern int des_check_key; /* defaults to false */
570 +extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
571 +
572 +/* The next line is used to disable full ANSI prototypes, if your
573 + * compiler has problems with the prototypes, make sure this line always
574 + * evaluates to true :-) */
575 +#if defined(MSDOS) || defined(__STDC__)
576 +#undef NOPROTO
577 +#endif
578 +#ifndef NOPROTO
579 +char *des_options(void);
580 +void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
581 + des_key_schedule ks1,des_key_schedule ks2,
582 + des_key_schedule ks3, int enc);
583 +DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
584 + long length,des_key_schedule schedule,des_cblock *ivec);
585 +void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
586 + des_key_schedule schedule,des_cblock *ivec,int enc);
587 +void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
588 + des_key_schedule schedule,des_cblock *ivec,int enc);
589 +void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
590 + des_key_schedule schedule,des_cblock *ivec,
591 + des_cblock *inw,des_cblock *outw,int enc);
592 +void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
593 + long length,des_key_schedule schedule,des_cblock *ivec,int enc);
594 +void des_ecb_encrypt(des_cblock *input,des_cblock *output,
595 + des_key_schedule ks,int enc);
596 +void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
597 +void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
598 +void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
599 + des_key_schedule ks2, des_key_schedule ks3);
600 +void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
601 + des_key_schedule ks2, des_key_schedule ks3);
602 +void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
603 + long length, des_key_schedule ks1, des_key_schedule ks2,
604 + des_key_schedule ks3, des_cblock *ivec, int enc);
605 +void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
606 + long length, des_key_schedule ks1, des_key_schedule ks2,
607 + des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
608 +void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
609 + long length, des_key_schedule ks1, des_key_schedule ks2,
610 + des_key_schedule ks3, des_cblock *ivec, int *num);
611 +
612 +void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
613 + des_cblock (*out_white));
614 +
615 +int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
616 + des_cblock *iv);
617 +int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
618 + des_cblock *iv);
619 +char *des_fcrypt(const char *buf,const char *salt, char *ret);
620 +#ifdef PERL5
621 +char *des_crypt(const char *buf,const char *salt);
622 +#else
623 +/* some stupid compilers complain because I have declared char instead
624 + * of const char */
625 +#ifndef __KERNEL__
626 +#ifdef HEADER_DES_LOCL_H
627 +char *crypt(const char *buf,const char *salt);
628 +#else /* HEADER_DES_LOCL_H */
629 +char *crypt(void);
630 +#endif /* HEADER_DES_LOCL_H */
631 +#endif /* __KERNEL__ */
632 +#endif /* PERL5 */
633 +void des_ofb_encrypt(unsigned char *in,unsigned char *out,
634 + int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
635 +void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
636 + des_key_schedule schedule,des_cblock *ivec,int enc);
637 +DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
638 + long length,int out_count,des_cblock *seed);
639 +void des_random_seed(des_cblock key);
640 +void des_random_key(des_cblock ret);
641 +int des_read_password(des_cblock *key,char *prompt,int verify);
642 +int des_read_2passwords(des_cblock *key1,des_cblock *key2,
643 + char *prompt,int verify);
644 +int des_read_pw_string(char *buf,int length,char *prompt,int verify);
645 +void des_set_odd_parity(des_cblock *key);
646 +int des_is_weak_key(des_cblock *key);
647 +int des_set_key(des_cblock *key,des_key_schedule schedule);
648 +int des_key_sched(des_cblock *key,des_key_schedule schedule);
649 +void des_string_to_key(char *str,des_cblock *key);
650 +void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
651 +void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
652 + des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
653 +void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
654 + des_key_schedule schedule, des_cblock *ivec, int *num);
655 +int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
656 +
657 +/* Extra functions from Mark Murray <mark@grondar.za> */
658 +/* The following functions are not in the normal unix build or the
659 + * SSLeay build. When using the SSLeay build, use RAND_seed()
660 + * and RAND_bytes() instead. */
661 +int des_new_random_key(des_cblock *key);
662 +void des_init_random_number_generator(des_cblock *key);
663 +void des_set_random_generator_seed(des_cblock *key);
664 +void des_set_sequence_number(des_cblock new_sequence_number);
665 +void des_generate_random_block(des_cblock *block);
666 +
667 +#else
668 +
669 +char *des_options();
670 +void des_ecb3_encrypt();
671 +DES_LONG des_cbc_cksum();
672 +void des_cbc_encrypt();
673 +void des_ncbc_encrypt();
674 +void des_xcbc_encrypt();
675 +void des_cfb_encrypt();
676 +void des_ede3_cfb64_encrypt();
677 +void des_ede3_ofb64_encrypt();
678 +void des_ecb_encrypt();
679 +void des_encrypt();
680 +void des_encrypt2();
681 +void des_encrypt3();
682 +void des_decrypt3();
683 +void des_ede3_cbc_encrypt();
684 +int des_enc_read();
685 +int des_enc_write();
686 +char *des_fcrypt();
687 +#ifdef PERL5
688 +char *des_crypt();
689 +#else
690 +char *crypt();
691 +#endif
692 +void des_ofb_encrypt();
693 +void des_pcbc_encrypt();
694 +DES_LONG des_quad_cksum();
695 +void des_random_seed();
696 +void des_random_key();
697 +int des_read_password();
698 +int des_read_2passwords();
699 +int des_read_pw_string();
700 +void des_set_odd_parity();
701 +int des_is_weak_key();
702 +int des_set_key();
703 +int des_key_sched();
704 +void des_string_to_key();
705 +void des_string_to_2keys();
706 +void des_cfb64_encrypt();
707 +void des_ofb64_encrypt();
708 +int des_read_pw();
709 +void des_xwhite_in2out();
710 +
711 +/* Extra functions from Mark Murray <mark@grondar.za> */
712 +/* The following functions are not in the normal unix build or the
713 + * SSLeay build. When using the SSLeay build, use RAND_seed()
714 + * and RAND_bytes() instead. */
715 +#ifdef FreeBSD
716 +int des_new_random_key();
717 +void des_init_random_number_generator();
718 +void des_set_random_generator_seed();
719 +void des_set_sequence_number();
720 +void des_generate_random_block();
721 +#endif
722 +
723 +#endif
724 +
725 +#ifdef __cplusplus
726 +}
727 +#endif
728 +
729 +#endif
730 --- /dev/null Tue Mar 11 13:02:56 2003
731 +++ linux/include/des/des_locl.h Mon Feb 9 13:51:03 2004
732 @@ -0,0 +1,515 @@
733 +/* crypto/des/des_locl.org */
734 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
735 + * All rights reserved.
736 + *
737 + * This package is an SSL implementation written
738 + * by Eric Young (eay@cryptsoft.com).
739 + * The implementation was written so as to conform with Netscapes SSL.
740 + *
741 + * This library is free for commercial and non-commercial use as long as
742 + * the following conditions are aheared to. The following conditions
743 + * apply to all code found in this distribution, be it the RC4, RSA,
744 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
745 + * included with this distribution is covered by the same copyright terms
746 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
747 + *
748 + * Copyright remains Eric Young's, and as such any Copyright notices in
749 + * the code are not to be removed.
750 + * If this package is used in a product, Eric Young should be given attribution
751 + * as the author of the parts of the library used.
752 + * This can be in the form of a textual message at program startup or
753 + * in documentation (online or textual) provided with the package.
754 + *
755 + * Redistribution and use in source and binary forms, with or without
756 + * modification, are permitted provided that the following conditions
757 + * are met:
758 + * 1. Redistributions of source code must retain the copyright
759 + * notice, this list of conditions and the following disclaimer.
760 + * 2. Redistributions in binary form must reproduce the above copyright
761 + * notice, this list of conditions and the following disclaimer in the
762 + * documentation and/or other materials provided with the distribution.
763 + * 3. All advertising materials mentioning features or use of this software
764 + * must display the following acknowledgement:
765 + * "This product includes cryptographic software written by
766 + * Eric Young (eay@cryptsoft.com)"
767 + * The word 'cryptographic' can be left out if the rouines from the library
768 + * being used are not cryptographic related :-).
769 + * 4. If you include any Windows specific code (or a derivative thereof) from
770 + * the apps directory (application code) you must include an acknowledgement:
771 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
772 + *
773 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
774 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
775 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
776 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
777 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
778 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
779 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
780 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
781 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
782 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
783 + * SUCH DAMAGE.
784 + *
785 + * The licence and distribution terms for any publically available version or
786 + * derivative of this code cannot be changed. i.e. this code cannot simply be
787 + * copied and put under another distribution licence
788 + * [including the GNU Public Licence.]
789 + */
790 +
791 +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
792 + *
793 + * Always modify des_locl.org since des_locl.h is automatically generated from
794 + * it during SSLeay configuration.
795 + *
796 + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
797 + */
798 +
799 +#ifndef HEADER_DES_LOCL_H
800 +#define HEADER_DES_LOCL_H
801 +
802 +#if defined(WIN32) || defined(WIN16)
803 +#ifndef MSDOS
804 +#define MSDOS
805 +#endif
806 +#endif
807 +
808 +#include "crypto/des.h"
809 +
810 +#ifndef DES_DEFAULT_OPTIONS
811 +/* the following is tweaked from a config script, that is why it is a
812 + * protected undef/define */
813 +#ifndef DES_PTR
814 +#define DES_PTR
815 +#endif
816 +
817 +/* This helps C compiler generate the correct code for multiple functional
818 + * units. It reduces register dependancies at the expense of 2 more
819 + * registers */
820 +#ifndef DES_RISC1
821 +#define DES_RISC1
822 +#endif
823 +
824 +#ifndef DES_RISC2
825 +#undef DES_RISC2
826 +#endif
827 +
828 +#if defined(DES_RISC1) && defined(DES_RISC2)
829 +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
830 +#endif
831 +
832 +/* Unroll the inner loop, this sometimes helps, sometimes hinders.
833 + * Very mucy CPU dependant */
834 +#ifndef DES_UNROLL
835 +#define DES_UNROLL
836 +#endif
837 +
838 +/* These default values were supplied by
839 + * Peter Gutman <pgut001@cs.auckland.ac.nz>
840 + * They are only used if nothing else has been defined */
841 +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
842 +/* Special defines which change the way the code is built depending on the
843 + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
844 + even newer MIPS CPU's, but at the moment one size fits all for
845 + optimization options. Older Sparc's work better with only UNROLL, but
846 + there's no way to tell at compile time what it is you're running on */
847 +
848 +#if defined( sun ) /* Newer Sparc's */
849 + #define DES_PTR
850 + #define DES_RISC1
851 + #define DES_UNROLL
852 +#elif defined( __ultrix ) /* Older MIPS */
853 + #define DES_PTR
854 + #define DES_RISC2
855 + #define DES_UNROLL
856 +#elif defined( __osf1__ ) /* Alpha */
857 + #define DES_PTR
858 + #define DES_RISC2
859 +#elif defined ( _AIX ) /* RS6000 */
860 + /* Unknown */
861 +#elif defined( __hpux ) /* HP-PA */
862 + /* Unknown */
863 +#elif defined( __aux ) /* 68K */
864 + /* Unknown */
865 +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
866 + #define DES_UNROLL
867 +#elif defined( __sgi ) /* Newer MIPS */
868 + #define DES_PTR
869 + #define DES_RISC2
870 + #define DES_UNROLL
871 +#elif defined( i386 ) /* x86 boxes, should be gcc */
872 + #define DES_PTR
873 + #define DES_RISC1
874 + #define DES_UNROLL
875 +#endif /* Systems-specific speed defines */
876 +#endif
877 +
878 +#endif /* DES_DEFAULT_OPTIONS */
879 +
880 +#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
881 +#include <stdlib.h>
882 +#include <errno.h>
883 +#include <time.h>
884 +#include <io.h>
885 +#ifndef RAND
886 +#define RAND
887 +#endif
888 +#undef NOPROTO
889 +#endif
890 +
891 +#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
892 +#ifndef __KERNEL__
893 +#include <string.h>
894 +#else
895 +#include <linux/string.h>
896 +#endif
897 +#endif
898 +
899 +#ifndef RAND
900 +#define RAND
901 +#endif
902 +
903 +#ifdef linux
904 +#undef RAND
905 +#endif
906 +
907 +#ifdef MSDOS
908 +#define getpid() 2
909 +#define RAND
910 +#undef NOPROTO
911 +#endif
912 +
913 +#if defined(NOCONST)
914 +#define const
915 +#endif
916 +
917 +#ifdef __STDC__
918 +#undef NOPROTO
919 +#endif
920 +
921 +#ifdef RAND
922 +#define srandom(s) srand(s)
923 +#define random rand
924 +#endif
925 +
926 +#define ITERATIONS 16
927 +#define HALF_ITERATIONS 8
928 +
929 +/* used in des_read and des_write */
930 +#define MAXWRITE (1024*16)
931 +#define BSIZE (MAXWRITE+4)
932 +
933 +#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
934 + l|=((DES_LONG)(*((c)++)))<< 8L, \
935 + l|=((DES_LONG)(*((c)++)))<<16L, \
936 + l|=((DES_LONG)(*((c)++)))<<24L)
937 +
938 +/* NOTE - c is not incremented as per c2l */
939 +#define c2ln(c,l1,l2,n) { \
940 + c+=n; \
941 + l1=l2=0; \
942 + switch (n) { \
943 + case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
944 + case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
945 + case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
946 + case 5: l2|=((DES_LONG)(*(--(c)))); \
947 + case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
948 + case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
949 + case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
950 + case 1: l1|=((DES_LONG)(*(--(c)))); \
951 + } \
952 + }
953 +
954 +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
955 + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
956 + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
957 + *((c)++)=(unsigned char)(((l)>>24L)&0xff))
958 +
959 +/* replacements for htonl and ntohl since I have no idea what to do
960 + * when faced with machines with 8 byte longs. */
961 +#define HDRSIZE 4
962 +
963 +#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
964 + l|=((DES_LONG)(*((c)++)))<<16L, \
965 + l|=((DES_LONG)(*((c)++)))<< 8L, \
966 + l|=((DES_LONG)(*((c)++))))
967 +
968 +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
969 + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
970 + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
971 + *((c)++)=(unsigned char)(((l) )&0xff))
972 +
973 +/* NOTE - c is not incremented as per l2c */
974 +#define l2cn(l1,l2,c,n) { \
975 + c+=n; \
976 + switch (n) { \
977 + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
978 + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
979 + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
980 + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
981 + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
982 + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
983 + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
984 + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
985 + } \
986 + }
987 +
988 +#if defined(WIN32)
989 +#define ROTATE(a,n) (_lrotr(a,n))
990 +#else
991 +#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
992 +#endif
993 +
994 +/* Don't worry about the LOAD_DATA() stuff, that is used by
995 + * fcrypt() to add it's little bit to the front */
996 +
997 +#ifdef DES_FCRYPT
998 +
999 +#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
1000 + { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
1001 +
1002 +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
1003 + t=R^(R>>16L); \
1004 + u=t&E0; t&=E1; \
1005 + tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
1006 + tmp=(t<<16); t^=R^s[S+1]; t^=tmp
1007 +#else
1008 +#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
1009 +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
1010 + u=R^s[S ]; \
1011 + t=R^s[S+1]
1012 +#endif
1013 +
1014 +/* The changes to this macro may help or hinder, depending on the
1015 + * compiler and the achitecture. gcc2 always seems to do well :-).
1016 + * Inspired by Dana How <how@isl.stanford.edu>
1017 + * DO NOT use the alternative version on machines with 8 byte longs.
1018 + * It does not seem to work on the Alpha, even when DES_LONG is 4
1019 + * bytes, probably an issue of accessing non-word aligned objects :-( */
1020 +#ifdef DES_PTR
1021 +
1022 +/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
1023 + * is no reason to not xor all the sub items together. This potentially
1024 + * saves a register since things can be xored directly into L */
1025 +
1026 +#if defined(DES_RISC1) || defined(DES_RISC2)
1027 +#ifdef DES_RISC1
1028 +#define D_ENCRYPT(LL,R,S) { \
1029 + unsigned int u1,u2,u3; \
1030 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
1031 + u2=(int)u>>8L; \
1032 + u1=(int)u&0xfc; \
1033 + u2&=0xfc; \
1034 + t=ROTATE(t,4); \
1035 + u>>=16L; \
1036 + LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
1037 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
1038 + u3=(int)(u>>8L); \
1039 + u1=(int)u&0xfc; \
1040 + u3&=0xfc; \
1041 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
1042 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
1043 + u2=(int)t>>8L; \
1044 + u1=(int)t&0xfc; \
1045 + u2&=0xfc; \
1046 + t>>=16L; \
1047 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
1048 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
1049 + u3=(int)t>>8L; \
1050 + u1=(int)t&0xfc; \
1051 + u3&=0xfc; \
1052 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
1053 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
1054 +#endif
1055 +#ifdef DES_RISC2
1056 +#define D_ENCRYPT(LL,R,S) { \
1057 + unsigned int u1,u2,s1,s2; \
1058 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
1059 + u2=(int)u>>8L; \
1060 + u1=(int)u&0xfc; \
1061 + u2&=0xfc; \
1062 + t=ROTATE(t,4); \
1063 + LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
1064 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
1065 + s1=(int)(u>>16L); \
1066 + s2=(int)(u>>24L); \
1067 + s1&=0xfc; \
1068 + s2&=0xfc; \
1069 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
1070 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
1071 + u2=(int)t>>8L; \
1072 + u1=(int)t&0xfc; \
1073 + u2&=0xfc; \
1074 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
1075 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
1076 + s1=(int)(t>>16L); \
1077 + s2=(int)(t>>24L); \
1078 + s1&=0xfc; \
1079 + s2&=0xfc; \
1080 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
1081 + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
1082 +#endif
1083 +#else
1084 +#define D_ENCRYPT(LL,R,S) { \
1085 + LOAD_DATA_tmp(R,S,u,t,E0,E1); \
1086 + t=ROTATE(t,4); \
1087 + LL^= \
1088 + *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
1089 + *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
1090 + *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
1091 + *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
1092 + *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
1093 + *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
1094 + *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
1095 + *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
1096 +#endif
1097 +
1098 +#else /* original version */
1099 +
1100 +#if defined(DES_RISC1) || defined(DES_RISC2)
1101 +#ifdef DES_RISC1
1102 +#define D_ENCRYPT(LL,R,S) {\
1103 + unsigned int u1,u2,u3; \
1104 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
1105 + u>>=2L; \
1106 + t=ROTATE(t,6); \
1107 + u2=(int)u>>8L; \
1108 + u1=(int)u&0x3f; \
1109 + u2&=0x3f; \
1110 + u>>=16L; \
1111 + LL^=des_SPtrans[0][u1]; \
1112 + LL^=des_SPtrans[2][u2]; \
1113 + u3=(int)u>>8L; \
1114 + u1=(int)u&0x3f; \
1115 + u3&=0x3f; \
1116 + LL^=des_SPtrans[4][u1]; \
1117 + LL^=des_SPtrans[6][u3]; \
1118 + u2=(int)t>>8L; \
1119 + u1=(int)t&0x3f; \
1120 + u2&=0x3f; \
1121 + t>>=16L; \
1122 + LL^=des_SPtrans[1][u1]; \
1123 + LL^=des_SPtrans[3][u2]; \
1124 + u3=(int)t>>8L; \
1125 + u1=(int)t&0x3f; \
1126 + u3&=0x3f; \
1127 + LL^=des_SPtrans[5][u1]; \
1128 + LL^=des_SPtrans[7][u3]; }
1129 +#endif
1130 +#ifdef DES_RISC2
1131 +#define D_ENCRYPT(LL,R,S) {\
1132 + unsigned int u1,u2,s1,s2; \
1133 + LOAD_DATA(R,S,u,t,E0,E1,u1); \
1134 + u>>=2L; \
1135 + t=ROTATE(t,6); \
1136 + u2=(int)u>>8L; \
1137 + u1=(int)u&0x3f; \
1138 + u2&=0x3f; \
1139 + LL^=des_SPtrans[0][u1]; \
1140 + LL^=des_SPtrans[2][u2]; \
1141 + s1=(int)u>>16L; \
1142 + s2=(int)u>>24L; \
1143 + s1&=0x3f; \
1144 + s2&=0x3f; \
1145 + LL^=des_SPtrans[4][s1]; \
1146 + LL^=des_SPtrans[6][s2]; \
1147 + u2=(int)t>>8L; \
1148 + u1=(int)t&0x3f; \
1149 + u2&=0x3f; \
1150 + LL^=des_SPtrans[1][u1]; \
1151 + LL^=des_SPtrans[3][u2]; \
1152 + s1=(int)t>>16; \
1153 + s2=(int)t>>24L; \
1154 + s1&=0x3f; \
1155 + s2&=0x3f; \
1156 + LL^=des_SPtrans[5][s1]; \
1157 + LL^=des_SPtrans[7][s2]; }
1158 +#endif
1159 +
1160 +#else
1161 +
1162 +#define D_ENCRYPT(LL,R,S) {\
1163 + LOAD_DATA_tmp(R,S,u,t,E0,E1); \
1164 + t=ROTATE(t,4); \
1165 + LL^=\
1166 + des_SPtrans[0][(u>> 2L)&0x3f]^ \
1167 + des_SPtrans[2][(u>>10L)&0x3f]^ \
1168 + des_SPtrans[4][(u>>18L)&0x3f]^ \
1169 + des_SPtrans[6][(u>>26L)&0x3f]^ \
1170 + des_SPtrans[1][(t>> 2L)&0x3f]^ \
1171 + des_SPtrans[3][(t>>10L)&0x3f]^ \
1172 + des_SPtrans[5][(t>>18L)&0x3f]^ \
1173 + des_SPtrans[7][(t>>26L)&0x3f]; }
1174 +#endif
1175 +#endif
1176 +
1177 + /* IP and FP
1178 + * The problem is more of a geometric problem that random bit fiddling.
1179 + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
1180 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
1181 + 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
1182 + 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
1183 +
1184 + 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
1185 + 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
1186 + 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
1187 + 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
1188 +
1189 + The output has been subject to swaps of the form
1190 + 0 1 -> 3 1 but the odd and even bits have been put into
1191 + 2 3 2 0
1192 + different words. The main trick is to remember that
1193 + t=((l>>size)^r)&(mask);
1194 + r^=t;
1195 + l^=(t<<size);
1196 + can be used to swap and move bits between words.
1197 +
1198 + So l = 0 1 2 3 r = 16 17 18 19
1199 + 4 5 6 7 20 21 22 23
1200 + 8 9 10 11 24 25 26 27
1201 + 12 13 14 15 28 29 30 31
1202 + becomes (for size == 2 and mask == 0x3333)
1203 + t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
1204 + 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
1205 + 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
1206 + 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
1207 +
1208 + Thanks for hints from Richard Outerbridge - he told me IP&FP
1209 + could be done in 15 xor, 10 shifts and 5 ands.
1210 + When I finally started to think of the problem in 2D
1211 + I first got ~42 operations without xors. When I remembered
1212 + how to use xors :-) I got it to its final state.
1213 + */
1214 +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
1215 + (b)^=(t),\
1216 + (a)^=((t)<<(n)))
1217 +
1218 +#define IP(l,r) \
1219 + { \
1220 + register DES_LONG tt; \
1221 + PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
1222 + PERM_OP(l,r,tt,16,0x0000ffffL); \
1223 + PERM_OP(r,l,tt, 2,0x33333333L); \
1224 + PERM_OP(l,r,tt, 8,0x00ff00ffL); \
1225 + PERM_OP(r,l,tt, 1,0x55555555L); \
1226 + }
1227 +
1228 +#define FP(l,r) \
1229 + { \
1230 + register DES_LONG tt; \
1231 + PERM_OP(l,r,tt, 1,0x55555555L); \
1232 + PERM_OP(r,l,tt, 8,0x00ff00ffL); \
1233 + PERM_OP(l,r,tt, 2,0x33333333L); \
1234 + PERM_OP(r,l,tt,16,0x0000ffffL); \
1235 + PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
1236 + }
1237 +
1238 +extern const DES_LONG des_SPtrans[8][64];
1239 +
1240 +#ifndef NOPROTO
1241 +void fcrypt_body(DES_LONG *out,des_key_schedule ks,
1242 + DES_LONG Eswap0, DES_LONG Eswap1);
1243 +#else
1244 +void fcrypt_body();
1245 +#endif
1246 +
1247 +#endif
1248 --- /dev/null Tue Mar 11 13:02:56 2003
1249 +++ linux/include/des/des_ver.h Mon Feb 9 13:51:03 2004
1250 @@ -0,0 +1,60 @@
1251 +/* crypto/des/des_ver.h */
1252 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1253 + * All rights reserved.
1254 + *
1255 + * This package is an SSL implementation written
1256 + * by Eric Young (eay@cryptsoft.com).
1257 + * The implementation was written so as to conform with Netscapes SSL.
1258 + *
1259 + * This library is free for commercial and non-commercial use as long as
1260 + * the following conditions are aheared to. The following conditions
1261 + * apply to all code found in this distribution, be it the RC4, RSA,
1262 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1263 + * included with this distribution is covered by the same copyright terms
1264 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1265 + *
1266 + * Copyright remains Eric Young's, and as such any Copyright notices in
1267 + * the code are not to be removed.
1268 + * If this package is used in a product, Eric Young should be given attribution
1269 + * as the author of the parts of the library used.
1270 + * This can be in the form of a textual message at program startup or
1271 + * in documentation (online or textual) provided with the package.
1272 + *
1273 + * Redistribution and use in source and binary forms, with or without
1274 + * modification, are permitted provided that the following conditions
1275 + * are met:
1276 + * 1. Redistributions of source code must retain the copyright
1277 + * notice, this list of conditions and the following disclaimer.
1278 + * 2. Redistributions in binary form must reproduce the above copyright
1279 + * notice, this list of conditions and the following disclaimer in the
1280 + * documentation and/or other materials provided with the distribution.
1281 + * 3. All advertising materials mentioning features or use of this software
1282 + * must display the following acknowledgement:
1283 + * "This product includes cryptographic software written by
1284 + * Eric Young (eay@cryptsoft.com)"
1285 + * The word 'cryptographic' can be left out if the rouines from the library
1286 + * being used are not cryptographic related :-).
1287 + * 4. If you include any Windows specific code (or a derivative thereof) from
1288 + * the apps directory (application code) you must include an acknowledgement:
1289 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1290 + *
1291 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1292 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1293 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1294 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1295 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1296 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1297 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1298 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1299 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1300 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1301 + * SUCH DAMAGE.
1302 + *
1303 + * The licence and distribution terms for any publically available version or
1304 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1305 + * copied and put under another distribution licence
1306 + * [including the GNU Public Licence.]
1307 + */
1308 +
1309 +extern char *DES_version; /* SSLeay version string */
1310 +extern char *libdes_version; /* old libdes version string */
1311 --- /dev/null Tue Mar 11 13:02:56 2003
1312 +++ linux/include/des/podd.h Mon Feb 9 13:51:03 2004
1313 @@ -0,0 +1,75 @@
1314 +/* crypto/des/podd.h */
1315 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1316 + * All rights reserved.
1317 + *
1318 + * This package is an SSL implementation written
1319 + * by Eric Young (eay@cryptsoft.com).
1320 + * The implementation was written so as to conform with Netscapes SSL.
1321 + *
1322 + * This library is free for commercial and non-commercial use as long as
1323 + * the following conditions are aheared to. The following conditions
1324 + * apply to all code found in this distribution, be it the RC4, RSA,
1325 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1326 + * included with this distribution is covered by the same copyright terms
1327 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1328 + *
1329 + * Copyright remains Eric Young's, and as such any Copyright notices in
1330 + * the code are not to be removed.
1331 + * If this package is used in a product, Eric Young should be given attribution
1332 + * as the author of the parts of the library used.
1333 + * This can be in the form of a textual message at program startup or
1334 + * in documentation (online or textual) provided with the package.
1335 + *
1336 + * Redistribution and use in source and binary forms, with or without
1337 + * modification, are permitted provided that the following conditions
1338 + * are met:
1339 + * 1. Redistributions of source code must retain the copyright
1340 + * notice, this list of conditions and the following disclaimer.
1341 + * 2. Redistributions in binary form must reproduce the above copyright
1342 + * notice, this list of conditions and the following disclaimer in the
1343 + * documentation and/or other materials provided with the distribution.
1344 + * 3. All advertising materials mentioning features or use of this software
1345 + * must display the following acknowledgement:
1346 + * "This product includes cryptographic software written by
1347 + * Eric Young (eay@cryptsoft.com)"
1348 + * The word 'cryptographic' can be left out if the rouines from the library
1349 + * being used are not cryptographic related :-).
1350 + * 4. If you include any Windows specific code (or a derivative thereof) from
1351 + * the apps directory (application code) you must include an acknowledgement:
1352 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1353 + *
1354 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1355 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1356 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1357 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1358 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1359 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1360 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1361 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1362 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1363 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1364 + * SUCH DAMAGE.
1365 + *
1366 + * The licence and distribution terms for any publically available version or
1367 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1368 + * copied and put under another distribution licence
1369 + * [including the GNU Public Licence.]
1370 + */
1371 +
1372 +static const unsigned char odd_parity[256]={
1373 + 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
1374 + 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
1375 + 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
1376 + 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
1377 + 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
1378 + 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
1379 + 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
1380 +112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
1381 +128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
1382 +145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
1383 +161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
1384 +176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
1385 +193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
1386 +208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
1387 +224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
1388 +241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
1389 --- /dev/null Tue Mar 11 13:02:56 2003
1390 +++ linux/include/des/sk.h Mon Feb 9 13:51:03 2004
1391 @@ -0,0 +1,204 @@
1392 +/* crypto/des/sk.h */
1393 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1394 + * All rights reserved.
1395 + *
1396 + * This package is an SSL implementation written
1397 + * by Eric Young (eay@cryptsoft.com).
1398 + * The implementation was written so as to conform with Netscapes SSL.
1399 + *
1400 + * This library is free for commercial and non-commercial use as long as
1401 + * the following conditions are aheared to. The following conditions
1402 + * apply to all code found in this distribution, be it the RC4, RSA,
1403 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1404 + * included with this distribution is covered by the same copyright terms
1405 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1406 + *
1407 + * Copyright remains Eric Young's, and as such any Copyright notices in
1408 + * the code are not to be removed.
1409 + * If this package is used in a product, Eric Young should be given attribution
1410 + * as the author of the parts of the library used.
1411 + * This can be in the form of a textual message at program startup or
1412 + * in documentation (online or textual) provided with the package.
1413 + *
1414 + * Redistribution and use in source and binary forms, with or without
1415 + * modification, are permitted provided that the following conditions
1416 + * are met:
1417 + * 1. Redistributions of source code must retain the copyright
1418 + * notice, this list of conditions and the following disclaimer.
1419 + * 2. Redistributions in binary form must reproduce the above copyright
1420 + * notice, this list of conditions and the following disclaimer in the
1421 + * documentation and/or other materials provided with the distribution.
1422 + * 3. All advertising materials mentioning features or use of this software
1423 + * must display the following acknowledgement:
1424 + * "This product includes cryptographic software written by
1425 + * Eric Young (eay@cryptsoft.com)"
1426 + * The word 'cryptographic' can be left out if the rouines from the library
1427 + * being used are not cryptographic related :-).
1428 + * 4. If you include any Windows specific code (or a derivative thereof) from
1429 + * the apps directory (application code) you must include an acknowledgement:
1430 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1431 + *
1432 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1433 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1434 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1435 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1436 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1437 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1438 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1439 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1440 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1441 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1442 + * SUCH DAMAGE.
1443 + *
1444 + * The licence and distribution terms for any publically available version or
1445 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1446 + * copied and put under another distribution licence
1447 + * [including the GNU Public Licence.]
1448 + */
1449 +
1450 +static const DES_LONG des_skb[8][64]={
1451 +{
1452 +/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
1453 +0x00000000L,0x00000010L,0x20000000L,0x20000010L,
1454 +0x00010000L,0x00010010L,0x20010000L,0x20010010L,
1455 +0x00000800L,0x00000810L,0x20000800L,0x20000810L,
1456 +0x00010800L,0x00010810L,0x20010800L,0x20010810L,
1457 +0x00000020L,0x00000030L,0x20000020L,0x20000030L,
1458 +0x00010020L,0x00010030L,0x20010020L,0x20010030L,
1459 +0x00000820L,0x00000830L,0x20000820L,0x20000830L,
1460 +0x00010820L,0x00010830L,0x20010820L,0x20010830L,
1461 +0x00080000L,0x00080010L,0x20080000L,0x20080010L,
1462 +0x00090000L,0x00090010L,0x20090000L,0x20090010L,
1463 +0x00080800L,0x00080810L,0x20080800L,0x20080810L,
1464 +0x00090800L,0x00090810L,0x20090800L,0x20090810L,
1465 +0x00080020L,0x00080030L,0x20080020L,0x20080030L,
1466 +0x00090020L,0x00090030L,0x20090020L,0x20090030L,
1467 +0x00080820L,0x00080830L,0x20080820L,0x20080830L,
1468 +0x00090820L,0x00090830L,0x20090820L,0x20090830L,
1469 +},{
1470 +/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
1471 +0x00000000L,0x02000000L,0x00002000L,0x02002000L,
1472 +0x00200000L,0x02200000L,0x00202000L,0x02202000L,
1473 +0x00000004L,0x02000004L,0x00002004L,0x02002004L,
1474 +0x00200004L,0x02200004L,0x00202004L,0x02202004L,
1475 +0x00000400L,0x02000400L,0x00002400L,0x02002400L,
1476 +0x00200400L,0x02200400L,0x00202400L,0x02202400L,
1477 +0x00000404L,0x02000404L,0x00002404L,0x02002404L,
1478 +0x00200404L,0x02200404L,0x00202404L,0x02202404L,
1479 +0x10000000L,0x12000000L,0x10002000L,0x12002000L,
1480 +0x10200000L,0x12200000L,0x10202000L,0x12202000L,
1481 +0x10000004L,0x12000004L,0x10002004L,0x12002004L,
1482 +0x10200004L,0x12200004L,0x10202004L,0x12202004L,
1483 +0x10000400L,0x12000400L,0x10002400L,0x12002400L,
1484 +0x10200400L,0x12200400L,0x10202400L,0x12202400L,
1485 +0x10000404L,0x12000404L,0x10002404L,0x12002404L,
1486 +0x10200404L,0x12200404L,0x10202404L,0x12202404L,
1487 +},{
1488 +/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
1489 +0x00000000L,0x00000001L,0x00040000L,0x00040001L,
1490 +0x01000000L,0x01000001L,0x01040000L,0x01040001L,
1491 +0x00000002L,0x00000003L,0x00040002L,0x00040003L,
1492 +0x01000002L,0x01000003L,0x01040002L,0x01040003L,
1493 +0x00000200L,0x00000201L,0x00040200L,0x00040201L,
1494 +0x01000200L,0x01000201L,0x01040200L,0x01040201L,
1495 +0x00000202L,0x00000203L,0x00040202L,0x00040203L,
1496 +0x01000202L,0x01000203L,0x01040202L,0x01040203L,
1497 +0x08000000L,0x08000001L,0x08040000L,0x08040001L,
1498 +0x09000000L,0x09000001L,0x09040000L,0x09040001L,
1499 +0x08000002L,0x08000003L,0x08040002L,0x08040003L,
1500 +0x09000002L,0x09000003L,0x09040002L,0x09040003L,
1501 +0x08000200L,0x08000201L,0x08040200L,0x08040201L,
1502 +0x09000200L,0x09000201L,0x09040200L,0x09040201L,
1503 +0x08000202L,0x08000203L,0x08040202L,0x08040203L,
1504 +0x09000202L,0x09000203L,0x09040202L,0x09040203L,
1505 +},{
1506 +/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
1507 +0x00000000L,0x00100000L,0x00000100L,0x00100100L,
1508 +0x00000008L,0x00100008L,0x00000108L,0x00100108L,
1509 +0x00001000L,0x00101000L,0x00001100L,0x00101100L,
1510 +0x00001008L,0x00101008L,0x00001108L,0x00101108L,
1511 +0x04000000L,0x04100000L,0x04000100L,0x04100100L,
1512 +0x04000008L,0x04100008L,0x04000108L,0x04100108L,
1513 +0x04001000L,0x04101000L,0x04001100L,0x04101100L,
1514 +0x04001008L,0x04101008L,0x04001108L,0x04101108L,
1515 +0x00020000L,0x00120000L,0x00020100L,0x00120100L,
1516 +0x00020008L,0x00120008L,0x00020108L,0x00120108L,
1517 +0x00021000L,0x00121000L,0x00021100L,0x00121100L,
1518 +0x00021008L,0x00121008L,0x00021108L,0x00121108L,
1519 +0x04020000L,0x04120000L,0x04020100L,0x04120100L,
1520 +0x04020008L,0x04120008L,0x04020108L,0x04120108L,
1521 +0x04021000L,0x04121000L,0x04021100L,0x04121100L,
1522 +0x04021008L,0x04121008L,0x04021108L,0x04121108L,
1523 +},{
1524 +/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
1525 +0x00000000L,0x10000000L,0x00010000L,0x10010000L,
1526 +0x00000004L,0x10000004L,0x00010004L,0x10010004L,
1527 +0x20000000L,0x30000000L,0x20010000L,0x30010000L,
1528 +0x20000004L,0x30000004L,0x20010004L,0x30010004L,
1529 +0x00100000L,0x10100000L,0x00110000L,0x10110000L,
1530 +0x00100004L,0x10100004L,0x00110004L,0x10110004L,
1531 +0x20100000L,0x30100000L,0x20110000L,0x30110000L,
1532 +0x20100004L,0x30100004L,0x20110004L,0x30110004L,
1533 +0x00001000L,0x10001000L,0x00011000L,0x10011000L,
1534 +0x00001004L,0x10001004L,0x00011004L,0x10011004L,
1535 +0x20001000L,0x30001000L,0x20011000L,0x30011000L,
1536 +0x20001004L,0x30001004L,0x20011004L,0x30011004L,
1537 +0x00101000L,0x10101000L,0x00111000L,0x10111000L,
1538 +0x00101004L,0x10101004L,0x00111004L,0x10111004L,
1539 +0x20101000L,0x30101000L,0x20111000L,0x30111000L,
1540 +0x20101004L,0x30101004L,0x20111004L,0x30111004L,
1541 +},{
1542 +/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
1543 +0x00000000L,0x08000000L,0x00000008L,0x08000008L,
1544 +0x00000400L,0x08000400L,0x00000408L,0x08000408L,
1545 +0x00020000L,0x08020000L,0x00020008L,0x08020008L,
1546 +0x00020400L,0x08020400L,0x00020408L,0x08020408L,
1547 +0x00000001L,0x08000001L,0x00000009L,0x08000009L,
1548 +0x00000401L,0x08000401L,0x00000409L,0x08000409L,
1549 +0x00020001L,0x08020001L,0x00020009L,0x08020009L,
1550 +0x00020401L,0x08020401L,0x00020409L,0x08020409L,
1551 +0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
1552 +0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
1553 +0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
1554 +0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
1555 +0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
1556 +0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
1557 +0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
1558 +0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
1559 +},{
1560 +/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
1561 +0x00000000L,0x00000100L,0x00080000L,0x00080100L,
1562 +0x01000000L,0x01000100L,0x01080000L,0x01080100L,
1563 +0x00000010L,0x00000110L,0x00080010L,0x00080110L,
1564 +0x01000010L,0x01000110L,0x01080010L,0x01080110L,
1565 +0x00200000L,0x00200100L,0x00280000L,0x00280100L,
1566 +0x01200000L,0x01200100L,0x01280000L,0x01280100L,
1567 +0x00200010L,0x00200110L,0x00280010L,0x00280110L,
1568 +0x01200010L,0x01200110L,0x01280010L,0x01280110L,
1569 +0x00000200L,0x00000300L,0x00080200L,0x00080300L,
1570 +0x01000200L,0x01000300L,0x01080200L,0x01080300L,
1571 +0x00000210L,0x00000310L,0x00080210L,0x00080310L,
1572 +0x01000210L,0x01000310L,0x01080210L,0x01080310L,
1573 +0x00200200L,0x00200300L,0x00280200L,0x00280300L,
1574 +0x01200200L,0x01200300L,0x01280200L,0x01280300L,
1575 +0x00200210L,0x00200310L,0x00280210L,0x00280310L,
1576 +0x01200210L,0x01200310L,0x01280210L,0x01280310L,
1577 +},{
1578 +/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
1579 +0x00000000L,0x04000000L,0x00040000L,0x04040000L,
1580 +0x00000002L,0x04000002L,0x00040002L,0x04040002L,
1581 +0x00002000L,0x04002000L,0x00042000L,0x04042000L,
1582 +0x00002002L,0x04002002L,0x00042002L,0x04042002L,
1583 +0x00000020L,0x04000020L,0x00040020L,0x04040020L,
1584 +0x00000022L,0x04000022L,0x00040022L,0x04040022L,
1585 +0x00002020L,0x04002020L,0x00042020L,0x04042020L,
1586 +0x00002022L,0x04002022L,0x00042022L,0x04042022L,
1587 +0x00000800L,0x04000800L,0x00040800L,0x04040800L,
1588 +0x00000802L,0x04000802L,0x00040802L,0x04040802L,
1589 +0x00002800L,0x04002800L,0x00042800L,0x04042800L,
1590 +0x00002802L,0x04002802L,0x00042802L,0x04042802L,
1591 +0x00000820L,0x04000820L,0x00040820L,0x04040820L,
1592 +0x00000822L,0x04000822L,0x00040822L,0x04040822L,
1593 +0x00002820L,0x04002820L,0x00042820L,0x04042820L,
1594 +0x00002822L,0x04002822L,0x00042822L,0x04042822L,
1595 +}};
1596 --- /dev/null Tue Mar 11 13:02:56 2003
1597 +++ linux/include/des/spr.h Mon Feb 9 13:51:03 2004
1598 @@ -0,0 +1,204 @@
1599 +/* crypto/des/spr.h */
1600 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
1601 + * All rights reserved.
1602 + *
1603 + * This package is an SSL implementation written
1604 + * by Eric Young (eay@cryptsoft.com).
1605 + * The implementation was written so as to conform with Netscapes SSL.
1606 + *
1607 + * This library is free for commercial and non-commercial use as long as
1608 + * the following conditions are aheared to. The following conditions
1609 + * apply to all code found in this distribution, be it the RC4, RSA,
1610 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1611 + * included with this distribution is covered by the same copyright terms
1612 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1613 + *
1614 + * Copyright remains Eric Young's, and as such any Copyright notices in
1615 + * the code are not to be removed.
1616 + * If this package is used in a product, Eric Young should be given attribution
1617 + * as the author of the parts of the library used.
1618 + * This can be in the form of a textual message at program startup or
1619 + * in documentation (online or textual) provided with the package.
1620 + *
1621 + * Redistribution and use in source and binary forms, with or without
1622 + * modification, are permitted provided that the following conditions
1623 + * are met:
1624 + * 1. Redistributions of source code must retain the copyright
1625 + * notice, this list of conditions and the following disclaimer.
1626 + * 2. Redistributions in binary form must reproduce the above copyright
1627 + * notice, this list of conditions and the following disclaimer in the
1628 + * documentation and/or other materials provided with the distribution.
1629 + * 3. All advertising materials mentioning features or use of this software
1630 + * must display the following acknowledgement:
1631 + * "This product includes cryptographic software written by
1632 + * Eric Young (eay@cryptsoft.com)"
1633 + * The word 'cryptographic' can be left out if the rouines from the library
1634 + * being used are not cryptographic related :-).
1635 + * 4. If you include any Windows specific code (or a derivative thereof) from
1636 + * the apps directory (application code) you must include an acknowledgement:
1637 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1638 + *
1639 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1640 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1641 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1642 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1643 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1644 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1645 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1646 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1647 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1648 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1649 + * SUCH DAMAGE.
1650 + *
1651 + * The licence and distribution terms for any publically available version or
1652 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1653 + * copied and put under another distribution licence
1654 + * [including the GNU Public Licence.]
1655 + */
1656 +
1657 +const DES_LONG des_SPtrans[8][64]={
1658 +{
1659 +/* nibble 0 */
1660 +0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
1661 +0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
1662 +0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
1663 +0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
1664 +0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
1665 +0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
1666 +0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
1667 +0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
1668 +0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
1669 +0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
1670 +0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
1671 +0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
1672 +0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
1673 +0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
1674 +0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
1675 +0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
1676 +},{
1677 +/* nibble 1 */
1678 +0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
1679 +0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
1680 +0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
1681 +0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
1682 +0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
1683 +0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
1684 +0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
1685 +0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
1686 +0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
1687 +0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
1688 +0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
1689 +0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
1690 +0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
1691 +0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
1692 +0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
1693 +0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
1694 +},{
1695 +/* nibble 2 */
1696 +0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
1697 +0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
1698 +0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
1699 +0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
1700 +0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
1701 +0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
1702 +0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
1703 +0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
1704 +0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
1705 +0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
1706 +0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
1707 +0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
1708 +0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
1709 +0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
1710 +0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
1711 +0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
1712 +},{
1713 +/* nibble 3 */
1714 +0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
1715 +0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
1716 +0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
1717 +0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
1718 +0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
1719 +0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
1720 +0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
1721 +0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
1722 +0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
1723 +0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
1724 +0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
1725 +0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
1726 +0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
1727 +0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
1728 +0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
1729 +0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
1730 +},{
1731 +/* nibble 4 */
1732 +0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
1733 +0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
1734 +0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
1735 +0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
1736 +0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
1737 +0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
1738 +0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
1739 +0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
1740 +0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
1741 +0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
1742 +0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
1743 +0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
1744 +0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
1745 +0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
1746 +0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
1747 +0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
1748 +},{
1749 +/* nibble 5 */
1750 +0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
1751 +0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
1752 +0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
1753 +0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
1754 +0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
1755 +0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
1756 +0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
1757 +0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
1758 +0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
1759 +0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
1760 +0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
1761 +0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
1762 +0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
1763 +0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
1764 +0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
1765 +0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
1766 +},{
1767 +/* nibble 6 */
1768 +0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
1769 +0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
1770 +0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
1771 +0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
1772 +0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
1773 +0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
1774 +0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
1775 +0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
1776 +0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
1777 +0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
1778 +0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
1779 +0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
1780 +0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
1781 +0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
1782 +0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
1783 +0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
1784 +},{
1785 +/* nibble 7 */
1786 +0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
1787 +0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
1788 +0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
1789 +0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
1790 +0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
1791 +0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
1792 +0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
1793 +0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
1794 +0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
1795 +0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
1796 +0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
1797 +0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
1798 +0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
1799 +0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
1800 +0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
1801 +0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
1802 +}};
1803 --- /dev/null Tue Mar 11 13:02:56 2003
1804 +++ linux/include/mast.h Mon Feb 9 13:51:03 2004
1805 @@ -0,0 +1,33 @@
1806 +struct mast_callbacks {
1807 + int (*packet_encap)(struct device *mast, void *context,
1808 + struct sk_buff *skb, int flowref);
1809 + int (*link_inquire)(struct device *mast, void *context);
1810 +};
1811 +
1812 +
1813 +struct device *mast_init (int family,
1814 + struct mast_callbacks *callbacks,
1815 + unsigned int flags,
1816 + unsigned int desired_unit,
1817 + unsigned int max_flowref,
1818 + void *context);
1819 +
1820 +int mast_destroy(struct device *mast);
1821 +
1822 +int mast_recv(struct device *mast, struct sk_buff *skb, int flowref);
1823 +
1824 +/* free this skb as being useless, increment failure count. */
1825 +int mast_toast(struct device *mast, struct sk_buff *skb, int flowref);
1826 +
1827 +int mast_linkstat (struct device *mast, int flowref,
1828 + int status);
1829 +
1830 +int mast_setreference (struct device *mast,
1831 + int defaultSA);
1832 +
1833 +int mast_setneighbor (struct device *mast,
1834 + struct sockaddr *source,
1835 + struct sockaddr *destination,
1836 + int flowref);
1837 +
1838 +
1839 --- /dev/null Tue Mar 11 13:02:56 2003
1840 +++ linux/include/openswan.h Mon Feb 9 13:51:03 2004
1841 @@ -0,0 +1,518 @@
1842 +#ifndef _OPENSWAN_H
1843 +/*
1844 + * header file for FreeS/WAN library functions
1845 + * Copyright (C) 1998, 1999, 2000 Henry Spencer.
1846 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
1847 + *
1848 + * This library is free software; you can redistribute it and/or modify it
1849 + * under the terms of the GNU Library General Public License as published by
1850 + * the Free Software Foundation; either version 2 of the License, or (at your
1851 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
1852 + *
1853 + * This library is distributed in the hope that it will be useful, but
1854 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1855 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
1856 + * License for more details.
1857 + *
1858 + * RCSID $Id: openswan.h,v 1.93 2005/04/14 20:21:51 mcr Exp $
1859 + */
1860 +#define _OPENSWAN_H /* seen it, no need to see it again */
1861 +
1862 +/* you'd think this should be builtin to compiler... */
1863 +#ifndef TRUE
1864 +#define TRUE 1
1865 +#endif
1866 +
1867 +#ifndef FALSE
1868 +#define FALSE 0
1869 +#endif
1870 +
1871 +
1872 +
1873 +/*
1874 + * We've just got to have some datatypes defined... And annoyingly, just
1875 + * where we get them depends on whether we're in userland or not.
1876 + */
1877 +/* things that need to come from one place or the other, depending */
1878 +#ifdef __KERNEL__
1879 +#include <linux/types.h>
1880 +#include <linux/socket.h>
1881 +#include <linux/in.h>
1882 +#include <linux/string.h>
1883 +#include <linux/ctype.h>
1884 +#define user_assert(foo) /*nothing*/
1885 +#else
1886 +#include <sys/types.h>
1887 +#include <netinet/in.h>
1888 +#include <string.h>
1889 +#include <ctype.h>
1890 +#include <assert.h>
1891 +#define user_assert(foo) assert(foo)
1892 +#include <stdio.h>
1893 +
1894 +# define uint8_t u_int8_t
1895 +# define uint16_t u_int16_t
1896 +# define uint32_t u_int32_t
1897 +# define uint64_t u_int64_t
1898 +
1899 +
1900 +# define DEBUG_NO_STATIC static
1901 +
1902 +#endif
1903 +
1904 +#include <openswan/ipsec_param.h>
1905 +
1906 +
1907 +/*
1908 + * Grab the kernel version to see if we have NET_21, and therefore
1909 + * IPv6. Some of this is repeated from ipsec_kversions.h. Of course,
1910 + * we aren't really testing if the kernel has IPv6, but rather if the
1911 + * the include files do.
1912 + */
1913 +#include <linux/version.h>
1914 +#ifndef KERNEL_VERSION
1915 +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
1916 +#endif
1917 +
1918 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
1919 +#define NET_21
1920 +#endif
1921 +
1922 +#ifndef IPPROTO_COMP
1923 +# define IPPROTO_COMP 108
1924 +#endif /* !IPPROTO_COMP */
1925 +
1926 +#ifndef IPPROTO_INT
1927 +# define IPPROTO_INT 61
1928 +#endif /* !IPPROTO_INT */
1929 +
1930 +#ifdef CONFIG_KLIPS_DEBUG
1931 +#ifndef DEBUG_NO_STATIC
1932 +# define DEBUG_NO_STATIC
1933 +#endif
1934 +#else /* CONFIG_KLIPS_DEBUG */
1935 +#ifndef DEBUG_NO_STATIC
1936 +# define DEBUG_NO_STATIC static
1937 +#endif
1938 +#endif /* CONFIG_KLIPS_DEBUG */
1939 +
1940 +#if !defined(ESPINUDP_WITH_NON_IKE)
1941 +#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
1942 +#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */
1943 +#endif
1944 +
1945 +/*
1946 + * Basic data types for the address-handling functions.
1947 + * ip_address and ip_subnet are supposed to be opaque types; do not
1948 + * use their definitions directly, they are subject to change!
1949 + */
1950 +
1951 +/* first, some quick fakes in case we're on an old system with no IPv6 */
1952 +#ifndef s6_addr16
1953 +struct in6_addr {
1954 + union
1955 + {
1956 + __u8 u6_addr8[16];
1957 + __u16 u6_addr16[8];
1958 + __u32 u6_addr32[4];
1959 + } in6_u;
1960 +#define s6_addr in6_u.u6_addr8
1961 +#define s6_addr16 in6_u.u6_addr16
1962 +#define s6_addr32 in6_u.u6_addr32
1963 +};
1964 +struct sockaddr_in6 {
1965 + unsigned short int sin6_family; /* AF_INET6 */
1966 + __u16 sin6_port; /* Transport layer port # */
1967 + __u32 sin6_flowinfo; /* IPv6 flow information */
1968 + struct in6_addr sin6_addr; /* IPv6 address */
1969 + __u32 sin6_scope_id; /* scope id (new in RFC2553) */
1970 +};
1971 +#endif /* !s6_addr16 */
1972 +
1973 +/* then the main types */
1974 +typedef struct {
1975 + union {
1976 + struct sockaddr_in v4;
1977 + struct sockaddr_in6 v6;
1978 + } u;
1979 +} ip_address;
1980 +typedef struct {
1981 + ip_address addr;
1982 + int maskbits;
1983 +} ip_subnet;
1984 +
1985 +/* and the SA ID stuff */
1986 +#ifdef __KERNEL__
1987 +typedef __u32 ipsec_spi_t;
1988 +#else
1989 +typedef u_int32_t ipsec_spi_t;
1990 +#endif
1991 +typedef struct { /* to identify an SA, we need: */
1992 + ip_address dst; /* A. destination host */
1993 + ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
1994 +# define SPI_PASS 256 /* magic values... */
1995 +# define SPI_DROP 257 /* ...for use... */
1996 +# define SPI_REJECT 258 /* ...with SA_INT */
1997 +# define SPI_HOLD 259
1998 +# define SPI_TRAP 260
1999 +# define SPI_TRAPSUBNET 261
2000 + int proto; /* C. protocol */
2001 +# define SA_ESP 50 /* IPPROTO_ESP */
2002 +# define SA_AH 51 /* IPPROTO_AH */
2003 +# define SA_IPIP 4 /* IPPROTO_IPIP */
2004 +# define SA_COMP 108 /* IPPROTO_COMP */
2005 +# define SA_INT 61 /* IANA reserved for internal use */
2006 +} ip_said;
2007 +
2008 +/* misc */
2009 +typedef const char *err_t; /* error message, or NULL for success */
2010 +struct prng { /* pseudo-random-number-generator guts */
2011 + unsigned char sbox[256];
2012 + int i, j;
2013 + unsigned long count;
2014 +};
2015 +
2016 +
2017 +/*
2018 + * definitions for user space, taken from freeswan/ipsec_sa.h
2019 + */
2020 +typedef uint32_t IPsecSAref_t;
2021 +
2022 +#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
2023 +
2024 +#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
2025 +#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
2026 +
2027 +#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0))
2028 +
2029 +/* GCC magic for use in function definitions! */
2030 +#ifdef GCC_LINT
2031 +# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
2032 +# define NEVER_RETURNS __attribute__ ((noreturn))
2033 +# define UNUSED __attribute__ ((unused))
2034 +# define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */
2035 +#else
2036 +# define PRINTF_LIKE(n) /* ignore */
2037 +# define NEVER_RETURNS /* ignore */
2038 +# define UNUSED /* ignore */
2039 +# define BLANK_FORMAT ""
2040 +#endif
2041 +
2042 +
2043 +
2044 +
2045 +
2046 +/*
2047 + * new IPv6-compatible functions
2048 + */
2049 +
2050 +/* text conversions */
2051 +err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
2052 +size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
2053 +#define ULTOT_BUF (22+1) /* holds 64 bits in octal */
2054 +err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
2055 +err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
2056 +size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
2057 +/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
2058 +#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1)
2059 +err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
2060 +size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
2061 +#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3)
2062 +size_t subnetporttot(const ip_subnet *src, int format, char *buf, size_t buflen);
2063 +#define SUBNETPROTOTOT_BUF (SUBNETTOTO_BUF + ULTOT_BUF)
2064 +err_t ttosa(const char *src, size_t srclen, ip_said *dst);
2065 +size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
2066 +#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
2067 +err_t ttodata(const char *src, size_t srclen, int base, char *buf,
2068 + size_t buflen, size_t *needed);
2069 +err_t ttodatav(const char *src, size_t srclen, int base,
2070 + char *buf, size_t buflen, size_t *needed,
2071 + char *errp, size_t errlen, unsigned int flags);
2072 +#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */
2073 +#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/
2074 +#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */
2075 +
2076 +size_t datatot(const char *src, size_t srclen, int format, char *buf,
2077 + size_t buflen);
2078 +size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst,
2079 + size_t dstlen);
2080 +size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
2081 + size_t mlen, char *dst, size_t dstlen);
2082 +#define KEYID_BUF 10 /* up to 9 text digits plus NUL */
2083 +err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port,
2084 + int *has_port_wildcard);
2085 +
2086 +/* initializations */
2087 +void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
2088 +err_t loopbackaddr(int af, ip_address *dst);
2089 +err_t unspecaddr(int af, ip_address *dst);
2090 +err_t anyaddr(int af, ip_address *dst);
2091 +err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
2092 +err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
2093 +err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
2094 +
2095 +/* misc. conversions and related */
2096 +err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
2097 +int addrtypeof(const ip_address *src);
2098 +int subnettypeof(const ip_subnet *src);
2099 +size_t addrlenof(const ip_address *src);
2100 +size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
2101 +size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
2102 +int masktocount(const ip_address *src);
2103 +void networkof(const ip_subnet *src, ip_address *dst);
2104 +void maskof(const ip_subnet *src, ip_address *dst);
2105 +
2106 +/* tests */
2107 +int sameaddr(const ip_address *a, const ip_address *b);
2108 +int addrcmp(const ip_address *a, const ip_address *b);
2109 +int samesubnet(const ip_subnet *a, const ip_subnet *b);
2110 +int addrinsubnet(const ip_address *a, const ip_subnet *s);
2111 +int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
2112 +int subnetishost(const ip_subnet *s);
2113 +int samesaid(const ip_said *a, const ip_said *b);
2114 +int sameaddrtype(const ip_address *a, const ip_address *b);
2115 +int samesubnettype(const ip_subnet *a, const ip_subnet *b);
2116 +int isanyaddr(const ip_address *src);
2117 +int isunspecaddr(const ip_address *src);
2118 +int isloopbackaddr(const ip_address *src);
2119 +
2120 +/* low-level grot */
2121 +int portof(const ip_address *src);
2122 +void setportof(int port, ip_address *dst);
2123 +struct sockaddr *sockaddrof(ip_address *src);
2124 +size_t sockaddrlenof(const ip_address *src);
2125 +
2126 +/* PRNG */
2127 +void prng_init(struct prng *prng, const unsigned char *key, size_t keylen);
2128 +void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen);
2129 +unsigned long prng_count(struct prng *prng);
2130 +void prng_final(struct prng *prng);
2131 +
2132 +/* odds and ends */
2133 +const char *ipsec_version_code(void);
2134 +const char *ipsec_version_string(void);
2135 +const char **ipsec_copyright_notice(void);
2136 +
2137 +const char *dns_string_rr(int rr, char *buf, int bufsize);
2138 +const char *dns_string_datetime(time_t seconds,
2139 + char *buf,
2140 + int bufsize);
2141 +
2142 +
2143 +/*
2144 + * old functions, to be deleted eventually
2145 + */
2146 +
2147 +/* unsigned long */
2148 +const char * /* NULL for success, else string literal */
2149 +atoul(
2150 + const char *src,
2151 + size_t srclen, /* 0 means strlen(src) */
2152 + int base, /* 0 means figure it out */
2153 + unsigned long *resultp
2154 +);
2155 +size_t /* space needed for full conversion */
2156 +ultoa(
2157 + unsigned long n,
2158 + int base,
2159 + char *dst,
2160 + size_t dstlen
2161 +);
2162 +#define ULTOA_BUF 21 /* just large enough for largest result, */
2163 + /* assuming 64-bit unsigned long! */
2164 +
2165 +/* Internet addresses */
2166 +const char * /* NULL for success, else string literal */
2167 +atoaddr(
2168 + const char *src,
2169 + size_t srclen, /* 0 means strlen(src) */
2170 + struct in_addr *addr
2171 +);
2172 +size_t /* space needed for full conversion */
2173 +addrtoa(
2174 + struct in_addr addr,
2175 + int format, /* character; 0 means default */
2176 + char *dst,
2177 + size_t dstlen
2178 +);
2179 +#define ADDRTOA_BUF 16 /* just large enough for largest result */
2180 +
2181 +/* subnets */
2182 +const char * /* NULL for success, else string literal */
2183 +atosubnet(
2184 + const char *src,
2185 + size_t srclen, /* 0 means strlen(src) */
2186 + struct in_addr *addr,
2187 + struct in_addr *mask
2188 +);
2189 +size_t /* space needed for full conversion */
2190 +subnettoa(
2191 + struct in_addr addr,
2192 + struct in_addr mask,
2193 + int format, /* character; 0 means default */
2194 + char *dst,
2195 + size_t dstlen
2196 +);
2197 +#define SUBNETTOA_BUF 32 /* large enough for worst case result */
2198 +
2199 +/* ranges */
2200 +const char * /* NULL for success, else string literal */
2201 +atoasr(
2202 + const char *src,
2203 + size_t srclen, /* 0 means strlen(src) */
2204 + char *type, /* 'a', 's', 'r' */
2205 + struct in_addr *addrs /* two-element array */
2206 +);
2207 +size_t /* space needed for full conversion */
2208 +rangetoa(
2209 + struct in_addr *addrs, /* two-element array */
2210 + int format, /* character; 0 means default */
2211 + char *dst,
2212 + size_t dstlen
2213 +);
2214 +#define RANGETOA_BUF 34 /* large enough for worst case result */
2215 +
2216 +/* data types for SA conversion functions */
2217 +
2218 +/* generic data, e.g. keys */
2219 +const char * /* NULL for success, else string literal */
2220 +atobytes(
2221 + const char *src,
2222 + size_t srclen, /* 0 means strlen(src) */
2223 + char *dst,
2224 + size_t dstlen,
2225 + size_t *lenp /* NULL means don't bother telling me */
2226 +);
2227 +size_t /* 0 failure, else true size */
2228 +bytestoa(
2229 + const char *src,
2230 + size_t srclen,
2231 + int format, /* character; 0 means default */
2232 + char *dst,
2233 + size_t dstlen
2234 +);
2235 +
2236 +/* old versions of generic-data functions; deprecated */
2237 +size_t /* 0 failure, else true size */
2238 +atodata(
2239 + const char *src,
2240 + size_t srclen, /* 0 means strlen(src) */
2241 + char *dst,
2242 + size_t dstlen
2243 +);
2244 +size_t /* 0 failure, else true size */
2245 +datatoa(
2246 + const char *src,
2247 + size_t srclen,
2248 + int format, /* character; 0 means default */
2249 + char *dst,
2250 + size_t dstlen
2251 +);
2252 +
2253 +/* part extraction and special addresses */
2254 +struct in_addr
2255 +subnetof(
2256 + struct in_addr addr,
2257 + struct in_addr mask
2258 +);
2259 +struct in_addr
2260 +hostof(
2261 + struct in_addr addr,
2262 + struct in_addr mask
2263 +);
2264 +struct in_addr
2265 +broadcastof(
2266 + struct in_addr addr,
2267 + struct in_addr mask
2268 +);
2269 +
2270 +/* mask handling */
2271 +int
2272 +goodmask(
2273 + struct in_addr mask
2274 +);
2275 +int
2276 +masktobits(
2277 + struct in_addr mask
2278 +);
2279 +struct in_addr
2280 +bitstomask(
2281 + int n
2282 +);
2283 +
2284 +
2285 +
2286 +/*
2287 + * general utilities
2288 + */
2289 +
2290 +#ifndef __KERNEL__
2291 +/* option pickup from files (userland only because of use of FILE) */
2292 +const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
2293 + int optind, FILE *errorreport);
2294 +
2295 +/* sanitize a string */
2296 +extern size_t sanitize_string(char *buf, size_t size);
2297 +
2298 +#endif
2299 +
2300 +
2301 +/*
2302 + * ENUM of klips debugging values. Not currently used in klips.
2303 + * debug flag is actually 32 -bits, but only one bit is ever used,
2304 + * so we can actually pack it all into a single 32-bit word.
2305 + */
2306 +enum klips_debug_flags {
2307 + KDF_VERBOSE = 0,
2308 + KDF_XMIT = 1,
2309 + KDF_NETLINK = 2, /* obsolete */
2310 + KDF_XFORM = 3,
2311 + KDF_EROUTE = 4,
2312 + KDF_SPI = 5,
2313 + KDF_RADIJ = 6,
2314 + KDF_ESP = 7,
2315 + KDF_AH = 8, /* obsolete */
2316 + KDF_RCV = 9,
2317 + KDF_TUNNEL = 10,
2318 + KDF_PFKEY = 11,
2319 + KDF_COMP = 12
2320 +};
2321 +
2322 +
2323 +/*
2324 + * Debugging levels for pfkey_lib_debug
2325 + */
2326 +#define PF_KEY_DEBUG_PARSE_NONE 0
2327 +#define PF_KEY_DEBUG_PARSE_PROBLEM 1
2328 +#define PF_KEY_DEBUG_PARSE_STRUCT 2
2329 +#define PF_KEY_DEBUG_PARSE_FLOW 4
2330 +#define PF_KEY_DEBUG_BUILD 8
2331 +#define PF_KEY_DEBUG_PARSE_MAX 15
2332 +
2333 +extern unsigned int pfkey_lib_debug; /* bits selecting what to report */
2334 +
2335 +/*
2336 + * pluto and lwdnsq need to know the maximum size of the commands to,
2337 + * and replies from lwdnsq.
2338 + */
2339 +
2340 +#define LWDNSQ_CMDBUF_LEN 1024
2341 +#define LWDNSQ_RESULT_LEN_MAX 4096
2342 +
2343 +
2344 +/* syntax for passthrough SA */
2345 +#ifndef PASSTHROUGHNAME
2346 +#define PASSTHROUGHNAME "%passthrough"
2347 +#define PASSTHROUGH4NAME "%passthrough4"
2348 +#define PASSTHROUGH6NAME "%passthrough6"
2349 +#define PASSTHROUGHIS "tun0@0.0.0.0"
2350 +#define PASSTHROUGH4IS "tun0@0.0.0.0"
2351 +#define PASSTHROUGH6IS "tun0@::"
2352 +#define PASSTHROUGHTYPE "tun"
2353 +#define PASSTHROUGHSPI 0
2354 +#define PASSTHROUGHDST 0
2355 +#endif
2356 +
2357 +
2358 +
2359 +#endif /* _OPENSWAN_H */
2360 --- /dev/null Tue Mar 11 13:02:56 2003
2361 +++ linux/include/openswan/ipcomp.h Mon Feb 9 13:51:03 2004
2362 @@ -0,0 +1,61 @@
2363 +/*
2364 + * IPCOMP zlib interface code.
2365 + * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
2366 + * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
2367 + *
2368 + * This program is free software; you can redistribute it and/or modify it
2369 + * under the terms of the GNU General Public License as published by the
2370 + * Free Software Foundation; either version 2 of the License, or (at your
2371 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2372 + *
2373 + * This program is distributed in the hope that it will be useful, but
2374 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2375 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2376 + * for more details.
2377 +
2378 + RCSID $Id: ipcomp.h,v 1.14 2004/07/10 19:08:41 mcr Exp $
2379 +
2380 + */
2381 +
2382 +/* SSS */
2383 +
2384 +#ifndef _IPCOMP_H
2385 +#define _IPCOMP_H
2386 +
2387 +/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
2388 +#ifndef IPCOMP_PREFIX
2389 +#define IPCOMP_PREFIX
2390 +#endif /* IPCOMP_PREFIX */
2391 +
2392 +#ifndef IPPROTO_COMP
2393 +#define IPPROTO_COMP 108
2394 +#endif /* IPPROTO_COMP */
2395 +
2396 +#ifdef CONFIG_KLIPS_DEBUG
2397 +extern int sysctl_ipsec_debug_ipcomp;
2398 +#endif /* CONFIG_KLIPS_DEBUG */
2399 +
2400 +struct ipcomphdr { /* IPCOMP header */
2401 + __u8 ipcomp_nh; /* Next header (protocol) */
2402 + __u8 ipcomp_flags; /* Reserved, must be 0 */
2403 + __u16 ipcomp_cpi; /* Compression Parameter Index */
2404 +};
2405 +
2406 +extern struct inet_protocol comp_protocol;
2407 +extern int sysctl_ipsec_debug_ipcomp;
2408 +
2409 +#define IPCOMP_UNCOMPRESSABLE 0x000000001
2410 +#define IPCOMP_COMPRESSIONERROR 0x000000002
2411 +#define IPCOMP_PARMERROR 0x000000004
2412 +#define IPCOMP_DECOMPRESSIONERROR 0x000000008
2413 +
2414 +#define IPCOMP_ADAPT_INITIAL_TRIES 8
2415 +#define IPCOMP_ADAPT_INITIAL_SKIP 4
2416 +#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
2417 +#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
2418 +
2419 +/* Function prototypes */
2420 +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
2421 +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
2422 +
2423 +#endif /* _IPCOMP_H */
2424 --- /dev/null Tue Mar 11 13:02:56 2003
2425 +++ linux/include/openswan/ipsec_ah.h Mon Feb 9 13:51:03 2004
2426 @@ -0,0 +1,200 @@
2427 +/*
2428 + * Authentication Header declarations
2429 + * Copyright (C) 1996, 1997 John Ioannidis.
2430 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
2431 + *
2432 + * This program is free software; you can redistribute it and/or modify it
2433 + * under the terms of the GNU General Public License as published by the
2434 + * Free Software Foundation; either version 2 of the License, or (at your
2435 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2436 + *
2437 + * This program is distributed in the hope that it will be useful, but
2438 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2439 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2440 + * for more details.
2441 + *
2442 + * RCSID $Id: ipsec_ah.h,v 1.26 2004/09/13 02:22:10 mcr Exp $
2443 + */
2444 +
2445 +#include "ipsec_md5h.h"
2446 +#include "ipsec_sha1.h"
2447 +
2448 +#ifndef IPPROTO_AH
2449 +#define IPPROTO_AH 51
2450 +#endif /* IPPROTO_AH */
2451 +
2452 +#include "ipsec_auth.h"
2453 +
2454 +#ifdef __KERNEL__
2455 +
2456 +extern struct inet_protocol ah_protocol;
2457 +
2458 +struct options;
2459 +
2460 +struct ahhdr /* Generic AH header */
2461 +{
2462 + __u8 ah_nh; /* Next header (protocol) */
2463 + __u8 ah_hl; /* AH length, in 32-bit words */
2464 + __u16 ah_rv; /* reserved, must be 0 */
2465 + __u32 ah_spi; /* Security Parameters Index */
2466 + __u32 ah_rpl; /* Replay prevention */
2467 + __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */
2468 +};
2469 +#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi
2470 + * and the ah_hl, says how many bytes after that
2471 + * to cover. */
2472 +
2473 +extern struct xform_functions ah_xform_funcs[];
2474 +
2475 +#ifdef CONFIG_KLIPS_DEBUG
2476 +extern int debug_ah;
2477 +#endif /* CONFIG_KLIPS_DEBUG */
2478 +#endif /* __KERNEL__ */
2479 +
2480 +/*
2481 + * $Log: ipsec_ah.h,v $
2482 + * Revision 1.26 2004/09/13 02:22:10 mcr
2483 + * #define inet_protocol if necessary.
2484 + *
2485 + * Revision 1.25 2004/09/06 18:35:41 mcr
2486 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
2487 + * so adjust for that.
2488 + *
2489 + * Revision 1.24 2004/07/10 19:08:41 mcr
2490 + * CONFIG_IPSEC -> CONFIG_KLIPS.
2491 + *
2492 + * Revision 1.23 2004/04/05 19:55:04 mcr
2493 + * Moved from linux/include/freeswan/ipsec_ah.h,v
2494 + *
2495 + * Revision 1.22 2004/04/05 19:41:05 mcr
2496 + * merged alg-branch code.
2497 + *
2498 + * Revision 1.21 2003/12/13 19:10:16 mcr
2499 + * refactored rcv and xmit code - same as FS 2.05.
2500 + *
2501 + * Revision 1.22 2003/12/11 20:14:58 mcr
2502 + * refactored the xmit code, to move all encapsulation
2503 + * code into protocol functions. Note that all functions
2504 + * are essentially done by a single function, which is probably
2505 + * wrong.
2506 + * the rcv_functions structures are renamed xform_functions.
2507 + *
2508 + * Revision 1.21 2003/12/06 21:21:19 mcr
2509 + * split up receive path into per-transform files, for
2510 + * easier later removal.
2511 + *
2512 + * Revision 1.20.8.1 2003/12/22 15:25:52 jjo
2513 + * Merged algo-0.8.1-rc11-test1 into alg-branch
2514 + *
2515 + * Revision 1.20 2003/02/06 02:21:34 rgb
2516 + *
2517 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
2518 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
2519 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
2520 + *
2521 + * Revision 1.19 2002/09/16 21:19:13 mcr
2522 + * fixes for west-ah-icmp-01 - length of AH header must be
2523 + * calculated properly, and next_header field properly copied.
2524 + *
2525 + * Revision 1.18 2002/05/14 02:37:02 rgb
2526 + * Change reference from _TDB to _IPSA.
2527 + *
2528 + * Revision 1.17 2002/04/24 07:36:46 mcr
2529 + * Moved from ./klips/net/ipsec/ipsec_ah.h,v
2530 + *
2531 + * Revision 1.16 2002/02/20 01:27:06 rgb
2532 + * Ditched a pile of structs only used by the old Netlink interface.
2533 + *
2534 + * Revision 1.15 2001/12/11 02:35:57 rgb
2535 + * Change "struct net_device" to "struct device" for 2.2 compatibility.
2536 + *
2537 + * Revision 1.14 2001/11/26 09:23:47 rgb
2538 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
2539 + *
2540 + * Revision 1.13.2.1 2001/09/25 02:18:24 mcr
2541 + * replace "struct device" with "struct netdevice"
2542 + *
2543 + * Revision 1.13 2001/06/14 19:35:08 rgb
2544 + * Update copyright date.
2545 + *
2546 + * Revision 1.12 2000/09/12 03:21:20 rgb
2547 + * Cleared out unused htonq.
2548 + *
2549 + * Revision 1.11 2000/09/08 19:12:55 rgb
2550 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
2551 + *
2552 + * Revision 1.10 2000/01/21 06:13:10 rgb
2553 + * Tidied up spacing.
2554 + * Added macros for HMAC padding magic numbers.(kravietz)
2555 + *
2556 + * Revision 1.9 1999/12/07 18:16:23 rgb
2557 + * Fixed comments at end of #endif lines.
2558 + *
2559 + * Revision 1.8 1999/04/11 00:28:56 henry
2560 + * GPL boilerplate
2561 + *
2562 + * Revision 1.7 1999/04/06 04:54:25 rgb
2563 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
2564 + * patch shell fixes.
2565 + *
2566 + * Revision 1.6 1999/01/26 02:06:01 rgb
2567 + * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
2568 + *
2569 + * Revision 1.5 1999/01/22 06:17:49 rgb
2570 + * Updated macro comments.
2571 + * Added context types to support algorithm switch code.
2572 + * 64-bit clean-up -- converting 'u long long' to __u64.
2573 + *
2574 + * Revision 1.4 1998/07/14 15:54:56 rgb
2575 + * Add #ifdef __KERNEL__ to protect kernel-only structures.
2576 + *
2577 + * Revision 1.3 1998/06/30 18:05:16 rgb
2578 + * Comment out references to htonq.
2579 + *
2580 + * Revision 1.2 1998/06/25 19:33:46 rgb
2581 + * Add prototype for protocol receive function.
2582 + * Rearrange for more logical layout.
2583 + *
2584 + * Revision 1.1 1998/06/18 21:27:43 henry
2585 + * move sources from klips/src to klips/net/ipsec, to keep stupid
2586 + * kernel-build scripts happier in the presence of symlinks
2587 + *
2588 + * Revision 1.4 1998/05/18 22:28:43 rgb
2589 + * Disable key printing facilities from /proc/net/ipsec_*.
2590 + *
2591 + * Revision 1.3 1998/04/21 21:29:07 rgb
2592 + * Rearrange debug switches to change on the fly debug output from user
2593 + * space. Only kernel changes checked in at this time. radij.c was also
2594 + * changed to temporarily remove buggy debugging code in rj_delete causing
2595 + * an OOPS and hence, netlink device open errors.
2596 + *
2597 + * Revision 1.2 1998/04/12 22:03:17 rgb
2598 + * Updated ESP-3DES-HMAC-MD5-96,
2599 + * ESP-DES-HMAC-MD5-96,
2600 + * AH-HMAC-MD5-96,
2601 + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
2602 + * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
2603 + *
2604 + * Fixed eroute references in /proc/net/ipsec*.
2605 + *
2606 + * Started to patch module unloading memory leaks in ipsec_netlink and
2607 + * radij tree unloading.
2608 + *
2609 + * Revision 1.1 1998/04/09 03:05:55 henry
2610 + * sources moved up from linux/net/ipsec
2611 + *
2612 + * Revision 1.1.1.1 1998/04/08 05:35:02 henry
2613 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
2614 + *
2615 + * Revision 0.4 1997/01/15 01:28:15 ji
2616 + * Added definitions for new AH transforms.
2617 + *
2618 + * Revision 0.3 1996/11/20 14:35:48 ji
2619 + * Minor Cleanup.
2620 + * Rationalized debugging code.
2621 + *
2622 + * Revision 0.2 1996/11/02 00:18:33 ji
2623 + * First limited release.
2624 + *
2625 + *
2626 + */
2627 --- /dev/null Tue Mar 11 13:02:56 2003
2628 +++ linux/include/openswan/ipsec_alg.h Mon Feb 9 13:51:03 2004
2629 @@ -0,0 +1,248 @@
2630 +/*
2631 + * Modular extensions service and registration functions interface
2632 + *
2633 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
2634 + *
2635 + * ipsec_alg.h,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
2636 + *
2637 + */
2638 +/*
2639 + * This program is free software; you can redistribute it and/or modify it
2640 + * under the terms of the GNU General Public License as published by the
2641 + * Free Software Foundation; either version 2 of the License, or (at your
2642 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2643 + *
2644 + * This program is distributed in the hope that it will be useful, but
2645 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2646 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2647 + * for more details.
2648 + *
2649 + */
2650 +#ifndef IPSEC_ALG_H
2651 +#define IPSEC_ALG_H
2652 +
2653 +/*
2654 + * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__
2655 + * *BUT* its a compiler variable.
2656 + */
2657 +#if (__GNUC__ >= 3)
2658 +#ifndef __FUNCTION__
2659 +#define __FUNCTION__ __func__
2660 +#endif
2661 +#endif
2662 +
2663 +/* Version 0.8.1-0 */
2664 +#define IPSEC_ALG_VERSION 0x00080100
2665 +
2666 +#include <linux/types.h>
2667 +#include <linux/list.h>
2668 +#include <asm/atomic.h>
2669 +#include <pfkey.h>
2670 +
2671 +/*
2672 + * The following structs are used via pointers in ipsec_alg object to
2673 + * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying
2674 + * module development
2675 + */
2676 +struct ipsec_sa;
2677 +struct esp;
2678 +
2679 +/**************************************
2680 + *
2681 + * Main registration object
2682 + *
2683 + *************************************/
2684 +#define IPSEC_ALG_VERSION_QUAD(v) \
2685 + (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff)
2686 +/*
2687 + * Main ipsec_alg objects: "OOPrograming wannabe"
2688 + * Hierachy (carefully handled with _minimal_ cast'ing):
2689 + *
2690 + * ipsec_alg+
2691 + * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT)
2692 + * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH)
2693 + */
2694 +
2695 +/***************************************************************
2696 + *
2697 + * INTERFACE object: struct ipsec_alg
2698 + *
2699 + ***************************************************************/
2700 +
2701 +#define ixt_alg_type ixt_support.ias_exttype
2702 +#define ixt_alg_id ixt_support.ias_id
2703 +
2704 +#define IPSEC_ALG_ST_SUPP 0x01
2705 +#define IPSEC_ALG_ST_REGISTERED 0x02
2706 +#define IPSEC_ALG_ST_EXCL 0x04
2707 +struct ipsec_alg {
2708 + unsigned ixt_version; /* only allow this version (or 'near')*/ \
2709 + struct list_head ixt_list; /* dlinked list */ \
2710 + struct module *ixt_module; /* THIS_MODULE */ \
2711 + unsigned ixt_state; /* state flags */ \
2712 + atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \
2713 + char ixt_name[16]; /* descriptive short name, eg. "3des" */ \
2714 + void *ixt_data; /* private for algo implementation */ \
2715 + uint8_t ixt_blocksize; /* blocksize in bytes */ \
2716 +
2717 + struct ipsec_alg_supported ixt_support;
2718 +};
2719 +/*
2720 + * Note the const in cbc_encrypt IV arg:
2721 + * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy
2722 + */
2723 +struct ipsec_alg_enc {
2724 + struct ipsec_alg ixt_common;
2725 + unsigned ixt_e_keylen; /* raw key length in bytes */
2726 + unsigned ixt_e_ctx_size; /* sa_p->key_e_size */
2727 + int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize);
2728 + __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize);
2729 + void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e);
2730 + int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt);
2731 +};
2732 +struct ipsec_alg_auth {
2733 + struct ipsec_alg ixt_common;
2734 + unsigned ixt_a_keylen; /* raw key length in bytes */
2735 + unsigned ixt_a_ctx_size; /* sa_p->key_a_size */
2736 + unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */
2737 + int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen);
2738 + int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen);
2739 +};
2740 +/*
2741 + * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT},
2742 + * to avoid header coupling for true constants
2743 + * about headers ... "cp is your friend" --Linus
2744 + */
2745 +#define IPSEC_ALG_TYPE_AUTH 14
2746 +#define IPSEC_ALG_TYPE_ENCRYPT 15
2747 +
2748 +/***************************************************************
2749 + *
2750 + * INTERFACE for module loading,testing, and unloading
2751 + *
2752 + ***************************************************************/
2753 +/* - registration calls */
2754 +int register_ipsec_alg(struct ipsec_alg *);
2755 +int unregister_ipsec_alg(struct ipsec_alg *);
2756 +/* - optional (simple test) for algos */
2757 +int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm);
2758 +/* inline wrappers (usefull for type validation */
2759 +static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
2760 + return register_ipsec_alg((struct ipsec_alg*)ixt);
2761 +}
2762 +static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
2763 + return unregister_ipsec_alg((struct ipsec_alg*)ixt);
2764 +}
2765 +static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
2766 + return register_ipsec_alg((struct ipsec_alg*)ixt);
2767 +}
2768 +static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
2769 + return unregister_ipsec_alg((struct ipsec_alg*)ixt);
2770 +}
2771 +
2772 +/*****************************************************************
2773 + *
2774 + * INTERFACE for ENC services: key creation, encrypt function
2775 + *
2776 + *****************************************************************/
2777 +
2778 +#define IPSEC_ALG_ENCRYPT 1
2779 +#define IPSEC_ALG_DECRYPT 0
2780 +
2781 +/* encryption key context creation function */
2782 +int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p);
2783 +/*
2784 + * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns
2785 + * 0 or ERR<0
2786 + */
2787 +int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action);
2788 +
2789 +/***************************************************************
2790 + *
2791 + * INTERFACE for AUTH services: key creation, hash functions
2792 + *
2793 + ***************************************************************/
2794 +int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p);
2795 +int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ;
2796 +#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0)
2797 +
2798 +/* only called from ipsec_init.c */
2799 +int ipsec_alg_init(void);
2800 +
2801 +/* algo module glue for static algos */
2802 +void ipsec_alg_static_init(void);
2803 +typedef int (*ipsec_alg_init_func_t) (void);
2804 +
2805 +/**********************************************
2806 + *
2807 + * INTERFACE for ipsec_sa init and wipe
2808 + *
2809 + **********************************************/
2810 +
2811 +/* returns true if ipsec_sa has ipsec_alg obj attached */
2812 +/*
2813 + * Initializes ipsec_sa's ipsec_alg object, using already loaded
2814 + * proto, authalg, encalg.; links ipsec_alg objects (enc, auth)
2815 + */
2816 +int ipsec_alg_sa_init(struct ipsec_sa *sa_p);
2817 +/*
2818 + * Destroys ipsec_sa's ipsec_alg object
2819 + * unlinking ipsec_alg objects
2820 + */
2821 +int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p);
2822 +
2823 +#define IPSEC_ALG_MODULE_INIT_MOD( func_name ) \
2824 + static int func_name(void); \
2825 + module_init(func_name); \
2826 + static int __init func_name(void)
2827 +#define IPSEC_ALG_MODULE_EXIT_MOD( func_name ) \
2828 + static void func_name(void); \
2829 + module_exit(func_name); \
2830 + static void __exit func_name(void)
2831 +
2832 +#define IPSEC_ALG_MODULE_INIT_STATIC( func_name ) \
2833 + extern int func_name(void); \
2834 + int func_name(void)
2835 +#define IPSEC_ALG_MODULE_EXIT_STATIC( func_name ) \
2836 + extern void func_name(void); \
2837 + void func_name(void)
2838 +
2839 +/**********************************************
2840 + *
2841 + * 2.2 backport for some 2.4 useful module stuff
2842 + *
2843 + **********************************************/
2844 +#ifdef MODULE
2845 +#ifndef THIS_MODULE
2846 +#define THIS_MODULE (&__this_module)
2847 +#endif
2848 +#ifndef module_init
2849 +typedef int (*__init_module_func_t)(void);
2850 +typedef void (*__cleanup_module_func_t)(void);
2851 +
2852 +#define module_init(x) \
2853 + int init_module(void) __attribute__((alias(#x))); \
2854 + static inline __init_module_func_t __init_module_inline(void) \
2855 + { return x; }
2856 +#define module_exit(x) \
2857 + void cleanup_module(void) __attribute__((alias(#x))); \
2858 + static inline __cleanup_module_func_t __cleanup_module_inline(void) \
2859 + { return x; }
2860 +#endif
2861 +#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_MOD( func_name )
2862 +#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_MOD( func_name )
2863 +
2864 +#else /* not MODULE */
2865 +#ifndef THIS_MODULE
2866 +#define THIS_MODULE NULL
2867 +#endif
2868 +/*
2869 + * I only want module_init() magic
2870 + * when algo.c file *is THE MODULE*, in all other
2871 + * cases, initialization is called explicitely from ipsec_alg_init()
2872 + */
2873 +#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_STATIC(func_name)
2874 +#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_STATIC(func_name)
2875 +#endif
2876 +
2877 +#endif /* IPSEC_ALG_H */
2878 --- /dev/null Tue Mar 11 13:02:56 2003
2879 +++ linux/include/openswan/ipsec_alg_3des.h Mon Feb 9 13:51:03 2004
2880 @@ -0,0 +1,12 @@
2881 +struct TripleDES_context {
2882 + des_key_schedule s1;
2883 + des_key_schedule s2;
2884 + des_key_schedule s3;
2885 +};
2886 +typedef struct TripleDES_context TripleDES_context;
2887 +
2888 +#define ESP_3DES_KEY_SZ 3*(sizeof(des_cblock))
2889 +#define ESP_3DES_CBC_BLK_LEN 8
2890 +
2891 +
2892 +
2893 --- /dev/null Tue Mar 11 13:02:56 2003
2894 +++ linux/include/openswan/ipsec_auth.h Mon Feb 9 13:51:03 2004
2895 @@ -0,0 +1,100 @@
2896 +/*
2897 + * Authentication Header declarations
2898 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
2899 + *
2900 + * This program is free software; you can redistribute it and/or modify it
2901 + * under the terms of the GNU General Public License as published by the
2902 + * Free Software Foundation; either version 2 of the License, or (at your
2903 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
2904 + *
2905 + * This program is distributed in the hope that it will be useful, but
2906 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
2907 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
2908 + * for more details.
2909 + *
2910 + * RCSID $Id: ipsec_auth.h,v 1.3 2004/04/06 02:49:08 mcr Exp $
2911 + */
2912 +
2913 +#include "ipsec_md5h.h"
2914 +#include "ipsec_sha1.h"
2915 +
2916 +#ifndef IPSEC_AUTH_H
2917 +#define IPSEC_AUTH_H
2918 +
2919 +#define AH_FLENGTH 12 /* size of fixed part */
2920 +#define AHMD5_KMAX 64 /* MD5 max 512 bits key */
2921 +#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */
2922 +
2923 +#define AHMD596_KLEN 16 /* MD5 128 bits key */
2924 +#define AHSHA196_KLEN 20 /* SHA1 160 bits key */
2925 +
2926 +#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */
2927 +#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */
2928 +
2929 +#define AHMD596_BLKLEN 64 /* MD5 block length */
2930 +#define AHSHA196_BLKLEN 64 /* SHA1 block length */
2931 +#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */
2932 +#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */
2933 +#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */
2934 +
2935 +#define AH_BLKLEN_MAX 128 /* keep up to date! */
2936 +
2937 +
2938 +#define AH_AMAX AHSHA196_ALEN /* keep up to date! */
2939 +#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */
2940 +#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */
2941 +
2942 +#define DB_AH_PKTRX 0x0001
2943 +#define DB_AH_PKTRX2 0x0002
2944 +#define DB_AH_DMP 0x0004
2945 +#define DB_AH_IPSA 0x0010
2946 +#define DB_AH_XF 0x0020
2947 +#define DB_AH_INAU 0x0040
2948 +#define DB_AH_REPLAY 0x0100
2949 +
2950 +#ifdef __KERNEL__
2951 +
2952 +/* General HMAC algorithm is described in RFC 2104 */
2953 +
2954 +#define HMAC_IPAD 0x36
2955 +#define HMAC_OPAD 0x5C
2956 +
2957 +struct md5_ctx {
2958 + MD5_CTX ictx; /* context after H(K XOR ipad) */
2959 + MD5_CTX octx; /* context after H(K XOR opad) */
2960 +};
2961 +
2962 +struct sha1_ctx {
2963 + SHA1_CTX ictx; /* context after H(K XOR ipad) */
2964 + SHA1_CTX octx; /* context after H(K XOR opad) */
2965 +};
2966 +
2967 +struct auth_alg {
2968 + void (*init)(void *ctx);
2969 + void (*update)(void *ctx, unsigned char *bytes, __u32 len);
2970 + void (*final)(unsigned char *hash, void *ctx);
2971 + int hashlen;
2972 +};
2973 +
2974 +struct options;
2975 +
2976 +#endif /* __KERNEL__ */
2977 +#endif /* IPSEC_AUTH_H */
2978 +
2979 +/*
2980 + * $Log: ipsec_auth.h,v $
2981 + * Revision 1.3 2004/04/06 02:49:08 mcr
2982 + * pullup of algo code from alg-branch.
2983 + *
2984 + * Revision 1.2 2004/04/05 19:55:04 mcr
2985 + * Moved from linux/include/freeswan/ipsec_auth.h,v
2986 + *
2987 + * Revision 1.1 2003/12/13 19:10:16 mcr
2988 + * refactored rcv and xmit code - same as FS 2.05.
2989 + *
2990 + * Revision 1.1 2003/12/06 21:21:19 mcr
2991 + * split up receive path into per-transform files, for
2992 + * easier later removal.
2993 + *
2994 + *
2995 + */
2996 --- /dev/null Tue Mar 11 13:02:56 2003
2997 +++ linux/include/openswan/ipsec_encap.h Mon Feb 9 13:51:03 2004
2998 @@ -0,0 +1,149 @@
2999 +/*
3000 + * declarations relevant to encapsulation-like operations
3001 + * Copyright (C) 1996, 1997 John Ioannidis.
3002 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3003 + *
3004 + * This program is free software; you can redistribute it and/or modify it
3005 + * under the terms of the GNU General Public License as published by the
3006 + * Free Software Foundation; either version 2 of the License, or (at your
3007 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3008 + *
3009 + * This program is distributed in the hope that it will be useful, but
3010 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3011 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3012 + * for more details.
3013 + *
3014 + * RCSID $Id: ipsec_encap.h,v 1.19 2004/04/05 19:55:04 mcr Exp $
3015 + */
3016 +
3017 +#ifndef _IPSEC_ENCAP_H_
3018 +
3019 +#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/
3020 + /* (2 * sizeof(struct in_addr)) */
3021 + /* sizeof(struct sockaddr_encap)
3022 + - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
3023 +
3024 +struct sockaddr_encap
3025 +{
3026 + __u8 sen_len; /* length */
3027 + __u8 sen_family; /* AF_ENCAP */
3028 + __u16 sen_type; /* see SENT_* */
3029 + union
3030 + {
3031 + struct /* SENT_IP4 */
3032 + {
3033 + struct in_addr Src;
3034 + struct in_addr Dst;
3035 + __u8 Proto;
3036 + __u16 Sport;
3037 + __u16 Dport;
3038 + } Sip4;
3039 + } Sen;
3040 +};
3041 +
3042 +#define sen_ip_src Sen.Sip4.Src
3043 +#define sen_ip_dst Sen.Sip4.Dst
3044 +#define sen_proto Sen.Sip4.Proto
3045 +#define sen_sport Sen.Sip4.Sport
3046 +#define sen_dport Sen.Sip4.Dport
3047 +
3048 +#ifndef AF_ENCAP
3049 +#define AF_ENCAP 26
3050 +#endif /* AF_ENCAP */
3051 +
3052 +#define _IPSEC_ENCAP_H_
3053 +#endif /* _IPSEC_ENCAP_H_ */
3054 +
3055 +/*
3056 + * $Log: ipsec_encap.h,v $
3057 + * Revision 1.19 2004/04/05 19:55:04 mcr
3058 + * Moved from linux/include/freeswan/ipsec_encap.h,v
3059 + *
3060 + * Revision 1.18 2003/10/31 02:27:05 mcr
3061 + * pulled up port-selector patches and sa_id elimination.
3062 + *
3063 + * Revision 1.17.30.1 2003/09/21 13:59:38 mcr
3064 + * pre-liminary X.509 patch - does not yet pass tests.
3065 + *
3066 + * Revision 1.17 2002/04/24 07:36:46 mcr
3067 + * Moved from ./klips/net/ipsec/ipsec_encap.h,v
3068 + *
3069 + * Revision 1.16 2001/11/26 09:23:47 rgb
3070 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3071 + *
3072 + * Revision 1.15.2.1 2001/09/25 02:18:54 mcr
3073 + * struct eroute moved to ipsec_eroute.h
3074 + *
3075 + * Revision 1.15 2001/09/14 16:58:36 rgb
3076 + * Added support for storing the first and last packets through a HOLD.
3077 + *
3078 + * Revision 1.14 2001/09/08 21:13:31 rgb
3079 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
3080 + *
3081 + * Revision 1.13 2001/06/14 19:35:08 rgb
3082 + * Update copyright date.
3083 + *
3084 + * Revision 1.12 2001/05/27 06:12:10 rgb
3085 + * Added structures for pid, packet count and last access time to eroute.
3086 + * Added packet count to beginning of /proc/net/ipsec_eroute.
3087 + *
3088 + * Revision 1.11 2000/09/08 19:12:56 rgb
3089 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3090 + *
3091 + * Revision 1.10 2000/03/22 16:15:36 rgb
3092 + * Fixed renaming of dev_get (MB).
3093 + *
3094 + * Revision 1.9 2000/01/21 06:13:26 rgb
3095 + * Added a macro for AF_ENCAP
3096 + *
3097 + * Revision 1.8 1999/12/31 14:56:55 rgb
3098 + * MB fix for 2.3 dev-use-count.
3099 + *
3100 + * Revision 1.7 1999/11/18 04:09:18 rgb
3101 + * Replaced all kernel version macros to shorter, readable form.
3102 + *
3103 + * Revision 1.6 1999/09/24 00:34:13 rgb
3104 + * Add Marc Boucher's support for 2.3.xx+.
3105 + *
3106 + * Revision 1.5 1999/04/11 00:28:57 henry
3107 + * GPL boilerplate
3108 + *
3109 + * Revision 1.4 1999/04/06 04:54:25 rgb
3110 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3111 + * patch shell fixes.
3112 + *
3113 + * Revision 1.3 1998/10/19 14:44:28 rgb
3114 + * Added inclusion of freeswan.h.
3115 + * sa_id structure implemented and used: now includes protocol.
3116 + *
3117 + * Revision 1.2 1998/07/14 18:19:33 rgb
3118 + * Added #ifdef __KERNEL__ directives to restrict scope of header.
3119 + *
3120 + * Revision 1.1 1998/06/18 21:27:44 henry
3121 + * move sources from klips/src to klips/net/ipsec, to keep stupid
3122 + * kernel-build scripts happier in the presence of symlinks
3123 + *
3124 + * Revision 1.2 1998/04/21 21:29:10 rgb
3125 + * Rearrange debug switches to change on the fly debug output from user
3126 + * space. Only kernel changes checked in at this time. radij.c was also
3127 + * changed to temporarily remove buggy debugging code in rj_delete causing
3128 + * an OOPS and hence, netlink device open errors.
3129 + *
3130 + * Revision 1.1 1998/04/09 03:05:58 henry
3131 + * sources moved up from linux/net/ipsec
3132 + *
3133 + * Revision 1.1.1.1 1998/04/08 05:35:02 henry
3134 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3135 + *
3136 + * Revision 0.4 1997/01/15 01:28:15 ji
3137 + * Minor cosmetic changes.
3138 + *
3139 + * Revision 0.3 1996/11/20 14:35:48 ji
3140 + * Minor Cleanup.
3141 + * Rationalized debugging code.
3142 + *
3143 + * Revision 0.2 1996/11/02 00:18:33 ji
3144 + * First limited release.
3145 + *
3146 + *
3147 + */
3148 --- /dev/null Tue Mar 11 13:02:56 2003
3149 +++ linux/include/openswan/ipsec_eroute.h Mon Feb 9 13:51:03 2004
3150 @@ -0,0 +1,112 @@
3151 +/*
3152 + * @(#) declarations of eroute structures
3153 + *
3154 + * Copyright (C) 1996, 1997 John Ioannidis.
3155 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
3156 + * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org>
3157 + *
3158 + * This program is free software; you can redistribute it and/or modify it
3159 + * under the terms of the GNU General Public License as published by the
3160 + * Free Software Foundation; either version 2 of the License, or (at your
3161 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3162 + *
3163 + * This program is distributed in the hope that it will be useful, but
3164 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3165 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3166 + * for more details.
3167 + *
3168 + * RCSID $Id: ipsec_eroute.h,v 1.5 2004/04/05 19:55:05 mcr Exp $
3169 + *
3170 + * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
3171 + *
3172 + */
3173 +
3174 +#ifndef _IPSEC_EROUTE_H_
3175 +
3176 +#include "radij.h"
3177 +#include "ipsec_encap.h"
3178 +#include "ipsec_radij.h"
3179 +
3180 +/*
3181 + * The "type" is really part of the address as far as the routing
3182 + * system is concerned. By using only one bit in the type field
3183 + * for each type, we sort-of make sure that different types of
3184 + * encapsulation addresses won't be matched against the wrong type.
3185 + */
3186 +
3187 +/*
3188 + * An entry in the radix tree
3189 + */
3190 +
3191 +struct rjtentry
3192 +{
3193 + struct radij_node rd_nodes[2]; /* tree glue, and other values */
3194 +#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
3195 +#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
3196 + short rd_flags;
3197 + short rd_count;
3198 +};
3199 +
3200 +struct ident
3201 +{
3202 + __u16 type; /* identity type */
3203 + __u64 id; /* identity id */
3204 + __u8 len; /* identity len */
3205 + caddr_t data; /* identity data */
3206 +};
3207 +
3208 +/*
3209 + * An encapsulation route consists of a pointer to a
3210 + * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
3211 + */
3212 +
3213 +struct eroute
3214 +{
3215 + struct rjtentry er_rjt;
3216 + ip_said er_said;
3217 + uint32_t er_pid;
3218 + uint32_t er_count;
3219 + uint64_t er_lasttime;
3220 + struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
3221 + struct sockaddr_encap er_emask;
3222 + struct ident er_ident_s;
3223 + struct ident er_ident_d;
3224 + struct sk_buff* er_first;
3225 + struct sk_buff* er_last;
3226 +};
3227 +
3228 +#define er_dst er_said.dst
3229 +#define er_spi er_said.spi
3230 +
3231 +#define _IPSEC_EROUTE_H_
3232 +#endif /* _IPSEC_EROUTE_H_ */
3233 +
3234 +/*
3235 + * $Log: ipsec_eroute.h,v $
3236 + * Revision 1.5 2004/04/05 19:55:05 mcr
3237 + * Moved from linux/include/freeswan/ipsec_eroute.h,v
3238 + *
3239 + * Revision 1.4 2003/10/31 02:27:05 mcr
3240 + * pulled up port-selector patches and sa_id elimination.
3241 + *
3242 + * Revision 1.3.30.2 2003/10/29 01:10:19 mcr
3243 + * elimited "struct sa_id"
3244 + *
3245 + * Revision 1.3.30.1 2003/09/21 13:59:38 mcr
3246 + * pre-liminary X.509 patch - does not yet pass tests.
3247 + *
3248 + * Revision 1.3 2002/04/24 07:36:46 mcr
3249 + * Moved from ./klips/net/ipsec/ipsec_eroute.h,v
3250 + *
3251 + * Revision 1.2 2001/11/26 09:16:13 rgb
3252 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3253 + *
3254 + * Revision 1.1.2.1 2001/09/25 02:18:54 mcr
3255 + * struct eroute moved to ipsec_eroute.h
3256 + *
3257 + *
3258 + * Local variables:
3259 + * c-file-style: "linux"
3260 + * End:
3261 + *
3262 + */
3263 --- /dev/null Tue Mar 11 13:02:56 2003
3264 +++ linux/include/openswan/ipsec_errs.h Mon Feb 9 13:51:03 2004
3265 @@ -0,0 +1,53 @@
3266 +/*
3267 + * @(#) definition of ipsec_errs structure
3268 + *
3269 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
3270 + * and Michael Richardson <mcr@freeswan.org>
3271 + *
3272 + * This program is free software; you can redistribute it and/or modify it
3273 + * under the terms of the GNU General Public License as published by the
3274 + * Free Software Foundation; either version 2 of the License, or (at your
3275 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3276 + *
3277 + * This program is distributed in the hope that it will be useful, but
3278 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3279 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3280 + * for more details.
3281 + *
3282 + * RCSID $Id: ipsec_errs.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
3283 + *
3284 + */
3285 +
3286 +/*
3287 + * This file describes the errors/statistics that FreeSWAN collects.
3288 + *
3289 + */
3290 +
3291 +struct ipsec_errs {
3292 + __u32 ips_alg_errs; /* number of algorithm errors */
3293 + __u32 ips_auth_errs; /* # of authentication errors */
3294 + __u32 ips_encsize_errs; /* # of encryption size errors*/
3295 + __u32 ips_encpad_errs; /* # of encryption pad errors*/
3296 + __u32 ips_replaywin_errs; /* # of pkt sequence errors */
3297 +};
3298 +
3299 +/*
3300 + * $Log: ipsec_errs.h,v $
3301 + * Revision 1.4 2004/04/05 19:55:05 mcr
3302 + * Moved from linux/include/freeswan/ipsec_errs.h,v
3303 + *
3304 + * Revision 1.3 2002/04/24 07:36:46 mcr
3305 + * Moved from ./klips/net/ipsec/ipsec_errs.h,v
3306 + *
3307 + * Revision 1.2 2001/11/26 09:16:13 rgb
3308 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3309 + *
3310 + * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
3311 + * lifetime structure created and common functions created.
3312 + *
3313 + *
3314 + * Local variables:
3315 + * c-file-style: "linux"
3316 + * End:
3317 + *
3318 + */
3319 --- /dev/null Tue Mar 11 13:02:56 2003
3320 +++ linux/include/openswan/ipsec_esp.h Mon Feb 9 13:51:03 2004
3321 @@ -0,0 +1,157 @@
3322 +/*
3323 + * Copyright (C) 1996, 1997 John Ioannidis.
3324 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3325 + *
3326 + * This program is free software; you can redistribute it and/or modify it
3327 + * under the terms of the GNU General Public License as published by the
3328 + * Free Software Foundation; either version 2 of the License, or (at your
3329 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3330 + *
3331 + * This program is distributed in the hope that it will be useful, but
3332 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3333 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3334 + * for more details.
3335 + *
3336 + * RCSID $Id: ipsec_esp.h,v 1.28 2004/09/13 02:22:10 mcr Exp $
3337 + */
3338 +
3339 +#include "openswan/ipsec_md5h.h"
3340 +#include "openswan/ipsec_sha1.h"
3341 +
3342 +#include "crypto/des.h"
3343 +
3344 +#ifndef IPPROTO_ESP
3345 +#define IPPROTO_ESP 50
3346 +#endif /* IPPROTO_ESP */
3347 +
3348 +#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/
3349 +
3350 +#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */
3351 +#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */
3352 +#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */
3353 +#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */
3354 +#define EMT_ESPDES_IV_SZ 8 /* IV size */
3355 +#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */
3356 +
3357 +#define ESP_IV_MAXSZ 16 /* This is _critical_ */
3358 +#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int))
3359 +
3360 +#define DB_ES_PKTRX 0x0001
3361 +#define DB_ES_PKTRX2 0x0002
3362 +#define DB_ES_IPSA 0x0010
3363 +#define DB_ES_XF 0x0020
3364 +#define DB_ES_IPAD 0x0040
3365 +#define DB_ES_INAU 0x0080
3366 +#define DB_ES_OINFO 0x0100
3367 +#define DB_ES_OINFO2 0x0200
3368 +#define DB_ES_OH 0x0400
3369 +#define DB_ES_REPLAY 0x0800
3370 +
3371 +#ifdef __KERNEL__
3372 +struct des_eks {
3373 + des_key_schedule ks;
3374 +};
3375 +
3376 +extern struct inet_protocol esp_protocol;
3377 +
3378 +struct options;
3379 +
3380 +struct esphdr
3381 +{
3382 + __u32 esp_spi; /* Security Parameters Index */
3383 + __u32 esp_rpl; /* Replay counter */
3384 + __u8 esp_iv[8]; /* iv */
3385 +};
3386 +
3387 +extern struct xform_functions esp_xform_funcs[];
3388 +
3389 +#ifdef CONFIG_KLIPS_DEBUG
3390 +extern int debug_esp;
3391 +#endif /* CONFIG_KLIPS_DEBUG */
3392 +#endif /* __KERNEL__ */
3393 +
3394 +/*
3395 + * $Log: ipsec_esp.h,v $
3396 + * Revision 1.28 2004/09/13 02:22:10 mcr
3397 + * #define inet_protocol if necessary.
3398 + *
3399 + * Revision 1.27 2004/09/06 18:35:41 mcr
3400 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
3401 + * so adjust for that.
3402 + *
3403 + * Revision 1.26 2004/07/10 19:08:41 mcr
3404 + * CONFIG_IPSEC -> CONFIG_KLIPS.
3405 + *
3406 + * Revision 1.25 2004/04/06 02:49:08 mcr
3407 + * pullup of algo code from alg-branch.
3408 + *
3409 + * Revision 1.24 2004/04/05 19:55:05 mcr
3410 + * Moved from linux/include/freeswan/ipsec_esp.h,v
3411 + *
3412 + * Revision 1.23 2004/04/05 19:41:05 mcr
3413 + * merged alg-branch code.
3414 + *
3415 + * Revision 1.22 2003/12/13 19:10:16 mcr
3416 + * refactored rcv and xmit code - same as FS 2.05.
3417 + *
3418 + * Revision 1.23 2003/12/11 20:14:58 mcr
3419 + * refactored the xmit code, to move all encapsulation
3420 + * code into protocol functions. Note that all functions
3421 + * are essentially done by a single function, which is probably
3422 + * wrong.
3423 + * the rcv_functions structures are renamed xform_functions.
3424 + *
3425 + * Revision 1.22 2003/12/06 21:21:19 mcr
3426 + * split up receive path into per-transform files, for
3427 + * easier later removal.
3428 + *
3429 + * Revision 1.21.8.1 2003/12/22 15:25:52 jjo
3430 + * Merged algo-0.8.1-rc11-test1 into alg-branch
3431 + *
3432 + * Revision 1.21 2003/02/06 02:21:34 rgb
3433 + *
3434 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
3435 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
3436 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
3437 + *
3438 + * Revision 1.20 2002/05/14 02:37:02 rgb
3439 + * Change reference from _TDB to _IPSA.
3440 + *
3441 + * Revision 1.19 2002/04/24 07:55:32 mcr
3442 + * #include patches and Makefiles for post-reorg compilation.
3443 + *
3444 + * Revision 1.18 2002/04/24 07:36:46 mcr
3445 + * Moved from ./klips/net/ipsec/ipsec_esp.h,v
3446 + *
3447 + * Revision 1.17 2002/02/20 01:27:07 rgb
3448 + * Ditched a pile of structs only used by the old Netlink interface.
3449 + *
3450 + * Revision 1.16 2001/12/11 02:35:57 rgb
3451 + * Change "struct net_device" to "struct device" for 2.2 compatibility.
3452 + *
3453 + * Revision 1.15 2001/11/26 09:23:48 rgb
3454 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
3455 + *
3456 + * Revision 1.14.2.3 2001/10/23 04:16:42 mcr
3457 + * get definition of des_key_schedule from des.h
3458 + *
3459 + * Revision 1.14.2.2 2001/10/22 20:33:13 mcr
3460 + * use "des_key_schedule" structure instead of cooking our own.
3461 + *
3462 + * Revision 1.14.2.1 2001/09/25 02:18:25 mcr
3463 + * replace "struct device" with "struct netdevice"
3464 + *
3465 + * Revision 1.14 2001/06/14 19:35:08 rgb
3466 + * Update copyright date.
3467 + *
3468 + * Revision 1.13 2000/09/08 19:12:56 rgb
3469 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
3470 + *
3471 + * Revision 1.12 2000/08/01 14:51:50 rgb
3472 + * Removed _all_ remaining traces of DES.
3473 + *
3474 + * Revision 1.11 2000/01/10 16:36:20 rgb
3475 + * Ditch last of EME option flags, including initiator.
3476 + *
3477 + *
3478 + */
3479 --- /dev/null Tue Mar 11 13:02:56 2003
3480 +++ linux/include/openswan/ipsec_ipcomp.h Mon Feb 9 13:51:03 2004
3481 @@ -0,0 +1,94 @@
3482 +/*
3483 + * IP compression header declations
3484 + *
3485 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3486 + *
3487 + * This program is free software; you can redistribute it and/or modify it
3488 + * under the terms of the GNU General Public License as published by the
3489 + * Free Software Foundation; either version 2 of the License, or (at your
3490 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3491 + *
3492 + * This program is distributed in the hope that it will be useful, but
3493 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3494 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3495 + * for more details.
3496 + *
3497 + * RCSID $Id: ipsec_ipcomp.h,v 1.4 2004/07/10 19:08:41 mcr Exp $
3498 + */
3499 +
3500 +#ifndef IPSEC_IPCOMP_H
3501 +#define IPSEC_IPCOMP_H
3502 +
3503 +#include "openswan/ipsec_auth.h"
3504 +
3505 +/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
3506 +#ifndef IPCOMP_PREFIX
3507 +#define IPCOMP_PREFIX
3508 +#endif /* IPCOMP_PREFIX */
3509 +
3510 +#ifndef IPPROTO_COMP
3511 +#define IPPROTO_COMP 108
3512 +#endif /* IPPROTO_COMP */
3513 +
3514 +#ifdef CONFIG_KLIPS_DEBUG
3515 +extern int sysctl_ipsec_debug_ipcomp;
3516 +#endif /* CONFIG_KLIPS_DEBUG */
3517 +
3518 +struct ipcomphdr { /* IPCOMP header */
3519 + __u8 ipcomp_nh; /* Next header (protocol) */
3520 + __u8 ipcomp_flags; /* Reserved, must be 0 */
3521 + __u16 ipcomp_cpi; /* Compression Parameter Index */
3522 +};
3523 +
3524 +extern struct inet_protocol comp_protocol;
3525 +extern int sysctl_ipsec_debug_ipcomp;
3526 +
3527 +#define IPCOMP_UNCOMPRESSABLE 0x000000001
3528 +#define IPCOMP_COMPRESSIONERROR 0x000000002
3529 +#define IPCOMP_PARMERROR 0x000000004
3530 +#define IPCOMP_DECOMPRESSIONERROR 0x000000008
3531 +
3532 +#define IPCOMP_ADAPT_INITIAL_TRIES 8
3533 +#define IPCOMP_ADAPT_INITIAL_SKIP 4
3534 +#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
3535 +#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
3536 +
3537 +/* Function prototypes */
3538 +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
3539 +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
3540 +
3541 +extern struct xform_functions ipcomp_xform_funcs[];
3542 +
3543 +#endif /* IPSEC_IPCOMP_H */
3544 +
3545 +/*
3546 + * $Log: ipsec_ipcomp.h,v $
3547 + * Revision 1.4 2004/07/10 19:08:41 mcr
3548 + * CONFIG_IPSEC -> CONFIG_KLIPS.
3549 + *
3550 + * Revision 1.3 2004/04/06 02:49:08 mcr
3551 + * pullup of algo code from alg-branch.
3552 + *
3553 + * Revision 1.2 2004/04/05 19:55:05 mcr
3554 + * Moved from linux/include/freeswan/ipsec_ipcomp.h,v
3555 + *
3556 + * Revision 1.1 2003/12/13 19:10:16 mcr
3557 + * refactored rcv and xmit code - same as FS 2.05.
3558 + *
3559 + * Revision 1.2 2003/12/11 20:14:58 mcr
3560 + * refactored the xmit code, to move all encapsulation
3561 + * code into protocol functions. Note that all functions
3562 + * are essentially done by a single function, which is probably
3563 + * wrong.
3564 + * the rcv_functions structures are renamed xform_functions.
3565 + *
3566 + * Revision 1.1 2003/12/06 21:21:19 mcr
3567 + * split up receive path into per-transform files, for
3568 + * easier later removal.
3569 + *
3570 + *
3571 + *
3572 + */
3573 +
3574 +
3575 +
3576 --- /dev/null Tue Mar 11 13:02:56 2003
3577 +++ linux/include/openswan/ipsec_ipe4.h Mon Feb 9 13:51:03 2004
3578 @@ -0,0 +1,68 @@
3579 +/*
3580 + * IP-in-IP Header declarations
3581 + * Copyright (C) 1996, 1997 John Ioannidis.
3582 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
3583 + *
3584 + * This program is free software; you can redistribute it and/or modify it
3585 + * under the terms of the GNU General Public License as published by the
3586 + * Free Software Foundation; either version 2 of the License, or (at your
3587 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3588 + *
3589 + * This program is distributed in the hope that it will be useful, but
3590 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3591 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3592 + * for more details.
3593 + *
3594 + * RCSID $Id: ipsec_ipe4.h,v 1.6 2004/04/05 19:55:05 mcr Exp $
3595 + */
3596 +
3597 +/* The packet header is an IP header! */
3598 +
3599 +struct ipe4_xdata /* transform table data */
3600 +{
3601 + struct in_addr i4_src;
3602 + struct in_addr i4_dst;
3603 +};
3604 +
3605 +#define EMT_IPE4_ULEN 8 /* coming from user mode */
3606 +
3607 +
3608 +/*
3609 + * $Log: ipsec_ipe4.h,v $
3610 + * Revision 1.6 2004/04/05 19:55:05 mcr
3611 + * Moved from linux/include/freeswan/ipsec_ipe4.h,v
3612 + *
3613 + * Revision 1.5 2002/04/24 07:36:46 mcr
3614 + * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v
3615 + *
3616 + * Revision 1.4 2001/06/14 19:35:08 rgb
3617 + * Update copyright date.
3618 + *
3619 + * Revision 1.3 1999/04/11 00:28:57 henry
3620 + * GPL boilerplate
3621 + *
3622 + * Revision 1.2 1999/04/06 04:54:25 rgb
3623 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
3624 + * patch shell fixes.
3625 + *
3626 + * Revision 1.1 1998/06/18 21:27:47 henry
3627 + * move sources from klips/src to klips/net/ipsec, to keep stupid
3628 + * kernel-build scripts happier in the presence of symlinks
3629 + *
3630 + * Revision 1.1 1998/04/09 03:06:07 henry
3631 + * sources moved up from linux/net/ipsec
3632 + *
3633 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
3634 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
3635 + *
3636 + * Revision 0.4 1997/01/15 01:28:15 ji
3637 + * No changes.
3638 + *
3639 + * Revision 0.3 1996/11/20 14:48:53 ji
3640 + * Release update only.
3641 + *
3642 + * Revision 0.2 1996/11/02 00:18:33 ji
3643 + * First limited release.
3644 + *
3645 + *
3646 + */
3647 --- /dev/null Tue Mar 11 13:02:56 2003
3648 +++ linux/include/openswan/ipsec_ipip.h Mon Feb 9 13:51:03 2004
3649 @@ -0,0 +1,45 @@
3650 +/*
3651 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3652 + *
3653 + * This program is free software; you can redistribute it and/or modify it
3654 + * under the terms of the GNU General Public License as published by the
3655 + * Free Software Foundation; either version 2 of the License, or (at your
3656 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3657 + *
3658 + * This program is distributed in the hope that it will be useful, but
3659 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3660 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3661 + * for more details.
3662 + *
3663 + * RCSID $Id: ipsec_ipip.h,v 1.2 2004/04/05 19:55:05 mcr Exp $
3664 + */
3665 +
3666 +#ifndef _IPSEC_IPIP_H_
3667 +
3668 +#ifndef IPPROTO_IPIP
3669 +#define IPPROTO_IPIP 4
3670 +#endif /* IPPROTO_ESP */
3671 +
3672 +extern struct xform_functions ipip_xform_funcs[];
3673 +
3674 +#define _IPSEC_IPIP_H_
3675 +
3676 +#endif /* _IPSEC_IPIP_H_ */
3677 +
3678 +/*
3679 + * $Log: ipsec_ipip.h,v $
3680 + * Revision 1.2 2004/04/05 19:55:05 mcr
3681 + * Moved from linux/include/freeswan/ipsec_ipip.h,v
3682 + *
3683 + * Revision 1.1 2003/12/13 19:10:16 mcr
3684 + * refactored rcv and xmit code - same as FS 2.05.
3685 + *
3686 + * Revision 1.1 2003/12/11 20:14:58 mcr
3687 + * refactored the xmit code, to move all encapsulation
3688 + * code into protocol functions. Note that all functions
3689 + * are essentially done by a single function, which is probably
3690 + * wrong.
3691 + * the rcv_functions structures are renamed xform_functions.
3692 + *
3693 + *
3694 + */
3695 --- /dev/null Tue Mar 11 13:02:56 2003
3696 +++ linux/include/openswan/ipsec_kern24.h Mon Feb 9 13:51:03 2004
3697 @@ -0,0 +1,61 @@
3698 +/*
3699 + * @(#) routines to makes kernel 2.4 compatible with 2.6 usage.
3700 + *
3701 + * Copyright (C) 2004 Michael Richardson <mcr@sandelman.ottawa.on.ca>
3702 + *
3703 + * This program is free software; you can redistribute it and/or modify it
3704 + * under the terms of the GNU General Public License as published by the
3705 + * Free Software Foundation; either version 2 of the License, or (at your
3706 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
3707 + *
3708 + * This program is distributed in the hope that it will be useful, but
3709 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3710 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
3711 + * for more details.
3712 + *
3713 + * RCSID $Id: ipsec_kern24.h,v 1.4 2005/05/20 03:19:18 mcr Exp $
3714 + */
3715 +
3716 +#ifndef _IPSEC_KERN24_H
3717 +
3718 +#ifndef NET_26
3719 +#define sk_receive_queue receive_queue
3720 +#define sk_destruct destruct
3721 +#define sk_reuse reuse
3722 +#define sk_zapped zapped
3723 +#define sk_family family
3724 +#define sk_protocol protocol
3725 +#define sk_protinfo protinfo
3726 +#define sk_sleep sleep
3727 +#define sk_state_change state_change
3728 +#define sk_shutdown shutdown
3729 +#define sk_err err
3730 +#define sk_stamp stamp
3731 +#define sk_socket socket
3732 +#define sk_sndbuf sndbuf
3733 +#define sock_flag(sk, flag) sk->dead
3734 +#define sk_for_each(sk, node, plist) for(sk=*plist; sk!=NULL; sk = sk->next)
3735 +#endif
3736 +
3737 +/* deal with 2.4 vs 2.6 issues with module counts */
3738 +
3739 +/* in 2.6, all refcounts are maintained *outside* of the
3740 + * module to deal with race conditions.
3741 + */
3742 +
3743 +#ifdef NET_26
3744 +#define KLIPS_INC_USE /* nothing */
3745 +#define KLIPS_DEC_USE /* nothing */
3746 +
3747 +#else
3748 +#define KLIPS_INC_USE MOD_INC_USE_COUNT
3749 +#define KLIPS_DEC_USE MOD_DEC_USE_COUNT
3750 +#endif
3751 +
3752 +extern int printk_ratelimit(void);
3753 +
3754 +
3755 +#define _IPSEC_KERN24_H 1
3756 +
3757 +#endif /* _IPSEC_KERN24_H */
3758 +
3759 --- /dev/null Tue Mar 11 13:02:56 2003
3760 +++ linux/include/openswan/ipsec_kversion.h Mon Feb 9 13:51:03 2004
3761 @@ -0,0 +1,352 @@
3762 +#ifndef _OPENSWAN_KVERSIONS_H
3763 +/*
3764 + * header file for FreeS/WAN library functions
3765 + * Copyright (C) 1998, 1999, 2000 Henry Spencer.
3766 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
3767 + *
3768 + * This library is free software; you can redistribute it and/or modify it
3769 + * under the terms of the GNU Library General Public License as published by
3770 + * the Free Software Foundation; either version 2 of the License, or (at your
3771 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
3772 + *
3773 + * This library is distributed in the hope that it will be useful, but
3774 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3775 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
3776 + * License for more details.
3777 + *
3778 + * RCSID $Id: ipsec_kversion.h,v 1.15.2.11 2007/02/20 03:53:16 paul Exp $
3779 + */
3780 +#define _OPENSWAN_KVERSIONS_H /* seen it, no need to see it again */
3781 +
3782 +/*
3783 + * this file contains a series of atomic defines that depend upon
3784 + * kernel version numbers. The kernel versions are arranged
3785 + * in version-order number (which is often not chronological)
3786 + * and each clause enables or disables a feature.
3787 + */
3788 +
3789 +/*
3790 + * First, assorted kernel-version-dependent trickery.
3791 + */
3792 +#include <linux/version.h>
3793 +#ifndef KERNEL_VERSION
3794 +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
3795 +#endif
3796 +
3797 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
3798 +#define HEADER_CACHE_BIND_21
3799 +#error "KLIPS is no longer supported on Linux 2.0. Sorry"
3800 +#endif
3801 +
3802 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
3803 +#define SPINLOCK
3804 +#define PROC_FS_21
3805 +#define NETLINK_SOCK
3806 +#define NET_21
3807 +#endif
3808 +
3809 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
3810 +#define net_device_stats enet_statistics
3811 +#endif
3812 +
3813 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
3814 +#define SPINLOCK_23
3815 +#define NETDEV_23
3816 +# ifndef CONFIG_IP_ALIAS
3817 +# define CONFIG_IP_ALIAS
3818 +# endif
3819 +#include <linux/socket.h>
3820 +#include <linux/skbuff.h>
3821 +#include <linux/netlink.h>
3822 +# ifdef NETLINK_XFRM
3823 +# define NETDEV_25
3824 +# endif
3825 +#endif
3826 +
3827 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
3828 +#define PROC_FS_2325
3829 +#undef PROC_FS_21
3830 +#endif
3831 +
3832 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
3833 +#define PROC_NO_DUMMY
3834 +#endif
3835 +
3836 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
3837 +#define SKB_COPY_EXPAND
3838 +#endif
3839 +
3840 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
3841 +#define IP_SELECT_IDENT
3842 +#endif
3843 +
3844 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
3845 +#define SKB_RESET_NFCT
3846 +#endif
3847 +
3848 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
3849 +#define IP_SELECT_IDENT_NEW
3850 +#endif
3851 +
3852 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
3853 +#define IPH_is_SKB_PULLED
3854 +#define SKB_COW_NEW
3855 +#define PROTO_HANDLER_SINGLE_PARM
3856 +#define IP_FRAGMENT_LINEARIZE 1
3857 +#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3858 +# ifdef REDHAT_BOGOSITY
3859 +# define IP_SELECT_IDENT_NEW
3860 +# define IPH_is_SKB_PULLED
3861 +# define SKB_COW_NEW
3862 +# define PROTO_HANDLER_SINGLE_PARM
3863 +# endif /* REDHAT_BOGOSITY */
3864 +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
3865 +
3866 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
3867 +#define MALLOC_SLAB
3868 +#define LINUX_KERNEL_HAS_SNPRINTF
3869 +#endif
3870 +
3871 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
3872 +#define HAVE_NETDEV_PRINTK 1
3873 +#define NET_26
3874 +#endif
3875 +
3876 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
3877 +#define NEED_INET_PROTOCOL
3878 +#endif
3879 +
3880 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
3881 +#define HAVE_SOCK_ZAPPED
3882 +#define NET_26_12_SKALLOC
3883 +#endif
3884 +
3885 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
3886 +#define HAVE_SOCK_SECURITY
3887 +/* skb->nf_debug disappared completely in 2.6.13 */
3888 +#define HAVE_SKB_NF_DEBUG
3889 +#endif
3890 +
3891 +#define SYSCTL_IPSEC_DEFAULT_TTL sysctl_ip_default_ttl
3892 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14)
3893 +/* skb->stamp changed to skb->tstamp in 2.6.14 */
3894 +#define HAVE_TSTAMP
3895 +#define HAVE_INET_SK_SPORT
3896 +#undef SYSCTL_IPSEC_DEFAULT_TTL
3897 +#define SYSCTL_IPSEC_DEFAULT_TTL IPSEC_DEFAULT_TTL
3898 +#else
3899 +#define HAVE_SKB_LIST
3900 +#endif
3901 +
3902 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
3903 +#define HAVE_NEW_SKB_LINEARIZE
3904 +#endif
3905 +
3906 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3907 +/* skb->nfmark changed to skb->mark in 2.6.20 */
3908 +#define nfmark mark
3909 +#endif
3910 +
3911 +#ifdef NET_21
3912 +# include <linux/in6.h>
3913 +#else
3914 + /* old kernel in.h has some IPv6 stuff, but not quite enough */
3915 +# define s6_addr16 s6_addr
3916 +# define AF_INET6 10
3917 +# define uint8_t __u8
3918 +# define uint16_t __u16
3919 +# define uint32_t __u32
3920 +# define uint64_t __u64
3921 +#endif
3922 +
3923 +#ifdef NET_21
3924 +# define ipsec_kfree_skb(a) kfree_skb(a)
3925 +#else /* NET_21 */
3926 +# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
3927 +#endif /* NET_21 */
3928 +
3929 +#ifdef NETDEV_23
3930 +#if 0
3931 +#ifndef NETDEV_25
3932 +#define device net_device
3933 +#endif
3934 +#endif
3935 +# define ipsec_dev_get dev_get_by_name
3936 +# define __ipsec_dev_get __dev_get_by_name
3937 +# define ipsec_dev_put(x) dev_put(x)
3938 +# define __ipsec_dev_put(x) __dev_put(x)
3939 +# define ipsec_dev_hold(x) dev_hold(x)
3940 +#else /* NETDEV_23 */
3941 +# define ipsec_dev_get dev_get
3942 +# define __ipsec_dev_put(x)
3943 +# define ipsec_dev_put(x)
3944 +# define ipsec_dev_hold(x)
3945 +#endif /* NETDEV_23 */
3946 +
3947 +#ifndef SPINLOCK
3948 +# include <linux/bios32.h>
3949 + /* simulate spin locks and read/write locks */
3950 + typedef struct {
3951 + volatile char lock;
3952 + } spinlock_t;
3953 +
3954 + typedef struct {
3955 + volatile unsigned int lock;
3956 + } rwlock_t;
3957 +
3958 +# define spin_lock_init(x) { (x)->lock = 0;}
3959 +# define rw_lock_init(x) { (x)->lock = 0; }
3960 +
3961 +# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
3962 +# define spin_lock_irq(x) { cli(); spin_lock(x);}
3963 +# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
3964 +
3965 +# define spin_unlock(x) { (x)->lock=0;}
3966 +# define spin_unlock_irq(x) { spin_unlock(x); sti();}
3967 +# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
3968 +
3969 +# define read_lock(x) spin_lock(x)
3970 +# define read_lock_irq(x) spin_lock_irq(x)
3971 +# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
3972 +
3973 +# define read_unlock(x) spin_unlock(x)
3974 +# define read_unlock_irq(x) spin_unlock_irq(x)
3975 +# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
3976 +
3977 +# define write_lock(x) spin_lock(x)
3978 +# define write_lock_irq(x) spin_lock_irq(x)
3979 +# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
3980 +
3981 +# define write_unlock(x) spin_unlock(x)
3982 +# define write_unlock_irq(x) spin_unlock_irq(x)
3983 +# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
3984 +#endif /* !SPINLOCK */
3985 +
3986 +#ifndef SPINLOCK_23
3987 +# define spin_lock_bh(x) spin_lock_irq(x)
3988 +# define spin_unlock_bh(x) spin_unlock_irq(x)
3989 +
3990 +# define read_lock_bh(x) read_lock_irq(x)
3991 +# define read_unlock_bh(x) read_unlock_irq(x)
3992 +
3993 +# define write_lock_bh(x) write_lock_irq(x)
3994 +# define write_unlock_bh(x) write_unlock_irq(x)
3995 +#endif /* !SPINLOCK_23 */
3996 +
3997 +#ifndef HAVE_NETDEV_PRINTK
3998 +#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
3999 + printk(sevlevel "%s: " format , netdev->name , ## arg)
4000 +#endif
4001 +
4002 +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0)
4003 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
4004 +#include "openswan/ipsec_kern24.h"
4005 +#else
4006 +#error "kernels before 2.4 are not supported at this time"
4007 +#endif
4008 +#endif
4009 +
4010 +
4011 +#endif /* _OPENSWAN_KVERSIONS_H */
4012 +
4013 +/*
4014 + * $Log: ipsec_kversion.h,v $
4015 + * Revision 1.15.2.11 2007/02/20 03:53:16 paul
4016 + * Added comment, made layout consistent with other checks.
4017 + *
4018 + * Revision 1.15.2.10 2007/02/16 19:08:12 paul
4019 + * Fix for compiling on 2.6.20 (nfmark is now called mark in sk_buff)
4020 + *
4021 + * Revision 1.15.2.9 2006/07/29 05:00:40 paul
4022 + * Added HAVE_NEW_SKB_LINEARIZE for 2.6.18+ kernels where skb_linearize
4023 + * only takes 1 argument.
4024 + *
4025 + * Revision 1.15.2.8 2006/05/01 14:31:52 mcr
4026 + * FREESWAN->OPENSWAN in #ifdef.
4027 + *
4028 + * Revision 1.15.2.7 2006/01/11 02:02:59 mcr
4029 + * updated patches and DEFAULT_TTL code to work
4030 + *
4031 + * Revision 1.15.2.6 2006/01/03 19:25:02 ken
4032 + * Remove duplicated #ifdef for TTL fix - bad patch
4033 + *
4034 + * Revision 1.15.2.5 2006/01/03 18:06:33 ken
4035 + * Fix for missing sysctl default ttl
4036 + *
4037 + * Revision 1.15.2.4 2005/11/27 21:40:14 paul
4038 + * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
4039 + * in for klips as module.
4040 + *
4041 + * Revision 1.15.2.3 2005/11/22 04:11:52 ken
4042 + * Backport fixes for 2.6.14 kernels from HEAD
4043 + *
4044 + * Revision 1.15.2.2 2005/09/01 01:57:19 paul
4045 + * michael's fixes for 2.6.13 from head
4046 + *
4047 + * Revision 1.15.2.1 2005/08/27 23:13:48 paul
4048 + * Fix for:
4049 + * 7 weeks ago: [NET]: Remove unused security member in sk_buff
4050 + * changeset 4280: 328ea53f5fee
4051 + * parent 4279: beb0afb0e3f8
4052 + * author: Thomas Graf <tgraf@suug.ch>
4053 + * date: Tue Jul 5 21:12:44 2005
4054 + * files: include/linux/skbuff.h include/linux/tc_ematch/tc_em_meta.h net/core/skbuff.c net/ipv4/ip_output.c net/ipv6/ip6_output.c net/sched/em_meta.c
4055 + *
4056 + * This should fix compilation on 2.6.13(rc) kernels
4057 + *
4058 + * Revision 1.15 2005/07/19 20:02:15 mcr
4059 + * sk_alloc() interface change.
4060 + *
4061 + * Revision 1.14 2005/07/08 16:20:05 mcr
4062 + * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
4063 + *
4064 + * Revision 1.13 2005/05/20 03:19:18 mcr
4065 + * modifications for use on 2.4.30 kernel, with backported
4066 + * printk_ratelimit(). all warnings removed.
4067 + *
4068 + * Revision 1.12 2005/04/13 22:46:21 mcr
4069 + * note that KLIPS does not work on Linux 2.0.
4070 + *
4071 + * Revision 1.11 2004/09/13 02:22:26 mcr
4072 + * #define inet_protocol if necessary.
4073 + *
4074 + * Revision 1.10 2004/08/03 18:17:15 mcr
4075 + * in 2.6, use "net_device" instead of #define device->net_device.
4076 + * this probably breaks 2.0 compiles.
4077 + *
4078 + * Revision 1.9 2004/04/05 19:55:05 mcr
4079 + * Moved from linux/include/freeswan/ipsec_kversion.h,v
4080 + *
4081 + * Revision 1.8 2003/12/13 19:10:16 mcr
4082 + * refactored rcv and xmit code - same as FS 2.05.
4083 + *
4084 + * Revision 1.7 2003/07/31 22:48:08 mcr
4085 + * derive NET25-ness from presence of NETLINK_XFRM macro.
4086 + *
4087 + * Revision 1.6 2003/06/24 20:22:32 mcr
4088 + * added new global: ipsecdevices[] so that we can keep track of
4089 + * the ipsecX devices. They will be referenced with dev_hold(),
4090 + * so 2.2 may need this as well.
4091 + *
4092 + * Revision 1.5 2003/04/03 17:38:09 rgb
4093 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4094 + *
4095 + * Revision 1.4 2002/04/24 07:36:46 mcr
4096 + * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
4097 + *
4098 + * Revision 1.3 2002/04/12 03:21:17 mcr
4099 + * three parameter version of ip_select_ident appears first
4100 + * in 2.4.2 (RH7.1) not 2.4.4.
4101 + *
4102 + * Revision 1.2 2002/03/08 21:35:22 rgb
4103 + * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
4104 + * 2.4.9. (Andreas Piesk).
4105 + *
4106 + * Revision 1.1 2002/01/29 02:11:42 mcr
4107 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
4108 + * updating of IPv6 structures to match latest in6.h version.
4109 + * removed dead code from freeswan.h that also duplicated kversions.h
4110 + * code.
4111 + *
4112 + *
4113 + */
4114 --- /dev/null Tue Mar 11 13:02:56 2003
4115 +++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004
4116 @@ -0,0 +1,112 @@
4117 +/*
4118 + * Definitions relevant to IPSEC lifetimes
4119 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4120 + * and Michael Richardson <mcr@freeswan.org>
4121 + *
4122 + * This program is free software; you can redistribute it and/or modify it
4123 + * under the terms of the GNU General Public License as published by the
4124 + * Free Software Foundation; either version 2 of the License, or (at your
4125 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4126 + *
4127 + * This program is distributed in the hope that it will be useful, but
4128 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4129 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4130 + * for more details.
4131 + *
4132 + * RCSID $Id: ipsec_life.h,v 1.4 2004/04/05 19:55:05 mcr Exp $
4133 + *
4134 + * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
4135 + *
4136 + */
4137 +
4138 +/*
4139 + * This file describes the book keeping fields for the
4140 + * IPsec Security Association Structure. ("ipsec_sa")
4141 + *
4142 + * This structure is never allocated directly by kernel code,
4143 + * (it is always a static/auto or is part of a structure)
4144 + * so it does not have a reference count.
4145 + *
4146 + */
4147 +
4148 +#ifndef _IPSEC_LIFE_H_
4149 +
4150 +/*
4151 + * _count is total count.
4152 + * _hard is hard limit (kill SA after this number)
4153 + * _soft is soft limit (try to renew SA after this number)
4154 + * _last is used in some special cases.
4155 + *
4156 + */
4157 +
4158 +struct ipsec_lifetime64
4159 +{
4160 + __u64 ipl_count;
4161 + __u64 ipl_soft;
4162 + __u64 ipl_hard;
4163 + __u64 ipl_last;
4164 +};
4165 +
4166 +struct ipsec_lifetimes
4167 +{
4168 + /* number of bytes processed */
4169 + struct ipsec_lifetime64 ipl_bytes;
4170 +
4171 + /* number of packets processed */
4172 + struct ipsec_lifetime64 ipl_packets;
4173 +
4174 + /* time since SA was added */
4175 + struct ipsec_lifetime64 ipl_addtime;
4176 +
4177 + /* time since SA was first used */
4178 + struct ipsec_lifetime64 ipl_usetime;
4179 +
4180 + /* from rfc2367:
4181 + * For CURRENT, the number of different connections,
4182 + * endpoints, or flows that the association has been
4183 + * allocated towards. For HARD and SOFT, the number of
4184 + * these the association may be allocated towards
4185 + * before it expires. The concept of a connection,
4186 + * flow, or endpoint is system specific.
4187 + *
4188 + * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
4189 + * They are maintained for PF_KEY compatibility.
4190 + */
4191 + struct ipsec_lifetime64 ipl_allocations;
4192 +};
4193 +
4194 +enum ipsec_life_alive {
4195 + ipsec_life_harddied = -1,
4196 + ipsec_life_softdied = 0,
4197 + ipsec_life_okay = 1
4198 +};
4199 +
4200 +enum ipsec_life_type {
4201 + ipsec_life_timebased = 1,
4202 + ipsec_life_countbased= 0
4203 +};
4204 +
4205 +#define _IPSEC_LIFE_H_
4206 +#endif /* _IPSEC_LIFE_H_ */
4207 +
4208 +
4209 +/*
4210 + * $Log: ipsec_life.h,v $
4211 + * Revision 1.4 2004/04/05 19:55:05 mcr
4212 + * Moved from linux/include/freeswan/ipsec_life.h,v
4213 + *
4214 + * Revision 1.3 2002/04/24 07:36:46 mcr
4215 + * Moved from ./klips/net/ipsec/ipsec_life.h,v
4216 + *
4217 + * Revision 1.2 2001/11/26 09:16:14 rgb
4218 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4219 + *
4220 + * Revision 1.1.2.1 2001/09/25 02:25:58 mcr
4221 + * lifetime structure created and common functions created.
4222 + *
4223 + *
4224 + * Local variables:
4225 + * c-file-style: "linux"
4226 + * End:
4227 + *
4228 + */
4229 --- /dev/null Tue Mar 11 13:02:56 2003
4230 +++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004
4231 @@ -0,0 +1,143 @@
4232 +/*
4233 + * RCSID $Id: ipsec_md5h.h,v 1.10 2004/09/08 17:21:35 ken Exp $
4234 + */
4235 +
4236 +/*
4237 + * The rest of this file is Copyright RSA DSI. See the following comments
4238 + * for the full Copyright notice.
4239 + */
4240 +
4241 +#ifndef _IPSEC_MD5H_H_
4242 +#define _IPSEC_MD5H_H_
4243 +
4244 +/* GLOBAL.H - RSAREF types and constants
4245 + */
4246 +
4247 +/* PROTOTYPES should be set to one if and only if the compiler supports
4248 + function argument prototyping.
4249 + The following makes PROTOTYPES default to 0 if it has not already
4250 + been defined with C compiler flags.
4251 + */
4252 +#ifndef PROTOTYPES
4253 +#define PROTOTYPES 1
4254 +#endif /* !PROTOTYPES */
4255 +
4256 +/* POINTER defines a generic pointer type */
4257 +typedef __u8 *POINTER;
4258 +
4259 +/* UINT2 defines a two byte word */
4260 +typedef __u16 UINT2;
4261 +
4262 +/* UINT4 defines a four byte word */
4263 +typedef __u32 UINT4;
4264 +
4265 +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
4266 + If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
4267 + returns an empty list.
4268 + */
4269 +
4270 +#if PROTOTYPES
4271 +#define PROTO_LIST(list) list
4272 +#else /* PROTOTYPES */
4273 +#define PROTO_LIST(list) ()
4274 +#endif /* PROTOTYPES */
4275 +
4276 +
4277 +/* MD5.H - header file for MD5C.C
4278 + */
4279 +
4280 +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
4281 +rights reserved.
4282 +
4283 +License to copy and use this software is granted provided that it
4284 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
4285 +Algorithm" in all material mentioning or referencing this software
4286 +or this function.
4287 +
4288 +License is also granted to make and use derivative works provided
4289 +that such works are identified as "derived from the RSA Data
4290 +Security, Inc. MD5 Message-Digest Algorithm" in all material
4291 +mentioning or referencing the derived work.
4292 +
4293 +RSA Data Security, Inc. makes no representations concerning either
4294 +the merchantability of this software or the suitability of this
4295 +software for any particular purpose. It is provided "as is"
4296 +without express or implied warranty of any kind.
4297 +
4298 +These notices must be retained in any copies of any part of this
4299 +documentation and/or software.
4300 + */
4301 +
4302 +/* MD5 context. */
4303 +typedef struct {
4304 + UINT4 state[4]; /* state (ABCD) */
4305 + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
4306 + unsigned char buffer[64]; /* input buffer */
4307 +} MD5_CTX;
4308 +
4309 +void osMD5Init PROTO_LIST ((void *));
4310 +void osMD5Update PROTO_LIST
4311 + ((void *, unsigned char *, __u32));
4312 +void osMD5Final PROTO_LIST ((unsigned char [16], void *));
4313 +
4314 +#endif /* _IPSEC_MD5H_H_ */
4315 +
4316 +/*
4317 + * $Log: ipsec_md5h.h,v $
4318 + * Revision 1.10 2004/09/08 17:21:35 ken
4319 + * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
4320 + *
4321 + * Revision 1.9 2004/04/05 19:55:05 mcr
4322 + * Moved from linux/include/freeswan/ipsec_md5h.h,v
4323 + *
4324 + * Revision 1.8 2002/09/10 01:45:09 mcr
4325 + * changed type of MD5_CTX and SHA1_CTX to void * so that
4326 + * the function prototypes would match, and could be placed
4327 + * into a pointer to a function.
4328 + *
4329 + * Revision 1.7 2002/04/24 07:36:46 mcr
4330 + * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
4331 + *
4332 + * Revision 1.6 1999/12/13 13:59:13 rgb
4333 + * Quick fix to argument size to Update bugs.
4334 + *
4335 + * Revision 1.5 1999/12/07 18:16:23 rgb
4336 + * Fixed comments at end of #endif lines.
4337 + *
4338 + * Revision 1.4 1999/04/06 04:54:26 rgb
4339 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
4340 + * patch shell fixes.
4341 + *
4342 + * Revision 1.3 1999/01/22 06:19:58 rgb
4343 + * 64-bit clean-up.
4344 + *
4345 + * Revision 1.2 1998/11/30 13:22:54 rgb
4346 + * Rationalised all the klips kernel file headers. They are much shorter
4347 + * now and won't conflict under RH5.2.
4348 + *
4349 + * Revision 1.1 1998/06/18 21:27:48 henry
4350 + * move sources from klips/src to klips/net/ipsec, to keep stupid
4351 + * kernel-build scripts happier in the presence of symlinks
4352 + *
4353 + * Revision 1.2 1998/04/23 20:54:03 rgb
4354 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
4355 + * verified.
4356 + *
4357 + * Revision 1.1 1998/04/09 03:04:21 henry
4358 + * sources moved up from linux/net/ipsec
4359 + * these two include files modified not to include others except in kernel
4360 + *
4361 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
4362 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
4363 + *
4364 + * Revision 0.4 1997/01/15 01:28:15 ji
4365 + * No changes.
4366 + *
4367 + * Revision 0.3 1996/11/20 14:48:53 ji
4368 + * Release update only.
4369 + *
4370 + * Revision 0.2 1996/11/02 00:18:33 ji
4371 + * First limited release.
4372 + *
4373 + *
4374 + */
4375 --- /dev/null Tue Mar 11 13:02:56 2003
4376 +++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004
4377 @@ -0,0 +1,387 @@
4378 +/*
4379 + * @(#) Openswan tunable paramaters
4380 + *
4381 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4382 + * and Michael Richardson <mcr@freeswan.org>
4383 + * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
4384 + *
4385 + * This program is free software; you can redistribute it and/or modify it
4386 + * under the terms of the GNU General Public License as published by the
4387 + * Free Software Foundation; either version 2 of the License, or (at your
4388 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4389 + *
4390 + * This program is distributed in the hope that it will be useful, but
4391 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4392 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4393 + * for more details.
4394 + *
4395 + * RCSID $Id: ipsec_param.h,v 1.29.6.3 2006/05/01 14:32:31 mcr Exp $
4396 + *
4397 + */
4398 +
4399 +/*
4400 + * This file provides a set of #define's which may be tuned by various
4401 + * people/configurations. It keeps all compile-time tunables in one place.
4402 + *
4403 + * This file should be included before all other IPsec kernel-only files.
4404 + *
4405 + */
4406 +
4407 +#ifndef _IPSEC_PARAM_H_
4408 +
4409 +#ifdef __KERNEL__
4410 +#include "ipsec_kversion.h"
4411 +
4412 +/* Set number of ipsecX virtual devices here. */
4413 +/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
4414 +/* It must also be reasonable so as not to overload the memory and CPU */
4415 +/* constraints of the host. */
4416 +#define IPSEC_NUM_IF 4
4417 +/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
4418 +/* With "ipsec" being 5 characters, that means 10 is the max field width */
4419 +/* but machine memory and CPU constraints are not likely to tollerate */
4420 +/* more than 3 digits. The default is one digit. */
4421 +/* Update: userland scripts get upset if they can't find "ipsec0", so */
4422 +/* for now, no "0"-padding should be used (which would have been helpful */
4423 +/* to make text-searches work */
4424 +#define IPSEC_DEV_FORMAT "ipsec%d"
4425 +/* For, say, 500 virtual ipsec devices, I would recommend: */
4426 +/* #define IPSEC_NUM_IF 500 */
4427 +/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
4428 +/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
4429 +
4430 +/* use dynamic ipsecX device allocation */
4431 +#ifndef CONFIG_KLIPS_DYNDEV
4432 +#define CONFIG_KLIPS_DYNDEV 1
4433 +#endif /* CONFIG_KLIPS_DYNDEV */
4434 +
4435 +
4436 +#ifdef CONFIG_KLIPS_BIGGATE
4437 +# define SADB_HASHMOD 8069
4438 +#else /* CONFIG_KLIPS_BIGGATE */
4439 +# define SADB_HASHMOD 257
4440 +#endif /* CONFIG_KLIPS_BIGGATE */
4441 +#endif /* __KERNEL__ */
4442 +
4443 +/*
4444 + * This is for the SA reference table. This number is related to the
4445 + * maximum number of SAs that KLIPS can concurrently deal with, plus enough
4446 + * space for keeping expired SAs around.
4447 + *
4448 + * TABLE_MAX_WIDTH is the number of bits that we will use.
4449 + * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
4450 + *
4451 + */
4452 +#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
4453 +# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
4454 +#endif
4455 +
4456 +#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
4457 +# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
4458 +#endif
4459 +
4460 +#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
4461 +# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
4462 +#endif
4463 +
4464 +#ifndef IPSEC_SA_REF_CODE
4465 +# define IPSEC_SA_REF_CODE 1
4466 +#endif
4467 +
4468 +#ifdef __KERNEL__
4469 +/* This is defined for 2.4, but not 2.2.... */
4470 +#ifndef ARPHRD_VOID
4471 +# define ARPHRD_VOID 0xFFFF
4472 +#endif
4473 +
4474 +/* always turn on IPIP mode */
4475 +#ifndef CONFIG_KLIPS_IPIP
4476 +#define CONFIG_KLIPS_IPIP 1
4477 +#endif
4478 +
4479 +/*
4480 + * Worry about PROC_FS stuff
4481 + */
4482 +#if defined(PROC_FS_2325)
4483 +/* kernel 2.4 */
4484 +# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
4485 +# define IPSEC_PROCFS_DEBUG_NO_STATIC
4486 +# define IPSEC_PROC_SUBDIRS
4487 +#else
4488 +/* kernel <2.4 */
4489 +# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
4490 +
4491 +# ifndef PROC_NO_DUMMY
4492 +# define IPSEC_PROC_LAST_ARG , int dummy
4493 +# else
4494 +# define IPSEC_PROC_LAST_ARG
4495 +# endif /* !PROC_NO_DUMMY */
4496 +#endif /* PROC_FS_2325 */
4497 +
4498 +#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
4499 +/* GNU CPP specific! */
4500 +# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
4501 +#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
4502 +
4503 +#ifdef SPINLOCK
4504 +# ifdef SPINLOCK_23
4505 +# include <linux/spinlock.h> /* *lock* */
4506 +# else /* SPINLOCK_23 */
4507 +# include <asm/spinlock.h> /* *lock* */
4508 +# endif /* SPINLOCK_23 */
4509 +#endif /* SPINLOCK */
4510 +
4511 +#ifndef KLIPS_FIXES_DES_PARITY
4512 +# define KLIPS_FIXES_DES_PARITY 1
4513 +#endif /* !KLIPS_FIXES_DES_PARITY */
4514 +
4515 +/* we don't really want to print these unless there are really big problems */
4516 +#ifndef KLIPS_DIVULGE_CYPHER_KEY
4517 +# define KLIPS_DIVULGE_CYPHER_KEY 0
4518 +#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
4519 +
4520 +#ifndef KLIPS_DIVULGE_HMAC_KEY
4521 +# define KLIPS_DIVULGE_HMAC_KEY 0
4522 +#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4523 +
4524 +#ifndef IPSEC_DISALLOW_IPOPTIONS
4525 +# define IPSEC_DISALLOW_IPOPTIONS 1
4526 +#endif /* !KLIPS_DIVULGE_HMAC_KEY */
4527 +
4528 +/* extra toggles for regression testing */
4529 +#ifdef CONFIG_KLIPS_REGRESS
4530 +
4531 +/*
4532 + * should pfkey_acquire() become 100% lossy?
4533 + *
4534 + */
4535 +extern int sysctl_ipsec_regress_pfkey_lossage;
4536 +#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
4537 +# ifdef CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE
4538 +# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
4539 +# endif /* CONFIG_KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4540 +#else
4541 +#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4542 +#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
4543 +
4544 +#else /* CONFIG_KLIPS_REGRESS */
4545 +#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
4546 +
4547 +#endif /* CONFIG_KLIPS_REGRESS */
4548 +
4549 +
4550 +/*
4551 + * debugging routines.
4552 + */
4553 +#define KLIPS_ERROR(flag, format, args...) if(printk_ratelimit() || flag) printk(KERN_ERR "KLIPS " format, ## args)
4554 +#ifdef CONFIG_KLIPS_DEBUG
4555 +extern void ipsec_print_ip(struct iphdr *ip);
4556 +
4557 + #define KLIPS_PRINT(flag, format, args...) \
4558 + ((flag) ? printk(KERN_INFO format , ## args) : 0)
4559 + #define KLIPS_PRINTMORE(flag, format, args...) \
4560 + ((flag) ? printk(format , ## args) : 0)
4561 + #define KLIPS_IP_PRINT(flag, ip) \
4562 + ((flag) ? ipsec_print_ip(ip) : 0)
4563 +#else /* CONFIG_KLIPS_DEBUG */
4564 + #define KLIPS_PRINT(flag, format, args...) do ; while(0)
4565 + #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
4566 + #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
4567 +#endif /* CONFIG_KLIPS_DEBUG */
4568 +
4569 +
4570 +/*
4571 + * Stupid kernel API differences in APIs. Not only do some
4572 + * kernels not have ip_select_ident, but some have differing APIs,
4573 + * and SuSE has one with one parameter, but no way of checking to
4574 + * see what is really what.
4575 + */
4576 +
4577 +#ifdef SUSE_LINUX_2_4_19_IS_STUPID
4578 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
4579 +#else
4580 +
4581 +/* simplest case, nothing */
4582 +#if !defined(IP_SELECT_IDENT)
4583 +#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
4584 +#endif
4585 +
4586 +/* kernels > 2.3.37-ish */
4587 +#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
4588 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
4589 +#endif
4590 +
4591 +/* kernels > 2.4.2 */
4592 +#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
4593 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
4594 +#endif
4595 +
4596 +#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
4597 +
4598 +/*
4599 + * make klips fail test:east-espiv-01.
4600 + * exploit is at testing/attacks/espiv
4601 + *
4602 + */
4603 +#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
4604 +
4605 +
4606 +/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
4607 +#ifndef IP_FRAGMENT_LINEARIZE
4608 +# define IP_FRAGMENT_LINEARIZE 0
4609 +#endif /* IP_FRAGMENT_LINEARIZE */
4610 +#endif /* __KERNEL__ */
4611 +
4612 +#ifdef NEED_INET_PROTOCOL
4613 +#define inet_protocol net_protocol
4614 +#endif
4615 +
4616 +#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && CONFIG_IPSEC_NAT_TRAVERSAL
4617 +#define NAT_TRAVERSAL 1
4618 +#else
4619 +/* let people either #undef, or #define = 0 it */
4620 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
4621 +#undef CONFIG_IPSEC_NAT_TRAVERSAL
4622 +#endif
4623 +#endif
4624 +
4625 +#ifndef IPSEC_DEFAULT_TTL
4626 +#define IPSEC_DEFAULT_TTL 64
4627 +#endif
4628 +
4629 +#define _IPSEC_PARAM_H_
4630 +#endif /* _IPSEC_PARAM_H_ */
4631 +
4632 +/*
4633 + * $Log: ipsec_param.h,v $
4634 + * Revision 1.29.6.3 2006/05/01 14:32:31 mcr
4635 + * added KLIPS_ERROR and make sure that things work without CONFIG_KLIPS_REGRESS.
4636 + *
4637 + * Revision 1.29.6.2 2005/11/27 21:40:14 paul
4638 + * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"
4639 + * in for klips as module.
4640 + *
4641 + * Revision 1.29.6.1 2005/08/12 16:24:18 ken
4642 + * Pull in NAT-T compile logic from HEAD
4643 + *
4644 + * Revision 1.29 2005/01/26 00:50:35 mcr
4645 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
4646 + * and make sure that NAT_TRAVERSAL is set as well to match
4647 + * userspace compiles of code.
4648 + *
4649 + * Revision 1.28 2004/09/13 15:50:15 mcr
4650 + * spell NEED_INET properly, not NET_INET.
4651 + *
4652 + * Revision 1.27 2004/09/13 02:21:45 mcr
4653 + * always turn on IPIP mode.
4654 + * #define inet_protocol if necessary.
4655 + *
4656 + * Revision 1.26 2004/08/17 03:25:43 mcr
4657 + * freeswan->openswan.
4658 + *
4659 + * Revision 1.25 2004/07/10 19:08:41 mcr
4660 + * CONFIG_IPSEC -> CONFIG_KLIPS.
4661 + *
4662 + * Revision 1.24 2004/04/05 19:55:06 mcr
4663 + * Moved from linux/include/freeswan/ipsec_param.h,v
4664 + *
4665 + * Revision 1.23 2003/12/13 19:10:16 mcr
4666 + * refactored rcv and xmit code - same as FS 2.05.
4667 + *
4668 + * Revision 1.22 2003/10/31 02:27:05 mcr
4669 + * pulled up port-selector patches and sa_id elimination.
4670 + *
4671 + * Revision 1.21.4.1 2003/10/29 01:10:19 mcr
4672 + * elimited "struct sa_id"
4673 + *
4674 + * Revision 1.21 2003/04/03 17:38:18 rgb
4675 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
4676 + * Change indentation for readability.
4677 + *
4678 + * Revision 1.20 2003/03/14 08:09:26 rgb
4679 + * Fixed up CONFIG_IPSEC_DYNDEV definitions.
4680 + *
4681 + * Revision 1.19 2003/01/30 02:31:43 rgb
4682 + *
4683 + * Rename SAref table macro names for clarity.
4684 + *
4685 + * Revision 1.18 2002/09/30 19:06:26 rgb
4686 + * Reduce default table to 16 bits width.
4687 + *
4688 + * Revision 1.17 2002/09/20 15:40:29 rgb
4689 + * Define switch to activate new SAref code.
4690 + * Prefix macros with "IPSEC_".
4691 + * Rework saref freelist.
4692 + * Restrict some bits to kernel context for use to klips utils.
4693 + *
4694 + * Revision 1.16 2002/09/20 05:00:31 rgb
4695 + * Define switch to divulge hmac keys for debugging.
4696 + * Added IPOPTIONS switch.
4697 + *
4698 + * Revision 1.15 2002/09/19 02:34:24 mcr
4699 + * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
4700 + * to decide if we are to create /proc/net/ipsec/.
4701 + *
4702 + * Revision 1.14 2002/08/30 01:20:54 mcr
4703 + * reorganized 2.0/2.2/2.4 procfs support macro so match
4704 + * 2.4 values/typedefs.
4705 + *
4706 + * Revision 1.13 2002/07/28 22:03:28 mcr
4707 + * added some documentation to SA_REF_*
4708 + * turned on fix for ESPIV attack, now that we have the attack code.
4709 + *
4710 + * Revision 1.12 2002/07/26 08:48:31 rgb
4711 + * Added SA ref table code.
4712 + *
4713 + * Revision 1.11 2002/07/23 02:57:45 rgb
4714 + * Define ARPHRD_VOID for < 2.4 kernels.
4715 + *
4716 + * Revision 1.10 2002/05/27 21:37:28 rgb
4717 + * Set the defaults sanely for those adventurous enough to try more than 1
4718 + * digit of ipsec devices.
4719 + *
4720 + * Revision 1.9 2002/05/27 18:56:07 rgb
4721 + * Convert to dynamic ipsec device allocation.
4722 + *
4723 + * Revision 1.8 2002/04/24 07:36:47 mcr
4724 + * Moved from ./klips/net/ipsec/ipsec_param.h,v
4725 + *
4726 + * Revision 1.7 2002/04/20 00:12:25 rgb
4727 + * Added esp IV CBC attack fix, disabled.
4728 + *
4729 + * Revision 1.6 2002/01/29 02:11:42 mcr
4730 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
4731 + * updating of IPv6 structures to match latest in6.h version.
4732 + * removed dead code from freeswan.h that also duplicated kversions.h
4733 + * code.
4734 + *
4735 + * Revision 1.5 2002/01/28 19:22:01 mcr
4736 + * by default, turn off LINEARIZE option
4737 + * (let kversions.h turn it on)
4738 + *
4739 + * Revision 1.4 2002/01/20 20:19:36 mcr
4740 + * renamed option to IP_FRAGMENT_LINEARIZE.
4741 + *
4742 + * Revision 1.3 2002/01/12 02:57:25 mcr
4743 + * first regression test causes acquire messages to be lost
4744 + * 100% of the time. This is to help testing of pluto.
4745 + *
4746 + * Revision 1.2 2001/11/26 09:16:14 rgb
4747 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
4748 + *
4749 + * Revision 1.1.2.3 2001/10/23 04:40:16 mcr
4750 + * added #define for DIVULGING session keys in debug output.
4751 + *
4752 + * Revision 1.1.2.2 2001/10/22 20:53:25 mcr
4753 + * added a define to control forcing of DES parity.
4754 + *
4755 + * Revision 1.1.2.1 2001/09/25 02:20:19 mcr
4756 + * many common kernel configuration questions centralized.
4757 + * more things remain that should be moved from freeswan.h.
4758 + *
4759 + *
4760 + * Local variables:
4761 + * c-file-style: "linux"
4762 + * End:
4763 + *
4764 + */
4765 --- /dev/null Tue Mar 11 13:02:56 2003
4766 +++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004
4767 @@ -0,0 +1,217 @@
4768 +#ifndef _IPSEC_POLICY_H
4769 +/*
4770 + * policy interface file between pluto and applications
4771 + * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
4772 + *
4773 + * This library is free software; you can redistribute it and/or modify it
4774 + * under the terms of the GNU Library General Public License as published by
4775 + * the Free Software Foundation; either version 2 of the License, or (at your
4776 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
4777 + *
4778 + * This library is distributed in the hope that it will be useful, but
4779 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
4780 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
4781 + * License for more details.
4782 + *
4783 + * RCSID $Id: ipsec_policy.h,v 1.7.6.1 2005/07/26 01:53:07 ken Exp $
4784 + */
4785 +#define _IPSEC_POLICY_H /* seen it, no need to see it again */
4786 +
4787 +
4788 +/*
4789 + * this file defines an interface between an application (or rather an
4790 + * application library) and a key/policy daemon. It provides for inquiries
4791 + * as to the current state of a connected socket, as well as for general
4792 + * questions.
4793 + *
4794 + * In general, the interface is defined as a series of functional interfaces,
4795 + * and the policy messages should be internal. However, because this is in
4796 + * fact an ABI between pieces of the system that may get compiled and revised
4797 + * seperately, this ABI must be public and revision controlled.
4798 + *
4799 + * It is expected that the daemon will always support previous versions.
4800 + */
4801 +
4802 +#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
4803 +
4804 +enum ipsec_policy_command {
4805 + IPSEC_CMD_QUERY_FD = 1,
4806 + IPSEC_CMD_QUERY_HOSTPAIR = 2,
4807 + IPSEC_CMD_QUERY_DSTONLY = 3,
4808 +};
4809 +
4810 +struct ipsec_policy_msg_head {
4811 + u_int32_t ipm_version;
4812 + u_int32_t ipm_msg_len;
4813 + u_int32_t ipm_msg_type;
4814 + u_int32_t ipm_msg_seq;
4815 +};
4816 +
4817 +enum ipsec_privacy_quality {
4818 + IPSEC_PRIVACY_NONE = 0,
4819 + IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
4820 + IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
4821 + IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
4822 + IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
4823 + IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
4824 + IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
4825 + IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
4826 + IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
4827 +};
4828 +
4829 +enum ipsec_bandwidth_quality {
4830 + IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
4831 + IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
4832 + Good enough for telnet/ssh. */
4833 + IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
4834 + IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
4835 + offloaded, but latency/jitter may be bad */
4836 + IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
4837 +};
4838 +
4839 +/* moved from programs/pluto/constants.h */
4840 +/* IPsec AH transform values
4841 + * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
4842 + * and in http://www.iana.org/assignments/isakmp-registry
4843 + */
4844 +enum ipsec_authentication_algo {
4845 + AH_MD5=2,
4846 + AH_SHA=3,
4847 + AH_DES=4,
4848 + AH_SHA2_256=5,
4849 + AH_SHA2_384=6,
4850 + AH_SHA2_512=7
4851 +};
4852 +
4853 +/* IPsec ESP transform values
4854 + * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
4855 + * and from http://www.iana.org/assignments/isakmp-registry
4856 + */
4857 +
4858 +enum ipsec_cipher_algo {
4859 + ESP_reserved=0,
4860 + ESP_DES_IV64=1,
4861 + ESP_DES=2,
4862 + ESP_3DES=3,
4863 + ESP_RC5=4,
4864 + ESP_IDEA=5,
4865 + ESP_CAST=6,
4866 + ESP_BLOWFISH=7,
4867 + ESP_3IDEA=8,
4868 + ESP_DES_IV32=9,
4869 + ESP_RC4=10,
4870 + ESP_NULL=11,
4871 + ESP_AES=12, /* 128 bit AES */
4872 +};
4873 +
4874 +/* IPCOMP transform values
4875 + * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
4876 + */
4877 +
4878 +enum ipsec_comp_algo {
4879 + IPCOMP_OUI= 1,
4880 + IPCOMP_DEFLATE= 2,
4881 + IPCOMP_LZS= 3,
4882 + IPCOMP_V42BIS= 4
4883 +};
4884 +
4885 +/* Identification type values
4886 + * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
4887 + */
4888 +
4889 +enum ipsec_id_type {
4890 + ID_IMPOSSIBLE= (-2), /* private to Pluto */
4891 + ID_MYID= (-1), /* private to Pluto */
4892 + ID_NONE= 0, /* private to Pluto */
4893 + ID_IPV4_ADDR= 1,
4894 + ID_FQDN= 2,
4895 + ID_USER_FQDN= 3,
4896 + ID_IPV4_ADDR_SUBNET= 4,
4897 + ID_IPV6_ADDR= 5,
4898 + ID_IPV6_ADDR_SUBNET= 6,
4899 + ID_IPV4_ADDR_RANGE= 7,
4900 + ID_IPV6_ADDR_RANGE= 8,
4901 + ID_DER_ASN1_DN= 9,
4902 + ID_DER_ASN1_GN= 10,
4903 + ID_KEY_ID= 11
4904 +};
4905 +
4906 +/* Certificate type values
4907 + * RFC 2408 ISAKMP, chapter 3.9
4908 + */
4909 +enum ipsec_cert_type {
4910 + CERT_NONE= 0, /* none, or guess from file contents */
4911 + CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */
4912 + CERT_PGP= 2,
4913 + CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */
4914 + CERT_X509_SIGNATURE= 4,
4915 + CERT_X509_KEY_EXCHANGE= 5,
4916 + CERT_KERBEROS_TOKENS= 6,
4917 + CERT_CRL= 7,
4918 + CERT_ARL= 8,
4919 + CERT_SPKI= 9,
4920 + CERT_X509_ATTRIBUTE= 10,
4921 + CERT_RAW_RSA= 11, /* raw RSA from config file */
4922 +};
4923 +
4924 +/* a SIG record in ASCII */
4925 +struct ipsec_dns_sig {
4926 + char fqdn[256];
4927 + char dns_sig[768]; /* empty string if not signed */
4928 +};
4929 +
4930 +struct ipsec_raw_key {
4931 + char id_name[256];
4932 + char fs_keyid[8];
4933 +};
4934 +
4935 +struct ipsec_identity {
4936 + enum ipsec_id_type ii_type;
4937 + enum ipsec_cert_type ii_format;
4938 + union {
4939 + struct ipsec_dns_sig ipsec_dns_signed;
4940 + /* some thing for PGP */
4941 + /* some thing for PKIX */
4942 + struct ipsec_raw_key ipsec_raw_key;
4943 + } ii_credential;
4944 +};
4945 +
4946 +#define IPSEC_MAX_CREDENTIALS 32
4947 +
4948 +struct ipsec_policy_cmd_query {
4949 + struct ipsec_policy_msg_head head;
4950 +
4951 + /* Query section */
4952 + ip_address query_local; /* us */
4953 + ip_address query_remote; /* them */
4954 + u_int8_t proto; /* TCP, ICMP, etc. */
4955 + u_short src_port, dst_port;
4956 +
4957 + /* Answer section */
4958 + enum ipsec_privacy_quality strength;
4959 + enum ipsec_bandwidth_quality bandwidth;
4960 + enum ipsec_authentication_algo auth_detail;
4961 + enum ipsec_cipher_algo esp_detail;
4962 + enum ipsec_comp_algo comp_detail;
4963 +
4964 + int credential_count;
4965 +
4966 + struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
4967 +};
4968 +
4969 +#define IPSEC_POLICY_SOCKET "/var/run/pluto/pluto.info"
4970 +
4971 +/* prototypes */
4972 +extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
4973 +extern err_t ipsec_policy_init(void);
4974 +extern err_t ipsec_policy_final(void);
4975 +extern err_t ipsec_policy_readmsg(int policysock,
4976 + unsigned char *buf, size_t buflen);
4977 +extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
4978 +extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
4979 +
4980 +
4981 +extern const char *ipsec_policy_version_code(void);
4982 +extern const char *ipsec_policy_version_string(void);
4983 +
4984 +#endif /* _IPSEC_POLICY_H */
4985 --- /dev/null Tue Mar 11 13:02:56 2003
4986 +++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004
4987 @@ -0,0 +1,199 @@
4988 +/*
4989 + * @(#) prototypes for FreeSWAN functions
4990 + *
4991 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
4992 + * and Michael Richardson <mcr@freeswan.org>
4993 + *
4994 + * This program is free software; you can redistribute it and/or modify it
4995 + * under the terms of the GNU General Public License as published by the
4996 + * Free Software Foundation; either version 2 of the License, or (at your
4997 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
4998 + *
4999 + * This program is distributed in the hope that it will be useful, but
5000 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5001 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5002 + * for more details.
5003 + *
5004 + * RCSID $Id: ipsec_proto.h,v 1.14 2005/04/29 04:50:03 mcr Exp $
5005 + *
5006 + */
5007 +
5008 +#ifndef _IPSEC_PROTO_H_
5009 +
5010 +#include "ipsec_param.h"
5011 +
5012 +/*
5013 + * This file is a kernel only file that declares prototypes for
5014 + * all intra-module function calls and global data structures.
5015 + *
5016 + * Include this file last.
5017 + *
5018 + */
5019 +
5020 +/* forward references */
5021 +enum ipsec_direction;
5022 +enum ipsec_life_type;
5023 +struct ipsec_lifetime64;
5024 +struct ident;
5025 +struct sockaddr_encap;
5026 +struct ipsec_sa;
5027 +
5028 +/* ipsec_init.c */
5029 +extern struct prng ipsec_prng;
5030 +
5031 +/* ipsec_sa.c */
5032 +extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
5033 +extern spinlock_t tdb_lock;
5034 +extern int ipsec_sadb_init(void);
5035 +extern int ipsec_sadb_cleanup(__u8);
5036 +
5037 +extern struct ipsec_sa *ipsec_sa_alloc(int*error);
5038 +
5039 +
5040 +extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *);
5041 +extern int ipsec_sa_put(struct ipsec_sa *);
5042 +extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
5043 +extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
5044 +extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
5045 +
5046 +extern int ipsec_sa_init(struct ipsec_sa *ipsp);
5047 +extern int ipsec_sa_wipe(struct ipsec_sa *ipsp);
5048 +
5049 +/* debug declarations */
5050 +
5051 +/* ipsec_proc.c */
5052 +extern int ipsec_proc_init(void);
5053 +extern void ipsec_proc_cleanup(void);
5054 +
5055 +/* ipsec_rcv.c */
5056 +extern int ipsec_rcv(struct sk_buff *skb);
5057 +extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5058 +
5059 +/* ipsec_xmit.c */
5060 +struct ipsec_xmit_state;
5061 +extern enum ipsec_xmit_value ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
5062 +extern enum ipsec_xmit_value ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
5063 +extern void ipsec_print_ip(struct iphdr *ip);
5064 +
5065 +
5066 +
5067 +/* ipsec_radij.c */
5068 +extern int ipsec_makeroute(struct sockaddr_encap *ea,
5069 + struct sockaddr_encap *em,
5070 + ip_said said,
5071 + uint32_t pid,
5072 + struct sk_buff *skb,
5073 + struct ident *ident_s,
5074 + struct ident *ident_d);
5075 +
5076 +extern int ipsec_breakroute(struct sockaddr_encap *ea,
5077 + struct sockaddr_encap *em,
5078 + struct sk_buff **first,
5079 + struct sk_buff **last);
5080 +
5081 +int ipsec_radijinit(void);
5082 +int ipsec_cleareroutes(void);
5083 +int ipsec_radijcleanup(void);
5084 +
5085 +/* ipsec_life.c */
5086 +extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
5087 + const char *lifename,
5088 + const char *saname,
5089 + enum ipsec_life_type ilt,
5090 + enum ipsec_direction idir,
5091 + struct ipsec_sa *ips);
5092 +
5093 +
5094 +extern int ipsec_lifetime_format(char *buffer,
5095 + int buflen,
5096 + char *lifename,
5097 + enum ipsec_life_type timebaselife,
5098 + struct ipsec_lifetime64 *lifetime);
5099 +
5100 +extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
5101 + __u64 newvalue);
5102 +
5103 +extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
5104 + __u64 newvalue);
5105 +
5106 +/* ipsec_snprintf.c */
5107 +extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
5108 +extern void ipsec_dmp_block(char *s, caddr_t bb, int len);
5109 +
5110 +
5111 +/* ipsec_alg.c */
5112 +extern int ipsec_alg_init(void);
5113 +
5114 +
5115 +#ifdef CONFIG_KLIPS_DEBUG
5116 +
5117 +extern int debug_xform;
5118 +extern int debug_eroute;
5119 +extern int debug_spi;
5120 +extern int debug_netlink;
5121 +
5122 +#endif /* CONFIG_KLIPS_DEBUG */
5123 +
5124 +
5125 +
5126 +
5127 +#define _IPSEC_PROTO_H
5128 +#endif /* _IPSEC_PROTO_H_ */
5129 +
5130 +/*
5131 + * $Log: ipsec_proto.h,v $
5132 + * Revision 1.14 2005/04/29 04:50:03 mcr
5133 + * prototypes for xmit and alg code.
5134 + *
5135 + * Revision 1.13 2005/04/17 03:46:07 mcr
5136 + * added prototypes for ipsec_rcv() routines.
5137 + *
5138 + * Revision 1.12 2005/04/14 20:28:37 mcr
5139 + * added additional prototypes.
5140 + *
5141 + * Revision 1.11 2005/04/14 01:16:28 mcr
5142 + * add prototypes for snprintf.
5143 + *
5144 + * Revision 1.10 2005/04/13 22:47:28 mcr
5145 + * make sure that forward references are available.
5146 + *
5147 + * Revision 1.9 2004/07/10 19:08:41 mcr
5148 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5149 + *
5150 + * Revision 1.8 2004/04/05 19:55:06 mcr
5151 + * Moved from linux/include/freeswan/ipsec_proto.h,v
5152 + *
5153 + * Revision 1.7 2003/10/31 02:27:05 mcr
5154 + * pulled up port-selector patches and sa_id elimination.
5155 + *
5156 + * Revision 1.6.30.1 2003/10/29 01:10:19 mcr
5157 + * elimited "struct sa_id"
5158 + *
5159 + * Revision 1.6 2002/05/23 07:13:48 rgb
5160 + * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
5161 + *
5162 + * Revision 1.5 2002/05/14 02:36:40 rgb
5163 + * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
5164 + * with "put" usage in the kernel.
5165 + *
5166 + * Revision 1.4 2002/04/24 07:36:47 mcr
5167 + * Moved from ./klips/net/ipsec/ipsec_proto.h,v
5168 + *
5169 + * Revision 1.3 2002/04/20 00:12:25 rgb
5170 + * Added esp IV CBC attack fix, disabled.
5171 + *
5172 + * Revision 1.2 2001/11/26 09:16:15 rgb
5173 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5174 + *
5175 + * Revision 1.1.2.1 2001/09/25 02:21:01 mcr
5176 + * ipsec_proto.h created to keep prototypes rather than deal with
5177 + * cyclic dependancies of structures and prototypes in .h files.
5178 + *
5179 + *
5180 + *
5181 + * Local variables:
5182 + * c-file-style: "linux"
5183 + * End:
5184 + *
5185 + */
5186 +
5187 --- /dev/null Tue Mar 11 13:02:56 2003
5188 +++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004
5189 @@ -0,0 +1,179 @@
5190 +/*
5191 + * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
5192 + * Copyright (C) 1996, 1997 John Ioannidis.
5193 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5194 + *
5195 + * This program is free software; you can redistribute it and/or modify it
5196 + * under the terms of the GNU General Public License as published by the
5197 + * Free Software Foundation; either version 2 of the License, or (at your
5198 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5199 + *
5200 + * This program is distributed in the hope that it will be useful, but
5201 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5202 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5203 + * for more details.
5204 + *
5205 + * RCSID $Id: ipsec_radij.h,v 1.22 2004/07/10 19:08:41 mcr Exp $
5206 + */
5207 +
5208 +#ifndef _IPSEC_RADIJ_H
5209 +
5210 +#include <openswan.h>
5211 +
5212 +int ipsec_walk(char *);
5213 +
5214 +int ipsec_rj_walker_procprint(struct radij_node *, void *);
5215 +int ipsec_rj_walker_delete(struct radij_node *, void *);
5216 +
5217 +/* This structure is used to pass information between
5218 + * ipsec_eroute_get_info and ipsec_rj_walker_procprint
5219 + * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
5220 + */
5221 +struct wsbuf
5222 +{
5223 + /* from caller of ipsec_eroute_get_info: */
5224 + char *const buffer; /* start of buffer provided */
5225 + const int length; /* length of buffer provided */
5226 + const off_t offset; /* file position of first character of interest */
5227 + /* accumulated by ipsec_rj_walker_procprint: */
5228 + int len; /* number of character filled into buffer */
5229 + off_t begin; /* file position contained in buffer[0] (<=offset) */
5230 +};
5231 +
5232 +extern struct radij_node_head *rnh;
5233 +extern spinlock_t eroute_lock;
5234 +
5235 +struct eroute * ipsec_findroute(struct sockaddr_encap *);
5236 +
5237 +#define O1(x) (int)(((x)>>24)&0xff)
5238 +#define O2(x) (int)(((x)>>16)&0xff)
5239 +#define O3(x) (int)(((x)>>8)&0xff)
5240 +#define O4(x) (int)(((x))&0xff)
5241 +
5242 +#ifdef CONFIG_KLIPS_DEBUG
5243 +extern int debug_radij;
5244 +void rj_dumptrees(void);
5245 +
5246 +#define DB_RJ_DUMPTREES 0x0001
5247 +#define DB_RJ_FINDROUTE 0x0002
5248 +#endif /* CONFIG_KLIPS_DEBUG */
5249 +
5250 +#define _IPSEC_RADIJ_H
5251 +#endif
5252 +
5253 +/*
5254 + * $Log: ipsec_radij.h,v $
5255 + * Revision 1.22 2004/07/10 19:08:41 mcr
5256 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5257 + *
5258 + * Revision 1.21 2004/04/29 11:06:42 ken
5259 + * Last bits from 2.06 procfs updates
5260 + *
5261 + * Revision 1.20 2004/04/06 02:49:08 mcr
5262 + * pullup of algo code from alg-branch.
5263 + *
5264 + * Revision 1.19 2004/04/05 19:55:06 mcr
5265 + * Moved from linux/include/freeswan/ipsec_radij.h,v
5266 + *
5267 + * Revision 1.18 2002/04/24 07:36:47 mcr
5268 + * Moved from ./klips/net/ipsec/ipsec_radij.h,v
5269 + *
5270 + * Revision 1.17 2001/11/26 09:23:49 rgb
5271 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5272 + *
5273 + * Revision 1.16.2.1 2001/09/25 02:21:17 mcr
5274 + * ipsec_proto.h created to keep prototypes rather than deal with
5275 + * cyclic dependancies of structures and prototypes in .h files.
5276 + *
5277 + * Revision 1.16 2001/09/15 16:24:04 rgb
5278 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
5279 + *
5280 + * Revision 1.15 2001/09/14 16:58:37 rgb
5281 + * Added support for storing the first and last packets through a HOLD.
5282 + *
5283 + * Revision 1.14 2001/09/08 21:13:32 rgb
5284 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
5285 + *
5286 + * Revision 1.13 2001/06/14 19:35:09 rgb
5287 + * Update copyright date.
5288 + *
5289 + * Revision 1.12 2001/05/27 06:12:11 rgb
5290 + * Added structures for pid, packet count and last access time to eroute.
5291 + * Added packet count to beginning of /proc/net/ipsec_eroute.
5292 + *
5293 + * Revision 1.11 2000/09/08 19:12:56 rgb
5294 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
5295 + *
5296 + * Revision 1.10 1999/11/17 15:53:39 rgb
5297 + * Changed all occurrences of #include "../../../lib/freeswan.h"
5298 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
5299 + * klips/net/ipsec/Makefile.
5300 + *
5301 + * Revision 1.9 1999/10/01 00:01:23 rgb
5302 + * Added eroute structure locking.
5303 + *
5304 + * Revision 1.8 1999/04/11 00:28:59 henry
5305 + * GPL boilerplate
5306 + *
5307 + * Revision 1.7 1999/04/06 04:54:26 rgb
5308 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5309 + * patch shell fixes.
5310 + *
5311 + * Revision 1.6 1999/01/22 06:23:26 rgb
5312 + * Cruft clean-out.
5313 + *
5314 + * Revision 1.5 1998/10/25 02:42:08 rgb
5315 + * Change return type on ipsec_breakroute and ipsec_makeroute and add an
5316 + * argument to be able to transmit more infomation about errors.
5317 + *
5318 + * Revision 1.4 1998/10/19 14:44:29 rgb
5319 + * Added inclusion of freeswan.h.
5320 + * sa_id structure implemented and used: now includes protocol.
5321 + *
5322 + * Revision 1.3 1998/07/28 00:03:31 rgb
5323 + * Comment out temporary inet_nto4u() kluge.
5324 + *
5325 + * Revision 1.2 1998/07/14 18:22:00 rgb
5326 + * Add function to clear the eroute table.
5327 + *
5328 + * Revision 1.1 1998/06/18 21:27:49 henry
5329 + * move sources from klips/src to klips/net/ipsec, to keep stupid
5330 + * kernel-build scripts happier in the presence of symlinks
5331 + *
5332 + * Revision 1.5 1998/05/25 20:30:38 rgb
5333 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
5334 + *
5335 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
5336 + * add ipsec_rj_walker_delete.
5337 + *
5338 + * Revision 1.4 1998/05/21 13:02:56 rgb
5339 + * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
5340 + * limit fix.
5341 + *
5342 + * Revision 1.3 1998/04/21 21:29:09 rgb
5343 + * Rearrange debug switches to change on the fly debug output from user
5344 + * space. Only kernel changes checked in at this time. radij.c was also
5345 + * changed to temporarily remove buggy debugging code in rj_delete causing
5346 + * an OOPS and hence, netlink device open errors.
5347 + *
5348 + * Revision 1.2 1998/04/14 17:30:39 rgb
5349 + * Fix up compiling errors for radij tree memory reclamation.
5350 + *
5351 + * Revision 1.1 1998/04/09 03:06:10 henry
5352 + * sources moved up from linux/net/ipsec
5353 + *
5354 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
5355 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
5356 + *
5357 + * Revision 0.4 1997/01/15 01:28:15 ji
5358 + * No changes.
5359 + *
5360 + * Revision 0.3 1996/11/20 14:39:04 ji
5361 + * Minor cleanups.
5362 + * Rationalized debugging code.
5363 + *
5364 + * Revision 0.2 1996/11/02 00:18:33 ji
5365 + * First limited release.
5366 + *
5367 + *
5368 + */
5369 --- /dev/null Tue Mar 11 13:02:56 2003
5370 +++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004
5371 @@ -0,0 +1,199 @@
5372 +/*
5373 + *
5374 + * Copyright (C) 1996, 1997 John Ioannidis.
5375 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
5376 + *
5377 + * This program is free software; you can redistribute it and/or modify it
5378 + * under the terms of the GNU General Public License as published by the
5379 + * Free Software Foundation; either version 2 of the License, or (at your
5380 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5381 + *
5382 + * This program is distributed in the hope that it will be useful, but
5383 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5384 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5385 + * for more details.
5386 + *
5387 + * RCSID $Id: ipsec_rcv.h,v 1.28.2.2 2006/10/06 21:39:26 paul Exp $
5388 + */
5389 +
5390 +#ifndef IPSEC_RCV_H
5391 +#define IPSEC_RCV_H
5392 +
5393 +#include "openswan/ipsec_auth.h"
5394 +
5395 +#define DB_RX_PKTRX 0x0001
5396 +#define DB_RX_PKTRX2 0x0002
5397 +#define DB_RX_DMP 0x0004
5398 +#define DB_RX_IPSA 0x0010
5399 +#define DB_RX_XF 0x0020
5400 +#define DB_RX_IPAD 0x0040
5401 +#define DB_RX_INAU 0x0080
5402 +#define DB_RX_OINFO 0x0100
5403 +#define DB_RX_OINFO2 0x0200
5404 +#define DB_RX_OH 0x0400
5405 +#define DB_RX_REPLAY 0x0800
5406 +
5407 +#ifdef __KERNEL__
5408 +/* struct options; */
5409 +
5410 +#define __NO_VERSION__
5411 +#ifndef AUTOCONF_INCLUDED
5412 +#include <linux/config.h> /* for CONFIG_IP_FORWARD */
5413 +#endif
5414 +#ifdef CONFIG_MODULES
5415 +#include <linux/module.h>
5416 +#endif
5417 +#include <linux/version.h>
5418 +#include <openswan.h>
5419 +
5420 +#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
5421 +
5422 +struct ipsec_birth_reply {
5423 + int packet_template_len;
5424 + unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
5425 +};
5426 +
5427 +extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
5428 +extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
5429 +
5430 +enum ipsec_rcv_value {
5431 + IPSEC_RCV_LASTPROTO=1,
5432 + IPSEC_RCV_OK=0,
5433 + IPSEC_RCV_BADPROTO=-1,
5434 + IPSEC_RCV_BADLEN=-2,
5435 + IPSEC_RCV_ESP_BADALG=-3,
5436 + IPSEC_RCV_3DES_BADBLOCKING=-4,
5437 + IPSEC_RCV_ESP_DECAPFAIL=-5,
5438 + IPSEC_RCV_DECAPFAIL=-6,
5439 + IPSEC_RCV_SAIDNOTFOUND=-7,
5440 + IPSEC_RCV_IPCOMPALONE=-8,
5441 + IPSEC_RCV_IPCOMPFAILED=-10,
5442 + IPSEC_RCV_SAIDNOTLIVE=-11,
5443 + IPSEC_RCV_FAILEDINBOUND=-12,
5444 + IPSEC_RCV_LIFETIMEFAILED=-13,
5445 + IPSEC_RCV_BADAUTH=-14,
5446 + IPSEC_RCV_REPLAYFAILED=-15,
5447 + IPSEC_RCV_AUTHFAILED=-16,
5448 + IPSEC_RCV_REPLAYROLLED=-17,
5449 + IPSEC_RCV_BAD_DECRYPT=-18
5450 +};
5451 +
5452 +struct ipsec_rcv_state {
5453 + struct sk_buff *skb;
5454 + struct net_device_stats *stats;
5455 + struct iphdr *ipp; /* the IP header */
5456 + struct ipsec_sa *ipsp; /* current SA being processed */
5457 + int len; /* length of packet */
5458 + int ilen; /* length of inner payload (-authlen) */
5459 + int authlen; /* how big is the auth data at end */
5460 + int hard_header_len; /* layer 2 size */
5461 + int iphlen; /* how big is IP header */
5462 + struct auth_alg *authfuncs;
5463 + ip_said said;
5464 + char sa[SATOT_BUF];
5465 + size_t sa_len;
5466 + __u8 next_header;
5467 + __u8 hash[AH_AMAX];
5468 + char ipsaddr_txt[ADDRTOA_BUF];
5469 + char ipdaddr_txt[ADDRTOA_BUF];
5470 + __u8 *octx;
5471 + __u8 *ictx;
5472 + int ictx_len;
5473 + int octx_len;
5474 + union {
5475 + struct {
5476 + struct esphdr *espp;
5477 + } espstuff;
5478 + struct {
5479 + struct ahhdr *ahp;
5480 + } ahstuff;
5481 + struct {
5482 + struct ipcomphdr *compp;
5483 + } ipcompstuff;
5484 + } protostuff;
5485 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
5486 + __u8 natt_type;
5487 + __u16 natt_sport;
5488 + __u16 natt_dport;
5489 + int natt_len;
5490 +#endif
5491 +};
5492 +
5493 +extern int
5494 +#ifdef PROTO_HANDLER_SINGLE_PARM
5495 +ipsec_rcv(struct sk_buff *skb);
5496 +#else /* PROTO_HANDLER_SINGLE_PARM */
5497 +ipsec_rcv(struct sk_buff *skb,
5498 + unsigned short xlen);
5499 +#endif /* PROTO_HANDLER_SINGLE_PARM */
5500 +
5501 +#ifdef CONFIG_KLIPS_DEBUG
5502 +extern int debug_rcv;
5503 +#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
5504 +#else
5505 +#define ipsec_rcv_dmp(_x,_y, _z) do {} while(0)
5506 +#endif /* CONFIG_KLIPS_DEBUG */
5507 +
5508 +extern int sysctl_ipsec_inbound_policy_check;
5509 +#endif /* __KERNEL__ */
5510 +
5511 +extern int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type);
5512 +
5513 +
5514 +#endif /* IPSEC_RCV_H */
5515 +
5516 +/*
5517 + * $Log: ipsec_rcv.h,v $
5518 + * Revision 1.28.2.2 2006/10/06 21:39:26 paul
5519 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
5520 + * set. This is defined through autoconf.h which is included through the
5521 + * linux kernel build macros.
5522 + *
5523 + * Revision 1.28.2.1 2006/07/10 15:52:20 paul
5524 + * Fix for bug #642 by Bart Trojanowski
5525 + *
5526 + * Revision 1.28 2005/05/11 00:59:45 mcr
5527 + * do not call debug routines if !defined KLIPS_DEBUG.
5528 + *
5529 + * Revision 1.27 2005/04/29 04:59:46 mcr
5530 + * use ipsec_dmp_block.
5531 + *
5532 + * Revision 1.26 2005/04/13 22:48:35 mcr
5533 + * added comments, and removed some log.
5534 + * removed Linux 2.0 support.
5535 + *
5536 + * Revision 1.25 2005/04/08 18:25:37 mcr
5537 + * prototype klips26 encap receive function
5538 + *
5539 + * Revision 1.24 2004/08/20 21:45:37 mcr
5540 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5541 + * be 26sec compatible. But, some defines where changed.
5542 + *
5543 + * Revision 1.23 2004/08/03 18:17:40 mcr
5544 + * in 2.6, use "net_device" instead of #define device->net_device.
5545 + * this probably breaks 2.0 compiles.
5546 + *
5547 + * Revision 1.22 2004/07/10 19:08:41 mcr
5548 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5549 + *
5550 + * Revision 1.21 2004/04/06 02:49:08 mcr
5551 + * pullup of algo code from alg-branch.
5552 + *
5553 + * Revision 1.20 2004/04/05 19:55:06 mcr
5554 + * Moved from linux/include/freeswan/ipsec_rcv.h,v
5555 + *
5556 + * Revision 1.19 2003/12/15 18:13:09 mcr
5557 + * when compiling with NAT traversal, don't assume that the
5558 + * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
5559 + * is set.
5560 + *
5561 + * history elided 2005-04-12.
5562 + *
5563 + * Local Variables:
5564 + * c-basic-offset:8
5565 + * c-style:linux
5566 + * End:
5567 + *
5568 + */
5569 +
5570 +
5571 --- /dev/null Tue Mar 11 13:02:56 2003
5572 +++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004
5573 @@ -0,0 +1,355 @@
5574 +/*
5575 + * @(#) Definitions of IPsec Security Association (ipsec_sa)
5576 + *
5577 + * Copyright (C) 2001, 2002, 2003
5578 + * Richard Guy Briggs <rgb@freeswan.org>
5579 + * and Michael Richardson <mcr@freeswan.org>
5580 + *
5581 + * This program is free software; you can redistribute it and/or modify it
5582 + * under the terms of the GNU General Public License as published by the
5583 + * Free Software Foundation; either version 2 of the License, or (at your
5584 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
5585 + *
5586 + * This program is distributed in the hope that it will be useful, but
5587 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
5588 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
5589 + * for more details.
5590 + *
5591 + * RCSID $Id: ipsec_sa.h,v 1.23 2005/05/11 01:18:59 mcr Exp $
5592 + *
5593 + * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
5594 + *
5595 + */
5596 +
5597 +/*
5598 + * This file describes the IPsec Security Association Structure.
5599 + *
5600 + * This structure keeps track of a single transform that may be done
5601 + * to a set of packets. It can describe applying the transform or
5602 + * apply the reverse. (e.g. compression vs expansion). However, it
5603 + * only describes one at a time. To describe both, two structures would
5604 + * be used, but since the sides of the transform are performed
5605 + * on different machines typically it is usual to have only one side
5606 + * of each association.
5607 + *
5608 + */
5609 +
5610 +#ifndef _IPSEC_SA_H_
5611 +
5612 +#ifdef __KERNEL__
5613 +#include "openswan/ipsec_stats.h"
5614 +#include "openswan/ipsec_life.h"
5615 +#include "openswan/ipsec_eroute.h"
5616 +#endif /* __KERNEL__ */
5617 +#include "openswan/ipsec_param.h"
5618 +
5619 +#include "pfkeyv2.h"
5620 +
5621 +
5622 +/* SAs are held in a table.
5623 + * Entries in this table are referenced by IPsecSAref_t values.
5624 + * IPsecSAref_t values are conceptually subscripts. Because
5625 + * we want to allocate the table piece-meal, the subscripting
5626 + * is implemented with two levels, a bit like paged virtual memory.
5627 + * This representation mechanism is known as an Iliffe Vector.
5628 + *
5629 + * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
5630 + * pointers to subtables.
5631 + * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
5632 + * is a pointer to an SA.
5633 + *
5634 + * An IPsecSAref_t contains either an exceptional value (signified by the
5635 + * high-order bit being on) or a reference to a table entry. A table entry
5636 + * reference has the subtable subscript in the low-order
5637 + * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
5638 + * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
5639 + *
5640 + * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
5641 + * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
5642 + *
5643 + * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
5644 + * struct ipsec_sa*. The macro definition clearly shows the two-level
5645 + * access needed to find the SA pointer.
5646 + *
5647 + * The Maintable is allocated when IPsec is initialized.
5648 + * Each subtable is allocated when needed, but the first is allocated
5649 + * when IPsec is initialized.
5650 + *
5651 + * IPsecSAref_t is designed to be smaller than an NFmark so that
5652 + * they can be stored in NFmarks and still leave a few bits for other
5653 + * purposes. The spare bits are in the low order of the NFmark
5654 + * but in the high order of the IPsecSAref_t, so conversion is required.
5655 + * We pick the upper bits of NFmark on the theory that they are less likely to
5656 + * interfere with more pedestrian uses of nfmark.
5657 + */
5658 +
5659 +
5660 +typedef unsigned short int IPsecRefTableUnusedCount;
5661 +
5662 +#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
5663 +
5664 +#ifdef __KERNEL__
5665 +#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
5666 +#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")"
5667 +#endif
5668 +
5669 +#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5670 +
5671 +#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
5672 +#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5673 +
5674 +#ifdef CONFIG_NETFILTER
5675 +#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
5676 +#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
5677 +#else /* CONFIG_NETFILTER */
5678 +/* just make it work for now, it doesn't matter, since there is no nfmark */
5679 +#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
5680 +#endif /* CONFIG_NETFILTER */
5681 +#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
5682 +#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
5683 +
5684 +#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
5685 +#define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5686 +#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
5687 +
5688 +#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
5689 +#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
5690 +#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
5691 +
5692 +#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
5693 +#define IPsecSA2SAref(x) ((x)->ips_ref)
5694 +
5695 +#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
5696 +
5697 +/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
5698 +struct ipsec_sa
5699 +{
5700 + IPsecSAref_t ips_ref; /* reference table entry number */
5701 + atomic_t ips_refcount; /* reference count for this struct */
5702 + struct ipsec_sa *ips_hnext; /* next in hash chain */
5703 + struct ipsec_sa *ips_inext; /* pointer to next xform */
5704 + struct ipsec_sa *ips_onext; /* pointer to prev xform */
5705 +
5706 + struct ifnet *ips_rcvif; /* related rcv encap interface */
5707 +
5708 + ip_said ips_said; /* SA ID */
5709 +
5710 + __u32 ips_seq; /* seq num of msg that initiated this SA */
5711 + __u32 ips_pid; /* PID of process that initiated this SA */
5712 + __u8 ips_authalg; /* auth algorithm for this SA */
5713 + __u8 ips_encalg; /* enc algorithm for this SA */
5714 +
5715 + struct ipsec_stats ips_errs;
5716 +
5717 + __u8 ips_replaywin; /* replay window size */
5718 + enum sadb_sastate ips_state; /* state of SA */
5719 + __u32 ips_replaywin_lastseq; /* last pkt sequence num */
5720 + __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
5721 + __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
5722 +
5723 + __u32 ips_flags; /* generic xform flags */
5724 +
5725 +
5726 + struct ipsec_lifetimes ips_life; /* lifetime records */
5727 +
5728 + /* selector information */
5729 + __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */
5730 + struct sockaddr*ips_addr_s; /* src sockaddr */
5731 + struct sockaddr*ips_addr_d; /* dst sockaddr */
5732 + struct sockaddr*ips_addr_p; /* proxy sockaddr */
5733 + __u16 ips_addr_s_size;
5734 + __u16 ips_addr_d_size;
5735 + __u16 ips_addr_p_size;
5736 + ip_address ips_flow_s;
5737 + ip_address ips_flow_d;
5738 + ip_address ips_mask_s;
5739 + ip_address ips_mask_d;
5740 +
5741 + __u16 ips_key_bits_a; /* size of authkey in bits */
5742 + __u16 ips_auth_bits; /* size of authenticator in bits */
5743 + __u16 ips_key_bits_e; /* size of enckey in bits */
5744 + __u16 ips_iv_bits; /* size of IV in bits */
5745 + __u8 ips_iv_size;
5746 + __u16 ips_key_a_size;
5747 + __u16 ips_key_e_size;
5748 +
5749 + caddr_t ips_key_a; /* authentication key */
5750 + caddr_t ips_key_e; /* encryption key */
5751 + caddr_t ips_iv; /* Initialisation Vector */
5752 +
5753 + struct ident ips_ident_s; /* identity src */
5754 + struct ident ips_ident_d; /* identity dst */
5755 +
5756 + /* these are included even if CONFIG_KLIPS_IPCOMP is off */
5757 + __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
5758 + __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
5759 + __u64 ips_comp_ratio_cbytes; /* compressed bytes */
5760 + __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
5761 +
5762 + /* these are included even if CONFIG_IPSEC_NAT_TRAVERSAL is off */
5763 + __u8 ips_natt_type;
5764 + __u8 ips_natt_reserved[3];
5765 + __u16 ips_natt_sport;
5766 + __u16 ips_natt_dport;
5767 +
5768 + struct sockaddr *ips_natt_oa;
5769 + __u16 ips_natt_oa_size;
5770 + __u16 ips_natt_reserved2;
5771 +
5772 +#if 0
5773 + __u32 ips_sens_dpd;
5774 + __u8 ips_sens_sens_level;
5775 + __u8 ips_sens_sens_len;
5776 + __u64* ips_sens_sens_bitmap;
5777 + __u8 ips_sens_integ_level;
5778 + __u8 ips_sens_integ_len;
5779 + __u64* ips_sens_integ_bitmap;
5780 +#endif
5781 + struct ipsec_alg_enc *ips_alg_enc;
5782 + struct ipsec_alg_auth *ips_alg_auth;
5783 + IPsecSAref_t ips_ref_rel;
5784 +};
5785 +
5786 +struct IPsecSArefSubTable
5787 +{
5788 + struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
5789 +};
5790 +
5791 +struct ipsec_sadb {
5792 + struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
5793 + IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
5794 + int refFreeListHead;
5795 + int refFreeListTail;
5796 + IPsecSAref_t refFreeListCont;
5797 + IPsecSAref_t said_hash[SADB_HASHMOD];
5798 + spinlock_t sadb_lock;
5799 +};
5800 +
5801 +extern struct ipsec_sadb ipsec_sadb;
5802 +
5803 +extern int ipsec_SAref_recycle(void);
5804 +extern int ipsec_SArefSubTable_alloc(unsigned table);
5805 +extern int ipsec_saref_freelist_init(void);
5806 +extern int ipsec_sadb_init(void);
5807 +extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
5808 +extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
5809 +extern int ipsec_sa_free(struct ipsec_sa* ips);
5810 +extern int ipsec_sa_put(struct ipsec_sa *ips);
5811 +extern int ipsec_sa_add(struct ipsec_sa *ips);
5812 +extern int ipsec_sa_del(struct ipsec_sa *ips);
5813 +extern int ipsec_sa_delchain(struct ipsec_sa *ips);
5814 +extern int ipsec_sadb_cleanup(__u8 proto);
5815 +extern int ipsec_sadb_free(void);
5816 +extern int ipsec_sa_wipe(struct ipsec_sa *ips);
5817 +#endif /* __KERNEL__ */
5818 +
5819 +enum ipsec_direction {
5820 + ipsec_incoming = 1,
5821 + ipsec_outgoing = 2
5822 +};
5823 +
5824 +#define _IPSEC_SA_H_
5825 +#endif /* _IPSEC_SA_H_ */
5826 +
5827 +/*
5828 + * $Log: ipsec_sa.h,v $
5829 + * Revision 1.23 2005/05/11 01:18:59 mcr
5830 + * do not change structure based upon options, to avoid
5831 + * too many #ifdef.
5832 + *
5833 + * Revision 1.22 2005/04/14 01:17:09 mcr
5834 + * change sadb_state to an enum.
5835 + *
5836 + * Revision 1.21 2004/08/20 21:45:37 mcr
5837 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
5838 + * be 26sec compatible. But, some defines where changed.
5839 + *
5840 + * Revision 1.20 2004/07/10 19:08:41 mcr
5841 + * CONFIG_IPSEC -> CONFIG_KLIPS.
5842 + *
5843 + * Revision 1.19 2004/04/05 19:55:06 mcr
5844 + * Moved from linux/include/freeswan/ipsec_sa.h,v
5845 + *
5846 + * Revision 1.18 2004/04/05 19:41:05 mcr
5847 + * merged alg-branch code.
5848 + *
5849 + * Revision 1.17.2.1 2003/12/22 15:25:52 jjo
5850 + * . Merged algo-0.8.1-rc11-test1 into alg-branch
5851 + *
5852 + * Revision 1.17 2003/12/10 01:20:06 mcr
5853 + * NAT-traversal patches to KLIPS.
5854 + *
5855 + * Revision 1.16 2003/10/31 02:27:05 mcr
5856 + * pulled up port-selector patches and sa_id elimination.
5857 + *
5858 + * Revision 1.15.4.1 2003/10/29 01:10:19 mcr
5859 + * elimited "struct sa_id"
5860 + *
5861 + * Revision 1.15 2003/05/11 00:53:09 mcr
5862 + * IPsecSAref_t and macros were moved to freeswan.h.
5863 + *
5864 + * Revision 1.14 2003/02/12 19:31:55 rgb
5865 + * Fixed bug in "file seen" machinery.
5866 + * Updated copyright year.
5867 + *
5868 + * Revision 1.13 2003/01/30 02:31:52 rgb
5869 + *
5870 + * Re-wrote comments describing SAref system for accuracy.
5871 + * Rename SAref table macro names for clarity.
5872 + * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
5873 + * Transmit error code through to caller from callee for better diagnosis of problems.
5874 + * Enclose all macro arguments in parens to avoid any possible obscrure bugs.
5875 + *
5876 + * Revision 1.12 2002/10/07 18:31:19 rgb
5877 + * Change comment to reflect the flexible nature of the main and sub-table widths.
5878 + * Added a counter for the number of unused entries in each subtable.
5879 + * Further break up host field type macro to host field.
5880 + * Move field width sanity checks to ipsec_sa.c
5881 + * Define a mask for an entire saref.
5882 + *
5883 + * Revision 1.11 2002/09/20 15:40:33 rgb
5884 + * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys.
5885 + * Fixed SAref/nfmark macros.
5886 + * Rework saref freeslist.
5887 + * Place all ipsec sadb globals into one struct.
5888 + * Restrict some bits to kernel context for use to klips utils.
5889 + *
5890 + * Revision 1.10 2002/09/20 05:00:34 rgb
5891 + * Update copyright date.
5892 + *
5893 + * Revision 1.9 2002/09/17 17:19:29 mcr
5894 + * make it compile even if there is no netfilter - we lost
5895 + * functionality, but it works, especially on 2.2.
5896 + *
5897 + * Revision 1.8 2002/07/28 22:59:53 mcr
5898 + * clarified/expanded one comment.
5899 + *
5900 + * Revision 1.7 2002/07/26 08:48:31 rgb
5901 + * Added SA ref table code.
5902 + *
5903 + * Revision 1.6 2002/05/31 17:27:48 rgb
5904 + * Comment fix.
5905 + *
5906 + * Revision 1.5 2002/05/27 18:55:03 rgb
5907 + * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
5908 + *
5909 + * Revision 1.4 2002/05/23 07:13:36 rgb
5910 + * Convert "usecount" to "refcount" to remove ambiguity.
5911 + *
5912 + * Revision 1.3 2002/04/24 07:36:47 mcr
5913 + * Moved from ./klips/net/ipsec/ipsec_sa.h,v
5914 + *
5915 + * Revision 1.2 2001/11/26 09:16:15 rgb
5916 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
5917 + *
5918 + * Revision 1.1.2.1 2001/09/25 02:24:58 mcr
5919 + * struct tdb -> struct ipsec_sa.
5920 + * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
5921 + * ipsec_xform.c removed. header file still contains useful things.
5922 + *
5923 + *
5924 + * Local variables:
5925 + * c-file-style: "linux"
5926 + * End:
5927 + *
5928 + */
5929 --- /dev/null Tue Mar 11 13:02:56 2003
5930 +++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004
5931 @@ -0,0 +1,79 @@
5932 +/*
5933 + * RCSID $Id: ipsec_sha1.h,v 1.8 2004/04/05 19:55:07 mcr Exp $
5934 + */
5935 +
5936 +/*
5937 + * Here is the original comment from the distribution:
5938 +
5939 +SHA-1 in C
5940 +By Steve Reid <steve@edmweb.com>
5941 +100% Public Domain
5942 +
5943 + * Adapted for use by the IPSEC code by John Ioannidis
5944 + */
5945 +
5946 +
5947 +#ifndef _IPSEC_SHA1_H_
5948 +#define _IPSEC_SHA1_H_
5949 +
5950 +typedef struct
5951 +{
5952 + __u32 state[5];
5953 + __u32 count[2];
5954 + __u8 buffer[64];
5955 +} SHA1_CTX;
5956 +
5957 +void SHA1Transform(__u32 state[5], __u8 buffer[64]);
5958 +void SHA1Init(void *context);
5959 +void SHA1Update(void *context, unsigned char *data, __u32 len);
5960 +void SHA1Final(unsigned char digest[20], void *context);
5961 +
5962 +
5963 +#endif /* _IPSEC_SHA1_H_ */
5964 +
5965 +/*
5966 + * $Log: ipsec_sha1.h,v $
5967 + * Revision 1.8 2004/04/05 19:55:07 mcr
5968 + * Moved from linux/include/freeswan/ipsec_sha1.h,v
5969 + *
5970 + * Revision 1.7 2002/09/10 01:45:09 mcr
5971 + * changed type of MD5_CTX and SHA1_CTX to void * so that
5972 + * the function prototypes would match, and could be placed
5973 + * into a pointer to a function.
5974 + *
5975 + * Revision 1.6 2002/04/24 07:36:47 mcr
5976 + * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
5977 + *
5978 + * Revision 1.5 1999/12/13 13:59:13 rgb
5979 + * Quick fix to argument size to Update bugs.
5980 + *
5981 + * Revision 1.4 1999/12/07 18:16:23 rgb
5982 + * Fixed comments at end of #endif lines.
5983 + *
5984 + * Revision 1.3 1999/04/06 04:54:27 rgb
5985 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
5986 + * patch shell fixes.
5987 + *
5988 + * Revision 1.2 1998/11/30 13:22:54 rgb
5989 + * Rationalised all the klips kernel file headers. They are much shorter
5990 + * now and won't conflict under RH5.2.
5991 + *
5992 + * Revision 1.1 1998/06/18 21:27:50 henry
5993 + * move sources from klips/src to klips/net/ipsec, to keep stupid
5994 + * kernel-build scripts happier in the presence of symlinks
5995 + *
5996 + * Revision 1.2 1998/04/23 20:54:05 rgb
5997 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
5998 + * verified.
5999 + *
6000 + * Revision 1.1 1998/04/09 03:04:21 henry
6001 + * sources moved up from linux/net/ipsec
6002 + * these two include files modified not to include others except in kernel
6003 + *
6004 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
6005 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6006 + *
6007 + * Revision 0.4 1997/01/15 01:28:15 ji
6008 + * New transform
6009 + *
6010 + */
6011 --- /dev/null Tue Mar 11 13:02:56 2003
6012 +++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004
6013 @@ -0,0 +1,76 @@
6014 +/*
6015 + * @(#) definition of ipsec_stats structure
6016 + *
6017 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
6018 + * and Michael Richardson <mcr@freeswan.org>
6019 + *
6020 + * This program is free software; you can redistribute it and/or modify it
6021 + * under the terms of the GNU General Public License as published by the
6022 + * Free Software Foundation; either version 2 of the License, or (at your
6023 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6024 + *
6025 + * This program is distributed in the hope that it will be useful, but
6026 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6027 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6028 + * for more details.
6029 + *
6030 + * RCSID $Id: ipsec_stats.h,v 1.7 2005/04/14 01:17:45 mcr Exp $
6031 + *
6032 + */
6033 +
6034 +/*
6035 + * This file describes the errors/statistics that FreeSWAN collects.
6036 + */
6037 +
6038 +#ifndef _IPSEC_STATS_H_
6039 +
6040 +struct ipsec_stats {
6041 + __u32 ips_alg_errs; /* number of algorithm errors */
6042 + __u32 ips_auth_errs; /* # of authentication errors */
6043 + __u32 ips_encsize_errs; /* # of encryption size errors*/
6044 + __u32 ips_encpad_errs; /* # of encryption pad errors*/
6045 + __u32 ips_replaywin_errs; /* # of pkt sequence errors */
6046 +};
6047 +
6048 +#define _IPSEC_STATS_H_
6049 +#endif /* _IPSEC_STATS_H_ */
6050 +
6051 +/*
6052 + * $Log: ipsec_stats.h,v $
6053 + * Revision 1.7 2005/04/14 01:17:45 mcr
6054 + * add prototypes for snprintf.
6055 + *
6056 + * Revision 1.6 2004/04/05 19:55:07 mcr
6057 + * Moved from linux/include/freeswan/ipsec_stats.h,v
6058 + *
6059 + * Revision 1.5 2004/04/05 19:41:05 mcr
6060 + * merged alg-branch code.
6061 + *
6062 + * Revision 1.4 2004/03/28 20:27:19 paul
6063 + * Included tested and confirmed fixes mcr made and dhr verified for
6064 + * snprint statements. Changed one other snprintf to use ipsec_snprintf
6065 + * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
6066 + * dhr. (thanks dhr!)
6067 + *
6068 + * Revision 1.4 2004/03/24 01:58:31 mcr
6069 + * sprintf->snprintf for formatting into proc buffer.
6070 + *
6071 + * Revision 1.3.34.1 2004/04/05 04:30:46 mcr
6072 + * patches for alg-branch to compile/work with 2.x openswan
6073 + *
6074 + * Revision 1.3 2002/04/24 07:36:47 mcr
6075 + * Moved from ./klips/net/ipsec/ipsec_stats.h,v
6076 + *
6077 + * Revision 1.2 2001/11/26 09:16:16 rgb
6078 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6079 + *
6080 + * Revision 1.1.2.1 2001/09/25 02:27:00 mcr
6081 + * statistics moved to seperate structure.
6082 + *
6083 + *
6084 + *
6085 + * Local variables:
6086 + * c-file-style: "linux"
6087 + * End:
6088 + *
6089 + */
6090 --- /dev/null Tue Mar 11 13:02:56 2003
6091 +++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004
6092 @@ -0,0 +1,280 @@
6093 +/*
6094 + * IPSEC tunneling code
6095 + * Copyright (C) 1996, 1997 John Ioannidis.
6096 + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6097 + *
6098 + * This program is free software; you can redistribute it and/or modify it
6099 + * under the terms of the GNU General Public License as published by the
6100 + * Free Software Foundation; either version 2 of the License, or (at your
6101 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6102 + *
6103 + * This program is distributed in the hope that it will be useful, but
6104 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6105 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6106 + * for more details.
6107 + *
6108 + * RCSID $Id: ipsec_tunnel.h,v 1.33 2005/06/04 16:06:05 mcr Exp $
6109 + */
6110 +
6111 +
6112 +#ifdef NET_21
6113 +# define DEV_QUEUE_XMIT(skb, device, pri) {\
6114 + skb->dev = device; \
6115 + neigh_compat_output(skb); \
6116 + /* skb->dst->output(skb); */ \
6117 + }
6118 +# define ICMP_SEND(skb_in, type, code, info, dev) \
6119 + icmp_send(skb_in, type, code, htonl(info))
6120 +# define IP_SEND(skb, dev) \
6121 + ip_send(skb);
6122 +#else /* NET_21 */
6123 +# define DEV_QUEUE_XMIT(skb, device, pri) {\
6124 + dev_queue_xmit(skb, device, pri); \
6125 + }
6126 +# define ICMP_SEND(skb_in, type, code, info, dev) \
6127 + icmp_send(skb_in, type, code, info, dev)
6128 +# define IP_SEND(skb, dev) \
6129 + if(ntohs(iph->tot_len) > physmtu) { \
6130 + ip_fragment(NULL, skb, dev, 0); \
6131 + ipsec_kfree_skb(skb); \
6132 + } else { \
6133 + dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
6134 + }
6135 +#endif /* NET_21 */
6136 +
6137 +
6138 +/*
6139 + * Heavily based on drivers/net/new_tunnel.c. Lots
6140 + * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
6141 + */
6142 +
6143 +struct ipsectunnelconf
6144 +{
6145 + __u32 cf_cmd;
6146 + union
6147 + {
6148 + char cfu_name[12];
6149 + } cf_u;
6150 +#define cf_name cf_u.cfu_name
6151 +};
6152 +
6153 +#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
6154 +#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
6155 +#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
6156 +
6157 +#ifdef __KERNEL__
6158 +#include <linux/version.h>
6159 +#ifndef KERNEL_VERSION
6160 +# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
6161 +#endif
6162 +struct ipsecpriv
6163 +{
6164 + struct sk_buff_head sendq;
6165 + struct net_device *dev;
6166 + struct wait_queue *wait_queue;
6167 + char locked;
6168 + int (*hard_start_xmit) (struct sk_buff *skb,
6169 + struct net_device *dev);
6170 + int (*hard_header) (struct sk_buff *skb,
6171 + struct net_device *dev,
6172 + unsigned short type,
6173 + void *daddr,
6174 + void *saddr,
6175 + unsigned len);
6176 +#ifdef NET_21
6177 + int (*rebuild_header)(struct sk_buff *skb);
6178 +#else /* NET_21 */
6179 + int (*rebuild_header)(void *buff, struct net_device *dev,
6180 + unsigned long raddr, struct sk_buff *skb);
6181 +#endif /* NET_21 */
6182 + int (*set_mac_address)(struct net_device *dev, void *addr);
6183 +#ifndef NET_21
6184 + void (*header_cache_bind)(struct hh_cache **hhp, struct net_device *dev,
6185 + unsigned short htype, __u32 daddr);
6186 +#endif /* !NET_21 */
6187 + void (*header_cache_update)(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr);
6188 + struct net_device_stats *(*get_stats)(struct net_device *dev);
6189 + struct net_device_stats mystats;
6190 + int mtu; /* What is the desired MTU? */
6191 +};
6192 +
6193 +extern char ipsec_tunnel_c_version[];
6194 +
6195 +extern struct net_device *ipsecdevices[IPSEC_NUM_IF];
6196 +
6197 +int ipsec_tunnel_init_devices(void);
6198 +
6199 +/* void */ int ipsec_tunnel_cleanup_devices(void);
6200 +
6201 +extern /* void */ int ipsec_init(void);
6202 +
6203 +extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev);
6204 +extern struct net_device *ipsec_get_device(int inst);
6205 +
6206 +#ifdef CONFIG_KLIPS_DEBUG
6207 +extern int debug_tunnel;
6208 +extern int sysctl_ipsec_debug_verbose;
6209 +#endif /* CONFIG_KLIPS_DEBUG */
6210 +#endif /* __KERNEL__ */
6211 +
6212 +#ifdef CONFIG_KLIPS_DEBUG
6213 +#define DB_TN_INIT 0x0001
6214 +#define DB_TN_PROCFS 0x0002
6215 +#define DB_TN_XMIT 0x0010
6216 +#define DB_TN_OHDR 0x0020
6217 +#define DB_TN_CROUT 0x0040
6218 +#define DB_TN_OXFS 0x0080
6219 +#define DB_TN_REVEC 0x0100
6220 +#define DB_TN_ENCAP 0x0200
6221 +#endif /* CONFIG_KLIPS_DEBUG */
6222 +
6223 +/*
6224 + * $Log: ipsec_tunnel.h,v $
6225 + * Revision 1.33 2005/06/04 16:06:05 mcr
6226 + * better patch for nat-t rcv-device code.
6227 + *
6228 + * Revision 1.32 2005/05/21 03:18:35 mcr
6229 + * added additional debug flag tunnelling.
6230 + *
6231 + * Revision 1.31 2004/08/03 18:18:02 mcr
6232 + * in 2.6, use "net_device" instead of #define device->net_device.
6233 + * this probably breaks 2.0 compiles.
6234 + *
6235 + * Revision 1.30 2004/07/10 19:08:41 mcr
6236 + * CONFIG_IPSEC -> CONFIG_KLIPS.
6237 + *
6238 + * Revision 1.29 2004/04/05 19:55:07 mcr
6239 + * Moved from linux/include/freeswan/ipsec_tunnel.h,v
6240 + *
6241 + * Revision 1.28 2003/06/24 20:22:32 mcr
6242 + * added new global: ipsecdevices[] so that we can keep track of
6243 + * the ipsecX devices. They will be referenced with dev_hold(),
6244 + * so 2.2 may need this as well.
6245 + *
6246 + * Revision 1.27 2003/04/03 17:38:09 rgb
6247 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
6248 + *
6249 + * Revision 1.26 2003/02/12 19:32:20 rgb
6250 + * Updated copyright year.
6251 + *
6252 + * Revision 1.25 2002/05/27 18:56:07 rgb
6253 + * Convert to dynamic ipsec device allocation.
6254 + *
6255 + * Revision 1.24 2002/04/24 07:36:48 mcr
6256 + * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
6257 + *
6258 + * Revision 1.23 2001/11/06 19:50:44 rgb
6259 + * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
6260 + * use also by pfkey_v2_parser.c
6261 + *
6262 + * Revision 1.22 2001/09/15 16:24:05 rgb
6263 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
6264 + *
6265 + * Revision 1.21 2001/06/14 19:35:10 rgb
6266 + * Update copyright date.
6267 + *
6268 + * Revision 1.20 2000/09/15 11:37:02 rgb
6269 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
6270 + * IPCOMP zlib deflate code.
6271 + *
6272 + * Revision 1.19 2000/09/08 19:12:56 rgb
6273 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6274 + *
6275 + * Revision 1.18 2000/07/28 13:50:54 rgb
6276 + * Changed enet_statistics to net_device_stats and added back compatibility
6277 + * for pre-2.1.19.
6278 + *
6279 + * Revision 1.17 1999/11/19 01:12:15 rgb
6280 + * Purge unneeded proc_info prototypes, now that static linking uses
6281 + * dynamic proc_info registration.
6282 + *
6283 + * Revision 1.16 1999/11/18 18:51:00 rgb
6284 + * Changed all device registrations for static linking to
6285 + * dynamic to reduce the number and size of patches.
6286 + *
6287 + * Revision 1.15 1999/11/18 04:14:21 rgb
6288 + * Replaced all kernel version macros to shorter, readable form.
6289 + * Added CONFIG_PROC_FS compiler directives in case it is shut off.
6290 + * Added Marc Boucher's 2.3.25 proc patches.
6291 + *
6292 + * Revision 1.14 1999/05/25 02:50:10 rgb
6293 + * Fix kernel version macros for 2.0.x static linking.
6294 + *
6295 + * Revision 1.13 1999/05/25 02:41:06 rgb
6296 + * Add ipsec_klipsdebug support for static linking.
6297 + *
6298 + * Revision 1.12 1999/05/05 22:02:32 rgb
6299 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
6300 + *
6301 + * Revision 1.11 1999/04/29 15:19:50 rgb
6302 + * Add return values to init and cleanup functions.
6303 + *
6304 + * Revision 1.10 1999/04/16 16:02:39 rgb
6305 + * Bump up macro to 4 ipsec I/Fs.
6306 + *
6307 + * Revision 1.9 1999/04/15 15:37:25 rgb
6308 + * Forward check changes from POST1_00 branch.
6309 + *
6310 + * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
6311 + * Backcheck from HEAD, pre1.0.
6312 + *
6313 + * Revision 1.8 1999/04/11 00:29:01 henry
6314 + * GPL boilerplate
6315 + *
6316 + * Revision 1.7 1999/04/06 04:54:28 rgb
6317 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
6318 + * patch shell fixes.
6319 + *
6320 + * Revision 1.6 1999/03/31 05:44:48 rgb
6321 + * Keep PMTU reduction private.
6322 + *
6323 + * Revision 1.5 1999/02/10 22:31:20 rgb
6324 + * Change rebuild_header member to reflect generality of link layer.
6325 + *
6326 + * Revision 1.4 1998/12/01 13:22:04 rgb
6327 + * Added support for debug printing of version info.
6328 + *
6329 + * Revision 1.3 1998/07/29 20:42:46 rgb
6330 + * Add a macro for clearing all tunnel devices.
6331 + * Rearrange structures and declarations for sharing with userspace.
6332 + *
6333 + * Revision 1.2 1998/06/25 20:01:45 rgb
6334 + * Make prototypes available for ipsec_init and ipsec proc_dir_entries
6335 + * for static linking.
6336 + *
6337 + * Revision 1.1 1998/06/18 21:27:50 henry
6338 + * move sources from klips/src to klips/net/ipsec, to keep stupid
6339 + * kernel-build scripts happier in the presence of symlinks
6340 + *
6341 + * Revision 1.3 1998/05/18 21:51:50 rgb
6342 + * Added macros for num of I/F's and a procfs debug switch.
6343 + *
6344 + * Revision 1.2 1998/04/21 21:29:09 rgb
6345 + * Rearrange debug switches to change on the fly debug output from user
6346 + * space. Only kernel changes checked in at this time. radij.c was also
6347 + * changed to temporarily remove buggy debugging code in rj_delete causing
6348 + * an OOPS and hence, netlink device open errors.
6349 + *
6350 + * Revision 1.1 1998/04/09 03:06:13 henry
6351 + * sources moved up from linux/net/ipsec
6352 + *
6353 + * Revision 1.1.1.1 1998/04/08 05:35:05 henry
6354 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
6355 + *
6356 + * Revision 0.5 1997/06/03 04:24:48 ji
6357 + * Added transport mode.
6358 + * Changed the way routing is done.
6359 + * Lots of bug fixes.
6360 + *
6361 + * Revision 0.4 1997/01/15 01:28:15 ji
6362 + * No changes.
6363 + *
6364 + * Revision 0.3 1996/11/20 14:39:04 ji
6365 + * Minor cleanups.
6366 + * Rationalized debugging code.
6367 + *
6368 + * Revision 0.2 1996/11/02 00:18:33 ji
6369 + * First limited release.
6370 + *
6371 + *
6372 + */
6373 --- /dev/null Tue Mar 11 13:02:56 2003
6374 +++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004
6375 @@ -0,0 +1,257 @@
6376 +/*
6377 + * Definitions relevant to IPSEC transformations
6378 + * Copyright (C) 1996, 1997 John Ioannidis.
6379 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
6380 + * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
6381 + *
6382 + * This program is free software; you can redistribute it and/or modify it
6383 + * under the terms of the GNU General Public License as published by the
6384 + * Free Software Foundation; either version 2 of the License, or (at your
6385 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6386 + *
6387 + * This program is distributed in the hope that it will be useful, but
6388 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6389 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6390 + * for more details.
6391 + *
6392 + * RCSID $Id: ipsec_xform.h,v 1.41 2004/07/10 19:08:41 mcr Exp $
6393 + */
6394 +
6395 +#ifndef _IPSEC_XFORM_H_
6396 +
6397 +#include <openswan.h>
6398 +
6399 +#define XF_NONE 0 /* No transform set */
6400 +#define XF_IP4 1 /* IPv4 inside IPv4 */
6401 +#define XF_AHMD5 2 /* AH MD5 */
6402 +#define XF_AHSHA 3 /* AH SHA */
6403 +#define XF_ESP3DES 5 /* ESP DES3-CBC */
6404 +#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
6405 +#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
6406 +#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
6407 +#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
6408 +#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
6409 +#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
6410 +#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
6411 +#define XF_IP6 15 /* IPv6 inside IPv6 */
6412 +#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
6413 +
6414 +#define XF_CLR 126 /* Clear SA table */
6415 +#define XF_DEL 127 /* Delete SA */
6416 +
6417 +/* IPsec AH transform values
6418 + * RFC 2407
6419 + * draft-ietf-ipsec-doi-tc-mib-02.txt
6420 + */
6421 +
6422 +#define AH_NONE 0
6423 +#define AH_MD5 2
6424 +#define AH_SHA 3
6425 +/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */
6426 +#define AH_SHA2_256 5
6427 +#define AH_SHA2_384 6
6428 +#define AH_SHA2_512 7
6429 +#define AH_RIPEMD 8
6430 +#define AH_MAX 15
6431 +
6432 +/* IPsec ESP transform values */
6433 +
6434 +#define ESP_NONE 0
6435 +#define ESP_DES 2
6436 +#define ESP_3DES 3
6437 +#define ESP_RC5 4
6438 +#define ESP_IDEA 5
6439 +#define ESP_CAST 6
6440 +#define ESP_BLOWFISH 7
6441 +#define ESP_3IDEA 8
6442 +#define ESP_RC4 10
6443 +#define ESP_NULL 11
6444 +#define ESP_AES 12
6445 +
6446 +/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */
6447 +#define ESP_MARS 249
6448 +#define ESP_RC6 250
6449 +#define ESP_SERPENT 252
6450 +#define ESP_TWOFISH 253
6451 +
6452 +/* IPCOMP transform values */
6453 +
6454 +#define IPCOMP_NONE 0
6455 +#define IPCOMP_OUI 1
6456 +#define IPCOMP_DEFLAT 2
6457 +#define IPCOMP_LZS 3
6458 +#define IPCOMP_V42BIS 4
6459 +
6460 +#define XFT_AUTH 0x0001
6461 +#define XFT_CONF 0x0100
6462 +
6463 +/* available if CONFIG_KLIPS_DEBUG is defined */
6464 +#define DB_XF_INIT 0x0001
6465 +
6466 +#define PROTO2TXT(x) \
6467 + (x) == IPPROTO_AH ? "AH" : \
6468 + (x) == IPPROTO_ESP ? "ESP" : \
6469 + (x) == IPPROTO_IPIP ? "IPIP" : \
6470 + (x) == IPPROTO_COMP ? "COMP" : \
6471 + "UNKNOWN_proto"
6472 +static inline const char *enc_name_id (unsigned id) {
6473 + static char buf[16];
6474 + snprintf(buf, sizeof(buf), "_ID%d", id);
6475 + return buf;
6476 +}
6477 +static inline const char *auth_name_id (unsigned id) {
6478 + static char buf[16];
6479 + snprintf(buf, sizeof(buf), "_ID%d", id);
6480 + return buf;
6481 +}
6482 +#define IPS_XFORM_NAME(x) \
6483 + PROTO2TXT((x)->ips_said.proto), \
6484 + (x)->ips_said.proto == IPPROTO_COMP ? \
6485 + ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
6486 + "_DEFLATE" : "_UNKNOWN_comp") : \
6487 + (x)->ips_encalg == ESP_NONE ? "" : \
6488 + (x)->ips_encalg == ESP_3DES ? "_3DES" : \
6489 + (x)->ips_encalg == ESP_AES ? "_AES" : \
6490 + (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
6491 + (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
6492 + enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
6493 + (x)->ips_authalg == AH_NONE ? "" : \
6494 + (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
6495 + (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
6496 + (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
6497 + (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
6498 + (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
6499 + auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
6500 +
6501 +#ifdef __KERNEL__
6502 +struct ipsec_rcv_state;
6503 +struct ipsec_xmit_state;
6504 +
6505 +struct xform_functions {
6506 + enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
6507 + struct sk_buff *skb);
6508 + enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
6509 +
6510 + enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
6511 + struct sk_buff *skb,
6512 + __u32 *replay,
6513 + unsigned char **authenticator);
6514 + enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
6515 + struct sk_buff *skb);
6516 +
6517 + enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
6518 + enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
6519 +
6520 + enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
6521 + struct sk_buff *skb,
6522 + __u32 *replay,
6523 + unsigned char **authenticator);
6524 + enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
6525 + struct sk_buff *skb);
6526 + int xmit_headroom;
6527 + int xmit_needtailroom;
6528 +};
6529 +
6530 +#endif /* __KERNEL__ */
6531 +
6532 +#ifdef CONFIG_KLIPS_DEBUG
6533 +extern void ipsec_dmp(char *s, caddr_t bb, int len);
6534 +#else /* CONFIG_KLIPS_DEBUG */
6535 +#define ipsec_dmp(_x, _y, _z)
6536 +#endif /* CONFIG_KLIPS_DEBUG */
6537 +
6538 +
6539 +#define _IPSEC_XFORM_H_
6540 +#endif /* _IPSEC_XFORM_H_ */
6541 +
6542 +/*
6543 + * $Log: ipsec_xform.h,v $
6544 + * Revision 1.41 2004/07/10 19:08:41 mcr
6545 + * CONFIG_IPSEC -> CONFIG_KLIPS.
6546 + *
6547 + * Revision 1.40 2004/04/06 02:49:08 mcr
6548 + * pullup of algo code from alg-branch.
6549 + *
6550 + * Revision 1.39 2004/04/05 19:55:07 mcr
6551 + * Moved from linux/include/freeswan/ipsec_xform.h,v
6552 + *
6553 + * Revision 1.38 2004/04/05 19:41:05 mcr
6554 + * merged alg-branch code.
6555 + *
6556 + * Revision 1.37 2003/12/13 19:10:16 mcr
6557 + * refactored rcv and xmit code - same as FS 2.05.
6558 + *
6559 + * Revision 1.36.34.1 2003/12/22 15:25:52 jjo
6560 + * Merged algo-0.8.1-rc11-test1 into alg-branch
6561 + *
6562 + * Revision 1.36 2002/04/24 07:36:48 mcr
6563 + * Moved from ./klips/net/ipsec/ipsec_xform.h,v
6564 + *
6565 + * Revision 1.35 2001/11/26 09:23:51 rgb
6566 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
6567 + *
6568 + * Revision 1.33.2.1 2001/09/25 02:24:58 mcr
6569 + * struct tdb -> struct ipsec_sa.
6570 + * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
6571 + * ipsec_xform.c removed. header file still contains useful things.
6572 + *
6573 + * Revision 1.34 2001/11/06 19:47:17 rgb
6574 + * Changed lifetime_packets to uint32 from uint64.
6575 + *
6576 + * Revision 1.33 2001/09/08 21:13:34 rgb
6577 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
6578 + *
6579 + * Revision 1.32 2001/07/06 07:40:01 rgb
6580 + * Reformatted for readability.
6581 + * Added inbound policy checking fields for use with IPIP SAs.
6582 + *
6583 + * Revision 1.31 2001/06/14 19:35:11 rgb
6584 + * Update copyright date.
6585 + *
6586 + * Revision 1.30 2001/05/30 08:14:03 rgb
6587 + * Removed vestiges of esp-null transforms.
6588 + *
6589 + * Revision 1.29 2001/01/30 23:42:47 rgb
6590 + * Allow pfkey msgs from pid other than user context required for ACQUIRE
6591 + * and subsequent ADD or UDATE.
6592 + *
6593 + * Revision 1.28 2000/11/06 04:30:40 rgb
6594 + * Add Svenning's adaptive content compression.
6595 + *
6596 + * Revision 1.27 2000/09/19 00:38:25 rgb
6597 + * Fixed algorithm name bugs introduced for ipcomp.
6598 + *
6599 + * Revision 1.26 2000/09/17 21:36:48 rgb
6600 + * Added proto2txt macro.
6601 + *
6602 + * Revision 1.25 2000/09/17 18:56:47 rgb
6603 + * Added IPCOMP support.
6604 + *
6605 + * Revision 1.24 2000/09/12 19:34:12 rgb
6606 + * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
6607 + *
6608 + * Revision 1.23 2000/09/12 03:23:14 rgb
6609 + * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
6610 + *
6611 + * Revision 1.22 2000/09/08 19:12:56 rgb
6612 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
6613 + *
6614 + * Revision 1.21 2000/09/01 18:32:43 rgb
6615 + * Added (disabled) sensitivity members to tdb struct.
6616 + *
6617 + * Revision 1.20 2000/08/30 05:31:01 rgb
6618 + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
6619 + * Kill remainder of tdb_xform, tdb_xdata, xformsw.
6620 + *
6621 + * Revision 1.19 2000/08/01 14:51:52 rgb
6622 + * Removed _all_ remaining traces of DES.
6623 + *
6624 + * Revision 1.18 2000/01/21 06:17:45 rgb
6625 + * Tidied up spacing.
6626 + *
6627 + *
6628 + * Local variables:
6629 + * c-file-style: "linux"
6630 + * End:
6631 + *
6632 + */
6633 --- /dev/null Tue Mar 11 13:02:56 2003
6634 +++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004
6635 @@ -0,0 +1,198 @@
6636 +/*
6637 + * IPSEC tunneling code
6638 + * Copyright (C) 1996, 1997 John Ioannidis.
6639 + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
6640 + *
6641 + * This program is free software; you can redistribute it and/or modify it
6642 + * under the terms of the GNU General Public License as published by the
6643 + * Free Software Foundation; either version 2 of the License, or (at your
6644 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
6645 + *
6646 + * This program is distributed in the hope that it will be useful, but
6647 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6648 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
6649 + * for more details.
6650 + *
6651 + * RCSID $Id: ipsec_xmit.h,v 1.14 2005/05/11 01:00:26 mcr Exp $
6652 + */
6653 +
6654 +#include "openswan/ipsec_sa.h"
6655 +
6656 +enum ipsec_xmit_value
6657 +{
6658 + IPSEC_XMIT_STOLEN=2,
6659 + IPSEC_XMIT_PASS=1,
6660 + IPSEC_XMIT_OK=0,
6661 + IPSEC_XMIT_ERRMEMALLOC=-1,
6662 + IPSEC_XMIT_ESP_BADALG=-2,
6663 + IPSEC_XMIT_BADPROTO=-3,
6664 + IPSEC_XMIT_ESP_PUSHPULLERR=-4,
6665 + IPSEC_XMIT_BADLEN=-5,
6666 + IPSEC_XMIT_AH_BADALG=-6,
6667 + IPSEC_XMIT_SAIDNOTFOUND=-7,
6668 + IPSEC_XMIT_SAIDNOTLIVE=-8,
6669 + IPSEC_XMIT_REPLAYROLLED=-9,
6670 + IPSEC_XMIT_LIFETIMEFAILED=-10,
6671 + IPSEC_XMIT_CANNOTFRAG=-11,
6672 + IPSEC_XMIT_MSSERR=-12,
6673 + IPSEC_XMIT_ERRSKBALLOC=-13,
6674 + IPSEC_XMIT_ENCAPFAIL=-14,
6675 + IPSEC_XMIT_NODEV=-15,
6676 + IPSEC_XMIT_NOPRIVDEV=-16,
6677 + IPSEC_XMIT_NOPHYSDEV=-17,
6678 + IPSEC_XMIT_NOSKB=-18,
6679 + IPSEC_XMIT_NOIPV6=-19,
6680 + IPSEC_XMIT_NOIPOPTIONS=-20,
6681 + IPSEC_XMIT_TTLEXPIRED=-21,
6682 + IPSEC_XMIT_BADHHLEN=-22,
6683 + IPSEC_XMIT_PUSHPULLERR=-23,
6684 + IPSEC_XMIT_ROUTEERR=-24,
6685 + IPSEC_XMIT_RECURSDETECT=-25,
6686 + IPSEC_XMIT_IPSENDFAILURE=-26,
6687 + IPSEC_XMIT_ESPUDP=-27,
6688 + IPSEC_XMIT_ESPUDP_BADTYPE=-28,
6689 +};
6690 +
6691 +struct ipsec_xmit_state
6692 +{
6693 + struct sk_buff *skb; /* working skb pointer */
6694 + struct net_device *dev; /* working dev pointer */
6695 + struct ipsecpriv *prv; /* Our device' private space */
6696 + struct sk_buff *oskb; /* Original skb pointer */
6697 + struct net_device_stats *stats; /* This device's statistics */
6698 + struct iphdr *iph; /* Our new IP header */
6699 + __u32 newdst; /* The other SG's IP address */
6700 + __u32 orgdst; /* Original IP destination address */
6701 + __u32 orgedst; /* 1st SG's IP address */
6702 + __u32 newsrc; /* The new source SG's IP address */
6703 + __u32 orgsrc; /* Original IP source address */
6704 + __u32 innersrc; /* Innermost IP source address */
6705 + int iphlen; /* IP header length */
6706 + int pyldsz; /* upper protocol payload size */
6707 + int headroom;
6708 + int tailroom;
6709 + int authlen;
6710 + int max_headroom; /* The extra header space needed */
6711 + int max_tailroom; /* The extra stuffing needed */
6712 + int ll_headroom; /* The extra link layer hard_header space needed */
6713 + int tot_headroom; /* The total header space needed */
6714 + int tot_tailroom; /* The totalstuffing needed */
6715 + __u8 *saved_header; /* saved copy of the hard header */
6716 + unsigned short sport, dport;
6717 +
6718 + struct sockaddr_encap matcher; /* eroute search key */
6719 + struct eroute *eroute;
6720 + struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */
6721 + char sa_txt[SATOT_BUF];
6722 + size_t sa_len;
6723 + int hard_header_stripped; /* has the hard header been removed yet? */
6724 + int hard_header_len;
6725 + struct net_device *physdev;
6726 +/* struct device *virtdev; */
6727 + short physmtu;
6728 + short cur_mtu; /* copy of prv->mtu, cause prv may == NULL */
6729 + short mtudiff;
6730 +#ifdef NET_21
6731 + struct rtable *route;
6732 +#endif /* NET_21 */
6733 + ip_said outgoing_said;
6734 +#ifdef NET_21
6735 + int pass;
6736 +#endif /* NET_21 */
6737 + int error;
6738 + uint32_t eroute_pid;
6739 + struct ipsec_sa ips;
6740 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
6741 + uint8_t natt_type;
6742 + uint8_t natt_head;
6743 + uint16_t natt_sport;
6744 + uint16_t natt_dport;
6745 +#endif
6746 +};
6747 +
6748 +enum ipsec_xmit_value
6749 +ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
6750 +
6751 +enum ipsec_xmit_value
6752 +ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
6753 +
6754 +enum ipsec_xmit_value
6755 +ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
6756 +
6757 +extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
6758 +
6759 +
6760 +extern int ipsec_xmit_trap_count;
6761 +extern int ipsec_xmit_trap_sendcount;
6762 +
6763 +#ifdef CONFIG_KLIPS_DEBUG
6764 +extern int debug_tunnel;
6765 +
6766 +#define debug_xmit debug_tunnel
6767 +
6768 +#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
6769 +#else
6770 +#define ipsec_xmit_dmp(_x,_y, _z) do {} while(0)
6771 +
6772 +#endif /* CONFIG_KLIPS_DEBUG */
6773 +
6774 +extern int sysctl_ipsec_debug_verbose;
6775 +extern int sysctl_ipsec_icmp;
6776 +extern int sysctl_ipsec_tos;
6777 +
6778 +
6779 +/*
6780 + * $Log: ipsec_xmit.h,v $
6781 + * Revision 1.14 2005/05/11 01:00:26 mcr
6782 + * do not call debug routines if !defined KLIPS_DEBUG.
6783 + *
6784 + * Revision 1.13 2005/04/29 05:01:38 mcr
6785 + * use ipsec_dmp_block.
6786 + * added cur_mtu to ixs instead of using ixs->dev.
6787 + *
6788 + * Revision 1.12 2004/08/20 21:45:37 mcr
6789 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
6790 + * be 26sec compatible. But, some defines where changed.
6791 + *
6792 + * Revision 1.11 2004/08/03 18:18:21 mcr
6793 + * in 2.6, use "net_device" instead of #define device->net_device.
6794 + * this probably breaks 2.0 compiles.
6795 + *
6796 + * Revision 1.10 2004/07/10 19:08:41 mcr
6797 + * CONFIG_IPSEC -> CONFIG_KLIPS.
6798 + *
6799 + * Revision 1.9 2004/04/06 02:49:08 mcr
6800 + * pullup of algo code from alg-branch.
6801 + *
6802 + * Revision 1.8 2004/04/05 19:55:07 mcr
6803 + * Moved from linux/include/freeswan/ipsec_xmit.h,v
6804 + *
6805 + * Revision 1.7 2004/02/03 03:11:40 mcr
6806 + * new xmit type if the UDP encapsulation is wrong.
6807 + *
6808 + * Revision 1.6 2003/12/13 19:10:16 mcr
6809 + * refactored rcv and xmit code - same as FS 2.05.
6810 + *
6811 + * Revision 1.5 2003/12/10 01:20:06 mcr
6812 + * NAT-traversal patches to KLIPS.
6813 + *
6814 + * Revision 1.4 2003/12/06 16:37:04 mcr
6815 + * 1.4.7a X.509 patch applied.
6816 + *
6817 + * Revision 1.3 2003/10/31 02:27:05 mcr
6818 + * pulled up port-selector patches and sa_id elimination.
6819 + *
6820 + * Revision 1.2.4.2 2003/10/29 01:10:19 mcr
6821 + * elimited "struct sa_id"
6822 + *
6823 + * Revision 1.2.4.1 2003/09/21 13:59:38 mcr
6824 + * pre-liminary X.509 patch - does not yet pass tests.
6825 + *
6826 + * Revision 1.2 2003/06/20 01:42:13 mcr
6827 + * added counters to measure how many ACQUIREs we send to pluto,
6828 + * and how many are successfully sent.
6829 + *
6830 + * Revision 1.1 2003/02/12 19:31:03 rgb
6831 + * Refactored from ipsec_tunnel.c
6832 + *
6833 + */
6834 --- /dev/null Tue Mar 11 13:02:56 2003
6835 +++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004
6836 @@ -0,0 +1,75 @@
6837 +/*
6838 + * sanitize a string into a printable format.
6839 + *
6840 + * Copyright (C) 1998-2002 D. Hugh Redelmeier.
6841 + * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
6842 + *
6843 + * This library is free software; you can redistribute it and/or modify it
6844 + * under the terms of the GNU Library General Public License as published by
6845 + * the Free Software Foundation; either version 2 of the License, or (at your
6846 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
6847 + *
6848 + * This library is distributed in the hope that it will be useful, but
6849 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6850 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
6851 + * License for more details.
6852 + *
6853 + * RCSID $Id: passert.h,v 1.7 2004/10/21 18:44:42 mcr Exp $
6854 + */
6855 +
6856 +#include "openswan.h"
6857 +
6858 +#ifndef _OPENSWAN_PASSERT_H
6859 +#define _OPENSWAN_PASSERT_H
6860 +/* our versions of assert: log result */
6861 +
6862 +#ifdef DEBUG
6863 +
6864 +typedef void (*openswan_passert_fail_t)(const char *pred_str,
6865 + const char *file_str,
6866 + unsigned long line_no) NEVER_RETURNS;
6867 +
6868 +openswan_passert_fail_t openswan_passert_fail;
6869 +
6870 +extern void pexpect_log(const char *pred_str
6871 + , const char *file_str, unsigned long line_no);
6872 +
6873 +# define impossible() do { \
6874 + if(openswan_passert_fail) { \
6875 + (*openswan_passert_fail)("impossible", __FILE__, __LINE__); \
6876 + }} while(0)
6877 +
6878 +extern void switch_fail(int n
6879 + , const char *file_str, unsigned long line_no) NEVER_RETURNS;
6880 +
6881 +# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
6882 +
6883 +# define passert(pred) do { \
6884 + if (!(pred)) \
6885 + if(openswan_passert_fail) { \
6886 + (*openswan_passert_fail)(#pred, __FILE__, __LINE__); \
6887 + } \
6888 + } while(0)
6889 +
6890 +# define pexpect(pred) do { \
6891 + if (!(pred)) \
6892 + pexpect_log(#pred, __FILE__, __LINE__); \
6893 + } while(0)
6894 +
6895 +/* assert that an err_t is NULL; evaluate exactly once */
6896 +# define happy(x) { \
6897 + err_t ugh = x; \
6898 + if (ugh != NULL) \
6899 + if(openswan_passert_fail) { (*openswan_passert_fail)(ugh, __FILE__, __LINE__); } \
6900 + }
6901 +
6902 +#else /*!DEBUG*/
6903 +
6904 +# define impossible() abort()
6905 +# define bad_case(n) abort()
6906 +# define passert(pred) { } /* do nothing */
6907 +# define happy(x) { (void) x; } /* evaluate non-judgementally */
6908 +
6909 +#endif /*!DEBUG*/
6910 +
6911 +#endif /* _OPENSWAN_PASSERT_H */
6912 --- /dev/null Tue Mar 11 13:02:56 2003
6913 +++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004
6914 @@ -0,0 +1,54 @@
6915 +/*
6916 + * sanitize a string into a printable format.
6917 + *
6918 + * Copyright (C) 1998-2002 D. Hugh Redelmeier.
6919 + * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
6920 + *
6921 + * This library is free software; you can redistribute it and/or modify it
6922 + * under the terms of the GNU Library General Public License as published by
6923 + * the Free Software Foundation; either version 2 of the License, or (at your
6924 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
6925 + *
6926 + * This library is distributed in the hope that it will be useful, but
6927 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
6928 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
6929 + * License for more details.
6930 + *
6931 + * RCSID $Id: pfkey_debug.h,v 1.3 2004/04/05 19:55:07 mcr Exp $
6932 + */
6933 +
6934 +#ifndef _FREESWAN_PFKEY_DEBUG_H
6935 +#define _FREESWAN_PFKEY_DEBUG_H
6936 +
6937 +#ifdef __KERNEL__
6938 +
6939 +/* note, kernel version ignores pfkey levels */
6940 +# define DEBUGGING(level,args...) \
6941 + KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
6942 +
6943 +# define ERROR(args...) printk(KERN_ERR "klips:" args)
6944 +
6945 +#else
6946 +
6947 +extern unsigned int pfkey_lib_debug;
6948 +
6949 +extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
6950 +extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
6951 +
6952 +#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \
6953 + if(pfkey_debug_func != NULL) { \
6954 + (*pfkey_debug_func)("pfkey_lib_debug:" args); \
6955 + } else { \
6956 + printf("pfkey_lib_debug:" args); \
6957 + } }
6958 +
6959 +#define ERROR(args...) if(pfkey_error_func != NULL) { \
6960 + (*pfkey_error_func)("pfkey_lib_debug:" args); \
6961 + }
6962 +
6963 +# define MALLOC(size) malloc(size)
6964 +# define FREE(obj) free(obj)
6965 +
6966 +#endif
6967 +
6968 +#endif
6969 --- /dev/null Tue Mar 11 13:02:56 2003
6970 +++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004
6971 @@ -0,0 +1,280 @@
6972 +/*
6973 + * RCSID $Id: radij.h,v 1.13 2004/04/05 19:55:08 mcr Exp $
6974 + */
6975 +
6976 +/*
6977 + * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
6978 + *
6979 + * Variable and procedure names have been modified so that they don't
6980 + * conflict with the original BSD code, as a small number of modifications
6981 + * have been introduced and we may want to reuse this code in BSD.
6982 + *
6983 + * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
6984 + * chi or a German ch sound (as `doch', not as in `milch'), or even a
6985 + * spanish j as in Juan. It is not as far back in the throat like
6986 + * the corresponding Hebrew sound, nor is it a soft breath like the English h.
6987 + * It has nothing to do with the Dutch ij sound.
6988 + *
6989 + * Here is the appropriate copyright notice:
6990 + */
6991 +
6992 +/*
6993 + * Copyright (c) 1988, 1989, 1993
6994 + * The Regents of the University of California. All rights reserved.
6995 + *
6996 + * Redistribution and use in source and binary forms, with or without
6997 + * modification, are permitted provided that the following conditions
6998 + * are met:
6999 + * 1. Redistributions of source code must retain the above copyright
7000 + * notice, this list of conditions and the following disclaimer.
7001 + * 2. Redistributions in binary form must reproduce the above copyright
7002 + * notice, this list of conditions and the following disclaimer in the
7003 + * documentation and/or other materials provided with the distribution.
7004 + * 3. All advertising materials mentioning features or use of this software
7005 + * must display the following acknowledgement:
7006 + * This product includes software developed by the University of
7007 + * California, Berkeley and its contributors.
7008 + * 4. Neither the name of the University nor the names of its contributors
7009 + * may be used to endorse or promote products derived from this software
7010 + * without specific prior written permission.
7011 + *
7012 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
7013 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7014 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
7015 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
7016 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
7017 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
7018 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
7019 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
7020 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
7021 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7022 + * SUCH DAMAGE.
7023 + *
7024 + * @(#)radix.h 8.1 (Berkeley) 6/10/93
7025 + */
7026 +
7027 +#ifndef _RADIJ_H_
7028 +#define _RADIJ_H_
7029 +
7030 +/*
7031 +#define RJ_DEBUG
7032 +*/
7033 +
7034 +#ifdef __KERNEL__
7035 +
7036 +#ifndef __P
7037 +#ifdef __STDC__
7038 +#define __P(x) x
7039 +#else
7040 +#define __P(x) ()
7041 +#endif
7042 +#endif
7043 +
7044 +/*
7045 + * Radix search tree node layout.
7046 + */
7047 +
7048 +struct radij_node
7049 +{
7050 + struct radij_mask *rj_mklist; /* list of masks contained in subtree */
7051 + struct radij_node *rj_p; /* parent */
7052 + short rj_b; /* bit offset; -1-index(netmask) */
7053 + char rj_bmask; /* node: mask for bit test*/
7054 + u_char rj_flags; /* enumerated next */
7055 +#define RJF_NORMAL 1 /* leaf contains normal route */
7056 +#define RJF_ROOT 2 /* leaf is root leaf for tree */
7057 +#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
7058 + union {
7059 + struct { /* leaf only data: */
7060 + caddr_t rj_Key; /* object of search */
7061 + caddr_t rj_Mask; /* netmask, if present */
7062 + struct radij_node *rj_Dupedkey;
7063 + } rj_leaf;
7064 + struct { /* node only data: */
7065 + int rj_Off; /* where to start compare */
7066 + struct radij_node *rj_L;/* progeny */
7067 + struct radij_node *rj_R;/* progeny */
7068 + }rj_node;
7069 + } rj_u;
7070 +#ifdef RJ_DEBUG
7071 + int rj_info;
7072 + struct radij_node *rj_twin;
7073 + struct radij_node *rj_ybro;
7074 +#endif
7075 +};
7076 +
7077 +#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
7078 +#define rj_key rj_u.rj_leaf.rj_Key
7079 +#define rj_mask rj_u.rj_leaf.rj_Mask
7080 +#define rj_off rj_u.rj_node.rj_Off
7081 +#define rj_l rj_u.rj_node.rj_L
7082 +#define rj_r rj_u.rj_node.rj_R
7083 +
7084 +/*
7085 + * Annotations to tree concerning potential routes applying to subtrees.
7086 + */
7087 +
7088 +extern struct radij_mask {
7089 + short rm_b; /* bit offset; -1-index(netmask) */
7090 + char rm_unused; /* cf. rj_bmask */
7091 + u_char rm_flags; /* cf. rj_flags */
7092 + struct radij_mask *rm_mklist; /* more masks to try */
7093 + caddr_t rm_mask; /* the mask */
7094 + int rm_refs; /* # of references to this struct */
7095 +} *rj_mkfreelist;
7096 +
7097 +#define MKGet(m) {\
7098 + if (rj_mkfreelist) {\
7099 + m = rj_mkfreelist; \
7100 + rj_mkfreelist = (m)->rm_mklist; \
7101 + } else \
7102 + R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
7103 +
7104 +#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
7105 +
7106 +struct radij_node_head {
7107 + struct radij_node *rnh_treetop;
7108 + int rnh_addrsize; /* permit, but not require fixed keys */
7109 + int rnh_pktsize; /* permit, but not require fixed keys */
7110 +#if 0
7111 + struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
7112 + __P((void *v, void *mask,
7113 + struct radij_node_head *head, struct radij_node nodes[]));
7114 +#endif
7115 + int (*rnh_addaddr) /* add based on sockaddr */
7116 + __P((void *v, void *mask,
7117 + struct radij_node_head *head, struct radij_node nodes[]));
7118 + struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
7119 + __P((void *v, void *mask,
7120 + struct radij_node_head *head, struct radij_node nodes[]));
7121 +#if 0
7122 + struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
7123 + __P((void *v, void *mask, struct radij_node_head *head));
7124 +#endif
7125 + int (*rnh_deladdr) /* remove based on sockaddr */
7126 + __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
7127 + struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
7128 + __P((void *v, void *mask, struct radij_node_head *head));
7129 + struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
7130 + __P((void *v, struct radij_node_head *head));
7131 + struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
7132 + __P((void *v, struct radij_node_head *head));
7133 + int (*rnh_walktree) /* traverse tree */
7134 + __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7135 + struct radij_node rnh_nodes[3]; /* empty tree for common case */
7136 +};
7137 +
7138 +
7139 +#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7140 +#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
7141 +#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
7142 +#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
7143 +#define Free(p) kfree((caddr_t)p);
7144 +
7145 +void rj_init __P((void));
7146 +int rj_inithead __P((void **, int));
7147 +int rj_refines __P((void *, void *));
7148 +int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
7149 +struct radij_node
7150 + *rj_addmask __P((void *, int, int)) /* , rgb */ ;
7151 +int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
7152 + struct radij_node [2])) /* , rgb */ ;
7153 +int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
7154 +struct radij_node /* rgb */
7155 + *rj_insert __P((void *, struct radij_node_head *, int *,
7156 + struct radij_node [2])),
7157 + *rj_match __P((void *, struct radij_node_head *)),
7158 + *rj_newpair __P((void *, int, struct radij_node[2])),
7159 + *rj_search __P((void *, struct radij_node *)),
7160 + *rj_search_m __P((void *, struct radij_node *, void *));
7161 +
7162 +void rj_deltree(struct radij_node_head *);
7163 +void rj_delnodes(struct radij_node *);
7164 +void rj_free_mkfreelist(void);
7165 +int radijcleartree(void);
7166 +int radijcleanup(void);
7167 +
7168 +extern struct radij_node_head *mask_rjhead;
7169 +extern int maj_keylen;
7170 +#endif /* __KERNEL__ */
7171 +
7172 +#endif /* _RADIJ_H_ */
7173 +
7174 +
7175 +/*
7176 + * $Log: radij.h,v $
7177 + * Revision 1.13 2004/04/05 19:55:08 mcr
7178 + * Moved from linux/include/freeswan/radij.h,v
7179 + *
7180 + * Revision 1.12 2002/04/24 07:36:48 mcr
7181 + * Moved from ./klips/net/ipsec/radij.h,v
7182 + *
7183 + * Revision 1.11 2001/09/20 15:33:00 rgb
7184 + * Min/max cleanup.
7185 + *
7186 + * Revision 1.10 1999/11/18 04:09:20 rgb
7187 + * Replaced all kernel version macros to shorter, readable form.
7188 + *
7189 + * Revision 1.9 1999/05/05 22:02:33 rgb
7190 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
7191 + *
7192 + * Revision 1.8 1999/04/29 15:24:58 rgb
7193 + * Add check for existence of macros min/max.
7194 + *
7195 + * Revision 1.7 1999/04/11 00:29:02 henry
7196 + * GPL boilerplate
7197 + *
7198 + * Revision 1.6 1999/04/06 04:54:29 rgb
7199 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
7200 + * patch shell fixes.
7201 + *
7202 + * Revision 1.5 1999/01/22 06:30:32 rgb
7203 + * 64-bit clean-up.
7204 + *
7205 + * Revision 1.4 1998/11/30 13:22:55 rgb
7206 + * Rationalised all the klips kernel file headers. They are much shorter
7207 + * now and won't conflict under RH5.2.
7208 + *
7209 + * Revision 1.3 1998/10/25 02:43:27 rgb
7210 + * Change return type on rj_addroute and rj_delete and add and argument
7211 + * to the latter to be able to transmit more infomation about errors.
7212 + *
7213 + * Revision 1.2 1998/07/14 18:09:51 rgb
7214 + * Add a routine to clear eroute table.
7215 + * Added #ifdef __KERNEL__ directives to restrict scope of header.
7216 + *
7217 + * Revision 1.1 1998/06/18 21:30:22 henry
7218 + * move sources from klips/src to klips/net/ipsec to keep stupid kernel
7219 + * build scripts happier about symlinks
7220 + *
7221 + * Revision 1.4 1998/05/25 20:34:16 rgb
7222 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
7223 + *
7224 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
7225 + * add ipsec_rj_walker_delete.
7226 + *
7227 + * Recover memory for eroute table on unload of module.
7228 + *
7229 + * Revision 1.3 1998/04/22 16:51:37 rgb
7230 + * Tidy up radij debug code from recent rash of modifications to debug code.
7231 + *
7232 + * Revision 1.2 1998/04/14 17:30:38 rgb
7233 + * Fix up compiling errors for radij tree memory reclamation.
7234 + *
7235 + * Revision 1.1 1998/04/09 03:06:16 henry
7236 + * sources moved up from linux/net/ipsec
7237 + *
7238 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
7239 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
7240 + *
7241 + * Revision 0.4 1997/01/15 01:28:15 ji
7242 + * No changes.
7243 + *
7244 + * Revision 0.3 1996/11/20 14:44:45 ji
7245 + * Release update only.
7246 + *
7247 + * Revision 0.2 1996/11/02 00:18:33 ji
7248 + * First limited release.
7249 + *
7250 + *
7251 + */
7252 --- /dev/null Tue Mar 11 13:02:56 2003
7253 +++ linux/include/pfkey.h Mon Feb 9 13:51:03 2004
7254 @@ -0,0 +1,529 @@
7255 +/*
7256 + * FreeS/WAN specific PF_KEY headers
7257 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
7258 + *
7259 + * This program is free software; you can redistribute it and/or modify it
7260 + * under the terms of the GNU General Public License as published by the
7261 + * Free Software Foundation; either version 2 of the License, or (at your
7262 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
7263 + *
7264 + * This program is distributed in the hope that it will be useful, but
7265 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
7266 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
7267 + * for more details.
7268 + *
7269 + * RCSID $Id: pfkey.h,v 1.49 2005/05/11 00:57:29 mcr Exp $
7270 + */
7271 +
7272 +#ifndef __NET_IPSEC_PF_KEY_H
7273 +#define __NET_IPSEC_PF_KEY_H
7274 +#ifdef __KERNEL__
7275 +extern struct proto_ops pfkey_proto_ops;
7276 +typedef struct sock pfkey_sock;
7277 +extern int debug_pfkey;
7278 +
7279 +extern /* void */ int pfkey_init(void);
7280 +extern /* void */ int pfkey_cleanup(void);
7281 +
7282 +struct socket_list
7283 +{
7284 + struct socket *socketp;
7285 + struct socket_list *next;
7286 +};
7287 +extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
7288 +extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
7289 +extern struct socket_list *pfkey_open_sockets;
7290 +extern struct socket_list *pfkey_registered_sockets[];
7291 +
7292 +struct ipsec_alg_supported
7293 +{
7294 + uint16_t ias_exttype;
7295 + uint8_t ias_id;
7296 + uint8_t ias_ivlen;
7297 + uint16_t ias_keyminbits;
7298 + uint16_t ias_keymaxbits;
7299 + char *ias_name;
7300 +};
7301 +
7302 +extern struct supported_list *pfkey_supported_list[];
7303 +struct supported_list
7304 +{
7305 + struct ipsec_alg_supported *supportedp;
7306 + struct supported_list *next;
7307 +};
7308 +extern int pfkey_list_insert_supported(struct ipsec_alg_supported*, struct supported_list**);
7309 +extern int pfkey_list_remove_supported(struct ipsec_alg_supported*, struct supported_list**);
7310 +
7311 +struct sockaddr_key
7312 +{
7313 + uint16_t key_family; /* PF_KEY */
7314 + uint16_t key_pad; /* not used */
7315 + uint32_t key_pid; /* process ID */
7316 +};
7317 +
7318 +struct pfkey_extracted_data
7319 +{
7320 + struct ipsec_sa* ips;
7321 + struct ipsec_sa* ips2;
7322 + struct eroute *eroute;
7323 +};
7324 +
7325 +/* forward reference */
7326 +struct sadb_ext;
7327 +struct sadb_msg;
7328 +struct sockaddr;
7329 +struct sadb_comb;
7330 +struct sadb_sadb;
7331 +struct sadb_alg;
7332 +
7333 +extern int
7334 +pfkey_alloc_eroute(struct eroute** eroute);
7335 +
7336 +extern int
7337 +pfkey_sa_process(struct sadb_ext *pfkey_ext,
7338 + struct pfkey_extracted_data* extr);
7339 +
7340 +extern int
7341 +pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
7342 + struct pfkey_extracted_data* extr);
7343 +
7344 +extern int
7345 +pfkey_address_process(struct sadb_ext *pfkey_ext,
7346 + struct pfkey_extracted_data* extr);
7347 +
7348 +extern int
7349 +pfkey_key_process(struct sadb_ext *pfkey_ext,
7350 + struct pfkey_extracted_data* extr);
7351 +
7352 +extern int
7353 +pfkey_ident_process(struct sadb_ext *pfkey_ext,
7354 + struct pfkey_extracted_data* extr);
7355 +
7356 +extern int
7357 +pfkey_sens_process(struct sadb_ext *pfkey_ext,
7358 + struct pfkey_extracted_data* extr);
7359 +
7360 +extern int
7361 +pfkey_prop_process(struct sadb_ext *pfkey_ext,
7362 + struct pfkey_extracted_data* extr);
7363 +
7364 +extern int
7365 +pfkey_supported_process(struct sadb_ext *pfkey_ext,
7366 + struct pfkey_extracted_data* extr);
7367 +
7368 +extern int
7369 +pfkey_spirange_process(struct sadb_ext *pfkey_ext,
7370 + struct pfkey_extracted_data* extr);
7371 +
7372 +extern int
7373 +pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
7374 + struct pfkey_extracted_data* extr);
7375 +
7376 +extern int
7377 +pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
7378 + struct pfkey_extracted_data* extr);
7379 +
7380 +extern int
7381 +pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
7382 + struct pfkey_extracted_data* extr);
7383 +
7384 +extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
7385 +extern int pfkey_expire(struct ipsec_sa *, int);
7386 +extern int pfkey_acquire(struct ipsec_sa *);
7387 +#else /* ! __KERNEL__ */
7388 +
7389 +extern void (*pfkey_debug_func)(const char *message, ...);
7390 +extern void (*pfkey_error_func)(const char *message, ...);
7391 +extern void pfkey_print(struct sadb_msg *msg, FILE *out);
7392 +
7393 +
7394 +#endif /* __KERNEL__ */
7395 +
7396 +extern uint8_t satype2proto(uint8_t satype);
7397 +extern uint8_t proto2satype(uint8_t proto);
7398 +extern char* satype2name(uint8_t satype);
7399 +extern char* proto2name(uint8_t proto);
7400 +
7401 +struct key_opt
7402 +{
7403 + uint32_t key_pid; /* process ID */
7404 + struct sock *sk;
7405 +};
7406 +
7407 +#define key_pid(sk) ((struct key_opt*)&((sk)->sk_protinfo))->key_pid
7408 +
7409 +/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
7410 + * words.
7411 + */
7412 +#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
7413 +#define BITS_PER_OCTET 8
7414 +#define OCTETBITS 8
7415 +#define PFKEYBITS 64
7416 +#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
7417 +#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
7418 +
7419 +#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN)
7420 +#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN)
7421 +
7422 +
7423 +#define PFKEYv2_MAX_MSGSIZE 4096
7424 +
7425 +/*
7426 + * PF_KEYv2 permitted and required extensions in and out bitmaps
7427 + */
7428 +struct pf_key_ext_parsers_def {
7429 + int (*parser)(struct sadb_ext*);
7430 + char *parser_name;
7431 +};
7432 +
7433 +
7434 +#define SADB_EXTENSIONS_MAX 31
7435 +extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX];
7436 +#define EXT_BITS_IN 0
7437 +#define EXT_BITS_OUT 1
7438 +#define EXT_BITS_PERM 0
7439 +#define EXT_BITS_REQ 1
7440 +
7441 +extern void pfkey_extensions_init(struct sadb_ext *extensions[]);
7442 +extern void pfkey_extensions_free(struct sadb_ext *extensions[]);
7443 +extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
7444 +
7445 +extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
7446 + struct pf_key_ext_parsers_def *ext_parsers[],
7447 + struct sadb_ext **extensions,
7448 + int dir);
7449 +
7450 +extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg);
7451 +
7452 +/*
7453 + * PF_KEYv2 build function prototypes
7454 + */
7455 +
7456 +int
7457 +pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
7458 + uint8_t msg_type,
7459 + uint8_t satype,
7460 + uint8_t msg_errno,
7461 + uint32_t seq,
7462 + uint32_t pid);
7463 +
7464 +int
7465 +pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
7466 + uint16_t exttype,
7467 + uint32_t spi, /* in network order */
7468 + uint8_t replay_window,
7469 + uint8_t sa_state,
7470 + uint8_t auth,
7471 + uint8_t encrypt,
7472 + uint32_t flags,
7473 + uint32_t/*IPsecSAref_t*/ ref);
7474 +
7475 +int
7476 +pfkey_sa_build(struct sadb_ext ** pfkey_ext,
7477 + uint16_t exttype,
7478 + uint32_t spi, /* in network order */
7479 + uint8_t replay_window,
7480 + uint8_t sa_state,
7481 + uint8_t auth,
7482 + uint8_t encrypt,
7483 + uint32_t flags);
7484 +
7485 +int
7486 +pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
7487 + uint16_t exttype,
7488 + uint32_t allocations,
7489 + uint64_t bytes,
7490 + uint64_t addtime,
7491 + uint64_t usetime,
7492 + uint32_t packets);
7493 +
7494 +int
7495 +pfkey_address_build(struct sadb_ext** pfkey_ext,
7496 + uint16_t exttype,
7497 + uint8_t proto,
7498 + uint8_t prefixlen,
7499 + struct sockaddr* address);
7500 +
7501 +int
7502 +pfkey_key_build(struct sadb_ext** pfkey_ext,
7503 + uint16_t exttype,
7504 + uint16_t key_bits,
7505 + char* key);
7506 +
7507 +int
7508 +pfkey_ident_build(struct sadb_ext** pfkey_ext,
7509 + uint16_t exttype,
7510 + uint16_t ident_type,
7511 + uint64_t ident_id,
7512 + uint8_t ident_len,
7513 + char* ident_string);
7514 +
7515 +#ifdef __KERNEL__
7516 +extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
7517 +extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7518 +extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
7519 +#endif /* __KERNEL__ */
7520 +int
7521 +pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
7522 + uint8_t type);
7523 +int
7524 +pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
7525 + uint16_t exttype,
7526 + uint16_t port);
7527 +
7528 +int
7529 +pfkey_sens_build(struct sadb_ext** pfkey_ext,
7530 + uint32_t dpd,
7531 + uint8_t sens_level,
7532 + uint8_t sens_len,
7533 + uint64_t* sens_bitmap,
7534 + uint8_t integ_level,
7535 + uint8_t integ_len,
7536 + uint64_t* integ_bitmap);
7537 +
7538 +int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
7539 +
7540 +
7541 +int
7542 +pfkey_prop_build(struct sadb_ext** pfkey_ext,
7543 + uint8_t replay,
7544 + unsigned int comb_num,
7545 + struct sadb_comb* comb);
7546 +
7547 +int
7548 +pfkey_supported_build(struct sadb_ext** pfkey_ext,
7549 + uint16_t exttype,
7550 + unsigned int alg_num,
7551 + struct sadb_alg* alg);
7552 +
7553 +int
7554 +pfkey_spirange_build(struct sadb_ext** pfkey_ext,
7555 + uint16_t exttype,
7556 + uint32_t min,
7557 + uint32_t max);
7558 +
7559 +int
7560 +pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
7561 +
7562 +int
7563 +pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
7564 + uint8_t satype);
7565 +
7566 +int
7567 +pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
7568 + uint32_t tunnel,
7569 + uint32_t netlink,
7570 + uint32_t xform,
7571 + uint32_t eroute,
7572 + uint32_t spi,
7573 + uint32_t radij,
7574 + uint32_t esp,
7575 + uint32_t ah,
7576 + uint32_t rcv,
7577 + uint32_t pfkey,
7578 + uint32_t ipcomp,
7579 + uint32_t verbose);
7580 +
7581 +int
7582 +pfkey_msg_build(struct sadb_msg** pfkey_msg,
7583 + struct sadb_ext* extensions[],
7584 + int dir);
7585 +
7586 +/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
7587 +const char *
7588 +pfkey_v2_sadb_ext_string(int extnum);
7589 +
7590 +const char *
7591 +pfkey_v2_sadb_type_string(int sadb_type);
7592 +
7593 +
7594 +#endif /* __NET_IPSEC_PF_KEY_H */
7595 +
7596 +/*
7597 + * $Log: pfkey.h,v $
7598 + * Revision 1.49 2005/05/11 00:57:29 mcr
7599 + * rename struct supported -> struct ipsec_alg_supported.
7600 + * make pfkey.h more standalone.
7601 + *
7602 + * Revision 1.48 2005/05/01 03:12:50 mcr
7603 + * include name of algorithm in datastructure.
7604 + *
7605 + * Revision 1.47 2004/08/21 00:44:14 mcr
7606 + * simplify definition of nat_t related prototypes.
7607 + *
7608 + * Revision 1.46 2004/08/04 16:27:22 mcr
7609 + * 2.6 sk_ options.
7610 + *
7611 + * Revision 1.45 2004/04/06 02:49:00 mcr
7612 + * pullup of algo code from alg-branch.
7613 + *
7614 + * Revision 1.44 2003/12/10 01:20:01 mcr
7615 + * NAT-traversal patches to KLIPS.
7616 + *
7617 + * Revision 1.43 2003/10/31 02:26:44 mcr
7618 + * pulled up port-selector patches.
7619 + *
7620 + * Revision 1.42.2.2 2003/10/29 01:09:32 mcr
7621 + * added debugging for pfkey library.
7622 + *
7623 + * Revision 1.42.2.1 2003/09/21 13:59:34 mcr
7624 + * pre-liminary X.509 patch - does not yet pass tests.
7625 + *
7626 + * Revision 1.42 2003/08/25 22:08:19 mcr
7627 + * removed pfkey_proto_init() from pfkey.h for 2.6 support.
7628 + *
7629 + * Revision 1.41 2003/05/07 17:28:57 mcr
7630 + * new function pfkey_debug_func added for us in debugging from
7631 +
7632 + * pfkey library.
7633 + *
7634 + * Revision 1.40 2003/01/30 02:31:34 rgb
7635 + *
7636 + * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
7637 + *
7638 + * Revision 1.39 2002/09/20 15:40:21 rgb
7639 + * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
7640 + * Added ref parameter to pfkey_sa_build().
7641 + * Cleaned out unused cruft.
7642 + *
7643 + * Revision 1.38 2002/05/14 02:37:24 rgb
7644 + * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
7645 + * ipsec_sa or ipsec_sa.
7646 + * Added function prototypes for the functions moved to
7647 + * pfkey_v2_ext_process.c.
7648 + *
7649 + * Revision 1.37 2002/04/24 07:36:49 mcr
7650 + * Moved from ./lib/pfkey.h,v
7651 + *
7652 + * Revision 1.36 2002/01/20 20:34:49 mcr
7653 + * added pfkey_v2_sadb_type_string to decode sadb_type to string.
7654 + *
7655 + * Revision 1.35 2001/11/27 05:27:47 mcr
7656 + * pfkey parses are now maintained by a structure
7657 + * that includes their name for debug purposes.
7658 + *
7659 + * Revision 1.34 2001/11/26 09:23:53 rgb
7660 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
7661 + *
7662 + * Revision 1.33 2001/11/06 19:47:47 rgb
7663 + * Added packet parameter to lifetime and comb structures.
7664 + *
7665 + * Revision 1.32 2001/09/08 21:13:34 rgb
7666 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
7667 + *
7668 + * Revision 1.31 2001/06/14 19:35:16 rgb
7669 + * Update copyright date.
7670 + *
7671 + * Revision 1.30 2001/02/27 07:04:52 rgb
7672 + * Added satype2name prototype.
7673 + *
7674 + * Revision 1.29 2001/02/26 19:59:33 rgb
7675 + * Ditch unused sadb_satype2proto[], replaced by satype2proto().
7676 + *
7677 + * Revision 1.28 2000/10/10 20:10:19 rgb
7678 + * Added support for debug_ipcomp and debug_verbose to klipsdebug.
7679 + *
7680 + * Revision 1.27 2000/09/21 04:20:45 rgb
7681 + * Fixed array size off-by-one error. (Thanks Svenning!)
7682 + *
7683 + * Revision 1.26 2000/09/12 03:26:05 rgb
7684 + * Added pfkey_acquire prototype.
7685 + *
7686 + * Revision 1.25 2000/09/08 19:21:28 rgb
7687 + * Fix pfkey_prop_build() parameter to be only single indirection.
7688 + *
7689 + * Revision 1.24 2000/09/01 18:46:42 rgb
7690 + * Added a supported algorithms array lists, one per satype and registered
7691 + * existing algorithms.
7692 + * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
7693 + * list.
7694 + *
7695 + * Revision 1.23 2000/08/27 01:55:26 rgb
7696 + * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
7697 + *
7698 + * Revision 1.22 2000/08/20 21:39:23 rgb
7699 + * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
7700 + * pfkey_expire().
7701 + *
7702 + * Revision 1.21 2000/08/15 17:29:23 rgb
7703 + * Fixes from SZI to untested pfkey_prop_build().
7704 + *
7705 + * Revision 1.20 2000/05/10 20:14:19 rgb
7706 + * Fleshed out sensitivity, proposal and supported extensions.
7707 + *
7708 + * Revision 1.19 2000/03/16 14:07:23 rgb
7709 + * Renamed ALIGN macro to avoid fighting with others in kernel.
7710 + *
7711 + * Revision 1.18 2000/01/22 23:24:06 rgb
7712 + * Added prototypes for proto2satype(), satype2proto() and proto2name().
7713 + *
7714 + * Revision 1.17 2000/01/21 06:26:59 rgb
7715 + * Converted from double tdb arguments to one structure (extr)
7716 + * containing pointers to all temporary information structures.
7717 + * Added klipsdebug switching capability.
7718 + * Dropped unused argument to pfkey_x_satype_build().
7719 + *
7720 + * Revision 1.16 1999/12/29 21:17:41 rgb
7721 + * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
7722 + * parameter for cleaner manipulation of extensions[] and to guard
7723 + * against potential memory leaks.
7724 + * Changed the I/F to pfkey_msg_free() for the same reason.
7725 + *
7726 + * Revision 1.15 1999/12/09 23:12:54 rgb
7727 + * Added macro for BITS_PER_OCTET.
7728 + * Added argument to pfkey_sa_build() to do eroutes.
7729 + *
7730 + * Revision 1.14 1999/12/08 20:33:25 rgb
7731 + * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
7732 + *
7733 + * Revision 1.13 1999/12/07 19:53:40 rgb
7734 + * Removed unused first argument from extension parsers.
7735 + * Changed __u* types to uint* to avoid use of asm/types.h and
7736 + * sys/types.h in userspace code.
7737 + * Added function prototypes for pfkey message and extensions
7738 + * initialisation and cleanup.
7739 + *
7740 + * Revision 1.12 1999/12/01 22:19:38 rgb
7741 + * Change pfkey_sa_build to accept an SPI in network byte order.
7742 + *
7743 + * Revision 1.11 1999/11/27 11:55:26 rgb
7744 + * Added extern sadb_satype2proto to enable moving protocol lookup table
7745 + * to lib/pfkey_v2_parse.c.
7746 + * Delete unused, moved typedefs.
7747 + * Add argument to pfkey_msg_parse() for direction.
7748 + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
7749 + *
7750 + * Revision 1.10 1999/11/23 22:29:21 rgb
7751 + * This file has been moved in the distribution from klips/net/ipsec to
7752 + * lib.
7753 + * Add macros for dealing with alignment and rounding up more opaquely.
7754 + * The uint<n>_t type defines have been moved to freeswan.h to avoid
7755 + * chicken-and-egg problems.
7756 + * Add macros for dealing with alignment and rounding up more opaque.
7757 + * Added prototypes for using extention header bitmaps.
7758 + * Added prototypes of all the build functions.
7759 + *
7760 + * Revision 1.9 1999/11/20 21:59:48 rgb
7761 + * Moved socketlist type declarations and prototypes for shared use.
7762 + * Slightly modified scope of sockaddr_key declaration.
7763 + *
7764 + * Revision 1.8 1999/11/17 14:34:25 rgb
7765 + * Protect sa_family_t from being used in userspace with GLIBC<2.
7766 + *
7767 + * Revision 1.7 1999/10/27 19:40:35 rgb
7768 + * Add a maximum PFKEY packet size macro.
7769 + *
7770 + * Revision 1.6 1999/10/26 16:58:58 rgb
7771 + * Created a sockaddr_key and key_opt socket extension structures.
7772 + *
7773 + * Revision 1.5 1999/06/10 05:24:41 rgb
7774 + * Renamed variables to reduce confusion.
7775 + *
7776 + * Revision 1.4 1999/04/29 15:21:11 rgb
7777 + * Add pfkey support to debugging.
7778 + * Add return values to init and cleanup functions.
7779 + *
7780 + * Revision 1.3 1999/04/15 17:58:07 rgb
7781 + * Add RCSID labels.
7782 + *
7783 + */
7784 --- /dev/null Tue Mar 11 13:02:56 2003
7785 +++ linux/include/pfkeyv2.h Mon Feb 9 13:51:03 2004
7786 @@ -0,0 +1,472 @@
7787 +/*
7788 + * RCSID $Id: pfkeyv2.h,v 1.31 2005/04/14 01:14:54 mcr Exp $
7789 + */
7790 +
7791 +/*
7792 +RFC 2367 PF_KEY Key Management API July 1998
7793 +
7794 +
7795 +Appendix D: Sample Header File
7796 +
7797 +This file defines structures and symbols for the PF_KEY Version 2
7798 +key management interface. It was written at the U.S. Naval Research
7799 +Laboratory. This file is in the public domain. The authors ask that
7800 +you leave this credit intact on any copies of this file.
7801 +*/
7802 +#ifndef __PFKEY_V2_H
7803 +#define __PFKEY_V2_H 1
7804 +
7805 +#define PF_KEY_V2 2
7806 +#define PFKEYV2_REVISION 199806L
7807 +
7808 +#define SADB_RESERVED 0
7809 +#define SADB_GETSPI 1
7810 +#define SADB_UPDATE 2
7811 +#define SADB_ADD 3
7812 +#define SADB_DELETE 4
7813 +#define SADB_GET 5
7814 +#define SADB_ACQUIRE 6
7815 +#define SADB_REGISTER 7
7816 +#define SADB_EXPIRE 8
7817 +#define SADB_FLUSH 9
7818 +#define SADB_DUMP 10
7819 +#define SADB_X_PROMISC 11
7820 +#define SADB_X_PCHANGE 12
7821 +#define SADB_X_GRPSA 13
7822 +#define SADB_X_ADDFLOW 14
7823 +#define SADB_X_DELFLOW 15
7824 +#define SADB_X_DEBUG 16
7825 +#define SADB_X_NAT_T_NEW_MAPPING 17
7826 +#define SADB_MAX 17
7827 +
7828 +struct sadb_msg {
7829 + uint8_t sadb_msg_version;
7830 + uint8_t sadb_msg_type;
7831 + uint8_t sadb_msg_errno;
7832 + uint8_t sadb_msg_satype;
7833 + uint16_t sadb_msg_len;
7834 + uint16_t sadb_msg_reserved;
7835 + uint32_t sadb_msg_seq;
7836 + uint32_t sadb_msg_pid;
7837 +};
7838 +
7839 +struct sadb_ext {
7840 + uint16_t sadb_ext_len;
7841 + uint16_t sadb_ext_type;
7842 +};
7843 +
7844 +struct sadb_sa {
7845 + uint16_t sadb_sa_len;
7846 + uint16_t sadb_sa_exttype;
7847 + uint32_t sadb_sa_spi;
7848 + uint8_t sadb_sa_replay;
7849 + uint8_t sadb_sa_state;
7850 + uint8_t sadb_sa_auth;
7851 + uint8_t sadb_sa_encrypt;
7852 + uint32_t sadb_sa_flags;
7853 + uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
7854 + uint8_t sadb_x_reserved[4];
7855 +};
7856 +
7857 +struct sadb_sa_v1 {
7858 + uint16_t sadb_sa_len;
7859 + uint16_t sadb_sa_exttype;
7860 + uint32_t sadb_sa_spi;
7861 + uint8_t sadb_sa_replay;
7862 + uint8_t sadb_sa_state;
7863 + uint8_t sadb_sa_auth;
7864 + uint8_t sadb_sa_encrypt;
7865 + uint32_t sadb_sa_flags;
7866 +};
7867 +
7868 +struct sadb_lifetime {
7869 + uint16_t sadb_lifetime_len;
7870 + uint16_t sadb_lifetime_exttype;
7871 + uint32_t sadb_lifetime_allocations;
7872 + uint64_t sadb_lifetime_bytes;
7873 + uint64_t sadb_lifetime_addtime;
7874 + uint64_t sadb_lifetime_usetime;
7875 + uint32_t sadb_x_lifetime_packets;
7876 + uint32_t sadb_x_lifetime_reserved;
7877 +};
7878 +
7879 +struct sadb_address {
7880 + uint16_t sadb_address_len;
7881 + uint16_t sadb_address_exttype;
7882 + uint8_t sadb_address_proto;
7883 + uint8_t sadb_address_prefixlen;
7884 + uint16_t sadb_address_reserved;
7885 +};
7886 +
7887 +struct sadb_key {
7888 + uint16_t sadb_key_len;
7889 + uint16_t sadb_key_exttype;
7890 + uint16_t sadb_key_bits;
7891 + uint16_t sadb_key_reserved;
7892 +};
7893 +
7894 +struct sadb_ident {
7895 + uint16_t sadb_ident_len;
7896 + uint16_t sadb_ident_exttype;
7897 + uint16_t sadb_ident_type;
7898 + uint16_t sadb_ident_reserved;
7899 + uint64_t sadb_ident_id;
7900 +};
7901 +
7902 +struct sadb_sens {
7903 + uint16_t sadb_sens_len;
7904 + uint16_t sadb_sens_exttype;
7905 + uint32_t sadb_sens_dpd;
7906 + uint8_t sadb_sens_sens_level;
7907 + uint8_t sadb_sens_sens_len;
7908 + uint8_t sadb_sens_integ_level;
7909 + uint8_t sadb_sens_integ_len;
7910 + uint32_t sadb_sens_reserved;
7911 +};
7912 +
7913 +struct sadb_prop {
7914 + uint16_t sadb_prop_len;
7915 + uint16_t sadb_prop_exttype;
7916 + uint8_t sadb_prop_replay;
7917 + uint8_t sadb_prop_reserved[3];
7918 +};
7919 +
7920 +struct sadb_comb {
7921 + uint8_t sadb_comb_auth;
7922 + uint8_t sadb_comb_encrypt;
7923 + uint16_t sadb_comb_flags;
7924 + uint16_t sadb_comb_auth_minbits;
7925 + uint16_t sadb_comb_auth_maxbits;
7926 + uint16_t sadb_comb_encrypt_minbits;
7927 + uint16_t sadb_comb_encrypt_maxbits;
7928 + uint32_t sadb_comb_reserved;
7929 + uint32_t sadb_comb_soft_allocations;
7930 + uint32_t sadb_comb_hard_allocations;
7931 + uint64_t sadb_comb_soft_bytes;
7932 + uint64_t sadb_comb_hard_bytes;
7933 + uint64_t sadb_comb_soft_addtime;
7934 + uint64_t sadb_comb_hard_addtime;
7935 + uint64_t sadb_comb_soft_usetime;
7936 + uint64_t sadb_comb_hard_usetime;
7937 + uint32_t sadb_x_comb_soft_packets;
7938 + uint32_t sadb_x_comb_hard_packets;
7939 +};
7940 +
7941 +struct sadb_supported {
7942 + uint16_t sadb_supported_len;
7943 + uint16_t sadb_supported_exttype;
7944 + uint32_t sadb_supported_reserved;
7945 +};
7946 +
7947 +struct sadb_alg {
7948 + uint8_t sadb_alg_id;
7949 + uint8_t sadb_alg_ivlen;
7950 + uint16_t sadb_alg_minbits;
7951 + uint16_t sadb_alg_maxbits;
7952 + uint16_t sadb_alg_reserved;
7953 +};
7954 +
7955 +struct sadb_spirange {
7956 + uint16_t sadb_spirange_len;
7957 + uint16_t sadb_spirange_exttype;
7958 + uint32_t sadb_spirange_min;
7959 + uint32_t sadb_spirange_max;
7960 + uint32_t sadb_spirange_reserved;
7961 +};
7962 +
7963 +struct sadb_x_kmprivate {
7964 + uint16_t sadb_x_kmprivate_len;
7965 + uint16_t sadb_x_kmprivate_exttype;
7966 + uint32_t sadb_x_kmprivate_reserved;
7967 +};
7968 +
7969 +struct sadb_x_satype {
7970 + uint16_t sadb_x_satype_len;
7971 + uint16_t sadb_x_satype_exttype;
7972 + uint8_t sadb_x_satype_satype;
7973 + uint8_t sadb_x_satype_reserved[3];
7974 +};
7975 +
7976 +struct sadb_x_policy {
7977 + uint16_t sadb_x_policy_len;
7978 + uint16_t sadb_x_policy_exttype;
7979 + uint16_t sadb_x_policy_type;
7980 + uint8_t sadb_x_policy_dir;
7981 + uint8_t sadb_x_policy_reserved;
7982 + uint32_t sadb_x_policy_id;
7983 + uint32_t sadb_x_policy_reserved2;
7984 +};
7985 +
7986 +struct sadb_x_debug {
7987 + uint16_t sadb_x_debug_len;
7988 + uint16_t sadb_x_debug_exttype;
7989 + uint32_t sadb_x_debug_tunnel;
7990 + uint32_t sadb_x_debug_netlink;
7991 + uint32_t sadb_x_debug_xform;
7992 + uint32_t sadb_x_debug_eroute;
7993 + uint32_t sadb_x_debug_spi;
7994 + uint32_t sadb_x_debug_radij;
7995 + uint32_t sadb_x_debug_esp;
7996 + uint32_t sadb_x_debug_ah;
7997 + uint32_t sadb_x_debug_rcv;
7998 + uint32_t sadb_x_debug_pfkey;
7999 + uint32_t sadb_x_debug_ipcomp;
8000 + uint32_t sadb_x_debug_verbose;
8001 + uint8_t sadb_x_debug_reserved[4];
8002 +};
8003 +
8004 +struct sadb_x_nat_t_type {
8005 + uint16_t sadb_x_nat_t_type_len;
8006 + uint16_t sadb_x_nat_t_type_exttype;
8007 + uint8_t sadb_x_nat_t_type_type;
8008 + uint8_t sadb_x_nat_t_type_reserved[3];
8009 +};
8010 +struct sadb_x_nat_t_port {
8011 + uint16_t sadb_x_nat_t_port_len;
8012 + uint16_t sadb_x_nat_t_port_exttype;
8013 + uint16_t sadb_x_nat_t_port_port;
8014 + uint16_t sadb_x_nat_t_port_reserved;
8015 +};
8016 +
8017 +/*
8018 + * A protocol structure for passing through the transport level
8019 + * protocol. It contains more fields than are actually used/needed
8020 + * but it is this way to be compatible with the structure used in
8021 + * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
8022 + */
8023 +struct sadb_protocol {
8024 + uint16_t sadb_protocol_len;
8025 + uint16_t sadb_protocol_exttype;
8026 + uint8_t sadb_protocol_proto;
8027 + uint8_t sadb_protocol_direction;
8028 + uint8_t sadb_protocol_flags;
8029 + uint8_t sadb_protocol_reserved2;
8030 +};
8031 +
8032 +#define SADB_EXT_RESERVED 0
8033 +#define SADB_EXT_SA 1
8034 +#define SADB_EXT_LIFETIME_CURRENT 2
8035 +#define SADB_EXT_LIFETIME_HARD 3
8036 +#define SADB_EXT_LIFETIME_SOFT 4
8037 +#define SADB_EXT_ADDRESS_SRC 5
8038 +#define SADB_EXT_ADDRESS_DST 6
8039 +#define SADB_EXT_ADDRESS_PROXY 7
8040 +#define SADB_EXT_KEY_AUTH 8
8041 +#define SADB_EXT_KEY_ENCRYPT 9
8042 +#define SADB_EXT_IDENTITY_SRC 10
8043 +#define SADB_EXT_IDENTITY_DST 11
8044 +#define SADB_EXT_SENSITIVITY 12
8045 +#define SADB_EXT_PROPOSAL 13
8046 +#define SADB_EXT_SUPPORTED_AUTH 14
8047 +#define SADB_EXT_SUPPORTED_ENCRYPT 15
8048 +#define SADB_EXT_SPIRANGE 16
8049 +#define SADB_X_EXT_KMPRIVATE 17
8050 +#define SADB_X_EXT_SATYPE2 18
8051 +#ifdef KERNEL26_HAS_KAME_DUPLICATES
8052 +#define SADB_X_EXT_POLICY 18
8053 +#endif
8054 +#define SADB_X_EXT_SA2 19
8055 +#define SADB_X_EXT_ADDRESS_DST2 20
8056 +#define SADB_X_EXT_ADDRESS_SRC_FLOW 21
8057 +#define SADB_X_EXT_ADDRESS_DST_FLOW 22
8058 +#define SADB_X_EXT_ADDRESS_SRC_MASK 23
8059 +#define SADB_X_EXT_ADDRESS_DST_MASK 24
8060 +#define SADB_X_EXT_DEBUG 25
8061 +#define SADB_X_EXT_PROTOCOL 26
8062 +#define SADB_X_EXT_NAT_T_TYPE 27
8063 +#define SADB_X_EXT_NAT_T_SPORT 28
8064 +#define SADB_X_EXT_NAT_T_DPORT 29
8065 +#define SADB_X_EXT_NAT_T_OA 30
8066 +#define SADB_EXT_MAX 30
8067 +
8068 +/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
8069 +#define SADB_X_EXT_ADDRESS_DELFLOW \
8070 + ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
8071 + | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
8072 + | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
8073 + | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
8074 +
8075 +#define SADB_SATYPE_UNSPEC 0
8076 +#define SADB_SATYPE_AH 2
8077 +#define SADB_SATYPE_ESP 3
8078 +#define SADB_SATYPE_RSVP 5
8079 +#define SADB_SATYPE_OSPFV2 6
8080 +#define SADB_SATYPE_RIPV2 7
8081 +#define SADB_SATYPE_MIP 8
8082 +#define SADB_X_SATYPE_IPIP 9
8083 +#ifdef KERNEL26_HAS_KAME_DUPLICATES
8084 +#define SADB_X_SATYPE_IPCOMP 9 /* ICK! */
8085 +#endif
8086 +#define SADB_X_SATYPE_COMP 10
8087 +#define SADB_X_SATYPE_INT 11
8088 +#define SADB_SATYPE_MAX 11
8089 +
8090 +enum sadb_sastate {
8091 + SADB_SASTATE_LARVAL=0,
8092 + SADB_SASTATE_MATURE=1,
8093 + SADB_SASTATE_DYING=2,
8094 + SADB_SASTATE_DEAD=3
8095 +};
8096 +#define SADB_SASTATE_MAX 3
8097 +
8098 +#define SADB_SAFLAGS_PFS 1
8099 +#define SADB_X_SAFLAGS_REPLACEFLOW 2
8100 +#define SADB_X_SAFLAGS_CLEARFLOW 4
8101 +#define SADB_X_SAFLAGS_INFLOW 8
8102 +
8103 +/* not obvious, but these are the same values as used in isakmp,
8104 + * and in freeswan/ipsec_policy.h. If you need to add any, they
8105 + * should be added as according to
8106 + * http://www.iana.org/assignments/isakmp-registry
8107 + *
8108 + * and if not, then please try to use a private-use value, and
8109 + * consider asking IANA to assign a value.
8110 + */
8111 +#define SADB_AALG_NONE 0
8112 +#define SADB_AALG_MD5HMAC 2
8113 +#define SADB_AALG_SHA1HMAC 3
8114 +#define SADB_X_AALG_SHA2_256HMAC 5
8115 +#define SADB_X_AALG_SHA2_384HMAC 6
8116 +#define SADB_X_AALG_SHA2_512HMAC 7
8117 +#define SADB_X_AALG_RIPEMD160HMAC 8
8118 +#define SADB_X_AALG_NULL 251 /* kame */
8119 +#define SADB_AALG_MAX 251
8120 +
8121 +#define SADB_EALG_NONE 0
8122 +#define SADB_EALG_DESCBC 2
8123 +#define SADB_EALG_3DESCBC 3
8124 +#define SADB_X_EALG_CASTCBC 6
8125 +#define SADB_X_EALG_BLOWFISHCBC 7
8126 +#define SADB_EALG_NULL 11
8127 +#define SADB_X_EALG_AESCBC 12
8128 +#define SADB_EALG_MAX 255
8129 +
8130 +#define SADB_X_CALG_NONE 0
8131 +#define SADB_X_CALG_OUI 1
8132 +#define SADB_X_CALG_DEFLATE 2
8133 +#define SADB_X_CALG_LZS 3
8134 +#define SADB_X_CALG_V42BIS 4
8135 +#ifdef KERNEL26_HAS_KAME_DUPLICATES
8136 +#define SADB_X_CALG_LZJH 4
8137 +#endif
8138 +#define SADB_X_CALG_MAX 4
8139 +
8140 +#define SADB_X_TALG_NONE 0
8141 +#define SADB_X_TALG_IPv4_in_IPv4 1
8142 +#define SADB_X_TALG_IPv6_in_IPv4 2
8143 +#define SADB_X_TALG_IPv4_in_IPv6 3
8144 +#define SADB_X_TALG_IPv6_in_IPv6 4
8145 +#define SADB_X_TALG_MAX 4
8146 +
8147 +
8148 +#define SADB_IDENTTYPE_RESERVED 0
8149 +#define SADB_IDENTTYPE_PREFIX 1
8150 +#define SADB_IDENTTYPE_FQDN 2
8151 +#define SADB_IDENTTYPE_USERFQDN 3
8152 +#define SADB_X_IDENTTYPE_CONNECTION 4
8153 +#define SADB_IDENTTYPE_MAX 4
8154 +
8155 +#define SADB_KEY_FLAGS_MAX 0
8156 +#endif /* __PFKEY_V2_H */
8157 +
8158 +/*
8159 + * $Log: pfkeyv2.h,v $
8160 + * Revision 1.31 2005/04/14 01:14:54 mcr
8161 + * change sadb_state to an enum.
8162 + *
8163 + * Revision 1.30 2004/04/06 02:49:00 mcr
8164 + * pullup of algo code from alg-branch.
8165 + *
8166 + * Revision 1.29 2003/12/22 21:35:58 mcr
8167 + * new patches from Dr{Who}.
8168 + *
8169 + * Revision 1.28 2003/12/22 19:33:15 mcr
8170 + * added 0.6c NAT-T patch.
8171 + *
8172 + * Revision 1.27 2003/12/10 01:20:01 mcr
8173 + * NAT-traversal patches to KLIPS.
8174 + *
8175 + * Revision 1.26 2003/10/31 02:26:44 mcr
8176 + * pulled up port-selector patches.
8177 + *
8178 + * Revision 1.25.4.1 2003/09/21 13:59:34 mcr
8179 + * pre-liminary X.509 patch - does not yet pass tests.
8180 + *
8181 + * Revision 1.25 2003/07/31 23:59:17 mcr
8182 + * re-introduce kernel 2.6 duplicate values for now.
8183 + * hope to get them changed!
8184 + *
8185 + * Revision 1.24 2003/07/31 22:55:27 mcr
8186 + * added some definitions to keep pfkeyv2.h files in sync.
8187 + *
8188 + * Revision 1.23 2003/05/11 00:43:48 mcr
8189 + * added comment about origin of values used
8190 + *
8191 + * Revision 1.22 2003/01/30 02:31:34 rgb
8192 + *
8193 + * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
8194 + *
8195 + * Revision 1.21 2002/12/16 19:26:49 mcr
8196 + * added definition of FS 1.xx sadb structure
8197 + *
8198 + * Revision 1.20 2002/09/20 15:40:25 rgb
8199 + * Added sadb_x_sa_ref to struct sadb_sa.
8200 + *
8201 + * Revision 1.19 2002/04/24 07:36:49 mcr
8202 + * Moved from ./lib/pfkeyv2.h,v
8203 + *
8204 + * Revision 1.18 2001/11/06 19:47:47 rgb
8205 + * Added packet parameter to lifetime and comb structures.
8206 + *
8207 + * Revision 1.17 2001/09/08 21:13:35 rgb
8208 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
8209 + *
8210 + * Revision 1.16 2001/07/06 19:49:46 rgb
8211 + * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks.
8212 + *
8213 + * Revision 1.15 2001/02/26 20:00:43 rgb
8214 + * Added internal IP protocol 61 for magic SAs.
8215 + *
8216 + * Revision 1.14 2001/02/08 18:51:05 rgb
8217 + * Include RFC document title and appendix subsection title.
8218 + *
8219 + * Revision 1.13 2000/10/10 20:10:20 rgb
8220 + * Added support for debug_ipcomp and debug_verbose to klipsdebug.
8221 + *
8222 + * Revision 1.12 2000/09/15 06:41:50 rgb
8223 + * Added V42BIS constant.
8224 + *
8225 + * Revision 1.11 2000/09/12 22:35:37 rgb
8226 + * Restructured to remove unused extensions from CLEARFLOW messages.
8227 + *
8228 + * Revision 1.10 2000/09/12 18:50:09 rgb
8229 + * Added IPIP tunnel types as algo support.
8230 + *
8231 + * Revision 1.9 2000/08/21 16:47:19 rgb
8232 + * Added SADB_X_CALG_* macros for IPCOMP.
8233 + *
8234 + * Revision 1.8 2000/08/09 20:43:34 rgb
8235 + * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
8236 + *
8237 + * Revision 1.7 2000/01/21 06:28:37 rgb
8238 + * Added flow add/delete message type macros.
8239 + * Added flow address extension type macros.
8240 + * Tidied up spacing.
8241 + * Added klipsdebug switching capability.
8242 + *
8243 + * Revision 1.6 1999/11/27 11:56:08 rgb
8244 + * Add SADB_X_SATYPE_COMP for compression, eventually.
8245 + *
8246 + * Revision 1.5 1999/11/23 22:23:16 rgb
8247 + * This file has been moved in the distribution from klips/net/ipsec to
8248 + * lib.
8249 + *
8250 + * Revision 1.4 1999/04/29 15:23:29 rgb
8251 + * Add GRPSA support.
8252 + * Add support for a second SATYPE, SA and DST_ADDRESS.
8253 + * Add IPPROTO_IPIP support.
8254 + *
8255 + * Revision 1.3 1999/04/15 17:58:08 rgb
8256 + * Add RCSID labels.
8257 + *
8258 + */
8259 --- /dev/null Tue Mar 11 13:02:56 2003
8260 +++ linux/include/zlib/zconf.h Mon Feb 9 13:51:03 2004
8261 @@ -0,0 +1,309 @@
8262 +/* zconf.h -- configuration of the zlib compression library
8263 + * Copyright (C) 1995-2002 Jean-loup Gailly.
8264 + * For conditions of distribution and use, see copyright notice in zlib.h
8265 + */
8266 +
8267 +/* @(#) $Id: zconf.h,v 1.4 2004/07/10 07:48:40 mcr Exp $ */
8268 +
8269 +#ifndef _ZCONF_H
8270 +#define _ZCONF_H
8271 +
8272 +/*
8273 + * If you *really* need a unique prefix for all types and library functions,
8274 + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
8275 + */
8276 +#ifdef IPCOMP_PREFIX
8277 +# define deflateInit_ ipcomp_deflateInit_
8278 +# define deflate ipcomp_deflate
8279 +# define deflateEnd ipcomp_deflateEnd
8280 +# define inflateInit_ ipcomp_inflateInit_
8281 +# define inflate ipcomp_inflate
8282 +# define inflateEnd ipcomp_inflateEnd
8283 +# define deflateInit2_ ipcomp_deflateInit2_
8284 +# define deflateSetDictionary ipcomp_deflateSetDictionary
8285 +# define deflateCopy ipcomp_deflateCopy
8286 +# define deflateReset ipcomp_deflateReset
8287 +# define deflateParams ipcomp_deflateParams
8288 +# define inflateInit2_ ipcomp_inflateInit2_
8289 +# define inflateSetDictionary ipcomp_inflateSetDictionary
8290 +# define inflateSync ipcomp_inflateSync
8291 +# define inflateSyncPoint ipcomp_inflateSyncPoint
8292 +# define inflateReset ipcomp_inflateReset
8293 +# define compress ipcomp_compress
8294 +# define compress2 ipcomp_compress2
8295 +# define uncompress ipcomp_uncompress
8296 +# define adler32 ipcomp_adler32
8297 +# define crc32 ipcomp_crc32
8298 +# define get_crc_table ipcomp_get_crc_table
8299 +/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
8300 +# define inflate_blocks ipcomp_deflate_blocks
8301 +# define inflate_blocks_free ipcomp_deflate_blocks_free
8302 +# define inflate_blocks_new ipcomp_inflate_blocks_new
8303 +# define inflate_blocks_reset ipcomp_inflate_blocks_reset
8304 +# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
8305 +# define inflate_set_dictionary ipcomp_inflate_set_dictionary
8306 +# define inflate_codes ipcomp_inflate_codes
8307 +# define inflate_codes_free ipcomp_inflate_codes_free
8308 +# define inflate_codes_new ipcomp_inflate_codes_new
8309 +# define inflate_fast ipcomp_inflate_fast
8310 +# define inflate_trees_bits ipcomp_inflate_trees_bits
8311 +# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
8312 +# define inflate_trees_fixed ipcomp_inflate_trees_fixed
8313 +# define inflate_flush ipcomp_inflate_flush
8314 +# define inflate_mask ipcomp_inflate_mask
8315 +# define _dist_code _ipcomp_dist_code
8316 +# define _length_code _ipcomp_length_code
8317 +# define _tr_align _ipcomp_tr_align
8318 +# define _tr_flush_block _ipcomp_tr_flush_block
8319 +# define _tr_init _ipcomp_tr_init
8320 +# define _tr_stored_block _ipcomp_tr_stored_block
8321 +# define _tr_tally _ipcomp_tr_tally
8322 +# define zError ipcomp_zError
8323 +# define z_errmsg ipcomp_z_errmsg
8324 +# define zlibVersion ipcomp_zlibVersion
8325 +# define match_init ipcomp_match_init
8326 +# define longest_match ipcomp_longest_match
8327 +#endif
8328 +
8329 +#ifdef Z_PREFIX
8330 +# define Byte z_Byte
8331 +# define uInt z_uInt
8332 +# define uLong z_uLong
8333 +# define Bytef z_Bytef
8334 +# define charf z_charf
8335 +# define intf z_intf
8336 +# define uIntf z_uIntf
8337 +# define uLongf z_uLongf
8338 +# define voidpf z_voidpf
8339 +# define voidp z_voidp
8340 +#endif
8341 +
8342 +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
8343 +# define WIN32
8344 +#endif
8345 +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
8346 +# ifndef __32BIT__
8347 +# define __32BIT__
8348 +# endif
8349 +#endif
8350 +#if defined(__MSDOS__) && !defined(MSDOS)
8351 +# define MSDOS
8352 +#endif
8353 +
8354 +/*
8355 + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
8356 + * than 64k bytes at a time (needed on systems with 16-bit int).
8357 + */
8358 +#if defined(MSDOS) && !defined(__32BIT__)
8359 +# define MAXSEG_64K
8360 +#endif
8361 +#ifdef MSDOS
8362 +# define UNALIGNED_OK
8363 +#endif
8364 +
8365 +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
8366 +# define STDC
8367 +#endif
8368 +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
8369 +# ifndef STDC
8370 +# define STDC
8371 +# endif
8372 +#endif
8373 +
8374 +#ifndef STDC
8375 +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
8376 +# define const
8377 +# endif
8378 +#endif
8379 +
8380 +/* Some Mac compilers merge all .h files incorrectly: */
8381 +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
8382 +# define NO_DUMMY_DECL
8383 +#endif
8384 +
8385 +/* Old Borland C incorrectly complains about missing returns: */
8386 +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
8387 +# define NEED_DUMMY_RETURN
8388 +#endif
8389 +
8390 +
8391 +/* Maximum value for memLevel in deflateInit2 */
8392 +#ifndef MAX_MEM_LEVEL
8393 +# ifdef MAXSEG_64K
8394 +# define MAX_MEM_LEVEL 8
8395 +# else
8396 +# define MAX_MEM_LEVEL 9
8397 +# endif
8398 +#endif
8399 +
8400 +/* Maximum value for windowBits in deflateInit2 and inflateInit2.
8401 + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
8402 + * created by gzip. (Files created by minigzip can still be extracted by
8403 + * gzip.)
8404 + */
8405 +#ifndef MAX_WBITS
8406 +# define MAX_WBITS 15 /* 32K LZ77 window */
8407 +#endif
8408 +
8409 +/* The memory requirements for deflate are (in bytes):
8410 + (1 << (windowBits+2)) + (1 << (memLevel+9))
8411 + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
8412 + plus a few kilobytes for small objects. For example, if you want to reduce
8413 + the default memory requirements from 256K to 128K, compile with
8414 + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
8415 + Of course this will generally degrade compression (there's no free lunch).
8416 +
8417 + The memory requirements for inflate are (in bytes) 1 << windowBits
8418 + that is, 32K for windowBits=15 (default value) plus a few kilobytes
8419 + for small objects.
8420 +*/
8421 +
8422 + /* Type declarations */
8423 +
8424 +#ifndef OF /* function prototypes */
8425 +# ifdef STDC
8426 +# define OF(args) args
8427 +# else
8428 +# define OF(args) ()
8429 +# endif
8430 +#endif
8431 +
8432 +/* The following definitions for FAR are needed only for MSDOS mixed
8433 + * model programming (small or medium model with some far allocations).
8434 + * This was tested only with MSC; for other MSDOS compilers you may have
8435 + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
8436 + * just define FAR to be empty.
8437 + */
8438 +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
8439 + /* MSC small or medium model */
8440 +# define SMALL_MEDIUM
8441 +# ifdef _MSC_VER
8442 +# define FAR _far
8443 +# else
8444 +# define FAR far
8445 +# endif
8446 +#endif
8447 +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
8448 +# ifndef __32BIT__
8449 +# define SMALL_MEDIUM
8450 +# define FAR _far
8451 +# endif
8452 +#endif
8453 +
8454 +/* Compile with -DZLIB_DLL for Windows DLL support */
8455 +#if defined(ZLIB_DLL)
8456 +# if defined(_WINDOWS) || defined(WINDOWS)
8457 +# ifdef FAR
8458 +# undef FAR
8459 +# endif
8460 +# include <windows.h>
8461 +# define ZEXPORT WINAPI
8462 +# ifdef WIN32
8463 +# define ZEXPORTVA WINAPIV
8464 +# else
8465 +# define ZEXPORTVA FAR _cdecl _export
8466 +# endif
8467 +# endif
8468 +# if defined (__BORLANDC__)
8469 +# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
8470 +# include <windows.h>
8471 +# define ZEXPORT __declspec(dllexport) WINAPI
8472 +# define ZEXPORTRVA __declspec(dllexport) WINAPIV
8473 +# else
8474 +# if defined (_Windows) && defined (__DLL__)
8475 +# define ZEXPORT _export
8476 +# define ZEXPORTVA _export
8477 +# endif
8478 +# endif
8479 +# endif
8480 +#endif
8481 +
8482 +#if defined (__BEOS__)
8483 +# if defined (ZLIB_DLL)
8484 +# define ZEXTERN extern __declspec(dllexport)
8485 +# else
8486 +# define ZEXTERN extern __declspec(dllimport)
8487 +# endif
8488 +#endif
8489 +
8490 +#ifndef ZEXPORT
8491 +# define ZEXPORT
8492 +#endif
8493 +#ifndef ZEXPORTVA
8494 +# define ZEXPORTVA
8495 +#endif
8496 +#ifndef ZEXTERN
8497 +# define ZEXTERN extern
8498 +#endif
8499 +
8500 +#ifndef FAR
8501 +# define FAR
8502 +#endif
8503 +
8504 +#if !defined(MACOS) && !defined(TARGET_OS_MAC)
8505 +typedef unsigned char Byte; /* 8 bits */
8506 +#endif
8507 +typedef unsigned int uInt; /* 16 bits or more */
8508 +typedef unsigned long uLong; /* 32 bits or more */
8509 +
8510 +#ifdef SMALL_MEDIUM
8511 + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
8512 +# define Bytef Byte FAR
8513 +#else
8514 + typedef Byte FAR Bytef;
8515 +#endif
8516 +typedef char FAR charf;
8517 +typedef int FAR intf;
8518 +typedef uInt FAR uIntf;
8519 +typedef uLong FAR uLongf;
8520 +
8521 +#ifdef STDC
8522 + typedef void FAR *voidpf;
8523 + typedef void *voidp;
8524 +#else
8525 + typedef Byte FAR *voidpf;
8526 + typedef Byte *voidp;
8527 +#endif
8528 +
8529 +#ifdef HAVE_UNISTD_H
8530 +# include <sys/types.h> /* for off_t */
8531 +# include <unistd.h> /* for SEEK_* and off_t */
8532 +# define z_off_t off_t
8533 +#endif
8534 +#ifndef SEEK_SET
8535 +# define SEEK_SET 0 /* Seek from beginning of file. */
8536 +# define SEEK_CUR 1 /* Seek from current position. */
8537 +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
8538 +#endif
8539 +#ifndef z_off_t
8540 +# define z_off_t long
8541 +#endif
8542 +
8543 +/* MVS linker does not support external names larger than 8 bytes */
8544 +#if defined(__MVS__)
8545 +# pragma map(deflateInit_,"DEIN")
8546 +# pragma map(deflateInit2_,"DEIN2")
8547 +# pragma map(deflateEnd,"DEEND")
8548 +# pragma map(inflateInit_,"ININ")
8549 +# pragma map(inflateInit2_,"ININ2")
8550 +# pragma map(inflateEnd,"INEND")
8551 +# pragma map(inflateSync,"INSY")
8552 +# pragma map(inflateSetDictionary,"INSEDI")
8553 +# pragma map(inflate_blocks,"INBL")
8554 +# pragma map(inflate_blocks_new,"INBLNE")
8555 +# pragma map(inflate_blocks_free,"INBLFR")
8556 +# pragma map(inflate_blocks_reset,"INBLRE")
8557 +# pragma map(inflate_codes_free,"INCOFR")
8558 +# pragma map(inflate_codes,"INCO")
8559 +# pragma map(inflate_fast,"INFA")
8560 +# pragma map(inflate_flush,"INFLU")
8561 +# pragma map(inflate_mask,"INMA")
8562 +# pragma map(inflate_set_dictionary,"INSEDI2")
8563 +# pragma map(ipcomp_inflate_copyright,"INCOPY")
8564 +# pragma map(inflate_trees_bits,"INTRBI")
8565 +# pragma map(inflate_trees_dynamic,"INTRDY")
8566 +# pragma map(inflate_trees_fixed,"INTRFI")
8567 +# pragma map(inflate_trees_free,"INTRFR")
8568 +#endif
8569 +
8570 +#endif /* _ZCONF_H */
8571 --- /dev/null Tue Mar 11 13:02:56 2003
8572 +++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004
8573 @@ -0,0 +1,893 @@
8574 +/* zlib.h -- interface of the 'zlib' general purpose compression library
8575 + version 1.1.4, March 11th, 2002
8576 +
8577 + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
8578 +
8579 + This software is provided 'as-is', without any express or implied
8580 + warranty. In no event will the authors be held liable for any damages
8581 + arising from the use of this software.
8582 +
8583 + Permission is granted to anyone to use this software for any purpose,
8584 + including commercial applications, and to alter it and redistribute it
8585 + freely, subject to the following restrictions:
8586 +
8587 + 1. The origin of this software must not be misrepresented; you must not
8588 + claim that you wrote the original software. If you use this software
8589 + in a product, an acknowledgment in the product documentation would be
8590 + appreciated but is not required.
8591 + 2. Altered source versions must be plainly marked as such, and must not be
8592 + misrepresented as being the original software.
8593 + 3. This notice may not be removed or altered from any source distribution.
8594 +
8595 + Jean-loup Gailly Mark Adler
8596 + jloup@gzip.org madler@alumni.caltech.edu
8597 +
8598 +
8599 + The data format used by the zlib library is described by RFCs (Request for
8600 + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
8601 + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
8602 +*/
8603 +
8604 +#ifndef _ZLIB_H
8605 +#define _ZLIB_H
8606 +
8607 +#include "zconf.h"
8608 +
8609 +#ifdef __cplusplus
8610 +extern "C" {
8611 +#endif
8612 +
8613 +#define ZLIB_VERSION "1.1.4"
8614 +
8615 +/*
8616 + The 'zlib' compression library provides in-memory compression and
8617 + decompression functions, including integrity checks of the uncompressed
8618 + data. This version of the library supports only one compression method
8619 + (deflation) but other algorithms will be added later and will have the same
8620 + stream interface.
8621 +
8622 + Compression can be done in a single step if the buffers are large
8623 + enough (for example if an input file is mmap'ed), or can be done by
8624 + repeated calls of the compression function. In the latter case, the
8625 + application must provide more input and/or consume the output
8626 + (providing more output space) before each call.
8627 +
8628 + The library also supports reading and writing files in gzip (.gz) format
8629 + with an interface similar to that of stdio.
8630 +
8631 + The library does not install any signal handler. The decoder checks
8632 + the consistency of the compressed data, so the library should never
8633 + crash even in case of corrupted input.
8634 +*/
8635 +
8636 +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
8637 +typedef void (*free_func) OF((voidpf opaque, voidpf address));
8638 +
8639 +struct internal_state;
8640 +
8641 +typedef struct z_stream_s {
8642 + Bytef *next_in; /* next input byte */
8643 + uInt avail_in; /* number of bytes available at next_in */
8644 + uLong total_in; /* total nb of input bytes read so far */
8645 +
8646 + Bytef *next_out; /* next output byte should be put there */
8647 + uInt avail_out; /* remaining free space at next_out */
8648 + uLong total_out; /* total nb of bytes output so far */
8649 +
8650 + const char *msg; /* last error message, NULL if no error */
8651 + struct internal_state FAR *state; /* not visible by applications */
8652 +
8653 + alloc_func zalloc; /* used to allocate the internal state */
8654 + free_func zfree; /* used to free the internal state */
8655 + voidpf opaque; /* private data object passed to zalloc and zfree */
8656 +
8657 + int data_type; /* best guess about the data type: ascii or binary */
8658 + uLong adler; /* adler32 value of the uncompressed data */
8659 + uLong reserved; /* reserved for future use */
8660 +} z_stream;
8661 +
8662 +typedef z_stream FAR *z_streamp;
8663 +
8664 +/*
8665 + The application must update next_in and avail_in when avail_in has
8666 + dropped to zero. It must update next_out and avail_out when avail_out
8667 + has dropped to zero. The application must initialize zalloc, zfree and
8668 + opaque before calling the init function. All other fields are set by the
8669 + compression library and must not be updated by the application.
8670 +
8671 + The opaque value provided by the application will be passed as the first
8672 + parameter for calls of zalloc and zfree. This can be useful for custom
8673 + memory management. The compression library attaches no meaning to the
8674 + opaque value.
8675 +
8676 + zalloc must return Z_NULL if there is not enough memory for the object.
8677 + If zlib is used in a multi-threaded application, zalloc and zfree must be
8678 + thread safe.
8679 +
8680 + On 16-bit systems, the functions zalloc and zfree must be able to allocate
8681 + exactly 65536 bytes, but will not be required to allocate more than this
8682 + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
8683 + pointers returned by zalloc for objects of exactly 65536 bytes *must*
8684 + have their offset normalized to zero. The default allocation function
8685 + provided by this library ensures this (see zutil.c). To reduce memory
8686 + requirements and avoid any allocation of 64K objects, at the expense of
8687 + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
8688 +
8689 + The fields total_in and total_out can be used for statistics or
8690 + progress reports. After compression, total_in holds the total size of
8691 + the uncompressed data and may be saved for use in the decompressor
8692 + (particularly if the decompressor wants to decompress everything in
8693 + a single step).
8694 +*/
8695 +
8696 + /* constants */
8697 +
8698 +#define Z_NO_FLUSH 0
8699 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
8700 +#define Z_SYNC_FLUSH 2
8701 +#define Z_FULL_FLUSH 3
8702 +#define Z_FINISH 4
8703 +/* Allowed flush values; see deflate() below for details */
8704 +
8705 +#define Z_OK 0
8706 +#define Z_STREAM_END 1
8707 +#define Z_NEED_DICT 2
8708 +#define Z_ERRNO (-1)
8709 +#define Z_STREAM_ERROR (-2)
8710 +#define Z_DATA_ERROR (-3)
8711 +#define Z_MEM_ERROR (-4)
8712 +#define Z_BUF_ERROR (-5)
8713 +#define Z_VERSION_ERROR (-6)
8714 +/* Return codes for the compression/decompression functions. Negative
8715 + * values are errors, positive values are used for special but normal events.
8716 + */
8717 +
8718 +#define Z_NO_COMPRESSION 0
8719 +#define Z_BEST_SPEED 1
8720 +#define Z_BEST_COMPRESSION 9
8721 +#define Z_DEFAULT_COMPRESSION (-1)
8722 +/* compression levels */
8723 +
8724 +#define Z_FILTERED 1
8725 +#define Z_HUFFMAN_ONLY 2
8726 +#define Z_DEFAULT_STRATEGY 0
8727 +/* compression strategy; see deflateInit2() below for details */
8728 +
8729 +#define Z_BINARY 0
8730 +#define Z_ASCII 1
8731 +#define Z_UNKNOWN 2
8732 +/* Possible values of the data_type field */
8733 +
8734 +#define Z_DEFLATED 8
8735 +/* The deflate compression method (the only one supported in this version) */
8736 +
8737 +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
8738 +
8739 +#define zlib_version zlibVersion()
8740 +/* for compatibility with versions < 1.0.2 */
8741 +
8742 + /* basic functions */
8743 +
8744 +ZEXTERN const char * ZEXPORT zlibVersion OF((void));
8745 +/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
8746 + If the first character differs, the library code actually used is
8747 + not compatible with the zlib.h header file used by the application.
8748 + This check is automatically made by deflateInit and inflateInit.
8749 + */
8750 +
8751 +/*
8752 +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
8753 +
8754 + Initializes the internal stream state for compression. The fields
8755 + zalloc, zfree and opaque must be initialized before by the caller.
8756 + If zalloc and zfree are set to Z_NULL, deflateInit updates them to
8757 + use default allocation functions.
8758 +
8759 + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
8760 + 1 gives best speed, 9 gives best compression, 0 gives no compression at
8761 + all (the input data is simply copied a block at a time).
8762 + Z_DEFAULT_COMPRESSION requests a default compromise between speed and
8763 + compression (currently equivalent to level 6).
8764 +
8765 + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
8766 + enough memory, Z_STREAM_ERROR if level is not a valid compression level,
8767 + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
8768 + with the version assumed by the caller (ZLIB_VERSION).
8769 + msg is set to null if there is no error message. deflateInit does not
8770 + perform any compression: this will be done by deflate().
8771 +*/
8772 +
8773 +
8774 +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
8775 +/*
8776 + deflate compresses as much data as possible, and stops when the input
8777 + buffer becomes empty or the output buffer becomes full. It may introduce some
8778 + output latency (reading input without producing any output) except when
8779 + forced to flush.
8780 +
8781 + The detailed semantics are as follows. deflate performs one or both of the
8782 + following actions:
8783 +
8784 + - Compress more input starting at next_in and update next_in and avail_in
8785 + accordingly. If not all input can be processed (because there is not
8786 + enough room in the output buffer), next_in and avail_in are updated and
8787 + processing will resume at this point for the next call of deflate().
8788 +
8789 + - Provide more output starting at next_out and update next_out and avail_out
8790 + accordingly. This action is forced if the parameter flush is non zero.
8791 + Forcing flush frequently degrades the compression ratio, so this parameter
8792 + should be set only when necessary (in interactive applications).
8793 + Some output may be provided even if flush is not set.
8794 +
8795 + Before the call of deflate(), the application should ensure that at least
8796 + one of the actions is possible, by providing more input and/or consuming
8797 + more output, and updating avail_in or avail_out accordingly; avail_out
8798 + should never be zero before the call. The application can consume the
8799 + compressed output when it wants, for example when the output buffer is full
8800 + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
8801 + and with zero avail_out, it must be called again after making room in the
8802 + output buffer because there might be more output pending.
8803 +
8804 + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
8805 + flushed to the output buffer and the output is aligned on a byte boundary, so
8806 + that the decompressor can get all input data available so far. (In particular
8807 + avail_in is zero after the call if enough output space has been provided
8808 + before the call.) Flushing may degrade compression for some compression
8809 + algorithms and so it should be used only when necessary.
8810 +
8811 + If flush is set to Z_FULL_FLUSH, all output is flushed as with
8812 + Z_SYNC_FLUSH, and the compression state is reset so that decompression can
8813 + restart from this point if previous compressed data has been damaged or if
8814 + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
8815 + the compression.
8816 +
8817 + If deflate returns with avail_out == 0, this function must be called again
8818 + with the same value of the flush parameter and more output space (updated
8819 + avail_out), until the flush is complete (deflate returns with non-zero
8820 + avail_out).
8821 +
8822 + If the parameter flush is set to Z_FINISH, pending input is processed,
8823 + pending output is flushed and deflate returns with Z_STREAM_END if there
8824 + was enough output space; if deflate returns with Z_OK, this function must be
8825 + called again with Z_FINISH and more output space (updated avail_out) but no
8826 + more input data, until it returns with Z_STREAM_END or an error. After
8827 + deflate has returned Z_STREAM_END, the only possible operations on the
8828 + stream are deflateReset or deflateEnd.
8829 +
8830 + Z_FINISH can be used immediately after deflateInit if all the compression
8831 + is to be done in a single step. In this case, avail_out must be at least
8832 + 0.1% larger than avail_in plus 12 bytes. If deflate does not return
8833 + Z_STREAM_END, then it must be called again as described above.
8834 +
8835 + deflate() sets strm->adler to the adler32 checksum of all input read
8836 + so far (that is, total_in bytes).
8837 +
8838 + deflate() may update data_type if it can make a good guess about
8839 + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
8840 + binary. This field is only for information purposes and does not affect
8841 + the compression algorithm in any manner.
8842 +
8843 + deflate() returns Z_OK if some progress has been made (more input
8844 + processed or more output produced), Z_STREAM_END if all input has been
8845 + consumed and all output has been produced (only when flush is set to
8846 + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
8847 + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
8848 + (for example avail_in or avail_out was zero).
8849 +*/
8850 +
8851 +
8852 +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
8853 +/*
8854 + All dynamically allocated data structures for this stream are freed.
8855 + This function discards any unprocessed input and does not flush any
8856 + pending output.
8857 +
8858 + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
8859 + stream state was inconsistent, Z_DATA_ERROR if the stream was freed
8860 + prematurely (some input or output was discarded). In the error case,
8861 + msg may be set but then points to a static string (which must not be
8862 + deallocated).
8863 +*/
8864 +
8865 +
8866 +/*
8867 +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
8868 +
8869 + Initializes the internal stream state for decompression. The fields
8870 + next_in, avail_in, zalloc, zfree and opaque must be initialized before by
8871 + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
8872 + value depends on the compression method), inflateInit determines the
8873 + compression method from the zlib header and allocates all data structures
8874 + accordingly; otherwise the allocation will be deferred to the first call of
8875 + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
8876 + use default allocation functions.
8877 +
8878 + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
8879 + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
8880 + version assumed by the caller. msg is set to null if there is no error
8881 + message. inflateInit does not perform any decompression apart from reading
8882 + the zlib header if present: this will be done by inflate(). (So next_in and
8883 + avail_in may be modified, but next_out and avail_out are unchanged.)
8884 +*/
8885 +
8886 +
8887 +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
8888 +/*
8889 + inflate decompresses as much data as possible, and stops when the input
8890 + buffer becomes empty or the output buffer becomes full. It may some
8891 + introduce some output latency (reading input without producing any output)
8892 + except when forced to flush.
8893 +
8894 + The detailed semantics are as follows. inflate performs one or both of the
8895 + following actions:
8896 +
8897 + - Decompress more input starting at next_in and update next_in and avail_in
8898 + accordingly. If not all input can be processed (because there is not
8899 + enough room in the output buffer), next_in is updated and processing
8900 + will resume at this point for the next call of inflate().
8901 +
8902 + - Provide more output starting at next_out and update next_out and avail_out
8903 + accordingly. inflate() provides as much output as possible, until there
8904 + is no more input data or no more space in the output buffer (see below
8905 + about the flush parameter).
8906 +
8907 + Before the call of inflate(), the application should ensure that at least
8908 + one of the actions is possible, by providing more input and/or consuming
8909 + more output, and updating the next_* and avail_* values accordingly.
8910 + The application can consume the uncompressed output when it wants, for
8911 + example when the output buffer is full (avail_out == 0), or after each
8912 + call of inflate(). If inflate returns Z_OK and with zero avail_out, it
8913 + must be called again after making room in the output buffer because there
8914 + might be more output pending.
8915 +
8916 + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
8917 + output as possible to the output buffer. The flushing behavior of inflate is
8918 + not specified for values of the flush parameter other than Z_SYNC_FLUSH
8919 + and Z_FINISH, but the current implementation actually flushes as much output
8920 + as possible anyway.
8921 +
8922 + inflate() should normally be called until it returns Z_STREAM_END or an
8923 + error. However if all decompression is to be performed in a single step
8924 + (a single call of inflate), the parameter flush should be set to
8925 + Z_FINISH. In this case all pending input is processed and all pending
8926 + output is flushed; avail_out must be large enough to hold all the
8927 + uncompressed data. (The size of the uncompressed data may have been saved
8928 + by the compressor for this purpose.) The next operation on this stream must
8929 + be inflateEnd to deallocate the decompression state. The use of Z_FINISH
8930 + is never required, but can be used to inform inflate that a faster routine
8931 + may be used for the single inflate() call.
8932 +
8933 + If a preset dictionary is needed at this point (see inflateSetDictionary
8934 + below), inflate sets strm-adler to the adler32 checksum of the
8935 + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
8936 + it sets strm->adler to the adler32 checksum of all output produced
8937 + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
8938 + an error code as described below. At the end of the stream, inflate()
8939 + checks that its computed adler32 checksum is equal to that saved by the
8940 + compressor and returns Z_STREAM_END only if the checksum is correct.
8941 +
8942 + inflate() returns Z_OK if some progress has been made (more input processed
8943 + or more output produced), Z_STREAM_END if the end of the compressed data has
8944 + been reached and all uncompressed output has been produced, Z_NEED_DICT if a
8945 + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
8946 + corrupted (input stream not conforming to the zlib format or incorrect
8947 + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
8948 + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
8949 + enough memory, Z_BUF_ERROR if no progress is possible or if there was not
8950 + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
8951 + case, the application may then call inflateSync to look for a good
8952 + compression block.
8953 +*/
8954 +
8955 +
8956 +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
8957 +/*
8958 + All dynamically allocated data structures for this stream are freed.
8959 + This function discards any unprocessed input and does not flush any
8960 + pending output.
8961 +
8962 + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
8963 + was inconsistent. In the error case, msg may be set but then points to a
8964 + static string (which must not be deallocated).
8965 +*/
8966 +
8967 + /* Advanced functions */
8968 +
8969 +/*
8970 + The following functions are needed only in some special applications.
8971 +*/
8972 +
8973 +/*
8974 +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
8975 + int level,
8976 + int method,
8977 + int windowBits,
8978 + int memLevel,
8979 + int strategy));
8980 +
8981 + This is another version of deflateInit with more compression options. The
8982 + fields next_in, zalloc, zfree and opaque must be initialized before by
8983 + the caller.
8984 +
8985 + The method parameter is the compression method. It must be Z_DEFLATED in
8986 + this version of the library.
8987 +
8988 + The windowBits parameter is the base two logarithm of the window size
8989 + (the size of the history buffer). It should be in the range 8..15 for this
8990 + version of the library. Larger values of this parameter result in better
8991 + compression at the expense of memory usage. The default value is 15 if
8992 + deflateInit is used instead.
8993 +
8994 + The memLevel parameter specifies how much memory should be allocated
8995 + for the internal compression state. memLevel=1 uses minimum memory but
8996 + is slow and reduces compression ratio; memLevel=9 uses maximum memory
8997 + for optimal speed. The default value is 8. See zconf.h for total memory
8998 + usage as a function of windowBits and memLevel.
8999 +
9000 + The strategy parameter is used to tune the compression algorithm. Use the
9001 + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
9002 + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
9003 + string match). Filtered data consists mostly of small values with a
9004 + somewhat random distribution. In this case, the compression algorithm is
9005 + tuned to compress them better. The effect of Z_FILTERED is to force more
9006 + Huffman coding and less string matching; it is somewhat intermediate
9007 + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
9008 + the compression ratio but not the correctness of the compressed output even
9009 + if it is not set appropriately.
9010 +
9011 + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9012 + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
9013 + method). msg is set to null if there is no error message. deflateInit2 does
9014 + not perform any compression: this will be done by deflate().
9015 +*/
9016 +
9017 +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
9018 + const Bytef *dictionary,
9019 + uInt dictLength));
9020 +/*
9021 + Initializes the compression dictionary from the given byte sequence
9022 + without producing any compressed output. This function must be called
9023 + immediately after deflateInit, deflateInit2 or deflateReset, before any
9024 + call of deflate. The compressor and decompressor must use exactly the same
9025 + dictionary (see inflateSetDictionary).
9026 +
9027 + The dictionary should consist of strings (byte sequences) that are likely
9028 + to be encountered later in the data to be compressed, with the most commonly
9029 + used strings preferably put towards the end of the dictionary. Using a
9030 + dictionary is most useful when the data to be compressed is short and can be
9031 + predicted with good accuracy; the data can then be compressed better than
9032 + with the default empty dictionary.
9033 +
9034 + Depending on the size of the compression data structures selected by
9035 + deflateInit or deflateInit2, a part of the dictionary may in effect be
9036 + discarded, for example if the dictionary is larger than the window size in
9037 + deflate or deflate2. Thus the strings most likely to be useful should be
9038 + put at the end of the dictionary, not at the front.
9039 +
9040 + Upon return of this function, strm->adler is set to the Adler32 value
9041 + of the dictionary; the decompressor may later use this value to determine
9042 + which dictionary has been used by the compressor. (The Adler32 value
9043 + applies to the whole dictionary even if only a subset of the dictionary is
9044 + actually used by the compressor.)
9045 +
9046 + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
9047 + parameter is invalid (such as NULL dictionary) or the stream state is
9048 + inconsistent (for example if deflate has already been called for this stream
9049 + or if the compression method is bsort). deflateSetDictionary does not
9050 + perform any compression: this will be done by deflate().
9051 +*/
9052 +
9053 +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
9054 + z_streamp source));
9055 +/*
9056 + Sets the destination stream as a complete copy of the source stream.
9057 +
9058 + This function can be useful when several compression strategies will be
9059 + tried, for example when there are several ways of pre-processing the input
9060 + data with a filter. The streams that will be discarded should then be freed
9061 + by calling deflateEnd. Note that deflateCopy duplicates the internal
9062 + compression state which can be quite large, so this strategy is slow and
9063 + can consume lots of memory.
9064 +
9065 + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
9066 + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
9067 + (such as zalloc being NULL). msg is left unchanged in both source and
9068 + destination.
9069 +*/
9070 +
9071 +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
9072 +/*
9073 + This function is equivalent to deflateEnd followed by deflateInit,
9074 + but does not free and reallocate all the internal compression state.
9075 + The stream will keep the same compression level and any other attributes
9076 + that may have been set by deflateInit2.
9077 +
9078 + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9079 + stream state was inconsistent (such as zalloc or state being NULL).
9080 +*/
9081 +
9082 +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
9083 + int level,
9084 + int strategy));
9085 +/*
9086 + Dynamically update the compression level and compression strategy. The
9087 + interpretation of level and strategy is as in deflateInit2. This can be
9088 + used to switch between compression and straight copy of the input data, or
9089 + to switch to a different kind of input data requiring a different
9090 + strategy. If the compression level is changed, the input available so far
9091 + is compressed with the old level (and may be flushed); the new level will
9092 + take effect only at the next call of deflate().
9093 +
9094 + Before the call of deflateParams, the stream state must be set as for
9095 + a call of deflate(), since the currently available input may have to
9096 + be compressed and flushed. In particular, strm->avail_out must be non-zero.
9097 +
9098 + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
9099 + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
9100 + if strm->avail_out was zero.
9101 +*/
9102 +
9103 +/*
9104 +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
9105 + int windowBits));
9106 +
9107 + This is another version of inflateInit with an extra parameter. The
9108 + fields next_in, avail_in, zalloc, zfree and opaque must be initialized
9109 + before by the caller.
9110 +
9111 + The windowBits parameter is the base two logarithm of the maximum window
9112 + size (the size of the history buffer). It should be in the range 8..15 for
9113 + this version of the library. The default value is 15 if inflateInit is used
9114 + instead. If a compressed stream with a larger window size is given as
9115 + input, inflate() will return with the error code Z_DATA_ERROR instead of
9116 + trying to allocate a larger window.
9117 +
9118 + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9119 + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
9120 + memLevel). msg is set to null if there is no error message. inflateInit2
9121 + does not perform any decompression apart from reading the zlib header if
9122 + present: this will be done by inflate(). (So next_in and avail_in may be
9123 + modified, but next_out and avail_out are unchanged.)
9124 +*/
9125 +
9126 +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
9127 + const Bytef *dictionary,
9128 + uInt dictLength));
9129 +/*
9130 + Initializes the decompression dictionary from the given uncompressed byte
9131 + sequence. This function must be called immediately after a call of inflate
9132 + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
9133 + can be determined from the Adler32 value returned by this call of
9134 + inflate. The compressor and decompressor must use exactly the same
9135 + dictionary (see deflateSetDictionary).
9136 +
9137 + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
9138 + parameter is invalid (such as NULL dictionary) or the stream state is
9139 + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
9140 + expected one (incorrect Adler32 value). inflateSetDictionary does not
9141 + perform any decompression: this will be done by subsequent calls of
9142 + inflate().
9143 +*/
9144 +
9145 +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
9146 +/*
9147 + Skips invalid compressed data until a full flush point (see above the
9148 + description of deflate with Z_FULL_FLUSH) can be found, or until all
9149 + available input is skipped. No output is provided.
9150 +
9151 + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
9152 + if no more input was provided, Z_DATA_ERROR if no flush point has been found,
9153 + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
9154 + case, the application may save the current current value of total_in which
9155 + indicates where valid compressed data was found. In the error case, the
9156 + application may repeatedly call inflateSync, providing more input each time,
9157 + until success or end of the input data.
9158 +*/
9159 +
9160 +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
9161 +/*
9162 + This function is equivalent to inflateEnd followed by inflateInit,
9163 + but does not free and reallocate all the internal decompression state.
9164 + The stream will keep attributes that may have been set by inflateInit2.
9165 +
9166 + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
9167 + stream state was inconsistent (such as zalloc or state being NULL).
9168 +*/
9169 +
9170 +
9171 + /* utility functions */
9172 +
9173 +/*
9174 + The following utility functions are implemented on top of the
9175 + basic stream-oriented functions. To simplify the interface, some
9176 + default options are assumed (compression level and memory usage,
9177 + standard memory allocation functions). The source code of these
9178 + utility functions can easily be modified if you need special options.
9179 +*/
9180 +
9181 +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
9182 + const Bytef *source, uLong sourceLen));
9183 +/*
9184 + Compresses the source buffer into the destination buffer. sourceLen is
9185 + the byte length of the source buffer. Upon entry, destLen is the total
9186 + size of the destination buffer, which must be at least 0.1% larger than
9187 + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
9188 + compressed buffer.
9189 + This function can be used to compress a whole file at once if the
9190 + input file is mmap'ed.
9191 + compress returns Z_OK if success, Z_MEM_ERROR if there was not
9192 + enough memory, Z_BUF_ERROR if there was not enough room in the output
9193 + buffer.
9194 +*/
9195 +
9196 +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
9197 + const Bytef *source, uLong sourceLen,
9198 + int level));
9199 +/*
9200 + Compresses the source buffer into the destination buffer. The level
9201 + parameter has the same meaning as in deflateInit. sourceLen is the byte
9202 + length of the source buffer. Upon entry, destLen is the total size of the
9203 + destination buffer, which must be at least 0.1% larger than sourceLen plus
9204 + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
9205 +
9206 + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
9207 + memory, Z_BUF_ERROR if there was not enough room in the output buffer,
9208 + Z_STREAM_ERROR if the level parameter is invalid.
9209 +*/
9210 +
9211 +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
9212 + const Bytef *source, uLong sourceLen));
9213 +/*
9214 + Decompresses the source buffer into the destination buffer. sourceLen is
9215 + the byte length of the source buffer. Upon entry, destLen is the total
9216 + size of the destination buffer, which must be large enough to hold the
9217 + entire uncompressed data. (The size of the uncompressed data must have
9218 + been saved previously by the compressor and transmitted to the decompressor
9219 + by some mechanism outside the scope of this compression library.)
9220 + Upon exit, destLen is the actual size of the compressed buffer.
9221 + This function can be used to decompress a whole file at once if the
9222 + input file is mmap'ed.
9223 +
9224 + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
9225 + enough memory, Z_BUF_ERROR if there was not enough room in the output
9226 + buffer, or Z_DATA_ERROR if the input data was corrupted.
9227 +*/
9228 +
9229 +
9230 +typedef voidp gzFile;
9231 +
9232 +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
9233 +/*
9234 + Opens a gzip (.gz) file for reading or writing. The mode parameter
9235 + is as in fopen ("rb" or "wb") but can also include a compression level
9236 + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
9237 + Huffman only compression as in "wb1h". (See the description
9238 + of deflateInit2 for more information about the strategy parameter.)
9239 +
9240 + gzopen can be used to read a file which is not in gzip format; in this
9241 + case gzread will directly read from the file without decompression.
9242 +
9243 + gzopen returns NULL if the file could not be opened or if there was
9244 + insufficient memory to allocate the (de)compression state; errno
9245 + can be checked to distinguish the two cases (if errno is zero, the
9246 + zlib error is Z_MEM_ERROR). */
9247 +
9248 +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
9249 +/*
9250 + gzdopen() associates a gzFile with the file descriptor fd. File
9251 + descriptors are obtained from calls like open, dup, creat, pipe or
9252 + fileno (in the file has been previously opened with fopen).
9253 + The mode parameter is as in gzopen.
9254 + The next call of gzclose on the returned gzFile will also close the
9255 + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
9256 + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
9257 + gzdopen returns NULL if there was insufficient memory to allocate
9258 + the (de)compression state.
9259 +*/
9260 +
9261 +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
9262 +/*
9263 + Dynamically update the compression level or strategy. See the description
9264 + of deflateInit2 for the meaning of these parameters.
9265 + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
9266 + opened for writing.
9267 +*/
9268 +
9269 +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
9270 +/*
9271 + Reads the given number of uncompressed bytes from the compressed file.
9272 + If the input file was not in gzip format, gzread copies the given number
9273 + of bytes into the buffer.
9274 + gzread returns the number of uncompressed bytes actually read (0 for
9275 + end of file, -1 for error). */
9276 +
9277 +ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
9278 + const voidp buf, unsigned len));
9279 +/*
9280 + Writes the given number of uncompressed bytes into the compressed file.
9281 + gzwrite returns the number of uncompressed bytes actually written
9282 + (0 in case of error).
9283 +*/
9284 +
9285 +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
9286 +/*
9287 + Converts, formats, and writes the args to the compressed file under
9288 + control of the format string, as in fprintf. gzprintf returns the number of
9289 + uncompressed bytes actually written (0 in case of error).
9290 +*/
9291 +
9292 +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
9293 +/*
9294 + Writes the given null-terminated string to the compressed file, excluding
9295 + the terminating null character.
9296 + gzputs returns the number of characters written, or -1 in case of error.
9297 +*/
9298 +
9299 +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
9300 +/*
9301 + Reads bytes from the compressed file until len-1 characters are read, or
9302 + a newline character is read and transferred to buf, or an end-of-file
9303 + condition is encountered. The string is then terminated with a null
9304 + character.
9305 + gzgets returns buf, or Z_NULL in case of error.
9306 +*/
9307 +
9308 +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
9309 +/*
9310 + Writes c, converted to an unsigned char, into the compressed file.
9311 + gzputc returns the value that was written, or -1 in case of error.
9312 +*/
9313 +
9314 +ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
9315 +/*
9316 + Reads one byte from the compressed file. gzgetc returns this byte
9317 + or -1 in case of end of file or error.
9318 +*/
9319 +
9320 +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
9321 +/*
9322 + Flushes all pending output into the compressed file. The parameter
9323 + flush is as in the deflate() function. The return value is the zlib
9324 + error number (see function gzerror below). gzflush returns Z_OK if
9325 + the flush parameter is Z_FINISH and all output could be flushed.
9326 + gzflush should be called only when strictly necessary because it can
9327 + degrade compression.
9328 +*/
9329 +
9330 +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
9331 + z_off_t offset, int whence));
9332 +/*
9333 + Sets the starting position for the next gzread or gzwrite on the
9334 + given compressed file. The offset represents a number of bytes in the
9335 + uncompressed data stream. The whence parameter is defined as in lseek(2);
9336 + the value SEEK_END is not supported.
9337 + If the file is opened for reading, this function is emulated but can be
9338 + extremely slow. If the file is opened for writing, only forward seeks are
9339 + supported; gzseek then compresses a sequence of zeroes up to the new
9340 + starting position.
9341 +
9342 + gzseek returns the resulting offset location as measured in bytes from
9343 + the beginning of the uncompressed stream, or -1 in case of error, in
9344 + particular if the file is opened for writing and the new starting position
9345 + would be before the current position.
9346 +*/
9347 +
9348 +ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
9349 +/*
9350 + Rewinds the given file. This function is supported only for reading.
9351 +
9352 + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
9353 +*/
9354 +
9355 +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
9356 +/*
9357 + Returns the starting position for the next gzread or gzwrite on the
9358 + given compressed file. This position represents a number of bytes in the
9359 + uncompressed data stream.
9360 +
9361 + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
9362 +*/
9363 +
9364 +ZEXTERN int ZEXPORT gzeof OF((gzFile file));
9365 +/*
9366 + Returns 1 when EOF has previously been detected reading the given
9367 + input stream, otherwise zero.
9368 +*/
9369 +
9370 +ZEXTERN int ZEXPORT gzclose OF((gzFile file));
9371 +/*
9372 + Flushes all pending output if necessary, closes the compressed file
9373 + and deallocates all the (de)compression state. The return value is the zlib
9374 + error number (see function gzerror below).
9375 +*/
9376 +
9377 +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
9378 +/*
9379 + Returns the error message for the last error which occurred on the
9380 + given compressed file. errnum is set to zlib error number. If an
9381 + error occurred in the file system and not in the compression library,
9382 + errnum is set to Z_ERRNO and the application may consult errno
9383 + to get the exact error code.
9384 +*/
9385 +
9386 + /* checksum functions */
9387 +
9388 +/*
9389 + These functions are not related to compression but are exported
9390 + anyway because they might be useful in applications using the
9391 + compression library.
9392 +*/
9393 +
9394 +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
9395 +
9396 +/*
9397 + Update a running Adler-32 checksum with the bytes buf[0..len-1] and
9398 + return the updated checksum. If buf is NULL, this function returns
9399 + the required initial value for the checksum.
9400 + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
9401 + much faster. Usage example:
9402 +
9403 + uLong adler = adler32(0L, Z_NULL, 0);
9404 +
9405 + while (read_buffer(buffer, length) != EOF) {
9406 + adler = adler32(adler, buffer, length);
9407 + }
9408 + if (adler != original_adler) error();
9409 +*/
9410 +
9411 +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
9412 +/*
9413 + Update a running crc with the bytes buf[0..len-1] and return the updated
9414 + crc. If buf is NULL, this function returns the required initial value
9415 + for the crc. Pre- and post-conditioning (one's complement) is performed
9416 + within this function so it shouldn't be done by the application.
9417 + Usage example:
9418 +
9419 + uLong crc = crc32(0L, Z_NULL, 0);
9420 +
9421 + while (read_buffer(buffer, length) != EOF) {
9422 + crc = crc32(crc, buffer, length);
9423 + }
9424 + if (crc != original_crc) error();
9425 +*/
9426 +
9427 +
9428 + /* various hacks, don't look :) */
9429 +
9430 +/* deflateInit and inflateInit are macros to allow checking the zlib version
9431 + * and the compiler's view of z_stream:
9432 + */
9433 +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
9434 + const char *version, int stream_size));
9435 +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
9436 + const char *version, int stream_size));
9437 +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
9438 + int windowBits, int memLevel,
9439 + int strategy, const char *version,
9440 + int stream_size));
9441 +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
9442 + const char *version, int stream_size));
9443 +#define deflateInit(strm, level) \
9444 + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
9445 +#define inflateInit(strm) \
9446 + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
9447 +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
9448 + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
9449 + (strategy), ZLIB_VERSION, sizeof(z_stream))
9450 +#define inflateInit2(strm, windowBits) \
9451 + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
9452 +
9453 +
9454 +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
9455 + struct internal_state {int dummy;}; /* hack for buggy compilers */
9456 +#endif
9457 +
9458 +ZEXTERN const char * ZEXPORT zError OF((int err));
9459 +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
9460 +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
9461 +
9462 +#ifdef __cplusplus
9463 +}
9464 +#endif
9465 +
9466 +#endif /* _ZLIB_H */
9467 --- /dev/null Tue Mar 11 13:02:56 2003
9468 +++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004
9469 @@ -0,0 +1,225 @@
9470 +/* zutil.h -- internal interface and configuration of the compression library
9471 + * Copyright (C) 1995-2002 Jean-loup Gailly.
9472 + * For conditions of distribution and use, see copyright notice in zlib.h
9473 + */
9474 +
9475 +/* WARNING: this file should *not* be used by applications. It is
9476 + part of the implementation of the compression library and is
9477 + subject to change. Applications should only use zlib.h.
9478 + */
9479 +
9480 +/* @(#) $Id: zutil.h,v 1.4 2002/04/24 07:36:48 mcr Exp $ */
9481 +
9482 +#ifndef _Z_UTIL_H
9483 +#define _Z_UTIL_H
9484 +
9485 +#include "zlib.h"
9486 +
9487 +#include <linux/string.h>
9488 +#define HAVE_MEMCPY
9489 +
9490 +#if 0 // #ifdef STDC
9491 +# include <stddef.h>
9492 +# include <string.h>
9493 +# include <stdlib.h>
9494 +#endif
9495 +#ifndef __KERNEL__
9496 +#ifdef NO_ERRNO_H
9497 + extern int errno;
9498 +#else
9499 +# include <errno.h>
9500 +#endif
9501 +#endif
9502 +
9503 +#ifndef local
9504 +# define local static
9505 +#endif
9506 +/* compile with -Dlocal if your debugger can't find static symbols */
9507 +
9508 +typedef unsigned char uch;
9509 +typedef uch FAR uchf;
9510 +typedef unsigned short ush;
9511 +typedef ush FAR ushf;
9512 +typedef unsigned long ulg;
9513 +
9514 +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
9515 +/* (size given to avoid silly warnings with Visual C++) */
9516 +
9517 +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
9518 +
9519 +#define ERR_RETURN(strm,err) \
9520 + return (strm->msg = ERR_MSG(err), (err))
9521 +/* To be used only when the state is known to be valid */
9522 +
9523 + /* common constants */
9524 +
9525 +#ifndef DEF_WBITS
9526 +# define DEF_WBITS MAX_WBITS
9527 +#endif
9528 +/* default windowBits for decompression. MAX_WBITS is for compression only */
9529 +
9530 +#if MAX_MEM_LEVEL >= 8
9531 +# define DEF_MEM_LEVEL 8
9532 +#else
9533 +# define DEF_MEM_LEVEL MAX_MEM_LEVEL
9534 +#endif
9535 +/* default memLevel */
9536 +
9537 +#define STORED_BLOCK 0
9538 +#define STATIC_TREES 1
9539 +#define DYN_TREES 2
9540 +/* The three kinds of block type */
9541 +
9542 +#define MIN_MATCH 3
9543 +#define MAX_MATCH 258
9544 +/* The minimum and maximum match lengths */
9545 +
9546 +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
9547 +
9548 + /* target dependencies */
9549 +
9550 +#ifdef MSDOS
9551 +# define OS_CODE 0x00
9552 +# if defined(__TURBOC__) || defined(__BORLANDC__)
9553 +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
9554 + /* Allow compilation with ANSI keywords only enabled */
9555 + void _Cdecl farfree( void *block );
9556 + void *_Cdecl farmalloc( unsigned long nbytes );
9557 +# else
9558 +# include <alloc.h>
9559 +# endif
9560 +# else /* MSC or DJGPP */
9561 +# include <malloc.h>
9562 +# endif
9563 +#endif
9564 +
9565 +#ifdef OS2
9566 +# define OS_CODE 0x06
9567 +#endif
9568 +
9569 +#ifdef WIN32 /* Window 95 & Windows NT */
9570 +# define OS_CODE 0x0b
9571 +#endif
9572 +
9573 +#if defined(VAXC) || defined(VMS)
9574 +# define OS_CODE 0x02
9575 +# define F_OPEN(name, mode) \
9576 + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
9577 +#endif
9578 +
9579 +#ifdef AMIGA
9580 +# define OS_CODE 0x01
9581 +#endif
9582 +
9583 +#if defined(ATARI) || defined(atarist)
9584 +# define OS_CODE 0x05
9585 +#endif
9586 +
9587 +#if defined(MACOS) || defined(TARGET_OS_MAC)
9588 +# define OS_CODE 0x07
9589 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
9590 +# include <unix.h> /* for fdopen */
9591 +# else
9592 +# ifndef fdopen
9593 +# define fdopen(fd,mode) NULL /* No fdopen() */
9594 +# endif
9595 +# endif
9596 +#endif
9597 +
9598 +#ifdef __50SERIES /* Prime/PRIMOS */
9599 +# define OS_CODE 0x0F
9600 +#endif
9601 +
9602 +#ifdef TOPS20
9603 +# define OS_CODE 0x0a
9604 +#endif
9605 +
9606 +#if defined(_BEOS_) || defined(RISCOS)
9607 +# define fdopen(fd,mode) NULL /* No fdopen() */
9608 +#endif
9609 +
9610 +#if (defined(_MSC_VER) && (_MSC_VER > 600))
9611 +# define fdopen(fd,type) _fdopen(fd,type)
9612 +#endif
9613 +
9614 +
9615 + /* Common defaults */
9616 +
9617 +#ifndef OS_CODE
9618 +# define OS_CODE 0x03 /* assume Unix */
9619 +#endif
9620 +
9621 +#ifndef F_OPEN
9622 +# define F_OPEN(name, mode) fopen((name), (mode))
9623 +#endif
9624 +
9625 + /* functions */
9626 +
9627 +#ifdef HAVE_STRERROR
9628 + extern char *strerror OF((int));
9629 +# define zstrerror(errnum) strerror(errnum)
9630 +#else
9631 +# define zstrerror(errnum) ""
9632 +#endif
9633 +
9634 +#if defined(pyr)
9635 +# define NO_MEMCPY
9636 +#endif
9637 +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
9638 + /* Use our own functions for small and medium model with MSC <= 5.0.
9639 + * You may have to use the same strategy for Borland C (untested).
9640 + * The __SC__ check is for Symantec.
9641 + */
9642 +# define NO_MEMCPY
9643 +#endif
9644 +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
9645 +# define HAVE_MEMCPY
9646 +#endif
9647 +#ifdef HAVE_MEMCPY
9648 +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
9649 +# define zmemcpy _fmemcpy
9650 +# define zmemcmp _fmemcmp
9651 +# define zmemzero(dest, len) _fmemset(dest, 0, len)
9652 +# else
9653 +# define zmemcpy memcpy
9654 +# define zmemcmp memcmp
9655 +# define zmemzero(dest, len) memset(dest, 0, len)
9656 +# endif
9657 +#else
9658 + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
9659 + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
9660 + extern void zmemzero OF((Bytef* dest, uInt len));
9661 +#endif
9662 +
9663 +/* Diagnostic functions */
9664 +#ifdef DEBUG
9665 +# include <stdio.h>
9666 + extern int z_verbose;
9667 + extern void z_error OF((char *m));
9668 +# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
9669 +# define Trace(x) {if (z_verbose>=0) fprintf x ;}
9670 +# define Tracev(x) {if (z_verbose>0) fprintf x ;}
9671 +# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
9672 +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
9673 +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
9674 +#else
9675 +# define Assert(cond,msg)
9676 +# define Trace(x)
9677 +# define Tracev(x)
9678 +# define Tracevv(x)
9679 +# define Tracec(c,x)
9680 +# define Tracecv(c,x)
9681 +#endif
9682 +
9683 +
9684 +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
9685 + uInt len));
9686 +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
9687 +void zcfree OF((voidpf opaque, voidpf ptr));
9688 +
9689 +#define ZALLOC(strm, items, size) \
9690 + (*((strm)->zalloc))((strm)->opaque, (items), (size))
9691 +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
9692 +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
9693 +
9694 +#endif /* _Z_UTIL_H */
9695 --- /dev/null Tue Mar 11 13:02:56 2003
9696 +++ linux/lib/libfreeswan/Makefile.objs Mon Feb 9 13:51:03 2004
9697 @@ -0,0 +1,21 @@
9698 +obj-y += satot.o
9699 +obj-y += addrtot.o
9700 +obj-y += ultot.o
9701 +obj-y += addrtypeof.o
9702 +obj-y += anyaddr.o
9703 +obj-y += initaddr.o
9704 +obj-y += ultoa.o
9705 +obj-y += addrtoa.o
9706 +obj-y += subnettoa.o
9707 +obj-y += subnetof.o
9708 +obj-y += goodmask.o
9709 +obj-y += datatot.o
9710 +obj-y += rangetoa.o
9711 +obj-y += prng.o
9712 +obj-y += pfkey_v2_parse.o
9713 +obj-y += pfkey_v2_build.o
9714 +obj-y += pfkey_v2_debug.o
9715 +obj-y += pfkey_v2_ext_bits.o
9716 +
9717 +#version.c: ${LIBFREESWANDIR}/version.in.c ${OPENSWANSRCDIR}/Makefile.ver
9718 +# sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@
9719 --- /dev/null Tue Mar 11 13:02:56 2003
9720 +++ linux/lib/zlib/Makefile Mon Feb 9 13:51:03 2004
9721 @@ -0,0 +1,118 @@
9722 +# (kernel) Makefile for IPCOMP zlib deflate code
9723 +# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
9724 +# Copyright (C) 2000 Svenning Soerensen
9725 +#
9726 +# This program is free software; you can redistribute it and/or modify it
9727 +# under the terms of the GNU General Public License as published by the
9728 +# Free Software Foundation; either version 2 of the License, or (at your
9729 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9730 +#
9731 +# This program is distributed in the hope that it will be useful, but
9732 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9733 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9734 +# for more details.
9735 +#
9736 +# RCSID $Id: Makefile,v 1.9 2002/04/24 07:55:32 mcr Exp $
9737 +#
9738 +
9739 +
9740 +
9741 +include ../Makefile.inc
9742 +
9743 +
9744 +
9745 +ifndef TOPDIR
9746 +TOPDIR := /usr/src/linux
9747 +endif
9748 +
9749 +
9750 +L_TARGET := zlib.a
9751 +
9752 +obj-y :=
9753 +
9754 +include Makefile.objs
9755 +
9756 +EXTRA_CFLAGS += $(KLIPSCOMPILE)
9757 +
9758 +EXTRA_CFLAGS += -Wall
9759 +#EXTRA_CFLAGS += -Wconversion
9760 +#EXTRA_CFLAGS += -Wmissing-prototypes
9761 +EXTRA_CFLAGS += -Wpointer-arith
9762 +#EXTRA_CFLAGS += -Wcast-qual
9763 +#EXTRA_CFLAGS += -Wmissing-declarations
9764 +EXTRA_CFLAGS += -Wstrict-prototypes
9765 +#EXTRA_CFLAGS += -pedantic
9766 +#EXTRA_CFLAGS += -W
9767 +#EXTRA_CFLAGS += -Wwrite-strings
9768 +EXTRA_CFLAGS += -Wbad-function-cast
9769 +EXTRA_CFLAGS += -DIPCOMP_PREFIX
9770 +
9771 +.S.o:
9772 + $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o
9773 +
9774 +asm-obj-$(CONFIG_M586) += match586.o
9775 +asm-obj-$(CONFIG_M586TSC) += match586.o
9776 +asm-obj-$(CONFIG_M586MMX) += match586.o
9777 +asm-obj-$(CONFIG_M686) += match686.o
9778 +asm-obj-$(CONFIG_MPENTIUMIII) += match686.o
9779 +asm-obj-$(CONFIG_MPENTIUM4) += match686.o
9780 +asm-obj-$(CONFIG_MK6) += match586.o
9781 +asm-obj-$(CONFIG_MK7) += match686.o
9782 +asm-obj-$(CONFIG_MCRUSOE) += match586.o
9783 +asm-obj-$(CONFIG_MWINCHIPC6) += match586.o
9784 +asm-obj-$(CONFIG_MWINCHIP2) += match686.o
9785 +asm-obj-$(CONFIG_MWINCHIP3D) += match686.o
9786 +
9787 +obj-y += $(asm-obj-y)
9788 +ifneq ($(strip $(asm-obj-y)),)
9789 + EXTRA_CFLAGS += -DASMV
9790 +endif
9791 +
9792 +active-objs := $(sort $(obj-y) $(obj-m))
9793 +L_OBJS := $(obj-y)
9794 +M_OBJS := $(obj-m)
9795 +MIX_OBJS := $(filter $(export-objs), $(active-objs))
9796 +
9797 +include $(TOPDIR)/Rules.make
9798 +
9799 +$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
9800 +
9801 +
9802 +clean:
9803 + -rm -f *.o *.a
9804 +
9805 +checkprograms:
9806 +programs: $(L_TARGET)
9807 +
9808 +#
9809 +# $Log: Makefile,v $
9810 +# Revision 1.9 2002/04/24 07:55:32 mcr
9811 +# #include patches and Makefiles for post-reorg compilation.
9812 +#
9813 +# Revision 1.8 2002/04/24 07:36:44 mcr
9814 +# Moved from ./zlib/Makefile,v
9815 +#
9816 +# Revision 1.7 2002/03/27 23:34:35 mcr
9817 +# added programs: target
9818 +#
9819 +# Revision 1.6 2001/12/05 20:19:08 henry
9820 +# use new compile-control variable
9821 +#
9822 +# Revision 1.5 2001/11/27 16:38:08 mcr
9823 +# added new "checkprograms" target to deal with programs that
9824 +# are required for "make check", but that may not be ready to
9825 +# build for every user due to external dependancies.
9826 +#
9827 +# Revision 1.4 2001/10/24 14:46:24 henry
9828 +# Makefile.inc
9829 +#
9830 +# Revision 1.3 2001/04/21 23:05:24 rgb
9831 +# Update asm directives for 2.4 style makefiles.
9832 +#
9833 +# Revision 1.2 2001/01/29 22:22:00 rgb
9834 +# Convert to 2.4 new style with back compat.
9835 +#
9836 +# Revision 1.1.1.1 2000/09/29 18:51:33 rgb
9837 +# zlib_beginnings
9838 +#
9839 +#
9840 --- /dev/null Tue Mar 11 13:02:56 2003
9841 +++ linux/lib/zlib/Makefile.objs Mon Feb 9 13:51:03 2004
9842 @@ -0,0 +1,27 @@
9843 +obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o
9844 +obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o
9845 +obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o
9846 +obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o
9847 +obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o
9848 +obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o
9849 +obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o
9850 +obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o
9851 +obj-$(CONFIG_IPSEC_IPCOMP) += trees.o
9852 +obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o
9853 +
9854 +asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o
9855 +asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o
9856 +asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o
9857 +asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o
9858 +asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o
9859 +asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o
9860 +asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o
9861 +asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o
9862 +asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o
9863 +asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o
9864 +asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o
9865 +asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o
9866 +
9867 +EXTRA_CFLAGS += -DIPCOMP_PREFIX
9868 +
9869 +
9870 --- swan26/net/Kconfig.preipsec 2005-09-01 18:15:19.000000000 -0400
9871 +++ swan26/net/Kconfig 2005-09-03 16:51:17.000000000 -0400
9872 @@ -215,2 +215,6 @@
9873
9874 +if INET
9875 +source "net/ipsec/Kconfig"
9876 +endif # if INET
9877 +
9878 endif # if NET
9879 --- /distros/kernel/linux-2.6.3-rc4/net/Makefile Mon Feb 16 21:22:12 2004
9880 +++ ref26/net/Makefile Thu Feb 19 21:02:25 2004
9881 @@ -42,3 +42,6 @@
9882 ifeq ($(CONFIG_NET),y)
9883 obj-$(CONFIG_SYSCTL) += sysctl_net.o
9884 endif
9885 +
9886 +obj-$(CONFIG_KLIPS) += ipsec/
9887 +
9888 --- /dev/null Tue Mar 11 13:02:56 2003
9889 +++ linux/net/ipsec/Kconfig Mon Feb 9 13:51:03 2004
9890 @@ -0,0 +1,161 @@
9891 +#
9892 +# IPSEC configuration
9893 +# Copyright (C) 2004 Michael Richardson <mcr@freeswan.org>
9894 +#
9895 +# This program is free software; you can redistribute it and/or modify it
9896 +# under the terms of the GNU General Public License as published by the
9897 +# Free Software Foundation; either version 2 of the License, or (at your
9898 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9899 +#
9900 +# This program is distributed in the hope that it will be useful, but
9901 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9902 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9903 +# for more details.
9904 +#
9905 +# RCSID $Id: Kconfig,v 1.6.2.2 2006/10/11 18:14:33 paul Exp $
9906 +
9907 +config KLIPS
9908 + tristate "Openswan IPsec (KLIPS26)"
9909 + default n
9910 + help
9911 + KLIPS is the Openswan (www.openswan.org) Kernel Level IP Security
9912 + system. It is extensively tested, and has interoperated with
9913 + many other systems.
9914 + It provides "ipsecX" devices on which one can do firewalling.
9915 + The userland, is compatible with both KLIPS and 26sec.
9916 +
9917 +menu "KLIPS options"
9918 + depends on KLIPS
9919 +
9920 +config KLIPS_ESP
9921 + bool 'Encapsulating Security Payload - ESP ("VPN")'
9922 + default y
9923 + help
9924 + This option provides support for the IPSEC Encapsulation Security
9925 + Payload (IP protocol 50) which provides packet layer content
9926 + hiding, and content authentication.
9927 + It is recommended to enable this. RFC2406
9928 +
9929 +config KLIPS_AH
9930 + bool 'Authentication Header - AH'
9931 + default n
9932 + help
9933 + This option provides support for the IPSEC Authentication Header
9934 + (IP protocol 51) which provides packet layer sender and content
9935 + authentication. It does not provide for confidentiality.
9936 + It is not recommended to enable this. RFC2402
9937 +
9938 +config KLIPS_AUTH_HMAC_MD5
9939 + bool 'HMAC-MD5 authentication algorithm'
9940 + default y
9941 + help
9942 + The HMAC-MD5 algorithm is used by ESP (and AH) to guarantee packet
9943 + integrity. There is little reason not to include it.
9944 +
9945 +config KLIPS_AUTH_HMAC_SHA1
9946 + bool 'HMAC-SHA1 authentication algorithm'
9947 + default y
9948 + help
9949 + The HMAC-SHA1 algorithm is used by ESP (and AH) to guarantee packet
9950 + integrity. SHA1 is a little slower than MD5, but is said to be
9951 + a bit more secure. There is little reason not to include it.
9952 +
9953 +config KLIPS_ENC_CRYPTOAPI
9954 + bool 'CryptoAPI algorithm interface'
9955 + default n
9956 + help
9957 + Enable the algorithm interface to make all CryptoAPI 1.0 algorithms
9958 + available to KLIPS.
9959 +
9960 +config KLIPS_ENC_1DES
9961 + bool 'Include 1DES with CryptoAPI'
9962 + default n
9963 + depends on KLIPS_ENC_CRYPTOAPI
9964 + help
9965 + The CryptoAPI interface does not include support for every algorithm
9966 + yet, and one that it doesn't support by default is the VERY WEAK
9967 + 1DES. Select this if you are terminally stupid.
9968 +
9969 +config KLIPS_ENC_3DES
9970 + bool '3DES encryption algorithm'
9971 + default y
9972 + help
9973 + The 3DES algorithm is used by ESP to provide for packet privacy.
9974 + 3DES is 3-repeats of the DES algorithm. 3DES is widely supported,
9975 + and analyzed and is considered very secure. 1DES is not supported.
9976 +
9977 +config KLIPS_ENC_AES
9978 + bool 'AES encryption algorithm'
9979 + default y
9980 + help
9981 + The AES algorithm is used by ESP to provide for packet privacy.
9982 + AES the NIST replacement for DES. AES is being widely analyzed,
9983 + and is very fast.
9984 +
9985 +config KLIPS_ENC_NULL
9986 + bool 'NULL NON-encryption algorithm'
9987 + default n
9988 + help
9989 + NON encryption algo , maybe useful for ESP auth only scenarios
9990 + (eg: with NAT-T), see RFC 2410.
9991 +
9992 +config KLIPS_IPCOMP
9993 + bool 'IP compression'
9994 + default y
9995 + help
9996 + The IPcomp protocol is used prior to ESP to make the packet
9997 + smaller. Once encrypted, compression will fail, so any link
9998 + layer efforts (e.g. PPP) will not work.
9999 +
10000 +config KLIPS_DEBUG
10001 + bool 'IPsec debugging'
10002 + default y
10003 + help
10004 + KLIPS includes a lot of debugging code. Unless there is a real
10005 + tangible benefit to removing this code, it should be left in place.
10006 + Debugging connections without access to kernel level debugging is
10007 + essentially impossible. Leave this on.
10008 +
10009 +endmenu
10010 +
10011 +#
10012 +#
10013 +# $Log: Kconfig,v $
10014 +# Revision 1.6.2.2 2006/10/11 18:14:33 paul
10015 +# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
10016 +# per default.
10017 +#
10018 +# Revision 1.6.2.1 2006/04/20 16:33:06 mcr
10019 +# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
10020 +# Fix in-kernel module compilation. Sub-makefiles do not work.
10021 +#
10022 +# Revision 1.6 2005/05/18 20:55:27 mcr
10023 +# default cryptoapi to n.
10024 +#
10025 +# Revision 1.5 2005/05/11 01:23:25 mcr
10026 +# added 1DES option to cryptoapi.
10027 +#
10028 +# Revision 1.4 2005/04/29 05:29:54 mcr
10029 +# add option to include cryptoapi algorithms.
10030 +#
10031 +# Revision 1.3 2004/08/17 03:27:23 mcr
10032 +# klips 2.6 edits.
10033 +#
10034 +# Revision 1.2 2004/08/14 03:27:39 mcr
10035 +# 2.6 kernel build/configuration files.
10036 +#
10037 +# Revision 1.1 2004/08/14 02:47:55 mcr
10038 +# kernel build/config patches
10039 +#
10040 +# Revision 1.3 2004/02/24 17:17:04 mcr
10041 +# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
10042 +# turn it on/off as well.
10043 +#
10044 +# Revision 1.2 2004/02/22 06:50:42 mcr
10045 +# kernel 2.6 port - merged with 2.4 code.
10046 +#
10047 +# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
10048 +# module configuration for KLIPS 2.6
10049 +#
10050 +#
10051 +
10052 --- /dev/null Tue Mar 11 13:02:56 2003
10053 +++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004
10054 @@ -0,0 +1,195 @@
10055 +# Makefile for KLIPS kernel code as a module for 2.6 kernels
10056 +#
10057 +# Makefile for KLIPS kernel code as a module
10058 +# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
10059 +# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
10060 +#
10061 +# This program is free software; you can redistribute it and/or modify it
10062 +# under the terms of the GNU General Public License as published by the
10063 +# Free Software Foundation; either version 2 of the License, or (at your
10064 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10065 +#
10066 +# This program is distributed in the hope that it will be useful, but
10067 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10068 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10069 +# for more details.
10070 +#
10071 +# RCSID $Id: Makefile.fs2_6,v 1.8.2.2 2006/10/11 18:14:33 paul Exp $
10072 +#
10073 +# Note! Dependencies are done automagically by 'make dep', which also
10074 +# removes any old dependencies. DON'T put your own dependencies here
10075 +# unless it's something special (ie not a .c file).
10076 +#
10077 +
10078 +OPENSWANSRCDIR?=.
10079 +KLIPS_TOP?=.
10080 +
10081 +-include ${OPENSWANSRCDIR}/Makefile.ver
10082 +
10083 +base-klips-objs :=
10084 +
10085 +base-klips-objs+= ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
10086 +base-klips-objs+= ipsec_life.o ipsec_proc.o
10087 +base-klips-objs+= ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
10088 +base-klips-objs+= ipsec_snprintf.o
10089 +base-klips-objs+= sysctl_net_ipsec.o
10090 +base-klips-objs+= pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
10091 +base-klips-objs+= version.o
10092 +
10093 +base-klips-objs+= satot.o
10094 +base-klips-objs+= addrtot.o
10095 +base-klips-objs+= ultot.o
10096 +base-klips-objs+= addrtypeof.o
10097 +base-klips-objs+= anyaddr.o
10098 +base-klips-objs+= initaddr.o
10099 +base-klips-objs+= ultoa.o
10100 +base-klips-objs+= addrtoa.o
10101 +base-klips-objs+= subnettoa.o
10102 +base-klips-objs+= subnetof.o
10103 +base-klips-objs+= goodmask.o
10104 +base-klips-objs+= datatot.o
10105 +base-klips-objs+= rangetoa.o
10106 +base-klips-objs+= prng.o
10107 +base-klips-objs+= pfkey_v2_parse.o
10108 +base-klips-objs+= pfkey_v2_build.o
10109 +base-klips-objs+= pfkey_v2_debug.o
10110 +base-klips-objs+= pfkey_v2_ext_bits.o
10111 +base-klips-objs+= version.o
10112 +
10113 +obj-${CONFIG_KLIPS} += ipsec.o
10114 +
10115 +ipsec-objs += ${base-klips-objs}
10116 +
10117 +ipsec-$(CONFIG_KLIPS_ESP) += ipsec_esp.o
10118 +ipsec-$(CONFIG_KLIPS_IPCOMP) += ipsec_ipcomp.o
10119 +ipsec-$(CONFIG_KLIPS_AUTH_HMAC_MD5) += ipsec_md5c.o
10120 +ipsec-$(CONFIG_KLIPS_AUTH_HMAC_SHA1) += ipsec_sha1.o
10121 +
10122 +# AH, if you really think you need it.
10123 +ipsec-$(CONFIG_KLIPS_AH) += ipsec_ah.o
10124 +
10125 +ipsec-y += ipsec_alg.o
10126 +
10127 +# include code from DES subdir
10128 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ipsec_alg_3des.o
10129 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/cbc_enc.o
10130 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/ecb_enc.o
10131 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/set_key.o
10132 +
10133 +ifeq ($(strip ${SUBARCH}),)
10134 +SUBARCH:=${ARCH}
10135 +endif
10136 +
10137 +# the assembly version expects frame pointers, which are
10138 +# optional in many kernel builds. If you want speed, you should
10139 +# probably use cryptoapi code instead.
10140 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10141 +ifeq (${USEASSEMBLY},i386y)
10142 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/dx86unix.o
10143 +else
10144 +crypto-$(CONFIG_KLIPS_ENC_3DES) += des/des_enc.o
10145 +endif
10146 +
10147 +# include code from AES subdir
10148 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/ipsec_alg_aes.o
10149 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_xcbc_mac.o
10150 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes_cbc.o
10151 +
10152 +ifeq ($(strip ${SUBARCH}),)
10153 +SUBARCH:=${ARCH}
10154 +endif
10155 +
10156 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
10157 +ifeq (${USEASSEMBLY},i386y)
10158 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes-i586.o
10159 +else
10160 +crypto-$(CONFIG_KLIPS_ENC_AES) += aes/aes.o
10161 +endif
10162 +
10163 +crypto-$(CONFIG_KLIPS_ENC_NULL) += null/ipsec_alg_null.o
10164 +
10165 +ipsec-y += ${crypto-y}
10166 +
10167 +ipsec-$(CONFIG_KLIPS_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o
10168 +
10169 +# IPcomp stuff
10170 +base-ipcomp-objs := ipcomp.o
10171 +base-ipcomp-objs += adler32.o
10172 +base-ipcomp-objs += deflate.o
10173 +base-ipcomp-objs += infblock.o
10174 +base-ipcomp-objs += infcodes.o
10175 +base-ipcomp-objs += inffast.o
10176 +base-ipcomp-objs += inflate.o
10177 +base-ipcomp-objs += inftrees.o
10178 +base-ipcomp-objs += infutil.o
10179 +base-ipcomp-objs += trees.o
10180 +base-ipcomp-objs += zutil.o
10181 +asm-ipcomp-obj-$(CONFIG_M586) += match586.o
10182 +asm-ipcomp-obj-$(CONFIG_M586TSC) += match586.o
10183 +asm-ipcomp-obj-$(CONFIG_M586MMX) += match586.o
10184 +asm-ipcomp-obj-$(CONFIG_M686) += match686.o
10185 +asm-ipcomp-obj-$(CONFIG_MPENTIUMIII) += match686.o
10186 +asm-ipcomp-obj-$(CONFIG_MPENTIUM4) += match686.o
10187 +asm-ipcomp-obj-$(CONFIG_MK6) += match586.o
10188 +asm-ipcomp-obj-$(CONFIG_MK7) += match686.o
10189 +asm-ipcomp-obj-$(CONFIG_MCRUSOE) += match586.o
10190 +asm-ipcomp-obj-$(CONFIG_MWINCHIPC6) += match586.o
10191 +asm-ipcomp-obj-$(CONFIG_MWINCHIP2) += match686.o
10192 +asm-ipcomp-obj-$(CONFIG_MWINCHIP3D) += match686.o
10193 +base-ipcomp-objs += ${asm-ipcomp-obj-y}
10194 +
10195 +ipsec-$(CONFIG_KLIPS_IPCOMP) += ${base-ipcomp-objs}
10196 +
10197 +EXTRA_CFLAGS += -DIPCOMP_PREFIX
10198 +
10199 +#
10200 +# $Log: Makefile.fs2_6,v $
10201 +# Revision 1.8.2.2 2006/10/11 18:14:33 paul
10202 +# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
10203 +# per default.
10204 +#
10205 +# Revision 1.8.2.1 2006/04/20 16:33:06 mcr
10206 +# remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
10207 +# Fix in-kernel module compilation. Sub-makefiles do not work.
10208 +#
10209 +# Revision 1.8 2005/05/11 03:15:42 mcr
10210 +# adjusted makefiles to sanely build modules properly.
10211 +#
10212 +# Revision 1.7 2005/04/13 22:52:12 mcr
10213 +# moved KLIPS specific snprintf() wrapper to seperate file.
10214 +#
10215 +# Revision 1.6 2004/08/22 05:02:03 mcr
10216 +# organized symbols such that it is easier to build modules.
10217 +#
10218 +# Revision 1.5 2004/08/18 01:43:56 mcr
10219 +# adjusted makefile enumation so that it can be used by module
10220 +# wrapper.
10221 +#
10222 +# Revision 1.4 2004/08/17 03:27:23 mcr
10223 +# klips 2.6 edits.
10224 +#
10225 +# Revision 1.3 2004/08/04 16:50:13 mcr
10226 +# removed duplicate definition of dx86unix.o
10227 +#
10228 +# Revision 1.2 2004/08/03 18:21:09 mcr
10229 +# only set KLIPS_TOP and OPENSWANSRCDIR if not already set.
10230 +#
10231 +# Revision 1.1 2004/07/26 15:02:22 mcr
10232 +# makefile for KLIPS module for 2.6.
10233 +#
10234 +# Revision 1.3 2004/02/24 17:17:04 mcr
10235 +# s/CONFIG_IPSEC/CONFIG_KLIPS/ as 26sec uses "CONFIG_IPSEC" to
10236 +# turn it on/off as well.
10237 +#
10238 +# Revision 1.2 2004/02/22 06:50:42 mcr
10239 +# kernel 2.6 port - merged with 2.4 code.
10240 +#
10241 +# Revision 1.1.2.1 2004/02/20 02:07:53 mcr
10242 +# module configuration for KLIPS 2.6
10243 +#
10244 +#
10245 +# Local Variables:
10246 +# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
10247 +# End Variables:
10248 +#
10249 +
10250 --- /dev/null Tue Mar 11 13:02:56 2003
10251 +++ linux/net/ipsec/README-zlib Mon Feb 9 13:51:03 2004
10252 @@ -0,0 +1,147 @@
10253 +zlib 1.1.4 is a general purpose data compression library. All the code
10254 +is thread safe. The data format used by the zlib library
10255 +is described by RFCs (Request for Comments) 1950 to 1952 in the files
10256 +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
10257 +format) and rfc1952.txt (gzip format). These documents are also available in
10258 +other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
10259 +
10260 +All functions of the compression library are documented in the file zlib.h
10261 +(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
10262 +example of the library is given in the file example.c which also tests that
10263 +the library is working correctly. Another example is given in the file
10264 +minigzip.c. The compression library itself is composed of all source files
10265 +except example.c and minigzip.c.
10266 +
10267 +To compile all files and run the test program, follow the instructions
10268 +given at the top of Makefile. In short "make test; make install"
10269 +should work for most machines. For Unix: "./configure; make test; make install"
10270 +For MSDOS, use one of the special makefiles such as Makefile.msc.
10271 +For VMS, use Make_vms.com or descrip.mms.
10272 +
10273 +Questions about zlib should be sent to <zlib@gzip.org>, or to
10274 +Gilles Vollant <info@winimage.com> for the Windows DLL version.
10275 +The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
10276 +Before reporting a problem, please check this site to verify that
10277 +you have the latest version of zlib; otherwise get the latest version and
10278 +check whether the problem still exists or not.
10279 +
10280 +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
10281 +before asking for help.
10282 +
10283 +Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
10284 +issue of Dr. Dobb's Journal; a copy of the article is available in
10285 +http://dogma.net/markn/articles/zlibtool/zlibtool.htm
10286 +
10287 +The changes made in version 1.1.4 are documented in the file ChangeLog.
10288 +The only changes made since 1.1.3 are bug corrections:
10289 +
10290 +- ZFREE was repeated on same allocation on some error conditions.
10291 + This creates a security problem described in
10292 + http://www.zlib.org/advisory-2002-03-11.txt
10293 +- Returned incorrect error (Z_MEM_ERROR) on some invalid data
10294 +- Avoid accesses before window for invalid distances with inflate window
10295 + less than 32K.
10296 +- force windowBits > 8 to avoid a bug in the encoder for a window size
10297 + of 256 bytes. (A complete fix will be available in 1.1.5).
10298 +
10299 +The beta version 1.1.5beta includes many more changes. A new official
10300 +version 1.1.5 will be released as soon as extensive testing has been
10301 +completed on it.
10302 +
10303 +
10304 +Unsupported third party contributions are provided in directory "contrib".
10305 +
10306 +A Java implementation of zlib is available in the Java Development Kit
10307 +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
10308 +See the zlib home page http://www.zlib.org for details.
10309 +
10310 +A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
10311 +is in the CPAN (Comprehensive Perl Archive Network) sites
10312 +http://www.cpan.org/modules/by-module/Compress/
10313 +
10314 +A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
10315 +is available in Python 1.5 and later versions, see
10316 +http://www.python.org/doc/lib/module-zlib.html
10317 +
10318 +A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
10319 +is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
10320 +
10321 +An experimental package to read and write files in .zip format,
10322 +written on top of zlib by Gilles Vollant <info@winimage.com>, is
10323 +available at http://www.winimage.com/zLibDll/unzip.html
10324 +and also in the contrib/minizip directory of zlib.
10325 +
10326 +
10327 +Notes for some targets:
10328 +
10329 +- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
10330 + and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
10331 + The zlib DLL support was initially done by Alessandro Iacopetti and is
10332 + now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
10333 + home page at http://www.winimage.com/zLibDll
10334 +
10335 + From Visual Basic, you can call the DLL functions which do not take
10336 + a structure as argument: compress, uncompress and all gz* functions.
10337 + See contrib/visual-basic.txt for more information, or get
10338 + http://www.tcfb.com/dowseware/cmp-z-it.zip
10339 +
10340 +- For 64-bit Irix, deflate.c must be compiled without any optimization.
10341 + With -O, one libpng test fails. The test works in 32 bit mode (with
10342 + the -n32 compiler flag). The compiler bug has been reported to SGI.
10343 +
10344 +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
10345 + it works when compiled with cc.
10346 +
10347 +- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
10348 + is necessary to get gzprintf working correctly. This is done by configure.
10349 +
10350 +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
10351 + with other compilers. Use "make test" to check your compiler.
10352 +
10353 +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
10354 +
10355 +- For Turbo C the small model is supported only with reduced performance to
10356 + avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
10357 +
10358 +- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
10359 + Per Harald Myrvang <perm@stud.cs.uit.no>
10360 +
10361 +
10362 +Acknowledgments:
10363 +
10364 + The deflate format used by zlib was defined by Phil Katz. The deflate
10365 + and zlib specifications were written by L. Peter Deutsch. Thanks to all the
10366 + people who reported problems and suggested various improvements in zlib;
10367 + they are too numerous to cite here.
10368 +
10369 +Copyright notice:
10370 +
10371 + (C) 1995-2002 Jean-loup Gailly and Mark Adler
10372 +
10373 + This software is provided 'as-is', without any express or implied
10374 + warranty. In no event will the authors be held liable for any damages
10375 + arising from the use of this software.
10376 +
10377 + Permission is granted to anyone to use this software for any purpose,
10378 + including commercial applications, and to alter it and redistribute it
10379 + freely, subject to the following restrictions:
10380 +
10381 + 1. The origin of this software must not be misrepresented; you must not
10382 + claim that you wrote the original software. If you use this software
10383 + in a product, an acknowledgment in the product documentation would be
10384 + appreciated but is not required.
10385 + 2. Altered source versions must be plainly marked as such, and must not be
10386 + misrepresented as being the original software.
10387 + 3. This notice may not be removed or altered from any source distribution.
10388 +
10389 + Jean-loup Gailly Mark Adler
10390 + jloup@gzip.org madler@alumni.caltech.edu
10391 +
10392 +If you use the zlib library in a product, we would appreciate *not*
10393 +receiving lengthy legal documents to sign. The sources are provided
10394 +for free but without warranty of any kind. The library has been
10395 +entirely written by Jean-loup Gailly and Mark Adler; it does not
10396 +include third-party code.
10397 +
10398 +If you redistribute modified sources, we would appreciate that you include
10399 +in the file ChangeLog history information documenting your changes.
10400 --- /dev/null Tue Mar 11 13:02:56 2003
10401 +++ linux/net/ipsec/README-zlib.freeswan Mon Feb 9 13:51:03 2004
10402 @@ -0,0 +1,13 @@
10403 +The only changes made to these files for use in FreeS/WAN are:
10404 +
10405 + - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
10406 + (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
10407 + - The copyright strings are defined local (static)
10408 +
10409 + The above changes are made to avoid name collisions with ppp_deflate
10410 + and ext2compr.
10411 +
10412 + - Files not needed for FreeS/WAN have been removed
10413 +
10414 + See the "README" file for information about where to obtain the complete
10415 + zlib package.
10416 --- /dev/null Tue Mar 11 13:02:56 2003
10417 +++ linux/net/ipsec/addrtoa.c Mon Feb 9 13:51:03 2004
10418 @@ -0,0 +1,67 @@
10419 +/*
10420 + * addresses to ASCII
10421 + * Copyright (C) 1998, 1999 Henry Spencer.
10422 + *
10423 + * This library is free software; you can redistribute it and/or modify it
10424 + * under the terms of the GNU Library General Public License as published by
10425 + * the Free Software Foundation; either version 2 of the License, or (at your
10426 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10427 + *
10428 + * This library is distributed in the hope that it will be useful, but
10429 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10430 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10431 + * License for more details.
10432 + *
10433 + * RCSID $Id: addrtoa.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10434 + */
10435 +#include "openswan.h"
10436 +
10437 +#define NBYTES 4 /* bytes in an address */
10438 +#define PERBYTE 4 /* three digits plus a dot or NUL */
10439 +#define BUFLEN (NBYTES*PERBYTE)
10440 +
10441 +#if BUFLEN != ADDRTOA_BUF
10442 +#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code"
10443 +#endif
10444 +
10445 +/*
10446 + - addrtoa - convert binary address to ASCII dotted decimal
10447 + */
10448 +size_t /* space needed for full conversion */
10449 +addrtoa(addr, format, dst, dstlen)
10450 +struct in_addr addr;
10451 +int format; /* character */
10452 +char *dst; /* need not be valid if dstlen is 0 */
10453 +size_t dstlen;
10454 +{
10455 + unsigned long a = ntohl(addr.s_addr);
10456 + int i;
10457 + size_t n;
10458 + unsigned long byte;
10459 + char buf[BUFLEN];
10460 + char *p;
10461 +
10462 + switch (format) {
10463 + case 0:
10464 + break;
10465 + default:
10466 + return 0;
10467 + break;
10468 + }
10469 +
10470 + p = buf;
10471 + for (i = NBYTES-1; i >= 0; i--) {
10472 + byte = (a >> (i*8)) & 0xff;
10473 + p += ultoa(byte, 10, p, PERBYTE);
10474 + if (i != 0)
10475 + *(p-1) = '.';
10476 + }
10477 + n = p - buf;
10478 +
10479 + if (dstlen > 0) {
10480 + if (n > dstlen)
10481 + buf[dstlen - 1] = '\0';
10482 + strcpy(dst, buf);
10483 + }
10484 + return n;
10485 +}
10486 --- /dev/null Tue Mar 11 13:02:56 2003
10487 +++ linux/net/ipsec/addrtot.c Mon Feb 9 13:51:03 2004
10488 @@ -0,0 +1,423 @@
10489 +/*
10490 + * addresses to text
10491 + * Copyright (C) 2000 Henry Spencer.
10492 + *
10493 + * This library is free software; you can redistribute it and/or modify it
10494 + * under the terms of the GNU Library General Public License as published by
10495 + * the Free Software Foundation; either version 2 of the License, or (at your
10496 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10497 + *
10498 + * This library is distributed in the hope that it will be useful, but
10499 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10500 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10501 + * License for more details.
10502 + *
10503 + * RCSID $Id: addrtot.c,v 1.22.2.1 2005/11/17 22:30:49 paul Exp $
10504 + */
10505 +
10506 +#if defined(__KERNEL__) && defined(__HAVE_ARCH_STRSTR)
10507 +#include <linux/string.h>
10508 +#endif
10509 +
10510 +#include "openswan.h"
10511 +
10512 +#define IP4BYTES 4 /* bytes in an IPv4 address */
10513 +#define PERBYTE 4 /* three digits plus a dot or NUL */
10514 +#define IP6BYTES 16 /* bytes in an IPv6 address */
10515 +
10516 +/* forwards */
10517 +static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
10518 +static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
10519 +static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
10520 +static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
10521 +
10522 +#if defined(__KERNEL__) && !defined(__HAVE_ARCH_STRSTR)
10523 +#define strstr ipsec_strstr
10524 +/*
10525 + * Find the first occurrence of find in s.
10526 + * (from NetBSD 1.6's /src/lib/libc/string/strstr.c)
10527 + */
10528 +static char *
10529 +strstr(s, find)
10530 + const char *s, *find;
10531 +{
10532 + char c, sc;
10533 + size_t len;
10534 +
10535 + if ((c = *find++) != 0) {
10536 + len = strlen(find);
10537 + do {
10538 + do {
10539 + if ((sc = *s++) == 0)
10540 + return (NULL);
10541 + } while (sc != c);
10542 + } while (strncmp(s, find, len) != 0);
10543 + s--;
10544 + }
10545 + /* LINTED interface specification */
10546 + return ((char *)s);
10547 +}
10548 +#endif
10549 +
10550 +/*
10551 + - addrtot - convert binary address to text (dotted decimal or IPv6 string)
10552 + */
10553 +size_t /* space needed for full conversion */
10554 +addrtot(src, format, dst, dstlen)
10555 +const ip_address *src;
10556 +int format; /* character */
10557 +char *dst; /* need not be valid if dstlen is 0 */
10558 +size_t dstlen;
10559 +{
10560 + const unsigned char *b;
10561 + size_t n;
10562 + char buf[1+ADDRTOT_BUF+1]; /* :address: */
10563 + char *p;
10564 + int t = addrtypeof(src);
10565 +# define TF(t, f) (((t)<<8) | (f))
10566 +
10567 + n = addrbytesptr(src, &b);
10568 + if (n == 0) {
10569 + bad:
10570 + dst[0]='\0';
10571 + strncat(dst, "<invalid>", dstlen);
10572 + return sizeof("<invalid>");
10573 + }
10574 +
10575 + switch (TF(t, format)) {
10576 + case TF(AF_INET, 0):
10577 + n = normal4(b, n, buf, &p);
10578 + break;
10579 + case TF(AF_INET6, 0):
10580 + n = normal6(b, n, buf, &p, 1);
10581 + break;
10582 + case TF(AF_INET, 'Q'):
10583 + n = normal4(b, n, buf, &p);
10584 + break;
10585 + case TF(AF_INET6, 'Q'):
10586 + n = normal6(b, n, buf, &p, 0);
10587 + break;
10588 + case TF(AF_INET, 'r'):
10589 + n = reverse4(b, n, buf, &p);
10590 + break;
10591 + case TF(AF_INET6, 'r'):
10592 + n = reverse6(b, n, buf, &p);
10593 + break;
10594 + default: /* including (AF_INET, 'R') */
10595 + goto bad;
10596 + break;
10597 + }
10598 +
10599 + if (dstlen > 0) {
10600 + if (dstlen < n)
10601 + p[dstlen - 1] = '\0';
10602 + strcpy(dst, p);
10603 + }
10604 + return n;
10605 +}
10606 +
10607 +/*
10608 + - normal4 - normal IPv4 address-text conversion
10609 + */
10610 +static size_t /* size of text, including NUL */
10611 +normal4(srcp, srclen, buf, dstp)
10612 +const unsigned char *srcp;
10613 +size_t srclen;
10614 +char *buf; /* guaranteed large enough */
10615 +char **dstp; /* where to put result pointer */
10616 +{
10617 + int i;
10618 + char *p;
10619 +
10620 + if (srclen != IP4BYTES) /* "can't happen" */
10621 + return 0;
10622 + p = buf;
10623 + for (i = 0; i < IP4BYTES; i++) {
10624 + p += ultot(srcp[i], 10, p, PERBYTE);
10625 + if (i != IP4BYTES - 1)
10626 + *(p-1) = '.'; /* overwrites the NUL */
10627 + }
10628 + *dstp = buf;
10629 + return p - buf;
10630 +}
10631 +
10632 +/*
10633 + - normal6 - normal IPv6 address-text conversion
10634 + */
10635 +static size_t /* size of text, including NUL */
10636 +normal6(srcp, srclen, buf, dstp, squish)
10637 +const unsigned char *srcp;
10638 +size_t srclen;
10639 +char *buf; /* guaranteed large enough, plus 2 */
10640 +char **dstp; /* where to put result pointer */
10641 +int squish; /* whether to squish out 0:0 */
10642 +{
10643 + int i;
10644 + unsigned long piece;
10645 + char *p;
10646 + char *q;
10647 +
10648 + if (srclen != IP6BYTES) /* "can't happen" */
10649 + return 0;
10650 + p = buf;
10651 + *p++ = ':';
10652 + for (i = 0; i < IP6BYTES/2; i++) {
10653 + piece = (srcp[2*i] << 8) + srcp[2*i + 1];
10654 + p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
10655 + *(p-1) = ':'; /* overwrites the NUL */
10656 + }
10657 + *p = '\0';
10658 + q = strstr(buf, ":0:0:");
10659 + if (squish && q != NULL) { /* zero squishing is possible */
10660 + p = q + 1;
10661 + while (*p == '0' && *(p+1) == ':')
10662 + p += 2;
10663 + q++;
10664 + *q++ = ':'; /* overwrite first 0 */
10665 + while (*p != '\0')
10666 + *q++ = *p++;
10667 + *q = '\0';
10668 + if (!(*(q-1) == ':' && *(q-2) == ':'))
10669 + *--q = '\0'; /* strip final : unless :: */
10670 + p = buf;
10671 + if (!(*p == ':' && *(p+1) == ':'))
10672 + p++; /* skip initial : unless :: */
10673 + } else {
10674 + q = p;
10675 + *--q = '\0'; /* strip final : */
10676 + p = buf + 1; /* skip initial : */
10677 + }
10678 + *dstp = p;
10679 + return q - p + 1;
10680 +}
10681 +
10682 +/*
10683 + - reverse4 - IPv4 reverse-lookup conversion
10684 + */
10685 +static size_t /* size of text, including NUL */
10686 +reverse4(srcp, srclen, buf, dstp)
10687 +const unsigned char *srcp;
10688 +size_t srclen;
10689 +char *buf; /* guaranteed large enough */
10690 +char **dstp; /* where to put result pointer */
10691 +{
10692 + int i;
10693 + char *p;
10694 +
10695 + if (srclen != IP4BYTES) /* "can't happen" */
10696 + return 0;
10697 + p = buf;
10698 + for (i = IP4BYTES-1; i >= 0; i--) {
10699 + p += ultot(srcp[i], 10, p, PERBYTE);
10700 + *(p-1) = '.'; /* overwrites the NUL */
10701 + }
10702 + strcpy(p, "IN-ADDR.ARPA.");
10703 + *dstp = buf;
10704 + return strlen(buf) + 1;
10705 +}
10706 +
10707 +/*
10708 + - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
10709 + * A trifle inefficient, really shouldn't use ultot...
10710 + */
10711 +static size_t /* size of text, including NUL */
10712 +reverse6(srcp, srclen, buf, dstp)
10713 +const unsigned char *srcp;
10714 +size_t srclen;
10715 +char *buf; /* guaranteed large enough */
10716 +char **dstp; /* where to put result pointer */
10717 +{
10718 + int i;
10719 + unsigned long piece;
10720 + char *p;
10721 +
10722 + if (srclen != IP6BYTES) /* "can't happen" */
10723 + return 0;
10724 + p = buf;
10725 + for (i = IP6BYTES-1; i >= 0; i--) {
10726 + piece = srcp[i];
10727 + p += ultot(piece&0xf, 16, p, 2);
10728 + *(p-1) = '.';
10729 + p += ultot(piece>>4, 16, p, 2);
10730 + *(p-1) = '.';
10731 + }
10732 + strcpy(p, "IP6.ARPA.");
10733 + *dstp = buf;
10734 + return strlen(buf) + 1;
10735 +}
10736 +
10737 +/*
10738 + - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
10739 + * this version removed as it was obsoleted in the end.
10740 + */
10741 +
10742 +#ifdef ADDRTOT_MAIN
10743 +
10744 +#include <stdio.h>
10745 +#include <sys/socket.h>
10746 +#include <netinet/in.h>
10747 +#include <arpa/inet.h>
10748 +
10749 +void regress(void);
10750 +
10751 +int
10752 +main(int argc, char *argv[])
10753 +{
10754 + if (argc < 2) {
10755 + fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
10756 + argv[0]);
10757 + exit(2);
10758 + }
10759 +
10760 + if (strcmp(argv[1], "-r") == 0) {
10761 + regress();
10762 + fprintf(stderr, "regress() returned?!?\n");
10763 + exit(1);
10764 + }
10765 + exit(0);
10766 +}
10767 +
10768 +struct rtab {
10769 + char *input;
10770 + char format;
10771 + char *output; /* NULL means error expected */
10772 +} rtab[] = {
10773 + {"1.2.3.0", 0, "1.2.3.0"},
10774 + {"1:2::3:4", 0, "1:2::3:4"},
10775 + {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
10776 + {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
10777 + {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
10778 + /* 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 */
10779 + {"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."},
10780 + {NULL, 0, NULL}
10781 +};
10782 +
10783 +void
10784 +regress()
10785 +{
10786 + struct rtab *r;
10787 + int status = 0;
10788 + ip_address a;
10789 + char in[100];
10790 + char buf[100];
10791 + const char *oops;
10792 + size_t n;
10793 +
10794 + for (r = rtab; r->input != NULL; r++) {
10795 + strcpy(in, r->input);
10796 +
10797 + /* convert it *to* internal format */
10798 + oops = ttoaddr(in, strlen(in), 0, &a);
10799 +
10800 + /* now convert it back */
10801 +
10802 + n = addrtot(&a, r->format, buf, sizeof(buf));
10803 +
10804 + if (n == 0 && r->output == NULL)
10805 + {} /* okay, error expected */
10806 +
10807 + else if (n == 0) {
10808 + printf("`%s' atoasr failed\n", r->input);
10809 + status = 1;
10810 +
10811 + } else if (r->output == NULL) {
10812 + printf("`%s' atoasr succeeded unexpectedly '%c'\n",
10813 + r->input, r->format);
10814 + status = 1;
10815 + } else {
10816 + if (strcasecmp(r->output, buf) != 0) {
10817 + printf("`%s' '%c' gave `%s', expected `%s'\n",
10818 + r->input, r->format, buf, r->output);
10819 + status = 1;
10820 + }
10821 + }
10822 + }
10823 + exit(status);
10824 +}
10825 +
10826 +#endif /* ADDRTOT_MAIN */
10827 +
10828 +/*
10829 + * $Log: addrtot.c,v $
10830 + * Revision 1.22.2.1 2005/11/17 22:30:49 paul
10831 + * pull up strstr fix from head.
10832 + *
10833 + * Revision 1.22 2005/05/20 16:47:40 mcr
10834 + * make strstr static if we need it.
10835 + *
10836 + * Revision 1.21 2005/03/21 00:35:12 mcr
10837 + * test for strstr properly
10838 + *
10839 + * Revision 1.20 2004/11/09 22:52:20 mcr
10840 + * until we figure out which kernels have strsep and which
10841 + * do not (UML does not under certain circumstances), then
10842 + * let's just provide our own.
10843 + *
10844 + * Revision 1.19 2004/10/08 16:30:33 mcr
10845 + * pull-up of initial crypto-offload work.
10846 + *
10847 + * Revision 1.18 2004/09/18 19:33:08 mcr
10848 + * use an appropriate kernel happy ifdef for strstr.
10849 + *
10850 + * Revision 1.17 2004/09/15 21:49:02 mcr
10851 + * use local copy of strstr() if this is going in the kernel.
10852 + * Not clear why this worked before, or why this shows up
10853 + * for modules only.
10854 + *
10855 + * Revision 1.16 2004/07/10 07:43:47 mcr
10856 + * Moved from linux/lib/libfreeswan/addrtot.c,v
10857 + *
10858 + * Revision 1.15 2004/04/11 17:39:25 mcr
10859 + * removed internal.h requirements.
10860 + *
10861 + * Revision 1.14 2004/03/08 01:59:08 ken
10862 + * freeswan.h -> openswan.h
10863 + *
10864 + * Revision 1.13 2004/01/05 23:21:05 mcr
10865 + * if the address type is invalid, then return length of <invalid>
10866 + * string!
10867 + *
10868 + * Revision 1.12 2003/12/30 06:42:48 mcr
10869 + * added $Log: addrtot.c,v $
10870 + * added Revision 1.22.2.1 2005/11/17 22:30:49 paul
10871 + * added pull up strstr fix from head.
10872 + * added
10873 + * added Revision 1.22 2005/05/20 16:47:40 mcr
10874 + * added make strstr static if we need it.
10875 + * added
10876 + * added Revision 1.21 2005/03/21 00:35:12 mcr
10877 + * added test for strstr properly
10878 + * added
10879 + * added Revision 1.20 2004/11/09 22:52:20 mcr
10880 + * added until we figure out which kernels have strsep and which
10881 + * added do not (UML does not under certain circumstances), then
10882 + * added let's just provide our own.
10883 + * added
10884 + * added Revision 1.19 2004/10/08 16:30:33 mcr
10885 + * added pull-up of initial crypto-offload work.
10886 + * added
10887 + * added Revision 1.18 2004/09/18 19:33:08 mcr
10888 + * added use an appropriate kernel happy ifdef for strstr.
10889 + * added
10890 + * added Revision 1.17 2004/09/15 21:49:02 mcr
10891 + * added use local copy of strstr() if this is going in the kernel.
10892 + * added Not clear why this worked before, or why this shows up
10893 + * added for modules only.
10894 + * added
10895 + * added Revision 1.16 2004/07/10 07:43:47 mcr
10896 + * added Moved from linux/lib/libfreeswan/addrtot.c,v
10897 + * added
10898 + * added Revision 1.15 2004/04/11 17:39:25 mcr
10899 + * added removed internal.h requirements.
10900 + * added
10901 + * added Revision 1.14 2004/03/08 01:59:08 ken
10902 + * added freeswan.h -> openswan.h
10903 + * added
10904 + * added Revision 1.13 2004/01/05 23:21:05 mcr
10905 + * added if the address type is invalid, then return length of <invalid>
10906 + * added string!
10907 + * added
10908 + *
10909 + *
10910 + */
10911 +
10912 --- /dev/null Tue Mar 11 13:02:56 2003
10913 +++ linux/net/ipsec/addrtypeof.c Mon Feb 9 13:51:03 2004
10914 @@ -0,0 +1,93 @@
10915 +/*
10916 + * extract parts of an ip_address
10917 + * Copyright (C) 2000 Henry Spencer.
10918 + *
10919 + * This library is free software; you can redistribute it and/or modify it
10920 + * under the terms of the GNU Library General Public License as published by
10921 + * the Free Software Foundation; either version 2 of the License, or (at your
10922 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10923 + *
10924 + * This library is distributed in the hope that it will be useful, but
10925 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10926 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
10927 + * License for more details.
10928 + *
10929 + * RCSID $Id: addrtypeof.c,v 1.10 2004/07/10 07:43:47 mcr Exp $
10930 + */
10931 +#include "openswan.h"
10932 +
10933 +/*
10934 + - addrtypeof - get the type of an ip_address
10935 + */
10936 +int
10937 +addrtypeof(src)
10938 +const ip_address *src;
10939 +{
10940 + return src->u.v4.sin_family;
10941 +}
10942 +
10943 +/*
10944 + - addrbytesptr - get pointer to the address bytes of an ip_address
10945 + */
10946 +size_t /* 0 for error */
10947 +addrbytesptr(src, dstp)
10948 +const ip_address *src;
10949 +const unsigned char **dstp; /* NULL means just a size query */
10950 +{
10951 + const unsigned char *p;
10952 + size_t n;
10953 +
10954 + switch (src->u.v4.sin_family) {
10955 + case AF_INET:
10956 + p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
10957 + n = 4;
10958 + break;
10959 + case AF_INET6:
10960 + p = (const unsigned char *)&src->u.v6.sin6_addr;
10961 + n = 16;
10962 + break;
10963 + default:
10964 + return 0;
10965 + break;
10966 + }
10967 +
10968 + if (dstp != NULL)
10969 + *dstp = p;
10970 + return n;
10971 +}
10972 +
10973 +/*
10974 + - addrlenof - get length of the address bytes of an ip_address
10975 + */
10976 +size_t /* 0 for error */
10977 +addrlenof(src)
10978 +const ip_address *src;
10979 +{
10980 + return addrbytesptr(src, NULL);
10981 +}
10982 +
10983 +/*
10984 + - addrbytesof - get the address bytes of an ip_address
10985 + */
10986 +size_t /* 0 for error */
10987 +addrbytesof(src, dst, dstlen)
10988 +const ip_address *src;
10989 +unsigned char *dst;
10990 +size_t dstlen;
10991 +{
10992 + const unsigned char *p;
10993 + size_t n;
10994 + size_t ncopy;
10995 +
10996 + n = addrbytesptr(src, &p);
10997 + if (n == 0)
10998 + return 0;
10999 +
11000 + if (dstlen > 0) {
11001 + ncopy = n;
11002 + if (ncopy > dstlen)
11003 + ncopy = dstlen;
11004 + memcpy(dst, p, ncopy);
11005 + }
11006 + return n;
11007 +}
11008 --- /dev/null Tue Mar 11 13:02:56 2003
11009 +++ linux/net/ipsec/adler32.c Mon Feb 9 13:51:03 2004
11010 @@ -0,0 +1,49 @@
11011 +/* adler32.c -- compute the Adler-32 checksum of a data stream
11012 + * Copyright (C) 1995-2002 Mark Adler
11013 + * For conditions of distribution and use, see copyright notice in zlib.h
11014 + */
11015 +
11016 +/* @(#) $Id: adler32.c,v 1.6 2004/07/10 19:11:18 mcr Exp $ */
11017 +
11018 +#include <zlib/zlib.h>
11019 +#include <zlib/zconf.h>
11020 +
11021 +#define BASE 65521L /* largest prime smaller than 65536 */
11022 +#define NMAX 5552
11023 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
11024 +
11025 +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
11026 +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
11027 +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
11028 +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
11029 +#define DO16(buf) DO8(buf,0); DO8(buf,8);
11030 +
11031 +/* ========================================================================= */
11032 +uLong ZEXPORT adler32(adler, buf, len)
11033 + uLong adler;
11034 + const Bytef *buf;
11035 + uInt len;
11036 +{
11037 + unsigned long s1 = adler & 0xffff;
11038 + unsigned long s2 = (adler >> 16) & 0xffff;
11039 + int k;
11040 +
11041 + if (buf == Z_NULL) return 1L;
11042 +
11043 + while (len > 0) {
11044 + k = len < NMAX ? len : NMAX;
11045 + len -= k;
11046 + while (k >= 16) {
11047 + DO16(buf);
11048 + buf += 16;
11049 + k -= 16;
11050 + }
11051 + if (k != 0) do {
11052 + s1 += *buf++;
11053 + s2 += s1;
11054 + } while (--k);
11055 + s1 %= BASE;
11056 + s2 %= BASE;
11057 + }
11058 + return (s2 << 16) | s1;
11059 +}
11060 --- /dev/null Tue Mar 11 13:02:56 2003
11061 +++ linux/net/ipsec/aes/Makefile Mon Feb 9 13:51:03 2004
11062 @@ -0,0 +1,59 @@
11063 +# Makefile for KLIPS 3DES kernel code as a module for 2.6 kernels
11064 +#
11065 +# Makefile for KLIPS kernel code as a module
11066 +# Copyright (C) 2002-2004 Michael Richardson <mcr@xelerance.com>
11067 +#
11068 +# This program is free software; you can redistribute it and/or modify it
11069 +# under the terms of the GNU General Public License as published by the
11070 +# Free Software Foundation; either version 2 of the License, or (at your
11071 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11072 +#
11073 +# This program is distributed in the hope that it will be useful, but
11074 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11075 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11076 +# for more details.
11077 +#
11078 +# RCSID $Id: Makefile.fs2_6,v 1.1.10.1 2005/08/12 16:10:05 ken Exp $
11079 +#
11080 +# Note! Dependencies are done automagically by 'make dep', which also
11081 +# removes any old dependencies. DON'T put your own dependencies here
11082 +# unless it's something special (ie not a .c file).
11083 +#
11084 +
11085 +obj-$(CONFIG_KLIPS_ENC_AES) += ipsec_alg_aes.o
11086 +obj-$(CONFIG_KLIPS_ENC_AES) += aes_xcbc_mac.o
11087 +obj-$(CONFIG_KLIPS_ENC_AES) += aes_cbc.o
11088 +
11089 +ifeq ($(strip ${SUBARCH}),)
11090 +SUBARCH:=${ARCH}
11091 +endif
11092 +
11093 +# the assembly version expects frame pointers, which are
11094 +# optional in many kernel builds. If you want speed, you should
11095 +# probably use cryptoapi code instead.
11096 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
11097 +ifeq (${USEASSEMBLY},i386y)
11098 +obj-$(CONFIG_KLIPS_ENC_AES) += aes-i586.o
11099 +else
11100 +obj-$(CONFIG_KLIPS_ENC_AES) += aes.o
11101 +endif
11102 +
11103 +
11104 +#
11105 +# $Log: Makefile.fs2_6,v $
11106 +# Revision 1.1.10.1 2005/08/12 16:10:05 ken
11107 +# do not use assembly code with there are no frame pointers
11108 +#
11109 +# Revision 1.2 2005/08/12 14:13:58 mcr
11110 +# do not use assembly code with there are no frame pointers,
11111 +# as it does not have the right linkages.
11112 +#
11113 +# Revision 1.1 2004/08/17 03:31:34 mcr
11114 +# klips 2.6 edits.
11115 +#
11116 +#
11117 +# Local Variables:
11118 +# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
11119 +# End Variables:
11120 +#
11121 +
11122 --- /dev/null Tue Mar 11 13:02:56 2003
11123 +++ linux/net/ipsec/aes/aes-i586.S Mon Feb 9 13:51:03 2004
11124 @@ -0,0 +1,892 @@
11125 +//
11126 +// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
11127 +// All rights reserved.
11128 +//
11129 +// TERMS
11130 +//
11131 +// Redistribution and use in source and binary forms, with or without
11132 +// modification, are permitted subject to the following conditions:
11133 +//
11134 +// 1. Redistributions of source code must retain the above copyright
11135 +// notice, this list of conditions and the following disclaimer.
11136 +//
11137 +// 2. Redistributions in binary form must reproduce the above copyright
11138 +// notice, this list of conditions and the following disclaimer in the
11139 +// documentation and/or other materials provided with the distribution.
11140 +//
11141 +// 3. The copyright holder's name must not be used to endorse or promote
11142 +// any products derived from this software without his specific prior
11143 +// written permission.
11144 +//
11145 +// This software is provided 'as is' with no express or implied warranties
11146 +// of correctness or fitness for purpose.
11147 +
11148 +// Modified by Jari Ruusu, December 24 2001
11149 +// - Converted syntax to GNU CPP/assembler syntax
11150 +// - C programming interface converted back to "old" API
11151 +// - Minor portability cleanups and speed optimizations
11152 +
11153 +// An AES (Rijndael) implementation for the Pentium. This version only
11154 +// implements the standard AES block length (128 bits, 16 bytes). This code
11155 +// does not preserve the eax, ecx or edx registers or the artihmetic status
11156 +// flags. However, the ebx, esi, edi, and ebp registers are preserved across
11157 +// calls.
11158 +
11159 +// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
11160 +// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
11161 +// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
11162 +
11163 +#if defined(USE_UNDERLINE)
11164 +# define aes_set_key _aes_set_key
11165 +# define aes_encrypt _aes_encrypt
11166 +# define aes_decrypt _aes_decrypt
11167 +#endif
11168 +#if !defined(ALIGN32BYTES)
11169 +# define ALIGN32BYTES 32
11170 +#endif
11171 +
11172 + .file "aes-i586.S"
11173 + .globl aes_set_key
11174 + .globl aes_encrypt
11175 + .globl aes_decrypt
11176 +
11177 +#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
11178 +
11179 +// offsets to parameters with one register pushed onto stack
11180 +
11181 +#define ctx 8 // AES context structure
11182 +#define in_blk 12 // input byte array address parameter
11183 +#define out_blk 16 // output byte array address parameter
11184 +
11185 +// offsets in context structure
11186 +
11187 +#define nkey 0 // key length, size 4
11188 +#define nrnd 4 // number of rounds, size 4
11189 +#define ekey 8 // encryption key schedule base address, size 256
11190 +#define dkey 264 // decryption key schedule base address, size 256
11191 +
11192 +// This macro performs a forward encryption cycle. It is entered with
11193 +// the first previous round column values in %eax, %ebx, %esi and %edi and
11194 +// exits with the final values in the same registers.
11195 +
11196 +#define fwd_rnd(p1,p2) \
11197 + mov %ebx,(%esp) ;\
11198 + movzbl %al,%edx ;\
11199 + mov %eax,%ecx ;\
11200 + mov p2(%ebp),%eax ;\
11201 + mov %edi,4(%esp) ;\
11202 + mov p2+12(%ebp),%edi ;\
11203 + xor p1(,%edx,4),%eax ;\
11204 + movzbl %ch,%edx ;\
11205 + shr $16,%ecx ;\
11206 + mov p2+4(%ebp),%ebx ;\
11207 + xor p1+tlen(,%edx,4),%edi ;\
11208 + movzbl %cl,%edx ;\
11209 + movzbl %ch,%ecx ;\
11210 + xor p1+3*tlen(,%ecx,4),%ebx ;\
11211 + mov %esi,%ecx ;\
11212 + mov p1+2*tlen(,%edx,4),%esi ;\
11213 + movzbl %cl,%edx ;\
11214 + xor p1(,%edx,4),%esi ;\
11215 + movzbl %ch,%edx ;\
11216 + shr $16,%ecx ;\
11217 + xor p1+tlen(,%edx,4),%ebx ;\
11218 + movzbl %cl,%edx ;\
11219 + movzbl %ch,%ecx ;\
11220 + xor p1+2*tlen(,%edx,4),%eax ;\
11221 + mov (%esp),%edx ;\
11222 + xor p1+3*tlen(,%ecx,4),%edi ;\
11223 + movzbl %dl,%ecx ;\
11224 + xor p2+8(%ebp),%esi ;\
11225 + xor p1(,%ecx,4),%ebx ;\
11226 + movzbl %dh,%ecx ;\
11227 + shr $16,%edx ;\
11228 + xor p1+tlen(,%ecx,4),%eax ;\
11229 + movzbl %dl,%ecx ;\
11230 + movzbl %dh,%edx ;\
11231 + xor p1+2*tlen(,%ecx,4),%edi ;\
11232 + mov 4(%esp),%ecx ;\
11233 + xor p1+3*tlen(,%edx,4),%esi ;\
11234 + movzbl %cl,%edx ;\
11235 + xor p1(,%edx,4),%edi ;\
11236 + movzbl %ch,%edx ;\
11237 + shr $16,%ecx ;\
11238 + xor p1+tlen(,%edx,4),%esi ;\
11239 + movzbl %cl,%edx ;\
11240 + movzbl %ch,%ecx ;\
11241 + xor p1+2*tlen(,%edx,4),%ebx ;\
11242 + xor p1+3*tlen(,%ecx,4),%eax
11243 +
11244 +// This macro performs an inverse encryption cycle. It is entered with
11245 +// the first previous round column values in %eax, %ebx, %esi and %edi and
11246 +// exits with the final values in the same registers.
11247 +
11248 +#define inv_rnd(p1,p2) \
11249 + movzbl %al,%edx ;\
11250 + mov %ebx,(%esp) ;\
11251 + mov %eax,%ecx ;\
11252 + mov p2(%ebp),%eax ;\
11253 + mov %edi,4(%esp) ;\
11254 + mov p2+4(%ebp),%ebx ;\
11255 + xor p1(,%edx,4),%eax ;\
11256 + movzbl %ch,%edx ;\
11257 + shr $16,%ecx ;\
11258 + mov p2+12(%ebp),%edi ;\
11259 + xor p1+tlen(,%edx,4),%ebx ;\
11260 + movzbl %cl,%edx ;\
11261 + movzbl %ch,%ecx ;\
11262 + xor p1+3*tlen(,%ecx,4),%edi ;\
11263 + mov %esi,%ecx ;\
11264 + mov p1+2*tlen(,%edx,4),%esi ;\
11265 + movzbl %cl,%edx ;\
11266 + xor p1(,%edx,4),%esi ;\
11267 + movzbl %ch,%edx ;\
11268 + shr $16,%ecx ;\
11269 + xor p1+tlen(,%edx,4),%edi ;\
11270 + movzbl %cl,%edx ;\
11271 + movzbl %ch,%ecx ;\
11272 + xor p1+2*tlen(,%edx,4),%eax ;\
11273 + mov (%esp),%edx ;\
11274 + xor p1+3*tlen(,%ecx,4),%ebx ;\
11275 + movzbl %dl,%ecx ;\
11276 + xor p2+8(%ebp),%esi ;\
11277 + xor p1(,%ecx,4),%ebx ;\
11278 + movzbl %dh,%ecx ;\
11279 + shr $16,%edx ;\
11280 + xor p1+tlen(,%ecx,4),%esi ;\
11281 + movzbl %dl,%ecx ;\
11282 + movzbl %dh,%edx ;\
11283 + xor p1+2*tlen(,%ecx,4),%edi ;\
11284 + mov 4(%esp),%ecx ;\
11285 + xor p1+3*tlen(,%edx,4),%eax ;\
11286 + movzbl %cl,%edx ;\
11287 + xor p1(,%edx,4),%edi ;\
11288 + movzbl %ch,%edx ;\
11289 + shr $16,%ecx ;\
11290 + xor p1+tlen(,%edx,4),%eax ;\
11291 + movzbl %cl,%edx ;\
11292 + movzbl %ch,%ecx ;\
11293 + xor p1+2*tlen(,%edx,4),%ebx ;\
11294 + xor p1+3*tlen(,%ecx,4),%esi
11295 +
11296 +// AES (Rijndael) Encryption Subroutine
11297 +
11298 + .text
11299 + .align ALIGN32BYTES
11300 +aes_encrypt:
11301 + push %ebp
11302 + mov ctx(%esp),%ebp // pointer to context
11303 + mov in_blk(%esp),%ecx
11304 + push %ebx
11305 + push %esi
11306 + push %edi
11307 + mov nrnd(%ebp),%edx // number of rounds
11308 + lea ekey+16(%ebp),%ebp // key pointer
11309 +
11310 +// input four columns and xor in first round key
11311 +
11312 + mov (%ecx),%eax
11313 + mov 4(%ecx),%ebx
11314 + mov 8(%ecx),%esi
11315 + mov 12(%ecx),%edi
11316 + xor -16(%ebp),%eax
11317 + xor -12(%ebp),%ebx
11318 + xor -8(%ebp),%esi
11319 + xor -4(%ebp),%edi
11320 +
11321 + sub $8,%esp // space for register saves on stack
11322 +
11323 + sub $10,%edx
11324 + je aes_15
11325 + add $32,%ebp
11326 + sub $2,%edx
11327 + je aes_13
11328 + add $32,%ebp
11329 +
11330 + fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
11331 + fwd_rnd(aes_ft_tab,-48)
11332 +aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
11333 + fwd_rnd(aes_ft_tab,-16)
11334 +aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
11335 + fwd_rnd(aes_ft_tab,16)
11336 + fwd_rnd(aes_ft_tab,32)
11337 + fwd_rnd(aes_ft_tab,48)
11338 + fwd_rnd(aes_ft_tab,64)
11339 + fwd_rnd(aes_ft_tab,80)
11340 + fwd_rnd(aes_ft_tab,96)
11341 + fwd_rnd(aes_ft_tab,112)
11342 + fwd_rnd(aes_ft_tab,128)
11343 + fwd_rnd(aes_fl_tab,144) // last round uses a different table
11344 +
11345 +// move final values to the output array.
11346 +
11347 + mov out_blk+20(%esp),%ebp
11348 + add $8,%esp
11349 + mov %eax,(%ebp)
11350 + mov %ebx,4(%ebp)
11351 + mov %esi,8(%ebp)
11352 + mov %edi,12(%ebp)
11353 + pop %edi
11354 + pop %esi
11355 + pop %ebx
11356 + pop %ebp
11357 + ret
11358 +
11359 +
11360 +// AES (Rijndael) Decryption Subroutine
11361 +
11362 + .align ALIGN32BYTES
11363 +aes_decrypt:
11364 + push %ebp
11365 + mov ctx(%esp),%ebp // pointer to context
11366 + mov in_blk(%esp),%ecx
11367 + push %ebx
11368 + push %esi
11369 + push %edi
11370 + mov nrnd(%ebp),%edx // number of rounds
11371 + lea dkey+16(%ebp),%ebp // key pointer
11372 +
11373 +// input four columns and xor in first round key
11374 +
11375 + mov (%ecx),%eax
11376 + mov 4(%ecx),%ebx
11377 + mov 8(%ecx),%esi
11378 + mov 12(%ecx),%edi
11379 + xor -16(%ebp),%eax
11380 + xor -12(%ebp),%ebx
11381 + xor -8(%ebp),%esi
11382 + xor -4(%ebp),%edi
11383 +
11384 + sub $8,%esp // space for register saves on stack
11385 +
11386 + sub $10,%edx
11387 + je aes_25
11388 + add $32,%ebp
11389 + sub $2,%edx
11390 + je aes_23
11391 + add $32,%ebp
11392 +
11393 + inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
11394 + inv_rnd(aes_it_tab,-48)
11395 +aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
11396 + inv_rnd(aes_it_tab,-16)
11397 +aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
11398 + inv_rnd(aes_it_tab,16)
11399 + inv_rnd(aes_it_tab,32)
11400 + inv_rnd(aes_it_tab,48)
11401 + inv_rnd(aes_it_tab,64)
11402 + inv_rnd(aes_it_tab,80)
11403 + inv_rnd(aes_it_tab,96)
11404 + inv_rnd(aes_it_tab,112)
11405 + inv_rnd(aes_it_tab,128)
11406 + inv_rnd(aes_il_tab,144) // last round uses a different table
11407 +
11408 +// move final values to the output array.
11409 +
11410 + mov out_blk+20(%esp),%ebp
11411 + add $8,%esp
11412 + mov %eax,(%ebp)
11413 + mov %ebx,4(%ebp)
11414 + mov %esi,8(%ebp)
11415 + mov %edi,12(%ebp)
11416 + pop %edi
11417 + pop %esi
11418 + pop %ebx
11419 + pop %ebp
11420 + ret
11421 +
11422 +// AES (Rijndael) Key Schedule Subroutine
11423 +
11424 +// input/output parameters
11425 +
11426 +#define aes_cx 12 // AES context
11427 +#define in_key 16 // key input array address
11428 +#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
11429 +#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
11430 +
11431 +// offsets for locals
11432 +
11433 +#define cnt -4
11434 +#define kpf -8
11435 +#define slen 8
11436 +
11437 +// This macro performs a column mixing operation on an input 32-bit
11438 +// word to give a 32-bit result. It uses each of the 4 bytes in the
11439 +// the input column to index 4 different tables of 256 32-bit words
11440 +// that are xored together to form the output value.
11441 +
11442 +#define mix_col(p1) \
11443 + movzbl %bl,%ecx ;\
11444 + mov p1(,%ecx,4),%eax ;\
11445 + movzbl %bh,%ecx ;\
11446 + ror $16,%ebx ;\
11447 + xor p1+tlen(,%ecx,4),%eax ;\
11448 + movzbl %bl,%ecx ;\
11449 + xor p1+2*tlen(,%ecx,4),%eax ;\
11450 + movzbl %bh,%ecx ;\
11451 + xor p1+3*tlen(,%ecx,4),%eax
11452 +
11453 +// Key Schedule Macros
11454 +
11455 +#define ksc4(p1) \
11456 + rol $24,%ebx ;\
11457 + mix_col(aes_fl_tab) ;\
11458 + ror $8,%ebx ;\
11459 + xor 4*p1+aes_rcon_tab,%eax ;\
11460 + xor %eax,%esi ;\
11461 + xor %esi,%ebp ;\
11462 + mov %esi,16*p1(%edi) ;\
11463 + mov %ebp,16*p1+4(%edi) ;\
11464 + xor %ebp,%edx ;\
11465 + xor %edx,%ebx ;\
11466 + mov %edx,16*p1+8(%edi) ;\
11467 + mov %ebx,16*p1+12(%edi)
11468 +
11469 +#define ksc6(p1) \
11470 + rol $24,%ebx ;\
11471 + mix_col(aes_fl_tab) ;\
11472 + ror $8,%ebx ;\
11473 + xor 4*p1+aes_rcon_tab,%eax ;\
11474 + xor 24*p1-24(%edi),%eax ;\
11475 + mov %eax,24*p1(%edi) ;\
11476 + xor 24*p1-20(%edi),%eax ;\
11477 + mov %eax,24*p1+4(%edi) ;\
11478 + xor %eax,%esi ;\
11479 + xor %esi,%ebp ;\
11480 + mov %esi,24*p1+8(%edi) ;\
11481 + mov %ebp,24*p1+12(%edi) ;\
11482 + xor %ebp,%edx ;\
11483 + xor %edx,%ebx ;\
11484 + mov %edx,24*p1+16(%edi) ;\
11485 + mov %ebx,24*p1+20(%edi)
11486 +
11487 +#define ksc8(p1) \
11488 + rol $24,%ebx ;\
11489 + mix_col(aes_fl_tab) ;\
11490 + ror $8,%ebx ;\
11491 + xor 4*p1+aes_rcon_tab,%eax ;\
11492 + xor 32*p1-32(%edi),%eax ;\
11493 + mov %eax,32*p1(%edi) ;\
11494 + xor 32*p1-28(%edi),%eax ;\
11495 + mov %eax,32*p1+4(%edi) ;\
11496 + xor 32*p1-24(%edi),%eax ;\
11497 + mov %eax,32*p1+8(%edi) ;\
11498 + xor 32*p1-20(%edi),%eax ;\
11499 + mov %eax,32*p1+12(%edi) ;\
11500 + push %ebx ;\
11501 + mov %eax,%ebx ;\
11502 + mix_col(aes_fl_tab) ;\
11503 + pop %ebx ;\
11504 + xor %eax,%esi ;\
11505 + xor %esi,%ebp ;\
11506 + mov %esi,32*p1+16(%edi) ;\
11507 + mov %ebp,32*p1+20(%edi) ;\
11508 + xor %ebp,%edx ;\
11509 + xor %edx,%ebx ;\
11510 + mov %edx,32*p1+24(%edi) ;\
11511 + mov %ebx,32*p1+28(%edi)
11512 +
11513 + .align ALIGN32BYTES
11514 +aes_set_key:
11515 + pushfl
11516 + push %ebp
11517 + mov %esp,%ebp
11518 + sub $slen,%esp
11519 + push %ebx
11520 + push %esi
11521 + push %edi
11522 +
11523 + mov aes_cx(%ebp),%edx // edx -> AES context
11524 +
11525 + mov key_ln(%ebp),%ecx // key length
11526 + cmpl $128,%ecx
11527 + jb aes_30
11528 + shr $3,%ecx
11529 +aes_30: cmpl $32,%ecx
11530 + je aes_32
11531 + cmpl $24,%ecx
11532 + je aes_32
11533 + mov $16,%ecx
11534 +aes_32: shr $2,%ecx
11535 + mov %ecx,nkey(%edx)
11536 +
11537 + lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
11538 + mov %eax,nrnd(%edx)
11539 +
11540 + mov in_key(%ebp),%esi // key input array
11541 + lea ekey(%edx),%edi // key position in AES context
11542 + cld
11543 + push %ebp
11544 + mov %ecx,%eax // save key length in eax
11545 + rep ; movsl // words in the key schedule
11546 + mov -4(%esi),%ebx // put some values in registers
11547 + mov -8(%esi),%edx // to allow faster code
11548 + mov -12(%esi),%ebp
11549 + mov -16(%esi),%esi
11550 +
11551 + cmpl $4,%eax // jump on key size
11552 + je aes_36
11553 + cmpl $6,%eax
11554 + je aes_35
11555 +
11556 + ksc8(0)
11557 + ksc8(1)
11558 + ksc8(2)
11559 + ksc8(3)
11560 + ksc8(4)
11561 + ksc8(5)
11562 + ksc8(6)
11563 + jmp aes_37
11564 +aes_35: ksc6(0)
11565 + ksc6(1)
11566 + ksc6(2)
11567 + ksc6(3)
11568 + ksc6(4)
11569 + ksc6(5)
11570 + ksc6(6)
11571 + ksc6(7)
11572 + jmp aes_37
11573 +aes_36: ksc4(0)
11574 + ksc4(1)
11575 + ksc4(2)
11576 + ksc4(3)
11577 + ksc4(4)
11578 + ksc4(5)
11579 + ksc4(6)
11580 + ksc4(7)
11581 + ksc4(8)
11582 + ksc4(9)
11583 +aes_37: pop %ebp
11584 + mov aes_cx(%ebp),%edx // edx -> AES context
11585 + cmpl $0,ed_flg(%ebp)
11586 + jne aes_39
11587 +
11588 +// compile decryption key schedule from encryption schedule - reverse
11589 +// order and do mix_column operation on round keys except first and last
11590 +
11591 + mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
11592 + shl $2,%eax
11593 + lea dkey(%edx,%eax,4),%edi
11594 + lea ekey(%edx),%esi // kf = cx->e_key
11595 +
11596 + movsl // copy first round key (unmodified)
11597 + movsl
11598 + movsl
11599 + movsl
11600 + sub $32,%edi
11601 + movl $1,cnt(%ebp)
11602 +aes_38: // do mix column on each column of
11603 + lodsl // each round key
11604 + mov %eax,%ebx
11605 + mix_col(aes_im_tab)
11606 + stosl
11607 + lodsl
11608 + mov %eax,%ebx
11609 + mix_col(aes_im_tab)
11610 + stosl
11611 + lodsl
11612 + mov %eax,%ebx
11613 + mix_col(aes_im_tab)
11614 + stosl
11615 + lodsl
11616 + mov %eax,%ebx
11617 + mix_col(aes_im_tab)
11618 + stosl
11619 + sub $32,%edi
11620 +
11621 + incl cnt(%ebp)
11622 + mov cnt(%ebp),%eax
11623 + cmp nrnd(%edx),%eax
11624 + jb aes_38
11625 +
11626 + movsl // copy last round key (unmodified)
11627 + movsl
11628 + movsl
11629 + movsl
11630 +aes_39: pop %edi
11631 + pop %esi
11632 + pop %ebx
11633 + mov %ebp,%esp
11634 + pop %ebp
11635 + popfl
11636 + ret
11637 +
11638 +
11639 +// finite field multiplies by {02}, {04} and {08}
11640 +
11641 +#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
11642 +#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
11643 +#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
11644 +
11645 +// finite field multiplies required in table generation
11646 +
11647 +#define f3(x) (f2(x) ^ x)
11648 +#define f9(x) (f8(x) ^ x)
11649 +#define fb(x) (f8(x) ^ f2(x) ^ x)
11650 +#define fd(x) (f8(x) ^ f4(x) ^ x)
11651 +#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
11652 +
11653 +// These defines generate the forward table entries
11654 +
11655 +#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
11656 +#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
11657 +#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
11658 +#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
11659 +
11660 +// These defines generate the inverse table entries
11661 +
11662 +#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
11663 +#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
11664 +#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
11665 +#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
11666 +
11667 +// These defines generate entries for the last round tables
11668 +
11669 +#define w0(x) (x)
11670 +#define w1(x) (x << 8)
11671 +#define w2(x) (x << 16)
11672 +#define w3(x) (x << 24)
11673 +
11674 +// macro to generate inverse mix column tables (needed for the key schedule)
11675 +
11676 +#define im_data0(p1) \
11677 + .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
11678 + .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
11679 + .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
11680 + .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
11681 +#define im_data1(p1) \
11682 + .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
11683 + .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
11684 + .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
11685 + .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
11686 +#define im_data2(p1) \
11687 + .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
11688 + .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
11689 + .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
11690 + .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
11691 +#define im_data3(p1) \
11692 + .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
11693 + .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
11694 + .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
11695 + .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
11696 +#define im_data4(p1) \
11697 + .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
11698 + .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
11699 + .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
11700 + .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
11701 +#define im_data5(p1) \
11702 + .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
11703 + .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
11704 + .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
11705 + .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
11706 +#define im_data6(p1) \
11707 + .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
11708 + .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
11709 + .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
11710 + .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
11711 +#define im_data7(p1) \
11712 + .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
11713 + .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
11714 + .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
11715 + .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
11716 +
11717 +// S-box data - 256 entries
11718 +
11719 +#define sb_data0(p1) \
11720 + .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
11721 + .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
11722 + .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
11723 + .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
11724 +#define sb_data1(p1) \
11725 + .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
11726 + .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
11727 + .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
11728 + .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
11729 +#define sb_data2(p1) \
11730 + .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
11731 + .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
11732 + .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
11733 + .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
11734 +#define sb_data3(p1) \
11735 + .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
11736 + .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
11737 + .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
11738 + .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
11739 +#define sb_data4(p1) \
11740 + .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
11741 + .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
11742 + .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
11743 + .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
11744 +#define sb_data5(p1) \
11745 + .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
11746 + .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
11747 + .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
11748 + .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
11749 +#define sb_data6(p1) \
11750 + .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
11751 + .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
11752 + .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
11753 + .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
11754 +#define sb_data7(p1) \
11755 + .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
11756 + .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
11757 + .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
11758 + .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
11759 +
11760 +// Inverse S-box data - 256 entries
11761 +
11762 +#define ib_data0(p1) \
11763 + .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
11764 + .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
11765 + .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
11766 + .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
11767 +#define ib_data1(p1) \
11768 + .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
11769 + .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
11770 + .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
11771 + .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
11772 +#define ib_data2(p1) \
11773 + .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
11774 + .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
11775 + .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
11776 + .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
11777 +#define ib_data3(p1) \
11778 + .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
11779 + .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
11780 + .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
11781 + .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
11782 +#define ib_data4(p1) \
11783 + .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
11784 + .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
11785 + .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
11786 + .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
11787 +#define ib_data5(p1) \
11788 + .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
11789 + .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
11790 + .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
11791 + .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
11792 +#define ib_data6(p1) \
11793 + .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
11794 + .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
11795 + .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
11796 + .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
11797 +#define ib_data7(p1) \
11798 + .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
11799 + .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
11800 + .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
11801 + .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
11802 +
11803 +// The rcon_table (needed for the key schedule)
11804 +//
11805 +// Here is original Dr Brian Gladman's source code:
11806 +// _rcon_tab:
11807 +// %assign x 1
11808 +// %rep 29
11809 +// dd x
11810 +// %assign x f2(x)
11811 +// %endrep
11812 +//
11813 +// Here is precomputed output (it's more portable this way):
11814 +
11815 + .align ALIGN32BYTES
11816 +aes_rcon_tab:
11817 + .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
11818 + .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
11819 + .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
11820 + .long 0xb3,0x7d,0xfa,0xef,0xc5
11821 +
11822 +// The forward xor tables
11823 +
11824 + .align ALIGN32BYTES
11825 +aes_ft_tab:
11826 + sb_data0(u0)
11827 + sb_data1(u0)
11828 + sb_data2(u0)
11829 + sb_data3(u0)
11830 + sb_data4(u0)
11831 + sb_data5(u0)
11832 + sb_data6(u0)
11833 + sb_data7(u0)
11834 +
11835 + sb_data0(u1)
11836 + sb_data1(u1)
11837 + sb_data2(u1)
11838 + sb_data3(u1)
11839 + sb_data4(u1)
11840 + sb_data5(u1)
11841 + sb_data6(u1)
11842 + sb_data7(u1)
11843 +
11844 + sb_data0(u2)
11845 + sb_data1(u2)
11846 + sb_data2(u2)
11847 + sb_data3(u2)
11848 + sb_data4(u2)
11849 + sb_data5(u2)
11850 + sb_data6(u2)
11851 + sb_data7(u2)
11852 +
11853 + sb_data0(u3)
11854 + sb_data1(u3)
11855 + sb_data2(u3)
11856 + sb_data3(u3)
11857 + sb_data4(u3)
11858 + sb_data5(u3)
11859 + sb_data6(u3)
11860 + sb_data7(u3)
11861 +
11862 + .align ALIGN32BYTES
11863 +aes_fl_tab:
11864 + sb_data0(w0)
11865 + sb_data1(w0)
11866 + sb_data2(w0)
11867 + sb_data3(w0)
11868 + sb_data4(w0)
11869 + sb_data5(w0)
11870 + sb_data6(w0)
11871 + sb_data7(w0)
11872 +
11873 + sb_data0(w1)
11874 + sb_data1(w1)
11875 + sb_data2(w1)
11876 + sb_data3(w1)
11877 + sb_data4(w1)
11878 + sb_data5(w1)
11879 + sb_data6(w1)
11880 + sb_data7(w1)
11881 +
11882 + sb_data0(w2)
11883 + sb_data1(w2)
11884 + sb_data2(w2)
11885 + sb_data3(w2)
11886 + sb_data4(w2)
11887 + sb_data5(w2)
11888 + sb_data6(w2)
11889 + sb_data7(w2)
11890 +
11891 + sb_data0(w3)
11892 + sb_data1(w3)
11893 + sb_data2(w3)
11894 + sb_data3(w3)
11895 + sb_data4(w3)
11896 + sb_data5(w3)
11897 + sb_data6(w3)
11898 + sb_data7(w3)
11899 +
11900 +// The inverse xor tables
11901 +
11902 + .align ALIGN32BYTES
11903 +aes_it_tab:
11904 + ib_data0(v0)
11905 + ib_data1(v0)
11906 + ib_data2(v0)
11907 + ib_data3(v0)
11908 + ib_data4(v0)
11909 + ib_data5(v0)
11910 + ib_data6(v0)
11911 + ib_data7(v0)
11912 +
11913 + ib_data0(v1)
11914 + ib_data1(v1)
11915 + ib_data2(v1)
11916 + ib_data3(v1)
11917 + ib_data4(v1)
11918 + ib_data5(v1)
11919 + ib_data6(v1)
11920 + ib_data7(v1)
11921 +
11922 + ib_data0(v2)
11923 + ib_data1(v2)
11924 + ib_data2(v2)
11925 + ib_data3(v2)
11926 + ib_data4(v2)
11927 + ib_data5(v2)
11928 + ib_data6(v2)
11929 + ib_data7(v2)
11930 +
11931 + ib_data0(v3)
11932 + ib_data1(v3)
11933 + ib_data2(v3)
11934 + ib_data3(v3)
11935 + ib_data4(v3)
11936 + ib_data5(v3)
11937 + ib_data6(v3)
11938 + ib_data7(v3)
11939 +
11940 + .align ALIGN32BYTES
11941 +aes_il_tab:
11942 + ib_data0(w0)
11943 + ib_data1(w0)
11944 + ib_data2(w0)
11945 + ib_data3(w0)
11946 + ib_data4(w0)
11947 + ib_data5(w0)
11948 + ib_data6(w0)
11949 + ib_data7(w0)
11950 +
11951 + ib_data0(w1)
11952 + ib_data1(w1)
11953 + ib_data2(w1)
11954 + ib_data3(w1)
11955 + ib_data4(w1)
11956 + ib_data5(w1)
11957 + ib_data6(w1)
11958 + ib_data7(w1)
11959 +
11960 + ib_data0(w2)
11961 + ib_data1(w2)
11962 + ib_data2(w2)
11963 + ib_data3(w2)
11964 + ib_data4(w2)
11965 + ib_data5(w2)
11966 + ib_data6(w2)
11967 + ib_data7(w2)
11968 +
11969 + ib_data0(w3)
11970 + ib_data1(w3)
11971 + ib_data2(w3)
11972 + ib_data3(w3)
11973 + ib_data4(w3)
11974 + ib_data5(w3)
11975 + ib_data6(w3)
11976 + ib_data7(w3)
11977 +
11978 +// The inverse mix column tables
11979 +
11980 + .align ALIGN32BYTES
11981 +aes_im_tab:
11982 + im_data0(v0)
11983 + im_data1(v0)
11984 + im_data2(v0)
11985 + im_data3(v0)
11986 + im_data4(v0)
11987 + im_data5(v0)
11988 + im_data6(v0)
11989 + im_data7(v0)
11990 +
11991 + im_data0(v1)
11992 + im_data1(v1)
11993 + im_data2(v1)
11994 + im_data3(v1)
11995 + im_data4(v1)
11996 + im_data5(v1)
11997 + im_data6(v1)
11998 + im_data7(v1)
11999 +
12000 + im_data0(v2)
12001 + im_data1(v2)
12002 + im_data2(v2)
12003 + im_data3(v2)
12004 + im_data4(v2)
12005 + im_data5(v2)
12006 + im_data6(v2)
12007 + im_data7(v2)
12008 +
12009 + im_data0(v3)
12010 + im_data1(v3)
12011 + im_data2(v3)
12012 + im_data3(v3)
12013 + im_data4(v3)
12014 + im_data5(v3)
12015 + im_data6(v3)
12016 + im_data7(v3)
12017 --- /dev/null Tue Mar 11 13:02:56 2003
12018 +++ linux/net/ipsec/aes/aes.c Mon Feb 9 13:51:03 2004
12019 @@ -0,0 +1,1415 @@
12020 +// I retain copyright in this code but I encourage its free use provided
12021 +// that I don't carry any responsibility for the results. I am especially
12022 +// happy to see it used in free and open source software. If you do use
12023 +// it I would appreciate an acknowledgement of its origin in the code or
12024 +// the product that results and I would also appreciate knowing a little
12025 +// about the use to which it is being put. I am grateful to Frank Yellin
12026 +// for some ideas that are used in this implementation.
12027 +//
12028 +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
12029 +//
12030 +// This is an implementation of the AES encryption algorithm (Rijndael)
12031 +// designed by Joan Daemen and Vincent Rijmen. This version is designed
12032 +// to provide both fixed and dynamic block and key lengths and can also
12033 +// run with either big or little endian internal byte order (see aes.h).
12034 +// It inputs block and key lengths in bytes with the legal values being
12035 +// 16, 24 and 32.
12036 +
12037 +/*
12038 + * Modified by Jari Ruusu, May 1 2001
12039 + * - Fixed some compile warnings, code was ok but gcc warned anyway.
12040 + * - Changed basic types: byte -> unsigned char, word -> u_int32_t
12041 + * - Major name space cleanup: Names visible to outside now begin
12042 + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
12043 + * - Removed C++ and DLL support as part of name space cleanup.
12044 + * - Eliminated unnecessary recomputation of tables. (actual bug fix)
12045 + * - Merged precomputed constant tables to aes.c file.
12046 + * - Removed data alignment restrictions for portability reasons.
12047 + * - Made block and key lengths accept bit count (128/192/256)
12048 + * as well byte count (16/24/32).
12049 + * - Removed all error checks. This change also eliminated the need
12050 + * to preinitialize the context struct to zero.
12051 + * - Removed some totally unused constants.
12052 + */
12053 +
12054 +#include "crypto/aes.h"
12055 +
12056 +// CONFIGURATION OPTIONS (see also aes.h)
12057 +//
12058 +// 1. Define UNROLL for full loop unrolling in encryption and decryption.
12059 +// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
12060 +// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
12061 +// 4. Define FF_TABLES to use tables for field multiplies and inverses.
12062 +// Do not enable this without understanding stack space requirements.
12063 +// 5. Define ARRAYS to use arrays to hold the local state block. If this
12064 +// is not defined, individually declared 32-bit words are used.
12065 +// 6. Define FAST_VARIABLE if a high speed variable block implementation
12066 +// is needed (essentially three separate fixed block size code sequences)
12067 +// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
12068 +// version using 1 table (2 kbytes of table space) or 4 tables (8
12069 +// kbytes of table space) for higher speed.
12070 +// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
12071 +// increase by using tables for the last rounds but with more table
12072 +// space (2 or 8 kbytes extra).
12073 +// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
12074 +// slower version is provided.
12075 +// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
12076 +// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
12077 +
12078 +#define UNROLL
12079 +//#define PARTIAL_UNROLL
12080 +
12081 +#define FIXED_TABLES
12082 +//#define FF_TABLES
12083 +//#define ARRAYS
12084 +#define FAST_VARIABLE
12085 +
12086 +//#define ONE_TABLE
12087 +#define FOUR_TABLES
12088 +
12089 +//#define ONE_LR_TABLE
12090 +#define FOUR_LR_TABLES
12091 +
12092 +//#define ONE_IM_TABLE
12093 +#define FOUR_IM_TABLES
12094 +
12095 +#if defined(UNROLL) && defined (PARTIAL_UNROLL)
12096 +#error both UNROLL and PARTIAL_UNROLL are defined
12097 +#endif
12098 +
12099 +#if defined(ONE_TABLE) && defined (FOUR_TABLES)
12100 +#error both ONE_TABLE and FOUR_TABLES are defined
12101 +#endif
12102 +
12103 +#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
12104 +#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
12105 +#endif
12106 +
12107 +#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
12108 +#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
12109 +#endif
12110 +
12111 +#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
12112 +#error an illegal block size has been specified
12113 +#endif
12114 +
12115 +// upr(x,n): rotates bytes within words by n positions, moving bytes
12116 +// to higher index positions with wrap around into low positions
12117 +// ups(x,n): moves bytes by n positions to higher index positions in
12118 +// words but without wrap around
12119 +// bval(x,n): extracts a byte from a word
12120 +
12121 +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
12122 +#define ups(x,n) ((x) << 8 * (n))
12123 +#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
12124 +#define bytes2word(b0, b1, b2, b3) \
12125 + ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
12126 +
12127 +
12128 +/* little endian processor without data alignment restrictions: AES_LE_OK */
12129 +/* original code: i386 */
12130 +#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
12131 +#define AES_LE_OK 1
12132 +/* added (tested): alpha --jjo */
12133 +#elif defined(__alpha__)|| defined (__alpha)
12134 +#define AES_LE_OK 1
12135 +/* added (tested): ia64 --jjo */
12136 +#elif defined(__ia64__)|| defined (__ia64)
12137 +#define AES_LE_OK 1
12138 +#endif
12139 +
12140 +#ifdef AES_LE_OK
12141 +/* little endian processor without data alignment restrictions */
12142 +#define word_in(x) *(u_int32_t*)(x)
12143 +#define const_word_in(x) *(const u_int32_t*)(x)
12144 +#define word_out(x,v) *(u_int32_t*)(x) = (v)
12145 +#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
12146 +#else
12147 +/* slower but generic big endian or with data alignment restrictions */
12148 +/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
12149 +#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))
12150 +#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))
12151 +#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)
12152 +#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)
12153 +#endif
12154 +
12155 +// Disable at least some poor combinations of options
12156 +
12157 +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
12158 +#define FIXED_TABLES
12159 +#undef UNROLL
12160 +#undef ONE_LR_TABLE
12161 +#undef FOUR_LR_TABLES
12162 +#undef ONE_IM_TABLE
12163 +#undef FOUR_IM_TABLES
12164 +#elif !defined(FOUR_TABLES)
12165 +#ifdef FOUR_LR_TABLES
12166 +#undef FOUR_LR_TABLES
12167 +#define ONE_LR_TABLE
12168 +#endif
12169 +#ifdef FOUR_IM_TABLES
12170 +#undef FOUR_IM_TABLES
12171 +#define ONE_IM_TABLE
12172 +#endif
12173 +#elif !defined(AES_BLOCK_SIZE)
12174 +#if defined(UNROLL)
12175 +#define PARTIAL_UNROLL
12176 +#undef UNROLL
12177 +#endif
12178 +#endif
12179 +
12180 +// the finite field modular polynomial and elements
12181 +
12182 +#define ff_poly 0x011b
12183 +#define ff_hi 0x80
12184 +
12185 +// multiply four bytes in GF(2^8) by 'x' {02} in parallel
12186 +
12187 +#define m1 0x80808080
12188 +#define m2 0x7f7f7f7f
12189 +#define m3 0x0000001b
12190 +#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
12191 +
12192 +// The following defines provide alternative definitions of FFmulX that might
12193 +// give improved performance if a fast 32-bit multiply is not available. Note
12194 +// that a temporary variable u needs to be defined where FFmulX is used.
12195 +
12196 +// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
12197 +// #define m4 0x1b1b1b1b
12198 +// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
12199 +
12200 +// perform column mix operation on four bytes in parallel
12201 +
12202 +#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
12203 +
12204 +#if defined(FIXED_TABLES)
12205 +
12206 +// the S-Box table
12207 +
12208 +static const unsigned char s_box[256] =
12209 +{
12210 + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
12211 + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
12212 + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
12213 + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
12214 + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
12215 + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
12216 + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
12217 + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
12218 + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
12219 + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
12220 + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
12221 + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
12222 + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
12223 + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
12224 + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
12225 + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
12226 + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
12227 + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
12228 + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
12229 + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
12230 + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
12231 + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
12232 + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
12233 + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
12234 + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
12235 + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
12236 + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
12237 + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
12238 + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
12239 + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
12240 + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
12241 + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
12242 +};
12243 +
12244 +// the inverse S-Box table
12245 +
12246 +static const unsigned char inv_s_box[256] =
12247 +{
12248 + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
12249 + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
12250 + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
12251 + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
12252 + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
12253 + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
12254 + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
12255 + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
12256 + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
12257 + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
12258 + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
12259 + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
12260 + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
12261 + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
12262 + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
12263 + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
12264 + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
12265 + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
12266 + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
12267 + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
12268 + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
12269 + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
12270 + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
12271 + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
12272 + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
12273 + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
12274 + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
12275 + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
12276 + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
12277 + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
12278 + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
12279 + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
12280 +};
12281 +
12282 +#define w0(p) 0x000000##p
12283 +
12284 +// Number of elements required in this table for different
12285 +// block and key lengths is:
12286 +//
12287 +// Nk = 4 6 8
12288 +// ----------
12289 +// Nb = 4 | 10 8 7
12290 +// 6 | 19 12 11
12291 +// 8 | 29 19 14
12292 +//
12293 +// this table can be a table of bytes if the key schedule
12294 +// code is adjusted accordingly
12295 +
12296 +static const u_int32_t rcon_tab[29] =
12297 +{
12298 + w0(01), w0(02), w0(04), w0(08),
12299 + w0(10), w0(20), w0(40), w0(80),
12300 + w0(1b), w0(36), w0(6c), w0(d8),
12301 + w0(ab), w0(4d), w0(9a), w0(2f),
12302 + w0(5e), w0(bc), w0(63), w0(c6),
12303 + w0(97), w0(35), w0(6a), w0(d4),
12304 + w0(b3), w0(7d), w0(fa), w0(ef),
12305 + w0(c5)
12306 +};
12307 +
12308 +#undef w0
12309 +
12310 +#define r0(p,q,r,s) 0x##p##q##r##s
12311 +#define r1(p,q,r,s) 0x##q##r##s##p
12312 +#define r2(p,q,r,s) 0x##r##s##p##q
12313 +#define r3(p,q,r,s) 0x##s##p##q##r
12314 +#define w0(p) 0x000000##p
12315 +#define w1(p) 0x0000##p##00
12316 +#define w2(p) 0x00##p##0000
12317 +#define w3(p) 0x##p##000000
12318 +
12319 +#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
12320 +
12321 +// data for forward tables (other than last round)
12322 +
12323 +#define f_table \
12324 + r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
12325 + r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
12326 + r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
12327 + r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
12328 + r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
12329 + r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
12330 + r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
12331 + r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
12332 + r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
12333 + r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
12334 + r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
12335 + r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
12336 + r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
12337 + r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
12338 + r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
12339 + r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
12340 + r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
12341 + r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
12342 + r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
12343 + r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
12344 + r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
12345 + r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
12346 + r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
12347 + r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
12348 + r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
12349 + r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
12350 + r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
12351 + r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
12352 + r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
12353 + r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
12354 + r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
12355 + r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
12356 + r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
12357 + r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
12358 + r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
12359 + r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
12360 + r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
12361 + r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
12362 + r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
12363 + r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
12364 + r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
12365 + r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
12366 + r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
12367 + r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
12368 + r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
12369 + r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
12370 + r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
12371 + r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
12372 + r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
12373 + r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
12374 + r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
12375 + r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
12376 + r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
12377 + r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
12378 + r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
12379 + r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
12380 + r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
12381 + r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
12382 + r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
12383 + r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
12384 + r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
12385 + r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
12386 + r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
12387 + r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
12388 +
12389 +// data for inverse tables (other than last round)
12390 +
12391 +#define i_table \
12392 + r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
12393 + r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
12394 + r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
12395 + r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
12396 + r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
12397 + r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
12398 + r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
12399 + r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
12400 + r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
12401 + r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
12402 + r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
12403 + r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
12404 + r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
12405 + r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
12406 + r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
12407 + r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
12408 + r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
12409 + r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
12410 + r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
12411 + r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
12412 + r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
12413 + r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
12414 + r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
12415 + r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
12416 + r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
12417 + r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
12418 + r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
12419 + r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
12420 + r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
12421 + r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
12422 + r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
12423 + r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
12424 + r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
12425 + r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
12426 + r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
12427 + r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
12428 + r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
12429 + r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
12430 + r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
12431 + r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
12432 + r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
12433 + r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
12434 + r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
12435 + r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
12436 + r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
12437 + r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
12438 + r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
12439 + r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
12440 + r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
12441 + r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
12442 + r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
12443 + r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
12444 + r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
12445 + r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
12446 + r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
12447 + r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
12448 + r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
12449 + r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
12450 + r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
12451 + r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
12452 + r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
12453 + r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
12454 + r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
12455 + r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
12456 +
12457 +// generate the required tables in the desired endian format
12458 +
12459 +#undef r
12460 +#define r r0
12461 +
12462 +#if defined(ONE_TABLE)
12463 +static const u_int32_t ft_tab[256] =
12464 + { f_table };
12465 +#elif defined(FOUR_TABLES)
12466 +static const u_int32_t ft_tab[4][256] =
12467 +{ { f_table },
12468 +#undef r
12469 +#define r r1
12470 + { f_table },
12471 +#undef r
12472 +#define r r2
12473 + { f_table },
12474 +#undef r
12475 +#define r r3
12476 + { f_table }
12477 +};
12478 +#endif
12479 +
12480 +#undef r
12481 +#define r r0
12482 +#if defined(ONE_TABLE)
12483 +static const u_int32_t it_tab[256] =
12484 + { i_table };
12485 +#elif defined(FOUR_TABLES)
12486 +static const u_int32_t it_tab[4][256] =
12487 +{ { i_table },
12488 +#undef r
12489 +#define r r1
12490 + { i_table },
12491 +#undef r
12492 +#define r r2
12493 + { i_table },
12494 +#undef r
12495 +#define r r3
12496 + { i_table }
12497 +};
12498 +#endif
12499 +
12500 +#endif
12501 +
12502 +#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
12503 +
12504 +// data for inverse tables (last round)
12505 +
12506 +#define li_table \
12507 + w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
12508 + w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
12509 + w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
12510 + w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
12511 + w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
12512 + w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
12513 + w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
12514 + w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
12515 + w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
12516 + w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
12517 + w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
12518 + w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
12519 + w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
12520 + w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
12521 + w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
12522 + w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
12523 + w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
12524 + w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
12525 + w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
12526 + w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
12527 + w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
12528 + w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
12529 + w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
12530 + w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
12531 + w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
12532 + w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
12533 + w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
12534 + w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
12535 + w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
12536 + w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
12537 + w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
12538 + w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
12539 +
12540 +// generate the required tables in the desired endian format
12541 +
12542 +#undef r
12543 +#define r(p,q,r,s) w0(q)
12544 +#if defined(ONE_LR_TABLE)
12545 +static const u_int32_t fl_tab[256] =
12546 + { f_table };
12547 +#elif defined(FOUR_LR_TABLES)
12548 +static const u_int32_t fl_tab[4][256] =
12549 +{ { f_table },
12550 +#undef r
12551 +#define r(p,q,r,s) w1(q)
12552 + { f_table },
12553 +#undef r
12554 +#define r(p,q,r,s) w2(q)
12555 + { f_table },
12556 +#undef r
12557 +#define r(p,q,r,s) w3(q)
12558 + { f_table }
12559 +};
12560 +#endif
12561 +
12562 +#undef w
12563 +#define w w0
12564 +#if defined(ONE_LR_TABLE)
12565 +static const u_int32_t il_tab[256] =
12566 + { li_table };
12567 +#elif defined(FOUR_LR_TABLES)
12568 +static const u_int32_t il_tab[4][256] =
12569 +{ { li_table },
12570 +#undef w
12571 +#define w w1
12572 + { li_table },
12573 +#undef w
12574 +#define w w2
12575 + { li_table },
12576 +#undef w
12577 +#define w w3
12578 + { li_table }
12579 +};
12580 +#endif
12581 +
12582 +#endif
12583 +
12584 +#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
12585 +
12586 +#define m_table \
12587 + r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
12588 + r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
12589 + r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
12590 + r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
12591 + r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
12592 + r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
12593 + r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
12594 + r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
12595 + r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
12596 + r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
12597 + r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
12598 + r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
12599 + r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
12600 + r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
12601 + r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
12602 + r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
12603 + r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
12604 + r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
12605 + r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
12606 + r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
12607 + r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
12608 + r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
12609 + r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
12610 + r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
12611 + r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
12612 + r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
12613 + r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
12614 + r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
12615 + r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
12616 + r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
12617 + r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
12618 + r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
12619 + r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
12620 + r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
12621 + r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
12622 + r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
12623 + r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
12624 + r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
12625 + r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
12626 + r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
12627 + r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
12628 + r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
12629 + r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
12630 + r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
12631 + r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
12632 + r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
12633 + r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
12634 + r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
12635 + r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
12636 + r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
12637 + r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
12638 + r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
12639 + r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
12640 + r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
12641 + r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
12642 + r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
12643 + r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
12644 + r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
12645 + r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
12646 + r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
12647 + r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
12648 + r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
12649 + r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
12650 + r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
12651 +
12652 +#undef r
12653 +#define r r0
12654 +
12655 +#if defined(ONE_IM_TABLE)
12656 +static const u_int32_t im_tab[256] =
12657 + { m_table };
12658 +#elif defined(FOUR_IM_TABLES)
12659 +static const u_int32_t im_tab[4][256] =
12660 +{ { m_table },
12661 +#undef r
12662 +#define r r1
12663 + { m_table },
12664 +#undef r
12665 +#define r r2
12666 + { m_table },
12667 +#undef r
12668 +#define r r3
12669 + { m_table }
12670 +};
12671 +#endif
12672 +
12673 +#endif
12674 +
12675 +#else
12676 +
12677 +static int tab_gen = 0;
12678 +
12679 +static unsigned char s_box[256]; // the S box
12680 +static unsigned char inv_s_box[256]; // the inverse S box
12681 +static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
12682 +
12683 +#if defined(ONE_TABLE)
12684 +static u_int32_t ft_tab[256];
12685 +static u_int32_t it_tab[256];
12686 +#elif defined(FOUR_TABLES)
12687 +static u_int32_t ft_tab[4][256];
12688 +static u_int32_t it_tab[4][256];
12689 +#endif
12690 +
12691 +#if defined(ONE_LR_TABLE)
12692 +static u_int32_t fl_tab[256];
12693 +static u_int32_t il_tab[256];
12694 +#elif defined(FOUR_LR_TABLES)
12695 +static u_int32_t fl_tab[4][256];
12696 +static u_int32_t il_tab[4][256];
12697 +#endif
12698 +
12699 +#if defined(ONE_IM_TABLE)
12700 +static u_int32_t im_tab[256];
12701 +#elif defined(FOUR_IM_TABLES)
12702 +static u_int32_t im_tab[4][256];
12703 +#endif
12704 +
12705 +// Generate the tables for the dynamic table option
12706 +
12707 +#if !defined(FF_TABLES)
12708 +
12709 +// It will generally be sensible to use tables to compute finite
12710 +// field multiplies and inverses but where memory is scarse this
12711 +// code might sometimes be better.
12712 +
12713 +// return 2 ^ (n - 1) where n is the bit number of the highest bit
12714 +// set in x with x in the range 1 < x < 0x00000200. This form is
12715 +// used so that locals within FFinv can be bytes rather than words
12716 +
12717 +static unsigned char hibit(const u_int32_t x)
12718 +{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
12719 +
12720 + r |= (r >> 2);
12721 + r |= (r >> 4);
12722 + return (r + 1) >> 1;
12723 +}
12724 +
12725 +// return the inverse of the finite field element x
12726 +
12727 +static unsigned char FFinv(const unsigned char x)
12728 +{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
12729 +
12730 + if(x < 2) return x;
12731 +
12732 + for(;;)
12733 + {
12734 + if(!n1) return v1;
12735 +
12736 + while(n2 >= n1)
12737 + {
12738 + n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
12739 + }
12740 +
12741 + if(!n2) return v2;
12742 +
12743 + while(n1 >= n2)
12744 + {
12745 + n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
12746 + }
12747 + }
12748 +}
12749 +
12750 +// define the finite field multiplies required for Rijndael
12751 +
12752 +#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
12753 +#define FFmul03(x) ((x) ^ FFmul02(x))
12754 +#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
12755 +#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
12756 +#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
12757 +#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
12758 +
12759 +#else
12760 +
12761 +#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
12762 +
12763 +#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
12764 +#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
12765 +#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
12766 +#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
12767 +#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
12768 +#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
12769 +
12770 +#endif
12771 +
12772 +// The forward and inverse affine transformations used in the S-box
12773 +
12774 +#define fwd_affine(x) \
12775 + (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
12776 +
12777 +#define inv_affine(x) \
12778 + (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
12779 +
12780 +static void gen_tabs(void)
12781 +{ u_int32_t i, w;
12782 +
12783 +#if defined(FF_TABLES)
12784 +
12785 + unsigned char pow[512], log[256];
12786 +
12787 + // log and power tables for GF(2^8) finite field with
12788 + // 0x011b as modular polynomial - the simplest primitive
12789 + // root is 0x03, used here to generate the tables
12790 +
12791 + i = 0; w = 1;
12792 + do
12793 + {
12794 + pow[i] = (unsigned char)w;
12795 + pow[i + 255] = (unsigned char)w;
12796 + log[w] = (unsigned char)i++;
12797 + w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12798 + }
12799 + while (w != 1);
12800 +
12801 +#endif
12802 +
12803 + for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
12804 + {
12805 + rcon_tab[i] = bytes2word(w, 0, 0, 0);
12806 + w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
12807 + }
12808 +
12809 + for(i = 0; i < 256; ++i)
12810 + { unsigned char b;
12811 +
12812 + s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
12813 +
12814 + w = bytes2word(b, 0, 0, 0);
12815 +#if defined(ONE_LR_TABLE)
12816 + fl_tab[i] = w;
12817 +#elif defined(FOUR_LR_TABLES)
12818 + fl_tab[0][i] = w;
12819 + fl_tab[1][i] = upr(w,1);
12820 + fl_tab[2][i] = upr(w,2);
12821 + fl_tab[3][i] = upr(w,3);
12822 +#endif
12823 + w = bytes2word(FFmul02(b), b, b, FFmul03(b));
12824 +#if defined(ONE_TABLE)
12825 + ft_tab[i] = w;
12826 +#elif defined(FOUR_TABLES)
12827 + ft_tab[0][i] = w;
12828 + ft_tab[1][i] = upr(w,1);
12829 + ft_tab[2][i] = upr(w,2);
12830 + ft_tab[3][i] = upr(w,3);
12831 +#endif
12832 + inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
12833 +
12834 + w = bytes2word(b, 0, 0, 0);
12835 +#if defined(ONE_LR_TABLE)
12836 + il_tab[i] = w;
12837 +#elif defined(FOUR_LR_TABLES)
12838 + il_tab[0][i] = w;
12839 + il_tab[1][i] = upr(w,1);
12840 + il_tab[2][i] = upr(w,2);
12841 + il_tab[3][i] = upr(w,3);
12842 +#endif
12843 + w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
12844 +#if defined(ONE_TABLE)
12845 + it_tab[i] = w;
12846 +#elif defined(FOUR_TABLES)
12847 + it_tab[0][i] = w;
12848 + it_tab[1][i] = upr(w,1);
12849 + it_tab[2][i] = upr(w,2);
12850 + it_tab[3][i] = upr(w,3);
12851 +#endif
12852 +#if defined(ONE_IM_TABLE)
12853 + im_tab[b] = w;
12854 +#elif defined(FOUR_IM_TABLES)
12855 + im_tab[0][b] = w;
12856 + im_tab[1][b] = upr(w,1);
12857 + im_tab[2][b] = upr(w,2);
12858 + im_tab[3][b] = upr(w,3);
12859 +#endif
12860 +
12861 + }
12862 +}
12863 +
12864 +#endif
12865 +
12866 +#define no_table(x,box,vf,rf,c) bytes2word( \
12867 + box[bval(vf(x,0,c),rf(0,c))], \
12868 + box[bval(vf(x,1,c),rf(1,c))], \
12869 + box[bval(vf(x,2,c),rf(2,c))], \
12870 + box[bval(vf(x,3,c),rf(3,c))])
12871 +
12872 +#define one_table(x,op,tab,vf,rf,c) \
12873 + ( tab[bval(vf(x,0,c),rf(0,c))] \
12874 + ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
12875 + ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
12876 + ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
12877 +
12878 +#define four_tables(x,tab,vf,rf,c) \
12879 + ( tab[0][bval(vf(x,0,c),rf(0,c))] \
12880 + ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
12881 + ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
12882 + ^ tab[3][bval(vf(x,3,c),rf(3,c))])
12883 +
12884 +#define vf1(x,r,c) (x)
12885 +#define rf1(r,c) (r)
12886 +#define rf2(r,c) ((r-c)&3)
12887 +
12888 +#if defined(FOUR_LR_TABLES)
12889 +#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
12890 +#elif defined(ONE_LR_TABLE)
12891 +#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
12892 +#else
12893 +#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
12894 +#endif
12895 +
12896 +#if defined(FOUR_IM_TABLES)
12897 +#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
12898 +#elif defined(ONE_IM_TABLE)
12899 +#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
12900 +#else
12901 +#define inv_mcol(x) \
12902 + (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
12903 + f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
12904 +#endif
12905 +
12906 +// Subroutine to set the block size (if variable) in bytes, legal
12907 +// values being 16, 24 and 32.
12908 +
12909 +#if defined(AES_BLOCK_SIZE)
12910 +#define nc (AES_BLOCK_SIZE / 4)
12911 +#else
12912 +#define nc (cx->aes_Ncol)
12913 +
12914 +void aes_set_blk(aes_context *cx, int n_bytes)
12915 +{
12916 +#if !defined(FIXED_TABLES)
12917 + if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12918 +#endif
12919 +
12920 + switch(n_bytes) {
12921 + case 32: /* bytes */
12922 + case 256: /* bits */
12923 + nc = 8;
12924 + break;
12925 + case 24: /* bytes */
12926 + case 192: /* bits */
12927 + nc = 6;
12928 + break;
12929 + case 16: /* bytes */
12930 + case 128: /* bits */
12931 + default:
12932 + nc = 4;
12933 + break;
12934 + }
12935 +}
12936 +
12937 +#endif
12938 +
12939 +// Initialise the key schedule from the user supplied key. The key
12940 +// length is now specified in bytes - 16, 24 or 32 as appropriate.
12941 +// This corresponds to bit lengths of 128, 192 and 256 bits, and
12942 +// to Nk values of 4, 6 and 8 respectively.
12943 +
12944 +#define mx(t,f) (*t++ = inv_mcol(*f),f++)
12945 +#define cp(t,f) *t++ = *f++
12946 +
12947 +#if AES_BLOCK_SIZE == 16
12948 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12949 +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12950 +#elif AES_BLOCK_SIZE == 24
12951 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12952 + cp(d,s); cp(d,s)
12953 +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12954 + mx(d,s); mx(d,s)
12955 +#elif AES_BLOCK_SIZE == 32
12956 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
12957 + cp(d,s); cp(d,s); cp(d,s); cp(d,s)
12958 +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
12959 + mx(d,s); mx(d,s); mx(d,s); mx(d,s)
12960 +#else
12961 +
12962 +#define cpy(d,s) \
12963 +switch(nc) \
12964 +{ case 8: cp(d,s); cp(d,s); \
12965 + case 6: cp(d,s); cp(d,s); \
12966 + case 4: cp(d,s); cp(d,s); \
12967 + cp(d,s); cp(d,s); \
12968 +}
12969 +
12970 +#define mix(d,s) \
12971 +switch(nc) \
12972 +{ case 8: mx(d,s); mx(d,s); \
12973 + case 6: mx(d,s); mx(d,s); \
12974 + case 4: mx(d,s); mx(d,s); \
12975 + mx(d,s); mx(d,s); \
12976 +}
12977 +
12978 +#endif
12979 +
12980 +void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
12981 +{ u_int32_t *kf, *kt, rci;
12982 +
12983 +#if !defined(FIXED_TABLES)
12984 + if(!tab_gen) { gen_tabs(); tab_gen = 1; }
12985 +#endif
12986 +
12987 + switch(n_bytes) {
12988 + case 32: /* bytes */
12989 + case 256: /* bits */
12990 + cx->aes_Nkey = 8;
12991 + break;
12992 + case 24: /* bytes */
12993 + case 192: /* bits */
12994 + cx->aes_Nkey = 6;
12995 + break;
12996 + case 16: /* bytes */
12997 + case 128: /* bits */
12998 + default:
12999 + cx->aes_Nkey = 4;
13000 + break;
13001 + }
13002 +
13003 + cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
13004 +
13005 + cx->aes_e_key[0] = const_word_in(in_key );
13006 + cx->aes_e_key[1] = const_word_in(in_key + 4);
13007 + cx->aes_e_key[2] = const_word_in(in_key + 8);
13008 + cx->aes_e_key[3] = const_word_in(in_key + 12);
13009 +
13010 + kf = cx->aes_e_key;
13011 + kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
13012 + rci = 0;
13013 +
13014 + switch(cx->aes_Nkey)
13015 + {
13016 + case 4: do
13017 + { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
13018 + kf[5] = kf[1] ^ kf[4];
13019 + kf[6] = kf[2] ^ kf[5];
13020 + kf[7] = kf[3] ^ kf[6];
13021 + kf += 4;
13022 + }
13023 + while(kf < kt);
13024 + break;
13025 +
13026 + case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
13027 + cx->aes_e_key[5] = const_word_in(in_key + 20);
13028 + do
13029 + { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
13030 + kf[ 7] = kf[1] ^ kf[ 6];
13031 + kf[ 8] = kf[2] ^ kf[ 7];
13032 + kf[ 9] = kf[3] ^ kf[ 8];
13033 + kf[10] = kf[4] ^ kf[ 9];
13034 + kf[11] = kf[5] ^ kf[10];
13035 + kf += 6;
13036 + }
13037 + while(kf < kt);
13038 + break;
13039 +
13040 + case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
13041 + cx->aes_e_key[5] = const_word_in(in_key + 20);
13042 + cx->aes_e_key[6] = const_word_in(in_key + 24);
13043 + cx->aes_e_key[7] = const_word_in(in_key + 28);
13044 + do
13045 + { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
13046 + kf[ 9] = kf[1] ^ kf[ 8];
13047 + kf[10] = kf[2] ^ kf[ 9];
13048 + kf[11] = kf[3] ^ kf[10];
13049 + kf[12] = kf[4] ^ ls_box(kf[11],0);
13050 + kf[13] = kf[5] ^ kf[12];
13051 + kf[14] = kf[6] ^ kf[13];
13052 + kf[15] = kf[7] ^ kf[14];
13053 + kf += 8;
13054 + }
13055 + while (kf < kt);
13056 + break;
13057 + }
13058 +
13059 + if(!f)
13060 + { u_int32_t i;
13061 +
13062 + kt = cx->aes_d_key + nc * cx->aes_Nrnd;
13063 + kf = cx->aes_e_key;
13064 +
13065 + cpy(kt, kf); kt -= 2 * nc;
13066 +
13067 + for(i = 1; i < cx->aes_Nrnd; ++i)
13068 + {
13069 +#if defined(ONE_TABLE) || defined(FOUR_TABLES)
13070 +#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
13071 + u_int32_t f2, f4, f8, f9;
13072 +#endif
13073 + mix(kt, kf);
13074 +#else
13075 + cpy(kt, kf);
13076 +#endif
13077 + kt -= 2 * nc;
13078 + }
13079 +
13080 + cpy(kt, kf);
13081 + }
13082 +}
13083 +
13084 +// y = output word, x = input word, r = row, c = column
13085 +// for r = 0, 1, 2 and 3 = column accessed for row r
13086 +
13087 +#if defined(ARRAYS)
13088 +#define s(x,c) x[c]
13089 +#else
13090 +#define s(x,c) x##c
13091 +#endif
13092 +
13093 +// I am grateful to Frank Yellin for the following constructions
13094 +// which, given the column (c) of the output state variable that
13095 +// is being computed, return the input state variables which are
13096 +// needed for each row (r) of the state
13097 +
13098 +// For the fixed block size options, compilers reduce these two
13099 +// expressions to fixed variable references. For variable block
13100 +// size code conditional clauses will sometimes be returned
13101 +
13102 +#define unused 77 // Sunset Strip
13103 +
13104 +#define fwd_var(x,r,c) \
13105 + ( r==0 ? \
13106 + ( c==0 ? s(x,0) \
13107 + : c==1 ? s(x,1) \
13108 + : c==2 ? s(x,2) \
13109 + : c==3 ? s(x,3) \
13110 + : c==4 ? s(x,4) \
13111 + : c==5 ? s(x,5) \
13112 + : c==6 ? s(x,6) \
13113 + : s(x,7)) \
13114 + : r==1 ? \
13115 + ( c==0 ? s(x,1) \
13116 + : c==1 ? s(x,2) \
13117 + : c==2 ? s(x,3) \
13118 + : c==3 ? nc==4 ? s(x,0) : s(x,4) \
13119 + : c==4 ? s(x,5) \
13120 + : c==5 ? nc==8 ? s(x,6) : s(x,0) \
13121 + : c==6 ? s(x,7) \
13122 + : s(x,0)) \
13123 + : r==2 ? \
13124 + ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
13125 + : c==1 ? nc==8 ? s(x,4) : s(x,3) \
13126 + : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
13127 + : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
13128 + : c==4 ? nc==8 ? s(x,7) : s(x,0) \
13129 + : c==5 ? nc==8 ? s(x,0) : s(x,1) \
13130 + : c==6 ? s(x,1) \
13131 + : s(x,2)) \
13132 + : \
13133 + ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
13134 + : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
13135 + : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
13136 + : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
13137 + : c==4 ? nc==8 ? s(x,0) : s(x,1) \
13138 + : c==5 ? nc==8 ? s(x,1) : s(x,2) \
13139 + : c==6 ? s(x,2) \
13140 + : s(x,3)))
13141 +
13142 +#define inv_var(x,r,c) \
13143 + ( r==0 ? \
13144 + ( c==0 ? s(x,0) \
13145 + : c==1 ? s(x,1) \
13146 + : c==2 ? s(x,2) \
13147 + : c==3 ? s(x,3) \
13148 + : c==4 ? s(x,4) \
13149 + : c==5 ? s(x,5) \
13150 + : c==6 ? s(x,6) \
13151 + : s(x,7)) \
13152 + : r==1 ? \
13153 + ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
13154 + : c==1 ? s(x,0) \
13155 + : c==2 ? s(x,1) \
13156 + : c==3 ? s(x,2) \
13157 + : c==4 ? s(x,3) \
13158 + : c==5 ? s(x,4) \
13159 + : c==6 ? s(x,5) \
13160 + : s(x,6)) \
13161 + : r==2 ? \
13162 + ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
13163 + : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
13164 + : c==2 ? nc==8 ? s(x,7) : s(x,0) \
13165 + : c==3 ? nc==8 ? s(x,0) : s(x,1) \
13166 + : c==4 ? nc==8 ? s(x,1) : s(x,2) \
13167 + : c==5 ? nc==8 ? s(x,2) : s(x,3) \
13168 + : c==6 ? s(x,3) \
13169 + : s(x,4)) \
13170 + : \
13171 + ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
13172 + : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
13173 + : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
13174 + : c==3 ? nc==8 ? s(x,7) : s(x,0) \
13175 + : c==4 ? nc==8 ? s(x,0) : s(x,1) \
13176 + : c==5 ? nc==8 ? s(x,1) : s(x,2) \
13177 + : c==6 ? s(x,2) \
13178 + : s(x,3)))
13179 +
13180 +#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
13181 +#define so(y,x,c) word_out(y + 4 * c, s(x,c))
13182 +
13183 +#if defined(FOUR_TABLES)
13184 +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
13185 +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
13186 +#elif defined(ONE_TABLE)
13187 +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
13188 +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
13189 +#else
13190 +#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
13191 +#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
13192 +#endif
13193 +
13194 +#if defined(FOUR_LR_TABLES)
13195 +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
13196 +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
13197 +#elif defined(ONE_LR_TABLE)
13198 +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
13199 +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
13200 +#else
13201 +#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
13202 +#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
13203 +#endif
13204 +
13205 +#if AES_BLOCK_SIZE == 16
13206 +
13207 +#if defined(ARRAYS)
13208 +#define locals(y,x) x[4],y[4]
13209 +#else
13210 +#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
13211 +// the following defines prevent the compiler requiring the declaration
13212 +// of generated but unused variables in the fwd_var and inv_var macros
13213 +#define b04 unused
13214 +#define b05 unused
13215 +#define b06 unused
13216 +#define b07 unused
13217 +#define b14 unused
13218 +#define b15 unused
13219 +#define b16 unused
13220 +#define b17 unused
13221 +#endif
13222 +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13223 + s(y,2) = s(x,2); s(y,3) = s(x,3);
13224 +#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)
13225 +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
13226 +#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)
13227 +
13228 +#elif AES_BLOCK_SIZE == 24
13229 +
13230 +#if defined(ARRAYS)
13231 +#define locals(y,x) x[6],y[6]
13232 +#else
13233 +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
13234 + y##0,y##1,y##2,y##3,y##4,y##5
13235 +#define b06 unused
13236 +#define b07 unused
13237 +#define b16 unused
13238 +#define b17 unused
13239 +#endif
13240 +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13241 + s(y,2) = s(x,2); s(y,3) = s(x,3); \
13242 + s(y,4) = s(x,4); s(y,5) = s(x,5);
13243 +#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
13244 + si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
13245 +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
13246 + so(y,x,3); so(y,x,4); so(y,x,5)
13247 +#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
13248 + rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
13249 +#else
13250 +
13251 +#if defined(ARRAYS)
13252 +#define locals(y,x) x[8],y[8]
13253 +#else
13254 +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
13255 + y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
13256 +#endif
13257 +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
13258 + s(y,2) = s(x,2); s(y,3) = s(x,3); \
13259 + s(y,4) = s(x,4); s(y,5) = s(x,5); \
13260 + s(y,6) = s(x,6); s(y,7) = s(x,7);
13261 +
13262 +#if AES_BLOCK_SIZE == 32
13263 +
13264 +#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); \
13265 + si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
13266 +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
13267 + so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
13268 +#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); \
13269 + rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
13270 +#else
13271 +
13272 +#define state_in(y,x,k) \
13273 +switch(nc) \
13274 +{ case 8: si(y,x,k,7); si(y,x,k,6); \
13275 + case 6: si(y,x,k,5); si(y,x,k,4); \
13276 + case 4: si(y,x,k,3); si(y,x,k,2); \
13277 + si(y,x,k,1); si(y,x,k,0); \
13278 +}
13279 +
13280 +#define state_out(y,x) \
13281 +switch(nc) \
13282 +{ case 8: so(y,x,7); so(y,x,6); \
13283 + case 6: so(y,x,5); so(y,x,4); \
13284 + case 4: so(y,x,3); so(y,x,2); \
13285 + so(y,x,1); so(y,x,0); \
13286 +}
13287 +
13288 +#if defined(FAST_VARIABLE)
13289 +
13290 +#define round(rm,y,x,k) \
13291 +switch(nc) \
13292 +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13293 + rm(y,x,k,5); rm(y,x,k,4); \
13294 + rm(y,x,k,3); rm(y,x,k,2); \
13295 + rm(y,x,k,1); rm(y,x,k,0); \
13296 + break; \
13297 + case 6: rm(y,x,k,5); rm(y,x,k,4); \
13298 + rm(y,x,k,3); rm(y,x,k,2); \
13299 + rm(y,x,k,1); rm(y,x,k,0); \
13300 + break; \
13301 + case 4: rm(y,x,k,3); rm(y,x,k,2); \
13302 + rm(y,x,k,1); rm(y,x,k,0); \
13303 + break; \
13304 +}
13305 +#else
13306 +
13307 +#define round(rm,y,x,k) \
13308 +switch(nc) \
13309 +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
13310 + case 6: rm(y,x,k,5); rm(y,x,k,4); \
13311 + case 4: rm(y,x,k,3); rm(y,x,k,2); \
13312 + rm(y,x,k,1); rm(y,x,k,0); \
13313 +}
13314 +
13315 +#endif
13316 +
13317 +#endif
13318 +#endif
13319 +
13320 +void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13321 +{ u_int32_t locals(b0, b1);
13322 + const u_int32_t *kp = cx->aes_e_key;
13323 +
13324 +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13325 + u_int32_t f2;
13326 +#endif
13327 +
13328 + state_in(b0, in_blk, kp); kp += nc;
13329 +
13330 +#if defined(UNROLL)
13331 +
13332 + switch(cx->aes_Nrnd)
13333 + {
13334 + case 14: round(fwd_rnd, b1, b0, kp );
13335 + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13336 + case 12: round(fwd_rnd, b1, b0, kp );
13337 + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13338 + case 10: round(fwd_rnd, b1, b0, kp );
13339 + round(fwd_rnd, b0, b1, kp + nc);
13340 + round(fwd_rnd, b1, b0, kp + 2 * nc);
13341 + round(fwd_rnd, b0, b1, kp + 3 * nc);
13342 + round(fwd_rnd, b1, b0, kp + 4 * nc);
13343 + round(fwd_rnd, b0, b1, kp + 5 * nc);
13344 + round(fwd_rnd, b1, b0, kp + 6 * nc);
13345 + round(fwd_rnd, b0, b1, kp + 7 * nc);
13346 + round(fwd_rnd, b1, b0, kp + 8 * nc);
13347 + round(fwd_lrnd, b0, b1, kp + 9 * nc);
13348 + }
13349 +
13350 +#elif defined(PARTIAL_UNROLL)
13351 + { u_int32_t rnd;
13352 +
13353 + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13354 + {
13355 + round(fwd_rnd, b1, b0, kp);
13356 + round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
13357 + }
13358 +
13359 + round(fwd_rnd, b1, b0, kp);
13360 + round(fwd_lrnd, b0, b1, kp + nc);
13361 + }
13362 +#else
13363 + { u_int32_t rnd;
13364 +
13365 + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13366 + {
13367 + round(fwd_rnd, b1, b0, kp);
13368 + l_copy(b0, b1); kp += nc;
13369 + }
13370 +
13371 + round(fwd_lrnd, b0, b1, kp);
13372 + }
13373 +#endif
13374 +
13375 + state_out(out_blk, b0);
13376 +}
13377 +
13378 +void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
13379 +{ u_int32_t locals(b0, b1);
13380 + const u_int32_t *kp = cx->aes_d_key;
13381 +
13382 +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
13383 + u_int32_t f2, f4, f8, f9;
13384 +#endif
13385 +
13386 + state_in(b0, in_blk, kp); kp += nc;
13387 +
13388 +#if defined(UNROLL)
13389 +
13390 + switch(cx->aes_Nrnd)
13391 + {
13392 + case 14: round(inv_rnd, b1, b0, kp );
13393 + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13394 + case 12: round(inv_rnd, b1, b0, kp );
13395 + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
13396 + case 10: round(inv_rnd, b1, b0, kp );
13397 + round(inv_rnd, b0, b1, kp + nc);
13398 + round(inv_rnd, b1, b0, kp + 2 * nc);
13399 + round(inv_rnd, b0, b1, kp + 3 * nc);
13400 + round(inv_rnd, b1, b0, kp + 4 * nc);
13401 + round(inv_rnd, b0, b1, kp + 5 * nc);
13402 + round(inv_rnd, b1, b0, kp + 6 * nc);
13403 + round(inv_rnd, b0, b1, kp + 7 * nc);
13404 + round(inv_rnd, b1, b0, kp + 8 * nc);
13405 + round(inv_lrnd, b0, b1, kp + 9 * nc);
13406 + }
13407 +
13408 +#elif defined(PARTIAL_UNROLL)
13409 + { u_int32_t rnd;
13410 +
13411 + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
13412 + {
13413 + round(inv_rnd, b1, b0, kp);
13414 + round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
13415 + }
13416 +
13417 + round(inv_rnd, b1, b0, kp);
13418 + round(inv_lrnd, b0, b1, kp + nc);
13419 + }
13420 +#else
13421 + { u_int32_t rnd;
13422 +
13423 + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
13424 + {
13425 + round(inv_rnd, b1, b0, kp);
13426 + l_copy(b0, b1); kp += nc;
13427 + }
13428 +
13429 + round(inv_lrnd, b0, b1, kp);
13430 + }
13431 +#endif
13432 +
13433 + state_out(out_blk, b0);
13434 +}
13435 --- /dev/null Tue Mar 11 13:02:56 2003
13436 +++ linux/net/ipsec/aes/aes_cbc.c Mon Feb 9 13:51:03 2004
13437 @@ -0,0 +1,46 @@
13438 +/*
13439 +// I retain copyright in this code but I encourage its free use provided
13440 +// that I don't carry any responsibility for the results. I am especially
13441 +// happy to see it used in free and open source software. If you do use
13442 +// it I would appreciate an acknowledgement of its origin in the code or
13443 +// the product that results and I would also appreciate knowing a little
13444 +// about the use to which it is being put. I am grateful to Frank Yellin
13445 +// for some ideas that are used in this implementation.
13446 +//
13447 +// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
13448 +//
13449 +// This is an implementation of the AES encryption algorithm (Rijndael)
13450 +// designed by Joan Daemen and Vincent Rijmen. This version is designed
13451 +// to provide both fixed and dynamic block and key lengths and can also
13452 +// run with either big or little endian internal byte order (see aes.h).
13453 +// It inputs block and key lengths in bytes with the legal values being
13454 +// 16, 24 and 32.
13455 +*
13456 +*/
13457 +
13458 +#ifdef __KERNEL__
13459 +#include <linux/types.h>
13460 +#else
13461 +#include <sys/types.h>
13462 +#endif
13463 +#include "crypto/aes_cbc.h"
13464 +#include "crypto/cbc_generic.h"
13465 +
13466 +/* returns bool success */
13467 +int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
13468 + aes_set_key(aes_ctx, key, keysize, 0);
13469 + return 1;
13470 +}
13471 +CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
13472 +
13473 +
13474 +/*
13475 + * $Log: aes_cbc.c,v $
13476 + * Revision 1.2 2004/07/10 07:48:40 mcr
13477 + * Moved from linux/crypto/ciphers/aes/aes_cbc.c,v
13478 + *
13479 + * Revision 1.1 2004/04/06 02:48:12 mcr
13480 + * pullup of AES cipher from alg-branch.
13481 + *
13482 + *
13483 + */
13484 --- /dev/null Tue Mar 11 13:02:56 2003
13485 +++ linux/net/ipsec/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004
13486 @@ -0,0 +1,67 @@
13487 +#ifdef __KERNEL__
13488 +#include <linux/types.h>
13489 +#include <linux/kernel.h>
13490 +#define DEBUG(x)
13491 +#else
13492 +#include <stdio.h>
13493 +#include <sys/types.h>
13494 +#define DEBUG(x) x
13495 +#endif
13496 +
13497 +#include "crypto/aes.h"
13498 +#include "crypto/aes_xcbc_mac.h"
13499 +
13500 +int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
13501 +{
13502 + int ret=1;
13503 + aes_block kn[3] = {
13504 + { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
13505 + { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
13506 + { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
13507 + };
13508 + aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
13509 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
13510 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
13511 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
13512 + aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
13513 + return ret;
13514 +}
13515 +static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
13516 + int pos=0;
13517 + for (pos=1; pos <= 16; pos++, in++, out++) {
13518 + if (pos <= len)
13519 + *out ^= *in;
13520 + if (pos > len) {
13521 + DEBUG(printf("put 0x80 at pos=%d\n", pos));
13522 + *out ^= 0x80;
13523 + break;
13524 + }
13525 + }
13526 +}
13527 +static void xor_block(aes_block res, const aes_block op) {
13528 + res[0] ^= op[0];
13529 + res[1] ^= op[1];
13530 + res[2] ^= op[2];
13531 + res[3] ^= op[3];
13532 +}
13533 +int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
13534 + int ret=ilen;
13535 + u_int32_t out[4] = { 0, 0, 0, 0 };
13536 + for (; ilen > 16 ; ilen-=16) {
13537 + xor_block(out, (const u_int32_t*) &in[0]);
13538 + aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
13539 + in+=16;
13540 + }
13541 + do_pad_xor((u_int8_t *)&out, in, ilen);
13542 + if (ilen==16) {
13543 + DEBUG(printf("using k3\n"));
13544 + xor_block(out, ctxm->k3);
13545 + }
13546 + else
13547 + {
13548 + DEBUG(printf("using k2\n"));
13549 + xor_block(out, ctxm->k2);
13550 + }
13551 + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
13552 + return ret;
13553 +}
13554 --- /dev/null Tue Mar 11 13:02:56 2003
13555 +++ linux/net/ipsec/aes/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
13556 @@ -0,0 +1,296 @@
13557 +/*
13558 + * ipsec_alg AES cipher stubs
13559 + *
13560 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
13561 + *
13562 + * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13563 + *
13564 + * This program is free software; you can redistribute it and/or modify it
13565 + * under the terms of the GNU General Public License as published by the
13566 + * Free Software Foundation; either version 2 of the License, or (at your
13567 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13568 + *
13569 + * This program is distributed in the hope that it will be useful, but
13570 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13571 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13572 + * for more details.
13573 + *
13574 + * Fixes by:
13575 + * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
13576 + * Fixes list:
13577 + * PK: make XCBC comply with latest draft (keylength)
13578 + *
13579 + */
13580 +#ifndef AUTOCONF_INCLUDED
13581 +#include <linux/config.h>
13582 +#endif
13583 +#include <linux/version.h>
13584 +
13585 +/*
13586 + * special case: ipsec core modular with this static algo inside:
13587 + * must avoid MODULE magic for this file
13588 + */
13589 +#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_AES)
13590 +#undef MODULE
13591 +#endif
13592 +
13593 +#include <linux/module.h>
13594 +#include <linux/init.h>
13595 +
13596 +#include <linux/kernel.h> /* printk() */
13597 +#include <linux/errno.h> /* error codes */
13598 +#include <linux/types.h> /* size_t */
13599 +#include <linux/string.h>
13600 +
13601 +/* Check if __exit is defined, if not null it */
13602 +#ifndef __exit
13603 +#define __exit
13604 +#endif
13605 +
13606 +/* Low freeswan header coupling */
13607 +#include "openswan/ipsec_alg.h"
13608 +#include "crypto/aes_cbc.h"
13609 +
13610 +#define CONFIG_KLIPS_ENC_AES_MAC 1
13611 +
13612 +#define AES_CONTEXT_T aes_context
13613 +static int debug_aes=0;
13614 +static int test_aes=0;
13615 +static int excl_aes=0;
13616 +static int keyminbits=0;
13617 +static int keymaxbits=0;
13618 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13619 +MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
13620 +#ifdef module_param
13621 +module_param(debug_aes,int,0600)
13622 +module_param(test_aes,int,0600)
13623 +module_param(excl_aes,int,0600)
13624 +module_param(keyminbits,int,0600)
13625 +module_param(keymaxbits,int,0600)
13626 +#else
13627 +MODULE_PARM(debug_aes, "i");
13628 +MODULE_PARM(test_aes, "i");
13629 +MODULE_PARM(excl_aes, "i");
13630 +MODULE_PARM(keyminbits, "i");
13631 +MODULE_PARM(keymaxbits, "i");
13632 +#endif
13633 +#endif
13634 +
13635 +#if CONFIG_KLIPS_ENC_AES_MAC
13636 +#include "crypto/aes_xcbc_mac.h"
13637 +
13638 +/*
13639 + * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
13640 + * We use 9 for non-modular algorithm and none for modular, thus
13641 + * forcing user to specify one on module load. -kravietz
13642 + */
13643 +#ifdef MODULE
13644 +static int auth_id=0;
13645 +#else
13646 +static int auth_id=9;
13647 +#endif
13648 +#ifdef module_param
13649 +module_param(auth_id, int, 0600);
13650 +#else
13651 +MODULE_PARM(auth_id, "i");
13652 +#endif
13653 +#endif
13654 +
13655 +#define ESP_AES 12 /* truely _constant_ :) */
13656 +
13657 +/* 128, 192 or 256 */
13658 +#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
13659 +#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
13660 +#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
13661 +
13662 +/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
13663 + * -kravietz
13664 + */
13665 +#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
13666 +#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
13667 +
13668 +static int _aes_set_key(struct ipsec_alg_enc *alg,
13669 + __u8 * key_e, const __u8 * key,
13670 + size_t keysize)
13671 +{
13672 + int ret;
13673 + AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13674 + ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
13675 + if (debug_aes > 0)
13676 + printk(KERN_DEBUG "klips_debug:_aes_set_key:"
13677 + "ret=%d key_e=%p key=%p keysize=%ld\n",
13678 + ret, key_e, key, (unsigned long int) keysize);
13679 + return ret;
13680 +}
13681 +
13682 +static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e,
13683 + __u8 * in, int ilen, const __u8 * iv,
13684 + int encrypt)
13685 +{
13686 + AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
13687 + if (debug_aes > 0)
13688 + printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
13689 + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
13690 + key_e, in, ilen, iv, encrypt);
13691 + return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
13692 +}
13693 +#if CONFIG_KLIPS_ENC_AES_MAC
13694 +static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
13695 + aes_context_mac *ctxm=(aes_context_mac *)key_a;
13696 + return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
13697 +}
13698 +static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
13699 + int ret;
13700 + char hash_buf[16];
13701 + aes_context_mac *ctxm=(aes_context_mac *)key_a;
13702 + ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
13703 + memcpy(hash, hash_buf, hashlen);
13704 + return ret;
13705 +}
13706 +static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
13707 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13708 + ixt_refcnt: ATOMIC_INIT(0),
13709 + ixt_name: "aes_mac",
13710 + ixt_blocksize: ESP_AES_MAC_BLK_LEN,
13711 + ixt_support: {
13712 + ias_exttype: IPSEC_ALG_TYPE_AUTH,
13713 + ias_id: 0,
13714 + ias_keyminbits: ESP_AES_MAC_KEY_SZ*8,
13715 + ias_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
13716 + },
13717 + },
13718 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13719 + ixt_module: THIS_MODULE,
13720 +#endif
13721 + ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
13722 + ixt_a_ctx_size: sizeof(aes_context_mac),
13723 + ixt_a_hmac_set_key: _aes_mac_set_key,
13724 + ixt_a_hmac_hash:_aes_mac_hash,
13725 +};
13726 +#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13727 +static struct ipsec_alg_enc ipsec_alg_AES = {
13728 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
13729 + ixt_refcnt: ATOMIC_INIT(0),
13730 + ixt_name: "aes",
13731 + ixt_blocksize: ESP_AES_CBC_BLK_LEN,
13732 + ixt_support: {
13733 + ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
13734 + ias_id: ESP_AES,
13735 + ias_keyminbits: ESP_AES_KEY_SZ_MIN*8,
13736 + ias_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
13737 + },
13738 + },
13739 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13740 + ixt_module: THIS_MODULE,
13741 +#endif
13742 + ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
13743 + ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
13744 + ixt_e_set_key: _aes_set_key,
13745 + ixt_e_cbc_encrypt:_aes_cbc_encrypt,
13746 +};
13747 +
13748 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13749 +IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
13750 +#else
13751 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
13752 +#endif
13753 +{
13754 + int ret, test_ret;
13755 +
13756 + if (keyminbits)
13757 + ipsec_alg_AES.ixt_common.ixt_support.ias_keyminbits=keyminbits;
13758 + if (keymaxbits) {
13759 + ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits=keymaxbits;
13760 + if (keymaxbits*8>ipsec_alg_AES.ixt_common.ixt_support.ias_keymaxbits)
13761 + ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
13762 + }
13763 + if (excl_aes) ipsec_alg_AES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
13764 + ret=register_ipsec_alg_enc(&ipsec_alg_AES);
13765 + printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13766 + ipsec_alg_AES.ixt_common.ixt_support.ias_exttype,
13767 + ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13768 + ipsec_alg_AES.ixt_common.ixt_name,
13769 + ret);
13770 + if (ret==0 && test_aes) {
13771 + test_ret=ipsec_alg_test(
13772 + ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13773 + ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13774 + test_aes);
13775 + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13776 + ipsec_alg_AES.ixt_common.ixt_support.ias_exttype ,
13777 + ipsec_alg_AES.ixt_common.ixt_support.ias_id,
13778 + test_ret);
13779 + }
13780 +#if CONFIG_KLIPS_ENC_AES_MAC
13781 + if (auth_id!=0){
13782 + int ret;
13783 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id=auth_id;
13784 + ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13785 + printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
13786 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13787 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13788 + ipsec_alg_AES_MAC.ixt_common.ixt_name,
13789 + ret);
13790 + if (ret==0 && test_aes) {
13791 + test_ret=ipsec_alg_test(
13792 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13793 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13794 + test_aes);
13795 + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
13796 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_exttype,
13797 + ipsec_alg_AES_MAC.ixt_common.ixt_support.ias_id,
13798 + test_ret);
13799 + }
13800 + } else {
13801 + printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
13802 + }
13803 +#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13804 + return ret;
13805 +}
13806 +
13807 +#if defined(CONFIG_KLIPS_ENC_AES_MODULE)
13808 +IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
13809 +#else
13810 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
13811 +#endif
13812 +{
13813 +#if CONFIG_KLIPS_ENC_AES_MAC
13814 + if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
13815 +#endif /* CONFIG_KLIPS_ENC_AES_MAC */
13816 + unregister_ipsec_alg_enc(&ipsec_alg_AES);
13817 + return;
13818 +}
13819 +#ifdef MODULE_LICENSE
13820 +MODULE_LICENSE("GPL");
13821 +#endif
13822 +
13823 +#if 0 /* +NOT_YET */
13824 +#ifndef MODULE
13825 +/*
13826 + * This is intended for static module setups, currently
13827 + * doesn't work for modular ipsec.o with static algos inside
13828 + */
13829 +static int setup_keybits(const char *str)
13830 +{
13831 + unsigned aux;
13832 + char *end;
13833 +
13834 + aux = simple_strtoul(str,&end,0);
13835 + if (aux != 128 && aux != 192 && aux != 256)
13836 + return 0;
13837 + keyminbits = aux;
13838 +
13839 + if (*end == 0 || *end != ',')
13840 + return 1;
13841 + str=end+1;
13842 + aux = simple_strtoul(str, NULL, 0);
13843 + if (aux != 128 && aux != 192 && aux != 256)
13844 + return 0;
13845 + if (aux >= keyminbits)
13846 + keymaxbits = aux;
13847 + return 1;
13848 +}
13849 +__setup("ipsec_aes_keybits=", setup_keybits);
13850 +#endif
13851 +#endif
13852 +
13853 --- /dev/null Tue Mar 11 13:02:56 2003
13854 +++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004
13855 @@ -0,0 +1,3 @@
13856 +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13857 + tristate ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES
13858 +fi
13859 --- /dev/null Tue Mar 11 13:02:56 2003
13860 +++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004
13861 @@ -0,0 +1,6 @@
13862 +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
13863 + dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
13864 + if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
13865 + bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
13866 + fi
13867 +fi
13868 --- /dev/null Tue Mar 11 13:02:56 2003
13869 +++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004
13870 @@ -0,0 +1,3 @@
13871 +#Placeholder
13872 +source net/ipsec/alg/Config.alg_aes.in
13873 +source net/ipsec/alg/Config.alg_cryptoapi.in
13874 --- /dev/null Tue Mar 11 13:02:56 2003
13875 +++ linux/net/ipsec/alg/Makefile Mon Feb 9 13:51:03 2004
13876 @@ -0,0 +1,112 @@
13877 +# Makefile,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
13878 +ifeq ($(strip $(KLIPSMODULE)),)
13879 +FREESWANSRCDIR=.
13880 +else
13881 +FREESWANSRCDIR=../../../..
13882 +endif
13883 +ifeq ($(strip $(KLIPS_TOP)),)
13884 +KLIPS_TOP=../../..
13885 +override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include
13886 +endif
13887 +
13888 +ifeq ($(CONFIG_IPSEC_DEBUG),y)
13889 +override EXTRA_CFLAGS += -g
13890 +endif
13891 +
13892 +# LIBCRYPTO normally comes as an argument from "parent" Makefile
13893 +# (this applies both to FS' "make module" and eg. Linux' "make modules"
13894 +# But make dep doest follow same evaluations, so we need this default:
13895 +LIBCRYPTO=$(TOPDIR)/lib/libcrypto
13896 +
13897 +override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include
13898 +override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes
13899 +
13900 +MOD_LIST_NAME := NET_MISC_MODULES
13901 +
13902 +#O_TARGET := static_init.o
13903 +
13904 +subdir- :=
13905 +subdir-n :=
13906 +subdir-y :=
13907 +subdir-m :=
13908 +
13909 +obj-y := static_init.o
13910 +
13911 +ARCH_ASM-y :=
13912 +ARCH_ASM-$(CONFIG_M586) := i586
13913 +ARCH_ASM-$(CONFIG_M586TSC) := i586
13914 +ARCH_ASM-$(CONFIG_M586MMX) := i586
13915 +ARCH_ASM-$(CONFIG_MK6) := i586
13916 +ARCH_ASM-$(CONFIG_M686) := i686
13917 +ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686
13918 +ARCH_ASM-$(CONFIG_MPENTIUM4) := i686
13919 +ARCH_ASM-$(CONFIG_MK7) := i686
13920 +ARCH_ASM-$(CONFIG_MCRUSOE) := i586
13921 +ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586
13922 +ARCH_ASM-$(CONFIG_MWINCHIP2) := i586
13923 +ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586
13924 +ARCH_ASM-$(CONFIG_USERMODE) := i586
13925 +
13926 +ARCH_ASM :=$(ARCH_ASM-y)
13927 +ifdef NO_ASM
13928 +ARCH_ASM :=
13929 +endif
13930 +
13931 +# The algorithm makefiles may put dependences, short-circuit them
13932 +null:
13933 +
13934 +makefiles=$(filter-out %.preipsec, $(wildcard Makefile.alg_*))
13935 +ifneq ($(makefiles),)
13936 +#include Makefile.alg_aes
13937 +#include Makefile.alg_aes-opt
13938 +include $(makefiles)
13939 +endif
13940 +
13941 +# These rules translate from new to old makefile rules
13942 +# Translate to Rules.make lists.
13943 +multi-used := $(filter $(list-multi), $(obj-y) $(obj-m))
13944 +multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs))
13945 +active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m))
13946 +O_OBJS := $(obj-y)
13947 +M_OBJS := $(obj-m)
13948 +MIX_OBJS := $(filter $(export-objs), $(active-objs))
13949 +#OX_OBJS := $(export-objs)
13950 +SUB_DIRS := $(subdir-y)
13951 +ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
13952 +MOD_SUB_DIRS := $(subdir-m)
13953 +
13954 +
13955 +static_init_mod.o: $(obj-y)
13956 + rm -f $@
13957 + $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@
13958 +
13959 +perlasm: ../../../crypto/ciphers/des/asm/perlasm
13960 + ln -sf $? $@
13961 +
13962 +$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
13963 +$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
13964 +
13965 +
13966 +all_alg_modules: perlasm $(ALG_MODULES)
13967 + @echo "ALG_MODULES=$(ALG_MODULES)"
13968 +
13969 +
13970 +#
13971 +# Construct alg. init. function: call ipsec_ALGO_init() for every static algo
13972 +# Needed when there are static algos (with static or modular ipsec.o)
13973 +#
13974 +static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh
13975 + @echo "Re-creating $@"
13976 + $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@
13977 +
13978 +clean:
13979 + @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0
13980 + @find . -type l -exec rm -f {} \;
13981 + -rm -f perlasm
13982 + -rm -rf $(ALG_SUBDIRS)
13983 + -rm -f *.o static_init.c
13984 +
13985 +ifdef TOPDIR
13986 +include $(TOPDIR)/Rules.make
13987 +endif
13988 +
13989 --- /dev/null Tue Mar 11 13:02:56 2003
13990 +++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004
13991 @@ -0,0 +1,18 @@
13992 +MOD_AES := ipsec_aes.o
13993 +
13994 +ALG_MODULES += $(MOD_AES)
13995 +ALG_SUBDIRS += libaes
13996 +
13997 +obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
13998 +static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
13999 +alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
14000 +
14001 +AES_OBJS := ipsec_alg_aes.o $(LIBCRYPTO)/libaes/libaes.a
14002 +
14003 +
14004 +$(MOD_AES): $(AES_OBJS)
14005 + $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
14006 +
14007 +$(LIBCRYPTO)/libaes/libaes.a:
14008 + $(MAKE) -C $(LIBCRYPTO)/libaes CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a
14009 +
14010 --- /dev/null Tue Mar 11 13:02:56 2003
14011 +++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004
14012 @@ -0,0 +1,14 @@
14013 +MOD_CRYPTOAPI := ipsec_cryptoapi.o
14014 +
14015 +ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
14016 +ALG_MODULES += $(MOD_CRYPTOAPI)
14017 +obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
14018 +static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
14019 +alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
14020 +else
14021 +$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
14022 +endif
14023 +
14024 +CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
14025 +$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
14026 + $(LD) -r $(CRYPTOAPI_OBJS) -o $@
14027 --- /dev/null Tue Mar 11 13:02:56 2003
14028 +++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
14029 @@ -0,0 +1,442 @@
14030 +/*
14031 + * ipsec_alg to linux cryptoapi GLUE
14032 + *
14033 + * Authors: CODE.ar TEAM
14034 + * Harpo MAxx <harpo@linuxmendoza.org.ar>
14035 + * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
14036 + * Luciano Ruete <docemeses@softhome.net>
14037 + *
14038 + * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
14039 + *
14040 + * This program is free software; you can redistribute it and/or modify it
14041 + * under the terms of the GNU General Public License as published by the
14042 + * Free Software Foundation; either version 2 of the License, or (at your
14043 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
14044 + *
14045 + * This program is distributed in the hope that it will be useful, but
14046 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14047 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14048 + * for more details.
14049 + *
14050 + * Example usage:
14051 + * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
14052 + * modprobe ipsec_cryptoapi
14053 + * modprobe ipsec_cryptoapi test=1
14054 + * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
14055 + * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
14056 + * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
14057 + * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
14058 + */
14059 +#ifndef AUTOCONF_INCLUDED
14060 +#include <linux/config.h>
14061 +#endif
14062 +#include <linux/version.h>
14063 +
14064 +/*
14065 + * special case: ipsec core modular with this static algo inside:
14066 + * must avoid MODULE magic for this file
14067 + */
14068 +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
14069 +#undef MODULE
14070 +#endif
14071 +
14072 +#include <linux/module.h>
14073 +#include <linux/init.h>
14074 +
14075 +#include <linux/kernel.h> /* printk() */
14076 +#include <linux/errno.h> /* error codes */
14077 +#include <linux/types.h> /* size_t */
14078 +#include <linux/string.h>
14079 +
14080 +/* Check if __exit is defined, if not null it */
14081 +#ifndef __exit
14082 +#define __exit
14083 +#endif
14084 +
14085 +/* warn the innocent */
14086 +#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
14087 +#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
14088 +#define NO_CRYPTOAPI_SUPPORT
14089 +#endif
14090 +/* Low freeswan header coupling */
14091 +#include "openswan/ipsec_alg.h"
14092 +
14093 +#include <linux/crypto.h>
14094 +#ifdef CRYPTO_API_VERSION_CODE
14095 +#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
14096 +#define NO_CRYPTOAPI_SUPPORT
14097 +#endif
14098 +
14099 +#ifdef NO_CRYPTOAPI_SUPPORT
14100 +#warning "Building an unusable module :P"
14101 +/* Catch old CryptoAPI by not allowing module to load */
14102 +IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
14103 +{
14104 + printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
14105 + return -EINVAL;
14106 +}
14107 +#else
14108 +#include <asm/scatterlist.h>
14109 +#include <asm/pgtable.h>
14110 +#include <linux/mm.h>
14111 +
14112 +#define CIPHERNAME_AES "aes"
14113 +#define CIPHERNAME_3DES "des3_ede"
14114 +#define CIPHERNAME_BLOWFISH "blowfish"
14115 +#define CIPHERNAME_CAST "cast5"
14116 +#define CIPHERNAME_SERPENT "serpent"
14117 +#define CIPHERNAME_TWOFISH "twofish"
14118 +
14119 +#define ESP_3DES 3
14120 +#define ESP_AES 12
14121 +#define ESP_BLOWFISH 7 /* truely _constant_ :) */
14122 +#define ESP_CAST 6 /* quite constant :) */
14123 +#define ESP_SERPENT 252 /* from ipsec drafts */
14124 +#define ESP_TWOFISH 253 /* from ipsec drafts */
14125 +
14126 +#define AH_MD5 2
14127 +#define AH_SHA 3
14128 +#define DIGESTNAME_MD5 "md5"
14129 +#define DIGESTNAME_SHA1 "sha1"
14130 +
14131 +MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
14132 +static int debug=0;
14133 +static int test=0;
14134 +static int excl=0;
14135 +static int noauto = 0;
14136 +
14137 +static int des_ede3[] = {-1, -1};
14138 +static int aes[] = {-1, -1};
14139 +static int blowfish[] = {-1, -1};
14140 +static int cast[] = {-1, -1};
14141 +static int serpent[] = {-1, -1};
14142 +static int twofish[] = {-1, -1};
14143 +
14144 +#ifdef module_param
14145 +module_param(debug,int,0600);
14146 +module_param(test,int,0600);
14147 +module_param(ebug,int,0600);
14148 +
14149 +module_param(noauto,int,0600);
14150 +module_param(ebug,int,0600);
14151 +
14152 +module_param_array(des_ede3,int,NULL,0);
14153 +module_param(aes,int,NULL,0);
14154 +module_param(blowfish,int,NULL,0);
14155 +module_param(cast,int,NULL,0);
14156 +module_param(serpent,int,NULL,0);
14157 +module_param(twofish,int,NULL,0);
14158 +#else
14159 +MODULE_PARM(debug, "i");
14160 +MODULE_PARM(test, "i");
14161 +MODULE_PARM(excl, "i");
14162 +
14163 +MODULE_PARM(noauto,"i");
14164 +
14165 +MODULE_PARM(des_ede3,"1-2i");
14166 +MODULE_PARM(aes,"1-2i");
14167 +MODULE_PARM(blowfish,"1-2i");
14168 +MODULE_PARM(cast,"1-2i");
14169 +MODULE_PARM(serpent,"1-2i");
14170 +MODULE_PARM(twofish,"1-2i");
14171 +#endif
14172 +
14173 +MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
14174 +
14175 +MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
14176 +MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
14177 +MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
14178 +MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
14179 +MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
14180 +MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
14181 +
14182 +struct ipsec_alg_capi_cipher {
14183 + const char *ciphername; /* cryptoapi's ciphername */
14184 + unsigned blocksize;
14185 + unsigned short minbits;
14186 + unsigned short maxbits;
14187 + int *parm; /* lkm param for this cipher */
14188 + struct ipsec_alg_enc alg; /* note it's not a pointer */
14189 +};
14190 +static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
14191 + { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
14192 + { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
14193 + { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
14194 + { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
14195 + { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
14196 + { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
14197 + { NULL, 0, 0, 0, NULL, {} }
14198 +};
14199 +#ifdef NOT_YET
14200 +struct ipsec_alg_capi_digest {
14201 + const char *digestname; /* cryptoapi's digestname */
14202 + struct digest_implementation *di;
14203 + struct ipsec_alg_auth alg; /* note it's not a pointer */
14204 +};
14205 +static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
14206 + { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
14207 + { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
14208 + { NULL, NULL, {} }
14209 +};
14210 +#endif
14211 +/*
14212 + * "generic" linux cryptoapi setup_cipher() function
14213 + */
14214 +int setup_cipher(const char *ciphername)
14215 +{
14216 + return crypto_alg_available(ciphername, 0);
14217 +}
14218 +
14219 +/*
14220 + * setups ipsec_alg_capi_cipher "hyper" struct components, calling
14221 + * register_ipsec_alg for cointaned ipsec_alg object
14222 + */
14223 +static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
14224 +static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
14225 +static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
14226 +
14227 +static int
14228 +setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
14229 +{
14230 + int ret;
14231 + cptr->alg.ixt_version = IPSEC_ALG_VERSION;
14232 + cptr->alg.ixt_module = THIS_MODULE;
14233 + atomic_set (& cptr->alg.ixt_refcnt, 0);
14234 + strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
14235 +
14236 + cptr->alg.ixt_blocksize=cptr->blocksize;
14237 + cptr->alg.ixt_keyminbits=cptr->minbits;
14238 + cptr->alg.ixt_keymaxbits=cptr->maxbits;
14239 + cptr->alg.ixt_state = 0;
14240 + if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
14241 + cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
14242 + cptr->alg.ixt_e_ctx_size = 0;
14243 + cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
14244 + cptr->alg.ixt_e_new_key = _capi_new_key;
14245 + cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
14246 + cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
14247 + cptr->alg.ixt_data = cptr;
14248 +
14249 + ret=register_ipsec_alg_enc(&cptr->alg);
14250 + printk("setup_ipsec_alg_capi_cipher(): "
14251 + "alg_type=%d alg_id=%d name=%s "
14252 + "keyminbits=%d keymaxbits=%d, ret=%d\n",
14253 + cptr->alg.ixt_alg_type,
14254 + cptr->alg.ixt_alg_id,
14255 + cptr->alg.ixt_name,
14256 + cptr->alg.ixt_keyminbits,
14257 + cptr->alg.ixt_keymaxbits,
14258 + ret);
14259 + return ret;
14260 +}
14261 +/*
14262 + * called in ipsec_sa_wipe() time, will destroy key contexts
14263 + * and do 1 unbind()
14264 + */
14265 +static void
14266 +_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
14267 +{
14268 + struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
14269 +
14270 + if (debug > 0)
14271 + printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
14272 + "name=%s key_e=%p \n",
14273 + alg->ixt_name, key_e);
14274 + if (!key_e) {
14275 + printk(KERN_ERR "klips_debug: _capi_destroy_key:"
14276 + "name=%s NULL key_e!\n",
14277 + alg->ixt_name);
14278 + return;
14279 + }
14280 + crypto_free_tfm(tfm);
14281 +}
14282 +
14283 +/*
14284 + * create new key context, need alg->ixt_data to know which
14285 + * (of many) cipher inside this module is the target
14286 + */
14287 +static __u8 *
14288 +_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
14289 +{
14290 + struct ipsec_alg_capi_cipher *cptr;
14291 + struct crypto_tfm *tfm=NULL;
14292 +
14293 + cptr = alg->ixt_data;
14294 + if (!cptr) {
14295 + printk(KERN_ERR "_capi_new_key(): "
14296 + "NULL ixt_data (?!) for \"%s\" algo\n"
14297 + , alg->ixt_name);
14298 + goto err;
14299 + }
14300 + if (debug > 0)
14301 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
14302 + "name=%s cptr=%p key=%p keysize=%d\n",
14303 + alg->ixt_name, cptr, key, keylen);
14304 +
14305 + /*
14306 + * alloc tfm
14307 + */
14308 + tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
14309 + if (!tfm) {
14310 + printk(KERN_ERR "_capi_new_key(): "
14311 + "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
14312 + , alg->ixt_name, cptr->ciphername);
14313 + goto err;
14314 + }
14315 + if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
14316 + printk(KERN_ERR "_capi_new_key(): "
14317 + "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
14318 + , alg->ixt_name, keylen);
14319 + crypto_free_tfm(tfm);
14320 + tfm=NULL;
14321 + }
14322 +err:
14323 + if (debug > 0)
14324 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
14325 + "name=%s key=%p keylen=%d tfm=%p\n",
14326 + alg->ixt_name, key, keylen, tfm);
14327 + return (__u8 *) tfm;
14328 +}
14329 +/*
14330 + * core encryption function: will use cx->ci to call actual cipher's
14331 + * cbc function
14332 + */
14333 +static int
14334 +_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
14335 + int error =0;
14336 + struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
14337 + struct scatterlist sg = {
14338 + .page = virt_to_page(in),
14339 + .offset = (unsigned long)(in) % PAGE_SIZE,
14340 + .length=ilen,
14341 + };
14342 + if (debug > 1)
14343 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
14344 + "key_e=%p "
14345 + "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
14346 + , key_e
14347 + , in, in, ilen, iv, encrypt);
14348 + crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
14349 + if (encrypt)
14350 + error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
14351 + else
14352 + error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
14353 + if (debug > 1)
14354 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
14355 + "error=%d\n"
14356 + , error);
14357 + return (error<0)? error : ilen;
14358 +}
14359 +/*
14360 + * main initialization loop: for each cipher in list, do
14361 + * 1) setup cryptoapi cipher else continue
14362 + * 2) register ipsec_alg object
14363 + */
14364 +static int
14365 +setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
14366 +{
14367 + struct ipsec_alg_capi_cipher *cptr;
14368 + /* foreach cipher in list ... */
14369 + for (cptr=clist;cptr->ciphername;cptr++) {
14370 + /*
14371 + * see if cipher has been disabled (0) or
14372 + * if noauto set and not enabled (1)
14373 + */
14374 + if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
14375 + if (debug>0)
14376 + printk(KERN_INFO "setup_cipher_list(): "
14377 + "ciphername=%s skipped at user request: "
14378 + "noauto=%d parm[0]=%d parm[1]=%d\n"
14379 + , cptr->ciphername
14380 + , noauto
14381 + , cptr->parm[0]
14382 + , cptr->parm[1]);
14383 + continue;
14384 + }
14385 + /*
14386 + * use a local ci to avoid touching cptr->ci,
14387 + * if register ipsec_alg success then bind cipher
14388 + */
14389 + if( setup_cipher(cptr->ciphername) ) {
14390 + if (debug > 0)
14391 + printk(KERN_DEBUG "klips_debug:"
14392 + "setup_cipher_list():"
14393 + "ciphername=%s found\n"
14394 + , cptr->ciphername);
14395 + if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
14396 +
14397 +
14398 + } else {
14399 + printk(KERN_ERR "klips_debug:"
14400 + "setup_cipher_list():"
14401 + "ciphername=%s failed ipsec_alg_register\n"
14402 + , cptr->ciphername);
14403 + }
14404 + } else {
14405 + if (debug>0)
14406 + printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
14407 + cptr->ciphername);
14408 + }
14409 + }
14410 + return 0;
14411 +}
14412 +/*
14413 + * deregister ipsec_alg objects and unbind ciphers
14414 + */
14415 +static int
14416 +unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
14417 +{
14418 + struct ipsec_alg_capi_cipher *cptr;
14419 + /* foreach cipher in list ... */
14420 + for (cptr=clist;cptr->ciphername;cptr++) {
14421 + if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14422 + unregister_ipsec_alg_enc(&cptr->alg);
14423 + }
14424 + }
14425 + return 0;
14426 +}
14427 +/*
14428 + * test loop for registered algos
14429 + */
14430 +static int
14431 +test_cipher_list (struct ipsec_alg_capi_cipher* clist)
14432 +{
14433 + int test_ret;
14434 + struct ipsec_alg_capi_cipher *cptr;
14435 + /* foreach cipher in list ... */
14436 + for (cptr=clist;cptr->ciphername;cptr++) {
14437 + if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
14438 + test_ret=ipsec_alg_test(
14439 + cptr->alg.ixt_alg_type,
14440 + cptr->alg.ixt_alg_id,
14441 + test);
14442 + printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
14443 + cptr->alg.ixt_alg_type,
14444 + cptr->alg.ixt_alg_id,
14445 + test_ret);
14446 + }
14447 + }
14448 + return 0;
14449 +}
14450 +
14451 +IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
14452 +{
14453 + int ret, test_ret;
14454 + if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
14455 + return -EPROTONOSUPPORT;
14456 + if (ret==0 && test) {
14457 + test_ret=test_cipher_list(alg_capi_carray);
14458 + }
14459 + return ret;
14460 +}
14461 +IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
14462 +{
14463 + unsetup_cipher_list(alg_capi_carray);
14464 + return;
14465 +}
14466 +#ifdef MODULE_LICENSE
14467 +MODULE_LICENSE("GPL");
14468 +#endif
14469 +
14470 +EXPORT_NO_SYMBOLS;
14471 +#endif /* NO_CRYPTOAPI_SUPPORT */
14472 --- /dev/null Tue Mar 11 13:02:56 2003
14473 +++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004
14474 @@ -0,0 +1,18 @@
14475 +#!/bin/sh
14476 +cat << EOF
14477 +#include <linux/kernel.h>
14478 +#include <linux/list.h>
14479 +#include "freeswan/ipsec_alg.h"
14480 +$(for i in $*; do
14481 + test -z "$i" && continue
14482 + echo "extern int $i(void);"
14483 +done)
14484 +void ipsec_alg_static_init(void){
14485 + int __attribute__ ((unused)) err=0;
14486 +$(for i in $*; do
14487 + test -z "$i" && continue
14488 + echo " if ((err=$i()) < 0)"
14489 + echo " printk(KERN_WARNING \"$i() returned %d\", err);"
14490 +done)
14491 +}
14492 +EOF
14493 --- /dev/null Tue Mar 11 13:02:56 2003
14494 +++ linux/net/ipsec/anyaddr.c Mon Feb 9 13:51:03 2004
14495 @@ -0,0 +1,148 @@
14496 +/*
14497 + * special addresses
14498 + * Copyright (C) 2000 Henry Spencer.
14499 + *
14500 + * This library is free software; you can redistribute it and/or modify it
14501 + * under the terms of the GNU Library General Public License as published by
14502 + * the Free Software Foundation; either version 2 of the License, or (at your
14503 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14504 + *
14505 + * This library is distributed in the hope that it will be useful, but
14506 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14507 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14508 + * License for more details.
14509 + *
14510 + * RCSID $Id: anyaddr.c,v 1.10.10.1 2006/11/24 05:55:46 paul Exp $
14511 + */
14512 +#include "openswan.h"
14513 +
14514 +/* these are mostly fallbacks for the no-IPv6-support-in-library case */
14515 +#ifndef IN6ADDR_ANY_INIT
14516 +#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
14517 +#endif
14518 +#ifndef IN6ADDR_LOOPBACK_INIT
14519 +#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
14520 +#endif
14521 +
14522 +static struct in6_addr v6any = IN6ADDR_ANY_INIT;
14523 +static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
14524 +
14525 +/*
14526 + - anyaddr - initialize to the any-address value
14527 + */
14528 +err_t /* NULL for success, else string literal */
14529 +anyaddr(af, dst)
14530 +int af; /* address family */
14531 +ip_address *dst;
14532 +{
14533 + uint32_t v4any = htonl(INADDR_ANY);
14534 +
14535 + switch (af) {
14536 + case AF_INET:
14537 + return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
14538 + break;
14539 + case AF_INET6:
14540 + return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
14541 + break;
14542 + default:
14543 + return "unknown address family in anyaddr/unspecaddr";
14544 + break;
14545 + }
14546 +}
14547 +
14548 +/*
14549 + - unspecaddr - initialize to the unspecified-address value
14550 + */
14551 +err_t /* NULL for success, else string literal */
14552 +unspecaddr(af, dst)
14553 +int af; /* address family */
14554 +ip_address *dst;
14555 +{
14556 + return anyaddr(af, dst);
14557 +}
14558 +
14559 +/*
14560 + - loopbackaddr - initialize to the loopback-address value
14561 + */
14562 +err_t /* NULL for success, else string literal */
14563 +loopbackaddr(af, dst)
14564 +int af; /* address family */
14565 +ip_address *dst;
14566 +{
14567 + uint32_t v4loop = htonl(INADDR_LOOPBACK);
14568 +
14569 + switch (af) {
14570 + case AF_INET:
14571 + return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
14572 + break;
14573 + case AF_INET6:
14574 + return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
14575 + break;
14576 + default:
14577 + return "unknown address family in loopbackaddr";
14578 + break;
14579 + }
14580 +}
14581 +
14582 +/*
14583 + - isanyaddr - test for the any-address value
14584 + */
14585 +int
14586 +isanyaddr(src)
14587 +const ip_address *src;
14588 +{
14589 + uint32_t v4any = htonl(INADDR_ANY);
14590 + int cmp;
14591 +
14592 + switch (src->u.v4.sin_family) {
14593 + case AF_INET:
14594 + cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
14595 + break;
14596 + case AF_INET6:
14597 + cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
14598 + break;
14599 + case 0:
14600 + /* a zeroed structure is considered any address */
14601 + return 1;
14602 + default:
14603 + return 0;
14604 + break;
14605 + }
14606 +
14607 + return (cmp == 0) ? 1 : 0;
14608 +}
14609 +
14610 +/*
14611 + - isunspecaddr - test for the unspecified-address value
14612 + */
14613 +int
14614 +isunspecaddr(src)
14615 +const ip_address *src;
14616 +{
14617 + return isanyaddr(src);
14618 +}
14619 +
14620 +/*
14621 + - isloopbackaddr - test for the loopback-address value
14622 + */
14623 +int
14624 +isloopbackaddr(src)
14625 +const ip_address *src;
14626 +{
14627 + uint32_t v4loop = htonl(INADDR_LOOPBACK);
14628 + int cmp;
14629 +
14630 + switch (src->u.v4.sin_family) {
14631 + case AF_INET:
14632 + cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
14633 + break;
14634 + case AF_INET6:
14635 + cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
14636 + break;
14637 + default:
14638 + return 0;
14639 + break;
14640 + }
14641 +
14642 + return (cmp == 0) ? 1 : 0;
14643 +}
14644 --- /dev/null Tue Mar 11 13:02:56 2003
14645 +++ linux/net/ipsec/datatot.c Mon Feb 9 13:51:03 2004
14646 @@ -0,0 +1,234 @@
14647 +/*
14648 + * convert from binary data (e.g. key) to text form
14649 + * Copyright (C) 2000 Henry Spencer.
14650 + *
14651 + * This library is free software; you can redistribute it and/or modify it
14652 + * under the terms of the GNU Library General Public License as published by
14653 + * the Free Software Foundation; either version 2 of the License, or (at your
14654 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
14655 + *
14656 + * This library is distributed in the hope that it will be useful, but
14657 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14658 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14659 + * License for more details.
14660 + *
14661 + * RCSID $Id: datatot.c,v 1.7 2005/04/14 20:48:43 mcr Exp $
14662 + */
14663 +#include "openswan.h"
14664 +
14665 +static void convert(const char *src, size_t nreal, int format, char *out);
14666 +
14667 +/*
14668 + - datatot - convert data bytes to text
14669 + */
14670 +size_t /* true length (with NUL) for success */
14671 +datatot(src, srclen, format, dst, dstlen)
14672 +const char *src;
14673 +size_t srclen;
14674 +int format; /* character indicating what format */
14675 +char *dst; /* need not be valid if dstlen is 0 */
14676 +size_t dstlen;
14677 +{
14678 + size_t inblocksize; /* process this many bytes at a time */
14679 + size_t outblocksize; /* producing this many */
14680 + size_t breakevery; /* add a _ every this many (0 means don't) */
14681 + size_t sincebreak; /* output bytes since last _ */
14682 + char breakchar; /* character used to break between groups */
14683 + char inblock[10]; /* enough for any format */
14684 + char outblock[10]; /* enough for any format */
14685 + char fake[1]; /* fake output area for dstlen == 0 */
14686 + size_t needed; /* return value */
14687 + char *stop; /* where the terminating NUL will go */
14688 + size_t ntodo; /* remaining input */
14689 + size_t nreal;
14690 + char *out;
14691 + char *prefix;
14692 +
14693 + breakevery = 0;
14694 + breakchar = '_';
14695 +
14696 + switch (format) {
14697 + case 0:
14698 + case 'h':
14699 + format = 'x';
14700 + breakevery = 8;
14701 + /* FALLTHROUGH */
14702 + case 'x':
14703 + inblocksize = 1;
14704 + outblocksize = 2;
14705 + prefix = "0x";
14706 + break;
14707 + case ':':
14708 + format = 'x';
14709 + breakevery = 2;
14710 + breakchar = ':';
14711 + /* FALLTHROUGH */
14712 + case 16:
14713 + inblocksize = 1;
14714 + outblocksize = 2;
14715 + prefix = "";
14716 + format = 'x';
14717 + break;
14718 + case 's':
14719 + inblocksize = 3;
14720 + outblocksize = 4;
14721 + prefix = "0s";
14722 + break;
14723 + case 64: /* beware, equals ' ' */
14724 + inblocksize = 3;
14725 + outblocksize = 4;
14726 + prefix = "";
14727 + format = 's';
14728 + break;
14729 + default:
14730 + return 0;
14731 + break;
14732 + }
14733 +
14734 + user_assert(inblocksize < sizeof(inblock));
14735 + user_assert(outblocksize < sizeof(outblock));
14736 + user_assert(breakevery % outblocksize == 0);
14737 +
14738 + if (srclen == 0)
14739 + return 0;
14740 + ntodo = srclen;
14741 +
14742 + if (dstlen == 0) { /* dispose of awkward special case */
14743 + dst = fake;
14744 + dstlen = 1;
14745 + }
14746 + stop = dst + dstlen - 1;
14747 +
14748 + nreal = strlen(prefix);
14749 + needed = nreal; /* for starters */
14750 + if (dstlen <= nreal) { /* prefix won't fit */
14751 + strncpy(dst, prefix, dstlen - 1);
14752 + dst += dstlen - 1;
14753 + } else {
14754 + strcpy(dst, prefix);
14755 + dst += nreal;
14756 + }
14757 +
14758 + user_assert(dst <= stop);
14759 + sincebreak = 0;
14760 +
14761 + while (ntodo > 0) {
14762 + if (ntodo < inblocksize) { /* incomplete input */
14763 + memset(inblock, 0, sizeof(inblock));
14764 + memcpy(inblock, src, ntodo);
14765 + src = inblock;
14766 + nreal = ntodo;
14767 + ntodo = inblocksize;
14768 + } else
14769 + nreal = inblocksize;
14770 + out = (outblocksize > stop - dst) ? outblock : dst;
14771 +
14772 + convert(src, nreal, format, out);
14773 + needed += outblocksize;
14774 + sincebreak += outblocksize;
14775 + if (dst < stop) {
14776 + if (out != dst) {
14777 + user_assert(outblocksize > stop - dst);
14778 + memcpy(dst, out, stop - dst);
14779 + dst = stop;
14780 + } else
14781 + dst += outblocksize;
14782 + }
14783 +
14784 + src += inblocksize;
14785 + ntodo -= inblocksize;
14786 + if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
14787 + if (dst < stop)
14788 + *dst++ = breakchar;
14789 + needed++;
14790 + sincebreak = 0;
14791 + }
14792 + }
14793 +
14794 + user_assert(dst <= stop);
14795 + *dst++ = '\0';
14796 + needed++;
14797 +
14798 + return needed;
14799 +}
14800 +
14801 +/*
14802 + - convert - convert one input block to one output block
14803 + */
14804 +static void
14805 +convert(src, nreal, format, out)
14806 +const char *src;
14807 +size_t nreal; /* how much of the input block is real */
14808 +int format;
14809 +char *out;
14810 +{
14811 + static char hex[] = "0123456789abcdef";
14812 + static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
14813 + "abcdefghijklmnopqrstuvwxyz"
14814 + "0123456789+/";
14815 + unsigned char c;
14816 + unsigned char c1, c2, c3;
14817 +
14818 + user_assert(nreal > 0);
14819 + switch (format) {
14820 + case 'x':
14821 + user_assert(nreal == 1);
14822 + c = (unsigned char)*src;
14823 + *out++ = hex[c >> 4];
14824 + *out++ = hex[c & 0xf];
14825 + break;
14826 + case 's':
14827 + c1 = (unsigned char)*src++;
14828 + c2 = (unsigned char)*src++;
14829 + c3 = (unsigned char)*src++;
14830 + *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
14831 + c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
14832 + c |= c2 >> 4; /* ...top 4 of c2 */
14833 + *out++ = base64[c];
14834 + if (nreal == 1)
14835 + *out++ = '=';
14836 + else {
14837 + c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
14838 + c |= c3 >> 6; /* ...top 2 of c3 */
14839 + *out++ = base64[c];
14840 + }
14841 + if (nreal <= 2)
14842 + *out++ = '=';
14843 + else
14844 + *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
14845 + break;
14846 + default:
14847 + user_assert(nreal == 0); /* unknown format */
14848 + break;
14849 + }
14850 +}
14851 +
14852 +/*
14853 + - datatoa - convert data to ASCII
14854 + * backward-compatibility synonym for datatot
14855 + */
14856 +size_t /* true length (with NUL) for success */
14857 +datatoa(src, srclen, format, dst, dstlen)
14858 +const char *src;
14859 +size_t srclen;
14860 +int format; /* character indicating what format */
14861 +char *dst; /* need not be valid if dstlen is 0 */
14862 +size_t dstlen;
14863 +{
14864 + return datatot(src, srclen, format, dst, dstlen);
14865 +}
14866 +
14867 +/*
14868 + - bytestoa - convert data bytes to ASCII
14869 + * backward-compatibility synonym for datatot
14870 + */
14871 +size_t /* true length (with NUL) for success */
14872 +bytestoa(src, srclen, format, dst, dstlen)
14873 +const char *src;
14874 +size_t srclen;
14875 +int format; /* character indicating what format */
14876 +char *dst; /* need not be valid if dstlen is 0 */
14877 +size_t dstlen;
14878 +{
14879 + return datatot(src, srclen, format, dst, dstlen);
14880 +}
14881 --- /dev/null Tue Mar 11 13:02:56 2003
14882 +++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004
14883 @@ -0,0 +1,148 @@
14884 +
14885 +#
14886 +# RCSID $Id: defconfig,v 1.28.2.1 2006/10/11 18:14:33 paul Exp $
14887 +#
14888 +
14889 +#
14890 +# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
14891 +#
14892 +
14893 +#
14894 +# First, lets override stuff already set or not in the kernel config.
14895 +#
14896 +# We can't even think about leaving this off...
14897 +CONFIG_INET=y
14898 +
14899 +#
14900 +# This must be on for subnet protection.
14901 +CONFIG_IP_FORWARD=y
14902 +
14903 +# Shut off IPSEC masquerading if it has been enabled, since it will
14904 +# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
14905 +# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
14906 +CONFIG_IP_MASQUERADE_IPSEC=n
14907 +
14908 +#
14909 +# Next, lets set the recommended FreeS/WAN configuration.
14910 +#
14911 +
14912 +# To config as static (preferred), 'y'. To config as module, 'm'.
14913 +CONFIG_KLIPS=m
14914 +
14915 +# To do tunnel mode IPSec, this must be enabled.
14916 +CONFIG_KLIPS_IPIP=y
14917 +
14918 +# To enable authentication, say 'y'. (Highly recommended)
14919 +CONFIG_KLIPS_AH=y
14920 +
14921 +# Authentication algorithm(s):
14922 +CONFIG_KLIPS_AUTH_HMAC_MD5=y
14923 +CONFIG_KLIPS_AUTH_HMAC_SHA1=y
14924 +
14925 +# To enable encryption, say 'y'. (Highly recommended)
14926 +CONFIG_KLIPS_ESP=y
14927 +
14928 +# modular algo extensions (and new ALGOs)
14929 +CONFIG_KLIPS_ALG=y
14930 +
14931 +# Encryption algorithm(s):
14932 +CONFIG_KLIPS_ENC_3DES=y
14933 +CONFIG_KLIPS_ENC_AES=y
14934 +# CONFIG_KLIPS_ENC_NULL=y
14935 +
14936 +# Use CryptoAPI for ALG? - by default, no.
14937 +CONFIG_KLIPS_ENC_CRYPTOAPI=n
14938 +
14939 +# IP Compression: new, probably still has minor bugs.
14940 +CONFIG_KLIPS_IPCOMP=y
14941 +
14942 +# To enable userspace-switchable KLIPS debugging, say 'y'.
14943 +CONFIG_KLIPS_DEBUG=y
14944 +
14945 +# NAT Traversal
14946 +CONFIG_IPSEC_NAT_TRAVERSAL=y
14947 +
14948 +#
14949 +#
14950 +# $Log: defconfig,v $
14951 +# Revision 1.28.2.1 2006/10/11 18:14:33 paul
14952 +# Add JuanJo Ciarlante's ESP_NULL patches for KLIPS, but leave it disabled
14953 +# per default.
14954 +#
14955 +# Revision 1.28 2005/05/11 03:15:42 mcr
14956 +# adjusted makefiles to sanely build modules properly.
14957 +#
14958 +# Revision 1.27 2005/03/20 03:00:05 mcr
14959 +# default configuration should enable NAT_TRAVERSAL.
14960 +#
14961 +# Revision 1.26 2004/07/10 19:11:18 mcr
14962 +# CONFIG_IPSEC -> CONFIG_KLIPS.
14963 +#
14964 +# Revision 1.25 2004/07/05 01:03:53 mcr
14965 +# fix for adding cryptoapi code.
14966 +# keep it off for now, since UMLs do not have it yet.
14967 +#
14968 +# Revision 1.24 2004/04/06 02:49:25 mcr
14969 +# pullup of algo code from alg-branch.
14970 +#
14971 +# Revision 1.23.2.2 2004/04/05 04:30:46 mcr
14972 +# patches for alg-branch to compile/work with 2.x openswan
14973 +#
14974 +# Revision 1.23.2.1 2003/12/22 15:25:52 jjo
14975 +# . Merged algo-0.8.1-rc11-test1 into alg-branch
14976 +#
14977 +# Revision 1.23 2003/12/10 01:14:27 mcr
14978 +# NAT-traversal patches to KLIPS.
14979 +#
14980 +# Revision 1.22 2003/02/24 19:37:27 mcr
14981 +# changed default compilation mode to static.
14982 +#
14983 +# Revision 1.21 2002/04/24 07:36:27 mcr
14984 +# Moved from ./klips/net/ipsec/defconfig,v
14985 +#
14986 +# Revision 1.20 2002/04/02 04:07:40 mcr
14987 +# default build is now 'm'odule for KLIPS
14988 +#
14989 +# Revision 1.19 2002/03/08 18:57:17 rgb
14990 +# Added a blank line at the beginning of the file to make it easier for
14991 +# other projects to patch ./arch/i386/defconfig, for example
14992 +# LIDS+grSecurity requested by Jason Pattie.
14993 +#
14994 +# Revision 1.18 2000/11/30 17:26:56 rgb
14995 +# Cleaned out unused options and enabled ipcomp by default.
14996 +#
14997 +# Revision 1.17 2000/09/15 11:37:01 rgb
14998 +# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
14999 +# IPCOMP zlib deflate code.
15000 +#
15001 +# Revision 1.16 2000/09/08 19:12:55 rgb
15002 +# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
15003 +#
15004 +# Revision 1.15 2000/05/24 19:37:13 rgb
15005 +# *** empty log message ***
15006 +#
15007 +# Revision 1.14 2000/05/11 21:14:57 henry
15008 +# just commenting the FOOBAR=y lines out is not enough
15009 +#
15010 +# Revision 1.13 2000/05/10 20:17:58 rgb
15011 +# Comment out netlink defaults, which are no longer needed.
15012 +#
15013 +# Revision 1.12 2000/05/10 19:13:38 rgb
15014 +# Added configure option to shut off no eroute passthrough.
15015 +#
15016 +# Revision 1.11 2000/03/16 07:09:46 rgb
15017 +# Hardcode PF_KEYv2 support.
15018 +# Disable IPSEC_ICMP by default.
15019 +# Remove DES config option from defaults file.
15020 +#
15021 +# Revision 1.10 2000/01/11 03:09:42 rgb
15022 +# Added a default of 'y' to PF_KEYv2 keying I/F.
15023 +#
15024 +# Revision 1.9 1999/05/08 21:23:12 rgb
15025 +# Added support for 2.2.x kernels.
15026 +#
15027 +# Revision 1.8 1999/04/06 04:54:25 rgb
15028 +# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
15029 +# patch shell fixes.
15030 +#
15031 +#
15032 --- /dev/null Tue Mar 11 13:02:56 2003
15033 +++ linux/net/ipsec/deflate.c Mon Feb 9 13:51:03 2004
15034 @@ -0,0 +1,1351 @@
15035 +/* deflate.c -- compress data using the deflation algorithm
15036 + * Copyright (C) 1995-2002 Jean-loup Gailly.
15037 + * For conditions of distribution and use, see copyright notice in zlib.h
15038 + */
15039 +
15040 +/*
15041 + * ALGORITHM
15042 + *
15043 + * The "deflation" process depends on being able to identify portions
15044 + * of the input text which are identical to earlier input (within a
15045 + * sliding window trailing behind the input currently being processed).
15046 + *
15047 + * The most straightforward technique turns out to be the fastest for
15048 + * most input files: try all possible matches and select the longest.
15049 + * The key feature of this algorithm is that insertions into the string
15050 + * dictionary are very simple and thus fast, and deletions are avoided
15051 + * completely. Insertions are performed at each input character, whereas
15052 + * string matches are performed only when the previous match ends. So it
15053 + * is preferable to spend more time in matches to allow very fast string
15054 + * insertions and avoid deletions. The matching algorithm for small
15055 + * strings is inspired from that of Rabin & Karp. A brute force approach
15056 + * is used to find longer strings when a small match has been found.
15057 + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
15058 + * (by Leonid Broukhis).
15059 + * A previous version of this file used a more sophisticated algorithm
15060 + * (by Fiala and Greene) which is guaranteed to run in linear amortized
15061 + * time, but has a larger average cost, uses more memory and is patented.
15062 + * However the F&G algorithm may be faster for some highly redundant
15063 + * files if the parameter max_chain_length (described below) is too large.
15064 + *
15065 + * ACKNOWLEDGEMENTS
15066 + *
15067 + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
15068 + * I found it in 'freeze' written by Leonid Broukhis.
15069 + * Thanks to many people for bug reports and testing.
15070 + *
15071 + * REFERENCES
15072 + *
15073 + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
15074 + * Available in ftp://ds.internic.net/rfc/rfc1951.txt
15075 + *
15076 + * A description of the Rabin and Karp algorithm is given in the book
15077 + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
15078 + *
15079 + * Fiala,E.R., and Greene,D.H.
15080 + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
15081 + *
15082 + */
15083 +
15084 +/* @(#) $Id: deflate.c,v 1.4 2004/07/10 07:48:37 mcr Exp $ */
15085 +
15086 +#include "deflate.h"
15087 +
15088 +local const char deflate_copyright[] =
15089 + " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
15090 +/*
15091 + If you use the zlib library in a product, an acknowledgment is welcome
15092 + in the documentation of your product. If for some reason you cannot
15093 + include such an acknowledgment, I would appreciate that you keep this
15094 + copyright string in the executable of your product.
15095 + */
15096 +
15097 +/* ===========================================================================
15098 + * Function prototypes.
15099 + */
15100 +typedef enum {
15101 + need_more, /* block not completed, need more input or more output */
15102 + block_done, /* block flush performed */
15103 + finish_started, /* finish started, need only more output at next deflate */
15104 + finish_done /* finish done, accept no more input or output */
15105 +} block_state;
15106 +
15107 +typedef block_state (*compress_func) OF((deflate_state *s, int flush));
15108 +/* Compression function. Returns the block state after the call. */
15109 +
15110 +local void fill_window OF((deflate_state *s));
15111 +local block_state deflate_stored OF((deflate_state *s, int flush));
15112 +local block_state deflate_fast OF((deflate_state *s, int flush));
15113 +local block_state deflate_slow OF((deflate_state *s, int flush));
15114 +local void lm_init OF((deflate_state *s));
15115 +local void putShortMSB OF((deflate_state *s, uInt b));
15116 +local void flush_pending OF((z_streamp strm));
15117 +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
15118 +#ifdef ASMV
15119 + void match_init OF((void)); /* asm code initialization */
15120 + uInt longest_match OF((deflate_state *s, IPos cur_match));
15121 +#else
15122 +local uInt longest_match OF((deflate_state *s, IPos cur_match));
15123 +#endif
15124 +
15125 +#ifdef DEBUG
15126 +local void check_match OF((deflate_state *s, IPos start, IPos match,
15127 + int length));
15128 +#endif
15129 +
15130 +/* ===========================================================================
15131 + * Local data
15132 + */
15133 +
15134 +#define NIL 0
15135 +/* Tail of hash chains */
15136 +
15137 +#ifndef TOO_FAR
15138 +# define TOO_FAR 4096
15139 +#endif
15140 +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
15141 +
15142 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
15143 +/* Minimum amount of lookahead, except at the end of the input file.
15144 + * See deflate.c for comments about the MIN_MATCH+1.
15145 + */
15146 +
15147 +/* Values for max_lazy_match, good_match and max_chain_length, depending on
15148 + * the desired pack level (0..9). The values given below have been tuned to
15149 + * exclude worst case performance for pathological files. Better values may be
15150 + * found for specific files.
15151 + */
15152 +typedef struct config_s {
15153 + ush good_length; /* reduce lazy search above this match length */
15154 + ush max_lazy; /* do not perform lazy search above this match length */
15155 + ush nice_length; /* quit search above this match length */
15156 + ush max_chain;
15157 + compress_func func;
15158 +} config;
15159 +
15160 +local const config configuration_table[10] = {
15161 +/* good lazy nice chain */
15162 +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
15163 +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
15164 +/* 2 */ {4, 5, 16, 8, deflate_fast},
15165 +/* 3 */ {4, 6, 32, 32, deflate_fast},
15166 +
15167 +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
15168 +/* 5 */ {8, 16, 32, 32, deflate_slow},
15169 +/* 6 */ {8, 16, 128, 128, deflate_slow},
15170 +/* 7 */ {8, 32, 128, 256, deflate_slow},
15171 +/* 8 */ {32, 128, 258, 1024, deflate_slow},
15172 +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
15173 +
15174 +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
15175 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
15176 + * meaning.
15177 + */
15178 +
15179 +#define EQUAL 0
15180 +/* result of memcmp for equal strings */
15181 +
15182 +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
15183 +
15184 +/* ===========================================================================
15185 + * Update a hash value with the given input byte
15186 + * IN assertion: all calls to to UPDATE_HASH are made with consecutive
15187 + * input characters, so that a running hash key can be computed from the
15188 + * previous key instead of complete recalculation each time.
15189 + */
15190 +#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
15191 +
15192 +
15193 +/* ===========================================================================
15194 + * Insert string str in the dictionary and set match_head to the previous head
15195 + * of the hash chain (the most recent string with same hash key). Return
15196 + * the previous length of the hash chain.
15197 + * If this file is compiled with -DFASTEST, the compression level is forced
15198 + * to 1, and no hash chains are maintained.
15199 + * IN assertion: all calls to to INSERT_STRING are made with consecutive
15200 + * input characters and the first MIN_MATCH bytes of str are valid
15201 + * (except for the last MIN_MATCH-1 bytes of the input file).
15202 + */
15203 +#ifdef FASTEST
15204 +#define INSERT_STRING(s, str, match_head) \
15205 + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
15206 + match_head = s->head[s->ins_h], \
15207 + s->head[s->ins_h] = (Pos)(str))
15208 +#else
15209 +#define INSERT_STRING(s, str, match_head) \
15210 + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
15211 + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
15212 + s->head[s->ins_h] = (Pos)(str))
15213 +#endif
15214 +
15215 +/* ===========================================================================
15216 + * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
15217 + * prev[] will be initialized on the fly.
15218 + */
15219 +#define CLEAR_HASH(s) \
15220 + s->head[s->hash_size-1] = NIL; \
15221 + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
15222 +
15223 +/* ========================================================================= */
15224 +int ZEXPORT deflateInit_(strm, level, version, stream_size)
15225 + z_streamp strm;
15226 + int level;
15227 + const char *version;
15228 + int stream_size;
15229 +{
15230 + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
15231 + Z_DEFAULT_STRATEGY, version, stream_size);
15232 + /* To do: ignore strm->next_in if we use it as window */
15233 +}
15234 +
15235 +/* ========================================================================= */
15236 +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
15237 + version, stream_size)
15238 + z_streamp strm;
15239 + int level;
15240 + int method;
15241 + int windowBits;
15242 + int memLevel;
15243 + int strategy;
15244 + const char *version;
15245 + int stream_size;
15246 +{
15247 + deflate_state *s;
15248 + int noheader = 0;
15249 + static const char* my_version = ZLIB_VERSION;
15250 +
15251 + ushf *overlay;
15252 + /* We overlay pending_buf and d_buf+l_buf. This works since the average
15253 + * output size for (length,distance) codes is <= 24 bits.
15254 + */
15255 +
15256 + if (version == Z_NULL || version[0] != my_version[0] ||
15257 + stream_size != sizeof(z_stream)) {
15258 + return Z_VERSION_ERROR;
15259 + }
15260 + if (strm == Z_NULL) return Z_STREAM_ERROR;
15261 +
15262 + strm->msg = Z_NULL;
15263 + if (strm->zalloc == Z_NULL) {
15264 + return Z_STREAM_ERROR;
15265 +/* strm->zalloc = zcalloc;
15266 + strm->opaque = (voidpf)0;*/
15267 + }
15268 + if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
15269 +
15270 + if (level == Z_DEFAULT_COMPRESSION) level = 6;
15271 +#ifdef FASTEST
15272 + level = 1;
15273 +#endif
15274 +
15275 + if (windowBits < 0) { /* undocumented feature: suppress zlib header */
15276 + noheader = 1;
15277 + windowBits = -windowBits;
15278 + }
15279 + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
15280 + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
15281 + strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
15282 + return Z_STREAM_ERROR;
15283 + }
15284 + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
15285 + if (s == Z_NULL) return Z_MEM_ERROR;
15286 + strm->state = (struct internal_state FAR *)s;
15287 + s->strm = strm;
15288 +
15289 + s->noheader = noheader;
15290 + s->w_bits = windowBits;
15291 + s->w_size = 1 << s->w_bits;
15292 + s->w_mask = s->w_size - 1;
15293 +
15294 + s->hash_bits = memLevel + 7;
15295 + s->hash_size = 1 << s->hash_bits;
15296 + s->hash_mask = s->hash_size - 1;
15297 + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
15298 +
15299 + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
15300 + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
15301 + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
15302 +
15303 + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
15304 +
15305 + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
15306 + s->pending_buf = (uchf *) overlay;
15307 + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
15308 +
15309 + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
15310 + s->pending_buf == Z_NULL) {
15311 + strm->msg = ERR_MSG(Z_MEM_ERROR);
15312 + deflateEnd (strm);
15313 + return Z_MEM_ERROR;
15314 + }
15315 + s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
15316 + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
15317 +
15318 + s->level = level;
15319 + s->strategy = strategy;
15320 + s->method = (Byte)method;
15321 +
15322 + return deflateReset(strm);
15323 +}
15324 +
15325 +/* ========================================================================= */
15326 +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
15327 + z_streamp strm;
15328 + const Bytef *dictionary;
15329 + uInt dictLength;
15330 +{
15331 + deflate_state *s;
15332 + uInt length = dictLength;
15333 + uInt n;
15334 + IPos hash_head = 0;
15335 +
15336 + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
15337 + strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
15338 +
15339 + s = strm->state;
15340 + strm->adler = adler32(strm->adler, dictionary, dictLength);
15341 +
15342 + if (length < MIN_MATCH) return Z_OK;
15343 + if (length > MAX_DIST(s)) {
15344 + length = MAX_DIST(s);
15345 +#ifndef USE_DICT_HEAD
15346 + dictionary += dictLength - length; /* use the tail of the dictionary */
15347 +#endif
15348 + }
15349 + zmemcpy(s->window, dictionary, length);
15350 + s->strstart = length;
15351 + s->block_start = (long)length;
15352 +
15353 + /* Insert all strings in the hash table (except for the last two bytes).
15354 + * s->lookahead stays null, so s->ins_h will be recomputed at the next
15355 + * call of fill_window.
15356 + */
15357 + s->ins_h = s->window[0];
15358 + UPDATE_HASH(s, s->ins_h, s->window[1]);
15359 + for (n = 0; n <= length - MIN_MATCH; n++) {
15360 + INSERT_STRING(s, n, hash_head);
15361 + }
15362 + if (hash_head) hash_head = 0; /* to make compiler happy */
15363 + return Z_OK;
15364 +}
15365 +
15366 +/* ========================================================================= */
15367 +int ZEXPORT deflateReset (strm)
15368 + z_streamp strm;
15369 +{
15370 + deflate_state *s;
15371 +
15372 + if (strm == Z_NULL || strm->state == Z_NULL ||
15373 + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
15374 +
15375 + strm->total_in = strm->total_out = 0;
15376 + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
15377 + strm->data_type = Z_UNKNOWN;
15378 +
15379 + s = (deflate_state *)strm->state;
15380 + s->pending = 0;
15381 + s->pending_out = s->pending_buf;
15382 +
15383 + if (s->noheader < 0) {
15384 + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
15385 + }
15386 + s->status = s->noheader ? BUSY_STATE : INIT_STATE;
15387 + strm->adler = 1;
15388 + s->last_flush = Z_NO_FLUSH;
15389 +
15390 + _tr_init(s);
15391 + lm_init(s);
15392 +
15393 + return Z_OK;
15394 +}
15395 +
15396 +/* ========================================================================= */
15397 +int ZEXPORT deflateParams(strm, level, strategy)
15398 + z_streamp strm;
15399 + int level;
15400 + int strategy;
15401 +{
15402 + deflate_state *s;
15403 + compress_func func;
15404 + int err = Z_OK;
15405 +
15406 + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15407 + s = strm->state;
15408 +
15409 + if (level == Z_DEFAULT_COMPRESSION) {
15410 + level = 6;
15411 + }
15412 + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
15413 + return Z_STREAM_ERROR;
15414 + }
15415 + func = configuration_table[s->level].func;
15416 +
15417 + if (func != configuration_table[level].func && strm->total_in != 0) {
15418 + /* Flush the last buffer: */
15419 + err = deflate(strm, Z_PARTIAL_FLUSH);
15420 + }
15421 + if (s->level != level) {
15422 + s->level = level;
15423 + s->max_lazy_match = configuration_table[level].max_lazy;
15424 + s->good_match = configuration_table[level].good_length;
15425 + s->nice_match = configuration_table[level].nice_length;
15426 + s->max_chain_length = configuration_table[level].max_chain;
15427 + }
15428 + s->strategy = strategy;
15429 + return err;
15430 +}
15431 +
15432 +/* =========================================================================
15433 + * Put a short in the pending buffer. The 16-bit value is put in MSB order.
15434 + * IN assertion: the stream state is correct and there is enough room in
15435 + * pending_buf.
15436 + */
15437 +local void putShortMSB (s, b)
15438 + deflate_state *s;
15439 + uInt b;
15440 +{
15441 + put_byte(s, (Byte)(b >> 8));
15442 + put_byte(s, (Byte)(b & 0xff));
15443 +}
15444 +
15445 +/* =========================================================================
15446 + * Flush as much pending output as possible. All deflate() output goes
15447 + * through this function so some applications may wish to modify it
15448 + * to avoid allocating a large strm->next_out buffer and copying into it.
15449 + * (See also read_buf()).
15450 + */
15451 +local void flush_pending(strm)
15452 + z_streamp strm;
15453 +{
15454 + unsigned len = strm->state->pending;
15455 +
15456 + if (len > strm->avail_out) len = strm->avail_out;
15457 + if (len == 0) return;
15458 +
15459 + zmemcpy(strm->next_out, strm->state->pending_out, len);
15460 + strm->next_out += len;
15461 + strm->state->pending_out += len;
15462 + strm->total_out += len;
15463 + strm->avail_out -= len;
15464 + strm->state->pending -= len;
15465 + if (strm->state->pending == 0) {
15466 + strm->state->pending_out = strm->state->pending_buf;
15467 + }
15468 +}
15469 +
15470 +/* ========================================================================= */
15471 +int ZEXPORT deflate (strm, flush)
15472 + z_streamp strm;
15473 + int flush;
15474 +{
15475 + int old_flush; /* value of flush param for previous deflate call */
15476 + deflate_state *s;
15477 +
15478 + if (strm == Z_NULL || strm->state == Z_NULL ||
15479 + flush > Z_FINISH || flush < 0) {
15480 + return Z_STREAM_ERROR;
15481 + }
15482 + s = strm->state;
15483 +
15484 + if (strm->next_out == Z_NULL ||
15485 + (strm->next_in == Z_NULL && strm->avail_in != 0) ||
15486 + (s->status == FINISH_STATE && flush != Z_FINISH)) {
15487 + ERR_RETURN(strm, Z_STREAM_ERROR);
15488 + }
15489 + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
15490 +
15491 + s->strm = strm; /* just in case */
15492 + old_flush = s->last_flush;
15493 + s->last_flush = flush;
15494 +
15495 + /* Write the zlib header */
15496 + if (s->status == INIT_STATE) {
15497 +
15498 + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
15499 + uInt level_flags = (s->level-1) >> 1;
15500 +
15501 + if (level_flags > 3) level_flags = 3;
15502 + header |= (level_flags << 6);
15503 + if (s->strstart != 0) header |= PRESET_DICT;
15504 + header += 31 - (header % 31);
15505 +
15506 + s->status = BUSY_STATE;
15507 + putShortMSB(s, header);
15508 +
15509 + /* Save the adler32 of the preset dictionary: */
15510 + if (s->strstart != 0) {
15511 + putShortMSB(s, (uInt)(strm->adler >> 16));
15512 + putShortMSB(s, (uInt)(strm->adler & 0xffff));
15513 + }
15514 + strm->adler = 1L;
15515 + }
15516 +
15517 + /* Flush as much pending output as possible */
15518 + if (s->pending != 0) {
15519 + flush_pending(strm);
15520 + if (strm->avail_out == 0) {
15521 + /* Since avail_out is 0, deflate will be called again with
15522 + * more output space, but possibly with both pending and
15523 + * avail_in equal to zero. There won't be anything to do,
15524 + * but this is not an error situation so make sure we
15525 + * return OK instead of BUF_ERROR at next call of deflate:
15526 + */
15527 + s->last_flush = -1;
15528 + return Z_OK;
15529 + }
15530 +
15531 + /* Make sure there is something to do and avoid duplicate consecutive
15532 + * flushes. For repeated and useless calls with Z_FINISH, we keep
15533 + * returning Z_STREAM_END instead of Z_BUFF_ERROR.
15534 + */
15535 + } else if (strm->avail_in == 0 && flush <= old_flush &&
15536 + flush != Z_FINISH) {
15537 + ERR_RETURN(strm, Z_BUF_ERROR);
15538 + }
15539 +
15540 + /* User must not provide more input after the first FINISH: */
15541 + if (s->status == FINISH_STATE && strm->avail_in != 0) {
15542 + ERR_RETURN(strm, Z_BUF_ERROR);
15543 + }
15544 +
15545 + /* Start a new block or continue the current one.
15546 + */
15547 + if (strm->avail_in != 0 || s->lookahead != 0 ||
15548 + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
15549 + block_state bstate;
15550 +
15551 + bstate = (*(configuration_table[s->level].func))(s, flush);
15552 +
15553 + if (bstate == finish_started || bstate == finish_done) {
15554 + s->status = FINISH_STATE;
15555 + }
15556 + if (bstate == need_more || bstate == finish_started) {
15557 + if (strm->avail_out == 0) {
15558 + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
15559 + }
15560 + return Z_OK;
15561 + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
15562 + * of deflate should use the same flush parameter to make sure
15563 + * that the flush is complete. So we don't have to output an
15564 + * empty block here, this will be done at next call. This also
15565 + * ensures that for a very small output buffer, we emit at most
15566 + * one empty block.
15567 + */
15568 + }
15569 + if (bstate == block_done) {
15570 + if (flush == Z_PARTIAL_FLUSH) {
15571 + _tr_align(s);
15572 + } else { /* FULL_FLUSH or SYNC_FLUSH */
15573 + _tr_stored_block(s, (char*)0, 0L, 0);
15574 + /* For a full flush, this empty block will be recognized
15575 + * as a special marker by inflate_sync().
15576 + */
15577 + if (flush == Z_FULL_FLUSH) {
15578 + CLEAR_HASH(s); /* forget history */
15579 + }
15580 + }
15581 + flush_pending(strm);
15582 + if (strm->avail_out == 0) {
15583 + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
15584 + return Z_OK;
15585 + }
15586 + }
15587 + }
15588 + Assert(strm->avail_out > 0, "bug2");
15589 +
15590 + if (flush != Z_FINISH) return Z_OK;
15591 + if (s->noheader) return Z_STREAM_END;
15592 +
15593 + /* Write the zlib trailer (adler32) */
15594 + putShortMSB(s, (uInt)(strm->adler >> 16));
15595 + putShortMSB(s, (uInt)(strm->adler & 0xffff));
15596 + flush_pending(strm);
15597 + /* If avail_out is zero, the application will call deflate again
15598 + * to flush the rest.
15599 + */
15600 + s->noheader = -1; /* write the trailer only once! */
15601 + return s->pending != 0 ? Z_OK : Z_STREAM_END;
15602 +}
15603 +
15604 +/* ========================================================================= */
15605 +int ZEXPORT deflateEnd (strm)
15606 + z_streamp strm;
15607 +{
15608 + int status;
15609 +
15610 + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
15611 +
15612 + status = strm->state->status;
15613 + if (status != INIT_STATE && status != BUSY_STATE &&
15614 + status != FINISH_STATE) {
15615 + return Z_STREAM_ERROR;
15616 + }
15617 +
15618 + /* Deallocate in reverse order of allocations: */
15619 + TRY_FREE(strm, strm->state->pending_buf);
15620 + TRY_FREE(strm, strm->state->head);
15621 + TRY_FREE(strm, strm->state->prev);
15622 + TRY_FREE(strm, strm->state->window);
15623 +
15624 + ZFREE(strm, strm->state);
15625 + strm->state = Z_NULL;
15626 +
15627 + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
15628 +}
15629 +
15630 +/* =========================================================================
15631 + * Copy the source state to the destination state.
15632 + * To simplify the source, this is not supported for 16-bit MSDOS (which
15633 + * doesn't have enough memory anyway to duplicate compression states).
15634 + */
15635 +int ZEXPORT deflateCopy (dest, source)
15636 + z_streamp dest;
15637 + z_streamp source;
15638 +{
15639 +#ifdef MAXSEG_64K
15640 + return Z_STREAM_ERROR;
15641 +#else
15642 + deflate_state *ds;
15643 + deflate_state *ss;
15644 + ushf *overlay;
15645 +
15646 +
15647 + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
15648 + return Z_STREAM_ERROR;
15649 + }
15650 +
15651 + ss = source->state;
15652 +
15653 + *dest = *source;
15654 +
15655 + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
15656 + if (ds == Z_NULL) return Z_MEM_ERROR;
15657 + dest->state = (struct internal_state FAR *) ds;
15658 + *ds = *ss;
15659 + ds->strm = dest;
15660 +
15661 + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
15662 + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
15663 + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
15664 + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
15665 + ds->pending_buf = (uchf *) overlay;
15666 +
15667 + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
15668 + ds->pending_buf == Z_NULL) {
15669 + deflateEnd (dest);
15670 + return Z_MEM_ERROR;
15671 + }
15672 + /* following zmemcpy do not work for 16-bit MSDOS */
15673 + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
15674 + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
15675 + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
15676 + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
15677 +
15678 + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
15679 + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
15680 + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
15681 +
15682 + ds->l_desc.dyn_tree = ds->dyn_ltree;
15683 + ds->d_desc.dyn_tree = ds->dyn_dtree;
15684 + ds->bl_desc.dyn_tree = ds->bl_tree;
15685 +
15686 + return Z_OK;
15687 +#endif
15688 +}
15689 +
15690 +/* ===========================================================================
15691 + * Read a new buffer from the current input stream, update the adler32
15692 + * and total number of bytes read. All deflate() input goes through
15693 + * this function so some applications may wish to modify it to avoid
15694 + * allocating a large strm->next_in buffer and copying from it.
15695 + * (See also flush_pending()).
15696 + */
15697 +local int read_buf(strm, buf, size)
15698 + z_streamp strm;
15699 + Bytef *buf;
15700 + unsigned size;
15701 +{
15702 + unsigned len = strm->avail_in;
15703 +
15704 + if (len > size) len = size;
15705 + if (len == 0) return 0;
15706 +
15707 + strm->avail_in -= len;
15708 +
15709 + if (!strm->state->noheader) {
15710 + strm->adler = adler32(strm->adler, strm->next_in, len);
15711 + }
15712 + zmemcpy(buf, strm->next_in, len);
15713 + strm->next_in += len;
15714 + strm->total_in += len;
15715 +
15716 + return (int)len;
15717 +}
15718 +
15719 +/* ===========================================================================
15720 + * Initialize the "longest match" routines for a new zlib stream
15721 + */
15722 +local void lm_init (s)
15723 + deflate_state *s;
15724 +{
15725 + s->window_size = (ulg)2L*s->w_size;
15726 +
15727 + CLEAR_HASH(s);
15728 +
15729 + /* Set the default configuration parameters:
15730 + */
15731 + s->max_lazy_match = configuration_table[s->level].max_lazy;
15732 + s->good_match = configuration_table[s->level].good_length;
15733 + s->nice_match = configuration_table[s->level].nice_length;
15734 + s->max_chain_length = configuration_table[s->level].max_chain;
15735 +
15736 + s->strstart = 0;
15737 + s->block_start = 0L;
15738 + s->lookahead = 0;
15739 + s->match_length = s->prev_length = MIN_MATCH-1;
15740 + s->match_available = 0;
15741 + s->ins_h = 0;
15742 +#ifdef ASMV
15743 + match_init(); /* initialize the asm code */
15744 +#endif
15745 +}
15746 +
15747 +/* ===========================================================================
15748 + * Set match_start to the longest match starting at the given string and
15749 + * return its length. Matches shorter or equal to prev_length are discarded,
15750 + * in which case the result is equal to prev_length and match_start is
15751 + * garbage.
15752 + * IN assertions: cur_match is the head of the hash chain for the current
15753 + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
15754 + * OUT assertion: the match length is not greater than s->lookahead.
15755 + */
15756 +#ifndef ASMV
15757 +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
15758 + * match.S. The code will be functionally equivalent.
15759 + */
15760 +#ifndef FASTEST
15761 +local uInt longest_match(s, cur_match)
15762 + deflate_state *s;
15763 + IPos cur_match; /* current match */
15764 +{
15765 + unsigned chain_length = s->max_chain_length;/* max hash chain length */
15766 + register Bytef *scan = s->window + s->strstart; /* current string */
15767 + register Bytef *match; /* matched string */
15768 + register int len; /* length of current match */
15769 + int best_len = s->prev_length; /* best match length so far */
15770 + int nice_match = s->nice_match; /* stop if match long enough */
15771 + IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
15772 + s->strstart - (IPos)MAX_DIST(s) : NIL;
15773 + /* Stop when cur_match becomes <= limit. To simplify the code,
15774 + * we prevent matches with the string of window index 0.
15775 + */
15776 + Posf *prev = s->prev;
15777 + uInt wmask = s->w_mask;
15778 +
15779 +#ifdef UNALIGNED_OK
15780 + /* Compare two bytes at a time. Note: this is not always beneficial.
15781 + * Try with and without -DUNALIGNED_OK to check.
15782 + */
15783 + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
15784 + register ush scan_start = *(ushf*)scan;
15785 + register ush scan_end = *(ushf*)(scan+best_len-1);
15786 +#else
15787 + register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15788 + register Byte scan_end1 = scan[best_len-1];
15789 + register Byte scan_end = scan[best_len];
15790 +#endif
15791 +
15792 + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15793 + * It is easy to get rid of this optimization if necessary.
15794 + */
15795 + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15796 +
15797 + /* Do not waste too much time if we already have a good match: */
15798 + if (s->prev_length >= s->good_match) {
15799 + chain_length >>= 2;
15800 + }
15801 + /* Do not look for matches beyond the end of the input. This is necessary
15802 + * to make deflate deterministic.
15803 + */
15804 + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
15805 +
15806 + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15807 +
15808 + do {
15809 + Assert(cur_match < s->strstart, "no future");
15810 + match = s->window + cur_match;
15811 +
15812 + /* Skip to next match if the match length cannot increase
15813 + * or if the match length is less than 2:
15814 + */
15815 +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
15816 + /* This code assumes sizeof(unsigned short) == 2. Do not use
15817 + * UNALIGNED_OK if your compiler uses a different size.
15818 + */
15819 + if (*(ushf*)(match+best_len-1) != scan_end ||
15820 + *(ushf*)match != scan_start) continue;
15821 +
15822 + /* It is not necessary to compare scan[2] and match[2] since they are
15823 + * always equal when the other bytes match, given that the hash keys
15824 + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
15825 + * strstart+3, +5, ... up to strstart+257. We check for insufficient
15826 + * lookahead only every 4th comparison; the 128th check will be made
15827 + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
15828 + * necessary to put more guard bytes at the end of the window, or
15829 + * to check more often for insufficient lookahead.
15830 + */
15831 + Assert(scan[2] == match[2], "scan[2]?");
15832 + scan++, match++;
15833 + do {
15834 + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15835 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15836 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15837 + *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
15838 + scan < strend);
15839 + /* The funny "do {}" generates better code on most compilers */
15840 +
15841 + /* Here, scan <= window+strstart+257 */
15842 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15843 + if (*scan == *match) scan++;
15844 +
15845 + len = (MAX_MATCH - 1) - (int)(strend-scan);
15846 + scan = strend - (MAX_MATCH-1);
15847 +
15848 +#else /* UNALIGNED_OK */
15849 +
15850 + if (match[best_len] != scan_end ||
15851 + match[best_len-1] != scan_end1 ||
15852 + *match != *scan ||
15853 + *++match != scan[1]) continue;
15854 +
15855 + /* The check at best_len-1 can be removed because it will be made
15856 + * again later. (This heuristic is not always a win.)
15857 + * It is not necessary to compare scan[2] and match[2] since they
15858 + * are always equal when the other bytes match, given that
15859 + * the hash keys are equal and that HASH_BITS >= 8.
15860 + */
15861 + scan += 2, match++;
15862 + Assert(*scan == *match, "match[2]?");
15863 +
15864 + /* We check for insufficient lookahead only every 8th comparison;
15865 + * the 256th check will be made at strstart+258.
15866 + */
15867 + do {
15868 + } while (*++scan == *++match && *++scan == *++match &&
15869 + *++scan == *++match && *++scan == *++match &&
15870 + *++scan == *++match && *++scan == *++match &&
15871 + *++scan == *++match && *++scan == *++match &&
15872 + scan < strend);
15873 +
15874 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15875 +
15876 + len = MAX_MATCH - (int)(strend - scan);
15877 + scan = strend - MAX_MATCH;
15878 +
15879 +#endif /* UNALIGNED_OK */
15880 +
15881 + if (len > best_len) {
15882 + s->match_start = cur_match;
15883 + best_len = len;
15884 + if (len >= nice_match) break;
15885 +#ifdef UNALIGNED_OK
15886 + scan_end = *(ushf*)(scan+best_len-1);
15887 +#else
15888 + scan_end1 = scan[best_len-1];
15889 + scan_end = scan[best_len];
15890 +#endif
15891 + }
15892 + } while ((cur_match = prev[cur_match & wmask]) > limit
15893 + && --chain_length != 0);
15894 +
15895 + if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
15896 + return s->lookahead;
15897 +}
15898 +
15899 +#else /* FASTEST */
15900 +/* ---------------------------------------------------------------------------
15901 + * Optimized version for level == 1 only
15902 + */
15903 +local uInt longest_match(s, cur_match)
15904 + deflate_state *s;
15905 + IPos cur_match; /* current match */
15906 +{
15907 + register Bytef *scan = s->window + s->strstart; /* current string */
15908 + register Bytef *match; /* matched string */
15909 + register int len; /* length of current match */
15910 + register Bytef *strend = s->window + s->strstart + MAX_MATCH;
15911 +
15912 + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
15913 + * It is easy to get rid of this optimization if necessary.
15914 + */
15915 + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
15916 +
15917 + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
15918 +
15919 + Assert(cur_match < s->strstart, "no future");
15920 +
15921 + match = s->window + cur_match;
15922 +
15923 + /* Return failure if the match length is less than 2:
15924 + */
15925 + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
15926 +
15927 + /* The check at best_len-1 can be removed because it will be made
15928 + * again later. (This heuristic is not always a win.)
15929 + * It is not necessary to compare scan[2] and match[2] since they
15930 + * are always equal when the other bytes match, given that
15931 + * the hash keys are equal and that HASH_BITS >= 8.
15932 + */
15933 + scan += 2, match += 2;
15934 + Assert(*scan == *match, "match[2]?");
15935 +
15936 + /* We check for insufficient lookahead only every 8th comparison;
15937 + * the 256th check will be made at strstart+258.
15938 + */
15939 + do {
15940 + } while (*++scan == *++match && *++scan == *++match &&
15941 + *++scan == *++match && *++scan == *++match &&
15942 + *++scan == *++match && *++scan == *++match &&
15943 + *++scan == *++match && *++scan == *++match &&
15944 + scan < strend);
15945 +
15946 + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
15947 +
15948 + len = MAX_MATCH - (int)(strend - scan);
15949 +
15950 + if (len < MIN_MATCH) return MIN_MATCH - 1;
15951 +
15952 + s->match_start = cur_match;
15953 + return len <= s->lookahead ? len : s->lookahead;
15954 +}
15955 +#endif /* FASTEST */
15956 +#endif /* ASMV */
15957 +
15958 +#ifdef DEBUG
15959 +/* ===========================================================================
15960 + * Check that the match at match_start is indeed a match.
15961 + */
15962 +local void check_match(s, start, match, length)
15963 + deflate_state *s;
15964 + IPos start, match;
15965 + int length;
15966 +{
15967 + /* check that the match is indeed a match */
15968 + if (zmemcmp(s->window + match,
15969 + s->window + start, length) != EQUAL) {
15970 + fprintf(stderr, " start %u, match %u, length %d\n",
15971 + start, match, length);
15972 + do {
15973 + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
15974 + } while (--length != 0);
15975 + z_error("invalid match");
15976 + }
15977 + if (z_verbose > 1) {
15978 + fprintf(stderr,"\\[%d,%d]", start-match, length);
15979 + do { putc(s->window[start++], stderr); } while (--length != 0);
15980 + }
15981 +}
15982 +#else
15983 +# define check_match(s, start, match, length)
15984 +#endif
15985 +
15986 +/* ===========================================================================
15987 + * Fill the window when the lookahead becomes insufficient.
15988 + * Updates strstart and lookahead.
15989 + *
15990 + * IN assertion: lookahead < MIN_LOOKAHEAD
15991 + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
15992 + * At least one byte has been read, or avail_in == 0; reads are
15993 + * performed for at least two bytes (required for the zip translate_eol
15994 + * option -- not supported here).
15995 + */
15996 +local void fill_window(s)
15997 + deflate_state *s;
15998 +{
15999 + register unsigned n, m;
16000 + register Posf *p;
16001 + unsigned more; /* Amount of free space at the end of the window. */
16002 + uInt wsize = s->w_size;
16003 +
16004 + do {
16005 + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
16006 +
16007 + /* Deal with !@#$% 64K limit: */
16008 + if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
16009 + more = wsize;
16010 +
16011 + } else if (more == (unsigned)(-1)) {
16012 + /* Very unlikely, but possible on 16 bit machine if strstart == 0
16013 + * and lookahead == 1 (input done one byte at time)
16014 + */
16015 + more--;
16016 +
16017 + /* If the window is almost full and there is insufficient lookahead,
16018 + * move the upper half to the lower one to make room in the upper half.
16019 + */
16020 + } else if (s->strstart >= wsize+MAX_DIST(s)) {
16021 +
16022 + zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
16023 + s->match_start -= wsize;
16024 + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
16025 + s->block_start -= (long) wsize;
16026 +
16027 + /* Slide the hash table (could be avoided with 32 bit values
16028 + at the expense of memory usage). We slide even when level == 0
16029 + to keep the hash table consistent if we switch back to level > 0
16030 + later. (Using level 0 permanently is not an optimal usage of
16031 + zlib, so we don't care about this pathological case.)
16032 + */
16033 + n = s->hash_size;
16034 + p = &s->head[n];
16035 + do {
16036 + m = *--p;
16037 + *p = (Pos)(m >= wsize ? m-wsize : NIL);
16038 + } while (--n);
16039 +
16040 + n = wsize;
16041 +#ifndef FASTEST
16042 + p = &s->prev[n];
16043 + do {
16044 + m = *--p;
16045 + *p = (Pos)(m >= wsize ? m-wsize : NIL);
16046 + /* If n is not on any hash chain, prev[n] is garbage but
16047 + * its value will never be used.
16048 + */
16049 + } while (--n);
16050 +#endif
16051 + more += wsize;
16052 + }
16053 + if (s->strm->avail_in == 0) return;
16054 +
16055 + /* If there was no sliding:
16056 + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
16057 + * more == window_size - lookahead - strstart
16058 + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
16059 + * => more >= window_size - 2*WSIZE + 2
16060 + * In the BIG_MEM or MMAP case (not yet supported),
16061 + * window_size == input_size + MIN_LOOKAHEAD &&
16062 + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
16063 + * Otherwise, window_size == 2*WSIZE so more >= 2.
16064 + * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
16065 + */
16066 + Assert(more >= 2, "more < 2");
16067 +
16068 + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
16069 + s->lookahead += n;
16070 +
16071 + /* Initialize the hash value now that we have some input: */
16072 + if (s->lookahead >= MIN_MATCH) {
16073 + s->ins_h = s->window[s->strstart];
16074 + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
16075 +#if MIN_MATCH != 3
16076 + Call UPDATE_HASH() MIN_MATCH-3 more times
16077 +#endif
16078 + }
16079 + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
16080 + * but this is not important since only literal bytes will be emitted.
16081 + */
16082 +
16083 + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
16084 +}
16085 +
16086 +/* ===========================================================================
16087 + * Flush the current block, with given end-of-file flag.
16088 + * IN assertion: strstart is set to the end of the current match.
16089 + */
16090 +#define FLUSH_BLOCK_ONLY(s, eof) { \
16091 + _tr_flush_block(s, (s->block_start >= 0L ? \
16092 + (charf *)&s->window[(unsigned)s->block_start] : \
16093 + (charf *)Z_NULL), \
16094 + (ulg)((long)s->strstart - s->block_start), \
16095 + (eof)); \
16096 + s->block_start = s->strstart; \
16097 + flush_pending(s->strm); \
16098 + Tracev((stderr,"[FLUSH]")); \
16099 +}
16100 +
16101 +/* Same but force premature exit if necessary. */
16102 +#define FLUSH_BLOCK(s, eof) { \
16103 + FLUSH_BLOCK_ONLY(s, eof); \
16104 + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
16105 +}
16106 +
16107 +/* ===========================================================================
16108 + * Copy without compression as much as possible from the input stream, return
16109 + * the current block state.
16110 + * This function does not insert new strings in the dictionary since
16111 + * uncompressible data is probably not useful. This function is used
16112 + * only for the level=0 compression option.
16113 + * NOTE: this function should be optimized to avoid extra copying from
16114 + * window to pending_buf.
16115 + */
16116 +local block_state deflate_stored(s, flush)
16117 + deflate_state *s;
16118 + int flush;
16119 +{
16120 + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
16121 + * to pending_buf_size, and each stored block has a 5 byte header:
16122 + */
16123 + ulg max_block_size = 0xffff;
16124 + ulg max_start;
16125 +
16126 + if (max_block_size > s->pending_buf_size - 5) {
16127 + max_block_size = s->pending_buf_size - 5;
16128 + }
16129 +
16130 + /* Copy as much as possible from input to output: */
16131 + for (;;) {
16132 + /* Fill the window as much as possible: */
16133 + if (s->lookahead <= 1) {
16134 +
16135 + Assert(s->strstart < s->w_size+MAX_DIST(s) ||
16136 + s->block_start >= (long)s->w_size, "slide too late");
16137 +
16138 + fill_window(s);
16139 + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
16140 +
16141 + if (s->lookahead == 0) break; /* flush the current block */
16142 + }
16143 + Assert(s->block_start >= 0L, "block gone");
16144 +
16145 + s->strstart += s->lookahead;
16146 + s->lookahead = 0;
16147 +
16148 + /* Emit a stored block if pending_buf will be full: */
16149 + max_start = s->block_start + max_block_size;
16150 + if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
16151 + /* strstart == 0 is possible when wraparound on 16-bit machine */
16152 + s->lookahead = (uInt)(s->strstart - max_start);
16153 + s->strstart = (uInt)max_start;
16154 + FLUSH_BLOCK(s, 0);
16155 + }
16156 + /* Flush if we may have to slide, otherwise block_start may become
16157 + * negative and the data will be gone:
16158 + */
16159 + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
16160 + FLUSH_BLOCK(s, 0);
16161 + }
16162 + }
16163 + FLUSH_BLOCK(s, flush == Z_FINISH);
16164 + return flush == Z_FINISH ? finish_done : block_done;
16165 +}
16166 +
16167 +/* ===========================================================================
16168 + * Compress as much as possible from the input stream, return the current
16169 + * block state.
16170 + * This function does not perform lazy evaluation of matches and inserts
16171 + * new strings in the dictionary only for unmatched strings or for short
16172 + * matches. It is used only for the fast compression options.
16173 + */
16174 +local block_state deflate_fast(s, flush)
16175 + deflate_state *s;
16176 + int flush;
16177 +{
16178 + IPos hash_head = NIL; /* head of the hash chain */
16179 + int bflush; /* set if current block must be flushed */
16180 +
16181 + for (;;) {
16182 + /* Make sure that we always have enough lookahead, except
16183 + * at the end of the input file. We need MAX_MATCH bytes
16184 + * for the next match, plus MIN_MATCH bytes to insert the
16185 + * string following the next match.
16186 + */
16187 + if (s->lookahead < MIN_LOOKAHEAD) {
16188 + fill_window(s);
16189 + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
16190 + return need_more;
16191 + }
16192 + if (s->lookahead == 0) break; /* flush the current block */
16193 + }
16194 +
16195 + /* Insert the string window[strstart .. strstart+2] in the
16196 + * dictionary, and set hash_head to the head of the hash chain:
16197 + */
16198 + if (s->lookahead >= MIN_MATCH) {
16199 + INSERT_STRING(s, s->strstart, hash_head);
16200 + }
16201 +
16202 + /* Find the longest match, discarding those <= prev_length.
16203 + * At this point we have always match_length < MIN_MATCH
16204 + */
16205 + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
16206 + /* To simplify the code, we prevent matches with the string
16207 + * of window index 0 (in particular we have to avoid a match
16208 + * of the string with itself at the start of the input file).
16209 + */
16210 + if (s->strategy != Z_HUFFMAN_ONLY) {
16211 + s->match_length = longest_match (s, hash_head);
16212 + }
16213 + /* longest_match() sets match_start */
16214 + }
16215 + if (s->match_length >= MIN_MATCH) {
16216 + check_match(s, s->strstart, s->match_start, s->match_length);
16217 +
16218 + _tr_tally_dist(s, s->strstart - s->match_start,
16219 + s->match_length - MIN_MATCH, bflush);
16220 +
16221 + s->lookahead -= s->match_length;
16222 +
16223 + /* Insert new strings in the hash table only if the match length
16224 + * is not too large. This saves time but degrades compression.
16225 + */
16226 +#ifndef FASTEST
16227 + if (s->match_length <= s->max_insert_length &&
16228 + s->lookahead >= MIN_MATCH) {
16229 + s->match_length--; /* string at strstart already in hash table */
16230 + do {
16231 + s->strstart++;
16232 + INSERT_STRING(s, s->strstart, hash_head);
16233 + /* strstart never exceeds WSIZE-MAX_MATCH, so there are
16234 + * always MIN_MATCH bytes ahead.
16235 + */
16236 + } while (--s->match_length != 0);
16237 + s->strstart++;
16238 + } else
16239 +#endif
16240 + {
16241 + s->strstart += s->match_length;
16242 + s->match_length = 0;
16243 + s->ins_h = s->window[s->strstart];
16244 + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
16245 +#if MIN_MATCH != 3
16246 + Call UPDATE_HASH() MIN_MATCH-3 more times
16247 +#endif
16248 + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
16249 + * matter since it will be recomputed at next deflate call.
16250 + */
16251 + }
16252 + } else {
16253 + /* No match, output a literal byte */
16254 + Tracevv((stderr,"%c", s->window[s->strstart]));
16255 + _tr_tally_lit (s, s->window[s->strstart], bflush);
16256 + s->lookahead--;
16257 + s->strstart++;
16258 + }
16259 + if (bflush) FLUSH_BLOCK(s, 0);
16260 + }
16261 + FLUSH_BLOCK(s, flush == Z_FINISH);
16262 + return flush == Z_FINISH ? finish_done : block_done;
16263 +}
16264 +
16265 +/* ===========================================================================
16266 + * Same as above, but achieves better compression. We use a lazy
16267 + * evaluation for matches: a match is finally adopted only if there is
16268 + * no better match at the next window position.
16269 + */
16270 +local block_state deflate_slow(s, flush)
16271 + deflate_state *s;
16272 + int flush;
16273 +{
16274 + IPos hash_head = NIL; /* head of hash chain */
16275 + int bflush; /* set if current block must be flushed */
16276 +
16277 + /* Process the input block. */
16278 + for (;;) {
16279 + /* Make sure that we always have enough lookahead, except
16280 + * at the end of the input file. We need MAX_MATCH bytes
16281 + * for the next match, plus MIN_MATCH bytes to insert the
16282 + * string following the next match.
16283 + */
16284 + if (s->lookahead < MIN_LOOKAHEAD) {
16285 + fill_window(s);
16286 + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
16287 + return need_more;
16288 + }
16289 + if (s->lookahead == 0) break; /* flush the current block */
16290 + }
16291 +
16292 + /* Insert the string window[strstart .. strstart+2] in the
16293 + * dictionary, and set hash_head to the head of the hash chain:
16294 + */
16295 + if (s->lookahead >= MIN_MATCH) {
16296 + INSERT_STRING(s, s->strstart, hash_head);
16297 + }
16298 +
16299 + /* Find the longest match, discarding those <= prev_length.
16300 + */
16301 + s->prev_length = s->match_length, s->prev_match = s->match_start;
16302 + s->match_length = MIN_MATCH-1;
16303 +
16304 + if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
16305 + s->strstart - hash_head <= MAX_DIST(s)) {
16306 + /* To simplify the code, we prevent matches with the string
16307 + * of window index 0 (in particular we have to avoid a match
16308 + * of the string with itself at the start of the input file).
16309 + */
16310 + if (s->strategy != Z_HUFFMAN_ONLY) {
16311 + s->match_length = longest_match (s, hash_head);
16312 + }
16313 + /* longest_match() sets match_start */
16314 +
16315 + if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
16316 + (s->match_length == MIN_MATCH &&
16317 + s->strstart - s->match_start > TOO_FAR))) {
16318 +
16319 + /* If prev_match is also MIN_MATCH, match_start is garbage
16320 + * but we will ignore the current match anyway.
16321 + */
16322 + s->match_length = MIN_MATCH-1;
16323 + }
16324 + }
16325 + /* If there was a match at the previous step and the current
16326 + * match is not better, output the previous match:
16327 + */
16328 + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
16329 + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
16330 + /* Do not insert strings in hash table beyond this. */
16331 +
16332 + check_match(s, s->strstart-1, s->prev_match, s->prev_length);
16333 +
16334 + _tr_tally_dist(s, s->strstart -1 - s->prev_match,
16335 + s->prev_length - MIN_MATCH, bflush);
16336 +
16337 + /* Insert in hash table all strings up to the end of the match.
16338 + * strstart-1 and strstart are already inserted. If there is not
16339 + * enough lookahead, the last two strings are not inserted in
16340 + * the hash table.
16341 + */
16342 + s->lookahead -= s->prev_length-1;
16343 + s->prev_length -= 2;
16344 + do {
16345 + if (++s->strstart <= max_insert) {
16346 + INSERT_STRING(s, s->strstart, hash_head);
16347 + }
16348 + } while (--s->prev_length != 0);
16349 + s->match_available = 0;
16350 + s->match_length = MIN_MATCH-1;
16351 + s->strstart++;
16352 +
16353 + if (bflush) FLUSH_BLOCK(s, 0);
16354 +
16355 + } else if (s->match_available) {
16356 + /* If there was no match at the previous position, output a
16357 + * single literal. If there was a match but the current match
16358 + * is longer, truncate the previous match to a single literal.
16359 + */
16360 + Tracevv((stderr,"%c", s->window[s->strstart-1]));
16361 + _tr_tally_lit(s, s->window[s->strstart-1], bflush);
16362 + if (bflush) {
16363 + FLUSH_BLOCK_ONLY(s, 0);
16364 + }
16365 + s->strstart++;
16366 + s->lookahead--;
16367 + if (s->strm->avail_out == 0) return need_more;
16368 + } else {
16369 + /* There is no previous match to compare with, wait for
16370 + * the next step to decide.
16371 + */
16372 + s->match_available = 1;
16373 + s->strstart++;
16374 + s->lookahead--;
16375 + }
16376 + }
16377 + Assert (flush != Z_NO_FLUSH, "no flush?");
16378 + if (s->match_available) {
16379 + Tracevv((stderr,"%c", s->window[s->strstart-1]));
16380 + _tr_tally_lit(s, s->window[s->strstart-1], bflush);
16381 + s->match_available = 0;
16382 + }
16383 + FLUSH_BLOCK(s, flush == Z_FINISH);
16384 + return flush == Z_FINISH ? finish_done : block_done;
16385 +}
16386 --- /dev/null Tue Mar 11 13:02:56 2003
16387 +++ linux/net/ipsec/deflate.h Mon Feb 9 13:51:03 2004
16388 @@ -0,0 +1,318 @@
16389 +/* deflate.h -- internal compression state
16390 + * Copyright (C) 1995-2002 Jean-loup Gailly
16391 + * For conditions of distribution and use, see copyright notice in zlib.h
16392 + */
16393 +
16394 +/* WARNING: this file should *not* be used by applications. It is
16395 + part of the implementation of the compression library and is
16396 + subject to change. Applications should only use zlib.h.
16397 + */
16398 +
16399 +/* @(#) $Id: deflate.h,v 1.5 2004/07/10 07:48:38 mcr Exp $ */
16400 +
16401 +#ifndef _DEFLATE_H
16402 +#define _DEFLATE_H
16403 +
16404 +#include "zlib/zutil.h"
16405 +
16406 +/* ===========================================================================
16407 + * Internal compression state.
16408 + */
16409 +
16410 +#define LENGTH_CODES 29
16411 +/* number of length codes, not counting the special END_BLOCK code */
16412 +
16413 +#define LITERALS 256
16414 +/* number of literal bytes 0..255 */
16415 +
16416 +#define L_CODES (LITERALS+1+LENGTH_CODES)
16417 +/* number of Literal or Length codes, including the END_BLOCK code */
16418 +
16419 +#define D_CODES 30
16420 +/* number of distance codes */
16421 +
16422 +#define BL_CODES 19
16423 +/* number of codes used to transfer the bit lengths */
16424 +
16425 +#define HEAP_SIZE (2*L_CODES+1)
16426 +/* maximum heap size */
16427 +
16428 +#define MAX_BITS 15
16429 +/* All codes must not exceed MAX_BITS bits */
16430 +
16431 +#define INIT_STATE 42
16432 +#define BUSY_STATE 113
16433 +#define FINISH_STATE 666
16434 +/* Stream status */
16435 +
16436 +
16437 +/* Data structure describing a single value and its code string. */
16438 +typedef struct ct_data_s {
16439 + union {
16440 + ush freq; /* frequency count */
16441 + ush code; /* bit string */
16442 + } fc;
16443 + union {
16444 + ush dad; /* father node in Huffman tree */
16445 + ush len; /* length of bit string */
16446 + } dl;
16447 +} FAR ct_data;
16448 +
16449 +#define Freq fc.freq
16450 +#define Code fc.code
16451 +#define Dad dl.dad
16452 +#define Len dl.len
16453 +
16454 +typedef struct static_tree_desc_s static_tree_desc;
16455 +
16456 +typedef struct tree_desc_s {
16457 + ct_data *dyn_tree; /* the dynamic tree */
16458 + int max_code; /* largest code with non zero frequency */
16459 + static_tree_desc *stat_desc; /* the corresponding static tree */
16460 +} FAR tree_desc;
16461 +
16462 +typedef ush Pos;
16463 +typedef Pos FAR Posf;
16464 +typedef unsigned IPos;
16465 +
16466 +/* A Pos is an index in the character window. We use short instead of int to
16467 + * save space in the various tables. IPos is used only for parameter passing.
16468 + */
16469 +
16470 +typedef struct internal_state {
16471 + z_streamp strm; /* pointer back to this zlib stream */
16472 + int status; /* as the name implies */
16473 + Bytef *pending_buf; /* output still pending */
16474 + ulg pending_buf_size; /* size of pending_buf */
16475 + Bytef *pending_out; /* next pending byte to output to the stream */
16476 + int pending; /* nb of bytes in the pending buffer */
16477 + int noheader; /* suppress zlib header and adler32 */
16478 + Byte data_type; /* UNKNOWN, BINARY or ASCII */
16479 + Byte method; /* STORED (for zip only) or DEFLATED */
16480 + int last_flush; /* value of flush param for previous deflate call */
16481 +
16482 + /* used by deflate.c: */
16483 +
16484 + uInt w_size; /* LZ77 window size (32K by default) */
16485 + uInt w_bits; /* log2(w_size) (8..16) */
16486 + uInt w_mask; /* w_size - 1 */
16487 +
16488 + Bytef *window;
16489 + /* Sliding window. Input bytes are read into the second half of the window,
16490 + * and move to the first half later to keep a dictionary of at least wSize
16491 + * bytes. With this organization, matches are limited to a distance of
16492 + * wSize-MAX_MATCH bytes, but this ensures that IO is always
16493 + * performed with a length multiple of the block size. Also, it limits
16494 + * the window size to 64K, which is quite useful on MSDOS.
16495 + * To do: use the user input buffer as sliding window.
16496 + */
16497 +
16498 + ulg window_size;
16499 + /* Actual size of window: 2*wSize, except when the user input buffer
16500 + * is directly used as sliding window.
16501 + */
16502 +
16503 + Posf *prev;
16504 + /* Link to older string with same hash index. To limit the size of this
16505 + * array to 64K, this link is maintained only for the last 32K strings.
16506 + * An index in this array is thus a window index modulo 32K.
16507 + */
16508 +
16509 + Posf *head; /* Heads of the hash chains or NIL. */
16510 +
16511 + uInt ins_h; /* hash index of string to be inserted */
16512 + uInt hash_size; /* number of elements in hash table */
16513 + uInt hash_bits; /* log2(hash_size) */
16514 + uInt hash_mask; /* hash_size-1 */
16515 +
16516 + uInt hash_shift;
16517 + /* Number of bits by which ins_h must be shifted at each input
16518 + * step. It must be such that after MIN_MATCH steps, the oldest
16519 + * byte no longer takes part in the hash key, that is:
16520 + * hash_shift * MIN_MATCH >= hash_bits
16521 + */
16522 +
16523 + long block_start;
16524 + /* Window position at the beginning of the current output block. Gets
16525 + * negative when the window is moved backwards.
16526 + */
16527 +
16528 + uInt match_length; /* length of best match */
16529 + IPos prev_match; /* previous match */
16530 + int match_available; /* set if previous match exists */
16531 + uInt strstart; /* start of string to insert */
16532 + uInt match_start; /* start of matching string */
16533 + uInt lookahead; /* number of valid bytes ahead in window */
16534 +
16535 + uInt prev_length;
16536 + /* Length of the best match at previous step. Matches not greater than this
16537 + * are discarded. This is used in the lazy match evaluation.
16538 + */
16539 +
16540 + uInt max_chain_length;
16541 + /* To speed up deflation, hash chains are never searched beyond this
16542 + * length. A higher limit improves compression ratio but degrades the
16543 + * speed.
16544 + */
16545 +
16546 + uInt max_lazy_match;
16547 + /* Attempt to find a better match only when the current match is strictly
16548 + * smaller than this value. This mechanism is used only for compression
16549 + * levels >= 4.
16550 + */
16551 +# define max_insert_length max_lazy_match
16552 + /* Insert new strings in the hash table only if the match length is not
16553 + * greater than this length. This saves time but degrades compression.
16554 + * max_insert_length is used only for compression levels <= 3.
16555 + */
16556 +
16557 + int level; /* compression level (1..9) */
16558 + int strategy; /* favor or force Huffman coding*/
16559 +
16560 + uInt good_match;
16561 + /* Use a faster search when the previous match is longer than this */
16562 +
16563 + int nice_match; /* Stop searching when current match exceeds this */
16564 +
16565 + /* used by trees.c: */
16566 + /* Didn't use ct_data typedef below to supress compiler warning */
16567 + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
16568 + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
16569 + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
16570 +
16571 + struct tree_desc_s l_desc; /* desc. for literal tree */
16572 + struct tree_desc_s d_desc; /* desc. for distance tree */
16573 + struct tree_desc_s bl_desc; /* desc. for bit length tree */
16574 +
16575 + ush bl_count[MAX_BITS+1];
16576 + /* number of codes at each bit length for an optimal tree */
16577 +
16578 + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
16579 + int heap_len; /* number of elements in the heap */
16580 + int heap_max; /* element of largest frequency */
16581 + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
16582 + * The same heap array is used to build all trees.
16583 + */
16584 +
16585 + uch depth[2*L_CODES+1];
16586 + /* Depth of each subtree used as tie breaker for trees of equal frequency
16587 + */
16588 +
16589 + uchf *l_buf; /* buffer for literals or lengths */
16590 +
16591 + uInt lit_bufsize;
16592 + /* Size of match buffer for literals/lengths. There are 4 reasons for
16593 + * limiting lit_bufsize to 64K:
16594 + * - frequencies can be kept in 16 bit counters
16595 + * - if compression is not successful for the first block, all input
16596 + * data is still in the window so we can still emit a stored block even
16597 + * when input comes from standard input. (This can also be done for
16598 + * all blocks if lit_bufsize is not greater than 32K.)
16599 + * - if compression is not successful for a file smaller than 64K, we can
16600 + * even emit a stored file instead of a stored block (saving 5 bytes).
16601 + * This is applicable only for zip (not gzip or zlib).
16602 + * - creating new Huffman trees less frequently may not provide fast
16603 + * adaptation to changes in the input data statistics. (Take for
16604 + * example a binary file with poorly compressible code followed by
16605 + * a highly compressible string table.) Smaller buffer sizes give
16606 + * fast adaptation but have of course the overhead of transmitting
16607 + * trees more frequently.
16608 + * - I can't count above 4
16609 + */
16610 +
16611 + uInt last_lit; /* running index in l_buf */
16612 +
16613 + ushf *d_buf;
16614 + /* Buffer for distances. To simplify the code, d_buf and l_buf have
16615 + * the same number of elements. To use different lengths, an extra flag
16616 + * array would be necessary.
16617 + */
16618 +
16619 + ulg opt_len; /* bit length of current block with optimal trees */
16620 + ulg static_len; /* bit length of current block with static trees */
16621 + uInt matches; /* number of string matches in current block */
16622 + int last_eob_len; /* bit length of EOB code for last block */
16623 +
16624 +#ifdef DEBUG
16625 + ulg compressed_len; /* total bit length of compressed file mod 2^32 */
16626 + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
16627 +#endif
16628 +
16629 + ush bi_buf;
16630 + /* Output buffer. bits are inserted starting at the bottom (least
16631 + * significant bits).
16632 + */
16633 + int bi_valid;
16634 + /* Number of valid bits in bi_buf. All bits above the last valid bit
16635 + * are always zero.
16636 + */
16637 +
16638 +} FAR deflate_state;
16639 +
16640 +/* Output a byte on the stream.
16641 + * IN assertion: there is enough room in pending_buf.
16642 + */
16643 +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
16644 +
16645 +
16646 +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
16647 +/* Minimum amount of lookahead, except at the end of the input file.
16648 + * See deflate.c for comments about the MIN_MATCH+1.
16649 + */
16650 +
16651 +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
16652 +/* In order to simplify the code, particularly on 16 bit machines, match
16653 + * distances are limited to MAX_DIST instead of WSIZE.
16654 + */
16655 +
16656 + /* in trees.c */
16657 +void _tr_init OF((deflate_state *s));
16658 +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
16659 +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
16660 + int eof));
16661 +void _tr_align OF((deflate_state *s));
16662 +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
16663 + int eof));
16664 +
16665 +#define d_code(dist) \
16666 + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
16667 +/* Mapping from a distance to a distance code. dist is the distance - 1 and
16668 + * must not have side effects. _dist_code[256] and _dist_code[257] are never
16669 + * used.
16670 + */
16671 +
16672 +#ifndef DEBUG
16673 +/* Inline versions of _tr_tally for speed: */
16674 +
16675 +#if defined(GEN_TREES_H) || !defined(STDC)
16676 + extern uch _length_code[];
16677 + extern uch _dist_code[];
16678 +#else
16679 + extern const uch _length_code[];
16680 + extern const uch _dist_code[];
16681 +#endif
16682 +
16683 +# define _tr_tally_lit(s, c, flush) \
16684 + { uch cc = (c); \
16685 + s->d_buf[s->last_lit] = 0; \
16686 + s->l_buf[s->last_lit++] = cc; \
16687 + s->dyn_ltree[cc].Freq++; \
16688 + flush = (s->last_lit == s->lit_bufsize-1); \
16689 + }
16690 +# define _tr_tally_dist(s, distance, length, flush) \
16691 + { uch len = (length); \
16692 + ush dist = (distance); \
16693 + s->d_buf[s->last_lit] = dist; \
16694 + s->l_buf[s->last_lit++] = len; \
16695 + dist--; \
16696 + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
16697 + s->dyn_dtree[d_code(dist)].Freq++; \
16698 + flush = (s->last_lit == s->lit_bufsize-1); \
16699 + }
16700 +#else
16701 +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
16702 +# define _tr_tally_dist(s, distance, length, flush) \
16703 + flush = _tr_tally(s, distance, length)
16704 +#endif
16705 +
16706 +#endif /* _DEFLATE_H */
16707 --- /dev/null Tue Mar 11 13:02:56 2003
16708 +++ linux/net/ipsec/des/COPYRIGHT Mon Feb 9 13:51:03 2004
16709 @@ -0,0 +1,50 @@
16710 +Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
16711 +All rights reserved.
16712 +
16713 +This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
16714 +The implementation was written so as to conform with MIT's libdes.
16715 +
16716 +This library is free for commercial and non-commercial use as long as
16717 +the following conditions are aheared to. The following conditions
16718 +apply to all code found in this distribution.
16719 +
16720 +Copyright remains Eric Young's, and as such any Copyright notices in
16721 +the code are not to be removed.
16722 +If this package is used in a product, Eric Young should be given attribution
16723 +as the author of that the SSL library. This can be in the form of a textual
16724 +message at program startup or in documentation (online or textual) provided
16725 +with the package.
16726 +
16727 +Redistribution and use in source and binary forms, with or without
16728 +modification, are permitted provided that the following conditions
16729 +are met:
16730 +1. Redistributions of source code must retain the copyright
16731 + notice, this list of conditions and the following disclaimer.
16732 +2. Redistributions in binary form must reproduce the above copyright
16733 + notice, this list of conditions and the following disclaimer in the
16734 + documentation and/or other materials provided with the distribution.
16735 +3. All advertising materials mentioning features or use of this software
16736 + must display the following acknowledgement:
16737 + This product includes software developed by Eric Young (eay@cryptsoft.com)
16738 +
16739 +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
16740 +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16741 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16742 +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
16743 +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16744 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
16745 +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
16746 +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
16747 +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
16748 +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16749 +SUCH DAMAGE.
16750 +
16751 +The license and distribution terms for any publically available version or
16752 +derivative of this code cannot be changed. i.e. this code cannot simply be
16753 +copied and put under another distrubution license
16754 +[including the GNU Public License.]
16755 +
16756 +The reason behind this being stated in this direct manner is past
16757 +experience in code simply being copied and the attribution removed
16758 +from it and then being distributed as part of other packages. This
16759 +implementation was a non-trivial and unpaid effort.
16760 --- /dev/null Tue Mar 11 13:02:56 2003
16761 +++ linux/net/ipsec/des/INSTALL Mon Feb 9 13:51:03 2004
16762 @@ -0,0 +1,69 @@
16763 +Check the CC and CFLAGS lines in the makefile
16764 +
16765 +If your C library does not support the times(3) function, change the
16766 +#define TIMES to
16767 +#undef TIMES in speed.c
16768 +If it does, check the HZ value for the times(3) function.
16769 +If your system does not define CLK_TCK it will be assumed to
16770 +be 100.0.
16771 +
16772 +If possible use gcc v 2.7.?
16773 +Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
16774 +In recent times, some system compilers give better performace.
16775 +
16776 +type 'make'
16777 +
16778 +run './destest' to check things are ok.
16779 +run './rpw' to check the tty code for reading passwords works.
16780 +run './speed' to see how fast those optimisations make the library run :-)
16781 +run './des_opts' to determin the best compile time options.
16782 +
16783 +The output from des_opts should be put in the makefile options and des_enc.c
16784 +should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
16785 +For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
16786 +and then you can use the 'DES_PTR' option.
16787 +
16788 +The file options.txt has the options listed for best speed on quite a
16789 +few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
16790 +turn on the relevent option in the Makefile
16791 +
16792 +There are some special Makefile targets that make life easier.
16793 +make cc - standard cc build
16794 +make gcc - standard gcc build
16795 +make x86-elf - x86 assembler (elf), linux-elf.
16796 +make x86-out - x86 assembler (a.out), FreeBSD
16797 +make x86-solaris- x86 assembler
16798 +make x86-bsdi - x86 assembler (a.out with primative assembler).
16799 +
16800 +If at all possible use the assembler (for Windows NT/95, use
16801 +asm/win32.obj to link with). The x86 assembler is very very fast.
16802 +
16803 +A make install will by default install
16804 +libdes.a in /usr/local/lib/libdes.a
16805 +des in /usr/local/bin/des
16806 +des_crypt.man in /usr/local/man/man3/des_crypt.3
16807 +des.man in /usr/local/man/man1/des.1
16808 +des.h in /usr/include/des.h
16809 +
16810 +des(1) should be compatible with sunOS's but I have been unable to
16811 +test it.
16812 +
16813 +These routines should compile on MSDOS, most 32bit and 64bit version
16814 +of Unix (BSD and SYSV) and VMS, without modification.
16815 +The only problems should be #include files that are in the wrong places.
16816 +
16817 +These routines can be compiled under MSDOS.
16818 +I have successfully encrypted files using des(1) under MSDOS and then
16819 +decrypted the files on a SparcStation.
16820 +I have been able to compile and test the routines with
16821 +Microsoft C v 5.1 and Turbo C v 2.0.
16822 +The code in this library is in no way optimised for the 16bit
16823 +operation of MSDOS.
16824 +
16825 +When building for glibc, ignore all of the above and just unpack into
16826 +glibc-1.??/des and then gmake as per normal.
16827 +
16828 +As a final note on performace. Certain CPUs like sparcs and Alpha often give
16829 +a %10 speed difference depending on the link order. It is rather anoying
16830 +when one program reports 'x' DES encrypts a second and another reports
16831 +'x*0.9' the speed.
16832 --- /dev/null Tue Mar 11 13:02:56 2003
16833 +++ linux/net/ipsec/des/Makefile Mon Feb 9 13:51:03 2004
16834 @@ -0,0 +1,63 @@
16835 +# Makefile for KLIPS kernel code as a module for 2.6 kernels
16836 +#
16837 +# Makefile for KLIPS kernel code as a module
16838 +# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
16839 +# Copyright (C) 2002-2004 Michael Richardson <mcr@freeswan.org>
16840 +#
16841 +# This program is free software; you can redistribute it and/or modify it
16842 +# under the terms of the GNU General Public License as published by the
16843 +# Free Software Foundation; either version 2 of the License, or (at your
16844 +# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16845 +#
16846 +# This program is distributed in the hope that it will be useful, but
16847 +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16848 +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16849 +# for more details.
16850 +#
16851 +# RCSID $Id: Makefile.fs2_6,v 1.2.2.1 2005/08/12 16:10:57 ken Exp $
16852 +#
16853 +# Note! Dependencies are done automagically by 'make dep', which also
16854 +# removes any old dependencies. DON'T put your own dependencies here
16855 +# unless it's something special (ie not a .c file).
16856 +#
16857 +
16858 +obj-$(CONFIG_KLIPS_ENC_3DES) += ipsec_alg_3des.o
16859 +obj-$(CONFIG_KLIPS_ENC_3DES) += cbc_enc.o
16860 +obj-$(CONFIG_KLIPS_ENC_3DES) += ecb_enc.o
16861 +obj-$(CONFIG_KLIPS_ENC_3DES) += set_key.o
16862 +
16863 +ifeq ($(strip ${SUBARCH}),)
16864 +SUBARCH:=${ARCH}
16865 +endif
16866 +
16867 +# the assembly version expects frame pointers, which are
16868 +# optional in many kernel builds. If you want speed, you should
16869 +# probably use cryptoapi code instead.
16870 +USEASSEMBLY=${SUBARCH}${CONFIG_FRAME_POINTER}
16871 +ifeq (${USEASSEMBLY},i386y)
16872 +obj-$(CONFIG_KLIPS_ENC_3DES) += dx86unix.o
16873 +else
16874 +obj-$(CONFIG_KLIPS_ENC_3DES) += des_enc.o
16875 +endif
16876 +
16877 +#
16878 +# $Log: Makefile.fs2_6,v $
16879 +# Revision 1.2.2.1 2005/08/12 16:10:57 ken
16880 +# do not use assembly code with there are no frame pointers
16881 +#
16882 +# Revision 1.3 2005/08/12 14:13:59 mcr
16883 +# do not use assembly code with there are no frame pointers,
16884 +# as it does not have the right linkages.
16885 +#
16886 +# Revision 1.2 2005/04/29 05:13:07 mcr
16887 +# 3DES algorithm code.
16888 +#
16889 +# Revision 1.1 2004/08/17 03:27:30 mcr
16890 +# klips 2.6 edits.
16891 +#
16892 +#
16893 +# Local Variables:
16894 +# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
16895 +# End Variables:
16896 +#
16897 +
16898 --- /dev/null Tue Mar 11 13:02:56 2003
16899 +++ linux/net/ipsec/des/README Mon Feb 9 13:51:03 2004
16900 @@ -0,0 +1,54 @@
16901 +
16902 + libdes, Version 4.01 10-Jan-97
16903 +
16904 + Copyright (c) 1997, Eric Young
16905 + All rights reserved.
16906 +
16907 + This program is free software; you can redistribute it and/or modify
16908 + it under the terms specified in COPYRIGHT.
16909 +
16910 +--
16911 +The primary ftp site for this library is
16912 +ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
16913 +libdes is now also shipped with SSLeay. Primary ftp site of
16914 +ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
16915 +
16916 +The best way to build this library is to build it as part of SSLeay.
16917 +
16918 +This kit builds a DES encryption library and a DES encryption program.
16919 +It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
16920 +triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
16921 +implementation of crypt(3).
16922 +It contains support routines to read keys from a terminal,
16923 +generate a random key, generate a key from an arbitrary length string,
16924 +read/write encrypted data from/to a file descriptor.
16925 +
16926 +The implementation was written so as to conform with the manual entry
16927 +for the des_crypt(3) library routines from MIT's project Athena.
16928 +
16929 +destest should be run after compilation to test the des routines.
16930 +rpw should be run after compilation to test the read password routines.
16931 +The des program is a replacement for the sun des command. I believe it
16932 +conforms to the sun version.
16933 +
16934 +The Imakefile is setup for use in the kerberos distribution.
16935 +
16936 +These routines are best compiled with gcc or any other good
16937 +optimising compiler.
16938 +Just turn you optimiser up to the highest settings and run destest
16939 +after the build to make sure everything works.
16940 +
16941 +I believe these routines are close to the fastest and most portable DES
16942 +routines that use small lookup tables (4.5k) that are publicly available.
16943 +The fcrypt routine is faster than ufc's fcrypt (when compiling with
16944 +gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
16945 +(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
16946 +[ 10-Jan-97 and a function of an incorrect speed testing program in
16947 + ufc which gave much better test figures that reality ].
16948 +
16949 +It is worth noting that on sparc and Alpha CPUs, performance of the DES
16950 +library can vary by upto %10 due to the positioning of files after application
16951 +linkage.
16952 +
16953 +Eric Young (eay@cryptsoft.com)
16954 +
16955 --- /dev/null Tue Mar 11 13:02:56 2003
16956 +++ linux/net/ipsec/des/README.freeswan Mon Feb 9 13:51:03 2004
16957 @@ -0,0 +1,33 @@
16958 +The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
16959 +
16960 +We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
16961 +on the Alpha, instead of just noting the issue in a comment.
16962 +
16963 +We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
16964 +use it, and its call to sprintf() can cause subtle difficulties when KLIPS
16965 +is built as a module (depending on details of Linux configuration options).
16966 +
16967 +We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
16968 +it cope better with Linux kernel Makefile stupidities, and took out an
16969 +explicit CC=gcc (unwise on systems with strange compilers).
16970 +
16971 +We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
16972 +of one function found only in the full libdes (not in libdes-lite), to
16973 +avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
16974 +Schultz for spotting this and pointing out the fixes.)
16975 +
16976 +We deleted a couple of .obj files in the asm subdirectory, which appear to
16977 +have been included in the original library by accident.
16978 +
16979 +We have added an include of our Makefile.inc file, to permit overriding
16980 +things like choice of compiler (although the libdes Makefile would
16981 +probably need some work to make this effective).
16982 +
16983 +
16984 +
16985 +Note that Eric Young is no longer at the email address listed in these
16986 +files, and is (alas) no longer working on free crypto software.
16987 +
16988 +
16989 +
16990 +This file is RCSID $Id: README.freeswan,v 1.12 2004/07/10 08:06:51 mcr Exp $
16991 --- /dev/null Tue Mar 11 13:02:56 2003
16992 +++ linux/net/ipsec/des/VERSION Mon Feb 9 13:51:03 2004
16993 @@ -0,0 +1,406 @@
16994 +Version 4.04
16995 + Fixed a few tests in destest. Also added x86 assember for
16996 + des_ncbc_encrypt() which is the standard cbc mode function.
16997 + This makes a very very large performace difference.
16998 + Ariel Glenn ariel@columbia.edu reports that the terminal
16999 + 'turn echo off' can return (errno == EINVAL) under solaris
17000 + when redirection is used. So I now catch that as well as ENOTTY.
17001 +
17002 +
17003 +Version 4.03
17004 + Left a static out of enc_write.c, which caused to buffer to be
17005 + continiously malloc()ed. Does anyone use these functions? I keep
17006 + on feeling like removing them since I only had these in there
17007 + for a version of kerberised login. Anyway, this was pointed out
17008 + by Theo de Raadt <deraadt@cvs.openbsd.org>
17009 + The 'n' bit ofb code was wrong, it was not shifting the shift
17010 + register. It worked correctly for n == 64. Thanks to
17011 + Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
17012 +
17013 +Version 4.02
17014 + I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
17015 + when checking for weak keys which is wrong :-(, pointed out by
17016 + Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
17017 +
17018 +Version 4.01
17019 + Even faster inner loop in the DES assembler for x86 and a modification
17020 + for IP/FP which is faster on x86. Both of these changes are
17021 + from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
17022 + changes make the assembler run %40 faster on a pentium. This is just
17023 + a case of getting the instruction sequence 'just right'.
17024 + All credit to 'Svend' :-)
17025 + Quite a few special x86 'make' targets.
17026 + A libdes-l (lite) distribution.
17027 +
17028 +Version 4.00
17029 + After a bit of a pause, I'll up the major version number since this
17030 + is mostly a performace release. I've added x86 assembler and
17031 + added more options for performance. A %28 speedup for gcc
17032 + on a pentium and the assembler is a %50 speedup.
17033 + MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
17034 + Run des_opts to work out which options should be used.
17035 + DES_RISC1/DES_RISC2 use alternative inner loops which use
17036 + more registers but should give speedups on any CPU that does
17037 + dual issue (pentium). DES_UNROLL unrolls the inner loop,
17038 + which costs in code size.
17039 +
17040 +Version 3.26
17041 + I've finally removed one of the shifts in D_ENCRYPT. This
17042 + meant I've changed the des_SPtrans table (spr.h), the set_key()
17043 + function and some things in des_enc.c. This has definitly
17044 + made things faster :-). I've known about this one for some
17045 + time but I've been too lazy to follow it up :-).
17046 + Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
17047 + instead of L^=((..)|(..)|(..).. This should save a register at
17048 + least.
17049 + Assember for x86. The file to replace is des_enc.c, which is replaced
17050 + by one of the assembler files found in asm. Look at des/asm/readme
17051 + for more info.
17052 +
17053 + /* Modification to fcrypt so it can be compiled to support
17054 + HPUX 10.x's long password format, define -DLONGCRYPT to use this.
17055 + Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
17056 +
17057 + SIGWINCH case put in des_read_passwd() so the function does not
17058 + 'exit' if this function is recieved.
17059 +
17060 +Version 3.25 17/07/96
17061 + Modified read_pwd.c so that stdin can be read if not a tty.
17062 + Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
17063 + des_init_random_number_generator() shortened due to VMS linker
17064 + limits.
17065 + Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
17066 + 8 byte quantites xored before and after encryption.
17067 + des_xcbc_encryption() - the name is funny to preserve the des_
17068 + prefix on all functions.
17069 +
17070 +Version 3.24 20/04/96
17071 + The DES_PTR macro option checked and used by SSLeay configuration
17072 +
17073 +Version 3.23 11/04/96
17074 + Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
17075 + it gives a %20 speedup :-)
17076 + Fixed the problem with des.pl under perl5. The patches were
17077 + sent by Ed Kubaitis (ejk@uiuc.edu).
17078 + if fcrypt.c, changed values to handle illegal salt values the way
17079 + normal crypt() implementations do. Some programs apparently use
17080 + them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
17081 +
17082 +Version 3.22 29/11/95
17083 + Bug in des(1), an error with the uuencoding stuff when the
17084 + 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
17085 + for the patch.
17086 +
17087 +Version 3.21 22/11/95
17088 + After some emailing back and forth with
17089 + Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
17090 + and in a future version I will probably put in some of the
17091 + optimisation he suggested for use with the DES_USE_PTR option.
17092 + Extra routines from Mark Murray <mark@grondar.za> for use in
17093 + freeBSD. They mostly involve random number generation for use
17094 + with kerberos. They involve evil machine specific system calls
17095 + etc so I would normally suggest pushing this stuff into the
17096 + application and/or using RAND_seed()/RAND_bytes() if you are
17097 + using this DES library as part of SSLeay.
17098 + Redone the read_pw() function so that it is cleaner and
17099 + supports termios, thanks to Sameer Parekh <sameer@c2.org>
17100 + for the initial patches for this.
17101 + Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
17102 + done just to make things more consistent.
17103 + I have also now added triple DES versions of cfb and ofb.
17104 +
17105 +Version 3.20
17106 + Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
17107 + my des_random_seed() function was only copying 4 bytes of the
17108 + passed seed into the init structure. It is now fixed to copy 8.
17109 + My own suggestion is to used something like MD5 :-)
17110 +
17111 +Version 3.19
17112 + While looking at my code one day, I though, why do I keep on
17113 + calling des_encrypt(in,out,ks,enc) when every function that
17114 + calls it has in and out the same. So I dropped the 'out'
17115 + parameter, people should not be using this function.
17116 +
17117 +Version 3.18 30/08/95
17118 + Fixed a few bit with the distribution and the filenames.
17119 + 3.17 had been munged via a move to DOS and back again.
17120 + NO CODE CHANGES
17121 +
17122 +Version 3.17 14/07/95
17123 + Fixed ede3 cbc which I had broken in 3.16. I have also
17124 + removed some unneeded variables in 7-8 of the routines.
17125 +
17126 +Version 3.16 26/06/95
17127 + Added des_encrypt2() which does not use IP/FP, used by triple
17128 + des routines. Tweaked things a bit elsewhere. %13 speedup on
17129 + sparc and %6 on a R4400 for ede3 cbc mode.
17130 +
17131 +Version 3.15 06/06/95
17132 + Added des_ncbc_encrypt(), it is des_cbc mode except that it is
17133 + 'normal' and copies the new iv value back over the top of the
17134 + passed parameter.
17135 + CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
17136 + the iv. THIS WILL BREAK EXISTING CODE, but since this function
17137 + only new, I feel I can change it, not so with des_cbc_encrypt :-(.
17138 + I need to update the documentation.
17139 +
17140 +Version 3.14 31/05/95
17141 + New release upon the world, as part of my SSL implementation.
17142 + New copyright and usage stuff. Basically free for all to use
17143 + as long as you say it came from me :-)
17144 +
17145 +Version 3.13 31/05/95
17146 + A fix in speed.c, if HZ is not defined, I set it to 100.0
17147 + which is reasonable for most unixes except SunOS 4.x.
17148 + I now have a #ifdef sun but timing for SunOS 4.x looked very
17149 + good :-(. At my last job where I used SunOS 4.x, it was
17150 + defined to be 60.0 (look at the old INSTALL documentation), at
17151 + the last release had it changed to 100.0 since I now work with
17152 + Solaris2 and SVR4 boxes.
17153 + Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
17154 + one out.
17155 +
17156 +Version 3.12 08/05/95
17157 + As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
17158 + my D_ENCRYPT macro in crypt() had an un-necessary variable.
17159 + It has been removed.
17160 +
17161 +Version 3.11 03/05/95
17162 + Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
17163 + and one iv. It is a standard and I needed it for my SSL code.
17164 + It makes more sense to use this for triple DES than
17165 + 3cbc_encrypt(). I have also added (or should I say tested :-)
17166 + cfb64_encrypt() which is cfb64 but it will encrypt a partial
17167 + number of bytes - 3 bytes in 3 bytes out. Again this is for
17168 + my SSL library, as a form of encryption to use with SSL
17169 + telnet.
17170 +
17171 +Version 3.10 22/03/95
17172 + Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
17173 + to cbc3_encrypt, the 2 iv values that were being returned to
17174 + be used in the next call were reversed :-(.
17175 + Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
17176 + this error.
17177 +
17178 +Version 3.09 01/02/95
17179 + Fixed des_random_key to far more random, it was rather feeble
17180 + with regards to picking the initial seed. The problem was
17181 + pointed out by Olaf Kirch <okir@monad.swb.de>.
17182 +
17183 +Version 3.08 14/12/94
17184 + Added Makefile.PL so libdes can be built into perl5.
17185 + Changed des_locl.h so RAND is always defined.
17186 +
17187 +Version 3.07 05/12/94
17188 + Added GNUmake and stuff so the library can be build with
17189 + glibc.
17190 +
17191 +Version 3.06 30/08/94
17192 + Added rpc_enc.c which contains _des_crypt. This is for use in
17193 + secure_rpc v 4.0
17194 + Finally fixed the cfb_enc problems.
17195 + Fixed a few parameter parsing bugs in des (-3 and -b), thanks
17196 + to Rob McMillan <R.McMillan@its.gu.edu.au>
17197 +
17198 +Version 3.05 21/04/94
17199 + for unsigned long l; gcc does not produce ((l>>34) == 0)
17200 + This causes bugs in cfb_enc.
17201 + Thanks to Hadmut Danisch <danisch@ira.uka.de>
17202 +
17203 +Version 3.04 20/04/94
17204 + Added a version number to des.c and libdes.a
17205 +
17206 +Version 3.03 12/01/94
17207 + Fixed a bug in non zero iv in 3cbc_enc.
17208 +
17209 +Version 3.02 29/10/93
17210 + I now work in a place where there are 6+ architectures and 14+
17211 + OS versions :-).
17212 + Fixed TERMIO definition so the most sys V boxes will work :-)
17213 +
17214 +Release upon comp.sources.misc
17215 +Version 3.01 08/10/93
17216 + Added des_3cbc_encrypt()
17217 +
17218 +Version 3.00 07/10/93
17219 + Fixed up documentation.
17220 + quad_cksum definitely compatible with MIT's now.
17221 +
17222 +Version 2.30 24/08/93
17223 + Triple DES now defaults to triple cbc but can do triple ecb
17224 + with the -b flag.
17225 + Fixed some MSDOS uuen/uudecoding problems, thanks to
17226 + Added prototypes.
17227 +
17228 +Version 2.22 29/06/93
17229 + Fixed a bug in des_is_weak_key() which stopped it working :-(
17230 + thanks to engineering@MorningStar.Com.
17231 +
17232 +Version 2.21 03/06/93
17233 + des(1) with no arguments gives quite a bit of help.
17234 + Added -c (generate ckecksum) flag to des(1).
17235 + Added -3 (triple DES) flag to des(1).
17236 + Added cfb and ofb routines to the library.
17237 +
17238 +Version 2.20 11/03/93
17239 + Added -u (uuencode) flag to des(1).
17240 + I have been playing with byte order in quad_cksum to make it
17241 + compatible with MIT's version. All I can say is avid this
17242 + function if possible since MIT's output is endian dependent.
17243 +
17244 +Version 2.12 14/10/92
17245 + Added MSDOS specific macro in ecb_encrypt which gives a %70
17246 + speed up when the code is compiled with turbo C.
17247 +
17248 +Version 2.11 12/10/92
17249 + Speedup in set_key (recoding of PC-1)
17250 + I now do it in 47 simple operations, down from 60.
17251 + Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
17252 + for motivating me to look for a faster system :-)
17253 + The speedup is probably less that 1% but it is still 13
17254 + instructions less :-).
17255 +
17256 +Version 2.10 06/10/92
17257 + The code now works on the 64bit ETA10 and CRAY without modifications or
17258 + #defines. I believe the code should work on any machine that
17259 + defines long, int or short to be 8 bytes long.
17260 + Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
17261 + for helping me fix the code to run on 64bit machines (he had
17262 + access to an ETA10).
17263 + Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
17264 + for testing the routines on a CRAY.
17265 + read_password.c has been renamed to read_passwd.c
17266 + string_to_key.c has been renamed to string2key.c
17267 +
17268 +Version 2.00 14/09/92
17269 + Made mods so that the library should work on 64bit CPU's.
17270 + Removed all my uchar and ulong defs. To many different
17271 + versions of unix define them in their header files in too many
17272 + different combinations :-)
17273 + IRIX - Sillicon Graphics mods (mostly in read_password.c).
17274 + Thanks to Andrew Daviel (advax@erich.triumf.ca)
17275 +
17276 +Version 1.99 26/08/92
17277 + Fixed a bug or 2 in enc_read.c
17278 + Fixed a bug in enc_write.c
17279 + Fixed a pseudo bug in fcrypt.c (very obscure).
17280 +
17281 +Version 1.98 31/07/92
17282 + Support for the ETA10. This is a strange machine that defines
17283 + longs and ints as 8 bytes and shorts as 4 bytes.
17284 + Since I do evil things with long * that assume that they are 4
17285 + bytes. Look in the Makefile for the option to compile for
17286 + this machine. quad_cksum appears to have problems but I
17287 + will don't have the time to fix it right now, and this is not
17288 + a function that uses DES and so will not effect the main uses
17289 + of the library.
17290 +
17291 +Version 1.97 20/05/92 eay
17292 + Fixed the Imakefile and made some changes to des.h to fix some
17293 + problems when building this package with Kerberos v 4.
17294 +
17295 +Version 1.96 18/05/92 eay
17296 + Fixed a small bug in string_to_key() where problems could
17297 + occur if des_check_key was set to true and the string
17298 + generated a weak key.
17299 +
17300 +Patch2 posted to comp.sources.misc
17301 +Version 1.95 13/05/92 eay
17302 + Added an alternative version of the D_ENCRYPT macro in
17303 + ecb_encrypt and fcrypt. Depending on the compiler, one version or the
17304 + other will be faster. This was inspired by
17305 + Dana How <how@isl.stanford.edu>, and her pointers about doing the
17306 + *(ulong *)((uchar *)ptr+(value&0xfc))
17307 + vs
17308 + ptr[value&0x3f]
17309 + to stop the C compiler doing a <<2 to convert the long array index.
17310 +
17311 +Version 1.94 05/05/92 eay
17312 + Fixed an incompatibility between my string_to_key and the MIT
17313 + version. When the key is longer than 8 chars, I was wrapping
17314 + with a different method. To use the old version, define
17315 + OLD_STR_TO_KEY in the makefile. Thanks to
17316 + viktor@newsu.shearson.com (Viktor Dukhovni).
17317 +
17318 +Version 1.93 28/04/92 eay
17319 + Fixed the VMS mods so that echo is now turned off in
17320 + read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
17321 + MSDOS support added. The routines can be compiled with
17322 + Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
17323 +
17324 +Patch1 posted to comp.sources.misc
17325 +Version 1.92 13/04/92 eay
17326 + Changed D_ENCRYPT so that the rotation of R occurs outside of
17327 + the loop. This required rotating all the longs in sp.h (now
17328 + called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
17329 + speed.c has been changed so it will work without SIGALRM. If
17330 + times(3) is not present it will try to use ftime() instead.
17331 +
17332 +Version 1.91 08/04/92 eay
17333 + Added -E/-D options to des(1) so it can use string_to_key.
17334 + Added SVR4 mods suggested by witr@rwwa.COM
17335 + Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
17336 + anyone knows how to turn of tty echo in VMS please tell me or
17337 + implement it yourself :-).
17338 + Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
17339 + does not like IN/OUT being used.
17340 +
17341 +Libdes posted to comp.sources.misc
17342 +Version 1.9 24/03/92 eay
17343 + Now contains a fast small crypt replacement.
17344 + Added des(1) command.
17345 + Added des_rw_mode so people can use cbc encryption with
17346 + enc_read and enc_write.
17347 +
17348 +Version 1.8 15/10/91 eay
17349 + Bug in cbc_cksum.
17350 + Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
17351 + one out.
17352 +
17353 +Version 1.7 24/09/91 eay
17354 + Fixed set_key :-)
17355 + set_key is 4 times faster and takes less space.
17356 + There are a few minor changes that could be made.
17357 +
17358 +Version 1.6 19/09/1991 eay
17359 + Finally go IP and FP finished.
17360 + Now I need to fix set_key.
17361 + This version is quite a bit faster that 1.51
17362 +
17363 +Version 1.52 15/06/1991 eay
17364 + 20% speedup in ecb_encrypt by changing the E bit selection
17365 + to use 2 32bit words. This also required modification of the
17366 + sp table. There is still a way to speedup the IP and IP-1
17367 + (hints from outer@sq.com) still working on this one :-(.
17368 +
17369 +Version 1.51 07/06/1991 eay
17370 + Faster des_encrypt by loop unrolling
17371 + Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
17372 +
17373 +Version 1.50 28/05/1991 eay
17374 + Optimised the code a bit more for the sparc. I have improved the
17375 + speed of the inner des_encrypt by speeding up the initial and
17376 + final permutations.
17377 +
17378 +Version 1.40 23/10/1990 eay
17379 + Fixed des_random_key, it did not produce a random key :-(
17380 +
17381 +Version 1.30 2/10/1990 eay
17382 + Have made des_quad_cksum the same as MIT's, the full package
17383 + should be compatible with MIT's
17384 + Have tested on a DECstation 3100
17385 + Still need to fix des_set_key (make it faster).
17386 + Does des_cbc_encrypts at 70.5k/sec on a 3100.
17387 +
17388 +Version 1.20 18/09/1990 eay
17389 + Fixed byte order dependencies.
17390 + Fixed (I hope) all the word alignment problems.
17391 + Speedup in des_ecb_encrypt.
17392 +
17393 +Version 1.10 11/09/1990 eay
17394 + Added des_enc_read and des_enc_write.
17395 + Still need to fix des_quad_cksum.
17396 + Still need to document des_enc_read and des_enc_write.
17397 +
17398 +Version 1.00 27/08/1990 eay
17399 +
17400 --- /dev/null Tue Mar 11 13:02:56 2003
17401 +++ linux/net/ipsec/des/asm/des-586.pl Mon Feb 9 13:51:03 2004
17402 @@ -0,0 +1,251 @@
17403 +#!/usr/local/bin/perl
17404 +#
17405 +# The inner loop instruction sequence and the IP/FP modifications are from
17406 +# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
17407 +#
17408 +
17409 +push(@INC,"perlasm","../../perlasm");
17410 +require "x86asm.pl";
17411 +require "cbc.pl";
17412 +require "desboth.pl";
17413 +
17414 +# base code is in microsft
17415 +# op dest, source
17416 +# format.
17417 +#
17418 +
17419 +&asm_init($ARGV[0],"des-586.pl");
17420 +
17421 +$L="edi";
17422 +$R="esi";
17423 +
17424 +&external_label("des_SPtrans");
17425 +&des_encrypt("des_encrypt",1);
17426 +&des_encrypt("des_encrypt2",0);
17427 +&des_encrypt3("des_encrypt3",1);
17428 +&des_encrypt3("des_decrypt3",0);
17429 +&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
17430 +&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
17431 +
17432 +&asm_finish();
17433 +
17434 +sub des_encrypt
17435 + {
17436 + local($name,$do_ip)=@_;
17437 +
17438 + &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
17439 +
17440 + &push("esi");
17441 + &push("edi");
17442 +
17443 + &comment("");
17444 + &comment("Load the 2 words");
17445 + $ks="ebp";
17446 +
17447 + if ($do_ip)
17448 + {
17449 + &mov($R,&wparam(0));
17450 + &xor( "ecx", "ecx" );
17451 +
17452 + &push("ebx");
17453 + &push("ebp");
17454 +
17455 + &mov("eax",&DWP(0,$R,"",0));
17456 + &mov("ebx",&wparam(2)); # get encrypt flag
17457 + &mov($L,&DWP(4,$R,"",0));
17458 + &comment("");
17459 + &comment("IP");
17460 + &IP_new("eax",$L,$R,3);
17461 + }
17462 + else
17463 + {
17464 + &mov("eax",&wparam(0));
17465 + &xor( "ecx", "ecx" );
17466 +
17467 + &push("ebx");
17468 + &push("ebp");
17469 +
17470 + &mov($R,&DWP(0,"eax","",0));
17471 + &mov("ebx",&wparam(2)); # get encrypt flag
17472 + &rotl($R,3);
17473 + &mov($L,&DWP(4,"eax","",0));
17474 + &rotl($L,3);
17475 + }
17476 +
17477 + &mov( $ks, &wparam(1) );
17478 + &cmp("ebx","0");
17479 + &je(&label("start_decrypt"));
17480 +
17481 + for ($i=0; $i<16; $i+=2)
17482 + {
17483 + &comment("");
17484 + &comment("Round $i");
17485 + &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17486 +
17487 + &comment("");
17488 + &comment("Round ".sprintf("%d",$i+1));
17489 + &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17490 + }
17491 + &jmp(&label("end"));
17492 +
17493 + &set_label("start_decrypt");
17494 +
17495 + for ($i=15; $i>0; $i-=2)
17496 + {
17497 + &comment("");
17498 + &comment("Round $i");
17499 + &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17500 + &comment("");
17501 + &comment("Round ".sprintf("%d",$i-1));
17502 + &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
17503 + }
17504 +
17505 + &set_label("end");
17506 +
17507 + if ($do_ip)
17508 + {
17509 + &comment("");
17510 + &comment("FP");
17511 + &mov("edx",&wparam(0));
17512 + &FP_new($L,$R,"eax",3);
17513 +
17514 + &mov(&DWP(0,"edx","",0),"eax");
17515 + &mov(&DWP(4,"edx","",0),$R);
17516 + }
17517 + else
17518 + {
17519 + &comment("");
17520 + &comment("Fixup");
17521 + &rotr($L,3); # r
17522 + &mov("eax",&wparam(0));
17523 + &rotr($R,3); # l
17524 + &mov(&DWP(0,"eax","",0),$L);
17525 + &mov(&DWP(4,"eax","",0),$R);
17526 + }
17527 +
17528 + &pop("ebp");
17529 + &pop("ebx");
17530 + &pop("edi");
17531 + &pop("esi");
17532 + &ret();
17533 +
17534 + &function_end_B($name);
17535 + }
17536 +
17537 +sub D_ENCRYPT
17538 + {
17539 + local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
17540 +
17541 + &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17542 + &xor( $tmp1, $tmp1);
17543 + &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17544 + &xor( $u, $R);
17545 + &xor( $t, $R);
17546 + &and( $u, "0xfcfcfcfc" );
17547 + &and( $t, "0xcfcfcfcf" );
17548 + &movb( &LB($tmp1), &LB($u) );
17549 + &movb( &LB($tmp2), &HB($u) );
17550 + &rotr( $t, 4 );
17551 + &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
17552 + &movb( &LB($tmp1), &LB($t) );
17553 + &xor( $L, $ks);
17554 + &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
17555 + &xor( $L, $ks); ######
17556 + &movb( &LB($tmp2), &HB($t) );
17557 + &shr( $u, 16);
17558 + &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
17559 + &xor( $L, $ks); ######
17560 + &movb( &LB($tmp1), &HB($u) );
17561 + &shr( $t, 16);
17562 + &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
17563 + &xor( $L, $ks);
17564 + &mov( $ks, &wparam(1) );
17565 + &movb( &LB($tmp2), &HB($t) );
17566 + &and( $u, "0xff" );
17567 + &and( $t, "0xff" );
17568 + &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
17569 + &xor( $L, $tmp1);
17570 + &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
17571 + &xor( $L, $tmp1);
17572 + &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
17573 + &xor( $L, $tmp1);
17574 + &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
17575 + &xor( $L, $tmp1);
17576 + }
17577 +
17578 +sub n2a
17579 + {
17580 + sprintf("%d",$_[0]);
17581 + }
17582 +
17583 +# now has a side affect of rotating $a by $shift
17584 +sub R_PERM_OP
17585 + {
17586 + local($a,$b,$tt,$shift,$mask,$last)=@_;
17587 +
17588 + &rotl( $a, $shift ) if ($shift != 0);
17589 + &mov( $tt, $a );
17590 + &xor( $a, $b );
17591 + &and( $a, $mask );
17592 + if (!$last eq $b)
17593 + {
17594 + &xor( $b, $a );
17595 + &xor( $tt, $a );
17596 + }
17597 + else
17598 + {
17599 + &xor( $tt, $a );
17600 + &xor( $b, $a );
17601 + }
17602 + &comment("");
17603 + }
17604 +
17605 +sub IP_new
17606 + {
17607 + local($l,$r,$tt,$lr)=@_;
17608 +
17609 + &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
17610 + &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
17611 + &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
17612 + &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
17613 + &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
17614 +
17615 + if ($lr != 3)
17616 + {
17617 + if (($lr-3) < 0)
17618 + { &rotr($tt, 3-$lr); }
17619 + else { &rotl($tt, $lr-3); }
17620 + }
17621 + if ($lr != 2)
17622 + {
17623 + if (($lr-2) < 0)
17624 + { &rotr($r, 2-$lr); }
17625 + else { &rotl($r, $lr-2); }
17626 + }
17627 + }
17628 +
17629 +sub FP_new
17630 + {
17631 + local($l,$r,$tt,$lr)=@_;
17632 +
17633 + if ($lr != 2)
17634 + {
17635 + if (($lr-2) < 0)
17636 + { &rotl($r, 2-$lr); }
17637 + else { &rotr($r, $lr-2); }
17638 + }
17639 + if ($lr != 3)
17640 + {
17641 + if (($lr-3) < 0)
17642 + { &rotl($l, 3-$lr); }
17643 + else { &rotr($l, $lr-3); }
17644 + }
17645 +
17646 + &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
17647 + &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
17648 + &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
17649 + &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
17650 + &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
17651 + &rotr($tt , 4);
17652 + }
17653 +
17654 --- /dev/null Tue Mar 11 13:02:56 2003
17655 +++ linux/net/ipsec/des/asm/des686.pl Mon Feb 9 13:51:03 2004
17656 @@ -0,0 +1,230 @@
17657 +#!/usr/local/bin/perl
17658 +
17659 +$prog="des686.pl";
17660 +
17661 +# base code is in microsft
17662 +# op dest, source
17663 +# format.
17664 +#
17665 +
17666 +# WILL NOT WORK ANYMORE WITH desboth.pl
17667 +require "desboth.pl";
17668 +
17669 +if ( ($ARGV[0] eq "elf"))
17670 + { require "x86unix.pl"; }
17671 +elsif ( ($ARGV[0] eq "a.out"))
17672 + { $aout=1; require "x86unix.pl"; }
17673 +elsif ( ($ARGV[0] eq "sol"))
17674 + { $sol=1; require "x86unix.pl"; }
17675 +elsif ( ($ARGV[0] eq "cpp"))
17676 + { $cpp=1; require "x86unix.pl"; }
17677 +elsif ( ($ARGV[0] eq "win32"))
17678 + { require "x86ms.pl"; }
17679 +else
17680 + {
17681 + print STDERR <<"EOF";
17682 +Pick one target type from
17683 + elf - linux, FreeBSD etc
17684 + a.out - old linux
17685 + sol - x86 solaris
17686 + cpp - format so x86unix.cpp can be used
17687 + win32 - Windows 95/Windows NT
17688 +EOF
17689 + exit(1);
17690 + }
17691 +
17692 +&comment("Don't even think of reading this code");
17693 +&comment("It was automatically generated by $prog");
17694 +&comment("Which is a perl program used to generate the x86 assember for");
17695 +&comment("any of elf, a.out, Win32, or Solaris");
17696 +&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
17697 +&comment("eric <eay\@cryptsoft.com>");
17698 +&comment("");
17699 +
17700 +&file("dx86xxxx");
17701 +
17702 +$L="edi";
17703 +$R="esi";
17704 +
17705 +&des_encrypt("des_encrypt",1);
17706 +&des_encrypt("des_encrypt2",0);
17707 +
17708 +&des_encrypt3("des_encrypt3",1);
17709 +&des_encrypt3("des_decrypt3",0);
17710 +
17711 +&file_end();
17712 +
17713 +sub des_encrypt
17714 + {
17715 + local($name,$do_ip)=@_;
17716 +
17717 + &function_begin($name,"EXTRN _des_SPtrans:DWORD");
17718 +
17719 + &comment("");
17720 + &comment("Load the 2 words");
17721 + &mov("eax",&wparam(0));
17722 + &mov($L,&DWP(0,"eax","",0));
17723 + &mov($R,&DWP(4,"eax","",0));
17724 +
17725 + $ksp=&wparam(1);
17726 +
17727 + if ($do_ip)
17728 + {
17729 + &comment("");
17730 + &comment("IP");
17731 + &IP_new($L,$R,"eax");
17732 + }
17733 +
17734 + &comment("");
17735 + &comment("fixup rotate");
17736 + &rotl($R,3);
17737 + &rotl($L,3);
17738 + &exch($L,$R);
17739 +
17740 + &comment("");
17741 + &comment("load counter, key_schedule and enc flag");
17742 + &mov("eax",&wparam(2)); # get encrypt flag
17743 + &mov("ebp",&wparam(1)); # get ks
17744 + &cmp("eax","0");
17745 + &je(&label("start_decrypt"));
17746 +
17747 + # encrypting part
17748 +
17749 + for ($i=0; $i<16; $i+=2)
17750 + {
17751 + &comment("");
17752 + &comment("Round $i");
17753 + &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17754 +
17755 + &comment("");
17756 + &comment("Round ".sprintf("%d",$i+1));
17757 + &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17758 + }
17759 + &jmp(&label("end"));
17760 +
17761 + &set_label("start_decrypt");
17762 +
17763 + for ($i=15; $i>0; $i-=2)
17764 + {
17765 + &comment("");
17766 + &comment("Round $i");
17767 + &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17768 + &comment("");
17769 + &comment("Round ".sprintf("%d",$i-1));
17770 + &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
17771 + }
17772 +
17773 + &set_label("end");
17774 +
17775 + &comment("");
17776 + &comment("Fixup");
17777 + &rotr($L,3); # r
17778 + &rotr($R,3); # l
17779 +
17780 + if ($do_ip)
17781 + {
17782 + &comment("");
17783 + &comment("FP");
17784 + &FP_new($R,$L,"eax");
17785 + }
17786 +
17787 + &mov("eax",&wparam(0));
17788 + &mov(&DWP(0,"eax","",0),$L);
17789 + &mov(&DWP(4,"eax","",0),$R);
17790 +
17791 + &function_end($name);
17792 + }
17793 +
17794 +
17795 +# The logic is to load R into 2 registers and operate on both at the same time.
17796 +# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
17797 +# while also masking the other copy and doing a lookup. We then also accumulate the
17798 +# L value in 2 registers then combine them at the end.
17799 +sub D_ENCRYPT
17800 + {
17801 + local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
17802 +
17803 + &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
17804 + &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
17805 + &xor( $u, $R );
17806 + &xor( $t, $R );
17807 + &rotr( $t, 4 );
17808 +
17809 + # the numbers at the end of the line are origional instruction order
17810 + &mov( $tmp2, $u ); # 1 2
17811 + &mov( $tmp1, $t ); # 1 1
17812 + &and( $tmp2, "0xfc" ); # 1 4
17813 + &and( $tmp1, "0xfc" ); # 1 3
17814 + &shr( $t, 8 ); # 1 5
17815 + &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
17816 + &shr( $u, 8 ); # 1 6
17817 + &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
17818 +
17819 + &mov( $tmp2, $u ); # 2 2
17820 + &xor( $L, $tmp1 ); # 1 9
17821 + &and( $tmp2, "0xfc" ); # 2 4
17822 + &mov( $tmp1, $t ); # 2 1
17823 + &and( $tmp1, "0xfc" ); # 2 3
17824 + &shr( $t, 8 ); # 2 5
17825 + &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
17826 + &shr( $u, 8 ); # 2 6
17827 + &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
17828 + &mov( $tmp2, $u ); # 3 2
17829 +
17830 + &xor( $L, $tmp1 ); # 2 9
17831 + &and( $tmp2, "0xfc" ); # 3 4
17832 +
17833 + &mov( $tmp1, $t ); # 3 1
17834 + &shr( $u, 8 ); # 3 6
17835 + &and( $tmp1, "0xfc" ); # 3 3
17836 + &shr( $t, 8 ); # 3 5
17837 + &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
17838 + &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
17839 +
17840 + &and( $t, "0xfc" ); # 4 1
17841 + &xor( $L, $tmp1 ); # 3 9
17842 +
17843 + &and( $u, "0xfc" ); # 4 2
17844 + &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
17845 + &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
17846 + }
17847 +
17848 +sub PERM_OP
17849 + {
17850 + local($a,$b,$tt,$shift,$mask)=@_;
17851 +
17852 + &mov( $tt, $a );
17853 + &shr( $tt, $shift );
17854 + &xor( $tt, $b );
17855 + &and( $tt, $mask );
17856 + &xor( $b, $tt );
17857 + &shl( $tt, $shift );
17858 + &xor( $a, $tt );
17859 + }
17860 +
17861 +sub IP_new
17862 + {
17863 + local($l,$r,$tt)=@_;
17864 +
17865 + &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
17866 + &PERM_OP($l,$r,$tt,16,"0x0000ffff");
17867 + &PERM_OP($r,$l,$tt, 2,"0x33333333");
17868 + &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
17869 + &PERM_OP($r,$l,$tt, 1,"0x55555555");
17870 + }
17871 +
17872 +sub FP_new
17873 + {
17874 + local($l,$r,$tt)=@_;
17875 +
17876 + &PERM_OP($l,$r,$tt, 1,"0x55555555");
17877 + &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
17878 + &PERM_OP($l,$r,$tt, 2,"0x33333333");
17879 + &PERM_OP($r,$l,$tt,16,"0x0000ffff");
17880 + &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
17881 + }
17882 +
17883 +sub n2a
17884 + {
17885 + sprintf("%d",$_[0]);
17886 + }
17887 --- /dev/null Tue Mar 11 13:02:56 2003
17888 +++ linux/net/ipsec/des/asm/desboth.pl Mon Feb 9 13:51:03 2004
17889 @@ -0,0 +1,79 @@
17890 +#!/usr/local/bin/perl
17891 +
17892 +$L="edi";
17893 +$R="esi";
17894 +
17895 +sub des_encrypt3
17896 + {
17897 + local($name,$enc)=@_;
17898 +
17899 + &function_begin_B($name,"");
17900 + &push("ebx");
17901 + &mov("ebx",&wparam(0));
17902 +
17903 + &push("ebp");
17904 + &push("esi");
17905 +
17906 + &push("edi");
17907 +
17908 + &comment("");
17909 + &comment("Load the data words");
17910 + &mov($L,&DWP(0,"ebx","",0));
17911 + &mov($R,&DWP(4,"ebx","",0));
17912 + &stack_push(3);
17913 +
17914 + &comment("");
17915 + &comment("IP");
17916 + &IP_new($L,$R,"edx",0);
17917 +
17918 + # put them back
17919 +
17920 + if ($enc)
17921 + {
17922 + &mov(&DWP(4,"ebx","",0),$R);
17923 + &mov("eax",&wparam(1));
17924 + &mov(&DWP(0,"ebx","",0),"edx");
17925 + &mov("edi",&wparam(2));
17926 + &mov("esi",&wparam(3));
17927 + }
17928 + else
17929 + {
17930 + &mov(&DWP(4,"ebx","",0),$R);
17931 + &mov("esi",&wparam(1));
17932 + &mov(&DWP(0,"ebx","",0),"edx");
17933 + &mov("edi",&wparam(2));
17934 + &mov("eax",&wparam(3));
17935 + }
17936 + &mov(&swtmp(2), (($enc)?"1":"0"));
17937 + &mov(&swtmp(1), "eax");
17938 + &mov(&swtmp(0), "ebx");
17939 + &call("des_encrypt2");
17940 + &mov(&swtmp(2), (($enc)?"0":"1"));
17941 + &mov(&swtmp(1), "edi");
17942 + &mov(&swtmp(0), "ebx");
17943 + &call("des_encrypt2");
17944 + &mov(&swtmp(2), (($enc)?"1":"0"));
17945 + &mov(&swtmp(1), "esi");
17946 + &mov(&swtmp(0), "ebx");
17947 + &call("des_encrypt2");
17948 +
17949 + &stack_pop(3);
17950 + &mov($L,&DWP(0,"ebx","",0));
17951 + &mov($R,&DWP(4,"ebx","",0));
17952 +
17953 + &comment("");
17954 + &comment("FP");
17955 + &FP_new($L,$R,"eax",0);
17956 +
17957 + &mov(&DWP(0,"ebx","",0),"eax");
17958 + &mov(&DWP(4,"ebx","",0),$R);
17959 +
17960 + &pop("edi");
17961 + &pop("esi");
17962 + &pop("ebp");
17963 + &pop("ebx");
17964 + &ret();
17965 + &function_end_B($name);
17966 + }
17967 +
17968 +
17969 --- /dev/null Tue Mar 11 13:02:56 2003
17970 +++ linux/net/ipsec/des/asm/readme Mon Feb 9 13:51:03 2004
17971 @@ -0,0 +1,131 @@
17972 +First up, let me say I don't like writing in assembler. It is not portable,
17973 +dependant on the particular CPU architecture release and is generally a pig
17974 +to debug and get right. Having said that, the x86 architecture is probably
17975 +the most important for speed due to number of boxes and since
17976 +it appears to be the worst architecture to to get
17977 +good C compilers for. So due to this, I have lowered myself to do
17978 +assembler for the inner DES routines in libdes :-).
17979 +
17980 +The file to implement in assembler is des_enc.c. Replace the following
17981 +4 functions
17982 +des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
17983 +des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
17984 +des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17985 +des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
17986 +
17987 +They encrypt/decrypt the 64 bits held in 'data' using
17988 +the 'ks' key schedules. The only difference between the 4 functions is that
17989 +des_encrypt2() does not perform IP() or FP() on the data (this is an
17990 +optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
17991 +perform triple des. The triple DES routines are in here because it does
17992 +make a big difference to have them located near the des_encrypt2 function
17993 +at link time..
17994 +
17995 +Now as we all know, there are lots of different operating systems running on
17996 +x86 boxes, and unfortunately they normally try to make sure their assembler
17997 +formating is not the same as the other peoples.
17998 +The 4 main formats I know of are
17999 +Microsoft Windows 95/Windows NT
18000 +Elf Includes Linux and FreeBSD(?).
18001 +a.out The older Linux.
18002 +Solaris Same as Elf but different comments :-(.
18003 +
18004 +Now I was not overly keen to write 4 different copies of the same code,
18005 +so I wrote a few perl routines to output the correct assembler, given
18006 +a target assembler type. This code is ugly and is just a hack.
18007 +The libraries are x86unix.pl and x86ms.pl.
18008 +des586.pl, des686.pl and des-som[23].pl are the programs to actually
18009 +generate the assembler.
18010 +
18011 +So to generate elf assembler
18012 +perl des-som3.pl elf >dx86-elf.s
18013 +For Windows 95/NT
18014 +perl des-som2.pl win32 >win32.asm
18015 +
18016 +[ update 4 Jan 1996 ]
18017 +I have added another way to do things.
18018 +perl des-som3.pl cpp >dx86-cpp.s
18019 +generates a file that will be included by dx86unix.cpp when it is compiled.
18020 +To build for elf, a.out, solaris, bsdi etc,
18021 +cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
18022 +cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
18023 +cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
18024 +cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
18025 +This was done to cut down the number of files in the distribution.
18026 +
18027 +Now the ugly part. I acquired my copy of Intels
18028 +"Optimization's For Intel's 32-Bit Processors" and found a few interesting
18029 +things. First, the aim of the exersize is to 'extract' one byte at a time
18030 +from a word and do an array lookup. This involves getting the byte from
18031 +the 4 locations in the word and moving it to a new word and doing the lookup.
18032 +The most obvious way to do this is
18033 +xor eax, eax # clear word
18034 +movb al, cl # get low byte
18035 +xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
18036 +movb al, ch # get next byte
18037 +xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
18038 +shr ecx 16
18039 +which seems ok. For the pentium, this system appears to be the best.
18040 +One has to do instruction interleaving to keep both functional units
18041 +operating, but it is basically very efficient.
18042 +
18043 +Now the crunch. When a full register is used after a partial write, eg.
18044 +mov al, cl
18045 +xor edi, DWORD PTR 0x100+des_SP[eax]
18046 +386 - 1 cycle stall
18047 +486 - 1 cycle stall
18048 +586 - 0 cycle stall
18049 +686 - at least 7 cycle stall (page 22 of the above mentioned document).
18050 +
18051 +So the technique that produces the best results on a pentium, according to
18052 +the documentation, will produce hideous results on a pentium pro.
18053 +
18054 +To get around this, des686.pl will generate code that is not as fast on
18055 +a pentium, should be very good on a pentium pro.
18056 +mov eax, ecx # copy word
18057 +shr ecx, 8 # line up next byte
18058 +and eax, 0fch # mask byte
18059 +xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
18060 +mov eax, ecx # get word
18061 +shr ecx 8 # line up next byte
18062 +and eax, 0fch # mask byte
18063 +xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
18064 +
18065 +Due to the execution units in the pentium, this actually works quite well.
18066 +For a pentium pro it should be very good. This is the type of output
18067 +Visual C++ generates.
18068 +
18069 +There is a third option. instead of using
18070 +mov al, ch
18071 +which is bad on the pentium pro, one may be able to use
18072 +movzx eax, ch
18073 +which may not incur the partial write penalty. On the pentium,
18074 +this instruction takes 4 cycles so is not worth using but on the
18075 +pentium pro it appears it may be worth while. I need access to one to
18076 +experiment :-).
18077 +
18078 +eric (20 Oct 1996)
18079 +
18080 +22 Nov 1996 - I have asked people to run the 2 different version on pentium
18081 +pros and it appears that the intel documentation is wrong. The
18082 +mov al,bh is still faster on a pentium pro, so just use the des586.pl
18083 +install des686.pl
18084 +
18085 +3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
18086 +functions into des_enc.c because it does make a massive performance
18087 +difference on some boxes to have the functions code located close to
18088 +the des_encrypt2() function.
18089 +
18090 +9 Jan 1997 - des-som2.pl is now the correct perl script to use for
18091 +pentiums. It contains an inner loop from
18092 +Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
18093 +273,000 per second. He had a previous version at 250,000 and the best
18094 +I was able to get was 203,000. The content has not changed, this is all
18095 +due to instruction sequencing (and actual instructions choice) which is able
18096 +to keep both functional units of the pentium going.
18097 +We may have lost the ugly register usage restrictions when x86 went 32 bit
18098 +but for the pentium it has been replaced by evil instruction ordering tricks.
18099 +
18100 +13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
18101 +raw DES at 281,000 per second on a pentium 100.
18102 +
18103 --- /dev/null Tue Mar 11 13:02:56 2003
18104 +++ linux/net/ipsec/des/cbc_enc.c Mon Feb 9 13:51:03 2004
18105 @@ -0,0 +1,135 @@
18106 +/* crypto/des/cbc_enc.c */
18107 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18108 + * All rights reserved.
18109 + *
18110 + * This package is an SSL implementation written
18111 + * by Eric Young (eay@cryptsoft.com).
18112 + * The implementation was written so as to conform with Netscapes SSL.
18113 + *
18114 + * This library is free for commercial and non-commercial use as long as
18115 + * the following conditions are aheared to. The following conditions
18116 + * apply to all code found in this distribution, be it the RC4, RSA,
18117 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18118 + * included with this distribution is covered by the same copyright terms
18119 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18120 + *
18121 + * Copyright remains Eric Young's, and as such any Copyright notices in
18122 + * the code are not to be removed.
18123 + * If this package is used in a product, Eric Young should be given attribution
18124 + * as the author of the parts of the library used.
18125 + * This can be in the form of a textual message at program startup or
18126 + * in documentation (online or textual) provided with the package.
18127 + *
18128 + * Redistribution and use in source and binary forms, with or without
18129 + * modification, are permitted provided that the following conditions
18130 + * are met:
18131 + * 1. Redistributions of source code must retain the copyright
18132 + * notice, this list of conditions and the following disclaimer.
18133 + * 2. Redistributions in binary form must reproduce the above copyright
18134 + * notice, this list of conditions and the following disclaimer in the
18135 + * documentation and/or other materials provided with the distribution.
18136 + * 3. All advertising materials mentioning features or use of this software
18137 + * must display the following acknowledgement:
18138 + * "This product includes cryptographic software written by
18139 + * Eric Young (eay@cryptsoft.com)"
18140 + * The word 'cryptographic' can be left out if the rouines from the library
18141 + * being used are not cryptographic related :-).
18142 + * 4. If you include any Windows specific code (or a derivative thereof) from
18143 + * the apps directory (application code) you must include an acknowledgement:
18144 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18145 + *
18146 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18147 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18148 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18149 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18150 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18151 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18152 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18153 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18154 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18155 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18156 + * SUCH DAMAGE.
18157 + *
18158 + * The licence and distribution terms for any publically available version or
18159 + * derivative of this code cannot be changed. i.e. this code cannot simply be
18160 + * copied and put under another distribution licence
18161 + * [including the GNU Public Licence.]
18162 + */
18163 +
18164 +#include "des/des_locl.h"
18165 +
18166 +void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
18167 +des_cblock (*input);
18168 +des_cblock (*output);
18169 +long length;
18170 +des_key_schedule schedule;
18171 +des_cblock (*ivec);
18172 +int enc;
18173 + {
18174 + register DES_LONG tin0,tin1;
18175 + register DES_LONG tout0,tout1,xor0,xor1;
18176 + register unsigned char *in,*out;
18177 + register long l=length;
18178 + DES_LONG tin[2];
18179 + unsigned char *iv;
18180 +
18181 + in=(unsigned char *)input;
18182 + out=(unsigned char *)output;
18183 + iv=(unsigned char *)ivec;
18184 +
18185 + if (enc)
18186 + {
18187 + c2l(iv,tout0);
18188 + c2l(iv,tout1);
18189 + for (l-=8; l>=0; l-=8)
18190 + {
18191 + c2l(in,tin0);
18192 + c2l(in,tin1);
18193 + tin0^=tout0; tin[0]=tin0;
18194 + tin1^=tout1; tin[1]=tin1;
18195 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18196 + tout0=tin[0]; l2c(tout0,out);
18197 + tout1=tin[1]; l2c(tout1,out);
18198 + }
18199 + if (l != -8)
18200 + {
18201 + c2ln(in,tin0,tin1,l+8);
18202 + tin0^=tout0; tin[0]=tin0;
18203 + tin1^=tout1; tin[1]=tin1;
18204 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
18205 + tout0=tin[0]; l2c(tout0,out);
18206 + tout1=tin[1]; l2c(tout1,out);
18207 + }
18208 + }
18209 + else
18210 + {
18211 + c2l(iv,xor0);
18212 + c2l(iv,xor1);
18213 + for (l-=8; l>=0; l-=8)
18214 + {
18215 + c2l(in,tin0); tin[0]=tin0;
18216 + c2l(in,tin1); tin[1]=tin1;
18217 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18218 + tout0=tin[0]^xor0;
18219 + tout1=tin[1]^xor1;
18220 + l2c(tout0,out);
18221 + l2c(tout1,out);
18222 + xor0=tin0;
18223 + xor1=tin1;
18224 + }
18225 + if (l != -8)
18226 + {
18227 + c2l(in,tin0); tin[0]=tin0;
18228 + c2l(in,tin1); tin[1]=tin1;
18229 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
18230 + tout0=tin[0]^xor0;
18231 + tout1=tin[1]^xor1;
18232 + l2cn(tout0,tout1,out,l+8);
18233 + /* xor0=tin0;
18234 + xor1=tin1; */
18235 + }
18236 + }
18237 + tin0=tin1=tout0=tout1=xor0=xor1=0;
18238 + tin[0]=tin[1]=0;
18239 + }
18240 +
18241 --- /dev/null Tue Mar 11 13:02:56 2003
18242 +++ linux/net/ipsec/des/des.doc Mon Feb 9 13:51:03 2004
18243 @@ -0,0 +1,505 @@
18244 +The DES library.
18245 +
18246 +Please note that this library was originally written to operate with
18247 +eBones, a version of Kerberos that had had encryption removed when it left
18248 +the USA and then put back in. As such there are some routines that I will
18249 +advise not using but they are still in the library for historical reasons.
18250 +For all calls that have an 'input' and 'output' variables, they can be the
18251 +same.
18252 +
18253 +This library requires the inclusion of 'des.h'.
18254 +
18255 +All of the encryption functions take what is called a des_key_schedule as an
18256 +argument. A des_key_schedule is an expanded form of the des key.
18257 +A des_key is 8 bytes of odd parity, the type used to hold the key is a
18258 +des_cblock. A des_cblock is an array of 8 bytes, often in this library
18259 +description I will refer to input bytes when the function specifies
18260 +des_cblock's as input or output, this just means that the variable should
18261 +be a multiple of 8 bytes.
18262 +
18263 +The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
18264 +specify decryption. The functions and global variable are as follows:
18265 +
18266 +int des_check_key;
18267 + DES keys are supposed to be odd parity. If this variable is set to
18268 + a non-zero value, des_set_key() will check that the key has odd
18269 + parity and is not one of the known weak DES keys. By default this
18270 + variable is turned off;
18271 +
18272 +void des_set_odd_parity(
18273 +des_cblock *key );
18274 + This function takes a DES key (8 bytes) and sets the parity to odd.
18275 +
18276 +int des_is_weak_key(
18277 +des_cblock *key );
18278 + This function returns a non-zero value if the DES key passed is a
18279 + weak, DES key. If it is a weak key, don't use it, try a different
18280 + one. If you are using 'random' keys, the chances of hitting a weak
18281 + key are 1/2^52 so it is probably not worth checking for them.
18282 +
18283 +int des_set_key(
18284 +des_cblock *key,
18285 +des_key_schedule schedule);
18286 + Des_set_key converts an 8 byte DES key into a des_key_schedule.
18287 + A des_key_schedule is an expanded form of the key which is used to
18288 + perform actual encryption. It can be regenerated from the DES key
18289 + so it only needs to be kept when encryption or decryption is about
18290 + to occur. Don't save or pass around des_key_schedule's since they
18291 + are CPU architecture dependent, DES keys are not. If des_check_key
18292 + is non zero, zero is returned if the key has the wrong parity or
18293 + the key is a weak key, else 1 is returned.
18294 +
18295 +int des_key_sched(
18296 +des_cblock *key,
18297 +des_key_schedule schedule);
18298 + An alternative name for des_set_key().
18299 +
18300 +int des_rw_mode; /* defaults to DES_PCBC_MODE */
18301 + This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
18302 + This specifies the function to use in the enc_read() and enc_write()
18303 + functions.
18304 +
18305 +void des_encrypt(
18306 +unsigned long *data,
18307 +des_key_schedule ks,
18308 +int enc);
18309 + This is the DES encryption function that gets called by just about
18310 + every other DES routine in the library. You should not use this
18311 + function except to implement 'modes' of DES. I say this because the
18312 + functions that call this routine do the conversion from 'char *' to
18313 + long, and this needs to be done to make sure 'non-aligned' memory
18314 + access do not occur. The characters are loaded 'little endian',
18315 + have a look at my source code for more details on how I use this
18316 + function.
18317 + Data is a pointer to 2 unsigned long's and ks is the
18318 + des_key_schedule to use. enc, is non zero specifies encryption,
18319 + zero if decryption.
18320 +
18321 +void des_encrypt2(
18322 +unsigned long *data,
18323 +des_key_schedule ks,
18324 +int enc);
18325 + This functions is the same as des_encrypt() except that the DES
18326 + initial permutation (IP) and final permutation (FP) have been left
18327 + out. As for des_encrypt(), you should not use this function.
18328 + It is used by the routines in my library that implement triple DES.
18329 + IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
18330 + as des_encrypt() des_encrypt() des_encrypt() except faster :-).
18331 +
18332 +void des_ecb_encrypt(
18333 +des_cblock *input,
18334 +des_cblock *output,
18335 +des_key_schedule ks,
18336 +int enc);
18337 + This is the basic Electronic Code Book form of DES, the most basic
18338 + form. Input is encrypted into output using the key represented by
18339 + ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
18340 + decryption occurs. Input is 8 bytes long and output is 8 bytes.
18341 + (the des_cblock structure is 8 chars).
18342 +
18343 +void des_ecb3_encrypt(
18344 +des_cblock *input,
18345 +des_cblock *output,
18346 +des_key_schedule ks1,
18347 +des_key_schedule ks2,
18348 +des_key_schedule ks3,
18349 +int enc);
18350 + This is the 3 key EDE mode of ECB DES. What this means is that
18351 + the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
18352 + then encrypted again with ks3, before being put into output;
18353 + C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
18354 + that only takes 2 des_key_schedules that implements,
18355 + C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
18356 +
18357 +void des_cbc_encrypt(
18358 +des_cblock *input,
18359 +des_cblock *output,
18360 +long length,
18361 +des_key_schedule ks,
18362 +des_cblock *ivec,
18363 +int enc);
18364 + This routine implements DES in Cipher Block Chaining mode.
18365 + Input, which should be a multiple of 8 bytes is encrypted
18366 + (or decrypted) to output which will also be a multiple of 8 bytes.
18367 + The number of bytes is in length (and from what I've said above,
18368 + should be a multiple of 8). If length is not a multiple of 8, I'm
18369 + not being held responsible :-). ivec is the initialisation vector.
18370 + This function does not modify this variable. To correctly implement
18371 + cbc mode, you need to do one of 2 things; copy the last 8 bytes of
18372 + cipher text for use as the next ivec in your application,
18373 + or use des_ncbc_encrypt().
18374 + Only this routine has this problem with updating the ivec, all
18375 + other routines that are implementing cbc mode update ivec.
18376 +
18377 +void des_ncbc_encrypt(
18378 +des_cblock *input,
18379 +des_cblock *output,
18380 +long length,
18381 +des_key_schedule sk,
18382 +des_cblock *ivec,
18383 +int enc);
18384 + For historical reasons, des_cbc_encrypt() did not update the
18385 + ivec with the value requires so that subsequent calls to
18386 + des_cbc_encrypt() would 'chain'. This was needed so that the same
18387 + 'length' values would not need to be used when decrypting.
18388 + des_ncbc_encrypt() does the right thing. It is the same as
18389 + des_cbc_encrypt accept that ivec is updates with the correct value
18390 + to pass in subsequent calls to des_ncbc_encrypt(). I advise using
18391 + des_ncbc_encrypt() instead of des_cbc_encrypt();
18392 +
18393 +void des_xcbc_encrypt(
18394 +des_cblock *input,
18395 +des_cblock *output,
18396 +long length,
18397 +des_key_schedule sk,
18398 +des_cblock *ivec,
18399 +des_cblock *inw,
18400 +des_cblock *outw,
18401 +int enc);
18402 + This is RSA's DESX mode of DES. It uses inw and outw to
18403 + 'whiten' the encryption. inw and outw are secret (unlike the iv)
18404 + and are as such, part of the key. So the key is sort of 24 bytes.
18405 + This is much better than cbc des.
18406 +
18407 +void des_3cbc_encrypt(
18408 +des_cblock *input,
18409 +des_cblock *output,
18410 +long length,
18411 +des_key_schedule sk1,
18412 +des_key_schedule sk2,
18413 +des_cblock *ivec1,
18414 +des_cblock *ivec2,
18415 +int enc);
18416 + This function is flawed, do not use it. I have left it in the
18417 + library because it is used in my des(1) program and will function
18418 + correctly when used by des(1). If I removed the function, people
18419 + could end up unable to decrypt files.
18420 + This routine implements outer triple cbc encryption using 2 ks and
18421 + 2 ivec's. Use des_ede2_cbc_encrypt() instead.
18422 +
18423 +void des_ede3_cbc_encrypt(
18424 +des_cblock *input,
18425 +des_cblock *output,
18426 +long length,
18427 +des_key_schedule ks1,
18428 +des_key_schedule ks2,
18429 +des_key_schedule ks3,
18430 +des_cblock *ivec,
18431 +int enc);
18432 + This function implements inner triple CBC DES encryption with 3
18433 + keys. What this means is that each 'DES' operation
18434 + inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
18435 + Again, this is cbc mode so an ivec is requires.
18436 + This mode is used by SSL.
18437 + There is also a des_ede2_cbc_encrypt() that only uses 2
18438 + des_key_schedule's, the first being reused for the final
18439 + encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
18440 + is used by the RSAref library.
18441 +
18442 +void des_pcbc_encrypt(
18443 +des_cblock *input,
18444 +des_cblock *output,
18445 +long length,
18446 +des_key_schedule ks,
18447 +des_cblock *ivec,
18448 +int enc);
18449 + This is Propagating Cipher Block Chaining mode of DES. It is used
18450 + by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
18451 +
18452 +void des_cfb_encrypt(
18453 +unsigned char *in,
18454 +unsigned char *out,
18455 +int numbits,
18456 +long length,
18457 +des_key_schedule ks,
18458 +des_cblock *ivec,
18459 +int enc);
18460 + Cipher Feedback Back mode of DES. This implementation 'feeds back'
18461 + in numbit blocks. The input (and output) is in multiples of numbits
18462 + bits. numbits should to be a multiple of 8 bits. Length is the
18463 + number of bytes input. If numbits is not a multiple of 8 bits,
18464 + the extra bits in the bytes will be considered padding. So if
18465 + numbits is 12, for each 2 input bytes, the 4 high bits of the
18466 + second byte will be ignored. So to encode 72 bits when using
18467 + a numbits of 12 take 12 bytes. To encode 72 bits when using
18468 + numbits of 9 will take 16 bytes. To encode 80 bits when using
18469 + numbits of 16 will take 10 bytes. etc, etc. This padding will
18470 + apply to both input and output.
18471 +
18472 +
18473 +void des_cfb64_encrypt(
18474 +unsigned char *in,
18475 +unsigned char *out,
18476 +long length,
18477 +des_key_schedule ks,
18478 +des_cblock *ivec,
18479 +int *num,
18480 +int enc);
18481 + This is one of the more useful functions in this DES library, it
18482 + implements CFB mode of DES with 64bit feedback. Why is this
18483 + useful you ask? Because this routine will allow you to encrypt an
18484 + arbitrary number of bytes, no 8 byte padding. Each call to this
18485 + routine will encrypt the input bytes to output and then update ivec
18486 + and num. num contains 'how far' we are though ivec. If this does
18487 + not make much sense, read more about cfb mode of DES :-).
18488 +
18489 +void des_ede3_cfb64_encrypt(
18490 +unsigned char *in,
18491 +unsigned char *out,
18492 +long length,
18493 +des_key_schedule ks1,
18494 +des_key_schedule ks2,
18495 +des_key_schedule ks3,
18496 +des_cblock *ivec,
18497 +int *num,
18498 +int enc);
18499 + Same as des_cfb64_encrypt() accept that the DES operation is
18500 + triple DES. As usual, there is a macro for
18501 + des_ede2_cfb64_encrypt() which reuses ks1.
18502 +
18503 +void des_ofb_encrypt(
18504 +unsigned char *in,
18505 +unsigned char *out,
18506 +int numbits,
18507 +long length,
18508 +des_key_schedule ks,
18509 +des_cblock *ivec);
18510 + This is a implementation of Output Feed Back mode of DES. It is
18511 + the same as des_cfb_encrypt() in that numbits is the size of the
18512 + units dealt with during input and output (in bits).
18513 +
18514 +void des_ofb64_encrypt(
18515 +unsigned char *in,
18516 +unsigned char *out,
18517 +long length,
18518 +des_key_schedule ks,
18519 +des_cblock *ivec,
18520 +int *num);
18521 + The same as des_cfb64_encrypt() except that it is Output Feed Back
18522 + mode.
18523 +
18524 +void des_ede3_ofb64_encrypt(
18525 +unsigned char *in,
18526 +unsigned char *out,
18527 +long length,
18528 +des_key_schedule ks1,
18529 +des_key_schedule ks2,
18530 +des_key_schedule ks3,
18531 +des_cblock *ivec,
18532 +int *num);
18533 + Same as des_ofb64_encrypt() accept that the DES operation is
18534 + triple DES. As usual, there is a macro for
18535 + des_ede2_ofb64_encrypt() which reuses ks1.
18536 +
18537 +int des_read_pw_string(
18538 +char *buf,
18539 +int length,
18540 +char *prompt,
18541 +int verify);
18542 + This routine is used to get a password from the terminal with echo
18543 + turned off. Buf is where the string will end up and length is the
18544 + size of buf. Prompt is a string presented to the 'user' and if
18545 + verify is set, the key is asked for twice and unless the 2 copies
18546 + match, an error is returned. A return code of -1 indicates a
18547 + system error, 1 failure due to use interaction, and 0 is success.
18548 +
18549 +unsigned long des_cbc_cksum(
18550 +des_cblock *input,
18551 +des_cblock *output,
18552 +long length,
18553 +des_key_schedule ks,
18554 +des_cblock *ivec);
18555 + This function produces an 8 byte checksum from input that it puts in
18556 + output and returns the last 4 bytes as a long. The checksum is
18557 + generated via cbc mode of DES in which only the last 8 byes are
18558 + kept. I would recommend not using this function but instead using
18559 + the EVP_Digest routines, or at least using MD5 or SHA. This
18560 + function is used by Kerberos v4 so that is why it stays in the
18561 + library.
18562 +
18563 +char *des_fcrypt(
18564 +const char *buf,
18565 +const char *salt
18566 +char *ret);
18567 + This is my fast version of the unix crypt(3) function. This version
18568 + takes only a small amount of space relative to other fast
18569 + crypt() implementations. This is different to the normal crypt
18570 + in that the third parameter is the buffer that the return value
18571 + is written into. It needs to be at least 14 bytes long. This
18572 + function is thread safe, unlike the normal crypt.
18573 +
18574 +char *crypt(
18575 +const char *buf,
18576 +const char *salt);
18577 + This function calls des_fcrypt() with a static array passed as the
18578 + third parameter. This emulates the normal non-thread safe semantics
18579 + of crypt(3).
18580 +
18581 +void des_string_to_key(
18582 +char *str,
18583 +des_cblock *key);
18584 + This function takes str and converts it into a DES key. I would
18585 + recommend using MD5 instead and use the first 8 bytes of output.
18586 + When I wrote the first version of these routines back in 1990, MD5
18587 + did not exist but I feel these routines are still sound. This
18588 + routines is compatible with the one in MIT's libdes.
18589 +
18590 +void des_string_to_2keys(
18591 +char *str,
18592 +des_cblock *key1,
18593 +des_cblock *key2);
18594 + This function takes str and converts it into 2 DES keys.
18595 + I would recommend using MD5 and using the 16 bytes as the 2 keys.
18596 + I have nothing against these 2 'string_to_key' routines, it's just
18597 + that if you say that your encryption key is generated by using the
18598 + 16 bytes of an MD5 hash, every-one knows how you generated your
18599 + keys.
18600 +
18601 +int des_read_password(
18602 +des_cblock *key,
18603 +char *prompt,
18604 +int verify);
18605 + This routine combines des_read_pw_string() with des_string_to_key().
18606 +
18607 +int des_read_2passwords(
18608 +des_cblock *key1,
18609 +des_cblock *key2,
18610 +char *prompt,
18611 +int verify);
18612 + This routine combines des_read_pw_string() with des_string_to_2key().
18613 +
18614 +void des_random_seed(
18615 +des_cblock key);
18616 + This routine sets a starting point for des_random_key().
18617 +
18618 +void des_random_key(
18619 +des_cblock ret);
18620 + This function return a random key. Make sure to 'seed' the random
18621 + number generator (with des_random_seed()) before using this function.
18622 + I personally now use a MD5 based random number system.
18623 +
18624 +int des_enc_read(
18625 +int fd,
18626 +char *buf,
18627 +int len,
18628 +des_key_schedule ks,
18629 +des_cblock *iv);
18630 + This function will write to a file descriptor the encrypted data
18631 + from buf. This data will be preceded by a 4 byte 'byte count' and
18632 + will be padded out to 8 bytes. The encryption is either CBC of
18633 + PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
18634 + pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
18635 + DES_PCBC_MODE.
18636 +
18637 +int des_enc_write(
18638 +int fd,
18639 +char *buf,
18640 +int len,
18641 +des_key_schedule ks,
18642 +des_cblock *iv);
18643 + This routines read stuff written by des_enc_read() and decrypts it.
18644 + I have used these routines quite a lot but I don't believe they are
18645 + suitable for non-blocking io. If you are after a full
18646 + authentication/encryption over networks, have a look at SSL instead.
18647 +
18648 +unsigned long des_quad_cksum(
18649 +des_cblock *input,
18650 +des_cblock *output,
18651 +long length,
18652 +int out_count,
18653 +des_cblock *seed);
18654 + This is a function from Kerberos v4 that is not anything to do with
18655 + DES but was needed. It is a cksum that is quicker to generate than
18656 + des_cbc_cksum(); I personally would use MD5 routines now.
18657 +=====
18658 +Modes of DES
18659 +Quite a bit of the following information has been taken from
18660 + AS 2805.5.2
18661 + Australian Standard
18662 + Electronic funds transfer - Requirements for interfaces,
18663 + Part 5.2: Modes of operation for an n-bit block cipher algorithm
18664 + Appendix A
18665 +
18666 +There are several different modes in which DES can be used, they are
18667 +as follows.
18668 +
18669 +Electronic Codebook Mode (ECB) (des_ecb_encrypt())
18670 +- 64 bits are enciphered at a time.
18671 +- The order of the blocks can be rearranged without detection.
18672 +- The same plaintext block always produces the same ciphertext block
18673 + (for the same key) making it vulnerable to a 'dictionary attack'.
18674 +- An error will only affect one ciphertext block.
18675 +
18676 +Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
18677 +- a multiple of 64 bits are enciphered at a time.
18678 +- The CBC mode produces the same ciphertext whenever the same
18679 + plaintext is encrypted using the same key and starting variable.
18680 +- The chaining operation makes the ciphertext blocks dependent on the
18681 + current and all preceding plaintext blocks and therefore blocks can not
18682 + be rearranged.
18683 +- The use of different starting variables prevents the same plaintext
18684 + enciphering to the same ciphertext.
18685 +- An error will affect the current and the following ciphertext blocks.
18686 +
18687 +Cipher Feedback Mode (CFB) (des_cfb_encrypt())
18688 +- a number of bits (j) <= 64 are enciphered at a time.
18689 +- The CFB mode produces the same ciphertext whenever the same
18690 + plaintext is encrypted using the same key and starting variable.
18691 +- The chaining operation makes the ciphertext variables dependent on the
18692 + current and all preceding variables and therefore j-bit variables are
18693 + chained together and can not be rearranged.
18694 +- The use of different starting variables prevents the same plaintext
18695 + enciphering to the same ciphertext.
18696 +- The strength of the CFB mode depends on the size of k (maximal if
18697 + j == k). In my implementation this is always the case.
18698 +- Selection of a small value for j will require more cycles through
18699 + the encipherment algorithm per unit of plaintext and thus cause
18700 + greater processing overheads.
18701 +- Only multiples of j bits can be enciphered.
18702 +- An error will affect the current and the following ciphertext variables.
18703 +
18704 +Output Feedback Mode (OFB) (des_ofb_encrypt())
18705 +- a number of bits (j) <= 64 are enciphered at a time.
18706 +- The OFB mode produces the same ciphertext whenever the same
18707 + plaintext enciphered using the same key and starting variable. More
18708 + over, in the OFB mode the same key stream is produced when the same
18709 + key and start variable are used. Consequently, for security reasons
18710 + a specific start variable should be used only once for a given key.
18711 +- The absence of chaining makes the OFB more vulnerable to specific attacks.
18712 +- The use of different start variables values prevents the same
18713 + plaintext enciphering to the same ciphertext, by producing different
18714 + key streams.
18715 +- Selection of a small value for j will require more cycles through
18716 + the encipherment algorithm per unit of plaintext and thus cause
18717 + greater processing overheads.
18718 +- Only multiples of j bits can be enciphered.
18719 +- OFB mode of operation does not extend ciphertext errors in the
18720 + resultant plaintext output. Every bit error in the ciphertext causes
18721 + only one bit to be in error in the deciphered plaintext.
18722 +- OFB mode is not self-synchronising. If the two operation of
18723 + encipherment and decipherment get out of synchronism, the system needs
18724 + to be re-initialised.
18725 +- Each re-initialisation should use a value of the start variable
18726 + different from the start variable values used before with the same
18727 + key. The reason for this is that an identical bit stream would be
18728 + produced each time from the same parameters. This would be
18729 + susceptible to a ' known plaintext' attack.
18730 +
18731 +Triple ECB Mode (des_ecb3_encrypt())
18732 +- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
18733 +- As for ECB encryption but increases the key length to 168 bits.
18734 + There are theoretic attacks that can be used that make the effective
18735 + key length 112 bits, but this attack also requires 2^56 blocks of
18736 + memory, not very likely, even for the NSA.
18737 +- If both keys are the same it is equivalent to encrypting once with
18738 + just one key.
18739 +- If the first and last key are the same, the key length is 112 bits.
18740 + There are attacks that could reduce the key space to 55 bit's but it
18741 + requires 2^56 blocks of memory.
18742 +- If all 3 keys are the same, this is effectively the same as normal
18743 + ecb mode.
18744 +
18745 +Triple CBC Mode (des_ede3_cbc_encrypt())
18746 +- Encrypt with key1, decrypt with key2 and then encrypt with key3.
18747 +- As for CBC encryption but increases the key length to 168 bits with
18748 + the same restrictions as for triple ecb mode.
18749 --- /dev/null Tue Mar 11 13:02:56 2003
18750 +++ linux/net/ipsec/des/des_enc.c Mon Feb 9 13:51:03 2004
18751 @@ -0,0 +1,502 @@
18752 +/* crypto/des/des_enc.c */
18753 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
18754 + * All rights reserved.
18755 + *
18756 + * This package is an SSL implementation written
18757 + * by Eric Young (eay@cryptsoft.com).
18758 + * The implementation was written so as to conform with Netscapes SSL.
18759 + *
18760 + * This library is free for commercial and non-commercial use as long as
18761 + * the following conditions are aheared to. The following conditions
18762 + * apply to all code found in this distribution, be it the RC4, RSA,
18763 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
18764 + * included with this distribution is covered by the same copyright terms
18765 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
18766 + *
18767 + * Copyright remains Eric Young's, and as such any Copyright notices in
18768 + * the code are not to be removed.
18769 + * If this package is used in a product, Eric Young should be given attribution
18770 + * as the author of the parts of the library used.
18771 + * This can be in the form of a textual message at program startup or
18772 + * in documentation (online or textual) provided with the package.
18773 + *
18774 + * Redistribution and use in source and binary forms, with or without
18775 + * modification, are permitted provided that the following conditions
18776 + * are met:
18777 + * 1. Redistributions of source code must retain the copyright
18778 + * notice, this list of conditions and the following disclaimer.
18779 + * 2. Redistributions in binary form must reproduce the above copyright
18780 + * notice, this list of conditions and the following disclaimer in the
18781 + * documentation and/or other materials provided with the distribution.
18782 + * 3. All advertising materials mentioning features or use of this software
18783 + * must display the following acknowledgement:
18784 + * "This product includes cryptographic software written by
18785 + * Eric Young (eay@cryptsoft.com)"
18786 + * The word 'cryptographic' can be left out if the rouines from the library
18787 + * being used are not cryptographic related :-).
18788 + * 4. If you include any Windows specific code (or a derivative thereof) from
18789 + * the apps directory (application code) you must include an acknowledgement:
18790 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
18791 + *
18792 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
18793 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18794 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18795 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18796 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18797 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
18798 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18799 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
18800 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
18801 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
18802 + * SUCH DAMAGE.
18803 + *
18804 + * The licence and distribution terms for any publically available version or
18805 + * derivative of this code cannot be changed. i.e. this code cannot simply be
18806 + * copied and put under another distribution licence
18807 + * [including the GNU Public Licence.]
18808 + */
18809 +
18810 +#include "des/des_locl.h"
18811 +
18812 +void des_encrypt(data, ks, enc)
18813 +DES_LONG *data;
18814 +des_key_schedule ks;
18815 +int enc;
18816 + {
18817 + register DES_LONG l,r,t,u;
18818 +#ifdef DES_PTR
18819 + register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18820 +#endif
18821 +#ifndef DES_UNROLL
18822 + register int i;
18823 +#endif
18824 + register DES_LONG *s;
18825 +
18826 + r=data[0];
18827 + l=data[1];
18828 +
18829 + IP(r,l);
18830 + /* Things have been modified so that the initial rotate is
18831 + * done outside the loop. This required the
18832 + * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18833 + * One perl script later and things have a 5% speed up on a sparc2.
18834 + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18835 + * for pointing this out. */
18836 + /* clear the top bits on machines with 8byte longs */
18837 + /* shift left by 2 */
18838 + r=ROTATE(r,29)&0xffffffffL;
18839 + l=ROTATE(l,29)&0xffffffffL;
18840 +
18841 + s=(DES_LONG *)ks;
18842 + /* I don't know if it is worth the effort of loop unrolling the
18843 + * inner loop */
18844 + if (enc)
18845 + {
18846 +#ifdef DES_UNROLL
18847 + D_ENCRYPT(l,r, 0); /* 1 */
18848 + D_ENCRYPT(r,l, 2); /* 2 */
18849 + D_ENCRYPT(l,r, 4); /* 3 */
18850 + D_ENCRYPT(r,l, 6); /* 4 */
18851 + D_ENCRYPT(l,r, 8); /* 5 */
18852 + D_ENCRYPT(r,l,10); /* 6 */
18853 + D_ENCRYPT(l,r,12); /* 7 */
18854 + D_ENCRYPT(r,l,14); /* 8 */
18855 + D_ENCRYPT(l,r,16); /* 9 */
18856 + D_ENCRYPT(r,l,18); /* 10 */
18857 + D_ENCRYPT(l,r,20); /* 11 */
18858 + D_ENCRYPT(r,l,22); /* 12 */
18859 + D_ENCRYPT(l,r,24); /* 13 */
18860 + D_ENCRYPT(r,l,26); /* 14 */
18861 + D_ENCRYPT(l,r,28); /* 15 */
18862 + D_ENCRYPT(r,l,30); /* 16 */
18863 +#else
18864 + for (i=0; i<32; i+=8)
18865 + {
18866 + D_ENCRYPT(l,r,i+0); /* 1 */
18867 + D_ENCRYPT(r,l,i+2); /* 2 */
18868 + D_ENCRYPT(l,r,i+4); /* 3 */
18869 + D_ENCRYPT(r,l,i+6); /* 4 */
18870 + }
18871 +#endif
18872 + }
18873 + else
18874 + {
18875 +#ifdef DES_UNROLL
18876 + D_ENCRYPT(l,r,30); /* 16 */
18877 + D_ENCRYPT(r,l,28); /* 15 */
18878 + D_ENCRYPT(l,r,26); /* 14 */
18879 + D_ENCRYPT(r,l,24); /* 13 */
18880 + D_ENCRYPT(l,r,22); /* 12 */
18881 + D_ENCRYPT(r,l,20); /* 11 */
18882 + D_ENCRYPT(l,r,18); /* 10 */
18883 + D_ENCRYPT(r,l,16); /* 9 */
18884 + D_ENCRYPT(l,r,14); /* 8 */
18885 + D_ENCRYPT(r,l,12); /* 7 */
18886 + D_ENCRYPT(l,r,10); /* 6 */
18887 + D_ENCRYPT(r,l, 8); /* 5 */
18888 + D_ENCRYPT(l,r, 6); /* 4 */
18889 + D_ENCRYPT(r,l, 4); /* 3 */
18890 + D_ENCRYPT(l,r, 2); /* 2 */
18891 + D_ENCRYPT(r,l, 0); /* 1 */
18892 +#else
18893 + for (i=30; i>0; i-=8)
18894 + {
18895 + D_ENCRYPT(l,r,i-0); /* 16 */
18896 + D_ENCRYPT(r,l,i-2); /* 15 */
18897 + D_ENCRYPT(l,r,i-4); /* 14 */
18898 + D_ENCRYPT(r,l,i-6); /* 13 */
18899 + }
18900 +#endif
18901 + }
18902 +
18903 + /* rotate and clear the top bits on machines with 8byte longs */
18904 + l=ROTATE(l,3)&0xffffffffL;
18905 + r=ROTATE(r,3)&0xffffffffL;
18906 +
18907 + FP(r,l);
18908 + data[0]=l;
18909 + data[1]=r;
18910 + l=r=t=u=0;
18911 + }
18912 +
18913 +void des_encrypt2(data, ks, enc)
18914 +DES_LONG *data;
18915 +des_key_schedule ks;
18916 +int enc;
18917 + {
18918 + register DES_LONG l,r,t,u;
18919 +#ifdef DES_PTR
18920 + register unsigned char *des_SP=(unsigned char *)des_SPtrans;
18921 +#endif
18922 +#ifndef DES_UNROLL
18923 + register int i;
18924 +#endif
18925 + register DES_LONG *s;
18926 +
18927 + r=data[0];
18928 + l=data[1];
18929 +
18930 + /* Things have been modified so that the initial rotate is
18931 + * done outside the loop. This required the
18932 + * des_SPtrans values in sp.h to be rotated 1 bit to the right.
18933 + * One perl script later and things have a 5% speed up on a sparc2.
18934 + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
18935 + * for pointing this out. */
18936 + /* clear the top bits on machines with 8byte longs */
18937 + r=ROTATE(r,29)&0xffffffffL;
18938 + l=ROTATE(l,29)&0xffffffffL;
18939 +
18940 + s=(DES_LONG *)ks;
18941 + /* I don't know if it is worth the effort of loop unrolling the
18942 + * inner loop */
18943 + if (enc)
18944 + {
18945 +#ifdef DES_UNROLL
18946 + D_ENCRYPT(l,r, 0); /* 1 */
18947 + D_ENCRYPT(r,l, 2); /* 2 */
18948 + D_ENCRYPT(l,r, 4); /* 3 */
18949 + D_ENCRYPT(r,l, 6); /* 4 */
18950 + D_ENCRYPT(l,r, 8); /* 5 */
18951 + D_ENCRYPT(r,l,10); /* 6 */
18952 + D_ENCRYPT(l,r,12); /* 7 */
18953 + D_ENCRYPT(r,l,14); /* 8 */
18954 + D_ENCRYPT(l,r,16); /* 9 */
18955 + D_ENCRYPT(r,l,18); /* 10 */
18956 + D_ENCRYPT(l,r,20); /* 11 */
18957 + D_ENCRYPT(r,l,22); /* 12 */
18958 + D_ENCRYPT(l,r,24); /* 13 */
18959 + D_ENCRYPT(r,l,26); /* 14 */
18960 + D_ENCRYPT(l,r,28); /* 15 */
18961 + D_ENCRYPT(r,l,30); /* 16 */
18962 +#else
18963 + for (i=0; i<32; i+=8)
18964 + {
18965 + D_ENCRYPT(l,r,i+0); /* 1 */
18966 + D_ENCRYPT(r,l,i+2); /* 2 */
18967 + D_ENCRYPT(l,r,i+4); /* 3 */
18968 + D_ENCRYPT(r,l,i+6); /* 4 */
18969 + }
18970 +#endif
18971 + }
18972 + else
18973 + {
18974 +#ifdef DES_UNROLL
18975 + D_ENCRYPT(l,r,30); /* 16 */
18976 + D_ENCRYPT(r,l,28); /* 15 */
18977 + D_ENCRYPT(l,r,26); /* 14 */
18978 + D_ENCRYPT(r,l,24); /* 13 */
18979 + D_ENCRYPT(l,r,22); /* 12 */
18980 + D_ENCRYPT(r,l,20); /* 11 */
18981 + D_ENCRYPT(l,r,18); /* 10 */
18982 + D_ENCRYPT(r,l,16); /* 9 */
18983 + D_ENCRYPT(l,r,14); /* 8 */
18984 + D_ENCRYPT(r,l,12); /* 7 */
18985 + D_ENCRYPT(l,r,10); /* 6 */
18986 + D_ENCRYPT(r,l, 8); /* 5 */
18987 + D_ENCRYPT(l,r, 6); /* 4 */
18988 + D_ENCRYPT(r,l, 4); /* 3 */
18989 + D_ENCRYPT(l,r, 2); /* 2 */
18990 + D_ENCRYPT(r,l, 0); /* 1 */
18991 +#else
18992 + for (i=30; i>0; i-=8)
18993 + {
18994 + D_ENCRYPT(l,r,i-0); /* 16 */
18995 + D_ENCRYPT(r,l,i-2); /* 15 */
18996 + D_ENCRYPT(l,r,i-4); /* 14 */
18997 + D_ENCRYPT(r,l,i-6); /* 13 */
18998 + }
18999 +#endif
19000 + }
19001 + /* rotate and clear the top bits on machines with 8byte longs */
19002 + data[0]=ROTATE(l,3)&0xffffffffL;
19003 + data[1]=ROTATE(r,3)&0xffffffffL;
19004 + l=r=t=u=0;
19005 + }
19006 +
19007 +void des_encrypt3(data,ks1,ks2,ks3)
19008 +DES_LONG *data;
19009 +des_key_schedule ks1;
19010 +des_key_schedule ks2;
19011 +des_key_schedule ks3;
19012 + {
19013 + register DES_LONG l,r;
19014 +
19015 + l=data[0];
19016 + r=data[1];
19017 + IP(l,r);
19018 + data[0]=l;
19019 + data[1]=r;
19020 + des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
19021 + des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
19022 + des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
19023 + l=data[0];
19024 + r=data[1];
19025 + FP(r,l);
19026 + data[0]=l;
19027 + data[1]=r;
19028 + }
19029 +
19030 +void des_decrypt3(data,ks1,ks2,ks3)
19031 +DES_LONG *data;
19032 +des_key_schedule ks1;
19033 +des_key_schedule ks2;
19034 +des_key_schedule ks3;
19035 + {
19036 + register DES_LONG l,r;
19037 +
19038 + l=data[0];
19039 + r=data[1];
19040 + IP(l,r);
19041 + data[0]=l;
19042 + data[1]=r;
19043 + des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
19044 + des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
19045 + des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
19046 + l=data[0];
19047 + r=data[1];
19048 + FP(r,l);
19049 + data[0]=l;
19050 + data[1]=r;
19051 + }
19052 +
19053 +#ifndef DES_DEFAULT_OPTIONS
19054 +
19055 +void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
19056 +des_cblock (*input);
19057 +des_cblock (*output);
19058 +long length;
19059 +des_key_schedule schedule;
19060 +des_cblock (*ivec);
19061 +int enc;
19062 + {
19063 + register DES_LONG tin0,tin1;
19064 + register DES_LONG tout0,tout1,xor0,xor1;
19065 + register unsigned char *in,*out;
19066 + register long l=length;
19067 + DES_LONG tin[2];
19068 + unsigned char *iv;
19069 +
19070 + in=(unsigned char *)input;
19071 + out=(unsigned char *)output;
19072 + iv=(unsigned char *)ivec;
19073 +
19074 + if (enc)
19075 + {
19076 + c2l(iv,tout0);
19077 + c2l(iv,tout1);
19078 + for (l-=8; l>=0; l-=8)
19079 + {
19080 + c2l(in,tin0);
19081 + c2l(in,tin1);
19082 + tin0^=tout0; tin[0]=tin0;
19083 + tin1^=tout1; tin[1]=tin1;
19084 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
19085 + tout0=tin[0]; l2c(tout0,out);
19086 + tout1=tin[1]; l2c(tout1,out);
19087 + }
19088 + if (l != -8)
19089 + {
19090 + c2ln(in,tin0,tin1,l+8);
19091 + tin0^=tout0; tin[0]=tin0;
19092 + tin1^=tout1; tin[1]=tin1;
19093 + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
19094 + tout0=tin[0]; l2c(tout0,out);
19095 + tout1=tin[1]; l2c(tout1,out);
19096 + }
19097 + iv=(unsigned char *)ivec;
19098 + l2c(tout0,iv);
19099 + l2c(tout1,iv);
19100 + }
19101 + else
19102 + {
19103 + c2l(iv,xor0);
19104 + c2l(iv,xor1);
19105 + for (l-=8; l>=0; l-=8)
19106 + {
19107 + c2l(in,tin0); tin[0]=tin0;
19108 + c2l(in,tin1); tin[1]=tin1;
19109 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
19110 + tout0=tin[0]^xor0;
19111 + tout1=tin[1]^xor1;
19112 + l2c(tout0,out);
19113 + l2c(tout1,out);
19114 + xor0=tin0;
19115 + xor1=tin1;
19116 + }
19117 + if (l != -8)
19118 + {
19119 + c2l(in,tin0); tin[0]=tin0;
19120 + c2l(in,tin1); tin[1]=tin1;
19121 + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
19122 + tout0=tin[0]^xor0;
19123 + tout1=tin[1]^xor1;
19124 + l2cn(tout0,tout1,out,l+8);
19125 + xor0=tin0;
19126 + xor1=tin1;
19127 + }
19128 +
19129 + iv=(unsigned char *)ivec;
19130 + l2c(xor0,iv);
19131 + l2c(xor1,iv);
19132 + }
19133 + tin0=tin1=tout0=tout1=xor0=xor1=0;
19134 + tin[0]=tin[1]=0;
19135 + }
19136 +
19137 +void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
19138 +des_cblock (*input);
19139 +des_cblock (*output);
19140 +long length;
19141 +des_key_schedule ks1;
19142 +des_key_schedule ks2;
19143 +des_key_schedule ks3;
19144 +des_cblock (*ivec);
19145 +int enc;
19146 + {
19147 + register DES_LONG tin0,tin1;
19148 + register DES_LONG tout0,tout1,xor0,xor1;
19149 + register unsigned char *in,*out;
19150 + register long l=length;
19151 + DES_LONG tin[2];
19152 + unsigned char *iv;
19153 +
19154 + in=(unsigned char *)input;
19155 + out=(unsigned char *)output;
19156 + iv=(unsigned char *)ivec;
19157 +
19158 + if (enc)
19159 + {
19160 + c2l(iv,tout0);
19161 + c2l(iv,tout1);
19162 + for (l-=8; l>=0; l-=8)
19163 + {
19164 + c2l(in,tin0);
19165 + c2l(in,tin1);
19166 + tin0^=tout0;
19167 + tin1^=tout1;
19168 +
19169 + tin[0]=tin0;
19170 + tin[1]=tin1;
19171 + des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19172 + tout0=tin[0];
19173 + tout1=tin[1];
19174 +
19175 + l2c(tout0,out);
19176 + l2c(tout1,out);
19177 + }
19178 + if (l != -8)
19179 + {
19180 + c2ln(in,tin0,tin1,l+8);
19181 + tin0^=tout0;
19182 + tin1^=tout1;
19183 +
19184 + tin[0]=tin0;
19185 + tin[1]=tin1;
19186 + des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19187 + tout0=tin[0];
19188 + tout1=tin[1];
19189 +
19190 + l2c(tout0,out);
19191 + l2c(tout1,out);
19192 + }
19193 + iv=(unsigned char *)ivec;
19194 + l2c(tout0,iv);
19195 + l2c(tout1,iv);
19196 + }
19197 + else
19198 + {
19199 + register DES_LONG t0,t1;
19200 +
19201 + c2l(iv,xor0);
19202 + c2l(iv,xor1);
19203 + for (l-=8; l>=0; l-=8)
19204 + {
19205 + c2l(in,tin0);
19206 + c2l(in,tin1);
19207 +
19208 + t0=tin0;
19209 + t1=tin1;
19210 +
19211 + tin[0]=tin0;
19212 + tin[1]=tin1;
19213 + des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19214 + tout0=tin[0];
19215 + tout1=tin[1];
19216 +
19217 + tout0^=xor0;
19218 + tout1^=xor1;
19219 + l2c(tout0,out);
19220 + l2c(tout1,out);
19221 + xor0=t0;
19222 + xor1=t1;
19223 + }
19224 + if (l != -8)
19225 + {
19226 + c2l(in,tin0);
19227 + c2l(in,tin1);
19228 +
19229 + t0=tin0;
19230 + t1=tin1;
19231 +
19232 + tin[0]=tin0;
19233 + tin[1]=tin1;
19234 + des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
19235 + tout0=tin[0];
19236 + tout1=tin[1];
19237 +
19238 + tout0^=xor0;
19239 + tout1^=xor1;
19240 + l2cn(tout0,tout1,out,l+8);
19241 + xor0=t0;
19242 + xor1=t1;
19243 + }
19244 +
19245 + iv=(unsigned char *)ivec;
19246 + l2c(xor0,iv);
19247 + l2c(xor1,iv);
19248 + }
19249 + tin0=tin1=tout0=tout1=xor0=xor1=0;
19250 + tin[0]=tin[1]=0;
19251 + }
19252 +
19253 +#endif /* DES_DEFAULT_OPTIONS */
19254 --- /dev/null Tue Mar 11 13:02:56 2003
19255 +++ linux/net/ipsec/des/des_opts.c Mon Feb 9 13:51:03 2004
19256 @@ -0,0 +1,620 @@
19257 +/* crypto/des/des_opts.c */
19258 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
19259 + * All rights reserved.
19260 + *
19261 + * This package is an SSL implementation written
19262 + * by Eric Young (eay@cryptsoft.com).
19263 + * The implementation was written so as to conform with Netscapes SSL.
19264 + *
19265 + * This library is free for commercial and non-commercial use as long as
19266 + * the following conditions are aheared to. The following conditions
19267 + * apply to all code found in this distribution, be it the RC4, RSA,
19268 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
19269 + * included with this distribution is covered by the same copyright terms
19270 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
19271 + *
19272 + * Copyright remains Eric Young's, and as such any Copyright notices in
19273 + * the code are not to be removed.
19274 + * If this package is used in a product, Eric Young should be given attribution
19275 + * as the author of the parts of the library used.
19276 + * This can be in the form of a textual message at program startup or
19277 + * in documentation (online or textual) provided with the package.
19278 + *
19279 + * Redistribution and use in source and binary forms, with or without
19280 + * modification, are permitted provided that the following conditions
19281 + * are met:
19282 + * 1. Redistributions of source code must retain the copyright
19283 + * notice, this list of conditions and the following disclaimer.
19284 + * 2. Redistributions in binary form must reproduce the above copyright
19285 + * notice, this list of conditions and the following disclaimer in the
19286 + * documentation and/or other materials provided with the distribution.
19287 + * 3. All advertising materials mentioning features or use of this software
19288 + * must display the following acknowledgement:
19289 + * "This product includes cryptographic software written by
19290 + * Eric Young (eay@cryptsoft.com)"
19291 + * The word 'cryptographic' can be left out if the rouines from the library
19292 + * being used are not cryptographic related :-).
19293 + * 4. If you include any Windows specific code (or a derivative thereof) from
19294 + * the apps directory (application code) you must include an acknowledgement:
19295 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
19296 + *
19297 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
19298 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19299 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19300 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19301 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19302 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19303 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
19304 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19305 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
19306 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
19307 + * SUCH DAMAGE.
19308 + *
19309 + * The licence and distribution terms for any publically available version or
19310 + * derivative of this code cannot be changed. i.e. this code cannot simply be
19311 + * copied and put under another distribution licence
19312 + * [including the GNU Public Licence.]
19313 + */
19314 +
19315 +/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
19316 + * This is for machines with 64k code segment size restrictions. */
19317 +
19318 +#ifndef MSDOS
19319 +#define TIMES
19320 +#endif
19321 +
19322 +#include <stdio.h>
19323 +#ifndef MSDOS
19324 +#include <unistd.h>
19325 +#else
19326 +#include <io.h>
19327 +extern void exit();
19328 +#endif
19329 +#include <signal.h>
19330 +#ifndef VMS
19331 +#ifndef _IRIX
19332 +#include <time.h>
19333 +#endif
19334 +#ifdef TIMES
19335 +#include <sys/types.h>
19336 +#include <sys/times.h>
19337 +#endif
19338 +#else /* VMS */
19339 +#include <types.h>
19340 +struct tms {
19341 + time_t tms_utime;
19342 + time_t tms_stime;
19343 + time_t tms_uchild; /* I dunno... */
19344 + time_t tms_uchildsys; /* so these names are a guess :-) */
19345 + }
19346 +#endif
19347 +#ifndef TIMES
19348 +#include <sys/timeb.h>
19349 +#endif
19350 +
19351 +#ifdef sun
19352 +#include <limits.h>
19353 +#include <sys/param.h>
19354 +#endif
19355 +
19356 +#include "des/des_locl.h"
19357 +#include "des/spr.h"
19358 +
19359 +#define DES_DEFAULT_OPTIONS
19360 +
19361 +#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
19362 +#define PART1
19363 +#define PART2
19364 +#define PART3
19365 +#define PART4
19366 +#endif
19367 +
19368 +#ifdef PART1
19369 +
19370 +#undef DES_UNROLL
19371 +#undef DES_RISC1
19372 +#undef DES_RISC2
19373 +#undef DES_PTR
19374 +#undef D_ENCRYPT
19375 +#define des_encrypt des_encrypt_u4_cisc_idx
19376 +#define des_encrypt2 des_encrypt2_u4_cisc_idx
19377 +#define des_encrypt3 des_encrypt3_u4_cisc_idx
19378 +#define des_decrypt3 des_decrypt3_u4_cisc_idx
19379 +#undef HEADER_DES_LOCL_H
19380 +#include "des_enc.c"
19381 +
19382 +#define DES_UNROLL
19383 +#undef DES_RISC1
19384 +#undef DES_RISC2
19385 +#undef DES_PTR
19386 +#undef D_ENCRYPT
19387 +#undef des_encrypt
19388 +#undef des_encrypt2
19389 +#undef des_encrypt3
19390 +#undef des_decrypt3
19391 +#define des_encrypt des_encrypt_u16_cisc_idx
19392 +#define des_encrypt2 des_encrypt2_u16_cisc_idx
19393 +#define des_encrypt3 des_encrypt3_u16_cisc_idx
19394 +#define des_decrypt3 des_decrypt3_u16_cisc_idx
19395 +#undef HEADER_DES_LOCL_H
19396 +#include "des_enc.c"
19397 +
19398 +#undef DES_UNROLL
19399 +#define DES_RISC1
19400 +#undef DES_RISC2
19401 +#undef DES_PTR
19402 +#undef D_ENCRYPT
19403 +#undef des_encrypt
19404 +#undef des_encrypt2
19405 +#undef des_encrypt3
19406 +#undef des_decrypt3
19407 +#define des_encrypt des_encrypt_u4_risc1_idx
19408 +#define des_encrypt2 des_encrypt2_u4_risc1_idx
19409 +#define des_encrypt3 des_encrypt3_u4_risc1_idx
19410 +#define des_decrypt3 des_decrypt3_u4_risc1_idx
19411 +#undef HEADER_DES_LOCL_H
19412 +#include "des_enc.c"
19413 +
19414 +#endif
19415 +
19416 +#ifdef PART2
19417 +
19418 +#undef DES_UNROLL
19419 +#undef DES_RISC1
19420 +#define DES_RISC2
19421 +#undef DES_PTR
19422 +#undef D_ENCRYPT
19423 +#undef des_encrypt
19424 +#undef des_encrypt2
19425 +#undef des_encrypt3
19426 +#undef des_decrypt3
19427 +#define des_encrypt des_encrypt_u4_risc2_idx
19428 +#define des_encrypt2 des_encrypt2_u4_risc2_idx
19429 +#define des_encrypt3 des_encrypt3_u4_risc2_idx
19430 +#define des_decrypt3 des_decrypt3_u4_risc2_idx
19431 +#undef HEADER_DES_LOCL_H
19432 +#include "des_enc.c"
19433 +
19434 +#define DES_UNROLL
19435 +#define DES_RISC1
19436 +#undef DES_RISC2
19437 +#undef DES_PTR
19438 +#undef D_ENCRYPT
19439 +#undef des_encrypt
19440 +#undef des_encrypt2
19441 +#undef des_encrypt3
19442 +#undef des_decrypt3
19443 +#define des_encrypt des_encrypt_u16_risc1_idx
19444 +#define des_encrypt2 des_encrypt2_u16_risc1_idx
19445 +#define des_encrypt3 des_encrypt3_u16_risc1_idx
19446 +#define des_decrypt3 des_decrypt3_u16_risc1_idx
19447 +#undef HEADER_DES_LOCL_H
19448 +#include "des_enc.c"
19449 +
19450 +#define DES_UNROLL
19451 +#undef DES_RISC1
19452 +#define DES_RISC2
19453 +#undef DES_PTR
19454 +#undef D_ENCRYPT
19455 +#undef des_encrypt
19456 +#undef des_encrypt2
19457 +#undef des_encrypt3
19458 +#undef des_decrypt3
19459 +#define des_encrypt des_encrypt_u16_risc2_idx
19460 +#define des_encrypt2 des_encrypt2_u16_risc2_idx
19461 +#define des_encrypt3 des_encrypt3_u16_risc2_idx
19462 +#define des_decrypt3 des_decrypt3_u16_risc2_idx
19463 +#undef HEADER_DES_LOCL_H
19464 +#include "des_enc.c"
19465 +
19466 +#endif
19467 +
19468 +#ifdef PART3
19469 +
19470 +#undef DES_UNROLL
19471 +#undef DES_RISC1
19472 +#undef DES_RISC2
19473 +#define DES_PTR
19474 +#undef D_ENCRYPT
19475 +#undef des_encrypt
19476 +#undef des_encrypt2
19477 +#undef des_encrypt3
19478 +#undef des_decrypt3
19479 +#define des_encrypt des_encrypt_u4_cisc_ptr
19480 +#define des_encrypt2 des_encrypt2_u4_cisc_ptr
19481 +#define des_encrypt3 des_encrypt3_u4_cisc_ptr
19482 +#define des_decrypt3 des_decrypt3_u4_cisc_ptr
19483 +#undef HEADER_DES_LOCL_H
19484 +#include "des_enc.c"
19485 +
19486 +#define DES_UNROLL
19487 +#undef DES_RISC1
19488 +#undef DES_RISC2
19489 +#define DES_PTR
19490 +#undef D_ENCRYPT
19491 +#undef des_encrypt
19492 +#undef des_encrypt2
19493 +#undef des_encrypt3
19494 +#undef des_decrypt3
19495 +#define des_encrypt des_encrypt_u16_cisc_ptr
19496 +#define des_encrypt2 des_encrypt2_u16_cisc_ptr
19497 +#define des_encrypt3 des_encrypt3_u16_cisc_ptr
19498 +#define des_decrypt3 des_decrypt3_u16_cisc_ptr
19499 +#undef HEADER_DES_LOCL_H
19500 +#include "des_enc.c"
19501 +
19502 +#undef DES_UNROLL
19503 +#define DES_RISC1
19504 +#undef DES_RISC2
19505 +#define DES_PTR
19506 +#undef D_ENCRYPT
19507 +#undef des_encrypt
19508 +#undef des_encrypt2
19509 +#undef des_encrypt3
19510 +#undef des_decrypt3
19511 +#define des_encrypt des_encrypt_u4_risc1_ptr
19512 +#define des_encrypt2 des_encrypt2_u4_risc1_ptr
19513 +#define des_encrypt3 des_encrypt3_u4_risc1_ptr
19514 +#define des_decrypt3 des_decrypt3_u4_risc1_ptr
19515 +#undef HEADER_DES_LOCL_H
19516 +#include "des_enc.c"
19517 +
19518 +#endif
19519 +
19520 +#ifdef PART4
19521 +
19522 +#undef DES_UNROLL
19523 +#undef DES_RISC1
19524 +#define DES_RISC2
19525 +#define DES_PTR
19526 +#undef D_ENCRYPT
19527 +#undef des_encrypt
19528 +#undef des_encrypt2
19529 +#undef des_encrypt3
19530 +#undef des_decrypt3
19531 +#define des_encrypt des_encrypt_u4_risc2_ptr
19532 +#define des_encrypt2 des_encrypt2_u4_risc2_ptr
19533 +#define des_encrypt3 des_encrypt3_u4_risc2_ptr
19534 +#define des_decrypt3 des_decrypt3_u4_risc2_ptr
19535 +#undef HEADER_DES_LOCL_H
19536 +#include "des_enc.c"
19537 +
19538 +#define DES_UNROLL
19539 +#define DES_RISC1
19540 +#undef DES_RISC2
19541 +#define DES_PTR
19542 +#undef D_ENCRYPT
19543 +#undef des_encrypt
19544 +#undef des_encrypt2
19545 +#undef des_encrypt3
19546 +#undef des_decrypt3
19547 +#define des_encrypt des_encrypt_u16_risc1_ptr
19548 +#define des_encrypt2 des_encrypt2_u16_risc1_ptr
19549 +#define des_encrypt3 des_encrypt3_u16_risc1_ptr
19550 +#define des_decrypt3 des_decrypt3_u16_risc1_ptr
19551 +#undef HEADER_DES_LOCL_H
19552 +#include "des_enc.c"
19553 +
19554 +#define DES_UNROLL
19555 +#undef DES_RISC1
19556 +#define DES_RISC2
19557 +#define DES_PTR
19558 +#undef D_ENCRYPT
19559 +#undef des_encrypt
19560 +#undef des_encrypt2
19561 +#undef des_encrypt3
19562 +#undef des_decrypt3
19563 +#define des_encrypt des_encrypt_u16_risc2_ptr
19564 +#define des_encrypt2 des_encrypt2_u16_risc2_ptr
19565 +#define des_encrypt3 des_encrypt3_u16_risc2_ptr
19566 +#define des_decrypt3 des_decrypt3_u16_risc2_ptr
19567 +#undef HEADER_DES_LOCL_H
19568 +#include "des_enc.c"
19569 +
19570 +#endif
19571 +
19572 +/* The following if from times(3) man page. It may need to be changed */
19573 +#ifndef HZ
19574 +# ifndef CLK_TCK
19575 +# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
19576 +# ifndef VMS
19577 +# define HZ 100.0
19578 +# else /* VMS */
19579 +# define HZ 100.0
19580 +# endif
19581 +# else /* _BSD_CLK_TCK_ */
19582 +# define HZ ((double)_BSD_CLK_TCK_)
19583 +# endif
19584 +# else /* CLK_TCK */
19585 +# define HZ ((double)CLK_TCK)
19586 +# endif
19587 +#endif
19588 +
19589 +#define BUFSIZE ((long)1024)
19590 +long run=0;
19591 +
19592 +#ifndef NOPROTO
19593 +double Time_F(int s);
19594 +#else
19595 +double Time_F();
19596 +#endif
19597 +
19598 +#ifdef SIGALRM
19599 +#if defined(__STDC__) || defined(sgi)
19600 +#define SIGRETTYPE void
19601 +#else
19602 +#define SIGRETTYPE int
19603 +#endif
19604 +
19605 +#ifndef NOPROTO
19606 +SIGRETTYPE sig_done(int sig);
19607 +#else
19608 +SIGRETTYPE sig_done();
19609 +#endif
19610 +
19611 +SIGRETTYPE sig_done(sig)
19612 +int sig;
19613 + {
19614 + signal(SIGALRM,sig_done);
19615 + run=0;
19616 +#ifdef LINT
19617 + sig=sig;
19618 +#endif
19619 + }
19620 +#endif
19621 +
19622 +#define START 0
19623 +#define STOP 1
19624 +
19625 +double Time_F(s)
19626 +int s;
19627 + {
19628 + double ret;
19629 +#ifdef TIMES
19630 + static struct tms tstart,tend;
19631 +
19632 + if (s == START)
19633 + {
19634 + times(&tstart);
19635 + return(0);
19636 + }
19637 + else
19638 + {
19639 + times(&tend);
19640 + ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
19641 + return((ret == 0.0)?1e-6:ret);
19642 + }
19643 +#else /* !times() */
19644 + static struct timeb tstart,tend;
19645 + long i;
19646 +
19647 + if (s == START)
19648 + {
19649 + ftime(&tstart);
19650 + return(0);
19651 + }
19652 + else
19653 + {
19654 + ftime(&tend);
19655 + i=(long)tend.millitm-(long)tstart.millitm;
19656 + ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
19657 + return((ret == 0.0)?1e-6:ret);
19658 + }
19659 +#endif
19660 + }
19661 +
19662 +#ifdef SIGALRM
19663 +#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
19664 +#else
19665 +#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
19666 +#endif
19667 +
19668 +#define time_it(func,name,index) \
19669 + print_name(name); \
19670 + Time_F(START); \
19671 + for (count=0,run=1; COND(cb); count++) \
19672 + { \
19673 + unsigned long d[2]; \
19674 + func(d,&(sch[0]),DES_ENCRYPT); \
19675 + } \
19676 + tm[index]=Time_F(STOP); \
19677 + fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
19678 + tm[index]=((double)COUNT(cb))/tm[index];
19679 +
19680 +#define print_it(name,index) \
19681 + fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
19682 + tm[index]*8,1.0e6/tm[index]);
19683 +
19684 +int main(argc,argv)
19685 +int argc;
19686 +char **argv;
19687 + {
19688 + long count;
19689 + static unsigned char buf[BUFSIZE];
19690 + static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
19691 + static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
19692 + static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
19693 + des_key_schedule sch,sch2,sch3;
19694 + double d,tm[16],max=0;
19695 + int rank[16];
19696 + char *str[16];
19697 + int max_idx=0,i,num=0,j;
19698 +#ifndef SIGALARM
19699 + long ca,cb,cc,cd,ce;
19700 +#endif
19701 +
19702 + for (i=0; i<12; i++)
19703 + {
19704 + tm[i]=0.0;
19705 + rank[i]=0;
19706 + }
19707 +
19708 +#ifndef TIMES
19709 + fprintf(stderr,"To get the most acurate results, try to run this\n");
19710 + fprintf(stderr,"program when this computer is idle.\n");
19711 +#endif
19712 +
19713 + des_set_key((C_Block *)key,sch);
19714 + des_set_key((C_Block *)key2,sch2);
19715 + des_set_key((C_Block *)key3,sch3);
19716 +
19717 +#ifndef SIGALRM
19718 + fprintf(stderr,"First we calculate the approximate speed ...\n");
19719 + des_set_key((C_Block *)key,sch);
19720 + count=10;
19721 + do {
19722 + long i;
19723 + unsigned long data[2];
19724 +
19725 + count*=2;
19726 + Time_F(START);
19727 + for (i=count; i; i--)
19728 + des_encrypt(data,&(sch[0]),DES_ENCRYPT);
19729 + d=Time_F(STOP);
19730 + } while (d < 3.0);
19731 + ca=count;
19732 + cb=count*3;
19733 + cc=count*3*8/BUFSIZE+1;
19734 + cd=count*8/BUFSIZE+1;
19735 +
19736 + ce=count/20+1;
19737 +#define COND(d) (count != (d))
19738 +#define COUNT(d) (d)
19739 +#else
19740 +#define COND(c) (run)
19741 +#define COUNT(d) (count)
19742 + signal(SIGALRM,sig_done);
19743 + alarm(10);
19744 +#endif
19745 +
19746 +#ifdef PART1
19747 + time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
19748 + time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
19749 + time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
19750 + num+=3;
19751 +#endif
19752 +#ifdef PART2
19753 + time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
19754 + time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
19755 + time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
19756 + num+=3;
19757 +#endif
19758 +#ifdef PART3
19759 + time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
19760 + time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
19761 + time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
19762 + num+=3;
19763 +#endif
19764 +#ifdef PART4
19765 + time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
19766 + time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
19767 + time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
19768 + num+=3;
19769 +#endif
19770 +
19771 +#ifdef PART1
19772 + str[0]=" 4 c i";
19773 + print_it("des_encrypt_u4_cisc_idx ",0);
19774 + max=tm[0];
19775 + max_idx=0;
19776 + str[1]="16 c i";
19777 + print_it("des_encrypt_u16_cisc_idx ",1);
19778 + if (max < tm[1]) { max=tm[1]; max_idx=1; }
19779 + str[2]=" 4 r1 i";
19780 + print_it("des_encrypt_u4_risc1_idx ",2);
19781 + if (max < tm[2]) { max=tm[2]; max_idx=2; }
19782 +#endif
19783 +#ifdef PART2
19784 + str[3]="16 r1 i";
19785 + print_it("des_encrypt_u16_risc1_idx",3);
19786 + if (max < tm[3]) { max=tm[3]; max_idx=3; }
19787 + str[4]=" 4 r2 i";
19788 + print_it("des_encrypt_u4_risc2_idx ",4);
19789 + if (max < tm[4]) { max=tm[4]; max_idx=4; }
19790 + str[5]="16 r2 i";
19791 + print_it("des_encrypt_u16_risc2_idx",5);
19792 + if (max < tm[5]) { max=tm[5]; max_idx=5; }
19793 +#endif
19794 +#ifdef PART3
19795 + str[6]=" 4 c p";
19796 + print_it("des_encrypt_u4_cisc_ptr ",6);
19797 + if (max < tm[6]) { max=tm[6]; max_idx=6; }
19798 + str[7]="16 c p";
19799 + print_it("des_encrypt_u16_cisc_ptr ",7);
19800 + if (max < tm[7]) { max=tm[7]; max_idx=7; }
19801 + str[8]=" 4 r1 p";
19802 + print_it("des_encrypt_u4_risc1_ptr ",8);
19803 + if (max < tm[8]) { max=tm[8]; max_idx=8; }
19804 +#endif
19805 +#ifdef PART4
19806 + str[9]="16 r1 p";
19807 + print_it("des_encrypt_u16_risc1_ptr",9);
19808 + if (max < tm[9]) { max=tm[9]; max_idx=9; }
19809 + str[10]=" 4 r2 p";
19810 + print_it("des_encrypt_u4_risc2_ptr ",10);
19811 + if (max < tm[10]) { max=tm[10]; max_idx=10; }
19812 + str[11]="16 r2 p";
19813 + print_it("des_encrypt_u16_risc2_ptr",11);
19814 + if (max < tm[11]) { max=tm[11]; max_idx=11; }
19815 +#endif
19816 + printf("options des ecb/s\n");
19817 + printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
19818 + d=tm[max_idx];
19819 + tm[max_idx]= -2.0;
19820 + max= -1.0;
19821 + for (;;)
19822 + {
19823 + for (i=0; i<12; i++)
19824 + {
19825 + if (max < tm[i]) { max=tm[i]; j=i; }
19826 + }
19827 + if (max < 0.0) break;
19828 + printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
19829 + tm[j]= -2.0;
19830 + max= -1.0;
19831 + }
19832 +
19833 + switch (max_idx)
19834 + {
19835 + case 0:
19836 + printf("-DDES_DEFAULT_OPTIONS\n");
19837 + break;
19838 + case 1:
19839 + printf("-DDES_UNROLL\n");
19840 + break;
19841 + case 2:
19842 + printf("-DDES_RISC1\n");
19843 + break;
19844 + case 3:
19845 + printf("-DDES_UNROLL -DDES_RISC1\n");
19846 + break;
19847 + case 4:
19848 + printf("-DDES_RISC2\n");
19849 + break;
19850 + case 5:
19851 + printf("-DDES_UNROLL -DDES_RISC2\n");
19852 + break;
19853 + case 6:
19854 + printf("-DDES_PTR\n");
19855 + break;
19856 + case 7:
19857 + printf("-DDES_UNROLL -DDES_PTR\n");
19858 + break;
19859 + case 8:
19860 + printf("-DDES_RISC1 -DDES_PTR\n");
19861 + break;
19862 + case 9:
19863 + printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
19864 + break;
19865 + case 10:
19866 + printf("-DDES_RISC2 -DDES_PTR\n");
19867 + break;
19868 + case 11:
19869 + printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
19870 + break;
19871 + }
19872 + exit(0);
19873 +#if defined(LINT) || defined(MSDOS)
19874 + return(0);
19875 +#endif
19876 + }
19877 --- /dev/null Tue Mar 11 13:02:56 2003
19878 +++ linux/net/ipsec/des/dx86unix.S Mon Feb 9 13:51:03 2004
19879 @@ -0,0 +1,3160 @@
19880 +/*
19881 + * This file was originally generated by Michael Richardson <mcr@freeswan.org>
19882 + * via the perl scripts found in the ASM subdir. It remains copyright of
19883 + * Eric Young, see the file COPYRIGHT.
19884 + *
19885 + * This was last done on October 9, 2002.
19886 + *
19887 + * While this file does not need to go through cpp, we pass it through
19888 + * CPP by naming it dx86unix.S instead of dx86unix.s because there is
19889 + * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
19890 + * which may contain stuff that AS doesn't understand instead of
19891 + * referencing EXTRA_AFLAGS.
19892 + */
19893 +
19894 + .file "dx86unix.S"
19895 + .version "01.01"
19896 +.text
19897 + .align 16
19898 +.globl des_encrypt
19899 + .type des_encrypt , @function
19900 +des_encrypt:
19901 + pushl %esi
19902 + pushl %edi
19903 +
19904 +
19905 + movl 12(%esp), %esi
19906 + xorl %ecx, %ecx
19907 + pushl %ebx
19908 + pushl %ebp
19909 + movl (%esi), %eax
19910 + movl 28(%esp), %ebx
19911 + movl 4(%esi), %edi
19912 +
19913 +
19914 + roll $4, %eax
19915 + movl %eax, %esi
19916 + xorl %edi, %eax
19917 + andl $0xf0f0f0f0, %eax
19918 + xorl %eax, %esi
19919 + xorl %eax, %edi
19920 +
19921 + roll $20, %edi
19922 + movl %edi, %eax
19923 + xorl %esi, %edi
19924 + andl $0xfff0000f, %edi
19925 + xorl %edi, %eax
19926 + xorl %edi, %esi
19927 +
19928 + roll $14, %eax
19929 + movl %eax, %edi
19930 + xorl %esi, %eax
19931 + andl $0x33333333, %eax
19932 + xorl %eax, %edi
19933 + xorl %eax, %esi
19934 +
19935 + roll $22, %esi
19936 + movl %esi, %eax
19937 + xorl %edi, %esi
19938 + andl $0x03fc03fc, %esi
19939 + xorl %esi, %eax
19940 + xorl %esi, %edi
19941 +
19942 + roll $9, %eax
19943 + movl %eax, %esi
19944 + xorl %edi, %eax
19945 + andl $0xaaaaaaaa, %eax
19946 + xorl %eax, %esi
19947 + xorl %eax, %edi
19948 +
19949 +.byte 209
19950 +.byte 199
19951 + movl 24(%esp), %ebp
19952 + cmpl $0, %ebx
19953 + je .L000start_decrypt
19954 +
19955 +
19956 + movl (%ebp), %eax
19957 + xorl %ebx, %ebx
19958 + movl 4(%ebp), %edx
19959 + xorl %esi, %eax
19960 + xorl %esi, %edx
19961 + andl $0xfcfcfcfc, %eax
19962 + andl $0xcfcfcfcf, %edx
19963 + movb %al, %bl
19964 + movb %ah, %cl
19965 + rorl $4, %edx
19966 + movl des_SPtrans(%ebx),%ebp
19967 + movb %dl, %bl
19968 + xorl %ebp, %edi
19969 + movl 0x200+des_SPtrans(%ecx),%ebp
19970 + xorl %ebp, %edi
19971 + movb %dh, %cl
19972 + shrl $16, %eax
19973 + movl 0x100+des_SPtrans(%ebx),%ebp
19974 + xorl %ebp, %edi
19975 + movb %ah, %bl
19976 + shrl $16, %edx
19977 + movl 0x300+des_SPtrans(%ecx),%ebp
19978 + xorl %ebp, %edi
19979 + movl 24(%esp), %ebp
19980 + movb %dh, %cl
19981 + andl $0xff, %eax
19982 + andl $0xff, %edx
19983 + movl 0x600+des_SPtrans(%ebx),%ebx
19984 + xorl %ebx, %edi
19985 + movl 0x700+des_SPtrans(%ecx),%ebx
19986 + xorl %ebx, %edi
19987 + movl 0x400+des_SPtrans(%eax),%ebx
19988 + xorl %ebx, %edi
19989 + movl 0x500+des_SPtrans(%edx),%ebx
19990 + xorl %ebx, %edi
19991 +
19992 +
19993 + movl 8(%ebp), %eax
19994 + xorl %ebx, %ebx
19995 + movl 12(%ebp), %edx
19996 + xorl %edi, %eax
19997 + xorl %edi, %edx
19998 + andl $0xfcfcfcfc, %eax
19999 + andl $0xcfcfcfcf, %edx
20000 + movb %al, %bl
20001 + movb %ah, %cl
20002 + rorl $4, %edx
20003 + movl des_SPtrans(%ebx),%ebp
20004 + movb %dl, %bl
20005 + xorl %ebp, %esi
20006 + movl 0x200+des_SPtrans(%ecx),%ebp
20007 + xorl %ebp, %esi
20008 + movb %dh, %cl
20009 + shrl $16, %eax
20010 + movl 0x100+des_SPtrans(%ebx),%ebp
20011 + xorl %ebp, %esi
20012 + movb %ah, %bl
20013 + shrl $16, %edx
20014 + movl 0x300+des_SPtrans(%ecx),%ebp
20015 + xorl %ebp, %esi
20016 + movl 24(%esp), %ebp
20017 + movb %dh, %cl
20018 + andl $0xff, %eax
20019 + andl $0xff, %edx
20020 + movl 0x600+des_SPtrans(%ebx),%ebx
20021 + xorl %ebx, %esi
20022 + movl 0x700+des_SPtrans(%ecx),%ebx
20023 + xorl %ebx, %esi
20024 + movl 0x400+des_SPtrans(%eax),%ebx
20025 + xorl %ebx, %esi
20026 + movl 0x500+des_SPtrans(%edx),%ebx
20027 + xorl %ebx, %esi
20028 +
20029 +
20030 + movl 16(%ebp), %eax
20031 + xorl %ebx, %ebx
20032 + movl 20(%ebp), %edx
20033 + xorl %esi, %eax
20034 + xorl %esi, %edx
20035 + andl $0xfcfcfcfc, %eax
20036 + andl $0xcfcfcfcf, %edx
20037 + movb %al, %bl
20038 + movb %ah, %cl
20039 + rorl $4, %edx
20040 + movl des_SPtrans(%ebx),%ebp
20041 + movb %dl, %bl
20042 + xorl %ebp, %edi
20043 + movl 0x200+des_SPtrans(%ecx),%ebp
20044 + xorl %ebp, %edi
20045 + movb %dh, %cl
20046 + shrl $16, %eax
20047 + movl 0x100+des_SPtrans(%ebx),%ebp
20048 + xorl %ebp, %edi
20049 + movb %ah, %bl
20050 + shrl $16, %edx
20051 + movl 0x300+des_SPtrans(%ecx),%ebp
20052 + xorl %ebp, %edi
20053 + movl 24(%esp), %ebp
20054 + movb %dh, %cl
20055 + andl $0xff, %eax
20056 + andl $0xff, %edx
20057 + movl 0x600+des_SPtrans(%ebx),%ebx
20058 + xorl %ebx, %edi
20059 + movl 0x700+des_SPtrans(%ecx),%ebx
20060 + xorl %ebx, %edi
20061 + movl 0x400+des_SPtrans(%eax),%ebx
20062 + xorl %ebx, %edi
20063 + movl 0x500+des_SPtrans(%edx),%ebx
20064 + xorl %ebx, %edi
20065 +
20066 +
20067 + movl 24(%ebp), %eax
20068 + xorl %ebx, %ebx
20069 + movl 28(%ebp), %edx
20070 + xorl %edi, %eax
20071 + xorl %edi, %edx
20072 + andl $0xfcfcfcfc, %eax
20073 + andl $0xcfcfcfcf, %edx
20074 + movb %al, %bl
20075 + movb %ah, %cl
20076 + rorl $4, %edx
20077 + movl des_SPtrans(%ebx),%ebp
20078 + movb %dl, %bl
20079 + xorl %ebp, %esi
20080 + movl 0x200+des_SPtrans(%ecx),%ebp
20081 + xorl %ebp, %esi
20082 + movb %dh, %cl
20083 + shrl $16, %eax
20084 + movl 0x100+des_SPtrans(%ebx),%ebp
20085 + xorl %ebp, %esi
20086 + movb %ah, %bl
20087 + shrl $16, %edx
20088 + movl 0x300+des_SPtrans(%ecx),%ebp
20089 + xorl %ebp, %esi
20090 + movl 24(%esp), %ebp
20091 + movb %dh, %cl
20092 + andl $0xff, %eax
20093 + andl $0xff, %edx
20094 + movl 0x600+des_SPtrans(%ebx),%ebx
20095 + xorl %ebx, %esi
20096 + movl 0x700+des_SPtrans(%ecx),%ebx
20097 + xorl %ebx, %esi
20098 + movl 0x400+des_SPtrans(%eax),%ebx
20099 + xorl %ebx, %esi
20100 + movl 0x500+des_SPtrans(%edx),%ebx
20101 + xorl %ebx, %esi
20102 +
20103 +
20104 + movl 32(%ebp), %eax
20105 + xorl %ebx, %ebx
20106 + movl 36(%ebp), %edx
20107 + xorl %esi, %eax
20108 + xorl %esi, %edx
20109 + andl $0xfcfcfcfc, %eax
20110 + andl $0xcfcfcfcf, %edx
20111 + movb %al, %bl
20112 + movb %ah, %cl
20113 + rorl $4, %edx
20114 + movl des_SPtrans(%ebx),%ebp
20115 + movb %dl, %bl
20116 + xorl %ebp, %edi
20117 + movl 0x200+des_SPtrans(%ecx),%ebp
20118 + xorl %ebp, %edi
20119 + movb %dh, %cl
20120 + shrl $16, %eax
20121 + movl 0x100+des_SPtrans(%ebx),%ebp
20122 + xorl %ebp, %edi
20123 + movb %ah, %bl
20124 + shrl $16, %edx
20125 + movl 0x300+des_SPtrans(%ecx),%ebp
20126 + xorl %ebp, %edi
20127 + movl 24(%esp), %ebp
20128 + movb %dh, %cl
20129 + andl $0xff, %eax
20130 + andl $0xff, %edx
20131 + movl 0x600+des_SPtrans(%ebx),%ebx
20132 + xorl %ebx, %edi
20133 + movl 0x700+des_SPtrans(%ecx),%ebx
20134 + xorl %ebx, %edi
20135 + movl 0x400+des_SPtrans(%eax),%ebx
20136 + xorl %ebx, %edi
20137 + movl 0x500+des_SPtrans(%edx),%ebx
20138 + xorl %ebx, %edi
20139 +
20140 +
20141 + movl 40(%ebp), %eax
20142 + xorl %ebx, %ebx
20143 + movl 44(%ebp), %edx
20144 + xorl %edi, %eax
20145 + xorl %edi, %edx
20146 + andl $0xfcfcfcfc, %eax
20147 + andl $0xcfcfcfcf, %edx
20148 + movb %al, %bl
20149 + movb %ah, %cl
20150 + rorl $4, %edx
20151 + movl des_SPtrans(%ebx),%ebp
20152 + movb %dl, %bl
20153 + xorl %ebp, %esi
20154 + movl 0x200+des_SPtrans(%ecx),%ebp
20155 + xorl %ebp, %esi
20156 + movb %dh, %cl
20157 + shrl $16, %eax
20158 + movl 0x100+des_SPtrans(%ebx),%ebp
20159 + xorl %ebp, %esi
20160 + movb %ah, %bl
20161 + shrl $16, %edx
20162 + movl 0x300+des_SPtrans(%ecx),%ebp
20163 + xorl %ebp, %esi
20164 + movl 24(%esp), %ebp
20165 + movb %dh, %cl
20166 + andl $0xff, %eax
20167 + andl $0xff, %edx
20168 + movl 0x600+des_SPtrans(%ebx),%ebx
20169 + xorl %ebx, %esi
20170 + movl 0x700+des_SPtrans(%ecx),%ebx
20171 + xorl %ebx, %esi
20172 + movl 0x400+des_SPtrans(%eax),%ebx
20173 + xorl %ebx, %esi
20174 + movl 0x500+des_SPtrans(%edx),%ebx
20175 + xorl %ebx, %esi
20176 +
20177 +
20178 + movl 48(%ebp), %eax
20179 + xorl %ebx, %ebx
20180 + movl 52(%ebp), %edx
20181 + xorl %esi, %eax
20182 + xorl %esi, %edx
20183 + andl $0xfcfcfcfc, %eax
20184 + andl $0xcfcfcfcf, %edx
20185 + movb %al, %bl
20186 + movb %ah, %cl
20187 + rorl $4, %edx
20188 + movl des_SPtrans(%ebx),%ebp
20189 + movb %dl, %bl
20190 + xorl %ebp, %edi
20191 + movl 0x200+des_SPtrans(%ecx),%ebp
20192 + xorl %ebp, %edi
20193 + movb %dh, %cl
20194 + shrl $16, %eax
20195 + movl 0x100+des_SPtrans(%ebx),%ebp
20196 + xorl %ebp, %edi
20197 + movb %ah, %bl
20198 + shrl $16, %edx
20199 + movl 0x300+des_SPtrans(%ecx),%ebp
20200 + xorl %ebp, %edi
20201 + movl 24(%esp), %ebp
20202 + movb %dh, %cl
20203 + andl $0xff, %eax
20204 + andl $0xff, %edx
20205 + movl 0x600+des_SPtrans(%ebx),%ebx
20206 + xorl %ebx, %edi
20207 + movl 0x700+des_SPtrans(%ecx),%ebx
20208 + xorl %ebx, %edi
20209 + movl 0x400+des_SPtrans(%eax),%ebx
20210 + xorl %ebx, %edi
20211 + movl 0x500+des_SPtrans(%edx),%ebx
20212 + xorl %ebx, %edi
20213 +
20214 +
20215 + movl 56(%ebp), %eax
20216 + xorl %ebx, %ebx
20217 + movl 60(%ebp), %edx
20218 + xorl %edi, %eax
20219 + xorl %edi, %edx
20220 + andl $0xfcfcfcfc, %eax
20221 + andl $0xcfcfcfcf, %edx
20222 + movb %al, %bl
20223 + movb %ah, %cl
20224 + rorl $4, %edx
20225 + movl des_SPtrans(%ebx),%ebp
20226 + movb %dl, %bl
20227 + xorl %ebp, %esi
20228 + movl 0x200+des_SPtrans(%ecx),%ebp
20229 + xorl %ebp, %esi
20230 + movb %dh, %cl
20231 + shrl $16, %eax
20232 + movl 0x100+des_SPtrans(%ebx),%ebp
20233 + xorl %ebp, %esi
20234 + movb %ah, %bl
20235 + shrl $16, %edx
20236 + movl 0x300+des_SPtrans(%ecx),%ebp
20237 + xorl %ebp, %esi
20238 + movl 24(%esp), %ebp
20239 + movb %dh, %cl
20240 + andl $0xff, %eax
20241 + andl $0xff, %edx
20242 + movl 0x600+des_SPtrans(%ebx),%ebx
20243 + xorl %ebx, %esi
20244 + movl 0x700+des_SPtrans(%ecx),%ebx
20245 + xorl %ebx, %esi
20246 + movl 0x400+des_SPtrans(%eax),%ebx
20247 + xorl %ebx, %esi
20248 + movl 0x500+des_SPtrans(%edx),%ebx
20249 + xorl %ebx, %esi
20250 +
20251 +
20252 + movl 64(%ebp), %eax
20253 + xorl %ebx, %ebx
20254 + movl 68(%ebp), %edx
20255 + xorl %esi, %eax
20256 + xorl %esi, %edx
20257 + andl $0xfcfcfcfc, %eax
20258 + andl $0xcfcfcfcf, %edx
20259 + movb %al, %bl
20260 + movb %ah, %cl
20261 + rorl $4, %edx
20262 + movl des_SPtrans(%ebx),%ebp
20263 + movb %dl, %bl
20264 + xorl %ebp, %edi
20265 + movl 0x200+des_SPtrans(%ecx),%ebp
20266 + xorl %ebp, %edi
20267 + movb %dh, %cl
20268 + shrl $16, %eax
20269 + movl 0x100+des_SPtrans(%ebx),%ebp
20270 + xorl %ebp, %edi
20271 + movb %ah, %bl
20272 + shrl $16, %edx
20273 + movl 0x300+des_SPtrans(%ecx),%ebp
20274 + xorl %ebp, %edi
20275 + movl 24(%esp), %ebp
20276 + movb %dh, %cl
20277 + andl $0xff, %eax
20278 + andl $0xff, %edx
20279 + movl 0x600+des_SPtrans(%ebx),%ebx
20280 + xorl %ebx, %edi
20281 + movl 0x700+des_SPtrans(%ecx),%ebx
20282 + xorl %ebx, %edi
20283 + movl 0x400+des_SPtrans(%eax),%ebx
20284 + xorl %ebx, %edi
20285 + movl 0x500+des_SPtrans(%edx),%ebx
20286 + xorl %ebx, %edi
20287 +
20288 +
20289 + movl 72(%ebp), %eax
20290 + xorl %ebx, %ebx
20291 + movl 76(%ebp), %edx
20292 + xorl %edi, %eax
20293 + xorl %edi, %edx
20294 + andl $0xfcfcfcfc, %eax
20295 + andl $0xcfcfcfcf, %edx
20296 + movb %al, %bl
20297 + movb %ah, %cl
20298 + rorl $4, %edx
20299 + movl des_SPtrans(%ebx),%ebp
20300 + movb %dl, %bl
20301 + xorl %ebp, %esi
20302 + movl 0x200+des_SPtrans(%ecx),%ebp
20303 + xorl %ebp, %esi
20304 + movb %dh, %cl
20305 + shrl $16, %eax
20306 + movl 0x100+des_SPtrans(%ebx),%ebp
20307 + xorl %ebp, %esi
20308 + movb %ah, %bl
20309 + shrl $16, %edx
20310 + movl 0x300+des_SPtrans(%ecx),%ebp
20311 + xorl %ebp, %esi
20312 + movl 24(%esp), %ebp
20313 + movb %dh, %cl
20314 + andl $0xff, %eax
20315 + andl $0xff, %edx
20316 + movl 0x600+des_SPtrans(%ebx),%ebx
20317 + xorl %ebx, %esi
20318 + movl 0x700+des_SPtrans(%ecx),%ebx
20319 + xorl %ebx, %esi
20320 + movl 0x400+des_SPtrans(%eax),%ebx
20321 + xorl %ebx, %esi
20322 + movl 0x500+des_SPtrans(%edx),%ebx
20323 + xorl %ebx, %esi
20324 +
20325 +
20326 + movl 80(%ebp), %eax
20327 + xorl %ebx, %ebx
20328 + movl 84(%ebp), %edx
20329 + xorl %esi, %eax
20330 + xorl %esi, %edx
20331 + andl $0xfcfcfcfc, %eax
20332 + andl $0xcfcfcfcf, %edx
20333 + movb %al, %bl
20334 + movb %ah, %cl
20335 + rorl $4, %edx
20336 + movl des_SPtrans(%ebx),%ebp
20337 + movb %dl, %bl
20338 + xorl %ebp, %edi
20339 + movl 0x200+des_SPtrans(%ecx),%ebp
20340 + xorl %ebp, %edi
20341 + movb %dh, %cl
20342 + shrl $16, %eax
20343 + movl 0x100+des_SPtrans(%ebx),%ebp
20344 + xorl %ebp, %edi
20345 + movb %ah, %bl
20346 + shrl $16, %edx
20347 + movl 0x300+des_SPtrans(%ecx),%ebp
20348 + xorl %ebp, %edi
20349 + movl 24(%esp), %ebp
20350 + movb %dh, %cl
20351 + andl $0xff, %eax
20352 + andl $0xff, %edx
20353 + movl 0x600+des_SPtrans(%ebx),%ebx
20354 + xorl %ebx, %edi
20355 + movl 0x700+des_SPtrans(%ecx),%ebx
20356 + xorl %ebx, %edi
20357 + movl 0x400+des_SPtrans(%eax),%ebx
20358 + xorl %ebx, %edi
20359 + movl 0x500+des_SPtrans(%edx),%ebx
20360 + xorl %ebx, %edi
20361 +
20362 +
20363 + movl 88(%ebp), %eax
20364 + xorl %ebx, %ebx
20365 + movl 92(%ebp), %edx
20366 + xorl %edi, %eax
20367 + xorl %edi, %edx
20368 + andl $0xfcfcfcfc, %eax
20369 + andl $0xcfcfcfcf, %edx
20370 + movb %al, %bl
20371 + movb %ah, %cl
20372 + rorl $4, %edx
20373 + movl des_SPtrans(%ebx),%ebp
20374 + movb %dl, %bl
20375 + xorl %ebp, %esi
20376 + movl 0x200+des_SPtrans(%ecx),%ebp
20377 + xorl %ebp, %esi
20378 + movb %dh, %cl
20379 + shrl $16, %eax
20380 + movl 0x100+des_SPtrans(%ebx),%ebp
20381 + xorl %ebp, %esi
20382 + movb %ah, %bl
20383 + shrl $16, %edx
20384 + movl 0x300+des_SPtrans(%ecx),%ebp
20385 + xorl %ebp, %esi
20386 + movl 24(%esp), %ebp
20387 + movb %dh, %cl
20388 + andl $0xff, %eax
20389 + andl $0xff, %edx
20390 + movl 0x600+des_SPtrans(%ebx),%ebx
20391 + xorl %ebx, %esi
20392 + movl 0x700+des_SPtrans(%ecx),%ebx
20393 + xorl %ebx, %esi
20394 + movl 0x400+des_SPtrans(%eax),%ebx
20395 + xorl %ebx, %esi
20396 + movl 0x500+des_SPtrans(%edx),%ebx
20397 + xorl %ebx, %esi
20398 +
20399 +
20400 + movl 96(%ebp), %eax
20401 + xorl %ebx, %ebx
20402 + movl 100(%ebp), %edx
20403 + xorl %esi, %eax
20404 + xorl %esi, %edx
20405 + andl $0xfcfcfcfc, %eax
20406 + andl $0xcfcfcfcf, %edx
20407 + movb %al, %bl
20408 + movb %ah, %cl
20409 + rorl $4, %edx
20410 + movl des_SPtrans(%ebx),%ebp
20411 + movb %dl, %bl
20412 + xorl %ebp, %edi
20413 + movl 0x200+des_SPtrans(%ecx),%ebp
20414 + xorl %ebp, %edi
20415 + movb %dh, %cl
20416 + shrl $16, %eax
20417 + movl 0x100+des_SPtrans(%ebx),%ebp
20418 + xorl %ebp, %edi
20419 + movb %ah, %bl
20420 + shrl $16, %edx
20421 + movl 0x300+des_SPtrans(%ecx),%ebp
20422 + xorl %ebp, %edi
20423 + movl 24(%esp), %ebp
20424 + movb %dh, %cl
20425 + andl $0xff, %eax
20426 + andl $0xff, %edx
20427 + movl 0x600+des_SPtrans(%ebx),%ebx
20428 + xorl %ebx, %edi
20429 + movl 0x700+des_SPtrans(%ecx),%ebx
20430 + xorl %ebx, %edi
20431 + movl 0x400+des_SPtrans(%eax),%ebx
20432 + xorl %ebx, %edi
20433 + movl 0x500+des_SPtrans(%edx),%ebx
20434 + xorl %ebx, %edi
20435 +
20436 +
20437 + movl 104(%ebp), %eax
20438 + xorl %ebx, %ebx
20439 + movl 108(%ebp), %edx
20440 + xorl %edi, %eax
20441 + xorl %edi, %edx
20442 + andl $0xfcfcfcfc, %eax
20443 + andl $0xcfcfcfcf, %edx
20444 + movb %al, %bl
20445 + movb %ah, %cl
20446 + rorl $4, %edx
20447 + movl des_SPtrans(%ebx),%ebp
20448 + movb %dl, %bl
20449 + xorl %ebp, %esi
20450 + movl 0x200+des_SPtrans(%ecx),%ebp
20451 + xorl %ebp, %esi
20452 + movb %dh, %cl
20453 + shrl $16, %eax
20454 + movl 0x100+des_SPtrans(%ebx),%ebp
20455 + xorl %ebp, %esi
20456 + movb %ah, %bl
20457 + shrl $16, %edx
20458 + movl 0x300+des_SPtrans(%ecx),%ebp
20459 + xorl %ebp, %esi
20460 + movl 24(%esp), %ebp
20461 + movb %dh, %cl
20462 + andl $0xff, %eax
20463 + andl $0xff, %edx
20464 + movl 0x600+des_SPtrans(%ebx),%ebx
20465 + xorl %ebx, %esi
20466 + movl 0x700+des_SPtrans(%ecx),%ebx
20467 + xorl %ebx, %esi
20468 + movl 0x400+des_SPtrans(%eax),%ebx
20469 + xorl %ebx, %esi
20470 + movl 0x500+des_SPtrans(%edx),%ebx
20471 + xorl %ebx, %esi
20472 +
20473 +
20474 + movl 112(%ebp), %eax
20475 + xorl %ebx, %ebx
20476 + movl 116(%ebp), %edx
20477 + xorl %esi, %eax
20478 + xorl %esi, %edx
20479 + andl $0xfcfcfcfc, %eax
20480 + andl $0xcfcfcfcf, %edx
20481 + movb %al, %bl
20482 + movb %ah, %cl
20483 + rorl $4, %edx
20484 + movl des_SPtrans(%ebx),%ebp
20485 + movb %dl, %bl
20486 + xorl %ebp, %edi
20487 + movl 0x200+des_SPtrans(%ecx),%ebp
20488 + xorl %ebp, %edi
20489 + movb %dh, %cl
20490 + shrl $16, %eax
20491 + movl 0x100+des_SPtrans(%ebx),%ebp
20492 + xorl %ebp, %edi
20493 + movb %ah, %bl
20494 + shrl $16, %edx
20495 + movl 0x300+des_SPtrans(%ecx),%ebp
20496 + xorl %ebp, %edi
20497 + movl 24(%esp), %ebp
20498 + movb %dh, %cl
20499 + andl $0xff, %eax
20500 + andl $0xff, %edx
20501 + movl 0x600+des_SPtrans(%ebx),%ebx
20502 + xorl %ebx, %edi
20503 + movl 0x700+des_SPtrans(%ecx),%ebx
20504 + xorl %ebx, %edi
20505 + movl 0x400+des_SPtrans(%eax),%ebx
20506 + xorl %ebx, %edi
20507 + movl 0x500+des_SPtrans(%edx),%ebx
20508 + xorl %ebx, %edi
20509 +
20510 +
20511 + movl 120(%ebp), %eax
20512 + xorl %ebx, %ebx
20513 + movl 124(%ebp), %edx
20514 + xorl %edi, %eax
20515 + xorl %edi, %edx
20516 + andl $0xfcfcfcfc, %eax
20517 + andl $0xcfcfcfcf, %edx
20518 + movb %al, %bl
20519 + movb %ah, %cl
20520 + rorl $4, %edx
20521 + movl des_SPtrans(%ebx),%ebp
20522 + movb %dl, %bl
20523 + xorl %ebp, %esi
20524 + movl 0x200+des_SPtrans(%ecx),%ebp
20525 + xorl %ebp, %esi
20526 + movb %dh, %cl
20527 + shrl $16, %eax
20528 + movl 0x100+des_SPtrans(%ebx),%ebp
20529 + xorl %ebp, %esi
20530 + movb %ah, %bl
20531 + shrl $16, %edx
20532 + movl 0x300+des_SPtrans(%ecx),%ebp
20533 + xorl %ebp, %esi
20534 + movl 24(%esp), %ebp
20535 + movb %dh, %cl
20536 + andl $0xff, %eax
20537 + andl $0xff, %edx
20538 + movl 0x600+des_SPtrans(%ebx),%ebx
20539 + xorl %ebx, %esi
20540 + movl 0x700+des_SPtrans(%ecx),%ebx
20541 + xorl %ebx, %esi
20542 + movl 0x400+des_SPtrans(%eax),%ebx
20543 + xorl %ebx, %esi
20544 + movl 0x500+des_SPtrans(%edx),%ebx
20545 + xorl %ebx, %esi
20546 + jmp .L001end
20547 +.L000start_decrypt:
20548 +
20549 +
20550 + movl 120(%ebp), %eax
20551 + xorl %ebx, %ebx
20552 + movl 124(%ebp), %edx
20553 + xorl %esi, %eax
20554 + xorl %esi, %edx
20555 + andl $0xfcfcfcfc, %eax
20556 + andl $0xcfcfcfcf, %edx
20557 + movb %al, %bl
20558 + movb %ah, %cl
20559 + rorl $4, %edx
20560 + movl des_SPtrans(%ebx),%ebp
20561 + movb %dl, %bl
20562 + xorl %ebp, %edi
20563 + movl 0x200+des_SPtrans(%ecx),%ebp
20564 + xorl %ebp, %edi
20565 + movb %dh, %cl
20566 + shrl $16, %eax
20567 + movl 0x100+des_SPtrans(%ebx),%ebp
20568 + xorl %ebp, %edi
20569 + movb %ah, %bl
20570 + shrl $16, %edx
20571 + movl 0x300+des_SPtrans(%ecx),%ebp
20572 + xorl %ebp, %edi
20573 + movl 24(%esp), %ebp
20574 + movb %dh, %cl
20575 + andl $0xff, %eax
20576 + andl $0xff, %edx
20577 + movl 0x600+des_SPtrans(%ebx),%ebx
20578 + xorl %ebx, %edi
20579 + movl 0x700+des_SPtrans(%ecx),%ebx
20580 + xorl %ebx, %edi
20581 + movl 0x400+des_SPtrans(%eax),%ebx
20582 + xorl %ebx, %edi
20583 + movl 0x500+des_SPtrans(%edx),%ebx
20584 + xorl %ebx, %edi
20585 +
20586 +
20587 + movl 112(%ebp), %eax
20588 + xorl %ebx, %ebx
20589 + movl 116(%ebp), %edx
20590 + xorl %edi, %eax
20591 + xorl %edi, %edx
20592 + andl $0xfcfcfcfc, %eax
20593 + andl $0xcfcfcfcf, %edx
20594 + movb %al, %bl
20595 + movb %ah, %cl
20596 + rorl $4, %edx
20597 + movl des_SPtrans(%ebx),%ebp
20598 + movb %dl, %bl
20599 + xorl %ebp, %esi
20600 + movl 0x200+des_SPtrans(%ecx),%ebp
20601 + xorl %ebp, %esi
20602 + movb %dh, %cl
20603 + shrl $16, %eax
20604 + movl 0x100+des_SPtrans(%ebx),%ebp
20605 + xorl %ebp, %esi
20606 + movb %ah, %bl
20607 + shrl $16, %edx
20608 + movl 0x300+des_SPtrans(%ecx),%ebp
20609 + xorl %ebp, %esi
20610 + movl 24(%esp), %ebp
20611 + movb %dh, %cl
20612 + andl $0xff, %eax
20613 + andl $0xff, %edx
20614 + movl 0x600+des_SPtrans(%ebx),%ebx
20615 + xorl %ebx, %esi
20616 + movl 0x700+des_SPtrans(%ecx),%ebx
20617 + xorl %ebx, %esi
20618 + movl 0x400+des_SPtrans(%eax),%ebx
20619 + xorl %ebx, %esi
20620 + movl 0x500+des_SPtrans(%edx),%ebx
20621 + xorl %ebx, %esi
20622 +
20623 +
20624 + movl 104(%ebp), %eax
20625 + xorl %ebx, %ebx
20626 + movl 108(%ebp), %edx
20627 + xorl %esi, %eax
20628 + xorl %esi, %edx
20629 + andl $0xfcfcfcfc, %eax
20630 + andl $0xcfcfcfcf, %edx
20631 + movb %al, %bl
20632 + movb %ah, %cl
20633 + rorl $4, %edx
20634 + movl des_SPtrans(%ebx),%ebp
20635 + movb %dl, %bl
20636 + xorl %ebp, %edi
20637 + movl 0x200+des_SPtrans(%ecx),%ebp
20638 + xorl %ebp, %edi
20639 + movb %dh, %cl
20640 + shrl $16, %eax
20641 + movl 0x100+des_SPtrans(%ebx),%ebp
20642 + xorl %ebp, %edi
20643 + movb %ah, %bl
20644 + shrl $16, %edx
20645 + movl 0x300+des_SPtrans(%ecx),%ebp
20646 + xorl %ebp, %edi
20647 + movl 24(%esp), %ebp
20648 + movb %dh, %cl
20649 + andl $0xff, %eax
20650 + andl $0xff, %edx
20651 + movl 0x600+des_SPtrans(%ebx),%ebx
20652 + xorl %ebx, %edi
20653 + movl 0x700+des_SPtrans(%ecx),%ebx
20654 + xorl %ebx, %edi
20655 + movl 0x400+des_SPtrans(%eax),%ebx
20656 + xorl %ebx, %edi
20657 + movl 0x500+des_SPtrans(%edx),%ebx
20658 + xorl %ebx, %edi
20659 +
20660 +
20661 + movl 96(%ebp), %eax
20662 + xorl %ebx, %ebx
20663 + movl 100(%ebp), %edx
20664 + xorl %edi, %eax
20665 + xorl %edi, %edx
20666 + andl $0xfcfcfcfc, %eax
20667 + andl $0xcfcfcfcf, %edx
20668 + movb %al, %bl
20669 + movb %ah, %cl
20670 + rorl $4, %edx
20671 + movl des_SPtrans(%ebx),%ebp
20672 + movb %dl, %bl
20673 + xorl %ebp, %esi
20674 + movl 0x200+des_SPtrans(%ecx),%ebp
20675 + xorl %ebp, %esi
20676 + movb %dh, %cl
20677 + shrl $16, %eax
20678 + movl 0x100+des_SPtrans(%ebx),%ebp
20679 + xorl %ebp, %esi
20680 + movb %ah, %bl
20681 + shrl $16, %edx
20682 + movl 0x300+des_SPtrans(%ecx),%ebp
20683 + xorl %ebp, %esi
20684 + movl 24(%esp), %ebp
20685 + movb %dh, %cl
20686 + andl $0xff, %eax
20687 + andl $0xff, %edx
20688 + movl 0x600+des_SPtrans(%ebx),%ebx
20689 + xorl %ebx, %esi
20690 + movl 0x700+des_SPtrans(%ecx),%ebx
20691 + xorl %ebx, %esi
20692 + movl 0x400+des_SPtrans(%eax),%ebx
20693 + xorl %ebx, %esi
20694 + movl 0x500+des_SPtrans(%edx),%ebx
20695 + xorl %ebx, %esi
20696 +
20697 +
20698 + movl 88(%ebp), %eax
20699 + xorl %ebx, %ebx
20700 + movl 92(%ebp), %edx
20701 + xorl %esi, %eax
20702 + xorl %esi, %edx
20703 + andl $0xfcfcfcfc, %eax
20704 + andl $0xcfcfcfcf, %edx
20705 + movb %al, %bl
20706 + movb %ah, %cl
20707 + rorl $4, %edx
20708 + movl des_SPtrans(%ebx),%ebp
20709 + movb %dl, %bl
20710 + xorl %ebp, %edi
20711 + movl 0x200+des_SPtrans(%ecx),%ebp
20712 + xorl %ebp, %edi
20713 + movb %dh, %cl
20714 + shrl $16, %eax
20715 + movl 0x100+des_SPtrans(%ebx),%ebp
20716 + xorl %ebp, %edi
20717 + movb %ah, %bl
20718 + shrl $16, %edx
20719 + movl 0x300+des_SPtrans(%ecx),%ebp
20720 + xorl %ebp, %edi
20721 + movl 24(%esp), %ebp
20722 + movb %dh, %cl
20723 + andl $0xff, %eax
20724 + andl $0xff, %edx
20725 + movl 0x600+des_SPtrans(%ebx),%ebx
20726 + xorl %ebx, %edi
20727 + movl 0x700+des_SPtrans(%ecx),%ebx
20728 + xorl %ebx, %edi
20729 + movl 0x400+des_SPtrans(%eax),%ebx
20730 + xorl %ebx, %edi
20731 + movl 0x500+des_SPtrans(%edx),%ebx
20732 + xorl %ebx, %edi
20733 +
20734 +
20735 + movl 80(%ebp), %eax
20736 + xorl %ebx, %ebx
20737 + movl 84(%ebp), %edx
20738 + xorl %edi, %eax
20739 + xorl %edi, %edx
20740 + andl $0xfcfcfcfc, %eax
20741 + andl $0xcfcfcfcf, %edx
20742 + movb %al, %bl
20743 + movb %ah, %cl
20744 + rorl $4, %edx
20745 + movl des_SPtrans(%ebx),%ebp
20746 + movb %dl, %bl
20747 + xorl %ebp, %esi
20748 + movl 0x200+des_SPtrans(%ecx),%ebp
20749 + xorl %ebp, %esi
20750 + movb %dh, %cl
20751 + shrl $16, %eax
20752 + movl 0x100+des_SPtrans(%ebx),%ebp
20753 + xorl %ebp, %esi
20754 + movb %ah, %bl
20755 + shrl $16, %edx
20756 + movl 0x300+des_SPtrans(%ecx),%ebp
20757 + xorl %ebp, %esi
20758 + movl 24(%esp), %ebp
20759 + movb %dh, %cl
20760 + andl $0xff, %eax
20761 + andl $0xff, %edx
20762 + movl 0x600+des_SPtrans(%ebx),%ebx
20763 + xorl %ebx, %esi
20764 + movl 0x700+des_SPtrans(%ecx),%ebx
20765 + xorl %ebx, %esi
20766 + movl 0x400+des_SPtrans(%eax),%ebx
20767 + xorl %ebx, %esi
20768 + movl 0x500+des_SPtrans(%edx),%ebx
20769 + xorl %ebx, %esi
20770 +
20771 +
20772 + movl 72(%ebp), %eax
20773 + xorl %ebx, %ebx
20774 + movl 76(%ebp), %edx
20775 + xorl %esi, %eax
20776 + xorl %esi, %edx
20777 + andl $0xfcfcfcfc, %eax
20778 + andl $0xcfcfcfcf, %edx
20779 + movb %al, %bl
20780 + movb %ah, %cl
20781 + rorl $4, %edx
20782 + movl des_SPtrans(%ebx),%ebp
20783 + movb %dl, %bl
20784 + xorl %ebp, %edi
20785 + movl 0x200+des_SPtrans(%ecx),%ebp
20786 + xorl %ebp, %edi
20787 + movb %dh, %cl
20788 + shrl $16, %eax
20789 + movl 0x100+des_SPtrans(%ebx),%ebp
20790 + xorl %ebp, %edi
20791 + movb %ah, %bl
20792 + shrl $16, %edx
20793 + movl 0x300+des_SPtrans(%ecx),%ebp
20794 + xorl %ebp, %edi
20795 + movl 24(%esp), %ebp
20796 + movb %dh, %cl
20797 + andl $0xff, %eax
20798 + andl $0xff, %edx
20799 + movl 0x600+des_SPtrans(%ebx),%ebx
20800 + xorl %ebx, %edi
20801 + movl 0x700+des_SPtrans(%ecx),%ebx
20802 + xorl %ebx, %edi
20803 + movl 0x400+des_SPtrans(%eax),%ebx
20804 + xorl %ebx, %edi
20805 + movl 0x500+des_SPtrans(%edx),%ebx
20806 + xorl %ebx, %edi
20807 +
20808 +
20809 + movl 64(%ebp), %eax
20810 + xorl %ebx, %ebx
20811 + movl 68(%ebp), %edx
20812 + xorl %edi, %eax
20813 + xorl %edi, %edx
20814 + andl $0xfcfcfcfc, %eax
20815 + andl $0xcfcfcfcf, %edx
20816 + movb %al, %bl
20817 + movb %ah, %cl
20818 + rorl $4, %edx
20819 + movl des_SPtrans(%ebx),%ebp
20820 + movb %dl, %bl
20821 + xorl %ebp, %esi
20822 + movl 0x200+des_SPtrans(%ecx),%ebp
20823 + xorl %ebp, %esi
20824 + movb %dh, %cl
20825 + shrl $16, %eax
20826 + movl 0x100+des_SPtrans(%ebx),%ebp
20827 + xorl %ebp, %esi
20828 + movb %ah, %bl
20829 + shrl $16, %edx
20830 + movl 0x300+des_SPtrans(%ecx),%ebp
20831 + xorl %ebp, %esi
20832 + movl 24(%esp), %ebp
20833 + movb %dh, %cl
20834 + andl $0xff, %eax
20835 + andl $0xff, %edx
20836 + movl 0x600+des_SPtrans(%ebx),%ebx
20837 + xorl %ebx, %esi
20838 + movl 0x700+des_SPtrans(%ecx),%ebx
20839 + xorl %ebx, %esi
20840 + movl 0x400+des_SPtrans(%eax),%ebx
20841 + xorl %ebx, %esi
20842 + movl 0x500+des_SPtrans(%edx),%ebx
20843 + xorl %ebx, %esi
20844 +
20845 +
20846 + movl 56(%ebp), %eax
20847 + xorl %ebx, %ebx
20848 + movl 60(%ebp), %edx
20849 + xorl %esi, %eax
20850 + xorl %esi, %edx
20851 + andl $0xfcfcfcfc, %eax
20852 + andl $0xcfcfcfcf, %edx
20853 + movb %al, %bl
20854 + movb %ah, %cl
20855 + rorl $4, %edx
20856 + movl des_SPtrans(%ebx),%ebp
20857 + movb %dl, %bl
20858 + xorl %ebp, %edi
20859 + movl 0x200+des_SPtrans(%ecx),%ebp
20860 + xorl %ebp, %edi
20861 + movb %dh, %cl
20862 + shrl $16, %eax
20863 + movl 0x100+des_SPtrans(%ebx),%ebp
20864 + xorl %ebp, %edi
20865 + movb %ah, %bl
20866 + shrl $16, %edx
20867 + movl 0x300+des_SPtrans(%ecx),%ebp
20868 + xorl %ebp, %edi
20869 + movl 24(%esp), %ebp
20870 + movb %dh, %cl
20871 + andl $0xff, %eax
20872 + andl $0xff, %edx
20873 + movl 0x600+des_SPtrans(%ebx),%ebx
20874 + xorl %ebx, %edi
20875 + movl 0x700+des_SPtrans(%ecx),%ebx
20876 + xorl %ebx, %edi
20877 + movl 0x400+des_SPtrans(%eax),%ebx
20878 + xorl %ebx, %edi
20879 + movl 0x500+des_SPtrans(%edx),%ebx
20880 + xorl %ebx, %edi
20881 +
20882 +
20883 + movl 48(%ebp), %eax
20884 + xorl %ebx, %ebx
20885 + movl 52(%ebp), %edx
20886 + xorl %edi, %eax
20887 + xorl %edi, %edx
20888 + andl $0xfcfcfcfc, %eax
20889 + andl $0xcfcfcfcf, %edx
20890 + movb %al, %bl
20891 + movb %ah, %cl
20892 + rorl $4, %edx
20893 + movl des_SPtrans(%ebx),%ebp
20894 + movb %dl, %bl
20895 + xorl %ebp, %esi
20896 + movl 0x200+des_SPtrans(%ecx),%ebp
20897 + xorl %ebp, %esi
20898 + movb %dh, %cl
20899 + shrl $16, %eax
20900 + movl 0x100+des_SPtrans(%ebx),%ebp
20901 + xorl %ebp, %esi
20902 + movb %ah, %bl
20903 + shrl $16, %edx
20904 + movl 0x300+des_SPtrans(%ecx),%ebp
20905 + xorl %ebp, %esi
20906 + movl 24(%esp), %ebp
20907 + movb %dh, %cl
20908 + andl $0xff, %eax
20909 + andl $0xff, %edx
20910 + movl 0x600+des_SPtrans(%ebx),%ebx
20911 + xorl %ebx, %esi
20912 + movl 0x700+des_SPtrans(%ecx),%ebx
20913 + xorl %ebx, %esi
20914 + movl 0x400+des_SPtrans(%eax),%ebx
20915 + xorl %ebx, %esi
20916 + movl 0x500+des_SPtrans(%edx),%ebx
20917 + xorl %ebx, %esi
20918 +
20919 +
20920 + movl 40(%ebp), %eax
20921 + xorl %ebx, %ebx
20922 + movl 44(%ebp), %edx
20923 + xorl %esi, %eax
20924 + xorl %esi, %edx
20925 + andl $0xfcfcfcfc, %eax
20926 + andl $0xcfcfcfcf, %edx
20927 + movb %al, %bl
20928 + movb %ah, %cl
20929 + rorl $4, %edx
20930 + movl des_SPtrans(%ebx),%ebp
20931 + movb %dl, %bl
20932 + xorl %ebp, %edi
20933 + movl 0x200+des_SPtrans(%ecx),%ebp
20934 + xorl %ebp, %edi
20935 + movb %dh, %cl
20936 + shrl $16, %eax
20937 + movl 0x100+des_SPtrans(%ebx),%ebp
20938 + xorl %ebp, %edi
20939 + movb %ah, %bl
20940 + shrl $16, %edx
20941 + movl 0x300+des_SPtrans(%ecx),%ebp
20942 + xorl %ebp, %edi
20943 + movl 24(%esp), %ebp
20944 + movb %dh, %cl
20945 + andl $0xff, %eax
20946 + andl $0xff, %edx
20947 + movl 0x600+des_SPtrans(%ebx),%ebx
20948 + xorl %ebx, %edi
20949 + movl 0x700+des_SPtrans(%ecx),%ebx
20950 + xorl %ebx, %edi
20951 + movl 0x400+des_SPtrans(%eax),%ebx
20952 + xorl %ebx, %edi
20953 + movl 0x500+des_SPtrans(%edx),%ebx
20954 + xorl %ebx, %edi
20955 +
20956 +
20957 + movl 32(%ebp), %eax
20958 + xorl %ebx, %ebx
20959 + movl 36(%ebp), %edx
20960 + xorl %edi, %eax
20961 + xorl %edi, %edx
20962 + andl $0xfcfcfcfc, %eax
20963 + andl $0xcfcfcfcf, %edx
20964 + movb %al, %bl
20965 + movb %ah, %cl
20966 + rorl $4, %edx
20967 + movl des_SPtrans(%ebx),%ebp
20968 + movb %dl, %bl
20969 + xorl %ebp, %esi
20970 + movl 0x200+des_SPtrans(%ecx),%ebp
20971 + xorl %ebp, %esi
20972 + movb %dh, %cl
20973 + shrl $16, %eax
20974 + movl 0x100+des_SPtrans(%ebx),%ebp
20975 + xorl %ebp, %esi
20976 + movb %ah, %bl
20977 + shrl $16, %edx
20978 + movl 0x300+des_SPtrans(%ecx),%ebp
20979 + xorl %ebp, %esi
20980 + movl 24(%esp), %ebp
20981 + movb %dh, %cl
20982 + andl $0xff, %eax
20983 + andl $0xff, %edx
20984 + movl 0x600+des_SPtrans(%ebx),%ebx
20985 + xorl %ebx, %esi
20986 + movl 0x700+des_SPtrans(%ecx),%ebx
20987 + xorl %ebx, %esi
20988 + movl 0x400+des_SPtrans(%eax),%ebx
20989 + xorl %ebx, %esi
20990 + movl 0x500+des_SPtrans(%edx),%ebx
20991 + xorl %ebx, %esi
20992 +
20993 +
20994 + movl 24(%ebp), %eax
20995 + xorl %ebx, %ebx
20996 + movl 28(%ebp), %edx
20997 + xorl %esi, %eax
20998 + xorl %esi, %edx
20999 + andl $0xfcfcfcfc, %eax
21000 + andl $0xcfcfcfcf, %edx
21001 + movb %al, %bl
21002 + movb %ah, %cl
21003 + rorl $4, %edx
21004 + movl des_SPtrans(%ebx),%ebp
21005 + movb %dl, %bl
21006 + xorl %ebp, %edi
21007 + movl 0x200+des_SPtrans(%ecx),%ebp
21008 + xorl %ebp, %edi
21009 + movb %dh, %cl
21010 + shrl $16, %eax
21011 + movl 0x100+des_SPtrans(%ebx),%ebp
21012 + xorl %ebp, %edi
21013 + movb %ah, %bl
21014 + shrl $16, %edx
21015 + movl 0x300+des_SPtrans(%ecx),%ebp
21016 + xorl %ebp, %edi
21017 + movl 24(%esp), %ebp
21018 + movb %dh, %cl
21019 + andl $0xff, %eax
21020 + andl $0xff, %edx
21021 + movl 0x600+des_SPtrans(%ebx),%ebx
21022 + xorl %ebx, %edi
21023 + movl 0x700+des_SPtrans(%ecx),%ebx
21024 + xorl %ebx, %edi
21025 + movl 0x400+des_SPtrans(%eax),%ebx
21026 + xorl %ebx, %edi
21027 + movl 0x500+des_SPtrans(%edx),%ebx
21028 + xorl %ebx, %edi
21029 +
21030 +
21031 + movl 16(%ebp), %eax
21032 + xorl %ebx, %ebx
21033 + movl 20(%ebp), %edx
21034 + xorl %edi, %eax
21035 + xorl %edi, %edx
21036 + andl $0xfcfcfcfc, %eax
21037 + andl $0xcfcfcfcf, %edx
21038 + movb %al, %bl
21039 + movb %ah, %cl
21040 + rorl $4, %edx
21041 + movl des_SPtrans(%ebx),%ebp
21042 + movb %dl, %bl
21043 + xorl %ebp, %esi
21044 + movl 0x200+des_SPtrans(%ecx),%ebp
21045 + xorl %ebp, %esi
21046 + movb %dh, %cl
21047 + shrl $16, %eax
21048 + movl 0x100+des_SPtrans(%ebx),%ebp
21049 + xorl %ebp, %esi
21050 + movb %ah, %bl
21051 + shrl $16, %edx
21052 + movl 0x300+des_SPtrans(%ecx),%ebp
21053 + xorl %ebp, %esi
21054 + movl 24(%esp), %ebp
21055 + movb %dh, %cl
21056 + andl $0xff, %eax
21057 + andl $0xff, %edx
21058 + movl 0x600+des_SPtrans(%ebx),%ebx
21059 + xorl %ebx, %esi
21060 + movl 0x700+des_SPtrans(%ecx),%ebx
21061 + xorl %ebx, %esi
21062 + movl 0x400+des_SPtrans(%eax),%ebx
21063 + xorl %ebx, %esi
21064 + movl 0x500+des_SPtrans(%edx),%ebx
21065 + xorl %ebx, %esi
21066 +
21067 +
21068 + movl 8(%ebp), %eax
21069 + xorl %ebx, %ebx
21070 + movl 12(%ebp), %edx
21071 + xorl %esi, %eax
21072 + xorl %esi, %edx
21073 + andl $0xfcfcfcfc, %eax
21074 + andl $0xcfcfcfcf, %edx
21075 + movb %al, %bl
21076 + movb %ah, %cl
21077 + rorl $4, %edx
21078 + movl des_SPtrans(%ebx),%ebp
21079 + movb %dl, %bl
21080 + xorl %ebp, %edi
21081 + movl 0x200+des_SPtrans(%ecx),%ebp
21082 + xorl %ebp, %edi
21083 + movb %dh, %cl
21084 + shrl $16, %eax
21085 + movl 0x100+des_SPtrans(%ebx),%ebp
21086 + xorl %ebp, %edi
21087 + movb %ah, %bl
21088 + shrl $16, %edx
21089 + movl 0x300+des_SPtrans(%ecx),%ebp
21090 + xorl %ebp, %edi
21091 + movl 24(%esp), %ebp
21092 + movb %dh, %cl
21093 + andl $0xff, %eax
21094 + andl $0xff, %edx
21095 + movl 0x600+des_SPtrans(%ebx),%ebx
21096 + xorl %ebx, %edi
21097 + movl 0x700+des_SPtrans(%ecx),%ebx
21098 + xorl %ebx, %edi
21099 + movl 0x400+des_SPtrans(%eax),%ebx
21100 + xorl %ebx, %edi
21101 + movl 0x500+des_SPtrans(%edx),%ebx
21102 + xorl %ebx, %edi
21103 +
21104 +
21105 + movl (%ebp), %eax
21106 + xorl %ebx, %ebx
21107 + movl 4(%ebp), %edx
21108 + xorl %edi, %eax
21109 + xorl %edi, %edx
21110 + andl $0xfcfcfcfc, %eax
21111 + andl $0xcfcfcfcf, %edx
21112 + movb %al, %bl
21113 + movb %ah, %cl
21114 + rorl $4, %edx
21115 + movl des_SPtrans(%ebx),%ebp
21116 + movb %dl, %bl
21117 + xorl %ebp, %esi
21118 + movl 0x200+des_SPtrans(%ecx),%ebp
21119 + xorl %ebp, %esi
21120 + movb %dh, %cl
21121 + shrl $16, %eax
21122 + movl 0x100+des_SPtrans(%ebx),%ebp
21123 + xorl %ebp, %esi
21124 + movb %ah, %bl
21125 + shrl $16, %edx
21126 + movl 0x300+des_SPtrans(%ecx),%ebp
21127 + xorl %ebp, %esi
21128 + movl 24(%esp), %ebp
21129 + movb %dh, %cl
21130 + andl $0xff, %eax
21131 + andl $0xff, %edx
21132 + movl 0x600+des_SPtrans(%ebx),%ebx
21133 + xorl %ebx, %esi
21134 + movl 0x700+des_SPtrans(%ecx),%ebx
21135 + xorl %ebx, %esi
21136 + movl 0x400+des_SPtrans(%eax),%ebx
21137 + xorl %ebx, %esi
21138 + movl 0x500+des_SPtrans(%edx),%ebx
21139 + xorl %ebx, %esi
21140 +.L001end:
21141 +
21142 +
21143 + movl 20(%esp), %edx
21144 +.byte 209
21145 +.byte 206
21146 + movl %edi, %eax
21147 + xorl %esi, %edi
21148 + andl $0xaaaaaaaa, %edi
21149 + xorl %edi, %eax
21150 + xorl %edi, %esi
21151 +
21152 + roll $23, %eax
21153 + movl %eax, %edi
21154 + xorl %esi, %eax
21155 + andl $0x03fc03fc, %eax
21156 + xorl %eax, %edi
21157 + xorl %eax, %esi
21158 +
21159 + roll $10, %edi
21160 + movl %edi, %eax
21161 + xorl %esi, %edi
21162 + andl $0x33333333, %edi
21163 + xorl %edi, %eax
21164 + xorl %edi, %esi
21165 +
21166 + roll $18, %esi
21167 + movl %esi, %edi
21168 + xorl %eax, %esi
21169 + andl $0xfff0000f, %esi
21170 + xorl %esi, %edi
21171 + xorl %esi, %eax
21172 +
21173 + roll $12, %edi
21174 + movl %edi, %esi
21175 + xorl %eax, %edi
21176 + andl $0xf0f0f0f0, %edi
21177 + xorl %edi, %esi
21178 + xorl %edi, %eax
21179 +
21180 + rorl $4, %eax
21181 + movl %eax, (%edx)
21182 + movl %esi, 4(%edx)
21183 + popl %ebp
21184 + popl %ebx
21185 + popl %edi
21186 + popl %esi
21187 + ret
21188 +.des_encrypt_end:
21189 + .size des_encrypt , .des_encrypt_end-des_encrypt
21190 +.ident "desasm.pl"
21191 +.text
21192 + .align 16
21193 +.globl des_encrypt2
21194 + .type des_encrypt2 , @function
21195 +des_encrypt2:
21196 + pushl %esi
21197 + pushl %edi
21198 +
21199 +
21200 + movl 12(%esp), %eax
21201 + xorl %ecx, %ecx
21202 + pushl %ebx
21203 + pushl %ebp
21204 + movl (%eax), %esi
21205 + movl 28(%esp), %ebx
21206 + roll $3, %esi
21207 + movl 4(%eax), %edi
21208 + roll $3, %edi
21209 + movl 24(%esp), %ebp
21210 + cmpl $0, %ebx
21211 + je .L002start_decrypt
21212 +
21213 +
21214 + movl (%ebp), %eax
21215 + xorl %ebx, %ebx
21216 + movl 4(%ebp), %edx
21217 + xorl %esi, %eax
21218 + xorl %esi, %edx
21219 + andl $0xfcfcfcfc, %eax
21220 + andl $0xcfcfcfcf, %edx
21221 + movb %al, %bl
21222 + movb %ah, %cl
21223 + rorl $4, %edx
21224 + movl des_SPtrans(%ebx),%ebp
21225 + movb %dl, %bl
21226 + xorl %ebp, %edi
21227 + movl 0x200+des_SPtrans(%ecx),%ebp
21228 + xorl %ebp, %edi
21229 + movb %dh, %cl
21230 + shrl $16, %eax
21231 + movl 0x100+des_SPtrans(%ebx),%ebp
21232 + xorl %ebp, %edi
21233 + movb %ah, %bl
21234 + shrl $16, %edx
21235 + movl 0x300+des_SPtrans(%ecx),%ebp
21236 + xorl %ebp, %edi
21237 + movl 24(%esp), %ebp
21238 + movb %dh, %cl
21239 + andl $0xff, %eax
21240 + andl $0xff, %edx
21241 + movl 0x600+des_SPtrans(%ebx),%ebx
21242 + xorl %ebx, %edi
21243 + movl 0x700+des_SPtrans(%ecx),%ebx
21244 + xorl %ebx, %edi
21245 + movl 0x400+des_SPtrans(%eax),%ebx
21246 + xorl %ebx, %edi
21247 + movl 0x500+des_SPtrans(%edx),%ebx
21248 + xorl %ebx, %edi
21249 +
21250 +
21251 + movl 8(%ebp), %eax
21252 + xorl %ebx, %ebx
21253 + movl 12(%ebp), %edx
21254 + xorl %edi, %eax
21255 + xorl %edi, %edx
21256 + andl $0xfcfcfcfc, %eax
21257 + andl $0xcfcfcfcf, %edx
21258 + movb %al, %bl
21259 + movb %ah, %cl
21260 + rorl $4, %edx
21261 + movl des_SPtrans(%ebx),%ebp
21262 + movb %dl, %bl
21263 + xorl %ebp, %esi
21264 + movl 0x200+des_SPtrans(%ecx),%ebp
21265 + xorl %ebp, %esi
21266 + movb %dh, %cl
21267 + shrl $16, %eax
21268 + movl 0x100+des_SPtrans(%ebx),%ebp
21269 + xorl %ebp, %esi
21270 + movb %ah, %bl
21271 + shrl $16, %edx
21272 + movl 0x300+des_SPtrans(%ecx),%ebp
21273 + xorl %ebp, %esi
21274 + movl 24(%esp), %ebp
21275 + movb %dh, %cl
21276 + andl $0xff, %eax
21277 + andl $0xff, %edx
21278 + movl 0x600+des_SPtrans(%ebx),%ebx
21279 + xorl %ebx, %esi
21280 + movl 0x700+des_SPtrans(%ecx),%ebx
21281 + xorl %ebx, %esi
21282 + movl 0x400+des_SPtrans(%eax),%ebx
21283 + xorl %ebx, %esi
21284 + movl 0x500+des_SPtrans(%edx),%ebx
21285 + xorl %ebx, %esi
21286 +
21287 +
21288 + movl 16(%ebp), %eax
21289 + xorl %ebx, %ebx
21290 + movl 20(%ebp), %edx
21291 + xorl %esi, %eax
21292 + xorl %esi, %edx
21293 + andl $0xfcfcfcfc, %eax
21294 + andl $0xcfcfcfcf, %edx
21295 + movb %al, %bl
21296 + movb %ah, %cl
21297 + rorl $4, %edx
21298 + movl des_SPtrans(%ebx),%ebp
21299 + movb %dl, %bl
21300 + xorl %ebp, %edi
21301 + movl 0x200+des_SPtrans(%ecx),%ebp
21302 + xorl %ebp, %edi
21303 + movb %dh, %cl
21304 + shrl $16, %eax
21305 + movl 0x100+des_SPtrans(%ebx),%ebp
21306 + xorl %ebp, %edi
21307 + movb %ah, %bl
21308 + shrl $16, %edx
21309 + movl 0x300+des_SPtrans(%ecx),%ebp
21310 + xorl %ebp, %edi
21311 + movl 24(%esp), %ebp
21312 + movb %dh, %cl
21313 + andl $0xff, %eax
21314 + andl $0xff, %edx
21315 + movl 0x600+des_SPtrans(%ebx),%ebx
21316 + xorl %ebx, %edi
21317 + movl 0x700+des_SPtrans(%ecx),%ebx
21318 + xorl %ebx, %edi
21319 + movl 0x400+des_SPtrans(%eax),%ebx
21320 + xorl %ebx, %edi
21321 + movl 0x500+des_SPtrans(%edx),%ebx
21322 + xorl %ebx, %edi
21323 +
21324 +
21325 + movl 24(%ebp), %eax
21326 + xorl %ebx, %ebx
21327 + movl 28(%ebp), %edx
21328 + xorl %edi, %eax
21329 + xorl %edi, %edx
21330 + andl $0xfcfcfcfc, %eax
21331 + andl $0xcfcfcfcf, %edx
21332 + movb %al, %bl
21333 + movb %ah, %cl
21334 + rorl $4, %edx
21335 + movl des_SPtrans(%ebx),%ebp
21336 + movb %dl, %bl
21337 + xorl %ebp, %esi
21338 + movl 0x200+des_SPtrans(%ecx),%ebp
21339 + xorl %ebp, %esi
21340 + movb %dh, %cl
21341 + shrl $16, %eax
21342 + movl 0x100+des_SPtrans(%ebx),%ebp
21343 + xorl %ebp, %esi
21344 + movb %ah, %bl
21345 + shrl $16, %edx
21346 + movl 0x300+des_SPtrans(%ecx),%ebp
21347 + xorl %ebp, %esi
21348 + movl 24(%esp), %ebp
21349 + movb %dh, %cl
21350 + andl $0xff, %eax
21351 + andl $0xff, %edx
21352 + movl 0x600+des_SPtrans(%ebx),%ebx
21353 + xorl %ebx, %esi
21354 + movl 0x700+des_SPtrans(%ecx),%ebx
21355 + xorl %ebx, %esi
21356 + movl 0x400+des_SPtrans(%eax),%ebx
21357 + xorl %ebx, %esi
21358 + movl 0x500+des_SPtrans(%edx),%ebx
21359 + xorl %ebx, %esi
21360 +
21361 +
21362 + movl 32(%ebp), %eax
21363 + xorl %ebx, %ebx
21364 + movl 36(%ebp), %edx
21365 + xorl %esi, %eax
21366 + xorl %esi, %edx
21367 + andl $0xfcfcfcfc, %eax
21368 + andl $0xcfcfcfcf, %edx
21369 + movb %al, %bl
21370 + movb %ah, %cl
21371 + rorl $4, %edx
21372 + movl des_SPtrans(%ebx),%ebp
21373 + movb %dl, %bl
21374 + xorl %ebp, %edi
21375 + movl 0x200+des_SPtrans(%ecx),%ebp
21376 + xorl %ebp, %edi
21377 + movb %dh, %cl
21378 + shrl $16, %eax
21379 + movl 0x100+des_SPtrans(%ebx),%ebp
21380 + xorl %ebp, %edi
21381 + movb %ah, %bl
21382 + shrl $16, %edx
21383 + movl 0x300+des_SPtrans(%ecx),%ebp
21384 + xorl %ebp, %edi
21385 + movl 24(%esp), %ebp
21386 + movb %dh, %cl
21387 + andl $0xff, %eax
21388 + andl $0xff, %edx
21389 + movl 0x600+des_SPtrans(%ebx),%ebx
21390 + xorl %ebx, %edi
21391 + movl 0x700+des_SPtrans(%ecx),%ebx
21392 + xorl %ebx, %edi
21393 + movl 0x400+des_SPtrans(%eax),%ebx
21394 + xorl %ebx, %edi
21395 + movl 0x500+des_SPtrans(%edx),%ebx
21396 + xorl %ebx, %edi
21397 +
21398 +
21399 + movl 40(%ebp), %eax
21400 + xorl %ebx, %ebx
21401 + movl 44(%ebp), %edx
21402 + xorl %edi, %eax
21403 + xorl %edi, %edx
21404 + andl $0xfcfcfcfc, %eax
21405 + andl $0xcfcfcfcf, %edx
21406 + movb %al, %bl
21407 + movb %ah, %cl
21408 + rorl $4, %edx
21409 + movl des_SPtrans(%ebx),%ebp
21410 + movb %dl, %bl
21411 + xorl %ebp, %esi
21412 + movl 0x200+des_SPtrans(%ecx),%ebp
21413 + xorl %ebp, %esi
21414 + movb %dh, %cl
21415 + shrl $16, %eax
21416 + movl 0x100+des_SPtrans(%ebx),%ebp
21417 + xorl %ebp, %esi
21418 + movb %ah, %bl
21419 + shrl $16, %edx
21420 + movl 0x300+des_SPtrans(%ecx),%ebp
21421 + xorl %ebp, %esi
21422 + movl 24(%esp), %ebp
21423 + movb %dh, %cl
21424 + andl $0xff, %eax
21425 + andl $0xff, %edx
21426 + movl 0x600+des_SPtrans(%ebx),%ebx
21427 + xorl %ebx, %esi
21428 + movl 0x700+des_SPtrans(%ecx),%ebx
21429 + xorl %ebx, %esi
21430 + movl 0x400+des_SPtrans(%eax),%ebx
21431 + xorl %ebx, %esi
21432 + movl 0x500+des_SPtrans(%edx),%ebx
21433 + xorl %ebx, %esi
21434 +
21435 +
21436 + movl 48(%ebp), %eax
21437 + xorl %ebx, %ebx
21438 + movl 52(%ebp), %edx
21439 + xorl %esi, %eax
21440 + xorl %esi, %edx
21441 + andl $0xfcfcfcfc, %eax
21442 + andl $0xcfcfcfcf, %edx
21443 + movb %al, %bl
21444 + movb %ah, %cl
21445 + rorl $4, %edx
21446 + movl des_SPtrans(%ebx),%ebp
21447 + movb %dl, %bl
21448 + xorl %ebp, %edi
21449 + movl 0x200+des_SPtrans(%ecx),%ebp
21450 + xorl %ebp, %edi
21451 + movb %dh, %cl
21452 + shrl $16, %eax
21453 + movl 0x100+des_SPtrans(%ebx),%ebp
21454 + xorl %ebp, %edi
21455 + movb %ah, %bl
21456 + shrl $16, %edx
21457 + movl 0x300+des_SPtrans(%ecx),%ebp
21458 + xorl %ebp, %edi
21459 + movl 24(%esp), %ebp
21460 + movb %dh, %cl
21461 + andl $0xff, %eax
21462 + andl $0xff, %edx
21463 + movl 0x600+des_SPtrans(%ebx),%ebx
21464 + xorl %ebx, %edi
21465 + movl 0x700+des_SPtrans(%ecx),%ebx
21466 + xorl %ebx, %edi
21467 + movl 0x400+des_SPtrans(%eax),%ebx
21468 + xorl %ebx, %edi
21469 + movl 0x500+des_SPtrans(%edx),%ebx
21470 + xorl %ebx, %edi
21471 +
21472 +
21473 + movl 56(%ebp), %eax
21474 + xorl %ebx, %ebx
21475 + movl 60(%ebp), %edx
21476 + xorl %edi, %eax
21477 + xorl %edi, %edx
21478 + andl $0xfcfcfcfc, %eax
21479 + andl $0xcfcfcfcf, %edx
21480 + movb %al, %bl
21481 + movb %ah, %cl
21482 + rorl $4, %edx
21483 + movl des_SPtrans(%ebx),%ebp
21484 + movb %dl, %bl
21485 + xorl %ebp, %esi
21486 + movl 0x200+des_SPtrans(%ecx),%ebp
21487 + xorl %ebp, %esi
21488 + movb %dh, %cl
21489 + shrl $16, %eax
21490 + movl 0x100+des_SPtrans(%ebx),%ebp
21491 + xorl %ebp, %esi
21492 + movb %ah, %bl
21493 + shrl $16, %edx
21494 + movl 0x300+des_SPtrans(%ecx),%ebp
21495 + xorl %ebp, %esi
21496 + movl 24(%esp), %ebp
21497 + movb %dh, %cl
21498 + andl $0xff, %eax
21499 + andl $0xff, %edx
21500 + movl 0x600+des_SPtrans(%ebx),%ebx
21501 + xorl %ebx, %esi
21502 + movl 0x700+des_SPtrans(%ecx),%ebx
21503 + xorl %ebx, %esi
21504 + movl 0x400+des_SPtrans(%eax),%ebx
21505 + xorl %ebx, %esi
21506 + movl 0x500+des_SPtrans(%edx),%ebx
21507 + xorl %ebx, %esi
21508 +
21509 +
21510 + movl 64(%ebp), %eax
21511 + xorl %ebx, %ebx
21512 + movl 68(%ebp), %edx
21513 + xorl %esi, %eax
21514 + xorl %esi, %edx
21515 + andl $0xfcfcfcfc, %eax
21516 + andl $0xcfcfcfcf, %edx
21517 + movb %al, %bl
21518 + movb %ah, %cl
21519 + rorl $4, %edx
21520 + movl des_SPtrans(%ebx),%ebp
21521 + movb %dl, %bl
21522 + xorl %ebp, %edi
21523 + movl 0x200+des_SPtrans(%ecx),%ebp
21524 + xorl %ebp, %edi
21525 + movb %dh, %cl
21526 + shrl $16, %eax
21527 + movl 0x100+des_SPtrans(%ebx),%ebp
21528 + xorl %ebp, %edi
21529 + movb %ah, %bl
21530 + shrl $16, %edx
21531 + movl 0x300+des_SPtrans(%ecx),%ebp
21532 + xorl %ebp, %edi
21533 + movl 24(%esp), %ebp
21534 + movb %dh, %cl
21535 + andl $0xff, %eax
21536 + andl $0xff, %edx
21537 + movl 0x600+des_SPtrans(%ebx),%ebx
21538 + xorl %ebx, %edi
21539 + movl 0x700+des_SPtrans(%ecx),%ebx
21540 + xorl %ebx, %edi
21541 + movl 0x400+des_SPtrans(%eax),%ebx
21542 + xorl %ebx, %edi
21543 + movl 0x500+des_SPtrans(%edx),%ebx
21544 + xorl %ebx, %edi
21545 +
21546 +
21547 + movl 72(%ebp), %eax
21548 + xorl %ebx, %ebx
21549 + movl 76(%ebp), %edx
21550 + xorl %edi, %eax
21551 + xorl %edi, %edx
21552 + andl $0xfcfcfcfc, %eax
21553 + andl $0xcfcfcfcf, %edx
21554 + movb %al, %bl
21555 + movb %ah, %cl
21556 + rorl $4, %edx
21557 + movl des_SPtrans(%ebx),%ebp
21558 + movb %dl, %bl
21559 + xorl %ebp, %esi
21560 + movl 0x200+des_SPtrans(%ecx),%ebp
21561 + xorl %ebp, %esi
21562 + movb %dh, %cl
21563 + shrl $16, %eax
21564 + movl 0x100+des_SPtrans(%ebx),%ebp
21565 + xorl %ebp, %esi
21566 + movb %ah, %bl
21567 + shrl $16, %edx
21568 + movl 0x300+des_SPtrans(%ecx),%ebp
21569 + xorl %ebp, %esi
21570 + movl 24(%esp), %ebp
21571 + movb %dh, %cl
21572 + andl $0xff, %eax
21573 + andl $0xff, %edx
21574 + movl 0x600+des_SPtrans(%ebx),%ebx
21575 + xorl %ebx, %esi
21576 + movl 0x700+des_SPtrans(%ecx),%ebx
21577 + xorl %ebx, %esi
21578 + movl 0x400+des_SPtrans(%eax),%ebx
21579 + xorl %ebx, %esi
21580 + movl 0x500+des_SPtrans(%edx),%ebx
21581 + xorl %ebx, %esi
21582 +
21583 +
21584 + movl 80(%ebp), %eax
21585 + xorl %ebx, %ebx
21586 + movl 84(%ebp), %edx
21587 + xorl %esi, %eax
21588 + xorl %esi, %edx
21589 + andl $0xfcfcfcfc, %eax
21590 + andl $0xcfcfcfcf, %edx
21591 + movb %al, %bl
21592 + movb %ah, %cl
21593 + rorl $4, %edx
21594 + movl des_SPtrans(%ebx),%ebp
21595 + movb %dl, %bl
21596 + xorl %ebp, %edi
21597 + movl 0x200+des_SPtrans(%ecx),%ebp
21598 + xorl %ebp, %edi
21599 + movb %dh, %cl
21600 + shrl $16, %eax
21601 + movl 0x100+des_SPtrans(%ebx),%ebp
21602 + xorl %ebp, %edi
21603 + movb %ah, %bl
21604 + shrl $16, %edx
21605 + movl 0x300+des_SPtrans(%ecx),%ebp
21606 + xorl %ebp, %edi
21607 + movl 24(%esp), %ebp
21608 + movb %dh, %cl
21609 + andl $0xff, %eax
21610 + andl $0xff, %edx
21611 + movl 0x600+des_SPtrans(%ebx),%ebx
21612 + xorl %ebx, %edi
21613 + movl 0x700+des_SPtrans(%ecx),%ebx
21614 + xorl %ebx, %edi
21615 + movl 0x400+des_SPtrans(%eax),%ebx
21616 + xorl %ebx, %edi
21617 + movl 0x500+des_SPtrans(%edx),%ebx
21618 + xorl %ebx, %edi
21619 +
21620 +
21621 + movl 88(%ebp), %eax
21622 + xorl %ebx, %ebx
21623 + movl 92(%ebp), %edx
21624 + xorl %edi, %eax
21625 + xorl %edi, %edx
21626 + andl $0xfcfcfcfc, %eax
21627 + andl $0xcfcfcfcf, %edx
21628 + movb %al, %bl
21629 + movb %ah, %cl
21630 + rorl $4, %edx
21631 + movl des_SPtrans(%ebx),%ebp
21632 + movb %dl, %bl
21633 + xorl %ebp, %esi
21634 + movl 0x200+des_SPtrans(%ecx),%ebp
21635 + xorl %ebp, %esi
21636 + movb %dh, %cl
21637 + shrl $16, %eax
21638 + movl 0x100+des_SPtrans(%ebx),%ebp
21639 + xorl %ebp, %esi
21640 + movb %ah, %bl
21641 + shrl $16, %edx
21642 + movl 0x300+des_SPtrans(%ecx),%ebp
21643 + xorl %ebp, %esi
21644 + movl 24(%esp), %ebp
21645 + movb %dh, %cl
21646 + andl $0xff, %eax
21647 + andl $0xff, %edx
21648 + movl 0x600+des_SPtrans(%ebx),%ebx
21649 + xorl %ebx, %esi
21650 + movl 0x700+des_SPtrans(%ecx),%ebx
21651 + xorl %ebx, %esi
21652 + movl 0x400+des_SPtrans(%eax),%ebx
21653 + xorl %ebx, %esi
21654 + movl 0x500+des_SPtrans(%edx),%ebx
21655 + xorl %ebx, %esi
21656 +
21657 +
21658 + movl 96(%ebp), %eax
21659 + xorl %ebx, %ebx
21660 + movl 100(%ebp), %edx
21661 + xorl %esi, %eax
21662 + xorl %esi, %edx
21663 + andl $0xfcfcfcfc, %eax
21664 + andl $0xcfcfcfcf, %edx
21665 + movb %al, %bl
21666 + movb %ah, %cl
21667 + rorl $4, %edx
21668 + movl des_SPtrans(%ebx),%ebp
21669 + movb %dl, %bl
21670 + xorl %ebp, %edi
21671 + movl 0x200+des_SPtrans(%ecx),%ebp
21672 + xorl %ebp, %edi
21673 + movb %dh, %cl
21674 + shrl $16, %eax
21675 + movl 0x100+des_SPtrans(%ebx),%ebp
21676 + xorl %ebp, %edi
21677 + movb %ah, %bl
21678 + shrl $16, %edx
21679 + movl 0x300+des_SPtrans(%ecx),%ebp
21680 + xorl %ebp, %edi
21681 + movl 24(%esp), %ebp
21682 + movb %dh, %cl
21683 + andl $0xff, %eax
21684 + andl $0xff, %edx
21685 + movl 0x600+des_SPtrans(%ebx),%ebx
21686 + xorl %ebx, %edi
21687 + movl 0x700+des_SPtrans(%ecx),%ebx
21688 + xorl %ebx, %edi
21689 + movl 0x400+des_SPtrans(%eax),%ebx
21690 + xorl %ebx, %edi
21691 + movl 0x500+des_SPtrans(%edx),%ebx
21692 + xorl %ebx, %edi
21693 +
21694 +
21695 + movl 104(%ebp), %eax
21696 + xorl %ebx, %ebx
21697 + movl 108(%ebp), %edx
21698 + xorl %edi, %eax
21699 + xorl %edi, %edx
21700 + andl $0xfcfcfcfc, %eax
21701 + andl $0xcfcfcfcf, %edx
21702 + movb %al, %bl
21703 + movb %ah, %cl
21704 + rorl $4, %edx
21705 + movl des_SPtrans(%ebx),%ebp
21706 + movb %dl, %bl
21707 + xorl %ebp, %esi
21708 + movl 0x200+des_SPtrans(%ecx),%ebp
21709 + xorl %ebp, %esi
21710 + movb %dh, %cl
21711 + shrl $16, %eax
21712 + movl 0x100+des_SPtrans(%ebx),%ebp
21713 + xorl %ebp, %esi
21714 + movb %ah, %bl
21715 + shrl $16, %edx
21716 + movl 0x300+des_SPtrans(%ecx),%ebp
21717 + xorl %ebp, %esi
21718 + movl 24(%esp), %ebp
21719 + movb %dh, %cl
21720 + andl $0xff, %eax
21721 + andl $0xff, %edx
21722 + movl 0x600+des_SPtrans(%ebx),%ebx
21723 + xorl %ebx, %esi
21724 + movl 0x700+des_SPtrans(%ecx),%ebx
21725 + xorl %ebx, %esi
21726 + movl 0x400+des_SPtrans(%eax),%ebx
21727 + xorl %ebx, %esi
21728 + movl 0x500+des_SPtrans(%edx),%ebx
21729 + xorl %ebx, %esi
21730 +
21731 +
21732 + movl 112(%ebp), %eax
21733 + xorl %ebx, %ebx
21734 + movl 116(%ebp), %edx
21735 + xorl %esi, %eax
21736 + xorl %esi, %edx
21737 + andl $0xfcfcfcfc, %eax
21738 + andl $0xcfcfcfcf, %edx
21739 + movb %al, %bl
21740 + movb %ah, %cl
21741 + rorl $4, %edx
21742 + movl des_SPtrans(%ebx),%ebp
21743 + movb %dl, %bl
21744 + xorl %ebp, %edi
21745 + movl 0x200+des_SPtrans(%ecx),%ebp
21746 + xorl %ebp, %edi
21747 + movb %dh, %cl
21748 + shrl $16, %eax
21749 + movl 0x100+des_SPtrans(%ebx),%ebp
21750 + xorl %ebp, %edi
21751 + movb %ah, %bl
21752 + shrl $16, %edx
21753 + movl 0x300+des_SPtrans(%ecx),%ebp
21754 + xorl %ebp, %edi
21755 + movl 24(%esp), %ebp
21756 + movb %dh, %cl
21757 + andl $0xff, %eax
21758 + andl $0xff, %edx
21759 + movl 0x600+des_SPtrans(%ebx),%ebx
21760 + xorl %ebx, %edi
21761 + movl 0x700+des_SPtrans(%ecx),%ebx
21762 + xorl %ebx, %edi
21763 + movl 0x400+des_SPtrans(%eax),%ebx
21764 + xorl %ebx, %edi
21765 + movl 0x500+des_SPtrans(%edx),%ebx
21766 + xorl %ebx, %edi
21767 +
21768 +
21769 + movl 120(%ebp), %eax
21770 + xorl %ebx, %ebx
21771 + movl 124(%ebp), %edx
21772 + xorl %edi, %eax
21773 + xorl %edi, %edx
21774 + andl $0xfcfcfcfc, %eax
21775 + andl $0xcfcfcfcf, %edx
21776 + movb %al, %bl
21777 + movb %ah, %cl
21778 + rorl $4, %edx
21779 + movl des_SPtrans(%ebx),%ebp
21780 + movb %dl, %bl
21781 + xorl %ebp, %esi
21782 + movl 0x200+des_SPtrans(%ecx),%ebp
21783 + xorl %ebp, %esi
21784 + movb %dh, %cl
21785 + shrl $16, %eax
21786 + movl 0x100+des_SPtrans(%ebx),%ebp
21787 + xorl %ebp, %esi
21788 + movb %ah, %bl
21789 + shrl $16, %edx
21790 + movl 0x300+des_SPtrans(%ecx),%ebp
21791 + xorl %ebp, %esi
21792 + movl 24(%esp), %ebp
21793 + movb %dh, %cl
21794 + andl $0xff, %eax
21795 + andl $0xff, %edx
21796 + movl 0x600+des_SPtrans(%ebx),%ebx
21797 + xorl %ebx, %esi
21798 + movl 0x700+des_SPtrans(%ecx),%ebx
21799 + xorl %ebx, %esi
21800 + movl 0x400+des_SPtrans(%eax),%ebx
21801 + xorl %ebx, %esi
21802 + movl 0x500+des_SPtrans(%edx),%ebx
21803 + xorl %ebx, %esi
21804 + jmp .L003end
21805 +.L002start_decrypt:
21806 +
21807 +
21808 + movl 120(%ebp), %eax
21809 + xorl %ebx, %ebx
21810 + movl 124(%ebp), %edx
21811 + xorl %esi, %eax
21812 + xorl %esi, %edx
21813 + andl $0xfcfcfcfc, %eax
21814 + andl $0xcfcfcfcf, %edx
21815 + movb %al, %bl
21816 + movb %ah, %cl
21817 + rorl $4, %edx
21818 + movl des_SPtrans(%ebx),%ebp
21819 + movb %dl, %bl
21820 + xorl %ebp, %edi
21821 + movl 0x200+des_SPtrans(%ecx),%ebp
21822 + xorl %ebp, %edi
21823 + movb %dh, %cl
21824 + shrl $16, %eax
21825 + movl 0x100+des_SPtrans(%ebx),%ebp
21826 + xorl %ebp, %edi
21827 + movb %ah, %bl
21828 + shrl $16, %edx
21829 + movl 0x300+des_SPtrans(%ecx),%ebp
21830 + xorl %ebp, %edi
21831 + movl 24(%esp), %ebp
21832 + movb %dh, %cl
21833 + andl $0xff, %eax
21834 + andl $0xff, %edx
21835 + movl 0x600+des_SPtrans(%ebx),%ebx
21836 + xorl %ebx, %edi
21837 + movl 0x700+des_SPtrans(%ecx),%ebx
21838 + xorl %ebx, %edi
21839 + movl 0x400+des_SPtrans(%eax),%ebx
21840 + xorl %ebx, %edi
21841 + movl 0x500+des_SPtrans(%edx),%ebx
21842 + xorl %ebx, %edi
21843 +
21844 +
21845 + movl 112(%ebp), %eax
21846 + xorl %ebx, %ebx
21847 + movl 116(%ebp), %edx
21848 + xorl %edi, %eax
21849 + xorl %edi, %edx
21850 + andl $0xfcfcfcfc, %eax
21851 + andl $0xcfcfcfcf, %edx
21852 + movb %al, %bl
21853 + movb %ah, %cl
21854 + rorl $4, %edx
21855 + movl des_SPtrans(%ebx),%ebp
21856 + movb %dl, %bl
21857 + xorl %ebp, %esi
21858 + movl 0x200+des_SPtrans(%ecx),%ebp
21859 + xorl %ebp, %esi
21860 + movb %dh, %cl
21861 + shrl $16, %eax
21862 + movl 0x100+des_SPtrans(%ebx),%ebp
21863 + xorl %ebp, %esi
21864 + movb %ah, %bl
21865 + shrl $16, %edx
21866 + movl 0x300+des_SPtrans(%ecx),%ebp
21867 + xorl %ebp, %esi
21868 + movl 24(%esp), %ebp
21869 + movb %dh, %cl
21870 + andl $0xff, %eax
21871 + andl $0xff, %edx
21872 + movl 0x600+des_SPtrans(%ebx),%ebx
21873 + xorl %ebx, %esi
21874 + movl 0x700+des_SPtrans(%ecx),%ebx
21875 + xorl %ebx, %esi
21876 + movl 0x400+des_SPtrans(%eax),%ebx
21877 + xorl %ebx, %esi
21878 + movl 0x500+des_SPtrans(%edx),%ebx
21879 + xorl %ebx, %esi
21880 +
21881 +
21882 + movl 104(%ebp), %eax
21883 + xorl %ebx, %ebx
21884 + movl 108(%ebp), %edx
21885 + xorl %esi, %eax
21886 + xorl %esi, %edx
21887 + andl $0xfcfcfcfc, %eax
21888 + andl $0xcfcfcfcf, %edx
21889 + movb %al, %bl
21890 + movb %ah, %cl
21891 + rorl $4, %edx
21892 + movl des_SPtrans(%ebx),%ebp
21893 + movb %dl, %bl
21894 + xorl %ebp, %edi
21895 + movl 0x200+des_SPtrans(%ecx),%ebp
21896 + xorl %ebp, %edi
21897 + movb %dh, %cl
21898 + shrl $16, %eax
21899 + movl 0x100+des_SPtrans(%ebx),%ebp
21900 + xorl %ebp, %edi
21901 + movb %ah, %bl
21902 + shrl $16, %edx
21903 + movl 0x300+des_SPtrans(%ecx),%ebp
21904 + xorl %ebp, %edi
21905 + movl 24(%esp), %ebp
21906 + movb %dh, %cl
21907 + andl $0xff, %eax
21908 + andl $0xff, %edx
21909 + movl 0x600+des_SPtrans(%ebx),%ebx
21910 + xorl %ebx, %edi
21911 + movl 0x700+des_SPtrans(%ecx),%ebx
21912 + xorl %ebx, %edi
21913 + movl 0x400+des_SPtrans(%eax),%ebx
21914 + xorl %ebx, %edi
21915 + movl 0x500+des_SPtrans(%edx),%ebx
21916 + xorl %ebx, %edi
21917 +
21918 +
21919 + movl 96(%ebp), %eax
21920 + xorl %ebx, %ebx
21921 + movl 100(%ebp), %edx
21922 + xorl %edi, %eax
21923 + xorl %edi, %edx
21924 + andl $0xfcfcfcfc, %eax
21925 + andl $0xcfcfcfcf, %edx
21926 + movb %al, %bl
21927 + movb %ah, %cl
21928 + rorl $4, %edx
21929 + movl des_SPtrans(%ebx),%ebp
21930 + movb %dl, %bl
21931 + xorl %ebp, %esi
21932 + movl 0x200+des_SPtrans(%ecx),%ebp
21933 + xorl %ebp, %esi
21934 + movb %dh, %cl
21935 + shrl $16, %eax
21936 + movl 0x100+des_SPtrans(%ebx),%ebp
21937 + xorl %ebp, %esi
21938 + movb %ah, %bl
21939 + shrl $16, %edx
21940 + movl 0x300+des_SPtrans(%ecx),%ebp
21941 + xorl %ebp, %esi
21942 + movl 24(%esp), %ebp
21943 + movb %dh, %cl
21944 + andl $0xff, %eax
21945 + andl $0xff, %edx
21946 + movl 0x600+des_SPtrans(%ebx),%ebx
21947 + xorl %ebx, %esi
21948 + movl 0x700+des_SPtrans(%ecx),%ebx
21949 + xorl %ebx, %esi
21950 + movl 0x400+des_SPtrans(%eax),%ebx
21951 + xorl %ebx, %esi
21952 + movl 0x500+des_SPtrans(%edx),%ebx
21953 + xorl %ebx, %esi
21954 +
21955 +
21956 + movl 88(%ebp), %eax
21957 + xorl %ebx, %ebx
21958 + movl 92(%ebp), %edx
21959 + xorl %esi, %eax
21960 + xorl %esi, %edx
21961 + andl $0xfcfcfcfc, %eax
21962 + andl $0xcfcfcfcf, %edx
21963 + movb %al, %bl
21964 + movb %ah, %cl
21965 + rorl $4, %edx
21966 + movl des_SPtrans(%ebx),%ebp
21967 + movb %dl, %bl
21968 + xorl %ebp, %edi
21969 + movl 0x200+des_SPtrans(%ecx),%ebp
21970 + xorl %ebp, %edi
21971 + movb %dh, %cl
21972 + shrl $16, %eax
21973 + movl 0x100+des_SPtrans(%ebx),%ebp
21974 + xorl %ebp, %edi
21975 + movb %ah, %bl
21976 + shrl $16, %edx
21977 + movl 0x300+des_SPtrans(%ecx),%ebp
21978 + xorl %ebp, %edi
21979 + movl 24(%esp), %ebp
21980 + movb %dh, %cl
21981 + andl $0xff, %eax
21982 + andl $0xff, %edx
21983 + movl 0x600+des_SPtrans(%ebx),%ebx
21984 + xorl %ebx, %edi
21985 + movl 0x700+des_SPtrans(%ecx),%ebx
21986 + xorl %ebx, %edi
21987 + movl 0x400+des_SPtrans(%eax),%ebx
21988 + xorl %ebx, %edi
21989 + movl 0x500+des_SPtrans(%edx),%ebx
21990 + xorl %ebx, %edi
21991 +
21992 +
21993 + movl 80(%ebp), %eax
21994 + xorl %ebx, %ebx
21995 + movl 84(%ebp), %edx
21996 + xorl %edi, %eax
21997 + xorl %edi, %edx
21998 + andl $0xfcfcfcfc, %eax
21999 + andl $0xcfcfcfcf, %edx
22000 + movb %al, %bl
22001 + movb %ah, %cl
22002 + rorl $4, %edx
22003 + movl des_SPtrans(%ebx),%ebp
22004 + movb %dl, %bl
22005 + xorl %ebp, %esi
22006 + movl 0x200+des_SPtrans(%ecx),%ebp
22007 + xorl %ebp, %esi
22008 + movb %dh, %cl
22009 + shrl $16, %eax
22010 + movl 0x100+des_SPtrans(%ebx),%ebp
22011 + xorl %ebp, %esi
22012 + movb %ah, %bl
22013 + shrl $16, %edx
22014 + movl 0x300+des_SPtrans(%ecx),%ebp
22015 + xorl %ebp, %esi
22016 + movl 24(%esp), %ebp
22017 + movb %dh, %cl
22018 + andl $0xff, %eax
22019 + andl $0xff, %edx
22020 + movl 0x600+des_SPtrans(%ebx),%ebx
22021 + xorl %ebx, %esi
22022 + movl 0x700+des_SPtrans(%ecx),%ebx
22023 + xorl %ebx, %esi
22024 + movl 0x400+des_SPtrans(%eax),%ebx
22025 + xorl %ebx, %esi
22026 + movl 0x500+des_SPtrans(%edx),%ebx
22027 + xorl %ebx, %esi
22028 +
22029 +
22030 + movl 72(%ebp), %eax
22031 + xorl %ebx, %ebx
22032 + movl 76(%ebp), %edx
22033 + xorl %esi, %eax
22034 + xorl %esi, %edx
22035 + andl $0xfcfcfcfc, %eax
22036 + andl $0xcfcfcfcf, %edx
22037 + movb %al, %bl
22038 + movb %ah, %cl
22039 + rorl $4, %edx
22040 + movl des_SPtrans(%ebx),%ebp
22041 + movb %dl, %bl
22042 + xorl %ebp, %edi
22043 + movl 0x200+des_SPtrans(%ecx),%ebp
22044 + xorl %ebp, %edi
22045 + movb %dh, %cl
22046 + shrl $16, %eax
22047 + movl 0x100+des_SPtrans(%ebx),%ebp
22048 + xorl %ebp, %edi
22049 + movb %ah, %bl
22050 + shrl $16, %edx
22051 + movl 0x300+des_SPtrans(%ecx),%ebp
22052 + xorl %ebp, %edi
22053 + movl 24(%esp), %ebp
22054 + movb %dh, %cl
22055 + andl $0xff, %eax
22056 + andl $0xff, %edx
22057 + movl 0x600+des_SPtrans(%ebx),%ebx
22058 + xorl %ebx, %edi
22059 + movl 0x700+des_SPtrans(%ecx),%ebx
22060 + xorl %ebx, %edi
22061 + movl 0x400+des_SPtrans(%eax),%ebx
22062 + xorl %ebx, %edi
22063 + movl 0x500+des_SPtrans(%edx),%ebx
22064 + xorl %ebx, %edi
22065 +
22066 +
22067 + movl 64(%ebp), %eax
22068 + xorl %ebx, %ebx
22069 + movl 68(%ebp), %edx
22070 + xorl %edi, %eax
22071 + xorl %edi, %edx
22072 + andl $0xfcfcfcfc, %eax
22073 + andl $0xcfcfcfcf, %edx
22074 + movb %al, %bl
22075 + movb %ah, %cl
22076 + rorl $4, %edx
22077 + movl des_SPtrans(%ebx),%ebp
22078 + movb %dl, %bl
22079 + xorl %ebp, %esi
22080 + movl 0x200+des_SPtrans(%ecx),%ebp
22081 + xorl %ebp, %esi
22082 + movb %dh, %cl
22083 + shrl $16, %eax
22084 + movl 0x100+des_SPtrans(%ebx),%ebp
22085 + xorl %ebp, %esi
22086 + movb %ah, %bl
22087 + shrl $16, %edx
22088 + movl 0x300+des_SPtrans(%ecx),%ebp
22089 + xorl %ebp, %esi
22090 + movl 24(%esp), %ebp
22091 + movb %dh, %cl
22092 + andl $0xff, %eax
22093 + andl $0xff, %edx
22094 + movl 0x600+des_SPtrans(%ebx),%ebx
22095 + xorl %ebx, %esi
22096 + movl 0x700+des_SPtrans(%ecx),%ebx
22097 + xorl %ebx, %esi
22098 + movl 0x400+des_SPtrans(%eax),%ebx
22099 + xorl %ebx, %esi
22100 + movl 0x500+des_SPtrans(%edx),%ebx
22101 + xorl %ebx, %esi
22102 +
22103 +
22104 + movl 56(%ebp), %eax
22105 + xorl %ebx, %ebx
22106 + movl 60(%ebp), %edx
22107 + xorl %esi, %eax
22108 + xorl %esi, %edx
22109 + andl $0xfcfcfcfc, %eax
22110 + andl $0xcfcfcfcf, %edx
22111 + movb %al, %bl
22112 + movb %ah, %cl
22113 + rorl $4, %edx
22114 + movl des_SPtrans(%ebx),%ebp
22115 + movb %dl, %bl
22116 + xorl %ebp, %edi
22117 + movl 0x200+des_SPtrans(%ecx),%ebp
22118 + xorl %ebp, %edi
22119 + movb %dh, %cl
22120 + shrl $16, %eax
22121 + movl 0x100+des_SPtrans(%ebx),%ebp
22122 + xorl %ebp, %edi
22123 + movb %ah, %bl
22124 + shrl $16, %edx
22125 + movl 0x300+des_SPtrans(%ecx),%ebp
22126 + xorl %ebp, %edi
22127 + movl 24(%esp), %ebp
22128 + movb %dh, %cl
22129 + andl $0xff, %eax
22130 + andl $0xff, %edx
22131 + movl 0x600+des_SPtrans(%ebx),%ebx
22132 + xorl %ebx, %edi
22133 + movl 0x700+des_SPtrans(%ecx),%ebx
22134 + xorl %ebx, %edi
22135 + movl 0x400+des_SPtrans(%eax),%ebx
22136 + xorl %ebx, %edi
22137 + movl 0x500+des_SPtrans(%edx),%ebx
22138 + xorl %ebx, %edi
22139 +
22140 +
22141 + movl 48(%ebp), %eax
22142 + xorl %ebx, %ebx
22143 + movl 52(%ebp), %edx
22144 + xorl %edi, %eax
22145 + xorl %edi, %edx
22146 + andl $0xfcfcfcfc, %eax
22147 + andl $0xcfcfcfcf, %edx
22148 + movb %al, %bl
22149 + movb %ah, %cl
22150 + rorl $4, %edx
22151 + movl des_SPtrans(%ebx),%ebp
22152 + movb %dl, %bl
22153 + xorl %ebp, %esi
22154 + movl 0x200+des_SPtrans(%ecx),%ebp
22155 + xorl %ebp, %esi
22156 + movb %dh, %cl
22157 + shrl $16, %eax
22158 + movl 0x100+des_SPtrans(%ebx),%ebp
22159 + xorl %ebp, %esi
22160 + movb %ah, %bl
22161 + shrl $16, %edx
22162 + movl 0x300+des_SPtrans(%ecx),%ebp
22163 + xorl %ebp, %esi
22164 + movl 24(%esp), %ebp
22165 + movb %dh, %cl
22166 + andl $0xff, %eax
22167 + andl $0xff, %edx
22168 + movl 0x600+des_SPtrans(%ebx),%ebx
22169 + xorl %ebx, %esi
22170 + movl 0x700+des_SPtrans(%ecx),%ebx
22171 + xorl %ebx, %esi
22172 + movl 0x400+des_SPtrans(%eax),%ebx
22173 + xorl %ebx, %esi
22174 + movl 0x500+des_SPtrans(%edx),%ebx
22175 + xorl %ebx, %esi
22176 +
22177 +
22178 + movl 40(%ebp), %eax
22179 + xorl %ebx, %ebx
22180 + movl 44(%ebp), %edx
22181 + xorl %esi, %eax
22182 + xorl %esi, %edx
22183 + andl $0xfcfcfcfc, %eax
22184 + andl $0xcfcfcfcf, %edx
22185 + movb %al, %bl
22186 + movb %ah, %cl
22187 + rorl $4, %edx
22188 + movl des_SPtrans(%ebx),%ebp
22189 + movb %dl, %bl
22190 + xorl %ebp, %edi
22191 + movl 0x200+des_SPtrans(%ecx),%ebp
22192 + xorl %ebp, %edi
22193 + movb %dh, %cl
22194 + shrl $16, %eax
22195 + movl 0x100+des_SPtrans(%ebx),%ebp
22196 + xorl %ebp, %edi
22197 + movb %ah, %bl
22198 + shrl $16, %edx
22199 + movl 0x300+des_SPtrans(%ecx),%ebp
22200 + xorl %ebp, %edi
22201 + movl 24(%esp), %ebp
22202 + movb %dh, %cl
22203 + andl $0xff, %eax
22204 + andl $0xff, %edx
22205 + movl 0x600+des_SPtrans(%ebx),%ebx
22206 + xorl %ebx, %edi
22207 + movl 0x700+des_SPtrans(%ecx),%ebx
22208 + xorl %ebx, %edi
22209 + movl 0x400+des_SPtrans(%eax),%ebx
22210 + xorl %ebx, %edi
22211 + movl 0x500+des_SPtrans(%edx),%ebx
22212 + xorl %ebx, %edi
22213 +
22214 +
22215 + movl 32(%ebp), %eax
22216 + xorl %ebx, %ebx
22217 + movl 36(%ebp), %edx
22218 + xorl %edi, %eax
22219 + xorl %edi, %edx
22220 + andl $0xfcfcfcfc, %eax
22221 + andl $0xcfcfcfcf, %edx
22222 + movb %al, %bl
22223 + movb %ah, %cl
22224 + rorl $4, %edx
22225 + movl des_SPtrans(%ebx),%ebp
22226 + movb %dl, %bl
22227 + xorl %ebp, %esi
22228 + movl 0x200+des_SPtrans(%ecx),%ebp
22229 + xorl %ebp, %esi
22230 + movb %dh, %cl
22231 + shrl $16, %eax
22232 + movl 0x100+des_SPtrans(%ebx),%ebp
22233 + xorl %ebp, %esi
22234 + movb %ah, %bl
22235 + shrl $16, %edx
22236 + movl 0x300+des_SPtrans(%ecx),%ebp
22237 + xorl %ebp, %esi
22238 + movl 24(%esp), %ebp
22239 + movb %dh, %cl
22240 + andl $0xff, %eax
22241 + andl $0xff, %edx
22242 + movl 0x600+des_SPtrans(%ebx),%ebx
22243 + xorl %ebx, %esi
22244 + movl 0x700+des_SPtrans(%ecx),%ebx
22245 + xorl %ebx, %esi
22246 + movl 0x400+des_SPtrans(%eax),%ebx
22247 + xorl %ebx, %esi
22248 + movl 0x500+des_SPtrans(%edx),%ebx
22249 + xorl %ebx, %esi
22250 +
22251 +
22252 + movl 24(%ebp), %eax
22253 + xorl %ebx, %ebx
22254 + movl 28(%ebp), %edx
22255 + xorl %esi, %eax
22256 + xorl %esi, %edx
22257 + andl $0xfcfcfcfc, %eax
22258 + andl $0xcfcfcfcf, %edx
22259 + movb %al, %bl
22260 + movb %ah, %cl
22261 + rorl $4, %edx
22262 + movl des_SPtrans(%ebx),%ebp
22263 + movb %dl, %bl
22264 + xorl %ebp, %edi
22265 + movl 0x200+des_SPtrans(%ecx),%ebp
22266 + xorl %ebp, %edi
22267 + movb %dh, %cl
22268 + shrl $16, %eax
22269 + movl 0x100+des_SPtrans(%ebx),%ebp
22270 + xorl %ebp, %edi
22271 + movb %ah, %bl
22272 + shrl $16, %edx
22273 + movl 0x300+des_SPtrans(%ecx),%ebp
22274 + xorl %ebp, %edi
22275 + movl 24(%esp), %ebp
22276 + movb %dh, %cl
22277 + andl $0xff, %eax
22278 + andl $0xff, %edx
22279 + movl 0x600+des_SPtrans(%ebx),%ebx
22280 + xorl %ebx, %edi
22281 + movl 0x700+des_SPtrans(%ecx),%ebx
22282 + xorl %ebx, %edi
22283 + movl 0x400+des_SPtrans(%eax),%ebx
22284 + xorl %ebx, %edi
22285 + movl 0x500+des_SPtrans(%edx),%ebx
22286 + xorl %ebx, %edi
22287 +
22288 +
22289 + movl 16(%ebp), %eax
22290 + xorl %ebx, %ebx
22291 + movl 20(%ebp), %edx
22292 + xorl %edi, %eax
22293 + xorl %edi, %edx
22294 + andl $0xfcfcfcfc, %eax
22295 + andl $0xcfcfcfcf, %edx
22296 + movb %al, %bl
22297 + movb %ah, %cl
22298 + rorl $4, %edx
22299 + movl des_SPtrans(%ebx),%ebp
22300 + movb %dl, %bl
22301 + xorl %ebp, %esi
22302 + movl 0x200+des_SPtrans(%ecx),%ebp
22303 + xorl %ebp, %esi
22304 + movb %dh, %cl
22305 + shrl $16, %eax
22306 + movl 0x100+des_SPtrans(%ebx),%ebp
22307 + xorl %ebp, %esi
22308 + movb %ah, %bl
22309 + shrl $16, %edx
22310 + movl 0x300+des_SPtrans(%ecx),%ebp
22311 + xorl %ebp, %esi
22312 + movl 24(%esp), %ebp
22313 + movb %dh, %cl
22314 + andl $0xff, %eax
22315 + andl $0xff, %edx
22316 + movl 0x600+des_SPtrans(%ebx),%ebx
22317 + xorl %ebx, %esi
22318 + movl 0x700+des_SPtrans(%ecx),%ebx
22319 + xorl %ebx, %esi
22320 + movl 0x400+des_SPtrans(%eax),%ebx
22321 + xorl %ebx, %esi
22322 + movl 0x500+des_SPtrans(%edx),%ebx
22323 + xorl %ebx, %esi
22324 +
22325 +
22326 + movl 8(%ebp), %eax
22327 + xorl %ebx, %ebx
22328 + movl 12(%ebp), %edx
22329 + xorl %esi, %eax
22330 + xorl %esi, %edx
22331 + andl $0xfcfcfcfc, %eax
22332 + andl $0xcfcfcfcf, %edx
22333 + movb %al, %bl
22334 + movb %ah, %cl
22335 + rorl $4, %edx
22336 + movl des_SPtrans(%ebx),%ebp
22337 + movb %dl, %bl
22338 + xorl %ebp, %edi
22339 + movl 0x200+des_SPtrans(%ecx),%ebp
22340 + xorl %ebp, %edi
22341 + movb %dh, %cl
22342 + shrl $16, %eax
22343 + movl 0x100+des_SPtrans(%ebx),%ebp
22344 + xorl %ebp, %edi
22345 + movb %ah, %bl
22346 + shrl $16, %edx
22347 + movl 0x300+des_SPtrans(%ecx),%ebp
22348 + xorl %ebp, %edi
22349 + movl 24(%esp), %ebp
22350 + movb %dh, %cl
22351 + andl $0xff, %eax
22352 + andl $0xff, %edx
22353 + movl 0x600+des_SPtrans(%ebx),%ebx
22354 + xorl %ebx, %edi
22355 + movl 0x700+des_SPtrans(%ecx),%ebx
22356 + xorl %ebx, %edi
22357 + movl 0x400+des_SPtrans(%eax),%ebx
22358 + xorl %ebx, %edi
22359 + movl 0x500+des_SPtrans(%edx),%ebx
22360 + xorl %ebx, %edi
22361 +
22362 +
22363 + movl (%ebp), %eax
22364 + xorl %ebx, %ebx
22365 + movl 4(%ebp), %edx
22366 + xorl %edi, %eax
22367 + xorl %edi, %edx
22368 + andl $0xfcfcfcfc, %eax
22369 + andl $0xcfcfcfcf, %edx
22370 + movb %al, %bl
22371 + movb %ah, %cl
22372 + rorl $4, %edx
22373 + movl des_SPtrans(%ebx),%ebp
22374 + movb %dl, %bl
22375 + xorl %ebp, %esi
22376 + movl 0x200+des_SPtrans(%ecx),%ebp
22377 + xorl %ebp, %esi
22378 + movb %dh, %cl
22379 + shrl $16, %eax
22380 + movl 0x100+des_SPtrans(%ebx),%ebp
22381 + xorl %ebp, %esi
22382 + movb %ah, %bl
22383 + shrl $16, %edx
22384 + movl 0x300+des_SPtrans(%ecx),%ebp
22385 + xorl %ebp, %esi
22386 + movl 24(%esp), %ebp
22387 + movb %dh, %cl
22388 + andl $0xff, %eax
22389 + andl $0xff, %edx
22390 + movl 0x600+des_SPtrans(%ebx),%ebx
22391 + xorl %ebx, %esi
22392 + movl 0x700+des_SPtrans(%ecx),%ebx
22393 + xorl %ebx, %esi
22394 + movl 0x400+des_SPtrans(%eax),%ebx
22395 + xorl %ebx, %esi
22396 + movl 0x500+des_SPtrans(%edx),%ebx
22397 + xorl %ebx, %esi
22398 +.L003end:
22399 +
22400 +
22401 + rorl $3, %edi
22402 + movl 20(%esp), %eax
22403 + rorl $3, %esi
22404 + movl %edi, (%eax)
22405 + movl %esi, 4(%eax)
22406 + popl %ebp
22407 + popl %ebx
22408 + popl %edi
22409 + popl %esi
22410 + ret
22411 +.des_encrypt2_end:
22412 + .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
22413 +.ident "desasm.pl"
22414 +.text
22415 + .align 16
22416 +.globl des_encrypt3
22417 + .type des_encrypt3 , @function
22418 +des_encrypt3:
22419 + pushl %ebx
22420 + movl 8(%esp), %ebx
22421 + pushl %ebp
22422 + pushl %esi
22423 + pushl %edi
22424 +
22425 +
22426 + movl (%ebx), %edi
22427 + movl 4(%ebx), %esi
22428 + subl $12, %esp
22429 +
22430 +
22431 + roll $4, %edi
22432 + movl %edi, %edx
22433 + xorl %esi, %edi
22434 + andl $0xf0f0f0f0, %edi
22435 + xorl %edi, %edx
22436 + xorl %edi, %esi
22437 +
22438 + roll $20, %esi
22439 + movl %esi, %edi
22440 + xorl %edx, %esi
22441 + andl $0xfff0000f, %esi
22442 + xorl %esi, %edi
22443 + xorl %esi, %edx
22444 +
22445 + roll $14, %edi
22446 + movl %edi, %esi
22447 + xorl %edx, %edi
22448 + andl $0x33333333, %edi
22449 + xorl %edi, %esi
22450 + xorl %edi, %edx
22451 +
22452 + roll $22, %edx
22453 + movl %edx, %edi
22454 + xorl %esi, %edx
22455 + andl $0x03fc03fc, %edx
22456 + xorl %edx, %edi
22457 + xorl %edx, %esi
22458 +
22459 + roll $9, %edi
22460 + movl %edi, %edx
22461 + xorl %esi, %edi
22462 + andl $0xaaaaaaaa, %edi
22463 + xorl %edi, %edx
22464 + xorl %edi, %esi
22465 +
22466 + rorl $3, %edx
22467 + rorl $2, %esi
22468 + movl %esi, 4(%ebx)
22469 + movl 36(%esp), %eax
22470 + movl %edx, (%ebx)
22471 + movl 40(%esp), %edi
22472 + movl 44(%esp), %esi
22473 + movl $1, 8(%esp)
22474 + movl %eax, 4(%esp)
22475 + movl %ebx, (%esp)
22476 + call des_encrypt2
22477 + movl $0, 8(%esp)
22478 + movl %edi, 4(%esp)
22479 + movl %ebx, (%esp)
22480 + call des_encrypt2
22481 + movl $1, 8(%esp)
22482 + movl %esi, 4(%esp)
22483 + movl %ebx, (%esp)
22484 + call des_encrypt2
22485 + addl $12, %esp
22486 + movl (%ebx), %edi
22487 + movl 4(%ebx), %esi
22488 +
22489 +
22490 + roll $2, %esi
22491 + roll $3, %edi
22492 + movl %edi, %eax
22493 + xorl %esi, %edi
22494 + andl $0xaaaaaaaa, %edi
22495 + xorl %edi, %eax
22496 + xorl %edi, %esi
22497 +
22498 + roll $23, %eax
22499 + movl %eax, %edi
22500 + xorl %esi, %eax
22501 + andl $0x03fc03fc, %eax
22502 + xorl %eax, %edi
22503 + xorl %eax, %esi
22504 +
22505 + roll $10, %edi
22506 + movl %edi, %eax
22507 + xorl %esi, %edi
22508 + andl $0x33333333, %edi
22509 + xorl %edi, %eax
22510 + xorl %edi, %esi
22511 +
22512 + roll $18, %esi
22513 + movl %esi, %edi
22514 + xorl %eax, %esi
22515 + andl $0xfff0000f, %esi
22516 + xorl %esi, %edi
22517 + xorl %esi, %eax
22518 +
22519 + roll $12, %edi
22520 + movl %edi, %esi
22521 + xorl %eax, %edi
22522 + andl $0xf0f0f0f0, %edi
22523 + xorl %edi, %esi
22524 + xorl %edi, %eax
22525 +
22526 + rorl $4, %eax
22527 + movl %eax, (%ebx)
22528 + movl %esi, 4(%ebx)
22529 + popl %edi
22530 + popl %esi
22531 + popl %ebp
22532 + popl %ebx
22533 + ret
22534 +.des_encrypt3_end:
22535 + .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
22536 +.ident "desasm.pl"
22537 +.text
22538 + .align 16
22539 +.globl des_decrypt3
22540 + .type des_decrypt3 , @function
22541 +des_decrypt3:
22542 + pushl %ebx
22543 + movl 8(%esp), %ebx
22544 + pushl %ebp
22545 + pushl %esi
22546 + pushl %edi
22547 +
22548 +
22549 + movl (%ebx), %edi
22550 + movl 4(%ebx), %esi
22551 + subl $12, %esp
22552 +
22553 +
22554 + roll $4, %edi
22555 + movl %edi, %edx
22556 + xorl %esi, %edi
22557 + andl $0xf0f0f0f0, %edi
22558 + xorl %edi, %edx
22559 + xorl %edi, %esi
22560 +
22561 + roll $20, %esi
22562 + movl %esi, %edi
22563 + xorl %edx, %esi
22564 + andl $0xfff0000f, %esi
22565 + xorl %esi, %edi
22566 + xorl %esi, %edx
22567 +
22568 + roll $14, %edi
22569 + movl %edi, %esi
22570 + xorl %edx, %edi
22571 + andl $0x33333333, %edi
22572 + xorl %edi, %esi
22573 + xorl %edi, %edx
22574 +
22575 + roll $22, %edx
22576 + movl %edx, %edi
22577 + xorl %esi, %edx
22578 + andl $0x03fc03fc, %edx
22579 + xorl %edx, %edi
22580 + xorl %edx, %esi
22581 +
22582 + roll $9, %edi
22583 + movl %edi, %edx
22584 + xorl %esi, %edi
22585 + andl $0xaaaaaaaa, %edi
22586 + xorl %edi, %edx
22587 + xorl %edi, %esi
22588 +
22589 + rorl $3, %edx
22590 + rorl $2, %esi
22591 + movl %esi, 4(%ebx)
22592 + movl 36(%esp), %esi
22593 + movl %edx, (%ebx)
22594 + movl 40(%esp), %edi
22595 + movl 44(%esp), %eax
22596 + movl $0, 8(%esp)
22597 + movl %eax, 4(%esp)
22598 + movl %ebx, (%esp)
22599 + call des_encrypt2
22600 + movl $1, 8(%esp)
22601 + movl %edi, 4(%esp)
22602 + movl %ebx, (%esp)
22603 + call des_encrypt2
22604 + movl $0, 8(%esp)
22605 + movl %esi, 4(%esp)
22606 + movl %ebx, (%esp)
22607 + call des_encrypt2
22608 + addl $12, %esp
22609 + movl (%ebx), %edi
22610 + movl 4(%ebx), %esi
22611 +
22612 +
22613 + roll $2, %esi
22614 + roll $3, %edi
22615 + movl %edi, %eax
22616 + xorl %esi, %edi
22617 + andl $0xaaaaaaaa, %edi
22618 + xorl %edi, %eax
22619 + xorl %edi, %esi
22620 +
22621 + roll $23, %eax
22622 + movl %eax, %edi
22623 + xorl %esi, %eax
22624 + andl $0x03fc03fc, %eax
22625 + xorl %eax, %edi
22626 + xorl %eax, %esi
22627 +
22628 + roll $10, %edi
22629 + movl %edi, %eax
22630 + xorl %esi, %edi
22631 + andl $0x33333333, %edi
22632 + xorl %edi, %eax
22633 + xorl %edi, %esi
22634 +
22635 + roll $18, %esi
22636 + movl %esi, %edi
22637 + xorl %eax, %esi
22638 + andl $0xfff0000f, %esi
22639 + xorl %esi, %edi
22640 + xorl %esi, %eax
22641 +
22642 + roll $12, %edi
22643 + movl %edi, %esi
22644 + xorl %eax, %edi
22645 + andl $0xf0f0f0f0, %edi
22646 + xorl %edi, %esi
22647 + xorl %edi, %eax
22648 +
22649 + rorl $4, %eax
22650 + movl %eax, (%ebx)
22651 + movl %esi, 4(%ebx)
22652 + popl %edi
22653 + popl %esi
22654 + popl %ebp
22655 + popl %ebx
22656 + ret
22657 +.des_decrypt3_end:
22658 + .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
22659 +.ident "desasm.pl"
22660 +.text
22661 + .align 16
22662 +.globl des_ncbc_encrypt
22663 + .type des_ncbc_encrypt , @function
22664 +des_ncbc_encrypt:
22665 +
22666 + pushl %ebp
22667 + pushl %ebx
22668 + pushl %esi
22669 + pushl %edi
22670 + movl 28(%esp), %ebp
22671 +
22672 + movl 36(%esp), %ebx
22673 + movl (%ebx), %esi
22674 + movl 4(%ebx), %edi
22675 + pushl %edi
22676 + pushl %esi
22677 + pushl %edi
22678 + pushl %esi
22679 + movl %esp, %ebx
22680 + movl 36(%esp), %esi
22681 + movl 40(%esp), %edi
22682 +
22683 + movl 56(%esp), %ecx
22684 +
22685 + pushl %ecx
22686 +
22687 + movl 52(%esp), %eax
22688 + pushl %eax
22689 + pushl %ebx
22690 + cmpl $0, %ecx
22691 + jz .L004decrypt
22692 + andl $4294967288, %ebp
22693 + movl 12(%esp), %eax
22694 + movl 16(%esp), %ebx
22695 + jz .L005encrypt_finish
22696 +.L006encrypt_loop:
22697 + movl (%esi), %ecx
22698 + movl 4(%esi), %edx
22699 + xorl %ecx, %eax
22700 + xorl %edx, %ebx
22701 + movl %eax, 12(%esp)
22702 + movl %ebx, 16(%esp)
22703 + call des_encrypt
22704 + movl 12(%esp), %eax
22705 + movl 16(%esp), %ebx
22706 + movl %eax, (%edi)
22707 + movl %ebx, 4(%edi)
22708 + addl $8, %esi
22709 + addl $8, %edi
22710 + subl $8, %ebp
22711 + jnz .L006encrypt_loop
22712 +.L005encrypt_finish:
22713 + movl 56(%esp), %ebp
22714 + andl $7, %ebp
22715 + jz .L007finish
22716 + xorl %ecx, %ecx
22717 + xorl %edx, %edx
22718 + movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
22719 + jmp *%ebp
22720 +.L009ej7:
22721 + movb 6(%esi), %dh
22722 + sall $8, %edx
22723 +.L010ej6:
22724 + movb 5(%esi), %dh
22725 +.L011ej5:
22726 + movb 4(%esi), %dl
22727 +.L012ej4:
22728 + movl (%esi), %ecx
22729 + jmp .L013ejend
22730 +.L014ej3:
22731 + movb 2(%esi), %ch
22732 + sall $8, %ecx
22733 +.L015ej2:
22734 + movb 1(%esi), %ch
22735 +.L016ej1:
22736 + movb (%esi), %cl
22737 +.L013ejend:
22738 + xorl %ecx, %eax
22739 + xorl %edx, %ebx
22740 + movl %eax, 12(%esp)
22741 + movl %ebx, 16(%esp)
22742 + call des_encrypt
22743 + movl 12(%esp), %eax
22744 + movl 16(%esp), %ebx
22745 + movl %eax, (%edi)
22746 + movl %ebx, 4(%edi)
22747 + jmp .L007finish
22748 +.align 16
22749 +.L004decrypt:
22750 + andl $4294967288, %ebp
22751 + movl 20(%esp), %eax
22752 + movl 24(%esp), %ebx
22753 + jz .L017decrypt_finish
22754 +.L018decrypt_loop:
22755 + movl (%esi), %eax
22756 + movl 4(%esi), %ebx
22757 + movl %eax, 12(%esp)
22758 + movl %ebx, 16(%esp)
22759 + call des_encrypt
22760 + movl 12(%esp), %eax
22761 + movl 16(%esp), %ebx
22762 + movl 20(%esp), %ecx
22763 + movl 24(%esp), %edx
22764 + xorl %eax, %ecx
22765 + xorl %ebx, %edx
22766 + movl (%esi), %eax
22767 + movl 4(%esi), %ebx
22768 + movl %ecx, (%edi)
22769 + movl %edx, 4(%edi)
22770 + movl %eax, 20(%esp)
22771 + movl %ebx, 24(%esp)
22772 + addl $8, %esi
22773 + addl $8, %edi
22774 + subl $8, %ebp
22775 + jnz .L018decrypt_loop
22776 +.L017decrypt_finish:
22777 + movl 56(%esp), %ebp
22778 + andl $7, %ebp
22779 + jz .L007finish
22780 + movl (%esi), %eax
22781 + movl 4(%esi), %ebx
22782 + movl %eax, 12(%esp)
22783 + movl %ebx, 16(%esp)
22784 + call des_encrypt
22785 + movl 12(%esp), %eax
22786 + movl 16(%esp), %ebx
22787 + movl 20(%esp), %ecx
22788 + movl 24(%esp), %edx
22789 + xorl %eax, %ecx
22790 + xorl %ebx, %edx
22791 + movl (%esi), %eax
22792 + movl 4(%esi), %ebx
22793 +.L019dj7:
22794 + rorl $16, %edx
22795 + movb %dl, 6(%edi)
22796 + shrl $16, %edx
22797 +.L020dj6:
22798 + movb %dh, 5(%edi)
22799 +.L021dj5:
22800 + movb %dl, 4(%edi)
22801 +.L022dj4:
22802 + movl %ecx, (%edi)
22803 + jmp .L023djend
22804 +.L024dj3:
22805 + rorl $16, %ecx
22806 + movb %cl, 2(%edi)
22807 + sall $16, %ecx
22808 +.L025dj2:
22809 + movb %ch, 1(%esi)
22810 +.L026dj1:
22811 + movb %cl, (%esi)
22812 +.L023djend:
22813 + jmp .L007finish
22814 +.align 16
22815 +.L007finish:
22816 + movl 64(%esp), %ecx
22817 + addl $28, %esp
22818 + movl %eax, (%ecx)
22819 + movl %ebx, 4(%ecx)
22820 + popl %edi
22821 + popl %esi
22822 + popl %ebx
22823 + popl %ebp
22824 + ret
22825 +.align 16
22826 +.L008cbc_enc_jmp_table:
22827 + .long 0
22828 + .long .L016ej1
22829 + .long .L015ej2
22830 + .long .L014ej3
22831 + .long .L012ej4
22832 + .long .L011ej5
22833 + .long .L010ej6
22834 + .long .L009ej7
22835 +.align 16
22836 +.L027cbc_dec_jmp_table:
22837 + .long 0
22838 + .long .L026dj1
22839 + .long .L025dj2
22840 + .long .L024dj3
22841 + .long .L022dj4
22842 + .long .L021dj5
22843 + .long .L020dj6
22844 + .long .L019dj7
22845 +.des_ncbc_encrypt_end:
22846 + .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
22847 +.ident "desasm.pl"
22848 +.text
22849 + .align 16
22850 +.globl des_ede3_cbc_encrypt
22851 + .type des_ede3_cbc_encrypt , @function
22852 +des_ede3_cbc_encrypt:
22853 +
22854 + pushl %ebp
22855 + pushl %ebx
22856 + pushl %esi
22857 + pushl %edi
22858 + movl 28(%esp), %ebp
22859 +
22860 + movl 44(%esp), %ebx
22861 + movl (%ebx), %esi
22862 + movl 4(%ebx), %edi
22863 + pushl %edi
22864 + pushl %esi
22865 + pushl %edi
22866 + pushl %esi
22867 + movl %esp, %ebx
22868 + movl 36(%esp), %esi
22869 + movl 40(%esp), %edi
22870 +
22871 + movl 64(%esp), %ecx
22872 +
22873 + movl 56(%esp), %eax
22874 + pushl %eax
22875 +
22876 + movl 56(%esp), %eax
22877 + pushl %eax
22878 +
22879 + movl 56(%esp), %eax
22880 + pushl %eax
22881 + pushl %ebx
22882 + cmpl $0, %ecx
22883 + jz .L028decrypt
22884 + andl $4294967288, %ebp
22885 + movl 16(%esp), %eax
22886 + movl 20(%esp), %ebx
22887 + jz .L029encrypt_finish
22888 +.L030encrypt_loop:
22889 + movl (%esi), %ecx
22890 + movl 4(%esi), %edx
22891 + xorl %ecx, %eax
22892 + xorl %edx, %ebx
22893 + movl %eax, 16(%esp)
22894 + movl %ebx, 20(%esp)
22895 + call des_encrypt3
22896 + movl 16(%esp), %eax
22897 + movl 20(%esp), %ebx
22898 + movl %eax, (%edi)
22899 + movl %ebx, 4(%edi)
22900 + addl $8, %esi
22901 + addl $8, %edi
22902 + subl $8, %ebp
22903 + jnz .L030encrypt_loop
22904 +.L029encrypt_finish:
22905 + movl 60(%esp), %ebp
22906 + andl $7, %ebp
22907 + jz .L031finish
22908 + xorl %ecx, %ecx
22909 + xorl %edx, %edx
22910 + movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
22911 + jmp *%ebp
22912 +.L033ej7:
22913 + movb 6(%esi), %dh
22914 + sall $8, %edx
22915 +.L034ej6:
22916 + movb 5(%esi), %dh
22917 +.L035ej5:
22918 + movb 4(%esi), %dl
22919 +.L036ej4:
22920 + movl (%esi), %ecx
22921 + jmp .L037ejend
22922 +.L038ej3:
22923 + movb 2(%esi), %ch
22924 + sall $8, %ecx
22925 +.L039ej2:
22926 + movb 1(%esi), %ch
22927 +.L040ej1:
22928 + movb (%esi), %cl
22929 +.L037ejend:
22930 + xorl %ecx, %eax
22931 + xorl %edx, %ebx
22932 + movl %eax, 16(%esp)
22933 + movl %ebx, 20(%esp)
22934 + call des_encrypt3
22935 + movl 16(%esp), %eax
22936 + movl 20(%esp), %ebx
22937 + movl %eax, (%edi)
22938 + movl %ebx, 4(%edi)
22939 + jmp .L031finish
22940 +.align 16
22941 +.L028decrypt:
22942 + andl $4294967288, %ebp
22943 + movl 24(%esp), %eax
22944 + movl 28(%esp), %ebx
22945 + jz .L041decrypt_finish
22946 +.L042decrypt_loop:
22947 + movl (%esi), %eax
22948 + movl 4(%esi), %ebx
22949 + movl %eax, 16(%esp)
22950 + movl %ebx, 20(%esp)
22951 + call des_decrypt3
22952 + movl 16(%esp), %eax
22953 + movl 20(%esp), %ebx
22954 + movl 24(%esp), %ecx
22955 + movl 28(%esp), %edx
22956 + xorl %eax, %ecx
22957 + xorl %ebx, %edx
22958 + movl (%esi), %eax
22959 + movl 4(%esi), %ebx
22960 + movl %ecx, (%edi)
22961 + movl %edx, 4(%edi)
22962 + movl %eax, 24(%esp)
22963 + movl %ebx, 28(%esp)
22964 + addl $8, %esi
22965 + addl $8, %edi
22966 + subl $8, %ebp
22967 + jnz .L042decrypt_loop
22968 +.L041decrypt_finish:
22969 + movl 60(%esp), %ebp
22970 + andl $7, %ebp
22971 + jz .L031finish
22972 + movl (%esi), %eax
22973 + movl 4(%esi), %ebx
22974 + movl %eax, 16(%esp)
22975 + movl %ebx, 20(%esp)
22976 + call des_decrypt3
22977 + movl 16(%esp), %eax
22978 + movl 20(%esp), %ebx
22979 + movl 24(%esp), %ecx
22980 + movl 28(%esp), %edx
22981 + xorl %eax, %ecx
22982 + xorl %ebx, %edx
22983 + movl (%esi), %eax
22984 + movl 4(%esi), %ebx
22985 +.L043dj7:
22986 + rorl $16, %edx
22987 + movb %dl, 6(%edi)
22988 + shrl $16, %edx
22989 +.L044dj6:
22990 + movb %dh, 5(%edi)
22991 +.L045dj5:
22992 + movb %dl, 4(%edi)
22993 +.L046dj4:
22994 + movl %ecx, (%edi)
22995 + jmp .L047djend
22996 +.L048dj3:
22997 + rorl $16, %ecx
22998 + movb %cl, 2(%edi)
22999 + sall $16, %ecx
23000 +.L049dj2:
23001 + movb %ch, 1(%esi)
23002 +.L050dj1:
23003 + movb %cl, (%esi)
23004 +.L047djend:
23005 + jmp .L031finish
23006 +.align 16
23007 +.L031finish:
23008 + movl 76(%esp), %ecx
23009 + addl $32, %esp
23010 + movl %eax, (%ecx)
23011 + movl %ebx, 4(%ecx)
23012 + popl %edi
23013 + popl %esi
23014 + popl %ebx
23015 + popl %ebp
23016 + ret
23017 +.align 16
23018 +.L032cbc_enc_jmp_table:
23019 + .long 0
23020 + .long .L040ej1
23021 + .long .L039ej2
23022 + .long .L038ej3
23023 + .long .L036ej4
23024 + .long .L035ej5
23025 + .long .L034ej6
23026 + .long .L033ej7
23027 +.align 16
23028 +.L051cbc_dec_jmp_table:
23029 + .long 0
23030 + .long .L050dj1
23031 + .long .L049dj2
23032 + .long .L048dj3
23033 + .long .L046dj4
23034 + .long .L045dj5
23035 + .long .L044dj6
23036 + .long .L043dj7
23037 +.des_ede3_cbc_encrypt_end:
23038 + .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
23039 +.ident "desasm.pl"
23040 --- /dev/null Tue Mar 11 13:02:56 2003
23041 +++ linux/net/ipsec/des/ecb_enc.c Mon Feb 9 13:51:03 2004
23042 @@ -0,0 +1,128 @@
23043 +/* crypto/des/ecb_enc.c */
23044 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
23045 + * All rights reserved.
23046 + *
23047 + * This package is an SSL implementation written
23048 + * by Eric Young (eay@cryptsoft.com).
23049 + * The implementation was written so as to conform with Netscapes SSL.
23050 + *
23051 + * This library is free for commercial and non-commercial use as long as
23052 + * the following conditions are aheared to. The following conditions
23053 + * apply to all code found in this distribution, be it the RC4, RSA,
23054 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
23055 + * included with this distribution is covered by the same copyright terms
23056 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
23057 + *
23058 + * Copyright remains Eric Young's, and as such any Copyright notices in
23059 + * the code are not to be removed.
23060 + * If this package is used in a product, Eric Young should be given attribution
23061 + * as the author of the parts of the library used.
23062 + * This can be in the form of a textual message at program startup or
23063 + * in documentation (online or textual) provided with the package.
23064 + *
23065 + * Redistribution and use in source and binary forms, with or without
23066 + * modification, are permitted provided that the following conditions
23067 + * are met:
23068 + * 1. Redistributions of source code must retain the copyright
23069 + * notice, this list of conditions and the following disclaimer.
23070 + * 2. Redistributions in binary form must reproduce the above copyright
23071 + * notice, this list of conditions and the following disclaimer in the
23072 + * documentation and/or other materials provided with the distribution.
23073 + * 3. All advertising materials mentioning features or use of this software
23074 + * must display the following acknowledgement:
23075 + * "This product includes cryptographic software written by
23076 + * Eric Young (eay@cryptsoft.com)"
23077 + * The word 'cryptographic' can be left out if the rouines from the library
23078 + * being used are not cryptographic related :-).
23079 + * 4. If you include any Windows specific code (or a derivative thereof) from
23080 + * the apps directory (application code) you must include an acknowledgement:
23081 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
23082 + *
23083 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
23084 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23085 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23086 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23087 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23088 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23089 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23090 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23091 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23092 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23093 + * SUCH DAMAGE.
23094 + *
23095 + * The licence and distribution terms for any publically available version or
23096 + * derivative of this code cannot be changed. i.e. this code cannot simply be
23097 + * copied and put under another distribution licence
23098 + * [including the GNU Public Licence.]
23099 + */
23100 +
23101 +#include "des/des_locl.h"
23102 +#include "des/spr.h"
23103 +
23104 +char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
23105 +char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
23106 +
23107 +/* RCSID $Id: ecb_enc.c,v 1.8 2004/08/04 15:57:22 mcr Exp $ */
23108 +/* This function ifdef'ed out for FreeS/WAN project. */
23109 +#ifdef notdef
23110 +char *des_options()
23111 + {
23112 + static int init=1;
23113 + static char buf[32];
23114 +
23115 + if (init)
23116 + {
23117 + char *ptr,*unroll,*risc,*size;
23118 +
23119 + init=0;
23120 +#ifdef DES_PTR
23121 + ptr="ptr";
23122 +#else
23123 + ptr="idx";
23124 +#endif
23125 +#if defined(DES_RISC1) || defined(DES_RISC2)
23126 +#ifdef DES_RISC1
23127 + risc="risc1";
23128 +#endif
23129 +#ifdef DES_RISC2
23130 + risc="risc2";
23131 +#endif
23132 +#else
23133 + risc="cisc";
23134 +#endif
23135 +#ifdef DES_UNROLL
23136 + unroll="16";
23137 +#else
23138 + unroll="4";
23139 +#endif
23140 + if (sizeof(DES_LONG) != sizeof(long))
23141 + size="int";
23142 + else
23143 + size="long";
23144 + sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
23145 + }
23146 + return(buf);
23147 + }
23148 +#endif
23149 +
23150 +
23151 +void des_ecb_encrypt(input, output, ks, enc)
23152 +des_cblock (*input);
23153 +des_cblock (*output);
23154 +des_key_schedule ks;
23155 +int enc;
23156 + {
23157 + register DES_LONG l;
23158 + register unsigned char *in,*out;
23159 + DES_LONG ll[2];
23160 +
23161 + in=(unsigned char *)input;
23162 + out=(unsigned char *)output;
23163 + c2l(in,l); ll[0]=l;
23164 + c2l(in,l); ll[1]=l;
23165 + des_encrypt(ll,ks,enc);
23166 + l=ll[0]; l2c(l,out);
23167 + l=ll[1]; l2c(l,out);
23168 + l=ll[0]=ll[1]=0;
23169 + }
23170 +
23171 --- /dev/null Tue Mar 11 13:02:56 2003
23172 +++ linux/net/ipsec/des/ipsec_alg_3des.c Mon Feb 9 13:51:03 2004
23173 @@ -0,0 +1,181 @@
23174 +/*
23175 + * ipsec_alg 3DES cipher stubs
23176 + *
23177 + * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
23178 + *
23179 + * Adapted from ipsec_alg_aes.c by JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
23180 + *
23181 + * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
23182 + *
23183 + * This program is free software; you can redistribute it and/or modify it
23184 + * under the terms of the GNU General Public License as published by the
23185 + * Free Software Foundation; either version 2 of the License, or (at your
23186 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
23187 + *
23188 + * This program is distributed in the hope that it will be useful, but
23189 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23190 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23191 + * for more details.
23192 + *
23193 + */
23194 +#ifndef AUTOCONF_INCLUDED
23195 +#include <linux/config.h>
23196 +#endif
23197 +#include <linux/version.h>
23198 +
23199 +/*
23200 + * special case: ipsec core modular with this static algo inside:
23201 + * must avoid MODULE magic for this file
23202 + */
23203 +#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_3DES)
23204 +#undef MODULE
23205 +#endif
23206 +
23207 +#include <linux/module.h>
23208 +#include <linux/init.h>
23209 +
23210 +#include <linux/kernel.h> /* printk() */
23211 +#include <linux/errno.h> /* error codes */
23212 +#include <linux/types.h> /* size_t */
23213 +#include <linux/string.h>
23214 +
23215 +/* Low freeswan header coupling */
23216 +#include "openswan/ipsec_xform.h"
23217 +#include "openswan/ipsec_alg.h"
23218 +#include "crypto/des.h"
23219 +#include "openswan/ipsec_alg_3des.h"
23220 +
23221 +#define AES_CONTEXT_T aes_context
23222 +static int debug_3des=0;
23223 +static int test_3des=0;
23224 +static int excl_3des=0;
23225 +
23226 +#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23227 +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
23228 +#ifdef module_param
23229 +module_param(debug_3des,int,0600)
23230 +module_param(test_des,int,0600)
23231 +module_param(excl_des,int,0600)
23232 +#else
23233 +MODULE_PARM(debug_3des, "i");
23234 +MODULE_PARM(test_des, "i");
23235 +MODULE_PARM(excl_des, "i");
23236 +#endif
23237 +#endif
23238 +
23239 +#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
23240 +#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
23241 +
23242 +static int _3des_set_key(struct ipsec_alg_enc *alg,
23243 + __u8 * key_e, const __u8 * key,
23244 + size_t keysize)
23245 +{
23246 + int ret = 0;
23247 + TripleDES_context *ctx = (TripleDES_context*)key_e;
23248 +
23249 + if(keysize != 192/8) {
23250 + return EINVAL;
23251 + }
23252 +
23253 + des_set_key((des_cblock *)(key + DES_KEY_SZ*0), ctx->s1);
23254 + des_set_key((des_cblock *)(key + DES_KEY_SZ*1), ctx->s2);
23255 + des_set_key((des_cblock *)(key + DES_KEY_SZ*2), ctx->s3);
23256 +
23257 + if (debug_3des > 0)
23258 + printk(KERN_DEBUG "klips_debug:_3des_set_key:"
23259 + "ret=%d key_e=%p key=%p keysize=%ld\n",
23260 + ret, key_e, key, (unsigned long int) keysize);
23261 + return ret;
23262 +}
23263 +
23264 +static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg,
23265 + __u8 * key_e,
23266 + __u8 * in,
23267 + int ilen, const __u8 * iv,
23268 + int encrypt)
23269 +{
23270 + TripleDES_context *ctx=(TripleDES_context*)key_e;
23271 + des_cblock miv;
23272 +
23273 + memcpy(&miv, iv, sizeof(miv));
23274 +
23275 + if (debug_3des > 0)
23276 + printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
23277 + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
23278 + key_e, in, ilen, iv, encrypt);
23279 +
23280 + des_ede3_cbc_encrypt((des_cblock *)in,
23281 + (des_cblock *)in,
23282 + ilen,
23283 + ctx->s1,
23284 + ctx->s2,
23285 + ctx->s3,
23286 + &miv, encrypt);
23287 + return 1;
23288 +}
23289 +
23290 +static struct ipsec_alg_enc ipsec_alg_3DES = {
23291 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
23292 + ixt_refcnt: ATOMIC_INIT(0),
23293 + ixt_name: "3des",
23294 + ixt_blocksize: ESP_3DES_CBC_BLK_LEN,
23295 + ixt_support: {
23296 + ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
23297 + ias_id: ESP_3DES,
23298 + ias_keyminbits: ESP_3DES_KEY_SZ*8,
23299 + ias_keymaxbits: ESP_3DES_KEY_SZ*8,
23300 + },
23301 + },
23302 +#if defined(MODULE_KLIPS_ENC_3DES_MODULE)
23303 + ixt_module: THIS_MODULE,
23304 +#endif
23305 + ixt_e_keylen: ESP_3DES_KEY_SZ*8,
23306 + ixt_e_ctx_size: sizeof(TripleDES_context),
23307 + ixt_e_set_key: _3des_set_key,
23308 + ixt_e_cbc_encrypt:_3des_cbc_encrypt,
23309 +};
23310 +
23311 +#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23312 +IPSEC_ALG_MODULE_INIT_MOD( ipsec_3des_init )
23313 +#else
23314 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_3des_init )
23315 +#endif
23316 +{
23317 + int ret, test_ret;
23318 +
23319 + if (excl_3des) ipsec_alg_3DES.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
23320 + ret=register_ipsec_alg_enc(&ipsec_alg_3DES);
23321 + printk("ipsec_3des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
23322 + ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23323 + ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23324 + ipsec_alg_3DES.ixt_common.ixt_name,
23325 + ret);
23326 + if (ret==0 && test_3des) {
23327 + test_ret=ipsec_alg_test(
23328 + ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23329 + ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23330 + test_3des);
23331 + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
23332 + ipsec_alg_3DES.ixt_common.ixt_support.ias_exttype,
23333 + ipsec_alg_3DES.ixt_common.ixt_support.ias_id,
23334 + test_ret);
23335 + }
23336 + return ret;
23337 +}
23338 +
23339 +#if defined(CONFIG_KLIPS_ENC_3DES_MODULE)
23340 +IPSEC_ALG_MODULE_EXIT_MOD( ipsec_3des_fini )
23341 +#else
23342 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_3des_fini )
23343 +#endif
23344 +{
23345 + unregister_ipsec_alg_enc(&ipsec_alg_3DES);
23346 + return;
23347 +}
23348 +
23349 +/* Dual, because 3des code is 4-clause BSD licensed */
23350 +#ifdef MODULE_LICENSE
23351 +MODULE_LICENSE("Dual BSD/GPL");
23352 +#endif
23353 +
23354 +
23355 --- /dev/null Tue Mar 11 13:02:56 2003
23356 +++ linux/net/ipsec/des/set_key.c Mon Feb 9 13:51:03 2004
23357 @@ -0,0 +1,246 @@
23358 +/* crypto/des/set_key.c */
23359 +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
23360 + * All rights reserved.
23361 + *
23362 + * This package is an SSL implementation written
23363 + * by Eric Young (eay@cryptsoft.com).
23364 + * The implementation was written so as to conform with Netscapes SSL.
23365 + *
23366 + * This library is free for commercial and non-commercial use as long as
23367 + * the following conditions are aheared to. The following conditions
23368 + * apply to all code found in this distribution, be it the RC4, RSA,
23369 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
23370 + * included with this distribution is covered by the same copyright terms
23371 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
23372 + *
23373 + * Copyright remains Eric Young's, and as such any Copyright notices in
23374 + * the code are not to be removed.
23375 + * If this package is used in a product, Eric Young should be given attribution
23376 + * as the author of the parts of the library used.
23377 + * This can be in the form of a textual message at program startup or
23378 + * in documentation (online or textual) provided with the package.
23379 + *
23380 + * Redistribution and use in source and binary forms, with or without
23381 + * modification, are permitted provided that the following conditions
23382 + * are met:
23383 + * 1. Redistributions of source code must retain the copyright
23384 + * notice, this list of conditions and the following disclaimer.
23385 + * 2. Redistributions in binary form must reproduce the above copyright
23386 + * notice, this list of conditions and the following disclaimer in the
23387 + * documentation and/or other materials provided with the distribution.
23388 + * 3. All advertising materials mentioning features or use of this software
23389 + * must display the following acknowledgement:
23390 + * "This product includes cryptographic software written by
23391 + * Eric Young (eay@cryptsoft.com)"
23392 + * The word 'cryptographic' can be left out if the rouines from the library
23393 + * being used are not cryptographic related :-).
23394 + * 4. If you include any Windows specific code (or a derivative thereof) from
23395 + * the apps directory (application code) you must include an acknowledgement:
23396 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
23397 + *
23398 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
23399 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23400 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23401 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23402 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23403 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23404 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23405 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23406 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23407 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23408 + * SUCH DAMAGE.
23409 + *
23410 + * The licence and distribution terms for any publically available version or
23411 + * derivative of this code cannot be changed. i.e. this code cannot simply be
23412 + * copied and put under another distribution licence
23413 + * [including the GNU Public Licence.]
23414 + */
23415 +
23416 +/* set_key.c v 1.4 eay 24/9/91
23417 + * 1.4 Speed up by 400% :-)
23418 + * 1.3 added register declarations.
23419 + * 1.2 unrolled make_key_sched a bit more
23420 + * 1.1 added norm_expand_bits
23421 + * 1.0 First working version
23422 + */
23423 +#include "des/des_locl.h"
23424 +#include "des/podd.h"
23425 +#include "des/sk.h"
23426 +
23427 +#ifndef NOPROTO
23428 +static int check_parity(des_cblock (*key));
23429 +#else
23430 +static int check_parity();
23431 +#endif
23432 +
23433 +int des_check_key=0;
23434 +
23435 +void des_set_odd_parity(key)
23436 +des_cblock (*key);
23437 + {
23438 + int i;
23439 +
23440 + for (i=0; i<DES_KEY_SZ; i++)
23441 + (*key)[i]=odd_parity[(*key)[i]];
23442 + }
23443 +
23444 +static int check_parity(key)
23445 +des_cblock (*key);
23446 + {
23447 + int i;
23448 +
23449 + for (i=0; i<DES_KEY_SZ; i++)
23450 + {
23451 + if ((*key)[i] != odd_parity[(*key)[i]])
23452 + return(0);
23453 + }
23454 + return(1);
23455 + }
23456 +
23457 +/* Weak and semi week keys as take from
23458 + * %A D.W. Davies
23459 + * %A W.L. Price
23460 + * %T Security for Computer Networks
23461 + * %I John Wiley & Sons
23462 + * %D 1984
23463 + * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
23464 + * (and actual cblock values).
23465 + */
23466 +#define NUM_WEAK_KEY 16
23467 +static des_cblock weak_keys[NUM_WEAK_KEY]={
23468 + /* weak keys */
23469 + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
23470 + {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
23471 + {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
23472 + {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
23473 + /* semi-weak keys */
23474 + {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
23475 + {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
23476 + {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
23477 + {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
23478 + {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
23479 + {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
23480 + {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
23481 + {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
23482 + {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
23483 + {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
23484 + {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
23485 + {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
23486 +
23487 +int des_is_weak_key(key)
23488 +des_cblock (*key);
23489 + {
23490 + int i;
23491 +
23492 + for (i=0; i<NUM_WEAK_KEY; i++)
23493 + /* Added == 0 to comparision, I obviously don't run
23494 + * this section very often :-(, thanks to
23495 + * engineering@MorningStar.Com for the fix
23496 + * eay 93/06/29
23497 + * Another problem, I was comparing only the first 4
23498 + * bytes, 97/03/18 */
23499 + if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
23500 + return(0);
23501 + }
23502 +
23503 +/* NOW DEFINED IN des_local.h
23504 + * See ecb_encrypt.c for a pseudo description of these macros.
23505 + * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
23506 + * (b)^=(t),\
23507 + * (a)=((a)^((t)<<(n))))
23508 + */
23509 +
23510 +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
23511 + (a)=(a)^(t)^(t>>(16-(n))))
23512 +
23513 +/* return 0 if key parity is odd (correct),
23514 + * return -1 if key parity error,
23515 + * return -2 if illegal weak key.
23516 + */
23517 +int des_set_key(key, schedule)
23518 +des_cblock (*key);
23519 +des_key_schedule schedule;
23520 + {
23521 + static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
23522 + register DES_LONG c,d,t,s,t2;
23523 + register unsigned char *in;
23524 + register DES_LONG *k;
23525 + register int i;
23526 +
23527 + if (des_check_key)
23528 + {
23529 + if (!check_parity(key))
23530 + return(-1);
23531 +
23532 + if (des_is_weak_key(key))
23533 + return(-2);
23534 + }
23535 +
23536 + k=(DES_LONG *)schedule;
23537 + in=(unsigned char *)key;
23538 +
23539 + c2l(in,c);
23540 + c2l(in,d);
23541 +
23542 + /* do PC1 in 60 simple operations */
23543 +/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
23544 + HPERM_OP(c,t,-2, 0xcccc0000L);
23545 + HPERM_OP(c,t,-1, 0xaaaa0000L);
23546 + HPERM_OP(c,t, 8, 0x00ff0000L);
23547 + HPERM_OP(c,t,-1, 0xaaaa0000L);
23548 + HPERM_OP(d,t,-8, 0xff000000L);
23549 + HPERM_OP(d,t, 8, 0x00ff0000L);
23550 + HPERM_OP(d,t, 2, 0x33330000L);
23551 + d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
23552 + d=(d>>8)|((c&0xf0000000L)>>4);
23553 + c&=0x0fffffffL; */
23554 +
23555 + /* I now do it in 47 simple operations :-)
23556 + * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
23557 + * for the inspiration. :-) */
23558 + PERM_OP (d,c,t,4,0x0f0f0f0fL);
23559 + HPERM_OP(c,t,-2,0xcccc0000L);
23560 + HPERM_OP(d,t,-2,0xcccc0000L);
23561 + PERM_OP (d,c,t,1,0x55555555L);
23562 + PERM_OP (c,d,t,8,0x00ff00ffL);
23563 + PERM_OP (d,c,t,1,0x55555555L);
23564 + d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
23565 + ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
23566 + c&=0x0fffffffL;
23567 +
23568 + for (i=0; i<ITERATIONS; i++)
23569 + {
23570 + if (shifts2[i])
23571 + { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
23572 + else
23573 + { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
23574 + c&=0x0fffffffL;
23575 + d&=0x0fffffffL;
23576 + /* could be a few less shifts but I am to lazy at this
23577 + * point in time to investigate */
23578 + s= des_skb[0][ (c )&0x3f ]|
23579 + des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
23580 + des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
23581 + des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
23582 + ((c>>22L)&0x38)];
23583 + t= des_skb[4][ (d )&0x3f ]|
23584 + des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
23585 + des_skb[6][ (d>>15L)&0x3f ]|
23586 + des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
23587 +
23588 + /* table contained 0213 4657 */
23589 + t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
23590 + *(k++)=ROTATE(t2,30)&0xffffffffL;
23591 +
23592 + t2=((s>>16L)|(t&0xffff0000L));
23593 + *(k++)=ROTATE(t2,26)&0xffffffffL;
23594 + }
23595 + return(0);
23596 + }
23597 +
23598 +int des_key_sched(key, schedule)
23599 +des_cblock (*key);
23600 +des_key_schedule schedule;
23601 + {
23602 + return(des_set_key(key,schedule));
23603 + }
23604 --- /dev/null Tue Mar 11 13:02:56 2003
23605 +++ linux/net/ipsec/goodmask.c Mon Feb 9 13:51:03 2004
23606 @@ -0,0 +1,100 @@
23607 +/*
23608 + * minor utilities for subnet-mask manipulation
23609 + * Copyright (C) 1998, 1999 Henry Spencer.
23610 + *
23611 + * This library is free software; you can redistribute it and/or modify it
23612 + * under the terms of the GNU Library General Public License as published by
23613 + * the Free Software Foundation; either version 2 of the License, or (at your
23614 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
23615 + *
23616 + * This library is distributed in the hope that it will be useful, but
23617 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23618 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
23619 + * License for more details.
23620 + *
23621 + * RCSID $Id: goodmask.c,v 1.12 2004/07/10 07:43:47 mcr Exp $
23622 + */
23623 +#include "openswan.h"
23624 +
23625 +#ifndef ABITS
23626 +#define ABITS 32 /* bits in an IPv4 address */
23627 +#endif
23628 +
23629 +/*
23630 + - goodmask - is this a good (^1*0*$) subnet mask?
23631 + * You are not expected to understand this. See Henry S. Warren Jr,
23632 + * "Functions realizable with word-parallel logical and two's-complement
23633 + * addition instructions", CACM 20.6 (June 1977), p.439.
23634 + */
23635 +int /* predicate */
23636 +goodmask(mask)
23637 +struct in_addr mask;
23638 +{
23639 + unsigned long x = ntohl(mask.s_addr);
23640 + /* clear rightmost contiguous string of 1-bits */
23641 +# define CRCS1B(x) (((x|(x-1))+1)&x)
23642 +# define TOPBIT (1UL << 31)
23643 +
23644 + /* either zero, or has one string of 1-bits which is left-justified */
23645 + if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
23646 + return 1;
23647 + return 0;
23648 +}
23649 +
23650 +/*
23651 + - masktobits - how many bits in this mask?
23652 + * The algorithm is essentially a binary search, but highly optimized
23653 + * for this particular task.
23654 + */
23655 +int /* -1 means !goodmask() */
23656 +masktobits(mask)
23657 +struct in_addr mask;
23658 +{
23659 + unsigned long m = ntohl(mask.s_addr);
23660 + int masklen;
23661 +
23662 + if (!goodmask(mask))
23663 + return -1;
23664 +
23665 + if (m&0x00000001UL)
23666 + return 32;
23667 + masklen = 0;
23668 + if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
23669 + masklen |= 0x10;
23670 + m <<= 16;
23671 + }
23672 + if (m&(0x00ff0000UL<<1)) {
23673 + masklen |= 0x08;
23674 + m <<= 8;
23675 + }
23676 + if (m&(0x0f000000UL<<1)) {
23677 + masklen |= 0x04;
23678 + m <<= 4;
23679 + }
23680 + if (m&(0x30000000UL<<1)) {
23681 + masklen |= 0x02;
23682 + m <<= 2;
23683 + }
23684 + if (m&(0x40000000UL<<1))
23685 + masklen |= 0x01;
23686 +
23687 + return masklen;
23688 +}
23689 +
23690 +/*
23691 + - bitstomask - return a mask with this many high bits on
23692 + */
23693 +struct in_addr
23694 +bitstomask(n)
23695 +int n;
23696 +{
23697 + struct in_addr result;
23698 +
23699 + if (n > 0 && n <= ABITS)
23700 + result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
23701 + else if (n == 0)
23702 + result.s_addr = 0;
23703 + else
23704 + result.s_addr = 0; /* best error report we can do */
23705 + return result;
23706 +}
23707 --- /dev/null Tue Mar 11 13:02:56 2003
23708 +++ linux/net/ipsec/infblock.c Mon Feb 9 13:51:03 2004
23709 @@ -0,0 +1,403 @@
23710 +/* infblock.c -- interpret and process block types to last block
23711 + * Copyright (C) 1995-2002 Mark Adler
23712 + * For conditions of distribution and use, see copyright notice in zlib.h
23713 + */
23714 +
23715 +#include <zlib/zutil.h>
23716 +#include "infblock.h"
23717 +#include "inftrees.h"
23718 +#include "infcodes.h"
23719 +#include "infutil.h"
23720 +
23721 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
23722 +
23723 +/* simplify the use of the inflate_huft type with some defines */
23724 +#define exop word.what.Exop
23725 +#define bits word.what.Bits
23726 +
23727 +/* Table for deflate from PKZIP's appnote.txt. */
23728 +local const uInt border[] = { /* Order of the bit length code lengths */
23729 + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
23730 +
23731 +/*
23732 + Notes beyond the 1.93a appnote.txt:
23733 +
23734 + 1. Distance pointers never point before the beginning of the output
23735 + stream.
23736 + 2. Distance pointers can point back across blocks, up to 32k away.
23737 + 3. There is an implied maximum of 7 bits for the bit length table and
23738 + 15 bits for the actual data.
23739 + 4. If only one code exists, then it is encoded using one bit. (Zero
23740 + would be more efficient, but perhaps a little confusing.) If two
23741 + codes exist, they are coded using one bit each (0 and 1).
23742 + 5. There is no way of sending zero distance codes--a dummy must be
23743 + sent if there are none. (History: a pre 2.0 version of PKZIP would
23744 + store blocks with no distance codes, but this was discovered to be
23745 + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
23746 + zero distance codes, which is sent as one code of zero bits in
23747 + length.
23748 + 6. There are up to 286 literal/length codes. Code 256 represents the
23749 + end-of-block. Note however that the static length tree defines
23750 + 288 codes just to fill out the Huffman codes. Codes 286 and 287
23751 + cannot be used though, since there is no length base or extra bits
23752 + defined for them. Similarily, there are up to 30 distance codes.
23753 + However, static trees define 32 codes (all 5 bits) to fill out the
23754 + Huffman codes, but the last two had better not show up in the data.
23755 + 7. Unzip can check dynamic Huffman blocks for complete code sets.
23756 + The exception is that a single code would not be complete (see #4).
23757 + 8. The five bits following the block type is really the number of
23758 + literal codes sent minus 257.
23759 + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
23760 + (1+6+6). Therefore, to output three times the length, you output
23761 + three codes (1+1+1), whereas to output four times the same length,
23762 + you only need two codes (1+3). Hmm.
23763 + 10. In the tree reconstruction algorithm, Code = Code + Increment
23764 + only if BitLength(i) is not zero. (Pretty obvious.)
23765 + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
23766 + 12. Note: length code 284 can represent 227-258, but length code 285
23767 + really is 258. The last length deserves its own, short code
23768 + since it gets used a lot in very redundant files. The length
23769 + 258 is special since 258 - 3 (the min match length) is 255.
23770 + 13. The literal/length and distance code bit lengths are read as a
23771 + single stream of lengths. It is possible (and advantageous) for
23772 + a repeat code (16, 17, or 18) to go across the boundary between
23773 + the two sets of lengths.
23774 + */
23775 +
23776 +
23777 +void inflate_blocks_reset(s, z, c)
23778 +inflate_blocks_statef *s;
23779 +z_streamp z;
23780 +uLongf *c;
23781 +{
23782 + if (c != Z_NULL)
23783 + *c = s->check;
23784 + if (s->mode == BTREE || s->mode == DTREE)
23785 + ZFREE(z, s->sub.trees.blens);
23786 + if (s->mode == CODES)
23787 + inflate_codes_free(s->sub.decode.codes, z);
23788 + s->mode = TYPE;
23789 + s->bitk = 0;
23790 + s->bitb = 0;
23791 + s->read = s->write = s->window;
23792 + if (s->checkfn != Z_NULL)
23793 + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
23794 + Tracev((stderr, "inflate: blocks reset\n"));
23795 +}
23796 +
23797 +
23798 +inflate_blocks_statef *inflate_blocks_new(z, c, w)
23799 +z_streamp z;
23800 +check_func c;
23801 +uInt w;
23802 +{
23803 + inflate_blocks_statef *s;
23804 +
23805 + if ((s = (inflate_blocks_statef *)ZALLOC
23806 + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
23807 + return s;
23808 + if ((s->hufts =
23809 + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
23810 + {
23811 + ZFREE(z, s);
23812 + return Z_NULL;
23813 + }
23814 + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
23815 + {
23816 + ZFREE(z, s->hufts);
23817 + ZFREE(z, s);
23818 + return Z_NULL;
23819 + }
23820 + s->end = s->window + w;
23821 + s->checkfn = c;
23822 + s->mode = TYPE;
23823 + Tracev((stderr, "inflate: blocks allocated\n"));
23824 + inflate_blocks_reset(s, z, Z_NULL);
23825 + return s;
23826 +}
23827 +
23828 +
23829 +int inflate_blocks(s, z, r)
23830 +inflate_blocks_statef *s;
23831 +z_streamp z;
23832 +int r;
23833 +{
23834 + uInt t; /* temporary storage */
23835 + uLong b; /* bit buffer */
23836 + uInt k; /* bits in bit buffer */
23837 + Bytef *p; /* input data pointer */
23838 + uInt n; /* bytes available there */
23839 + Bytef *q; /* output window write pointer */
23840 + uInt m; /* bytes to end of window or read pointer */
23841 +
23842 + /* copy input/output information to locals (UPDATE macro restores) */
23843 + LOAD
23844 +
23845 + /* process input based on current state */
23846 + while (1) switch (s->mode)
23847 + {
23848 + case TYPE:
23849 + NEEDBITS(3)
23850 + t = (uInt)b & 7;
23851 + s->last = t & 1;
23852 + switch (t >> 1)
23853 + {
23854 + case 0: /* stored */
23855 + Tracev((stderr, "inflate: stored block%s\n",
23856 + s->last ? " (last)" : ""));
23857 + DUMPBITS(3)
23858 + t = k & 7; /* go to byte boundary */
23859 + DUMPBITS(t)
23860 + s->mode = LENS; /* get length of stored block */
23861 + break;
23862 + case 1: /* fixed */
23863 + Tracev((stderr, "inflate: fixed codes block%s\n",
23864 + s->last ? " (last)" : ""));
23865 + {
23866 + uInt bl, bd;
23867 + inflate_huft *tl, *td;
23868 +
23869 + inflate_trees_fixed(&bl, &bd, &tl, &td, z);
23870 + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
23871 + if (s->sub.decode.codes == Z_NULL)
23872 + {
23873 + r = Z_MEM_ERROR;
23874 + LEAVE
23875 + }
23876 + }
23877 + DUMPBITS(3)
23878 + s->mode = CODES;
23879 + break;
23880 + case 2: /* dynamic */
23881 + Tracev((stderr, "inflate: dynamic codes block%s\n",
23882 + s->last ? " (last)" : ""));
23883 + DUMPBITS(3)
23884 + s->mode = TABLE;
23885 + break;
23886 + case 3: /* illegal */
23887 + DUMPBITS(3)
23888 + s->mode = BAD;
23889 + z->msg = (char*)"invalid block type";
23890 + r = Z_DATA_ERROR;
23891 + LEAVE
23892 + }
23893 + break;
23894 + case LENS:
23895 + NEEDBITS(32)
23896 + if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
23897 + {
23898 + s->mode = BAD;
23899 + z->msg = (char*)"invalid stored block lengths";
23900 + r = Z_DATA_ERROR;
23901 + LEAVE
23902 + }
23903 + s->sub.left = (uInt)b & 0xffff;
23904 + b = k = 0; /* dump bits */
23905 + Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
23906 + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
23907 + break;
23908 + case STORED:
23909 + if (n == 0)
23910 + LEAVE
23911 + NEEDOUT
23912 + t = s->sub.left;
23913 + if (t > n) t = n;
23914 + if (t > m) t = m;
23915 + zmemcpy(q, p, t);
23916 + p += t; n -= t;
23917 + q += t; m -= t;
23918 + if ((s->sub.left -= t) != 0)
23919 + break;
23920 + Tracev((stderr, "inflate: stored end, %lu total out\n",
23921 + z->total_out + (q >= s->read ? q - s->read :
23922 + (s->end - s->read) + (q - s->window))));
23923 + s->mode = s->last ? DRY : TYPE;
23924 + break;
23925 + case TABLE:
23926 + NEEDBITS(14)
23927 + s->sub.trees.table = t = (uInt)b & 0x3fff;
23928 +#ifndef PKZIP_BUG_WORKAROUND
23929 + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
23930 + {
23931 + s->mode = BAD;
23932 + z->msg = (char*)"too many length or distance symbols";
23933 + r = Z_DATA_ERROR;
23934 + LEAVE
23935 + }
23936 +#endif
23937 + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
23938 + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
23939 + {
23940 + r = Z_MEM_ERROR;
23941 + LEAVE
23942 + }
23943 + DUMPBITS(14)
23944 + s->sub.trees.index = 0;
23945 + Tracev((stderr, "inflate: table sizes ok\n"));
23946 + s->mode = BTREE;
23947 + case BTREE:
23948 + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
23949 + {
23950 + NEEDBITS(3)
23951 + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
23952 + DUMPBITS(3)
23953 + }
23954 + while (s->sub.trees.index < 19)
23955 + s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
23956 + s->sub.trees.bb = 7;
23957 + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
23958 + &s->sub.trees.tb, s->hufts, z);
23959 + if (t != Z_OK)
23960 + {
23961 + r = t;
23962 + if (r == Z_DATA_ERROR)
23963 + {
23964 + ZFREE(z, s->sub.trees.blens);
23965 + s->mode = BAD;
23966 + }
23967 + LEAVE
23968 + }
23969 + s->sub.trees.index = 0;
23970 + Tracev((stderr, "inflate: bits tree ok\n"));
23971 + s->mode = DTREE;
23972 + case DTREE:
23973 + while (t = s->sub.trees.table,
23974 + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
23975 + {
23976 + inflate_huft *h;
23977 + uInt i, j, c;
23978 +
23979 + t = s->sub.trees.bb;
23980 + NEEDBITS(t)
23981 + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
23982 + t = h->bits;
23983 + c = h->base;
23984 + if (c < 16)
23985 + {
23986 + DUMPBITS(t)
23987 + s->sub.trees.blens[s->sub.trees.index++] = c;
23988 + }
23989 + else /* c == 16..18 */
23990 + {
23991 + i = c == 18 ? 7 : c - 14;
23992 + j = c == 18 ? 11 : 3;
23993 + NEEDBITS(t + i)
23994 + DUMPBITS(t)
23995 + j += (uInt)b & inflate_mask[i];
23996 + DUMPBITS(i)
23997 + i = s->sub.trees.index;
23998 + t = s->sub.trees.table;
23999 + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
24000 + (c == 16 && i < 1))
24001 + {
24002 + ZFREE(z, s->sub.trees.blens);
24003 + s->mode = BAD;
24004 + z->msg = (char*)"invalid bit length repeat";
24005 + r = Z_DATA_ERROR;
24006 + LEAVE
24007 + }
24008 + c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
24009 + do {
24010 + s->sub.trees.blens[i++] = c;
24011 + } while (--j);
24012 + s->sub.trees.index = i;
24013 + }
24014 + }
24015 + s->sub.trees.tb = Z_NULL;
24016 + {
24017 + uInt bl, bd;
24018 + inflate_huft *tl, *td;
24019 + inflate_codes_statef *c;
24020 +
24021 + bl = 9; /* must be <= 9 for lookahead assumptions */
24022 + bd = 6; /* must be <= 9 for lookahead assumptions */
24023 + t = s->sub.trees.table;
24024 + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
24025 + s->sub.trees.blens, &bl, &bd, &tl, &td,
24026 + s->hufts, z);
24027 + if (t != Z_OK)
24028 + {
24029 + if (t == (uInt)Z_DATA_ERROR)
24030 + {
24031 + ZFREE(z, s->sub.trees.blens);
24032 + s->mode = BAD;
24033 + }
24034 + r = t;
24035 + LEAVE
24036 + }
24037 + Tracev((stderr, "inflate: trees ok\n"));
24038 + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
24039 + {
24040 + r = Z_MEM_ERROR;
24041 + LEAVE
24042 + }
24043 + s->sub.decode.codes = c;
24044 + }
24045 + ZFREE(z, s->sub.trees.blens);
24046 + s->mode = CODES;
24047 + case CODES:
24048 + UPDATE
24049 + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
24050 + return inflate_flush(s, z, r);
24051 + r = Z_OK;
24052 + inflate_codes_free(s->sub.decode.codes, z);
24053 + LOAD
24054 + Tracev((stderr, "inflate: codes end, %lu total out\n",
24055 + z->total_out + (q >= s->read ? q - s->read :
24056 + (s->end - s->read) + (q - s->window))));
24057 + if (!s->last)
24058 + {
24059 + s->mode = TYPE;
24060 + break;
24061 + }
24062 + s->mode = DRY;
24063 + case DRY:
24064 + FLUSH
24065 + if (s->read != s->write)
24066 + LEAVE
24067 + s->mode = DONE;
24068 + case DONE:
24069 + r = Z_STREAM_END;
24070 + LEAVE
24071 + case BAD:
24072 + r = Z_DATA_ERROR;
24073 + LEAVE
24074 + default:
24075 + r = Z_STREAM_ERROR;
24076 + LEAVE
24077 + }
24078 +}
24079 +
24080 +
24081 +int inflate_blocks_free(s, z)
24082 +inflate_blocks_statef *s;
24083 +z_streamp z;
24084 +{
24085 + inflate_blocks_reset(s, z, Z_NULL);
24086 + ZFREE(z, s->window);
24087 + ZFREE(z, s->hufts);
24088 + ZFREE(z, s);
24089 + Tracev((stderr, "inflate: blocks freed\n"));
24090 + return Z_OK;
24091 +}
24092 +
24093 +
24094 +void inflate_set_dictionary(s, d, n)
24095 +inflate_blocks_statef *s;
24096 +const Bytef *d;
24097 +uInt n;
24098 +{
24099 + zmemcpy(s->window, d, n);
24100 + s->read = s->write = s->window + n;
24101 +}
24102 +
24103 +
24104 +/* Returns true if inflate is currently at the end of a block generated
24105 + * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
24106 + * IN assertion: s != Z_NULL
24107 + */
24108 +int inflate_blocks_sync_point(s)
24109 +inflate_blocks_statef *s;
24110 +{
24111 + return s->mode == LENS;
24112 +}
24113 --- /dev/null Tue Mar 11 13:02:56 2003
24114 +++ linux/net/ipsec/infblock.h Mon Feb 9 13:51:03 2004
24115 @@ -0,0 +1,39 @@
24116 +/* infblock.h -- header to use infblock.c
24117 + * Copyright (C) 1995-2002 Mark Adler
24118 + * For conditions of distribution and use, see copyright notice in zlib.h
24119 + */
24120 +
24121 +/* WARNING: this file should *not* be used by applications. It is
24122 + part of the implementation of the compression library and is
24123 + subject to change. Applications should only use zlib.h.
24124 + */
24125 +
24126 +struct inflate_blocks_state;
24127 +typedef struct inflate_blocks_state FAR inflate_blocks_statef;
24128 +
24129 +extern inflate_blocks_statef * inflate_blocks_new OF((
24130 + z_streamp z,
24131 + check_func c, /* check function */
24132 + uInt w)); /* window size */
24133 +
24134 +extern int inflate_blocks OF((
24135 + inflate_blocks_statef *,
24136 + z_streamp ,
24137 + int)); /* initial return code */
24138 +
24139 +extern void inflate_blocks_reset OF((
24140 + inflate_blocks_statef *,
24141 + z_streamp ,
24142 + uLongf *)); /* check value on output */
24143 +
24144 +extern int inflate_blocks_free OF((
24145 + inflate_blocks_statef *,
24146 + z_streamp));
24147 +
24148 +extern void inflate_set_dictionary OF((
24149 + inflate_blocks_statef *s,
24150 + const Bytef *d, /* dictionary */
24151 + uInt n)); /* dictionary length */
24152 +
24153 +extern int inflate_blocks_sync_point OF((
24154 + inflate_blocks_statef *s));
24155 --- /dev/null Tue Mar 11 13:02:56 2003
24156 +++ linux/net/ipsec/infcodes.c Mon Feb 9 13:51:03 2004
24157 @@ -0,0 +1,251 @@
24158 +/* infcodes.c -- process literals and length/distance pairs
24159 + * Copyright (C) 1995-2002 Mark Adler
24160 + * For conditions of distribution and use, see copyright notice in zlib.h
24161 + */
24162 +
24163 +#include <zlib/zutil.h>
24164 +#include "inftrees.h"
24165 +#include "infblock.h"
24166 +#include "infcodes.h"
24167 +#include "infutil.h"
24168 +#include "inffast.h"
24169 +
24170 +/* simplify the use of the inflate_huft type with some defines */
24171 +#define exop word.what.Exop
24172 +#define bits word.what.Bits
24173 +
24174 +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
24175 + START, /* x: set up for LEN */
24176 + LEN, /* i: get length/literal/eob next */
24177 + LENEXT, /* i: getting length extra (have base) */
24178 + DIST, /* i: get distance next */
24179 + DISTEXT, /* i: getting distance extra */
24180 + COPY, /* o: copying bytes in window, waiting for space */
24181 + LIT, /* o: got literal, waiting for output space */
24182 + WASH, /* o: got eob, possibly still output waiting */
24183 + END, /* x: got eob and all data flushed */
24184 + BADCODE} /* x: got error */
24185 +inflate_codes_mode;
24186 +
24187 +/* inflate codes private state */
24188 +struct inflate_codes_state {
24189 +
24190 + /* mode */
24191 + inflate_codes_mode mode; /* current inflate_codes mode */
24192 +
24193 + /* mode dependent information */
24194 + uInt len;
24195 + union {
24196 + struct {
24197 + inflate_huft *tree; /* pointer into tree */
24198 + uInt need; /* bits needed */
24199 + } code; /* if LEN or DIST, where in tree */
24200 + uInt lit; /* if LIT, literal */
24201 + struct {
24202 + uInt get; /* bits to get for extra */
24203 + uInt dist; /* distance back to copy from */
24204 + } copy; /* if EXT or COPY, where and how much */
24205 + } sub; /* submode */
24206 +
24207 + /* mode independent information */
24208 + Byte lbits; /* ltree bits decoded per branch */
24209 + Byte dbits; /* dtree bits decoder per branch */
24210 + inflate_huft *ltree; /* literal/length/eob tree */
24211 + inflate_huft *dtree; /* distance tree */
24212 +
24213 +};
24214 +
24215 +
24216 +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
24217 +uInt bl, bd;
24218 +inflate_huft *tl;
24219 +inflate_huft *td; /* need separate declaration for Borland C++ */
24220 +z_streamp z;
24221 +{
24222 + inflate_codes_statef *c;
24223 +
24224 + if ((c = (inflate_codes_statef *)
24225 + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
24226 + {
24227 + c->mode = START;
24228 + c->lbits = (Byte)bl;
24229 + c->dbits = (Byte)bd;
24230 + c->ltree = tl;
24231 + c->dtree = td;
24232 + Tracev((stderr, "inflate: codes new\n"));
24233 + }
24234 + return c;
24235 +}
24236 +
24237 +
24238 +int inflate_codes(s, z, r)
24239 +inflate_blocks_statef *s;
24240 +z_streamp z;
24241 +int r;
24242 +{
24243 + uInt j; /* temporary storage */
24244 + inflate_huft *t; /* temporary pointer */
24245 + uInt e; /* extra bits or operation */
24246 + uLong b; /* bit buffer */
24247 + uInt k; /* bits in bit buffer */
24248 + Bytef *p; /* input data pointer */
24249 + uInt n; /* bytes available there */
24250 + Bytef *q; /* output window write pointer */
24251 + uInt m; /* bytes to end of window or read pointer */
24252 + Bytef *f; /* pointer to copy strings from */
24253 + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
24254 +
24255 + /* copy input/output information to locals (UPDATE macro restores) */
24256 + LOAD
24257 +
24258 + /* process input and output based on current state */
24259 + while (1) switch (c->mode)
24260 + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
24261 + case START: /* x: set up for LEN */
24262 +#ifndef SLOW
24263 + if (m >= 258 && n >= 10)
24264 + {
24265 + UPDATE
24266 + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
24267 + LOAD
24268 + if (r != Z_OK)
24269 + {
24270 + c->mode = r == Z_STREAM_END ? WASH : BADCODE;
24271 + break;
24272 + }
24273 + }
24274 +#endif /* !SLOW */
24275 + c->sub.code.need = c->lbits;
24276 + c->sub.code.tree = c->ltree;
24277 + c->mode = LEN;
24278 + case LEN: /* i: get length/literal/eob next */
24279 + j = c->sub.code.need;
24280 + NEEDBITS(j)
24281 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
24282 + DUMPBITS(t->bits)
24283 + e = (uInt)(t->exop);
24284 + if (e == 0) /* literal */
24285 + {
24286 + c->sub.lit = t->base;
24287 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24288 + "inflate: literal '%c'\n" :
24289 + "inflate: literal 0x%02x\n", t->base));
24290 + c->mode = LIT;
24291 + break;
24292 + }
24293 + if (e & 16) /* length */
24294 + {
24295 + c->sub.copy.get = e & 15;
24296 + c->len = t->base;
24297 + c->mode = LENEXT;
24298 + break;
24299 + }
24300 + if ((e & 64) == 0) /* next table */
24301 + {
24302 + c->sub.code.need = e;
24303 + c->sub.code.tree = t + t->base;
24304 + break;
24305 + }
24306 + if (e & 32) /* end of block */
24307 + {
24308 + Tracevv((stderr, "inflate: end of block\n"));
24309 + c->mode = WASH;
24310 + break;
24311 + }
24312 + c->mode = BADCODE; /* invalid code */
24313 + z->msg = (char*)"invalid literal/length code";
24314 + r = Z_DATA_ERROR;
24315 + LEAVE
24316 + case LENEXT: /* i: getting length extra (have base) */
24317 + j = c->sub.copy.get;
24318 + NEEDBITS(j)
24319 + c->len += (uInt)b & inflate_mask[j];
24320 + DUMPBITS(j)
24321 + c->sub.code.need = c->dbits;
24322 + c->sub.code.tree = c->dtree;
24323 + Tracevv((stderr, "inflate: length %u\n", c->len));
24324 + c->mode = DIST;
24325 + case DIST: /* i: get distance next */
24326 + j = c->sub.code.need;
24327 + NEEDBITS(j)
24328 + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
24329 + DUMPBITS(t->bits)
24330 + e = (uInt)(t->exop);
24331 + if (e & 16) /* distance */
24332 + {
24333 + c->sub.copy.get = e & 15;
24334 + c->sub.copy.dist = t->base;
24335 + c->mode = DISTEXT;
24336 + break;
24337 + }
24338 + if ((e & 64) == 0) /* next table */
24339 + {
24340 + c->sub.code.need = e;
24341 + c->sub.code.tree = t + t->base;
24342 + break;
24343 + }
24344 + c->mode = BADCODE; /* invalid code */
24345 + z->msg = (char*)"invalid distance code";
24346 + r = Z_DATA_ERROR;
24347 + LEAVE
24348 + case DISTEXT: /* i: getting distance extra */
24349 + j = c->sub.copy.get;
24350 + NEEDBITS(j)
24351 + c->sub.copy.dist += (uInt)b & inflate_mask[j];
24352 + DUMPBITS(j)
24353 + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
24354 + c->mode = COPY;
24355 + case COPY: /* o: copying bytes in window, waiting for space */
24356 + f = q - c->sub.copy.dist;
24357 + while (f < s->window) /* modulo window size-"while" instead */
24358 + f += s->end - s->window; /* of "if" handles invalid distances */
24359 + while (c->len)
24360 + {
24361 + NEEDOUT
24362 + OUTBYTE(*f++)
24363 + if (f == s->end)
24364 + f = s->window;
24365 + c->len--;
24366 + }
24367 + c->mode = START;
24368 + break;
24369 + case LIT: /* o: got literal, waiting for output space */
24370 + NEEDOUT
24371 + OUTBYTE(c->sub.lit)
24372 + c->mode = START;
24373 + break;
24374 + case WASH: /* o: got eob, possibly more output */
24375 + if (k > 7) /* return unused byte, if any */
24376 + {
24377 + Assert(k < 16, "inflate_codes grabbed too many bytes")
24378 + k -= 8;
24379 + n++;
24380 + p--; /* can always return one */
24381 + }
24382 + FLUSH
24383 + if (s->read != s->write)
24384 + LEAVE
24385 + c->mode = END;
24386 + case END:
24387 + r = Z_STREAM_END;
24388 + LEAVE
24389 + case BADCODE: /* x: got error */
24390 + r = Z_DATA_ERROR;
24391 + LEAVE
24392 + default:
24393 + r = Z_STREAM_ERROR;
24394 + LEAVE
24395 + }
24396 +#ifdef NEED_DUMMY_RETURN
24397 + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
24398 +#endif
24399 +}
24400 +
24401 +
24402 +void inflate_codes_free(c, z)
24403 +inflate_codes_statef *c;
24404 +z_streamp z;
24405 +{
24406 + ZFREE(z, c);
24407 + Tracev((stderr, "inflate: codes free\n"));
24408 +}
24409 --- /dev/null Tue Mar 11 13:02:56 2003
24410 +++ linux/net/ipsec/infcodes.h Mon Feb 9 13:51:03 2004
24411 @@ -0,0 +1,31 @@
24412 +/* infcodes.h -- header to use infcodes.c
24413 + * Copyright (C) 1995-2002 Mark Adler
24414 + * For conditions of distribution and use, see copyright notice in zlib.h
24415 + */
24416 +
24417 +/* WARNING: this file should *not* be used by applications. It is
24418 + part of the implementation of the compression library and is
24419 + subject to change. Applications should only use zlib.h.
24420 + */
24421 +
24422 +#ifndef _INFCODES_H
24423 +#define _INFCODES_H
24424 +
24425 +struct inflate_codes_state;
24426 +typedef struct inflate_codes_state FAR inflate_codes_statef;
24427 +
24428 +extern inflate_codes_statef *inflate_codes_new OF((
24429 + uInt, uInt,
24430 + inflate_huft *, inflate_huft *,
24431 + z_streamp ));
24432 +
24433 +extern int inflate_codes OF((
24434 + inflate_blocks_statef *,
24435 + z_streamp ,
24436 + int));
24437 +
24438 +extern void inflate_codes_free OF((
24439 + inflate_codes_statef *,
24440 + z_streamp ));
24441 +
24442 +#endif /* _INFCODES_H */
24443 --- /dev/null Tue Mar 11 13:02:56 2003
24444 +++ linux/net/ipsec/inffast.c Mon Feb 9 13:51:03 2004
24445 @@ -0,0 +1,183 @@
24446 +/* inffast.c -- process literals and length/distance pairs fast
24447 + * Copyright (C) 1995-2002 Mark Adler
24448 + * For conditions of distribution and use, see copyright notice in zlib.h
24449 + */
24450 +
24451 +#include <zlib/zutil.h>
24452 +#include "inftrees.h"
24453 +#include "infblock.h"
24454 +#include "infcodes.h"
24455 +#include "infutil.h"
24456 +#include "inffast.h"
24457 +
24458 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
24459 +
24460 +/* simplify the use of the inflate_huft type with some defines */
24461 +#define exop word.what.Exop
24462 +#define bits word.what.Bits
24463 +
24464 +/* macros for bit input with no checking and for returning unused bytes */
24465 +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
24466 +#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
24467 +
24468 +/* Called with number of bytes left to write in window at least 258
24469 + (the maximum string length) and number of input bytes available
24470 + at least ten. The ten bytes are six bytes for the longest length/
24471 + distance pair plus four bytes for overloading the bit buffer. */
24472 +
24473 +int inflate_fast(bl, bd, tl, td, s, z)
24474 +uInt bl, bd;
24475 +inflate_huft *tl;
24476 +inflate_huft *td; /* need separate declaration for Borland C++ */
24477 +inflate_blocks_statef *s;
24478 +z_streamp z;
24479 +{
24480 + inflate_huft *t; /* temporary pointer */
24481 + uInt e; /* extra bits or operation */
24482 + uLong b; /* bit buffer */
24483 + uInt k; /* bits in bit buffer */
24484 + Bytef *p; /* input data pointer */
24485 + uInt n; /* bytes available there */
24486 + Bytef *q; /* output window write pointer */
24487 + uInt m; /* bytes to end of window or read pointer */
24488 + uInt ml; /* mask for literal/length tree */
24489 + uInt md; /* mask for distance tree */
24490 + uInt c; /* bytes to copy */
24491 + uInt d; /* distance back to copy from */
24492 + Bytef *r; /* copy source pointer */
24493 +
24494 + /* load input, output, bit values */
24495 + LOAD
24496 +
24497 + /* initialize masks */
24498 + ml = inflate_mask[bl];
24499 + md = inflate_mask[bd];
24500 +
24501 + /* do until not enough input or output space for fast loop */
24502 + do { /* assume called with m >= 258 && n >= 10 */
24503 + /* get literal/length code */
24504 + GRABBITS(20) /* max bits for literal/length code */
24505 + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
24506 + {
24507 + DUMPBITS(t->bits)
24508 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24509 + "inflate: * literal '%c'\n" :
24510 + "inflate: * literal 0x%02x\n", t->base));
24511 + *q++ = (Byte)t->base;
24512 + m--;
24513 + continue;
24514 + }
24515 + do {
24516 + DUMPBITS(t->bits)
24517 + if (e & 16)
24518 + {
24519 + /* get extra bits for length */
24520 + e &= 15;
24521 + c = t->base + ((uInt)b & inflate_mask[e]);
24522 + DUMPBITS(e)
24523 + Tracevv((stderr, "inflate: * length %u\n", c));
24524 +
24525 + /* decode distance base of block to copy */
24526 + GRABBITS(15); /* max bits for distance code */
24527 + e = (t = td + ((uInt)b & md))->exop;
24528 + do {
24529 + DUMPBITS(t->bits)
24530 + if (e & 16)
24531 + {
24532 + /* get extra bits to add to distance base */
24533 + e &= 15;
24534 + GRABBITS(e) /* get extra bits (up to 13) */
24535 + d = t->base + ((uInt)b & inflate_mask[e]);
24536 + DUMPBITS(e)
24537 + Tracevv((stderr, "inflate: * distance %u\n", d));
24538 +
24539 + /* do the copy */
24540 + m -= c;
24541 + r = q - d;
24542 + if (r < s->window) /* wrap if needed */
24543 + {
24544 + do {
24545 + r += s->end - s->window; /* force pointer in window */
24546 + } while (r < s->window); /* covers invalid distances */
24547 + e = s->end - r;
24548 + if (c > e)
24549 + {
24550 + c -= e; /* wrapped copy */
24551 + do {
24552 + *q++ = *r++;
24553 + } while (--e);
24554 + r = s->window;
24555 + do {
24556 + *q++ = *r++;
24557 + } while (--c);
24558 + }
24559 + else /* normal copy */
24560 + {
24561 + *q++ = *r++; c--;
24562 + *q++ = *r++; c--;
24563 + do {
24564 + *q++ = *r++;
24565 + } while (--c);
24566 + }
24567 + }
24568 + else /* normal copy */
24569 + {
24570 + *q++ = *r++; c--;
24571 + *q++ = *r++; c--;
24572 + do {
24573 + *q++ = *r++;
24574 + } while (--c);
24575 + }
24576 + break;
24577 + }
24578 + else if ((e & 64) == 0)
24579 + {
24580 + t += t->base;
24581 + e = (t += ((uInt)b & inflate_mask[e]))->exop;
24582 + }
24583 + else
24584 + {
24585 + z->msg = (char*)"invalid distance code";
24586 + UNGRAB
24587 + UPDATE
24588 + return Z_DATA_ERROR;
24589 + }
24590 + } while (1);
24591 + break;
24592 + }
24593 + if ((e & 64) == 0)
24594 + {
24595 + t += t->base;
24596 + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
24597 + {
24598 + DUMPBITS(t->bits)
24599 + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
24600 + "inflate: * literal '%c'\n" :
24601 + "inflate: * literal 0x%02x\n", t->base));
24602 + *q++ = (Byte)t->base;
24603 + m--;
24604 + break;
24605 + }
24606 + }
24607 + else if (e & 32)
24608 + {
24609 + Tracevv((stderr, "inflate: * end of block\n"));
24610 + UNGRAB
24611 + UPDATE
24612 + return Z_STREAM_END;
24613 + }
24614 + else
24615 + {
24616 + z->msg = (char*)"invalid literal/length code";
24617 + UNGRAB
24618 + UPDATE
24619 + return Z_DATA_ERROR;
24620 + }
24621 + } while (1);
24622 + } while (m >= 258 && n >= 10);
24623 +
24624 + /* not enough input or output--restore pointers and return */
24625 + UNGRAB
24626 + UPDATE
24627 + return Z_OK;
24628 +}
24629 --- /dev/null Tue Mar 11 13:02:56 2003
24630 +++ linux/net/ipsec/inffast.h Mon Feb 9 13:51:03 2004
24631 @@ -0,0 +1,22 @@
24632 +/* inffast.h -- header to use inffast.c
24633 + * Copyright (C) 1995-2002 Mark Adler
24634 + * For conditions of distribution and use, see copyright notice in zlib.h
24635 + */
24636 +
24637 +/* WARNING: this file should *not* be used by applications. It is
24638 + part of the implementation of the compression library and is
24639 + subject to change. Applications should only use zlib.h.
24640 + */
24641 +
24642 +#ifndef _INFFAST_H
24643 +#define _INFFAST_H
24644 +
24645 +extern int inflate_fast OF((
24646 + uInt,
24647 + uInt,
24648 + inflate_huft *,
24649 + inflate_huft *,
24650 + inflate_blocks_statef *,
24651 + z_streamp ));
24652 +
24653 +#endif /* _INFFAST_H */
24654 --- /dev/null Tue Mar 11 13:02:56 2003
24655 +++ linux/net/ipsec/inffixed.h Mon Feb 9 13:51:03 2004
24656 @@ -0,0 +1,151 @@
24657 +/* inffixed.h -- table for decoding fixed codes
24658 + * Generated automatically by the maketree.c program
24659 + */
24660 +
24661 +/* WARNING: this file should *not* be used by applications. It is
24662 + part of the implementation of the compression library and is
24663 + subject to change. Applications should only use zlib.h.
24664 + */
24665 +
24666 +local uInt fixed_bl = 9;
24667 +local uInt fixed_bd = 5;
24668 +local inflate_huft fixed_tl[] = {
24669 + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24670 + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
24671 + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
24672 + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
24673 + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
24674 + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
24675 + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
24676 + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
24677 + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24678 + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
24679 + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
24680 + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
24681 + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
24682 + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
24683 + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
24684 + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
24685 + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24686 + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
24687 + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
24688 + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
24689 + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
24690 + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
24691 + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
24692 + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
24693 + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24694 + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
24695 + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
24696 + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
24697 + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
24698 + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
24699 + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
24700 + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
24701 + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24702 + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
24703 + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
24704 + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
24705 + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
24706 + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
24707 + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
24708 + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
24709 + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24710 + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
24711 + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
24712 + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
24713 + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
24714 + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
24715 + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
24716 + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
24717 + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24718 + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
24719 + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
24720 + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
24721 + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
24722 + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
24723 + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
24724 + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
24725 + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24726 + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
24727 + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
24728 + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
24729 + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
24730 + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
24731 + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
24732 + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
24733 + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
24734 + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
24735 + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
24736 + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
24737 + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
24738 + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
24739 + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
24740 + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
24741 + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
24742 + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
24743 + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
24744 + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
24745 + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
24746 + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
24747 + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
24748 + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
24749 + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
24750 + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
24751 + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
24752 + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
24753 + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
24754 + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
24755 + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
24756 + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
24757 + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
24758 + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
24759 + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
24760 + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
24761 + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
24762 + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
24763 + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
24764 + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
24765 + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
24766 + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
24767 + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
24768 + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
24769 + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
24770 + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
24771 + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
24772 + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
24773 + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
24774 + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
24775 + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
24776 + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
24777 + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
24778 + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
24779 + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
24780 + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
24781 + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
24782 + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
24783 + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
24784 + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
24785 + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
24786 + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
24787 + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
24788 + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
24789 + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
24790 + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
24791 + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
24792 + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
24793 + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
24794 + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
24795 + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
24796 + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
24797 + };
24798 +local inflate_huft fixed_td[] = {
24799 + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
24800 + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
24801 + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
24802 + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
24803 + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
24804 + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
24805 + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
24806 + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
24807 + };
24808 --- /dev/null Tue Mar 11 13:02:56 2003
24809 +++ linux/net/ipsec/inflate.c Mon Feb 9 13:51:03 2004
24810 @@ -0,0 +1,368 @@
24811 +/* inflate.c -- zlib interface to inflate modules
24812 + * Copyright (C) 1995-2002 Mark Adler
24813 + * For conditions of distribution and use, see copyright notice in zlib.h
24814 + */
24815 +
24816 +#include <zlib/zutil.h>
24817 +#include "infblock.h"
24818 +
24819 +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
24820 +
24821 +typedef enum {
24822 + METHOD, /* waiting for method byte */
24823 + FLAG, /* waiting for flag byte */
24824 + DICT4, /* four dictionary check bytes to go */
24825 + DICT3, /* three dictionary check bytes to go */
24826 + DICT2, /* two dictionary check bytes to go */
24827 + DICT1, /* one dictionary check byte to go */
24828 + DICT0, /* waiting for inflateSetDictionary */
24829 + BLOCKS, /* decompressing blocks */
24830 + CHECK4, /* four check bytes to go */
24831 + CHECK3, /* three check bytes to go */
24832 + CHECK2, /* two check bytes to go */
24833 + CHECK1, /* one check byte to go */
24834 + DONE, /* finished check, done */
24835 + BAD} /* got an error--stay here */
24836 +inflate_mode;
24837 +
24838 +/* inflate private state */
24839 +struct internal_state {
24840 +
24841 + /* mode */
24842 + inflate_mode mode; /* current inflate mode */
24843 +
24844 + /* mode dependent information */
24845 + union {
24846 + uInt method; /* if FLAGS, method byte */
24847 + struct {
24848 + uLong was; /* computed check value */
24849 + uLong need; /* stream check value */
24850 + } check; /* if CHECK, check values to compare */
24851 + uInt marker; /* if BAD, inflateSync's marker bytes count */
24852 + } sub; /* submode */
24853 +
24854 + /* mode independent information */
24855 + int nowrap; /* flag for no wrapper */
24856 + uInt wbits; /* log2(window size) (8..15, defaults to 15) */
24857 + inflate_blocks_statef
24858 + *blocks; /* current inflate_blocks state */
24859 +
24860 +};
24861 +
24862 +
24863 +int ZEXPORT inflateReset(z)
24864 +z_streamp z;
24865 +{
24866 + if (z == Z_NULL || z->state == Z_NULL)
24867 + return Z_STREAM_ERROR;
24868 + z->total_in = z->total_out = 0;
24869 + z->msg = Z_NULL;
24870 + z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
24871 + inflate_blocks_reset(z->state->blocks, z, Z_NULL);
24872 + Tracev((stderr, "inflate: reset\n"));
24873 + return Z_OK;
24874 +}
24875 +
24876 +
24877 +int ZEXPORT inflateEnd(z)
24878 +z_streamp z;
24879 +{
24880 + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
24881 + return Z_STREAM_ERROR;
24882 + if (z->state->blocks != Z_NULL)
24883 + inflate_blocks_free(z->state->blocks, z);
24884 + ZFREE(z, z->state);
24885 + z->state = Z_NULL;
24886 + Tracev((stderr, "inflate: end\n"));
24887 + return Z_OK;
24888 +}
24889 +
24890 +
24891 +int ZEXPORT inflateInit2_(z, w, version, stream_size)
24892 +z_streamp z;
24893 +int w;
24894 +const char *version;
24895 +int stream_size;
24896 +{
24897 + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
24898 + stream_size != sizeof(z_stream))
24899 + return Z_VERSION_ERROR;
24900 +
24901 + /* initialize state */
24902 + if (z == Z_NULL)
24903 + return Z_STREAM_ERROR;
24904 + z->msg = Z_NULL;
24905 + if (z->zalloc == Z_NULL)
24906 + {
24907 + return Z_STREAM_ERROR;
24908 +/* z->zalloc = zcalloc;
24909 + z->opaque = (voidpf)0;
24910 +*/
24911 + }
24912 + if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
24913 + if ((z->state = (struct internal_state FAR *)
24914 + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
24915 + return Z_MEM_ERROR;
24916 + z->state->blocks = Z_NULL;
24917 +
24918 + /* handle undocumented nowrap option (no zlib header or check) */
24919 + z->state->nowrap = 0;
24920 + if (w < 0)
24921 + {
24922 + w = - w;
24923 + z->state->nowrap = 1;
24924 + }
24925 +
24926 + /* set window size */
24927 + if (w < 8 || w > 15)
24928 + {
24929 + inflateEnd(z);
24930 + return Z_STREAM_ERROR;
24931 + }
24932 + z->state->wbits = (uInt)w;
24933 +
24934 + /* create inflate_blocks state */
24935 + if ((z->state->blocks =
24936 + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
24937 + == Z_NULL)
24938 + {
24939 + inflateEnd(z);
24940 + return Z_MEM_ERROR;
24941 + }
24942 + Tracev((stderr, "inflate: allocated\n"));
24943 +
24944 + /* reset state */
24945 + inflateReset(z);
24946 + return Z_OK;
24947 +}
24948 +
24949 +
24950 +int ZEXPORT inflateInit_(z, version, stream_size)
24951 +z_streamp z;
24952 +const char *version;
24953 +int stream_size;
24954 +{
24955 + return inflateInit2_(z, DEF_WBITS, version, stream_size);
24956 +}
24957 +
24958 +
24959 +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
24960 +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
24961 +
24962 +int ZEXPORT inflate(z, f)
24963 +z_streamp z;
24964 +int f;
24965 +{
24966 + int r;
24967 + uInt b;
24968 +
24969 + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
24970 + return Z_STREAM_ERROR;
24971 + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
24972 + r = Z_BUF_ERROR;
24973 + while (1) switch (z->state->mode)
24974 + {
24975 + case METHOD:
24976 + NEEDBYTE
24977 + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
24978 + {
24979 + z->state->mode = BAD;
24980 + z->msg = (char*)"unknown compression method";
24981 + z->state->sub.marker = 5; /* can't try inflateSync */
24982 + break;
24983 + }
24984 + if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
24985 + {
24986 + z->state->mode = BAD;
24987 + z->msg = (char*)"invalid window size";
24988 + z->state->sub.marker = 5; /* can't try inflateSync */
24989 + break;
24990 + }
24991 + z->state->mode = FLAG;
24992 + case FLAG:
24993 + NEEDBYTE
24994 + b = NEXTBYTE;
24995 + if (((z->state->sub.method << 8) + b) % 31)
24996 + {
24997 + z->state->mode = BAD;
24998 + z->msg = (char*)"incorrect header check";
24999 + z->state->sub.marker = 5; /* can't try inflateSync */
25000 + break;
25001 + }
25002 + Tracev((stderr, "inflate: zlib header ok\n"));
25003 + if (!(b & PRESET_DICT))
25004 + {
25005 + z->state->mode = BLOCKS;
25006 + break;
25007 + }
25008 + z->state->mode = DICT4;
25009 + case DICT4:
25010 + NEEDBYTE
25011 + z->state->sub.check.need = (uLong)NEXTBYTE << 24;
25012 + z->state->mode = DICT3;
25013 + case DICT3:
25014 + NEEDBYTE
25015 + z->state->sub.check.need += (uLong)NEXTBYTE << 16;
25016 + z->state->mode = DICT2;
25017 + case DICT2:
25018 + NEEDBYTE
25019 + z->state->sub.check.need += (uLong)NEXTBYTE << 8;
25020 + z->state->mode = DICT1;
25021 + case DICT1:
25022 + NEEDBYTE
25023 + z->state->sub.check.need += (uLong)NEXTBYTE;
25024 + z->adler = z->state->sub.check.need;
25025 + z->state->mode = DICT0;
25026 + return Z_NEED_DICT;
25027 + case DICT0:
25028 + z->state->mode = BAD;
25029 + z->msg = (char*)"need dictionary";
25030 + z->state->sub.marker = 0; /* can try inflateSync */
25031 + return Z_STREAM_ERROR;
25032 + case BLOCKS:
25033 + r = inflate_blocks(z->state->blocks, z, r);
25034 + if (r == Z_DATA_ERROR)
25035 + {
25036 + z->state->mode = BAD;
25037 + z->state->sub.marker = 0; /* can try inflateSync */
25038 + break;
25039 + }
25040 + if (r == Z_OK)
25041 + r = f;
25042 + if (r != Z_STREAM_END)
25043 + return r;
25044 + r = f;
25045 + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
25046 + if (z->state->nowrap)
25047 + {
25048 + z->state->mode = DONE;
25049 + break;
25050 + }
25051 + z->state->mode = CHECK4;
25052 + case CHECK4:
25053 + NEEDBYTE
25054 + z->state->sub.check.need = (uLong)NEXTBYTE << 24;
25055 + z->state->mode = CHECK3;
25056 + case CHECK3:
25057 + NEEDBYTE
25058 + z->state->sub.check.need += (uLong)NEXTBYTE << 16;
25059 + z->state->mode = CHECK2;
25060 + case CHECK2:
25061 + NEEDBYTE
25062 + z->state->sub.check.need += (uLong)NEXTBYTE << 8;
25063 + z->state->mode = CHECK1;
25064 + case CHECK1:
25065 + NEEDBYTE
25066 + z->state->sub.check.need += (uLong)NEXTBYTE;
25067 +
25068 + if (z->state->sub.check.was != z->state->sub.check.need)
25069 + {
25070 + z->state->mode = BAD;
25071 + z->msg = (char*)"incorrect data check";
25072 + z->state->sub.marker = 5; /* can't try inflateSync */
25073 + break;
25074 + }
25075 + Tracev((stderr, "inflate: zlib check ok\n"));
25076 + z->state->mode = DONE;
25077 + case DONE:
25078 + return Z_STREAM_END;
25079 + case BAD:
25080 + return Z_DATA_ERROR;
25081 + default:
25082 + return Z_STREAM_ERROR;
25083 + }
25084 +#ifdef NEED_DUMMY_RETURN
25085 + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
25086 +#endif
25087 +}
25088 +
25089 +
25090 +int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
25091 +z_streamp z;
25092 +const Bytef *dictionary;
25093 +uInt dictLength;
25094 +{
25095 + uInt length = dictLength;
25096 +
25097 + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
25098 + return Z_STREAM_ERROR;
25099 +
25100 + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
25101 + z->adler = 1L;
25102 +
25103 + if (length >= ((uInt)1<<z->state->wbits))
25104 + {
25105 + length = (1<<z->state->wbits)-1;
25106 + dictionary += dictLength - length;
25107 + }
25108 + inflate_set_dictionary(z->state->blocks, dictionary, length);
25109 + z->state->mode = BLOCKS;
25110 + return Z_OK;
25111 +}
25112 +
25113 +
25114 +int ZEXPORT inflateSync(z)
25115 +z_streamp z;
25116 +{
25117 + uInt n; /* number of bytes to look at */
25118 + Bytef *p; /* pointer to bytes */
25119 + uInt m; /* number of marker bytes found in a row */
25120 + uLong r, w; /* temporaries to save total_in and total_out */
25121 +
25122 + /* set up */
25123 + if (z == Z_NULL || z->state == Z_NULL)
25124 + return Z_STREAM_ERROR;
25125 + if (z->state->mode != BAD)
25126 + {
25127 + z->state->mode = BAD;
25128 + z->state->sub.marker = 0;
25129 + }
25130 + if ((n = z->avail_in) == 0)
25131 + return Z_BUF_ERROR;
25132 + p = z->next_in;
25133 + m = z->state->sub.marker;
25134 +
25135 + /* search */
25136 + while (n && m < 4)
25137 + {
25138 + static const Byte mark[4] = {0, 0, 0xff, 0xff};
25139 + if (*p == mark[m])
25140 + m++;
25141 + else if (*p)
25142 + m = 0;
25143 + else
25144 + m = 4 - m;
25145 + p++, n--;
25146 + }
25147 +
25148 + /* restore */
25149 + z->total_in += p - z->next_in;
25150 + z->next_in = p;
25151 + z->avail_in = n;
25152 + z->state->sub.marker = m;
25153 +
25154 + /* return no joy or set up to restart on a new block */
25155 + if (m != 4)
25156 + return Z_DATA_ERROR;
25157 + r = z->total_in; w = z->total_out;
25158 + inflateReset(z);
25159 + z->total_in = r; z->total_out = w;
25160 + z->state->mode = BLOCKS;
25161 + return Z_OK;
25162 +}
25163 +
25164 +
25165 +/* Returns true if inflate is currently at the end of a block generated
25166 + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
25167 + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
25168 + * but removes the length bytes of the resulting empty stored block. When
25169 + * decompressing, PPP checks that at the end of input packet, inflate is
25170 + * waiting for these length bytes.
25171 + */
25172 +int ZEXPORT inflateSyncPoint(z)
25173 +z_streamp z;
25174 +{
25175 + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
25176 + return Z_STREAM_ERROR;
25177 + return inflate_blocks_sync_point(z->state->blocks);
25178 +}
25179 --- /dev/null Tue Mar 11 13:02:56 2003
25180 +++ linux/net/ipsec/inftrees.c Mon Feb 9 13:51:03 2004
25181 @@ -0,0 +1,454 @@
25182 +/* inftrees.c -- generate Huffman trees for efficient decoding
25183 + * Copyright (C) 1995-2002 Mark Adler
25184 + * For conditions of distribution and use, see copyright notice in zlib.h
25185 + */
25186 +
25187 +#include <zlib/zutil.h>
25188 +#include "inftrees.h"
25189 +
25190 +#if !defined(BUILDFIXED) && !defined(STDC)
25191 +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
25192 +#endif
25193 +
25194 +local const char inflate_copyright[] =
25195 + " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
25196 +/*
25197 + If you use the zlib library in a product, an acknowledgment is welcome
25198 + in the documentation of your product. If for some reason you cannot
25199 + include such an acknowledgment, I would appreciate that you keep this
25200 + copyright string in the executable of your product.
25201 + */
25202 +struct internal_state {int dummy;}; /* for buggy compilers */
25203 +
25204 +/* simplify the use of the inflate_huft type with some defines */
25205 +#define exop word.what.Exop
25206 +#define bits word.what.Bits
25207 +
25208 +
25209 +local int huft_build OF((
25210 + uIntf *, /* code lengths in bits */
25211 + uInt, /* number of codes */
25212 + uInt, /* number of "simple" codes */
25213 + const uIntf *, /* list of base values for non-simple codes */
25214 + const uIntf *, /* list of extra bits for non-simple codes */
25215 + inflate_huft * FAR*,/* result: starting table */
25216 + uIntf *, /* maximum lookup bits (returns actual) */
25217 + inflate_huft *, /* space for trees */
25218 + uInt *, /* hufts used in space */
25219 + uIntf * )); /* space for values */
25220 +
25221 +/* Tables for deflate from PKZIP's appnote.txt. */
25222 +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
25223 + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
25224 + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
25225 + /* see note #13 above about 258 */
25226 +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
25227 + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
25228 + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
25229 +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
25230 + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
25231 + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
25232 + 8193, 12289, 16385, 24577};
25233 +local const uInt cpdext[30] = { /* Extra bits for distance codes */
25234 + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
25235 + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
25236 + 12, 12, 13, 13};
25237 +
25238 +/*
25239 + Huffman code decoding is performed using a multi-level table lookup.
25240 + The fastest way to decode is to simply build a lookup table whose
25241 + size is determined by the longest code. However, the time it takes
25242 + to build this table can also be a factor if the data being decoded
25243 + is not very long. The most common codes are necessarily the
25244 + shortest codes, so those codes dominate the decoding time, and hence
25245 + the speed. The idea is you can have a shorter table that decodes the
25246 + shorter, more probable codes, and then point to subsidiary tables for
25247 + the longer codes. The time it costs to decode the longer codes is
25248 + then traded against the time it takes to make longer tables.
25249 +
25250 + This results of this trade are in the variables lbits and dbits
25251 + below. lbits is the number of bits the first level table for literal/
25252 + length codes can decode in one step, and dbits is the same thing for
25253 + the distance codes. Subsequent tables are also less than or equal to
25254 + those sizes. These values may be adjusted either when all of the
25255 + codes are shorter than that, in which case the longest code length in
25256 + bits is used, or when the shortest code is *longer* than the requested
25257 + table size, in which case the length of the shortest code in bits is
25258 + used.
25259 +
25260 + There are two different values for the two tables, since they code a
25261 + different number of possibilities each. The literal/length table
25262 + codes 286 possible values, or in a flat code, a little over eight
25263 + bits. The distance table codes 30 possible values, or a little less
25264 + than five bits, flat. The optimum values for speed end up being
25265 + about one bit more than those, so lbits is 8+1 and dbits is 5+1.
25266 + The optimum values may differ though from machine to machine, and
25267 + possibly even between compilers. Your mileage may vary.
25268 + */
25269 +
25270 +
25271 +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
25272 +#define BMAX 15 /* maximum bit length of any code */
25273 +
25274 +local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
25275 +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
25276 +uInt n; /* number of codes (assumed <= 288) */
25277 +uInt s; /* number of simple-valued codes (0..s-1) */
25278 +const uIntf *d; /* list of base values for non-simple codes */
25279 +const uIntf *e; /* list of extra bits for non-simple codes */
25280 +inflate_huft * FAR *t; /* result: starting table */
25281 +uIntf *m; /* maximum lookup bits, returns actual */
25282 +inflate_huft *hp; /* space for trees */
25283 +uInt *hn; /* hufts used in space */
25284 +uIntf *v; /* working area: values in order of bit length */
25285 +/* Given a list of code lengths and a maximum table size, make a set of
25286 + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
25287 + if the given code set is incomplete (the tables are still built in this
25288 + case), or Z_DATA_ERROR if the input is invalid. */
25289 +{
25290 +
25291 + uInt a; /* counter for codes of length k */
25292 + uInt c[BMAX+1]; /* bit length count table */
25293 + uInt f; /* i repeats in table every f entries */
25294 + int g; /* maximum code length */
25295 + int h; /* table level */
25296 + register uInt i; /* counter, current code */
25297 + register uInt j; /* counter */
25298 + register int k; /* number of bits in current code */
25299 + int l; /* bits per table (returned in m) */
25300 + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
25301 + register uIntf *p; /* pointer into c[], b[], or v[] */
25302 + inflate_huft *q; /* points to current table */
25303 + struct inflate_huft_s r; /* table entry for structure assignment */
25304 + inflate_huft *u[BMAX]; /* table stack */
25305 + register int w; /* bits before this table == (l * h) */
25306 + uInt x[BMAX+1]; /* bit offsets, then code stack */
25307 + uIntf *xp; /* pointer into x */
25308 + int y; /* number of dummy codes added */
25309 + uInt z; /* number of entries in current table */
25310 +
25311 +
25312 + /* Generate counts for each bit length */
25313 + p = c;
25314 +#define C0 *p++ = 0;
25315 +#define C2 C0 C0 C0 C0
25316 +#define C4 C2 C2 C2 C2
25317 + C4 /* clear c[]--assume BMAX+1 is 16 */
25318 + p = b; i = n;
25319 + do {
25320 + c[*p++]++; /* assume all entries <= BMAX */
25321 + } while (--i);
25322 + if (c[0] == n) /* null input--all zero length codes */
25323 + {
25324 + *t = (inflate_huft *)Z_NULL;
25325 + *m = 0;
25326 + return Z_OK;
25327 + }
25328 +
25329 +
25330 + /* Find minimum and maximum length, bound *m by those */
25331 + l = *m;
25332 + for (j = 1; j <= BMAX; j++)
25333 + if (c[j])
25334 + break;
25335 + k = j; /* minimum code length */
25336 + if ((uInt)l < j)
25337 + l = j;
25338 + for (i = BMAX; i; i--)
25339 + if (c[i])
25340 + break;
25341 + g = i; /* maximum code length */
25342 + if ((uInt)l > i)
25343 + l = i;
25344 + *m = l;
25345 +
25346 +
25347 + /* Adjust last length count to fill out codes, if needed */
25348 + for (y = 1 << j; j < i; j++, y <<= 1)
25349 + if ((y -= c[j]) < 0)
25350 + return Z_DATA_ERROR;
25351 + if ((y -= c[i]) < 0)
25352 + return Z_DATA_ERROR;
25353 + c[i] += y;
25354 +
25355 +
25356 + /* Generate starting offsets into the value table for each length */
25357 + x[1] = j = 0;
25358 + p = c + 1; xp = x + 2;
25359 + while (--i) { /* note that i == g from above */
25360 + *xp++ = (j += *p++);
25361 + }
25362 +
25363 +
25364 + /* Make a table of values in order of bit lengths */
25365 + p = b; i = 0;
25366 + do {
25367 + if ((j = *p++) != 0)
25368 + v[x[j]++] = i;
25369 + } while (++i < n);
25370 + n = x[g]; /* set n to length of v */
25371 +
25372 +
25373 + /* Generate the Huffman codes and for each, make the table entries */
25374 + x[0] = i = 0; /* first Huffman code is zero */
25375 + p = v; /* grab values in bit order */
25376 + h = -1; /* no tables yet--level -1 */
25377 + w = -l; /* bits decoded == (l * h) */
25378 + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
25379 + q = (inflate_huft *)Z_NULL; /* ditto */
25380 + z = 0; /* ditto */
25381 +
25382 + /* go through the bit lengths (k already is bits in shortest code) */
25383 + for (; k <= g; k++)
25384 + {
25385 + a = c[k];
25386 + while (a--)
25387 + {
25388 + /* here i is the Huffman code of length k bits for value *p */
25389 + /* make tables up to required level */
25390 + while (k > w + l)
25391 + {
25392 + h++;
25393 + w += l; /* previous table always l bits */
25394 +
25395 + /* compute minimum size table less than or equal to l bits */
25396 + z = g - w;
25397 + z = z > (uInt)l ? l : z; /* table size upper limit */
25398 + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
25399 + { /* too few codes for k-w bit table */
25400 + f -= a + 1; /* deduct codes from patterns left */
25401 + xp = c + k;
25402 + if (j < z)
25403 + while (++j < z) /* try smaller tables up to z bits */
25404 + {
25405 + if ((f <<= 1) <= *++xp)
25406 + break; /* enough codes to use up j bits */
25407 + f -= *xp; /* else deduct codes from patterns */
25408 + }
25409 + }
25410 + z = 1 << j; /* table entries for j-bit table */
25411 +
25412 + /* allocate new table */
25413 + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
25414 + return Z_DATA_ERROR; /* overflow of MANY */
25415 + u[h] = q = hp + *hn;
25416 + *hn += z;
25417 +
25418 + /* connect to last table, if there is one */
25419 + if (h)
25420 + {
25421 + x[h] = i; /* save pattern for backing up */
25422 + r.bits = (Byte)l; /* bits to dump before this table */
25423 + r.exop = (Byte)j; /* bits in this table */
25424 + j = i >> (w - l);
25425 + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
25426 + u[h-1][j] = r; /* connect to last table */
25427 + }
25428 + else
25429 + *t = q; /* first table is returned result */
25430 + }
25431 +
25432 + /* set up table entry in r */
25433 + r.bits = (Byte)(k - w);
25434 + if (p >= v + n)
25435 + r.exop = 128 + 64; /* out of values--invalid code */
25436 + else if (*p < s)
25437 + {
25438 + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
25439 + r.base = *p++; /* simple code is just the value */
25440 + }
25441 + else
25442 + {
25443 + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
25444 + r.base = d[*p++ - s];
25445 + }
25446 +
25447 + /* fill code-like entries with r */
25448 + f = 1 << (k - w);
25449 + for (j = i >> w; j < z; j += f)
25450 + q[j] = r;
25451 +
25452 + /* backwards increment the k-bit code i */
25453 + for (j = 1 << (k - 1); i & j; j >>= 1)
25454 + i ^= j;
25455 + i ^= j;
25456 +
25457 + /* backup over finished tables */
25458 + mask = (1 << w) - 1; /* needed on HP, cc -O bug */
25459 + while ((i & mask) != x[h])
25460 + {
25461 + h--; /* don't need to update q */
25462 + w -= l;
25463 + mask = (1 << w) - 1;
25464 + }
25465 + }
25466 + }
25467 +
25468 +
25469 + /* Return Z_BUF_ERROR if we were given an incomplete table */
25470 + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
25471 +}
25472 +
25473 +
25474 +int inflate_trees_bits(c, bb, tb, hp, z)
25475 +uIntf *c; /* 19 code lengths */
25476 +uIntf *bb; /* bits tree desired/actual depth */
25477 +inflate_huft * FAR *tb; /* bits tree result */
25478 +inflate_huft *hp; /* space for trees */
25479 +z_streamp z; /* for messages */
25480 +{
25481 + int r;
25482 + uInt hn = 0; /* hufts used in space */
25483 + uIntf *v; /* work area for huft_build */
25484 +
25485 + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
25486 + return Z_MEM_ERROR;
25487 + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
25488 + tb, bb, hp, &hn, v);
25489 + if (r == Z_DATA_ERROR)
25490 + z->msg = (char*)"oversubscribed dynamic bit lengths tree";
25491 + else if (r == Z_BUF_ERROR || *bb == 0)
25492 + {
25493 + z->msg = (char*)"incomplete dynamic bit lengths tree";
25494 + r = Z_DATA_ERROR;
25495 + }
25496 + ZFREE(z, v);
25497 + return r;
25498 +}
25499 +
25500 +
25501 +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
25502 +uInt nl; /* number of literal/length codes */
25503 +uInt nd; /* number of distance codes */
25504 +uIntf *c; /* that many (total) code lengths */
25505 +uIntf *bl; /* literal desired/actual bit depth */
25506 +uIntf *bd; /* distance desired/actual bit depth */
25507 +inflate_huft * FAR *tl; /* literal/length tree result */
25508 +inflate_huft * FAR *td; /* distance tree result */
25509 +inflate_huft *hp; /* space for trees */
25510 +z_streamp z; /* for messages */
25511 +{
25512 + int r;
25513 + uInt hn = 0; /* hufts used in space */
25514 + uIntf *v; /* work area for huft_build */
25515 +
25516 + /* allocate work area */
25517 + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25518 + return Z_MEM_ERROR;
25519 +
25520 + /* build literal/length tree */
25521 + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
25522 + if (r != Z_OK || *bl == 0)
25523 + {
25524 + if (r == Z_DATA_ERROR)
25525 + z->msg = (char*)"oversubscribed literal/length tree";
25526 + else if (r != Z_MEM_ERROR)
25527 + {
25528 + z->msg = (char*)"incomplete literal/length tree";
25529 + r = Z_DATA_ERROR;
25530 + }
25531 + ZFREE(z, v);
25532 + return r;
25533 + }
25534 +
25535 + /* build distance tree */
25536 + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
25537 + if (r != Z_OK || (*bd == 0 && nl > 257))
25538 + {
25539 + if (r == Z_DATA_ERROR)
25540 + z->msg = (char*)"oversubscribed distance tree";
25541 + else if (r == Z_BUF_ERROR) {
25542 +#ifdef PKZIP_BUG_WORKAROUND
25543 + r = Z_OK;
25544 + }
25545 +#else
25546 + z->msg = (char*)"incomplete distance tree";
25547 + r = Z_DATA_ERROR;
25548 + }
25549 + else if (r != Z_MEM_ERROR)
25550 + {
25551 + z->msg = (char*)"empty distance tree with lengths";
25552 + r = Z_DATA_ERROR;
25553 + }
25554 + ZFREE(z, v);
25555 + return r;
25556 +#endif
25557 + }
25558 +
25559 + /* done */
25560 + ZFREE(z, v);
25561 + return Z_OK;
25562 +}
25563 +
25564 +
25565 +/* build fixed tables only once--keep them here */
25566 +#ifdef BUILDFIXED
25567 +local int fixed_built = 0;
25568 +#define FIXEDH 544 /* number of hufts used by fixed tables */
25569 +local inflate_huft fixed_mem[FIXEDH];
25570 +local uInt fixed_bl;
25571 +local uInt fixed_bd;
25572 +local inflate_huft *fixed_tl;
25573 +local inflate_huft *fixed_td;
25574 +#else
25575 +#include "inffixed.h"
25576 +#endif
25577 +
25578 +
25579 +int inflate_trees_fixed(bl, bd, tl, td, z)
25580 +uIntf *bl; /* literal desired/actual bit depth */
25581 +uIntf *bd; /* distance desired/actual bit depth */
25582 +inflate_huft * FAR *tl; /* literal/length tree result */
25583 +inflate_huft * FAR *td; /* distance tree result */
25584 +z_streamp z; /* for memory allocation */
25585 +{
25586 +#ifdef BUILDFIXED
25587 + /* build fixed tables if not already */
25588 + if (!fixed_built)
25589 + {
25590 + int k; /* temporary variable */
25591 + uInt f = 0; /* number of hufts used in fixed_mem */
25592 + uIntf *c; /* length list for huft_build */
25593 + uIntf *v; /* work area for huft_build */
25594 +
25595 + /* allocate memory */
25596 + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25597 + return Z_MEM_ERROR;
25598 + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
25599 + {
25600 + ZFREE(z, c);
25601 + return Z_MEM_ERROR;
25602 + }
25603 +
25604 + /* literal table */
25605 + for (k = 0; k < 144; k++)
25606 + c[k] = 8;
25607 + for (; k < 256; k++)
25608 + c[k] = 9;
25609 + for (; k < 280; k++)
25610 + c[k] = 7;
25611 + for (; k < 288; k++)
25612 + c[k] = 8;
25613 + fixed_bl = 9;
25614 + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
25615 + fixed_mem, &f, v);
25616 +
25617 + /* distance table */
25618 + for (k = 0; k < 30; k++)
25619 + c[k] = 5;
25620 + fixed_bd = 5;
25621 + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
25622 + fixed_mem, &f, v);
25623 +
25624 + /* done */
25625 + ZFREE(z, v);
25626 + ZFREE(z, c);
25627 + fixed_built = 1;
25628 + }
25629 +#endif
25630 + *bl = fixed_bl;
25631 + *bd = fixed_bd;
25632 + *tl = fixed_tl;
25633 + *td = fixed_td;
25634 + return Z_OK;
25635 +}
25636 --- /dev/null Tue Mar 11 13:02:56 2003
25637 +++ linux/net/ipsec/inftrees.h Mon Feb 9 13:51:03 2004
25638 @@ -0,0 +1,63 @@
25639 +/* inftrees.h -- header to use inftrees.c
25640 + * Copyright (C) 1995-2002 Mark Adler
25641 + * For conditions of distribution and use, see copyright notice in zlib.h
25642 + */
25643 +
25644 +/* WARNING: this file should *not* be used by applications. It is
25645 + part of the implementation of the compression library and is
25646 + subject to change. Applications should only use zlib.h.
25647 + */
25648 +
25649 +/* Huffman code lookup table entry--this entry is four bytes for machines
25650 + that have 16-bit pointers (e.g. PC's in the small or medium model). */
25651 +
25652 +#ifndef _INFTREES_H
25653 +#define _INFTREES_H
25654 +
25655 +typedef struct inflate_huft_s FAR inflate_huft;
25656 +
25657 +struct inflate_huft_s {
25658 + union {
25659 + struct {
25660 + Byte Exop; /* number of extra bits or operation */
25661 + Byte Bits; /* number of bits in this code or subcode */
25662 + } what;
25663 + uInt pad; /* pad structure to a power of 2 (4 bytes for */
25664 + } word; /* 16-bit, 8 bytes for 32-bit int's) */
25665 + uInt base; /* literal, length base, distance base,
25666 + or table offset */
25667 +};
25668 +
25669 +/* Maximum size of dynamic tree. The maximum found in a long but non-
25670 + exhaustive search was 1004 huft structures (850 for length/literals
25671 + and 154 for distances, the latter actually the result of an
25672 + exhaustive search). The actual maximum is not known, but the
25673 + value below is more than safe. */
25674 +#define MANY 1440
25675 +
25676 +extern int inflate_trees_bits OF((
25677 + uIntf *, /* 19 code lengths */
25678 + uIntf *, /* bits tree desired/actual depth */
25679 + inflate_huft * FAR *, /* bits tree result */
25680 + inflate_huft *, /* space for trees */
25681 + z_streamp)); /* for messages */
25682 +
25683 +extern int inflate_trees_dynamic OF((
25684 + uInt, /* number of literal/length codes */
25685 + uInt, /* number of distance codes */
25686 + uIntf *, /* that many (total) code lengths */
25687 + uIntf *, /* literal desired/actual bit depth */
25688 + uIntf *, /* distance desired/actual bit depth */
25689 + inflate_huft * FAR *, /* literal/length tree result */
25690 + inflate_huft * FAR *, /* distance tree result */
25691 + inflate_huft *, /* space for trees */
25692 + z_streamp)); /* for messages */
25693 +
25694 +extern int inflate_trees_fixed OF((
25695 + uIntf *, /* literal desired/actual bit depth */
25696 + uIntf *, /* distance desired/actual bit depth */
25697 + inflate_huft * FAR *, /* literal/length tree result */
25698 + inflate_huft * FAR *, /* distance tree result */
25699 + z_streamp)); /* for memory allocation */
25700 +
25701 +#endif /* _INFTREES_H */
25702 --- /dev/null Tue Mar 11 13:02:56 2003
25703 +++ linux/net/ipsec/infutil.c Mon Feb 9 13:51:03 2004
25704 @@ -0,0 +1,87 @@
25705 +/* inflate_util.c -- data and routines common to blocks and codes
25706 + * Copyright (C) 1995-2002 Mark Adler
25707 + * For conditions of distribution and use, see copyright notice in zlib.h
25708 + */
25709 +
25710 +#include <zlib/zutil.h>
25711 +#include "infblock.h"
25712 +#include "inftrees.h"
25713 +#include "infcodes.h"
25714 +#include "infutil.h"
25715 +
25716 +struct inflate_codes_state {int dummy;}; /* for buggy compilers */
25717 +
25718 +/* And'ing with mask[n] masks the lower n bits */
25719 +uInt inflate_mask[17] = {
25720 + 0x0000,
25721 + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
25722 + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
25723 +};
25724 +
25725 +
25726 +/* copy as much as possible from the sliding window to the output area */
25727 +int inflate_flush(s, z, r)
25728 +inflate_blocks_statef *s;
25729 +z_streamp z;
25730 +int r;
25731 +{
25732 + uInt n;
25733 + Bytef *p;
25734 + Bytef *q;
25735 +
25736 + /* local copies of source and destination pointers */
25737 + p = z->next_out;
25738 + q = s->read;
25739 +
25740 + /* compute number of bytes to copy as far as end of window */
25741 + n = (uInt)((q <= s->write ? s->write : s->end) - q);
25742 + if (n > z->avail_out) n = z->avail_out;
25743 + if (n && r == Z_BUF_ERROR) r = Z_OK;
25744 +
25745 + /* update counters */
25746 + z->avail_out -= n;
25747 + z->total_out += n;
25748 +
25749 + /* update check information */
25750 + if (s->checkfn != Z_NULL)
25751 + z->adler = s->check = (*s->checkfn)(s->check, q, n);
25752 +
25753 + /* copy as far as end of window */
25754 + zmemcpy(p, q, n);
25755 + p += n;
25756 + q += n;
25757 +
25758 + /* see if more to copy at beginning of window */
25759 + if (q == s->end)
25760 + {
25761 + /* wrap pointers */
25762 + q = s->window;
25763 + if (s->write == s->end)
25764 + s->write = s->window;
25765 +
25766 + /* compute bytes to copy */
25767 + n = (uInt)(s->write - q);
25768 + if (n > z->avail_out) n = z->avail_out;
25769 + if (n && r == Z_BUF_ERROR) r = Z_OK;
25770 +
25771 + /* update counters */
25772 + z->avail_out -= n;
25773 + z->total_out += n;
25774 +
25775 + /* update check information */
25776 + if (s->checkfn != Z_NULL)
25777 + z->adler = s->check = (*s->checkfn)(s->check, q, n);
25778 +
25779 + /* copy */
25780 + zmemcpy(p, q, n);
25781 + p += n;
25782 + q += n;
25783 + }
25784 +
25785 + /* update pointers */
25786 + z->next_out = p;
25787 + s->read = q;
25788 +
25789 + /* done */
25790 + return r;
25791 +}
25792 --- /dev/null Tue Mar 11 13:02:56 2003
25793 +++ linux/net/ipsec/infutil.h Mon Feb 9 13:51:03 2004
25794 @@ -0,0 +1,98 @@
25795 +/* infutil.h -- types and macros common to blocks and codes
25796 + * Copyright (C) 1995-2002 Mark Adler
25797 + * For conditions of distribution and use, see copyright notice in zlib.h
25798 + */
25799 +
25800 +/* WARNING: this file should *not* be used by applications. It is
25801 + part of the implementation of the compression library and is
25802 + subject to change. Applications should only use zlib.h.
25803 + */
25804 +
25805 +#ifndef _INFUTIL_H
25806 +#define _INFUTIL_H
25807 +
25808 +typedef enum {
25809 + TYPE, /* get type bits (3, including end bit) */
25810 + LENS, /* get lengths for stored */
25811 + STORED, /* processing stored block */
25812 + TABLE, /* get table lengths */
25813 + BTREE, /* get bit lengths tree for a dynamic block */
25814 + DTREE, /* get length, distance trees for a dynamic block */
25815 + CODES, /* processing fixed or dynamic block */
25816 + DRY, /* output remaining window bytes */
25817 + DONE, /* finished last block, done */
25818 + BAD} /* got a data error--stuck here */
25819 +inflate_block_mode;
25820 +
25821 +/* inflate blocks semi-private state */
25822 +struct inflate_blocks_state {
25823 +
25824 + /* mode */
25825 + inflate_block_mode mode; /* current inflate_block mode */
25826 +
25827 + /* mode dependent information */
25828 + union {
25829 + uInt left; /* if STORED, bytes left to copy */
25830 + struct {
25831 + uInt table; /* table lengths (14 bits) */
25832 + uInt index; /* index into blens (or border) */
25833 + uIntf *blens; /* bit lengths of codes */
25834 + uInt bb; /* bit length tree depth */
25835 + inflate_huft *tb; /* bit length decoding tree */
25836 + } trees; /* if DTREE, decoding info for trees */
25837 + struct {
25838 + inflate_codes_statef
25839 + *codes;
25840 + } decode; /* if CODES, current state */
25841 + } sub; /* submode */
25842 + uInt last; /* true if this block is the last block */
25843 +
25844 + /* mode independent information */
25845 + uInt bitk; /* bits in bit buffer */
25846 + uLong bitb; /* bit buffer */
25847 + inflate_huft *hufts; /* single malloc for tree space */
25848 + Bytef *window; /* sliding window */
25849 + Bytef *end; /* one byte after sliding window */
25850 + Bytef *read; /* window read pointer */
25851 + Bytef *write; /* window write pointer */
25852 + check_func checkfn; /* check function */
25853 + uLong check; /* check on output */
25854 +
25855 +};
25856 +
25857 +
25858 +/* defines for inflate input/output */
25859 +/* update pointers and return */
25860 +#define UPDBITS {s->bitb=b;s->bitk=k;}
25861 +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
25862 +#define UPDOUT {s->write=q;}
25863 +#define UPDATE {UPDBITS UPDIN UPDOUT}
25864 +#define LEAVE {UPDATE return inflate_flush(s,z,r);}
25865 +/* get bytes and bits */
25866 +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
25867 +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
25868 +#define NEXTBYTE (n--,*p++)
25869 +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
25870 +#define DUMPBITS(j) {b>>=(j);k-=(j);}
25871 +/* output bytes */
25872 +#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
25873 +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
25874 +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
25875 +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
25876 +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
25877 +#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
25878 +/* load local pointers */
25879 +#define LOAD {LOADIN LOADOUT}
25880 +
25881 +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
25882 +extern uInt inflate_mask[17];
25883 +
25884 +/* copy as much as possible from the sliding window to the output area */
25885 +extern int inflate_flush OF((
25886 + inflate_blocks_statef *,
25887 + z_streamp ,
25888 + int));
25889 +
25890 +struct internal_state {int dummy;}; /* for buggy compilers */
25891 +
25892 +#endif /* _INFUTIL_H */
25893 --- /dev/null Tue Mar 11 13:02:56 2003
25894 +++ linux/net/ipsec/initaddr.c Mon Feb 9 13:51:03 2004
25895 @@ -0,0 +1,50 @@
25896 +/*
25897 + * initialize address structure
25898 + * Copyright (C) 2000 Henry Spencer.
25899 + *
25900 + * This library is free software; you can redistribute it and/or modify it
25901 + * under the terms of the GNU Library General Public License as published by
25902 + * the Free Software Foundation; either version 2 of the License, or (at your
25903 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
25904 + *
25905 + * This library is distributed in the hope that it will be useful, but
25906 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25907 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
25908 + * License for more details.
25909 + *
25910 + * RCSID $Id: initaddr.c,v 1.6 2004/07/10 07:43:47 mcr Exp $
25911 + */
25912 +#include "openswan.h"
25913 +
25914 +/*
25915 + - initaddr - initialize ip_address from bytes
25916 + */
25917 +err_t /* NULL for success, else string literal */
25918 +initaddr(src, srclen, af, dst)
25919 +const unsigned char *src;
25920 +size_t srclen;
25921 +int af; /* address family */
25922 +ip_address *dst;
25923 +{
25924 + switch (af) {
25925 + case AF_INET:
25926 + if (srclen != 4)
25927 + return "IPv4 address must be exactly 4 bytes";
25928 + dst->u.v4.sin_family = af;
25929 + dst->u.v4.sin_port = 0; /* unused */
25930 + memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
25931 + break;
25932 + case AF_INET6:
25933 + if (srclen != 16)
25934 + return "IPv6 address must be exactly 16 bytes";
25935 + dst->u.v6.sin6_family = af;
25936 + dst->u.v6.sin6_flowinfo = 0; /* unused */
25937 + dst->u.v6.sin6_port = 0; /* unused */
25938 + memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
25939 + break;
25940 + default:
25941 + return "unknown address family in initaddr";
25942 + break;
25943 + }
25944 + return NULL;
25945 +}
25946 --- /dev/null Tue Mar 11 13:02:56 2003
25947 +++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004
25948 @@ -0,0 +1,701 @@
25949 +/*
25950 + * IPCOMP zlib interface code.
25951 + * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
25952 + * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
25953 + *
25954 + * This program is free software; you can redistribute it and/or modify it
25955 + * under the terms of the GNU General Public License as published by the
25956 + * Free Software Foundation; either version 2 of the License, or (at your
25957 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
25958 + *
25959 + * This program is distributed in the hope that it will be useful, but
25960 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25961 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25962 + * for more details.
25963 + */
25964 +
25965 +char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.41.2.5 2006/10/06 21:39:26 paul Exp $";
25966 +
25967 +/* SSS */
25968 +
25969 +#ifndef AUTOCONF_INCLUDED
25970 +#include <linux/config.h>
25971 +#endif
25972 +#include <linux/version.h>
25973 +
25974 +#define __NO_VERSION__
25975 +#include <linux/module.h>
25976 +#include <linux/kernel.h> /* printk() */
25977 +
25978 +#include "openswan/ipsec_param.h"
25979 +
25980 +#ifdef MALLOC_SLAB
25981 +# include <linux/slab.h> /* kmalloc() */
25982 +#else /* MALLOC_SLAB */
25983 +# include <linux/malloc.h> /* kmalloc() */
25984 +#endif /* MALLOC_SLAB */
25985 +#include <linux/errno.h> /* error codes */
25986 +#include <linux/types.h>
25987 +#include <linux/netdevice.h>
25988 +#include <linux/ip.h>
25989 +#include <linux/skbuff.h>
25990 +
25991 +#include <linux/netdevice.h> /* struct device, and other headers */
25992 +#include <linux/etherdevice.h> /* eth_type_trans */
25993 +#include <linux/ip.h> /* struct iphdr */
25994 +#include <linux/skbuff.h>
25995 +#include <asm/uaccess.h>
25996 +#include <asm/checksum.h>
25997 +
25998 +#include <openswan.h>
25999 +
26000 +#include <net/ip.h>
26001 +
26002 +#include "openswan/radij.h"
26003 +#include "openswan/ipsec_encap.h"
26004 +#include "openswan/ipsec_sa.h"
26005 +
26006 +#include "openswan/ipsec_xform.h"
26007 +#include "openswan/ipsec_tunnel.h"
26008 +#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
26009 +#include "openswan/ipsec_proto.h"
26010 +#include "openswan/ipcomp.h"
26011 +#include "zlib/zlib.h"
26012 +#include "zlib/zutil.h"
26013 +
26014 +#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
26015 +
26016 +#ifdef CONFIG_KLIPS_DEBUG
26017 +int sysctl_ipsec_debug_ipcomp = 0;
26018 +#endif /* CONFIG_KLIPS_DEBUG */
26019 +
26020 +static
26021 +struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
26022 +
26023 +static
26024 +voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
26025 +{
26026 + return (voidpf) kmalloc(items*size, GFP_ATOMIC);
26027 +}
26028 +
26029 +static
26030 +void my_zfree(voidpf opaque, voidpf address)
26031 +{
26032 + kfree(address);
26033 +}
26034 +
26035 +/*
26036 + * We use this function because sometimes we want to pass a negative offset
26037 + * into skb_put(), this does not work on 64bit platforms because long to
26038 + * unsigned int casting.
26039 + */
26040 +static inline unsigned char *
26041 +safe_skb_put(struct sk_buff *skb, int extend)
26042 +{
26043 + unsigned char *ptr;
26044 +
26045 + if (extend>0) {
26046 + // increase the size of the packet
26047 + ptr = skb_put(skb, extend);
26048 + } else {
26049 + // shrink the size of the packet
26050 + ptr = skb->tail;
26051 + skb_trim (skb, skb->len + extend);
26052 + }
26053 +
26054 + return ptr;
26055 +}
26056 +
26057 +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
26058 +{
26059 + struct iphdr *iph;
26060 + unsigned int iphlen, pyldsz, cpyldsz;
26061 + unsigned char *buffer;
26062 + z_stream zs;
26063 + int zresult;
26064 +
26065 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26066 + "klips_debug:skb_compress: .\n");
26067 +
26068 + if(skb == NULL) {
26069 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26070 + "klips_debug:skb_compress: "
26071 + "passed in NULL skb, returning ERROR.\n");
26072 + if(flags != NULL) {
26073 + *flags |= IPCOMP_PARMERROR;
26074 + }
26075 + return skb;
26076 + }
26077 +
26078 + if(ips == NULL) {
26079 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26080 + "klips_debug:skb_compress: "
26081 + "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
26082 + if(flags) {
26083 + *flags |= IPCOMP_PARMERROR;
26084 + }
26085 + return skb;
26086 + }
26087 +
26088 + if (flags == NULL) {
26089 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26090 + "klips_debug:skb_compress: "
26091 + "passed in NULL flags, returning ERROR.\n");
26092 + ipsec_kfree_skb(skb);
26093 + return NULL;
26094 + }
26095 +
26096 +#ifdef NET_21
26097 + iph = skb->nh.iph;
26098 +#else /* NET_21 */
26099 + iph = skb->ip_hdr;
26100 +#endif /* NET_21 */
26101 +
26102 + switch (iph->protocol) {
26103 + case IPPROTO_COMP:
26104 + case IPPROTO_AH:
26105 + case IPPROTO_ESP:
26106 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26107 + "klips_debug:skb_compress: "
26108 + "skipping compression of packet with ip protocol %d.\n",
26109 + iph->protocol);
26110 + *flags |= IPCOMP_UNCOMPRESSABLE;
26111 + return skb;
26112 + }
26113 +
26114 + /* Don't compress packets already fragmented */
26115 + if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
26116 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26117 + "klips_debug:skb_compress: "
26118 + "skipping compression of fragmented packet.\n");
26119 + *flags |= IPCOMP_UNCOMPRESSABLE;
26120 + return skb;
26121 + }
26122 +
26123 + iphlen = iph->ihl << 2;
26124 + pyldsz = ntohs(iph->tot_len) - iphlen;
26125 +
26126 + /* Don't compress less than 90 bytes (rfc 2394) */
26127 + if (pyldsz < 90) {
26128 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26129 + "klips_debug:skb_compress: "
26130 + "skipping compression of tiny packet, len=%d.\n",
26131 + pyldsz);
26132 + *flags |= IPCOMP_UNCOMPRESSABLE;
26133 + return skb;
26134 + }
26135 +
26136 + /* Adaptive decision */
26137 + if (ips->ips_comp_adapt_skip) {
26138 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26139 + "klips_debug:skb_compress: "
26140 + "skipping compression: ips_comp_adapt_skip=%d.\n",
26141 + ips->ips_comp_adapt_skip);
26142 + ips->ips_comp_adapt_skip--;
26143 + *flags |= IPCOMP_UNCOMPRESSABLE;
26144 + return skb;
26145 + }
26146 +
26147 + zs.zalloc = my_zcalloc;
26148 + zs.zfree = my_zfree;
26149 + zs.opaque = 0;
26150 +
26151 + /* We want to use deflateInit2 because we don't want the adler
26152 + header. */
26153 + zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
26154 + DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
26155 + if (zresult != Z_OK) {
26156 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26157 + "klips_error:skb_compress: "
26158 + "deflateInit2() returned error %d (%s), "
26159 + "skipping compression.\n",
26160 + zresult,
26161 + zs.msg ? zs.msg : zError(zresult));
26162 + *flags |= IPCOMP_COMPRESSIONERROR;
26163 + return skb;
26164 + }
26165 +
26166 +
26167 + /* Max output size. Result should be max this size.
26168 + * Implementation specific tweak:
26169 + * If it's not at least 32 bytes and 6.25% smaller than
26170 + * the original packet, it's probably not worth wasting
26171 + * the receiver's CPU cycles decompressing it.
26172 + * Your mileage may vary.
26173 + */
26174 + cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
26175 +
26176 + buffer = kmalloc(cpyldsz, GFP_ATOMIC);
26177 + if (!buffer) {
26178 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26179 + "klips_error:skb_compress: "
26180 + "unable to kmalloc(%d, GFP_ATOMIC), "
26181 + "skipping compression.\n",
26182 + cpyldsz);
26183 + *flags |= IPCOMP_COMPRESSIONERROR;
26184 + deflateEnd(&zs);
26185 + return skb;
26186 + }
26187 +
26188 +#ifdef CONFIG_KLIPS_DEBUG
26189 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26190 + __u8 *c;
26191 +
26192 + c = (__u8*)iph + iphlen;
26193 + ipsec_dmp_block("compress before", c, pyldsz);
26194 + }
26195 +#endif /* CONFIG_KLIPS_DEBUG */
26196 +
26197 + zs.next_in = (char *) iph + iphlen; /* start of payload */
26198 + zs.avail_in = pyldsz;
26199 + zs.next_out = buffer; /* start of compressed payload */
26200 + zs.avail_out = cpyldsz;
26201 +
26202 + /* Finish compression in one step */
26203 + zresult = deflate(&zs, Z_FINISH);
26204 +
26205 + /* Free all dynamically allocated buffers */
26206 + deflateEnd(&zs);
26207 + if (zresult != Z_STREAM_END) {
26208 + *flags |= IPCOMP_UNCOMPRESSABLE;
26209 + kfree(buffer);
26210 +
26211 + /* Adjust adaptive counters */
26212 + if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
26213 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26214 + "klips_debug:skb_compress: "
26215 + "first %d packets didn't compress, "
26216 + "skipping next %d\n",
26217 + IPCOMP_ADAPT_INITIAL_TRIES,
26218 + IPCOMP_ADAPT_INITIAL_SKIP);
26219 + ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
26220 + }
26221 + else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
26222 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26223 + "klips_debug:skb_compress: "
26224 + "next %d packets didn't compress, "
26225 + "skipping next %d\n",
26226 + IPCOMP_ADAPT_SUBSEQ_TRIES,
26227 + IPCOMP_ADAPT_SUBSEQ_SKIP);
26228 + ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
26229 + ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
26230 + }
26231 +
26232 + return skb;
26233 + }
26234 +
26235 + /* resulting compressed size */
26236 + cpyldsz -= zs.avail_out;
26237 +
26238 + /* Insert IPCOMP header */
26239 + ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
26240 + ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
26241 + /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
26242 + for internal reference only. */
26243 + ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
26244 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26245 + "klips_debug:skb_compress: "
26246 + "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
26247 + ntohl(ips->ips_said.spi),
26248 + ntohl(ips->ips_said.spi) & 0x0000ffff,
26249 + ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
26250 + pyldsz,
26251 + cpyldsz);
26252 +
26253 + /* Update IP header */
26254 + iph->protocol = IPPROTO_COMP;
26255 + iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
26256 +#if 1 /* XXX checksum is done by ipsec_tunnel ? */
26257 + iph->check = 0;
26258 + iph->check = ip_fast_csum((char *) iph, iph->ihl);
26259 +#endif
26260 +
26261 + /* Copy compressed payload */
26262 + memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
26263 + buffer,
26264 + cpyldsz);
26265 + kfree(buffer);
26266 +
26267 + /* Update skb length/tail by "unputting" the shrinkage */
26268 + safe_skb_put (skb, cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
26269 +
26270 +#ifdef CONFIG_KLIPS_DEBUG
26271 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26272 + __u8 *c;
26273 +
26274 + c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
26275 + ipsec_dmp_block("compress result", c, cpyldsz);
26276 + }
26277 +#endif /* CONFIG_KLIPS_DEBUG */
26278 +
26279 + ips->ips_comp_adapt_skip = 0;
26280 + ips->ips_comp_adapt_tries = 0;
26281 +
26282 + return skb;
26283 +}
26284 +
26285 +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
26286 +{
26287 + struct sk_buff *nskb = NULL;
26288 +
26289 + /* original ip header */
26290 + struct iphdr *oiph, *iph;
26291 + unsigned int iphlen, pyldsz, cpyldsz;
26292 + z_stream zs;
26293 + int zresult;
26294 +
26295 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26296 + "klips_debug:skb_decompress: .\n");
26297 +
26298 + if(!skb) {
26299 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26300 + "klips_error:skb_decompress: "
26301 + "passed in NULL skb, returning ERROR.\n");
26302 + if (flags) *flags |= IPCOMP_PARMERROR;
26303 + return skb;
26304 + }
26305 +
26306 + if(!ips && sysctl_ipsec_inbound_policy_check) {
26307 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26308 + "klips_error:skb_decompress: "
26309 + "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
26310 + if (flags) *flags |= IPCOMP_PARMERROR;
26311 + return skb;
26312 + }
26313 +
26314 + if (!flags) {
26315 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26316 + "klips_error:skb_decompress: "
26317 + "passed in NULL flags, returning ERROR.\n");
26318 + ipsec_kfree_skb(skb);
26319 + return NULL;
26320 + }
26321 +
26322 +#ifdef NET_21
26323 + oiph = skb->nh.iph;
26324 +#else /* NET_21 */
26325 + oiph = skb->ip_hdr;
26326 +#endif /* NET_21 */
26327 +
26328 + iphlen = oiph->ihl << 2;
26329 +
26330 + if (oiph->protocol != IPPROTO_COMP) {
26331 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26332 + "klips_error:skb_decompress: "
26333 + "called with non-IPCOMP packet (protocol=%d),"
26334 + "skipping decompression.\n",
26335 + oiph->protocol);
26336 + *flags |= IPCOMP_PARMERROR;
26337 + return skb;
26338 + }
26339 +
26340 + if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
26341 + || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
26342 + != htons(SADB_X_CALG_DEFLATE))
26343 + && sysctl_ipsec_inbound_policy_check
26344 + && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
26345 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26346 + "klips_error:skb_decompress: "
26347 + "called with incompatible IPCOMP packet (flags=%d, "
26348 + "cpi=%d), ips-compalg=%d, skipping decompression.\n",
26349 + ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
26350 + ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
26351 + ips ? ips->ips_encalg : 0);
26352 + *flags |= IPCOMP_PARMERROR;
26353 +
26354 + return skb;
26355 + }
26356 +
26357 + if (ntohs(oiph->frag_off) & ~0x4000) {
26358 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26359 + "klips_error:skb_decompress: "
26360 + "called with fragmented IPCOMP packet, "
26361 + "skipping decompression.\n");
26362 + *flags |= IPCOMP_PARMERROR;
26363 + return skb;
26364 + }
26365 +
26366 + /* original compressed payload size */
26367 + cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
26368 +
26369 + zs.zalloc = my_zcalloc;
26370 + zs.zfree = my_zfree;
26371 + zs.opaque = 0;
26372 +
26373 + zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
26374 + zs.avail_in = cpyldsz;
26375 +
26376 + /* Maybe we should be a bit conservative about memory
26377 + requirements and use inflateInit2 */
26378 + /* Beware, that this might make us unable to decompress packets
26379 + from other implementations - HINT: check PGPnet source code */
26380 + /* We want to use inflateInit2 because we don't want the adler
26381 + header. */
26382 + zresult = inflateInit2(&zs, -15);
26383 + if (zresult != Z_OK) {
26384 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26385 + "klips_error:skb_decompress: "
26386 + "inflateInit2() returned error %d (%s), "
26387 + "skipping decompression.\n",
26388 + zresult,
26389 + zs.msg ? zs.msg : zError(zresult));
26390 + *flags |= IPCOMP_DECOMPRESSIONERROR;
26391 +
26392 + return skb;
26393 + }
26394 +
26395 + /* We have no way of knowing the exact length of the resulting
26396 + decompressed output before we have actually done the decompression.
26397 + For now, we guess that the packet will not be bigger than the
26398 + attached ipsec device's mtu or 16260, whichever is biggest.
26399 + This may be wrong, since the sender's mtu may be bigger yet.
26400 + XXX This must be dealt with later XXX
26401 + */
26402 +
26403 + /* max payload size */
26404 + pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
26405 + : (65520 - iphlen);
26406 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26407 + "klips_debug:skb_decompress: "
26408 + "max payload size: %d\n", pyldsz);
26409 +
26410 + while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
26411 + (nskb = skb_copy_ipcomp(skb,
26412 + pyldsz - cpyldsz - sizeof(struct ipcomphdr),
26413 + GFP_ATOMIC)) == NULL) {
26414 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26415 + "klips_error:skb_decompress: "
26416 + "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
26417 + "trying with less payload size.\n",
26418 + (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
26419 + pyldsz >>=1;
26420 + }
26421 +
26422 + if (!nskb) {
26423 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26424 + "klips_error:skb_decompress: "
26425 + "unable to allocate memory, dropping packet.\n");
26426 + *flags |= IPCOMP_DECOMPRESSIONERROR;
26427 + inflateEnd(&zs);
26428 +
26429 + return skb;
26430 + }
26431 +
26432 +#ifdef CONFIG_KLIPS_DEBUG
26433 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26434 + __u8 *c;
26435 +
26436 + c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
26437 + ipsec_dmp_block("decompress before", c, cpyldsz);
26438 + }
26439 +#endif /* CONFIG_KLIPS_DEBUG */
26440 +
26441 +#ifdef NET_21
26442 + iph = nskb->nh.iph;
26443 +#else /* NET_21 */
26444 + iph = nskb->ip_hdr;
26445 +#endif /* NET_21 */
26446 + zs.next_out = (char *)iph + iphlen;
26447 + zs.avail_out = pyldsz;
26448 +
26449 + zresult = inflate(&zs, Z_SYNC_FLUSH);
26450 +
26451 + /* work around a bug in zlib, which sometimes wants to taste an extra
26452 + * byte when being used in the (undocumented) raw deflate mode.
26453 + */
26454 + if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
26455 + __u8 zerostuff = 0;
26456 +
26457 + zs.next_in = &zerostuff;
26458 + zs.avail_in = 1;
26459 + zresult = inflate(&zs, Z_FINISH);
26460 + }
26461 +
26462 + inflateEnd(&zs);
26463 + if (zresult != Z_STREAM_END) {
26464 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26465 + "klips_error:skb_decompress: "
26466 + "inflate() returned error %d (%s), "
26467 + "skipping decompression.\n",
26468 + zresult,
26469 + zs.msg ? zs.msg : zError(zresult));
26470 + *flags |= IPCOMP_DECOMPRESSIONERROR;
26471 + ipsec_kfree_skb(nskb);
26472 +
26473 + return skb;
26474 + }
26475 +
26476 + /* Update IP header */
26477 + /* resulting decompressed size */
26478 + pyldsz -= zs.avail_out;
26479 + iph->tot_len = htons(iphlen + pyldsz);
26480 + iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
26481 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26482 + "klips_debug:skb_decompress: "
26483 + "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
26484 + ips ? ntohl(ips->ips_said.spi) : 0,
26485 + ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
26486 + ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
26487 + cpyldsz,
26488 + pyldsz,
26489 + iph->protocol);
26490 +
26491 +#if 1 /* XXX checksum is done by ipsec_rcv ? */
26492 + iph->check = 0;
26493 + iph->check = ip_fast_csum((char*) iph, iph->ihl);
26494 +#endif
26495 +
26496 + /* Update skb length/tail by "unputting" the unused data area */
26497 + safe_skb_put(nskb, -zs.avail_out);
26498 +
26499 + ipsec_kfree_skb(skb);
26500 +
26501 + if (iph->protocol == IPPROTO_COMP)
26502 + {
26503 +#ifdef CONFIG_KLIPS_DEBUG
26504 + if(sysctl_ipsec_debug_ipcomp)
26505 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26506 + "klips_debug:skb_decompress: "
26507 + "Eh? inner packet is also compressed, dropping.\n");
26508 +#endif /* CONFIG_KLIPS_DEBUG */
26509 +
26510 + ipsec_kfree_skb(nskb);
26511 + return NULL;
26512 + }
26513 +
26514 +#ifdef CONFIG_KLIPS_DEBUG
26515 + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
26516 + __u8 *c;
26517 +
26518 + c = (__u8*)iph + iphlen;
26519 + ipsec_dmp_block("decompress result", c, pyldsz);
26520 + }
26521 +#endif /* CONFIG_KLIPS_DEBUG */
26522 +
26523 + return nskb;
26524 +}
26525 +
26526 +
26527 +/* this is derived from skb_copy() in linux 2.2.14 */
26528 +/* May be incompatible with other kernel versions!! */
26529 +static
26530 +struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
26531 +{
26532 + struct sk_buff *n;
26533 + struct iphdr *iph;
26534 + unsigned long offset;
26535 + unsigned int iphlen;
26536 +
26537 + if(!skb) {
26538 + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
26539 + "klips_debug:skb_copy_ipcomp: "
26540 + "passed in NULL skb, returning NULL.\n");
26541 + return NULL;
26542 + }
26543 +
26544 + /*
26545 + * Allocate the copy buffer
26546 + */
26547 +
26548 +#ifdef NET_21
26549 + iph = skb->nh.iph;
26550 +#else /* NET_21 */
26551 + iph = skb->ip_hdr;
26552 +#endif /* NET_21 */
26553 + if (!iph) return NULL;
26554 + iphlen = iph->ihl << 2;
26555 +
26556 + n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
26557 + if(n==NULL)
26558 + return NULL;
26559 +
26560 + /*
26561 + * Shift between the two data areas in bytes
26562 + */
26563 +
26564 + offset=n->head-skb->head;
26565 +
26566 + /* Set the data pointer */
26567 + skb_reserve(n,skb->data-skb->head);
26568 + /* Set the tail pointer and length */
26569 + safe_skb_put(n,skb->len+data_growth);
26570 + /* Copy the bytes up to and including the ip header */
26571 + memcpy(n->head,
26572 + skb->head,
26573 + ((char *)iph - (char *)skb->head) + iphlen);
26574 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)
26575 + n->list=NULL;
26576 +#endif
26577 + n->next=NULL;
26578 + n->prev=NULL;
26579 + n->sk=NULL;
26580 + n->dev=skb->dev;
26581 + if (skb->h.raw)
26582 + n->h.raw=skb->h.raw+offset;
26583 + else
26584 + n->h.raw=NULL;
26585 + n->protocol=skb->protocol;
26586 +#ifdef NET_21
26587 + n->csum = 0;
26588 + n->priority=skb->priority;
26589 + n->dst=dst_clone(skb->dst);
26590 + n->nh.raw=skb->nh.raw+offset;
26591 +#ifndef NETDEV_23
26592 + n->is_clone=0;
26593 +#endif /* NETDEV_23 */
26594 + atomic_set(&n->users, 1);
26595 + n->destructor = NULL;
26596 +#ifdef HAVE_SOCK_SECURITY
26597 + n->security=skb->security;
26598 +#endif
26599 + memcpy(n->cb, skb->cb, sizeof(skb->cb));
26600 +#ifdef CONFIG_IP_FIREWALL
26601 + n->fwmark = skb->fwmark;
26602 +#endif
26603 +#else /* NET_21 */
26604 + n->link3=NULL;
26605 + n->when=skb->when;
26606 + n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
26607 + n->saddr=skb->saddr;
26608 + n->daddr=skb->daddr;
26609 + n->raddr=skb->raddr;
26610 + n->seq=skb->seq;
26611 + n->end_seq=skb->end_seq;
26612 + n->ack_seq=skb->ack_seq;
26613 + n->acked=skb->acked;
26614 + n->free=1;
26615 + n->arp=skb->arp;
26616 + n->tries=0;
26617 + n->lock=0;
26618 + n->users=0;
26619 + memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
26620 +#endif /* NET_21 */
26621 + if (skb->mac.raw)
26622 + n->mac.raw=skb->mac.raw+offset;
26623 + else
26624 + n->mac.raw=NULL;
26625 +#ifndef NETDEV_23
26626 + n->used=skb->used;
26627 +#endif /* !NETDEV_23 */
26628 + n->pkt_type=skb->pkt_type;
26629 +#ifndef NETDEV_23
26630 + n->pkt_bridged=skb->pkt_bridged;
26631 +#endif /* NETDEV_23 */
26632 + n->ip_summed=0;
26633 +#ifdef HAVE_TSTAMP
26634 + n->tstamp = skb->tstamp;
26635 +#else
26636 + n->stamp=skb->stamp;
26637 +#endif
26638 +#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
26639 +#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
26640 + n->shapelatency=skb->shapelatency; /* Latency on frame */
26641 + n->shapeclock=skb->shapeclock; /* Time it should go out */
26642 + n->shapelen=skb->shapelen; /* Frame length in clocks */
26643 + n->shapestamp=skb->shapestamp; /* Stamp for shaper */
26644 + n->shapepend=skb->shapepend; /* Pending */
26645 +#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
26646 +#endif /* NETDEV_23 */
26647 +
26648 + return n;
26649 +}
26650 --- /dev/null Tue Mar 11 13:02:56 2003
26651 +++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004
26652 @@ -0,0 +1,407 @@
26653 +/*
26654 + * processing code for AH
26655 + * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com>
26656 + *
26657 + * This program is free software; you can redistribute it and/or modify it
26658 + * under the terms of the GNU General Public License as published by the
26659 + * Free Software Foundation; either version 2 of the License, or (at your
26660 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
26661 + *
26662 + * This program is distributed in the hope that it will be useful, but
26663 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26664 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26665 + * for more details.
26666 + */
26667 +
26668 +char ipsec_ah_c_version[] = "RCSID $Id: ipsec_ah.c,v 1.12.2.2 2006/10/06 21:39:26 paul Exp $";
26669 +#ifndef AUTOCONF_INCLUDED
26670 +#include <linux/config.h>
26671 +#endif
26672 +#include <linux/version.h>
26673 +
26674 +#define __NO_VERSION__
26675 +#include <linux/module.h>
26676 +#include <linux/kernel.h> /* printk() */
26677 +
26678 +#include "openswan/ipsec_param.h"
26679 +
26680 +#ifdef MALLOC_SLAB
26681 +# include <linux/slab.h> /* kmalloc() */
26682 +#else /* MALLOC_SLAB */
26683 +# include <linux/malloc.h> /* kmalloc() */
26684 +#endif /* MALLOC_SLAB */
26685 +#include <linux/errno.h> /* error codes */
26686 +#include <linux/types.h> /* size_t */
26687 +#include <linux/interrupt.h> /* mark_bh */
26688 +
26689 +#include <linux/netdevice.h> /* struct device, and other headers */
26690 +#include <linux/etherdevice.h> /* eth_type_trans */
26691 +#include <linux/ip.h> /* struct iphdr */
26692 +#include <linux/skbuff.h>
26693 +#include <openswan.h>
26694 +#ifdef SPINLOCK
26695 +# ifdef SPINLOCK_23
26696 +# include <linux/spinlock.h> /* *lock* */
26697 +# else /* SPINLOCK_23 */
26698 +# include <asm/spinlock.h> /* *lock* */
26699 +# endif /* SPINLOCK_23 */
26700 +#endif /* SPINLOCK */
26701 +
26702 +#include <net/ip.h>
26703 +#include <net/protocol.h>
26704 +
26705 +#include "openswan/radij.h"
26706 +#include "openswan/ipsec_encap.h"
26707 +#include "openswan/ipsec_sa.h"
26708 +
26709 +#include "openswan/ipsec_radij.h"
26710 +#include "openswan/ipsec_xform.h"
26711 +#include "openswan/ipsec_tunnel.h"
26712 +#include "openswan/ipsec_rcv.h"
26713 +#include "openswan/ipsec_xmit.h"
26714 +
26715 +#include "openswan/ipsec_auth.h"
26716 +#include "openswan/ipsec_ah.h"
26717 +#include "openswan/ipsec_proto.h"
26718 +
26719 +__u32 zeroes[AH_AMAX];
26720 +
26721 +enum ipsec_rcv_value
26722 +ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
26723 + struct sk_buff *skb)
26724 +{
26725 + int ahminlen;
26726 +
26727 + ahminlen = irs->hard_header_len + sizeof(struct iphdr);
26728 +
26729 + /* take care not to deref this pointer until we check the minlen though */
26730 + irs->protostuff.ahstuff.ahp = (struct ahhdr *)skb->h.raw;
26731 +
26732 + if((skb->len < ahminlen+sizeof(struct ahhdr)) ||
26733 + (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
26734 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26735 + "klips_debug:ipsec_rcv: "
26736 + "runt ah packet of skb->len=%d received from %s, dropped.\n",
26737 + skb->len,
26738 + irs->ipsaddr_txt);
26739 + if(irs->stats) {
26740 + irs->stats->rx_errors++;
26741 + }
26742 + return IPSEC_RCV_BADLEN;
26743 + }
26744 +
26745 + irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
26746 +
26747 + /* XXX we only support the one 12-byte authenticator for now */
26748 + if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
26749 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
26750 + "klips_debug:ipsec_rcv: "
26751 + "bad authenticator length %ld, expected %lu from %s.\n",
26752 + (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
26753 + (unsigned long) sizeof(struct ahhdr),
26754 + irs->ipsaddr_txt);
26755 + if(irs->stats) {
26756 + irs->stats->rx_errors++;
26757 + }
26758 + return IPSEC_RCV_BADLEN;
26759 + }
26760 +
26761 + return IPSEC_RCV_OK;
26762 +}
26763 +
26764 +
26765 +enum ipsec_rcv_value
26766 +ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
26767 + struct sk_buff *skb,
26768 + __u32 *replay,
26769 + unsigned char **authenticator)
26770 +{
26771 + struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26772 +
26773 + *replay = ntohl(ahp->ah_rpl);
26774 + *authenticator = ahp->ah_data;
26775 +
26776 + return IPSEC_RCV_OK;
26777 +}
26778 +
26779 +enum ipsec_rcv_value
26780 +ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
26781 + struct sk_buff *skb)
26782 +{
26783 + struct auth_alg *aa;
26784 + struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26785 + union {
26786 + MD5_CTX md5;
26787 + SHA1_CTX sha1;
26788 + } tctx;
26789 + struct iphdr ipo;
26790 + int ahhlen;
26791 +
26792 + aa = irs->authfuncs;
26793 +
26794 + /* copy the initialized keying material */
26795 + memcpy(&tctx, irs->ictx, irs->ictx_len);
26796 +
26797 + ipo = *irs->ipp;
26798 + ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
26799 + ipo.frag_off = 0;
26800 + ipo.ttl = 0;
26801 + ipo.check = 0;
26802 +
26803 +
26804 + /* do the sanitized header */
26805 + (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
26806 +
26807 + /* XXX we didn't do the options here! */
26808 +
26809 + /* now do the AH header itself */
26810 + ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26811 + (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN);
26812 +
26813 + /* now, do some zeroes */
26814 + (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN);
26815 +
26816 + /* finally, do the packet contents themselves */
26817 + (*aa->update)((void*)&tctx,
26818 + (caddr_t)skb->h.raw + ahhlen,
26819 + skb->len - ahhlen);
26820 +
26821 + (*aa->final)(irs->hash, (void *)&tctx);
26822 +
26823 + memcpy(&tctx, irs->octx, irs->octx_len);
26824 +
26825 + (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
26826 + (*aa->final)(irs->hash, (void *)&tctx);
26827 +
26828 + return IPSEC_RCV_OK;
26829 +}
26830 +
26831 +enum ipsec_rcv_value
26832 +ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
26833 +{
26834 + struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
26835 + struct sk_buff *skb;
26836 + int ahhlen;
26837 +
26838 + skb=irs->skb;
26839 +
26840 + ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
26841 +
26842 + irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
26843 + irs->next_header = ahp->ah_nh;
26844 +
26845 + /*
26846 + * move the IP header forward by the size of the AH header, which
26847 + * will remove the the AH header from the packet.
26848 + */
26849 + memmove((void *)(skb->nh.raw + ahhlen),
26850 + (void *)(skb->nh.raw), irs->iphlen);
26851 +
26852 + ipsec_rcv_dmp("ah postmove", skb->data, skb->len);
26853 +
26854 + /* skb_pull below, will move up by ahhlen */
26855 +
26856 + /* XXX not clear how this can happen, as the message indicates */
26857 + if(skb->len < ahhlen) {
26858 + printk(KERN_WARNING
26859 + "klips_error:ipsec_rcv: "
26860 + "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n",
26861 + ahhlen,
26862 + (int)(skb->len));
26863 + return IPSEC_RCV_DECAPFAIL;
26864 + }
26865 + skb_pull(skb, ahhlen);
26866 +
26867 + skb->nh.raw = skb->nh.raw + ahhlen;
26868 + irs->ipp = skb->nh.iph;
26869 +
26870 + ipsec_rcv_dmp("ah postpull", (void *)skb->nh.iph, skb->len);
26871 +
26872 + return IPSEC_RCV_OK;
26873 +}
26874 +
26875 +enum ipsec_xmit_value
26876 +ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs)
26877 +{
26878 + struct iphdr ipo;
26879 + struct ahhdr *ahp;
26880 + __u8 hash[AH_AMAX];
26881 + union {
26882 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26883 + MD5_CTX md5;
26884 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26885 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26886 + SHA1_CTX sha1;
26887 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26888 + } tctx;
26889 + unsigned char *dat = (unsigned char *)ixs->iph;
26890 +
26891 + ahp = (struct ahhdr *)(dat + ixs->iphlen);
26892 + ahp->ah_spi = ixs->ipsp->ips_said.spi;
26893 + ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
26894 + ahp->ah_rv = 0;
26895 + ahp->ah_nh = ixs->iph->protocol;
26896 + ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32);
26897 + ixs->iph->protocol = IPPROTO_AH;
26898 + ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp));
26899 +
26900 + ipo = *ixs->iph;
26901 + ipo.tos = 0;
26902 + ipo.frag_off = 0;
26903 + ipo.ttl = 0;
26904 + ipo.check = 0;
26905 + ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo));
26906 +
26907 + switch(ixs->ipsp->ips_authalg) {
26908 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
26909 + case AH_MD5:
26910 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26911 + ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
26912 + osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
26913 + ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
26914 + osMD5Update(&tctx.md5, (unsigned char *)ahp,
26915 + sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26916 + ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
26917 + osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26918 + ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
26919 + osMD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr),
26920 + ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26921 + ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
26922 + osMD5Final(hash, &tctx.md5);
26923 + ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
26924 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
26925 + ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
26926 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
26927 + ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
26928 + osMD5Final(hash, &tctx.md5);
26929 + ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
26930 +
26931 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26932 +
26933 + /* paranoid */
26934 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
26935 + memset((caddr_t)hash, 0, sizeof(*hash));
26936 + break;
26937 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
26938 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
26939 + case AH_SHA:
26940 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
26941 + SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
26942 + SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data));
26943 + SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
26944 + SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr),
26945 + ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
26946 + SHA1Final(hash, &tctx.sha1);
26947 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
26948 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
26949 + SHA1Final(hash, &tctx.sha1);
26950 +
26951 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
26952 +
26953 + /* paranoid */
26954 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
26955 + memset((caddr_t)hash, 0, sizeof(*hash));
26956 + break;
26957 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
26958 + default:
26959 + ixs->stats->tx_errors++;
26960 + return IPSEC_XMIT_AH_BADALG;
26961 + }
26962 +#ifdef NET_21
26963 + ixs->skb->h.raw = (unsigned char*)ahp;
26964 +#endif /* NET_21 */
26965 +
26966 + return IPSEC_XMIT_OK;
26967 +}
26968 +
26969 +struct xform_functions ah_xform_funcs[]={
26970 + { rcv_checks: ipsec_rcv_ah_checks,
26971 + rcv_setup_auth: ipsec_rcv_ah_setup_auth,
26972 + rcv_calc_auth: ipsec_rcv_ah_authcalc,
26973 + rcv_decrypt: ipsec_rcv_ah_decap,
26974 +
26975 + xmit_setup: ipsec_xmit_ah_setup,
26976 + xmit_headroom: sizeof(struct ahhdr),
26977 + xmit_needtailroom: 0,
26978 + },
26979 +};
26980 +
26981 +
26982 +#ifdef NET_26
26983 +struct inet_protocol ah_protocol = {
26984 + .handler = ipsec_rcv,
26985 + .no_policy = 1,
26986 +};
26987 +#else
26988 +struct inet_protocol ah_protocol =
26989 +{
26990 + ipsec_rcv, /* AH handler */
26991 + NULL, /* TUNNEL error control */
26992 +#ifdef NETDEV_25
26993 + 1, /* no policy */
26994 +#else
26995 + 0, /* next */
26996 + IPPROTO_AH, /* protocol ID */
26997 + 0, /* copy */
26998 + NULL, /* data */
26999 + "AH" /* name */
27000 +#endif
27001 +};
27002 +#endif /* NET_26 */
27003 +
27004 +/*
27005 + * $Log: ipsec_ah.c,v $
27006 + * Revision 1.12.2.2 2006/10/06 21:39:26 paul
27007 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
27008 + * set. This is defined through autoconf.h which is included through the
27009 + * linux kernel build macros.
27010 + *
27011 + * Revision 1.12.2.1 2006/02/15 05:35:14 paul
27012 + * Patch by David McCullough <davidm@snapgear.com>
27013 + * If you setup a tunnel without ESP it doesn't work. It used to work in
27014 + * an older openswan version but stopped when klips was modified to deal
27015 + * with the pulled IP header on the received SKB's.
27016 + *
27017 + * The code in ipsec_ah.c still thinks the IP header is there and runs the
27018 + * hash on the incorrect data.
27019 + *
27020 + * Revision 1.12 2005/04/29 05:10:22 mcr
27021 + * removed from extraenous includes to make unit testing easier.
27022 + *
27023 + * Revision 1.11 2005/04/15 19:50:55 mcr
27024 + * adjustments to use proper skb fields for data.
27025 + *
27026 + * Revision 1.10 2004/09/14 00:22:57 mcr
27027 + * adjustment of MD5* functions.
27028 + *
27029 + * Revision 1.9 2004/09/13 02:22:47 mcr
27030 + * #define inet_protocol if necessary.
27031 + *
27032 + * Revision 1.8 2004/09/06 18:35:48 mcr
27033 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
27034 + * so adjust for that.
27035 + *
27036 + * Revision 1.7 2004/08/22 05:00:48 mcr
27037 + * if we choose to compile the file, we want the contents,
27038 + * so don't pull any punches.
27039 + *
27040 + * Revision 1.6 2004/08/17 03:27:23 mcr
27041 + * klips 2.6 edits.
27042 + *
27043 + * Revision 1.5 2004/08/14 03:28:24 mcr
27044 + * fixed log comment to remove warning about embedded comment.
27045 + *
27046 + * Revision 1.4 2004/08/04 15:57:07 mcr
27047 + * moved des .h files to include/des/ *
27048 + * included 2.6 protocol specific things
27049 + * started at NAT-T support, but it will require a kernel patch.
27050 + *
27051 + * Revision 1.3 2004/07/10 19:11:18 mcr
27052 + * CONFIG_IPSEC -> CONFIG_KLIPS.
27053 + *
27054 + * Revision 1.2 2004/04/06 02:49:25 mcr
27055 + * pullup of algo code from alg-branch.
27056 + *
27057 + *
27058 + *
27059 + */
27060 --- /dev/null Tue Mar 11 13:02:56 2003
27061 +++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004
27062 @@ -0,0 +1,1057 @@
27063 +/*
27064 + * Modular extensions service and registration functions
27065 + *
27066 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
27067 + *
27068 + * Version: 0.8.1
27069 + *
27070 + * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
27071 + *
27072 + * This program is free software; you can redistribute it and/or modify it
27073 + * under the terms of the GNU General Public License as published by the
27074 + * Free Software Foundation; either version 2 of the License, or (at your
27075 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
27076 + *
27077 + * This program is distributed in the hope that it will be useful, but
27078 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27079 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27080 + * for more details.
27081 + *
27082 + */
27083 +#define __NO_VERSION__
27084 +
27085 +#if defined (MODULE)
27086 +#include <linux/module.h>
27087 +#endif
27088 +
27089 +#include <linux/kernel.h> /* printk() */
27090 +
27091 +#include <linux/netdevice.h> /* struct device, and other headers */
27092 +#include <linux/etherdevice.h> /* eth_type_trans */
27093 +#include <linux/ip.h> /* struct iphdr */
27094 +#include <linux/skbuff.h>
27095 +#include <linux/socket.h>
27096 +#include <linux/in.h>
27097 +#include <linux/types.h>
27098 +#include <linux/string.h> /* memcmp() */
27099 +#include <linux/random.h> /* get_random_bytes() */
27100 +#include <linux/errno.h> /* error codes */
27101 +#ifdef SPINLOCK
27102 +# ifdef SPINLOCK_23
27103 +# include <linux/spinlock.h> /* *lock* */
27104 +# else /* SPINLOCK_23 */
27105 +# include <asm/spinlock.h> /* *lock* */
27106 +# endif /* SPINLOCK_23 */
27107 +#endif /* SPINLOCK */
27108 +
27109 +#include "openswan/ipsec_param.h"
27110 +#include <openswan.h>
27111 +#include "openswan/ipsec_sa.h"
27112 +#include "openswan/radij.h"
27113 +#include "openswan/ipsec_encap.h"
27114 +#include "openswan/ipsec_radij.h"
27115 +#include "openswan/ipsec_xform.h"
27116 +#include "openswan/ipsec_tunnel.h"
27117 +#include "openswan/ipsec_rcv.h"
27118 +#if defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH)
27119 +# include "openswan/ipsec_ah.h"
27120 +#endif /* defined(CONFIG_KLIPS_ESP) || defined(CONFIG_KLIPS_AH) */
27121 +#ifdef CONFIG_KLIPS_ESP
27122 +# include "openswan/ipsec_esp.h"
27123 +#endif /* !CONFIG_KLIPS_ESP */
27124 +#ifdef CONFIG_KLIPS_IPCOMP
27125 +# include "openswan/ipcomp.h"
27126 +#endif /* CONFIG_KLIPS_COMP */
27127 +
27128 +#include <pfkeyv2.h>
27129 +#include <pfkey.h>
27130 +
27131 +#include "openswan/ipsec_alg.h"
27132 +#include "openswan/ipsec_proto.h"
27133 +
27134 +#if SADB_EALG_MAX < 255
27135 +#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
27136 +#endif
27137 +
27138 +static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
27139 +#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
27140 +static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
27141 +
27142 +/* Old gcc's will fail here */
27143 +#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) \
27144 + ; goto out; } while(0)
27145 +
27146 +#ifdef NET_26
27147 +/*
27148 + * Must be already protected by lock
27149 + */
27150 +static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt)
27151 +{
27152 +#ifdef MODULE
27153 + if (ixt->ixt_module)
27154 + try_module_get(ixt->ixt_module);
27155 +#endif
27156 + atomic_inc(&ixt->ixt_refcnt);
27157 +}
27158 +static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
27159 + atomic_dec(&ixt->ixt_refcnt);
27160 +#ifdef MODULE
27161 + if (ixt->ixt_module)
27162 + module_put(ixt->ixt_module);
27163 +#endif
27164 +}
27165 +
27166 +#else
27167 +
27168 +/*
27169 + * Must be already protected by lock
27170 + */
27171 +static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
27172 +#ifdef MODULE
27173 + if (ixt->ixt_module) {
27174 + __MOD_INC_USE_COUNT(ixt->ixt_module);
27175 + }
27176 +#endif
27177 + atomic_inc(&ixt->ixt_refcnt);
27178 +}
27179 +static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
27180 + atomic_dec(&ixt->ixt_refcnt);
27181 +#ifdef MODULE
27182 + if (ixt->ixt_module)
27183 + __MOD_DEC_USE_COUNT(ixt->ixt_module);
27184 +#endif
27185 +}
27186 +#endif
27187 +
27188 +/*
27189 + * simple hash function, optimized for 0-hash (1 list) special
27190 + * case
27191 + */
27192 +#if IPSEC_ALG_HASHSZ > 1
27193 +static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
27194 + return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
27195 +}
27196 +#else
27197 +#define ipsec_alg_hashfn(x,y) (0)
27198 +#endif
27199 +
27200 +/*****************************************************************
27201 + *
27202 + * INTERNAL table handling: insert, delete, find
27203 + *
27204 + *****************************************************************/
27205 +
27206 +/*
27207 + * hash table initialization, called from ipsec_alg_init()
27208 + */
27209 +static void ipsec_alg_hash_init(void) {
27210 + struct list_head *head = ipsec_alg_hash_table;
27211 + int i = IPSEC_ALG_HASHSZ;
27212 + do {
27213 + INIT_LIST_HEAD(head);
27214 + head++;
27215 + i--;
27216 + } while (i);
27217 +}
27218 +/*
27219 + * hash list lookup by {alg_type, alg_id} and table head,
27220 + * must be already protected by lock
27221 + */
27222 +static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
27223 + struct list_head *p;
27224 + struct ipsec_alg *ixt=NULL;
27225 + for (p=head->next; p!=head; p=p->next) {
27226 + ixt = list_entry(p, struct ipsec_alg, ixt_list);
27227 + if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
27228 + goto out;
27229 + }
27230 + }
27231 + ixt=NULL;
27232 +out:
27233 + return ixt;
27234 +}
27235 +/*
27236 + * inserts (in front) a new entry in hash table,
27237 + * called from ipsec_alg_register() when new algorithm is registered.
27238 + */
27239 +static int ipsec_alg_insert(struct ipsec_alg *ixt) {
27240 + int ret=-EINVAL;
27241 + unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
27242 + struct list_head *head= ipsec_alg_hash_table + hashval;
27243 + struct ipsec_alg *ixt_cur;
27244 +
27245 + /* new element must be virgin ... */
27246 + if (ixt->ixt_list.next != &ixt->ixt_list ||
27247 + ixt->ixt_list.prev != &ixt->ixt_list) {
27248 + printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
27249 + "list head not initialized\n",
27250 + ixt->ixt_name);
27251 + return ret;
27252 + }
27253 + write_lock_bh(&ipsec_alg_lock);
27254 +
27255 + ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
27256 +
27257 + /* if previous (current) ipsec_alg found check excl flag of _anyone_ */
27258 + if (ixt_cur
27259 + && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) {
27260 + barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
27261 + "Not loaded (ret=%d).\n",
27262 + ixt->ixt_alg_type,
27263 + ixt->ixt_alg_id, ret=-EEXIST);
27264 + }
27265 + list_add(&ixt->ixt_list, head);
27266 + ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
27267 + ret=0;
27268 +out:
27269 + write_unlock_bh(&ipsec_alg_lock);
27270 + return ret;
27271 +}
27272 +
27273 +/*
27274 + * deletes an existing entry in hash table,
27275 + * called from ipsec_alg_unregister() when algorithm is unregistered.
27276 + */
27277 +static int ipsec_alg_delete(struct ipsec_alg *ixt) {
27278 + write_lock_bh(&ipsec_alg_lock);
27279 + list_del(&ixt->ixt_list);
27280 + write_unlock_bh(&ipsec_alg_lock);
27281 + return 0;
27282 +}
27283 +
27284 +/*
27285 + * here @user context (read-only when @kernel bh context)
27286 + * -> no bh disabling
27287 + *
27288 + * called from ipsec_sa_init() -> ipsec_alg_sa_init()
27289 + */
27290 +static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id)
27291 +{
27292 + unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
27293 + struct list_head *head= ipsec_alg_hash_table + hashval;
27294 + struct ipsec_alg *ixt;
27295 +
27296 + read_lock(&ipsec_alg_lock);
27297 + ixt=__ipsec_alg_find(alg_type, alg_id, head);
27298 + if (ixt) __ipsec_alg_usage_inc(ixt);
27299 + read_unlock(&ipsec_alg_lock);
27300 +
27301 + return ixt;
27302 +}
27303 +
27304 +static void ipsec_alg_put(struct ipsec_alg *ixt) {
27305 + __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
27306 +}
27307 +
27308 +/*****************************************************************
27309 + *
27310 + * INTERFACE for ENC services: key creation, encrypt function
27311 + *
27312 + *****************************************************************/
27313 +
27314 +/*
27315 + * main encrypt service entry point
27316 + * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
27317 + * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
27318 + */
27319 +int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat,
27320 + int ilen, const __u8 * iv, int encrypt)
27321 +{
27322 + int ret;
27323 + struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
27324 +#ifdef CONFIG_KLIPS_DEBUG
27325 + int debug_flag = (encrypt==IPSEC_ALG_ENCRYPT ?
27326 + debug_tunnel : debug_rcv);
27327 +#endif
27328 +
27329 + KLIPS_PRINT(debug_flag,
27330 + "klips_debug:ipsec_alg_esp_encrypt: "
27331 + "entering with encalg=%d, ixt_e=%p\n",
27332 + sa_p->ips_encalg, ixt_e);
27333 + if (ixt_e == NULL) {
27334 +#ifdef CONFIG_KLIPS_DEBUG
27335 + KLIPS_ERROR(debug_flag,
27336 + "klips_debug:ipsec_alg_esp_encrypt: "
27337 + "NULL ipsec_alg_enc object\n");
27338 +#endif
27339 + return -1;
27340 + }
27341 + KLIPS_PRINT(debug_flag,
27342 + "klips_debug:ipsec_alg_esp_encrypt: "
27343 + "calling cbc_encrypt encalg=%d "
27344 + "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
27345 + sa_p->ips_encalg,
27346 + sa_p->ips_key_e, idat, ilen, iv, encrypt);
27347 + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat,
27348 + ilen, iv, encrypt);
27349 + KLIPS_PRINT(debug_flag,
27350 + "klips_debug:ipsec_alg_esp_encrypt: "
27351 + "returned ret=%d\n",
27352 + ret);
27353 + return ret;
27354 +}
27355 +
27356 +/*
27357 + * encryption key context creation function
27358 + * called from pfkey_v2_parser.c:pfkey_ips_init()
27359 + */
27360 +int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
27361 + int ret=-EINVAL;
27362 + int keyminbits, keymaxbits;
27363 + caddr_t ekp;
27364 + struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
27365 +
27366 + KLIPS_PRINT(debug_pfkey,
27367 + "klips_debug:ipsec_alg_enc_key_create: "
27368 + "entering with encalg=%d ixt_e=%p\n",
27369 + sa_p->ips_encalg, ixt_e);
27370 + if (!ixt_e) {
27371 + KLIPS_PRINT(debug_pfkey,
27372 + "klips_debug:ipsec_alg_enc_key_create: "
27373 + "NULL ipsec_alg_enc object\n");
27374 + return -EPROTO;
27375 + }
27376 +
27377 + /*
27378 + * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo
27379 + */
27380 + switch(ixt_e->ixt_common.ixt_support.ias_id) {
27381 + case ESP_3DES:
27382 + keyminbits=keymaxbits=192;break;
27383 + case ESP_DES:
27384 + keyminbits=keymaxbits=64;break;
27385 + default:
27386 + keyminbits=ixt_e->ixt_common.ixt_support.ias_keyminbits;
27387 + keymaxbits=ixt_e->ixt_common.ixt_support.ias_keymaxbits;
27388 + }
27389 + if(sa_p->ips_key_bits_e<keyminbits ||
27390 + sa_p->ips_key_bits_e>keymaxbits) {
27391 + KLIPS_PRINT(debug_pfkey,
27392 + "klips_debug:ipsec_alg_enc_key_create: "
27393 + "incorrect encryption key size for id=%d: %d bits -- "
27394 + "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
27395 + ixt_e->ixt_common.ixt_support.ias_id,
27396 + sa_p->ips_key_bits_e, keyminbits, keymaxbits);
27397 + ret=-EINVAL;
27398 + goto ixt_out;
27399 + }
27400 + /* save encryption key pointer */
27401 + ekp = sa_p->ips_key_e;
27402 +
27403 +
27404 + if (ixt_e->ixt_e_new_key) {
27405 + sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
27406 + ekp, sa_p->ips_key_bits_e/8);
27407 + ret = (sa_p->ips_key_e)? 0 : -EINVAL;
27408 + } else {
27409 + if((sa_p->ips_key_e = (caddr_t)
27410 + kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
27411 + GFP_ATOMIC)) == NULL) {
27412 + ret=-ENOMEM;
27413 + goto ixt_out;
27414 + }
27415 + /* zero-out key_e */
27416 + memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
27417 +
27418 + /* I cast here to allow more decoupling in alg module */
27419 + KLIPS_PRINT(debug_pfkey,
27420 + "klips_debug:ipsec_alg_enc_key_create: about to call:"
27421 + "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
27422 + (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27423 + ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
27424 + }
27425 + /* paranoid */
27426 + memset(ekp, 0, sa_p->ips_key_bits_e/8);
27427 + kfree(ekp);
27428 +ixt_out:
27429 + return ret;
27430 +}
27431 +
27432 +/***************************************************************
27433 + *
27434 + * INTERFACE for AUTH services: key creation, hash functions
27435 + *
27436 + ***************************************************************/
27437 +
27438 +/*
27439 + * auth key context creation function
27440 + * called from pfkey_v2_parser.c:pfkey_ips_init()
27441 + */
27442 +int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
27443 + int ret=-EINVAL;
27444 + struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27445 + int keyminbits, keymaxbits;
27446 + unsigned char *akp;
27447 + unsigned int aks;
27448 + KLIPS_PRINT(debug_pfkey,
27449 + "klips_debug:ipsec_alg_auth_key_create: "
27450 + "entering with authalg=%d ixt_a=%p\n",
27451 + sa_p->ips_authalg, ixt_a);
27452 + if (!ixt_a) {
27453 + KLIPS_PRINT(debug_pfkey,
27454 + "klips_debug:ipsec_alg_auth_key_create: "
27455 + "NULL ipsec_alg_auth object\n");
27456 + return -EPROTO;
27457 + }
27458 + keyminbits=ixt_a->ixt_common.ixt_support.ias_keyminbits;
27459 + keymaxbits=ixt_a->ixt_common.ixt_support.ias_keymaxbits;
27460 + if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
27461 + KLIPS_PRINT(debug_pfkey,
27462 + "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
27463 + "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
27464 + sa_p->ips_key_bits_a, keyminbits, keymaxbits);
27465 + ret=-EINVAL;
27466 + goto ixt_out;
27467 + }
27468 + /* save auth key pointer */
27469 + sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
27470 + akp = sa_p->ips_key_a;
27471 + aks = sa_p->ips_key_a_size;
27472 +
27473 + /* will hold: 2 ctx and a blocksize buffer: kb */
27474 + sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
27475 + if((sa_p->ips_key_a =
27476 + (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
27477 + ret=-ENOMEM;
27478 + goto ixt_out;
27479 + }
27480 + ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
27481 + ret=0;
27482 + memset(akp, 0, aks);
27483 + kfree(akp);
27484 +
27485 +ixt_out:
27486 + return ret;
27487 +}
27488 +
27489 +
27490 +int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp,
27491 + int len, __u8 *hash, int hashlen)
27492 +{
27493 + struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
27494 + if (!ixt_a) {
27495 + KLIPS_PRINT(debug_pfkey,
27496 + "klips_debug:ipsec_sa_esp_hash: "
27497 + "NULL ipsec_alg_auth object\n");
27498 + return -EPROTO;
27499 + }
27500 + KLIPS_PRINT(debug_tunnel|debug_rcv,
27501 + "klips_debug:ipsec_sa_esp_hash: "
27502 + "hashing %p (%d bytes) to %p (%d bytes)\n",
27503 + espp, len,
27504 + hash, hashlen);
27505 + ixt_a->ixt_a_hmac_hash(ixt_a,
27506 + sa_p->ips_key_a,
27507 + espp, len,
27508 + hash, hashlen);
27509 + return 0;
27510 +}
27511 +
27512 +/***************************************************************
27513 + *
27514 + * INTERFACE for module loading,testing, and unloading
27515 + *
27516 + ***************************************************************/
27517 +
27518 +/* validation for registering (enc) module */
27519 +static int check_enc(struct ipsec_alg_enc *ixt)
27520 +{
27521 + int ret=-EINVAL;
27522 + if (ixt->ixt_common.ixt_blocksize==0) /* || ixt->ixt_common.ixt_blocksize%2) need for ESP_NULL */
27523 + barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_common.ixt_blocksize);
27524 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0
27525 + && ixt->ixt_common.ixt_support.ias_keymaxbits==0
27526 + && ixt->ixt_e_keylen==0)
27527 + goto zero_key_ok;
27528 +
27529 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27530 + barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27531 +
27532 + if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27533 + barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27534 +
27535 + if (ixt->ixt_e_keylen==0)
27536 + barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
27537 +
27538 +zero_key_ok:
27539 + if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
27540 + barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
27541 + if (ixt->ixt_e_cbc_encrypt==NULL)
27542 + barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
27543 + ret=0;
27544 +out:
27545 + return ret;
27546 +}
27547 +
27548 +/* validation for registering (auth) module */
27549 +static int check_auth(struct ipsec_alg_auth *ixt)
27550 +{
27551 + int ret=-EINVAL;
27552 + if (ixt->ixt_common.ixt_support.ias_id==0 || ixt->ixt_common.ixt_support.ias_id > SADB_AALG_MAX)
27553 + barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n",
27554 + ixt->ixt_common.ixt_support.ias_id, SADB_AALG_MAX);
27555 +
27556 + if (ixt->ixt_common.ixt_blocksize==0
27557 + || ixt->ixt_common.ixt_blocksize%2)
27558 + barf_out(KERN_ERR "invalid blocksize=%d\n",
27559 + ixt->ixt_common.ixt_blocksize);
27560 +
27561 + if (ixt->ixt_common.ixt_blocksize>AH_BLKLEN_MAX)
27562 + barf_out(KERN_ERR "sorry blocksize=%d > %d. "
27563 + "Please increase AH_BLKLEN_MAX and recompile\n",
27564 + ixt->ixt_common.ixt_blocksize,
27565 + AH_BLKLEN_MAX);
27566 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0 && ixt->ixt_common.ixt_support.ias_keymaxbits==0 && ixt->ixt_a_keylen==0)
27567 + goto zero_key_ok;
27568 + if (ixt->ixt_common.ixt_support.ias_keyminbits==0)
27569 + barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_common.ixt_support.ias_keyminbits);
27570 + if (ixt->ixt_common.ixt_support.ias_keymaxbits==0)
27571 + barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_common.ixt_support.ias_keymaxbits);
27572 + if (ixt->ixt_common.ixt_support.ias_keymaxbits!=ixt->ixt_common.ixt_support.ias_keyminbits)
27573 + barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
27574 + if (ixt->ixt_a_keylen==0)
27575 + barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
27576 +zero_key_ok:
27577 + if (ixt->ixt_a_ctx_size==0)
27578 + barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
27579 + if (ixt->ixt_a_hmac_set_key==NULL)
27580 + barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
27581 + if (ixt->ixt_a_hmac_hash==NULL)
27582 + barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
27583 + ret=0;
27584 +out:
27585 + return ret;
27586 +}
27587 +
27588 +/*
27589 + * Generic (enc, auth) registration entry point
27590 + */
27591 +int register_ipsec_alg(struct ipsec_alg *ixt)
27592 +{
27593 + int ret=-EINVAL;
27594 + /* Validation */
27595 + if (ixt==NULL)
27596 + barf_out("NULL ipsec_alg object passed\n");
27597 + if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
27598 + barf_out("incorrect version: %d.%d.%d-%d, "
27599 + "must be %d.%d.%d[-%d]\n",
27600 + IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
27601 + IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
27602 +
27603 + switch(ixt->ixt_alg_type) {
27604 + case IPSEC_ALG_TYPE_AUTH:
27605 + if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
27606 + goto out;
27607 + break;
27608 + case IPSEC_ALG_TYPE_ENCRYPT:
27609 + if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
27610 + goto out;
27611 + /*
27612 + * Adapted two lines below:
27613 + * ivlen == 0 is possible (NULL enc has blocksize==1)
27614 + *
27615 + * fixed NULL support by David De Reu <DeReu@tComLabs.com>
27616 + */
27617 + if (ixt->ixt_support.ias_ivlen == 0
27618 + && ixt->ixt_blocksize > 1) {
27619 + ixt->ixt_support.ias_ivlen = ixt->ixt_blocksize*8;
27620 + }
27621 + break;
27622 + default:
27623 + barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);
27624 + }
27625 + INIT_LIST_HEAD(&ixt->ixt_list);
27626 + ret = ipsec_alg_insert(ixt);
27627 + if (ret<0)
27628 + barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
27629 + "Not loaded (ret=%d).\n",
27630 + ixt->ixt_support.ias_id, ret);
27631 +
27632 +
27633 + ret = pfkey_list_insert_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27634 + , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27635 +
27636 + if (ret==0) {
27637 + ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
27638 + /* send register event to userspace */
27639 + pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27640 + } else
27641 + printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
27642 + "Loading anyway.\n", ret);
27643 + ret=0;
27644 +out:
27645 + return ret;
27646 +}
27647 +
27648 +/*
27649 + * unregister ipsec_alg object from own tables, if
27650 + * success => calls pfkey_list_remove_supported()
27651 + */
27652 +int unregister_ipsec_alg(struct ipsec_alg *ixt) {
27653 + int ret= -EINVAL;
27654 + switch(ixt->ixt_alg_type) {
27655 + case IPSEC_ALG_TYPE_AUTH:
27656 + case IPSEC_ALG_TYPE_ENCRYPT:
27657 + break;
27658 + default:
27659 + /* this is not a typo :) */
27660 + barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
27661 + ixt->ixt_name);
27662 + }
27663 +
27664 + ret=ipsec_alg_delete(ixt);
27665 + if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
27666 + ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
27667 + pfkey_list_remove_supported((struct ipsec_alg_supported *)&ixt->ixt_support
27668 + , &(pfkey_supported_list[SADB_SATYPE_ESP]));
27669 +
27670 + /* send register event to userspace */
27671 + pfkey_register_reply(SADB_SATYPE_ESP, NULL);
27672 + }
27673 +
27674 +out:
27675 + return ret;
27676 +}
27677 +
27678 +/*
27679 + * Must be called from user context
27680 + * used at module load type for testing algo implementation
27681 + */
27682 +static int ipsec_alg_test_encrypt(int enc_alg, int test) {
27683 + int ret;
27684 + caddr_t buf = NULL;
27685 + int iv_size, keysize, key_e_size;
27686 + struct ipsec_alg_enc *ixt_e;
27687 + void *tmp_key_e = NULL;
27688 + #define BUFSZ 1024
27689 + #define MARGIN 0
27690 + #define test_enc (buf+MARGIN)
27691 + #define test_dec (test_enc+BUFSZ+MARGIN)
27692 + #define test_tmp (test_dec+BUFSZ+MARGIN)
27693 + #define test_key_e (test_tmp+BUFSZ+MARGIN)
27694 + #define test_iv (test_key_e+key_e_size+MARGIN)
27695 + #define test_key (test_iv+iv_size+MARGIN)
27696 + #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
27697 + ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
27698 + if (ixt_e==NULL) {
27699 + KLIPS_PRINT(1,
27700 + "klips_debug: ipsec_alg_test_encrypt: "
27701 + "encalg=%d object not found\n",
27702 + enc_alg);
27703 + ret=-EINVAL;
27704 + goto out;
27705 + }
27706 + iv_size=ixt_e->ixt_common.ixt_support.ias_ivlen / 8;
27707 + key_e_size=ixt_e->ixt_e_ctx_size;
27708 + keysize=ixt_e->ixt_e_keylen;
27709 + KLIPS_PRINT(1,
27710 + "klips_debug: ipsec_alg_test_encrypt: "
27711 + "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
27712 + enc_alg, iv_size, key_e_size, keysize);
27713 + if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27714 + ret= -ENOMEM;
27715 + goto out;
27716 + }
27717 + get_random_bytes(test_key, keysize);
27718 + get_random_bytes(test_iv, iv_size);
27719 + if (ixt_e->ixt_e_new_key) {
27720 + tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
27721 + ret = tmp_key_e ? 0 : -EINVAL;
27722 + } else {
27723 + tmp_key_e = test_key_e;
27724 + ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
27725 + }
27726 + if (ret < 0)
27727 + goto out;
27728 + get_random_bytes(test_enc, BUFSZ);
27729 + memcpy(test_tmp, test_enc, BUFSZ);
27730 + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
27731 + printk(KERN_INFO
27732 + "klips_info: ipsec_alg_test_encrypt: "
27733 + "cbc_encrypt=1 ret=%d\n",
27734 + ret);
27735 + ret=memcmp(test_enc, test_tmp, BUFSZ);
27736 + printk(KERN_INFO
27737 + "klips_info: ipsec_alg_test_encrypt: "
27738 + "memcmp(enc, tmp) ret=%d: %s\n", ret,
27739 + ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
27740 + memcpy(test_dec, test_enc, BUFSZ);
27741 + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
27742 + printk(KERN_INFO
27743 + "klips_info: ipsec_alg_test_encrypt: "
27744 + "cbc_encrypt=0 ret=%d\n", ret);
27745 + ret=memcmp(test_dec, test_tmp, BUFSZ);
27746 + printk(KERN_INFO
27747 + "klips_info: ipsec_alg_test_encrypt: "
27748 + "memcmp(dec,tmp) ret=%d: %s\n", ret,
27749 + ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
27750 + {
27751 + /* Shamelessly taken from drivers/md sources O:) */
27752 + unsigned long now;
27753 + int i, count, max=0;
27754 + int encrypt, speed;
27755 + for (encrypt=0; encrypt <2;encrypt ++) {
27756 + for (i = 0; i < 5; i++) {
27757 + now = jiffies;
27758 + count = 0;
27759 + while (jiffies == now) {
27760 + mb();
27761 + ixt_e->ixt_e_cbc_encrypt(ixt_e,
27762 + tmp_key_e, test_tmp,
27763 + BUFSZ, test_iv, encrypt);
27764 + mb();
27765 + count++;
27766 + mb();
27767 + }
27768 + if (count > max)
27769 + max = count;
27770 + }
27771 + speed = max * (HZ * BUFSZ / 1024);
27772 + printk(KERN_INFO
27773 + "klips_info: ipsec_alg_test_encrypt: "
27774 + "%s %s speed=%d KB/s\n",
27775 + ixt_e->ixt_common.ixt_name,
27776 + encrypt? "encrypt": "decrypt", speed);
27777 + }
27778 + }
27779 +out:
27780 + if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
27781 + if (buf) kfree(buf);
27782 + if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
27783 + return ret;
27784 + #undef test_enc
27785 + #undef test_dec
27786 + #undef test_tmp
27787 + #undef test_key_e
27788 + #undef test_iv
27789 + #undef test_key
27790 + #undef test_size
27791 +}
27792 +
27793 +/*
27794 + * Must be called from user context
27795 + * used at module load type for testing algo implementation
27796 + */
27797 +static int ipsec_alg_test_auth(int auth_alg, int test) {
27798 + int ret;
27799 + caddr_t buf = NULL;
27800 + int blocksize, keysize, key_a_size;
27801 + struct ipsec_alg_auth *ixt_a;
27802 + #define BUFSZ 1024
27803 + #define MARGIN 0
27804 + #define test_auth (buf+MARGIN)
27805 + #define test_key_a (test_auth+BUFSZ+MARGIN)
27806 + #define test_key (test_key_a+key_a_size+MARGIN)
27807 + #define test_hash (test_key+keysize+MARGIN)
27808 + #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
27809 + ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
27810 + if (ixt_a==NULL) {
27811 + KLIPS_PRINT(1,
27812 + "klips_debug: ipsec_alg_test_auth: "
27813 + "encalg=%d object not found\n",
27814 + auth_alg);
27815 + ret=-EINVAL;
27816 + goto out;
27817 + }
27818 + blocksize=ixt_a->ixt_common.ixt_blocksize;
27819 + key_a_size=ixt_a->ixt_a_ctx_size;
27820 + keysize=ixt_a->ixt_a_keylen;
27821 + KLIPS_PRINT(1,
27822 + "klips_debug: ipsec_alg_test_auth: "
27823 + "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
27824 + auth_alg, blocksize, key_a_size, keysize);
27825 + if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
27826 + ret= -ENOMEM;
27827 + goto out;
27828 + }
27829 + get_random_bytes(test_key, keysize);
27830 + ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
27831 + if (ret < 0 )
27832 + goto out;
27833 + get_random_bytes(test_auth, BUFSZ);
27834 + ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27835 + printk(KERN_INFO
27836 + "klips_info: ipsec_alg_test_auth: "
27837 + "ret=%d\n", ret);
27838 + {
27839 + /* Shamelessly taken from drivers/md sources O:) */
27840 + unsigned long now;
27841 + int i, count, max=0;
27842 + int speed;
27843 + for (i = 0; i < 5; i++) {
27844 + now = jiffies;
27845 + count = 0;
27846 + while (jiffies == now) {
27847 + mb();
27848 + ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
27849 + mb();
27850 + count++;
27851 + mb();
27852 + }
27853 + if (count > max)
27854 + max = count;
27855 + }
27856 + speed = max * (HZ * BUFSZ / 1024);
27857 + printk(KERN_INFO
27858 + "klips_info: ipsec_alg_test_auth: "
27859 + "%s hash speed=%d KB/s\n",
27860 + ixt_a->ixt_common.ixt_name,
27861 + speed);
27862 + }
27863 +out:
27864 + if (buf) kfree(buf);
27865 + if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
27866 + return ret;
27867 + #undef test_auth
27868 + #undef test_key_a
27869 + #undef test_key
27870 + #undef test_hash
27871 + #undef test_size
27872 +}
27873 +
27874 +int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
27875 + switch(alg_type) {
27876 + case IPSEC_ALG_TYPE_ENCRYPT:
27877 + return ipsec_alg_test_encrypt(alg_id, test);
27878 + break;
27879 + case IPSEC_ALG_TYPE_AUTH:
27880 + return ipsec_alg_test_auth(alg_id, test);
27881 + break;
27882 + }
27883 + printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
27884 + "alg_type=%d alg_id=%d\n",
27885 + alg_type, alg_id);
27886 + return -EINVAL;
27887 +}
27888 +
27889 +int ipsec_alg_init(void) {
27890 + KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27891 + "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
27892 + IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
27893 + SADB_EALG_MAX, SADB_AALG_MAX);
27894 + /* Initialize tables */
27895 + write_lock_bh(&ipsec_alg_lock);
27896 + ipsec_alg_hash_init();
27897 + write_unlock_bh(&ipsec_alg_lock);
27898 +
27899 + /* Initialize static algos */
27900 + KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
27901 + "calling ipsec_alg_static_init()\n");
27902 +
27903 + /* If we are suppose to use our AES, and don't have
27904 + * CryptoAPI enabled...
27905 + */
27906 +#if defined(CONFIG_KLIPS_ENC_AES) && CONFIG_KLIPS_ENC_AES && !defined(CONFIG_KLIPS_ENC_AES_MODULE)
27907 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27908 +#warning "Using built-in AES rather than CryptoAPI AES"
27909 +#endif
27910 + {
27911 + extern int ipsec_aes_init(void);
27912 + ipsec_aes_init();
27913 + }
27914 +#endif
27915 +
27916 +#if defined(CONFIG_KLIPS_ENC_3DES) && CONFIG_KLIPS_ENC_3DES && !defined(CONFIG_KLIPS_ENC_3DES_MODULE)
27917 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27918 +#warning "Using built-in 3des rather than CryptoAPI 3des"
27919 +#endif
27920 + {
27921 + extern int ipsec_3des_init(void);
27922 + ipsec_3des_init();
27923 + }
27924 +#endif
27925 +#if defined(CONFIG_KLIPS_ENC_NULL) && CONFIG_KLIPS_ENC_NULL && !defined(CONFIG_KLIPS_ENC_NULL_MODULE)
27926 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI
27927 +#warning "Using built-in null cipher rather than CryptoAPI null cipher"
27928 +#endif
27929 +#warning "Building with null cipher (ESP_NULL), blame on you :-)"
27930 + {
27931 + extern int ipsec_null_init(void);
27932 + ipsec_null_init();
27933 + }
27934 +#endif
27935 +
27936 +
27937 + /* If we are doing CryptoAPI, then init */
27938 +#if defined(CONFIG_KLIPS_ENC_CRYPTOAPI) && CONFIG_KLIPS_ENC_CRYPTOAPI && !defined(CONFIG_KLIPS_ENC_CRYPTOAPI_MODULE)
27939 + {
27940 + extern int ipsec_cryptoapi_init(void);
27941 + ipsec_cryptoapi_init();
27942 + }
27943 +#endif
27944 +
27945 +
27946 + return 0;
27947 +}
27948 +
27949 +/**********************************************
27950 + *
27951 + * INTERFACE for ipsec_sa init and wipe
27952 + *
27953 + **********************************************/
27954 +
27955 +/*
27956 + * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
27957 + */
27958 +int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
27959 + struct ipsec_alg_enc *ixt_e;
27960 + struct ipsec_alg_auth *ixt_a;
27961 +
27962 + /* Only ESP for now ... */
27963 + if (sa_p->ips_said.proto != IPPROTO_ESP)
27964 + return -EPROTONOSUPPORT;
27965 +
27966 + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
27967 + "entering for encalg=%d, authalg=%d\n",
27968 + sa_p->ips_encalg, sa_p->ips_authalg);
27969 +
27970 + if ((ixt_e=(struct ipsec_alg_enc *)
27971 + ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
27972 + KLIPS_PRINT(debug_pfkey,
27973 + "klips_debug: ipsec_alg_sa_init() :"
27974 + "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
27975 + ixt_e, sa_p->ips_encalg);
27976 + sa_p->ips_alg_enc=ixt_e;
27977 + }
27978 +
27979 + if ((ixt_a=(struct ipsec_alg_auth *)
27980 + ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
27981 + KLIPS_PRINT(debug_pfkey,
27982 + "klips_debug: ipsec_alg_sa_init() :"
27983 + "found ipsec_alg (ixt_a=%p) for auth=%d\n",
27984 + ixt_a, sa_p->ips_authalg);
27985 + sa_p->ips_alg_auth=ixt_a;
27986 + }
27987 + return 0;
27988 +}
27989 +
27990 +/*
27991 + * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
27992 + */
27993 +int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
27994 + struct ipsec_alg *ixt;
27995 + if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
27996 + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
27997 + "unlinking for encalg=%d\n",
27998 + ixt->ixt_support.ias_id);
27999 + ipsec_alg_put(ixt);
28000 + }
28001 + if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
28002 + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
28003 + "unlinking for authalg=%d\n",
28004 + ixt->ixt_support.ias_id);
28005 + ipsec_alg_put(ixt);
28006 + }
28007 + return 0;
28008 +}
28009 +
28010 +IPSEC_PROCFS_DEBUG_NO_STATIC
28011 +int
28012 +ipsec_xform_get_info(char *buffer,
28013 + char **start,
28014 + off_t offset,
28015 + int length IPSEC_PROC_LAST_ARG)
28016 +{
28017 + int len = 0;
28018 + off_t begin = 0;
28019 + int i;
28020 + struct list_head *head;
28021 + struct ipsec_alg *ixt;
28022 +
28023 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
28024 + "klips_debug:ipsec_tncfg_get_info: "
28025 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
28026 + buffer,
28027 + *start,
28028 + (int)offset,
28029 + length);
28030 +
28031 + for(i = 0, head = ipsec_alg_hash_table;
28032 + i<IPSEC_ALG_HASHSZ;
28033 + i++, head++)
28034 + {
28035 + struct list_head *p;
28036 + for (p=head->next; p!=head; p=p->next)
28037 + {
28038 + ixt = list_entry(p, struct ipsec_alg, ixt_list);
28039 + len += ipsec_snprintf(buffer+len, length-len,
28040 + "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
28041 + ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_support.ias_id,
28042 + ixt->ixt_name, ixt->ixt_refcnt);
28043 +
28044 + len += ipsec_snprintf(buffer+len, length-len,
28045 + "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
28046 + ixt->ixt_state, ixt->ixt_blocksize,
28047 + ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
28048 +
28049 + len += ipsec_snprintf(buffer+len, length-len,
28050 + "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
28051 + ixt->ixt_support.ias_ivlen, ixt->ixt_support.ias_keyminbits, ixt->ixt_support.ias_keymaxbits);
28052 +
28053 + switch(ixt->ixt_alg_type)
28054 + {
28055 + case IPSEC_ALG_TYPE_AUTH:
28056 + {
28057 + struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
28058 +
28059 + len += ipsec_snprintf(buffer+len, length-len,
28060 + "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
28061 + auth->ixt_a_keylen, auth->ixt_a_ctx_size,
28062 + auth->ixt_a_authlen);
28063 + break;
28064 + }
28065 + case IPSEC_ALG_TYPE_ENCRYPT:
28066 + {
28067 + struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
28068 + len += ipsec_snprintf(buffer+len, length-len,
28069 + "KEYLEN=%d CTXSIZE=%d ",
28070 + enc->ixt_e_keylen, enc->ixt_e_ctx_size);
28071 +
28072 + break;
28073 + }
28074 + }
28075 +
28076 + len += ipsec_snprintf(buffer+len, length-len, "\n");
28077 + }
28078 + }
28079 +
28080 + *start = buffer + (offset - begin); /* Start of wanted data */
28081 + len -= (offset - begin); /* Start slop */
28082 + if (len > length)
28083 + len = length;
28084 + return len;
28085 +}
28086 +
28087 +
28088 +/*
28089 + * As the author of this module, I ONLY ALLOW using it from
28090 + * GPL (or same LICENSE TERMS as kernel source) modules.
28091 + *
28092 + * In respect to hardware crypto engines this means:
28093 + * * Closed-source device drivers ARE NOT ALLOWED to use
28094 + * this interface.
28095 + * * Closed-source VHDL/Verilog firmware running on
28096 + * the crypto hardware device IS ALLOWED to use this interface
28097 + * via a GPL (or same LICENSE TERMS as kernel source) device driver.
28098 + * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
28099 + */
28100 +
28101 +/*
28102 + * These symbols can only be used from GPL modules
28103 + * for now, I'm disabling this because it creates false
28104 + * symbol problems for old modutils.
28105 + */
28106 +
28107 +#ifdef CONFIG_MODULES
28108 +#ifndef NET_26
28109 +#if 0
28110 +#ifndef EXPORT_SYMBOL_GPL
28111 +#undef EXPORT_SYMBOL_GPL
28112 +#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
28113 +#endif
28114 +#endif
28115 +EXPORT_SYMBOL(register_ipsec_alg);
28116 +EXPORT_SYMBOL(unregister_ipsec_alg);
28117 +EXPORT_SYMBOL(ipsec_alg_test);
28118 +#endif
28119 +#endif
28120 --- /dev/null Tue Mar 11 13:02:56 2003
28121 +++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
28122 @@ -0,0 +1,455 @@
28123 +/*
28124 + * ipsec_alg to linux cryptoapi GLUE
28125 + *
28126 + * Authors: CODE.ar TEAM
28127 + * Harpo MAxx <harpo@linuxmendoza.org.ar>
28128 + * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
28129 + * Luciano Ruete <docemeses@softhome.net>
28130 + *
28131 + * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
28132 + *
28133 + * This program is free software; you can redistribute it and/or modify it
28134 + * under the terms of the GNU General Public License as published by the
28135 + * Free Software Foundation; either version 2 of the License, or (at your
28136 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28137 + *
28138 + * This program is distributed in the hope that it will be useful, but
28139 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28140 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28141 + * for more details.
28142 + *
28143 + * Example usage:
28144 + * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
28145 + * modprobe ipsec_cryptoapi
28146 + * modprobe ipsec_cryptoapi test=1
28147 + * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
28148 + * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
28149 + * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
28150 + * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
28151 + */
28152 +#ifndef AUTOCONF_INCLUDED
28153 +#include <linux/config.h>
28154 +#endif
28155 +#include <linux/version.h>
28156 +
28157 +/*
28158 + * special case: ipsec core modular with this static algo inside:
28159 + * must avoid MODULE magic for this file
28160 + */
28161 +#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_CRYPTOAPI)
28162 +#undef MODULE
28163 +#endif
28164 +
28165 +#include <linux/module.h>
28166 +#include <linux/init.h>
28167 +
28168 +#include <linux/kernel.h> /* printk() */
28169 +#include <linux/errno.h> /* error codes */
28170 +#include <linux/types.h> /* size_t */
28171 +#include <linux/string.h>
28172 +
28173 +/* Check if __exit is defined, if not null it */
28174 +#ifndef __exit
28175 +#define __exit
28176 +#endif
28177 +
28178 +/* warn the innocent */
28179 +#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
28180 +#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
28181 +#define NO_CRYPTOAPI_SUPPORT
28182 +#endif
28183 +
28184 +#include "openswan.h"
28185 +#include "openswan/ipsec_alg.h"
28186 +#include "openswan/ipsec_policy.h"
28187 +
28188 +#include <linux/crypto.h>
28189 +#ifdef CRYPTO_API_VERSION_CODE
28190 +#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
28191 +#define NO_CRYPTOAPI_SUPPORT
28192 +#endif
28193 +
28194 +#ifdef NO_CRYPTOAPI_SUPPORT
28195 +#warning "Building an unusable module :P"
28196 +/* Catch old CryptoAPI by not allowing module to load */
28197 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
28198 +{
28199 + printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
28200 + return -EINVAL;
28201 +}
28202 +#else
28203 +#include <asm/scatterlist.h>
28204 +#include <asm/pgtable.h>
28205 +#include <linux/mm.h>
28206 +
28207 +#define CIPHERNAME_AES "aes"
28208 +#define CIPHERNAME_1DES "des"
28209 +#define CIPHERNAME_3DES "des3_ede"
28210 +#define CIPHERNAME_BLOWFISH "blowfish"
28211 +#define CIPHERNAME_CAST "cast5"
28212 +#define CIPHERNAME_SERPENT "serpent"
28213 +#define CIPHERNAME_TWOFISH "twofish"
28214 +
28215 +#define ESP_SERPENT 252 /* from ipsec drafts */
28216 +#define ESP_TWOFISH 253 /* from ipsec drafts */
28217 +
28218 +#define DIGESTNAME_MD5 "md5"
28219 +#define DIGESTNAME_SHA1 "sha1"
28220 +
28221 +MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
28222 +static int debug_crypto=0;
28223 +static int test_crypto=0;
28224 +static int excl_crypto=0;
28225 +
28226 +static int noauto = 0;
28227 +
28228 +#ifdef module_param
28229 +module_param(debug_crypto,int,0600)
28230 +module_param(test_crypto,int,0600)
28231 +module_param(excl_crypto,int,0600)
28232 +
28233 +module_param(noauto,int,0600)
28234 +#else
28235 +MODULE_PARM(debug_crypto, "i");
28236 +MODULE_PARM(test_crypto, "i");
28237 +MODULE_PARM(excl_crypto, "i");
28238 +
28239 +MODULE_PARM(noauto,"i");
28240 +#endif
28241 +MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
28242 +
28243 +#ifdef CONFIG_KLIPS_ENC_1DES
28244 +static int des_ede1[] = {-1, -1};
28245 +#endif
28246 +static int des_ede3[] = {-1, -1};
28247 +static int aes[] = {-1, -1};
28248 +static int blowfish[] = {-1, -1};
28249 +static int cast[] = {-1, -1};
28250 +static int serpent[] = {-1, -1};
28251 +static int twofish[] = {-1, -1};
28252 +
28253 +#ifdef CONFIG_KLIPS_ENC_1DES
28254 +#ifdef module_param
28255 +module_param_array(des_ede1,int,NULL,0)
28256 +#else
28257 +MODULE_PARM(des_ede1,"1-2i");
28258 +#endif
28259 +#endif
28260 +#ifdef module_param
28261 +module_param_array(des_ede3,int,NULL,0)
28262 +module_param_array(aes,int,NULL,0)
28263 +module_param_array(blowfish,int,NULL,0)
28264 +module_param_array(cast,int,NULL,0)
28265 +module_param_array(serpent,int,NULL,0)
28266 +module_param_array(twofish,int,NULL,0)
28267 +#else
28268 +MODULE_PARM(des_ede3,"1-2i");
28269 +MODULE_PARM(aes,"1-2i");
28270 +MODULE_PARM(blowfish,"1-2i");
28271 +MODULE_PARM(cast,"1-2i");
28272 +MODULE_PARM(serpent,"1-2i");
28273 +MODULE_PARM(twofish,"1-2i");
28274 +#endif
28275 +MODULE_PARM_DESC(des_ede1, "0: disable | 1: force_enable | min,max: dontuse");
28276 +MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
28277 +MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
28278 +MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
28279 +MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
28280 +MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
28281 +MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
28282 +
28283 +struct ipsec_alg_capi_cipher {
28284 + const char *ciphername; /* cryptoapi's ciphername */
28285 + unsigned blocksize;
28286 + unsigned short minbits;
28287 + unsigned short maxbits;
28288 + int *parm; /* lkm param for this cipher */
28289 + struct ipsec_alg_enc alg; /* note it's not a pointer */
28290 +};
28291 +
28292 +static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
28293 + { CIPHERNAME_AES, 16, 128, 256, aes, { ixt_common:{ ixt_support:{ ias_id: ESP_AES}}}},
28294 + { CIPHERNAME_TWOFISH, 16, 128, 256, twofish, { ixt_common:{ ixt_support:{ ias_id: ESP_TWOFISH,}}}},
28295 + { CIPHERNAME_SERPENT, 16, 128, 256, serpent, { ixt_common:{ ixt_support:{ ias_id: ESP_SERPENT,}}}},
28296 + { CIPHERNAME_CAST, 8, 128, 128, cast , { ixt_common:{ ixt_support:{ ias_id: ESP_CAST,}}}},
28297 + { CIPHERNAME_BLOWFISH, 8, 96, 448, blowfish, { ixt_common:{ ixt_support:{ ias_id: ESP_BLOWFISH,}}}},
28298 + { CIPHERNAME_3DES, 8, 192, 192, des_ede3, { ixt_common:{ ixt_support:{ ias_id: ESP_3DES,}}}},
28299 +#ifdef CONFIG_KLIPS_ENC_1DES
28300 + { CIPHERNAME_1DES, 8, 64, 64, des_ede1, { ixt_common:{ ixt_support:{ ias_id: ESP_DES,}}}},
28301 +#endif
28302 + { NULL, 0, 0, 0, NULL, {} }
28303 +};
28304 +
28305 +#ifdef NOT_YET
28306 +struct ipsec_alg_capi_digest {
28307 + const char *digestname; /* cryptoapi's digestname */
28308 + struct digest_implementation *di;
28309 + struct ipsec_alg_auth alg; /* note it's not a pointer */
28310 +};
28311 +static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
28312 + { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
28313 + { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
28314 + { NULL, NULL, {} }
28315 +};
28316 +#endif
28317 +/*
28318 + * "generic" linux cryptoapi setup_cipher() function
28319 + */
28320 +int setup_cipher(const char *ciphername)
28321 +{
28322 + return crypto_alg_available(ciphername, 0);
28323 +}
28324 +
28325 +/*
28326 + * setups ipsec_alg_capi_cipher "hyper" struct components, calling
28327 + * register_ipsec_alg for cointaned ipsec_alg object
28328 + */
28329 +static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
28330 +static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
28331 +static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
28332 +
28333 +static int
28334 +setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
28335 +{
28336 + int ret;
28337 + cptr->alg.ixt_common.ixt_version = IPSEC_ALG_VERSION;
28338 + cptr->alg.ixt_common.ixt_module = THIS_MODULE;
28339 + atomic_set (& cptr->alg.ixt_common.ixt_refcnt, 0);
28340 + strncpy (cptr->alg.ixt_common.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_common.ixt_name));
28341 +
28342 + cptr->alg.ixt_common.ixt_blocksize=cptr->blocksize;
28343 + cptr->alg.ixt_common.ixt_support.ias_keyminbits=cptr->minbits;
28344 + cptr->alg.ixt_common.ixt_support.ias_keymaxbits=cptr->maxbits;
28345 + cptr->alg.ixt_common.ixt_state = 0;
28346 + if (excl_crypto) cptr->alg.ixt_common.ixt_state |= IPSEC_ALG_ST_EXCL;
28347 + cptr->alg.ixt_e_keylen=cptr->alg.ixt_common.ixt_support.ias_keymaxbits/8;
28348 + cptr->alg.ixt_e_ctx_size = 0;
28349 + cptr->alg.ixt_common.ixt_support.ias_exttype = IPSEC_ALG_TYPE_ENCRYPT;
28350 + cptr->alg.ixt_e_new_key = _capi_new_key;
28351 + cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
28352 + cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
28353 + cptr->alg.ixt_common.ixt_data = cptr;
28354 +
28355 + ret=register_ipsec_alg_enc(&cptr->alg);
28356 + printk(KERN_INFO "KLIPS cryptoapi interface: "
28357 + "alg_type=%d alg_id=%d name=%s "
28358 + "keyminbits=%d keymaxbits=%d, %s(%d)\n",
28359 + cptr->alg.ixt_common.ixt_support.ias_exttype,
28360 + cptr->alg.ixt_common.ixt_support.ias_id,
28361 + cptr->alg.ixt_common.ixt_name,
28362 + cptr->alg.ixt_common.ixt_support.ias_keyminbits,
28363 + cptr->alg.ixt_common.ixt_support.ias_keymaxbits,
28364 + ret ? "not found" : "found", ret);
28365 + return ret;
28366 +}
28367 +/*
28368 + * called in ipsec_sa_wipe() time, will destroy key contexts
28369 + * and do 1 unbind()
28370 + */
28371 +static void
28372 +_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
28373 +{
28374 + struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
28375 +
28376 + if (debug_crypto > 0)
28377 + printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
28378 + "name=%s key_e=%p \n",
28379 + alg->ixt_common.ixt_name, key_e);
28380 + if (!key_e) {
28381 + printk(KERN_ERR "klips_debug: _capi_destroy_key:"
28382 + "name=%s NULL key_e!\n",
28383 + alg->ixt_common.ixt_name);
28384 + return;
28385 + }
28386 + crypto_free_tfm(tfm);
28387 +}
28388 +
28389 +/*
28390 + * create new key context, need alg->ixt_data to know which
28391 + * (of many) cipher inside this module is the target
28392 + */
28393 +static __u8 *
28394 +_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
28395 +{
28396 + struct ipsec_alg_capi_cipher *cptr;
28397 + struct crypto_tfm *tfm=NULL;
28398 +
28399 + cptr = alg->ixt_common.ixt_data;
28400 + if (!cptr) {
28401 + printk(KERN_ERR "_capi_new_key(): "
28402 + "NULL ixt_data (?!) for \"%s\" algo\n"
28403 + , alg->ixt_common.ixt_name);
28404 + goto err;
28405 + }
28406 + if (debug_crypto > 0)
28407 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28408 + "name=%s cptr=%p key=%p keysize=%d\n",
28409 + alg->ixt_common.ixt_name, cptr, key, keylen);
28410 +
28411 + /*
28412 + * alloc tfm
28413 + */
28414 + tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
28415 + if (!tfm) {
28416 + printk(KERN_ERR "_capi_new_key(): "
28417 + "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
28418 + , alg->ixt_common.ixt_name, cptr->ciphername);
28419 + goto err;
28420 + }
28421 + if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
28422 + printk(KERN_ERR "_capi_new_key(): "
28423 + "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
28424 + , alg->ixt_common.ixt_name, keylen);
28425 + crypto_free_tfm(tfm);
28426 + tfm=NULL;
28427 + }
28428 +err:
28429 + if (debug_crypto > 0)
28430 + printk(KERN_DEBUG "klips_debug:_capi_new_key:"
28431 + "name=%s key=%p keylen=%d tfm=%p\n",
28432 + alg->ixt_common.ixt_name, key, keylen, tfm);
28433 + return (__u8 *) tfm;
28434 +}
28435 +/*
28436 + * core encryption function: will use cx->ci to call actual cipher's
28437 + * cbc function
28438 + */
28439 +static int
28440 +_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
28441 + int error =0;
28442 + struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
28443 + struct scatterlist sg = {
28444 + .page = virt_to_page(in),
28445 + .offset = (unsigned long)(in) % PAGE_SIZE,
28446 + .length=ilen,
28447 + };
28448 + if (debug_crypto > 1)
28449 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28450 + "key_e=%p "
28451 + "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
28452 + , key_e
28453 + , in, in, ilen, iv, encrypt);
28454 + crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
28455 + if (encrypt)
28456 + error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
28457 + else
28458 + error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
28459 + if (debug_crypto > 1)
28460 + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
28461 + "error=%d\n"
28462 + , error);
28463 + return (error<0)? error : ilen;
28464 +}
28465 +/*
28466 + * main initialization loop: for each cipher in list, do
28467 + * 1) setup cryptoapi cipher else continue
28468 + * 2) register ipsec_alg object
28469 + */
28470 +static int
28471 +setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28472 +{
28473 + struct ipsec_alg_capi_cipher *cptr;
28474 + /* foreach cipher in list ... */
28475 + for (cptr=clist;cptr->ciphername;cptr++) {
28476 + /*
28477 + * see if cipher has been disabled (0) or
28478 + * if noauto set and not enabled (1)
28479 + */
28480 + if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
28481 + if (debug_crypto>0)
28482 + printk(KERN_INFO "setup_cipher_list(): "
28483 + "ciphername=%s skipped at user request: "
28484 + "noauto=%d parm[0]=%d parm[1]=%d\n"
28485 + , cptr->ciphername
28486 + , noauto
28487 + , cptr->parm[0]
28488 + , cptr->parm[1]);
28489 + continue;
28490 + }
28491 + /*
28492 + * use a local ci to avoid touching cptr->ci,
28493 + * if register ipsec_alg success then bind cipher
28494 + */
28495 + if(cptr->alg.ixt_common.ixt_support.ias_name == NULL) {
28496 + cptr->alg.ixt_common.ixt_support.ias_name = cptr->ciphername;
28497 + }
28498 +
28499 + if( setup_cipher(cptr->ciphername) ) {
28500 + if (debug_crypto > 0)
28501 + printk(KERN_DEBUG "klips_debug:"
28502 + "setup_cipher_list():"
28503 + "ciphername=%s found\n"
28504 + , cptr->ciphername);
28505 +
28506 + if (setup_ipsec_alg_capi_cipher(cptr) != 0) {
28507 + printk(KERN_ERR "klips_debug:"
28508 + "setup_cipher_list():"
28509 + "ciphername=%s failed ipsec_alg_register\n"
28510 + , cptr->ciphername);
28511 + }
28512 + } else {
28513 + printk(KERN_INFO "KLIPS: lookup for ciphername=%s: not found \n",
28514 + cptr->ciphername);
28515 + }
28516 + }
28517 + return 0;
28518 +}
28519 +/*
28520 + * deregister ipsec_alg objects and unbind ciphers
28521 + */
28522 +static int
28523 +unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
28524 +{
28525 + struct ipsec_alg_capi_cipher *cptr;
28526 + /* foreach cipher in list ... */
28527 + for (cptr=clist;cptr->ciphername;cptr++) {
28528 + if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28529 + unregister_ipsec_alg_enc(&cptr->alg);
28530 + }
28531 + }
28532 + return 0;
28533 +}
28534 +/*
28535 + * test loop for registered algos
28536 + */
28537 +static int
28538 +test_cipher_list (struct ipsec_alg_capi_cipher* clist)
28539 +{
28540 + int test_ret;
28541 + struct ipsec_alg_capi_cipher *cptr;
28542 + /* foreach cipher in list ... */
28543 + for (cptr=clist;cptr->ciphername;cptr++) {
28544 + if (cptr->alg.ixt_common.ixt_state & IPSEC_ALG_ST_REGISTERED) {
28545 + test_ret=ipsec_alg_test(
28546 + cptr->alg.ixt_common.ixt_support.ias_exttype,
28547 + cptr->alg.ixt_common.ixt_support.ias_id,
28548 + test_crypto);
28549 + printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
28550 + cptr->alg.ixt_common.ixt_support.ias_exttype,
28551 + cptr->alg.ixt_common.ixt_support.ias_id,
28552 + test_ret);
28553 + }
28554 + }
28555 + return 0;
28556 +}
28557 +
28558 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
28559 +{
28560 + int ret, test_ret;
28561 + if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
28562 + return -EPROTONOSUPPORT;
28563 + if (ret==0 && test_crypto) {
28564 + test_ret=test_cipher_list(alg_capi_carray);
28565 + }
28566 + return ret;
28567 +}
28568 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini )
28569 +{
28570 + unsetup_cipher_list(alg_capi_carray);
28571 + return;
28572 +}
28573 +#ifdef MODULE_LICENSE
28574 +MODULE_LICENSE("GPL");
28575 +#endif
28576 +
28577 +#endif /* NO_CRYPTOAPI_SUPPORT */
28578 --- /dev/null Tue Mar 11 13:02:56 2003
28579 +++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004
28580 @@ -0,0 +1,607 @@
28581 +/*
28582 + * processing code for ESP
28583 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
28584 + *
28585 + * This program is free software; you can redistribute it and/or modify it
28586 + * under the terms of the GNU General Public License as published by the
28587 + * Free Software Foundation; either version 2 of the License, or (at your
28588 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
28589 + *
28590 + * This program is distributed in the hope that it will be useful, but
28591 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28592 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28593 + * for more details.
28594 + */
28595 +
28596 +char ipsec_esp_c_version[] = "RCSID $Id: ipsec_esp.c,v 1.13.2.6 2006/10/06 21:39:26 paul Exp $";
28597 +#ifndef AUTOCONF_INCLUDED
28598 +#include <linux/config.h>
28599 +#endif
28600 +#include <linux/version.h>
28601 +
28602 +#define __NO_VERSION__
28603 +#include <linux/module.h>
28604 +#include <linux/kernel.h> /* printk() */
28605 +
28606 +#include "openswan/ipsec_param.h"
28607 +
28608 +#ifdef MALLOC_SLAB
28609 +# include <linux/slab.h> /* kmalloc() */
28610 +#else /* MALLOC_SLAB */
28611 +# include <linux/malloc.h> /* kmalloc() */
28612 +#endif /* MALLOC_SLAB */
28613 +#include <linux/errno.h> /* error codes */
28614 +#include <linux/types.h> /* size_t */
28615 +#include <linux/interrupt.h> /* mark_bh */
28616 +
28617 +#include <linux/netdevice.h> /* struct device, and other headers */
28618 +#include <linux/etherdevice.h> /* eth_type_trans */
28619 +#include <linux/ip.h> /* struct iphdr */
28620 +#include <linux/skbuff.h>
28621 +#include <openswan.h>
28622 +#ifdef SPINLOCK
28623 +# ifdef SPINLOCK_23
28624 +# include <linux/spinlock.h> /* *lock* */
28625 +# else /* SPINLOCK_23 */
28626 +# include <asm/spinlock.h> /* *lock* */
28627 +# endif /* SPINLOCK_23 */
28628 +#endif /* SPINLOCK */
28629 +
28630 +#include <net/ip.h>
28631 +#include <net/protocol.h>
28632 +
28633 +#include "openswan/radij.h"
28634 +#include "openswan/ipsec_encap.h"
28635 +#include "openswan/ipsec_sa.h"
28636 +
28637 +#include "openswan/ipsec_radij.h"
28638 +#include "openswan/ipsec_xform.h"
28639 +#include "openswan/ipsec_tunnel.h"
28640 +#include "openswan/ipsec_rcv.h"
28641 +#include "openswan/ipsec_xmit.h"
28642 +
28643 +#include "openswan/ipsec_auth.h"
28644 +
28645 +#ifdef CONFIG_KLIPS_ESP
28646 +#include "openswan/ipsec_esp.h"
28647 +#endif /* CONFIG_KLIPS_ESP */
28648 +
28649 +#include "openswan/ipsec_proto.h"
28650 +#include "openswan/ipsec_alg.h"
28651 +
28652 +#ifdef CONFIG_KLIPS_DEBUG
28653 +#define ESP_DMP(_x,_y,_z) if(debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp_block(_x,_y,_z)
28654 +#else
28655 +#define ESP_DMP(_x,_y,_z)
28656 +#endif
28657 +
28658 +#ifdef CONFIG_KLIPS_ESP
28659 +enum ipsec_rcv_value
28660 +ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
28661 + struct sk_buff *skb)
28662 +{
28663 + __u8 proto;
28664 + int len; /* packet length */
28665 +
28666 + len = skb->len;
28667 + proto = irs->ipp->protocol;
28668 +
28669 + /* XXX this will need to be 8 for IPv6 */
28670 + if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
28671 + printk("klips_error:ipsec_rcv: "
28672 + "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
28673 + len - irs->iphlen,
28674 + irs->ipsaddr_txt);
28675 + if(irs->stats) {
28676 + irs->stats->rx_errors++;
28677 + }
28678 + return IPSEC_RCV_BADLEN;
28679 + }
28680 +
28681 + if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {
28682 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
28683 + "klips_debug:ipsec_rcv: "
28684 + "runt esp packet of skb->len=%d received from %s, dropped.\n",
28685 + skb->len,
28686 + irs->ipsaddr_txt);
28687 + if(irs->stats) {
28688 + irs->stats->rx_errors++;
28689 + }
28690 + return IPSEC_RCV_BADLEN;
28691 + }
28692 +
28693 + irs->protostuff.espstuff.espp = (struct esphdr *)skb->h.raw;
28694 + irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
28695 +
28696 + return IPSEC_RCV_OK;
28697 +}
28698 +
28699 +enum ipsec_rcv_value
28700 +ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
28701 + struct sk_buff *skb,
28702 + __u32 *replay,
28703 + unsigned char **authenticator)
28704 +{
28705 + struct esphdr *espp = irs->protostuff.espstuff.espp;
28706 + //unsigned char *idat = (unsigned char *)espp;
28707 +
28708 + KLIPS_PRINT(debug_rcv,
28709 + "klips_debug:ipsec_rcv: "
28710 + "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
28711 + irs->ipsaddr_txt,
28712 + (__u32)ntohl(espp->esp_rpl),
28713 + (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
28714 + (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
28715 + irs->len,
28716 + irs->ilen,
28717 + irs->sa_len ? irs->sa : " (error)");
28718 +
28719 + *replay = ntohl(espp->esp_rpl);
28720 + *authenticator = &(skb->h.raw[irs->ilen]);
28721 +
28722 + return IPSEC_RCV_OK;
28723 +}
28724 +
28725 +enum ipsec_rcv_value
28726 +ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
28727 + struct sk_buff *skb)
28728 +{
28729 + struct auth_alg *aa;
28730 + struct esphdr *espp = irs->protostuff.espstuff.espp;
28731 + union {
28732 + MD5_CTX md5;
28733 + SHA1_CTX sha1;
28734 + } tctx;
28735 +
28736 + if (irs->ipsp->ips_alg_auth) {
28737 + KLIPS_PRINT(debug_rcv,
28738 + "klips_debug:ipsec_rcv: "
28739 + "ipsec_alg hashing proto=%d... ",
28740 + irs->said.proto);
28741 + if(irs->said.proto == IPPROTO_ESP) {
28742 + ipsec_alg_sa_esp_hash(irs->ipsp,
28743 + (caddr_t)espp, irs->ilen,
28744 + irs->hash, AHHMAC_HASHLEN);
28745 + return IPSEC_RCV_OK;
28746 + }
28747 + return IPSEC_RCV_BADPROTO;
28748 + }
28749 + aa = irs->authfuncs;
28750 +
28751 + /* copy the initialized keying material */
28752 + memcpy(&tctx, irs->ictx, irs->ictx_len);
28753 +
28754 +#ifdef HASH_DEBUG
28755 + ESP_DMP("ictx", irs->ictx, irs->ictx_len);
28756 +
28757 + ESP_DMP("mac_esp", (caddr_t)espp, irs->ilen);
28758 +#endif
28759 + (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
28760 +
28761 + (*aa->final)(irs->hash, (void *)&tctx);
28762 +
28763 +#ifdef HASH_DEBUG
28764 + ESP_DMP("hash1", irs->hash, aa->hashlen);
28765 +#endif
28766 +
28767 + memcpy(&tctx, irs->octx, irs->octx_len);
28768 +
28769 +#ifdef HASH_DEBUG
28770 + ESP_DMP("octx", irs->octx, irs->octx_len);
28771 +#endif
28772 +
28773 + (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
28774 + (*aa->final)(irs->hash, (void *)&tctx);
28775 +
28776 + return IPSEC_RCV_OK;
28777 +}
28778 +
28779 +
28780 +enum ipsec_rcv_value
28781 +ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
28782 +{
28783 + struct ipsec_sa *ipsp = irs->ipsp;
28784 + struct esphdr *espp = irs->protostuff.espstuff.espp;
28785 + int i;
28786 + int pad = 0, padlen;
28787 + int badpad = 0;
28788 + int esphlen = 0;
28789 + __u8 *idat; /* pointer to content to be decrypted/authenticated */
28790 + int encaplen = 0;
28791 + struct sk_buff *skb;
28792 + struct ipsec_alg_enc *ixt_e=NULL;
28793 +
28794 + skb=irs->skb;
28795 +
28796 + idat = skb->h.raw;
28797 +
28798 + /* encaplen is the distance between the end of the IP
28799 + * header and the beginning of the ESP header.
28800 + * on ESP headers it is zero, but on UDP-encap ESP
28801 + * it includes the space for the UDP header.
28802 + *
28803 + * Note: UDP-encap code has already moved the
28804 + * skb->data forward to accomodate this.
28805 + */
28806 + encaplen = idat - (skb->nh.raw + irs->iphlen);
28807 +
28808 + ixt_e=ipsp->ips_alg_enc;
28809 + esphlen = ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
28810 + KLIPS_PRINT(debug_rcv,
28811 + "klips_debug:ipsec_rcv: "
28812 + "encalg=%d esphlen=%d\n",
28813 + ipsp->ips_encalg, esphlen);
28814 +
28815 + idat += esphlen;
28816 + irs->ilen -= esphlen;
28817 +
28818 + if (ipsec_alg_esp_encrypt(ipsp,
28819 + idat, irs->ilen, espp->esp_iv,
28820 + IPSEC_ALG_DECRYPT) <= 0) {
28821 +#ifdef CONFIG_KLIPS_DEBUG
28822 + KLIPS_ERROR(debug_rcv, "klips_error:ipsec_rcv: "
28823 + "got packet with esplen = %d "
28824 + "from %s -- should be on "
28825 + "ENC(%d) octet boundary, "
28826 + "packet dropped\n",
28827 + irs->ilen,
28828 + irs->ipsaddr_txt,
28829 + ipsp->ips_encalg);
28830 +#endif
28831 + if(irs->stats) {
28832 + irs->stats->rx_errors++;
28833 + }
28834 + return IPSEC_RCV_BAD_DECRYPT;
28835 + }
28836 +
28837 + ESP_DMP("postdecrypt", idat, irs->ilen);
28838 +
28839 + irs->next_header = idat[irs->ilen - 1];
28840 + padlen = idat[irs->ilen - 2];
28841 + pad = padlen + 2 + irs->authlen;
28842 +
28843 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28844 + "klips_debug:ipsec_rcv: "
28845 + "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
28846 + padlen);
28847 +
28848 + for (i = 1; i <= padlen; i++) {
28849 + if((i % 16) == 1) {
28850 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28851 + "klips_debug: %02x:",
28852 + i - 1);
28853 + }
28854 + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28855 + " %02x",
28856 + idat[irs->ilen - 2 - padlen + i - 1]);
28857 + if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
28858 + badpad = 1;
28859 + }
28860 + if((i % 16) == 0) {
28861 + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28862 + "\n");
28863 + }
28864 + }
28865 + if((i % 16) != 1) {
28866 + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
28867 + "\n");
28868 + }
28869 + if(badpad) {
28870 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28871 + "klips_debug:ipsec_rcv: "
28872 + "warning, decrypted packet from %s has bad padding\n",
28873 + irs->ipsaddr_txt);
28874 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28875 + "klips_debug:ipsec_rcv: "
28876 + "...may be bad decryption -- not dropped\n");
28877 + ipsp->ips_errs.ips_encpad_errs += 1;
28878 + }
28879 +
28880 + KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
28881 + "klips_debug:ipsec_rcv: "
28882 + "packet decrypted from %s: next_header = %d, padding = %d\n",
28883 + irs->ipsaddr_txt,
28884 + irs->next_header,
28885 + pad - 2 - irs->authlen);
28886 +
28887 + irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad));
28888 +
28889 + /*
28890 + * move the IP header forward by the size of the ESP header, which
28891 + * will remove the the ESP header from the packet.
28892 + *
28893 + * XXX this is really unnecessary, since odds we are in tunnel
28894 + * mode, and we will be *removing* this IP header.
28895 + *
28896 + */
28897 + memmove((void *)(idat - irs->iphlen),
28898 + (void *)(skb->nh.raw), irs->iphlen);
28899 +
28900 + ESP_DMP("esp postmove", (idat - irs->iphlen),
28901 + irs->iphlen + irs->ilen);
28902 +
28903 + /* skb_pull below, will move up by esphlen */
28904 +
28905 + /* XXX not clear how this can happen, as the message indicates */
28906 + if(skb->len < esphlen) {
28907 + printk(KERN_WARNING
28908 + "klips_error:ipsec_rcv: "
28909 + "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n",
28910 + esphlen, (int)(skb->len));
28911 + return IPSEC_RCV_ESP_DECAPFAIL;
28912 + }
28913 + skb_pull(skb, esphlen);
28914 + skb->nh.raw = idat - irs->iphlen;
28915 + irs->ipp = skb->nh.iph;
28916 +
28917 + ESP_DMP("esp postpull", skb->data, skb->len);
28918 +
28919 + /* now, trip off the padding from the end */
28920 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28921 + "klips_debug:ipsec_rcv: "
28922 + "trimming to %d.\n",
28923 + irs->len - esphlen - pad);
28924 + if(pad + esphlen <= irs->len) {
28925 + skb_trim(skb, irs->len - esphlen - pad);
28926 + } else {
28927 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
28928 + "klips_debug:ipsec_rcv: "
28929 + "bogus packet, size is zero or negative, dropping.\n");
28930 + return IPSEC_RCV_DECAPFAIL;
28931 + }
28932 +
28933 + return IPSEC_RCV_OK;
28934 +}
28935 +
28936 +/*
28937 + *
28938 + */
28939 +enum ipsec_xmit_value
28940 +ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs)
28941 +{
28942 +#ifdef CONFIG_KLIPS_ENC_3DES
28943 + __u32 iv[2];
28944 +#endif
28945 + struct esphdr *espp;
28946 + int ilen = 0;
28947 + int padlen = 0, i;
28948 + unsigned char *dat;
28949 + unsigned char *idat, *pad;
28950 + __u8 hash[AH_AMAX];
28951 + union {
28952 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
28953 + MD5_CTX md5;
28954 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
28955 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
28956 + SHA1_CTX sha1;
28957 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
28958 + } tctx;
28959 +
28960 + dat = (unsigned char *)ixs->iph;
28961 +
28962 + espp = (struct esphdr *)(dat + ixs->iphlen);
28963 + espp->esp_spi = ixs->ipsp->ips_said.spi;
28964 + espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
28965 +
28966 + switch(ixs->ipsp->ips_encalg) {
28967 +#if defined(CONFIG_KLIPS_ENC_3DES)
28968 +#ifdef CONFIG_KLIPS_ENC_3DES
28969 + case ESP_3DES:
28970 +#endif /* CONFIG_KLIPS_ENC_3DES */
28971 + iv[0] = *((__u32*)&(espp->esp_iv) ) =
28972 + ((__u32*)(ixs->ipsp->ips_iv))[0];
28973 + iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
28974 + ((__u32*)(ixs->ipsp->ips_iv))[1];
28975 + break;
28976 +#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
28977 + default:
28978 + ixs->stats->tx_errors++;
28979 + return IPSEC_XMIT_ESP_BADALG;
28980 + }
28981 +
28982 + idat = dat + ixs->iphlen + sizeof(struct esphdr);
28983 + ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen);
28984 +
28985 + /* Self-describing padding */
28986 + pad = &dat[ixs->skb->len - ixs->tailroom];
28987 + padlen = ixs->tailroom - 2 - ixs->authlen;
28988 + for (i = 0; i < padlen; i++) {
28989 + pad[i] = i + 1;
28990 + }
28991 + dat[ixs->skb->len - ixs->authlen - 2] = padlen;
28992 +
28993 + dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol;
28994 + ixs->iph->protocol = IPPROTO_ESP;
28995 +
28996 + switch(ixs->ipsp->ips_encalg) {
28997 +#ifdef CONFIG_KLIPS_ENC_3DES
28998 + case ESP_3DES:
28999 + des_ede3_cbc_encrypt((des_cblock *)idat,
29000 + (des_cblock *)idat,
29001 + ilen,
29002 + ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
29003 + ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
29004 + ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
29005 + (des_cblock *)iv, 1);
29006 + break;
29007 +#endif /* CONFIG_KLIPS_ENC_3DES */
29008 + default:
29009 + ixs->stats->tx_errors++;
29010 + return IPSEC_XMIT_ESP_BADALG;
29011 + }
29012 +
29013 + switch(ixs->ipsp->ips_encalg) {
29014 +#if defined(CONFIG_KLIPS_ENC_3DES)
29015 +#ifdef CONFIG_KLIPS_ENC_3DES
29016 + case ESP_3DES:
29017 +#endif /* CONFIG_KLIPS_ENC_3DES */
29018 + /* XXX update IV with the last 8 octets of the encryption */
29019 +#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
29020 + ((__u32*)(ixs->ipsp->ips_iv))[0] =
29021 + ((__u32 *)(idat))[(ilen >> 2) - 2];
29022 + ((__u32*)(ixs->ipsp->ips_iv))[1] =
29023 + ((__u32 *)(idat))[(ilen >> 2) - 1];
29024 +#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
29025 + prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
29026 +#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
29027 + break;
29028 +#endif /* defined(CONFIG_KLIPS_ENC_3DES) */
29029 + default:
29030 + ixs->stats->tx_errors++;
29031 + return IPSEC_XMIT_ESP_BADALG;
29032 + }
29033 +
29034 + switch(ixs->ipsp->ips_authalg) {
29035 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
29036 + case AH_MD5:
29037 + ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29038 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
29039 + ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
29040 + osMD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29041 + ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
29042 + osMD5Final(hash, &tctx.md5);
29043 + ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
29044 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
29045 + ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
29046 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
29047 + ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
29048 + osMD5Final(hash, &tctx.md5);
29049 + ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
29050 + memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
29051 +
29052 + /* paranoid */
29053 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
29054 + memset((caddr_t)hash, 0, sizeof(*hash));
29055 + break;
29056 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
29057 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
29058 + case AH_SHA:
29059 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
29060 + SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
29061 + SHA1Final(hash, &tctx.sha1);
29062 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
29063 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
29064 + SHA1Final(hash, &tctx.sha1);
29065 + memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
29066 +
29067 + /* paranoid */
29068 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
29069 + memset((caddr_t)hash, 0, sizeof(*hash));
29070 + break;
29071 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
29072 + case AH_NONE:
29073 + break;
29074 + default:
29075 + ixs->stats->tx_errors++;
29076 + return IPSEC_XMIT_AH_BADALG;
29077 + }
29078 +
29079 + ixs->skb->h.raw = (unsigned char*)espp;
29080 +
29081 + return IPSEC_XMIT_OK;
29082 +}
29083 +
29084 +
29085 +struct xform_functions esp_xform_funcs[]={
29086 + { rcv_checks: ipsec_rcv_esp_checks,
29087 + rcv_setup_auth: ipsec_rcv_esp_decrypt_setup,
29088 + rcv_calc_auth: ipsec_rcv_esp_authcalc,
29089 + rcv_decrypt: ipsec_rcv_esp_decrypt,
29090 +
29091 + xmit_setup: ipsec_xmit_esp_setup,
29092 + xmit_headroom: sizeof(struct esphdr),
29093 + xmit_needtailroom: 1,
29094 + },
29095 +};
29096 +
29097 +#ifdef NET_26
29098 +struct inet_protocol esp_protocol = {
29099 + .handler = ipsec_rcv,
29100 + .no_policy = 1,
29101 +};
29102 +#else
29103 +struct inet_protocol esp_protocol =
29104 +{
29105 + ipsec_rcv, /* ESP handler */
29106 + NULL, /* TUNNEL error control */
29107 +#ifdef NETDEV_25
29108 + 1, /* no policy */
29109 +#else
29110 + 0, /* next */
29111 + IPPROTO_ESP, /* protocol ID */
29112 + 0, /* copy */
29113 + NULL, /* data */
29114 + "ESP" /* name */
29115 +#endif
29116 +};
29117 +#endif /* NET_26 */
29118 +
29119 +#endif /* !CONFIG_KLIPS_ESP */
29120 +
29121 +
29122 +/*
29123 + * $Log: ipsec_esp.c,v $
29124 + * Revision 1.13.2.6 2006/10/06 21:39:26 paul
29125 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
29126 + * set. This is defined through autoconf.h which is included through the
29127 + * linux kernel build macros.
29128 + *
29129 + * Revision 1.13.2.5 2006/08/24 03:02:01 paul
29130 + * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
29131 + *
29132 + * Revision 1.13.2.4 2006/05/06 03:07:38 ken
29133 + * Pull in proper padsize->tailroom fix from #public
29134 + * Need to do correct math on padlen since padsize is not equal to tailroom
29135 + *
29136 + * Revision 1.13.2.3 2006/05/05 03:58:04 ken
29137 + * ixs->padsize becomes ixs->tailroom
29138 + *
29139 + * Revision 1.13.2.2 2006/05/01 14:36:03 mcr
29140 + * use KLIPS_ERROR for fatal things.
29141 + *
29142 + * Revision 1.13.2.1 2006/04/20 16:33:06 mcr
29143 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
29144 + * Fix in-kernel module compilation. Sub-makefiles do not work.
29145 + *
29146 + * Revision 1.13 2005/05/21 03:19:57 mcr
29147 + * hash ctx is not really that interesting most of the time.
29148 + *
29149 + * Revision 1.12 2005/05/11 01:28:49 mcr
29150 + * removed "poor-man"s OOP in favour of proper C structures.
29151 + *
29152 + * Revision 1.11 2005/04/29 05:10:22 mcr
29153 + * removed from extraenous includes to make unit testing easier.
29154 + *
29155 + * Revision 1.10 2005/04/17 04:36:14 mcr
29156 + * code now deals with ESP and UDP-ESP code.
29157 + *
29158 + * Revision 1.9 2005/04/15 19:52:30 mcr
29159 + * adjustments to use proper skb fields for data.
29160 + *
29161 + * Revision 1.8 2004/09/14 00:22:57 mcr
29162 + * adjustment of MD5* functions.
29163 + *
29164 + * Revision 1.7 2004/09/13 02:23:01 mcr
29165 + * #define inet_protocol if necessary.
29166 + *
29167 + * Revision 1.6 2004/09/06 18:35:49 mcr
29168 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
29169 + * so adjust for that.
29170 + *
29171 + * Revision 1.5 2004/08/17 03:27:23 mcr
29172 + * klips 2.6 edits.
29173 + *
29174 + * Revision 1.4 2004/08/04 15:57:07 mcr
29175 + * moved des .h files to include/des/ *
29176 + * included 2.6 protocol specific things
29177 + * started at NAT-T support, but it will require a kernel patch.
29178 + *
29179 + * Revision 1.3 2004/07/10 19:11:18 mcr
29180 + * CONFIG_IPSEC -> CONFIG_KLIPS.
29181 + *
29182 + * Revision 1.2 2004/04/06 02:49:25 mcr
29183 + * pullup of algo code from alg-branch.
29184 + *
29185 + *
29186 + *
29187 + */
29188 --- /dev/null Tue Mar 11 13:02:56 2003
29189 +++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004
29190 @@ -0,0 +1,614 @@
29191 +/*
29192 + * @(#) Initialization code.
29193 + * Copyright (C) 1996, 1997 John Ioannidis.
29194 + * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org>
29195 + * 2001 - 2004 Michael Richardson <mcr@xelerance.com>
29196 + *
29197 + * This program is free software; you can redistribute it and/or modify it
29198 + * under the terms of the GNU General Public License as published by the
29199 + * Free Software Foundation; either version 2 of the License, or (at your
29200 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29201 + *
29202 + * This program is distributed in the hope that it will be useful, but
29203 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29204 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29205 + * for more details.
29206 + *
29207 + * /proc system code was split out into ipsec_proc.c after rev. 1.70.
29208 + *
29209 + */
29210 +
29211 +char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.104.2.4 2006/10/06 21:39:26 paul Exp $";
29212 +
29213 +#ifndef AUTOCONF_INCLUDED
29214 +#include <linux/config.h>
29215 +#endif
29216 +#include <linux/version.h>
29217 +#include <linux/module.h>
29218 +#include <linux/kernel.h> /* printk() */
29219 +
29220 +#include "openswan/ipsec_param.h"
29221 +
29222 +#ifdef MALLOC_SLAB
29223 +# include <linux/slab.h> /* kmalloc() */
29224 +#else /* MALLOC_SLAB */
29225 +# include <linux/malloc.h> /* kmalloc() */
29226 +#endif /* MALLOC_SLAB */
29227 +#include <linux/errno.h> /* error codes */
29228 +#include <linux/types.h> /* size_t */
29229 +#include <linux/interrupt.h> /* mark_bh */
29230 +
29231 +#include <linux/netdevice.h> /* struct device, and other headers */
29232 +#include <linux/etherdevice.h> /* eth_type_trans */
29233 +#include <linux/ip.h> /* struct iphdr */
29234 +#include <linux/in.h> /* struct sockaddr_in */
29235 +#include <linux/skbuff.h>
29236 +#include <linux/random.h> /* get_random_bytes() */
29237 +#include <net/protocol.h>
29238 +
29239 +#include <openswan.h>
29240 +
29241 +#ifdef SPINLOCK
29242 +# ifdef SPINLOCK_23
29243 +# include <linux/spinlock.h> /* *lock* */
29244 +# else /* 23_SPINLOCK */
29245 +# include <asm/spinlock.h> /* *lock* */
29246 +# endif /* 23_SPINLOCK */
29247 +#endif /* SPINLOCK */
29248 +
29249 +#include <net/ip.h>
29250 +
29251 +#ifdef CONFIG_PROC_FS
29252 +# include <linux/proc_fs.h>
29253 +#endif /* CONFIG_PROC_FS */
29254 +
29255 +#ifdef NETLINK_SOCK
29256 +# include <linux/netlink.h>
29257 +#else
29258 +# include <net/netlink.h>
29259 +#endif
29260 +
29261 +#include "openswan/radij.h"
29262 +
29263 +#include "openswan/ipsec_life.h"
29264 +#include "openswan/ipsec_stats.h"
29265 +#include "openswan/ipsec_sa.h"
29266 +
29267 +#include "openswan/ipsec_encap.h"
29268 +#include "openswan/ipsec_radij.h"
29269 +#include "openswan/ipsec_xform.h"
29270 +#include "openswan/ipsec_tunnel.h"
29271 +
29272 +#include "openswan/ipsec_rcv.h"
29273 +#include "openswan/ipsec_ah.h"
29274 +#include "openswan/ipsec_esp.h"
29275 +
29276 +#ifdef CONFIG_KLIPS_IPCOMP
29277 +# include "openswan/ipcomp.h"
29278 +#endif /* CONFIG_KLIPS_IPCOMP */
29279 +
29280 +#include "openswan/ipsec_proto.h"
29281 +#include "openswan/ipsec_alg.h"
29282 +
29283 +#include <pfkeyv2.h>
29284 +#include <pfkey.h>
29285 +
29286 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29287 +#include <net/xfrmudp.h>
29288 +#endif
29289 +
29290 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(HAVE_XFRM4_UDP_REGISTER)
29291 +#warning "You are trying to build KLIPS2.6 with NAT-T support, but you did not"
29292 +#error "properly apply the NAT-T patch to your 2.6 kernel source tree."
29293 +#endif
29294 +
29295 +#if !defined(CONFIG_KLIPS_ESP) && !defined(CONFIG_KLIPS_AH)
29296 +#error "kernel configuration must include ESP or AH"
29297 +#endif
29298 +
29299 +/*
29300 + * seems to be present in 2.4.10 (Linus), but also in some RH and other
29301 + * distro kernels of a lower number.
29302 + */
29303 +#ifdef MODULE_LICENSE
29304 +MODULE_LICENSE("GPL");
29305 +#endif
29306 +
29307 +#ifdef CONFIG_KLIPS_DEBUG
29308 +int debug_eroute = 0;
29309 +int debug_spi = 0;
29310 +int debug_netlink = 0;
29311 +#endif /* CONFIG_KLIPS_DEBUG */
29312 +
29313 +struct prng ipsec_prng;
29314 +
29315 +
29316 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29317 +xfrm4_rcv_encap_t klips_old_encap = NULL;
29318 +#endif
29319 +
29320 +extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
29321 +/*
29322 + * the following structure is required so that we receive
29323 + * event notifications when network devices are enabled and
29324 + * disabled (ifconfig up and down).
29325 + */
29326 +static struct notifier_block ipsec_dev_notifier={
29327 + ipsec_device_event,
29328 + NULL,
29329 + 0
29330 +};
29331 +
29332 +#ifdef CONFIG_SYSCTL
29333 +extern int ipsec_sysctl_register(void);
29334 +extern void ipsec_sysctl_unregister(void);
29335 +#endif
29336 +
29337 +#if defined(NET_26) || defined(IPSKB_XFRM_TUNNEL_SIZE)
29338 +static inline int
29339 +openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
29340 +{
29341 + return inet_add_protocol(prot, protocol);
29342 +}
29343 +
29344 +static inline int
29345 +openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
29346 +{
29347 + return inet_del_protocol(prot, protocol);
29348 +}
29349 +
29350 +#else
29351 +static inline int
29352 +openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
29353 +{
29354 + inet_add_protocol(prot);
29355 + return 0;
29356 +}
29357 +
29358 +static inline int
29359 +openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
29360 +{
29361 + inet_del_protocol(prot);
29362 + return 0;
29363 +}
29364 +
29365 +#endif
29366 +
29367 +/* void */
29368 +int
29369 +ipsec_klips_init(void)
29370 +{
29371 + int error = 0;
29372 + unsigned char seed[256];
29373 +#ifdef CONFIG_KLIPS_ENC_3DES
29374 + extern int des_check_key;
29375 +
29376 + /* turn off checking of keys */
29377 + des_check_key=0;
29378 +#endif /* CONFIG_KLIPS_ENC_3DES */
29379 +
29380 + KLIPS_PRINT(1, "klips_info:ipsec_init: "
29381 + "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n",
29382 + ipsec_version_code());
29383 +
29384 + error |= ipsec_proc_init();
29385 +
29386 +#ifdef SPINLOCK
29387 + ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
29388 +#else /* SPINLOCK */
29389 + ipsec_sadb.sadb_lock = 0;
29390 +#endif /* SPINLOCK */
29391 +
29392 +#ifndef SPINLOCK
29393 + tdb_lock.lock = 0;
29394 + eroute_lock.lock = 0;
29395 +#endif /* !SPINLOCK */
29396 +
29397 + error |= ipsec_sadb_init();
29398 + error |= ipsec_radijinit();
29399 +
29400 + error |= pfkey_init();
29401 +
29402 + error |= register_netdevice_notifier(&ipsec_dev_notifier);
29403 +
29404 +#ifdef CONFIG_KLIPS_ESP
29405 + openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP);
29406 +#endif /* CONFIG_KLIPS_ESP */
29407 +
29408 +#ifdef CONFIG_KLIPS_AH
29409 + openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH);
29410 +#endif /* CONFIG_KLIPS_AH */
29411 +
29412 +/* we never actually link IPCOMP to the stack */
29413 +#ifdef IPCOMP_USED_ALONE
29414 +#ifdef CONFIG_KLIPS_IPCOMP
29415 + openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP);
29416 +#endif /* CONFIG_KLIPS_IPCOMP */
29417 +#endif
29418 +
29419 + error |= ipsec_tunnel_init_devices();
29420 +
29421 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29422 + /* register our ESP-UDP handler */
29423 + if(udp4_register_esp_rcvencap(klips26_rcv_encap
29424 + , &klips_old_encap)!=0) {
29425 + printk(KERN_ERR "KLIPS: can not register klips_rcv_encap function\n");
29426 + }
29427 +#endif
29428 +
29429 +
29430 +#ifdef CONFIG_SYSCTL
29431 + error |= ipsec_sysctl_register();
29432 +#endif
29433 +
29434 + ipsec_alg_init();
29435 +
29436 + get_random_bytes((void *)seed, sizeof(seed));
29437 + prng_init(&ipsec_prng, seed, sizeof(seed));
29438 +
29439 + return error;
29440 +}
29441 +
29442 +
29443 +/* void */
29444 +int
29445 +ipsec_cleanup(void)
29446 +{
29447 + int error = 0;
29448 +
29449 +#ifdef CONFIG_SYSCTL
29450 + ipsec_sysctl_unregister();
29451 +#endif
29452 +#if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
29453 + if(udp4_unregister_esp_rcvencap(klips_old_encap) < 0) {
29454 + printk(KERN_ERR "KLIPS: can not unregister klips_rcv_encap function\n");
29455 + }
29456 +#endif
29457 +
29458 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29459 + "klips_debug:ipsec_cleanup: "
29460 + "calling ipsec_tunnel_cleanup_devices.\n");
29461 + error |= ipsec_tunnel_cleanup_devices();
29462 +
29463 + KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
29464 +
29465 +/* we never actually link IPCOMP to the stack */
29466 +#ifdef IPCOMP_USED_ALONE
29467 +#ifdef CONFIG_KLIPS_IPCOMP
29468 + if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
29469 + printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29470 + "comp close: can't remove protocol\n");
29471 +#endif /* CONFIG_KLIPS_IPCOMP */
29472 +#endif /* IPCOMP_USED_ALONE */
29473 +
29474 +#ifdef CONFIG_KLIPS_AH
29475 + if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
29476 + printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29477 + "ah close: can't remove protocol\n");
29478 +#endif /* CONFIG_KLIPS_AH */
29479 +
29480 +#ifdef CONFIG_KLIPS_ESP
29481 + if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0)
29482 + printk(KERN_INFO "klips_debug:ipsec_cleanup: "
29483 + "esp close: can't remove protocol\n");
29484 +#endif /* CONFIG_KLIPS_ESP */
29485 +
29486 + error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
29487 +
29488 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29489 + "klips_debug:ipsec_cleanup: "
29490 + "calling ipsec_sadb_cleanup.\n");
29491 + error |= ipsec_sadb_cleanup(0);
29492 + error |= ipsec_sadb_free();
29493 +
29494 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29495 + "klips_debug:ipsec_cleanup: "
29496 + "calling ipsec_radijcleanup.\n");
29497 + error |= ipsec_radijcleanup();
29498 +
29499 + KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
29500 + "klips_debug:ipsec_cleanup: "
29501 + "calling pfkey_cleanup.\n");
29502 + error |= pfkey_cleanup();
29503 +
29504 + ipsec_proc_cleanup();
29505 +
29506 + prng_final(&ipsec_prng);
29507 +
29508 + return error;
29509 +}
29510 +
29511 +#ifdef MODULE
29512 +int
29513 +init_module(void)
29514 +{
29515 + int error = 0;
29516 +
29517 + error |= ipsec_klips_init();
29518 +
29519 + return error;
29520 +}
29521 +
29522 +void
29523 +cleanup_module(void)
29524 +{
29525 + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
29526 + "klips_debug:cleanup_module: "
29527 + "calling ipsec_cleanup.\n");
29528 +
29529 + ipsec_cleanup();
29530 +
29531 + KLIPS_PRINT(1, "klips_info:cleanup_module: "
29532 + "ipsec module unloaded.\n");
29533 +}
29534 +#endif /* MODULE */
29535 +
29536 +/*
29537 + * $Log: ipsec_init.c,v $
29538 + * Revision 1.104.2.4 2006/10/06 21:39:26 paul
29539 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
29540 + * set. This is defined through autoconf.h which is included through the
29541 + * linux kernel build macros.
29542 + *
29543 + * Revision 1.104.2.3 2006/07/31 15:25:20 paul
29544 + * Check for NETKEY backport in Debian using IPSKB_XFRM_TUNNEL_SIZE to
29545 + * determine wether inet_add_protocol needs the protocol argument.
29546 + *
29547 + * Revision 1.104.2.2 2006/04/20 16:33:06 mcr
29548 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
29549 + * Fix in-kernel module compilation. Sub-makefiles do not work.
29550 + *
29551 + * Revision 1.104.2.1 2005/08/12 01:18:20 ken
29552 + * Warn people who don't have NAT-T patch applied, but try and compile NAT-T code
29553 + *
29554 + * Revision 1.105 2005/08/12 00:56:33 mcr
29555 + * add warning for people who didn't apply nat-t patch.
29556 + *
29557 + * Revision 1.104 2005/07/08 15:51:41 mcr
29558 + * removed duplicate NAT-T code.
29559 + * if CONFIG_IPSEC_NAT_TRAVERSAL isn't defined, then there is no issue.
29560 + *
29561 + * Revision 1.103 2005/07/08 03:02:05 paul
29562 + * Fixed garbled define that accidentally got commited to the real tree.
29563 + *
29564 + * Revision 1.102 2005/07/08 02:56:37 paul
29565 + * gcc4 fixes that were not commited because vault was down
29566 + *
29567 + * Revision 1.101 2005/04/29 05:10:22 mcr
29568 + * removed from extraenous includes to make unit testing easier.
29569 + *
29570 + * Revision 1.100 2005/04/10 22:56:09 mcr
29571 + * change to udp.c registration API.
29572 + *
29573 + * Revision 1.99 2005/04/08 18:26:13 mcr
29574 + * register with udp.c, the klips26 encap receive function
29575 + *
29576 + * Revision 1.98 2004/09/13 02:23:18 mcr
29577 + * #define inet_protocol if necessary.
29578 + *
29579 + * Revision 1.97 2004/09/06 18:35:49 mcr
29580 + * 2.6.8.1 gets rid of inet_protocol->net_protocol compatibility,
29581 + * so adjust for that.
29582 + *
29583 + * Revision 1.96 2004/08/17 03:27:23 mcr
29584 + * klips 2.6 edits.
29585 + *
29586 + * Revision 1.95 2004/08/03 18:19:08 mcr
29587 + * in 2.6, use "net_device" instead of #define device->net_device.
29588 + * this probably breaks 2.0 compiles.
29589 + *
29590 + * Revision 1.94 2004/07/10 19:11:18 mcr
29591 + * CONFIG_IPSEC -> CONFIG_KLIPS.
29592 + *
29593 + * Revision 1.93 2004/04/06 02:49:26 mcr
29594 + * pullup of algo code from alg-branch.
29595 + *
29596 + * Revision 1.92 2004/03/30 15:30:39 ken
29597 + * Proper Capitalization
29598 + *
29599 + * Revision 1.91 2004/03/22 01:51:51 ken
29600 + * We are open
29601 + *
29602 + * Revision 1.90.4.2 2004/04/05 04:30:46 mcr
29603 + * patches for alg-branch to compile/work with 2.x openswan
29604 + *
29605 + * Revision 1.90.4.1 2003/12/22 15:25:52 jjo
29606 + * Merged algo-0.8.1-rc11-test1 into alg-branch
29607 + *
29608 + * Revision 1.90 2003/10/31 02:27:55 mcr
29609 + * pulled up port-selector patches and sa_id elimination.
29610 + *
29611 + * Revision 1.89.4.1 2003/10/29 01:30:41 mcr
29612 + * elimited "struct sa_id".
29613 + *
29614 + * Revision 1.89 2003/07/31 22:47:16 mcr
29615 + * preliminary (untested by FS-team) 2.5 patches.
29616 + *
29617 + * Revision 1.88 2003/06/22 20:05:36 mcr
29618 + * clarified why IPCOMP was not being registered, and put a new
29619 + * #ifdef in rather than #if 0.
29620 + *
29621 + * Revision 1.87 2002/09/20 15:40:51 rgb
29622 + * Added a lock to the global ipsec_sadb struct for future use.
29623 + * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
29624 + * of freeing newly created structures when clearing the reftable upon startup
29625 + * to start from a known state.
29626 + *
29627 + * Revision 1.86 2002/08/15 18:39:15 rgb
29628 + * Move ipsec_prng outside debug code.
29629 + *
29630 + * Revision 1.85 2002/05/14 02:35:29 rgb
29631 + * Change reference to tdb to ipsa.
29632 + *
29633 + * Revision 1.84 2002/04/24 07:55:32 mcr
29634 + * #include patches and Makefiles for post-reorg compilation.
29635 + *
29636 + * Revision 1.83 2002/04/24 07:36:28 mcr
29637 + * Moved from ./klips/net/ipsec/ipsec_init.c,v
29638 + *
29639 + * Revision 1.82 2002/04/20 00:12:25 rgb
29640 + * Added esp IV CBC attack fix, disabled.
29641 + *
29642 + * Revision 1.81 2002/04/09 16:13:32 mcr
29643 + * switch license to straight GPL.
29644 + *
29645 + * Revision 1.80 2002/03/24 07:34:08 rgb
29646 + * Sanity check for at least one of AH or ESP configured.
29647 + *
29648 + * Revision 1.79 2002/02/05 22:55:15 mcr
29649 + * added MODULE_LICENSE declaration.
29650 + * This macro does not appear in all kernel versions (see comment).
29651 + *
29652 + * Revision 1.78 2002/01/29 17:17:55 mcr
29653 + * moved include of ipsec_param.h to after include of linux/kernel.h
29654 + * otherwise, it seems that some option that is set in ipsec_param.h
29655 + * screws up something subtle in the include path to kernel.h, and
29656 + * it complains on the snprintf() prototype.
29657 + *
29658 + * Revision 1.77 2002/01/29 04:00:51 mcr
29659 + * more excise of kversions.h header.
29660 + *
29661 + * Revision 1.76 2002/01/29 02:13:17 mcr
29662 + * introduction of ipsec_kversion.h means that include of
29663 + * ipsec_param.h must preceed any decisions about what files to
29664 + * include to deal with differences in kernel source.
29665 + *
29666 + * Revision 1.75 2001/11/26 09:23:48 rgb
29667 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
29668 + *
29669 + * Revision 1.74 2001/11/22 05:44:11 henry
29670 + * new version stuff
29671 + *
29672 + * Revision 1.71.2.2 2001/10/22 20:51:00 mcr
29673 + * explicitely set des_check_key.
29674 + *
29675 + * Revision 1.71.2.1 2001/09/25 02:19:39 mcr
29676 + * /proc manipulation code moved to new ipsec_proc.c
29677 + *
29678 + * Revision 1.73 2001/11/06 19:47:17 rgb
29679 + * Changed lifetime_packets to uint32 from uint64.
29680 + *
29681 + * Revision 1.72 2001/10/18 04:45:19 rgb
29682 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
29683 + * lib/freeswan.h version macros moved to lib/kversions.h.
29684 + * Other compiler directive cleanups.
29685 + *
29686 + * Revision 1.71 2001/09/20 15:32:45 rgb
29687 + * Minor pfkey lifetime fixes.
29688 + *
29689 + * Revision 1.70 2001/07/06 19:51:21 rgb
29690 + * Added inbound policy checking code for IPIP SAs.
29691 + *
29692 + * Revision 1.69 2001/06/14 19:33:26 rgb
29693 + * Silence startup message for console, but allow it to be logged.
29694 + * Update copyright date.
29695 + *
29696 + * Revision 1.68 2001/05/29 05:14:36 rgb
29697 + * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'.
29698 + *
29699 + * Revision 1.67 2001/05/04 16:34:52 rgb
29700 + * Rremove erroneous checking of return codes for proc_net_* in 2.4.
29701 + *
29702 + * Revision 1.66 2001/05/03 19:40:34 rgb
29703 + * Check error return codes in startup and shutdown.
29704 + *
29705 + * Revision 1.65 2001/02/28 05:03:27 rgb
29706 + * Clean up and rationalise startup messages.
29707 + *
29708 + * Revision 1.64 2001/02/27 22:24:53 rgb
29709 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
29710 + * Check for satoa() return codes.
29711 + *
29712 + * Revision 1.63 2000/11/29 20:14:06 rgb
29713 + * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
29714 + *
29715 + * Revision 1.62 2000/11/06 04:31:24 rgb
29716 + * Ditched spin_lock_irqsave in favour of spin_lock_bh.
29717 + * Fixed longlong for pre-2.4 kernels (Svenning).
29718 + * Add Svenning's adaptive content compression.
29719 + * Disabled registration of ipcomp handler.
29720 + *
29721 + * Revision 1.61 2000/10/11 13:37:54 rgb
29722 + * #ifdef out debug print that causes proc/net/ipsec_version to oops.
29723 + *
29724 + * Revision 1.60 2000/09/20 03:59:01 rgb
29725 + * Change static info functions to DEBUG_NO_STATIC to reveal function names
29726 + * in oopsen.
29727 + *
29728 + * Revision 1.59 2000/09/16 01:06:26 rgb
29729 + * Added cast of var to silence compiler warning about long fed to int
29730 + * format.
29731 + *
29732 + * Revision 1.58 2000/09/15 11:37:01 rgb
29733 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
29734 + * IPCOMP zlib deflate code.
29735 + *
29736 + * Revision 1.57 2000/09/12 03:21:50 rgb
29737 + * Moved radij_c_version printing to ipsec_version_get_info().
29738 + * Reformatted ipsec_version_get_info().
29739 + * Added sysctl_{,un}register() calls.
29740 + *
29741 + * Revision 1.56 2000/09/08 19:16:50 rgb
29742 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
29743 + * Removed all references to CONFIG_IPSEC_PFKEYv2.
29744 + *
29745 + * Revision 1.55 2000/08/30 05:19:03 rgb
29746 + * Cleaned up no longer used spi_next, netlink register/unregister, other
29747 + * minor cleanup.
29748 + * Removed cruft replaced by TDB_XFORM_NAME.
29749 + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
29750 + * Moved debug version strings to printk when /proc/net/ipsec_version is
29751 + * called.
29752 + *
29753 + * Revision 1.54 2000/08/20 18:31:05 rgb
29754 + * Changed cosmetic alignment in spi_info.
29755 + * Changed addtime and usetime to use actual value which is relative
29756 + * anyways, as intended. (Momchil)
29757 + *
29758 + * Revision 1.53 2000/08/18 17:37:03 rgb
29759 + * Added an (int) cast to shut up the compiler...
29760 + *
29761 + * Revision 1.52 2000/08/01 14:51:50 rgb
29762 + * Removed _all_ remaining traces of DES.
29763 + *
29764 + * Revision 1.51 2000/07/25 20:41:22 rgb
29765 + * Removed duplicate parameter in spi_getinfo.
29766 + *
29767 + * Revision 1.50 2000/07/17 03:21:45 rgb
29768 + * Removed /proc/net/ipsec_spinew.
29769 + *
29770 + * Revision 1.49 2000/06/28 05:46:51 rgb
29771 + * Renamed ivlen to iv_bits for consistency.
29772 + * Changed output of add and use times to be relative to now.
29773 + *
29774 + * Revision 1.48 2000/05/11 18:26:10 rgb
29775 + * Commented out calls to netlink_attach/detach to avoid activating netlink
29776 + * in the kenrel config.
29777 + *
29778 + * Revision 1.47 2000/05/10 22:35:26 rgb
29779 + * Comment out most of the startup version information.
29780 + *
29781 + * Revision 1.46 2000/03/22 16:15:36 rgb
29782 + * Fixed renaming of dev_get (MB).
29783 + *
29784 + * Revision 1.45 2000/03/16 06:40:48 rgb
29785 + * Hardcode PF_KEYv2 support.
29786 + *
29787 + * Revision 1.44 2000/01/22 23:19:20 rgb
29788 + * Simplified code to use existing macro TDB_XFORM_NAME().
29789 + *
29790 + * Revision 1.43 2000/01/21 06:14:04 rgb
29791 + * Print individual stats only if non-zero.
29792 + * Removed 'bits' from each keylength for brevity.
29793 + * Shortened lifetimes legend for brevity.
29794 + * Changed wording from 'last_used' to the clearer 'idle'.
29795 + *
29796 + * Revision 1.42 1999/12/31 14:57:19 rgb
29797 + * MB fix for new dummy-less proc_get_info in 2.3.35.
29798 + *
29799 + *
29800 + * Local variables:
29801 + * c-file-style: "linux"
29802 + * End:
29803 + *
29804 + */
29805 --- /dev/null Tue Mar 11 13:02:56 2003
29806 +++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004
29807 @@ -0,0 +1,256 @@
29808 +/*
29809 + * processing code for IPCOMP
29810 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
29811 + *
29812 + * This program is free software; you can redistribute it and/or modify it
29813 + * under the terms of the GNU General Public License as published by the
29814 + * Free Software Foundation; either version 2 of the License, or (at your
29815 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
29816 + *
29817 + * This program is distributed in the hope that it will be useful, but
29818 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
29819 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29820 + * for more details.
29821 + */
29822 +
29823 +char ipsec_ipcomp_c_version[] = "RCSID $Id: ipsec_ipcomp.c,v 1.5.2.2 2006/10/06 21:39:26 paul Exp $";
29824 +#ifndef AUTOCONF_INCLUDED
29825 +#include <linux/config.h>
29826 +#endif
29827 +#include <linux/version.h>
29828 +
29829 +#define __NO_VERSION__
29830 +#include <linux/module.h>
29831 +#include <linux/kernel.h> /* printk() */
29832 +
29833 +#include "openswan/ipsec_param.h"
29834 +
29835 +#ifdef MALLOC_SLAB
29836 +# include <linux/slab.h> /* kmalloc() */
29837 +#else /* MALLOC_SLAB */
29838 +# include <linux/malloc.h> /* kmalloc() */
29839 +#endif /* MALLOC_SLAB */
29840 +#include <linux/errno.h> /* error codes */
29841 +#include <linux/types.h> /* size_t */
29842 +#include <linux/interrupt.h> /* mark_bh */
29843 +
29844 +#include <linux/netdevice.h> /* struct device, and other headers */
29845 +#include <linux/etherdevice.h> /* eth_type_trans */
29846 +#include <linux/ip.h> /* struct iphdr */
29847 +#include <linux/skbuff.h>
29848 +#include <openswan.h>
29849 +#ifdef SPINLOCK
29850 +# ifdef SPINLOCK_23
29851 +# include <linux/spinlock.h> /* *lock* */
29852 +# else /* SPINLOCK_23 */
29853 +# include <asm/spinlock.h> /* *lock* */
29854 +# endif /* SPINLOCK_23 */
29855 +#endif /* SPINLOCK */
29856 +
29857 +#include <net/ip.h>
29858 +
29859 +#include "openswan/radij.h"
29860 +#include "openswan/ipsec_encap.h"
29861 +#include "openswan/ipsec_sa.h"
29862 +
29863 +#include "openswan/ipsec_radij.h"
29864 +#include "openswan/ipsec_xform.h"
29865 +#include "openswan/ipsec_tunnel.h"
29866 +#include "openswan/ipsec_rcv.h"
29867 +#include "openswan/ipsec_xmit.h"
29868 +
29869 +#include "openswan/ipsec_auth.h"
29870 +
29871 +#ifdef CONFIG_KLIPS_IPCOMP
29872 +#include "openswan/ipsec_ipcomp.h"
29873 +#endif /* CONFIG_KLIPS_IPCOMP */
29874 +
29875 +#include "openswan/ipsec_proto.h"
29876 +
29877 +#ifdef CONFIG_KLIPS_DEBUG
29878 +int debug_ipcomp = 0;
29879 +#endif /* CONFIG_KLIPS_DEBUG */
29880 +
29881 +
29882 +#ifdef CONFIG_KLIPS_IPCOMP
29883 +enum ipsec_rcv_value
29884 +ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
29885 + struct sk_buff *skb)
29886 +{
29887 + int ipcompminlen;
29888 +
29889 + ipcompminlen = sizeof(struct iphdr);
29890 +
29891 + if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
29892 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
29893 + "klips_debug:ipsec_rcv: "
29894 + "runt comp packet of skb->len=%d received from %s, dropped.\n",
29895 + skb->len,
29896 + irs->ipsaddr_txt);
29897 + if(irs->stats) {
29898 + irs->stats->rx_errors++;
29899 + }
29900 + return IPSEC_RCV_BADLEN;
29901 + }
29902 +
29903 + irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)skb->h.raw;
29904 + irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
29905 + return IPSEC_RCV_OK;
29906 +}
29907 +
29908 +enum ipsec_rcv_value
29909 +ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
29910 +{
29911 + unsigned int flags = 0;
29912 + struct ipsec_sa *ipsp = irs->ipsp;
29913 + struct sk_buff *skb;
29914 +
29915 + skb=irs->skb;
29916 +
29917 + ipsec_xmit_dmp("ipcomp", skb->h.raw, skb->len);
29918 +
29919 + if(ipsp == NULL) {
29920 + return IPSEC_RCV_SAIDNOTFOUND;
29921 + }
29922 +
29923 + if(sysctl_ipsec_inbound_policy_check &&
29924 + ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
29925 + (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */
29926 + ))) {
29927 + char sa2[SATOT_BUF];
29928 + size_t sa_len2 = 0;
29929 +
29930 + sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2));
29931 +
29932 + KLIPS_PRINT(debug_rcv,
29933 + "klips_debug:ipsec_rcv: "
29934 + "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",
29935 + irs->sa_len ? irs->sa : " (error)",
29936 + ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
29937 + ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
29938 + (__u32)ntohl(irs->said.spi),
29939 + ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29940 + ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
29941 + if(irs->stats) {
29942 + irs->stats->rx_dropped++;
29943 + }
29944 + return IPSEC_RCV_SAIDNOTFOUND;
29945 + }
29946 +
29947 + ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
29948 + irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
29949 +
29950 + skb = skb_decompress(skb, ipsp, &flags);
29951 + if (!skb || flags) {
29952 + spin_unlock(&tdb_lock);
29953 + KLIPS_PRINT(debug_rcv,
29954 + "klips_debug:ipsec_rcv: "
29955 + "skb_decompress() returned error flags=%x, dropped.\n",
29956 + flags);
29957 + if (irs->stats) {
29958 + if (flags)
29959 + irs->stats->rx_errors++;
29960 + else
29961 + irs->stats->rx_dropped++;
29962 + }
29963 + return IPSEC_RCV_IPCOMPFAILED;
29964 + }
29965 +
29966 + /* make sure we update the pointer */
29967 + irs->skb = skb;
29968 +
29969 +#ifdef NET_21
29970 + irs->ipp = skb->nh.iph;
29971 +#else /* NET_21 */
29972 + irs->ipp = skb->ip_hdr;
29973 +#endif /* NET_21 */
29974 +
29975 + ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
29976 +
29977 + KLIPS_PRINT(debug_rcv,
29978 + "klips_debug:ipsec_rcv: "
29979 + "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
29980 + irs->sa_len ? irs->sa : " (error)",
29981 + (__u32)ntohl(irs->said.spi),
29982 + ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
29983 + ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
29984 + irs->next_header);
29985 + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
29986 +
29987 + return IPSEC_RCV_OK;
29988 +}
29989 +
29990 +enum ipsec_xmit_value
29991 +ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
29992 +{
29993 + unsigned int flags = 0;
29994 +#ifdef CONFIG_KLIPS_DEBUG
29995 + unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
29996 +#endif /* CONFIG_KLIPS_DEBUG */
29997 +
29998 + ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
29999 +
30000 + ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
30001 +
30002 +#ifdef NET_21
30003 + ixs->iph = ixs->skb->nh.iph;
30004 +#else /* NET_21 */
30005 + ixs->iph = ixs->skb->ip_hdr;
30006 +#endif /* NET_21 */
30007 +
30008 + ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
30009 +
30010 +#ifdef CONFIG_KLIPS_DEBUG
30011 + if (debug_tunnel & DB_TN_CROUT)
30012 + {
30013 + if (old_tot_len > ntohs(ixs->iph->tot_len))
30014 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
30015 + "klips_debug:ipsec_xmit_encap_once: "
30016 + "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
30017 + old_tot_len, ntohs(ixs->iph->tot_len),
30018 + ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
30019 + ntohl(ixs->ipsp->ips_said.spi),
30020 + (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
30021 + else
30022 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
30023 + "klips_debug:ipsec_xmit_encap_once: "
30024 + "packet did not compress (flags = %d).\n",
30025 + flags);
30026 + }
30027 +#endif /* CONFIG_KLIPS_DEBUG */
30028 +
30029 + return IPSEC_XMIT_OK;
30030 +}
30031 +
30032 +struct xform_functions ipcomp_xform_funcs[]={
30033 + {rcv_checks: ipsec_rcv_ipcomp_checks,
30034 + rcv_decrypt: ipsec_rcv_ipcomp_decomp,
30035 + xmit_setup: ipsec_xmit_ipcomp_setup,
30036 + xmit_headroom: 0,
30037 + xmit_needtailroom: 0,
30038 + },
30039 +};
30040 +
30041 +#if 0
30042 +/* We probably don't want to install a pure IPCOMP protocol handler, but
30043 + only want to handle IPCOMP if it is encapsulated inside an ESP payload
30044 + (which is already handled) */
30045 +#ifdef CONFIG_KLIPS_IPCOMP
30046 +struct inet_protocol comp_protocol =
30047 +{
30048 + ipsec_rcv, /* COMP handler */
30049 + NULL, /* COMP error control */
30050 +#ifdef NETDEV_25
30051 + 1, /* no policy */
30052 +#else
30053 + 0, /* next */
30054 + IPPROTO_COMP, /* protocol ID */
30055 + 0, /* copy */
30056 + NULL, /* data */
30057 + "COMP" /* name */
30058 +#endif
30059 +};
30060 +#endif /* CONFIG_KLIPS_IPCOMP */
30061 +#endif
30062 +
30063 +#endif /* CONFIG_KLIPS_IPCOMP */
30064 --- /dev/null Tue Mar 11 13:02:56 2003
30065 +++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004
30066 @@ -0,0 +1,122 @@
30067 +/*
30068 + * processing code for IPIP
30069 + * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
30070 + *
30071 + * This program is free software; you can redistribute it and/or modify it
30072 + * under the terms of the GNU General Public License as published by the
30073 + * Free Software Foundation; either version 2 of the License, or (at your
30074 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30075 + *
30076 + * This program is distributed in the hope that it will be useful, but
30077 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30078 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30079 + * for more details.
30080 + */
30081 +
30082 +char ipsec_ipip_c_version[] = "RCSID $Id: ipsec_ipip.c,v 1.3.2.3 2006/10/06 21:39:26 paul Exp $";
30083 +#ifndef AUTOCONF_INCLUDED
30084 +#include <linux/config.h>
30085 +#endif
30086 +#include <linux/version.h>
30087 +
30088 +#define __NO_VERSION__
30089 +#include <linux/module.h>
30090 +#include <linux/kernel.h> /* printk() */
30091 +
30092 +#include "openswan/ipsec_param.h"
30093 +
30094 +#ifdef MALLOC_SLAB
30095 +# include <linux/slab.h> /* kmalloc() */
30096 +#else /* MALLOC_SLAB */
30097 +# include <linux/malloc.h> /* kmalloc() */
30098 +#endif /* MALLOC_SLAB */
30099 +#include <linux/errno.h> /* error codes */
30100 +#include <linux/types.h> /* size_t */
30101 +#include <linux/interrupt.h> /* mark_bh */
30102 +
30103 +#include <linux/netdevice.h> /* struct device, and other headers */
30104 +#include <linux/etherdevice.h> /* eth_type_trans */
30105 +#include <linux/ip.h> /* struct iphdr */
30106 +#include <linux/skbuff.h>
30107 +#include <openswan.h>
30108 +#ifdef SPINLOCK
30109 +# ifdef SPINLOCK_23
30110 +# include <linux/spinlock.h> /* *lock* */
30111 +# else /* SPINLOCK_23 */
30112 +# include <asm/spinlock.h> /* *lock* */
30113 +# endif /* SPINLOCK_23 */
30114 +#endif /* SPINLOCK */
30115 +
30116 +#include <net/ip.h>
30117 +
30118 +#include "openswan/radij.h"
30119 +#include "openswan/ipsec_encap.h"
30120 +#include "openswan/ipsec_sa.h"
30121 +
30122 +#include "openswan/ipsec_radij.h"
30123 +#include "openswan/ipsec_xform.h"
30124 +#include "openswan/ipsec_tunnel.h"
30125 +#include "openswan/ipsec_rcv.h"
30126 +#include "openswan/ipsec_xmit.h"
30127 +
30128 +#include "openswan/ipsec_auth.h"
30129 +#include "openswan/ipsec_ipip.h"
30130 +#include "openswan/ipsec_param.h"
30131 +
30132 +#include "openswan/ipsec_proto.h"
30133 +
30134 +enum ipsec_xmit_value
30135 +ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
30136 +{
30137 + ixs->iph->version = 4;
30138 +
30139 + switch(sysctl_ipsec_tos) {
30140 + case 0:
30141 +#ifdef NET_21
30142 + ixs->iph->tos = ixs->skb->nh.iph->tos;
30143 +#else /* NET_21 */
30144 + ixs->iph->tos = ixs->skb->ip_hdr->tos;
30145 +#endif /* NET_21 */
30146 + break;
30147 + case 1:
30148 + ixs->iph->tos = 0;
30149 + break;
30150 + default:
30151 + break;
30152 + }
30153 + ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
30154 + ixs->iph->frag_off = 0;
30155 + ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
30156 + ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
30157 + ixs->iph->protocol = IPPROTO_IPIP;
30158 + ixs->iph->ihl = sizeof(struct iphdr) >> 2;
30159 +
30160 + KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
30161 +
30162 + ixs->newdst = (__u32)ixs->iph->daddr;
30163 + ixs->newsrc = (__u32)ixs->iph->saddr;
30164 +
30165 +#ifdef NET_21
30166 + ixs->skb->h.ipiph = ixs->skb->nh.iph;
30167 +#endif /* NET_21 */
30168 + return IPSEC_XMIT_OK;
30169 +}
30170 +
30171 +struct xform_functions ipip_xform_funcs[]={
30172 + { rcv_checks: NULL,
30173 + rcv_setup_auth: NULL,
30174 + rcv_calc_auth: NULL,
30175 + rcv_decrypt: NULL,
30176 +
30177 + xmit_setup: ipsec_xmit_ipip_setup,
30178 + xmit_headroom: sizeof(struct iphdr),
30179 + xmit_needtailroom: 0,
30180 + },
30181 +};
30182 +
30183 +
30184 +
30185 +
30186 +
30187 +
30188 +
30189 --- /dev/null Tue Mar 11 13:02:56 2003
30190 +++ linux/net/ipsec/ipsec_kern24.c Mon Feb 9 13:51:03 2004
30191 @@ -0,0 +1,74 @@
30192 +/*
30193 + * Copyright 2005 (C) Michael Richardson <mcr@xelerance.com>
30194 + *
30195 + * This is a file of functions which are present in 2.6 kernels,
30196 + * but are not available by default in the 2.4 series.
30197 + *
30198 + * As such this code is usually from the Linux kernel, and is covered by
30199 + * GPL.
30200 + *
30201 + * This program is free software; you can redistribute it and/or modify it
30202 + * under the terms of the GNU General Public License as published by the
30203 + * Free Software Foundation; either version 2 of the License, or (at your
30204 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30205 + *
30206 + * This program is distributed in the hope that it will be useful, but
30207 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30208 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30209 + * for more details.
30210 + *
30211 + * $Id: ipsec_kern24.c,v 1.2 2005/05/20 03:19:18 mcr Exp $
30212 + *
30213 + */
30214 +
30215 +#include <linux/kernel.h>
30216 +#include <linux/mm.h>
30217 +#include <linux/spinlock.h>
30218 +
30219 +/*
30220 + * printk rate limiting, lifted from the networking subsystem.
30221 + *
30222 + * This enforces a rate limit: not more than one kernel message
30223 + * every printk_ratelimit_jiffies to make a denial-of-service
30224 + * attack impossible.
30225 + */
30226 +static spinlock_t ratelimit_lock = SPIN_LOCK_UNLOCKED;
30227 +
30228 +int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst)
30229 +{
30230 + static unsigned long toks = 10*5*HZ;
30231 + static unsigned long last_msg;
30232 + static int missed;
30233 + unsigned long flags;
30234 + unsigned long now = jiffies;
30235 +
30236 + spin_lock_irqsave(&ratelimit_lock, flags);
30237 + toks += now - last_msg;
30238 + last_msg = now;
30239 + if (toks > (ratelimit_burst * ratelimit_jiffies))
30240 + toks = ratelimit_burst * ratelimit_jiffies;
30241 + if (toks >= ratelimit_jiffies) {
30242 + int lost = missed;
30243 + missed = 0;
30244 + toks -= ratelimit_jiffies;
30245 + spin_unlock_irqrestore(&ratelimit_lock, flags);
30246 + if (lost)
30247 + printk(KERN_WARNING "printk: %d messages suppressed.\n", lost);
30248 + return 1;
30249 + }
30250 + missed++;
30251 + spin_unlock_irqrestore(&ratelimit_lock, flags);
30252 + return 0;
30253 +}
30254 +
30255 +/* minimum time in jiffies between messages */
30256 +int printk_ratelimit_jiffies = 5*HZ;
30257 +
30258 +/* number of messages we send before ratelimiting */
30259 +int printk_ratelimit_burst = 10;
30260 +
30261 +int printk_ratelimit(void)
30262 +{
30263 + return __printk_ratelimit(printk_ratelimit_jiffies,
30264 + printk_ratelimit_burst);
30265 +}
30266 --- /dev/null Tue Mar 11 13:02:56 2003
30267 +++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004
30268 @@ -0,0 +1,273 @@
30269 +/*
30270 + * @(#) lifetime structure utilities
30271 + *
30272 + * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
30273 + * and Michael Richardson <mcr@freeswan.org>
30274 + *
30275 + * This program is free software; you can redistribute it and/or modify it
30276 + * under the terms of the GNU General Public License as published by the
30277 + * Free Software Foundation; either version 2 of the License, or (at your
30278 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30279 + *
30280 + * This program is distributed in the hope that it will be useful, but
30281 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30282 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30283 + * for more details.
30284 + *
30285 + * RCSID $Id: ipsec_life.c,v 1.13.10.1 2006/10/06 21:39:26 paul Exp $
30286 + *
30287 + */
30288 +
30289 +/*
30290 + * This provides series of utility functions for dealing with lifetime
30291 + * structures.
30292 + *
30293 + * ipsec_check_lifetime - returns -1 hard lifetime exceeded
30294 + * 0 soft lifetime exceeded
30295 + * 1 everything is okay
30296 + * based upon whether or not the count exceeds hard/soft
30297 + *
30298 + */
30299 +
30300 +#define __NO_VERSION__
30301 +#include <linux/module.h>
30302 +#ifndef AUTOCONF_INCLUDED
30303 +#include <linux/config.h>
30304 +#endif /* for CONFIG_IP_FORWARD */
30305 +#include <linux/version.h>
30306 +#include <linux/kernel.h> /* printk() */
30307 +
30308 +#include "openswan/ipsec_param.h"
30309 +
30310 +#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
30311 +#include <linux/etherdevice.h> /* eth_type_trans */
30312 +#include <linux/skbuff.h>
30313 +#include <openswan.h>
30314 +
30315 +#include "openswan/radij.h"
30316 +#include "openswan/ipsec_life.h"
30317 +#include "openswan/ipsec_xform.h"
30318 +#include "openswan/ipsec_eroute.h"
30319 +#include "openswan/ipsec_encap.h"
30320 +#include "openswan/ipsec_radij.h"
30321 +
30322 +#include "openswan/ipsec_sa.h"
30323 +#include "openswan/ipsec_tunnel.h"
30324 +#include "openswan/ipsec_ipe4.h"
30325 +#include "openswan/ipsec_ah.h"
30326 +#include "openswan/ipsec_esp.h"
30327 +
30328 +#ifdef CONFIG_KLIPS_IPCOMP
30329 +#include "openswan/ipcomp.h"
30330 +#endif /* CONFIG_KLIPS_IPCOMP */
30331 +
30332 +#include <pfkeyv2.h>
30333 +#include <pfkey.h>
30334 +
30335 +#include "openswan/ipsec_proto.h"
30336 +
30337 +
30338 +enum ipsec_life_alive
30339 +ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
30340 + const char *lifename,
30341 + const char *saname,
30342 + enum ipsec_life_type ilt,
30343 + enum ipsec_direction idir,
30344 + struct ipsec_sa *ips)
30345 +{
30346 + __u64 count;
30347 + const char *dir;
30348 +
30349 + if(saname == NULL) {
30350 + saname = "unknown-SA";
30351 + }
30352 +
30353 + if(idir == ipsec_incoming) {
30354 + dir = "incoming";
30355 + } else {
30356 + dir = "outgoing";
30357 + }
30358 +
30359 +
30360 + if(ilt == ipsec_life_timebased) {
30361 + count = jiffies/HZ - il64->ipl_count;
30362 + } else {
30363 + count = il64->ipl_count;
30364 + }
30365 +
30366 + if(il64->ipl_hard &&
30367 + (count > il64->ipl_hard)) {
30368 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
30369 + "klips_debug:ipsec_lifetime_check: "
30370 + "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
30371 + "%s packet dropped.\n",
30372 + lifename,
30373 + IPS_XFORM_NAME(ips),
30374 + saname,
30375 + dir);
30376 +
30377 + pfkey_expire(ips, 1);
30378 + return ipsec_life_harddied;
30379 + }
30380 +
30381 + if(il64->ipl_soft &&
30382 + (count > il64->ipl_soft)) {
30383 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
30384 + "klips_debug:ipsec_lifetime_check: "
30385 + "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
30386 + "soft expire message sent up, %s packet still processed.\n",
30387 + lifename,
30388 + IPS_XFORM_NAME(ips),
30389 + saname,
30390 + dir);
30391 +
30392 + if(ips->ips_state != SADB_SASTATE_DYING) {
30393 + pfkey_expire(ips, 0);
30394 + }
30395 + ips->ips_state = SADB_SASTATE_DYING;
30396 +
30397 + return ipsec_life_softdied;
30398 + }
30399 + return ipsec_life_okay;
30400 +}
30401 +
30402 +
30403 +/*
30404 + * This function takes a buffer (with length), a lifetime name and type,
30405 + * and formats a string to represent the current values of the lifetime.
30406 + *
30407 + * It returns the number of bytes that the format took (or would take,
30408 + * if the buffer were large enough: snprintf semantics).
30409 + * This is used in /proc routines and in debug output.
30410 + */
30411 +int
30412 +ipsec_lifetime_format(char *buffer,
30413 + int buflen,
30414 + char *lifename,
30415 + enum ipsec_life_type timebaselife,
30416 + struct ipsec_lifetime64 *lifetime)
30417 +{
30418 + int len = 0;
30419 + __u64 count;
30420 +
30421 + if(timebaselife == ipsec_life_timebased) {
30422 + count = jiffies/HZ - lifetime->ipl_count;
30423 + } else {
30424 + count = lifetime->ipl_count;
30425 + }
30426 +
30427 + if(lifetime->ipl_count > 1 ||
30428 + lifetime->ipl_soft ||
30429 + lifetime->ipl_hard) {
30430 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
30431 + len = ipsec_snprintf(buffer, buflen,
30432 + "%s(%Lu,%Lu,%Lu)",
30433 + lifename,
30434 + count,
30435 + lifetime->ipl_soft,
30436 + lifetime->ipl_hard);
30437 +#else /* XXX high 32 bits are not displayed */
30438 + len = ipsec_snprintf(buffer, buflen,
30439 + "%s(%lu,%lu,%lu)",
30440 + lifename,
30441 + (unsigned long)count,
30442 + (unsigned long)lifetime->ipl_soft,
30443 + (unsigned long)lifetime->ipl_hard);
30444 +#endif
30445 + }
30446 +
30447 + return len;
30448 +}
30449 +
30450 +void
30451 +ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
30452 + __u64 newvalue)
30453 +{
30454 + if(newvalue &&
30455 + (!lifetime->ipl_hard ||
30456 + (newvalue < lifetime->ipl_hard))) {
30457 + lifetime->ipl_hard = newvalue;
30458 +
30459 + if(!lifetime->ipl_soft &&
30460 + (lifetime->ipl_hard < lifetime->ipl_soft)) {
30461 + lifetime->ipl_soft = lifetime->ipl_hard;
30462 + }
30463 + }
30464 +}
30465 +
30466 +void
30467 +ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
30468 + __u64 newvalue)
30469 +{
30470 + if(newvalue &&
30471 + (!lifetime->ipl_soft ||
30472 + (newvalue < lifetime->ipl_soft))) {
30473 + lifetime->ipl_soft = newvalue;
30474 +
30475 + if(lifetime->ipl_hard &&
30476 + (lifetime->ipl_hard < lifetime->ipl_soft)) {
30477 + lifetime->ipl_soft = lifetime->ipl_hard;
30478 + }
30479 + }
30480 +}
30481 +
30482 +
30483 +/*
30484 + * $Log: ipsec_life.c,v $
30485 + * Revision 1.13.10.1 2006/10/06 21:39:26 paul
30486 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
30487 + * set. This is defined through autoconf.h which is included through the
30488 + * linux kernel build macros.
30489 + *
30490 + * Revision 1.13 2004/07/10 19:11:18 mcr
30491 + * CONFIG_IPSEC -> CONFIG_KLIPS.
30492 + *
30493 + * Revision 1.12 2004/04/23 20:44:35 ken
30494 + * Update comments
30495 + *
30496 + * Revision 1.11 2004/04/06 02:49:26 mcr
30497 + * pullup of algo code from alg-branch.
30498 + *
30499 + * Revision 1.10 2004/03/30 11:03:10 paul
30500 + * two more occurances of snprintf, found by Sam from a users oops msg.
30501 + *
30502 + * Revision 1.9 2003/10/31 02:27:55 mcr
30503 + * pulled up port-selector patches and sa_id elimination.
30504 + *
30505 + * Revision 1.8.4.1 2003/10/29 01:30:41 mcr
30506 + * elimited "struct sa_id".
30507 + *
30508 + * Revision 1.8 2003/02/06 02:00:10 rgb
30509 + * Fixed incorrect debugging text label
30510 + *
30511 + * Revision 1.7 2002/05/23 07:16:26 rgb
30512 + * Fixed absolute/relative reference to lifetime count printout.
30513 + *
30514 + * Revision 1.6 2002/04/24 07:55:32 mcr
30515 + * #include patches and Makefiles for post-reorg compilation.
30516 + *
30517 + * Revision 1.5 2002/04/24 07:36:28 mcr
30518 + * Moved from ./klips/net/ipsec/ipsec_life.c,v
30519 + *
30520 + * Revision 1.4 2002/01/29 17:17:55 mcr
30521 + * moved include of ipsec_param.h to after include of linux/kernel.h
30522 + * otherwise, it seems that some option that is set in ipsec_param.h
30523 + * screws up something subtle in the include path to kernel.h, and
30524 + * it complains on the snprintf() prototype.
30525 + *
30526 + * Revision 1.3 2002/01/29 02:13:17 mcr
30527 + * introduction of ipsec_kversion.h means that include of
30528 + * ipsec_param.h must preceed any decisions about what files to
30529 + * include to deal with differences in kernel source.
30530 + *
30531 + * Revision 1.2 2001/11/26 09:16:14 rgb
30532 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
30533 + *
30534 + * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
30535 + * lifetime structure created and common functions created.
30536 + *
30537 + * Local variables:
30538 + * c-file-style: "linux"
30539 + * End:
30540 + *
30541 + */
30542 --- /dev/null Tue Mar 11 13:02:56 2003
30543 +++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004
30544 @@ -0,0 +1,1099 @@
30545 +/*
30546 + * IPSEC MAST code.
30547 + * Copyright (C) 1996, 1997 John Ioannidis.
30548 + * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
30549 + *
30550 + * This program is free software; you can redistribute it and/or modify it
30551 + * under the terms of the GNU General Public License as published by the
30552 + * Free Software Foundation; either version 2 of the License, or (at your
30553 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
30554 + *
30555 + * This program is distributed in the hope that it will be useful, but
30556 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
30557 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
30558 + * for more details.
30559 + */
30560 +
30561 +char ipsec_mast_c_version[] = "RCSID $Id: ipsec_mast.c,v 1.7.2.1 2006/10/06 21:39:26 paul Exp $";
30562 +
30563 +#define __NO_VERSION__
30564 +#include <linux/module.h>
30565 +#ifndef AUTOCONF_INCLUDED
30566 +#include <linux/config.h>
30567 +#endif /* for CONFIG_IP_FORWARD */
30568 +#include <linux/version.h>
30569 +#include <linux/kernel.h> /* printk() */
30570 +
30571 +#include "freeswan/ipsec_param.h"
30572 +
30573 +#ifdef MALLOC_SLAB
30574 +# include <linux/slab.h> /* kmalloc() */
30575 +#else /* MALLOC_SLAB */
30576 +# include <linux/malloc.h> /* kmalloc() */
30577 +#endif /* MALLOC_SLAB */
30578 +#include <linux/errno.h> /* error codes */
30579 +#include <linux/types.h> /* size_t */
30580 +#include <linux/interrupt.h> /* mark_bh */
30581 +
30582 +#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
30583 +#include <linux/etherdevice.h> /* eth_type_trans */
30584 +#include <linux/ip.h> /* struct iphdr */
30585 +#include <linux/tcp.h> /* struct tcphdr */
30586 +#include <linux/udp.h> /* struct udphdr */
30587 +#include <linux/skbuff.h>
30588 +#include <freeswan.h>
30589 +#include <linux/in6.h>
30590 +#include <net/dst.h>
30591 +#undef dev_kfree_skb
30592 +#define dev_kfree_skb(a,b) kfree_skb(a)
30593 +#define PHYSDEV_TYPE
30594 +#include <net/icmp.h> /* icmp_send() */
30595 +#include <net/ip.h>
30596 +#include <linux/netfilter_ipv4.h>
30597 +
30598 +#include <linux/if_arp.h>
30599 +
30600 +#include "freeswan/radij.h"
30601 +#include "freeswan/ipsec_life.h"
30602 +#include "freeswan/ipsec_xform.h"
30603 +#include "freeswan/ipsec_eroute.h"
30604 +#include "freeswan/ipsec_encap.h"
30605 +#include "freeswan/ipsec_radij.h"
30606 +#include "freeswan/ipsec_sa.h"
30607 +#include "freeswan/ipsec_tunnel.h"
30608 +#include "freeswan/ipsec_mast.h"
30609 +#include "freeswan/ipsec_ipe4.h"
30610 +#include "freeswan/ipsec_ah.h"
30611 +#include "freeswan/ipsec_esp.h"
30612 +
30613 +#include <pfkeyv2.h>
30614 +#include <pfkey.h>
30615 +
30616 +#include "freeswan/ipsec_proto.h"
30617 +
30618 +int ipsec_maxdevice_count = -1;
30619 +
30620 +DEBUG_NO_STATIC int
30621 +ipsec_mast_open(struct net_device *dev)
30622 +{
30623 + struct ipsecpriv *prv = dev->priv;
30624 +
30625 + /*
30626 + * Can't open until attached.
30627 + */
30628 +
30629 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
30630 + "klips_debug:ipsec_mast_open: "
30631 + "dev = %s, prv->dev = %s\n",
30632 + dev->name, prv->dev?prv->dev->name:"NONE");
30633 +
30634 + if (prv->dev == NULL)
30635 + return -ENODEV;
30636 +
30637 + KLIPS_INC_USE;
30638 + return 0;
30639 +}
30640 +
30641 +DEBUG_NO_STATIC int
30642 +ipsec_mast_close(struct net_device *dev)
30643 +{
30644 + KLIPS_DEC_USE;
30645 + return 0;
30646 +}
30647 +
30648 +static inline int ipsec_mast_xmit2(struct sk_buff *skb)
30649 +{
30650 + return ip_send(skb);
30651 +}
30652 +
30653 +enum ipsec_xmit_value
30654 +ipsec_mast_send(struct ipsec_xmit_state*ixs)
30655 +{
30656 + /* new route/dst cache code from James Morris */
30657 + ixs->skb->dev = ixs->physdev;
30658 + /*skb_orphan(ixs->skb);*/
30659 + if((ixs->error = ip_route_output(&ixs->route,
30660 + ixs->skb->nh.iph->daddr,
30661 + ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
30662 + RT_TOS(ixs->skb->nh.iph->tos),
30663 + ixs->physdev->iflink /* rgb: should this be 0? */))) {
30664 + ixs->stats->tx_errors++;
30665 + KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30666 + "klips_debug:ipsec_xmit_send: "
30667 + "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
30668 + ixs->error,
30669 + ixs->route->u.dst.dev->name);
30670 + return IPSEC_XMIT_ROUTEERR;
30671 + }
30672 + if(ixs->dev == ixs->route->u.dst.dev) {
30673 + ip_rt_put(ixs->route);
30674 + /* This is recursion, drop it. */
30675 + ixs->stats->tx_errors++;
30676 + KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30677 + "klips_debug:ipsec_xmit_send: "
30678 + "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
30679 + ixs->dev->name);
30680 + return IPSEC_XMIT_RECURSDETECT;
30681 + }
30682 + dst_release(ixs->skb->dst);
30683 + ixs->skb->dst = &ixs->route->u.dst;
30684 + ixs->stats->tx_bytes += ixs->skb->len;
30685 + if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
30686 + ixs->stats->tx_errors++;
30687 + printk(KERN_WARNING
30688 + "klips_error:ipsec_xmit_send: "
30689 + "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
30690 + (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
30691 + ixs->skb->len);
30692 + return IPSEC_XMIT_PUSHPULLERR;
30693 + }
30694 + __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
30695 +#ifdef SKB_RESET_NFCT
30696 + nf_conntrack_put(ixs->skb->nfct);
30697 + ixs->skb->nfct = NULL;
30698 +#ifdef CONFIG_NETFILTER_DEBUG
30699 + ixs->skb->nf_debug = 0;
30700 +#endif /* CONFIG_NETFILTER_DEBUG */
30701 +#endif /* SKB_RESET_NFCT */
30702 + KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
30703 + "klips_debug:ipsec_xmit_send: "
30704 + "...done, calling ip_send() on device:%s\n",
30705 + ixs->skb->dev ? ixs->skb->dev->name : "NULL");
30706 + KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
30707 + {
30708 + int err;
30709 +
30710 + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
30711 + ipsec_mast_xmit2);
30712 + if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
30713 + if(net_ratelimit())
30714 + printk(KERN_ERR
30715 + "klips_error:ipsec_xmit_send: "
30716 + "ip_send() failed, err=%d\n",
30717 + -err);
30718 + ixs->stats->tx_errors++;
30719 + ixs->stats->tx_aborted_errors++;
30720 + ixs->skb = NULL;
30721 + return IPSEC_XMIT_IPSENDFAILURE;
30722 + }
30723 + }
30724 + ixs->stats->tx_packets++;
30725 +
30726 + ixs->skb = NULL;
30727 +
30728 + return IPSEC_XMIT_OK;
30729 +}
30730 +
30731 +void
30732 +ipsec_mast_cleanup(struct ipsec_xmit_state*ixs)
30733 +{
30734 +#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
30735 + netif_wake_queue(ixs->dev);
30736 +#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30737 + ixs->dev->tbusy = 0;
30738 +#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
30739 + if(ixs->saved_header) {
30740 + kfree(ixs->saved_header);
30741 + }
30742 + if(ixs->skb) {
30743 + dev_kfree_skb(ixs->skb, FREE_WRITE);
30744 + }
30745 + if(ixs->oskb) {
30746 + dev_kfree_skb(ixs->oskb, FREE_WRITE);
30747 + }
30748 + if (ixs->ips.ips_ident_s.data) {
30749 + kfree(ixs->ips.ips_ident_s.data);
30750 + }
30751 + if (ixs->ips.ips_ident_d.data) {
30752 + kfree(ixs->ips.ips_ident_d.data);
30753 + }
30754 +}
30755 +
30756 +#if 0
30757 +/*
30758 + * This function assumes it is being called from dev_queue_xmit()
30759 + * and that skb is filled properly by that function.
30760 + */
30761 +int
30762 +ipsec_mast_start_xmit(struct sk_buff *skb, struct net_device *dev, IPsecSAref_t SAref)
30763 +{
30764 + struct ipsec_xmit_state ixs_mem;
30765 + struct ipsec_xmit_state *ixs = &ixs_mem;
30766 + enum ipsec_xmit_value stat = IPSEC_XMIT_OK;
30767 +
30768 + /* dev could be a mast device, but should be optional, I think... */
30769 + /* SAref is also optional, but one of the two must be present. */
30770 + /* I wonder if it could accept no device or saref and guess? */
30771 +
30772 +/* ipsec_xmit_sanity_check_dev(ixs); */
30773 +
30774 + ipsec_xmit_sanity_check_skb(ixs);
30775 +
30776 + ipsec_xmit_adjust_hard_header(ixs);
30777 +
30778 + stat = ipsec_xmit_encap_bundle(ixs);
30779 + if(stat != IPSEC_XMIT_OK) {
30780 + /* SA processing failed */
30781 + }
30782 +
30783 + ipsec_xmit_hard_header_restore();
30784 +}
30785 +#endif
30786 +
30787 +DEBUG_NO_STATIC struct net_device_stats *
30788 +ipsec_mast_get_stats(struct net_device *dev)
30789 +{
30790 + return &(((struct ipsecpriv *)(dev->priv))->mystats);
30791 +}
30792 +
30793 +/*
30794 + * Revectored calls.
30795 + * For each of these calls, a field exists in our private structure.
30796 + */
30797 +
30798 +DEBUG_NO_STATIC int
30799 +ipsec_mast_hard_header(struct sk_buff *skb, struct net_device *dev,
30800 + unsigned short type, void *daddr, void *saddr, unsigned len)
30801 +{
30802 + struct ipsecpriv *prv = dev->priv;
30803 + struct net_device *tmp;
30804 + int ret;
30805 + struct net_device_stats *stats; /* This device's statistics */
30806 +
30807 + if(skb == NULL) {
30808 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30809 + "klips_debug:ipsec_mast_hard_header: "
30810 + "no skb...\n");
30811 + return -ENODATA;
30812 + }
30813 +
30814 + if(dev == NULL) {
30815 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30816 + "klips_debug:ipsec_mast_hard_header: "
30817 + "no device...\n");
30818 + return -ENODEV;
30819 + }
30820 +
30821 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30822 + "klips_debug:ipsec_mast_hard_header: "
30823 + "skb->dev=%s dev=%s.\n",
30824 + skb->dev ? skb->dev->name : "NULL",
30825 + dev->name);
30826 +
30827 + if(prv == NULL) {
30828 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30829 + "klips_debug:ipsec_mast_hard_header: "
30830 + "no private space associated with dev=%s\n",
30831 + dev->name ? dev->name : "NULL");
30832 + return -ENODEV;
30833 + }
30834 +
30835 + stats = (struct net_device_stats *) &(prv->mystats);
30836 +
30837 + if(prv->dev == NULL) {
30838 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30839 + "klips_debug:ipsec_mast_hard_header: "
30840 + "no physical device associated with dev=%s\n",
30841 + dev->name ? dev->name : "NULL");
30842 + stats->tx_dropped++;
30843 + return -ENODEV;
30844 + }
30845 +
30846 + /* check if we have to send a IPv6 packet. It might be a Router
30847 + Solicitation, where the building of the packet happens in
30848 + reverse order:
30849 + 1. ll hdr,
30850 + 2. IPv6 hdr,
30851 + 3. ICMPv6 hdr
30852 + -> skb->nh.raw is still uninitialized when this function is
30853 + called!! If this is no IPv6 packet, we can print debugging
30854 + messages, otherwise we skip all debugging messages and just
30855 + build the ll header */
30856 + if(type != ETH_P_IPV6) {
30857 + /* execute this only, if we don't have to build the
30858 + header for a IPv6 packet */
30859 + if(!prv->hard_header) {
30860 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30861 + "klips_debug:ipsec_mast_hard_header: "
30862 + "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
30863 + saddr,
30864 + daddr,
30865 + len,
30866 + type,
30867 + dev->name);
30868 + KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
30869 + "ip=%08x->%08x\n",
30870 + (__u32)ntohl(skb->nh.iph->saddr),
30871 + (__u32)ntohl(skb->nh.iph->daddr) );
30872 + stats->tx_dropped++;
30873 + return -ENODEV;
30874 + }
30875 +
30876 +#define da ((struct net_device *)(prv->dev))->dev_addr
30877 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30878 + "klips_debug:ipsec_mast_hard_header: "
30879 + "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
30880 + saddr,
30881 + daddr,
30882 + len,
30883 + type,
30884 + dev->name,
30885 + prv->dev->name,
30886 + da[0], da[1], da[2], da[3], da[4], da[5]);
30887 + KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
30888 + "ip=%08x->%08x\n",
30889 + (__u32)ntohl(skb->nh.iph->saddr),
30890 + (__u32)ntohl(skb->nh.iph->daddr) );
30891 + } else {
30892 + KLIPS_PRINT(debug_mast,
30893 + "klips_debug:ipsec_mast_hard_header: "
30894 + "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
30895 + }
30896 + tmp = skb->dev;
30897 + skb->dev = prv->dev;
30898 + ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
30899 + skb->dev = tmp;
30900 + return ret;
30901 +}
30902 +
30903 +DEBUG_NO_STATIC int
30904 +ipsec_mast_rebuild_header(struct sk_buff *skb)
30905 +{
30906 + struct ipsecpriv *prv = skb->dev->priv;
30907 + struct net_device *tmp;
30908 + int ret;
30909 + struct net_device_stats *stats; /* This device's statistics */
30910 +
30911 + if(skb->dev == NULL) {
30912 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30913 + "klips_debug:ipsec_mast_rebuild_header: "
30914 + "no device...");
30915 + return -ENODEV;
30916 + }
30917 +
30918 + if(prv == NULL) {
30919 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30920 + "klips_debug:ipsec_mast_rebuild_header: "
30921 + "no private space associated with dev=%s",
30922 + skb->dev->name ? skb->dev->name : "NULL");
30923 + return -ENODEV;
30924 + }
30925 +
30926 + stats = (struct net_device_stats *) &(prv->mystats);
30927 +
30928 + if(prv->dev == NULL) {
30929 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30930 + "klips_debug:ipsec_mast_rebuild_header: "
30931 + "no physical device associated with dev=%s",
30932 + skb->dev->name ? skb->dev->name : "NULL");
30933 + stats->tx_dropped++;
30934 + return -ENODEV;
30935 + }
30936 +
30937 + if(!prv->rebuild_header) {
30938 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30939 + "klips_debug:ipsec_mast_rebuild_header: "
30940 + "physical device has been detached, packet dropped skb->dev=%s->NULL ",
30941 + skb->dev->name);
30942 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30943 + "ip=%08x->%08x\n",
30944 + (__u32)ntohl(skb->nh.iph->saddr),
30945 + (__u32)ntohl(skb->nh.iph->daddr) );
30946 + stats->tx_dropped++;
30947 + return -ENODEV;
30948 + }
30949 +
30950 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30951 + "klips_debug:ipsec_mast: "
30952 + "Revectored rebuild_header dev=%s->%s ",
30953 + skb->dev->name, prv->dev->name);
30954 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30955 + "ip=%08x->%08x\n",
30956 + (__u32)ntohl(skb->nh.iph->saddr),
30957 + (__u32)ntohl(skb->nh.iph->daddr) );
30958 + tmp = skb->dev;
30959 + skb->dev = prv->dev;
30960 +
30961 + ret = prv->rebuild_header(skb);
30962 + skb->dev = tmp;
30963 + return ret;
30964 +}
30965 +
30966 +DEBUG_NO_STATIC int
30967 +ipsec_mast_set_mac_address(struct net_device *dev, void *addr)
30968 +{
30969 + struct ipsecpriv *prv = dev->priv;
30970 +
30971 + struct net_device_stats *stats; /* This device's statistics */
30972 +
30973 + if(dev == NULL) {
30974 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30975 + "klips_debug:ipsec_mast_set_mac_address: "
30976 + "no device...");
30977 + return -ENODEV;
30978 + }
30979 +
30980 + if(prv == NULL) {
30981 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30982 + "klips_debug:ipsec_mast_set_mac_address: "
30983 + "no private space associated with dev=%s",
30984 + dev->name ? dev->name : "NULL");
30985 + return -ENODEV;
30986 + }
30987 +
30988 + stats = (struct net_device_stats *) &(prv->mystats);
30989 +
30990 + if(prv->dev == NULL) {
30991 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
30992 + "klips_debug:ipsec_mast_set_mac_address: "
30993 + "no physical device associated with dev=%s",
30994 + dev->name ? dev->name : "NULL");
30995 + stats->tx_dropped++;
30996 + return -ENODEV;
30997 + }
30998 +
30999 + if(!prv->set_mac_address) {
31000 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31001 + "klips_debug:ipsec_mast_set_mac_address: "
31002 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
31003 + dev->name);
31004 + return -ENODEV;
31005 + }
31006 +
31007 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31008 + "klips_debug:ipsec_mast_set_mac_address: "
31009 + "Revectored dev=%s->%s addr=0p%p\n",
31010 + dev->name, prv->dev->name, addr);
31011 + return prv->set_mac_address(prv->dev, addr);
31012 +
31013 +}
31014 +
31015 +DEBUG_NO_STATIC void
31016 +ipsec_mast_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
31017 +{
31018 + struct ipsecpriv *prv = dev->priv;
31019 +
31020 + struct net_device_stats *stats; /* This device's statistics */
31021 +
31022 + if(dev == NULL) {
31023 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31024 + "klips_debug:ipsec_mast_cache_update: "
31025 + "no device...");
31026 + return;
31027 + }
31028 +
31029 + if(prv == NULL) {
31030 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31031 + "klips_debug:ipsec_mast_cache_update: "
31032 + "no private space associated with dev=%s",
31033 + dev->name ? dev->name : "NULL");
31034 + return;
31035 + }
31036 +
31037 + stats = (struct net_device_stats *) &(prv->mystats);
31038 +
31039 + if(prv->dev == NULL) {
31040 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31041 + "klips_debug:ipsec_mast_cache_update: "
31042 + "no physical device associated with dev=%s",
31043 + dev->name ? dev->name : "NULL");
31044 + stats->tx_dropped++;
31045 + return;
31046 + }
31047 +
31048 + if(!prv->header_cache_update) {
31049 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31050 + "klips_debug:ipsec_mast_cache_update: "
31051 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
31052 + dev->name);
31053 + return;
31054 + }
31055 +
31056 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31057 + "klips_debug:ipsec_mast: "
31058 + "Revectored cache_update\n");
31059 + prv->header_cache_update(hh, prv->dev, haddr);
31060 + return;
31061 +}
31062 +
31063 +DEBUG_NO_STATIC int
31064 +ipsec_mast_neigh_setup(struct neighbour *n)
31065 +{
31066 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31067 + "klips_debug:ipsec_mast_neigh_setup:\n");
31068 +
31069 + if (n->nud_state == NUD_NONE) {
31070 + n->ops = &arp_broken_ops;
31071 + n->output = n->ops->output;
31072 + }
31073 + return 0;
31074 +}
31075 +
31076 +DEBUG_NO_STATIC int
31077 +ipsec_mast_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
31078 +{
31079 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31080 + "klips_debug:ipsec_mast_neigh_setup_dev: "
31081 + "setting up %s\n",
31082 + dev ? dev->name : "NULL");
31083 +
31084 + if (p->tbl->family == AF_INET) {
31085 + p->neigh_setup = ipsec_mast_neigh_setup;
31086 + p->ucast_probes = 0;
31087 + p->mcast_probes = 0;
31088 + }
31089 + return 0;
31090 +}
31091 +
31092 +/*
31093 + * We call the attach routine to attach another device.
31094 + */
31095 +
31096 +DEBUG_NO_STATIC int
31097 +ipsec_mast_attach(struct net_device *dev, struct net_device *physdev)
31098 +{
31099 + int i;
31100 + struct ipsecpriv *prv = dev->priv;
31101 +
31102 + if(dev == NULL) {
31103 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31104 + "klips_debug:ipsec_mast_attach: "
31105 + "no device...");
31106 + return -ENODEV;
31107 + }
31108 +
31109 + if(prv == NULL) {
31110 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31111 + "klips_debug:ipsec_mast_attach: "
31112 + "no private space associated with dev=%s",
31113 + dev->name ? dev->name : "NULL");
31114 + return -ENODATA;
31115 + }
31116 +
31117 + prv->dev = physdev;
31118 + prv->hard_start_xmit = physdev->hard_start_xmit;
31119 + prv->get_stats = physdev->get_stats;
31120 +
31121 + if (physdev->hard_header) {
31122 + prv->hard_header = physdev->hard_header;
31123 + dev->hard_header = ipsec_mast_hard_header;
31124 + } else
31125 + dev->hard_header = NULL;
31126 +
31127 + if (physdev->rebuild_header) {
31128 + prv->rebuild_header = physdev->rebuild_header;
31129 + dev->rebuild_header = ipsec_mast_rebuild_header;
31130 + } else
31131 + dev->rebuild_header = NULL;
31132 +
31133 + if (physdev->set_mac_address) {
31134 + prv->set_mac_address = physdev->set_mac_address;
31135 + dev->set_mac_address = ipsec_mast_set_mac_address;
31136 + } else
31137 + dev->set_mac_address = NULL;
31138 +
31139 + if (physdev->header_cache_update) {
31140 + prv->header_cache_update = physdev->header_cache_update;
31141 + dev->header_cache_update = ipsec_mast_cache_update;
31142 + } else
31143 + dev->header_cache_update = NULL;
31144 +
31145 + dev->hard_header_len = physdev->hard_header_len;
31146 +
31147 +/* prv->neigh_setup = physdev->neigh_setup; */
31148 + dev->neigh_setup = ipsec_mast_neigh_setup_dev;
31149 + dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
31150 + prv->mtu = physdev->mtu;
31151 +
31152 +#ifdef PHYSDEV_TYPE
31153 + dev->type = physdev->type; /* ARPHRD_MAST; */
31154 +#endif /* PHYSDEV_TYPE */
31155 +
31156 + dev->addr_len = physdev->addr_len;
31157 + for (i=0; i<dev->addr_len; i++) {
31158 + dev->dev_addr[i] = physdev->dev_addr[i];
31159 + }
31160 +#ifdef CONFIG_KLIPS_DEBUG
31161 + if(debug_mast & DB_MAST_INIT) {
31162 + printk(KERN_INFO "klips_debug:ipsec_mast_attach: "
31163 + "physical device %s being attached has HW address: %2x",
31164 + physdev->name, physdev->dev_addr[0]);
31165 + for (i=1; i < physdev->addr_len; i++) {
31166 + printk(":%02x", physdev->dev_addr[i]);
31167 + }
31168 + printk("\n");
31169 + }
31170 +#endif /* CONFIG_KLIPS_DEBUG */
31171 +
31172 + return 0;
31173 +}
31174 +
31175 +/*
31176 + * We call the detach routine to detach the ipsec mast from another device.
31177 + */
31178 +
31179 +DEBUG_NO_STATIC int
31180 +ipsec_mast_detach(struct net_device *dev)
31181 +{
31182 + int i;
31183 + struct ipsecpriv *prv = dev->priv;
31184 +
31185 + if(dev == NULL) {
31186 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31187 + "klips_debug:ipsec_mast_detach: "
31188 + "no device...");
31189 + return -ENODEV;
31190 + }
31191 +
31192 + if(prv == NULL) {
31193 + KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
31194 + "klips_debug:ipsec_mast_detach: "
31195 + "no private space associated with dev=%s",
31196 + dev->name ? dev->name : "NULL");
31197 + return -ENODATA;
31198 + }
31199 +
31200 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31201 + "klips_debug:ipsec_mast_detach: "
31202 + "physical device %s being detached from virtual device %s\n",
31203 + prv->dev ? prv->dev->name : "NULL",
31204 + dev->name);
31205 +
31206 + prv->dev = NULL;
31207 + prv->hard_start_xmit = NULL;
31208 + prv->get_stats = NULL;
31209 +
31210 + prv->hard_header = NULL;
31211 +#ifdef DETACH_AND_DOWN
31212 + dev->hard_header = NULL;
31213 +#endif /* DETACH_AND_DOWN */
31214 +
31215 + prv->rebuild_header = NULL;
31216 +#ifdef DETACH_AND_DOWN
31217 + dev->rebuild_header = NULL;
31218 +#endif /* DETACH_AND_DOWN */
31219 +
31220 + prv->set_mac_address = NULL;
31221 +#ifdef DETACH_AND_DOWN
31222 + dev->set_mac_address = NULL;
31223 +#endif /* DETACH_AND_DOWN */
31224 +
31225 + prv->header_cache_update = NULL;
31226 +#ifdef DETACH_AND_DOWN
31227 + dev->header_cache_update = NULL;
31228 +#endif /* DETACH_AND_DOWN */
31229 +
31230 +#ifdef DETACH_AND_DOWN
31231 + dev->neigh_setup = NULL;
31232 +#endif /* DETACH_AND_DOWN */
31233 +
31234 + dev->hard_header_len = 0;
31235 +#ifdef DETACH_AND_DOWN
31236 + dev->mtu = 0;
31237 +#endif /* DETACH_AND_DOWN */
31238 + prv->mtu = 0;
31239 + for (i=0; i<MAX_ADDR_LEN; i++) {
31240 + dev->dev_addr[i] = 0;
31241 + }
31242 + dev->addr_len = 0;
31243 +#ifdef PHYSDEV_TYPE
31244 + dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */
31245 +#endif /* PHYSDEV_TYPE */
31246 +
31247 + return 0;
31248 +}
31249 +
31250 +/*
31251 + * We call the clear routine to detach all ipsec masts from other devices.
31252 + */
31253 +DEBUG_NO_STATIC int
31254 +ipsec_mast_clear(void)
31255 +{
31256 + int i;
31257 + struct net_device *ipsecdev = NULL, *prvdev;
31258 + struct ipsecpriv *prv;
31259 + char name[9];
31260 + int ret;
31261 +
31262 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31263 + "klips_debug:ipsec_mast_clear: .\n");
31264 +
31265 + for(i = 0; i < IPSEC_NUM_IF; i++) {
31266 + sprintf(name, IPSEC_DEV_FORMAT, i);
31267 + if((ipsecdev = ipsec_dev_get(name)) != NULL) {
31268 + if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
31269 + prvdev = (struct net_device *)(prv->dev);
31270 + if(prvdev) {
31271 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31272 + "klips_debug:ipsec_mast_clear: "
31273 + "physical device for device %s is %s\n",
31274 + name, prvdev->name);
31275 + if((ret = ipsec_mast_detach(ipsecdev))) {
31276 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31277 + "klips_debug:ipsec_mast_clear: "
31278 + "error %d detatching device %s from device %s.\n",
31279 + ret, name, prvdev->name);
31280 + return ret;
31281 + }
31282 + }
31283 + }
31284 + }
31285 + }
31286 + return 0;
31287 +}
31288 +
31289 +DEBUG_NO_STATIC int
31290 +ipsec_mast_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
31291 +{
31292 + struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
31293 + struct ipsecpriv *prv = dev->priv;
31294 + struct net_device *them; /* physical device */
31295 +#ifdef CONFIG_IP_ALIAS
31296 + char *colon;
31297 + char realphysname[IFNAMSIZ];
31298 +#endif /* CONFIG_IP_ALIAS */
31299 +
31300 + if(dev == NULL) {
31301 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31302 + "klips_debug:ipsec_mast_ioctl: "
31303 + "device not supplied.\n");
31304 + return -ENODEV;
31305 + }
31306 +
31307 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31308 + "klips_debug:ipsec_mast_ioctl: "
31309 + "tncfg service call #%d for dev=%s\n",
31310 + cmd,
31311 + dev->name ? dev->name : "NULL");
31312 + switch (cmd) {
31313 + /* attach a virtual ipsec? device to a physical device */
31314 + case IPSEC_SET_DEV:
31315 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31316 + "klips_debug:ipsec_mast_ioctl: "
31317 + "calling ipsec_mast_attatch...\n");
31318 +#ifdef CONFIG_IP_ALIAS
31319 + /* If this is an IP alias interface, get its real physical name */
31320 + strncpy(realphysname, cf->cf_name, IFNAMSIZ);
31321 + realphysname[IFNAMSIZ-1] = 0;
31322 + colon = strchr(realphysname, ':');
31323 + if (colon) *colon = 0;
31324 + them = ipsec_dev_get(realphysname);
31325 +#else /* CONFIG_IP_ALIAS */
31326 + them = ipsec_dev_get(cf->cf_name);
31327 +#endif /* CONFIG_IP_ALIAS */
31328 +
31329 + if (them == NULL) {
31330 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31331 + "klips_debug:ipsec_mast_ioctl: "
31332 + "physical device %s requested is null\n",
31333 + cf->cf_name);
31334 + return -ENXIO;
31335 + }
31336 +
31337 +#if 0
31338 + if (them->flags & IFF_UP) {
31339 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31340 + "klips_debug:ipsec_mast_ioctl: "
31341 + "physical device %s requested is not up.\n",
31342 + cf->cf_name);
31343 + return -ENXIO;
31344 + }
31345 +#endif
31346 +
31347 + if (prv && prv->dev) {
31348 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31349 + "klips_debug:ipsec_mast_ioctl: "
31350 + "virtual device is already connected to %s.\n",
31351 + prv->dev->name ? prv->dev->name : "NULL");
31352 + return -EBUSY;
31353 + }
31354 + return ipsec_mast_attach(dev, them);
31355 +
31356 + case IPSEC_DEL_DEV:
31357 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31358 + "klips_debug:ipsec_mast_ioctl: "
31359 + "calling ipsec_mast_detatch.\n");
31360 + if (! prv->dev) {
31361 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31362 + "klips_debug:ipsec_mast_ioctl: "
31363 + "physical device not connected.\n");
31364 + return -ENODEV;
31365 + }
31366 + return ipsec_mast_detach(dev);
31367 +
31368 + case IPSEC_CLR_DEV:
31369 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31370 + "klips_debug:ipsec_mast_ioctl: "
31371 + "calling ipsec_mast_clear.\n");
31372 + return ipsec_mast_clear();
31373 +
31374 + default:
31375 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31376 + "klips_debug:ipsec_mast_ioctl: "
31377 + "unknown command %d.\n",
31378 + cmd);
31379 + return -EOPNOTSUPP;
31380 + }
31381 +}
31382 +
31383 +int
31384 +ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
31385 +{
31386 + struct net_device *dev = ptr;
31387 + struct net_device *ipsec_dev;
31388 + struct ipsecpriv *priv;
31389 + char name[9];
31390 + int i;
31391 +
31392 + if (dev == NULL) {
31393 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31394 + "klips_debug:ipsec_mast_device_event: "
31395 + "dev=NULL for event type %ld.\n",
31396 + event);
31397 + return(NOTIFY_DONE);
31398 + }
31399 +
31400 + /* check for loopback devices */
31401 + if (dev && (dev->flags & IFF_LOOPBACK)) {
31402 + return(NOTIFY_DONE);
31403 + }
31404 +
31405 + switch (event) {
31406 + case NETDEV_DOWN:
31407 + /* look very carefully at the scope of these compiler
31408 + directives before changing anything... -- RGB */
31409 +
31410 + case NETDEV_UNREGISTER:
31411 + switch (event) {
31412 + case NETDEV_DOWN:
31413 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31414 + "klips_debug:ipsec_mast_device_event: "
31415 + "NETDEV_DOWN dev=%s flags=%x\n",
31416 + dev->name,
31417 + dev->flags);
31418 + if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
31419 + printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
31420 + dev->name);
31421 + }
31422 + break;
31423 + case NETDEV_UNREGISTER:
31424 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31425 + "klips_debug:ipsec_mast_device_event: "
31426 + "NETDEV_UNREGISTER dev=%s flags=%x\n",
31427 + dev->name,
31428 + dev->flags);
31429 + break;
31430 + }
31431 +
31432 + /* find the attached physical device and detach it. */
31433 + for(i = 0; i < IPSEC_NUM_IF; i++) {
31434 + sprintf(name, IPSEC_DEV_FORMAT, i);
31435 + ipsec_dev = ipsec_dev_get(name);
31436 + if(ipsec_dev) {
31437 + priv = (struct ipsecpriv *)(ipsec_dev->priv);
31438 + if(priv) {
31439 + ;
31440 + if(((struct net_device *)(priv->dev)) == dev) {
31441 + /* dev_close(ipsec_dev); */
31442 + /* return */ ipsec_mast_detach(ipsec_dev);
31443 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31444 + "klips_debug:ipsec_mast_device_event: "
31445 + "device '%s' has been detached.\n",
31446 + ipsec_dev->name);
31447 + break;
31448 + }
31449 + } else {
31450 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31451 + "klips_debug:ipsec_mast_device_event: "
31452 + "device '%s' has no private data space!\n",
31453 + ipsec_dev->name);
31454 + }
31455 + }
31456 + }
31457 + break;
31458 + case NETDEV_UP:
31459 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31460 + "klips_debug:ipsec_mast_device_event: "
31461 + "NETDEV_UP dev=%s\n",
31462 + dev->name);
31463 + break;
31464 + case NETDEV_REBOOT:
31465 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31466 + "klips_debug:ipsec_mast_device_event: "
31467 + "NETDEV_REBOOT dev=%s\n",
31468 + dev->name);
31469 + break;
31470 + case NETDEV_CHANGE:
31471 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31472 + "klips_debug:ipsec_mast_device_event: "
31473 + "NETDEV_CHANGE dev=%s flags=%x\n",
31474 + dev->name,
31475 + dev->flags);
31476 + break;
31477 + case NETDEV_REGISTER:
31478 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31479 + "klips_debug:ipsec_mast_device_event: "
31480 + "NETDEV_REGISTER dev=%s\n",
31481 + dev->name);
31482 + break;
31483 + case NETDEV_CHANGEMTU:
31484 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31485 + "klips_debug:ipsec_mast_device_event: "
31486 + "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
31487 + dev->name,
31488 + dev->mtu);
31489 + break;
31490 + case NETDEV_CHANGEADDR:
31491 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31492 + "klips_debug:ipsec_mast_device_event: "
31493 + "NETDEV_CHANGEADDR dev=%s\n",
31494 + dev->name);
31495 + break;
31496 + case NETDEV_GOING_DOWN:
31497 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31498 + "klips_debug:ipsec_mast_device_event: "
31499 + "NETDEV_GOING_DOWN dev=%s\n",
31500 + dev->name);
31501 + break;
31502 + case NETDEV_CHANGENAME:
31503 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31504 + "klips_debug:ipsec_mast_device_event: "
31505 + "NETDEV_CHANGENAME dev=%s\n",
31506 + dev->name);
31507 + break;
31508 + default:
31509 + KLIPS_PRINT(debug_mast & DB_MAST_INIT,
31510 + "klips_debug:ipsec_mast_device_event: "
31511 + "event type %ld unrecognised for dev=%s\n",
31512 + event,
31513 + dev->name);
31514 + break;
31515 + }
31516 + return NOTIFY_DONE;
31517 +}
31518 +
31519 +/*
31520 + * Called when an ipsec mast device is initialized.
31521 + * The ipsec mast device structure is passed to us.
31522 + */
31523 +
31524 +int
31525 +ipsec_mast_init(struct net_device *dev)
31526 +{
31527 + int i;
31528 +
31529 + KLIPS_PRINT(debug_mast,
31530 + "klips_debug:ipsec_mast_init: "
31531 + "allocating %lu bytes initialising device: %s\n",
31532 + (unsigned long) sizeof(struct ipsecpriv),
31533 + dev->name ? dev->name : "NULL");
31534 +
31535 + /* Add our mast functions to the device */
31536 + dev->open = ipsec_mast_open;
31537 + dev->stop = ipsec_mast_close;
31538 + dev->hard_start_xmit = ipsec_mast_start_xmit;
31539 + dev->get_stats = ipsec_mast_get_stats;
31540 +
31541 + dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
31542 + if (dev->priv == NULL)
31543 + return -ENOMEM;
31544 + memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
31545 +
31546 + for(i = 0; i < sizeof(zeroes); i++) {
31547 + ((__u8*)(zeroes))[i] = 0;
31548 + }
31549 +
31550 + dev->set_multicast_list = NULL;
31551 + dev->do_ioctl = ipsec_mast_ioctl;
31552 + dev->hard_header = NULL;
31553 + dev->rebuild_header = NULL;
31554 + dev->set_mac_address = NULL;
31555 + dev->header_cache_update= NULL;
31556 + dev->neigh_setup = ipsec_mast_neigh_setup_dev;
31557 + dev->hard_header_len = 0;
31558 + dev->mtu = 0;
31559 + dev->addr_len = 0;
31560 + dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */
31561 + dev->tx_queue_len = 10; /* Small queue */
31562 + memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
31563 +
31564 + /* New-style flags. */
31565 + dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
31566 + dev_init_buffers(dev);
31567 +
31568 + /* We're done. Have I forgotten anything? */
31569 + return 0;
31570 +}
31571 +
31572 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31573 +/* Module specific interface (but it links with the rest of IPSEC) */
31574 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
31575 +
31576 +int
31577 +ipsec_mast_probe(struct net_device *dev)
31578 +{
31579 + ipsec_mast_init(dev);
31580 + return 0;
31581 +}
31582 +
31583 +int
31584 +ipsec_mast_init_devices(void)
31585 +{
31586 + return 0;
31587 +}
31588 +
31589 +/* void */
31590 +int
31591 +ipsec_mast_cleanup_devices(void)
31592 +{
31593 + int error = 0;
31594 + int i;
31595 + char name[10];
31596 + struct net_device *dev_mast;
31597 +
31598 + for(i = 0; i < ipsec_mastdevice_count; i++) {
31599 + sprintf(name, MAST_DEV_FORMAT, i);
31600 + if((dev_mast = ipsec_dev_get(name)) == NULL) {
31601 + break;
31602 + }
31603 + unregister_netdev(dev_mast);
31604 + kfree(dev_mast->priv);
31605 + dev_mast->priv=NULL;
31606 + }
31607 + return error;
31608 +}
31609 +
31610 +/*
31611 + * $Log: ipsec_mast.c,v $
31612 + * Revision 1.7.2.1 2006/10/06 21:39:26 paul
31613 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
31614 + * set. This is defined through autoconf.h which is included through the
31615 + * linux kernel build macros.
31616 + *
31617 + * Revision 1.7 2005/04/29 05:10:22 mcr
31618 + * removed from extraenous includes to make unit testing easier.
31619 + *
31620 + * Revision 1.6 2004/12/03 21:25:57 mcr
31621 + * compile time fixes for running on 2.6.
31622 + * still experimental.
31623 + *
31624 + * Revision 1.5 2004/08/03 18:19:08 mcr
31625 + * in 2.6, use "net_device" instead of #define device->net_device.
31626 + * this probably breaks 2.0 compiles.
31627 + *
31628 + * Revision 1.4 2004/07/10 19:11:18 mcr
31629 + * CONFIG_IPSEC -> CONFIG_KLIPS.
31630 + *
31631 + * Revision 1.3 2003/10/31 02:27:55 mcr
31632 + * pulled up port-selector patches and sa_id elimination.
31633 + *
31634 + * Revision 1.2.4.1 2003/10/29 01:30:41 mcr
31635 + * elimited "struct sa_id".
31636 + *
31637 + * Revision 1.2 2003/06/22 20:06:17 mcr
31638 + * refactored mast code still had lots of ipsecX junk in it.
31639 + *
31640 + * Revision 1.1 2003/02/12 19:31:12 rgb
31641 + * Refactored from ipsec_tunnel.c
31642 + *
31643 + */
31644 --- /dev/null Tue Mar 11 13:02:56 2003
31645 +++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004
31646 @@ -0,0 +1,453 @@
31647 +/*
31648 + * RCSID $Id: ipsec_md5c.c,v 1.10 2005/04/15 01:25:57 mcr Exp $
31649 + */
31650 +
31651 +/*
31652 + * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
31653 + * changes to accomodate it in the kernel by ji.
31654 + */
31655 +
31656 +#include <asm/byteorder.h>
31657 +#include <linux/string.h>
31658 +
31659 +#include "openswan/ipsec_md5h.h"
31660 +
31661 +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
31662 + */
31663 +
31664 +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
31665 +rights reserved.
31666 +
31667 +License to copy and use this software is granted provided that it
31668 +is identified as the "RSA Data Security, Inc. MD5 Message-Digest
31669 +Algorithm" in all material mentioning or referencing this software
31670 +or this function.
31671 +
31672 +License is also granted to make and use derivative works provided
31673 +that such works are identified as "derived from the RSA Data
31674 +Security, Inc. MD5 Message-Digest Algorithm" in all material
31675 +mentioning or referencing the derived work.
31676 +
31677 +RSA Data Security, Inc. makes no representations concerning either
31678 +the merchantability of this software or the suitability of this
31679 +software for any particular purpose. It is provided "as is"
31680 +without express or implied warranty of any kind.
31681 +
31682 +These notices must be retained in any copies of any part of this
31683 +documentation and/or software.
31684 + */
31685 +
31686 +/*
31687 + * Additions by JI
31688 + *
31689 + * HAVEMEMCOPY is defined if mem* routines are available
31690 + *
31691 + * HAVEHTON is defined if htons() and htonl() can be used
31692 + * for big/little endian conversions
31693 + *
31694 + */
31695 +
31696 +#define HAVEMEMCOPY
31697 +#ifdef __LITTLE_ENDIAN
31698 +#define LITTLENDIAN
31699 +#endif
31700 +#ifdef __BIG_ENDIAN
31701 +#define BIGENDIAN
31702 +#endif
31703 +
31704 +/* Constants for MD5Transform routine.
31705 + */
31706 +
31707 +#define S11 7
31708 +#define S12 12
31709 +#define S13 17
31710 +#define S14 22
31711 +#define S21 5
31712 +#define S22 9
31713 +#define S23 14
31714 +#define S24 20
31715 +#define S31 4
31716 +#define S32 11
31717 +#define S33 16
31718 +#define S34 23
31719 +#define S41 6
31720 +#define S42 10
31721 +#define S43 15
31722 +#define S44 21
31723 +
31724 +static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
31725 +
31726 +#ifdef LITTLEENDIAN
31727 +#define Encode MD5_memcpy
31728 +#define Decode MD5_memcpy
31729 +#else
31730 +static void Encode PROTO_LIST
31731 + ((unsigned char *, UINT4 *, unsigned int));
31732 +static void Decode PROTO_LIST
31733 + ((UINT4 *, unsigned char *, unsigned int));
31734 +#endif
31735 +
31736 +#ifdef HAVEMEMCOPY
31737 +/* no need to include <memory.h> here; <linux/string.h> defines these */
31738 +#define MD5_memcpy memcpy
31739 +#define MD5_memset memset
31740 +#else
31741 +#ifdef HAVEBCOPY
31742 +#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
31743 +#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
31744 +#else
31745 +static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
31746 +static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
31747 +#endif
31748 +#endif
31749 +static unsigned char PADDING[64] = {
31750 + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31751 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31752 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
31753 +};
31754 +
31755 +/* F, G, H and I are basic MD5 functions.
31756 + */
31757 +#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
31758 +#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
31759 +#define H(x, y, z) ((x) ^ (y) ^ (z))
31760 +#define I(x, y, z) ((y) ^ ((x) | (~z)))
31761 +
31762 +/* ROTATE_LEFT rotates x left n bits.
31763 + */
31764 +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
31765 +
31766 +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
31767 +Rotation is separate from addition to prevent recomputation.
31768 + */
31769 +#define FF(a, b, c, d, x, s, ac) { \
31770 + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
31771 + (a) = ROTATE_LEFT ((a), (s)); \
31772 + (a) += (b); \
31773 + }
31774 +#define GG(a, b, c, d, x, s, ac) { \
31775 + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
31776 + (a) = ROTATE_LEFT ((a), (s)); \
31777 + (a) += (b); \
31778 + }
31779 +#define HH(a, b, c, d, x, s, ac) { \
31780 + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
31781 + (a) = ROTATE_LEFT ((a), (s)); \
31782 + (a) += (b); \
31783 + }
31784 +#define II(a, b, c, d, x, s, ac) { \
31785 + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
31786 + (a) = ROTATE_LEFT ((a), (s)); \
31787 + (a) += (b); \
31788 + }
31789 +
31790 +/*
31791 + * MD5 initialization. Begins an MD5 operation, writing a new context.
31792 + */
31793 +void osMD5Init(void *vcontext)
31794 +{
31795 + MD5_CTX *context = vcontext;
31796 +
31797 + context->count[0] = context->count[1] = 0;
31798 + /* Load magic initialization constants.*/
31799 + context->state[0] = 0x67452301;
31800 + context->state[1] = 0xefcdab89;
31801 + context->state[2] = 0x98badcfe;
31802 + context->state[3] = 0x10325476;
31803 +}
31804 +
31805 +/* MD5 block update operation. Continues an MD5 message-digest
31806 + operation, processing another message block, and updating the
31807 + context.
31808 + */
31809 +void osMD5Update (vcontext, input, inputLen)
31810 + void *vcontext;
31811 + unsigned char *input; /* input block */
31812 + __u32 inputLen; /* length of input block */
31813 +{
31814 + MD5_CTX *context = vcontext;
31815 + __u32 i;
31816 + unsigned int index, partLen;
31817 +
31818 + /* Compute number of bytes mod 64 */
31819 + index = (unsigned int)((context->count[0] >> 3) & 0x3F);
31820 +
31821 + /* Update number of bits */
31822 + if ((context->count[0] += ((UINT4)inputLen << 3))
31823 + < ((UINT4)inputLen << 3))
31824 + context->count[1]++;
31825 + context->count[1] += ((UINT4)inputLen >> 29);
31826 +
31827 + partLen = 64 - index;
31828 +
31829 + /* Transform as many times as possible.
31830 +*/
31831 + if (inputLen >= partLen) {
31832 + MD5_memcpy
31833 + ((POINTER)&context->buffer[index], (POINTER)input, partLen);
31834 + MD5Transform (context->state, context->buffer);
31835 +
31836 + for (i = partLen; i + 63 < inputLen; i += 64)
31837 + MD5Transform (context->state, &input[i]);
31838 +
31839 + index = 0;
31840 + }
31841 + else
31842 + i = 0;
31843 +
31844 + /* Buffer remaining input */
31845 + MD5_memcpy
31846 + ((POINTER)&context->buffer[index], (POINTER)&input[i],
31847 + inputLen-i);
31848 +}
31849 +
31850 +/* MD5 finalization. Ends an MD5 message-digest operation, writing the
31851 + the message digest and zeroizing the context.
31852 + */
31853 +void osMD5Final (digest, vcontext)
31854 +unsigned char digest[16]; /* message digest */
31855 +void *vcontext; /* context */
31856 +{
31857 + MD5_CTX *context = vcontext;
31858 + unsigned char bits[8];
31859 + unsigned int index, padLen;
31860 +
31861 + /* Save number of bits */
31862 + Encode (bits, context->count, 8);
31863 +
31864 + /* Pad out to 56 mod 64.
31865 +*/
31866 + index = (unsigned int)((context->count[0] >> 3) & 0x3f);
31867 + padLen = (index < 56) ? (56 - index) : (120 - index);
31868 + osMD5Update (context, PADDING, padLen);
31869 +
31870 + /* Append length (before padding) */
31871 + osMD5Update (context, bits, 8);
31872 +
31873 + if (digest != NULL) /* Bill Simpson's padding */
31874 + {
31875 + /* store state in digest */
31876 + Encode (digest, context->state, 16);
31877 +
31878 + /* Zeroize sensitive information.
31879 + */
31880 + MD5_memset ((POINTER)context, 0, sizeof (*context));
31881 + }
31882 +}
31883 +
31884 +/* MD5 basic transformation. Transforms state based on block.
31885 + */
31886 +static void MD5Transform (state, block)
31887 +UINT4 state[4];
31888 +unsigned char block[64];
31889 +{
31890 + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
31891 +
31892 + Decode (x, block, 64);
31893 +
31894 + /* Round 1 */
31895 + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
31896 + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
31897 + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
31898 + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
31899 + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
31900 + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
31901 + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
31902 + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
31903 + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
31904 + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
31905 + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
31906 + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
31907 + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
31908 + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
31909 + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
31910 + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
31911 +
31912 + /* Round 2 */
31913 + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
31914 + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
31915 + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
31916 + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
31917 + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
31918 + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
31919 + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
31920 + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
31921 + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
31922 + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
31923 + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
31924 + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
31925 + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
31926 + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
31927 + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
31928 + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
31929 +
31930 + /* Round 3 */
31931 + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
31932 + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
31933 + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
31934 + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
31935 + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
31936 + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
31937 + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
31938 + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
31939 + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
31940 + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
31941 + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
31942 + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
31943 + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
31944 + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
31945 + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
31946 + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
31947 +
31948 + /* Round 4 */
31949 + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
31950 + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
31951 + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
31952 + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
31953 + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
31954 + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
31955 + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
31956 + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
31957 + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
31958 + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
31959 + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
31960 + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
31961 + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
31962 + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
31963 + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
31964 + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
31965 +
31966 + state[0] += a;
31967 + state[1] += b;
31968 + state[2] += c;
31969 + state[3] += d;
31970 +
31971 + /* Zeroize sensitive information.
31972 +*/
31973 + MD5_memset ((POINTER)x, 0, sizeof (x));
31974 +}
31975 +
31976 +#ifndef LITTLEENDIAN
31977 +
31978 +/* Encodes input (UINT4) into output (unsigned char). Assumes len is
31979 + a multiple of 4.
31980 + */
31981 +static void Encode (output, input, len)
31982 +unsigned char *output;
31983 +UINT4 *input;
31984 +unsigned int len;
31985 +{
31986 + unsigned int i, j;
31987 +
31988 + for (i = 0, j = 0; j < len; i++, j += 4) {
31989 + output[j] = (unsigned char)(input[i] & 0xff);
31990 + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
31991 + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
31992 + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
31993 + }
31994 +}
31995 +
31996 +/* Decodes input (unsigned char) into output (UINT4). Assumes len is
31997 + a multiple of 4.
31998 + */
31999 +static void Decode (output, input, len)
32000 +UINT4 *output;
32001 +unsigned char *input;
32002 +unsigned int len;
32003 +{
32004 + unsigned int i, j;
32005 +
32006 + for (i = 0, j = 0; j < len; i++, j += 4)
32007 + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
32008 + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
32009 +}
32010 +
32011 +#endif
32012 +
32013 +#ifndef HAVEMEMCOPY
32014 +#ifndef HAVEBCOPY
32015 +/* Note: Replace "for loop" with standard memcpy if possible.
32016 + */
32017 +
32018 +static void MD5_memcpy (output, input, len)
32019 +POINTER output;
32020 +POINTER input;
32021 +unsigned int len;
32022 +{
32023 + unsigned int i;
32024 +
32025 + for (i = 0; i < len; i++)
32026 +
32027 + output[i] = input[i];
32028 +}
32029 +
32030 +/* Note: Replace "for loop" with standard memset if possible.
32031 + */
32032 +
32033 +static void MD5_memset (output, value, len)
32034 +POINTER output;
32035 +int value;
32036 +unsigned int len;
32037 +{
32038 + unsigned int i;
32039 +
32040 + for (i = 0; i < len; i++)
32041 + ((char *)output)[i] = (char)value;
32042 +}
32043 +#endif
32044 +#endif
32045 +
32046 +/*
32047 + * $Log: ipsec_md5c.c,v $
32048 + * Revision 1.10 2005/04/15 01:25:57 mcr
32049 + * minor fix to comments.
32050 + *
32051 + * Revision 1.9 2004/09/08 17:21:36 ken
32052 + * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
32053 + *
32054 + * Revision 1.8 2004/04/06 02:49:26 mcr
32055 + * pullup of algo code from alg-branch.
32056 + *
32057 + * Revision 1.7 2002/09/10 01:45:14 mcr
32058 + * changed type of MD5_CTX and SHA1_CTX to void * so that
32059 + * the function prototypes would match, and could be placed
32060 + * into a pointer to a function.
32061 + *
32062 + * Revision 1.6 2002/04/24 07:55:32 mcr
32063 + * #include patches and Makefiles for post-reorg compilation.
32064 + *
32065 + * Revision 1.5 2002/04/24 07:36:28 mcr
32066 + * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
32067 + *
32068 + * Revision 1.4 1999/12/13 13:59:12 rgb
32069 + * Quick fix to argument size to Update bugs.
32070 + *
32071 + * Revision 1.3 1999/05/21 18:09:28 henry
32072 + * unnecessary <memory.h> include causes trouble in 2.2
32073 + *
32074 + * Revision 1.2 1999/04/06 04:54:26 rgb
32075 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
32076 + * patch shell fixes.
32077 + *
32078 + * Revision 1.1 1998/06/18 21:27:48 henry
32079 + * move sources from klips/src to klips/net/ipsec, to keep stupid
32080 + * kernel-build scripts happier in the presence of symlinks
32081 + *
32082 + * Revision 1.2 1998/04/23 20:54:02 rgb
32083 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
32084 + * verified.
32085 + *
32086 + * Revision 1.1 1998/04/09 03:06:08 henry
32087 + * sources moved up from linux/net/ipsec
32088 + *
32089 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
32090 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
32091 + *
32092 + * Revision 0.3 1996/11/20 14:48:53 ji
32093 + * Release update only.
32094 + *
32095 + * Revision 0.2 1996/11/02 00:18:33 ji
32096 + * First limited release.
32097 + *
32098 + *
32099 + */
32100 --- /dev/null Tue Mar 11 13:02:56 2003
32101 +++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004
32102 @@ -0,0 +1,1186 @@
32103 +/*
32104 + * @(#) /proc file system interface code.
32105 + *
32106 + * Copyright (C) 1996, 1997 John Ioannidis.
32107 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
32108 + * 2001 Michael Richardson <mcr@freeswan.org>
32109 + *
32110 + * This program is free software; you can redistribute it and/or modify it
32111 + * under the terms of the GNU General Public License as published by the
32112 + * Free Software Foundation; either version 2 of the License, or (at your
32113 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
32114 + *
32115 + * This program is distributed in the hope that it will be useful, but
32116 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
32117 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32118 + * for more details.
32119 + *
32120 + * Split out from ipsec_init.c version 1.70.
32121 + */
32122 +
32123 +char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.39.2.4 2006/11/15 22:21:39 paul Exp $";
32124 +
32125 +
32126 +#ifndef AUTOCONF_INCLUDED
32127 +#include <linux/config.h>
32128 +#endif
32129 +#include <linux/version.h>
32130 +#define __NO_VERSION__
32131 +#include <linux/module.h>
32132 +#include <linux/kernel.h> /* printk() */
32133 +
32134 +#include "openswan/ipsec_kversion.h"
32135 +#include "openswan/ipsec_param.h"
32136 +
32137 +#ifdef MALLOC_SLAB
32138 +# include <linux/slab.h> /* kmalloc() */
32139 +#else /* MALLOC_SLAB */
32140 +# include <linux/malloc.h> /* kmalloc() */
32141 +#endif /* MALLOC_SLAB */
32142 +#include <linux/errno.h> /* error codes */
32143 +#include <linux/types.h> /* size_t */
32144 +#include <linux/interrupt.h> /* mark_bh */
32145 +
32146 +#include <linux/netdevice.h> /* struct device, and other headers */
32147 +#include <linux/etherdevice.h> /* eth_type_trans */
32148 +#include <linux/ip.h> /* struct iphdr */
32149 +#include <linux/in.h> /* struct sockaddr_in */
32150 +#include <linux/skbuff.h>
32151 +#include <asm/uaccess.h> /* copy_from_user */
32152 +#include <openswan.h>
32153 +#ifdef SPINLOCK
32154 +#ifdef SPINLOCK_23
32155 +#include <linux/spinlock.h> /* *lock* */
32156 +#else /* SPINLOCK_23 */
32157 +#include <asm/spinlock.h> /* *lock* */
32158 +#endif /* SPINLOCK_23 */
32159 +#endif /* SPINLOCK */
32160 +
32161 +#include <net/ip.h>
32162 +#ifdef CONFIG_PROC_FS
32163 +#include <linux/proc_fs.h>
32164 +#endif /* CONFIG_PROC_FS */
32165 +#ifdef NETLINK_SOCK
32166 +#include <linux/netlink.h>
32167 +#else
32168 +#include <net/netlink.h>
32169 +#endif
32170 +
32171 +#include "openswan/radij.h"
32172 +
32173 +#include "openswan/ipsec_life.h"
32174 +#include "openswan/ipsec_stats.h"
32175 +#include "openswan/ipsec_sa.h"
32176 +
32177 +#include "openswan/ipsec_encap.h"
32178 +#include "openswan/ipsec_radij.h"
32179 +#include "openswan/ipsec_xform.h"
32180 +#include "openswan/ipsec_tunnel.h"
32181 +#include "openswan/ipsec_xmit.h"
32182 +
32183 +#include "openswan/ipsec_rcv.h"
32184 +#include "openswan/ipsec_ah.h"
32185 +#include "openswan/ipsec_esp.h"
32186 +#include "openswan/ipsec_kern24.h"
32187 +
32188 +#ifdef CONFIG_KLIPS_IPCOMP
32189 +#include "openswan/ipcomp.h"
32190 +#endif /* CONFIG_KLIPS_IPCOMP */
32191 +
32192 +#include "openswan/ipsec_proto.h"
32193 +
32194 +#include <pfkeyv2.h>
32195 +#include <pfkey.h>
32196 +
32197 +#ifdef CONFIG_PROC_FS
32198 +
32199 +#ifdef IPSEC_PROC_SUBDIRS
32200 +static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
32201 +static struct proc_dir_entry *proc_eroute_dir = NULL;
32202 +static struct proc_dir_entry *proc_spi_dir = NULL;
32203 +static struct proc_dir_entry *proc_spigrp_dir = NULL;
32204 +static struct proc_dir_entry *proc_birth_dir = NULL;
32205 +static struct proc_dir_entry *proc_stats_dir = NULL;
32206 +#endif
32207 +
32208 +struct ipsec_birth_reply ipsec_ipv4_birth_packet;
32209 +struct ipsec_birth_reply ipsec_ipv6_birth_packet;
32210 +
32211 +#ifdef CONFIG_KLIPS_DEBUG
32212 +int debug_esp = 0;
32213 +int debug_ah = 0;
32214 +#endif /* CONFIG_KLIPS_DEBUG */
32215 +
32216 +#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)
32217 +
32218 +extern int ipsec_xform_get_info(char *buffer, char **start,
32219 + off_t offset, int length IPSEC_PROC_LAST_ARG);
32220 +
32221 +
32222 +IPSEC_PROCFS_DEBUG_NO_STATIC
32223 +int
32224 +ipsec_eroute_get_info(char *buffer,
32225 + char **start,
32226 + off_t offset,
32227 + int length IPSEC_PROC_LAST_ARG)
32228 +{
32229 + struct wsbuf w = {buffer, length, offset, 0, 0};
32230 +
32231 +#ifdef CONFIG_KLIPS_DEBUG
32232 + if (debug_radij & DB_RJ_DUMPTREES)
32233 + rj_dumptrees(); /* XXXXXXXXX */
32234 +#endif /* CONFIG_KLIPS_DEBUG */
32235 +
32236 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32237 + "klips_debug:ipsec_eroute_get_info: "
32238 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32239 + buffer,
32240 + *start,
32241 + (int)offset,
32242 + length);
32243 +
32244 + spin_lock_bh(&eroute_lock);
32245 +
32246 + rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
32247 +/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
32248 +
32249 + spin_unlock_bh(&eroute_lock);
32250 +
32251 + *start = buffer + (offset - w.begin); /* Start of wanted data */
32252 + return w.len - (offset - w.begin);
32253 +}
32254 +
32255 +IPSEC_PROCFS_DEBUG_NO_STATIC
32256 +int
32257 +ipsec_spi_get_info(char *buffer,
32258 + char **start,
32259 + off_t offset,
32260 + int length IPSEC_PROC_LAST_ARG)
32261 +{
32262 + const int max_content = length > 0? length-1 : 0;
32263 + int len = 0;
32264 + off_t begin = 0;
32265 + int i;
32266 + struct ipsec_sa *sa_p;
32267 + char sa[SATOT_BUF];
32268 + char buf_s[SUBNETTOA_BUF];
32269 + char buf_d[SUBNETTOA_BUF];
32270 + size_t sa_len;
32271 +
32272 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32273 + "klips_debug:ipsec_spi_get_info: "
32274 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32275 + buffer,
32276 + *start,
32277 + (int)offset,
32278 + length);
32279 +
32280 + spin_lock_bh(&tdb_lock);
32281 +
32282 + for (i = 0; i < SADB_HASHMOD; i++) {
32283 + for (sa_p = ipsec_sadb_hash[i];
32284 + sa_p;
32285 + sa_p = sa_p->ips_hnext) {
32286 + atomic_inc(&sa_p->ips_refcount);
32287 + sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
32288 + len += ipsec_snprintf(buffer+len, length-len, "%s ",
32289 + sa_len ? sa : " (error)");
32290 +
32291 + len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
32292 + IPS_XFORM_NAME(sa_p));
32293 +
32294 + len += ipsec_snprintf(buffer+len, length-len, ": dir=%s",
32295 + (sa_p->ips_flags & EMT_INBOUND) ?
32296 + "in " : "out");
32297 +
32298 + if(sa_p->ips_addr_s) {
32299 + addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
32300 + 0, buf_s, sizeof(buf_s));
32301 + len += ipsec_snprintf(buffer+len, length-len, " src=%s",
32302 + buf_s);
32303 + }
32304 +
32305 + if((sa_p->ips_said.proto == IPPROTO_IPIP)
32306 + && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
32307 + subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
32308 + sa_p->ips_mask_s.u.v4.sin_addr,
32309 + 0,
32310 + buf_s,
32311 + sizeof(buf_s));
32312 +
32313 + subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
32314 + sa_p->ips_mask_d.u.v4.sin_addr,
32315 + 0,
32316 + buf_d,
32317 + sizeof(buf_d));
32318 +
32319 + len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
32320 + buf_s, buf_d);
32321 + }
32322 +
32323 + if(sa_p->ips_iv_bits) {
32324 + int j;
32325 + len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
32326 + sa_p->ips_iv_bits);
32327 +
32328 + for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
32329 + len += ipsec_snprintf(buffer+len, length-len, "%02x",
32330 + (__u32)((__u8*)(sa_p->ips_iv))[j]);
32331 + }
32332 + }
32333 +
32334 + if(sa_p->ips_encalg || sa_p->ips_authalg) {
32335 + if(sa_p->ips_replaywin) {
32336 + len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
32337 + sa_p->ips_replaywin);
32338 + }
32339 + if(sa_p->ips_errs.ips_replaywin_errs) {
32340 + len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
32341 + sa_p->ips_errs.ips_replaywin_errs);
32342 + }
32343 + if(sa_p->ips_replaywin_lastseq) {
32344 + len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
32345 + sa_p->ips_replaywin_lastseq);
32346 + }
32347 + if(sa_p->ips_replaywin_bitmap) {
32348 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32349 + len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
32350 + sa_p->ips_replaywin_bitmap);
32351 +#else
32352 + len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x",
32353 + (__u32)(sa_p->ips_replaywin_bitmap >> 32),
32354 + (__u32)sa_p->ips_replaywin_bitmap);
32355 +#endif
32356 + }
32357 + if(sa_p->ips_replaywin_maxdiff) {
32358 + len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
32359 + sa_p->ips_replaywin_maxdiff);
32360 + }
32361 + }
32362 + if(sa_p->ips_flags & ~EMT_INBOUND) {
32363 + len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
32364 + sa_p->ips_flags & ~EMT_INBOUND);
32365 + len += ipsec_snprintf(buffer+len, length-len, "<");
32366 + /* flag printing goes here */
32367 + len += ipsec_snprintf(buffer+len, length-len, ">");
32368 + }
32369 + if(sa_p->ips_auth_bits) {
32370 + len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
32371 + sa_p->ips_auth_bits);
32372 + }
32373 + if(sa_p->ips_key_bits_a) {
32374 + len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
32375 + sa_p->ips_key_bits_a);
32376 + }
32377 + if(sa_p->ips_errs.ips_auth_errs) {
32378 + len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
32379 + sa_p->ips_errs.ips_auth_errs);
32380 + }
32381 + if(sa_p->ips_key_bits_e) {
32382 + len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
32383 + sa_p->ips_key_bits_e);
32384 + }
32385 + if(sa_p->ips_errs.ips_encsize_errs) {
32386 + len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
32387 + sa_p->ips_errs.ips_encsize_errs);
32388 + }
32389 + if(sa_p->ips_errs.ips_encpad_errs) {
32390 + len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
32391 + sa_p->ips_errs.ips_encpad_errs);
32392 + }
32393 +
32394 + len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)=");
32395 +
32396 + len += ipsec_lifetime_format(buffer + len,
32397 + length - len,
32398 + "alloc",
32399 + ipsec_life_countbased,
32400 + &sa_p->ips_life.ipl_allocations);
32401 +
32402 + len += ipsec_lifetime_format(buffer + len,
32403 + length - len,
32404 + "bytes",
32405 + ipsec_life_countbased,
32406 + &sa_p->ips_life.ipl_bytes);
32407 +
32408 + len += ipsec_lifetime_format(buffer + len,
32409 + length - len,
32410 + "addtime",
32411 + ipsec_life_timebased,
32412 + &sa_p->ips_life.ipl_addtime);
32413 +
32414 + len += ipsec_lifetime_format(buffer + len,
32415 + length - len,
32416 + "usetime",
32417 + ipsec_life_timebased,
32418 + &sa_p->ips_life.ipl_usetime);
32419 +
32420 + len += ipsec_lifetime_format(buffer + len,
32421 + length - len,
32422 + "packets",
32423 + ipsec_life_countbased,
32424 + &sa_p->ips_life.ipl_packets);
32425 +
32426 + if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
32427 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32428 + len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
32429 + jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
32430 +#else
32431 + len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
32432 + jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
32433 +#endif
32434 + }
32435 +
32436 +#ifdef CONFIG_KLIPS_IPCOMP
32437 + if(sa_p->ips_said.proto == IPPROTO_COMP &&
32438 + (sa_p->ips_comp_ratio_dbytes ||
32439 + sa_p->ips_comp_ratio_cbytes)) {
32440 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
32441 + len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
32442 + sa_p->ips_comp_ratio_dbytes,
32443 + sa_p->ips_comp_ratio_cbytes);
32444 +#else
32445 + len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
32446 + (unsigned long)sa_p->ips_comp_ratio_dbytes,
32447 + (unsigned long)sa_p->ips_comp_ratio_cbytes);
32448 +#endif
32449 + }
32450 +#endif /* CONFIG_KLIPS_IPCOMP */
32451 +
32452 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32453 + {
32454 + char *natttype_name;
32455 +
32456 + switch(sa_p->ips_natt_type)
32457 + {
32458 + case 0:
32459 + natttype_name="none";
32460 + break;
32461 + case ESPINUDP_WITH_NON_IKE:
32462 + natttype_name="nonike";
32463 + break;
32464 + case ESPINUDP_WITH_NON_ESP:
32465 + natttype_name="nonesp";
32466 + break;
32467 + default:
32468 + natttype_name = "unknown";
32469 + break;
32470 + }
32471 +
32472 + len += ipsec_snprintf(buffer + len, length-len, " natencap=%s",
32473 + natttype_name);
32474 +
32475 + len += ipsec_snprintf(buffer + len, length-len, " natsport=%d",
32476 + sa_p->ips_natt_sport);
32477 +
32478 + len += ipsec_snprintf(buffer + len,length-len, " natdport=%d",
32479 + sa_p->ips_natt_dport);
32480 + }
32481 +#else
32482 + len += ipsec_snprintf(buffer + len, length-len, " natencap=na");
32483 +#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
32484 +
32485 + len += ipsec_snprintf(buffer + len,length-len, " refcount=%d",
32486 + atomic_read(&sa_p->ips_refcount));
32487 +
32488 + len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
32489 + sa_p->ips_ref);
32490 +#ifdef CONFIG_KLIPS_DEBUG
32491 + if(debug_xform) {
32492 + len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
32493 + (unsigned long)IPsecSAref2table(sa_p->ips_ref),
32494 + (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
32495 + }
32496 +#endif /* CONFIG_KLIPS_DEBUG */
32497 +
32498 + len += ipsec_snprintf(buffer+len, length-len, "\n");
32499 +
32500 + atomic_dec(&sa_p->ips_refcount);
32501 +
32502 + if (len >= max_content) {
32503 + /* we've done all that can fit -- stop loops */
32504 + len = max_content; /* truncate crap */
32505 + goto done_spi_i;
32506 + } else {
32507 + const off_t pos = begin + len; /* file position of end of what we've generated */
32508 +
32509 + if (pos <= offset) {
32510 + /* all is before first interesting character:
32511 + * discard, but note where we are.
32512 + */
32513 + len = 0;
32514 + begin = pos;
32515 + }
32516 + }
32517 + }
32518 + }
32519 +
32520 +done_spi_i:
32521 + spin_unlock_bh(&tdb_lock);
32522 +
32523 + *start = buffer + (offset - begin); /* Start of wanted data */
32524 + return len - (offset - begin);
32525 +}
32526 +
32527 +IPSEC_PROCFS_DEBUG_NO_STATIC
32528 +int
32529 +ipsec_spigrp_get_info(char *buffer,
32530 + char **start,
32531 + off_t offset,
32532 + int length IPSEC_PROC_LAST_ARG)
32533 +{
32534 + /* Limit of useful snprintf output */
32535 + const int max_content = length > 0? length-1 : 0;
32536 +
32537 + int len = 0;
32538 + off_t begin = 0;
32539 + int i;
32540 + struct ipsec_sa *sa_p, *sa_p2;
32541 + char sa[SATOT_BUF];
32542 + size_t sa_len;
32543 +
32544 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32545 + "klips_debug:ipsec_spigrp_get_info: "
32546 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32547 + buffer,
32548 + *start,
32549 + (int)offset,
32550 + length);
32551 +
32552 + spin_lock_bh(&tdb_lock);
32553 +
32554 + for (i = 0; i < SADB_HASHMOD; i++) {
32555 + for (sa_p = ipsec_sadb_hash[i];
32556 + sa_p != NULL;
32557 + sa_p = sa_p->ips_hnext)
32558 + {
32559 + atomic_inc(&sa_p->ips_refcount);
32560 + if(sa_p->ips_inext == NULL) {
32561 + sa_p2 = sa_p;
32562 + while(sa_p2 != NULL) {
32563 + atomic_inc(&sa_p2->ips_refcount);
32564 + sa_len = satot(&sa_p2->ips_said,
32565 + 'x', sa, sizeof(sa));
32566 +
32567 + len += ipsec_snprintf(buffer+len, length-len, "%s ",
32568 + sa_len ? sa : " (error)");
32569 + atomic_dec(&sa_p2->ips_refcount);
32570 + sa_p2 = sa_p2->ips_onext;
32571 + }
32572 + len += ipsec_snprintf(buffer+len, length-len, "\n");
32573 + }
32574 +
32575 + atomic_dec(&sa_p->ips_refcount);
32576 +
32577 + if (len >= max_content) {
32578 + /* we've done all that can fit -- stop loops */
32579 + len = max_content; /* truncate crap */
32580 + goto done_spigrp_i;
32581 + } else {
32582 + const off_t pos = begin + len;
32583 +
32584 + if (pos <= offset) {
32585 + /* all is before first interesting character:
32586 + * discard, but note where we are.
32587 + */
32588 + len = 0;
32589 + begin = pos;
32590 + }
32591 + }
32592 + }
32593 + }
32594 +
32595 +done_spigrp_i:
32596 + spin_unlock_bh(&tdb_lock);
32597 +
32598 + *start = buffer + (offset - begin); /* Start of wanted data */
32599 + return len - (offset - begin);
32600 +}
32601 +
32602 +
32603 +IPSEC_PROCFS_DEBUG_NO_STATIC
32604 +int
32605 +ipsec_tncfg_get_info(char *buffer,
32606 + char **start,
32607 + off_t offset,
32608 + int length IPSEC_PROC_LAST_ARG)
32609 +{
32610 + /* limit of useful snprintf output */
32611 + const int max_content = length > 0? length-1 : 0;
32612 + int len = 0;
32613 + off_t begin = 0;
32614 + int i;
32615 + char name[9];
32616 + struct net_device *dev, *privdev;
32617 + struct ipsecpriv *priv;
32618 +
32619 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32620 + "klips_debug:ipsec_tncfg_get_info: "
32621 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32622 + buffer,
32623 + *start,
32624 + (int)offset,
32625 + length);
32626 +
32627 + for(i = 0; i < IPSEC_NUM_IF; i++) {
32628 + ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i);
32629 + dev = __ipsec_dev_get(name);
32630 + if(dev) {
32631 + priv = (struct ipsecpriv *)(dev->priv);
32632 + len += ipsec_snprintf(buffer+len, length-len, "%s",
32633 + dev->name);
32634 + if(priv) {
32635 + privdev = (struct net_device *)(priv->dev);
32636 + len += ipsec_snprintf(buffer+len, length-len, " -> %s",
32637 + privdev ? privdev->name : "NULL");
32638 + len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d",
32639 + dev->mtu,
32640 + priv->mtu,
32641 + privdev ? privdev->mtu : 0);
32642 + } else {
32643 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32644 + "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
32645 + dev->name);
32646 + }
32647 + len += ipsec_snprintf(buffer+len, length-len, "\n");
32648 +
32649 + if (len >= max_content) {
32650 + /* we've done all that can fit -- stop loop */
32651 + len = max_content; /* truncate crap */
32652 + break;
32653 + } else {
32654 + const off_t pos = begin + len;
32655 + if (pos <= offset) {
32656 + len = 0;
32657 + begin = pos;
32658 + }
32659 + }
32660 + }
32661 + }
32662 + *start = buffer + (offset - begin); /* Start of wanted data */
32663 + len -= (offset - begin); /* Start slop */
32664 + if (len > length)
32665 + len = length;
32666 + return len;
32667 +}
32668 +
32669 +IPSEC_PROCFS_DEBUG_NO_STATIC
32670 +int
32671 +ipsec_version_get_info(char *buffer,
32672 + char **start,
32673 + off_t offset,
32674 + int length IPSEC_PROC_LAST_ARG)
32675 +{
32676 + int len = 0;
32677 + off_t begin = 0;
32678 +
32679 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32680 + "klips_debug:ipsec_version_get_info: "
32681 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32682 + buffer,
32683 + *start,
32684 + (int)offset,
32685 + length);
32686 +
32687 + len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n",
32688 + ipsec_version_code());
32689 +#if 0
32690 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32691 + "klips_debug:ipsec_version_get_info: "
32692 + "ipsec_init version: %s\n",
32693 + ipsec_init_c_version);
32694 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32695 + "klips_debug:ipsec_version_get_info: "
32696 + "ipsec_tunnel version: %s\n",
32697 + ipsec_tunnel_c_version);
32698 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32699 + "klips_debug:ipsec_version_get_info: "
32700 + "ipsec_netlink version: %s\n",
32701 + ipsec_netlink_c_version);
32702 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32703 + "klips_debug:ipsec_version_get_info: "
32704 + "radij_c_version: %s\n",
32705 + radij_c_version);
32706 +#endif
32707 +
32708 +
32709 + *start = buffer + (offset - begin); /* Start of wanted data */
32710 + len -= (offset - begin); /* Start slop */
32711 + if (len > length)
32712 + len = length;
32713 + return len;
32714 +}
32715 +
32716 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32717 +unsigned int natt_available = 1;
32718 +#else
32719 +unsigned int natt_available = 0;
32720 +#endif
32721 +module_param(natt_available, int, 0444);
32722 +
32723 +IPSEC_PROCFS_DEBUG_NO_STATIC
32724 +int
32725 +ipsec_natt_get_info(char *buffer,
32726 + char **start,
32727 + off_t offset,
32728 + int length IPSEC_PROC_LAST_ARG)
32729 +{
32730 + int len = 0;
32731 + off_t begin = 0;
32732 +
32733 + len += ipsec_snprintf(buffer + len,
32734 + length-len, "%d\n",
32735 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
32736 + 1
32737 +#else
32738 + 0
32739 +#endif
32740 + );
32741 +
32742 + *start = buffer + (offset - begin); /* Start of wanted data */
32743 + len -= (offset - begin); /* Start slop */
32744 + if (len > length)
32745 + len = length;
32746 + return len;
32747 +}
32748 +
32749 +IPSEC_PROCFS_DEBUG_NO_STATIC
32750 +int
32751 +ipsec_birth_info(char *page,
32752 + char **start,
32753 + off_t offset,
32754 + int count,
32755 + int *eof,
32756 + void *data)
32757 +{
32758 + struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32759 + int len;
32760 +
32761 + if(offset >= ibr->packet_template_len) {
32762 + if(eof) {
32763 + *eof=1;
32764 + }
32765 + return 0;
32766 + }
32767 +
32768 + len = ibr->packet_template_len;
32769 + len -= offset;
32770 + if (len > count)
32771 + len = count;
32772 +
32773 + memcpy(page + offset, ibr->packet_template+offset, len);
32774 +
32775 + return len;
32776 +}
32777 +
32778 +IPSEC_PROCFS_DEBUG_NO_STATIC
32779 +int
32780 +ipsec_birth_set(struct file *file, const char *buffer,
32781 + unsigned long count, void *data)
32782 +{
32783 + struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
32784 + int len;
32785 +
32786 + KLIPS_INC_USE;
32787 + if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
32788 + len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
32789 + } else {
32790 + len = count;
32791 + }
32792 +
32793 + if(copy_from_user(ibr->packet_template, buffer, len)) {
32794 + KLIPS_DEC_USE;
32795 + return -EFAULT;
32796 + }
32797 + ibr->packet_template_len = len;
32798 +
32799 + KLIPS_DEC_USE;
32800 +
32801 + return len;
32802 +}
32803 +
32804 +
32805 +#ifdef CONFIG_KLIPS_DEBUG
32806 +IPSEC_PROCFS_DEBUG_NO_STATIC
32807 +int
32808 +ipsec_klipsdebug_get_info(char *buffer,
32809 + char **start,
32810 + off_t offset,
32811 + int length IPSEC_PROC_LAST_ARG)
32812 +{
32813 + int len = 0;
32814 + off_t begin = 0;
32815 +
32816 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
32817 + "klips_debug:ipsec_klipsdebug_get_info: "
32818 + "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
32819 + buffer,
32820 + *start,
32821 + (int)offset,
32822 + length);
32823 +
32824 + len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
32825 + len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
32826 + len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
32827 + len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
32828 + len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
32829 + len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
32830 + len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah);
32831 + len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
32832 + len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
32833 +
32834 + *start = buffer + (offset - begin); /* Start of wanted data */
32835 + len -= (offset - begin); /* Start slop */
32836 + if (len > length)
32837 + len = length;
32838 + return len;
32839 +}
32840 +#endif /* CONFIG_KLIPS_DEBUG */
32841 +
32842 +IPSEC_PROCFS_DEBUG_NO_STATIC
32843 +int
32844 +ipsec_stats_get_int_info(char *buffer,
32845 + char **start,
32846 + off_t offset,
32847 + int length,
32848 + int *eof,
32849 + void *data)
32850 +{
32851 +
32852 + const int max_content = length > 0? length-1 : 0;
32853 + int len = 0;
32854 + int *thing;
32855 +
32856 + thing = (int *)data;
32857 +
32858 + len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing);
32859 +
32860 + if (len >= max_content)
32861 + len = max_content; /* truncate crap */
32862 +
32863 + *start = buffer + offset; /* Start of wanted data */
32864 + return len > offset? len - offset : 0;
32865 +
32866 +}
32867 +
32868 +#ifndef PROC_FS_2325
32869 +struct proc_dir_entry ipsec_eroute =
32870 +{
32871 + 0,
32872 + 12, "ipsec_eroute",
32873 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32874 + &proc_net_inode_operations,
32875 + ipsec_eroute_get_info,
32876 + NULL, NULL, NULL, NULL, NULL
32877 +};
32878 +
32879 +struct proc_dir_entry ipsec_spi =
32880 +{
32881 + 0,
32882 + 9, "ipsec_spi",
32883 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32884 + &proc_net_inode_operations,
32885 + ipsec_spi_get_info,
32886 + NULL, NULL, NULL, NULL, NULL
32887 +};
32888 +
32889 +struct proc_dir_entry ipsec_spigrp =
32890 +{
32891 + 0,
32892 + 12, "ipsec_spigrp",
32893 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32894 + &proc_net_inode_operations,
32895 + ipsec_spigrp_get_info,
32896 + NULL, NULL, NULL, NULL, NULL
32897 +};
32898 +
32899 +struct proc_dir_entry ipsec_tncfg =
32900 +{
32901 + 0,
32902 + 11, "ipsec_tncfg",
32903 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32904 + &proc_net_inode_operations,
32905 + ipsec_tncfg_get_info,
32906 + NULL, NULL, NULL, NULL, NULL
32907 +};
32908 +
32909 +struct proc_dir_entry ipsec_version =
32910 +{
32911 + 0,
32912 + 13, "ipsec_version",
32913 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32914 + &proc_net_inode_operations,
32915 + ipsec_version_get_info,
32916 + NULL, NULL, NULL, NULL, NULL
32917 +};
32918 +
32919 +#ifdef CONFIG_KLIPS_DEBUG
32920 +struct proc_dir_entry ipsec_klipsdebug =
32921 +{
32922 + 0,
32923 + 16, "ipsec_klipsdebug",
32924 + S_IFREG | S_IRUGO, 1, 0, 0, 0,
32925 + &proc_net_inode_operations,
32926 + ipsec_klipsdebug_get_info,
32927 + NULL, NULL, NULL, NULL, NULL
32928 +};
32929 +#endif /* CONFIG_KLIPS_DEBUG */
32930 +#endif /* !PROC_FS_2325 */
32931 +#endif /* CONFIG_PROC_FS */
32932 +
32933 +#if defined(PROC_FS_2325)
32934 +struct ipsec_proc_list {
32935 + char *name;
32936 + struct proc_dir_entry **parent;
32937 + struct proc_dir_entry **dir;
32938 + read_proc_t *readthing;
32939 + write_proc_t *writething;
32940 + void *data;
32941 +};
32942 +static struct ipsec_proc_list proc_items[]={
32943 +#ifdef CONFIG_KLIPS_DEBUG
32944 + {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL},
32945 +#endif
32946 + {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
32947 + {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL},
32948 + {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL},
32949 + {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL},
32950 + {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
32951 + {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL},
32952 + {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL},
32953 + {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
32954 + {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
32955 + {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL},
32956 + {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL},
32957 + {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL},
32958 + {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
32959 + {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
32960 + {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL},
32961 + {NULL, NULL, NULL, NULL, NULL, NULL}
32962 +};
32963 +#endif
32964 +
32965 +int
32966 +ipsec_proc_init()
32967 +{
32968 + int error = 0;
32969 +#ifdef IPSEC_PROC_SUBDIRS
32970 + struct proc_dir_entry *item;
32971 +#endif
32972 +
32973 + /*
32974 + * just complain because pluto won't run without /proc!
32975 + */
32976 +#ifndef CONFIG_PROC_FS
32977 +#error You must have PROC_FS built in to use KLIPS
32978 +#endif
32979 +
32980 + /* for 2.0 kernels */
32981 +#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
32982 + error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
32983 + error |= proc_register_dynamic(&proc_net, &ipsec_spi);
32984 + error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
32985 + error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
32986 + error |= proc_register_dynamic(&proc_net, &ipsec_version);
32987 +#ifdef CONFIG_KLIPS_DEBUG
32988 + error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
32989 +#endif /* CONFIG_KLIPS_DEBUG */
32990 +#endif
32991 +
32992 + /* for 2.2 kernels */
32993 +#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
32994 + error |= proc_register(proc_net, &ipsec_eroute);
32995 + error |= proc_register(proc_net, &ipsec_spi);
32996 + error |= proc_register(proc_net, &ipsec_spigrp);
32997 + error |= proc_register(proc_net, &ipsec_tncfg);
32998 + error |= proc_register(proc_net, &ipsec_version);
32999 +#ifdef CONFIG_KLIPS_DEBUG
33000 + error |= proc_register(proc_net, &ipsec_klipsdebug);
33001 +#endif /* CONFIG_KLIPS_DEBUG */
33002 +#endif
33003 +
33004 + /* for 2.4 kernels */
33005 +#if defined(PROC_FS_2325)
33006 + /* create /proc/net/ipsec */
33007 +
33008 + /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
33009 + memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
33010 + memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
33011 +
33012 + proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
33013 + if(proc_net_ipsec_dir == NULL) {
33014 + /* no point in continuing */
33015 + return 1;
33016 + }
33017 +
33018 + {
33019 + struct ipsec_proc_list *it;
33020 +
33021 + it=proc_items;
33022 + while(it->name!=NULL) {
33023 + if(it->dir) {
33024 + /* make a dir instead */
33025 + item = proc_mkdir(it->name, *it->parent);
33026 + *it->dir = item;
33027 + } else {
33028 + item = create_proc_entry(it->name, 0400, *it->parent);
33029 + }
33030 + if(item) {
33031 + item->read_proc = it->readthing;
33032 + item->write_proc = it->writething;
33033 + item->data = it->data;
33034 +#ifdef MODULE
33035 + item->owner = THIS_MODULE;
33036 +#endif
33037 + } else {
33038 + error |= 1;
33039 + }
33040 + it++;
33041 + }
33042 + }
33043 +
33044 + /* now create some symlinks to provide compatibility */
33045 + proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
33046 + proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all");
33047 + proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
33048 + proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg");
33049 + proc_symlink("ipsec_version",proc_net, "ipsec/version");
33050 + proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
33051 +
33052 +#endif /* !PROC_FS_2325 */
33053 +
33054 + return error;
33055 +}
33056 +
33057 +void
33058 +ipsec_proc_cleanup()
33059 +{
33060 +
33061 + /* for 2.0 and 2.2 kernels */
33062 +#if !defined(PROC_FS_2325)
33063 +
33064 +#ifdef CONFIG_KLIPS_DEBUG
33065 + if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
33066 + printk("klips_debug:ipsec_cleanup: "
33067 + "cannot unregister /proc/net/ipsec_klipsdebug\n");
33068 +#endif /* CONFIG_KLIPS_DEBUG */
33069 +
33070 + if (proc_net_unregister(ipsec_version.low_ino) != 0)
33071 + printk("klips_debug:ipsec_cleanup: "
33072 + "cannot unregister /proc/net/ipsec_version\n");
33073 + if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
33074 + printk("klips_debug:ipsec_cleanup: "
33075 + "cannot unregister /proc/net/ipsec_eroute\n");
33076 + if (proc_net_unregister(ipsec_spi.low_ino) != 0)
33077 + printk("klips_debug:ipsec_cleanup: "
33078 + "cannot unregister /proc/net/ipsec_spi\n");
33079 + if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
33080 + printk("klips_debug:ipsec_cleanup: "
33081 + "cannot unregister /proc/net/ipsec_spigrp\n");
33082 + if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
33083 + printk("klips_debug:ipsec_cleanup: "
33084 + "cannot unregister /proc/net/ipsec_tncfg\n");
33085 +#endif
33086 +
33087 + /* for 2.4 kernels */
33088 +#if defined(PROC_FS_2325)
33089 + {
33090 + struct ipsec_proc_list *it;
33091 +
33092 + /* find end of list */
33093 + it=proc_items;
33094 + while(it->name!=NULL) {
33095 + it++;
33096 + }
33097 + it--;
33098 +
33099 + do {
33100 + remove_proc_entry(it->name, *it->parent);
33101 + it--;
33102 + } while(it >= proc_items);
33103 + }
33104 +
33105 +
33106 +#ifdef CONFIG_KLIPS_DEBUG
33107 + remove_proc_entry("ipsec_klipsdebug", proc_net);
33108 +#endif /* CONFIG_KLIPS_DEBUG */
33109 + remove_proc_entry("ipsec_eroute", proc_net);
33110 + remove_proc_entry("ipsec_spi", proc_net);
33111 + remove_proc_entry("ipsec_spigrp", proc_net);
33112 + remove_proc_entry("ipsec_tncfg", proc_net);
33113 + remove_proc_entry("ipsec_version", proc_net);
33114 + remove_proc_entry("ipsec", proc_net);
33115 +#endif /* 2.4 kernel */
33116 +}
33117 +
33118 +/*
33119 + * $Log: ipsec_proc.c,v $
33120 + * Revision 1.39.2.4 2006/11/15 22:21:39 paul
33121 + * backport of creating a /sys/ file to test for nat-t capability in kernel.
33122 + *
33123 + * Revision 1.39.2.3 2006/10/06 21:39:26 paul
33124 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
33125 + * set. This is defined through autoconf.h which is included through the
33126 + * linux kernel build macros.
33127 + *
33128 + * Revision 1.39.2.2 2006/02/13 18:48:12 paul
33129 + * Fix by Ankit Desai <ankit@elitecore.com> for module unloading.
33130 + *
33131 + * Revision 1.39.2.1 2005/09/07 00:45:59 paul
33132 + * pull up of mcr's nat-t klips detection patch from head
33133 + *
33134 + * Revision 1.39 2005/05/20 03:19:18 mcr
33135 + * modifications for use on 2.4.30 kernel, with backported
33136 + * printk_ratelimit(). all warnings removed.
33137 + *
33138 + * Revision 1.38 2005/04/29 05:10:22 mcr
33139 + * removed from extraenous includes to make unit testing easier.
33140 + *
33141 + * Revision 1.37 2005/04/13 22:49:49 mcr
33142 + * moved KLIPS specific snprintf() wrapper to seperate file.
33143 + *
33144 + * Revision 1.36 2005/04/06 17:44:36 mcr
33145 + * when NAT-T is compiled out, show encap as "NA"
33146 + *
33147 + * Revision 1.35 2005/01/26 00:50:35 mcr
33148 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
33149 + * and make sure that NAT_TRAVERSAL is set as well to match
33150 + * userspace compiles of code.
33151 + *
33152 + * Revision 1.34 2004/12/03 21:25:57 mcr
33153 + * compile time fixes for running on 2.6.
33154 + * still experimental.
33155 + *
33156 + * Revision 1.33 2004/08/17 03:27:23 mcr
33157 + * klips 2.6 edits.
33158 + *
33159 + * Revision 1.32 2004/08/03 18:19:08 mcr
33160 + * in 2.6, use "net_device" instead of #define device->net_device.
33161 + * this probably breaks 2.0 compiles.
33162 + *
33163 + * Revision 1.31 2004/07/10 19:11:18 mcr
33164 + * CONFIG_IPSEC -> CONFIG_KLIPS.
33165 + *
33166 + * Revision 1.30 2004/04/25 21:23:11 ken
33167 + * Pull in dhr's changes from FreeS/WAN 2.06
33168 + *
33169 + * Revision 1.29 2004/04/06 02:49:26 mcr
33170 + * pullup of algo code from alg-branch.
33171 + *
33172 + * Revision 1.28 2004/03/28 20:29:58 paul
33173 + * <hugh_> ssize_t, not ssized_t
33174 + *
33175 + * Revision 1.27 2004/03/28 20:27:20 paul
33176 + * Included tested and confirmed fixes mcr made and dhr verified for
33177 + * snprint statements. Changed one other snprintf to use ipsec_snprintf
33178 + * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
33179 + * dhr. (thanks dhr!)
33180 + *
33181 + * Revision 1.26 2004/02/09 22:07:06 mcr
33182 + * added information about nat-traversal setting to spi-output.
33183 + *
33184 + * Revision 1.25.4.1 2004/04/05 04:30:46 mcr
33185 + * patches for alg-branch to compile/work with 2.x openswan
33186 + *
33187 + * Revision 1.25 2003/10/31 02:27:55 mcr
33188 + * pulled up port-selector patches and sa_id elimination.
33189 + *
33190 + * Revision 1.24.4.1 2003/10/29 01:30:41 mcr
33191 + * elimited "struct sa_id".
33192 + *
33193 + * Revision 1.24 2003/06/20 01:42:21 mcr
33194 + * added counters to measure how many ACQUIREs we send to pluto,
33195 + * and how many are successfully sent.
33196 + *
33197 + * Revision 1.23 2003/04/03 17:38:09 rgb
33198 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
33199 + *
33200 + * Revision 1.22 2002/09/20 15:40:57 rgb
33201 + * Renamed saref macros for consistency and brevity.
33202 + *
33203 + * Revision 1.21 2002/09/20 05:01:35 rgb
33204 + * Print ref and reftable, refentry seperately.
33205 + *
33206 + * Revision 1.20 2002/09/19 02:35:39 mcr
33207 + * do not define structures needed by /proc/net/ipsec/ if we
33208 + * aren't going create that directory.
33209 + *
33210 + * Revision 1.19 2002/09/10 01:43:25 mcr
33211 + * fixed problem in /-* comment.
33212 + *
33213 + * Revision 1.18 2002/09/03 16:22:11 mcr
33214 + * fixed initialization of birth/stuff values - some simple
33215 + * screw ups in the code.
33216 + * removed debugging that was left in by mistake.
33217 + *
33218 + * Revision 1.17 2002/09/02 17:54:53 mcr
33219 + * changed how the table driven /proc entries are created so that
33220 + * making subdirs is now explicit rather than implicit.
33221 + *
33222 + * Revision 1.16 2002/08/30 01:23:37 mcr
33223 + * reorganized /proc creating code to clear up ifdefs,
33224 + * make the 2.4 code table driven, and put things into
33225 + * /proc/net/ipsec subdir. Symlinks are left for compatibility.
33226 + *
33227 + * Revision 1.15 2002/08/13 19:01:25 mcr
33228 + * patches from kenb to permit compilation of FreeSWAN on ia64.
33229 + * des library patched to use proper DES_LONG type for ia64.
33230 + *
33231 + * Revision 1.14 2002/07/26 08:48:31 rgb
33232 + * Added SA ref table code.
33233 + *
33234 + * Revision 1.13 2002/07/24 18:44:54 rgb
33235 + * Type fiddling to tame ia64 compiler.
33236 + *
33237 + * Revision 1.12 2002/05/27 18:56:07 rgb
33238 + * Convert to dynamic ipsec device allocation.
33239 + *
33240 + * Revision 1.11 2002/05/23 07:14:50 rgb
33241 + * Added refcount code.
33242 + * Cleaned up %p variants to 0p%p for test suite cleanup.
33243 + * Convert "usecount" to "refcount" to remove ambiguity.
33244 + *
33245 + * Revision 1.10 2002/04/24 07:55:32 mcr
33246 + * #include patches and Makefiles for post-reorg compilation.
33247 + *
33248 + * Revision 1.9 2002/04/24 07:36:28 mcr
33249 + * Moved from ./klips/net/ipsec/ipsec_proc.c,v
33250 + *
33251 + * Revision 1.8 2002/01/29 17:17:55 mcr
33252 + * moved include of ipsec_param.h to after include of linux/kernel.h
33253 + * otherwise, it seems that some option that is set in ipsec_param.h
33254 + * screws up something subtle in the include path to kernel.h, and
33255 + * it complains on the snprintf() prototype.
33256 + *
33257 + * Revision 1.7 2002/01/29 04:00:52 mcr
33258 + * more excise of kversions.h header.
33259 + *
33260 + * Revision 1.6 2002/01/29 02:13:17 mcr
33261 + * introduction of ipsec_kversion.h means that include of
33262 + * ipsec_param.h must preceed any decisions about what files to
33263 + * include to deal with differences in kernel source.
33264 + *
33265 + * Revision 1.5 2002/01/12 02:54:30 mcr
33266 + * beginnings of /proc/net/ipsec dir.
33267 + *
33268 + * Revision 1.4 2001/12/11 02:21:05 rgb
33269 + * Don't include module version here, fixing 2.2 compile bug.
33270 + *
33271 + * Revision 1.3 2001/12/05 07:19:44 rgb
33272 + * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
33273 + *
33274 + * Revision 1.2 2001/11/26 09:16:14 rgb
33275 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
33276 + *
33277 + * Revision 1.74 2001/11/22 05:44:11 henry
33278 + * new version stuff
33279 + *
33280 + * Revision 1.1.2.1 2001/09/25 02:19:40 mcr
33281 + * /proc manipulation code moved to new ipsec_proc.c
33282 + *
33283 + *
33284 + * Local variables:
33285 + * c-file-style: "linux"
33286 + * End:
33287 + *
33288 + */
33289 --- /dev/null Tue Mar 11 13:02:56 2003
33290 +++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004
33291 @@ -0,0 +1,889 @@
33292 +/*
33293 + * Interface between the IPSEC code and the radix (radij) tree code
33294 + * Copyright (C) 1996, 1997 John Ioannidis.
33295 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
33296 + *
33297 + * This program is free software; you can redistribute it and/or modify it
33298 + * under the terms of the GNU General Public License as published by the
33299 + * Free Software Foundation; either version 2 of the License, or (at your
33300 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
33301 + *
33302 + * This program is distributed in the hope that it will be useful, but
33303 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
33304 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
33305 + * for more details.
33306 + *
33307 + * RCSID $Id: ipsec_radij.c,v 1.73.2.1 2006/10/06 21:39:26 paul Exp $
33308 + */
33309 +
33310 +#ifndef AUTOCONF_INCLUDED
33311 +#include <linux/config.h>
33312 +#endif
33313 +#include <linux/version.h>
33314 +#include <linux/kernel.h> /* printk() */
33315 +
33316 +#include "openswan/ipsec_param.h"
33317 +
33318 +#ifdef MALLOC_SLAB
33319 +# include <linux/slab.h> /* kmalloc() */
33320 +#else /* MALLOC_SLAB */
33321 +# include <linux/malloc.h> /* kmalloc() */
33322 +#endif /* MALLOC_SLAB */
33323 +#include <linux/errno.h> /* error codes */
33324 +#include <linux/types.h> /* size_t */
33325 +#include <linux/interrupt.h> /* mark_bh */
33326 +
33327 +#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
33328 +#include <linux/etherdevice.h> /* eth_type_trans */
33329 +#include <linux/ip.h> /* struct iphdr */
33330 +#include <linux/skbuff.h>
33331 +#include <openswan.h>
33332 +#ifdef SPINLOCK
33333 +# ifdef SPINLOCK_23
33334 +# include <linux/spinlock.h> /* *lock* */
33335 +# else /* 23_SPINLOCK */
33336 +# include <asm/spinlock.h> /* *lock* */
33337 +# endif /* 23_SPINLOCK */
33338 +#endif /* SPINLOCK */
33339 +
33340 +#include <net/ip.h>
33341 +
33342 +#include "openswan/ipsec_eroute.h"
33343 +#include "openswan/ipsec_sa.h"
33344 +
33345 +#include "openswan/radij.h"
33346 +#include "openswan/ipsec_encap.h"
33347 +#include "openswan/radij.h"
33348 +#include "openswan/ipsec_encap.h"
33349 +#include "openswan/ipsec_radij.h"
33350 +#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */
33351 +#include "openswan/ipsec_xform.h"
33352 +
33353 +#include <pfkeyv2.h>
33354 +#include <pfkey.h>
33355 +
33356 +#include "openswan/ipsec_proto.h"
33357 +
33358 +#ifdef CONFIG_KLIPS_DEBUG
33359 +int debug_radij = 0;
33360 +#endif /* CONFIG_KLIPS_DEBUG */
33361 +
33362 +struct radij_node_head *rnh = NULL;
33363 +#ifdef SPINLOCK
33364 +spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
33365 +#else /* SPINLOCK */
33366 +spinlock_t eroute_lock;
33367 +#endif /* SPINLOCK */
33368 +
33369 +int
33370 +ipsec_radijinit(void)
33371 +{
33372 + maj_keylen = sizeof (struct sockaddr_encap);
33373 +
33374 + rj_init();
33375 +
33376 + if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
33377 + return -1;
33378 + return 0;
33379 +}
33380 +
33381 +int
33382 +ipsec_radijcleanup(void)
33383 +{
33384 + int error;
33385 +
33386 + spin_lock_bh(&eroute_lock);
33387 +
33388 + error = radijcleanup();
33389 +
33390 + spin_unlock_bh(&eroute_lock);
33391 +
33392 + return error;
33393 +}
33394 +
33395 +int
33396 +ipsec_cleareroutes(void)
33397 +{
33398 + int error;
33399 +
33400 + spin_lock_bh(&eroute_lock);
33401 +
33402 + error = radijcleartree();
33403 +
33404 + spin_unlock_bh(&eroute_lock);
33405 +
33406 + return error;
33407 +}
33408 +
33409 +int
33410 +ipsec_breakroute(struct sockaddr_encap *eaddr,
33411 + struct sockaddr_encap *emask,
33412 + struct sk_buff **first,
33413 + struct sk_buff **last)
33414 +{
33415 + struct eroute *ro;
33416 + struct radij_node *rn;
33417 + int error;
33418 +#ifdef CONFIG_KLIPS_DEBUG
33419 +
33420 + if (debug_eroute) {
33421 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33422 + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33423 + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33424 + KLIPS_PRINT(debug_eroute,
33425 + "klips_debug:ipsec_breakroute: "
33426 + "attempting to delete eroute for %s:%d->%s:%d %d\n",
33427 + buf1, ntohs(eaddr->sen_sport),
33428 + buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
33429 + }
33430 +#endif /* CONFIG_KLIPS_DEBUG */
33431 +
33432 + spin_lock_bh(&eroute_lock);
33433 +
33434 + if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
33435 + spin_unlock_bh(&eroute_lock);
33436 + KLIPS_PRINT(debug_eroute,
33437 + "klips_debug:ipsec_breakroute: "
33438 + "node not found, eroute delete failed.\n");
33439 + return error;
33440 + }
33441 +
33442 + spin_unlock_bh(&eroute_lock);
33443 +
33444 + ro = (struct eroute *)rn;
33445 +
33446 + KLIPS_PRINT(debug_eroute,
33447 + "klips_debug:ipsec_breakroute: "
33448 + "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
33449 + ro,
33450 + ro->er_ident_s.data,
33451 + ro->er_ident_d.data,
33452 + ro->er_first,
33453 + ro->er_last);
33454 +
33455 + if (ro->er_ident_s.data != NULL) {
33456 + kfree(ro->er_ident_s.data);
33457 + }
33458 + if (ro->er_ident_d.data != NULL) {
33459 + kfree(ro->er_ident_d.data);
33460 + }
33461 + if (ro->er_first != NULL) {
33462 +#if 0
33463 + struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
33464 + stats->tx_dropped--;
33465 +#endif
33466 + *first = ro->er_first;
33467 + }
33468 + if (ro->er_last != NULL) {
33469 +#if 0
33470 + struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
33471 + stats->tx_dropped--;
33472 +#endif
33473 + *last = ro->er_last;
33474 + }
33475 +
33476 + if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
33477 + panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
33478 + memset((caddr_t)rn, 0, sizeof (struct eroute));
33479 + kfree(rn);
33480 +
33481 + return 0;
33482 +}
33483 +
33484 +int
33485 +ipsec_makeroute(struct sockaddr_encap *eaddr,
33486 + struct sockaddr_encap *emask,
33487 + ip_said said,
33488 + uint32_t pid,
33489 + struct sk_buff *skb,
33490 + struct ident *ident_s,
33491 + struct ident *ident_d)
33492 +{
33493 + struct eroute *retrt;
33494 + int error;
33495 + char sa[SATOT_BUF];
33496 + size_t sa_len;
33497 +
33498 +#ifdef CONFIG_KLIPS_DEBUG
33499 +
33500 + if (debug_eroute) {
33501 +
33502 + {
33503 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33504 +
33505 + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33506 + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33507 + sa_len = satot(&said, 0, sa, sizeof(sa));
33508 + KLIPS_PRINT(debug_eroute,
33509 + "klips_debug:ipsec_makeroute: "
33510 + "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
33511 + (unsigned long) sizeof(struct eroute),
33512 + buf1,
33513 + buf2,
33514 + sa_len ? sa : " (error)",
33515 + pid,
33516 + skb,
33517 + (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
33518 + (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
33519 + }
33520 + {
33521 + char buf1[sizeof(struct sockaddr_encap)*2 + 1],
33522 + buf2[sizeof(struct sockaddr_encap)*2 + 1];
33523 + int i;
33524 + unsigned char *b1 = buf1,
33525 + *b2 = buf2,
33526 + *ea = (unsigned char *)eaddr,
33527 + *em = (unsigned char *)emask;
33528 +
33529 +
33530 + for (i=0; i<sizeof(struct sockaddr_encap); i++) {
33531 + sprintf(b1, "%02x", ea[i]);
33532 + sprintf(b2, "%02x", em[i]);
33533 + b1+=2;
33534 + b2+=2;
33535 + }
33536 + KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
33537 + }
33538 +
33539 + }
33540 +#endif /* CONFIG_KLIPS_DEBUG */
33541 +
33542 + retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
33543 + if (retrt == NULL) {
33544 + printk("klips_error:ipsec_makeroute: "
33545 + "not able to allocate kernel memory");
33546 + return -ENOMEM;
33547 + }
33548 + memset((caddr_t)retrt, 0, sizeof (struct eroute));
33549 +
33550 + retrt->er_eaddr = *eaddr;
33551 + retrt->er_emask = *emask;
33552 + retrt->er_said = said;
33553 + retrt->er_pid = pid;
33554 + retrt->er_count = 0;
33555 + retrt->er_lasttime = jiffies/HZ;
33556 +
33557 + {
33558 + /* this is because gcc 3. doesn't like cast's as lvalues */
33559 + struct rjtentry *rje = (struct rjtentry *)&(retrt->er_rjt);
33560 + caddr_t er = (caddr_t)&(retrt->er_eaddr);
33561 +
33562 + rje->rd_nodes->rj_key= er;
33563 + }
33564 +
33565 + if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
33566 + int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33567 +
33568 + retrt->er_ident_s.type = ident_s->type;
33569 + retrt->er_ident_s.id = ident_s->id;
33570 + retrt->er_ident_s.len = ident_s->len;
33571 + if(data_len) {
33572 + KLIPS_PRINT(debug_eroute,
33573 + "klips_debug:ipsec_makeroute: "
33574 + "attempting to allocate %u bytes for ident_s.\n",
33575 + data_len);
33576 + if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
33577 + kfree(retrt);
33578 + printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33579 + return ENOMEM;
33580 + }
33581 + memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
33582 + } else {
33583 + retrt->er_ident_s.data = NULL;
33584 + }
33585 + }
33586 +
33587 + if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
33588 + int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
33589 +
33590 + retrt->er_ident_d.type = ident_d->type;
33591 + retrt->er_ident_d.id = ident_d->id;
33592 + retrt->er_ident_d.len = ident_d->len;
33593 + if(data_len) {
33594 + KLIPS_PRINT(debug_eroute,
33595 + "klips_debug:ipsec_makeroute: "
33596 + "attempting to allocate %u bytes for ident_d.\n",
33597 + data_len);
33598 + if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
33599 + if (retrt->er_ident_s.data)
33600 + kfree(retrt->er_ident_s.data);
33601 + kfree(retrt);
33602 + printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
33603 + return ENOMEM;
33604 + }
33605 + memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
33606 + } else {
33607 + retrt->er_ident_d.data = NULL;
33608 + }
33609 + }
33610 + retrt->er_first = skb;
33611 + retrt->er_last = NULL;
33612 +
33613 + KLIPS_PRINT(debug_eroute,
33614 + "klips_debug:ipsec_makeroute: "
33615 + "calling rj_addroute now\n");
33616 +
33617 + spin_lock_bh(&eroute_lock);
33618 +
33619 + error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
33620 + rnh, retrt->er_rjt.rd_nodes);
33621 +
33622 + spin_unlock_bh(&eroute_lock);
33623 +
33624 + if(error) {
33625 + sa_len = satot(&said, 0, sa, sizeof(sa));
33626 + KLIPS_PRINT(debug_eroute,
33627 + "klips_debug:ipsec_makeroute: "
33628 + "rj_addroute not able to insert eroute for SA:%s (error:%d)\n",
33629 + sa_len ? sa : " (error)", error);
33630 + if (retrt->er_ident_s.data)
33631 + kfree(retrt->er_ident_s.data);
33632 + if (retrt->er_ident_d.data)
33633 + kfree(retrt->er_ident_d.data);
33634 +
33635 + kfree(retrt);
33636 +
33637 + return error;
33638 + }
33639 +
33640 +#ifdef CONFIG_KLIPS_DEBUG
33641 + if (debug_eroute) {
33642 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33643 +/*
33644 + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
33645 + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
33646 +*/
33647 + subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
33648 + subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
33649 + sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa));
33650 +
33651 + KLIPS_PRINT(debug_eroute,
33652 + "klips_debug:ipsec_makeroute: "
33653 + "pid=%05d "
33654 + "count=%10d "
33655 + "lasttime=%6d "
33656 + "%-18s -> %-18s => %s\n",
33657 + retrt->er_pid,
33658 + retrt->er_count,
33659 + (int)(jiffies/HZ - retrt->er_lasttime),
33660 + buf1,
33661 + buf2,
33662 + sa_len ? sa : " (error)");
33663 + }
33664 +#endif /* CONFIG_KLIPS_DEBUG */
33665 + KLIPS_PRINT(debug_eroute,
33666 + "klips_debug:ipsec_makeroute: "
33667 + "succeeded.\n");
33668 + return 0;
33669 +}
33670 +
33671 +struct eroute *
33672 +ipsec_findroute(struct sockaddr_encap *eaddr)
33673 +{
33674 + struct radij_node *rn;
33675 +#ifdef CONFIG_KLIPS_DEBUG
33676 + char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
33677 +
33678 + if (debug_radij & DB_RJ_FINDROUTE) {
33679 + addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
33680 + addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
33681 + KLIPS_PRINT(debug_eroute,
33682 + "klips_debug:ipsec_findroute: "
33683 + "%s:%d->%s:%d %d\n",
33684 + buf1, ntohs(eaddr->sen_sport),
33685 + buf2, ntohs(eaddr->sen_dport),
33686 + eaddr->sen_proto);
33687 + }
33688 +#endif /* CONFIG_KLIPS_DEBUG */
33689 + rn = rj_match((caddr_t)eaddr, rnh);
33690 + if(rn) {
33691 + KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
33692 + "klips_debug:ipsec_findroute: "
33693 + "found, points to proto=%d, spi=%x, dst=%x.\n",
33694 + ((struct eroute*)rn)->er_said.proto,
33695 + ntohl(((struct eroute*)rn)->er_said.spi),
33696 + ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr));
33697 + }
33698 + return (struct eroute *)rn;
33699 +}
33700 +
33701 +#ifdef CONFIG_PROC_FS
33702 +/** ipsec_rj_walker_procprint: print one line of eroute table output.
33703 + *
33704 + * Theoretical BUG: if w->length is less than the length
33705 + * of some line we should produce, that line will never
33706 + * be finished. In effect, the "file" will stop part way
33707 + * through that line.
33708 + */
33709 +int
33710 +ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
33711 +{
33712 + struct eroute *ro = (struct eroute *)rn;
33713 + struct rjtentry *rd = (struct rjtentry *)rn;
33714 + struct wsbuf *w = (struct wsbuf *)w0;
33715 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33716 + char buf3[16];
33717 + char sa[SATOT_BUF];
33718 + size_t sa_len, buf_len;
33719 + struct sockaddr_encap *key, *mask;
33720 +
33721 + KLIPS_PRINT(debug_radij,
33722 + "klips_debug:ipsec_rj_walker_procprint: "
33723 + "rn=0p%p, w0=0p%p\n",
33724 + rn,
33725 + w0);
33726 + if (rn->rj_b >= 0) {
33727 + return 0;
33728 + }
33729 +
33730 + key = rd_key(rd);
33731 + mask = rd_mask(rd);
33732 +
33733 + if (key == NULL || mask == NULL) {
33734 + return 0;
33735 + }
33736 +
33737 + buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33738 + if(key->sen_sport != 0) {
33739 + sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
33740 + }
33741 +
33742 + buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33743 + if(key->sen_dport != 0) {
33744 + sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
33745 + }
33746 +
33747 + buf3[0]='\0';
33748 + if(key->sen_proto != 0) {
33749 + sprintf(buf3, ":%d", key->sen_proto);
33750 + }
33751 +
33752 + sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa));
33753 + w->len += ipsec_snprintf(w->buffer + w->len,
33754 + w->length - w->len,
33755 + "%-10d "
33756 + "%-18s -> %-18s => %s%s\n",
33757 + ro->er_count,
33758 + buf1,
33759 + buf2,
33760 + sa_len ? sa : " (error)",
33761 + buf3);
33762 +
33763 + {
33764 + /* snprintf can only fill the last character with NUL
33765 + * so the maximum useful character is w->length-1.
33766 + * However, if w->length == 0, we cannot go back.
33767 + * (w->length surely cannot be negative.)
33768 + */
33769 + int max_content = w->length > 0? w->length-1 : 0;
33770 +
33771 + if (w->len >= max_content) {
33772 + /* we've done all that can fit -- stop treewalking */
33773 + w->len = max_content; /* truncate crap */
33774 + return -ENOBUFS;
33775 + } else {
33776 + const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
33777 +
33778 + if (pos <= w->offset) {
33779 + /* all is before first interesting character:
33780 + * discard, but note where we are.
33781 + */
33782 + w->len = 0;
33783 + w->begin = pos;
33784 + }
33785 + return 0;
33786 + }
33787 + }
33788 +}
33789 +#endif /* CONFIG_PROC_FS */
33790 +
33791 +int
33792 +ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
33793 +{
33794 + struct eroute *ro;
33795 + struct rjtentry *rd = (struct rjtentry *)rn;
33796 + struct radij_node *rn2;
33797 + int error;
33798 + struct sockaddr_encap *key, *mask;
33799 +
33800 + key = rd_key(rd);
33801 + mask = rd_mask(rd);
33802 +
33803 + if(!key || !mask) {
33804 + return -ENODATA;
33805 + }
33806 +#ifdef CONFIG_KLIPS_DEBUG
33807 + if(debug_radij) {
33808 + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
33809 + subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
33810 + subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
33811 + KLIPS_PRINT(debug_radij,
33812 + "klips_debug:ipsec_rj_walker_delete: "
33813 + "deleting: %s -> %s\n",
33814 + buf1,
33815 + buf2);
33816 + }
33817 +#endif /* CONFIG_KLIPS_DEBUG */
33818 +
33819 + if((error = rj_delete(key, mask, rnh, &rn2))) {
33820 + KLIPS_PRINT(debug_radij,
33821 + "klips_debug:ipsec_rj_walker_delete: "
33822 + "rj_delete failed with error=%d.\n", error);
33823 + return error;
33824 + }
33825 +
33826 + if(rn2 != rn) {
33827 + printk("klips_debug:ipsec_rj_walker_delete: "
33828 + "tried to delete a different node?!? This should never happen!\n");
33829 + }
33830 +
33831 + ro = (struct eroute *)rn;
33832 +
33833 + if (ro->er_ident_s.data)
33834 + kfree(ro->er_ident_s.data);
33835 + if (ro->er_ident_d.data)
33836 + kfree(ro->er_ident_d.data);
33837 +
33838 + memset((caddr_t)rn, 0, sizeof (struct eroute));
33839 + kfree(rn);
33840 +
33841 + return 0;
33842 +}
33843 +
33844 +/*
33845 + * $Log: ipsec_radij.c,v $
33846 + * Revision 1.73.2.1 2006/10/06 21:39:26 paul
33847 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
33848 + * set. This is defined through autoconf.h which is included through the
33849 + * linux kernel build macros.
33850 + *
33851 + * Revision 1.73 2005/04/29 05:10:22 mcr
33852 + * removed from extraenous includes to make unit testing easier.
33853 + *
33854 + * Revision 1.72 2004/12/03 21:25:57 mcr
33855 + * compile time fixes for running on 2.6.
33856 + * still experimental.
33857 + *
33858 + * Revision 1.71 2004/07/10 19:11:18 mcr
33859 + * CONFIG_IPSEC -> CONFIG_KLIPS.
33860 + *
33861 + * Revision 1.70 2004/04/25 21:10:52 ken
33862 + * Pull in dhr's changes from FreeS/WAN 2.06
33863 + *
33864 + * Revision 1.69 2004/04/06 02:49:26 mcr
33865 + * pullup of algo code from alg-branch.
33866 + *
33867 + * Revision 1.68 2004/03/28 20:27:20 paul
33868 + * Included tested and confirmed fixes mcr made and dhr verified for
33869 + * snprint statements. Changed one other snprintf to use ipsec_snprintf
33870 + * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
33871 + * dhr. (thanks dhr!)
33872 + *
33873 + * Revision 1.67.4.1 2004/04/05 04:30:46 mcr
33874 + * patches for alg-branch to compile/work with 2.x openswan
33875 + *
33876 + * Revision 1.67 2003/10/31 02:27:55 mcr
33877 + * pulled up port-selector patches and sa_id elimination.
33878 + *
33879 + * Revision 1.66.24.2 2003/10/29 01:30:41 mcr
33880 + * elimited "struct sa_id".
33881 + *
33882 + * Revision 1.66.24.1 2003/09/21 13:59:56 mcr
33883 + * pre-liminary X.509 patch - does not yet pass tests.
33884 + *
33885 + * Revision 1.66 2002/10/12 23:11:53 dhr
33886 + *
33887 + * [KenB + DHR] more 64-bit cleanup
33888 + *
33889 + * Revision 1.65 2002/09/20 05:01:40 rgb
33890 + * Added memory allocation debugging.
33891 + *
33892 + * Revision 1.64 2002/05/31 01:46:05 mcr
33893 + * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute
33894 + * as requested in PR#14.
33895 + *
33896 + * Revision 1.63 2002/05/23 07:14:11 rgb
33897 + * Cleaned up %p variants to 0p%p for test suite cleanup.
33898 + *
33899 + * Revision 1.62 2002/04/24 07:55:32 mcr
33900 + * #include patches and Makefiles for post-reorg compilation.
33901 + *
33902 + * Revision 1.61 2002/04/24 07:36:29 mcr
33903 + * Moved from ./klips/net/ipsec/ipsec_radij.c,v
33904 + *
33905 + * Revision 1.60 2002/02/19 23:59:45 rgb
33906 + * Removed redundant compiler directives.
33907 + *
33908 + * Revision 1.59 2002/02/06 04:13:47 mcr
33909 + * missing #ifdef CONFIG_IPSEC_DEBUG.
33910 + *
33911 + * Revision 1.58 2002/01/29 17:17:56 mcr
33912 + * moved include of ipsec_param.h to after include of linux/kernel.h
33913 + * otherwise, it seems that some option that is set in ipsec_param.h
33914 + * screws up something subtle in the include path to kernel.h, and
33915 + * it complains on the snprintf() prototype.
33916 + *
33917 + * Revision 1.57 2002/01/29 04:00:52 mcr
33918 + * more excise of kversions.h header.
33919 + *
33920 + * Revision 1.56 2002/01/29 02:13:17 mcr
33921 + * introduction of ipsec_kversion.h means that include of
33922 + * ipsec_param.h must preceed any decisions about what files to
33923 + * include to deal with differences in kernel source.
33924 + *
33925 + * Revision 1.55 2001/11/26 09:23:48 rgb
33926 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
33927 + *
33928 + * Revision 1.53.2.1 2001/09/25 02:26:32 mcr
33929 + * headers adjusted for new usage.
33930 + *
33931 + * Revision 1.54 2001/10/18 04:45:20 rgb
33932 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
33933 + * lib/freeswan.h version macros moved to lib/kversions.h.
33934 + * Other compiler directive cleanups.
33935 + *
33936 + * Revision 1.53 2001/09/19 17:19:40 rgb
33937 + * Debug output bugfix for NetCelo's PF_KEY ident patch.
33938 + *
33939 + * Revision 1.52 2001/09/19 16:33:37 rgb
33940 + * Temporarily disable ident fields to /proc/net/ipsec_eroute.
33941 + *
33942 + * Revision 1.51 2001/09/15 16:24:04 rgb
33943 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
33944 + *
33945 + * Revision 1.50 2001/09/14 16:58:36 rgb
33946 + * Added support for storing the first and last packets through a HOLD.
33947 + *
33948 + * Revision 1.49 2001/09/08 21:13:32 rgb
33949 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
33950 + *
33951 + * Revision 1.48 2001/06/15 04:12:56 rgb
33952 + * Fixed kernel memory allocation error return code polarity bug.
33953 + *
33954 + * Revision 1.47 2001/06/14 19:35:09 rgb
33955 + * Update copyright date.
33956 + *
33957 + * Revision 1.46 2001/06/08 08:47:18 rgb
33958 + * Fixed for debug disabled.
33959 + *
33960 + * Revision 1.45 2001/05/27 06:12:11 rgb
33961 + * Added structures for pid, packet count and last access time to eroute.
33962 + * Added packet count to beginning of /proc/net/ipsec_eroute.
33963 + *
33964 + * Revision 1.44 2001/05/03 19:41:01 rgb
33965 + * Initialise error return variable.
33966 + * Use more appropriate return value for ipsec_rj_walker_delete().
33967 + *
33968 + * Revision 1.43 2001/02/27 22:24:54 rgb
33969 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
33970 + * Check for satoa() return codes.
33971 + *
33972 + * Revision 1.42 2001/02/27 06:21:57 rgb
33973 + * Added findroute success instrumentation.
33974 + *
33975 + * Revision 1.41 2000/11/06 04:32:08 rgb
33976 + * Ditched spin_lock_irqsave in favour of spin_lock_bh.
33977 + *
33978 + * Revision 1.40 2000/09/08 19:12:56 rgb
33979 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
33980 + *
33981 + * Revision 1.39 2000/08/30 05:25:20 rgb
33982 + * Correct debug text in ipsec_breakroute() from incorrect
33983 + * "ipsec_callback".
33984 + *
33985 + * Revision 1.38 2000/07/28 14:58:31 rgb
33986 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
33987 + *
33988 + * Revision 1.37 2000/03/16 14:02:50 rgb
33989 + * Fixed debug scope to enable compilation with debug off.
33990 + *
33991 + * Revision 1.36 2000/01/21 06:14:46 rgb
33992 + * Added debugging text to ipsec_rj_walker_delete().
33993 + * Set return code to negative for consistency.
33994 + *
33995 + * Revision 1.35 1999/11/23 23:05:24 rgb
33996 + * Use provided macro ADDRTOA_BUF instead of hardcoded value.
33997 + *
33998 + * Revision 1.34 1999/11/18 04:13:56 rgb
33999 + * Replaced all kernel version macros to shorter, readable form.
34000 + * Added CONFIG_PROC_FS compiler directives in case it is shut off.
34001 + *
34002 + * Revision 1.33 1999/11/17 15:53:39 rgb
34003 + * Changed all occurrences of #include "../../../lib/freeswan.h"
34004 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
34005 + * klips/net/ipsec/Makefile.
34006 + *
34007 + * Revision 1.32 1999/10/26 13:58:33 rgb
34008 + * Put spinlock flags variable declaration outside the debug compiler
34009 + * directive to enable compilation with debug shut off.
34010 + *
34011 + * Revision 1.31 1999/10/15 22:13:29 rgb
34012 + * Clean out cruft.
34013 + * Align /proc/net/ipsec_eroute output for easier readability.
34014 + * Fix double linefeed in radij debug output.
34015 + * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
34016 + *
34017 + * Revision 1.30 1999/10/08 18:37:33 rgb
34018 + * Fix end-of-line spacing to sate whining PHMs.
34019 + *
34020 + * Revision 1.29 1999/10/03 18:52:45 rgb
34021 + * Spinlock support for 2.0.xx.
34022 + * Dumb return code spin_unlock fix.
34023 + *
34024 + * Revision 1.28 1999/10/01 16:22:24 rgb
34025 + * Switch from assignment init. to functional init. of spinlocks.
34026 + *
34027 + * Revision 1.27 1999/10/01 15:44:53 rgb
34028 + * Move spinlock header include to 2.1> scope.
34029 + *
34030 + * Revision 1.26 1999/10/01 00:01:23 rgb
34031 + * Added eroute structure locking.
34032 + *
34033 + * Revision 1.25 1999/06/10 16:07:30 rgb
34034 + * Silence delete eroute on no debug.
34035 + *
34036 + * Revision 1.24 1999/05/09 03:25:36 rgb
34037 + * Fix bug introduced by 2.2 quick-and-dirty patch.
34038 + *
34039 + * Revision 1.23 1999/05/05 22:02:31 rgb
34040 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
34041 + *
34042 + * Revision 1.22 1999/04/29 15:17:23 rgb
34043 + * Add return values to init and cleanup functions.
34044 + * Add sanity checking for null pointer arguments.
34045 + *
34046 + * Revision 1.21 1999/04/11 00:28:58 henry
34047 + * GPL boilerplate
34048 + *
34049 + * Revision 1.20 1999/04/06 04:54:26 rgb
34050 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
34051 + * patch shell fixes.
34052 + *
34053 + * Revision 1.19 1999/02/17 16:50:35 rgb
34054 + * Clean out unused cruft.
34055 + * Consolidate for space and speed efficiency.
34056 + * Convert DEBUG_IPSEC to KLIPS_PRINT
34057 + *
34058 + * Revision 1.18 1999/01/22 06:22:06 rgb
34059 + * Cruft clean-out.
34060 + * 64-bit clean-up.
34061 + *
34062 + * Revision 1.17 1998/12/02 03:09:39 rgb
34063 + * Clean up debug printing conditionals to compile with debugging off.
34064 + *
34065 + * Revision 1.16 1998/12/01 13:49:39 rgb
34066 + * Wrap version info printing in debug switches.
34067 + *
34068 + * Revision 1.15 1998/11/30 13:22:54 rgb
34069 + * Rationalised all the klips kernel file headers. They are much shorter
34070 + * now and won't conflict under RH5.2.
34071 + *
34072 + * Revision 1.14 1998/10/31 06:48:17 rgb
34073 + * Fixed up comments in #endif directives.
34074 + *
34075 + * Revision 1.13 1998/10/27 13:48:09 rgb
34076 + * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
34077 + * Fixed less(1) truncated output bug.
34078 + * Code clean-up.
34079 + *
34080 + * Revision 1.12 1998/10/25 02:41:36 rgb
34081 + * Change return type on ipsec_breakroute and ipsec_makeroute and add an
34082 + * argument to be able to transmit more infomation about errors.
34083 + * Fix cut-and-paste debug statement identifier.
34084 + *
34085 + * Revision 1.11 1998/10/22 06:45:39 rgb
34086 + * Cleaned up cruft.
34087 + * Convert to use satoa for printk.
34088 + *
34089 + * Revision 1.10 1998/10/19 14:44:28 rgb
34090 + * Added inclusion of freeswan.h.
34091 + * sa_id structure implemented and used: now includes protocol.
34092 + *
34093 + * Revision 1.9 1998/10/09 04:30:52 rgb
34094 + * Added 'klips_debug' prefix to all klips printk debug statements.
34095 + * Deleted old commented out cruft.
34096 + *
34097 + * Revision 1.8 1998/08/06 17:24:23 rgb
34098 + * Fix addrtoa return code bug from stale manpage advice preventing packets
34099 + * from being erouted.
34100 + *
34101 + * Revision 1.7 1998/08/06 07:44:59 rgb
34102 + * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
34103 + * ended up in nothing being printed.
34104 + *
34105 + * Revision 1.6 1998/08/05 22:16:41 rgb
34106 + * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
34107 + *
34108 + * Revision 1.5 1998/07/29 20:38:44 rgb
34109 + * Debug and fix subnettoa and addrtoa output.
34110 + *
34111 + * Revision 1.4 1998/07/28 00:02:39 rgb
34112 + * Converting to exclusive use of addrtoa.
34113 + * Fix eroute delete.
34114 + *
34115 + * Revision 1.3 1998/07/14 18:21:26 rgb
34116 + * Add function to clear the eroute table.
34117 + *
34118 + * Revision 1.2 1998/06/23 02:59:14 rgb
34119 + * Added debugging output to eroute add/delete routines.
34120 + *
34121 + * Revision 1.9 1998/06/18 21:29:06 henry
34122 + * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
34123 + * build scripts happier in presence of symbolic links
34124 + *
34125 + * Revision 1.8 1998/06/05 02:32:26 rgb
34126 + * Fix spi ntoh kernel debug output.
34127 + *
34128 + * Revision 1.7 1998/05/25 20:30:37 rgb
34129 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
34130 + *
34131 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
34132 + * add ipsec_rj_walker_delete.
34133 + *
34134 + * Revision 1.6 1998/05/21 13:08:57 rgb
34135 + * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
34136 + * information is available for printout.
34137 + *
34138 + * Revision 1.5 1998/05/18 21:35:55 rgb
34139 + * Clean up output for numerical consistency and readability. Zero freed
34140 + * eroute memory.
34141 + *
34142 + * Revision 1.4 1998/04/21 21:28:58 rgb
34143 + * Rearrange debug switches to change on the fly debug output from user
34144 + * space. Only kernel changes checked in at this time. radij.c was also
34145 + * changed to temporarily remove buggy debugging code in rj_delete causing
34146 + * an OOPS and hence, netlink device open errors.
34147 + *
34148 + * Revision 1.3 1998/04/14 17:30:39 rgb
34149 + * Fix up compiling errors for radij tree memory reclamation.
34150 + *
34151 + * Revision 1.2 1998/04/12 22:03:23 rgb
34152 + * Updated ESP-3DES-HMAC-MD5-96,
34153 + * ESP-DES-HMAC-MD5-96,
34154 + * AH-HMAC-MD5-96,
34155 + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
34156 + * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
34157 + *
34158 + * Fixed eroute references in /proc/net/ipsec*.
34159 + *
34160 + * Started to patch module unloading memory leaks in ipsec_netlink and
34161 + * radij tree unloading.
34162 + *
34163 + * Revision 1.1 1998/04/09 03:06:10 henry
34164 + * sources moved up from linux/net/ipsec
34165 + *
34166 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
34167 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
34168 + *
34169 + * Revision 0.4 1997/01/15 01:28:15 ji
34170 + * No changes.
34171 + *
34172 + * Revision 0.3 1996/11/20 14:39:04 ji
34173 + * Minor cleanups.
34174 + * Rationalized debugging code.
34175 + *
34176 + * Revision 0.2 1996/11/02 00:18:33 ji
34177 + * First limited release.
34178 + *
34179 + *
34180 + */
34181 --- /dev/null Tue Mar 11 13:02:56 2003
34182 +++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004
34183 @@ -0,0 +1,2317 @@
34184 +/*
34185 + * receive code
34186 + * Copyright (C) 1996, 1997 John Ioannidis.
34187 + * Copyright (C) 1998-2003 Richard Guy Briggs.
34188 + * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
34189 + *
34190 + * This program is free software; you can redistribute it and/or modify it
34191 + * under the terms of the GNU General Public License as published by the
34192 + * Free Software Foundation; either version 2 of the License, or (at your
34193 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
34194 + *
34195 + * This program is distributed in the hope that it will be useful, but
34196 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
34197 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34198 + * for more details.
34199 + */
34200 +
34201 +char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.171.2.11 2007/04/28 20:46:40 paul Exp $";
34202 +
34203 +#ifndef AUTOCONF_INCLUDED
34204 +#include <linux/config.h>
34205 +#endif
34206 +#include <linux/version.h>
34207 +
34208 +#define __NO_VERSION__
34209 +#include <linux/module.h>
34210 +#include <linux/kernel.h> /* printk() */
34211 +
34212 +#include "openswan/ipsec_param.h"
34213 +
34214 +#ifdef MALLOC_SLAB
34215 +# include <linux/slab.h> /* kmalloc() */
34216 +#else /* MALLOC_SLAB */
34217 +# include <linux/malloc.h> /* kmalloc() */
34218 +#endif /* MALLOC_SLAB */
34219 +#include <linux/errno.h> /* error codes */
34220 +#include <linux/types.h> /* size_t */
34221 +#include <linux/interrupt.h> /* mark_bh */
34222 +
34223 +#include <linux/netdevice.h> /* struct device, and other headers */
34224 +#include <linux/etherdevice.h> /* eth_type_trans */
34225 +#include <linux/ip.h> /* struct iphdr */
34226 +
34227 +#include <net/tcp.h>
34228 +#include <net/udp.h>
34229 +#include <linux/skbuff.h>
34230 +#include <openswan.h>
34231 +#ifdef SPINLOCK
34232 +# ifdef SPINLOCK_23
34233 +# include <linux/spinlock.h> /* *lock* */
34234 +# else /* SPINLOCK_23 */
34235 +# include <asm/spinlock.h> /* *lock* */
34236 +# endif /* SPINLOCK_23 */
34237 +#endif /* SPINLOCK */
34238 +
34239 +#include <net/ip.h>
34240 +
34241 +#include "openswan/ipsec_kern24.h"
34242 +#include "openswan/radij.h"
34243 +#include "openswan/ipsec_encap.h"
34244 +#include "openswan/ipsec_sa.h"
34245 +
34246 +#include "openswan/ipsec_radij.h"
34247 +#include "openswan/ipsec_xform.h"
34248 +#include "openswan/ipsec_tunnel.h"
34249 +#include "openswan/ipsec_rcv.h"
34250 +
34251 +#include "openswan/ipsec_auth.h"
34252 +
34253 +#include "openswan/ipsec_esp.h"
34254 +
34255 +#ifdef CONFIG_KLIPS_AH
34256 +#include "openswan/ipsec_ah.h"
34257 +#endif /* CONFIG_KLIPS_AH */
34258 +
34259 +#ifdef CONFIG_KLIPS_IPCOMP
34260 +#include "openswan/ipsec_ipcomp.h"
34261 +#endif /* CONFIG_KLIPS_COMP */
34262 +
34263 +#include <pfkeyv2.h>
34264 +#include <pfkey.h>
34265 +
34266 +#include "openswan/ipsec_proto.h"
34267 +#include "openswan/ipsec_alg.h"
34268 +#include "openswan/ipsec_kern24.h"
34269 +
34270 +#ifdef CONFIG_KLIPS_DEBUG
34271 +int debug_rcv = 0;
34272 +#endif /* CONFIG_KLIPS_DEBUG */
34273 +
34274 +int sysctl_ipsec_inbound_policy_check = 1;
34275 +
34276 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34277 +#include <linux/udp.h>
34278 +#endif
34279 +
34280 +/* This is a private use protocol, and AT&T should be ashamed. They should have
34281 + * used protocol # 59, which is "no next header" instead of 0xFE.
34282 + */
34283 +#ifndef IPPROTO_ATT_HEARTBEAT
34284 +#define IPPROTO_ATT_HEARTBEAT 0xFE
34285 +#endif
34286 +
34287 +/*
34288 + * Check-replay-window routine, adapted from the original
34289 + * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
34290 + *
34291 + * This is a routine that implements a 64 packet window. This is intend-
34292 + * ed on being an implementation sample.
34293 + */
34294 +
34295 +DEBUG_NO_STATIC int
34296 +ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
34297 +{
34298 + __u32 diff;
34299 +
34300 + if (ipsp->ips_replaywin == 0) /* replay shut off */
34301 + return 1;
34302 + if (seq == 0)
34303 + return 0; /* first == 0 or wrapped */
34304 +
34305 + /* new larger sequence number */
34306 + if (seq > ipsp->ips_replaywin_lastseq) {
34307 + return 1; /* larger is good */
34308 + }
34309 + diff = ipsp->ips_replaywin_lastseq - seq;
34310 +
34311 + /* too old or wrapped */ /* if wrapped, kill off SA? */
34312 + if (diff >= ipsp->ips_replaywin) {
34313 + return 0;
34314 + }
34315 + /* this packet already seen */
34316 + if (ipsp->ips_replaywin_bitmap & (1 << diff))
34317 + return 0;
34318 + return 1; /* out of order but good */
34319 +}
34320 +
34321 +DEBUG_NO_STATIC int
34322 +ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
34323 +{
34324 + __u32 diff;
34325 +
34326 + if (ipsp->ips_replaywin == 0) /* replay shut off */
34327 + return 1;
34328 + if (seq == 0)
34329 + return 0; /* first == 0 or wrapped */
34330 +
34331 + /* new larger sequence number */
34332 + if (seq > ipsp->ips_replaywin_lastseq) {
34333 + diff = seq - ipsp->ips_replaywin_lastseq;
34334 +
34335 + /* In win, set bit for this pkt */
34336 + if (diff < ipsp->ips_replaywin)
34337 + ipsp->ips_replaywin_bitmap =
34338 + (ipsp->ips_replaywin_bitmap << diff) | 1;
34339 + else
34340 + /* This packet has way larger seq num */
34341 + ipsp->ips_replaywin_bitmap = 1;
34342 +
34343 + if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
34344 + ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
34345 + }
34346 + ipsp->ips_replaywin_lastseq = seq;
34347 + return 1; /* larger is good */
34348 + }
34349 + diff = ipsp->ips_replaywin_lastseq - seq;
34350 +
34351 + /* too old or wrapped */ /* if wrapped, kill off SA? */
34352 + if (diff >= ipsp->ips_replaywin) {
34353 +/*
34354 + if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
34355 + ipsec_sa_delchain(ipsp);
34356 + }
34357 +*/
34358 + return 0;
34359 + }
34360 + /* this packet already seen */
34361 + if (ipsp->ips_replaywin_bitmap & (1 << diff))
34362 + return 0;
34363 + ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */
34364 + return 1; /* out of order but good */
34365 +}
34366 +
34367 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34368 +struct auth_alg ipsec_rcv_md5[]={
34369 + {osMD5Init, osMD5Update, osMD5Final, AHMD596_ALEN}
34370 +};
34371 +
34372 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34373 +
34374 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34375 +struct auth_alg ipsec_rcv_sha1[]={
34376 + {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
34377 +};
34378 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34379 +
34380 +/*
34381 + * decapsulate a single layer of the system
34382 + *
34383 + * the following things should be setup to enter this function.
34384 + *
34385 + * irs->stats == stats structure (or NULL)
34386 + * irs->ipp = IP header.
34387 + * irs->len = total length of packet
34388 + * skb->nh.iph = ipp;
34389 + * skb->h.raw = start of payload
34390 + * irs->ipsp = NULL.
34391 + * irs->iphlen = N/A = is recalculated.
34392 + * irs->ilen = 0;
34393 + * irs->authlen = 0;
34394 + * irs->authfuncs = NULL;
34395 + * irs->skb = the skb;
34396 + *
34397 + * proto_funcs should be from ipsec_esp.c, ipsec_ah.c or ipsec_ipcomp.c.
34398 + *
34399 + */
34400 +enum ipsec_rcv_value
34401 +ipsec_rcv_decap_once(struct ipsec_rcv_state *irs
34402 + , struct xform_functions *proto_funcs)
34403 +{
34404 + int iphlen;
34405 + __u8 proto;
34406 + struct in_addr ipsaddr;
34407 + struct in_addr ipdaddr;
34408 + int replay = 0; /* replay value in AH or ESP packet */
34409 + struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
34410 + struct ipsec_sa *newipsp;
34411 + struct iphdr *ipp;
34412 + struct sk_buff *skb;
34413 + struct ipsec_alg_auth *ixt_a=NULL;
34414 +
34415 + skb = irs->skb;
34416 + irs->len = skb->len;
34417 + ipp = irs->ipp;
34418 + proto = ipp->protocol;
34419 + ipsaddr.s_addr = ipp->saddr;
34420 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
34421 + ipdaddr.s_addr = ipp->daddr;
34422 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
34423 +
34424 + iphlen = ipp->ihl << 2;
34425 + irs->iphlen=iphlen;
34426 + ipp->check = 0; /* we know the sum is good */
34427 +
34428 + KLIPS_PRINT(debug_rcv,
34429 + "klips_debug:ipsec_rcv_decap_once: "
34430 + "decap (%d) from %s -> %s\n",
34431 + proto, irs->ipsaddr_txt, irs->ipdaddr_txt);
34432 +
34433 + /*
34434 + * Find tunnel control block and (indirectly) call the
34435 + * appropriate tranform routine. The resulting sk_buf
34436 + * is a valid IP packet ready to go through input processing.
34437 + */
34438 +
34439 + irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr;
34440 + irs->said.dst.u.v4.sin_family = AF_INET;
34441 +
34442 + /* note: rcv_checks set up the said.spi value, if appropriate */
34443 + if(proto_funcs->rcv_checks) {
34444 + enum ipsec_rcv_value retval =
34445 + (*proto_funcs->rcv_checks)(irs, skb);
34446 +
34447 + if(retval < 0) {
34448 + return retval;
34449 + }
34450 + }
34451 +
34452 + irs->said.proto = proto;
34453 + irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
34454 + if(irs->sa_len == 0) {
34455 + strcpy(irs->sa, "(error)");
34456 + }
34457 +
34458 + newipsp = ipsec_sa_getbyid(&irs->said);
34459 + if (newipsp == NULL) {
34460 + KLIPS_PRINT(debug_rcv,
34461 + "klips_debug:ipsec_rcv: "
34462 + "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
34463 + irs->sa_len ? irs->sa : " (error)");
34464 + if(irs->stats) {
34465 + irs->stats->rx_dropped++;
34466 + }
34467 + return IPSEC_RCV_SAIDNOTFOUND;
34468 + }
34469 +
34470 + /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having
34471 + * incremented the refcount, why in the world would we decrement it
34472 + * here? */
34473 + /* ipsec_sa_put(irs->ipsp);*/ /* incomplete */
34474 +
34475 + /* If it is in larval state, drop the packet, we cannot process yet. */
34476 + if(newipsp->ips_state == SADB_SASTATE_LARVAL) {
34477 + KLIPS_PRINT(debug_rcv,
34478 + "klips_debug:ipsec_rcv: "
34479 + "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
34480 + if(irs->stats) {
34481 + irs->stats->rx_dropped++;
34482 + }
34483 + ipsec_sa_put(newipsp);
34484 + return IPSEC_RCV_SAIDNOTLIVE;
34485 + }
34486 +
34487 + if(newipsp->ips_state == SADB_SASTATE_DEAD) {
34488 + KLIPS_PRINT(debug_rcv,
34489 + "klips_debug:ipsec_rcv: "
34490 + "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
34491 + if(irs->stats) {
34492 + irs->stats->rx_dropped++;
34493 + }
34494 + ipsec_sa_put(newipsp);
34495 + return IPSEC_RCV_SAIDNOTLIVE;
34496 + }
34497 +
34498 + if(sysctl_ipsec_inbound_policy_check) {
34499 + if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
34500 + KLIPS_PRINT(debug_rcv,
34501 + "klips_debug:ipsec_rcv: "
34502 + "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
34503 + irs->sa_len ? irs->sa : " (error)",
34504 + irs->ipsaddr_txt);
34505 + if(irs->stats) {
34506 + irs->stats->rx_dropped++;
34507 + }
34508 + ipsec_sa_put(newipsp);
34509 + return IPSEC_RCV_FAILEDINBOUND;
34510 + }
34511 +
34512 + KLIPS_PRINT(debug_rcv,
34513 + "klips_debug:ipsec_rcv: "
34514 + "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
34515 + irs->sa_len ? irs->sa : " (error)",
34516 + irs->ipsaddr_txt);
34517 +
34518 + /*
34519 + * at this point, we have looked up a new SA, and we want to make sure that if this
34520 + * isn't the first SA in the list, that the previous SA actually points at this one.
34521 + */
34522 + if(irs->ipsp) {
34523 + if(irs->ipsp->ips_inext != newipsp) {
34524 + KLIPS_PRINT(debug_rcv,
34525 + "klips_debug:ipsec_rcv: "
34526 + "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
34527 + irs->sa_len ? irs->sa : " (error)");
34528 + if(irs->stats) {
34529 + irs->stats->rx_dropped++;
34530 + }
34531 + ipsec_sa_put(newipsp);
34532 + return IPSEC_RCV_FAILEDINBOUND;
34533 + }
34534 + KLIPS_PRINT(debug_rcv,
34535 + "klips_debug:ipsec_rcv: "
34536 + "SA:%s grouping from previous SA is OK.\n",
34537 + irs->sa_len ? irs->sa : " (error)");
34538 + } else {
34539 + KLIPS_PRINT(debug_rcv,
34540 + "klips_debug:ipsec_rcv: "
34541 + "SA:%s First SA in group.\n",
34542 + irs->sa_len ? irs->sa : " (error)");
34543 + }
34544 +
34545 +
34546 +
34547 +
34548 +
34549 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34550 + if (proto == IPPROTO_ESP) {
34551 + KLIPS_PRINT(debug_rcv,
34552 + "klips_debug:ipsec_rcv: "
34553 + "natt_type=%u tdbp->ips_natt_type=%u : %s\n",
34554 + irs->natt_type, newipsp->ips_natt_type,
34555 + (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad");
34556 + if (irs->natt_type != newipsp->ips_natt_type) {
34557 + KLIPS_PRINT(debug_rcv,
34558 + "klips_debug:ipsec_rcv: "
34559 + "SA:%s does not agree with expected NAT-T policy.\n",
34560 + irs->sa_len ? irs->sa : " (error)");
34561 + if(irs->stats) {
34562 + irs->stats->rx_dropped++;
34563 + }
34564 + ipsec_sa_put(newipsp);
34565 + return IPSEC_RCV_FAILEDINBOUND;
34566 + }
34567 + }
34568 +#endif
34569 + }
34570 +
34571 + /* okay, SA checks out, so free any previous SA, and record a new one*/
34572 +
34573 + if(irs->ipsp) {
34574 + ipsec_sa_put(irs->ipsp);
34575 + }
34576 + irs->ipsp=newipsp;
34577 +
34578 + /* note that the outer code will free the irs->ipsp
34579 + if there is an error */
34580 +
34581 +
34582 + /* now check the lifetimes */
34583 + if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes",
34584 + irs->sa, ipsec_life_countbased, ipsec_incoming,
34585 + irs->ipsp) == ipsec_life_harddied ||
34586 + ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",
34587 + irs->sa, ipsec_life_timebased, ipsec_incoming,
34588 + irs->ipsp) == ipsec_life_harddied ||
34589 + ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",
34590 + irs->sa, ipsec_life_timebased, ipsec_incoming,
34591 + irs->ipsp) == ipsec_life_harddied ||
34592 + ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",
34593 + irs->sa, ipsec_life_countbased, ipsec_incoming,
34594 + irs->ipsp) == ipsec_life_harddied) {
34595 + ipsec_sa_delchain(irs->ipsp);
34596 + if(irs->stats) {
34597 + irs->stats->rx_dropped++;
34598 + }
34599 +
34600 + KLIPS_PRINT(debug_rcv,
34601 + "klips_debug:ipsec_rcv_decap_once: "
34602 + "decap (%d) failed lifetime check\n",
34603 + proto);
34604 +
34605 + return IPSEC_RCV_LIFETIMEFAILED;
34606 + }
34607 +
34608 +#if 0
34609 + /*
34610 + * This is removed for some reasons:
34611 + * 1) it needs to happen *after* authentication.
34612 + * 2) do we really care, if it authenticates, if it came
34613 + * from the wrong location?
34614 + * 3) the NAT_KA messages in IKE will also get to pluto
34615 + * and it will figure out that stuff has moved.
34616 + * 4) the 2.6 udp-esp encap function does not pass us
34617 + * the originating port number, and I can't tell
34618 + * if skb->sk is guaranteed to be valid here.
34619 + * 2005-04-16: mcr@xelerance.com
34620 + */
34621 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
34622 + /*
34623 + *
34624 + * XXX we should ONLY update pluto if the SA passes all checks,
34625 + * which we clearly do not now.
34626 + */
34627 + if ((irs->natt_type) &&
34628 + ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) ||
34629 + (irs->natt_sport != newipsp->ips_natt_sport)
34630 + )) {
34631 + struct sockaddr sipaddr;
34632 + struct sockaddr_in *psin = (struct sockaddr_in*)(newipsp->ips_addr_s);
34633 +
34634 + /** Advertise NAT-T addr change to pluto **/
34635 + sipaddr.sa_family = AF_INET;
34636 + ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr;
34637 + ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport);
34638 + pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport);
34639 +
34640 + /**
34641 + * Then allow or block packet depending on
34642 + * sysctl_ipsec_inbound_policy_check.
34643 + *
34644 + * In all cases, pluto will update SA if new mapping is
34645 + * accepted.
34646 + */
34647 + if (sysctl_ipsec_inbound_policy_check) {
34648 + KLIPS_PRINT(debug_rcv,
34649 + "klips_debug:ipsec_rcv: "
34650 + "SA:%s, src=%s:%u of pkt does not agree with expected "
34651 + "SA source address [%08x:%u] (notifying pluto of change).\n",
34652 + irs->sa_len ? irs->sa : " (error)",
34653 + irs->ipsaddr_txt, irs->natt_sport,
34654 + psin->sin_addr.s_addr,
34655 + newipsp->ips_natt_sport);
34656 + if(irs->stats) {
34657 + irs->stats->rx_dropped++;
34658 + }
34659 + ipsec_sa_put(newipsp);
34660 + return IPSEC_RCV_FAILEDINBOUND;
34661 + }
34662 + }
34663 +#endif
34664 +#endif
34665 +
34666 + irs->authfuncs=NULL;
34667 +
34668 + /* authenticate, if required */
34669 + if ((ixt_a=irs->ipsp->ips_alg_auth)) {
34670 + irs->authlen = AHHMAC_HASHLEN;
34671 + irs->authfuncs = NULL;
34672 + irs->ictx = NULL;
34673 + irs->octx = NULL;
34674 + irs->ictx_len = 0;
34675 + irs->octx_len = 0;
34676 + KLIPS_PRINT(debug_rcv,
34677 + "klips_debug:ipsec_rcv: "
34678 + "authalg=%d authlen=%d\n",
34679 + irs->ipsp->ips_authalg,
34680 + irs->authlen);
34681 + } else
34682 + switch(irs->ipsp->ips_authalg) {
34683 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
34684 + case AH_MD5:
34685 + irs->authlen = AHHMAC_HASHLEN;
34686 + irs->authfuncs = ipsec_rcv_md5;
34687 + irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
34688 + irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
34689 + irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
34690 + irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
34691 + break;
34692 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
34693 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
34694 + case AH_SHA:
34695 + irs->authlen = AHHMAC_HASHLEN;
34696 + irs->authfuncs = ipsec_rcv_sha1;
34697 + irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
34698 + irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
34699 + irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
34700 + irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
34701 + break;
34702 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
34703 + case AH_NONE:
34704 + irs->authlen = 0;
34705 + irs->authfuncs = NULL;
34706 + irs->ictx = NULL;
34707 + irs->octx = NULL;
34708 + irs->ictx_len = 0;
34709 + irs->octx_len = 0;
34710 + break;
34711 + default:
34712 + irs->ipsp->ips_errs.ips_alg_errs += 1;
34713 + if(irs->stats) {
34714 + irs->stats->rx_errors++;
34715 + }
34716 + return IPSEC_RCV_BADAUTH;
34717 + }
34718 +
34719 + /* ilen counts number of bytes in ESP portion */
34720 + irs->ilen = ((skb->data + skb->len) - skb->h.raw) - irs->authlen;
34721 + if(irs->ilen <= 0) {
34722 + KLIPS_PRINT(debug_rcv,
34723 + "klips_debug:ipsec_rcv: "
34724 + "runt %s packet with no data, dropping.\n",
34725 + (proto == IPPROTO_ESP ? "esp" : "ah"));
34726 + if(irs->stats) {
34727 + irs->stats->rx_dropped++;
34728 + }
34729 + return IPSEC_RCV_BADLEN;
34730 + }
34731 +
34732 + if(irs->authfuncs || ixt_a) {
34733 + unsigned char *authenticator = NULL;
34734 +
34735 + if(proto_funcs->rcv_setup_auth) {
34736 + enum ipsec_rcv_value retval
34737 + = (*proto_funcs->rcv_setup_auth)(irs, skb,
34738 + &replay,
34739 + &authenticator);
34740 + if(retval < 0) {
34741 + return retval;
34742 + }
34743 + }
34744 +
34745 + if(!authenticator) {
34746 + irs->ipsp->ips_errs.ips_auth_errs += 1;
34747 + if(irs->stats) {
34748 + irs->stats->rx_dropped++;
34749 + }
34750 + return IPSEC_RCV_BADAUTH;
34751 + }
34752 +
34753 + if(!ipsec_checkreplaywindow(irs->ipsp, replay)) {
34754 + irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34755 + KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34756 + "klips_debug:ipsec_rcv: "
34757 + "duplicate frame from %s, packet dropped\n",
34758 + irs->ipsaddr_txt);
34759 + if(irs->stats) {
34760 + irs->stats->rx_dropped++;
34761 + }
34762 + return IPSEC_RCV_REPLAYFAILED;
34763 + }
34764 +
34765 + /*
34766 + * verify authenticator
34767 + */
34768 +
34769 + KLIPS_PRINT(debug_rcv,
34770 + "klips_debug:ipsec_rcv: "
34771 + "encalg = %d, authalg = %d.\n",
34772 + irs->ipsp->ips_encalg,
34773 + irs->ipsp->ips_authalg);
34774 +
34775 + /* calculate authenticator */
34776 + if(proto_funcs->rcv_calc_auth == NULL) {
34777 + return IPSEC_RCV_BADAUTH;
34778 + }
34779 + (*proto_funcs->rcv_calc_auth)(irs, skb);
34780 +
34781 + if (memcmp(irs->hash, authenticator, irs->authlen)) {
34782 + irs->ipsp->ips_errs.ips_auth_errs += 1;
34783 + KLIPS_PRINT(debug_rcv & DB_RX_INAU,
34784 + "klips_debug:ipsec_rcv: "
34785 + "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
34786 + irs->ipsaddr_txt,
34787 + ntohl(*(__u32*)&irs->hash[0]),
34788 + ntohl(*(__u32*)&irs->hash[4]),
34789 + ntohl(*(__u32*)&irs->hash[8]),
34790 + ntohl(*(__u32*)authenticator),
34791 + ntohl(*((__u32*)authenticator + 1)),
34792 + ntohl(*((__u32*)authenticator + 2)));
34793 + if(irs->stats) {
34794 + irs->stats->rx_dropped++;
34795 + }
34796 + return IPSEC_RCV_AUTHFAILED;
34797 + } else {
34798 + KLIPS_PRINT(debug_rcv,
34799 + "klips_debug:ipsec_rcv: "
34800 + "authentication successful.\n");
34801 + }
34802 +
34803 + /* Crypto hygiene: clear memory used to calculate autheticator.
34804 + * The length varies with the algorithm.
34805 + */
34806 + memset(irs->hash, 0, irs->authlen);
34807 +
34808 + /* If the sequence number == 0, expire SA, it had rolled */
34809 + if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) {
34810 + ipsec_sa_delchain(irs->ipsp);
34811 + KLIPS_PRINT(debug_rcv,
34812 + "klips_debug:ipsec_rcv: "
34813 + "replay window counter rolled, expiring SA.\n");
34814 + if(irs->stats) {
34815 + irs->stats->rx_dropped++;
34816 + }
34817 + return IPSEC_RCV_REPLAYROLLED;
34818 + }
34819 +
34820 + /* now update the replay counter */
34821 + if (!ipsec_updatereplaywindow(irs->ipsp, replay)) {
34822 + irs->ipsp->ips_errs.ips_replaywin_errs += 1;
34823 + KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
34824 + "klips_debug:ipsec_rcv: "
34825 + "duplicate frame from %s, packet dropped\n",
34826 + irs->ipsaddr_txt);
34827 + if(irs->stats) {
34828 + irs->stats->rx_dropped++;
34829 + }
34830 + return IPSEC_RCV_REPLAYROLLED;
34831 + }
34832 + }
34833 +
34834 + if(proto_funcs->rcv_decrypt) {
34835 + enum ipsec_rcv_value retval =
34836 + (*proto_funcs->rcv_decrypt)(irs);
34837 +
34838 + if(retval != IPSEC_RCV_OK) {
34839 + return retval;
34840 + }
34841 + }
34842 +
34843 + /*
34844 + * Adjust pointers
34845 + */
34846 + skb = irs->skb;
34847 + irs->len = skb->len;
34848 + ipp = irs->ipp = skb->nh.iph;
34849 + iphlen = ipp->ihl<<2;
34850 + skb->h.raw = skb->nh.raw + iphlen;
34851 +
34852 + /* zero any options that there might be */
34853 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
34854 +
34855 + ipsaddr.s_addr = ipp->saddr;
34856 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
34857 + ipdaddr.s_addr = ipp->daddr;
34858 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
34859 +
34860 + /*
34861 + * Discard the original ESP/AH header
34862 + */
34863 + ipp->protocol = irs->next_header;
34864 +
34865 + ipp->check = 0; /* NOTE: this will be included in checksum */
34866 + ipp->check = ip_fast_csum((unsigned char *)skb->nh.iph, iphlen >> 2);
34867 +
34868 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34869 + "klips_debug:ipsec_rcv: "
34870 + "after <%s%s%s>, SA:%s:\n",
34871 + IPS_XFORM_NAME(irs->ipsp),
34872 + irs->sa_len ? irs->sa : " (error)");
34873 + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
34874 +
34875 + skb->protocol = htons(ETH_P_IP);
34876 + skb->ip_summed = 0;
34877 +
34878 + ipsnext = irs->ipsp->ips_inext;
34879 + if(sysctl_ipsec_inbound_policy_check) {
34880 + if(ipsnext) {
34881 + if(
34882 + ipp->protocol != IPPROTO_AH
34883 + && ipp->protocol != IPPROTO_ESP
34884 +#ifdef CONFIG_KLIPS_IPCOMP
34885 + && ipp->protocol != IPPROTO_COMP
34886 + && (ipsnext->ips_said.proto != IPPROTO_COMP
34887 + || ipsnext->ips_inext)
34888 +#endif /* CONFIG_KLIPS_IPCOMP */
34889 + && ipp->protocol != IPPROTO_IPIP
34890 + && ipp->protocol != IPPROTO_ATT_HEARTBEAT /* heartbeats to AT&T SIG/GIG */
34891 + ) {
34892 + KLIPS_PRINT(debug_rcv,
34893 + "klips_debug:ipsec_rcv: "
34894 + "packet with incomplete policy dropped, last successful SA:%s.\n",
34895 + irs->sa_len ? irs->sa : " (error)");
34896 + if(irs->stats) {
34897 + irs->stats->rx_dropped++;
34898 + }
34899 + return IPSEC_RCV_FAILEDINBOUND;
34900 + }
34901 + KLIPS_PRINT(debug_rcv,
34902 + "klips_debug:ipsec_rcv: "
34903 + "SA:%s, Another IPSEC header to process.\n",
34904 + irs->sa_len ? irs->sa : " (error)");
34905 + } else {
34906 + KLIPS_PRINT(debug_rcv,
34907 + "klips_debug:ipsec_rcv: "
34908 + "No ips_inext from this SA:%s.\n",
34909 + irs->sa_len ? irs->sa : " (error)");
34910 + }
34911 + }
34912 +
34913 +#ifdef CONFIG_KLIPS_IPCOMP
34914 + /* update ipcomp ratio counters, even if no ipcomp packet is present */
34915 + if (ipsnext
34916 + && ipsnext->ips_said.proto == IPPROTO_COMP
34917 + && ipp->protocol != IPPROTO_COMP) {
34918 + ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
34919 + ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
34920 + }
34921 +#endif /* CONFIG_KLIPS_IPCOMP */
34922 +
34923 + irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
34924 + irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len;
34925 +
34926 + if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
34927 + irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
34928 + }
34929 + irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
34930 + irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
34931 +
34932 +#ifdef CONFIG_NETFILTER
34933 + if(proto == IPPROTO_ESP || proto == IPPROTO_AH) {
34934 + skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
34935 + | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
34936 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
34937 + "klips_debug:ipsec_rcv: "
34938 + "%s SA sets skb->nfmark=0x%x.\n",
34939 + proto == IPPROTO_ESP ? "ESP" : "AH",
34940 + (unsigned)skb->nfmark);
34941 + }
34942 +#endif /* CONFIG_NETFILTER */
34943 +
34944 + return IPSEC_RCV_OK;
34945 +}
34946 +
34947 +
34948 +/*
34949 + * core decapsulation loop for all protocols.
34950 + *
34951 + * the following things should be setup to enter this function.
34952 + *
34953 + * irs->stats == stats structure (or NULL)
34954 + * irs->ipp = IP header.
34955 + * irs->ipsp = NULL.
34956 + * irs->ilen = 0;
34957 + * irs->authlen = 0;
34958 + * irs->authfuncs = NULL;
34959 + * irs->skb = skb;
34960 + * skb->nh.iph = ipp;
34961 + * skb->h.raw = start of payload
34962 + *
34963 + */
34964 +int ipsec_rcv_decap(struct ipsec_rcv_state *irs)
34965 +{
34966 + struct ipsec_sa *ipsp = NULL;
34967 + struct ipsec_sa* ipsnext = NULL;
34968 + struct in_addr ipsaddr;
34969 + struct in_addr ipdaddr;
34970 + struct iphdr *ipp;
34971 + struct sk_buff *skb = NULL;
34972 +
34973 + /* begin decapsulating loop here */
34974 +
34975 + /*
34976 + The spinlock is to prevent any other process from
34977 + accessing or deleting the ipsec_sa hash table or any of the
34978 + ipsec_sa s while we are using and updating them.
34979 +
34980 + This is not optimal, but was relatively straightforward
34981 + at the time. A better way to do it has been planned for
34982 + more than a year, to lock the hash table and put reference
34983 + counts on each ipsec_sa instead. This is not likely to happen
34984 + in KLIPS1 unless a volunteer contributes it, but will be
34985 + designed into KLIPS2.
34986 + */
34987 + spin_lock(&tdb_lock);
34988 +
34989 + do {
34990 + int decap_stat;
34991 + struct xform_functions *proto_funcs;
34992 +
34993 + switch(irs->ipp->protocol) {
34994 + case IPPROTO_ESP:
34995 + proto_funcs = esp_xform_funcs;
34996 + break;
34997 +
34998 +#ifdef CONFIG_KLIPS_AH
34999 + case IPPROTO_AH:
35000 + proto_funcs = ah_xform_funcs;
35001 + break;
35002 +#endif /* !CONFIG_KLIPS_AH */
35003 +
35004 +#ifdef CONFIG_KLIPS_IPCOMP
35005 + case IPPROTO_COMP:
35006 + proto_funcs = ipcomp_xform_funcs;
35007 + break;
35008 +#endif /* !CONFIG_KLIPS_IPCOMP */
35009 + default:
35010 + if(irs->stats) {
35011 + irs->stats->rx_errors++;
35012 + }
35013 + decap_stat = IPSEC_RCV_BADPROTO;
35014 + goto rcvleave;
35015 + }
35016 +
35017 + decap_stat = ipsec_rcv_decap_once(irs, proto_funcs);
35018 +
35019 + if(decap_stat != IPSEC_RCV_OK) {
35020 + spin_unlock(&tdb_lock);
35021 + KLIPS_PRINT(debug_rcv,
35022 + "klips_debug:ipsec_rcv: decap_once failed: %d\n",
35023 + decap_stat);
35024 +
35025 + goto rcvleave;
35026 + }
35027 + /* end decapsulation loop here */
35028 + } while( (irs->ipp->protocol == IPPROTO_ESP )
35029 + || (irs->ipp->protocol == IPPROTO_AH )
35030 +#ifdef CONFIG_KLIPS_IPCOMP
35031 + || (irs->ipp->protocol == IPPROTO_COMP)
35032 +#endif /* CONFIG_KLIPS_IPCOMP */
35033 + );
35034 +
35035 + /* set up for decap loop */
35036 + ipp =irs->ipp;
35037 + ipsp =irs->ipsp;
35038 + ipsnext = ipsp->ips_inext;
35039 + skb = irs->skb;
35040 +
35041 + /* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
35042 + * then we can just skip it
35043 + */
35044 +#ifdef CONFIG_KLIPS_IPCOMP
35045 + if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) {
35046 + ipsp = ipsnext;
35047 + ipsnext = ipsp->ips_inext;
35048 + }
35049 +#endif /* CONFIG_KLIPS_IPCOMP */
35050 +
35051 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35052 + if ((irs->natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
35053 + /**
35054 + * NAT-Traversal and Transport Mode:
35055 + * we need to correct TCP/UDP checksum
35056 + *
35057 + * If we've got NAT-OA, we can fix checksum without recalculation.
35058 + */
35059 + __u32 natt_oa = ipsp->ips_natt_oa ?
35060 + ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
35061 + __u16 pkt_len = skb->tail - (unsigned char *)ipp;
35062 + __u16 data_len = pkt_len - (ipp->ihl << 2);
35063 +
35064 + switch (ipp->protocol) {
35065 + case IPPROTO_TCP:
35066 + if (data_len >= sizeof(struct tcphdr)) {
35067 + struct tcphdr *tcp = skb->h.th;
35068 + if (natt_oa) {
35069 + __u32 buff[2] = { ~natt_oa, ipp->saddr };
35070 + KLIPS_PRINT(debug_rcv,
35071 + "klips_debug:ipsec_rcv: "
35072 + "NAT-T & TRANSPORT: "
35073 + "fix TCP checksum using NAT-OA\n");
35074 + tcp->check = csum_fold(
35075 + csum_partial((unsigned char *)buff, sizeof(buff),
35076 + tcp->check^0xffff));
35077 + }
35078 + else {
35079 + KLIPS_PRINT(debug_rcv,
35080 + "klips_debug:ipsec_rcv: "
35081 + "NAT-T & TRANSPORT: recalc TCP checksum\n");
35082 + if (pkt_len > (ntohs(ipp->tot_len)))
35083 + data_len -= (pkt_len - ntohs(ipp->tot_len));
35084 + tcp->check = 0;
35085 + tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr,
35086 + data_len, IPPROTO_TCP,
35087 + csum_partial((unsigned char *)tcp, data_len, 0));
35088 + }
35089 + }
35090 + else {
35091 + KLIPS_PRINT(debug_rcv,
35092 + "klips_debug:ipsec_rcv: "
35093 + "NAT-T & TRANSPORT: can't fix TCP checksum\n");
35094 + }
35095 + break;
35096 + case IPPROTO_UDP:
35097 + if (data_len >= sizeof(struct udphdr)) {
35098 + struct udphdr *udp = skb->h.uh;
35099 + if (udp->check == 0) {
35100 + KLIPS_PRINT(debug_rcv,
35101 + "klips_debug:ipsec_rcv: "
35102 + "NAT-T & TRANSPORT: UDP checksum already 0\n");
35103 + }
35104 + else if (natt_oa) {
35105 + __u32 buff[2] = { ~natt_oa, ipp->saddr };
35106 + KLIPS_PRINT(debug_rcv,
35107 + "klips_debug:ipsec_rcv: "
35108 + "NAT-T & TRANSPORT: "
35109 + "fix UDP checksum using NAT-OA\n");
35110 +#ifdef DISABLE_UDP_CHECKSUM
35111 + udp->check=0
35112 + KLIPS_PRINT(debug_rcv,
35113 + "klips_debug:ipsec_rcv: "
35114 + "NAT-T & TRANSPORT: "
35115 + "UDP checksum using NAT-OA disabled at compile time\n");
35116 +#else
35117 + udp->check = csum_fold(
35118 + csum_partial((unsigned char *)buff, sizeof(buff),
35119 + udp->check^0xffff));
35120 +#endif
35121 + }
35122 + else {
35123 + KLIPS_PRINT(debug_rcv,
35124 + "klips_debug:ipsec_rcv: "
35125 + "NAT-T & TRANSPORT: zero UDP checksum\n");
35126 + udp->check = 0;
35127 + }
35128 + }
35129 + else {
35130 + KLIPS_PRINT(debug_rcv,
35131 + "klips_debug:ipsec_rcv: "
35132 + "NAT-T & TRANSPORT: can't fix UDP checksum\n");
35133 + }
35134 + break;
35135 + default:
35136 + KLIPS_PRINT(debug_rcv,
35137 + "klips_debug:ipsec_rcv: "
35138 + "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
35139 + break;
35140 + }
35141 + }
35142 +#endif
35143 +
35144 + /*
35145 + * XXX this needs to be locked from when it was first looked
35146 + * up in the decapsulation loop. Perhaps it is better to put
35147 + * the IPIP decap inside the loop.
35148 + */
35149 + if(ipsnext) {
35150 + ipsp = ipsnext;
35151 + irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
35152 + if((ipp->protocol != IPPROTO_IPIP) &&
35153 + (ipp->protocol != IPPROTO_ATT_HEARTBEAT)) { /* AT&T heartbeats to SIG/GIG */
35154 + spin_unlock(&tdb_lock);
35155 + KLIPS_PRINT(debug_rcv,
35156 + "klips_debug:ipsec_rcv: "
35157 + "SA:%s, Hey! How did this get through? Dropped.\n",
35158 + irs->sa_len ? irs->sa : " (error)");
35159 + if(irs->stats) {
35160 + irs->stats->rx_dropped++;
35161 + }
35162 + goto rcvleave;
35163 + }
35164 + if(sysctl_ipsec_inbound_policy_check) {
35165 + struct sockaddr_in *psin = (struct sockaddr_in*)(ipsp->ips_addr_s);
35166 + if((ipsnext = ipsp->ips_inext)) {
35167 + char sa2[SATOT_BUF];
35168 + size_t sa_len2;
35169 + sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2));
35170 + spin_unlock(&tdb_lock);
35171 + KLIPS_PRINT(debug_rcv,
35172 + "klips_debug:ipsec_rcv: "
35173 + "unexpected SA:%s after IPIP SA:%s\n",
35174 + sa_len2 ? sa2 : " (error)",
35175 + irs->sa_len ? irs->sa : " (error)");
35176 + if(irs->stats) {
35177 + irs->stats->rx_dropped++;
35178 + }
35179 + goto rcvleave;
35180 + }
35181 + if(ipp->saddr != psin->sin_addr.s_addr) {
35182 + spin_unlock(&tdb_lock);
35183 + KLIPS_PRINT(debug_rcv,
35184 + "klips_debug:ipsec_rcv: "
35185 + "SA:%s, src=%s(%08x) does match expected 0x%08x.\n",
35186 + irs->sa_len ? irs->sa : " (error)",
35187 + irs->ipsaddr_txt,
35188 + ipp->saddr, psin->sin_addr.s_addr);
35189 + if(irs->stats) {
35190 + irs->stats->rx_dropped++;
35191 + }
35192 + goto rcvleave;
35193 + }
35194 + }
35195 +
35196 + if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */
35197 + {
35198 + /*
35199 + * XXX this needs to be locked from when it was first looked
35200 + * up in the decapsulation loop. Perhaps it is better to put
35201 + * the IPIP decap inside the loop.
35202 + */
35203 + ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
35204 + ipsp->ips_life.ipl_bytes.ipl_last = skb->len;
35205 +
35206 + if(!ipsp->ips_life.ipl_usetime.ipl_count) {
35207 + ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
35208 + }
35209 + ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
35210 + ipsp->ips_life.ipl_packets.ipl_count += 1;
35211 +
35212 + if(skb->len < irs->iphlen) {
35213 + spin_unlock(&tdb_lock);
35214 + printk(KERN_WARNING "klips_debug:ipsec_rcv: "
35215 + "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n",
35216 + irs->iphlen,
35217 + (int)(skb->len));
35218 +
35219 + goto rcvleave;
35220 + }
35221 +
35222 + /*
35223 + * we need to pull up by size of IP header,
35224 + * options, but also by any UDP/ESP encap there might
35225 + * have been, and this deals with all cases.
35226 + */
35227 + skb_pull(skb, (skb->h.raw - skb->nh.raw));
35228 +
35229 + /* new L3 header is where L4 payload was */
35230 + skb->nh.raw = skb->h.raw;
35231 +
35232 + /* now setup new L4 payload location */
35233 + ipp = (struct iphdr *)skb->nh.raw;
35234 + skb->h.raw = skb->nh.raw + (ipp->ihl << 2);
35235 +
35236 +
35237 + /* remove any saved options that we might have,
35238 + * since we have a new IP header.
35239 + */
35240 + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
35241 +
35242 +#if 0
35243 + KLIPS_PRINT(debug_rcv, "csum: %d\n", ip_fast_csum((u8 *)ipp, ipp->ihl));
35244 +#endif
35245 +
35246 + /* re-do any strings for debugging */
35247 + ipsaddr.s_addr = ipp->saddr;
35248 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
35249 + ipdaddr.s_addr = ipp->daddr;
35250 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
35251 +
35252 + skb->protocol = htons(ETH_P_IP);
35253 + skb->ip_summed = 0;
35254 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35255 + "klips_debug:ipsec_rcv: "
35256 + "IPIP tunnel stripped.\n");
35257 + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
35258 + }
35259 +
35260 + if(sysctl_ipsec_inbound_policy_check
35261 + /*
35262 + Note: "xor" (^) logically replaces "not equal"
35263 + (!=) and "bitwise or" (|) logically replaces
35264 + "boolean or" (||). This is done to speed up
35265 + execution by doing only bitwise operations and
35266 + no branch operations
35267 + */
35268 + && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
35269 + ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
35270 + | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
35271 + ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
35272 + {
35273 + char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
35274 +
35275 + subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
35276 + ipsp->ips_mask_s.u.v4.sin_addr,
35277 + 0, sflow_txt, sizeof(sflow_txt));
35278 + subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
35279 + ipsp->ips_mask_d.u.v4.sin_addr,
35280 + 0, dflow_txt, sizeof(dflow_txt));
35281 + spin_unlock(&tdb_lock);
35282 + KLIPS_PRINT(debug_rcv,
35283 + "klips_debug:ipsec_rcv: "
35284 + "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
35285 + irs->sa_len ? irs->sa : " (error)",
35286 + sflow_txt,
35287 + dflow_txt,
35288 + irs->ipsaddr_txt,
35289 + irs->ipdaddr_txt);
35290 + if(irs->stats) {
35291 + irs->stats->rx_dropped++;
35292 + }
35293 + goto rcvleave;
35294 + }
35295 +#ifdef CONFIG_NETFILTER
35296 + skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
35297 + | IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
35298 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35299 + "klips_debug:ipsec_rcv: "
35300 + "IPIP SA sets skb->nfmark=0x%x.\n",
35301 + (unsigned)skb->nfmark);
35302 +#endif /* CONFIG_NETFILTER */
35303 + }
35304 +
35305 + spin_unlock(&tdb_lock);
35306 +
35307 + if(irs->stats) {
35308 + irs->stats->rx_bytes += skb->len;
35309 + }
35310 + if(skb->dst) {
35311 + dst_release(skb->dst);
35312 + skb->dst = NULL;
35313 + }
35314 + skb->pkt_type = PACKET_HOST;
35315 + if(irs->hard_header_len &&
35316 + (skb->mac.raw != (skb->nh.raw - irs->hard_header_len)) &&
35317 + (irs->hard_header_len <= skb_headroom(skb))) {
35318 + /* copy back original MAC header */
35319 + memmove(skb->nh.raw - irs->hard_header_len,
35320 + skb->mac.raw, irs->hard_header_len);
35321 + skb->mac.raw = skb->nh.raw - irs->hard_header_len;
35322 + }
35323 +
35324 +#ifdef CONFIG_KLIPS_IPCOMP
35325 + if(ipp->protocol == IPPROTO_COMP) {
35326 + unsigned int flags = 0;
35327 +
35328 + if(sysctl_ipsec_inbound_policy_check) {
35329 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35330 + "klips_debug:ipsec_rcv: "
35331 + "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
35332 + if (irs->stats) {
35333 + irs->stats->rx_errors++;
35334 + }
35335 + goto rcvleave;
35336 + }
35337 + /*
35338 + XXX need a ipsec_sa for updating ratio counters but it is not
35339 + following policy anyways so it is not a priority
35340 + */
35341 + skb = skb_decompress(skb, NULL, &flags);
35342 + if (!skb || flags) {
35343 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35344 + "klips_debug:ipsec_rcv: "
35345 + "skb_decompress() returned error flags: %d, dropped.\n",
35346 + flags);
35347 + if (irs->stats) {
35348 + irs->stats->rx_errors++;
35349 + }
35350 + goto rcvleave;
35351 + }
35352 + }
35353 +#endif /* CONFIG_KLIPS_IPCOMP */
35354 +
35355 + /*
35356 + * make sure that data now starts at IP header, since we are going
35357 + * to pass this back to ip_input (aka netif_rx). Rules for what the
35358 + * pointers wind up a different for 2.6 vs 2.4, so we just fudge it here.
35359 + */
35360 +#ifdef NET_26
35361 + skb->data = skb_push(skb, skb->h.raw - skb->nh.raw);
35362 +#else
35363 + skb->data = skb->nh.raw;
35364 + {
35365 + struct iphdr *iph = skb->nh.iph;
35366 + int len = ntohs(iph->tot_len);
35367 + skb->len = len;
35368 + }
35369 +#endif
35370 +
35371 +#ifdef SKB_RESET_NFCT
35372 + nf_conntrack_put(skb->nfct);
35373 + skb->nfct = NULL;
35374 +#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
35375 + skb->nf_debug = 0;
35376 +#endif /* CONFIG_NETFILTER_DEBUG */
35377 +#endif /* SKB_RESET_NFCT */
35378 + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
35379 + "klips_debug:ipsec_rcv: "
35380 + "netif_rx() called.\n");
35381 + netif_rx(skb);
35382 + skb=NULL;
35383 +
35384 + rcvleave:
35385 + if(skb) {
35386 + ipsec_kfree_skb(skb);
35387 + }
35388 +
35389 + /* KLIPS_DEC_USE; Artifact from refactor? bug # 454 */
35390 + return(0);
35391 +}
35392 +
35393 +struct sk_buff *ipsec_rcv_unclone(struct sk_buff *skb,
35394 + struct ipsec_rcv_state *irs)
35395 +{
35396 + /* if skb was cloned (most likely due to a packet sniffer such as
35397 + tcpdump being momentarily attached to the interface), make
35398 + a copy of our own to modify */
35399 + if(skb_cloned(skb)) {
35400 + /* include any mac header while copying.. */
35401 + if(skb_headroom(skb) < irs->hard_header_len) {
35402 + printk(KERN_WARNING "klips_error:ipsec_rcv: "
35403 + "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
35404 + irs->hard_header_len,
35405 + skb_headroom(skb));
35406 + goto rcvleave;
35407 + }
35408 + skb_push(skb, irs->hard_header_len);
35409 + if
35410 +#ifdef SKB_COW_NEW
35411 + (skb_cow(skb, skb_headroom(skb)) != 0)
35412 +#else /* SKB_COW_NEW */
35413 + ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
35414 +#endif /* SKB_COW_NEW */
35415 + {
35416 + goto rcvleave;
35417 + }
35418 + if(skb->len < irs->hard_header_len) {
35419 + printk(KERN_WARNING "klips_error:ipsec_rcv: "
35420 + "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
35421 + irs->hard_header_len,
35422 + skb->len);
35423 + goto rcvleave;
35424 + }
35425 + skb_pull(skb, irs->hard_header_len);
35426 + }
35427 + return skb;
35428 +
35429 +rcvleave:
35430 + ipsec_kfree_skb(skb);
35431 + return NULL;
35432 +}
35433 +
35434 +
35435 +#if !defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL)
35436 +/*
35437 + * decapsulate a UDP encapsulated ESP packet
35438 + */
35439 +struct sk_buff *ipsec_rcv_natt_decap(struct sk_buff *skb
35440 + , struct ipsec_rcv_state *irs
35441 + , int *udp_decap_ret_p)
35442 +{
35443 + *udp_decap_ret_p = 0;
35444 + if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) {
35445 + /**
35446 + * Packet comes from udp_queue_rcv_skb so it is already defrag,
35447 + * checksum verified, ... (ie safe to use)
35448 + *
35449 + * If the packet is not for us, return -1 and udp_queue_rcv_skb
35450 + * will continue to handle it (do not kfree skb !!).
35451 + */
35452 +
35453 +#ifndef UDP_OPT_IN_SOCK
35454 + struct udp_opt {
35455 + __u32 esp_in_udp;
35456 + };
35457 + struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);
35458 +#else
35459 + struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp);
35460 +#endif
35461 +
35462 + struct iphdr *ip = (struct iphdr *)skb->nh.iph;
35463 + struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
35464 + __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
35465 + __u32 *udpdata32 = (__u32 *)udpdata;
35466 +
35467 + irs->natt_sport = ntohs(udp->source);
35468 + irs->natt_dport = ntohs(udp->dest);
35469 +
35470 + KLIPS_PRINT(debug_rcv,
35471 + "klips_debug:ipsec_rcv: "
35472 + "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
35473 + tp->esp_in_udp);
35474 + KLIPS_IP_PRINT(debug_rcv, ip);
35475 +
35476 + if (udpdata < skb->tail) {
35477 + unsigned int len = skb->tail - udpdata;
35478 + if ((len==1) && (udpdata[0]==0xff)) {
35479 + KLIPS_PRINT(debug_rcv,
35480 + "klips_debug:ipsec_rcv: "
35481 + /* not IPv6 compliant message */
35482 + "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
35483 + *udp_decap_ret_p = 0;
35484 + return NULL;
35485 + }
35486 + else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
35487 + (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&
35488 + (udpdata32[0]==0) && (udpdata32[1]==0) ) {
35489 + /* ESP Packet with Non-IKE header */
35490 + KLIPS_PRINT(debug_rcv,
35491 + "klips_debug:ipsec_rcv: "
35492 + "ESPinUDP pkt with Non-IKE - spi=0x%x\n",
35493 + ntohl(udpdata32[2]));
35494 + irs->natt_type = ESPINUDP_WITH_NON_IKE;
35495 + irs->natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
35496 + }
35497 + else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
35498 + (len > sizeof(struct esphdr)) &&
35499 + (udpdata32[0]!=0) ) {
35500 + /* ESP Packet without Non-ESP header */
35501 + irs->natt_type = ESPINUDP_WITH_NON_ESP;
35502 + irs->natt_len = sizeof(struct udphdr);
35503 + KLIPS_PRINT(debug_rcv,
35504 + "klips_debug:ipsec_rcv: "
35505 + "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
35506 + ntohl(udpdata32[0]));
35507 + }
35508 + else {
35509 + KLIPS_PRINT(debug_rcv,
35510 + "klips_debug:ipsec_rcv: "
35511 + "IKE packet - not handled here\n");
35512 + *udp_decap_ret_p = -1;
35513 + return NULL;
35514 + }
35515 + }
35516 + else {
35517 + return NULL;
35518 + }
35519 + }
35520 + return skb;
35521 +}
35522 +#endif
35523 +
35524 +
35525 +int
35526 +ipsec_rcv(struct sk_buff *skb
35527 +#ifndef PROTO_HANDLER_SINGLE_PARM
35528 + unsigned short xlen
35529 +#endif /* PROTO_HANDLER_SINGLE_PARM */
35530 + )
35531 +{
35532 +#ifdef CONFIG_KLIPS_DEBUG
35533 + struct net_device *dev = skb->dev;
35534 +#endif /* CONFIG_KLIPS_DEBUG */
35535 + unsigned char protoc;
35536 + struct net_device_stats *stats = NULL; /* This device's statistics */
35537 + struct net_device *ipsecdev = NULL, *prvdev;
35538 + struct ipsecpriv *prv;
35539 + struct ipsec_rcv_state nirs, *irs = &nirs;
35540 + struct iphdr *ipp;
35541 + char name[9];
35542 + int i;
35543 +
35544 + /* Don't unlink in the middle of a turnaround */
35545 + KLIPS_INC_USE;
35546 +
35547 + memset(&nirs, 0, sizeof(struct ipsec_rcv_state));
35548 +
35549 + if (skb == NULL) {
35550 + KLIPS_PRINT(debug_rcv,
35551 + "klips_debug:ipsec_rcv: "
35552 + "NULL skb passed in.\n");
35553 + goto rcvleave;
35554 + }
35555 +
35556 + if (skb->data == NULL) {
35557 + KLIPS_PRINT(debug_rcv,
35558 + "klips_debug:ipsec_rcv: "
35559 + "NULL skb->data passed in, packet is bogus, dropping.\n");
35560 + goto rcvleave;
35561 + }
35562 +
35563 +#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35564 + {
35565 + /* NET_26 NAT-T is handled by seperate function */
35566 + struct sk_buff *nskb;
35567 + int udp_decap_ret = 0;
35568 +
35569 + nskb = ipsec_rcv_natt_decap(skb, irs, &udp_decap_ret);
35570 + if(nskb == NULL) {
35571 + /* return with non-zero, because UDP.c code
35572 + * need to send it upstream.
35573 + */
35574 + if(skb && udp_decap_ret == 0) {
35575 + ipsec_kfree_skb(skb);
35576 + }
35577 + KLIPS_DEC_USE;
35578 + return(udp_decap_ret);
35579 + }
35580 + skb = nskb;
35581 + }
35582 +#endif /* NAT_T */
35583 +
35584 + /* dev->hard_header_len is unreliable and should not be used */
35585 + irs->hard_header_len = skb->mac.raw ? (skb->nh.raw - skb->mac.raw) : 0;
35586 + if((irs->hard_header_len < 0) || (irs->hard_header_len > skb_headroom(skb)))
35587 + irs->hard_header_len = 0;
35588 +
35589 + skb = ipsec_rcv_unclone(skb, irs);
35590 + if(skb == NULL) {
35591 + goto rcvleave;
35592 + }
35593 +
35594 +#if IP_FRAGMENT_LINEARIZE
35595 + /* In Linux 2.4.4, we may have to reassemble fragments. They are
35596 + not assembled automatically to save TCP from having to copy
35597 + twice.
35598 + */
35599 + if (skb_is_nonlinear(skb)) {
35600 +#ifdef HAVE_NEW_SKB_LINEARIZE
35601 + if (skb_linearize_cow(skb) != 0)
35602 +#else
35603 + if (skb_linearize(skb, GFP_ATOMIC) != 0)
35604 +#endif
35605 + {
35606 + goto rcvleave;
35607 + }
35608 + }
35609 +#endif /* IP_FRAGMENT_LINEARIZE */
35610 +
35611 +#if defined(CONFIG_IPSEC_NAT_TRAVERSAL) && !defined(NET_26)
35612 + if (irs->natt_len) {
35613 + /**
35614 + * Now, we are sure packet is ESPinUDP, and we have a private
35615 + * copy that has been linearized, remove natt_len bytes
35616 + * from packet and modify protocol to ESP.
35617 + */
35618 + if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph)
35619 + && ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head))
35620 + {
35621 + unsigned int _len = (unsigned char *)skb->data -
35622 + (unsigned char *)skb->nh.iph;
35623 + KLIPS_PRINT(debug_rcv,
35624 + "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
35625 + _len);
35626 + skb_push(skb, _len);
35627 + }
35628 + KLIPS_PRINT(debug_rcv,
35629 + "klips_debug:ipsec_rcv: "
35630 + "removing %d bytes from ESPinUDP packet\n", irs->natt_len);
35631 + ipp = skb->nh.iph;
35632 + irs->iphlen = ipp->ihl << 2;
35633 + ipp->tot_len = htons(ntohs(ipp->tot_len) - irs->natt_len);
35634 + if (skb->len < irs->iphlen + irs->natt_len) {
35635 + printk(KERN_WARNING
35636 + "klips_error:ipsec_rcv: "
35637 + "ESPinUDP packet is too small (%d < %d+%d). "
35638 + "This should never happen, please report.\n",
35639 + (int)(skb->len), irs->iphlen, irs->natt_len);
35640 + goto rcvleave;
35641 + }
35642 +
35643 + /* advance payload pointer to point past the UDP header */
35644 + skb->h.raw = skb->h.raw + irs->natt_len;
35645 +
35646 + /* modify protocol */
35647 + ipp->protocol = IPPROTO_ESP;
35648 +
35649 + skb->sk = NULL;
35650 +
35651 + KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);
35652 + }
35653 +#endif
35654 +
35655 + ipp = skb->nh.iph;
35656 +
35657 + {
35658 + struct in_addr ipsaddr;
35659 + struct in_addr ipdaddr;
35660 +
35661 + ipsaddr.s_addr = ipp->saddr;
35662 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt
35663 + , sizeof(irs->ipsaddr_txt));
35664 + ipdaddr.s_addr = ipp->daddr;
35665 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt
35666 + , sizeof(irs->ipdaddr_txt));
35667 + }
35668 +
35669 + irs->iphlen = ipp->ihl << 2;
35670 +
35671 + KLIPS_PRINT(debug_rcv,
35672 + "klips_debug:ipsec_rcv: "
35673 + "<<< Info -- ");
35674 + KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
35675 + skb->dev->name ? skb->dev->name : "NULL");
35676 + KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
35677 + dev->name ? dev->name : "NULL");
35678 + KLIPS_PRINTMORE(debug_rcv, "\n");
35679 +
35680 + KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
35681 + "klips_debug:ipsec_rcv: "
35682 + "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
35683 + skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
35684 + dev ? (dev->name ? dev->name : "NULL") : "NULL");
35685 +
35686 + protoc = ipp->protocol;
35687 +#ifndef NET_21
35688 + if((!protocol) || (protocol->protocol != protoc)) {
35689 + KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35690 + "klips_debug:ipsec_rcv: "
35691 + "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
35692 + }
35693 +#endif /* !NET_21 */
35694 +
35695 + if( (protoc != IPPROTO_AH) &&
35696 +#ifdef CONFIG_KLIPS_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
35697 + (protoc != IPPROTO_COMP) &&
35698 +#endif /* CONFIG_KLIPS_IPCOMP */
35699 + (protoc != IPPROTO_ESP) ) {
35700 + KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
35701 + "klips_debug:ipsec_rcv: Why the hell is someone "
35702 + "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
35703 + protoc);
35704 + goto rcvleave;
35705 + }
35706 +
35707 + if(skb->dev) {
35708 + for(i = 0; i < IPSEC_NUM_IF; i++) {
35709 + sprintf(name, IPSEC_DEV_FORMAT, i);
35710 + if(!strcmp(name, skb->dev->name)) {
35711 + prv = (struct ipsecpriv *)(skb->dev->priv);
35712 + if(prv) {
35713 + stats = (struct net_device_stats *) &(prv->mystats);
35714 + }
35715 + ipsecdev = skb->dev;
35716 + KLIPS_PRINT(debug_rcv,
35717 + "klips_debug:ipsec_rcv: "
35718 + "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
35719 + break;
35720 + }
35721 + if((ipsecdev = __ipsec_dev_get(name)) == NULL) {
35722 + KLIPS_PRINT(debug_rcv,
35723 + "klips_error:ipsec_rcv: "
35724 + "device %s does not exist\n",
35725 + name);
35726 + }
35727 + prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
35728 + prvdev = prv ? (struct net_device *)(prv->dev) : NULL;
35729 +
35730 +#if 0
35731 + KLIPS_PRINT(debug_rcv && prvdev,
35732 + "klips_debug:ipsec_rcv: "
35733 + "physical device for device %s is %s\n",
35734 + name,
35735 + prvdev->name);
35736 +#endif
35737 + if(prvdev && skb->dev &&
35738 + !strcmp(prvdev->name, skb->dev->name)) {
35739 + stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
35740 + skb->dev = ipsecdev;
35741 + KLIPS_PRINT(debug_rcv && prvdev,
35742 + "klips_debug:ipsec_rcv: "
35743 + "assigning packet ownership to virtual device %s from physical device %s.\n",
35744 + name, prvdev->name);
35745 + if(stats) {
35746 + stats->rx_packets++;
35747 + }
35748 + break;
35749 + }
35750 + }
35751 + } else {
35752 + KLIPS_PRINT(debug_rcv,
35753 + "klips_debug:ipsec_rcv: "
35754 + "device supplied with skb is NULL\n");
35755 + }
35756 +
35757 + if(stats == NULL) {
35758 + KLIPS_PRINT((debug_rcv),
35759 + "klips_error:ipsec_rcv: "
35760 + "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",
35761 + skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
35762 + }
35763 +
35764 + KLIPS_IP_PRINT(debug_rcv, ipp);
35765 +
35766 + /* set up for decap loop */
35767 + irs->stats= stats;
35768 + irs->ipp = ipp;
35769 + irs->ipsp = NULL;
35770 + irs->ilen = 0;
35771 + irs->authlen=0;
35772 + irs->authfuncs=NULL;
35773 + irs->skb = skb;
35774 +
35775 + ipsec_rcv_decap(irs);
35776 + KLIPS_DEC_USE;
35777 + return(0);
35778 +
35779 + rcvleave:
35780 + if(skb) {
35781 + ipsec_kfree_skb(skb);
35782 + }
35783 + KLIPS_DEC_USE;
35784 + return(0);
35785 +
35786 +}
35787 +
35788 +#ifdef NET_26
35789 +/*
35790 + * this entry point is not a protocol entry point, so the entry
35791 + * is a bit different.
35792 + *
35793 + * skb->iph->tot_len has been byte-swapped, and reduced by the size of
35794 + * the IP header (and options).
35795 + *
35796 + * skb->h.raw has been pulled up the ESP header.
35797 + *
35798 + * skb->iph->protocol = 50 IPPROTO_ESP;
35799 + *
35800 + */
35801 +int klips26_rcv_encap(struct sk_buff *skb, __u16 encap_type)
35802 +{
35803 + struct ipsec_rcv_state nirs, *irs = &nirs;
35804 + struct iphdr *ipp;
35805 +
35806 + /* Don't unlink in the middle of a turnaround */
35807 + KLIPS_INC_USE;
35808 +
35809 + memset(irs, 0, sizeof(*irs));
35810 +
35811 + /* XXX fudge it so that all nat-t stuff comes from ipsec0 */
35812 + /* eventually, the SA itself will determine which device
35813 + * it comes from
35814 + */
35815 + {
35816 + skb->dev = ipsec_get_device(0);
35817 + }
35818 +
35819 + /* set up for decap loop */
35820 + irs->hard_header_len = skb->dev->hard_header_len;
35821 +
35822 + skb = ipsec_rcv_unclone(skb, irs);
35823 +
35824 +#if IP_FRAGMENT_LINEARIZE
35825 + /* In Linux 2.4.4, we may have to reassemble fragments. They are
35826 + not assembled automatically to save TCP from having to copy
35827 + twice.
35828 + */
35829 + if (skb_is_nonlinear(skb)) {
35830 +#ifdef HAVE_NEW_SKB_LINEARIZE
35831 + if (skb_linearize_cow(skb) != 0)
35832 +#else
35833 + if (skb_linearize(skb, GFP_ATOMIC) != 0)
35834 +#endif
35835 + {
35836 + goto rcvleave;
35837 + }
35838 + }
35839 +#endif /* IP_FRAGMENT_LINEARIZE */
35840 +
35841 + ipp = skb->nh.iph;
35842 +
35843 + {
35844 + struct in_addr ipsaddr;
35845 + struct in_addr ipdaddr;
35846 +
35847 + ipsaddr.s_addr = ipp->saddr;
35848 + addrtoa(ipsaddr, 0, irs->ipsaddr_txt
35849 + , sizeof(irs->ipsaddr_txt));
35850 + ipdaddr.s_addr = ipp->daddr;
35851 + addrtoa(ipdaddr, 0, irs->ipdaddr_txt
35852 + , sizeof(irs->ipdaddr_txt));
35853 + }
35854 +
35855 + irs->iphlen = ipp->ihl << 2;
35856 +
35857 + KLIPS_IP_PRINT(debug_rcv, ipp);
35858 +
35859 + irs->stats= NULL;
35860 + irs->ipp = ipp;
35861 + irs->ipsp = NULL;
35862 + irs->ilen = 0;
35863 + irs->authlen=0;
35864 + irs->authfuncs=NULL;
35865 + irs->skb = skb;
35866 +
35867 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
35868 + switch(encap_type) {
35869 + case UDP_ENCAP_ESPINUDP:
35870 + irs->natt_type = ESPINUDP_WITH_NON_ESP;
35871 + break;
35872 +
35873 + case UDP_ENCAP_ESPINUDP_NON_IKE:
35874 + irs->natt_type = ESPINUDP_WITH_NON_IKE;
35875 + break;
35876 +
35877 + default:
35878 + if(printk_ratelimit()) {
35879 + printk(KERN_INFO "KLIPS received unknown UDP-ESP encap type %u\n",
35880 + encap_type);
35881 + }
35882 + return -1;
35883 + }
35884 +
35885 +#endif
35886 + ipsec_rcv_decap(irs);
35887 + KLIPS_DEC_USE;
35888 + return 0;
35889 +
35890 +rcvleave:
35891 + if(skb) {
35892 + ipsec_kfree_skb(skb);
35893 + }
35894 + KLIPS_DEC_USE;
35895 + return 0;
35896 +}
35897 +#endif
35898 +
35899 +
35900 +/*
35901 + * $Log: ipsec_rcv.c,v $
35902 + * Revision 1.171.2.11 2007/04/28 20:46:40 paul
35903 + * Added compile time switch for -DDISABLE_UDP_CHECKSUM that seems to be
35904 + * breaking IPsec+NAT+Transport mode with NAT-OA. Enabled this per default
35905 + * via Makefile.inc's USERCOMPILE flags.
35906 + *
35907 + * Revision 1.171.2.10 2006/10/06 21:39:26 paul
35908 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
35909 + * set. This is defined through autoconf.h which is included through the
35910 + * linux kernel build macros.
35911 + *
35912 + * Revision 1.171.2.9 2006/07/30 02:09:33 paul
35913 + * Author: Bart Trojanowski <bart@xelerance.com>
35914 + * This fixes a NATT+ESP bug in rcv path.
35915 + *
35916 + * We only want to test NATT policy on the ESP packet. Doing so on the
35917 + * bundled SA breaks because the next layer does not know anything about
35918 + * NATT.
35919 + *
35920 + * Fix just puts an if(proto == IPPROTO_ESP) around the NATT policy check.
35921 + *
35922 + * Revision 1.171.2.8 2006/07/29 05:03:04 paul
35923 + * Added check for new version of skb_linearize that only takes 1 argument,
35924 + * for 2.6.18+ kernels.
35925 + *
35926 + * Revision 1.171.2.7 2006/04/20 16:33:07 mcr
35927 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
35928 + * Fix in-kernel module compilation. Sub-makefiles do not work.
35929 + *
35930 + * Revision 1.171.2.6 2005/12/07 06:07:04 paul
35931 + * comment out KLIPS_DEC_USE in ipsec_rcv_decap. Likely an artifact from
35932 + * refactoring. http://bugs.xelerance.com/view.php?id=454
35933 + *
35934 + * Revision 1.171.2.5 2005/10/21 02:22:29 mcr
35935 + * pull up of another try at 2.4.x kernel fix
35936 + *
35937 + * Revision 1.171.2.4 2005/10/21 01:39:56 mcr
35938 + * nat-t fix is 2.4/2.6 specific
35939 + *
35940 + * Revision 1.178 2005/10/21 02:19:34 mcr
35941 + * on 2.4 systems, we have to fix up the length as well.
35942 + *
35943 + * Revision 1.177 2005/10/21 00:18:31 mcr
35944 + * nat-t fix is 2.4 specific.
35945 + *
35946 + * Revision 1.176 2005/10/20 21:06:11 mcr
35947 + * possible fix for nat-t problem on 2.4 kernels.
35948 + *
35949 + * Revision 1.175 2005/10/13 02:49:24 mcr
35950 + * tested UDP-encapsulated ESP packets that were not actually ESP,
35951 + * (but IKE) were being eaten.
35952 + *
35953 + * Revision 1.174 2005/10/13 01:25:22 mcr
35954 + * UDP-encapsulated ESP packets that were not actually ESP,
35955 + * (but IKE) were being eaten.
35956 + *
35957 + * Revision 1.173 2005/08/31 23:26:11 mcr
35958 + * fixes for 2.6.13
35959 + *
35960 + * Revision 1.172 2005/08/05 08:44:54 mcr
35961 + * ipsec_kern24.h (compat code for 2.4) must be include
35962 + * explicitely now.
35963 + *
35964 + * Revision 1.171 2005/07/08 23:56:06 ken
35965 + * #ifdef
35966 + *
35967 + * Revision 1.170 2005/07/08 23:50:05 ken
35968 + * Don't attempt to decapsulate if NAT-T isn't available in the code
35969 + *
35970 + * Revision 1.169 2005/06/06 00:27:31 mcr
35971 + * fix for making tcpdump (packet capture) work correctly for
35972 + * nat-t received packets.
35973 + *
35974 + * Revision 1.168 2005/06/04 16:06:06 mcr
35975 + * better patch for nat-t rcv-device code.
35976 + *
35977 + * Revision 1.167 2005/06/03 17:04:46 mcr
35978 + * nat-t packets are forced to arrive from ipsec0.
35979 + *
35980 + * Revision 1.166 2005/04/29 05:10:22 mcr
35981 + * removed from extraenous includes to make unit testing easier.
35982 + *
35983 + * Revision 1.165 2005/04/20 17:11:32 mcr
35984 + * fixed to compile on 2.4.
35985 + *
35986 + * Revision 1.164 2005/04/18 03:09:50 ken
35987 + * Fix typo
35988 + *
35989 + * Revision 1.163 2005/04/17 05:32:58 mcr
35990 + * remove extraneous debugging
35991 + * make sure to return success from klips26_encap_rcv().
35992 + *
35993 + * Revision 1.162 2005/04/17 04:37:01 mcr
35994 + * make sure that irs->ipp is still set.
35995 + *
35996 + * Revision 1.161 2005/04/17 03:51:52 mcr
35997 + * removed old comment about removed code.
35998 + * added translation from udp.c/2.6 to KLIPS NAT-ESP naming.
35999 + * comment about check for origin address/port for incoming NAT-ESP packets.
36000 + *
36001 + * Revision 1.160 2005/04/15 19:55:58 mcr
36002 + * adjustments to use proper skb fields for data.
36003 + *
36004 + * Revision 1.159 2005/04/10 22:58:20 mcr
36005 + * refactoring of receive functions to make it easier to
36006 + * call the ESP decap.
36007 + *
36008 + * Revision 1.158 2005/04/08 18:27:53 mcr
36009 + * refactored ipsec_rcv() into ipsec_rcv() and ipsec_rcv_decap().
36010 + *
36011 + * Revision 1.157 2004/12/28 23:13:09 mcr
36012 + * use consistent CONFIG_IPSEC_NAT_TRAVERSAL.
36013 + *
36014 + * Revision 1.156 2004/12/03 21:34:51 mcr
36015 + * mistype of KLIPS_USE_COUNT -> KLIPS_INC_USE;
36016 + *
36017 + * Revision 1.155 2004/12/03 21:25:57 mcr
36018 + * compile time fixes for running on 2.6.
36019 + * still experimental.
36020 + *
36021 + * Revision 1.154 2004/09/08 17:21:36 ken
36022 + * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
36023 + *
36024 + * Revision 1.153 2004/08/22 20:10:00 mcr
36025 + * removed check for incorrect setting of NET_26.
36026 + *
36027 + * Revision 1.152 2004/08/21 15:22:39 mcr
36028 + * added #defines for ATT heartbeat.
36029 + *
36030 + * Revision 1.151 2004/08/21 02:16:32 ken
36031 + * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support
36032 + *
36033 + * Revision 1.150 2004/08/21 00:44:48 mcr
36034 + * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
36035 + *
36036 + * Revision 1.149 2004/08/20 21:45:45 mcr
36037 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
36038 + * be 26sec compatible. But, some defines where changed.
36039 + *
36040 + * Revision 1.148 2004/08/17 03:27:23 mcr
36041 + * klips 2.6 edits.
36042 + *
36043 + * Revision 1.147 2004/08/05 23:29:27 mcr
36044 + * fixed nesting of #ifdef vs {} in ipsec_rcv().
36045 + *
36046 + * Revision 1.146 2004/08/04 15:57:07 mcr
36047 + * moved des .h files to include/des/ *
36048 + * included 2.6 protocol specific things
36049 + * started at NAT-T support, but it will require a kernel patch.
36050 + *
36051 + * Revision 1.145 2004/08/03 18:19:08 mcr
36052 + * in 2.6, use "net_device" instead of #define device->net_device.
36053 + * this probably breaks 2.0 compiles.
36054 + *
36055 + * Revision 1.144 2004/07/10 19:11:18 mcr
36056 + * CONFIG_IPSEC -> CONFIG_KLIPS.
36057 + *
36058 + * Revision 1.143 2004/05/10 22:27:00 mcr
36059 + * fix for ESP-3DES-noauth test case.
36060 + *
36061 + * Revision 1.142 2004/05/10 22:25:57 mcr
36062 + * reformat of calls to ipsec_lifetime_check().
36063 + *
36064 + * Revision 1.141 2004/04/06 02:49:26 mcr
36065 + * pullup of algo code from alg-branch.
36066 + *
36067 + * Revision 1.140 2004/02/03 03:12:53 mcr
36068 + * removed erroneously, double patched code.
36069 + *
36070 + * Revision 1.139 2004/01/05 23:21:29 mcr
36071 + * initialize sin_family in ipsec_rcv.c
36072 + *
36073 + * Revision 1.138 2003/12/24 19:46:52 mcr
36074 + * if sock.h patch has not been applied, then define appropriate
36075 + * structure so we can use it. This is serious inferior, and
36076 + * depends upon the concept that the structure in question is
36077 + * smaller than the other members of that union.
36078 + * getting rid of differing methods is a better solution.
36079 + *
36080 + * Revision 1.137 2003/12/22 19:40:57 mcr
36081 + * NAT-T patches 0.6c.
36082 + *
36083 + * Revision 1.136 2003/12/15 18:13:12 mcr
36084 + * when compiling with NAT traversal, don't assume that the
36085 + * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
36086 + * is set.
36087 + *
36088 + * Revision 1.135 2003/12/13 19:10:21 mcr
36089 + * refactored rcv and xmit code - same as FS 2.05.
36090 + *
36091 + * Revision 1.134.2.1 2003/12/22 15:25:52 jjo
36092 + * Merged algo-0.8.1-rc11-test1 into alg-branch
36093 + *
36094 + * Revision 1.134 2003/12/10 01:14:27 mcr
36095 + * NAT-traversal patches to KLIPS.
36096 + *
36097 + * Revision 1.133 2003/10/31 02:27:55 mcr
36098 + * pulled up port-selector patches and sa_id elimination.
36099 + *
36100 + * Revision 1.132.2.1 2003/10/29 01:30:41 mcr
36101 + * elimited "struct sa_id".
36102 + *
36103 + * Revision 1.132 2003/09/02 19:51:48 mcr
36104 + * fixes for PR#252.
36105 + *
36106 + * Revision 1.131 2003/07/31 22:47:16 mcr
36107 + * preliminary (untested by FS-team) 2.5 patches.
36108 + *
36109 + * Revision 1.130 2003/04/03 17:38:25 rgb
36110 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
36111 + * Clarified logic for non-connected devices.
36112 + *
36113 + * Revision 1.129 2003/02/06 02:21:34 rgb
36114 + *
36115 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
36116 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
36117 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
36118 + *
36119 + * Revision 1.128 2002/12/13 20:58:03 rgb
36120 + * Relegated MCR's recent "_dmp" routine to debug_verbose.
36121 + * Cleaned up printing of source and destination addresses in debug output.
36122 + *
36123 + * Revision 1.127 2002/12/04 16:00:16 rgb
36124 + *
36125 + * Fixed AH decapsulation pointer update bug and added some comments and
36126 + * debugging.
36127 + * This bug was caught by west-ah-0[12].
36128 + *
36129 + * Revision 1.126 2002/11/04 05:03:43 mcr
36130 + * fixes for IPCOMP. There were two problems:
36131 + * 1) the irs->ipp pointer was not being updated properly after
36132 + * the ESP descryption. The meant nothing for IPIP, as the
36133 + * later IP header overwrote the earlier one.
36134 + * 2) the more serious problem was that skb_decompress will
36135 + * usually allocate a new SKB, so we have to make sure that
36136 + * it doesn't get lost.
36137 + * #2 meant removing the skb argument from the ->decrypt routine
36138 + * and moving it to the irs->skb, so it could be value/result.
36139 + *
36140 + * Revision 1.125 2002/11/01 01:53:35 dhr
36141 + *
36142 + * fix typo
36143 + *
36144 + * Revision 1.124 2002/10/31 22:49:01 dhr
36145 + *
36146 + * - eliminate unused variable "hash"
36147 + * - reduce scope of variable "authenticator"
36148 + * - add comment on a couple of tricky bits
36149 + *
36150 + * Revision 1.123 2002/10/31 22:39:56 dhr
36151 + *
36152 + * use correct type for result of function calls
36153 + *
36154 + * Revision 1.122 2002/10/31 22:36:25 dhr
36155 + *
36156 + * simplify complex test
36157 + *
36158 + * Revision 1.121 2002/10/31 22:34:04 dhr
36159 + *
36160 + * ipsprev is never used: ditch it
36161 + *
36162 + * Revision 1.120 2002/10/31 22:30:21 dhr
36163 + *
36164 + * eliminate redundant assignments
36165 + *
36166 + * Revision 1.119 2002/10/31 22:27:43 dhr
36167 + *
36168 + * make whitespace canonical
36169 + *
36170 + * Revision 1.118 2002/10/30 05:47:17 rgb
36171 + * Fixed cut-and-paste error mis-identifying comp runt as ah.
36172 + *
36173 + * Revision 1.117 2002/10/17 16:37:45 rgb
36174 + * Remove compp intermediate variable and in-line its contents
36175 + * where used
36176 + *
36177 + * Revision 1.116 2002/10/12 23:11:53 dhr
36178 + *
36179 + * [KenB + DHR] more 64-bit cleanup
36180 + *
36181 + * Revision 1.115 2002/10/07 19:06:58 rgb
36182 + * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming.
36183 + *
36184 + * Revision 1.114 2002/10/07 18:31:31 rgb
36185 + * Set saref on incoming packets.
36186 + *
36187 + * Revision 1.113 2002/09/16 21:28:12 mcr
36188 + * adjust hash length for HMAC calculation - must look at whether
36189 + * it is MD5 or SHA1.
36190 + *
36191 + * Revision 1.112 2002/09/16 21:19:15 mcr
36192 + * fixes for west-ah-icmp-01 - length of AH header must be
36193 + * calculated properly, and next_header field properly copied.
36194 + *
36195 + * Revision 1.111 2002/09/10 02:45:56 mcr
36196 + * re-factored the ipsec_rcv function into several functions,
36197 + * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP.
36198 + * In addition, the MD5 and SHA1 functions are replaced with pointers.
36199 + *
36200 + * Revision 1.110 2002/08/30 06:34:33 rgb
36201 + * Fix scope of shift in AH header length check.
36202 + *
36203 + * Revision 1.109 2002/08/27 16:49:20 rgb
36204 + * Fixed ESP short packet DOS (and AH and IPCOMP).
36205 + *
36206 + * Revision 1.108 2002/07/24 18:44:54 rgb
36207 + * Type fiddling to tame ia64 compiler.
36208 + *
36209 + * Revision 1.107 2002/05/27 18:58:18 rgb
36210 + * Convert to dynamic ipsec device allocation.
36211 + * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
36212 + *
36213 + * Revision 1.106 2002/05/23 07:15:21 rgb
36214 + * Pointer clean-up.
36215 + * Added refcount code.
36216 + *
36217 + * Revision 1.105 2002/05/14 02:35:06 rgb
36218 + * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
36219 + * ipsec_sa or ipsec_sa.
36220 + * Change references to _TDB to _IPSA.
36221 + *
36222 + * Revision 1.104 2002/04/24 07:55:32 mcr
36223 + * #include patches and Makefiles for post-reorg compilation.
36224 + *
36225 + * Revision 1.103 2002/04/24 07:36:30 mcr
36226 + * Moved from ./klips/net/ipsec/ipsec_rcv.c,v
36227 + *
36228 + * Revision 1.102 2002/01/29 17:17:56 mcr
36229 + * moved include of ipsec_param.h to after include of linux/kernel.h
36230 + * otherwise, it seems that some option that is set in ipsec_param.h
36231 + * screws up something subtle in the include path to kernel.h, and
36232 + * it complains on the snprintf() prototype.
36233 + *
36234 + * Revision 1.101 2002/01/29 04:00:52 mcr
36235 + * more excise of kversions.h header.
36236 + *
36237 + * Revision 1.100 2002/01/29 02:13:17 mcr
36238 + * introduction of ipsec_kversion.h means that include of
36239 + * ipsec_param.h must preceed any decisions about what files to
36240 + * include to deal with differences in kernel source.
36241 + *
36242 + * Revision 1.99 2002/01/28 21:40:59 mcr
36243 + * should use #if to test boolean option rather than #ifdef.
36244 + *
36245 + * Revision 1.98 2002/01/20 20:19:36 mcr
36246 + * renamed option to IP_FRAGMENT_LINEARIZE.
36247 + *
36248 + * Revision 1.97 2002/01/12 02:55:36 mcr
36249 + * fix for post-2.4.4 to linearize skb's when ESP packet
36250 + * was assembled from fragments.
36251 + *
36252 + * Revision 1.96 2001/11/26 09:23:49 rgb
36253 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
36254 + *
36255 + * Revision 1.93.2.2 2001/10/22 20:54:07 mcr
36256 + * include des.h, removed phony prototypes and fixed calling
36257 + * conventions to match real prototypes.
36258 + *
36259 + * Revision 1.93.2.1 2001/09/25 02:22:22 mcr
36260 + * struct tdb -> struct ipsec_sa.
36261 + * lifetime checks moved to ipsec_life.c
36262 + * some sa(tdb) manipulation functions renamed.
36263 + *
36264 + * Revision 1.95 2001/11/06 19:49:07 rgb
36265 + * Added variable descriptions.
36266 + * Removed unauthenticated sequence==0 check to prevent DoS.
36267 + *
36268 + * Revision 1.94 2001/10/18 04:45:20 rgb
36269 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
36270 + * lib/freeswan.h version macros moved to lib/kversions.h.
36271 + * Other compiler directive cleanups.
36272 + *
36273 + * Revision 1.93 2001/09/07 22:17:24 rgb
36274 + * Fix for removal of transport layer protocol handler arg in 2.4.4.
36275 + * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
36276 + *
36277 + * Revision 1.92 2001/08/27 19:44:41 rgb
36278 + * Fix error in comment.
36279 + *
36280 + * Revision 1.91 2001/07/20 19:31:48 dhr
36281 + * [DHR] fix source and destination subnets of policy in diagnostic
36282 + *
36283 + * Revision 1.90 2001/07/06 19:51:09 rgb
36284 + * Added inbound policy checking code for IPIP SAs.
36285 + * Renamed unused function argument for ease and intuitive naming.
36286 + *
36287 + * Revision 1.89 2001/06/22 19:35:23 rgb
36288 + * Disable ipcomp processing if we are handed a ipcomp packet with no esp
36289 + * or ah header.
36290 + * Print protocol if we are handed a non-ipsec packet.
36291 + *
36292 + * Revision 1.88 2001/06/20 06:30:47 rgb
36293 + * Fixed transport mode IPCOMP policy check bug.
36294 + *
36295 + * Revision 1.87 2001/06/13 20:58:40 rgb
36296 + * Added parentheses around assignment used as truth value to silence
36297 + * compiler.
36298 + *
36299 + * Revision 1.86 2001/06/07 22:25:23 rgb
36300 + * Added a source address policy check for tunnel mode. It still does
36301 + * not check client addresses and masks.
36302 + * Only decapsulate IPIP if it is expected.
36303 + *
36304 + * Revision 1.85 2001/05/30 08:14:02 rgb
36305 + * Removed vestiges of esp-null transforms.
36306 + *
36307 + * Revision 1.84 2001/05/27 06:12:11 rgb
36308 + * Added structures for pid, packet count and last access time to eroute.
36309 + * Added packet count to beginning of /proc/net/ipsec_eroute.
36310 + *
36311 + * Revision 1.83 2001/05/04 16:45:47 rgb
36312 + * Remove unneeded code. ipp is not used after this point.
36313 + *
36314 + * Revision 1.82 2001/05/04 16:36:00 rgb
36315 + * Fix skb_cow() call for 2.4.4. (SS)
36316 + *
36317 + * Revision 1.81 2001/05/02 14:46:53 rgb
36318 + * Fix typo for compiler directive to pull IPH back.
36319 + *
36320 + * Revision 1.80 2001/04/30 19:46:34 rgb
36321 + * Update for 2.4.4. We now receive the skb with skb->data pointing to
36322 + * h.raw.
36323 + *
36324 + * Revision 1.79 2001/04/23 15:01:15 rgb
36325 + * Added spin_lock() check to prevent double-locking for multiple
36326 + * transforms and hence kernel lock-ups with SMP kernels.
36327 + * Minor spin_unlock() adjustments to unlock before non-dependant prints
36328 + * and IPSEC device stats updates.
36329 + *
36330 + * Revision 1.78 2001/04/21 23:04:24 rgb
36331 + * Check if soft expire has already been sent before sending another to
36332 + * prevent ACQUIRE flooding.
36333 + *
36334 + * Revision 1.77 2001/03/16 07:35:20 rgb
36335 + * Ditch extra #if 1 around now permanent policy checking code.
36336 + *
36337 + * Revision 1.76 2001/02/27 22:24:54 rgb
36338 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
36339 + * Check for satoa() return codes.
36340 + *
36341 + * Revision 1.75 2001/02/19 22:28:30 rgb
36342 + * Minor change to virtual device discovery code to assert which I/F has
36343 + * been found.
36344 + *
36345 + * Revision 1.74 2000/11/25 03:50:36 rgb
36346 + * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
36347 + *
36348 + * Revision 1.73 2000/11/09 20:52:15 rgb
36349 + * More spinlock shuffling, locking earlier and unlocking later in rcv to
36350 + * include ipcomp and prevent races, renaming some tdb variables that got
36351 + * forgotten, moving some unlocks to include tdbs and adding a missing
36352 + * unlock. Thanks to Svenning for some of these.
36353 + *
36354 + * Revision 1.72 2000/11/09 20:11:22 rgb
36355 + * Minor shuffles to fix non-standard kernel config option selection.
36356 + *
36357 + * Revision 1.71 2000/11/06 04:36:18 rgb
36358 + * Ditched spin_lock_irqsave in favour of spin_lock.
36359 + * Minor initial protocol check rewrite.
36360 + * Clean up debug printing.
36361 + * Clean up tdb handling on ipcomp.
36362 + * Fixed transport mode null pointer de-reference without ipcomp.
36363 + * Add Svenning's adaptive content compression.
36364 + * Disabled registration of ipcomp handler.
36365 + *
36366 + * Revision 1.70 2000/10/30 23:41:43 henry
36367 + * Hans-Joerg Hoexer's null-pointer fix
36368 + *
36369 + * Revision 1.69 2000/10/10 18:54:16 rgb
36370 + * Added a fix for incoming policy check with ipcomp enabled but
36371 + * uncompressible.
36372 + *
36373 + * Revision 1.68 2000/09/22 17:53:12 rgb
36374 + * Fixed ipcomp tdb pointers update for policy checking.
36375 + *
36376 + * Revision 1.67 2000/09/21 03:40:58 rgb
36377 + * Added more debugging to try and track down the cpi outward copy problem.
36378 + *
36379 + * Revision 1.66 2000/09/20 04:00:10 rgb
36380 + * Changed static functions to DEBUG_NO_STATIC to reveal function names for
36381 + * debugging oopsen.
36382 + *
36383 + * Revision 1.65 2000/09/19 07:07:16 rgb
36384 + * Added debugging to inbound policy check for ipcomp.
36385 + * Added missing spin_unlocks (thanks Svenning!).
36386 + * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
36387 + * Protect ipcomp policy check following ipip decap with sysctl switch.
36388 + *
36389 + * Revision 1.64 2000/09/18 21:27:29 rgb
36390 + * 2.0 fixes.
36391 + *
36392 + * Revision 1.63 2000/09/18 02:35:50 rgb
36393 + * Added policy checking to ipcomp and re-enabled policy checking by
36394 + * default.
36395 + * Optimised satoa calls.
36396 + *
36397 + * Revision 1.62 2000/09/17 21:02:32 rgb
36398 + * Clean up debugging, removing slow timestamp debug code.
36399 + *
36400 + * Revision 1.61 2000/09/16 01:07:55 rgb
36401 + * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
36402 + *
36403 + * Revision 1.60 2000/09/15 11:37:01 rgb
36404 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
36405 + * IPCOMP zlib deflate code.
36406 + *
36407 + * Revision 1.59 2000/09/15 04:56:20 rgb
36408 + * Remove redundant satoa() call, reformat comment.
36409 + *
36410 + * Revision 1.58 2000/09/13 08:00:52 rgb
36411 + * Flick on inbound policy checking.
36412 + *
36413 + * Revision 1.57 2000/09/12 03:22:19 rgb
36414 + * Converted inbound_policy_check to sysctl.
36415 + * Re-enabled policy backcheck.
36416 + * Moved policy checks to top and within tdb lock.
36417 + *
36418 + * Revision 1.56 2000/09/08 19:12:56 rgb
36419 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
36420 + *
36421 + * Revision 1.55 2000/08/28 18:15:46 rgb
36422 + * Added MB's nf-debug reset patch.
36423 + *
36424 + * Revision 1.54 2000/08/27 01:41:26 rgb
36425 + * More minor tweaks to the bad padding debug code.
36426 + *
36427 + * Revision 1.53 2000/08/24 16:54:16 rgb
36428 + * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
36429 + * info.
36430 + * Tidied up device reporting at the start of ipsec_rcv.
36431 + * Tidied up bad padding debugging and processing.
36432 + *
36433 + * Revision 1.52 2000/08/20 21:36:03 rgb
36434 + * Activated pfkey_expire() calls.
36435 + * Added a hard/soft expiry parameter to pfkey_expire().
36436 + * Added sanity checking to avoid propagating zero or smaller-length skbs
36437 + * from a bogus decryption.
36438 + * Re-arranged the order of soft and hard expiry to conform to RFC2367.
36439 + * Clean up references to CONFIG_IPSEC_PFKEYv2.
36440 + *
36441 + * Revision 1.51 2000/08/18 21:23:30 rgb
36442 + * Improve bad padding warning so that the printk buffer doesn't get
36443 + * trampled.
36444 + *
36445 + * Revision 1.50 2000/08/01 14:51:51 rgb
36446 + * Removed _all_ remaining traces of DES.
36447 + *
36448 + * Revision 1.49 2000/07/28 13:50:53 rgb
36449 + * Changed enet_statistics to net_device_stats and added back compatibility
36450 + * for pre-2.1.19.
36451 + *
36452 + * Revision 1.48 2000/05/10 19:14:40 rgb
36453 + * Only check usetime against soft and hard limits if the tdb has been
36454 + * used.
36455 + * Cast output of ntohl so that the broken prototype doesn't make our
36456 + * compile noisy.
36457 + *
36458 + * Revision 1.47 2000/05/09 17:45:43 rgb
36459 + * Fix replay bitmap corruption bug upon receipt of bogus packet
36460 + * with correct SPI. This was a DoS.
36461 + *
36462 + * Revision 1.46 2000/03/27 02:31:58 rgb
36463 + * Fixed authentication failure printout bug.
36464 + *
36465 + * Revision 1.45 2000/03/22 16:15:37 rgb
36466 + * Fixed renaming of dev_get (MB).
36467 + *
36468 + * Revision 1.44 2000/03/16 08:17:24 rgb
36469 + * Hardcode PF_KEYv2 support.
36470 + * Fixed minor bug checking AH header length.
36471 + *
36472 + * Revision 1.43 2000/03/14 12:26:59 rgb
36473 + * Added skb->nfct support for clearing netfilter conntrack bits (MB).
36474 + *
36475 + * Revision 1.42 2000/01/26 10:04:04 rgb
36476 + * Fixed inbound policy checking on transport mode bug.
36477 + * Fixed noisy 2.0 printk arguments.
36478 + *
36479 + * Revision 1.41 2000/01/24 20:58:02 rgb
36480 + * Improve debugging/reporting support for (disabled) inbound
36481 + * policy checking.
36482 + *
36483 + * Revision 1.40 2000/01/22 23:20:10 rgb
36484 + * Fixed up inboud policy checking code.
36485 + * Cleaned out unused crud.
36486 + *
36487 + * Revision 1.39 2000/01/21 06:15:29 rgb
36488 + * Added sanity checks on skb_push(), skb_pull() to prevent panics.
36489 + * Fixed cut-and-paste debug_tunnel to debug_rcv.
36490 + * Added inbound policy checking code, disabled.
36491 + * Simplified output code by updating ipp to post-IPIP decapsulation.
36492 + *
36493 + * elided pre-2000 comments. Use "cvs log"
36494 + *
36495 + *
36496 + * Local Variables:
36497 + * c-set-style: linux
36498 + * End:
36499 + *
36500 + */
36501 --- /dev/null Tue Mar 11 13:02:56 2003
36502 +++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004
36503 @@ -0,0 +1,1870 @@
36504 +/*
36505 + * Common routines for IPsec SA maintenance routines.
36506 + *
36507 + * Copyright (C) 1996, 1997 John Ioannidis.
36508 + * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
36509 + *
36510 + * This program is free software; you can redistribute it and/or modify it
36511 + * under the terms of the GNU General Public License as published by the
36512 + * Free Software Foundation; either version 2 of the License, or (at your
36513 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
36514 + *
36515 + * This program is distributed in the hope that it will be useful, but
36516 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
36517 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36518 + * for more details.
36519 + *
36520 + * RCSID $Id: ipsec_sa.c,v 1.30.2.2 2006/10/06 21:39:26 paul Exp $
36521 + *
36522 + * This is the file formerly known as "ipsec_xform.h"
36523 + *
36524 + */
36525 +
36526 +#ifndef AUTOCONF_INCLUDED
36527 +#include <linux/config.h>
36528 +#endif
36529 +#include <linux/version.h>
36530 +#include <linux/kernel.h> /* printk() */
36531 +
36532 +#include "openswan/ipsec_param.h"
36533 +
36534 +#ifdef MALLOC_SLAB
36535 +# include <linux/slab.h> /* kmalloc() */
36536 +#else /* MALLOC_SLAB */
36537 +# include <linux/malloc.h> /* kmalloc() */
36538 +#endif /* MALLOC_SLAB */
36539 +#include <linux/vmalloc.h> /* vmalloc() */
36540 +#include <linux/errno.h> /* error codes */
36541 +#include <linux/types.h> /* size_t */
36542 +#include <linux/interrupt.h> /* mark_bh */
36543 +
36544 +#include <linux/netdevice.h> /* struct device, and other headers */
36545 +#include <linux/etherdevice.h> /* eth_type_trans */
36546 +#include <linux/ip.h> /* struct iphdr */
36547 +#include <linux/skbuff.h>
36548 +#include <openswan.h>
36549 +#ifdef SPINLOCK
36550 +#ifdef SPINLOCK_23
36551 +#include <linux/spinlock.h> /* *lock* */
36552 +#else /* SPINLOCK_23 */
36553 +#include <asm/spinlock.h> /* *lock* */
36554 +#endif /* SPINLOCK_23 */
36555 +#endif /* SPINLOCK */
36556 +
36557 +#include <net/ip.h>
36558 +
36559 +#include "openswan/radij.h"
36560 +
36561 +#include "openswan/ipsec_stats.h"
36562 +#include "openswan/ipsec_life.h"
36563 +#include "openswan/ipsec_sa.h"
36564 +#include "openswan/ipsec_xform.h"
36565 +
36566 +#include "openswan/ipsec_encap.h"
36567 +#include "openswan/ipsec_radij.h"
36568 +#include "openswan/ipsec_xform.h"
36569 +#include "openswan/ipsec_ipe4.h"
36570 +#include "openswan/ipsec_ah.h"
36571 +#include "openswan/ipsec_esp.h"
36572 +
36573 +#include <pfkeyv2.h>
36574 +#include <pfkey.h>
36575 +
36576 +#include "openswan/ipsec_proto.h"
36577 +#include "openswan/ipsec_alg.h"
36578 +
36579 +
36580 +#ifdef CONFIG_KLIPS_DEBUG
36581 +int debug_xform = 0;
36582 +#endif /* CONFIG_KLIPS_DEBUG */
36583 +
36584 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
36585 +
36586 +struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
36587 +#ifdef SPINLOCK
36588 +spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
36589 +#else /* SPINLOCK */
36590 +spinlock_t tdb_lock;
36591 +#endif /* SPINLOCK */
36592 +
36593 +struct ipsec_sadb ipsec_sadb;
36594 +
36595 +#if IPSEC_SA_REF_CODE
36596 +
36597 +/* the sub table must be narrower (or equal) in bits than the variable type
36598 + in the main table to count the number of unused entries in it. */
36599 +typedef struct {
36600 + int testSizeOf_refSubTable :
36601 + ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
36602 +} dummy;
36603 +
36604 +
36605 +/* The field where the saref will be hosted in the skb must be wide enough to
36606 + accomodate the information it needs to store. */
36607 +typedef struct {
36608 + int testSizeOf_refField :
36609 + (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
36610 +} dummy2;
36611 +
36612 +
36613 +#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
36614 +
36615 +
36616 +void
36617 +ipsec_SAtest(void)
36618 +{
36619 + IPsecSAref_t SAref = 258;
36620 + struct ipsec_sa ips;
36621 + ips.ips_ref = 772;
36622 +
36623 + printk("klips_debug:ipsec_SAtest: "
36624 + "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
36625 + "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
36626 + "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
36627 + "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
36628 + "IPSEC_SA_REF_TABLE_MASK=%x\n"
36629 + "IPSEC_SA_REF_ENTRY_MASK=%x\n"
36630 + "IPsecSAref2table(%d)=%u\n"
36631 + "IPsecSAref2entry(%d)=%u\n"
36632 + "IPsecSAref2NFmark(%d)=%u\n"
36633 + "IPsecSAref2SA(%d)=%p\n"
36634 + "IPsecSA2SAref(%p)=%d\n"
36635 + ,
36636 + IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36637 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
36638 + IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36639 + (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH,
36640 + IPSEC_SA_REF_TABLE_MASK,
36641 + IPSEC_SA_REF_ENTRY_MASK,
36642 + SAref, IPsecSAref2table(SAref),
36643 + SAref, IPsecSAref2entry(SAref),
36644 + SAref, IPsecSAref2NFmark(SAref),
36645 + SAref, IPsecSAref2SA(SAref),
36646 + (&ips), IPsecSA2SAref((&ips))
36647 + );
36648 + return;
36649 +}
36650 +
36651 +int
36652 +ipsec_SAref_recycle(void)
36653 +{
36654 + int table;
36655 + int entry;
36656 + int error = 0;
36657 +
36658 + ipsec_sadb.refFreeListHead = -1;
36659 + ipsec_sadb.refFreeListTail = -1;
36660 +
36661 + if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
36662 + KLIPS_PRINT(debug_xform,
36663 + "klips_debug:ipsec_SAref_recycle: "
36664 + "end of table reached, continuing at start..\n");
36665 + ipsec_sadb.refFreeListCont = 0;
36666 + }
36667 +
36668 + KLIPS_PRINT(debug_xform,
36669 + "klips_debug:ipsec_SAref_recycle: "
36670 + "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
36671 + ipsec_sadb.refFreeListCont,
36672 + (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
36673 + IPsecSAref2table(ipsec_sadb.refFreeListCont),
36674 + IPsecSAref2entry(ipsec_sadb.refFreeListCont));
36675 +
36676 + for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
36677 + table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
36678 + table++) {
36679 + if(ipsec_sadb.refTable[table] == NULL) {
36680 + error = ipsec_SArefSubTable_alloc(table);
36681 + if(error) {
36682 + return error;
36683 + }
36684 + }
36685 + for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
36686 + entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
36687 + entry++) {
36688 + if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
36689 + ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
36690 + if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
36691 + ipsec_sadb.refFreeListHead = 0;
36692 + ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
36693 + KLIPS_PRINT(debug_xform,
36694 + "klips_debug:ipsec_SAref_recycle: "
36695 + "SArefFreeList refilled.\n");
36696 + return 0;
36697 + }
36698 + }
36699 + }
36700 + }
36701 +
36702 + if(ipsec_sadb.refFreeListTail == -1) {
36703 + KLIPS_PRINT(debug_xform,
36704 + "klips_debug:ipsec_SAref_recycle: "
36705 + "out of room in the SArefTable.\n");
36706 +
36707 + return(-ENOSPC);
36708 + }
36709 +
36710 + ipsec_sadb.refFreeListHead = 0;
36711 + ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
36712 + KLIPS_PRINT(debug_xform,
36713 + "klips_debug:ipsec_SAref_recycle: "
36714 + "SArefFreeList partly refilled to %d of %d.\n",
36715 + ipsec_sadb.refFreeListTail,
36716 + IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36717 + return 0;
36718 +}
36719 +
36720 +int
36721 +ipsec_SArefSubTable_alloc(unsigned table)
36722 +{
36723 + unsigned entry;
36724 + struct IPsecSArefSubTable* SArefsub;
36725 +
36726 + KLIPS_PRINT(debug_xform,
36727 + "klips_debug:ipsec_SArefSubTable_alloc: "
36728 + "allocating %lu bytes for table %u of %u.\n",
36729 + (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
36730 + table,
36731 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36732 +
36733 + /* allocate another sub-table */
36734 + SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
36735 + if(SArefsub == NULL) {
36736 + KLIPS_PRINT(debug_xform,
36737 + "klips_debug:ipsec_SArefSubTable_alloc: "
36738 + "error allocating memory for table %u of %u!\n",
36739 + table,
36740 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
36741 + return -ENOMEM;
36742 + }
36743 +
36744 + /* add this sub-table to the main table */
36745 + ipsec_sadb.refTable[table] = SArefsub;
36746 +
36747 + /* initialise each element to NULL */
36748 + KLIPS_PRINT(debug_xform,
36749 + "klips_debug:ipsec_SArefSubTable_alloc: "
36750 + "initialising %u elements (2 ^ %u) of table %u.\n",
36751 + IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
36752 + IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
36753 + table);
36754 + for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
36755 + SArefsub->entry[entry] = NULL;
36756 + }
36757 +
36758 + return 0;
36759 +}
36760 +#endif /* IPSEC_SA_REF_CODE */
36761 +
36762 +int
36763 +ipsec_saref_freelist_init(void)
36764 +{
36765 + int i;
36766 +
36767 + KLIPS_PRINT(debug_xform,
36768 + "klips_debug:ipsec_saref_freelist_init: "
36769 + "initialising %u elements of FreeList.\n",
36770 + IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36771 +
36772 + for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
36773 + ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
36774 + }
36775 + ipsec_sadb.refFreeListHead = -1;
36776 + ipsec_sadb.refFreeListCont = 0;
36777 + ipsec_sadb.refFreeListTail = -1;
36778 +
36779 + return 0;
36780 +}
36781 +
36782 +int
36783 +ipsec_sadb_init(void)
36784 +{
36785 + int error = 0;
36786 + unsigned i;
36787 +
36788 + for(i = 0; i < SADB_HASHMOD; i++) {
36789 + ipsec_sadb_hash[i] = NULL;
36790 + }
36791 + /* parts above are for the old style SADB hash table */
36792 +
36793 +
36794 +#if IPSEC_SA_REF_CODE
36795 + /* initialise SA reference table */
36796 +
36797 + /* initialise the main table */
36798 + KLIPS_PRINT(debug_xform,
36799 + "klips_debug:ipsec_sadb_init: "
36800 + "initialising main table of size %u (2 ^ %u).\n",
36801 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
36802 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
36803 + {
36804 + unsigned table;
36805 + for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
36806 + ipsec_sadb.refTable[table] = NULL;
36807 + }
36808 + }
36809 +
36810 + /* allocate the first sub-table */
36811 + error = ipsec_SArefSubTable_alloc(0);
36812 + if(error) {
36813 + return error;
36814 + }
36815 +
36816 + error = ipsec_saref_freelist_init();
36817 +#endif /* IPSEC_SA_REF_CODE */
36818 + return error;
36819 +}
36820 +
36821 +#if IPSEC_SA_REF_CODE
36822 +IPsecSAref_t
36823 +ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
36824 +{
36825 + IPsecSAref_t SAref;
36826 +
36827 + KLIPS_PRINT(debug_xform,
36828 + "klips_debug:ipsec_SAref_alloc: "
36829 + "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
36830 + ipsec_sadb.refFreeListHead,
36831 + ipsec_sadb.refFreeListCont,
36832 + ipsec_sadb.refFreeListTail,
36833 + IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
36834 +
36835 + if(ipsec_sadb.refFreeListHead == -1) {
36836 + KLIPS_PRINT(debug_xform,
36837 + "klips_debug:ipsec_SAref_alloc: "
36838 + "FreeList empty, recycling...\n");
36839 + *error = ipsec_SAref_recycle();
36840 + if(*error) {
36841 + return IPSEC_SAREF_NULL;
36842 + }
36843 + }
36844 +
36845 + SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
36846 + if(SAref == IPSEC_SAREF_NULL) {
36847 + KLIPS_PRINT(debug_xform,
36848 + "klips_debug:ipsec_SAref_alloc: "
36849 + "unexpected error, refFreeListHead = %d points to invalid entry.\n",
36850 + ipsec_sadb.refFreeListHead);
36851 + *error = -ESPIPE;
36852 + return IPSEC_SAREF_NULL;
36853 + }
36854 +
36855 + KLIPS_PRINT(debug_xform,
36856 + "klips_debug:ipsec_SAref_alloc: "
36857 + "allocating SAref=%d, table=%u, entry=%u of %u.\n",
36858 + SAref,
36859 + IPsecSAref2table(SAref),
36860 + IPsecSAref2entry(SAref),
36861 + IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
36862 +
36863 + ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
36864 + ipsec_sadb.refFreeListHead++;
36865 + if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
36866 + KLIPS_PRINT(debug_xform,
36867 + "klips_debug:ipsec_SAref_alloc: "
36868 + "last FreeList entry allocated, resetting list head to empty.\n");
36869 + ipsec_sadb.refFreeListHead = -1;
36870 + }
36871 +
36872 + return SAref;
36873 +}
36874 +#endif /* IPSEC_SA_REF_CODE */
36875 +
36876 +int
36877 +ipsec_sa_print(struct ipsec_sa *ips)
36878 +{
36879 + char sa[SATOT_BUF];
36880 + size_t sa_len;
36881 +
36882 + printk(KERN_INFO "klips_debug: SA:");
36883 + if(ips == NULL) {
36884 + printk("NULL\n");
36885 + return -ENOENT;
36886 + }
36887 + printk(" ref=%d", ips->ips_ref);
36888 + printk(" refcount=%d", atomic_read(&ips->ips_refcount));
36889 + if(ips->ips_hnext != NULL) {
36890 + printk(" hnext=0p%p", ips->ips_hnext);
36891 + }
36892 + if(ips->ips_inext != NULL) {
36893 + printk(" inext=0p%p", ips->ips_inext);
36894 + }
36895 + if(ips->ips_onext != NULL) {
36896 + printk(" onext=0p%p", ips->ips_onext);
36897 + }
36898 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
36899 + printk(" said=%s", sa_len ? sa : " (error)");
36900 + if(ips->ips_seq) {
36901 + printk(" seq=%u", ips->ips_seq);
36902 + }
36903 + if(ips->ips_pid) {
36904 + printk(" pid=%u", ips->ips_pid);
36905 + }
36906 + if(ips->ips_authalg) {
36907 + printk(" authalg=%u", ips->ips_authalg);
36908 + }
36909 + if(ips->ips_encalg) {
36910 + printk(" encalg=%u", ips->ips_encalg);
36911 + }
36912 + printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
36913 + if(ips->ips_replaywin) {
36914 + printk(" ooowin=%u", ips->ips_replaywin);
36915 + }
36916 + if(ips->ips_flags) {
36917 + printk(" flags=%u", ips->ips_flags);
36918 + }
36919 + if(ips->ips_addr_s) {
36920 + char buf[SUBNETTOA_BUF];
36921 + addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36922 + 0, buf, sizeof(buf));
36923 + printk(" src=%s", buf);
36924 + }
36925 + if(ips->ips_addr_d) {
36926 + char buf[SUBNETTOA_BUF];
36927 + addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
36928 + 0, buf, sizeof(buf));
36929 + printk(" dst=%s", buf);
36930 + }
36931 + if(ips->ips_addr_p) {
36932 + char buf[SUBNETTOA_BUF];
36933 + addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
36934 + 0, buf, sizeof(buf));
36935 + printk(" proxy=%s", buf);
36936 + }
36937 + if(ips->ips_key_bits_a) {
36938 + printk(" key_bits_a=%u", ips->ips_key_bits_a);
36939 + }
36940 + if(ips->ips_key_bits_e) {
36941 + printk(" key_bits_e=%u", ips->ips_key_bits_e);
36942 + }
36943 +
36944 + printk("\n");
36945 + return 0;
36946 +}
36947 +
36948 +struct ipsec_sa*
36949 +ipsec_sa_alloc(int*error) /* pass in error var by pointer */
36950 +{
36951 + struct ipsec_sa* ips;
36952 +
36953 + if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
36954 + KLIPS_PRINT(debug_xform,
36955 + "klips_debug:ipsec_sa_alloc: "
36956 + "memory allocation error\n");
36957 + *error = -ENOMEM;
36958 + return NULL;
36959 + }
36960 + memset((caddr_t)ips, 0, sizeof(*ips));
36961 +#if IPSEC_SA_REF_CODE
36962 + ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */
36963 + KLIPS_PRINT(debug_xform,
36964 + "klips_debug:ipsec_sa_alloc: "
36965 + "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
36966 + (unsigned long) sizeof(*ips),
36967 + ips,
36968 + ips->ips_ref);
36969 + if(ips->ips_ref == IPSEC_SAREF_NULL) {
36970 + kfree(ips);
36971 + KLIPS_PRINT(debug_xform,
36972 + "klips_debug:ipsec_sa_alloc: "
36973 + "SAref allocation error\n");
36974 + return NULL;
36975 + }
36976 +
36977 + atomic_inc(&ips->ips_refcount);
36978 + IPsecSAref2SA(ips->ips_ref) = ips;
36979 +#endif /* IPSEC_SA_REF_CODE */
36980 +
36981 + *error = 0;
36982 + return(ips);
36983 +}
36984 +
36985 +int
36986 +ipsec_sa_free(struct ipsec_sa* ips)
36987 +{
36988 + return ipsec_sa_wipe(ips);
36989 +}
36990 +
36991 +struct ipsec_sa *
36992 +ipsec_sa_getbyid(ip_said *said)
36993 +{
36994 + int hashval;
36995 + struct ipsec_sa *ips;
36996 + char sa[SATOT_BUF];
36997 + size_t sa_len;
36998 +
36999 + if(said == NULL) {
37000 + KLIPS_PRINT(debug_xform,
37001 + "klips_error:ipsec_sa_getbyid: "
37002 + "null pointer passed in!\n");
37003 + return NULL;
37004 + }
37005 +
37006 + sa_len = satot(said, 0, sa, sizeof(sa));
37007 +
37008 + hashval = IPS_HASH(said);
37009 +
37010 + KLIPS_PRINT(debug_xform,
37011 + "klips_debug:ipsec_sa_getbyid: "
37012 + "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
37013 + hashval,
37014 + sa_len ? sa : " (error)");
37015 +
37016 + if((ips = ipsec_sadb_hash[hashval]) == NULL) {
37017 + KLIPS_PRINT(debug_xform,
37018 + "klips_debug:ipsec_sa_getbyid: "
37019 + "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
37020 + hashval,
37021 + sa_len ? sa : " (error)");
37022 + return NULL;
37023 + }
37024 +
37025 + for (; ips; ips = ips->ips_hnext) {
37026 + if ((ips->ips_said.spi == said->spi) &&
37027 + (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
37028 + (ips->ips_said.proto == said->proto)) {
37029 + atomic_inc(&ips->ips_refcount);
37030 + return ips;
37031 + }
37032 + }
37033 +
37034 + KLIPS_PRINT(debug_xform,
37035 + "klips_debug:ipsec_sa_getbyid: "
37036 + "no entry in linked list for hash=%d of SA:%s.\n",
37037 + hashval,
37038 + sa_len ? sa : " (error)");
37039 + return NULL;
37040 +}
37041 +
37042 +int
37043 +ipsec_sa_put(struct ipsec_sa *ips)
37044 +{
37045 + char sa[SATOT_BUF];
37046 + size_t sa_len;
37047 +
37048 + if(ips == NULL) {
37049 + KLIPS_PRINT(debug_xform,
37050 + "klips_error:ipsec_sa_put: "
37051 + "null pointer passed in!\n");
37052 + return -1;
37053 + }
37054 +
37055 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37056 +
37057 + KLIPS_PRINT(debug_xform,
37058 + "klips_debug:ipsec_sa_put: "
37059 + "ipsec_sa SA:%s, ref:%d reference count decremented.\n",
37060 + sa_len ? sa : " (error)",
37061 + ips->ips_ref);
37062 +
37063 + atomic_dec(&ips->ips_refcount);
37064 +
37065 + return 0;
37066 +}
37067 +
37068 +/*
37069 + The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
37070 +*/
37071 +int
37072 +ipsec_sa_add(struct ipsec_sa *ips)
37073 +{
37074 + int error = 0;
37075 + unsigned int hashval;
37076 +
37077 + if(ips == NULL) {
37078 + KLIPS_PRINT(debug_xform,
37079 + "klips_error:ipsec_sa_add: "
37080 + "null pointer passed in!\n");
37081 + return -ENODATA;
37082 + }
37083 + hashval = IPS_HASH(&ips->ips_said);
37084 +
37085 + atomic_inc(&ips->ips_refcount);
37086 + spin_lock_bh(&tdb_lock);
37087 +
37088 + ips->ips_hnext = ipsec_sadb_hash[hashval];
37089 + ipsec_sadb_hash[hashval] = ips;
37090 +
37091 + spin_unlock_bh(&tdb_lock);
37092 +
37093 + return error;
37094 +}
37095 +
37096 +/*
37097 + The ipsec_sa table better be locked before it is handed in, or races might happen
37098 +*/
37099 +int
37100 +ipsec_sa_del(struct ipsec_sa *ips)
37101 +{
37102 + unsigned int hashval;
37103 + struct ipsec_sa *ipstp;
37104 + char sa[SATOT_BUF];
37105 + size_t sa_len;
37106 +
37107 + if(ips == NULL) {
37108 + KLIPS_PRINT(debug_xform,
37109 + "klips_error:ipsec_sa_del: "
37110 + "null pointer passed in!\n");
37111 + return -ENODATA;
37112 + }
37113 +
37114 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37115 + if(ips->ips_inext || ips->ips_onext) {
37116 + KLIPS_PRINT(debug_xform,
37117 + "klips_error:ipsec_sa_del: "
37118 + "SA:%s still linked!\n",
37119 + sa_len ? sa : " (error)");
37120 + return -EMLINK;
37121 + }
37122 +
37123 + hashval = IPS_HASH(&ips->ips_said);
37124 +
37125 + KLIPS_PRINT(debug_xform,
37126 + "klips_debug:ipsec_sa_del: "
37127 + "deleting SA:%s, hashval=%d.\n",
37128 + sa_len ? sa : " (error)",
37129 + hashval);
37130 + if(ipsec_sadb_hash[hashval] == NULL) {
37131 + KLIPS_PRINT(debug_xform,
37132 + "klips_debug:ipsec_sa_del: "
37133 + "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
37134 + hashval,
37135 + sa_len ? sa : " (error)");
37136 + return -ENOENT;
37137 + }
37138 +
37139 + if (ips == ipsec_sadb_hash[hashval]) {
37140 + ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
37141 + ips->ips_hnext = NULL;
37142 + atomic_dec(&ips->ips_refcount);
37143 + KLIPS_PRINT(debug_xform,
37144 + "klips_debug:ipsec_sa_del: "
37145 + "successfully deleted first ipsec_sa in chain.\n");
37146 + return 0;
37147 + } else {
37148 + for (ipstp = ipsec_sadb_hash[hashval];
37149 + ipstp;
37150 + ipstp = ipstp->ips_hnext) {
37151 + if (ipstp->ips_hnext == ips) {
37152 + ipstp->ips_hnext = ips->ips_hnext;
37153 + ips->ips_hnext = NULL;
37154 + atomic_dec(&ips->ips_refcount);
37155 + KLIPS_PRINT(debug_xform,
37156 + "klips_debug:ipsec_sa_del: "
37157 + "successfully deleted link in ipsec_sa chain.\n");
37158 + return 0;
37159 + }
37160 + }
37161 + }
37162 +
37163 + KLIPS_PRINT(debug_xform,
37164 + "klips_debug:ipsec_sa_del: "
37165 + "no entries in linked list for hash=%d of SA:%s.\n",
37166 + hashval,
37167 + sa_len ? sa : " (error)");
37168 + return -ENOENT;
37169 +}
37170 +
37171 +/*
37172 + The ipsec_sa table better be locked before it is handed in, or races
37173 + might happen
37174 +*/
37175 +int
37176 +ipsec_sa_delchain(struct ipsec_sa *ips)
37177 +{
37178 + struct ipsec_sa *ipsdel;
37179 + int error = 0;
37180 + char sa[SATOT_BUF];
37181 + size_t sa_len;
37182 +
37183 + if(ips == NULL) {
37184 + KLIPS_PRINT(debug_xform,
37185 + "klips_error:ipsec_sa_delchain: "
37186 + "null pointer passed in!\n");
37187 + return -ENODATA;
37188 + }
37189 +
37190 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37191 + KLIPS_PRINT(debug_xform,
37192 + "klips_debug:ipsec_sa_delchain: "
37193 + "passed SA:%s\n",
37194 + sa_len ? sa : " (error)");
37195 + while(ips->ips_onext != NULL) {
37196 + ips = ips->ips_onext;
37197 + }
37198 +
37199 + while(ips) {
37200 + /* XXX send a pfkey message up to advise of deleted ipsec_sa */
37201 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37202 + KLIPS_PRINT(debug_xform,
37203 + "klips_debug:ipsec_sa_delchain: "
37204 + "unlinking and delting SA:%s",
37205 + sa_len ? sa : " (error)");
37206 + ipsdel = ips;
37207 + ips = ips->ips_inext;
37208 + if(ips != NULL) {
37209 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37210 + KLIPS_PRINT(debug_xform,
37211 + ", inext=%s",
37212 + sa_len ? sa : " (error)");
37213 + atomic_dec(&ipsdel->ips_refcount);
37214 + ipsdel->ips_inext = NULL;
37215 + atomic_dec(&ips->ips_refcount);
37216 + ips->ips_onext = NULL;
37217 + }
37218 + KLIPS_PRINT(debug_xform,
37219 + ".\n");
37220 + if((error = ipsec_sa_del(ipsdel))) {
37221 + KLIPS_PRINT(debug_xform,
37222 + "klips_debug:ipsec_sa_delchain: "
37223 + "ipsec_sa_del returned error %d.\n", -error);
37224 + return error;
37225 + }
37226 + if((error = ipsec_sa_wipe(ipsdel))) {
37227 + KLIPS_PRINT(debug_xform,
37228 + "klips_debug:ipsec_sa_delchain: "
37229 + "ipsec_sa_wipe returned error %d.\n", -error);
37230 + return error;
37231 + }
37232 + }
37233 + return error;
37234 +}
37235 +
37236 +int
37237 +ipsec_sadb_cleanup(__u8 proto)
37238 +{
37239 + unsigned i;
37240 + int error = 0;
37241 + struct ipsec_sa *ips, **ipsprev, *ipsdel;
37242 + char sa[SATOT_BUF];
37243 + size_t sa_len;
37244 +
37245 + KLIPS_PRINT(debug_xform,
37246 + "klips_debug:ipsec_sadb_cleanup: "
37247 + "cleaning up proto=%d.\n",
37248 + proto);
37249 +
37250 + spin_lock_bh(&tdb_lock);
37251 +
37252 + for (i = 0; i < SADB_HASHMOD; i++) {
37253 + ipsprev = &(ipsec_sadb_hash[i]);
37254 + ips = ipsec_sadb_hash[i];
37255 + if(ips != NULL) {
37256 + atomic_inc(&ips->ips_refcount);
37257 + }
37258 + for(; ips != NULL;) {
37259 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37260 + KLIPS_PRINT(debug_xform,
37261 + "klips_debug:ipsec_sadb_cleanup: "
37262 + "checking SA:%s, hash=%d, ref=%d",
37263 + sa_len ? sa : " (error)",
37264 + i,
37265 + ips->ips_ref);
37266 + ipsdel = ips;
37267 + ips = ipsdel->ips_hnext;
37268 + if(ips != NULL) {
37269 + atomic_inc(&ips->ips_refcount);
37270 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37271 + KLIPS_PRINT(debug_xform,
37272 + ", hnext=%s",
37273 + sa_len ? sa : " (error)");
37274 + }
37275 + if(*ipsprev != NULL) {
37276 + sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
37277 + KLIPS_PRINT(debug_xform,
37278 + ", *ipsprev=%s",
37279 + sa_len ? sa : " (error)");
37280 + if((*ipsprev)->ips_hnext) {
37281 + sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
37282 + KLIPS_PRINT(debug_xform,
37283 + ", *ipsprev->ips_hnext=%s",
37284 + sa_len ? sa : " (error)");
37285 + }
37286 + }
37287 + KLIPS_PRINT(debug_xform,
37288 + ".\n");
37289 + if(proto == 0 || (proto == ipsdel->ips_said.proto)) {
37290 + sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa));
37291 + KLIPS_PRINT(debug_xform,
37292 + "klips_debug:ipsec_sadb_cleanup: "
37293 + "deleting SA chain:%s.\n",
37294 + sa_len ? sa : " (error)");
37295 + if((error = ipsec_sa_delchain(ipsdel))) {
37296 + SENDERR(-error);
37297 + }
37298 + ipsprev = &(ipsec_sadb_hash[i]);
37299 + ips = ipsec_sadb_hash[i];
37300 +
37301 + KLIPS_PRINT(debug_xform,
37302 + "klips_debug:ipsec_sadb_cleanup: "
37303 + "deleted SA chain:%s",
37304 + sa_len ? sa : " (error)");
37305 + if(ips != NULL) {
37306 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37307 + KLIPS_PRINT(debug_xform,
37308 + ", ipsec_sadb_hash[%d]=%s",
37309 + i,
37310 + sa_len ? sa : " (error)");
37311 + }
37312 + if(*ipsprev != NULL) {
37313 + sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
37314 + KLIPS_PRINT(debug_xform,
37315 + ", *ipsprev=%s",
37316 + sa_len ? sa : " (error)");
37317 + if((*ipsprev)->ips_hnext != NULL) {
37318 + sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
37319 + KLIPS_PRINT(debug_xform,
37320 + ", *ipsprev->ips_hnext=%s",
37321 + sa_len ? sa : " (error)");
37322 + }
37323 + }
37324 + KLIPS_PRINT(debug_xform,
37325 + ".\n");
37326 + } else {
37327 + ipsprev = &ipsdel;
37328 + }
37329 + if(ipsdel != NULL) {
37330 + ipsec_sa_put(ipsdel);
37331 + }
37332 + }
37333 + }
37334 + errlab:
37335 +
37336 + spin_unlock_bh(&tdb_lock);
37337 +
37338 +
37339 +#if IPSEC_SA_REF_CODE
37340 + /* clean up SA reference table */
37341 +
37342 + /* go through the ref table and clean out all the SAs */
37343 + KLIPS_PRINT(debug_xform,
37344 + "klips_debug:ipsec_sadb_cleanup: "
37345 + "removing SAref entries and tables.");
37346 + {
37347 + unsigned table, entry;
37348 + for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
37349 + KLIPS_PRINT(debug_xform,
37350 + "klips_debug:ipsec_sadb_cleanup: "
37351 + "cleaning SAref table=%u.\n",
37352 + table);
37353 + if(ipsec_sadb.refTable[table] == NULL) {
37354 + printk("\n");
37355 + KLIPS_PRINT(debug_xform,
37356 + "klips_debug:ipsec_sadb_cleanup: "
37357 + "cleaned %u used refTables.\n",
37358 + table);
37359 + break;
37360 + }
37361 + for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
37362 + if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
37363 + ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
37364 + ipsec_sadb.refTable[table]->entry[entry] = NULL;
37365 + }
37366 + }
37367 + }
37368 + }
37369 +#endif /* IPSEC_SA_REF_CODE */
37370 +
37371 + return(error);
37372 +}
37373 +
37374 +int
37375 +ipsec_sadb_free(void)
37376 +{
37377 + int error = 0;
37378 +
37379 + KLIPS_PRINT(debug_xform,
37380 + "klips_debug:ipsec_sadb_free: "
37381 + "freeing SArefTable memory.\n");
37382 +
37383 + /* clean up SA reference table */
37384 +
37385 + /* go through the ref table and clean out all the SAs if any are
37386 + left and free table memory */
37387 + KLIPS_PRINT(debug_xform,
37388 + "klips_debug:ipsec_sadb_free: "
37389 + "removing SAref entries and tables.\n");
37390 + {
37391 + unsigned table, entry;
37392 + for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
37393 + KLIPS_PRINT(debug_xform,
37394 + "klips_debug:ipsec_sadb_free: "
37395 + "removing SAref table=%u.\n",
37396 + table);
37397 + if(ipsec_sadb.refTable[table] == NULL) {
37398 + KLIPS_PRINT(debug_xform,
37399 + "klips_debug:ipsec_sadb_free: "
37400 + "removed %u used refTables.\n",
37401 + table);
37402 + break;
37403 + }
37404 + for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
37405 + if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
37406 + ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
37407 + ipsec_sadb.refTable[table]->entry[entry] = NULL;
37408 + }
37409 + }
37410 + vfree(ipsec_sadb.refTable[table]);
37411 + ipsec_sadb.refTable[table] = NULL;
37412 + }
37413 + }
37414 +
37415 + return(error);
37416 +}
37417 +
37418 +int
37419 +ipsec_sa_wipe(struct ipsec_sa *ips)
37420 +{
37421 + if(ips == NULL) {
37422 + return -ENODATA;
37423 + }
37424 +
37425 + /* if(atomic_dec_and_test(ips)) {
37426 + }; */
37427 +
37428 +#if IPSEC_SA_REF_CODE
37429 + /* remove me from the SArefTable */
37430 + {
37431 + char sa[SATOT_BUF];
37432 + size_t sa_len;
37433 + sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
37434 + KLIPS_PRINT(debug_xform,
37435 + "klips_debug:ipsec_sa_wipe: "
37436 + "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
37437 + sa_len ? sa : " (error)",
37438 + ips,
37439 + ips->ips_ref,
37440 + IPsecSAref2table(IPsecSA2SAref(ips)),
37441 + ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
37442 + IPsecSAref2entry(IPsecSA2SAref(ips)));
37443 + }
37444 + if(ips->ips_ref == IPSEC_SAREF_NULL) {
37445 + KLIPS_PRINT(debug_xform,
37446 + "klips_debug:ipsec_sa_wipe: "
37447 + "why does this SA not have a valid SAref?.\n");
37448 + }
37449 + ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
37450 + ips->ips_ref = IPSEC_SAREF_NULL;
37451 + ipsec_sa_put(ips);
37452 +#endif /* IPSEC_SA_REF_CODE */
37453 +
37454 + /* paranoid clean up */
37455 + if(ips->ips_addr_s != NULL) {
37456 + memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
37457 + kfree(ips->ips_addr_s);
37458 + }
37459 + ips->ips_addr_s = NULL;
37460 +
37461 + if(ips->ips_addr_d != NULL) {
37462 + memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
37463 + kfree(ips->ips_addr_d);
37464 + }
37465 + ips->ips_addr_d = NULL;
37466 +
37467 + if(ips->ips_addr_p != NULL) {
37468 + memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
37469 + kfree(ips->ips_addr_p);
37470 + }
37471 + ips->ips_addr_p = NULL;
37472 +
37473 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
37474 + if(ips->ips_natt_oa) {
37475 + memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
37476 + kfree(ips->ips_natt_oa);
37477 + }
37478 + ips->ips_natt_oa = NULL;
37479 +#endif
37480 +
37481 + if(ips->ips_key_a != NULL) {
37482 + memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
37483 + kfree(ips->ips_key_a);
37484 + }
37485 + ips->ips_key_a = NULL;
37486 +
37487 + if(ips->ips_key_e != NULL) {
37488 + if (ips->ips_alg_enc &&
37489 + ips->ips_alg_enc->ixt_e_destroy_key)
37490 + {
37491 + ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
37492 + ips->ips_key_e);
37493 + } else
37494 + {
37495 + memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
37496 + kfree(ips->ips_key_e);
37497 + }
37498 + }
37499 + ips->ips_key_e = NULL;
37500 +
37501 + if(ips->ips_iv != NULL) {
37502 + memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
37503 + kfree(ips->ips_iv);
37504 + }
37505 + ips->ips_iv = NULL;
37506 +
37507 + if(ips->ips_ident_s.data != NULL) {
37508 + memset((caddr_t)(ips->ips_ident_s.data),
37509 + 0,
37510 + ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37511 + kfree(ips->ips_ident_s.data);
37512 + }
37513 + ips->ips_ident_s.data = NULL;
37514 +
37515 + if(ips->ips_ident_d.data != NULL) {
37516 + memset((caddr_t)(ips->ips_ident_d.data),
37517 + 0,
37518 + ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
37519 + kfree(ips->ips_ident_d.data);
37520 + }
37521 + ips->ips_ident_d.data = NULL;
37522 +
37523 + if (ips->ips_alg_enc||ips->ips_alg_auth) {
37524 + ipsec_alg_sa_wipe(ips);
37525 + }
37526 +
37527 + memset((caddr_t)ips, 0, sizeof(*ips));
37528 + kfree(ips);
37529 + ips = NULL;
37530 +
37531 + return 0;
37532 +}
37533 +
37534 +extern int sysctl_ipsec_debug_verbose;
37535 +
37536 +int ipsec_sa_init(struct ipsec_sa *ipsp)
37537 +{
37538 + int i;
37539 + int error = 0;
37540 + char sa[SATOT_BUF];
37541 + size_t sa_len;
37542 + char ipaddr_txt[ADDRTOA_BUF];
37543 + char ipaddr2_txt[ADDRTOA_BUF];
37544 +#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37545 + unsigned char kb[AHMD596_BLKLEN];
37546 +#endif
37547 + struct ipsec_alg_enc *ixt_e = NULL;
37548 + struct ipsec_alg_auth *ixt_a = NULL;
37549 +
37550 + if(ipsp == NULL) {
37551 + KLIPS_PRINT(debug_pfkey,
37552 + "ipsec_sa_init: "
37553 + "ipsp is NULL, fatal\n");
37554 + SENDERR(EINVAL);
37555 + }
37556 +
37557 + sa_len = satot(&ipsp->ips_said, 0, sa, sizeof(sa));
37558 +
37559 + KLIPS_PRINT(debug_pfkey,
37560 + "ipsec_sa_init: "
37561 + "(pfkey defined) called for SA:%s\n",
37562 + sa_len ? sa : " (error)");
37563 +
37564 + KLIPS_PRINT(debug_pfkey,
37565 + "ipsec_sa_init: "
37566 + "calling init routine of %s%s%s\n",
37567 + IPS_XFORM_NAME(ipsp));
37568 +
37569 + switch(ipsp->ips_said.proto) {
37570 +
37571 +#ifdef CONFIG_KLIPS_IPIP
37572 + case IPPROTO_IPIP: {
37573 + addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
37574 + 0,
37575 + ipaddr_txt, sizeof(ipaddr_txt));
37576 + addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
37577 + 0,
37578 + ipaddr2_txt, sizeof(ipaddr_txt));
37579 + KLIPS_PRINT(debug_pfkey,
37580 + "ipsec_sa_init: "
37581 + "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
37582 + ipaddr_txt,
37583 + ipaddr2_txt);
37584 + }
37585 + break;
37586 +#endif /* !CONFIG_KLIPS_IPIP */
37587 +
37588 +#ifdef CONFIG_KLIPS_AH
37589 + case IPPROTO_AH:
37590 + switch(ipsp->ips_authalg) {
37591 +# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37592 + case AH_MD5: {
37593 + unsigned char *akp;
37594 + unsigned int aks;
37595 + MD5_CTX *ictx;
37596 + MD5_CTX *octx;
37597 +
37598 + if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37599 + KLIPS_PRINT(debug_pfkey,
37600 + "ipsec_sa_init: "
37601 + "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37602 + ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
37603 + SENDERR(EINVAL);
37604 + }
37605 +
37606 +# if KLIPS_DIVULGE_HMAC_KEY
37607 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37608 + "ipsec_sa_init: "
37609 + "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37610 + ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37611 + ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37612 + ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37613 + ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37614 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37615 +
37616 + ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37617 +
37618 + /* save the pointer to the key material */
37619 + akp = ipsp->ips_key_a;
37620 + aks = ipsp->ips_key_a_size;
37621 +
37622 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37623 + "ipsec_sa_init: "
37624 + "allocating %lu bytes for md5_ctx.\n",
37625 + (unsigned long) sizeof(struct md5_ctx));
37626 + if((ipsp->ips_key_a = (caddr_t)
37627 + kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37628 + ipsp->ips_key_a = akp;
37629 + SENDERR(ENOMEM);
37630 + }
37631 + ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37632 +
37633 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37634 + kb[i] = akp[i] ^ HMAC_IPAD;
37635 + }
37636 + for (; i < AHMD596_BLKLEN; i++) {
37637 + kb[i] = HMAC_IPAD;
37638 + }
37639 +
37640 + ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37641 + osMD5Init(ictx);
37642 + osMD5Update(ictx, kb, AHMD596_BLKLEN);
37643 +
37644 + for (i = 0; i < AHMD596_BLKLEN; i++) {
37645 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37646 + }
37647 +
37648 + octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37649 + osMD5Init(octx);
37650 + osMD5Update(octx, kb, AHMD596_BLKLEN);
37651 +
37652 +# if KLIPS_DIVULGE_HMAC_KEY
37653 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37654 + "ipsec_sa_init: "
37655 + "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37656 + ((__u32*)ictx)[0],
37657 + ((__u32*)ictx)[1],
37658 + ((__u32*)ictx)[2],
37659 + ((__u32*)ictx)[3],
37660 + ((__u32*)octx)[0],
37661 + ((__u32*)octx)[1],
37662 + ((__u32*)octx)[2],
37663 + ((__u32*)octx)[3] );
37664 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37665 +
37666 + /* zero key buffer -- paranoid */
37667 + memset(akp, 0, aks);
37668 + kfree(akp);
37669 + }
37670 + break;
37671 +# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37672 +# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37673 + case AH_SHA: {
37674 + unsigned char *akp;
37675 + unsigned int aks;
37676 + SHA1_CTX *ictx;
37677 + SHA1_CTX *octx;
37678 +
37679 + if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37680 + KLIPS_PRINT(debug_pfkey,
37681 + "ipsec_sa_init: "
37682 + "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37683 + ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
37684 + SENDERR(EINVAL);
37685 + }
37686 +
37687 +# if KLIPS_DIVULGE_HMAC_KEY
37688 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37689 + "ipsec_sa_init: "
37690 + "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37691 + ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37692 + ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37693 + ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37694 + ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37695 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37696 +
37697 + ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37698 +
37699 + /* save the pointer to the key material */
37700 + akp = ipsp->ips_key_a;
37701 + aks = ipsp->ips_key_a_size;
37702 +
37703 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37704 + "ipsec_sa_init: "
37705 + "allocating %lu bytes for sha1_ctx.\n",
37706 + (unsigned long) sizeof(struct sha1_ctx));
37707 + if((ipsp->ips_key_a = (caddr_t)
37708 + kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37709 + ipsp->ips_key_a = akp;
37710 + SENDERR(ENOMEM);
37711 + }
37712 + ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37713 +
37714 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37715 + kb[i] = akp[i] ^ HMAC_IPAD;
37716 + }
37717 + for (; i < AHMD596_BLKLEN; i++) {
37718 + kb[i] = HMAC_IPAD;
37719 + }
37720 +
37721 + ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37722 + SHA1Init(ictx);
37723 + SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37724 +
37725 + for (i = 0; i < AHSHA196_BLKLEN; i++) {
37726 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37727 + }
37728 +
37729 + octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
37730 + SHA1Init(octx);
37731 + SHA1Update(octx, kb, AHSHA196_BLKLEN);
37732 +
37733 +# if KLIPS_DIVULGE_HMAC_KEY
37734 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37735 + "ipsec_sa_init: "
37736 + "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37737 + ((__u32*)ictx)[0],
37738 + ((__u32*)ictx)[1],
37739 + ((__u32*)ictx)[2],
37740 + ((__u32*)ictx)[3],
37741 + ((__u32*)octx)[0],
37742 + ((__u32*)octx)[1],
37743 + ((__u32*)octx)[2],
37744 + ((__u32*)octx)[3] );
37745 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37746 + /* zero key buffer -- paranoid */
37747 + memset(akp, 0, aks);
37748 + kfree(akp);
37749 + }
37750 + break;
37751 +# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37752 + default:
37753 + KLIPS_PRINT(debug_pfkey,
37754 + "ipsec_sa_init: "
37755 + "authalg=%d support not available in the kernel",
37756 + ipsp->ips_authalg);
37757 + SENDERR(EINVAL);
37758 + }
37759 + break;
37760 +#endif /* CONFIG_KLIPS_AH */
37761 +
37762 +#ifdef CONFIG_KLIPS_ESP
37763 + case IPPROTO_ESP:
37764 + {
37765 +#if defined (CONFIG_KLIPS_AUTH_HMAC_MD5) || defined (CONFIG_KLIPS_AUTH_HMAC_SHA1)
37766 + unsigned char *akp;
37767 + unsigned int aks;
37768 +#endif
37769 +
37770 + ipsec_alg_sa_init(ipsp);
37771 + ixt_e=ipsp->ips_alg_enc;
37772 +
37773 + if (ixt_e == NULL) {
37774 + if(printk_ratelimit()) {
37775 + printk(KERN_INFO
37776 + "ipsec_sa_init: "
37777 + "encalg=%d support not available in the kernel",
37778 + ipsp->ips_encalg);
37779 + }
37780 + SENDERR(ENOENT);
37781 + }
37782 +
37783 + ipsp->ips_iv_size = ixt_e->ixt_common.ixt_support.ias_ivlen/8;
37784 +
37785 + /* Create IV */
37786 + if (ipsp->ips_iv_size) {
37787 + if((ipsp->ips_iv = (caddr_t)
37788 + kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) {
37789 + SENDERR(ENOMEM);
37790 + }
37791 + prng_bytes(&ipsec_prng,
37792 + (char *)ipsp->ips_iv,
37793 + ipsp->ips_iv_size);
37794 + ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
37795 + }
37796 +
37797 + if ((error=ipsec_alg_enc_key_create(ipsp)) < 0)
37798 + SENDERR(-error);
37799 +
37800 + if ((ixt_a=ipsp->ips_alg_auth)) {
37801 + if ((error=ipsec_alg_auth_key_create(ipsp)) < 0)
37802 + SENDERR(-error);
37803 + } else
37804 +
37805 + switch(ipsp->ips_authalg) {
37806 +# ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
37807 + case AH_MD5: {
37808 + MD5_CTX *ictx;
37809 + MD5_CTX *octx;
37810 +
37811 + if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
37812 + KLIPS_PRINT(debug_pfkey,
37813 + "ipsec_sa_init: "
37814 + "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37815 + ipsp->ips_key_bits_a,
37816 + AHMD596_KLEN * 8);
37817 + SENDERR(EINVAL);
37818 + }
37819 +
37820 +# if KLIPS_DIVULGE_HMAC_KEY
37821 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37822 + "ipsec_sa_init: "
37823 + "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
37824 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
37825 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
37826 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
37827 + ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
37828 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37829 + ipsp->ips_auth_bits = AHMD596_ALEN * 8;
37830 +
37831 + /* save the pointer to the key material */
37832 + akp = ipsp->ips_key_a;
37833 + aks = ipsp->ips_key_a_size;
37834 +
37835 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37836 + "ipsec_sa_init: "
37837 + "allocating %lu bytes for md5_ctx.\n",
37838 + (unsigned long) sizeof(struct md5_ctx));
37839 + if((ipsp->ips_key_a = (caddr_t)
37840 + kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
37841 + ipsp->ips_key_a = akp;
37842 + SENDERR(ENOMEM);
37843 + }
37844 + ipsp->ips_key_a_size = sizeof(struct md5_ctx);
37845 +
37846 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37847 + kb[i] = akp[i] ^ HMAC_IPAD;
37848 + }
37849 + for (; i < AHMD596_BLKLEN; i++) {
37850 + kb[i] = HMAC_IPAD;
37851 + }
37852 +
37853 + ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
37854 + osMD5Init(ictx);
37855 + osMD5Update(ictx, kb, AHMD596_BLKLEN);
37856 +
37857 + for (i = 0; i < AHMD596_BLKLEN; i++) {
37858 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37859 + }
37860 +
37861 + octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
37862 + osMD5Init(octx);
37863 + osMD5Update(octx, kb, AHMD596_BLKLEN);
37864 +
37865 +# if KLIPS_DIVULGE_HMAC_KEY
37866 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37867 + "ipsec_sa_init: "
37868 + "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37869 + ((__u32*)ictx)[0],
37870 + ((__u32*)ictx)[1],
37871 + ((__u32*)ictx)[2],
37872 + ((__u32*)ictx)[3],
37873 + ((__u32*)octx)[0],
37874 + ((__u32*)octx)[1],
37875 + ((__u32*)octx)[2],
37876 + ((__u32*)octx)[3] );
37877 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37878 + /* paranoid */
37879 + memset(akp, 0, aks);
37880 + kfree(akp);
37881 + break;
37882 + }
37883 +# endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
37884 +# ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
37885 + case AH_SHA: {
37886 + SHA1_CTX *ictx;
37887 + SHA1_CTX *octx;
37888 +
37889 + if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
37890 + KLIPS_PRINT(debug_pfkey,
37891 + "ipsec_sa_init: "
37892 + "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
37893 + ipsp->ips_key_bits_a,
37894 + AHSHA196_KLEN * 8);
37895 + SENDERR(EINVAL);
37896 + }
37897 +
37898 +# if KLIPS_DIVULGE_HMAC_KEY
37899 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37900 + "ipsec_sa_init: "
37901 + "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
37902 + ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
37903 + ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
37904 + ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
37905 + ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
37906 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37907 + ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
37908 +
37909 + /* save the pointer to the key material */
37910 + akp = ipsp->ips_key_a;
37911 + aks = ipsp->ips_key_a_size;
37912 +
37913 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37914 + "ipsec_sa_init: "
37915 + "allocating %lu bytes for sha1_ctx.\n",
37916 + (unsigned long) sizeof(struct sha1_ctx));
37917 + if((ipsp->ips_key_a = (caddr_t)
37918 + kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
37919 + ipsp->ips_key_a = akp;
37920 + SENDERR(ENOMEM);
37921 + }
37922 + ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
37923 +
37924 + for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
37925 + kb[i] = akp[i] ^ HMAC_IPAD;
37926 + }
37927 + for (; i < AHMD596_BLKLEN; i++) {
37928 + kb[i] = HMAC_IPAD;
37929 + }
37930 +
37931 + ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
37932 + SHA1Init(ictx);
37933 + SHA1Update(ictx, kb, AHSHA196_BLKLEN);
37934 +
37935 + for (i = 0; i < AHSHA196_BLKLEN; i++) {
37936 + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
37937 + }
37938 +
37939 + octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
37940 + SHA1Init(octx);
37941 + SHA1Update(octx, kb, AHSHA196_BLKLEN);
37942 +
37943 +# if KLIPS_DIVULGE_HMAC_KEY
37944 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
37945 + "ipsec_sa_init: "
37946 + "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
37947 + ((__u32*)ictx)[0],
37948 + ((__u32*)ictx)[1],
37949 + ((__u32*)ictx)[2],
37950 + ((__u32*)ictx)[3],
37951 + ((__u32*)octx)[0],
37952 + ((__u32*)octx)[1],
37953 + ((__u32*)octx)[2],
37954 + ((__u32*)octx)[3] );
37955 +# endif /* KLIPS_DIVULGE_HMAC_KEY */
37956 + memset(akp, 0, aks);
37957 + kfree(akp);
37958 + break;
37959 + }
37960 +# endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
37961 + case AH_NONE:
37962 + break;
37963 + default:
37964 + KLIPS_PRINT(debug_pfkey,
37965 + "ipsec_sa_init: "
37966 + "authalg=%d support not available in the kernel.\n",
37967 + ipsp->ips_authalg);
37968 + SENDERR(EINVAL);
37969 + }
37970 + }
37971 + break;
37972 +#endif /* !CONFIG_KLIPS_ESP */
37973 +#ifdef CONFIG_KLIPS_IPCOMP
37974 + case IPPROTO_COMP:
37975 + ipsp->ips_comp_adapt_tries = 0;
37976 + ipsp->ips_comp_adapt_skip = 0;
37977 + ipsp->ips_comp_ratio_cbytes = 0;
37978 + ipsp->ips_comp_ratio_dbytes = 0;
37979 + break;
37980 +#endif /* CONFIG_KLIPS_IPCOMP */
37981 + default:
37982 + printk(KERN_ERR "KLIPS sa initialization: "
37983 + "proto=%d unknown.\n",
37984 + ipsp->ips_said.proto);
37985 + SENDERR(EINVAL);
37986 + }
37987 +
37988 + errlab:
37989 + return(error);
37990 +}
37991 +
37992 +
37993 +
37994 +/*
37995 + * $Log: ipsec_sa.c,v $
37996 + * Revision 1.30.2.2 2006/10/06 21:39:26 paul
37997 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
37998 + * set. This is defined through autoconf.h which is included through the
37999 + * linux kernel build macros.
38000 + *
38001 + * Revision 1.30.2.1 2006/04/20 16:33:07 mcr
38002 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
38003 + * Fix in-kernel module compilation. Sub-makefiles do not work.
38004 + *
38005 + * Revision 1.30 2005/05/24 01:02:35 mcr
38006 + * some refactoring/simplification of situation where alg
38007 + * is not found.
38008 + *
38009 + * Revision 1.29 2005/05/18 19:13:28 mcr
38010 + * rename debug messages. make sure that algo not found is not
38011 + * a debug message.
38012 + *
38013 + * Revision 1.28 2005/05/11 01:30:20 mcr
38014 + * removed "poor-man"s OOP in favour of proper C structures.
38015 + *
38016 + * Revision 1.27 2005/04/29 05:10:22 mcr
38017 + * removed from extraenous includes to make unit testing easier.
38018 + *
38019 + * Revision 1.26 2005/04/14 20:56:24 mcr
38020 + * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
38021 + *
38022 + * Revision 1.25 2004/08/22 20:12:16 mcr
38023 + * one more KLIPS_NAT->IPSEC_NAT.
38024 + *
38025 + * Revision 1.24 2004/07/10 19:11:18 mcr
38026 + * CONFIG_IPSEC -> CONFIG_KLIPS.
38027 + *
38028 + * Revision 1.23 2004/04/06 02:49:26 mcr
38029 + * pullup of algo code from alg-branch.
38030 + *
38031 + * Revision 1.22.2.1 2003/12/22 15:25:52 jjo
38032 + * . Merged algo-0.8.1-rc11-test1 into alg-branch
38033 + *
38034 + * Revision 1.22 2003/12/10 01:14:27 mcr
38035 + * NAT-traversal patches to KLIPS.
38036 + *
38037 + * Revision 1.21 2003/10/31 02:27:55 mcr
38038 + * pulled up port-selector patches and sa_id elimination.
38039 + *
38040 + * Revision 1.20.4.1 2003/10/29 01:30:41 mcr
38041 + * elimited "struct sa_id".
38042 + *
38043 + * Revision 1.20 2003/02/06 01:50:34 rgb
38044 + * Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0.
38045 + *
38046 + * Revision 1.19 2003/01/30 02:32:22 rgb
38047 + *
38048 + * Rename SAref table macro names for clarity.
38049 + * Transmit error code through to caller from callee for better diagnosis of problems.
38050 + * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
38051 + *
38052 + * Revision 1.18 2002/10/12 23:11:53 dhr
38053 + *
38054 + * [KenB + DHR] more 64-bit cleanup
38055 + *
38056 + * Revision 1.17 2002/10/07 18:31:43 rgb
38057 + * Move field width sanity checks to ipsec_sa.c
38058 + *
38059 + * Revision 1.16 2002/09/20 15:41:02 rgb
38060 + * Re-wrote most of the SAref code to eliminate Entry pointers.
38061 + * Added SAref code compiler directive switch.
38062 + * Added a saref test function for testing macros.
38063 + * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
38064 + * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
38065 + * of freeing newly created structures when clearing the reftable upon startup
38066 + * to start from a known state.
38067 + * Place all ipsec sadb globals into one struct.
38068 + * Rework saref freelist.
38069 + * Added memory allocation debugging.
38070 + *
38071 + * Revision 1.15 2002/09/20 05:01:44 rgb
38072 + * Update copyright date.
38073 + *
38074 + * Revision 1.14 2002/08/13 19:01:25 mcr
38075 + * patches from kenb to permit compilation of FreeSWAN on ia64.
38076 + * des library patched to use proper DES_LONG type for ia64.
38077 + *
38078 + * Revision 1.13 2002/07/29 03:06:20 mcr
38079 + * get rid of variable not used warnings.
38080 + *
38081 + * Revision 1.12 2002/07/26 08:48:31 rgb
38082 + * Added SA ref table code.
38083 + *
38084 + * Revision 1.11 2002/06/04 16:48:49 rgb
38085 + * Tidied up pointer code for processor independance.
38086 + *
38087 + * Revision 1.10 2002/05/23 07:16:17 rgb
38088 + * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
38089 + * Pointer clean-up.
38090 + * Added refcount code.
38091 + * Convert "usecount" to "refcount" to remove ambiguity.
38092 + *
38093 + * Revision 1.9 2002/05/14 02:34:49 rgb
38094 + * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
38095 + * with "put" usage in the kernel.
38096 + * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
38097 + * ipsec_sa or ipsec_sa.
38098 + * Added some preliminary refcount code.
38099 + *
38100 + * Revision 1.8 2002/04/24 07:55:32 mcr
38101 + * #include patches and Makefiles for post-reorg compilation.
38102 + *
38103 + * Revision 1.7 2002/04/24 07:36:30 mcr
38104 + * Moved from ./klips/net/ipsec/ipsec_sa.c,v
38105 + *
38106 + * Revision 1.6 2002/04/20 00:12:25 rgb
38107 + * Added esp IV CBC attack fix, disabled.
38108 + *
38109 + * Revision 1.5 2002/01/29 17:17:56 mcr
38110 + * moved include of ipsec_param.h to after include of linux/kernel.h
38111 + * otherwise, it seems that some option that is set in ipsec_param.h
38112 + * screws up something subtle in the include path to kernel.h, and
38113 + * it complains on the snprintf() prototype.
38114 + *
38115 + * Revision 1.4 2002/01/29 04:00:52 mcr
38116 + * more excise of kversions.h header.
38117 + *
38118 + * Revision 1.3 2002/01/29 02:13:18 mcr
38119 + * introduction of ipsec_kversion.h means that include of
38120 + * ipsec_param.h must preceed any decisions about what files to
38121 + * include to deal with differences in kernel source.
38122 + *
38123 + * Revision 1.2 2001/11/26 09:16:15 rgb
38124 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
38125 + *
38126 + * Revision 1.1.2.2 2001/10/22 21:05:41 mcr
38127 + * removed phony prototype for des_set_key.
38128 + *
38129 + * Revision 1.1.2.1 2001/09/25 02:24:57 mcr
38130 + * struct tdb -> struct ipsec_sa.
38131 + * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
38132 + * ipsec_xform.c removed. header file still contains useful things.
38133 + *
38134 + *
38135 + *
38136 + * CLONED from ipsec_xform.c:
38137 + * Revision 1.53 2001/09/08 21:13:34 rgb
38138 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
38139 + *
38140 + * Revision 1.52 2001/06/14 19:35:11 rgb
38141 + * Update copyright date.
38142 + *
38143 + * Revision 1.51 2001/05/30 08:14:03 rgb
38144 + * Removed vestiges of esp-null transforms.
38145 + *
38146 + * Revision 1.50 2001/05/03 19:43:18 rgb
38147 + * Initialise error return variable.
38148 + * Update SENDERR macro.
38149 + * Fix sign of error return code for ipsec_tdbcleanup().
38150 + * Use more appropriate return code for ipsec_tdbwipe().
38151 + *
38152 + * Revision 1.49 2001/04/19 18:56:17 rgb
38153 + * Fixed tdb table locking comments.
38154 + *
38155 + * Revision 1.48 2001/02/27 22:24:55 rgb
38156 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
38157 + * Check for satoa() return codes.
38158 + *
38159 + * Revision 1.47 2000/11/06 04:32:08 rgb
38160 + * Ditched spin_lock_irqsave in favour of spin_lock_bh.
38161 + *
38162 + * Revision 1.46 2000/09/20 16:21:57 rgb
38163 + * Cleaned up ident string alloc/free.
38164 + *
38165 + * Revision 1.45 2000/09/08 19:16:51 rgb
38166 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
38167 + * Removed all references to CONFIG_IPSEC_PFKEYv2.
38168 + *
38169 + * Revision 1.44 2000/08/30 05:29:04 rgb
38170 + * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
38171 + *
38172 + * Revision 1.43 2000/08/18 21:30:41 rgb
38173 + * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
38174 + *
38175 + * Revision 1.42 2000/08/01 14:51:51 rgb
38176 + * Removed _all_ remaining traces of DES.
38177 + *
38178 + * Revision 1.41 2000/07/28 14:58:31 rgb
38179 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
38180 + *
38181 + * Revision 1.40 2000/06/28 05:50:11 rgb
38182 + * Actually set iv_bits.
38183 + *
38184 + * Revision 1.39 2000/05/10 23:11:09 rgb
38185 + * Added netlink debugging output.
38186 + * Added a cast to quiet down the ntohl bug.
38187 + *
38188 + * Revision 1.38 2000/05/10 19:18:42 rgb
38189 + * Cast output of ntohl so that the broken prototype doesn't make our
38190 + * compile noisy.
38191 + *
38192 + * Revision 1.37 2000/03/16 14:04:59 rgb
38193 + * Hardwired CONFIG_IPSEC_PFKEYv2 on.
38194 + *
38195 + * Revision 1.36 2000/01/26 10:11:28 rgb
38196 + * Fixed spacing in error text causing run-in words.
38197 + *
38198 + * Revision 1.35 2000/01/21 06:17:16 rgb
38199 + * Tidied up compiler directive indentation for readability.
38200 + * Added ictx,octx vars for simplification.(kravietz)
38201 + * Added macros for HMAC padding magic numbers.(kravietz)
38202 + * Fixed missing key length reporting bug.
38203 + * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
38204 + *
38205 + * Revision 1.34 1999/12/08 00:04:19 rgb
38206 + * Fixed SA direction overwriting bug for netlink users.
38207 + *
38208 + * Revision 1.33 1999/12/01 22:16:44 rgb
38209 + * Minor formatting changes in ESP MD5 initialisation.
38210 + *
38211 + * Revision 1.32 1999/11/25 09:06:36 rgb
38212 + * Fixed error return messages, should be returning negative numbers.
38213 + * Implemented SENDERR macro for propagating error codes.
38214 + * Added debug message and separate error code for algorithms not compiled
38215 + * in.
38216 + *
38217 + * Revision 1.31 1999/11/23 23:06:26 rgb
38218 + * Sort out pfkey and freeswan headers, putting them in a library path.
38219 + *
38220 + * Revision 1.30 1999/11/18 04:09:20 rgb
38221 + * Replaced all kernel version macros to shorter, readable form.
38222 + *
38223 + * Revision 1.29 1999/11/17 15:53:40 rgb
38224 + * Changed all occurrences of #include "../../../lib/freeswan.h"
38225 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
38226 + * klips/net/ipsec/Makefile.
38227 + *
38228 + * Revision 1.28 1999/10/18 20:04:01 rgb
38229 + * Clean-out unused cruft.
38230 + *
38231 + * Revision 1.27 1999/10/03 19:01:03 rgb
38232 + * Spinlock support for 2.3.xx and 2.0.xx kernels.
38233 + *
38234 + * Revision 1.26 1999/10/01 16:22:24 rgb
38235 + * Switch from assignment init. to functional init. of spinlocks.
38236 + *
38237 + * Revision 1.25 1999/10/01 15:44:54 rgb
38238 + * Move spinlock header include to 2.1> scope.
38239 + *
38240 + * Revision 1.24 1999/10/01 00:03:46 rgb
38241 + * Added tdb structure locking.
38242 + * Minor formatting changes.
38243 + * Add function to initialize tdb hash table.
38244 + *
38245 + * Revision 1.23 1999/05/25 22:42:12 rgb
38246 + * Add deltdbchain() debugging.
38247 + *
38248 + * Revision 1.22 1999/05/25 21:24:31 rgb
38249 + * Add debugging statements to deltdbchain().
38250 + *
38251 + * Revision 1.21 1999/05/25 03:51:48 rgb
38252 + * Refix error return code.
38253 + *
38254 + * Revision 1.20 1999/05/25 03:34:07 rgb
38255 + * Fix error return for flush.
38256 + *
38257 + * Revision 1.19 1999/05/09 03:25:37 rgb
38258 + * Fix bug introduced by 2.2 quick-and-dirty patch.
38259 + *
38260 + * Revision 1.18 1999/05/05 22:02:32 rgb
38261 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
38262 + *
38263 + * Revision 1.17 1999/04/29 15:20:16 rgb
38264 + * Change gettdb parameter to a pointer to reduce stack loading and
38265 + * facilitate parameter sanity checking.
38266 + * Add sanity checking for null pointer arguments.
38267 + * Add debugging instrumentation.
38268 + * Add function deltdbchain() which will take care of unlinking,
38269 + * zeroing and deleting a chain of tdbs.
38270 + * Add a parameter to tdbcleanup to be able to delete a class of SAs.
38271 + * tdbwipe now actually zeroes the tdb as well as any of its pointed
38272 + * structures.
38273 + *
38274 + * Revision 1.16 1999/04/16 15:36:29 rgb
38275 + * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
38276 + *
38277 + * Revision 1.15 1999/04/11 00:29:01 henry
38278 + * GPL boilerplate
38279 + *
38280 + * Revision 1.14 1999/04/06 04:54:28 rgb
38281 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
38282 + * patch shell fixes.
38283 + *
38284 + * Revision 1.13 1999/02/19 18:23:01 rgb
38285 + * Nix debug off compile warning.
38286 + *
38287 + * Revision 1.12 1999/02/17 16:52:16 rgb
38288 + * Consolidate satoa()s for space and speed efficiency.
38289 + * Convert DEBUG_IPSEC to KLIPS_PRINT
38290 + * Clean out unused cruft.
38291 + * Ditch NET_IPIP dependancy.
38292 + * Loop for 3des key setting.
38293 + *
38294 + * Revision 1.11 1999/01/26 02:09:05 rgb
38295 + * Remove ah/esp/IPIP switching on include files.
38296 + * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
38297 + * Removed dead code.
38298 + * Clean up debug code when switched off.
38299 + * Remove references to INET_GET_PROTOCOL.
38300 + * Added code exclusion macros to reduce code from unused algorithms.
38301 + *
38302 + * Revision 1.10 1999/01/22 06:28:55 rgb
38303 + * Cruft clean-out.
38304 + * Put random IV generation in kernel.
38305 + * Added algorithm switch code.
38306 + * Enhanced debugging.
38307 + * 64-bit clean-up.
38308 + *
38309 + * Revision 1.9 1998/11/30 13:22:55 rgb
38310 + * Rationalised all the klips kernel file headers. They are much shorter
38311 + * now and won't conflict under RH5.2.
38312 + *
38313 + * Revision 1.8 1998/11/25 04:59:06 rgb
38314 + * Add conditionals for no IPIP tunnel code.
38315 + * Delete commented out code.
38316 + *
38317 + * Revision 1.7 1998/10/31 06:50:41 rgb
38318 + * Convert xform ASCII names to no spaces.
38319 + * Fixed up comments in #endif directives.
38320 + *
38321 + * Revision 1.6 1998/10/19 14:44:28 rgb
38322 + * Added inclusion of freeswan.h.
38323 + * sa_id structure implemented and used: now includes protocol.
38324 + *
38325 + * Revision 1.5 1998/10/09 04:32:19 rgb
38326 + * Added 'klips_debug' prefix to all klips printk debug statements.
38327 + *
38328 + * Revision 1.4 1998/08/12 00:11:31 rgb
38329 + * Added new xform functions to the xform table.
38330 + * Fixed minor debug output spelling error.
38331 + *
38332 + * Revision 1.3 1998/07/09 17:45:31 rgb
38333 + * Clarify algorithm not available message.
38334 + *
38335 + * Revision 1.2 1998/06/23 03:00:51 rgb
38336 + * Check for presence of IPIP protocol if it is setup one way (we don't
38337 + * know what has been set up the other way and can only assume it will be
38338 + * symmetrical with the exception of keys).
38339 + *
38340 + * Revision 1.1 1998/06/18 21:27:51 henry
38341 + * move sources from klips/src to klips/net/ipsec, to keep stupid
38342 + * kernel-build scripts happier in the presence of symlinks
38343 + *
38344 + * Revision 1.3 1998/06/11 05:54:59 rgb
38345 + * Added transform version string pointer to xformsw initialisations.
38346 + *
38347 + * Revision 1.2 1998/04/21 21:28:57 rgb
38348 + * Rearrange debug switches to change on the fly debug output from user
38349 + * space. Only kernel changes checked in at this time. radij.c was also
38350 + * changed to temporarily remove buggy debugging code in rj_delete causing
38351 + * an OOPS and hence, netlink device open errors.
38352 + *
38353 + * Revision 1.1 1998/04/09 03:06:13 henry
38354 + * sources moved up from linux/net/ipsec
38355 + *
38356 + * Revision 1.1.1.1 1998/04/08 05:35:02 henry
38357 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
38358 + *
38359 + * Revision 0.5 1997/06/03 04:24:48 ji
38360 + * Added ESP-3DES-MD5-96
38361 + *
38362 + * Revision 0.4 1997/01/15 01:28:15 ji
38363 + * Added new transforms.
38364 + *
38365 + * Revision 0.3 1996/11/20 14:39:04 ji
38366 + * Minor cleanups.
38367 + * Rationalized debugging code.
38368 + *
38369 + * Revision 0.2 1996/11/02 00:18:33 ji
38370 + * First limited release.
38371 + *
38372 + *
38373 + */
38374 --- /dev/null Tue Mar 11 13:02:56 2003
38375 +++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004
38376 @@ -0,0 +1,219 @@
38377 +/*
38378 + * RCSID $Id: ipsec_sha1.c,v 1.9 2004/04/06 02:49:26 mcr Exp $
38379 + */
38380 +
38381 +/*
38382 + * The rest of the code is derived from sha1.c by Steve Reid, which is
38383 + * public domain.
38384 + * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
38385 + */
38386 +
38387 +#include <asm/byteorder.h>
38388 +#include <linux/string.h>
38389 +
38390 +#include "openswan/ipsec_sha1.h"
38391 +
38392 +#if defined(rol)
38393 +#undef rol
38394 +#endif
38395 +
38396 +#define SHA1HANDSOFF
38397 +
38398 +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
38399 +
38400 +/* blk0() and blk() perform the initial expand. */
38401 +/* I got the idea of expanding during the round function from SSLeay */
38402 +#ifdef __LITTLE_ENDIAN
38403 +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
38404 + |(rol(block->l[i],8)&0x00FF00FF))
38405 +#else
38406 +#define blk0(i) block->l[i]
38407 +#endif
38408 +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
38409 + ^block->l[(i+2)&15]^block->l[i&15],1))
38410 +
38411 +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
38412 +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
38413 +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
38414 +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
38415 +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
38416 +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
38417 +
38418 +
38419 +/* Hash a single 512-bit block. This is the core of the algorithm. */
38420 +
38421 +void SHA1Transform(__u32 state[5], __u8 buffer[64])
38422 +{
38423 +__u32 a, b, c, d, e;
38424 +typedef union {
38425 + unsigned char c[64];
38426 + __u32 l[16];
38427 +} CHAR64LONG16;
38428 +CHAR64LONG16* block;
38429 +#ifdef SHA1HANDSOFF
38430 +static unsigned char workspace[64];
38431 + block = (CHAR64LONG16*)workspace;
38432 + memcpy(block, buffer, 64);
38433 +#else
38434 + block = (CHAR64LONG16*)buffer;
38435 +#endif
38436 + /* Copy context->state[] to working vars */
38437 + a = state[0];
38438 + b = state[1];
38439 + c = state[2];
38440 + d = state[3];
38441 + e = state[4];
38442 + /* 4 rounds of 20 operations each. Loop unrolled. */
38443 + 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);
38444 + 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);
38445 + 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);
38446 + 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);
38447 + 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);
38448 + 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);
38449 + 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);
38450 + 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);
38451 + 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);
38452 + 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);
38453 + 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);
38454 + 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);
38455 + 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);
38456 + 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);
38457 + 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);
38458 + 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);
38459 + 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);
38460 + 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);
38461 + 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);
38462 + 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);
38463 + /* Add the working vars back into context.state[] */
38464 + state[0] += a;
38465 + state[1] += b;
38466 + state[2] += c;
38467 + state[3] += d;
38468 + state[4] += e;
38469 + /* Wipe variables */
38470 + a = b = c = d = e = 0;
38471 +}
38472 +
38473 +
38474 +/* SHA1Init - Initialize new context */
38475 +
38476 +void SHA1Init(void *vcontext)
38477 +{
38478 + SHA1_CTX* context = vcontext;
38479 +
38480 + /* SHA1 initialization constants */
38481 + context->state[0] = 0x67452301;
38482 + context->state[1] = 0xEFCDAB89;
38483 + context->state[2] = 0x98BADCFE;
38484 + context->state[3] = 0x10325476;
38485 + context->state[4] = 0xC3D2E1F0;
38486 + context->count[0] = context->count[1] = 0;
38487 +}
38488 +
38489 +
38490 +/* Run your data through this. */
38491 +
38492 +void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
38493 +{
38494 + SHA1_CTX* context = vcontext;
38495 + __u32 i, j;
38496 +
38497 + j = context->count[0];
38498 + if ((context->count[0] += len << 3) < j)
38499 + context->count[1]++;
38500 + context->count[1] += (len>>29);
38501 + j = (j >> 3) & 63;
38502 + if ((j + len) > 63) {
38503 + memcpy(&context->buffer[j], data, (i = 64-j));
38504 + SHA1Transform(context->state, context->buffer);
38505 + for ( ; i + 63 < len; i += 64) {
38506 + SHA1Transform(context->state, &data[i]);
38507 + }
38508 + j = 0;
38509 + }
38510 + else i = 0;
38511 + memcpy(&context->buffer[j], &data[i], len - i);
38512 +}
38513 +
38514 +
38515 +/* Add padding and return the message digest. */
38516 +
38517 +void SHA1Final(unsigned char digest[20], void *vcontext)
38518 +{
38519 + __u32 i, j;
38520 + unsigned char finalcount[8];
38521 + SHA1_CTX* context = vcontext;
38522 +
38523 + for (i = 0; i < 8; i++) {
38524 + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
38525 + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
38526 + }
38527 + SHA1Update(context, (unsigned char *)"\200", 1);
38528 + while ((context->count[0] & 504) != 448) {
38529 + SHA1Update(context, (unsigned char *)"\0", 1);
38530 + }
38531 + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
38532 + for (i = 0; i < 20; i++) {
38533 + digest[i] = (unsigned char)
38534 + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
38535 + }
38536 + /* Wipe variables */
38537 + i = j = 0;
38538 + memset(context->buffer, 0, 64);
38539 + memset(context->state, 0, 20);
38540 + memset(context->count, 0, 8);
38541 + memset(&finalcount, 0, 8);
38542 +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
38543 + SHA1Transform(context->state, context->buffer);
38544 +#endif
38545 +}
38546 +
38547 +
38548 +/*
38549 + * $Log: ipsec_sha1.c,v $
38550 + * Revision 1.9 2004/04/06 02:49:26 mcr
38551 + * pullup of algo code from alg-branch.
38552 + *
38553 + * Revision 1.8 2002/09/10 01:45:14 mcr
38554 + * changed type of MD5_CTX and SHA1_CTX to void * so that
38555 + * the function prototypes would match, and could be placed
38556 + * into a pointer to a function.
38557 + *
38558 + * Revision 1.7 2002/04/24 07:55:32 mcr
38559 + * #include patches and Makefiles for post-reorg compilation.
38560 + *
38561 + * Revision 1.6 2002/04/24 07:36:30 mcr
38562 + * Moved from ./klips/net/ipsec/ipsec_sha1.c,v
38563 + *
38564 + * Revision 1.5 1999/12/13 13:59:13 rgb
38565 + * Quick fix to argument size to Update bugs.
38566 + *
38567 + * Revision 1.4 1999/04/11 00:29:00 henry
38568 + * GPL boilerplate
38569 + *
38570 + * Revision 1.3 1999/04/06 04:54:27 rgb
38571 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
38572 + * patch shell fixes.
38573 + *
38574 + * Revision 1.2 1999/01/22 06:55:50 rgb
38575 + * 64-bit clean-up.
38576 + *
38577 + * Revision 1.1 1998/06/18 21:27:50 henry
38578 + * move sources from klips/src to klips/net/ipsec, to keep stupid
38579 + * kernel-build scripts happier in the presence of symlinks
38580 + *
38581 + * Revision 1.2 1998/04/23 20:54:04 rgb
38582 + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
38583 + * verified.
38584 + *
38585 + * Revision 1.1 1998/04/09 03:06:11 henry
38586 + * sources moved up from linux/net/ipsec
38587 + *
38588 + * Revision 1.1.1.1 1998/04/08 05:35:05 henry
38589 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
38590 + *
38591 + * Revision 0.4 1997/01/15 01:28:15 ji
38592 + * New transform
38593 + *
38594 + *
38595 + */
38596 --- /dev/null Tue Mar 11 13:02:56 2003
38597 +++ linux/net/ipsec/ipsec_snprintf.c Mon Feb 9 13:51:03 2004
38598 @@ -0,0 +1,135 @@
38599 +/*
38600 + * @(#) ipsec_snprintf() function
38601 + *
38602 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
38603 + * 2001 Michael Richardson <mcr@freeswan.org>
38604 + * Copyright (C) 2005 Michael Richardson <mcr@xelerance.com>
38605 + *
38606 + * This program is free software; you can redistribute it and/or modify it
38607 + * under the terms of the GNU General Public License as published by the
38608 + * Free Software Foundation; either version 2 of the License, or (at your
38609 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
38610 + *
38611 + * This program is distributed in the hope that it will be useful, but
38612 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
38613 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38614 + * for more details.
38615 + *
38616 + * Split out from ipsec_proc.c.
38617 + */
38618 +
38619 +#ifndef AUTOCONF_INCLUDED
38620 +#include <linux/config.h>
38621 +#endif
38622 +#include <linux/version.h>
38623 +#define __NO_VERSION__
38624 +#include <linux/module.h>
38625 +#include <linux/kernel.h> /* printk() */
38626 +
38627 +#include "openswan/ipsec_kversion.h"
38628 +#include "openswan/ipsec_param.h"
38629 +
38630 +#include <net/ip.h>
38631 +
38632 +#include "openswan/radij.h"
38633 +
38634 +#include "openswan/ipsec_life.h"
38635 +#include "openswan/ipsec_stats.h"
38636 +#include "openswan/ipsec_sa.h"
38637 +
38638 +#include "openswan/ipsec_encap.h"
38639 +#include "openswan/ipsec_radij.h"
38640 +#include "openswan/ipsec_xform.h"
38641 +#include "openswan/ipsec_tunnel.h"
38642 +#include "openswan/ipsec_xmit.h"
38643 +
38644 +#include "openswan/ipsec_rcv.h"
38645 +#include "openswan/ipsec_ah.h"
38646 +#include "openswan/ipsec_esp.h"
38647 +#include "openswan/ipsec_kern24.h"
38648 +
38649 +#ifdef CONFIG_KLIPS_IPCOMP
38650 +#include "openswan/ipcomp.h"
38651 +#endif /* CONFIG_KLIPS_IPCOMP */
38652 +
38653 +#include "openswan/ipsec_proto.h"
38654 +
38655 +#include <pfkeyv2.h>
38656 +#include <pfkey.h>
38657 +
38658 +/* ipsec_snprintf: like snprintf except
38659 + * - size is signed and a negative value is treated as if it were 0
38660 + * - the returned result is never negative --
38661 + * an error generates a "?" or null output (depending on space).
38662 + * (Our callers are too lazy to check for an error return.)
38663 + *
38664 + * @param buf String buffer
38665 + * @param size Size of the string
38666 + * @param fmt printf string
38667 + * @param ... Variables to be displayed in fmt
38668 + * @return int Return code
38669 + */
38670 +int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
38671 +{
38672 + va_list args;
38673 + int i;
38674 + size_t possize = size < 0? 0 : size;
38675 + va_start(args, fmt);
38676 + i = vsnprintf(buf,possize,fmt,args);
38677 + va_end(args);
38678 + if (i < 0) {
38679 + /* create empty output in place of error */
38680 + i = 0;
38681 + if (size > 0) {
38682 + *buf = '\0';
38683 + }
38684 + }
38685 + return i;
38686 +}
38687 +
38688 +
38689 +void ipsec_dmp_block(char *s, caddr_t bb, int len)
38690 +{
38691 + int i;
38692 + unsigned char *b = bb;
38693 +
38694 + printk(KERN_INFO "klips_dmp: "
38695 + "at %s, len=%d:\n", s, len);
38696 +
38697 + for(i = 0; i < len; i++ /*, c++*/) {
38698 + if(!(i % 16)) {
38699 + printk(KERN_INFO
38700 + "klips_debug: @%03x:",
38701 + i);
38702 + }
38703 + printk(" %02x", b[i]);
38704 + if(!((i + 1) % 16)) {
38705 + printk("\n");
38706 + }
38707 + }
38708 + if(i % 16) {
38709 + printk("\n");
38710 + }
38711 +}
38712 +
38713 +/*
38714 + *
38715 + * $Log: ipsec_snprintf.c,v $
38716 + * Revision 1.3.2.1 2006/10/06 21:39:26 paul
38717 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
38718 + * set. This is defined through autoconf.h which is included through the
38719 + * linux kernel build macros.
38720 + *
38721 + * Revision 1.3 2005/04/29 05:10:22 mcr
38722 + * removed from extraenous includes to make unit testing easier.
38723 + *
38724 + * Revision 1.2 2005/04/15 00:32:01 mcr
38725 + * added ipsec_dmp_block routine.
38726 + *
38727 + *
38728 + * Local Variables:
38729 + * c-file-style: "linux"
38730 + * End:
38731 + *
38732 + */
38733 +
38734 --- /dev/null Tue Mar 11 13:02:56 2003
38735 +++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004
38736 @@ -0,0 +1,2878 @@
38737 +/*
38738 + * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
38739 + * Copyright (C) 1996, 1997 John Ioannidis.
38740 + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
38741 + *
38742 + * This program is free software; you can redistribute it and/or modify it
38743 + * under the terms of the GNU General Public License as published by the
38744 + * Free Software Foundation; either version 2 of the License, or (at your
38745 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
38746 + *
38747 + * This program is distributed in the hope that it will be useful, but
38748 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
38749 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
38750 + * for more details.
38751 + */
38752 +
38753 +char ipsec_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.232.2.5 2006/10/06 21:39:26 paul Exp $";
38754 +
38755 +#define __NO_VERSION__
38756 +#include <linux/module.h>
38757 +#ifndef AUTOCONF_INCLUDED
38758 +#include <linux/config.h>
38759 +#endif /* for CONFIG_IP_FORWARD */
38760 +#include <linux/version.h>
38761 +#include <linux/kernel.h> /* printk() */
38762 +
38763 +#include "openswan/ipsec_param.h"
38764 +
38765 +#ifdef MALLOC_SLAB
38766 +# include <linux/slab.h> /* kmalloc() */
38767 +#else /* MALLOC_SLAB */
38768 +# include <linux/malloc.h> /* kmalloc() */
38769 +#endif /* MALLOC_SLAB */
38770 +#include <linux/errno.h> /* error codes */
38771 +#include <linux/types.h> /* size_t */
38772 +#include <linux/interrupt.h> /* mark_bh */
38773 +
38774 +#include <net/tcp.h>
38775 +#include <net/udp.h>
38776 +#include <linux/skbuff.h>
38777 +
38778 +#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
38779 +#include <linux/etherdevice.h> /* eth_type_trans */
38780 +#include <linux/ip.h> /* struct iphdr */
38781 +#include <linux/skbuff.h>
38782 +
38783 +#include <openswan.h>
38784 +
38785 +#ifdef NET_21
38786 +# include <linux/in6.h>
38787 +# define ip_chk_addr inet_addr_type
38788 +# define IS_MYADDR RTN_LOCAL
38789 +# include <net/dst.h>
38790 +# undef dev_kfree_skb
38791 +# define dev_kfree_skb(a,b) kfree_skb(a)
38792 +# define PHYSDEV_TYPE
38793 +#endif /* NET_21 */
38794 +
38795 +#include <net/icmp.h> /* icmp_send() */
38796 +#include <net/ip.h>
38797 +#ifdef NETDEV_23
38798 +# include <linux/netfilter_ipv4.h>
38799 +#endif /* NETDEV_23 */
38800 +
38801 +#include <linux/if_arp.h>
38802 +#include <net/arp.h>
38803 +
38804 +#include "openswan/ipsec_kversion.h"
38805 +#include "openswan/radij.h"
38806 +#include "openswan/ipsec_life.h"
38807 +#include "openswan/ipsec_xform.h"
38808 +#include "openswan/ipsec_eroute.h"
38809 +#include "openswan/ipsec_encap.h"
38810 +#include "openswan/ipsec_radij.h"
38811 +#include "openswan/ipsec_sa.h"
38812 +#include "openswan/ipsec_tunnel.h"
38813 +#include "openswan/ipsec_xmit.h"
38814 +#include "openswan/ipsec_ipe4.h"
38815 +#include "openswan/ipsec_ah.h"
38816 +#include "openswan/ipsec_esp.h"
38817 +#include "openswan/ipsec_kern24.h"
38818 +
38819 +#include <pfkeyv2.h>
38820 +#include <pfkey.h>
38821 +
38822 +#include "openswan/ipsec_proto.h"
38823 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
38824 +#include <linux/udp.h>
38825 +#endif
38826 +
38827 +static __u32 zeroes[64];
38828 +
38829 +#ifdef CONFIG_KLIPS_DEBUG
38830 +int debug_tunnel = 0;
38831 +#endif /* CONFIG_KLIPS_DEBUG */
38832 +
38833 +DEBUG_NO_STATIC int
38834 +ipsec_tunnel_open(struct net_device *dev)
38835 +{
38836 + struct ipsecpriv *prv = dev->priv;
38837 +
38838 + /*
38839 + * Can't open until attached.
38840 + */
38841 +
38842 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
38843 + "klips_debug:ipsec_tunnel_open: "
38844 + "dev = %s, prv->dev = %s\n",
38845 + dev->name, prv->dev?prv->dev->name:"NONE");
38846 +
38847 + if (prv->dev == NULL)
38848 + return -ENODEV;
38849 +
38850 + KLIPS_INC_USE;
38851 + return 0;
38852 +}
38853 +
38854 +DEBUG_NO_STATIC int
38855 +ipsec_tunnel_close(struct net_device *dev)
38856 +{
38857 + KLIPS_DEC_USE;
38858 + return 0;
38859 +}
38860 +
38861 +#ifdef NETDEV_23
38862 +static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
38863 +{
38864 +#ifdef NETDEV_25 /* 2.6 kernels */
38865 + return dst_output(skb);
38866 +#else
38867 + return ip_send(skb);
38868 +#endif
38869 +}
38870 +#endif /* NETDEV_23 */
38871 +
38872 +enum ipsec_xmit_value
38873 +ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs)
38874 +{
38875 + /* ixs->physdev->hard_header_len is unreliable and should not be used */
38876 + ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data;
38877 +
38878 + if(ixs->hard_header_len < 0) {
38879 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38880 + "klips_error:ipsec_xmit_strip_hard_header: "
38881 + "Negative hard_header_len (%d)?!\n", ixs->hard_header_len);
38882 + ixs->stats->tx_dropped++;
38883 + return IPSEC_XMIT_BADHHLEN;
38884 + }
38885 +
38886 + /* while ixs->physdev->hard_header_len is unreliable and
38887 + * should not be trusted, it accurate and required for ATM, GRE and
38888 + * some other interfaces to work. Thanks to Willy Tarreau
38889 + * <willy@w.ods.org>.
38890 + */
38891 + if(ixs->hard_header_len == 0) { /* no hard header present */
38892 + ixs->hard_header_stripped = 1;
38893 + ixs->hard_header_len = ixs->physdev->hard_header_len;
38894 + }
38895 +
38896 +#ifdef CONFIG_KLIPS_DEBUG
38897 + if (debug_tunnel & DB_TN_XMIT) {
38898 + int i;
38899 + char c;
38900 +
38901 + printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: "
38902 + ">>> skb->len=%ld hard_header_len:%d",
38903 + (unsigned long int)ixs->skb->len, ixs->hard_header_len);
38904 + c = ' ';
38905 + for (i=0; i < ixs->hard_header_len; i++) {
38906 + printk("%c%02x", c, ixs->skb->data[i]);
38907 + c = ':';
38908 + }
38909 + printk(" \n");
38910 + }
38911 +#endif /* CONFIG_KLIPS_DEBUG */
38912 +
38913 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
38914 +
38915 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
38916 + "klips_debug:ipsec_xmit_strip_hard_header: "
38917 + "Original head,tailroom: %d,%d\n",
38918 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
38919 +
38920 + return IPSEC_XMIT_OK;
38921 +}
38922 +
38923 +enum ipsec_xmit_value
38924 +ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs)
38925 +{
38926 + unsigned int bypass;
38927 +
38928 + bypass = FALSE;
38929 +
38930 + /*
38931 + * First things first -- look us up in the erouting tables.
38932 + */
38933 + ixs->matcher.sen_len = sizeof (struct sockaddr_encap);
38934 + ixs->matcher.sen_family = AF_ENCAP;
38935 + ixs->matcher.sen_type = SENT_IP4;
38936 + ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
38937 + ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
38938 + ixs->matcher.sen_proto = ixs->iph->protocol;
38939 + ipsec_extract_ports(ixs->iph, &ixs->matcher);
38940 +
38941 + /*
38942 + * The spinlock is to prevent any other process from accessing or deleting
38943 + * the eroute while we are using and updating it.
38944 + */
38945 + spin_lock(&eroute_lock);
38946 +
38947 + ixs->eroute = ipsec_findroute(&ixs->matcher);
38948 +
38949 + if(ixs->iph->protocol == IPPROTO_UDP) {
38950 + struct udphdr *t = NULL;
38951 +
38952 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38953 + "klips_debug:udp port check: "
38954 + "fragoff: %d len: %d>%ld \n",
38955 + ntohs(ixs->iph->frag_off) & IP_OFFSET,
38956 + (ixs->skb->len - ixs->hard_header_len),
38957 + (unsigned long int) ((ixs->iph->ihl << 2) + sizeof(struct udphdr)));
38958 +
38959 + if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
38960 + ((ixs->skb->len - ixs->hard_header_len) >=
38961 + ((ixs->iph->ihl << 2) + sizeof(struct udphdr))))
38962 + {
38963 + t =((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
38964 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
38965 + "klips_debug:udp port in packet: "
38966 + "port %d -> %d\n",
38967 + ntohs(t->source), ntohs(t->dest));
38968 + }
38969 +
38970 + ixs->sport=0; ixs->dport=0;
38971 +
38972 + if(ixs->skb->sk) {
38973 +#ifdef NET_26
38974 + struct udp_sock *us;
38975 +
38976 + us = (struct udp_sock *)ixs->skb->sk;
38977 +
38978 + ixs->sport = ntohs(us->inet.sport);
38979 + ixs->dport = ntohs(us->inet.dport);
38980 +#else
38981 + ixs->sport = ntohs(ixs->skb->sk->sport);
38982 + ixs->dport = ntohs(ixs->skb->sk->dport);
38983 +#endif
38984 +
38985 + }
38986 +
38987 + if(t != NULL) {
38988 + if(ixs->sport == 0) {
38989 + ixs->sport = ntohs(t->source);
38990 + }
38991 + if(ixs->dport == 0) {
38992 + ixs->dport = ntohs(t->dest);
38993 + }
38994 + }
38995 + }
38996 +
38997 + /*
38998 + * practically identical to above, but let's be careful about
38999 + * tcp vs udp headers
39000 + */
39001 + if(ixs->iph->protocol == IPPROTO_TCP) {
39002 + struct tcphdr *t = NULL;
39003 +
39004 + if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
39005 + ((ixs->skb->len - ixs->hard_header_len) >=
39006 + ((ixs->iph->ihl << 2) + sizeof(struct tcphdr)))) {
39007 + t =((struct tcphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)));
39008 + }
39009 +
39010 + ixs->sport=0; ixs->dport=0;
39011 +
39012 + if(ixs->skb->sk) {
39013 +#ifdef NET_26
39014 +#ifdef HAVE_INET_SK_SPORT
39015 + ixs->sport = ntohs(inet_sk(ixs->skb->sk)->sport);
39016 + ixs->dport = ntohs(inet_sk(ixs->skb->sk)->dport);
39017 +#else
39018 + struct tcp_tw_bucket *tw;
39019 +
39020 + tw = (struct tcp_tw_bucket *)ixs->skb->sk;
39021 +
39022 + ixs->sport = ntohs(tw->tw_sport);
39023 + ixs->dport = ntohs(tw->tw_dport);
39024 +#endif
39025 +#else
39026 + ixs->sport = ntohs(ixs->skb->sk->sport);
39027 + ixs->dport = ntohs(ixs->skb->sk->dport);
39028 +#endif
39029 + }
39030 +
39031 + if(t != NULL) {
39032 + if(ixs->sport == 0) {
39033 + ixs->sport = ntohs(t->source);
39034 + }
39035 + if(ixs->dport == 0) {
39036 + ixs->dport = ntohs(t->dest);
39037 + }
39038 + }
39039 + }
39040 +
39041 + /* default to a %drop eroute */
39042 + ixs->outgoing_said.proto = IPPROTO_INT;
39043 + ixs->outgoing_said.spi = htonl(SPI_DROP);
39044 + ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
39045 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39046 + "klips_debug:ipsec_xmit_SAlookup: "
39047 + "checking for local udp/500 IKE packet "
39048 + "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
39049 + ntohl((unsigned int)ixs->iph->saddr),
39050 + ixs->eroute,
39051 + ntohl((unsigned int)ixs->iph->daddr),
39052 + ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0,
39053 + ixs->iph->protocol,
39054 + ixs->sport,
39055 + ixs->dport);
39056 +
39057 + /*
39058 + * cheat for now...are we udp/500? If so, let it through
39059 + * without interference since it is most likely an IKE packet.
39060 + */
39061 +
39062 + if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
39063 + && (ixs->eroute==NULL
39064 + || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
39065 + || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
39066 + && (ixs->iph->protocol == IPPROTO_UDP &&
39067 + (ixs->sport == 500 || ixs->sport == 4500))) {
39068 + /* Whatever the eroute, this is an IKE message
39069 + * from us (i.e. not being forwarded).
39070 + * Furthermore, if there is a tunnel eroute,
39071 + * the destination is the peer for this eroute.
39072 + * So %pass the packet: modify the default %drop.
39073 + */
39074 +
39075 + ixs->outgoing_said.spi = htonl(SPI_PASS);
39076 + if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) {
39077 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39078 + "klips_debug:ipsec_xmit_SAlookup: "
39079 + "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
39080 + }
39081 + bypass = TRUE;
39082 + }
39083 +
39084 +#ifdef KLIPS_EXCEPT_DNS53
39085 + /*
39086 + *
39087 + * if we are udp/53 or tcp/53, also let it through a %trap or %hold,
39088 + * since it is DNS, but *also* follow the %trap.
39089 + *
39090 + * we do not do this for tunnels, only %trap's and %hold's.
39091 + *
39092 + */
39093 +
39094 + if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
39095 + && (ixs->eroute==NULL
39096 + || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
39097 + || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
39098 + && ((ixs->iph->protocol == IPPROTO_UDP
39099 + || ixs->iph->protocol == IPPROTO_TCP)
39100 + && ixs->dport == 53)) {
39101 +
39102 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39103 + "klips_debug:ipsec_xmit_SAlookup: "
39104 + "possible DNS packet\n");
39105 +
39106 + if(ixs->eroute)
39107 + {
39108 + if(ixs->eroute->er_said.spi == htonl(SPI_TRAP)
39109 + || ixs->eroute->er_said.spi == htonl(SPI_HOLD))
39110 + {
39111 + ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
39112 + bypass = TRUE;
39113 + }
39114 + }
39115 + else
39116 + {
39117 + ixs->outgoing_said.spi = htonl(SPI_PASSTRAP);
39118 + bypass = TRUE;
39119 + }
39120 +
39121 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39122 + "klips_debug:ipsec_xmit_SAlookup: "
39123 + "bypass = %d\n", bypass);
39124 +
39125 + if(bypass
39126 + && !(ixs->skb->sk)
39127 + && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0))
39128 + {
39129 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39130 + "klips_debug:ipsec_xmit_SAlookup: "
39131 + "local port 53 (probably DNS) passthrough:"
39132 + "base fragment, rest of fragments will "
39133 + "probably get filtered.\n");
39134 + }
39135 + }
39136 +#endif
39137 +
39138 + if (bypass==FALSE && ixs->eroute) {
39139 + ixs->eroute->er_count++;
39140 + ixs->eroute->er_lasttime = jiffies/HZ;
39141 + if(ixs->eroute->er_said.proto==IPPROTO_INT
39142 + && ixs->eroute->er_said.spi==htonl(SPI_HOLD))
39143 + {
39144 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39145 + "klips_debug:ipsec_xmit_SAlookup: "
39146 + "shunt SA of HOLD: skb stored in HOLD.\n");
39147 + if(ixs->eroute->er_last != NULL) {
39148 + kfree_skb(ixs->eroute->er_last);
39149 + }
39150 + ixs->eroute->er_last = ixs->skb;
39151 + ixs->skb = NULL;
39152 + ixs->stats->tx_dropped++;
39153 + spin_unlock(&eroute_lock);
39154 + return IPSEC_XMIT_STOLEN;
39155 + }
39156 + ixs->outgoing_said = ixs->eroute->er_said;
39157 + ixs->eroute_pid = ixs->eroute->er_pid;
39158 +
39159 + /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
39160 + if(ixs->outgoing_said.proto==IPPROTO_INT
39161 + && (ixs->outgoing_said.spi==htonl(SPI_TRAP)
39162 + || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
39163 + int len;
39164 +
39165 + ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type;
39166 + ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id;
39167 + ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len;
39168 + if (ixs->ips.ips_ident_s.len)
39169 + {
39170 + len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
39171 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39172 + "klips_debug:ipsec_xmit_SAlookup: "
39173 + "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
39174 + len);
39175 + if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
39176 + printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
39177 + "Failed, tried to allocate %d bytes for source ident.\n",
39178 + len);
39179 + ixs->stats->tx_dropped++;
39180 + spin_unlock(&eroute_lock);
39181 + return IPSEC_XMIT_ERRMEMALLOC;
39182 + }
39183 + memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len);
39184 + }
39185 + ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type;
39186 + ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id;
39187 + ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len;
39188 + if (ixs->ips.ips_ident_d.len)
39189 + {
39190 + len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
39191 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39192 + "klips_debug:ipsec_xmit_SAlookup: "
39193 + "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
39194 + len);
39195 + if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
39196 + printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
39197 + "Failed, tried to allocate %d bytes for dest ident.\n",
39198 + len);
39199 + ixs->stats->tx_dropped++;
39200 + spin_unlock(&eroute_lock);
39201 + return IPSEC_XMIT_ERRMEMALLOC;
39202 + }
39203 + memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len);
39204 + }
39205 + }
39206 + }
39207 +
39208 + spin_unlock(&eroute_lock);
39209 + return IPSEC_XMIT_OK;
39210 +}
39211 +
39212 +
39213 +enum ipsec_xmit_value
39214 +ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs)
39215 +{
39216 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39217 + "klips_debug:ipsec_xmit_restore_hard_header: "
39218 + "After recursive xforms -- head,tailroom: %d,%d\n",
39219 + skb_headroom(ixs->skb),
39220 + skb_tailroom(ixs->skb));
39221 +
39222 + if(ixs->saved_header) {
39223 + if(skb_headroom(ixs->skb) < ixs->hard_header_len) {
39224 + printk(KERN_WARNING
39225 + "klips_error:ipsec_xmit_restore_hard_header: "
39226 + "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
39227 + ixs->hard_header_len,
39228 + skb_headroom(ixs->skb));
39229 + ixs->stats->tx_errors++;
39230 + return IPSEC_XMIT_PUSHPULLERR;
39231 +
39232 + }
39233 + skb_push(ixs->skb, ixs->hard_header_len);
39234 + {
39235 + int i;
39236 + for (i = 0; i < ixs->hard_header_len; i++) {
39237 + ixs->skb->data[i] = ixs->saved_header[i];
39238 + }
39239 + }
39240 + }
39241 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39242 + if (ixs->natt_type && ixs->natt_head) {
39243 + struct iphdr *ipp = ixs->skb->nh.iph;
39244 + struct udphdr *udp;
39245 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39246 + "klips_debug:ipsec_tunnel_start_xmit: "
39247 + "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
39248 + ixs->natt_type, ixs->natt_head);
39249 +
39250 + ixs->iphlen = ipp->ihl << 2;
39251 + ipp->tot_len =
39252 + htons(ntohs(ipp->tot_len) + ixs->natt_head);
39253 + if(skb_tailroom(ixs->skb) < ixs->natt_head) {
39254 + printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
39255 + "tried to skb_put %d, %d available. "
39256 + "This should never happen, please report.\n",
39257 + ixs->natt_head,
39258 + skb_tailroom(ixs->skb));
39259 + ixs->stats->tx_errors++;
39260 + return IPSEC_XMIT_ESPUDP;
39261 + }
39262 + skb_put(ixs->skb, ixs->natt_head);
39263 +
39264 + udp = (struct udphdr *)((char *)ipp + ixs->iphlen);
39265 +
39266 + /* move ESP hdr after UDP hdr */
39267 + memmove((void *)((char *)udp + ixs->natt_head),
39268 + (void *)(udp),
39269 + ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head);
39270 +
39271 + /* clear UDP & Non-IKE Markers (if any) */
39272 + memset(udp, 0, ixs->natt_head);
39273 +
39274 + /* fill UDP with usefull informations ;-) */
39275 + udp->source = htons(ixs->natt_sport);
39276 + udp->dest = htons(ixs->natt_dport);
39277 + udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen);
39278 +
39279 + /* set protocol */
39280 + ipp->protocol = IPPROTO_UDP;
39281 +
39282 + /* fix IP checksum */
39283 + ipp->check = 0;
39284 + ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
39285 + }
39286 +#endif
39287 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
39288 + "klips_debug:ipsec_xmit_restore_hard_header: "
39289 + "With hard_header, final head,tailroom: %d,%d\n",
39290 + skb_headroom(ixs->skb),
39291 + skb_tailroom(ixs->skb));
39292 +
39293 + return IPSEC_XMIT_OK;
39294 +}
39295 +
39296 +enum ipsec_xmit_value
39297 +ipsec_tunnel_send(struct ipsec_xmit_state*ixs)
39298 +{
39299 +#ifdef NETDEV_25
39300 + struct flowi fl;
39301 +#endif
39302 +
39303 +#ifdef NET_21 /* 2.2 and 2.4 kernels */
39304 + /* new route/dst cache code from James Morris */
39305 + ixs->skb->dev = ixs->physdev;
39306 +#ifdef NETDEV_25
39307 + memset (&fl, 0x0, sizeof (struct flowi));
39308 + fl.oif = ixs->physdev->iflink;
39309 + fl.nl_u.ip4_u.daddr = ixs->skb->nh.iph->daddr;
39310 + fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ixs->skb->nh.iph->saddr;
39311 + fl.nl_u.ip4_u.tos = RT_TOS(ixs->skb->nh.iph->tos);
39312 + fl.proto = ixs->skb->nh.iph->protocol;
39313 + if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) {
39314 +#else
39315 + /*skb_orphan(ixs->skb);*/
39316 + if((ixs->error = ip_route_output(&ixs->route,
39317 + ixs->skb->nh.iph->daddr,
39318 + ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
39319 + RT_TOS(ixs->skb->nh.iph->tos),
39320 + /* mcr->rgb: should this be 0 instead? */
39321 + ixs->physdev->iflink))) {
39322 +#endif
39323 + ixs->stats->tx_errors++;
39324 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39325 + "klips_debug:ipsec_xmit_send: "
39326 + "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
39327 + ixs->error,
39328 + ixs->route->u.dst.dev->name);
39329 + return IPSEC_XMIT_ROUTEERR;
39330 + }
39331 + if(ixs->dev == ixs->route->u.dst.dev) {
39332 + ip_rt_put(ixs->route);
39333 + /* This is recursion, drop it. */
39334 + ixs->stats->tx_errors++;
39335 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39336 + "klips_debug:ipsec_xmit_send: "
39337 + "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
39338 + ixs->dev->name);
39339 + return IPSEC_XMIT_RECURSDETECT;
39340 + }
39341 + dst_release(ixs->skb->dst);
39342 + ixs->skb->dst = &ixs->route->u.dst;
39343 + ixs->stats->tx_bytes += ixs->skb->len;
39344 + if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
39345 + ixs->stats->tx_errors++;
39346 + printk(KERN_WARNING
39347 + "klips_error:ipsec_xmit_send: "
39348 + "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
39349 + (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
39350 + ixs->skb->len);
39351 + return IPSEC_XMIT_PUSHPULLERR;
39352 + }
39353 + __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
39354 +#ifdef SKB_RESET_NFCT
39355 + if(!ixs->pass) {
39356 + nf_conntrack_put(ixs->skb->nfct);
39357 + ixs->skb->nfct = NULL;
39358 + }
39359 +#if defined(CONFIG_NETFILTER_DEBUG) && defined(HAVE_SKB_NF_DEBUG)
39360 + ixs->skb->nf_debug = 0;
39361 +#endif /* CONFIG_NETFILTER_DEBUG */
39362 +#endif /* SKB_RESET_NFCT */
39363 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39364 + "klips_debug:ipsec_xmit_send: "
39365 + "...done, calling ip_send() on device:%s\n",
39366 + ixs->skb->dev ? ixs->skb->dev->name : "NULL");
39367 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->skb->nh.iph);
39368 +#ifdef NETDEV_23 /* 2.4 kernels */
39369 + {
39370 + int err;
39371 +
39372 + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
39373 + ipsec_tunnel_xmit2);
39374 + if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
39375 + if(net_ratelimit())
39376 + printk(KERN_ERR
39377 + "klips_error:ipsec_xmit_send: "
39378 + "ip_send() failed, err=%d\n",
39379 + -err);
39380 + ixs->stats->tx_errors++;
39381 + ixs->stats->tx_aborted_errors++;
39382 + ixs->skb = NULL;
39383 + return IPSEC_XMIT_IPSENDFAILURE;
39384 + }
39385 + }
39386 +#else /* NETDEV_23 */ /* 2.2 kernels */
39387 + ip_send(ixs->skb);
39388 +#endif /* NETDEV_23 */
39389 +#else /* NET_21 */ /* 2.0 kernels */
39390 + ixs->skb->arp = 1;
39391 + /* ISDN/ASYNC PPP from Matjaz Godec. */
39392 + /* skb->protocol = htons(ETH_P_IP); */
39393 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39394 + "klips_debug:ipsec_xmit_send: "
39395 + "...done, calling dev_queue_xmit() or ip_fragment().\n");
39396 + IP_SEND(ixs->skb, ixs->physdev);
39397 +#endif /* NET_21 */
39398 + ixs->stats->tx_packets++;
39399 +
39400 + ixs->skb = NULL;
39401 +
39402 + return IPSEC_XMIT_OK;
39403 +}
39404 +
39405 +void
39406 +ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs)
39407 +{
39408 +#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
39409 + netif_wake_queue(ixs->dev);
39410 +#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
39411 + ixs->dev->tbusy = 0;
39412 +#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
39413 + if(ixs->saved_header) {
39414 + kfree(ixs->saved_header);
39415 + }
39416 + if(ixs->skb) {
39417 + dev_kfree_skb(ixs->skb, FREE_WRITE);
39418 + }
39419 + if(ixs->oskb) {
39420 + dev_kfree_skb(ixs->oskb, FREE_WRITE);
39421 + }
39422 + if (ixs->ips.ips_ident_s.data) {
39423 + kfree(ixs->ips.ips_ident_s.data);
39424 + }
39425 + if (ixs->ips.ips_ident_d.data) {
39426 + kfree(ixs->ips.ips_ident_d.data);
39427 + }
39428 +}
39429 +
39430 +/*
39431 + * This function assumes it is being called from dev_queue_xmit()
39432 + * and that skb is filled properly by that function.
39433 + */
39434 +int
39435 +ipsec_tunnel_start_xmit(struct sk_buff *skb, struct net_device *dev)
39436 +{
39437 + struct ipsec_xmit_state ixs_mem;
39438 + struct ipsec_xmit_state *ixs = &ixs_mem;
39439 + enum ipsec_xmit_value stat;
39440 +
39441 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
39442 + ixs->natt_type = 0, ixs->natt_head = 0;
39443 + ixs->natt_sport = 0, ixs->natt_dport = 0;
39444 +#endif
39445 +
39446 + memset((caddr_t)ixs, 0, sizeof(*ixs));
39447 + ixs->oskb = NULL;
39448 + ixs->saved_header = NULL; /* saved copy of the hard header */
39449 + ixs->route = NULL;
39450 + memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips));
39451 + ixs->dev = dev;
39452 + ixs->skb = skb;
39453 +
39454 + stat = ipsec_xmit_sanity_check_dev(ixs);
39455 + if(stat != IPSEC_XMIT_OK) {
39456 + goto cleanup;
39457 + }
39458 +
39459 + stat = ipsec_xmit_sanity_check_skb(ixs);
39460 + if(stat != IPSEC_XMIT_OK) {
39461 + goto cleanup;
39462 + }
39463 +
39464 + stat = ipsec_tunnel_strip_hard_header(ixs);
39465 + if(stat != IPSEC_XMIT_OK) {
39466 + goto cleanup;
39467 + }
39468 +
39469 + stat = ipsec_tunnel_SAlookup(ixs);
39470 + if(stat != IPSEC_XMIT_OK) {
39471 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39472 + "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n",
39473 + stat);
39474 + goto cleanup;
39475 + }
39476 +
39477 + ixs->innersrc = ixs->iph->saddr;
39478 + /* start encapsulation loop here XXX */
39479 + do {
39480 + stat = ipsec_xmit_encap_bundle(ixs);
39481 + if(stat != IPSEC_XMIT_OK) {
39482 + if(stat == IPSEC_XMIT_PASS) {
39483 + goto bypass;
39484 + }
39485 +
39486 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
39487 + "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n",
39488 + stat);
39489 + goto cleanup;
39490 + }
39491 +
39492 + ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
39493 + ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
39494 + ixs->matcher.sen_proto = ixs->iph->protocol;
39495 + ipsec_extract_ports(ixs->iph, &ixs->matcher);
39496 +
39497 + spin_lock(&eroute_lock);
39498 + ixs->eroute = ipsec_findroute(&ixs->matcher);
39499 + if(ixs->eroute) {
39500 + ixs->outgoing_said = ixs->eroute->er_said;
39501 + ixs->eroute_pid = ixs->eroute->er_pid;
39502 + ixs->eroute->er_count++;
39503 + ixs->eroute->er_lasttime = jiffies/HZ;
39504 + }
39505 + spin_unlock(&eroute_lock);
39506 +
39507 + KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
39508 + /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */
39509 + (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
39510 + ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
39511 + ixs->eroute,
39512 + "klips_debug:ipsec_tunnel_start_xmit: "
39513 + "We are recursing here.\n");
39514 +
39515 + } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/
39516 + (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
39517 + ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
39518 + ixs->eroute);
39519 +
39520 + stat = ipsec_tunnel_restore_hard_header(ixs);
39521 + if(stat != IPSEC_XMIT_OK) {
39522 + goto cleanup;
39523 + }
39524 +
39525 + bypass:
39526 + stat = ipsec_tunnel_send(ixs);
39527 +
39528 + cleanup:
39529 + ipsec_tunnel_cleanup(ixs);
39530 +
39531 + return 0;
39532 +}
39533 +
39534 +DEBUG_NO_STATIC struct net_device_stats *
39535 +ipsec_tunnel_get_stats(struct net_device *dev)
39536 +{
39537 + return &(((struct ipsecpriv *)(dev->priv))->mystats);
39538 +}
39539 +
39540 +/*
39541 + * Revectored calls.
39542 + * For each of these calls, a field exists in our private structure.
39543 + */
39544 +
39545 +DEBUG_NO_STATIC int
39546 +ipsec_tunnel_hard_header(struct sk_buff *skb, struct net_device *dev,
39547 + unsigned short type, void *daddr, void *saddr, unsigned len)
39548 +{
39549 + struct ipsecpriv *prv = dev->priv;
39550 + struct net_device *tmp;
39551 + int ret;
39552 + struct net_device_stats *stats; /* This device's statistics */
39553 +
39554 + if(skb == NULL) {
39555 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39556 + "klips_debug:ipsec_tunnel_hard_header: "
39557 + "no skb...\n");
39558 + return -ENODATA;
39559 + }
39560 +
39561 + if(dev == NULL) {
39562 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39563 + "klips_debug:ipsec_tunnel_hard_header: "
39564 + "no device...\n");
39565 + return -ENODEV;
39566 + }
39567 +
39568 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39569 + "klips_debug:ipsec_tunnel_hard_header: "
39570 + "skb->dev=%s dev=%s.\n",
39571 + skb->dev ? skb->dev->name : "NULL",
39572 + dev->name);
39573 +
39574 + if(prv == NULL) {
39575 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39576 + "klips_debug:ipsec_tunnel_hard_header: "
39577 + "no private space associated with dev=%s\n",
39578 + dev->name ? dev->name : "NULL");
39579 + return -ENODEV;
39580 + }
39581 +
39582 + stats = (struct net_device_stats *) &(prv->mystats);
39583 +
39584 + if(prv->dev == NULL) {
39585 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39586 + "klips_debug:ipsec_tunnel_hard_header: "
39587 + "no physical device associated with dev=%s\n",
39588 + dev->name ? dev->name : "NULL");
39589 + stats->tx_dropped++;
39590 + return -ENODEV;
39591 + }
39592 +
39593 + /* check if we have to send a IPv6 packet. It might be a Router
39594 + Solicitation, where the building of the packet happens in
39595 + reverse order:
39596 + 1. ll hdr,
39597 + 2. IPv6 hdr,
39598 + 3. ICMPv6 hdr
39599 + -> skb->nh.raw is still uninitialized when this function is
39600 + called!! If this is no IPv6 packet, we can print debugging
39601 + messages, otherwise we skip all debugging messages and just
39602 + build the ll header */
39603 + if(type != ETH_P_IPV6) {
39604 + /* execute this only, if we don't have to build the
39605 + header for a IPv6 packet */
39606 + if(!prv->hard_header) {
39607 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39608 + "klips_debug:ipsec_tunnel_hard_header: "
39609 + "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
39610 + saddr,
39611 + daddr,
39612 + len,
39613 + type,
39614 + dev->name);
39615 +#ifdef NET_21
39616 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39617 + "ip=%08x->%08x\n",
39618 + (__u32)ntohl(skb->nh.iph->saddr),
39619 + (__u32)ntohl(skb->nh.iph->daddr) );
39620 +#else /* NET_21 */
39621 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39622 + "ip=%08x->%08x\n",
39623 + (__u32)ntohl(skb->ip_hdr->saddr),
39624 + (__u32)ntohl(skb->ip_hdr->daddr) );
39625 +#endif /* NET_21 */
39626 + stats->tx_dropped++;
39627 + return -ENODEV;
39628 + }
39629 +
39630 +#define da ((struct net_device *)(prv->dev))->dev_addr
39631 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39632 + "klips_debug:ipsec_tunnel_hard_header: "
39633 + "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
39634 + saddr,
39635 + daddr,
39636 + len,
39637 + type,
39638 + dev->name,
39639 + prv->dev->name,
39640 + da[0], da[1], da[2], da[3], da[4], da[5]);
39641 +#ifdef NET_21
39642 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39643 + "ip=%08x->%08x\n",
39644 + (__u32)ntohl(skb->nh.iph->saddr),
39645 + (__u32)ntohl(skb->nh.iph->daddr) );
39646 +#else /* NET_21 */
39647 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
39648 + "ip=%08x->%08x\n",
39649 + (__u32)ntohl(skb->ip_hdr->saddr),
39650 + (__u32)ntohl(skb->ip_hdr->daddr) );
39651 +#endif /* NET_21 */
39652 + } else {
39653 + KLIPS_PRINT(debug_tunnel,
39654 + "klips_debug:ipsec_tunnel_hard_header: "
39655 + "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
39656 + }
39657 + tmp = skb->dev;
39658 + skb->dev = prv->dev;
39659 + ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
39660 + skb->dev = tmp;
39661 + return ret;
39662 +}
39663 +
39664 +DEBUG_NO_STATIC int
39665 +#ifdef NET_21
39666 +ipsec_tunnel_rebuild_header(struct sk_buff *skb)
39667 +#else /* NET_21 */
39668 +ipsec_tunnel_rebuild_header(void *buff, struct net_device *dev,
39669 + unsigned long raddr, struct sk_buff *skb)
39670 +#endif /* NET_21 */
39671 +{
39672 + struct ipsecpriv *prv = skb->dev->priv;
39673 + struct net_device *tmp;
39674 + int ret;
39675 + struct net_device_stats *stats; /* This device's statistics */
39676 +
39677 + if(skb->dev == NULL) {
39678 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39679 + "klips_debug:ipsec_tunnel_rebuild_header: "
39680 + "no device...");
39681 + return -ENODEV;
39682 + }
39683 +
39684 + if(prv == NULL) {
39685 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39686 + "klips_debug:ipsec_tunnel_rebuild_header: "
39687 + "no private space associated with dev=%s",
39688 + skb->dev->name ? skb->dev->name : "NULL");
39689 + return -ENODEV;
39690 + }
39691 +
39692 + stats = (struct net_device_stats *) &(prv->mystats);
39693 +
39694 + if(prv->dev == NULL) {
39695 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39696 + "klips_debug:ipsec_tunnel_rebuild_header: "
39697 + "no physical device associated with dev=%s",
39698 + skb->dev->name ? skb->dev->name : "NULL");
39699 + stats->tx_dropped++;
39700 + return -ENODEV;
39701 + }
39702 +
39703 + if(!prv->rebuild_header) {
39704 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39705 + "klips_debug:ipsec_tunnel_rebuild_header: "
39706 + "physical device has been detached, packet dropped skb->dev=%s->NULL ",
39707 + skb->dev->name);
39708 +#ifdef NET_21
39709 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39710 + "ip=%08x->%08x\n",
39711 + (__u32)ntohl(skb->nh.iph->saddr),
39712 + (__u32)ntohl(skb->nh.iph->daddr) );
39713 +#else /* NET_21 */
39714 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39715 + "ip=%08x->%08x\n",
39716 + (__u32)ntohl(skb->ip_hdr->saddr),
39717 + (__u32)ntohl(skb->ip_hdr->daddr) );
39718 +#endif /* NET_21 */
39719 + stats->tx_dropped++;
39720 + return -ENODEV;
39721 + }
39722 +
39723 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39724 + "klips_debug:ipsec_tunnel: "
39725 + "Revectored rebuild_header dev=%s->%s ",
39726 + skb->dev->name, prv->dev->name);
39727 +#ifdef NET_21
39728 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39729 + "ip=%08x->%08x\n",
39730 + (__u32)ntohl(skb->nh.iph->saddr),
39731 + (__u32)ntohl(skb->nh.iph->daddr) );
39732 +#else /* NET_21 */
39733 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39734 + "ip=%08x->%08x\n",
39735 + (__u32)ntohl(skb->ip_hdr->saddr),
39736 + (__u32)ntohl(skb->ip_hdr->daddr) );
39737 +#endif /* NET_21 */
39738 + tmp = skb->dev;
39739 + skb->dev = prv->dev;
39740 +
39741 +#ifdef NET_21
39742 + ret = prv->rebuild_header(skb);
39743 +#else /* NET_21 */
39744 + ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
39745 +#endif /* NET_21 */
39746 + skb->dev = tmp;
39747 + return ret;
39748 +}
39749 +
39750 +DEBUG_NO_STATIC int
39751 +ipsec_tunnel_set_mac_address(struct net_device *dev, void *addr)
39752 +{
39753 + struct ipsecpriv *prv = dev->priv;
39754 +
39755 + struct net_device_stats *stats; /* This device's statistics */
39756 +
39757 + if(dev == NULL) {
39758 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39759 + "klips_debug:ipsec_tunnel_set_mac_address: "
39760 + "no device...");
39761 + return -ENODEV;
39762 + }
39763 +
39764 + if(prv == NULL) {
39765 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39766 + "klips_debug:ipsec_tunnel_set_mac_address: "
39767 + "no private space associated with dev=%s",
39768 + dev->name ? dev->name : "NULL");
39769 + return -ENODEV;
39770 + }
39771 +
39772 + stats = (struct net_device_stats *) &(prv->mystats);
39773 +
39774 + if(prv->dev == NULL) {
39775 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39776 + "klips_debug:ipsec_tunnel_set_mac_address: "
39777 + "no physical device associated with dev=%s",
39778 + dev->name ? dev->name : "NULL");
39779 + stats->tx_dropped++;
39780 + return -ENODEV;
39781 + }
39782 +
39783 + if(!prv->set_mac_address) {
39784 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39785 + "klips_debug:ipsec_tunnel_set_mac_address: "
39786 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39787 + dev->name);
39788 + return -ENODEV;
39789 + }
39790 +
39791 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39792 + "klips_debug:ipsec_tunnel_set_mac_address: "
39793 + "Revectored dev=%s->%s addr=0p%p\n",
39794 + dev->name, prv->dev->name, addr);
39795 + return prv->set_mac_address(prv->dev, addr);
39796 +
39797 +}
39798 +
39799 +#ifndef NET_21
39800 +DEBUG_NO_STATIC void
39801 +ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct net_device *dev,
39802 + unsigned short htype, __u32 daddr)
39803 +{
39804 + struct ipsecpriv *prv = dev->priv;
39805 +
39806 + struct net_device_stats *stats; /* This device's statistics */
39807 +
39808 + if(dev == NULL) {
39809 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39810 + "klips_debug:ipsec_tunnel_cache_bind: "
39811 + "no device...");
39812 + return;
39813 + }
39814 +
39815 + if(prv == NULL) {
39816 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39817 + "klips_debug:ipsec_tunnel_cache_bind: "
39818 + "no private space associated with dev=%s",
39819 + dev->name ? dev->name : "NULL");
39820 + return;
39821 + }
39822 +
39823 + stats = (struct net_device_stats *) &(prv->mystats);
39824 +
39825 + if(prv->dev == NULL) {
39826 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39827 + "klips_debug:ipsec_tunnel_cache_bind: "
39828 + "no physical device associated with dev=%s",
39829 + dev->name ? dev->name : "NULL");
39830 + stats->tx_dropped++;
39831 + return;
39832 + }
39833 +
39834 + if(!prv->header_cache_bind) {
39835 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39836 + "klips_debug:ipsec_tunnel_cache_bind: "
39837 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39838 + dev->name);
39839 + stats->tx_dropped++;
39840 + return;
39841 + }
39842 +
39843 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39844 + "klips_debug:ipsec_tunnel_cache_bind: "
39845 + "Revectored \n");
39846 + prv->header_cache_bind(hhp, prv->dev, htype, daddr);
39847 + return;
39848 +}
39849 +#endif /* !NET_21 */
39850 +
39851 +
39852 +DEBUG_NO_STATIC void
39853 +ipsec_tunnel_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
39854 +{
39855 + struct ipsecpriv *prv = dev->priv;
39856 +
39857 + struct net_device_stats *stats; /* This device's statistics */
39858 +
39859 + if(dev == NULL) {
39860 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39861 + "klips_debug:ipsec_tunnel_cache_update: "
39862 + "no device...");
39863 + return;
39864 + }
39865 +
39866 + if(prv == NULL) {
39867 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39868 + "klips_debug:ipsec_tunnel_cache_update: "
39869 + "no private space associated with dev=%s",
39870 + dev->name ? dev->name : "NULL");
39871 + return;
39872 + }
39873 +
39874 + stats = (struct net_device_stats *) &(prv->mystats);
39875 +
39876 + if(prv->dev == NULL) {
39877 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39878 + "klips_debug:ipsec_tunnel_cache_update: "
39879 + "no physical device associated with dev=%s",
39880 + dev->name ? dev->name : "NULL");
39881 + stats->tx_dropped++;
39882 + return;
39883 + }
39884 +
39885 + if(!prv->header_cache_update) {
39886 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39887 + "klips_debug:ipsec_tunnel_cache_update: "
39888 + "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
39889 + dev->name);
39890 + return;
39891 + }
39892 +
39893 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39894 + "klips_debug:ipsec_tunnel: "
39895 + "Revectored cache_update\n");
39896 + prv->header_cache_update(hh, prv->dev, haddr);
39897 + return;
39898 +}
39899 +
39900 +#ifdef NET_21
39901 +DEBUG_NO_STATIC int
39902 +ipsec_tunnel_neigh_setup(struct neighbour *n)
39903 +{
39904 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39905 + "klips_debug:ipsec_tunnel_neigh_setup:\n");
39906 +
39907 + if (n->nud_state == NUD_NONE) {
39908 + n->ops = &arp_broken_ops;
39909 + n->output = n->ops->output;
39910 + }
39911 + return 0;
39912 +}
39913 +
39914 +DEBUG_NO_STATIC int
39915 +ipsec_tunnel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
39916 +{
39917 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39918 + "klips_debug:ipsec_tunnel_neigh_setup_dev: "
39919 + "setting up %s\n",
39920 + dev ? dev->name : "NULL");
39921 +
39922 + if (p->tbl->family == AF_INET) {
39923 + p->neigh_setup = ipsec_tunnel_neigh_setup;
39924 + p->ucast_probes = 0;
39925 + p->mcast_probes = 0;
39926 + }
39927 + return 0;
39928 +}
39929 +#endif /* NET_21 */
39930 +
39931 +/*
39932 + * We call the attach routine to attach another device.
39933 + */
39934 +
39935 +DEBUG_NO_STATIC int
39936 +ipsec_tunnel_attach(struct net_device *dev, struct net_device *physdev)
39937 +{
39938 + int i;
39939 + struct ipsecpriv *prv = dev->priv;
39940 +
39941 + if(dev == NULL) {
39942 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39943 + "klips_debug:ipsec_tunnel_attach: "
39944 + "no device...");
39945 + return -ENODEV;
39946 + }
39947 +
39948 + if(prv == NULL) {
39949 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
39950 + "klips_debug:ipsec_tunnel_attach: "
39951 + "no private space associated with dev=%s",
39952 + dev->name ? dev->name : "NULL");
39953 + return -ENODATA;
39954 + }
39955 +
39956 + prv->dev = physdev;
39957 + prv->hard_start_xmit = physdev->hard_start_xmit;
39958 + prv->get_stats = physdev->get_stats;
39959 +
39960 + if (physdev->hard_header) {
39961 + prv->hard_header = physdev->hard_header;
39962 + dev->hard_header = ipsec_tunnel_hard_header;
39963 + } else
39964 + dev->hard_header = NULL;
39965 +
39966 + if (physdev->rebuild_header) {
39967 + prv->rebuild_header = physdev->rebuild_header;
39968 + dev->rebuild_header = ipsec_tunnel_rebuild_header;
39969 + } else
39970 + dev->rebuild_header = NULL;
39971 +
39972 + if (physdev->set_mac_address) {
39973 + prv->set_mac_address = physdev->set_mac_address;
39974 + dev->set_mac_address = ipsec_tunnel_set_mac_address;
39975 + } else
39976 + dev->set_mac_address = NULL;
39977 +
39978 +#ifndef NET_21
39979 + if (physdev->header_cache_bind) {
39980 + prv->header_cache_bind = physdev->header_cache_bind;
39981 + dev->header_cache_bind = ipsec_tunnel_cache_bind;
39982 + } else
39983 + dev->header_cache_bind = NULL;
39984 +#endif /* !NET_21 */
39985 +
39986 + if (physdev->header_cache_update) {
39987 + prv->header_cache_update = physdev->header_cache_update;
39988 + dev->header_cache_update = ipsec_tunnel_cache_update;
39989 + } else
39990 + dev->header_cache_update = NULL;
39991 +
39992 + dev->hard_header_len = physdev->hard_header_len;
39993 +
39994 +#ifdef NET_21
39995 +/* prv->neigh_setup = physdev->neigh_setup; */
39996 + dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
39997 +#endif /* NET_21 */
39998 + dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
39999 + prv->mtu = physdev->mtu;
40000 +
40001 +#ifdef PHYSDEV_TYPE
40002 + dev->type = physdev->type; /* ARPHRD_TUNNEL; */
40003 +#endif /* PHYSDEV_TYPE */
40004 +
40005 + dev->addr_len = physdev->addr_len;
40006 + for (i=0; i<dev->addr_len; i++) {
40007 + dev->dev_addr[i] = physdev->dev_addr[i];
40008 + }
40009 +#ifdef CONFIG_KLIPS_DEBUG
40010 + if(debug_tunnel & DB_TN_INIT) {
40011 + printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
40012 + "physical device %s being attached has HW address: %2x",
40013 + physdev->name, physdev->dev_addr[0]);
40014 + for (i=1; i < physdev->addr_len; i++) {
40015 + printk(":%02x", physdev->dev_addr[i]);
40016 + }
40017 + printk("\n");
40018 + }
40019 +#endif /* CONFIG_KLIPS_DEBUG */
40020 +
40021 + return 0;
40022 +}
40023 +
40024 +/*
40025 + * We call the detach routine to detach the ipsec tunnel from another device.
40026 + */
40027 +
40028 +DEBUG_NO_STATIC int
40029 +ipsec_tunnel_detach(struct net_device *dev)
40030 +{
40031 + int i;
40032 + struct ipsecpriv *prv = dev->priv;
40033 +
40034 + if(dev == NULL) {
40035 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40036 + "klips_debug:ipsec_tunnel_detach: "
40037 + "no device...");
40038 + return -ENODEV;
40039 + }
40040 +
40041 + if(prv == NULL) {
40042 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
40043 + "klips_debug:ipsec_tunnel_detach: "
40044 + "no private space associated with dev=%s",
40045 + dev->name ? dev->name : "NULL");
40046 + return -ENODATA;
40047 + }
40048 +
40049 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40050 + "klips_debug:ipsec_tunnel_detach: "
40051 + "physical device %s being detached from virtual device %s\n",
40052 + prv->dev ? prv->dev->name : "NULL",
40053 + dev->name);
40054 +
40055 + ipsec_dev_put(prv->dev);
40056 + prv->dev = NULL;
40057 + prv->hard_start_xmit = NULL;
40058 + prv->get_stats = NULL;
40059 +
40060 + prv->hard_header = NULL;
40061 +#ifdef DETACH_AND_DOWN
40062 + dev->hard_header = NULL;
40063 +#endif /* DETACH_AND_DOWN */
40064 +
40065 + prv->rebuild_header = NULL;
40066 +#ifdef DETACH_AND_DOWN
40067 + dev->rebuild_header = NULL;
40068 +#endif /* DETACH_AND_DOWN */
40069 +
40070 + prv->set_mac_address = NULL;
40071 +#ifdef DETACH_AND_DOWN
40072 + dev->set_mac_address = NULL;
40073 +#endif /* DETACH_AND_DOWN */
40074 +
40075 +#ifndef NET_21
40076 + prv->header_cache_bind = NULL;
40077 +#ifdef DETACH_AND_DOWN
40078 + dev->header_cache_bind = NULL;
40079 +#endif /* DETACH_AND_DOWN */
40080 +#endif /* !NET_21 */
40081 +
40082 + prv->header_cache_update = NULL;
40083 +#ifdef DETACH_AND_DOWN
40084 + dev->header_cache_update = NULL;
40085 +#endif /* DETACH_AND_DOWN */
40086 +
40087 +#ifdef NET_21
40088 +/* prv->neigh_setup = NULL; */
40089 +#ifdef DETACH_AND_DOWN
40090 + dev->neigh_setup = NULL;
40091 +#endif /* DETACH_AND_DOWN */
40092 +#endif /* NET_21 */
40093 + dev->hard_header_len = 0;
40094 +#ifdef DETACH_AND_DOWN
40095 + dev->mtu = 0;
40096 +#endif /* DETACH_AND_DOWN */
40097 + prv->mtu = 0;
40098 + for (i=0; i<MAX_ADDR_LEN; i++) {
40099 + dev->dev_addr[i] = 0;
40100 + }
40101 + dev->addr_len = 0;
40102 +#ifdef PHYSDEV_TYPE
40103 + dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
40104 +#endif /* PHYSDEV_TYPE */
40105 +
40106 + return 0;
40107 +}
40108 +
40109 +/*
40110 + * We call the clear routine to detach all ipsec tunnels from other devices.
40111 + */
40112 +DEBUG_NO_STATIC int
40113 +ipsec_tunnel_clear(void)
40114 +{
40115 + int i;
40116 + struct net_device *ipsecdev = NULL, *prvdev;
40117 + struct ipsecpriv *prv;
40118 + int ret;
40119 +
40120 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40121 + "klips_debug:ipsec_tunnel_clear: .\n");
40122 +
40123 + for(i = 0; i < IPSEC_NUM_IF; i++) {
40124 + ipsecdev = ipsecdevices[i];
40125 + if(ipsecdev != NULL) {
40126 + if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
40127 + prvdev = (struct net_device *)(prv->dev);
40128 + if(prvdev) {
40129 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40130 + "klips_debug:ipsec_tunnel_clear: "
40131 + "physical device for device %s is %s\n",
40132 + ipsecdev->name, prvdev->name);
40133 + if((ret = ipsec_tunnel_detach(ipsecdev))) {
40134 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40135 + "klips_debug:ipsec_tunnel_clear: "
40136 + "error %d detatching device %s from device %s.\n",
40137 + ret, ipsecdev->name, prvdev->name);
40138 + return ret;
40139 + }
40140 + }
40141 + }
40142 + }
40143 + }
40144 + return 0;
40145 +}
40146 +
40147 +DEBUG_NO_STATIC int
40148 +ipsec_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
40149 +{
40150 + struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
40151 + struct ipsecpriv *prv = dev->priv;
40152 + struct net_device *them; /* physical device */
40153 +#ifdef CONFIG_IP_ALIAS
40154 + char *colon;
40155 + char realphysname[IFNAMSIZ];
40156 +#endif /* CONFIG_IP_ALIAS */
40157 +
40158 + if(dev == NULL) {
40159 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40160 + "klips_debug:ipsec_tunnel_ioctl: "
40161 + "device not supplied.\n");
40162 + return -ENODEV;
40163 + }
40164 +
40165 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40166 + "klips_debug:ipsec_tunnel_ioctl: "
40167 + "tncfg service call #%d for dev=%s\n",
40168 + cmd,
40169 + dev->name ? dev->name : "NULL");
40170 + switch (cmd) {
40171 + /* attach a virtual ipsec? device to a physical device */
40172 + case IPSEC_SET_DEV:
40173 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40174 + "klips_debug:ipsec_tunnel_ioctl: "
40175 + "calling ipsec_tunnel_attatch...\n");
40176 +#ifdef CONFIG_IP_ALIAS
40177 + /* If this is an IP alias interface, get its real physical name */
40178 + strncpy(realphysname, cf->cf_name, IFNAMSIZ);
40179 + realphysname[IFNAMSIZ-1] = 0;
40180 + colon = strchr(realphysname, ':');
40181 + if (colon) *colon = 0;
40182 + them = ipsec_dev_get(realphysname);
40183 +#else /* CONFIG_IP_ALIAS */
40184 + them = ipsec_dev_get(cf->cf_name);
40185 +#endif /* CONFIG_IP_ALIAS */
40186 +
40187 + if (them == NULL) {
40188 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40189 + "klips_debug:ipsec_tunnel_ioctl: "
40190 + "physical device %s requested is null\n",
40191 + cf->cf_name);
40192 + return -ENXIO;
40193 + }
40194 +
40195 +#if 0
40196 + if (them->flags & IFF_UP) {
40197 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40198 + "klips_debug:ipsec_tunnel_ioctl: "
40199 + "physical device %s requested is not up.\n",
40200 + cf->cf_name);
40201 + ipsec_dev_put(them);
40202 + return -ENXIO;
40203 + }
40204 +#endif
40205 +
40206 + if (prv && prv->dev) {
40207 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40208 + "klips_debug:ipsec_tunnel_ioctl: "
40209 + "virtual device is already connected to %s.\n",
40210 + prv->dev->name ? prv->dev->name : "NULL");
40211 + ipsec_dev_put(them);
40212 + return -EBUSY;
40213 + }
40214 + return ipsec_tunnel_attach(dev, them);
40215 +
40216 + case IPSEC_DEL_DEV:
40217 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40218 + "klips_debug:ipsec_tunnel_ioctl: "
40219 + "calling ipsec_tunnel_detatch.\n");
40220 + if (! prv->dev) {
40221 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40222 + "klips_debug:ipsec_tunnel_ioctl: "
40223 + "physical device not connected.\n");
40224 + return -ENODEV;
40225 + }
40226 + return ipsec_tunnel_detach(dev);
40227 +
40228 + case IPSEC_CLR_DEV:
40229 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40230 + "klips_debug:ipsec_tunnel_ioctl: "
40231 + "calling ipsec_tunnel_clear.\n");
40232 + return ipsec_tunnel_clear();
40233 +
40234 + default:
40235 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40236 + "klips_debug:ipsec_tunnel_ioctl: "
40237 + "unknown command %d.\n",
40238 + cmd);
40239 + return -EOPNOTSUPP;
40240 + }
40241 +}
40242 +
40243 +struct net_device *ipsec_get_device(int inst)
40244 +{
40245 + struct net_device *ipsec_dev;
40246 +
40247 + ipsec_dev = NULL;
40248 +
40249 + if(inst < IPSEC_NUM_IF) {
40250 + ipsec_dev = ipsecdevices[inst];
40251 + }
40252 +
40253 + return ipsec_dev;
40254 +}
40255 +
40256 +int
40257 +ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
40258 +{
40259 + struct net_device *dev = ptr;
40260 + struct net_device *ipsec_dev;
40261 + struct ipsecpriv *priv;
40262 + int i;
40263 +
40264 + if (dev == NULL) {
40265 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40266 + "klips_debug:ipsec_device_event: "
40267 + "dev=NULL for event type %ld.\n",
40268 + event);
40269 + return(NOTIFY_DONE);
40270 + }
40271 +
40272 + /* check for loopback devices */
40273 + if (dev && (dev->flags & IFF_LOOPBACK)) {
40274 + return(NOTIFY_DONE);
40275 + }
40276 +
40277 + switch (event) {
40278 + case NETDEV_DOWN:
40279 + /* look very carefully at the scope of these compiler
40280 + directives before changing anything... -- RGB */
40281 +#ifdef NET_21
40282 + case NETDEV_UNREGISTER:
40283 + switch (event) {
40284 + case NETDEV_DOWN:
40285 +#endif /* NET_21 */
40286 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40287 + "klips_debug:ipsec_device_event: "
40288 + "NETDEV_DOWN dev=%s flags=%x\n",
40289 + dev->name,
40290 + dev->flags);
40291 + if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
40292 + printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
40293 + dev->name);
40294 + }
40295 +#ifdef NET_21
40296 + break;
40297 + case NETDEV_UNREGISTER:
40298 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40299 + "klips_debug:ipsec_device_event: "
40300 + "NETDEV_UNREGISTER dev=%s flags=%x\n",
40301 + dev->name,
40302 + dev->flags);
40303 + break;
40304 + }
40305 +#endif /* NET_21 */
40306 +
40307 + /* find the attached physical device and detach it. */
40308 + for(i = 0; i < IPSEC_NUM_IF; i++) {
40309 + ipsec_dev = ipsecdevices[i];
40310 +
40311 + if(ipsec_dev) {
40312 + priv = (struct ipsecpriv *)(ipsec_dev->priv);
40313 + if(priv) {
40314 + ;
40315 + if(((struct net_device *)(priv->dev)) == dev) {
40316 + /* dev_close(ipsec_dev); */
40317 + /* return */ ipsec_tunnel_detach(ipsec_dev);
40318 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40319 + "klips_debug:ipsec_device_event: "
40320 + "device '%s' has been detached.\n",
40321 + ipsec_dev->name);
40322 + break;
40323 + }
40324 + } else {
40325 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40326 + "klips_debug:ipsec_device_event: "
40327 + "device '%s' has no private data space!\n",
40328 + ipsec_dev->name);
40329 + }
40330 + }
40331 + }
40332 + break;
40333 + case NETDEV_UP:
40334 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40335 + "klips_debug:ipsec_device_event: "
40336 + "NETDEV_UP dev=%s\n",
40337 + dev->name);
40338 + break;
40339 +#ifdef NET_21
40340 + case NETDEV_REBOOT:
40341 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40342 + "klips_debug:ipsec_device_event: "
40343 + "NETDEV_REBOOT dev=%s\n",
40344 + dev->name);
40345 + break;
40346 + case NETDEV_CHANGE:
40347 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40348 + "klips_debug:ipsec_device_event: "
40349 + "NETDEV_CHANGE dev=%s flags=%x\n",
40350 + dev->name,
40351 + dev->flags);
40352 + break;
40353 + case NETDEV_REGISTER:
40354 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40355 + "klips_debug:ipsec_device_event: "
40356 + "NETDEV_REGISTER dev=%s\n",
40357 + dev->name);
40358 + break;
40359 + case NETDEV_CHANGEMTU:
40360 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40361 + "klips_debug:ipsec_device_event: "
40362 + "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
40363 + dev->name,
40364 + dev->mtu);
40365 + break;
40366 + case NETDEV_CHANGEADDR:
40367 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40368 + "klips_debug:ipsec_device_event: "
40369 + "NETDEV_CHANGEADDR dev=%s\n",
40370 + dev->name);
40371 + break;
40372 + case NETDEV_GOING_DOWN:
40373 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40374 + "klips_debug:ipsec_device_event: "
40375 + "NETDEV_GOING_DOWN dev=%s\n",
40376 + dev->name);
40377 + break;
40378 + case NETDEV_CHANGENAME:
40379 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40380 + "klips_debug:ipsec_device_event: "
40381 + "NETDEV_CHANGENAME dev=%s\n",
40382 + dev->name);
40383 + break;
40384 +#endif /* NET_21 */
40385 + default:
40386 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40387 + "klips_debug:ipsec_device_event: "
40388 + "event type %ld unrecognised for dev=%s\n",
40389 + event,
40390 + dev->name);
40391 + break;
40392 + }
40393 + return NOTIFY_DONE;
40394 +}
40395 +
40396 +/*
40397 + * Called when an ipsec tunnel device is initialized.
40398 + * The ipsec tunnel device structure is passed to us.
40399 + */
40400 +
40401 +int
40402 +ipsec_tunnel_init(struct net_device *dev)
40403 +{
40404 + int i;
40405 +
40406 + KLIPS_PRINT(debug_tunnel,
40407 + "klips_debug:ipsec_tunnel_init: "
40408 + "allocating %lu bytes initialising device: %s\n",
40409 + (unsigned long) sizeof(struct ipsecpriv),
40410 + dev->name ? dev->name : "NULL");
40411 +
40412 + /* Add our tunnel functions to the device */
40413 + dev->open = ipsec_tunnel_open;
40414 + dev->stop = ipsec_tunnel_close;
40415 + dev->hard_start_xmit = ipsec_tunnel_start_xmit;
40416 + dev->get_stats = ipsec_tunnel_get_stats;
40417 +
40418 + dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
40419 + if (dev->priv == NULL)
40420 + return -ENOMEM;
40421 + memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
40422 +
40423 + for(i = 0; i < sizeof(zeroes); i++) {
40424 + ((__u8*)(zeroes))[i] = 0;
40425 + }
40426 +
40427 +#ifndef NET_21
40428 + /* Initialize the tunnel device structure */
40429 + for (i = 0; i < DEV_NUMBUFFS; i++)
40430 + skb_queue_head_init(&dev->buffs[i]);
40431 +#endif /* !NET_21 */
40432 +
40433 + dev->set_multicast_list = NULL;
40434 + dev->do_ioctl = ipsec_tunnel_ioctl;
40435 + dev->hard_header = NULL;
40436 + dev->rebuild_header = NULL;
40437 + dev->set_mac_address = NULL;
40438 +#ifndef NET_21
40439 + dev->header_cache_bind = NULL;
40440 +#endif /* !NET_21 */
40441 + dev->header_cache_update= NULL;
40442 +
40443 +#ifdef NET_21
40444 +/* prv->neigh_setup = NULL; */
40445 + dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
40446 +#endif /* NET_21 */
40447 + dev->hard_header_len = 0;
40448 + dev->mtu = 0;
40449 + dev->addr_len = 0;
40450 + dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
40451 + dev->tx_queue_len = 10; /* Small queue */
40452 + memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
40453 +
40454 + /* New-style flags. */
40455 + dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
40456 +
40457 +#if 0
40458 +#ifdef NET_21
40459 + dev_init_buffers(dev);
40460 +#else /* NET_21 */
40461 + dev->family = AF_INET;
40462 + dev->pa_addr = 0;
40463 + dev->pa_brdaddr = 0;
40464 + dev->pa_mask = 0;
40465 + dev->pa_alen = 4;
40466 +#endif /* NET_21 */
40467 +#endif
40468 +
40469 + /* We're done. Have I forgotten anything? */
40470 + return 0;
40471 +}
40472 +
40473 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40474 +/* Module specific interface (but it links with the rest of IPSEC) */
40475 +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40476 +
40477 +int
40478 +ipsec_tunnel_probe(struct net_device *dev)
40479 +{
40480 + ipsec_tunnel_init(dev);
40481 + return 0;
40482 +}
40483 +
40484 +struct net_device *ipsecdevices[IPSEC_NUM_IF];
40485 +
40486 +int
40487 +ipsec_tunnel_init_devices(void)
40488 +{
40489 + int i;
40490 + char name[IFNAMSIZ];
40491 + struct net_device *dev_ipsec;
40492 +
40493 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40494 + "klips_debug:ipsec_tunnel_init_devices: "
40495 + "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
40496 + IPSEC_NUM_IF,
40497 + (unsigned long) (sizeof(struct net_device) + IFNAMSIZ),
40498 + IFNAMSIZ);
40499 +
40500 + for(i = 0; i < IPSEC_NUM_IF; i++) {
40501 + sprintf(name, IPSEC_DEV_FORMAT, i);
40502 + dev_ipsec = (struct net_device*)kmalloc(sizeof(struct net_device), GFP_KERNEL);
40503 + if (dev_ipsec == NULL) {
40504 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40505 + "klips_debug:ipsec_tunnel_init_devices: "
40506 + "failed to allocate memory for device %s, quitting device init.\n",
40507 + name);
40508 + return -ENOMEM;
40509 + }
40510 + memset((caddr_t)dev_ipsec, 0, sizeof(struct net_device));
40511 +#ifdef NETDEV_23
40512 + strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
40513 +#else /* NETDEV_23 */
40514 + dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
40515 + if (dev_ipsec->name == NULL) {
40516 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40517 + "klips_debug:ipsec_tunnel_init_devices: "
40518 + "failed to allocate memory for device %s name, quitting device init.\n",
40519 + name);
40520 + return -ENOMEM;
40521 + }
40522 + memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ);
40523 + strncpy(dev_ipsec->name, name, IFNAMSIZ);
40524 +#endif /* NETDEV_23 */
40525 + dev_ipsec->next = NULL;
40526 + dev_ipsec->init = &ipsec_tunnel_probe;
40527 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40528 + "klips_debug:ipsec_tunnel_init_devices: "
40529 + "registering device %s\n",
40530 + dev_ipsec->name);
40531 +
40532 + /* reference and hold the device reference */
40533 + dev_hold(dev_ipsec);
40534 + ipsecdevices[i]=dev_ipsec;
40535 +
40536 + if (register_netdev(dev_ipsec) != 0) {
40537 + KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
40538 + "klips_debug:ipsec_tunnel_init_devices: "
40539 + "registering device %s failed, quitting device init.\n",
40540 + dev_ipsec->name);
40541 + return -EIO;
40542 + } else {
40543 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
40544 + "klips_debug:ipsec_tunnel_init_devices: "
40545 + "registering device %s succeeded, continuing...\n",
40546 + dev_ipsec->name);
40547 + }
40548 + }
40549 + return 0;
40550 +}
40551 +
40552 +/* void */
40553 +int
40554 +ipsec_tunnel_cleanup_devices(void)
40555 +{
40556 + int error = 0;
40557 + int i;
40558 + struct net_device *dev_ipsec;
40559 +
40560 + for(i = 0; i < IPSEC_NUM_IF; i++) {
40561 + dev_ipsec = ipsecdevices[i];
40562 + if(dev_ipsec == NULL) {
40563 + continue;
40564 + }
40565 +
40566 + /* release reference */
40567 + ipsecdevices[i]=NULL;
40568 + ipsec_dev_put(dev_ipsec);
40569 +
40570 + KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
40571 + dev_ipsec->name,
40572 + atomic_read(&dev_ipsec->refcnt));
40573 + unregister_netdev(dev_ipsec);
40574 + KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", dev_ipsec->name);
40575 +#ifndef NETDEV_23
40576 + kfree(dev_ipsec->name);
40577 + dev_ipsec->name=NULL;
40578 +#endif /* !NETDEV_23 */
40579 + kfree(dev_ipsec->priv);
40580 + dev_ipsec->priv=NULL;
40581 + }
40582 + return error;
40583 +}
40584 +
40585 +/*
40586 + * $Log: ipsec_tunnel.c,v $
40587 + * Revision 1.232.2.5 2006/10/06 21:39:26 paul
40588 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
40589 + * set. This is defined through autoconf.h which is included through the
40590 + * linux kernel build macros.
40591 + *
40592 + * Revision 1.232.2.4 2006/03/28 20:58:19 ken
40593 + * Fix for KLIPS on 2.6.16 - need to include <net/arp.h> now
40594 + *
40595 + * Revision 1.232.2.3 2006/02/15 05:14:12 paul
40596 + * 568: uninitialized struct in ipsec_tunnel.c coud break routing under 2.6 kernels
40597 + * ipsec_tunnel_send() calls the entry point function of routing subsystem
40598 + * (ip_route_output_key()) using a not fully initialized struct of type
40599 + * struct flowi.
40600 + * This will cause a failure in routing packets through an ipsec interface
40601 + * when patches for multipath routing from http://www.ssi.bg/~ja/
40602 + * are applied.
40603 + *
40604 + * Revision 1.232.2.2 2005/11/22 04:11:52 ken
40605 + * Backport fixes for 2.6.14 kernels from HEAD
40606 + *
40607 + * Revision 1.232.2.1 2005/09/21 22:57:43 paul
40608 + * pulled up compile fix for 2.6.13
40609 + *
40610 + * Revision 1.232 2005/06/04 16:06:06 mcr
40611 + * better patch for nat-t rcv-device code.
40612 + *
40613 + * Revision 1.231 2005/05/21 03:28:51 mcr
40614 + * make sure that port-500 hole is used for port-4500 as well.
40615 + *
40616 + * Revision 1.230 2005/05/11 01:42:04 mcr
40617 + * removal of debugging showed useless/wrong variables used.
40618 + *
40619 + * Revision 1.229 2005/04/29 05:10:22 mcr
40620 + * removed from extraenous includes to make unit testing easier.
40621 + *
40622 + * Revision 1.228 2005/01/26 00:50:35 mcr
40623 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
40624 + * and make sure that NAT_TRAVERSAL is set as well to match
40625 + * userspace compiles of code.
40626 + *
40627 + * Revision 1.227 2004/12/10 21:16:08 ken
40628 + * 64bit fixes from Opteron port of KLIPS 2.6
40629 + *
40630 + * Revision 1.226 2004/12/04 07:11:23 mcr
40631 + * fix for snmp SIOCPRIVATE use of snmpd.
40632 + * http://bugs.xelerance.com/view.php?id=144
40633 + *
40634 + * Revision 1.225 2004/12/03 21:25:57 mcr
40635 + * compile time fixes for running on 2.6.
40636 + * still experimental.
40637 + *
40638 + * Revision 1.224 2004/08/14 03:28:24 mcr
40639 + * fixed log comment to remove warning about embedded comment.
40640 + *
40641 + * Revision 1.223 2004/08/04 15:57:07 mcr
40642 + * moved des .h files to include/des/ *
40643 + * included 2.6 protocol specific things
40644 + * started at NAT-T support, but it will require a kernel patch.
40645 + *
40646 + * Revision 1.222 2004/08/03 18:19:08 mcr
40647 + * in 2.6, use "net_device" instead of #define device->net_device.
40648 + * this probably breaks 2.0 compiles.
40649 + *
40650 + * Revision 1.221 2004/07/10 19:11:18 mcr
40651 + * CONFIG_IPSEC -> CONFIG_KLIPS.
40652 + *
40653 + * Revision 1.220 2004/04/06 02:49:26 mcr
40654 + * pullup of algo code from alg-branch.
40655 + *
40656 + * Revision 1.219 2004/02/03 03:13:17 mcr
40657 + * minor edits for readability, and error reporting.
40658 + *
40659 + * Revision 1.218 2004/01/27 20:29:20 mcr
40660 + * fix for unregister_netdev() problem for underlying eth0.
40661 + *
40662 + * Revision 1.217 2003/12/10 01:14:27 mcr
40663 + * NAT-traversal patches to KLIPS.
40664 + *
40665 + * Revision 1.216 2003/12/04 23:01:17 mcr
40666 + * removed ipsec_netlink.h
40667 + *
40668 + * Revision 1.215 2003/12/04 16:35:16 ken
40669 + * Fix for ATM devices where physdev->hard_header_len *is* correct
40670 + *
40671 + * Revision 1.214 2003/11/25 23:52:37 mcr
40672 + * fix typo in patch - ixs-> needed.
40673 + *
40674 + * Revision 1.213 2003/11/24 18:25:49 mcr
40675 + * patch from willy@w.ods.org to fix problems with ATM interfaces.
40676 + *
40677 + * Revision 1.212 2003/10/31 02:27:55 mcr
40678 + * pulled up port-selector patches and sa_id elimination.
40679 + *
40680 + * Revision 1.211.2.2 2003/10/29 01:30:41 mcr
40681 + * elimited "struct sa_id".
40682 + *
40683 + * Revision 1.211.2.1 2003/09/21 13:59:56 mcr
40684 + * pre-liminary X.509 patch - does not yet pass tests.
40685 + *
40686 + * Revision 1.211 2003/09/10 16:46:30 mcr
40687 + * patches for 2.4 backport/2.6 existence.
40688 + *
40689 + * Revision 1.210 2003/07/31 22:47:16 mcr
40690 + * preliminary (untested by FS-team) 2.5 patches.
40691 + *
40692 + * Revision 1.209 2003/06/22 21:28:43 mcr
40693 + * inability to unload module was caused by calls to dev_get
40694 + * (ipsec_dev_get), to gather a device from a name. There is
40695 + * simply no reason to look the devices up - they should be kept
40696 + * in a nice array, ready for use.
40697 + *
40698 + * Revision 1.208 2003/06/22 21:25:07 mcr
40699 + * all staticly counted ipsecXXX device support removed.
40700 + *
40701 + * Revision 1.207 2003/04/02 20:15:37 mcr
40702 + * fix for PR#204 - do not clear connection tracking info if we
40703 + * the packet is being sent in the clear.
40704 + *
40705 + * Revision 1.206 2003/02/12 19:32:51 rgb
40706 + * Refactored file to:
40707 + * ipsec_xmit.c
40708 + * ipsec_xmit.h
40709 + * ipsec_mast.c
40710 + *
40711 + * Revision 1.205 2003/02/06 17:47:00 rgb
40712 + *
40713 + * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code.
40714 + * Refactor ipsec_tunnel_start_xmit() further into:
40715 + * ipsec_xmit_sanity_check_dev()
40716 + * ipsec_xmit_sanity_check_skb()
40717 + * ipsec_xmit_strip_hard_header()
40718 + * ipsec_xmit_restore_hard_header()
40719 + * ipsec_xmit_send()
40720 + * ipsec_xmit_cleanup()
40721 + * and start a skeletal ipsec_mast_start_xmit() .
40722 + *
40723 + * Revision 1.204 2003/02/06 06:43:46 rgb
40724 + *
40725 + * Refactor ipsec_tunnel_start_xmit, bringing out:
40726 + * ipsec_xmit_SAlookup
40727 + * ipsec_xmit_encap_once
40728 + * ipsec_xmit_encap_bundle
40729 + *
40730 + * Revision 1.203 2003/02/06 02:21:34 rgb
40731 + *
40732 + * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
40733 + * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
40734 + * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
40735 + *
40736 + * Revision 1.202 2003/01/03 07:38:01 rgb
40737 + *
40738 + * Start to refactor ipsec_tunnel_start_xmit() by putting local variables
40739 + * into struct ipsec_xmit_state and renaming a few variables to give more
40740 + * unique or searchable names.
40741 + *
40742 + * Revision 1.201 2003/01/03 00:31:28 rgb
40743 + *
40744 + * Clean up memset usage, including fixing 2 places where keys were not
40745 + * properly wiped.
40746 + *
40747 + * Revision 1.200 2002/12/06 02:24:02 mcr
40748 + * patches for compiling against SUSE 8.1 kernels. Requires
40749 + * an additional -DSUSE_LINUX_2_4_19_IS_STUPID.
40750 + *
40751 + * Revision 1.199 2002/10/12 23:11:53 dhr
40752 + *
40753 + * [KenB + DHR] more 64-bit cleanup
40754 + *
40755 + * Revision 1.198 2002/10/05 05:02:58 dhr
40756 + *
40757 + * C labels go on statements
40758 + *
40759 + * Revision 1.197 2002/09/20 05:01:50 rgb
40760 + * Added compiler directive to switch on IP options and fix IP options bug.
40761 + * Make ip->ihl treatment consistent using shifts rather than multiplications.
40762 + * Check for large enough packet before accessing udp header for IKE bypass.
40763 + * Added memory allocation debugging.
40764 + * Fixed potential memory allocation failure-induced oops.
40765 + *
40766 + * Revision 1.196 2002/07/24 18:44:54 rgb
40767 + * Type fiddling to tame ia64 compiler.
40768 + *
40769 + * Revision 1.195 2002/07/23 03:36:07 rgb
40770 + * Fixed 2.2 device initialisation hang.
40771 + *
40772 + * Revision 1.194 2002/05/27 21:40:34 rgb
40773 + * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2.
40774 + * Cleaned up intermediate step to dynamic device allocation.
40775 + *
40776 + * Revision 1.193 2002/05/27 19:31:36 rgb
40777 + * Convert to dynamic ipsec device allocation.
40778 + * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
40779 + *
40780 + * Revision 1.192 2002/05/23 07:14:28 rgb
40781 + * Added refcount code.
40782 + * Cleaned up %p variants to 0p%p for test suite cleanup.
40783 + *
40784 + * Revision 1.191 2002/05/14 02:34:37 rgb
40785 + * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
40786 + * ipsec_sa or ipsec_sa.
40787 + *
40788 + * Revision 1.190 2002/04/24 07:55:32 mcr
40789 + * #include patches and Makefiles for post-reorg compilation.
40790 + *
40791 + * Revision 1.189 2002/04/24 07:36:32 mcr
40792 + * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v
40793 + *
40794 + * Revision 1.188 2002/04/20 00:12:25 rgb
40795 + * Added esp IV CBC attack fix, disabled.
40796 + *
40797 + * Revision 1.187 2002/03/23 19:55:17 rgb
40798 + * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if
40799 + * iptraf or another pcap app is running.
40800 + *
40801 + * Revision 1.186 2002/03/19 03:26:22 rgb
40802 + * Applied DHR's tunnel patch to streamline IKE/specialSA processing.
40803 + *
40804 + * Revision 1.185 2002/02/20 04:13:05 rgb
40805 + * Send back ICMP_PKT_FILTERED upon %reject.
40806 + *
40807 + * Revision 1.184 2002/01/29 17:17:56 mcr
40808 + * moved include of ipsec_param.h to after include of linux/kernel.h
40809 + * otherwise, it seems that some option that is set in ipsec_param.h
40810 + * screws up something subtle in the include path to kernel.h, and
40811 + * it complains on the snprintf() prototype.
40812 + *
40813 + * Revision 1.183 2002/01/29 04:00:53 mcr
40814 + * more excise of kversions.h header.
40815 + *
40816 + * Revision 1.182 2002/01/29 02:13:18 mcr
40817 + * introduction of ipsec_kversion.h means that include of
40818 + * ipsec_param.h must preceed any decisions about what files to
40819 + * include to deal with differences in kernel source.
40820 + *
40821 + * Revision 1.181 2002/01/07 20:00:33 rgb
40822 + * Added IKE destination port debugging.
40823 + *
40824 + * Revision 1.180 2001/12/21 21:49:54 rgb
40825 + * Fixed bug as a result of moving IKE bypass above %trap/%hold code.
40826 + *
40827 + * Revision 1.179 2001/12/19 21:08:14 rgb
40828 + * Added transport protocol ports to ipsec_print_ip().
40829 + * Update eroute info for non-SA targets.
40830 + * Added obey DF code disabled.
40831 + * Fixed formatting bugs in ipsec_tunnel_hard_header().
40832 + *
40833 + * Revision 1.178 2001/12/05 09:36:10 rgb
40834 + * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid
40835 + * IKE packets being stolen by the %hold (and returned to the sending KMd
40836 + * in an ACQUIRE, ironically ;-).
40837 + *
40838 + * Revision 1.177 2001/11/26 09:23:50 rgb
40839 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
40840 + *
40841 + * Revision 1.170.2.1 2001/09/25 02:28:27 mcr
40842 + * struct tdb -> struct ipsec_sa.
40843 + * lifetime checks moved to common routines.
40844 + * cleaned up includes.
40845 + *
40846 + * Revision 1.170.2.2 2001/10/22 21:08:01 mcr
40847 + * include des.h, removed phony prototypes and fixed calling
40848 + * conventions to match real prototypes.
40849 + *
40850 + * Revision 1.176 2001/11/09 18:32:31 rgb
40851 + * Added Hans Schultz' fragmented UDP/500 IKE socket port selector.
40852 + *
40853 + * Revision 1.175 2001/11/06 20:47:00 rgb
40854 + * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling.
40855 + *
40856 + * Revision 1.174 2001/11/06 19:50:43 rgb
40857 + * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
40858 + * use also by pfkey_v2_parser.c
40859 + *
40860 + * Revision 1.173 2001/10/29 21:53:44 henry
40861 + * tone down the device-down message slightly, until we can make it smarter
40862 + *
40863 + * Revision 1.172 2001/10/26 04:59:37 rgb
40864 + * Added a critical level syslog message if an ipsec device goes down.
40865 + *
40866 + * Revision 1.171 2001/10/18 04:45:21 rgb
40867 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
40868 + * lib/freeswan.h version macros moved to lib/kversions.h.
40869 + * Other compiler directive cleanups.
40870 + *
40871 + * Revision 1.170 2001/09/25 00:09:50 rgb
40872 + * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a
40873 + * HOLD.
40874 + *
40875 + * Revision 1.169 2001/09/15 16:24:05 rgb
40876 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
40877 + *
40878 + * Revision 1.168 2001/09/14 16:58:37 rgb
40879 + * Added support for storing the first and last packets through a HOLD.
40880 + *
40881 + * Revision 1.167 2001/09/08 21:13:33 rgb
40882 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
40883 + *
40884 + * Revision 1.166 2001/08/27 19:47:59 rgb
40885 + * Clear tdb before usage.
40886 + * Added comment: clear IF before calling routing?
40887 + *
40888 + * Revision 1.165 2001/07/03 01:23:53 rgb
40889 + * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len >
40890 + * emtu, and don't drop.
40891 + *
40892 + * Revision 1.164 2001/06/14 19:35:10 rgb
40893 + * Update copyright date.
40894 + *
40895 + * Revision 1.163 2001/06/06 20:28:51 rgb
40896 + * Added sanity checks for NULL skbs and devices.
40897 + * Added more debugging output to various functions.
40898 + * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach().
40899 + * Renamed ipsec_tunnel_attach() virtual and physical device arguments.
40900 + * Corrected neigh_setup() device function assignment.
40901 + * Keep valid pointers to ipsec_tunnel_*() on detach.
40902 + * Set dev->type to the originally-initiallised value.
40903 + *
40904 + * Revision 1.162 2001/06/01 07:28:04 rgb
40905 + * Added sanity checks for detached devices. Don't down virtual devices
40906 + * to prevent packets going out in the clear if the detached device comes
40907 + * back up.
40908 + *
40909 + * Revision 1.161 2001/05/30 08:14:52 rgb
40910 + * Removed vestiges of esp-null transforms.
40911 + * NetDev Notifier instrumentation to track down disappearing devices.
40912 + *
40913 + * Revision 1.160 2001/05/29 05:15:12 rgb
40914 + * Added SS' PMTU patch which notifies sender if packet doesn't fit
40915 + * physical MTU (if it wasn't ICMP) and then drops it.
40916 + *
40917 + * Revision 1.159 2001/05/27 06:12:12 rgb
40918 + * Added structures for pid, packet count and last access time to eroute.
40919 + * Added packet count to beginning of /proc/net/ipsec_eroute.
40920 + *
40921 + * Revision 1.158 2001/05/24 05:39:33 rgb
40922 + * Applied source zeroing to 2.2 ip_route_output() call as well to enable
40923 + * PASS eroutes for opportunism.
40924 + *
40925 + * Revision 1.157 2001/05/23 22:35:28 rgb
40926 + * 2.4 source override simplification.
40927 + *
40928 + * Revision 1.156 2001/05/23 21:41:31 rgb
40929 + * Added error return code printing on ip_route_output().
40930 + *
40931 + * Revision 1.155 2001/05/23 05:09:13 rgb
40932 + * Fixed incorrect ip_route_output() failure message.
40933 + *
40934 + * Revision 1.154 2001/05/21 14:53:31 rgb
40935 + * Added debug statement for case when ip_route_output() fails, causing
40936 + * packet to be dropped, but log looked ok.
40937 + *
40938 + * Revision 1.153 2001/05/19 02:37:54 rgb
40939 + * Fixed missing comment termination.
40940 + *
40941 + * Revision 1.152 2001/05/19 02:35:50 rgb
40942 + * Debug code optimisation for non-debug speed.
40943 + * Kernel version compiler define comments.
40944 + * 2.2 and 2.4 kernel ip_send device and ip debug output added.
40945 + *
40946 + * Revision 1.151 2001/05/18 16:17:35 rgb
40947 + * Changed reference from "magic" to "shunt" SAs.
40948 + *
40949 + * Revision 1.150 2001/05/18 16:12:19 rgb
40950 + * Changed UDP/500 bypass test from 3 nested ifs to one anded if.
40951 + *
40952 + * Revision 1.149 2001/05/16 04:39:33 rgb
40953 + * Add default == eroute.dest to IKE bypass conditions for magic eroutes.
40954 + *
40955 + * Revision 1.148 2001/05/05 03:31:41 rgb
40956 + * IP frag debugging updates and enhancements.
40957 + *
40958 + * Revision 1.147 2001/05/03 19:41:40 rgb
40959 + * Added SS' skb_cow fix for 2.4.4.
40960 + *
40961 + * Revision 1.146 2001/04/30 19:28:16 rgb
40962 + * Update for 2.4.4. ip_select_ident() now has 3 args.
40963 + *
40964 + * Revision 1.145 2001/04/23 14:56:10 rgb
40965 + * Added spin_lock() check to prevent double-locking for multiple
40966 + * transforms and hence kernel lock-ups with SMP kernels.
40967 + *
40968 + * Revision 1.144 2001/04/21 23:04:45 rgb
40969 + * Define out skb->used for 2.4 kernels.
40970 + * Check if soft expire has already been sent before sending another to
40971 + * prevent ACQUIRE flooding.
40972 + *
40973 + * Revision 1.143 2001/03/16 07:37:21 rgb
40974 + * Added comments to all #endifs.
40975 + *
40976 + * Revision 1.142 2001/02/28 05:03:27 rgb
40977 + * Clean up and rationalise startup messages.
40978 + *
40979 + * Revision 1.141 2001/02/27 22:24:54 rgb
40980 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
40981 + * Check for satoa() return codes.
40982 + *
40983 + * Revision 1.140 2001/02/27 06:40:12 rgb
40984 + * Fixed TRAP->HOLD eroute byte order.
40985 + *
40986 + * Revision 1.139 2001/02/26 20:38:59 rgb
40987 + * Added compiler defines for 2.4.x-specific code.
40988 + *
40989 + * Revision 1.138 2001/02/26 19:57:27 rgb
40990 + * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
40991 + * of the new SPD and to support opportunistic.
40992 + * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
40993 + *
40994 + * Revision 1.137 2001/02/19 22:29:49 rgb
40995 + * Fixes for presence of active ipv6 segments which share ipsec physical
40996 + * device (gg).
40997 + *
40998 + * Revision 1.136 2001/01/29 22:30:38 rgb
40999 + * Fixed minor acquire debug printing bug.
41000 + *
41001 + * Revision 1.135 2001/01/29 22:19:45 rgb
41002 + * Zero source address for 2.4 bypass route lookup.
41003 + *
41004 + * Revision 1.134 2001/01/23 20:19:49 rgb
41005 + * 2.4 fix to remove removed is_clone member.
41006 + *
41007 + * Revision 1.133 2000/12/09 22:08:35 rgb
41008 + * Fix NET_23 bug, should be NETDEV_23.
41009 + *
41010 + * Revision 1.132 2000/12/01 06:54:50 rgb
41011 + * Fix for new 2.4 IP TTL default variable name.
41012 + *
41013 + * Revision 1.131 2000/11/09 20:52:15 rgb
41014 + * More spinlock shuffling, locking earlier and unlocking later in rcv to
41015 + * include ipcomp and prevent races, renaming some tdb variables that got
41016 + * forgotten, moving some unlocks to include tdbs and adding a missing
41017 + * unlock. Thanks to Svenning for some of these.
41018 + *
41019 + * Revision 1.130 2000/11/09 20:11:22 rgb
41020 + * Minor shuffles to fix non-standard kernel config option selection.
41021 + *
41022 + * Revision 1.129 2000/11/06 04:32:49 rgb
41023 + * Clean up debug printing.
41024 + * Copy skb->protocol for all kernel versions.
41025 + * Ditched spin_lock_irqsave in favour of spin_lock.
41026 + * Disabled TTL decrement, done in ip_forward.
41027 + * Added debug printing before pfkey_acquire().
41028 + * Fixed printk-deltdbchain-spin_lock races (Svenning).
41029 + * Use defaultTTL for 2.1+ kernels.
41030 + * Add Svenning's adaptive content compression.
41031 + * Fix up debug display arguments.
41032 + *
41033 + * Revision 1.128 2000/09/28 00:58:57 rgb
41034 + * Moved the IKE passthrough check after the eroute lookup so we can pass
41035 + * IKE through intermediate tunnels.
41036 + *
41037 + * Revision 1.127 2000/09/22 17:52:11 rgb
41038 + * Fixed misleading ipcomp debug output.
41039 + *
41040 + * Revision 1.126 2000/09/22 04:22:56 rgb
41041 + * Fixed dumb spi->cpi conversion error.
41042 + *
41043 + * Revision 1.125 2000/09/21 04:34:48 rgb
41044 + * A few debug-specific things should be hidden under
41045 + * CONFIG_IPSEC_DEBUG.(MB)
41046 + * Improved ip_send() error handling.(MB)
41047 + *
41048 + * Revision 1.124 2000/09/21 03:40:58 rgb
41049 + * Added more debugging to try and track down the cpi outward copy problem.
41050 + *
41051 + * Revision 1.123 2000/09/19 07:08:49 rgb
41052 + * Added debugging to outgoing compression report.
41053 + *
41054 + * Revision 1.122 2000/09/18 19:21:26 henry
41055 + * RGB-supplied fix for RH5.2 problem
41056 + *
41057 + * Revision 1.121 2000/09/17 21:05:09 rgb
41058 + * Added tdb to skb_compress call to write in cpi.
41059 + *
41060 + * Revision 1.120 2000/09/17 16:57:16 rgb
41061 + * Added Svenning's patch to remove restriction of ipcomp to innermost
41062 + * transform.
41063 + *
41064 + * Revision 1.119 2000/09/15 11:37:01 rgb
41065 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
41066 + * IPCOMP zlib deflate code.
41067 + *
41068 + * Revision 1.118 2000/09/15 04:57:16 rgb
41069 + * Moved debug output after sanity check.
41070 + * Added tos copy sysctl.
41071 + *
41072 + * Revision 1.117 2000/09/12 03:22:51 rgb
41073 + * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
41074 + * sysctl.
41075 + *
41076 + * Revision 1.116 2000/09/08 19:18:19 rgb
41077 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
41078 + * Added outgoing opportunistic hook, ifdef'ed out.
41079 + *
41080 + * Revision 1.115 2000/08/30 05:27:29 rgb
41081 + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
41082 + * Kill remainder of tdb_xform, tdb_xdata, xformsw.
41083 + *
41084 + * Revision 1.114 2000/08/28 18:15:46 rgb
41085 + * Added MB's nf-debug reset patch.
41086 + *
41087 + * Revision 1.113 2000/08/27 02:26:40 rgb
41088 + * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
41089 + * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
41090 + *
41091 + * Revision 1.112 2000/08/20 21:37:33 rgb
41092 + * Activated pfkey_expire() calls.
41093 + * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
41094 + * Re-arranged the order of soft and hard expiry to conform to RFC2367.
41095 + * Clean up references to CONFIG_IPSEC_PFKEYv2.
41096 + *
41097 + * Revision 1.111 2000/08/01 14:51:51 rgb
41098 + * Removed _all_ remaining traces of DES.
41099 + *
41100 + * Revision 1.110 2000/07/28 14:58:31 rgb
41101 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
41102 + *
41103 + * Revision 1.109 2000/07/28 13:50:54 rgb
41104 + * Changed enet_statistics to net_device_stats and added back compatibility
41105 + * for pre-2.1.19.
41106 + *
41107 + * Revision 1.108 2000/05/16 03:03:11 rgb
41108 + * Updates for 2.3.99pre8 from MB.
41109 + *
41110 + * Revision 1.107 2000/05/10 23:08:21 rgb
41111 + * Print a debug warning about bogus packets received by the outgoing
41112 + * processing machinery only when klipsdebug is not set to none.
41113 + * Comment out the device initialisation informational messages.
41114 + *
41115 + * Revision 1.106 2000/05/10 19:17:14 rgb
41116 + * Define an IP_SEND macro, intending to have all packet passthroughs
41117 + * use fragmentation. This didn't quite work, but is a step in the
41118 + * right direction.
41119 + * Added buffer allocation debugging statements.
41120 + * Added configure option to shut off no eroute passthrough.
41121 + * Only check usetime against soft and hard limits if the tdb has been
41122 + * used.
41123 + * Cast output of ntohl so that the broken prototype doesn't make our
41124 + * compile noisy.
41125 + *
41126 + * Revision 1.105 2000/03/22 16:15:37 rgb
41127 + * Fixed renaming of dev_get (MB).
41128 + *
41129 + * Revision 1.104 2000/03/16 14:04:15 rgb
41130 + * Indented headers for readability.
41131 + * Fixed debug scope to enable compilation with debug off.
41132 + * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
41133 + *
41134 + * Revision 1.103 2000/03/16 07:11:07 rgb
41135 + * Hardcode PF_KEYv2 support.
41136 + * Fixed bug which allowed UDP/500 packet from another machine
41137 + * through in the clear.
41138 + * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
41139 + *
41140 + * Revision 1.102 2000/03/14 12:26:59 rgb
41141 + * Added skb->nfct support for clearing netfilter conntrack bits (MB).
41142 + *
41143 + * Revision 1.101 2000/02/14 21:05:22 rgb
41144 + * Added MB's netif_queue fix for kernels 2.3.43+.
41145 + *
41146 + * Revision 1.100 2000/01/26 10:04:57 rgb
41147 + * Fixed noisy 2.0 printk arguments.
41148 + *
41149 + * Revision 1.99 2000/01/21 06:16:25 rgb
41150 + * Added sanity checks on skb_push(), skb_pull() to prevent panics.
41151 + * Switched to AF_ENCAP macro.
41152 + * Shortened debug output per packet and re-arranging debug_tunnel
41153 + * bitmap flags, while retaining necessary information to avoid
41154 + * trampling the kernel print ring buffer.
41155 + * Reformatted recursion switch code.
41156 + * Changed all references to tdb_proto to tdb_said.proto for clarity.
41157 + *
41158 + * Revision 1.98 2000/01/13 08:09:31 rgb
41159 + * Shuffled debug_tunnel switches to focus output.
41160 + * Fixed outgoing recursion bug, limiting to recursing only if the remote
41161 + * SG changes and if it is valid, ie. not passthrough.
41162 + * Clarified a number of debug messages.
41163 + *
41164 + * Revision 1.97 2000/01/10 16:37:16 rgb
41165 + * MB support for new ip_select_ident() upon disappearance of
41166 + * ip_id_count in 2.3.36+.
41167 + *
41168 + * Revision 1.96 1999/12/31 14:59:08 rgb
41169 + * MB fix to use new skb_copy_expand in kernel 2.3.35.
41170 + *
41171 + * Revision 1.95 1999/12/29 21:15:44 rgb
41172 + * Fix tncfg to aliased device bug.
41173 + *
41174 + * Revision 1.94 1999/12/22 04:26:06 rgb
41175 + * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
41176 + * debugging by providing external labels to all functions with debugging
41177 + * turned on.
41178 + *
41179 + * Revision 1.93 1999/12/13 13:30:14 rgb
41180 + * Changed MTU reports and HW address reporting back to debug only.
41181 + *
41182 + * Revision 1.92 1999/12/07 18:57:56 rgb
41183 + * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
41184 + *
41185 + * Revision 1.91 1999/12/01 22:15:36 rgb
41186 + * Add checks for LARVAL and DEAD SAs.
41187 + * Change state of SA from MATURE to DYING when a soft lifetime is
41188 + * reached and print debug warning.
41189 + *
41190 + * Revision 1.90 1999/11/23 23:04:04 rgb
41191 + * Use provided macro ADDRTOA_BUF instead of hardcoded value.
41192 + * Sort out pfkey and freeswan headers, putting them in a library path.
41193 + *
41194 + * Revision 1.89 1999/11/18 18:50:59 rgb
41195 + * Changed all device registrations for static linking to
41196 + * dynamic to reduce the number and size of patches.
41197 + *
41198 + * Revision 1.88 1999/11/18 04:09:19 rgb
41199 + * Replaced all kernel version macros to shorter, readable form.
41200 + *
41201 + * Revision 1.87 1999/11/17 15:53:40 rgb
41202 + * Changed all occurrences of #include "../../../lib/freeswan.h"
41203 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
41204 + * klips/net/ipsec/Makefile.
41205 + *
41206 + * Revision 1.86 1999/10/16 18:25:37 rgb
41207 + * Moved SA lifetime expiry checks before packet processing.
41208 + * Expire SA on replay counter rollover.
41209 + *
41210 + * Revision 1.85 1999/10/16 04:24:31 rgb
41211 + * Add stats for time since last packet.
41212 + *
41213 + * Revision 1.84 1999/10/16 00:30:47 rgb
41214 + * Added SA lifetime counting.
41215 + *
41216 + * Revision 1.83 1999/10/15 22:15:57 rgb
41217 + * Clean out cruft.
41218 + * Add debugging.
41219 + *
41220 + * Revision 1.82 1999/10/08 18:26:19 rgb
41221 + * Fix 2.0.3x outgoing fragmented packet memory leak.
41222 + *
41223 + * Revision 1.81 1999/10/05 02:38:54 rgb
41224 + * Lower the default mtu of virtual devices to 16260.
41225 + *
41226 + * Revision 1.80 1999/10/03 18:56:41 rgb
41227 + * Spinlock support for 2.3.xx.
41228 + * Don't forget to undo spinlocks on error!
41229 + * Check for valid eroute before copying the structure.
41230 + *
41231 + * Revision 1.79 1999/10/01 15:44:53 rgb
41232 + * Move spinlock header include to 2.1> scope.
41233 + *
41234 + * Revision 1.78 1999/10/01 00:02:43 rgb
41235 + * Added tdb structure locking.
41236 + * Added eroute structure locking.
41237 + *
41238 + * Revision 1.77 1999/09/30 02:52:29 rgb
41239 + * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
41240 + *
41241 + * Revision 1.76 1999/09/25 19:31:27 rgb
41242 + * Refine MSS hack to affect SYN, but not SYN+ACK packets.
41243 + *
41244 + * Revision 1.75 1999/09/24 22:52:38 rgb
41245 + * Fix two things broken in 2.0.38 by trying to fix network notifiers.
41246 + *
41247 + * Revision 1.74 1999/09/24 00:30:37 rgb
41248 + * Add test for changed source as well as destination to check for
41249 + * recursion.
41250 + *
41251 + * Revision 1.73 1999/09/23 20:52:24 rgb
41252 + * Add James Morris' MSS hack patch, disabled.
41253 + *
41254 + * Revision 1.72 1999/09/23 20:22:40 rgb
41255 + * Enable, tidy and fix network notifier code.
41256 + *
41257 + * Revision 1.71 1999/09/23 18:09:05 rgb
41258 + * Clean up 2.2.x fragmenting traces.
41259 + * Disable dev->type switching, forcing ARPHRD_TUNNEL.
41260 + *
41261 + * Revision 1.70 1999/09/22 14:14:24 rgb
41262 + * Add sanity checks for revectored calls to prevent calling a downed I/F.
41263 + *
41264 + * Revision 1.69 1999/09/21 15:00:57 rgb
41265 + * Add Marc Boucher's packet size check.
41266 + * Flesh out network device notifier code.
41267 + *
41268 + * Revision 1.68 1999/09/18 11:39:57 rgb
41269 + * Start to add (disabled) netdevice notifier code.
41270 + *
41271 + * Revision 1.67 1999/09/17 23:44:40 rgb
41272 + * Add a comment warning potential code hackers to stay away from mac.raw.
41273 + *
41274 + * Revision 1.66 1999/09/17 18:04:02 rgb
41275 + * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
41276 + * Ditch TTL decrement in 2.2 (MB).
41277 + *
41278 + * Revision 1.65 1999/09/15 23:15:35 henry
41279 + * Marc Boucher's PPP fixes
41280 + *
41281 + * Revision 1.64 1999/09/07 13:40:53 rgb
41282 + * Ditch unreliable references to skb->mac.raw.
41283 + *
41284 + * Revision 1.63 1999/08/28 11:33:09 rgb
41285 + * Check for null skb->mac pointer.
41286 + *
41287 + * Revision 1.62 1999/08/28 02:02:30 rgb
41288 + * Add Marc Boucher's fix for properly dealing with skb->sk.
41289 + *
41290 + * Revision 1.61 1999/08/27 05:23:05 rgb
41291 + * Clean up skb->data/raw/nh/h manipulation.
41292 + * Add Marc Boucher's mods to aid tcpdump.
41293 + * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
41294 + * Re-order hard_header stripping -- might be able to remove it...
41295 + *
41296 + * Revision 1.60 1999/08/26 20:01:02 rgb
41297 + * Tidy up compiler directives and macros.
41298 + * Re-enable ICMP for tunnels where inner_dst != outer_dst.
41299 + * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
41300 + *
41301 + * Revision 1.59 1999/08/25 15:44:41 rgb
41302 + * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
41303 + *
41304 + * Revision 1.58 1999/08/25 15:00:54 rgb
41305 + * Add dst cache code for 2.2.xx.
41306 + * Add sanity check for skb packet header pointers.
41307 + * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
41308 + * *_rebuild_header.
41309 + * Add neigh_* cache code.
41310 + * Change dev->type back to ARPHRD_TUNNEL.
41311 + *
41312 + * Revision 1.57 1999/08/17 21:50:23 rgb
41313 + * Fixed minor debug output bugs.
41314 + * Regrouped error recovery exit code.
41315 + * Added compiler directives to remove unwanted code and symbols.
41316 + * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
41317 + * Add debugging code for output function addresses.
41318 + * Fix minor bug in (possibly unused) header_cache_bind function.
41319 + * Add device neighbour caching code.
41320 + * Change dev->type from ARPHRD_TUNNEL to physdev->type.
41321 + *
41322 + * Revision 1.56 1999/08/03 17:22:56 rgb
41323 + * Debug output clarification using KERN_* macros. Other inactive changes
41324 + * added.
41325 + *
41326 + * Revision 1.55 1999/08/03 16:58:46 rgb
41327 + * Fix skb_copy_expand size bug. Was getting incorrect size.
41328 + *
41329 + * Revision 1.54 1999/07/14 19:32:38 rgb
41330 + * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
41331 + *
41332 + * Revision 1.53 1999/06/10 15:44:02 rgb
41333 + * Minor reformatting and clean-up.
41334 + *
41335 + * Revision 1.52 1999/05/09 03:25:36 rgb
41336 + * Fix bug introduced by 2.2 quick-and-dirty patch.
41337 + *
41338 + * Revision 1.51 1999/05/08 21:24:59 rgb
41339 + * Add casting to silence the 2.2.x compile.
41340 + *
41341 + * Revision 1.50 1999/05/05 22:02:32 rgb
41342 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
41343 + *
41344 + * Revision 1.49 1999/04/29 15:18:52 rgb
41345 + * Change gettdb parameter to a pointer to reduce stack loading and
41346 + * facilitate parameter sanity checking.
41347 + * Fix undetected bug that might have tried to access a null pointer.
41348 + * Eliminate unnessessary usage of tdb_xform member to further switch
41349 + * away from the transform switch to the algorithm switch.
41350 + * Add return values to init and cleanup functions.
41351 + *
41352 + * Revision 1.48 1999/04/16 15:38:00 rgb
41353 + * Minor rearrangement of freeing code to avoid memory leaks with impossible or
41354 + * rare situations.
41355 + *
41356 + * Revision 1.47 1999/04/15 15:37:25 rgb
41357 + * Forward check changes from POST1_00 branch.
41358 + *
41359 + * Revision 1.32.2.4 1999/04/13 21:00:18 rgb
41360 + * Ditch 'things I wish I had known before...'.
41361 + *
41362 + * Revision 1.32.2.3 1999/04/13 20:34:38 rgb
41363 + * Free skb after fragmentation.
41364 + * Use stats more effectively.
41365 + * Add I/F to mtu notch-down reporting.
41366 + *
41367 + * Revision 1.32.2.2 1999/04/02 04:26:14 rgb
41368 + * Backcheck from HEAD, pre1.0.
41369 + *
41370 + * Revision 1.46 1999/04/11 00:29:00 henry
41371 + * GPL boilerplate
41372 + *
41373 + * Revision 1.45 1999/04/07 15:42:01 rgb
41374 + * Fix mtu/ping bug AGAIN!
41375 + *
41376 + * Revision 1.44 1999/04/06 04:54:27 rgb
41377 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
41378 + * patch shell fixes.
41379 + *
41380 + * Revision 1.43 1999/04/04 03:57:07 rgb
41381 + * ip_fragment() doesn't free the supplied skb. Freed.
41382 + *
41383 + * Revision 1.42 1999/04/01 23:27:15 rgb
41384 + * Preload size of virtual mtu.
41385 + *
41386 + * Revision 1.41 1999/04/01 09:31:23 rgb
41387 + * Invert meaning of ICMP PMTUD config option and clarify.
41388 + * Code clean-up.
41389 + *
41390 + * Revision 1.40 1999/04/01 04:37:17 rgb
41391 + * SSH stalling bug fix.
41392 + *
41393 + * Revision 1.39 1999/03/31 23:44:28 rgb
41394 + * Don't send ICMP on DF and frag_off.
41395 + *
41396 + * Revision 1.38 1999/03/31 15:20:10 rgb
41397 + * Quiet down debugging.
41398 + *
41399 + * Revision 1.37 1999/03/31 08:30:31 rgb
41400 + * Add switch to shut off ICMP PMTUD packets.
41401 + *
41402 + * Revision 1.36 1999/03/31 05:44:47 rgb
41403 + * Keep PMTU reduction private.
41404 + *
41405 + * Revision 1.35 1999/03/27 15:13:02 rgb
41406 + * PMTU/fragmentation bug fix.
41407 + *
41408 + * Revision 1.34 1999/03/17 21:19:26 rgb
41409 + * Fix kmalloc nonatomic bug.
41410 + *
41411 + * Revision 1.33 1999/03/17 15:38:42 rgb
41412 + * Code clean-up.
41413 + * ESP_NULL IV bug fix.
41414 + *
41415 + * Revision 1.32 1999/03/01 20:44:25 rgb
41416 + * Code clean-up.
41417 + * Memory leak bug fix.
41418 + *
41419 + * Revision 1.31 1999/02/27 00:02:09 rgb
41420 + * Tune to report the MTU reduction once, rather than after every recursion
41421 + * through the encapsulating code, preventing tcp stream stalling.
41422 + *
41423 + * Revision 1.30 1999/02/24 20:21:01 rgb
41424 + * Reformat debug printk's.
41425 + * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
41426 + * Clean-up.
41427 + *
41428 + * Revision 1.29 1999/02/22 17:08:14 rgb
41429 + * Fix recursive encapsulation code.
41430 + *
41431 + * Revision 1.28 1999/02/19 18:27:02 rgb
41432 + * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
41433 + *
41434 + * Revision 1.27 1999/02/17 16:51:37 rgb
41435 + * Clean out unused cruft.
41436 + * Temporarily tone down volume of debug output.
41437 + * Temporarily shut off fragment rejection.
41438 + * Disabled temporary failed recursive encapsulation loop.
41439 + *
41440 + * Revision 1.26 1999/02/12 21:21:26 rgb
41441 + * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
41442 + *
41443 + * Revision 1.25 1999/02/11 19:38:27 rgb
41444 + * More clean-up.
41445 + * Add sanity checking for skb_copy_expand() to prevent kernel panics on
41446 + * skb_put() values out of range.
41447 + * Fix head/tailroom calculation causing skb_put() out-of-range values.
41448 + * Fix return values to prevent 'nonatomic alloc_skb' warnings.
41449 + * Allocate new skb iff needed.
41450 + * Added more debug statements.
41451 + * Make headroom depend on structure, not hard-coded values.
41452 + *
41453 + * Revision 1.24 1999/02/10 23:20:33 rgb
41454 + * Shut up annoying 'statement has no effect' compiler warnings with
41455 + * debugging compiled out.
41456 + *
41457 + * Revision 1.23 1999/02/10 22:36:30 rgb
41458 + * Clean-up obsolete, unused and messy code.
41459 + * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
41460 + * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
41461 + * original ipsec_tunnel_start_xmit.
41462 + * Send all packet with different inner and outer destinations directly to
41463 + * the attached physical device, rather than back through ip_forward,
41464 + * preventing disappearing routes problems.
41465 + * Do sanity checking before investing too much CPU in allocating new
41466 + * structures.
41467 + * Fail on IP header options: We cannot process them yet.
41468 + * Add some helpful comments.
41469 + * Use virtual device for parameters instead of physical device.
41470 + *
41471 + * Revision 1.22 1999/02/10 03:03:02 rgb
41472 + * Duh. Fixed the TTL bug: forgot to update the checksum.
41473 + *
41474 + * Revision 1.21 1999/02/09 23:17:53 rgb
41475 + * Add structure members to ipsec_print_ip debug function.
41476 + * Temporarily fix TTL bug preventing tunnel mode from functioning.
41477 + *
41478 + * Revision 1.20 1999/02/09 00:14:25 rgb
41479 + * Add KLIPSPRINT macro. (Not used yet, though.)
41480 + * Delete old ip_tunnel code (BADCODE).
41481 + * Decrement TTL in outgoing packet.
41482 + * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
41483 + * Delete ethernet only feature and fix hard-coded hard_header_len.
41484 + *
41485 + * Revision 1.19 1999/01/29 17:56:22 rgb
41486 + * 64-bit re-fix submitted by Peter Onion.
41487 + *
41488 + * Revision 1.18 1999/01/28 22:43:24 rgb
41489 + * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
41490 + *
41491 + * Revision 1.17 1999/01/26 02:08:16 rgb
41492 + * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
41493 + * Removed dead code.
41494 + *
41495 + * Revision 1.16 1999/01/22 06:25:26 rgb
41496 + * Cruft clean-out.
41497 + * Added algorithm switch code.
41498 + * 64-bit clean-up.
41499 + * Passthrough on IPIP protocol, spi 0x0 fix.
41500 + * Enhanced debugging.
41501 + *
41502 + * Revision 1.15 1998/12/01 13:22:04 rgb
41503 + * Added support for debug printing of version info.
41504 + *
41505 + * Revision 1.14 1998/11/30 13:22:55 rgb
41506 + * Rationalised all the klips kernel file headers. They are much shorter
41507 + * now and won't conflict under RH5.2.
41508 + *
41509 + * Revision 1.13 1998/11/17 21:13:52 rgb
41510 + * Put IKE port bypass debug output in user-switched debug statements.
41511 + *
41512 + * Revision 1.12 1998/11/13 13:20:25 rgb
41513 + * Fixed ntohs bug in udp/500 hole for IKE.
41514 + *
41515 + * Revision 1.11 1998/11/10 08:01:19 rgb
41516 + * Kill tcp/500 hole, keep udp/500 hole.
41517 + *
41518 + * Revision 1.10 1998/11/09 21:29:26 rgb
41519 + * If no eroute is found, discard packet and incr. tx_error.
41520 + *
41521 + * Revision 1.9 1998/10/31 06:50:00 rgb
41522 + * Add tcp/udp/500 bypass.
41523 + * Fixed up comments in #endif directives.
41524 + *
41525 + * Revision 1.8 1998/10/27 00:34:31 rgb
41526 + * Reformat debug output of IP headers.
41527 + * Newlines added before calls to ipsec_print_ip.
41528 + *
41529 + * Revision 1.7 1998/10/19 14:44:28 rgb
41530 + * Added inclusion of freeswan.h.
41531 + * sa_id structure implemented and used: now includes protocol.
41532 + *
41533 + * Revision 1.6 1998/10/09 04:31:35 rgb
41534 + * Added 'klips_debug' prefix to all klips printk debug statements.
41535 + *
41536 + * Revision 1.5 1998/08/28 03:09:51 rgb
41537 + * Prevent kernel log spam with default route through ipsec.
41538 + *
41539 + * Revision 1.4 1998/08/05 22:23:09 rgb
41540 + * Change setdev return code to ENXIO for a non-existant physical device.
41541 + *
41542 + * Revision 1.3 1998/07/29 20:41:11 rgb
41543 + * Add ipsec_tunnel_clear to clear all tunnel attachments.
41544 + *
41545 + * Revision 1.2 1998/06/25 20:00:33 rgb
41546 + * Clean up #endif comments.
41547 + * Rename dev_ipsec to dev_ipsec0 for consistency.
41548 + * Document ipsec device fields.
41549 + * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
41550 + * Get debugging report for *every* ipsec device initialisation.
41551 + * Comment out redundant code.
41552 + *
41553 + * Revision 1.1 1998/06/18 21:27:50 henry
41554 + * move sources from klips/src to klips/net/ipsec, to keep stupid
41555 + * kernel-build scripts happier in the presence of symlinks
41556 + *
41557 + * Revision 1.8 1998/06/14 23:49:40 rgb
41558 + * Clarify version reporting on module loading.
41559 + *
41560 + * Revision 1.7 1998/05/27 23:19:20 rgb
41561 + * Added version reporting.
41562 + *
41563 + * Revision 1.6 1998/05/18 21:56:23 rgb
41564 + * Clean up for numerical consistency of output and cleaning up debug code.
41565 + *
41566 + * Revision 1.5 1998/05/12 02:44:23 rgb
41567 + * Clarifying 'no e-route to host' message.
41568 + *
41569 + * Revision 1.4 1998/04/30 15:34:35 rgb
41570 + * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
41571 + *
41572 + * Revision 1.3 1998/04/21 21:28:54 rgb
41573 + * Rearrange debug switches to change on the fly debug output from user
41574 + * space. Only kernel changes checked in at this time. radij.c was also
41575 + * changed to temporarily remove buggy debugging code in rj_delete causing
41576 + * an OOPS and hence, netlink device open errors.
41577 + *
41578 + * Revision 1.2 1998/04/12 22:03:24 rgb
41579 + * Updated ESP-3DES-HMAC-MD5-96,
41580 + * ESP-DES-HMAC-MD5-96,
41581 + * AH-HMAC-MD5-96,
41582 + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
41583 + * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
41584 + *
41585 + * Fixed eroute references in /proc/net/ipsec*.
41586 + *
41587 + * Started to patch module unloading memory leaks in ipsec_netlink and
41588 + * radij tree unloading.
41589 + *
41590 + * Revision 1.1 1998/04/09 03:06:12 henry
41591 + * sources moved up from linux/net/ipsec
41592 + *
41593 + * Revision 1.1.1.1 1998/04/08 05:35:04 henry
41594 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
41595 + *
41596 + * Revision 0.5 1997/06/03 04:24:48 ji
41597 + * Added transport mode.
41598 + * Changed the way routing is done.
41599 + * Lots of bug fixes.
41600 + *
41601 + * Revision 0.4 1997/01/15 01:28:15 ji
41602 + * No changes.
41603 + *
41604 + * Revision 0.3 1996/11/20 14:39:04 ji
41605 + * Minor cleanups.
41606 + * Rationalized debugging code.
41607 + *
41608 + * Revision 0.2 1996/11/02 00:18:33 ji
41609 + * First limited release.
41610 + *
41611 + * Local Variables:
41612 + * c-style: linux
41613 + * End:
41614 + */
41615 --- /dev/null Tue Mar 11 13:02:56 2003
41616 +++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004
41617 @@ -0,0 +1,360 @@
41618 +/*
41619 + * Common routines for IPSEC transformations.
41620 + * Copyright (C) 1996, 1997 John Ioannidis.
41621 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
41622 + *
41623 + * This program is free software; you can redistribute it and/or modify it
41624 + * under the terms of the GNU General Public License as published by the
41625 + * Free Software Foundation; either version 2 of the License, or (at your
41626 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
41627 + *
41628 + * This program is distributed in the hope that it will be useful, but
41629 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
41630 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41631 + * for more details.
41632 + *
41633 + * RCSID $Id: ipsec_xform.c,v 1.65.2.1 2006/10/06 21:39:26 paul Exp $
41634 + */
41635 +
41636 +#ifndef AUTOCONF_INCLUDED
41637 +#include <linux/config.h>
41638 +#endif
41639 +#include <linux/version.h>
41640 +#include <linux/kernel.h> /* printk() */
41641 +
41642 +#include "freeswan/ipsec_param.h"
41643 +
41644 +#ifdef MALLOC_SLAB
41645 +# include <linux/slab.h> /* kmalloc() */
41646 +#else /* MALLOC_SLAB */
41647 +# include <linux/malloc.h> /* kmalloc() */
41648 +#endif /* MALLOC_SLAB */
41649 +#include <linux/errno.h> /* error codes */
41650 +#include <linux/types.h> /* size_t */
41651 +#include <linux/interrupt.h> /* mark_bh */
41652 +
41653 +#include <linux/netdevice.h> /* struct device, and other headers */
41654 +#include <linux/etherdevice.h> /* eth_type_trans */
41655 +#include <linux/ip.h> /* struct iphdr */
41656 +#include <linux/skbuff.h>
41657 +#include <linux/random.h> /* get_random_bytes() */
41658 +#include <freeswan.h>
41659 +#ifdef SPINLOCK
41660 +# ifdef SPINLOCK_23
41661 +# include <linux/spinlock.h> /* *lock* */
41662 +# else /* SPINLOCK_23 */
41663 +# include <asm/spinlock.h> /* *lock* */
41664 +# endif /* SPINLOCK_23 */
41665 +#endif /* SPINLOCK */
41666 +
41667 +#include <net/ip.h>
41668 +
41669 +#include "freeswan/radij.h"
41670 +#include "freeswan/ipsec_encap.h"
41671 +#include "freeswan/ipsec_radij.h"
41672 +#include "freeswan/ipsec_xform.h"
41673 +#include "freeswan/ipsec_ipe4.h"
41674 +#include "freeswan/ipsec_ah.h"
41675 +#include "freeswan/ipsec_esp.h"
41676 +
41677 +#include <pfkeyv2.h>
41678 +#include <pfkey.h>
41679 +
41680 +#ifdef CONFIG_KLIPS_DEBUG
41681 +int debug_xform = 0;
41682 +#endif /* CONFIG_KLIPS_DEBUG */
41683 +
41684 +#ifdef SPINLOCK
41685 +spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
41686 +#else /* SPINLOCK */
41687 +spinlock_t tdb_lock;
41688 +#endif /* SPINLOCK */
41689 +
41690 +/*
41691 + * $Log: ipsec_xform.c,v $
41692 + * Revision 1.65.2.1 2006/10/06 21:39:26 paul
41693 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
41694 + * set. This is defined through autoconf.h which is included through the
41695 + * linux kernel build macros.
41696 + *
41697 + * Revision 1.65 2005/04/29 05:10:22 mcr
41698 + * removed from extraenous includes to make unit testing easier.
41699 + *
41700 + * Revision 1.64 2004/07/10 19:11:18 mcr
41701 + * CONFIG_IPSEC -> CONFIG_KLIPS.
41702 + *
41703 + * Revision 1.63 2003/10/31 02:27:55 mcr
41704 + * pulled up port-selector patches and sa_id elimination.
41705 + *
41706 + * Revision 1.62.30.1 2003/10/29 01:30:41 mcr
41707 + * elimited "struct sa_id".
41708 + *
41709 + * Revision 1.62 2002/05/14 02:34:21 rgb
41710 + * Delete stale code.
41711 + *
41712 + * Revision 1.61 2002/04/24 07:55:32 mcr
41713 + * #include patches and Makefiles for post-reorg compilation.
41714 + *
41715 + * Revision 1.60 2002/04/24 07:36:33 mcr
41716 + * Moved from ./klips/net/ipsec/ipsec_xform.c,v
41717 + *
41718 + * Revision 1.59 2002/03/29 15:01:36 rgb
41719 + * Delete decommissioned code.
41720 + *
41721 + * Revision 1.58 2002/01/29 17:17:57 mcr
41722 + * moved include of ipsec_param.h to after include of linux/kernel.h
41723 + * otherwise, it seems that some option that is set in ipsec_param.h
41724 + * screws up something subtle in the include path to kernel.h, and
41725 + * it complains on the snprintf() prototype.
41726 + *
41727 + * Revision 1.57 2002/01/29 04:00:53 mcr
41728 + * more excise of kversions.h header.
41729 + *
41730 + * Revision 1.56 2001/11/27 05:17:22 mcr
41731 + * turn off the worst of the per-packet debugging.
41732 + *
41733 + * Revision 1.55 2001/11/26 09:23:50 rgb
41734 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
41735 + *
41736 + * Revision 1.54 2001/10/18 04:45:21 rgb
41737 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
41738 + * lib/freeswan.h version macros moved to lib/kversions.h.
41739 + * Other compiler directive cleanups.
41740 + *
41741 + * Revision 1.53 2001/09/08 21:13:34 rgb
41742 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
41743 + *
41744 + * Revision 1.52 2001/06/14 19:35:11 rgb
41745 + * Update copyright date.
41746 + *
41747 + * Revision 1.51 2001/05/30 08:14:03 rgb
41748 + * Removed vestiges of esp-null transforms.
41749 + *
41750 + * Revision 1.50 2001/05/03 19:43:18 rgb
41751 + * Initialise error return variable.
41752 + * Update SENDERR macro.
41753 + * Fix sign of error return code for ipsec_tdbcleanup().
41754 + * Use more appropriate return code for ipsec_tdbwipe().
41755 + *
41756 + * Revision 1.49 2001/04/19 18:56:17 rgb
41757 + * Fixed tdb table locking comments.
41758 + *
41759 + * Revision 1.48 2001/02/27 22:24:55 rgb
41760 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
41761 + * Check for satoa() return codes.
41762 + *
41763 + * Revision 1.47 2000/11/06 04:32:08 rgb
41764 + * Ditched spin_lock_irqsave in favour of spin_lock_bh.
41765 + *
41766 + * Revision 1.46 2000/09/20 16:21:57 rgb
41767 + * Cleaned up ident string alloc/free.
41768 + *
41769 + * Revision 1.45 2000/09/08 19:16:51 rgb
41770 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
41771 + * Removed all references to CONFIG_IPSEC_PFKEYv2.
41772 + *
41773 + * Revision 1.44 2000/08/30 05:29:04 rgb
41774 + * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
41775 + *
41776 + * Revision 1.43 2000/08/18 21:30:41 rgb
41777 + * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
41778 + *
41779 + * Revision 1.42 2000/08/01 14:51:51 rgb
41780 + * Removed _all_ remaining traces of DES.
41781 + *
41782 + * Revision 1.41 2000/07/28 14:58:31 rgb
41783 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
41784 + *
41785 + * Revision 1.40 2000/06/28 05:50:11 rgb
41786 + * Actually set iv_bits.
41787 + *
41788 + * Revision 1.39 2000/05/10 23:11:09 rgb
41789 + * Added netlink debugging output.
41790 + * Added a cast to quiet down the ntohl bug.
41791 + *
41792 + * Revision 1.38 2000/05/10 19:18:42 rgb
41793 + * Cast output of ntohl so that the broken prototype doesn't make our
41794 + * compile noisy.
41795 + *
41796 + * Revision 1.37 2000/03/16 14:04:59 rgb
41797 + * Hardwired CONFIG_IPSEC_PFKEYv2 on.
41798 + *
41799 + * Revision 1.36 2000/01/26 10:11:28 rgb
41800 + * Fixed spacing in error text causing run-in words.
41801 + *
41802 + * Revision 1.35 2000/01/21 06:17:16 rgb
41803 + * Tidied up compiler directive indentation for readability.
41804 + * Added ictx,octx vars for simplification.(kravietz)
41805 + * Added macros for HMAC padding magic numbers.(kravietz)
41806 + * Fixed missing key length reporting bug.
41807 + * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
41808 + *
41809 + * Revision 1.34 1999/12/08 00:04:19 rgb
41810 + * Fixed SA direction overwriting bug for netlink users.
41811 + *
41812 + * Revision 1.33 1999/12/01 22:16:44 rgb
41813 + * Minor formatting changes in ESP MD5 initialisation.
41814 + *
41815 + * Revision 1.32 1999/11/25 09:06:36 rgb
41816 + * Fixed error return messages, should be returning negative numbers.
41817 + * Implemented SENDERR macro for propagating error codes.
41818 + * Added debug message and separate error code for algorithms not compiled
41819 + * in.
41820 + *
41821 + * Revision 1.31 1999/11/23 23:06:26 rgb
41822 + * Sort out pfkey and freeswan headers, putting them in a library path.
41823 + *
41824 + * Revision 1.30 1999/11/18 04:09:20 rgb
41825 + * Replaced all kernel version macros to shorter, readable form.
41826 + *
41827 + * Revision 1.29 1999/11/17 15:53:40 rgb
41828 + * Changed all occurrences of #include "../../../lib/freeswan.h"
41829 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
41830 + * klips/net/ipsec/Makefile.
41831 + *
41832 + * Revision 1.28 1999/10/18 20:04:01 rgb
41833 + * Clean-out unused cruft.
41834 + *
41835 + * Revision 1.27 1999/10/03 19:01:03 rgb
41836 + * Spinlock support for 2.3.xx and 2.0.xx kernels.
41837 + *
41838 + * Revision 1.26 1999/10/01 16:22:24 rgb
41839 + * Switch from assignment init. to functional init. of spinlocks.
41840 + *
41841 + * Revision 1.25 1999/10/01 15:44:54 rgb
41842 + * Move spinlock header include to 2.1> scope.
41843 + *
41844 + * Revision 1.24 1999/10/01 00:03:46 rgb
41845 + * Added tdb structure locking.
41846 + * Minor formatting changes.
41847 + * Add function to initialize tdb hash table.
41848 + *
41849 + * Revision 1.23 1999/05/25 22:42:12 rgb
41850 + * Add deltdbchain() debugging.
41851 + *
41852 + * Revision 1.22 1999/05/25 21:24:31 rgb
41853 + * Add debugging statements to deltdbchain().
41854 + *
41855 + * Revision 1.21 1999/05/25 03:51:48 rgb
41856 + * Refix error return code.
41857 + *
41858 + * Revision 1.20 1999/05/25 03:34:07 rgb
41859 + * Fix error return for flush.
41860 + *
41861 + * Revision 1.19 1999/05/09 03:25:37 rgb
41862 + * Fix bug introduced by 2.2 quick-and-dirty patch.
41863 + *
41864 + * Revision 1.18 1999/05/05 22:02:32 rgb
41865 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
41866 + *
41867 + * Revision 1.17 1999/04/29 15:20:16 rgb
41868 + * Change gettdb parameter to a pointer to reduce stack loading and
41869 + * facilitate parameter sanity checking.
41870 + * Add sanity checking for null pointer arguments.
41871 + * Add debugging instrumentation.
41872 + * Add function deltdbchain() which will take care of unlinking,
41873 + * zeroing and deleting a chain of tdbs.
41874 + * Add a parameter to tdbcleanup to be able to delete a class of SAs.
41875 + * tdbwipe now actually zeroes the tdb as well as any of its pointed
41876 + * structures.
41877 + *
41878 + * Revision 1.16 1999/04/16 15:36:29 rgb
41879 + * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
41880 + *
41881 + * Revision 1.15 1999/04/11 00:29:01 henry
41882 + * GPL boilerplate
41883 + *
41884 + * Revision 1.14 1999/04/06 04:54:28 rgb
41885 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
41886 + * patch shell fixes.
41887 + *
41888 + * Revision 1.13 1999/02/19 18:23:01 rgb
41889 + * Nix debug off compile warning.
41890 + *
41891 + * Revision 1.12 1999/02/17 16:52:16 rgb
41892 + * Consolidate satoa()s for space and speed efficiency.
41893 + * Convert DEBUG_IPSEC to KLIPS_PRINT
41894 + * Clean out unused cruft.
41895 + * Ditch NET_IPIP dependancy.
41896 + * Loop for 3des key setting.
41897 + *
41898 + * Revision 1.11 1999/01/26 02:09:05 rgb
41899 + * Remove ah/esp/IPIP switching on include files.
41900 + * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
41901 + * Removed dead code.
41902 + * Clean up debug code when switched off.
41903 + * Remove references to INET_GET_PROTOCOL.
41904 + * Added code exclusion macros to reduce code from unused algorithms.
41905 + *
41906 + * Revision 1.10 1999/01/22 06:28:55 rgb
41907 + * Cruft clean-out.
41908 + * Put random IV generation in kernel.
41909 + * Added algorithm switch code.
41910 + * Enhanced debugging.
41911 + * 64-bit clean-up.
41912 + *
41913 + * Revision 1.9 1998/11/30 13:22:55 rgb
41914 + * Rationalised all the klips kernel file headers. They are much shorter
41915 + * now and won't conflict under RH5.2.
41916 + *
41917 + * Revision 1.8 1998/11/25 04:59:06 rgb
41918 + * Add conditionals for no IPIP tunnel code.
41919 + * Delete commented out code.
41920 + *
41921 + * Revision 1.7 1998/10/31 06:50:41 rgb
41922 + * Convert xform ASCII names to no spaces.
41923 + * Fixed up comments in #endif directives.
41924 + *
41925 + * Revision 1.6 1998/10/19 14:44:28 rgb
41926 + * Added inclusion of freeswan.h.
41927 + * sa_id structure implemented and used: now includes protocol.
41928 + *
41929 + * Revision 1.5 1998/10/09 04:32:19 rgb
41930 + * Added 'klips_debug' prefix to all klips printk debug statements.
41931 + *
41932 + * Revision 1.4 1998/08/12 00:11:31 rgb
41933 + * Added new xform functions to the xform table.
41934 + * Fixed minor debug output spelling error.
41935 + *
41936 + * Revision 1.3 1998/07/09 17:45:31 rgb
41937 + * Clarify algorithm not available message.
41938 + *
41939 + * Revision 1.2 1998/06/23 03:00:51 rgb
41940 + * Check for presence of IPIP protocol if it is setup one way (we don't
41941 + * know what has been set up the other way and can only assume it will be
41942 + * symmetrical with the exception of keys).
41943 + *
41944 + * Revision 1.1 1998/06/18 21:27:51 henry
41945 + * move sources from klips/src to klips/net/ipsec, to keep stupid
41946 + * kernel-build scripts happier in the presence of symlinks
41947 + *
41948 + * Revision 1.3 1998/06/11 05:54:59 rgb
41949 + * Added transform version string pointer to xformsw initialisations.
41950 + *
41951 + * Revision 1.2 1998/04/21 21:28:57 rgb
41952 + * Rearrange debug switches to change on the fly debug output from user
41953 + * space. Only kernel changes checked in at this time. radij.c was also
41954 + * changed to temporarily remove buggy debugging code in rj_delete causing
41955 + * an OOPS and hence, netlink device open errors.
41956 + *
41957 + * Revision 1.1 1998/04/09 03:06:13 henry
41958 + * sources moved up from linux/net/ipsec
41959 + *
41960 + * Revision 1.1.1.1 1998/04/08 05:35:02 henry
41961 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
41962 + *
41963 + * Revision 0.5 1997/06/03 04:24:48 ji
41964 + * Added ESP-3DES-MD5-96
41965 + *
41966 + * Revision 0.4 1997/01/15 01:28:15 ji
41967 + * Added new transforms.
41968 + *
41969 + * Revision 0.3 1996/11/20 14:39:04 ji
41970 + * Minor cleanups.
41971 + * Rationalized debugging code.
41972 + *
41973 + * Revision 0.2 1996/11/02 00:18:33 ji
41974 + * First limited release.
41975 + *
41976 + *
41977 + */
41978 --- /dev/null Tue Mar 11 13:02:56 2003
41979 +++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004
41980 @@ -0,0 +1,1855 @@
41981 +/*
41982 + * IPSEC Transmit code.
41983 + * Copyright (C) 1996, 1997 John Ioannidis.
41984 + * Copyright (C) 1998-2003 Richard Guy Briggs.
41985 + * Copyright (C) 2004-2005 Michael Richardson <mcr@xelerance.com>
41986 + *
41987 + * This program is free software; you can redistribute it and/or modify it
41988 + * under the terms of the GNU General Public License as published by the
41989 + * Free Software Foundation; either version 2 of the License, or (at your
41990 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
41991 + *
41992 + * This program is distributed in the hope that it will be useful, but
41993 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
41994 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
41995 + * for more details.
41996 + */
41997 +
41998 +char ipsec_xmit_c_version[] = "RCSID $Id: ipsec_xmit.c,v 1.20.2.9 2007/07/06 17:18:43 paul Exp $";
41999 +
42000 +#define __NO_VERSION__
42001 +#include <linux/module.h>
42002 +#ifndef AUTOCONF_INCLUDED
42003 +#include <linux/config.h>
42004 +#endif /* for CONFIG_IP_FORWARD */
42005 +#include <linux/version.h>
42006 +#include <linux/kernel.h> /* printk() */
42007 +
42008 +#include "openswan/ipsec_param.h"
42009 +
42010 +#ifdef MALLOC_SLAB
42011 +# include <linux/slab.h> /* kmalloc() */
42012 +#else /* MALLOC_SLAB */
42013 +# include <linux/malloc.h> /* kmalloc() */
42014 +#endif /* MALLOC_SLAB */
42015 +#include <linux/errno.h> /* error codes */
42016 +#include <linux/types.h> /* size_t */
42017 +#include <linux/interrupt.h> /* mark_bh */
42018 +
42019 +#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
42020 +#include <linux/etherdevice.h> /* eth_type_trans */
42021 +#include <linux/ip.h> /* struct iphdr */
42022 +#include <linux/tcp.h> /* struct tcphdr */
42023 +#include <linux/udp.h> /* struct udphdr */
42024 +#include <linux/skbuff.h>
42025 +#include <asm/uaccess.h>
42026 +#include <asm/checksum.h>
42027 +#include <openswan.h>
42028 +#ifdef NET_21
42029 +# define MSS_HACK_ /* experimental */
42030 +# include <linux/in6.h>
42031 +# include <net/dst.h>
42032 +# define proto_priv cb
42033 +#endif /* NET_21 */
42034 +
42035 +#include <net/icmp.h> /* icmp_send() */
42036 +#include <net/ip.h>
42037 +#ifdef NETDEV_23
42038 +# include <linux/netfilter_ipv4.h>
42039 +#endif /* NETDEV_23 */
42040 +
42041 +#include <linux/if_arp.h>
42042 +#ifdef MSS_HACK
42043 +# include <net/tcp.h> /* TCP options */
42044 +#endif /* MSS_HACK */
42045 +
42046 +#include "openswan/radij.h"
42047 +#include "openswan/ipsec_life.h"
42048 +#include "openswan/ipsec_xform.h"
42049 +#include "openswan/ipsec_eroute.h"
42050 +#include "openswan/ipsec_encap.h"
42051 +#include "openswan/ipsec_radij.h"
42052 +#include "openswan/ipsec_xmit.h"
42053 +#include "openswan/ipsec_sa.h"
42054 +#include "openswan/ipsec_tunnel.h"
42055 +#include "openswan/ipsec_ipe4.h"
42056 +#include "openswan/ipsec_ah.h"
42057 +#include "openswan/ipsec_esp.h"
42058 +
42059 +#ifdef CONFIG_KLIPS_IPCOMP
42060 +#include "openswan/ipcomp.h"
42061 +#endif /* CONFIG_KLIPS_IPCOMP */
42062 +
42063 +#include <pfkeyv2.h>
42064 +#include <pfkey.h>
42065 +
42066 +#include "openswan/ipsec_proto.h"
42067 +#include "openswan/ipsec_alg.h"
42068 +
42069 +
42070 +/*
42071 + * Stupid kernel API differences in APIs. Not only do some
42072 + * kernels not have ip_select_ident, but some have differing APIs,
42073 + * and SuSE has one with one parameter, but no way of checking to
42074 + * see what is really what.
42075 + */
42076 +
42077 +#ifdef SUSE_LINUX_2_4_19_IS_STUPID
42078 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
42079 +#else
42080 +
42081 +/* simplest case, nothing */
42082 +#if !defined(IP_SELECT_IDENT)
42083 +#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
42084 +#endif
42085 +
42086 +/* kernels > 2.3.37-ish */
42087 +#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
42088 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
42089 +#endif
42090 +
42091 +/* kernels > 2.4.2 */
42092 +#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
42093 +#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
42094 +#endif
42095 +
42096 +#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
42097 +
42098 +
42099 +
42100 +#if defined(CONFIG_KLIPS_AH)
42101 +static __u32 zeroes[64];
42102 +#endif
42103 +
42104 +#ifdef CONFIG_KLIPS_DEBUG
42105 +int sysctl_ipsec_debug_verbose = 0;
42106 +#endif /* CONFIG_KLIPS_DEBUG */
42107 +
42108 +int ipsec_xmit_trap_count = 0;
42109 +int ipsec_xmit_trap_sendcount = 0;
42110 +
42111 +int sysctl_ipsec_icmp = 0;
42112 +int sysctl_ipsec_tos = 0;
42113 +
42114 +#ifdef CONFIG_KLIPS_DEBUG
42115 +#define dmp(_x,_y,_z) if(debug_tunnel) ipsec_dmp_block(_x,_y,_z)
42116 +#else /* CONFIG_KLIPS_DEBUG */
42117 +#define dmp(_x, _y, _z)
42118 +#endif /* CONFIG_KLIPS_DEBUG */
42119 +
42120 +
42121 +#if !defined(SKB_COPY_EXPAND) || defined(KLIPS_UNIT_TESTS)
42122 +/*
42123 + * This is mostly skbuff.c:skb_copy().
42124 + */
42125 +struct sk_buff *
42126 +skb_copy_expand(const struct sk_buff *skb, int headroom,
42127 + int tailroom, int priority)
42128 +{
42129 + struct sk_buff *n;
42130 + unsigned long offset;
42131 +
42132 + /*
42133 + * Do sanity checking
42134 + */
42135 + if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
42136 + printk(KERN_WARNING
42137 + "klips_error:skb_copy_expand: "
42138 + "Illegal negative head,tailroom %d,%d\n",
42139 + headroom,
42140 + tailroom);
42141 + return NULL;
42142 + }
42143 + /*
42144 + * Allocate the copy buffer
42145 + */
42146 +
42147 +#ifndef NET_21
42148 + IS_SKB(skb);
42149 +#endif /* !NET_21 */
42150 +
42151 +
42152 + n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
42153 +
42154 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42155 + "klips_debug:skb_copy_expand: "
42156 + "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
42157 + skb->end - skb->head + headroom + tailroom,
42158 + skb->head,
42159 + skb->data,
42160 + skb->tail,
42161 + skb->end,
42162 + skb->end - skb->head,
42163 + skb->tail - skb->data);
42164 +
42165 + if(n==NULL)
42166 + return NULL;
42167 +
42168 + /*
42169 + * Shift between the two data areas in bytes
42170 + */
42171 +
42172 + /* Set the data pointer */
42173 + skb_reserve(n,skb->data-skb->head+headroom);
42174 + /* Set the tail pointer and length */
42175 + if(skb_tailroom(n) < skb->len) {
42176 + printk(KERN_WARNING "klips_error:skb_copy_expand: "
42177 + "tried to skb_put %ld, %d available. This should never happen, please report.\n",
42178 + (unsigned long int)skb->len,
42179 + skb_tailroom(n));
42180 + ipsec_kfree_skb(n);
42181 + return NULL;
42182 + }
42183 + skb_put(n,skb->len);
42184 +
42185 + offset=n->head + headroom - skb->head;
42186 +
42187 + /* Copy the bytes */
42188 + memcpy(n->head + headroom, skb->head,skb->end-skb->head);
42189 +#ifdef NET_21
42190 + n->csum=skb->csum;
42191 + n->priority=skb->priority;
42192 + n->dst=dst_clone(skb->dst);
42193 + if(skb->nh.raw)
42194 + n->nh.raw=skb->nh.raw+offset;
42195 +#ifndef NETDEV_23
42196 + n->is_clone=0;
42197 +#endif /* NETDEV_23 */
42198 + atomic_set(&n->users, 1);
42199 + n->destructor = NULL;
42200 +#ifdef HAVE_SOCK_SECURITY
42201 + n->security=skb->security;
42202 +#endif
42203 +#else /* NET_21 */
42204 + n->link3=NULL;
42205 + n->when=skb->when;
42206 + if(skb->ip_hdr)
42207 + n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
42208 + n->saddr=skb->saddr;
42209 + n->daddr=skb->daddr;
42210 + n->raddr=skb->raddr;
42211 + n->seq=skb->seq;
42212 + n->end_seq=skb->end_seq;
42213 + n->ack_seq=skb->ack_seq;
42214 + n->acked=skb->acked;
42215 + n->free=1;
42216 + n->arp=skb->arp;
42217 + n->tries=0;
42218 + n->lock=0;
42219 + n->users=0;
42220 +#endif /* NET_21 */
42221 + n->protocol=skb->protocol;
42222 + n->list=NULL;
42223 + n->sk=NULL;
42224 + n->dev=skb->dev;
42225 + if(skb->h.raw)
42226 + n->h.raw=skb->h.raw+offset;
42227 + if(skb->mac.raw)
42228 + n->mac.raw=skb->mac.raw+offset;
42229 + memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
42230 +#ifndef NETDEV_23
42231 + n->used=skb->used;
42232 +#endif /* !NETDEV_23 */
42233 + n->pkt_type=skb->pkt_type;
42234 + n->stamp=skb->stamp;
42235 +
42236 +#ifndef NET_21
42237 + IS_SKB(n);
42238 +#endif /* !NET_21 */
42239 + return n;
42240 +}
42241 +#endif /* !SKB_COPY_EXPAND */
42242 +
42243 +#ifdef CONFIG_KLIPS_DEBUG
42244 +void
42245 +ipsec_print_ip(struct iphdr *ip)
42246 +{
42247 + char buf[ADDRTOA_BUF];
42248 +
42249 + printk(KERN_INFO "klips_debug: IP:");
42250 + printk(" ihl:%d", ip->ihl << 2);
42251 + printk(" ver:%d", ip->version);
42252 + printk(" tos:%d", ip->tos);
42253 + printk(" tlen:%d", ntohs(ip->tot_len));
42254 + printk(" id:%d", ntohs(ip->id));
42255 + printk(" %s%s%sfrag_off:%d",
42256 + ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
42257 + ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
42258 + ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
42259 + (ntohs(ip->frag_off) & IP_OFFSET) << 3);
42260 + printk(" ttl:%d", ip->ttl);
42261 + printk(" proto:%d", ip->protocol);
42262 + if(ip->protocol == IPPROTO_UDP)
42263 + printk(" (UDP)");
42264 + if(ip->protocol == IPPROTO_TCP)
42265 + printk(" (TCP)");
42266 + if(ip->protocol == IPPROTO_ICMP)
42267 + printk(" (ICMP)");
42268 + if(ip->protocol == IPPROTO_ESP)
42269 + printk(" (ESP)");
42270 + if(ip->protocol == IPPROTO_AH)
42271 + printk(" (AH)");
42272 + if(ip->protocol == IPPROTO_COMP)
42273 + printk(" (COMP)");
42274 + printk(" chk:%d", ntohs(ip->check));
42275 + addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
42276 + printk(" saddr:%s", buf);
42277 + if(ip->protocol == IPPROTO_UDP)
42278 + printk(":%d",
42279 + ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
42280 + if(ip->protocol == IPPROTO_TCP)
42281 + printk(":%d",
42282 + ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
42283 + addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
42284 + printk(" daddr:%s", buf);
42285 + if(ip->protocol == IPPROTO_UDP)
42286 + printk(":%d",
42287 + ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
42288 + if(ip->protocol == IPPROTO_TCP)
42289 + printk(":%d",
42290 + ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
42291 + if(ip->protocol == IPPROTO_ICMP)
42292 + printk(" type:code=%d:%d",
42293 + ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
42294 + ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
42295 + printk("\n");
42296 +
42297 + if(sysctl_ipsec_debug_verbose) {
42298 + __u8 *c;
42299 + int len = ntohs(ip->tot_len) - ip->ihl*4;
42300 +
42301 + c = ((__u8*)ip) + ip->ihl*4;
42302 + ipsec_dmp_block("ip_print", c, len);
42303 + }
42304 +}
42305 +#endif /* CONFIG_KLIPS_DEBUG */
42306 +
42307 +#ifdef MSS_HACK
42308 +/*
42309 + * Issues:
42310 + * 1) Fragments arriving in the tunnel should probably be rejected.
42311 + * 2) How does this affect syncookies, mss_cache, dst cache ?
42312 + * 3) Path MTU discovery handling needs to be reviewed. For example,
42313 + * if we receive an ICMP 'packet too big' message from an intermediate
42314 + * router specifying it's next hop MTU, our stack may process this and
42315 + * adjust the MSS without taking our AH/ESP overheads into account.
42316 + */
42317 +
42318 +
42319 +/*
42320 + * Recaclulate checksum using differences between changed datum,
42321 + * borrowed from netfilter.
42322 + */
42323 +DEBUG_NO_STATIC u_int16_t
42324 +ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
42325 +{
42326 + u_int32_t diffs[] = { oldvalinv, newval };
42327 + return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
42328 + oldcheck^0xFFFF));
42329 +}
42330 +
42331 +/*
42332 + * Determine effective MSS.
42333 + *
42334 + * Note that we assume that there is always an MSS option for our own
42335 + * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
42336 + * This could change, and we should probably parse TCP options instead.
42337 + *
42338 + */
42339 +DEBUG_NO_STATIC u_int8_t
42340 +ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
42341 +{
42342 + u_int16_t oldmss, newmss;
42343 + u_int32_t *mssp;
42344 + struct sock *sk = skb->sk;
42345 +
42346 + newmss = tcp_sync_mss(sk, mtu);
42347 + printk(KERN_INFO "klips: setting mss to %u\n", newmss);
42348 + mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
42349 + oldmss = ntohl(*mssp) & 0x0000FFFF;
42350 + *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
42351 + tcph->check = ipsec_fast_csum(htons(~oldmss),
42352 + htons(newmss), tcph->check);
42353 + return 1;
42354 +}
42355 +#endif /* MSS_HACK */
42356 +
42357 +/*
42358 + * Sanity checks
42359 + */
42360 +enum ipsec_xmit_value
42361 +ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs)
42362 +{
42363 +
42364 + if (ixs->dev == NULL) {
42365 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42366 + "klips_error:ipsec_xmit_sanity_check_dev: "
42367 + "No device associated with skb!\n" );
42368 + return IPSEC_XMIT_NODEV;
42369 + }
42370 +
42371 + ixs->prv = ixs->dev->priv;
42372 + if (ixs->prv == NULL) {
42373 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42374 + "klips_error:ipsec_xmit_sanity_check_dev: "
42375 + "Device has no private structure!\n" );
42376 + return IPSEC_XMIT_NOPRIVDEV;
42377 + }
42378 +
42379 + ixs->physdev = ixs->prv->dev;
42380 + if (ixs->physdev == NULL) {
42381 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42382 + "klips_error:ipsec_xmit_sanity_check_dev: "
42383 + "Device is not attached to physical device!\n" );
42384 + return IPSEC_XMIT_NOPHYSDEV;
42385 + }
42386 +
42387 + ixs->physmtu = ixs->physdev->mtu;
42388 + ixs->cur_mtu = ixs->physdev->mtu;
42389 + ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);
42390 +
42391 + return IPSEC_XMIT_OK;
42392 +}
42393 +
42394 +enum ipsec_xmit_value
42395 +ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs)
42396 +{
42397 + /*
42398 + * Return if there is nothing to do. (Does this ever happen?) XXX
42399 + */
42400 + if (ixs->skb == NULL) {
42401 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42402 + "klips_error:ipsec_xmit_sanity_check_skb: "
42403 + "Nothing to do!\n" );
42404 + return IPSEC_XMIT_NOSKB;
42405 + }
42406 +
42407 + /* if skb was cloned (most likely due to a packet sniffer such as
42408 + tcpdump being momentarily attached to the interface), make
42409 + a copy of our own to modify */
42410 + if(skb_cloned(ixs->skb)) {
42411 + if
42412 +#ifdef SKB_COW_NEW
42413 + (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0)
42414 +#else /* SKB_COW_NEW */
42415 + ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL)
42416 +#endif /* SKB_COW_NEW */
42417 + {
42418 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42419 + "klips_error:ipsec_xmit_sanity_check_skb: "
42420 + "skb_cow failed to allocate buffer, dropping.\n" );
42421 + ixs->stats->tx_dropped++;
42422 + return IPSEC_XMIT_ERRSKBALLOC;
42423 + }
42424 + }
42425 +
42426 + ixs->iph = ixs->skb->nh.iph;
42427 +
42428 + /* sanity check for IP version as we can't handle IPv6 right now */
42429 + if (ixs->iph->version != 4) {
42430 + KLIPS_PRINT(debug_tunnel,
42431 + "klips_debug:ipsec_xmit_sanity_check_skb: "
42432 + "found IP Version %d but cannot process other IP versions than v4.\n",
42433 + ixs->iph->version); /* XXX */
42434 + ixs->stats->tx_dropped++;
42435 + return IPSEC_XMIT_NOIPV6;
42436 + }
42437 +
42438 +#if IPSEC_DISALLOW_IPOPTIONS
42439 + if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) {
42440 + KLIPS_PRINT(debug_tunnel,
42441 + "klips_debug:ipsec_xmit_sanity_check_skb: "
42442 + "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */
42443 + ixs->stats->tx_dropped++;
42444 + return IPSEC_XMIT_NOIPOPTIONS;
42445 + }
42446 +#endif /* IPSEC_DISALLOW_IPOPTIONS */
42447 +
42448 +#ifndef NET_21
42449 + if (ixs->iph->ttl <= 0) {
42450 + /* Tell the sender its packet died... */
42451 + ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev);
42452 +
42453 + KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: "
42454 + "TTL=0, too many hops!\n");
42455 + ixs->stats->tx_dropped++;
42456 + return IPSEC_XMIT_TTLEXPIRED;
42457 + }
42458 +#endif /* !NET_21 */
42459 +
42460 + return IPSEC_XMIT_OK;
42461 +}
42462 +
42463 +enum ipsec_xmit_value
42464 +ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs)
42465 +{
42466 +#ifdef CONFIG_KLIPS_ESP
42467 + struct esphdr *espp;
42468 + unsigned char *idat, *pad;
42469 + int authlen = 0, padlen = 0, i;
42470 +#endif /* !CONFIG_KLIPS_ESP */
42471 +#ifdef CONFIG_KLIPS_AH
42472 + struct iphdr ipo;
42473 + struct ahhdr *ahp;
42474 +#endif /* CONFIG_KLIPS_AH */
42475 +#if defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMAC_SHA1)
42476 + union {
42477 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42478 + MD5_CTX md5;
42479 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42480 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42481 + SHA1_CTX sha1;
42482 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42483 + } tctx;
42484 + __u8 hash[AH_AMAX];
42485 +#endif /* defined(CONFIG_KLIPS_AUTH_HMAC_MD5) || defined(CONFIG_KLIPS_AUTH_HMACn_SHA1) */
42486 + int headroom = 0, tailroom = 0, ilen = 0, len = 0;
42487 + unsigned char *dat;
42488 + int blocksize = 8; /* XXX: should be inside ixs --jjo */
42489 + struct ipsec_alg_enc *ixt_e = NULL;
42490 + struct ipsec_alg_auth *ixt_a = NULL;
42491 +
42492 + ixs->iphlen = ixs->iph->ihl << 2;
42493 + ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
42494 + ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF);
42495 + KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
42496 + "klips_debug:ipsec_xmit_encap_once: "
42497 + "calling output for <%s%s%s>, SA:%s\n",
42498 + IPS_XFORM_NAME(ixs->ipsp),
42499 + ixs->sa_len ? ixs->sa_txt : " (error)");
42500 +
42501 + switch(ixs->ipsp->ips_said.proto) {
42502 +#ifdef CONFIG_KLIPS_AH
42503 + case IPPROTO_AH:
42504 + headroom += sizeof(struct ahhdr);
42505 + break;
42506 +#endif /* CONFIG_KLIPS_AH */
42507 +
42508 +#ifdef CONFIG_KLIPS_ESP
42509 + case IPPROTO_ESP:
42510 + ixt_e=ixs->ipsp->ips_alg_enc;
42511 + if (ixt_e) {
42512 + blocksize = ixt_e->ixt_common.ixt_blocksize;
42513 + headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
42514 + } else {
42515 + ixs->stats->tx_errors++;
42516 + return IPSEC_XMIT_ESP_BADALG;
42517 + }
42518 +
42519 + ixt_a=ixs->ipsp->ips_alg_auth;
42520 + if (ixt_a) {
42521 + tailroom += AHHMAC_HASHLEN;
42522 + authlen = AHHMAC_HASHLEN;
42523 + } else
42524 + switch(ixs->ipsp->ips_authalg) {
42525 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42526 + case AH_MD5:
42527 + authlen = AHHMAC_HASHLEN;
42528 + break;
42529 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42530 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42531 + case AH_SHA:
42532 + authlen = AHHMAC_HASHLEN;
42533 + break;
42534 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42535 + case AH_NONE:
42536 + break;
42537 + default:
42538 + ixs->stats->tx_errors++;
42539 + return IPSEC_XMIT_ESP_BADALG;
42540 + }
42541 + tailroom += blocksize != 1 ?
42542 + ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
42543 + ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
42544 + tailroom += authlen;
42545 + break;
42546 +#endif /* CONFIG_KLIPS_ESP */
42547 +
42548 +#ifdef CONFIG_KLIPS_IPIP
42549 + case IPPROTO_IPIP:
42550 + headroom += sizeof(struct iphdr);
42551 + ixs->iphlen = sizeof(struct iphdr);
42552 + break;
42553 +#endif /* !CONFIG_KLIPS_IPIP */
42554 +
42555 +#ifdef CONFIG_KLIPS_IPCOMP
42556 + case IPPROTO_COMP:
42557 + break;
42558 +#endif /* CONFIG_KLIPS_IPCOMP */
42559 +
42560 + default:
42561 + ixs->stats->tx_errors++;
42562 + return IPSEC_XMIT_BADPROTO;
42563 + }
42564 +
42565 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42566 + "klips_debug:ipsec_xmit_encap_once: "
42567 + "pushing %d bytes, putting %d, proto %d.\n",
42568 + headroom, tailroom, ixs->ipsp->ips_said.proto);
42569 + if(skb_headroom(ixs->skb) < headroom) {
42570 + printk(KERN_WARNING
42571 + "klips_error:ipsec_xmit_encap_once: "
42572 + "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n",
42573 + headroom, skb_headroom(ixs->skb));
42574 + ixs->stats->tx_errors++;
42575 + return IPSEC_XMIT_ESP_PUSHPULLERR;
42576 + }
42577 +
42578 + dat = skb_push(ixs->skb, headroom);
42579 + ilen = ixs->skb->len - tailroom;
42580 + if(skb_tailroom(ixs->skb) < tailroom) {
42581 + printk(KERN_WARNING
42582 + "klips_error:ipsec_xmit_encap_once: "
42583 + "tried to skb_put %d, %d available. This should never happen, please report.\n",
42584 + tailroom, skb_tailroom(ixs->skb));
42585 + ixs->stats->tx_errors++;
42586 + return IPSEC_XMIT_ESP_PUSHPULLERR;
42587 + }
42588 + skb_put(ixs->skb, tailroom);
42589 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42590 + "klips_debug:ipsec_xmit_encap_once: "
42591 + "head,tailroom: %d,%d before xform.\n",
42592 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
42593 + len = ixs->skb->len;
42594 + if(len > 0xfff0) {
42595 + printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: "
42596 + "tot_len (%d) > 65520. This should never happen, please report.\n",
42597 + len);
42598 + ixs->stats->tx_errors++;
42599 + return IPSEC_XMIT_BADLEN;
42600 + }
42601 + memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen);
42602 + ixs->iph = (struct iphdr *)dat;
42603 + ixs->iph->tot_len = htons(ixs->skb->len);
42604 +
42605 + switch(ixs->ipsp->ips_said.proto) {
42606 +#ifdef CONFIG_KLIPS_ESP
42607 + case IPPROTO_ESP:
42608 + espp = (struct esphdr *)(dat + ixs->iphlen);
42609 + espp->esp_spi = ixs->ipsp->ips_said.spi;
42610 + espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
42611 +
42612 + if (!ixt_e) {
42613 + ixs->stats->tx_errors++;
42614 + return IPSEC_XMIT_ESP_BADALG;
42615 + }
42616 +
42617 + idat = dat + ixs->iphlen + headroom;
42618 + ilen = len - (ixs->iphlen + headroom + authlen);
42619 +
42620 + /* Self-describing padding */
42621 + pad = &dat[len - tailroom];
42622 + padlen = tailroom - 2 - authlen;
42623 + for (i = 0; i < padlen; i++) {
42624 + pad[i] = i + 1;
42625 + }
42626 + dat[len - authlen - 2] = padlen;
42627 +
42628 + dat[len - authlen - 1] = ixs->iph->protocol;
42629 + ixs->iph->protocol = IPPROTO_ESP;
42630 +#ifdef CONFIG_KLIPS_DEBUG
42631 + if(debug_tunnel & DB_TN_ENCAP) {
42632 + dmp("pre-encrypt", dat, len);
42633 + }
42634 +#endif
42635 +
42636 + /*
42637 + * Do all operations here:
42638 + * copy IV->ESP, encrypt, update ips IV
42639 + *
42640 + */
42641 + {
42642 + int ret;
42643 + memcpy(espp->esp_iv,
42644 + ixs->ipsp->ips_iv,
42645 + ixs->ipsp->ips_iv_size);
42646 + ret=ipsec_alg_esp_encrypt(ixs->ipsp,
42647 + idat, ilen, espp->esp_iv,
42648 + IPSEC_ALG_ENCRYPT);
42649 +
42650 + prng_bytes(&ipsec_prng,
42651 + (char *)ixs->ipsp->ips_iv,
42652 + ixs->ipsp->ips_iv_size);
42653 + }
42654 +
42655 + if (ixt_a) {
42656 + ipsec_alg_sa_esp_hash(ixs->ipsp,
42657 + (caddr_t)espp, len - ixs->iphlen - authlen,
42658 + &(dat[len - authlen]), authlen);
42659 +
42660 + } else
42661 + switch(ixs->ipsp->ips_authalg) {
42662 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42663 + case AH_MD5:
42664 + dmp("espp", (char*)espp, len - ixs->iphlen - authlen);
42665 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42666 + dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
42667 + osMD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen);
42668 + dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
42669 + osMD5Final(hash, &tctx.md5);
42670 + dmp("ictx hash", (char*)&hash, sizeof(hash));
42671 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
42672 + dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
42673 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
42674 + dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
42675 + osMD5Final(hash, &tctx.md5);
42676 + dmp("octx hash", (char*)&hash, sizeof(hash));
42677 + memcpy(&(dat[len - authlen]), hash, authlen);
42678 +
42679 + /* paranoid */
42680 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
42681 + memset((caddr_t)hash, 0, sizeof(*hash));
42682 + break;
42683 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42684 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42685 + case AH_SHA:
42686 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42687 + SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen);
42688 + SHA1Final(hash, &tctx.sha1);
42689 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
42690 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
42691 + SHA1Final(hash, &tctx.sha1);
42692 + memcpy(&(dat[len - authlen]), hash, authlen);
42693 +
42694 + /* paranoid */
42695 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
42696 + memset((caddr_t)hash, 0, sizeof(*hash));
42697 + break;
42698 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42699 + case AH_NONE:
42700 + break;
42701 + default:
42702 + ixs->stats->tx_errors++;
42703 + return IPSEC_XMIT_AH_BADALG;
42704 + }
42705 +#ifdef NET_21
42706 + ixs->skb->h.raw = (unsigned char*)espp;
42707 +#endif /* NET_21 */
42708 + break;
42709 +#endif /* !CONFIG_KLIPS_ESP */
42710 +#ifdef CONFIG_KLIPS_AH
42711 + case IPPROTO_AH:
42712 + ahp = (struct ahhdr *)(dat + ixs->iphlen);
42713 + ahp->ah_spi = ixs->ipsp->ips_said.spi;
42714 + ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
42715 + ahp->ah_rv = 0;
42716 + ahp->ah_nh = ixs->iph->protocol;
42717 + ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
42718 + ixs->iph->protocol = IPPROTO_AH;
42719 + dmp("ahp", (char*)ahp, sizeof(*ahp));
42720 +
42721 + ipo = *ixs->iph;
42722 + ipo.tos = 0;
42723 + ipo.frag_off = 0;
42724 + ipo.ttl = 0;
42725 + ipo.check = 0;
42726 + dmp("ipo", (char*)&ipo, sizeof(ipo));
42727 +
42728 + switch(ixs->ipsp->ips_authalg) {
42729 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
42730 + case AH_MD5:
42731 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42732 + dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
42733 + osMD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
42734 + dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
42735 + osMD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
42736 + dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
42737 + osMD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
42738 + dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
42739 + osMD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
42740 + dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
42741 + osMD5Final(hash, &tctx.md5);
42742 + dmp("ictx hash", (char*)&hash, sizeof(hash));
42743 + tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
42744 + dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
42745 + osMD5Update(&tctx.md5, hash, AHMD596_ALEN);
42746 + dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
42747 + osMD5Final(hash, &tctx.md5);
42748 + dmp("octx hash", (char*)&hash, sizeof(hash));
42749 +
42750 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
42751 +
42752 + /* paranoid */
42753 + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
42754 + memset((caddr_t)hash, 0, sizeof(*hash));
42755 + break;
42756 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
42757 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
42758 + case AH_SHA:
42759 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
42760 + SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
42761 + SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
42762 + SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
42763 + SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
42764 + SHA1Final(hash, &tctx.sha1);
42765 + tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
42766 + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
42767 + SHA1Final(hash, &tctx.sha1);
42768 +
42769 + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
42770 +
42771 + /* paranoid */
42772 + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
42773 + memset((caddr_t)hash, 0, sizeof(*hash));
42774 + break;
42775 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
42776 + default:
42777 + ixs->stats->tx_errors++;
42778 + return IPSEC_XMIT_AH_BADALG;
42779 + }
42780 +#ifdef NET_21
42781 + ixs->skb->h.raw = (unsigned char*)ahp;
42782 +#endif /* NET_21 */
42783 + break;
42784 +#endif /* CONFIG_KLIPS_AH */
42785 +#ifdef CONFIG_KLIPS_IPIP
42786 + case IPPROTO_IPIP:
42787 + ixs->iph->version = 4;
42788 + switch(sysctl_ipsec_tos) {
42789 + case 0:
42790 +#ifdef NET_21
42791 + ixs->iph->tos = ixs->skb->nh.iph->tos;
42792 +#else /* NET_21 */
42793 + ixs->iph->tos = ixs->skb->ip_hdr->tos;
42794 +#endif /* NET_21 */
42795 + break;
42796 + case 1:
42797 + ixs->iph->tos = 0;
42798 + break;
42799 + default:
42800 + break;
42801 + }
42802 + ixs->iph->ttl = SYSCTL_IPSEC_DEFAULT_TTL;
42803 + ixs->iph->frag_off = 0;
42804 + ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
42805 + ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
42806 + ixs->iph->protocol = IPPROTO_IPIP;
42807 + ixs->iph->ihl = sizeof(struct iphdr) >> 2;
42808 +
42809 + KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
42810 +
42811 + ixs->newdst = (__u32)ixs->iph->daddr;
42812 + ixs->newsrc = (__u32)ixs->iph->saddr;
42813 +
42814 +#ifdef NET_21
42815 + ixs->skb->h.ipiph = ixs->skb->nh.iph;
42816 +#endif /* NET_21 */
42817 + break;
42818 +#endif /* !CONFIG_KLIPS_IPIP */
42819 +#ifdef CONFIG_KLIPS_IPCOMP
42820 + case IPPROTO_COMP:
42821 + {
42822 + unsigned int flags = 0;
42823 +#ifdef CONFIG_KLIPS_DEBUG
42824 + unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
42825 +#endif /* CONFIG_KLIPS_DEBUG */
42826 + ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
42827 +
42828 + ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
42829 +
42830 +#ifdef NET_21
42831 + ixs->iph = ixs->skb->nh.iph;
42832 +#else /* NET_21 */
42833 + ixs->iph = ixs->skb->ip_hdr;
42834 +#endif /* NET_21 */
42835 +
42836 + ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
42837 +
42838 +#ifdef CONFIG_KLIPS_DEBUG
42839 + if (debug_tunnel & DB_TN_CROUT)
42840 + {
42841 + if (old_tot_len > ntohs(ixs->iph->tot_len))
42842 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42843 + "klips_debug:ipsec_xmit_encap_once: "
42844 + "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
42845 + old_tot_len, ntohs(ixs->iph->tot_len),
42846 + ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
42847 + ntohl(ixs->ipsp->ips_said.spi),
42848 + (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
42849 + else
42850 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
42851 + "klips_debug:ipsec_xmit_encap_once: "
42852 + "packet did not compress (flags = %d).\n",
42853 + flags);
42854 + }
42855 +#endif /* CONFIG_KLIPS_DEBUG */
42856 + }
42857 + break;
42858 +#endif /* CONFIG_KLIPS_IPCOMP */
42859 + default:
42860 + ixs->stats->tx_errors++;
42861 + return IPSEC_XMIT_BADPROTO;
42862 + }
42863 +
42864 +#ifdef NET_21
42865 + ixs->skb->nh.raw = ixs->skb->data;
42866 +#else /* NET_21 */
42867 + ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data;
42868 +#endif /* NET_21 */
42869 + ixs->iph->check = 0;
42870 + ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl);
42871 +
42872 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
42873 + "klips_debug:ipsec_xmit_encap_once: "
42874 + "after <%s%s%s>, SA:%s:\n",
42875 + IPS_XFORM_NAME(ixs->ipsp),
42876 + ixs->sa_len ? ixs->sa_txt : " (error)");
42877 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
42878 +
42879 + ixs->ipsp->ips_life.ipl_bytes.ipl_count += len;
42880 + ixs->ipsp->ips_life.ipl_bytes.ipl_last = len;
42881 +
42882 + if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) {
42883 + ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
42884 + }
42885 + ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
42886 + ixs->ipsp->ips_life.ipl_packets.ipl_count++;
42887 +
42888 + ixs->ipsp = ixs->ipsp->ips_onext;
42889 +
42890 + return IPSEC_XMIT_OK;
42891 +}
42892 +
42893 +/*
42894 + * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
42895 + * source and destination ports to those from the TCP/UDP header.
42896 + */
42897 +void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
42898 +{
42899 + struct udphdr *udp;
42900 +
42901 + switch (iph->protocol) {
42902 + case IPPROTO_UDP:
42903 + case IPPROTO_TCP:
42904 + /*
42905 + * The ports are at the same offsets in a TCP and UDP
42906 + * header so hack it ...
42907 + */
42908 + udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
42909 + er->sen_sport = udp->source;
42910 + er->sen_dport = udp->dest;
42911 + break;
42912 + default:
42913 + er->sen_sport = 0;
42914 + er->sen_dport = 0;
42915 + break;
42916 + }
42917 +}
42918 +
42919 +/*
42920 + * A TRAP eroute is installed and we want to replace it with a HOLD
42921 + * eroute.
42922 + */
42923 +static int create_hold_eroute(struct eroute *origtrap,
42924 + struct sk_buff * skb, struct iphdr * iph,
42925 + uint32_t eroute_pid)
42926 +{
42927 + struct eroute hold_eroute;
42928 + ip_said hold_said;
42929 + struct sk_buff *first, *last;
42930 + int error;
42931 +
42932 + first = last = NULL;
42933 + memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
42934 + memset((caddr_t)&hold_said, 0, sizeof(hold_said));
42935 +
42936 + hold_said.proto = IPPROTO_INT;
42937 + hold_said.spi = htonl(SPI_HOLD);
42938 + hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
42939 +
42940 + hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
42941 + hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
42942 + hold_eroute.er_eaddr.sen_family = AF_ENCAP;
42943 + hold_eroute.er_emask.sen_family = AF_ENCAP;
42944 + hold_eroute.er_eaddr.sen_type = SENT_IP4;
42945 + hold_eroute.er_emask.sen_type = 255;
42946 +
42947 + hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
42948 + hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
42949 + hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
42950 + hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
42951 + hold_eroute.er_emask.sen_sport = 0;
42952 + hold_eroute.er_emask.sen_dport = 0;
42953 + hold_eroute.er_pid = eroute_pid;
42954 + hold_eroute.er_count = 0;
42955 + hold_eroute.er_lasttime = jiffies/HZ;
42956 +
42957 + /*
42958 + * if it wasn't captured by a wildcard, then don't record it as
42959 + * a wildcard.
42960 + */
42961 + if(origtrap->er_eaddr.sen_proto != 0) {
42962 + hold_eroute.er_eaddr.sen_proto = iph->protocol;
42963 +
42964 + if((iph->protocol == IPPROTO_TCP ||
42965 + iph->protocol == IPPROTO_UDP) &&
42966 + (origtrap->er_eaddr.sen_sport != 0 ||
42967 + origtrap->er_eaddr.sen_dport != 0)) {
42968 +
42969 + if(origtrap->er_eaddr.sen_sport != 0)
42970 + hold_eroute.er_emask.sen_sport = ~0;
42971 +
42972 + if(origtrap->er_eaddr.sen_dport != 0)
42973 + hold_eroute.er_emask.sen_dport = ~0;
42974 +
42975 + ipsec_extract_ports(iph, &hold_eroute.er_eaddr);
42976 + }
42977 + }
42978 +
42979 +#ifdef CONFIG_KLIPS_DEBUG
42980 + if (debug_pfkey) {
42981 + char buf1[64], buf2[64];
42982 + subnettoa(hold_eroute.er_eaddr.sen_ip_src,
42983 + hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
42984 + subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
42985 + hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
42986 + KLIPS_PRINT(debug_pfkey,
42987 + "klips_debug:ipsec_tunnel_start_xmit: "
42988 + "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
42989 + buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
42990 + buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
42991 + hold_eroute.er_eaddr.sen_proto);
42992 + }
42993 +#endif /* CONFIG_KLIPS_DEBUG */
42994 +
42995 + if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
42996 + &first, &last)) {
42997 + KLIPS_PRINT(debug_pfkey,
42998 + "klips_debug:ipsec_tunnel_start_xmit: "
42999 + "HOLD breakeroute found nothing.\n");
43000 + } else {
43001 + KLIPS_PRINT(debug_pfkey,
43002 + "klips_debug:ipsec_tunnel_start_xmit: "
43003 + "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
43004 + NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
43005 + ntohs(hold_eroute.er_eaddr.sen_sport),
43006 + NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
43007 + ntohs(hold_eroute.er_eaddr.sen_dport),
43008 + hold_eroute.er_eaddr.sen_proto);
43009 + }
43010 + if (first != NULL)
43011 + kfree_skb(first);
43012 + if (last != NULL)
43013 + kfree_skb(last);
43014 +
43015 + error = ipsec_makeroute(&(hold_eroute.er_eaddr),
43016 + &(hold_eroute.er_emask),
43017 + hold_said, eroute_pid, skb, NULL, NULL);
43018 + if (error) {
43019 + KLIPS_PRINT(debug_pfkey,
43020 + "klips_debug:ipsec_tunnel_start_xmit: "
43021 + "HOLD makeroute returned %d, failed.\n", error);
43022 + } else {
43023 + KLIPS_PRINT(debug_pfkey,
43024 + "klips_debug:ipsec_tunnel_start_xmit: "
43025 + "HOLD makeroute call successful.\n");
43026 + }
43027 + return (error == 0);
43028 +}
43029 +
43030 +/*
43031 + * upon entry to this function, ixs->skb should be setup
43032 + * as follows:
43033 + *
43034 + * data = beginning of IP packet <- differs from ipsec_rcv().
43035 + * nh.raw = beginning of IP packet.
43036 + * h.raw = data after the IP packet.
43037 + *
43038 + */
43039 +enum ipsec_xmit_value
43040 +ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs)
43041 +{
43042 + struct ipsec_alg_enc *ixt_e = NULL;
43043 + struct ipsec_alg_auth *ixt_a = NULL;
43044 + int blocksize = 8;
43045 + enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK;
43046 +
43047 + ixs->newdst = ixs->orgdst = ixs->iph->daddr;
43048 + ixs->newsrc = ixs->orgsrc = ixs->iph->saddr;
43049 + ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr;
43050 + ixs->iphlen = ixs->iph->ihl << 2;
43051 + ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
43052 + ixs->max_headroom = ixs->max_tailroom = 0;
43053 +
43054 + if (ixs->outgoing_said.proto == IPPROTO_INT) {
43055 + switch (ntohl(ixs->outgoing_said.spi)) {
43056 + case SPI_DROP:
43057 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43058 + "klips_debug:ipsec_xmit_encap_bundle: "
43059 + "shunt SA of DROP or no eroute: dropping.\n");
43060 + ixs->stats->tx_dropped++;
43061 + break;
43062 +
43063 + case SPI_REJECT:
43064 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43065 + "klips_debug:ipsec_xmit_encap_bundle: "
43066 + "shunt SA of REJECT: notifying and dropping.\n");
43067 + ICMP_SEND(ixs->skb,
43068 + ICMP_DEST_UNREACH,
43069 + ICMP_PKT_FILTERED,
43070 + 0,
43071 + ixs->physdev);
43072 + ixs->stats->tx_dropped++;
43073 + break;
43074 +
43075 + case SPI_PASS:
43076 +#ifdef NET_21
43077 + ixs->pass = 1;
43078 +#endif /* NET_21 */
43079 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43080 + "klips_debug:ipsec_xmit_encap_bundle: "
43081 + "PASS: calling dev_queue_xmit\n");
43082 + return IPSEC_XMIT_PASS;
43083 + goto cleanup;
43084 +
43085 + case SPI_HOLD:
43086 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43087 + "klips_debug:ipsec_xmit_encap_bundle: "
43088 + "shunt SA of HOLD: this does not make sense here, dropping.\n");
43089 + ixs->stats->tx_dropped++;
43090 + break;
43091 +
43092 + case SPI_TRAP:
43093 + case SPI_TRAPSUBNET:
43094 + {
43095 + struct sockaddr_in src, dst;
43096 +#ifdef CONFIG_KLIPS_DEBUG
43097 + char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
43098 +#endif /* CONFIG_KLIPS_DEBUG */
43099 +
43100 + /* Signal all listening KMds with a PF_KEY ACQUIRE */
43101 +
43102 + memset(&src, 0, sizeof(src));
43103 + memset(&dst, 0, sizeof(dst));
43104 + src.sin_family = AF_INET;
43105 + dst.sin_family = AF_INET;
43106 + src.sin_addr.s_addr = ixs->iph->saddr;
43107 + dst.sin_addr.s_addr = ixs->iph->daddr;
43108 +
43109 + ixs->ips.ips_transport_protocol = 0;
43110 + src.sin_port = 0;
43111 + dst.sin_port = 0;
43112 +
43113 + if(ixs->eroute->er_eaddr.sen_proto != 0) {
43114 + ixs->ips.ips_transport_protocol = ixs->iph->protocol;
43115 +
43116 + if(ixs->eroute->er_eaddr.sen_sport != 0) {
43117 + src.sin_port =
43118 + (ixs->iph->protocol == IPPROTO_UDP
43119 + ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source
43120 + : (ixs->iph->protocol == IPPROTO_TCP
43121 + ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source
43122 + : 0));
43123 + }
43124 + if(ixs->eroute->er_eaddr.sen_dport != 0) {
43125 + dst.sin_port =
43126 + (ixs->iph->protocol == IPPROTO_UDP
43127 + ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest
43128 + : (ixs->iph->protocol == IPPROTO_TCP
43129 + ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest
43130 + : 0));
43131 + }
43132 + }
43133 +
43134 + ixs->ips.ips_addr_s = (struct sockaddr*)(&src);
43135 + ixs->ips.ips_addr_d = (struct sockaddr*)(&dst);
43136 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43137 + "klips_debug:ipsec_xmit_encap_bundle: "
43138 + "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
43139 + addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
43140 + ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port),
43141 + addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
43142 + ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port),
43143 + ixs->ips.ips_said.proto);
43144 +
43145 + /* increment count of total traps needed */
43146 + ipsec_xmit_trap_count++;
43147 +
43148 + if (pfkey_acquire(&ixs->ips) == 0) {
43149 +
43150 + /* note that we succeeded */
43151 + ipsec_xmit_trap_sendcount++;
43152 +
43153 + if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
43154 + /*
43155 + * The spinlock is to prevent any other
43156 + * process from accessing or deleting
43157 + * the eroute while we are using and
43158 + * updating it.
43159 + */
43160 + spin_lock(&eroute_lock);
43161 + ixs->eroute = ipsec_findroute(&ixs->matcher);
43162 + if(ixs->eroute) {
43163 + ixs->eroute->er_said.spi = htonl(SPI_HOLD);
43164 + ixs->eroute->er_first = ixs->skb;
43165 + ixs->skb = NULL;
43166 + }
43167 + spin_unlock(&eroute_lock);
43168 + } else if (create_hold_eroute(ixs->eroute,
43169 + ixs->skb,
43170 + ixs->iph,
43171 + ixs->eroute_pid)) {
43172 + ixs->skb = NULL;
43173 + }
43174 + /* whether or not the above succeeded, we continue */
43175 +
43176 + }
43177 + ixs->stats->tx_dropped++;
43178 + }
43179 + default:
43180 + /* XXX what do we do with an unknown shunt spi? */
43181 + break;
43182 + } /* switch (ntohl(ixs->outgoing_said.spi)) */
43183 + return IPSEC_XMIT_STOLEN;
43184 + } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */
43185 +
43186 + /*
43187 + The spinlock is to prevent any other process from
43188 + accessing or deleting the ipsec_sa hash table or any of the
43189 + ipsec_sa s while we are using and updating them.
43190 +
43191 + This is not optimal, but was relatively straightforward
43192 + at the time. A better way to do it has been planned for
43193 + more than a year, to lock the hash table and put reference
43194 + counts on each ipsec_sa instead. This is not likely to happen
43195 + in KLIPS1 unless a volunteer contributes it, but will be
43196 + designed into KLIPS2.
43197 + */
43198 + spin_lock(&tdb_lock);
43199 +
43200 + ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said);
43201 + ixs->sa_len = satot(&ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
43202 +
43203 + if (ixs->ipsp == NULL) {
43204 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43205 + "klips_debug:ipsec_xmit_encap_bundle: "
43206 + "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
43207 + ixs->sa_len ? ixs->sa_txt : " (error)");
43208 + if(ixs->stats) {
43209 + ixs->stats->tx_dropped++;
43210 + }
43211 + bundle_stat = IPSEC_XMIT_SAIDNOTFOUND;
43212 + goto cleanup;
43213 + }
43214 +
43215 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43216 + "klips_debug:ipsec_xmit_encap_bundle: "
43217 + "found ipsec_sa -- SA:<%s%s%s> %s\n",
43218 + IPS_XFORM_NAME(ixs->ipsp),
43219 + ixs->sa_len ? ixs->sa_txt : " (error)");
43220 +
43221 + /*
43222 + * How much headroom do we need to be able to apply
43223 + * all the grouped transforms?
43224 + */
43225 + ixs->ipsq = ixs->ipsp; /* save the head of the ipsec_sa chain */
43226 + while (ixs->ipsp) {
43227 + ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
43228 + if(ixs->sa_len == 0) {
43229 + strcpy(ixs->sa_txt, "(error)");
43230 + }
43231 +
43232 + /* If it is in larval state, drop the packet, we cannot process yet. */
43233 + if(ixs->ipsp->ips_state == SADB_SASTATE_LARVAL) {
43234 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43235 + "klips_debug:ipsec_xmit_encap_bundle: "
43236 + "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
43237 + IPS_XFORM_NAME(ixs->ipsp),
43238 + ixs->sa_len ? ixs->sa_txt : " (error)");
43239 + if(ixs->stats) {
43240 + ixs->stats->tx_errors++;
43241 + }
43242 + bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
43243 + goto cleanup;
43244 + }
43245 +
43246 + if(ixs->ipsp->ips_state == SADB_SASTATE_DEAD) {
43247 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43248 + "klips_debug:ipsec_xmit_encap_bundle: "
43249 + "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
43250 + IPS_XFORM_NAME(ixs->ipsp),
43251 + ixs->sa_len ? ixs->sa_txt : " (error)");
43252 + ixs->stats->tx_errors++;
43253 + bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
43254 + goto cleanup;
43255 + }
43256 +
43257 + /* If the replay window counter == -1, expire SA, it will roll */
43258 + if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) {
43259 + pfkey_expire(ixs->ipsp, 1);
43260 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43261 + "klips_debug:ipsec_xmit_encap_bundle: "
43262 + "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
43263 + IPS_XFORM_NAME(ixs->ipsp),
43264 + ixs->sa_len ? ixs->sa_txt : " (error)");
43265 + ipsec_sa_delchain(ixs->ipsp);
43266 + ixs->stats->tx_errors++;
43267 + bundle_stat = IPSEC_XMIT_REPLAYROLLED;
43268 + goto cleanup;
43269 + }
43270 +
43271 + /*
43272 + * if this is the first time we are using this SA, mark start time,
43273 + * and offset hard/soft counters by "now" for later checking.
43274 + */
43275 +#if 0
43276 + if(ixs->ipsp->ips_life.ipl_usetime.count == 0) {
43277 + ixs->ipsp->ips_life.ipl_usetime.count = jiffies;
43278 + ixs->ipsp->ips_life.ipl_usetime.hard += jiffies;
43279 + ixs->ipsp->ips_life.ipl_usetime.soft += jiffies;
43280 + }
43281 +#endif
43282 +
43283 +
43284 + if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt,
43285 + ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43286 + ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt,
43287 + ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43288 + ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt,
43289 + ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
43290 + ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt,
43291 + ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) {
43292 +
43293 + ipsec_sa_delchain(ixs->ipsp);
43294 + ixs->stats->tx_errors++;
43295 + bundle_stat = IPSEC_XMIT_LIFETIMEFAILED;
43296 + goto cleanup;
43297 + }
43298 +
43299 +
43300 + ixs->headroom = ixs->tailroom = 0;
43301 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43302 + "klips_debug:ipsec_xmit_encap_bundle: "
43303 + "calling room for <%s%s%s>, SA:%s\n",
43304 + IPS_XFORM_NAME(ixs->ipsp),
43305 + ixs->sa_len ? ixs->sa_txt : " (error)");
43306 + switch(ixs->ipsp->ips_said.proto) {
43307 +#ifdef CONFIG_KLIPS_AH
43308 + case IPPROTO_AH:
43309 + ixs->headroom += sizeof(struct ahhdr);
43310 + break;
43311 +#endif /* CONFIG_KLIPS_AH */
43312 +#ifdef CONFIG_KLIPS_ESP
43313 + case IPPROTO_ESP:
43314 + ixt_e=ixs->ipsp->ips_alg_enc;
43315 + if (ixt_e) {
43316 + blocksize = ixt_e->ixt_common.ixt_blocksize;
43317 + ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_common.ixt_support.ias_ivlen/8;
43318 + }
43319 + else {
43320 + ixs->stats->tx_errors++;
43321 + bundle_stat = IPSEC_XMIT_ESP_BADALG;
43322 + goto cleanup;
43323 + }
43324 +
43325 + if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
43326 + ixs->tailroom += AHHMAC_HASHLEN;
43327 + } else
43328 + switch(ixs->ipsp->ips_authalg) {
43329 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
43330 + case AH_MD5:
43331 + ixs->tailroom += AHHMAC_HASHLEN;
43332 + break;
43333 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
43334 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
43335 + case AH_SHA:
43336 + ixs->tailroom += AHHMAC_HASHLEN;
43337 + break;
43338 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
43339 + case AH_NONE:
43340 + break;
43341 + default:
43342 + ixs->stats->tx_errors++;
43343 + bundle_stat = IPSEC_XMIT_AH_BADALG;
43344 + goto cleanup;
43345 + }
43346 + ixs->tailroom += blocksize != 1 ?
43347 + ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
43348 + ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
43349 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
43350 + if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) {
43351 + ixs->natt_type = ixs->ipsp->ips_natt_type;
43352 + ixs->natt_sport = ixs->ipsp->ips_natt_sport;
43353 + ixs->natt_dport = ixs->ipsp->ips_natt_dport;
43354 + switch (ixs->natt_type) {
43355 + case ESPINUDP_WITH_NON_IKE:
43356 + ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32));
43357 + break;
43358 +
43359 + case ESPINUDP_WITH_NON_ESP:
43360 + ixs->natt_head = sizeof(struct udphdr);
43361 + break;
43362 +
43363 + default:
43364 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT
43365 + , "klips_xmit: invalid nat-t type %d"
43366 + , ixs->natt_type);
43367 + bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;
43368 + goto cleanup;
43369 +
43370 + break;
43371 + }
43372 + ixs->tailroom += ixs->natt_head;
43373 + }
43374 +#endif
43375 + break;
43376 +#endif /* !CONFIG_KLIPS_ESP */
43377 +#ifdef CONFIG_KLIPS_IPIP
43378 + case IPPROTO_IPIP:
43379 + ixs->headroom += sizeof(struct iphdr);
43380 + break;
43381 +#endif /* !CONFIG_KLIPS_IPIP */
43382 + case IPPROTO_COMP:
43383 +#ifdef CONFIG_KLIPS_IPCOMP
43384 + /*
43385 + We can't predict how much the packet will
43386 + shrink without doing the actual compression.
43387 + We could do it here, if we were the first
43388 + encapsulation in the chain. That might save
43389 + us a skb_copy_expand, since we might fit
43390 + into the existing skb then. However, this
43391 + would be a bit unclean (and this hack has
43392 + bit us once), so we better not do it. After
43393 + all, the skb_copy_expand is cheap in
43394 + comparison to the actual compression.
43395 + At least we know the packet will not grow.
43396 + */
43397 + break;
43398 +#endif /* CONFIG_KLIPS_IPCOMP */
43399 + default:
43400 + ixs->stats->tx_errors++;
43401 + bundle_stat = IPSEC_XMIT_BADPROTO;
43402 + goto cleanup;
43403 + }
43404 + ixs->ipsp = ixs->ipsp->ips_onext;
43405 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43406 + "klips_debug:ipsec_xmit_encap_bundle: "
43407 + "Required head,tailroom: %d,%d\n",
43408 + ixs->headroom, ixs->tailroom);
43409 + ixs->max_headroom += ixs->headroom;
43410 + ixs->max_tailroom += ixs->tailroom;
43411 + ixs->pyldsz += (ixs->headroom + ixs->tailroom);
43412 + }
43413 + ixs->ipsp = ixs->ipsq; /* restore the head of the ipsec_sa chain */
43414 +
43415 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43416 + "klips_debug:ipsec_xmit_encap_bundle: "
43417 + "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
43418 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb),
43419 + ixs->max_headroom, ixs->max_tailroom);
43420 +
43421 + ixs->tot_headroom += ixs->max_headroom;
43422 + ixs->tot_tailroom += ixs->max_tailroom;
43423 +
43424 + ixs->mtudiff = ixs->cur_mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;
43425 +
43426 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43427 + "klips_debug:ipsec_xmit_encap_bundle: "
43428 + "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
43429 + ixs->cur_mtu, ixs->physmtu,
43430 + ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));
43431 + if(ixs->mtudiff > 0) {
43432 + int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);
43433 +
43434 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43435 + "klips_info:ipsec_xmit_encap_bundle: "
43436 + "dev %s mtu of %d decreased by %d to %d\n",
43437 + ixs->dev ? ixs->dev->name : "ifX",
43438 + ixs->cur_mtu,
43439 + ixs->cur_mtu - newmtu,
43440 + newmtu);
43441 + ixs->cur_mtu = newmtu;
43442 +
43443 + /* this would seem to adjust the MTU of the route as well */
43444 +#if 0
43445 + ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */
43446 +#endif /* 0 */
43447 + }
43448 +
43449 + /*
43450 + If the sender is doing PMTU discovery, and the
43451 + packet doesn't fit within ixs->prv->mtu, notify him
43452 + (unless it was an ICMP packet, or it was not the
43453 + zero-offset packet) and send it anyways.
43454 +
43455 + Note: buggy firewall configuration may prevent the
43456 + ICMP packet from getting back.
43457 + */
43458 + if(sysctl_ipsec_icmp
43459 + && ixs->cur_mtu < ntohs(ixs->iph->tot_len)
43460 + && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {
43461 + int notify = ixs->iph->protocol != IPPROTO_ICMP
43462 + && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
43463 +
43464 +#ifdef IPSEC_obey_DF
43465 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43466 + "klips_debug:ipsec_xmit_encap_bundle: "
43467 + "fragmentation needed and DF set; %sdropping packet\n",
43468 + notify ? "sending ICMP and " : "");
43469 + if (notify)
43470 + ICMP_SEND(ixs->skb,
43471 + ICMP_DEST_UNREACH,
43472 + ICMP_FRAG_NEEDED,
43473 + ixs->cur_mtu,
43474 + ixs->physdev);
43475 + ixs->stats->tx_errors++;
43476 + bundle_stat = IPSEC_XMIT_CANNOTFRAG;
43477 + goto cleanup;
43478 +#else /* IPSEC_obey_DF */
43479 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43480 + "klips_debug:ipsec_xmit_encap_bundle: "
43481 + "fragmentation needed and DF set; %spassing packet\n",
43482 + notify ? "sending ICMP and " : "");
43483 + if (notify)
43484 + ICMP_SEND(ixs->skb,
43485 + ICMP_DEST_UNREACH,
43486 + ICMP_FRAG_NEEDED,
43487 + ixs->cur_mtu,
43488 + ixs->physdev);
43489 +#endif /* IPSEC_obey_DF */
43490 + }
43491 +
43492 +#ifdef MSS_HACK
43493 + /*
43494 + * If this is a transport mode TCP packet with
43495 + * SYN set, determine an effective MSS based on
43496 + * AH/ESP overheads determined above.
43497 + */
43498 + if (ixs->iph->protocol == IPPROTO_TCP
43499 + && ixs->outgoing_said.proto != IPPROTO_IPIP) {
43500 + struct tcphdr *tcph = ixs->skb->h.th;
43501 + if (tcph->syn && !tcph->ack) {
43502 + if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->cur_mtu)) {
43503 + printk(KERN_WARNING
43504 + "klips_warning:ipsec_xmit_encap_bundle: "
43505 + "ipsec_adjust_mss() failed\n");
43506 + ixs->stats->tx_errors++;
43507 + bundle_stat = IPSEC_XMIT_MSSERR;
43508 + goto cleanup;
43509 + }
43510 + }
43511 + }
43512 +#endif /* MSS_HACK */
43513 +
43514 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
43515 + if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {
43516 + /**
43517 + * NAT-Traversal and Transport Mode:
43518 + * we need to correct TCP/UDP checksum
43519 + *
43520 + * If we've got NAT-OA, we can fix checksum without recalculation.
43521 + * If we don't we can zero udp checksum.
43522 + */
43523 + __u32 natt_oa = ixs->ipsp->ips_natt_oa ?
43524 + ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
43525 + __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph;
43526 + __u16 data_len = pkt_len - (ixs->iph->ihl << 2);
43527 + switch (ixs->iph->protocol) {
43528 + case IPPROTO_TCP:
43529 + if (data_len >= sizeof(struct tcphdr)) {
43530 + struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
43531 + if (natt_oa) {
43532 + __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
43533 + KLIPS_PRINT(debug_tunnel,
43534 + "klips_debug:ipsec_tunnel_start_xmit: "
43535 + "NAT-T & TRANSPORT: "
43536 + "fix TCP checksum using NAT-OA\n");
43537 + tcp->check = csum_fold(
43538 + csum_partial((unsigned char *)buff, sizeof(buff),
43539 + tcp->check^0xffff));
43540 + }
43541 + else {
43542 + KLIPS_PRINT(debug_tunnel,
43543 + "klips_debug:ipsec_tunnel_start_xmit: "
43544 + "NAT-T & TRANSPORT: do not recalc TCP checksum\n");
43545 + }
43546 + }
43547 + else {
43548 + KLIPS_PRINT(debug_tunnel,
43549 + "klips_debug:ipsec_tunnel_start_xmit: "
43550 + "NAT-T & TRANSPORT: can't fix TCP checksum\n");
43551 + }
43552 + break;
43553 + case IPPROTO_UDP:
43554 + if (data_len >= sizeof(struct udphdr)) {
43555 + struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
43556 + if (udp->check == 0) {
43557 + KLIPS_PRINT(debug_tunnel,
43558 + "klips_debug:ipsec_tunnel_start_xmit: "
43559 + "NAT-T & TRANSPORT: UDP checksum already 0\n");
43560 + }
43561 + else if (natt_oa) {
43562 + __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
43563 + KLIPS_PRINT(debug_tunnel,
43564 + "klips_debug:ipsec_tunnel_start_xmit: "
43565 + "NAT-T & TRANSPORT: "
43566 + "fix UDP checksum using NAT-OA\n");
43567 + udp->check = csum_fold(
43568 + csum_partial((unsigned char *)buff, sizeof(buff),
43569 + udp->check^0xffff));
43570 + }
43571 + else {
43572 + KLIPS_PRINT(debug_tunnel,
43573 + "klips_debug:ipsec_tunnel_start_xmit: "
43574 + "NAT-T & TRANSPORT: zero UDP checksum\n");
43575 + udp->check = 0;
43576 + }
43577 + }
43578 + else {
43579 + KLIPS_PRINT(debug_tunnel,
43580 + "klips_debug:ipsec_tunnel_start_xmit: "
43581 + "NAT-T & TRANSPORT: can't fix UDP checksum\n");
43582 + }
43583 + break;
43584 + default:
43585 + KLIPS_PRINT(debug_tunnel,
43586 + "klips_debug:ipsec_tunnel_start_xmit: "
43587 + "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
43588 + break;
43589 + }
43590 + }
43591 +#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
43592 +
43593 + if(!ixs->hard_header_stripped && ixs->hard_header_len>0) {
43594 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43595 + "klips_debug:ipsec_xmit_encap_bundle: "
43596 + "allocating %d bytes for hardheader.\n",
43597 + ixs->hard_header_len);
43598 + if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {
43599 + printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: "
43600 + "Failed, tried to allocate %d bytes for temp hard_header.\n",
43601 + ixs->hard_header_len);
43602 + ixs->stats->tx_errors++;
43603 + bundle_stat = IPSEC_XMIT_ERRMEMALLOC;
43604 + goto cleanup;
43605 + }
43606 + {
43607 + int i;
43608 + for (i = 0; i < ixs->hard_header_len; i++) {
43609 + ixs->saved_header[i] = ixs->skb->data[i];
43610 + }
43611 + }
43612 + if(ixs->skb->len < ixs->hard_header_len) {
43613 + printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: "
43614 + "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
43615 + ixs->hard_header_len, (int)(ixs->skb->len));
43616 + ixs->stats->tx_errors++;
43617 + bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;
43618 + goto cleanup;
43619 + }
43620 + skb_pull(ixs->skb, ixs->hard_header_len);
43621 + ixs->hard_header_stripped = 1;
43622 +
43623 +/* ixs->iph = (struct iphdr *) (ixs->skb->data); */
43624 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43625 + "klips_debug:ipsec_xmit_encap_bundle: "
43626 + "head,tailroom: %d,%d after hard_header stripped.\n",
43627 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
43628 + KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);
43629 + } else {
43630 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43631 + "klips_debug:ipsec_xmit_encap_bundle: "
43632 + "hard header already stripped.\n");
43633 + }
43634 +
43635 + ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;
43636 +
43637 + if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) &&
43638 + (skb_tailroom(ixs->skb) >= ixs->max_tailroom)
43639 +#ifndef NET_21
43640 + && ixs->skb->free
43641 +#endif /* !NET_21 */
43642 + ) {
43643 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43644 + "klips_debug:ipsec_xmit_encap_bundle: "
43645 + "data fits in existing skb\n");
43646 + } else {
43647 + struct sk_buff* tskb;
43648 +
43649 + if(!ixs->oskb) {
43650 + ixs->oskb = ixs->skb;
43651 + }
43652 +
43653 + tskb = skb_copy_expand(ixs->skb,
43654 + /* The need for 2 * link layer length here remains unexplained...RGB */
43655 + ixs->max_headroom + 2 * ixs->ll_headroom,
43656 + ixs->max_tailroom,
43657 + GFP_ATOMIC);
43658 +
43659 + if(tskb && ixs->skb->sk) {
43660 + skb_set_owner_w(tskb, ixs->skb->sk);
43661 + }
43662 +
43663 + if(ixs->skb != ixs->oskb) {
43664 + ipsec_kfree_skb(ixs->skb);
43665 + }
43666 + ixs->skb = tskb;
43667 + if (!ixs->skb) {
43668 + printk(KERN_WARNING
43669 + "klips_debug:ipsec_xmit_encap_bundle: "
43670 + "Failed, tried to allocate %d head and %d tailroom\n",
43671 + ixs->max_headroom, ixs->max_tailroom);
43672 + ixs->stats->tx_errors++;
43673 + bundle_stat = IPSEC_XMIT_ERRSKBALLOC;
43674 + goto cleanup;
43675 + }
43676 + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
43677 + "klips_debug:ipsec_xmit_encap_bundle: "
43678 + "head,tailroom: %d,%d after allocation\n",
43679 + skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
43680 + }
43681 +#ifdef CONFIG_KLIPS_DEBUG
43682 + if(debug_tunnel & DB_TN_ENCAP) {
43683 + ipsec_print_ip(ixs->iph);
43684 + }
43685 +#endif
43686 +
43687 + /*
43688 + * Apply grouped transforms to packet
43689 + */
43690 + while (ixs->ipsp) {
43691 + enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK;
43692 +
43693 + encap_stat = ipsec_xmit_encap_once(ixs);
43694 +#ifdef CONFIG_KLIPS_DEBUG
43695 + if(debug_tunnel & DB_TN_ENCAP) {
43696 + ipsec_print_ip(ixs->iph);
43697 + }
43698 +#endif
43699 +
43700 + if(encap_stat != IPSEC_XMIT_OK) {
43701 + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
43702 + "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n",
43703 + encap_stat);
43704 +
43705 + bundle_stat = IPSEC_XMIT_ENCAPFAIL;
43706 + goto cleanup;
43707 + }
43708 + }
43709 +
43710 + /* we are done with this SA */
43711 + ipsec_sa_put(ixs->ipsp);
43712 +
43713 + /* end encapsulation loop here XXX */
43714 + cleanup:
43715 + spin_unlock(&tdb_lock);
43716 + return bundle_stat;
43717 +}
43718 +
43719 +/*
43720 + * $Log: ipsec_xmit.c,v $
43721 + * Revision 1.20.2.9 2007/07/06 17:18:43 paul
43722 + * Fix for authentication field on sent packets has size equals to zero when
43723 + * using custom auth algorithms. This is bug #811. Patch by "iamscared".
43724 + *
43725 + * Revision 1.20.2.8 2006/10/06 21:39:26 paul
43726 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
43727 + * set. This is defined through autoconf.h which is included through the
43728 + * linux kernel build macros.
43729 + *
43730 + * Revision 1.20.2.7 2006/08/24 03:02:01 paul
43731 + * Compile fixes for when CONFIG_KLIPS_DEBUG is not set. (bug #642)
43732 + *
43733 + * Revision 1.20.2.6 2006/07/07 22:09:49 paul
43734 + * From: Bart Trojanowski <bart@xelerance.com>
43735 + * Removing a left over '#else' that split another '#if/#endif' block in two.
43736 + *
43737 + * Revision 1.20.2.5 2006/07/07 15:43:17 paul
43738 + * From: Bart Trojanowski <bart@xelerance.com>
43739 + * improved protocol detection in ipsec_print_ip() -- a debug aid.
43740 + *
43741 + * Revision 1.20.2.4 2006/04/20 16:33:07 mcr
43742 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
43743 + * Fix in-kernel module compilation. Sub-makefiles do not work.
43744 + *
43745 + * Revision 1.20.2.3 2005/11/29 21:52:57 ken
43746 + * Fix for #518 MTU issues
43747 + *
43748 + * Revision 1.20.2.2 2005/11/27 21:41:03 paul
43749 + * Pull down TTL fixes from head. this fixes "Unknown symbol sysctl_ip_default_ttl"in for klips as module.
43750 + *
43751 + * Revision 1.20.2.1 2005/08/27 23:40:00 paul
43752 + * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
43753 + *
43754 + * Revision 1.20 2005/07/12 15:39:27 paul
43755 + * include asm/uaccess.h for VERIFY_WRITE
43756 + *
43757 + * Revision 1.19 2005/05/24 01:02:35 mcr
43758 + * some refactoring/simplification of situation where alg
43759 + * is not found.
43760 + *
43761 + * Revision 1.18 2005/05/23 23:52:33 mcr
43762 + * adjust comments, add additional debugging.
43763 + *
43764 + * Revision 1.17 2005/05/23 22:57:23 mcr
43765 + * removed explicit 3DES support.
43766 + *
43767 + * Revision 1.16 2005/05/21 03:29:15 mcr
43768 + * fixed warning about unused zeroes if AH is off.
43769 + *
43770 + * Revision 1.15 2005/05/20 16:47:59 mcr
43771 + * include asm/checksum.h to get ip_fast_csum macro.
43772 + *
43773 + * Revision 1.14 2005/05/11 01:43:03 mcr
43774 + * removed "poor-man"s OOP in favour of proper C structures.
43775 + *
43776 + * Revision 1.13 2005/04/29 05:10:22 mcr
43777 + * removed from extraenous includes to make unit testing easier.
43778 + *
43779 + * Revision 1.12 2005/04/15 01:28:34 mcr
43780 + * use ipsec_dmp_block.
43781 + *
43782 + * Revision 1.11 2005/01/26 00:50:35 mcr
43783 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
43784 + * and make sure that NAT_TRAVERSAL is set as well to match
43785 + * userspace compiles of code.
43786 + *
43787 + * Revision 1.10 2004/09/13 17:55:21 ken
43788 + * MD5* -> osMD5*
43789 + *
43790 + * Revision 1.9 2004/07/10 19:11:18 mcr
43791 + * CONFIG_IPSEC -> CONFIG_KLIPS.
43792 + *
43793 + * Revision 1.8 2004/04/06 02:49:26 mcr
43794 + * pullup of algo code from alg-branch.
43795 + *
43796 + * Revision 1.7 2004/02/03 03:13:41 mcr
43797 + * mark invalid encapsulation states.
43798 + *
43799 + * Revision 1.6.2.1 2003/12/22 15:25:52 jjo
43800 + * Merged algo-0.8.1-rc11-test1 into alg-branch
43801 + *
43802 + * Revision 1.6 2003/12/10 01:14:27 mcr
43803 + * NAT-traversal patches to KLIPS.
43804 + *
43805 + * Revision 1.5 2003/10/31 02:27:55 mcr
43806 + * pulled up port-selector patches and sa_id elimination.
43807 + *
43808 + * Revision 1.4.4.2 2003/10/29 01:37:39 mcr
43809 + * when creating %hold from %trap, only make the %hold as
43810 + * specific as the %trap was - so if the protocol and ports
43811 + * were wildcards, then the %hold will be too.
43812 + *
43813 + * Revision 1.4.4.1 2003/09/21 13:59:56 mcr
43814 + * pre-liminary X.509 patch - does not yet pass tests.
43815 + *
43816 + * Revision 1.4 2003/06/20 02:28:10 mcr
43817 + * misstype of variable name, not detected by module build.
43818 + *
43819 + * Revision 1.3 2003/06/20 01:42:21 mcr
43820 + * added counters to measure how many ACQUIREs we send to pluto,
43821 + * and how many are successfully sent.
43822 + *
43823 + * Revision 1.2 2003/04/03 17:38:35 rgb
43824 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
43825 + * Normalised coding style.
43826 + * Simplified logic and reduced duplication of code.
43827 + *
43828 + * Revision 1.1 2003/02/12 19:31:23 rgb
43829 + * Refactored from ipsec_tunnel.c
43830 + *
43831 + * Local Variables:
43832 + * c-file-style: "linux"
43833 + * End:
43834 + *
43835 + */
43836 --- /dev/null Tue Mar 11 13:02:56 2003
43837 +++ linux/net/ipsec/match586.S Mon Feb 9 13:51:03 2004
43838 @@ -0,0 +1,357 @@
43839 +/* match.s -- Pentium-optimized version of longest_match()
43840 + * Written for zlib 1.1.2
43841 + * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
43842 + *
43843 + * This is free software; you can redistribute it and/or modify it
43844 + * under the terms of the GNU General Public License.
43845 + */
43846 +
43847 +#ifndef NO_UNDERLINE
43848 +#define match_init _ipcomp_match_init
43849 +#define longest_match _ipcomp_longest_match
43850 +#else
43851 +#define match_init ipcomp_match_init
43852 +#define longest_match ipcomp_longest_match
43853 +#endif
43854 +
43855 +#define MAX_MATCH (258)
43856 +#define MIN_MATCH (3)
43857 +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
43858 +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
43859 +
43860 +/* stack frame offsets */
43861 +
43862 +#define wmask 0 /* local copy of s->wmask */
43863 +#define window 4 /* local copy of s->window */
43864 +#define windowbestlen 8 /* s->window + bestlen */
43865 +#define chainlenscanend 12 /* high word: current chain len */
43866 + /* low word: last bytes sought */
43867 +#define scanstart 16 /* first two bytes of string */
43868 +#define scanalign 20 /* dword-misalignment of string */
43869 +#define nicematch 24 /* a good enough match size */
43870 +#define bestlen 28 /* size of best match so far */
43871 +#define scan 32 /* ptr to string wanting match */
43872 +
43873 +#define LocalVarsSize (36)
43874 +/* saved ebx 36 */
43875 +/* saved edi 40 */
43876 +/* saved esi 44 */
43877 +/* saved ebp 48 */
43878 +/* return address 52 */
43879 +#define deflatestate 56 /* the function arguments */
43880 +#define curmatch 60
43881 +
43882 +/* Offsets for fields in the deflate_state structure. These numbers
43883 + * are calculated from the definition of deflate_state, with the
43884 + * assumption that the compiler will dword-align the fields. (Thus,
43885 + * changing the definition of deflate_state could easily cause this
43886 + * program to crash horribly, without so much as a warning at
43887 + * compile time. Sigh.)
43888 + */
43889 +#define dsWSize 36
43890 +#define dsWMask 44
43891 +#define dsWindow 48
43892 +#define dsPrev 56
43893 +#define dsMatchLen 88
43894 +#define dsPrevMatch 92
43895 +#define dsStrStart 100
43896 +#define dsMatchStart 104
43897 +#define dsLookahead 108
43898 +#define dsPrevLen 112
43899 +#define dsMaxChainLen 116
43900 +#define dsGoodMatch 132
43901 +#define dsNiceMatch 136
43902 +
43903 +
43904 +.file "match.S"
43905 +
43906 +.globl match_init, longest_match
43907 +
43908 +.text
43909 +
43910 +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
43911 +
43912 +longest_match:
43913 +
43914 +/* Save registers that the compiler may be using, and adjust %esp to */
43915 +/* make room for our stack frame. */
43916 +
43917 + pushl %ebp
43918 + pushl %edi
43919 + pushl %esi
43920 + pushl %ebx
43921 + subl $LocalVarsSize, %esp
43922 +
43923 +/* Retrieve the function arguments. %ecx will hold cur_match */
43924 +/* throughout the entire function. %edx will hold the pointer to the */
43925 +/* deflate_state structure during the function's setup (before */
43926 +/* entering the main loop). */
43927 +
43928 + movl deflatestate(%esp), %edx
43929 + movl curmatch(%esp), %ecx
43930 +
43931 +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
43932 +
43933 + movl dsNiceMatch(%edx), %eax
43934 + movl dsLookahead(%edx), %ebx
43935 + cmpl %eax, %ebx
43936 + jl LookaheadLess
43937 + movl %eax, %ebx
43938 +LookaheadLess: movl %ebx, nicematch(%esp)
43939 +
43940 +/* register Bytef *scan = s->window + s->strstart; */
43941 +
43942 + movl dsWindow(%edx), %esi
43943 + movl %esi, window(%esp)
43944 + movl dsStrStart(%edx), %ebp
43945 + lea (%esi,%ebp), %edi
43946 + movl %edi, scan(%esp)
43947 +
43948 +/* Determine how many bytes the scan ptr is off from being */
43949 +/* dword-aligned. */
43950 +
43951 + movl %edi, %eax
43952 + negl %eax
43953 + andl $3, %eax
43954 + movl %eax, scanalign(%esp)
43955 +
43956 +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
43957 +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
43958 +
43959 + movl dsWSize(%edx), %eax
43960 + subl $MIN_LOOKAHEAD, %eax
43961 + subl %eax, %ebp
43962 + jg LimitPositive
43963 + xorl %ebp, %ebp
43964 +LimitPositive:
43965 +
43966 +/* unsigned chain_length = s->max_chain_length; */
43967 +/* if (s->prev_length >= s->good_match) { */
43968 +/* chain_length >>= 2; */
43969 +/* } */
43970 +
43971 + movl dsPrevLen(%edx), %eax
43972 + movl dsGoodMatch(%edx), %ebx
43973 + cmpl %ebx, %eax
43974 + movl dsMaxChainLen(%edx), %ebx
43975 + jl LastMatchGood
43976 + shrl $2, %ebx
43977 +LastMatchGood:
43978 +
43979 +/* chainlen is decremented once beforehand so that the function can */
43980 +/* use the sign flag instead of the zero flag for the exit test. */
43981 +/* It is then shifted into the high word, to make room for the scanend */
43982 +/* scanend value, which it will always accompany. */
43983 +
43984 + decl %ebx
43985 + shll $16, %ebx
43986 +
43987 +/* int best_len = s->prev_length; */
43988 +
43989 + movl dsPrevLen(%edx), %eax
43990 + movl %eax, bestlen(%esp)
43991 +
43992 +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
43993 +
43994 + addl %eax, %esi
43995 + movl %esi, windowbestlen(%esp)
43996 +
43997 +/* register ush scan_start = *(ushf*)scan; */
43998 +/* register ush scan_end = *(ushf*)(scan+best_len-1); */
43999 +
44000 + movw (%edi), %bx
44001 + movw %bx, scanstart(%esp)
44002 + movw -1(%edi,%eax), %bx
44003 + movl %ebx, chainlenscanend(%esp)
44004 +
44005 +/* Posf *prev = s->prev; */
44006 +/* uInt wmask = s->w_mask; */
44007 +
44008 + movl dsPrev(%edx), %edi
44009 + movl dsWMask(%edx), %edx
44010 + mov %edx, wmask(%esp)
44011 +
44012 +/* Jump into the main loop. */
44013 +
44014 + jmp LoopEntry
44015 +
44016 +.balign 16
44017 +
44018 +/* do {
44019 + * match = s->window + cur_match;
44020 + * if (*(ushf*)(match+best_len-1) != scan_end ||
44021 + * *(ushf*)match != scan_start) continue;
44022 + * [...]
44023 + * } while ((cur_match = prev[cur_match & wmask]) > limit
44024 + * && --chain_length != 0);
44025 + *
44026 + * Here is the inner loop of the function. The function will spend the
44027 + * majority of its time in this loop, and majority of that time will
44028 + * be spent in the first ten instructions.
44029 + *
44030 + * Within this loop:
44031 + * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
44032 + * %ecx = curmatch
44033 + * %edx = curmatch & wmask
44034 + * %esi = windowbestlen - i.e., (window + bestlen)
44035 + * %edi = prev
44036 + * %ebp = limit
44037 + *
44038 + * Two optimization notes on the choice of instructions:
44039 + *
44040 + * The first instruction uses a 16-bit address, which costs an extra,
44041 + * unpairable cycle. This is cheaper than doing a 32-bit access and
44042 + * zeroing the high word, due to the 3-cycle misalignment penalty which
44043 + * would occur half the time. This also turns out to be cheaper than
44044 + * doing two separate 8-bit accesses, as the memory is so rarely in the
44045 + * L1 cache.
44046 + *
44047 + * The window buffer, however, apparently spends a lot of time in the
44048 + * cache, and so it is faster to retrieve the word at the end of the
44049 + * match string with two 8-bit loads. The instructions that test the
44050 + * word at the beginning of the match string, however, are executed
44051 + * much less frequently, and there it was cheaper to use 16-bit
44052 + * instructions, which avoided the necessity of saving off and
44053 + * subsequently reloading one of the other registers.
44054 + */
44055 +LookupLoop:
44056 + /* 1 U & V */
44057 + movw (%edi,%edx,2), %cx /* 2 U pipe */
44058 + movl wmask(%esp), %edx /* 2 V pipe */
44059 + cmpl %ebp, %ecx /* 3 U pipe */
44060 + jbe LeaveNow /* 3 V pipe */
44061 + subl $0x00010000, %ebx /* 4 U pipe */
44062 + js LeaveNow /* 4 V pipe */
44063 +LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
44064 + andl %ecx, %edx /* 5 V pipe */
44065 + cmpb %bl, %al /* 6 U pipe */
44066 + jnz LookupLoop /* 6 V pipe */
44067 + movb (%esi,%ecx), %ah
44068 + cmpb %bh, %ah
44069 + jnz LookupLoop
44070 + movl window(%esp), %eax
44071 + movw (%eax,%ecx), %ax
44072 + cmpw scanstart(%esp), %ax
44073 + jnz LookupLoop
44074 +
44075 +/* Store the current value of chainlen. */
44076 +
44077 + movl %ebx, chainlenscanend(%esp)
44078 +
44079 +/* Point %edi to the string under scrutiny, and %esi to the string we */
44080 +/* are hoping to match it up with. In actuality, %esi and %edi are */
44081 +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
44082 +/* initialized to -(MAX_MATCH_8 - scanalign). */
44083 +
44084 + movl window(%esp), %esi
44085 + movl scan(%esp), %edi
44086 + addl %ecx, %esi
44087 + movl scanalign(%esp), %eax
44088 + movl $(-MAX_MATCH_8), %edx
44089 + lea MAX_MATCH_8(%edi,%eax), %edi
44090 + lea MAX_MATCH_8(%esi,%eax), %esi
44091 +
44092 +/* Test the strings for equality, 8 bytes at a time. At the end,
44093 + * adjust %edx so that it is offset to the exact byte that mismatched.
44094 + *
44095 + * We already know at this point that the first three bytes of the
44096 + * strings match each other, and they can be safely passed over before
44097 + * starting the compare loop. So what this code does is skip over 0-3
44098 + * bytes, as much as necessary in order to dword-align the %edi
44099 + * pointer. (%esi will still be misaligned three times out of four.)
44100 + *
44101 + * It should be confessed that this loop usually does not represent
44102 + * much of the total running time. Replacing it with a more
44103 + * straightforward "rep cmpsb" would not drastically degrade
44104 + * performance.
44105 + */
44106 +LoopCmps:
44107 + movl (%esi,%edx), %eax
44108 + movl (%edi,%edx), %ebx
44109 + xorl %ebx, %eax
44110 + jnz LeaveLoopCmps
44111 + movl 4(%esi,%edx), %eax
44112 + movl 4(%edi,%edx), %ebx
44113 + xorl %ebx, %eax
44114 + jnz LeaveLoopCmps4
44115 + addl $8, %edx
44116 + jnz LoopCmps
44117 + jmp LenMaximum
44118 +LeaveLoopCmps4: addl $4, %edx
44119 +LeaveLoopCmps: testl $0x0000FFFF, %eax
44120 + jnz LenLower
44121 + addl $2, %edx
44122 + shrl $16, %eax
44123 +LenLower: subb $1, %al
44124 + adcl $0, %edx
44125 +
44126 +/* Calculate the length of the match. If it is longer than MAX_MATCH, */
44127 +/* then automatically accept it as the best possible match and leave. */
44128 +
44129 + lea (%edi,%edx), %eax
44130 + movl scan(%esp), %edi
44131 + subl %edi, %eax
44132 + cmpl $MAX_MATCH, %eax
44133 + jge LenMaximum
44134 +
44135 +/* If the length of the match is not longer than the best match we */
44136 +/* have so far, then forget it and return to the lookup loop. */
44137 +
44138 + movl deflatestate(%esp), %edx
44139 + movl bestlen(%esp), %ebx
44140 + cmpl %ebx, %eax
44141 + jg LongerMatch
44142 + movl chainlenscanend(%esp), %ebx
44143 + movl windowbestlen(%esp), %esi
44144 + movl dsPrev(%edx), %edi
44145 + movl wmask(%esp), %edx
44146 + andl %ecx, %edx
44147 + jmp LookupLoop
44148 +
44149 +/* s->match_start = cur_match; */
44150 +/* best_len = len; */
44151 +/* if (len >= nice_match) break; */
44152 +/* scan_end = *(ushf*)(scan+best_len-1); */
44153 +
44154 +LongerMatch: movl nicematch(%esp), %ebx
44155 + movl %eax, bestlen(%esp)
44156 + movl %ecx, dsMatchStart(%edx)
44157 + cmpl %ebx, %eax
44158 + jge LeaveNow
44159 + movl window(%esp), %esi
44160 + addl %eax, %esi
44161 + movl %esi, windowbestlen(%esp)
44162 + movl chainlenscanend(%esp), %ebx
44163 + movw -1(%edi,%eax), %bx
44164 + movl dsPrev(%edx), %edi
44165 + movl %ebx, chainlenscanend(%esp)
44166 + movl wmask(%esp), %edx
44167 + andl %ecx, %edx
44168 + jmp LookupLoop
44169 +
44170 +/* Accept the current string, with the maximum possible length. */
44171 +
44172 +LenMaximum: movl deflatestate(%esp), %edx
44173 + movl $MAX_MATCH, bestlen(%esp)
44174 + movl %ecx, dsMatchStart(%edx)
44175 +
44176 +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
44177 +/* return s->lookahead; */
44178 +
44179 +LeaveNow:
44180 + movl deflatestate(%esp), %edx
44181 + movl bestlen(%esp), %ebx
44182 + movl dsLookahead(%edx), %eax
44183 + cmpl %eax, %ebx
44184 + jg LookaheadRet
44185 + movl %ebx, %eax
44186 +LookaheadRet:
44187 +
44188 +/* Restore the stack and return from whence we came. */
44189 +
44190 + addl $LocalVarsSize, %esp
44191 + popl %ebx
44192 + popl %esi
44193 + popl %edi
44194 + popl %ebp
44195 +match_init: ret
44196 --- /dev/null Tue Mar 11 13:02:56 2003
44197 +++ linux/net/ipsec/match686.S Mon Feb 9 13:51:03 2004
44198 @@ -0,0 +1,330 @@
44199 +/* match.s -- Pentium-Pro-optimized version of longest_match()
44200 + * Written for zlib 1.1.2
44201 + * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
44202 + *
44203 + * This is free software; you can redistribute it and/or modify it
44204 + * under the terms of the GNU General Public License.
44205 + */
44206 +
44207 +#ifndef NO_UNDERLINE
44208 +#define match_init _ipcomp_match_init
44209 +#define longest_match _ipcomp_longest_match
44210 +#else
44211 +#define match_init ipcomp_match_init
44212 +#define longest_match ipcomp_longest_match
44213 +#endif
44214 +
44215 +#define MAX_MATCH (258)
44216 +#define MIN_MATCH (3)
44217 +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
44218 +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
44219 +
44220 +/* stack frame offsets */
44221 +
44222 +#define chainlenwmask 0 /* high word: current chain len */
44223 + /* low word: s->wmask */
44224 +#define window 4 /* local copy of s->window */
44225 +#define windowbestlen 8 /* s->window + bestlen */
44226 +#define scanstart 16 /* first two bytes of string */
44227 +#define scanend 12 /* last two bytes of string */
44228 +#define scanalign 20 /* dword-misalignment of string */
44229 +#define nicematch 24 /* a good enough match size */
44230 +#define bestlen 28 /* size of best match so far */
44231 +#define scan 32 /* ptr to string wanting match */
44232 +
44233 +#define LocalVarsSize (36)
44234 +/* saved ebx 36 */
44235 +/* saved edi 40 */
44236 +/* saved esi 44 */
44237 +/* saved ebp 48 */
44238 +/* return address 52 */
44239 +#define deflatestate 56 /* the function arguments */
44240 +#define curmatch 60
44241 +
44242 +/* Offsets for fields in the deflate_state structure. These numbers
44243 + * are calculated from the definition of deflate_state, with the
44244 + * assumption that the compiler will dword-align the fields. (Thus,
44245 + * changing the definition of deflate_state could easily cause this
44246 + * program to crash horribly, without so much as a warning at
44247 + * compile time. Sigh.)
44248 + */
44249 +#define dsWSize 36
44250 +#define dsWMask 44
44251 +#define dsWindow 48
44252 +#define dsPrev 56
44253 +#define dsMatchLen 88
44254 +#define dsPrevMatch 92
44255 +#define dsStrStart 100
44256 +#define dsMatchStart 104
44257 +#define dsLookahead 108
44258 +#define dsPrevLen 112
44259 +#define dsMaxChainLen 116
44260 +#define dsGoodMatch 132
44261 +#define dsNiceMatch 136
44262 +
44263 +
44264 +.file "match.S"
44265 +
44266 +.globl match_init, longest_match
44267 +
44268 +.text
44269 +
44270 +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
44271 +
44272 +longest_match:
44273 +
44274 +/* Save registers that the compiler may be using, and adjust %esp to */
44275 +/* make room for our stack frame. */
44276 +
44277 + pushl %ebp
44278 + pushl %edi
44279 + pushl %esi
44280 + pushl %ebx
44281 + subl $LocalVarsSize, %esp
44282 +
44283 +/* Retrieve the function arguments. %ecx will hold cur_match */
44284 +/* throughout the entire function. %edx will hold the pointer to the */
44285 +/* deflate_state structure during the function's setup (before */
44286 +/* entering the main loop). */
44287 +
44288 + movl deflatestate(%esp), %edx
44289 + movl curmatch(%esp), %ecx
44290 +
44291 +/* uInt wmask = s->w_mask; */
44292 +/* unsigned chain_length = s->max_chain_length; */
44293 +/* if (s->prev_length >= s->good_match) { */
44294 +/* chain_length >>= 2; */
44295 +/* } */
44296 +
44297 + movl dsPrevLen(%edx), %eax
44298 + movl dsGoodMatch(%edx), %ebx
44299 + cmpl %ebx, %eax
44300 + movl dsWMask(%edx), %eax
44301 + movl dsMaxChainLen(%edx), %ebx
44302 + jl LastMatchGood
44303 + shrl $2, %ebx
44304 +LastMatchGood:
44305 +
44306 +/* chainlen is decremented once beforehand so that the function can */
44307 +/* use the sign flag instead of the zero flag for the exit test. */
44308 +/* It is then shifted into the high word, to make room for the wmask */
44309 +/* value, which it will always accompany. */
44310 +
44311 + decl %ebx
44312 + shll $16, %ebx
44313 + orl %eax, %ebx
44314 + movl %ebx, chainlenwmask(%esp)
44315 +
44316 +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
44317 +
44318 + movl dsNiceMatch(%edx), %eax
44319 + movl dsLookahead(%edx), %ebx
44320 + cmpl %eax, %ebx
44321 + jl LookaheadLess
44322 + movl %eax, %ebx
44323 +LookaheadLess: movl %ebx, nicematch(%esp)
44324 +
44325 +/* register Bytef *scan = s->window + s->strstart; */
44326 +
44327 + movl dsWindow(%edx), %esi
44328 + movl %esi, window(%esp)
44329 + movl dsStrStart(%edx), %ebp
44330 + lea (%esi,%ebp), %edi
44331 + movl %edi, scan(%esp)
44332 +
44333 +/* Determine how many bytes the scan ptr is off from being */
44334 +/* dword-aligned. */
44335 +
44336 + movl %edi, %eax
44337 + negl %eax
44338 + andl $3, %eax
44339 + movl %eax, scanalign(%esp)
44340 +
44341 +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
44342 +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
44343 +
44344 + movl dsWSize(%edx), %eax
44345 + subl $MIN_LOOKAHEAD, %eax
44346 + subl %eax, %ebp
44347 + jg LimitPositive
44348 + xorl %ebp, %ebp
44349 +LimitPositive:
44350 +
44351 +/* int best_len = s->prev_length; */
44352 +
44353 + movl dsPrevLen(%edx), %eax
44354 + movl %eax, bestlen(%esp)
44355 +
44356 +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
44357 +
44358 + addl %eax, %esi
44359 + movl %esi, windowbestlen(%esp)
44360 +
44361 +/* register ush scan_start = *(ushf*)scan; */
44362 +/* register ush scan_end = *(ushf*)(scan+best_len-1); */
44363 +/* Posf *prev = s->prev; */
44364 +
44365 + movzwl (%edi), %ebx
44366 + movl %ebx, scanstart(%esp)
44367 + movzwl -1(%edi,%eax), %ebx
44368 + movl %ebx, scanend(%esp)
44369 + movl dsPrev(%edx), %edi
44370 +
44371 +/* Jump into the main loop. */
44372 +
44373 + movl chainlenwmask(%esp), %edx
44374 + jmp LoopEntry
44375 +
44376 +.balign 16
44377 +
44378 +/* do {
44379 + * match = s->window + cur_match;
44380 + * if (*(ushf*)(match+best_len-1) != scan_end ||
44381 + * *(ushf*)match != scan_start) continue;
44382 + * [...]
44383 + * } while ((cur_match = prev[cur_match & wmask]) > limit
44384 + * && --chain_length != 0);
44385 + *
44386 + * Here is the inner loop of the function. The function will spend the
44387 + * majority of its time in this loop, and majority of that time will
44388 + * be spent in the first ten instructions.
44389 + *
44390 + * Within this loop:
44391 + * %ebx = scanend
44392 + * %ecx = curmatch
44393 + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
44394 + * %esi = windowbestlen - i.e., (window + bestlen)
44395 + * %edi = prev
44396 + * %ebp = limit
44397 + */
44398 +LookupLoop:
44399 + andl %edx, %ecx
44400 + movzwl (%edi,%ecx,2), %ecx
44401 + cmpl %ebp, %ecx
44402 + jbe LeaveNow
44403 + subl $0x00010000, %edx
44404 + js LeaveNow
44405 +LoopEntry: movzwl -1(%esi,%ecx), %eax
44406 + cmpl %ebx, %eax
44407 + jnz LookupLoop
44408 + movl window(%esp), %eax
44409 + movzwl (%eax,%ecx), %eax
44410 + cmpl scanstart(%esp), %eax
44411 + jnz LookupLoop
44412 +
44413 +/* Store the current value of chainlen. */
44414 +
44415 + movl %edx, chainlenwmask(%esp)
44416 +
44417 +/* Point %edi to the string under scrutiny, and %esi to the string we */
44418 +/* are hoping to match it up with. In actuality, %esi and %edi are */
44419 +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
44420 +/* initialized to -(MAX_MATCH_8 - scanalign). */
44421 +
44422 + movl window(%esp), %esi
44423 + movl scan(%esp), %edi
44424 + addl %ecx, %esi
44425 + movl scanalign(%esp), %eax
44426 + movl $(-MAX_MATCH_8), %edx
44427 + lea MAX_MATCH_8(%edi,%eax), %edi
44428 + lea MAX_MATCH_8(%esi,%eax), %esi
44429 +
44430 +/* Test the strings for equality, 8 bytes at a time. At the end,
44431 + * adjust %edx so that it is offset to the exact byte that mismatched.
44432 + *
44433 + * We already know at this point that the first three bytes of the
44434 + * strings match each other, and they can be safely passed over before
44435 + * starting the compare loop. So what this code does is skip over 0-3
44436 + * bytes, as much as necessary in order to dword-align the %edi
44437 + * pointer. (%esi will still be misaligned three times out of four.)
44438 + *
44439 + * It should be confessed that this loop usually does not represent
44440 + * much of the total running time. Replacing it with a more
44441 + * straightforward "rep cmpsb" would not drastically degrade
44442 + * performance.
44443 + */
44444 +LoopCmps:
44445 + movl (%esi,%edx), %eax
44446 + xorl (%edi,%edx), %eax
44447 + jnz LeaveLoopCmps
44448 + movl 4(%esi,%edx), %eax
44449 + xorl 4(%edi,%edx), %eax
44450 + jnz LeaveLoopCmps4
44451 + addl $8, %edx
44452 + jnz LoopCmps
44453 + jmp LenMaximum
44454 +LeaveLoopCmps4: addl $4, %edx
44455 +LeaveLoopCmps: testl $0x0000FFFF, %eax
44456 + jnz LenLower
44457 + addl $2, %edx
44458 + shrl $16, %eax
44459 +LenLower: subb $1, %al
44460 + adcl $0, %edx
44461 +
44462 +/* Calculate the length of the match. If it is longer than MAX_MATCH, */
44463 +/* then automatically accept it as the best possible match and leave. */
44464 +
44465 + lea (%edi,%edx), %eax
44466 + movl scan(%esp), %edi
44467 + subl %edi, %eax
44468 + cmpl $MAX_MATCH, %eax
44469 + jge LenMaximum
44470 +
44471 +/* If the length of the match is not longer than the best match we */
44472 +/* have so far, then forget it and return to the lookup loop. */
44473 +
44474 + movl deflatestate(%esp), %edx
44475 + movl bestlen(%esp), %ebx
44476 + cmpl %ebx, %eax
44477 + jg LongerMatch
44478 + movl windowbestlen(%esp), %esi
44479 + movl dsPrev(%edx), %edi
44480 + movl scanend(%esp), %ebx
44481 + movl chainlenwmask(%esp), %edx
44482 + jmp LookupLoop
44483 +
44484 +/* s->match_start = cur_match; */
44485 +/* best_len = len; */
44486 +/* if (len >= nice_match) break; */
44487 +/* scan_end = *(ushf*)(scan+best_len-1); */
44488 +
44489 +LongerMatch: movl nicematch(%esp), %ebx
44490 + movl %eax, bestlen(%esp)
44491 + movl %ecx, dsMatchStart(%edx)
44492 + cmpl %ebx, %eax
44493 + jge LeaveNow
44494 + movl window(%esp), %esi
44495 + addl %eax, %esi
44496 + movl %esi, windowbestlen(%esp)
44497 + movzwl -1(%edi,%eax), %ebx
44498 + movl dsPrev(%edx), %edi
44499 + movl %ebx, scanend(%esp)
44500 + movl chainlenwmask(%esp), %edx
44501 + jmp LookupLoop
44502 +
44503 +/* Accept the current string, with the maximum possible length. */
44504 +
44505 +LenMaximum: movl deflatestate(%esp), %edx
44506 + movl $MAX_MATCH, bestlen(%esp)
44507 + movl %ecx, dsMatchStart(%edx)
44508 +
44509 +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
44510 +/* return s->lookahead; */
44511 +
44512 +LeaveNow:
44513 + movl deflatestate(%esp), %edx
44514 + movl bestlen(%esp), %ebx
44515 + movl dsLookahead(%edx), %eax
44516 + cmpl %eax, %ebx
44517 + jg LookaheadRet
44518 + movl %ebx, %eax
44519 +LookaheadRet:
44520 +
44521 +/* Restore the stack and return from whence we came. */
44522 +
44523 + addl $LocalVarsSize, %esp
44524 + popl %ebx
44525 + popl %esi
44526 + popl %edi
44527 + popl %ebp
44528 +match_init: ret
44529 --- /dev/null Tue Mar 11 13:02:56 2003
44530 +++ linux/net/ipsec/null/ipsec_alg_null.c Mon Feb 9 13:51:03 2004
44531 @@ -0,0 +1,145 @@
44532 +/*
44533 + * ipsec_alg NULL cipher stubs
44534 + *
44535 + * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
44536 + *
44537 + * $Id: ipsec_alg_null.c,v 1.1.2.1 2006/10/11 18:14:33 paul Exp $
44538 + *
44539 + * This program is free software; you can redistribute it and/or modify it
44540 + * under the terms of the GNU General Public License as published by the
44541 + * Free Software Foundation; either version 2 of the License, or (at your
44542 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
44543 + *
44544 + * This program is distributed in the hope that it will be useful, but
44545 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
44546 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44547 + * for more details.
44548 + *
44549 + */
44550 +#include <linux/config.h>
44551 +#include <linux/version.h>
44552 +
44553 +/*
44554 + * special case: ipsec core modular with this static algo inside:
44555 + * must avoid MODULE magic for this file
44556 + */
44557 +#if defined(CONFIG_KLIPS_MODULE) && defined(CONFIG_KLIPS_ENC_NULL)
44558 +#undef MODULE
44559 +#endif
44560 +
44561 +#include <linux/module.h>
44562 +#include <linux/init.h>
44563 +
44564 +#include <linux/kernel.h> /* printk() */
44565 +#include <linux/errno.h> /* error codes */
44566 +#include <linux/types.h> /* size_t */
44567 +#include <linux/string.h>
44568 +
44569 +/* Check if __exit is defined, if not null it */
44570 +#ifndef __exit
44571 +#define __exit
44572 +#endif
44573 +
44574 +/* Low freeswan header coupling */
44575 +#include "openswan/ipsec_alg.h"
44576 +
44577 +#define ESP_NULL 11 /* from ipsec drafts */
44578 +#define ESP_NULL_BLK_LEN 1
44579 +
44580 +MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
44581 +static int debug_null=0;
44582 +static int test_null=0;
44583 +#ifdef module_param
44584 +module_param(debug_null, int, 0600);
44585 +module_param(test_null, int, 0600);
44586 +#else
44587 +MODULE_PARM(debug_null, "i");
44588 +MODULE_PARM(test_null, "i");
44589 +#endif
44590 +
44591 +typedef int null_context;
44592 +
44593 +struct null_eks{
44594 + null_context null_ctx;
44595 +};
44596 +static int _null_set_key(struct ipsec_alg_enc *alg,
44597 + __u8 * key_e, const __u8 * key,
44598 + size_t keysize) {
44599 + null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
44600 + if (debug_null > 0)
44601 + printk(KERN_DEBUG "klips_debug:_null_set_key:"
44602 + "key_e=%p key=%p keysize=%d\n",
44603 + key_e, key, keysize);
44604 + *ctx = 1;
44605 + return 0;
44606 +}
44607 +static int _null_cbc_encrypt(struct ipsec_alg_enc *alg,
44608 + __u8 * key_e, __u8 * in, int ilen, const __u8 * iv,
44609 + int encrypt) {
44610 + null_context *ctx=&((struct null_eks*)key_e)->null_ctx;
44611 + if (debug_null > 0)
44612 + printk(KERN_DEBUG "klips_debug:_null_cbc_encrypt:"
44613 + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
44614 + key_e, in, ilen, iv, encrypt);
44615 + (*ctx)++;
44616 + return ilen;
44617 +}
44618 +static struct ipsec_alg_enc ipsec_alg_NULL = {
44619 + ixt_common: { ixt_version: IPSEC_ALG_VERSION,
44620 + ixt_refcnt: ATOMIC_INIT(0),
44621 + ixt_name: "null",
44622 + ixt_blocksize: ESP_NULL_BLK_LEN,
44623 + ixt_support: {
44624 + ias_exttype: IPSEC_ALG_TYPE_ENCRYPT,
44625 + ias_id: ESP_NULL,
44626 + ias_ivlen: 0,
44627 + ias_keyminbits: 0,
44628 + ias_keymaxbits: 0,
44629 + },
44630 + },
44631 +#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44632 + ixt_module: THIS_MODULE,
44633 +#endif
44634 + ixt_e_keylen: 0,
44635 + ixt_e_ctx_size: sizeof(null_context),
44636 + ixt_e_set_key: _null_set_key,
44637 + ixt_e_cbc_encrypt:_null_cbc_encrypt,
44638 +};
44639 +
44640 +#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44641 +IPSEC_ALG_MODULE_INIT_MOD( ipsec_null_init )
44642 +#else
44643 +IPSEC_ALG_MODULE_INIT_STATIC( ipsec_null_init )
44644 +#endif
44645 +{
44646 + int ret, test_ret;
44647 + ret=register_ipsec_alg_enc(&ipsec_alg_NULL);
44648 + printk("ipsec_null_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
44649 + ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44650 + ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44651 + ipsec_alg_NULL.ixt_common.ixt_name,
44652 + ret);
44653 + if (ret==0 && test_null) {
44654 + test_ret=ipsec_alg_test(
44655 + ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44656 + ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44657 + test_null);
44658 + printk("ipsec_null_init(alg_type=%d alg_id=%d): test_ret=%d\n",
44659 + ipsec_alg_NULL.ixt_common.ixt_support.ias_exttype,
44660 + ipsec_alg_NULL.ixt_common.ixt_support.ias_id,
44661 + test_ret);
44662 + }
44663 + return ret;
44664 +}
44665 +#if defined(CONFIG_KLIPS_ENC_NULL_MODULE)
44666 +IPSEC_ALG_MODULE_EXIT_MOD( ipsec_null_fini )
44667 +#else
44668 +IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_null_fini )
44669 +#endif
44670 +{
44671 + unregister_ipsec_alg_enc(&ipsec_alg_NULL);
44672 + return;
44673 +}
44674 +#ifdef MODULE_LICENSE
44675 +MODULE_LICENSE("GPL");
44676 +#endif
44677 --- /dev/null Tue Mar 11 13:02:56 2003
44678 +++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004
44679 @@ -0,0 +1,2022 @@
44680 +/*
44681 + * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
44682 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
44683 + *
44684 + * This program is free software; you can redistribute it and/or modify it
44685 + * under the terms of the GNU General Public License as published by the
44686 + * Free Software Foundation; either version 2 of the License, or (at your
44687 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
44688 + *
44689 + * This program is distributed in the hope that it will be useful, but
44690 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
44691 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
44692 + * for more details.
44693 + *
44694 + * RCSID $Id: pfkey_v2.c,v 1.97.2.12 2006/11/24 05:43:29 paul Exp $
44695 + */
44696 +
44697 +/*
44698 + * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
44699 + * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
44700 + */
44701 +
44702 +#define __NO_VERSION__
44703 +#include <linux/module.h>
44704 +#include <linux/version.h>
44705 +#ifndef AUTOCONF_INCLUDED
44706 +#include <linux/config.h>
44707 +#endif
44708 +#include <linux/kernel.h>
44709 +
44710 +#include "openswan/ipsec_param.h"
44711 +
44712 +#include <linux/major.h>
44713 +#include <linux/signal.h>
44714 +#include <linux/sched.h>
44715 +#include <linux/errno.h>
44716 +#include <linux/string.h>
44717 +#include <linux/stat.h>
44718 +#include <linux/socket.h>
44719 +#include <linux/un.h>
44720 +#include <linux/fcntl.h>
44721 +#include <linux/termios.h>
44722 +#include <linux/socket.h>
44723 +#include <linux/sockios.h>
44724 +#include <linux/net.h> /* struct socket */
44725 +#include <linux/in.h>
44726 +#include <linux/fs.h>
44727 +#ifdef MALLOC_SLAB
44728 +# include <linux/slab.h> /* kmalloc() */
44729 +#else /* MALLOC_SLAB */
44730 +# include <linux/malloc.h> /* kmalloc() */
44731 +#endif /* MALLOC_SLAB */
44732 +#include <asm/segment.h>
44733 +#include <linux/skbuff.h>
44734 +#include <linux/netdevice.h>
44735 +#include <net/sock.h> /* struct sock */
44736 +#include <net/protocol.h>
44737 +/* #include <net/tcp.h> */
44738 +#include <net/af_unix.h>
44739 +#ifdef CONFIG_PROC_FS
44740 +# include <linux/proc_fs.h>
44741 +#endif /* CONFIG_PROC_FS */
44742 +
44743 +#include <linux/types.h>
44744 +
44745 +#include <openswan.h>
44746 +
44747 +#include "openswan/radij.h"
44748 +#include "openswan/ipsec_encap.h"
44749 +#include "openswan/ipsec_sa.h"
44750 +
44751 +#include <pfkeyv2.h>
44752 +#include <pfkey.h>
44753 +
44754 +#include "openswan/ipsec_proto.h"
44755 +#include "openswan/ipsec_kern24.h"
44756 +
44757 +#ifdef CONFIG_KLIPS_DEBUG
44758 +int debug_pfkey = 0;
44759 +extern int sysctl_ipsec_debug_verbose;
44760 +#endif /* CONFIG_KLIPS_DEBUG */
44761 +
44762 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
44763 +
44764 +#ifndef SOCKOPS_WRAPPED
44765 +#define SOCKOPS_WRAPPED(name) name
44766 +#endif /* SOCKOPS_WRAPPED */
44767 +
44768 +#ifdef NET_26
44769 +static rwlock_t pfkey_sock_lock = RW_LOCK_UNLOCKED;
44770 +HLIST_HEAD(pfkey_sock_list);
44771 +static DECLARE_WAIT_QUEUE_HEAD(pfkey_sock_wait);
44772 +static atomic_t pfkey_sock_users = ATOMIC_INIT(0);
44773 +#else
44774 +struct sock *pfkey_sock_list = NULL;
44775 +#endif
44776 +
44777 +struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
44778 +
44779 +struct socket_list *pfkey_open_sockets = NULL;
44780 +struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
44781 +
44782 +int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
44783 +
44784 +DEBUG_NO_STATIC int pfkey_create(struct socket *sock, int protocol);
44785 +DEBUG_NO_STATIC int pfkey_shutdown(struct socket *sock, int mode);
44786 +DEBUG_NO_STATIC int pfkey_release(struct socket *sock);
44787 +
44788 +#ifdef NET_26
44789 +DEBUG_NO_STATIC int pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len);
44790 +DEBUG_NO_STATIC int pfkey_recvmsg(struct kiocb *kiocb, struct socket *sock, struct msghdr *msg
44791 + , size_t size, int flags);
44792 +#else
44793 +DEBUG_NO_STATIC int pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm);
44794 +DEBUG_NO_STATIC int pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm);
44795 +#endif
44796 +
44797 +struct net_proto_family pfkey_family_ops = {
44798 +#ifdef NETDEV_23
44799 + .family = PF_KEY,
44800 + .create = pfkey_create,
44801 +#ifdef NET_26
44802 + .owner = THIS_MODULE,
44803 +#endif
44804 +#else
44805 + PF_KEY,
44806 + pfkey_create
44807 +#endif
44808 +};
44809 +
44810 +struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
44811 +#ifdef NETDEV_23
44812 + family: PF_KEY,
44813 +#ifdef NET_26
44814 + owner: THIS_MODULE,
44815 +#endif
44816 + release: pfkey_release,
44817 + bind: sock_no_bind,
44818 + connect: sock_no_connect,
44819 + socketpair: sock_no_socketpair,
44820 + accept: sock_no_accept,
44821 + getname: sock_no_getname,
44822 + poll: datagram_poll,
44823 + ioctl: sock_no_ioctl,
44824 + listen: sock_no_listen,
44825 + shutdown: pfkey_shutdown,
44826 + setsockopt: sock_no_setsockopt,
44827 + getsockopt: sock_no_getsockopt,
44828 + sendmsg: pfkey_sendmsg,
44829 + recvmsg: pfkey_recvmsg,
44830 + mmap: sock_no_mmap,
44831 +#else /* NETDEV_23 */
44832 + PF_KEY,
44833 + sock_no_dup,
44834 + pfkey_release,
44835 + sock_no_bind,
44836 + sock_no_connect,
44837 + sock_no_socketpair,
44838 + sock_no_accept,
44839 + sock_no_getname,
44840 + datagram_poll,
44841 + sock_no_ioctl,
44842 + sock_no_listen,
44843 + pfkey_shutdown,
44844 + sock_no_setsockopt,
44845 + sock_no_getsockopt,
44846 + sock_no_fcntl,
44847 + pfkey_sendmsg,
44848 + pfkey_recvmsg
44849 +#endif /* NETDEV_23 */
44850 +};
44851 +
44852 +#ifdef NETDEV_23
44853 +#include <linux/smp_lock.h>
44854 +SOCKOPS_WRAP(pfkey, PF_KEY);
44855 +#endif /* NETDEV_23 */
44856 +
44857 +#ifdef NET_26
44858 +static void pfkey_sock_list_grab(void)
44859 +{
44860 + write_lock_bh(&pfkey_sock_lock);
44861 +
44862 + if (atomic_read(&pfkey_sock_users)) {
44863 + DECLARE_WAITQUEUE(wait, current);
44864 +
44865 + add_wait_queue_exclusive(&pfkey_sock_wait, &wait);
44866 + for(;;) {
44867 + set_current_state(TASK_UNINTERRUPTIBLE);
44868 + if (atomic_read(&pfkey_sock_users) == 0)
44869 + break;
44870 + write_unlock_bh(&pfkey_sock_lock);
44871 + schedule();
44872 + write_lock_bh(&pfkey_sock_lock);
44873 + }
44874 +
44875 + __set_current_state(TASK_RUNNING);
44876 + remove_wait_queue(&pfkey_sock_wait, &wait);
44877 + }
44878 +}
44879 +
44880 +static __inline__ void pfkey_sock_list_ungrab(void)
44881 +{
44882 + write_unlock_bh(&pfkey_sock_lock);
44883 + wake_up(&pfkey_sock_wait);
44884 +}
44885 +
44886 +static __inline__ void pfkey_lock_sock_list(void)
44887 +{
44888 + /* read_lock() synchronizes us to pfkey_table_grab */
44889 +
44890 + read_lock(&pfkey_sock_lock);
44891 + atomic_inc(&pfkey_sock_users);
44892 + read_unlock(&pfkey_sock_lock);
44893 +}
44894 +
44895 +static __inline__ void pfkey_unlock_sock_list(void)
44896 +{
44897 + if (atomic_dec_and_test(&pfkey_sock_users))
44898 + wake_up(&pfkey_sock_wait);
44899 +}
44900 +#endif
44901 +
44902 +int
44903 +pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
44904 +{
44905 + struct socket_list *socket_listp,*prev;
44906 +
44907 + if(!socketp) {
44908 + KLIPS_PRINT(debug_pfkey,
44909 + "klips_debug:pfkey_list_remove_socket: "
44910 + "NULL socketp handed in, failed.\n");
44911 + return -EINVAL;
44912 + }
44913 +
44914 + if(!sockets) {
44915 + KLIPS_PRINT(debug_pfkey,
44916 + "klips_debug:pfkey_list_remove_socket: "
44917 + "NULL sockets list handed in, failed.\n");
44918 + return -EINVAL;
44919 + }
44920 +
44921 + socket_listp = *sockets;
44922 + prev = NULL;
44923 +
44924 + KLIPS_PRINT(debug_pfkey,
44925 + "klips_debug:pfkey_list_remove_socket: "
44926 + "removing sock=0p%p\n",
44927 + socketp);
44928 +
44929 + while(socket_listp != NULL) {
44930 + if(socket_listp->socketp == socketp) {
44931 + if(prev != NULL) {
44932 + prev->next = socket_listp->next;
44933 + } else {
44934 + *sockets = socket_listp->next;
44935 + }
44936 +
44937 + kfree((void*)socket_listp);
44938 +
44939 + break;
44940 + }
44941 + prev = socket_listp;
44942 + socket_listp = socket_listp->next;
44943 + }
44944 +
44945 + return 0;
44946 +}
44947 +
44948 +int
44949 +pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
44950 +{
44951 + struct socket_list *socket_listp;
44952 +
44953 + if(!socketp) {
44954 + KLIPS_PRINT(debug_pfkey,
44955 + "klips_debug:pfkey_list_insert_socket: "
44956 + "NULL socketp handed in, failed.\n");
44957 + return -EINVAL;
44958 + }
44959 +
44960 + if(!sockets) {
44961 + KLIPS_PRINT(debug_pfkey,
44962 + "klips_debug:pfkey_list_insert_socket: "
44963 + "NULL sockets list handed in, failed.\n");
44964 + return -EINVAL;
44965 + }
44966 +
44967 + KLIPS_PRINT(debug_pfkey,
44968 + "klips_debug:pfkey_list_insert_socket: "
44969 + "allocating %lu bytes for socketp=0p%p\n",
44970 + (unsigned long) sizeof(struct socket_list),
44971 + socketp);
44972 +
44973 + if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
44974 + KLIPS_PRINT(debug_pfkey,
44975 + "klips_debug:pfkey_list_insert_socket: "
44976 + "memory allocation error.\n");
44977 + return -ENOMEM;
44978 + }
44979 +
44980 + socket_listp->socketp = socketp;
44981 + socket_listp->next = *sockets;
44982 + *sockets = socket_listp;
44983 +
44984 + return 0;
44985 +}
44986 +
44987 +int
44988 +pfkey_list_remove_supported(struct ipsec_alg_supported *supported, struct supported_list **supported_list)
44989 +{
44990 + struct supported_list *supported_listp = *supported_list, *prev = NULL;
44991 +
44992 + if(!supported) {
44993 + KLIPS_PRINT(debug_pfkey,
44994 + "klips_debug:pfkey_list_remove_supported: "
44995 + "NULL supported handed in, failed.\n");
44996 + return -EINVAL;
44997 + }
44998 +
44999 + if(!supported_list) {
45000 + KLIPS_PRINT(debug_pfkey,
45001 + "klips_debug:pfkey_list_remove_supported: "
45002 + "NULL supported_list handed in, failed.\n");
45003 + return -EINVAL;
45004 + }
45005 +
45006 + KLIPS_PRINT(debug_pfkey,
45007 + "klips_debug:pfkey_list_remove_supported: "
45008 + "removing supported=0p%p\n",
45009 + supported);
45010 +
45011 + while(supported_listp != NULL) {
45012 + if(supported_listp->supportedp == supported) {
45013 + if(prev != NULL) {
45014 + prev->next = supported_listp->next;
45015 + } else {
45016 + *supported_list = supported_listp->next;
45017 + }
45018 +
45019 + kfree((void*)supported_listp);
45020 +
45021 + break;
45022 + }
45023 + prev = supported_listp;
45024 + supported_listp = supported_listp->next;
45025 + }
45026 +
45027 + return 0;
45028 +}
45029 +
45030 +int
45031 +pfkey_list_insert_supported(struct ipsec_alg_supported *supported
45032 + , struct supported_list **supported_list)
45033 +{
45034 + struct supported_list *supported_listp;
45035 +
45036 + if(!supported) {
45037 + KLIPS_PRINT(debug_pfkey,
45038 + "klips_debug:pfkey_list_insert_supported: "
45039 + "NULL supported handed in, failed.\n");
45040 + return -EINVAL;
45041 + }
45042 +
45043 + if(!supported_list) {
45044 + KLIPS_PRINT(debug_pfkey,
45045 + "klips_debug:pfkey_list_insert_supported: "
45046 + "NULL supported_list handed in, failed.\n");
45047 + return -EINVAL;
45048 + }
45049 +
45050 + KLIPS_PRINT(debug_pfkey,
45051 + "klips_debug:pfkey_list_insert_supported: "
45052 + "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
45053 + (unsigned long) sizeof(struct supported_list),
45054 + supported,
45055 + supported_list);
45056 +
45057 + supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
45058 +
45059 + if(supported_listp == NULL)
45060 + {
45061 + KLIPS_PRINT(debug_pfkey,
45062 + "klips_debug:pfkey_list_insert_supported: "
45063 + "memory allocation error.\n");
45064 + return -ENOMEM;
45065 + }
45066 +
45067 + supported_listp->supportedp = supported;
45068 + supported_listp->next = *supported_list;
45069 + *supported_list = supported_listp;
45070 + KLIPS_PRINT(debug_pfkey,
45071 + "klips_debug:pfkey_list_insert_supported: "
45072 + "outgoing, supported=0p%p, supported_list=0p%p\n",
45073 + supported,
45074 + supported_list);
45075 +
45076 + return 0;
45077 +}
45078 +
45079 +#ifdef NET_26
45080 +DEBUG_NO_STATIC void
45081 +pfkey_insert_socket(struct sock *sk)
45082 +{
45083 + KLIPS_PRINT(debug_pfkey,
45084 + "klips_debug:pfkey_insert_socket: "
45085 + "sk=0p%p\n",
45086 + sk);
45087 + pfkey_sock_list_grab();
45088 + sk_add_node(sk, &pfkey_sock_list);
45089 + pfkey_sock_list_ungrab();
45090 +}
45091 +
45092 +DEBUG_NO_STATIC void
45093 +pfkey_remove_socket(struct sock *sk)
45094 +{
45095 + KLIPS_PRINT(debug_pfkey,
45096 + "klips_debug:pfkey_remove_socket: 0p%p\n", sk);
45097 + pfkey_sock_list_grab();
45098 + sk_del_node_init(sk);
45099 + pfkey_sock_list_ungrab();
45100 + return;
45101 +}
45102 +#else
45103 +
45104 +DEBUG_NO_STATIC void
45105 +pfkey_insert_socket(struct sock *sk)
45106 +{
45107 + KLIPS_PRINT(debug_pfkey,
45108 + "klips_debug:pfkey_insert_socket: "
45109 + "sk=0p%p\n",
45110 + sk);
45111 + cli();
45112 + sk->next=pfkey_sock_list;
45113 + pfkey_sock_list=sk;
45114 + sti();
45115 +}
45116 +DEBUG_NO_STATIC void
45117 +pfkey_remove_socket(struct sock *sk)
45118 +{
45119 + struct sock **s;
45120 +
45121 + s = NULL;
45122 + KLIPS_PRINT(debug_pfkey,
45123 + "klips_debug:pfkey_remove_socket: .\n");
45124 +
45125 + cli();
45126 + s=&pfkey_sock_list;
45127 +
45128 + while(*s!=NULL) {
45129 + if(*s==sk) {
45130 + *s=sk->next;
45131 + sk->next=NULL;
45132 + sti();
45133 + KLIPS_PRINT(debug_pfkey,
45134 + "klips_debug:pfkey_remove_socket: "
45135 + "succeeded.\n");
45136 + return;
45137 + }
45138 + s=&((*s)->next);
45139 + }
45140 + sti();
45141 +
45142 + KLIPS_PRINT(debug_pfkey,
45143 + "klips_debug:pfkey_remove_socket: "
45144 + "not found.\n");
45145 + return;
45146 +}
45147 +#endif
45148 +
45149 +DEBUG_NO_STATIC void
45150 +pfkey_destroy_socket(struct sock *sk)
45151 +{
45152 + struct sk_buff *skb;
45153 +
45154 + KLIPS_PRINT(debug_pfkey,
45155 + "klips_debug:pfkey_destroy_socket: 0p%p\n",sk);
45156 + pfkey_remove_socket(sk);
45157 +
45158 + KLIPS_PRINT(debug_pfkey,
45159 + "klips_debug:pfkey_destroy_socket: "
45160 + "pfkey_remove_socket called, sk=0p%p\n",sk);
45161 +
45162 + KLIPS_PRINT(debug_pfkey,
45163 + "klips_debug:pfkey_destroy_socket: "
45164 + "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
45165 + sk,
45166 + &(sk->sk_receive_queue),
45167 + sk->sk_receive_queue.next,
45168 + sk->sk_receive_queue.prev);
45169 +
45170 + while(sk && ((skb=skb_dequeue(&(sk->sk_receive_queue)))!=NULL)) {
45171 +#ifdef CONFIG_KLIPS_DEBUG
45172 + if(debug_pfkey && sysctl_ipsec_debug_verbose) {
45173 + KLIPS_PRINT(debug_pfkey,
45174 + "klips_debug:pfkey_destroy_socket: "
45175 + "skb=0p%p dequeued.\n", skb);
45176 + printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
45177 + "pfkey_skb contents:");
45178 + printk(" next:0p%p", skb->next);
45179 + printk(" prev:0p%p", skb->prev);
45180 + printk(" sk:0p%p", skb->sk);
45181 + printk(" dev:0p%p", skb->dev);
45182 + if(skb->dev) {
45183 + if(skb->dev->name) {
45184 + printk(" dev->name:%s", skb->dev->name);
45185 + } else {
45186 + printk(" dev->name:NULL?");
45187 + }
45188 + } else {
45189 + printk(" dev:NULL");
45190 + }
45191 + printk(" h:0p%p", skb->h.raw);
45192 + printk(" nh:0p%p", skb->nh.raw);
45193 + printk(" mac:0p%p", skb->mac.raw);
45194 + printk(" dst:0p%p", skb->dst);
45195 + if(sysctl_ipsec_debug_verbose) {
45196 + int i;
45197 +
45198 + printk(" cb");
45199 + for(i=0; i<48; i++) {
45200 + printk(":%2x", skb->cb[i]);
45201 + }
45202 + }
45203 + printk(" len:%d", skb->len);
45204 + printk(" csum:%d", skb->csum);
45205 +#ifndef NETDEV_23
45206 + printk(" used:%d", skb->used);
45207 + printk(" is_clone:%d", skb->is_clone);
45208 +#endif /* NETDEV_23 */
45209 + printk(" cloned:%d", skb->cloned);
45210 + printk(" pkt_type:%d", skb->pkt_type);
45211 + printk(" ip_summed:%d", skb->ip_summed);
45212 + printk(" priority:%d", skb->priority);
45213 + printk(" protocol:%d", skb->protocol);
45214 +#ifdef HAVE_SOCK_SECURITY
45215 + printk(" security:%d", skb->security);
45216 +#endif
45217 + printk(" truesize:%d", skb->truesize);
45218 + printk(" head:0p%p", skb->head);
45219 + printk(" data:0p%p", skb->data);
45220 + printk(" tail:0p%p", skb->tail);
45221 + printk(" end:0p%p", skb->end);
45222 + if(sysctl_ipsec_debug_verbose) {
45223 + unsigned char* i;
45224 + printk(" data");
45225 + for(i = skb->head; i < skb->end; i++) {
45226 + printk(":%2x", (unsigned char)(*(i)));
45227 + }
45228 + }
45229 + printk(" destructor:0p%p", skb->destructor);
45230 + printk("\n");
45231 + }
45232 +#endif /* CONFIG_KLIPS_DEBUG */
45233 + KLIPS_PRINT(debug_pfkey,
45234 + "klips_debug:pfkey_destroy_socket: "
45235 + "skb=0p%p freed.\n",
45236 + skb);
45237 + ipsec_kfree_skb(skb);
45238 + }
45239 +
45240 +#ifdef NET_26
45241 + sock_set_flag(sk, SOCK_DEAD);
45242 +#else
45243 + sk->dead = 1;
45244 +#endif
45245 + sk_free(sk);
45246 +
45247 + KLIPS_PRINT(debug_pfkey,
45248 + "klips_debug:pfkey_destroy_socket: destroyed.\n");
45249 +}
45250 +
45251 +int
45252 +pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
45253 +{
45254 + int error = 0;
45255 + struct sk_buff * skb = NULL;
45256 + struct sock *sk;
45257 +
45258 + if(sock == NULL) {
45259 + KLIPS_PRINT(debug_pfkey,
45260 + "klips_debug:pfkey_upmsg: "
45261 + "NULL socket passed in.\n");
45262 + return -EINVAL;
45263 + }
45264 +
45265 + if(pfkey_msg == NULL) {
45266 + KLIPS_PRINT(debug_pfkey,
45267 + "klips_debug:pfkey_upmsg: "
45268 + "NULL pfkey_msg passed in.\n");
45269 + return -EINVAL;
45270 + }
45271 +
45272 + sk = sock->sk;
45273 +
45274 + if(sk == NULL) {
45275 + KLIPS_PRINT(debug_pfkey,
45276 + "klips_debug:pfkey_upmsg: "
45277 + "NULL sock passed in.\n");
45278 + return -EINVAL;
45279 + }
45280 +
45281 + KLIPS_PRINT(debug_pfkey,
45282 + "klips_debug:pfkey_upmsg: "
45283 + "allocating %d bytes...\n",
45284 + (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
45285 + if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
45286 + KLIPS_PRINT(debug_pfkey,
45287 + "klips_debug:pfkey_upmsg: "
45288 + "no buffers left to send up a message.\n");
45289 + return -ENOBUFS;
45290 + }
45291 + KLIPS_PRINT(debug_pfkey,
45292 + "klips_debug:pfkey_upmsg: "
45293 + "...allocated at 0p%p.\n",
45294 + skb);
45295 +
45296 + skb->dev = NULL;
45297 +
45298 + if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
45299 + printk(KERN_WARNING "klips_error:pfkey_upmsg: "
45300 + "tried to skb_put %ld, %d available. This should never happen, please report.\n",
45301 + (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
45302 + skb_tailroom(skb));
45303 + ipsec_kfree_skb(skb);
45304 + return -ENOBUFS;
45305 + }
45306 + skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
45307 + memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
45308 +
45309 + if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
45310 + skb->sk=NULL;
45311 + KLIPS_PRINT(debug_pfkey,
45312 + "klips_debug:pfkey_upmsg: "
45313 + "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
45314 + error,
45315 + skb);
45316 + ipsec_kfree_skb(skb);
45317 + return error;
45318 + }
45319 + return error;
45320 +}
45321 +
45322 +#ifdef NET_26_12_SKALLOC
45323 +static struct proto key_proto = {
45324 + .name = "KEY",
45325 + .owner = THIS_MODULE,
45326 + .obj_size = sizeof(struct sock),
45327 +
45328 +};
45329 +#endif
45330 +
45331 +DEBUG_NO_STATIC int
45332 +pfkey_create(struct socket *sock, int protocol)
45333 +{
45334 + struct sock *sk;
45335 +
45336 + if(sock == NULL) {
45337 + KLIPS_PRINT(debug_pfkey,
45338 + "klips_debug:pfkey_create: "
45339 + "socket NULL.\n");
45340 + return -EINVAL;
45341 + }
45342 +
45343 + KLIPS_PRINT(debug_pfkey,
45344 + "klips_debug:pfkey_create: "
45345 + "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
45346 + sock,
45347 + sock->type,
45348 + (unsigned int)(sock->state),
45349 + sock->flags, protocol);
45350 +
45351 + if(sock->type != SOCK_RAW) {
45352 + KLIPS_PRINT(debug_pfkey,
45353 + "klips_debug:pfkey_create: "
45354 + "only SOCK_RAW supported.\n");
45355 + return -ESOCKTNOSUPPORT;
45356 + }
45357 +
45358 + if(protocol != PF_KEY_V2) {
45359 + KLIPS_PRINT(debug_pfkey,
45360 + "klips_debug:pfkey_create: "
45361 + "protocol not PF_KEY_V2.\n");
45362 + return -EPROTONOSUPPORT;
45363 + }
45364 +
45365 + if((current->uid != 0)) {
45366 + KLIPS_PRINT(debug_pfkey,
45367 + "klips_debug:pfkey_create: "
45368 + "must be root to open pfkey sockets.\n");
45369 + return -EACCES;
45370 + }
45371 +
45372 + sock->state = SS_UNCONNECTED;
45373 +
45374 + KLIPS_INC_USE;
45375 +
45376 +#ifdef NET_26
45377 +#ifdef NET_26_12_SKALLOC
45378 + sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, &key_proto, 1);
45379 +#else
45380 + sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1, NULL);
45381 +#endif
45382 +#else
45383 + /* 2.4 interface */
45384 + sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1);
45385 +#endif
45386 +
45387 + if(sk == NULL)
45388 + {
45389 + KLIPS_PRINT(debug_pfkey,
45390 + "klips_debug:pfkey_create: "
45391 + "Out of memory trying to allocate.\n");
45392 + KLIPS_DEC_USE;
45393 + return -ENOMEM;
45394 + }
45395 +
45396 + sock_init_data(sock, sk);
45397 +
45398 + sk->sk_destruct = NULL;
45399 + sk->sk_reuse = 1;
45400 + sock->ops = &pfkey_ops;
45401 +
45402 + sk->sk_family = PF_KEY;
45403 +/* sk->num = protocol; */
45404 + sk->sk_protocol = protocol;
45405 + key_pid(sk) = current->pid;
45406 + KLIPS_PRINT(debug_pfkey,
45407 + "klips_debug:pfkey_create: "
45408 + "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
45409 + sock->fasync_list,
45410 + sk->sk_sleep);
45411 +
45412 + pfkey_insert_socket(sk);
45413 + pfkey_list_insert_socket(sock, &pfkey_open_sockets);
45414 +
45415 + KLIPS_PRINT(debug_pfkey,
45416 + "klips_debug:pfkey_create: "
45417 + "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
45418 + return 0;
45419 +}
45420 +
45421 +DEBUG_NO_STATIC int
45422 +#ifdef NETDEV_23
45423 +pfkey_release(struct socket *sock)
45424 +#else /* NETDEV_23 */
45425 +pfkey_release(struct socket *sock, struct socket *peersock)
45426 +#endif /* NETDEV_23 */
45427 +{
45428 + struct sock *sk;
45429 + int i;
45430 +
45431 + if(sock==NULL) {
45432 + KLIPS_PRINT(debug_pfkey,
45433 + "klips_debug:pfkey_release: "
45434 + "No socket attached.\n");
45435 + return 0; /* -EINVAL; */
45436 + }
45437 +
45438 + sk=sock->sk;
45439 +
45440 + /* May not have data attached */
45441 + if(sk==NULL) {
45442 + KLIPS_PRINT(debug_pfkey,
45443 + "klips_debug:pfkey_release: "
45444 + "No sk attached to sock=0p%p.\n", sock);
45445 + return 0; /* -EINVAL; */
45446 + }
45447 +
45448 + KLIPS_PRINT(debug_pfkey,
45449 + "klips_debug:pfkey_release: "
45450 + "sock=0p%p sk=0p%p\n", sock, sk);
45451 +
45452 + if(sock_flag(sk, SOCK_DEAD))
45453 + if(sk->sk_state_change) {
45454 + sk->sk_state_change(sk);
45455 + }
45456 +
45457 + sock->sk = NULL;
45458 +
45459 + /* Try to flush out this socket. Throw out buffers at least */
45460 + pfkey_destroy_socket(sk);
45461 + pfkey_list_remove_socket(sock, &pfkey_open_sockets);
45462 + for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
45463 + pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
45464 + }
45465 +
45466 + KLIPS_DEC_USE;
45467 + KLIPS_PRINT(debug_pfkey,
45468 + "klips_debug:pfkey_release: "
45469 + "succeeded.\n");
45470 +
45471 + return 0;
45472 +}
45473 +
45474 +DEBUG_NO_STATIC int
45475 +pfkey_shutdown(struct socket *sock, int mode)
45476 +{
45477 + struct sock *sk;
45478 +
45479 + if(sock == NULL) {
45480 + KLIPS_PRINT(debug_pfkey,
45481 + "klips_debug:pfkey_shutdown: "
45482 + "NULL socket passed in.\n");
45483 + return -EINVAL;
45484 + }
45485 +
45486 + sk=sock->sk;
45487 +
45488 + if(sk == NULL) {
45489 + KLIPS_PRINT(debug_pfkey,
45490 + "klips_debug:pfkey_shutdown: "
45491 + "No sock attached to socket.\n");
45492 + return -EINVAL;
45493 + }
45494 +
45495 + KLIPS_PRINT(debug_pfkey,
45496 + "klips_debug:pfkey_shutdown: "
45497 + "mode=%x.\n", mode);
45498 + mode++;
45499 +
45500 + if(mode&SEND_SHUTDOWN) {
45501 + sk->sk_shutdown|=SEND_SHUTDOWN;
45502 + sk->sk_state_change(sk);
45503 + }
45504 +
45505 + if(mode&RCV_SHUTDOWN) {
45506 + sk->sk_shutdown|=RCV_SHUTDOWN;
45507 + sk->sk_state_change(sk);
45508 + }
45509 + return 0;
45510 +}
45511 +
45512 +/*
45513 + * Send PF_KEY data down.
45514 + */
45515 +
45516 +DEBUG_NO_STATIC int
45517 +#ifdef NET_26
45518 +pfkey_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len)
45519 +#else
45520 +pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
45521 +#endif
45522 +{
45523 + struct sock *sk;
45524 + int error = 0;
45525 + struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
45526 +
45527 + if(sock == NULL) {
45528 + KLIPS_PRINT(debug_pfkey,
45529 + "klips_debug:pfkey_sendmsg: "
45530 + "Null socket passed in.\n");
45531 + SENDERR(EINVAL);
45532 + }
45533 +
45534 + sk = sock->sk;
45535 +
45536 + if(sk == NULL) {
45537 + KLIPS_PRINT(debug_pfkey,
45538 + "klips_debug:pfkey_sendmsg: "
45539 + "Null sock passed in.\n");
45540 + SENDERR(EINVAL);
45541 + }
45542 +
45543 + if(msg == NULL) {
45544 + KLIPS_PRINT(debug_pfkey,
45545 + "klips_debug:pfkey_sendmsg: "
45546 + "Null msghdr passed in.\n");
45547 + SENDERR(EINVAL);
45548 + }
45549 +
45550 + KLIPS_PRINT(debug_pfkey,
45551 + "klips_debug:pfkey_sendmsg: .\n");
45552 + if(sk->sk_err) {
45553 + error = sock_error(sk);
45554 + KLIPS_PRINT(debug_pfkey,
45555 + "klips_debug:pfkey_sendmsg: "
45556 + "sk->err is non-zero, returns %d.\n",
45557 + error);
45558 + SENDERR(-error);
45559 + }
45560 +
45561 + if((current->uid != 0)) {
45562 + KLIPS_PRINT(debug_pfkey,
45563 + "klips_debug:pfkey_sendmsg: "
45564 + "must be root to send messages to pfkey sockets.\n");
45565 + SENDERR(EACCES);
45566 + }
45567 +
45568 + if(msg->msg_control)
45569 + {
45570 + KLIPS_PRINT(debug_pfkey,
45571 + "klips_debug:pfkey_sendmsg: "
45572 + "can't set flags or set msg_control.\n");
45573 + SENDERR(EINVAL);
45574 + }
45575 +
45576 + if(sk->sk_shutdown & SEND_SHUTDOWN) {
45577 + KLIPS_PRINT(debug_pfkey,
45578 + "klips_debug:pfkey_sendmsg: "
45579 + "shutdown.\n");
45580 + send_sig(SIGPIPE, current, 0);
45581 + SENDERR(EPIPE);
45582 + }
45583 +
45584 + if(len < sizeof(struct sadb_msg)) {
45585 + KLIPS_PRINT(debug_pfkey,
45586 + "klips_debug:pfkey_sendmsg: "
45587 + "bogus msg len of %d, too small.\n", (int)len);
45588 + SENDERR(EMSGSIZE);
45589 + }
45590 +
45591 + KLIPS_PRINT(debug_pfkey,
45592 + "klips_debug:pfkey_sendmsg: "
45593 + "allocating %d bytes for downward message.\n",
45594 + (int)len);
45595 + if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
45596 + KLIPS_PRINT(debug_pfkey,
45597 + "klips_debug:pfkey_sendmsg: "
45598 + "memory allocation error.\n");
45599 + SENDERR(ENOBUFS);
45600 + }
45601 +
45602 + memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
45603 +
45604 + if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
45605 + KLIPS_PRINT(1 || debug_pfkey,
45606 + "klips_debug:pfkey_sendmsg: "
45607 + "not PF_KEY_V2 msg, found %d, should be %d.\n",
45608 + pfkey_msg->sadb_msg_version,
45609 + PF_KEY_V2);
45610 + kfree((void*)pfkey_msg);
45611 + return -EINVAL;
45612 + }
45613 +
45614 + if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
45615 + KLIPS_PRINT(debug_pfkey,
45616 + "klips_debug:pfkey_sendmsg: "
45617 + "bogus msg len of %d, not %d byte aligned.\n",
45618 + (int)len, (int)IPSEC_PFKEYv2_ALIGN);
45619 + SENDERR(EMSGSIZE);
45620 + }
45621 +
45622 +#if 0
45623 + /* This check is questionable, since a downward message could be
45624 + the result of an ACQUIRE either from kernel (PID==0) or
45625 + userspace (some other PID). */
45626 + /* check PID */
45627 + if(pfkey_msg->sadb_msg_pid != current->pid) {
45628 + KLIPS_PRINT(debug_pfkey,
45629 + "klips_debug:pfkey_sendmsg: "
45630 + "pid (%d) does not equal sending process pid (%d).\n",
45631 + pfkey_msg->sadb_msg_pid, current->pid);
45632 + SENDERR(EINVAL);
45633 + }
45634 +#endif
45635 +
45636 + if(pfkey_msg->sadb_msg_reserved) {
45637 + KLIPS_PRINT(debug_pfkey,
45638 + "klips_debug:pfkey_sendmsg: "
45639 + "reserved field must be zero, set to %d.\n",
45640 + pfkey_msg->sadb_msg_reserved);
45641 + SENDERR(EINVAL);
45642 + }
45643 +
45644 + if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
45645 + KLIPS_PRINT(debug_pfkey,
45646 + "klips_debug:pfkey_sendmsg: "
45647 + "msg type too large or small:%d.\n",
45648 + pfkey_msg->sadb_msg_type);
45649 + SENDERR(EINVAL);
45650 + }
45651 +
45652 + KLIPS_PRINT(debug_pfkey,
45653 + "klips_debug:pfkey_sendmsg: "
45654 + "msg sent for parsing.\n");
45655 +
45656 + if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
45657 + struct socket_list *pfkey_socketsp;
45658 +
45659 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45660 + "pfkey_msg_parse returns %d.\n",
45661 + error);
45662 +
45663 + if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
45664 + KLIPS_PRINT(debug_pfkey,
45665 + "klips_debug:pfkey_sendmsg: "
45666 + "memory allocation error.\n");
45667 + SENDERR(ENOBUFS);
45668 + }
45669 + memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
45670 + pfkey_reply->sadb_msg_errno = -error;
45671 + pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
45672 +
45673 + for(pfkey_socketsp = pfkey_open_sockets;
45674 + pfkey_socketsp;
45675 + pfkey_socketsp = pfkey_socketsp->next) {
45676 + int error_upmsg = 0;
45677 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45678 + "sending up error=%d message=0p%p to socket=0p%p.\n",
45679 + error,
45680 + pfkey_reply,
45681 + pfkey_socketsp->socketp);
45682 + if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
45683 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45684 + "sending up error message to socket=0p%p failed with error=%d.\n",
45685 + pfkey_socketsp->socketp,
45686 + error_upmsg);
45687 + /* pfkey_msg_free(&pfkey_reply); */
45688 + /* SENDERR(-error); */
45689 + }
45690 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
45691 + "sending up error message to socket=0p%p succeeded.\n",
45692 + pfkey_socketsp->socketp);
45693 + }
45694 +
45695 + pfkey_msg_free(&pfkey_reply);
45696 +
45697 + SENDERR(-error);
45698 + }
45699 +
45700 + errlab:
45701 + if (pfkey_msg) {
45702 + kfree((void*)pfkey_msg);
45703 + }
45704 +
45705 + if(error) {
45706 + return error;
45707 + } else {
45708 + return len;
45709 + }
45710 +}
45711 +
45712 +/*
45713 + * Receive PF_KEY data up.
45714 + */
45715 +
45716 +DEBUG_NO_STATIC int
45717 +#ifdef NET_26
45718 +pfkey_recvmsg(struct kiocb *kiocb
45719 + , struct socket *sock
45720 + , struct msghdr *msg
45721 + , size_t size
45722 + , int flags)
45723 +#else
45724 +pfkey_recvmsg(struct socket *sock
45725 + , struct msghdr *msg
45726 + , int size, int flags
45727 + , struct scm_cookie *scm)
45728 +#endif
45729 +{
45730 + struct sock *sk;
45731 + int noblock = flags & MSG_DONTWAIT;
45732 + struct sk_buff *skb;
45733 + int error;
45734 +
45735 + if(sock == NULL) {
45736 + KLIPS_PRINT(debug_pfkey,
45737 + "klips_debug:pfkey_recvmsg: "
45738 + "Null socket passed in.\n");
45739 + return -EINVAL;
45740 + }
45741 +
45742 + sk = sock->sk;
45743 +
45744 + if(sk == NULL) {
45745 + KLIPS_PRINT(debug_pfkey,
45746 + "klips_debug:pfkey_recvmsg: "
45747 + "Null sock passed in for sock=0p%p.\n", sock);
45748 + return -EINVAL;
45749 + }
45750 +
45751 + if(msg == NULL) {
45752 + KLIPS_PRINT(debug_pfkey,
45753 + "klips_debug:pfkey_recvmsg: "
45754 + "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
45755 + sock, sk);
45756 + return -EINVAL;
45757 + }
45758 +
45759 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
45760 + "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
45761 + sock, sk, msg, (int)size);
45762 + if(flags & ~MSG_PEEK) {
45763 + KLIPS_PRINT(debug_pfkey,
45764 + "klips_debug:pfkey_sendmsg: "
45765 + "flags (%d) other than MSG_PEEK not supported.\n",
45766 + flags);
45767 + return -EOPNOTSUPP;
45768 + }
45769 +
45770 + msg->msg_namelen = 0; /* sizeof(*ska); */
45771 +
45772 + if(sk->sk_err) {
45773 + KLIPS_PRINT(debug_pfkey,
45774 + "klips_debug:pfkey_sendmsg: "
45775 + "sk->sk_err=%d.\n", sk->sk_err);
45776 + return sock_error(sk);
45777 + }
45778 +
45779 + if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
45780 + return error;
45781 + }
45782 +
45783 + if(size > skb->len) {
45784 + size = skb->len;
45785 + }
45786 + else if(size <skb->len) {
45787 + msg->msg_flags |= MSG_TRUNC;
45788 + }
45789 +
45790 + skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
45791 +#ifdef HAVE_TSTAMP
45792 + sk->sk_stamp.tv_sec = skb->tstamp.off_sec;
45793 + sk->sk_stamp.tv_usec = skb->tstamp.off_usec;
45794 +#else
45795 + sk->sk_stamp=skb->stamp;
45796 +#endif
45797 +
45798 + skb_free_datagram(sk, skb);
45799 + return size;
45800 +}
45801 +
45802 +#ifdef CONFIG_PROC_FS
45803 +#ifndef PROC_FS_2325
45804 +DEBUG_NO_STATIC
45805 +#endif /* PROC_FS_2325 */
45806 +int
45807 +pfkey_get_info(char *buffer, char **start, off_t offset, int length
45808 +#ifndef PROC_NO_DUMMY
45809 +, int dummy
45810 +#endif /* !PROC_NO_DUMMY */
45811 +)
45812 +{
45813 + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
45814 +#ifdef NET_26
45815 + struct hlist_node *node;
45816 +#endif
45817 + off_t begin=0;
45818 + int len=0;
45819 + struct sock *sk;
45820 +
45821 +#ifdef CONFIG_KLIPS_DEBUG
45822 + if(!sysctl_ipsec_debug_verbose) {
45823 +#endif /* CONFIG_KLIPS_DEBUG */
45824 + len += ipsec_snprintf(buffer, length,
45825 + " sock pid socket next prev e n p sndbf Flags Type St\n");
45826 +#ifdef CONFIG_KLIPS_DEBUG
45827 + } else {
45828 + len += ipsec_snprintf(buffer, length,
45829 + " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
45830 + }
45831 +#endif /* CONFIG_KLIPS_DEBUG */
45832 +
45833 + sk_for_each(sk, node, &pfkey_sock_list) {
45834 +
45835 +#ifdef CONFIG_KLIPS_DEBUG
45836 + if(!sysctl_ipsec_debug_verbose) {
45837 +#endif /* CONFIG_KLIPS_DEBUG */
45838 + len += ipsec_snprintf(buffer+len, length-len,
45839 + "%8p %5d %8p %d %d %5d %08lX %8X %2X\n",
45840 + sk,
45841 + key_pid(sk),
45842 + sk->sk_socket,
45843 + sk->sk_err,
45844 + sk->sk_protocol,
45845 + sk->sk_sndbuf,
45846 + sk->sk_socket->flags,
45847 + sk->sk_socket->type,
45848 + sk->sk_socket->state);
45849 +#ifdef CONFIG_KLIPS_DEBUG
45850 + } else {
45851 + len += ipsec_snprintf(buffer+len, length-len,
45852 + "%8p %5d %d %8p %8p %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
45853 + sk,
45854 + key_pid(sk),
45855 + sock_flag(sk, SOCK_DEAD),
45856 + sk->sk_sleep,
45857 + sk->sk_socket,
45858 + sk->sk_err,
45859 + sk->sk_reuse,
45860 +#ifdef HAVE_SOCK_ZAPPED
45861 + sock_flag(sk, SOCK_ZAPPED),
45862 +#else
45863 + sk->sk_zapped,
45864 +#endif
45865 + sk->sk_protocol,
45866 + sk->sk_sndbuf,
45867 + (unsigned int)sk->sk_stamp.tv_sec,
45868 + (unsigned int)sk->sk_stamp.tv_usec,
45869 + sk->sk_socket->flags,
45870 + sk->sk_socket->type,
45871 + sk->sk_socket->state);
45872 + }
45873 +#endif /* CONFIG_KLIPS_DEBUG */
45874 +
45875 + if (len >= max_content) {
45876 + /* we've done all that can fit -- stop loop */
45877 + len = max_content; /* truncate crap */
45878 + break;
45879 + } else {
45880 + const off_t pos = begin + len; /* file position of end of what we've generated */
45881 +
45882 + if (pos <= offset) {
45883 + /* all is before first interesting character:
45884 + * discard, but note where we are.
45885 + */
45886 + len = 0;
45887 + begin = pos;
45888 + }
45889 + }
45890 + }
45891 +
45892 + *start = buffer + (offset - begin); /* Start of wanted data */
45893 + return len - (offset - begin);
45894 +}
45895 +
45896 +#ifndef PROC_FS_2325
45897 +DEBUG_NO_STATIC
45898 +#endif /* PROC_FS_2325 */
45899 +int
45900 +pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
45901 +#ifndef PROC_NO_DUMMY
45902 +, int dummy
45903 +#endif /* !PROC_NO_DUMMY */
45904 +)
45905 +{
45906 + /* limit of useful snprintf output */
45907 + const int max_content = length > 0? length-1 : 0;
45908 + off_t begin=0;
45909 + int len=0;
45910 + int satype;
45911 + struct supported_list *ps;
45912 +
45913 + len += ipsec_snprintf(buffer, length,
45914 + "satype exttype alg_id ivlen minbits maxbits name\n");
45915 +
45916 + for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
45917 + ps = pfkey_supported_list[satype];
45918 + while(ps) {
45919 + struct ipsec_alg_supported *alg = ps->supportedp;
45920 + unsigned char *n = alg->ias_name;
45921 + if(n == NULL) n = "unknown";
45922 +
45923 + len += ipsec_snprintf(buffer+len, length-len,
45924 + " %2d %2d %2d %3d %3d %3d %20s\n",
45925 + satype,
45926 + alg->ias_exttype,
45927 + alg->ias_id,
45928 + alg->ias_ivlen,
45929 + alg->ias_keyminbits,
45930 + alg->ias_keymaxbits,
45931 + n);
45932 +
45933 + if (len >= max_content) {
45934 + /* we've done all that can fit -- stop loop */
45935 + len = max_content; /* truncate crap */
45936 + break;
45937 + } else {
45938 + const off_t pos = begin + len; /* file position of end of what we've generated */
45939 +
45940 + if (pos <= offset) {
45941 + /* all is before first interesting character:
45942 + * discard, but note where we are.
45943 + */
45944 + len = 0;
45945 + begin = pos;
45946 + }
45947 + }
45948 +
45949 + ps = ps->next;
45950 + }
45951 + }
45952 + *start = buffer + (offset - begin); /* Start of wanted data */
45953 + return len - (offset - begin);
45954 +}
45955 +
45956 +#ifndef PROC_FS_2325
45957 +DEBUG_NO_STATIC
45958 +#endif /* PROC_FS_2325 */
45959 +int
45960 +pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
45961 +#ifndef PROC_NO_DUMMY
45962 +, int dummy
45963 +#endif /* !PROC_NO_DUMMY */
45964 +)
45965 +{
45966 + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */
45967 + off_t begin=0;
45968 + int len=0;
45969 + int satype;
45970 + struct socket_list *pfkey_sockets;
45971 +
45972 + len += ipsec_snprintf(buffer, length,
45973 + "satype socket pid sk\n");
45974 +
45975 + for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
45976 + pfkey_sockets = pfkey_registered_sockets[satype];
45977 + while(pfkey_sockets) {
45978 + len += ipsec_snprintf(buffer+len, length-len,
45979 + " %2d %8p %5d %8p\n",
45980 + satype,
45981 + pfkey_sockets->socketp,
45982 + key_pid(pfkey_sockets->socketp->sk),
45983 + pfkey_sockets->socketp->sk);
45984 +
45985 + if (len >= max_content) {
45986 + /* we've done all that can fit -- stop loop (could stop two) */
45987 + len = max_content; /* truncate crap */
45988 + break;
45989 + } else {
45990 + const off_t pos = begin + len; /* file position of end of what we've generated */
45991 +
45992 + if (pos <= offset) {
45993 + /* all is before first interesting character:
45994 + * discard, but note where we are.
45995 + */
45996 + len = 0;
45997 + begin = pos;
45998 + }
45999 + }
46000 +
46001 + pfkey_sockets = pfkey_sockets->next;
46002 + }
46003 + }
46004 + *start = buffer + (offset - begin); /* Start of wanted data */
46005 + return len - (offset - begin);
46006 +}
46007 +
46008 +#ifndef PROC_FS_2325
46009 +struct proc_dir_entry proc_net_pfkey =
46010 +{
46011 + 0,
46012 + 6, "pf_key",
46013 + S_IFREG | S_IRUGO, 1, 0, 0,
46014 + 0, &proc_net_inode_operations,
46015 + pfkey_get_info
46016 +};
46017 +struct proc_dir_entry proc_net_pfkey_supported =
46018 +{
46019 + 0,
46020 + 16, "pf_key_supported",
46021 + S_IFREG | S_IRUGO, 1, 0, 0,
46022 + 0, &proc_net_inode_operations,
46023 + pfkey_supported_get_info
46024 +};
46025 +struct proc_dir_entry proc_net_pfkey_registered =
46026 +{
46027 + 0,
46028 + 17, "pf_key_registered",
46029 + S_IFREG | S_IRUGO, 1, 0, 0,
46030 + 0, &proc_net_inode_operations,
46031 + pfkey_registered_get_info
46032 +};
46033 +#endif /* !PROC_FS_2325 */
46034 +#endif /* CONFIG_PROC_FS */
46035 +
46036 +DEBUG_NO_STATIC int
46037 +supported_add_all(int satype, struct ipsec_alg_supported supported[], int size)
46038 +{
46039 + int i;
46040 + int error = 0;
46041 +
46042 + KLIPS_PRINT(debug_pfkey,
46043 + "klips_debug:init_pfkey: "
46044 + "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct ipsec_alg_supported)[%d]=%d.\n",
46045 + satype,
46046 + size,
46047 + (int)sizeof(struct ipsec_alg_supported),
46048 + (int)(size/sizeof(struct ipsec_alg_supported)));
46049 +
46050 + for(i = 0; i < size / sizeof(struct ipsec_alg_supported); i++) {
46051 +
46052 + unsigned char *n = supported[i].ias_name;
46053 + if(n == NULL) n="unknown";
46054 +
46055 + KLIPS_PRINT(debug_pfkey,
46056 + "klips_debug:init_pfkey: "
46057 + "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
46058 + i,
46059 + satype,
46060 + supported[i].ias_exttype,
46061 + supported[i].ias_id,
46062 + supported[i].ias_ivlen,
46063 + supported[i].ias_keyminbits,
46064 + supported[i].ias_keymaxbits,
46065 + n);
46066 +
46067 + error |= pfkey_list_insert_supported(&(supported[i]),
46068 + &(pfkey_supported_list[satype]));
46069 + }
46070 + return error;
46071 +}
46072 +
46073 +DEBUG_NO_STATIC int
46074 +supported_remove_all(int satype)
46075 +{
46076 + int error = 0;
46077 + struct ipsec_alg_supported*supportedp;
46078 +
46079 + while(pfkey_supported_list[satype]) {
46080 + unsigned char *n;
46081 + supportedp = pfkey_supported_list[satype]->supportedp;
46082 +
46083 + n = supportedp->ias_name;
46084 + if(n == NULL) n="unknown";
46085 +
46086 + KLIPS_PRINT(debug_pfkey,
46087 + "klips_debug:init_pfkey: "
46088 + "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d name=%s.\n",
46089 + satype,
46090 + supportedp->ias_exttype,
46091 + supportedp->ias_id,
46092 + supportedp->ias_ivlen,
46093 + supportedp->ias_keyminbits,
46094 + supportedp->ias_keymaxbits, n);
46095 +
46096 + error |= pfkey_list_remove_supported(supportedp,
46097 + &(pfkey_supported_list[satype]));
46098 + }
46099 + return error;
46100 +}
46101 +
46102 +int
46103 +pfkey_init(void)
46104 +{
46105 + int error = 0;
46106 + int i;
46107 +
46108 + static struct ipsec_alg_supported supported_init_ah[] = {
46109 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
46110 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
46111 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
46112 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
46113 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
46114 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
46115 + };
46116 + static struct ipsec_alg_supported supported_init_esp[] = {
46117 +#ifdef CONFIG_KLIPS_AUTH_HMAC_MD5
46118 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
46119 +#endif /* CONFIG_KLIPS_AUTH_HMAC_MD5 */
46120 +#ifdef CONFIG_KLIPS_AUTH_HMAC_SHA1
46121 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
46122 +#endif /* CONFIG_KLIPS_AUTH_HMAC_SHA1 */
46123 +#ifdef CONFIG_KLIPS_ENC_3DES
46124 + {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168},
46125 +#endif /* CONFIG_KLIPS_ENC_3DES */
46126 + };
46127 + static struct ipsec_alg_supported supported_init_ipip[] = {
46128 + {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
46129 +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
46130 + , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
46131 + , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
46132 + , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
46133 +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
46134 + };
46135 +#ifdef CONFIG_KLIPS_IPCOMP
46136 + static struct ipsec_alg_supported supported_init_ipcomp[] = {
46137 + {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
46138 + };
46139 +#endif /* CONFIG_KLIPS_IPCOMP */
46140 +
46141 +#if 0
46142 + printk(KERN_INFO
46143 + "klips_info:pfkey_init: "
46144 + "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
46145 +#endif
46146 +
46147 + for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
46148 + pfkey_registered_sockets[i] = NULL;
46149 + pfkey_supported_list[i] = NULL;
46150 + }
46151 +
46152 + error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
46153 + error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
46154 +#ifdef CONFIG_KLIPS_IPCOMP
46155 + error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
46156 +#endif /* CONFIG_KLIPS_IPCOMP */
46157 + error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
46158 +
46159 + error |= sock_register(&pfkey_family_ops);
46160 +
46161 +#ifdef CONFIG_PROC_FS
46162 +# ifndef PROC_FS_2325
46163 +# ifdef PROC_FS_21
46164 + error |= proc_register(proc_net, &proc_net_pfkey);
46165 + error |= proc_register(proc_net, &proc_net_pfkey_supported);
46166 + error |= proc_register(proc_net, &proc_net_pfkey_registered);
46167 +# else /* PROC_FS_21 */
46168 + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
46169 + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
46170 + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
46171 +# endif /* PROC_FS_21 */
46172 +# else /* !PROC_FS_2325 */
46173 + proc_net_create ("pf_key", 0, pfkey_get_info);
46174 + proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
46175 + proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
46176 +# endif /* !PROC_FS_2325 */
46177 +#endif /* CONFIG_PROC_FS */
46178 +
46179 + return error;
46180 +}
46181 +
46182 +int
46183 +pfkey_cleanup(void)
46184 +{
46185 + int error = 0;
46186 +
46187 + printk(KERN_INFO "klips_info:pfkey_cleanup: "
46188 + "shutting down PF_KEY domain sockets.\n");
46189 + sock_unregister(PF_KEY);
46190 +
46191 + error |= supported_remove_all(SADB_SATYPE_AH);
46192 + error |= supported_remove_all(SADB_SATYPE_ESP);
46193 +#ifdef CONFIG_KLIPS_IPCOMP
46194 + error |= supported_remove_all(SADB_X_SATYPE_COMP);
46195 +#endif /* CONFIG_KLIPS_IPCOMP */
46196 + error |= supported_remove_all(SADB_X_SATYPE_IPIP);
46197 +
46198 +#ifdef CONFIG_PROC_FS
46199 +# ifndef PROC_FS_2325
46200 + if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
46201 + printk("klips_debug:pfkey_cleanup: "
46202 + "cannot unregister /proc/net/pf_key\n");
46203 + if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
46204 + printk("klips_debug:pfkey_cleanup: "
46205 + "cannot unregister /proc/net/pf_key_supported\n");
46206 + if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
46207 + printk("klips_debug:pfkey_cleanup: "
46208 + "cannot unregister /proc/net/pf_key_registered\n");
46209 +# else /* !PROC_FS_2325 */
46210 + proc_net_remove ("pf_key");
46211 + proc_net_remove ("pf_key_supported");
46212 + proc_net_remove ("pf_key_registered");
46213 +# endif /* !PROC_FS_2325 */
46214 +#endif /* CONFIG_PROC_FS */
46215 +
46216 + /* other module unloading cleanup happens here */
46217 + return error;
46218 +}
46219 +
46220 +#ifdef MODULE
46221 +#if 0
46222 +int
46223 +init_module(void)
46224 +{
46225 + pfkey_init();
46226 + return 0;
46227 +}
46228 +
46229 +void
46230 +cleanup_module(void)
46231 +{
46232 + pfkey_cleanup();
46233 +}
46234 +#endif /* 0 */
46235 +#else /* MODULE */
46236 +struct net_protocol;
46237 +void pfkey_proto_init(struct net_protocol *pro)
46238 +{
46239 + pfkey_init();
46240 +}
46241 +#endif /* MODULE */
46242 +
46243 +/*
46244 + * $Log: pfkey_v2.c,v $
46245 + * Revision 1.97.2.12 2006/11/24 05:43:29 paul
46246 + * kernels after 2.6.18 do not return a code from unregister_socket()
46247 + * backport from git 41e54a2684dc809d7952e816860ea646a3194a72
46248 + *
46249 + * Revision 1.97.2.11 2006/11/15 16:05:57 paul
46250 + * fix for compiling on 2.4. kernels by Matthias Haas.
46251 + *
46252 + * Revision 1.97.2.10 2006/10/10 20:43:28 paul
46253 + * Add family/create/owner for pfkey_family_ops. This fixes bug #671
46254 + *
46255 + * Revision 1.97.2.9 2006/10/06 21:39:26 paul
46256 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
46257 + * set. This is defined through autoconf.h which is included through the
46258 + * linux kernel build macros.
46259 + *
46260 + * Revision 1.97.2.8 2006/07/10 15:56:11 paul
46261 + * Fix for bug #642 by Bart.
46262 + *
46263 + * Revision 1.97.2.7 2006/04/04 11:34:19 ken
46264 + * Backport SMP fixes + #ifdef cleanup from #public
46265 + *
46266 + * Revision 1.97.2.6 2006/02/15 05:00:20 paul
46267 + * Fix for crasher on 2.6.12+ with klips (mostly seen on redhat kernels)
46268 + *
46269 + * Revision 1.97.2.5 2005/11/22 04:11:52 ken
46270 + * Backport fixes for 2.6.14 kernels from HEAD
46271 + *
46272 + * Revision 1.97.2.4 2005/09/14 16:40:45 mcr
46273 + * pull up of compilation on 2.4
46274 + *
46275 + * Revision 1.97.2.3 2005/09/06 02:10:03 mcr
46276 + * pulled up possible SMP-related compilation fix
46277 + *
46278 + * Revision 1.97.2.2 2005/08/28 01:21:12 paul
46279 + * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on
46280 + * SMP kernels.
46281 + *
46282 + * Revision 1.97.2.1 2005/08/27 23:40:00 paul
46283 + * recommited HAVE_SOCK_SECURITY fixes for linux 2.6.13
46284 + *
46285 + * Revision 1.102 2005/09/14 16:37:23 mcr
46286 + * fix to compile on 2.4.
46287 + *
46288 + * Revision 1.101 2005/09/06 01:42:25 mcr
46289 + * removed additional SOCKOPS_WRAPPED code
46290 + *
46291 + * Revision 1.100 2005/08/30 18:10:15 mcr
46292 + * remove SOCKOPS_WRAPPED() code, add proper locking to the
46293 + * pfkey code. (cross fingers)
46294 + *
46295 + * Revision 1.99 2005/08/28 01:53:37 paul
46296 + * Undid Ken's gcc4 fix in version 1.94 since it breaks linking KLIPS on SMP kernels.
46297 + *
46298 + * Revision 1.98 2005/08/27 23:07:21 paul
46299 + * Somewhere between 2.6.12 and 2.6.13rc7 the unused security memnber in sk_buff
46300 + * has been removed. This patch should fix compilation for both cases.
46301 + *
46302 + * Revision 1.97 2005/07/20 00:33:36 mcr
46303 + * fixed typo in #ifdef for SKALLOC.
46304 + *
46305 + * Revision 1.96 2005/07/19 20:02:15 mcr
46306 + * sk_alloc() interface change.
46307 + *
46308 + * Revision 1.95 2005/07/09 00:40:06 ken
46309 + * Fix for GCC4 - it doesn't like the potential for duplicate declaration
46310 + *
46311 + * Revision 1.94 2005/07/09 00:14:04 ken
46312 + * Casts for 64bit cleanliness
46313 + *
46314 + * Revision 1.93 2005/07/08 16:20:05 mcr
46315 + * fix for 2.6.12 disapperance of sk_zapped field -> sock_flags.
46316 + *
46317 + * Revision 1.92 2005/05/21 03:29:39 mcr
46318 + * fixed missing prototype definition.
46319 + *
46320 + * Revision 1.91 2005/05/11 01:43:45 mcr
46321 + * removed "poor-man"s OOP in favour of proper C structures.
46322 + *
46323 + * Revision 1.90 2005/05/02 18:42:47 mcr
46324 + * fix for cut&paste error with pfkey_v2.c "supported_name"
46325 + *
46326 + * Revision 1.89 2005/05/01 03:12:31 mcr
46327 + * print name if it is available.
46328 + *
46329 + * Revision 1.88 2005/04/29 05:10:22 mcr
46330 + * removed from extraenous includes to make unit testing easier.
46331 + *
46332 + * Revision 1.87 2005/04/15 19:57:10 mcr
46333 + * make sure that address has 0p so that it will
46334 + * sanitized.
46335 + *
46336 + * Revision 1.86 2005/04/08 18:28:36 mcr
46337 + * some minor #ifdef simplification in pursuit of a possible bug.
46338 + *
46339 + * Revision 1.85 2004/12/03 21:25:57 mcr
46340 + * compile time fixes for running on 2.6.
46341 + * still experimental.
46342 + *
46343 + * Revision 1.84 2004/08/17 03:27:23 mcr
46344 + * klips 2.6 edits.
46345 + *
46346 + * Revision 1.83 2004/08/04 15:57:07 mcr
46347 + * moved des .h files to include/des/ *
46348 + * included 2.6 protocol specific things
46349 + * started at NAT-T support, but it will require a kernel patch.
46350 + *
46351 + * Revision 1.82 2004/07/10 19:11:18 mcr
46352 + * CONFIG_IPSEC -> CONFIG_KLIPS.
46353 + *
46354 + * Revision 1.81 2004/04/25 21:23:11 ken
46355 + * Pull in dhr's changes from FreeS/WAN 2.06
46356 + *
46357 + * Revision 1.80 2004/04/06 02:49:26 mcr
46358 + * pullup of algo code from alg-branch.
46359 + *
46360 + * Revision 1.79.4.1 2003/12/22 15:25:52 jjo
46361 + * . Merged algo-0.8.1-rc11-test1 into alg-branch
46362 + *
46363 + * Revision 1.79 2003/10/31 02:27:55 mcr
46364 + * pulled up port-selector patches and sa_id elimination.
46365 + *
46366 + * Revision 1.78.4.1 2003/10/29 01:30:41 mcr
46367 + * elimited "struct sa_id".
46368 + *
46369 + * Revision 1.78 2003/04/03 17:38:09 rgb
46370 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
46371 + *
46372 + * Revision 1.77 2002/10/17 16:49:36 mcr
46373 + * sock->ops should reference the unwrapped options so that
46374 + * we get hacked in locking on SMP systems.
46375 + *
46376 + * Revision 1.76 2002/10/12 23:11:53 dhr
46377 + *
46378 + * [KenB + DHR] more 64-bit cleanup
46379 + *
46380 + * Revision 1.75 2002/09/20 05:01:57 rgb
46381 + * Added memory allocation debugging.
46382 + *
46383 + * Revision 1.74 2002/09/19 02:42:50 mcr
46384 + * do not define the pfkey_ops function for now.
46385 + *
46386 + * Revision 1.73 2002/09/17 17:29:23 mcr
46387 + * #if 0 out some dead code - pfkey_ops is never used as written.
46388 + *
46389 + * Revision 1.72 2002/07/24 18:44:54 rgb
46390 + * Type fiddling to tame ia64 compiler.
46391 + *
46392 + * Revision 1.71 2002/05/23 07:14:11 rgb
46393 + * Cleaned up %p variants to 0p%p for test suite cleanup.
46394 + *
46395 + * Revision 1.70 2002/04/24 07:55:32 mcr
46396 + * #include patches and Makefiles for post-reorg compilation.
46397 + *
46398 + * Revision 1.69 2002/04/24 07:36:33 mcr
46399 + * Moved from ./klips/net/ipsec/pfkey_v2.c,v
46400 + *
46401 + * Revision 1.68 2002/03/08 01:15:17 mcr
46402 + * put some internal structure only debug messages behind
46403 + * && sysctl_ipsec_debug_verbose.
46404 + *
46405 + * Revision 1.67 2002/01/29 17:17:57 mcr
46406 + * moved include of ipsec_param.h to after include of linux/kernel.h
46407 + * otherwise, it seems that some option that is set in ipsec_param.h
46408 + * screws up something subtle in the include path to kernel.h, and
46409 + * it complains on the snprintf() prototype.
46410 + *
46411 + * Revision 1.66 2002/01/29 04:00:54 mcr
46412 + * more excise of kversions.h header.
46413 + *
46414 + * Revision 1.65 2002/01/29 02:13:18 mcr
46415 + * introduction of ipsec_kversion.h means that include of
46416 + * ipsec_param.h must preceed any decisions about what files to
46417 + * include to deal with differences in kernel source.
46418 + *
46419 + * Revision 1.64 2001/11/26 09:23:51 rgb
46420 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
46421 + *
46422 + * Revision 1.61.2.1 2001/09/25 02:28:44 mcr
46423 + * cleaned up includes.
46424 + *
46425 + * Revision 1.63 2001/11/12 19:38:00 rgb
46426 + * Continue trying other sockets even if one fails and return only original
46427 + * error.
46428 + *
46429 + * Revision 1.62 2001/10/18 04:45:22 rgb
46430 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
46431 + * lib/freeswan.h version macros moved to lib/kversions.h.
46432 + * Other compiler directive cleanups.
46433 + *
46434 + * Revision 1.61 2001/09/20 15:32:59 rgb
46435 + * Min/max cleanup.
46436 + *
46437 + * Revision 1.60 2001/06/14 19:35:12 rgb
46438 + * Update copyright date.
46439 + *
46440 + * Revision 1.59 2001/06/13 15:35:48 rgb
46441 + * Fixed #endif comments.
46442 + *
46443 + * Revision 1.58 2001/05/04 16:37:24 rgb
46444 + * Remove erroneous checking of return codes for proc_net_* in 2.4.
46445 + *
46446 + * Revision 1.57 2001/05/03 19:43:36 rgb
46447 + * Initialise error return variable.
46448 + * Check error return codes in startup and shutdown.
46449 + * Standardise on SENDERR() macro.
46450 + *
46451 + * Revision 1.56 2001/04/21 23:05:07 rgb
46452 + * Define out skb->used for 2.4 kernels.
46453 + *
46454 + * Revision 1.55 2001/02/28 05:03:28 rgb
46455 + * Clean up and rationalise startup messages.
46456 + *
46457 + * Revision 1.54 2001/02/27 22:24:55 rgb
46458 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
46459 + * Check for satoa() return codes.
46460 + *
46461 + * Revision 1.53 2001/02/27 06:48:18 rgb
46462 + * Fixed pfkey socket unregister log message to reflect type and function.
46463 + *
46464 + * Revision 1.52 2001/02/26 22:34:38 rgb
46465 + * Fix error return code that was getting overwritten by the error return
46466 + * code of an upmsg.
46467 + *
46468 + * Revision 1.51 2001/01/30 23:42:47 rgb
46469 + * Allow pfkey msgs from pid other than user context required for ACQUIRE
46470 + * and subsequent ADD or UDATE.
46471 + *
46472 + * Revision 1.50 2001/01/23 20:22:59 rgb
46473 + * 2.4 fix to remove removed is_clone member.
46474 + *
46475 + * Revision 1.49 2000/11/06 04:33:47 rgb
46476 + * Changed non-exported functions to DEBUG_NO_STATIC.
46477 + *
46478 + * Revision 1.48 2000/09/29 19:47:41 rgb
46479 + * Update copyright.
46480 + *
46481 + * Revision 1.47 2000/09/22 04:23:04 rgb
46482 + * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
46483 + *
46484 + * Revision 1.46 2000/09/21 04:20:44 rgb
46485 + * Fixed array size off-by-one error. (Thanks Svenning!)
46486 + *
46487 + * Revision 1.45 2000/09/20 04:01:26 rgb
46488 + * Changed static functions to DEBUG_NO_STATIC for revealing function names
46489 + * in oopsen.
46490 + *
46491 + * Revision 1.44 2000/09/19 00:33:17 rgb
46492 + * 2.0 fixes.
46493 + *
46494 + * Revision 1.43 2000/09/16 01:28:13 rgb
46495 + * Fixed use of 0 in p format warning.
46496 + *
46497 + * Revision 1.42 2000/09/16 01:09:41 rgb
46498 + * Fixed debug format warning for pointers that was expecting ints.
46499 + *
46500 + * Revision 1.41 2000/09/13 15:54:00 rgb
46501 + * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
46502 + * Moved supported algos add and remove to functions.
46503 + *
46504 + * Revision 1.40 2000/09/12 18:49:28 rgb
46505 + * Added IPIP tunnel and IPCOMP register support.
46506 + *
46507 + * Revision 1.39 2000/09/12 03:23:49 rgb
46508 + * Converted #if0 debugs to sysctl.
46509 + * Removed debug_pfkey initialisations that prevented no_debug loading or
46510 + * linking.
46511 + *
46512 + * Revision 1.38 2000/09/09 06:38:02 rgb
46513 + * Return positive errno in pfkey_reply error message.
46514 + *
46515 + * Revision 1.37 2000/09/08 19:19:09 rgb
46516 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
46517 + * Clean-up of long-unused crud...
46518 + * Create pfkey error message on on failure.
46519 + * Give pfkey_list_{insert,remove}_{socket,supported}() some error
46520 + * checking.
46521 + *
46522 + * Revision 1.36 2000/09/01 18:49:38 rgb
46523 + * Reap experimental NET_21_ bits.
46524 + * Turned registered sockets list into an array of one list per satype.
46525 + * Remove references to deprecated sklist_{insert,remove}_socket.
46526 + * Removed leaking socket debugging code.
46527 + * Removed duplicate pfkey_insert_socket in pfkey_create.
46528 + * Removed all references to pfkey msg->msg_name, since it is not used for
46529 + * pfkey.
46530 + * Added a supported algorithms array lists, one per satype and registered
46531 + * existing algorithms.
46532 + * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
46533 + * list.
46534 + * Only send pfkey_expire() messages to sockets registered for that satype.
46535 + *
46536 + * Revision 1.35 2000/08/24 17:03:00 rgb
46537 + * Corrected message size error return code for PF_KEYv2.
46538 + * Removed downward error prohibition.
46539 + *
46540 + * Revision 1.34 2000/08/21 16:32:26 rgb
46541 + * Re-formatted for cosmetic consistency and readability.
46542 + *
46543 + * Revision 1.33 2000/08/20 21:38:24 rgb
46544 + * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
46545 + * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
46546 + *
46547 + * Revision 1.32 2000/07/28 14:58:31 rgb
46548 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
46549 + *
46550 + * Revision 1.31 2000/05/16 03:04:00 rgb
46551 + * Updates for 2.3.99pre8 from MB.
46552 + *
46553 + * Revision 1.30 2000/05/10 19:22:21 rgb
46554 + * Use sklist private functions for 2.3.xx compatibility.
46555 + *
46556 + * Revision 1.29 2000/03/22 16:17:03 rgb
46557 + * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
46558 + *
46559 + * Revision 1.28 2000/02/21 19:30:45 rgb
46560 + * Removed references to pkt_bridged for 2.3.47 compatibility.
46561 + *
46562 + * Revision 1.27 2000/02/14 21:07:00 rgb
46563 + * Fixed /proc/net/pf-key legend spacing.
46564 + *
46565 + * Revision 1.26 2000/01/22 03:46:59 rgb
46566 + * Fixed pfkey error return mechanism so that we are able to free the
46567 + * local copy of the pfkey_msg, plugging a memory leak and silencing
46568 + * the bad object free complaints.
46569 + *
46570 + * Revision 1.25 2000/01/21 06:19:44 rgb
46571 + * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
46572 + * Added debugging to pfkey_upmsg.
46573 + *
46574 + * Revision 1.24 2000/01/10 16:38:23 rgb
46575 + * MB fixups for 2.3.x.
46576 + *
46577 + * Revision 1.23 1999/12/09 23:22:16 rgb
46578 + * Added more instrumentation for debugging 2.0 socket
46579 + * selection/reading.
46580 + * Removed erroneous 2.0 wait==NULL check bug in select.
46581 + *
46582 + * Revision 1.22 1999/12/08 20:32:16 rgb
46583 + * Tidied up 2.0.xx support, after major pfkey work, eliminating
46584 + * msg->msg_name twiddling in the process, since it is not defined
46585 + * for PF_KEYv2.
46586 + *
46587 + * Revision 1.21 1999/12/01 22:17:19 rgb
46588 + * Set skb->dev to zero on new skb in case it is a reused skb.
46589 + * Added check for skb_put overflow and freeing to avoid upmsg on error.
46590 + * Added check for wrong pfkey version and freeing to avoid upmsg on
46591 + * error.
46592 + * Shut off content dumping in pfkey_destroy.
46593 + * Added debugging message for size of buffer allocated for upmsg.
46594 + *
46595 + * Revision 1.20 1999/11/27 12:11:00 rgb
46596 + * Minor clean-up, enabling quiet operation of pfkey if desired.
46597 + *
46598 + * Revision 1.19 1999/11/25 19:04:21 rgb
46599 + * Update proc_fs code for pfkey to use dynamic registration.
46600 + *
46601 + * Revision 1.18 1999/11/25 09:07:17 rgb
46602 + * Implemented SENDERR macro for propagating error codes.
46603 + * Fixed error return code bug.
46604 + *
46605 + * Revision 1.17 1999/11/23 23:07:20 rgb
46606 + * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
46607 + * parses. (PJO)
46608 + * Sort out pfkey and freeswan headers, putting them in a library path.
46609 + *
46610 + * Revision 1.16 1999/11/20 22:00:22 rgb
46611 + * Moved socketlist type declarations and prototypes for shared use.
46612 + * Renamed reformatted and generically extended for use by other socket
46613 + * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
46614 + *
46615 + * Revision 1.15 1999/11/18 04:15:09 rgb
46616 + * Make pfkey_data_ready temporarily available for 2.2.x testing.
46617 + * Clean up pfkey_destroy_socket() debugging statements.
46618 + * Add Peter Onion's code to send messages up to all listening sockets.
46619 + * Changed all occurrences of #include "../../../lib/freeswan.h"
46620 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
46621 + * klips/net/ipsec/Makefile.
46622 + * Replaced all kernel version macros to shorter, readable form.
46623 + * Added CONFIG_PROC_FS compiler directives in case it is shut off.
46624 + *
46625 + * Revision 1.14 1999/11/17 16:01:00 rgb
46626 + * Make pfkey_data_ready temporarily available for 2.2.x testing.
46627 + * Clean up pfkey_destroy_socket() debugging statements.
46628 + * Add Peter Onion's code to send messages up to all listening sockets.
46629 + * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
46630 + * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
46631 + *
46632 + * Revision 1.13 1999/10/27 19:59:51 rgb
46633 + * Removed af_unix comments that are no longer relevant.
46634 + * Added debug prink statements.
46635 + * Added to the /proc output in pfkey_get_info.
46636 + * Made most functions non-static to enable oops tracing.
46637 + * Re-enable skb dequeueing and freeing.
46638 + * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
46639 + *
46640 + * Revision 1.12 1999/10/26 17:05:42 rgb
46641 + * Complete re-ordering based on proto_ops structure order.
46642 + * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
46643 + * Simplification to use built-in socket ops where possible for 2.2.x.
46644 + * Add shorter macros for compiler directives to visually clean-up.
46645 + * Add lots of sk skb dequeueing debugging statements.
46646 + * Added to the /proc output in pfkey_get_info.
46647 + *
46648 + * Revision 1.11 1999/09/30 02:55:10 rgb
46649 + * Bogus skb detection.
46650 + * Fix incorrect /proc/net/ipsec-eroute printk message.
46651 + *
46652 + * Revision 1.10 1999/09/21 15:22:13 rgb
46653 + * Temporary fix while I figure out the right way to destroy sockets.
46654 + *
46655 + * Revision 1.9 1999/07/08 19:19:44 rgb
46656 + * Fix pointer format warning.
46657 + * Fix missing member error under 2.0.xx kernels.
46658 + *
46659 + * Revision 1.8 1999/06/13 07:24:04 rgb
46660 + * Add more debugging.
46661 + *
46662 + * Revision 1.7 1999/06/10 05:24:17 rgb
46663 + * Clarified compiler directives.
46664 + * Renamed variables to reduce confusion.
46665 + * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
46666 + * Added lots of sanity checking.
46667 + *
46668 + * Revision 1.6 1999/06/03 18:59:50 rgb
46669 + * More updates to 2.2.x socket support. Almost works, oops at end of call.
46670 + *
46671 + * Revision 1.5 1999/05/25 22:44:05 rgb
46672 + * Start fixing 2.2 sockets.
46673 + *
46674 + * Revision 1.4 1999/04/29 15:21:34 rgb
46675 + * Move log to the end of the file.
46676 + * Eliminate min/max redefinition in #include <net/tcp.h>.
46677 + * Correct path for pfkey #includes
46678 + * Standardise an error return method.
46679 + * Add debugging instrumentation.
46680 + * Move message type checking to pfkey_msg_parse().
46681 + * Add check for errno incorrectly set.
46682 + * Add check for valid PID.
46683 + * Add check for reserved illegally set.
46684 + * Add check for message out of bounds.
46685 + *
46686 + * Revision 1.3 1999/04/15 17:58:07 rgb
46687 + * Add RCSID labels.
46688 + *
46689 + * Revision 1.2 1999/04/15 15:37:26 rgb
46690 + * Forward check changes from POST1_00 branch.
46691 + *
46692 + * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
46693 + * Header Title correction.
46694 + *
46695 + * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
46696 + * Add pfkeyv2 support to KLIPS.
46697 + *
46698 + *
46699 + * RFC 2367
46700 + * PF_KEY_v2 Key Management API
46701 + */
46702 --- /dev/null Tue Mar 11 13:02:56 2003
46703 +++ linux/net/ipsec/pfkey_v2_build.c Mon Feb 9 13:51:03 2004
46704 @@ -0,0 +1,1581 @@
46705 +/*
46706 + * RFC2367 PF_KEYv2 Key management API message parser
46707 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
46708 + *
46709 + * This program is free software; you can redistribute it and/or modify it
46710 + * under the terms of the GNU General Public License as published by the
46711 + * Free Software Foundation; either version 2 of the License, or (at your
46712 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
46713 + *
46714 + * This program is distributed in the hope that it will be useful, but
46715 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
46716 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
46717 + * for more details.
46718 + *
46719 + * RCSID $Id: pfkey_v2_build.c,v 1.51.8.1 2006/05/01 14:36:39 mcr Exp $
46720 + */
46721 +
46722 +/*
46723 + * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
46724 + */
46725 +
46726 +char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.51.8.1 2006/05/01 14:36:39 mcr Exp $";
46727 +
46728 +/*
46729 + * Some ugly stuff to allow consistent debugging code for use in the
46730 + * kernel and in user space
46731 +*/
46732 +
46733 +#ifdef __KERNEL__
46734 +
46735 +# include <linux/kernel.h> /* for printk */
46736 +
46737 +# include "openswan/ipsec_kversion.h" /* for malloc switch */
46738 +# ifdef MALLOC_SLAB
46739 +# include <linux/slab.h> /* kmalloc() */
46740 +# else /* MALLOC_SLAB */
46741 +# include <linux/malloc.h> /* kmalloc() */
46742 +# endif /* MALLOC_SLAB */
46743 +# include <linux/errno.h> /* error codes */
46744 +# include <linux/types.h> /* size_t */
46745 +# include <linux/interrupt.h> /* mark_bh */
46746 +
46747 +# include <linux/netdevice.h> /* struct device, and other headers */
46748 +# include <linux/etherdevice.h> /* eth_type_trans */
46749 +# include <linux/ip.h> /* struct iphdr */
46750 +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
46751 +# include <linux/ipv6.h> /* struct ipv6hdr */
46752 +# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
46753 +
46754 +# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
46755 +# define FREE(obj) kfree(obj)
46756 +# include <openswan.h>
46757 +#else /* __KERNEL__ */
46758 +
46759 +# include <sys/types.h>
46760 +# include <linux/types.h>
46761 +# include <linux/errno.h>
46762 +# include <malloc.h>
46763 +# include <string.h> /* memset */
46764 +
46765 +# include <openswan.h>
46766 +
46767 +#endif /* __KERNEL__ */
46768 +
46769 +#include <pfkeyv2.h>
46770 +#include <pfkey.h>
46771 +
46772 +#ifdef __KERNEL__
46773 +#include "openswan/radij.h" /* rd_nodes */
46774 +#include "openswan/ipsec_encap.h" /* sockaddr_encap */
46775 +#endif /* __KERNEL__ */
46776 +
46777 +
46778 +#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
46779 +#include "openswan/pfkey_debug.h"
46780 +
46781 +
46782 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
46783 +
46784 +void
46785 +pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
46786 +{
46787 + int i;
46788 +
46789 + for (i = 0; i != SADB_EXT_MAX + 1; i++) {
46790 + extensions[i] = NULL;
46791 + }
46792 +}
46793 +
46794 +void
46795 +pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
46796 +{
46797 + int i;
46798 +
46799 + if(!extensions) {
46800 + return;
46801 + }
46802 +
46803 + if(extensions[0]) {
46804 + memset(extensions[0], 0, sizeof(struct sadb_msg));
46805 + FREE(extensions[0]);
46806 + extensions[0] = NULL;
46807 + }
46808 +
46809 + for (i = 1; i != SADB_EXT_MAX + 1; i++) {
46810 + if(extensions[i]) {
46811 + memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
46812 + FREE(extensions[i]);
46813 + extensions[i] = NULL;
46814 + }
46815 + }
46816 +}
46817 +
46818 +void
46819 +pfkey_msg_free(struct sadb_msg **pfkey_msg)
46820 +{
46821 + if(*pfkey_msg) {
46822 + memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
46823 + FREE(*pfkey_msg);
46824 + *pfkey_msg = NULL;
46825 + }
46826 +}
46827 +
46828 +/* Default extension builders taken from the KLIPS code */
46829 +
46830 +int
46831 +pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
46832 + uint8_t msg_type,
46833 + uint8_t satype,
46834 + uint8_t msg_errno,
46835 + uint32_t seq,
46836 + uint32_t pid)
46837 +{
46838 + int error = 0;
46839 + struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
46840 +
46841 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46842 + "pfkey_msg_hdr_build:\n");
46843 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46844 + "pfkey_msg_hdr_build: "
46845 + "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
46846 + &pfkey_ext,
46847 + pfkey_ext,
46848 + *pfkey_ext);
46849 + /* sanity checks... */
46850 + if(pfkey_msg) {
46851 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46852 + "pfkey_msg_hdr_build: "
46853 + "why is pfkey_msg already pointing to something?\n");
46854 + SENDERR(EINVAL);
46855 + }
46856 +
46857 + if(!msg_type) {
46858 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46859 + "pfkey_msg_hdr_build: "
46860 + "msg type not set, must be non-zero..\n");
46861 + SENDERR(EINVAL);
46862 + }
46863 +
46864 + if(msg_type > SADB_MAX) {
46865 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46866 + "pfkey_msg_hdr_build: "
46867 + "msg type too large:%d.\n",
46868 + msg_type);
46869 + SENDERR(EINVAL);
46870 + }
46871 +
46872 + if(satype > SADB_SATYPE_MAX) {
46873 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46874 + "pfkey_msg_hdr_build: "
46875 + "satype %d > max %d\n",
46876 + satype, SADB_SATYPE_MAX);
46877 + SENDERR(EINVAL);
46878 + }
46879 +
46880 + pfkey_msg = (struct sadb_msg*)MALLOC(sizeof(struct sadb_msg));
46881 + *pfkey_ext = (struct sadb_ext*)pfkey_msg;
46882 +
46883 + if(pfkey_msg == NULL) {
46884 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46885 + "pfkey_msg_hdr_build: "
46886 + "memory allocation failed\n");
46887 + SENDERR(ENOMEM);
46888 + }
46889 + memset(pfkey_msg, 0, sizeof(struct sadb_msg));
46890 +
46891 + pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
46892 +
46893 + pfkey_msg->sadb_msg_type = msg_type;
46894 + pfkey_msg->sadb_msg_satype = satype;
46895 +
46896 + pfkey_msg->sadb_msg_version = PF_KEY_V2;
46897 + pfkey_msg->sadb_msg_errno = msg_errno;
46898 + pfkey_msg->sadb_msg_reserved = 0;
46899 + pfkey_msg->sadb_msg_seq = seq;
46900 + pfkey_msg->sadb_msg_pid = pid;
46901 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46902 + "pfkey_msg_hdr_build: "
46903 + "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
46904 + &pfkey_ext,
46905 + pfkey_ext,
46906 + *pfkey_ext);
46907 +errlab:
46908 + return error;
46909 +}
46910 +
46911 +int
46912 +pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
46913 + uint16_t exttype,
46914 + uint32_t spi,
46915 + uint8_t replay_window,
46916 + uint8_t sa_state,
46917 + uint8_t auth,
46918 + uint8_t encrypt,
46919 + uint32_t flags,
46920 + uint32_t/*IPsecSAref_t*/ ref)
46921 +{
46922 + int error = 0;
46923 + struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
46924 +
46925 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46926 + "pfkey_sa_build: "
46927 + "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
46928 + ntohl(spi), /* in network order */
46929 + replay_window,
46930 + sa_state,
46931 + auth,
46932 + encrypt,
46933 + flags);
46934 + /* sanity checks... */
46935 + if(pfkey_sa) {
46936 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46937 + "pfkey_sa_build: "
46938 + "why is pfkey_sa already pointing to something?\n");
46939 + SENDERR(EINVAL);
46940 + }
46941 +
46942 + if(exttype != SADB_EXT_SA &&
46943 + exttype != SADB_X_EXT_SA2) {
46944 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46945 + "pfkey_sa_build: "
46946 + "invalid exttype=%d.\n",
46947 + exttype);
46948 + SENDERR(EINVAL);
46949 + }
46950 +
46951 + if(replay_window > 64) {
46952 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46953 + "pfkey_sa_build: "
46954 + "replay window size: %d -- must be 0 <= size <= 64\n",
46955 + replay_window);
46956 + SENDERR(EINVAL);
46957 + }
46958 +
46959 + if(auth > SADB_AALG_MAX) {
46960 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46961 + "pfkey_sa_build: "
46962 + "auth=%d > SADB_AALG_MAX=%d.\n",
46963 + auth,
46964 + SADB_AALG_MAX);
46965 + SENDERR(EINVAL);
46966 + }
46967 +
46968 +#if SADB_EALG_MAX < 255
46969 + if(encrypt > SADB_EALG_MAX) {
46970 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46971 + "pfkey_sa_build: "
46972 + "encrypt=%d > SADB_EALG_MAX=%d.\n",
46973 + encrypt,
46974 + SADB_EALG_MAX);
46975 + SENDERR(EINVAL);
46976 + }
46977 +#endif
46978 +
46979 + if(sa_state > SADB_SASTATE_MAX) {
46980 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46981 + "pfkey_sa_build: "
46982 + "sa_state=%d exceeds MAX=%d.\n",
46983 + sa_state,
46984 + SADB_SASTATE_MAX);
46985 + SENDERR(EINVAL);
46986 + }
46987 +
46988 + if(sa_state == SADB_SASTATE_DEAD) {
46989 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46990 + "pfkey_sa_build: "
46991 + "sa_state=%d is DEAD=%d is not allowed.\n",
46992 + sa_state,
46993 + SADB_SASTATE_DEAD);
46994 + SENDERR(EINVAL);
46995 + }
46996 +
46997 + if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
46998 + DEBUGGING(PF_KEY_DEBUG_BUILD,
46999 + "pfkey_sa_build: "
47000 + "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
47001 + ref,
47002 + IPSEC_SAREF_NULL,
47003 + IPSEC_SA_REF_TABLE_NUM_ENTRIES);
47004 + SENDERR(EINVAL);
47005 + }
47006 +
47007 + pfkey_sa = (struct sadb_sa*)MALLOC(sizeof(struct sadb_sa));
47008 + *pfkey_ext = (struct sadb_ext*)pfkey_sa;
47009 +
47010 + if(pfkey_sa == NULL) {
47011 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47012 + "pfkey_sa_build: "
47013 + "memory allocation failed\n");
47014 + SENDERR(ENOMEM);
47015 + }
47016 + memset(pfkey_sa, 0, sizeof(struct sadb_sa));
47017 +
47018 + pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
47019 + pfkey_sa->sadb_sa_exttype = exttype;
47020 + pfkey_sa->sadb_sa_spi = spi;
47021 + pfkey_sa->sadb_sa_replay = replay_window;
47022 + pfkey_sa->sadb_sa_state = sa_state;
47023 + pfkey_sa->sadb_sa_auth = auth;
47024 + pfkey_sa->sadb_sa_encrypt = encrypt;
47025 + pfkey_sa->sadb_sa_flags = flags;
47026 + pfkey_sa->sadb_x_sa_ref = ref;
47027 +
47028 +errlab:
47029 + return error;
47030 +}
47031 +
47032 +int
47033 +pfkey_sa_build(struct sadb_ext ** pfkey_ext,
47034 + uint16_t exttype,
47035 + uint32_t spi,
47036 + uint8_t replay_window,
47037 + uint8_t sa_state,
47038 + uint8_t auth,
47039 + uint8_t encrypt,
47040 + uint32_t flags)
47041 +{
47042 + return pfkey_sa_ref_build(pfkey_ext,
47043 + exttype,
47044 + spi,
47045 + replay_window,
47046 + sa_state,
47047 + auth,
47048 + encrypt,
47049 + flags,
47050 + IPSEC_SAREF_NULL);
47051 +}
47052 +
47053 +int
47054 +pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
47055 + uint16_t exttype,
47056 + uint32_t allocations,
47057 + uint64_t bytes,
47058 + uint64_t addtime,
47059 + uint64_t usetime,
47060 + uint32_t packets)
47061 +{
47062 + int error = 0;
47063 + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
47064 +
47065 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47066 + "pfkey_lifetime_build:\n");
47067 + /* sanity checks... */
47068 + if(pfkey_lifetime) {
47069 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47070 + "pfkey_lifetime_build: "
47071 + "why is pfkey_lifetime already pointing to something?\n");
47072 + SENDERR(EINVAL);
47073 + }
47074 +
47075 + if(exttype != SADB_EXT_LIFETIME_CURRENT &&
47076 + exttype != SADB_EXT_LIFETIME_HARD &&
47077 + exttype != SADB_EXT_LIFETIME_SOFT) {
47078 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47079 + "pfkey_lifetime_build: "
47080 + "invalid exttype=%d.\n",
47081 + exttype);
47082 + SENDERR(EINVAL);
47083 + }
47084 +
47085 + pfkey_lifetime = (struct sadb_lifetime*)MALLOC(sizeof(struct sadb_lifetime));
47086 + *pfkey_ext = (struct sadb_ext*) pfkey_lifetime;
47087 +
47088 + if(pfkey_lifetime == NULL) {
47089 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47090 + "pfkey_lifetime_build: "
47091 + "memory allocation failed\n");
47092 + SENDERR(ENOMEM);
47093 + }
47094 + memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
47095 +
47096 + pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
47097 + pfkey_lifetime->sadb_lifetime_exttype = exttype;
47098 + pfkey_lifetime->sadb_lifetime_allocations = allocations;
47099 + pfkey_lifetime->sadb_lifetime_bytes = bytes;
47100 + pfkey_lifetime->sadb_lifetime_addtime = addtime;
47101 + pfkey_lifetime->sadb_lifetime_usetime = usetime;
47102 + pfkey_lifetime->sadb_x_lifetime_packets = packets;
47103 +
47104 +errlab:
47105 + return error;
47106 +}
47107 +
47108 +int
47109 +pfkey_address_build(struct sadb_ext** pfkey_ext,
47110 + uint16_t exttype,
47111 + uint8_t proto,
47112 + uint8_t prefixlen,
47113 + struct sockaddr* address)
47114 +{
47115 + int error = 0;
47116 + int saddr_len = 0;
47117 + char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
47118 + struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
47119 +
47120 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47121 + "pfkey_address_build: "
47122 + "exttype=%d proto=%d prefixlen=%d\n",
47123 + exttype,
47124 + proto,
47125 + prefixlen);
47126 + /* sanity checks... */
47127 + if(pfkey_address) {
47128 + ERROR("pfkey_address_build: "
47129 + "why is pfkey_address already pointing to something?\n");
47130 + SENDERR(EINVAL);
47131 + }
47132 +
47133 + if (!address) {
47134 + ERROR("pfkey_address_build: " "address is NULL\n");
47135 + SENDERR(EINVAL);
47136 + }
47137 +
47138 + switch(exttype) {
47139 + case SADB_EXT_ADDRESS_SRC:
47140 + case SADB_EXT_ADDRESS_DST:
47141 + case SADB_EXT_ADDRESS_PROXY:
47142 + case SADB_X_EXT_ADDRESS_DST2:
47143 + case SADB_X_EXT_ADDRESS_SRC_FLOW:
47144 + case SADB_X_EXT_ADDRESS_DST_FLOW:
47145 + case SADB_X_EXT_ADDRESS_SRC_MASK:
47146 + case SADB_X_EXT_ADDRESS_DST_MASK:
47147 +#ifdef NAT_TRAVERSAL
47148 + case SADB_X_EXT_NAT_T_OA:
47149 +#endif
47150 + break;
47151 + default:
47152 + ERROR("pfkey_address_build: "
47153 + "unrecognised ext_type=%d.\n",
47154 + exttype);
47155 + SENDERR(EINVAL);
47156 + }
47157 +
47158 + switch(address->sa_family) {
47159 + case AF_INET:
47160 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47161 + "pfkey_address_build: "
47162 + "found address family AF_INET.\n");
47163 + saddr_len = sizeof(struct sockaddr_in);
47164 + sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
47165 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
47166 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
47167 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
47168 + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
47169 + , ntohs(((struct sockaddr_in*)address)->sin_port));
47170 + break;
47171 + case AF_INET6:
47172 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47173 + "pfkey_address_build: "
47174 + "found address family AF_INET6.\n");
47175 + saddr_len = sizeof(struct sockaddr_in6);
47176 + sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
47177 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
47178 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
47179 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
47180 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
47181 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
47182 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
47183 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
47184 + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
47185 + , ntohs(((struct sockaddr_in6*)address)->sin6_port));
47186 + break;
47187 + default:
47188 + ERROR("pfkey_address_build: "
47189 + "address->sa_family=%d not supported.\n",
47190 + address->sa_family);
47191 + SENDERR(EPFNOSUPPORT);
47192 + }
47193 +
47194 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47195 + "pfkey_address_build: "
47196 + "found address=%s.\n",
47197 + ipaddr_txt);
47198 + if(prefixlen != 0) {
47199 + ERROR("pfkey_address_build: "
47200 + "address prefixes not supported yet.\n");
47201 + SENDERR(EAFNOSUPPORT); /* not supported yet */
47202 + }
47203 +
47204 + /* allocate some memory for the extension */
47205 + pfkey_address = (struct sadb_address*)
47206 + MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
47207 + *pfkey_ext = (struct sadb_ext*)pfkey_address;
47208 +
47209 + if(pfkey_address == NULL ) {
47210 + ERROR("pfkey_lifetime_build: "
47211 + "memory allocation failed\n");
47212 + SENDERR(ENOMEM);
47213 + }
47214 + memset(pfkey_address,
47215 + 0,
47216 + ALIGN_N(sizeof(struct sadb_address) + saddr_len,
47217 + IPSEC_PFKEYv2_ALIGN));
47218 +
47219 + pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
47220 + IPSEC_PFKEYv2_ALIGN);
47221 +
47222 + pfkey_address->sadb_address_exttype = exttype;
47223 + pfkey_address->sadb_address_proto = proto;
47224 + pfkey_address->sadb_address_prefixlen = prefixlen;
47225 + pfkey_address->sadb_address_reserved = 0;
47226 +
47227 + memcpy((char*)pfkey_address + sizeof(struct sadb_address),
47228 + address,
47229 + saddr_len);
47230 +
47231 +#if 0
47232 + for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
47233 + pfkey_address_s_ska.sin_zero[i] = 0;
47234 + }
47235 +#endif
47236 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47237 + "pfkey_address_build: "
47238 + "successful created len: %d.\n", pfkey_address->sadb_address_len);
47239 +
47240 + errlab:
47241 + return error;
47242 +}
47243 +
47244 +int
47245 +pfkey_key_build(struct sadb_ext** pfkey_ext,
47246 + uint16_t exttype,
47247 + uint16_t key_bits,
47248 + char* key)
47249 +{
47250 + int error = 0;
47251 + struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
47252 +
47253 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47254 + "pfkey_key_build:\n");
47255 + /* sanity checks... */
47256 + if(pfkey_key) {
47257 + ERROR("pfkey_key_build: "
47258 + "why is pfkey_key already pointing to something?\n");
47259 + SENDERR(EINVAL);
47260 + }
47261 +
47262 + if(!key_bits) {
47263 + ERROR("pfkey_key_build: "
47264 + "key_bits is zero, it must be non-zero.\n");
47265 + SENDERR(EINVAL);
47266 + }
47267 +
47268 + if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
47269 + ERROR("pfkey_key_build: "
47270 + "unsupported extension type=%d.\n",
47271 + exttype);
47272 + SENDERR(EINVAL);
47273 + }
47274 +
47275 + pfkey_key = (struct sadb_key*)
47276 + MALLOC(sizeof(struct sadb_key) +
47277 + DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
47278 +
47279 + *pfkey_ext = (struct sadb_ext*)pfkey_key;
47280 +
47281 + if(pfkey_key == NULL) {
47282 + ERROR("pfkey_key_build: "
47283 + "memory allocation failed\n");
47284 + SENDERR(ENOMEM);
47285 + }
47286 + memset(pfkey_key,
47287 + 0,
47288 + sizeof(struct sadb_key) +
47289 + DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
47290 +
47291 + pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
47292 + 64);
47293 + pfkey_key->sadb_key_exttype = exttype;
47294 + pfkey_key->sadb_key_bits = key_bits;
47295 + pfkey_key->sadb_key_reserved = 0;
47296 + memcpy((char*)pfkey_key + sizeof(struct sadb_key),
47297 + key,
47298 + DIVUP(key_bits, 8));
47299 +
47300 +errlab:
47301 + return error;
47302 +}
47303 +
47304 +int
47305 +pfkey_ident_build(struct sadb_ext** pfkey_ext,
47306 + uint16_t exttype,
47307 + uint16_t ident_type,
47308 + uint64_t ident_id,
47309 + uint8_t ident_len,
47310 + char* ident_string)
47311 +{
47312 + int error = 0;
47313 + struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
47314 + int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
47315 +
47316 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47317 + "pfkey_ident_build:\n");
47318 + /* sanity checks... */
47319 + if(pfkey_ident) {
47320 + ERROR("pfkey_ident_build: "
47321 + "why is pfkey_ident already pointing to something?\n");
47322 + SENDERR(EINVAL);
47323 + }
47324 +
47325 + if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
47326 + (exttype == SADB_EXT_IDENTITY_DST))) {
47327 + ERROR("pfkey_ident_build: "
47328 + "unsupported extension type=%d.\n",
47329 + exttype);
47330 + SENDERR(EINVAL);
47331 + }
47332 +
47333 + if((ident_type == SADB_IDENTTYPE_RESERVED)) {
47334 + ERROR("pfkey_ident_build: "
47335 + "ident_type must be non-zero.\n");
47336 + SENDERR(EINVAL);
47337 + }
47338 +
47339 + if(ident_type > SADB_IDENTTYPE_MAX) {
47340 + ERROR("pfkey_ident_build: "
47341 + "identtype=%d out of range.\n",
47342 + ident_type);
47343 + SENDERR(EINVAL);
47344 + }
47345 +
47346 + if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
47347 + (ident_type == SADB_IDENTTYPE_FQDN)) &&
47348 + !ident_string) {
47349 + ERROR("pfkey_ident_build: "
47350 + "string required to allocate size of extension.\n");
47351 + SENDERR(EINVAL);
47352 + }
47353 +
47354 +#if 0
47355 + if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
47356 + }
47357 +#endif
47358 +
47359 + pfkey_ident = (struct sadb_ident*)
47360 + MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN);
47361 +
47362 + *pfkey_ext = (struct sadb_ext*)pfkey_ident;
47363 +
47364 + if(pfkey_ident == NULL) {
47365 + ERROR("pfkey_ident_build: "
47366 + "memory allocation failed\n");
47367 + SENDERR(ENOMEM);
47368 + }
47369 + memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
47370 +
47371 + pfkey_ident->sadb_ident_len = ident_len;
47372 + pfkey_ident->sadb_ident_exttype = exttype;
47373 + pfkey_ident->sadb_ident_type = ident_type;
47374 + pfkey_ident->sadb_ident_reserved = 0;
47375 + pfkey_ident->sadb_ident_id = ident_id;
47376 + memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
47377 + ident_string,
47378 + data_len);
47379 +
47380 +errlab:
47381 + return error;
47382 +}
47383 +
47384 +int
47385 +pfkey_sens_build(struct sadb_ext** pfkey_ext,
47386 + uint32_t dpd,
47387 + uint8_t sens_level,
47388 + uint8_t sens_len,
47389 + uint64_t* sens_bitmap,
47390 + uint8_t integ_level,
47391 + uint8_t integ_len,
47392 + uint64_t* integ_bitmap)
47393 +{
47394 + int error = 0;
47395 + struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
47396 + int i;
47397 + uint64_t* bitmap;
47398 +
47399 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47400 + "pfkey_sens_build:\n");
47401 + /* sanity checks... */
47402 + if(pfkey_sens) {
47403 + ERROR("pfkey_sens_build: "
47404 + "why is pfkey_sens already pointing to something?\n");
47405 + SENDERR(EINVAL);
47406 + }
47407 +
47408 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47409 + "pfkey_sens_build: "
47410 + "Sorry, I can't build exttype=%d yet.\n",
47411 + (*pfkey_ext)->sadb_ext_type);
47412 + SENDERR(EINVAL); /* don't process these yet */
47413 +
47414 + pfkey_sens = (struct sadb_sens*)
47415 + MALLOC(sizeof(struct sadb_sens) +
47416 + (sens_len + integ_len) * sizeof(uint64_t));
47417 +
47418 + *pfkey_ext = (struct sadb_ext*)pfkey_sens;
47419 +
47420 + if(pfkey_sens == NULL) {
47421 + ERROR("pfkey_sens_build: "
47422 + "memory allocation failed\n");
47423 + SENDERR(ENOMEM);
47424 + }
47425 + memset(pfkey_sens,
47426 + 0,
47427 + sizeof(struct sadb_sens) +
47428 + (sens_len + integ_len) * sizeof(uint64_t));
47429 +
47430 + pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
47431 + (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
47432 + pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
47433 + pfkey_sens->sadb_sens_dpd = dpd;
47434 + pfkey_sens->sadb_sens_sens_level = sens_level;
47435 + pfkey_sens->sadb_sens_sens_len = sens_len;
47436 + pfkey_sens->sadb_sens_integ_level = integ_level;
47437 + pfkey_sens->sadb_sens_integ_len = integ_len;
47438 + pfkey_sens->sadb_sens_reserved = 0;
47439 +
47440 + bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
47441 + for(i = 0; i < sens_len; i++) {
47442 + *bitmap = sens_bitmap[i];
47443 + bitmap++;
47444 + }
47445 + for(i = 0; i < integ_len; i++) {
47446 + *bitmap = integ_bitmap[i];
47447 + bitmap++;
47448 + }
47449 +
47450 +errlab:
47451 + return error;
47452 +}
47453 +
47454 +int
47455 +pfkey_prop_build(struct sadb_ext** pfkey_ext,
47456 + uint8_t replay,
47457 + unsigned int comb_num,
47458 + struct sadb_comb* comb)
47459 +{
47460 + int error = 0;
47461 + int i;
47462 + struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
47463 + struct sadb_comb *combp;
47464 +
47465 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47466 + "pfkey_prop_build:\n");
47467 + /* sanity checks... */
47468 + if(pfkey_prop) {
47469 + ERROR("pfkey_prop_build: "
47470 + "why is pfkey_prop already pointing to something?\n");
47471 + SENDERR(EINVAL);
47472 + }
47473 +
47474 + pfkey_prop = (struct sadb_prop*)
47475 + MALLOC(sizeof(struct sadb_prop) +
47476 + comb_num * sizeof(struct sadb_comb));
47477 +
47478 + *pfkey_ext = (struct sadb_ext*)pfkey_prop;
47479 +
47480 + if(pfkey_prop == NULL) {
47481 + ERROR("pfkey_prop_build: "
47482 + "memory allocation failed\n");
47483 + SENDERR(ENOMEM);
47484 + }
47485 + memset(pfkey_prop,
47486 + 0,
47487 + sizeof(struct sadb_prop) +
47488 + comb_num * sizeof(struct sadb_comb));
47489 +
47490 + pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
47491 + comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
47492 +
47493 + pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
47494 + pfkey_prop->sadb_prop_replay = replay;
47495 +
47496 + for(i=0; i<3; i++) {
47497 + pfkey_prop->sadb_prop_reserved[i] = 0;
47498 + }
47499 +
47500 + combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
47501 + for(i = 0; i < comb_num; i++) {
47502 + memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
47503 + combp++;
47504 + }
47505 +
47506 +#if 0
47507 + uint8_t sadb_comb_auth;
47508 + uint8_t sadb_comb_encrypt;
47509 + uint16_t sadb_comb_flags;
47510 + uint16_t sadb_comb_auth_minbits;
47511 + uint16_t sadb_comb_auth_maxbits;
47512 + uint16_t sadb_comb_encrypt_minbits;
47513 + uint16_t sadb_comb_encrypt_maxbits;
47514 + uint32_t sadb_comb_reserved;
47515 + uint32_t sadb_comb_soft_allocations;
47516 + uint32_t sadb_comb_hard_allocations;
47517 + uint64_t sadb_comb_soft_bytes;
47518 + uint64_t sadb_comb_hard_bytes;
47519 + uint64_t sadb_comb_soft_addtime;
47520 + uint64_t sadb_comb_hard_addtime;
47521 + uint64_t sadb_comb_soft_usetime;
47522 + uint64_t sadb_comb_hard_usetime;
47523 + uint32_t sadb_comb_soft_packets;
47524 + uint32_t sadb_comb_hard_packets;
47525 +#endif
47526 +errlab:
47527 + return error;
47528 +}
47529 +
47530 +int
47531 +pfkey_supported_build(struct sadb_ext** pfkey_ext,
47532 + uint16_t exttype,
47533 + unsigned int alg_num,
47534 + struct sadb_alg* alg)
47535 +{
47536 + int error = 0;
47537 + unsigned int i;
47538 + struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
47539 + struct sadb_alg *pfkey_alg;
47540 +
47541 + /* sanity checks... */
47542 + if(pfkey_supported) {
47543 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47544 + "pfkey_supported_build: "
47545 + "why is pfkey_supported already pointing to something?\n");
47546 + SENDERR(EINVAL);
47547 + }
47548 +
47549 + if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
47550 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47551 + "pfkey_supported_build: "
47552 + "unsupported extension type=%d.\n",
47553 + exttype);
47554 + SENDERR(EINVAL);
47555 + }
47556 +
47557 + pfkey_supported = (struct sadb_supported*)
47558 + MALLOC(sizeof(struct sadb_supported) +
47559 + alg_num *
47560 + sizeof(struct sadb_alg));
47561 +
47562 + *pfkey_ext = (struct sadb_ext*)pfkey_supported;
47563 +
47564 + if(pfkey_supported == NULL) {
47565 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47566 + "pfkey_supported_build: "
47567 + "memory allocation failed\n");
47568 + SENDERR(ENOMEM);
47569 + }
47570 + memset(pfkey_supported,
47571 + 0,
47572 + sizeof(struct sadb_supported) +
47573 + alg_num *
47574 + sizeof(struct sadb_alg));
47575 +
47576 + pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
47577 + alg_num *
47578 + sizeof(struct sadb_alg)) /
47579 + IPSEC_PFKEYv2_ALIGN;
47580 + pfkey_supported->sadb_supported_exttype = exttype;
47581 + pfkey_supported->sadb_supported_reserved = 0;
47582 +
47583 + pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
47584 + for(i = 0; i < alg_num; i++) {
47585 + memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
47586 + pfkey_alg->sadb_alg_reserved = 0;
47587 + pfkey_alg++;
47588 + }
47589 +
47590 +#if 0
47591 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47592 + "pfkey_supported_build: "
47593 + "Sorry, I can't build exttype=%d yet.\n",
47594 + (*pfkey_ext)->sadb_ext_type);
47595 + SENDERR(EINVAL); /* don't process these yet */
47596 +
47597 + uint8_t sadb_alg_id;
47598 + uint8_t sadb_alg_ivlen;
47599 + uint16_t sadb_alg_minbits;
47600 + uint16_t sadb_alg_maxbits;
47601 + uint16_t sadb_alg_reserved;
47602 +#endif
47603 +errlab:
47604 + return error;
47605 +}
47606 +
47607 +int
47608 +pfkey_spirange_build(struct sadb_ext** pfkey_ext,
47609 + uint16_t exttype,
47610 + uint32_t min, /* in network order */
47611 + uint32_t max) /* in network order */
47612 +{
47613 + int error = 0;
47614 + struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
47615 +
47616 + /* sanity checks... */
47617 + if(pfkey_spirange) {
47618 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47619 + "pfkey_spirange_build: "
47620 + "why is pfkey_spirange already pointing to something?\n");
47621 + SENDERR(EINVAL);
47622 + }
47623 +
47624 + if(ntohl(max) < ntohl(min)) {
47625 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47626 + "pfkey_spirange_build: "
47627 + "minspi=%08x must be < maxspi=%08x.\n",
47628 + ntohl(min),
47629 + ntohl(max));
47630 + SENDERR(EINVAL);
47631 + }
47632 +
47633 + if(ntohl(min) <= 255) {
47634 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47635 + "pfkey_spirange_build: "
47636 + "minspi=%08x must be > 255.\n",
47637 + ntohl(min));
47638 + SENDERR(EEXIST);
47639 + }
47640 +
47641 + pfkey_spirange = (struct sadb_spirange*)
47642 + MALLOC(sizeof(struct sadb_spirange));
47643 +
47644 + *pfkey_ext = (struct sadb_ext*)pfkey_spirange;
47645 +
47646 + if(pfkey_spirange == NULL) {
47647 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47648 + "pfkey_spirange_build: "
47649 + "memory allocation failed\n");
47650 + SENDERR(ENOMEM);
47651 + }
47652 + memset(pfkey_spirange,
47653 + 0,
47654 + sizeof(struct sadb_spirange));
47655 +
47656 + pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
47657 +
47658 + pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
47659 + pfkey_spirange->sadb_spirange_min = min;
47660 + pfkey_spirange->sadb_spirange_max = max;
47661 + pfkey_spirange->sadb_spirange_reserved = 0;
47662 + errlab:
47663 + return error;
47664 +}
47665 +
47666 +int
47667 +pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
47668 +{
47669 + int error = 0;
47670 + struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
47671 +
47672 + /* sanity checks... */
47673 + if(pfkey_x_kmprivate) {
47674 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47675 + "pfkey_x_kmprivate_build: "
47676 + "why is pfkey_x_kmprivate already pointing to something?\n");
47677 + SENDERR(EINVAL);
47678 + }
47679 +
47680 + pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
47681 +
47682 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47683 + "pfkey_x_kmprivate_build: "
47684 + "Sorry, I can't build exttype=%d yet.\n",
47685 + (*pfkey_ext)->sadb_ext_type);
47686 + SENDERR(EINVAL); /* don't process these yet */
47687 +
47688 + pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
47689 + MALLOC(sizeof(struct sadb_x_kmprivate));
47690 +
47691 + *pfkey_ext = (struct sadb_ext*)pfkey_x_kmprivate;
47692 +
47693 + if(pfkey_x_kmprivate == NULL) {
47694 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47695 + "pfkey_x_kmprivate_build: "
47696 + "memory allocation failed\n");
47697 + SENDERR(ENOMEM);
47698 + }
47699 + memset(pfkey_x_kmprivate,
47700 + 0,
47701 + sizeof(struct sadb_x_kmprivate));
47702 +
47703 + pfkey_x_kmprivate->sadb_x_kmprivate_len =
47704 + sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
47705 +
47706 + pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
47707 + pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
47708 +errlab:
47709 + return error;
47710 +}
47711 +
47712 +int
47713 +pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
47714 + uint8_t satype)
47715 +{
47716 + int error = 0;
47717 + int i;
47718 + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
47719 +
47720 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47721 + "pfkey_x_satype_build:\n");
47722 + /* sanity checks... */
47723 + if(pfkey_x_satype) {
47724 + ERROR("pfkey_x_satype_build: "
47725 + "why is pfkey_x_satype already pointing to something?\n");
47726 + SENDERR(EINVAL);
47727 + }
47728 +
47729 + if(!satype) {
47730 + ERROR("pfkey_x_satype_build: "
47731 + "SA type not set, must be non-zero.\n");
47732 + SENDERR(EINVAL);
47733 + }
47734 +
47735 + if(satype > SADB_SATYPE_MAX) {
47736 + ERROR("pfkey_x_satype_build: "
47737 + "satype %d > max %d\n",
47738 + satype, SADB_SATYPE_MAX);
47739 + SENDERR(EINVAL);
47740 + }
47741 +
47742 + pfkey_x_satype = (struct sadb_x_satype*)
47743 + MALLOC(sizeof(struct sadb_x_satype));
47744 +
47745 + *pfkey_ext = (struct sadb_ext*)pfkey_x_satype;
47746 + if(pfkey_x_satype == NULL) {
47747 + ERROR("pfkey_x_satype_build: "
47748 + "memory allocation failed\n");
47749 + SENDERR(ENOMEM);
47750 + }
47751 + memset(pfkey_x_satype,
47752 + 0,
47753 + sizeof(struct sadb_x_satype));
47754 +
47755 + pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
47756 +
47757 + pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
47758 + pfkey_x_satype->sadb_x_satype_satype = satype;
47759 + for(i=0; i<3; i++) {
47760 + pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
47761 + }
47762 +
47763 +errlab:
47764 + return error;
47765 +}
47766 +
47767 +int
47768 +pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
47769 + uint32_t tunnel,
47770 + uint32_t netlink,
47771 + uint32_t xform,
47772 + uint32_t eroute,
47773 + uint32_t spi,
47774 + uint32_t radij,
47775 + uint32_t esp,
47776 + uint32_t ah,
47777 + uint32_t rcv,
47778 + uint32_t pfkey,
47779 + uint32_t ipcomp,
47780 + uint32_t verbose)
47781 +{
47782 + int error = 0;
47783 + int i;
47784 + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
47785 +
47786 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47787 + "pfkey_x_debug_build:\n");
47788 + /* sanity checks... */
47789 + if(pfkey_x_debug) {
47790 + ERROR("pfkey_x_debug_build: "
47791 + "why is pfkey_x_debug already pointing to something?\n");
47792 + SENDERR(EINVAL);
47793 + }
47794 +
47795 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47796 + "pfkey_x_debug_build: "
47797 + "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",
47798 + tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
47799 +
47800 + pfkey_x_debug = (struct sadb_x_debug*)
47801 + MALLOC(sizeof(struct sadb_x_debug));
47802 +
47803 + *pfkey_ext = (struct sadb_ext*)pfkey_x_debug;
47804 +
47805 + if(pfkey_x_debug == NULL) {
47806 + ERROR("pfkey_x_debug_build: "
47807 + "memory allocation failed\n");
47808 + SENDERR(ENOMEM);
47809 + }
47810 +#if 0
47811 + memset(pfkey_x_debug,
47812 + 0,
47813 + sizeof(struct sadb_x_debug));
47814 +#endif
47815 +
47816 + pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
47817 + pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
47818 +
47819 + pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
47820 + pfkey_x_debug->sadb_x_debug_netlink = netlink;
47821 + pfkey_x_debug->sadb_x_debug_xform = xform;
47822 + pfkey_x_debug->sadb_x_debug_eroute = eroute;
47823 + pfkey_x_debug->sadb_x_debug_spi = spi;
47824 + pfkey_x_debug->sadb_x_debug_radij = radij;
47825 + pfkey_x_debug->sadb_x_debug_esp = esp;
47826 + pfkey_x_debug->sadb_x_debug_ah = ah;
47827 + pfkey_x_debug->sadb_x_debug_rcv = rcv;
47828 + pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
47829 + pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
47830 + pfkey_x_debug->sadb_x_debug_verbose = verbose;
47831 +
47832 + for(i=0; i<4; i++) {
47833 + pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
47834 + }
47835 +
47836 +errlab:
47837 + return error;
47838 +}
47839 +
47840 +int
47841 +pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
47842 + uint8_t type)
47843 +{
47844 + int error = 0;
47845 + int i;
47846 + struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
47847 +
47848 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47849 + "pfkey_x_nat_t_type_build:\n");
47850 + /* sanity checks... */
47851 + if(pfkey_x_nat_t_type) {
47852 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47853 + "pfkey_x_nat_t_type_build: "
47854 + "why is pfkey_x_nat_t_type already pointing to something?\n");
47855 + SENDERR(EINVAL);
47856 + }
47857 +
47858 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47859 + "pfkey_x_nat_t_type_build: "
47860 + "type=%d\n", type);
47861 +
47862 + pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
47863 + MALLOC(sizeof(struct sadb_x_nat_t_type));
47864 +
47865 + *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type;
47866 +
47867 + if(pfkey_x_nat_t_type == NULL) {
47868 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47869 + "pfkey_x_nat_t_type_build: "
47870 + "memory allocation failed\n");
47871 + SENDERR(ENOMEM);
47872 + }
47873 +
47874 + pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
47875 + pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
47876 + pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
47877 + for(i=0; i<3; i++) {
47878 + pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
47879 + }
47880 +
47881 +errlab:
47882 + return error;
47883 +}
47884 +int
47885 +pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
47886 + uint16_t exttype,
47887 + uint16_t port)
47888 +{
47889 + int error = 0;
47890 + struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
47891 +
47892 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47893 + "pfkey_x_nat_t_port_build:\n");
47894 + /* sanity checks... */
47895 + if(pfkey_x_nat_t_port) {
47896 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47897 + "pfkey_x_nat_t_port_build: "
47898 + "why is pfkey_x_nat_t_port already pointing to something?\n");
47899 + SENDERR(EINVAL);
47900 + }
47901 +
47902 + switch(exttype) {
47903 + case SADB_X_EXT_NAT_T_SPORT:
47904 + case SADB_X_EXT_NAT_T_DPORT:
47905 + break;
47906 + default:
47907 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47908 + "pfkey_nat_t_port_build: "
47909 + "unrecognised ext_type=%d.\n",
47910 + exttype);
47911 + SENDERR(EINVAL);
47912 + }
47913 +
47914 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47915 + "pfkey_x_nat_t_port_build: "
47916 + "ext=%d, port=%d\n", exttype, port);
47917 +
47918 + pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
47919 + MALLOC(sizeof(struct sadb_x_nat_t_port));
47920 +
47921 + *pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port;
47922 +
47923 + if(pfkey_x_nat_t_port == NULL) {
47924 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47925 + "pfkey_x_nat_t_port_build: "
47926 + "memory allocation failed\n");
47927 + SENDERR(ENOMEM);
47928 + }
47929 +
47930 + pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
47931 + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
47932 + pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
47933 + pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
47934 +
47935 +errlab:
47936 + return error;
47937 +}
47938 +
47939 +int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
47940 + uint8_t protocol)
47941 +{
47942 + int error = 0;
47943 + struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
47944 + DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol);
47945 + /* sanity checks... */
47946 + if (p != 0) {
47947 + ERROR("pfkey_x_protocol_build: bogus protocol pointer\n");
47948 + SENDERR(EINVAL);
47949 + }
47950 + if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
47951 + ERROR("pfkey_build: memory allocation failed\n");
47952 + SENDERR(ENOMEM);
47953 + }
47954 + *pfkey_ext = (struct sadb_ext *)p;
47955 + p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
47956 + p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
47957 + p->sadb_protocol_proto = protocol;
47958 + p->sadb_protocol_flags = 0;
47959 + p->sadb_protocol_reserved2 = 0;
47960 + errlab:
47961 + return error;
47962 +}
47963 +
47964 +int
47965 +pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
47966 +{
47967 + int error = 0;
47968 + unsigned ext;
47969 + unsigned total_size;
47970 + struct sadb_ext *pfkey_ext;
47971 + int extensions_seen = 0;
47972 +#ifndef __KERNEL__
47973 + struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
47974 +#endif
47975 +
47976 + if(!extensions[0]) {
47977 + ERROR("pfkey_msg_build: "
47978 + "extensions[0] must be specified (struct sadb_msg).\n");
47979 + SENDERR(EINVAL);
47980 + }
47981 +
47982 + /* figure out the total size for all the requested extensions */
47983 + total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
47984 + for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
47985 + if(extensions[ext]) {
47986 + total_size += (extensions[ext])->sadb_ext_len;
47987 + }
47988 + }
47989 +
47990 + /* allocate that much space */
47991 + *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN);
47992 + if(*pfkey_msg == NULL) {
47993 + ERROR("pfkey_msg_build: "
47994 + "memory allocation failed\n");
47995 + SENDERR(ENOMEM);
47996 + }
47997 +
47998 + DEBUGGING(PF_KEY_DEBUG_BUILD,
47999 + "pfkey_msg_build: "
48000 + "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
48001 + *pfkey_msg,
48002 + (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
48003 + &(extensions[0]));
48004 +
48005 + memcpy(*pfkey_msg,
48006 + extensions[0],
48007 + sizeof(struct sadb_msg));
48008 + (*pfkey_msg)->sadb_msg_len = total_size;
48009 + (*pfkey_msg)->sadb_msg_reserved = 0;
48010 + extensions_seen = 1 ;
48011 +
48012 + /*
48013 + * point pfkey_ext to immediately after the space for the header,
48014 + * i.e. at the first extension location.
48015 + */
48016 + pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
48017 +
48018 + for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
48019 + /* copy from extension[ext] to buffer */
48020 + if(extensions[ext]) {
48021 + /* Is this type of extension permitted for this type of message? */
48022 + if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
48023 + 1<<ext)) {
48024 + ERROR("pfkey_msg_build: "
48025 + "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
48026 + ext,
48027 + extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
48028 + 1<<ext);
48029 + SENDERR(EINVAL);
48030 + }
48031 +
48032 + DEBUGGING(PF_KEY_DEBUG_BUILD,
48033 + "pfkey_msg_build: "
48034 + "copying %lu bytes from extensions[%u] (type=%d)\n",
48035 + (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
48036 + ext,
48037 + extensions[ext]->sadb_ext_type);
48038 +
48039 + memcpy(pfkey_ext,
48040 + extensions[ext],
48041 + (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
48042 + {
48043 + char *pfkey_ext_c = (char *)pfkey_ext;
48044 +
48045 + pfkey_ext_c += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
48046 + pfkey_ext = (struct sadb_ext *)pfkey_ext_c;
48047 + }
48048 +
48049 + /* Mark that we have seen this extension and remember the header location */
48050 + extensions_seen |= ( 1 << ext );
48051 + }
48052 + }
48053 +
48054 + /* check required extensions */
48055 + DEBUGGING(PF_KEY_DEBUG_BUILD,
48056 + "pfkey_msg_build: "
48057 + "extensions permitted=%08x, seen=%08x, required=%08x.\n",
48058 + extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
48059 + extensions_seen,
48060 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
48061 +
48062 + if((extensions_seen &
48063 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
48064 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
48065 + DEBUGGING(PF_KEY_DEBUG_BUILD,
48066 + "pfkey_msg_build: "
48067 + "required extensions missing:%08x.\n",
48068 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
48069 + (extensions_seen &
48070 + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
48071 + SENDERR(EINVAL);
48072 + }
48073 +
48074 +#ifndef __KERNEL__
48075 +/*
48076 + * this is silly, there is no need to reparse the message that we just built.
48077 + *
48078 + */
48079 + if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
48080 + ERROR(
48081 + "pfkey_msg_build: "
48082 + "Trouble parsing newly built pfkey message, error=%d.\n",
48083 + error);
48084 + SENDERR(-error);
48085 + }
48086 +#endif
48087 +
48088 +errlab:
48089 +
48090 + return error;
48091 +}
48092 +
48093 +/*
48094 + * $Log: pfkey_v2_build.c,v $
48095 + * Revision 1.51.8.1 2006/05/01 14:36:39 mcr
48096 + * get rid of dead code.
48097 + *
48098 + * Revision 1.51 2004/10/03 01:26:36 mcr
48099 + * fixes for gcc 3.4 compilation.
48100 + *
48101 + * Revision 1.50 2004/07/10 07:48:35 mcr
48102 + * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
48103 + *
48104 + * Revision 1.49 2004/04/12 02:59:06 mcr
48105 + * erroneously moved pfkey_v2_build.c
48106 + *
48107 + * Revision 1.48 2004/04/09 18:00:40 mcr
48108 + * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
48109 + *
48110 + * Revision 1.47 2004/03/08 01:59:08 ken
48111 + * freeswan.h -> openswan.h
48112 + *
48113 + * Revision 1.46 2003/12/10 01:20:19 mcr
48114 + * NAT-traversal patches to KLIPS.
48115 + *
48116 + * Revision 1.45 2003/12/04 23:01:12 mcr
48117 + * removed ipsec_netlink.h
48118 + *
48119 + * Revision 1.44 2003/10/31 02:27:12 mcr
48120 + * pulled up port-selector patches and sa_id elimination.
48121 + *
48122 + * Revision 1.43.4.2 2003/10/29 01:11:32 mcr
48123 + * added debugging for pfkey library.
48124 + *
48125 + * Revision 1.43.4.1 2003/09/21 13:59:44 mcr
48126 + * pre-liminary X.509 patch - does not yet pass tests.
48127 + *
48128 + * Revision 1.43 2003/05/07 17:29:17 mcr
48129 + * new function pfkey_debug_func added for us in debugging from
48130 + * pfkey library.
48131 + *
48132 + * Revision 1.42 2003/01/30 02:32:09 rgb
48133 + *
48134 + * Rename SAref table macro names for clarity.
48135 + * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
48136 + *
48137 + * Revision 1.41 2002/12/13 18:16:02 mcr
48138 + * restored sa_ref code
48139 + *
48140 + * Revision 1.40 2002/12/13 18:06:52 mcr
48141 + * temporarily removed sadb_x_sa_ref reference for 2.xx
48142 + *
48143 + * Revision 1.39 2002/12/13 17:43:28 mcr
48144 + * commented out access to sadb_x_sa_ref for 2.xx branch
48145 + *
48146 + * Revision 1.38 2002/10/09 03:12:05 dhr
48147 + *
48148 + * [kenb+dhr] 64-bit fixes
48149 + *
48150 + * Revision 1.37 2002/09/20 15:40:39 rgb
48151 + * Added new function pfkey_sa_ref_build() to accomodate saref parameter.
48152 + *
48153 + * Revision 1.36 2002/09/20 05:01:22 rgb
48154 + * Generalise for platform independance: fix (ia64) using unsigned for sizes.
48155 + *
48156 + * Revision 1.35 2002/07/24 18:44:54 rgb
48157 + * Type fiddling to tame ia64 compiler.
48158 + *
48159 + * Revision 1.34 2002/05/23 07:14:11 rgb
48160 + * Cleaned up %p variants to 0p%p for test suite cleanup.
48161 + *
48162 + * Revision 1.33 2002/04/24 07:55:32 mcr
48163 + * #include patches and Makefiles for post-reorg compilation.
48164 + *
48165 + * Revision 1.32 2002/04/24 07:36:40 mcr
48166 + * Moved from ./lib/pfkey_v2_build.c,v
48167 + *
48168 + * Revision 1.31 2002/01/29 22:25:35 rgb
48169 + * Re-add ipsec_kversion.h to keep MALLOC happy.
48170 + *
48171 + * Revision 1.30 2002/01/29 01:59:09 mcr
48172 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
48173 + * updating of IPv6 structures to match latest in6.h version.
48174 + * removed dead code from openswan.h that also duplicated kversions.h
48175 + * code.
48176 + *
48177 + * Revision 1.29 2001/12/19 21:06:09 rgb
48178 + * Added port numbers to pfkey_address_build() debugging.
48179 + *
48180 + * Revision 1.28 2001/11/06 19:47:47 rgb
48181 + * Added packet parameter to lifetime and comb structures.
48182 + *
48183 + * Revision 1.27 2001/10/18 04:45:24 rgb
48184 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
48185 + * lib/openswan.h version macros moved to lib/kversions.h.
48186 + * Other compiler directive cleanups.
48187 + *
48188 + * Revision 1.26 2001/09/08 21:13:34 rgb
48189 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
48190 + *
48191 + * Revision 1.25 2001/06/14 19:35:16 rgb
48192 + * Update copyright date.
48193 + *
48194 + * Revision 1.24 2001/03/20 03:49:45 rgb
48195 + * Ditch superfluous debug_pfkey declaration.
48196 + * Move misplaced openswan.h inclusion for kernel case.
48197 + *
48198 + * Revision 1.23 2001/03/16 07:41:50 rgb
48199 + * Put openswan.h include before pluto includes.
48200 + *
48201 + * Revision 1.22 2001/02/27 22:24:56 rgb
48202 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
48203 + * Check for satoa() return codes.
48204 + *
48205 + * Revision 1.21 2000/11/17 18:10:30 rgb
48206 + * Fixed bugs mostly relating to spirange, to treat all spi variables as
48207 + * network byte order since this is the way PF_KEYv2 stored spis.
48208 + *
48209 + * Revision 1.20 2000/10/12 00:02:39 rgb
48210 + * Removed 'format, ##' nonsense from debug macros for RH7.0.
48211 + *
48212 + * Revision 1.19 2000/10/10 20:10:20 rgb
48213 + * Added support for debug_ipcomp and debug_verbose to klipsdebug.
48214 + *
48215 + * Revision 1.18 2000/09/12 18:59:54 rgb
48216 + * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
48217 + *
48218 + * Revision 1.17 2000/09/12 03:27:00 rgb
48219 + * Moved DEBUGGING definition to compile kernel with debug off.
48220 + *
48221 + * Revision 1.16 2000/09/08 19:22:12 rgb
48222 + * Fixed pfkey_prop_build() parameter to be only single indirection.
48223 + * Fixed struct alg copy.
48224 + *
48225 + * Revision 1.15 2000/08/20 21:40:01 rgb
48226 + * Added an address parameter sanity check to pfkey_address_build().
48227 + *
48228 + * Revision 1.14 2000/08/15 17:29:23 rgb
48229 + * Fixes from SZI to untested pfkey_prop_build().
48230 + *
48231 + * Revision 1.13 2000/06/02 22:54:14 rgb
48232 + * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
48233 + *
48234 + * Revision 1.12 2000/05/10 19:24:01 rgb
48235 + * Fleshed out sensitivity, proposal and supported extensions.
48236 + *
48237 + * Revision 1.11 2000/03/16 14:07:23 rgb
48238 + * Renamed ALIGN macro to avoid fighting with others in kernel.
48239 + *
48240 + * Revision 1.10 2000/01/24 21:14:35 rgb
48241 + * Added disabled pluto pfkey lib debug flag.
48242 + *
48243 + * Revision 1.9 2000/01/21 06:27:32 rgb
48244 + * Added address cases for eroute flows.
48245 + * Removed unused code.
48246 + * Dropped unused argument to pfkey_x_satype_build().
48247 + * Indented compiler directives for readability.
48248 + * Added klipsdebug switching capability.
48249 + * Fixed SADB_EXT_MAX bug not permitting last extension access.
48250 + *
48251 + * Revision 1.8 1999/12/29 21:17:41 rgb
48252 + * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
48253 + * parameter for cleaner manipulation of extensions[] and to guard
48254 + * against potential memory leaks.
48255 + * Changed the I/F to pfkey_msg_free() for the same reason.
48256 + *
48257 + * Revision 1.7 1999/12/09 23:12:20 rgb
48258 + * Removed unused cruft.
48259 + * Added argument to pfkey_sa_build() to do eroutes.
48260 + * Fixed exttype check in as yet unused pfkey_lifetime_build().
48261 + *
48262 + * Revision 1.6 1999/12/07 19:54:29 rgb
48263 + * Removed static pluto debug flag.
48264 + * Added functions for pfkey message and extensions initialisation
48265 + * and cleanup.
48266 + *
48267 + * Revision 1.5 1999/12/01 22:20:06 rgb
48268 + * Changed pfkey_sa_build to accept an SPI in network byte order.
48269 + * Added <string.h> to quiet userspace compiler.
48270 + * Moved pfkey_lib_debug variable into the library.
48271 + * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
48272 + * Added extension assembly debugging.
48273 + * Isolated assignment with brackets to be sure of scope.
48274 + *
48275 + * Revision 1.4 1999/11/27 11:57:35 rgb
48276 + * Added ipv6 headers.
48277 + * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
48278 + * Debugging error messages added.
48279 + * Fixed missing auth and encrypt assignment bug.
48280 + * Add argument to pfkey_msg_parse() for direction.
48281 + * Move parse-after-build check inside pfkey_msg_build().
48282 + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
48283 + * Add CVS log entry to bottom of file.
48284 + *
48285 + */
48286 --- /dev/null Tue Mar 11 13:02:56 2003
48287 +++ linux/net/ipsec/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004
48288 @@ -0,0 +1,181 @@
48289 +/*
48290 + * @(#) pfkey version 2 debugging messages
48291 + *
48292 + * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org>
48293 + * and Michael Richardson <mcr@openswan.org>
48294 + *
48295 + * This program is free software; you can redistribute it and/or modify it
48296 + * under the terms of the GNU General Public License as published by the
48297 + * Free Software Foundation; either version 2 of the License, or (at your
48298 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
48299 + *
48300 + * This program is distributed in the hope that it will be useful, but
48301 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48302 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48303 + * for more details.
48304 + *
48305 + * RCSID $Id: pfkey_v2_debug.c,v 1.11 2005/04/06 17:45:16 mcr Exp $
48306 + *
48307 + */
48308 +
48309 +#ifdef __KERNEL__
48310 +
48311 +# include <linux/kernel.h> /* for printk */
48312 +
48313 +# include "openswan/ipsec_kversion.h" /* for malloc switch */
48314 +# ifdef MALLOC_SLAB
48315 +# include <linux/slab.h> /* kmalloc() */
48316 +# else /* MALLOC_SLAB */
48317 +# include <linux/malloc.h> /* kmalloc() */
48318 +# endif /* MALLOC_SLAB */
48319 +# include <linux/errno.h> /* error codes */
48320 +# include <linux/types.h> /* size_t */
48321 +# include <linux/interrupt.h> /* mark_bh */
48322 +
48323 +# include <linux/netdevice.h> /* struct device, and other headers */
48324 +# include <linux/etherdevice.h> /* eth_type_trans */
48325 +extern int debug_pfkey;
48326 +
48327 +#else /* __KERNEL__ */
48328 +
48329 +# include <sys/types.h>
48330 +# include <linux/types.h>
48331 +# include <linux/errno.h>
48332 +
48333 +#endif /* __KERNEL__ */
48334 +
48335 +#include "openswan.h"
48336 +#include "pfkeyv2.h"
48337 +#include "pfkey.h"
48338 +
48339 +/*
48340 + * This file provides ASCII translations of PF_KEY magic numbers.
48341 + *
48342 + */
48343 +
48344 +static char *pfkey_sadb_ext_strings[]={
48345 + "reserved", /* SADB_EXT_RESERVED 0 */
48346 + "security-association", /* SADB_EXT_SA 1 */
48347 + "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */
48348 + "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */
48349 + "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */
48350 + "source-address", /* SADB_EXT_ADDRESS_SRC 5 */
48351 + "destination-address", /* SADB_EXT_ADDRESS_DST 6 */
48352 + "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */
48353 + "authentication-key", /* SADB_EXT_KEY_AUTH 8 */
48354 + "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */
48355 + "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */
48356 + "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */
48357 + "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */
48358 + "proposal", /* SADB_EXT_PROPOSAL 13 */
48359 + "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */
48360 + "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */
48361 + "spi-range", /* SADB_EXT_SPIRANGE 16 */
48362 + "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */
48363 + "X-satype2", /* SADB_X_EXT_SATYPE2 18 */
48364 + "X-security-association", /* SADB_X_EXT_SA2 19 */
48365 + "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */
48366 + "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
48367 + "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */
48368 + "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */
48369 + "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */
48370 + "X-set-debug", /* SADB_X_EXT_DEBUG 25 */
48371 + /* NAT_TRAVERSAL */
48372 + "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */
48373 + "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */
48374 + "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */
48375 + "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */
48376 +};
48377 +
48378 +const char *
48379 +pfkey_v2_sadb_ext_string(int ext)
48380 +{
48381 + if(ext <= SADB_EXT_MAX) {
48382 + return pfkey_sadb_ext_strings[ext];
48383 + } else {
48384 + return "unknown-ext";
48385 + }
48386 +}
48387 +
48388 +
48389 +static char *pfkey_sadb_type_strings[]={
48390 + "reserved", /* SADB_RESERVED */
48391 + "getspi", /* SADB_GETSPI */
48392 + "update", /* SADB_UPDATE */
48393 + "add", /* SADB_ADD */
48394 + "delete", /* SADB_DELETE */
48395 + "get", /* SADB_GET */
48396 + "acquire", /* SADB_ACQUIRE */
48397 + "register", /* SADB_REGISTER */
48398 + "expire", /* SADB_EXPIRE */
48399 + "flush", /* SADB_FLUSH */
48400 + "dump", /* SADB_DUMP */
48401 + "x-promisc", /* SADB_X_PROMISC */
48402 + "x-pchange", /* SADB_X_PCHANGE */
48403 + "x-groupsa", /* SADB_X_GRPSA */
48404 + "x-addflow(eroute)", /* SADB_X_ADDFLOW */
48405 + "x-delflow(eroute)", /* SADB_X_DELFLOW */
48406 + "x-debug", /* SADB_X_DEBUG */
48407 +};
48408 +
48409 +const char *
48410 +pfkey_v2_sadb_type_string(int sadb_type)
48411 +{
48412 + if(sadb_type <= SADB_MAX) {
48413 + return pfkey_sadb_type_strings[sadb_type];
48414 + } else {
48415 + return "unknown-sadb-type";
48416 + }
48417 +}
48418 +
48419 +
48420 +
48421 +
48422 +/*
48423 + * $Log: pfkey_v2_debug.c,v $
48424 + * Revision 1.11 2005/04/06 17:45:16 mcr
48425 + * always include NAT-T names.
48426 + *
48427 + * Revision 1.10 2004/07/10 07:48:35 mcr
48428 + * Moved from linux/lib/libfreeswan/pfkey_v2_debug.c,v
48429 + *
48430 + * Revision 1.9 2004/03/08 01:59:08 ken
48431 + * freeswan.h -> openswan.h
48432 + *
48433 + * Revision 1.8 2003/12/10 01:20:19 mcr
48434 + * NAT-traversal patches to KLIPS.
48435 + *
48436 + * Revision 1.7 2002/09/20 05:01:26 rgb
48437 + * Fixed limit inclusion error in both type and ext string conversion.
48438 + *
48439 + * Revision 1.6 2002/04/24 07:55:32 mcr
48440 + * #include patches and Makefiles for post-reorg compilation.
48441 + *
48442 + * Revision 1.5 2002/04/24 07:36:40 mcr
48443 + * Moved from ./lib/pfkey_v2_debug.c,v
48444 + *
48445 + * Revision 1.4 2002/01/29 22:25:36 rgb
48446 + * Re-add ipsec_kversion.h to keep MALLOC happy.
48447 + *
48448 + * Revision 1.3 2002/01/29 01:59:09 mcr
48449 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
48450 + * updating of IPv6 structures to match latest in6.h version.
48451 + * removed dead code from openswan.h that also duplicated kversions.h
48452 + * code.
48453 + *
48454 + * Revision 1.2 2002/01/20 20:34:50 mcr
48455 + * added pfkey_v2_sadb_type_string to decode sadb_type to string.
48456 + *
48457 + * Revision 1.1 2001/11/27 05:30:06 mcr
48458 + * initial set of debug strings for pfkey debugging.
48459 + * this will eventually only be included for debug builds.
48460 + *
48461 + * Revision 1.1 2001/09/21 04:12:03 mcr
48462 + * first compilable version.
48463 + *
48464 + *
48465 + * Local variables:
48466 + * c-file-style: "linux"
48467 + * End:
48468 + *
48469 + */
48470 --- /dev/null Tue Mar 11 13:02:56 2003
48471 +++ linux/net/ipsec/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004
48472 @@ -0,0 +1,814 @@
48473 +/*
48474 + * RFC2367 PF_KEYv2 Key management API message parser
48475 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
48476 + *
48477 + * This program is free software; you can redistribute it and/or modify it
48478 + * under the terms of the GNU General Public License as published by the
48479 + * Free Software Foundation; either version 2 of the License, or (at your
48480 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
48481 + *
48482 + * This program is distributed in the hope that it will be useful, but
48483 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48484 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
48485 + * for more details.
48486 + *
48487 + * RCSID $Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $
48488 + */
48489 +
48490 +/*
48491 + * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
48492 + */
48493 +
48494 +char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.22 2005/05/11 01:45:31 mcr Exp $";
48495 +
48496 +/*
48497 + * Some ugly stuff to allow consistent debugging code for use in the
48498 + * kernel and in user space
48499 +*/
48500 +
48501 +#ifdef __KERNEL__
48502 +
48503 +# include <linux/kernel.h> /* for printk */
48504 +
48505 +# include "openswan/ipsec_kversion.h" /* for malloc switch */
48506 +# ifdef MALLOC_SLAB
48507 +# include <linux/slab.h> /* kmalloc() */
48508 +# else /* MALLOC_SLAB */
48509 +# include <linux/malloc.h> /* kmalloc() */
48510 +# endif /* MALLOC_SLAB */
48511 +# include <linux/errno.h> /* error codes */
48512 +# include <linux/types.h> /* size_t */
48513 +# include <linux/interrupt.h> /* mark_bh */
48514 +
48515 +# include <linux/netdevice.h> /* struct device, and other headers */
48516 +# include <linux/etherdevice.h> /* eth_type_trans */
48517 +# include <linux/ip.h> /* struct iphdr */
48518 +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
48519 +# include <linux/ipv6.h>
48520 +# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
48521 +
48522 +#else /* __KERNEL__ */
48523 +
48524 +# include <sys/types.h>
48525 +# include <linux/types.h>
48526 +# include <linux/errno.h>
48527 +#endif
48528 +
48529 +#include <openswan.h>
48530 +#include <pfkeyv2.h>
48531 +#include <pfkey.h>
48532 +
48533 +unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_EXTENSIONS_MAX] = {
48534 +
48535 +/* INBOUND EXTENSIONS */
48536 +{
48537 +
48538 +/* PERMITTED IN */
48539 +{
48540 +/* SADB_RESERVED */
48541 +0
48542 +,
48543 +/* SADB_GETSPI */
48544 +1<<SADB_EXT_RESERVED
48545 +| 1<<SADB_EXT_ADDRESS_SRC
48546 +| 1<<SADB_EXT_ADDRESS_DST
48547 +| 1<<SADB_EXT_ADDRESS_PROXY
48548 +| 1<<SADB_EXT_SPIRANGE
48549 +,
48550 +/* SADB_UPDATE */
48551 +1<<SADB_EXT_RESERVED
48552 +| 1<<SADB_EXT_SA
48553 +| 1<<SADB_EXT_LIFETIME_CURRENT
48554 +| 1<<SADB_EXT_LIFETIME_HARD
48555 +| 1<<SADB_EXT_LIFETIME_SOFT
48556 +| 1<<SADB_EXT_ADDRESS_SRC
48557 +| 1<<SADB_EXT_ADDRESS_DST
48558 +| 1<<SADB_EXT_ADDRESS_PROXY
48559 +| 1<<SADB_EXT_KEY_AUTH
48560 +| 1<<SADB_EXT_KEY_ENCRYPT
48561 +| 1<<SADB_EXT_IDENTITY_SRC
48562 +| 1<<SADB_EXT_IDENTITY_DST
48563 +| 1<<SADB_EXT_SENSITIVITY
48564 +| 1<<SADB_X_EXT_NAT_T_SPORT
48565 +| 1<<SADB_X_EXT_NAT_T_DPORT
48566 +,
48567 +/* SADB_ADD */
48568 +1<<SADB_EXT_RESERVED
48569 +| 1<<SADB_EXT_SA
48570 +| 1<<SADB_EXT_LIFETIME_HARD
48571 +| 1<<SADB_EXT_LIFETIME_SOFT
48572 +| 1<<SADB_EXT_ADDRESS_SRC
48573 +| 1<<SADB_EXT_ADDRESS_DST
48574 +| 1<<SADB_EXT_ADDRESS_PROXY
48575 +| 1<<SADB_EXT_KEY_AUTH
48576 +| 1<<SADB_EXT_KEY_ENCRYPT
48577 +| 1<<SADB_EXT_IDENTITY_SRC
48578 +| 1<<SADB_EXT_IDENTITY_DST
48579 +| 1<<SADB_EXT_SENSITIVITY
48580 +| 1<<SADB_X_EXT_NAT_T_TYPE
48581 +| 1<<SADB_X_EXT_NAT_T_SPORT
48582 +| 1<<SADB_X_EXT_NAT_T_DPORT
48583 +| 1<<SADB_X_EXT_NAT_T_OA
48584 +,
48585 +/* SADB_DELETE */
48586 +1<<SADB_EXT_RESERVED
48587 +| 1<<SADB_EXT_SA
48588 +| 1<<SADB_EXT_ADDRESS_SRC
48589 +| 1<<SADB_EXT_ADDRESS_DST
48590 +,
48591 +/* SADB_GET */
48592 +1<<SADB_EXT_RESERVED
48593 +| 1<<SADB_EXT_SA
48594 +| 1<<SADB_EXT_ADDRESS_SRC
48595 +| 1<<SADB_EXT_ADDRESS_DST
48596 +,
48597 +/* SADB_ACQUIRE */
48598 +1<<SADB_EXT_RESERVED
48599 +| 1<<SADB_EXT_ADDRESS_SRC
48600 +| 1<<SADB_EXT_ADDRESS_DST
48601 +| 1<<SADB_EXT_ADDRESS_PROXY
48602 +| 1<<SADB_EXT_IDENTITY_SRC
48603 +| 1<<SADB_EXT_IDENTITY_DST
48604 +| 1<<SADB_EXT_SENSITIVITY
48605 +| 1<<SADB_EXT_PROPOSAL
48606 +,
48607 +/* SADB_REGISTER */
48608 +1<<SADB_EXT_RESERVED
48609 +,
48610 +/* SADB_EXPIRE */
48611 +0
48612 +,
48613 +/* SADB_FLUSH */
48614 +1<<SADB_EXT_RESERVED
48615 +,
48616 +/* SADB_DUMP */
48617 +1<<SADB_EXT_RESERVED
48618 +,
48619 +/* SADB_X_PROMISC */
48620 +1<<SADB_EXT_RESERVED
48621 +| 1<<SADB_EXT_SA
48622 +| 1<<SADB_EXT_LIFETIME_CURRENT
48623 +| 1<<SADB_EXT_LIFETIME_HARD
48624 +| 1<<SADB_EXT_LIFETIME_SOFT
48625 +| 1<<SADB_EXT_ADDRESS_SRC
48626 +| 1<<SADB_EXT_ADDRESS_DST
48627 +| 1<<SADB_EXT_ADDRESS_PROXY
48628 +| 1<<SADB_EXT_KEY_AUTH
48629 +| 1<<SADB_EXT_KEY_ENCRYPT
48630 +| 1<<SADB_EXT_IDENTITY_SRC
48631 +| 1<<SADB_EXT_IDENTITY_DST
48632 +| 1<<SADB_EXT_SENSITIVITY
48633 +| 1<<SADB_EXT_PROPOSAL
48634 +| 1<<SADB_EXT_SUPPORTED_AUTH
48635 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48636 +| 1<<SADB_EXT_SPIRANGE
48637 +| 1<<SADB_X_EXT_KMPRIVATE
48638 +| 1<<SADB_X_EXT_SATYPE2
48639 +| 1<<SADB_X_EXT_SA2
48640 +| 1<<SADB_X_EXT_ADDRESS_DST2
48641 +,
48642 +/* SADB_X_PCHANGE */
48643 +1<<SADB_EXT_RESERVED
48644 +| 1<<SADB_EXT_SA
48645 +| 1<<SADB_EXT_LIFETIME_CURRENT
48646 +| 1<<SADB_EXT_LIFETIME_HARD
48647 +| 1<<SADB_EXT_LIFETIME_SOFT
48648 +| 1<<SADB_EXT_ADDRESS_SRC
48649 +| 1<<SADB_EXT_ADDRESS_DST
48650 +| 1<<SADB_EXT_ADDRESS_PROXY
48651 +| 1<<SADB_EXT_KEY_AUTH
48652 +| 1<<SADB_EXT_KEY_ENCRYPT
48653 +| 1<<SADB_EXT_IDENTITY_SRC
48654 +| 1<<SADB_EXT_IDENTITY_DST
48655 +| 1<<SADB_EXT_SENSITIVITY
48656 +| 1<<SADB_EXT_PROPOSAL
48657 +| 1<<SADB_EXT_SUPPORTED_AUTH
48658 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48659 +| 1<<SADB_EXT_SPIRANGE
48660 +| 1<<SADB_X_EXT_KMPRIVATE
48661 +| 1<<SADB_X_EXT_SATYPE2
48662 +| 1<<SADB_X_EXT_SA2
48663 +| 1<<SADB_X_EXT_ADDRESS_DST2
48664 +,
48665 +/* SADB_X_GRPSA */
48666 +1<<SADB_EXT_RESERVED
48667 +| 1<<SADB_EXT_SA
48668 +| 1<<SADB_EXT_ADDRESS_DST
48669 +| 1<<SADB_X_EXT_SATYPE2
48670 +| 1<<SADB_X_EXT_SA2
48671 +| 1<<SADB_X_EXT_ADDRESS_DST2
48672 +,
48673 +/* SADB_X_ADDFLOW */
48674 +1<<SADB_EXT_RESERVED
48675 +| 1<<SADB_EXT_SA
48676 +| 1<<SADB_EXT_ADDRESS_SRC
48677 +| 1<<SADB_EXT_ADDRESS_DST
48678 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48679 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48680 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48681 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48682 +| 1<<SADB_EXT_IDENTITY_SRC
48683 +| 1<<SADB_EXT_IDENTITY_DST
48684 +| 1<<SADB_X_EXT_PROTOCOL
48685 +,
48686 +/* SADB_X_DELFLOW */
48687 +1<<SADB_EXT_RESERVED
48688 +| 1<<SADB_EXT_SA
48689 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48690 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48691 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48692 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48693 +| 1<<SADB_EXT_IDENTITY_SRC
48694 +| 1<<SADB_EXT_IDENTITY_DST
48695 +| 1<<SADB_X_EXT_PROTOCOL
48696 +,
48697 +/* SADB_X_DEBUG */
48698 +1<<SADB_EXT_RESERVED
48699 +| 1<<SADB_X_EXT_DEBUG
48700 +,
48701 +/* SADB_X_NAT_T_NEW_MAPPING */
48702 +1<<SADB_EXT_RESERVED
48703 +| 1<<SADB_EXT_SA
48704 +| 1<<SADB_EXT_ADDRESS_SRC
48705 +| 1<<SADB_EXT_ADDRESS_DST
48706 +| 1<<SADB_X_EXT_NAT_T_SPORT
48707 +| 1<<SADB_X_EXT_NAT_T_DPORT
48708 +},
48709 +
48710 +/* REQUIRED IN */
48711 +{
48712 +/* SADB_RESERVED */
48713 +0
48714 +,
48715 +/* SADB_GETSPI */
48716 +1<<SADB_EXT_RESERVED
48717 +| 1<<SADB_EXT_ADDRESS_SRC
48718 +| 1<<SADB_EXT_ADDRESS_DST
48719 +| 1<<SADB_EXT_SPIRANGE
48720 +,
48721 +/* SADB_UPDATE */
48722 +1<<SADB_EXT_RESERVED
48723 +| 1<<SADB_EXT_SA
48724 +| 1<<SADB_EXT_ADDRESS_SRC
48725 +| 1<<SADB_EXT_ADDRESS_DST
48726 +/*| 1<<SADB_EXT_KEY_AUTH*/
48727 +/*| 1<<SADB_EXT_KEY_ENCRYPT*/
48728 +,
48729 +/* SADB_ADD */
48730 +1<<SADB_EXT_RESERVED
48731 +| 1<<SADB_EXT_SA
48732 +| 1<<SADB_EXT_ADDRESS_SRC
48733 +| 1<<SADB_EXT_ADDRESS_DST
48734 +/*| 1<<SADB_EXT_KEY_AUTH*/
48735 +/*| 1<<SADB_EXT_KEY_ENCRYPT*/
48736 +,
48737 +/* SADB_DELETE */
48738 +1<<SADB_EXT_RESERVED
48739 +| 1<<SADB_EXT_SA
48740 +| 1<<SADB_EXT_ADDRESS_SRC
48741 +| 1<<SADB_EXT_ADDRESS_DST
48742 +,
48743 +/* SADB_GET */
48744 +1<<SADB_EXT_RESERVED
48745 +| 1<<SADB_EXT_SA
48746 +| 1<<SADB_EXT_ADDRESS_SRC
48747 +| 1<<SADB_EXT_ADDRESS_DST
48748 +,
48749 +/* SADB_ACQUIRE */
48750 +1<<SADB_EXT_RESERVED
48751 +| 1<<SADB_EXT_ADDRESS_SRC
48752 +| 1<<SADB_EXT_ADDRESS_DST
48753 +| 1<<SADB_EXT_PROPOSAL
48754 +,
48755 +/* SADB_REGISTER */
48756 +1<<SADB_EXT_RESERVED
48757 +,
48758 +/* SADB_EXPIRE */
48759 +0
48760 +,
48761 +/* SADB_FLUSH */
48762 +1<<SADB_EXT_RESERVED
48763 +,
48764 +/* SADB_DUMP */
48765 +1<<SADB_EXT_RESERVED
48766 +,
48767 +/* SADB_X_PROMISC */
48768 +1<<SADB_EXT_RESERVED
48769 +| 1<<SADB_EXT_SA
48770 +| 1<<SADB_EXT_LIFETIME_CURRENT
48771 +| 1<<SADB_EXT_LIFETIME_HARD
48772 +| 1<<SADB_EXT_LIFETIME_SOFT
48773 +| 1<<SADB_EXT_ADDRESS_SRC
48774 +| 1<<SADB_EXT_ADDRESS_DST
48775 +| 1<<SADB_EXT_ADDRESS_PROXY
48776 +| 1<<SADB_EXT_KEY_AUTH
48777 +| 1<<SADB_EXT_KEY_ENCRYPT
48778 +| 1<<SADB_EXT_IDENTITY_SRC
48779 +| 1<<SADB_EXT_IDENTITY_DST
48780 +| 1<<SADB_EXT_SENSITIVITY
48781 +| 1<<SADB_EXT_PROPOSAL
48782 +| 1<<SADB_EXT_SUPPORTED_AUTH
48783 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48784 +| 1<<SADB_EXT_SPIRANGE
48785 +| 1<<SADB_X_EXT_KMPRIVATE
48786 +| 1<<SADB_X_EXT_SATYPE2
48787 +| 1<<SADB_X_EXT_SA2
48788 +| 1<<SADB_X_EXT_ADDRESS_DST2
48789 +,
48790 +/* SADB_X_PCHANGE */
48791 +1<<SADB_EXT_RESERVED
48792 +| 1<<SADB_EXT_SA
48793 +| 1<<SADB_EXT_LIFETIME_CURRENT
48794 +| 1<<SADB_EXT_LIFETIME_HARD
48795 +| 1<<SADB_EXT_LIFETIME_SOFT
48796 +| 1<<SADB_EXT_ADDRESS_SRC
48797 +| 1<<SADB_EXT_ADDRESS_DST
48798 +| 1<<SADB_EXT_ADDRESS_PROXY
48799 +| 1<<SADB_EXT_KEY_AUTH
48800 +| 1<<SADB_EXT_KEY_ENCRYPT
48801 +| 1<<SADB_EXT_IDENTITY_SRC
48802 +| 1<<SADB_EXT_IDENTITY_DST
48803 +| 1<<SADB_EXT_SENSITIVITY
48804 +| 1<<SADB_EXT_PROPOSAL
48805 +| 1<<SADB_EXT_SUPPORTED_AUTH
48806 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48807 +| 1<<SADB_EXT_SPIRANGE
48808 +| 1<<SADB_X_EXT_KMPRIVATE
48809 +| 1<<SADB_X_EXT_SATYPE2
48810 +| 1<<SADB_X_EXT_SA2
48811 +| 1<<SADB_X_EXT_ADDRESS_DST2
48812 +,
48813 +/* SADB_X_GRPSA */
48814 +1<<SADB_EXT_RESERVED
48815 +| 1<<SADB_EXT_SA
48816 +| 1<<SADB_EXT_ADDRESS_DST
48817 +/*| 1<<SADB_X_EXT_SATYPE2*/
48818 +/*| 1<<SADB_X_EXT_SA2*/
48819 +/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
48820 +,
48821 +/* SADB_X_ADDFLOW */
48822 +1<<SADB_EXT_RESERVED
48823 +| 1<<SADB_EXT_SA
48824 +| 1<<SADB_EXT_ADDRESS_DST
48825 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48826 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48827 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48828 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48829 +,
48830 +/* SADB_X_DELFLOW */
48831 +1<<SADB_EXT_RESERVED
48832 +/*| 1<<SADB_EXT_SA*/
48833 +#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
48834 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
48835 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
48836 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
48837 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
48838 +#endif
48839 +,
48840 +/* SADB_X_DEBUG */
48841 +1<<SADB_EXT_RESERVED
48842 +| 1<<SADB_X_EXT_DEBUG
48843 +,
48844 +/* SADB_X_NAT_T_NEW_MAPPING */
48845 +1<<SADB_EXT_RESERVED
48846 +| 1<<SADB_EXT_SA
48847 +| 1<<SADB_EXT_ADDRESS_SRC
48848 +| 1<<SADB_EXT_ADDRESS_DST
48849 +| 1<<SADB_X_EXT_NAT_T_SPORT
48850 +| 1<<SADB_X_EXT_NAT_T_DPORT
48851 +}
48852 +
48853 +},
48854 +
48855 +/* OUTBOUND EXTENSIONS */
48856 +{
48857 +
48858 +/* PERMITTED OUT */
48859 +{
48860 +/* SADB_RESERVED */
48861 +0
48862 +,
48863 +/* SADB_GETSPI */
48864 +1<<SADB_EXT_RESERVED
48865 +| 1<<SADB_EXT_SA
48866 +| 1<<SADB_EXT_ADDRESS_SRC
48867 +| 1<<SADB_EXT_ADDRESS_DST
48868 +,
48869 +/* SADB_UPDATE */
48870 +1<<SADB_EXT_RESERVED
48871 +| 1<<SADB_EXT_SA
48872 +| 1<<SADB_EXT_LIFETIME_CURRENT
48873 +| 1<<SADB_EXT_LIFETIME_HARD
48874 +| 1<<SADB_EXT_LIFETIME_SOFT
48875 +| 1<<SADB_EXT_ADDRESS_SRC
48876 +| 1<<SADB_EXT_ADDRESS_DST
48877 +| 1<<SADB_EXT_ADDRESS_PROXY
48878 +| 1<<SADB_EXT_IDENTITY_SRC
48879 +| 1<<SADB_EXT_IDENTITY_DST
48880 +| 1<<SADB_EXT_SENSITIVITY
48881 +| 1<<SADB_X_EXT_NAT_T_SPORT
48882 +| 1<<SADB_X_EXT_NAT_T_DPORT
48883 +,
48884 +/* SADB_ADD */
48885 +1<<SADB_EXT_RESERVED
48886 +| 1<<SADB_EXT_SA
48887 +| 1<<SADB_EXT_LIFETIME_HARD
48888 +| 1<<SADB_EXT_LIFETIME_SOFT
48889 +| 1<<SADB_EXT_ADDRESS_SRC
48890 +| 1<<SADB_EXT_ADDRESS_DST
48891 +| 1<<SADB_EXT_IDENTITY_SRC
48892 +| 1<<SADB_EXT_IDENTITY_DST
48893 +| 1<<SADB_EXT_SENSITIVITY
48894 +| 1<<SADB_X_EXT_NAT_T_TYPE
48895 +| 1<<SADB_X_EXT_NAT_T_SPORT
48896 +| 1<<SADB_X_EXT_NAT_T_DPORT
48897 +| 1<<SADB_X_EXT_NAT_T_OA
48898 +,
48899 +/* SADB_DELETE */
48900 +1<<SADB_EXT_RESERVED
48901 +| 1<<SADB_EXT_SA
48902 +| 1<<SADB_EXT_ADDRESS_SRC
48903 +| 1<<SADB_EXT_ADDRESS_DST
48904 +,
48905 +/* SADB_GET */
48906 +1<<SADB_EXT_RESERVED
48907 +| 1<<SADB_EXT_SA
48908 +| 1<<SADB_EXT_LIFETIME_CURRENT
48909 +| 1<<SADB_EXT_LIFETIME_HARD
48910 +| 1<<SADB_EXT_LIFETIME_SOFT
48911 +| 1<<SADB_EXT_ADDRESS_SRC
48912 +| 1<<SADB_EXT_ADDRESS_DST
48913 +| 1<<SADB_EXT_ADDRESS_PROXY
48914 +| 1<<SADB_EXT_KEY_AUTH
48915 +| 1<<SADB_EXT_KEY_ENCRYPT
48916 +| 1<<SADB_EXT_IDENTITY_SRC
48917 +| 1<<SADB_EXT_IDENTITY_DST
48918 +| 1<<SADB_EXT_SENSITIVITY
48919 +| 1<<SADB_X_EXT_NAT_T_TYPE
48920 +| 1<<SADB_X_EXT_NAT_T_SPORT
48921 +| 1<<SADB_X_EXT_NAT_T_DPORT
48922 +| 1<<SADB_X_EXT_NAT_T_OA
48923 +,
48924 +/* SADB_ACQUIRE */
48925 +1<<SADB_EXT_RESERVED
48926 +| 1<<SADB_EXT_ADDRESS_SRC
48927 +| 1<<SADB_EXT_ADDRESS_DST
48928 +| 1<<SADB_EXT_ADDRESS_PROXY
48929 +| 1<<SADB_EXT_IDENTITY_SRC
48930 +| 1<<SADB_EXT_IDENTITY_DST
48931 +| 1<<SADB_EXT_SENSITIVITY
48932 +| 1<<SADB_EXT_PROPOSAL
48933 +,
48934 +/* SADB_REGISTER */
48935 +1<<SADB_EXT_RESERVED
48936 +| 1<<SADB_EXT_SUPPORTED_AUTH
48937 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48938 +,
48939 +/* SADB_EXPIRE */
48940 +1<<SADB_EXT_RESERVED
48941 +| 1<<SADB_EXT_SA
48942 +| 1<<SADB_EXT_LIFETIME_CURRENT
48943 +| 1<<SADB_EXT_LIFETIME_HARD
48944 +| 1<<SADB_EXT_LIFETIME_SOFT
48945 +| 1<<SADB_EXT_ADDRESS_SRC
48946 +| 1<<SADB_EXT_ADDRESS_DST
48947 +,
48948 +/* SADB_FLUSH */
48949 +1<<SADB_EXT_RESERVED
48950 +,
48951 +/* SADB_DUMP */
48952 +1<<SADB_EXT_RESERVED
48953 +| 1<<SADB_EXT_SA
48954 +| 1<<SADB_EXT_LIFETIME_CURRENT
48955 +| 1<<SADB_EXT_LIFETIME_HARD
48956 +| 1<<SADB_EXT_LIFETIME_SOFT
48957 +| 1<<SADB_EXT_ADDRESS_SRC
48958 +| 1<<SADB_EXT_ADDRESS_DST
48959 +| 1<<SADB_EXT_ADDRESS_PROXY
48960 +| 1<<SADB_EXT_KEY_AUTH
48961 +| 1<<SADB_EXT_KEY_ENCRYPT
48962 +| 1<<SADB_EXT_IDENTITY_SRC
48963 +| 1<<SADB_EXT_IDENTITY_DST
48964 +| 1<<SADB_EXT_SENSITIVITY
48965 +| 1<<SADB_X_EXT_NAT_T_TYPE
48966 +| 1<<SADB_X_EXT_NAT_T_SPORT
48967 +| 1<<SADB_X_EXT_NAT_T_DPORT
48968 +| 1<<SADB_X_EXT_NAT_T_OA
48969 +,
48970 +/* SADB_X_PROMISC */
48971 +1<<SADB_EXT_RESERVED
48972 +| 1<<SADB_EXT_SA
48973 +| 1<<SADB_EXT_LIFETIME_CURRENT
48974 +| 1<<SADB_EXT_LIFETIME_HARD
48975 +| 1<<SADB_EXT_LIFETIME_SOFT
48976 +| 1<<SADB_EXT_ADDRESS_SRC
48977 +| 1<<SADB_EXT_ADDRESS_DST
48978 +| 1<<SADB_EXT_ADDRESS_PROXY
48979 +| 1<<SADB_EXT_KEY_AUTH
48980 +| 1<<SADB_EXT_KEY_ENCRYPT
48981 +| 1<<SADB_EXT_IDENTITY_SRC
48982 +| 1<<SADB_EXT_IDENTITY_DST
48983 +| 1<<SADB_EXT_SENSITIVITY
48984 +| 1<<SADB_EXT_PROPOSAL
48985 +| 1<<SADB_EXT_SUPPORTED_AUTH
48986 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
48987 +| 1<<SADB_EXT_SPIRANGE
48988 +| 1<<SADB_X_EXT_KMPRIVATE
48989 +| 1<<SADB_X_EXT_SATYPE2
48990 +| 1<<SADB_X_EXT_SA2
48991 +| 1<<SADB_X_EXT_ADDRESS_DST2
48992 +,
48993 +/* SADB_X_PCHANGE */
48994 +1<<SADB_EXT_RESERVED
48995 +| 1<<SADB_EXT_SA
48996 +| 1<<SADB_EXT_LIFETIME_CURRENT
48997 +| 1<<SADB_EXT_LIFETIME_HARD
48998 +| 1<<SADB_EXT_LIFETIME_SOFT
48999 +| 1<<SADB_EXT_ADDRESS_SRC
49000 +| 1<<SADB_EXT_ADDRESS_DST
49001 +| 1<<SADB_EXT_ADDRESS_PROXY
49002 +| 1<<SADB_EXT_KEY_AUTH
49003 +| 1<<SADB_EXT_KEY_ENCRYPT
49004 +| 1<<SADB_EXT_IDENTITY_SRC
49005 +| 1<<SADB_EXT_IDENTITY_DST
49006 +| 1<<SADB_EXT_SENSITIVITY
49007 +| 1<<SADB_EXT_PROPOSAL
49008 +| 1<<SADB_EXT_SUPPORTED_AUTH
49009 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49010 +| 1<<SADB_EXT_SPIRANGE
49011 +| 1<<SADB_X_EXT_KMPRIVATE
49012 +| 1<<SADB_X_EXT_SATYPE2
49013 +| 1<<SADB_X_EXT_SA2
49014 +| 1<<SADB_X_EXT_ADDRESS_DST2
49015 +,
49016 +/* SADB_X_GRPSA */
49017 +1<<SADB_EXT_RESERVED
49018 +| 1<<SADB_EXT_SA
49019 +| 1<<SADB_EXT_ADDRESS_DST
49020 +| 1<<SADB_X_EXT_SATYPE2
49021 +| 1<<SADB_X_EXT_SA2
49022 +| 1<<SADB_X_EXT_ADDRESS_DST2
49023 +,
49024 +/* SADB_X_ADDFLOW */
49025 +1<<SADB_EXT_RESERVED
49026 +| 1<<SADB_EXT_SA
49027 +| 1<<SADB_EXT_ADDRESS_SRC
49028 +| 1<<SADB_EXT_ADDRESS_DST
49029 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49030 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49031 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49032 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49033 +| 1<<SADB_X_EXT_PROTOCOL
49034 +,
49035 +/* SADB_X_DELFLOW */
49036 +1<<SADB_EXT_RESERVED
49037 +| 1<<SADB_EXT_SA
49038 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49039 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49040 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49041 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49042 +| 1<<SADB_X_EXT_PROTOCOL
49043 +,
49044 +/* SADB_X_DEBUG */
49045 +1<<SADB_EXT_RESERVED
49046 +| 1<<SADB_X_EXT_DEBUG
49047 +,
49048 +/* SADB_X_NAT_T_NEW_MAPPING */
49049 +1<<SADB_EXT_RESERVED
49050 +| 1<<SADB_EXT_SA
49051 +| 1<<SADB_EXT_ADDRESS_SRC
49052 +| 1<<SADB_EXT_ADDRESS_DST
49053 +| 1<<SADB_X_EXT_NAT_T_SPORT
49054 +| 1<<SADB_X_EXT_NAT_T_DPORT
49055 +},
49056 +
49057 +/* REQUIRED OUT */
49058 +{
49059 +/* SADB_RESERVED */
49060 +0
49061 +,
49062 +/* SADB_GETSPI */
49063 +1<<SADB_EXT_RESERVED
49064 +| 1<<SADB_EXT_SA
49065 +| 1<<SADB_EXT_ADDRESS_SRC
49066 +| 1<<SADB_EXT_ADDRESS_DST
49067 +,
49068 +/* SADB_UPDATE */
49069 +1<<SADB_EXT_RESERVED
49070 +| 1<<SADB_EXT_SA
49071 +| 1<<SADB_EXT_ADDRESS_SRC
49072 +| 1<<SADB_EXT_ADDRESS_DST
49073 +,
49074 +/* SADB_ADD */
49075 +1<<SADB_EXT_RESERVED
49076 +| 1<<SADB_EXT_SA
49077 +| 1<<SADB_EXT_ADDRESS_SRC
49078 +| 1<<SADB_EXT_ADDRESS_DST
49079 +,
49080 +/* SADB_DELETE */
49081 +1<<SADB_EXT_RESERVED
49082 +| 1<<SADB_EXT_SA
49083 +| 1<<SADB_EXT_ADDRESS_SRC
49084 +| 1<<SADB_EXT_ADDRESS_DST
49085 +,
49086 +/* SADB_GET */
49087 +1<<SADB_EXT_RESERVED
49088 +| 1<<SADB_EXT_SA
49089 +| 1<<SADB_EXT_ADDRESS_SRC
49090 +| 1<<SADB_EXT_ADDRESS_DST
49091 +/* | 1<<SADB_EXT_KEY_AUTH */
49092 +/* | 1<<SADB_EXT_KEY_ENCRYPT */
49093 +,
49094 +/* SADB_ACQUIRE */
49095 +1<<SADB_EXT_RESERVED
49096 +| 1<<SADB_EXT_ADDRESS_SRC
49097 +| 1<<SADB_EXT_ADDRESS_DST
49098 +| 1<<SADB_EXT_PROPOSAL
49099 +,
49100 +/* SADB_REGISTER */
49101 +1<<SADB_EXT_RESERVED
49102 +/* | 1<<SADB_EXT_SUPPORTED_AUTH
49103 + | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
49104 +,
49105 +/* SADB_EXPIRE */
49106 +1<<SADB_EXT_RESERVED
49107 +| 1<<SADB_EXT_SA
49108 +| 1<<SADB_EXT_LIFETIME_CURRENT
49109 +/* | 1<<SADB_EXT_LIFETIME_HARD
49110 + | 1<<SADB_EXT_LIFETIME_SOFT */
49111 +| 1<<SADB_EXT_ADDRESS_SRC
49112 +| 1<<SADB_EXT_ADDRESS_DST
49113 +,
49114 +/* SADB_FLUSH */
49115 +1<<SADB_EXT_RESERVED
49116 +,
49117 +/* SADB_DUMP */
49118 +1<<SADB_EXT_RESERVED
49119 +| 1<<SADB_EXT_SA
49120 +| 1<<SADB_EXT_ADDRESS_SRC
49121 +| 1<<SADB_EXT_ADDRESS_DST
49122 +| 1<<SADB_EXT_KEY_AUTH
49123 +| 1<<SADB_EXT_KEY_ENCRYPT
49124 +,
49125 +/* SADB_X_PROMISC */
49126 +1<<SADB_EXT_RESERVED
49127 +| 1<<SADB_EXT_SA
49128 +| 1<<SADB_EXT_LIFETIME_CURRENT
49129 +| 1<<SADB_EXT_LIFETIME_HARD
49130 +| 1<<SADB_EXT_LIFETIME_SOFT
49131 +| 1<<SADB_EXT_ADDRESS_SRC
49132 +| 1<<SADB_EXT_ADDRESS_DST
49133 +| 1<<SADB_EXT_ADDRESS_PROXY
49134 +| 1<<SADB_EXT_KEY_AUTH
49135 +| 1<<SADB_EXT_KEY_ENCRYPT
49136 +| 1<<SADB_EXT_IDENTITY_SRC
49137 +| 1<<SADB_EXT_IDENTITY_DST
49138 +| 1<<SADB_EXT_SENSITIVITY
49139 +| 1<<SADB_EXT_PROPOSAL
49140 +| 1<<SADB_EXT_SUPPORTED_AUTH
49141 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49142 +| 1<<SADB_EXT_SPIRANGE
49143 +| 1<<SADB_X_EXT_KMPRIVATE
49144 +| 1<<SADB_X_EXT_SATYPE2
49145 +| 1<<SADB_X_EXT_SA2
49146 +| 1<<SADB_X_EXT_ADDRESS_DST2
49147 +,
49148 +/* SADB_X_PCHANGE */
49149 +1<<SADB_EXT_RESERVED
49150 +| 1<<SADB_EXT_SA
49151 +| 1<<SADB_EXT_LIFETIME_CURRENT
49152 +| 1<<SADB_EXT_LIFETIME_HARD
49153 +| 1<<SADB_EXT_LIFETIME_SOFT
49154 +| 1<<SADB_EXT_ADDRESS_SRC
49155 +| 1<<SADB_EXT_ADDRESS_DST
49156 +| 1<<SADB_EXT_ADDRESS_PROXY
49157 +| 1<<SADB_EXT_KEY_AUTH
49158 +| 1<<SADB_EXT_KEY_ENCRYPT
49159 +| 1<<SADB_EXT_IDENTITY_SRC
49160 +| 1<<SADB_EXT_IDENTITY_DST
49161 +| 1<<SADB_EXT_SENSITIVITY
49162 +| 1<<SADB_EXT_PROPOSAL
49163 +| 1<<SADB_EXT_SUPPORTED_AUTH
49164 +| 1<<SADB_EXT_SUPPORTED_ENCRYPT
49165 +| 1<<SADB_EXT_SPIRANGE
49166 +| 1<<SADB_X_EXT_KMPRIVATE
49167 +| 1<<SADB_X_EXT_SATYPE2
49168 +| 1<<SADB_X_EXT_SA2
49169 +| 1<<SADB_X_EXT_ADDRESS_DST2
49170 +,
49171 +/* SADB_X_GRPSA */
49172 +1<<SADB_EXT_RESERVED
49173 +| 1<<SADB_EXT_SA
49174 +| 1<<SADB_EXT_ADDRESS_DST
49175 +,
49176 +/* SADB_X_ADDFLOW */
49177 +1<<SADB_EXT_RESERVED
49178 +| 1<<SADB_EXT_SA
49179 +| 1<<SADB_EXT_ADDRESS_DST
49180 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49181 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49182 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49183 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49184 +,
49185 +/* SADB_X_DELFLOW */
49186 +1<<SADB_EXT_RESERVED
49187 +/*| 1<<SADB_EXT_SA*/
49188 +| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
49189 +| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
49190 +| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
49191 +| 1<<SADB_X_EXT_ADDRESS_DST_MASK
49192 +,
49193 +/* SADB_X_DEBUG */
49194 +1<<SADB_EXT_RESERVED
49195 +| 1<<SADB_X_EXT_DEBUG
49196 +,
49197 +/* SADB_X_NAT_T_NEW_MAPPING */
49198 +1<<SADB_EXT_RESERVED
49199 +| 1<<SADB_EXT_SA
49200 +| 1<<SADB_EXT_ADDRESS_SRC
49201 +| 1<<SADB_EXT_ADDRESS_DST
49202 +| 1<<SADB_X_EXT_NAT_T_SPORT
49203 +| 1<<SADB_X_EXT_NAT_T_DPORT
49204 +}
49205 +}
49206 +};
49207 +
49208 +/*
49209 + * $Log: pfkey_v2_ext_bits.c,v $
49210 + * Revision 1.22 2005/05/11 01:45:31 mcr
49211 + * make pfkey.h standalone.
49212 + *
49213 + * Revision 1.21 2004/07/10 07:48:36 mcr
49214 + * Moved from linux/lib/libfreeswan/pfkey_v2_ext_bits.c,v
49215 + *
49216 + * Revision 1.20 2004/03/08 01:59:08 ken
49217 + * freeswan.h -> openswan.h
49218 + *
49219 + * Revision 1.19 2003/12/22 21:38:13 mcr
49220 + * removed extraenous #endif.
49221 + *
49222 + * Revision 1.18 2003/12/22 19:34:41 mcr
49223 + * added 0.6c NAT-T patch.
49224 + *
49225 + * Revision 1.17 2003/12/10 01:20:19 mcr
49226 + * NAT-traversal patches to KLIPS.
49227 + *
49228 + * Revision 1.16 2003/10/31 02:27:12 mcr
49229 + * pulled up port-selector patches and sa_id elimination.
49230 + *
49231 + * Revision 1.15.30.1 2003/09/21 13:59:44 mcr
49232 + * pre-liminary X.509 patch - does not yet pass tests.
49233 + *
49234 + * Revision 1.15 2002/04/24 07:55:32 mcr
49235 + * #include patches and Makefiles for post-reorg compilation.
49236 + *
49237 + * Revision 1.14 2002/04/24 07:36:40 mcr
49238 + * Moved from ./lib/pfkey_v2_ext_bits.c,v
49239 + *
49240 + * Revision 1.13 2002/01/29 22:25:36 rgb
49241 + * Re-add ipsec_kversion.h to keep MALLOC happy.
49242 + *
49243 + * Revision 1.12 2002/01/29 01:59:10 mcr
49244 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
49245 + * updating of IPv6 structures to match latest in6.h version.
49246 + * removed dead code from openswan.h that also duplicated kversions.h
49247 + * code.
49248 + *
49249 + * Revision 1.11 2001/10/18 04:45:24 rgb
49250 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
49251 + * lib/openswan.h version macros moved to lib/kversions.h.
49252 + * Other compiler directive cleanups.
49253 + *
49254 + * Revision 1.10 2001/09/08 21:13:35 rgb
49255 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
49256 + *
49257 + * Revision 1.9 2001/06/14 19:35:16 rgb
49258 + * Update copyright date.
49259 + *
49260 + * Revision 1.8 2001/03/26 23:07:36 rgb
49261 + * Remove requirement for auth and enc key from UPDATE.
49262 + *
49263 + * Revision 1.7 2000/09/12 22:35:37 rgb
49264 + * Restructured to remove unused extensions from CLEARFLOW messages.
49265 + *
49266 + * Revision 1.6 2000/09/09 06:39:01 rgb
49267 + * Added comments for clarity.
49268 + *
49269 + * Revision 1.5 2000/06/02 22:54:14 rgb
49270 + * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
49271 + *
49272 + * Revision 1.4 2000/01/21 06:27:56 rgb
49273 + * Added address cases for eroute flows.
49274 + * Added comments for each message type.
49275 + * Added klipsdebug switching capability.
49276 + * Fixed GRPSA bitfields.
49277 + *
49278 + * Revision 1.3 1999/12/01 22:20:27 rgb
49279 + * Remove requirement for a proxy address in an incoming getspi message.
49280 + *
49281 + * Revision 1.2 1999/11/27 11:57:06 rgb
49282 + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
49283 + * Add CVS log entry to bottom of file.
49284 + * Cleaned out unused bits.
49285 + *
49286 + */
49287 --- /dev/null Tue Mar 11 13:02:56 2003
49288 +++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004
49289 @@ -0,0 +1,951 @@
49290 +/*
49291 + * @(#) RFC2367 PF_KEYv2 Key management API message parser
49292 + * Copyright (C) 1998-2003 Richard Guy Briggs.
49293 + * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
49294 + *
49295 + * This program is free software; you can redistribute it and/or modify it
49296 + * under the terms of the GNU General Public License as published by the
49297 + * Free Software Foundation; either version 2 of the License, or (at your
49298 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
49299 + *
49300 + * This program is distributed in the hope that it will be useful, but
49301 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
49302 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
49303 + * for more details.
49304 + *
49305 + * RCSID $Id: pfkey_v2_ext_process.c,v 1.20.2.2 2006/10/06 21:39:26 paul Exp $
49306 + */
49307 +
49308 +/*
49309 + * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
49310 + */
49311 +
49312 +char pfkey_v2_ext_process_c_version[] = "$Id: pfkey_v2_ext_process.c,v 1.20.2.2 2006/10/06 21:39:26 paul Exp $";
49313 +
49314 +#ifndef AUTOCONF_INCLUDED
49315 +#include <linux/config.h>
49316 +#endif
49317 +#include <linux/version.h>
49318 +#include <linux/kernel.h> /* printk() */
49319 +
49320 +#include "openswan/ipsec_param.h"
49321 +
49322 +#ifdef MALLOC_SLAB
49323 +# include <linux/slab.h> /* kmalloc() */
49324 +#else /* MALLOC_SLAB */
49325 +# include <linux/malloc.h> /* kmalloc() */
49326 +#endif /* MALLOC_SLAB */
49327 +#include <linux/errno.h> /* error codes */
49328 +#include <linux/types.h> /* size_t */
49329 +#include <linux/interrupt.h> /* mark_bh */
49330 +
49331 +#include <linux/netdevice.h> /* struct device, and other headers */
49332 +#include <linux/etherdevice.h> /* eth_type_trans */
49333 +#include <linux/ip.h> /* struct iphdr */
49334 +#include <linux/skbuff.h>
49335 +
49336 +#include <openswan.h>
49337 +
49338 +#include <crypto/des.h>
49339 +
49340 +#ifdef SPINLOCK
49341 +# ifdef SPINLOCK_23
49342 +# include <linux/spinlock.h> /* *lock* */
49343 +# else /* SPINLOCK_23 */
49344 +# include <asm/spinlock.h> /* *lock* */
49345 +# endif /* SPINLOCK_23 */
49346 +#endif /* SPINLOCK */
49347 +#ifdef NET_21
49348 +# include <linux/in6.h>
49349 +# define ip_chk_addr inet_addr_type
49350 +# define IS_MYADDR RTN_LOCAL
49351 +#endif
49352 +
49353 +#include <net/ip.h>
49354 +#ifdef NETLINK_SOCK
49355 +# include <linux/netlink.h>
49356 +#else
49357 +# include <net/netlink.h>
49358 +#endif
49359 +
49360 +#include <linux/random.h> /* get_random_bytes() */
49361 +
49362 +#include "openswan/radij.h"
49363 +#include "openswan/ipsec_encap.h"
49364 +#include "openswan/ipsec_sa.h"
49365 +
49366 +#include "openswan/ipsec_radij.h"
49367 +#include "openswan/ipsec_xform.h"
49368 +#include "openswan/ipsec_ah.h"
49369 +#include "openswan/ipsec_esp.h"
49370 +#include "openswan/ipsec_tunnel.h"
49371 +#include "openswan/ipsec_rcv.h"
49372 +#include "openswan/ipcomp.h"
49373 +
49374 +#include <pfkeyv2.h>
49375 +#include <pfkey.h>
49376 +
49377 +#include "openswan/ipsec_proto.h"
49378 +#include "openswan/ipsec_alg.h"
49379 +
49380 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
49381 +
49382 +int
49383 +pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49384 +{
49385 + struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
49386 + int error = 0;
49387 + struct ipsec_sa* ipsp;
49388 +
49389 + KLIPS_PRINT(debug_pfkey,
49390 + "klips_debug:pfkey_sa_process: .\n");
49391 +
49392 + if(!extr || !extr->ips) {
49393 + KLIPS_PRINT(debug_pfkey,
49394 + "klips_debug:pfkey_sa_process: "
49395 + "extr or extr->ips is NULL, fatal\n");
49396 + SENDERR(EINVAL);
49397 + }
49398 +
49399 + switch(pfkey_ext->sadb_ext_type) {
49400 + case SADB_EXT_SA:
49401 + ipsp = extr->ips;
49402 + break;
49403 + case SADB_X_EXT_SA2:
49404 + if(extr->ips2 == NULL) {
49405 + extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49406 + }
49407 + if(extr->ips2 == NULL) {
49408 + SENDERR(-error);
49409 + }
49410 + ipsp = extr->ips2;
49411 + break;
49412 + default:
49413 + KLIPS_PRINT(debug_pfkey,
49414 + "klips_debug:pfkey_sa_process: "
49415 + "invalid exttype=%d.\n",
49416 + pfkey_ext->sadb_ext_type);
49417 + SENDERR(EINVAL);
49418 + }
49419 +
49420 + ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
49421 + ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
49422 + ipsp->ips_state = pfkey_sa->sadb_sa_state;
49423 + ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
49424 + ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
49425 + ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref;
49426 +
49427 + switch(ipsp->ips_said.proto) {
49428 + case IPPROTO_AH:
49429 + ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
49430 + ipsp->ips_encalg = SADB_EALG_NONE;
49431 + break;
49432 + case IPPROTO_ESP:
49433 + ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
49434 + ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
49435 + ipsec_alg_sa_init(ipsp);
49436 + break;
49437 + case IPPROTO_IPIP:
49438 + ipsp->ips_authalg = AH_NONE;
49439 + ipsp->ips_encalg = ESP_NONE;
49440 + break;
49441 +#ifdef CONFIG_KLIPS_IPCOMP
49442 + case IPPROTO_COMP:
49443 + ipsp->ips_authalg = AH_NONE;
49444 + ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
49445 + break;
49446 +#endif /* CONFIG_KLIPS_IPCOMP */
49447 + case IPPROTO_INT:
49448 + ipsp->ips_authalg = AH_NONE;
49449 + ipsp->ips_encalg = ESP_NONE;
49450 + break;
49451 + case 0:
49452 + break;
49453 + default:
49454 + KLIPS_PRINT(debug_pfkey,
49455 + "klips_debug:pfkey_sa_process: "
49456 + "unknown proto=%d.\n",
49457 + ipsp->ips_said.proto);
49458 + SENDERR(EINVAL);
49459 + }
49460 +
49461 +errlab:
49462 + return error;
49463 +}
49464 +
49465 +int
49466 +pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49467 +{
49468 + int error = 0;
49469 + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
49470 +
49471 + KLIPS_PRINT(debug_pfkey,
49472 + "klips_debug:pfkey_lifetime_process: .\n");
49473 +
49474 + if(!extr || !extr->ips) {
49475 + KLIPS_PRINT(debug_pfkey,
49476 + "klips_debug:pfkey_lifetime_process: "
49477 + "extr or extr->ips is NULL, fatal\n");
49478 + SENDERR(EINVAL);
49479 + }
49480 +
49481 + switch(pfkey_lifetime->sadb_lifetime_exttype) {
49482 + case SADB_EXT_LIFETIME_CURRENT:
49483 + KLIPS_PRINT(debug_pfkey,
49484 + "klips_debug:pfkey_lifetime_process: "
49485 + "lifetime_current not supported yet.\n");
49486 + SENDERR(EINVAL);
49487 + break;
49488 + case SADB_EXT_LIFETIME_HARD:
49489 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
49490 + pfkey_lifetime->sadb_lifetime_allocations);
49491 +
49492 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
49493 + pfkey_lifetime->sadb_lifetime_bytes);
49494 +
49495 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
49496 + pfkey_lifetime->sadb_lifetime_addtime);
49497 +
49498 + ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
49499 + pfkey_lifetime->sadb_lifetime_usetime);
49500 +
49501 + break;
49502 +
49503 + case SADB_EXT_LIFETIME_SOFT:
49504 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
49505 + pfkey_lifetime->sadb_lifetime_allocations);
49506 +
49507 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
49508 + pfkey_lifetime->sadb_lifetime_bytes);
49509 +
49510 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
49511 + pfkey_lifetime->sadb_lifetime_addtime);
49512 +
49513 + ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
49514 + pfkey_lifetime->sadb_lifetime_usetime);
49515 +
49516 + break;
49517 + default:
49518 + KLIPS_PRINT(debug_pfkey,
49519 + "klips_debug:pfkey_lifetime_process: "
49520 + "invalid exttype=%d.\n",
49521 + pfkey_ext->sadb_ext_type);
49522 + SENDERR(EINVAL);
49523 + }
49524 +
49525 +errlab:
49526 + return error;
49527 +}
49528 +
49529 +int
49530 +pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49531 +{
49532 + int error = 0;
49533 + int saddr_len = 0;
49534 + char ipaddr_txt[ADDRTOA_BUF];
49535 + unsigned char **sap;
49536 + unsigned short * portp = 0;
49537 + struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
49538 + struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
49539 + struct ipsec_sa* ipsp;
49540 +
49541 + KLIPS_PRINT(debug_pfkey,
49542 + "klips_debug:pfkey_address_process:\n");
49543 +
49544 + if(!extr || !extr->ips) {
49545 + KLIPS_PRINT(debug_pfkey,
49546 + "klips_debug:pfkey_address_process: "
49547 + "extr or extr->ips is NULL, fatal\n");
49548 + SENDERR(EINVAL);
49549 + }
49550 +
49551 + switch(s->sa_family) {
49552 + case AF_INET:
49553 + saddr_len = sizeof(struct sockaddr_in);
49554 + addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
49555 + KLIPS_PRINT(debug_pfkey,
49556 + "klips_debug:pfkey_address_process: "
49557 + "found address family=%d, AF_INET, %s.\n",
49558 + s->sa_family,
49559 + ipaddr_txt);
49560 + break;
49561 +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
49562 + case AF_INET6:
49563 + saddr_len = sizeof(struct sockaddr_in6);
49564 + break;
49565 +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
49566 + default:
49567 + KLIPS_PRINT(debug_pfkey,
49568 + "klips_debug:pfkey_address_process: "
49569 + "s->sa_family=%d not supported.\n",
49570 + s->sa_family);
49571 + SENDERR(EPFNOSUPPORT);
49572 + }
49573 +
49574 + switch(pfkey_address->sadb_address_exttype) {
49575 + case SADB_EXT_ADDRESS_SRC:
49576 + KLIPS_PRINT(debug_pfkey,
49577 + "klips_debug:pfkey_address_process: "
49578 + "found src address.\n");
49579 + sap = (unsigned char **)&(extr->ips->ips_addr_s);
49580 + extr->ips->ips_addr_s_size = saddr_len;
49581 + break;
49582 + case SADB_EXT_ADDRESS_DST:
49583 + KLIPS_PRINT(debug_pfkey,
49584 + "klips_debug:pfkey_address_process: "
49585 + "found dst address.\n");
49586 + sap = (unsigned char **)&(extr->ips->ips_addr_d);
49587 + extr->ips->ips_addr_d_size = saddr_len;
49588 + break;
49589 + case SADB_EXT_ADDRESS_PROXY:
49590 + KLIPS_PRINT(debug_pfkey,
49591 + "klips_debug:pfkey_address_process: "
49592 + "found proxy address.\n");
49593 + sap = (unsigned char **)&(extr->ips->ips_addr_p);
49594 + extr->ips->ips_addr_p_size = saddr_len;
49595 + break;
49596 + case SADB_X_EXT_ADDRESS_DST2:
49597 + KLIPS_PRINT(debug_pfkey,
49598 + "klips_debug:pfkey_address_process: "
49599 + "found 2nd dst address.\n");
49600 + if(extr->ips2 == NULL) {
49601 + extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49602 + }
49603 + if(extr->ips2 == NULL) {
49604 + SENDERR(-error);
49605 + }
49606 + sap = (unsigned char **)&(extr->ips2->ips_addr_d);
49607 + extr->ips2->ips_addr_d_size = saddr_len;
49608 + break;
49609 + case SADB_X_EXT_ADDRESS_SRC_FLOW:
49610 + KLIPS_PRINT(debug_pfkey,
49611 + "klips_debug:pfkey_address_process: "
49612 + "found src flow address.\n");
49613 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49614 + SENDERR(ENOMEM);
49615 + }
49616 + sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
49617 + portp = &(extr->eroute->er_eaddr.sen_sport);
49618 + break;
49619 + case SADB_X_EXT_ADDRESS_DST_FLOW:
49620 + KLIPS_PRINT(debug_pfkey,
49621 + "klips_debug:pfkey_address_process: "
49622 + "found dst flow address.\n");
49623 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49624 + SENDERR(ENOMEM);
49625 + }
49626 + sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
49627 + portp = &(extr->eroute->er_eaddr.sen_dport);
49628 + break;
49629 + case SADB_X_EXT_ADDRESS_SRC_MASK:
49630 + KLIPS_PRINT(debug_pfkey,
49631 + "klips_debug:pfkey_address_process: "
49632 + "found src mask address.\n");
49633 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49634 + SENDERR(ENOMEM);
49635 + }
49636 + sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
49637 + portp = &(extr->eroute->er_emask.sen_sport);
49638 + break;
49639 + case SADB_X_EXT_ADDRESS_DST_MASK:
49640 + KLIPS_PRINT(debug_pfkey,
49641 + "klips_debug:pfkey_address_process: "
49642 + "found dst mask address.\n");
49643 + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
49644 + SENDERR(ENOMEM);
49645 + }
49646 + sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
49647 + portp = &(extr->eroute->er_emask.sen_dport);
49648 + break;
49649 +#ifdef NAT_TRAVERSAL
49650 + case SADB_X_EXT_NAT_T_OA:
49651 + KLIPS_PRINT(debug_pfkey,
49652 + "klips_debug:pfkey_address_process: "
49653 + "found NAT-OA address.\n");
49654 + sap = (unsigned char **)&(extr->ips->ips_natt_oa);
49655 + extr->ips->ips_natt_oa_size = saddr_len;
49656 + break;
49657 +#endif
49658 + default:
49659 + KLIPS_PRINT(debug_pfkey,
49660 + "klips_debug:pfkey_address_process: "
49661 + "unrecognised ext_type=%d.\n",
49662 + pfkey_address->sadb_address_exttype);
49663 + SENDERR(EINVAL);
49664 + }
49665 +
49666 + switch(pfkey_address->sadb_address_exttype) {
49667 + case SADB_EXT_ADDRESS_SRC:
49668 + case SADB_EXT_ADDRESS_DST:
49669 + case SADB_EXT_ADDRESS_PROXY:
49670 + case SADB_X_EXT_ADDRESS_DST2:
49671 +#ifdef NAT_TRAVERSAL
49672 + case SADB_X_EXT_NAT_T_OA:
49673 +#endif
49674 + KLIPS_PRINT(debug_pfkey,
49675 + "klips_debug:pfkey_address_process: "
49676 + "allocating %d bytes for saddr.\n",
49677 + saddr_len);
49678 + if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
49679 + SENDERR(ENOMEM);
49680 + }
49681 + memcpy(*sap, s, saddr_len);
49682 + break;
49683 + default:
49684 + if(s->sa_family != AF_INET) {
49685 + KLIPS_PRINT(debug_pfkey,
49686 + "klips_debug:pfkey_address_process: "
49687 + "s->sa_family=%d not supported.\n",
49688 + s->sa_family);
49689 + SENDERR(EPFNOSUPPORT);
49690 + }
49691 + {
49692 + unsigned long *ulsap = (unsigned long *)sap;
49693 + *ulsap = ((struct sockaddr_in*)s)->sin_addr.s_addr;
49694 + }
49695 +
49696 + if (portp != 0)
49697 + *portp = ((struct sockaddr_in*)s)->sin_port;
49698 +#ifdef CONFIG_KLIPS_DEBUG
49699 + if(extr->eroute) {
49700 + char buf1[64], buf2[64];
49701 + if (debug_pfkey) {
49702 + subnettoa(extr->eroute->er_eaddr.sen_ip_src,
49703 + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
49704 + subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
49705 + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
49706 + KLIPS_PRINT(debug_pfkey,
49707 + "klips_debug:pfkey_address_parse: "
49708 + "extr->eroute set to %s:%d->%s:%d\n",
49709 + buf1,
49710 + ntohs(extr->eroute->er_eaddr.sen_sport),
49711 + buf2,
49712 + ntohs(extr->eroute->er_eaddr.sen_dport));
49713 + }
49714 + }
49715 +#endif /* CONFIG_KLIPS_DEBUG */
49716 + }
49717 +
49718 + ipsp = extr->ips;
49719 + switch(pfkey_address->sadb_address_exttype) {
49720 + case SADB_X_EXT_ADDRESS_DST2:
49721 + ipsp = extr->ips2;
49722 + case SADB_EXT_ADDRESS_DST:
49723 + if(s->sa_family == AF_INET) {
49724 + ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
49725 + ipsp->ips_said.dst.u.v4.sin_family = AF_INET;
49726 + addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
49727 + 0,
49728 + ipaddr_txt,
49729 + sizeof(ipaddr_txt));
49730 + KLIPS_PRINT(debug_pfkey,
49731 + "klips_debug:pfkey_address_process: "
49732 + "ips_said.dst set to %s.\n",
49733 + ipaddr_txt);
49734 + } else {
49735 + KLIPS_PRINT(debug_pfkey,
49736 + "klips_debug:pfkey_address_process: "
49737 + "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
49738 + s->sa_family);
49739 + }
49740 + default:
49741 + break;
49742 + }
49743 +
49744 + /* XXX check if port!=0 */
49745 +
49746 + KLIPS_PRINT(debug_pfkey,
49747 + "klips_debug:pfkey_address_process: successful.\n");
49748 + errlab:
49749 + return error;
49750 +}
49751 +
49752 +int
49753 +pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49754 +{
49755 + int error = 0;
49756 + struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
49757 +
49758 + KLIPS_PRINT(debug_pfkey,
49759 + "klips_debug:pfkey_key_process: .\n");
49760 +
49761 + if(!extr || !extr->ips) {
49762 + KLIPS_PRINT(debug_pfkey,
49763 + "klips_debug:pfkey_key_process: "
49764 + "extr or extr->ips is NULL, fatal\n");
49765 + SENDERR(EINVAL);
49766 + }
49767 +
49768 + switch(pfkey_key->sadb_key_exttype) {
49769 + case SADB_EXT_KEY_AUTH:
49770 + KLIPS_PRINT(debug_pfkey,
49771 + "klips_debug:pfkey_key_process: "
49772 + "allocating %d bytes for authkey.\n",
49773 + DIVUP(pfkey_key->sadb_key_bits, 8));
49774 + if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
49775 + KLIPS_PRINT(debug_pfkey,
49776 + "klips_debug:pfkey_key_process: "
49777 + "memory allocation error.\n");
49778 + SENDERR(ENOMEM);
49779 + }
49780 + extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
49781 + extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
49782 + memcpy(extr->ips->ips_key_a,
49783 + (char*)pfkey_key + sizeof(struct sadb_key),
49784 + extr->ips->ips_key_a_size);
49785 + break;
49786 + case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
49787 + KLIPS_PRINT(debug_pfkey,
49788 + "klips_debug:pfkey_key_process: "
49789 + "allocating %d bytes for enckey.\n",
49790 + DIVUP(pfkey_key->sadb_key_bits, 8));
49791 + if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
49792 + KLIPS_PRINT(debug_pfkey,
49793 + "klips_debug:pfkey_key_process: "
49794 + "memory allocation error.\n");
49795 + SENDERR(ENOMEM);
49796 + }
49797 + extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
49798 + extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
49799 + memcpy(extr->ips->ips_key_e,
49800 + (char*)pfkey_key + sizeof(struct sadb_key),
49801 + extr->ips->ips_key_e_size);
49802 + break;
49803 + default:
49804 + SENDERR(EINVAL);
49805 + }
49806 +
49807 + KLIPS_PRINT(debug_pfkey,
49808 + "klips_debug:pfkey_key_process: "
49809 + "success.\n");
49810 +errlab:
49811 + return error;
49812 +}
49813 +
49814 +int
49815 +pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49816 +{
49817 + int error = 0;
49818 + struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
49819 + int data_len;
49820 +
49821 + KLIPS_PRINT(debug_pfkey,
49822 + "klips_debug:pfkey_ident_process: .\n");
49823 +
49824 + if(!extr || !extr->ips) {
49825 + KLIPS_PRINT(debug_pfkey,
49826 + "klips_debug:pfkey_ident_process: "
49827 + "extr or extr->ips is NULL, fatal\n");
49828 + SENDERR(EINVAL);
49829 + }
49830 +
49831 + switch(pfkey_ident->sadb_ident_exttype) {
49832 + case SADB_EXT_IDENTITY_SRC:
49833 + data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
49834 +
49835 + extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
49836 + extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
49837 + extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
49838 + if(data_len) {
49839 + KLIPS_PRINT(debug_pfkey,
49840 + "klips_debug:pfkey_ident_process: "
49841 + "allocating %d bytes for ident_s.\n",
49842 + data_len);
49843 + if(!(extr->ips->ips_ident_s.data
49844 + = kmalloc(data_len, GFP_KERNEL))) {
49845 + SENDERR(ENOMEM);
49846 + }
49847 + memcpy(extr->ips->ips_ident_s.data,
49848 + (char*)pfkey_ident + sizeof(struct sadb_ident),
49849 + data_len);
49850 + } else {
49851 + extr->ips->ips_ident_s.data = NULL;
49852 + }
49853 + break;
49854 + case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
49855 + data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
49856 +
49857 + extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
49858 + extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
49859 + extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
49860 + if(data_len) {
49861 + KLIPS_PRINT(debug_pfkey,
49862 + "klips_debug:pfkey_ident_process: "
49863 + "allocating %d bytes for ident_d.\n",
49864 + data_len);
49865 + if(!(extr->ips->ips_ident_d.data
49866 + = kmalloc(data_len, GFP_KERNEL))) {
49867 + SENDERR(ENOMEM);
49868 + }
49869 + memcpy(extr->ips->ips_ident_d.data,
49870 + (char*)pfkey_ident + sizeof(struct sadb_ident),
49871 + data_len);
49872 + } else {
49873 + extr->ips->ips_ident_d.data = NULL;
49874 + }
49875 + break;
49876 + default:
49877 + SENDERR(EINVAL);
49878 + }
49879 +errlab:
49880 + return error;
49881 +}
49882 +
49883 +int
49884 +pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49885 +{
49886 + int error = 0;
49887 +
49888 + KLIPS_PRINT(debug_pfkey,
49889 + "klips_debug:pfkey_sens_process: "
49890 + "Sorry, I can't process exttype=%d yet.\n",
49891 + pfkey_ext->sadb_ext_type);
49892 + SENDERR(EINVAL); /* don't process these yet */
49893 + errlab:
49894 + return error;
49895 +}
49896 +
49897 +int
49898 +pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49899 +{
49900 + int error = 0;
49901 +
49902 + KLIPS_PRINT(debug_pfkey,
49903 + "klips_debug:pfkey_prop_process: "
49904 + "Sorry, I can't process exttype=%d yet.\n",
49905 + pfkey_ext->sadb_ext_type);
49906 + SENDERR(EINVAL); /* don't process these yet */
49907 +
49908 + errlab:
49909 + return error;
49910 +}
49911 +
49912 +int
49913 +pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49914 +{
49915 + int error = 0;
49916 +
49917 + KLIPS_PRINT(debug_pfkey,
49918 + "klips_debug:pfkey_supported_process: "
49919 + "Sorry, I can't process exttype=%d yet.\n",
49920 + pfkey_ext->sadb_ext_type);
49921 + SENDERR(EINVAL); /* don't process these yet */
49922 +
49923 +errlab:
49924 + return error;
49925 +}
49926 +
49927 +int
49928 +pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49929 +{
49930 + int error = 0;
49931 +
49932 + KLIPS_PRINT(debug_pfkey,
49933 + "klips_debug:pfkey_spirange_process: .\n");
49934 +/* errlab: */
49935 + return error;
49936 +}
49937 +
49938 +int
49939 +pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49940 +{
49941 + int error = 0;
49942 +
49943 + KLIPS_PRINT(debug_pfkey,
49944 + "klips_debug:pfkey_x_kmprivate_process: "
49945 + "Sorry, I can't process exttype=%d yet.\n",
49946 + pfkey_ext->sadb_ext_type);
49947 + SENDERR(EINVAL); /* don't process these yet */
49948 +
49949 +errlab:
49950 + return error;
49951 +}
49952 +
49953 +int
49954 +pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49955 +{
49956 + int error = 0;
49957 + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
49958 +
49959 + KLIPS_PRINT(debug_pfkey,
49960 + "klips_debug:pfkey_x_satype_process: .\n");
49961 +
49962 + if(!extr || !extr->ips) {
49963 + KLIPS_PRINT(debug_pfkey,
49964 + "klips_debug:pfkey_x_satype_process: "
49965 + "extr or extr->ips is NULL, fatal\n");
49966 + SENDERR(EINVAL);
49967 + }
49968 +
49969 + if(extr->ips2 == NULL) {
49970 + extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
49971 + }
49972 + if(extr->ips2 == NULL) {
49973 + SENDERR(-error);
49974 + }
49975 + if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
49976 + KLIPS_PRINT(debug_pfkey,
49977 + "klips_debug:pfkey_x_satype_process: "
49978 + "proto lookup from satype=%d failed.\n",
49979 + pfkey_x_satype->sadb_x_satype_satype);
49980 + SENDERR(EINVAL);
49981 + }
49982 + KLIPS_PRINT(debug_pfkey,
49983 + "klips_debug:pfkey_x_satype_process: "
49984 + "protocol==%d decoded from satype==%d(%s).\n",
49985 + extr->ips2->ips_said.proto,
49986 + pfkey_x_satype->sadb_x_satype_satype,
49987 + satype2name(pfkey_x_satype->sadb_x_satype_satype));
49988 +
49989 +errlab:
49990 + return error;
49991 +}
49992 +
49993 +
49994 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
49995 +int
49996 +pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
49997 +{
49998 + int error = 0;
49999 + struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
50000 +
50001 + if(!pfkey_x_nat_t_type) {
50002 + printk("klips_debug:pfkey_x_nat_t_type_process: "
50003 + "null pointer passed in\n");
50004 + SENDERR(EINVAL);
50005 + }
50006 +
50007 + KLIPS_PRINT(debug_pfkey,
50008 + "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
50009 + pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
50010 +
50011 + if(!extr || !extr->ips) {
50012 + KLIPS_PRINT(debug_pfkey,
50013 + "klips_debug:pfkey_nat_t_type_process: "
50014 + "extr or extr->ips is NULL, fatal\n");
50015 + SENDERR(EINVAL);
50016 + }
50017 +
50018 + switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
50019 + case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */
50020 + case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
50021 +
50022 + extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
50023 + break;
50024 + default:
50025 + KLIPS_PRINT(debug_pfkey,
50026 + "klips_debug:pfkey_x_nat_t_type_process: "
50027 + "unknown type %d.\n",
50028 + pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
50029 + SENDERR(EINVAL);
50030 + break;
50031 + }
50032 +
50033 +errlab:
50034 + return error;
50035 +}
50036 +
50037 +int
50038 +pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50039 +{
50040 + int error = 0;
50041 + struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
50042 +
50043 + if(!pfkey_x_nat_t_port) {
50044 + printk("klips_debug:pfkey_x_nat_t_port_process: "
50045 + "null pointer passed in\n");
50046 + SENDERR(EINVAL);
50047 + }
50048 +
50049 + KLIPS_PRINT(debug_pfkey,
50050 + "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
50051 + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
50052 + pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
50053 +
50054 + if(!extr || !extr->ips) {
50055 + KLIPS_PRINT(debug_pfkey,
50056 + "klips_debug:pfkey_nat_t_type_process: "
50057 + "extr or extr->ips is NULL, fatal\n");
50058 + SENDERR(EINVAL);
50059 + }
50060 +
50061 + switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
50062 + case SADB_X_EXT_NAT_T_SPORT:
50063 + extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
50064 + break;
50065 + case SADB_X_EXT_NAT_T_DPORT:
50066 + extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
50067 + break;
50068 + default:
50069 + KLIPS_PRINT(debug_pfkey,
50070 + "klips_debug:pfkey_x_nat_t_port_process: "
50071 + "unknown exttype %d.\n",
50072 + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
50073 + SENDERR(EINVAL);
50074 + break;
50075 + }
50076 +
50077 +errlab:
50078 + return error;
50079 +}
50080 +#endif
50081 +
50082 +int
50083 +pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
50084 +{
50085 + int error = 0;
50086 + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
50087 +
50088 + if(!pfkey_x_debug) {
50089 + printk("klips_debug:pfkey_x_debug_process: "
50090 + "null pointer passed in\n");
50091 + SENDERR(EINVAL);
50092 + }
50093 +
50094 + KLIPS_PRINT(debug_pfkey,
50095 + "klips_debug:pfkey_x_debug_process: .\n");
50096 +
50097 +#ifdef CONFIG_KLIPS_DEBUG
50098 + if(pfkey_x_debug->sadb_x_debug_netlink >>
50099 + (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
50100 + pfkey_x_debug->sadb_x_debug_netlink &=
50101 + ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
50102 + debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
50103 + debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
50104 + debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
50105 + debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
50106 + debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
50107 + debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
50108 + debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
50109 + debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
50110 + debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
50111 + debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
50112 +#ifdef CONFIG_KLIPS_IPCOMP
50113 + sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
50114 +#endif /* CONFIG_KLIPS_IPCOMP */
50115 + sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
50116 + KLIPS_PRINT(debug_pfkey,
50117 + "klips_debug:pfkey_x_debug_process: "
50118 + "set\n");
50119 + } else {
50120 + KLIPS_PRINT(debug_pfkey,
50121 + "klips_debug:pfkey_x_debug_process: "
50122 + "unset\n");
50123 + debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
50124 + debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
50125 + debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
50126 + debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
50127 + debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
50128 + debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
50129 + debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
50130 + debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
50131 + debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
50132 + debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
50133 +#ifdef CONFIG_KLIPS_IPCOMP
50134 + sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
50135 +#endif /* CONFIG_KLIPS_IPCOMP */
50136 + sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
50137 + }
50138 +#else /* CONFIG_KLIPS_DEBUG */
50139 + printk("klips_debug:pfkey_x_debug_process: "
50140 + "debugging not enabled\n");
50141 + SENDERR(EINVAL);
50142 +#endif /* CONFIG_KLIPS_DEBUG */
50143 +
50144 +errlab:
50145 + return error;
50146 +}
50147 +
50148 +/*
50149 + * $Log: pfkey_v2_ext_process.c,v $
50150 + * Revision 1.20.2.2 2006/10/06 21:39:26 paul
50151 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
50152 + * set. This is defined through autoconf.h which is included through the
50153 + * linux kernel build macros.
50154 + *
50155 + * Revision 1.20.2.1 2006/04/20 16:33:07 mcr
50156 + * remove all of CONFIG_KLIPS_ALG --- one can no longer build without it.
50157 + * Fix in-kernel module compilation. Sub-makefiles do not work.
50158 + *
50159 + * Revision 1.20 2005/04/29 05:10:22 mcr
50160 + * removed from extraenous includes to make unit testing easier.
50161 + *
50162 + * Revision 1.19 2004/12/04 07:14:18 mcr
50163 + * resolution to gcc3-ism was wrong. fixed to assign correct
50164 + * variable.
50165 + *
50166 + * Revision 1.18 2004/12/03 21:25:57 mcr
50167 + * compile time fixes for running on 2.6.
50168 + * still experimental.
50169 + *
50170 + * Revision 1.17 2004/08/21 00:45:04 mcr
50171 + * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
50172 + *
50173 + * Revision 1.16 2004/07/10 19:11:18 mcr
50174 + * CONFIG_IPSEC -> CONFIG_KLIPS.
50175 + *
50176 + * Revision 1.15 2004/04/06 02:49:26 mcr
50177 + * pullup of algo code from alg-branch.
50178 + *
50179 + * Revision 1.14 2004/02/03 03:13:59 mcr
50180 + * no longer #ifdef out NON_ESP mode. That was a mistake.
50181 + *
50182 + * Revision 1.13 2003/12/15 18:13:12 mcr
50183 + * when compiling with NAT traversal, don't assume that the
50184 + * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
50185 + * is set.
50186 + *
50187 + * Revision 1.12.2.1 2003/12/22 15:25:52 jjo
50188 + * Merged algo-0.8.1-rc11-test1 into alg-branch
50189 + *
50190 + * Revision 1.12 2003/12/10 01:14:27 mcr
50191 + * NAT-traversal patches to KLIPS.
50192 + *
50193 + * Revision 1.11 2003/10/31 02:27:55 mcr
50194 + * pulled up port-selector patches and sa_id elimination.
50195 + *
50196 + * Revision 1.10.4.2 2003/10/29 01:30:41 mcr
50197 + * elimited "struct sa_id".
50198 + *
50199 + * Revision 1.10.4.1 2003/09/21 13:59:56 mcr
50200 + * pre-liminary X.509 patch - does not yet pass tests.
50201 + *
50202 + * Revision 1.10 2003/02/06 01:51:41 rgb
50203 + * Removed no longer relevant comment
50204 + *
50205 + * Revision 1.9 2003/01/30 02:32:44 rgb
50206 + *
50207 + * Transmit error code through to caller from callee for better diagnosis of problems.
50208 + *
50209 + * Revision 1.8 2002/12/13 22:42:22 mcr
50210 + * restored sa_ref code
50211 + *
50212 + * Revision 1.7 2002/12/13 22:40:48 mcr
50213 + * temporarily removed sadb_x_sa_ref reference for 2.xx
50214 + *
50215 + * Revision 1.6 2002/10/05 05:02:58 dhr
50216 + *
50217 + * C labels go on statements
50218 + *
50219 + * Revision 1.5 2002/09/20 15:41:08 rgb
50220 + * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
50221 + * Added sadb_x_sa_ref to struct sadb_sa.
50222 + *
50223 + * Revision 1.4 2002/09/20 05:02:02 rgb
50224 + * Added memory allocation debugging.
50225 + *
50226 + * Revision 1.3 2002/07/24 18:44:54 rgb
50227 + * Type fiddling to tame ia64 compiler.
50228 + *
50229 + * Revision 1.2 2002/05/27 18:55:03 rgb
50230 + * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
50231 + *
50232 + * Revision 1.1 2002/05/14 02:33:51 rgb
50233 + * Moved all the extension processing functions to pfkey_v2_ext_process.c.
50234 + *
50235 + *
50236 + * Local variables:
50237 + * c-file-style: "linux"
50238 + * End:
50239 + *
50240 + */
50241 --- /dev/null Tue Mar 11 13:02:56 2003
50242 +++ linux/net/ipsec/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004
50243 @@ -0,0 +1,1846 @@
50244 +/*
50245 + * RFC2367 PF_KEYv2 Key management API message parser
50246 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
50247 + *
50248 + * This program is free software; you can redistribute it and/or modify it
50249 + * under the terms of the GNU General Public License as published by the
50250 + * Free Software Foundation; either version 2 of the License, or (at your
50251 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
50252 + *
50253 + * This program is distributed in the hope that it will be useful, but
50254 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
50255 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50256 + * for more details.
50257 + *
50258 + * RCSID $Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $
50259 + */
50260 +
50261 +/*
50262 + * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
50263 + */
50264 +
50265 +char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.65 2005/04/06 17:46:05 mcr Exp $";
50266 +
50267 +/*
50268 + * Some ugly stuff to allow consistent debugging code for use in the
50269 + * kernel and in user space
50270 +*/
50271 +
50272 +#ifdef __KERNEL__
50273 +
50274 +# include <linux/kernel.h> /* for printk */
50275 +
50276 +#include "openswan/ipsec_kversion.h" /* for malloc switch */
50277 +
50278 +# ifdef MALLOC_SLAB
50279 +# include <linux/slab.h> /* kmalloc() */
50280 +# else /* MALLOC_SLAB */
50281 +# include <linux/malloc.h> /* kmalloc() */
50282 +# endif /* MALLOC_SLAB */
50283 +# include <linux/errno.h> /* error codes */
50284 +# include <linux/types.h> /* size_t */
50285 +# include <linux/interrupt.h> /* mark_bh */
50286 +
50287 +# include <linux/netdevice.h> /* struct device, and other headers */
50288 +# include <linux/etherdevice.h> /* eth_type_trans */
50289 +# include <linux/ip.h> /* struct iphdr */
50290 +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
50291 +# include <linux/ipv6.h> /* struct ipv6hdr */
50292 +# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
50293 +extern int debug_pfkey;
50294 +
50295 +# include <openswan.h>
50296 +
50297 +#include "openswan/ipsec_encap.h"
50298 +
50299 +#else /* __KERNEL__ */
50300 +
50301 +# include <sys/types.h>
50302 +# include <linux/types.h>
50303 +# include <linux/errno.h>
50304 +
50305 +# include <openswan.h>
50306 +# include "constants.h"
50307 +# include "programs/pluto/defs.h" /* for PRINTF_LIKE */
50308 +
50309 +#endif /* __KERNEL__ */
50310 +
50311 +
50312 +#include <pfkeyv2.h>
50313 +#include <pfkey.h>
50314 +
50315 +#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
50316 +
50317 +/*
50318 + * how to handle debugging for pfkey.
50319 + */
50320 +#include <openswan/pfkey_debug.h>
50321 +
50322 +unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;
50323 +void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
50324 +void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
50325 +
50326 +
50327 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
50328 +
50329 +struct satype_tbl {
50330 + uint8_t proto;
50331 + uint8_t satype;
50332 + char* name;
50333 +} static satype_tbl[] = {
50334 +#ifdef __KERNEL__
50335 + { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
50336 + { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
50337 + { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
50338 +#ifdef CONFIG_KLIPS_IPCOMP
50339 + { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
50340 +#endif /* CONFIG_KLIPS_IPCOMP */
50341 + { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
50342 +#else /* __KERNEL__ */
50343 + { SA_ESP, SADB_SATYPE_ESP, "ESP" },
50344 + { SA_AH, SADB_SATYPE_AH, "AH" },
50345 + { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
50346 + { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
50347 + { SA_INT, SADB_X_SATYPE_INT, "INT" },
50348 +#endif /* __KERNEL__ */
50349 + { 0, 0, "UNKNOWN" }
50350 +};
50351 +
50352 +uint8_t
50353 +satype2proto(uint8_t satype)
50354 +{
50355 + int i =0;
50356 +
50357 + while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
50358 + i++;
50359 + }
50360 + return satype_tbl[i].proto;
50361 +}
50362 +
50363 +uint8_t
50364 +proto2satype(uint8_t proto)
50365 +{
50366 + int i = 0;
50367 +
50368 + while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
50369 + i++;
50370 + }
50371 + return satype_tbl[i].satype;
50372 +}
50373 +
50374 +char*
50375 +satype2name(uint8_t satype)
50376 +{
50377 + int i = 0;
50378 +
50379 + while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
50380 + i++;
50381 + }
50382 + return satype_tbl[i].name;
50383 +}
50384 +
50385 +char*
50386 +proto2name(uint8_t proto)
50387 +{
50388 + int i = 0;
50389 +
50390 + while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
50391 + i++;
50392 + }
50393 + return satype_tbl[i].name;
50394 +}
50395 +
50396 +/* Default extension parsers taken from the KLIPS code */
50397 +
50398 +DEBUG_NO_STATIC int
50399 +pfkey_sa_parse(struct sadb_ext *pfkey_ext)
50400 +{
50401 + int error = 0;
50402 + struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
50403 +#if 0
50404 + struct sadb_sa sav2;
50405 +#endif
50406 +
50407 + /* sanity checks... */
50408 + if(!pfkey_sa) {
50409 + ERROR("pfkey_sa_parse: "
50410 + "NULL pointer passed in.\n");
50411 + SENDERR(EINVAL);
50412 + }
50413 +
50414 +#if 0
50415 + /* check if this structure is short, and if so, fix it up.
50416 + * XXX this is NOT the way to do things.
50417 + */
50418 + if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
50419 +
50420 + /* yes, so clear out a temporary structure, and copy first */
50421 + memset(&sav2, 0, sizeof(sav2));
50422 + memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
50423 + sav2.sadb_x_sa_ref=-1;
50424 + sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
50425 +
50426 + pfkey_sa = &sav2;
50427 + }
50428 +#endif
50429 +
50430 +
50431 + if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
50432 + ERROR(
50433 + "pfkey_sa_parse: "
50434 + "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
50435 + pfkey_sa->sadb_sa_len,
50436 + (int)sizeof(struct sadb_sa));
50437 + SENDERR(EINVAL);
50438 + }
50439 +
50440 +#if SADB_EALG_MAX < 255
50441 + if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
50442 + ERROR(
50443 + "pfkey_sa_parse: "
50444 + "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
50445 + pfkey_sa->sadb_sa_encrypt,
50446 + SADB_EALG_MAX);
50447 + SENDERR(EINVAL);
50448 + }
50449 +#endif
50450 +
50451 +#if SADB_AALG_MAX < 255
50452 + if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
50453 + ERROR(
50454 + "pfkey_sa_parse: "
50455 + "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
50456 + pfkey_sa->sadb_sa_auth,
50457 + SADB_AALG_MAX);
50458 + SENDERR(EINVAL);
50459 + }
50460 +#endif
50461 +
50462 +#if SADB_SASTATE_MAX < 255
50463 + if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
50464 + ERROR(
50465 + "pfkey_sa_parse: "
50466 + "state=%d exceeds MAX=%d.\n",
50467 + pfkey_sa->sadb_sa_state,
50468 + SADB_SASTATE_MAX);
50469 + SENDERR(EINVAL);
50470 + }
50471 +#endif
50472 +
50473 + if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
50474 + ERROR(
50475 + "pfkey_sa_parse: "
50476 + "state=%d is DEAD=%d.\n",
50477 + pfkey_sa->sadb_sa_state,
50478 + SADB_SASTATE_DEAD);
50479 + SENDERR(EINVAL);
50480 + }
50481 +
50482 + if(pfkey_sa->sadb_sa_replay > 64) {
50483 + ERROR(
50484 + "pfkey_sa_parse: "
50485 + "replay window size: %d -- must be 0 <= size <= 64\n",
50486 + pfkey_sa->sadb_sa_replay);
50487 + SENDERR(EINVAL);
50488 + }
50489 +
50490 + if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
50491 + (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
50492 + {
50493 + ERROR(
50494 + "pfkey_sa_parse: "
50495 + "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
50496 + pfkey_sa->sadb_sa_exttype,
50497 + SADB_EXT_SA,
50498 + SADB_X_EXT_SA2);
50499 + SENDERR(EINVAL);
50500 + }
50501 +
50502 + if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
50503 + ERROR(
50504 + "pfkey_sa_parse: "
50505 + "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
50506 + pfkey_sa->sadb_x_sa_ref,
50507 + IPSEC_SAREF_NULL,
50508 + IPSEC_SA_REF_TABLE_NUM_ENTRIES);
50509 + SENDERR(EINVAL);
50510 + }
50511 +
50512 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50513 + "pfkey_sa_parse: "
50514 + "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
50515 + pfkey_sa->sadb_sa_len,
50516 + pfkey_sa->sadb_sa_exttype,
50517 + pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
50518 + (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
50519 + pfkey_sa->sadb_sa_replay,
50520 + pfkey_sa->sadb_sa_state,
50521 + pfkey_sa->sadb_sa_auth,
50522 + pfkey_sa->sadb_sa_encrypt,
50523 + pfkey_sa->sadb_sa_flags,
50524 + pfkey_sa->sadb_x_sa_ref);
50525 +
50526 + errlab:
50527 + return error;
50528 +}
50529 +
50530 +DEBUG_NO_STATIC int
50531 +pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
50532 +{
50533 + int error = 0;
50534 + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
50535 +
50536 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50537 + "pfkey_lifetime_parse:enter\n");
50538 + /* sanity checks... */
50539 + if(!pfkey_lifetime) {
50540 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50541 + "pfkey_lifetime_parse: "
50542 + "NULL pointer passed in.\n");
50543 + SENDERR(EINVAL);
50544 + }
50545 +
50546 + if(pfkey_lifetime->sadb_lifetime_len !=
50547 + sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
50548 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50549 + "pfkey_lifetime_parse: "
50550 + "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
50551 + pfkey_lifetime->sadb_lifetime_len,
50552 + (int)sizeof(struct sadb_lifetime));
50553 + SENDERR(EINVAL);
50554 + }
50555 +
50556 + if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
50557 + (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
50558 + (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
50559 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50560 + "pfkey_lifetime_parse: "
50561 + "unexpected ext_type=%d.\n",
50562 + pfkey_lifetime->sadb_lifetime_exttype);
50563 + SENDERR(EINVAL);
50564 + }
50565 +
50566 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50567 + "pfkey_lifetime_parse: "
50568 + "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n",
50569 + pfkey_lifetime->sadb_lifetime_exttype,
50570 + pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
50571 + pfkey_lifetime->sadb_lifetime_allocations,
50572 + (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
50573 + (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
50574 + (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
50575 + pfkey_lifetime->sadb_x_lifetime_packets);
50576 +errlab:
50577 + return error;
50578 +}
50579 +
50580 +DEBUG_NO_STATIC int
50581 +pfkey_address_parse(struct sadb_ext *pfkey_ext)
50582 +{
50583 + int error = 0;
50584 + int saddr_len = 0;
50585 + struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
50586 + struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
50587 + char ipaddr_txt[ADDRTOT_BUF];
50588 +
50589 + /* sanity checks... */
50590 + if(!pfkey_address) {
50591 + ERROR(
50592 + "pfkey_address_parse: "
50593 + "NULL pointer passed in.\n");
50594 + SENDERR(EINVAL);
50595 + }
50596 +
50597 + if(pfkey_address->sadb_address_len <
50598 + (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
50599 + IPSEC_PFKEYv2_ALIGN) {
50600 + ERROR("pfkey_address_parse: "
50601 + "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
50602 + pfkey_address->sadb_address_len,
50603 + (int)sizeof(struct sadb_address),
50604 + (int)sizeof(struct sockaddr));
50605 + SENDERR(EINVAL);
50606 + }
50607 +
50608 + if(pfkey_address->sadb_address_reserved) {
50609 + ERROR("pfkey_address_parse: "
50610 + "res=%d, must be zero.\n",
50611 + pfkey_address->sadb_address_reserved);
50612 + SENDERR(EINVAL);
50613 + }
50614 +
50615 + switch(pfkey_address->sadb_address_exttype) {
50616 + case SADB_EXT_ADDRESS_SRC:
50617 + case SADB_EXT_ADDRESS_DST:
50618 + case SADB_EXT_ADDRESS_PROXY:
50619 + case SADB_X_EXT_ADDRESS_DST2:
50620 + case SADB_X_EXT_ADDRESS_SRC_FLOW:
50621 + case SADB_X_EXT_ADDRESS_DST_FLOW:
50622 + case SADB_X_EXT_ADDRESS_SRC_MASK:
50623 + case SADB_X_EXT_ADDRESS_DST_MASK:
50624 +#ifdef NAT_TRAVERSAL
50625 + case SADB_X_EXT_NAT_T_OA:
50626 +#endif
50627 + break;
50628 + default:
50629 + ERROR(
50630 + "pfkey_address_parse: "
50631 + "unexpected ext_type=%d.\n",
50632 + pfkey_address->sadb_address_exttype);
50633 + SENDERR(ENOPKG);
50634 + }
50635 +
50636 + switch(s->sa_family) {
50637 + case AF_INET:
50638 + saddr_len = sizeof(struct sockaddr_in);
50639 + sprintf(ipaddr_txt, "%d.%d.%d.%d"
50640 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
50641 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
50642 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
50643 + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
50644 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50645 + "pfkey_address_parse: "
50646 + "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
50647 + pfkey_address->sadb_address_exttype,
50648 + pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
50649 + s->sa_family,
50650 + ipaddr_txt,
50651 + pfkey_address->sadb_address_proto,
50652 + ntohs(((struct sockaddr_in*)s)->sin_port));
50653 + break;
50654 + case AF_INET6:
50655 + saddr_len = sizeof(struct sockaddr_in6);
50656 + sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
50657 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
50658 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
50659 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
50660 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
50661 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
50662 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
50663 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
50664 + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
50665 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50666 + "pfkey_address_parse: "
50667 + "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
50668 + pfkey_address->sadb_address_exttype,
50669 + pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
50670 + s->sa_family,
50671 + ipaddr_txt,
50672 + pfkey_address->sadb_address_proto,
50673 + ((struct sockaddr_in6*)s)->sin6_port);
50674 + break;
50675 + default:
50676 + ERROR(
50677 + "pfkey_address_parse: "
50678 + "s->sa_family=%d not supported.\n",
50679 + s->sa_family);
50680 + SENDERR(EPFNOSUPPORT);
50681 + }
50682 +
50683 + if(pfkey_address->sadb_address_len !=
50684 + DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
50685 + ERROR(
50686 + "pfkey_address_parse: "
50687 + "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
50688 + pfkey_address->sadb_address_len,
50689 + (int)sizeof(struct sadb_address),
50690 + saddr_len);
50691 + SENDERR(EINVAL);
50692 + }
50693 +
50694 + if(pfkey_address->sadb_address_prefixlen != 0) {
50695 + ERROR(
50696 + "pfkey_address_parse: "
50697 + "address prefixes not supported yet.\n");
50698 + SENDERR(EAFNOSUPPORT); /* not supported yet */
50699 + }
50700 +
50701 + /* XXX check if port!=0 */
50702 +
50703 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
50704 + "pfkey_address_parse: successful.\n");
50705 + errlab:
50706 + return error;
50707 +}
50708 +
50709 +DEBUG_NO_STATIC int
50710 +pfkey_key_parse(struct sadb_ext *pfkey_ext)
50711 +{
50712 + int error = 0;
50713 + struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
50714 +
50715 + /* sanity checks... */
50716 +
50717 + if(!pfkey_key) {
50718 + ERROR(
50719 + "pfkey_key_parse: "
50720 + "NULL pointer passed in.\n");
50721 + SENDERR(EINVAL);
50722 + }
50723 +
50724 + if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
50725 + ERROR(
50726 + "pfkey_key_parse: "
50727 + "size wrong ext_len=%d, key_ext_len=%d.\n",
50728 + pfkey_key->sadb_key_len,
50729 + (int)sizeof(struct sadb_key));
50730 + SENDERR(EINVAL);
50731 + }
50732 +
50733 + if(!pfkey_key->sadb_key_bits) {
50734 + ERROR(
50735 + "pfkey_key_parse: "
50736 + "key length set to zero, must be non-zero.\n");
50737 + SENDERR(EINVAL);
50738 + }
50739 +
50740 + if(pfkey_key->sadb_key_len !=
50741 + DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
50742 + PFKEYBITS)) {
50743 + ERROR(
50744 + "pfkey_key_parse: "
50745 + "key length=%d does not agree with extension length=%d.\n",
50746 + pfkey_key->sadb_key_bits,
50747 + pfkey_key->sadb_key_len);
50748 + SENDERR(EINVAL);
50749 + }
50750 +
50751 + if(pfkey_key->sadb_key_reserved) {
50752 + ERROR(
50753 + "pfkey_key_parse: "
50754 + "res=%d, must be zero.\n",
50755 + pfkey_key->sadb_key_reserved);
50756 + SENDERR(EINVAL);
50757 + }
50758 +
50759 + if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
50760 + (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
50761 + ERROR(
50762 + "pfkey_key_parse: "
50763 + "expecting extension type AUTH or ENCRYPT, got %d.\n",
50764 + pfkey_key->sadb_key_exttype);
50765 + SENDERR(EINVAL);
50766 + }
50767 +
50768 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
50769 + "pfkey_key_parse: "
50770 + "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
50771 + pfkey_key->sadb_key_len,
50772 + pfkey_key->sadb_key_exttype,
50773 + pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
50774 + pfkey_key->sadb_key_bits,
50775 + pfkey_key->sadb_key_reserved);
50776 +
50777 +errlab:
50778 + return error;
50779 +}
50780 +
50781 +DEBUG_NO_STATIC int
50782 +pfkey_ident_parse(struct sadb_ext *pfkey_ext)
50783 +{
50784 + int error = 0;
50785 + struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
50786 +
50787 + /* sanity checks... */
50788 + if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
50789 + ERROR(
50790 + "pfkey_ident_parse: "
50791 + "size wrong ext_len=%d, key_ext_len=%d.\n",
50792 + pfkey_ident->sadb_ident_len,
50793 + (int)sizeof(struct sadb_ident));
50794 + SENDERR(EINVAL);
50795 + }
50796 +
50797 + if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
50798 + ERROR(
50799 + "pfkey_ident_parse: "
50800 + "ident_type=%d out of range, must be less than %d.\n",
50801 + pfkey_ident->sadb_ident_type,
50802 + SADB_IDENTTYPE_MAX);
50803 + SENDERR(EINVAL);
50804 + }
50805 +
50806 + if(pfkey_ident->sadb_ident_reserved) {
50807 + ERROR(
50808 + "pfkey_ident_parse: "
50809 + "res=%d, must be zero.\n",
50810 + pfkey_ident->sadb_ident_reserved);
50811 + SENDERR(EINVAL);
50812 + }
50813 +
50814 + /* string terminator/padding must be zero */
50815 + if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
50816 + if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
50817 + ERROR(
50818 + "pfkey_ident_parse: "
50819 + "string padding must be zero, last is 0x%02x.\n",
50820 + *((char*)pfkey_ident +
50821 + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
50822 + SENDERR(EINVAL);
50823 + }
50824 + }
50825 +
50826 + if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
50827 + (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
50828 + ERROR(
50829 + "pfkey_key_parse: "
50830 + "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
50831 + pfkey_ident->sadb_ident_exttype);
50832 + SENDERR(EINVAL);
50833 + }
50834 +
50835 +errlab:
50836 + return error;
50837 +}
50838 +
50839 +DEBUG_NO_STATIC int
50840 +pfkey_sens_parse(struct sadb_ext *pfkey_ext)
50841 +{
50842 + int error = 0;
50843 + struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
50844 +
50845 + /* sanity checks... */
50846 + if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
50847 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50848 + "pfkey_sens_parse: "
50849 + "size wrong ext_len=%d, key_ext_len=%d.\n",
50850 + pfkey_sens->sadb_sens_len,
50851 + (int)sizeof(struct sadb_sens));
50852 + SENDERR(EINVAL);
50853 + }
50854 +
50855 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50856 + "pfkey_sens_parse: "
50857 + "Sorry, I can't parse exttype=%d yet.\n",
50858 + pfkey_ext->sadb_ext_type);
50859 +#if 0
50860 + SENDERR(EINVAL); /* don't process these yet */
50861 +#endif
50862 +
50863 +errlab:
50864 + return error;
50865 +}
50866 +
50867 +DEBUG_NO_STATIC int
50868 +pfkey_prop_parse(struct sadb_ext *pfkey_ext)
50869 +{
50870 + int error = 0;
50871 + int i, num_comb;
50872 + struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
50873 + struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
50874 +
50875 + /* sanity checks... */
50876 + if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
50877 + (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
50878 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50879 + "pfkey_prop_parse: "
50880 + "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
50881 + pfkey_prop->sadb_prop_len,
50882 + (int)sizeof(struct sadb_prop),
50883 + (int)sizeof(struct sadb_comb));
50884 + SENDERR(EINVAL);
50885 + }
50886 +
50887 + if(pfkey_prop->sadb_prop_replay > 64) {
50888 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50889 + "pfkey_prop_parse: "
50890 + "replay window size: %d -- must be 0 <= size <= 64\n",
50891 + pfkey_prop->sadb_prop_replay);
50892 + SENDERR(EINVAL);
50893 + }
50894 +
50895 + for(i=0; i<3; i++) {
50896 + if(pfkey_prop->sadb_prop_reserved[i]) {
50897 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50898 + "pfkey_prop_parse: "
50899 + "res[%d]=%d, must be zero.\n",
50900 + i, pfkey_prop->sadb_prop_reserved[i]);
50901 + SENDERR(EINVAL);
50902 + }
50903 + }
50904 +
50905 + num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
50906 +
50907 + for(i = 0; i < num_comb; i++) {
50908 + if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
50909 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50910 + "pfkey_prop_parse: "
50911 + "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
50912 + i,
50913 + pfkey_comb->sadb_comb_auth,
50914 + SADB_AALG_MAX);
50915 + SENDERR(EINVAL);
50916 + }
50917 +
50918 + if(pfkey_comb->sadb_comb_auth) {
50919 + if(!pfkey_comb->sadb_comb_auth_minbits) {
50920 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50921 + "pfkey_prop_parse: "
50922 + "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
50923 + i);
50924 + SENDERR(EINVAL);
50925 + }
50926 + if(!pfkey_comb->sadb_comb_auth_maxbits) {
50927 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50928 + "pfkey_prop_parse: "
50929 + "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
50930 + i);
50931 + SENDERR(EINVAL);
50932 + }
50933 + if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
50934 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50935 + "pfkey_prop_parse: "
50936 + "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
50937 + i,
50938 + pfkey_comb->sadb_comb_auth_minbits,
50939 + pfkey_comb->sadb_comb_auth_maxbits);
50940 + SENDERR(EINVAL);
50941 + }
50942 + } else {
50943 + if(pfkey_comb->sadb_comb_auth_minbits) {
50944 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50945 + "pfkey_prop_parse: "
50946 + "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
50947 + i,
50948 + pfkey_comb->sadb_comb_auth_minbits);
50949 + SENDERR(EINVAL);
50950 + }
50951 + if(pfkey_comb->sadb_comb_auth_maxbits) {
50952 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50953 + "pfkey_prop_parse: "
50954 + "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
50955 + i,
50956 + pfkey_comb->sadb_comb_auth_maxbits);
50957 + SENDERR(EINVAL);
50958 + }
50959 + }
50960 +
50961 +#if SADB_EALG_MAX < 255
50962 + if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
50963 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50964 + "pfkey_comb_parse: "
50965 + "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
50966 + i,
50967 + pfkey_comb->sadb_comb_encrypt,
50968 + SADB_EALG_MAX);
50969 + SENDERR(EINVAL);
50970 + }
50971 +#endif
50972 +
50973 + if(pfkey_comb->sadb_comb_encrypt) {
50974 + if(!pfkey_comb->sadb_comb_encrypt_minbits) {
50975 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50976 + "pfkey_prop_parse: "
50977 + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
50978 + i);
50979 + SENDERR(EINVAL);
50980 + }
50981 + if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
50982 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50983 + "pfkey_prop_parse: "
50984 + "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
50985 + i);
50986 + SENDERR(EINVAL);
50987 + }
50988 + if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
50989 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
50990 + "pfkey_prop_parse: "
50991 + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
50992 + i,
50993 + pfkey_comb->sadb_comb_encrypt_minbits,
50994 + pfkey_comb->sadb_comb_encrypt_maxbits);
50995 + SENDERR(EINVAL);
50996 + }
50997 + } else {
50998 + if(pfkey_comb->sadb_comb_encrypt_minbits) {
50999 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51000 + "pfkey_prop_parse: "
51001 + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
51002 + i,
51003 + pfkey_comb->sadb_comb_encrypt_minbits);
51004 + SENDERR(EINVAL);
51005 + }
51006 + if(pfkey_comb->sadb_comb_encrypt_maxbits) {
51007 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51008 + "pfkey_prop_parse: "
51009 + "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
51010 + i,
51011 + pfkey_comb->sadb_comb_encrypt_maxbits);
51012 + SENDERR(EINVAL);
51013 + }
51014 + }
51015 +
51016 + /* XXX do sanity check on flags */
51017 +
51018 + if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
51019 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51020 + "pfkey_prop_parse: "
51021 + "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
51022 + i,
51023 + pfkey_comb->sadb_comb_soft_allocations,
51024 + pfkey_comb->sadb_comb_hard_allocations);
51025 + SENDERR(EINVAL);
51026 + }
51027 +
51028 + if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
51029 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51030 + "pfkey_prop_parse: "
51031 + "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
51032 + i,
51033 + (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
51034 + (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
51035 + SENDERR(EINVAL);
51036 + }
51037 +
51038 + if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
51039 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51040 + "pfkey_prop_parse: "
51041 + "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
51042 + i,
51043 + (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
51044 + (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
51045 + SENDERR(EINVAL);
51046 + }
51047 +
51048 + if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
51049 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51050 + "pfkey_prop_parse: "
51051 + "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
51052 + i,
51053 + (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
51054 + (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
51055 + SENDERR(EINVAL);
51056 + }
51057 +
51058 + if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
51059 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51060 + "pfkey_prop_parse: "
51061 + "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
51062 + i,
51063 + pfkey_comb->sadb_x_comb_soft_packets,
51064 + pfkey_comb->sadb_x_comb_hard_packets);
51065 + SENDERR(EINVAL);
51066 + }
51067 +
51068 + if(pfkey_comb->sadb_comb_reserved) {
51069 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51070 + "pfkey_prop_parse: "
51071 + "comb[%d].res=%d, must be zero.\n",
51072 + i,
51073 + pfkey_comb->sadb_comb_reserved);
51074 + SENDERR(EINVAL);
51075 + }
51076 + pfkey_comb++;
51077 + }
51078 +
51079 +errlab:
51080 + return error;
51081 +}
51082 +
51083 +DEBUG_NO_STATIC int
51084 +pfkey_supported_parse(struct sadb_ext *pfkey_ext)
51085 +{
51086 + int error = 0;
51087 + unsigned int i, num_alg;
51088 + struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
51089 + struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
51090 +
51091 + /* sanity checks... */
51092 + if((pfkey_supported->sadb_supported_len <
51093 + sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
51094 + (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
51095 + sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
51096 +
51097 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51098 + "pfkey_supported_parse: "
51099 + "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
51100 + pfkey_supported->sadb_supported_len,
51101 + (int)sizeof(struct sadb_supported),
51102 + (int)sizeof(struct sadb_alg));
51103 + SENDERR(EINVAL);
51104 + }
51105 +
51106 + if(pfkey_supported->sadb_supported_reserved) {
51107 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51108 + "pfkey_supported_parse: "
51109 + "res=%d, must be zero.\n",
51110 + pfkey_supported->sadb_supported_reserved);
51111 + SENDERR(EINVAL);
51112 + }
51113 +
51114 + num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
51115 +
51116 + for(i = 0; i < num_alg; i++) {
51117 + /* process algo description */
51118 + if(pfkey_alg->sadb_alg_reserved) {
51119 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51120 + "pfkey_supported_parse: "
51121 + "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
51122 + i,
51123 + pfkey_alg->sadb_alg_id,
51124 + pfkey_alg->sadb_alg_ivlen,
51125 + pfkey_alg->sadb_alg_minbits,
51126 + pfkey_alg->sadb_alg_maxbits,
51127 + pfkey_alg->sadb_alg_reserved);
51128 + SENDERR(EINVAL);
51129 + }
51130 +
51131 + /* XXX can alg_id auth/enc be determined from info given?
51132 + Yes, but OpenBSD's method does not iteroperate with rfc2367.
51133 + rgb, 2000-04-06 */
51134 +
51135 + switch(pfkey_supported->sadb_supported_exttype) {
51136 + case SADB_EXT_SUPPORTED_AUTH:
51137 + if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
51138 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51139 + "pfkey_supported_parse: "
51140 + "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
51141 + i,
51142 + pfkey_alg->sadb_alg_id,
51143 + SADB_AALG_MAX);
51144 + SENDERR(EINVAL);
51145 + }
51146 + break;
51147 + case SADB_EXT_SUPPORTED_ENCRYPT:
51148 +#if SADB_EALG_MAX < 255
51149 + if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
51150 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51151 + "pfkey_supported_parse: "
51152 + "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
51153 + i,
51154 + pfkey_alg->sadb_alg_id,
51155 + SADB_EALG_MAX);
51156 + SENDERR(EINVAL);
51157 + }
51158 +#endif
51159 + break;
51160 + default:
51161 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51162 + "pfkey_supported_parse: "
51163 + "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
51164 + i,
51165 + pfkey_alg->sadb_alg_id,
51166 + SADB_EALG_MAX);
51167 + SENDERR(EINVAL);
51168 + }
51169 + pfkey_alg++;
51170 + }
51171 +
51172 + errlab:
51173 + return error;
51174 +}
51175 +
51176 +DEBUG_NO_STATIC int
51177 +pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
51178 +{
51179 + int error = 0;
51180 + struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
51181 +
51182 + /* sanity checks... */
51183 + if(pfkey_spirange->sadb_spirange_len !=
51184 + sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
51185 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51186 + "pfkey_spirange_parse: "
51187 + "size wrong ext_len=%d, key_ext_len=%d.\n",
51188 + pfkey_spirange->sadb_spirange_len,
51189 + (int)sizeof(struct sadb_spirange));
51190 + SENDERR(EINVAL);
51191 + }
51192 +
51193 + if(pfkey_spirange->sadb_spirange_reserved) {
51194 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51195 + "pfkey_spirange_parse: "
51196 + "reserved=%d must be set to zero.\n",
51197 + pfkey_spirange->sadb_spirange_reserved);
51198 + SENDERR(EINVAL);
51199 + }
51200 +
51201 + if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
51202 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51203 + "pfkey_spirange_parse: "
51204 + "minspi=%08x must be < maxspi=%08x.\n",
51205 + ntohl(pfkey_spirange->sadb_spirange_min),
51206 + ntohl(pfkey_spirange->sadb_spirange_max));
51207 + SENDERR(EINVAL);
51208 + }
51209 +
51210 + if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
51211 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51212 + "pfkey_spirange_parse: "
51213 + "minspi=%08x must be > 255.\n",
51214 + ntohl(pfkey_spirange->sadb_spirange_min));
51215 + SENDERR(EEXIST);
51216 + }
51217 +
51218 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51219 + "pfkey_spirange_parse: "
51220 + "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
51221 + pfkey_spirange->sadb_spirange_len,
51222 + pfkey_spirange->sadb_spirange_exttype,
51223 + pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
51224 + pfkey_spirange->sadb_spirange_min,
51225 + pfkey_spirange->sadb_spirange_max,
51226 + pfkey_spirange->sadb_spirange_reserved);
51227 + errlab:
51228 + return error;
51229 +}
51230 +
51231 +DEBUG_NO_STATIC int
51232 +pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
51233 +{
51234 + int error = 0;
51235 + struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
51236 +
51237 + /* sanity checks... */
51238 + if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
51239 + sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
51240 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51241 + "pfkey_x_kmprivate_parse: "
51242 + "size wrong ext_len=%d, key_ext_len=%d.\n",
51243 + pfkey_x_kmprivate->sadb_x_kmprivate_len,
51244 + (int)sizeof(struct sadb_x_kmprivate));
51245 + SENDERR(EINVAL);
51246 + }
51247 +
51248 + if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
51249 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51250 + "pfkey_x_kmprivate_parse: "
51251 + "reserved=%d must be set to zero.\n",
51252 + pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
51253 + SENDERR(EINVAL);
51254 + }
51255 +
51256 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51257 + "pfkey_x_kmprivate_parse: "
51258 + "Sorry, I can't parse exttype=%d yet.\n",
51259 + pfkey_ext->sadb_ext_type);
51260 + SENDERR(EINVAL); /* don't process these yet */
51261 +
51262 +errlab:
51263 + return error;
51264 +}
51265 +
51266 +DEBUG_NO_STATIC int
51267 +pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
51268 +{
51269 + int error = 0;
51270 + int i;
51271 + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
51272 +
51273 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51274 + "pfkey_x_satype_parse: enter\n");
51275 + /* sanity checks... */
51276 + if(pfkey_x_satype->sadb_x_satype_len !=
51277 + sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
51278 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51279 + "pfkey_x_satype_parse: "
51280 + "size wrong ext_len=%d, key_ext_len=%d.\n",
51281 + pfkey_x_satype->sadb_x_satype_len,
51282 + (int)sizeof(struct sadb_x_satype));
51283 + SENDERR(EINVAL);
51284 + }
51285 +
51286 + if(!pfkey_x_satype->sadb_x_satype_satype) {
51287 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51288 + "pfkey_x_satype_parse: "
51289 + "satype is zero, must be non-zero.\n");
51290 + SENDERR(EINVAL);
51291 + }
51292 +
51293 + if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
51294 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51295 + "pfkey_x_satype_parse: "
51296 + "satype %d > max %d, invalid.\n",
51297 + pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
51298 + SENDERR(EINVAL);
51299 + }
51300 +
51301 + if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
51302 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51303 + "pfkey_x_satype_parse: "
51304 + "proto lookup from satype=%d failed.\n",
51305 + pfkey_x_satype->sadb_x_satype_satype);
51306 + SENDERR(EINVAL);
51307 + }
51308 +
51309 + for(i = 0; i < 3; i++) {
51310 + if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
51311 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51312 + "pfkey_x_satype_parse: "
51313 + "reserved[%d]=%d must be set to zero.\n",
51314 + i, pfkey_x_satype->sadb_x_satype_reserved[i]);
51315 + SENDERR(EINVAL);
51316 + }
51317 + }
51318 +
51319 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51320 + "pfkey_x_satype_parse: "
51321 + "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
51322 + pfkey_x_satype->sadb_x_satype_len,
51323 + pfkey_x_satype->sadb_x_satype_exttype,
51324 + pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
51325 + pfkey_x_satype->sadb_x_satype_satype,
51326 + satype2name(pfkey_x_satype->sadb_x_satype_satype),
51327 + pfkey_x_satype->sadb_x_satype_reserved[0],
51328 + pfkey_x_satype->sadb_x_satype_reserved[1],
51329 + pfkey_x_satype->sadb_x_satype_reserved[2]);
51330 +errlab:
51331 + return error;
51332 +}
51333 +
51334 +DEBUG_NO_STATIC int
51335 +pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
51336 +{
51337 + int error = 0;
51338 + int i;
51339 + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
51340 +
51341 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51342 + "pfkey_x_debug_parse: enter\n");
51343 + /* sanity checks... */
51344 + if(pfkey_x_debug->sadb_x_debug_len !=
51345 + sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
51346 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51347 + "pfkey_x_debug_parse: "
51348 + "size wrong ext_len=%d, key_ext_len=%d.\n",
51349 + pfkey_x_debug->sadb_x_debug_len,
51350 + (int)sizeof(struct sadb_x_debug));
51351 + SENDERR(EINVAL);
51352 + }
51353 +
51354 + for(i = 0; i < 4; i++) {
51355 + if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
51356 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51357 + "pfkey_x_debug_parse: "
51358 + "reserved[%d]=%d must be set to zero.\n",
51359 + i, pfkey_x_debug->sadb_x_debug_reserved[i]);
51360 + SENDERR(EINVAL);
51361 + }
51362 + }
51363 +
51364 +errlab:
51365 + return error;
51366 +}
51367 +
51368 +DEBUG_NO_STATIC int
51369 +pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
51370 +{
51371 + int error = 0;
51372 + struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
51373 +
51374 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
51375 + /* sanity checks... */
51376 +
51377 + if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
51378 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51379 + "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
51380 + p->sadb_protocol_len, (int)sizeof(*p));
51381 + SENDERR(EINVAL);
51382 + }
51383 +
51384 + if (p->sadb_protocol_reserved2 != 0) {
51385 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51386 + "pfkey_protocol_parse: res=%d, must be zero.\n",
51387 + p->sadb_protocol_reserved2);
51388 + SENDERR(EINVAL);
51389 + }
51390 +
51391 + errlab:
51392 + return error;
51393 +}
51394 +
51395 +#ifdef NAT_TRAVERSAL
51396 +DEBUG_NO_STATIC int
51397 +pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
51398 +{
51399 + return 0;
51400 +}
51401 +DEBUG_NO_STATIC int
51402 +pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
51403 +{
51404 + return 0;
51405 +}
51406 +#endif
51407 +
51408 +#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
51409 +
51410 +DEFINEPARSER(pfkey_sa_parse);
51411 +DEFINEPARSER(pfkey_lifetime_parse);
51412 +DEFINEPARSER(pfkey_address_parse);
51413 +DEFINEPARSER(pfkey_key_parse);
51414 +DEFINEPARSER(pfkey_ident_parse);
51415 +DEFINEPARSER(pfkey_sens_parse);
51416 +DEFINEPARSER(pfkey_prop_parse);
51417 +DEFINEPARSER(pfkey_supported_parse);
51418 +DEFINEPARSER(pfkey_spirange_parse);
51419 +DEFINEPARSER(pfkey_x_kmprivate_parse);
51420 +DEFINEPARSER(pfkey_x_satype_parse);
51421 +DEFINEPARSER(pfkey_x_ext_debug_parse);
51422 +DEFINEPARSER(pfkey_x_ext_protocol_parse);
51423 +#ifdef NAT_TRAVERSAL
51424 +DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
51425 +DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
51426 +#endif
51427 +
51428 +struct pf_key_ext_parsers_def *ext_default_parsers[]=
51429 +{
51430 + NULL, /* pfkey_msg_parse, */
51431 + &pfkey_sa_parse_def,
51432 + &pfkey_lifetime_parse_def,
51433 + &pfkey_lifetime_parse_def,
51434 + &pfkey_lifetime_parse_def,
51435 + &pfkey_address_parse_def,
51436 + &pfkey_address_parse_def,
51437 + &pfkey_address_parse_def,
51438 + &pfkey_key_parse_def,
51439 + &pfkey_key_parse_def,
51440 + &pfkey_ident_parse_def,
51441 + &pfkey_ident_parse_def,
51442 + &pfkey_sens_parse_def,
51443 + &pfkey_prop_parse_def,
51444 + &pfkey_supported_parse_def,
51445 + &pfkey_supported_parse_def,
51446 + &pfkey_spirange_parse_def,
51447 + &pfkey_x_kmprivate_parse_def,
51448 + &pfkey_x_satype_parse_def,
51449 + &pfkey_sa_parse_def,
51450 + &pfkey_address_parse_def,
51451 + &pfkey_address_parse_def,
51452 + &pfkey_address_parse_def,
51453 + &pfkey_address_parse_def,
51454 + &pfkey_address_parse_def,
51455 + &pfkey_x_ext_debug_parse_def,
51456 + &pfkey_x_ext_protocol_parse_def
51457 +#ifdef NAT_TRAVERSAL
51458 + ,
51459 + &pfkey_x_ext_nat_t_type_parse_def,
51460 + &pfkey_x_ext_nat_t_port_parse_def,
51461 + &pfkey_x_ext_nat_t_port_parse_def,
51462 + &pfkey_address_parse_def
51463 +#endif
51464 +};
51465 +
51466 +int
51467 +pfkey_msg_parse(struct sadb_msg *pfkey_msg,
51468 + struct pf_key_ext_parsers_def *ext_parsers[],
51469 + struct sadb_ext *extensions[],
51470 + int dir)
51471 +{
51472 + int error = 0;
51473 + int remain;
51474 + struct sadb_ext *pfkey_ext;
51475 + int extensions_seen = 0;
51476 +
51477 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51478 + "pfkey_msg_parse: "
51479 + "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
51480 + pfkey_msg->sadb_msg_version,
51481 + pfkey_msg->sadb_msg_type,
51482 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
51483 + pfkey_msg->sadb_msg_errno,
51484 + pfkey_msg->sadb_msg_satype,
51485 + satype2name(pfkey_msg->sadb_msg_satype),
51486 + pfkey_msg->sadb_msg_len,
51487 + pfkey_msg->sadb_msg_reserved,
51488 + pfkey_msg->sadb_msg_seq,
51489 + pfkey_msg->sadb_msg_pid);
51490 +
51491 + if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
51492 +
51493 + pfkey_extensions_init(extensions);
51494 +
51495 + remain = pfkey_msg->sadb_msg_len;
51496 + remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
51497 +
51498 + pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
51499 + sizeof(struct sadb_msg));
51500 +
51501 + extensions[0] = (struct sadb_ext *) pfkey_msg;
51502 +
51503 +
51504 + if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
51505 + ERROR("pfkey_msg_parse: "
51506 + "not PF_KEY_V2 msg, found %d, should be %d.\n",
51507 + pfkey_msg->sadb_msg_version,
51508 + PF_KEY_V2);
51509 + SENDERR(EINVAL);
51510 + }
51511 +
51512 + if(!pfkey_msg->sadb_msg_type) {
51513 + ERROR("pfkey_msg_parse: "
51514 + "msg type not set, must be non-zero..\n");
51515 + SENDERR(EINVAL);
51516 + }
51517 +
51518 + if(pfkey_msg->sadb_msg_type > SADB_MAX) {
51519 + ERROR("pfkey_msg_parse: "
51520 + "msg type=%d > max=%d.\n",
51521 + pfkey_msg->sadb_msg_type,
51522 + SADB_MAX);
51523 + SENDERR(EINVAL);
51524 + }
51525 +
51526 + switch(pfkey_msg->sadb_msg_type) {
51527 + case SADB_GETSPI:
51528 + case SADB_UPDATE:
51529 + case SADB_ADD:
51530 + case SADB_DELETE:
51531 + case SADB_GET:
51532 + case SADB_X_GRPSA:
51533 + case SADB_X_ADDFLOW:
51534 + if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
51535 + ERROR("pfkey_msg_parse: "
51536 + "satype %d conversion to proto failed for msg_type %d (%s).\n",
51537 + pfkey_msg->sadb_msg_satype,
51538 + pfkey_msg->sadb_msg_type,
51539 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51540 + SENDERR(EINVAL);
51541 + } else {
51542 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51543 + "pfkey_msg_parse: "
51544 + "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
51545 + pfkey_msg->sadb_msg_satype,
51546 + satype2name(pfkey_msg->sadb_msg_satype),
51547 + satype2proto(pfkey_msg->sadb_msg_satype),
51548 + pfkey_msg->sadb_msg_type,
51549 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51550 + }
51551 + case SADB_ACQUIRE:
51552 + case SADB_REGISTER:
51553 + case SADB_EXPIRE:
51554 + if(!pfkey_msg->sadb_msg_satype) {
51555 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51556 + "pfkey_msg_parse: "
51557 + "satype is zero, must be non-zero for msg_type %d(%s).\n",
51558 + pfkey_msg->sadb_msg_type,
51559 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
51560 + SENDERR(EINVAL);
51561 + }
51562 + default:
51563 + break;
51564 + }
51565 +
51566 + /* errno must not be set in downward messages */
51567 + /* this is not entirely true... a response to an ACQUIRE could return an error */
51568 + if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
51569 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51570 + "pfkey_msg_parse: "
51571 + "errno set to %d.\n",
51572 + pfkey_msg->sadb_msg_errno);
51573 + SENDERR(EINVAL);
51574 + }
51575 +
51576 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51577 + "pfkey_msg_parse: "
51578 + "remain=%d\n",
51579 + remain
51580 + );
51581 +
51582 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51583 + "pfkey_msg_parse: "
51584 + "extensions permitted=%08x, required=%08x.\n",
51585 + extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51586 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
51587 +
51588 + extensions_seen = 1;
51589 +
51590 + while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
51591 + /* Is there enough message left to support another extension header? */
51592 + if(remain < pfkey_ext->sadb_ext_len) {
51593 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51594 + "pfkey_msg_parse: "
51595 + "remain %d less than ext len %d.\n",
51596 + remain, pfkey_ext->sadb_ext_len);
51597 + SENDERR(EINVAL);
51598 + }
51599 +
51600 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51601 + "pfkey_msg_parse: "
51602 + "parsing ext type=%d(%s) remain=%d.\n",
51603 + pfkey_ext->sadb_ext_type,
51604 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51605 + remain);
51606 +
51607 + /* Is the extension header type valid? */
51608 + if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
51609 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51610 + "pfkey_msg_parse: "
51611 + "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
51612 + pfkey_ext->sadb_ext_type,
51613 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51614 + SADB_EXT_MAX);
51615 + SENDERR(EINVAL);
51616 + }
51617 +
51618 + /* Have we already seen this type of extension? */
51619 + if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
51620 + {
51621 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51622 + "pfkey_msg_parse: "
51623 + "ext type %d(%s) already seen.\n",
51624 + pfkey_ext->sadb_ext_type,
51625 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51626 + SENDERR(EINVAL);
51627 + }
51628 +
51629 + /* Do I even know about this type of extension? */
51630 + if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
51631 + ERROR("pfkey_msg_parse: "
51632 + "ext type %d(%s) unknown, ignoring.\n",
51633 + pfkey_ext->sadb_ext_type,
51634 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51635 + goto next_ext;
51636 + }
51637 +
51638 + /* Is this type of extension permitted for this type of message? */
51639 + if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
51640 + 1<<pfkey_ext->sadb_ext_type)) {
51641 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51642 + "pfkey_msg_parse: "
51643 + "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
51644 + pfkey_ext->sadb_ext_type,
51645 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51646 + extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51647 + 1<<pfkey_ext->sadb_ext_type);
51648 + SENDERR(EINVAL);
51649 + }
51650 +
51651 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51652 + "pfkey_msg_parse: "
51653 + "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
51654 + remain,
51655 + pfkey_ext->sadb_ext_type,
51656 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51657 + pfkey_ext->sadb_ext_len,
51658 + pfkey_ext,
51659 + ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
51660 +
51661 + /* Parse the extension */
51662 + if((error =
51663 + (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
51664 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51665 + "pfkey_msg_parse: "
51666 + "extension parsing for type %d(%s) failed with error %d.\n",
51667 + pfkey_ext->sadb_ext_type,
51668 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
51669 + error);
51670 + SENDERR(-error);
51671 + }
51672 + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
51673 + "pfkey_msg_parse: "
51674 + "Extension %d(%s) parsed.\n",
51675 + pfkey_ext->sadb_ext_type,
51676 + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
51677 +
51678 + /* Mark that we have seen this extension and remember the header location */
51679 + extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
51680 + extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
51681 +
51682 + next_ext:
51683 + /* Calculate how much message remains */
51684 + remain -= pfkey_ext->sadb_ext_len;
51685 +
51686 + if(!remain) {
51687 + break;
51688 + }
51689 + /* Find the next extension header */
51690 + pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
51691 + pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
51692 + }
51693 +
51694 + if(remain) {
51695 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51696 + "pfkey_msg_parse: "
51697 + "unexpected remainder of %d.\n",
51698 + remain);
51699 + /* why is there still something remaining? */
51700 + SENDERR(EINVAL);
51701 + }
51702 +
51703 + /* check required extensions */
51704 + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
51705 + "pfkey_msg_parse: "
51706 + "extensions permitted=%08x, seen=%08x, required=%08x.\n",
51707 + extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
51708 + extensions_seen,
51709 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
51710 +
51711 + /* don't check further if it is an error return message since it
51712 + may not have a body */
51713 + if(pfkey_msg->sadb_msg_errno) {
51714 + SENDERR(-error);
51715 + }
51716 +
51717 + if((extensions_seen &
51718 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
51719 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
51720 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51721 + "pfkey_msg_parse: "
51722 + "required extensions missing:%08x.\n",
51723 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
51724 + (extensions_seen &
51725 + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
51726 + SENDERR(EINVAL);
51727 + }
51728 +
51729 + if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
51730 + && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
51731 + != SADB_X_EXT_ADDRESS_DELFLOW)
51732 + && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
51733 + || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
51734 + & SADB_X_SAFLAGS_CLEARFLOW)
51735 + != SADB_X_SAFLAGS_CLEARFLOW))) {
51736 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51737 + "pfkey_msg_parse: "
51738 + "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
51739 + SADB_X_EXT_ADDRESS_DELFLOW
51740 + - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
51741 + (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
51742 + SENDERR(EINVAL);
51743 + }
51744 +
51745 + switch(pfkey_msg->sadb_msg_type) {
51746 + case SADB_ADD:
51747 + case SADB_UPDATE:
51748 + /* check maturity */
51749 + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
51750 + SADB_SASTATE_MATURE) {
51751 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51752 + "pfkey_msg_parse: "
51753 + "state=%d for add or update should be MATURE=%d.\n",
51754 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
51755 + SADB_SASTATE_MATURE);
51756 + SENDERR(EINVAL);
51757 + }
51758 +
51759 + /* check AH and ESP */
51760 + switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
51761 + case SADB_SATYPE_AH:
51762 + if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
51763 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
51764 + SADB_AALG_NONE)) {
51765 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51766 + "pfkey_msg_parse: "
51767 + "auth alg is zero, must be non-zero for AH SAs.\n");
51768 + SENDERR(EINVAL);
51769 + }
51770 + if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
51771 + SADB_EALG_NONE) {
51772 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51773 + "pfkey_msg_parse: "
51774 + "AH handed encalg=%d, must be zero.\n",
51775 + ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
51776 + SENDERR(EINVAL);
51777 + }
51778 + break;
51779 + case SADB_SATYPE_ESP:
51780 + if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
51781 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
51782 + SADB_EALG_NONE)) {
51783 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51784 + "pfkey_msg_parse: "
51785 + "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
51786 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
51787 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
51788 + SENDERR(EINVAL);
51789 + }
51790 + if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
51791 + SADB_EALG_NULL) &&
51792 + (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
51793 + SADB_AALG_NONE) ) {
51794 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51795 + "pfkey_msg_parse: "
51796 + "ESP handed encNULL+authNONE, illegal combination.\n");
51797 + SENDERR(EINVAL);
51798 + }
51799 + break;
51800 + case SADB_X_SATYPE_COMP:
51801 + if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
51802 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
51803 + SADB_EALG_NONE)) {
51804 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51805 + "pfkey_msg_parse: "
51806 + "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
51807 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
51808 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
51809 + SENDERR(EINVAL);
51810 + }
51811 + if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
51812 + SADB_AALG_NONE) {
51813 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51814 + "pfkey_msg_parse: "
51815 + "COMP handed auth=%d, must be zero.\n",
51816 + ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
51817 + SENDERR(EINVAL);
51818 + }
51819 + break;
51820 + default:
51821 + break;
51822 + }
51823 + if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
51824 + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
51825 + "pfkey_msg_parse: "
51826 + "spi=%08x must be > 255.\n",
51827 + ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
51828 + SENDERR(EINVAL);
51829 + }
51830 + default:
51831 + break;
51832 + }
51833 +errlab:
51834 +
51835 + return error;
51836 +}
51837 +
51838 +/*
51839 + * $Log: pfkey_v2_parse.c,v $
51840 + * Revision 1.65 2005/04/06 17:46:05 mcr
51841 + * failure to recognize an extension is considered an error.
51842 + * This could be a problem in the future, but we need some kind
51843 + * of logging. This should be rate limited, probably.
51844 + *
51845 + * Revision 1.64 2005/01/26 00:50:35 mcr
51846 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
51847 + * and make sure that NAT_TRAVERSAL is set as well to match
51848 + * userspace compiles of code.
51849 + *
51850 + * Revision 1.63 2004/10/28 22:54:10 mcr
51851 + * results from valgrind, thanks to: Harald Hoyer <harald@redhat.com>
51852 + *
51853 + * Revision 1.62 2004/10/03 01:26:36 mcr
51854 + * fixes for gcc 3.4 compilation.
51855 + *
51856 + * Revision 1.61 2004/07/10 19:11:18 mcr
51857 + * CONFIG_IPSEC -> CONFIG_KLIPS.
51858 + *
51859 + * Revision 1.59 2004/04/18 03:03:49 mcr
51860 + * renamed common include files from pluto directory.
51861 + *
51862 + * Revision 1.58 2004/03/08 01:59:08 ken
51863 + * freeswan.h -> openswan.h
51864 + *
51865 + * Revision 1.57 2003/12/10 01:20:19 mcr
51866 + * NAT-traversal patches to KLIPS.
51867 + *
51868 + * Revision 1.56 2003/12/04 23:01:12 mcr
51869 + * removed ipsec_netlink.h
51870 + *
51871 + * Revision 1.55 2003/11/07 01:30:37 ken
51872 + * Cast sizeof() to int to keep things 64bit clean
51873 + *
51874 + * Revision 1.54 2003/10/31 02:27:12 mcr
51875 + * pulled up port-selector patches and sa_id elimination.
51876 + *
51877 + * Revision 1.53.20.2 2003/10/29 01:11:32 mcr
51878 + * added debugging for pfkey library.
51879 + *
51880 + * Revision 1.53.20.1 2003/09/21 13:59:44 mcr
51881 + * pre-liminary X.509 patch - does not yet pass tests.
51882 + *
51883 + * Revision 1.53 2003/01/30 02:32:09 rgb
51884 + *
51885 + * Rename SAref table macro names for clarity.
51886 + * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
51887 + *
51888 + * Revision 1.52 2002/12/30 06:53:07 mcr
51889 + * deal with short SA structures... #if 0 out for now. Probably
51890 + * not quite the right way.
51891 + *
51892 + * Revision 1.51 2002/12/13 18:16:02 mcr
51893 + * restored sa_ref code
51894 + *
51895 + * Revision 1.50 2002/12/13 18:06:52 mcr
51896 + * temporarily removed sadb_x_sa_ref reference for 2.xx
51897 + *
51898 + * Revision 1.49 2002/10/05 05:02:58 dhr
51899 + *
51900 + * C labels go on statements
51901 + *
51902 + * Revision 1.48 2002/09/20 15:40:45 rgb
51903 + * Added sadb_x_sa_ref to struct sadb_sa.
51904 + *
51905 + * Revision 1.47 2002/09/20 05:01:31 rgb
51906 + * Fixed usage of pfkey_lib_debug.
51907 + * Format for function declaration style consistency.
51908 + * Added text labels to elucidate numeric values presented.
51909 + * Re-organised debug output to reduce noise in output.
51910 + *
51911 + * Revision 1.46 2002/07/24 18:44:54 rgb
51912 + * Type fiddling to tame ia64 compiler.
51913 + *
51914 + * Revision 1.45 2002/05/23 07:14:11 rgb
51915 + * Cleaned up %p variants to 0p%p for test suite cleanup.
51916 + *
51917 + * Revision 1.44 2002/04/24 07:55:32 mcr
51918 + * #include patches and Makefiles for post-reorg compilation.
51919 + *
51920 + * Revision 1.43 2002/04/24 07:36:40 mcr
51921 + * Moved from ./lib/pfkey_v2_parse.c,v
51922 + *
51923 + * Revision 1.42 2002/01/29 22:25:36 rgb
51924 + * Re-add ipsec_kversion.h to keep MALLOC happy.
51925 + *
51926 + * Revision 1.41 2002/01/29 01:59:10 mcr
51927 + * removal of kversions.h - sources that needed it now use ipsec_param.h.
51928 + * updating of IPv6 structures to match latest in6.h version.
51929 + * removed dead code from openswan.h that also duplicated kversions.h
51930 + * code.
51931 + *
51932 + * Revision 1.40 2002/01/20 20:34:50 mcr
51933 + * added pfkey_v2_sadb_type_string to decode sadb_type to string.
51934 + *
51935 + * Revision 1.39 2001/11/27 05:29:22 mcr
51936 + * pfkey parses are now maintained by a structure
51937 + * that includes their name for debug purposes.
51938 + * DEBUGGING() macro changed so that it takes a debug
51939 + * level so that pf_key() can use this to decode the
51940 + * structures without innundanting humans.
51941 + * Also uses pfkey_v2_sadb_ext_string() in messages.
51942 + *
51943 + * Revision 1.38 2001/11/06 19:47:47 rgb
51944 + * Added packet parameter to lifetime and comb structures.
51945 + *
51946 + * Revision 1.37 2001/10/18 04:45:24 rgb
51947 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
51948 + * lib/openswan.h version macros moved to lib/kversions.h.
51949 + * Other compiler directive cleanups.
51950 + *
51951 + * Revision 1.36 2001/06/14 19:35:16 rgb
51952 + * Update copyright date.
51953 + *
51954 + * Revision 1.35 2001/05/03 19:44:51 rgb
51955 + * Standardise on SENDERR() macro.
51956 + *
51957 + * Revision 1.34 2001/03/16 07:41:51 rgb
51958 + * Put openswan.h include before pluto includes.
51959 + *
51960 + * Revision 1.33 2001/02/27 07:13:51 rgb
51961 + * Added satype2name() function.
51962 + * Added text to default satype_tbl entry.
51963 + * Added satype2name() conversions for most satype debug output.
51964 + *
51965 + * Revision 1.32 2001/02/26 20:01:09 rgb
51966 + * Added internal IP protocol 61 for magic SAs.
51967 + * Ditch unused sadb_satype2proto[], replaced by satype2proto().
51968 + * Re-formatted debug output (split lines, consistent spacing).
51969 + * Removed acquire, register and expire requirements for a known satype.
51970 + * Changed message type checking to a switch structure.
51971 + * Verify expected NULL auth for IPCOMP.
51972 + * Enforced spi > 0x100 requirement, now that pass uses a magic SA for
51973 + * appropriate message types.
51974 + *
51975 + * Revision 1.31 2000/12/01 07:09:00 rgb
51976 + * Added ipcomp sanity check to require encalgo is set.
51977 + *
51978 + * Revision 1.30 2000/11/17 18:10:30 rgb
51979 + * Fixed bugs mostly relating to spirange, to treat all spi variables as
51980 + * network byte order since this is the way PF_KEYv2 stored spis.
51981 + *
51982 + * Revision 1.29 2000/10/12 00:02:39 rgb
51983 + * Removed 'format, ##' nonsense from debug macros for RH7.0.
51984 + *
51985 + * Revision 1.28 2000/09/20 16:23:04 rgb
51986 + * Remove over-paranoid extension check in the presence of sadb_msg_errno.
51987 + *
51988 + * Revision 1.27 2000/09/20 04:04:21 rgb
51989 + * Changed static functions to DEBUG_NO_STATIC to reveal function names in
51990 + * oopsen.
51991 + *
51992 + * Revision 1.26 2000/09/15 11:37:02 rgb
51993 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
51994 + * IPCOMP zlib deflate code.
51995 + *
51996 + * Revision 1.25 2000/09/12 22:35:37 rgb
51997 + * Restructured to remove unused extensions from CLEARFLOW messages.
51998 + *
51999 + * Revision 1.24 2000/09/12 18:59:54 rgb
52000 + * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
52001 + *
52002 + * Revision 1.23 2000/09/12 03:27:00 rgb
52003 + * Moved DEBUGGING definition to compile kernel with debug off.
52004 + *
52005 + * Revision 1.22 2000/09/09 06:39:27 rgb
52006 + * Restrict pfkey errno check to downward messages only.
52007 + *
52008 + * Revision 1.21 2000/09/08 19:22:34 rgb
52009 + * Enabled pfkey_sens_parse().
52010 + * Added check for errno on downward acquire messages only.
52011 + *
52012 + * Revision 1.20 2000/09/01 18:48:23 rgb
52013 + * Fixed reserved check bug and added debug output in
52014 + * pfkey_supported_parse().
52015 + * Fixed debug output label bug in pfkey_ident_parse().
52016 + *
52017 + * Revision 1.19 2000/08/27 01:55:26 rgb
52018 + * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
52019 + *
52020 + * Revision 1.18 2000/08/24 17:00:36 rgb
52021 + * Ignore unknown extensions instead of failing.
52022 + *
52023 + * Revision 1.17 2000/06/02 22:54:14 rgb
52024 + * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
52025 + *
52026 + * Revision 1.16 2000/05/10 19:25:11 rgb
52027 + * Fleshed out proposal and supported extensions.
52028 + *
52029 + * Revision 1.15 2000/01/24 21:15:31 rgb
52030 + * Added disabled pluto pfkey lib debug flag.
52031 + * Added algo debugging reporting.
52032 + *
52033 + * Revision 1.14 2000/01/22 23:24:29 rgb
52034 + * Added new functions proto2satype() and satype2proto() and lookup
52035 + * table satype_tbl. Also added proto2name() since it was easy.
52036 + *
52037 + * Revision 1.13 2000/01/21 09:43:59 rgb
52038 + * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
52039 + *
52040 + * Revision 1.12 2000/01/21 06:28:19 rgb
52041 + * Added address cases for eroute flows.
52042 + * Indented compiler directives for readability.
52043 + * Added klipsdebug switching capability.
52044 + *
52045 + * Revision 1.11 1999/12/29 21:14:59 rgb
52046 + * Fixed debug text cut and paste typo.
52047 + *
52048 + * Revision 1.10 1999/12/10 17:45:24 rgb
52049 + * Added address debugging.
52050 + *
52051 + * Revision 1.9 1999/12/09 23:11:42 rgb
52052 + * Ditched <string.h> include since we no longer use memset().
52053 + * Use new pfkey_extensions_init() instead of memset().
52054 + * Added check for SATYPE in pfkey_msg_build().
52055 + * Tidy up comments and debugging comments.
52056 + *
52057 + * Revision 1.8 1999/12/07 19:55:26 rgb
52058 + * Removed unused first argument from extension parsers.
52059 + * Removed static pluto debug flag.
52060 + * Moved message type and state checking to pfkey_msg_parse().
52061 + * Changed print[fk] type from lx to x to quiet compiler.
52062 + * Removed redundant remain check.
52063 + * Changed __u* types to uint* to avoid use of asm/types.h and
52064 + * sys/types.h in userspace code.
52065 + *
52066 + * Revision 1.7 1999/12/01 22:20:51 rgb
52067 + * Moved pfkey_lib_debug variable into the library.
52068 + * Added pfkey version check into header parsing.
52069 + * Added check for SATYPE only for those extensions that require a
52070 + * non-zero value.
52071 + *
52072 + * Revision 1.6 1999/11/27 11:58:05 rgb
52073 + * Added ipv6 headers.
52074 + * Moved sadb_satype2proto protocol lookup table from
52075 + * klips/net/ipsec/pfkey_v2_parser.c.
52076 + * Enable lifetime_current checking.
52077 + * Debugging error messages added.
52078 + * Add argument to pfkey_msg_parse() for direction.
52079 + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
52080 + * Add CVS log entry to bottom of file.
52081 + * Moved auth and enc alg check to pfkey_msg_parse().
52082 + * Enable accidentally disabled spirange parsing.
52083 + * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
52084 + *
52085 + * Local variables:
52086 + * c-file-style: "linux"
52087 + * End:
52088 + *
52089 + */
52090 --- /dev/null Tue Mar 11 13:02:56 2003
52091 +++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004
52092 @@ -0,0 +1,3520 @@
52093 +/*
52094 + * @(#) RFC2367 PF_KEYv2 Key management API message parser
52095 + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
52096 + *
52097 + * This program is free software; you can redistribute it and/or modify it
52098 + * under the terms of the GNU General Public License as published by the
52099 + * Free Software Foundation; either version 2 of the License, or (at your
52100 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
52101 + *
52102 + * This program is distributed in the hope that it will be useful, but
52103 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
52104 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
52105 + * for more details.
52106 + *
52107 + * RCSID $Id: pfkey_v2_parser.c,v 1.134.2.2 2006/10/06 21:39:26 paul Exp $
52108 + */
52109 +
52110 +/*
52111 + * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
52112 + */
52113 +
52114 +char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.134.2.2 2006/10/06 21:39:26 paul Exp $";
52115 +
52116 +#ifndef AUTOCONF_INCLUDED
52117 +#include <linux/config.h>
52118 +#endif
52119 +#include <linux/version.h>
52120 +#include <linux/kernel.h> /* printk() */
52121 +
52122 +#include "openswan/ipsec_param.h"
52123 +
52124 +#ifdef MALLOC_SLAB
52125 +# include <linux/slab.h> /* kmalloc() */
52126 +#else /* MALLOC_SLAB */
52127 +# include <linux/malloc.h> /* kmalloc() */
52128 +#endif /* MALLOC_SLAB */
52129 +#include <linux/errno.h> /* error codes */
52130 +#include <linux/types.h> /* size_t */
52131 +#include <linux/interrupt.h> /* mark_bh */
52132 +
52133 +#include <linux/netdevice.h> /* struct device, and other headers */
52134 +#include <linux/etherdevice.h> /* eth_type_trans */
52135 +#include <linux/ip.h> /* struct iphdr */
52136 +#include <linux/skbuff.h>
52137 +
52138 +#include <openswan.h>
52139 +
52140 +#include <crypto/des.h>
52141 +
52142 +#ifdef SPINLOCK
52143 +# ifdef SPINLOCK_23
52144 +# include <linux/spinlock.h> /* *lock* */
52145 +# else /* SPINLOCK_23 */
52146 +# include <asm/spinlock.h> /* *lock* */
52147 +# endif /* SPINLOCK_23 */
52148 +#endif /* SPINLOCK */
52149 +
52150 +#include <linux/in6.h>
52151 +#include <net/route.h>
52152 +
52153 +#include <net/ip.h>
52154 +#ifdef NETLINK_SOCK
52155 +# include <linux/netlink.h>
52156 +#else
52157 +# include <net/netlink.h>
52158 +#endif
52159 +
52160 +#include <linux/random.h> /* get_random_bytes() */
52161 +
52162 +#include "openswan/radij.h"
52163 +#include "openswan/ipsec_encap.h"
52164 +#include "openswan/ipsec_sa.h"
52165 +
52166 +#include "openswan/ipsec_radij.h"
52167 +#include "openswan/ipsec_xform.h"
52168 +#include "openswan/ipsec_ah.h"
52169 +#include "openswan/ipsec_esp.h"
52170 +#include "openswan/ipsec_tunnel.h"
52171 +#include "openswan/ipsec_rcv.h"
52172 +#include "openswan/ipcomp.h"
52173 +
52174 +#include <pfkeyv2.h>
52175 +#include <pfkey.h>
52176 +
52177 +#include "openswan/ipsec_proto.h"
52178 +#include "openswan/ipsec_alg.h"
52179 +
52180 +#include "openswan/ipsec_kern24.h"
52181 +
52182 +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
52183 +
52184 +struct sklist_t {
52185 + struct socket *sk;
52186 + struct sklist_t* next;
52187 +} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
52188 +
52189 +__u32 pfkey_msg_seq = 0;
52190 +
52191 +
52192 +#if 0
52193 +#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)
52194 +#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)
52195 +static void dump_said(ip_said *s, int line)
52196 +{
52197 + char msa[SATOT_BUF];
52198 + size_t msa_len;
52199 +
52200 + msa_len = satot(s, 0, msa, sizeof(msa));
52201 +
52202 + printk("line: %d msa: %s\n", line, msa);
52203 +}
52204 +#endif
52205 +
52206 +
52207 +int
52208 +pfkey_alloc_eroute(struct eroute** eroute)
52209 +{
52210 + int error = 0;
52211 + if(*eroute) {
52212 + KLIPS_PRINT(debug_pfkey,
52213 + "klips_debug:pfkey_alloc_eroute: "
52214 + "eroute struct already allocated\n");
52215 + SENDERR(EEXIST);
52216 + }
52217 +
52218 + if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
52219 + KLIPS_PRINT(debug_pfkey,
52220 + "klips_debug:pfkey_alloc_eroute: "
52221 + "memory allocation error\n");
52222 + SENDERR(ENOMEM);
52223 + }
52224 +
52225 + KLIPS_PRINT(debug_pfkey,
52226 + "klips_debug:pfkey_alloc_eroute: "
52227 + "allocating %lu bytes for an eroute at 0p%p\n",
52228 + (unsigned long) sizeof(**eroute), *eroute);
52229 +
52230 + memset((caddr_t)*eroute, 0, sizeof(**eroute));
52231 + (*eroute)->er_eaddr.sen_len =
52232 + (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
52233 + (*eroute)->er_eaddr.sen_family =
52234 + (*eroute)->er_emask.sen_family = AF_ENCAP;
52235 + (*eroute)->er_eaddr.sen_type = SENT_IP4;
52236 + (*eroute)->er_emask.sen_type = 255;
52237 + (*eroute)->er_pid = 0;
52238 + (*eroute)->er_count = 0;
52239 + (*eroute)->er_lasttime = jiffies/HZ;
52240 +
52241 + errlab:
52242 + return(error);
52243 +}
52244 +
52245 +DEBUG_NO_STATIC int
52246 +pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
52247 + struct pfkey_extracted_data *extr)
52248 +{
52249 + int error = 0;
52250 + struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
52251 +
52252 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
52253 +
52254 + if (extr == 0) {
52255 + KLIPS_PRINT(debug_pfkey,
52256 + "klips_debug:pfkey_x_protocol_process:"
52257 + "extr is NULL, fatal\n");
52258 + SENDERR(EINVAL);
52259 + }
52260 + if (extr->eroute == 0) {
52261 + KLIPS_PRINT(debug_pfkey,
52262 + "klips_debug:pfkey_x_protocol_process:"
52263 + "extr->eroute is NULL, fatal\n");
52264 + SENDERR(EINVAL);
52265 + }
52266 +
52267 + extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
52268 + extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
52269 + KLIPS_PRINT(debug_pfkey,
52270 + "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
52271 + p->sadb_protocol_proto);
52272 + errlab:
52273 + return error;
52274 +}
52275 +
52276 +DEBUG_NO_STATIC int
52277 +pfkey_ipsec_sa_init(struct ipsec_sa *ipsp)
52278 +{
52279 +
52280 + return ipsec_sa_init(ipsp);
52281 +}
52282 +
52283 +int
52284 +pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
52285 +{
52286 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
52287 + "error=%d\n",
52288 + error);
52289 + if (!error) {
52290 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
52291 + "success.\n");
52292 + return 1;
52293 + } else {
52294 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
52295 + "caught error %d\n",
52296 + error);
52297 + pfkey_extensions_free(extensions);
52298 + return 0;
52299 + }
52300 +}
52301 +
52302 +
52303 +DEBUG_NO_STATIC int
52304 +pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52305 +{
52306 + int error = 0;
52307 + ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
52308 + int found_avail = 0;
52309 + struct ipsec_sa *ipsq;
52310 + char sa[SATOT_BUF];
52311 + size_t sa_len;
52312 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52313 + struct sadb_msg *pfkey_reply = NULL;
52314 + struct socket_list *pfkey_socketsp;
52315 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52316 +
52317 + KLIPS_PRINT(debug_pfkey,
52318 + "klips_debug:pfkey_getspi_parse: .\n");
52319 +
52320 + pfkey_extensions_init(extensions_reply);
52321 +
52322 + if(extr == NULL || extr->ips == NULL) {
52323 + KLIPS_PRINT(debug_pfkey,
52324 + "klips_debug:pfkey_getspi_parse: "
52325 + "error, extr or extr->ipsec_sa pointer NULL\n");
52326 + SENDERR(EINVAL);
52327 + }
52328 +
52329 + if(extensions[SADB_EXT_SPIRANGE]) {
52330 + minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
52331 + maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
52332 + }
52333 +
52334 + if(maxspi == minspi) {
52335 + extr->ips->ips_said.spi = maxspi;
52336 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52337 + if(ipsq != NULL) {
52338 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52339 + ipsec_sa_put(ipsq);
52340 + KLIPS_PRINT(debug_pfkey,
52341 + "klips_debug:pfkey_getspi_parse: "
52342 + "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
52343 + sa_len ? sa : " (error)");
52344 + SENDERR(EEXIST);
52345 + } else {
52346 + found_avail = 1;
52347 + }
52348 + } else {
52349 + int i = 0;
52350 + __u32 rand_val;
52351 + __u32 spi_diff;
52352 + while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
52353 + prng_bytes(&ipsec_prng, (char *) &(rand_val),
52354 + ( (spi_diff < (2^8)) ? 1 :
52355 + ( (spi_diff < (2^16)) ? 2 :
52356 + ( (spi_diff < (2^24)) ? 3 :
52357 + 4 ) ) ) );
52358 + extr->ips->ips_said.spi = htonl(ntohl(minspi) +
52359 + (rand_val %
52360 + (spi_diff + 1)));
52361 + i++;
52362 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52363 + if(ipsq == NULL) {
52364 + found_avail = 1;
52365 + } else {
52366 + ipsec_sa_put(ipsq);
52367 + }
52368 + }
52369 + }
52370 +
52371 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52372 +
52373 + if (!found_avail) {
52374 + KLIPS_PRINT(debug_pfkey,
52375 + "klips_debug:pfkey_getspi_parse: "
52376 + "found an old ipsec_sa for SA: %s, delete it first.\n",
52377 + sa_len ? sa : " (error)");
52378 + SENDERR(EEXIST);
52379 + }
52380 +
52381 + if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52382 + extr->ips->ips_flags |= EMT_INBOUND;
52383 + }
52384 +
52385 + KLIPS_PRINT(debug_pfkey,
52386 + "klips_debug:pfkey_getspi_parse: "
52387 + "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
52388 + sa_len ? sa : " (error)",
52389 + extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52390 +
52391 + /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52392 + extr->ips->ips_rcvif = NULL;
52393 + extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
52394 +
52395 + extr->ips->ips_state = SADB_SASTATE_LARVAL;
52396 +
52397 + if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
52398 + extr->ips->ips_life.ipl_allocations.ipl_count += 1;
52399 + }
52400 +
52401 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52402 + SADB_GETSPI,
52403 + satype,
52404 + 0,
52405 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52406 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52407 + extensions_reply)
52408 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52409 + SADB_EXT_SA,
52410 + extr->ips->ips_said.spi,
52411 + 0,
52412 + SADB_SASTATE_LARVAL,
52413 + 0,
52414 + 0,
52415 + 0,
52416 + extr->ips->ips_ref),
52417 + extensions_reply)
52418 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52419 + SADB_EXT_ADDRESS_SRC,
52420 + 0, /*extr->ips->ips_said.proto,*/
52421 + 0,
52422 + extr->ips->ips_addr_s),
52423 + extensions_reply)
52424 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52425 + SADB_EXT_ADDRESS_DST,
52426 + 0, /*extr->ips->ips_said.proto,*/
52427 + 0,
52428 + extr->ips->ips_addr_d),
52429 + extensions_reply) )) {
52430 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52431 + "failed to build the getspi reply message extensions\n");
52432 + goto errlab;
52433 + }
52434 +
52435 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52436 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52437 + "failed to build the getspi reply message\n");
52438 + SENDERR(-error);
52439 + }
52440 + for(pfkey_socketsp = pfkey_open_sockets;
52441 + pfkey_socketsp;
52442 + pfkey_socketsp = pfkey_socketsp->next) {
52443 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52444 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52445 + "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52446 + satype,
52447 + satype2name(satype),
52448 + pfkey_socketsp->socketp,
52449 + error);
52450 + SENDERR(-error);
52451 + }
52452 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52453 + "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52454 + satype,
52455 + satype2name(satype),
52456 + pfkey_socketsp->socketp);
52457 + }
52458 +
52459 + if((error = ipsec_sa_add(extr->ips))) {
52460 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
52461 + "failed to add the larval SA=%s with error=%d.\n",
52462 + sa_len ? sa : " (error)",
52463 + error);
52464 + SENDERR(-error);
52465 + }
52466 + extr->ips = NULL;
52467 +
52468 + KLIPS_PRINT(debug_pfkey,
52469 + "klips_debug:pfkey_getspi_parse: "
52470 + "successful for SA: %s\n",
52471 + sa_len ? sa : " (error)");
52472 +
52473 + errlab:
52474 + if (pfkey_reply) {
52475 + pfkey_msg_free(&pfkey_reply);
52476 + }
52477 + pfkey_extensions_free(extensions_reply);
52478 + return error;
52479 +}
52480 +
52481 +DEBUG_NO_STATIC int
52482 +pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52483 +{
52484 + int error = 0;
52485 + struct ipsec_sa* ipsq;
52486 + char sa[SATOT_BUF];
52487 + size_t sa_len;
52488 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52489 + struct sadb_msg *pfkey_reply = NULL;
52490 + struct socket_list *pfkey_socketsp;
52491 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52492 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52493 + struct ipsec_sa *nat_t_ips_saved = NULL;
52494 +#endif
52495 + KLIPS_PRINT(debug_pfkey,
52496 + "klips_debug:pfkey_update_parse: .\n");
52497 +
52498 + pfkey_extensions_init(extensions_reply);
52499 +
52500 + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
52501 + KLIPS_PRINT(debug_pfkey,
52502 + "klips_debug:pfkey_update_parse: "
52503 + "error, sa_state=%d must be MATURE=%d\n",
52504 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
52505 + SADB_SASTATE_MATURE);
52506 + SENDERR(EINVAL);
52507 + }
52508 +
52509 + if(extr == NULL || extr->ips == NULL) {
52510 + KLIPS_PRINT(debug_pfkey,
52511 + "klips_debug:pfkey_update_parse: "
52512 + "error, extr or extr->ips pointer NULL\n");
52513 + SENDERR(EINVAL);
52514 + }
52515 +
52516 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52517 +
52518 + spin_lock_bh(&tdb_lock);
52519 +
52520 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52521 + if (ipsq == NULL) {
52522 + spin_unlock_bh(&tdb_lock);
52523 + KLIPS_PRINT(debug_pfkey,
52524 + "klips_debug:pfkey_update_parse: "
52525 + "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n",
52526 + sa_len ? sa : " (error)");
52527 + SENDERR(ENOENT);
52528 + }
52529 +
52530 + if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52531 + extr->ips->ips_flags |= EMT_INBOUND;
52532 + }
52533 +
52534 + KLIPS_PRINT(debug_pfkey,
52535 + "klips_debug:pfkey_update_parse: "
52536 + "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
52537 + sa_len ? sa : " (error)",
52538 + extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52539 +
52540 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52541 + if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) {
52542 + KLIPS_PRINT(debug_pfkey,
52543 + "klips_debug:pfkey_update_parse: only updating NAT-T ports "
52544 + "(%u:%u -> %u:%u)\n",
52545 + ipsq->ips_natt_sport, ipsq->ips_natt_dport,
52546 + extr->ips->ips_natt_sport, extr->ips->ips_natt_dport);
52547 +
52548 + if (extr->ips->ips_natt_sport) {
52549 + ipsq->ips_natt_sport = extr->ips->ips_natt_sport;
52550 + if (ipsq->ips_addr_s->sa_family == AF_INET) {
52551 + ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport);
52552 + }
52553 + }
52554 +
52555 + if (extr->ips->ips_natt_dport) {
52556 + ipsq->ips_natt_dport = extr->ips->ips_natt_dport;
52557 + if (ipsq->ips_addr_d->sa_family == AF_INET) {
52558 + ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport);
52559 + }
52560 + }
52561 +
52562 + nat_t_ips_saved = extr->ips;
52563 + extr->ips = ipsq;
52564 + }
52565 + else {
52566 +#endif
52567 +
52568 + /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52569 + extr->ips->ips_rcvif = NULL;
52570 + if ((error = pfkey_ipsec_sa_init(extr->ips))) {
52571 + ipsec_sa_put(ipsq);
52572 + spin_unlock_bh(&tdb_lock);
52573 + KLIPS_PRINT(debug_pfkey,
52574 + "klips_debug:pfkey_update_parse: "
52575 + "not successful for SA: %s, deleting.\n",
52576 + sa_len ? sa : " (error)");
52577 + SENDERR(-error);
52578 + }
52579 +
52580 + extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
52581 + ipsec_sa_put(ipsq);
52582 + if((error = ipsec_sa_delchain(ipsq))) {
52583 + spin_unlock_bh(&tdb_lock);
52584 + KLIPS_PRINT(debug_pfkey,
52585 + "klips_debug:pfkey_update_parse: "
52586 + "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n",
52587 + error,
52588 + sa_len ? sa : " (error)");
52589 + SENDERR(-error);
52590 + }
52591 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52592 + }
52593 +#endif
52594 +
52595 + spin_unlock_bh(&tdb_lock);
52596 +
52597 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52598 + SADB_UPDATE,
52599 + satype,
52600 + 0,
52601 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52602 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52603 + extensions_reply)
52604 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52605 + SADB_EXT_SA,
52606 + extr->ips->ips_said.spi,
52607 + extr->ips->ips_replaywin,
52608 + extr->ips->ips_state,
52609 + extr->ips->ips_authalg,
52610 + extr->ips->ips_encalg,
52611 + extr->ips->ips_flags,
52612 + extr->ips->ips_ref),
52613 + extensions_reply)
52614 + /* The 3 lifetime extentions should only be sent if non-zero. */
52615 + && (extensions[SADB_EXT_LIFETIME_HARD]
52616 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
52617 + SADB_EXT_LIFETIME_HARD,
52618 + extr->ips->ips_life.ipl_allocations.ipl_hard,
52619 + extr->ips->ips_life.ipl_bytes.ipl_hard,
52620 + extr->ips->ips_life.ipl_addtime.ipl_hard,
52621 + extr->ips->ips_life.ipl_usetime.ipl_hard,
52622 + extr->ips->ips_life.ipl_packets.ipl_hard),
52623 + extensions_reply) : 1)
52624 + && (extensions[SADB_EXT_LIFETIME_SOFT]
52625 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
52626 + SADB_EXT_LIFETIME_SOFT,
52627 + extr->ips->ips_life.ipl_allocations.ipl_count,
52628 + extr->ips->ips_life.ipl_bytes.ipl_count,
52629 + extr->ips->ips_life.ipl_addtime.ipl_count,
52630 + extr->ips->ips_life.ipl_usetime.ipl_count,
52631 + extr->ips->ips_life.ipl_packets.ipl_count),
52632 + extensions_reply) : 1)
52633 + && (extr->ips->ips_life.ipl_allocations.ipl_count
52634 + || extr->ips->ips_life.ipl_bytes.ipl_count
52635 + || extr->ips->ips_life.ipl_addtime.ipl_count
52636 + || extr->ips->ips_life.ipl_usetime.ipl_count
52637 + || extr->ips->ips_life.ipl_packets.ipl_count
52638 +
52639 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
52640 + SADB_EXT_LIFETIME_CURRENT,
52641 + extr->ips->ips_life.ipl_allocations.ipl_count,
52642 + extr->ips->ips_life.ipl_bytes.ipl_count,
52643 + extr->ips->ips_life.ipl_addtime.ipl_count,
52644 + extr->ips->ips_life.ipl_usetime.ipl_count,
52645 + extr->ips->ips_life.ipl_packets.ipl_count),
52646 + extensions_reply) : 1)
52647 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52648 + SADB_EXT_ADDRESS_SRC,
52649 + 0, /*extr->ips->ips_said.proto,*/
52650 + 0,
52651 + extr->ips->ips_addr_s),
52652 + extensions_reply)
52653 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52654 + SADB_EXT_ADDRESS_DST,
52655 + 0, /*extr->ips->ips_said.proto,*/
52656 + 0,
52657 + extr->ips->ips_addr_d),
52658 + extensions_reply)
52659 + && (extr->ips->ips_ident_s.data
52660 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
52661 + SADB_EXT_IDENTITY_SRC,
52662 + extr->ips->ips_ident_s.type,
52663 + extr->ips->ips_ident_s.id,
52664 + extr->ips->ips_ident_s.len,
52665 + extr->ips->ips_ident_s.data),
52666 + extensions_reply) : 1)
52667 + && (extr->ips->ips_ident_d.data
52668 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
52669 + SADB_EXT_IDENTITY_DST,
52670 + extr->ips->ips_ident_d.type,
52671 + extr->ips->ips_ident_d.id,
52672 + extr->ips->ips_ident_d.len,
52673 + extr->ips->ips_ident_d.data),
52674 + extensions_reply) : 1)
52675 +#if 0
52676 + /* FIXME: This won't work yet because I have not finished
52677 + it. */
52678 + && (extr->ips->ips_sens_
52679 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
52680 + extr->ips->ips_sens_dpd,
52681 + extr->ips->ips_sens_sens_level,
52682 + extr->ips->ips_sens_sens_len,
52683 + extr->ips->ips_sens_sens_bitmap,
52684 + extr->ips->ips_sens_integ_level,
52685 + extr->ips->ips_sens_integ_len,
52686 + extr->ips->ips_sens_integ_bitmap),
52687 + extensions_reply) : 1)
52688 +#endif
52689 + )) {
52690 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52691 + "failed to build the update reply message extensions\n");
52692 + SENDERR(-error);
52693 + }
52694 +
52695 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52696 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52697 + "failed to build the update reply message\n");
52698 + SENDERR(-error);
52699 + }
52700 + for(pfkey_socketsp = pfkey_open_sockets;
52701 + pfkey_socketsp;
52702 + pfkey_socketsp = pfkey_socketsp->next) {
52703 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52704 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52705 + "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52706 + satype,
52707 + satype2name(satype),
52708 + pfkey_socketsp->socketp,
52709 + error);
52710 + SENDERR(-error);
52711 + }
52712 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52713 + "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52714 + satype,
52715 + satype2name(satype),
52716 + pfkey_socketsp->socketp);
52717 + }
52718 +
52719 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
52720 + if (nat_t_ips_saved) {
52721 + /**
52722 + * As we _really_ update existing SA, we keep tdbq and need to delete
52723 + * parsed ips (nat_t_ips_saved, was extr->ips).
52724 + *
52725 + * goto errlab with extr->ips = nat_t_ips_saved will free it.
52726 + */
52727 +
52728 + extr->ips = nat_t_ips_saved;
52729 +
52730 + error = 0;
52731 + KLIPS_PRINT(debug_pfkey,
52732 + "klips_debug:pfkey_update_parse (NAT-T ports): "
52733 + "successful for SA: %s\n",
52734 + sa_len ? sa : " (error)");
52735 +
52736 + goto errlab;
52737 + }
52738 +#endif
52739 +
52740 + if((error = ipsec_sa_add(extr->ips))) {
52741 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
52742 + "failed to update the mature SA=%s with error=%d.\n",
52743 + sa_len ? sa : " (error)",
52744 + error);
52745 + SENDERR(-error);
52746 + }
52747 + extr->ips = NULL;
52748 +
52749 + KLIPS_PRINT(debug_pfkey,
52750 + "klips_debug:pfkey_update_parse: "
52751 + "successful for SA: %s\n",
52752 + sa_len ? sa : " (error)");
52753 +
52754 + errlab:
52755 + if (pfkey_reply) {
52756 + pfkey_msg_free(&pfkey_reply);
52757 + }
52758 + pfkey_extensions_free(extensions_reply);
52759 + return error;
52760 +}
52761 +
52762 +DEBUG_NO_STATIC int
52763 +pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52764 +{
52765 + int error = 0;
52766 + struct ipsec_sa* ipsq;
52767 + char sa[SATOT_BUF];
52768 + size_t sa_len;
52769 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52770 + struct sadb_msg *pfkey_reply = NULL;
52771 + struct socket_list *pfkey_socketsp;
52772 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52773 +
52774 + KLIPS_PRINT(debug_pfkey,
52775 + "klips_debug:pfkey_add_parse: .\n");
52776 +
52777 + pfkey_extensions_init(extensions_reply);
52778 +
52779 + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
52780 + KLIPS_PRINT(debug_pfkey,
52781 + "klips_debug:pfkey_add_parse: "
52782 + "error, sa_state=%d must be MATURE=%d\n",
52783 + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
52784 + SADB_SASTATE_MATURE);
52785 + SENDERR(EINVAL);
52786 + }
52787 +
52788 + if(!extr || !extr->ips) {
52789 + KLIPS_PRINT(debug_pfkey,
52790 + "klips_debug:pfkey_add_parse: "
52791 + "extr or extr->ips pointer NULL\n");
52792 + SENDERR(EINVAL);
52793 + }
52794 +
52795 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52796 +
52797 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
52798 + if(ipsq != NULL) {
52799 + ipsec_sa_put(ipsq);
52800 + KLIPS_PRINT(debug_pfkey,
52801 + "klips_debug:pfkey_add_parse: "
52802 + "found an old ipsec_sa for SA%s, delete it first.\n",
52803 + sa_len ? sa : " (error)");
52804 + SENDERR(EEXIST);
52805 + }
52806 +
52807 + if(inet_addr_type((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == RTN_LOCAL) {
52808 + extr->ips->ips_flags |= EMT_INBOUND;
52809 + }
52810 +
52811 + KLIPS_PRINT(debug_pfkey,
52812 + "klips_debug:pfkey_add_parse: "
52813 + "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
52814 + sa_len ? sa : " (error)",
52815 + extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
52816 +
52817 + /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
52818 + extr->ips->ips_rcvif = NULL;
52819 +
52820 + if ((error = pfkey_ipsec_sa_init(extr->ips))) {
52821 + KLIPS_PRINT(debug_pfkey,
52822 + "klips_debug:pfkey_add_parse: "
52823 + "not successful for SA: %s, deleting.\n",
52824 + sa_len ? sa : " (error)");
52825 + SENDERR(-error);
52826 + }
52827 +
52828 + extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
52829 + if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
52830 + extr->ips->ips_life.ipl_allocations.ipl_count += 1;
52831 + }
52832 +
52833 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
52834 + SADB_ADD,
52835 + satype,
52836 + 0,
52837 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
52838 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
52839 + extensions_reply)
52840 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
52841 + SADB_EXT_SA,
52842 + extr->ips->ips_said.spi,
52843 + extr->ips->ips_replaywin,
52844 + extr->ips->ips_state,
52845 + extr->ips->ips_authalg,
52846 + extr->ips->ips_encalg,
52847 + extr->ips->ips_flags,
52848 + extr->ips->ips_ref),
52849 + extensions_reply)
52850 + /* The 3 lifetime extentions should only be sent if non-zero. */
52851 + && (extensions[SADB_EXT_LIFETIME_HARD]
52852 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
52853 + SADB_EXT_LIFETIME_HARD,
52854 + extr->ips->ips_life.ipl_allocations.ipl_hard,
52855 + extr->ips->ips_life.ipl_bytes.ipl_hard,
52856 + extr->ips->ips_life.ipl_addtime.ipl_hard,
52857 + extr->ips->ips_life.ipl_usetime.ipl_hard,
52858 + extr->ips->ips_life.ipl_packets.ipl_hard),
52859 + extensions_reply) : 1)
52860 + && (extensions[SADB_EXT_LIFETIME_SOFT]
52861 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
52862 + SADB_EXT_LIFETIME_SOFT,
52863 + extr->ips->ips_life.ipl_allocations.ipl_soft,
52864 + extr->ips->ips_life.ipl_bytes.ipl_soft,
52865 + extr->ips->ips_life.ipl_addtime.ipl_soft,
52866 + extr->ips->ips_life.ipl_usetime.ipl_soft,
52867 + extr->ips->ips_life.ipl_packets.ipl_soft),
52868 + extensions_reply) : 1)
52869 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
52870 + SADB_EXT_ADDRESS_SRC,
52871 + 0, /*extr->ips->ips_said.proto,*/
52872 + 0,
52873 + extr->ips->ips_addr_s),
52874 + extensions_reply)
52875 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
52876 + SADB_EXT_ADDRESS_DST,
52877 + 0, /*extr->ips->ips_said.proto,*/
52878 + 0,
52879 + extr->ips->ips_addr_d),
52880 + extensions_reply)
52881 + && (extr->ips->ips_ident_s.data
52882 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
52883 + SADB_EXT_IDENTITY_SRC,
52884 + extr->ips->ips_ident_s.type,
52885 + extr->ips->ips_ident_s.id,
52886 + extr->ips->ips_ident_s.len,
52887 + extr->ips->ips_ident_s.data),
52888 + extensions_reply) : 1)
52889 + && (extr->ips->ips_ident_d.data
52890 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
52891 + SADB_EXT_IDENTITY_DST,
52892 + extr->ips->ips_ident_d.type,
52893 + extr->ips->ips_ident_d.id,
52894 + extr->ips->ips_ident_d.len,
52895 + extr->ips->ips_ident_d.data),
52896 + extensions_reply) : 1)
52897 +#if 0
52898 + /* FIXME: This won't work yet because I have not finished
52899 + it. */
52900 + && (extr->ips->ips_sens_
52901 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
52902 + extr->ips->ips_sens_dpd,
52903 + extr->ips->ips_sens_sens_level,
52904 + extr->ips->ips_sens_sens_len,
52905 + extr->ips->ips_sens_sens_bitmap,
52906 + extr->ips->ips_sens_integ_level,
52907 + extr->ips->ips_sens_integ_len,
52908 + extr->ips->ips_sens_integ_bitmap),
52909 + extensions_reply) : 1)
52910 +#endif
52911 + )) {
52912 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52913 + "failed to build the add reply message extensions\n");
52914 + SENDERR(-error);
52915 + }
52916 +
52917 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
52918 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52919 + "failed to build the add reply message\n");
52920 + SENDERR(-error);
52921 + }
52922 + for(pfkey_socketsp = pfkey_open_sockets;
52923 + pfkey_socketsp;
52924 + pfkey_socketsp = pfkey_socketsp->next) {
52925 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
52926 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52927 + "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
52928 + satype,
52929 + satype2name(satype),
52930 + pfkey_socketsp->socketp,
52931 + error);
52932 + SENDERR(-error);
52933 + }
52934 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52935 + "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
52936 + satype,
52937 + satype2name(satype),
52938 + pfkey_socketsp->socketp);
52939 + }
52940 +
52941 + if((error = ipsec_sa_add(extr->ips))) {
52942 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
52943 + "failed to add the mature SA=%s with error=%d.\n",
52944 + sa_len ? sa : " (error)",
52945 + error);
52946 + SENDERR(-error);
52947 + }
52948 + extr->ips = NULL;
52949 +
52950 + KLIPS_PRINT(debug_pfkey,
52951 + "klips_debug:pfkey_add_parse: "
52952 + "successful for SA: %s\n",
52953 + sa_len ? sa : " (error)");
52954 +
52955 + errlab:
52956 + if (pfkey_reply) {
52957 + pfkey_msg_free(&pfkey_reply);
52958 + }
52959 + pfkey_extensions_free(extensions_reply);
52960 + return error;
52961 +}
52962 +
52963 +DEBUG_NO_STATIC int
52964 +pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
52965 +{
52966 + struct ipsec_sa *ipsp;
52967 + char sa[SATOT_BUF];
52968 + size_t sa_len;
52969 + int error = 0;
52970 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
52971 + struct sadb_msg *pfkey_reply = NULL;
52972 + struct socket_list *pfkey_socketsp;
52973 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
52974 +
52975 + KLIPS_PRINT(debug_pfkey,
52976 + "klips_debug:pfkey_delete_parse: .\n");
52977 +
52978 + pfkey_extensions_init(extensions_reply);
52979 +
52980 + if(!extr || !extr->ips) {
52981 + KLIPS_PRINT(debug_pfkey,
52982 + "klips_debug:pfkey_delete_parse: "
52983 + "extr or extr->ips pointer NULL, fatal\n");
52984 + SENDERR(EINVAL);
52985 + }
52986 +
52987 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
52988 +
52989 + spin_lock_bh(&tdb_lock);
52990 +
52991 + ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
52992 + if (ipsp == NULL) {
52993 + spin_unlock_bh(&tdb_lock);
52994 + KLIPS_PRINT(debug_pfkey,
52995 + "klips_debug:pfkey_delete_parse: "
52996 + "ipsec_sa not found for SA:%s, could not delete.\n",
52997 + sa_len ? sa : " (error)");
52998 + SENDERR(ESRCH);
52999 + }
53000 +
53001 + ipsec_sa_put(ipsp);
53002 + if((error = ipsec_sa_delchain(ipsp))) {
53003 + spin_unlock_bh(&tdb_lock);
53004 + KLIPS_PRINT(debug_pfkey,
53005 + "klips_debug:pfkey_delete_parse: "
53006 + "error=%d returned trying to delete ipsec_sa for SA:%s.\n",
53007 + error,
53008 + sa_len ? sa : " (error)");
53009 + SENDERR(-error);
53010 + }
53011 + spin_unlock_bh(&tdb_lock);
53012 +
53013 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53014 + SADB_DELETE,
53015 + satype,
53016 + 0,
53017 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53018 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53019 + extensions_reply)
53020 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53021 + SADB_EXT_SA,
53022 + extr->ips->ips_said.spi,
53023 + 0,
53024 + 0,
53025 + 0,
53026 + 0,
53027 + 0,
53028 + extr->ips->ips_ref),
53029 + extensions_reply)
53030 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
53031 + SADB_EXT_ADDRESS_SRC,
53032 + 0, /*extr->ips->ips_said.proto,*/
53033 + 0,
53034 + extr->ips->ips_addr_s),
53035 + extensions_reply)
53036 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53037 + SADB_EXT_ADDRESS_DST,
53038 + 0, /*extr->ips->ips_said.proto,*/
53039 + 0,
53040 + extr->ips->ips_addr_d),
53041 + extensions_reply)
53042 + )) {
53043 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53044 + "failed to build the delete reply message extensions\n");
53045 + SENDERR(-error);
53046 + }
53047 +
53048 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53049 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53050 + "failed to build the delete reply message\n");
53051 + SENDERR(-error);
53052 + }
53053 + for(pfkey_socketsp = pfkey_open_sockets;
53054 + pfkey_socketsp;
53055 + pfkey_socketsp = pfkey_socketsp->next) {
53056 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53057 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53058 + "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53059 + satype,
53060 + satype2name(satype),
53061 + pfkey_socketsp->socketp,
53062 + error);
53063 + SENDERR(-error);
53064 + }
53065 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
53066 + "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53067 + satype,
53068 + satype2name(satype),
53069 + pfkey_socketsp->socketp);
53070 + }
53071 +
53072 + errlab:
53073 + if (pfkey_reply) {
53074 + pfkey_msg_free(&pfkey_reply);
53075 + }
53076 + pfkey_extensions_free(extensions_reply);
53077 + return error;
53078 +}
53079 +
53080 +DEBUG_NO_STATIC int
53081 +pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53082 +{
53083 + int error = 0;
53084 + struct ipsec_sa *ipsp;
53085 + char sa[SATOT_BUF];
53086 + size_t sa_len;
53087 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53088 + struct sadb_msg *pfkey_reply = NULL;
53089 +
53090 + KLIPS_PRINT(debug_pfkey,
53091 + "klips_debug:pfkey_get_parse: .\n");
53092 +
53093 + pfkey_extensions_init(extensions_reply);
53094 +
53095 + if(!extr || !extr->ips) {
53096 + KLIPS_PRINT(debug_pfkey,
53097 + "klips_debug:pfkey_get_parse: "
53098 + "extr or extr->ips pointer NULL, fatal\n");
53099 + SENDERR(EINVAL);
53100 + }
53101 +
53102 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
53103 +
53104 + spin_lock_bh(&tdb_lock);
53105 +
53106 + ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
53107 + if (ipsp == NULL) {
53108 + spin_unlock_bh(&tdb_lock);
53109 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53110 + "ipsec_sa not found for SA=%s, could not get.\n",
53111 + sa_len ? sa : " (error)");
53112 + SENDERR(ESRCH);
53113 + }
53114 +
53115 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53116 + SADB_GET,
53117 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
53118 + 0,
53119 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53120 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53121 + extensions_reply)
53122 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53123 + SADB_EXT_SA,
53124 + extr->ips->ips_said.spi,
53125 + extr->ips->ips_replaywin,
53126 + extr->ips->ips_state,
53127 + extr->ips->ips_authalg,
53128 + extr->ips->ips_encalg,
53129 + extr->ips->ips_flags,
53130 + extr->ips->ips_ref),
53131 + extensions_reply)
53132 + /* The 3 lifetime extentions should only be sent if non-zero. */
53133 + && (ipsp->ips_life.ipl_allocations.ipl_count
53134 + || ipsp->ips_life.ipl_bytes.ipl_count
53135 + || ipsp->ips_life.ipl_addtime.ipl_count
53136 + || ipsp->ips_life.ipl_usetime.ipl_count
53137 + || ipsp->ips_life.ipl_packets.ipl_count
53138 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
53139 + SADB_EXT_LIFETIME_CURRENT,
53140 + ipsp->ips_life.ipl_allocations.ipl_count,
53141 + ipsp->ips_life.ipl_bytes.ipl_count,
53142 + ipsp->ips_life.ipl_addtime.ipl_count,
53143 + ipsp->ips_life.ipl_usetime.ipl_count,
53144 + ipsp->ips_life.ipl_packets.ipl_count),
53145 + extensions_reply) : 1)
53146 + && (ipsp->ips_life.ipl_allocations.ipl_hard
53147 + || ipsp->ips_life.ipl_bytes.ipl_hard
53148 + || ipsp->ips_life.ipl_addtime.ipl_hard
53149 + || ipsp->ips_life.ipl_usetime.ipl_hard
53150 + || ipsp->ips_life.ipl_packets.ipl_hard
53151 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
53152 + SADB_EXT_LIFETIME_HARD,
53153 + ipsp->ips_life.ipl_allocations.ipl_hard,
53154 + ipsp->ips_life.ipl_bytes.ipl_hard,
53155 + ipsp->ips_life.ipl_addtime.ipl_hard,
53156 + ipsp->ips_life.ipl_usetime.ipl_hard,
53157 + ipsp->ips_life.ipl_packets.ipl_hard),
53158 + extensions_reply) : 1)
53159 + && (ipsp->ips_life.ipl_allocations.ipl_soft
53160 + || ipsp->ips_life.ipl_bytes.ipl_soft
53161 + || ipsp->ips_life.ipl_addtime.ipl_soft
53162 + || ipsp->ips_life.ipl_usetime.ipl_soft
53163 + || ipsp->ips_life.ipl_packets.ipl_soft
53164 + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
53165 + SADB_EXT_LIFETIME_SOFT,
53166 + ipsp->ips_life.ipl_allocations.ipl_soft,
53167 + ipsp->ips_life.ipl_bytes.ipl_soft,
53168 + ipsp->ips_life.ipl_addtime.ipl_soft,
53169 + ipsp->ips_life.ipl_usetime.ipl_soft,
53170 + ipsp->ips_life.ipl_packets.ipl_soft),
53171 + extensions_reply) : 1)
53172 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
53173 + SADB_EXT_ADDRESS_SRC,
53174 + 0, /*extr->ips->ips_said.proto,*/
53175 + 0,
53176 + extr->ips->ips_addr_s),
53177 + extensions_reply)
53178 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53179 + SADB_EXT_ADDRESS_DST,
53180 + 0, /*extr->ips->ips_said.proto,*/
53181 + 0,
53182 + extr->ips->ips_addr_d),
53183 + extensions_reply)
53184 + && (extr->ips->ips_addr_p
53185 + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
53186 + SADB_EXT_ADDRESS_PROXY,
53187 + 0, /*extr->ips->ips_said.proto,*/
53188 + 0,
53189 + extr->ips->ips_addr_p),
53190 + extensions_reply) : 1)
53191 +#if 0
53192 + /* FIXME: This won't work yet because the keys are not
53193 + stored directly in the ipsec_sa. They are stored as
53194 + contexts. */
53195 + && (extr->ips->ips_key_a_size
53196 + ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
53197 + SADB_EXT_KEY_AUTH,
53198 + extr->ips->ips_key_a_size * 8,
53199 + extr->ips->ips_key_a),
53200 + extensions_reply) : 1)
53201 + /* FIXME: This won't work yet because the keys are not
53202 + stored directly in the ipsec_sa. They are stored as
53203 + key schedules. */
53204 + && (extr->ips->ips_key_e_size
53205 + ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
53206 + SADB_EXT_KEY_ENCRYPT,
53207 + extr->ips->ips_key_e_size * 8,
53208 + extr->ips->ips_key_e),
53209 + extensions_reply) : 1)
53210 +#endif
53211 + && (extr->ips->ips_ident_s.data
53212 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
53213 + SADB_EXT_IDENTITY_SRC,
53214 + extr->ips->ips_ident_s.type,
53215 + extr->ips->ips_ident_s.id,
53216 + extr->ips->ips_ident_s.len,
53217 + extr->ips->ips_ident_s.data),
53218 + extensions_reply) : 1)
53219 + && (extr->ips->ips_ident_d.data
53220 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
53221 + SADB_EXT_IDENTITY_DST,
53222 + extr->ips->ips_ident_d.type,
53223 + extr->ips->ips_ident_d.id,
53224 + extr->ips->ips_ident_d.len,
53225 + extr->ips->ips_ident_d.data),
53226 + extensions_reply) : 1)
53227 +#if 0
53228 + /* FIXME: This won't work yet because I have not finished
53229 + it. */
53230 + && (extr->ips->ips_sens_
53231 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
53232 + extr->ips->ips_sens_dpd,
53233 + extr->ips->ips_sens_sens_level,
53234 + extr->ips->ips_sens_sens_len,
53235 + extr->ips->ips_sens_sens_bitmap,
53236 + extr->ips->ips_sens_integ_level,
53237 + extr->ips->ips_sens_integ_len,
53238 + extr->ips->ips_sens_integ_bitmap),
53239 + extensions_reply) : 1)
53240 +#endif
53241 + )) {
53242 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53243 + "failed to build the get reply message extensions\n");
53244 + ipsec_sa_put(ipsp);
53245 + spin_unlock_bh(&tdb_lock);
53246 + SENDERR(-error);
53247 + }
53248 +
53249 + ipsec_sa_put(ipsp);
53250 + spin_unlock_bh(&tdb_lock);
53251 +
53252 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53253 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53254 + "failed to build the get reply message\n");
53255 + SENDERR(-error);
53256 + }
53257 +
53258 + if((error = pfkey_upmsg(sk->sk_socket, pfkey_reply))) {
53259 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53260 + "failed to send the get reply message\n");
53261 + SENDERR(-error);
53262 + }
53263 +
53264 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
53265 + "succeeded in sending get reply message.\n");
53266 +
53267 + errlab:
53268 + if (pfkey_reply) {
53269 + pfkey_msg_free(&pfkey_reply);
53270 + }
53271 + pfkey_extensions_free(extensions_reply);
53272 + return error;
53273 +}
53274 +
53275 +DEBUG_NO_STATIC int
53276 +pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53277 +{
53278 + int error = 0;
53279 + struct socket_list *pfkey_socketsp;
53280 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53281 +
53282 + KLIPS_PRINT(debug_pfkey,
53283 + "klips_debug:pfkey_acquire_parse: .\n");
53284 +
53285 + /* XXX I don't know if we want an upper bound, since userspace may
53286 + want to register itself for an satype > SADB_SATYPE_MAX. */
53287 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53288 + KLIPS_PRINT(debug_pfkey,
53289 + "klips_debug:pfkey_acquire_parse: "
53290 + "SATYPE=%d invalid.\n",
53291 + satype);
53292 + SENDERR(EINVAL);
53293 + }
53294 +
53295 + if(!(pfkey_registered_sockets[satype])) {
53296 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53297 + "no sockets registered for SAtype=%d(%s).\n",
53298 + satype,
53299 + satype2name(satype));
53300 + SENDERR(EPROTONOSUPPORT);
53301 + }
53302 +
53303 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
53304 + pfkey_socketsp;
53305 + pfkey_socketsp = pfkey_socketsp->next) {
53306 + if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53307 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53308 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53309 + "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53310 + satype,
53311 + satype2name(satype),
53312 + pfkey_socketsp->socketp,
53313 + error);
53314 + SENDERR(-error);
53315 + }
53316 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
53317 + "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53318 + satype,
53319 + satype2name(satype),
53320 + pfkey_socketsp->socketp);
53321 + }
53322 +
53323 + errlab:
53324 + return error;
53325 +}
53326 +
53327 +DEBUG_NO_STATIC int
53328 +pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53329 +{
53330 + int error = 0;
53331 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53332 +
53333 + KLIPS_PRINT(debug_pfkey,
53334 + "klips_debug:pfkey_register_parse: .\n");
53335 +
53336 + /* XXX I don't know if we want an upper bound, since userspace may
53337 + want to register itself for an satype > SADB_SATYPE_MAX. */
53338 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53339 + KLIPS_PRINT(debug_pfkey,
53340 + "klips_debug:pfkey_register_parse: "
53341 + "SATYPE=%d invalid.\n",
53342 + satype);
53343 + SENDERR(EINVAL);
53344 + }
53345 +
53346 + if(!pfkey_list_insert_socket(sk->sk_socket,
53347 + &(pfkey_registered_sockets[satype]))) {
53348 + KLIPS_PRINT(debug_pfkey,
53349 + "klips_debug:pfkey_register_parse: "
53350 + "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
53351 + satype,
53352 + satype2name(satype),
53353 + key_pid(sk));
53354 + };
53355 +
53356 + /* send up register msg with supported SATYPE algos */
53357 +
53358 + error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]);
53359 + errlab:
53360 + return error;
53361 +}
53362 +
53363 +int
53364 +pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
53365 +{
53366 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53367 + struct sadb_msg *pfkey_reply = NULL;
53368 + struct socket_list *pfkey_socketsp;
53369 + struct supported_list *pfkey_supported_listp;
53370 + unsigned int alg_num_a = 0, alg_num_e = 0;
53371 + struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
53372 + int error = 0;
53373 +
53374 + pfkey_extensions_init(extensions_reply);
53375 +
53376 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
53377 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53378 + "SAtype=%d unspecified or unknown.\n",
53379 + satype);
53380 + SENDERR(EINVAL);
53381 + }
53382 + if(!(pfkey_registered_sockets[satype])) {
53383 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53384 + "no sockets registered for SAtype=%d(%s).\n",
53385 + satype,
53386 + satype2name(satype));
53387 + SENDERR(EPROTONOSUPPORT);
53388 + }
53389 + /* send up register msg with supported SATYPE algos */
53390 + pfkey_supported_listp = pfkey_supported_list[satype];
53391 + KLIPS_PRINT(debug_pfkey,
53392 + "klips_debug:pfkey_register_reply: "
53393 + "pfkey_supported_list[%d]=0p%p\n",
53394 + satype,
53395 + pfkey_supported_list[satype]);
53396 + while(pfkey_supported_listp) {
53397 + KLIPS_PRINT(debug_pfkey,
53398 + "klips_debug:pfkey_register_reply: "
53399 + "checking supported=0p%p\n",
53400 + pfkey_supported_listp);
53401 + if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
53402 + KLIPS_PRINT(debug_pfkey,
53403 + "klips_debug:pfkey_register_reply: "
53404 + "adding auth alg.\n");
53405 + alg_num_a++;
53406 + }
53407 + if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
53408 + KLIPS_PRINT(debug_pfkey,
53409 + "klips_debug:pfkey_register_reply: "
53410 + "adding encrypt alg.\n");
53411 + alg_num_e++;
53412 + }
53413 + pfkey_supported_listp = pfkey_supported_listp->next;
53414 + }
53415 +
53416 + if(alg_num_a) {
53417 + KLIPS_PRINT(debug_pfkey,
53418 + "klips_debug:pfkey_register_reply: "
53419 + "allocating %lu bytes for auth algs.\n",
53420 + (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
53421 + if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
53422 + KLIPS_PRINT(debug_pfkey,
53423 + "klips_debug:pfkey_register_reply: "
53424 + "auth alg memory allocation error\n");
53425 + SENDERR(ENOMEM);
53426 + }
53427 + alg_ap = alg_a;
53428 + }
53429 +
53430 + if(alg_num_e) {
53431 + KLIPS_PRINT(debug_pfkey,
53432 + "klips_debug:pfkey_register_reply: "
53433 + "allocating %lu bytes for enc algs.\n",
53434 + (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
53435 + if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
53436 + KLIPS_PRINT(debug_pfkey,
53437 + "klips_debug:pfkey_register_reply: "
53438 + "enc alg memory allocation error\n");
53439 + SENDERR(ENOMEM);
53440 + }
53441 + alg_ep = alg_e;
53442 + }
53443 +
53444 + pfkey_supported_listp = pfkey_supported_list[satype];
53445 + while(pfkey_supported_listp) {
53446 + if(alg_num_a) {
53447 + if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_AUTH) {
53448 + alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
53449 + alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
53450 + alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
53451 + alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
53452 + alg_ap->sadb_alg_reserved = 0;
53453 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
53454 + "klips_debug:pfkey_register_reply: "
53455 + "adding auth=0p%p\n",
53456 + alg_ap);
53457 + alg_ap++;
53458 + }
53459 + }
53460 + if(alg_num_e) {
53461 + if(pfkey_supported_listp->supportedp->ias_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
53462 + alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->ias_id;
53463 + alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->ias_ivlen;
53464 + alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->ias_keyminbits;
53465 + alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->ias_keymaxbits;
53466 + alg_ep->sadb_alg_reserved = 0;
53467 + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
53468 + "klips_debug:pfkey_register_reply: "
53469 + "adding encrypt=0p%p\n",
53470 + alg_ep);
53471 + alg_ep++;
53472 + }
53473 + }
53474 + KLIPS_PRINT(debug_pfkey,
53475 + "klips_debug:pfkey_register_reply: "
53476 + "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
53477 + satype,
53478 + satype2name(satype),
53479 + pfkey_supported_listp->supportedp->ias_exttype,
53480 + pfkey_supported_listp->supportedp->ias_id,
53481 + pfkey_supported_listp->supportedp->ias_ivlen,
53482 + pfkey_supported_listp->supportedp->ias_keyminbits,
53483 + pfkey_supported_listp->supportedp->ias_keymaxbits);
53484 + pfkey_supported_listp = pfkey_supported_listp->next;
53485 + }
53486 +
53487 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53488 + SADB_REGISTER,
53489 + satype,
53490 + 0,
53491 + sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
53492 + sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
53493 + extensions_reply) &&
53494 + (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
53495 + SADB_EXT_SUPPORTED_AUTH,
53496 + alg_num_a,
53497 + alg_a),
53498 + extensions_reply) : 1) &&
53499 + (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
53500 + SADB_EXT_SUPPORTED_ENCRYPT,
53501 + alg_num_e,
53502 + alg_e),
53503 + extensions_reply) : 1))) {
53504 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53505 + "failed to build the register message extensions_reply\n");
53506 + SENDERR(-error);
53507 + }
53508 +
53509 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53510 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53511 + "failed to build the register message\n");
53512 + SENDERR(-error);
53513 + }
53514 + /* this should go to all registered sockets for that satype only */
53515 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
53516 + pfkey_socketsp;
53517 + pfkey_socketsp = pfkey_socketsp->next) {
53518 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53519 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53520 + "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53521 + satype,
53522 + satype2name(satype),
53523 + pfkey_socketsp->socketp,
53524 + error);
53525 + SENDERR(-error);
53526 + }
53527 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
53528 + "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n",
53529 + satype,
53530 + satype2name(satype),
53531 + pfkey_socketsp->socketp);
53532 + }
53533 +
53534 + errlab:
53535 + if(alg_a) {
53536 + kfree(alg_a);
53537 + }
53538 + if(alg_e) {
53539 + kfree(alg_e);
53540 + }
53541 +
53542 + if (pfkey_reply) {
53543 + pfkey_msg_free(&pfkey_reply);
53544 + }
53545 + pfkey_extensions_free(extensions_reply);
53546 + return error;
53547 +}
53548 +
53549 +DEBUG_NO_STATIC int
53550 +pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53551 +{
53552 + int error = 0;
53553 + struct socket_list *pfkey_socketsp;
53554 +#ifdef CONFIG_KLIPS_DEBUG
53555 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53556 +#endif /* CONFIG_KLIPS_DEBUG */
53557 +
53558 + KLIPS_PRINT(debug_pfkey,
53559 + "klips_debug:pfkey_expire_parse: .\n");
53560 +
53561 + if(pfkey_open_sockets) {
53562 + for(pfkey_socketsp = pfkey_open_sockets;
53563 + pfkey_socketsp;
53564 + pfkey_socketsp = pfkey_socketsp->next) {
53565 + if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53566 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53567 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
53568 + "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53569 + satype,
53570 + satype2name(satype),
53571 + pfkey_socketsp->socketp,
53572 + error);
53573 + SENDERR(-error);
53574 + }
53575 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
53576 + "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53577 + satype,
53578 + satype2name(satype),
53579 + pfkey_socketsp->socketp);
53580 + }
53581 + }
53582 +
53583 + errlab:
53584 + return error;
53585 +}
53586 +
53587 +DEBUG_NO_STATIC int
53588 +pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53589 +{
53590 + int error = 0;
53591 + struct socket_list *pfkey_socketsp;
53592 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53593 + uint8_t proto = 0;
53594 +
53595 + KLIPS_PRINT(debug_pfkey,
53596 + "klips_debug:pfkey_flush_parse: "
53597 + "flushing type %d SAs\n",
53598 + satype);
53599 +
53600 + if(satype && !(proto = satype2proto(satype))) {
53601 + KLIPS_PRINT(debug_pfkey,
53602 + "klips_debug:pfkey_flush_parse: "
53603 + "satype %d lookup failed.\n",
53604 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
53605 + SENDERR(EINVAL);
53606 + }
53607 +
53608 + if ((error = ipsec_sadb_cleanup(proto))) {
53609 + SENDERR(-error);
53610 + }
53611 +
53612 + if(pfkey_open_sockets) {
53613 + for(pfkey_socketsp = pfkey_open_sockets;
53614 + pfkey_socketsp;
53615 + pfkey_socketsp = pfkey_socketsp->next) {
53616 + if((error = pfkey_upmsg(pfkey_socketsp->socketp,
53617 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
53618 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
53619 + "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
53620 + satype,
53621 + satype2name(satype),
53622 + proto,
53623 + pfkey_socketsp->socketp,
53624 + error);
53625 + SENDERR(-error);
53626 + }
53627 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
53628 + "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53629 + satype,
53630 + satype2name(satype),
53631 + pfkey_socketsp->socketp);
53632 + }
53633 + }
53634 +
53635 + errlab:
53636 + return error;
53637 +}
53638 +
53639 +DEBUG_NO_STATIC int
53640 +pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53641 +{
53642 + int error = 0;
53643 +
53644 + KLIPS_PRINT(debug_pfkey,
53645 + "klips_debug:pfkey_dump_parse: .\n");
53646 +
53647 + SENDERR(ENOSYS);
53648 + errlab:
53649 + return error;
53650 +}
53651 +
53652 +DEBUG_NO_STATIC int
53653 +pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53654 +{
53655 + int error = 0;
53656 +
53657 + KLIPS_PRINT(debug_pfkey,
53658 + "klips_debug:pfkey_promisc_parse: .\n");
53659 +
53660 + SENDERR(ENOSYS);
53661 + errlab:
53662 + return error;
53663 +}
53664 +
53665 +DEBUG_NO_STATIC int
53666 +pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53667 +{
53668 + int error = 0;
53669 +
53670 + KLIPS_PRINT(debug_pfkey,
53671 + "klips_debug:pfkey_x_pchange_parse: .\n");
53672 +
53673 + SENDERR(ENOSYS);
53674 + errlab:
53675 + return error;
53676 +}
53677 +
53678 +DEBUG_NO_STATIC int
53679 +pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53680 +{
53681 + struct ipsec_sa *ips1p, *ips2p, *ipsp;
53682 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53683 + struct sadb_msg *pfkey_reply = NULL;
53684 + struct socket_list *pfkey_socketsp;
53685 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53686 + char sa1[SATOT_BUF], sa2[SATOT_BUF];
53687 + size_t sa_len1, sa_len2 = 0;
53688 + int error = 0;
53689 +
53690 + KLIPS_PRINT(debug_pfkey,
53691 + "klips_debug:pfkey_x_grpsa_parse: .\n");
53692 +
53693 + pfkey_extensions_init(extensions_reply);
53694 +
53695 + if(extr == NULL || extr->ips == NULL) {
53696 + KLIPS_PRINT(debug_pfkey,
53697 + "klips_debug:pfkey_x_grpsa_parse: "
53698 + "extr or extr->ips is NULL, fatal.\n");
53699 + SENDERR(EINVAL);
53700 + }
53701 +
53702 + sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1));
53703 + if(extr->ips2 != NULL) {
53704 + sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2));
53705 + }
53706 +
53707 + spin_lock_bh(&tdb_lock);
53708 +
53709 + ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
53710 + if(ips1p == NULL) {
53711 + spin_unlock_bh(&tdb_lock);
53712 + KLIPS_PRINT(debug_pfkey,
53713 + "klips_debug:pfkey_x_grpsa_parse: "
53714 + "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n",
53715 + sa_len1 ? sa1 : " (error)");
53716 + SENDERR(ENOENT);
53717 + }
53718 + if(extr->ips2) { /* GRPSA */
53719 + ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
53720 + if(ips2p == NULL) {
53721 + ipsec_sa_put(ips1p);
53722 + spin_unlock_bh(&tdb_lock);
53723 + KLIPS_PRINT(debug_pfkey,
53724 + "klips_debug:pfkey_x_grpsa_parse: "
53725 + "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n",
53726 + sa_len2 ? sa2 : " (error)");
53727 + SENDERR(ENOENT);
53728 + }
53729 +
53730 + /* Is either one already linked? */
53731 + if(ips1p->ips_onext) {
53732 + ipsec_sa_put(ips1p);
53733 + ipsec_sa_put(ips2p);
53734 + spin_unlock_bh(&tdb_lock);
53735 + KLIPS_PRINT(debug_pfkey,
53736 + "klips_debug:pfkey_x_grpsa_parse: "
53737 + "ipsec_sa for SA: %s is already linked.\n",
53738 + sa_len1 ? sa1 : " (error)");
53739 + SENDERR(EEXIST);
53740 + }
53741 + if(ips2p->ips_inext) {
53742 + ipsec_sa_put(ips1p);
53743 + ipsec_sa_put(ips2p);
53744 + spin_unlock_bh(&tdb_lock);
53745 + KLIPS_PRINT(debug_pfkey,
53746 + "klips_debug:pfkey_x_grpsa_parse: "
53747 + "ipsec_sa for SA: %s is already linked.\n",
53748 + sa_len2 ? sa2 : " (error)");
53749 + SENDERR(EEXIST);
53750 + }
53751 +
53752 + /* Is extr->ips already linked to extr->ips2? */
53753 + ipsp = ips2p;
53754 + while(ipsp) {
53755 + if(ipsp == ips1p) {
53756 + ipsec_sa_put(ips1p);
53757 + ipsec_sa_put(ips2p);
53758 + spin_unlock_bh(&tdb_lock);
53759 + KLIPS_PRINT(debug_pfkey,
53760 + "klips_debug:pfkey_x_grpsa_parse: "
53761 + "ipsec_sa for SA: %s is already linked to %s.\n",
53762 + sa_len1 ? sa1 : " (error)",
53763 + sa_len2 ? sa2 : " (error)");
53764 + SENDERR(EEXIST);
53765 + }
53766 + ipsp = ipsp->ips_onext;
53767 + }
53768 +
53769 + /* link 'em */
53770 + KLIPS_PRINT(debug_pfkey,
53771 + "klips_debug:pfkey_x_grpsa_parse: "
53772 + "linking ipsec_sa SA: %s with %s.\n",
53773 + sa_len1 ? sa1 : " (error)",
53774 + sa_len2 ? sa2 : " (error)");
53775 + ips1p->ips_onext = ips2p;
53776 + ips2p->ips_inext = ips1p;
53777 + } else { /* UNGRPSA */
53778 + ipsec_sa_put(ips1p);
53779 + KLIPS_PRINT(debug_pfkey,
53780 + "klips_debug:pfkey_x_grpsa_parse: "
53781 + "unlinking ipsec_sa SA: %s.\n",
53782 + sa_len1 ? sa1 : " (error)");
53783 + while(ips1p->ips_onext) {
53784 + ips1p = ips1p->ips_onext;
53785 + }
53786 + while(ips1p->ips_inext) {
53787 + ipsp = ips1p;
53788 + ips1p = ips1p->ips_inext;
53789 + ipsec_sa_put(ips1p);
53790 + ipsp->ips_inext = NULL;
53791 + ipsec_sa_put(ipsp);
53792 + ips1p->ips_onext = NULL;
53793 + }
53794 + }
53795 +
53796 + spin_unlock_bh(&tdb_lock);
53797 +
53798 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
53799 + SADB_X_GRPSA,
53800 + satype,
53801 + 0,
53802 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
53803 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
53804 + extensions_reply)
53805 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
53806 + SADB_EXT_SA,
53807 + extr->ips->ips_said.spi,
53808 + extr->ips->ips_replaywin,
53809 + extr->ips->ips_state,
53810 + extr->ips->ips_authalg,
53811 + extr->ips->ips_encalg,
53812 + extr->ips->ips_flags,
53813 + extr->ips->ips_ref),
53814 + extensions_reply)
53815 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
53816 + SADB_EXT_ADDRESS_DST,
53817 + 0, /*extr->ips->ips_said.proto,*/
53818 + 0,
53819 + extr->ips->ips_addr_d),
53820 + extensions_reply)
53821 + && (extr->ips2
53822 + ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
53823 + ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
53824 + /* proto2satype(extr->ips2->ips_said.proto) */),
53825 + extensions_reply)
53826 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2],
53827 + SADB_X_EXT_SA2,
53828 + extr->ips2->ips_said.spi,
53829 + extr->ips2->ips_replaywin,
53830 + extr->ips2->ips_state,
53831 + extr->ips2->ips_authalg,
53832 + extr->ips2->ips_encalg,
53833 + extr->ips2->ips_flags,
53834 + extr->ips2->ips_ref),
53835 + extensions_reply)
53836 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
53837 + SADB_X_EXT_ADDRESS_DST2,
53838 + 0, /*extr->ips->ips_said.proto,*/
53839 + 0,
53840 + extr->ips2->ips_addr_d),
53841 + extensions_reply) ) : 1 )
53842 + )) {
53843 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53844 + "failed to build the x_grpsa reply message extensions\n");
53845 + SENDERR(-error);
53846 + }
53847 +
53848 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
53849 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53850 + "failed to build the x_grpsa reply message\n");
53851 + SENDERR(-error);
53852 + }
53853 +
53854 + for(pfkey_socketsp = pfkey_open_sockets;
53855 + pfkey_socketsp;
53856 + pfkey_socketsp = pfkey_socketsp->next) {
53857 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
53858 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53859 + "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
53860 + satype,
53861 + satype2name(satype),
53862 + pfkey_socketsp->socketp,
53863 + error);
53864 + SENDERR(-error);
53865 + }
53866 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53867 + "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
53868 + satype,
53869 + satype2name(satype),
53870 + pfkey_socketsp->socketp);
53871 + }
53872 +
53873 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
53874 + "succeeded in sending x_grpsa reply message.\n");
53875 +
53876 + errlab:
53877 + if (pfkey_reply) {
53878 + pfkey_msg_free(&pfkey_reply);
53879 + }
53880 + pfkey_extensions_free(extensions_reply);
53881 + return error;
53882 +}
53883 +
53884 +DEBUG_NO_STATIC int
53885 +pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
53886 +{
53887 + int error = 0;
53888 +#ifdef CONFIG_KLIPS_DEBUG
53889 + char buf1[64], buf2[64];
53890 +#endif /* CONFIG_KLIPS_DEBUG */
53891 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
53892 + struct sadb_msg *pfkey_reply = NULL;
53893 + struct socket_list *pfkey_socketsp;
53894 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
53895 + ip_address srcflow, dstflow, srcmask, dstmask;
53896 +
53897 + KLIPS_PRINT(debug_pfkey,
53898 + "klips_debug:pfkey_x_addflow_parse: .\n");
53899 +
53900 + pfkey_extensions_init(extensions_reply);
53901 +
53902 + memset((caddr_t)&srcflow, 0, sizeof(srcflow));
53903 + memset((caddr_t)&dstflow, 0, sizeof(dstflow));
53904 + memset((caddr_t)&srcmask, 0, sizeof(srcmask));
53905 + memset((caddr_t)&dstmask, 0, sizeof(dstmask));
53906 +
53907 + if(!extr || !(extr->ips) || !(extr->eroute)) {
53908 + KLIPS_PRINT(debug_pfkey,
53909 + "klips_debug:pfkey_x_addflow_parse: "
53910 + "missing extr, ipsec_sa or eroute data.\n");
53911 + SENDERR(EINVAL);
53912 + }
53913 +
53914 + srcflow.u.v4.sin_family = AF_INET;
53915 + dstflow.u.v4.sin_family = AF_INET;
53916 + srcmask.u.v4.sin_family = AF_INET;
53917 + dstmask.u.v4.sin_family = AF_INET;
53918 + srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
53919 + dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
53920 + srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
53921 + dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
53922 +
53923 +#ifdef CONFIG_KLIPS_DEBUG
53924 + if (debug_pfkey) {
53925 + subnettoa(extr->eroute->er_eaddr.sen_ip_src,
53926 + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
53927 + subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
53928 + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
53929 + KLIPS_PRINT(debug_pfkey,
53930 + "klips_debug:pfkey_x_addflow_parse: "
53931 + "calling breakeroute and/or makeroute for %s->%s\n",
53932 + buf1, buf2);
53933 + }
53934 +#endif /* CONFIG_KLIPS_DEBUG */
53935 +
53936 + if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
53937 + struct ipsec_sa *ipsp, *ipsq;
53938 + char sa[SATOT_BUF];
53939 + size_t sa_len;
53940 +
53941 + ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
53942 + if(ipsq == NULL) {
53943 + KLIPS_PRINT(debug_pfkey,
53944 + "klips_debug:pfkey_x_addflow_parse: "
53945 + "ipsec_sa not found, cannot set incoming policy.\n");
53946 + SENDERR(ENOENT);
53947 + }
53948 +
53949 + ipsp = ipsq;
53950 + while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
53951 + ipsp = ipsp->ips_inext;
53952 + }
53953 +
53954 + if(ipsp == NULL) {
53955 + ipsec_sa_put(ipsq);
53956 + KLIPS_PRINT(debug_pfkey,
53957 + "klips_debug:pfkey_x_addflow_parse: "
53958 + "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
53959 + SENDERR(ENOENT);
53960 + }
53961 +
53962 + sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
53963 +
53964 + ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
53965 + ipsp->ips_flow_s = srcflow;
53966 + ipsp->ips_flow_d = dstflow;
53967 + ipsp->ips_mask_s = srcmask;
53968 + ipsp->ips_mask_d = dstmask;
53969 +
53970 + ipsec_sa_put(ipsq);
53971 +
53972 + KLIPS_PRINT(debug_pfkey,
53973 + "klips_debug:pfkey_x_addflow_parse: "
53974 + "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
53975 + sa_len ? sa : " (error)");
53976 + } else {
53977 + struct sk_buff *first = NULL, *last = NULL;
53978 +
53979 + if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
53980 + KLIPS_PRINT(debug_pfkey,
53981 + "klips_debug:pfkey_x_addflow_parse: "
53982 + "REPLACEFLOW flag set, calling breakeroute.\n");
53983 + if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
53984 + &(extr->eroute->er_emask),
53985 + &first, &last))) {
53986 + KLIPS_PRINT(debug_pfkey,
53987 + "klips_debug:pfkey_x_addflow_parse: "
53988 + "breakeroute returned %d. first=0p%p, last=0p%p\n",
53989 + error,
53990 + first,
53991 + last);
53992 + if(first != NULL) {
53993 + ipsec_kfree_skb(first);
53994 + }
53995 + if(last != NULL) {
53996 + ipsec_kfree_skb(last);
53997 + }
53998 + SENDERR(-error);
53999 + }
54000 + }
54001 +
54002 + KLIPS_PRINT(debug_pfkey,
54003 + "klips_debug:pfkey_x_addflow_parse: "
54004 + "calling makeroute.\n");
54005 +
54006 + if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
54007 + &(extr->eroute->er_emask),
54008 + extr->ips->ips_said,
54009 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
54010 + NULL,
54011 + &(extr->ips->ips_ident_s),
54012 + &(extr->ips->ips_ident_d)))) {
54013 + KLIPS_PRINT(debug_pfkey,
54014 + "klips_debug:pfkey_x_addflow_parse: "
54015 + "makeroute returned %d.\n", error);
54016 + SENDERR(-error);
54017 + }
54018 + if(first != NULL) {
54019 + KLIPS_PRINT(debug_eroute,
54020 + "klips_debug:pfkey_x_addflow_parse: "
54021 + "first=0p%p HOLD packet re-injected.\n",
54022 + first);
54023 + DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL);
54024 + }
54025 + if(last != NULL) {
54026 + KLIPS_PRINT(debug_eroute,
54027 + "klips_debug:pfkey_x_addflow_parse: "
54028 + "last=0p%p HOLD packet re-injected.\n",
54029 + last);
54030 + DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL);
54031 + }
54032 + }
54033 +
54034 + KLIPS_PRINT(debug_pfkey,
54035 + "klips_debug:pfkey_x_addflow_parse: "
54036 + "makeroute call successful.\n");
54037 +
54038 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
54039 + SADB_X_ADDFLOW,
54040 + satype,
54041 + 0,
54042 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
54043 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
54044 + extensions_reply)
54045 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
54046 + SADB_EXT_SA,
54047 + extr->ips->ips_said.spi,
54048 + extr->ips->ips_replaywin,
54049 + extr->ips->ips_state,
54050 + extr->ips->ips_authalg,
54051 + extr->ips->ips_encalg,
54052 + extr->ips->ips_flags,
54053 + extr->ips->ips_ref),
54054 + extensions_reply)
54055 + && (extensions[SADB_EXT_ADDRESS_SRC]
54056 + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
54057 + SADB_EXT_ADDRESS_SRC,
54058 + 0, /*extr->ips->ips_said.proto,*/
54059 + 0,
54060 + extr->ips->ips_addr_s),
54061 + extensions_reply) : 1)
54062 + && (extensions[SADB_EXT_ADDRESS_DST]
54063 + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
54064 + SADB_EXT_ADDRESS_DST,
54065 + 0, /*extr->ips->ips_said.proto,*/
54066 + 0,
54067 + extr->ips->ips_addr_d),
54068 + extensions_reply) : 1)
54069 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
54070 + SADB_X_EXT_ADDRESS_SRC_FLOW,
54071 + 0, /*extr->ips->ips_said.proto,*/
54072 + 0,
54073 + (struct sockaddr*)&srcflow),
54074 + extensions_reply)
54075 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
54076 + SADB_X_EXT_ADDRESS_DST_FLOW,
54077 + 0, /*extr->ips->ips_said.proto,*/
54078 + 0,
54079 + (struct sockaddr*)&dstflow),
54080 + extensions_reply)
54081 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
54082 + SADB_X_EXT_ADDRESS_SRC_MASK,
54083 + 0, /*extr->ips->ips_said.proto,*/
54084 + 0,
54085 + (struct sockaddr*)&srcmask),
54086 + extensions_reply)
54087 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
54088 + SADB_X_EXT_ADDRESS_DST_MASK,
54089 + 0, /*extr->ips->ips_said.proto,*/
54090 + 0,
54091 + (struct sockaddr*)&dstmask),
54092 + extensions_reply)
54093 + )) {
54094 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54095 + "failed to build the x_addflow reply message extensions\n");
54096 + SENDERR(-error);
54097 + }
54098 +
54099 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
54100 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54101 + "failed to build the x_addflow reply message\n");
54102 + SENDERR(-error);
54103 + }
54104 +
54105 + for(pfkey_socketsp = pfkey_open_sockets;
54106 + pfkey_socketsp;
54107 + pfkey_socketsp = pfkey_socketsp->next) {
54108 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
54109 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54110 + "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54111 + satype,
54112 + satype2name(satype),
54113 + pfkey_socketsp->socketp,
54114 + error);
54115 + SENDERR(-error);
54116 + }
54117 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
54118 + "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
54119 + satype,
54120 + satype2name(satype),
54121 + extr->ips->ips_said.proto,
54122 + pfkey_socketsp->socketp);
54123 + }
54124 +
54125 + KLIPS_PRINT(debug_pfkey,
54126 + "klips_debug:pfkey_x_addflow_parse: "
54127 + "extr->ips cleaned up and freed.\n");
54128 +
54129 + errlab:
54130 + if (pfkey_reply) {
54131 + pfkey_msg_free(&pfkey_reply);
54132 + }
54133 + pfkey_extensions_free(extensions_reply);
54134 + return error;
54135 +}
54136 +
54137 +DEBUG_NO_STATIC int
54138 +pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54139 +{
54140 + int error = 0;
54141 +#ifdef CONFIG_KLIPS_DEBUG
54142 + char buf1[64], buf2[64];
54143 +#endif /* CONFIG_KLIPS_DEBUG */
54144 + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
54145 + struct sadb_msg *pfkey_reply = NULL;
54146 + struct socket_list *pfkey_socketsp;
54147 + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
54148 + ip_address srcflow, dstflow, srcmask, dstmask;
54149 +
54150 + KLIPS_PRINT(debug_pfkey,
54151 + "klips_debug:pfkey_x_delflow_parse: .\n");
54152 +
54153 + pfkey_extensions_init(extensions_reply);
54154 +
54155 + memset((caddr_t)&srcflow, 0, sizeof(srcflow));
54156 + memset((caddr_t)&dstflow, 0, sizeof(dstflow));
54157 + memset((caddr_t)&srcmask, 0, sizeof(srcmask));
54158 + memset((caddr_t)&dstmask, 0, sizeof(dstmask));
54159 +
54160 + if(!extr || !(extr->ips)) {
54161 + KLIPS_PRINT(debug_pfkey,
54162 + "klips_debug:pfkey_x_delflow_parse: "
54163 + "extr, or extr->ips is NULL, fatal\n");
54164 + SENDERR(EINVAL);
54165 + }
54166 +
54167 + if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
54168 + KLIPS_PRINT(debug_pfkey,
54169 + "klips_debug:pfkey_x_delflow_parse: "
54170 + "CLEARFLOW flag set, calling cleareroutes.\n");
54171 + if ((error = ipsec_cleareroutes()))
54172 + KLIPS_PRINT(debug_pfkey,
54173 + "klips_debug:pfkey_x_delflow_parse: "
54174 + "cleareroutes returned %d.\n", error);
54175 + SENDERR(-error);
54176 + } else {
54177 + struct sk_buff *first = NULL, *last = NULL;
54178 +
54179 + if(!(extr->eroute)) {
54180 + KLIPS_PRINT(debug_pfkey,
54181 + "klips_debug:pfkey_x_delflow_parse: "
54182 + "extr->eroute is NULL, fatal.\n");
54183 + SENDERR(EINVAL);
54184 + }
54185 +
54186 + srcflow.u.v4.sin_family = AF_INET;
54187 + dstflow.u.v4.sin_family = AF_INET;
54188 + srcmask.u.v4.sin_family = AF_INET;
54189 + dstmask.u.v4.sin_family = AF_INET;
54190 + srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
54191 + dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
54192 + srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
54193 + dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
54194 +
54195 +#ifdef CONFIG_KLIPS_DEBUG
54196 + if (debug_pfkey) {
54197 + subnettoa(extr->eroute->er_eaddr.sen_ip_src,
54198 + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
54199 + subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
54200 + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
54201 + KLIPS_PRINT(debug_pfkey,
54202 + "klips_debug:pfkey_x_delflow_parse: "
54203 + "calling breakeroute for %s->%s\n",
54204 + buf1, buf2);
54205 + }
54206 +#endif /* CONFIG_KLIPS_DEBUG */
54207 + error = ipsec_breakroute(&(extr->eroute->er_eaddr),
54208 + &(extr->eroute->er_emask),
54209 + &first, &last);
54210 + if(error) {
54211 + KLIPS_PRINT(debug_pfkey,
54212 + "klips_debug:pfkey_x_delflow_parse: "
54213 + "breakeroute returned %d. first=0p%p, last=0p%p\n",
54214 + error,
54215 + first,
54216 + last);
54217 + }
54218 + if(first != NULL) {
54219 + ipsec_kfree_skb(first);
54220 + }
54221 + if(last != NULL) {
54222 + ipsec_kfree_skb(last);
54223 + }
54224 + if(error) {
54225 + SENDERR(-error);
54226 + }
54227 + }
54228 +
54229 + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
54230 + SADB_X_DELFLOW,
54231 + satype,
54232 + 0,
54233 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
54234 + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
54235 + extensions_reply)
54236 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
54237 + SADB_EXT_SA,
54238 + extr->ips->ips_said.spi,
54239 + extr->ips->ips_replaywin,
54240 + extr->ips->ips_state,
54241 + extr->ips->ips_authalg,
54242 + extr->ips->ips_encalg,
54243 + extr->ips->ips_flags,
54244 + extr->ips->ips_ref),
54245 + extensions_reply)
54246 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
54247 + SADB_X_EXT_ADDRESS_SRC_FLOW,
54248 + 0, /*extr->ips->ips_said.proto,*/
54249 + 0,
54250 + (struct sockaddr*)&srcflow),
54251 + extensions_reply)
54252 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
54253 + SADB_X_EXT_ADDRESS_DST_FLOW,
54254 + 0, /*extr->ips->ips_said.proto,*/
54255 + 0,
54256 + (struct sockaddr*)&dstflow),
54257 + extensions_reply)
54258 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
54259 + SADB_X_EXT_ADDRESS_SRC_MASK,
54260 + 0, /*extr->ips->ips_said.proto,*/
54261 + 0,
54262 + (struct sockaddr*)&srcmask),
54263 + extensions_reply)
54264 + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
54265 + SADB_X_EXT_ADDRESS_DST_MASK,
54266 + 0, /*extr->ips->ips_said.proto,*/
54267 + 0,
54268 + (struct sockaddr*)&dstmask),
54269 + extensions_reply)
54270 + )) {
54271 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54272 + "failed to build the x_delflow reply message extensions\n");
54273 + SENDERR(-error);
54274 + }
54275 +
54276 + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
54277 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54278 + "failed to build the x_delflow reply message\n");
54279 + SENDERR(-error);
54280 + }
54281 +
54282 + for(pfkey_socketsp = pfkey_open_sockets;
54283 + pfkey_socketsp;
54284 + pfkey_socketsp = pfkey_socketsp->next) {
54285 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
54286 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54287 + "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54288 + satype,
54289 + satype2name(satype),
54290 + pfkey_socketsp->socketp,
54291 + error);
54292 + SENDERR(-error);
54293 + }
54294 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
54295 + "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
54296 + satype,
54297 + satype2name(satype),
54298 + pfkey_socketsp->socketp);
54299 + }
54300 +
54301 + KLIPS_PRINT(debug_pfkey,
54302 + "klips_debug:pfkey_x_delflow_parse: "
54303 + "extr->ips cleaned up and freed.\n");
54304 +
54305 + errlab:
54306 + if (pfkey_reply) {
54307 + pfkey_msg_free(&pfkey_reply);
54308 + }
54309 + pfkey_extensions_free(extensions_reply);
54310 + return error;
54311 +}
54312 +
54313 +DEBUG_NO_STATIC int
54314 +pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54315 +{
54316 + int error = 0;
54317 +
54318 + KLIPS_PRINT(debug_pfkey,
54319 + "klips_debug:pfkey_x_msg_debug_parse: .\n");
54320 +
54321 +/* errlab:*/
54322 + return error;
54323 +}
54324 +
54325 +/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
54326 +int
54327 +pfkey_expire(struct ipsec_sa *ipsp, int hard)
54328 +{
54329 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
54330 + struct sadb_msg *pfkey_msg = NULL;
54331 + struct socket_list *pfkey_socketsp;
54332 + int error = 0;
54333 + uint8_t satype;
54334 +
54335 + pfkey_extensions_init(extensions);
54336 +
54337 + if(!(satype = proto2satype(ipsp->ips_said.proto))) {
54338 + KLIPS_PRINT(debug_pfkey,
54339 + "klips_debug:pfkey_expire: "
54340 + "satype lookup for protocol %d lookup failed.\n",
54341 + ipsp->ips_said.proto);
54342 + SENDERR(EINVAL);
54343 + }
54344 +
54345 + if(!pfkey_open_sockets) {
54346 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54347 + "no sockets listening.\n");
54348 + SENDERR(EPROTONOSUPPORT);
54349 + }
54350 +
54351 + if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
54352 + SADB_EXPIRE,
54353 + satype,
54354 + 0,
54355 + ++pfkey_msg_seq,
54356 + 0),
54357 + extensions)
54358 + && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
54359 + SADB_EXT_SA,
54360 + ipsp->ips_said.spi,
54361 + ipsp->ips_replaywin,
54362 + ipsp->ips_state,
54363 + ipsp->ips_authalg,
54364 + ipsp->ips_encalg,
54365 + ipsp->ips_flags,
54366 + ipsp->ips_ref),
54367 + extensions)
54368 + && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
54369 + SADB_EXT_LIFETIME_CURRENT,
54370 + ipsp->ips_life.ipl_allocations.ipl_count,
54371 + ipsp->ips_life.ipl_bytes.ipl_count,
54372 + ipsp->ips_life.ipl_addtime.ipl_count,
54373 + ipsp->ips_life.ipl_usetime.ipl_count,
54374 + ipsp->ips_life.ipl_packets.ipl_count),
54375 + extensions)
54376 + && (hard ?
54377 + pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
54378 + SADB_EXT_LIFETIME_HARD,
54379 + ipsp->ips_life.ipl_allocations.ipl_hard,
54380 + ipsp->ips_life.ipl_bytes.ipl_hard,
54381 + ipsp->ips_life.ipl_addtime.ipl_hard,
54382 + ipsp->ips_life.ipl_usetime.ipl_hard,
54383 + ipsp->ips_life.ipl_packets.ipl_hard),
54384 + extensions)
54385 + : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
54386 + SADB_EXT_LIFETIME_SOFT,
54387 + ipsp->ips_life.ipl_allocations.ipl_soft,
54388 + ipsp->ips_life.ipl_bytes.ipl_soft,
54389 + ipsp->ips_life.ipl_addtime.ipl_soft,
54390 + ipsp->ips_life.ipl_usetime.ipl_soft,
54391 + ipsp->ips_life.ipl_packets.ipl_soft),
54392 + extensions))
54393 + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54394 + SADB_EXT_ADDRESS_SRC,
54395 + 0, /* ipsp->ips_said.proto, */
54396 + 0,
54397 + ipsp->ips_addr_s),
54398 + extensions)
54399 + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54400 + SADB_EXT_ADDRESS_DST,
54401 + 0, /* ipsp->ips_said.proto, */
54402 + 0,
54403 + ipsp->ips_addr_d),
54404 + extensions))) {
54405 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54406 + "failed to build the expire message extensions\n");
54407 + spin_unlock(&tdb_lock);
54408 + goto errlab;
54409 + }
54410 +
54411 + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54412 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54413 + "failed to build the expire message\n");
54414 + SENDERR(-error);
54415 + }
54416 +
54417 + for(pfkey_socketsp = pfkey_open_sockets;
54418 + pfkey_socketsp;
54419 + pfkey_socketsp = pfkey_socketsp->next) {
54420 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54421 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54422 + "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54423 + satype,
54424 + satype2name(satype),
54425 + pfkey_socketsp->socketp,
54426 + error);
54427 + SENDERR(-error);
54428 + }
54429 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
54430 + "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
54431 + satype,
54432 + satype2name(satype),
54433 + ipsp->ips_said.proto,
54434 + pfkey_socketsp->socketp);
54435 + }
54436 +
54437 + errlab:
54438 + if (pfkey_msg) {
54439 + pfkey_msg_free(&pfkey_msg);
54440 + }
54441 + pfkey_extensions_free(extensions);
54442 + return error;
54443 +}
54444 +
54445 +int
54446 +pfkey_acquire(struct ipsec_sa *ipsp)
54447 +{
54448 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
54449 + struct sadb_msg *pfkey_msg = NULL;
54450 + struct socket_list *pfkey_socketsp;
54451 + int error = 0;
54452 + struct sadb_comb comb[] = {
54453 + /* auth; encrypt; flags; */
54454 + /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
54455 + /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
54456 + /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
54457 + /* soft_packets; hard_packets; */
54458 + { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
54459 + 128, 128, 168, 168,
54460 + 0, 0, 0, 0, 0,
54461 + 57600, 86400, 57600, 86400,
54462 + 0, 0 },
54463 + { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
54464 + 160, 160, 168, 168,
54465 + 0, 0, 0, 0, 0,
54466 + 57600, 86400, 57600, 86400,
54467 + 0, 0 }
54468 + };
54469 +
54470 + /* XXX This should not be hard-coded. It should be taken from the spdb */
54471 + uint8_t satype = SADB_SATYPE_ESP;
54472 +
54473 + pfkey_extensions_init(extensions);
54474 +
54475 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
54476 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
54477 + "SAtype=%d unspecified or unknown.\n",
54478 + satype);
54479 + SENDERR(EINVAL);
54480 + }
54481 +
54482 + if(!(pfkey_registered_sockets[satype])) {
54483 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54484 + "no sockets registered for SAtype=%d(%s).\n",
54485 + satype,
54486 + satype2name(satype));
54487 + SENDERR(EPROTONOSUPPORT);
54488 + }
54489 +
54490 + if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
54491 + SADB_ACQUIRE,
54492 + satype,
54493 + 0,
54494 + ++pfkey_msg_seq,
54495 + 0),
54496 + extensions)
54497 + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54498 + SADB_EXT_ADDRESS_SRC,
54499 + ipsp->ips_transport_protocol,
54500 + 0,
54501 + ipsp->ips_addr_s),
54502 + extensions)
54503 + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54504 + SADB_EXT_ADDRESS_DST,
54505 + ipsp->ips_transport_protocol,
54506 + 0,
54507 + ipsp->ips_addr_d),
54508 + extensions)
54509 +#if 0
54510 + && (ipsp->ips_addr_p
54511 + ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
54512 + SADB_EXT_ADDRESS_PROXY,
54513 + ipsp->ips_transport_protocol,
54514 + 0,
54515 + ipsp->ips_addr_p),
54516 + extensions) : 1)
54517 +#endif
54518 + && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
54519 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
54520 + SADB_EXT_IDENTITY_SRC,
54521 + ipsp->ips_ident_s.type,
54522 + ipsp->ips_ident_s.id,
54523 + ipsp->ips_ident_s.len,
54524 + ipsp->ips_ident_s.data),
54525 + extensions) : 1)
54526 +
54527 + && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
54528 + ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
54529 + SADB_EXT_IDENTITY_DST,
54530 + ipsp->ips_ident_d.type,
54531 + ipsp->ips_ident_d.id,
54532 + ipsp->ips_ident_d.len,
54533 + ipsp->ips_ident_d.data),
54534 + extensions) : 1)
54535 +#if 0
54536 + /* FIXME: This won't work yet because I have not finished
54537 + it. */
54538 + && (ipsp->ips_sens_
54539 + ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
54540 + ipsp->ips_sens_dpd,
54541 + ipsp->ips_sens_sens_level,
54542 + ipsp->ips_sens_sens_len,
54543 + ipsp->ips_sens_sens_bitmap,
54544 + ipsp->ips_sens_integ_level,
54545 + ipsp->ips_sens_integ_len,
54546 + ipsp->ips_sens_integ_bitmap),
54547 + extensions) : 1)
54548 +#endif
54549 + && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
54550 + 64, /* replay */
54551 + sizeof(comb)/sizeof(struct sadb_comb),
54552 + &(comb[0])),
54553 + extensions)
54554 + )) {
54555 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54556 + "failed to build the acquire message extensions\n");
54557 + SENDERR(-error);
54558 + }
54559 +
54560 + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54561 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54562 + "failed to build the acquire message\n");
54563 + SENDERR(-error);
54564 + }
54565 +
54566 +#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
54567 + if(sysctl_ipsec_regress_pfkey_lossage) {
54568 + return(0);
54569 + }
54570 +#endif
54571 +
54572 + /* this should go to all registered sockets for that satype only */
54573 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
54574 + pfkey_socketsp;
54575 + pfkey_socketsp = pfkey_socketsp->next) {
54576 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54577 + KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
54578 + "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
54579 + satype,
54580 + satype2name(satype),
54581 + pfkey_socketsp->socketp,
54582 + error);
54583 + SENDERR(-error);
54584 + }
54585 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
54586 + "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
54587 + satype,
54588 + satype2name(satype),
54589 + pfkey_socketsp->socketp);
54590 + }
54591 +
54592 + errlab:
54593 + if (pfkey_msg) {
54594 + pfkey_msg_free(&pfkey_msg);
54595 + }
54596 + pfkey_extensions_free(extensions);
54597 + return error;
54598 +}
54599 +
54600 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54601 +int
54602 +pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr,
54603 + __u16 sport)
54604 +{
54605 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
54606 + struct sadb_msg *pfkey_msg = NULL;
54607 + struct socket_list *pfkey_socketsp;
54608 + int error = 0;
54609 + uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0;
54610 +
54611 + /* Construct SADB_X_NAT_T_NEW_MAPPING message */
54612 +
54613 + pfkey_extensions_init(extensions);
54614 +
54615 + if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
54616 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54617 + "SAtype=%d unspecified or unknown.\n",
54618 + satype);
54619 + SENDERR(EINVAL);
54620 + }
54621 +
54622 + if(!(pfkey_registered_sockets[satype])) {
54623 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54624 + "no sockets registered for SAtype=%d(%s).\n",
54625 + satype,
54626 + satype2name(satype));
54627 + SENDERR(EPROTONOSUPPORT);
54628 + }
54629 +
54630 + if (!(pfkey_safe_build
54631 + (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING,
54632 + satype, 0, ++pfkey_msg_seq, 0), extensions)
54633 + /* SA */
54634 + && pfkey_safe_build
54635 + (error = pfkey_sa_build(&extensions[SADB_EXT_SA],
54636 + SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions)
54637 + /* ADDRESS_SRC = old addr */
54638 + && pfkey_safe_build
54639 + (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54640 + SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s),
54641 + extensions)
54642 + /* NAT_T_SPORT = old port */
54643 + && pfkey_safe_build
54644 + (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT],
54645 + SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions)
54646 + /* ADDRESS_DST = new addr */
54647 + && pfkey_safe_build
54648 + (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54649 + SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions)
54650 + /* NAT_T_DPORT = new port */
54651 + && pfkey_safe_build
54652 + (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT],
54653 + SADB_X_EXT_NAT_T_DPORT, sport), extensions)
54654 + )) {
54655 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54656 + "failed to build the nat_t_new_mapping message extensions\n");
54657 + SENDERR(-error);
54658 + }
54659 +
54660 + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
54661 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54662 + "failed to build the nat_t_new_mapping message\n");
54663 + SENDERR(-error);
54664 + }
54665 +
54666 + /* this should go to all registered sockets for that satype only */
54667 + for(pfkey_socketsp = pfkey_registered_sockets[satype];
54668 + pfkey_socketsp;
54669 + pfkey_socketsp = pfkey_socketsp->next) {
54670 + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
54671 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54672 + "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
54673 + satype,
54674 + satype2name(satype),
54675 + pfkey_socketsp->socketp,
54676 + error);
54677 + SENDERR(-error);
54678 + }
54679 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
54680 + "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
54681 + satype,
54682 + satype2name(satype),
54683 + pfkey_socketsp->socketp);
54684 + }
54685 +
54686 + errlab:
54687 + if (pfkey_msg) {
54688 + pfkey_msg_free(&pfkey_msg);
54689 + }
54690 + pfkey_extensions_free(extensions);
54691 + return error;
54692 +}
54693 +
54694 +DEBUG_NO_STATIC int
54695 +pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
54696 +{
54697 + /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */
54698 + return -EINVAL;
54699 +}
54700 +#endif
54701 +
54702 +DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
54703 +{
54704 + NULL, /* pfkey_msg_process, */
54705 + pfkey_sa_process,
54706 + pfkey_lifetime_process,
54707 + pfkey_lifetime_process,
54708 + pfkey_lifetime_process,
54709 + pfkey_address_process,
54710 + pfkey_address_process,
54711 + pfkey_address_process,
54712 + pfkey_key_process,
54713 + pfkey_key_process,
54714 + pfkey_ident_process,
54715 + pfkey_ident_process,
54716 + pfkey_sens_process,
54717 + pfkey_prop_process,
54718 + pfkey_supported_process,
54719 + pfkey_supported_process,
54720 + pfkey_spirange_process,
54721 + pfkey_x_kmprivate_process,
54722 + pfkey_x_satype_process,
54723 + pfkey_sa_process,
54724 + pfkey_address_process,
54725 + pfkey_address_process,
54726 + pfkey_address_process,
54727 + pfkey_address_process,
54728 + pfkey_address_process,
54729 + pfkey_x_debug_process,
54730 + pfkey_x_protocol_process
54731 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54732 + ,
54733 + pfkey_x_nat_t_type_process,
54734 + pfkey_x_nat_t_port_process,
54735 + pfkey_x_nat_t_port_process,
54736 + pfkey_address_process
54737 +#endif
54738 +};
54739 +
54740 +
54741 +DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
54742 + =
54743 +{
54744 + NULL, /* RESERVED */
54745 + pfkey_getspi_parse,
54746 + pfkey_update_parse,
54747 + pfkey_add_parse,
54748 + pfkey_delete_parse,
54749 + pfkey_get_parse,
54750 + pfkey_acquire_parse,
54751 + pfkey_register_parse,
54752 + pfkey_expire_parse,
54753 + pfkey_flush_parse,
54754 + pfkey_dump_parse,
54755 + pfkey_x_promisc_parse,
54756 + pfkey_x_pchange_parse,
54757 + pfkey_x_grpsa_parse,
54758 + pfkey_x_addflow_parse,
54759 + pfkey_x_delflow_parse,
54760 + pfkey_x_msg_debug_parse
54761 +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
54762 + , pfkey_x_nat_t_new_mapping_parse
54763 +#endif
54764 +};
54765 +
54766 +int
54767 +pfkey_build_reply(struct sadb_msg *pfkey_msg,
54768 + struct pfkey_extracted_data *extr,
54769 + struct sadb_msg **pfkey_reply)
54770 +{
54771 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
54772 + int error = 0;
54773 + int msg_type = pfkey_msg->sadb_msg_type;
54774 + int seq = pfkey_msg->sadb_msg_seq;
54775 +
54776 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
54777 + "building reply with type: %d\n",
54778 + msg_type);
54779 + pfkey_extensions_init(extensions);
54780 + if (!extr || !extr->ips) {
54781 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
54782 + "bad ipsec_sa passed\n");
54783 + return EINVAL;
54784 + }
54785 + error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
54786 + msg_type,
54787 + proto2satype(extr->ips->ips_said.proto),
54788 + 0,
54789 + seq,
54790 + pfkey_msg->sadb_msg_pid),
54791 + extensions) &&
54792 + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54793 + 1 << SADB_EXT_SA)
54794 + || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
54795 + SADB_EXT_SA,
54796 + extr->ips->ips_said.spi,
54797 + extr->ips->ips_replaywin,
54798 + extr->ips->ips_state,
54799 + extr->ips->ips_authalg,
54800 + extr->ips->ips_encalg,
54801 + extr->ips->ips_flags,
54802 + extr->ips->ips_ref),
54803 + extensions)) &&
54804 + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54805 + 1 << SADB_EXT_LIFETIME_CURRENT)
54806 + || pfkey_safe_build(pfkey_lifetime_build(&extensions
54807 + [SADB_EXT_LIFETIME_CURRENT],
54808 + SADB_EXT_LIFETIME_CURRENT,
54809 + extr->ips->ips_life.ipl_allocations.ipl_count,
54810 + extr->ips->ips_life.ipl_bytes.ipl_count,
54811 + extr->ips->ips_life.ipl_addtime.ipl_count,
54812 + extr->ips->ips_life.ipl_usetime.ipl_count,
54813 + extr->ips->ips_life.ipl_packets.ipl_count),
54814 + extensions)) &&
54815 + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54816 + 1 << SADB_EXT_ADDRESS_SRC)
54817 + || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
54818 + SADB_EXT_ADDRESS_SRC,
54819 + extr->ips->ips_said.proto,
54820 + 0,
54821 + extr->ips->ips_addr_s),
54822 + extensions)) &&
54823 + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
54824 + 1 << SADB_EXT_ADDRESS_DST)
54825 + || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
54826 + SADB_EXT_ADDRESS_DST,
54827 + extr->ips->ips_said.proto,
54828 + 0,
54829 + extr->ips->ips_addr_d),
54830 + extensions));
54831 +
54832 + if (error == 0) {
54833 + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
54834 + "building extensions failed\n");
54835 + return EINVAL;
54836 + }
54837 +
54838 + KLIPS_PRINT(debug_pfkey,
54839 + "klips_debug:pfkey_build_reply: "
54840 + "built extensions, proceed to build the message\n");
54841 + KLIPS_PRINT(debug_pfkey,
54842 + "klips_debug:pfkey_build_reply: "
54843 + "extensions[1]=0p%p\n",
54844 + extensions[1]);
54845 + error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
54846 + pfkey_extensions_free(extensions);
54847 +
54848 + return error;
54849 +}
54850 +
54851 +int
54852 +pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
54853 + struct sadb_msg **pfkey_reply)
54854 +{
54855 + int error = 0;
54856 + int i;
54857 + struct sadb_ext *extensions[SADB_EXT_MAX+1];
54858 + struct pfkey_extracted_data extr = {NULL, NULL, NULL};
54859 +
54860 + pfkey_extensions_init(extensions);
54861 + KLIPS_PRINT(debug_pfkey,
54862 + "klips_debug:pfkey_msg_interp: "
54863 + "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
54864 + pfkey_msg->sadb_msg_version,
54865 + pfkey_msg->sadb_msg_type,
54866 + pfkey_msg->sadb_msg_errno,
54867 + pfkey_msg->sadb_msg_satype,
54868 + satype2name(pfkey_msg->sadb_msg_satype),
54869 + pfkey_msg->sadb_msg_len,
54870 + pfkey_msg->sadb_msg_reserved,
54871 + pfkey_msg->sadb_msg_seq,
54872 + pfkey_msg->sadb_msg_pid);
54873 +
54874 + extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
54875 + if(extr.ips == NULL) {
54876 + KLIPS_PRINT(debug_pfkey,
54877 + "klips_debug:pfkey_msg_interp: "
54878 + "memory allocation error.\n");
54879 + SENDERR(-error);
54880 + }
54881 +
54882 + KLIPS_PRINT(debug_pfkey,
54883 + "klips_debug:pfkey_msg_interp: "
54884 + "allocated extr->ips=0p%p.\n",
54885 + extr.ips);
54886 +
54887 + if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
54888 + KLIPS_PRINT(debug_pfkey,
54889 + "klips_debug:pfkey_msg_interp: "
54890 + "satype %d > max %d\n",
54891 + pfkey_msg->sadb_msg_satype,
54892 + SADB_SATYPE_MAX);
54893 + SENDERR(EINVAL);
54894 + }
54895 +
54896 + switch(pfkey_msg->sadb_msg_type) {
54897 + case SADB_GETSPI:
54898 + case SADB_UPDATE:
54899 + case SADB_ADD:
54900 + case SADB_DELETE:
54901 + case SADB_X_GRPSA:
54902 + case SADB_X_ADDFLOW:
54903 + if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
54904 + KLIPS_PRINT(debug_pfkey,
54905 + "klips_debug:pfkey_msg_interp: "
54906 + "satype %d lookup failed.\n",
54907 + pfkey_msg->sadb_msg_satype);
54908 + SENDERR(EINVAL);
54909 + } else {
54910 + KLIPS_PRINT(debug_pfkey,
54911 + "klips_debug:pfkey_msg_interp: "
54912 + "satype %d lookups to proto=%d.\n",
54913 + pfkey_msg->sadb_msg_satype,
54914 + extr.ips->ips_said.proto);
54915 + }
54916 + break;
54917 + default:
54918 + break;
54919 + }
54920 +
54921 + /* The NULL below causes the default extension parsers to be used */
54922 + /* Parse the extensions */
54923 + if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
54924 + {
54925 + KLIPS_PRINT(debug_pfkey,
54926 + "klips_debug:pfkey_msg_interp: "
54927 + "message parsing failed with error %d.\n",
54928 + error);
54929 + SENDERR(-error);
54930 + }
54931 +
54932 + /* Process the extensions */
54933 + for(i=1; i <= SADB_EXT_MAX;i++) {
54934 + if(extensions[i] != NULL) {
54935 + KLIPS_PRINT(debug_pfkey,
54936 + "klips_debug:pfkey_msg_interp: "
54937 + "processing ext %d 0p%p with processor 0p%p.\n",
54938 + i, extensions[i], ext_processors[i]);
54939 + if((error = ext_processors[i](extensions[i], &extr))) {
54940 + KLIPS_PRINT(debug_pfkey,
54941 + "klips_debug:pfkey_msg_interp: "
54942 + "extension processing for type %d failed with error %d.\n",
54943 + i,
54944 + error);
54945 + SENDERR(-error);
54946 + }
54947 +
54948 + }
54949 +
54950 + }
54951 +
54952 + /* Parse the message types */
54953 + KLIPS_PRINT(debug_pfkey,
54954 + "klips_debug:pfkey_msg_interp: "
54955 + "parsing message type %d(%s) with msg_parser 0p%p.\n",
54956 + pfkey_msg->sadb_msg_type,
54957 + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
54958 + msg_parsers[pfkey_msg->sadb_msg_type]);
54959 + if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
54960 + KLIPS_PRINT(debug_pfkey,
54961 + "klips_debug:pfkey_msg_interp: "
54962 + "message parsing failed with error %d.\n",
54963 + error);
54964 + SENDERR(-error);
54965 + }
54966 +
54967 +#if 0
54968 + error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
54969 + if (error) {
54970 + *pfkey_reply = NULL;
54971 + }
54972 +#endif
54973 + errlab:
54974 + if(extr.ips != NULL) {
54975 + ipsec_sa_wipe(extr.ips);
54976 + }
54977 + if(extr.ips2 != NULL) {
54978 + ipsec_sa_wipe(extr.ips2);
54979 + }
54980 + if (extr.eroute != NULL) {
54981 + kfree(extr.eroute);
54982 + }
54983 + return(error);
54984 +}
54985 +
54986 +/*
54987 + * $Log: pfkey_v2_parser.c,v $
54988 + * Revision 1.134.2.2 2006/10/06 21:39:26 paul
54989 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
54990 + * set. This is defined through autoconf.h which is included through the
54991 + * linux kernel build macros.
54992 + *
54993 + * Revision 1.134.2.1 2006/05/01 14:37:25 mcr
54994 + * ip_chk_addr -> inet_addr_type for more direct 2.4/2.6 support.
54995 + *
54996 + * Revision 1.134 2005/05/11 01:48:20 mcr
54997 + * removed "poor-man"s OOP in favour of proper C structures.
54998 + *
54999 + * Revision 1.133 2005/04/29 05:10:22 mcr
55000 + * removed from extraenous includes to make unit testing easier.
55001 + *
55002 + * Revision 1.132 2005/04/14 20:56:24 mcr
55003 + * moved (pfkey_)ipsec_sa_init to ipsec_sa.c.
55004 + *
55005 + * Revision 1.131 2005/01/26 00:50:35 mcr
55006 + * adjustment of confusion of CONFIG_IPSEC_NAT vs CONFIG_KLIPS_NAT,
55007 + * and make sure that NAT_TRAVERSAL is set as well to match
55008 + * userspace compiles of code.
55009 + *
55010 + * Revision 1.130 2004/09/08 17:21:36 ken
55011 + * Rename MD5* -> osMD5 functions to prevent clashes with other symbols exported by kernel modules (CIFS in 2.6 initiated this)
55012 + *
55013 + * Revision 1.129 2004/09/06 18:36:30 mcr
55014 + * if a protocol can not be found, then log it. This is not
55015 + * debugging.
55016 + *
55017 + * Revision 1.128 2004/08/21 00:45:19 mcr
55018 + * CONFIG_KLIPS_NAT was wrong, also need to include udp.h.
55019 + *
55020 + * Revision 1.127 2004/08/20 21:45:45 mcr
55021 + * CONFIG_KLIPS_NAT_TRAVERSAL is not used in an attempt to
55022 + * be 26sec compatible. But, some defines where changed.
55023 + *
55024 + * Revision 1.126 2004/08/17 03:27:23 mcr
55025 + * klips 2.6 edits.
55026 + *
55027 + * Revision 1.125 2004/08/04 15:57:07 mcr
55028 + * moved des .h files to include/des/ *
55029 + * included 2.6 protocol specific things
55030 + * started at NAT-T support, but it will require a kernel patch.
55031 + *
55032 + * Revision 1.124 2004/07/10 19:11:18 mcr
55033 + * CONFIG_IPSEC -> CONFIG_KLIPS.
55034 + *
55035 + * Revision 1.123 2004/04/06 02:49:26 mcr
55036 + * pullup of algo code from alg-branch.
55037 + *
55038 + * Revision 1.122.2.2 2004/04/05 04:30:46 mcr
55039 + * patches for alg-branch to compile/work with 2.x openswan
55040 + *
55041 + * Revision 1.122.2.1 2003/12/22 15:25:52 jjo
55042 + * . Merged algo-0.8.1-rc11-test1 into alg-branch
55043 + *
55044 + * Revision 1.122 2003/12/10 01:14:27 mcr
55045 + * NAT-traversal patches to KLIPS.
55046 + *
55047 + * Revision 1.121 2003/10/31 02:27:55 mcr
55048 + * pulled up port-selector patches and sa_id elimination.
55049 + *
55050 + * Revision 1.120.4.2 2003/10/29 01:30:41 mcr
55051 + * elimited "struct sa_id".
55052 + *
55053 + * Revision 1.120.4.1 2003/09/21 13:59:56 mcr
55054 + * pre-liminary X.509 patch - does not yet pass tests.
55055 + *
55056 + * Revision 1.120 2003/04/03 17:38:09 rgb
55057 + * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
55058 + *
55059 + * Revision 1.119 2003/02/06 01:52:37 rgb
55060 + * Removed no longer relevant comment
55061 + *
55062 + * Revision 1.118 2003/01/30 02:32:44 rgb
55063 + *
55064 + * Transmit error code through to caller from callee for better diagnosis of problems.
55065 + *
55066 + * Revision 1.117 2003/01/16 18:48:13 rgb
55067 + *
55068 + * Fixed sign bug in error return from an sa allocation call in
55069 + * pfkey_msg_interp.
55070 + *
55071 + * Revision 1.116 2002/10/17 16:38:01 rgb
55072 + * Change pfkey_alloc_eroute() to never static since its consumers
55073 + * have been moved outside the file.
55074 + *
55075 + * Revision 1.115 2002/10/12 23:11:53 dhr
55076 + *
55077 + * [KenB + DHR] more 64-bit cleanup
55078 + *
55079 + * Revision 1.114 2002/10/05 05:02:58 dhr
55080 + *
55081 + * C labels go on statements
55082 + *
55083 + * Revision 1.113 2002/09/30 19:11:22 rgb
55084 + * Turn on debugging for upgoing acquire messages to test for reliability.
55085 + *
55086 + * Revision 1.112 2002/09/20 15:41:16 rgb
55087 + * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
55088 + * Added sadb_x_sa_ref to struct sadb_sa.
55089 + * Added ref parameter to pfkey_sa_build().
55090 + *
55091 + * Revision 1.111 2002/09/20 05:02:08 rgb
55092 + * Added memory allocation debugging.
55093 + * Convert to switch to divulge hmac keys for debugging.
55094 + * Added text labels to elucidate numeric values presented.
55095 + *
55096 + * Revision 1.110 2002/08/03 18:03:05 mcr
55097 + * loop that checks for SPI's to have been already linked
55098 + * fails to actually step to next pointer, but continuously
55099 + * resets to head of list. Wrong pointer used.
55100 + * test east-icmp-02 revealed this.
55101 + *
55102 + * Revision 1.109 2002/07/26 08:48:31 rgb
55103 + * Added SA ref table code.
55104 + *
55105 + * Revision 1.108 2002/05/27 18:55:03 rgb
55106 + * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
55107 + *
55108 + * Revision 1.107 2002/05/23 07:16:08 rgb
55109 + * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
55110 + * Pointer clean-up.
55111 + * Added refcount code.
55112 + *
55113 + * Revision 1.106 2002/05/14 02:34:13 rgb
55114 + * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
55115 + * with "put" usage in the kernel.
55116 + * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
55117 + * ipsec_sa or ipsec_sa.
55118 + * Moved all the extension parsing functions to pfkey_v2_ext_process.c.
55119 + *
55120 + * Revision 1.105 2002/04/24 07:55:32 mcr
55121 + * #include patches and Makefiles for post-reorg compilation.
55122 + *
55123 + * Revision 1.104 2002/04/24 07:36:34 mcr
55124 + * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v
55125 + *
55126 + * Revision 1.103 2002/04/20 00:12:25 rgb
55127 + * Added esp IV CBC attack fix, disabled.
55128 + *
55129 + * Revision 1.102 2002/03/08 01:15:17 mcr
55130 + * put some internal structure only debug messages behind
55131 + * && sysctl_ipsec_debug_verbose.
55132 + *
55133 + * Revision 1.101 2002/01/29 17:17:57 mcr
55134 + * moved include of ipsec_param.h to after include of linux/kernel.h
55135 + * otherwise, it seems that some option that is set in ipsec_param.h
55136 + * screws up something subtle in the include path to kernel.h, and
55137 + * it complains on the snprintf() prototype.
55138 + *
55139 + * Revision 1.100 2002/01/29 04:00:54 mcr
55140 + * more excise of kversions.h header.
55141 + *
55142 + * Revision 1.99 2002/01/29 02:13:19 mcr
55143 + * introduction of ipsec_kversion.h means that include of
55144 + * ipsec_param.h must preceed any decisions about what files to
55145 + * include to deal with differences in kernel source.
55146 + *
55147 + * Revision 1.98 2002/01/12 02:57:57 mcr
55148 + * first regression test causes acquire messages to be lost
55149 + * 100% of the time. This is to help testing of pluto.
55150 + *
55151 + * Revision 1.97 2001/11/26 09:23:52 rgb
55152 + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
55153 + *
55154 + * Revision 1.93.2.4 2001/10/23 04:20:27 mcr
55155 + * parity was forced on wrong structure! prototypes help here.
55156 + *
55157 + * Revision 1.93.2.3 2001/10/22 21:14:59 mcr
55158 + * include des.h, removed phony prototypes and fixed calling
55159 + * conventions to match real prototypes.
55160 + *
55161 + * Revision 1.93.2.2 2001/10/15 05:39:03 mcr
55162 + * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
55163 + *
55164 + * Revision 1.93.2.1 2001/09/25 02:30:14 mcr
55165 + * struct tdb -> struct ipsec_sa.
55166 + * use new lifetime structure. common format routines for debug.
55167 + *
55168 + * Revision 1.96 2001/11/06 20:47:54 rgb
55169 + * Fixed user context call to ipsec_dev_start_xmit() bug. Call
55170 + * dev_queue_xmit() instead.
55171 + *
55172 + * Revision 1.95 2001/11/06 19:47:46 rgb
55173 + * Added packet parameter to lifetime and comb structures.
55174 + *
55175 + * Revision 1.94 2001/10/18 04:45:23 rgb
55176 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
55177 + * lib/freeswan.h version macros moved to lib/kversions.h.
55178 + * Other compiler directive cleanups.
55179 + *
55180 + * Revision 1.93 2001/09/20 15:32:59 rgb
55181 + * Min/max cleanup.
55182 + *
55183 + * Revision 1.92 2001/09/19 16:35:48 rgb
55184 + * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
55185 + *
55186 + * Revision 1.91 2001/09/15 16:24:06 rgb
55187 + * Re-inject first and last HOLD packet when an eroute REPLACE is done.
55188 + *
55189 + * Revision 1.90 2001/09/14 16:58:38 rgb
55190 + * Added support for storing the first and last packets through a HOLD.
55191 + *
55192 + * Revision 1.89 2001/09/08 21:14:07 rgb
55193 + * Added pfkey ident extension support for ISAKMPd. (NetCelo)
55194 + * Better state coherency (error management) between pf_key and IKE daemon.
55195 + * (NetCelo)
55196 + *
55197 + * Revision 1.88 2001/08/27 19:42:44 rgb
55198 + * Fix memory leak of encrypt and auth structs in pfkey register.
55199 + *
55200 + * Revision 1.87 2001/07/06 19:50:46 rgb
55201 + * Removed unused debugging code.
55202 + * Added inbound policy checking code for IPIP SAs.
55203 + *
55204 + * Revision 1.86 2001/06/20 06:26:04 rgb
55205 + * Changed missing SA errors from EEXIST to ENOENT and added debug output
55206 + * for already linked SAs.
55207 + *
55208 + * Revision 1.85 2001/06/15 04:57:02 rgb
55209 + * Remove single error return condition check and check for all errors in
55210 + * the case of a replace eroute delete operation. This means that
55211 + * applications must expect to be deleting something before replacing it
55212 + * and if nothing is found, complain.
55213 + *
55214 + * Revision 1.84 2001/06/14 19:35:12 rgb
55215 + * Update copyright date.
55216 + *
55217 + * Revision 1.83 2001/06/12 00:03:19 rgb
55218 + * Silence debug set/unset under normal conditions.
55219 + *
55220 + * Revision 1.82 2001/05/30 08:14:04 rgb
55221 + * Removed vestiges of esp-null transforms.
55222 + *
55223 + * Revision 1.81 2001/05/27 06:12:12 rgb
55224 + * Added structures for pid, packet count and last access time to eroute.
55225 + * Added packet count to beginning of /proc/net/ipsec_eroute.
55226 + *
55227 + * Revision 1.80 2001/05/03 19:43:59 rgb
55228 + * Check error return codes for all build function calls.
55229 + * Standardise on SENDERR() macro.
55230 + *
55231 + * Revision 1.79 2001/04/20 21:09:16 rgb
55232 + * Cleaned up fixed tdbwipes.
55233 + * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
55234 + * delflow (Per Cederqvist) plugging memleaks.
55235 + *
55236 + * Revision 1.78 2001/04/19 19:02:39 rgb
55237 + * Fixed extr.tdb freeing, stealing it for getspi, update and add.
55238 + * Refined a couple of spinlocks, fixed the one in update.
55239 + *
55240 + * Revision 1.77 2001/04/18 20:26:16 rgb
55241 + * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
55242 + * instead of inside each message type parser. This fixes two memleaks.
55243 + *
55244 + * Revision 1.76 2001/04/17 23:51:18 rgb
55245 + * Quiet down pfkey_x_debug_process().
55246 + *
55247 + * Revision 1.75 2001/03/29 01:55:05 rgb
55248 + * Fixed pfkey key init memleak.
55249 + * Fixed pfkey encryption key debug output.
55250 + *
55251 + * Revision 1.74 2001/03/27 05:29:14 rgb
55252 + * Debug output cleanup/silencing.
55253 + *
55254 + * Revision 1.73 2001/02/28 05:03:28 rgb
55255 + * Clean up and rationalise startup messages.
55256 + *
55257 + * Revision 1.72 2001/02/27 22:24:56 rgb
55258 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
55259 + * Check for satoa() return codes.
55260 + *
55261 + * Revision 1.71 2001/02/27 06:59:30 rgb
55262 + * Added satype2name() conversions most places satype is debug printed.
55263 + *
55264 + * Revision 1.70 2001/02/26 22:37:08 rgb
55265 + * Fixed 'unknown proto' INT bug in new code.
55266 + * Added satype to protocol debugging instrumentation.
55267 + *
55268 + * Revision 1.69 2001/02/26 19:57:51 rgb
55269 + * Re-formatted debug output (split lines, consistent spacing).
55270 + * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
55271 + * with an satype instead of proto.
55272 + * Checked for satype consistency and fixed minor bugs.
55273 + * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
55274 + * Check for satype sanity in pfkey_expire().
55275 + * Added satype sanity check to addflow.
55276 + *
55277 + * Revision 1.68 2001/02/12 23:14:40 rgb
55278 + * Remove double spin lock in pfkey_expire().
55279 + *
55280 + * Revision 1.67 2001/01/31 19:23:40 rgb
55281 + * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
55282 + *
55283 + * Revision 1.66 2001/01/29 22:20:04 rgb
55284 + * Fix minor add upmsg lifetime bug.
55285 + *
55286 + * Revision 1.65 2001/01/24 06:12:33 rgb
55287 + * Fixed address extension compile bugs just introduced.
55288 + *
55289 + * Revision 1.64 2001/01/24 00:31:15 rgb
55290 + * Added upmsg for addflow/delflow.
55291 + *
55292 + * Revision 1.63 2001/01/23 22:02:55 rgb
55293 + * Added upmsg to x_grpsa.
55294 + * Fixed lifetimes extentions to add/update/get upmsg.
55295 + *
55296 + * Revision 1.62 2000/11/30 21:47:51 rgb
55297 + * Fix error return bug after returning from pfkey_tdb_init().
55298 + *
55299 + * Revision 1.61 2000/11/17 18:10:29 rgb
55300 + * Fixed bugs mostly relating to spirange, to treat all spi variables as
55301 + * network byte order since this is the way PF_KEYv2 stored spis.
55302 + *
55303 + * Revision 1.60 2000/11/06 04:34:53 rgb
55304 + * Changed non-exported functions to DEBUG_NO_STATIC.
55305 + * Add Svenning's adaptive content compression.
55306 + * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
55307 + * Fixed double unlock bug (Svenning).
55308 + * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
55309 + * Fixed incorrect extension type (prop) in pfkey)acquire().
55310 + *
55311 + * Revision 1.59 2000/10/11 15:25:12 rgb
55312 + * Fixed IPCOMP disabled compile bug.
55313 + *
55314 + * Revision 1.58 2000/10/11 14:54:03 rgb
55315 + * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
55316 + * protocol violations of setting pfkey_address_build() protocol parameter
55317 + * to non-zero except in the case of pfkey_acquire().
55318 + *
55319 + * Revision 1.57 2000/10/10 20:10:18 rgb
55320 + * Added support for debug_ipcomp and debug_verbose to klipsdebug.
55321 + *
55322 + * Revision 1.56 2000/10/06 20:24:36 rgb
55323 + * Fixes to pfkey_acquire to initialize extensions[] and use correct
55324 + * ipproto.
55325 + *
55326 + * Revision 1.55 2000/10/03 03:20:57 rgb
55327 + * Added brackets to get a?b:c scope right for pfkey_register reply.
55328 + *
55329 + * Revision 1.54 2000/09/29 19:49:30 rgb
55330 + * As-yet-unused-bits cleanup.
55331 + *
55332 + * Revision 1.53 2000/09/28 00:35:45 rgb
55333 + * Padded SATYPE printout in pfkey_register for vertical alignment.
55334 + *
55335 + * Revision 1.52 2000/09/20 16:21:58 rgb
55336 + * Cleaned up ident string alloc/free.
55337 + *
55338 + * Revision 1.51 2000/09/20 04:04:20 rgb
55339 + * Changed static functions to DEBUG_NO_STATIC to reveal function names in
55340 + * oopsen.
55341 + *
55342 + * Revision 1.50 2000/09/16 01:10:53 rgb
55343 + * Fixed unused var warning with debug off.
55344 + *
55345 + * Revision 1.49 2000/09/15 11:37:02 rgb
55346 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
55347 + * IPCOMP zlib deflate code.
55348 + *
55349 + * Revision 1.48 2000/09/15 04:57:57 rgb
55350 + * Cleaned up existing IPCOMP code before svenning addition.
55351 + * Initialize pfkey_reply and extensions_reply in case of early error in
55352 + * message parsing functions (thanks Kai!).
55353 + *
55354 + * Revision 1.47 2000/09/13 08:02:56 rgb
55355 + * Added KMd registration notification.
55356 + *
55357 + * Revision 1.46 2000/09/12 22:35:36 rgb
55358 + * Restructured to remove unused extensions from CLEARFLOW messages.
55359 + *
55360 + * Revision 1.45 2000/09/12 03:24:23 rgb
55361 + * Converted #if0 debugs to sysctl.
55362 + *
55363 + * Revision 1.44 2000/09/09 06:38:39 rgb
55364 + * Correct SADB message type for update, add and delete.
55365 + *
55366 + * Revision 1.43 2000/09/08 19:19:56 rgb
55367 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
55368 + * Removed all references to CONFIG_IPSEC_PFKEYv2.
55369 + * Put in sanity checks in most msg type parsers to catch invalid satypes
55370 + * and empty socket lists.
55371 + * Moved spin-locks in pfkey_get_parse() to simplify.
55372 + * Added pfkey_acquire().
55373 + * Added upwards messages to update, add, delete, acquire_parse,
55374 + * expire_parse and flush.
55375 + * Fix pfkey_prop_build() parameter to be only single indirection.
55376 + * Changed all replies to use pfkey_reply.
55377 + * Check return code on puttdb() and deltdbchain() in getspi, update,
55378 + * add, delete.
55379 + * Fixed up all pfkey replies to open and registered sockets.
55380 + *
55381 + * Revision 1.42 2000/09/01 18:50:26 rgb
55382 + * Added a supported algorithms array lists, one per satype and registered
55383 + * existing algorithms.
55384 + * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
55385 + * list.
55386 + * Only send pfkey_expire() messages to sockets registered for that satype.
55387 + * Added reply to pfkey_getspi_parse().
55388 + * Added reply to pfkey_get_parse().
55389 + * Fixed debug output label bug in pfkey_lifetime_process().
55390 + * Cleaned up pfkey_sa_process a little.
55391 + * Moved pfkey_safe_build() above message type parsers to make it available
55392 + * for creating replies.
55393 + * Added comments for future work in pfkey_acquire_parse().
55394 + * Fleshed out guts of pfkey_register_parse().
55395 + *
55396 + * Revision 1.41 2000/08/24 16:58:11 rgb
55397 + * Fixed key debugging variables.
55398 + * Fixed error return code for a failed search.
55399 + * Changed order of pfkey_get operations.
55400 + *
55401 + * Revision 1.40 2000/08/21 16:32:27 rgb
55402 + * Re-formatted for cosmetic consistency and readability.
55403 + *
55404 + * Revision 1.39 2000/08/20 21:38:57 rgb
55405 + * Bugfixes to as-yet-unused pfkey_update_parse() and
55406 + * pfkey_register_parse(). (Momchil)
55407 + * Added functions pfkey_safe_build(), pfkey_expire() and
55408 + * pfkey_build_reply(). (Momchil)
55409 + * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
55410 + *
55411 + * Revision 1.38 2000/08/18 21:30:41 rgb
55412 + * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
55413 + *
55414 + * Revision 1.37 2000/08/18 18:18:02 rgb
55415 + * Cosmetic and descriptive changes made to debug test.
55416 + * getspi and update fixes from Momchil.
55417 + *
55418 + * Revision 1.36 2000/08/15 15:41:55 rgb
55419 + * Fixed the (as yet unused and untested) pfkey_getspi() routine.
55420 + *
55421 + * Revision 1.35 2000/08/01 14:51:52 rgb
55422 + * Removed _all_ remaining traces of DES.
55423 + *
55424 + * Revision 1.34 2000/07/28 14:58:32 rgb
55425 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
55426 + *
55427 + * Revision 1.33 2000/06/28 05:50:11 rgb
55428 + * Actually set iv_bits.
55429 + *
55430 + * Revision 1.32 2000/05/30 18:36:56 rgb
55431 + * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY
55432 + * FreeS/WAN, but fixes interop with other implementations.
55433 + *
55434 + * Revision 1.31 2000/03/16 14:05:48 rgb
55435 + * Fixed brace scope preventing non-debug compile.
55436 + * Added null parameter check for pfkey_x_debug().
55437 + *
55438 + * Revision 1.30 2000/01/22 23:21:13 rgb
55439 + * Use new function satype2proto().
55440 + *
55441 + * Revision 1.29 2000/01/22 08:40:21 rgb
55442 + * Invert condition to known value to avoid AF_INET6 in 2.0.36.
55443 + *
55444 + * Revision 1.28 2000/01/22 07:58:57 rgb
55445 + * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
55446 + *
55447 + * Revision 1.27 2000/01/22 03:48:01 rgb
55448 + * Added extr pointer component debugging.
55449 + *
55450 + * Revision 1.26 2000/01/21 09:41:25 rgb
55451 + * Changed a (void*) to (char*) cast to do proper pointer math.
55452 + * Don't call tdbwipe if tdb2 is NULL.
55453 + *
55454 + * Revision 1.25 2000/01/21 06:21:01 rgb
55455 + * Added address cases for eroute flows.
55456 + * Tidied up compiler directive indentation for readability.
55457 + * Added ictx,octx vars for simplification.
55458 + * Added macros for HMAC padding magic numbers.
55459 + * Converted from double tdb arguments to one structure (extr)
55460 + * containing pointers to all temporary information structures
55461 + * and checking for valid arguments to all ext processors and
55462 + * msg type parsers.
55463 + * Added spiungrp'ing.
55464 + * Added klipsdebug switching capability.
55465 + * Removed sa_process() check for zero protocol.
55466 + * Added address case for DST2 for grouping.
55467 + * Added/changed minor debugging instrumentation.
55468 + * Fixed spigrp for single said, ungrouping case.
55469 + * Added code to parse addflow and delflow messages.
55470 + * Removed redundant statements duplicating tdbwipe() functionality
55471 + * and causing double kfrees.
55472 + * Permit addflow to have a protocol of 0.
55473 + *
55474 + * Revision 1.24 1999/12/09 23:23:00 rgb
55475 + * Added check to pfkey_sa_process() to do eroutes.
55476 + * Converted to DIVUP() macro.
55477 + * Converted if() to switch() in pfkey_register_parse().
55478 + * Use new pfkey_extensions_init() instead of memset().
55479 + *
55480 + * Revision 1.23 1999/12/01 22:18:13 rgb
55481 + * Preset minspi and maxspi values in case and spirange extension is not
55482 + * included and check for the presence of an spirange extension before
55483 + * using it. Initialise tdb_sastate to LARVAL.
55484 + * Fixed debugging output typo.
55485 + * Fixed authentication context initialisation bugs (4 places).
55486 + *
55487 + * Revision 1.22 1999/11/27 11:53:08 rgb
55488 + * Moved pfkey_msg_parse prototype to pfkey.h
55489 + * Moved exts_permitted/required prototype to pfkey.h.
55490 + * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
55491 + * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
55492 + * be called.
55493 + * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
55494 + * Debugging error messages added.
55495 + * Enable lifetime_current checking.
55496 + * Remove illegal requirement for SA extension to be present in an
55497 + * originating GETSPI call.
55498 + * Re-instate requirement for UPDATE or ADD message to be MATURE.
55499 + * Add argument to pfkey_msg_parse() for direction.
55500 + * Fixed IPIP dst address bug and purged redundant, leaky code.
55501 + *
55502 + * Revision 1.21 1999/11/24 05:24:20 rgb
55503 + * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
55504 + * Fixed indention.
55505 + * Ditched redundant replay check.
55506 + * Fixed debug message text from 'parse' to 'process'.
55507 + * Added more debug output.
55508 + * Forgot to zero extensions array causing bug, fixed.
55509 + *
55510 + * Revision 1.20 1999/11/23 23:08:13 rgb
55511 + * Move all common parsing code to lib/pfkey_v2_parse.c and rename
55512 + * remaining bits to *_process. (PJO)
55513 + * Add macros for dealing with alignment and rounding up more opaquely.
55514 + * Use provided macro ADDRTOA_BUF instead of hardcoded value.
55515 + * Sort out pfkey and freeswan headers, putting them in a library path.
55516 + * Corrected a couple of bugs in as-yet-inactive code.
55517 + *
55518 + * Revision 1.19 1999/11/20 22:01:10 rgb
55519 + * Add more descriptive error messages for non-zero reserved fields.
55520 + * Add more descriptive error message for spirange parsing.
55521 + * Start on supported extension parsing.
55522 + * Start on register and get message parsing.
55523 + *
55524 + * Revision 1.18 1999/11/18 04:09:20 rgb
55525 + * Replaced all kernel version macros to shorter, readable form.
55526 + *
55527 + * Revision 1.17 1999/11/17 15:53:41 rgb
55528 + * Changed all occurrences of #include "../../../lib/freeswan.h"
55529 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
55530 + * klips/net/ipsec/Makefile.
55531 + *
55532 + * Revision 1.16 1999/10/26 16:57:43 rgb
55533 + * Add shorter macros for compiler directives to visually clean-up.
55534 + * Give ipv6 code meaningful compiler directive.
55535 + * Add comments to other #if 0 debug code.
55536 + * Remove unused *_bh_atomic() calls.
55537 + * Fix mis-placed spinlock.
55538 + *
55539 + * Revision 1.15 1999/10/16 18:27:10 rgb
55540 + * Clean-up unused cruft.
55541 + * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
55542 + *
55543 + * Revision 1.14 1999/10/08 18:37:34 rgb
55544 + * Fix end-of-line spacing to sate whining PHMs.
55545 + *
55546 + * Revision 1.13 1999/10/03 18:49:12 rgb
55547 + * Spinlock fixes for 2.0.xx and 2.3.xx.
55548 + *
55549 + * Revision 1.12 1999/10/01 15:44:54 rgb
55550 + * Move spinlock header include to 2.1> scope.
55551 + *
55552 + * Revision 1.11 1999/10/01 00:05:45 rgb
55553 + * Added tdb structure locking.
55554 + * Use 'jiffies' instead of do_get_timeofday().
55555 + * Fix lifetime assignments.
55556 + *
55557 + * Revision 1.10 1999/09/21 15:24:45 rgb
55558 + * Rework spirange code to save entropy and prevent endless loops.
55559 + *
55560 + * Revision 1.9 1999/09/16 12:10:21 rgb
55561 + * Minor fixes to random spi selection for correctness and entropy conservation.
55562 + *
55563 + * Revision 1.8 1999/05/25 22:54:46 rgb
55564 + * Fix comparison that should be an assignment in an if.
55565 + *
55566 + * Revision 1.7 1999/05/09 03:25:37 rgb
55567 + * Fix bug introduced by 2.2 quick-and-dirty patch.
55568 + *
55569 + * Revision 1.6 1999/05/08 21:32:30 rgb
55570 + * Fix error return reporting.
55571 + *
55572 + * Revision 1.5 1999/05/05 22:02:33 rgb
55573 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
55574 + *
55575 + * Revision 1.4 1999/04/29 15:22:40 rgb
55576 + * Standardise an error return method.
55577 + * Add debugging instrumentation.
55578 + * Add check for existence of macros min/max.
55579 + * Add extensions permitted/required in/out filters.
55580 + * Add satype-to-protocol table.
55581 + * Add a second tdb pointer to each parser to accomodate GRPSA.
55582 + * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
55583 + * Add OOO window check.
55584 + * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
55585 + * Add timestamp to lifetime parse.
55586 + * Fix address structure length checking bug.
55587 + * Fix address structure allocation bug (forgot to kmalloc!).
55588 + * Add checks for extension lengths.
55589 + * Add checks for extension reserved illegal values.
55590 + * Add check for spirange legal values.
55591 + * Add an extension type for parsing a second satype, SA and
55592 + * DST_ADDRESS.
55593 + * Make changes to tdb_init() template to get pfkey_tdb_init(),
55594 + * eliminating any mention of xformsw.
55595 + * Implement getspi, update and grpsa (not tested).
55596 + * Add stubs for as yet unimplemented message types.
55597 + * Add table of message parsers to substitute for msg_parse switch.
55598 + *
55599 + * Revision 1.3 1999/04/15 17:58:07 rgb
55600 + * Add RCSID labels.
55601 + *
55602 + * Revision 1.2 1999/04/15 15:37:26 rgb
55603 + * Forward check changes from POST1_00 branch.
55604 + *
55605 + * Revision 1.1.2.1 1999/03/26 20:58:56 rgb
55606 + * Add pfkeyv2 support to KLIPS.
55607 + *
55608 + * Local variables:
55609 + * c-file-style: "linux"
55610 + * End:
55611 + *
55612 + */
55613 --- /dev/null Tue Mar 11 13:02:56 2003
55614 +++ linux/net/ipsec/prng.c Mon Feb 9 13:51:03 2004
55615 @@ -0,0 +1,201 @@
55616 +/*
55617 + * crypto-class pseudorandom number generator
55618 + * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
55619 + * Copyright (C) 2002 Henry Spencer.
55620 + *
55621 + * This library is free software; you can redistribute it and/or modify it
55622 + * under the terms of the GNU Library General Public License as published by
55623 + * the Free Software Foundation; either version 2 of the License, or (at your
55624 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
55625 + *
55626 + * This library is distributed in the hope that it will be useful, but
55627 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
55628 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
55629 + * License for more details.
55630 + *
55631 + * RCSID $Id: prng.c,v 1.7 2004/07/10 07:48:36 mcr Exp $
55632 + */
55633 +#include "openswan.h"
55634 +
55635 +/*
55636 + - prng_init - initialize PRNG from a key
55637 + */
55638 +void
55639 +prng_init(prng, key, keylen)
55640 +struct prng *prng;
55641 +const unsigned char *key;
55642 +size_t keylen;
55643 +{
55644 + unsigned char k[256];
55645 + int i, j;
55646 + unsigned const char *p;
55647 + unsigned const char *keyend = key + keylen;
55648 + unsigned char t;
55649 +
55650 + for (i = 0; i <= 255; i++)
55651 + prng->sbox[i] = i;
55652 + p = key;
55653 + for (i = 0; i <= 255; i++) {
55654 + k[i] = *p++;
55655 + if (p >= keyend)
55656 + p = key;
55657 + }
55658 + j = 0;
55659 + for (i = 0; i <= 255; i++) {
55660 + j = (j + prng->sbox[i] + k[i]) & 0xff;
55661 + t = prng->sbox[i];
55662 + prng->sbox[i] = prng->sbox[j];
55663 + prng->sbox[j] = t;
55664 + k[i] = 0; /* clear out key memory */
55665 + }
55666 + prng->i = 0;
55667 + prng->j = 0;
55668 + prng->count = 0;
55669 +}
55670 +
55671 +/*
55672 + - prng_bytes - get some pseudorandom bytes from PRNG
55673 + */
55674 +void
55675 +prng_bytes(prng, dst, dstlen)
55676 +struct prng *prng;
55677 +unsigned char *dst;
55678 +size_t dstlen;
55679 +{
55680 + int i, j, t;
55681 + unsigned char *p = dst;
55682 + size_t remain = dstlen;
55683 +# define MAX 4000000000ul
55684 +
55685 + while (remain > 0) {
55686 + i = (prng->i + 1) & 0xff;
55687 + prng->i = i;
55688 + j = (prng->j + prng->sbox[i]) & 0xff;
55689 + prng->j = j;
55690 + t = prng->sbox[i];
55691 + prng->sbox[i] = prng->sbox[j];
55692 + prng->sbox[j] = t;
55693 + t = (t + prng->sbox[i]) & 0xff;
55694 + *p++ = prng->sbox[t];
55695 + remain--;
55696 + }
55697 + if (prng->count < MAX - dstlen)
55698 + prng->count += dstlen;
55699 + else
55700 + prng->count = MAX;
55701 +}
55702 +
55703 +/*
55704 + - prnt_count - how many bytes have been extracted from PRNG so far?
55705 + */
55706 +unsigned long
55707 +prng_count(prng)
55708 +struct prng *prng;
55709 +{
55710 + return prng->count;
55711 +}
55712 +
55713 +/*
55714 + - prng_final - clear out PRNG to ensure nothing left in memory
55715 + */
55716 +void
55717 +prng_final(prng)
55718 +struct prng *prng;
55719 +{
55720 + int i;
55721 +
55722 + for (i = 0; i <= 255; i++)
55723 + prng->sbox[i] = 0;
55724 + prng->i = 0;
55725 + prng->j = 0;
55726 + prng->count = 0; /* just for good measure */
55727 +}
55728 +
55729 +
55730 +
55731 +#ifdef PRNG_MAIN
55732 +
55733 +#include <stdio.h>
55734 +
55735 +void regress();
55736 +
55737 +int
55738 +main(argc, argv)
55739 +int argc;
55740 +char *argv[];
55741 +{
55742 + struct prng pr;
55743 + unsigned char buf[100];
55744 + unsigned char *p;
55745 + size_t n;
55746 +
55747 + if (argc < 2) {
55748 + fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
55749 + exit(2);
55750 + }
55751 +
55752 + if (strcmp(argv[1], "-r") == 0) {
55753 + regress();
55754 + fprintf(stderr, "regress() returned?!?\n");
55755 + exit(1);
55756 + }
55757 +
55758 + prng_init(&pr, argv[1], strlen(argv[1]));
55759 + prng_bytes(&pr, buf, 32);
55760 + printf("0x");
55761 + for (p = buf, n = 32; n > 0; p++, n--)
55762 + printf("%02x", *p);
55763 + printf("\n%lu bytes\n", prng_count(&pr));
55764 + prng_final(&pr);
55765 + exit(0);
55766 +}
55767 +
55768 +void
55769 +regress()
55770 +{
55771 + struct prng pr;
55772 + unsigned char buf[100];
55773 + unsigned char *p;
55774 + size_t n;
55775 + /* somewhat non-random sample key */
55776 + unsigned char key[] = "here we go gathering nuts in May";
55777 + /* first thirty bytes of output from that key */
55778 + unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
55779 + "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
55780 + "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
55781 + int nzero, none;
55782 + int show = 0;
55783 +
55784 + prng_init(&pr, key, strlen(key));
55785 + prng_bytes(&pr, buf, sizeof(buf));
55786 + for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
55787 + if (*p == 0)
55788 + nzero++;
55789 + if (*p == 255)
55790 + none++;
55791 + }
55792 + if (nzero > 3 || none > 3) {
55793 + fprintf(stderr, "suspiciously non-random output!\n");
55794 + show = 1;
55795 + }
55796 + if (memcmp(buf, good, strlen(good)) != 0) {
55797 + fprintf(stderr, "incorrect output!\n");
55798 + show = 1;
55799 + }
55800 + if (show) {
55801 + fprintf(stderr, "0x");
55802 + for (p = buf, n = sizeof(buf); n > 0; p++, n--)
55803 + fprintf(stderr, "%02x", *p);
55804 + fprintf(stderr, "\n");
55805 + exit(1);
55806 + }
55807 + if (prng_count(&pr) != sizeof(buf)) {
55808 + fprintf(stderr, "got %u bytes, but count is %lu\n",
55809 + sizeof(buf), prng_count(&pr));
55810 + exit(1);
55811 + }
55812 + prng_final(&pr);
55813 + exit(0);
55814 +}
55815 +
55816 +#endif /* PRNG_MAIN */
55817 --- /dev/null Tue Mar 11 13:02:56 2003
55818 +++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004
55819 @@ -0,0 +1,1237 @@
55820 +char radij_c_version[] = "RCSID $Id: radij.c,v 1.48.2.1 2006/10/06 21:39:27 paul Exp $";
55821 +
55822 +/*
55823 + * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
55824 + *
55825 + * Variable and procedure names have been modified so that they don't
55826 + * conflict with the original BSD code, as a small number of modifications
55827 + * have been introduced and we may want to reuse this code in BSD.
55828 + *
55829 + * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
55830 + * chi or a German ch sound (as `doch', not as in `milch'), or even a
55831 + * spanish j as in Juan. It is not as far back in the throat like
55832 + * the corresponding Hebrew sound, nor is it a soft breath like the English h.
55833 + * It has nothing to do with the Dutch ij sound.
55834 + *
55835 + * Here is the appropriate copyright notice:
55836 + */
55837 +
55838 +/*
55839 + * Copyright (c) 1988, 1989, 1993
55840 + * The Regents of the University of California. All rights reserved.
55841 + *
55842 + * Redistribution and use in source and binary forms, with or without
55843 + * modification, are permitted provided that the following conditions
55844 + * are met:
55845 + * 1. Redistributions of source code must retain the above copyright
55846 + * notice, this list of conditions and the following disclaimer.
55847 + * 2. Redistributions in binary form must reproduce the above copyright
55848 + * notice, this list of conditions and the following disclaimer in the
55849 + * documentation and/or other materials provided with the distribution.
55850 + * 3. All advertising materials mentioning features or use of this software
55851 + * must display the following acknowledgement:
55852 + * This product includes software developed by the University of
55853 + * California, Berkeley and its contributors.
55854 + * 4. Neither the name of the University nor the names of its contributors
55855 + * may be used to endorse or promote products derived from this software
55856 + * without specific prior written permission.
55857 + *
55858 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
55859 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55860 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55861 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55862 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55863 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55864 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55865 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55866 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55867 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55868 + * SUCH DAMAGE.
55869 + *
55870 + * @(#)radix.c 8.2 (Berkeley) 1/4/94
55871 + */
55872 +
55873 +/*
55874 + * Routines to build and maintain radix trees for routing lookups.
55875 + */
55876 +
55877 +#ifndef AUTOCONF_INCLUDED
55878 +#include <linux/config.h>
55879 +#endif
55880 +#include <linux/version.h>
55881 +#include <linux/kernel.h> /* printk() */
55882 +
55883 +#include "openswan/ipsec_param.h"
55884 +
55885 +#ifdef MALLOC_SLAB
55886 +# include <linux/slab.h> /* kmalloc() */
55887 +#else /* MALLOC_SLAB */
55888 +# include <linux/malloc.h> /* kmalloc() */
55889 +#endif /* MALLOC_SLAB */
55890 +#include <linux/errno.h> /* error codes */
55891 +#include <linux/types.h> /* size_t */
55892 +#include <linux/interrupt.h> /* mark_bh */
55893 +
55894 +#include <linux/netdevice.h> /* struct device, and other headers */
55895 +#include <linux/etherdevice.h> /* eth_type_trans */
55896 +#include <linux/ip.h> /* struct iphdr */
55897 +#include <linux/skbuff.h>
55898 +#ifdef NET_21
55899 +# include <linux/in6.h>
55900 +#endif /* NET_21 */
55901 +
55902 +#include <net/ip.h>
55903 +
55904 +#include <openswan.h>
55905 +
55906 +#include "openswan/radij.h"
55907 +#include "openswan/ipsec_encap.h"
55908 +#include "openswan/ipsec_radij.h"
55909 +
55910 +int maj_keylen;
55911 +struct radij_mask *rj_mkfreelist;
55912 +struct radij_node_head *mask_rjhead;
55913 +static int gotOddMasks;
55914 +static char *maskedKey;
55915 +static char *rj_zeroes, *rj_ones;
55916 +
55917 +#define rj_masktop (mask_rjhead->rnh_treetop)
55918 +#ifdef Bcmp
55919 +# undef Bcmp
55920 +#endif /* Bcmp */
55921 +#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
55922 +/*
55923 + * The data structure for the keys is a radix tree with one way
55924 + * branching removed. The index rj_b at an internal node n represents a bit
55925 + * position to be tested. The tree is arranged so that all descendants
55926 + * of a node n have keys whose bits all agree up to position rj_b - 1.
55927 + * (We say the index of n is rj_b.)
55928 + *
55929 + * There is at least one descendant which has a one bit at position rj_b,
55930 + * and at least one with a zero there.
55931 + *
55932 + * A route is determined by a pair of key and mask. We require that the
55933 + * bit-wise logical and of the key and mask to be the key.
55934 + * We define the index of a route to associated with the mask to be
55935 + * the first bit number in the mask where 0 occurs (with bit number 0
55936 + * representing the highest order bit).
55937 + *
55938 + * We say a mask is normal if every bit is 0, past the index of the mask.
55939 + * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
55940 + * and m is a normal mask, then the route applies to every descendant of n.
55941 + * If the index(m) < rj_b, this implies the trailing last few bits of k
55942 + * before bit b are all 0, (and hence consequently true of every descendant
55943 + * of n), so the route applies to all descendants of the node as well.
55944 + *
55945 + * The present version of the code makes no use of normal routes,
55946 + * but similar logic shows that a non-normal mask m such that
55947 + * index(m) <= index(n) could potentially apply to many children of n.
55948 + * Thus, for each non-host route, we attach its mask to a list at an internal
55949 + * node as high in the tree as we can go.
55950 + */
55951 +
55952 +struct radij_node *
55953 +rj_search(v_arg, head)
55954 + void *v_arg;
55955 + struct radij_node *head;
55956 +{
55957 + register struct radij_node *x;
55958 + register caddr_t v;
55959 +
55960 + for (x = head, v = v_arg; x->rj_b >= 0;) {
55961 + if (x->rj_bmask & v[x->rj_off])
55962 + x = x->rj_r;
55963 + else
55964 + x = x->rj_l;
55965 + }
55966 + return (x);
55967 +};
55968 +
55969 +struct radij_node *
55970 +rj_search_m(v_arg, head, m_arg)
55971 + struct radij_node *head;
55972 + void *v_arg, *m_arg;
55973 +{
55974 + register struct radij_node *x;
55975 + register caddr_t v = v_arg, m = m_arg;
55976 +
55977 + for (x = head; x->rj_b >= 0;) {
55978 + if ((x->rj_bmask & m[x->rj_off]) &&
55979 + (x->rj_bmask & v[x->rj_off]))
55980 + x = x->rj_r;
55981 + else
55982 + x = x->rj_l;
55983 + }
55984 + return x;
55985 +};
55986 +
55987 +int
55988 +rj_refines(m_arg, n_arg)
55989 + void *m_arg, *n_arg;
55990 +{
55991 + register caddr_t m = m_arg, n = n_arg;
55992 + register caddr_t lim, lim2 = lim = n + *(u_char *)n;
55993 + int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
55994 + int masks_are_equal = 1;
55995 +
55996 + if (longer > 0)
55997 + lim -= longer;
55998 + while (n < lim) {
55999 + if (*n & ~(*m))
56000 + return 0;
56001 + if (*n++ != *m++)
56002 + masks_are_equal = 0;
56003 +
56004 + }
56005 + while (n < lim2)
56006 + if (*n++)
56007 + return 0;
56008 + if (masks_are_equal && (longer < 0))
56009 + for (lim2 = m - longer; m < lim2; )
56010 + if (*m++)
56011 + return 1;
56012 + return (!masks_are_equal);
56013 +}
56014 +
56015 +
56016 +struct radij_node *
56017 +rj_match(v_arg, head)
56018 + void *v_arg;
56019 + struct radij_node_head *head;
56020 +{
56021 + caddr_t v = v_arg;
56022 + register struct radij_node *t = head->rnh_treetop, *x;
56023 + register caddr_t cp = v, cp2, cp3;
56024 + caddr_t cplim, mstart;
56025 + struct radij_node *saved_t, *top = t;
56026 + int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
56027 +
56028 + /*
56029 + * Open code rj_search(v, top) to avoid overhead of extra
56030 + * subroutine call.
56031 + */
56032 + for (; t->rj_b >= 0; ) {
56033 + if (t->rj_bmask & cp[t->rj_off])
56034 + t = t->rj_r;
56035 + else
56036 + t = t->rj_l;
56037 + }
56038 + /*
56039 + * See if we match exactly as a host destination
56040 + */
56041 + KLIPS_PRINT(debug_radij,
56042 + "klips_debug:rj_match: "
56043 + "* See if we match exactly as a host destination\n");
56044 +
56045 + cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
56046 + for (; cp < cplim; cp++, cp2++)
56047 + if (*cp != *cp2)
56048 + goto on1;
56049 + /*
56050 + * This extra grot is in case we are explicitly asked
56051 + * to look up the default. Ugh!
56052 + */
56053 + if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
56054 + t = t->rj_dupedkey;
56055 + return t;
56056 +on1:
56057 + matched_off = cp - v;
56058 + saved_t = t;
56059 + KLIPS_PRINT(debug_radij,
56060 + "klips_debug:rj_match: "
56061 + "** try to match a leaf, t=0p%p\n", t);
56062 + do {
56063 + if (t->rj_mask) {
56064 + /*
56065 + * Even if we don't match exactly as a hosts;
56066 + * we may match if the leaf we wound up at is
56067 + * a route to a net.
56068 + */
56069 + cp3 = matched_off + t->rj_mask;
56070 + cp2 = matched_off + t->rj_key;
56071 + for (; cp < cplim; cp++)
56072 + if ((*cp2++ ^ *cp) & *cp3++)
56073 + break;
56074 + if (cp == cplim)
56075 + return t;
56076 + cp = matched_off + v;
56077 + }
56078 + } while ((t = t->rj_dupedkey));
56079 + t = saved_t;
56080 + /* start searching up the tree */
56081 + KLIPS_PRINT(debug_radij,
56082 + "klips_debug:rj_match: "
56083 + "*** start searching up the tree, t=0p%p\n",
56084 + t);
56085 + do {
56086 + register struct radij_mask *m;
56087 +
56088 + t = t->rj_p;
56089 + KLIPS_PRINT(debug_radij,
56090 + "klips_debug:rj_match: "
56091 + "**** t=0p%p\n",
56092 + t);
56093 + if ((m = t->rj_mklist)) {
56094 + /*
56095 + * After doing measurements here, it may
56096 + * turn out to be faster to open code
56097 + * rj_search_m here instead of always
56098 + * copying and masking.
56099 + */
56100 + /* off = min(t->rj_off, matched_off); */
56101 + off = t->rj_off;
56102 + if (matched_off < off)
56103 + off = matched_off;
56104 + mstart = maskedKey + off;
56105 + do {
56106 + cp2 = mstart;
56107 + cp3 = m->rm_mask + off;
56108 + KLIPS_PRINT(debug_radij,
56109 + "klips_debug:rj_match: "
56110 + "***** cp2=0p%p cp3=0p%p\n",
56111 + cp2, cp3);
56112 + for (cp = v + off; cp < cplim;)
56113 + *cp2++ = *cp++ & *cp3++;
56114 + x = rj_search(maskedKey, t);
56115 + while (x && x->rj_mask != m->rm_mask)
56116 + x = x->rj_dupedkey;
56117 + if (x &&
56118 + (Bcmp(mstart, x->rj_key + off,
56119 + vlen - off) == 0))
56120 + return x;
56121 + } while ((m = m->rm_mklist));
56122 + }
56123 + } while (t != top);
56124 + KLIPS_PRINT(debug_radij,
56125 + "klips_debug:rj_match: "
56126 + "***** not found.\n");
56127 + return 0;
56128 +};
56129 +
56130 +#ifdef RJ_DEBUG
56131 +int rj_nodenum;
56132 +struct radij_node *rj_clist;
56133 +int rj_saveinfo;
56134 +DEBUG_NO_STATIC void traverse(struct radij_node *);
56135 +#ifdef RJ_DEBUG2
56136 +int rj_debug = 1;
56137 +#else
56138 +int rj_debug = 0;
56139 +#endif /* RJ_DEBUG2 */
56140 +#endif /* RJ_DEBUG */
56141 +
56142 +struct radij_node *
56143 +rj_newpair(v, b, nodes)
56144 + void *v;
56145 + int b;
56146 + struct radij_node nodes[2];
56147 +{
56148 + register struct radij_node *tt = nodes, *t = tt + 1;
56149 + t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
56150 + t->rj_l = tt; t->rj_off = b >> 3;
56151 + tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
56152 + tt->rj_flags = t->rj_flags = RJF_ACTIVE;
56153 +#ifdef RJ_DEBUG
56154 + tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
56155 + tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
56156 +#endif /* RJ_DEBUG */
56157 + return t;
56158 +}
56159 +
56160 +struct radij_node *
56161 +rj_insert(v_arg, head, dupentry, nodes)
56162 + void *v_arg;
56163 + struct radij_node_head *head;
56164 + int *dupentry;
56165 + struct radij_node nodes[2];
56166 +{
56167 + caddr_t v = v_arg;
56168 + struct radij_node *top = head->rnh_treetop;
56169 + int head_off = top->rj_off, vlen = (int)*((u_char *)v);
56170 + register struct radij_node *t = rj_search(v_arg, top);
56171 + register caddr_t cp = v + head_off;
56172 + register int b;
56173 + struct radij_node *tt;
56174 + /*
56175 + *find first bit at which v and t->rj_key differ
56176 + */
56177 + {
56178 + register caddr_t cp2 = t->rj_key + head_off;
56179 + register int cmp_res;
56180 + caddr_t cplim = v + vlen;
56181 +
56182 + while (cp < cplim)
56183 + if (*cp2++ != *cp++)
56184 + goto on1;
56185 + *dupentry = 1;
56186 + return t;
56187 +on1:
56188 + *dupentry = 0;
56189 + cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
56190 + for (b = (cp - v) << 3; cmp_res; b--)
56191 + cmp_res >>= 1;
56192 + }
56193 + {
56194 + register struct radij_node *p, *x = top;
56195 + cp = v;
56196 + do {
56197 + p = x;
56198 + if (cp[x->rj_off] & x->rj_bmask)
56199 + x = x->rj_r;
56200 + else x = x->rj_l;
56201 + } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
56202 +#ifdef RJ_DEBUG
56203 + if (rj_debug)
56204 + printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
56205 +#endif /* RJ_DEBUG */
56206 + t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
56207 + if ((cp[p->rj_off] & p->rj_bmask) == 0)
56208 + p->rj_l = t;
56209 + else
56210 + p->rj_r = t;
56211 + x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
56212 + if ((cp[t->rj_off] & t->rj_bmask) == 0) {
56213 + t->rj_r = x;
56214 + } else {
56215 + t->rj_r = tt; t->rj_l = x;
56216 + }
56217 +#ifdef RJ_DEBUG
56218 + if (rj_debug)
56219 + printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
56220 +#endif /* RJ_DEBUG */
56221 + }
56222 + return (tt);
56223 +}
56224 +
56225 +struct radij_node *
56226 +rj_addmask(n_arg, search, skip)
56227 + int search, skip;
56228 + void *n_arg;
56229 +{
56230 + caddr_t netmask = (caddr_t)n_arg;
56231 + register struct radij_node *x;
56232 + register caddr_t cp, cplim;
56233 + register int b, mlen, j;
56234 + int maskduplicated;
56235 +
56236 + mlen = *(u_char *)netmask;
56237 + if (search) {
56238 + x = rj_search(netmask, rj_masktop);
56239 + mlen = *(u_char *)netmask;
56240 + if (Bcmp(netmask, x->rj_key, mlen) == 0)
56241 + return (x);
56242 + }
56243 + R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
56244 + if (x == 0)
56245 + return (0);
56246 + Bzero(x, maj_keylen + 2 * sizeof (*x));
56247 + cp = (caddr_t)(x + 2);
56248 + Bcopy(netmask, cp, mlen);
56249 + netmask = cp;
56250 + x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
56251 + /*
56252 + * Calculate index of mask.
56253 + */
56254 + cplim = netmask + mlen;
56255 + for (cp = netmask + skip; cp < cplim; cp++)
56256 + if (*(u_char *)cp != 0xff)
56257 + break;
56258 + b = (cp - netmask) << 3;
56259 + if (cp != cplim) {
56260 + if (*cp != 0) {
56261 + gotOddMasks = 1;
56262 + for (j = 0x80; j; b++, j >>= 1)
56263 + if ((j & *cp) == 0)
56264 + break;
56265 + }
56266 + }
56267 + x->rj_b = -1 - b;
56268 + return (x);
56269 +}
56270 +
56271 +#if 0
56272 +struct radij_node *
56273 +#endif
56274 +int
56275 +rj_addroute(v_arg, n_arg, head, treenodes)
56276 + void *v_arg, *n_arg;
56277 + struct radij_node_head *head;
56278 + struct radij_node treenodes[2];
56279 +{
56280 + caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
56281 + register struct radij_node *t, *x=NULL, *tt;
56282 + struct radij_node *saved_tt, *top = head->rnh_treetop;
56283 + short b = 0, b_leaf;
56284 + int mlen, keyduplicated;
56285 + caddr_t cplim;
56286 + struct radij_mask *m, **mp;
56287 +
56288 + /*
56289 + * In dealing with non-contiguous masks, there may be
56290 + * many different routes which have the same mask.
56291 + * We will find it useful to have a unique pointer to
56292 + * the mask to speed avoiding duplicate references at
56293 + * nodes and possibly save time in calculating indices.
56294 + */
56295 + if (netmask) {
56296 + x = rj_search(netmask, rj_masktop);
56297 + mlen = *(u_char *)netmask;
56298 + if (Bcmp(netmask, x->rj_key, mlen) != 0) {
56299 + x = rj_addmask(netmask, 0, top->rj_off);
56300 + if (x == 0)
56301 + return -ENOMEM; /* (0) rgb */
56302 + }
56303 + netmask = x->rj_key;
56304 + b = -1 - x->rj_b;
56305 + }
56306 + /*
56307 + * Deal with duplicated keys: attach node to previous instance
56308 + */
56309 + saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
56310 +#ifdef RJ_DEBUG
56311 + printk("addkey: duplicated: %d\n", keyduplicated);
56312 +#endif
56313 + if (keyduplicated) {
56314 + do {
56315 + if (tt->rj_mask == netmask)
56316 + return -EEXIST; /* -ENXIO; (0) rgb */
56317 + t = tt;
56318 + if (netmask == 0 ||
56319 + (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
56320 + break;
56321 + } while ((tt = tt->rj_dupedkey));
56322 + /*
56323 + * If the mask is not duplicated, we wouldn't
56324 + * find it among possible duplicate key entries
56325 + * anyway, so the above test doesn't hurt.
56326 + *
56327 + * We sort the masks for a duplicated key the same way as
56328 + * in a masklist -- most specific to least specific.
56329 + * This may require the unfortunate nuisance of relocating
56330 + * the head of the list.
56331 + */
56332 + if (tt && t == saved_tt) {
56333 + struct radij_node *xx = x;
56334 + /* link in at head of list */
56335 + (tt = treenodes)->rj_dupedkey = t;
56336 + tt->rj_flags = t->rj_flags;
56337 + tt->rj_p = x = t->rj_p;
56338 + if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
56339 + saved_tt = tt; x = xx;
56340 + } else {
56341 + (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
56342 + t->rj_dupedkey = tt;
56343 + }
56344 +#ifdef RJ_DEBUG
56345 + t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
56346 + tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
56347 +#endif /* RJ_DEBUG */
56348 + t = saved_tt;
56349 + tt->rj_key = (caddr_t) v;
56350 + tt->rj_b = -1;
56351 + tt->rj_flags = t->rj_flags & ~RJF_ROOT;
56352 + }
56353 + /*
56354 + * Put mask in tree.
56355 + */
56356 + if (netmask) {
56357 + tt->rj_mask = netmask;
56358 + tt->rj_b = x->rj_b;
56359 + }
56360 + t = saved_tt->rj_p;
56361 + b_leaf = -1 - t->rj_b;
56362 + if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
56363 + /* Promote general routes from below */
56364 + if (x->rj_b < 0) {
56365 + if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
56366 + MKGet(m);
56367 + if (m) {
56368 + Bzero(m, sizeof *m);
56369 + m->rm_b = x->rj_b;
56370 + m->rm_mask = x->rj_mask;
56371 + x->rj_mklist = t->rj_mklist = m;
56372 + }
56373 + }
56374 + } else if (x->rj_mklist) {
56375 + /*
56376 + * Skip over masks whose index is > that of new node
56377 + */
56378 + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
56379 + if (m->rm_b >= b_leaf)
56380 + break;
56381 + t->rj_mklist = m; *mp = 0;
56382 + }
56383 + /* Add new route to highest possible ancestor's list */
56384 + if ((netmask == 0) || (b > t->rj_b )) {
56385 +#ifdef RJ_DEBUG
56386 + printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b);
56387 +#endif
56388 + return 0; /* tt rgb */ /* can't lift at all */
56389 + }
56390 + b_leaf = tt->rj_b;
56391 + do {
56392 + x = t;
56393 + t = t->rj_p;
56394 + } while (b <= t->rj_b && x != top);
56395 + /*
56396 + * Search through routes associated with node to
56397 + * insert new route according to index.
56398 + * For nodes of equal index, place more specific
56399 + * masks first.
56400 + */
56401 + cplim = netmask + mlen;
56402 + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
56403 + if (m->rm_b < b_leaf)
56404 + continue;
56405 + if (m->rm_b > b_leaf)
56406 + break;
56407 + if (m->rm_mask == netmask) {
56408 + m->rm_refs++;
56409 + tt->rj_mklist = m;
56410 +#ifdef RJ_DEBUG
56411 + printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask);
56412 +#endif
56413 + return 0; /* tt rgb */
56414 + }
56415 + if (rj_refines(netmask, m->rm_mask))
56416 + break;
56417 + }
56418 + MKGet(m);
56419 + if (m == 0) {
56420 + printk("klips_debug:rj_addroute: "
56421 + "Mask for route not entered\n");
56422 + return 0; /* (tt) rgb */
56423 + }
56424 + Bzero(m, sizeof *m);
56425 + m->rm_b = b_leaf;
56426 + m->rm_mask = netmask;
56427 + m->rm_mklist = *mp;
56428 + *mp = m;
56429 + tt->rj_mklist = m;
56430 +#ifdef RJ_DEBUG
56431 + printk("klips:radij.c: addroute done\n");
56432 +#endif
56433 + return 0; /* tt rgb */
56434 +}
56435 +
56436 +int
56437 +rj_delete(v_arg, netmask_arg, head, node)
56438 + void *v_arg, *netmask_arg;
56439 + struct radij_node_head *head;
56440 + struct radij_node **node;
56441 +{
56442 + register struct radij_node *t, *p, *x, *tt;
56443 + struct radij_mask *m, *saved_m, **mp;
56444 + struct radij_node *dupedkey, *saved_tt, *top;
56445 + caddr_t v, netmask;
56446 + int b, head_off, vlen;
56447 +
56448 + v = v_arg;
56449 + netmask = netmask_arg;
56450 + x = head->rnh_treetop;
56451 + tt = rj_search(v, x);
56452 + head_off = x->rj_off;
56453 + vlen = *(u_char *)v;
56454 + saved_tt = tt;
56455 + top = x;
56456 + if (tt == 0 ||
56457 + Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
56458 + return -EFAULT; /* (0) rgb */
56459 + /*
56460 + * Delete our route from mask lists.
56461 + */
56462 + if ((dupedkey = tt->rj_dupedkey)) {
56463 + if (netmask)
56464 + netmask = rj_search(netmask, rj_masktop)->rj_key;
56465 + while (tt->rj_mask != netmask)
56466 + if ((tt = tt->rj_dupedkey) == 0)
56467 + return -ENOENT; /* -ENXIO; (0) rgb */
56468 + }
56469 + if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
56470 + goto on1;
56471 + if (m->rm_mask != tt->rj_mask) {
56472 + printk("klips_debug:rj_delete: "
56473 + "inconsistent annotation\n");
56474 + goto on1;
56475 + }
56476 + if (--m->rm_refs >= 0)
56477 + goto on1;
56478 + b = -1 - tt->rj_b;
56479 + t = saved_tt->rj_p;
56480 + if (b > t->rj_b)
56481 + goto on1; /* Wasn't lifted at all */
56482 + do {
56483 + x = t;
56484 + t = t->rj_p;
56485 + } while (b <= t->rj_b && x != top);
56486 + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
56487 + if (m == saved_m) {
56488 + *mp = m->rm_mklist;
56489 + MKFree(m);
56490 + break;
56491 + }
56492 + if (m == 0)
56493 + printk("klips_debug:rj_delete: "
56494 + "couldn't find our annotation\n");
56495 +on1:
56496 + /*
56497 + * Eliminate us from tree
56498 + */
56499 + if (tt->rj_flags & RJF_ROOT)
56500 + return -EFAULT; /* (0) rgb */
56501 +#ifdef RJ_DEBUG
56502 + /* Get us out of the creation list */
56503 + for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
56504 + if (t) t->rj_ybro = tt->rj_ybro;
56505 +#endif /* RJ_DEBUG */
56506 + t = tt->rj_p;
56507 + if (dupedkey) {
56508 + if (tt == saved_tt) {
56509 + x = dupedkey; x->rj_p = t;
56510 + if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
56511 + } else {
56512 + for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
56513 + p = p->rj_dupedkey;
56514 + if (p) p->rj_dupedkey = tt->rj_dupedkey;
56515 + else printk("klips_debug:rj_delete: "
56516 + "couldn't find node that we started with\n");
56517 + }
56518 + t = tt + 1;
56519 + if (t->rj_flags & RJF_ACTIVE) {
56520 +#ifndef RJ_DEBUG
56521 + *++x = *t; p = t->rj_p;
56522 +#else
56523 + b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
56524 +#endif /* RJ_DEBUG */
56525 + if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
56526 + x->rj_l->rj_p = x; x->rj_r->rj_p = x;
56527 + }
56528 + goto out;
56529 + }
56530 + if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
56531 + p = t->rj_p;
56532 + if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
56533 + x->rj_p = p;
56534 + /*
56535 + * Demote routes attached to us.
56536 + */
56537 + if (t->rj_mklist) {
56538 + if (x->rj_b >= 0) {
56539 + for (mp = &x->rj_mklist; (m = *mp);)
56540 + mp = &m->rm_mklist;
56541 + *mp = t->rj_mklist;
56542 + } else {
56543 + for (m = t->rj_mklist; m;) {
56544 + struct radij_mask *mm = m->rm_mklist;
56545 + if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
56546 + x->rj_mklist = 0;
56547 + MKFree(m);
56548 + } else
56549 + printk("klips_debug:rj_delete: "
56550 + "Orphaned Mask 0p%p at 0p%p\n", m, x);
56551 + m = mm;
56552 + }
56553 + }
56554 + }
56555 + /*
56556 + * We may be holding an active internal node in the tree.
56557 + */
56558 + x = tt + 1;
56559 + if (t != x) {
56560 +#ifndef RJ_DEBUG
56561 + *t = *x;
56562 +#else
56563 + b = t->rj_info; *t = *x; t->rj_info = b;
56564 +#endif /* RJ_DEBUG */
56565 + t->rj_l->rj_p = t; t->rj_r->rj_p = t;
56566 + p = x->rj_p;
56567 + if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
56568 + }
56569 +out:
56570 + tt->rj_flags &= ~RJF_ACTIVE;
56571 + tt[1].rj_flags &= ~RJF_ACTIVE;
56572 + *node = tt;
56573 + return 0; /* (tt) rgb */
56574 +}
56575 +
56576 +int
56577 +rj_walktree(h, f, w)
56578 + struct radij_node_head *h;
56579 + register int (*f)(struct radij_node *,void *);
56580 + void *w;
56581 +{
56582 + int error;
56583 + struct radij_node *base, *next;
56584 + register struct radij_node *rn;
56585 +
56586 + if(!h || !f /* || !w */) {
56587 + return -ENODATA;
56588 + }
56589 +
56590 + rn = h->rnh_treetop;
56591 + /*
56592 + * This gets complicated because we may delete the node
56593 + * while applying the function f to it, so we need to calculate
56594 + * the successor node in advance.
56595 + */
56596 + /* First time through node, go left */
56597 + while (rn->rj_b >= 0)
56598 + rn = rn->rj_l;
56599 + for (;;) {
56600 +#ifdef CONFIG_KLIPS_DEBUG
56601 + if(debug_radij) {
56602 + printk("klips_debug:rj_walktree: "
56603 + "for: rn=0p%p rj_b=%d rj_flags=%x",
56604 + rn,
56605 + rn->rj_b,
56606 + rn->rj_flags);
56607 + rn->rj_b >= 0 ?
56608 + printk(" node off=%x\n",
56609 + rn->rj_off) :
56610 + printk(" leaf key = %08x->%08x\n",
56611 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56612 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56613 + ;
56614 + }
56615 +#endif /* CONFIG_KLIPS_DEBUG */
56616 + base = rn;
56617 + /* If at right child go back up, otherwise, go right */
56618 + while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
56619 + rn = rn->rj_p;
56620 + /* Find the next *leaf* since next node might vanish, too */
56621 + for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
56622 + rn = rn->rj_l;
56623 + next = rn;
56624 +#ifdef CONFIG_KLIPS_DEBUG
56625 + if(debug_radij) {
56626 + printk("klips_debug:rj_walktree: "
56627 + "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
56628 + rn,
56629 + rn->rj_b,
56630 + rn->rj_flags);
56631 + rn->rj_b >= 0 ?
56632 + printk(" node off=%x\n",
56633 + rn->rj_off) :
56634 + printk(" leaf key = %08x->%08x\n",
56635 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56636 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56637 + ;
56638 + }
56639 +#endif /* CONFIG_KLIPS_DEBUG */
56640 + /* Process leaves */
56641 + while ((rn = base)) {
56642 + base = rn->rj_dupedkey;
56643 +#ifdef CONFIG_KLIPS_DEBUG
56644 + if(debug_radij) {
56645 + printk("klips_debug:rj_walktree: "
56646 + "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
56647 + base,
56648 + rn,
56649 + rn->rj_b,
56650 + rn->rj_flags);
56651 + rn->rj_b >= 0 ?
56652 + printk(" node off=%x\n",
56653 + rn->rj_off) :
56654 + printk(" leaf key = %08x->%08x\n",
56655 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56656 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
56657 + ;
56658 + }
56659 +#endif /* CONFIG_KLIPS_DEBUG */
56660 + if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
56661 + return (-error);
56662 + }
56663 + rn = next;
56664 + if (rn->rj_flags & RJF_ROOT)
56665 + return (0);
56666 + }
56667 + /* NOTREACHED */
56668 +}
56669 +
56670 +int
56671 +rj_inithead(head, off)
56672 + void **head;
56673 + int off;
56674 +{
56675 + register struct radij_node_head *rnh;
56676 + register struct radij_node *t, *tt, *ttt;
56677 + if (*head)
56678 + return (1);
56679 + R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
56680 + if (rnh == NULL)
56681 + return (0);
56682 + Bzero(rnh, sizeof (*rnh));
56683 + *head = rnh;
56684 + t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
56685 + ttt = rnh->rnh_nodes + 2;
56686 + t->rj_r = ttt;
56687 + t->rj_p = t;
56688 + tt = t->rj_l;
56689 + tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
56690 + tt->rj_b = -1 - off;
56691 + *ttt = *tt;
56692 + ttt->rj_key = rj_ones;
56693 + rnh->rnh_addaddr = rj_addroute;
56694 + rnh->rnh_deladdr = rj_delete;
56695 + rnh->rnh_matchaddr = rj_match;
56696 + rnh->rnh_walktree = rj_walktree;
56697 + rnh->rnh_treetop = t;
56698 + return (1);
56699 +}
56700 +
56701 +void
56702 +rj_init()
56703 +{
56704 + char *cp, *cplim;
56705 +
56706 + if (maj_keylen == 0) {
56707 + printk("klips_debug:rj_init: "
56708 + "radij functions require maj_keylen be set\n");
56709 + return;
56710 + }
56711 + R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
56712 + if (rj_zeroes == NULL)
56713 + panic("rj_init");
56714 + Bzero(rj_zeroes, 3 * maj_keylen);
56715 + rj_ones = cp = rj_zeroes + maj_keylen;
56716 + maskedKey = cplim = rj_ones + maj_keylen;
56717 + while (cp < cplim)
56718 + *cp++ = -1;
56719 + if (rj_inithead((void **)&mask_rjhead, 0) == 0)
56720 + panic("rj_init 2");
56721 +}
56722 +
56723 +void
56724 +rj_preorder(struct radij_node *rn, int l)
56725 +{
56726 + int i;
56727 +
56728 + if (rn == NULL){
56729 + printk("klips_debug:rj_preorder: "
56730 + "NULL pointer\n");
56731 + return;
56732 + }
56733 +
56734 + if (rn->rj_b >= 0){
56735 + rj_preorder(rn->rj_l, l+1);
56736 + rj_preorder(rn->rj_r, l+1);
56737 + printk("klips_debug:");
56738 + for (i=0; i<l; i++)
56739 + printk("*");
56740 + printk(" off = %d\n",
56741 + rn->rj_off);
56742 + } else {
56743 + printk("klips_debug:");
56744 + for (i=0; i<l; i++)
56745 + printk("@");
56746 + printk(" flags = %x",
56747 + (u_int)rn->rj_flags);
56748 + if (rn->rj_flags & RJF_ACTIVE) {
56749 + printk(" @key=0p%p",
56750 + rn->rj_key);
56751 + printk(" key = %08x->%08x",
56752 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
56753 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
56754 + printk(" @mask=0p%p",
56755 + rn->rj_mask);
56756 + if (rn->rj_mask)
56757 + printk(" mask = %08x->%08x",
56758 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
56759 + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
56760 + if (rn->rj_dupedkey)
56761 + printk(" dupedkey = 0p%p",
56762 + rn->rj_dupedkey);
56763 + }
56764 + printk("\n");
56765 + }
56766 +}
56767 +
56768 +#ifdef RJ_DEBUG
56769 +DEBUG_NO_STATIC void traverse(struct radij_node *p)
56770 +{
56771 + rj_preorder(p, 0);
56772 +}
56773 +#endif /* RJ_DEBUG */
56774 +
56775 +void
56776 +rj_dumptrees(void)
56777 +{
56778 + rj_preorder(rnh->rnh_treetop, 0);
56779 +}
56780 +
56781 +void
56782 +rj_free_mkfreelist(void)
56783 +{
56784 + struct radij_mask *mknp, *mknp2;
56785 +
56786 + mknp = rj_mkfreelist;
56787 + while(mknp)
56788 + {
56789 + mknp2 = mknp;
56790 + mknp = mknp->rm_mklist;
56791 + kfree(mknp2);
56792 + }
56793 +}
56794 +
56795 +int
56796 +radijcleartree(void)
56797 +{
56798 + return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
56799 +}
56800 +
56801 +int
56802 +radijcleanup(void)
56803 +{
56804 + int error = 0;
56805 +
56806 + error = radijcleartree();
56807 +
56808 + rj_free_mkfreelist();
56809 +
56810 +/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
56811 + if(mask_rjhead) {
56812 + kfree(mask_rjhead);
56813 + }
56814 +
56815 + if(rj_zeroes) {
56816 + kfree(rj_zeroes);
56817 + }
56818 +
56819 + if(rnh) {
56820 + kfree(rnh);
56821 + }
56822 +
56823 + return error;
56824 +}
56825 +
56826 +/*
56827 + * $Log: radij.c,v $
56828 + * Revision 1.48.2.1 2006/10/06 21:39:27 paul
56829 + * Fix for 2.6.18+ only include linux/config.h if AUTOCONF_INCLUDED is not
56830 + * set. This is defined through autoconf.h which is included through the
56831 + * linux kernel build macros.
56832 + *
56833 + * Revision 1.48 2005/04/29 05:10:22 mcr
56834 + * removed from extraenous includes to make unit testing easier.
56835 + *
56836 + * Revision 1.47 2004/07/10 19:11:18 mcr
56837 + * CONFIG_IPSEC -> CONFIG_KLIPS.
56838 + *
56839 + * Revision 1.46 2004/04/06 02:49:26 mcr
56840 + * pullup of algo code from alg-branch.
56841 + *
56842 + * Revision 1.45 2003/10/31 02:27:55 mcr
56843 + * pulled up port-selector patches and sa_id elimination.
56844 + *
56845 + * Revision 1.44.30.1 2003/10/29 01:30:41 mcr
56846 + * elimited "struct sa_id".
56847 + *
56848 + * Revision 1.44 2002/07/24 18:44:54 rgb
56849 + * Type fiddling to tame ia64 compiler.
56850 + *
56851 + * Revision 1.43 2002/05/23 07:14:11 rgb
56852 + * Cleaned up %p variants to 0p%p for test suite cleanup.
56853 + *
56854 + * Revision 1.42 2002/04/24 07:55:32 mcr
56855 + * #include patches and Makefiles for post-reorg compilation.
56856 + *
56857 + * Revision 1.41 2002/04/24 07:36:35 mcr
56858 + * Moved from ./klips/net/ipsec/radij.c,v
56859 + *
56860 + * Revision 1.40 2002/01/29 17:17:58 mcr
56861 + * moved include of ipsec_param.h to after include of linux/kernel.h
56862 + * otherwise, it seems that some option that is set in ipsec_param.h
56863 + * screws up something subtle in the include path to kernel.h, and
56864 + * it complains on the snprintf() prototype.
56865 + *
56866 + * Revision 1.39 2002/01/29 04:00:55 mcr
56867 + * more excise of kversions.h header.
56868 + *
56869 + * Revision 1.38 2002/01/29 02:13:19 mcr
56870 + * introduction of ipsec_kversion.h means that include of
56871 + * ipsec_param.h must preceed any decisions about what files to
56872 + * include to deal with differences in kernel source.
56873 + *
56874 + * Revision 1.37 2001/10/18 04:45:23 rgb
56875 + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
56876 + * lib/freeswan.h version macros moved to lib/kversions.h.
56877 + * Other compiler directive cleanups.
56878 + *
56879 + * Revision 1.36 2001/08/22 13:43:51 henry
56880 + * eliminate the single use of min() to avoid problems with Linus changing it
56881 + *
56882 + * Revision 1.35 2001/06/15 04:57:29 rgb
56883 + * Clarified error return codes.
56884 + * Changed mask add already exists to EEXIST.
56885 + * Changed mask delete did not exist to ENOENT.
56886 + *
56887 + * Revision 1.34 2001/05/03 19:44:26 rgb
56888 + * Fix sign of error return codes for rj_addroute().
56889 + *
56890 + * Revision 1.33 2001/02/27 22:24:56 rgb
56891 + * Re-formatting debug output (line-splitting, joining, 1arg/line).
56892 + * Check for satoa() return codes.
56893 + *
56894 + * Revision 1.32 2001/02/27 06:23:15 rgb
56895 + * Debug line splitting.
56896 + *
56897 + * Revision 1.31 2000/11/06 04:35:21 rgb
56898 + * Clear table *before* releasing other items in radijcleanup.
56899 + *
56900 + * Revision 1.30 2000/09/20 04:07:40 rgb
56901 + * Changed static functions to DEBUG_NO_STATIC to reveal function names in
56902 + * oopsen.
56903 + *
56904 + * Revision 1.29 2000/09/12 03:25:02 rgb
56905 + * Moved radij_c_version printing to ipsec_version_get_info().
56906 + *
56907 + * Revision 1.28 2000/09/08 19:12:56 rgb
56908 + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
56909 + *
56910 + * Revision 1.27 2000/07/28 14:58:32 rgb
56911 + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
56912 + *
56913 + * Revision 1.26 2000/05/10 23:11:37 rgb
56914 + * Comment out most of the startup version information.
56915 + *
56916 + * Revision 1.25 2000/01/21 06:21:47 rgb
56917 + * Change return codes to negative on error.
56918 + *
56919 + * Revision 1.24 1999/11/18 04:09:20 rgb
56920 + * Replaced all kernel version macros to shorter, readable form.
56921 + *
56922 + * Revision 1.23 1999/11/17 15:53:41 rgb
56923 + * Changed all occurrences of #include "../../../lib/freeswan.h"
56924 + * to #include <freeswan.h> which works due to -Ilibfreeswan in the
56925 + * klips/net/ipsec/Makefile.
56926 + *
56927 + * Revision 1.22 1999/10/15 22:17:28 rgb
56928 + * Modify radijcleanup() to call radijcleartree().
56929 + *
56930 + * Revision 1.21 1999/10/08 18:37:34 rgb
56931 + * Fix end-of-line spacing to sate whining PHMs.
56932 + *
56933 + * Revision 1.20 1999/10/01 15:44:54 rgb
56934 + * Move spinlock header include to 2.1> scope.
56935 + *
56936 + * Revision 1.19 1999/10/01 08:35:52 rgb
56937 + * Add spinlock include to shut up compiler for 2.0.38.
56938 + *
56939 + * Revision 1.18 1999/09/23 18:02:52 rgb
56940 + * De-alarm the search failure message so it doesn't sound so grave.
56941 + *
56942 + * Revision 1.17 1999/05/25 21:26:01 rgb
56943 + * Fix rj_walktree() sanity checking bug.
56944 + *
56945 + * Revision 1.16 1999/05/09 03:25:38 rgb
56946 + * Fix bug introduced by 2.2 quick-and-dirty patch.
56947 + *
56948 + * Revision 1.15 1999/05/05 22:02:33 rgb
56949 + * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
56950 + *
56951 + * Revision 1.14 1999/04/29 15:24:15 rgb
56952 + * Add sanity checking for null pointer arguments.
56953 + * Standardise an error return method.
56954 + *
56955 + * Revision 1.13 1999/04/11 00:29:02 henry
56956 + * GPL boilerplate
56957 + *
56958 + * Revision 1.12 1999/04/06 04:54:28 rgb
56959 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
56960 + * patch shell fixes.
56961 + *
56962 + * Revision 1.11 1999/02/17 16:52:53 rgb
56963 + * Convert DEBUG_IPSEC to KLIPS_PRINT
56964 + * Clean out unused cruft.
56965 + *
56966 + * Revision 1.10 1999/01/22 06:30:05 rgb
56967 + * Cruft clean-out.
56968 + * 64-bit clean-up.
56969 + *
56970 + * Revision 1.9 1998/12/01 13:22:04 rgb
56971 + * Added support for debug printing of version info.
56972 + *
56973 + * Revision 1.8 1998/11/30 13:22:55 rgb
56974 + * Rationalised all the klips kernel file headers. They are much shorter
56975 + * now and won't conflict under RH5.2.
56976 + *
56977 + * Revision 1.7 1998/10/25 02:43:26 rgb
56978 + * Change return type on rj_addroute and rj_delete and add and argument
56979 + * to the latter to be able to transmit more infomation about errors.
56980 + *
56981 + * Revision 1.6 1998/10/19 14:30:06 rgb
56982 + * Added inclusion of freeswan.h.
56983 + *
56984 + * Revision 1.5 1998/10/09 04:33:27 rgb
56985 + * Added 'klips_debug' prefix to all klips printk debug statements.
56986 + * Fixed output formatting slightly.
56987 + *
56988 + * Revision 1.4 1998/07/28 00:06:59 rgb
56989 + * Add debug detail to tree traversing.
56990 + *
56991 + * Revision 1.3 1998/07/14 18:07:58 rgb
56992 + * Add a routine to clear the eroute tree.
56993 + *
56994 + * Revision 1.2 1998/06/25 20:03:22 rgb
56995 + * Cleanup #endif comments. Debug output for rj_init.
56996 + *
56997 + * Revision 1.1 1998/06/18 21:30:22 henry
56998 + * move sources from klips/src to klips/net/ipsec to keep stupid kernel
56999 + * build scripts happier about symlinks
57000 + *
57001 + * Revision 1.8 1998/05/25 20:34:15 rgb
57002 + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
57003 + *
57004 + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
57005 + * add ipsec_rj_walker_delete.
57006 + *
57007 + * Recover memory for eroute table on unload of module.
57008 + *
57009 + * Revision 1.7 1998/05/21 12:58:58 rgb
57010 + * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
57011 + *
57012 + * Revision 1.6 1998/04/23 20:57:29 rgb
57013 + * Cleaned up compiler warnings for unused debugging functions.
57014 + *
57015 + * Revision 1.5 1998/04/22 16:51:38 rgb
57016 + * Tidy up radij debug code from recent rash of modifications to debug code.
57017 + *
57018 + * Revision 1.4 1998/04/21 21:28:56 rgb
57019 + * Rearrange debug switches to change on the fly debug output from user
57020 + * space. Only kernel changes checked in at this time. radij.c was also
57021 + * changed to temporarily remove buggy debugging code in rj_delete causing
57022 + * an OOPS and hence, netlink device open errors.
57023 + *
57024 + * Revision 1.3 1998/04/14 17:30:37 rgb
57025 + * Fix up compiling errors for radij tree memory reclamation.
57026 + *
57027 + * Revision 1.2 1998/04/12 22:03:25 rgb
57028 + * Updated ESP-3DES-HMAC-MD5-96,
57029 + * ESP-DES-HMAC-MD5-96,
57030 + * AH-HMAC-MD5-96,
57031 + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
57032 + * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
57033 + *
57034 + * Fixed eroute references in /proc/net/ipsec*.
57035 + *
57036 + * Started to patch module unloading memory leaks in ipsec_netlink and
57037 + * radij tree unloading.
57038 + *
57039 + * Revision 1.1 1998/04/09 03:06:15 henry
57040 + * sources moved up from linux/net/ipsec
57041 + *
57042 + * Revision 1.1.1.1 1998/04/08 05:35:03 henry
57043 + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
57044 + *
57045 + * Revision 0.4 1997/01/15 01:28:15 ji
57046 + * No changes.
57047 + *
57048 + * Revision 0.3 1996/11/20 14:39:04 ji
57049 + * Minor cleanups.
57050 + * Rationalized debugging code.
57051 + *
57052 + * Revision 0.2 1996/11/02 00:18:33 ji
57053 + * First limited release.
57054 + *
57055 + *
57056 + */
57057 --- /dev/null Tue Mar 11 13:02:56 2003
57058 +++ linux/net/ipsec/rangetoa.c Mon Feb 9 13:51:03 2004
57059 @@ -0,0 +1,60 @@
57060 +/*
57061 + * convert binary form of address range to ASCII
57062 + * Copyright (C) 1998, 1999 Henry Spencer.
57063 + *
57064 + * This library is free software; you can redistribute it and/or modify it
57065 + * under the terms of the GNU Library General Public License as published by
57066 + * the Free Software Foundation; either version 2 of the License, or (at your
57067 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57068 + *
57069 + * This library is distributed in the hope that it will be useful, but
57070 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57071 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57072 + * License for more details.
57073 + *
57074 + * RCSID $Id: rangetoa.c,v 1.9 2004/07/10 07:48:37 mcr Exp $
57075 + */
57076 +#include "openswan.h"
57077 +
57078 +/*
57079 + - rangetoa - convert address range to ASCII
57080 + */
57081 +size_t /* space needed for full conversion */
57082 +rangetoa(addrs, format, dst, dstlen)
57083 +struct in_addr addrs[2];
57084 +int format; /* character */
57085 +char *dst; /* need not be valid if dstlen is 0 */
57086 +size_t dstlen;
57087 +{
57088 + size_t len;
57089 + size_t rest;
57090 + int n;
57091 + char *p;
57092 +
57093 + switch (format) {
57094 + case 0:
57095 + break;
57096 + default:
57097 + return 0;
57098 + break;
57099 + }
57100 +
57101 + len = addrtoa(addrs[0], 0, dst, dstlen);
57102 + if (len < dstlen)
57103 + for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
57104 + p++, len++, n--)
57105 + *p = '.';
57106 + else
57107 + p = NULL;
57108 + if (len < dstlen)
57109 + rest = dstlen - len;
57110 + else {
57111 + if (dstlen > 0)
57112 + *(dst + dstlen - 1) = '\0';
57113 + rest = 0;
57114 + }
57115 +
57116 + len += addrtoa(addrs[1], 0, p, rest);
57117 +
57118 + return len;
57119 +}
57120 --- /dev/null Tue Mar 11 13:02:56 2003
57121 +++ linux/net/ipsec/satot.c Mon Feb 9 13:51:03 2004
57122 @@ -0,0 +1,133 @@
57123 +/*
57124 + * convert from binary form of SA ID to text
57125 + * Copyright (C) 2000, 2001 Henry Spencer.
57126 + *
57127 + * This library is free software; you can redistribute it and/or modify it
57128 + * under the terms of the GNU Library General Public License as published by
57129 + * the Free Software Foundation; either version 2 of the License, or (at your
57130 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57131 + *
57132 + * This library is distributed in the hope that it will be useful, but
57133 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57134 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57135 + * License for more details.
57136 + *
57137 + * RCSID $Id: satot.c,v 1.13 2004/07/10 07:48:37 mcr Exp $
57138 + */
57139 +#include "openswan.h"
57140 +
57141 +static struct typename {
57142 + char type;
57143 + char *name;
57144 +} typenames[] = {
57145 + { SA_AH, "ah" },
57146 + { SA_ESP, "esp" },
57147 + { SA_IPIP, "tun" },
57148 + { SA_COMP, "comp" },
57149 + { SA_INT, "int" },
57150 + { 0, NULL }
57151 +};
57152 +
57153 +/*
57154 + - satot - convert SA to text "ah507@1.2.3.4"
57155 + */
57156 +size_t /* space needed for full conversion */
57157 +satot(sa, format, dst, dstlen)
57158 +const ip_said *sa;
57159 +int format; /* character */
57160 +char *dst; /* need not be valid if dstlen is 0 */
57161 +size_t dstlen;
57162 +{
57163 + size_t len = 0; /* 0 means "not recognized yet" */
57164 + int base;
57165 + int showversion; /* use delimiter to show IP version? */
57166 + struct typename *tn;
57167 + char *p;
57168 + char *pre;
57169 + char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
57170 + char unk[10];
57171 +
57172 + switch (format) {
57173 + case 0:
57174 + base = 16;
57175 + showversion = 1;
57176 + break;
57177 + case 'f':
57178 + base = 17;
57179 + showversion = 1;
57180 + break;
57181 + case 'x':
57182 + base = 'x';
57183 + showversion = 0;
57184 + break;
57185 + case 'd':
57186 + base = 10;
57187 + showversion = 0;
57188 + break;
57189 + default:
57190 + return 0;
57191 + break;
57192 + }
57193 +
57194 + memset(buf, 0, sizeof(buf));
57195 +
57196 + pre = NULL;
57197 + for (tn = typenames; tn->name != NULL; tn++)
57198 + if (sa->proto == tn->type) {
57199 + pre = tn->name;
57200 + break; /* NOTE BREAK OUT */
57201 + }
57202 + if (pre == NULL) { /* unknown protocol */
57203 + strcpy(unk, "unk");
57204 + (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
57205 + sizeof(unk)-strlen(unk));
57206 + pre = unk;
57207 + }
57208 +
57209 + if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
57210 + sa->spi == PASSTHROUGHSPI &&
57211 + isunspecaddr(&sa->dst)) {
57212 + strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
57213 + PASSTHROUGH4NAME :
57214 + PASSTHROUGH6NAME);
57215 + len = strlen(buf);
57216 + }
57217 +
57218 + if (sa->proto == SA_INT) {
57219 + switch (ntohl(sa->spi)) {
57220 + case SPI_PASS: p = "%pass"; break;
57221 + case SPI_DROP: p = "%drop"; break;
57222 + case SPI_REJECT: p = "%reject"; break;
57223 + case SPI_HOLD: p = "%hold"; break;
57224 + case SPI_TRAP: p = "%trap"; break;
57225 + case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
57226 + default: p = NULL; break;
57227 + }
57228 + if (p != NULL) {
57229 + strcpy(buf, p);
57230 + len = strlen(buf);
57231 + }
57232 + }
57233 +
57234 + if (len == 0) { /* general case needed */
57235 + strcpy(buf, pre);
57236 + len = strlen(buf);
57237 + if (showversion) {
57238 + *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
57239 + ':';
57240 + len++;
57241 + *(buf+len) = '\0';
57242 + }
57243 + len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
57244 + *(buf+len-1) = '@';
57245 + len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
57246 + *(buf+len) = '\0';
57247 + }
57248 +
57249 + if (dst != NULL) {
57250 + if (len > dstlen)
57251 + *(buf+dstlen-1) = '\0';
57252 + strcpy(dst, buf);
57253 + }
57254 + return len;
57255 +}
57256 --- /dev/null Tue Mar 11 13:02:56 2003
57257 +++ linux/net/ipsec/subnetof.c Mon Feb 9 13:51:03 2004
57258 @@ -0,0 +1,59 @@
57259 +/*
57260 + * minor network-address manipulation utilities
57261 + * Copyright (C) 1998, 1999 Henry Spencer.
57262 + *
57263 + * This library is free software; you can redistribute it and/or modify it
57264 + * under the terms of the GNU Library General Public License as published by
57265 + * the Free Software Foundation; either version 2 of the License, or (at your
57266 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57267 + *
57268 + * This library is distributed in the hope that it will be useful, but
57269 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57270 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57271 + * License for more details.
57272 + *
57273 + * RCSID $Id: subnetof.c,v 1.8 2004/07/10 07:48:37 mcr Exp $
57274 + */
57275 +#include "openswan.h"
57276 +
57277 +/*
57278 + - subnetof - given address and mask, return subnet part
57279 + */
57280 +struct in_addr
57281 +subnetof(addr, mask)
57282 +struct in_addr addr;
57283 +struct in_addr mask;
57284 +{
57285 + struct in_addr result;
57286 +
57287 + result.s_addr = addr.s_addr & mask.s_addr;
57288 + return result;
57289 +}
57290 +
57291 +/*
57292 + - hostof - given address and mask, return host part
57293 + */
57294 +struct in_addr
57295 +hostof(addr, mask)
57296 +struct in_addr addr;
57297 +struct in_addr mask;
57298 +{
57299 + struct in_addr result;
57300 +
57301 + result.s_addr = addr.s_addr & ~mask.s_addr;
57302 + return result;
57303 +}
57304 +
57305 +/*
57306 + - broadcastof - given (network) address and mask, return broadcast address
57307 + */
57308 +struct in_addr
57309 +broadcastof(addr, mask)
57310 +struct in_addr addr;
57311 +struct in_addr mask;
57312 +{
57313 + struct in_addr result;
57314 +
57315 + result.s_addr = addr.s_addr | ~mask.s_addr;
57316 + return result;
57317 +}
57318 --- /dev/null Tue Mar 11 13:02:56 2003
57319 +++ linux/net/ipsec/subnettoa.c Mon Feb 9 13:51:03 2004
57320 @@ -0,0 +1,61 @@
57321 +/*
57322 + * convert binary form of subnet description to ASCII
57323 + * Copyright (C) 1998, 1999 Henry Spencer.
57324 + *
57325 + * This library is free software; you can redistribute it and/or modify it
57326 + * under the terms of the GNU Library General Public License as published by
57327 + * the Free Software Foundation; either version 2 of the License, or (at your
57328 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
57329 + *
57330 + * This library is distributed in the hope that it will be useful, but
57331 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57332 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
57333 + * License for more details.
57334 + *
57335 + * RCSID $Id: subnettoa.c,v 1.11 2004/07/10 07:48:37 mcr Exp $
57336 + */
57337 +#include "openswan.h"
57338 +
57339 +/*
57340 + - subnettoa - convert address and mask to ASCII "addr/mask"
57341 + * Output expresses the mask as a bit count if possible, else dotted decimal.
57342 + */
57343 +size_t /* space needed for full conversion */
57344 +subnettoa(addr, mask, format, dst, dstlen)
57345 +struct in_addr addr;
57346 +struct in_addr mask;
57347 +int format; /* character */
57348 +char *dst; /* need not be valid if dstlen is 0 */
57349 +size_t dstlen;
57350 +{
57351 + size_t len;
57352 + size_t rest;
57353 + int n;
57354 + char *p;
57355 +
57356 + switch (format) {
57357 + case 0:
57358 + break;
57359 + default:
57360 + return 0;
57361 + break;
57362 + }
57363 +
57364 + len = addrtoa(addr, 0, dst, dstlen);
57365 + if (len < dstlen) {
57366 + dst[len - 1] = '/';
57367 + p = dst + len;
57368 + rest = dstlen - len;
57369 + } else {
57370 + p = NULL;
57371 + rest = 0;
57372 + }
57373 +
57374 + n = masktobits(mask);
57375 + if (n >= 0)
57376 + len += ultoa((unsigned long)n, 10, p, rest);
57377 + else
57378 + len += addrtoa(mask, 0, p, rest);
57379 +
57380 + return len;
57381 +}
57382 --- /dev/null Tue Mar 11 13:02:56 2003
57383 +++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004
57384 @@ -0,0 +1,199 @@
57385 +/*
57386 + * sysctl interface to net IPSEC subsystem.
57387 + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
57388 + *
57389 + * This program is free software; you can redistribute it and/or modify it
57390 + * under the terms of the GNU General Public License as published by the
57391 + * Free Software Foundation; either version 2 of the License, or (at your
57392 + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
57393 + *
57394 + * This program is distributed in the hope that it will be useful, but
57395 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
57396 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
57397 + * for more details.
57398 + *
57399 + * RCSID $Id: sysctl_net_ipsec.c,v 1.17 2004/07/10 19:11:18 mcr Exp $
57400 + */
57401 +
57402 +/* -*- linux-c -*-
57403 + *
57404 + * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
57405 + */
57406 +
57407 +#include <linux/mm.h>
57408 +#include <linux/sysctl.h>
57409 +
57410 +#include "openswan/ipsec_param.h"
57411 +
57412 +#ifdef CONFIG_SYSCTL
57413 +
57414 +#define NET_IPSEC 2112 /* Random number */
57415 +#ifdef CONFIG_KLIPS_DEBUG
57416 +extern int debug_ah;
57417 +extern int debug_esp;
57418 +extern int debug_tunnel;
57419 +extern int debug_eroute;
57420 +extern int debug_spi;
57421 +extern int debug_radij;
57422 +extern int debug_netlink;
57423 +extern int debug_xform;
57424 +extern int debug_rcv;
57425 +extern int debug_pfkey;
57426 +extern int sysctl_ipsec_debug_verbose;
57427 +#ifdef CONFIG_KLIPS_IPCOMP
57428 +extern int sysctl_ipsec_debug_ipcomp;
57429 +#endif /* CONFIG_KLIPS_IPCOMP */
57430 +#endif /* CONFIG_KLIPS_DEBUG */
57431 +
57432 +extern int sysctl_ipsec_icmp;
57433 +extern int sysctl_ipsec_inbound_policy_check;
57434 +extern int sysctl_ipsec_tos;
57435 +int sysctl_ipsec_regress_pfkey_lossage;
57436 +
57437 +enum {
57438 +#ifdef CONFIG_KLIPS_DEBUG
57439 + NET_IPSEC_DEBUG_AH=1,
57440 + NET_IPSEC_DEBUG_ESP=2,
57441 + NET_IPSEC_DEBUG_TUNNEL=3,
57442 + NET_IPSEC_DEBUG_EROUTE=4,
57443 + NET_IPSEC_DEBUG_SPI=5,
57444 + NET_IPSEC_DEBUG_RADIJ=6,
57445 + NET_IPSEC_DEBUG_NETLINK=7,
57446 + NET_IPSEC_DEBUG_XFORM=8,
57447 + NET_IPSEC_DEBUG_RCV=9,
57448 + NET_IPSEC_DEBUG_PFKEY=10,
57449 + NET_IPSEC_DEBUG_VERBOSE=11,
57450 + NET_IPSEC_DEBUG_IPCOMP=12,
57451 +#endif /* CONFIG_KLIPS_DEBUG */
57452 + NET_IPSEC_ICMP=13,
57453 + NET_IPSEC_INBOUND_POLICY_CHECK=14,
57454 + NET_IPSEC_TOS=15,
57455 + NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
57456 +};
57457 +
57458 +static ctl_table ipsec_table[] = {
57459 +#ifdef CONFIG_KLIPS_DEBUG
57460 + { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
57461 + sizeof(int), 0644, NULL, &proc_dointvec},
57462 + { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
57463 + sizeof(int), 0644, NULL, &proc_dointvec},
57464 + { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
57465 + sizeof(int), 0644, NULL, &proc_dointvec},
57466 + { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
57467 + sizeof(int), 0644, NULL, &proc_dointvec},
57468 + { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
57469 + sizeof(int), 0644, NULL, &proc_dointvec},
57470 + { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
57471 + sizeof(int), 0644, NULL, &proc_dointvec},
57472 + { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
57473 + sizeof(int), 0644, NULL, &proc_dointvec},
57474 + { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
57475 + sizeof(int), 0644, NULL, &proc_dointvec},
57476 + { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
57477 + sizeof(int), 0644, NULL, &proc_dointvec},
57478 + { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
57479 + sizeof(int), 0644, NULL, &proc_dointvec},
57480 + { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
57481 + sizeof(int), 0644, NULL, &proc_dointvec},
57482 +#ifdef CONFIG_KLIPS_IPCOMP
57483 + { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
57484 + sizeof(int), 0644, NULL, &proc_dointvec},
57485 +#endif /* CONFIG_KLIPS_IPCOMP */
57486 +
57487 +#ifdef CONFIG_KLIPS_REGRESS
57488 + { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
57489 + &sysctl_ipsec_regress_pfkey_lossage,
57490 + sizeof(int), 0644, NULL, &proc_dointvec},
57491 +#endif /* CONFIG_KLIPS_REGRESS */
57492 +
57493 +#endif /* CONFIG_KLIPS_DEBUG */
57494 + { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
57495 + sizeof(int), 0644, NULL, &proc_dointvec},
57496 + { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
57497 + sizeof(int), 0644, NULL, &proc_dointvec},
57498 + { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
57499 + sizeof(int), 0644, NULL, &proc_dointvec},
57500 + {0}
57501 +};
57502 +
57503 +static ctl_table ipsec_net_table[] = {
57504 + { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
57505 + { 0 }
57506 +};
57507 +
57508 +static ctl_table ipsec_root_table[] = {
57509 + { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
57510 + { 0 }
57511 +};
57512 +
57513 +static struct ctl_table_header *ipsec_table_header;
57514 +
57515 +int ipsec_sysctl_register(void)
57516 +{
57517 + ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
57518 + if (!ipsec_table_header) {
57519 + return -ENOMEM;
57520 + }
57521 + return 0;
57522 +}
57523 +
57524 +void ipsec_sysctl_unregister(void)
57525 +{
57526 + unregister_sysctl_table(ipsec_table_header);
57527 +}
57528 +
57529 +#endif /* CONFIG_SYSCTL */
57530 +
57531 +/*
57532 + * $Log: sysctl_net_ipsec.c,v $
57533 + * Revision 1.17 2004/07/10 19:11:18 mcr
57534 + * CONFIG_IPSEC -> CONFIG_KLIPS.
57535 + *
57536 + * Revision 1.16 2004/04/06 02:49:26 mcr
57537 + * pullup of algo code from alg-branch.
57538 + *
57539 + * Revision 1.15 2002/04/24 07:55:32 mcr
57540 + * #include patches and Makefiles for post-reorg compilation.
57541 + *
57542 + * Revision 1.14 2002/04/24 07:36:35 mcr
57543 + * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
57544 + *
57545 + * Revision 1.13 2002/01/12 02:58:32 mcr
57546 + * first regression test causes acquire messages to be lost
57547 + * 100% of the time. This is to help testing of pluto.
57548 + *
57549 + * Revision 1.12 2001/06/14 19:35:13 rgb
57550 + * Update copyright date.
57551 + *
57552 + * Revision 1.11 2001/02/26 19:58:13 rgb
57553 + * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
57554 + *
57555 + * Revision 1.10 2000/09/16 01:50:15 rgb
57556 + * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
57557 + * linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
57558 + *
57559 + * Revision 1.9 2000/09/15 23:17:51 rgb
57560 + * Moved stuff around to compile with debug off.
57561 + *
57562 + * Revision 1.8 2000/09/15 11:37:02 rgb
57563 + * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
57564 + * IPCOMP zlib deflate code.
57565 + *
57566 + * Revision 1.7 2000/09/15 07:37:15 rgb
57567 + * Munged silly log comment that was causing a warning.
57568 + *
57569 + * Revision 1.6 2000/09/15 04:58:23 rgb
57570 + * Added tos runtime switch.
57571 + * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
57572 + *
57573 + * Revision 1.5 2000/09/12 03:25:28 rgb
57574 + * Filled in and implemented sysctl.
57575 + *
57576 + * Revision 1.4 1999/04/11 00:29:03 henry
57577 + * GPL boilerplate
57578 + *
57579 + * Revision 1.3 1999/04/06 04:54:29 rgb
57580 + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
57581 + * patch shell fixes.
57582 + *
57583 + */
57584 --- /dev/null Tue Mar 11 13:02:56 2003
57585 +++ linux/net/ipsec/trees.c Mon Feb 9 13:51:03 2004
57586 @@ -0,0 +1,1214 @@
57587 +/* trees.c -- output deflated data using Huffman coding
57588 + * Copyright (C) 1995-2002 Jean-loup Gailly
57589 + * For conditions of distribution and use, see copyright notice in zlib.h
57590 + */
57591 +
57592 +/*
57593 + * ALGORITHM
57594 + *
57595 + * The "deflation" process uses several Huffman trees. The more
57596 + * common source values are represented by shorter bit sequences.
57597 + *
57598 + * Each code tree is stored in a compressed form which is itself
57599 + * a Huffman encoding of the lengths of all the code strings (in
57600 + * ascending order by source values). The actual code strings are
57601 + * reconstructed from the lengths in the inflate process, as described
57602 + * in the deflate specification.
57603 + *
57604 + * REFERENCES
57605 + *
57606 + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
57607 + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
57608 + *
57609 + * Storer, James A.
57610 + * Data Compression: Methods and Theory, pp. 49-50.
57611 + * Computer Science Press, 1988. ISBN 0-7167-8156-5.
57612 + *
57613 + * Sedgewick, R.
57614 + * Algorithms, p290.
57615 + * Addison-Wesley, 1983. ISBN 0-201-06672-6.
57616 + */
57617 +
57618 +/* @(#) $Id: trees.c,v 1.4 2004/07/10 07:48:39 mcr Exp $ */
57619 +
57620 +/* #define GEN_TREES_H */
57621 +
57622 +#include "deflate.h"
57623 +
57624 +#ifdef DEBUG
57625 +# include <ctype.h>
57626 +#endif
57627 +
57628 +/* ===========================================================================
57629 + * Constants
57630 + */
57631 +
57632 +#define MAX_BL_BITS 7
57633 +/* Bit length codes must not exceed MAX_BL_BITS bits */
57634 +
57635 +#define END_BLOCK 256
57636 +/* end of block literal code */
57637 +
57638 +#define REP_3_6 16
57639 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */
57640 +
57641 +#define REPZ_3_10 17
57642 +/* repeat a zero length 3-10 times (3 bits of repeat count) */
57643 +
57644 +#define REPZ_11_138 18
57645 +/* repeat a zero length 11-138 times (7 bits of repeat count) */
57646 +
57647 +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
57648 + = {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};
57649 +
57650 +local const int extra_dbits[D_CODES] /* extra bits for each distance code */
57651 + = {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};
57652 +
57653 +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
57654 + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
57655 +
57656 +local const uch bl_order[BL_CODES]
57657 + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
57658 +/* The lengths of the bit length codes are sent in order of decreasing
57659 + * probability, to avoid transmitting the lengths for unused bit length codes.
57660 + */
57661 +
57662 +#define Buf_size (8 * 2*sizeof(char))
57663 +/* Number of bits used within bi_buf. (bi_buf might be implemented on
57664 + * more than 16 bits on some systems.)
57665 + */
57666 +
57667 +/* ===========================================================================
57668 + * Local data. These are initialized only once.
57669 + */
57670 +
57671 +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
57672 +
57673 +#if defined(GEN_TREES_H) || !defined(STDC)
57674 +/* non ANSI compilers may not accept trees.h */
57675 +
57676 +local ct_data static_ltree[L_CODES+2];
57677 +/* The static literal tree. Since the bit lengths are imposed, there is no
57678 + * need for the L_CODES extra codes used during heap construction. However
57679 + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
57680 + * below).
57681 + */
57682 +
57683 +local ct_data static_dtree[D_CODES];
57684 +/* The static distance tree. (Actually a trivial tree since all codes use
57685 + * 5 bits.)
57686 + */
57687 +
57688 +uch _dist_code[DIST_CODE_LEN];
57689 +/* Distance codes. The first 256 values correspond to the distances
57690 + * 3 .. 258, the last 256 values correspond to the top 8 bits of
57691 + * the 15 bit distances.
57692 + */
57693 +
57694 +uch _length_code[MAX_MATCH-MIN_MATCH+1];
57695 +/* length code for each normalized match length (0 == MIN_MATCH) */
57696 +
57697 +local int base_length[LENGTH_CODES];
57698 +/* First normalized length for each code (0 = MIN_MATCH) */
57699 +
57700 +local int base_dist[D_CODES];
57701 +/* First normalized distance for each code (0 = distance of 1) */
57702 +
57703 +#else
57704 +# include "trees.h"
57705 +#endif /* GEN_TREES_H */
57706 +
57707 +struct static_tree_desc_s {
57708 + const ct_data *static_tree; /* static tree or NULL */
57709 + const intf *extra_bits; /* extra bits for each code or NULL */
57710 + int extra_base; /* base index for extra_bits */
57711 + int elems; /* max number of elements in the tree */
57712 + int max_length; /* max bit length for the codes */
57713 +};
57714 +
57715 +local static_tree_desc static_l_desc =
57716 +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
57717 +
57718 +local static_tree_desc static_d_desc =
57719 +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
57720 +
57721 +local static_tree_desc static_bl_desc =
57722 +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
57723 +
57724 +/* ===========================================================================
57725 + * Local (static) routines in this file.
57726 + */
57727 +
57728 +local void tr_static_init OF((void));
57729 +local void init_block OF((deflate_state *s));
57730 +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
57731 +local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
57732 +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
57733 +local void build_tree OF((deflate_state *s, tree_desc *desc));
57734 +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
57735 +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
57736 +local int build_bl_tree OF((deflate_state *s));
57737 +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
57738 + int blcodes));
57739 +local void compress_block OF((deflate_state *s, const ct_data *ltree,
57740 + const ct_data *dtree));
57741 +local void set_data_type OF((deflate_state *s));
57742 +local unsigned bi_reverse OF((unsigned value, int length));
57743 +local void bi_windup OF((deflate_state *s));
57744 +local void bi_flush OF((deflate_state *s));
57745 +local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
57746 + int header));
57747 +
57748 +#ifdef GEN_TREES_H
57749 +local void gen_trees_header OF((void));
57750 +#endif
57751 +
57752 +#ifndef DEBUG
57753 +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
57754 + /* Send a code of the given tree. c and tree must not have side effects */
57755 +
57756 +#else /* DEBUG */
57757 +# define send_code(s, c, tree) \
57758 + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
57759 + send_bits(s, tree[c].Code, tree[c].Len); }
57760 +#endif
57761 +
57762 +/* ===========================================================================
57763 + * Output a short LSB first on the stream.
57764 + * IN assertion: there is enough room in pendingBuf.
57765 + */
57766 +#define put_short(s, w) { \
57767 + put_byte(s, (uch)((w) & 0xff)); \
57768 + put_byte(s, (uch)((ush)(w) >> 8)); \
57769 +}
57770 +
57771 +/* ===========================================================================
57772 + * Send a value on a given number of bits.
57773 + * IN assertion: length <= 16 and value fits in length bits.
57774 + */
57775 +#ifdef DEBUG
57776 +local void send_bits OF((deflate_state *s, int value, int length));
57777 +
57778 +local void send_bits(s, value, length)
57779 + deflate_state *s;
57780 + int value; /* value to send */
57781 + int length; /* number of bits */
57782 +{
57783 + Tracevv((stderr," l %2d v %4x ", length, value));
57784 + Assert(length > 0 && length <= 15, "invalid length");
57785 + s->bits_sent += (ulg)length;
57786 +
57787 + /* If not enough room in bi_buf, use (valid) bits from bi_buf and
57788 + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
57789 + * unused bits in value.
57790 + */
57791 + if (s->bi_valid > (int)Buf_size - length) {
57792 + s->bi_buf |= (value << s->bi_valid);
57793 + put_short(s, s->bi_buf);
57794 + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
57795 + s->bi_valid += length - Buf_size;
57796 + } else {
57797 + s->bi_buf |= value << s->bi_valid;
57798 + s->bi_valid += length;
57799 + }
57800 +}
57801 +#else /* !DEBUG */
57802 +
57803 +#define send_bits(s, value, length) \
57804 +{ int len = length;\
57805 + if (s->bi_valid > (int)Buf_size - len) {\
57806 + int val = value;\
57807 + s->bi_buf |= (val << s->bi_valid);\
57808 + put_short(s, s->bi_buf);\
57809 + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
57810 + s->bi_valid += len - Buf_size;\
57811 + } else {\
57812 + s->bi_buf |= (value) << s->bi_valid;\
57813 + s->bi_valid += len;\
57814 + }\
57815 +}
57816 +#endif /* DEBUG */
57817 +
57818 +
57819 +#define MAX(a,b) (a >= b ? a : b)
57820 +/* the arguments must not have side effects */
57821 +
57822 +/* ===========================================================================
57823 + * Initialize the various 'constant' tables.
57824 + */
57825 +local void tr_static_init()
57826 +{
57827 +#if defined(GEN_TREES_H) || !defined(STDC)
57828 + static int static_init_done = 0;
57829 + int n; /* iterates over tree elements */
57830 + int bits; /* bit counter */
57831 + int length; /* length value */
57832 + int code; /* code value */
57833 + int dist; /* distance index */
57834 + ush bl_count[MAX_BITS+1];
57835 + /* number of codes at each bit length for an optimal tree */
57836 +
57837 + if (static_init_done) return;
57838 +
57839 + /* For some embedded targets, global variables are not initialized: */
57840 + static_l_desc.static_tree = static_ltree;
57841 + static_l_desc.extra_bits = extra_lbits;
57842 + static_d_desc.static_tree = static_dtree;
57843 + static_d_desc.extra_bits = extra_dbits;
57844 + static_bl_desc.extra_bits = extra_blbits;
57845 +
57846 + /* Initialize the mapping length (0..255) -> length code (0..28) */
57847 + length = 0;
57848 + for (code = 0; code < LENGTH_CODES-1; code++) {
57849 + base_length[code] = length;
57850 + for (n = 0; n < (1<<extra_lbits[code]); n++) {
57851 + _length_code[length++] = (uch)code;
57852 + }
57853 + }
57854 + Assert (length == 256, "tr_static_init: length != 256");
57855 + /* Note that the length 255 (match length 258) can be represented
57856 + * in two different ways: code 284 + 5 bits or code 285, so we
57857 + * overwrite length_code[255] to use the best encoding:
57858 + */
57859 + _length_code[length-1] = (uch)code;
57860 +
57861 + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
57862 + dist = 0;
57863 + for (code = 0 ; code < 16; code++) {
57864 + base_dist[code] = dist;
57865 + for (n = 0; n < (1<<extra_dbits[code]); n++) {
57866 + _dist_code[dist++] = (uch)code;
57867 + }
57868 + }
57869 + Assert (dist == 256, "tr_static_init: dist != 256");
57870 + dist >>= 7; /* from now on, all distances are divided by 128 */
57871 + for ( ; code < D_CODES; code++) {
57872 + base_dist[code] = dist << 7;
57873 + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
57874 + _dist_code[256 + dist++] = (uch)code;
57875 + }
57876 + }
57877 + Assert (dist == 256, "tr_static_init: 256+dist != 512");
57878 +
57879 + /* Construct the codes of the static literal tree */
57880 + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
57881 + n = 0;
57882 + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
57883 + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
57884 + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
57885 + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
57886 + /* Codes 286 and 287 do not exist, but we must include them in the
57887 + * tree construction to get a canonical Huffman tree (longest code
57888 + * all ones)
57889 + */
57890 + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
57891 +
57892 + /* The static distance tree is trivial: */
57893 + for (n = 0; n < D_CODES; n++) {
57894 + static_dtree[n].Len = 5;
57895 + static_dtree[n].Code = bi_reverse((unsigned)n, 5);
57896 + }
57897 + static_init_done = 1;
57898 +
57899 +# ifdef GEN_TREES_H
57900 + gen_trees_header();
57901 +# endif
57902 +#endif /* defined(GEN_TREES_H) || !defined(STDC) */
57903 +}
57904 +
57905 +/* ===========================================================================
57906 + * Genererate the file trees.h describing the static trees.
57907 + */
57908 +#ifdef GEN_TREES_H
57909 +# ifndef DEBUG
57910 +# include <stdio.h>
57911 +# endif
57912 +
57913 +# define SEPARATOR(i, last, width) \
57914 + ((i) == (last)? "\n};\n\n" : \
57915 + ((i) % (width) == (width)-1 ? ",\n" : ", "))
57916 +
57917 +void gen_trees_header()
57918 +{
57919 + FILE *header = fopen("trees.h", "w");
57920 + int i;
57921 +
57922 + Assert (header != NULL, "Can't open trees.h");
57923 + fprintf(header,
57924 + "/* header created automatically with -DGEN_TREES_H */\n\n");
57925 +
57926 + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
57927 + for (i = 0; i < L_CODES+2; i++) {
57928 + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
57929 + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
57930 + }
57931 +
57932 + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
57933 + for (i = 0; i < D_CODES; i++) {
57934 + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
57935 + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
57936 + }
57937 +
57938 + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
57939 + for (i = 0; i < DIST_CODE_LEN; i++) {
57940 + fprintf(header, "%2u%s", _dist_code[i],
57941 + SEPARATOR(i, DIST_CODE_LEN-1, 20));
57942 + }
57943 +
57944 + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
57945 + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
57946 + fprintf(header, "%2u%s", _length_code[i],
57947 + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
57948 + }
57949 +
57950 + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
57951 + for (i = 0; i < LENGTH_CODES; i++) {
57952 + fprintf(header, "%1u%s", base_length[i],
57953 + SEPARATOR(i, LENGTH_CODES-1, 20));
57954 + }
57955 +
57956 + fprintf(header, "local const int base_dist[D_CODES] = {\n");
57957 + for (i = 0; i < D_CODES; i++) {
57958 + fprintf(header, "%5u%s", base_dist[i],
57959 + SEPARATOR(i, D_CODES-1, 10));
57960 + }
57961 +
57962 + fclose(header);
57963 +}
57964 +#endif /* GEN_TREES_H */
57965 +
57966 +/* ===========================================================================
57967 + * Initialize the tree data structures for a new zlib stream.
57968 + */
57969 +void _tr_init(s)
57970 + deflate_state *s;
57971 +{
57972 + tr_static_init();
57973 +
57974 + s->l_desc.dyn_tree = s->dyn_ltree;
57975 + s->l_desc.stat_desc = &static_l_desc;
57976 +
57977 + s->d_desc.dyn_tree = s->dyn_dtree;
57978 + s->d_desc.stat_desc = &static_d_desc;
57979 +
57980 + s->bl_desc.dyn_tree = s->bl_tree;
57981 + s->bl_desc.stat_desc = &static_bl_desc;
57982 +
57983 + s->bi_buf = 0;
57984 + s->bi_valid = 0;
57985 + s->last_eob_len = 8; /* enough lookahead for inflate */
57986 +#ifdef DEBUG
57987 + s->compressed_len = 0L;
57988 + s->bits_sent = 0L;
57989 +#endif
57990 +
57991 + /* Initialize the first block of the first file: */
57992 + init_block(s);
57993 +}
57994 +
57995 +/* ===========================================================================
57996 + * Initialize a new block.
57997 + */
57998 +local void init_block(s)
57999 + deflate_state *s;
58000 +{
58001 + int n; /* iterates over tree elements */
58002 +
58003 + /* Initialize the trees. */
58004 + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
58005 + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
58006 + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
58007 +
58008 + s->dyn_ltree[END_BLOCK].Freq = 1;
58009 + s->opt_len = s->static_len = 0L;
58010 + s->last_lit = s->matches = 0;
58011 +}
58012 +
58013 +#define SMALLEST 1
58014 +/* Index within the heap array of least frequent node in the Huffman tree */
58015 +
58016 +
58017 +/* ===========================================================================
58018 + * Remove the smallest element from the heap and recreate the heap with
58019 + * one less element. Updates heap and heap_len.
58020 + */
58021 +#define pqremove(s, tree, top) \
58022 +{\
58023 + top = s->heap[SMALLEST]; \
58024 + s->heap[SMALLEST] = s->heap[s->heap_len--]; \
58025 + pqdownheap(s, tree, SMALLEST); \
58026 +}
58027 +
58028 +/* ===========================================================================
58029 + * Compares to subtrees, using the tree depth as tie breaker when
58030 + * the subtrees have equal frequency. This minimizes the worst case length.
58031 + */
58032 +#define smaller(tree, n, m, depth) \
58033 + (tree[n].Freq < tree[m].Freq || \
58034 + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
58035 +
58036 +/* ===========================================================================
58037 + * Restore the heap property by moving down the tree starting at node k,
58038 + * exchanging a node with the smallest of its two sons if necessary, stopping
58039 + * when the heap property is re-established (each father smaller than its
58040 + * two sons).
58041 + */
58042 +local void pqdownheap(s, tree, k)
58043 + deflate_state *s;
58044 + ct_data *tree; /* the tree to restore */
58045 + int k; /* node to move down */
58046 +{
58047 + int v = s->heap[k];
58048 + int j = k << 1; /* left son of k */
58049 + while (j <= s->heap_len) {
58050 + /* Set j to the smallest of the two sons: */
58051 + if (j < s->heap_len &&
58052 + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
58053 + j++;
58054 + }
58055 + /* Exit if v is smaller than both sons */
58056 + if (smaller(tree, v, s->heap[j], s->depth)) break;
58057 +
58058 + /* Exchange v with the smallest son */
58059 + s->heap[k] = s->heap[j]; k = j;
58060 +
58061 + /* And continue down the tree, setting j to the left son of k */
58062 + j <<= 1;
58063 + }
58064 + s->heap[k] = v;
58065 +}
58066 +
58067 +/* ===========================================================================
58068 + * Compute the optimal bit lengths for a tree and update the total bit length
58069 + * for the current block.
58070 + * IN assertion: the fields freq and dad are set, heap[heap_max] and
58071 + * above are the tree nodes sorted by increasing frequency.
58072 + * OUT assertions: the field len is set to the optimal bit length, the
58073 + * array bl_count contains the frequencies for each bit length.
58074 + * The length opt_len is updated; static_len is also updated if stree is
58075 + * not null.
58076 + */
58077 +local void gen_bitlen(s, desc)
58078 + deflate_state *s;
58079 + tree_desc *desc; /* the tree descriptor */
58080 +{
58081 + ct_data *tree = desc->dyn_tree;
58082 + int max_code = desc->max_code;
58083 + const ct_data *stree = desc->stat_desc->static_tree;
58084 + const intf *extra = desc->stat_desc->extra_bits;
58085 + int base = desc->stat_desc->extra_base;
58086 + int max_length = desc->stat_desc->max_length;
58087 + int h; /* heap index */
58088 + int n, m; /* iterate over the tree elements */
58089 + int bits; /* bit length */
58090 + int xbits; /* extra bits */
58091 + ush f; /* frequency */
58092 + int overflow = 0; /* number of elements with bit length too large */
58093 +
58094 + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
58095 +
58096 + /* In a first pass, compute the optimal bit lengths (which may
58097 + * overflow in the case of the bit length tree).
58098 + */
58099 + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
58100 +
58101 + for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
58102 + n = s->heap[h];
58103 + bits = tree[tree[n].Dad].Len + 1;
58104 + if (bits > max_length) bits = max_length, overflow++;
58105 + tree[n].Len = (ush)bits;
58106 + /* We overwrite tree[n].Dad which is no longer needed */
58107 +
58108 + if (n > max_code) continue; /* not a leaf node */
58109 +
58110 + s->bl_count[bits]++;
58111 + xbits = 0;
58112 + if (n >= base) xbits = extra[n-base];
58113 + f = tree[n].Freq;
58114 + s->opt_len += (ulg)f * (bits + xbits);
58115 + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
58116 + }
58117 + if (overflow == 0) return;
58118 +
58119 + Trace((stderr,"\nbit length overflow\n"));
58120 + /* This happens for example on obj2 and pic of the Calgary corpus */
58121 +
58122 + /* Find the first bit length which could increase: */
58123 + do {
58124 + bits = max_length-1;
58125 + while (s->bl_count[bits] == 0) bits--;
58126 + s->bl_count[bits]--; /* move one leaf down the tree */
58127 + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
58128 + s->bl_count[max_length]--;
58129 + /* The brother of the overflow item also moves one step up,
58130 + * but this does not affect bl_count[max_length]
58131 + */
58132 + overflow -= 2;
58133 + } while (overflow > 0);
58134 +
58135 + /* Now recompute all bit lengths, scanning in increasing frequency.
58136 + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
58137 + * lengths instead of fixing only the wrong ones. This idea is taken
58138 + * from 'ar' written by Haruhiko Okumura.)
58139 + */
58140 + for (bits = max_length; bits != 0; bits--) {
58141 + n = s->bl_count[bits];
58142 + while (n != 0) {
58143 + m = s->heap[--h];
58144 + if (m > max_code) continue;
58145 + if (tree[m].Len != (unsigned) bits) {
58146 + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
58147 + s->opt_len += ((long)bits - (long)tree[m].Len)
58148 + *(long)tree[m].Freq;
58149 + tree[m].Len = (ush)bits;
58150 + }
58151 + n--;
58152 + }
58153 + }
58154 +}
58155 +
58156 +/* ===========================================================================
58157 + * Generate the codes for a given tree and bit counts (which need not be
58158 + * optimal).
58159 + * IN assertion: the array bl_count contains the bit length statistics for
58160 + * the given tree and the field len is set for all tree elements.
58161 + * OUT assertion: the field code is set for all tree elements of non
58162 + * zero code length.
58163 + */
58164 +local void gen_codes (tree, max_code, bl_count)
58165 + ct_data *tree; /* the tree to decorate */
58166 + int max_code; /* largest code with non zero frequency */
58167 + ushf *bl_count; /* number of codes at each bit length */
58168 +{
58169 + ush next_code[MAX_BITS+1]; /* next code value for each bit length */
58170 + ush code = 0; /* running code value */
58171 + int bits; /* bit index */
58172 + int n; /* code index */
58173 +
58174 + /* The distribution counts are first used to generate the code values
58175 + * without bit reversal.
58176 + */
58177 + for (bits = 1; bits <= MAX_BITS; bits++) {
58178 + next_code[bits] = code = (code + bl_count[bits-1]) << 1;
58179 + }
58180 + /* Check that the bit counts in bl_count are consistent. The last code
58181 + * must be all ones.
58182 + */
58183 + Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
58184 + "inconsistent bit counts");
58185 + Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
58186 +
58187 + for (n = 0; n <= max_code; n++) {
58188 + int len = tree[n].Len;
58189 + if (len == 0) continue;
58190 + /* Now reverse the bits */
58191 + tree[n].Code = bi_reverse(next_code[len]++, len);
58192 +
58193 + Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
58194 + n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
58195 + }
58196 +}
58197 +
58198 +/* ===========================================================================
58199 + * Construct one Huffman tree and assigns the code bit strings and lengths.
58200 + * Update the total bit length for the current block.
58201 + * IN assertion: the field freq is set for all tree elements.
58202 + * OUT assertions: the fields len and code are set to the optimal bit length
58203 + * and corresponding code. The length opt_len is updated; static_len is
58204 + * also updated if stree is not null. The field max_code is set.
58205 + */
58206 +local void build_tree(s, desc)
58207 + deflate_state *s;
58208 + tree_desc *desc; /* the tree descriptor */
58209 +{
58210 + ct_data *tree = desc->dyn_tree;
58211 + const ct_data *stree = desc->stat_desc->static_tree;
58212 + int elems = desc->stat_desc->elems;
58213 + int n, m; /* iterate over heap elements */
58214 + int max_code = -1; /* largest code with non zero frequency */
58215 + int node; /* new node being created */
58216 +
58217 + /* Construct the initial heap, with least frequent element in
58218 + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
58219 + * heap[0] is not used.
58220 + */
58221 + s->heap_len = 0, s->heap_max = HEAP_SIZE;
58222 +
58223 + for (n = 0; n < elems; n++) {
58224 + if (tree[n].Freq != 0) {
58225 + s->heap[++(s->heap_len)] = max_code = n;
58226 + s->depth[n] = 0;
58227 + } else {
58228 + tree[n].Len = 0;
58229 + }
58230 + }
58231 +
58232 + /* The pkzip format requires that at least one distance code exists,
58233 + * and that at least one bit should be sent even if there is only one
58234 + * possible code. So to avoid special checks later on we force at least
58235 + * two codes of non zero frequency.
58236 + */
58237 + while (s->heap_len < 2) {
58238 + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
58239 + tree[node].Freq = 1;
58240 + s->depth[node] = 0;
58241 + s->opt_len--; if (stree) s->static_len -= stree[node].Len;
58242 + /* node is 0 or 1 so it does not have extra bits */
58243 + }
58244 + desc->max_code = max_code;
58245 +
58246 + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
58247 + * establish sub-heaps of increasing lengths:
58248 + */
58249 + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
58250 +
58251 + /* Construct the Huffman tree by repeatedly combining the least two
58252 + * frequent nodes.
58253 + */
58254 + node = elems; /* next internal node of the tree */
58255 + do {
58256 + pqremove(s, tree, n); /* n = node of least frequency */
58257 + m = s->heap[SMALLEST]; /* m = node of next least frequency */
58258 +
58259 + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
58260 + s->heap[--(s->heap_max)] = m;
58261 +
58262 + /* Create a new node father of n and m */
58263 + tree[node].Freq = tree[n].Freq + tree[m].Freq;
58264 + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
58265 + tree[n].Dad = tree[m].Dad = (ush)node;
58266 +#ifdef DUMP_BL_TREE
58267 + if (tree == s->bl_tree) {
58268 + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
58269 + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
58270 + }
58271 +#endif
58272 + /* and insert the new node in the heap */
58273 + s->heap[SMALLEST] = node++;
58274 + pqdownheap(s, tree, SMALLEST);
58275 +
58276 + } while (s->heap_len >= 2);
58277 +
58278 + s->heap[--(s->heap_max)] = s->heap[SMALLEST];
58279 +
58280 + /* At this point, the fields freq and dad are set. We can now
58281 + * generate the bit lengths.
58282 + */
58283 + gen_bitlen(s, (tree_desc *)desc);
58284 +
58285 + /* The field len is now set, we can generate the bit codes */
58286 + gen_codes ((ct_data *)tree, max_code, s->bl_count);
58287 +}
58288 +
58289 +/* ===========================================================================
58290 + * Scan a literal or distance tree to determine the frequencies of the codes
58291 + * in the bit length tree.
58292 + */
58293 +local void scan_tree (s, tree, max_code)
58294 + deflate_state *s;
58295 + ct_data *tree; /* the tree to be scanned */
58296 + int max_code; /* and its largest code of non zero frequency */
58297 +{
58298 + int n; /* iterates over all tree elements */
58299 + int prevlen = -1; /* last emitted length */
58300 + int curlen; /* length of current code */
58301 + int nextlen = tree[0].Len; /* length of next code */
58302 + int count = 0; /* repeat count of the current code */
58303 + int max_count = 7; /* max repeat count */
58304 + int min_count = 4; /* min repeat count */
58305 +
58306 + if (nextlen == 0) max_count = 138, min_count = 3;
58307 + tree[max_code+1].Len = (ush)0xffff; /* guard */
58308 +
58309 + for (n = 0; n <= max_code; n++) {
58310 + curlen = nextlen; nextlen = tree[n+1].Len;
58311 + if (++count < max_count && curlen == nextlen) {
58312 + continue;
58313 + } else if (count < min_count) {
58314 + s->bl_tree[curlen].Freq += count;
58315 + } else if (curlen != 0) {
58316 + if (curlen != prevlen) s->bl_tree[curlen].Freq++;
58317 + s->bl_tree[REP_3_6].Freq++;
58318 + } else if (count <= 10) {
58319 + s->bl_tree[REPZ_3_10].Freq++;
58320 + } else {
58321 + s->bl_tree[REPZ_11_138].Freq++;
58322 + }
58323 + count = 0; prevlen = curlen;
58324 + if (nextlen == 0) {
58325 + max_count = 138, min_count = 3;
58326 + } else if (curlen == nextlen) {
58327 + max_count = 6, min_count = 3;
58328 + } else {
58329 + max_count = 7, min_count = 4;
58330 + }
58331 + }
58332 +}
58333 +
58334 +/* ===========================================================================
58335 + * Send a literal or distance tree in compressed form, using the codes in
58336 + * bl_tree.
58337 + */
58338 +local void send_tree (s, tree, max_code)
58339 + deflate_state *s;
58340 + ct_data *tree; /* the tree to be scanned */
58341 + int max_code; /* and its largest code of non zero frequency */
58342 +{
58343 + int n; /* iterates over all tree elements */
58344 + int prevlen = -1; /* last emitted length */
58345 + int curlen; /* length of current code */
58346 + int nextlen = tree[0].Len; /* length of next code */
58347 + int count = 0; /* repeat count of the current code */
58348 + int max_count = 7; /* max repeat count */
58349 + int min_count = 4; /* min repeat count */
58350 +
58351 + /* tree[max_code+1].Len = -1; */ /* guard already set */
58352 + if (nextlen == 0) max_count = 138, min_count = 3;
58353 +
58354 + for (n = 0; n <= max_code; n++) {
58355 + curlen = nextlen; nextlen = tree[n+1].Len;
58356 + if (++count < max_count && curlen == nextlen) {
58357 + continue;
58358 + } else if (count < min_count) {
58359 + do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
58360 +
58361 + } else if (curlen != 0) {
58362 + if (curlen != prevlen) {
58363 + send_code(s, curlen, s->bl_tree); count--;
58364 + }
58365 + Assert(count >= 3 && count <= 6, " 3_6?");
58366 + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
58367 +
58368 + } else if (count <= 10) {
58369 + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
58370 +
58371 + } else {
58372 + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
58373 + }
58374 + count = 0; prevlen = curlen;
58375 + if (nextlen == 0) {
58376 + max_count = 138, min_count = 3;
58377 + } else if (curlen == nextlen) {
58378 + max_count = 6, min_count = 3;
58379 + } else {
58380 + max_count = 7, min_count = 4;
58381 + }
58382 + }
58383 +}
58384 +
58385 +/* ===========================================================================
58386 + * Construct the Huffman tree for the bit lengths and return the index in
58387 + * bl_order of the last bit length code to send.
58388 + */
58389 +local int build_bl_tree(s)
58390 + deflate_state *s;
58391 +{
58392 + int max_blindex; /* index of last bit length code of non zero freq */
58393 +
58394 + /* Determine the bit length frequencies for literal and distance trees */
58395 + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
58396 + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
58397 +
58398 + /* Build the bit length tree: */
58399 + build_tree(s, (tree_desc *)(&(s->bl_desc)));
58400 + /* opt_len now includes the length of the tree representations, except
58401 + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
58402 + */
58403 +
58404 + /* Determine the number of bit length codes to send. The pkzip format
58405 + * requires that at least 4 bit length codes be sent. (appnote.txt says
58406 + * 3 but the actual value used is 4.)
58407 + */
58408 + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
58409 + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
58410 + }
58411 + /* Update opt_len to include the bit length tree and counts */
58412 + s->opt_len += 3*(max_blindex+1) + 5+5+4;
58413 + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
58414 + s->opt_len, s->static_len));
58415 +
58416 + return max_blindex;
58417 +}
58418 +
58419 +/* ===========================================================================
58420 + * Send the header for a block using dynamic Huffman trees: the counts, the
58421 + * lengths of the bit length codes, the literal tree and the distance tree.
58422 + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
58423 + */
58424 +local void send_all_trees(s, lcodes, dcodes, blcodes)
58425 + deflate_state *s;
58426 + int lcodes, dcodes, blcodes; /* number of codes for each tree */
58427 +{
58428 + int rank; /* index in bl_order */
58429 +
58430 + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
58431 + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
58432 + "too many codes");
58433 + Tracev((stderr, "\nbl counts: "));
58434 + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
58435 + send_bits(s, dcodes-1, 5);
58436 + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
58437 + for (rank = 0; rank < blcodes; rank++) {
58438 + Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
58439 + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
58440 + }
58441 + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
58442 +
58443 + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
58444 + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
58445 +
58446 + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
58447 + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
58448 +}
58449 +
58450 +/* ===========================================================================
58451 + * Send a stored block
58452 + */
58453 +void _tr_stored_block(s, buf, stored_len, eof)
58454 + deflate_state *s;
58455 + charf *buf; /* input block */
58456 + ulg stored_len; /* length of input block */
58457 + int eof; /* true if this is the last block for a file */
58458 +{
58459 + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
58460 +#ifdef DEBUG
58461 + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
58462 + s->compressed_len += (stored_len + 4) << 3;
58463 +#endif
58464 + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
58465 +}
58466 +
58467 +/* ===========================================================================
58468 + * Send one empty static block to give enough lookahead for inflate.
58469 + * This takes 10 bits, of which 7 may remain in the bit buffer.
58470 + * The current inflate code requires 9 bits of lookahead. If the
58471 + * last two codes for the previous block (real code plus EOB) were coded
58472 + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
58473 + * the last real code. In this case we send two empty static blocks instead
58474 + * of one. (There are no problems if the previous block is stored or fixed.)
58475 + * To simplify the code, we assume the worst case of last real code encoded
58476 + * on one bit only.
58477 + */
58478 +void _tr_align(s)
58479 + deflate_state *s;
58480 +{
58481 + send_bits(s, STATIC_TREES<<1, 3);
58482 + send_code(s, END_BLOCK, static_ltree);
58483 +#ifdef DEBUG
58484 + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
58485 +#endif
58486 + bi_flush(s);
58487 + /* Of the 10 bits for the empty block, we have already sent
58488 + * (10 - bi_valid) bits. The lookahead for the last real code (before
58489 + * the EOB of the previous block) was thus at least one plus the length
58490 + * of the EOB plus what we have just sent of the empty static block.
58491 + */
58492 + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
58493 + send_bits(s, STATIC_TREES<<1, 3);
58494 + send_code(s, END_BLOCK, static_ltree);
58495 +#ifdef DEBUG
58496 + s->compressed_len += 10L;
58497 +#endif
58498 + bi_flush(s);
58499 + }
58500 + s->last_eob_len = 7;
58501 +}
58502 +
58503 +/* ===========================================================================
58504 + * Determine the best encoding for the current block: dynamic trees, static
58505 + * trees or store, and output the encoded block to the zip file.
58506 + */
58507 +void _tr_flush_block(s, buf, stored_len, eof)
58508 + deflate_state *s;
58509 + charf *buf; /* input block, or NULL if too old */
58510 + ulg stored_len; /* length of input block */
58511 + int eof; /* true if this is the last block for a file */
58512 +{
58513 + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
58514 + int max_blindex = 0; /* index of last bit length code of non zero freq */
58515 +
58516 + /* Build the Huffman trees unless a stored block is forced */
58517 + if (s->level > 0) {
58518 +
58519 + /* Check if the file is ascii or binary */
58520 + if (s->data_type == Z_UNKNOWN) set_data_type(s);
58521 +
58522 + /* Construct the literal and distance trees */
58523 + build_tree(s, (tree_desc *)(&(s->l_desc)));
58524 + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
58525 + s->static_len));
58526 +
58527 + build_tree(s, (tree_desc *)(&(s->d_desc)));
58528 + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
58529 + s->static_len));
58530 + /* At this point, opt_len and static_len are the total bit lengths of
58531 + * the compressed block data, excluding the tree representations.
58532 + */
58533 +
58534 + /* Build the bit length tree for the above two trees, and get the index
58535 + * in bl_order of the last bit length code to send.
58536 + */
58537 + max_blindex = build_bl_tree(s);
58538 +
58539 + /* Determine the best encoding. Compute first the block length in bytes*/
58540 + opt_lenb = (s->opt_len+3+7)>>3;
58541 + static_lenb = (s->static_len+3+7)>>3;
58542 +
58543 + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
58544 + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
58545 + s->last_lit));
58546 +
58547 + if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
58548 +
58549 + } else {
58550 + Assert(buf != (char*)0, "lost buf");
58551 + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
58552 + }
58553 +
58554 +#ifdef FORCE_STORED
58555 + if (buf != (char*)0) { /* force stored block */
58556 +#else
58557 + if (stored_len+4 <= opt_lenb && buf != (char*)0) {
58558 + /* 4: two words for the lengths */
58559 +#endif
58560 + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
58561 + * Otherwise we can't have processed more than WSIZE input bytes since
58562 + * the last block flush, because compression would have been
58563 + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
58564 + * transform a block into a stored block.
58565 + */
58566 + _tr_stored_block(s, buf, stored_len, eof);
58567 +
58568 +#ifdef FORCE_STATIC
58569 + } else if (static_lenb >= 0) { /* force static trees */
58570 +#else
58571 + } else if (static_lenb == opt_lenb) {
58572 +#endif
58573 + send_bits(s, (STATIC_TREES<<1)+eof, 3);
58574 + compress_block(s, static_ltree, static_dtree);
58575 +#ifdef DEBUG
58576 + s->compressed_len += 3 + s->static_len;
58577 +#endif
58578 + } else {
58579 + send_bits(s, (DYN_TREES<<1)+eof, 3);
58580 + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
58581 + max_blindex+1);
58582 + compress_block(s, s->dyn_ltree, s->dyn_dtree);
58583 +#ifdef DEBUG
58584 + s->compressed_len += 3 + s->opt_len;
58585 +#endif
58586 + }
58587 + Assert (s->compressed_len == s->bits_sent, "bad compressed size");
58588 + /* The above check is made mod 2^32, for files larger than 512 MB
58589 + * and uLong implemented on 32 bits.
58590 + */
58591 + init_block(s);
58592 +
58593 + if (eof) {
58594 + bi_windup(s);
58595 +#ifdef DEBUG
58596 + s->compressed_len += 7; /* align on byte boundary */
58597 +#endif
58598 + }
58599 + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
58600 + s->compressed_len-7*eof));
58601 +}
58602 +
58603 +/* ===========================================================================
58604 + * Save the match info and tally the frequency counts. Return true if
58605 + * the current block must be flushed.
58606 + */
58607 +int _tr_tally (s, dist, lc)
58608 + deflate_state *s;
58609 + unsigned dist; /* distance of matched string */
58610 + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
58611 +{
58612 + s->d_buf[s->last_lit] = (ush)dist;
58613 + s->l_buf[s->last_lit++] = (uch)lc;
58614 + if (dist == 0) {
58615 + /* lc is the unmatched char */
58616 + s->dyn_ltree[lc].Freq++;
58617 + } else {
58618 + s->matches++;
58619 + /* Here, lc is the match length - MIN_MATCH */
58620 + dist--; /* dist = match distance - 1 */
58621 + Assert((ush)dist < (ush)MAX_DIST(s) &&
58622 + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
58623 + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
58624 +
58625 + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
58626 + s->dyn_dtree[d_code(dist)].Freq++;
58627 + }
58628 +
58629 +#ifdef TRUNCATE_BLOCK
58630 + /* Try to guess if it is profitable to stop the current block here */
58631 + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
58632 + /* Compute an upper bound for the compressed length */
58633 + ulg out_length = (ulg)s->last_lit*8L;
58634 + ulg in_length = (ulg)((long)s->strstart - s->block_start);
58635 + int dcode;
58636 + for (dcode = 0; dcode < D_CODES; dcode++) {
58637 + out_length += (ulg)s->dyn_dtree[dcode].Freq *
58638 + (5L+extra_dbits[dcode]);
58639 + }
58640 + out_length >>= 3;
58641 + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
58642 + s->last_lit, in_length, out_length,
58643 + 100L - out_length*100L/in_length));
58644 + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
58645 + }
58646 +#endif
58647 + return (s->last_lit == s->lit_bufsize-1);
58648 + /* We avoid equality with lit_bufsize because of wraparound at 64K
58649 + * on 16 bit machines and because stored blocks are restricted to
58650 + * 64K-1 bytes.
58651 + */
58652 +}
58653 +
58654 +/* ===========================================================================
58655 + * Send the block data compressed using the given Huffman trees
58656 + */
58657 +local void compress_block(s, ltree, dtree)
58658 + deflate_state *s;
58659 + const ct_data *ltree; /* literal tree */
58660 + const ct_data *dtree; /* distance tree */
58661 +{
58662 + unsigned dist; /* distance of matched string */
58663 + int lc; /* match length or unmatched char (if dist == 0) */
58664 + unsigned lx = 0; /* running index in l_buf */
58665 + unsigned code; /* the code to send */
58666 + int extra; /* number of extra bits to send */
58667 +
58668 + if (s->last_lit != 0) do {
58669 + dist = s->d_buf[lx];
58670 + lc = s->l_buf[lx++];
58671 + if (dist == 0) {
58672 + send_code(s, lc, ltree); /* send a literal byte */
58673 + Tracecv(isgraph(lc), (stderr," '%c' ", lc));
58674 + } else {
58675 + /* Here, lc is the match length - MIN_MATCH */
58676 + code = _length_code[lc];
58677 + send_code(s, code+LITERALS+1, ltree); /* send the length code */
58678 + extra = extra_lbits[code];
58679 + if (extra != 0) {
58680 + lc -= base_length[code];
58681 + send_bits(s, lc, extra); /* send the extra length bits */
58682 + }
58683 + dist--; /* dist is now the match distance - 1 */
58684 + code = d_code(dist);
58685 + Assert (code < D_CODES, "bad d_code");
58686 +
58687 + send_code(s, code, dtree); /* send the distance code */
58688 + extra = extra_dbits[code];
58689 + if (extra != 0) {
58690 + dist -= base_dist[code];
58691 + send_bits(s, dist, extra); /* send the extra distance bits */
58692 + }
58693 + } /* literal or match pair ? */
58694 +
58695 + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
58696 + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
58697 +
58698 + } while (lx < s->last_lit);
58699 +
58700 + send_code(s, END_BLOCK, ltree);
58701 + s->last_eob_len = ltree[END_BLOCK].Len;
58702 +}
58703 +
58704 +/* ===========================================================================
58705 + * Set the data type to ASCII or BINARY, using a crude approximation:
58706 + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
58707 + * IN assertion: the fields freq of dyn_ltree are set and the total of all
58708 + * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
58709 + */
58710 +local void set_data_type(s)
58711 + deflate_state *s;
58712 +{
58713 + int n = 0;
58714 + unsigned ascii_freq = 0;
58715 + unsigned bin_freq = 0;
58716 + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
58717 + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
58718 + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
58719 + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
58720 +}
58721 +
58722 +/* ===========================================================================
58723 + * Reverse the first len bits of a code, using straightforward code (a faster
58724 + * method would use a table)
58725 + * IN assertion: 1 <= len <= 15
58726 + */
58727 +local unsigned bi_reverse(code, len)
58728 + unsigned code; /* the value to invert */
58729 + int len; /* its bit length */
58730 +{
58731 + register unsigned res = 0;
58732 + do {
58733 + res |= code & 1;
58734 + code >>= 1, res <<= 1;
58735 + } while (--len > 0);
58736 + return res >> 1;
58737 +}
58738 +
58739 +/* ===========================================================================
58740 + * Flush the bit buffer, keeping at most 7 bits in it.
58741 + */
58742 +local void bi_flush(s)
58743 + deflate_state *s;
58744 +{
58745 + if (s->bi_valid == 16) {
58746 + put_short(s, s->bi_buf);
58747 + s->bi_buf = 0;
58748 + s->bi_valid = 0;
58749 + } else if (s->bi_valid >= 8) {
58750 + put_byte(s, (Byte)s->bi_buf);
58751 + s->bi_buf >>= 8;
58752 + s->bi_valid -= 8;
58753 + }
58754 +}
58755 +
58756 +/* ===========================================================================
58757 + * Flush the bit buffer and align the output on a byte boundary
58758 + */
58759 +local void bi_windup(s)
58760 + deflate_state *s;
58761 +{
58762 + if (s->bi_valid > 8) {
58763 + put_short(s, s->bi_buf);
58764 + } else if (s->bi_valid > 0) {
58765 + put_byte(s, (Byte)s->bi_buf);
58766 + }
58767 + s->bi_buf = 0;
58768 + s->bi_valid = 0;
58769 +#ifdef DEBUG
58770 + s->bits_sent = (s->bits_sent+7) & ~7;
58771 +#endif
58772 +}
58773 +
58774 +/* ===========================================================================
58775 + * Copy a stored block, storing first the length and its
58776 + * one's complement if requested.
58777 + */
58778 +local void copy_block(s, buf, len, header)
58779 + deflate_state *s;
58780 + charf *buf; /* the input data */
58781 + unsigned len; /* its length */
58782 + int header; /* true if block header must be written */
58783 +{
58784 + bi_windup(s); /* align on byte boundary */
58785 + s->last_eob_len = 8; /* enough lookahead for inflate */
58786 +
58787 + if (header) {
58788 + put_short(s, (ush)len);
58789 + put_short(s, (ush)~len);
58790 +#ifdef DEBUG
58791 + s->bits_sent += 2*16;
58792 +#endif
58793 + }
58794 +#ifdef DEBUG
58795 + s->bits_sent += (ulg)len<<3;
58796 +#endif
58797 + while (len--) {
58798 + put_byte(s, *buf++);
58799 + }
58800 +}
58801 --- /dev/null Tue Mar 11 13:02:56 2003
58802 +++ linux/net/ipsec/trees.h Mon Feb 9 13:51:03 2004
58803 @@ -0,0 +1,128 @@
58804 +/* header created automatically with -DGEN_TREES_H */
58805 +
58806 +local const ct_data static_ltree[L_CODES+2] = {
58807 +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
58808 +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
58809 +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
58810 +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
58811 +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
58812 +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
58813 +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
58814 +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
58815 +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
58816 +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
58817 +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
58818 +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
58819 +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
58820 +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
58821 +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
58822 +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
58823 +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
58824 +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
58825 +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
58826 +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
58827 +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
58828 +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
58829 +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
58830 +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
58831 +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
58832 +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
58833 +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
58834 +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
58835 +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
58836 +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
58837 +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
58838 +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
58839 +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
58840 +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
58841 +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
58842 +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
58843 +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
58844 +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
58845 +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
58846 +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
58847 +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
58848 +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
58849 +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
58850 +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
58851 +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
58852 +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
58853 +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
58854 +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
58855 +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
58856 +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
58857 +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
58858 +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
58859 +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
58860 +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
58861 +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
58862 +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
58863 +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
58864 +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
58865 +};
58866 +
58867 +local const ct_data static_dtree[D_CODES] = {
58868 +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
58869 +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
58870 +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
58871 +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
58872 +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
58873 +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
58874 +};
58875 +
58876 +const uch _dist_code[DIST_CODE_LEN] = {
58877 + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
58878 + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
58879 +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
58880 +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
58881 +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
58882 +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
58883 +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
58884 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
58885 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
58886 +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
58887 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
58888 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
58889 +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
58890 +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
58891 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
58892 +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
58893 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
58894 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
58895 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
58896 +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
58897 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
58898 +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
58899 +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
58900 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
58901 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
58902 +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
58903 +};
58904 +
58905 +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
58906 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
58907 +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
58908 +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
58909 +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
58910 +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
58911 +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
58912 +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
58913 +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
58914 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
58915 +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
58916 +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
58917 +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
58918 +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
58919 +};
58920 +
58921 +local const int base_length[LENGTH_CODES] = {
58922 +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
58923 +64, 80, 96, 112, 128, 160, 192, 224, 0
58924 +};
58925 +
58926 +local const int base_dist[D_CODES] = {
58927 + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
58928 + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
58929 + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
58930 +};
58931 +
58932 --- /dev/null Tue Mar 11 13:02:56 2003
58933 +++ linux/net/ipsec/ultoa.c Mon Feb 9 13:51:03 2004
58934 @@ -0,0 +1,66 @@
58935 +/*
58936 + * convert unsigned long to ASCII
58937 + * Copyright (C) 1998, 1999 Henry Spencer.
58938 + *
58939 + * This library is free software; you can redistribute it and/or modify it
58940 + * under the terms of the GNU Library General Public License as published by
58941 + * the Free Software Foundation; either version 2 of the License, or (at your
58942 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
58943 + *
58944 + * This library is distributed in the hope that it will be useful, but
58945 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
58946 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
58947 + * License for more details.
58948 + *
58949 + * RCSID $Id: ultoa.c,v 1.10 2004/07/10 07:48:37 mcr Exp $
58950 + */
58951 +#include "openswan.h"
58952 +
58953 +/*
58954 + - ultoa - convert unsigned long to decimal ASCII
58955 + */
58956 +size_t /* length required for full conversion */
58957 +ultoa(n, base, dst, dstlen)
58958 +unsigned long n;
58959 +int base;
58960 +char *dst; /* need not be valid if dstlen is 0 */
58961 +size_t dstlen;
58962 +{
58963 + char buf[3*sizeof(unsigned long) + 1];
58964 + char *bufend = buf + sizeof(buf);
58965 + size_t len;
58966 + char *p;
58967 + static char hex[] = "0123456789abcdef";
58968 +
58969 + p = bufend;
58970 + *--p = '\0';
58971 + if (base == 10) {
58972 + do {
58973 + *--p = n%10 + '0';
58974 + n /= 10;
58975 + } while (n != 0);
58976 + } else if (base == 16) {
58977 + do {
58978 + *--p = hex[n&0xf];
58979 + n >>= 4;
58980 + } while (n != 0);
58981 + *--p = 'x';
58982 + *--p = '0';
58983 + } else if (base == 8) {
58984 + do {
58985 + *--p = (n&07) + '0';
58986 + n >>= 3;
58987 + } while (n != 0);
58988 + *--p = '0';
58989 + } else
58990 + *--p = '?';
58991 +
58992 + len = bufend - p;
58993 +
58994 + if (dstlen > 0) {
58995 + if (len > dstlen)
58996 + *(p + dstlen - 1) = '\0';
58997 + strcpy(dst, p);
58998 + }
58999 + return len;
59000 +}
59001 --- /dev/null Tue Mar 11 13:02:56 2003
59002 +++ linux/net/ipsec/ultot.c Mon Feb 9 13:51:03 2004
59003 @@ -0,0 +1,82 @@
59004 +/*
59005 + * convert unsigned long to text
59006 + * Copyright (C) 2000 Henry Spencer.
59007 + *
59008 + * This library is free software; you can redistribute it and/or modify it
59009 + * under the terms of the GNU Library General Public License as published by
59010 + * the Free Software Foundation; either version 2 of the License, or (at your
59011 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
59012 + *
59013 + * This library is distributed in the hope that it will be useful, but
59014 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
59015 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
59016 + * License for more details.
59017 + *
59018 + * RCSID $Id: ultot.c,v 1.5 2004/07/10 07:48:37 mcr Exp $
59019 + */
59020 +#include "openswan.h"
59021 +
59022 +/*
59023 + - ultot - convert unsigned long to text
59024 + */
59025 +size_t /* length required for full conversion */
59026 +ultot(n, base, dst, dstlen)
59027 +unsigned long n;
59028 +int base;
59029 +char *dst; /* need not be valid if dstlen is 0 */
59030 +size_t dstlen;
59031 +{
59032 + char buf[3*sizeof(unsigned long) + 1];
59033 + char *bufend = buf + sizeof(buf);
59034 + size_t len;
59035 + char *p;
59036 + static char hex[] = "0123456789abcdef";
59037 +# define HEX32 (32/4)
59038 +
59039 + p = bufend;
59040 + *--p = '\0';
59041 + switch (base) {
59042 + case 10:
59043 + case 'd':
59044 + do {
59045 + *--p = n%10 + '0';
59046 + n /= 10;
59047 + } while (n != 0);
59048 + break;
59049 + case 16:
59050 + case 17:
59051 + case 'x':
59052 + do {
59053 + *--p = hex[n&0xf];
59054 + n >>= 4;
59055 + } while (n != 0);
59056 + if (base == 17)
59057 + while (bufend - p < HEX32 + 1)
59058 + *--p = '0';
59059 + if (base == 'x') {
59060 + *--p = 'x';
59061 + *--p = '0';
59062 + }
59063 + break;
59064 + case 8:
59065 + case 'o':
59066 + do {
59067 + *--p = (n&07) + '0';
59068 + n >>= 3;
59069 + } while (n != 0);
59070 + if (base == 'o')
59071 + *--p = '0';
59072 + break;
59073 + default:
59074 + return 0;
59075 + break;
59076 + }
59077 +
59078 + len = bufend - p;
59079 + if (dstlen > 0) {
59080 + if (len > dstlen)
59081 + *(p + dstlen - 1) = '\0';
59082 + strcpy(dst, p);
59083 + }
59084 + return len;
59085 +}
59086 --- /dev/null Tue Mar 11 13:02:56 2003
59087 +++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004
59088 @@ -0,0 +1,44 @@
59089 +/*
59090 + * return IPsec version information
59091 + * Copyright (C) 2001 Henry Spencer.
59092 + *
59093 + * This library is free software; you can redistribute it and/or modify it
59094 + * under the terms of the GNU Library General Public License as published by
59095 + * the Free Software Foundation; either version 2 of the License, or (at your
59096 + * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
59097 + *
59098 + * This library is distributed in the hope that it will be useful, but
59099 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
59100 + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
59101 + * License for more details.
59102 + *
59103 + * RCSID $Id: version.in.c,v 1.2 2004/04/14 05:09:46 ken Exp $
59104 + */
59105 +
59106 +#ifdef __KERNEL__
59107 +#include <linux/netdevice.h>
59108 +#endif
59109 +
59110 +#include "openswan.h"
59111 +
59112 +#define V "2.4.9" /* substituted in by Makefile */
59113 +static const char openswan_number[] = V;
59114 +static const char openswan_string[] = "Openswan " V;
59115 +
59116 +/*
59117 + - ipsec_version_code - return IPsec version number/code, as string
59118 + */
59119 +const char *
59120 +ipsec_version_code()
59121 +{
59122 + return openswan_number;
59123 +}
59124 +
59125 +/*
59126 + - ipsec_version_string - return full version string
59127 + */
59128 +const char *
59129 +ipsec_version_string()
59130 +{
59131 + return openswan_string;
59132 +}
59133 --- /dev/null Tue Mar 11 13:02:56 2003
59134 +++ linux/net/ipsec/zutil.c Mon Feb 9 13:51:03 2004
59135 @@ -0,0 +1,227 @@
59136 +/* zutil.c -- target dependent utility functions for the compression library
59137 + * Copyright (C) 1995-2002 Jean-loup Gailly.
59138 + * For conditions of distribution and use, see copyright notice in zlib.h
59139 + */
59140 +
59141 +/* @(#) $Id: zutil.c,v 1.5 2004/07/10 07:48:40 mcr Exp $ */
59142 +
59143 +#include <zlib/zutil.h>
59144 +
59145 +#define MY_ZCALLOC
59146 +
59147 +struct internal_state {int dummy;}; /* for buggy compilers */
59148 +
59149 +#ifndef STDC
59150 +extern void exit OF((int));
59151 +#endif
59152 +
59153 +const char *z_errmsg[10] = {
59154 +"need dictionary", /* Z_NEED_DICT 2 */
59155 +"stream end", /* Z_STREAM_END 1 */
59156 +"", /* Z_OK 0 */
59157 +"file error", /* Z_ERRNO (-1) */
59158 +"stream error", /* Z_STREAM_ERROR (-2) */
59159 +"data error", /* Z_DATA_ERROR (-3) */
59160 +"insufficient memory", /* Z_MEM_ERROR (-4) */
59161 +"buffer error", /* Z_BUF_ERROR (-5) */
59162 +"incompatible version",/* Z_VERSION_ERROR (-6) */
59163 +""};
59164 +
59165 +
59166 +const char * ZEXPORT zlibVersion()
59167 +{
59168 + return ZLIB_VERSION;
59169 +}
59170 +
59171 +#ifdef DEBUG
59172 +
59173 +# ifndef verbose
59174 +# define verbose 0
59175 +# endif
59176 +int z_verbose = verbose;
59177 +
59178 +void z_error (m)
59179 + char *m;
59180 +{
59181 + fprintf(stderr, "%s\n", m);
59182 + exit(1);
59183 +}
59184 +#endif
59185 +
59186 +/* exported to allow conversion of error code to string for compress() and
59187 + * uncompress()
59188 + */
59189 +const char * ZEXPORT zError(err)
59190 + int err;
59191 +{
59192 + return ERR_MSG(err);
59193 +}
59194 +
59195 +
59196 +#ifndef HAVE_MEMCPY
59197 +
59198 +void zmemcpy(dest, source, len)
59199 + Bytef* dest;
59200 + const Bytef* source;
59201 + uInt len;
59202 +{
59203 + if (len == 0) return;
59204 + do {
59205 + *dest++ = *source++; /* ??? to be unrolled */
59206 + } while (--len != 0);
59207 +}
59208 +
59209 +int zmemcmp(s1, s2, len)
59210 + const Bytef* s1;
59211 + const Bytef* s2;
59212 + uInt len;
59213 +{
59214 + uInt j;
59215 +
59216 + for (j = 0; j < len; j++) {
59217 + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
59218 + }
59219 + return 0;
59220 +}
59221 +
59222 +void zmemzero(dest, len)
59223 + Bytef* dest;
59224 + uInt len;
59225 +{
59226 + if (len == 0) return;
59227 + do {
59228 + *dest++ = 0; /* ??? to be unrolled */
59229 + } while (--len != 0);
59230 +}
59231 +#endif
59232 +
59233 +#ifdef __TURBOC__
59234 +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
59235 +/* Small and medium model in Turbo C are for now limited to near allocation
59236 + * with reduced MAX_WBITS and MAX_MEM_LEVEL
59237 + */
59238 +# define MY_ZCALLOC
59239 +
59240 +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
59241 + * and farmalloc(64K) returns a pointer with an offset of 8, so we
59242 + * must fix the pointer. Warning: the pointer must be put back to its
59243 + * original form in order to free it, use zcfree().
59244 + */
59245 +
59246 +#define MAX_PTR 10
59247 +/* 10*64K = 640K */
59248 +
59249 +local int next_ptr = 0;
59250 +
59251 +typedef struct ptr_table_s {
59252 + voidpf org_ptr;
59253 + voidpf new_ptr;
59254 +} ptr_table;
59255 +
59256 +local ptr_table table[MAX_PTR];
59257 +/* This table is used to remember the original form of pointers
59258 + * to large buffers (64K). Such pointers are normalized with a zero offset.
59259 + * Since MSDOS is not a preemptive multitasking OS, this table is not
59260 + * protected from concurrent access. This hack doesn't work anyway on
59261 + * a protected system like OS/2. Use Microsoft C instead.
59262 + */
59263 +
59264 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
59265 +{
59266 + voidpf buf = opaque; /* just to make some compilers happy */
59267 + ulg bsize = (ulg)items*size;
59268 +
59269 + /* If we allocate less than 65520 bytes, we assume that farmalloc
59270 + * will return a usable pointer which doesn't have to be normalized.
59271 + */
59272 + if (bsize < 65520L) {
59273 + buf = farmalloc(bsize);
59274 + if (*(ush*)&buf != 0) return buf;
59275 + } else {
59276 + buf = farmalloc(bsize + 16L);
59277 + }
59278 + if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
59279 + table[next_ptr].org_ptr = buf;
59280 +
59281 + /* Normalize the pointer to seg:0 */
59282 + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
59283 + *(ush*)&buf = 0;
59284 + table[next_ptr++].new_ptr = buf;
59285 + return buf;
59286 +}
59287 +
59288 +void zcfree (voidpf opaque, voidpf ptr)
59289 +{
59290 + int n;
59291 + if (*(ush*)&ptr != 0) { /* object < 64K */
59292 + farfree(ptr);
59293 + return;
59294 + }
59295 + /* Find the original pointer */
59296 + for (n = 0; n < next_ptr; n++) {
59297 + if (ptr != table[n].new_ptr) continue;
59298 +
59299 + farfree(table[n].org_ptr);
59300 + while (++n < next_ptr) {
59301 + table[n-1] = table[n];
59302 + }
59303 + next_ptr--;
59304 + return;
59305 + }
59306 + ptr = opaque; /* just to make some compilers happy */
59307 + Assert(0, "zcfree: ptr not found");
59308 +}
59309 +#endif
59310 +#endif /* __TURBOC__ */
59311 +
59312 +
59313 +#if defined(M_I86) && !defined(__32BIT__)
59314 +/* Microsoft C in 16-bit mode */
59315 +
59316 +# define MY_ZCALLOC
59317 +
59318 +#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
59319 +# define _halloc halloc
59320 +# define _hfree hfree
59321 +#endif
59322 +
59323 +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
59324 +{
59325 + if (opaque) opaque = 0; /* to make compiler happy */
59326 + return _halloc((long)items, size);
59327 +}
59328 +
59329 +void zcfree (voidpf opaque, voidpf ptr)
59330 +{
59331 + if (opaque) opaque = 0; /* to make compiler happy */
59332 + _hfree(ptr);
59333 +}
59334 +
59335 +#endif /* MSC */
59336 +
59337 +
59338 +#ifndef MY_ZCALLOC /* Any system without a special alloc function */
59339 +
59340 +#ifndef STDC
59341 +extern voidp calloc OF((uInt items, uInt size));
59342 +extern void free OF((voidpf ptr));
59343 +#endif
59344 +
59345 +voidpf zcalloc (opaque, items, size)
59346 + voidpf opaque;
59347 + unsigned items;
59348 + unsigned size;
59349 +{
59350 + if (opaque) items += size - size; /* make compiler happy */
59351 + return (voidpf)calloc(items, size);
59352 +}
59353 +
59354 +void zcfree (opaque, ptr)
59355 + voidpf opaque;
59356 + voidpf ptr;
59357 +{
59358 + free(ptr);
59359 + if (opaque) return; /* make compiler happy */
59360 +}
59361 +
59362 +#endif /* MY_ZCALLOC */
59363 --- swan26/net/ipv4/af_inet.c.orig Wed Jun 16 01:18:58 2004
59364 +++ swan26/net/ipv4/af_inet.c Fri Aug 13 23:09:27 2004
59365 @@ -1169,6 +1169,18 @@
59366 #if defined(CONFIG_IP_MROUTE)
59367 ip_mr_init();
59368 #endif
59369 +
59370 +#if defined(CONFIG_KLIPS)
59371 + {
59372 + extern int ipsec_klips_init(void);
59373 + /*
59374 + * Initialise AF_INET ESP and AH protocol support including
59375 + * e-routing and SA tables
59376 + */
59377 + ipsec_klips_init();
59378 + }
59379 +#endif /* CONFIG_IPSEC */
59380 +
59381 /*
59382 * Initialise per-cpu ipv4 mibs
59383 */
59384 --- /dev/null Fri May 10 13:59:54 2002
59385 +++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002
59386 @@ -0,0 +1 @@
59387 +IPSECVERSION=2.4.9