diff -urN linux-2.4.29/Documentation/Configure.help linux-2.4.29-openswan-1.0.9/Documentation/Configure.help --- linux-2.4.29/Documentation/Configure.help Mon Jan 31 22:01:10 2005 +++ linux-2.4.29-openswan-1.0.9/Documentation/Configure.help Sun Feb 6 16:33:51 2005 @@ -6363,6 +6363,59 @@ See configuration for Cryptographic API and enable these algorithms to make usable by SCTP. +IP Security Protocol (IPSEC) (EXPERIMENTAL) +CONFIG_IPSEC + This unit is experimental code. + Pick 'y' for static linking, 'm' for module support or 'n' for none. + This option adds support for network layer packet encryption and/or + authentication with participating hosts. The standards start with: + RFCs 2411, 2407 and 2401. Others are mentioned where they refer to + specific features below. There are more pending which can be found + at: ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*. + A description of each document can also be found at: + http://ietf.org/ids.by.wg/ipsec.html. + Their charter can be found at: + http://www.ietf.org/html.charters/ipsec-charter.html + Snapshots and releases of the current work can be found at: + http://www.freeswan.org/ + +IPSEC: IP-in-IP encapsulation +CONFIG_IPSEC_IPIP + This option provides support for tunnel mode IPSEC. It is recommended + to enable this. + +IPSEC: Authentication Header +CONFIG_IPSEC_AH + This option provides support for the IPSEC Authentication Header + (IP protocol 51) which provides packet layer sender and content + authentication. It is recommended to enable this. RFC2402 + +HMAC-MD5 algorithm +CONFIG_IPSEC_AUTH_HMAC_MD5 + Provides support for authentication using the HMAC MD5 + algorithm with 96 bits of hash used as the authenticator. RFC2403 + +HMAC-SHA1 algorithm +CONFIG_IPSEC_AUTH_HMAC_SHA1 + Provides support for Authentication Header using the HMAC SHA1 + algorithm with 96 bits of hash used as the authenticator. RFC2404 + +IPSEC: Encapsulating Security Payload +CONFIG_IPSEC_ESP + This option provides support for the IPSEC Encapsulation Security + Payload (IP protocol 50) which provides packet layer content + hiding. It is recommended to enable this. RFC2406 + +3DES algorithm +CONFIG_IPSEC_ENC_3DES + Provides support for Encapsulation Security Payload protocol, using + the triple DES encryption algorithm. RFC2451 + +IPSEC Debugging Option +CONFIG_IPSEC_DEBUG + Enables IPSEC kernel debugging. It is further controlled by the + user space utility 'klipsdebug'. + Kernel httpd acceleration CONFIG_KHTTPD The kernel httpd acceleration daemon (kHTTPd) is a (limited) web diff -urN linux-2.4.29/arch/i386/defconfig linux-2.4.29-openswan-1.0.9/arch/i386/defconfig --- linux-2.4.29/arch/i386/defconfig Mon Jan 31 22:01:10 2005 +++ linux-2.4.29-openswan-1.0.9/arch/i386/defconfig Sun Feb 6 16:32:40 2005 @@ -948,3 +948,143 @@ CONFIG_CRC32=y # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set + +# +# RCSID $Id: defconfig,v 1.6 2004/10/25 19:29:13 ken Exp $ +# + +# +# FreeS/WAN IPSec implementation, KLIPS kernel config defaults +# + +# +# First, lets override stuff already set or not in the kernel config. +# +# We can't even think about leaving this off... +CONFIG_INET=y + +# +# This must be on for subnet protection. +CONFIG_IP_FORWARD=y + +# Shut off IPSEC masquerading if it has been enabled, since it will +# break the compile. IPPROTO_ESP and IPPROTO_AH were included in +# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h. +CONFIG_IP_MASQUERADE_IPSEC=n + +# +# Next, lets set the recommended FreeS/WAN configuration. +# + +# To config as static (preferred), 'y'. To config as module, 'm'. +CONFIG_IPSEC=m + +# To do tunnel mode IPSec, this must be enabled. +CONFIG_IPSEC_IPIP=y + +# To enable authentication, say 'y'. (Highly recommended) +CONFIG_IPSEC_AH=y + +# Authentication algorithm(s): +CONFIG_IPSEC_AUTH_HMAC_MD5=y +CONFIG_IPSEC_AUTH_HMAC_SHA1=y + +# To enable encryption, say 'y'. (Highly recommended) +CONFIG_IPSEC_ESP=y + +# Encryption algorithm(s): +CONFIG_IPSEC_ENC_3DES=y + +# IP Compression: new, probably still has minor bugs. +CONFIG_IPSEC_IPCOMP=y + +# To enable userspace-switchable KLIPS debugging, say 'y'. +CONFIG_IPSEC_DEBUG=y + +# modular algo extensions (and new ALGOs) +CONFIG_IPSEC_ALG=y +CONFIG_IPSEC_ALG_AES=m +CONFIG_IPSEC_ALG_TWOFISH=m +CONFIG_IPSEC_ALG_SERPENT=m +CONFIG_IPSEC_ALG_MD5=m +CONFIG_IPSEC_ALG_SHA1=m +CONFIG_IPSEC_ALG_SHA2=m +CONFIG_IPSEC_ALG_3DES=m +CONFIG_IPSEC_ALG_BLOWFISH=m + +# NAT Traversal +CONFIG_IPSEC_NAT_TRAVERSAL=y + +# Use CryptoAPI for ALG? +CONFIG_IPSEC_ALG_CRYPTOAPI=n + +# NAT Traversal +CONFIG_IPSEC_NAT_TRAVERSAL=y + +# +# +# $Log: defconfig,v $ +# Revision 1.6 2004/10/25 19:29:13 ken +# Add defaults for modular algs +# +# Revision 1.5 2003/07/04 19:07:34 ken +# Added NAT-T 0.6 diff/patch from Tuomo +# +# Revision 1.4 2003/02/21 22:59:21 ken +# Set default for CONFIG_IPSEC_ALG_CRYPTOAPI=n +# +# Revision 1.3 2002/09/05 16:50:58 ken +# Enabled NAT-T by default +# +# Revision 1.2 2002/09/05 03:27:08 ken +# Applied freeswan-alg-0.8.0-BASE-klips.diff +# +# Revision 1.1.1.1 2002/09/05 03:13:17 ken +# 1.98b +# +# Revision 1.20 2002/04/02 04:07:40 mcr +# default build is now 'm'odule for KLIPS +# +# Revision 1.19 2002/03/08 18:57:17 rgb +# Added a blank line at the beginning of the file to make it easier for +# other projects to patch ./arch/i386/defconfig, for example +# LIDS+grSecurity requested by Jason Pattie. +# +# Revision 1.18 2000/11/30 17:26:56 rgb +# Cleaned out unused options and enabled ipcomp by default. +# +# Revision 1.17 2000/09/15 11:37:01 rgb +# Merge in heavily modified Svenning Soerensen's +# IPCOMP zlib deflate code. +# +# Revision 1.16 2000/09/08 19:12:55 rgb +# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. +# +# Revision 1.15 2000/05/24 19:37:13 rgb +# *** empty log message *** +# +# Revision 1.14 2000/05/11 21:14:57 henry +# just commenting the FOOBAR=y lines out is not enough +# +# Revision 1.13 2000/05/10 20:17:58 rgb +# Comment out netlink defaults, which are no longer needed. +# +# Revision 1.12 2000/05/10 19:13:38 rgb +# Added configure option to shut off no eroute passthrough. +# +# Revision 1.11 2000/03/16 07:09:46 rgb +# Hardcode PF_KEYv2 support. +# Disable IPSEC_ICMP by default. +# Remove DES config option from defaults file. +# +# Revision 1.10 2000/01/11 03:09:42 rgb +# Added a default of 'y' to PF_KEYv2 keying I/F. +# +# Revision 1.9 1999/05/08 21:23:12 rgb +# Added support for 2.2.x kernels. +# +# Revision 1.8 1999/04/06 04:54:25 rgb +# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes +# patch shell fixes. +# +# diff -urN linux-2.4.29/include/net/sock.h linux-2.4.29-openswan-1.0.9/include/net/sock.h --- linux-2.4.29/include/net/sock.h Sat Feb 5 16:12:55 2005 +++ linux-2.4.29-openswan-1.0.9/include/net/sock.h Sun Feb 6 16:32:39 2005 @@ -488,7 +488,12 @@ } bictcp; }; - +#if 1 +struct udp_opt { + __u32 esp_in_udp; +}; +#endif + /* * This structure really needs to be cleaned up. * Most of it is for TCP, and not used by any of @@ -655,6 +660,9 @@ #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE) struct spx_opt af_spx; #endif /* CONFIG_SPX */ +#if 1 + struct udp_opt af_udp; +#endif } tp_pinfo; diff -urN linux-2.4.29/net/Config.in linux-2.4.29-openswan-1.0.9/net/Config.in --- linux-2.4.29/net/Config.in Mon Jan 31 22:01:10 2005 +++ linux-2.4.29-openswan-1.0.9/net/Config.in Sun Feb 6 16:32:39 2005 @@ -104,4 +104,9 @@ dep_tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN $CONFIG_PROC_FS endmenu +tristate 'IP Security Protocol (Openswan IPsec Stack)' CONFIG_IPSEC +if [ "$CONFIG_IPSEC" != "n" ]; then + source net/ipsec/Config.in +fi + endmenu diff -urN linux-2.4.29/net/Makefile linux-2.4.29-openswan-1.0.9/net/Makefile --- linux-2.4.29/net/Makefile Sat Jul 31 18:45:19 2004 +++ linux-2.4.29-openswan-1.0.9/net/Makefile Sun Feb 6 16:32:39 2005 @@ -18,6 +18,7 @@ subdir-$(CONFIG_IPV6) += ipv6 subdir-$(CONFIG_INET) += ipv4 subdir-$(CONFIG_NETFILTER) += ipv4/netfilter +subdir-$(CONFIG_IPSEC) += ipsec subdir-$(CONFIG_UNIX) += unix subdir-$(CONFIG_IP_SCTP) += sctp diff -urN linux-2.4.29/net/ipsec/Config.in linux-2.4.29-openswan-1.0.9/net/ipsec/Config.in --- linux-2.4.29/net/ipsec/Config.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/Config.in Thu Sep 5 05:53:52 2002 @@ -0,0 +1,63 @@ +# +# IPSEC configuration +# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See . +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# RCSID $Id: Config.in,v 1.3 2002/09/05 03:53:52 ken Exp $ + +comment 'IPSec options (FreeS/WAN)' + +bool ' IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP + +bool ' IPSEC: Authentication Header' CONFIG_IPSEC_AH +if [ "$CONFIG_IPSEC_AH" = "y" -o "$CONFIG_IPSEC_ESP" = "y" ]; then + bool ' HMAC-MD5 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_MD5 + bool ' HMAC-SHA1 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_SHA1 +fi + +bool ' IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP +if [ "$CONFIG_IPSEC_ESP" = "y" ]; then + bool ' 3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES +fi + +bool ' IPSEC Modular Extensions' CONFIG_IPSEC_ALG +if [ "$CONFIG_IPSEC_ALG" != "n" ]; then + source net/ipsec/alg/Config.in +fi + +bool ' IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP + +bool ' IPSEC Debugging Option' CONFIG_IPSEC_DEBUG + +bool ' IPSEC NAT-Traversal' CONFIG_IPSEC_NAT_TRAVERSAL + +# +# +# $Log: Config.in,v $ +# Revision 1.3 2002/09/05 03:53:52 ken +# Added NAT-T Patch +# +# Revision 1.2 2002/09/05 03:27:08 ken +# Applied freeswan-alg-0.8.0-BASE-klips.diff +# +# Revision 1.1.1.1 2002/09/05 03:13:17 ken +# 1.98b +# +# Revision 1.25 2002/02/21 19:55:12 mcr +# removed all traces of IPSEC_CONFIG_REGRESS because it +# screwed up 2.2's "make menuconfig" scripts. +# +# Revision 1.24 2002/01/28 20:24:31 mcr +# commented out IPSEC_REGRESS option from user visible config. +# +# + diff -urN linux-2.4.29/net/ipsec/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/Makefile --- linux-2.4.29/net/ipsec/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/Makefile Thu Dec 18 21:44:24 2003 @@ -0,0 +1,339 @@ +# Makefile for KLIPS kernel code +# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See . +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# RCSID $Id: Makefile,v 1.5 2003/12/18 20:44:24 ken Exp $ +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definition is now in the main makefile... + +ifndef TOPDIR +TOPDIR := /usr/src/linux +endif + +subdir- := +subdir-n := +subdir-y := +subdir-m := + +O_TARGET := ipsec.o +obj-y := ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o +obj-y += ipsec_life.o ipsec_proc.o +obj-y += ipsec_tunnel.o ipsec_rcv.o sysctl_net_ipsec.o +obj-y += pfkey_v2.o pfkey_v2_parser.o + +export-objs := radij.o + +obj-$(CONFIG_IPSEC_ALG) +=ipsec_alg.o alg/ipsec_alg_static.o +export-objs += ipsec_alg.o +subdir-m += alg + +# 'override CFLAGS' should really be 'EXTRA_CFLAGS' +EXTRA_CFLAGS += -Ilibopenswan -Ilibdes +ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.2-2) +EXTRA_CFLAGS += -DREDHAT_BOGOSITY +endif +ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.3-12) +EXTRA_CFLAGS += -DREDHAT_BOGOSITY +endif + +#ifeq ($(CONFIG_IPSEC_DEBUG),y) +#EXTRA_CFLAGS += -g +#endif + +EXTRA_CFLAGS += $(KLIPSCOMPILE) +EXTRA_CFLAGS += -Wall +#EXTRA_CFLAGS += -Werror +#EXTRA_CFLAGS += -Wconversion +#EXTRA_CFLAGS += -Wmissing-prototypes +EXTRA_CFLAGS += -Wpointer-arith +#EXTRA_CFLAGS += -Wcast-qual +#EXTRA_CFLAGS += -Wmissing-declarations +EXTRA_CFLAGS += -Wstrict-prototypes +#EXTRA_CFLAGS += -pedantic +#EXTRA_CFLAGS += -O3 +#EXTRA_CFLAGS += -W +#EXTRA_CFLAGS += -Wwrite-strings +#EXTRA_CFLAGS += -Wbad-function-cast + +obj-$(CONFIG_IPSEC_ENC_3DES) += libdes/libdes.a +obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o +obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o +obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o zlib/zlib.a +subdir-$(CONFIG_IPSEC_IPCOMP) += zlib +subdir-$(CONFIG_IPSEC) += libopenswan +obj-y += libopenswan/libkernel.a + +### +### Pre Rules.make +### +# undo O_TARGET, obj-y if no static +ifneq ($(CONFIG_IPSEC),y) +O_TARGET := +ipsec_obj-y := $(obj-y) +obj-y := +subdir-y := +endif + +# Define obj-m if modular ipsec +ifeq ($(CONFIG_IPSEC),m) +obj-m += ipsec.o +endif + + +# These rules translate from new to old makefile rules +# Translate to Rules.make lists. +multi-used := $(filter $(list-multi), $(obj-y) $(obj-m)) +multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs)) +active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m)) +O_OBJS := $(obj-y) +M_OBJS := $(obj-m) +MIX_OBJS := $(filter $(export-objs), $(active-objs)) +OX_OBJS := $(export-objs) +SUB_DIRS := $(subdir-y) +ALL_SUB_DIRS := $(subdir-y) $(subdir-m) +MOD_SUB_DIRS := $(subdir-m) + +# dunno why, but some 2.2 setups may need explicit -DEXPORT_SYMTAB +# uncomment next line if ipsec_alg.c compilation fails with +# "parse error before `EXPORT_SYMTAB_not_defined'" --Juanjo +# CFLAGS_ipsec_alg.o += -DEXPORT_SYMTAB +# + +include $(TOPDIR)/Rules.make + +### +### Post Rules.make +### +# for modular ipsec, no O_TARGET defined => define ipsec.o creation rules +ifeq ($(CONFIG_IPSEC),m) +ipsec.o : $(ipsec_obj-y) + rm -f $@ + $(LD) $(LD_EXTRAFLAGS) -r $(ipsec_obj-y) -o $@ +endif + +$(ipsec_obj-y) $(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h + +libdes/libdes.a: + ( cd libdes && \ + if test " $(ARCH)" = " i386" ; \ + then $(MAKE) CC='$(CC)' CFLAG='$(CFLAGS)' TESTING='' x86-elf ; \ + else $(MAKE) CC='$(CC)' CFLAG='$(CFLAGS)' libdes.a ; \ + fi ) + +libopenswan/libkernel.a: + $(MAKE) -C libopenswan + +zlib/zlib.a: + $(MAKE) -C zlib + +alg/ipsec_alg_static.o: dummy + $(MAKE) -C alg CC='$(CC)' CFLAGS='$(CFLAGS)' ipsec_alg_static.o + +clean: + $(MAKE) -C alg clean + -rm -f *.o + +tags TAGS: *.c *.h libopenswan/*.c libopenswan/*.h + find . -name '*.[ch]' |xargs etags + find . -name '*.[ch]' |xargs ctags + +tar: + tar -cvf /dev/f1 . + +# +# $Log: Makefile,v $ +# Revision 1.5 2003/12/18 20:44:24 ken +# Fix for cross compiling - we can count on being set now +# +# Revision 1.4 2003/11/19 02:29:41 mcr +# renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. +# +# Revision 1.3 2003/02/07 13:14:24 ken +# Pullin jjo's ALG 0.8.1rc branch +# +# Revision 1.2.2.1 2003/02/06 22:09:49 jjo +# sync to alg-0.8.1-rc4 +# +# Revision 1.2 2002/09/05 03:27:08 ken +# Applied freeswan-alg-0.8.0-BASE-klips.diff +# +# Revision 1.1.1.1 2002/09/05 03:13:17 ken +# 1.98b +# +# Revision 1.39 2002/01/17 04:39:40 rgb +# Take compile options from top level Makefile.inc +# +# Revision 1.38 2001/11/27 05:28:07 rgb +# Shut off -Werror until we figure out a graceful way of quieting down the +# pfkey_ops defined but not used complaint in the case of SMP in +# pfkey_v2.c. +# +# Revision 1.37 2001/11/27 05:10:15 rgb +# Added -Ilibdes and removed lib/des* symlinks. +# +# Revision 1.36 2001/11/26 09:23:47 rgb +# Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. +# +# Revision 1.35.2.1 2001/09/25 02:17:50 mcr +# added ipsec_sa, ipsec_life, ipsec_proc. +# added -Werror to compile flags (see fix for zlib/zutil.h) +# +# Revision 1.3 2001/09/21 04:41:26 mcr +# actually, ipsec_proc.c and ipsec_life.c were never actually compiled. +# +# Revision 1.2 2001/09/21 04:11:33 mcr +# first compilable version. +# +# Revision 1.1.1.2 2001/09/17 01:17:52 mcr +# snapshot 2001-09-16 +# +# Revision 1.35 2001/09/07 22:09:12 rgb +# Quiet down compilation. +# +# Revision 1.34 2001/08/11 17:10:23 henry +# update bogosity stuff to cover RH7.1 update +# +# Revision 1.33 2001/06/14 19:35:07 rgb +# Update copyright date. +# +# Revision 1.32 2001/06/13 21:00:50 rgb +# Added a kludge to get around RedHat kernel version bogosity... +# +# Revision 1.31 2001/01/29 22:19:06 rgb +# Convert to 2.4 new style with back compat. +# +# Revision 1.30 2000/09/29 19:51:57 rgb +# Moved klips/net/ipsec/ipcomp_* to zlib/* (Svenning). +# +# Revision 1.29 2000/09/15 11:37:01 rgb +# Merge in heavily modified Svenning Soerensen's +# IPCOMP zlib deflate code. +# +# Revision 1.28 2000/09/15 04:55:25 rgb +# Clean up pfkey object inclusion into the default object. +# +# Revision 1.27 2000/09/12 03:20:47 rgb +# Cleared out now unused pfkeyv2 switch. +# Enabled sysctl. +# +# Revision 1.26 2000/09/08 19:12:55 rgb +# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. +# +# Revision 1.25 2000/06/16 03:09:16 rgb +# Shut up cast lost warning due to changes in 2.4.0-test1. +# +# Revision 1.24 2000/03/16 06:40:48 rgb +# Hardcode PF_KEYv2 support. +# +# Revision 1.23 2000/02/14 21:10:38 rgb +# Added gcc debug flag when KLIPS_DEBUG is swtiched on. +# +# Revision 1.22 2000/01/21 09:44:29 rgb +# Added compiler switches to be a lot more fussy. +# +# Revision 1.21 1999/11/25 23:35:20 rgb +# Removed quotes to fix Alpha compile issues. +# +# Revision 1.20 1999/11/17 15:49:34 rgb +# Changed all occurrences of ../../../lib in pathnames to libfreeswan, +# which refers to the /usr/src/linux/net/ipsec/lib directory setup by the +# klink target in the top-level Makefile; and libdeslite.o to +# libdes/libdes.a. +# Added SUB_DIRS := lib definition for the kernel libraries. +# +# Revision 1.19 1999/04/27 19:06:47 rgb +# dd libs and dependancies to tags generation. +# +# Revision 1.18 1999/04/16 16:28:12 rgb +# Minor bugfix to avoid including DES if only AH is used. +# +# Revision 1.17 1999/04/15 15:37:23 rgb +# Forward check changes from POST1_00 branch. +# +# Revision 1.14.2.1 1999/03/30 17:29:17 rgb +# Add support for pfkey. +# +# Revision 1.16 1999/04/11 00:28:56 henry +# GPL boilerplate +# +# Revision 1.15 1999/04/06 04:54:25 rgb +# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes +# patch shell fixes. +# +# Revision 1.14 1999/02/18 16:50:45 henry +# update for new DES library +# +# Revision 1.13 1999/02/12 21:11:45 rgb +# Prepare for newer LIBDES (patch from P.Onion). +# +# Revision 1.12 1999/01/26 02:05:08 rgb +# Remove references to INET_GET_PROTOCOL. +# Removed CONFIG_IPSEC_ALGO_SWITCH macro. +# Change from transform switch to algorithm switch. +# +# Revision 1.11 1999/01/22 06:16:09 rgb +# Added algorithm switch code config option. +# +# Revision 1.10 1998/11/08 05:31:21 henry +# be a little fussier +# +# Revision 1.9 1998/11/08 05:29:41 henry +# revisions for new libdes handling +# +# Revision 1.8 1998/08/12 00:05:48 rgb +# Added new xforms to Makefile (moved des-cbc to des-old). +# +# Revision 1.7 1998/07/27 21:48:47 rgb +# Add libkernel. +# +# Revision 1.6 1998/07/14 15:50:47 rgb +# Add dependancies on linux config files. +# +# Revision 1.5 1998/07/09 17:44:06 rgb +# Added 'clean' and 'tags' targets. +# Added TOPDIR macro. +# Change module back from symbol exporting to not. +# +# Revision 1.3 1998/06/25 19:25:04 rgb +# Rearrange to support static linking and objects with exported symbol +# tables. +# +# Revision 1.1 1998/06/18 21:27:42 henry +# move sources from klips/src to klips/net/ipsec, to keep stupid +# kernel-build scripts happier in the presence of symlinks +# +# Revision 1.3 1998/04/15 23:18:43 rgb +# Unfixed the ../../libdes fix to avoid messing up Henry's script. +# +# Revision 1.2 1998/04/14 17:50:47 rgb +# Fixed to find the new location of libdes. +# +# Revision 1.1 1998/04/09 03:05:22 henry +# sources moved up from linux/net/ipsec +# modifications to centralize libdes code +# +# Revision 1.1.1.1 1998/04/08 05:35:02 henry +# RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 +# +# Revision 0.5 1997/06/03 04:24:48 ji +# Added ESP-3DES-MD5-96 +# +# Revision 0.4 1997/01/15 01:32:59 ji +# Added new transforms. +# +# Revision 0.3 1996/11/20 14:22:53 ji +# *** empty log message *** +# diff -urN linux-2.4.29/net/ipsec/Makefile.inc linux-2.4.29-openswan-1.0.9/net/ipsec/Makefile.inc --- linux-2.4.29/net/ipsec/Makefile.inc Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/Makefile.inc Sat Apr 26 04:27:17 2003 @@ -0,0 +1,182 @@ +# FreeS/WAN pathnames and other master configuration +# Copyright (C) 2001, 2002 Henry Spencer. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See . +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# RCSID $Id: Makefile.inc,v 1.3 2003/04/26 02:27:17 ken Exp $ + + + +# Variables in this file with names starting with INC_ are not for use +# by Makefiles which include it; they are subject to change without warning. +# +# "Final" and "finally" refer to where the files will end up on the +# running IPsec system, as opposed to where they get installed by our +# Makefiles. (The two are different for cross-compiles and the like, +# where our Makefiles are not the end of the installation process.) +# Paths with FINAL in their names are the only ones that the installed +# software itself depends on. (Very few things should know about the +# FINAL paths; think twice and consult Henry before making something new +# depend on them.) All other paths are install targets. +# See also DESTDIR, below. + + + +### boilerplate, do not change +SHELL=/bin/sh + + + +### install pathnames + +# DESTDIR can be used to supply a prefix to all install targets. +# (Note that "final" pathnames, signifying where files will eventually +# reside rather than where install puts them, are exempt from this.) +# The prefixing is done in this file, so as to have central control over +# it; DESTDIR itself should never appear in any other Makefile. +DESTDIR?= + +# "local" part of tree, used in building other pathnames +INC_USRLOCAL=/usr/local + +# PUBDIR is where the "ipsec" command goes; beware, many things define PATH +# settings which are assumed to include it (or at least, to include *some* +# copy of the "ipsec" command). +PUBDIR=$(DESTDIR)$(INC_USRLOCAL)/sbin + +# BINDIR is where commands get put, FINALBINDIR is where the "ipsec" +# command will look for them when it is run. +FINALBINDIR=$(INC_USRLOCAL)/lib/ipsec +BINDIR=$(DESTDIR)$(FINALBINDIR) + +# where the appropriate manpage tree is located +# location within INC_USRLOCAL +INC_MANDIR=man +# the full pathname +MANTREE=$(DESTDIR)$(INC_USRLOCAL)/$(INC_MANDIR) +# all relevant subdirectories of MANTREE +MANPLACES=man3 man5 man8 + +# where configuration files go +FINALCONFDIR=/etc +CONFDIR=$(DESTDIR)$(FINALCONFDIR) + +# An attempt is made to automatically figure out where boot/shutdown scripts +# will finally go: the first directory in INC_RCDIRS which exists gets them. +# If none of those exists (or INC_RCDIRS is empty), INC_RCDEFAULT gets them. +# With a non-null DESTDIR, INC_RCDEFAULT will be used unless one of the +# INC_RCDIRS directories has been pre-created under DESTDIR. +INC_RCDIRS=/etc/rc.d/init.d /etc/rc.d /etc/init.d /sbin/init.d +INC_RCDEFAULT=/etc/rc.d/init.d + +# RCDIR is where boot/shutdown scripts go; FINALRCDIR is where they think +# will finally be (so utils/Makefile can create a symlink in BINDIR to the +# place where the boot/shutdown script will finally be, rather than the +# place where it is installed). +FINALRCDIR=$(shell for d in $(INC_RCDIRS) ; \ + do if test -d $(DESTDIR)/$$d ; \ + then echo $$d ; exit 0 ; \ + fi ; done ; echo $(INC_RCDEFAULT) ) +RCDIR=$(DESTDIR)$(FINALRCDIR) + + + +### kernel pathnames + +# Kernel location: where patches are inserted, where kernel builds are done. +KERNELSRC?=/usr/src/linux + +# things whose existence indicates what kernel version we have +DIRIN22=$(KERNELSRC)/net/netlink +FILIN24=$(KERNELSRC)/net/khttpd/main.c + +# where kernel configuration outputs are located +KCFILE=$(KERNELSRC)/.config +ACFILE=$(KERNELSRC)/include/linux/autoconf.h +VERFILE=$(KERNELSRC)/include/linux/version.h + + + +### misc installation stuff + +# what program to use when installing things +INSTALL=install + +# flags to the install program, for programs, manpages, and config files +# -b has install make backups (n.b., unlinks original), --suffix controls +# how backup names are composed. +# Note that the install procedures will never overwrite an existing config +# file, which is why -b is not specified for them. +INSTBINFLAGS=-b --suffix=.old +INSTMANFLAGS= +INSTCONFFLAGS= + + + +### misc configuration, included here in hopes that other files will not +### have to be changed for common customizations. + +# extra compile flags, for userland and kernel stuff, e.g. -g for debug info +# (caution, this stuff is still being sorted out, will change in future) +USERCOMPILE=-g -O3 +KLIPSCOMPILE=-O3 + +# command used to link/copy KLIPS into kernel source tree +# There are good reasons why this is "ln -s"; only people like distribution +# builders should ever change it. +KLIPSLINK=ln -s + +# extra options for use in kernel build +KERNMAKEOPTS= + +# kernel Makefile targets to be done before build +# Can be overridden if you are *sure* your kernel doesn't need them. (2.2.xx +# and later reportedly do not.) +KERNDEP=dep +KERNCLEAN=clean + +# kernel make name: zImage for 2.0.xx, bzImage for 2.2.xx and later, and +# boot on non-x86s (what ever happened to standards?) +INC_B=$(shell test -d $(DIRIN22) && echo b) +KERNEL=$(shell if expr " `uname -m`" : ' i.86' >/dev/null ; \ + then echo $(INC_B)zImage ; \ + else echo boot ; \ + fi) + +# temporary directory to be used when building RPMs, and where to put the +# resulting RPM tree +RPMKERNDIR := $(shell echo `pwd`/tmp.rpmkernel) +RPMTMPDIR := $(shell echo `pwd`/tmp.rpmbuild) +RPMDEST := $(shell echo `pwd`/rpms) +# Newer versions of RPM do not permit building of packages with the "rpm" +# command. For RedHat systems with older version of RPM, use: +# RPMBUILD=rpm +# instead. +RPMBUILD=rpmbuild + +# +# Set this to a RedHat kernel-sources RPM. This normally extracts into +# /usr/src/linux-2.4, but you might have extracted it elsewhere with +# rpm2cpio. +# +RH_KERNELSRC=/usr/src/linux-2.4 + +#RH_KERNELSRC=/a3/kernel_sources/linux-2.4.2 +#RH_KERNELSRC=/a3/kernel_sources/linux-2.4.9-13 +#RH_KERNELSRC=/c2/kernel/rh/linux-2.4.9-13 + +# the following is a list of symbols which will be used to construct +# the module goo to identify which module goes with each kernel. +MODULE_GOO_LIST=irq_stat netif_rx register_sysctl_table send_sig +MODULE_GOO_LIST+=kmalloc __kfree_skb __ip_select_ident alloc_skb +MODULE_GOO_LIST+=icmp_send ip_fragment sock_register + + diff -urN linux-2.4.29/net/ipsec/Makefile.ver linux-2.4.29-openswan-1.0.9/net/ipsec/Makefile.ver --- linux-2.4.29/net/ipsec/Makefile.ver Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/Makefile.ver Tue Jan 25 14:54:44 2005 @@ -0,0 +1 @@ +IPSECVERSION=1.0.9 diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_1des.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_1des.in --- linux-2.4.29/net/ipsec/alg/Config.alg_1des.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_1des.in Fri Feb 7 15:39:36 2003 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' 1DES **INSECURE** encryption algorithm (modular alg)' CONFIG_IPSEC_ALG_1DES +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_3des.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_3des.in --- linux-2.4.29/net/ipsec/alg/Config.alg_3des.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_3des.in Thu Sep 5 05:36:54 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' 3DES encryption algorithm (modular alg)' CONFIG_IPSEC_ALG_3DES +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_aes.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_aes.in --- linux-2.4.29/net/ipsec/alg/Config.alg_aes.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_aes.in Thu Sep 5 05:38:06 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' AES encryption algorithm' CONFIG_IPSEC_ALG_AES +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_blowfish.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_blowfish.in --- linux-2.4.29/net/ipsec/alg/Config.alg_blowfish.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_blowfish.in Thu Sep 5 05:39:46 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' BLOWFISH encryption algorithm' CONFIG_IPSEC_ALG_BLOWFISH +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_cast.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_cast.in --- linux-2.4.29/net/ipsec/alg/Config.alg_cast.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_cast.in Thu Sep 5 05:48:04 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' CAST encryption algorithm' CONFIG_IPSEC_ALG_CAST +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_cryptoapi.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_cryptoapi.in --- linux-2.4.29/net/ipsec/alg/Config.alg_cryptoapi.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_cryptoapi.in Sat Feb 22 00:23:03 2003 @@ -0,0 +1,6 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO + if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then + bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE + fi +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_md5.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_md5.in --- linux-2.4.29/net/ipsec/alg/Config.alg_md5.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_md5.in Thu Sep 5 05:31:27 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' HMAC_MD5 auth algorithm (modular alg)' CONFIG_IPSEC_ALG_MD5 +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_null.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_null.in --- linux-2.4.29/net/ipsec/alg/Config.alg_null.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_null.in Thu Sep 5 05:49:06 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' NULL encryption algorithm' CONFIG_IPSEC_ALG_NULL +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_serpent.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_serpent.in --- linux-2.4.29/net/ipsec/alg/Config.alg_serpent.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_serpent.in Thu Sep 5 05:43:55 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' SERPENT encryption algorithm' CONFIG_IPSEC_ALG_SERPENT +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_sha1.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_sha1.in --- linux-2.4.29/net/ipsec/alg/Config.alg_sha1.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_sha1.in Thu Sep 5 05:34:24 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' HMAC_SHA1 auth algorithm (modular alg)' CONFIG_IPSEC_ALG_SHA1 +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_sha2.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_sha2.in --- linux-2.4.29/net/ipsec/alg/Config.alg_sha2.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_sha2.in Thu Sep 5 05:34:24 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' HMAC_SHA2 auth algorithm' CONFIG_IPSEC_ALG_SHA2 +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.alg_twofish.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_twofish.in --- linux-2.4.29/net/ipsec/alg/Config.alg_twofish.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.alg_twofish.in Thu Sep 5 05:41:17 2002 @@ -0,0 +1,3 @@ +if [ "$CONFIG_IPSEC_ALG" = "y" ]; then + tristate ' TWOFISH encryption algorithm' CONFIG_IPSEC_ALG_TWOFISH +fi diff -urN linux-2.4.29/net/ipsec/alg/Config.in linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.in --- linux-2.4.29/net/ipsec/alg/Config.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Config.in Tue May 20 03:12:35 2003 @@ -0,0 +1,13 @@ +#Placeholder +source net/ipsec/alg/Config.alg_md5.in +source net/ipsec/alg/Config.alg_sha1.in +source net/ipsec/alg/Config.alg_sha2.in +source net/ipsec/alg/Config.alg_3des.in +source net/ipsec/alg/Config.alg_aes.in +source net/ipsec/alg/Config.alg_blowfish.in +source net/ipsec/alg/Config.alg_twofish.in +source net/ipsec/alg/Config.alg_serpent.in +source net/ipsec/alg/Config.alg_cast.in +source net/ipsec/alg/Config.alg_null.in +source net/ipsec/alg/Config.alg_cryptoapi.in +source net/ipsec/alg/Config.alg_1des.in diff -urN linux-2.4.29/net/ipsec/alg/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile --- linux-2.4.29/net/ipsec/alg/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile Wed Nov 19 03:29:45 2003 @@ -0,0 +1,104 @@ +# $Id: Makefile,v 1.3 2003/11/19 02:29:45 mcr Exp $ +KLIPSDIR:= $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi)/.. + +#LIBCRYPTO:=$(KLIPSDIR)/../../../libcrypto +LIBCRYPTO:=$(KLIPSDIR)/libcrypto +EXTRA_CFLAGS:=-I$(KLIPSDIR) -I$(KLIPSDIR)/libopenswan -I$(LIBCRYPTO)/include -I$(LIBCRYPTO) +ifeq ($(CONFIG_IPSEC_DEBUG),y) +EXTRA_CFLAGS += -g +endif +EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes + +MOD_LIST_NAME := NET_MISC_MODULES + +#O_TARGET := ipsec_alg_static.o + +subdir- := +subdir-n := +subdir-y := +subdir-m := + +obj-y := ipsec_alg_static_init.o + +ARCH_ASM-y := +ARCH_ASM-$(CONFIG_M586) := i586 +ARCH_ASM-$(CONFIG_M586TSC) := i586 +ARCH_ASM-$(CONFIG_M586MMX) := i586 +ARCH_ASM-$(CONFIG_MK6) := i586 +ARCH_ASM-$(CONFIG_M686) := i686 +ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686 +ARCH_ASM-$(CONFIG_MPENTIUM4) := i686 +ARCH_ASM-$(CONFIG_MK7) := i686 +ARCH_ASM-$(CONFIG_MCRUSOE) := i586 +ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586 +ARCH_ASM-$(CONFIG_MWINCHIP2) := i586 +ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586 +ARCH_ASM-$(CONFIG_USERMODE) := i586 + +ARCH_ASM :=$(ARCH_ASM-y) +ifdef NO_ASM +ARCH_ASM := +endif + +## debug: +#$(warning CONFIG_M586=$(CONFIG_M586)) +#$(warning CONFIG_M686=$(CONFIG_M686)) +#$(warning ARCH_ASM=$(ARCH_ASM)) +# The algorithm makefiles may put dependences, short-circuit them +null: + +makefiles=$(wildcard Makefile.alg_*) +ifneq ($(makefiles),) +#include Makefile.alg_aes +#include Makefile.alg_aes-opt +include $(makefiles) +endif + +# These rules translate from new to old makefile rules +# Translate to Rules.make lists. +multi-used := $(filter $(list-multi), $(obj-y) $(obj-m)) +multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs)) +active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m)) +O_OBJS := $(obj-y) +M_OBJS := $(obj-m) +MIX_OBJS := $(filter $(export-objs), $(active-objs)) +#OX_OBJS := $(export-objs) +SUB_DIRS := $(subdir-y) +ALL_SUB_DIRS := $(subdir-y) $(subdir-m) +MOD_SUB_DIRS := $(subdir-m) + + +ifdef TOPDIR +include $(TOPDIR)/Rules.make +endif + +ipsec_alg_static.o: $(obj-y) + rm -f $@ + $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@ + +perlasm: $(LIBCRYPTO)/perlasm + ln -sf $? $@ + +$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h ../ipsec_alg.h +$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h ../ipsec_alg.h + + +alg_modules: perlasm $(ALG_MODULES) + @echo "ALG_MODULES=$(ALG_MODULES)" + + +# +# Construct alg. init. function: call ipsec_ALGO_init() for every static algo +# Needed when there are static algos (with static or modular ipsec.o) +# +ipsec_alg_static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh + @echo "Re-creating $@" + $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@ + +clean: + @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0 + @find . -type l -exec rm -f {} \; + -rm -f perlasm + -rm -rf $(ALG_SUBDIRS) + -rm -f *.o ipsec_alg_static_init.c + diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_1des linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_1des --- linux-2.4.29/net/ipsec/alg/Makefile.alg_1des Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_1des Fri Mar 28 14:56:19 2003 @@ -0,0 +1,20 @@ +MOD_1DES += ipsec_1des.o + +ALG_MODULES += $(MOD_1DES) +ALG_SUBDIRS += libdes + +obj-$(CONFIG_IPSEC_ALG_1DES) += $(MOD_1DES) +static_init-func-$(CONFIG_IPSEC_ALG_1DES)+= ipsec_1des_init +alg_obj-$(CONFIG_IPSEC_ALG_1DES) += ipsec_alg_1des.o + +DES_1DES_OBJS=ipsec_alg_1des.o ../libdes/libdes.a + +$(MOD_1DES): $(DES_1DES_OBJS) + $(LD) -r $(DES_1DES_OBJS) -o $@ + +# avoid multiple rules for libdes.a +ifeq ($(LIBDES),) +LIBDES:=../libdes/libdes.a +$(LIBDES): + $(MAKE) -C .. libdes/libdes.a +endif diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_3des linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_3des --- linux-2.4.29/net/ipsec/alg/Makefile.alg_3des Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_3des Fri Mar 28 14:56:19 2003 @@ -0,0 +1,20 @@ +MOD_3DES += ipsec_3des.o + +ALG_MODULES += $(MOD_3DES) +ALG_SUBDIRS += libdes + +obj-$(CONFIG_IPSEC_ALG_3DES) += $(MOD_3DES) +static_init-func-$(CONFIG_IPSEC_ALG_3DES)+= ipsec_3des_init +alg_obj-$(CONFIG_IPSEC_ALG_3DES) += ipsec_alg_3des.o + +DES_3DES_OBJS=ipsec_alg_3des.o ../libdes/libdes.a + +$(MOD_3DES): $(DES_3DES_OBJS) + $(LD) -r $(DES_3DES_OBJS) -o $@ + +# avoid multiple rules for libdes.a +ifeq ($(LIBDES),) +LIBDES:=../libdes/libdes.a +$(LIBDES): + $(MAKE) -C .. libdes/libdes.a +endif diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_aes linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_aes --- linux-2.4.29/net/ipsec/alg/Makefile.alg_aes Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_aes Thu Sep 5 05:38:06 2002 @@ -0,0 +1,23 @@ +MOD_AES := ipsec_aes.o + +ALG_MODULES += $(MOD_AES) +ALG_SUBDIRS += libaes + +obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES) +static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init +alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o + +AES_OBJS := ipsec_alg_aes.o libaes/libaes.a + +$(MOD_AES): libaes $(AES_OBJS) + $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@ + +libaes: $(LIBCRYPTO)/libaes + test -d $@ || mkdir $@ ;exit 0 + test -d $@/asm || mkdir $@/asm;exit 0 + cd $@ && ln -sf $?/Makefile $?/*.[chS] . + cd $@/asm && ln -sf $?/asm/*.S . + +libaes/libaes.a: libaes + ( cd libaes && \ + $(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libaes.a ;) diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_blowfish linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_blowfish --- linux-2.4.29/net/ipsec/alg/Makefile.alg_blowfish Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_blowfish Thu Sep 5 05:39:46 2002 @@ -0,0 +1,23 @@ +MOD_BLOWFISH := ipsec_blowfish.o + +ALG_MODULES += $(MOD_BLOWFISH) +ALG_SUBDIRS += libblowfish + +obj-$(CONFIG_IPSEC_ALG_BLOWFISH) += $(MOD_BLOWFISH) +static_init-func-$(CONFIG_IPSEC_ALG_BLOWFISH)+= ipsec_blowfish_init +alg_obj-$(CONFIG_IPSEC_ALG_BLOWFISH) += ipsec_alg_blowfish.o + +BLOWFISH_OBJS:= ipsec_alg_blowfish.o libblowfish/libblowfish.a + +$(MOD_BLOWFISH): libblowfish $(BLOWFISH_OBJS) + $(LD) -r $(BLOWFISH_OBJS) -o $@ + +libblowfish : $(LIBCRYPTO)/libblowfish + test -d $@ || mkdir $@ ;exit 0 + test -d $@/asm || mkdir $@/asm;exit 0 + cd $@ && ln -sf $?/Makefile $?/*.[chS] . + cd $@/asm && ln -sf $?/asm/*.pl . + +libblowfish/libblowfish.a: + ( cd libblowfish && \ + $(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libblowfish.a ;) diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_cast linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_cast --- linux-2.4.29/net/ipsec/alg/Makefile.alg_cast Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_cast Thu Sep 5 05:48:04 2002 @@ -0,0 +1,23 @@ +MOD_CAST := ipsec_cast.o + +ALG_MODULES += $(MOD_CAST) +ALG_SUBDIRS += libcast + +obj-$(CONFIG_IPSEC_ALG_CAST) += $(MOD_CAST) +static_init-func-$(CONFIG_IPSEC_ALG_CAST)+= ipsec_cast_init +alg_obj-$(CONFIG_IPSEC_ALG_CAST) += ipsec_alg_cast.o + +CAST_OBJS := ipsec_alg_cast.o libcast/libcast.a + +$(MOD_CAST): libcast $(CAST_OBJS) + $(LD) -r $(CAST_OBJS) -o $@ + +libcast : $(LIBCRYPTO)/libcast + test -d $@ || mkdir $@ ;exit 0 + test -d $@/asm || mkdir $@/asm;exit 0 + cd $@ && ln -sf $?/Makefile $?/*.[chS] . + cd $@/asm && ln -sf $?/asm/*.pl . + +libcast/libcast.a: + ( cd libcast && \ + $(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libcast.a ;) diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_cryptoapi linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_cryptoapi --- linux-2.4.29/net/ipsec/alg/Makefile.alg_cryptoapi Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_cryptoapi Fri Feb 7 15:39:36 2003 @@ -0,0 +1,11 @@ +MOD_CRYPTOAPI := ipsec_cryptoapi.o + +ALG_MODULES += $(MOD_CRYPTOAPI) + +obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI) +static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init +alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o + +CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o +$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS) + $(LD) -r $(CRYPTOAPI_OBJS) -o $@ diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_md5 linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_md5 --- linux-2.4.29/net/ipsec/alg/Makefile.alg_md5 Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_md5 Thu Sep 5 05:31:27 2002 @@ -0,0 +1,23 @@ +MOD_MD5 := ipsec_md5.o + +ALG_MODULES += $(MOD_MD5) +ALG_SUBDIRS += libmd5 + +obj-$(CONFIG_IPSEC_ALG_MD5) += $(MOD_MD5) +static_init-func-$(CONFIG_IPSEC_ALG_MD5)+= ipsec_md5_init +alg_obj-$(CONFIG_IPSEC_ALG_MD5) += ipsec_alg_md5.o + +MD5_OBJS :=ipsec_alg_md5.o libmd5/libmd5.a + +$(MOD_MD5): libmd5 $(MD5_OBJS) + $(LD) $(EXTRA_LDFLAGS) -r $(MD5_OBJS) -o $@ + +libmd5 : $(LIBCRYPTO)/libmd5 + test -d $@ || mkdir $@ ;exit 0 + test -d $@/asm || mkdir $@/asm;exit 0 + cd $@ && ln -sf $?/Makefile $?/*.[chS] . + cd $@/asm && ln -sf $?/asm/*.pl . + +libmd5/libmd5.a: + ( cd libmd5 && \ + $(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libmd5.a ;) diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_null linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_null --- linux-2.4.29/net/ipsec/alg/Makefile.alg_null Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_null Thu Sep 5 05:49:06 2002 @@ -0,0 +1,13 @@ +MOD_NULL := ipsec_null.o + +ALG_MODULES += $(MOD_NULL) +ALG_SUBDIRS += + +obj-$(CONFIG_IPSEC_ALG_NULL) += ipsec_null.o +static_init-func-$(CONFIG_IPSEC_ALG_NULL)+= ipsec_null_init +alg_obj-$(CONFIG_IPSEC_ALG_NULL) += ipsec_alg_null.o + +NULL_OBJS=ipsec_alg_null.o +ipsec_null.o: $(NULL_OBJS) + $(LD) -r $(NULL_OBJS) -o $@ + diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_serpent linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_serpent --- linux-2.4.29/net/ipsec/alg/Makefile.alg_serpent Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_serpent Thu Sep 5 05:43:55 2002 @@ -0,0 +1,21 @@ +MOD_SERPENT := ipsec_serpent.o + +ALG_MODULES += $(MOD_SERPENT) +ALG_SUBDIRS += libserpent + +obj-$(CONFIG_IPSEC_ALG_SERPENT) += $(MOD_SERPENT) +static_init-func-$(CONFIG_IPSEC_ALG_SERPENT)+= ipsec_serpent_init +alg_obj-$(CONFIG_IPSEC_ALG_SERPENT) += ipsec_alg_serpent.o + +SERPENT_OBJS=ipsec_alg_serpent.o libserpent/libserpent.a +$(MOD_SERPENT) : libserpent $(SERPENT_OBJS) + $(LD) -r $(SERPENT_OBJS) -o $@ + +libserpent : $(LIBCRYPTO)/libserpent + test -d $@ || mkdir $@ ;exit 0 + test -d $@/asm || mkdir $@/asm;exit 0 + cd $@ && ln -sf $?/Makefile $?/*.[chS] . + +libserpent/libserpent.a: + ( cd libserpent && \ + $(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libserpent.a ;) diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_sha1 linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_sha1 --- linux-2.4.29/net/ipsec/alg/Makefile.alg_sha1 Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_sha1 Thu Sep 5 05:34:24 2002 @@ -0,0 +1,23 @@ +MOD_SHA1 := ipsec_sha1.o + +ALG_MODULES += $(MOD_SHA1) +ALG_SUBDIRS += libsha1 + +obj-$(CONFIG_IPSEC_ALG_SHA1) += $(MOD_SHA1) +static_init-func-$(CONFIG_IPSEC_ALG_SHA1)+= ipsec_sha1_init +alg_obj-$(CONFIG_IPSEC_ALG_SHA1) += ipsec_alg_sha1.o + +SHA1_OBJS :=ipsec_alg_sha1.o libsha1/libsha1.a + +$(MOD_SHA1): libsha1 $(SHA1_OBJS) + $(LD) $(EXTRA_LDFLAGS) -r $(SHA1_OBJS) -o $@ + +libsha1 : $(LIBCRYPTO)/libsha1 + test -d $@ || mkdir $@ ;exit 0 + test -d $@/asm || mkdir $@/asm;exit 0 + cd $@ && ln -sf $?/Makefile $?/*.[chS] . + cd $@/asm && ln -sf $?/asm/*.pl . + +libsha1/libsha1.a: + ( cd libsha1 && \ + $(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libsha1.a ;) diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_sha2 linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_sha2 --- linux-2.4.29/net/ipsec/alg/Makefile.alg_sha2 Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_sha2 Thu Sep 5 05:34:24 2002 @@ -0,0 +1,22 @@ +MOD_SHA2 := ipsec_sha2.o + +ALG_MODULES += $(MOD_SHA2) +ALG_SUBDIRS += libsha2 + +obj-$(CONFIG_IPSEC_ALG_SHA2) += $(MOD_SHA2) +static_init-func-$(CONFIG_IPSEC_ALG_SHA2)+= ipsec_sha2_init +alg_obj-$(CONFIG_IPSEC_ALG_SHA2) += ipsec_alg_sha2.o + +SHA2_OBJS := ipsec_alg_sha2.o libsha2/libsha2.a + +$(MOD_SHA2): libsha2 $(SHA2_OBJS) + $(LD) $(EXTRA_LDFLAGS) -r $(SHA2_OBJS) -o $@ + +libsha2 : $(LIBCRYPTO)/libsha2 + test -d $@ || mkdir $@ ;exit 0 + test -d $@/asm || mkdir $@/asm;exit 0 + cd $@ && ln -sf $?/Makefile $?/*.[chS] . + +libsha2/libsha2.a: + ( cd libsha2 && \ + $(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libsha2.a ;) diff -urN linux-2.4.29/net/ipsec/alg/Makefile.alg_twofish linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_twofish --- linux-2.4.29/net/ipsec/alg/Makefile.alg_twofish Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/Makefile.alg_twofish Thu Sep 5 05:41:17 2002 @@ -0,0 +1,21 @@ +MOD_TWOFISH := ipsec_twofish.o + +ALG_MODULES += $(MOD_TWOFISH) +ALG_SUBDIRS += libtwofish + +obj-$(CONFIG_IPSEC_ALG_TWOFISH) += $(MOD_TWOFISH) +static_init-func-$(CONFIG_IPSEC_ALG_TWOFISH)+= ipsec_twofish_init +alg_obj-$(CONFIG_IPSEC_ALG_TWOFISH) += ipsec_alg_twofish.o + +TWOFISH_OBJS := ipsec_alg_twofish.o libtwofish/libtwofish.a +$(MOD_TWOFISH): libtwofish $(TWOFISH_OBJS) + $(LD) -r $(TWOFISH_OBJS) -o $@ + +libtwofish : $(LIBCRYPTO)/libtwofish + test -d $@ || mkdir $@ ;exit 0 + test -d $@/asm || mkdir $@/asm;exit 0 + cd $@ && ln -sf $?/Makefile $?/*.[chS] . + +libtwofish/libtwofish.a: + ( cd libtwofish && \ + $(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' libtwofish.a ;) diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_1des.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_1des.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_1des.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_1des.c Thu Dec 4 04:16:33 2003 @@ -0,0 +1,161 @@ +/* + * ipsec_alg 1DES cipher + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_1des.c,v 1.4 2003/12/04 03:16:33 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_1DES +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +#include +#include +#include "ipsec_param.h" +#include "ipsec_sa.h" +#include "ipsec_alg.h" +#include "../libdes/des.h" + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int I_know_des_is_insecure=0; +MODULE_PARM(I_know_des_is_insecure, "i"); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); +static int esp_id=0; +MODULE_PARM(esp_id, "i"); + +#define ESP_DES 2 + +#define ESP_DES_CBC_BLKLEN 8 /* 64 bit blocks */ +#define ESP_DES_KEY_SZ 8 /* 56 bits keylen :P */ + +struct des1_eks{ + des_key_schedule ctx[1]; +}; +static int _1des_set_key(struct ipsec_alg_enc *alg,__u8 *key_e, const __u8 * key, size_t keysize) { + des_key_schedule *ctx=((struct des1_eks*)key_e)->ctx; + int error; + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _1des_set_key: " + "key_e=%p key=%p keysize=%d\n", + key_e, key, (int)keysize); + if (!I_know_des_is_insecure) + printk(KERN_WARNING "You should NOT use 1DES except for testing purposes !\n"); + des_set_odd_parity((des_cblock *)key); + error = des_set_key((des_cblock *)key, ctx[0]); + if (debug > 0) + printk(KERN_DEBUG "klips_debug:des_set_key:" + "ctx[%d]=%p, error=%d \n", + 0, ctx[0], error); + if (error == -1) + printk("klips_debug: _1des_set_key: " + "parity error in 1des key\n"); + else if (error == -2) + printk("klips_debug: _1des_set_key: " + "illegal weak 1des key \n"); + if (error) + return error; + return 0; +} +void des_cbc_encrypt(des_cblock *input, des_cblock *output, + long length, des_key_schedule ks, + des_cblock *ivec, int enc); + +static int _1des_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { + char iv_buf[ESP_DES_CBC_BLKLEN]; + des_key_schedule *ctx=((struct des1_eks*)key_e)->ctx; + *((__u32*)&(iv_buf)) = ((__u32*)(iv))[0]; + *((__u32*)&(iv_buf)+1) = ((__u32*)(iv))[1]; + if (debug > 1) { + printk(KERN_DEBUG "klips_debug:_1des_cbc_encrypt:" + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", + ctx, in, ilen, iv, encrypt); + } + des_cbc_encrypt((des_cblock*) in, (des_cblock*) in, ilen, ctx[0], (des_cblock *)iv_buf, encrypt); + return ilen; +} +static struct ipsec_alg_enc ipsec_alg_1DES = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_name: "1des", + ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, + ixt_alg_id: ESP_DES, + ixt_blocksize: ESP_DES_CBC_BLKLEN, + ixt_keyminbits: ESP_DES_KEY_SZ*7, /* 7bits key+1bit parity */ + ixt_keymaxbits: ESP_DES_KEY_SZ*7, /* 7bits key+1bit parity */ + ixt_e_keylen: ESP_DES_KEY_SZ, + ixt_e_ctx_size: sizeof(struct des1_eks), + ixt_e_set_key: _1des_set_key, + ixt_e_cbc_encrypt:_1des_cbc_encrypt, +}; + +IPSEC_ALG_MODULE_INIT(ipsec_1des_init) +{ + int ret, test_ret; + if (esp_id) + ipsec_alg_1DES.ixt_alg_id=esp_id; + if (excl) ipsec_alg_1DES.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_enc(&ipsec_alg_1DES); + printk("ipsec_1des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_1DES.ixt_alg_type, + ipsec_alg_1DES.ixt_alg_id, + ipsec_alg_1DES.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_1DES.ixt_alg_type, + ipsec_alg_1DES.ixt_alg_id, + test); + printk("ipsec_1des_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_1DES.ixt_alg_type, + ipsec_alg_1DES.ixt_alg_id, + test_ret); + } + if (!I_know_des_is_insecure) + printk(KERN_WARNING "You should NOT load 1DES support except for testing purposes !\n"); + return ret; +} +IPSEC_ALG_MODULE_EXIT(ipsec_1des_fini) +{ + unregister_ipsec_alg_enc(&ipsec_alg_1DES); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_3des.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_3des.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_3des.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_3des.c Thu Dec 4 04:16:33 2003 @@ -0,0 +1,160 @@ +/* + * ipsec_alg 3DES cipher + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_3des.c,v 1.5 2003/12/04 03:16:33 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_3DES +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +#include +#include +#include "ipsec_param.h" +#include "ipsec_sa.h" +#include "ipsec_alg.h" +#include "../libdes/des.h" + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); +static int esp_id=0; +MODULE_PARM(esp_id, "i"); + +#define ESP_3DES 3 + +#define ESP_3DES_CBC_BLKLEN 8 /* 64 bit blocks */ +#define ESP_DES_KEY_SZ 8 +#define ESP_3DES_KEY_SZ 8*3 /* 3DES */ + +struct des3_eks{ + des_key_schedule ctx[3]; +}; +static int _3des_set_key(struct ipsec_alg_enc *alg,__u8 *key_e, const __u8 * key, size_t keysize) { + des_key_schedule *ctx=((struct des3_eks*)key_e)->ctx; + int i, error; + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _3des_set_key: " + "key_e=%p key=%p keysize=%d\n", + key_e, key, (int)keysize); + for(i = 0; i < 3; i++) { + des_set_odd_parity((des_cblock *)(key+ESP_DES_KEY_SZ * i)); + error = des_set_key((des_cblock *)(key+ESP_DES_KEY_SZ * i), + ctx[i]); + if (debug > 0) + printk(KERN_DEBUG "klips_debug:des_set_key:" + "ctx[%d]=%p, error=%d \n", + i, ctx[i], error); + if (error == -1) + printk("klips_debug: _3des_set_key: " + "parity error in des key %d/3\n", + i + 1); + else if (error == -2) + printk("klips_debug: _3des_set_key: " + "illegal weak des key %d/3\n", i + 1); + if (error) + return error; + } + return 0; +} +void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, + long length, des_key_schedule ks1, des_key_schedule ks2, + des_key_schedule ks3, des_cblock *ivec, int enc); + +static int _3des_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { + char iv_buf[ESP_3DES_CBC_BLKLEN]; + des_key_schedule *ctx=((struct des3_eks*)key_e)->ctx; + *((__u32*)&(iv_buf)) = ((__u32*)(iv))[0]; + *((__u32*)&(iv_buf)+1) = ((__u32*)(iv))[1]; + if (debug > 1) { + printk(KERN_DEBUG "klips_debug:_3des_cbc_encrypt:" + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", + ctx, in, ilen, iv, encrypt); + } + des_ede3_cbc_encrypt((des_cblock*) in, (des_cblock*) in, ilen, ctx[0], ctx[1], ctx[2], (des_cblock *)iv_buf, encrypt); + return ilen; +} +static struct ipsec_alg_enc ipsec_alg_3DES = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_name: "3des", + ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, + ixt_alg_id: ESP_3DES, + ixt_blocksize: ESP_3DES_CBC_BLKLEN, + ixt_keyminbits: ESP_3DES_KEY_SZ*7, /* 7bits key+1bit parity */ + ixt_keymaxbits: ESP_3DES_KEY_SZ*7, /* 7bits key+1bit parity */ + ixt_e_keylen: ESP_3DES_KEY_SZ, + ixt_e_ctx_size: sizeof(struct des3_eks), + ixt_e_set_key: _3des_set_key, + ixt_e_cbc_encrypt:_3des_cbc_encrypt, +}; + +IPSEC_ALG_MODULE_INIT(ipsec_3des_init) +{ + int ret, test_ret; + if (esp_id) + ipsec_alg_3DES.ixt_alg_id=esp_id; + if (excl) ipsec_alg_3DES.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_enc(&ipsec_alg_3DES); + printk("ipsec_3des_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_3DES.ixt_alg_type, + ipsec_alg_3DES.ixt_alg_id, + ipsec_alg_3DES.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_3DES.ixt_alg_type, + ipsec_alg_3DES.ixt_alg_id, + test); + printk("ipsec_3des_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_3DES.ixt_alg_type, + ipsec_alg_3DES.ixt_alg_id, + test_ret); + } + return ret; +} +IPSEC_ALG_MODULE_EXIT(ipsec_3des_fini) +{ + unregister_ipsec_alg_enc(&ipsec_alg_3DES); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_aes.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_aes.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_aes.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_aes.c Thu Dec 4 04:16:33 2003 @@ -0,0 +1,253 @@ +/* + * ipsec_alg AES cipher stubs + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_aes.c,v 1.5 2003/12/04 03:16:33 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * Fixes by: + * PK: Pawel Krawczyk + * Fixes list: + * PK: make XCBC comply with latest draft (keylength) + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* Low freeswan header coupling */ +#include "ipsec_alg.h" +#include "libaes/aes_cbc.h" + +#define CONFIG_IPSEC_ALG_AES_MAC 1 + +#define AES_CONTEXT_T aes_context +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); +static int keyminbits=0; +MODULE_PARM(keyminbits, "i"); +static int keymaxbits=0; +MODULE_PARM(keymaxbits, "i"); + +#if CONFIG_IPSEC_ALG_AES_MAC +#include "libaes/aes_xcbc_mac.h" + +/* + * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt). + * We use 9 for non-modular algorithm and none for modular, thus + * forcing user to specify one on module load. -kravietz + */ +#ifdef MODULE +static int auth_id=0; +#else +static int auth_id=9; +#endif +MODULE_PARM(auth_id, "i"); +#endif + +#define ESP_AES 12 /* truely _constant_ :) */ + +/* 128, 192 or 256 */ +#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */ +#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */ +#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */ + +/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt + * -kravietz + */ +#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */ +#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */ + +static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { + int ret; + AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; + ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_aes_set_key:" + "ret=%d key_e=%p key=%p keysize=%d\n", + ret, key_e, key, (int)keysize); + return ret; +} +static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { + AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:" + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", + key_e, in, ilen, iv, encrypt); + return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt); +} +#if CONFIG_IPSEC_ALG_AES_MAC +static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) { + aes_context_mac *ctxm=(aes_context_mac *)key_a; + return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL; +} +static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) { + int ret; + char hash_buf[16]; + aes_context_mac *ctxm=(aes_context_mac *)key_a; + ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf); + memcpy(hash, hash_buf, hashlen); + return ret; +} +static struct ipsec_alg_auth ipsec_alg_AES_MAC = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_AUTH, + ixt_alg_id: 0, + ixt_name: "aes_mac", + ixt_blocksize: ESP_AES_MAC_BLK_LEN, + ixt_keyminbits: ESP_AES_MAC_KEY_SZ*8, + ixt_keymaxbits: ESP_AES_MAC_KEY_SZ*8, + ixt_a_keylen: ESP_AES_MAC_KEY_SZ, + ixt_a_ctx_size: sizeof(aes_context_mac), + ixt_a_hmac_set_key: _aes_mac_set_key, + ixt_a_hmac_hash:_aes_mac_hash, +}; +#endif /* CONFIG_IPSEC_ALG_AES_MAC */ +static struct ipsec_alg_enc ipsec_alg_AES = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, + ixt_alg_id: ESP_AES, + ixt_name: "aes", + ixt_blocksize: ESP_AES_CBC_BLK_LEN, + ixt_keyminbits: ESP_AES_KEY_SZ_MIN*8, + ixt_keymaxbits: ESP_AES_KEY_SZ_MAX*8, + ixt_e_keylen: ESP_AES_KEY_SZ_MAX, + ixt_e_ctx_size: sizeof(AES_CONTEXT_T), + ixt_e_set_key: _aes_set_key, + ixt_e_cbc_encrypt:_aes_cbc_encrypt, +}; + +IPSEC_ALG_MODULE_INIT( ipsec_aes_init ) +{ + int ret, test_ret; + if (keyminbits) + ipsec_alg_AES.ixt_keyminbits=keyminbits; + if (keymaxbits) { + ipsec_alg_AES.ixt_keymaxbits=keymaxbits; + if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits) + ipsec_alg_AES.ixt_e_keylen=keymaxbits*8; + } + if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_enc(&ipsec_alg_AES); + printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_AES.ixt_alg_type, + ipsec_alg_AES.ixt_alg_id, + ipsec_alg_AES.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_AES.ixt_alg_type, + ipsec_alg_AES.ixt_alg_id, + test); + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_AES.ixt_alg_type, + ipsec_alg_AES.ixt_alg_id, + test_ret); + } +#if CONFIG_IPSEC_ALG_AES_MAC + if (auth_id!=0){ + int ret; + ipsec_alg_AES_MAC.ixt_alg_id=auth_id; + ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC); + printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_AES_MAC.ixt_alg_type, + ipsec_alg_AES_MAC.ixt_alg_id, + ipsec_alg_AES_MAC.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_AES_MAC.ixt_alg_type, + ipsec_alg_AES_MAC.ixt_alg_id, + test); + printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_AES_MAC.ixt_alg_type, + ipsec_alg_AES_MAC.ixt_alg_id, + test_ret); + } + } else { + printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id); + } +#endif /* CONFIG_IPSEC_ALG_AES_MAC */ + return ret; +} +IPSEC_ALG_MODULE_EXIT( ipsec_aes_fini ) +{ +#if CONFIG_IPSEC_ALG_AES_MAC + if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC); +#endif /* CONFIG_IPSEC_ALG_AES_MAC */ + unregister_ipsec_alg_enc(&ipsec_alg_AES); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +#if 0+NOT_YET +#ifndef MODULE +/* + * This is intended for static module setups, currently + * doesn't work for modular ipsec.o with static algos inside + */ +static int setup_keybits(const char *str) +{ + unsigned aux; + char *end; + + aux = simple_strtoul(str,&end,0); + if (aux != 128 && aux != 192 && aux != 256) + return 0; + keyminbits = aux; + + if (*end == 0 || *end != ',') + return 1; + str=end+1; + aux = simple_strtoul(str, NULL, 0); + if (aux != 128 && aux != 192 && aux != 256) + return 0; + if (aux >= keyminbits) + keymaxbits = aux; + return 1; +} +__setup("ipsec_aes_keybits=", setup_keybits); +#endif +#endif +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_blowfish.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_blowfish.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_blowfish.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_blowfish.c Thu Dec 4 04:16:33 2003 @@ -0,0 +1,143 @@ +/* + * ipsec_alg BLOWFISH cipher stubs + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_blowfish.c,v 1.6 2003/12/04 03:16:33 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_BLOWFISH +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* Low freeswan header coupling */ +#include "ipsec_alg.h" +#include "libblowfish/blowfish.h" +#define blowfish_context BF_KEY + +#define ESP_BLOWFISH 7 /* truely _constant_ :) */ + +#define ESP_BLOWFISH_KEY_SZ_MIN 12 /* 96 bit secret key min */ +#define ESP_BLOWFISH_KEY_SZ 16 /* 128 bit secret key */ +#define ESP_BLOWFISH_KEY_SZ_MAX 56 /* 448 bit secret key */ +#define ESP_BLOWFISH_CBC_BLK_LEN 8 /* block size */ + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); +static int keyminbits=0; +MODULE_PARM(keyminbits, "i"); +static int keymaxbits=0; +MODULE_PARM(keymaxbits, "i"); + +static int _blowfish_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { + blowfish_context *ctx=(blowfish_context*)key_e; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_blowfish_set_key:" + "key_e=%p key=%p keysize=%d\n", + key_e, key, (int)keysize); + BF_set_key(ctx, keysize, (unsigned char *)key); + return 0; +} +static int _blowfish_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 *iv, int encrypt) { + /* blowfish toasts passed IV */ + __u8 iv_buf[ESP_BLOWFISH_CBC_BLK_LEN]; + blowfish_context *ctx=(blowfish_context*)key_e; + *((__u32*)&(iv_buf)) = ((__u32*)(iv))[0]; + *((__u32*)&(iv_buf)+1) = ((__u32*)(iv))[1]; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_blowfish_cbc_encrypt:" + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", + key_e, in, ilen, iv_buf, encrypt); + BF_cbc_encrypt(in, in, ilen, ctx, iv_buf, encrypt); + return ilen; +} +static struct ipsec_alg_enc ipsec_alg_BLOWFISH = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, + ixt_alg_id: ESP_BLOWFISH, + ixt_name: "blowfish", + ixt_blocksize: ESP_BLOWFISH_CBC_BLK_LEN, + ixt_keyminbits: ESP_BLOWFISH_KEY_SZ_MIN*8, + ixt_keymaxbits: ESP_BLOWFISH_KEY_SZ_MAX*8, + ixt_e_keylen: ESP_BLOWFISH_KEY_SZ, + ixt_e_ctx_size: sizeof(blowfish_context), + ixt_e_set_key: _blowfish_set_key, + ixt_e_cbc_encrypt:_blowfish_cbc_encrypt, +}; + +IPSEC_ALG_MODULE_INIT(ipsec_blowfish_init) +{ + int ret, test_ret; + if (keyminbits) + ipsec_alg_BLOWFISH.ixt_keyminbits=keyminbits; + if (keymaxbits) { + ipsec_alg_BLOWFISH.ixt_keymaxbits=keymaxbits; + if (keymaxbits*8>ipsec_alg_BLOWFISH.ixt_keymaxbits) + ipsec_alg_BLOWFISH.ixt_e_keylen=keymaxbits*8; + } + if (excl) ipsec_alg_BLOWFISH.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_enc(&ipsec_alg_BLOWFISH); + printk("ipsec_blowfish_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_BLOWFISH.ixt_alg_type, + ipsec_alg_BLOWFISH.ixt_alg_id, + ipsec_alg_BLOWFISH.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_BLOWFISH.ixt_alg_type, + ipsec_alg_BLOWFISH.ixt_alg_id, + test); + printk("ipsec_blowfish_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_BLOWFISH.ixt_alg_type, + ipsec_alg_BLOWFISH.ixt_alg_id, + test_ret); + } + return ret; +} +IPSEC_ALG_MODULE_EXIT(ipsec_blowfish_fini) +{ + unregister_ipsec_alg_enc(&ipsec_alg_BLOWFISH); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_cast.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_cast.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_cast.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_cast.c Thu Dec 4 04:16:33 2003 @@ -0,0 +1,144 @@ +/* + * ipsec_alg CAST cipher stubs + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_cast.c,v 1.5 2003/12/04 03:16:33 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CAST +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* Low freeswan header coupling */ +#include "ipsec_alg.h" +#define cast_context cast_key +#include "libcast/cast.h" + +#define ESP_CAST 6 /* quite constant :) */ + +#define ESP_CAST_KEY_SZ_MIN 5 +#define ESP_CAST_KEY_SZ 16 /* 128 bit secret key */ +#define ESP_CAST_CBC_BLK_LEN 8 /* CAST-CBC block size */ + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); +static int keyminbits=0; +MODULE_PARM(keyminbits, "i"); +static int keymaxbits=0; +MODULE_PARM(keymaxbits, "i"); + +#undef cast_context +#define cast_context CAST_KEY +static int _cast_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { + cast_context *ctx=(cast_context *)key_e; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_cast_set_key:" + "key_e=%p key=%p keysize=%d\n", + key_e, key, (int)keysize); + CAST_set_key(ctx, keysize, (u_int8_t *)key); + return 0; +} +static int _cast_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { + /* cast toasts passed IV */ + __u8 iv_buf[ESP_CAST_CBC_BLK_LEN]; + cast_context *ctx=(cast_context *)key_e; + *((__u32*)&(iv_buf)) = ((__u32*)(iv))[0]; + *((__u32*)&(iv_buf)+1) = ((__u32*)(iv))[1]; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_cast_cbc_encrypt:" + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", + key_e, in, ilen, iv, encrypt); + CAST_cbc_encrypt(in, in, ilen, ctx, iv_buf, encrypt); + return ilen; +} +static struct ipsec_alg_enc ipsec_alg_CAST = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, + ixt_alg_id: ESP_CAST, + ixt_name: "cast", + ixt_blocksize: ESP_CAST_CBC_BLK_LEN, + ixt_keyminbits: ESP_CAST_KEY_SZ_MIN*8, + ixt_keymaxbits: ESP_CAST_KEY_SZ*8, + ixt_e_keylen: ESP_CAST_KEY_SZ, + ixt_e_ctx_size: sizeof(cast_context), + ixt_e_set_key: _cast_set_key, + ixt_e_cbc_encrypt:_cast_cbc_encrypt, +}; + +IPSEC_ALG_MODULE_INIT(ipsec_cast_init) +{ + int ret, test_ret; + if (keyminbits) + ipsec_alg_CAST.ixt_keyminbits=keyminbits; + if (keymaxbits) { + ipsec_alg_CAST.ixt_keymaxbits=keymaxbits; + if (keymaxbits*8>ipsec_alg_CAST.ixt_keymaxbits) + ipsec_alg_CAST.ixt_e_keylen=keymaxbits*8; + } + if (excl) ipsec_alg_CAST.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_enc(&ipsec_alg_CAST); + printk("ipsec_cast_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_CAST.ixt_alg_type, + ipsec_alg_CAST.ixt_alg_id, + ipsec_alg_CAST.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_CAST.ixt_alg_type, + ipsec_alg_CAST.ixt_alg_id, + test); + printk("ipsec_cast_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_CAST.ixt_alg_type, + ipsec_alg_CAST.ixt_alg_id, + test_ret); + } + return ret; +} +IPSEC_ALG_MODULE_EXIT(ipsec_cast_fini) +{ + unregister_ipsec_alg_enc(&ipsec_alg_CAST); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_cryptoapi.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_cryptoapi.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_cryptoapi.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_cryptoapi.c Thu Dec 11 18:57:40 2003 @@ -0,0 +1,405 @@ +/* + * ipsec_alg to linux cryptoapi GLUE + * + * Authors: CODE.ar TEAM + * Harpo MAxx + * JuanJo Ciarlante + * Luciano Ruete + * + * $Id: ipsec_alg_cryptoapi.c,v 1.3 2003/12/11 17:57:40 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * Example usage: + * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos) + * modprobe ipsec_cryptoapi + * modprobe ipsec_cryptoapi test=1 + * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo) + * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers) + * modprobe ipsec_cryptoapi aes=128,128 (force these keylens) + * modprobe ipsec_cryptoapi des3_ede=0 (everything but 3DES) + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* warn the innocent */ +#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE) +#warning "No linux cryptoapi setup found... you *MUST* install it ! (www.kerneli.org)" +#endif +/* Low freeswan header coupling */ +#include "ipsec_alg.h" +#include + +#include +#include +#include + +#define CIPHERNAME_AES "aes" +#define CIPHERNAME_3DES "des3_ede" +#define CIPHERNAME_BLOWFISH "blowfish" +#define CIPHERNAME_CAST "cast5" +#define CIPHERNAME_SERPENT "serpent" +#define CIPHERNAME_TWOFISH "twofish" + +#define ESP_3DES 3 +#define ESP_AES 12 +#define ESP_BLOWFISH 7 /* truely _constant_ :) */ +#define ESP_CAST 6 /* quite constant :) */ +#define ESP_SERPENT 252 /* from ipsec drafts */ +#define ESP_TWOFISH 253 /* from ipsec drafts */ + +#define AH_MD5 2 +#define AH_SHA 3 +#define DIGESTNAME_MD5 "md5" +#define DIGESTNAME_SHA1 "sha1" + +MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete"); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); + +static int noauto = 0; +MODULE_PARM(noauto,"i"); +MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones"); + +static int des3_ede[] = {-1, -1}; +static int aes[] = {-1, -1}; +static int blowfish[] = {-1, -1}; +static int cast[] = {-1, -1}; +static int serpent[] = {-1, -1}; +static int twofish[] = {-1, -1}; + +MODULE_PARM(des3_ede,"1-2i"); +MODULE_PARM(aes,"1-2i"); +MODULE_PARM(blowfish,"1-2i"); +MODULE_PARM(cast,"1-2i"); +MODULE_PARM(serpent,"1-2i"); +MODULE_PARM(twofish,"1-2i"); +MODULE_PARM_DESC(des3_ede, "0: disable | 1: force_enable | min,max: dontuse"); +MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens"); +MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens"); +MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens"); +MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens"); +MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens"); + +struct ipsec_alg_capi_cipher { + const char *ciphername; /* cryptoapi's ciphername */ + unsigned blocksize; + unsigned short minbits; + unsigned short maxbits; + int *parm; /* lkm param for this cipher */ + struct ipsec_alg_enc alg; /* note it's not a pointer */ +}; +static struct ipsec_alg_capi_cipher alg_capi_carray[] = { + { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }}, + { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }}, + { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }}, + { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }}, + { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }}, + { CIPHERNAME_3DES , 8, 192, 192, des3_ede,{ ixt_alg_id: ESP_3DES, }}, + { NULL, 0, 0, 0, NULL, {} } +}; +#ifdef NOT_YET +struct ipsec_alg_capi_digest { + const char *digestname; /* cryptoapi's digestname */ + struct digest_implementation *di; + struct ipsec_alg_auth alg; /* note it's not a pointer */ +}; +static struct ipsec_alg_capi_cipher alg_capi_darray[] = { + { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }}, + { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }}, + { NULL, NULL, {} } +}; +#endif +/* + * "generic" linux cryptoapi setup_cipher() function + */ +int setup_cipher(const char *ciphername) +{ + return crypto_alg_available(ciphername, 0); +} + +/* + * setups ipsec_alg_capi_cipher "hyper" struct components, calling + * register_ipsec_alg for cointaned ipsec_alg object + */ +static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e); +static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen); +static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt); + +static int +setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr) +{ + int ret; + cptr->alg.ixt_version = IPSEC_ALG_VERSION; + cptr->alg.ixt_module = THIS_MODULE; + atomic_set (& cptr->alg.ixt_refcnt, 0); + strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name)); + + cptr->alg.ixt_blocksize=cptr->blocksize; + cptr->alg.ixt_keyminbits=cptr->minbits; + cptr->alg.ixt_keymaxbits=cptr->maxbits; + cptr->alg.ixt_state = 0; + if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL; + cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8; + cptr->alg.ixt_e_ctx_size = 0; + cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT; + cptr->alg.ixt_e_new_key = _capi_new_key; + cptr->alg.ixt_e_destroy_key = _capi_destroy_key; + cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt; + cptr->alg.ixt_data = cptr; + + ret=register_ipsec_alg_enc(&cptr->alg); + printk("setup_ipsec_alg_capi_cipher(): " + "alg_type=%d alg_id=%d name=%s " + "keyminbits=%d keymaxbits=%d, ret=%d\n", + cptr->alg.ixt_alg_type, + cptr->alg.ixt_alg_id, + cptr->alg.ixt_name, + cptr->alg.ixt_keyminbits, + cptr->alg.ixt_keymaxbits, + ret); + return ret; +} +/* + * called in ipsec_sa_wipe() time, will destroy key contexts + * and do 1 unbind() + */ +static void +_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e) +{ + struct crypto_tfm *tfm=(struct crypto_tfm*)key_e; + + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _capi_destroy_key:" + "name=%s key_e=%p \n", + alg->ixt_name, key_e); + if (!key_e) { + printk(KERN_ERR "klips_debug: _capi_destroy_key:" + "name=%s NULL key_e!\n", + alg->ixt_name); + return; + } + crypto_free_tfm(tfm); +} + +/* + * create new key context, need alg->ixt_data to know which + * (of many) cipher inside this module is the target + */ +static __u8 * +_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen) +{ + struct ipsec_alg_capi_cipher *cptr; + struct crypto_tfm *tfm=NULL; + + cptr = alg->ixt_data; + if (!cptr) { + printk(KERN_ERR "_capi_new_key(): " + "NULL ixt_data (?!) for \"%s\" algo\n" + , alg->ixt_name); + goto err; + } + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_capi_new_key:" + "name=%s cptr=%p key=%p keysize=%d\n", + alg->ixt_name, cptr, key, keylen); + + /* + * alloc tfm + */ + tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC); + if (!tfm) { + printk(KERN_ERR "_capi_new_key(): " + "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n" + , alg->ixt_name, cptr->ciphername); + goto err; + } + if (crypto_cipher_setkey(tfm, key, keylen) < 0) { + printk(KERN_ERR "_capi_new_key(): " + "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n" + , alg->ixt_name, keylen); + crypto_free_tfm(tfm); + tfm=NULL; + } +err: + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_capi_new_key:" + "name=%s key=%p keylen=%d tfm=%p\n", + alg->ixt_name, key, keylen, tfm); + return (__u8 *) tfm; +} +/* + * core encryption function: will use cx->ci to call actual cipher's + * cbc function + */ +static int +_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { + int error =0; + struct crypto_tfm *tfm=(struct crypto_tfm *)key_e; + struct scatterlist sg = { + .page = virt_to_page(in), + .offset = (unsigned long)(in) % PAGE_SIZE, + .length=ilen, + }; + if (debug > 1) + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" + "key_e=%p " + "in=%p out=%p ilen=%d iv=%p encrypt=%d\n" + , key_e + , in, in, ilen, iv, encrypt); + crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm)); + if (encrypt) + error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen); + else + error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen); + if (debug > 1) + printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:" + "error=%d\n" + , error); + return (error<0)? error : ilen; +} +/* + * main initialization loop: for each cipher in list, do + * 1) setup cryptoapi cipher else continue + * 2) register ipsec_alg object + */ +static int +setup_cipher_list (struct ipsec_alg_capi_cipher* clist) +{ + struct ipsec_alg_capi_cipher *cptr; + /* foreach cipher in list ... */ + for (cptr=clist;cptr->ciphername;cptr++) { + /* + * see if cipher has been disabled (0) or + * if noauto set and not enabled (1) + */ + if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) { + if (debug>0) + printk(KERN_INFO "setup_cipher_list(): " + "ciphername=%s skipped at user request: " + "noauto=%d parm[0]=%d parm[1]=%d\n" + , cptr->ciphername + , noauto + , cptr->parm[0] + , cptr->parm[1]); + continue; + } + /* + * use a local ci to avoid touching cptr->ci, + * if register ipsec_alg success then bind cipher + */ + if( setup_cipher(cptr->ciphername) ) { + if (debug > 0) + printk(KERN_DEBUG "klips_debug:" + "setup_cipher_list():" + "ciphername=%s found\n" + , cptr->ciphername); + if (setup_ipsec_alg_capi_cipher(cptr) == 0) { + + + } else { + printk(KERN_ERR "klips_debug:" + "setup_cipher_list():" + "ciphername=%s failed ipsec_alg_register\n" + , cptr->ciphername); + } + } else { + if (debug>0) + printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n", + cptr->ciphername); + } + } + return 0; +} +/* + * deregister ipsec_alg objects and unbind ciphers + */ +static int +unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist) +{ + struct ipsec_alg_capi_cipher *cptr; + /* foreach cipher in list ... */ + for (cptr=clist;cptr->ciphername;cptr++) { + if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { + unregister_ipsec_alg_enc(&cptr->alg); + } + } + return 0; +} +/* + * test loop for registered algos + */ +static int +test_cipher_list (struct ipsec_alg_capi_cipher* clist) +{ + int test_ret; + struct ipsec_alg_capi_cipher *cptr; + /* foreach cipher in list ... */ + for (cptr=clist;cptr->ciphername;cptr++) { + if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) { + test_ret=ipsec_alg_test( + cptr->alg.ixt_alg_type, + cptr->alg.ixt_alg_id, + test); + printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n", + cptr->alg.ixt_alg_type, + cptr->alg.ixt_alg_id, + test_ret); + } + } + return 0; +} + +IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init ) +{ + int ret, test_ret; + if ((ret=setup_cipher_list(alg_capi_carray)) < 0) + return -EPROTONOSUPPORT; + if (ret==0 && test) { + test_ret=test_cipher_list(alg_capi_carray); + } + return ret; +} +IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini ) +{ + unsetup_cipher_list(alg_capi_carray); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_md5.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_md5.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_md5.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_md5.c Fri Feb 7 14:14:25 2003 @@ -0,0 +1,122 @@ +/* + * ipsec_alg MD5 hash stubs + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_md5.c,v 1.2 2003/02/07 13:14:25 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_MD5 +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* Low freeswan header coupling */ +#include "ipsec_alg.h" +#include "libmd5/md5.h" +#include "libmd5/hmac_md5.h" + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); + +#define AH_MD5 2 + +static int _md5_hmac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) { + md5_hmac_context *hctx=(md5_hmac_context*)(key_a); + md5_hmac_set_key(hctx, key, keylen); + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _md5_hmac_set_key(): " + "key_a=%p key=%p keysize=%d\n", + key_a, key, keylen); + return 0; +} +static int _md5_hmac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) { + md5_hmac_context *hctx=(md5_hmac_context*)(key_a); + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _md5_hmac_hash(): " + "key_a=%p dat=%p len=%d hash=%p hashlen=%d\n", + key_a, dat, len, hash, hashlen); + md5_hmac_hash(hctx, dat, len, hash, hashlen); + return 0; +} +static struct ipsec_alg_auth ipsec_alg_MD5 = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_AUTH, + ixt_alg_id: AH_MD5, + ixt_name: "md5", + ixt_blocksize: MD5_BLOCKSIZE, + ixt_keyminbits: 128, + ixt_keymaxbits: 128, + ixt_a_keylen: 128/8, + ixt_a_ctx_size: sizeof(md5_hmac_context), + ixt_a_hmac_set_key: _md5_hmac_set_key, + ixt_a_hmac_hash: _md5_hmac_hash, +}; +IPSEC_ALG_MODULE_INIT( ipsec_md5_init ) +{ + int ret, test_ret; + if (excl) ipsec_alg_MD5.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_auth(&ipsec_alg_MD5); + printk("ipsec_md5_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_MD5.ixt_alg_type, + ipsec_alg_MD5.ixt_alg_id, + ipsec_alg_MD5.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_MD5.ixt_alg_type, + ipsec_alg_MD5.ixt_alg_id, + test); + printk("ipsec_md5_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_MD5.ixt_alg_type, + ipsec_alg_MD5.ixt_alg_id, + test_ret); + } + return ret; +} +IPSEC_ALG_MODULE_EXIT( ipsec_md5_fini ) +{ + unregister_ipsec_alg_auth(&ipsec_alg_MD5); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_null.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_null.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_null.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_null.c Thu Dec 4 04:16:33 2003 @@ -0,0 +1,133 @@ +/* + * ipsec_alg NULL cipher stubs + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_null.c,v 1.6 2003/12/04 03:16:33 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * Fixes by: + * DDR: David De Reu + * Fixes: + * DDR: comply to RFC2410 and make it interop with other impl. + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_NULL +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* Low freeswan header coupling */ +#include "ipsec_alg.h" + +#define ESP_NULL 11 /* from ipsec drafts */ +#define ESP_NULL_BLK_LEN 1 /* from RFC 2410 */ +#define ESP_NULL_IV_LEN 0 /* from RFC 2410 */ + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); + +typedef int null_context; + +struct null_eks{ + null_context null_ctx; +}; +static int _null_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { + null_context *ctx=&((struct null_eks*)key_e)->null_ctx; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_null_set_key:" + "key_e=%p key=%p keysize=%d\n", + key_e, key, (int)keysize); + *ctx = 1; + return 0; +} +static int _null_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { + null_context *ctx=&((struct null_eks*)key_e)->null_ctx; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_null_cbc_encrypt:" + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", + key_e, in, ilen, iv, encrypt); + (*ctx)++; + return ilen; +} +static struct ipsec_alg_enc ipsec_alg_NULL = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, + ixt_alg_id: ESP_NULL, + ixt_name: "null", + ixt_blocksize: ESP_NULL_BLK_LEN, + ixt_ivlen: ESP_NULL_IV_LEN, + ixt_keyminbits: 0, + ixt_keymaxbits: 0, + ixt_e_keylen: 0, + ixt_e_ctx_size: sizeof(null_context), + ixt_e_set_key: _null_set_key, + ixt_e_cbc_encrypt:_null_cbc_encrypt, +}; + +IPSEC_ALG_MODULE_INIT(ipsec_null_init) +{ + int ret, test_ret; + if (excl) ipsec_alg_NULL.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_enc(&ipsec_alg_NULL); + printk("ipsec_null_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_NULL.ixt_alg_type, + ipsec_alg_NULL.ixt_alg_id, + ipsec_alg_NULL.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_NULL.ixt_alg_type, + ipsec_alg_NULL.ixt_alg_id, + test); + printk("ipsec_null_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_NULL.ixt_alg_type, + ipsec_alg_NULL.ixt_alg_id, + test_ret); + } + return ret; +} +IPSEC_ALG_MODULE_EXIT(ipsec_null_fini) +{ + unregister_ipsec_alg_enc(&ipsec_alg_NULL); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_serpent.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_serpent.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_serpent.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_serpent.c Thu Dec 4 04:16:33 2003 @@ -0,0 +1,139 @@ +/* + * ipsec_alg SERPENT cipher stubs + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_serpent.c,v 1.5 2003/12/04 03:16:33 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_SERPENT +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* Low freeswan header coupling */ +#include "ipsec_alg.h" +#include "libserpent/serpent.h" +#include "libserpent/serpent_cbc.h" + +#define ESP_SERPENT 252 /* from ipsec drafts */ + +/* 128, 192 or 256 */ +#define ESP_SERPENT_KEY_SZ_MIN 16 /* 128 bit secret key */ +#define ESP_SERPENT_KEY_SZ_MAX 32 /* 256 bit secret key */ +#define ESP_SERPENT_CBC_BLK_LEN 16 /* SERPENT-CBC block size */ + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); +static int keyminbits=0; +MODULE_PARM(keyminbits, "i"); +static int keymaxbits=0; +MODULE_PARM(keymaxbits, "i"); + +static int _serpent_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { + serpent_context *ctx=(serpent_context *)key_e; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_serpent_set_key:" + "key_e=%p key=%p keysize=%d\n", + key_e, key, (int)keysize); + serpent_set_key(ctx, key, keysize); + return 0; +} +static int _serpent_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { + serpent_context *ctx=(serpent_context *)key_e; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_serpent_cbc_encrypt:" + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", + key_e, in, ilen, iv, encrypt); + serpent_cbc_encrypt(ctx, in, in, ilen, iv, encrypt); + return ilen; +} +static struct ipsec_alg_enc ipsec_alg_SERPENT = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, + ixt_alg_id: ESP_SERPENT, + ixt_name: "serpent", + ixt_blocksize: ESP_SERPENT_CBC_BLK_LEN, + ixt_keyminbits: ESP_SERPENT_KEY_SZ_MIN * 8, + ixt_keymaxbits: ESP_SERPENT_KEY_SZ_MAX * 8, + ixt_e_keylen: ESP_SERPENT_KEY_SZ_MAX, + ixt_e_ctx_size: sizeof(serpent_context), + ixt_e_set_key: _serpent_set_key, + ixt_e_cbc_encrypt:_serpent_cbc_encrypt, +}; + +IPSEC_ALG_MODULE_INIT(ipsec_serpent_init) +{ + int ret, test_ret; + if (keyminbits) + ipsec_alg_SERPENT.ixt_keyminbits=keyminbits; + if (keymaxbits) { + ipsec_alg_SERPENT.ixt_keymaxbits=keymaxbits; + if (keymaxbits*8>ipsec_alg_SERPENT.ixt_keymaxbits) + ipsec_alg_SERPENT.ixt_e_keylen=keymaxbits*8; + } + if (excl) ipsec_alg_SERPENT.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_enc(&ipsec_alg_SERPENT); + printk("ipsec_serpent_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_SERPENT.ixt_alg_type, + ipsec_alg_SERPENT.ixt_alg_id, + ipsec_alg_SERPENT.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_SERPENT.ixt_alg_type, + ipsec_alg_SERPENT.ixt_alg_id, + test); + printk("ipsec_serpent_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_SERPENT.ixt_alg_type, + ipsec_alg_SERPENT.ixt_alg_id, + test_ret); + } + return ret; +} +IPSEC_ALG_MODULE_EXIT(ipsec_serpent_fini) +{ + unregister_ipsec_alg_enc(&ipsec_alg_SERPENT); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_sha1.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_sha1.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_sha1.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_sha1.c Fri Feb 7 14:14:25 2003 @@ -0,0 +1,122 @@ +/* + * ipsec_alg SHA1 hash stubs + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_sha1.c,v 1.2 2003/02/07 13:14:25 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_SHA1 +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* Low freeswan header coupling */ +#include "ipsec_alg.h" +#include "libsha1/sha.h" +#include "libsha1/hmac_sha1.h" + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); + +#define AH_SHA 3 + +static int _sha1_hmac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) { + sha1_hmac_context *hctx=(sha1_hmac_context*)(key_a); + sha1_hmac_set_key(hctx, key, keylen); + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _sha1_hmac_set_key(): " + "key_a=%p key=%p keysize=%d\n", + key_a, key, keylen); + return 0; +} +static int _sha1_hmac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) { + sha1_hmac_context *hctx=(sha1_hmac_context*)(key_a); + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _sha1_hmac_hash(): " + "key_a=%p dat=%p len=%d hash=%p hashlen=%d\n", + key_a, dat, len, hash, hashlen); + sha1_hmac_hash(hctx, dat, len, hash, hashlen); + return 0; +} +static struct ipsec_alg_auth ipsec_alg_SHA1 = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_AUTH, + ixt_alg_id: AH_SHA, + ixt_name: "sha1", + ixt_blocksize: SHA1_BLOCKSIZE, + ixt_keyminbits: 160, + ixt_keymaxbits: 160, + ixt_a_keylen: 160/8, + ixt_a_ctx_size: sizeof(sha1_hmac_context), + ixt_a_hmac_set_key: _sha1_hmac_set_key, + ixt_a_hmac_hash: _sha1_hmac_hash, +}; +IPSEC_ALG_MODULE_INIT( ipsec_sha1_init ) +{ + int ret, test_ret; + if (excl) ipsec_alg_SHA1.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_auth(&ipsec_alg_SHA1); + printk("ipsec_sha1_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_SHA1.ixt_alg_type, + ipsec_alg_SHA1.ixt_alg_id, + ipsec_alg_SHA1.ixt_name, + ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_SHA1.ixt_alg_type, + ipsec_alg_SHA1.ixt_alg_id, + test); + printk("ipsec_sha1_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_SHA1.ixt_alg_type, + ipsec_alg_SHA1.ixt_alg_id, + test_ret); + } + return ret; +} +IPSEC_ALG_MODULE_EXIT( ipsec_sha1_fini ) +{ + unregister_ipsec_alg_auth(&ipsec_alg_SHA1); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_sha2.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_sha2.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_sha2.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_sha2.c Fri Feb 7 14:14:25 2003 @@ -0,0 +1,185 @@ +/* + * ipsec_alg SHA2 hash stubs + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_sha2.c,v 1.2 2003/02/07 13:14:25 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_SHA2 +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* Low freeswan header coupling */ +#include "ipsec_alg.h" +#include "libsha2/sha2.h" +#include "libsha2/hmac_sha2.h" + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); + +/* almost constants ...: draft-ietf-ipsec-ciph-aes-cbc-03.txt */ +#define AH_SHA2_256 5 +#define AH_SHA2_384 6 +#define AH_SHA2_512 7 + +static int _sha256_hmac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) { + sha256_hmac_context *hctx=(sha256_hmac_context*)(key_a); + sha256_hmac_set_key(hctx, key, keylen); + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _sha256_hmac_set_key(): " + "key_a=%p key=%p keysize=%d\n", + key_a, key, keylen); + return 0; +} +static int _sha256_hmac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) { + sha256_hmac_context *hctx=(sha256_hmac_context*)(key_a); + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _sha256_hmac_hash(): " + "key_a=%p dat=%p len=%d hash=%p hashlen=%d\n", + key_a, dat, len, hash, hashlen); + sha256_hmac_hash(hctx, dat, len, hash, hashlen); + return 0; +} +static int _sha512_hmac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) { + sha512_hmac_context *hctx=(sha512_hmac_context*)(key_a); + sha512_hmac_set_key(hctx, key, keylen); + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _sha512_hmac_set_key(): " + "key_a=%p key=%p keysize=%d\n", + key_a, key, keylen); + return 0; +} +static int _sha512_hmac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) { + sha512_hmac_context *hctx=(sha512_hmac_context*)(key_a); + if (debug > 0) + printk(KERN_DEBUG "klips_debug: _sha512_hmac_hash(): " + "key_a=%p dat=%p len=%d hash=%p hashlen=%d\n", + key_a, dat, len, hash, hashlen); + sha512_hmac_hash(hctx, dat, len, hash, hashlen); + return 0; +} +static struct ipsec_alg_auth ipsec_alg_SHA2_256 = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_AUTH, + ixt_alg_id: AH_SHA2_256, + ixt_name: "sha2_256", + ixt_blocksize: SHA256_BLOCKSIZE, + ixt_keyminbits: 256, + ixt_keymaxbits: 256, + ixt_a_keylen: 256/8, + ixt_a_ctx_size: sizeof(sha256_hmac_context), + ixt_a_hmac_set_key: _sha256_hmac_set_key, + ixt_a_hmac_hash: _sha256_hmac_hash, +}; +static struct ipsec_alg_auth ipsec_alg_SHA2_512 = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_AUTH, + ixt_alg_id: AH_SHA2_512, + ixt_name: "sha2_512", + ixt_blocksize: SHA512_BLOCKSIZE, + ixt_keyminbits: 512, + ixt_keymaxbits: 512, + ixt_a_keylen: 512/8, + ixt_a_ctx_size: sizeof(sha512_hmac_context), + ixt_a_hmac_set_key: _sha512_hmac_set_key, + ixt_a_hmac_hash: _sha512_hmac_hash, +}; + +IPSEC_ALG_MODULE_INIT( ipsec_sha2_init ) +{ + int ret, test_ret; + if (excl) ipsec_alg_SHA2_256.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_auth(&ipsec_alg_SHA2_256); + printk("ipsec_sha2_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_SHA2_256.ixt_alg_type, + ipsec_alg_SHA2_256.ixt_alg_id, + ipsec_alg_SHA2_256.ixt_name, + ret); + if (ret != 0) + goto out; + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_SHA2_256.ixt_alg_type, + ipsec_alg_SHA2_256.ixt_alg_id, + test); + printk("ipsec_sha2_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_SHA2_256.ixt_alg_type, + ipsec_alg_SHA2_256.ixt_alg_id, + test_ret); + } + if (excl) ipsec_alg_SHA2_512.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_auth(&ipsec_alg_SHA2_512); + printk("ipsec_sha2_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_SHA2_512.ixt_alg_type, + ipsec_alg_SHA2_512.ixt_alg_id, + ipsec_alg_SHA2_512.ixt_name, + ret); + if (ret != 0) + goto out_256; + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_SHA2_512.ixt_alg_type, + ipsec_alg_SHA2_512.ixt_alg_id, + test); + printk("ipsec_sha2_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_SHA2_512.ixt_alg_type, + ipsec_alg_SHA2_512.ixt_alg_id, + test_ret); + } + goto out; +out_256: + unregister_ipsec_alg_auth(&ipsec_alg_SHA2_256); +out: + return ret; +} +IPSEC_ALG_MODULE_EXIT( ipsec_sha2_fini ) +{ + unregister_ipsec_alg_auth(&ipsec_alg_SHA2_512); + unregister_ipsec_alg_auth(&ipsec_alg_SHA2_256); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +EXPORT_NO_SYMBOLS; diff -urN linux-2.4.29/net/ipsec/alg/ipsec_alg_twofish.c linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_twofish.c --- linux-2.4.29/net/ipsec/alg/ipsec_alg_twofish.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/ipsec_alg_twofish.c Thu Dec 4 04:16:33 2003 @@ -0,0 +1,138 @@ +/* + * ipsec_alg TWOFISH cipher stubs + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg_twofish.c,v 1.5 2003/12/04 03:16:33 ken Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#include +#include + +/* + * special case: ipsec core modular with this static algo inside: + * must avoid MODULE magic for this file + */ +#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_TWOFISH +#undef MODULE +#endif + +#include +#include + +#include /* printk() */ +#include /* error codes */ +#include /* size_t */ +#include + +/* Check if __exit is defined, if not null it */ +#ifndef __exit +#define __exit +#endif + +/* Low freeswan header coupling */ +#include "ipsec_alg.h" +#include "libtwofish/twofish.h" +#include "libtwofish/twofish_cbc.h" + +#define ESP_TWOFISH 253 /* from ipsec drafts */ + +/* 128, 192 or 256 */ +#define ESP_TWOFISH_KEY_SZ_MIN 16 /* 128 bit secret key */ +#define ESP_TWOFISH_KEY_SZ_MAX 32 /* 256 bit secret key */ +#define ESP_TWOFISH_CBC_BLK_LEN 16 /* TWOFISH-CBC block size */ + +MODULE_AUTHOR("JuanJo Ciarlante "); +static int debug=0; +MODULE_PARM(debug, "i"); +static int test=0; +MODULE_PARM(test, "i"); +static int excl=0; +MODULE_PARM(excl, "i"); +static int keyminbits=0; +MODULE_PARM(keyminbits, "i"); +static int keymaxbits=0; +MODULE_PARM(keymaxbits, "i"); + +static int _twofish_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) { + twofish_context *ctx=(twofish_context *)key_e; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_twofish_set_key:" + "key_e=%p key=%p keysize=%d\n", + key_e, key, (int)keysize); + twofish_set_key(ctx, key, keysize); + return 0; +} +static int _twofish_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) { + twofish_context *ctx=(twofish_context *)key_e; + if (debug > 0) + printk(KERN_DEBUG "klips_debug:_twofish_cbc_encrypt:" + "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n", + key_e, in, ilen, iv, encrypt); + twofish_cbc_encrypt(ctx, in, in, ilen, iv, encrypt); + return ilen; +} +static struct ipsec_alg_enc ipsec_alg_TWOFISH = { + ixt_version: IPSEC_ALG_VERSION, + ixt_module: THIS_MODULE, + ixt_refcnt: ATOMIC_INIT(0), + ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT, + ixt_alg_id: ESP_TWOFISH, + ixt_name: "twofish", + ixt_blocksize: ESP_TWOFISH_CBC_BLK_LEN, + ixt_keyminbits: ESP_TWOFISH_KEY_SZ_MIN * 8, + ixt_keymaxbits: ESP_TWOFISH_KEY_SZ_MAX * 8, + ixt_e_keylen: ESP_TWOFISH_KEY_SZ_MAX, + ixt_e_ctx_size: sizeof(twofish_context), + ixt_e_set_key: _twofish_set_key, + ixt_e_cbc_encrypt:_twofish_cbc_encrypt, +}; + +IPSEC_ALG_MODULE_INIT( ipsec_twofish_init ) +{ + int ret, test_ret; + if (keyminbits) + ipsec_alg_TWOFISH.ixt_keyminbits=keyminbits; + if (keymaxbits) { + ipsec_alg_TWOFISH.ixt_keymaxbits=keymaxbits; + if (keymaxbits*8>ipsec_alg_TWOFISH.ixt_keymaxbits) + ipsec_alg_TWOFISH.ixt_e_keylen=keymaxbits*8; + } + if (excl) ipsec_alg_TWOFISH.ixt_state |= IPSEC_ALG_ST_EXCL; + ret=register_ipsec_alg_enc(&ipsec_alg_TWOFISH); + printk("ipsec_twofish_init(alg_type=%d alg_id=%d name=%s): ret=%d\n", + ipsec_alg_TWOFISH.ixt_alg_type, + ipsec_alg_TWOFISH.ixt_alg_id, + ipsec_alg_TWOFISH.ixt_name, ret); + if (ret==0 && test) { + test_ret=ipsec_alg_test( + ipsec_alg_TWOFISH.ixt_alg_type, + ipsec_alg_TWOFISH.ixt_alg_id, + test); + printk("ipsec_twofish_init(alg_type=%d alg_id=%d): test_ret=%d\n", + ipsec_alg_TWOFISH.ixt_alg_type, + ipsec_alg_TWOFISH.ixt_alg_id, + ret); + } + return ret; +} +IPSEC_ALG_MODULE_EXIT( ipsec_twofish_fini ) +{ + unregister_ipsec_alg_enc(&ipsec_alg_TWOFISH); + return; +} +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); + +EXPORT_NO_SYMBOLS; +#endif diff -urN linux-2.4.29/net/ipsec/alg/scripts/mk-static_init.c.sh linux-2.4.29-openswan-1.0.9/net/ipsec/alg/scripts/mk-static_init.c.sh --- linux-2.4.29/net/ipsec/alg/scripts/mk-static_init.c.sh Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/alg/scripts/mk-static_init.c.sh Thu Sep 5 05:36:54 2002 @@ -0,0 +1,17 @@ +#!/bin/sh +cat << EOF +#include +#include "../ipsec_alg.h" +$(for i in $*; do + test -z "$i" && continue + echo "extern int $i(void);" +done) +void ipsec_alg_static_init(void){ + int __attribute__ ((unused)) err=0; +$(for i in $*; do + test -z "$i" && continue + echo " if ((err=$i()) < 0)" + echo " printk(KERN_WARNING \"$i() returned %d\", err);" +done) +} +EOF diff -urN linux-2.4.29/net/ipsec/defconfig linux-2.4.29-openswan-1.0.9/net/ipsec/defconfig --- linux-2.4.29/net/ipsec/defconfig Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/defconfig Mon Oct 25 21:29:13 2004 @@ -0,0 +1,140 @@ + +# +# RCSID $Id: defconfig,v 1.6 2004/10/25 19:29:13 ken Exp $ +# + +# +# FreeS/WAN IPSec implementation, KLIPS kernel config defaults +# + +# +# First, lets override stuff already set or not in the kernel config. +# +# We can't even think about leaving this off... +CONFIG_INET=y + +# +# This must be on for subnet protection. +CONFIG_IP_FORWARD=y + +# Shut off IPSEC masquerading if it has been enabled, since it will +# break the compile. IPPROTO_ESP and IPPROTO_AH were included in +# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h. +CONFIG_IP_MASQUERADE_IPSEC=n + +# +# Next, lets set the recommended FreeS/WAN configuration. +# + +# To config as static (preferred), 'y'. To config as module, 'm'. +CONFIG_IPSEC=m + +# To do tunnel mode IPSec, this must be enabled. +CONFIG_IPSEC_IPIP=y + +# To enable authentication, say 'y'. (Highly recommended) +CONFIG_IPSEC_AH=y + +# Authentication algorithm(s): +CONFIG_IPSEC_AUTH_HMAC_MD5=y +CONFIG_IPSEC_AUTH_HMAC_SHA1=y + +# To enable encryption, say 'y'. (Highly recommended) +CONFIG_IPSEC_ESP=y + +# Encryption algorithm(s): +CONFIG_IPSEC_ENC_3DES=y + +# IP Compression: new, probably still has minor bugs. +CONFIG_IPSEC_IPCOMP=y + +# To enable userspace-switchable KLIPS debugging, say 'y'. +CONFIG_IPSEC_DEBUG=y + +# modular algo extensions (and new ALGOs) +CONFIG_IPSEC_ALG=y +CONFIG_IPSEC_ALG_AES=m +CONFIG_IPSEC_ALG_TWOFISH=m +CONFIG_IPSEC_ALG_SERPENT=m +CONFIG_IPSEC_ALG_MD5=m +CONFIG_IPSEC_ALG_SHA1=m +CONFIG_IPSEC_ALG_SHA2=m +CONFIG_IPSEC_ALG_3DES=m +CONFIG_IPSEC_ALG_BLOWFISH=m + +# NAT Traversal +CONFIG_IPSEC_NAT_TRAVERSAL=y + +# Use CryptoAPI for ALG? +CONFIG_IPSEC_ALG_CRYPTOAPI=n + +# NAT Traversal +CONFIG_IPSEC_NAT_TRAVERSAL=y + +# +# +# $Log: defconfig,v $ +# Revision 1.6 2004/10/25 19:29:13 ken +# Add defaults for modular algs +# +# Revision 1.5 2003/07/04 19:07:34 ken +# Added NAT-T 0.6 diff/patch from Tuomo +# +# Revision 1.4 2003/02/21 22:59:21 ken +# Set default for CONFIG_IPSEC_ALG_CRYPTOAPI=n +# +# Revision 1.3 2002/09/05 16:50:58 ken +# Enabled NAT-T by default +# +# Revision 1.2 2002/09/05 03:27:08 ken +# Applied freeswan-alg-0.8.0-BASE-klips.diff +# +# Revision 1.1.1.1 2002/09/05 03:13:17 ken +# 1.98b +# +# Revision 1.20 2002/04/02 04:07:40 mcr +# default build is now 'm'odule for KLIPS +# +# Revision 1.19 2002/03/08 18:57:17 rgb +# Added a blank line at the beginning of the file to make it easier for +# other projects to patch ./arch/i386/defconfig, for example +# LIDS+grSecurity requested by Jason Pattie. +# +# Revision 1.18 2000/11/30 17:26:56 rgb +# Cleaned out unused options and enabled ipcomp by default. +# +# Revision 1.17 2000/09/15 11:37:01 rgb +# Merge in heavily modified Svenning Soerensen's +# IPCOMP zlib deflate code. +# +# Revision 1.16 2000/09/08 19:12:55 rgb +# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. +# +# Revision 1.15 2000/05/24 19:37:13 rgb +# *** empty log message *** +# +# Revision 1.14 2000/05/11 21:14:57 henry +# just commenting the FOOBAR=y lines out is not enough +# +# Revision 1.13 2000/05/10 20:17:58 rgb +# Comment out netlink defaults, which are no longer needed. +# +# Revision 1.12 2000/05/10 19:13:38 rgb +# Added configure option to shut off no eroute passthrough. +# +# Revision 1.11 2000/03/16 07:09:46 rgb +# Hardcode PF_KEYv2 support. +# Disable IPSEC_ICMP by default. +# Remove DES config option from defaults file. +# +# Revision 1.10 2000/01/11 03:09:42 rgb +# Added a default of 'y' to PF_KEYv2 keying I/F. +# +# Revision 1.9 1999/05/08 21:23:12 rgb +# Added support for 2.2.x kernels. +# +# Revision 1.8 1999/04/06 04:54:25 rgb +# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes +# patch shell fixes. +# +# diff -urN linux-2.4.29/net/ipsec/ipcomp.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipcomp.c --- linux-2.4.29/net/ipsec/ipcomp.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipcomp.c Thu Dec 4 04:11:29 2003 @@ -0,0 +1,742 @@ +/* + * IPCOMP zlib interface code. + * Copyright (C) 2000 Svenning Soerensen + * Copyright (C) 2000, 2001 Richard Guy Briggs + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +char ipcomp_c_version[] = "RCSID $Id: ipcomp.c,v 1.3 2003/12/04 03:11:29 ken Exp $"; + +/* SSS */ + +#include +#include + +#define __NO_VERSION__ +#include +#include /* printk() */ + +#define IPSEC_KLIPS1_COMPAT +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include +#include +#include +#include + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include + +#include +#ifdef NET_21 +# include +# include +# include +# define proto_priv cb +#endif /* NET21 */ +#include +#include + +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_sa.h" + +#include "ipsec_netlink.h" +#include "ipsec_xform.h" +#include "ipsec_tunnel.h" +#include "ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */ +#include "ipcomp.h" +#include "zlib/zlib.h" +#include "zlib/zutil.h" + +#include /* SADB_X_CALG_DEFLATE */ + +#ifdef CONFIG_IPSEC_DEBUG +int sysctl_ipsec_debug_ipcomp = 0; +#endif /* CONFIG_IPSEC_DEBUG */ + +static +struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask); + +static +voidpf my_zcalloc(voidpf opaque, uInt items, uInt size) +{ + return (voidpf) kmalloc(items*size, GFP_ATOMIC); +} + +static +void my_zfree(voidpf opaque, voidpf address) +{ + kfree(address); +} + +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *tdb, unsigned int *flags) +{ + struct iphdr *iph; + unsigned int iphlen, pyldsz, cpyldsz; + unsigned char *buffer; + z_stream zs; + int zresult; + + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: .\n"); + + if(!skb) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "passed in NULL skb, returning ERROR.\n"); + if (flags) *flags |= IPCOMP_PARMERROR; + return skb; + } + + if(!tdb) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "passed in NULL tdb needed for cpi, returning ERROR.\n"); + if (flags) *flags |= IPCOMP_PARMERROR; + return skb; + } + + if (!flags) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "passed in NULL flags, returning ERROR.\n"); +#ifdef NET_21 + kfree_skb(skb); +#else /* NET_21 */ + dev_kfree_skb(skb, FREE_WRITE); +#endif /* NET_21 */ + return NULL; + } + +#ifdef NET_21 + iph = skb->nh.iph; +#else /* NET_21 */ + iph = skb->ip_hdr; +#endif /* NET_21 */ + + switch (iph->protocol) { + case IPPROTO_COMP: + case IPPROTO_AH: + case IPPROTO_ESP: + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "skipping compression of packet with ip protocol %d.\n", + iph->protocol); + *flags |= IPCOMP_UNCOMPRESSABLE; + return skb; + } + + /* Don't compress packets already fragmented */ + if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "skipping compression of fragmented packet.\n"); + *flags |= IPCOMP_UNCOMPRESSABLE; + return skb; + } + + iphlen = iph->ihl << 2; + pyldsz = ntohs(iph->tot_len) - iphlen; + + /* Don't compress less than 90 bytes (rfc 2394) */ + if (pyldsz < 90) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "skipping compression of tiny packet, len=%d.\n", + pyldsz); + *flags |= IPCOMP_UNCOMPRESSABLE; + return skb; + } + + /* Adaptive decision */ + if (tdb->tdb_comp_adapt_skip) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "skipping compression: tdb_comp_adapt_skip=%d.\n", + tdb->tdb_comp_adapt_skip); + tdb->tdb_comp_adapt_skip--; + *flags |= IPCOMP_UNCOMPRESSABLE; + return skb; + } + + zs.zalloc = my_zcalloc; + zs.zfree = my_zfree; + zs.opaque = 0; + + /* We want to use deflateInit2 because we don't want the adler + header. */ + zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11, + DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); + if (zresult != Z_OK) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_compress: " + "deflateInit2() returned error %d (%s), " + "skipping compression.\n", + zresult, + zs.msg ? zs.msg : zError(zresult)); + *flags |= IPCOMP_COMPRESSIONERROR; + return skb; + } + + + /* Max output size. Result should be max this size. + * Implementation specific tweak: + * If it's not at least 32 bytes and 6.25% smaller than + * the original packet, it's probably not worth wasting + * the receiver's CPU cycles decompressing it. + * Your mileage may vary. + */ + cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4); + + buffer = kmalloc(cpyldsz, GFP_ATOMIC); + if (!buffer) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_compress: " + "unable to kmalloc(%d, GFP_ATOMIC), " + "skipping compression.\n", + cpyldsz); + *flags |= IPCOMP_COMPRESSIONERROR; + deflateEnd(&zs); + return skb; + } + +#ifdef CONFIG_IPSEC_DEBUG + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { + __u8 *c; + int i; + + c = (__u8*)iph + iphlen; + for(i = 0; i < pyldsz; i++, c++) { + if(!(i % 16)) { + printk(KERN_INFO "skb_compress: before:"); + } + printk("%02x ", *c); + if(!((i + 1) % 16)) { + printk("\n"); + } + } + if(i % 16) { + printk("\n"); + } + } +#endif /* CONFIG_IPSEC_DEBUG */ + + zs.next_in = (char *) iph + iphlen; /* start of payload */ + zs.avail_in = pyldsz; + zs.next_out = buffer; /* start of compressed payload */ + zs.avail_out = cpyldsz; + + /* Finish compression in one step */ + zresult = deflate(&zs, Z_FINISH); + + /* Free all dynamically allocated buffers */ + deflateEnd(&zs); + if (zresult != Z_STREAM_END) { + *flags |= IPCOMP_UNCOMPRESSABLE; + kfree(buffer); + + /* Adjust adaptive counters */ + if (++(tdb->tdb_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "first %d packets didn't compress, " + "skipping next %d\n", + IPCOMP_ADAPT_INITIAL_TRIES, + IPCOMP_ADAPT_INITIAL_SKIP); + tdb->tdb_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP; + } + else if (tdb->tdb_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "next %d packets didn't compress, " + "skipping next %d\n", + IPCOMP_ADAPT_SUBSEQ_TRIES, + IPCOMP_ADAPT_SUBSEQ_SKIP); + tdb->tdb_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP; + tdb->tdb_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES; + } + + return skb; + } + + /* resulting compressed size */ + cpyldsz -= zs.avail_out; + + /* Insert IPCOMP header */ + ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol; + ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0; + /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are + for internal reference only. */ + ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(tdb->tdb_said.spi) & 0x0000ffff)); + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_compress: " + "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n", + ntohl(tdb->tdb_said.spi), + ntohl(tdb->tdb_said.spi) & 0x0000ffff, + ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi), + pyldsz, + cpyldsz); + + /* Update IP header */ + iph->protocol = IPPROTO_COMP; + iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz); +#if 1 /* XXX checksum is done by ipsec_tunnel ? */ + iph->check = 0; + iph->check = ip_fast_csum((char *) iph, iph->ihl); +#endif + + /* Copy compressed payload */ + memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr), + buffer, + cpyldsz); + kfree(buffer); + + /* Update skb length/tail by "unputting" the shrinkage */ + skb_put(skb, + cpyldsz + sizeof(struct ipcomphdr) - pyldsz); + +#ifdef CONFIG_IPSEC_DEBUG + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { + __u8 *c; + int i; + + c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr); + for(i = 0; i < cpyldsz; i++, c++) { + if(!(i % 16)) { + printk(KERN_INFO "skb_compress: result:"); + } + printk("%02x ", *c); + if(!((i + 1) % 16)) { + printk("\n"); + } + } + if(i % 16) { + printk("\n"); + } + } +#endif /* CONFIG_IPSEC_DEBUG */ + + tdb->tdb_comp_adapt_skip = 0; + tdb->tdb_comp_adapt_tries = 0; + + return skb; +} + +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *tdb, unsigned int *flags) +{ + struct sk_buff *nskb = NULL; + + /* original ip header */ + struct iphdr *oiph, *iph; + unsigned int iphlen, pyldsz, cpyldsz; + z_stream zs; + int zresult; + + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_decompress: .\n"); + + if(!skb) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "passed in NULL skb, returning ERROR.\n"); + if (flags) *flags |= IPCOMP_PARMERROR; + return skb; + } + + if(!tdb && sysctl_ipsec_inbound_policy_check) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "passed in NULL tdb needed for comp alg, returning ERROR.\n"); + if (flags) *flags |= IPCOMP_PARMERROR; + return skb; + } + + if (!flags) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "passed in NULL flags, returning ERROR.\n"); +#ifdef NET_21 + kfree_skb(skb); +#else /* NET_21 */ + dev_kfree_skb(skb, FREE_WRITE); +#endif /* NET_21 */ + return NULL; + } + +#ifdef NET_21 + oiph = skb->nh.iph; +#else /* NET_21 */ + oiph = skb->ip_hdr; +#endif /* NET_21 */ + + iphlen = oiph->ihl << 2; + + if (oiph->protocol != IPPROTO_COMP) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "called with non-IPCOMP packet (protocol=%d)," + "skipping decompression.\n", + oiph->protocol); + *flags |= IPCOMP_PARMERROR; + return skb; + } + + if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0) + || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi + != htons(SADB_X_CALG_DEFLATE)) + && sysctl_ipsec_inbound_policy_check + && (!tdb || (tdb && (tdb->tdb_encalg != SADB_X_CALG_DEFLATE)))) ) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "called with incompatible IPCOMP packet (flags=%d, " + "cpi=%d), tdb-compalg=%d, skipping decompression.\n", + ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags), + ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi), + tdb ? tdb->tdb_encalg : 0); + *flags |= IPCOMP_PARMERROR; + + return skb; + } + + if (ntohs(oiph->frag_off) & ~0x4000) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "called with fragmented IPCOMP packet, " + "skipping decompression.\n"); + *flags |= IPCOMP_PARMERROR; + return skb; + } + + /* original compressed payload size */ + cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr); + + zs.zalloc = my_zcalloc; + zs.zfree = my_zfree; + zs.opaque = 0; + + zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr); + zs.avail_in = cpyldsz; + + /* Maybe we should be a bit conservative about memory + requirements and use inflateInit2 */ + /* Beware, that this might make us unable to decompress packets + from other implementations - HINT: check PGPnet source code */ + /* We want to use inflateInit2 because we don't want the adler + header. */ + zresult = inflateInit2(&zs, -15); + if (zresult != Z_OK) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "inflateInit2() returned error %d (%s), " + "skipping decompression.\n", + zresult, + zs.msg ? zs.msg : zError(zresult)); + *flags |= IPCOMP_DECOMPRESSIONERROR; + + return skb; + } + + /* We have no way of knowing the exact length of the resulting + decompressed output before we have actually done the decompression. + For now, we guess that the packet will not be bigger than the + attached ipsec device's mtu or 16260, whichever is biggest. + This may be wrong, since the sender's mtu may be bigger yet. + XXX This must be dealt with later XXX + */ + + /* max payload size */ + pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu) + : (65520 - iphlen); + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_decompress: " + "max payload size: %d\n", pyldsz); + + while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) && + (nskb = skb_copy_ipcomp(skb, + pyldsz - cpyldsz - sizeof(struct ipcomphdr), + GFP_ATOMIC)) == NULL) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), " + "trying with less payload size.\n", + (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr))); + pyldsz >>=1; + } + + if (!nskb) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "unable to allocate memory, dropping packet.\n"); + *flags |= IPCOMP_DECOMPRESSIONERROR; + inflateEnd(&zs); + + return skb; + } + +#ifdef CONFIG_IPSEC_DEBUG + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { + __u8 *c; + int i; + + c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr); + for(i = 0; i < cpyldsz; i++, c++) { + if(!(i % 16)) { + printk(KERN_INFO "skb_decompress: before:"); + } + printk("%02x ", *c); + if(!((i + 1) % 16)) { + printk("\n"); + } + } + if(i % 16) { + printk("\n"); + } + } +#endif /* CONFIG_IPSEC_DEBUG */ + +#ifdef NET_21 + iph = nskb->nh.iph; +#else /* NET_21 */ + iph = nskb->ip_hdr; +#endif /* NET_21 */ + zs.next_out = (char *)iph + iphlen; + zs.avail_out = pyldsz; + + zresult = inflate(&zs, Z_SYNC_FLUSH); + + /* work around a bug in zlib, which sometimes wants to taste an extra + * byte when being used in the (undocumented) raw deflate mode. + */ + if (zresult == Z_OK && !zs.avail_in && zs.avail_out) { + __u8 zerostuff = 0; + + zs.next_in = &zerostuff; + zs.avail_in = 1; + zresult = inflate(&zs, Z_FINISH); + } + + inflateEnd(&zs); + if (zresult != Z_STREAM_END) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_error:skb_decompress: " + "inflate() returned error %d (%s), " + "skipping decompression.\n", + zresult, + zs.msg ? zs.msg : zError(zresult)); + *flags |= IPCOMP_DECOMPRESSIONERROR; +#ifdef NET_21 + kfree_skb(nskb); +#else /* NET_21 */ + dev_kfree_skb(nskb, FREE_WRITE); +#endif /* NET_21 */ + + return skb; + } + + /* Update IP header */ + /* resulting decompressed size */ + pyldsz -= zs.avail_out; + iph->tot_len = htons(iphlen + pyldsz); + iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh; + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_decompress: " + "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n", + tdb ? ntohl(tdb->tdb_said.spi) : 0, + tdb ? ntohl(tdb->tdb_said.spi) & 0x0000ffff : 0, + ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi), + cpyldsz, + pyldsz, + iph->protocol); + +#if 1 /* XXX checksum is done by ipsec_rcv ? */ + iph->check = 0; + iph->check = ip_fast_csum((char*) iph, iph->ihl); +#endif + + /* Update skb length/tail by "unputting" the unused data area */ + skb_put(nskb, -zs.avail_out); + +#ifdef NET_21 + kfree_skb(skb); +#else /* NET_21 */ + dev_kfree_skb(skb, FREE_WRITE); +#endif /* NET_21 */ + + if (iph->protocol == IPPROTO_COMP) + { +#ifdef CONFIG_IPSEC_DEBUG + if(sysctl_ipsec_debug_ipcomp) + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_decompress: " + "Eh? inner packet is also compressed, dropping.\n"); +#endif /* CONFIG_IPSEC_DEBUG */ + +#ifdef NET_21 + kfree_skb(nskb); +#else /* NET_21 */ + dev_kfree_skb(nskb, FREE_WRITE); +#endif /* NET_21 */ + return NULL; + } + +#ifdef CONFIG_IPSEC_DEBUG + if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) { + __u8 *c; + int i; + + c = (__u8*)iph + iphlen; + for(i = 0; i < pyldsz; i++, c++) { + if(!(i % 16)) { + printk(KERN_INFO "skb_decompress: result:"); + } + printk("%02x ", *c); + if(!((i + 1) % 16)) { + printk("\n"); + } + } + if(i % 16) { + printk("\n"); + } + } +#endif /* CONFIG_IPSEC_DEBUG */ + + return nskb; +} + + +/* this is derived from skb_copy() in linux 2.2.14 */ +/* May be incompatible with other kernel versions!! */ +static +struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask) +{ + struct sk_buff *n; + struct iphdr *iph; + unsigned long offset; + unsigned int iphlen; + + if(!skb) { + KLIPS_PRINT(sysctl_ipsec_debug_ipcomp, + "klips_debug:skb_copy_ipcomp: " + "passed in NULL skb, returning NULL.\n"); + return NULL; + } + + /* + * Allocate the copy buffer + */ + +#ifdef NET_21 + iph = skb->nh.iph; +#else /* NET_21 */ + iph = skb->ip_hdr; +#endif /* NET_21 */ + if (!iph) return NULL; + iphlen = iph->ihl << 2; + + n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask); + if(n==NULL) + return NULL; + + /* + * Shift between the two data areas in bytes + */ + + offset=n->head-skb->head; + + /* Set the data pointer */ + skb_reserve(n,skb->data-skb->head); + /* Set the tail pointer and length */ + skb_put(n,skb->len+data_growth); + /* Copy the bytes up to and including the ip header */ + memcpy(n->head, + skb->head, + ((char *)iph - (char *)skb->head) + iphlen); + n->list=NULL; + n->next=NULL; + n->prev=NULL; + n->sk=NULL; + n->dev=skb->dev; + if (skb->h.raw) + n->h.raw=skb->h.raw+offset; + else + n->h.raw=NULL; + n->protocol=skb->protocol; +#ifdef NET_21 + n->csum = 0; + n->priority=skb->priority; + n->dst=dst_clone(skb->dst); + n->nh.raw=skb->nh.raw+offset; +#ifndef NETDEV_23 + n->is_clone=0; +#endif /* NETDEV_23 */ + atomic_set(&n->users, 1); + n->destructor = NULL; + n->security=skb->security; + memcpy(n->cb, skb->cb, sizeof(skb->cb)); +#ifdef CONFIG_IP_FIREWALL + n->fwmark = skb->fwmark; +#endif +#else /* NET_21 */ + n->link3=NULL; + n->when=skb->when; + n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset); + n->saddr=skb->saddr; + n->daddr=skb->daddr; + n->raddr=skb->raddr; + n->seq=skb->seq; + n->end_seq=skb->end_seq; + n->ack_seq=skb->ack_seq; + n->acked=skb->acked; + n->free=1; + n->arp=skb->arp; + n->tries=0; + n->lock=0; + n->users=0; + memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv)); +#endif /* NET_21 */ + if (skb->mac.raw) + n->mac.raw=skb->mac.raw+offset; + else + n->mac.raw=NULL; +#ifndef NETDEV_23 + n->used=skb->used; +#endif /* !NETDEV_23 */ + n->pkt_type=skb->pkt_type; +#ifndef NETDEV_23 + n->pkt_bridged=skb->pkt_bridged; +#endif /* NETDEV_23 */ + n->ip_summed=0; + n->stamp=skb->stamp; +#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */ +#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) + n->shapelatency=skb->shapelatency; /* Latency on frame */ + n->shapeclock=skb->shapeclock; /* Time it should go out */ + n->shapelen=skb->shapelen; /* Frame length in clocks */ + n->shapestamp=skb->shapestamp; /* Stamp for shaper */ + n->shapepend=skb->shapepend; /* Pending */ +#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */ +#endif /* NETDEV_23 */ +#ifdef CONFIG_HIPPI + n->private.ifield=skb->private.ifield; +#endif /* CONFIG_HIPPI */ + + return n; +} diff -urN linux-2.4.29/net/ipsec/ipcomp.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipcomp.h --- linux-2.4.29/net/ipsec/ipcomp.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipcomp.h Thu Sep 5 05:13:17 2002 @@ -0,0 +1,59 @@ +/* + * IPCOMP zlib interface code. + * Copyright (C) 2000 Svenning Soerensen + * Copyright (C) 2000, 2001 Richard Guy Briggs + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + + RCSID $Id: ipcomp.h,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + + */ + +/* SSS */ + +#ifndef _IPCOMP_H +#define _IPCOMP_H + +/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */ +#define IPCOMP_PREFIX + +#ifndef IPPROTO_COMP +#define IPPROTO_COMP 108 +#endif /* IPPROTO_COMP */ + +#ifdef CONFIG_IPSEC_DEBUG +extern int sysctl_ipsec_debug_ipcomp; +#endif /* CONFIG_IPSEC_DEBUG */ + +struct ipcomphdr { /* IPCOMP header */ + __u8 ipcomp_nh; /* Next header (protocol) */ + __u8 ipcomp_flags; /* Reserved, must be 0 */ + __u16 ipcomp_cpi; /* Compression Parameter Index */ +}; + +extern struct inet_protocol comp_protocol; +extern int sysctl_ipsec_debug_ipcomp; + +#define IPCOMP_UNCOMPRESSABLE 0x000000001 +#define IPCOMP_COMPRESSIONERROR 0x000000002 +#define IPCOMP_PARMERROR 0x000000004 +#define IPCOMP_DECOMPRESSIONERROR 0x000000008 + +#define IPCOMP_ADAPT_INITIAL_TRIES 8 +#define IPCOMP_ADAPT_INITIAL_SKIP 4 +#define IPCOMP_ADAPT_SUBSEQ_TRIES 2 +#define IPCOMP_ADAPT_SUBSEQ_SKIP 8 + +/* Function prototypes */ +struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *tdb, unsigned int *flags); +struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *tdb, unsigned int *flags); + +#endif /* _IPCOMP_H */ diff -urN linux-2.4.29/net/ipsec/ipsec_ah.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_ah.h --- linux-2.4.29/net/ipsec/ipsec_ah.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_ah.h Thu Sep 5 05:27:08 2002 @@ -0,0 +1,205 @@ +/* + * Authentication Header declarations + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_ah.h,v 1.2 2002/09/05 03:27:08 ken Exp $ + */ + +#include "ipsec_md5h.h" +#include "ipsec_sha1.h" + +#ifndef IPPROTO_AH +#define IPPROTO_AH 51 +#endif /* IPPROTO_AH */ + +#define AH_FLENGTH 12 /* size of fixed part */ +#define AHMD5_KMAX 64 /* MD5 max 512 bits key */ +#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */ + +#define AHMD596_KLEN 16 /* MD5 128 bits key */ +#define AHSHA196_KLEN 20 /* SHA1 160 bits key */ + +#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */ +#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */ + +#define AHMD596_BLKLEN 64 /* MD5 block length */ +#define AHSHA196_BLKLEN 64 /* SHA1 block length */ +#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */ +#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */ +#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */ + +#define AH_BLKLEN_MAX 128 /* keep up to date! */ + +#define AH_AMAX AHSHA196_ALEN /* keep up to date! */ +#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */ +#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */ + +#define DB_AH_PKTRX 0x0001 +#define DB_AH_PKTRX2 0x0002 +#define DB_AH_DMP 0x0004 +#define DB_AH_TDB 0x0010 +#define DB_AH_XF 0x0020 +#define DB_AH_INAU 0x0040 +#define DB_AH_REPLAY 0x0100 + +#ifdef __KERNEL__ + +/* General HMAC algorithm is described in RFC 2104 */ + +#define HMAC_IPAD 0x36 +#define HMAC_OPAD 0x5C + +struct md5_ctx { + MD5_CTX ictx; /* context after H(K XOR ipad) */ + MD5_CTX octx; /* context after H(K XOR opad) */ +}; + +struct sha1_ctx { + SHA1_CTX ictx; /* context after H(K XOR ipad) */ + SHA1_CTX octx; /* context after H(K XOR opad) */ +}; + +extern struct inet_protocol ah_protocol; + +struct options; + +extern int +ah_rcv(struct sk_buff *skb, + struct device *dev, + struct options *opt, + __u32 daddr, + unsigned short len, + __u32 saddr, + int redo, + struct inet_protocol *protocol); + +struct ah /* Generic AH header */ +{ + __u8 ah_nh; /* Next header (protocol) */ + __u8 ah_hl; /* AH length, in 32-bit words */ + __u16 ah_rv; /* reserved, must be 0 */ + __u32 ah_spi; /* Security Parameters Index */ + __u32 ah_rpl; /* Replay prevention */ + __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */ +}; + +#ifdef CONFIG_IPSEC_DEBUG +extern int debug_ah; +#endif /* CONFIG_IPSEC_DEBUG */ +#endif /* __KERNEL__ */ + +/* + * $Log: ipsec_ah.h,v $ + * Revision 1.2 2002/09/05 03:27:08 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.16 2002/02/20 01:27:06 rgb + * Ditched a pile of structs only used by the old Netlink interface. + * + * Revision 1.15 2001/12/11 02:35:57 rgb + * Change "struct net_device" to "struct device" for 2.2 compatibility. + * + * Revision 1.14 2001/11/26 09:23:47 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.13.2.1 2001/09/25 02:18:24 mcr + * replace "struct device" with "struct netdevice" + * + * Revision 1.13 2001/06/14 19:35:08 rgb + * Update copyright date. + * + * Revision 1.12 2000/09/12 03:21:20 rgb + * Cleared out unused htonq. + * + * Revision 1.11 2000/09/08 19:12:55 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.10 2000/01/21 06:13:10 rgb + * Tidied up spacing. + * Added macros for HMAC padding magic numbers.(kravietz) + * + * Revision 1.9 1999/12/07 18:16:23 rgb + * Fixed comments at end of #endif lines. + * + * Revision 1.8 1999/04/11 00:28:56 henry + * GPL boilerplate + * + * Revision 1.7 1999/04/06 04:54:25 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.6 1999/01/26 02:06:01 rgb + * Removed CONFIG_IPSEC_ALGO_SWITCH macro. + * + * Revision 1.5 1999/01/22 06:17:49 rgb + * Updated macro comments. + * Added context types to support algorithm switch code. + * 64-bit clean-up -- converting 'u long long' to __u64. + * + * Revision 1.4 1998/07/14 15:54:56 rgb + * Add #ifdef __KERNEL__ to protect kernel-only structures. + * + * Revision 1.3 1998/06/30 18:05:16 rgb + * Comment out references to htonq. + * + * Revision 1.2 1998/06/25 19:33:46 rgb + * Add prototype for protocol receive function. + * Rearrange for more logical layout. + * + * Revision 1.1 1998/06/18 21:27:43 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.4 1998/05/18 22:28:43 rgb + * Disable key printing facilities from /proc/net/ipsec_*. + * + * Revision 1.3 1998/04/21 21:29:07 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.2 1998/04/12 22:03:17 rgb + * Updated ESP-3DES-HMAC-MD5-96, + * ESP-DES-HMAC-MD5-96, + * AH-HMAC-MD5-96, + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository + * from old standards (RFC182[5-9] to new (as of March 1998) drafts. + * + * Fixed eroute references in /proc/net/ipsec*. + * + * Started to patch module unloading memory leaks in ipsec_netlink and + * radij tree unloading. + * + * Revision 1.1 1998/04/09 03:05:55 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:02 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * Added definitions for new AH transforms. + * + * Revision 0.3 1996/11/20 14:35:48 ji + * Minor Cleanup. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_alg.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_alg.c --- linux-2.4.29/net/ipsec/ipsec_alg.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_alg.c Wed Nov 19 03:29:41 2003 @@ -0,0 +1,847 @@ +/* + * Modular extensions service and registration functions + * + * Author: JuanJo Ciarlante + * + * Version: 0.7.3 + * + * $Id: ipsec_alg.c,v 1.6 2003/11/19 02:29:41 mcr Exp $ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#define __NO_VERSION__ +#include +#include /* printk() */ + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include +#include +#include +#include +#include /* memcmp() */ +#include /* get_random_bytes() */ +#include /* error codes */ +#ifdef SPINLOCK +# ifdef SPINLOCK_23 +# include /* *lock* */ +# else /* SPINLOCK_23 */ +# include /* *lock* */ +# endif /* SPINLOCK_23 */ +#endif /* SPINLOCK */ +#ifdef NET_21 +# include +# include +# define proto_priv cb +#endif /* NET21 */ +#include "ipsec_param.h" +#include +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_xform.h" +#include "ipsec_tunnel.h" +#include "ipsec_rcv.h" +#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) +# include "ipsec_ah.h" +#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */ +#ifdef CONFIG_IPSEC_ESP +# include "ipsec_esp.h" +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_IPCOMP +# include "ipcomp.h" +#endif /* CONFIG_IPSEC_COMP */ + +#include +#include + +#include "ipsec_sa.h" +#include "ipsec_alg.h" + +#if SADB_EALG_MAX < 255 +#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 ) +#endif + +static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED; +#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */ +static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ]; + +/* Old gcc's will fail here */ +#define barf_out(fmt, args...) do { printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixt->ixt_name , ## args)\ + ; goto out; } while(0) + +/* + * Must be already protected by lock + */ +static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) { + if (ixt->ixt_module) + __MOD_INC_USE_COUNT(ixt->ixt_module); + atomic_inc(&ixt->ixt_refcnt); +} +static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) { + atomic_dec(&ixt->ixt_refcnt); + if (ixt->ixt_module) + __MOD_DEC_USE_COUNT(ixt->ixt_module); +} +/* + * simple hash function, optimized for 0-hash (1 list) special + * case + */ +#if IPSEC_ALG_HASHSZ > 1 +static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) { + return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1)); +} +#else +#define ipsec_alg_hashfn(x,y) (0) +#endif + +/***************************************************************** + * + * INTERNAL table handling: insert, delete, find + * + *****************************************************************/ + +/* + * hash table initialization, called from ipsec_alg_init() + */ +static void ipsec_alg_hash_init(void) { + struct list_head *head = ipsec_alg_hash_table; + int i = IPSEC_ALG_HASHSZ; + do { + INIT_LIST_HEAD(head); + head++; + i--; + } while (i); +} +/* + * hash list lookup by {alg_type, alg_id} and table head, + * must be already protected by lock + */ +static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) { + struct list_head *p; + struct ipsec_alg *ixt=NULL; + for (p=head->next; p!=head; p=p->next) { + ixt = list_entry(p, struct ipsec_alg, ixt_list); + if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) { + goto out; + } + } + ixt=NULL; +out: + return ixt; +} +/* + * inserts (in front) a new entry in hash table, + * called from ipsec_alg_register() when new algorithm is registered. + */ +static int ipsec_alg_insert(struct ipsec_alg *ixt) { + int ret=-EINVAL; + unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id); + struct list_head *head= ipsec_alg_hash_table + hashval; + struct ipsec_alg *ixt_cur; + /* new element must be virgin ... */ + if (ixt->ixt_list.next != &ixt->ixt_list || + ixt->ixt_list.prev != &ixt->ixt_list) { + printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" " + "list head not initialized\n", + ixt->ixt_name); + return ret; + } + write_lock_bh(&ipsec_alg_lock); + ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head); + /* if previous (current) ipsec_alg found check excl flag of _anyone_ */ + if (ixt_cur && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL)) + barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. " + "Not loaded (ret=%d).\n", + ixt->ixt_alg_type, + ixt->ixt_alg_id, ret=-EEXIST); + list_add(&ixt->ixt_list, head); + ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED; + ret=0; +out: + write_unlock_bh(&ipsec_alg_lock); + return ret; +} +/* + * deletes an existing entry in hash table, + * called from ipsec_alg_unregister() when algorithm is unregistered. + */ +static int ipsec_alg_delete(struct ipsec_alg *ixt) { + write_lock_bh(&ipsec_alg_lock); + list_del(&ixt->ixt_list); + write_unlock_bh(&ipsec_alg_lock); + return 0; +} +/* + * here @user context (read-only when @kernel bh context) + * -> no bh disabling + * + * called from ipsec_sa_init() -> ipsec_alg_sa_init() + */ +static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id) { + unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id); + struct list_head *head= ipsec_alg_hash_table + hashval; + struct ipsec_alg *ixt; + read_lock(&ipsec_alg_lock); + ixt=__ipsec_alg_find(alg_type, alg_id, head); + if (ixt) __ipsec_alg_usage_inc(ixt); + read_unlock(&ipsec_alg_lock); + return ixt; +} + +static void ipsec_alg_put(struct ipsec_alg *ixt) { + __ipsec_alg_usage_dec((struct ipsec_alg *)ixt); +} + +/***************************************************************** + * + * INTERFACE for ENC services: key creation, encrypt function + * + *****************************************************************/ + +/* + * main encrypt service entry point + * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and + * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT + */ +int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat, int ilen, const __u8 * iv, int encrypt) { + int ret; + struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc; + KLIPS_PRINT(debug_rcv||debug_tunnel, + "klips_debug:ipsec_alg_esp_encrypt: " + "entering with encalg=%d, ixt_e=%p\n", + sa_p->ips_encalg, ixt_e); + if (!ixt_e) { + KLIPS_PRINT(debug_rcv||debug_tunnel, + "klips_debug:ipsec_alg_esp_encrypt: " + "NULL ipsec_alg_enc object\n"); + return -1; + } + KLIPS_PRINT(debug_rcv||debug_tunnel, + "klips_debug:ipsec_alg_esp_encrypt: " + "calling cbc_encrypt encalg=%d " + "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n", + sa_p->ips_encalg, + sa_p->ips_key_e, idat, ilen, iv, encrypt); + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat, ilen, iv, encrypt); + KLIPS_PRINT(debug_rcv||debug_tunnel, + "klips_debug:ipsec_alg_esp_encrypt: " + "returned ret=%d\n", + ret); + return ret; +} +/* + * encryption key context creation function + * called from pfkey_v2_parser.c:pfkey_ips_init() + */ +int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) { + int ret=-EINVAL; + int keyminbits, keymaxbits; + caddr_t ekp; + struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_alg_enc_key_create: " + "entering with encalg=%d ixt_e=%p\n", + sa_p->ips_encalg, ixt_e); + if (!ixt_e) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_alg_enc_key_create: " + "NULL ipsec_alg_enc object\n"); + return -EPROTO; + } + + /* + * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo + */ + switch(ixt_e->ixt_alg_id) { + case ESP_3DES: + keyminbits=keymaxbits=192;break; + case ESP_DES: + keyminbits=keymaxbits=64;break; + default: + keyminbits=ixt_e->ixt_keyminbits; + keymaxbits=ixt_e->ixt_keymaxbits; + } + if(sa_p->ips_key_bits_eips_key_bits_e>keymaxbits) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_alg_enc_key_create: " + "incorrect encryption key size for id=%d: %d bits -- " + "must be between %d,%d bits\n" /*octets (bytes)\n"*/, + ixt_e->ixt_alg_id, + sa_p->ips_key_bits_e, keyminbits, keymaxbits); + ret=-EINVAL; + goto ixt_out; + } + /* save encryption key pointer */ + ekp = sa_p->ips_key_e; + + + if (ixt_e->ixt_e_new_key) { + sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e, + ekp, sa_p->ips_key_bits_e/8); + ret = (sa_p->ips_key_e)? 0 : -EINVAL; + } else { + if((sa_p->ips_key_e = (caddr_t) + kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size), + GFP_ATOMIC)) == NULL) { + ret=-ENOMEM; + goto ixt_out; + } + /* zero-out key_e */ + memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size); + + /* I cast here to allow more decoupling in alg module */ + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_alg_enc_key_create: about to call:" + "set_key(key_e=%p, ekp=%p, key_size=%d)\n", + (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8); + ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8); + } + /* paranoid */ + memset(ekp, 0, sa_p->ips_key_bits_e/8); + kfree(ekp); +ixt_out: + return ret; +} + +/*************************************************************** + * + * INTERFACE for AUTH services: key creation, hash functions + * + ***************************************************************/ + +/* + * auth key context creation function + * called from pfkey_v2_parser.c:pfkey_ips_init() + */ +int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) { + int ret=-EINVAL; + struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth; + int keyminbits, keymaxbits; + unsigned char *akp; + unsigned int aks; + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_alg_auth_key_create: " + "entering with authalg=%d ixt_a=%p\n", + sa_p->ips_authalg, ixt_a); + if (!ixt_a) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_alg_auth_key_create: " + "NULL ipsec_alg_auth object\n"); + return -EPROTO; + } + keyminbits=ixt_a->ixt_keyminbits; + keymaxbits=ixt_a->ixt_keymaxbits; + if(sa_p->ips_key_bits_aips_key_bits_a>keymaxbits) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_alg_auth_key_create: incorrect auth" + "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/, + sa_p->ips_key_bits_a, keyminbits, keymaxbits); + ret=-EINVAL; + goto ixt_out; + } + /* save auth key pointer */ + sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */ + akp = sa_p->ips_key_a; + aks = sa_p->ips_key_a_size; + + /* will hold: 2 ctx and a blocksize buffer: kb */ + sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size; + if((sa_p->ips_key_a = + (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) { + ret=-ENOMEM; + goto ixt_out; + } + ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */ + ret=0; + memset(akp, 0, aks); + kfree(akp); + +ixt_out: + return ret; +} +int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) { + struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth; + if (!ixt_a) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_sa_esp_hash: " + "NULL ipsec_alg_auth object\n"); + return -EPROTO; + } + KLIPS_PRINT(debug_tunnel|debug_rcv, + "klips_debug:ipsec_sa_esp_hash: " + "hashing %p (%d bytes) to %p (%d bytes)\n", + espp, len, + hash, hashlen); + ixt_a->ixt_a_hmac_hash(ixt_a, + sa_p->ips_key_a, + espp, len, + hash, hashlen); + return 0; +} + +/*************************************************************** + * + * INTERFACE for module loading,testing, and unloading + * + ***************************************************************/ + +/* validation for registering (enc) module */ +static int check_enc(struct ipsec_alg_enc *ixt) { + int ret=-EINVAL; + if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_EALG_MAX) + barf_out("invalid alg_id=%d >= %d\n", ixt->ixt_alg_id, SADB_EALG_MAX); + if (ixt->ixt_blocksize==0) /* || ixt->ixt_blocksize%2) need for ESP_NULL */ + barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize); + if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_e_keylen==0) + goto zero_key_ok; + if (ixt->ixt_keyminbits==0) + barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits); + if (ixt->ixt_keymaxbits==0) + barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits); + if (ixt->ixt_e_keylen==0) + barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen); +zero_key_ok: + if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL) + barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size); + if (ixt->ixt_e_cbc_encrypt==NULL) + barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n"); + ret=0; +out: + return ret; +} + +/* validation for registering (auth) module */ +static int check_auth(struct ipsec_alg_auth *ixt) { + int ret=-EINVAL; + if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_AALG_MAX) + barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n", ixt->ixt_alg_id, SADB_AALG_MAX); + if (ixt->ixt_blocksize==0 || ixt->ixt_blocksize%2) + barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize); + if (ixt->ixt_blocksize>AH_BLKLEN_MAX) + barf_out(KERN_ERR "sorry blocksize=%d > %d. " + "Please increase AH_BLKLEN_MAX and recompile\n", + ixt->ixt_blocksize, + AH_BLKLEN_MAX); + if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_a_keylen==0) + goto zero_key_ok; + if (ixt->ixt_keyminbits==0) + barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits); + if (ixt->ixt_keymaxbits==0) + barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits); + if (ixt->ixt_keymaxbits!=ixt->ixt_keyminbits) + barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n"); + if (ixt->ixt_a_keylen==0) + barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen); +zero_key_ok: + if (ixt->ixt_a_ctx_size==0) + barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size); + if (ixt->ixt_a_hmac_set_key==NULL) + barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n"); + if (ixt->ixt_a_hmac_hash==NULL) + barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n"); + ret=0; +out: + return ret; +} + +/* + * Generic (enc, auth) registration entry point + */ +int register_ipsec_alg(struct ipsec_alg *ixt) { + int ret=-EINVAL; + /* Validation */ + if (ixt==NULL) + barf_out("NULL ipsec_alg object passed\n"); + if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00)) + barf_out("incorrect version: %d.%d.%d-%d, " + "must be %d.%d.%d[-%d]\n", + IPSEC_ALG_VERSION_QUAD(ixt->ixt_version), + IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION)); + switch(ixt->ixt_alg_type) { + case IPSEC_ALG_TYPE_AUTH: + if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0)) + goto out; + break; + case IPSEC_ALG_TYPE_ENCRYPT: + if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0)) + goto out; + /* + * Adapted two lines below: + * ivlen == 0 is possible (NULL enc has blocksize==1) + * + * fixed NULL support by David De Reu + */ + if (ixt->ixt_ivlen == 0 && ixt->ixt_blocksize > 1) + ixt->ixt_ivlen = ixt->ixt_blocksize*8; + break; + default: + barf_out("alg_type=%d not supported", ixt->ixt_alg_type); + } + INIT_LIST_HEAD(&ixt->ixt_list); + ret = ipsec_alg_insert(ixt); + if (ret<0) + barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed." + "Not loaded (ret=%d).\n", + ixt->ixt_alg_id, ret); + + ret = pfkey_list_insert_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP])); + if (ret==0) { + ixt->ixt_state |= IPSEC_ALG_ST_SUPP; + /* send register event to userspace */ + pfkey_register_reply(SADB_SATYPE_ESP, NULL); + } else + printk(KERN_ERR "pfkey_list_insert_supported returned %d. " + "Loading anyway.\n", ret); + ret=0; +out: + return ret; +} + +/* + * unregister ipsec_alg object from own tables, if + * success => calls pfkey_list_remove_supported() + */ +int unregister_ipsec_alg(struct ipsec_alg *ixt) { + int ret= -EINVAL; + switch(ixt->ixt_alg_type) { + case IPSEC_ALG_TYPE_AUTH: + case IPSEC_ALG_TYPE_ENCRYPT: + break; + default: + /* this is not a typo :) */ + barf_out("frog found in list (\"%s\"): ixt_p=NULL\n", + ixt->ixt_name); + } + + ret=ipsec_alg_delete(ixt); + if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) { + ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP; + pfkey_list_remove_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP])); + /* send register event to userspace */ + pfkey_register_reply(SADB_SATYPE_ESP, NULL); + } + +out: + return ret; +} +/* + * Must be called from user context + * used at module load type for testing algo implementation + */ +static int ipsec_alg_test_encrypt(int enc_alg, int test) { + int ret; + caddr_t buf = NULL; + int iv_size, keysize, key_e_size; + struct ipsec_alg_enc *ixt_e; + void *tmp_key_e = NULL; + #define BUFSZ 1024 + #define MARGIN 0 + #define test_enc (buf+MARGIN) + #define test_dec (test_enc+BUFSZ+MARGIN) + #define test_tmp (test_dec+BUFSZ+MARGIN) + #define test_key_e (test_tmp+BUFSZ+MARGIN) + #define test_iv (test_key_e+key_e_size+MARGIN) + #define test_key (test_iv+iv_size+MARGIN) + #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7) + ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg); + if (ixt_e==NULL) { + KLIPS_PRINT(1, + "klips_debug: ipsec_alg_test_encrypt: " + "encalg=%d object not found\n", + enc_alg); + ret=-EINVAL; + goto out; + } + iv_size=ixt_e->ixt_ivlen / 8; + key_e_size=ixt_e->ixt_e_ctx_size; + keysize=ixt_e->ixt_e_keylen; + KLIPS_PRINT(1, + "klips_debug: ipsec_alg_test_encrypt: " + "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n", + enc_alg, iv_size, key_e_size, keysize); + if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) { + ret= -ENOMEM; + goto out; + } + get_random_bytes(test_key, keysize); + get_random_bytes(test_iv, iv_size); + if (ixt_e->ixt_e_new_key) { + tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize); + ret = tmp_key_e ? 0 : -EINVAL; + } else { + tmp_key_e = test_key_e; + ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize); + } + if (ret < 0) + goto out; + get_random_bytes(test_enc, BUFSZ); + memcpy(test_tmp, test_enc, BUFSZ); + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1); + printk(KERN_INFO + "klips_info: ipsec_alg_test_encrypt: " + "cbc_encrypt=1 ret=%d\n", + ret); + ret=memcmp(test_enc, test_tmp, BUFSZ); + printk(KERN_INFO + "klips_info: ipsec_alg_test_encrypt: " + "memcmp(enc, tmp) ret=%d: %s\n", ret, + ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" ); + memcpy(test_dec, test_enc, BUFSZ); + ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0); + printk(KERN_INFO + "klips_info: ipsec_alg_test_encrypt: " + "cbc_encrypt=0 ret=%d\n", ret); + ret=memcmp(test_dec, test_tmp, BUFSZ); + printk(KERN_INFO + "klips_info: ipsec_alg_test_encrypt: " + "memcmp(dec,tmp) ret=%d: %s\n", ret, + ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" ); + { + /* Shamelessly taken from drivers/md sources O:) */ + unsigned long now; + int i, count, max=0; + int encrypt, speed; + for (encrypt=0; encrypt <2;encrypt ++) { + for (i = 0; i < 5; i++) { + now = jiffies; + count = 0; + while (jiffies == now) { + mb(); + ixt_e->ixt_e_cbc_encrypt(ixt_e, + tmp_key_e, test_tmp, + BUFSZ, test_iv, encrypt); + mb(); + count++; + mb(); + } + if (count > max) + max = count; + } + speed = max * (HZ * BUFSZ / 1024); + printk(KERN_INFO + "klips_info: ipsec_alg_test_encrypt: " + "%s %s speed=%d KB/s\n", + ixt_e->ixt_name, + encrypt? "encrypt": "decrypt", speed); + } + } +out: + if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e); + if (buf) kfree(buf); + if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e); + return ret; + #undef test_enc + #undef test_dec + #undef test_tmp + #undef test_key_e + #undef test_iv + #undef test_key + #undef test_size +} +/* + * Must be called from user context + * used at module load type for testing algo implementation + */ +static int ipsec_alg_test_auth(int auth_alg, int test) { + int ret; + caddr_t buf = NULL; + int blocksize, keysize, key_a_size; + struct ipsec_alg_auth *ixt_a; + #define BUFSZ 1024 + #define MARGIN 0 + #define test_auth (buf+MARGIN) + #define test_key_a (test_auth+BUFSZ+MARGIN) + #define test_key (test_key_a+key_a_size+MARGIN) + #define test_hash (test_key+keysize+MARGIN) + #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4) + ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg); + if (ixt_a==NULL) { + KLIPS_PRINT(1, + "klips_debug: ipsec_alg_test_auth: " + "encalg=%d object not found\n", + auth_alg); + ret=-EINVAL; + goto out; + } + blocksize=ixt_a->ixt_blocksize; + key_a_size=ixt_a->ixt_a_ctx_size; + keysize=ixt_a->ixt_a_keylen; + KLIPS_PRINT(1, + "klips_debug: ipsec_alg_test_auth: " + "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n", + auth_alg, blocksize, key_a_size, keysize); + if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) { + ret= -ENOMEM; + goto out; + } + get_random_bytes(test_key, keysize); + ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize); + if (ret < 0 ) + goto out; + get_random_bytes(test_auth, BUFSZ); + ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN); + printk(KERN_INFO + "klips_info: ipsec_alg_test_auth: " + "ret=%d\n", ret); + { + /* Shamelessly taken from drivers/md sources O:) */ + unsigned long now; + int i, count, max=0; + int speed; + for (i = 0; i < 5; i++) { + now = jiffies; + count = 0; + while (jiffies == now) { + mb(); + ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN); + mb(); + count++; + mb(); + } + if (count > max) + max = count; + } + speed = max * (HZ * BUFSZ / 1024); + printk(KERN_INFO + "klips_info: ipsec_alg_test_auth: " + "%s hash speed=%d KB/s\n", + ixt_a->ixt_name, + speed); + } +out: + if (buf) kfree(buf); + if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a); + return ret; + #undef test_auth + #undef test_key_a + #undef test_key + #undef test_hash + #undef test_size +} +int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) { + switch(alg_type) { + case IPSEC_ALG_TYPE_ENCRYPT: + return ipsec_alg_test_encrypt(alg_id, test); + break; + case IPSEC_ALG_TYPE_AUTH: + return ipsec_alg_test_auth(alg_id, test); + break; + } + printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: " + "alg_type=%d alg_id=%d\n", + alg_type, alg_id); + return -EINVAL; +} +int ipsec_alg_init(void) { + KLIPS_PRINT(1, "klips_info:ipsec_alg_init: " + "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n", + IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION), + SADB_EALG_MAX, SADB_AALG_MAX); + /* Initialize tables */ + write_lock_bh(&ipsec_alg_lock); + ipsec_alg_hash_init(); + write_unlock_bh(&ipsec_alg_lock); + /* Initialize static algos */ + KLIPS_PRINT(1, "klips_info:ipsec_alg_init: " + "calling ipsec_alg_static_init()\n"); + ipsec_alg_static_init(); + return 0; +} + +/********************************************** + * + * INTERFACE for ipsec_sa init and wipe + * + **********************************************/ + +/* + * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init() + */ +int ipsec_alg_sa_init(struct ipsec_sa *sa_p) { + struct ipsec_alg_enc *ixt_e; + struct ipsec_alg_auth *ixt_a; + + /* Only ESP for now ... */ + if (sa_p->ips_said.proto != IPPROTO_ESP) + return -EPROTONOSUPPORT; + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :" + "entering for encalg=%d, authalg=%d\n", + sa_p->ips_encalg, sa_p->ips_authalg); + if ((ixt_e=(struct ipsec_alg_enc *) + ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug: ipsec_alg_sa_init() :" + "found ipsec_alg (ixt_e=%p) for encalg=%d\n", + ixt_e, sa_p->ips_encalg); + sa_p->ips_alg_enc=ixt_e; + } + if ((ixt_a=(struct ipsec_alg_auth *) + ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug: ipsec_alg_sa_init() :" + "found ipsec_alg (ixt_a=%p) for auth=%d\n", + ixt_a, sa_p->ips_authalg); + sa_p->ips_alg_auth=ixt_a; + } + return 0; +} + +/* + * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain() + */ +int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) { + struct ipsec_alg *ixt; + if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) { + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :" + "unlinking for encalg=%d\n", + ixt->ixt_alg_id); + ipsec_alg_put(ixt); + } + if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) { + KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :" + "unlinking for authalg=%d\n", + ixt->ixt_alg_id); + ipsec_alg_put(ixt); + } + return 0; +} +/* + * As the author of this module, I ONLY ALLOW using it from + * GPL (or same LICENSE TERMS as kernel source) modules. + * + * In respect to hardware crypto engines this means: + * * Closed-source device drivers ARE NOT ALLOWED to use + * this interface. + * * Closed-source VHDL/Verilog firmware running on + * the crypto hardware device IS ALLOWED to use this interface + * via a GPL (or same LICENSE TERMS as kernel source) device driver. + * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording) + */ + +/* + * These symbols can only be used from GPL modules + * for now, I'm disabling this because it creates false + * symbol problems for old modutils. + */ + +/* #ifndef EXPORT_SYMBOL_GPL */ +#undef EXPORT_SYMBOL_GPL +#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL +/* #endif */ +EXPORT_SYMBOL_GPL(register_ipsec_alg); +EXPORT_SYMBOL_GPL(unregister_ipsec_alg); +EXPORT_SYMBOL_GPL(ipsec_alg_test); diff -urN linux-2.4.29/net/ipsec/ipsec_alg.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_alg.h --- linux-2.4.29/net/ipsec/ipsec_alg.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_alg.h Fri Feb 7 14:14:24 2003 @@ -0,0 +1,256 @@ +/* + * Modular extensions service and registration functions interface + * + * Author: JuanJo Ciarlante + * + * $Id: ipsec_alg.h,v 1.5 2003/02/07 13:14:24 ken Exp $ + * + */ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ +#ifndef IPSEC_ALG_H +#define IPSEC_ALG_H + +/* + * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__ + * *BUT* its a compiler variable. + */ +#if (__GNUC__ >= 3) +#ifndef __FUNCTION__ +#define __FUNCTION__ __func__ +#endif +#endif + +/* Version 0.8.1-0 */ +#define IPSEC_ALG_VERSION 0x00080100 + +#include +#include +#include +/* + * The following structs are used via pointers in ipsec_alg object to + * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying + * module development + */ +struct ipsec_sa; +struct esp; + +/************************************** + * + * Main registration object + * + *************************************/ +#define IPSEC_ALG_VERSION_QUAD(v) \ + (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff) +/* + * Main ipsec_alg objects: "OOPrograming wannabe" + * Hierachy (carefully handled with _minimal_ cast'ing): + * + * ipsec_alg+ + * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT) + * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH) + */ + +/*************************************************************** + * + * INTERFACE object: struct ipsec_alg + * + ***************************************************************/ + +/* + * common part for every struct ipsec_alg_* + * (sortof poor's man OOP) + */ +#define IPSEC_ALG_STRUCT_COMMON \ + unsigned ixt_version; /* only allow this version (or 'near')*/ \ + struct list_head ixt_list; /* dlinked list */ \ + struct module *ixt_module; /* THIS_MODULE */ \ + unsigned ixt_state; /* state flags */ \ + atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \ + char ixt_name[16]; /* descriptive short name, eg. "3des" */ \ + void *ixt_data; /* private for algo implementation */ \ + uint8_t ixt_blocksize; /* blocksize in bytes */ \ + \ + /* THIS IS A COPY of struct supported (lib/pfkey.h) \ + * please keep in sync until we migrate 'supported' stuff \ + * to ipsec_alg \ + */ \ + uint16_t ixt_alg_type; /* correspond to IPSEC_ALG_{ENCRYPT,AUTH} */ \ + uint8_t ixt_alg_id; /* enc. alg. number, eg. ESP_3DES */ \ + uint8_t ixt_ivlen; /* ivlen in bits, expected to be multiple of 8! */ \ + uint16_t ixt_keyminbits;/* min. keybits (of entropy) */ \ + uint16_t ixt_keymaxbits;/* max. keybits (of entropy) */ + +#define ixt_support ixt_alg_type + +#define IPSEC_ALG_ST_SUPP 0x01 +#define IPSEC_ALG_ST_REGISTERED 0x02 +#define IPSEC_ALG_ST_EXCL 0x04 +struct ipsec_alg { + IPSEC_ALG_STRUCT_COMMON +}; +/* + * Note the const in cbc_encrypt IV arg: + * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy + */ +struct ipsec_alg_enc { + IPSEC_ALG_STRUCT_COMMON + unsigned ixt_e_keylen; /* raw key length in bytes */ + unsigned ixt_e_ctx_size; /* sa_p->key_e_size */ + int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize); + __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize); + void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e); + int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt); +}; +struct ipsec_alg_auth { + IPSEC_ALG_STRUCT_COMMON + unsigned ixt_a_keylen; /* raw key length in bytes */ + unsigned ixt_a_ctx_size; /* sa_p->key_a_size */ + unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */ + int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen); + int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen); +}; +/* + * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT}, + * to avoid header coupling for true constants + * about headers ... "cp is your friend" --Linus + */ +#define IPSEC_ALG_TYPE_AUTH 14 +#define IPSEC_ALG_TYPE_ENCRYPT 15 + +/*************************************************************** + * + * INTERFACE for module loading,testing, and unloading + * + ***************************************************************/ +/* - registration calls */ +int register_ipsec_alg(struct ipsec_alg *); +int unregister_ipsec_alg(struct ipsec_alg *); +/* - optional (simple test) for algos */ +int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm); +/* inline wrappers (usefull for type validation */ +static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) { + return register_ipsec_alg((struct ipsec_alg*)ixt); +} +static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) { + return unregister_ipsec_alg((struct ipsec_alg*)ixt); +} +static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) { + return register_ipsec_alg((struct ipsec_alg*)ixt); +} +static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) { + return unregister_ipsec_alg((struct ipsec_alg*)ixt); +} + +/***************************************************************** + * + * INTERFACE for ENC services: key creation, encrypt function + * + *****************************************************************/ + +#define IPSEC_ALG_ENCRYPT 1 +#define IPSEC_ALG_DECRYPT 0 + +/* encryption key context creation function */ +int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p); +/* + * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns + * 0 or ERR<0 + */ +int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action); + +/*************************************************************** + * + * INTERFACE for AUTH services: key creation, hash functions + * + ***************************************************************/ +int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p); +int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ; +#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0) + +/* only called from ipsec_init.c */ +int ipsec_alg_init(void); + +/* algo module glue for static algos */ +void ipsec_alg_static_init(void); +typedef int (*ipsec_alg_init_func_t) (void); + +/********************************************** + * + * INTERFACE for ipsec_sa init and wipe + * + **********************************************/ + +/* returns true if ipsec_sa has ipsec_alg obj attached */ +#define IPSEC_ALG_SA_ESP_ENC(sa_p) ((sa_p)->ips_alg_enc) +#define IPSEC_ALG_SA_ESP_AUTH(sa_p) ((sa_p)->ips_alg_auth) +/* + * Initializes ipsec_sa's ipsec_alg object, using already loaded + * proto, authalg, encalg.; links ipsec_alg objects (enc, auth) + */ +int ipsec_alg_sa_init(struct ipsec_sa *sa_p); +/* + * Destroys ipsec_sa's ipsec_alg object + * unlinking ipsec_alg objects + */ +int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p); + +/********************************************** + * + * 2.2 backport for some 2.4 useful module stuff + * + **********************************************/ +#ifdef MODULE +#ifndef THIS_MODULE +#define THIS_MODULE (&__this_module) +#endif +#ifndef module_init +typedef int (*__init_module_func_t)(void); +typedef void (*__cleanup_module_func_t)(void); + +#define module_init(x) \ + int init_module(void) __attribute__((alias(#x))); \ + static inline __init_module_func_t __init_module_inline(void) \ + { return x; } +#define module_exit(x) \ + void cleanup_module(void) __attribute__((alias(#x))); \ + static inline __cleanup_module_func_t __cleanup_module_inline(void) \ + { return x; } +#endif + +#define IPSEC_ALG_MODULE_INIT( func_name ) \ + static int func_name(void); \ + module_init(func_name); \ + static int __init func_name(void) +#define IPSEC_ALG_MODULE_EXIT( func_name ) \ + static void func_name(void); \ + module_exit(func_name); \ + static void __exit func_name(void) +#else /* not MODULE */ +#ifndef THIS_MODULE +#define THIS_MODULE NULL +#endif +/* + * I only want module_init() magic + * when algo.c file *is THE MODULE*, in all other + * cases, initialization is called explicitely from ipsec_alg_init() + */ +#define IPSEC_ALG_MODULE_INIT( func_name ) \ + extern int func_name(void); \ + int func_name(void) +#define IPSEC_ALG_MODULE_EXIT( func_name ) \ + extern void func_name(void); \ + void func_name(void) +#endif + +#endif /* IPSEC_ALG_H */ diff -urN linux-2.4.29/net/ipsec/ipsec_encap.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_encap.h --- linux-2.4.29/net/ipsec/ipsec_encap.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_encap.h Thu Dec 12 04:32:07 2002 @@ -0,0 +1,143 @@ +/* + * declarations relevant to encapsulation-like operations + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_encap.h,v 1.2 2002/12/12 03:32:07 ken Exp $ + */ + +#ifndef _IPSEC_ENCAP_H_ + +#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/ + /* (2 * sizeof(struct in_addr)) */ + /* sizeof(struct sockaddr_encap) + - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */ + +struct sockaddr_encap +{ + __u8 sen_len; /* length */ + __u8 sen_family; /* AF_ENCAP */ + __u16 sen_type; /* see SENT_* */ + union + { + struct /* SENT_IP4 */ + { + struct in_addr Src; + struct in_addr Dst; + __u8 Proto; + __u16 Sport; + __u16 Dport; + } Sip4; + } Sen; +}; + +#define sen_ip_src Sen.Sip4.Src +#define sen_ip_dst Sen.Sip4.Dst +#define sen_proto Sen.Sip4.Proto +#define sen_sport Sen.Sip4.Sport +#define sen_dport Sen.Sip4.Dport + +#ifndef AF_ENCAP +#define AF_ENCAP 26 +#endif /* AF_ENCAP */ + +#define _IPSEC_ENCAP_H_ +#endif /* _IPSEC_ENCAP_H_ */ + +/* + * $Log: ipsec_encap.h,v $ + * Revision 1.2 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.16 2001/11/26 09:23:47 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.15.2.1 2001/09/25 02:18:54 mcr + * struct eroute moved to ipsec_eroute.h + * + * Revision 1.15 2001/09/14 16:58:36 rgb + * Added support for storing the first and last packets through a HOLD. + * + * Revision 1.14 2001/09/08 21:13:31 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.13 2001/06/14 19:35:08 rgb + * Update copyright date. + * + * Revision 1.12 2001/05/27 06:12:10 rgb + * Added structures for pid, packet count and last access time to eroute. + * Added packet count to beginning of /proc/net/ipsec_eroute. + * + * Revision 1.11 2000/09/08 19:12:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.10 2000/03/22 16:15:36 rgb + * Fixed renaming of dev_get (MB). + * + * Revision 1.9 2000/01/21 06:13:26 rgb + * Added a macro for AF_ENCAP + * + * Revision 1.8 1999/12/31 14:56:55 rgb + * MB fix for 2.3 dev-use-count. + * + * Revision 1.7 1999/11/18 04:09:18 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.6 1999/09/24 00:34:13 rgb + * Add Marc Boucher's support for 2.3.xx+. + * + * Revision 1.5 1999/04/11 00:28:57 henry + * GPL boilerplate + * + * Revision 1.4 1999/04/06 04:54:25 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.3 1998/10/19 14:44:28 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * + * Revision 1.2 1998/07/14 18:19:33 rgb + * Added #ifdef __KERNEL__ directives to restrict scope of header. + * + * Revision 1.1 1998/06/18 21:27:44 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.2 1998/04/21 21:29:10 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.1 1998/04/09 03:05:58 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:02 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * Minor cosmetic changes. + * + * Revision 0.3 1996/11/20 14:35:48 ji + * Minor Cleanup. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_eroute.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_eroute.h --- linux-2.4.29/net/ipsec/ipsec_eroute.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_eroute.h Thu Dec 12 04:32:07 2002 @@ -0,0 +1,103 @@ +/* + * @(#) declarations of eroute structures + * + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs + * Copyright (C) 2001 Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_eroute.h,v 1.2 2002/12/12 03:32:07 ken Exp $ + * + * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr. + * + */ + +#ifndef _IPSEC_EROUTE_H_ + +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_radij.h" + +/* + * The "type" is really part of the address as far as the routing + * system is concerned. By using only one bit in the type field + * for each type, we sort-of make sure that different types of + * encapsulation addresses won't be matched against the wrong type. + */ + +/* + * An entry in the radix tree + */ + +struct rjtentry +{ + struct radij_node rd_nodes[2]; /* tree glue, and other values */ +#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key)) +#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask)) + short rd_flags; + short rd_count; +}; + +struct ident +{ + __u16 type; /* identity type */ + __u64 id; /* identity id */ + __u8 len; /* identity len */ + caddr_t data; /* identity data */ +}; + +/* + * An encapsulation route consists of a pointer to a + * radix tree entry and a SAID (a destination_address/SPI/protocol triple). + */ + +struct eroute +{ + struct rjtentry er_rjt; + struct sa_id er_said; + uint32_t er_pid; + uint32_t er_count; + uint64_t er_lasttime; + struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/ + struct sockaddr_encap er_emask; + struct ident er_ident_s; + struct ident er_ident_d; + struct sk_buff* er_first; + struct sk_buff* er_last; +}; + +#define er_dst er_said.dst +#define er_spi er_said.spi + +#define _IPSEC_EROUTE_H_ +#endif /* _IPSEC_EROUTE_H_ */ + +/* + * $Log: ipsec_eroute.h,v $ + * Revision 1.2 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.2 2001/11/26 09:16:13 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.1.2.1 2001/09/25 02:18:54 mcr + * struct eroute moved to ipsec_eroute.h + * + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_errs.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_errs.h --- linux-2.4.29/net/ipsec/ipsec_errs.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_errs.h Thu Sep 5 05:13:17 2002 @@ -0,0 +1,50 @@ +/* + * @(#) definition of ipsec_errs structure + * + * Copyright (C) 2001 Richard Guy Briggs + * and Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_errs.h,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + * + */ + +/* + * This file describes the errors/statistics that FreeSWAN collects. + * + */ + +struct ipsec_errs { + __u32 ips_alg_errs; /* number of algorithm errors */ + __u32 ips_auth_errs; /* # of authentication errors */ + __u32 ips_encsize_errs; /* # of encryption size errors*/ + __u32 ips_encpad_errs; /* # of encryption pad errors*/ + __u32 ips_replaywin_errs; /* # of pkt sequence errors */ +}; + +/* + * $Log: ipsec_errs.h,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.2 2001/11/26 09:16:13 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.1.2.1 2001/09/25 02:25:57 mcr + * lifetime structure created and common functions created. + * + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_esp.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_esp.h --- linux-2.4.29/net/ipsec/ipsec_esp.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_esp.h Thu Sep 5 05:27:08 2002 @@ -0,0 +1,202 @@ +/* + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_esp.h,v 1.2 2002/09/05 03:27:08 ken Exp $ + */ + +#include "ipsec_md5h.h" +#include "ipsec_sha1.h" + +#include "des.h" + +#ifndef IPPROTO_ESP +#define IPPROTO_ESP 50 +#endif /* IPPROTO_ESP */ + +#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/ + +#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */ +#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */ +#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */ +#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */ +#define EMT_ESPDES_IV_SZ 8 /* IV size */ +#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */ + +#define ESP_IV_MAXSZ 16 /* This is _critical_ */ +#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int)) + +#define DB_ES_PKTRX 0x0001 +#define DB_ES_PKTRX2 0x0002 +#define DB_ES_TDB 0x0010 +#define DB_ES_XF 0x0020 +#define DB_ES_IPAD 0x0040 +#define DB_ES_INAU 0x0080 +#define DB_ES_OINFO 0x0100 +#define DB_ES_OINFO2 0x0200 +#define DB_ES_OH 0x0400 +#define DB_ES_REPLAY 0x0800 + +#ifdef __KERNEL__ +struct des_eks { + des_key_schedule ks; +}; + +extern struct inet_protocol esp_protocol; + +struct options; + +extern int +esp_rcv(struct sk_buff *skb, + struct device *dev, + struct options *opt, + __u32 daddr, + unsigned short len, + __u32 saddr, + int redo, + struct inet_protocol *protocol); + +/* XXX: only for 64 bits IVs, eg. ESP_3DES */ +struct esp +{ + __u32 esp_spi; /* Security Parameters Index */ + __u32 esp_rpl; /* Replay counter */ + __u8 esp_iv[8]; /* iv */ +}; + +#ifdef CONFIG_IPSEC_DEBUG +extern int debug_esp; +#endif /* CONFIG_IPSEC_DEBUG */ +#endif /* __KERNEL__ */ + +/* + * $Log: ipsec_esp.h,v $ + * Revision 1.2 2002/09/05 03:27:08 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.17 2002/02/20 01:27:07 rgb + * Ditched a pile of structs only used by the old Netlink interface. + * + * Revision 1.16 2001/12/11 02:35:57 rgb + * Change "struct net_device" to "struct device" for 2.2 compatibility. + * + * Revision 1.15 2001/11/26 09:23:48 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.14.2.3 2001/10/23 04:16:42 mcr + * get definition of des_key_schedule from des.h + * + * Revision 1.14.2.2 2001/10/22 20:33:13 mcr + * use "des_key_schedule" structure instead of cooking our own. + * + * Revision 1.14.2.1 2001/09/25 02:18:25 mcr + * replace "struct device" with "struct netdevice" + * + * Revision 1.14 2001/06/14 19:35:08 rgb + * Update copyright date. + * + * Revision 1.13 2000/09/08 19:12:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.12 2000/08/01 14:51:50 rgb + * Removed _all_ remaining traces of DES. + * + * Revision 1.11 2000/01/10 16:36:20 rgb + * Ditch last of EME option flags, including initiator. + * + * Revision 1.10 1999/12/07 18:16:22 rgb + * Fixed comments at end of #endif lines. + * + * Revision 1.9 1999/04/11 00:28:57 henry + * GPL boilerplate + * + * Revision 1.8 1999/04/06 04:54:25 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.7 1999/01/26 02:06:00 rgb + * Removed CONFIG_IPSEC_ALGO_SWITCH macro. + * + * Revision 1.6 1999/01/22 15:22:05 rgb + * Re-enable IV in the espblkrply_edata structure to avoid breaking pluto + * until pluto can be fixed properly. + * + * Revision 1.5 1999/01/22 06:18:16 rgb + * Updated macro comments. + * Added key schedule types to support algorithm switch code. + * + * Revision 1.4 1998/08/12 00:07:32 rgb + * Added data structures for new xforms: null, {,3}dessha1. + * + * Revision 1.3 1998/07/14 15:57:01 rgb + * Add #ifdef __KERNEL__ to protect kernel-only structures. + * + * Revision 1.2 1998/06/25 19:33:46 rgb + * Add prototype for protocol receive function. + * Rearrange for more logical layout. + * + * Revision 1.1 1998/06/18 21:27:45 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.6 1998/06/05 02:28:08 rgb + * Minor comment fix. + * + * Revision 1.5 1998/05/27 22:34:00 rgb + * Changed structures to accomodate key separation. + * + * Revision 1.4 1998/05/18 22:28:43 rgb + * Disable key printing facilities from /proc/net/ipsec_*. + * + * Revision 1.3 1998/04/21 21:29:07 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.2 1998/04/12 22:03:20 rgb + * Updated ESP-3DES-HMAC-MD5-96, + * ESP-DES-HMAC-MD5-96, + * AH-HMAC-MD5-96, + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository + * from old standards (RFC182[5-9] to new (as of March 1998) drafts. + * + * Fixed eroute references in /proc/net/ipsec*. + * + * Started to patch module unloading memory leaks in ipsec_netlink and + * radij tree unloading. + * + * Revision 1.1 1998/04/09 03:06:00 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:02 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.5 1997/06/03 04:24:48 ji + * Added ESP-3DES-MD5-96 transform. + * + * Revision 0.4 1997/01/15 01:28:15 ji + * Added definitions for new ESP transforms. + * + * Revision 0.3 1996/11/20 14:35:48 ji + * Minor Cleanup. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_init.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_init.c --- linux-2.4.29/net/ipsec/ipsec_init.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_init.c Fri Dec 12 14:09:40 2003 @@ -0,0 +1,672 @@ +/* + * @(#) Initialization code. + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs + * 2001 Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * /proc system code was split out into ipsec_proc.c after rev. 1.70. + * + */ + +char ipsec_init_c_version[] = "RCSID $Id: ipsec_init.c,v 1.5 2003/12/12 13:09:40 ken Exp $"; + +#include +#include +#include +#include /* printk() */ + +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include /* struct sockaddr_in */ +#include +#include + +#ifdef NET_21 +# include +# include +#endif /* NET_21 */ + +#include +#include + +#ifdef CONFIG_PROC_FS +# include +#endif /* CONFIG_PROC_FS */ + +#ifdef NETLINK_SOCK +# include +#else +# include +#endif + +#include "radij.h" + +#include "ipsec_life.h" +#include "ipsec_stats.h" +#include "ipsec_sa.h" + +#include "ipsec_encap.h" +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_xform.h" +#include "ipsec_tunnel.h" + +#include "ipsec_rcv.h" +#include "ipsec_ah.h" +#include "ipsec_esp.h" + +#ifdef CONFIG_IPSEC_IPCOMP +# include "ipcomp.h" +#endif /* CONFIG_IPSEC_IPCOMP */ + +#include "ipsec_proto.h" +#include "ipsec_alg.h" + +#include +#include + +#if !defined(CONFIG_IPSEC_ESP) && !defined(CONFIG_IPSEC_AH) +#error "kernel configuration must include ESP or AH" +#endif + +/* + * seems to be present in 2.4.10 (Linus), but also in some RH and other + * distro kernels of a lower number. + */ +#ifdef MODULE_LICENSE +MODULE_LICENSE("Dual BSD/GPL"); +#endif + +#ifdef CONFIG_IPSEC_DEBUG +int debug_eroute = 0; +int debug_spi = 0; +int debug_netlink = 0; +#endif /* CONFIG_IPSEC_DEBUG */ + +int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr); +/* + * the following structure is required so that we receive + * event notifications when network devices are enabled and + * disabled (ifconfig up and down). + */ +static struct notifier_block ipsec_dev_notifier={ + ipsec_device_event, + NULL, + 0 +}; + +#ifdef CONFIG_SYSCTL +extern int ipsec_sysctl_register(void); +extern void ipsec_sysctl_unregister(void); +#endif + +/* void */ +int +ipsec_init(void) +{ + int error = 0; +#ifdef CONFIG_IPSEC_ENC_3DES + extern int des_check_key; + + /* turn off checking of keys */ + des_check_key=0; +#endif /* CONFIG_IPSEC_ENC_3DES */ + + KLIPS_PRINT(1, "klips_info:ipsec_init: " + "KLIPS startup, Openswan IPsec stack %s\n", + ipsec_version_code()); + + error |= ipsec_proc_init(); + +#ifndef SPINLOCK + tdb_lock.lock = 0; + eroute_lock.lock = 0; +#endif /* !SPINLOCK */ + + error |= ipsec_sadb_init(); + error |= ipsec_radijinit(); + + error |= pfkey_init(); + + error |= register_netdevice_notifier(&ipsec_dev_notifier); + +#ifdef CONFIG_IPSEC_ESP + inet_add_protocol(&esp_protocol); +#endif /* CONFIG_IPSEC_ESP */ + +#ifdef CONFIG_IPSEC_AH + inet_add_protocol(&ah_protocol); +#endif /* CONFIG_IPSEC_AH */ + +#if 0 +#ifdef CONFIG_IPSEC_IPCOMP + inet_add_protocol(&comp_protocol); +#endif /* CONFIG_IPSEC_IPCOMP */ +#endif + + error |= ipsec_tunnel_init_devices(); + +#ifdef CONFIG_SYSCTL + error |= ipsec_sysctl_register(); +#endif +#ifdef CONFIG_IPSEC_ALG + ipsec_alg_init(); +#endif + return error; +} + + +/* void */ +int +ipsec_cleanup(void) +{ + int error = 0; + +#ifdef CONFIG_SYSCTL + ipsec_sysctl_unregister(); +#endif + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ + "klips_debug:ipsec_cleanup: " + "calling ipsec_tunnel_cleanup_devices.\n"); + error |= ipsec_tunnel_cleanup_devices(); + +#if 0 +#ifdef CONFIG_IPSEC_IPCOMP + if (inet_del_protocol(&comp_protocol) < 0) + printk(KERN_INFO "klips_debug:ipsec_cleanup: " + "comp close: can't remove protocol\n"); +#endif /* CONFIG_IPSEC_IPCOMP */ +#endif /* 0 */ +#ifdef CONFIG_IPSEC_AH + if (inet_del_protocol(&ah_protocol) < 0) + printk(KERN_INFO "klips_debug:ipsec_cleanup: " + "ah close: can't remove protocol\n"); +#endif /* CONFIG_IPSEC_AH */ +#ifdef CONFIG_IPSEC_ESP + if (inet_del_protocol(&esp_protocol) < 0) + printk(KERN_INFO "klips_debug:ipsec_cleanup: " + "esp close: can't remove protocol\n"); +#endif /* CONFIG_IPSEC_ESP */ + + error |= unregister_netdevice_notifier(&ipsec_dev_notifier); + + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ + "klips_debug:ipsec_cleanup: " + "calling ipsec_tdbcleanup.\n"); + error |= ipsec_sadb_cleanup(0); + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ + "klips_debug:ipsec_cleanup: " + "calling ipsec_radijcleanup.\n"); + error |= ipsec_radijcleanup(); + + KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */ + "klips_debug:ipsec_cleanup: " + "calling pfkey_cleanup.\n"); + error |= pfkey_cleanup(); + + ipsec_proc_cleanup(); + + return error; +} + +#ifdef MODULE +int +init_module(void) +{ + int error = 0; + + error |= ipsec_init(); + + return error; +} + +int +cleanup_module(void) +{ + int error = 0; + + KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */ + "klips_debug:cleanup_module: " + "calling ipsec_cleanup.\n"); + + error |= ipsec_cleanup(); + + KLIPS_PRINT(1, "klips_info:cleanup_module: " + "ipsec module unloaded.\n"); + + return error; +} +#endif /* MODULE */ + +/* + * $Log: ipsec_init.c,v $ + * Revision 1.5 2003/12/12 13:09:40 ken + * Remove v from version output + * + * Revision 1.4 2003/11/25 00:25:34 ken + * Change references to Openswan + * + * Revision 1.3 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.2 2002/09/05 03:27:08 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.80 2002/03/24 07:34:08 rgb + * Sanity check for at least one of AH or ESP configured. + * + * Revision 1.79 2002/02/05 22:55:15 mcr + * added MODULE_LICENSE declaration. + * This macro does not appear in all kernel versions (see comment). + * + * Revision 1.78 2002/01/29 17:17:55 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.77 2002/01/29 04:00:51 mcr + * more excise of kversions.h header. + * + * Revision 1.76 2002/01/29 02:13:17 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.75 2001/11/26 09:23:48 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.74 2001/11/22 05:44:11 henry + * new version stuff + * + * Revision 1.71.2.2 2001/10/22 20:51:00 mcr + * explicitely set des_check_key. + * + * Revision 1.71.2.1 2001/09/25 02:19:39 mcr + * /proc manipulation code moved to new ipsec_proc.c + * + * Revision 1.73 2001/11/06 19:47:17 rgb + * Changed lifetime_packets to uint32 from uint64. + * + * Revision 1.72 2001/10/18 04:45:19 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/freeswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.71 2001/09/20 15:32:45 rgb + * Minor pfkey lifetime fixes. + * + * Revision 1.70 2001/07/06 19:51:21 rgb + * Added inbound policy checking code for IPIP SAs. + * + * Revision 1.69 2001/06/14 19:33:26 rgb + * Silence startup message for console, but allow it to be logged. + * Update copyright date. + * + * Revision 1.68 2001/05/29 05:14:36 rgb + * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'. + * + * Revision 1.67 2001/05/04 16:34:52 rgb + * Rremove erroneous checking of return codes for proc_net_* in 2.4. + * + * Revision 1.66 2001/05/03 19:40:34 rgb + * Check error return codes in startup and shutdown. + * + * Revision 1.65 2001/02/28 05:03:27 rgb + * Clean up and rationalise startup messages. + * + * Revision 1.64 2001/02/27 22:24:53 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.63 2000/11/29 20:14:06 rgb + * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP. + * + * Revision 1.62 2000/11/06 04:31:24 rgb + * Ditched spin_lock_irqsave in favour of spin_lock_bh. + * Fixed longlong for pre-2.4 kernels (Svenning). + * Add Svenning's adaptive content compression. + * Disabled registration of ipcomp handler. + * + * Revision 1.61 2000/10/11 13:37:54 rgb + * #ifdef out debug print that causes proc/net/ipsec_version to oops. + * + * Revision 1.60 2000/09/20 03:59:01 rgb + * Change static info functions to DEBUG_NO_STATIC to reveal function names + * in oopsen. + * + * Revision 1.59 2000/09/16 01:06:26 rgb + * Added cast of var to silence compiler warning about long fed to int + * format. + * + * Revision 1.58 2000/09/15 11:37:01 rgb + * Merge in heavily modified Svenning Soerensen's + * IPCOMP zlib deflate code. + * + * Revision 1.57 2000/09/12 03:21:50 rgb + * Moved radij_c_version printing to ipsec_version_get_info(). + * Reformatted ipsec_version_get_info(). + * Added sysctl_{,un}register() calls. + * + * Revision 1.56 2000/09/08 19:16:50 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * Removed all references to CONFIG_IPSEC_PFKEYv2. + * + * Revision 1.55 2000/08/30 05:19:03 rgb + * Cleaned up no longer used spi_next, netlink register/unregister, other + * minor cleanup. + * Removed cruft replaced by TDB_XFORM_NAME. + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. + * Moved debug version strings to printk when /proc/net/ipsec_version is + * called. + * + * Revision 1.54 2000/08/20 18:31:05 rgb + * Changed cosmetic alignment in spi_info. + * Changed addtime and usetime to use actual value which is relative + * anyways, as intended. (Momchil) + * + * Revision 1.53 2000/08/18 17:37:03 rgb + * Added an (int) cast to shut up the compiler... + * + * Revision 1.52 2000/08/01 14:51:50 rgb + * Removed _all_ remaining traces of DES. + * + * Revision 1.51 2000/07/25 20:41:22 rgb + * Removed duplicate parameter in spi_getinfo. + * + * Revision 1.50 2000/07/17 03:21:45 rgb + * Removed /proc/net/ipsec_spinew. + * + * Revision 1.49 2000/06/28 05:46:51 rgb + * Renamed ivlen to iv_bits for consistency. + * Changed output of add and use times to be relative to now. + * + * Revision 1.48 2000/05/11 18:26:10 rgb + * Commented out calls to netlink_attach/detach to avoid activating netlink + * in the kenrel config. + * + * Revision 1.47 2000/05/10 22:35:26 rgb + * Comment out most of the startup version information. + * + * Revision 1.46 2000/03/22 16:15:36 rgb + * Fixed renaming of dev_get (MB). + * + * Revision 1.45 2000/03/16 06:40:48 rgb + * Hardcode PF_KEYv2 support. + * + * Revision 1.44 2000/01/22 23:19:20 rgb + * Simplified code to use existing macro TDB_XFORM_NAME(). + * + * Revision 1.43 2000/01/21 06:14:04 rgb + * Print individual stats only if non-zero. + * Removed 'bits' from each keylength for brevity. + * Shortened lifetimes legend for brevity. + * Changed wording from 'last_used' to the clearer 'idle'. + * + * Revision 1.42 1999/12/31 14:57:19 rgb + * MB fix for new dummy-less proc_get_info in 2.3.35. + * + * Revision 1.41 1999/11/23 23:04:03 rgb + * Use provided macro ADDRTOA_BUF instead of hardcoded value. + * Sort out pfkey and freeswan headers, putting them in a library path. + * + * Revision 1.40 1999/11/18 18:47:01 rgb + * Added dynamic proc registration for 2.3.25+. + * Changed all device registrations for static linking to + * dynamic to reduce the number and size of patches. + * Changed all protocol registrations for static linking to + * dynamic to reduce the number and size of patches. + * + * Revision 1.39 1999/11/18 04:12:07 rgb + * Replaced all kernel version macros to shorter, readable form. + * Added Marc Boucher's 2.3.25 proc patches. + * Converted all PROC_FS entries to dynamic to reduce kernel patching. + * Added CONFIG_PROC_FS compiler directives in case it is shut off. + * + * Revision 1.38 1999/11/17 15:53:38 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.37 1999/10/16 04:23:06 rgb + * Add stats for replaywin_errs, replaywin_max_sequence_difference, + * authentication errors, encryption size errors, encryption padding + * errors, and time since last packet. + * + * Revision 1.36 1999/10/16 00:30:47 rgb + * Added SA lifetime counting. + * + * Revision 1.35 1999/10/15 22:14:00 rgb + * Clean out cruft. + * + * Revision 1.34 1999/10/03 18:46:28 rgb + * Spinlock fixes for 2.0.xx and 2.3.xx. + * + * Revision 1.33 1999/10/01 17:08:10 rgb + * Disable spinlock init. + * + * Revision 1.32 1999/10/01 16:22:24 rgb + * Switch from assignment init. to functional init. of spinlocks. + * + * Revision 1.31 1999/10/01 15:44:52 rgb + * Move spinlock header include to 2.1> scope. + * + * Revision 1.30 1999/10/01 00:00:16 rgb + * Added eroute structure locking. + * Added tdb structure locking. + * Minor formatting changes. + * Add call to initialize tdb hash table. + * + * Revision 1.29 1999/09/23 20:22:40 rgb + * Enable, tidy and fix network notifier code. + * + * Revision 1.28 1999/09/18 11:39:56 rgb + * Start to add (disabled) netdevice notifier code. + * + * Revision 1.27 1999/08/28 08:24:47 rgb + * Add compiler directives to compile cleanly without debugging. + * + * Revision 1.26 1999/08/06 16:03:22 rgb + * Correct error messages on failure to unload /proc entries. + * + * Revision 1.25 1999/08/03 17:07:25 rgb + * Report device MTU, not private MTU. + * + * Revision 1.24 1999/05/25 22:24:37 rgb + * /PROC/NET/ipsec* init problem fix. + * + * Revision 1.23 1999/05/25 02:16:38 rgb + * Make modular proc_fs entries dynamic and fix for 2.2.x. + * + * Revision 1.22 1999/05/09 03:25:35 rgb + * Fix bug introduced by 2.2 quick-and-dirty patch. + * + * Revision 1.21 1999/05/05 22:02:30 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.20 1999/04/29 15:15:50 rgb + * Fix undetected iv_len reporting bug. + * Add sanity checking for null pointer to private data space. + * Add return values to init and cleanup functions. + * + * Revision 1.19 1999/04/27 19:24:44 rgb + * Added /proc/net/ipsec_klipsdebug support for reading the current debug + * settings. + * Instrument module load/init/unload. + * + * Revision 1.18 1999/04/15 15:37:24 rgb + * Forward check changes from POST1_00 branch. + * + * Revision 1.15.2.3 1999/04/13 20:29:19 rgb + * /proc/net/ipsec_* cleanup. + * + * Revision 1.15.2.2 1999/04/02 04:28:23 rgb + * /proc/net/ipsec_* formatting enhancements. + * + * Revision 1.15.2.1 1999/03/30 17:08:33 rgb + * Add pfkey initialisation. + * + * Revision 1.17 1999/04/11 00:28:57 henry + * GPL boilerplate + * + * Revision 1.16 1999/04/06 04:54:25 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.15 1999/02/24 20:15:07 rgb + * Update output format. + * + * Revision 1.14 1999/02/17 16:49:39 rgb + * Convert DEBUG_IPSEC to KLIPS_PRINT + * Ditch NET_IPIP dependancy. + * + * Revision 1.13 1999/01/26 02:06:37 rgb + * Remove ah/esp switching on include files. + * Removed CONFIG_IPSEC_ALGO_SWITCH macro. + * Removed dead code. + * Remove references to INET_GET_PROTOCOL. + * + * Revision 1.12 1999/01/22 06:19:18 rgb + * Cruft clean-out. + * 64-bit clean-up. + * Added algorithm switch code. + * + * Revision 1.11 1998/12/01 05:54:53 rgb + * Cleanup and order debug version output. + * + * Revision 1.10 1998/11/30 13:22:54 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.9 1998/11/10 05:35:13 rgb + * Print direction in/out flag from /proc/net/ipsec_spi. + * + * Revision 1.8 1998/10/27 13:48:10 rgb + * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts. + * Fixed less(1) truncated output bug. + * Code clean-up. + * + * Revision 1.7 1998/10/22 06:43:16 rgb + * Convert to use satoa for printk. + * + * Revision 1.6 1998/10/19 14:24:35 rgb + * Added inclusion of freeswan.h. + * + * Revision 1.5 1998/10/09 04:43:35 rgb + * Added 'klips_debug' prefix to all klips printk debug statements. + * + * Revision 1.4 1998/07/27 21:50:22 rgb + * Not necessary to traverse mask tree for /proc/net/ipsec_eroute. + * + * Revision 1.3 1998/06/25 19:51:20 rgb + * Clean up #endif comments. + * Shift debugging comment control for procfs to debug_tunnel. + * Make proc_dir_entries visible to rest of kernel for static link. + * Replace hardwired fileperms with macros. + * Use macros for procfs inode numbers. + * Rearrange initialisations between ipsec_init and module_init as appropriate + * for static loading. + * + * Revision 1.2 1998/06/23 02:55:43 rgb + * Slightly quieted init-time messages. + * Re-introduced inet_add_protocol after it mysteriously disappeared... + * Check for and warn of absence of IPIP protocol on install of module. + * Move tdbcleanup to ipsec_xform.c. + * + * Revision 1.10 1998/06/18 21:29:04 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid kernel + * build scripts happier in presence of symbolic links + * + * Revision 1.9 1998/06/14 23:49:40 rgb + * Clarify version reporting on module loading. + * + * Revision 1.8 1998/06/11 05:54:23 rgb + * Added /proc/net/ipsec_version to report freeswan and transform versions. + * Added /proc/net/ipsec_spinew to generate new and unique spi's.. + * Fixed /proc/net/ipsec_tncfg bug. + * + * Revision 1.7 1998/05/25 20:23:13 rgb + * proc_register changed to dynamic registration to avoid arbitrary inode + * numbers. + * + * Implement memory recovery from tdb and eroute tables. + * + * Revision 1.6 1998/05/21 13:08:58 rgb + * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of + * information is available for printout. + * + * Revision 1.5 1998/05/18 21:29:48 rgb + * Cleaned up /proc/net/ipsec_* output, including a title line, algorithm + * names instead of numbers, standard format for numerical output base, + * whitespace for legibility, and the names themselves for consistency. + * + * Added /proc/net/ipsec_spigrp and /proc/net/ipsec_tncfg. + * + * Revision 1.4 1998/04/30 15:42:24 rgb + * Silencing attach for normal operations with #ifdef IPSEC_DEBUG. + * + * Revision 1.3 1998/04/21 21:28:58 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.2 1998/04/12 22:03:22 rgb + * Updated ESP-3DES-HMAC-MD5-96, + * ESP-DES-HMAC-MD5-96, + * AH-HMAC-MD5-96, + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository + * from old standards (RFC182[5-9] to new (as of March 1998) drafts. + * + * Fixed eroute references in /proc/net/ipsec*. + * + * Started to patch module unloading memory leaks in ipsec_netlink and + * radij tree unloading. + * + * Revision 1.1 1998/04/09 03:06:05 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:02 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Fixed problem with node names of /proc/net entries. + * Other minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_ipe4.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_ipe4.h --- linux-2.4.29/net/ipsec/ipsec_ipe4.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_ipe4.h Thu Sep 5 05:13:17 2002 @@ -0,0 +1,65 @@ +/* + * IP-in-IP Header declarations + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_ipe4.h,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + */ + +/* The packet header is an IP header! */ + +struct ipe4_xdata /* transform table data */ +{ + struct in_addr i4_src; + struct in_addr i4_dst; +}; + +#define EMT_IPE4_ULEN 8 /* coming from user mode */ + + +/* + * $Log: ipsec_ipe4.h,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.4 2001/06/14 19:35:08 rgb + * Update copyright date. + * + * Revision 1.3 1999/04/11 00:28:57 henry + * GPL boilerplate + * + * Revision 1.2 1999/04/06 04:54:25 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.1 1998/06/18 21:27:47 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.1 1998/04/09 03:06:07 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:03 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:48:53 ji + * Release update only. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_kversion.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_kversion.h --- linux-2.4.29/net/ipsec/ipsec_kversion.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_kversion.h Mon Nov 17 01:28:57 2003 @@ -0,0 +1,193 @@ +#ifndef _OPENSWAN_KVERSIONS_H +/* + * header file for FreeS/WAN library functions + * Copyright (C) 1998, 1999, 2000 Henry Spencer. + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: ipsec_kversion.h,v 1.2 2003/11/17 00:28:57 ken Exp $ + */ +#define _OPENSWAN_KVERSIONS_H /* seen it, no need to see it again */ + +/* + * this file contains a series of atomic defines that depend upon + * kernel version numbers. The kernel versions are arranged + * in version-order number (which is often not chronological) + * and each clause enables or disables a feature. + */ + +/* + * First, assorted kernel-version-dependent trickery. + */ +#include +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) +#define HEADER_CACHE_BIND_21 +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) +#define SPINLOCK +#define PROC_FS_21 +#define NETLINK_SOCK +#define NET_21 +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19) +#define net_device_stats enet_statistics +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) +#define SPINLOCK_23 +#define NETDEV_23 +# ifndef CONFIG_IP_ALIAS +# define CONFIG_IP_ALIAS +# endif +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25) +#define PROC_FS_2325 +#undef PROC_FS_21 +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30) +#define PROC_NO_DUMMY +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35) +#define SKB_COPY_EXPAND +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37) +#define IP_SELECT_IDENT +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER) +#define SKB_RESET_NFCT +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2) +#define IP_SELECT_IDENT_NEW +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) +#define IPH_is_SKB_PULLED +#define SKB_COW_NEW +#define PROTO_HANDLER_SINGLE_PARM +#define IP_FRAGMENT_LINEARIZE 1 +#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */ +# ifdef REDHAT_BOGOSITY +# define IP_SELECT_IDENT_NEW +# define IPH_is_SKB_PULLED +# define SKB_COW_NEW +# define PROTO_HANDLER_SINGLE_PARM +# endif /* REDHAT_BOGOSITY */ +#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9) +#define MALLOC_SLAB +#define LINUX_KERNEL_HAS_SNPRINTF +#endif + +#ifdef NET_21 +# include +#else + /* old kernel in.h has some IPv6 stuff, but not quite enough */ +# define s6_addr16 s6_addr +# define AF_INET6 10 +# define uint8_t __u8 +# define uint16_t __u16 +# define uint32_t __u32 +# define uint64_t __u64 +#endif + +#ifndef SPINLOCK +# include + /* simulate spin locks and read/write locks */ + typedef struct { + volatile char lock; + } spinlock_t; + + typedef struct { + volatile unsigned int lock; + } rwlock_t; + +# define spin_lock_init(x) { (x)->lock = 0;} +# define rw_lock_init(x) { (x)->lock = 0; } + +# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;} +# define spin_lock_irq(x) { cli(); spin_lock(x);} +# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);} + +# define spin_unlock(x) { (x)->lock=0;} +# define spin_unlock_irq(x) { spin_unlock(x); sti();} +# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);} + +# define read_lock(x) spin_lock(x) +# define read_lock_irq(x) spin_lock_irq(x) +# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags) + +# define read_unlock(x) spin_unlock(x) +# define read_unlock_irq(x) spin_unlock_irq(x) +# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags) + +# define write_lock(x) spin_lock(x) +# define write_lock_irq(x) spin_lock_irq(x) +# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags) + +# define write_unlock(x) spin_unlock(x) +# define write_unlock_irq(x) spin_unlock_irq(x) +# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags) +#endif /* !SPINLOCK */ + +#ifndef SPINLOCK_23 +# define spin_lock_bh(x) spin_lock_irq(x) +# define spin_unlock_bh(x) spin_unlock_irq(x) + +# define read_lock_bh(x) read_lock_irq(x) +# define read_unlock_bh(x) read_unlock_irq(x) + +# define write_lock_bh(x) write_lock_irq(x) +# define write_unlock_bh(x) write_unlock_irq(x) +#endif /* !SPINLOCK_23 */ + +#endif /* _OPENSWAN_KVERSIONS_H */ + +/* + * $Log: ipsec_kversion.h,v $ + * Revision 1.2 2003/11/17 00:28:57 ken + * Changing references + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.2.2.1 2002/04/12 03:21:43 mcr + * fixes for compilation on RH 7.1 + * + * Revision 1.3 2002/04/12 03:21:17 mcr + * three parameter version of ip_select_ident appears first + * in 2.4.2 (RH7.1) not 2.4.4. + * + * Revision 1.2 2002/03/08 21:35:22 rgb + * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after + * 2.4.9. (Andreas Piesk). + * + * Revision 1.1 2002/01/29 02:11:42 mcr + * removal of kversions.h - sources that needed it now use ipsec_param.h. + * updating of IPv6 structures to match latest in6.h version. + * removed dead code from freeswan.h that also duplicated kversions.h + * code. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_life.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_life.c --- linux-2.4.29/net/ipsec/ipsec_life.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_life.c Thu Jun 17 10:47:11 2004 @@ -0,0 +1,255 @@ +/* + * @(#) lifetime structure utilities + * + * Copyright (C) 2001 Richard Guy Briggs + * and Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_life.c,v 1.5 2004/06/17 08:47:11 ken Exp $ + * + */ + +/* + * This provides series of utility functions for dealing with lifetime + * structures. + * + * ipsec_check_lifetime - returns -1 hard lifetime exceeded + * 0 soft lifetime exceeded + * 1 everything is okay + * based upon whether or not the count exceeds hard/soft + * + */ + +#define __NO_VERSION__ +#include +#include /* for CONFIG_IP_FORWARD */ +#include +#include /* printk() */ + +#include "ipsec_param.h" + +#include /* struct device, struct net_device_stats and other headers */ +#include /* eth_type_trans */ +#include +#include + +#include "radij.h" +#include "ipsec_life.h" +#include "ipsec_xform.h" +#include "ipsec_eroute.h" +#include "ipsec_encap.h" +#include "ipsec_radij.h" + +#include "ipsec_netlink.h" +#include "ipsec_sa.h" +#include "ipsec_tunnel.h" +#include "ipsec_ipe4.h" +#include "ipsec_ah.h" +#include "ipsec_esp.h" + +#ifdef CONFIG_IPSEC_IPCOMP +#include "ipcomp.h" +#endif /* CONFIG_IPSEC_IPCOMP */ + +#include +#include + +#include "ipsec_proto.h" + + +enum ipsec_life_alive +ipsec_lifetime_check(struct ipsec_lifetime64 *il64, + const char *lifename, + const char *saname, + enum ipsec_life_type ilt, + enum ipsec_direction idir, + struct ipsec_sa *ips) +{ + __u64 count; + const char *dir; + + if(saname == NULL) { + saname = "unknown-SA"; + } + + if(idir == ipsec_incoming) { + dir = "incoming"; + } else { + dir = "outgoing"; + } + + + if(ilt == ipsec_life_timebased) { + count = jiffies/HZ - il64->ipl_count; + } else { + count = il64->ipl_count; + } + + if(il64->ipl_hard && + (count > il64->ipl_hard)) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, " + "%s packet dropped.\n", + lifename, + IPS_XFORM_NAME(ips), + saname, + dir); + + pfkey_expire(ips, 1); + return ipsec_life_harddied; + } + + if(il64->ipl_soft && + (count > il64->ipl_soft)) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, " + "soft expire message sent up, %s packet still processed.\n", + lifename, + IPS_XFORM_NAME(ips), + saname, + dir); + + if(ips->ips_state != SADB_SASTATE_DYING) { + pfkey_expire(ips, 0); + } + ips->ips_state = SADB_SASTATE_DYING; + + return ipsec_life_softdied; + } + return ipsec_life_okay; +} + + +/* + * This function takes a buffer (with length), a lifetime name and type, + * and formats a string to represent the current values of the lifetime. + * + * It returns the number of bytes that the format took (or would take, + * if the buffer were large enough: snprintf semantics). + * This is used in /proc routines and in debug output. + */ +int +ipsec_lifetime_format(char *buffer, + int buflen, + char *lifename, + enum ipsec_life_type timebaselife, + struct ipsec_lifetime64 *lifetime) +{ + int len = 0; + __u64 count; + + if(timebaselife == ipsec_life_timebased) { + count = jiffies/HZ - lifetime->ipl_count; + } else { + count = lifetime->ipl_count; + } + + if(lifetime->ipl_count > 1 || + lifetime->ipl_soft || + lifetime->ipl_hard) { +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) + len = ipsec_snprintf(buffer, buflen, + "%s(%Lu,%Lu,%Lu)", + lifename, + (long long)count, + (long long)lifetime->ipl_soft, + (long long)lifetime->ipl_hard); +#else /* XXX high 32 bits are not displayed */ + len = ipsec_snprintf(buffer, buflen, + "%s(%lu,%lu,%lu)", + lifename, + (unsigned long)count, + (unsigned long)lifetime->ipl_soft, + (unsigned long)lifetime->ipl_hard); +#endif + } + + return len; +} + +void +ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime, + __u64 newvalue) +{ + if(newvalue && + (!lifetime->ipl_hard || + (newvalue < lifetime->ipl_hard))) { + lifetime->ipl_hard = newvalue; + + if(!lifetime->ipl_soft && + (lifetime->ipl_hard < lifetime->ipl_soft)) { + lifetime->ipl_soft = lifetime->ipl_hard; + } + } +} + +void +ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime, + __u64 newvalue) +{ + if(newvalue && + (!lifetime->ipl_soft || + (newvalue < lifetime->ipl_soft))) { + lifetime->ipl_soft = newvalue; + + if(lifetime->ipl_hard && + (lifetime->ipl_hard < lifetime->ipl_soft)) { + lifetime->ipl_soft = lifetime->ipl_hard; + } + } +} + + +/* + * $Log: ipsec_life.c,v $ + * Revision 1.5 2004/06/17 08:47:11 ken + * Remove bad /* string from comments + * + * Revision 1.4 2004/04/27 22:18:54 ken + * Backport of FreeS/WAN 2.06 ipsec_snprintf() and /proc/ipsec* fixes (ts/kb) + * + * Revision 1.3 2003/12/04 02:55:36 ken + * Cast safely for ia64 + * + * Revision 1.2 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.4.6.1 2002/05/31 00:19:05 mcr + * pullup of PR#72 fix from mainbranch-lifetime is relative. + * + * Revision 1.4 2002/01/29 17:17:55 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.3 2002/01/29 02:13:17 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.2 2001/11/26 09:16:14 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.1.2.1 2001/09/25 02:25:57 mcr + * lifetime structure created and common functions created. + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_life.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_life.h --- linux-2.4.29/net/ipsec/ipsec_life.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_life.h Thu Sep 5 05:13:17 2002 @@ -0,0 +1,109 @@ +/* + * Definitions relevant to IPSEC lifetimes + * Copyright (C) 2001 Richard Guy Briggs + * and Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_life.h,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + * + * This file derived from ipsec_xform.h on 2001/9/18 by mcr. + * + */ + +/* + * This file describes the book keeping fields for the + * IPsec Security Association Structure. ("ipsec_sa") + * + * This structure is never allocated directly by kernel code, + * (it is always a static/auto or is part of a structure) + * so it does not have a reference count. + * + */ + +#ifndef _IPSEC_LIFE_H_ + +/* + * _count is total count. + * _hard is hard limit (kill SA after this number) + * _soft is soft limit (try to renew SA after this number) + * _last is used in some special cases. + * + */ + +struct ipsec_lifetime64 +{ + __u64 ipl_count; + __u64 ipl_soft; + __u64 ipl_hard; + __u64 ipl_last; +}; + +struct ipsec_lifetimes +{ + /* number of bytes processed */ + struct ipsec_lifetime64 ipl_bytes; + + /* number of packets processed */ + struct ipsec_lifetime64 ipl_packets; + + /* time since SA was added */ + struct ipsec_lifetime64 ipl_addtime; + + /* time since SA was first used */ + struct ipsec_lifetime64 ipl_usetime; + + /* from rfc2367: + * For CURRENT, the number of different connections, + * endpoints, or flows that the association has been + * allocated towards. For HARD and SOFT, the number of + * these the association may be allocated towards + * before it expires. The concept of a connection, + * flow, or endpoint is system specific. + * + * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN. + * They are maintained for PF_KEY compatibility. + */ + struct ipsec_lifetime64 ipl_allocations; +}; + +enum ipsec_life_alive { + ipsec_life_harddied = -1, + ipsec_life_softdied = 0, + ipsec_life_okay = 1 +}; + +enum ipsec_life_type { + ipsec_life_timebased = 1, + ipsec_life_countbased= 0 +}; + +#define _IPSEC_LIFE_H_ +#endif /* _IPSEC_LIFE_H_ */ + + +/* + * $Log: ipsec_life.h,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.2 2001/11/26 09:16:14 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.1.2.1 2001/09/25 02:25:58 mcr + * lifetime structure created and common functions created. + * + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_md5c.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_md5c.c --- linux-2.4.29/net/ipsec/ipsec_md5c.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_md5c.c Thu Sep 5 05:13:17 2002 @@ -0,0 +1,433 @@ +/* + * RCSID $Id: ipsec_md5c.c,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + */ + +/* + * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic + * changes to accomodate it in the kernel by ji. + */ + +#include +#include + +#include "ipsec_md5h.h" + +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +/* + * Additions by JI + * + * HAVEMEMCOPY is defined if mem* routines are available + * + * HAVEHTON is defined if htons() and htonl() can be used + * for big/little endian conversions + * + */ + +#define HAVEMEMCOPY +#ifdef __LITTLE_ENDIAN +#define LITTLENDIAN +#endif +#ifdef __BIG_ENDIAN +#define BIGENDIAN +#endif + +/* Constants for MD5Transform routine. + */ + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); + +#ifdef LITTLEENDIAN +#define Encode MD5_memcpy +#define Decode MD5_memcpy +#else +static void Encode PROTO_LIST + ((unsigned char *, UINT4 *, unsigned int)); +static void Decode PROTO_LIST + ((UINT4 *, unsigned char *, unsigned int)); +#endif + +#ifdef HAVEMEMCOPY +/* no need to include here; defines these */ +#define MD5_memcpy memcpy +#define MD5_memset memset +#else +#ifdef HAVEBCOPY +#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c)) +#define MD5_memset(_a,_b,_c) bzero((_a),(_c)) +#else +static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); +static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); +#endif +#endif +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. + */ +void MD5Init (context) +MD5_CTX *context; /* context */ +{ + context->count[0] = context->count[1] = 0; + /* Load magic initialization constants. +*/ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the + context. + */ +void MD5Update (context, input, inputLen) +MD5_CTX *context; /* context */ +unsigned char *input; /* input block */ +__u32 inputLen; /* length of input block */ +{ + __u32 i; + unsigned int index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. +*/ + if (inputLen >= partLen) { + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)input, partLen); + MD5Transform (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)&input[i], + inputLen-i); +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. + */ +void MD5Final (digest, context) +unsigned char digest[16]; /* message digest */ +MD5_CTX *context; /* context */ +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. +*/ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + MD5Update (context, bits, 8); + + if (digest != NULL) /* Bill Simpson's padding */ + { + /* store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. + */ + MD5_memset ((POINTER)context, 0, sizeof (*context)); + } +} + +/* MD5 basic transformation. Transforms state based on block. + */ +static void MD5Transform (state, block) +UINT4 state[4]; +unsigned char block[64]; +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. +*/ + MD5_memset ((POINTER)x, 0, sizeof (x)); +} + +#ifndef LITTLEENDIAN + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + */ +static void Encode (output, input, len) +unsigned char *output; +UINT4 *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + */ +static void Decode (output, input, len) +UINT4 *output; +unsigned char *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); +} + +#endif + +#ifndef HAVEMEMCOPY +#ifndef HAVEBCOPY +/* Note: Replace "for loop" with standard memcpy if possible. + */ + +static void MD5_memcpy (output, input, len) +POINTER output; +POINTER input; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + + output[i] = input[i]; +} + +/* Note: Replace "for loop" with standard memset if possible. + */ + +static void MD5_memset (output, value, len) +POINTER output; +int value; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + ((char *)output)[i] = (char)value; +} +#endif +#endif + +/* + * $Log: ipsec_md5c.c,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.4 1999/12/13 13:59:12 rgb + * Quick fix to argument size to Update bugs. + * + * Revision 1.3 1999/05/21 18:09:28 henry + * unnecessary include causes trouble in 2.2 + * + * Revision 1.2 1999/04/06 04:54:26 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.1 1998/06/18 21:27:48 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.2 1998/04/23 20:54:02 rgb + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when + * verified. + * + * Revision 1.1 1998/04/09 03:06:08 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:04 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.3 1996/11/20 14:48:53 ji + * Release update only. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_md5h.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_md5h.h --- linux-2.4.29/net/ipsec/ipsec_md5h.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_md5h.h Thu Sep 5 05:13:17 2002 @@ -0,0 +1,132 @@ +/* + * RCSID $Id: ipsec_md5h.h,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + */ + +/* + * The rest of this file is Copyright RSA DSI. See the following comments + * for the full Copyright notice. + */ + +#ifndef _IPSEC_MD5H_H_ +#define _IPSEC_MD5H_H_ + +/* GLOBAL.H - RSAREF types and constants + */ + +/* PROTOTYPES should be set to one if and only if the compiler supports + function argument prototyping. + The following makes PROTOTYPES default to 0 if it has not already + been defined with C compiler flags. + */ +#ifndef PROTOTYPES +#define PROTOTYPES 1 +#endif /* !PROTOTYPES */ + +/* POINTER defines a generic pointer type */ +typedef __u8 *POINTER; + +/* UINT2 defines a two byte word */ +typedef __u16 UINT2; + +/* UINT4 defines a four byte word */ +typedef __u32 UINT4; + +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. + If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it + returns an empty list. + */ + +#if PROTOTYPES +#define PROTO_LIST(list) list +#else /* PROTOTYPES */ +#define PROTO_LIST(list) () +#endif /* PROTOTYPES */ + + +/* MD5.H - header file for MD5C.C + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +/* MD5 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +void MD5Init PROTO_LIST ((MD5_CTX *)); +void MD5Update PROTO_LIST + ((MD5_CTX *, unsigned char *, __u32)); +void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); + +#endif /* _IPSEC_MD5H_H_ */ + +/* + * $Log: ipsec_md5h.h,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.6 1999/12/13 13:59:13 rgb + * Quick fix to argument size to Update bugs. + * + * Revision 1.5 1999/12/07 18:16:23 rgb + * Fixed comments at end of #endif lines. + * + * Revision 1.4 1999/04/06 04:54:26 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.3 1999/01/22 06:19:58 rgb + * 64-bit clean-up. + * + * Revision 1.2 1998/11/30 13:22:54 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.1 1998/06/18 21:27:48 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.2 1998/04/23 20:54:03 rgb + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when + * verified. + * + * Revision 1.1 1998/04/09 03:04:21 henry + * sources moved up from linux/net/ipsec + * these two include files modified not to include others except in kernel + * + * Revision 1.1.1.1 1998/04/08 05:35:03 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:48:53 ji + * Release update only. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_netlink.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_netlink.c --- linux-2.4.29/net/ipsec/ipsec_netlink.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_netlink.c Wed Nov 19 03:29:41 2003 @@ -0,0 +1,713 @@ +/* + * IPSEC <> netlink interface + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +char ipsec_netlink_c_version[] = "RCSID $Id: ipsec_netlink.c,v 1.4 2003/11/19 02:29:41 mcr Exp $"; + +#include +#include +#include /* printk() */ + +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include +#include +#ifdef SPINLOCK +# ifdef SPINLOCK_23 +# include /* *lock* */ +# else /* 23_SPINLOCK */ +# include /* *lock* */ +# endif /* 23_SPINLOCK */ +#endif /* SPINLOCK */ +#ifdef NET_21 +# include +# include +# define ip_chk_addr inet_addr_type +# define IS_MYADDR RTN_LOCAL +#endif +#include +#include +#ifdef NETLINK_SOCK +# include +#else +# include +#endif + +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_xform.h" + +#include "ipsec_rcv.h" +#include "ipsec_ah.h" +#include "ipsec_esp.h" + +#ifdef CONFIG_IPSEC_DEBUG +# include "ipsec_tunnel.h" +#endif /* CONFIG_IPSEC_DEBUG */ + +#include +#include + +#ifdef CONFIG_IPSEC_DEBUG + int debug_netlink = 0; +#endif /* CONFIG_IPSEC_DEBUG */ + +#define SENDERR(_x) do { len = -(_x); goto errlab; } while (0) + +#if 0 +int +#ifdef NETLINK_SOCK +ipsec_callback(int proto, struct sk_buff *skb) +#else /* NETLINK_SOCK */ +ipsec_callback(struct sk_buff *skb) +#endif /* NETLINK_SOCK */ +{ + /* + * this happens when we write to /dev/ipsec (c 36 10) + */ + int len = skb->len; + u_char *dat = (u_char *)skb->data; + struct encap_msghdr *em = (struct encap_msghdr *)dat; + struct tdb *tdbp, *tprev; + int i, nspis, error = 0; +#ifdef CONFIG_IPSEC_DEBUG + struct eroute *eret; + char sa[SATOA_BUF]; + size_t sa_len; + struct sk_buff *first, *last; + + + sa_len = satoa(em->em_said, 0, sa, SATOA_BUF); + + if(debug_netlink) { + printk("klips_debug:ipsec_callback: " + "skb=0x%p skblen=%ld em_magic=%d em_type=%d\n", + skb, + (unsigned long int)skb->len, + em->em_magic, + em->em_type); + switch(em->em_type) { + case EMT_SETDEBUG: + printk("klips_debug:ipsec_callback: " + "set ipsec_debug level\n"); + break; + case EMT_DELEROUTE: + case EMT_CLREROUTE: + case EMT_CLRSPIS: + break; + default: + printk("klips_debug:ipsec_callback: " + "called for SA:%s\n", + sa_len ? sa : " (error)"); + } + } +#endif /* CONFIG_IPSEC_DEBUG */ + + /* XXXX Temporarily disable netlink I/F code until it gets permanantly + ripped out in favour of PF_KEYv2 I/F. */ + SENDERR(EPROTONOSUPPORT); + + /* em = (struct encap_msghdr *)dat; */ + if (em->em_magic != EM_MAGIC) { + printk("klips_debug:ipsec_callback: " + "bad magic=%d failed, should be %d\n", + em->em_magic, + EM_MAGIC); + SENDERR(EINVAL); + } + switch (em->em_type) { + case EMT_SETDEBUG: +#ifdef CONFIG_IPSEC_DEBUG + if(em->em_db_nl >> (sizeof(em->em_db_nl) * 8 - 1)) { + em->em_db_nl &= ~(1 << (sizeof(em->em_db_nl) * 8 -1)); + debug_tunnel |= em->em_db_tn; + debug_netlink |= em->em_db_nl; + debug_xform |= em->em_db_xf; + debug_eroute |= em->em_db_er; + debug_spi |= em->em_db_sp; + debug_radij |= em->em_db_rj; + debug_esp |= em->em_db_es; + debug_ah |= em->em_db_ah; + debug_rcv |= em->em_db_rx; + debug_pfkey |= em->em_db_ky; + if(debug_netlink) + printk("klips_debug:ipsec_callback: set\n"); + } else { + if(debug_netlink) + printk("klips_debug:ipsec_callback: unset\n"); + debug_tunnel &= em->em_db_tn; + debug_netlink &= em->em_db_nl; + debug_xform &= em->em_db_xf; + debug_eroute &= em->em_db_er; + debug_spi &= em->em_db_sp; + debug_radij &= em->em_db_rj; + debug_esp &= em->em_db_es; + debug_ah &= em->em_db_ah; + debug_rcv &= em->em_db_rx; + debug_pfkey &= em->em_db_ky; + } +#else /* CONFIG_IPSEC_DEBUG */ + printk("klips_debug:ipsec_callback: " + "debugging not enabled\n"); + SENDERR(EINVAL); +#endif /* CONFIG_IPSEC_DEBUG */ + break; + + case EMT_SETEROUTE: + if ((error = ipsec_makeroute(&(em->em_eaddr), &(em->em_emask), em->em_ersaid, 0, NULL, NULL, NULL))) + SENDERR(-error); + break; + + case EMT_REPLACEROUTE: + if ((error = ipsec_breakroute(&(em->em_eaddr), &(em->em_emask), &first, &last)) == EINVAL) { + kfree_skb(first); + kfree_skb(last); + SENDERR(-error); + } + if ((error = ipsec_makeroute(&(em->em_eaddr), &(em->em_emask), em->em_ersaid, NULL, NULL))) + SENDERR(-error); + break; + + case EMT_DELEROUTE: + if ((error = ipsec_breakroute(&(em->em_eaddr), &(em->em_emask), &first, &last))) + kfree_skb(first); + kfree_skb(last); + SENDERR(-error); + break; + + case EMT_CLREROUTE: + if ((error = ipsec_cleareroutes())) + SENDERR(-error); + break; + + case EMT_SETSPI: + if (em->em_if >= 5) /* XXX -- why 5? */ + SENDERR(ENODEV); + + tdbp = gettdb(&(em->em_said)); + if (tdbp == NULL) { + tdbp = (struct tdb *)kmalloc(sizeof (*tdbp), GFP_ATOMIC); + + if (tdbp == NULL) + SENDERR(ENOBUFS); + + memset((caddr_t)tdbp, 0, sizeof(*tdbp)); + + tdbp->tdb_said = em->em_said; + tdbp->tdb_flags = em->em_flags; + + if(ip_chk_addr((unsigned long)em->em_said.dst.s_addr) == IS_MYADDR) { + tdbp->tdb_flags |= EMT_INBOUND; + } + KLIPS_PRINT(debug_netlink & DB_NL_TDBCB, + "klips_debug:ipsec_callback: " + "existing Tunnel Descriptor Block not found (this is good) for SA: %s, %s-bound, allocating.\n", + sa_len ? sa : " (error)", + (tdbp->tdb_flags & EMT_INBOUND) ? "in" : "out"); + +/* XXX tdbp->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/ + tdbp->tdb_rcvif = NULL; + } else { + KLIPS_PRINT(debug_netlink & DB_NL_TDBCB, + "klips_debug:ipsec_callback: " + "EMT_SETSPI found an old Tunnel Descriptor Block for SA: %s, delete it first.\n", + sa_len ? sa : " (error)"); + SENDERR(EEXIST); + } + + if ((error = tdb_init(tdbp, em))) { + KLIPS_PRINT(debug_netlink & DB_NL_TDBCB, + "klips_debug:ipsec_callback: " + "EMT_SETSPI not successful for SA: %s, deleting.\n", + sa_len ? sa : " (error)"); + ipsec_tdbwipe(tdbp); + + SENDERR(-error); + } + + tdbp->tdb_lifetime_addtime_c = jiffies/HZ; + tdbp->tdb_state = 1; + if(!tdbp->tdb_lifetime_allocations_c) { + tdbp->tdb_lifetime_allocations_c += 1; + } + + puttdb(tdbp); + KLIPS_PRINT(debug_netlink & DB_NL_TDBCB, + "klips_debug:ipsec_callback: " + "EMT_SETSPI successful for SA: %s\n", + sa_len ? sa : " (error)"); + break; + + case EMT_DELSPI: + if (em->em_if >= 5) /* XXX -- why 5? */ + SENDERR(ENODEV); + + spin_lock_bh(&tdb_lock); + + tdbp = gettdb(&(em->em_said)); + if (tdbp == NULL) { + KLIPS_PRINT(debug_netlink & DB_NL_TDBCB, + "klips_debug:ipsec_callback: " + "EMT_DELSPI Tunnel Descriptor Block not found for SA%s, could not delete.\n", + sa_len ? sa : " (error)"); + spin_unlock_bh(&tdb_lock); + SENDERR(ENXIO); /* XXX -- wrong error message... */ + } else { + if((error = deltdbchain(tdbp))) { + spin_unlock_bh(&tdb_lock); + SENDERR(-error); + } + } + spin_unlock_bh(&tdb_lock); + + break; + + case EMT_GRPSPIS: + nspis = (len - EMT_GRPSPIS_FLEN) / sizeof(em->em_rel[0]); + if ((nspis * (sizeof(em->em_rel[0]))) != (len - EMT_GRPSPIS_FLEN)) { + printk("klips_debug:ipsec_callback: " + "EMT_GRPSPI message size incorrect, expected nspis(%d)*%d, got %d.\n", + nspis, + sizeof(em->em_rel[0]), + (len - EMT_GRPSPIS_FLEN)); + SENDERR(EINVAL); + break; + } + + spin_lock_bh(&tdb_lock); + + for (i = 0; i < nspis; i++) { + KLIPS_PRINT(debug_netlink, + "klips_debug:ipsec_callback: " + "EMT_GRPSPI for SA(%d) %s,\n", + i, + sa_len ? sa : " (error)"); + if ((tdbp = gettdb(&(em->em_rel[i].emr_said))) == NULL) { + KLIPS_PRINT(debug_netlink, + "klips_debug:ipsec_callback: " + "EMT_GRPSPI Tunnel Descriptor Block not found for SA%s, could not group.\n", + sa_len ? sa : " (error)"); + spin_unlock_bh(&tdb_lock); + SENDERR(ENXIO); + } else { + if(tdbp->tdb_inext || tdbp->tdb_onext) { + KLIPS_PRINT(debug_netlink, + "klips_debug:ipsec_callback: " + "EMT_GRPSPI Tunnel Descriptor Block already grouped for SA: %s, can't regroup.\n", + sa_len ? sa : " (error)"); + spin_unlock_bh(&tdb_lock); + SENDERR(EBUSY); + } + em->em_rel[i].emr_tdb = tdbp; + } + } + tprev = em->em_rel[0].emr_tdb; + tprev->tdb_inext = NULL; + for (i = 1; i < nspis; i++) { + tdbp = em->em_rel[i].emr_tdb; + tprev->tdb_onext = tdbp; + tdbp->tdb_inext = tprev; + tprev = tdbp; + } + tprev->tdb_onext = NULL; + + spin_unlock_bh(&tdb_lock); + + error = 0; + break; + + case EMT_UNGRPSPIS: + if (len != (8 + (sizeof(struct sa_id) + sizeof(struct tdb *)) /* 12 */) ) { + printk("klips_debug:ipsec_callback: " + "EMT_UNGRPSPIS message size incorrect, expected %d, got %d.\n", + 8 + (sizeof(struct sa_id) + sizeof(struct tdb *)), + len); + SENDERR(EINVAL); + break; + } + + spin_lock_bh(&tdb_lock); + + if ((tdbp = gettdb(&(em->em_rel[0].emr_said))) == NULL) { + KLIPS_PRINT(debug_netlink, + "klips_debug:ipsec_callback: " + "EMT_UGRPSPI Tunnel Descriptor Block not found for SA%s, could not ungroup.\n", + sa_len ? sa : " (error)"); + spin_unlock_bh(&tdb_lock); + SENDERR(ENXIO); + } + while(tdbp->tdb_onext) { + tdbp = tdbp->tdb_onext; + } + while(tdbp->tdb_inext) { + tprev = tdbp; + tdbp = tdbp->tdb_inext; + tprev->tdb_inext = NULL; + tdbp->tdb_onext = NULL; + } + + spin_unlock_bh(&tdb_lock); + + break; + + case EMT_CLRSPIS: + KLIPS_PRINT(debug_netlink, + "klips_debug:ipsec_callback: " + "spi clear called.\n"); + if (em->em_if >= 5) /* XXX -- why 5? */ + SENDERR(ENODEV); + ipsec_tdbcleanup(0); + break; + default: + KLIPS_PRINT(debug_netlink, + "klips_debug:ipsec_callback: " + "unknown message type\n"); + SENDERR(EINVAL); + } + errlab: +#ifdef NET_21 + kfree_skb(skb); +#else /* NET_21 */ + kfree_skb(skb, FREE_WRITE); +#endif /* NET_21 */ + return len; +} +#endif + +/* + * $Log: ipsec_netlink.c,v $ + * Revision 1.4 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.3 2003/01/19 22:32:30 ken + * X.509 0.9.19 -> 0.9.20 + * + * Revision 1.2 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.56 2002/01/29 17:17:55 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.55 2002/01/29 04:00:51 mcr + * more excise of kversions.h header. + * + * Revision 1.54 2001/10/18 04:45:19 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/freeswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.53 2001/09/15 16:24:04 rgb + * Re-inject first and last HOLD packet when an eroute REPLACE is done. + * + * Revision 1.52 2001/09/14 16:58:36 rgb + * Added support for storing the first and last packets through a HOLD. + * + * Revision 1.51 2001/09/08 21:13:32 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.50 2001/07/06 19:49:00 rgb + * Renamed EMT_RPLACEROUTE to EMT_REPLACEROUTE for clarity and logical text + * searching. + * + * Revision 1.49 2001/06/14 19:35:08 rgb + * Update copyright date. + * + * Revision 1.48 2001/02/27 22:24:54 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.47 2000/11/06 04:32:08 rgb + * Ditched spin_lock_irqsave in favour of spin_lock_bh. + * + * Revision 1.46 2000/09/08 19:16:50 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * Removed all references to CONFIG_IPSEC_PFKEYv2. + * + * Revision 1.45 2000/08/30 05:23:55 rgb + * Compiler-define out ipsec_callback() function of ipsec_netlink.c. + * Nothing should be using it anyways. + * + * Revision 1.44 2000/03/16 14:01:26 rgb + * Indented headers for readability. + * + * Revision 1.43 2000/03/16 07:13:04 rgb + * Hardcode PF_KEYv2 support. + * Disable NET_LINK support. + * + * Revision 1.42 2000/01/21 06:14:27 rgb + * Moved debug message for expected output on set or clear. + * + * Revision 1.41 1999/12/01 22:14:37 rgb + * Added debugging message for bad netlink magic. + * Initialise tdb_sastate to MATURE (1). + * Added UNGRPSPIS bad length debugging message. + * + * Revision 1.40 1999/11/23 23:06:25 rgb + * Sort out pfkey and freeswan headers, putting them in a library path. + * + * Revision 1.39 1999/11/18 04:09:18 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.38 1999/11/17 15:53:39 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.37 1999/10/26 13:58:32 rgb + * Put spinlock flags variable declaration outside the debug compiler + * directive to enable compilation with debug shut off. + * + * Revision 1.36 1999/10/16 18:24:22 rgb + * Initialize lifetime_addtime_c and lifetime_allocations_c. + * Clean-up unused cruft. + * + * Revision 1.35 1999/10/08 18:37:34 rgb + * Fix end-of-line spacing to sate whining PHMs. + * + * Revision 1.34 1999/10/03 18:49:11 rgb + * Spinlock fixes for 2.0.xx and 2.3.xx. + * + * Revision 1.33 1999/10/01 15:44:53 rgb + * Move spinlock header include to 2.1> scope. + * + * Revision 1.32 1999/10/01 00:00:53 rgb + * Fix for proper netlink debugging operation. + * Added tdb structure locking. + * Minor formatting changes. + * + * Revision 1.31 1999/05/25 21:21:43 rgb + * Fix deltdbchain() error return code checking. + * + * Revision 1.30 1999/05/09 03:25:36 rgb + * Fix bug introduced by 2.2 quick-and-dirty patch. + * + * Revision 1.29 1999/05/08 21:23:27 rgb + * Simplify satoa() calling. + * Fix error return reporting. + * Add casting to silence the 2.2.x compile. + * + * Revision 1.28 1999/05/05 22:02:31 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.27 1999/04/29 15:16:24 rgb + * Add pfkey support to debugging. + * Change gettdb parameter to a pointer to reduce stack loading and + * facilitate + * parameter sanity checking. + * Add IS_MYADDR support obviating the necessity of doing this in user + * space. + * Fix undetected bug by moving puttdb in SETSPI until after initialisation + * to + * prevent tdb usage before it is ready and to save work if it does not + * initialise. + * Clean up deltdb/wipe code. + * Fix undetected bug of returning error as positive value. + * Add a parameter to tdbcleanup to be able to delete a class of SAs. + * + * Revision 1.26 1999/04/16 15:39:35 rgb + * Fix already fixed unbalanced #endif. + * + * Revision 1.25 1999/04/15 15:37:24 rgb + * Forward check changes from POST1_00 branch. + * + * Revision 1.21.2.1 1999/04/13 20:30:26 rgb + * Add experimental 'getdebug'. + * + * Revision 1.24 1999/04/11 00:28:58 henry + * GPL boilerplate + * + * Revision 1.23 1999/04/07 17:44:21 rgb + * Fix ipsec_callback memory leak, skb not freed after use. + * + * Revision 1.22 1999/04/06 04:54:26 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.21 1999/02/17 16:50:11 rgb + * Consolidate satoa()s for space and speed efficiency. + * Convert DEBUG_IPSEC to KLIPS_PRINT + * Clean out unused cruft. + * + * Revision 1.20 1999/01/28 23:20:49 rgb + * Replace hard-coded numbers in macros and code with meaningful values + * automatically generated from sizeof() and offsetof() to further the + * goal of platform independance. + * + * Revision 1.19 1999/01/26 02:07:07 rgb + * Removed CONFIG_IPSEC_ALGO_SWITCH macro. + * Remove ah/esp switching on include files. + * Removed dead code. + * + * Revision 1.18 1999/01/22 06:20:36 rgb + * Cruft clean-out. + * 64-bit clean-up. + * Added algorithm switch code. + * + * Revision 1.17 1998/12/02 03:09:39 rgb + * Clean up debug printing conditionals to compile with debugging off. + * + * Revision 1.16 1998/12/01 05:56:57 rgb + * Add support for debug printing of version info. + * Fail on unknown error for breakroute in replace command. + * + * Revision 1.15 1998/11/30 13:22:54 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.14 1998/11/10 05:36:14 rgb + * Clean up debug output. + * Add direction to spi setup debug code. + * Add support for SA direction flag. + * + * Revision 1.13 1998/10/31 06:51:56 rgb + * Get zeroize to return something useful. + * Clean up code to isolate 'spi --add/del' memory leak. + * Fixed up comments in #endif directives. + * + * Revision 1.12 1998/10/27 00:35:02 rgb + * Supressed debug output during normal operation. + * + * Revision 1.11 1998/10/25 02:40:21 rgb + * Selective debug printing, depending upon called service. + * Institute more precise error return codes from eroute commands. + * Fix bug in size of stucture passed in from user space for grpspi command. + * + * Revision 1.10 1998/10/22 06:44:58 rgb + * Convert to use satoa for printk. + * Moved break; in 'set debug level code to avoid undetected bug. + * Fixed run-on error message to fit 80 columns. + * + * Revision 1.9 1998/10/19 14:44:28 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * + * Revision 1.8 1998/10/09 04:29:51 rgb + * Added support for '-replace' option to eroute. + * Fixed spiungroup bug. + * Added 'klips_debug' prefix to all klips printk debug statements. + * + * Revision 1.7 1998/08/12 00:10:06 rgb + * Fixed minor error return code syntax. + * + * Revision 1.6 1998/07/29 20:22:57 rgb + * Cosmetic cleanup. + * + * Revision 1.5 1998/07/27 21:53:11 rgb + * Check for proper return code from eroute clear command. + * Use appropriate error return codes from kernel. + * Add an option to clear the SA table. + * + * Revision 1.4 1998/07/14 18:02:40 rgb + * Add a command to clear the eroute table. + * Clean up some error codes. + * + * Revision 1.3 1998/06/25 19:52:33 rgb + * Code cosmetic changes only. + * + * Revision 1.2 1998/06/23 02:57:58 rgb + * Clean up after an error condition in setspi. + * + * Revision 1.9 1998/06/18 21:29:06 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid kernel + * build scripts happier in presence of symbolic links + * + * Revision 1.8 1998/06/08 17:57:15 rgb + * Very minor spacing change. + * + * Revision 1.7 1998/05/18 21:46:45 rgb + * Clean up for numerical consistency of output. + * + * Added debugging switch output. + * + * SETSPI will refuse to overwrite a previous SA. This is to make it + * consistent with the eroute command. + * + * spidel now deletes entire chain of spi's. + * + * spigrp can now ungroup a set of spi's. + * + * spigrp will not regroup a previously grouped spi. + * + * Key data is properly cleaned up, ie. zeroed. + * + * Revision 1.6 1998/05/07 20:36:27 rgb + * Fixed case where debugging not enabled that caused ipsec_netlink.c to + * not compile. + * + * Revision 1.5 1998/05/06 03:34:21 rgb + * Updated debugging output statements. + * + * Revision 1.4 1998/04/23 21:03:59 rgb + * Completed kernel development for userspace access to klips kernel debugging + * switches. + * Added detail to the kernel error message when trying to group non-existant + * spi's. + * + * Revision 1.3 1998/04/21 21:29:06 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.2 1998/04/12 22:03:23 rgb + * Updated ESP-3DES-HMAC-MD5-96, + * ESP-DES-HMAC-MD5-96, + * AH-HMAC-MD5-96, + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository + * from old standards (RFC182[5-9] to new (as of March 1998) drafts. + * + * Fixed eroute references in /proc/net/ipsec*. + * + * Started to patch module unloading memory leaks in ipsec_netlink and + * radij tree unloading. + * + * Revision 1.1 1998/04/09 03:06:08 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:02 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_netlink.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_netlink.h --- linux-2.4.29/net/ipsec/ipsec_netlink.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_netlink.h Thu Sep 5 05:13:17 2002 @@ -0,0 +1,345 @@ +/* + * IPSEC <> netlink interface + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_netlink.h,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + */ + +#include + +#ifndef NETLINK_IPSEC +#define NETLINK_IPSEC 10 /* IPSEC */ +#endif /* !NETLINK_IPSEC */ + +#define EM_MAXRELSPIS 4 /* at most five chained xforms */ +#define EM_MAGIC 0x5377616e /* "Swan" */ + +#define EMT_IFADDR 1 /* set enc if addr */ +#define EMT_SETSPI 2 /* Set SPI properties */ +#define EMT_DELSPI 3 /* Delete an SPI */ +#define EMT_GRPSPIS 4 /* Group SPIs (output order) */ +#define EMT_SETEROUTE 5 /* set an extended route */ +#define EMT_DELEROUTE 6 /* del an extended route */ +#define EMT_TESTROUTE 7 /* try to find route, print to console */ +#define EMT_SETDEBUG 8 /* set debug level if active */ +#define EMT_UNGRPSPIS 9 /* UnGroup SPIs (output order) */ +#define EMT_CLREROUTE 10 /* clear the extended route table */ +#define EMT_CLRSPIS 11 /* clear the spi table */ +#define EMT_REPLACEROUTE 12 /* set an extended route */ +#define EMT_GETDEBUG 13 /* get debug level if active */ +#define EMT_INEROUTE 14 /* set incoming policy for IPIP on a chain */ + +#ifdef CONFIG_IPSEC_DEBUG +#define DB_NL_TDBCB 0x0001 +#endif /* CONFIG_IPSEC_DEBUG */ + +/* em_flags constants */ +/* be mindful that this flag conflicts with SADB_SAFLAGS_PFS in pfkeyv2 */ +/* perhaps it should be moved... */ +#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */ + +struct encap_msghdr +{ + __u32 em_magic; /* EM_MAGIC */ +#if 0 + __u16 em_msglen; /* message length */ +#endif + __u8 em_msglen; /* message length */ + __u8 em_flags; /* message flags */ + __u8 em_version; /* for future expansion */ + __u8 em_type; /* message type */ + union + { + __u8 C; /* Free-text */ + + struct + { + struct sa_id Said; /* SA ID */ + struct sockaddr_encap Eaddr; + struct sockaddr_encap Emask; + } Ert; + + struct + { + struct in_addr Ia; + __u8 Ifn; + __u8 xxx[3]; /* makes life a lot easier */ + } Ifa; + + struct + { + struct sa_id Said; /* SA ID */ + int If; /* enc i/f for input */ + int Alg; /* Algorithm to use */ + + /* The following union is a surrogate for + * algorithm-specific data. To insure + * proper alignment, worst-case fields + * should be included. It would be even + * better to include the types that will + * actually be used, but they may not be + * defined for each use of this header. + * The actual length is expected to be longer + * than is declared here. References are normally + * made using the em_dat macro, as if it were a + * field name. + */ + union { /* Data */ + __u8 Dat[1]; + __u64 Datq[1]; /* maximal alignment (?) */ + } u; + } Xfm; + + struct + { + struct sa_id emr_said; /* SA ID */ + struct ipsec_sa * emr_tdb; /* used internally! */ + + } Rel[EM_MAXRELSPIS]; + +#ifdef CONFIG_IPSEC_DEBUG + struct + { + int debug_tunnel; + int debug_netlink; + int debug_xform; + int debug_eroute; + int debug_spi; + int debug_radij; + int debug_esp; + int debug_ah; + int debug_rcv; + int debug_pfkey; + int debug_ipcomp; + int debug_verbose; + } Dbg; +#endif /* CONFIG_IPSEC_DEBUG */ + } Eu; +}; + +#define EM_MINLEN offsetof(struct encap_msghdr, Eu) +#define EMT_SETSPI_FLEN offsetof(struct encap_msghdr, em_dat) +#define EMT_GRPSPIS_FLEN offsetof(struct encap_msghdr, Eu.Rel) +#define EMT_SETDEBUG_FLEN (offsetof(struct encap_msghdr, Eu.Dbg + \ + sizeof(((struct encap_msghdr*)0)->Eu.Dbg))) + +#define em_c Eu.C +#define em_eaddr Eu.Ert.Eaddr +#define em_emask Eu.Ert.Emask +#define em_ersaid Eu.Ert.Said +#define em_erdst Eu.Ert.Said.dst +#define em_erspi Eu.Ert.Said.spi +#define em_erproto Eu.Ert.Said.proto + +#define em_ifa Eu.Ifa.Ia +#define em_ifn Eu.Ifa.Ifn + +#define em_said Eu.Xfm.Said +#define em_spi Eu.Xfm.Said.spi +#define em_dst Eu.Xfm.Said.dst +#define em_proto Eu.Xfm.Said.proto +#define em_if Eu.Xfm.If +#define em_alg Eu.Xfm.Alg +#define em_dat Eu.Xfm.u.Dat + +#define em_rel Eu.Rel +#define emr_dst emr_said.dst +#define emr_spi emr_said.spi +#define emr_proto emr_said.proto + +#ifdef CONFIG_IPSEC_DEBUG +#define em_db_tn Eu.Dbg.debug_tunnel +#define em_db_nl Eu.Dbg.debug_netlink +#define em_db_xf Eu.Dbg.debug_xform +#define em_db_er Eu.Dbg.debug_eroute +#define em_db_sp Eu.Dbg.debug_spi +#define em_db_rj Eu.Dbg.debug_radij +#define em_db_es Eu.Dbg.debug_esp +#define em_db_ah Eu.Dbg.debug_ah +#define em_db_rx Eu.Dbg.debug_rcv +#define em_db_ky Eu.Dbg.debug_pfkey +#define em_db_gz Eu.Dbg.debug_ipcomp +#define em_db_vb Eu.Dbg.debug_verbose +#endif /* CONFIG_IPSEC_DEBUG */ + +#ifdef __KERNEL__ +extern char ipsec_netlink_c_version[]; +#ifndef KERNEL_VERSION +# include +#endif +#ifdef NETLINK_SOCK +extern int ipsec_callback(int proto, struct sk_buff *skb); +#else /* NETLINK_SOCK */ +extern int ipsec_callback(struct sk_buff *skb); +#endif /* NETLINK_SOCK */ +extern void ipsec_print_ip(struct iphdr *ip); + +#ifdef CONFIG_IPSEC_DEBUG + #define KLIPS_PRINT(flag, format, args...) \ + ((flag) ? printk(KERN_INFO format , ## args) : 0) + #define KLIPS_PRINTMORE(flag, format, args...) \ + ((flag) ? printk(format , ## args) : 0) + #define KLIPS_IP_PRINT(flag, ip) \ + ((flag) ? ipsec_print_ip(ip) : 0) +#else /* CONFIG_IPSEC_DEBUG */ + #define KLIPS_PRINT(flag, format, args...) do ; while(0) + #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0) + #define KLIPS_IP_PRINT(flag, ip) do ; while(0) +#endif /* CONFIG_IPSEC_DEBUG */ + +#ifdef CONFIG_IPSEC_DEBUG +extern int debug_netlink; +#endif /* CONFIG_IPSEC_DEBUG */ +#endif /* __KERNEL__ */ + +/* + * $Log: ipsec_netlink.h,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.31 2001/11/26 09:23:48 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.30 2001/07/06 19:49:16 rgb + * Renamed EMT_RPLACEROUTE to EMT_REPLACEROUTE for clarity and logical text + * searching. + * Added EMT_INEROUTE for supporting incoming policy checks. + * + * Revision 1.29 2001/06/14 19:35:09 rgb + * Update copyright date. + * + * Revision 1.28 2000/10/10 20:10:18 rgb + * Added support for debug_ipcomp and debug_verbose to klipsdebug. + * + * Revision 1.27 2000/09/12 03:20:28 rgb + * Cleared out now unused pfkeyv2 switch. + * + * Revision 1.26 2000/09/08 19:16:50 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * Removed all references to CONFIG_IPSEC_PFKEYv2. + * + * Revision 1.25 2000/08/24 16:51:59 rgb + * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level + * info. + * + * Revision 1.24 2000/08/09 20:43:34 rgb + * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE. + * + * Revision 1.23 2000/03/16 14:01:48 rgb + * Hardwired CONFIG_IPSEC_PFKEYv2 on. + * + * Revision 1.22 1999/12/08 20:31:32 rgb + * Moved IPPROTO_COMP to lib/freeswan.h to simplify userspace includes. + * + * Revision 1.21 1999/11/18 18:47:41 rgb + * Added "#define NETLINK_IPSEC" in case kernel was not compiled with it. + * + * Revision 1.20 1999/11/18 04:09:18 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.19 1999/08/28 08:27:05 rgb + * Add a temporary kludge for 2.0.37-38 to compile even if one patch failed. + * + * Revision 1.18 1999/08/03 17:09:33 rgb + * Tidy up debug output, use KERN_INFO macro in printk's. + * + * Revision 1.17 1999/05/25 01:45:37 rgb + * Fix version macros for 2.0.x as a module. + * + * Revision 1.16 1999/05/05 22:02:31 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.15 1999/04/29 15:16:55 rgb + * Add pfkey support to debugging. + * + * Revision 1.14 1999/04/15 15:37:24 rgb + * Forward check changes from POST1_00 branch. + * + * Revision 1.13 1999/04/11 00:28:58 henry + * GPL boilerplate + * + * Revision 1.12 1999/04/06 04:54:26 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.11 1999/02/12 21:13:17 rgb + * Moved KLIPS_PRINT into a more accessible place. + * + * Revision 1.10 1999/01/28 23:20:49 rgb + * Replace hard-coded numbers in macros and code with meaningful values + * automatically generated from sizeof() and offsetof() to further the + * goal of platform independance. + * + * Revision 1.9 1999/01/22 06:21:23 rgb + * Added algorithm switch code. + * Cruft clean-out. + * 64-bit clean-up. + * + * Revision 1.8 1998/12/01 05:57:42 rgb + * Add support for printing debug version info. + * + * Revision 1.7 1998/11/10 05:37:35 rgb + * Add support for SA direction flag. + * + * Revision 1.6 1998/10/25 02:40:45 rgb + * Fix bug in size of stucture passed in from user space for grpspi command. + * + * Revision 1.5 1998/10/19 14:44:29 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * + * Revision 1.4 1998/10/09 04:30:11 rgb + * Added support for '-replace' option to eroute. + * + * Revision 1.3 1998/07/27 21:54:22 rgb + * Rearrange structures for consistent alignment within a union. + * Add an option for clearing SA table. + * + * Revision 1.2 1998/07/14 18:05:51 rgb + * Added #ifdef __KERNEL__ directives to restrict scope of header. + * + * Revision 1.1 1998/06/18 21:27:49 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.4 1998/05/18 21:48:24 rgb + * Added switch for ungrouping spi's. + * + * Revision 1.3 1998/04/23 21:01:50 rgb + * Added a macro for userspace access to klips kernel debugging switches. + * + * Revision 1.2 1998/04/21 21:29:09 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.1 1998/04/09 03:06:09 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:03 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_param.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_param.h --- linux-2.4.29/net/ipsec/ipsec_param.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_param.h Thu Sep 5 05:13:17 2002 @@ -0,0 +1,150 @@ +/* + * @(#) FreeSWAN tunable paramaters + * + * Copyright (C) 2001 Richard Guy Briggs + * and Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_param.h,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + * + */ + +/* + * This file provides a set of #define's which may be tuned by various + * people/configurations. It keeps all compile-time tunables in one place. + * + * This file should be included before all other IPsec kernel-only files. + * + */ + +#ifndef _IPSEC_PARAM_H_ + +#include "ipsec_kversion.h" + +#ifdef CONFIG_IPSEC_BIGGATE +#define SADB_HASHMOD 8069 +#else +#define SADB_HASHMOD 257 +#endif + +#ifndef PROC_NO_DUMMY +#define IPSEC_PROC_LAST_ARG , int dummy +#else +#define IPSEC_PROC_LAST_ARG +#endif /* !PROC_NO_DUMMY */ + +#ifdef NETDEV_23 + +#define device net_device +#define ipsec_dev_get __dev_get_by_name + +#else + +#define ipsec_dev_get dev_get + +#endif /* NETDEV_23 */ + +#ifndef PROC_FS_2325 +#define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC +#else +#define IPSEC_PROCFS_DEBUG_NO_STATIC +#endif /* PROC_FS_2325 */ + +#if !defined(LINUX_KERNEL_HAS_SNPRINTF) +/* GNU CPP specific! */ +#define snprintf(buf, len, fmt...) sprintf(buf, ##fmt) +#endif + +#ifdef SPINLOCK + #ifdef SPINLOCK_23 + #include /* *lock* */ + #else /* SPINLOCK_23 */ + #include /* *lock* */ + #endif /* SPINLOCK_23 */ +#endif /* SPINLOCK */ + +#ifndef KLIPS_FIXES_DES_PARITY +#define KLIPS_FIXES_DES_PARITY 1 +#endif + +#ifndef KLIPS_DIVULGE_CYPHER_KEY +#define KLIPS_DIVULGE_CYPHER_KEY 0 +#endif + +/* extra toggles for regression testing */ +#ifdef CONFIG_IPSEC_REGRESS + +/* + * should pfkey_acquire() become 100% lossy? + * + */ +extern int sysctl_ipsec_regress_pfkey_lossage; +#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE +#ifdef CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE +#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100 +#else +/* not by default! */ +#define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0 +#endif +#endif + +#endif + +/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */ +#ifndef IP_FRAGMENT_LINEARIZE +#define IP_FRAGMENT_LINEARIZE 0 +#endif + +#define _IPSEC_PARAM_H_ +#endif + +/* + * $Log: ipsec_param.h,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.6 2002/01/29 02:11:42 mcr + * removal of kversions.h - sources that needed it now use ipsec_param.h. + * updating of IPv6 structures to match latest in6.h version. + * removed dead code from freeswan.h that also duplicated kversions.h + * code. + * + * Revision 1.5 2002/01/28 19:22:01 mcr + * by default, turn off LINEARIZE option + * (let kversions.h turn it on) + * + * Revision 1.4 2002/01/20 20:19:36 mcr + * renamed option to IP_FRAGMENT_LINEARIZE. + * + * Revision 1.3 2002/01/12 02:57:25 mcr + * first regression test causes acquire messages to be lost + * 100% of the time. This is to help testing of pluto. + * + * Revision 1.2 2001/11/26 09:16:14 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.1.2.3 2001/10/23 04:40:16 mcr + * added #define for DIVULGING session keys in debug output. + * + * Revision 1.1.2.2 2001/10/22 20:53:25 mcr + * added a define to control forcing of DES parity. + * + * Revision 1.1.2.1 2001/09/25 02:20:19 mcr + * many common kernel configuration questions centralized. + * more things remain that should be moved from freeswan.h. + * + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_proc.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_proc.c --- linux-2.4.29/net/ipsec/ipsec_proc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_proc.c Thu Jun 17 10:47:11 2004 @@ -0,0 +1,825 @@ +/* + * @(#) /proc file system interface code. + * + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs + * 2001 Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * Split out from ipsec_init.c version 1.70. + */ + +char ipsec_proc_c_version[] = "RCSID $Id: ipsec_proc.c,v 1.8 2004/06/17 08:47:11 ken Exp $"; + +#include +#include +#define __NO_VERSION__ +#include +#include /* printk() */ + +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include /* struct sockaddr_in */ +#include +#include +#ifdef SPINLOCK +#ifdef SPINLOCK_23 +#include /* *lock* */ +#else /* SPINLOCK_23 */ +#include /* *lock* */ +#endif /* SPINLOCK_23 */ +#endif /* SPINLOCK */ +#ifdef NET_21 +#include +#include +#endif /* NET_21 */ +#include +#include +#ifdef CONFIG_PROC_FS +#include +#endif /* CONFIG_PROC_FS */ +#ifdef NETLINK_SOCK +#include +#else +#include +#endif + +#include "radij.h" + +#include "ipsec_life.h" +#include "ipsec_stats.h" +#include "ipsec_sa.h" + +#include "ipsec_encap.h" +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_xform.h" +#include "ipsec_tunnel.h" + +#include "ipsec_rcv.h" +#include "ipsec_ah.h" +#include "ipsec_esp.h" + +#ifdef CONFIG_IPSEC_IPCOMP +#include "ipcomp.h" +#endif /* CONFIG_IPSEC_IPCOMP */ + +#include "ipsec_proto.h" + +#include +#include + +#ifdef CONFIG_PROC_FS + +#if 0 +static struct proc_dir_entry *proc_net_ipsec_dir; +#endif + +/* ipsec_snprintf: like snprintf except + * - size is signed and a negative value is treated as if it were 0 + * - the returned result is never negative -- + * an error generates a "?" or null output (depending on space). + * (Our callers are too lazy to check for an error return.) + */ +int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...) +{ + va_list args; + int i; + size_t possize = size < 0? 0 : size; + + va_start(args, fmt); + i = vsnprintf(buf,possize,fmt,args); + va_end(args); + if (i < 0) { + /* create empty output in place of error */ + i = 0; + if (size > 0) { + *buf = '\0'; + } + } + return i; +} + +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_eroute_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + struct wsbuf w = {buffer, length, offset, 0, 0}; + +#ifdef CONFIG_IPSEC_DEBUG + if (debug_radij & DB_RJ_DUMPTREES) + rj_dumptrees(); /* XXXXXXXXX */ +#endif /* CONFIG_IPSEC_DEBUG */ + + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_eroute_get_info: " + "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n", + buffer, + (u_int)*start, + (int)offset, + length); + + spin_lock_bh(&eroute_lock); + + rj_walktree(rnh, ipsec_rj_walker_procprint, &w); +/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */ + + spin_unlock_bh(&eroute_lock); + + *start = buffer + (offset - w.begin); /* Start of wanted data */ + return w.len - (offset - w.begin); +} + +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_spi_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ + int len = 0; + off_t begin = 0; + int i; + struct ipsec_sa *sa_p; + char sa[SATOA_BUF]; + char buf_s[SUBNETTOA_BUF]; + char buf_d[SUBNETTOA_BUF]; + size_t sa_len; + + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_spi_get_info: " + "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n", + buffer, + (u_int)*start, + (int)offset, + length); + + spin_lock_bh(&tdb_lock); + + for (i = 0; i < SADB_HASHMOD; i++) { + for (sa_p = ipsec_sadb_hash[i]; + sa_p; + sa_p = sa_p->ips_hnext) { + sa_len = satoa(sa_p->ips_said, 0, sa, SATOA_BUF); + len += ipsec_snprintf(buffer+len, length-len, "%s ", + sa_len ? sa : " (error)"); + + len += ipsec_snprintf(buffer+len, length-len, "%s%s%s", + IPS_XFORM_NAME(sa_p)); + + len += ipsec_snprintf(buffer+len, length-len, ": dir=%s", + (sa_p->ips_flags & EMT_INBOUND) ? + "in " : "out"); + + if(sa_p->ips_addr_s) { + addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr, + 0, buf_s, sizeof(buf_s)); + len += ipsec_snprintf(buffer+len, length-len, " src=%s", + buf_s); + } + + if((sa_p->ips_said.proto == IPPROTO_IPIP) + && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) { + subnettoa(sa_p->ips_flow_s.u.v4.sin_addr, + sa_p->ips_mask_s.u.v4.sin_addr, + 0, + buf_s, + sizeof(buf_s)); + + subnettoa(sa_p->ips_flow_d.u.v4.sin_addr, + sa_p->ips_mask_d.u.v4.sin_addr, + 0, + buf_d, + sizeof(buf_d)); + + len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s", + buf_s, buf_d); + } + + if(sa_p->ips_iv_bits) { + int j; + len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x", + sa_p->ips_iv_bits); + + for(j = 0; j < sa_p->ips_iv_bits / 8; j++) { + len += ipsec_snprintf(buffer+len, length-len, "%02x", + (__u32)((__u8*)(sa_p->ips_iv))[j]); + } + } + + if(sa_p->ips_encalg || sa_p->ips_authalg) { + if(sa_p->ips_replaywin) { + len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d", + sa_p->ips_replaywin); + } + if(sa_p->ips_errs.ips_replaywin_errs) { + len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d", + sa_p->ips_errs.ips_replaywin_errs); + } + if(sa_p->ips_replaywin_lastseq) { + len += ipsec_snprintf(buffer+len, length-len, " seq=%d", + sa_p->ips_replaywin_lastseq); + } + if(sa_p->ips_replaywin_bitmap) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx", + (long long)sa_p->ips_replaywin_bitmap); +#else + len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x", + (__u32)(sa_p->ips_replaywin_bitmap >> 32), + (__u32)sa_p->ips_replaywin_bitmap); +#endif + } + if(sa_p->ips_replaywin_maxdiff) { + len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d", + sa_p->ips_replaywin_maxdiff); + } + } + if(sa_p->ips_flags & ~EMT_INBOUND) { + len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x", + sa_p->ips_flags & ~EMT_INBOUND); + len += ipsec_snprintf(buffer+len, length-len, "<"); + /* flag printing goes here */ + len += ipsec_snprintf(buffer+len, length-len, ">"); + } + if(sa_p->ips_auth_bits) { + len += ipsec_snprintf(buffer+len, length-len, " alen=%d", + sa_p->ips_auth_bits); + } + if(sa_p->ips_key_bits_a) { + len += ipsec_snprintf(buffer+len, length-len, " aklen=%d", + sa_p->ips_key_bits_a); + } + if(sa_p->ips_errs.ips_auth_errs) { + len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d", + sa_p->ips_errs.ips_auth_errs); + } + if(sa_p->ips_key_bits_e) { + len += ipsec_snprintf(buffer + len, length-len, " eklen=%d", + sa_p->ips_key_bits_e); + } + if(sa_p->ips_errs.ips_encsize_errs) { + len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d", + sa_p->ips_errs.ips_encsize_errs); + } + if(sa_p->ips_errs.ips_encpad_errs) { + len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d", + sa_p->ips_errs.ips_encpad_errs); + } + + len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)="); + + len += ipsec_lifetime_format(buffer + len, + length - len, + "alloc", + ipsec_life_countbased, + &sa_p->ips_life.ipl_allocations); + + len += ipsec_lifetime_format(buffer + len, + length - len, + "bytes", + ipsec_life_countbased, + &sa_p->ips_life.ipl_bytes); + + len += ipsec_lifetime_format(buffer + len, + length - len, + "addtime", + ipsec_life_timebased, + &sa_p->ips_life.ipl_addtime); + + len += ipsec_lifetime_format(buffer + len, + length - len, + "usetime", + ipsec_life_timebased, + &sa_p->ips_life.ipl_usetime); + + len += ipsec_lifetime_format(buffer + len, + length - len, + "packets", + ipsec_life_countbased, + &sa_p->ips_life.ipl_packets); + + if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld", + (long long)(jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last)); +#else + len += ipsec_snprintf(buffer+len, length-len, " idle=%lu", + jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last); +#endif + } + +#ifdef CONFIG_IPSEC_IPCOMP + if(sa_p->ips_said.proto == IPPROTO_COMP && + (sa_p->ips_comp_ratio_dbytes || + sa_p->ips_comp_ratio_cbytes)) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0) + len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld", + (long long)sa_p->ips_comp_ratio_dbytes, + (long long)sa_p->ips_comp_ratio_cbytes); +#else + len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu", + (unsigned long)sa_p->ips_comp_ratio_dbytes, + (unsigned long)sa_p->ips_comp_ratio_cbytes); +#endif + } +#endif /* CONFIG_IPSEC_IPCOMP */ + + len += ipsec_snprintf(buffer+len, length-len, "\n"); + + if (len >= max_content) { + /* we've done all that can fit -- stop loops */ + len = max_content; /* truncate crap */ + goto done_spi_i; + } else { + const off_t pos = begin + len; /* file position of end of what we've generated */ + + if (pos <= offset) { + /* all is before first interesting character: + * discard, but note where we are. + */ + len = 0; + begin = pos; + } + } + } + } + + done_spi_i: + spin_unlock_bh(&tdb_lock); + + *start = buffer + (offset - begin); /* Start of wanted data */ + return len - (offset - begin); +} + +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_spigrp_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ + int len = 0; + off_t begin = 0; + int i; + struct ipsec_sa *sa_p, *sa_p2; + char sa[SATOA_BUF]; + size_t sa_len; + + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_spigrp_get_info: " + "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n", + buffer, + (u_int)*start, + (int)offset, + length); + + spin_lock_bh(&tdb_lock); + + for (i = 0; i < SADB_HASHMOD; i++) { + for (sa_p = ipsec_sadb_hash[i]; + sa_p; + sa_p = sa_p->ips_hnext) + { + if(!sa_p->ips_inext) + { + sa_p2 = sa_p; + while(sa_p2) { + sa_len = satoa(sa_p2->ips_said, + 0, sa, SATOA_BUF); + + len += ipsec_snprintf(buffer+len, length-len, "%s ", + sa_len ? sa : " (error)"); + sa_p2 = sa_p2->ips_onext; + } + len += ipsec_snprintf(buffer+len, length-len, "\n"); + } + + if (len >= max_content) { + /* we've done all that can fit -- stop loops */ + len = max_content; /* truncate crap */ + goto done_spigrp_i; + } else { + const off_t pos = begin + len; /* file position of end of what we've generated */ + + if (pos <= offset) { + /* all is before first interesting character: + * discard, but note where we are. + */ + len = 0; + begin = pos; + } + } + } + } + + done_spigrp_i: + spin_unlock_bh(&tdb_lock); + + *start = buffer + (offset - begin); /* Start of wanted data */ + return len - (offset - begin); +} + + +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_tncfg_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ + int len = 0; + off_t begin = 0; + int i; + char name[9]; + struct device *dev, *privdev; + struct ipsecpriv *priv; + + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_tncfg_get_info: " + "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n", + buffer, + (u_int)*start, + (int)offset, + length); + + for(i = 0; i < IPSEC_NUM_IF; i++) { + /* minimum changes to remove sprintf, TIS */ + snprintf(name, sizeof(name), "ipsec%u", i); + dev = ipsec_dev_get(name); + if(dev) { + priv = (struct ipsecpriv *)(dev->priv); + len += ipsec_snprintf(buffer+len, length-len, "%s", + dev->name); + if(priv) { + privdev = (struct device *)(priv->dev); + len += ipsec_snprintf(buffer+len, length-len, " -> %s", + privdev ? privdev->name : "NULL"); + len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d", + dev->mtu, + priv->mtu, + privdev ? privdev->mtu : 0); + } else { + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n", + dev->name); + } + len += ipsec_snprintf(buffer+len, length-len, "\n"); + + if (len >= max_content) { + /* we've done all that can fit -- stop loop */ + len = max_content; /* truncate crap */ + break; + } else { + const off_t pos = begin + len; /* file position of end of what we've generated */ + + if (pos <= offset) { + /* all is before first interesting character: + * discard, but note where we are. + */ + len = 0; + begin = pos; + } + } + } + } + *start = buffer + (offset - begin); /* Start of wanted data */ + return len - (offset - begin); +} + +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_version_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ + int len = 0; + + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_version_get_info: " + "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n", + buffer, + (u_int)*start, + (int)offset, + length); + + len += ipsec_snprintf(buffer+len, length-len, "Openswan %s\n", + ipsec_version_code()); +#if 0 + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_version_get_info: " + "ipsec_init version: %s\n", + ipsec_init_c_version); + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_version_get_info: " + "ipsec_tunnel version: %s\n", + ipsec_tunnel_c_version); + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_version_get_info: " + "ipsec_netlink version: %s\n", + ipsec_netlink_c_version); + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_version_get_info: " + "radij_c_version: %s\n", + radij_c_version); +#endif + + if (len >= max_content) + len = max_content; /* truncate crap */ + + *start = buffer + offset; /* Start of wanted data */ + return len > offset? len - offset : 0; +} + +#ifdef CONFIG_IPSEC_DEBUG +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_klipsdebug_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ + int len = 0; + + KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, + "klips_debug:ipsec_klipsdebug_get_info: " + "buffer=0x%p, *start=0x%x, offset=%d, length=%d\n", + buffer, + (u_int)*start, + (int)offset, + length); + + len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel); + len += ipsec_snprintf(buffer+len, length-len, "debug_netlink=%08x.\n", debug_netlink); + len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform); + len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute); + len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi); + len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij); + len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp); + len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah); + len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv); + len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey); + + if (len >= max_content) + len = max_content; /* truncate crap */ + + *start = buffer + offset; /* Start of wanted data */ + return len > offset? len - offset : 0; +} +#endif /* CONFIG_IPSEC_DEBUG */ + +#ifndef PROC_FS_2325 +struct proc_dir_entry ipsec_eroute = +{ + 0, + 12, "ipsec_eroute", + S_IFREG | S_IRUGO, 1, 0, 0, 0, + &proc_net_inode_operations, + ipsec_eroute_get_info, + NULL, NULL, NULL, NULL, NULL +}; + +struct proc_dir_entry ipsec_spi = +{ + 0, + 9, "ipsec_spi", + S_IFREG | S_IRUGO, 1, 0, 0, 0, + &proc_net_inode_operations, + ipsec_spi_get_info, + NULL, NULL, NULL, NULL, NULL +}; + +struct proc_dir_entry ipsec_spigrp = +{ + 0, + 12, "ipsec_spigrp", + S_IFREG | S_IRUGO, 1, 0, 0, 0, + &proc_net_inode_operations, + ipsec_spigrp_get_info, + NULL, NULL, NULL, NULL, NULL +}; + +struct proc_dir_entry ipsec_tncfg = +{ + 0, + 11, "ipsec_tncfg", + S_IFREG | S_IRUGO, 1, 0, 0, 0, + &proc_net_inode_operations, + ipsec_tncfg_get_info, + NULL, NULL, NULL, NULL, NULL +}; + +struct proc_dir_entry ipsec_version = +{ + 0, + 13, "ipsec_version", + S_IFREG | S_IRUGO, 1, 0, 0, 0, + &proc_net_inode_operations, + ipsec_version_get_info, + NULL, NULL, NULL, NULL, NULL +}; + +#ifdef CONFIG_IPSEC_DEBUG +struct proc_dir_entry ipsec_klipsdebug = +{ + 0, + 16, "ipsec_klipsdebug", + S_IFREG | S_IRUGO, 1, 0, 0, 0, + &proc_net_inode_operations, + ipsec_klipsdebug_get_info, + NULL, NULL, NULL, NULL, NULL +}; +#endif /* CONFIG_IPSEC_DEBUG */ +#endif /* !PROC_FS_2325 */ +#endif /* CONFIG_PROC_FS */ + +int +ipsec_proc_init() +{ + int error = 0; + + /* compile a dummy function if no /proc/-fs */ + + /* XXX-mcr probably should just complain because pluto won't + * run without /proc! + */ + +#ifdef CONFIG_PROC_FS +# ifndef PROC_FS_2325 +# ifdef PROC_FS_21 + error |= proc_register(proc_net, &ipsec_eroute); + error |= proc_register(proc_net, &ipsec_spi); + error |= proc_register(proc_net, &ipsec_spigrp); + error |= proc_register(proc_net, &ipsec_tncfg); + error |= proc_register(proc_net, &ipsec_version); +# ifdef CONFIG_IPSEC_DEBUG + error |= proc_register(proc_net, &ipsec_klipsdebug); +# endif /* CONFIG_IPSEC_DEBUG */ +# else /* PROC_FS_21 */ + error |= proc_register_dynamic(&proc_net, &ipsec_eroute); + error |= proc_register_dynamic(&proc_net, &ipsec_spi); + error |= proc_register_dynamic(&proc_net, &ipsec_spigrp); + error |= proc_register_dynamic(&proc_net, &ipsec_tncfg); + error |= proc_register_dynamic(&proc_net, &ipsec_version); +# ifdef CONFIG_IPSEC_DEBUG + error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug); +# endif /* CONFIG_IPSEC_DEBUG */ +# endif /* PROC_FS_21 */ +# else /* !PROC_FS_2325 */ + /* create /proc/net/ipsec */ +#if 0 + proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net); + if(proc_net_ipsec_dir == NULL) { + error |= 1; + } else{ + error |= proc_register(); + } +#endif + + proc_net_create ("ipsec_eroute", 0, ipsec_eroute_get_info); + proc_net_create ("ipsec_spi", 0, ipsec_spi_get_info); + proc_net_create ("ipsec_spigrp", 0, ipsec_spigrp_get_info); + proc_net_create ("ipsec_tncfg", 0, ipsec_tncfg_get_info); + proc_net_create ("ipsec_version", 0, ipsec_version_get_info); +# ifdef CONFIG_IPSEC_DEBUG + proc_net_create ("ipsec_klipsdebug", 0, ipsec_klipsdebug_get_info); +# endif /* CONFIG_IPSEC_DEBUG */ +# endif /* !PROC_FS_2325 */ +#endif /* CONFIG_PROC_FS */ + + return error; +} + +void +ipsec_proc_cleanup() +{ +#ifdef CONFIG_PROC_FS +# ifndef PROC_FS_2325 +# ifdef CONFIG_IPSEC_DEBUG + if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0) + printk("klips_debug:ipsec_cleanup: " + "cannot unregister /proc/net/ipsec_klipsdebug\n"); +# endif /* CONFIG_IPSEC_DEBUG */ + if (proc_net_unregister(ipsec_version.low_ino) != 0) + printk("klips_debug:ipsec_cleanup: " + "cannot unregister /proc/net/ipsec_version\n"); + if (proc_net_unregister(ipsec_eroute.low_ino) != 0) + printk("klips_debug:ipsec_cleanup: " + "cannot unregister /proc/net/ipsec_eroute\n"); + if (proc_net_unregister(ipsec_spi.low_ino) != 0) + printk("klips_debug:ipsec_cleanup: " + "cannot unregister /proc/net/ipsec_spi\n"); + if (proc_net_unregister(ipsec_spigrp.low_ino) != 0) + printk("klips_debug:ipsec_cleanup: " + "cannot unregister /proc/net/ipsec_spigrp\n"); + if (proc_net_unregister(ipsec_tncfg.low_ino) != 0) + printk("klips_debug:ipsec_cleanup: " + "cannot unregister /proc/net/ipsec_tncfg\n"); +# else /* !PROC_FS_2325 */ +# ifdef CONFIG_IPSEC_DEBUG + proc_net_remove ("ipsec_klipsdebug"); +# endif /* CONFIG_IPSEC_DEBUG */ + proc_net_remove ("ipsec_eroute"); + proc_net_remove ("ipsec_spi"); + proc_net_remove ("ipsec_spigrp"); + proc_net_remove ("ipsec_tncfg"); + proc_net_remove ("ipsec_version"); +# endif /* !PROC_FS_2325 */ +#endif /* CONFIG_PROC_FS */ +} + +/* + * $Log: ipsec_proc.c,v $ + * Revision 1.8 2004/06/17 08:47:11 ken + * Remove bad /* string from comments + * + * Revision 1.7 2004/04/27 22:18:54 ken + * Backport of FreeS/WAN 2.06 ipsec_snprintf() and /proc/ipsec* fixes (ts/kb) + * + * Revision 1.6 2004/04/01 18:57:09 paul + * sprintf->ipsec_snprintf fixes by mcr,dhr,sam backported to openswan-1. This + * is needed to properly run on 2.4.25+ + * + * Revision 1.5 2003/12/12 13:09:40 ken + * Remove v from version output + * + * Revision 1.4 2003/12/04 03:01:17 ken + * Cast safely for ia64 + * + * Revision 1.3 2003/11/25 00:25:34 ken + * Change references to Openswan + * + * Revision 1.2 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.8 2002/01/29 17:17:55 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.7 2002/01/29 04:00:52 mcr + * more excise of kversions.h header. + * + * Revision 1.6 2002/01/29 02:13:17 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.5 2002/01/12 02:54:30 mcr + * beginnings of /proc/net/ipsec dir. + * + * Revision 1.4 2001/12/11 02:21:05 rgb + * Don't include module version here, fixing 2.2 compile bug. + * + * Revision 1.3 2001/12/05 07:19:44 rgb + * Fixed extraneous #include "version.c" bug causing modular KLIPS failure. + * + * Revision 1.2 2001/11/26 09:16:14 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.74 2001/11/22 05:44:11 henry + * new version stuff + * + * Revision 1.1.2.1 2001/09/25 02:19:40 mcr + * /proc manipulation code moved to new ipsec_proc.c + * + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_proto.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_proto.h --- linux-2.4.29/net/ipsec/ipsec_proto.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_proto.h Sun Jan 19 23:32:30 2003 @@ -0,0 +1,134 @@ +/* + * @(#) prototypes for FreeSWAN functions + * + * Copyright (C) 2001 Richard Guy Briggs + * and Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_proto.h,v 1.3 2003/01/19 22:32:30 ken Exp $ + * + */ + +#ifndef _IPSEC_PROTO_H_ + +#include "ipsec_param.h" + +/* + * This file is a kernel only file that declares prototypes for + * all intra-module function calls and global data structures. + * + * Include this file last. + * + */ + +/* ipsec_sa.c */ +extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD]; +extern spinlock_t tdb_lock; +extern int ipsec_sadb_init(void); + +extern struct ipsec_sa *ipsec_sa_getbyid(struct sa_id*); +extern /* void */ int ipsec_sa_del(struct ipsec_sa *); +extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *); +extern /* void */ int ipsec_sa_put(struct ipsec_sa *); + +extern int ipsec_sa_init(struct ipsec_sa *, struct encap_msghdr *); +extern int ipsec_sadb_cleanup(__u8); +extern int ipsec_sa_wipe(struct ipsec_sa *); + +/* debug declarations */ + +/* ipsec_proc.c */ +extern int ipsec_proc_init(void); +extern void ipsec_proc_cleanup(void); + +/* ipsec_radij.c */ +extern int ipsec_makeroute(struct sockaddr_encap *ea, + struct sockaddr_encap *em, + struct sa_id said, + uint32_t pid, + struct sk_buff *skb, + struct ident *ident_s, + struct ident *ident_d); + +extern int ipsec_breakroute(struct sockaddr_encap *ea, + struct sockaddr_encap *em, + struct sk_buff **first, + struct sk_buff **last); + +int ipsec_radijinit(void); +int ipsec_cleareroutes(void); +int ipsec_radijcleanup(void); + +/* ipsec_life.c */ +extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64, + const char *lifename, + const char *saname, + enum ipsec_life_type ilt, + enum ipsec_direction idir, + struct ipsec_sa *ips); + + +extern int ipsec_lifetime_format(char *buffer, + int buflen, + char *lifename, + enum ipsec_life_type timebaselife, + struct ipsec_lifetime64 *lifetime); + +extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime, + __u64 newvalue); + +extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime, + __u64 newvalue); + + + + +#ifdef CONFIG_IPSEC_DEBUG + +extern int debug_xform; +extern int debug_eroute; +extern int debug_spi; + +#endif /* CONFIG_IPSEC_DEBUG */ + + + + +#define _IPSEC_PROTO_H +#endif /* _IPSEC_PROTO_H_ */ + +/* + * $Log: ipsec_proto.h,v $ + * Revision 1.3 2003/01/19 22:32:30 ken + * X.509 0.9.19 -> 0.9.20 + * + * Revision 1.2 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.2 2001/11/26 09:16:15 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.1.2.1 2001/09/25 02:21:01 mcr + * ipsec_proto.h created to keep prototypes rather than deal with + * cyclic dependancies of structures and prototypes in .h files. + * + * + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ + diff -urN linux-2.4.29/net/ipsec/ipsec_radij.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_radij.c --- linux-2.4.29/net/ipsec/ipsec_radij.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_radij.c Thu Jun 17 10:47:11 2004 @@ -0,0 +1,822 @@ +/* + * Interface between the IPSEC code and the radix (radij) tree code + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_radij.c,v 1.7 2004/06/17 08:47:11 ken Exp $ + */ + +#include +#include +#include /* printk() */ + +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, struct net_device_stats and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include +#include +#ifdef SPINLOCK +# ifdef SPINLOCK_23 +# include /* *lock* */ +# else /* 23_SPINLOCK */ +# include /* *lock* */ +# endif /* 23_SPINLOCK */ +#endif /* SPINLOCK */ +#ifdef NET_21 +# include +# include +#endif +#include +#include + +#include "ipsec_eroute.h" +#include "ipsec_sa.h" + +#include "radij.h" +#include "ipsec_encap.h" +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_tunnel.h" /* struct ipsecpriv */ +#include "ipsec_xform.h" + +#include +#include + +#include "ipsec_proto.h" + +#ifdef CONFIG_IPSEC_DEBUG +int debug_radij = 0; +#endif /* CONFIG_IPSEC_DEBUG */ + +struct radij_node_head *rnh = NULL; +#ifdef SPINLOCK +spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED; +#else /* SPINLOCK */ +spinlock_t eroute_lock; +#endif /* SPINLOCK */ + +int +ipsec_radijinit(void) +{ + maj_keylen = sizeof (struct sockaddr_encap); + + rj_init(); + + if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */ + return -1; + return 0; +} + +int +ipsec_radijcleanup(void) +{ + int error; + + spin_lock_bh(&eroute_lock); + + error = radijcleanup(); + + spin_unlock_bh(&eroute_lock); + + return error; +} + +int +ipsec_cleareroutes(void) +{ + int error; + + spin_lock_bh(&eroute_lock); + + error = radijcleartree(); + + spin_unlock_bh(&eroute_lock); + + return error; +} + +int +ipsec_breakroute(struct sockaddr_encap *eaddr, + struct sockaddr_encap *emask, + struct sk_buff **first, + struct sk_buff **last) +{ + struct eroute *ro; + struct radij_node *rn; + int error; +#ifdef CONFIG_IPSEC_DEBUG + if (debug_eroute) { + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; + + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); + KLIPS_PRINT(debug_eroute, + "klips_debug:ipsec_breakroute: " + "attempting to delete eroute for %s:%d->%s:%d %d\n", + buf1, ntohs(eaddr->sen_sport), + buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto); + } +#endif /* CONFIG_IPSEC_DEBUG */ + + spin_lock_bh(&eroute_lock); + + if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) { + spin_unlock_bh(&eroute_lock); + KLIPS_PRINT(debug_eroute, + "klips_debug:ipsec_breakroute: " + "node not found, eroute delete failed.\n"); + return error; + } + + spin_unlock_bh(&eroute_lock); + + ro = (struct eroute *)rn; + + KLIPS_PRINT(debug_eroute, + "klips_debug:ipsec_breakroute: " + "deleted eroute=%p, ident=%p->%p, first=%p, last=%p\n", + ro, + ro->er_ident_s.data, + ro->er_ident_d.data, + ro->er_first, + ro->er_last); + + if (ro->er_ident_s.data != NULL) { + kfree(ro->er_ident_s.data); + } + if (ro->er_ident_d.data != NULL) { + kfree(ro->er_ident_d.data); + } + if (ro->er_first != NULL) { +#if 0 + struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats); + stats->tx_dropped--; +#endif + *first = ro->er_first; + } + if (ro->er_last != NULL) { +#if 0 + struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats); + stats->tx_dropped--; +#endif + *last = ro->er_last; + } + + if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT)) + panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n"); + memset((caddr_t)rn, 0, sizeof (struct eroute)); + kfree(rn); + + return 0; +} + +int +ipsec_makeroute(struct sockaddr_encap *eaddr, + struct sockaddr_encap *emask, + struct sa_id said, + uint32_t pid, + struct sk_buff *skb, + struct ident *ident_s, + struct ident *ident_d) +{ + struct eroute *retrt; + int error; + char sa[SATOA_BUF]; + size_t sa_len; + +#ifdef CONFIG_IPSEC_DEBUG + if (debug_eroute) { + { + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); + sa_len = satoa(said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_eroute, + "klips_debug:ipsec_makeroute: " + "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n", + (unsigned long) sizeof(struct eroute), + buf1, + buf2, + sa_len ? sa : " (error)", + pid, + skb, + (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"), + (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL")); + } + { + char buf1[sizeof(struct sockaddr_encap)*2 + 1], + buf2[sizeof(struct sockaddr_encap)*2 + 1]; + int i; + unsigned char *b1 = buf1, + *b2 = buf2, + *ea = (unsigned char *)eaddr, + *em = (unsigned char *)emask; + + for (i=0; ier_eaddr = *eaddr; + retrt->er_emask = *emask; + retrt->er_said = said; + retrt->er_pid = pid; + retrt->er_count = 0; + retrt->er_lasttime = jiffies/HZ; + rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr); + + if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) { + int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); + + retrt->er_ident_s.type = ident_s->type; + retrt->er_ident_s.id = ident_s->id; + retrt->er_ident_s.len = ident_s->len; + if(data_len) { + if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) { + kfree(retrt); + printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len); + return ENOMEM; + } + memcpy(retrt->er_ident_s.data, ident_s->data, data_len); + } else { + retrt->er_ident_s.data = NULL; + } + } + + if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) { + int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); + + retrt->er_ident_d.type = ident_d->type; + retrt->er_ident_d.id = ident_d->id; + retrt->er_ident_d.len = ident_d->len; + if(data_len) { + if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) { + if (retrt->er_ident_s.data) + kfree(retrt->er_ident_s.data); + kfree(retrt); + printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len); + return ENOMEM; + } + memcpy(retrt->er_ident_d.data, ident_d->data, data_len); + } else { + retrt->er_ident_d.data = NULL; + } + } + retrt->er_first = skb; + retrt->er_last = NULL; + + spin_lock_bh(&eroute_lock); + + error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask), + rnh, retrt->er_rjt.rd_nodes); + + spin_unlock_bh(&eroute_lock); + + if(error) { + sa_len = satoa(said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_eroute, + "klips_debug:ipsec_makeroute: " + "rj_addroute not able to insert eroute for SA:%s\n", + sa_len ? sa : " (error)"); + if (retrt->er_ident_s.data) + kfree(retrt->er_ident_s.data); + if (retrt->er_ident_d.data) + kfree(retrt->er_ident_d.data); + + kfree(retrt); + + return error; + } + +#ifdef CONFIG_IPSEC_DEBUG + if (debug_eroute && 0) { + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; + +/* + subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1)); + subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2)); +*/ + subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1)); + subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2)); + sa_len = satoa(retrt->er_said, 0, sa, SATOA_BUF); + + KLIPS_PRINT(debug_eroute, + "klips_debug:ipsec_makeroute: " + "pid=%05d " + "count=%10d " + "lasttime=%6d " + "%-18s -> %-18s => %s\n", + retrt->er_pid, + retrt->er_count, + (int)(jiffies/HZ - retrt->er_lasttime), + buf1, + buf2, + sa_len ? sa : " (error)"); + } +#endif /* CONFIG_IPSEC_DEBUG */ + KLIPS_PRINT(debug_eroute, + "klips_debug:ipsec_makeroute: " + "succeeded, I think...\n"); + return 0; +} + +struct eroute * +ipsec_findroute(struct sockaddr_encap *eaddr) +{ + struct radij_node *rn; +#ifdef CONFIG_IPSEC_DEBUG + char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF]; + + if (debug_radij & DB_RJ_FINDROUTE) { + addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1)); + addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2)); + KLIPS_PRINT(debug_eroute, + "klips_debug:ipsec_findroute: " + "%s:%d->%s:%d %d\n", + buf1, ntohs(eaddr->sen_sport), + buf2, ntohs(eaddr->sen_dport), + eaddr->sen_proto); + } +#endif /* CONFIG_IPSEC_DEBUG */ + rn = rj_match((caddr_t)eaddr, rnh); + if(rn) { + KLIPS_PRINT(debug_eroute, + "klips_debug:ipsec_findroute: " + "found, points to proto=%d, spi=%x, dst=%x.\n", + ((struct eroute*)rn)->er_said.proto, + ntohl(((struct eroute*)rn)->er_said.spi), + ntohl(((struct eroute*)rn)->er_said.dst.s_addr)); + } + return (struct eroute *)rn; +} + +#ifdef CONFIG_PROC_FS +/* ipsec_rj_walker_procprint: print one line of eroute table output. + * + * Theoretical BUG: if w->length is less than the length + * of some line we should produce, that line will never + * be finished. In effect, the "file" will stop part way + * through that line. + */ +int +ipsec_rj_walker_procprint(struct radij_node *rn, void *w0) +{ + struct eroute *ro = (struct eroute *)rn; + struct rjtentry *rd = (struct rjtentry *)rn; + struct wsbuf *w = (struct wsbuf *)w0; + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; + char sa[SATOA_BUF]; + size_t sa_len, buf_len; + struct sockaddr_encap *key, *mask; + + KLIPS_PRINT(debug_radij, + "klips_debug:ipsec_rj_walker_procprint: " + "rn=%p, w0=%p\n", + rn, + w0); + + if (rn->rj_b >= 0) { + return 0; + } + + key = rd_key(rd); + mask = rd_mask(rd); + + if (key == NULL || mask == NULL) { + return 0; + } + + buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1)); + sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport)); + buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2)); + sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport)); + sa_len = satoa(ro->er_said, 0, sa, SATOA_BUF); + w->len += ipsec_snprintf(w->buffer + w->len, + w->length - w->len, + "%-10d " + "%-18s -> %-18s => %s:%d\n", + ro->er_count, + buf1, + buf2, + sa_len ? sa : " (error)", + key->sen_proto); + + { + /* snprintf can only fill the last character with NUL + * so the maximum useful character is w->length-1. + * However, if w->length == 0, we cannot go back. + * (w->length surely cannot be negative.) + */ + int max_content = w->length > 0? w->length-1 : 0; + + if (w->len >= max_content) { + /* we've done all that can fit -- stop treewalking */ + w->len = max_content; /* truncate crap */ + return -ENOBUFS; + } else { + const off_t pos = w->begin + w->len; /* file position of end of what we've generated */ + + if (pos <= w->offset) { + /* all is before first interesting character: + * discard, but note where we are. + */ + w->len = 0; + w->begin = pos; + } + return 0; + } + } +} +#endif /* CONFIG_PROC_FS */ + +int +ipsec_rj_walker_delete(struct radij_node *rn, void *w0) +{ + struct eroute *ro; + struct rjtentry *rd = (struct rjtentry *)rn; + struct radij_node *rn2; + int error; + struct sockaddr_encap *key, *mask; + + key = rd_key(rd); + mask = rd_mask(rd); + + if(!key || !mask) { + return -ENODATA; + } +#ifdef CONFIG_IPSEC_DEBUG + if(debug_radij) { + char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF]; + + subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1)); + subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2)); + KLIPS_PRINT(debug_radij, + "klips_debug:ipsec_rj_walker_delete: " + "deleting: %s -> %s\n", + buf1, + buf2); + } +#endif /* CONFIG_IPSEC_DEBUG */ + + if((error = rj_delete(key, mask, rnh, &rn2))) { + KLIPS_PRINT(debug_radij, + "klips_debug:ipsec_rj_walker_delete: " + "rj_delete failed with error=%d.\n", error); + return error; + } + + if(rn2 != rn) { + printk("klips_debug:ipsec_rj_walker_delete: " + "tried to delete a different node?!? This should never happen!\n"); + } + + ro = (struct eroute *)rn; + + if (ro->er_ident_s.data) + kfree(ro->er_ident_s.data); + if (ro->er_ident_d.data) + kfree(ro->er_ident_d.data); + + memset((caddr_t)rn, 0, sizeof (struct eroute)); + kfree(rn); + + return 0; +} + +/* + * $Log: ipsec_radij.c,v $ + * Revision 1.7 2004/06/17 08:47:11 ken + * Remove bad /* string from comments + * + * Revision 1.6 2004/04/27 22:18:54 ken + * Backport of FreeS/WAN 2.06 ipsec_snprintf() and /proc/ipsec* fixes (ts/kb) + * + * Revision 1.5 2004/04/01 18:57:09 paul + * sprintf->ipsec_snprintf fixes by mcr,dhr,sam backported to openswan-1. This + * is needed to properly run on 2.4.25+ + * + * Revision 1.4 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.3 2003/01/19 22:32:30 ken + * X.509 0.9.19 -> 0.9.20 + * + * Revision 1.2 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.60 2002/02/19 23:59:45 rgb + * Removed redundant compiler directives. + * + * Revision 1.59 2002/02/06 04:13:47 mcr + * missing #ifdef CONFIG_IPSEC_DEBUG. + * + * Revision 1.58 2002/01/29 17:17:56 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.57 2002/01/29 04:00:52 mcr + * more excise of kversions.h header. + * + * Revision 1.56 2002/01/29 02:13:17 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.55 2001/11/26 09:23:48 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.53.2.1 2001/09/25 02:26:32 mcr + * headers adjusted for new usage. + * + * Revision 1.54 2001/10/18 04:45:20 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/freeswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.53 2001/09/19 17:19:40 rgb + * Debug output bugfix for NetCelo's PF_KEY ident patch. + * + * Revision 1.52 2001/09/19 16:33:37 rgb + * Temporarily disable ident fields to /proc/net/ipsec_eroute. + * + * Revision 1.51 2001/09/15 16:24:04 rgb + * Re-inject first and last HOLD packet when an eroute REPLACE is done. + * + * Revision 1.50 2001/09/14 16:58:36 rgb + * Added support for storing the first and last packets through a HOLD. + * + * Revision 1.49 2001/09/08 21:13:32 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.48 2001/06/15 04:12:56 rgb + * Fixed kernel memory allocation error return code polarity bug. + * + * Revision 1.47 2001/06/14 19:35:09 rgb + * Update copyright date. + * + * Revision 1.46 2001/06/08 08:47:18 rgb + * Fixed for debug disabled. + * + * Revision 1.45 2001/05/27 06:12:11 rgb + * Added structures for pid, packet count and last access time to eroute. + * Added packet count to beginning of /proc/net/ipsec_eroute. + * + * Revision 1.44 2001/05/03 19:41:01 rgb + * Initialise error return variable. + * Use more appropriate return value for ipsec_rj_walker_delete(). + * + * Revision 1.43 2001/02/27 22:24:54 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.42 2001/02/27 06:21:57 rgb + * Added findroute success instrumentation. + * + * Revision 1.41 2000/11/06 04:32:08 rgb + * Ditched spin_lock_irqsave in favour of spin_lock_bh. + * + * Revision 1.40 2000/09/08 19:12:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.39 2000/08/30 05:25:20 rgb + * Correct debug text in ipsec_breakroute() from incorrect + * "ipsec_callback". + * + * Revision 1.38 2000/07/28 14:58:31 rgb + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. + * + * Revision 1.37 2000/03/16 14:02:50 rgb + * Fixed debug scope to enable compilation with debug off. + * + * Revision 1.36 2000/01/21 06:14:46 rgb + * Added debugging text to ipsec_rj_walker_delete(). + * Set return code to negative for consistency. + * + * Revision 1.35 1999/11/23 23:05:24 rgb + * Use provided macro ADDRTOA_BUF instead of hardcoded value. + * + * Revision 1.34 1999/11/18 04:13:56 rgb + * Replaced all kernel version macros to shorter, readable form. + * Added CONFIG_PROC_FS compiler directives in case it is shut off. + * + * Revision 1.33 1999/11/17 15:53:39 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.32 1999/10/26 13:58:33 rgb + * Put spinlock flags variable declaration outside the debug compiler + * directive to enable compilation with debug shut off. + * + * Revision 1.31 1999/10/15 22:13:29 rgb + * Clean out cruft. + * Align /proc/net/ipsec_eroute output for easier readability. + * Fix double linefeed in radij debug output. + * Fix double locking bug that locks up 2.0.36 but not 2.0.38. + * + * Revision 1.30 1999/10/08 18:37:33 rgb + * Fix end-of-line spacing to sate whining PHMs. + * + * Revision 1.29 1999/10/03 18:52:45 rgb + * Spinlock support for 2.0.xx. + * Dumb return code spin_unlock fix. + * + * Revision 1.28 1999/10/01 16:22:24 rgb + * Switch from assignment init. to functional init. of spinlocks. + * + * Revision 1.27 1999/10/01 15:44:53 rgb + * Move spinlock header include to 2.1> scope. + * + * Revision 1.26 1999/10/01 00:01:23 rgb + * Added eroute structure locking. + * + * Revision 1.25 1999/06/10 16:07:30 rgb + * Silence delete eroute on no debug. + * + * Revision 1.24 1999/05/09 03:25:36 rgb + * Fix bug introduced by 2.2 quick-and-dirty patch. + * + * Revision 1.23 1999/05/05 22:02:31 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.22 1999/04/29 15:17:23 rgb + * Add return values to init and cleanup functions. + * Add sanity checking for null pointer arguments. + * + * Revision 1.21 1999/04/11 00:28:58 henry + * GPL boilerplate + * + * Revision 1.20 1999/04/06 04:54:26 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.19 1999/02/17 16:50:35 rgb + * Clean out unused cruft. + * Consolidate for space and speed efficiency. + * Convert DEBUG_IPSEC to KLIPS_PRINT + * + * Revision 1.18 1999/01/22 06:22:06 rgb + * Cruft clean-out. + * 64-bit clean-up. + * + * Revision 1.17 1998/12/02 03:09:39 rgb + * Clean up debug printing conditionals to compile with debugging off. + * + * Revision 1.16 1998/12/01 13:49:39 rgb + * Wrap version info printing in debug switches. + * + * Revision 1.15 1998/11/30 13:22:54 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.14 1998/10/31 06:48:17 rgb + * Fixed up comments in #endif directives. + * + * Revision 1.13 1998/10/27 13:48:09 rgb + * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts. + * Fixed less(1) truncated output bug. + * Code clean-up. + * + * Revision 1.12 1998/10/25 02:41:36 rgb + * Change return type on ipsec_breakroute and ipsec_makeroute and add an + * argument to be able to transmit more infomation about errors. + * Fix cut-and-paste debug statement identifier. + * + * Revision 1.11 1998/10/22 06:45:39 rgb + * Cleaned up cruft. + * Convert to use satoa for printk. + * + * Revision 1.10 1998/10/19 14:44:28 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * + * Revision 1.9 1998/10/09 04:30:52 rgb + * Added 'klips_debug' prefix to all klips printk debug statements. + * Deleted old commented out cruft. + * + * Revision 1.8 1998/08/06 17:24:23 rgb + * Fix addrtoa return code bug from stale manpage advice preventing packets + * from being erouted. + * + * Revision 1.7 1998/08/06 07:44:59 rgb + * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that + * ended up in nothing being printed. + * + * Revision 1.6 1998/08/05 22:16:41 rgb + * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal. + * + * Revision 1.5 1998/07/29 20:38:44 rgb + * Debug and fix subnettoa and addrtoa output. + * + * Revision 1.4 1998/07/28 00:02:39 rgb + * Converting to exclusive use of addrtoa. + * Fix eroute delete. + * + * Revision 1.3 1998/07/14 18:21:26 rgb + * Add function to clear the eroute table. + * + * Revision 1.2 1998/06/23 02:59:14 rgb + * Added debugging output to eroute add/delete routines. + * + * Revision 1.9 1998/06/18 21:29:06 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid kernel + * build scripts happier in presence of symbolic links + * + * Revision 1.8 1998/06/05 02:32:26 rgb + * Fix spi ntoh kernel debug output. + * + * Revision 1.7 1998/05/25 20:30:37 rgb + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. + * + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and + * add ipsec_rj_walker_delete. + * + * Revision 1.6 1998/05/21 13:08:57 rgb + * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of + * information is available for printout. + * + * Revision 1.5 1998/05/18 21:35:55 rgb + * Clean up output for numerical consistency and readability. Zero freed + * eroute memory. + * + * Revision 1.4 1998/04/21 21:28:58 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.3 1998/04/14 17:30:39 rgb + * Fix up compiling errors for radij tree memory reclamation. + * + * Revision 1.2 1998/04/12 22:03:23 rgb + * Updated ESP-3DES-HMAC-MD5-96, + * ESP-DES-HMAC-MD5-96, + * AH-HMAC-MD5-96, + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository + * from old standards (RFC182[5-9] to new (as of March 1998) drafts. + * + * Fixed eroute references in /proc/net/ipsec*. + * + * Started to patch module unloading memory leaks in ipsec_netlink and + * radij tree unloading. + * + * Revision 1.1 1998/04/09 03:06:10 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:03 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_radij.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_radij.h --- linux-2.4.29/net/ipsec/ipsec_radij.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_radij.h Thu Jun 17 10:47:11 2004 @@ -0,0 +1,176 @@ +/* + * @(#) Definitions relevant to the IPSEC <> radij tree interfacing + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_radij.h,v 1.4 2004/06/17 08:47:11 ken Exp $ + */ + +#ifndef _IPSEC_RADIJ_H + +#include + +int ipsec_walk(char *); + +int ipsec_rj_walker_procprint(struct radij_node *, void *); +int ipsec_rj_walker_delete(struct radij_node *, void *); + +/* This structure is used to pass information between + * ipsec_eroute_get_info and ipsec_rj_walker_procprint + * (through rj_walktree) and between calls of ipsec_rj_walker_procprint. + */ +struct wsbuf +{ + /* from caller of ipsec_eroute_get_info: */ + char *const buffer; /* start of buffer provided */ + const int length; /* length of buffer provided */ + const off_t offset; /* file position of first character of interest */ + /* accumulated by ipsec_rj_walker_procprint: */ + int len; /* number of character filled into buffer */ + off_t begin; /* file position contained in buffer[0] (<=offset) */ +}; + +extern struct radij_node_head *rnh; +extern spinlock_t eroute_lock; + +struct eroute * ipsec_findroute(struct sockaddr_encap *); + +#define O1(x) (int)(((x)>>24)&0xff) +#define O2(x) (int)(((x)>>16)&0xff) +#define O3(x) (int)(((x)>>8)&0xff) +#define O4(x) (int)(((x))&0xff) + +#ifdef CONFIG_IPSEC_DEBUG +extern int debug_radij; +void rj_dumptrees(void); + +#define DB_RJ_DUMPTREES 0x0001 +#define DB_RJ_FINDROUTE 0x0002 +#endif /* CONFIG_IPSEC_DEBUG */ + +#define _IPSEC_RADIJ_H +#endif + +/* + * $Log: ipsec_radij.h,v $ + * Revision 1.4 2004/06/17 08:47:11 ken + * Remove bad /* string from comments + * + * Revision 1.3 2004/04/27 22:18:54 ken + * Backport of FreeS/WAN 2.06 ipsec_snprintf() and /proc/ipsec* fixes (ts/kb) + * + * Revision 1.2 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.17 2001/11/26 09:23:49 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.16.2.1 2001/09/25 02:21:17 mcr + * ipsec_proto.h created to keep prototypes rather than deal with + * cyclic dependancies of structures and prototypes in .h files. + * + * Revision 1.16 2001/09/15 16:24:04 rgb + * Re-inject first and last HOLD packet when an eroute REPLACE is done. + * + * Revision 1.15 2001/09/14 16:58:37 rgb + * Added support for storing the first and last packets through a HOLD. + * + * Revision 1.14 2001/09/08 21:13:32 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.13 2001/06/14 19:35:09 rgb + * Update copyright date. + * + * Revision 1.12 2001/05/27 06:12:11 rgb + * Added structures for pid, packet count and last access time to eroute. + * Added packet count to beginning of /proc/net/ipsec_eroute. + * + * Revision 1.11 2000/09/08 19:12:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.10 1999/11/17 15:53:39 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.9 1999/10/01 00:01:23 rgb + * Added eroute structure locking. + * + * Revision 1.8 1999/04/11 00:28:59 henry + * GPL boilerplate + * + * Revision 1.7 1999/04/06 04:54:26 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.6 1999/01/22 06:23:26 rgb + * Cruft clean-out. + * + * Revision 1.5 1998/10/25 02:42:08 rgb + * Change return type on ipsec_breakroute and ipsec_makeroute and add an + * argument to be able to transmit more infomation about errors. + * + * Revision 1.4 1998/10/19 14:44:29 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * + * Revision 1.3 1998/07/28 00:03:31 rgb + * Comment out temporary inet_nto4u() kluge. + * + * Revision 1.2 1998/07/14 18:22:00 rgb + * Add function to clear the eroute table. + * + * Revision 1.1 1998/06/18 21:27:49 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.5 1998/05/25 20:30:38 rgb + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. + * + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and + * add ipsec_rj_walker_delete. + * + * Revision 1.4 1998/05/21 13:02:56 rgb + * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k + * limit fix. + * + * Revision 1.3 1998/04/21 21:29:09 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.2 1998/04/14 17:30:39 rgb + * Fix up compiling errors for radij tree memory reclamation. + * + * Revision 1.1 1998/04/09 03:06:10 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:04 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_rcv.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_rcv.c --- linux-2.4.29/net/ipsec/ipsec_rcv.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_rcv.c Thu Dec 4 04:04:38 2003 @@ -0,0 +1,2605 @@ +/* + * receive code + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +char ipsec_rcv_c_version[] = "RCSID $Id: ipsec_rcv.c,v 1.18 2003/12/04 03:04:38 ken Exp $"; + +#include +#include + +#define __NO_VERSION__ +#include +#include /* printk() */ + +#define IPSEC_KLIPS1_COMPAT 1 +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include +#include +#ifdef SPINLOCK +# ifdef SPINLOCK_23 +# include /* *lock* */ +# else /* SPINLOCK_23 */ +# include /* *lock* */ +# endif /* SPINLOCK_23 */ +#endif /* SPINLOCK */ +#ifdef NET_21 +# include +# include +# define proto_priv cb +#endif /* NET21 */ +#include +#include + +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_sa.h" + +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_xform.h" +#include "ipsec_tunnel.h" +#include "ipsec_rcv.h" +#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) +# include "ipsec_ah.h" +#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */ +#ifdef CONFIG_IPSEC_ESP +# include "ipsec_esp.h" +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_IPCOMP +# include "ipcomp.h" +#endif /* CONFIG_IPSEC_COMP */ + +#include +#include + +#include "ipsec_proto.h" + +#include "ipsec_alg.h" + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL +#include +#endif + +#ifdef CONFIG_IPSEC_DEBUG +int debug_ah = 0; +int debug_esp = 0; +int debug_rcv = 0; +#endif /* CONFIG_IPSEC_DEBUG */ + +int sysctl_ipsec_inbound_policy_check = 1; + +#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) +__u32 zeroes[AH_AMAX]; +#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */ + +/* + * Check-replay-window routine, adapted from the original + * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt + * + * This is a routine that implements a 64 packet window. This is intend- + * ed on being an implementation sample. + */ + +DEBUG_NO_STATIC int +ipsec_checkreplaywindow(struct ipsec_sa*tdbp, __u32 seq) +{ + __u32 diff; + + if (tdbp->tdb_replaywin == 0) /* replay shut off */ + return 1; + if (seq == 0) + return 0; /* first == 0 or wrapped */ + + /* new larger sequence number */ + if (seq > tdbp->tdb_replaywin_lastseq) { + return 1; /* larger is good */ + } + diff = tdbp->tdb_replaywin_lastseq - seq; + + /* too old or wrapped */ /* if wrapped, kill off SA? */ + if (diff >= tdbp->tdb_replaywin) { + return 0; + } + /* this packet already seen */ + if (tdbp->tdb_replaywin_bitmap & (1 << diff)) + return 0; + return 1; /* out of order but good */ +} + +DEBUG_NO_STATIC int +ipsec_updatereplaywindow(struct ipsec_sa*tdbp, __u32 seq) +{ + __u32 diff; + + if (tdbp->tdb_replaywin == 0) /* replay shut off */ + return 1; + if (seq == 0) + return 0; /* first == 0 or wrapped */ + + /* new larger sequence number */ + if (seq > tdbp->tdb_replaywin_lastseq) { + diff = seq - tdbp->tdb_replaywin_lastseq; + + /* In win, set bit for this pkt */ + if (diff < tdbp->tdb_replaywin) + tdbp->tdb_replaywin_bitmap = + (tdbp->tdb_replaywin_bitmap << diff) | 1; + else + /* This packet has way larger seq num */ + tdbp->tdb_replaywin_bitmap = 1; + + if(seq - tdbp->tdb_replaywin_lastseq - 1 > tdbp->tdb_replaywin_maxdiff) { + tdbp->tdb_replaywin_maxdiff = seq - tdbp->tdb_replaywin_lastseq - 1; + } + tdbp->tdb_replaywin_lastseq = seq; + return 1; /* larger is good */ + } + diff = tdbp->tdb_replaywin_lastseq - seq; + + /* too old or wrapped */ /* if wrapped, kill off SA? */ + if (diff >= tdbp->tdb_replaywin) { +/* + if(seq < 0.25*max && tdbp->tdb_replaywin_lastseq > 0.75*max) { + deltdbchain(tdbp); + } +*/ + return 0; + } + /* this packet already seen */ + if (tdbp->tdb_replaywin_bitmap & (1 << diff)) + return 0; + tdbp->tdb_replaywin_bitmap |= (1 << diff); /* mark as seen */ + return 1; /* out of order but good */ +} + +int +#ifdef PROTO_HANDLER_SINGLE_PARM +ipsec_rcv(struct sk_buff *skb) +#else /* PROTO_HANDLER_SINGLE_PARM */ +#ifdef NET_21 +ipsec_rcv(struct sk_buff *skb, unsigned short xlen) +#else /* NET_21 */ +ipsec_rcv(struct sk_buff *skb, struct device *dev, struct options *opt, + __u32 daddr_unused, unsigned short xlen, __u32 saddr, + int redo, struct inet_protocol *protocol) +#endif /* NET_21 */ +#endif /* PROTO_HANDLER_SINGLE_PARM */ +{ +#ifdef NET_21 +#ifdef CONFIG_IPSEC_DEBUG + struct device *dev = skb->dev; +#endif /* CONFIG_IPSEC_DEBUG */ +#endif /* NET_21 */ + unsigned char protoc; + struct iphdr *ipp; + int authlen = 0; +#ifdef CONFIG_IPSEC_ESP + struct esp *espp = NULL; + int esphlen = 0; +#ifdef CONFIG_IPSEC_ENC_3DES + __u32 iv[ESP_IV_MAXSZ_INT]; +#endif /* !CONFIG_IPSEC_ENC_3DES */ +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_AH + struct ah *ahp = NULL; + int ahhlen = 0; +#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) + struct iphdr ipo; +#endif +#endif /* CONFIG_IPSEC_AH */ + unsigned char *authenticator = NULL; + union { + MD5_CTX md5; + SHA1_CTX sha1; + } tctx; + __u8 hash[AH_AMAX]; +#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) +#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */ +#ifdef CONFIG_IPSEC_IPCOMP + struct ipcomphdr*compp = NULL; +#endif /* CONFIG_IPSEC_IPCOMP */ + + int hard_header_len; + int iphlen; + unsigned char *dat; + struct ipsec_sa *tdbp = NULL; + struct sa_id said; + struct net_device_stats *stats = NULL; /* This device's statistics */ + struct device *ipsecdev = NULL, *prvdev; + struct ipsecpriv *prv; + char name[9]; + char sa[SATOA_BUF]; + size_t sa_len; + char ipaddr_txt[ADDRTOA_BUF]; + int i; + struct in_addr ipaddr; + __u8 next_header = 0; + __u8 proto; + +#ifdef CONFIG_IPSEC_ESP + int pad = 0, padlen; +#endif /* CONFIG_IPSEC_ESP */ + int ilen; /* content to be decrypted/authenticated */ + int len; /* packet length */ + int replay = 0; /* replay value in AH or ESP packet */ + __u8 *idat; /* pointer to content to be decrypted/authenticated */ + struct ipsec_sa* tdbprev = NULL; /* previous SA from outside of packet */ + struct ipsec_sa* tdbnext = NULL; /* next SA towards inside of packet */ +#ifdef INBOUND_POLICY_CHECK_eroute + struct sockaddr_encap matcher; /* eroute search key */ + struct eroute *er; + struct ipsec_sa* policy_tdb = NULL; + struct sa_id policy_said; + struct sockaddr_encap policy_eaddr; + struct sockaddr_encap policy_emask; +#endif /* INBOUND_POLICY_CHECK_eroute */ +#ifdef CONFIG_IPSEC_ALG + struct ipsec_alg_enc *ixt_e=NULL; + struct ipsec_alg_auth *ixt_a=NULL; +#endif /* CONFIG_IPSEC_ALG */ + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + __u16 natt_len = 0, natt_sport = 0, natt_dport = 0; + __u8 natt_type = 0; +#endif + + /* Don't unlink in the middle of a turnaround */ + MOD_INC_USE_COUNT; + + if (skb == NULL) { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NULL skb passed in.\n"); + goto rcvleave; + } + + if (skb->data == NULL) { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NULL skb->data passed in, packet is bogus, dropping.\n"); + goto rcvleave; + } + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) { + /** + * Packet comes from udp_queue_rcv_skb so it is already defrag, + * checksum verified, ... (ie safe to use) + * + * If the packet is not for us, return -1 and udp_queue_rcv_skb + * will continue to handle it (do not kfree skb !!). + */ + struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp); + struct iphdr *ip = (struct iphdr *)skb->nh.iph; + struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl); + __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr); + __u32 *udpdata32 = (__u32 *)udpdata; + + natt_sport = ntohs(udp->source); + natt_dport = ntohs(udp->dest); + + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "suspected ESPinUDP packet (NAT-Traversal) [%d].\n", + tp->esp_in_udp); + KLIPS_IP_PRINT(debug_rcv, ip); + + if (udpdata < skb->tail) { + unsigned int len = skb->tail - udpdata; + if ((len==1) && (udpdata[0]==0xff)) { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + /* not IPv6 compliant message */ + "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr)); + goto rcvleave; + } + else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) && + (len > (2*sizeof(__u32) + sizeof(struct esp))) && + (udpdata32[0]==0) && (udpdata32[1]==0) ) { + /* ESP Packet with Non-IKE header */ + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "ESPinUDP pkt with Non-IKE - spi=0x%x\n", + udpdata32[2]); + natt_type = ESPINUDP_WITH_NON_IKE; + natt_len = sizeof(struct udphdr)+(2*sizeof(__u32)); + } + else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) && + (len > sizeof(struct esp)) && + (udpdata32[0]!=0) ) { + /* ESP Packet without Non-ESP header */ + natt_type = ESPINUDP_WITH_NON_ESP; + natt_len = sizeof(struct udphdr); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "ESPinUDP pkt without Non-ESP - spi=0x%x\n", + udpdata32[0]); + } + else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "IKE packet - not handled here\n"); + MOD_DEC_USE_COUNT; + return -1; + } + } + else { + MOD_DEC_USE_COUNT; + return -1; + } + } +#endif + +#ifdef IPH_is_SKB_PULLED + /* In Linux 2.4.4, the IP header has been skb_pull()ed before the + packet is passed to us. So we'll skb_push() to get back to it. */ + if (skb->data == skb->h.raw) { + skb_push(skb, skb->h.raw - skb->nh.raw); + } +#endif /* IPH_is_SKB_PULLED */ + + ipp = (struct iphdr *)skb->data; + iphlen = ipp->ihl << 2; + /* dev->hard_header_len is unreliable and should not be used */ + hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0; + if((hard_header_len < 0) || (hard_header_len > skb_headroom(skb))) + hard_header_len = 0; + +#ifdef NET_21 + /* if skb was cloned (most likely due to a packet sniffer such as + tcpdump being momentarily attached to the interface), make + a copy of our own to modify */ + if(skb_cloned(skb)) { + /* include any mac header while copying.. */ + if(skb_headroom(skb) < hard_header_len) { + printk(KERN_WARNING "klips_error:ipsec_rcv: " + "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n", + hard_header_len, + skb_headroom(skb)); + goto rcvleave; + } + skb_push(skb, hard_header_len); + if +#ifdef SKB_COW_NEW + (skb_cow(skb, skb_headroom(skb)) != 0) +#else /* SKB_COW_NEW */ + ((skb = skb_cow(skb, skb_headroom(skb))) == NULL) +#endif /* SKB_COW_NEW */ + { + goto rcvleave; + } + if(skb->len < hard_header_len) { + printk(KERN_WARNING "klips_error:ipsec_rcv: " + "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n", + hard_header_len, + skb->len); + goto rcvleave; + } + skb_pull(skb, hard_header_len); + } + +#endif /* NET_21 */ + +#if IP_FRAGMENT_LINEARIZE + /* In Linux 2.4.4, we may have to reassemble fragments. They are + not assembled automatically to save TCP from having to copy + twice. + */ + if (skb_is_nonlinear(skb)) { + if (skb_linearize(skb, GFP_ATOMIC) != 0) { + goto rcvleave; + } + } + ipp = (struct iphdr *)skb->nh.iph; + iphlen = ipp->ihl << 2; +#endif + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if (natt_len) { + /** + * Now, we are sure packet is ESPinUDP. Remove natt_len bytes from + * packet and modify protocol to ESP. + */ + if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph) && + ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head)) { + unsigned int _len = (unsigned char *)skb->data - + (unsigned char *)skb->nh.iph; + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n", + _len); + skb_push(skb, _len); + } + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "removing %d bytes from ESPinUDP packet\n", natt_len); + ipp = (struct iphdr *)skb->data; + iphlen = ipp->ihl << 2; + ipp->tot_len = htons(ntohs(ipp->tot_len) - natt_len); + if (skb->len < iphlen + natt_len) { + printk(KERN_WARNING + "klips_error:ipsec_rcv: " + "ESPinUDP packet is too small (%d < %d+%d). " + "This should never happen, please report.\n", + (int)(skb->len), iphlen, natt_len); + goto rcvleave; + } + memmove(skb->data + natt_len, skb->data, iphlen); + skb_pull(skb, natt_len); + + /* update nh.iph */ + ipp = skb->nh.iph = (struct iphdr *)skb->data; + + /* modify protocol */ + ipp->protocol = IPPROTO_ESP; + + skb->sk = NULL; + + KLIPS_IP_PRINT(debug_rcv, skb->nh.iph); + } +#endif + + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "<<< Info -- "); + KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ", + skb->dev->name ? skb->dev->name : "NULL"); + KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ", + dev->name ? dev->name : "NULL"); + KLIPS_PRINTMORE(debug_rcv, "\n"); + + KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)), + "klips_debug:ipsec_rcv: " + "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n", + skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL", + dev ? (dev->name ? dev->name : "NULL") : "NULL"); + + protoc = ipp->protocol; +#ifndef NET_21 + if((!protocol) || (protocol->protocol != protoc)) { + KLIPS_PRINT(debug_rcv & DB_RX_TDB, + "klips_debug:ipsec_rcv: " + "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n"); + } +#endif /* !NET_21 */ + + if( (protoc != IPPROTO_AH) && +#ifdef CONFIG_IPSEC_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER + (protoc != IPPROTO_COMP) && +#endif /* CONFIG_IPSEC_IPCOMP */ + (protoc != IPPROTO_ESP) ) { + KLIPS_PRINT(debug_rcv & DB_RX_TDB, + "klips_debug:ipsec_rcv: Why the hell is someone " + "passing me a non-ipsec protocol = %d packet? -- dropped.\n", + protoc); + goto rcvleave; + } + + if(skb->dev) { + for(i = 0; i < IPSEC_NUM_IF; i++) { + sprintf(name, "ipsec%d", i); + if(!strcmp(name, skb->dev->name)) { + prv = (struct ipsecpriv *)(skb->dev->priv); + if(prv) { + stats = (struct net_device_stats *) &(prv->mystats); + } + ipsecdev = skb->dev; + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n"); + break; + } + if((ipsecdev = ipsec_dev_get(name)) == NULL) { + KLIPS_PRINT(debug_rcv, + "klips_error:ipsec_rcv: " + "device %s does not exist\n", + name); + } + prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL; + prvdev = prv ? (struct device *)(prv->dev) : NULL; + +#if 0 + KLIPS_PRINT(debug_rcv && prvdev, + "klips_debug:ipsec_rcv: " + "physical device for device %s is %s\n", + name, + prvdev->name); +#endif + if(prvdev && skb->dev && + !strcmp(prvdev->name, skb->dev->name)) { + stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL; + skb->dev = ipsecdev; + KLIPS_PRINT(debug_rcv && prvdev, + "klips_debug:ipsec_rcv: " + "assigning packet ownership to virtual device %s from physical device %s.\n", + name, prvdev->name); + if(stats) { + stats->rx_packets++; + } + break; + } + } + } else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "device supplied with skb is NULL\n"); + } + + if(!stats) { + ipsecdev = NULL; + } + KLIPS_PRINT((debug_rcv && !stats), + "klips_error:ipsec_rcv: " + "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", + skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL"); + + KLIPS_IP_PRINT(debug_rcv, ipp); + + /* begin decapsulating loop here */ + do { + authlen = 0; +#ifdef CONFIG_IPSEC_ESP + espp = NULL; + esphlen = 0; +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_AH + ahp = NULL; + ahhlen = 0; +#endif /* CONFIG_IPSEC_AH */ +#ifdef CONFIG_IPSEC_IPCOMP + compp = NULL; +#endif /* CONFIG_IPSEC_IPCOMP */ + + len = skb->len; + dat = skb->data; + ipp = (struct iphdr *)skb->data; + proto = ipp->protocol; + ipaddr.s_addr = ipp->saddr; + addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt)); + + iphlen = ipp->ihl << 2; + ipp->check = 0; /* we know the sum is good */ + +#ifdef CONFIG_IPSEC_ESP + /* XXX this will need to be 8 for IPv6 */ + if ((proto == IPPROTO_ESP) && ((len - iphlen) % 4)) { + printk("klips_error:ipsec_rcv: " + "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n", + len - iphlen, + ipaddr_txt); + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } +#endif /* !CONFIG_IPSEC_ESP */ + + /* + * Find tunnel control block and (indirectly) call the + * appropriate tranform routine. The resulting sk_buf + * is a valid IP packet ready to go through input processing. + */ + + said.dst.s_addr = ipp->daddr; + switch(proto) { +#ifdef CONFIG_IPSEC_ESP + case IPPROTO_ESP: + if(skb->len < (hard_header_len + sizeof(struct iphdr) + sizeof(struct esp))) { + KLIPS_PRINT(debug_rcv & DB_RX_INAU, + "klips_debug:ipsec_rcv: " + "runt esp packet of skb->len=%d received from %s, dropped.\n", + skb->len, + ipaddr_txt); + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } + + espp = (struct esp *)(skb->data + iphlen); + said.spi = espp->esp_spi; + break; +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_AH + case IPPROTO_AH: + if((skb->len + < (hard_header_len + sizeof(struct iphdr) + sizeof(struct ah))) + || (skb->len + < (hard_header_len + sizeof(struct iphdr) + + ((ahp = (struct ah *) (skb->data + iphlen))->ah_hl << 2)))) { + KLIPS_PRINT(debug_rcv & DB_RX_INAU, + "klips_debug:ipsec_rcv: " + "runt ah packet of skb->len=%d received from %s, dropped.\n", + skb->len, + ipaddr_txt); + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } + + said.spi = ahp->ah_spi; + break; +#endif /* CONFIG_IPSEC_AH */ +#ifdef CONFIG_IPSEC_IPCOMP + case IPPROTO_COMP: + if(skb->len < (hard_header_len + sizeof(struct iphdr) + sizeof(struct ipcomphdr))) { + KLIPS_PRINT(debug_rcv & DB_RX_INAU, + "klips_debug:ipsec_rcv: " + "runt comp packet of skb->len=%d received from %s, dropped.\n", + skb->len, + ipaddr_txt); + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } + + compp = (struct ipcomphdr *)(skb->data + iphlen); + said.spi = htonl((__u32)ntohs(compp->ipcomp_cpi)); + break; +#endif /* CONFIG_IPSEC_IPCOMP */ + default: + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } + said.proto = proto; + sa_len = satoa(said, 0, sa, SATOA_BUF); + if(sa_len == 0) { + strcpy(sa, "(error)"); + } + +#ifdef CONFIG_IPSEC_AH + if(proto == IPPROTO_AH) { + ahhlen = (ahp->ah_hl << 2) + + ((caddr_t)&(ahp->ah_rpl) - (caddr_t)ahp); + next_header = ahp->ah_nh; + if (ahhlen != sizeof(struct ah)) { + KLIPS_PRINT(debug_rcv & DB_RX_INAU, + "klips_debug:ipsec_rcv: " + "bad authenticator length %d, expected %d from %s.\n", + (int)(ahhlen - ((caddr_t)(ahp->ah_data) - (caddr_t)ahp)), + AHHMAC_HASHLEN, + ipaddr_txt); + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } + + } +#endif /* CONFIG_IPSEC_AH */ + + /* + The spinlock is to prevent any other process from + accessing or deleting the TDB hash table or any of the + TDBs while we are using and updating them. + + This is not optimal, but was relatively straightforward + at the time. A better way to do it has been planned for + more than a year, to lock the hash table and put reference + counts on each TDB instead. This is not likely to happen + in KLIPS1 unless a volunteer contributes it, but will be + designed into KLIPS2. + */ + if(tdbprev == NULL) { + spin_lock(&tdb_lock); + } + +#ifdef CONFIG_IPSEC_IPCOMP + if (proto == IPPROTO_COMP) { + unsigned int flags = 0; + if (tdbp == NULL) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "Incoming packet with outer IPCOMP header SA:%s: not yet supported by KLIPS, dropped\n", + sa_len ? sa : " (error)"); + if(stats) { + stats->rx_dropped++; + } + + goto rcvleave; + } + + tdbprev = tdbp; + tdbp = tdbnext; + + if(sysctl_ipsec_inbound_policy_check + && ((tdbp == NULL) + || (((ntohl(tdbp->tdb_said.spi) & 0x0000ffff) + != ntohl(said.spi)) + /* next line is a workaround for peer + non-compliance with rfc2393 */ + && (tdbp->tdb_encalg != ntohl(said.spi)) + ))) { + char sa2[SATOA_BUF]; + size_t sa_len2 = 0; + + if(tdbp) { + sa_len2 = satoa(tdbp->tdb_said, 0, sa2, SATOA_BUF); + } + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "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", + sa_len ? sa : " (error)", + tdbp ? (sa_len2 ? sa2 : " (error)") : "NULL", + ntohs(compp->ipcomp_cpi), + (__u32)ntohl(said.spi), + tdbp ? (__u32)ntohl((tdbp->tdb_said.spi)) : 0, + tdbp ? (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff) : 0); + spin_unlock(&tdb_lock); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + + if (tdbp) { + tdbp->tdb_comp_ratio_cbytes += ntohs(ipp->tot_len); + tdbnext = tdbp->tdb_inext; + } + next_header = compp->ipcomp_nh; + + skb = skb_decompress(skb, tdbp, &flags); + if (!skb || flags) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "skb_decompress() returned error flags=%x, dropped.\n", + flags); + if (stats) { + if (flags) + stats->rx_errors++; + else + stats->rx_dropped++; + } + goto rcvleave; + } +#ifdef NET_21 + ipp = skb->nh.iph; +#else /* NET_21 */ + ipp = skb->ip_hdr; +#endif /* NET_21 */ + + if (tdbp) { + tdbp->tdb_comp_ratio_dbytes += ntohs(ipp->tot_len); + } + + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n", + sa_len ? sa : " (error)", + (__u32)ntohl(said.spi), + tdbp ? (__u32)ntohl((tdbp->tdb_said.spi)) : 0, + tdbp ? (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff) : 0, + next_header); + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); + + continue; + /* Skip rest of stuff and decapsulate next inner + packet, if any */ + } +#endif /* CONFIG_IPSEC_IPCOMP */ + + tdbp = ipsec_sa_getbyid(&said); + if (tdbp == NULL) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "no Tunnel Descriptor Block for SA:%s: incoming packet with no SA dropped\n", + sa_len ? sa : " (error)"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if ((natt_type) && + ( (ipp->saddr != (((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr)) || + (natt_sport != tdbp->ips_natt_sport) + )) { + struct sockaddr sipaddr; + /** Advertise NAT-T addr change to pluto **/ + sipaddr.sa_family = AF_INET; + ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = ipp->saddr; + ((struct sockaddr_in*)&sipaddr)->sin_port = htons(natt_sport); + pfkey_nat_t_new_mapping(tdbp, &sipaddr, natt_sport); + /** + * Then allow or block packet depending on + * sysctl_ipsec_inbound_policy_check. + * + * In all cases, pluto will update SA if new mapping is + * accepted. + */ + if (sysctl_ipsec_inbound_policy_check) { + spin_unlock(&tdb_lock); + ipaddr.s_addr = ipp->saddr; + addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt)); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s, src=%s:%u of pkt does not agree with expected " + "SA source address policy (pluto has been informed).\n", + sa_len ? sa : " (error)", + ipaddr_txt, natt_sport); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + } +#endif + + if(sysctl_ipsec_inbound_policy_check) { + if(ipp->saddr != ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr) { + spin_unlock(&tdb_lock); + ipaddr.s_addr = ipp->saddr; + addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt)); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n", + sa_len ? sa : " (error)", + ipaddr_txt); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + ipaddr.s_addr = ipp->saddr; + addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt)); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n", + sa_len ? sa : " (error)", + ipaddr_txt); + if(tdbnext) { + if(tdbnext != tdbp) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "unexpected SA:%s: does not agree with tdb->inext policy, dropped\n", + sa_len ? sa : " (error)"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s grouping from previous SA is OK.\n", + sa_len ? sa : " (error)"); + } else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s First SA in group.\n", + sa_len ? sa : " (error)"); + } + + if(tdbp->tdb_onext) { + if(tdbprev != tdbp->tdb_onext) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "unexpected SA:%s: does not agree with tdb->onext policy, dropped.\n", + sa_len ? sa : " (error)"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s grouping to previous SA is OK.\n", + sa_len ? sa : " (error)"); + } + } else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s No previous backlink in group.\n", + sa_len ? sa : " (error)"); + } +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "natt_type=%u tdbp->ips_natt_type=%u : %s\n", + natt_type, tdbp->ips_natt_type, + (natt_type==tdbp->ips_natt_type)?"ok":"bad"); + if (natt_type != tdbp->ips_natt_type) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s does not agree with expected NAT-T policy.\n", + sa_len ? sa : " (error)"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } +#endif + } + + /* If it is in larval state, drop the packet, we cannot process yet. */ + if(tdbp->tdb_state == SADB_SASTATE_LARVAL) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "TDB in larval state, cannot be used yet, dropping packet.\n"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + + if(tdbp->tdb_state == SADB_SASTATE_DEAD) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "TDB in dead state, cannot be used any more, dropping packet.\n"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + + if(ipsec_lifetime_check(&tdbp->ips_life.ipl_bytes, "bytes", sa, + ipsec_life_countbased, ipsec_incoming, tdbp) == ipsec_life_harddied || + ipsec_lifetime_check(&tdbp->ips_life.ipl_addtime, "addtime",sa, + ipsec_life_timebased, ipsec_incoming, tdbp) == ipsec_life_harddied || + ipsec_lifetime_check(&tdbp->ips_life.ipl_addtime, "usetime",sa, + ipsec_life_timebased, ipsec_incoming, tdbp) == ipsec_life_harddied || + ipsec_lifetime_check(&tdbp->ips_life.ipl_packets, "packets",sa, + ipsec_life_countbased, ipsec_incoming, tdbp) == ipsec_life_harddied) { + ipsec_sa_delchain(tdbp); + spin_unlock(&tdb_lock); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + + /* authenticate, if required */ + idat = dat + iphlen; +#ifdef CONFIG_IPSEC_ALG + if ((ixt_a=IPSEC_ALG_SA_ESP_AUTH(tdbp))) { + authlen = AHHMAC_HASHLEN; + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "authalg=%d authlen=%d\n", + tdbp->tdb_authalg, authlen); + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_authalg) { +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case AH_MD5: + authlen = AHHMAC_HASHLEN; + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + case AH_SHA: + authlen = AHHMAC_HASHLEN; + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + case AH_NONE: + authlen = 0; + break; + default: + tdbp->tdb_alg_errs += 1; + spin_unlock(&tdb_lock); + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } + ilen = len - iphlen - authlen; + if(ilen <= 0) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "runt AH packet with no data, dropping.\n"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + +#ifdef CONFIG_IPSEC_ESP + KLIPS_PRINT(proto == IPPROTO_ESP && debug_rcv, + "klips_debug:ipsec_rcv: " + "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n", + ipaddr_txt, + (__u32)ntohl(espp->esp_rpl), + (__u32)ntohl(*((__u32 *)(espp->esp_iv) )), + (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)), + len, + ilen, + sa_len ? sa : " (error)"); +#endif /* !CONFIG_IPSEC_ESP */ + + switch(proto) { +#ifdef CONFIG_IPSEC_ESP + case IPPROTO_ESP: + replay = ntohl(espp->esp_rpl); + authenticator = &(dat[len - authlen]); + break; +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_AH + case IPPROTO_AH: + replay = ntohl(ahp->ah_rpl); + authenticator = ahp->ah_data; + break; +#endif /* CONFIG_IPSEC_AH */ + } + + if (!ipsec_checkreplaywindow(tdbp, replay)) { + tdbp->tdb_replaywin_errs += 1; + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, + "klips_debug:ipsec_rcv: " + "duplicate frame from %s, packet dropped\n", + ipaddr_txt); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + + /* + * verify authenticator + */ + + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "encalg = %d, authalg = %d.\n", + tdbp->tdb_encalg, + tdbp->tdb_authalg); + +#ifdef CONFIG_IPSEC_ALG + if (ixt_a) { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "ipsec_alg hashing ... "); + if(proto == IPPROTO_ESP) { + ipsec_alg_sa_esp_hash(tdbp, + (caddr_t)espp, ilen, + hash, AHHMAC_HASHLEN); +#ifdef CONFIG_IPSEC_AH +#ifdef IPSEC_ALG_WHEN_AH_IS_READY + } else { + ipo = *ipp; + ipo.tos = 0; + ipo.frag_off = 0; + ipo.ttl = 0; + ipo.check = 0; + + ipsec_alg_hmac_update(tdbp->tdb_key_a, + (caddr_t)&ipo, + sizeof(struct iphdr)); + ipsec_alg_hmac_update(tdbp->tdb_key_a, + (caddr_t)ahp, + ahhlen - AHHMAC_HASHLEN); + ipsec_alg_hmac_update(tdbp->tdb_key_a, + (caddr_t)zeroes, + AHHMAC_HASHLEN); + ipsec_alg_hmac_hash(tdbp->tdb_key_a, + (caddr_t)dat + iphlen + ahhlen, + len - iphlen - ahhlen, + hash, AHHMAC_HASHLEN); +#endif +#endif /* CONFIG_IPSEC_AH */ + } + } else +#endif /* CONFIG_IPSEC_ALG */ + if(tdbp->tdb_authalg) { + switch(tdbp->tdb_authalg) { +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case AH_MD5: + tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx; + if(proto == IPPROTO_ESP) { + MD5Update(&tctx.md5, (caddr_t)espp, ilen); +#ifdef CONFIG_IPSEC_AH + } else { + ipo = *ipp; + ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */ + ipo.frag_off = 0; + ipo.ttl = 0; + ipo.check = 0; + + MD5Update(&tctx.md5, (caddr_t)&ipo, + sizeof(struct iphdr)); + MD5Update(&tctx.md5, (caddr_t)ahp, + ahhlen - AHHMAC_HASHLEN); + MD5Update(&tctx.md5, (caddr_t)zeroes, + AHHMAC_HASHLEN); + MD5Update(&tctx.md5, + (caddr_t)dat + iphlen + ahhlen, + len - iphlen - ahhlen); +#endif /* CONFIG_IPSEC_AH */ + } + MD5Final(hash, &tctx.md5); + tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx; + MD5Update(&tctx.md5, hash, AHMD596_ALEN); + MD5Final(hash, &tctx.md5); + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + case AH_SHA: + tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx; + if(proto == IPPROTO_ESP) { + SHA1Update(&tctx.sha1, (caddr_t)espp, ilen); +#ifdef CONFIG_IPSEC_AH + } else { + ipo = *ipp; + ipo.tos = 0; + ipo.frag_off = 0; + ipo.ttl = 0; + ipo.check = 0; + + SHA1Update(&tctx.sha1, (caddr_t)&ipo, + sizeof(struct iphdr)); + SHA1Update(&tctx.sha1, (caddr_t)ahp, + ahhlen - AHHMAC_HASHLEN); + SHA1Update(&tctx.sha1, (caddr_t)zeroes, + AHHMAC_HASHLEN); + SHA1Update(&tctx.sha1, + (caddr_t)dat + iphlen + ahhlen, + len - iphlen - ahhlen); +#endif /* CONFIG_IPSEC_AH */ + } + SHA1Final(hash, &tctx.sha1); + tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx; + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); + SHA1Final(hash, &tctx.sha1); + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + case AH_NONE: + break; + } + + if(!authenticator) { + tdbp->tdb_auth_errs += 1; + spin_unlock(&tdb_lock); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + + if (memcmp(hash, authenticator, authlen)) { + tdbp->tdb_auth_errs += 1; + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv & DB_RX_INAU, + "klips_debug:ipsec_rcv: " + "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n", + ipaddr_txt, + *(__u32*)&hash[0], + *(__u32*)&hash[4], + *(__u32*)&hash[8], + *(__u32*)authenticator, + *((__u32*)authenticator + 1), + *((__u32*)authenticator + 2)); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "authentication successful.\n"); + } + + memset((caddr_t)&tctx, 0, sizeof(tctx)); + memset(hash, 0, sizeof(hash)); + } + + /* If the sequence number == 0, expire SA, it had rolled */ + if(tdbp->tdb_replaywin && !replay /* !tdbp->tdb_replaywin_lastseq */) { + ipsec_sa_delchain(tdbp); + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "replay window counter rolled, expiring SA.\n"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + + if (!ipsec_updatereplaywindow(tdbp, replay)) { + tdbp->tdb_replaywin_errs += 1; + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv & DB_RX_REPLAY, + "klips_debug:ipsec_rcv: " + "duplicate frame from %s, packet dropped\n", + ipaddr_txt); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + + switch(proto) { +#ifdef CONFIG_IPSEC_ESP + case IPPROTO_ESP: +#ifdef CONFIG_IPSEC_ALG + if ((ixt_e=IPSEC_ALG_SA_ESP_ENC(tdbp))) { + esphlen = ESP_HEADER_LEN + ixt_e->ixt_ivlen/8; + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "encalg=%d esphlen=%d\n", + tdbp->tdb_encalg, esphlen); + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_encalg) { +#ifdef CONFIG_IPSEC_ENC_3DES + case ESP_3DES: + iv[0] = *((__u32 *)(espp->esp_iv) ); + iv[1] = *((__u32 *)(espp->esp_iv) + 1); + esphlen = sizeof(struct esp); + break; +#endif /* CONFIG_IPSEC_ENC_3DES */ + default: + tdbp->tdb_alg_errs += 1; + spin_unlock(&tdb_lock); + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } + idat += esphlen; + ilen -= esphlen; + +#ifdef CONFIG_IPSEC_ALG + if (ixt_e) + { + if (ipsec_alg_esp_encrypt(tdbp, + idat, ilen, espp->esp_iv, + IPSEC_ALG_DECRYPT) <= 0) + { + spin_unlock(&tdb_lock); + printk("klips_error:ipsec_rcv: " + "got packet with esplen = %d " + "from %s -- should be on " + "ENC(%d) octet boundary, " + "packet dropped\n", + ilen, + ipaddr_txt, + tdbp->tdb_encalg); + stats->rx_errors++; + goto rcvleave; + } + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_encalg) { +#ifdef CONFIG_IPSEC_ENC_3DES + case ESP_3DES: + if ((ilen) % 8) { + tdbp->tdb_encsize_errs += 1; + spin_unlock(&tdb_lock); + printk("klips_error:ipsec_rcv: " + "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n", + ilen, + ipaddr_txt); + if(stats) { + stats->rx_errors++; + } + goto rcvleave; + } + des_ede3_cbc_encrypt((des_cblock *)idat, + (des_cblock *)idat, + ilen, + ((struct des_eks *)(tdbp->tdb_key_e))[0].ks, + ((struct des_eks *)(tdbp->tdb_key_e))[1].ks, + ((struct des_eks *)(tdbp->tdb_key_e))[2].ks, + (des_cblock *)iv, 0); + break; +#endif /* CONFIG_IPSEC_ENC_3DES */ + default: + } + next_header = idat[ilen - 1]; + padlen = idat[ilen - 2]; + pad = padlen + 2 + authlen; + { + int badpad = 0; + + KLIPS_PRINT(debug_rcv & DB_RX_IPAD, + "klips_debug:ipsec_rcv: " + "padlen=%d, contents: 0x: 0x 0x ...\n", + padlen); + + for (i = 1; i <= padlen; i++) { + if((i % 16) == 1) { + KLIPS_PRINT(debug_rcv & DB_RX_IPAD, + "klips_debug: %02x:", + i - 1); + } + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, + " %02x", + idat[ilen - 2 - padlen + i - 1]); + if(i != idat[ilen - 2 - padlen + i - 1]) { + badpad = 1; + } + if((i % 16) == 0) { + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, + "\n"); + } + } + if((i % 16) != 1) { + KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD, + "\n"); + } + if(badpad) { + KLIPS_PRINT(debug_rcv & DB_RX_IPAD, + "klips_debug:ipsec_rcv: " + "warning, decrypted packet from %s has bad padding\n", + ipaddr_txt); + KLIPS_PRINT(debug_rcv & DB_RX_IPAD, + "klips_debug:ipsec_rcv: " + "...may be bad decryption -- not dropped\n"); + tdbp->tdb_encpad_errs += 1; + } + + KLIPS_PRINT(debug_rcv & DB_RX_IPAD, + "klips_debug:ipsec_rcv: " + "packet decrypted from %s: next_header = %d, padding = %d\n", + ipaddr_txt, + next_header, + pad - 2 - authlen); + } +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_AH + case IPPROTO_AH: + break; +#endif /* CONFIG_IPSEC_AH */ + } + + /* + * Discard the original ESP/AH header + */ + + ipp->protocol = next_header; + + switch(proto) { +#ifdef CONFIG_IPSEC_ESP + case IPPROTO_ESP: + ipp->tot_len = htons(ntohs(ipp->tot_len) - (esphlen + pad)); + memmove((void *)(skb->data + esphlen), + (void *)(skb->data), iphlen); + if(skb->len < esphlen) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING + "klips_error:ipsec_rcv: " + "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n", + esphlen, (int)(skb->len)); + goto rcvleave; + } + skb_pull(skb, esphlen); + + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, + "klips_debug:ipsec_rcv: " + "trimming to %d.\n", + len - esphlen - pad); + if(pad + esphlen <= len) { + skb_trim(skb, len - esphlen - pad); + } else { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, + "klips_debug:ipsec_rcv: " + "bogus packet, size is zero or negative, dropping.\n"); + goto rcvleave; + } + break; +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_AH + case IPPROTO_AH: + ipp->tot_len = htons(ntohs(ipp->tot_len) - ahhlen); + memmove((void *)(skb->data + ahhlen), + (void *)(skb->data), iphlen); + if(skb->len < ahhlen) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING + "klips_error:ipsec_rcv: " + "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n", + ahhlen, + (int)(skb->len)); + goto rcvleave; + } + skb_pull(skb, ahhlen); + break; +#endif /* CONFIG_IPSEC_AH */ + } + + + /* + * Adjust pointers + */ + + len = skb->len; + dat = skb->data; + +#ifdef NET_21 +/* skb->h.ipiph=(struct iphdr *)skb->data; */ + skb->nh.raw = skb->data; + skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2); + + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); +#else /* NET_21 */ + skb->h.iph=(struct iphdr *)skb->data; + skb->ip_hdr=(struct iphdr *)skb->data; + memset(skb->proto_priv, 0, sizeof(struct options)); +#endif /* NET_21 */ + + ipp = (struct iphdr *)dat; + ipp->check = 0; + ipp->check = ip_fast_csum((unsigned char *)dat, iphlen >> 2); + + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, + "klips_debug:ipsec_rcv: " + "after <%s%s%s>, SA:%s:\n", + IPS_XFORM_NAME(tdbp), + sa_len ? sa : " (error)"); + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); + + skb->protocol = htons(ETH_P_IP); + skb->ip_summed = 0; + + tdbprev = tdbp; + tdbnext = tdbp->tdb_inext; + if(sysctl_ipsec_inbound_policy_check) { + if(tdbnext) { + if(tdbnext->tdb_onext != tdbp) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s, backpolicy does not agree with fwdpolicy.\n", + sa_len ? sa : " (error)"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s, backpolicy agrees with fwdpolicy.\n", + sa_len ? sa : " (error)"); + if( + ipp->protocol != IPPROTO_AH + && ipp->protocol != IPPROTO_ESP +#ifdef CONFIG_IPSEC_IPCOMP + && ipp->protocol != IPPROTO_COMP + && (tdbnext->tdb_said.proto != IPPROTO_COMP + || (tdbnext->tdb_said.proto == IPPROTO_COMP + && tdbnext->tdb_inext)) +#endif /* CONFIG_IPSEC_IPCOMP */ + && ipp->protocol != IPPROTO_IPIP + && ipp->protocol != 0xFE // added to support heartbeats to AT&T SIG/GIG + ) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "packet with incomplete policy dropped, last successful SA:%s.\n", + sa_len ? sa : " (error)"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s, Another IPSEC header to process.\n", + sa_len ? sa : " (error)"); + } else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "No tdb_inext from this SA:%s.\n", + sa_len ? sa : " (error)"); + } + } + +#ifdef CONFIG_IPSEC_IPCOMP + /* update ipcomp ratio counters, even if no ipcomp packet is present */ + if (tdbnext + && tdbnext->tdb_said.proto == IPPROTO_COMP + && ipp->protocol != IPPROTO_COMP) { + tdbnext->tdb_comp_ratio_cbytes += ntohs(ipp->tot_len); + tdbnext->tdb_comp_ratio_dbytes += ntohs(ipp->tot_len); + } +#endif /* CONFIG_IPSEC_IPCOMP */ + + tdbp->ips_life.ipl_bytes.ipl_count += len; + tdbp->ips_life.ipl_bytes.ipl_last = len; + + if(!tdbp->ips_life.ipl_usetime.ipl_count) { + tdbp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; + } + tdbp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; + tdbp->ips_life.ipl_packets.ipl_count += 1; + + /* end decapsulation loop here */ + } while( (ipp->protocol == IPPROTO_ESP ) + || (ipp->protocol == IPPROTO_AH ) +#ifdef CONFIG_IPSEC_IPCOMP + || (ipp->protocol == IPPROTO_COMP) +#endif /* CONFIG_IPSEC_IPCOMP */ + ); + +#ifdef CONFIG_IPSEC_IPCOMP + if(tdbnext && tdbnext->tdb_said.proto == IPPROTO_COMP) { + tdbprev = tdbp; + tdbp = tdbnext; + tdbnext = tdbp->tdb_inext; + } +#endif /* CONFIG_IPSEC_IPCOMP */ + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if ((natt_type) && (ipp->protocol != IPPROTO_IPIP)) { + /** + * NAT-Traversal and Transport Mode: + * we need to correct TCP/UDP checksum + * + * If we've got NAT-OA, we can fix checksum without recalculation. + */ + __u32 natt_oa = tdbp->ips_natt_oa ? + ((struct sockaddr_in*)(tdbp->ips_natt_oa))->sin_addr.s_addr : 0; + __u16 pkt_len = skb->tail - (unsigned char *)ipp; + __u16 data_len = pkt_len - (ipp->ihl << 2); + + switch (ipp->protocol) { + case IPPROTO_TCP: + if (data_len >= sizeof(struct tcphdr)) { + struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ipp+ipp->ihl); + if (natt_oa) { + __u32 buff[2] = { ~natt_oa, ipp->saddr }; + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NAT-T & TRANSPORT: " + "fix TCP checksum using NAT-OA\n"); + tcp->check = csum_fold( + csum_partial((unsigned char *)buff, sizeof(buff), + tcp->check^0xffff)); + } + else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NAT-T & TRANSPORT: recalc TCP checksum\n"); + if (pkt_len > (ntohs(ipp->tot_len))) + data_len -= (pkt_len - ntohs(ipp->tot_len)); + tcp->check = 0; + tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr, + data_len, IPPROTO_TCP, + csum_partial((unsigned char *)tcp, data_len, 0)); + } + } + else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NAT-T & TRANSPORT: can't fix TCP checksum\n"); + } + break; + case IPPROTO_UDP: + if (data_len >= sizeof(struct udphdr)) { + struct udphdr *udp = (struct udphdr *)((__u32 *)ipp+ipp->ihl); + if (udp->check == 0) { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NAT-T & TRANSPORT: UDP checksum already 0\n"); + } + else if (natt_oa) { + __u32 buff[2] = { ~natt_oa, ipp->saddr }; + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NAT-T & TRANSPORT: " + "fix UDP checksum using NAT-OA\n"); + udp->check = csum_fold( + csum_partial((unsigned char *)buff, sizeof(buff), + udp->check^0xffff)); + } + else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NAT-T & TRANSPORT: zero UDP checksum\n"); + udp->check = 0; + } + } + else { + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NAT-T & TRANSPORT: can't fix UDP checksum\n"); + } + break; + default: + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n"); + break; + } + } +#endif + + /* + * XXX this needs to be locked from when it was first looked + * up in the decapsulation loop. Perhaps it is better to put + * the IPIP decap inside the loop. + */ + if(tdbnext) { + tdbp = tdbnext; + sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF); + if((ipp->protocol != IPPROTO_IPIP) && + ( 0xFE != ipp->protocol)) // added to support AT&T heartbeats to SIG/GIG + { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s, Hey! How did this get through? Dropped.\n", + sa_len ? sa : " (error)"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + if(sysctl_ipsec_inbound_policy_check) { + if((tdbnext = tdbp->tdb_inext)) { + char sa2[SATOA_BUF]; + size_t sa_len2; + sa_len2 = satoa(tdbnext->tdb_said, 0, sa2, SATOA_BUF); + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "unexpected SA:%s after IPIP SA:%s\n", + sa_len2 ? sa2 : " (error)", + sa_len ? sa : " (error)"); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + if(ipp->saddr != ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr) { + spin_unlock(&tdb_lock); + ipaddr.s_addr = ipp->saddr; + addrtoa(ipaddr, 0, ipaddr_txt, sizeof(ipaddr_txt)); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n", + sa_len ? sa : " (error)", + ipaddr_txt); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + } + + if(ipp->protocol == IPPROTO_IPIP) // added to support AT&T heartbeats to SIG/GIG + { + /* + * XXX this needs to be locked from when it was first looked + * up in the decapsulation loop. Perhaps it is better to put + * the IPIP decap inside the loop. + */ + tdbp->ips_life.ipl_bytes.ipl_count += len; + tdbp->ips_life.ipl_bytes.ipl_last = len; + + if(!tdbp->ips_life.ipl_usetime.ipl_count) { + tdbp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; + } + tdbp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; + tdbp->ips_life.ipl_packets.ipl_count += 1; + + if(skb->len < iphlen) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING "klips_debug:ipsec_rcv: " + "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n", + iphlen, + (int)(skb->len)); + + goto rcvleave; + } + skb_pull(skb, iphlen); + +#ifdef NET_21 + ipp = (struct iphdr *)skb->nh.raw = skb->data; + skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2); + + memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); +#else /* NET_21 */ + ipp = skb->ip_hdr = skb->h.iph = (struct iphdr *)skb->data; + + memset(skb->proto_priv, 0, sizeof(struct options)); +#endif /* NET_21 */ + + skb->protocol = htons(ETH_P_IP); + skb->ip_summed = 0; + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, + "klips_debug:ipsec_rcv: " + "IPIP tunnel stripped.\n"); + KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp); + } + + if(sysctl_ipsec_inbound_policy_check + /* + Note: "xor" (^) logically replaces "not equal" + (!=) and "bitwise or" (|) logically replaces + "boolean or" (||). This is done to speed up + execution by doing only bitwise operations and + no branch operations + */ + && (((ipp->saddr & tdbp->tdb_mask_s.u.v4.sin_addr.s_addr) + ^ tdbp->tdb_flow_s.u.v4.sin_addr.s_addr) + | ((ipp->daddr & tdbp->tdb_mask_d.u.v4.sin_addr.s_addr) + ^ tdbp->tdb_flow_d.u.v4.sin_addr.s_addr)) ) + { + struct in_addr daddr, saddr; + char saddr_txt[ADDRTOA_BUF], daddr_txt[ADDRTOA_BUF]; + char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF]; + + subnettoa(tdbp->tdb_flow_s.u.v4.sin_addr, + tdbp->tdb_mask_s.u.v4.sin_addr, + 0, sflow_txt, sizeof(sflow_txt)); + subnettoa(tdbp->tdb_flow_d.u.v4.sin_addr, + tdbp->tdb_mask_d.u.v4.sin_addr, + 0, dflow_txt, sizeof(dflow_txt)); + spin_unlock(&tdb_lock); + saddr.s_addr = ipp->saddr; + daddr.s_addr = ipp->daddr; + addrtoa(saddr, 0, saddr_txt, sizeof(saddr_txt)); + addrtoa(daddr, 0, daddr_txt, sizeof(daddr_txt)); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n", + sa_len ? sa : " (error)", + sflow_txt, + dflow_txt, + saddr_txt, + daddr_txt); + if(stats) { + stats->rx_dropped++; + } + goto rcvleave; + } + } + +#ifdef INBOUND_POLICY_CHECK_eroute + /* + Do *not* enable this without thoroughly checking spinlock issues + first. In particular, nesting an eroute spinlock within a tdb + spinlock could result in a deadlock. (Well, only on a SMP machine + under 2.4?) + */ + + /* + * First things first -- look us up in the erouting tables. + */ + matcher.sen_len = sizeof (struct sockaddr_encap); + matcher.sen_family = AF_ENCAP; + matcher.sen_type = SENT_IP4; + if(ipp->protocol == IPPROTO_IPIP) { + struct iphdr *ipp2; + + ipp2 = (struct iphdr*) (((char*)ipp) + (ipp->ihl << 2)); + matcher.sen_ip_src.s_addr = ipp2->saddr; + matcher.sen_ip_dst.s_addr = ipp2->daddr; + } else { + matcher.sen_ip_src.s_addr = ipp->saddr; + matcher.sen_ip_dst.s_addr = ipp->daddr; + } + + /* + * The spinlock is to prevent any other process from accessing or + * deleting the eroute while we are using and updating it. + */ + spin_lock(&eroute_lock); + + er = ipsec_findroute(&matcher); + if(er) { + policy_said = er->er_said; + policy_eaddr = er->er_eaddr; + policy_emask = er->er_emask; + er->er_count++; + er->er_lasttime = jiffies/HZ; + } + + spin_unlock(&eroute_lock); + + if(er) { + /* + * The spinlock is to prevent any other process from + * accessing or deleting the tdb while we are using and + * updating it. + */ + spin_lock(&tdb_lock); + + policy_tdb = gettdb(&policy_said); + if (policy_tdb == NULL) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "no Tunnel Descriptor Block for SA%s: incoming packet with no policy SA, dropped.\n", + sa_len ? sa : " (error)"); + goto rcvleave; + } + + sa_len = satoa(policy_said, 0, sa, SATOA_BUF); + + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "found policy Tunnel Descriptor Block -- SA:%s\n", + sa_len ? sa : " (error)"); + while(1) { + if(policy_tdb->tdb_inext) { + policy_tdb = policy_tdb->tdb_inext; + } else { + break; + } + } + if(policy_tdb != tdbp) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_rcv, + "klips_debug:ipsec_rcv: " + "Tunnel Descriptor Block for SA%s: incoming packet with different policy SA, dropped.\n", + sa_len ? sa : " (error)"); + goto rcvleave; + } + + /* spin_unlock(&tdb_lock); */ + } +#endif /* INBOUND_POLICY_CHECK_eroute */ + + spin_unlock(&tdb_lock); + +#ifdef NET_21 + if(stats) { + stats->rx_bytes += skb->len; + } + if(skb->dst) { + dst_release(skb->dst); + skb->dst = NULL; + } + skb->pkt_type = PACKET_HOST; + if(hard_header_len && + (skb->mac.raw != (skb->data - hard_header_len)) && + (hard_header_len <= skb_headroom(skb))) { + /* copy back original MAC header */ + memmove(skb->data - hard_header_len, skb->mac.raw, hard_header_len); + skb->mac.raw = skb->data - hard_header_len; + } +#endif /* NET_21 */ + +#ifdef CONFIG_IPSEC_IPCOMP + if(ipp->protocol == IPPROTO_COMP) { + unsigned int flags = 0; + + if(sysctl_ipsec_inbound_policy_check) { + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, + "klips_debug:ipsec_rcv: " + "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n"); + if (stats) { + stats->rx_errors++; + } + goto rcvleave; + } + /* + XXX need a TDB for updating ratio counters but it is not + following policy anyways so it is not a priority + */ + skb = skb_decompress(skb, NULL, &flags); + if (!skb || flags) { + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, + "klips_debug:ipsec_rcv: " + "skb_decompress() returned error flags: %d, dropped.\n", + flags); + if (stats) { + stats->rx_errors++; + } + goto rcvleave; + } + } +#endif /* CONFIG_IPSEC_IPCOMP */ + +#ifdef SKB_RESET_NFCT + nf_conntrack_put(skb->nfct); + skb->nfct = NULL; +#ifdef CONFIG_NETFILTER_DEBUG + skb->nf_debug = 0; +#endif /* CONFIG_NETFILTER_DEBUG */ +#endif /* SKB_RESET_NFCT */ + KLIPS_PRINT(debug_rcv & DB_RX_PKTRX, + "klips_debug:ipsec_rcv: " + "netif_rx() called.\n"); + netif_rx(skb); + + MOD_DEC_USE_COUNT; + return(0); + + rcvleave: + if(skb) { +#ifdef NET_21 + kfree_skb(skb); +#else /* NET_21 */ + kfree_skb(skb, FREE_WRITE); +#endif /* NET_21 */ + } + + MOD_DEC_USE_COUNT; + return(0); +} + +struct inet_protocol ah_protocol = +{ + ipsec_rcv, /* AH handler */ + NULL, /* TUNNEL error control */ + 0, /* next */ + IPPROTO_AH, /* protocol ID */ + 0, /* copy */ + NULL, /* data */ + "AH" /* name */ +}; + +struct inet_protocol esp_protocol = +{ + ipsec_rcv, /* ESP handler */ + NULL, /* TUNNEL error control */ + 0, /* next */ + IPPROTO_ESP, /* protocol ID */ + 0, /* copy */ + NULL, /* data */ + "ESP" /* name */ +}; + +#if 0 +/* We probably don't want to install a pure IPCOMP protocol handler, but + only want to handle IPCOMP if it is encapsulated inside an ESP payload + (which is already handled) */ +#ifdef CONFIG_IPSEC_IPCOMP +struct inet_protocol comp_protocol = +{ + ipsec_rcv, /* COMP handler */ + NULL, /* COMP error control */ + 0, /* next */ + IPPROTO_COMP, /* protocol ID */ + 0, /* copy */ + NULL, /* data */ + "COMP" /* name */ +}; +#endif /* CONFIG_IPSEC_IPCOMP */ +#endif + +/* + * $Log: ipsec_rcv.c,v $ + * Revision 1.18 2003/12/04 03:04:38 ken + * Cast safely for ia64 + * + * Revision 1.17 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.16 2003/09/30 00:26:01 ken + * Tuomo Soini's NAT-T 0.6 cleanup patch + * Fixes a number of #ifdefs around NAT-T, and brings a few other other cleanups in + * + * Revision 1.15 2003/07/04 19:07:34 ken + * Added NAT-T 0.6 diff/patch from Tuomo + * + * Revision 1.14 2003/02/07 13:14:24 ken + * Pullin jjo's ALG 0.8.1rc branch + * + * Revision 1.13.2.1 2003/02/06 22:09:49 jjo + * sync to alg-0.8.1-rc4 + * + * Revision 1.13 2003/01/19 23:06:27 ken + * Added MTS Patch (fix broken AT&T VPN System for IBM Users) - amcedwards + * + * Revision 1.12 2003/01/02 21:47:45 ken + * NAT-T 0.5 + * + * Revision 1.11 2002/11/05 01:41:46 ken + * Pulled from 1.99 + * + * Revision 1.102.6.6 2002/10/30 17:39:07 rgb + * Fixed cut-and-paste error mis-identifying comp runt as ah. + * + * Revision 1.102.6.5 2002/10/30 05:45:19 rgb + * Make sure partial esp/ah/comp headers don't cause oops. + * + * Revision 1.102.6.4 2002/10/28 19:54:56 sam + * Fix scope of shift in AH header length check. + * + * Revision 1.10 2002/11/05 01:35:58 ken + * 1.99cand -> 1.99 Final Code changes + * + * Revision 1.9 2002/10/26 19:18:48 ken + * fixed bad patch of ipsec_rcv.c + * + * Revision 1.102.6.3 2002/10/25 17:26:40 sam + * runt patch applied for DOS + * + * Revision 1.102.6.2 2002/10/18 05:20:36 sam + * Patched with RGB's fix from ipsec_rcv.c v1.109: + * + * Fixed ESP short packet DOS (and AH and IPCOMP) + * + * Revision 1.8 2002/10/26 14:32:44 ken + * Patch in code from 1.99 for ESP DOS Fix, and RPM build fixes. + * patch -p1 -F 3 < ../_kb9-DOSFIX.diff + * + * Revision 1.7 2002/10/16 00:21:46 ken + * Applied JuanJo's NULL Patch + * + * Revision 1.6 2002/10/16 00:16:50 ken + * Backed out David patch in prep for JuanJo's + * + * Revision 1.5 2002/10/15 18:35:24 ken + * Updated README/CHANGES for _kb8 + * + * Revision 1.4 2002/10/15 17:52:47 ken + * Added David De Reu's NULL ALG Bugfix + * + * Revision 1.3 2002/09/05 03:53:52 ken + * Added NAT-T Patch + * + * Revision 1.2 2002/09/05 03:27:08 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.102 2002/01/29 17:17:56 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.101 2002/01/29 04:00:52 mcr + * more excise of kversions.h header. + * + * Revision 1.100 2002/01/29 02:13:17 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.99 2002/01/28 21:40:59 mcr + * should use #if to test boolean option rather than #ifdef. + * + * Revision 1.98 2002/01/20 20:19:36 mcr + * renamed option to IP_FRAGMENT_LINEARIZE. + * + * Revision 1.97 2002/01/12 02:55:36 mcr + * fix for post-2.4.4 to linearize skb's when ESP packet + * was assembled from fragments. + * + * Revision 1.96 2001/11/26 09:23:49 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.93.2.2 2001/10/22 20:54:07 mcr + * include des.h, removed phony prototypes and fixed calling + * conventions to match real prototypes. + * + * Revision 1.93.2.1 2001/09/25 02:22:22 mcr + * struct tdb -> struct ipsec_sa. + * lifetime checks moved to ipsec_life.c + * some sa(tdb) manipulation functions renamed. + * + * Revision 1.95 2001/11/06 19:49:07 rgb + * Added variable descriptions. + * Removed unauthenticated sequence==0 check to prevent DoS. + * + * Revision 1.94 2001/10/18 04:45:20 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/freeswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.93 2001/09/07 22:17:24 rgb + * Fix for removal of transport layer protocol handler arg in 2.4.4. + * Fix to accomodate peer non-conformance to IPCOMP rfc2393. + * + * Revision 1.92 2001/08/27 19:44:41 rgb + * Fix error in comment. + * + * Revision 1.91 2001/07/20 19:31:48 dhr + * [DHR] fix source and destination subnets of policy in diagnostic + * + * Revision 1.90 2001/07/06 19:51:09 rgb + * Added inbound policy checking code for IPIP SAs. + * Renamed unused function argument for ease and intuitive naming. + * + * Revision 1.89 2001/06/22 19:35:23 rgb + * Disable ipcomp processing if we are handed a ipcomp packet with no esp + * or ah header. + * Print protocol if we are handed a non-ipsec packet. + * + * Revision 1.88 2001/06/20 06:30:47 rgb + * Fixed transport mode IPCOMP policy check bug. + * + * Revision 1.87 2001/06/13 20:58:40 rgb + * Added parentheses around assignment used as truth value to silence + * compiler. + * + * Revision 1.86 2001/06/07 22:25:23 rgb + * Added a source address policy check for tunnel mode. It still does + * not check client addresses and masks. + * Only decapsulate IPIP if it is expected. + * + * Revision 1.85 2001/05/30 08:14:02 rgb + * Removed vestiges of esp-null transforms. + * + * Revision 1.84 2001/05/27 06:12:11 rgb + * Added structures for pid, packet count and last access time to eroute. + * Added packet count to beginning of /proc/net/ipsec_eroute. + * + * Revision 1.83 2001/05/04 16:45:47 rgb + * Remove unneeded code. ipp is not used after this point. + * + * Revision 1.82 2001/05/04 16:36:00 rgb + * Fix skb_cow() call for 2.4.4. (SS) + * + * Revision 1.81 2001/05/02 14:46:53 rgb + * Fix typo for compiler directive to pull IPH back. + * + * Revision 1.80 2001/04/30 19:46:34 rgb + * Update for 2.4.4. We now receive the skb with skb->data pointing to + * h.raw. + * + * Revision 1.79 2001/04/23 15:01:15 rgb + * Added spin_lock() check to prevent double-locking for multiple + * transforms and hence kernel lock-ups with SMP kernels. + * Minor spin_unlock() adjustments to unlock before non-dependant prints + * and IPSEC device stats updates. + * + * Revision 1.78 2001/04/21 23:04:24 rgb + * Check if soft expire has already been sent before sending another to + * prevent ACQUIRE flooding. + * + * Revision 1.77 2001/03/16 07:35:20 rgb + * Ditch extra #if 1 around now permanent policy checking code. + * + * Revision 1.76 2001/02/27 22:24:54 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.75 2001/02/19 22:28:30 rgb + * Minor change to virtual device discovery code to assert which I/F has + * been found. + * + * Revision 1.74 2000/11/25 03:50:36 rgb + * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb. + * + * Revision 1.73 2000/11/09 20:52:15 rgb + * More spinlock shuffling, locking earlier and unlocking later in rcv to + * include ipcomp and prevent races, renaming some tdb variables that got + * forgotten, moving some unlocks to include tdbs and adding a missing + * unlock. Thanks to Svenning for some of these. + * + * Revision 1.72 2000/11/09 20:11:22 rgb + * Minor shuffles to fix non-standard kernel config option selection. + * + * Revision 1.71 2000/11/06 04:36:18 rgb + * Ditched spin_lock_irqsave in favour of spin_lock. + * Minor initial protocol check rewrite. + * Clean up debug printing. + * Clean up tdb handling on ipcomp. + * Fixed transport mode null pointer de-reference without ipcomp. + * Add Svenning's adaptive content compression. + * Disabled registration of ipcomp handler. + * + * Revision 1.70 2000/10/30 23:41:43 henry + * Hans-Joerg Hoexer's null-pointer fix + * + * Revision 1.69 2000/10/10 18:54:16 rgb + * Added a fix for incoming policy check with ipcomp enabled but + * uncompressible. + * + * Revision 1.68 2000/09/22 17:53:12 rgb + * Fixed ipcomp tdb pointers update for policy checking. + * + * Revision 1.67 2000/09/21 03:40:58 rgb + * Added more debugging to try and track down the cpi outward copy problem. + * + * Revision 1.66 2000/09/20 04:00:10 rgb + * Changed static functions to DEBUG_NO_STATIC to reveal function names for + * debugging oopsen. + * + * Revision 1.65 2000/09/19 07:07:16 rgb + * Added debugging to inbound policy check for ipcomp. + * Added missing spin_unlocks (thanks Svenning!). + * Fixed misplaced tdbnext pointers causing mismatched ipip policy check. + * Protect ipcomp policy check following ipip decap with sysctl switch. + * + * Revision 1.64 2000/09/18 21:27:29 rgb + * 2.0 fixes. + * + * Revision 1.63 2000/09/18 02:35:50 rgb + * Added policy checking to ipcomp and re-enabled policy checking by + * default. + * Optimised satoa calls. + * + * Revision 1.62 2000/09/17 21:02:32 rgb + * Clean up debugging, removing slow timestamp debug code. + * + * Revision 1.61 2000/09/16 01:07:55 rgb + * Fixed erroneous ref from struct ipcomp to struct ipcomphdr. + * + * Revision 1.60 2000/09/15 11:37:01 rgb + * Merge in heavily modified Svenning Soerensen's + * IPCOMP zlib deflate code. + * + * Revision 1.59 2000/09/15 04:56:20 rgb + * Remove redundant satoa() call, reformat comment. + * + * Revision 1.58 2000/09/13 08:00:52 rgb + * Flick on inbound policy checking. + * + * Revision 1.57 2000/09/12 03:22:19 rgb + * Converted inbound_policy_check to sysctl. + * Re-enabled policy backcheck. + * Moved policy checks to top and within tdb lock. + * + * Revision 1.56 2000/09/08 19:12:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.55 2000/08/28 18:15:46 rgb + * Added MB's nf-debug reset patch. + * + * Revision 1.54 2000/08/27 01:41:26 rgb + * More minor tweaks to the bad padding debug code. + * + * Revision 1.53 2000/08/24 16:54:16 rgb + * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level + * info. + * Tidied up device reporting at the start of ipsec_rcv. + * Tidied up bad padding debugging and processing. + * + * Revision 1.52 2000/08/20 21:36:03 rgb + * Activated pfkey_expire() calls. + * Added a hard/soft expiry parameter to pfkey_expire(). + * Added sanity checking to avoid propagating zero or smaller-length skbs + * from a bogus decryption. + * Re-arranged the order of soft and hard expiry to conform to RFC2367. + * Clean up references to CONFIG_IPSEC_PFKEYv2. + * + * Revision 1.51 2000/08/18 21:23:30 rgb + * Improve bad padding warning so that the printk buffer doesn't get + * trampled. + * + * Revision 1.50 2000/08/01 14:51:51 rgb + * Removed _all_ remaining traces of DES. + * + * Revision 1.49 2000/07/28 13:50:53 rgb + * Changed enet_statistics to net_device_stats and added back compatibility + * for pre-2.1.19. + * + * Revision 1.48 2000/05/10 19:14:40 rgb + * Only check usetime against soft and hard limits if the tdb has been + * used. + * Cast output of ntohl so that the broken prototype doesn't make our + * compile noisy. + * + * Revision 1.47 2000/05/09 17:45:43 rgb + * Fix replay bitmap corruption bug upon receipt of bogus packet + * with correct SPI. This was a DoS. + * + * Revision 1.46 2000/03/27 02:31:58 rgb + * Fixed authentication failure printout bug. + * + * Revision 1.45 2000/03/22 16:15:37 rgb + * Fixed renaming of dev_get (MB). + * + * Revision 1.44 2000/03/16 08:17:24 rgb + * Hardcode PF_KEYv2 support. + * Fixed minor bug checking AH header length. + * + * Revision 1.43 2000/03/14 12:26:59 rgb + * Added skb->nfct support for clearing netfilter conntrack bits (MB). + * + * Revision 1.42 2000/01/26 10:04:04 rgb + * Fixed inbound policy checking on transport mode bug. + * Fixed noisy 2.0 printk arguments. + * + * Revision 1.41 2000/01/24 20:58:02 rgb + * Improve debugging/reporting support for (disabled) inbound + * policy checking. + * + * Revision 1.40 2000/01/22 23:20:10 rgb + * Fixed up inboud policy checking code. + * Cleaned out unused crud. + * + * Revision 1.39 2000/01/21 06:15:29 rgb + * Added sanity checks on skb_push(), skb_pull() to prevent panics. + * Fixed cut-and-paste debug_tunnel to debug_rcv. + * Added inbound policy checking code, disabled. + * Simplified output code by updating ipp to post-IPIP decapsulation. + * + * Revision 1.38 1999/12/22 05:08:36 rgb + * Checked for null skb, skb->dev, skb->data, skb->dev->name, dev->name, + * protocol and take appropriate action for sanity. + * Set ipsecdev to NULL if device could not be determined. + * Fixed NULL stats access bug if device could not be determined. + * + * Revision 1.37 1999/12/14 20:07:59 rgb + * Added a default switch case to catch bogus encalg values. + * + * Revision 1.36 1999/12/07 18:57:57 rgb + * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled. + * + * Revision 1.35 1999/12/01 22:15:35 rgb + * Add checks for LARVAL and DEAD SAs. + * Change state of SA from MATURE to DYING when a soft lifetime is + * reached and print debug warning. + * + * Revision 1.34 1999/11/23 23:04:03 rgb + * Use provided macro ADDRTOA_BUF instead of hardcoded value. + * Sort out pfkey and freeswan headers, putting them in a library path. + * + * Revision 1.33 1999/11/19 01:10:06 rgb + * Enable protocol handler structures for static linking. + * + * Revision 1.32 1999/11/18 04:09:19 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.31 1999/11/17 15:53:39 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.30 1999/10/26 15:09:07 rgb + * Used debug compiler directives to shut up compiler for decl/assign + * statement. + * + * Revision 1.29 1999/10/16 18:25:37 rgb + * Moved SA lifetime expiry checks before packet processing. + * Expire SA on replay counter rollover. + * + * Revision 1.28 1999/10/16 04:23:07 rgb + * Add stats for replaywin_errs, replaywin_max_sequence_difference, + * authentication errors, encryption size errors, encryption padding + * errors, and time since last packet. + * + * Revision 1.27 1999/10/16 00:30:47 rgb + * Added SA lifetime counting. + * + * Revision 1.26 1999/10/15 22:14:37 rgb + * Add debugging. + * + * Revision 1.25 1999/10/08 18:37:34 rgb + * Fix end-of-line spacing to sate whining PHMs. + * + * Revision 1.24 1999/10/03 18:54:51 rgb + * Spinlock support for 2.3.xx. + * Don't forget to undo spinlocks on error! + * + * Revision 1.23 1999/10/01 15:44:53 rgb + * Move spinlock header include to 2.1> scope. + * + * Revision 1.22 1999/10/01 00:01:54 rgb + * Added tdb structure locking. + * + * Revision 1.21 1999/09/18 11:42:12 rgb + * Add Marc Boucher's tcpdump cloned packet fix. + * + * Revision 1.20 1999/09/17 23:50:25 rgb + * Add Marc Boucher's hard_header_len patches. + * + * Revision 1.19 1999/09/10 05:31:36 henry + * tentative fix for 2.0.38-crash bug (move chunk of new code into 2.2 #ifdef) + * + * Revision 1.18 1999/08/28 08:28:06 rgb + * Delete redundant sanity check. + * + * Revision 1.17 1999/08/28 02:00:58 rgb + * Add an extra sanity check for null skbs. + * + * Revision 1.16 1999/08/27 05:21:38 rgb + * Clean up skb->data/raw/nh/h manipulation. + * Add Marc Boucher's mods to aid tcpdump. + * + * Revision 1.15 1999/08/25 14:22:40 rgb + * Require 4-octet boundary check only for ESP. + * + * Revision 1.14 1999/08/11 08:36:44 rgb + * Add compiler directives to allow configuring out AH, ESP or transforms. + * + * Revision 1.13 1999/08/03 17:10:49 rgb + * Cosmetic fixes and clarification to debug output. + * + * Revision 1.12 1999/05/09 03:25:36 rgb + * Fix bug introduced by 2.2 quick-and-dirty patch. + * + * Revision 1.11 1999/05/08 21:23:57 rgb + * Add casting to silence the 2.2.x compile. + * + * Revision 1.10 1999/05/05 22:02:31 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.9 1999/04/29 15:18:01 rgb + * hange debugging to respond only to debug_rcv. + * Change gettdb parameter to a pointer to reduce stack loading and + * facilitate parameter sanity checking. + * + * Revision 1.8 1999/04/15 15:37:24 rgb + * Forward check changes from POST1_00 branch. + * + * Revision 1.4.2.2 1999/04/13 20:32:45 rgb + * Move null skb sanity check. + * Silence debug a bit more when off. + * Use stats more effectively. + * + * Revision 1.4.2.1 1999/03/30 17:10:32 rgb + * Update AH+ESP bugfix. + * + * Revision 1.7 1999/04/11 00:28:59 henry + * GPL boilerplate + * + * Revision 1.6 1999/04/06 04:54:27 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.5 1999/03/17 15:39:23 rgb + * Code clean-up. + * Bundling bug fix. + * ESP_NULL esphlen and IV bug fix. + * + * Revision 1.4 1999/02/17 16:51:02 rgb + * Ditch NET_IPIP dependancy. + * Decapsulate recursively for an entire bundle. + * + * Revision 1.3 1999/02/12 21:22:47 rgb + * Convert debugging printks to KLIPS_PRINT macro. + * Clean-up cruft. + * Process IPIP tunnels internally. + * + * Revision 1.2 1999/01/26 02:07:36 rgb + * Clean up debug code when switched off. + * Remove references to INET_GET_PROTOCOL. + * + * Revision 1.1 1999/01/21 20:29:11 rgb + * Converted from transform switching to algorithm switching. + * + * + * Id: ipsec_esp.c,v 1.16 1998/12/02 03:08:11 rgb Exp $ + * + * Log: ipsec_esp.c,v $ + * Revision 1.16 1998/12/02 03:08:11 rgb + * Fix incoming I/F bug in AH and clean up inconsistencies in the I/F + * discovery routine in both AH and ESP. + * + * Revision 1.15 1998/11/30 13:22:51 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.14 1998/11/10 05:55:37 rgb + * Add even more detail to 'wrong I/F' debug statement. + * + * Revision 1.13 1998/11/10 05:01:30 rgb + * Clean up debug output to be quiet when disabled. + * Add more detail to 'wrong I/F' debug statement. + * + * Revision 1.12 1998/10/31 06:39:32 rgb + * Fixed up comments in #endif directives. + * Tidied up debug printk output. + * Convert to addrtoa and satoa where possible. + * + * Revision 1.11 1998/10/27 00:49:30 rgb + * AH+ESP bundling bug has been squished. + * Cosmetic brace fixing in code. + * Newlines added before calls to ipsec_print_ip. + * Fix debug output function ID's. + * + * Revision 1.10 1998/10/22 06:37:22 rgb + * Fixed run-on error message to fit 80 columns. + * + * Revision 1.9 1998/10/20 02:41:04 rgb + * Fixed a replay window size sanity test bug. + * + * Revision 1.8 1998/10/19 18:55:27 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * \n bugfix to printk debug message. + * + * Revision 1.7 1998/10/09 04:23:03 rgb + * Fixed possible DoS caused by invalid transform called from an ESP + * packet. This should not be a problem when protocol is added to the SA. + * Sanity check added for null xf_input routine. Sanity check added for null + * socket buffer returned from xf_input routine. + * Added 'klips_debug' prefix to all klips printk debug statements. + * + * Revision 1.6 1998/07/14 15:56:04 rgb + * Set sdb->dev to virtual ipsec I/F. + * + * Revision 1.5 1998/06/30 18:07:46 rgb + * Change for ah/esp_protocol stuct visible only if module. + * + * Revision 1.4 1998/06/30 00:12:46 rgb + * Clean up a module compile error. + * + * Revision 1.3 1998/06/25 19:28:06 rgb + * Readjust premature unloading of module on packet receipt. + * Make protocol structure abailable to rest of kernel. + * Use macro for protocol number. + * + * Revision 1.2 1998/06/23 02:49:34 rgb + * Fix minor #include bug that prevented compiling without debugging. + * Added code to check for presence of IPIP protocol if an incoming packet + * is IPIP encapped. + * + * Revision 1.1 1998/06/18 21:27:44 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.9 1998/06/14 23:48:42 rgb + * Fix I/F name comparison oops bug. + * + * Revision 1.8 1998/06/11 07:20:04 rgb + * Stats fixed for rx_packets. + * + * Revision 1.7 1998/06/11 05:53:34 rgb + * Added stats for rx error and good packet reporting. + * + * Revision 1.6 1998/06/05 02:27:28 rgb + * Add rx_errors stats. + * Fix DoS bug: skb's not being freed on dropped packets. + * + * Revision 1.5 1998/05/27 21:21:29 rgb + * Fix DoS potential bug. skb was not being freed if the packet was bad. + * + * Revision 1.4 1998/05/18 22:31:37 rgb + * Minor change in debug output and comments. + * + * Revision 1.3 1998/04/21 21:29:02 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.2 1998/04/12 22:03:19 rgb + * Updated ESP-3DES-HMAC-MD5-96, + * ESP-DES-HMAC-MD5-96, + * AH-HMAC-MD5-96, + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository + * from old standards (RFC182[5-9] to new (as of March 1998) drafts. + * + * Fixed eroute references in /proc/net/ipsec*. + * + * Started to patch module unloading memory leaks in ipsec_netlink and + * radij tree unloading. + * + * Revision 1.1 1998/04/09 03:05:59 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:04 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * Minor cosmetic changes. + * + * Revision 0.3 1996/11/20 14:35:48 ji + * Minor Cleanup. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_rcv.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_rcv.h --- linux-2.4.29/net/ipsec/ipsec_rcv.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_rcv.h Wed Nov 19 03:29:41 2003 @@ -0,0 +1,180 @@ +/* + * + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_rcv.h,v 1.2 2003/11/19 02:29:41 mcr Exp $ + */ + +#define DB_RX_PKTRX 0x0001 +#define DB_RX_PKTRX2 0x0002 +#define DB_RX_DMP 0x0004 +#define DB_RX_TDB 0x0010 +#define DB_RX_XF 0x0020 +#define DB_RX_IPAD 0x0040 +#define DB_RX_INAU 0x0080 +#define DB_RX_OINFO 0x0100 +#define DB_RX_OINFO2 0x0200 +#define DB_RX_OH 0x0400 +#define DB_RX_REPLAY 0x0800 + +#ifdef __KERNEL__ +/* struct options; */ + +#define __NO_VERSION__ +#include +#include /* for CONFIG_IP_FORWARD */ +#include +#include + +extern int +#ifdef PROTO_HANDLER_SINGLE_PARM +ipsec_rcv(struct sk_buff *skb); +#else /* PROTO_HANDLER_SINGLE_PARM */ +ipsec_rcv(struct sk_buff *skb, +#ifdef NET_21 + unsigned short xlen); +#else /* NET_21 */ + struct device *dev, + struct options *opt, + __u32 daddr, + unsigned short len, + __u32 saddr, + int redo, + struct inet_protocol *protocol); +#endif /* NET_21 */ +#endif /* PROTO_HANDLER_SINGLE_PARM */ + +#ifdef CONFIG_IPSEC_DEBUG +extern int debug_rcv; +#endif /* CONFIG_IPSEC_DEBUG */ +extern int sysctl_ipsec_inbound_policy_check; +#endif /* __KERNEL__ */ + +/* + * $Log: ipsec_rcv.h,v $ + * Revision 1.2 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.14 2001/09/07 22:15:48 rgb + * Fix for removal of transport layer protocol handler arg in 2.4.4. + * + * Revision 1.13 2001/06/14 19:35:09 rgb + * Update copyright date. + * + * Revision 1.12 2001/03/16 07:36:44 rgb + * Fixed #endif comment to sate compiler. + * + * Revision 1.11 2000/09/21 04:34:21 rgb + * Moved declaration of sysctl_ipsec_inbound_policy_check outside + * CONFIG_IPSEC_DEBUG. (MB) + * + * Revision 1.10 2000/09/18 02:36:10 rgb + * Exported sysctl_ipsec_inbound_policy_check for skb_decompress(). + * + * Revision 1.9 2000/09/08 19:12:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.8 1999/11/18 04:09:19 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.7 1999/05/25 01:45:37 rgb + * Fix version macros for 2.0.x as a module. + * + * Revision 1.6 1999/05/08 21:24:27 rgb + * Add includes for 2.2.x include into net/ipv4/protocol.c + * + * Revision 1.5 1999/05/05 22:02:32 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.4 1999/04/11 00:28:59 henry + * GPL boilerplate + * + * Revision 1.3 1999/04/06 04:54:27 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.2 1999/01/22 20:06:59 rgb + * Fixed cut-and-paste error from ipsec_esp.h. + * + * Revision 1.1 1999/01/21 20:29:12 rgb + * Converted from transform switching to algorithm switching. + * + * Log: ipsec_esp.h,v + * Revision 1.4 1998/08/12 00:07:32 rgb + * Added data structures for new xforms: null, {,3}dessha1. + * + * Revision 1.3 1998/07/14 15:57:01 rgb + * Add #ifdef __KERNEL__ to protect kernel-only structures. + * + * Revision 1.2 1998/06/25 19:33:46 rgb + * Add prototype for protocol receive function. + * Rearrange for more logical layout. + * + * Revision 1.1 1998/06/18 21:27:45 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.6 1998/06/05 02:28:08 rgb + * Minor comment fix. + * + * Revision 1.5 1998/05/27 22:34:00 rgb + * Changed structures to accomodate key separation. + * + * Revision 1.4 1998/05/18 22:28:43 rgb + * Disable key printing facilities from /proc/net/ipsec_*. + * + * Revision 1.3 1998/04/21 21:29:07 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.2 1998/04/12 22:03:20 rgb + * Updated ESP-3DES-HMAC-MD5-96, + * ESP-DES-HMAC-MD5-96, + * AH-HMAC-MD5-96, + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository + * from old standards (RFC182[5-9] to new (as of March 1998) drafts. + * + * Fixed eroute references in /proc/net/ipsec*. + * + * Started to patch module unloading memory leaks in ipsec_netlink and + * radij tree unloading. + * + * Revision 1.1 1998/04/09 03:06:00 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:02 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.5 1997/06/03 04:24:48 ji + * Added ESP-3DES-MD5-96 transform. + * + * Revision 0.4 1997/01/15 01:28:15 ji + * Added definitions for new ESP transforms. + * + * Revision 0.3 1996/11/20 14:35:48 ji + * Minor Cleanup. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ + + diff -urN linux-2.4.29/net/ipsec/ipsec_sa.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_sa.c --- linux-2.4.29/net/ipsec/ipsec_sa.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_sa.c Wed Nov 19 03:29:41 2003 @@ -0,0 +1,789 @@ +/* + * Common routines for IPsec SA maintenance routines. + * + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_sa.c,v 1.6 2003/11/19 02:29:41 mcr Exp $ + * + * This is the file formerly known as "ipsec_xform.h" + * + */ + +#include +#include +#include /* printk() */ + +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include +#include /* get_random_bytes() */ +#include +#ifdef SPINLOCK +#ifdef SPINLOCK_23 +#include /* *lock* */ +#else /* SPINLOCK_23 */ +#include /* *lock* */ +#endif /* SPINLOCK_23 */ +#endif /* SPINLOCK */ +#ifdef NET_21 +#include +#include +#endif +#include +#include + +#include "radij.h" + +#include "ipsec_stats.h" +#include "ipsec_life.h" +#include "ipsec_sa.h" +#include "ipsec_xform.h" + +#include "ipsec_encap.h" +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_xform.h" +#include "ipsec_ipe4.h" +#include "ipsec_ah.h" +#include "ipsec_esp.h" + +#include +#include + +#include "ipsec_proto.h" +#include "ipsec_alg.h" + + +#ifdef CONFIG_IPSEC_DEBUG +int debug_xform = 0; +#endif /* CONFIG_IPSEC_DEBUG */ + +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) + +struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD]; +#ifdef SPINLOCK +spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED; +#else /* SPINLOCK */ +spinlock_t tdb_lock; +#endif /* SPINLOCK */ + +int +ipsec_sadb_init(void) +{ + int i; + + for(i = 1; i < SADB_HASHMOD; i++) { + ipsec_sadb_hash[i] = NULL; + } + return 0; +} + +struct ipsec_sa * +ipsec_sa_getbyid(struct sa_id *said) +{ + int hashval; + struct ipsec_sa *ips; + char sa[SATOA_BUF]; + size_t sa_len; + + if(!said) { + KLIPS_PRINT(debug_xform, + "klips_error:gettdb: " + "null pointer passed in!\n"); + return NULL; + } + + sa_len = satoa(*said, 0, sa, SATOA_BUF); + + hashval = (said->spi+said->dst.s_addr+said->proto) % SADB_HASHMOD; + + KLIPS_PRINT(debug_xform, + "klips_debug:gettdb: " + "linked entry in tdb table for hash=%d of SA:%s requested.\n", + hashval, + sa_len ? sa : " (error)"); + + if(!(ips = ipsec_sadb_hash[hashval])) { + KLIPS_PRINT(debug_xform, + "klips_debug:gettdb: " + "no entries in tdb table for hash=%d of SA:%s.\n", + hashval, + sa_len ? sa : " (error)"); + return NULL; + } + + for (; ips; ips = ips->ips_hnext) { + if ((ips->ips_said.spi == said->spi) && + (ips->ips_said.dst.s_addr == said->dst.s_addr) && + (ips->ips_said.proto == said->proto)) { + return ips; + } + } + + KLIPS_PRINT(debug_xform, + "klips_debug:gettdb: " + "no entry in linked list for hash=%d of SA:%s.\n", + hashval, + sa_len ? sa : " (error)"); + return NULL; +} + +/* + The tdb table better *NOT* be locked before it is handed in, or SMP locks will happen +*/ +int +ipsec_sa_put(struct ipsec_sa *ips) +{ + int error = 0; + unsigned int hashval; + + if(!ips) { + KLIPS_PRINT(debug_xform, + "klips_error:puttdb: " + "null pointer passed in!\n"); + return -ENODATA; + } + hashval = ((ips->ips_said.spi + ips->ips_said.dst.s_addr + ips->ips_said.proto) % SADB_HASHMOD); + + spin_lock_bh(&tdb_lock); + + ips->ips_hnext = ipsec_sadb_hash[hashval]; + ipsec_sadb_hash[hashval] = ips; + + spin_unlock_bh(&tdb_lock); + + return error; +} + +/* + The tdb table better be locked before it is handed in, or races might happen +*/ +int +ipsec_sa_del(struct ipsec_sa *ips) +{ + unsigned int hashval; + struct ipsec_sa *tdbtp; + char sa[SATOA_BUF]; + size_t sa_len; + + if(!ips) { + KLIPS_PRINT(debug_xform, + "klips_error:deltdb: " + "null pointer passed in!\n"); + return -ENODATA; + } + + sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); + if(ips->ips_inext || ips->ips_onext) { + KLIPS_PRINT(debug_xform, + "klips_error:deltdb: " + "SA:%s still linked!\n", + sa_len ? sa : " (error)"); + return -EMLINK; + } + + hashval = ((ips->ips_said.spi + ips->ips_said.dst.s_addr + ips->ips_said.proto) % SADB_HASHMOD); + + KLIPS_PRINT(debug_xform, + "klips_debug:deltdb: " + "deleting SA:%s, hashval=%d.\n", + sa_len ? sa : " (error)", + hashval); + if(!ipsec_sadb_hash[hashval]) { + KLIPS_PRINT(debug_xform, + "klips_debug:deltdb: " + "no entries in tdb table for hash=%d of SA:%s.\n", + hashval, + sa_len ? sa : " (error)"); + return -ENOENT; + } + + if (ips == ipsec_sadb_hash[hashval]) { + ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext; + ips->ips_hnext = NULL; + KLIPS_PRINT(debug_xform, + "klips_debug:deltdb: " + "successfully deleted first tdb in chain.\n"); + return 0; + } else { + for (tdbtp = ipsec_sadb_hash[hashval]; + tdbtp; + tdbtp = tdbtp->ips_hnext) { + if (tdbtp->ips_hnext == ips) { + tdbtp->ips_hnext = ips->ips_hnext; + ips->ips_hnext = NULL; + KLIPS_PRINT(debug_xform, + "klips_debug:deltdb: " + "successfully deleted link in tdb chain.\n"); + return 0; + } + } + } + + KLIPS_PRINT(debug_xform, + "klips_debug:deltdb: " + "no entries in linked list for hash=%d of SA:%s.\n", + hashval, + sa_len ? sa : " (error)"); + return -ENOENT; +} + +/* + The tdb table better be locked before it is handed in, or races might happen +*/ +int +ipsec_sa_delchain(struct ipsec_sa *ips) +{ + struct ipsec_sa *tdbdel; + int error = 0; + char sa[SATOA_BUF]; + size_t sa_len; + + if(!ips) { + KLIPS_PRINT(debug_xform, + "klips_error:deltdbchain: " + "null pointer passed in!\n"); + return -ENODATA; + } + + sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + "klips_debug:deltdbchain: " + "passed SA:%s\n", + sa_len ? sa : " (error)"); + while(ips->ips_onext) { + ips = ips->ips_onext; + } + + while(ips) { + /* XXX send a pfkey message up to advise of deleted TDB */ + sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + "klips_debug:deltdbchain: " + "unlinking and delting SA:%s", + sa_len ? sa : " (error)"); + tdbdel = ips; + ips = ips->ips_inext; + if(ips) { + sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + ", inext=%s", + sa_len ? sa : " (error)"); + tdbdel->ips_inext = NULL; + ips->ips_onext = NULL; + } + KLIPS_PRINT(debug_xform, + ".\n"); + if((error = ipsec_sa_del(tdbdel))) { + KLIPS_PRINT(debug_xform, + "klips_debug:deltdbchain: " + "deltdb returned error %d.\n", -error); + return error; + } + if((error = ipsec_sa_wipe(tdbdel))) { + KLIPS_PRINT(debug_xform, + "klips_debug:deltdbchain: " + "ipsec_tdbwipe returned error %d.\n", -error); + return error; + } + } + return error; +} + +int +ipsec_sadb_cleanup(__u8 proto) +{ + int i; + int error = 0; + struct ipsec_sa *ips, **ipsprev, *tdbdel; + char sa[SATOA_BUF]; + size_t sa_len; + + KLIPS_PRINT(debug_xform, + "klips_debug:ipsec_tdbcleanup: " + "cleaning up proto=%d.\n", + proto); + + spin_lock_bh(&tdb_lock); + + for (i = 0; i < SADB_HASHMOD; i++) { + ipsprev = &(ipsec_sadb_hash[i]); + ips = ipsec_sadb_hash[i]; + for(; ips;) { + sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + "klips_debug:ipsec_tdbcleanup: " + "checking SA:%s, hash=%d", + sa_len ? sa : " (error)", + i); + tdbdel = ips; + ips = tdbdel->ips_hnext; + if(ips) { + sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + ", hnext=%s", + sa_len ? sa : " (error)"); + } + if(*ipsprev) { + sa_len = satoa((*ipsprev)->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + ", *ipsprev=%s", + sa_len ? sa : " (error)"); + if((*ipsprev)->ips_hnext) { + sa_len = satoa((*ipsprev)->ips_hnext->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + ", *ipsprev->ips_hnext=%s", + sa_len ? sa : " (error)"); + } + } + KLIPS_PRINT(debug_xform, + ".\n"); + if(!proto || (proto == tdbdel->ips_said.proto)) { + sa_len = satoa(tdbdel->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + "klips_debug:ipsec_tdbcleanup: " + "deleting SA chain:%s.\n", + sa_len ? sa : " (error)"); + if((error = ipsec_sa_delchain(tdbdel))) { + SENDERR(-error); + } + ipsprev = &(ipsec_sadb_hash[i]); + ips = ipsec_sadb_hash[i]; + + KLIPS_PRINT(debug_xform, + "klips_debug:ipsec_tdbcleanup: " + "deleted SA chain:%s", + sa_len ? sa : " (error)"); + if(ips) { + sa_len = satoa(ips->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + ", tdbh[%d]=%s", + i, + sa_len ? sa : " (error)"); + } + if(*ipsprev) { + sa_len = satoa((*ipsprev)->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + ", *ipsprev=%s", + sa_len ? sa : " (error)"); + if((*ipsprev)->ips_hnext) { + sa_len = satoa((*ipsprev)->ips_hnext->ips_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_xform, + ", *ipsprev->ips_hnext=%s", + sa_len ? sa : " (error)"); + } + } + KLIPS_PRINT(debug_xform, + ".\n"); + } else { + ipsprev = &tdbdel; + } + } + } + errlab: + + spin_unlock_bh(&tdb_lock); + + return(error); +} + +int +ipsec_sa_wipe(struct ipsec_sa *ips) +{ + if(!ips) { + return -ENODATA; + } + + if(ips->ips_addr_s) { + memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size); + kfree(ips->ips_addr_s); + } + ips->ips_addr_s = NULL; + + if(ips->ips_addr_d) { + memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size); + kfree(ips->ips_addr_d); + } + ips->ips_addr_d = NULL; + + if(ips->ips_addr_p) { + memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size); + kfree(ips->ips_addr_p); + } + ips->ips_addr_p = NULL; + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if(ips->ips_natt_oa) { + memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size); + kfree(ips->ips_natt_oa); + } + ips->ips_natt_oa = NULL; +#endif + + if(ips->ips_key_a) { + memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size); + kfree(ips->ips_key_a); + } + ips->ips_key_a = NULL; + + if(ips->ips_key_e) { +#ifdef CONFIG_IPSEC_ALG + if (ips->ips_alg_enc&&ips->ips_alg_enc->ixt_e_destroy_key) { + ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc, + ips->ips_key_e); + } else { +#endif /* CONFIG_IPSEC_ALG */ + memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size); + kfree(ips->ips_key_e); +#ifdef CONFIG_IPSEC_ALG + } +#endif /* CONFIG_IPSEC_ALG */ + } + ips->ips_key_e = NULL; + + if(ips->ips_iv) { + memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size); + kfree(ips->ips_iv); + } + ips->ips_iv = NULL; + + if(ips->ips_ident_s.data) { + memset((caddr_t)(ips->ips_ident_s.data), + 0, + ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); + kfree(ips->ips_ident_s.data); + } + ips->ips_ident_s.data = NULL; + + if(ips->ips_ident_d.data) { + memset((caddr_t)(ips->ips_ident_d.data), + 0, + ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident)); + kfree(ips->ips_ident_d.data); + } + ips->ips_ident_d.data = NULL; + +#ifdef CONFIG_IPSEC_ALG + if (ips->ips_alg_enc||ips->ips_alg_auth) { + ipsec_alg_sa_wipe(ips); + } +#endif /* CONFIG_IPSEC_ALG */ + + memset((caddr_t)ips, 0, sizeof(*ips)); + kfree(ips); + ips = NULL; + + return 0; +} + +/* + * $Log: ipsec_sa.c,v $ + * Revision 1.6 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.5 2003/02/07 13:14:25 ken + * Pullin jjo's ALG 0.8.1rc branch + * + * Revision 1.4.2.1 2003/02/06 22:09:50 jjo + * sync to alg-0.8.1-rc4 + * + * Revision 1.4 2002/10/30 12:41:26 ken + * #ifdef around ipsec_alg_sa_wipe when not using ALGs + * + * Revision 1.3 2002/09/05 03:53:52 ken + * Added NAT-T Patch + * + * Revision 1.2 2002/09/05 03:27:08 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.5 2002/01/29 17:17:56 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.4 2002/01/29 04:00:52 mcr + * more excise of kversions.h header. + * + * Revision 1.3 2002/01/29 02:13:18 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.2 2001/11/26 09:16:15 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.1.2.2 2001/10/22 21:05:41 mcr + * removed phony prototype for des_set_key. + * + * Revision 1.1.2.1 2001/09/25 02:24:57 mcr + * struct tdb -> struct ipsec_sa. + * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c + * ipsec_xform.c removed. header file still contains useful things. + * + * + * + * CLONED from ipsec_xform.c: + * Revision 1.53 2001/09/08 21:13:34 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.52 2001/06/14 19:35:11 rgb + * Update copyright date. + * + * Revision 1.51 2001/05/30 08:14:03 rgb + * Removed vestiges of esp-null transforms. + * + * Revision 1.50 2001/05/03 19:43:18 rgb + * Initialise error return variable. + * Update SENDERR macro. + * Fix sign of error return code for ipsec_tdbcleanup(). + * Use more appropriate return code for ipsec_tdbwipe(). + * + * Revision 1.49 2001/04/19 18:56:17 rgb + * Fixed tdb table locking comments. + * + * Revision 1.48 2001/02/27 22:24:55 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.47 2000/11/06 04:32:08 rgb + * Ditched spin_lock_irqsave in favour of spin_lock_bh. + * + * Revision 1.46 2000/09/20 16:21:57 rgb + * Cleaned up ident string alloc/free. + * + * Revision 1.45 2000/09/08 19:16:51 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * Removed all references to CONFIG_IPSEC_PFKEYv2. + * + * Revision 1.44 2000/08/30 05:29:04 rgb + * Compiler-define out no longer used tdb_init() in ipsec_xform.c. + * + * Revision 1.43 2000/08/18 21:30:41 rgb + * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. + * + * Revision 1.42 2000/08/01 14:51:51 rgb + * Removed _all_ remaining traces of DES. + * + * Revision 1.41 2000/07/28 14:58:31 rgb + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. + * + * Revision 1.40 2000/06/28 05:50:11 rgb + * Actually set iv_bits. + * + * Revision 1.39 2000/05/10 23:11:09 rgb + * Added netlink debugging output. + * Added a cast to quiet down the ntohl bug. + * + * Revision 1.38 2000/05/10 19:18:42 rgb + * Cast output of ntohl so that the broken prototype doesn't make our + * compile noisy. + * + * Revision 1.37 2000/03/16 14:04:59 rgb + * Hardwired CONFIG_IPSEC_PFKEYv2 on. + * + * Revision 1.36 2000/01/26 10:11:28 rgb + * Fixed spacing in error text causing run-in words. + * + * Revision 1.35 2000/01/21 06:17:16 rgb + * Tidied up compiler directive indentation for readability. + * Added ictx,octx vars for simplification.(kravietz) + * Added macros for HMAC padding magic numbers.(kravietz) + * Fixed missing key length reporting bug. + * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in. + * + * Revision 1.34 1999/12/08 00:04:19 rgb + * Fixed SA direction overwriting bug for netlink users. + * + * Revision 1.33 1999/12/01 22:16:44 rgb + * Minor formatting changes in ESP MD5 initialisation. + * + * Revision 1.32 1999/11/25 09:06:36 rgb + * Fixed error return messages, should be returning negative numbers. + * Implemented SENDERR macro for propagating error codes. + * Added debug message and separate error code for algorithms not compiled + * in. + * + * Revision 1.31 1999/11/23 23:06:26 rgb + * Sort out pfkey and freeswan headers, putting them in a library path. + * + * Revision 1.30 1999/11/18 04:09:20 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.29 1999/11/17 15:53:40 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.28 1999/10/18 20:04:01 rgb + * Clean-out unused cruft. + * + * Revision 1.27 1999/10/03 19:01:03 rgb + * Spinlock support for 2.3.xx and 2.0.xx kernels. + * + * Revision 1.26 1999/10/01 16:22:24 rgb + * Switch from assignment init. to functional init. of spinlocks. + * + * Revision 1.25 1999/10/01 15:44:54 rgb + * Move spinlock header include to 2.1> scope. + * + * Revision 1.24 1999/10/01 00:03:46 rgb + * Added tdb structure locking. + * Minor formatting changes. + * Add function to initialize tdb hash table. + * + * Revision 1.23 1999/05/25 22:42:12 rgb + * Add deltdbchain() debugging. + * + * Revision 1.22 1999/05/25 21:24:31 rgb + * Add debugging statements to deltdbchain(). + * + * Revision 1.21 1999/05/25 03:51:48 rgb + * Refix error return code. + * + * Revision 1.20 1999/05/25 03:34:07 rgb + * Fix error return for flush. + * + * Revision 1.19 1999/05/09 03:25:37 rgb + * Fix bug introduced by 2.2 quick-and-dirty patch. + * + * Revision 1.18 1999/05/05 22:02:32 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.17 1999/04/29 15:20:16 rgb + * Change gettdb parameter to a pointer to reduce stack loading and + * facilitate parameter sanity checking. + * Add sanity checking for null pointer arguments. + * Add debugging instrumentation. + * Add function deltdbchain() which will take care of unlinking, + * zeroing and deleting a chain of tdbs. + * Add a parameter to tdbcleanup to be able to delete a class of SAs. + * tdbwipe now actually zeroes the tdb as well as any of its pointed + * structures. + * + * Revision 1.16 1999/04/16 15:36:29 rgb + * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing. + * + * Revision 1.15 1999/04/11 00:29:01 henry + * GPL boilerplate + * + * Revision 1.14 1999/04/06 04:54:28 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.13 1999/02/19 18:23:01 rgb + * Nix debug off compile warning. + * + * Revision 1.12 1999/02/17 16:52:16 rgb + * Consolidate satoa()s for space and speed efficiency. + * Convert DEBUG_IPSEC to KLIPS_PRINT + * Clean out unused cruft. + * Ditch NET_IPIP dependancy. + * Loop for 3des key setting. + * + * Revision 1.11 1999/01/26 02:09:05 rgb + * Remove ah/esp/IPIP switching on include files. + * Removed CONFIG_IPSEC_ALGO_SWITCH macro. + * Removed dead code. + * Clean up debug code when switched off. + * Remove references to INET_GET_PROTOCOL. + * Added code exclusion macros to reduce code from unused algorithms. + * + * Revision 1.10 1999/01/22 06:28:55 rgb + * Cruft clean-out. + * Put random IV generation in kernel. + * Added algorithm switch code. + * Enhanced debugging. + * 64-bit clean-up. + * + * Revision 1.9 1998/11/30 13:22:55 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.8 1998/11/25 04:59:06 rgb + * Add conditionals for no IPIP tunnel code. + * Delete commented out code. + * + * Revision 1.7 1998/10/31 06:50:41 rgb + * Convert xform ASCII names to no spaces. + * Fixed up comments in #endif directives. + * + * Revision 1.6 1998/10/19 14:44:28 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * + * Revision 1.5 1998/10/09 04:32:19 rgb + * Added 'klips_debug' prefix to all klips printk debug statements. + * + * Revision 1.4 1998/08/12 00:11:31 rgb + * Added new xform functions to the xform table. + * Fixed minor debug output spelling error. + * + * Revision 1.3 1998/07/09 17:45:31 rgb + * Clarify algorithm not available message. + * + * Revision 1.2 1998/06/23 03:00:51 rgb + * Check for presence of IPIP protocol if it is setup one way (we don't + * know what has been set up the other way and can only assume it will be + * symmetrical with the exception of keys). + * + * Revision 1.1 1998/06/18 21:27:51 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.3 1998/06/11 05:54:59 rgb + * Added transform version string pointer to xformsw initialisations. + * + * Revision 1.2 1998/04/21 21:28:57 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.1 1998/04/09 03:06:13 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:02 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.5 1997/06/03 04:24:48 ji + * Added ESP-3DES-MD5-96 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * Added new transforms. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_sa.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_sa.h --- linux-2.4.29/net/ipsec/ipsec_sa.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_sa.h Thu Sep 5 05:53:52 2002 @@ -0,0 +1,215 @@ +/* + * @(#) Definitions of IPsec Security Association (ipsec_sa) + * + * Copyright (C) 2001 Richard Guy Briggs + * and Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_sa.h,v 1.3 2002/09/05 03:53:52 ken Exp $ + * + * This file derived from ipsec_xform.h on 2001/9/18 by mcr. + * + */ + +/* + * This file describes the IPsec Security Association Structure. + * + * This structure keeps track of a single transform that may be done + * to a set of packets. It can describe applying the transform or + * apply the reverse. (e.g. compression vs expansion). However, it + * only describes one at a time. To describe both, two structures would + * be used, but since the sides of the transform are performed + * on different machines typically it is usual to have only one side + * of each association. + * + */ + +#ifndef _IPSEC_SA_H_ + +#include "ipsec_stats.h" +#include "ipsec_life.h" +#include "ipsec_eroute.h" + +/* 'struct ipsec_sa' should be 64bit aligned when allocated. */ +struct ipsec_sa +{ + atomic_t ips_usecount; /* use count for this struct */ + struct ipsec_sa *ips_hnext; /* next in hash chain */ + struct ipsec_sa *ips_inext; /* pointer to next xform */ + struct ipsec_sa *ips_onext; /* pointer to prev xform */ + + struct ifnet *ips_rcvif; /* related rcv encap interface */ + + struct sa_id ips_said; /* SA ID */ + + __u32 ips_seq; /* seq num of msg that initiated this SA */ + __u32 ips_pid; /* PID of process that initiated this SA */ + __u8 ips_authalg; /* auth algorithm for this SA */ + __u8 ips_encalg; /* enc algorithm for this SA */ + + struct ipsec_stats ips_errs; + + __u8 ips_replaywin; /* replay window size */ + __u8 ips_state; /* state of SA */ + __u32 ips_replaywin_lastseq; /* last pkt sequence num */ + __u64 ips_replaywin_bitmap; /* bitmap of received pkts */ + __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */ + + __u32 ips_flags; /* generic xform flags */ + + + struct ipsec_lifetimes ips_life; /* lifetime records */ + + /* selector information */ + struct sockaddr*ips_addr_s; /* src sockaddr */ + struct sockaddr*ips_addr_d; /* dst sockaddr */ + struct sockaddr*ips_addr_p; /* proxy sockaddr */ + __u16 ips_addr_s_size; + __u16 ips_addr_d_size; + __u16 ips_addr_p_size; + ip_address ips_flow_s; + ip_address ips_flow_d; + ip_address ips_mask_s; + ip_address ips_mask_d; + + __u16 ips_key_bits_a; /* size of authkey in bits */ + __u16 ips_auth_bits; /* size of authenticator in bits */ + __u16 ips_key_bits_e; /* size of enckey in bits */ + __u16 ips_iv_bits; /* size of IV in bits */ + __u8 ips_iv_size; + __u16 ips_key_a_size; + __u16 ips_key_e_size; + + caddr_t ips_key_a; /* authentication key */ + caddr_t ips_key_e; /* encryption key */ + caddr_t ips_iv; /* Initialisation Vector */ + + struct ident ips_ident_s; /* identity src */ + struct ident ips_ident_d; /* identity dst */ + +#ifdef CONFIG_IPSEC_IPCOMP + __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */ + __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */ + __u64 ips_comp_ratio_cbytes; /* compressed bytes */ + __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */ +#endif /* CONFIG_IPSEC_IPCOMP */ + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + __u8 ips_natt_type; + __u8 ips_natt_reserved[3]; + __u16 ips_natt_sport; + __u16 ips_natt_dport; + + struct sockaddr *ips_natt_oa; + __u16 ips_natt_oa_size; + __u16 ips_natt_reserved2; +#endif + +#if 0 + __u32 ips_sens_dpd; + __u8 ips_sens_sens_level; + __u8 ips_sens_sens_len; + __u64* ips_sens_sens_bitmap; + __u8 ips_sens_integ_level; + __u8 ips_sens_integ_len; + __u64* ips_sens_integ_bitmap; +#endif + struct ipsec_alg_enc *ips_alg_enc; + struct ipsec_alg_auth *ips_alg_auth; +}; + +enum ipsec_direction { + ipsec_incoming = 1, + ipsec_outgoing = 2 +}; + +#ifdef IPSEC_KLIPS1_COMPAT +#define tdb_hnext ips_hnext +#define tdb_inext ips_inext +#define tdb_onext ips_onext +#define tdb_said ips_said +#define tdb_addr_s ips_addr_s +#define tdb_addr_s_size ips_addr_s_size +#define tdb_addr_d ips_addr_d +#define tdb_addr_d_size ips_addr_d_size +#define tdb_addr_p ips_addr_p +#define tdb_addr_p_size ips_addr_p_size +#define tdb_ident_s ips_ident_s +#define tdb_ident_d ips_ident_d +#define tdb_state ips_state + +#define tdb_replaywin ips_replaywin +#define tdb_replaywin_lastseq ips_replaywin_lastseq +#define tdb_replaywin_bitmap ips_replaywin_bitmap +#define tdb_replaywin_maxdiff ips_replaywin_maxdiff +#define tdb_replaywin_errs ips_errs.ips_replaywin_errs + +#define tdb_encalg ips_encalg +#define tdb_encsize_errs ips_errs.ips_encsize_errs +#define tdb_encpad_errs ips_errs.ips_encpad_errs +#define tdb_alg_errs ips_errs.ips_alg_errs +#define tdb_authalg ips_authalg +#define tdb_auth_errs ips_errs.ips_auth_errs +#define tdb_iv ips_iv +#define tdb_iv_size ips_iv_size +#define tdb_iv_bits ips_iv_bits +#define tdb_key_e ips_key_e +#define tdb_key_e_size ips_key_e_size +#define tdb_key_bits_e ips_key_bits_e +#define tdb_key_bits_a ips_key_bits_a +#define tdb_key_a ips_key_a +#define tdb_auth_bits ips_auth_bits +#define tdb_key_a_size ips_key_a_size + +#define tdb_comp_ratio_cbytes ips_comp_ratio_cbytes +#define tdb_comp_ratio_dbytes ips_comp_ratio_dbytes +#define tdb_comp_adapt_tries ips_comp_adapt_tries +#define tdb_comp_adapt_skip ips_comp_adapt_skip + +#define tdb_mask_s ips_mask_s +#define tdb_flow_s ips_flow_s +#define tdb_mask_d ips_mask_d +#define tdb_flow_d ips_flow_d + +#define tdb_flags ips_flags +#define tdb_rcvif ips_rcvif + +#endif /* IPSEC_KLIPS1_COMPAT */ + +#define _IPSEC_SA_H +#endif /* _IPSEC_SA_H_ */ + +/* + * $Log: ipsec_sa.h,v $ + * Revision 1.3 2002/09/05 03:53:52 ken + * Added NAT-T Patch + * + * Revision 1.2 2002/09/05 03:27:08 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.2 2001/11/26 09:16:15 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.1.2.1 2001/09/25 02:24:58 mcr + * struct tdb -> struct ipsec_sa. + * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c + * ipsec_xform.c removed. header file still contains useful things. + * + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_sha1.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_sha1.c --- linux-2.4.29/net/ipsec/ipsec_sha1.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_sha1.c Thu Sep 5 05:13:17 2002 @@ -0,0 +1,204 @@ +/* + * RCSID $Id: ipsec_sha1.c,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + */ + +/* + * The rest of the code is derived from sha1.c by Steve Reid, which is + * public domain. + * Minor cosmetic changes to accomodate it in the Linux kernel by ji. + */ + +#include +#include + +#include "ipsec_sha1.h" + +#if defined(rol) +#undef rol +#endif + +#define SHA1HANDSOFF + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#ifdef __LITTLE_ENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ + |(rol(block->l[i],8)&0x00FF00FF)) +#else +#define blk0(i) block->l[i] +#endif +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform(__u32 state[5], __u8 buffer[64]) +{ +__u32 a, b, c, d, e; +typedef union { + unsigned char c[64]; + __u32 l[16]; +} CHAR64LONG16; +CHAR64LONG16* block; +#ifdef SHA1HANDSOFF +static unsigned char workspace[64]; + block = (CHAR64LONG16*)workspace; + memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16*)buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + 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); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ + +void SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void SHA1Update(SHA1_CTX* context, unsigned char* data, __u32 len) +{ +__u32 i, j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1]++; + context->count[1] += (len>>29); + j = (j >> 3) & 63; + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* Add padding and return the message digest. */ + +void SHA1Final(unsigned char digest[20], SHA1_CTX* context) +{ +__u32 i, j; +unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1Update(context, (unsigned char *)"\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1Update(context, (unsigned char *)"\0", 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + i = j = 0; + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(&finalcount, 0, 8); +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */ + SHA1Transform(context->state, context->buffer); +#endif +} + + +/* + * $Log: ipsec_sha1.c,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.5 1999/12/13 13:59:13 rgb + * Quick fix to argument size to Update bugs. + * + * Revision 1.4 1999/04/11 00:29:00 henry + * GPL boilerplate + * + * Revision 1.3 1999/04/06 04:54:27 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.2 1999/01/22 06:55:50 rgb + * 64-bit clean-up. + * + * Revision 1.1 1998/06/18 21:27:50 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.2 1998/04/23 20:54:04 rgb + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when + * verified. + * + * Revision 1.1 1998/04/09 03:06:11 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:05 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * New transform + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_sha1.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_sha1.h --- linux-2.4.29/net/ipsec/ipsec_sha1.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_sha1.h Thu Sep 5 05:13:17 2002 @@ -0,0 +1,71 @@ +/* + * RCSID $Id: ipsec_sha1.h,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + */ + +/* + * Here is the original comment from the distribution: + +SHA-1 in C +By Steve Reid +100% Public Domain + + * Adapted for use by the IPSEC code by John Ioannidis + */ + + +#ifndef _IPSEC_SHA1_H_ +#define _IPSEC_SHA1_H_ + +typedef struct +{ + __u32 state[5]; + __u32 count[2]; + __u8 buffer[64]; +} SHA1_CTX; + +void SHA1Transform(__u32 state[5], __u8 buffer[64]); +void SHA1Init(SHA1_CTX *context); +void SHA1Update(SHA1_CTX *context, unsigned char *data, __u32 len); +void SHA1Final(unsigned char digest[20], SHA1_CTX *context); + + +#endif /* _IPSEC_SHA1_H_ */ + +/* + * $Log: ipsec_sha1.h,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.5 1999/12/13 13:59:13 rgb + * Quick fix to argument size to Update bugs. + * + * Revision 1.4 1999/12/07 18:16:23 rgb + * Fixed comments at end of #endif lines. + * + * Revision 1.3 1999/04/06 04:54:27 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.2 1998/11/30 13:22:54 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.1 1998/06/18 21:27:50 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.2 1998/04/23 20:54:05 rgb + * Fixed md5 and sha1 include file nesting issues, to be cleaned up when + * verified. + * + * Revision 1.1 1998/04/09 03:04:21 henry + * sources moved up from linux/net/ipsec + * these two include files modified not to include others except in kernel + * + * Revision 1.1.1.1 1998/04/08 05:35:04 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * New transform + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_stats.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_stats.h --- linux-2.4.29/net/ipsec/ipsec_stats.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_stats.h Thu Apr 1 20:57:09 2004 @@ -0,0 +1,61 @@ +/* + * @(#) definition of ipsec_stats structure + * + * Copyright (C) 2001 Richard Guy Briggs + * and Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_stats.h,v 1.2 2004/04/01 18:57:09 paul Exp $ + * + */ + +/* + * This file describes the errors/statistics that FreeSWAN collects. + */ + +#ifndef _IPSEC_STATS_H_ + +struct ipsec_stats { + __u32 ips_alg_errs; /* number of algorithm errors */ + __u32 ips_auth_errs; /* # of authentication errors */ + __u32 ips_encsize_errs; /* # of encryption size errors*/ + __u32 ips_encpad_errs; /* # of encryption pad errors*/ + __u32 ips_replaywin_errs; /* # of pkt sequence errors */ +}; + +extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...); + +#define _IPSEC_STATS_H_ +#endif /* _IPSEC_STATS_H_ */ + +/* + * $Log: ipsec_stats.h,v $ + * Revision 1.2 2004/04/01 18:57:09 paul + * sprintf->ipsec_snprintf fixes by mcr,dhr,sam backported to openswan-1. This + * is needed to properly run on 2.4.25+ + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.2 2001/11/26 09:16:16 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.1.2.1 2001/09/25 02:27:00 mcr + * statistics moved to seperate structure. + * + * + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_tunnel.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_tunnel.c --- linux-2.4.29/net/ipsec/ipsec_tunnel.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_tunnel.c Thu Dec 4 04:03:24 2003 @@ -0,0 +1,4179 @@ +/* + * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +char ipsec_tunnel_c_version[] = "RCSID $Id: ipsec_tunnel.c,v 1.18 2003/12/04 03:03:24 ken Exp $"; + +#define __NO_VERSION__ +#include +#include /* for CONFIG_IP_FORWARD */ +#include +#include /* printk() */ + +/* XXX-mcr remove this definition when the code has been properly rototiled */ +#define IPSEC_KLIPS1_COMPAT 1 +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include /* struct tcphdr */ +#include /* struct udphdr */ +#include +#include +#ifdef NET_21 +# define MSS_HACK_ /* experimental */ +# include +# include +# define ip_chk_addr inet_addr_type +# define IS_MYADDR RTN_LOCAL +# include +# undef dev_kfree_skb +# define dev_kfree_skb(a,b) kfree_skb(a) +# define proto_priv cb +# define PHYSDEV_TYPE +#endif /* NET_21 */ +#include +#include /* icmp_send() */ +#include +#ifdef NETDEV_23 +# include +#endif /* NETDEV_23 */ + +#include "ipsec_alg.h" + +#include +#ifdef MSS_HACK +# include /* TCP options */ +#endif /* MSS_HACK */ + +#include "radij.h" +#include "ipsec_life.h" +#include "ipsec_xform.h" +#include "ipsec_eroute.h" +#include "ipsec_encap.h" +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_sa.h" +#include "ipsec_tunnel.h" +#include "ipsec_ipe4.h" +#include "ipsec_ah.h" +#include "ipsec_esp.h" + +#ifdef CONFIG_IPSEC_IPCOMP +# include "ipcomp.h" +#endif /* CONFIG_IPSEC_IPCOMP */ + +#include +#include + +#include "ipsec_proto.h" + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL +#include +#endif + +static __u32 zeroes[64]; + +#ifdef CONFIG_IPSEC_DEBUG +int debug_tunnel = 0; +int sysctl_ipsec_debug_verbose = 0; +#endif /* CONFIG_IPSEC_DEBUG */ + +int sysctl_ipsec_icmp = 0; +int sysctl_ipsec_tos = 0; + +/* + * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps + * source and destination ports to those from the TCP/UDP header. + */ +static void extract_ports(struct iphdr * iph, struct sockaddr_encap * er) +{ + struct udphdr *udp; + + switch (iph->protocol) { + case IPPROTO_UDP: + case IPPROTO_TCP: + /* + * The ports are at the same offsets in a TCP and UDP + * header so hack it ... + */ + udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2)); + er->sen_sport = udp->source; + er->sen_dport = udp->dest; + break; + default: + er->sen_sport = 0; + er->sen_dport = 0; + break; + } +} + +/* + * A TRAP eroute is installed and we want to replace it with a HOLD + * eroute. + */ +static int create_hold_eroute(struct sk_buff * skb, struct iphdr * iph, + uint32_t eroute_pid) +{ + struct eroute hold_eroute; + struct sa_id hold_said; + struct sk_buff *first, *last; + int error; + + first = last = NULL; + memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute)); + memset((caddr_t)&hold_said, 0, sizeof(hold_said)); + + hold_said.proto = IPPROTO_INT; + hold_said.spi = htonl(SPI_HOLD); + hold_said.dst.s_addr = INADDR_ANY; + + hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap); + hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap); + hold_eroute.er_eaddr.sen_family = AF_ENCAP; + hold_eroute.er_emask.sen_family = AF_ENCAP; + hold_eroute.er_eaddr.sen_type = SENT_IP4; + hold_eroute.er_emask.sen_type = 255; + + hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr; + hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr; + hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST; + hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST; + hold_eroute.er_emask.sen_sport = ~0; + hold_eroute.er_emask.sen_dport = ~0; + hold_eroute.er_pid = eroute_pid; + hold_eroute.er_count = 0; + hold_eroute.er_lasttime = jiffies/HZ; + + hold_eroute.er_eaddr.sen_proto = iph->protocol; + extract_ports(iph, &hold_eroute.er_eaddr); + +#ifdef CONFIG_IPSEC_DEBUG + if (debug_pfkey) { + char buf1[64], buf2[64]; + subnettoa(hold_eroute.er_eaddr.sen_ip_src, + hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); + subnettoa(hold_eroute.er_eaddr.sen_ip_dst, + hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_tunnel_start_xmit: " + "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n", + buf1, ntohs(hold_eroute.er_eaddr.sen_sport), + buf2, ntohs(hold_eroute.er_eaddr.sen_dport), + hold_eroute.er_eaddr.sen_proto); + } +#endif /* CONFIG_IPSEC_DEBUG */ + + if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask), + &first, &last)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_tunnel_start_xmit: " + "HOLD breakeroute found nothing.\n"); + } else { + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_tunnel_start_xmit: " + "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n", + NIPQUAD(hold_eroute.er_eaddr.sen_ip_src), + ntohs(hold_eroute.er_eaddr.sen_sport), + NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst), + ntohs(hold_eroute.er_eaddr.sen_dport), + hold_eroute.er_eaddr.sen_proto); + } + if (first != NULL) + kfree_skb(first); + if (last != NULL) + kfree_skb(last); + + error = ipsec_makeroute(&(hold_eroute.er_eaddr), + &(hold_eroute.er_emask), + hold_said, eroute_pid, skb, NULL, NULL); + if (error) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_tunnel_start_xmit: " + "HOLD makeroute returned %d, failed.\n", error); + } else { + KLIPS_PRINT(debug_pfkey, + "klips_debug:ipsec_tunnel_start_xmit: " + "HOLD makeroute call successful.\n"); + } + return (error == 0); +} + + + +#ifdef CONFIG_IPSEC_DEBUG_ +DEBUG_NO_STATIC void +dmp(char *s, caddr_t bb, int len) +{ + int i; + unsigned char *b = bb; + + if (debug_tunnel) { + printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: " + "at %s, len=%d:", + s, + len); + for (i=0; i < len; i++) { + if(!(i%16)){ + printk("\nklips_debug: "); + } + printk(" %02x", *b++); + } + printk("\n"); + } +} +#else /* CONFIG_IPSEC_DEBUG */ +#define dmp(_x, _y, _z) +#endif /* CONFIG_IPSEC_DEBUG */ + +#ifndef SKB_COPY_EXPAND +/* + * This is mostly skbuff.c:skb_copy(). + */ +struct sk_buff * +skb_copy_expand(struct sk_buff *skb, int headroom, int tailroom, int priority) +{ + struct sk_buff *n; + unsigned long offset; + + /* + * Do sanity checking + */ + if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) { + printk(KERN_WARNING + "klips_error:skb_copy_expand: " + "Illegal negative head,tailroom %d,%d\n", + headroom, + tailroom); + return NULL; + } + /* + * Allocate the copy buffer + */ + +#ifndef NET_21 + IS_SKB(skb); +#endif /* !NET_21 */ + + + n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority); + + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:skb_copy_expand: " + "head=%p data=%p tail=%p end=%p end-head=%d tail-data=%d\n", + skb->head, + skb->data, + skb->tail, + skb->end, + skb->end - skb->head, + skb->tail - skb->data); + + if(n==NULL) + return NULL; + + /* + * Shift between the two data areas in bytes + */ + + /* offset=n->head-skb->head; */ /* moved down a few lines */ + + /* Set the data pointer */ + skb_reserve(n,skb->data-skb->head+headroom); + /* Set the tail pointer and length */ + if(skb_tailroom(n) < skb->len) { + printk(KERN_WARNING "klips_error:skb_copy_expand: " + "tried to skb_put %ld, %d available. This should never happen, please report.\n", + (unsigned long int)skb->len, + skb_tailroom(n)); + dev_kfree_skb(n, FREE_WRITE); + return NULL; + } + skb_put(n,skb->len); + + offset=n->head + headroom - skb->head; + + /* Copy the bytes */ + memcpy(n->head + headroom, skb->head,skb->end-skb->head); +#ifdef NET_21 + n->csum=skb->csum; + n->priority=skb->priority; + n->dst=dst_clone(skb->dst); + if(skb->nh.raw) + n->nh.raw=skb->nh.raw+offset; +#ifndef NETDEV_23 + n->is_clone=0; +#endif /* NETDEV_23 */ + atomic_set(&n->users, 1); + n->destructor = NULL; + n->security=skb->security; +#else /* NET_21 */ + n->link3=NULL; + n->when=skb->when; + if(skb->ip_hdr) + n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset); + n->saddr=skb->saddr; + n->daddr=skb->daddr; + n->raddr=skb->raddr; + n->seq=skb->seq; + n->end_seq=skb->end_seq; + n->ack_seq=skb->ack_seq; + n->acked=skb->acked; + n->free=1; + n->arp=skb->arp; + n->tries=0; + n->lock=0; + n->users=0; +#endif /* NET_21 */ + n->protocol=skb->protocol; + n->list=NULL; + n->sk=NULL; + n->dev=skb->dev; + if(skb->h.raw) + n->h.raw=skb->h.raw+offset; + if(skb->mac.raw) + n->mac.raw=skb->mac.raw+offset; + memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv)); +#ifndef NETDEV_23 + n->used=skb->used; +#endif /* !NETDEV_23 */ + n->pkt_type=skb->pkt_type; + n->stamp=skb->stamp; + +#ifndef NET_21 + IS_SKB(n); +#endif /* !NET_21 */ + return n; +} +#endif /* !SKB_COPY_EXPAND */ + +#ifdef CONFIG_IPSEC_DEBUG +void +ipsec_print_ip(struct iphdr *ip) +{ + char buf[ADDRTOA_BUF]; + + printk(KERN_INFO "klips_debug: IP:"); + printk(" ihl:%d", ip->ihl*4); + printk(" ver:%d", ip->version); + printk(" tos:%d", ip->tos); + printk(" tlen:%d", ntohs(ip->tot_len)); + printk(" id:%d", ntohs(ip->id)); + printk(" %s%s%sfrag_off:%d", + ip->frag_off & __constant_htons(IP_CE) ? "CE " : "", + ip->frag_off & __constant_htons(IP_DF) ? "DF " : "", + ip->frag_off & __constant_htons(IP_MF) ? "MF " : "", + (ntohs(ip->frag_off) & IP_OFFSET) << 3); + printk(" ttl:%d", ip->ttl); + printk(" proto:%d", ip->protocol); + if(ip->protocol == IPPROTO_UDP) + printk(" (UDP)"); + if(ip->protocol == IPPROTO_TCP) + printk(" (TCP)"); + if(ip->protocol == IPPROTO_ICMP) + printk(" (ICMP)"); + printk(" chk:%d", ntohs(ip->check)); + addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf)); + printk(" saddr:%s", buf); + if(ip->protocol == IPPROTO_UDP) + printk(":%d", + ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source)); + if(ip->protocol == IPPROTO_TCP) + printk(":%d", + ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source)); + addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf)); + printk(" daddr:%s", buf); + if(ip->protocol == IPPROTO_UDP) + printk(":%d", + ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest)); + if(ip->protocol == IPPROTO_TCP) + printk(":%d", + ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest)); + if(ip->protocol == IPPROTO_ICMP) + printk(" type:code=%d:%d", + ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type, + ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code); + printk("\n"); + + if(sysctl_ipsec_debug_verbose) { + __u8 *c; + int i; + + c = ((__u8*)ip) + ip->ihl*4; + for(i = 0; i < ntohs(ip->tot_len) - ip->ihl*4; i++ /*, c++*/) { + if(!(i % 16)) { + printk(KERN_INFO + "klips_debug: @%03x:", + i); + } + printk(" %02x", /***/c[i]); + if(!((i + 1) % 16)) { + printk("\n"); + } + } + if(i % 16) { + printk("\n"); + } + } +} +#endif /* CONFIG_IPSEC_DEBUG */ + +#ifdef REAL_LOCKING_P +/* + * Locking + */ + +#if 0 +DEBUG_NO_STATIC int +ipsec_tunnel_lock(struct ipsecpriv *prv) +{ + unsigned long flags; + save_flags(flags); + cli(); + /* + * Lock in an interrupt may fail + */ + if(prv->locked && in_interrupt()) { + restore_flags(flags); + return 0; + } + while(prv->locked) + sleep_on(&prv->wait_queue); + prv->locked=1; + restore_flags(flags); + return 1; +} +#endif + +#if 0 +DEBUG_NO_STATIC void +ipsec_tunnel_unlock(struct ipsecpriv *prv) +{ + prv->locked=0; + wake_up(&prv->wait_queue); +} +#endif +#endif /* REAL_LOCKING_P */ + +DEBUG_NO_STATIC int +ipsec_tunnel_open(struct device *dev) +{ + struct ipsecpriv *prv = dev->priv; + + /* + * Can't open until attached. + */ + + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_open: " + "dev = %s, prv->dev = %s\n", + dev->name, prv->dev?prv->dev->name:"NONE"); + + if (prv->dev == NULL) + return -ENODEV; + + MOD_INC_USE_COUNT; + return 0; +} + +DEBUG_NO_STATIC int +ipsec_tunnel_close(struct device *dev) +{ + MOD_DEC_USE_COUNT; + return 0; +} + +#ifdef MSS_HACK +/* + * Issues: + * 1) Fragments arriving in the tunnel should probably be rejected. + * 2) How does this affect syncookies, mss_cache, dst cache ? + * 3) Path MTU discovery handling needs to be reviewed. For example, + * if we receive an ICMP 'packet too big' message from an intermediate + * router specifying it's next hop MTU, our stack may process this and + * adjust the MSS without taking our AH/ESP overheads into account. + */ + + +/* + * Recaclulate checksum using differences between changed datum, + * borrowed from netfilter. + */ +DEBUG_NO_STATIC u_int16_t +ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck) +{ + u_int32_t diffs[] = { oldvalinv, newval }; + return csum_fold(csum_partial((char *)diffs, sizeof(diffs), + oldcheck^0xFFFF)); +} + +/* + * Determine effective MSS. + * + * Note that we assume that there is always an MSS option for our own + * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x. + * This could change, and we should probably parse TCP options instead. + * + */ +DEBUG_NO_STATIC u_int8_t +ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu) +{ + u_int16_t oldmss, newmss; + u_int32_t *mssp; + struct sock *sk = skb->sk; + + newmss = tcp_sync_mss(sk, mtu); + printk(KERN_INFO "klips: setting mss to %u\n", newmss); + mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t); + oldmss = ntohl(*mssp) & 0x0000FFFF; + *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss); + tcph->check = ipsec_fast_csum(htons(~oldmss), + htons(newmss), tcph->check); + return 1; +} +#endif /* MSS_HACK */ + +#ifdef NETDEV_23 +static inline int ipsec_tunnel_xmit2(struct sk_buff *skb) +{ + return ip_send(skb); +} +#endif /* NETDEV_23 */ + +/* + * This function assumes it is being called from dev_queue_xmit() + * and that skb is filled properly by that function. + */ + +int +ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev) +{ + struct ipsecpriv *prv; /* Our device' private space */ + struct sk_buff *oskb = NULL; /* Original skb pointer */ + struct net_device_stats *stats; /* This device's statistics */ + struct iphdr *iph; /* Our new IP header */ + __u32 newdst; /* The other SG's IP address */ + __u32 orgdst; /* Original IP destination address */ + __u32 orgedst; /* 1st SG's IP address */ + __u32 newsrc; /* The new source SG's IP address */ + __u32 orgsrc; /* Original IP source address */ + __u32 innersrc; /* Innermost IP source address */ + int iphlen; /* IP header length */ + int pyldsz; /* upper protocol payload size */ + int headroom; + int tailroom; + int max_headroom = 0; /* The extra header space needed */ + int max_tailroom = 0; /* The extra stuffing needed */ + int ll_headroom; /* The extra link layer hard_header space needed */ + int tot_headroom = 0; /* The total header space needed */ + int tot_tailroom = 0; /* The totalstuffing needed */ + __u8 *saved_header = NULL; /* saved copy of the hard header */ + int i; + unsigned short sport,dport; + + struct sockaddr_encap matcher; /* eroute search key */ + struct eroute *er; + struct ipsec_sa *tdbp, *tdbq; /* Tunnel Descriptor Block pointers */ + char sa[SATOA_BUF]; + size_t sa_len; + int hard_header_stripped = 0; /* has the hard header been removed yet? */ + int hard_header_len = 0; + struct device *physdev; +/* struct device *virtdev; */ + short physmtu; + short mtudiff; + int blocksize = 8; +#ifdef NET_21 + struct rtable *rt = NULL; +#endif /* NET_21 */ + struct sa_id outgoing_said; +#ifdef NET_21 + int pass = 0; +#endif /* NET_21 */ + int error = 0; + uint32_t eroute_pid = 0; + struct ipsec_sa tdb; +#ifdef CONFIG_IPSEC_ALG + struct ipsec_alg_enc *ixt_e = NULL; + struct ipsec_alg_auth *ixt_a = NULL; +#endif /* CONFIG_IPSEC_ALG */ + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + uint8_t natt_type = 0, natt_head = 0; + uint16_t natt_sport = 0, natt_dport = 0; +#endif + + dport=sport=0; + + memset((char*)&tdb, 0, sizeof(struct ipsec_sa)); + + /* + * Return if there is nothing to do. (Does this ever happen?) XXX + */ + if (skb == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_error:ipsec_tunnel_start_xmit: " + "Nothing to do!\n" ); + goto cleanup; + } + if (dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_error:ipsec_tunnel_start_xmit: " + "No device associated with skb!\n" ); + goto cleanup; + } + + prv = dev->priv; + if (prv == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_error:ipsec_tunnel_start_xmit: " + "Device has no private structure!\n" ); + goto cleanup; + } + + physdev = prv->dev; + if (physdev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_error:ipsec_tunnel_start_xmit: " + "Device is not attached to physical device!\n" ); + goto cleanup; + } + + physmtu = physdev->mtu; + + stats = (struct net_device_stats *) &(prv->mystats); + +#ifdef NET_21 + /* if skb was cloned (most likely due to a packet sniffer such as + tcpdump being momentarily attached to the interface), make + a copy of our own to modify */ + if(skb_cloned(skb)) { + if +#ifdef SKB_COW_NEW + (skb_cow(skb, skb_headroom(skb)) != 0) +#else /* SKB_COW_NEW */ + ((skb = skb_cow(skb, skb_headroom(skb))) == NULL) +#endif /* SKB_COW_NEW */ + { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_error:ipsec_tunnel_start_xmit: " + "skb_cow failed to allocate buffer, dropping.\n" ); + stats->tx_dropped++; + goto cleanup; + } + } +#endif /* NET_21 */ + +#ifdef NET_21 + iph = skb->nh.iph; +#else /* NET_21 */ + iph = skb->ip_hdr; +#endif /* NET_21 */ + + /* sanity check for IP version as we can't handle IPv6 right now */ + if (iph->version != 4) { + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "found IP Version %d but cannot process other IP versions than v4.\n", + iph->version); /* XXX */ + stats->tx_dropped++; + goto cleanup; + } + + /* physdev->hard_header_len is unreliable and should not be used */ + hard_header_len = (unsigned char *)iph - skb->data; + + if(hard_header_len < 0) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_error:ipsec_tunnel_start_xmit: " + "Negative hard_header_len (%d)?!\n", hard_header_len); + stats->tx_dropped++; + goto cleanup; + } + + if(hard_header_len == 0) { /* no hard header present */ + hard_header_stripped = 1; + /* otherwise it panics in clip_start_xmit()/skb_push() */ + hard_header_len = physdev->hard_header_len; + + } + +#ifdef CONFIG_IPSEC_DEBUG + if (debug_tunnel & DB_TN_XMIT) { + int i; + char c; + + printk(KERN_INFO "klips_debug:ipsec_tunnel_start_xmit: " + ">>> skb->len=%ld hard_header_len:%d", + (unsigned long int)skb->len, hard_header_len); + c = ' '; + for (i=0; i < hard_header_len; i++) { + printk("%c%02x", c, skb->data[i]); + c = ':'; + } + printk(" \n"); + } +#endif /* CONFIG_IPSEC_DEBUG */ + + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph); + + /* + * Sanity checks + */ + + if ((iph->ihl << 2) != sizeof (struct iphdr)) { + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */ + stats->tx_dropped++; + goto cleanup; + } + +#ifndef NET_21 + /* TTL decrement code (on the way out!) borrowed from ip_forward.c */ + if(0) { + unsigned long checksum = iph->check; + iph->ttl--; + /* + * Re-compute the IP header checksum. + * This is efficient. We know what has happened to the header + * and can thus adjust the checksum as Phil Karn does in KA9Q + * except we do this in "network byte order". + */ + checksum += htons(0x0100); + /* carry overflow? */ + checksum += checksum >> 16; + iph->check = checksum; + } + if (iph->ttl <= 0) { + /* Tell the sender its packet died... */ + ICMP_SEND(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, physdev); + + KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_tunnel_start_xmit: " + "TTL=0, too many hops!\n"); + stats->tx_dropped++; + goto cleanup; + } +#endif /* !NET_21 */ + + /* + * First things first -- look us up in the erouting tables. + */ + matcher.sen_len = sizeof (struct sockaddr_encap); + matcher.sen_family = AF_ENCAP; + matcher.sen_type = SENT_IP4; + matcher.sen_ip_src.s_addr = iph->saddr; + matcher.sen_ip_dst.s_addr = iph->daddr; + matcher.sen_proto = iph->protocol; + extract_ports(iph, &matcher); + + /* + * The spinlock is to prevent any other process from accessing or deleting + * the eroute while we are using and updating it. + */ + spin_lock(&eroute_lock); + + er = ipsec_findroute(&matcher); + + if(iph->protocol == IPPROTO_UDP) { + if(skb->sk) { + sport=ntohs(skb->sk->sport); + dport=ntohs(skb->sk->dport); + } else if((ntohs(iph->frag_off) & IP_OFFSET) == 0 && + iph->ihl << 2 > sizeof(struct iphdr) + sizeof(struct udphdr)) { + sport=ntohs(((struct udphdr*)((caddr_t)iph+(iph->ihl<<2)))->source); + dport=ntohs(((struct udphdr*)((caddr_t)iph + (iph->ihl<<2)))->dest); + } else { + sport=0; dport=0; + } + } + + /* default to a %drop eroute */ + outgoing_said.proto = IPPROTO_INT; + outgoing_said.spi = htonl(SPI_DROP); + outgoing_said.dst.s_addr = INADDR_ANY; + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "checking for local udp/500 IKE packet " + "saddr=%x, er=%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n", + ntohl((unsigned int)iph->saddr), + er, + ntohl((unsigned int)iph->daddr), + er ? ntohl((unsigned int)er->er_said.dst.s_addr) : 0, + iph->protocol, + sport, + dport); + + /* + * Quick cheat for now...are we udp/500? If so, let it through + * without interference since it is most likely an IKE packet. + */ + + if (ip_chk_addr((unsigned long)iph->saddr) == IS_MYADDR + && (!er + || iph->daddr == er->er_said.dst.s_addr + || INADDR_ANY == er->er_said.dst.s_addr) +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + && ((sport == 500) || (sport == 4500)) +#else + && (sport == 500) +#endif + ) { + /* Whatever the eroute, this is an IKE message + * from us (i.e. not being forwarded). + * Furthermore, if there is a tunnel eroute, + * the destination is the peer for this eroute. + * So %pass the packet: modify the default %drop. + */ + outgoing_said.spi = htonl(SPI_PASS); + if(!(skb->sk) && ((ntohs(iph->frag_off) & IP_MF) != 0)) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n"); + } + } else if (er) { + er->er_count++; + er->er_lasttime = jiffies/HZ; + if(er->er_said.proto==IPPROTO_INT + && er->er_said.spi==htonl(SPI_HOLD)) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "shunt SA of HOLD: skb stored in HOLD.\n"); + if(er->er_last != NULL) { + kfree_skb(er->er_last); + } + er->er_last = skb; + skb = NULL; + stats->tx_dropped++; + spin_unlock(&eroute_lock); + goto cleanup; + } + outgoing_said = er->er_said; + eroute_pid = er->er_pid; + /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */ + if(outgoing_said.proto==IPPROTO_INT + && (outgoing_said.spi==htonl(SPI_TRAP) + || (outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) { + int len; + + tdb.tdb_ident_s.type = er->er_ident_s.type; + tdb.tdb_ident_s.id = er->er_ident_s.id; + tdb.tdb_ident_s.len = er->er_ident_s.len; + if (tdb.tdb_ident_s.len) { + len = tdb.tdb_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); + if ((tdb.tdb_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) { + printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: " + "Failed, tried to allocate %d bytes for source ident.\n", + len); + stats->tx_dropped++; + spin_unlock(&eroute_lock); + goto cleanup; + } + memcpy(tdb.tdb_ident_s.data, er->er_ident_s.data, len); + } + tdb.tdb_ident_d.type = er->er_ident_d.type; + tdb.tdb_ident_d.id = er->er_ident_d.id; + tdb.tdb_ident_d.len = er->er_ident_d.len; + if (tdb.tdb_ident_d.len) { + len = tdb.tdb_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); + if ((tdb.tdb_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) { + printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: " + "Failed, tried to allocate %d bytes for dest ident.\n", + len); + stats->tx_dropped++; + spin_unlock(&eroute_lock); + goto cleanup; + } + memcpy(tdb.tdb_ident_d.data, er->er_ident_d.data, len); + } + } + } + + spin_unlock(&eroute_lock); + + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "Original head,tailroom: %d,%d\n", + skb_headroom(skb), skb_tailroom(skb)); + + innersrc = iph->saddr; + /* start encapsulation loop here XXX */ + do { + struct ipsec_sa *tdbprev = NULL; + + newdst = orgdst = iph->daddr; + newsrc = orgsrc = iph->saddr; + orgedst = outgoing_said.dst.s_addr; + iphlen = iph->ihl << 2; + pyldsz = ntohs(iph->tot_len) - iphlen; + max_headroom = max_tailroom = 0; + + if (outgoing_said.proto == IPPROTO_INT) { + switch (ntohl(outgoing_said.spi)) { + case SPI_DROP: + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "shunt SA of DROP or no eroute: dropping.\n"); + stats->tx_dropped++; + break; + + case SPI_REJECT: + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "shunt SA of REJECT: notifying and dropping.\n"); + ICMP_SEND(skb, + ICMP_DEST_UNREACH, + ICMP_PKT_FILTERED, + 0, + physdev); + stats->tx_dropped++; + break; + + case SPI_PASS: +#ifdef NET_21 + pass = 1; +#endif /* NET_21 */ + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "PASS: calling dev_queue_xmit\n"); + goto bypass; + +#if 1 /* now moved up to finderoute so we don't need to lock it longer */ + case SPI_HOLD: + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "shunt SA of HOLD: this does not make sense here, dropping.\n"); + stats->tx_dropped++; + break; +#endif + case SPI_TRAP: + case SPI_TRAPSUBNET: + { + struct sockaddr_in src, dst; +#ifdef CONFIG_IPSEC_DEBUG + char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF]; +#endif /* CONFIG_IPSEC_DEBUG */ + + /* Signal all listening KMds with a PF_KEY ACQUIRE */ + tdb.tdb_said.proto = iph->protocol; + src.sin_family = AF_INET; + dst.sin_family = AF_INET; + src.sin_addr.s_addr = iph->saddr; + dst.sin_addr.s_addr = iph->daddr; + src.sin_port = + (iph->protocol == IPPROTO_UDP + ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->source + : (iph->protocol == IPPROTO_TCP + ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->source + : 0)); + dst.sin_port = + (iph->protocol == IPPROTO_UDP + ? ((struct udphdr*) (((caddr_t)iph) + (iph->ihl << 2)))->dest + : (iph->protocol == IPPROTO_TCP + ? ((struct tcphdr*)((caddr_t)iph + (iph->ihl << 2)))->dest + : 0)); + for(i = 0; + i < sizeof(struct sockaddr_in) + - offsetof(struct sockaddr_in, sin_zero); + i++) { + src.sin_zero[i] = 0; + dst.sin_zero[i] = 0; + } + + tdb.tdb_addr_s = (struct sockaddr*)(&src); + tdb.tdb_addr_d = (struct sockaddr*)(&dst); + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n", + addrtoa(((struct sockaddr_in*)(tdb.tdb_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR", + ntohs(((struct sockaddr_in*)(tdb.tdb_addr_s))->sin_port), + addrtoa(((struct sockaddr_in*)(tdb.tdb_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR", + ntohs(((struct sockaddr_in*)(tdb.tdb_addr_d))->sin_port), + tdb.tdb_said.proto); + + if (pfkey_acquire(&tdb) == 0) { + + if (outgoing_said.spi==htonl(SPI_TRAPSUBNET)) { + /* + * The spinlock is to prevent any other + * process from accessing or deleting + * the eroute while we are using and + * updating it. + */ + spin_lock(&eroute_lock); + er = ipsec_findroute(&matcher); + if(er) { + er->er_said.spi = htonl(SPI_HOLD); + er->er_first = skb; + skb = NULL; + } + spin_unlock(&eroute_lock); + } else if (create_hold_eroute(skb, iph, eroute_pid)) { + skb = NULL; + } + } + stats->tx_dropped++; + } + default: + /* XXX what do we do with an unknown shunt spi? */ + } /* switch (ntohl(outgoing_said.spi)) */ + goto cleanup; + } /* if (outgoing_said.proto == IPPROTO_INT) */ + + /* + The spinlock is to prevent any other process from + accessing or deleting the TDB hash table or any of the + TDBs while we are using and updating them. + + This is not optimal, but was relatively straightforward + at the time. A better way to do it has been planned for + more than a year, to lock the hash table and put reference + counts on each TDB instead. This is not likely to happen + in KLIPS1 unless a volunteer contributes it, but will be + designed into KLIPS2. + */ + spin_lock(&tdb_lock); + + tdbp = ipsec_sa_getbyid(&outgoing_said); + sa_len = satoa(outgoing_said, 0, sa, SATOA_BUF); + + if (tdbp == NULL) { + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "no Tunnel Descriptor Block for SA%s: outgoing packet with no SA, dropped.\n", + sa_len ? sa : " (error)"); + stats->tx_dropped++; + goto cleanup; + } + + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "found Tunnel Descriptor Block -- SA:<%s%s%s> %s\n", + IPS_XFORM_NAME(tdbp), + sa_len ? sa : " (error)"); + + /* + * How much headroom do we need to be able to apply + * all the grouped transforms? + */ + tdbq = tdbp; /* save the head of the tdb chain */ + while (tdbp) { + sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF); + if(sa_len == 0) { + strcpy(sa, "(error)"); + } + + /* If it is in larval state, drop the packet, we cannot process yet. */ + if(tdbp->tdb_state == SADB_SASTATE_LARVAL) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "TDB in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n", + IPS_XFORM_NAME(tdbp), + sa_len ? sa : " (error)"); + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } + + if(tdbp->tdb_state == SADB_SASTATE_DEAD) { + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "TDB in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n", + IPS_XFORM_NAME(tdbp), + sa_len ? sa : " (error)"); + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } + + /* If the replay window counter == -1, expire SA, it will roll */ + if(tdbp->tdb_replaywin && tdbp->tdb_replaywin_lastseq == -1) { + pfkey_expire(tdbp, 1); + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n", + IPS_XFORM_NAME(tdbp), + sa_len ? sa : " (error)"); + ipsec_sa_delchain(tdbp); + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } + + /* + * if this is the first time we are using this SA, mark start time, + * and offset hard/soft counters by "now" for later checking. + */ +#if 0 + if(tdbp->ips_life.ipl_usetime.count == 0) { + tdbp->ips_life.ipl_usetime.count = jiffies; + tdbp->ips_life.ipl_usetime.hard += jiffies; + tdbp->ips_life.ipl_usetime.soft += jiffies; + } +#endif + + + if(ipsec_lifetime_check(&tdbp->ips_life.ipl_bytes, "bytes", sa, + ipsec_life_countbased, ipsec_outgoing, tdbp) == ipsec_life_harddied || + ipsec_lifetime_check(&tdbp->ips_life.ipl_addtime, "addtime",sa, + ipsec_life_timebased, ipsec_outgoing, tdbp) == ipsec_life_harddied || + ipsec_lifetime_check(&tdbp->ips_life.ipl_usetime, "usetime",sa, + ipsec_life_timebased, ipsec_outgoing, tdbp) == ipsec_life_harddied || + ipsec_lifetime_check(&tdbp->ips_life.ipl_packets, "packets",sa, + ipsec_life_countbased, ipsec_outgoing, tdbp) == ipsec_life_harddied) { + + ipsec_sa_delchain(tdbp); + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } + + + headroom = tailroom = 0; + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "calling room for <%s%s%s>, SA:%s\n", + IPS_XFORM_NAME(tdbp), + sa_len ? sa : " (error)"); + switch(tdbp->tdb_said.proto) { +#ifdef CONFIG_IPSEC_AH + case IPPROTO_AH: + headroom += sizeof(struct ah); + break; +#endif /* CONFIG_IPSEC_AH */ +#ifdef CONFIG_IPSEC_ESP + case IPPROTO_ESP: +#ifdef CONFIG_IPSEC_ALG + if ((ixt_e=IPSEC_ALG_SA_ESP_ENC(tdbp))) { + blocksize = ixt_e->ixt_blocksize; + headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8; + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_encalg) { +#ifdef CONFIG_IPSEC_ENC_3DES + case ESP_3DES: + headroom += sizeof(struct esp); + break; +#endif /* CONFIG_IPSEC_ENC_3DES */ + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } +#ifdef CONFIG_IPSEC_ALG + if ((ixt_a=IPSEC_ALG_SA_ESP_AUTH(tdbp))) { + tailroom += AHHMAC_HASHLEN; + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_authalg) { +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case AH_MD5: + tailroom += AHHMAC_HASHLEN; + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + case AH_SHA: + tailroom += AHHMAC_HASHLEN; + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + case AH_NONE: + break; + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } +/* tailroom += ((blocksize - ((pyldsz + 2 * sizeof(unsigned char)) % blocksize)) % blocksize) + 2; */ + tailroom += + blocksize != 1 ? + ((blocksize - ((pyldsz + 2) % blocksize)) % blocksize) + 2 : + ((4 - ((pyldsz + 2) % 4)) % 4) + 2; + + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if ((tdbp->ips_natt_type) && (!natt_type)) { + natt_type = tdbp->ips_natt_type; + natt_sport = tdbp->ips_natt_sport; + natt_dport = tdbp->ips_natt_dport; + switch (natt_type) { + case ESPINUDP_WITH_NON_IKE: + natt_head = sizeof(struct udphdr)+(2*sizeof(__u32)); + break; + case ESPINUDP_WITH_NON_ESP: + natt_head = sizeof(struct udphdr); + break; + default: + natt_head = 0; + break; + } + tailroom += natt_head; + } +#endif + break; +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_IPIP + case IPPROTO_IPIP: + headroom += sizeof(struct iphdr); + break; +#endif /* !CONFIG_IPSEC_IPIP */ + case IPPROTO_COMP: +#ifdef CONFIG_IPSEC_IPCOMP + /* + We can't predict how much the packet will + shrink without doing the actual compression. + We could do it here, if we were the first + encapsulation in the chain. That might save + us a skb_copy_expand, since we might fit + into the existing skb then. However, this + would be a bit unclean (and this hack has + bit us once), so we better not do it. After + all, the skb_copy_expand is cheap in + comparison to the actual compression. + At least we know the packet will not grow. + */ + break; +#endif /* CONFIG_IPSEC_IPCOMP */ + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } + tdbp = tdbp->tdb_onext; +#ifdef CONFIG_IPSEC_ALG + ixt_e = NULL; /* invalidate ipsec_alg */ + ixt_a = NULL; +#endif /* CONFIG_IPSEC_ALG */ + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "Required head,tailroom: %d,%d\n", + headroom, tailroom); + max_headroom += headroom; + max_tailroom += tailroom; + pyldsz += (headroom + tailroom); + } + tdbp = tdbq; /* restore the head of the tdb chain */ + + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n", + skb_headroom(skb), skb_tailroom(skb), + max_headroom, max_tailroom); + + tot_headroom += max_headroom; + tot_tailroom += max_tailroom; + + mtudiff = prv->mtu + tot_headroom + tot_tailroom - physmtu; + + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n", + prv->mtu, physmtu, + tot_headroom, tot_tailroom, mtudiff, ntohs(iph->tot_len)); + if(mtudiff > 0) { + int newmtu = physmtu - (tot_headroom + ((tot_tailroom + 2) & ~7) + 5); + + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_info:ipsec_tunnel_start_xmit: " + "dev %s mtu of %d decreased by %d to %d\n", + dev->name, + prv->mtu, + prv->mtu - newmtu, + newmtu); + prv->mtu = newmtu; +#ifdef NET_21 +#if 0 + skb->dst->pmtu = prv->mtu; /* RGB */ +#endif /* 0 */ +#else /* NET_21 */ +#if 0 + dev->mtu = prv->mtu; /* RGB */ +#endif /* 0 */ +#endif /* NET_21 */ + } + + /* + If the sender is doing PMTU discovery, and the + packet doesn't fit within prv->mtu, notify him + (unless it was an ICMP packet, or it was not the + zero-offset packet) and send it anyways. + + Note: buggy firewall configuration may prevent the + ICMP packet from getting back. + */ + if(sysctl_ipsec_icmp + && prv->mtu < ntohs(iph->tot_len) + && (iph->frag_off & __constant_htons(IP_DF)) ) { + int notify = iph->protocol != IPPROTO_ICMP + && (iph->frag_off & __constant_htons(IP_OFFSET)) == 0; + +#ifdef IPSEC_obey_DF + spin_unlock(&tdb_lock); + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "fragmentation needed and DF set; %sdropping packet\n", + notify ? "sending ICMP and " : ""); + if (notify) + ICMP_SEND(skb, + ICMP_DEST_UNREACH, + ICMP_FRAG_NEEDED, + prv->mtu, + physdev); + stats->tx_errors++; + goto cleanup; +#else /* IPSEC_obey_DF */ + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "fragmentation needed and DF set; %spassing packet\n", + notify ? "sending ICMP and " : ""); + if (notify) + ICMP_SEND(skb, + ICMP_DEST_UNREACH, + ICMP_FRAG_NEEDED, + prv->mtu, + physdev); +#endif /* IPSEC_obey_DF */ + } + +#ifdef MSS_HACK + /* + * If this is a transport mode TCP packet with + * SYN set, determine an effective MSS based on + * AH/ESP overheads determined above. + */ + if (iph->protocol == IPPROTO_TCP + && outgoing_said.proto != IPPROTO_IPIP) { + struct tcphdr *tcph = skb->h.th; + if (tcph->syn && !tcph->ack) { + if(!ipsec_adjust_mss(skb, tcph, prv->mtu)) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING + "klips_warning:ipsec_tunnel_start_xmit: " + "ipsec_adjust_mss() failed\n"); + stats->tx_errors++; + goto cleanup; + } + } + } +#endif /* MSS_HACK */ + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if ((natt_type) && (outgoing_said.proto != IPPROTO_IPIP)) { + /** + * NAT-Traversal and Transport Mode: + * we need to correct TCP/UDP checksum + * + * If we've got NAT-OA, we can fix checksum without recalculation. + * If we don't we can zero udp checksum. + */ + __u32 natt_oa = tdbp->ips_natt_oa ? + ((struct sockaddr_in*)(tdbp->ips_natt_oa))->sin_addr.s_addr : 0; + __u16 pkt_len = skb->tail - (unsigned char *)iph; + __u16 data_len = pkt_len - (iph->ihl << 2); + switch (iph->protocol) { + case IPPROTO_TCP: + if (data_len >= sizeof(struct tcphdr)) { + struct tcphdr *tcp = (struct tcphdr *)((__u32 *)iph+iph->ihl); + if (natt_oa) { + __u32 buff[2] = { ~iph->daddr, natt_oa }; + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "NAT-T & TRANSPORT: " + "fix TCP checksum using NAT-OA\n"); + tcp->check = csum_fold( + csum_partial((unsigned char *)buff, sizeof(buff), + tcp->check^0xffff)); + } + else { + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "NAT-T & TRANSPORT: do not recalc TCP checksum\n"); + } + } + else { + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "NAT-T & TRANSPORT: can't fix TCP checksum\n"); + } + break; + case IPPROTO_UDP: + if (data_len >= sizeof(struct udphdr)) { + struct udphdr *udp = (struct udphdr *)((__u32 *)iph+iph->ihl); + if (udp->check == 0) { + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "NAT-T & TRANSPORT: UDP checksum already 0\n"); + } + else if (natt_oa) { + __u32 buff[2] = { ~iph->daddr, natt_oa }; + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "NAT-T & TRANSPORT: " + "fix UDP checksum using NAT-OA\n"); + udp->check = csum_fold( + csum_partial((unsigned char *)buff, sizeof(buff), + udp->check^0xffff)); + } + else { + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "NAT-T & TRANSPORT: zero UDP checksum\n"); + udp->check = 0; + } + } + else { + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "NAT-T & TRANSPORT: can't fix UDP checksum\n"); + } + break; + default: + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_start_xmit: " + "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n"); + break; + } + } +#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */ + + if(!hard_header_stripped) { + if((saved_header = kmalloc(hard_header_len, GFP_ATOMIC)) == NULL) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING "klips_debug:ipsec_tunnel_start_xmit: " + "Failed, tried to allocate %d bytes for temp hard_header.\n", + hard_header_len); + stats->tx_errors++; + goto cleanup; + } + for (i = 0; i < hard_header_len; i++) { + saved_header[i] = skb->data[i]; + } + if(skb->len < hard_header_len) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: " + "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n", + hard_header_len, (int)(skb->len)); + stats->tx_errors++; + goto cleanup; + } + skb_pull(skb, hard_header_len); + hard_header_stripped = 1; + +/* iph = (struct iphdr *) (skb->data); */ + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "head,tailroom: %d,%d after hard_header stripped.\n", + skb_headroom(skb), skb_tailroom(skb)); + KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, iph); + } else { + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "hard header already stripped.\n"); + } + + ll_headroom = (hard_header_len + 15) & ~15; + + if ((skb_headroom(skb) >= max_headroom + 2 * ll_headroom) && + (skb_tailroom(skb) >= max_tailroom) +#ifndef NET_21 + && skb->free +#endif /* !NET_21 */ + ) { + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "data fits in existing skb\n"); + } else { + struct sk_buff* tskb = skb; + + if(!oskb) { + oskb = skb; + } + + tskb = skb_copy_expand(skb, + /* The reason for 2 * link layer length here still baffles me...RGB */ + max_headroom + 2 * ll_headroom, + max_tailroom, + GFP_ATOMIC); +#ifdef NET_21 + if(tskb && skb->sk) { + skb_set_owner_w(tskb, skb->sk); + } +#endif /* NET_21 */ + if(!(skb == oskb) ) { + dev_kfree_skb(skb, FREE_WRITE); + } + skb = tskb; + if (!skb) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING + "klips_debug:ipsec_tunnel_start_xmit: " + "Failed, tried to allocate %d head and %d tailroom\n", + max_headroom, max_tailroom); + stats->tx_errors++; + goto cleanup; + } + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "head,tailroom: %d,%d after allocation\n", + skb_headroom(skb), skb_tailroom(skb)); + } + + /* + * Apply grouped transforms to packet + */ + while (tdbp) { +#ifdef CONFIG_IPSEC_ESP + struct esp *espp; +#ifdef CONFIG_IPSEC_ENC_3DES + __u32 iv[ESP_IV_MAXSZ_INT]; +#endif /* !CONFIG_IPSEC_ENC_3DES */ + unsigned char *idat, *pad; + int authlen = 0, padlen = 0, i; +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_AH + struct iphdr ipo; + struct ah *ahp; +#endif /* CONFIG_IPSEC_AH */ +#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) + union { +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + MD5_CTX md5; +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + SHA1_CTX sha1; +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + } tctx; + __u8 hash[AH_AMAX]; +#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */ + int headroom = 0, tailroom = 0, ilen = 0, len = 0; + unsigned char *dat; + + iphlen = iph->ihl << 2; + pyldsz = ntohs(iph->tot_len) - iphlen; + sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_tunnel & DB_TN_OXFS, + "klips_debug:ipsec_tunnel_start_xmit: " + "calling output for <%s%s%s>, SA:%s\n", + IPS_XFORM_NAME(tdbp), + sa_len ? sa : " (error)"); + + switch(tdbp->tdb_said.proto) { +#ifdef CONFIG_IPSEC_AH + case IPPROTO_AH: + headroom += sizeof(struct ah); + break; +#endif /* CONFIG_IPSEC_AH */ +#ifdef CONFIG_IPSEC_ESP + case IPPROTO_ESP: +#ifdef CONFIG_IPSEC_ALG + if ((ixt_e=IPSEC_ALG_SA_ESP_ENC(tdbp))) { + blocksize = ixt_e->ixt_blocksize; + headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8; + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_encalg) { +#ifdef CONFIG_IPSEC_ENC_3DES + case ESP_3DES: + headroom += sizeof(struct esp); + break; +#endif /* CONFIG_IPSEC_ENC_3DES */ + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } +#ifdef CONFIG_IPSEC_ALG + if ((ixt_a=IPSEC_ALG_SA_ESP_AUTH(tdbp))) { + authlen = AHHMAC_HASHLEN; + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_authalg) { +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case AH_MD5: + authlen = AHHMAC_HASHLEN; + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + case AH_SHA: + authlen = AHHMAC_HASHLEN; + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + case AH_NONE: + break; + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } + tailroom += + blocksize != 1 ? + ((blocksize - ((pyldsz + 2) % blocksize)) % blocksize) + 2 : + ((4 - ((pyldsz + 2) % 4)) % 4) + 2; + tailroom += authlen; + break; +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_IPIP + case IPPROTO_IPIP: + headroom += sizeof(struct iphdr); + break; +#endif /* !CONFIG_IPSEC_IPIP */ +#ifdef CONFIG_IPSEC_IPCOMP + case IPPROTO_COMP: + break; +#endif /* CONFIG_IPSEC_IPCOMP */ + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } + + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "pushing %d bytes, putting %d, proto %d.\n", + headroom, tailroom, tdbp->tdb_said.proto); + if(skb_headroom(skb) < headroom) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING + "klips_error:ipsec_tunnel_start_xmit: " + "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n", + headroom, skb_headroom(skb)); + stats->tx_errors++; + goto cleanup; + } + dat = skb_push(skb, headroom); + ilen = skb->len - tailroom; + if(skb_tailroom(skb) < tailroom) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING + "klips_error:ipsec_tunnel_start_xmit: " + "tried to skb_put %d, %d available. This should never happen, please report.\n", + tailroom, skb_tailroom(skb)); + stats->tx_errors++; + goto cleanup; + } + skb_put(skb, tailroom); + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "head,tailroom: %d,%d before xform.\n", + skb_headroom(skb), skb_tailroom(skb)); + len = skb->len; + if(len > 0xfff0) { + spin_unlock(&tdb_lock); + printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: " + "tot_len (%d) > 65520. This should never happen, please report.\n", + len); + stats->tx_errors++; + goto cleanup; + } + memmove((void *)dat, (void *)(dat + headroom), iphlen); + iph = (struct iphdr *)dat; + iph->tot_len = htons(skb->len); + + switch(tdbp->tdb_said.proto) { +#ifdef CONFIG_IPSEC_ESP + case IPPROTO_ESP: + espp = (struct esp *)(dat + iphlen); + espp->esp_spi = tdbp->tdb_said.spi; + espp->esp_rpl = htonl(++(tdbp->tdb_replaywin_lastseq)); + +#ifdef CONFIG_IPSEC_ALG + if (!ixt_e) +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_encalg) { +#if defined(CONFIG_IPSEC_ENC_3DES) +#ifdef CONFIG_IPSEC_ENC_3DES + case ESP_3DES: +#endif /* CONFIG_IPSEC_ENC_3DES */ + iv[0] = *((__u32*)&(espp->esp_iv) ) = + ((__u32*)(tdbp->tdb_iv))[0]; + iv[1] = *((__u32*)&(espp->esp_iv) + 1) = + ((__u32*)(tdbp->tdb_iv))[1]; + break; +#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } + + idat = dat + iphlen + headroom; + ilen = len - (iphlen + headroom + authlen); + + /* Self-describing padding */ + pad = &dat[len - tailroom]; + padlen = tailroom - 2 - authlen; + for (i = 0; i < padlen; i++) { + pad[i] = i + 1; + } + dat[len - authlen - 2] = padlen; + + dat[len - authlen - 1] = iph->protocol; + iph->protocol = IPPROTO_ESP; + +#ifdef CONFIG_IPSEC_ALG + /* Do all operations here: + * copy IV->ESP, encrypt, update ips IV + */ + if (ixt_e) { + int ret; + memcpy(espp->esp_iv, + tdbp->ips_iv, + ixt_e->ixt_ivlen/8); + ret=ipsec_alg_esp_encrypt(tdbp, + idat, ilen, espp->esp_iv, + IPSEC_ALG_ENCRYPT); + memcpy(tdbp->ips_iv, + idat + ilen - ixt_e->ixt_ivlen/8, + ixt_e->ixt_ivlen/8); + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_encalg) { +#ifdef CONFIG_IPSEC_ENC_3DES + case ESP_3DES: + des_ede3_cbc_encrypt((des_cblock *)idat, + (des_cblock *)idat, + ilen, + ((struct des_eks *)(tdbp->tdb_key_e))[0].ks, + ((struct des_eks *)(tdbp->tdb_key_e))[1].ks, + ((struct des_eks *)(tdbp->tdb_key_e))[2].ks, + (des_cblock *)iv, 1); + break; +#endif /* CONFIG_IPSEC_ENC_3DES */ + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } +#ifdef CONFIG_IPSEC_ALG + if (!ixt_e) +#endif /* CONFIG_IPSEC_ALG */ + + switch(tdbp->tdb_encalg) { +#if defined(CONFIG_IPSEC_ENC_3DES) +#ifdef CONFIG_IPSEC_ENC_3DES + case ESP_3DES: +#endif /* CONFIG_IPSEC_ENC_3DES */ + /* XXX update IV with the last 8 octets of the encryption */ + ((__u32*)(tdbp->tdb_iv))[0] = + ((__u32 *)(idat))[(ilen >> 2) - 2]; + ((__u32*)(tdbp->tdb_iv))[1] = + ((__u32 *)(idat))[(ilen >> 2) - 1]; + break; +#endif /* defined(CONFIG_IPSEC_ENC_3DES) */ + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } +#ifdef CONFIG_IPSEC_ALG + if (ixt_a) { + ipsec_alg_sa_esp_hash(tdbp, + (caddr_t)espp, len - iphlen - authlen, + &(dat[len - authlen]), authlen); + + } else +#endif /* CONFIG_IPSEC_ALG */ + + switch(tdbp->tdb_authalg) { +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case AH_MD5: + dmp("espp", (char*)espp, len - iphlen - authlen); + tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx; + dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Update(&tctx.md5, (caddr_t)espp, len - iphlen - authlen); + dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Final(hash, &tctx.md5); + dmp("ictx hash", (char*)&hash, sizeof(hash)); + tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx; + dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Update(&tctx.md5, hash, AHMD596_ALEN); + dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Final(hash, &tctx.md5); + dmp("octx hash", (char*)&hash, sizeof(hash)); + memcpy(&(dat[len - authlen]), hash, authlen); + + /* paranoid */ + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); + memset((caddr_t)hash, 0, sizeof(*hash)); + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + case AH_SHA: + tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx; + SHA1Update(&tctx.sha1, (caddr_t)espp, len - iphlen - authlen); + SHA1Final(hash, &tctx.sha1); + tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx; + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); + SHA1Final(hash, &tctx.sha1); + memcpy(&(dat[len - authlen]), hash, authlen); + + /* paranoid */ + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); + memset((caddr_t)hash, 0, sizeof(*hash)); + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + case AH_NONE: + break; + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } +#ifdef NET_21 + skb->h.raw = (unsigned char*)espp; +#endif /* NET_21 */ + break; +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_AH + case IPPROTO_AH: + ahp = (struct ah *)(dat + iphlen); + ahp->ah_spi = tdbp->tdb_said.spi; + ahp->ah_rpl = htonl(++(tdbp->tdb_replaywin_lastseq)); + ahp->ah_rv = 0; + ahp->ah_nh = iph->protocol; + ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32); + iph->protocol = IPPROTO_AH; + dmp("ahp", (char*)ahp, sizeof(*ahp)); + + ipo = *iph; + ipo.tos = 0; + ipo.frag_off = 0; + ipo.ttl = 0; + ipo.check = 0; + dmp("ipo", (char*)&ipo, sizeof(ipo)); + + switch(tdbp->tdb_authalg) { +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case AH_MD5: + tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->ictx; + dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr)); + dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data)); + dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN); + dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Update(&tctx.md5, dat + iphlen + headroom, len - iphlen - headroom); + dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Final(hash, &tctx.md5); + dmp("ictx hash", (char*)&hash, sizeof(hash)); + tctx.md5 = ((struct md5_ctx*)(tdbp->tdb_key_a))->octx; + dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Update(&tctx.md5, hash, AHMD596_ALEN); + dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5)); + MD5Final(hash, &tctx.md5); + dmp("octx hash", (char*)&hash, sizeof(hash)); + + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); + + /* paranoid */ + memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5)); + memset((caddr_t)hash, 0, sizeof(hash)); + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + case AH_SHA: + tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx; + SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr)); + SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data)); + SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN); + SHA1Update(&tctx.sha1, dat + iphlen + headroom, len - iphlen - headroom); + SHA1Final(hash, &tctx.sha1); + tctx.sha1 = ((struct sha1_ctx*)(tdbp->tdb_key_a))->octx; + SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN); + SHA1Final(hash, &tctx.sha1); + + memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN); + + /* paranoid */ + memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1)); + memset((caddr_t)hash, 0, sizeof(hash)); + break; +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } +#ifdef NET_21 + skb->h.raw = (unsigned char*)ahp; +#endif /* NET_21 */ + break; +#endif /* CONFIG_IPSEC_AH */ +#ifdef CONFIG_IPSEC_IPIP + case IPPROTO_IPIP: + iph->version = 4; + switch(sysctl_ipsec_tos) { + case 0: +#ifdef NET_21 + iph->tos = skb->nh.iph->tos; +#else /* NET_21 */ + iph->tos = skb->ip_hdr->tos; +#endif /* NET_21 */ + break; + case 1: + iph->tos = 0; + break; + default: + } +#ifdef NET_21 +#ifdef NETDEV_23 + iph->ttl = sysctl_ip_default_ttl; +#else /* NETDEV_23 */ + iph->ttl = ip_statistics.IpDefaultTTL; +#endif /* NETDEV_23 */ +#else /* NET_21 */ + iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */ +#endif /* NET_21 */ + iph->frag_off = 0; + iph->saddr = ((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr.s_addr; + iph->daddr = ((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr.s_addr; + iph->protocol = IPPROTO_IPIP; + iph->ihl = sizeof(struct iphdr) >> 2 /* 5 */; +#ifdef IP_SELECT_IDENT + /* XXX use of skb->dst below is a questionable + substitute for &rt->u.dst which is only + available later-on */ +#ifdef IP_SELECT_IDENT_NEW + ip_select_ident(iph, skb->dst, NULL); +#else /* IP_SELECT_IDENT_NEW */ + ip_select_ident(iph, skb->dst); +#endif /* IP_SELECT_IDENT_NEW */ +#else /* IP_SELECT_IDENT */ + iph->id = htons(ip_id_count++); /* Race condition here? */ +#endif /* IP_SELECT_IDENT */ + + newdst = (__u32)iph->daddr; + newsrc = (__u32)iph->saddr; + +#ifdef NET_21 + skb->h.ipiph = skb->nh.iph; +#endif /* NET_21 */ + break; +#endif /* !CONFIG_IPSEC_IPIP */ +#ifdef CONFIG_IPSEC_IPCOMP + case IPPROTO_COMP: + { + unsigned int flags = 0; +#ifdef CONFIG_IPSEC_DEBUG + unsigned int old_tot_len = ntohs(iph->tot_len); +#endif /* CONFIG_IPSEC_DEBUG */ + tdbp->tdb_comp_ratio_dbytes += ntohs(iph->tot_len); + + skb = skb_compress(skb, tdbp, &flags); + +#ifdef NET_21 + iph = skb->nh.iph; +#else /* NET_21 */ + iph = skb->ip_hdr; +#endif /* NET_21 */ + + tdbp->tdb_comp_ratio_cbytes += ntohs(iph->tot_len); + +#ifdef CONFIG_IPSEC_DEBUG + if (debug_tunnel & DB_TN_CROUT) + { + if (old_tot_len > ntohs(iph->tot_len)) + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n", + old_tot_len, ntohs(iph->tot_len), + ntohs(((struct ipcomphdr*)(((char*)iph) + ((iph->ihl) << 2)))->ipcomp_cpi), + ntohl(tdbp->tdb_said.spi), + (__u16)(ntohl(tdbp->tdb_said.spi) & 0x0000ffff)); + else + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "packet did not compress (flags = %d).\n", + flags); + } +#endif /* CONFIG_IPSEC_DEBUG */ + } + break; +#endif /* CONFIG_IPSEC_IPCOMP */ + default: + spin_unlock(&tdb_lock); + stats->tx_errors++; + goto cleanup; + } + +#ifdef NET_21 + skb->nh.raw = skb->data; +#else /* NET_21 */ + skb->ip_hdr = skb->h.iph = (struct iphdr *) skb->data; +#endif /* NET_21 */ + iph->check = 0; + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); + + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "after <%s%s%s>, SA:%s:\n", + IPS_XFORM_NAME(tdbp), + sa_len ? sa : " (error)"); + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, iph); + + tdbp->ips_life.ipl_bytes.ipl_count += len; + tdbp->ips_life.ipl_bytes.ipl_last = len; + + if(!tdbp->ips_life.ipl_usetime.ipl_count) { + tdbp->ips_life.ipl_usetime.ipl_count = jiffies / HZ; + } + tdbp->ips_life.ipl_usetime.ipl_last = jiffies / HZ; + tdbp->ips_life.ipl_packets.ipl_count++; + + tdbprev = tdbp; + tdbp = tdbp->ips_onext; +#ifdef CONFIG_IPSEC_ALG + ixt_e = NULL; /* invalidate ipsec_alg */ + ixt_a = NULL; +#endif /* CONFIG_IPSEC_ALG */ + + } + /* end encapsulation loop here XXX */ + + spin_unlock(&tdb_lock); + + matcher.sen_ip_src.s_addr = iph->saddr; + matcher.sen_ip_dst.s_addr = iph->daddr; + matcher.sen_proto = iph->protocol; + extract_ports(iph, &matcher); + + spin_lock(&eroute_lock); + er = ipsec_findroute(&matcher); + if(er) { + outgoing_said = er->er_said; + eroute_pid = er->er_pid; + er->er_count++; + er->er_lasttime = jiffies/HZ; + } + spin_unlock(&eroute_lock); + KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) && + /* ((orgdst != newdst) || (orgsrc != newsrc)) */ + (orgedst != outgoing_said.dst.s_addr) && + outgoing_said.dst.s_addr && + er, + "klips_debug:ipsec_tunnel_start_xmit: " + "We are recursing here.\n"); + } while(/*((orgdst != newdst) || (orgsrc != newsrc))*/ + (orgedst != outgoing_said.dst.s_addr) && + outgoing_said.dst.s_addr && + er); + + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "After recursive xforms -- head,tailroom: %d,%d\n", + skb_headroom(skb), skb_tailroom(skb)); + + if(saved_header) { + if(skb_headroom(skb) < hard_header_len) { + printk(KERN_WARNING + "klips_error:ipsec_tunnel_start_xmit: " + "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n", + hard_header_len, skb_headroom(skb)); + stats->tx_errors++; + goto cleanup; + } + skb_push(skb, hard_header_len); + for (i = 0; i < hard_header_len; i++) { + skb->data[i] = saved_header[i]; + } + } +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if (natt_type && natt_head) { + struct iphdr *ipp = skb->nh.iph; + struct udphdr *udp; + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "encapsuling packet into UDP (NAT-Traversal)\n"); + iphlen = ipp->ihl << 2; + ipp->tot_len = + htons(ntohs(ipp->tot_len) + natt_head); + if(skb_tailroom(skb) < natt_head) { + printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: " + "tried to skb_put %d, %d available. " + "This should never happen, please report.\n", + natt_head, + skb_tailroom(skb)); + stats->tx_errors++; + goto cleanup; + } + skb_put(skb, natt_head); + udp = (struct udphdr *)((char *)ipp + iphlen); + /* move ESP hdr after UDP hdr */ + memmove((void *)((char *)udp + natt_head), + (void *)(udp), + ntohs(ipp->tot_len) - iphlen - natt_head); + /* clear UDP & Non-IKE Markers (if any) */ + memset(udp, 0, natt_head); + /* fill UDP with usefull informations ;-) */ + udp->source = htons(natt_sport); + udp->dest = htons(natt_dport); + udp->len = htons(ntohs(ipp->tot_len) - iphlen); + /* set protocol */ + ipp->protocol = IPPROTO_UDP; + /* fix IP checksum */ + ipp->check = 0; + ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl); + } +#endif + bypass: + KLIPS_PRINT(debug_tunnel & DB_TN_CROUT, + "klips_debug:ipsec_tunnel_start_xmit: " + "With hard_header, final head,tailroom: %d,%d\n", + skb_headroom(skb), skb_tailroom(skb)); + +#ifdef NET_21 /* 2.2 and 2.4 kernels */ + /* new route/dst cache code from James Morris */ + skb->dev = physdev; + /*skb_orphan(skb);*/ + if((error = ip_route_output(&rt, + skb->nh.iph->daddr, + pass ? 0 : skb->nh.iph->saddr, + RT_TOS(skb->nh.iph->tos), + physdev->iflink /* rgb: should this be 0? */))) { + stats->tx_errors++; + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n", + error, + rt->u.dst.dev->name); + goto cleanup; + } + if(dev == rt->u.dst.dev) { + ip_rt_put(rt); + /* This is recursion, drop it. */ + stats->tx_errors++; + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n", dev->name); + goto cleanup; + } + dst_release(skb->dst); + skb->dst = &rt->u.dst; + stats->tx_bytes += skb->len; + if(skb->len < skb->nh.raw - skb->data) { + stats->tx_errors++; + printk(KERN_WARNING + "klips_error:ipsec_tunnel_start_xmit: " + "tried to __skb_pull nh-data=%d, %d available. This should never happen, please report.\n", + (int)(skb->nh.raw - skb->data), skb->len); + goto cleanup; + } + __skb_pull(skb, skb->nh.raw - skb->data); +#ifdef SKB_RESET_NFCT + if(!pass) { + nf_conntrack_put(skb->nfct); + skb->nfct = NULL; + } +#ifdef CONFIG_NETFILTER_DEBUG + skb->nf_debug = 0; +#endif /* CONFIG_NETFILTER_DEBUG */ +#endif /* SKB_RESET_NFCT */ + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "...done, calling ip_send() on device:%s\n", + skb->dev ? skb->dev->name : "NULL"); + KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, skb->nh.iph); +#ifdef NETDEV_23 /* 2.4 kernels */ + { + int err; + + err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, + ipsec_tunnel_xmit2); + if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) { + if(net_ratelimit()) + printk(KERN_ERR + "klips_error:ipsec_tunnel_start_xmit: " + "ip_send() failed, err=%d\n", + -err); + stats->tx_errors++; + stats->tx_aborted_errors++; + skb = NULL; + goto cleanup; + } + } +#else /* NETDEV_23 */ /* 2.2 kernels */ + ip_send(skb); +#endif /* NETDEV_23 */ +#else /* NET_21 */ /* 2.0 kernels */ + skb->arp = 1; + /* ISDN/ASYNC PPP from Matjaz Godec. */ + /* skb->protocol = htons(ETH_P_IP); */ + KLIPS_PRINT(debug_tunnel & DB_TN_XMIT, + "klips_debug:ipsec_tunnel_start_xmit: " + "...done, calling dev_queue_xmit() or ip_fragment().\n"); + IP_SEND(skb, physdev); +#endif /* NET_21 */ + stats->tx_packets++; + + skb = NULL; + cleanup: +#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) + netif_wake_queue(dev); +#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ + dev->tbusy = 0; +#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */ + if(saved_header) { + kfree(saved_header); + } + if(skb) { + dev_kfree_skb(skb, FREE_WRITE); + } + if(oskb) { + dev_kfree_skb(oskb, FREE_WRITE); + } + if (tdb.tdb_ident_s.data) { + kfree(tdb.tdb_ident_s.data); + } + if (tdb.tdb_ident_d.data) { + kfree(tdb.tdb_ident_d.data); + } + return 0; +} + +DEBUG_NO_STATIC struct net_device_stats * +ipsec_tunnel_get_stats(struct device *dev) +{ + return &(((struct ipsecpriv *)(dev->priv))->mystats); +} + +/* + * Revectored calls. + * For each of these calls, a field exists in our private structure. + */ + +DEBUG_NO_STATIC int +ipsec_tunnel_hard_header(struct sk_buff *skb, struct device *dev, + unsigned short type, void *daddr, void *saddr, unsigned len) +{ + struct ipsecpriv *prv = dev->priv; + struct device *tmp; + int ret; + struct net_device_stats *stats; /* This device's statistics */ + + if(skb == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_hard_header: " + "no skb...\n"); + return -ENODATA; + } + + if(dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_hard_header: " + "no device...\n"); + return -ENODEV; + } + + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_hard_header: " + "skb->dev=%s dev=%s.\n", + skb->dev ? skb->dev->name : "NULL", + dev->name); + + if(prv == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_hard_header: " + "no private space associated with dev=%s\n", + dev->name ? dev->name : "NULL"); + return -ENODEV; + } + + stats = (struct net_device_stats *) &(prv->mystats); + + if(prv->dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_hard_header: " + "no physical device associated with dev=%s\n", + dev->name ? dev->name : "NULL"); + stats->tx_dropped++; + return -ENODEV; + } + + /* check if we have to send a IPv6 packet. It might be a Router + Solicitation, where the building of the packet happens in + reverse order: + 1. ll hdr, + 2. IPv6 hdr, + 3. ICMPv6 hdr + -> skb->nh.raw is still uninitialized when this function is + called!! If this is no IPv6 packet, we can print debugging + messages, otherwise we skip all debugging messages and just + build the ll header */ + if(type != ETH_P_IPV6) { + /* execute this only, if we don't have to build the + header for a IPv6 packet */ + if(!prv->hard_header) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_hard_header: " + "physical device has been detached, packet dropped 0x%p->0x%p len=%d type=%d dev=%s->NULL ", + saddr, + daddr, + len, + type, + dev->name); +#ifdef NET_21 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, + "ip=%08x->%08x\n", + (__u32)ntohl(skb->nh.iph->saddr), + (__u32)ntohl(skb->nh.iph->daddr) ); +#else /* NET_21 */ + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, + "ip=%08x->%08x\n", + (__u32)ntohl(skb->ip_hdr->saddr), + (__u32)ntohl(skb->ip_hdr->daddr) ); +#endif /* NET_21 */ + stats->tx_dropped++; + return -ENODEV; + } + +#define da ((struct device *)(prv->dev))->dev_addr + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_hard_header: " + "Revectored 0x%p->0x%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ", + saddr, + daddr, + len, + type, + dev->name, + prv->dev->name, + da[0], da[1], da[2], da[3], da[4], da[5]); +#ifdef NET_21 + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, + "ip=%08x->%08x\n", + (__u32)ntohl(skb->nh.iph->saddr), + (__u32)ntohl(skb->nh.iph->daddr) ); +#else /* NET_21 */ + KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC, + "ip=%08x->%08x\n", + (__u32)ntohl(skb->ip_hdr->saddr), + (__u32)ntohl(skb->ip_hdr->daddr) ); +#endif /* NET_21 */ + } else { + KLIPS_PRINT(debug_tunnel, + "klips_debug:ipsec_tunnel_hard_header: " + "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n"); + } + tmp = skb->dev; + skb->dev = prv->dev; + ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len); + skb->dev = tmp; + return ret; +} + +DEBUG_NO_STATIC int +#ifdef NET_21 +ipsec_tunnel_rebuild_header(struct sk_buff *skb) +#else /* NET_21 */ +ipsec_tunnel_rebuild_header(void *buff, struct device *dev, + unsigned long raddr, struct sk_buff *skb) +#endif /* NET_21 */ +{ + struct ipsecpriv *prv = skb->dev->priv; + struct device *tmp; + int ret; + struct net_device_stats *stats; /* This device's statistics */ + + if(skb->dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_rebuild_header: " + "no device..."); + return -ENODEV; + } + + if(prv == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_rebuild_header: " + "no private space associated with dev=%s", + skb->dev->name ? skb->dev->name : "NULL"); + return -ENODEV; + } + + stats = (struct net_device_stats *) &(prv->mystats); + + if(prv->dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_rebuild_header: " + "no physical device associated with dev=%s", + skb->dev->name ? skb->dev->name : "NULL"); + stats->tx_dropped++; + return -ENODEV; + } + + if(!prv->rebuild_header) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_rebuild_header: " + "physical device has been detached, packet dropped skb->dev=%s->NULL ", + skb->dev->name); +#ifdef NET_21 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "ip=%08x->%08x\n", + (__u32)ntohl(skb->nh.iph->saddr), + (__u32)ntohl(skb->nh.iph->daddr) ); +#else /* NET_21 */ + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "ip=%08x->%08x\n", + (__u32)ntohl(skb->ip_hdr->saddr), + (__u32)ntohl(skb->ip_hdr->daddr) ); +#endif /* NET_21 */ + stats->tx_dropped++; + return -ENODEV; + } + + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel: " + "Revectored rebuild_header dev=%s->%s ", + skb->dev->name, prv->dev->name); +#ifdef NET_21 + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "ip=%08x->%08x\n", + (__u32)ntohl(skb->nh.iph->saddr), + (__u32)ntohl(skb->nh.iph->daddr) ); +#else /* NET_21 */ + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "ip=%08x->%08x\n", + (__u32)ntohl(skb->ip_hdr->saddr), + (__u32)ntohl(skb->ip_hdr->daddr) ); +#endif /* NET_21 */ + tmp = skb->dev; + skb->dev = prv->dev; + +#ifdef NET_21 + ret = prv->rebuild_header(skb); +#else /* NET_21 */ + ret = prv->rebuild_header(buff, prv->dev, raddr, skb); +#endif /* NET_21 */ + skb->dev = tmp; + return ret; +} + +DEBUG_NO_STATIC int +ipsec_tunnel_set_mac_address(struct device *dev, void *addr) +{ + struct ipsecpriv *prv = dev->priv; + + struct net_device_stats *stats; /* This device's statistics */ + + if(dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_set_mac_address: " + "no device..."); + return -ENODEV; + } + + if(prv == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_set_mac_address: " + "no private space associated with dev=%s", + dev->name ? dev->name : "NULL"); + return -ENODEV; + } + + stats = (struct net_device_stats *) &(prv->mystats); + + if(prv->dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_set_mac_address: " + "no physical device associated with dev=%s", + dev->name ? dev->name : "NULL"); + stats->tx_dropped++; + return -ENODEV; + } + + if(!prv->set_mac_address) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_set_mac_address: " + "physical device has been detached, cannot set - skb->dev=%s->NULL\n", + dev->name); + return -ENODEV; + } + + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_set_mac_address: " + "Revectored dev=%s->%s addr=%p\n", + dev->name, prv->dev->name, addr); + return prv->set_mac_address(prv->dev, addr); + +} + +#ifndef NET_21 +DEBUG_NO_STATIC void +ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct device *dev, + unsigned short htype, __u32 daddr) +{ + struct ipsecpriv *prv = dev->priv; + + struct net_device_stats *stats; /* This device's statistics */ + + if(dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_cache_bind: " + "no device..."); + return; + } + + if(prv == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_cache_bind: " + "no private space associated with dev=%s", + dev->name ? dev->name : "NULL"); + return; + } + + stats = (struct net_device_stats *) &(prv->mystats); + + if(prv->dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_cache_bind: " + "no physical device associated with dev=%s", + dev->name ? dev->name : "NULL"); + stats->tx_dropped++; + return; + } + + if(!prv->header_cache_bind) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_cache_bind: " + "physical device has been detached, cannot set - skb->dev=%s->NULL\n", + dev->name); + stats->tx_dropped++; + return; + } + + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_cache_bind: " + "Revectored \n"); + prv->header_cache_bind(hhp, prv->dev, htype, daddr); + return; +} +#endif /* !NET_21 */ + + +DEBUG_NO_STATIC void +ipsec_tunnel_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr) +{ + struct ipsecpriv *prv = dev->priv; + + struct net_device_stats *stats; /* This device's statistics */ + + if(dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_cache_update: " + "no device..."); + return; + } + + if(prv == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_cache_update: " + "no private space associated with dev=%s", + dev->name ? dev->name : "NULL"); + return; + } + + stats = (struct net_device_stats *) &(prv->mystats); + + if(prv->dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_cache_update: " + "no physical device associated with dev=%s", + dev->name ? dev->name : "NULL"); + stats->tx_dropped++; + return; + } + + if(!prv->header_cache_update) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_cache_update: " + "physical device has been detached, cannot set - skb->dev=%s->NULL\n", + dev->name); + return; + } + + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel: " + "Revectored cache_update\n"); + prv->header_cache_update(hh, prv->dev, haddr); + return; +} + +#ifdef NET_21 +DEBUG_NO_STATIC int +ipsec_tunnel_neigh_setup(struct neighbour *n) +{ + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_neigh_setup:\n"); + + if (n->nud_state == NUD_NONE) { + n->ops = &arp_broken_ops; + n->output = n->ops->output; + } + return 0; +} + +DEBUG_NO_STATIC int +ipsec_tunnel_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +{ + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_neigh_setup_dev: " + "setting up %s\n", + dev ? dev->name : "NULL"); + + if (p->tbl->family == AF_INET) { + p->neigh_setup = ipsec_tunnel_neigh_setup; + p->ucast_probes = 0; + p->mcast_probes = 0; + } + return 0; +} +#endif /* NET_21 */ + +/* + * We call the attach routine to attach another device. + */ + +DEBUG_NO_STATIC int +ipsec_tunnel_attach(struct device *dev, struct device *physdev) +{ + int i; + struct ipsecpriv *prv = dev->priv; + + if(dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_attach: " + "no device..."); + return -ENODEV; + } + + if(prv == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_attach: " + "no private space associated with dev=%s", + dev->name ? dev->name : "NULL"); + return -ENODATA; + } + + prv->dev = physdev; + prv->hard_start_xmit = physdev->hard_start_xmit; + prv->get_stats = physdev->get_stats; + + if (physdev->hard_header) { + prv->hard_header = physdev->hard_header; + dev->hard_header = ipsec_tunnel_hard_header; + } else + dev->hard_header = NULL; + + if (physdev->rebuild_header) { + prv->rebuild_header = physdev->rebuild_header; + dev->rebuild_header = ipsec_tunnel_rebuild_header; + } else + dev->rebuild_header = NULL; + + if (physdev->set_mac_address) { + prv->set_mac_address = physdev->set_mac_address; + dev->set_mac_address = ipsec_tunnel_set_mac_address; + } else + dev->set_mac_address = NULL; + +#ifndef NET_21 + if (physdev->header_cache_bind) { + prv->header_cache_bind = physdev->header_cache_bind; + dev->header_cache_bind = ipsec_tunnel_cache_bind; + } else + dev->header_cache_bind = NULL; +#endif /* !NET_21 */ + + if (physdev->header_cache_update) { + prv->header_cache_update = physdev->header_cache_update; + dev->header_cache_update = ipsec_tunnel_cache_update; + } else + dev->header_cache_update = NULL; + + dev->hard_header_len = physdev->hard_header_len; + +#ifdef NET_21 +/* prv->neigh_setup = physdev->neigh_setup; */ + dev->neigh_setup = ipsec_tunnel_neigh_setup_dev; +#endif /* NET_21 */ + dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */ + prv->mtu = physdev->mtu; + +#ifdef PHYSDEV_TYPE + dev->type = physdev->type /* ARPHRD_TUNNEL */; /* initially */ +#endif /* PHYSDEV_TYPE */ + + dev->addr_len = physdev->addr_len; + for (i=0; iaddr_len; i++) { + dev->dev_addr[i] = physdev->dev_addr[i]; + } +#ifdef CONFIG_IPSEC_DEBUG + if(debug_tunnel & DB_TN_INIT) { + printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: " + "physical device %s being attached has HW address: %2x", + physdev->name, physdev->dev_addr[0]); + for (i=1; i < physdev->addr_len; i++) { + printk(":%02x", physdev->dev_addr[i]); + } + printk("\n"); + } +#endif /* CONFIG_IPSEC_DEBUG */ + + return 0; +} + +/* + * We call the detach routine to detach the ipsec tunnel from another device. + */ + +DEBUG_NO_STATIC int +ipsec_tunnel_detach(struct device *dev) +{ + int i; + struct ipsecpriv *prv = dev->priv; + + if(dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_detach: " + "no device..."); + return -ENODEV; + } + + if(prv == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_REVEC, + "klips_debug:ipsec_tunnel_detach: " + "no private space associated with dev=%s", + dev->name ? dev->name : "NULL"); + return -ENODATA; + } + + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_detach: " + "physical device %s being detached from virtual device %s\n", + prv->dev ? prv->dev->name : "NULL", + dev->name); + + prv->dev = NULL; + prv->hard_start_xmit = NULL; + prv->get_stats = NULL; + + prv->hard_header = NULL; +#ifdef DETACH_AND_DOWN + dev->hard_header = NULL; +#endif /* DETACH_AND_DOWN */ + + prv->rebuild_header = NULL; +#ifdef DETACH_AND_DOWN + dev->rebuild_header = NULL; +#endif /* DETACH_AND_DOWN */ + + prv->set_mac_address = NULL; +#ifdef DETACH_AND_DOWN + dev->set_mac_address = NULL; +#endif /* DETACH_AND_DOWN */ + +#ifndef NET_21 + prv->header_cache_bind = NULL; +#ifdef DETACH_AND_DOWN + dev->header_cache_bind = NULL; +#endif /* DETACH_AND_DOWN */ +#endif /* !NET_21 */ + + prv->header_cache_update = NULL; +#ifdef DETACH_AND_DOWN + dev->header_cache_update = NULL; +#endif /* DETACH_AND_DOWN */ + +#ifdef NET_21 +/* prv->neigh_setup = NULL; */ +#ifdef DETACH_AND_DOWN + dev->neigh_setup = NULL; +#endif /* DETACH_AND_DOWN */ +#endif /* NET_21 */ + dev->hard_header_len = 0; +#ifdef DETACH_AND_DOWN + dev->mtu = 0; +#endif /* DETACH_AND_DOWN */ + prv->mtu = 0; + for (i=0; idev_addr[i] = 0; + } + dev->addr_len = 0; +#ifdef PHYSDEV_TYPE + dev->type = ARPHRD_TUNNEL; +#endif /* PHYSDEV_TYPE */ + + return 0; +} + +/* + * We call the clear routine to detach all ipsec tunnels from other devices. + */ +DEBUG_NO_STATIC int +ipsec_tunnel_clear(void) +{ + int i; + struct device *ipsecdev = NULL, *prvdev; + struct ipsecpriv *prv; + char name[9]; + int ret; + + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_clear: .\n"); + + for(i = 0; i < IPSEC_NUM_IF; i++) { + sprintf(name, "ipsec%d", i); + if((ipsecdev = ipsec_dev_get(name)) != NULL) { + if((prv = (struct ipsecpriv *)(ipsecdev->priv))) { + prvdev = (struct device *)(prv->dev); + if(prvdev) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_clear: " + "physical device for device %s is %s\n", + name, prvdev->name); + if((ret = ipsec_tunnel_detach(ipsecdev))) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_clear: " + "error %d detatching device %s from device %s.\n", + ret, name, prvdev->name); + return ret; + } + } + } + } + } + return 0; +} + +DEBUG_NO_STATIC int +ipsec_tunnel_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +{ + struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data; + struct ipsecpriv *prv = dev->priv; + struct device *them; /* physical device */ +#ifdef CONFIG_IP_ALIAS + char *colon; + char realphysname[IFNAMSIZ]; +#endif /* CONFIG_IP_ALIAS */ + + if(dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "device not supplied.\n"); + return -ENODEV; + } + + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "tncfg service call #%d for dev=%s\n", + cmd, + dev->name ? dev->name : "NULL"); + switch (cmd) { + /* attach a virtual ipsec? device to a physical device */ + case IPSEC_SET_DEV: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "calling ipsec_tunnel_attatch...\n"); +#ifdef CONFIG_IP_ALIAS + /* If this is an IP alias interface, get its real physical name */ + strncpy(realphysname, cf->cf_name, IFNAMSIZ); + realphysname[IFNAMSIZ-1] = 0; + colon = strchr(realphysname, ':'); + if (colon) *colon = 0; + them = ipsec_dev_get(realphysname); +#else /* CONFIG_IP_ALIAS */ + them = ipsec_dev_get(cf->cf_name); +#endif /* CONFIG_IP_ALIAS */ + + if (them == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "physical device %s requested is null\n", + cf->cf_name); + return -ENXIO; + } + +#if 0 + if (them->flags & IFF_UP) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "physical device %s requested is not up.\n", + cf->cf_name); + return -ENXIO; + } +#endif + + if (prv && prv->dev) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "virtual device is already connected to %s.\n", + prv->dev->name ? prv->dev->name : "NULL"); + return -EBUSY; + } + return ipsec_tunnel_attach(dev, them); + + case IPSEC_DEL_DEV: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "calling ipsec_tunnel_detatch.\n"); + if (! prv->dev) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "physical device not connected.\n"); + return -ENODEV; + } + return ipsec_tunnel_detach(dev); + + case IPSEC_CLR_DEV: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "calling ipsec_tunnel_clear.\n"); + return ipsec_tunnel_clear(); + + default: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_ioctl: " + "unknown command %d.\n", + cmd); + return -EOPNOTSUPP; + } +} + +int +ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr) +{ + struct device *dev = ptr; + struct device *ipsec_dev; + struct ipsecpriv *priv; + char name[9]; + int i; + + if (dev == NULL) { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "dev=NULL for event type %ld.\n", + event); + return(NOTIFY_DONE); + } + + /* check for loopback devices */ + if (dev && (dev->flags & IFF_LOOPBACK)) { + return(NOTIFY_DONE); + } + + switch (event) { + case NETDEV_DOWN: + /* look very carefully at the scope of these compiler + directives before changing anything... -- RGB */ +#ifdef NET_21 + case NETDEV_UNREGISTER: + switch (event) { + case NETDEV_DOWN: +#endif /* NET_21 */ + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_DOWN dev=%s flags=%x\n", + dev->name, + dev->flags); + if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) { + printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n", + dev->name); + } +#ifdef NET_21 + break; + case NETDEV_UNREGISTER: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_UNREGISTER dev=%s flags=%x\n", + dev->name, + dev->flags); + break; + } +#endif /* NET_21 */ + + /* find the attached physical device and detach it. */ + for(i = 0; i < IPSEC_NUM_IF; i++) { + sprintf(name, "ipsec%d", i); + ipsec_dev = ipsec_dev_get(name); + if(ipsec_dev) { + priv = (struct ipsecpriv *)(ipsec_dev->priv); + if(priv) { + ; + if(((struct device *)(priv->dev)) == dev) { + /* dev_close(ipsec_dev); */ + /* return */ ipsec_tunnel_detach(ipsec_dev); + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "device '%s' has been detached.\n", + ipsec_dev->name); + break; + } + } else { + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "device '%s' has no private data space!\n", + ipsec_dev->name); + } + } + } + break; + case NETDEV_UP: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_UP dev=%s\n", + dev->name); + break; +#ifdef NET_21 + case NETDEV_REBOOT: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_REBOOT dev=%s\n", + dev->name); + break; + case NETDEV_CHANGE: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_CHANGE dev=%s flags=%x\n", + dev->name, + dev->flags); + break; + case NETDEV_REGISTER: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_REGISTER dev=%s\n", + dev->name); + break; + case NETDEV_CHANGEMTU: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_CHANGEMTU dev=%s to mtu=%d\n", + dev->name, + dev->mtu); + break; + case NETDEV_CHANGEADDR: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_CHANGEADDR dev=%s\n", + dev->name); + break; + case NETDEV_GOING_DOWN: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_GOING_DOWN dev=%s\n", + dev->name); + break; + case NETDEV_CHANGENAME: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "NETDEV_CHANGENAME dev=%s\n", + dev->name); + break; +#endif /* NET_21 */ + default: + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_device_event: " + "event type %ld unrecognised for dev=%s\n", + event, + dev->name); + break; + } + return NOTIFY_DONE; +} + +/* + * Called when an ipsec tunnel device is initialized. + * The ipsec tunnel device structure is passed to us. + */ + +int +ipsec_tunnel_init(struct device *dev) +{ + int i; + +#if 0 + printk(KERN_INFO + "klips_debug:ipsec_tunnel_init: " + "initialisation of device: %s\n", + dev->name ? dev->name : "NULL"); +#endif + + /* Add our tunnel functions to the device */ + dev->open = ipsec_tunnel_open; + dev->stop = ipsec_tunnel_close; + dev->hard_start_xmit = ipsec_tunnel_start_xmit; + dev->get_stats = ipsec_tunnel_get_stats; + + dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL); + if (dev->priv == NULL) + return -ENOMEM; + memset(dev->priv, 0, sizeof(struct ipsecpriv)); + + for(i = 0; i < sizeof(zeroes); i++) { + ((__u8*)(zeroes))[i] = 0; + } + +#ifndef NET_21 + /* Initialize the tunnel device structure */ + for (i = 0; i < DEV_NUMBUFFS; i++) + skb_queue_head_init(&dev->buffs[i]); +#endif /* !NET_21 */ + + dev->set_multicast_list = NULL; + dev->do_ioctl = ipsec_tunnel_ioctl; + dev->hard_header = NULL; + dev->rebuild_header = NULL; + dev->set_mac_address = NULL; +#ifndef NET_21 + dev->header_cache_bind = NULL; +#endif /* !NET_21 */ + dev->header_cache_update= NULL; + +#ifdef NET_21 +/* prv->neigh_setup = NULL; */ + dev->neigh_setup = ipsec_tunnel_neigh_setup_dev; +#endif /* NET_21 */ + dev->hard_header_len = 0; + dev->mtu = 0; + dev->addr_len = 0; + dev->type = ARPHRD_TUNNEL; /* 0 */ /* ARPHRD_ETHER; */ /* initially */ + dev->tx_queue_len = 10; /* Small queue */ + memset(dev->broadcast,0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */ + + /* New-style flags. */ + dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */; +#ifdef NET_21 + dev_init_buffers(dev); +#else /* NET_21 */ + dev->family = AF_INET; + dev->pa_addr = 0; + dev->pa_brdaddr = 0; + dev->pa_mask = 0; + dev->pa_alen = 4; +#endif /* NET_21 */ + + /* We're done. Have I forgotten anything? */ + return 0; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Module specific interface (but it links with the rest of IPSEC */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +int +ipsec_tunnel_probe(struct device *dev) +{ + ipsec_tunnel_init(dev); + return 0; +} + +static struct device dev_ipsec3 = +{ + "ipsec3\0 ", /* name */ + 0, /* recv memory end */ + 0, /* recv memory start */ + 0, /* memory end */ + 0, /* memory start */ + 0x0, /* base I/O address */ + 0, /* IRQ */ + 0, 0, 0, /* flags */ + NULL, /* next device */ + ipsec_tunnel_probe /* setup */ +}; + +static struct device dev_ipsec2 = +{ + "ipsec2\0 ", /* name */ + 0, /* recv memory end */ + 0, /* recv memory start */ + 0, /* memory end */ + 0, /* memory start */ + 0x0, /* base I/O address */ + 0, /* IRQ */ + 0, 0, 0, /* flags */ + NULL, /* next device */ + ipsec_tunnel_probe /* setup */ +}; + +static struct device dev_ipsec1 = +{ + "ipsec1\0 ", /* name */ + 0, /* recv memory end */ + 0, /* recv memory start */ + 0, /* memory end */ + 0, /* memory start */ + 0x0, /* base I/O address */ + 0, /* IRQ */ + 0, 0, 0, /* flags */ + NULL, /* next device */ + ipsec_tunnel_probe /* setup */ +}; + +static struct device dev_ipsec0 = +{ + "ipsec0\0 ", /* name */ + 0, /* recv memory end */ + 0, /* recv memory start */ + 0, /* memory end */ + 0, /* memory start */ + 0x0, /* base I/O address */ + 0, /* IRQ */ + 0, 0, 0, /* flags */ + NULL, /* next device */ + ipsec_tunnel_probe /* setup */ +}; + +int +ipsec_tunnel_init_devices(void) +{ +#if 0 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "registering device %s\n", + dev_ipsec0.name); +#endif + if (register_netdev(&dev_ipsec0) != 0) + return -EIO; +#if 0 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "registering device %s\n", + dev_ipsec1.name); +#endif + if (register_netdev(&dev_ipsec1) != 0) + return -EIO; +#if 0 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "registering device %s\n", + dev_ipsec2.name); +#endif + if (register_netdev(&dev_ipsec2) != 0) + return -EIO; +#if 0 + KLIPS_PRINT(debug_tunnel & DB_TN_INIT, + "klips_debug:ipsec_tunnel_init_devices: " + "registering device %s\n", + dev_ipsec3.name); +#endif + if (register_netdev(&dev_ipsec3) != 0) + return -EIO; + return 0; +} + +/* void */ +int +ipsec_tunnel_cleanup_devices(void) +{ + int error = 0; + + unregister_netdev(&dev_ipsec0); + unregister_netdev(&dev_ipsec1); + unregister_netdev(&dev_ipsec2); + unregister_netdev(&dev_ipsec3); + kfree(dev_ipsec0.priv); + kfree(dev_ipsec1.priv); + kfree(dev_ipsec2.priv); + kfree(dev_ipsec3.priv); + dev_ipsec0.priv=NULL; + dev_ipsec1.priv=NULL; + dev_ipsec2.priv=NULL; + dev_ipsec3.priv=NULL; + + return error; +} + +/* + * $Log: ipsec_tunnel.c,v $ + * Revision 1.18 2003/12/04 03:03:24 ken + * Cast safely for ia64 + * + * Revision 1.17 2003/11/25 00:09:44 ken + * Remove + + * + * Revision 1.16 2003/11/25 00:04:29 ken + * Fix for ATM interfaces (and some others) (willy@w.ods.org) + * + * Revision 1.15 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.14 2003/07/04 19:07:34 ken + * Added NAT-T 0.6 diff/patch from Tuomo + * + * Revision 1.13 2003/04/09 15:22:54 ken + * OE SNAT Fix (mcr) + * + * Revision 1.12 2003/02/07 13:14:25 ken + * Pullin jjo's ALG 0.8.1rc branch + * + * Revision 1.11.2.1 2003/02/06 22:09:50 jjo + * sync to alg-0.8.1-rc4 + * + * Revision 1.11 2003/01/19 22:32:30 ken + * X.509 0.9.19 -> 0.9.20 + * + * Revision 1.10 2003/01/09 04:33:54 ken + * Applied diffs from X.509 0.9.18 -> 0.9.19 + * + * Revision 1.9 2003/01/06 15:27:46 ken + * Patched NAT-T 0.5 -> 0.5a - mlafon + * + * Revision 1.8 2003/01/06 00:13:17 ken + * Fix from NAT-T 0.5a - keep udp/4500 (NAT-T Float) hole open. mlafon + * + * Revision 1.7 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.6 2002/10/16 00:21:47 ken + * Applied JuanJo's NULL Patch + * + * Revision 1.5 2002/10/16 00:16:50 ken + * Backed out David patch in prep for JuanJo's + * + * Revision 1.4 2002/10/15 17:52:47 ken + * Added David De Reu's NULL ALG Bugfix + * + * Revision 1.3 2002/09/05 03:53:52 ken + * Added NAT-T Patch + * + * Revision 1.2 2002/09/05 03:27:08 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.187 2002/03/23 19:55:17 rgb + * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if + * iptraf or another pcap app is running. + * + * Revision 1.186 2002/03/19 03:26:22 rgb + * Applied DHR's tunnel patch to streamline IKE/specialSA processing. + * + * Revision 1.185 2002/02/20 04:13:05 rgb + * Send back ICMP_PKT_FILTERED upon %reject. + * + * Revision 1.184 2002/01/29 17:17:56 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.183 2002/01/29 04:00:53 mcr + * more excise of kversions.h header. + * + * Revision 1.182 2002/01/29 02:13:18 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.181 2002/01/07 20:00:33 rgb + * Added IKE destination port debugging. + * + * Revision 1.180 2001/12/21 21:49:54 rgb + * Fixed bug as a result of moving IKE bypass above %trap/%hold code. + * + * Revision 1.179 2001/12/19 21:08:14 rgb + * Added transport protocol ports to ipsec_print_ip(). + * Update eroute info for non-SA targets. + * Added obey DF code disabled. + * Fixed formatting bugs in ipsec_tunnel_hard_header(). + * + * Revision 1.178 2001/12/05 09:36:10 rgb + * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid + * IKE packets being stolen by the %hold (and returned to the sending KMd + * in an ACQUIRE, ironically ;-). + * + * Revision 1.177 2001/11/26 09:23:50 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.170.2.1 2001/09/25 02:28:27 mcr + * struct tdb -> struct ipsec_sa. + * lifetime checks moved to common routines. + * cleaned up includes. + * + * Revision 1.170.2.2 2001/10/22 21:08:01 mcr + * include des.h, removed phony prototypes and fixed calling + * conventions to match real prototypes. + * + * Revision 1.176 2001/11/09 18:32:31 rgb + * Added Hans Schultz' fragmented UDP/500 IKE socket port selector. + * + * Revision 1.175 2001/11/06 20:47:00 rgb + * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling. + * + * Revision 1.174 2001/11/06 19:50:43 rgb + * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for + * use also by pfkey_v2_parser.c + * + * Revision 1.173 2001/10/29 21:53:44 henry + * tone down the device-down message slightly, until we can make it smarter + * + * Revision 1.172 2001/10/26 04:59:37 rgb + * Added a critical level syslog message if an ipsec device goes down. + * + * Revision 1.171 2001/10/18 04:45:21 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/freeswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.170 2001/09/25 00:09:50 rgb + * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a + * HOLD. + * + * Revision 1.169 2001/09/15 16:24:05 rgb + * Re-inject first and last HOLD packet when an eroute REPLACE is done. + * + * Revision 1.168 2001/09/14 16:58:37 rgb + * Added support for storing the first and last packets through a HOLD. + * + * Revision 1.167 2001/09/08 21:13:33 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.166 2001/08/27 19:47:59 rgb + * Clear tdb before usage. + * Added comment: clear IF before calling routing? + * + * Revision 1.165 2001/07/03 01:23:53 rgb + * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len > + * emtu, and don't drop. + * + * Revision 1.164 2001/06/14 19:35:10 rgb + * Update copyright date. + * + * Revision 1.163 2001/06/06 20:28:51 rgb + * Added sanity checks for NULL skbs and devices. + * Added more debugging output to various functions. + * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach(). + * Renamed ipsec_tunnel_attach() virtual and physical device arguments. + * Corrected neigh_setup() device function assignment. + * Keep valid pointers to ipsec_tunnel_*() on detach. + * Set dev->type to the originally-initiallised value. + * + * Revision 1.162 2001/06/01 07:28:04 rgb + * Added sanity checks for detached devices. Don't down virtual devices + * to prevent packets going out in the clear if the detached device comes + * back up. + * + * Revision 1.161 2001/05/30 08:14:52 rgb + * Removed vestiges of esp-null transforms. + * NetDev Notifier instrumentation to track down disappearing devices. + * + * Revision 1.160 2001/05/29 05:15:12 rgb + * Added SS' PMTU patch which notifies sender if packet doesn't fit + * physical MTU (if it wasn't ICMP) and then drops it. + * + * Revision 1.159 2001/05/27 06:12:12 rgb + * Added structures for pid, packet count and last access time to eroute. + * Added packet count to beginning of /proc/net/ipsec_eroute. + * + * Revision 1.158 2001/05/24 05:39:33 rgb + * Applied source zeroing to 2.2 ip_route_output() call as well to enable + * PASS eroutes for opportunism. + * + * Revision 1.157 2001/05/23 22:35:28 rgb + * 2.4 source override simplification. + * + * Revision 1.156 2001/05/23 21:41:31 rgb + * Added error return code printing on ip_route_output(). + * + * Revision 1.155 2001/05/23 05:09:13 rgb + * Fixed incorrect ip_route_output() failure message. + * + * Revision 1.154 2001/05/21 14:53:31 rgb + * Added debug statement for case when ip_route_output() fails, causing + * packet to be dropped, but log looked ok. + * + * Revision 1.153 2001/05/19 02:37:54 rgb + * Fixed missing comment termination. + * + * Revision 1.152 2001/05/19 02:35:50 rgb + * Debug code optimisation for non-debug speed. + * Kernel version compiler define comments. + * 2.2 and 2.4 kernel ip_send device and ip debug output added. + * + * Revision 1.151 2001/05/18 16:17:35 rgb + * Changed reference from "magic" to "shunt" SAs. + * + * Revision 1.150 2001/05/18 16:12:19 rgb + * Changed UDP/500 bypass test from 3 nested ifs to one anded if. + * + * Revision 1.149 2001/05/16 04:39:33 rgb + * Add default == eroute.dest to IKE bypass conditions for magic eroutes. + * + * Revision 1.148 2001/05/05 03:31:41 rgb + * IP frag debugging updates and enhancements. + * + * Revision 1.147 2001/05/03 19:41:40 rgb + * Added SS' skb_cow fix for 2.4.4. + * + * Revision 1.146 2001/04/30 19:28:16 rgb + * Update for 2.4.4. ip_select_ident() now has 3 args. + * + * Revision 1.145 2001/04/23 14:56:10 rgb + * Added spin_lock() check to prevent double-locking for multiple + * transforms and hence kernel lock-ups with SMP kernels. + * + * Revision 1.144 2001/04/21 23:04:45 rgb + * Define out skb->used for 2.4 kernels. + * Check if soft expire has already been sent before sending another to + * prevent ACQUIRE flooding. + * + * Revision 1.143 2001/03/16 07:37:21 rgb + * Added comments to all #endifs. + * + * Revision 1.142 2001/02/28 05:03:27 rgb + * Clean up and rationalise startup messages. + * + * Revision 1.141 2001/02/27 22:24:54 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.140 2001/02/27 06:40:12 rgb + * Fixed TRAP->HOLD eroute byte order. + * + * Revision 1.139 2001/02/26 20:38:59 rgb + * Added compiler defines for 2.4.x-specific code. + * + * Revision 1.138 2001/02/26 19:57:27 rgb + * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part + * of the new SPD and to support opportunistic. + * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs. + * + * Revision 1.137 2001/02/19 22:29:49 rgb + * Fixes for presence of active ipv6 segments which share ipsec physical + * device (gg). + * + * Revision 1.136 2001/01/29 22:30:38 rgb + * Fixed minor acquire debug printing bug. + * + * Revision 1.135 2001/01/29 22:19:45 rgb + * Zero source address for 2.4 bypass route lookup. + * + * Revision 1.134 2001/01/23 20:19:49 rgb + * 2.4 fix to remove removed is_clone member. + * + * Revision 1.133 2000/12/09 22:08:35 rgb + * Fix NET_23 bug, should be NETDEV_23. + * + * Revision 1.132 2000/12/01 06:54:50 rgb + * Fix for new 2.4 IP TTL default variable name. + * + * Revision 1.131 2000/11/09 20:52:15 rgb + * More spinlock shuffling, locking earlier and unlocking later in rcv to + * include ipcomp and prevent races, renaming some tdb variables that got + * forgotten, moving some unlocks to include tdbs and adding a missing + * unlock. Thanks to Svenning for some of these. + * + * Revision 1.130 2000/11/09 20:11:22 rgb + * Minor shuffles to fix non-standard kernel config option selection. + * + * Revision 1.129 2000/11/06 04:32:49 rgb + * Clean up debug printing. + * Copy skb->protocol for all kernel versions. + * Ditched spin_lock_irqsave in favour of spin_lock. + * Disabled TTL decrement, done in ip_forward. + * Added debug printing before pfkey_acquire(). + * Fixed printk-deltdbchain-spin_lock races (Svenning). + * Use defaultTTL for 2.1+ kernels. + * Add Svenning's adaptive content compression. + * Fix up debug display arguments. + * + * Revision 1.128 2000/09/28 00:58:57 rgb + * Moved the IKE passthrough check after the eroute lookup so we can pass + * IKE through intermediate tunnels. + * + * Revision 1.127 2000/09/22 17:52:11 rgb + * Fixed misleading ipcomp debug output. + * + * Revision 1.126 2000/09/22 04:22:56 rgb + * Fixed dumb spi->cpi conversion error. + * + * Revision 1.125 2000/09/21 04:34:48 rgb + * A few debug-specific things should be hidden under + * CONFIG_IPSEC_DEBUG.(MB) + * Improved ip_send() error handling.(MB) + * + * Revision 1.124 2000/09/21 03:40:58 rgb + * Added more debugging to try and track down the cpi outward copy problem. + * + * Revision 1.123 2000/09/19 07:08:49 rgb + * Added debugging to outgoing compression report. + * + * Revision 1.122 2000/09/18 19:21:26 henry + * RGB-supplied fix for RH5.2 problem + * + * Revision 1.121 2000/09/17 21:05:09 rgb + * Added tdb to skb_compress call to write in cpi. + * + * Revision 1.120 2000/09/17 16:57:16 rgb + * Added Svenning's patch to remove restriction of ipcomp to innermost + * transform. + * + * Revision 1.119 2000/09/15 11:37:01 rgb + * Merge in heavily modified Svenning Soerensen's + * IPCOMP zlib deflate code. + * + * Revision 1.118 2000/09/15 04:57:16 rgb + * Moved debug output after sanity check. + * Added tos copy sysctl. + * + * Revision 1.117 2000/09/12 03:22:51 rgb + * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to + * sysctl. + * + * Revision 1.116 2000/09/08 19:18:19 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * Added outgoing opportunistic hook, ifdef'ed out. + * + * Revision 1.115 2000/08/30 05:27:29 rgb + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. + * Kill remainder of tdb_xform, tdb_xdata, xformsw. + * + * Revision 1.114 2000/08/28 18:15:46 rgb + * Added MB's nf-debug reset patch. + * + * Revision 1.113 2000/08/27 02:26:40 rgb + * Send all no-eroute-bypass, pluto-bypass and passthrough packets through + * fragmentation machinery for 2.0, 2.2 and 2.4 kernels. + * + * Revision 1.112 2000/08/20 21:37:33 rgb + * Activated pfkey_expire() calls. + * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil) + * Re-arranged the order of soft and hard expiry to conform to RFC2367. + * Clean up references to CONFIG_IPSEC_PFKEYv2. + * + * Revision 1.111 2000/08/01 14:51:51 rgb + * Removed _all_ remaining traces of DES. + * + * Revision 1.110 2000/07/28 14:58:31 rgb + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. + * + * Revision 1.109 2000/07/28 13:50:54 rgb + * Changed enet_statistics to net_device_stats and added back compatibility + * for pre-2.1.19. + * + * Revision 1.108 2000/05/16 03:03:11 rgb + * Updates for 2.3.99pre8 from MB. + * + * Revision 1.107 2000/05/10 23:08:21 rgb + * Print a debug warning about bogus packets received by the outgoing + * processing machinery only when klipsdebug is not set to none. + * Comment out the device initialisation informational messages. + * + * Revision 1.106 2000/05/10 19:17:14 rgb + * Define an IP_SEND macro, intending to have all packet passthroughs + * use fragmentation. This didn't quite work, but is a step in the + * right direction. + * Added buffer allocation debugging statements. + * Added configure option to shut off no eroute passthrough. + * Only check usetime against soft and hard limits if the tdb has been + * used. + * Cast output of ntohl so that the broken prototype doesn't make our + * compile noisy. + * + * Revision 1.105 2000/03/22 16:15:37 rgb + * Fixed renaming of dev_get (MB). + * + * Revision 1.104 2000/03/16 14:04:15 rgb + * Indented headers for readability. + * Fixed debug scope to enable compilation with debug off. + * Added macros for ip_chk_addr and IS_MYADDR for identifying self. + * + * Revision 1.103 2000/03/16 07:11:07 rgb + * Hardcode PF_KEYv2 support. + * Fixed bug which allowed UDP/500 packet from another machine + * through in the clear. + * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec. + * + * Revision 1.102 2000/03/14 12:26:59 rgb + * Added skb->nfct support for clearing netfilter conntrack bits (MB). + * + * Revision 1.101 2000/02/14 21:05:22 rgb + * Added MB's netif_queue fix for kernels 2.3.43+. + * + * Revision 1.100 2000/01/26 10:04:57 rgb + * Fixed noisy 2.0 printk arguments. + * + * Revision 1.99 2000/01/21 06:16:25 rgb + * Added sanity checks on skb_push(), skb_pull() to prevent panics. + * Switched to AF_ENCAP macro. + * Shortened debug output per packet and re-arranging debug_tunnel + * bitmap flags, while retaining necessary information to avoid + * trampling the kernel print ring buffer. + * Reformatted recursion switch code. + * Changed all references to tdb_proto to tdb_said.proto for clarity. + * + * Revision 1.98 2000/01/13 08:09:31 rgb + * Shuffled debug_tunnel switches to focus output. + * Fixed outgoing recursion bug, limiting to recursing only if the remote + * SG changes and if it is valid, ie. not passthrough. + * Clarified a number of debug messages. + * + * Revision 1.97 2000/01/10 16:37:16 rgb + * MB support for new ip_select_ident() upon disappearance of + * ip_id_count in 2.3.36+. + * + * Revision 1.96 1999/12/31 14:59:08 rgb + * MB fix to use new skb_copy_expand in kernel 2.3.35. + * + * Revision 1.95 1999/12/29 21:15:44 rgb + * Fix tncfg to aliased device bug. + * + * Revision 1.94 1999/12/22 04:26:06 rgb + * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable + * debugging by providing external labels to all functions with debugging + * turned on. + * + * Revision 1.93 1999/12/13 13:30:14 rgb + * Changed MTU reports and HW address reporting back to debug only. + * + * Revision 1.92 1999/12/07 18:57:56 rgb + * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled. + * + * Revision 1.91 1999/12/01 22:15:36 rgb + * Add checks for LARVAL and DEAD SAs. + * Change state of SA from MATURE to DYING when a soft lifetime is + * reached and print debug warning. + * + * Revision 1.90 1999/11/23 23:04:04 rgb + * Use provided macro ADDRTOA_BUF instead of hardcoded value. + * Sort out pfkey and freeswan headers, putting them in a library path. + * + * Revision 1.89 1999/11/18 18:50:59 rgb + * Changed all device registrations for static linking to + * dynamic to reduce the number and size of patches. + * + * Revision 1.88 1999/11/18 04:09:19 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.87 1999/11/17 15:53:40 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.86 1999/10/16 18:25:37 rgb + * Moved SA lifetime expiry checks before packet processing. + * Expire SA on replay counter rollover. + * + * Revision 1.85 1999/10/16 04:24:31 rgb + * Add stats for time since last packet. + * + * Revision 1.84 1999/10/16 00:30:47 rgb + * Added SA lifetime counting. + * + * Revision 1.83 1999/10/15 22:15:57 rgb + * Clean out cruft. + * Add debugging. + * + * Revision 1.82 1999/10/08 18:26:19 rgb + * Fix 2.0.3x outgoing fragmented packet memory leak. + * + * Revision 1.81 1999/10/05 02:38:54 rgb + * Lower the default mtu of virtual devices to 16260. + * + * Revision 1.80 1999/10/03 18:56:41 rgb + * Spinlock support for 2.3.xx. + * Don't forget to undo spinlocks on error! + * Check for valid eroute before copying the structure. + * + * Revision 1.79 1999/10/01 15:44:53 rgb + * Move spinlock header include to 2.1> scope. + * + * Revision 1.78 1999/10/01 00:02:43 rgb + * Added tdb structure locking. + * Added eroute structure locking. + * + * Revision 1.77 1999/09/30 02:52:29 rgb + * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c). + * + * Revision 1.76 1999/09/25 19:31:27 rgb + * Refine MSS hack to affect SYN, but not SYN+ACK packets. + * + * Revision 1.75 1999/09/24 22:52:38 rgb + * Fix two things broken in 2.0.38 by trying to fix network notifiers. + * + * Revision 1.74 1999/09/24 00:30:37 rgb + * Add test for changed source as well as destination to check for + * recursion. + * + * Revision 1.73 1999/09/23 20:52:24 rgb + * Add James Morris' MSS hack patch, disabled. + * + * Revision 1.72 1999/09/23 20:22:40 rgb + * Enable, tidy and fix network notifier code. + * + * Revision 1.71 1999/09/23 18:09:05 rgb + * Clean up 2.2.x fragmenting traces. + * Disable dev->type switching, forcing ARPHRD_TUNNEL. + * + * Revision 1.70 1999/09/22 14:14:24 rgb + * Add sanity checks for revectored calls to prevent calling a downed I/F. + * + * Revision 1.69 1999/09/21 15:00:57 rgb + * Add Marc Boucher's packet size check. + * Flesh out network device notifier code. + * + * Revision 1.68 1999/09/18 11:39:57 rgb + * Start to add (disabled) netdevice notifier code. + * + * Revision 1.67 1999/09/17 23:44:40 rgb + * Add a comment warning potential code hackers to stay away from mac.raw. + * + * Revision 1.66 1999/09/17 18:04:02 rgb + * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB). + * Ditch TTL decrement in 2.2 (MB). + * + * Revision 1.65 1999/09/15 23:15:35 henry + * Marc Boucher's PPP fixes + * + * Revision 1.64 1999/09/07 13:40:53 rgb + * Ditch unreliable references to skb->mac.raw. + * + * Revision 1.63 1999/08/28 11:33:09 rgb + * Check for null skb->mac pointer. + * + * Revision 1.62 1999/08/28 02:02:30 rgb + * Add Marc Boucher's fix for properly dealing with skb->sk. + * + * Revision 1.61 1999/08/27 05:23:05 rgb + * Clean up skb->data/raw/nh/h manipulation. + * Add Marc Boucher's mods to aid tcpdump. + * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand. + * Re-order hard_header stripping -- might be able to remove it... + * + * Revision 1.60 1999/08/26 20:01:02 rgb + * Tidy up compiler directives and macros. + * Re-enable ICMP for tunnels where inner_dst != outer_dst. + * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x. + * + * Revision 1.59 1999/08/25 15:44:41 rgb + * Clean up from 2.2.x instrumenting for compilation under 2.0.36. + * + * Revision 1.58 1999/08/25 15:00:54 rgb + * Add dst cache code for 2.2.xx. + * Add sanity check for skb packet header pointers. + * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and + * *_rebuild_header. + * Add neigh_* cache code. + * Change dev->type back to ARPHRD_TUNNEL. + * + * Revision 1.57 1999/08/17 21:50:23 rgb + * Fixed minor debug output bugs. + * Regrouped error recovery exit code. + * Added compiler directives to remove unwanted code and symbols. + * Shut off ICMP messages: to be refined to only send ICMP to remote systems. + * Add debugging code for output function addresses. + * Fix minor bug in (possibly unused) header_cache_bind function. + * Add device neighbour caching code. + * Change dev->type from ARPHRD_TUNNEL to physdev->type. + * + * Revision 1.56 1999/08/03 17:22:56 rgb + * Debug output clarification using KERN_* macros. Other inactive changes + * added. + * + * Revision 1.55 1999/08/03 16:58:46 rgb + * Fix skb_copy_expand size bug. Was getting incorrect size. + * + * Revision 1.54 1999/07/14 19:32:38 rgb + * Fix oversize packet crash and ssh stalling in 2.2.x kernels. + * + * Revision 1.53 1999/06/10 15:44:02 rgb + * Minor reformatting and clean-up. + * + * Revision 1.52 1999/05/09 03:25:36 rgb + * Fix bug introduced by 2.2 quick-and-dirty patch. + * + * Revision 1.51 1999/05/08 21:24:59 rgb + * Add casting to silence the 2.2.x compile. + * + * Revision 1.50 1999/05/05 22:02:32 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.49 1999/04/29 15:18:52 rgb + * Change gettdb parameter to a pointer to reduce stack loading and + * facilitate parameter sanity checking. + * Fix undetected bug that might have tried to access a null pointer. + * Eliminate unnessessary usage of tdb_xform member to further switch + * away from the transform switch to the algorithm switch. + * Add return values to init and cleanup functions. + * + * Revision 1.48 1999/04/16 15:38:00 rgb + * Minor rearrangement of freeing code to avoid memory leaks with impossible or + * rare situations. + * + * Revision 1.47 1999/04/15 15:37:25 rgb + * Forward check changes from POST1_00 branch. + * + * Revision 1.32.2.4 1999/04/13 21:00:18 rgb + * Ditch 'things I wish I had known before...'. + * + * Revision 1.32.2.3 1999/04/13 20:34:38 rgb + * Free skb after fragmentation. + * Use stats more effectively. + * Add I/F to mtu notch-down reporting. + * + * Revision 1.32.2.2 1999/04/02 04:26:14 rgb + * Backcheck from HEAD, pre1.0. + * + * Revision 1.46 1999/04/11 00:29:00 henry + * GPL boilerplate + * + * Revision 1.45 1999/04/07 15:42:01 rgb + * Fix mtu/ping bug AGAIN! + * + * Revision 1.44 1999/04/06 04:54:27 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.43 1999/04/04 03:57:07 rgb + * ip_fragment() doesn't free the supplied skb. Freed. + * + * Revision 1.42 1999/04/01 23:27:15 rgb + * Preload size of virtual mtu. + * + * Revision 1.41 1999/04/01 09:31:23 rgb + * Invert meaning of ICMP PMTUD config option and clarify. + * Code clean-up. + * + * Revision 1.40 1999/04/01 04:37:17 rgb + * SSH stalling bug fix. + * + * Revision 1.39 1999/03/31 23:44:28 rgb + * Don't send ICMP on DF and frag_off. + * + * Revision 1.38 1999/03/31 15:20:10 rgb + * Quiet down debugging. + * + * Revision 1.37 1999/03/31 08:30:31 rgb + * Add switch to shut off ICMP PMTUD packets. + * + * Revision 1.36 1999/03/31 05:44:47 rgb + * Keep PMTU reduction private. + * + * Revision 1.35 1999/03/27 15:13:02 rgb + * PMTU/fragmentation bug fix. + * + * Revision 1.34 1999/03/17 21:19:26 rgb + * Fix kmalloc nonatomic bug. + * + * Revision 1.33 1999/03/17 15:38:42 rgb + * Code clean-up. + * ESP_NULL IV bug fix. + * + * Revision 1.32 1999/03/01 20:44:25 rgb + * Code clean-up. + * Memory leak bug fix. + * + * Revision 1.31 1999/02/27 00:02:09 rgb + * Tune to report the MTU reduction once, rather than after every recursion + * through the encapsulating code, preventing tcp stream stalling. + * + * Revision 1.30 1999/02/24 20:21:01 rgb + * Reformat debug printk's. + * Fix recursive encapsulation, dynamic MTU bugs and add debugging code. + * Clean-up. + * + * Revision 1.29 1999/02/22 17:08:14 rgb + * Fix recursive encapsulation code. + * + * Revision 1.28 1999/02/19 18:27:02 rgb + * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery. + * + * Revision 1.27 1999/02/17 16:51:37 rgb + * Clean out unused cruft. + * Temporarily tone down volume of debug output. + * Temporarily shut off fragment rejection. + * Disabled temporary failed recursive encapsulation loop. + * + * Revision 1.26 1999/02/12 21:21:26 rgb + * Move KLIPS_PRINT to ipsec_netlink.h for accessibility. + * + * Revision 1.25 1999/02/11 19:38:27 rgb + * More clean-up. + * Add sanity checking for skb_copy_expand() to prevent kernel panics on + * skb_put() values out of range. + * Fix head/tailroom calculation causing skb_put() out-of-range values. + * Fix return values to prevent 'nonatomic alloc_skb' warnings. + * Allocate new skb iff needed. + * Added more debug statements. + * Make headroom depend on structure, not hard-coded values. + * + * Revision 1.24 1999/02/10 23:20:33 rgb + * Shut up annoying 'statement has no effect' compiler warnings with + * debugging compiled out. + * + * Revision 1.23 1999/02/10 22:36:30 rgb + * Clean-up obsolete, unused and messy code. + * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros. + * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated + * original ipsec_tunnel_start_xmit. + * Send all packet with different inner and outer destinations directly to + * the attached physical device, rather than back through ip_forward, + * preventing disappearing routes problems. + * Do sanity checking before investing too much CPU in allocating new + * structures. + * Fail on IP header options: We cannot process them yet. + * Add some helpful comments. + * Use virtual device for parameters instead of physical device. + * + * Revision 1.22 1999/02/10 03:03:02 rgb + * Duh. Fixed the TTL bug: forgot to update the checksum. + * + * Revision 1.21 1999/02/09 23:17:53 rgb + * Add structure members to ipsec_print_ip debug function. + * Temporarily fix TTL bug preventing tunnel mode from functioning. + * + * Revision 1.20 1999/02/09 00:14:25 rgb + * Add KLIPSPRINT macro. (Not used yet, though.) + * Delete old ip_tunnel code (BADCODE). + * Decrement TTL in outgoing packet. + * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL. + * Delete ethernet only feature and fix hard-coded hard_header_len. + * + * Revision 1.19 1999/01/29 17:56:22 rgb + * 64-bit re-fix submitted by Peter Onion. + * + * Revision 1.18 1999/01/28 22:43:24 rgb + * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion. + * + * Revision 1.17 1999/01/26 02:08:16 rgb + * Removed CONFIG_IPSEC_ALGO_SWITCH macro. + * Removed dead code. + * + * Revision 1.16 1999/01/22 06:25:26 rgb + * Cruft clean-out. + * Added algorithm switch code. + * 64-bit clean-up. + * Passthrough on IPIP protocol, spi 0x0 fix. + * Enhanced debugging. + * + * Revision 1.15 1998/12/01 13:22:04 rgb + * Added support for debug printing of version info. + * + * Revision 1.14 1998/11/30 13:22:55 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.13 1998/11/17 21:13:52 rgb + * Put IKE port bypass debug output in user-switched debug statements. + * + * Revision 1.12 1998/11/13 13:20:25 rgb + * Fixed ntohs bug in udp/500 hole for IKE. + * + * Revision 1.11 1998/11/10 08:01:19 rgb + * Kill tcp/500 hole, keep udp/500 hole. + * + * Revision 1.10 1998/11/09 21:29:26 rgb + * If no eroute is found, discard packet and incr. tx_error. + * + * Revision 1.9 1998/10/31 06:50:00 rgb + * Add tcp/udp/500 bypass. + * Fixed up comments in #endif directives. + * + * Revision 1.8 1998/10/27 00:34:31 rgb + * Reformat debug output of IP headers. + * Newlines added before calls to ipsec_print_ip. + * + * Revision 1.7 1998/10/19 14:44:28 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * + * Revision 1.6 1998/10/09 04:31:35 rgb + * Added 'klips_debug' prefix to all klips printk debug statements. + * + * Revision 1.5 1998/08/28 03:09:51 rgb + * Prevent kernel log spam with default route through ipsec. + * + * Revision 1.4 1998/08/05 22:23:09 rgb + * Change setdev return code to ENXIO for a non-existant physical device. + * + * Revision 1.3 1998/07/29 20:41:11 rgb + * Add ipsec_tunnel_clear to clear all tunnel attachments. + * + * Revision 1.2 1998/06/25 20:00:33 rgb + * Clean up #endif comments. + * Rename dev_ipsec to dev_ipsec0 for consistency. + * Document ipsec device fields. + * Make ipsec_tunnel_probe visible from rest of kernel for static linking. + * Get debugging report for *every* ipsec device initialisation. + * Comment out redundant code. + * + * Revision 1.1 1998/06/18 21:27:50 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.8 1998/06/14 23:49:40 rgb + * Clarify version reporting on module loading. + * + * Revision 1.7 1998/05/27 23:19:20 rgb + * Added version reporting. + * + * Revision 1.6 1998/05/18 21:56:23 rgb + * Clean up for numerical consistency of output and cleaning up debug code. + * + * Revision 1.5 1998/05/12 02:44:23 rgb + * Clarifying 'no e-route to host' message. + * + * Revision 1.4 1998/04/30 15:34:35 rgb + * Enclosed most remaining debugging statements in #ifdef's to make it quieter. + * + * Revision 1.3 1998/04/21 21:28:54 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.2 1998/04/12 22:03:24 rgb + * Updated ESP-3DES-HMAC-MD5-96, + * ESP-DES-HMAC-MD5-96, + * AH-HMAC-MD5-96, + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository + * from old standards (RFC182[5-9] to new (as of March 1998) drafts. + * + * Fixed eroute references in /proc/net/ipsec*. + * + * Started to patch module unloading memory leaks in ipsec_netlink and + * radij tree unloading. + * + * Revision 1.1 1998/04/09 03:06:12 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:04 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.5 1997/06/03 04:24:48 ji + * Added transport mode. + * Changed the way routing is done. + * Lots of bug fixes. + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_tunnel.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_tunnel.h --- linux-2.4.29/net/ipsec/ipsec_tunnel.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_tunnel.h Thu Sep 5 05:13:17 2002 @@ -0,0 +1,248 @@ +/* + * IPSEC tunneling code + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_tunnel.h,v 1.1.1.1 2002/09/05 03:13:17 ken Exp $ + */ + + +#ifdef NET_21 +# define DEV_QUEUE_XMIT(skb, device, pri) {\ + skb->dev = device; \ + neigh_compat_output(skb); \ + /* skb->dst->output(skb); */ \ + } +# define ICMP_SEND(skb_in, type, code, info, dev) \ + icmp_send(skb_in, type, code, htonl(info)) +# define IP_SEND(skb, dev) \ + ip_send(skb); +#else /* NET_21 */ +# define DEV_QUEUE_XMIT(skb, device, pri) {\ + dev_queue_xmit(skb, device, pri); \ + } +# define ICMP_SEND(skb_in, type, code, info, dev) \ + icmp_send(skb_in, type, code, info, dev) +# define IP_SEND(skb, dev) \ + if(ntohs(iph->tot_len) > physmtu) { \ + ip_fragment(NULL, skb, dev, 0); \ + dev_kfree_skb(skb, FREE_WRITE); \ + } else { \ + dev_queue_xmit(skb, dev, SOPRI_NORMAL); \ + } +#endif /* NET_21 */ + + +/* + * Heavily based on drivers/net/new_tunnel.c. Lots + * of ideas also taken from the 2.1.x version of drivers/net/shaper.c + */ + +struct ipsectunnelconf +{ + __u32 cf_cmd; + union + { + char cfu_name[12]; + } cf_u; +#define cf_name cf_u.cfu_name +}; + +#define IPSEC_SET_DEV (SIOCDEVPRIVATE) +#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1) +#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2) + +#ifdef __KERNEL__ +#include +#ifndef KERNEL_VERSION +# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif +struct ipsecpriv +{ + struct sk_buff_head sendq; + struct device *dev; + struct wait_queue *wait_queue; + char locked; + int (*hard_start_xmit) (struct sk_buff *skb, + struct device *dev); + int (*hard_header) (struct sk_buff *skb, + struct device *dev, + unsigned short type, + void *daddr, + void *saddr, + unsigned len); +#ifdef NET_21 + int (*rebuild_header)(struct sk_buff *skb); +#else /* NET_21 */ + int (*rebuild_header)(void *buff, struct device *dev, + unsigned long raddr, struct sk_buff *skb); +#endif /* NET_21 */ + int (*set_mac_address)(struct device *dev, void *addr); +#ifndef NET_21 + void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev, + unsigned short htype, __u32 daddr); +#endif /* !NET_21 */ + void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr); + struct net_device_stats *(*get_stats)(struct device *dev); + struct net_device_stats mystats; + int mtu; /* What is the desired MTU? */ +}; + +#define IPSEC_NUM_IF 4 + +extern char ipsec_tunnel_c_version[]; + +int ipsec_tunnel_init_devices(void); + +/* void */ int ipsec_tunnel_cleanup_devices(void); + +extern /* void */ int ipsec_init(void); + +extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev); + +#ifdef CONFIG_IPSEC_DEBUG +extern int debug_tunnel; +extern int sysctl_ipsec_debug_verbose; +#endif /* CONFIG_IPSEC_DEBUG */ +#endif /* __KERNEL__ */ + +#ifdef CONFIG_IPSEC_DEBUG +#define DB_TN_INIT 0x0001 +#define DB_TN_PROCFS 0x0002 +#define DB_TN_XMIT 0x0010 +#define DB_TN_OHDR 0x0020 +#define DB_TN_CROUT 0x0040 +#define DB_TN_OXFS 0x0080 +#define DB_TN_REVEC 0x0100 +#endif /* CONFIG_IPSEC_DEBUG */ + +/* + * $Log: ipsec_tunnel.h,v $ + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.23 2001/11/06 19:50:44 rgb + * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for + * use also by pfkey_v2_parser.c + * + * Revision 1.22 2001/09/15 16:24:05 rgb + * Re-inject first and last HOLD packet when an eroute REPLACE is done. + * + * Revision 1.21 2001/06/14 19:35:10 rgb + * Update copyright date. + * + * Revision 1.20 2000/09/15 11:37:02 rgb + * Merge in heavily modified Svenning Soerensen's + * IPCOMP zlib deflate code. + * + * Revision 1.19 2000/09/08 19:12:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.18 2000/07/28 13:50:54 rgb + * Changed enet_statistics to net_device_stats and added back compatibility + * for pre-2.1.19. + * + * Revision 1.17 1999/11/19 01:12:15 rgb + * Purge unneeded proc_info prototypes, now that static linking uses + * dynamic proc_info registration. + * + * Revision 1.16 1999/11/18 18:51:00 rgb + * Changed all device registrations for static linking to + * dynamic to reduce the number and size of patches. + * + * Revision 1.15 1999/11/18 04:14:21 rgb + * Replaced all kernel version macros to shorter, readable form. + * Added CONFIG_PROC_FS compiler directives in case it is shut off. + * Added Marc Boucher's 2.3.25 proc patches. + * + * Revision 1.14 1999/05/25 02:50:10 rgb + * Fix kernel version macros for 2.0.x static linking. + * + * Revision 1.13 1999/05/25 02:41:06 rgb + * Add ipsec_klipsdebug support for static linking. + * + * Revision 1.12 1999/05/05 22:02:32 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.11 1999/04/29 15:19:50 rgb + * Add return values to init and cleanup functions. + * + * Revision 1.10 1999/04/16 16:02:39 rgb + * Bump up macro to 4 ipsec I/Fs. + * + * Revision 1.9 1999/04/15 15:37:25 rgb + * Forward check changes from POST1_00 branch. + * + * Revision 1.5.2.1 1999/04/02 04:26:14 rgb + * Backcheck from HEAD, pre1.0. + * + * Revision 1.8 1999/04/11 00:29:01 henry + * GPL boilerplate + * + * Revision 1.7 1999/04/06 04:54:28 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.6 1999/03/31 05:44:48 rgb + * Keep PMTU reduction private. + * + * Revision 1.5 1999/02/10 22:31:20 rgb + * Change rebuild_header member to reflect generality of link layer. + * + * Revision 1.4 1998/12/01 13:22:04 rgb + * Added support for debug printing of version info. + * + * Revision 1.3 1998/07/29 20:42:46 rgb + * Add a macro for clearing all tunnel devices. + * Rearrange structures and declarations for sharing with userspace. + * + * Revision 1.2 1998/06/25 20:01:45 rgb + * Make prototypes available for ipsec_init and ipsec proc_dir_entries + * for static linking. + * + * Revision 1.1 1998/06/18 21:27:50 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.3 1998/05/18 21:51:50 rgb + * Added macros for num of I/F's and a procfs debug switch. + * + * Revision 1.2 1998/04/21 21:29:09 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.1 1998/04/09 03:06:13 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:05 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.5 1997/06/03 04:24:48 ji + * Added transport mode. + * Changed the way routing is done. + * Lots of bug fixes. + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_xform.c linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_xform.c --- linux-2.4.29/net/ipsec/ipsec_xform.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_xform.c Wed Nov 19 03:29:41 2003 @@ -0,0 +1,371 @@ +/* + * Common routines for IPSEC transformations. + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_xform.c,v 1.2 2003/11/19 02:29:41 mcr Exp $ + */ + +#include +#include +#include /* printk() */ + +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include +#include /* get_random_bytes() */ +#include +#ifdef SPINLOCK +# ifdef SPINLOCK_23 +# include /* *lock* */ +# else /* SPINLOCK_23 */ +# include /* *lock* */ +# endif /* SPINLOCK_23 */ +#endif /* SPINLOCK */ +#ifdef NET_21 +# include +# include +#endif +#include +#include + +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_xform.h" +#include "ipsec_ipe4.h" +#include "ipsec_ah.h" +#include "ipsec_esp.h" + +#include +#include + +#ifdef CONFIG_IPSEC_DEBUG +int debug_xform = 0; +#endif /* CONFIG_IPSEC_DEBUG */ + +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) + +extern int des_set_key(caddr_t, caddr_t); + +struct xformsw xformsw[] = { +{ XF_IP4, 0, "IPv4_Encapsulation"}, +{ XF_AHHMACMD5, XFT_AUTH, "HMAC_MD5_Authentication"}, +{ XF_AHHMACSHA1, XFT_AUTH, "HMAC_SHA-1_Authentication"}, +{ XF_ESP3DES, XFT_CONF, "3DES_Encryption"}, +{ XF_ESP3DESMD596, XFT_CONF, "3DES-MD5-96_Encryption"}, +{ XF_ESP3DESSHA196, XFT_CONF, "3DES-SHA1-96_Encryption"}, +{ XF_ESPNULLMD596, XFT_CONF, "NULL-MD5-96_ESP_*Plaintext*"}, +{ XF_ESPNULLSHA196, XFT_CONF, "NULL-SHA1-96_ESP_*Plaintext*"}, +}; + +struct tdb *tdbh[TDB_HASHMOD]; +#ifdef SPINLOCK +spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED; +#else /* SPINLOCK */ +spinlock_t tdb_lock; +#endif /* SPINLOCK */ +struct xformsw *xformswNXFORMSW = &xformsw[sizeof(xformsw)/sizeof(xformsw[0])]; + +int +ipsec_tdbinit(void) +{ + int i; + + for(i = 1; i < TDB_HASHMOD; i++) { + tdbh[i] = NULL; + } + return 0; +} + +/* + * $Log: ipsec_xform.c,v $ + * Revision 1.2 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.59 2002/03/29 15:01:36 rgb + * Delete decommissioned code. + * + * Revision 1.58 2002/01/29 17:17:57 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.57 2002/01/29 04:00:53 mcr + * more excise of kversions.h header. + * + * Revision 1.56 2001/11/27 05:17:22 mcr + * turn off the worst of the per-packet debugging. + * + * Revision 1.55 2001/11/26 09:23:50 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.54 2001/10/18 04:45:21 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/freeswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.53 2001/09/08 21:13:34 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.52 2001/06/14 19:35:11 rgb + * Update copyright date. + * + * Revision 1.51 2001/05/30 08:14:03 rgb + * Removed vestiges of esp-null transforms. + * + * Revision 1.50 2001/05/03 19:43:18 rgb + * Initialise error return variable. + * Update SENDERR macro. + * Fix sign of error return code for ipsec_tdbcleanup(). + * Use more appropriate return code for ipsec_tdbwipe(). + * + * Revision 1.49 2001/04/19 18:56:17 rgb + * Fixed tdb table locking comments. + * + * Revision 1.48 2001/02/27 22:24:55 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.47 2000/11/06 04:32:08 rgb + * Ditched spin_lock_irqsave in favour of spin_lock_bh. + * + * Revision 1.46 2000/09/20 16:21:57 rgb + * Cleaned up ident string alloc/free. + * + * Revision 1.45 2000/09/08 19:16:51 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * Removed all references to CONFIG_IPSEC_PFKEYv2. + * + * Revision 1.44 2000/08/30 05:29:04 rgb + * Compiler-define out no longer used tdb_init() in ipsec_xform.c. + * + * Revision 1.43 2000/08/18 21:30:41 rgb + * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. + * + * Revision 1.42 2000/08/01 14:51:51 rgb + * Removed _all_ remaining traces of DES. + * + * Revision 1.41 2000/07/28 14:58:31 rgb + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. + * + * Revision 1.40 2000/06/28 05:50:11 rgb + * Actually set iv_bits. + * + * Revision 1.39 2000/05/10 23:11:09 rgb + * Added netlink debugging output. + * Added a cast to quiet down the ntohl bug. + * + * Revision 1.38 2000/05/10 19:18:42 rgb + * Cast output of ntohl so that the broken prototype doesn't make our + * compile noisy. + * + * Revision 1.37 2000/03/16 14:04:59 rgb + * Hardwired CONFIG_IPSEC_PFKEYv2 on. + * + * Revision 1.36 2000/01/26 10:11:28 rgb + * Fixed spacing in error text causing run-in words. + * + * Revision 1.35 2000/01/21 06:17:16 rgb + * Tidied up compiler directive indentation for readability. + * Added ictx,octx vars for simplification.(kravietz) + * Added macros for HMAC padding magic numbers.(kravietz) + * Fixed missing key length reporting bug. + * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in. + * + * Revision 1.34 1999/12/08 00:04:19 rgb + * Fixed SA direction overwriting bug for netlink users. + * + * Revision 1.33 1999/12/01 22:16:44 rgb + * Minor formatting changes in ESP MD5 initialisation. + * + * Revision 1.32 1999/11/25 09:06:36 rgb + * Fixed error return messages, should be returning negative numbers. + * Implemented SENDERR macro for propagating error codes. + * Added debug message and separate error code for algorithms not compiled + * in. + * + * Revision 1.31 1999/11/23 23:06:26 rgb + * Sort out pfkey and freeswan headers, putting them in a library path. + * + * Revision 1.30 1999/11/18 04:09:20 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.29 1999/11/17 15:53:40 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.28 1999/10/18 20:04:01 rgb + * Clean-out unused cruft. + * + * Revision 1.27 1999/10/03 19:01:03 rgb + * Spinlock support for 2.3.xx and 2.0.xx kernels. + * + * Revision 1.26 1999/10/01 16:22:24 rgb + * Switch from assignment init. to functional init. of spinlocks. + * + * Revision 1.25 1999/10/01 15:44:54 rgb + * Move spinlock header include to 2.1> scope. + * + * Revision 1.24 1999/10/01 00:03:46 rgb + * Added tdb structure locking. + * Minor formatting changes. + * Add function to initialize tdb hash table. + * + * Revision 1.23 1999/05/25 22:42:12 rgb + * Add deltdbchain() debugging. + * + * Revision 1.22 1999/05/25 21:24:31 rgb + * Add debugging statements to deltdbchain(). + * + * Revision 1.21 1999/05/25 03:51:48 rgb + * Refix error return code. + * + * Revision 1.20 1999/05/25 03:34:07 rgb + * Fix error return for flush. + * + * Revision 1.19 1999/05/09 03:25:37 rgb + * Fix bug introduced by 2.2 quick-and-dirty patch. + * + * Revision 1.18 1999/05/05 22:02:32 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.17 1999/04/29 15:20:16 rgb + * Change gettdb parameter to a pointer to reduce stack loading and + * facilitate parameter sanity checking. + * Add sanity checking for null pointer arguments. + * Add debugging instrumentation. + * Add function deltdbchain() which will take care of unlinking, + * zeroing and deleting a chain of tdbs. + * Add a parameter to tdbcleanup to be able to delete a class of SAs. + * tdbwipe now actually zeroes the tdb as well as any of its pointed + * structures. + * + * Revision 1.16 1999/04/16 15:36:29 rgb + * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing. + * + * Revision 1.15 1999/04/11 00:29:01 henry + * GPL boilerplate + * + * Revision 1.14 1999/04/06 04:54:28 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.13 1999/02/19 18:23:01 rgb + * Nix debug off compile warning. + * + * Revision 1.12 1999/02/17 16:52:16 rgb + * Consolidate satoa()s for space and speed efficiency. + * Convert DEBUG_IPSEC to KLIPS_PRINT + * Clean out unused cruft. + * Ditch NET_IPIP dependancy. + * Loop for 3des key setting. + * + * Revision 1.11 1999/01/26 02:09:05 rgb + * Remove ah/esp/IPIP switching on include files. + * Removed CONFIG_IPSEC_ALGO_SWITCH macro. + * Removed dead code. + * Clean up debug code when switched off. + * Remove references to INET_GET_PROTOCOL. + * Added code exclusion macros to reduce code from unused algorithms. + * + * Revision 1.10 1999/01/22 06:28:55 rgb + * Cruft clean-out. + * Put random IV generation in kernel. + * Added algorithm switch code. + * Enhanced debugging. + * 64-bit clean-up. + * + * Revision 1.9 1998/11/30 13:22:55 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.8 1998/11/25 04:59:06 rgb + * Add conditionals for no IPIP tunnel code. + * Delete commented out code. + * + * Revision 1.7 1998/10/31 06:50:41 rgb + * Convert xform ASCII names to no spaces. + * Fixed up comments in #endif directives. + * + * Revision 1.6 1998/10/19 14:44:28 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * + * Revision 1.5 1998/10/09 04:32:19 rgb + * Added 'klips_debug' prefix to all klips printk debug statements. + * + * Revision 1.4 1998/08/12 00:11:31 rgb + * Added new xform functions to the xform table. + * Fixed minor debug output spelling error. + * + * Revision 1.3 1998/07/09 17:45:31 rgb + * Clarify algorithm not available message. + * + * Revision 1.2 1998/06/23 03:00:51 rgb + * Check for presence of IPIP protocol if it is setup one way (we don't + * know what has been set up the other way and can only assume it will be + * symmetrical with the exception of keys). + * + * Revision 1.1 1998/06/18 21:27:51 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.3 1998/06/11 05:54:59 rgb + * Added transform version string pointer to xformsw initialisations. + * + * Revision 1.2 1998/04/21 21:28:57 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.1 1998/04/09 03:06:13 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:02 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.5 1997/06/03 04:24:48 ji + * Added ESP-3DES-MD5-96 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * Added new transforms. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/ipsec_xform.h linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_xform.h --- linux-2.4.29/net/ipsec/ipsec_xform.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/ipsec_xform.h Mon Nov 17 00:32:11 2003 @@ -0,0 +1,328 @@ +/* + * Definitions relevant to IPSEC transformations + * Copyright (C) 1996, 1997 John Ioannidis. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ipsec_xform.h,v 1.4 2003/11/16 23:32:11 ken Exp $ + */ + +#ifndef _IPSEC_XFORM_H_ + +#include + +#define XF_NONE 0 /* No transform set */ +#define XF_IP4 1 /* IPv4 inside IPv4 */ +#define XF_AHMD5 2 /* AH MD5 */ +#define XF_AHSHA 3 /* AH SHA */ +#define XF_ESP3DES 5 /* ESP DES3-CBC */ +#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */ +#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */ +#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */ +#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */ +#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */ +#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */ +#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */ +#define XF_IP6 15 /* IPv6 inside IPv6 */ +#define XF_COMPDEFLATE 16 /* IPCOMP deflate */ + +#define XF_CLR 126 /* Clear SA table */ +#define XF_DEL 127 /* Delete SA */ + +/* IPsec AH transform values + * RFC 2407 + * draft-ietf-ipsec-doi-tc-mib-02.txt + */ + +#define AH_NONE 0 +#define AH_MD5 2 +#define AH_SHA 3 +/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */ +#define AH_SHA2_256 5 +#define AH_SHA2_384 6 +#define AH_SHA2_512 7 +#define AH_RIPEMD 8 +#define AH_MAX 15 + +/* IPsec ESP transform values */ + +#define ESP_NONE 0 +#define ESP_DES 2 +#define ESP_3DES 3 +#define ESP_RC5 4 +#define ESP_IDEA 5 +#define ESP_CAST 6 +#define ESP_BLOWFISH 7 +#define ESP_3IDEA 8 +#define ESP_RC4 10 +#define ESP_NULL 11 +#define ESP_AES 12 + +/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */ +#define ESP_MARS 249 +#define ESP_RC6 250 +#define ESP_SERPENT 252 +#define ESP_TWOFISH 253 + +/* IPCOMP transform values */ + +#define IPCOMP_NONE 0 +#define IPCOMP_OUI 1 +#define IPCOMP_DEFLAT 2 +#define IPCOMP_LZS 3 +#define IPCOMP_V42BIS 4 + +#define XFT_AUTH 0x0001 +#define XFT_CONF 0x0100 + +/* available if CONFIG_IPSEC_DEBUG is defined */ +#define DB_XF_INIT 0x0001 + +#define PROTO2TXT(x) \ + (x) == IPPROTO_AH ? "AH" : \ + (x) == IPPROTO_ESP ? "ESP" : \ + (x) == IPPROTO_IPIP ? "IPIP" : \ + (x) == IPPROTO_COMP ? "COMP" : \ + "UNKNOWN_proto" +static inline const char *enc_name_id (unsigned id) { + static char buf[16]; + snprintf(buf, sizeof(buf), "_ID%d", id); + return buf; +} +static inline const char *auth_name_id (unsigned id) { + static char buf[16]; + snprintf(buf, sizeof(buf), "_ID%d", id); + return buf; +} +#define IPS_XFORM_NAME(x) \ + PROTO2TXT((x)->ips_said.proto), \ + (x)->ips_said.proto == IPPROTO_COMP ? \ + ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \ + "_DEFLATE" : "_UNKNOWN_comp") : \ + (x)->ips_encalg == ESP_NONE ? "" : \ + (x)->ips_encalg == ESP_3DES ? "_3DES" : \ + (x)->ips_encalg == ESP_RC5 ? "_RC5" : \ + (x)->ips_encalg == ESP_IDEA ? "_IDEA" : \ + (x)->ips_encalg == ESP_CAST ? "_CAST" : \ + (x)->ips_encalg == ESP_BLOWFISH ? "_BLOWFISH" : \ + (x)->ips_encalg == ESP_3IDEA ? "_3IDEA" : \ + (x)->ips_encalg == ESP_RC4 ? "_RC4" : \ + (x)->ips_encalg == ESP_NULL ? "_NULL" : \ + (x)->ips_encalg == ESP_AES ? "_AES" : \ + (x)->ips_encalg == ESP_MARS ? "_MARS" : \ + (x)->ips_encalg == ESP_RC6 ? "_RC6" : \ + (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \ + (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \ + (x)->ips_encalg == ESP_DES ? "_DES" : \ + enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \ + (x)->ips_authalg == AH_NONE ? "" : \ + (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \ + (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \ + (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \ + (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \ + (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \ + (x)->ips_authalg == AH_RIPEMD ? "_HMAC_RIPEMD" : \ + auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \ + + +#define _IPSEC_XFORM_H_ +#endif /* _IPSEC_XFORM_H_ */ + +/* + * $Log: ipsec_xform.h,v $ + * Revision 1.4 2003/11/16 23:32:11 ken + * We are now Openswan + * + * Revision 1.3 2003/02/07 13:14:25 ken + * Pullin jjo's ALG 0.8.1rc branch + * + * Revision 1.2.2.1 2003/02/06 22:09:50 jjo + * sync to alg-0.8.1-rc4 + * + * Revision 1.2 2002/09/05 03:27:09 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:17 ken + * 1.98b + * + * Revision 1.35 2001/11/26 09:23:51 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.33.2.1 2001/09/25 02:24:58 mcr + * struct tdb -> struct ipsec_sa. + * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c + * ipsec_xform.c removed. header file still contains useful things. + * + * Revision 1.34 2001/11/06 19:47:17 rgb + * Changed lifetime_packets to uint32 from uint64. + * + * Revision 1.33 2001/09/08 21:13:34 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.32 2001/07/06 07:40:01 rgb + * Reformatted for readability. + * Added inbound policy checking fields for use with IPIP SAs. + * + * Revision 1.31 2001/06/14 19:35:11 rgb + * Update copyright date. + * + * Revision 1.30 2001/05/30 08:14:03 rgb + * Removed vestiges of esp-null transforms. + * + * Revision 1.29 2001/01/30 23:42:47 rgb + * Allow pfkey msgs from pid other than user context required for ACQUIRE + * and subsequent ADD or UDATE. + * + * Revision 1.28 2000/11/06 04:30:40 rgb + * Add Svenning's adaptive content compression. + * + * Revision 1.27 2000/09/19 00:38:25 rgb + * Fixed algorithm name bugs introduced for ipcomp. + * + * Revision 1.26 2000/09/17 21:36:48 rgb + * Added proto2txt macro. + * + * Revision 1.25 2000/09/17 18:56:47 rgb + * Added IPCOMP support. + * + * Revision 1.24 2000/09/12 19:34:12 rgb + * Defined XF_IP6 from Gerhard for ipv6 tunnel support. + * + * Revision 1.23 2000/09/12 03:23:14 rgb + * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb. + * + * Revision 1.22 2000/09/08 19:12:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.21 2000/09/01 18:32:43 rgb + * Added (disabled) sensitivity members to tdb struct. + * + * Revision 1.20 2000/08/30 05:31:01 rgb + * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst. + * Kill remainder of tdb_xform, tdb_xdata, xformsw. + * + * Revision 1.19 2000/08/01 14:51:52 rgb + * Removed _all_ remaining traces of DES. + * + * Revision 1.18 2000/01/21 06:17:45 rgb + * Tidied up spacing. + * + * Revision 1.17 1999/11/17 15:53:40 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.16 1999/10/16 04:23:07 rgb + * Add stats for replaywin_errs, replaywin_max_sequence_difference, + * authentication errors, encryption size errors, encryption padding + * errors, and time since last packet. + * + * Revision 1.15 1999/10/16 00:29:11 rgb + * Added SA lifetime packet counting variables. + * + * Revision 1.14 1999/10/01 00:04:14 rgb + * Added tdb structure locking. + * Add function to initialize tdb hash table. + * + * Revision 1.13 1999/04/29 15:20:57 rgb + * dd return values to init and cleanup functions. + * Eliminate unnessessary usage of tdb_xform member to further switch + * away from the transform switch to the algorithm switch. + * Change gettdb parameter to a pointer to reduce stack loading and + * facilitate parameter sanity checking. + * Add a parameter to tdbcleanup to be able to delete a class of SAs. + * + * Revision 1.12 1999/04/15 15:37:25 rgb + * Forward check changes from POST1_00 branch. + * + * Revision 1.9.2.2 1999/04/13 20:35:57 rgb + * Fix spelling mistake in comment. + * + * Revision 1.9.2.1 1999/03/30 17:13:52 rgb + * Extend struct tdb to support pfkey. + * + * Revision 1.11 1999/04/11 00:29:01 henry + * GPL boilerplate + * + * Revision 1.10 1999/04/06 04:54:28 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.9 1999/01/26 02:09:31 rgb + * Removed CONFIG_IPSEC_ALGO_SWITCH macro. + * Removed dead code. + * + * Revision 1.8 1999/01/22 06:29:35 rgb + * Added algorithm switch code. + * Cruft clean-out. + * + * Revision 1.7 1998/11/10 05:37:35 rgb + * Add support for SA direction flag. + * + * Revision 1.6 1998/10/19 14:44:29 rgb + * Added inclusion of freeswan.h. + * sa_id structure implemented and used: now includes protocol. + * + * Revision 1.5 1998/08/12 00:12:30 rgb + * Added macros for new xforms. Added prototypes for new xforms. + * + * Revision 1.4 1998/07/28 00:04:20 rgb + * Add macro for clearing the SA table. + * + * Revision 1.3 1998/07/14 18:06:46 rgb + * Added #ifdef __KERNEL__ directives to restrict scope of header. + * + * Revision 1.2 1998/06/23 03:02:19 rgb + * Created a prototype for ipsec_tdbcleanup when it was moved from + * ipsec_init.c. + * + * Revision 1.1 1998/06/18 21:27:51 henry + * move sources from klips/src to klips/net/ipsec, to keep stupid + * kernel-build scripts happier in the presence of symlinks + * + * Revision 1.4 1998/06/11 05:55:31 rgb + * Added transform version string pointer to xformsw structure definition. + * Added extern declarations for transform version strings. + * + * Revision 1.3 1998/05/18 22:02:54 rgb + * Modify the *_zeroize function prototypes to include one parameter. + * + * Revision 1.2 1998/04/21 21:29:08 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.1 1998/04/09 03:06:14 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:06 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.5 1997/06/03 04:24:48 ji + * Added ESP-3DES-MD5-96 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * Added new transforms. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/libcrypto/include/cbc_generic.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/include/cbc_generic.h --- linux-2.4.29/net/ipsec/libcrypto/include/cbc_generic.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/include/cbc_generic.h Thu Sep 5 05:26:31 2002 @@ -0,0 +1,110 @@ +#ifndef _CBC_GENERIC_H +#define _CBC_GENERIC_H +/* + * CBC macro helpers + * + * Author: JuanJo Ciarlante + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ + +/* + * Heavily inspired in loop_AES + */ +#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \ +int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \ + int ret=ilen, pos; \ + const u_int32_t *iv_i; \ + if ((ilen) % 16) return 0; \ + if (encrypt) { \ + pos=0; \ + while(pos=0) { \ + dec_func(ctx, (const addr_type) in, (addr_type) out); \ + if (pos==0) \ + iv_i=(const u_int32_t*) (iv); \ + else \ + iv_i=(const u_int32_t*) (in-16); \ + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \ + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \ + *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \ + *((u_int32_t *)(&out[12])) ^= iv_i[3]; \ + in-=16; \ + out-=16; \ + pos-=16; \ + } \ + } \ + return ret; \ +} +#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \ +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \ + int ret=ilen, pos; \ + const u_int32_t *iv_i; \ + if ((ilen) % 8) return 0; \ + if (encrypt) { \ + pos=0; \ + while(pos=0) { \ + dec_func(ctx, (const addr_type)in, (addr_type)out); \ + if (pos==0) \ + iv_i=(const u_int32_t*) (iv); \ + else \ + iv_i=(const u_int32_t*) (in-8); \ + *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \ + *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \ + in-=8; \ + out-=8; \ + pos-=8; \ + } \ + } \ + return ret; \ +} +#define CBC_DECL(name, ctx_type) \ +int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) +/* +Eg.: +CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt); +CBC_DECL(AES_cbc_encrypt, aes_context); +*/ +#endif /* _CBC_GENERIC_H */ diff -urN linux-2.4.29/net/ipsec/libcrypto/include/hmac_generic.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/include/hmac_generic.h --- linux-2.4.29/net/ipsec/libcrypto/include/hmac_generic.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/include/hmac_generic.h Thu Sep 5 05:26:31 2002 @@ -0,0 +1,60 @@ +#ifndef _HMAC_GENERIC_H +#define _HMAC_GENERIC_H +/* + * HMAC macro helpers + * + * Author: JuanJo Ciarlante + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + */ + +#ifndef DIVUP +#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */ +#endif +#ifndef HMAC_IPAD +#define HMAC_IPAD 0x36 +#define HMAC_OPAD 0x5C +#endif +#define HMAC_SET_KEY_IMPL(func_name, hctx_t, blocksize, func_init, func_update) \ +void func_name(hctx_t *hctx, const u_int8_t * key, int keylen) { \ + int i;\ + u_int8_t kb[blocksize]; \ + for (i = 0; i < DIVUP(keylen*8, 8); i++) { \ + kb[i] = key[i] ^ HMAC_IPAD; \ + } \ + for (; i < blocksize; i++) { \ + kb[i] = HMAC_IPAD; \ + } \ + func_init(&hctx->ictx); \ + func_update(&hctx->ictx, kb, blocksize); \ + for (i = 0; i < blocksize; i++) { \ + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); \ + } \ + func_init(&hctx->octx); \ + func_update(&hctx->octx, kb, blocksize); \ +} +#define HMAC_HASH_IMPL(func_name, hctx_t, ctx_t, ahlen, func_update, func_result ) \ +void func_name(hctx_t *hctx, const u_int8_t * dat, int len, u_int8_t * hash, int hashlen) { \ + ctx_t ctx; \ + ctx=hctx->ictx; \ + if (dat) func_update(&ctx, dat, len); \ + if (hash) { \ + u_int8_t hash_buf[ahlen]; \ + func_result(&ctx, hash_buf, ahlen); \ + ctx=hctx->octx; \ + func_update(&ctx, hash_buf, ahlen); \ + func_result(&ctx, hash, hashlen); \ + memset(&ctx, 0, sizeof (ctx)); \ + memset(&hash_buf, 0, sizeof (hash_buf));\ + } \ +} +#endif /* _HMAC_GENERIC_H */ diff -urN linux-2.4.29/net/ipsec/libcrypto/include/md32_common.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/include/md32_common.h --- linux-2.4.29/net/ipsec/libcrypto/include/md32_common.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/include/md32_common.h Thu Sep 5 05:26:31 2002 @@ -0,0 +1,607 @@ +/* crypto/md32_common.h */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This is a generic 32 bit "collector" for message digest algorithms. + * Whenever needed it collects input character stream into chunks of + * 32 bit values and invokes a block function that performs actual hash + * calculations. + * + * Porting guide. + * + * Obligatory macros: + * + * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN + * this macro defines byte order of input stream. + * HASH_CBLOCK + * size of a unit chunk HASH_BLOCK operates on. + * HASH_LONG + * has to be at lest 32 bit wide, if it's wider, then + * HASH_LONG_LOG2 *has to* be defined along + * HASH_CTX + * context structure that at least contains following + * members: + * typedef struct { + * ... + * HASH_LONG Nl,Nh; + * HASH_LONG data[HASH_LBLOCK]; + * int num; + * ... + * } HASH_CTX; + * HASH_UPDATE + * name of "Update" function, implemented here. + * HASH_TRANSFORM + * name of "Transform" function, implemented here. + * HASH_FINAL + * name of "Final" function, implemented here. + * HASH_BLOCK_HOST_ORDER + * name of "block" function treating *aligned* input message + * in host byte order, implemented externally. + * HASH_BLOCK_DATA_ORDER + * name of "block" function treating *unaligned* input message + * in original (data) byte order, implemented externally (it + * actually is optional if data and host are of the same + * "endianess"). + * HASH_MAKE_STRING + * macro convering context variables to an ASCII hash string. + * + * Optional macros: + * + * B_ENDIAN or L_ENDIAN + * defines host byte-order. + * HASH_LONG_LOG2 + * defaults to 2 if not states otherwise. + * HASH_LBLOCK + * assumed to be HASH_CBLOCK/4 if not stated otherwise. + * HASH_BLOCK_DATA_ORDER_ALIGNED + * alternative "block" function capable of treating + * aligned input message in original (data) order, + * implemented externally. + * + * MD5 example: + * + * #define DATA_ORDER_IS_LITTLE_ENDIAN + * + * #define HASH_LONG MD5_LONG + * #define HASH_LONG_LOG2 MD5_LONG_LOG2 + * #define HASH_CTX MD5_CTX + * #define HASH_CBLOCK MD5_CBLOCK + * #define HASH_LBLOCK MD5_LBLOCK + * #define HASH_UPDATE MD5_Update + * #define HASH_TRANSFORM MD5_Transform + * #define HASH_FINAL MD5_Final + * #define HASH_BLOCK_HOST_ORDER md5_block_host_order + * #define HASH_BLOCK_DATA_ORDER md5_block_data_order + * + * + */ + +#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) +#error "DATA_ORDER must be defined!" +#endif + +#ifndef HASH_CBLOCK +#error "HASH_CBLOCK must be defined!" +#endif +#ifndef HASH_LONG +#error "HASH_LONG must be defined!" +#endif +#ifndef HASH_CTX +#error "HASH_CTX must be defined!" +#endif + +#ifndef HASH_UPDATE +#error "HASH_UPDATE must be defined!" +#endif +#ifndef HASH_TRANSFORM +#error "HASH_TRANSFORM must be defined!" +#endif +#ifndef HASH_FINAL +#error "HASH_FINAL must be defined!" +#endif + +#ifndef HASH_BLOCK_HOST_ORDER +#error "HASH_BLOCK_HOST_ORDER must be defined!" +#endif + +#if 0 +/* + * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED + * isn't defined. + */ +#ifndef HASH_BLOCK_DATA_ORDER +#error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif +#endif + +#ifndef HASH_LBLOCK +#define HASH_LBLOCK (HASH_CBLOCK/4) +#endif + +#ifndef HASH_LONG_LOG2 +#define HASH_LONG_LOG2 2 +#endif + +/* + * Engage compiler specific rotate intrinsic function if available. + */ +#undef ROTATE +#ifndef PEDANTIC +# if defined(_MSC_VER) +# define ROTATE(a,n) _lrotl(a,n) +# elif defined(__MWERKS__) +# if defined(__POWERPC__) +# define ROTATE(a,n) __rlwinm(a,n,0,31) +# elif defined(__MC68K__) + /* Motorola specific tweak. */ +# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) ) +# else +# define ROTATE(a,n) __rol(a,n) +# endif +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM) + /* + * Some GNU C inline assembler templates. Note that these are + * rotates by *constant* number of bits! But that's exactly + * what we need here... + * + * + */ +# if defined(__i386) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "roll %1,%0" \ + : "=r"(ret) \ + : "I"(n), "0"(a) \ + : "cc"); \ + ret; \ + }) +# elif defined(__powerpc) || defined(__ppc) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "rlwinm %0,%1,%2,0,31" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +# endif +# endif + +/* + * Engage compiler specific "fetch in reverse byte order" + * intrinsic function if available. + */ +# if defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM) + /* some GNU C inline assembler templates by */ +# if defined(__i386) && !defined(I386_ONLY) +# define BE_FETCH32(a) ({ register unsigned int l=(a);\ + asm ( \ + "bswapl %0" \ + : "=r"(l) : "0"(l)); \ + l; \ + }) +# elif defined(__powerpc) +# define LE_FETCH32(a) ({ register unsigned int l; \ + asm ( \ + "lwbrx %0,0,%1" \ + : "=r"(l) \ + : "r"(a)); \ + l; \ + }) + +# elif defined(__sparc) && defined(ULTRASPARC) +# define LE_FETCH32(a) ({ register unsigned int l; \ + asm ( \ + "lda [%1]#ASI_PRIMARY_LITTLE,%0"\ + : "=r"(l) \ + : "r"(a)); \ + l; \ + }) +# endif +# endif +#endif /* PEDANTIC */ + +#if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */ +/* A nice byte order reversal from Wei Dai */ +#ifdef ROTATE +/* 5 instructions with rotate instruction, else 9 */ +#define REVERSE_FETCH32(a,l) ( \ + l=*(const HASH_LONG *)(a), \ + ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \ + ) +#else +/* 6 instructions with rotate instruction, else 8 */ +#define REVERSE_FETCH32(a,l) ( \ + l=*(const HASH_LONG *)(a), \ + l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \ + ROTATE(l,16) \ + ) +/* + * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|... + * It's rewritten as above for two reasons: + * - RISCs aren't good at long constants and have to explicitely + * compose 'em with several (well, usually 2) instructions in a + * register before performing the actual operation and (as you + * already realized:-) having same constant should inspire the + * compiler to permanently allocate the only register for it; + * - most modern CPUs have two ALUs, but usually only one has + * circuitry for shifts:-( this minor tweak inspires compiler + * to schedule shift instructions in a better way... + * + * + */ +#endif +#endif + +#ifndef ROTATE +#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#endif + +/* + * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED + * and HASH_BLOCK_HOST_ORDER ought to be the same if input data + * and host are of the same "endianess". It's possible to mask + * this with blank #define HASH_BLOCK_DATA_ORDER though... + * + * + */ +#if defined(B_ENDIAN) +# if defined(DATA_ORDER_IS_BIG_ENDIAN) +# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 +# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER +# endif +# elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# ifndef HOST_FETCH32 +# ifdef LE_FETCH32 +# define HOST_FETCH32(p,l) LE_FETCH32(p) +# elif defined(REVERSE_FETCH32) +# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l) +# endif +# endif +# endif +#elif defined(L_ENDIAN) +# if defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2 +# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER +# endif +# elif defined(DATA_ORDER_IS_BIG_ENDIAN) +# ifndef HOST_FETCH32 +# ifdef BE_FETCH32 +# define HOST_FETCH32(p,l) BE_FETCH32(p) +# elif defined(REVERSE_FETCH32) +# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l) +# endif +# endif +# endif +#endif + +#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) +#ifndef HASH_BLOCK_DATA_ORDER +#error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif +#endif + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) ), \ + l) +#define HOST_p_c2l(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + case 3: l|=((unsigned long)(*((c)++))); \ + } } +#define HOST_p_c2l_p(c,l,sc,len) { \ + switch (sc) { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + } } +/* NOTE the pointer is not incremented at the end of this */ +#define HOST_c2l_p(c,l,n) { \ + l=0; (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<< 8; \ + case 2: l|=((unsigned long)(*(--(c))))<<16; \ + case 1: l|=((unsigned long)(*(--(c))))<<24; \ + } } +#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff), \ + l) + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24), \ + l) +#define HOST_p_c2l(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++))); \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + case 3: l|=((unsigned long)(*((c)++)))<<24; \ + } } +#define HOST_p_c2l_p(c,l,sc,len) { \ + switch (sc) { \ + case 0: l =((unsigned long)(*((c)++))); \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + } } +/* NOTE the pointer is not incremented at the end of this */ +#define HOST_c2l_p(c,l,n) { \ + l=0; (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<<16; \ + case 2: l|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l|=((unsigned long)(*(--(c)))); \ + } } +#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + l) + +#endif + +/* + * Time for some action:-) + */ + +void HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len) + { + const unsigned char *data=data_; + register HASH_LONG * p; + register unsigned long l; + int sw,sc,ew,ec; + + if (len==0) return; + + l=(c->Nl+(len<<3))&0xffffffffL; + /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to + * Wei Dai for pointing it out. */ + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh+=(len>>29); + c->Nl=l; + + if (c->num != 0) + { + p=c->data; + sw=c->num>>2; + sc=c->num&0x03; + + if ((c->num+len) >= HASH_CBLOCK) + { + l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; + for (; swnum); + c->num=0; + /* drop through and do the rest */ + } + else + { + c->num+=len; + if ((sc+len) < 4) /* ugly, add char's to a word */ + { + l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l; + } + else + { + ew=(c->num>>2); + ec=(c->num&0x03); + l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l; + for (; sw < ew; sw++) + { + HOST_c2l(data,l); p[sw]=l; + } + if (ec) + { + HOST_c2l_p(data,l,ec); p[sw]=l; + } + } + return; + } + } + + sw=len/HASH_CBLOCK; + if (sw > 0) + { +#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) + /* + * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined + * only if sizeof(HASH_LONG)==4. + */ + if ((((unsigned long)data)%4) == 0) + { + /* data is properly aligned so that we can cast it: */ + HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw); + sw*=HASH_CBLOCK; + data+=sw; + len-=sw; + } + else +#if !defined(HASH_BLOCK_DATA_ORDER) + while (sw--) + { + memcpy (p=c->data,data,HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1); + data+=HASH_CBLOCK; + len-=HASH_CBLOCK; + } +#endif +#endif +#if defined(HASH_BLOCK_DATA_ORDER) + { + HASH_BLOCK_DATA_ORDER(c,data,sw); + sw*=HASH_CBLOCK; + data+=sw; + len-=sw; + } +#endif + } + + if (len!=0) + { + p = c->data; + c->num = len; + ew=len>>2; /* words to copy */ + ec=len&0x03; + for (; ew; ew--,p++) + { + HOST_c2l(data,l); *p=l; + } + HOST_c2l_p(data,l,ec); + *p=l; + } + } + + +void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data) + { +#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED) + if ((((unsigned long)data)%4) == 0) + /* data is properly aligned so that we can cast it: */ + HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1); + else +#if !defined(HASH_BLOCK_DATA_ORDER) + { + memcpy (c->data,data,HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1); + } +#endif +#endif +#if defined(HASH_BLOCK_DATA_ORDER) + HASH_BLOCK_DATA_ORDER (c,data,1); +#endif + } + + +void HASH_FINAL (unsigned char *md, HASH_CTX *c) + { + register HASH_LONG *p; + register unsigned long l; + register int i,j; + static const unsigned char end[4]={0x80,0x00,0x00,0x00}; + const unsigned char *cp=end; + + /* c->num should definitly have room for at least one more byte. */ + p=c->data; + i=c->num>>2; + j=c->num&0x03; + +#if 0 + /* purify often complains about the following line as an + * Uninitialized Memory Read. While this can be true, the + * following p_c2l macro will reset l when that case is true. + * This is because j&0x03 contains the number of 'valid' bytes + * already in p[i]. If and only if j&0x03 == 0, the UMR will + * occur but this is also the only time p_c2l will do + * l= *(cp++) instead of l|= *(cp++) + * Many thanks to Alex Tang for pickup this + * 'potential bug' */ +#ifdef PURIFY + if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */ +#endif + l=p[i]; +#else + l = (j==0) ? 0 : p[i]; +#endif + HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */ + + if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */ + { + if (iNh; + p[HASH_LBLOCK-1]=c->Nl; +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + p[HASH_LBLOCK-2]=c->Nl; + p[HASH_LBLOCK-1]=c->Nh; +#endif + HASH_BLOCK_HOST_ORDER (c,p,1); + +#ifndef HASH_MAKE_STRING +#error "HASH_MAKE_STRING must be defined!" +#else + HASH_MAKE_STRING(c,md); +#endif + + c->num=0; + /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack + * but I'm not worried :-) + memset((void *)c,0,sizeof(HASH_CTX)); + */ + } diff -urN linux-2.4.29/net/ipsec/libcrypto/libaes/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/Makefile --- linux-2.4.29/net/ipsec/libcrypto/libaes/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/Makefile Tue Jul 8 16:21:05 2003 @@ -0,0 +1,40 @@ +CFLAGS=-O3 -fomit-frame-pointer -D__KERNEL__ -Wall -Wcast-qual $(EXTRA_CFLAGS) +INC=-I../include + +AES_CORE_OBJ:=aes.o + +ASM-$(ARCH_ASM):=1 +ASM_X86:=$(ASM-i586)$(ASM-i686) +ifneq ($(strip $(ASM_X86)),) +AES_CORE_OBJ:= asm/aes-i586.o +endif + +LIBOBJ := aes_xcbc_mac.o aes_cbc.o $(AES_CORE_OBJ) +LDLIBS := -laes +LDFLAGS := -L. + +BLIB := libaes.a + +L_TARGET := $(BLIB) + +.c.o: + $(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c $< -o $@ + +.S.o: + $(CC) $(AFLAGS) -c $< -o $@ + +$(BLIB): $(LIBOBJ) + /bin/rm -f $(BLIB) + ar cr $(BLIB) $(LIBOBJ) + -if test -s /bin/ranlib; then /bin/ranlib $(BLIB); \ + else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(BLIB); \ + else exit 0; fi; fi + +testx: test_main_mac.o $(BLIB) + $(CC) -o $@ $^ + +test: test_main.o $(BLIB) + $(CC) -o $@ $^ + +clean: + rm -f *.[oa] asm/*.o core $(TARGET) test testx diff -urN linux-2.4.29/net/ipsec/libcrypto/libaes/aes.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes.c --- linux-2.4.29/net/ipsec/libcrypto/libaes/aes.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes.c Fri Feb 7 14:14:26 2003 @@ -0,0 +1,1415 @@ +// I retain copyright in this code but I encourage its free use provided +// that I don't carry any responsibility for the results. I am especially +// happy to see it used in free and open source software. If you do use +// it I would appreciate an acknowledgement of its origin in the code or +// the product that results and I would also appreciate knowing a little +// about the use to which it is being put. I am grateful to Frank Yellin +// for some ideas that are used in this implementation. +// +// Dr B. R. Gladman 6th April 2001. +// +// This is an implementation of the AES encryption algorithm (Rijndael) +// designed by Joan Daemen and Vincent Rijmen. This version is designed +// to provide both fixed and dynamic block and key lengths and can also +// run with either big or little endian internal byte order (see aes.h). +// It inputs block and key lengths in bytes with the legal values being +// 16, 24 and 32. + +/* + * Modified by Jari Ruusu, May 1 2001 + * - Fixed some compile warnings, code was ok but gcc warned anyway. + * - Changed basic types: byte -> unsigned char, word -> u_int32_t + * - Major name space cleanup: Names visible to outside now begin + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c + * - Removed C++ and DLL support as part of name space cleanup. + * - Eliminated unnecessary recomputation of tables. (actual bug fix) + * - Merged precomputed constant tables to aes.c file. + * - Removed data alignment restrictions for portability reasons. + * - Made block and key lengths accept bit count (128/192/256) + * as well byte count (16/24/32). + * - Removed all error checks. This change also eliminated the need + * to preinitialize the context struct to zero. + * - Removed some totally unused constants. + */ + +#include "aes.h" + +// CONFIGURATION OPTIONS (see also aes.h) +// +// 1. Define UNROLL for full loop unrolling in encryption and decryption. +// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption. +// 3. Define FIXED_TABLES for compiled rather than dynamic tables. +// 4. Define FF_TABLES to use tables for field multiplies and inverses. +// Do not enable this without understanding stack space requirements. +// 5. Define ARRAYS to use arrays to hold the local state block. If this +// is not defined, individually declared 32-bit words are used. +// 6. Define FAST_VARIABLE if a high speed variable block implementation +// is needed (essentially three separate fixed block size code sequences) +// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven +// version using 1 table (2 kbytes of table space) or 4 tables (8 +// kbytes of table space) for higher speed. +// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed +// increase by using tables for the last rounds but with more table +// space (2 or 8 kbytes extra). +// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but +// slower version is provided. +// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE +// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra). + +#define UNROLL +//#define PARTIAL_UNROLL + +#define FIXED_TABLES +//#define FF_TABLES +//#define ARRAYS +#define FAST_VARIABLE + +//#define ONE_TABLE +#define FOUR_TABLES + +//#define ONE_LR_TABLE +#define FOUR_LR_TABLES + +//#define ONE_IM_TABLE +#define FOUR_IM_TABLES + +#if defined(UNROLL) && defined (PARTIAL_UNROLL) +#error both UNROLL and PARTIAL_UNROLL are defined +#endif + +#if defined(ONE_TABLE) && defined (FOUR_TABLES) +#error both ONE_TABLE and FOUR_TABLES are defined +#endif + +#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES) +#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined +#endif + +#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES) +#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined +#endif + +#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32 +#error an illegal block size has been specified +#endif + +// upr(x,n): rotates bytes within words by n positions, moving bytes +// to higher index positions with wrap around into low positions +// ups(x,n): moves bytes by n positions to higher index positions in +// words but without wrap around +// bval(x,n): extracts a byte from a word + +#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n)))) +#define ups(x,n) ((x) << 8 * (n)) +#define bval(x,n) ((unsigned char)((x) >> 8 * (n))) +#define bytes2word(b0, b1, b2, b3) \ + ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0)) + + +/* little endian processor without data alignment restrictions: AES_LE_OK */ +/* original code: i386 */ +#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386) +#define AES_LE_OK 1 +/* added (tested): alpha --jjo */ +#elif defined(__alpha__)|| defined (__alpha) +#define AES_LE_OK 1 +/* added (tested): ia64 --jjo */ +#elif defined(__ia64__)|| defined (__ia64) +#define AES_LE_OK 1 +#endif + +#ifdef AES_LE_OK +/* little endian processor without data alignment restrictions */ +#define word_in(x) *(u_int32_t*)(x) +#define const_word_in(x) *(const u_int32_t*)(x) +#define word_out(x,v) *(u_int32_t*)(x) = (v) +#define const_word_out(x,v) *(const u_int32_t*)(x) = (v) +#else +/* slower but generic big endian or with data alignment restrictions */ +/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */ +#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)) +#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)) +#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) +#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) +#endif + +// Disable at least some poor combinations of options + +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES) +#define FIXED_TABLES +#undef UNROLL +#undef ONE_LR_TABLE +#undef FOUR_LR_TABLES +#undef ONE_IM_TABLE +#undef FOUR_IM_TABLES +#elif !defined(FOUR_TABLES) +#ifdef FOUR_LR_TABLES +#undef FOUR_LR_TABLES +#define ONE_LR_TABLE +#endif +#ifdef FOUR_IM_TABLES +#undef FOUR_IM_TABLES +#define ONE_IM_TABLE +#endif +#elif !defined(AES_BLOCK_SIZE) +#if defined(UNROLL) +#define PARTIAL_UNROLL +#undef UNROLL +#endif +#endif + +// the finite field modular polynomial and elements + +#define ff_poly 0x011b +#define ff_hi 0x80 + +// multiply four bytes in GF(2^8) by 'x' {02} in parallel + +#define m1 0x80808080 +#define m2 0x7f7f7f7f +#define m3 0x0000001b +#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3)) + +// The following defines provide alternative definitions of FFmulX that might +// give improved performance if a fast 32-bit multiply is not available. Note +// that a temporary variable u needs to be defined where FFmulX is used. + +// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6)) +// #define m4 0x1b1b1b1b +// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4) + +// perform column mix operation on four bytes in parallel + +#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1)) + +#if defined(FIXED_TABLES) + +// the S-Box table + +static const unsigned char s_box[256] = +{ + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +}; + +// the inverse S-Box table + +static const unsigned char inv_s_box[256] = +{ + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +}; + +#define w0(p) 0x000000##p + +// Number of elements required in this table for different +// block and key lengths is: +// +// Nk = 4 6 8 +// ---------- +// Nb = 4 | 10 8 7 +// 6 | 19 12 11 +// 8 | 29 19 14 +// +// this table can be a table of bytes if the key schedule +// code is adjusted accordingly + +static const u_int32_t rcon_tab[29] = +{ + w0(01), w0(02), w0(04), w0(08), + w0(10), w0(20), w0(40), w0(80), + w0(1b), w0(36), w0(6c), w0(d8), + w0(ab), w0(4d), w0(9a), w0(2f), + w0(5e), w0(bc), w0(63), w0(c6), + w0(97), w0(35), w0(6a), w0(d4), + w0(b3), w0(7d), w0(fa), w0(ef), + w0(c5) +}; + +#undef w0 + +#define r0(p,q,r,s) 0x##p##q##r##s +#define r1(p,q,r,s) 0x##q##r##s##p +#define r2(p,q,r,s) 0x##r##s##p##q +#define r3(p,q,r,s) 0x##s##p##q##r +#define w0(p) 0x000000##p +#define w1(p) 0x0000##p##00 +#define w2(p) 0x00##p##0000 +#define w3(p) 0x##p##000000 + +#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES)) + +// data for forward tables (other than last round) + +#define f_table \ + r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\ + r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\ + r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\ + r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\ + r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\ + r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\ + r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\ + r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\ + r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\ + r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\ + r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\ + r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\ + r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\ + r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\ + r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\ + r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\ + r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\ + r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\ + r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\ + r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\ + r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\ + r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\ + r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\ + r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\ + r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\ + r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\ + r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\ + r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\ + r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\ + r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\ + r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\ + r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\ + r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\ + r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\ + r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\ + r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\ + r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\ + r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\ + r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\ + r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\ + r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\ + r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\ + r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\ + r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\ + r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\ + r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\ + r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\ + r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\ + r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\ + r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\ + r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\ + r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\ + r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\ + r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\ + r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\ + r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\ + r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\ + r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\ + r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\ + r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\ + r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\ + r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\ + r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\ + r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c) + +// data for inverse tables (other than last round) + +#define i_table \ + r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\ + r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\ + r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\ + r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\ + r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\ + r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\ + r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\ + r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\ + r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\ + r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\ + r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\ + r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\ + r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\ + r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\ + r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\ + r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\ + r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\ + r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\ + r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\ + r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\ + r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\ + r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\ + r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\ + r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\ + r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\ + r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\ + r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\ + r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\ + r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\ + r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\ + r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\ + r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\ + r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\ + r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\ + r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\ + r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\ + r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\ + r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\ + r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\ + r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\ + r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\ + r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\ + r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\ + r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\ + r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\ + r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\ + r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\ + r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\ + r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\ + r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\ + r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\ + r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\ + r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\ + r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\ + r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\ + r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\ + r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\ + r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\ + r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\ + r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\ + r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\ + r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\ + r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\ + r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0) + +// generate the required tables in the desired endian format + +#undef r +#define r r0 + +#if defined(ONE_TABLE) +static const u_int32_t ft_tab[256] = + { f_table }; +#elif defined(FOUR_TABLES) +static const u_int32_t ft_tab[4][256] = +{ { f_table }, +#undef r +#define r r1 + { f_table }, +#undef r +#define r r2 + { f_table }, +#undef r +#define r r3 + { f_table } +}; +#endif + +#undef r +#define r r0 +#if defined(ONE_TABLE) +static const u_int32_t it_tab[256] = + { i_table }; +#elif defined(FOUR_TABLES) +static const u_int32_t it_tab[4][256] = +{ { i_table }, +#undef r +#define r r1 + { i_table }, +#undef r +#define r r2 + { i_table }, +#undef r +#define r r3 + { i_table } +}; +#endif + +#endif + +#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES)) + +// data for inverse tables (last round) + +#define li_table \ + w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\ + w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\ + w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\ + w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\ + w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\ + w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\ + w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\ + w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\ + w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\ + w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\ + w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\ + w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\ + w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\ + w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\ + w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\ + w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\ + w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\ + w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\ + w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\ + w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\ + w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\ + w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\ + w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\ + w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\ + w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\ + w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\ + w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\ + w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\ + w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\ + w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\ + w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\ + w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d), + +// generate the required tables in the desired endian format + +#undef r +#define r(p,q,r,s) w0(q) +#if defined(ONE_LR_TABLE) +static const u_int32_t fl_tab[256] = + { f_table }; +#elif defined(FOUR_LR_TABLES) +static const u_int32_t fl_tab[4][256] = +{ { f_table }, +#undef r +#define r(p,q,r,s) w1(q) + { f_table }, +#undef r +#define r(p,q,r,s) w2(q) + { f_table }, +#undef r +#define r(p,q,r,s) w3(q) + { f_table } +}; +#endif + +#undef w +#define w w0 +#if defined(ONE_LR_TABLE) +static const u_int32_t il_tab[256] = + { li_table }; +#elif defined(FOUR_LR_TABLES) +static const u_int32_t il_tab[4][256] = +{ { li_table }, +#undef w +#define w w1 + { li_table }, +#undef w +#define w w2 + { li_table }, +#undef w +#define w w3 + { li_table } +}; +#endif + +#endif + +#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES)) + +#define m_table \ + r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\ + r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\ + r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\ + r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\ + r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\ + r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\ + r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\ + r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\ + r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\ + r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\ + r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\ + r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\ + r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\ + r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\ + r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\ + r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\ + r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\ + r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\ + r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\ + r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\ + r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\ + r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\ + r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\ + r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\ + r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\ + r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\ + r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\ + r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\ + r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\ + r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\ + r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\ + r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\ + r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\ + r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\ + r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\ + r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\ + r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\ + r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\ + r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\ + r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\ + r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\ + r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\ + r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\ + r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\ + r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\ + r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\ + r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\ + r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\ + r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\ + r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\ + r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\ + r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\ + r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\ + r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\ + r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\ + r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\ + r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\ + r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\ + r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\ + r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\ + r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\ + r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\ + r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\ + r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d) + +#undef r +#define r r0 + +#if defined(ONE_IM_TABLE) +static const u_int32_t im_tab[256] = + { m_table }; +#elif defined(FOUR_IM_TABLES) +static const u_int32_t im_tab[4][256] = +{ { m_table }, +#undef r +#define r r1 + { m_table }, +#undef r +#define r r2 + { m_table }, +#undef r +#define r r3 + { m_table } +}; +#endif + +#endif + +#else + +static int tab_gen = 0; + +static unsigned char s_box[256]; // the S box +static unsigned char inv_s_box[256]; // the inverse S box +static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants + +#if defined(ONE_TABLE) +static u_int32_t ft_tab[256]; +static u_int32_t it_tab[256]; +#elif defined(FOUR_TABLES) +static u_int32_t ft_tab[4][256]; +static u_int32_t it_tab[4][256]; +#endif + +#if defined(ONE_LR_TABLE) +static u_int32_t fl_tab[256]; +static u_int32_t il_tab[256]; +#elif defined(FOUR_LR_TABLES) +static u_int32_t fl_tab[4][256]; +static u_int32_t il_tab[4][256]; +#endif + +#if defined(ONE_IM_TABLE) +static u_int32_t im_tab[256]; +#elif defined(FOUR_IM_TABLES) +static u_int32_t im_tab[4][256]; +#endif + +// Generate the tables for the dynamic table option + +#if !defined(FF_TABLES) + +// It will generally be sensible to use tables to compute finite +// field multiplies and inverses but where memory is scarse this +// code might sometimes be better. + +// return 2 ^ (n - 1) where n is the bit number of the highest bit +// set in x with x in the range 1 < x < 0x00000200. This form is +// used so that locals within FFinv can be bytes rather than words + +static unsigned char hibit(const u_int32_t x) +{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2)); + + r |= (r >> 2); + r |= (r >> 4); + return (r + 1) >> 1; +} + +// return the inverse of the finite field element x + +static unsigned char FFinv(const unsigned char x) +{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; + + if(x < 2) return x; + + for(;;) + { + if(!n1) return v1; + + while(n2 >= n1) + { + n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2); + } + + if(!n2) return v2; + + while(n1 >= n2) + { + n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1); + } + } +} + +// define the finite field multiplies required for Rijndael + +#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0)) +#define FFmul03(x) ((x) ^ FFmul02(x)) +#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x)))) +#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x)))) +#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x)))) +#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x))) + +#else + +#define FFinv(x) ((x) ? pow[255 - log[x]]: 0) + +#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0) +#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0) +#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0) +#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0) +#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0) +#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0) + +#endif + +// The forward and inverse affine transformations used in the S-box + +#define fwd_affine(x) \ + (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8))) + +#define inv_affine(x) \ + (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8))) + +static void gen_tabs(void) +{ u_int32_t i, w; + +#if defined(FF_TABLES) + + unsigned char pow[512], log[256]; + + // log and power tables for GF(2^8) finite field with + // 0x011b as modular polynomial - the simplest primitive + // root is 0x03, used here to generate the tables + + i = 0; w = 1; + do + { + pow[i] = (unsigned char)w; + pow[i + 255] = (unsigned char)w; + log[w] = (unsigned char)i++; + w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0); + } + while (w != 1); + +#endif + + for(i = 0, w = 1; i < AES_RC_LENGTH; ++i) + { + rcon_tab[i] = bytes2word(w, 0, 0, 0); + w = (w << 1) ^ (w & ff_hi ? ff_poly : 0); + } + + for(i = 0; i < 256; ++i) + { unsigned char b; + + s_box[i] = b = fwd_affine(FFinv((unsigned char)i)); + + w = bytes2word(b, 0, 0, 0); +#if defined(ONE_LR_TABLE) + fl_tab[i] = w; +#elif defined(FOUR_LR_TABLES) + fl_tab[0][i] = w; + fl_tab[1][i] = upr(w,1); + fl_tab[2][i] = upr(w,2); + fl_tab[3][i] = upr(w,3); +#endif + w = bytes2word(FFmul02(b), b, b, FFmul03(b)); +#if defined(ONE_TABLE) + ft_tab[i] = w; +#elif defined(FOUR_TABLES) + ft_tab[0][i] = w; + ft_tab[1][i] = upr(w,1); + ft_tab[2][i] = upr(w,2); + ft_tab[3][i] = upr(w,3); +#endif + inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i)); + + w = bytes2word(b, 0, 0, 0); +#if defined(ONE_LR_TABLE) + il_tab[i] = w; +#elif defined(FOUR_LR_TABLES) + il_tab[0][i] = w; + il_tab[1][i] = upr(w,1); + il_tab[2][i] = upr(w,2); + il_tab[3][i] = upr(w,3); +#endif + w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b)); +#if defined(ONE_TABLE) + it_tab[i] = w; +#elif defined(FOUR_TABLES) + it_tab[0][i] = w; + it_tab[1][i] = upr(w,1); + it_tab[2][i] = upr(w,2); + it_tab[3][i] = upr(w,3); +#endif +#if defined(ONE_IM_TABLE) + im_tab[b] = w; +#elif defined(FOUR_IM_TABLES) + im_tab[0][b] = w; + im_tab[1][b] = upr(w,1); + im_tab[2][b] = upr(w,2); + im_tab[3][b] = upr(w,3); +#endif + + } +} + +#endif + +#define no_table(x,box,vf,rf,c) bytes2word( \ + box[bval(vf(x,0,c),rf(0,c))], \ + box[bval(vf(x,1,c),rf(1,c))], \ + box[bval(vf(x,2,c),rf(2,c))], \ + box[bval(vf(x,3,c),rf(3,c))]) + +#define one_table(x,op,tab,vf,rf,c) \ + ( tab[bval(vf(x,0,c),rf(0,c))] \ + ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ + ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ + ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) + +#define four_tables(x,tab,vf,rf,c) \ + ( tab[0][bval(vf(x,0,c),rf(0,c))] \ + ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ + ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ + ^ tab[3][bval(vf(x,3,c),rf(3,c))]) + +#define vf1(x,r,c) (x) +#define rf1(r,c) (r) +#define rf2(r,c) ((r-c)&3) + +#if defined(FOUR_LR_TABLES) +#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c) +#elif defined(ONE_LR_TABLE) +#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c) +#else +#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c) +#endif + +#if defined(FOUR_IM_TABLES) +#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0) +#elif defined(ONE_IM_TABLE) +#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0) +#else +#define inv_mcol(x) \ + (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \ + f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1)) +#endif + +// Subroutine to set the block size (if variable) in bytes, legal +// values being 16, 24 and 32. + +#if defined(AES_BLOCK_SIZE) +#define nc (AES_BLOCK_SIZE / 4) +#else +#define nc (cx->aes_Ncol) + +void aes_set_blk(aes_context *cx, int n_bytes) +{ +#if !defined(FIXED_TABLES) + if(!tab_gen) { gen_tabs(); tab_gen = 1; } +#endif + + switch(n_bytes) { + case 32: /* bytes */ + case 256: /* bits */ + nc = 8; + break; + case 24: /* bytes */ + case 192: /* bits */ + nc = 6; + break; + case 16: /* bytes */ + case 128: /* bits */ + default: + nc = 4; + break; + } +} + +#endif + +// Initialise the key schedule from the user supplied key. The key +// length is now specified in bytes - 16, 24 or 32 as appropriate. +// This corresponds to bit lengths of 128, 192 and 256 bits, and +// to Nk values of 4, 6 and 8 respectively. + +#define mx(t,f) (*t++ = inv_mcol(*f),f++) +#define cp(t,f) *t++ = *f++ + +#if AES_BLOCK_SIZE == 16 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s) +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s) +#elif AES_BLOCK_SIZE == 24 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \ + cp(d,s); cp(d,s) +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \ + mx(d,s); mx(d,s) +#elif AES_BLOCK_SIZE == 32 +#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \ + cp(d,s); cp(d,s); cp(d,s); cp(d,s) +#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \ + mx(d,s); mx(d,s); mx(d,s); mx(d,s) +#else + +#define cpy(d,s) \ +switch(nc) \ +{ case 8: cp(d,s); cp(d,s); \ + case 6: cp(d,s); cp(d,s); \ + case 4: cp(d,s); cp(d,s); \ + cp(d,s); cp(d,s); \ +} + +#define mix(d,s) \ +switch(nc) \ +{ case 8: mx(d,s); mx(d,s); \ + case 6: mx(d,s); mx(d,s); \ + case 4: mx(d,s); mx(d,s); \ + mx(d,s); mx(d,s); \ +} + +#endif + +void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f) +{ u_int32_t *kf, *kt, rci; + +#if !defined(FIXED_TABLES) + if(!tab_gen) { gen_tabs(); tab_gen = 1; } +#endif + + switch(n_bytes) { + case 32: /* bytes */ + case 256: /* bits */ + cx->aes_Nkey = 8; + break; + case 24: /* bytes */ + case 192: /* bits */ + cx->aes_Nkey = 6; + break; + case 16: /* bytes */ + case 128: /* bits */ + default: + cx->aes_Nkey = 4; + break; + } + + cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6; + + cx->aes_e_key[0] = const_word_in(in_key ); + cx->aes_e_key[1] = const_word_in(in_key + 4); + cx->aes_e_key[2] = const_word_in(in_key + 8); + cx->aes_e_key[3] = const_word_in(in_key + 12); + + kf = cx->aes_e_key; + kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey; + rci = 0; + + switch(cx->aes_Nkey) + { + case 4: do + { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++]; + kf[5] = kf[1] ^ kf[4]; + kf[6] = kf[2] ^ kf[5]; + kf[7] = kf[3] ^ kf[6]; + kf += 4; + } + while(kf < kt); + break; + + case 6: cx->aes_e_key[4] = const_word_in(in_key + 16); + cx->aes_e_key[5] = const_word_in(in_key + 20); + do + { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++]; + kf[ 7] = kf[1] ^ kf[ 6]; + kf[ 8] = kf[2] ^ kf[ 7]; + kf[ 9] = kf[3] ^ kf[ 8]; + kf[10] = kf[4] ^ kf[ 9]; + kf[11] = kf[5] ^ kf[10]; + kf += 6; + } + while(kf < kt); + break; + + case 8: cx->aes_e_key[4] = const_word_in(in_key + 16); + cx->aes_e_key[5] = const_word_in(in_key + 20); + cx->aes_e_key[6] = const_word_in(in_key + 24); + cx->aes_e_key[7] = const_word_in(in_key + 28); + do + { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++]; + kf[ 9] = kf[1] ^ kf[ 8]; + kf[10] = kf[2] ^ kf[ 9]; + kf[11] = kf[3] ^ kf[10]; + kf[12] = kf[4] ^ ls_box(kf[11],0); + kf[13] = kf[5] ^ kf[12]; + kf[14] = kf[6] ^ kf[13]; + kf[15] = kf[7] ^ kf[14]; + kf += 8; + } + while (kf < kt); + break; + } + + if(!f) + { u_int32_t i; + + kt = cx->aes_d_key + nc * cx->aes_Nrnd; + kf = cx->aes_e_key; + + cpy(kt, kf); kt -= 2 * nc; + + for(i = 1; i < cx->aes_Nrnd; ++i) + { +#if defined(ONE_TABLE) || defined(FOUR_TABLES) +#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES) + u_int32_t f2, f4, f8, f9; +#endif + mix(kt, kf); +#else + cpy(kt, kf); +#endif + kt -= 2 * nc; + } + + cpy(kt, kf); + } +} + +// y = output word, x = input word, r = row, c = column +// for r = 0, 1, 2 and 3 = column accessed for row r + +#if defined(ARRAYS) +#define s(x,c) x[c] +#else +#define s(x,c) x##c +#endif + +// I am grateful to Frank Yellin for the following constructions +// which, given the column (c) of the output state variable that +// is being computed, return the input state variables which are +// needed for each row (r) of the state + +// For the fixed block size options, compilers reduce these two +// expressions to fixed variable references. For variable block +// size code conditional clauses will sometimes be returned + +#define unused 77 // Sunset Strip + +#define fwd_var(x,r,c) \ + ( r==0 ? \ + ( c==0 ? s(x,0) \ + : c==1 ? s(x,1) \ + : c==2 ? s(x,2) \ + : c==3 ? s(x,3) \ + : c==4 ? s(x,4) \ + : c==5 ? s(x,5) \ + : c==6 ? s(x,6) \ + : s(x,7)) \ + : r==1 ? \ + ( c==0 ? s(x,1) \ + : c==1 ? s(x,2) \ + : c==2 ? s(x,3) \ + : c==3 ? nc==4 ? s(x,0) : s(x,4) \ + : c==4 ? s(x,5) \ + : c==5 ? nc==8 ? s(x,6) : s(x,0) \ + : c==6 ? s(x,7) \ + : s(x,0)) \ + : r==2 ? \ + ( c==0 ? nc==8 ? s(x,3) : s(x,2) \ + : c==1 ? nc==8 ? s(x,4) : s(x,3) \ + : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ + : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ + : c==4 ? nc==8 ? s(x,7) : s(x,0) \ + : c==5 ? nc==8 ? s(x,0) : s(x,1) \ + : c==6 ? s(x,1) \ + : s(x,2)) \ + : \ + ( c==0 ? nc==8 ? s(x,4) : s(x,3) \ + : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \ + : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \ + : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \ + : c==4 ? nc==8 ? s(x,0) : s(x,1) \ + : c==5 ? nc==8 ? s(x,1) : s(x,2) \ + : c==6 ? s(x,2) \ + : s(x,3))) + +#define inv_var(x,r,c) \ + ( r==0 ? \ + ( c==0 ? s(x,0) \ + : c==1 ? s(x,1) \ + : c==2 ? s(x,2) \ + : c==3 ? s(x,3) \ + : c==4 ? s(x,4) \ + : c==5 ? s(x,5) \ + : c==6 ? s(x,6) \ + : s(x,7)) \ + : r==1 ? \ + ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \ + : c==1 ? s(x,0) \ + : c==2 ? s(x,1) \ + : c==3 ? s(x,2) \ + : c==4 ? s(x,3) \ + : c==5 ? s(x,4) \ + : c==6 ? s(x,5) \ + : s(x,6)) \ + : r==2 ? \ + ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ + : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ + : c==2 ? nc==8 ? s(x,7) : s(x,0) \ + : c==3 ? nc==8 ? s(x,0) : s(x,1) \ + : c==4 ? nc==8 ? s(x,1) : s(x,2) \ + : c==5 ? nc==8 ? s(x,2) : s(x,3) \ + : c==6 ? s(x,3) \ + : s(x,4)) \ + : \ + ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \ + : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \ + : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \ + : c==3 ? nc==8 ? s(x,7) : s(x,0) \ + : c==4 ? nc==8 ? s(x,0) : s(x,1) \ + : c==5 ? nc==8 ? s(x,1) : s(x,2) \ + : c==6 ? s(x,2) \ + : s(x,3))) + +#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c] +#define so(y,x,c) word_out(y + 4 * c, s(x,c)) + +#if defined(FOUR_TABLES) +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c) +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c) +#elif defined(ONE_TABLE) +#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c) +#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c) +#else +#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c] +#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]) +#endif + +#if defined(FOUR_LR_TABLES) +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c) +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c) +#elif defined(ONE_LR_TABLE) +#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c) +#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c) +#else +#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c] +#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c] +#endif + +#if AES_BLOCK_SIZE == 16 + +#if defined(ARRAYS) +#define locals(y,x) x[4],y[4] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 +// the following defines prevent the compiler requiring the declaration +// of generated but unused variables in the fwd_var and inv_var macros +#define b04 unused +#define b05 unused +#define b06 unused +#define b07 unused +#define b14 unused +#define b15 unused +#define b16 unused +#define b17 unused +#endif +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); +#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) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) +#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) + +#elif AES_BLOCK_SIZE == 24 + +#if defined(ARRAYS) +#define locals(y,x) x[6],y[6] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \ + y##0,y##1,y##2,y##3,y##4,y##5 +#define b06 unused +#define b07 unused +#define b16 unused +#define b17 unused +#endif +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); \ + s(y,4) = s(x,4); s(y,5) = s(x,5); +#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); si(y,x,k,4); si(y,x,k,5) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \ + so(y,x,3); so(y,x,4); so(y,x,5) +#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); rm(y,x,k,4); rm(y,x,k,5) +#else + +#if defined(ARRAYS) +#define locals(y,x) x[8],y[8] +#else +#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \ + y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7 +#endif +#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ + s(y,2) = s(x,2); s(y,3) = s(x,3); \ + s(y,4) = s(x,4); s(y,5) = s(x,5); \ + s(y,6) = s(x,6); s(y,7) = s(x,7); + +#if AES_BLOCK_SIZE == 32 + +#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); \ + si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7) +#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \ + so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7) +#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); \ + rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7) +#else + +#define state_in(y,x,k) \ +switch(nc) \ +{ case 8: si(y,x,k,7); si(y,x,k,6); \ + case 6: si(y,x,k,5); si(y,x,k,4); \ + case 4: si(y,x,k,3); si(y,x,k,2); \ + si(y,x,k,1); si(y,x,k,0); \ +} + +#define state_out(y,x) \ +switch(nc) \ +{ case 8: so(y,x,7); so(y,x,6); \ + case 6: so(y,x,5); so(y,x,4); \ + case 4: so(y,x,3); so(y,x,2); \ + so(y,x,1); so(y,x,0); \ +} + +#if defined(FAST_VARIABLE) + +#define round(rm,y,x,k) \ +switch(nc) \ +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ + rm(y,x,k,5); rm(y,x,k,4); \ + rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ + break; \ + case 6: rm(y,x,k,5); rm(y,x,k,4); \ + rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ + break; \ + case 4: rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ + break; \ +} +#else + +#define round(rm,y,x,k) \ +switch(nc) \ +{ case 8: rm(y,x,k,7); rm(y,x,k,6); \ + case 6: rm(y,x,k,5); rm(y,x,k,4); \ + case 4: rm(y,x,k,3); rm(y,x,k,2); \ + rm(y,x,k,1); rm(y,x,k,0); \ +} + +#endif + +#endif +#endif + +void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) +{ u_int32_t locals(b0, b1); + const u_int32_t *kp = cx->aes_e_key; + +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES) + u_int32_t f2; +#endif + + state_in(b0, in_blk, kp); kp += nc; + +#if defined(UNROLL) + + switch(cx->aes_Nrnd) + { + case 14: round(fwd_rnd, b1, b0, kp ); + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc; + case 12: round(fwd_rnd, b1, b0, kp ); + round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc; + case 10: round(fwd_rnd, b1, b0, kp ); + round(fwd_rnd, b0, b1, kp + nc); + round(fwd_rnd, b1, b0, kp + 2 * nc); + round(fwd_rnd, b0, b1, kp + 3 * nc); + round(fwd_rnd, b1, b0, kp + 4 * nc); + round(fwd_rnd, b0, b1, kp + 5 * nc); + round(fwd_rnd, b1, b0, kp + 6 * nc); + round(fwd_rnd, b0, b1, kp + 7 * nc); + round(fwd_rnd, b1, b0, kp + 8 * nc); + round(fwd_lrnd, b0, b1, kp + 9 * nc); + } + +#elif defined(PARTIAL_UNROLL) + { u_int32_t rnd; + + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd) + { + round(fwd_rnd, b1, b0, kp); + round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc; + } + + round(fwd_rnd, b1, b0, kp); + round(fwd_lrnd, b0, b1, kp + nc); + } +#else + { u_int32_t rnd; + + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd) + { + round(fwd_rnd, b1, b0, kp); + l_copy(b0, b1); kp += nc; + } + + round(fwd_lrnd, b0, b1, kp); + } +#endif + + state_out(out_blk, b0); +} + +void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) +{ u_int32_t locals(b0, b1); + const u_int32_t *kp = cx->aes_d_key; + +#if !defined(ONE_TABLE) && !defined(FOUR_TABLES) + u_int32_t f2, f4, f8, f9; +#endif + + state_in(b0, in_blk, kp); kp += nc; + +#if defined(UNROLL) + + switch(cx->aes_Nrnd) + { + case 14: round(inv_rnd, b1, b0, kp ); + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc; + case 12: round(inv_rnd, b1, b0, kp ); + round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc; + case 10: round(inv_rnd, b1, b0, kp ); + round(inv_rnd, b0, b1, kp + nc); + round(inv_rnd, b1, b0, kp + 2 * nc); + round(inv_rnd, b0, b1, kp + 3 * nc); + round(inv_rnd, b1, b0, kp + 4 * nc); + round(inv_rnd, b0, b1, kp + 5 * nc); + round(inv_rnd, b1, b0, kp + 6 * nc); + round(inv_rnd, b0, b1, kp + 7 * nc); + round(inv_rnd, b1, b0, kp + 8 * nc); + round(inv_lrnd, b0, b1, kp + 9 * nc); + } + +#elif defined(PARTIAL_UNROLL) + { u_int32_t rnd; + + for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd) + { + round(inv_rnd, b1, b0, kp); + round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc; + } + + round(inv_rnd, b1, b0, kp); + round(inv_lrnd, b0, b1, kp + nc); + } +#else + { u_int32_t rnd; + + for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd) + { + round(inv_rnd, b1, b0, kp); + l_copy(b0, b1); kp += nc; + } + + round(inv_lrnd, b0, b1, kp); + } +#endif + + state_out(out_blk, b0); +} diff -urN linux-2.4.29/net/ipsec/libcrypto/libaes/aes.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes.h --- linux-2.4.29/net/ipsec/libcrypto/libaes/aes.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes.h Thu Sep 5 05:38:06 2002 @@ -0,0 +1,97 @@ +// I retain copyright in this code but I encourage its free use provided +// that I don't carry any responsibility for the results. I am especially +// happy to see it used in free and open source software. If you do use +// it I would appreciate an acknowledgement of its origin in the code or +// the product that results and I would also appreciate knowing a little +// about the use to which it is being put. I am grateful to Frank Yellin +// for some ideas that are used in this implementation. +// +// Dr B. R. Gladman 6th April 2001. +// +// This is an implementation of the AES encryption algorithm (Rijndael) +// designed by Joan Daemen and Vincent Rijmen. This version is designed +// to provide both fixed and dynamic block and key lengths and can also +// run with either big or little endian internal byte order (see aes.h). +// It inputs block and key lengths in bytes with the legal values being +// 16, 24 and 32. + +/* + * Modified by Jari Ruusu, May 1 2001 + * - Fixed some compile warnings, code was ok but gcc warned anyway. + * - Changed basic types: byte -> unsigned char, word -> u_int32_t + * - Major name space cleanup: Names visible to outside now begin + * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c + * - Removed C++ and DLL support as part of name space cleanup. + * - Eliminated unnecessary recomputation of tables. (actual bug fix) + * - Merged precomputed constant tables to aes.c file. + * - Removed data alignment restrictions for portability reasons. + * - Made block and key lengths accept bit count (128/192/256) + * as well byte count (16/24/32). + * - Removed all error checks. This change also eliminated the need + * to preinitialize the context struct to zero. + * - Removed some totally unused constants. + */ + +#ifndef _AES_H +#define _AES_H + +#if defined(__linux__) && defined(__KERNEL__) +# include +#else +# include +#endif + +// CONFIGURATION OPTIONS (see also aes.c) +// +// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or +// leave this undefined for dynamically variable block size (this will +// result in much slower code). +// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If +// left undefined a slower version providing variable block length is compiled + +#define AES_BLOCK_SIZE 16 + +// The number of key schedule words for different block and key lengths +// allowing for method of computation which requires the length to be a +// multiple of the key length +// +// Nk = 4 6 8 +// ------------- +// Nb = 4 | 60 60 64 +// 6 | 96 90 96 +// 8 | 120 120 120 + +#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32) +#define AES_KS_LENGTH 120 +#define AES_RC_LENGTH 29 +#else +#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE +#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8 +#endif + +typedef struct +{ + u_int32_t aes_Nkey; // the number of words in the key input block + u_int32_t aes_Nrnd; // the number of cipher rounds + u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule + u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule +#if !defined(AES_BLOCK_SIZE) + u_int32_t aes_Ncol; // the number of columns in the cipher state +#endif +} aes_context; + +// THE CIPHER INTERFACE + +#if !defined(AES_BLOCK_SIZE) +extern void aes_set_blk(aes_context *, const int); +#endif +extern void aes_set_key(aes_context *, const unsigned char [], const int, const int); +extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []); +extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []); + +// The block length inputs to aes_set_block and aes_set_key are in numbers +// of bytes or bits. The calls to subroutines must be made in the above +// order but multiple calls can be made without repeating earlier calls +// if their parameters have not changed. + +#endif // _AES_H diff -urN linux-2.4.29/net/ipsec/libcrypto/libaes/aes_cbc.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes_cbc.c --- linux-2.4.29/net/ipsec/libcrypto/libaes/aes_cbc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes_cbc.c Thu Sep 5 05:38:06 2002 @@ -0,0 +1,13 @@ +#ifdef __KERNEL__ +#include +#else +#include +#endif +#include "aes_cbc.h" +#include "cbc_generic.h" +/* returns bool success */ +int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) { + aes_set_key(aes_ctx, key, keysize, 0); + return 1; +} +CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt); diff -urN linux-2.4.29/net/ipsec/libcrypto/libaes/aes_cbc.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes_cbc.h --- linux-2.4.29/net/ipsec/libcrypto/libaes/aes_cbc.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes_cbc.h Thu Sep 5 05:38:06 2002 @@ -0,0 +1,4 @@ +/* Glue header */ +#include "aes.h" +int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize); +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); diff -urN linux-2.4.29/net/ipsec/libcrypto/libaes/aes_xcbc_mac.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes_xcbc_mac.c --- linux-2.4.29/net/ipsec/libcrypto/libaes/aes_xcbc_mac.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes_xcbc_mac.c Thu Sep 5 05:38:06 2002 @@ -0,0 +1,67 @@ +#ifdef __KERNEL__ +#include +#include +#define DEBUG(x) +#else +#include +#include +#define DEBUG(x) x +#endif + +#include "aes.h" +#include "aes_xcbc_mac.h" + +int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen) +{ + int ret=1; + aes_block kn[3] = { + { 0x01010101, 0x01010101, 0x01010101, 0x01010101 }, + { 0x02020202, 0x02020202, 0x02020202, 0x02020202 }, + { 0x03030303, 0x03030303, 0x03030303, 0x03030303 }, + }; + aes_set_key(&ctxm->ctx_k1, key, keylen, 0); + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]); + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2); + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3); + aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0); + return ret; +} +static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) { + int pos=0; + for (pos=1; pos <= 16; pos++, in++, out++) { + if (pos <= len) + *out ^= *in; + if (pos > len) { + DEBUG(printf("put 0x80 at pos=%d\n", pos)); + *out ^= 0x80; + break; + } + } +} +static void xor_block(aes_block res, const aes_block op) { + res[0] ^= op[0]; + res[1] ^= op[1]; + res[2] ^= op[2]; + res[3] ^= op[3]; +} +int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) { + int ret=ilen; + u_int32_t out[4] = { 0, 0, 0, 0 }; + for (; ilen > 16 ; ilen-=16) { + xor_block(out, (const u_int32_t*) &in[0]); + aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]); + in+=16; + } + do_pad_xor((u_int8_t *)&out, in, ilen); + if (ilen==16) { + DEBUG(printf("using k3\n")); + xor_block(out, ctxm->k3); + } + else + { + DEBUG(printf("using k2\n")); + xor_block(out, ctxm->k2); + } + aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash); + return ret; +} diff -urN linux-2.4.29/net/ipsec/libcrypto/libaes/aes_xcbc_mac.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes_xcbc_mac.h --- linux-2.4.29/net/ipsec/libcrypto/libaes/aes_xcbc_mac.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/aes_xcbc_mac.h Thu Sep 5 05:38:06 2002 @@ -0,0 +1,12 @@ +#ifndef _AES_XCBC_MAC_H +#define _AES_XCBC_MAC_H + +typedef u_int32_t aes_block[4]; +typedef struct { + aes_context ctx_k1; + aes_block k2; + aes_block k3; +} aes_context_mac; +int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen); +int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]); +#endif /* _AES_XCBC_MAC_H */ diff -urN linux-2.4.29/net/ipsec/libcrypto/libaes/asm/aes-i586.S linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/asm/aes-i586.S --- linux-2.4.29/net/ipsec/libcrypto/libaes/asm/aes-i586.S Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/asm/aes-i586.S Thu Sep 5 05:42:26 2002 @@ -0,0 +1,892 @@ +// +// Copyright (c) 2001, Dr Brian Gladman , Worcester, UK. +// All rights reserved. +// +// TERMS +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted subject to the following conditions: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The copyright holder's name must not be used to endorse or promote +// any products derived from this software without his specific prior +// written permission. +// +// This software is provided 'as is' with no express or implied warranties +// of correctness or fitness for purpose. + +// Modified by Jari Ruusu, December 24 2001 +// - Converted syntax to GNU CPP/assembler syntax +// - C programming interface converted back to "old" API +// - Minor portability cleanups and speed optimizations + +// An AES (Rijndael) implementation for the Pentium. This version only +// implements the standard AES block length (128 bits, 16 bytes). This code +// does not preserve the eax, ecx or edx registers or the artihmetic status +// flags. However, the ebx, esi, edi, and ebp registers are preserved across +// calls. + +// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f) +// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) +// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[]) + +#if defined(USE_UNDERLINE) +# define aes_set_key _aes_set_key +# define aes_encrypt _aes_encrypt +# define aes_decrypt _aes_decrypt +#endif +#if !defined(ALIGN32BYTES) +# define ALIGN32BYTES 32 +#endif + + .file "aes-i586.S" + .globl aes_set_key + .globl aes_encrypt + .globl aes_decrypt + +#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words) + +// offsets to parameters with one register pushed onto stack + +#define ctx 8 // AES context structure +#define in_blk 12 // input byte array address parameter +#define out_blk 16 // output byte array address parameter + +// offsets in context structure + +#define nkey 0 // key length, size 4 +#define nrnd 4 // number of rounds, size 4 +#define ekey 8 // encryption key schedule base address, size 256 +#define dkey 264 // decryption key schedule base address, size 256 + +// This macro performs a forward encryption cycle. It is entered with +// the first previous round column values in %eax, %ebx, %esi and %edi and +// exits with the final values in the same registers. + +#define fwd_rnd(p1,p2) \ + mov %ebx,(%esp) ;\ + movzbl %al,%edx ;\ + mov %eax,%ecx ;\ + mov p2(%ebp),%eax ;\ + mov %edi,4(%esp) ;\ + mov p2+12(%ebp),%edi ;\ + xor p1(,%edx,4),%eax ;\ + movzbl %ch,%edx ;\ + shr $16,%ecx ;\ + mov p2+4(%ebp),%ebx ;\ + xor p1+tlen(,%edx,4),%edi ;\ + movzbl %cl,%edx ;\ + movzbl %ch,%ecx ;\ + xor p1+3*tlen(,%ecx,4),%ebx ;\ + mov %esi,%ecx ;\ + mov p1+2*tlen(,%edx,4),%esi ;\ + movzbl %cl,%edx ;\ + xor p1(,%edx,4),%esi ;\ + movzbl %ch,%edx ;\ + shr $16,%ecx ;\ + xor p1+tlen(,%edx,4),%ebx ;\ + movzbl %cl,%edx ;\ + movzbl %ch,%ecx ;\ + xor p1+2*tlen(,%edx,4),%eax ;\ + mov (%esp),%edx ;\ + xor p1+3*tlen(,%ecx,4),%edi ;\ + movzbl %dl,%ecx ;\ + xor p2+8(%ebp),%esi ;\ + xor p1(,%ecx,4),%ebx ;\ + movzbl %dh,%ecx ;\ + shr $16,%edx ;\ + xor p1+tlen(,%ecx,4),%eax ;\ + movzbl %dl,%ecx ;\ + movzbl %dh,%edx ;\ + xor p1+2*tlen(,%ecx,4),%edi ;\ + mov 4(%esp),%ecx ;\ + xor p1+3*tlen(,%edx,4),%esi ;\ + movzbl %cl,%edx ;\ + xor p1(,%edx,4),%edi ;\ + movzbl %ch,%edx ;\ + shr $16,%ecx ;\ + xor p1+tlen(,%edx,4),%esi ;\ + movzbl %cl,%edx ;\ + movzbl %ch,%ecx ;\ + xor p1+2*tlen(,%edx,4),%ebx ;\ + xor p1+3*tlen(,%ecx,4),%eax + +// This macro performs an inverse encryption cycle. It is entered with +// the first previous round column values in %eax, %ebx, %esi and %edi and +// exits with the final values in the same registers. + +#define inv_rnd(p1,p2) \ + movzbl %al,%edx ;\ + mov %ebx,(%esp) ;\ + mov %eax,%ecx ;\ + mov p2(%ebp),%eax ;\ + mov %edi,4(%esp) ;\ + mov p2+4(%ebp),%ebx ;\ + xor p1(,%edx,4),%eax ;\ + movzbl %ch,%edx ;\ + shr $16,%ecx ;\ + mov p2+12(%ebp),%edi ;\ + xor p1+tlen(,%edx,4),%ebx ;\ + movzbl %cl,%edx ;\ + movzbl %ch,%ecx ;\ + xor p1+3*tlen(,%ecx,4),%edi ;\ + mov %esi,%ecx ;\ + mov p1+2*tlen(,%edx,4),%esi ;\ + movzbl %cl,%edx ;\ + xor p1(,%edx,4),%esi ;\ + movzbl %ch,%edx ;\ + shr $16,%ecx ;\ + xor p1+tlen(,%edx,4),%edi ;\ + movzbl %cl,%edx ;\ + movzbl %ch,%ecx ;\ + xor p1+2*tlen(,%edx,4),%eax ;\ + mov (%esp),%edx ;\ + xor p1+3*tlen(,%ecx,4),%ebx ;\ + movzbl %dl,%ecx ;\ + xor p2+8(%ebp),%esi ;\ + xor p1(,%ecx,4),%ebx ;\ + movzbl %dh,%ecx ;\ + shr $16,%edx ;\ + xor p1+tlen(,%ecx,4),%esi ;\ + movzbl %dl,%ecx ;\ + movzbl %dh,%edx ;\ + xor p1+2*tlen(,%ecx,4),%edi ;\ + mov 4(%esp),%ecx ;\ + xor p1+3*tlen(,%edx,4),%eax ;\ + movzbl %cl,%edx ;\ + xor p1(,%edx,4),%edi ;\ + movzbl %ch,%edx ;\ + shr $16,%ecx ;\ + xor p1+tlen(,%edx,4),%eax ;\ + movzbl %cl,%edx ;\ + movzbl %ch,%ecx ;\ + xor p1+2*tlen(,%edx,4),%ebx ;\ + xor p1+3*tlen(,%ecx,4),%esi + +// AES (Rijndael) Encryption Subroutine + + .text + .align ALIGN32BYTES +aes_encrypt: + push %ebp + mov ctx(%esp),%ebp // pointer to context + mov in_blk(%esp),%ecx + push %ebx + push %esi + push %edi + mov nrnd(%ebp),%edx // number of rounds + lea ekey+16(%ebp),%ebp // key pointer + +// input four columns and xor in first round key + + mov (%ecx),%eax + mov 4(%ecx),%ebx + mov 8(%ecx),%esi + mov 12(%ecx),%edi + xor -16(%ebp),%eax + xor -12(%ebp),%ebx + xor -8(%ebp),%esi + xor -4(%ebp),%edi + + sub $8,%esp // space for register saves on stack + + sub $10,%edx + je aes_15 + add $32,%ebp + sub $2,%edx + je aes_13 + add $32,%ebp + + fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key + fwd_rnd(aes_ft_tab,-48) +aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key + fwd_rnd(aes_ft_tab,-16) +aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key + fwd_rnd(aes_ft_tab,16) + fwd_rnd(aes_ft_tab,32) + fwd_rnd(aes_ft_tab,48) + fwd_rnd(aes_ft_tab,64) + fwd_rnd(aes_ft_tab,80) + fwd_rnd(aes_ft_tab,96) + fwd_rnd(aes_ft_tab,112) + fwd_rnd(aes_ft_tab,128) + fwd_rnd(aes_fl_tab,144) // last round uses a different table + +// move final values to the output array. + + mov out_blk+20(%esp),%ebp + add $8,%esp + mov %eax,(%ebp) + mov %ebx,4(%ebp) + mov %esi,8(%ebp) + mov %edi,12(%ebp) + pop %edi + pop %esi + pop %ebx + pop %ebp + ret + + +// AES (Rijndael) Decryption Subroutine + + .align ALIGN32BYTES +aes_decrypt: + push %ebp + mov ctx(%esp),%ebp // pointer to context + mov in_blk(%esp),%ecx + push %ebx + push %esi + push %edi + mov nrnd(%ebp),%edx // number of rounds + lea dkey+16(%ebp),%ebp // key pointer + +// input four columns and xor in first round key + + mov (%ecx),%eax + mov 4(%ecx),%ebx + mov 8(%ecx),%esi + mov 12(%ecx),%edi + xor -16(%ebp),%eax + xor -12(%ebp),%ebx + xor -8(%ebp),%esi + xor -4(%ebp),%edi + + sub $8,%esp // space for register saves on stack + + sub $10,%edx + je aes_25 + add $32,%ebp + sub $2,%edx + je aes_23 + add $32,%ebp + + inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key + inv_rnd(aes_it_tab,-48) +aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key + inv_rnd(aes_it_tab,-16) +aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key + inv_rnd(aes_it_tab,16) + inv_rnd(aes_it_tab,32) + inv_rnd(aes_it_tab,48) + inv_rnd(aes_it_tab,64) + inv_rnd(aes_it_tab,80) + inv_rnd(aes_it_tab,96) + inv_rnd(aes_it_tab,112) + inv_rnd(aes_it_tab,128) + inv_rnd(aes_il_tab,144) // last round uses a different table + +// move final values to the output array. + + mov out_blk+20(%esp),%ebp + add $8,%esp + mov %eax,(%ebp) + mov %ebx,4(%ebp) + mov %esi,8(%ebp) + mov %edi,12(%ebp) + pop %edi + pop %esi + pop %ebx + pop %ebp + ret + +// AES (Rijndael) Key Schedule Subroutine + +// input/output parameters + +#define aes_cx 12 // AES context +#define in_key 16 // key input array address +#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256) +#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only + +// offsets for locals + +#define cnt -4 +#define kpf -8 +#define slen 8 + +// This macro performs a column mixing operation on an input 32-bit +// word to give a 32-bit result. It uses each of the 4 bytes in the +// the input column to index 4 different tables of 256 32-bit words +// that are xored together to form the output value. + +#define mix_col(p1) \ + movzbl %bl,%ecx ;\ + mov p1(,%ecx,4),%eax ;\ + movzbl %bh,%ecx ;\ + ror $16,%ebx ;\ + xor p1+tlen(,%ecx,4),%eax ;\ + movzbl %bl,%ecx ;\ + xor p1+2*tlen(,%ecx,4),%eax ;\ + movzbl %bh,%ecx ;\ + xor p1+3*tlen(,%ecx,4),%eax + +// Key Schedule Macros + +#define ksc4(p1) \ + rol $24,%ebx ;\ + mix_col(aes_fl_tab) ;\ + ror $8,%ebx ;\ + xor 4*p1+aes_rcon_tab,%eax ;\ + xor %eax,%esi ;\ + xor %esi,%ebp ;\ + mov %esi,16*p1(%edi) ;\ + mov %ebp,16*p1+4(%edi) ;\ + xor %ebp,%edx ;\ + xor %edx,%ebx ;\ + mov %edx,16*p1+8(%edi) ;\ + mov %ebx,16*p1+12(%edi) + +#define ksc6(p1) \ + rol $24,%ebx ;\ + mix_col(aes_fl_tab) ;\ + ror $8,%ebx ;\ + xor 4*p1+aes_rcon_tab,%eax ;\ + xor 24*p1-24(%edi),%eax ;\ + mov %eax,24*p1(%edi) ;\ + xor 24*p1-20(%edi),%eax ;\ + mov %eax,24*p1+4(%edi) ;\ + xor %eax,%esi ;\ + xor %esi,%ebp ;\ + mov %esi,24*p1+8(%edi) ;\ + mov %ebp,24*p1+12(%edi) ;\ + xor %ebp,%edx ;\ + xor %edx,%ebx ;\ + mov %edx,24*p1+16(%edi) ;\ + mov %ebx,24*p1+20(%edi) + +#define ksc8(p1) \ + rol $24,%ebx ;\ + mix_col(aes_fl_tab) ;\ + ror $8,%ebx ;\ + xor 4*p1+aes_rcon_tab,%eax ;\ + xor 32*p1-32(%edi),%eax ;\ + mov %eax,32*p1(%edi) ;\ + xor 32*p1-28(%edi),%eax ;\ + mov %eax,32*p1+4(%edi) ;\ + xor 32*p1-24(%edi),%eax ;\ + mov %eax,32*p1+8(%edi) ;\ + xor 32*p1-20(%edi),%eax ;\ + mov %eax,32*p1+12(%edi) ;\ + push %ebx ;\ + mov %eax,%ebx ;\ + mix_col(aes_fl_tab) ;\ + pop %ebx ;\ + xor %eax,%esi ;\ + xor %esi,%ebp ;\ + mov %esi,32*p1+16(%edi) ;\ + mov %ebp,32*p1+20(%edi) ;\ + xor %ebp,%edx ;\ + xor %edx,%ebx ;\ + mov %edx,32*p1+24(%edi) ;\ + mov %ebx,32*p1+28(%edi) + + .align ALIGN32BYTES +aes_set_key: + pushfl + push %ebp + mov %esp,%ebp + sub $slen,%esp + push %ebx + push %esi + push %edi + + mov aes_cx(%ebp),%edx // edx -> AES context + + mov key_ln(%ebp),%ecx // key length + cmpl $128,%ecx + jb aes_30 + shr $3,%ecx +aes_30: cmpl $32,%ecx + je aes_32 + cmpl $24,%ecx + je aes_32 + mov $16,%ecx +aes_32: shr $2,%ecx + mov %ecx,nkey(%edx) + + lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length + mov %eax,nrnd(%edx) + + mov in_key(%ebp),%esi // key input array + lea ekey(%edx),%edi // key position in AES context + cld + push %ebp + mov %ecx,%eax // save key length in eax + rep ; movsl // words in the key schedule + mov -4(%esi),%ebx // put some values in registers + mov -8(%esi),%edx // to allow faster code + mov -12(%esi),%ebp + mov -16(%esi),%esi + + cmpl $4,%eax // jump on key size + je aes_36 + cmpl $6,%eax + je aes_35 + + ksc8(0) + ksc8(1) + ksc8(2) + ksc8(3) + ksc8(4) + ksc8(5) + ksc8(6) + jmp aes_37 +aes_35: ksc6(0) + ksc6(1) + ksc6(2) + ksc6(3) + ksc6(4) + ksc6(5) + ksc6(6) + ksc6(7) + jmp aes_37 +aes_36: ksc4(0) + ksc4(1) + ksc4(2) + ksc4(3) + ksc4(4) + ksc4(5) + ksc4(6) + ksc4(7) + ksc4(8) + ksc4(9) +aes_37: pop %ebp + mov aes_cx(%ebp),%edx // edx -> AES context + cmpl $0,ed_flg(%ebp) + jne aes_39 + +// compile decryption key schedule from encryption schedule - reverse +// order and do mix_column operation on round keys except first and last + + mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd + shl $2,%eax + lea dkey(%edx,%eax,4),%edi + lea ekey(%edx),%esi // kf = cx->e_key + + movsl // copy first round key (unmodified) + movsl + movsl + movsl + sub $32,%edi + movl $1,cnt(%ebp) +aes_38: // do mix column on each column of + lodsl // each round key + mov %eax,%ebx + mix_col(aes_im_tab) + stosl + lodsl + mov %eax,%ebx + mix_col(aes_im_tab) + stosl + lodsl + mov %eax,%ebx + mix_col(aes_im_tab) + stosl + lodsl + mov %eax,%ebx + mix_col(aes_im_tab) + stosl + sub $32,%edi + + incl cnt(%ebp) + mov cnt(%ebp),%eax + cmp nrnd(%edx),%eax + jb aes_38 + + movsl // copy last round key (unmodified) + movsl + movsl + movsl +aes_39: pop %edi + pop %esi + pop %ebx + mov %ebp,%esp + pop %ebp + popfl + ret + + +// finite field multiplies by {02}, {04} and {08} + +#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b)) +#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b)) +#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b)) + +// finite field multiplies required in table generation + +#define f3(x) (f2(x) ^ x) +#define f9(x) (f8(x) ^ x) +#define fb(x) (f8(x) ^ f2(x) ^ x) +#define fd(x) (f8(x) ^ f4(x) ^ x) +#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) + +// These defines generate the forward table entries + +#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x)) +#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x)) +#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x) +#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x) + +// These defines generate the inverse table entries + +#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x)) +#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x)) +#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x)) +#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x)) + +// These defines generate entries for the last round tables + +#define w0(x) (x) +#define w1(x) (x << 8) +#define w2(x) (x << 16) +#define w3(x) (x << 24) + +// macro to generate inverse mix column tables (needed for the key schedule) + +#define im_data0(p1) \ + .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\ + .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\ + .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\ + .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f) +#define im_data1(p1) \ + .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\ + .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\ + .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\ + .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f) +#define im_data2(p1) \ + .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\ + .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\ + .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\ + .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f) +#define im_data3(p1) \ + .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\ + .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\ + .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\ + .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f) +#define im_data4(p1) \ + .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\ + .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\ + .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\ + .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f) +#define im_data5(p1) \ + .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\ + .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\ + .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\ + .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf) +#define im_data6(p1) \ + .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\ + .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\ + .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\ + .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf) +#define im_data7(p1) \ + .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\ + .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\ + .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\ + .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff) + +// S-box data - 256 entries + +#define sb_data0(p1) \ + .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\ + .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\ + .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\ + .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0) +#define sb_data1(p1) \ + .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\ + .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\ + .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\ + .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75) +#define sb_data2(p1) \ + .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\ + .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\ + .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\ + .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf) +#define sb_data3(p1) \ + .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\ + .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\ + .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\ + .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2) +#define sb_data4(p1) \ + .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\ + .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\ + .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\ + .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb) +#define sb_data5(p1) \ + .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\ + .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\ + .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\ + .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08) +#define sb_data6(p1) \ + .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\ + .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\ + .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\ + .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e) +#define sb_data7(p1) \ + .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\ + .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\ + .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\ + .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16) + +// Inverse S-box data - 256 entries + +#define ib_data0(p1) \ + .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\ + .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\ + .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\ + .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb) +#define ib_data1(p1) \ + .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\ + .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\ + .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\ + .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25) +#define ib_data2(p1) \ + .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\ + .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\ + .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\ + .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84) +#define ib_data3(p1) \ + .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\ + .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\ + .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\ + .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b) +#define ib_data4(p1) \ + .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\ + .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\ + .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\ + .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e) +#define ib_data5(p1) \ + .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\ + .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\ + .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\ + .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4) +#define ib_data6(p1) \ + .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\ + .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\ + .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\ + .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef) +#define ib_data7(p1) \ + .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\ + .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\ + .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\ + .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d) + +// The rcon_table (needed for the key schedule) +// +// Here is original Dr Brian Gladman's source code: +// _rcon_tab: +// %assign x 1 +// %rep 29 +// dd x +// %assign x f2(x) +// %endrep +// +// Here is precomputed output (it's more portable this way): + + .align ALIGN32BYTES +aes_rcon_tab: + .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 + .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f + .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4 + .long 0xb3,0x7d,0xfa,0xef,0xc5 + +// The forward xor tables + + .align ALIGN32BYTES +aes_ft_tab: + sb_data0(u0) + sb_data1(u0) + sb_data2(u0) + sb_data3(u0) + sb_data4(u0) + sb_data5(u0) + sb_data6(u0) + sb_data7(u0) + + sb_data0(u1) + sb_data1(u1) + sb_data2(u1) + sb_data3(u1) + sb_data4(u1) + sb_data5(u1) + sb_data6(u1) + sb_data7(u1) + + sb_data0(u2) + sb_data1(u2) + sb_data2(u2) + sb_data3(u2) + sb_data4(u2) + sb_data5(u2) + sb_data6(u2) + sb_data7(u2) + + sb_data0(u3) + sb_data1(u3) + sb_data2(u3) + sb_data3(u3) + sb_data4(u3) + sb_data5(u3) + sb_data6(u3) + sb_data7(u3) + + .align ALIGN32BYTES +aes_fl_tab: + sb_data0(w0) + sb_data1(w0) + sb_data2(w0) + sb_data3(w0) + sb_data4(w0) + sb_data5(w0) + sb_data6(w0) + sb_data7(w0) + + sb_data0(w1) + sb_data1(w1) + sb_data2(w1) + sb_data3(w1) + sb_data4(w1) + sb_data5(w1) + sb_data6(w1) + sb_data7(w1) + + sb_data0(w2) + sb_data1(w2) + sb_data2(w2) + sb_data3(w2) + sb_data4(w2) + sb_data5(w2) + sb_data6(w2) + sb_data7(w2) + + sb_data0(w3) + sb_data1(w3) + sb_data2(w3) + sb_data3(w3) + sb_data4(w3) + sb_data5(w3) + sb_data6(w3) + sb_data7(w3) + +// The inverse xor tables + + .align ALIGN32BYTES +aes_it_tab: + ib_data0(v0) + ib_data1(v0) + ib_data2(v0) + ib_data3(v0) + ib_data4(v0) + ib_data5(v0) + ib_data6(v0) + ib_data7(v0) + + ib_data0(v1) + ib_data1(v1) + ib_data2(v1) + ib_data3(v1) + ib_data4(v1) + ib_data5(v1) + ib_data6(v1) + ib_data7(v1) + + ib_data0(v2) + ib_data1(v2) + ib_data2(v2) + ib_data3(v2) + ib_data4(v2) + ib_data5(v2) + ib_data6(v2) + ib_data7(v2) + + ib_data0(v3) + ib_data1(v3) + ib_data2(v3) + ib_data3(v3) + ib_data4(v3) + ib_data5(v3) + ib_data6(v3) + ib_data7(v3) + + .align ALIGN32BYTES +aes_il_tab: + ib_data0(w0) + ib_data1(w0) + ib_data2(w0) + ib_data3(w0) + ib_data4(w0) + ib_data5(w0) + ib_data6(w0) + ib_data7(w0) + + ib_data0(w1) + ib_data1(w1) + ib_data2(w1) + ib_data3(w1) + ib_data4(w1) + ib_data5(w1) + ib_data6(w1) + ib_data7(w1) + + ib_data0(w2) + ib_data1(w2) + ib_data2(w2) + ib_data3(w2) + ib_data4(w2) + ib_data5(w2) + ib_data6(w2) + ib_data7(w2) + + ib_data0(w3) + ib_data1(w3) + ib_data2(w3) + ib_data3(w3) + ib_data4(w3) + ib_data5(w3) + ib_data6(w3) + ib_data7(w3) + +// The inverse mix column tables + + .align ALIGN32BYTES +aes_im_tab: + im_data0(v0) + im_data1(v0) + im_data2(v0) + im_data3(v0) + im_data4(v0) + im_data5(v0) + im_data6(v0) + im_data7(v0) + + im_data0(v1) + im_data1(v1) + im_data2(v1) + im_data3(v1) + im_data4(v1) + im_data5(v1) + im_data6(v1) + im_data7(v1) + + im_data0(v2) + im_data1(v2) + im_data2(v2) + im_data3(v2) + im_data4(v2) + im_data5(v2) + im_data6(v2) + im_data7(v2) + + im_data0(v3) + im_data1(v3) + im_data2(v3) + im_data3(v3) + im_data4(v3) + im_data5(v3) + im_data6(v3) + im_data7(v3) diff -urN linux-2.4.29/net/ipsec/libcrypto/libaes/test_main.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/test_main.c --- linux-2.4.29/net/ipsec/libcrypto/libaes/test_main.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libaes/test_main.c Fri Feb 7 14:14:26 2003 @@ -0,0 +1,41 @@ +#include +#include +#include +#include "aes_cbc.h" +#define AES_BLOCK_SIZE 16 +#define KEY_SIZE 128 /* bits */ +#define KEY "1234567890123456" +#define STR "hola guaso como estaisss ... 012" +#define STRSZ (sizeof(STR)-1) + +#define EMT_AESCBC_BLKLEN AES_BLOCK_SIZE +#define AES_CONTEXT_T aes_context +#define EMT_ESPAES_KEY_SZ 16 +int pretty_print(const unsigned char *buf, int count) { + int i=0; + for (;i +#include +#include +#include "aes.h" +#include "aes_xcbc_mac.h" +#define STR "Hola guasssso c|mo estais ...012" +void print_hash(const __u8 *hash) { + printf("%08x %08x %08x %08x\n", + *(__u32*)(&hash[0]), + *(__u32*)(&hash[4]), + *(__u32*)(&hash[8]), + *(__u32*)(&hash[12])); +} +int main(int argc, char *argv[]) { + aes_block key= { 0xdeadbeef, 0xceedcaca, 0xcafebabe, 0xff010204 }; + __u8 hash[16]; + char *str = argv[1]; + aes_context_mac ctx; + if (str==NULL) { + fprintf(stderr, "pasame el str\n"); + return 255; + } + AES_xcbc_mac_set_key(&ctx, (__u8 *)&key, sizeof(key)); + AES_xcbc_mac_hash(&ctx, str, strlen(str), hash); + print_hash(hash); + str[2]='x'; + AES_xcbc_mac_hash(&ctx, str, strlen(str), hash); + print_hash(hash); + return 0; +} diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/COPYRIGHT linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/COPYRIGHT --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/COPYRIGHT Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/COPYRIGHT Thu Sep 5 05:39:46 2002 @@ -0,0 +1,46 @@ +Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +All rights reserved. + +This package is an Blowfish implementation written +by Eric Young (eay@cryptsoft.com). + +This library is free for commercial and non-commercial use as long as +the following conditions are aheared to. The following conditions +apply to all code found in this distribution. + +Copyright remains Eric Young's, and as such any Copyright notices in +the code are not to be removed. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by Eric Young (eay@cryptsoft.com) + +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +The license and distribution terms for any publically available version or +derivative of this code cannot be changed. i.e. this code cannot simply be +copied and put under another distrubution license +[including the GNU Public License.] + +The reason behind this being stated in this direct manner is past +experience in code simply being copied and the attribution removed +from it and then being distributed as part of other packages. This +implementation was a non-trivial and unpaid effort. diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/INSTALL linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/INSTALL --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/INSTALL Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/INSTALL Thu Sep 5 05:39:46 2002 @@ -0,0 +1,14 @@ +This Eric Young's blowfish implementation, taken from his SSLeay library +and made available as a separate library. + +The version number (0.7.2m) is the SSLeay version that this library was +taken from. + +To build, just unpack and type make. +If you are not using gcc, edit the Makefile. +If you are compiling for an x86 box, try the assembler (it needs improving). +There are also some compile time options that can improve performance, +these are documented in the Makefile. + +eric 15-Apr-1997 + diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/Makefile --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/Makefile Thu Sep 5 05:39:46 2002 @@ -0,0 +1,121 @@ +# +# SSLeay/crypto/blowfish/Makefile +# + +DIR= bf +TOP= ../.. +CC= cc +CPP= $(CC) -E +INC=-I ../include +CFLAG=-g -D__KERNEL__ -I/usr/src/linux/include +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKE= make -f Makefile.ssl +MAKEDEPEND= $(TOP)/util/domd $(TOP) +MAKEFILE= Makefile.ssl +AR= ar r +RANLIB= ranlib +PERL= perl + +CFLAGS= $(INC) $(CFLAG) + +.c.o: + $(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c $< -o $@ + +BF_ASM-i586 := bf-586.pl +BF_ASM-i686 := bf-686.pl +BF_ENC := bf_enc.o + +ASM-$(ARCH_ASM):=1 +ASM_X86:=$(ASM-i586)$(ASM-i686) +ifneq ($(strip $(ASM_X86)),) + BF_ENC= asm/bx86-elf.o + BF_ASM= $(BF_ASM-$(ARCH_ASM)) +endif + + +GENERAL=Makefile +TEST=bftest.c +APPS= + +LIB=libblowfish.a +LIBSRC=bf_skey.c bf_enc.c +LIBOBJ=bf_skey.o $(BF_ENC) + +SRC= $(LIBSRC) + +EXHEADER= blowfish.h +HEADER= bf_pi.h bf_locl.h $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +#top: +# (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIB) + +$(LIB): $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) + +# elf +asm/bx86-elf.o: asm/bx86unix.cpp + $(CPP) -DELF -x c asm/bx86unix.cpp | as -o asm/bx86-elf.o + +# solaris +asm/bx86-sol.o: asm/bx86unix.cpp + $(CC) -E -DSOL asm/bx86unix.cpp | sed 's/^#.*//' > asm/bx86-sol.s + as -o asm/bx86-sol.o asm/bx86-sol.s + rm -f asm/bx86-sol.s + +# a.out +asm/bx86-out.o: asm/bx86unix.cpp + $(CPP) -DOUT asm/bx86unix.cpp | as -o asm/bx86-out.o + +# bsdi +asm/bx86bsdi.o: asm/bx86unix.cpp + $(CPP) -DBSDI asm/bx86unix.cpp | sed 's/ :/:/' | as -o asm/bx86bsdi.o + +asm/bx86unix.cpp: asm/$(BF_ASM) ../perlasm/x86asm.pl ../perlasm/cbc.pl + (cd asm; $(PERL) $(BF_ASM) cpp $(PROCESSOR) >bx86unix.cpp) + +files: + $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO + +links: + @$(TOP)/util/point.sh Makefile.ssl Makefile + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: installs + +installs: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f asm/bx86unix.cpp *.o asm/*.o *.obj $(LIB) tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/README linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/README --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/README Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/README Thu Sep 5 05:39:46 2002 @@ -0,0 +1,8 @@ +This is a quick packaging up of my blowfish code into a library. +It has been lifted from SSLeay. +The copyright notices seem a little harsh because I have not spent the +time to rewrite the conditions from the normal SSLeay ones. + +Basically if you just want to play with the library, not a problem. + +eric 15-Apr-1997 diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/VERSION linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/VERSION --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/VERSION Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/VERSION Thu Sep 5 05:39:46 2002 @@ -0,0 +1,6 @@ +The version numbers will follow my SSL implementation + +0.7.2r - Some reasonable default compiler options from + Peter Gutman + +0.7.2m - the first release diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/asm/bf-586.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/asm/bf-586.pl --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/asm/bf-586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/asm/bf-586.pl Thu Sep 5 05:42:26 2002 @@ -0,0 +1,136 @@ +#!/usr/local/bin/perl + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; +require "cbc.pl"; + +&asm_init($ARGV[0],"bf-586.pl",$ARGV[$#ARGV] eq "386"); + +$BF_ROUNDS=16; +$BF_OFF=($BF_ROUNDS+2)*4; +$L="edi"; +$R="esi"; +$P="ebp"; +$tmp1="eax"; +$tmp2="ebx"; +$tmp3="ecx"; +$tmp4="edx"; + +&BF_encrypt("BF_encrypt",1); +&BF_encrypt("BF_decrypt",0); +&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1); +&asm_finish(); + +sub BF_encrypt + { + local($name,$enc)=@_; + + &function_begin_B($name,""); + + &comment(""); + + &push("ebp"); + &push("ebx"); + &mov($tmp2,&wparam(0)); + &mov($P,&wparam(1)); + &push("esi"); + &push("edi"); + + &comment("Load the 2 words"); + &mov($L,&DWP(0,$tmp2,"",0)); + &mov($R,&DWP(4,$tmp2,"",0)); + + &xor( $tmp1, $tmp1); + + # encrypting part + + if ($enc) + { + &mov($tmp2,&DWP(0,$P,"",0)); + &xor( $tmp3, $tmp3); + + &xor($L,$tmp2); + for ($i=0; $i<$BF_ROUNDS; $i+=2) + { + &comment(""); + &comment("Round $i"); + &BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1); + + &comment(""); + &comment("Round ".sprintf("%d",$i+1)); + &BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1); + } + # &mov($tmp1,&wparam(0)); In last loop + &mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); + } + else + { + &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); + &xor( $tmp3, $tmp3); + + &xor($L,$tmp2); + for ($i=$BF_ROUNDS; $i>0; $i-=2) + { + &comment(""); + &comment("Round $i"); + &BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0); + &comment(""); + &comment("Round ".sprintf("%d",$i-1)); + &BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0); + } + # &mov($tmp1,&wparam(0)); In last loop + &mov($tmp4,&DWP(0,$P,"",0)); + } + + &xor($R,$tmp4); + &mov(&DWP(4,$tmp1,"",0),$L); + + &mov(&DWP(0,$tmp1,"",0),$R); + &function_end($name); + } + +sub BF_ENCRYPT + { + local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_; + + &mov( $tmp4, &DWP(&n2a($i*4),$P,"",0)); # for next round + + &mov( $tmp2, $R); + &xor( $L, $tmp4); + + &shr( $tmp2, 16); + &mov( $tmp4, $R); + + &movb( &LB($tmp1), &HB($tmp2)); # A + &and( $tmp2, 0xff); # B + + &movb( &LB($tmp3), &HB($tmp4)); # C + &and( $tmp4, 0xff); # D + + &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4)); + &mov( $tmp2, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4)); + + &add( $tmp2, $tmp1); + &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4)); + + &xor( $tmp2, $tmp1); + &mov( $tmp4, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4)); + + &add( $tmp2, $tmp4); + if (($enc && ($i != 16)) || ((!$enc) && ($i != 1))) + { &xor( $tmp1, $tmp1); } + else + { + &comment("Load parameter 0 ($i) enc=$enc"); + &mov($tmp1,&wparam(0)); + } # In last loop + + &xor( $L, $tmp2); + # delay + } + +sub n2a + { + sprintf("%d",$_[0]); + } + diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/asm/bf-686.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/asm/bf-686.pl --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/asm/bf-686.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/asm/bf-686.pl Thu Sep 5 05:42:26 2002 @@ -0,0 +1,127 @@ +#!/usr/local/bin/perl + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; +require "cbc.pl"; + +&asm_init($ARGV[0],"bf-686.pl"); + +$BF_ROUNDS=16; +$BF_OFF=($BF_ROUNDS+2)*4; +$L="ecx"; +$R="edx"; +$P="edi"; +$tot="esi"; +$tmp1="eax"; +$tmp2="ebx"; +$tmp3="ebp"; + +&des_encrypt("BF_encrypt",1); +&des_encrypt("BF_decrypt",0); +&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1); + +&asm_finish(); + +&file_end(); + +sub des_encrypt + { + local($name,$enc)=@_; + + &function_begin($name,""); + + &comment(""); + &comment("Load the 2 words"); + &mov("eax",&wparam(0)); + &mov($L,&DWP(0,"eax","",0)); + &mov($R,&DWP(4,"eax","",0)); + + &comment(""); + &comment("P pointer, s and enc flag"); + &mov($P,&wparam(1)); + + &xor( $tmp1, $tmp1); + &xor( $tmp2, $tmp2); + + # encrypting part + + if ($enc) + { + &xor($L,&DWP(0,$P,"",0)); + for ($i=0; $i<$BF_ROUNDS; $i+=2) + { + &comment(""); + &comment("Round $i"); + &BF_ENCRYPT($i+1,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3); + + &comment(""); + &comment("Round ".sprintf("%d",$i+1)); + &BF_ENCRYPT($i+2,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3); + } + &xor($R,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); + + &mov("eax",&wparam(0)); + &mov(&DWP(0,"eax","",0),$R); + &mov(&DWP(4,"eax","",0),$L); + &function_end_A($name); + } + else + { + &xor($L,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); + for ($i=$BF_ROUNDS; $i>0; $i-=2) + { + &comment(""); + &comment("Round $i"); + &BF_ENCRYPT($i,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3); + &comment(""); + &comment("Round ".sprintf("%d",$i-1)); + &BF_ENCRYPT($i-1,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3); + } + &xor($R,&DWP(0,$P,"",0)); + + &mov("eax",&wparam(0)); + &mov(&DWP(0,"eax","",0),$R); + &mov(&DWP(4,"eax","",0),$L); + &function_end_A($name); + } + + &function_end_B($name); + } + +sub BF_ENCRYPT + { + local($i,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3)=@_; + + &rotr( $R, 16); + &mov( $tot, &DWP(&n2a($i*4),$P,"",0)); + + &movb( &LB($tmp1), &HB($R)); + &movb( &LB($tmp2), &LB($R)); + + &rotr( $R, 16); + &xor( $L, $tot); + + &mov( $tot, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4)); + &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4)); + + &movb( &LB($tmp1), &HB($R)); + &movb( &LB($tmp2), &LB($R)); + + &add( $tot, $tmp3); + &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp1,4)); # delay + + &xor( $tot, $tmp1); + &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp2,4)); + + &add( $tot, $tmp3); + &xor( $tmp1, $tmp1); + + &xor( $L, $tot); + # delay + } + +sub n2a + { + sprintf("%d",$_[0]); + } + diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/asm/readme linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/asm/readme --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/asm/readme Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/asm/readme Thu Sep 5 05:42:26 2002 @@ -0,0 +1,10 @@ +There are blowfish assembler generation scripts. +bf-586.pl version is for the pentium and +bf-686.pl is my original version, which is faster on the pentium pro. + +When using a bf-586.pl, the pentium pro/II is %8 slower than using +bf-686.pl. When using a bf-686.pl, the pentium is %16 slower +than bf-586.pl + +So the default is bf-586.pl + diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/bf_enc.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/bf_enc.c --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/bf_enc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/bf_enc.c Tue May 13 21:44:33 2003 @@ -0,0 +1,306 @@ +/* crypto/bf/bf_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "blowfish.h" +#include "bf_locl.h" + +/* Blowfish as implemented from 'Blowfish: Springer-Verlag paper' + * (From LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, + * CAMBRIDGE SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) + */ + +#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20) +#error If you set BF_ROUNDS to some value other than 16 or 20, you will have \ +to modify the code. +#endif + +void BF_encrypt(BF_LONG *data, const BF_KEY *key) + { +#ifndef BF_PTR2 + const BF_LONG *p,*s; + BF_LONG l,r; + + p=key->P; + s= &(key->S[0]); + l=data[0]; + r=data[1]; + + l^=p[0]; + BF_ENC(r,l,s,p[ 1]); + BF_ENC(l,r,s,p[ 2]); + BF_ENC(r,l,s,p[ 3]); + BF_ENC(l,r,s,p[ 4]); + BF_ENC(r,l,s,p[ 5]); + BF_ENC(l,r,s,p[ 6]); + BF_ENC(r,l,s,p[ 7]); + BF_ENC(l,r,s,p[ 8]); + BF_ENC(r,l,s,p[ 9]); + BF_ENC(l,r,s,p[10]); + BF_ENC(r,l,s,p[11]); + BF_ENC(l,r,s,p[12]); + BF_ENC(r,l,s,p[13]); + BF_ENC(l,r,s,p[14]); + BF_ENC(r,l,s,p[15]); + BF_ENC(l,r,s,p[16]); +#if BF_ROUNDS == 20 + BF_ENC(r,l,s,p[17]); + BF_ENC(l,r,s,p[18]); + BF_ENC(r,l,s,p[19]); + BF_ENC(l,r,s,p[20]); +#endif + r^=p[BF_ROUNDS+1]; + + data[1]=l&0xffffffffL; + data[0]=r&0xffffffffL; +#else + BF_LONG l,r,t,*k; + + l=data[0]; + r=data[1]; + k=(BF_LONG*)key; + + l^=k[0]; + BF_ENC(r,l,k, 1); + BF_ENC(l,r,k, 2); + BF_ENC(r,l,k, 3); + BF_ENC(l,r,k, 4); + BF_ENC(r,l,k, 5); + BF_ENC(l,r,k, 6); + BF_ENC(r,l,k, 7); + BF_ENC(l,r,k, 8); + BF_ENC(r,l,k, 9); + BF_ENC(l,r,k,10); + BF_ENC(r,l,k,11); + BF_ENC(l,r,k,12); + BF_ENC(r,l,k,13); + BF_ENC(l,r,k,14); + BF_ENC(r,l,k,15); + BF_ENC(l,r,k,16); +#if BF_ROUNDS == 20 + BF_ENC(r,l,k,17); + BF_ENC(l,r,k,18); + BF_ENC(r,l,k,19); + BF_ENC(l,r,k,20); +#endif + r^=k[BF_ROUNDS+1]; + + data[1]=l&0xffffffffL; + data[0]=r&0xffffffffL; +#endif + } + +#ifndef BF_DEFAULT_OPTIONS + +void BF_decrypt(BF_LONG *data, const BF_KEY *key) + { +#ifndef BF_PTR2 + const BF_LONG *p,*s; + BF_LONG l,r; + + p=key->P; + s= &(key->S[0]); + l=data[0]; + r=data[1]; + + l^=p[BF_ROUNDS+1]; +#if BF_ROUNDS == 20 + BF_ENC(r,l,s,p[20]); + BF_ENC(l,r,s,p[19]); + BF_ENC(r,l,s,p[18]); + BF_ENC(l,r,s,p[17]); +#endif + BF_ENC(r,l,s,p[16]); + BF_ENC(l,r,s,p[15]); + BF_ENC(r,l,s,p[14]); + BF_ENC(l,r,s,p[13]); + BF_ENC(r,l,s,p[12]); + BF_ENC(l,r,s,p[11]); + BF_ENC(r,l,s,p[10]); + BF_ENC(l,r,s,p[ 9]); + BF_ENC(r,l,s,p[ 8]); + BF_ENC(l,r,s,p[ 7]); + BF_ENC(r,l,s,p[ 6]); + BF_ENC(l,r,s,p[ 5]); + BF_ENC(r,l,s,p[ 4]); + BF_ENC(l,r,s,p[ 3]); + BF_ENC(r,l,s,p[ 2]); + BF_ENC(l,r,s,p[ 1]); + r^=p[0]; + + data[1]=l&0xffffffffL; + data[0]=r&0xffffffffL; +#else + BF_LONG l,r,t,*k; + + l=data[0]; + r=data[1]; + k=(BF_LONG *)key; + + l^=k[BF_ROUNDS+1]; +#if BF_ROUNDS == 20 + BF_ENC(r,l,k,20); + BF_ENC(l,r,k,19); + BF_ENC(r,l,k,18); + BF_ENC(l,r,k,17); +#endif + BF_ENC(r,l,k,16); + BF_ENC(l,r,k,15); + BF_ENC(r,l,k,14); + BF_ENC(l,r,k,13); + BF_ENC(r,l,k,12); + BF_ENC(l,r,k,11); + BF_ENC(r,l,k,10); + BF_ENC(l,r,k, 9); + BF_ENC(r,l,k, 8); + BF_ENC(l,r,k, 7); + BF_ENC(r,l,k, 6); + BF_ENC(l,r,k, 5); + BF_ENC(r,l,k, 4); + BF_ENC(l,r,k, 3); + BF_ENC(r,l,k, 2); + BF_ENC(l,r,k, 1); + r^=k[0]; + + data[1]=l&0xffffffffL; + data[0]=r&0xffffffffL; +#endif + } + +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int encrypt) + { + BF_LONG tin0,tin1; + BF_LONG tout0,tout1,xor0,xor1; + long l=length; + BF_LONG tin[2]; + + if (encrypt) + { + n2l(ivec,tout0); + n2l(ivec,tout1); + ivec-=8; + for (l-=8; l>=0; l-=8) + { + n2l(in,tin0); + n2l(in,tin1); + tin0^=tout0; + tin1^=tout1; + tin[0]=tin0; + tin[1]=tin1; + BF_encrypt(tin,schedule); + tout0=tin[0]; + tout1=tin[1]; + l2n(tout0,out); + l2n(tout1,out); + } + if (l != -8) + { + n2ln(in,tin0,tin1,l+8); + tin0^=tout0; + tin1^=tout1; + tin[0]=tin0; + tin[1]=tin1; + BF_encrypt(tin,schedule); + tout0=tin[0]; + tout1=tin[1]; + l2n(tout0,out); + l2n(tout1,out); + } + l2n(tout0,ivec); + l2n(tout1,ivec); + } + else + { + n2l(ivec,xor0); + n2l(ivec,xor1); + ivec-=8; + for (l-=8; l>=0; l-=8) + { + n2l(in,tin0); + n2l(in,tin1); + tin[0]=tin0; + tin[1]=tin1; + BF_decrypt(tin,schedule); + tout0=tin[0]^xor0; + tout1=tin[1]^xor1; + l2n(tout0,out); + l2n(tout1,out); + xor0=tin0; + xor1=tin1; + } + if (l != -8) + { + n2l(in,tin0); + n2l(in,tin1); + tin[0]=tin0; + tin[1]=tin1; + BF_decrypt(tin,schedule); + tout0=tin[0]^xor0; + tout1=tin[1]^xor1; + l2nn(tout0,tout1,out,l+8); + xor0=tin0; + xor1=tin1; + } + l2n(xor0,ivec); + l2n(xor1,ivec); + } + tin0=tin1=tout0=tout1=xor0=xor1=0; + tin[0]=tin[1]=0; + } + +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/bf_locl.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/bf_locl.h --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/bf_locl.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/bf_locl.h Fri Feb 7 14:14:26 2003 @@ -0,0 +1,218 @@ +/* crypto/bf/bf_locl.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BF_LOCL_H +#define HEADER_BF_LOCL_H + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* This is actually a big endian algorithm, the most significant byte + * is used to lookup array 0 */ + +#if defined(BF_PTR2) + +/* + * This is basically a special Intel version. Point is that Intel + * doesn't have many registers, but offers a reach choice of addressing + * modes. So we spare some registers by directly traversing BF_KEY + * structure and hiring the most decorated addressing mode. The code + * generated by EGCS is *perfectly* competitive with assembler + * implementation! + */ +#define BF_ENC(LL,R,KEY,Pi) (\ + LL^=KEY[Pi], \ + t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \ + t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \ + LL^=t \ + ) + +#elif defined(BF_PTR) + +#ifndef BF_LONG_LOG2 +#define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */ +#endif +#define BF_M (0xFF<>BF_i)&BF_M gets folded into a single instruction, namely + * rlwinm. So let'em double-check if their compiler does it. + */ + +#define BF_ENC(LL,R,S,P) ( \ + LL^=P, \ + LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \ + *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \ + *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \ + *(BF_LONG *)((unsigned char *)&(S[768])+((R<>24)&0xff)] + \ + S[0x0100+((int)(R>>16)&0xff)])^ \ + S[0x0200+((int)(R>> 8)&0xff)])+ \ + S[0x0300+((int)(R )&0xff)])&0xffffffffL \ + ) +#endif + +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/bf_pi.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/bf_pi.h --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/bf_pi.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/bf_pi.h Thu Sep 5 05:39:46 2002 @@ -0,0 +1,325 @@ +/* crypto/bf/bf_pi.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +static const BF_KEY bf_init= { + { + 0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L, + 0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L, + 0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL, + 0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L, + 0x9216d5d9L, 0x8979fb1b + },{ + 0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, 0xd01adfb7L, + 0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, 0xf12c7f99L, + 0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, 0x858efc16L, + 0x636920d8L, 0x71574e69L, 0xa458fea3L, 0xf4933d7eL, + 0x0d95748fL, 0x728eb658L, 0x718bcd58L, 0x82154aeeL, + 0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, 0x2af26013L, + 0xc5d1b023L, 0x286085f0L, 0xca417918L, 0xb8db38efL, + 0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, 0xb01e8a3eL, + 0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, 0x55605c60L, + 0xe65525f3L, 0xaa55ab94L, 0x57489862L, 0x63e81440L, + 0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, 0x1141e8ceL, + 0xa15486afL, 0x7c72e993L, 0xb3ee1411L, 0x636fbc2aL, + 0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, 0x9b87931eL, + 0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, 0x28958677L, + 0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, 0x66282193L, + 0x61d809ccL, 0xfb21a991L, 0x487cac60L, 0x5dec8032L, + 0xef845d5dL, 0xe98575b1L, 0xdc262302L, 0xeb651b88L, + 0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, 0x83f44239L, + 0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, 0x9e1f9b5eL, + 0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, 0xabd388f0L, + 0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, 0xab5133a3L, + 0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, 0x7efb2a98L, + 0xa1f1651dL, 0x39af0176L, 0x66ca593eL, 0x82430e88L, + 0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, 0x3b8b5ebeL, + 0xe06f75d8L, 0x85c12073L, 0x401a449fL, 0x56c16aa6L, + 0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, 0x429b023dL, + 0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, 0x49f1c09bL, + 0x075372c9L, 0x80991b7bL, 0x25d479d8L, 0xf6e8def7L, + 0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, 0x04c006baL, + 0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, 0x196a2463L, + 0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, 0x3b52ec6fL, + 0x6dfc511fL, 0x9b30952cL, 0xcc814544L, 0xaf5ebd09L, + 0xbee3d004L, 0xde334afdL, 0x660f2807L, 0x192e4bb3L, + 0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, 0xb9d3fbdbL, + 0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, 0x402c7279L, + 0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, 0xdb3222f8L, + 0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, 0xad0552abL, + 0x323db5faL, 0xfd238760L, 0x53317b48L, 0x3e00df82L, + 0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, 0xdf1769dbL, + 0xd542a8f6L, 0x287effc3L, 0xac6732c6L, 0x8c4f5573L, + 0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, 0xb8f011a0L, + 0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, 0x2dd1d35bL, + 0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, 0x4bfb9790L, + 0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, 0xcee4c6e8L, + 0xef20cadaL, 0x36774c01L, 0xd07e9efeL, 0x2bf11fb4L, + 0x95dbda4dL, 0xae909198L, 0xeaad8e71L, 0x6b93d5a0L, + 0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, 0x8e7594b7L, + 0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, 0x900df01cL, + 0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, 0xb3a8c1adL, + 0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, 0x8b021fa1L, + 0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, 0xce89e299L, + 0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, 0xd2ada8d9L, + 0x165fa266L, 0x80957705L, 0x93cc7314L, 0x211a1477L, + 0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, 0xfb9d35cfL, + 0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, 0xae1e7e49L, + 0x00250e2dL, 0x2071b35eL, 0x226800bbL, 0x57b8e0afL, + 0x2464369bL, 0xf009b91eL, 0x5563911dL, 0x59dfa6aaL, + 0x78c14389L, 0xd95a537fL, 0x207d5ba2L, 0x02e5b9c5L, + 0x83260376L, 0x6295cfa9L, 0x11c81968L, 0x4e734a41L, + 0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, 0x9a532915L, + 0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, 0x81e67400L, + 0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, 0x2a0dd915L, + 0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, 0xc5855664L, + 0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, 0x6e85076aL, + 0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, 0xc4192623L, + 0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, 0x8fedb266L, + 0xecaa8c71L, 0x699a17ffL, 0x5664526cL, 0xc2b19ee1L, + 0x193602a5L, 0x75094c29L, 0xa0591340L, 0xe4183a3eL, + 0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, 0x99f73fd6L, + 0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, 0xf0255dc1L, + 0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, 0x021ecc5eL, + 0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, 0x6b6a70a1L, + 0x687f3584L, 0x52a0e286L, 0xb79c5305L, 0xaa500737L, + 0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, 0x5716f2b8L, + 0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, 0x0200b3ffL, + 0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, 0xdc0921bdL, + 0xd19113f9L, 0x7ca92ff6L, 0x94324773L, 0x22f54701L, + 0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, 0x9af3dda7L, + 0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, 0xa4751e41L, + 0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, 0x183eb331L, + 0x4e548b38L, 0x4f6db908L, 0x6f420d03L, 0xf60a04bfL, + 0x2cb81290L, 0x24977c79L, 0x5679b072L, 0xbcaf89afL, + 0xde9a771fL, 0xd9930810L, 0xb38bae12L, 0xdccf3f2eL, + 0x5512721fL, 0x2e6b7124L, 0x501adde6L, 0x9f84cd87L, + 0x7a584718L, 0x7408da17L, 0xbc9f9abcL, 0xe94b7d8cL, + 0xec7aec3aL, 0xdb851dfaL, 0x63094366L, 0xc464c3d2L, + 0xef1c1847L, 0x3215d908L, 0xdd433b37L, 0x24c2ba16L, + 0x12a14d43L, 0x2a65c451L, 0x50940002L, 0x133ae4ddL, + 0x71dff89eL, 0x10314e55L, 0x81ac77d6L, 0x5f11199bL, + 0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, 0x5924a509L, + 0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, 0x1e153c6eL, + 0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, 0x5a3e2ab3L, + 0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, 0x99e71d0fL, + 0x803e89d6L, 0x5266c825L, 0x2e4cc978L, 0x9c10b36aL, + 0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, 0x1e0a2df4L, + 0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, 0x19c27960L, + 0x5223a708L, 0xf71312b6L, 0xebadfe6eL, 0xeac31f66L, + 0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, 0x018cff28L, + 0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, 0x68ab9802L, + 0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, 0x5b6e2f84L, + 0x1521b628L, 0x29076170L, 0xecdd4775L, 0x619f1510L, + 0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, 0xaa0363cfL, + 0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, 0xcbaade14L, + 0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, 0xb2f3846eL, + 0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, 0x655abb50L, + 0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, 0xc021b8f7L, + 0x9b540b19L, 0x875fa099L, 0x95f7997eL, 0x623d7da8L, + 0xf837889aL, 0x97e32d77L, 0x11ed935fL, 0x16681281L, + 0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, 0x7858ba99L, + 0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, 0x1ac24696L, + 0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, 0x6dbc3128L, + 0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, 0xee7c3c73L, + 0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, 0x203e13e0L, + 0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, 0xfacb4fd0L, + 0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, 0x41cd2105L, + 0xd81e799eL, 0x86854dc7L, 0xe44b476aL, 0x3d816250L, + 0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, 0xc1c7b6a3L, + 0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, 0x5692b285L, + 0x095bbf00L, 0xad19489dL, 0x1462b174L, 0x23820e00L, + 0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, 0x233f7061L, + 0x3372f092L, 0x8d937e41L, 0xd65fecf1L, 0x6c223bdbL, + 0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, 0xce77326eL, + 0xa6078084L, 0x19f8509eL, 0xe8efd855L, 0x61d99735L, + 0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, 0x800bcadcL, + 0x9e447a2eL, 0xc3453484L, 0xfdd56705L, 0x0e1e9ec9L, + 0xdb73dbd3L, 0x105588cdL, 0x675fda79L, 0xe3674340L, + 0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, 0xf16dff20L, + 0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, 0xdb83adf7L, + 0xe93d5a68L, 0x948140f7L, 0xf64c261cL, 0x94692934L, + 0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, 0xd4a20068L, + 0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, 0x500061afL, + 0x1e39f62eL, 0x97244546L, 0x14214f74L, 0xbf8b8840L, + 0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, 0x66a02f45L, + 0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, 0x31cb8504L, + 0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, 0xabca0a9aL, + 0x28507825L, 0x530429f4L, 0x0a2c86daL, 0xe9b66dfbL, + 0x68dc1462L, 0xd7486900L, 0x680ec0a4L, 0x27a18deeL, + 0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, 0x7af4d6b6L, + 0xaace1e7cL, 0xd3375fecL, 0xce78a399L, 0x406b2a42L, + 0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, 0x3b124e8bL, + 0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, 0xeae397b2L, + 0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, 0xca7820fbL, + 0xfb0af54eL, 0xd8feb397L, 0x454056acL, 0xba489527L, + 0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, 0xd096954bL, + 0x55a867bcL, 0xa1159a58L, 0xcca92963L, 0x99e1db33L, + 0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, 0x9029317cL, + 0xfdf8e802L, 0x04272f70L, 0x80bb155cL, 0x05282ce3L, + 0x95c11548L, 0xe4c66d22L, 0x48c1133fL, 0xc70f86dcL, + 0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, 0x5d886e17L, + 0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, 0x41113564L, + 0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, 0x1f636c1bL, + 0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, 0xcad18115L, + 0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, 0xeebeb922L, + 0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, 0x2da2f728L, + 0xd0127845L, 0x95b794fdL, 0x647d0862L, 0xe7ccf5f0L, + 0x5449a36fL, 0x877d48faL, 0xc39dfd27L, 0xf33e8d1eL, + 0x0a476341L, 0x992eff74L, 0x3a6f6eabL, 0xf4f8fd37L, + 0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, 0xdb6e6b0dL, + 0xc67b5510L, 0x6d672c37L, 0x2765d43bL, 0xdcd0e804L, + 0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, 0x690fed0bL, + 0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, 0xd9155ea3L, + 0xbb132f88L, 0x515bad24L, 0x7b9479bfL, 0x763bd6ebL, + 0x37392eb3L, 0xcc115979L, 0x8026e297L, 0xf42e312dL, + 0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, 0x782ef11cL, + 0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, 0x4bfb6350L, + 0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, 0xe2e1c3c9L, + 0x44421659L, 0x0a121386L, 0xd90cec6eL, 0xd5abea2aL, + 0x64af674eL, 0xda86a85fL, 0xbebfe988L, 0x64e4c3feL, + 0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, 0x6003604dL, + 0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, 0xd736fcccL, + 0x83426b33L, 0xf01eab71L, 0xb0804187L, 0x3c005e5fL, + 0x77a057beL, 0xbde8ae24L, 0x55464299L, 0xbf582e61L, + 0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, 0x8789bdc2L, + 0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, 0x46fcd9b9L, + 0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, 0x915f95e2L, + 0x466e598eL, 0x20b45770L, 0x8cd55591L, 0xc902de4cL, + 0xb90bace1L, 0xbb8205d0L, 0x11a86248L, 0x7574a99eL, + 0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, 0xc4324633L, + 0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, 0x1d6efe10L, + 0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, 0x2868f169L, + 0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, 0x4fcd7f52L, + 0x50115e01L, 0xa70683faL, 0xa002b5c4L, 0x0de6d027L, + 0x9af88c27L, 0x773f8641L, 0xc3604c06L, 0x61a806b5L, + 0xf0177a28L, 0xc0f586e0L, 0x006058aaL, 0x30dc7d62L, + 0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, 0xc2c21634L, + 0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, 0xce591d76L, + 0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, 0x7c927c24L, + 0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, 0xd39eb8fcL, + 0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, 0x4dad0fc4L, + 0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, 0x6c51133cL, + 0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, 0xddc6c837L, + 0xd79a3234L, 0x92638212L, 0x670efa8eL, 0x406000e0L, + 0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, 0x5ac52d1bL, + 0x5cb0679eL, 0x4fa33742L, 0xd3822740L, 0x99bc9bbeL, + 0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, 0xc700c47bL, + 0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, 0x6a366eb4L, + 0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, 0x6549c2c8L, + 0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, 0x4cd04dc6L, + 0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, 0xbe5ee304L, + 0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, 0x9a86ee22L, + 0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, 0x9cf2d0a4L, + 0x83c061baL, 0x9be96a4dL, 0x8fe51550L, 0xba645bd6L, + 0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, 0xef5562e9L, + 0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, 0x77fa0a59L, + 0x80e4a915L, 0x87b08601L, 0x9b09e6adL, 0x3b3ee593L, + 0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, 0x022b8b51L, + 0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, 0x7c7d2d28L, + 0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, 0x5a88f54cL, + 0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, 0xed93fa9bL, + 0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, 0x79132e28L, + 0x785f0191L, 0xed756055L, 0xf7960e44L, 0xe3d35e8cL, + 0x15056dd4L, 0x88f46dbaL, 0x03a16125L, 0x0564f0bdL, + 0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, 0xa93a072aL, + 0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, 0x26dcf319L, + 0x7533d928L, 0xb155fdf5L, 0x03563482L, 0x8aba3cbbL, + 0x28517711L, 0xc20ad9f8L, 0xabcc5167L, 0xccad925fL, + 0x4de81751L, 0x3830dc8eL, 0x379d5862L, 0x9320f991L, + 0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, 0x774fbe32L, + 0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, 0x6413e680L, + 0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, 0x09072166L, + 0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, 0x1c20c8aeL, + 0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, 0x6bb4e3bbL, + 0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, 0xbcb4cdd5L, + 0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, 0xbf3c6f47L, + 0xd29be463L, 0x542f5d9eL, 0xaec2771bL, 0xf64e6370L, + 0x740e0d8dL, 0xe75b1357L, 0xf8721671L, 0xaf537d5dL, + 0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, 0x0115af84L, + 0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, 0xce6ea048L, + 0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, 0x277227f8L, + 0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, 0x344525bdL, + 0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, 0xa01fbac9L, + 0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, 0xa1e8aac7L, + 0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, 0xd50ada38L, + 0x0339c32aL, 0xc6913667L, 0x8df9317cL, 0xe0b12b4fL, + 0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, 0x27d9459cL, + 0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, 0x9b941525L, + 0xfae59361L, 0xceb69cebL, 0xc2a86459L, 0x12baa8d1L, + 0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, 0xcb03a442L, + 0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, 0x3278e964L, + 0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, 0x8971f21eL, + 0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, 0xc37632d8L, + 0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, 0x0fe3f11dL, + 0xe54cda54L, 0x1edad891L, 0xce6279cfL, 0xcd3e7e6fL, + 0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, 0xf6fb2299L, + 0xf523f357L, 0xa6327623L, 0x93a83531L, 0x56cccd02L, + 0xacf08162L, 0x5a75ebb5L, 0x6e163697L, 0x88d273ccL, + 0xde966292L, 0x81b949d0L, 0x4c50901bL, 0x71c65614L, + 0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, 0xc3f27b9aL, + 0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, 0x35bdd2f6L, + 0x71126905L, 0xb2040222L, 0xb6cbcf7cL, 0xcd769c2bL, + 0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, 0x2547adf0L, + 0xba38209cL, 0xf746ce76L, 0x77afa1c5L, 0x20756060L, + 0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, 0x4cf9aa7eL, + 0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, 0xd6ebe1f9L, + 0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, 0xc208e69fL, + 0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, 0x3ac372e6L, + } + }; + diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/bf_skey.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/bf_skey.c --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/bf_skey.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/bf_skey.c Fri Feb 7 14:14:26 2003 @@ -0,0 +1,122 @@ +/* crypto/bf/bf_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif + +#include "blowfish.h" +#include "bf_locl.h" +#include "bf_pi.h" + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data) + { + int i; + BF_LONG *p,ri,in[2]; + const unsigned char *d,*end; + + + memcpy((char *)key,(const char *)&bf_init,sizeof(BF_KEY)); + p=key->P; + + if (len > ((BF_ROUNDS+2)*4)) len=(BF_ROUNDS+2)*4; + + d=data; + end= &(data[len]); + for (i=0; i<(BF_ROUNDS+2); i++) + { + ri= *(d++); + if (d >= end) d=data; + + ri<<=8; + ri|= *(d++); + if (d >= end) d=data; + + ri<<=8; + ri|= *(d++); + if (d >= end) d=data; + + ri<<=8; + ri|= *(d++); + if (d >= end) d=data; + + p[i]^=ri; + } + + in[0]=0L; + in[1]=0L; + for (i=0; i<(BF_ROUNDS+2); i+=2) + { + BF_encrypt(in,key); + p[i ]=in[0]; + p[i+1]=in[1]; + } + + p=key->S; + for (i=0; i<4*256; i+=2) + { + BF_encrypt(in,key); + p[i ]=in[0]; + p[i+1]=in[1]; + } + } + diff -urN linux-2.4.29/net/ipsec/libcrypto/libblowfish/blowfish.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/blowfish.h --- linux-2.4.29/net/ipsec/libcrypto/libblowfish/blowfish.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libblowfish/blowfish.h Fri Feb 7 14:14:26 2003 @@ -0,0 +1,133 @@ +/* crypto/bf/blowfish.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BLOWFISH_H +#define HEADER_BLOWFISH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NO_BF +#error BF is disabled. +#endif + +#define BF_ENCRYPT 1 +#define BF_DECRYPT 0 + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! BF_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(WIN16) || defined(__LP32__) +#define BF_LONG unsigned long +#elif defined(_CRAY) || defined(__ILP64__) +#define BF_LONG unsigned long +#define BF_LONG_LOG2 3 +#endif +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ + +/* des.h-like hack */ +#ifndef BF_LONG +#ifdef __KERNEL__ +#include +#else +#include +#endif +#define BF_LONG u_int32_t +#endif + +#define BF_ROUNDS 16 +#define BF_BLOCK 8 + +typedef struct bf_key_st + { + BF_LONG P[BF_ROUNDS+2]; + BF_LONG S[4*256]; + } BF_KEY; + + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data,const BF_KEY *key); +void BF_decrypt(BF_LONG *data,const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int *num); +const char *BF_options(void); + +#ifdef __cplusplus +} +#endif + +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libcast/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/Makefile --- linux-2.4.29/net/ipsec/libcrypto/libcast/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/Makefile Thu Sep 5 05:48:04 2002 @@ -0,0 +1,112 @@ +# +# SSLeay/crypto/cast/Makefile +# + +DIR= cast +TOP= ../.. +CC= cc +CPP= $(CC) -E +INCLUDES= +CFLAG=-g -I ../include -D__KERNEL__ -I/usr/src/linux/include +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKE= make -f Makefile.ssl +MAKEDEPEND= $(TOP)/util/domd $(TOP) +MAKEFILE= Makefile.ssl +AR= ar r +RANLIB= ranlib +PERL= perl + +CAST_ENC := c_enc.o + +ASM-$(ARCH_ASM):=1 +ASM_X86:=$(ASM-i586)$(ASM-i686) +ifneq ($(strip $(ASM_X86)),) + CAST_ENC:= asm/cx86-elf.o +endif + +CFLAGS= $(INCLUDES) $(CFLAG) + +GENERAL=Makefile +TEST=casttest.c +APPS= + +LIB=libcast.a +LIBSRC=c_skey.c c_enc.c +LIBOBJ=c_skey.o $(CAST_ENC) + +SRC= $(LIBSRC) + +EXHEADER= cast.h +HEADER= cast_s.h cast_lcl.h $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +#top: +# (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIB) + +$(LIB): $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) + +# elf +asm/cx86-elf.o: asm/cx86unix.cpp + $(CPP) -DELF -x c asm/cx86unix.cpp | as -o asm/cx86-elf.o + +# solaris +asm/cx86-sol.o: asm/cx86unix.cpp + $(CC) -E -DSOL asm/cx86unix.cpp | sed 's/^#.*//' > asm/cx86-sol.s + as -o asm/cx86-sol.o asm/cx86-sol.s + rm -f asm/cx86-sol.s + +# a.out +asm/cx86-out.o: asm/cx86unix.cpp + $(CPP) -DOUT asm/cx86unix.cpp | as -o asm/cx86-out.o + +# bsdi +asm/cx86bsdi.o: asm/cx86unix.cpp + $(CPP) -DBSDI asm/cx86unix.cpp | sed 's/ :/:/' | as -o asm/cx86bsdi.o + +asm/cx86unix.cpp: asm/cast-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl + (cd asm; $(PERL) cast-586.pl cpp $(PROCESSOR) >cx86unix.cpp) + +files: + $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO + +links: + @$(TOP)/util/point.sh Makefile.ssl Makefile + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f asm/cx86unix.cpp *.o asm/*.o *.obj $(LIB) tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff -urN linux-2.4.29/net/ipsec/libcrypto/libcast/asm/cast-586.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/asm/cast-586.pl --- linux-2.4.29/net/ipsec/libcrypto/libcast/asm/cast-586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/asm/cast-586.pl Thu Sep 5 05:48:32 2002 @@ -0,0 +1,176 @@ +#!/usr/local/bin/perl + +# define for pentium pro friendly version +$ppro=1; + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; +require "cbc.pl"; + +&asm_init($ARGV[0],"cast-586.pl",$ARGV[$#ARGV] eq "386"); + +$CAST_ROUNDS=16; +$L="edi"; +$R="esi"; +$K="ebp"; +$tmp1="ecx"; +$tmp2="ebx"; +$tmp3="eax"; +$tmp4="edx"; +$S1="CAST_S_table0"; +$S2="CAST_S_table1"; +$S3="CAST_S_table2"; +$S4="CAST_S_table3"; + +@F1=("add","xor","sub"); +@F2=("xor","sub","add"); +@F3=("sub","add","xor"); + +&CAST_encrypt("CAST_encrypt",1); +&CAST_encrypt("CAST_decrypt",0); +&cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1); + +&asm_finish(); + +sub CAST_encrypt { + local($name,$enc)=@_; + + local($win_ex)=<<"EOF"; +EXTERN _CAST_S_table0:DWORD +EXTERN _CAST_S_table1:DWORD +EXTERN _CAST_S_table2:DWORD +EXTERN _CAST_S_table3:DWORD +EOF + &main::external_label( + "CAST_S_table0", + "CAST_S_table1", + "CAST_S_table2", + "CAST_S_table3", + ); + + &function_begin_B($name,$win_ex); + + &comment(""); + + &push("ebp"); + &push("ebx"); + &mov($tmp2,&wparam(0)); + &mov($K,&wparam(1)); + &push("esi"); + &push("edi"); + + &comment("Load the 2 words"); + &mov($L,&DWP(0,$tmp2,"",0)); + &mov($R,&DWP(4,$tmp2,"",0)); + + &comment('Get short key flag'); + &mov($tmp3,&DWP(128,$K,"",0)); + if($enc) { + &push($tmp3); + } else { + &or($tmp3,$tmp3); + &jnz(&label('cast_dec_skip')); + } + + &xor($tmp3, $tmp3); + + # encrypting part + + if ($enc) { + &E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &comment('test short key flag'); + &pop($tmp4); + &or($tmp4,$tmp4); + &jnz(&label('cast_enc_done')); + &E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + } else { + &E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &set_label('cast_dec_skip'); + &E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + } + + &set_label('cast_enc_done') if $enc; +# Why the nop? - Ben 17/1/99 + &nop(); + &mov($tmp3,&wparam(0)); + &mov(&DWP(4,$tmp3,"",0),$L); + &mov(&DWP(0,$tmp3,"",0),$R); + &function_end($name); +} + +sub E_CAST { + local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_; + # Ri needs to have 16 pre added. + + &comment("round $i"); + &mov( $tmp4, &DWP($i*8,$K,"",1)); + + &mov( $tmp1, &DWP($i*8+4,$K,"",1)); + &$OP1( $tmp4, $R); + + &rotl( $tmp4, &LB($tmp1)); + + if ($ppro) { + &mov( $tmp2, $tmp4); # B + &xor( $tmp1, $tmp1); + + &movb( &LB($tmp1), &HB($tmp4)); # A + &and( $tmp2, 0xff); + + &shr( $tmp4, 16); # + &xor( $tmp3, $tmp3); + } else { + &mov( $tmp2, $tmp4); # B + &movb( &LB($tmp1), &HB($tmp4)); # A # BAD BAD BAD + + &shr( $tmp4, 16); # + &and( $tmp2, 0xff); + } + + &movb( &LB($tmp3), &HB($tmp4)); # C # BAD BAD BAD + &and( $tmp4, 0xff); # D + + &mov( $tmp1, &DWP($S1,"",$tmp1,4)); + &mov( $tmp2, &DWP($S2,"",$tmp2,4)); + + &$OP2( $tmp1, $tmp2); + &mov( $tmp2, &DWP($S3,"",$tmp3,4)); + + &$OP3( $tmp1, $tmp2); + &mov( $tmp2, &DWP($S4,"",$tmp4,4)); + + &$OP1( $tmp1, $tmp2); + # XXX + + &xor( $L, $tmp1); + # XXX +} + diff -urN linux-2.4.29/net/ipsec/libcrypto/libcast/asm/readme linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/asm/readme --- linux-2.4.29/net/ipsec/libcrypto/libcast/asm/readme Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/asm/readme Thu Sep 5 05:48:32 2002 @@ -0,0 +1,7 @@ +There is a ppro flag in cast-586 which turns on/off +generation of pentium pro/II friendly code + +This flag makes the inner loop one cycle longer, but generates +code that runs %30 faster on the pentium pro/II, while only %7 slower +on the pentium. By default, this flag is on. + diff -urN linux-2.4.29/net/ipsec/libcrypto/libcast/c_enc.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/c_enc.c --- linux-2.4.29/net/ipsec/libcrypto/libcast/c_enc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/c_enc.c Thu Sep 5 05:48:04 2002 @@ -0,0 +1,207 @@ +/* crypto/cast/c_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "cast.h" +#include "cast_lcl.h" + +void CAST_encrypt(CAST_LONG *data, CAST_KEY *key) + { + register CAST_LONG l,r,*k,t; + + k= &(key->data[0]); + l=data[0]; + r=data[1]; + + E_CAST( 0,k,l,r,+,^,-); + E_CAST( 1,k,r,l,^,-,+); + E_CAST( 2,k,l,r,-,+,^); + E_CAST( 3,k,r,l,+,^,-); + E_CAST( 4,k,l,r,^,-,+); + E_CAST( 5,k,r,l,-,+,^); + E_CAST( 6,k,l,r,+,^,-); + E_CAST( 7,k,r,l,^,-,+); + E_CAST( 8,k,l,r,-,+,^); + E_CAST( 9,k,r,l,+,^,-); + E_CAST(10,k,l,r,^,-,+); + E_CAST(11,k,r,l,-,+,^); + if(!key->short_key) + { + E_CAST(12,k,l,r,+,^,-); + E_CAST(13,k,r,l,^,-,+); + E_CAST(14,k,l,r,-,+,^); + E_CAST(15,k,r,l,+,^,-); + } + + data[1]=l&0xffffffffL; + data[0]=r&0xffffffffL; + } + +void CAST_decrypt(CAST_LONG *data, CAST_KEY *key) + { + register CAST_LONG l,r,*k,t; + + k= &(key->data[0]); + l=data[0]; + r=data[1]; + + if(!key->short_key) + { + E_CAST(15,k,l,r,+,^,-); + E_CAST(14,k,r,l,-,+,^); + E_CAST(13,k,l,r,^,-,+); + E_CAST(12,k,r,l,+,^,-); + } + E_CAST(11,k,l,r,-,+,^); + E_CAST(10,k,r,l,^,-,+); + E_CAST( 9,k,l,r,+,^,-); + E_CAST( 8,k,r,l,-,+,^); + E_CAST( 7,k,l,r,^,-,+); + E_CAST( 6,k,r,l,+,^,-); + E_CAST( 5,k,l,r,-,+,^); + E_CAST( 4,k,r,l,^,-,+); + E_CAST( 3,k,l,r,+,^,-); + E_CAST( 2,k,r,l,-,+,^); + E_CAST( 1,k,l,r,^,-,+); + E_CAST( 0,k,r,l,+,^,-); + + data[1]=l&0xffffffffL; + data[0]=r&0xffffffffL; + } + +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + CAST_KEY *ks, unsigned char *iv, int enc) + { + register CAST_LONG tin0,tin1; + register CAST_LONG tout0,tout1,xor0,xor1; + register long l=length; + CAST_LONG tin[2]; + + if (enc) + { + n2l(iv,tout0); + n2l(iv,tout1); + iv-=8; + for (l-=8; l>=0; l-=8) + { + n2l(in,tin0); + n2l(in,tin1); + tin0^=tout0; + tin1^=tout1; + tin[0]=tin0; + tin[1]=tin1; + CAST_encrypt(tin,ks); + tout0=tin[0]; + tout1=tin[1]; + l2n(tout0,out); + l2n(tout1,out); + } + if (l != -8) + { + n2ln(in,tin0,tin1,l+8); + tin0^=tout0; + tin1^=tout1; + tin[0]=tin0; + tin[1]=tin1; + CAST_encrypt(tin,ks); + tout0=tin[0]; + tout1=tin[1]; + l2n(tout0,out); + l2n(tout1,out); + } + l2n(tout0,iv); + l2n(tout1,iv); + } + else + { + n2l(iv,xor0); + n2l(iv,xor1); + iv-=8; + for (l-=8; l>=0; l-=8) + { + n2l(in,tin0); + n2l(in,tin1); + tin[0]=tin0; + tin[1]=tin1; + CAST_decrypt(tin,ks); + tout0=tin[0]^xor0; + tout1=tin[1]^xor1; + l2n(tout0,out); + l2n(tout1,out); + xor0=tin0; + xor1=tin1; + } + if (l != -8) + { + n2l(in,tin0); + n2l(in,tin1); + tin[0]=tin0; + tin[1]=tin1; + CAST_decrypt(tin,ks); + tout0=tin[0]^xor0; + tout1=tin[1]^xor1; + l2nn(tout0,tout1,out,l+8); + xor0=tin0; + xor1=tin1; + } + l2n(xor0,iv); + l2n(xor1,iv); + } + tin0=tin1=tout0=tout1=xor0=xor1=0; + tin[0]=tin[1]=0; + } + diff -urN linux-2.4.29/net/ipsec/libcrypto/libcast/c_skey.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/c_skey.c --- linux-2.4.29/net/ipsec/libcrypto/libcast/c_skey.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/c_skey.c Thu Sep 5 05:48:04 2002 @@ -0,0 +1,166 @@ +/* crypto/cast/c_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "cast.h" +#include "cast_lcl.h" +#include "cast_s.h" + +#define CAST_exp(l,A,a,n) \ + A[n/4]=l; \ + a[n+3]=(l )&0xff; \ + a[n+2]=(l>> 8)&0xff; \ + a[n+1]=(l>>16)&0xff; \ + a[n+0]=(l>>24)&0xff; + +#define S4 CAST_S_table4 +#define S5 CAST_S_table5 +#define S6 CAST_S_table6 +#define S7 CAST_S_table7 + +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) + { + CAST_LONG x[16]; + CAST_LONG z[16]; + CAST_LONG k[32]; + CAST_LONG X[4],Z[4]; + CAST_LONG l,*K; + int i; + + for (i=0; i<16; i++) x[i]=0; + if (len > 16) len=16; + for (i=0; ishort_key=1; + else + key->short_key=0; + + K= &k[0]; + X[0]=((x[ 0]<<24)|(x[ 1]<<16)|(x[ 2]<<8)|x[ 3])&0xffffffffL; + X[1]=((x[ 4]<<24)|(x[ 5]<<16)|(x[ 6]<<8)|x[ 7])&0xffffffffL; + X[2]=((x[ 8]<<24)|(x[ 9]<<16)|(x[10]<<8)|x[11])&0xffffffffL; + X[3]=((x[12]<<24)|(x[13]<<16)|(x[14]<<8)|x[15])&0xffffffffL; + + for (;;) + { + l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]]; + CAST_exp(l,Z,z, 0); + l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]]; + CAST_exp(l,Z,z, 4); + l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]]; + CAST_exp(l,Z,z, 8); + l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]]; + CAST_exp(l,Z,z,12); + + K[ 0]= S4[z[ 8]]^S5[z[ 9]]^S6[z[ 7]]^S7[z[ 6]]^S4[z[ 2]]; + K[ 1]= S4[z[10]]^S5[z[11]]^S6[z[ 5]]^S7[z[ 4]]^S5[z[ 6]]; + K[ 2]= S4[z[12]]^S5[z[13]]^S6[z[ 3]]^S7[z[ 2]]^S6[z[ 9]]; + K[ 3]= S4[z[14]]^S5[z[15]]^S6[z[ 1]]^S7[z[ 0]]^S7[z[12]]; + + l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]]; + CAST_exp(l,X,x, 0); + l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]]; + CAST_exp(l,X,x, 4); + l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]]; + CAST_exp(l,X,x, 8); + l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]]; + CAST_exp(l,X,x,12); + + K[ 4]= S4[x[ 3]]^S5[x[ 2]]^S6[x[12]]^S7[x[13]]^S4[x[ 8]]; + K[ 5]= S4[x[ 1]]^S5[x[ 0]]^S6[x[14]]^S7[x[15]]^S5[x[13]]; + K[ 6]= S4[x[ 7]]^S5[x[ 6]]^S6[x[ 8]]^S7[x[ 9]]^S6[x[ 3]]; + K[ 7]= S4[x[ 5]]^S5[x[ 4]]^S6[x[10]]^S7[x[11]]^S7[x[ 7]]; + + l=X[0]^S4[x[13]]^S5[x[15]]^S6[x[12]]^S7[x[14]]^S6[x[ 8]]; + CAST_exp(l,Z,z, 0); + l=X[2]^S4[z[ 0]]^S5[z[ 2]]^S6[z[ 1]]^S7[z[ 3]]^S7[x[10]]; + CAST_exp(l,Z,z, 4); + l=X[3]^S4[z[ 7]]^S5[z[ 6]]^S6[z[ 5]]^S7[z[ 4]]^S4[x[ 9]]; + CAST_exp(l,Z,z, 8); + l=X[1]^S4[z[10]]^S5[z[ 9]]^S6[z[11]]^S7[z[ 8]]^S5[x[11]]; + CAST_exp(l,Z,z,12); + + K[ 8]= S4[z[ 3]]^S5[z[ 2]]^S6[z[12]]^S7[z[13]]^S4[z[ 9]]; + K[ 9]= S4[z[ 1]]^S5[z[ 0]]^S6[z[14]]^S7[z[15]]^S5[z[12]]; + K[10]= S4[z[ 7]]^S5[z[ 6]]^S6[z[ 8]]^S7[z[ 9]]^S6[z[ 2]]; + K[11]= S4[z[ 5]]^S5[z[ 4]]^S6[z[10]]^S7[z[11]]^S7[z[ 6]]; + + l=Z[2]^S4[z[ 5]]^S5[z[ 7]]^S6[z[ 4]]^S7[z[ 6]]^S6[z[ 0]]; + CAST_exp(l,X,x, 0); + l=Z[0]^S4[x[ 0]]^S5[x[ 2]]^S6[x[ 1]]^S7[x[ 3]]^S7[z[ 2]]; + CAST_exp(l,X,x, 4); + l=Z[1]^S4[x[ 7]]^S5[x[ 6]]^S6[x[ 5]]^S7[x[ 4]]^S4[z[ 1]]; + CAST_exp(l,X,x, 8); + l=Z[3]^S4[x[10]]^S5[x[ 9]]^S6[x[11]]^S7[x[ 8]]^S5[z[ 3]]; + CAST_exp(l,X,x,12); + + K[12]= S4[x[ 8]]^S5[x[ 9]]^S6[x[ 7]]^S7[x[ 6]]^S4[x[ 3]]; + K[13]= S4[x[10]]^S5[x[11]]^S6[x[ 5]]^S7[x[ 4]]^S5[x[ 7]]; + K[14]= S4[x[12]]^S5[x[13]]^S6[x[ 3]]^S7[x[ 2]]^S6[x[ 8]]; + K[15]= S4[x[14]]^S5[x[15]]^S6[x[ 1]]^S7[x[ 0]]^S7[x[13]]; + if (K != k) break; + K+=16; + } + + for (i=0; i<16; i++) + { + key->data[i*2]=k[i]; + key->data[i*2+1]=((k[i+16])+16)&0x1f; + } + } + diff -urN linux-2.4.29/net/ipsec/libcrypto/libcast/cast.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/cast.h --- linux-2.4.29/net/ipsec/libcrypto/libcast/cast.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/cast.h Fri Feb 7 14:14:26 2003 @@ -0,0 +1,111 @@ +/* crypto/cast/cast.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CAST_H +#define HEADER_CAST_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NO_CAST +#error CAST is disabled. +#endif + +#define CAST_ENCRYPT 1 +#define CAST_DECRYPT 0 + +/* des.h-like hack */ +#ifndef CAST_LONG +#ifdef __KERNEL__ +#include +#else +#include +#endif +#define CAST_LONG u_int32_t +#endif + +#define CAST_BLOCK 8 +#define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st + { + CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ + } CAST_KEY; + + +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +void CAST_ecb_encrypt(const unsigned char *in,unsigned char *out,CAST_KEY *key, + int enc); +void CAST_encrypt(CAST_LONG *data,CAST_KEY *key); +void CAST_decrypt(CAST_LONG *data,CAST_KEY *key); +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + CAST_KEY *ks, unsigned char *iv, int enc); +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, CAST_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, CAST_KEY *schedule, unsigned char *ivec, + int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libcast/cast_lcl.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/cast_lcl.h --- linux-2.4.29/net/ipsec/libcrypto/libcast/cast_lcl.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/cast_lcl.h Thu Sep 5 05:48:04 2002 @@ -0,0 +1,227 @@ +/* crypto/cast/cast_lcl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifdef WIN32 +#include +#endif + + +# define OPENSSL_EXTERN extern +# define OPENSSL_GLOBAL + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#if defined(WIN32) && defined(_MSC_VER) +#define ROTL(a,n) (_lrotl(a,n)) +#else +#define ROTL(a,n) ((((a)<<(n))&0xffffffffL)|((a)>>(32-(n)))) +#endif + +#define C_M 0x3fc +#define C_0 22L +#define C_1 14L +#define C_2 6L +#define C_3 2L /* left shift */ + +/* The rotate has an extra 16 added to it to help the x86 asm */ +#if defined(CAST_PTR) +#define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + int i; \ + t=(key[n*2] OP1 R)&0xffffffffL; \ + i=key[n*2+1]; \ + t=ROTL(t,i); \ + L^= (((((*(CAST_LONG *)((unsigned char *) \ + CAST_S_table0+((t>>C_2)&C_M)) OP2 \ + *(CAST_LONG *)((unsigned char *) \ + CAST_S_table1+((t<>C_0)&C_M)))&0xffffffffL) OP1 \ + *(CAST_LONG *)((unsigned char *) \ + CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \ + } +#elif defined(CAST_PTR2) +#define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + int i; \ + CAST_LONG u,v,w; \ + w=(key[n*2] OP1 R)&0xffffffffL; \ + i=key[n*2+1]; \ + w=ROTL(w,i); \ + u=w>>C_2; \ + v=w<>C_0; \ + t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\ + v=w>>C_1; \ + u&=C_M; \ + v&=C_M; \ + t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\ + t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\ + L^=(t&0xffffffff); \ + } +#else +#define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + CAST_LONG a,b,c,d; \ + t=(key[n*2] OP1 R)&0xffffffff; \ + t=ROTL(t,(key[n*2+1])); \ + a=CAST_S_table0[(t>> 8)&0xff]; \ + b=CAST_S_table1[(t )&0xff]; \ + c=CAST_S_table2[(t>>24)&0xff]; \ + d=CAST_S_table3[(t>>16)&0xff]; \ + L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \ + } +#endif + +OPENSSL_EXTERN const CAST_LONG CAST_S_table0[256]; +OPENSSL_EXTERN const CAST_LONG CAST_S_table1[256]; +OPENSSL_EXTERN const CAST_LONG CAST_S_table2[256]; +OPENSSL_EXTERN const CAST_LONG CAST_S_table3[256]; +OPENSSL_EXTERN const CAST_LONG CAST_S_table4[256]; +OPENSSL_EXTERN const CAST_LONG CAST_S_table5[256]; +OPENSSL_EXTERN const CAST_LONG CAST_S_table6[256]; +OPENSSL_EXTERN const CAST_LONG CAST_S_table7[256]; diff -urN linux-2.4.29/net/ipsec/libcrypto/libcast/cast_s.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/cast_s.h --- linux-2.4.29/net/ipsec/libcrypto/libcast/cast_s.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libcast/cast_s.h Thu Sep 5 05:48:04 2002 @@ -0,0 +1,585 @@ +/* crypto/cast/cast_s.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +OPENSSL_GLOBAL const CAST_LONG CAST_S_table0[256]={ + 0x30fb40d4,0x9fa0ff0b,0x6beccd2f,0x3f258c7a, + 0x1e213f2f,0x9c004dd3,0x6003e540,0xcf9fc949, + 0xbfd4af27,0x88bbbdb5,0xe2034090,0x98d09675, + 0x6e63a0e0,0x15c361d2,0xc2e7661d,0x22d4ff8e, + 0x28683b6f,0xc07fd059,0xff2379c8,0x775f50e2, + 0x43c340d3,0xdf2f8656,0x887ca41a,0xa2d2bd2d, + 0xa1c9e0d6,0x346c4819,0x61b76d87,0x22540f2f, + 0x2abe32e1,0xaa54166b,0x22568e3a,0xa2d341d0, + 0x66db40c8,0xa784392f,0x004dff2f,0x2db9d2de, + 0x97943fac,0x4a97c1d8,0x527644b7,0xb5f437a7, + 0xb82cbaef,0xd751d159,0x6ff7f0ed,0x5a097a1f, + 0x827b68d0,0x90ecf52e,0x22b0c054,0xbc8e5935, + 0x4b6d2f7f,0x50bb64a2,0xd2664910,0xbee5812d, + 0xb7332290,0xe93b159f,0xb48ee411,0x4bff345d, + 0xfd45c240,0xad31973f,0xc4f6d02e,0x55fc8165, + 0xd5b1caad,0xa1ac2dae,0xa2d4b76d,0xc19b0c50, + 0x882240f2,0x0c6e4f38,0xa4e4bfd7,0x4f5ba272, + 0x564c1d2f,0xc59c5319,0xb949e354,0xb04669fe, + 0xb1b6ab8a,0xc71358dd,0x6385c545,0x110f935d, + 0x57538ad5,0x6a390493,0xe63d37e0,0x2a54f6b3, + 0x3a787d5f,0x6276a0b5,0x19a6fcdf,0x7a42206a, + 0x29f9d4d5,0xf61b1891,0xbb72275e,0xaa508167, + 0x38901091,0xc6b505eb,0x84c7cb8c,0x2ad75a0f, + 0x874a1427,0xa2d1936b,0x2ad286af,0xaa56d291, + 0xd7894360,0x425c750d,0x93b39e26,0x187184c9, + 0x6c00b32d,0x73e2bb14,0xa0bebc3c,0x54623779, + 0x64459eab,0x3f328b82,0x7718cf82,0x59a2cea6, + 0x04ee002e,0x89fe78e6,0x3fab0950,0x325ff6c2, + 0x81383f05,0x6963c5c8,0x76cb5ad6,0xd49974c9, + 0xca180dcf,0x380782d5,0xc7fa5cf6,0x8ac31511, + 0x35e79e13,0x47da91d0,0xf40f9086,0xa7e2419e, + 0x31366241,0x051ef495,0xaa573b04,0x4a805d8d, + 0x548300d0,0x00322a3c,0xbf64cddf,0xba57a68e, + 0x75c6372b,0x50afd341,0xa7c13275,0x915a0bf5, + 0x6b54bfab,0x2b0b1426,0xab4cc9d7,0x449ccd82, + 0xf7fbf265,0xab85c5f3,0x1b55db94,0xaad4e324, + 0xcfa4bd3f,0x2deaa3e2,0x9e204d02,0xc8bd25ac, + 0xeadf55b3,0xd5bd9e98,0xe31231b2,0x2ad5ad6c, + 0x954329de,0xadbe4528,0xd8710f69,0xaa51c90f, + 0xaa786bf6,0x22513f1e,0xaa51a79b,0x2ad344cc, + 0x7b5a41f0,0xd37cfbad,0x1b069505,0x41ece491, + 0xb4c332e6,0x032268d4,0xc9600acc,0xce387e6d, + 0xbf6bb16c,0x6a70fb78,0x0d03d9c9,0xd4df39de, + 0xe01063da,0x4736f464,0x5ad328d8,0xb347cc96, + 0x75bb0fc3,0x98511bfb,0x4ffbcc35,0xb58bcf6a, + 0xe11f0abc,0xbfc5fe4a,0xa70aec10,0xac39570a, + 0x3f04442f,0x6188b153,0xe0397a2e,0x5727cb79, + 0x9ceb418f,0x1cacd68d,0x2ad37c96,0x0175cb9d, + 0xc69dff09,0xc75b65f0,0xd9db40d8,0xec0e7779, + 0x4744ead4,0xb11c3274,0xdd24cb9e,0x7e1c54bd, + 0xf01144f9,0xd2240eb1,0x9675b3fd,0xa3ac3755, + 0xd47c27af,0x51c85f4d,0x56907596,0xa5bb15e6, + 0x580304f0,0xca042cf1,0x011a37ea,0x8dbfaadb, + 0x35ba3e4a,0x3526ffa0,0xc37b4d09,0xbc306ed9, + 0x98a52666,0x5648f725,0xff5e569d,0x0ced63d0, + 0x7c63b2cf,0x700b45e1,0xd5ea50f1,0x85a92872, + 0xaf1fbda7,0xd4234870,0xa7870bf3,0x2d3b4d79, + 0x42e04198,0x0cd0ede7,0x26470db8,0xf881814c, + 0x474d6ad7,0x7c0c5e5c,0xd1231959,0x381b7298, + 0xf5d2f4db,0xab838653,0x6e2f1e23,0x83719c9e, + 0xbd91e046,0x9a56456e,0xdc39200c,0x20c8c571, + 0x962bda1c,0xe1e696ff,0xb141ab08,0x7cca89b9, + 0x1a69e783,0x02cc4843,0xa2f7c579,0x429ef47d, + 0x427b169c,0x5ac9f049,0xdd8f0f00,0x5c8165bf, + }; +OPENSSL_GLOBAL const CAST_LONG CAST_S_table1[256]={ + 0x1f201094,0xef0ba75b,0x69e3cf7e,0x393f4380, + 0xfe61cf7a,0xeec5207a,0x55889c94,0x72fc0651, + 0xada7ef79,0x4e1d7235,0xd55a63ce,0xde0436ba, + 0x99c430ef,0x5f0c0794,0x18dcdb7d,0xa1d6eff3, + 0xa0b52f7b,0x59e83605,0xee15b094,0xe9ffd909, + 0xdc440086,0xef944459,0xba83ccb3,0xe0c3cdfb, + 0xd1da4181,0x3b092ab1,0xf997f1c1,0xa5e6cf7b, + 0x01420ddb,0xe4e7ef5b,0x25a1ff41,0xe180f806, + 0x1fc41080,0x179bee7a,0xd37ac6a9,0xfe5830a4, + 0x98de8b7f,0x77e83f4e,0x79929269,0x24fa9f7b, + 0xe113c85b,0xacc40083,0xd7503525,0xf7ea615f, + 0x62143154,0x0d554b63,0x5d681121,0xc866c359, + 0x3d63cf73,0xcee234c0,0xd4d87e87,0x5c672b21, + 0x071f6181,0x39f7627f,0x361e3084,0xe4eb573b, + 0x602f64a4,0xd63acd9c,0x1bbc4635,0x9e81032d, + 0x2701f50c,0x99847ab4,0xa0e3df79,0xba6cf38c, + 0x10843094,0x2537a95e,0xf46f6ffe,0xa1ff3b1f, + 0x208cfb6a,0x8f458c74,0xd9e0a227,0x4ec73a34, + 0xfc884f69,0x3e4de8df,0xef0e0088,0x3559648d, + 0x8a45388c,0x1d804366,0x721d9bfd,0xa58684bb, + 0xe8256333,0x844e8212,0x128d8098,0xfed33fb4, + 0xce280ae1,0x27e19ba5,0xd5a6c252,0xe49754bd, + 0xc5d655dd,0xeb667064,0x77840b4d,0xa1b6a801, + 0x84db26a9,0xe0b56714,0x21f043b7,0xe5d05860, + 0x54f03084,0x066ff472,0xa31aa153,0xdadc4755, + 0xb5625dbf,0x68561be6,0x83ca6b94,0x2d6ed23b, + 0xeccf01db,0xa6d3d0ba,0xb6803d5c,0xaf77a709, + 0x33b4a34c,0x397bc8d6,0x5ee22b95,0x5f0e5304, + 0x81ed6f61,0x20e74364,0xb45e1378,0xde18639b, + 0x881ca122,0xb96726d1,0x8049a7e8,0x22b7da7b, + 0x5e552d25,0x5272d237,0x79d2951c,0xc60d894c, + 0x488cb402,0x1ba4fe5b,0xa4b09f6b,0x1ca815cf, + 0xa20c3005,0x8871df63,0xb9de2fcb,0x0cc6c9e9, + 0x0beeff53,0xe3214517,0xb4542835,0x9f63293c, + 0xee41e729,0x6e1d2d7c,0x50045286,0x1e6685f3, + 0xf33401c6,0x30a22c95,0x31a70850,0x60930f13, + 0x73f98417,0xa1269859,0xec645c44,0x52c877a9, + 0xcdff33a6,0xa02b1741,0x7cbad9a2,0x2180036f, + 0x50d99c08,0xcb3f4861,0xc26bd765,0x64a3f6ab, + 0x80342676,0x25a75e7b,0xe4e6d1fc,0x20c710e6, + 0xcdf0b680,0x17844d3b,0x31eef84d,0x7e0824e4, + 0x2ccb49eb,0x846a3bae,0x8ff77888,0xee5d60f6, + 0x7af75673,0x2fdd5cdb,0xa11631c1,0x30f66f43, + 0xb3faec54,0x157fd7fa,0xef8579cc,0xd152de58, + 0xdb2ffd5e,0x8f32ce19,0x306af97a,0x02f03ef8, + 0x99319ad5,0xc242fa0f,0xa7e3ebb0,0xc68e4906, + 0xb8da230c,0x80823028,0xdcdef3c8,0xd35fb171, + 0x088a1bc8,0xbec0c560,0x61a3c9e8,0xbca8f54d, + 0xc72feffa,0x22822e99,0x82c570b4,0xd8d94e89, + 0x8b1c34bc,0x301e16e6,0x273be979,0xb0ffeaa6, + 0x61d9b8c6,0x00b24869,0xb7ffce3f,0x08dc283b, + 0x43daf65a,0xf7e19798,0x7619b72f,0x8f1c9ba4, + 0xdc8637a0,0x16a7d3b1,0x9fc393b7,0xa7136eeb, + 0xc6bcc63e,0x1a513742,0xef6828bc,0x520365d6, + 0x2d6a77ab,0x3527ed4b,0x821fd216,0x095c6e2e, + 0xdb92f2fb,0x5eea29cb,0x145892f5,0x91584f7f, + 0x5483697b,0x2667a8cc,0x85196048,0x8c4bacea, + 0x833860d4,0x0d23e0f9,0x6c387e8a,0x0ae6d249, + 0xb284600c,0xd835731d,0xdcb1c647,0xac4c56ea, + 0x3ebd81b3,0x230eabb0,0x6438bc87,0xf0b5b1fa, + 0x8f5ea2b3,0xfc184642,0x0a036b7a,0x4fb089bd, + 0x649da589,0xa345415e,0x5c038323,0x3e5d3bb9, + 0x43d79572,0x7e6dd07c,0x06dfdf1e,0x6c6cc4ef, + 0x7160a539,0x73bfbe70,0x83877605,0x4523ecf1, + }; +OPENSSL_GLOBAL const CAST_LONG CAST_S_table2[256]={ + 0x8defc240,0x25fa5d9f,0xeb903dbf,0xe810c907, + 0x47607fff,0x369fe44b,0x8c1fc644,0xaececa90, + 0xbeb1f9bf,0xeefbcaea,0xe8cf1950,0x51df07ae, + 0x920e8806,0xf0ad0548,0xe13c8d83,0x927010d5, + 0x11107d9f,0x07647db9,0xb2e3e4d4,0x3d4f285e, + 0xb9afa820,0xfade82e0,0xa067268b,0x8272792e, + 0x553fb2c0,0x489ae22b,0xd4ef9794,0x125e3fbc, + 0x21fffcee,0x825b1bfd,0x9255c5ed,0x1257a240, + 0x4e1a8302,0xbae07fff,0x528246e7,0x8e57140e, + 0x3373f7bf,0x8c9f8188,0xa6fc4ee8,0xc982b5a5, + 0xa8c01db7,0x579fc264,0x67094f31,0xf2bd3f5f, + 0x40fff7c1,0x1fb78dfc,0x8e6bd2c1,0x437be59b, + 0x99b03dbf,0xb5dbc64b,0x638dc0e6,0x55819d99, + 0xa197c81c,0x4a012d6e,0xc5884a28,0xccc36f71, + 0xb843c213,0x6c0743f1,0x8309893c,0x0feddd5f, + 0x2f7fe850,0xd7c07f7e,0x02507fbf,0x5afb9a04, + 0xa747d2d0,0x1651192e,0xaf70bf3e,0x58c31380, + 0x5f98302e,0x727cc3c4,0x0a0fb402,0x0f7fef82, + 0x8c96fdad,0x5d2c2aae,0x8ee99a49,0x50da88b8, + 0x8427f4a0,0x1eac5790,0x796fb449,0x8252dc15, + 0xefbd7d9b,0xa672597d,0xada840d8,0x45f54504, + 0xfa5d7403,0xe83ec305,0x4f91751a,0x925669c2, + 0x23efe941,0xa903f12e,0x60270df2,0x0276e4b6, + 0x94fd6574,0x927985b2,0x8276dbcb,0x02778176, + 0xf8af918d,0x4e48f79e,0x8f616ddf,0xe29d840e, + 0x842f7d83,0x340ce5c8,0x96bbb682,0x93b4b148, + 0xef303cab,0x984faf28,0x779faf9b,0x92dc560d, + 0x224d1e20,0x8437aa88,0x7d29dc96,0x2756d3dc, + 0x8b907cee,0xb51fd240,0xe7c07ce3,0xe566b4a1, + 0xc3e9615e,0x3cf8209d,0x6094d1e3,0xcd9ca341, + 0x5c76460e,0x00ea983b,0xd4d67881,0xfd47572c, + 0xf76cedd9,0xbda8229c,0x127dadaa,0x438a074e, + 0x1f97c090,0x081bdb8a,0x93a07ebe,0xb938ca15, + 0x97b03cff,0x3dc2c0f8,0x8d1ab2ec,0x64380e51, + 0x68cc7bfb,0xd90f2788,0x12490181,0x5de5ffd4, + 0xdd7ef86a,0x76a2e214,0xb9a40368,0x925d958f, + 0x4b39fffa,0xba39aee9,0xa4ffd30b,0xfaf7933b, + 0x6d498623,0x193cbcfa,0x27627545,0x825cf47a, + 0x61bd8ba0,0xd11e42d1,0xcead04f4,0x127ea392, + 0x10428db7,0x8272a972,0x9270c4a8,0x127de50b, + 0x285ba1c8,0x3c62f44f,0x35c0eaa5,0xe805d231, + 0x428929fb,0xb4fcdf82,0x4fb66a53,0x0e7dc15b, + 0x1f081fab,0x108618ae,0xfcfd086d,0xf9ff2889, + 0x694bcc11,0x236a5cae,0x12deca4d,0x2c3f8cc5, + 0xd2d02dfe,0xf8ef5896,0xe4cf52da,0x95155b67, + 0x494a488c,0xb9b6a80c,0x5c8f82bc,0x89d36b45, + 0x3a609437,0xec00c9a9,0x44715253,0x0a874b49, + 0xd773bc40,0x7c34671c,0x02717ef6,0x4feb5536, + 0xa2d02fff,0xd2bf60c4,0xd43f03c0,0x50b4ef6d, + 0x07478cd1,0x006e1888,0xa2e53f55,0xb9e6d4bc, + 0xa2048016,0x97573833,0xd7207d67,0xde0f8f3d, + 0x72f87b33,0xabcc4f33,0x7688c55d,0x7b00a6b0, + 0x947b0001,0x570075d2,0xf9bb88f8,0x8942019e, + 0x4264a5ff,0x856302e0,0x72dbd92b,0xee971b69, + 0x6ea22fde,0x5f08ae2b,0xaf7a616d,0xe5c98767, + 0xcf1febd2,0x61efc8c2,0xf1ac2571,0xcc8239c2, + 0x67214cb8,0xb1e583d1,0xb7dc3e62,0x7f10bdce, + 0xf90a5c38,0x0ff0443d,0x606e6dc6,0x60543a49, + 0x5727c148,0x2be98a1d,0x8ab41738,0x20e1be24, + 0xaf96da0f,0x68458425,0x99833be5,0x600d457d, + 0x282f9350,0x8334b362,0xd91d1120,0x2b6d8da0, + 0x642b1e31,0x9c305a00,0x52bce688,0x1b03588a, + 0xf7baefd5,0x4142ed9c,0xa4315c11,0x83323ec5, + 0xdfef4636,0xa133c501,0xe9d3531c,0xee353783, + }; +OPENSSL_GLOBAL const CAST_LONG CAST_S_table3[256]={ + 0x9db30420,0x1fb6e9de,0xa7be7bef,0xd273a298, + 0x4a4f7bdb,0x64ad8c57,0x85510443,0xfa020ed1, + 0x7e287aff,0xe60fb663,0x095f35a1,0x79ebf120, + 0xfd059d43,0x6497b7b1,0xf3641f63,0x241e4adf, + 0x28147f5f,0x4fa2b8cd,0xc9430040,0x0cc32220, + 0xfdd30b30,0xc0a5374f,0x1d2d00d9,0x24147b15, + 0xee4d111a,0x0fca5167,0x71ff904c,0x2d195ffe, + 0x1a05645f,0x0c13fefe,0x081b08ca,0x05170121, + 0x80530100,0xe83e5efe,0xac9af4f8,0x7fe72701, + 0xd2b8ee5f,0x06df4261,0xbb9e9b8a,0x7293ea25, + 0xce84ffdf,0xf5718801,0x3dd64b04,0xa26f263b, + 0x7ed48400,0x547eebe6,0x446d4ca0,0x6cf3d6f5, + 0x2649abdf,0xaea0c7f5,0x36338cc1,0x503f7e93, + 0xd3772061,0x11b638e1,0x72500e03,0xf80eb2bb, + 0xabe0502e,0xec8d77de,0x57971e81,0xe14f6746, + 0xc9335400,0x6920318f,0x081dbb99,0xffc304a5, + 0x4d351805,0x7f3d5ce3,0xa6c866c6,0x5d5bcca9, + 0xdaec6fea,0x9f926f91,0x9f46222f,0x3991467d, + 0xa5bf6d8e,0x1143c44f,0x43958302,0xd0214eeb, + 0x022083b8,0x3fb6180c,0x18f8931e,0x281658e6, + 0x26486e3e,0x8bd78a70,0x7477e4c1,0xb506e07c, + 0xf32d0a25,0x79098b02,0xe4eabb81,0x28123b23, + 0x69dead38,0x1574ca16,0xdf871b62,0x211c40b7, + 0xa51a9ef9,0x0014377b,0x041e8ac8,0x09114003, + 0xbd59e4d2,0xe3d156d5,0x4fe876d5,0x2f91a340, + 0x557be8de,0x00eae4a7,0x0ce5c2ec,0x4db4bba6, + 0xe756bdff,0xdd3369ac,0xec17b035,0x06572327, + 0x99afc8b0,0x56c8c391,0x6b65811c,0x5e146119, + 0x6e85cb75,0xbe07c002,0xc2325577,0x893ff4ec, + 0x5bbfc92d,0xd0ec3b25,0xb7801ab7,0x8d6d3b24, + 0x20c763ef,0xc366a5fc,0x9c382880,0x0ace3205, + 0xaac9548a,0xeca1d7c7,0x041afa32,0x1d16625a, + 0x6701902c,0x9b757a54,0x31d477f7,0x9126b031, + 0x36cc6fdb,0xc70b8b46,0xd9e66a48,0x56e55a79, + 0x026a4ceb,0x52437eff,0x2f8f76b4,0x0df980a5, + 0x8674cde3,0xedda04eb,0x17a9be04,0x2c18f4df, + 0xb7747f9d,0xab2af7b4,0xefc34d20,0x2e096b7c, + 0x1741a254,0xe5b6a035,0x213d42f6,0x2c1c7c26, + 0x61c2f50f,0x6552daf9,0xd2c231f8,0x25130f69, + 0xd8167fa2,0x0418f2c8,0x001a96a6,0x0d1526ab, + 0x63315c21,0x5e0a72ec,0x49bafefd,0x187908d9, + 0x8d0dbd86,0x311170a7,0x3e9b640c,0xcc3e10d7, + 0xd5cad3b6,0x0caec388,0xf73001e1,0x6c728aff, + 0x71eae2a1,0x1f9af36e,0xcfcbd12f,0xc1de8417, + 0xac07be6b,0xcb44a1d8,0x8b9b0f56,0x013988c3, + 0xb1c52fca,0xb4be31cd,0xd8782806,0x12a3a4e2, + 0x6f7de532,0x58fd7eb6,0xd01ee900,0x24adffc2, + 0xf4990fc5,0x9711aac5,0x001d7b95,0x82e5e7d2, + 0x109873f6,0x00613096,0xc32d9521,0xada121ff, + 0x29908415,0x7fbb977f,0xaf9eb3db,0x29c9ed2a, + 0x5ce2a465,0xa730f32c,0xd0aa3fe8,0x8a5cc091, + 0xd49e2ce7,0x0ce454a9,0xd60acd86,0x015f1919, + 0x77079103,0xdea03af6,0x78a8565e,0xdee356df, + 0x21f05cbe,0x8b75e387,0xb3c50651,0xb8a5c3ef, + 0xd8eeb6d2,0xe523be77,0xc2154529,0x2f69efdf, + 0xafe67afb,0xf470c4b2,0xf3e0eb5b,0xd6cc9876, + 0x39e4460c,0x1fda8538,0x1987832f,0xca007367, + 0xa99144f8,0x296b299e,0x492fc295,0x9266beab, + 0xb5676e69,0x9bd3ddda,0xdf7e052f,0xdb25701c, + 0x1b5e51ee,0xf65324e6,0x6afce36c,0x0316cc04, + 0x8644213e,0xb7dc59d0,0x7965291f,0xccd6fd43, + 0x41823979,0x932bcdf6,0xb657c34d,0x4edfd282, + 0x7ae5290c,0x3cb9536b,0x851e20fe,0x9833557e, + 0x13ecf0b0,0xd3ffb372,0x3f85c5c1,0x0aef7ed2, + }; +OPENSSL_GLOBAL const CAST_LONG CAST_S_table4[256]={ + 0x7ec90c04,0x2c6e74b9,0x9b0e66df,0xa6337911, + 0xb86a7fff,0x1dd358f5,0x44dd9d44,0x1731167f, + 0x08fbf1fa,0xe7f511cc,0xd2051b00,0x735aba00, + 0x2ab722d8,0x386381cb,0xacf6243a,0x69befd7a, + 0xe6a2e77f,0xf0c720cd,0xc4494816,0xccf5c180, + 0x38851640,0x15b0a848,0xe68b18cb,0x4caadeff, + 0x5f480a01,0x0412b2aa,0x259814fc,0x41d0efe2, + 0x4e40b48d,0x248eb6fb,0x8dba1cfe,0x41a99b02, + 0x1a550a04,0xba8f65cb,0x7251f4e7,0x95a51725, + 0xc106ecd7,0x97a5980a,0xc539b9aa,0x4d79fe6a, + 0xf2f3f763,0x68af8040,0xed0c9e56,0x11b4958b, + 0xe1eb5a88,0x8709e6b0,0xd7e07156,0x4e29fea7, + 0x6366e52d,0x02d1c000,0xc4ac8e05,0x9377f571, + 0x0c05372a,0x578535f2,0x2261be02,0xd642a0c9, + 0xdf13a280,0x74b55bd2,0x682199c0,0xd421e5ec, + 0x53fb3ce8,0xc8adedb3,0x28a87fc9,0x3d959981, + 0x5c1ff900,0xfe38d399,0x0c4eff0b,0x062407ea, + 0xaa2f4fb1,0x4fb96976,0x90c79505,0xb0a8a774, + 0xef55a1ff,0xe59ca2c2,0xa6b62d27,0xe66a4263, + 0xdf65001f,0x0ec50966,0xdfdd55bc,0x29de0655, + 0x911e739a,0x17af8975,0x32c7911c,0x89f89468, + 0x0d01e980,0x524755f4,0x03b63cc9,0x0cc844b2, + 0xbcf3f0aa,0x87ac36e9,0xe53a7426,0x01b3d82b, + 0x1a9e7449,0x64ee2d7e,0xcddbb1da,0x01c94910, + 0xb868bf80,0x0d26f3fd,0x9342ede7,0x04a5c284, + 0x636737b6,0x50f5b616,0xf24766e3,0x8eca36c1, + 0x136e05db,0xfef18391,0xfb887a37,0xd6e7f7d4, + 0xc7fb7dc9,0x3063fcdf,0xb6f589de,0xec2941da, + 0x26e46695,0xb7566419,0xf654efc5,0xd08d58b7, + 0x48925401,0xc1bacb7f,0xe5ff550f,0xb6083049, + 0x5bb5d0e8,0x87d72e5a,0xab6a6ee1,0x223a66ce, + 0xc62bf3cd,0x9e0885f9,0x68cb3e47,0x086c010f, + 0xa21de820,0xd18b69de,0xf3f65777,0xfa02c3f6, + 0x407edac3,0xcbb3d550,0x1793084d,0xb0d70eba, + 0x0ab378d5,0xd951fb0c,0xded7da56,0x4124bbe4, + 0x94ca0b56,0x0f5755d1,0xe0e1e56e,0x6184b5be, + 0x580a249f,0x94f74bc0,0xe327888e,0x9f7b5561, + 0xc3dc0280,0x05687715,0x646c6bd7,0x44904db3, + 0x66b4f0a3,0xc0f1648a,0x697ed5af,0x49e92ff6, + 0x309e374f,0x2cb6356a,0x85808573,0x4991f840, + 0x76f0ae02,0x083be84d,0x28421c9a,0x44489406, + 0x736e4cb8,0xc1092910,0x8bc95fc6,0x7d869cf4, + 0x134f616f,0x2e77118d,0xb31b2be1,0xaa90b472, + 0x3ca5d717,0x7d161bba,0x9cad9010,0xaf462ba2, + 0x9fe459d2,0x45d34559,0xd9f2da13,0xdbc65487, + 0xf3e4f94e,0x176d486f,0x097c13ea,0x631da5c7, + 0x445f7382,0x175683f4,0xcdc66a97,0x70be0288, + 0xb3cdcf72,0x6e5dd2f3,0x20936079,0x459b80a5, + 0xbe60e2db,0xa9c23101,0xeba5315c,0x224e42f2, + 0x1c5c1572,0xf6721b2c,0x1ad2fff3,0x8c25404e, + 0x324ed72f,0x4067b7fd,0x0523138e,0x5ca3bc78, + 0xdc0fd66e,0x75922283,0x784d6b17,0x58ebb16e, + 0x44094f85,0x3f481d87,0xfcfeae7b,0x77b5ff76, + 0x8c2302bf,0xaaf47556,0x5f46b02a,0x2b092801, + 0x3d38f5f7,0x0ca81f36,0x52af4a8a,0x66d5e7c0, + 0xdf3b0874,0x95055110,0x1b5ad7a8,0xf61ed5ad, + 0x6cf6e479,0x20758184,0xd0cefa65,0x88f7be58, + 0x4a046826,0x0ff6f8f3,0xa09c7f70,0x5346aba0, + 0x5ce96c28,0xe176eda3,0x6bac307f,0x376829d2, + 0x85360fa9,0x17e3fe2a,0x24b79767,0xf5a96b20, + 0xd6cd2595,0x68ff1ebf,0x7555442c,0xf19f06be, + 0xf9e0659a,0xeeb9491d,0x34010718,0xbb30cab8, + 0xe822fe15,0x88570983,0x750e6249,0xda627e55, + 0x5e76ffa8,0xb1534546,0x6d47de08,0xefe9e7d4, + }; +OPENSSL_GLOBAL const CAST_LONG CAST_S_table5[256]={ + 0xf6fa8f9d,0x2cac6ce1,0x4ca34867,0xe2337f7c, + 0x95db08e7,0x016843b4,0xeced5cbc,0x325553ac, + 0xbf9f0960,0xdfa1e2ed,0x83f0579d,0x63ed86b9, + 0x1ab6a6b8,0xde5ebe39,0xf38ff732,0x8989b138, + 0x33f14961,0xc01937bd,0xf506c6da,0xe4625e7e, + 0xa308ea99,0x4e23e33c,0x79cbd7cc,0x48a14367, + 0xa3149619,0xfec94bd5,0xa114174a,0xeaa01866, + 0xa084db2d,0x09a8486f,0xa888614a,0x2900af98, + 0x01665991,0xe1992863,0xc8f30c60,0x2e78ef3c, + 0xd0d51932,0xcf0fec14,0xf7ca07d2,0xd0a82072, + 0xfd41197e,0x9305a6b0,0xe86be3da,0x74bed3cd, + 0x372da53c,0x4c7f4448,0xdab5d440,0x6dba0ec3, + 0x083919a7,0x9fbaeed9,0x49dbcfb0,0x4e670c53, + 0x5c3d9c01,0x64bdb941,0x2c0e636a,0xba7dd9cd, + 0xea6f7388,0xe70bc762,0x35f29adb,0x5c4cdd8d, + 0xf0d48d8c,0xb88153e2,0x08a19866,0x1ae2eac8, + 0x284caf89,0xaa928223,0x9334be53,0x3b3a21bf, + 0x16434be3,0x9aea3906,0xefe8c36e,0xf890cdd9, + 0x80226dae,0xc340a4a3,0xdf7e9c09,0xa694a807, + 0x5b7c5ecc,0x221db3a6,0x9a69a02f,0x68818a54, + 0xceb2296f,0x53c0843a,0xfe893655,0x25bfe68a, + 0xb4628abc,0xcf222ebf,0x25ac6f48,0xa9a99387, + 0x53bddb65,0xe76ffbe7,0xe967fd78,0x0ba93563, + 0x8e342bc1,0xe8a11be9,0x4980740d,0xc8087dfc, + 0x8de4bf99,0xa11101a0,0x7fd37975,0xda5a26c0, + 0xe81f994f,0x9528cd89,0xfd339fed,0xb87834bf, + 0x5f04456d,0x22258698,0xc9c4c83b,0x2dc156be, + 0x4f628daa,0x57f55ec5,0xe2220abe,0xd2916ebf, + 0x4ec75b95,0x24f2c3c0,0x42d15d99,0xcd0d7fa0, + 0x7b6e27ff,0xa8dc8af0,0x7345c106,0xf41e232f, + 0x35162386,0xe6ea8926,0x3333b094,0x157ec6f2, + 0x372b74af,0x692573e4,0xe9a9d848,0xf3160289, + 0x3a62ef1d,0xa787e238,0xf3a5f676,0x74364853, + 0x20951063,0x4576698d,0xb6fad407,0x592af950, + 0x36f73523,0x4cfb6e87,0x7da4cec0,0x6c152daa, + 0xcb0396a8,0xc50dfe5d,0xfcd707ab,0x0921c42f, + 0x89dff0bb,0x5fe2be78,0x448f4f33,0x754613c9, + 0x2b05d08d,0x48b9d585,0xdc049441,0xc8098f9b, + 0x7dede786,0xc39a3373,0x42410005,0x6a091751, + 0x0ef3c8a6,0x890072d6,0x28207682,0xa9a9f7be, + 0xbf32679d,0xd45b5b75,0xb353fd00,0xcbb0e358, + 0x830f220a,0x1f8fb214,0xd372cf08,0xcc3c4a13, + 0x8cf63166,0x061c87be,0x88c98f88,0x6062e397, + 0x47cf8e7a,0xb6c85283,0x3cc2acfb,0x3fc06976, + 0x4e8f0252,0x64d8314d,0xda3870e3,0x1e665459, + 0xc10908f0,0x513021a5,0x6c5b68b7,0x822f8aa0, + 0x3007cd3e,0x74719eef,0xdc872681,0x073340d4, + 0x7e432fd9,0x0c5ec241,0x8809286c,0xf592d891, + 0x08a930f6,0x957ef305,0xb7fbffbd,0xc266e96f, + 0x6fe4ac98,0xb173ecc0,0xbc60b42a,0x953498da, + 0xfba1ae12,0x2d4bd736,0x0f25faab,0xa4f3fceb, + 0xe2969123,0x257f0c3d,0x9348af49,0x361400bc, + 0xe8816f4a,0x3814f200,0xa3f94043,0x9c7a54c2, + 0xbc704f57,0xda41e7f9,0xc25ad33a,0x54f4a084, + 0xb17f5505,0x59357cbe,0xedbd15c8,0x7f97c5ab, + 0xba5ac7b5,0xb6f6deaf,0x3a479c3a,0x5302da25, + 0x653d7e6a,0x54268d49,0x51a477ea,0x5017d55b, + 0xd7d25d88,0x44136c76,0x0404a8c8,0xb8e5a121, + 0xb81a928a,0x60ed5869,0x97c55b96,0xeaec991b, + 0x29935913,0x01fdb7f1,0x088e8dfa,0x9ab6f6f5, + 0x3b4cbf9f,0x4a5de3ab,0xe6051d35,0xa0e1d855, + 0xd36b4cf1,0xf544edeb,0xb0e93524,0xbebb8fbd, + 0xa2d762cf,0x49c92f54,0x38b5f331,0x7128a454, + 0x48392905,0xa65b1db8,0x851c97bd,0xd675cf2f, + }; +OPENSSL_GLOBAL const CAST_LONG CAST_S_table6[256]={ + 0x85e04019,0x332bf567,0x662dbfff,0xcfc65693, + 0x2a8d7f6f,0xab9bc912,0xde6008a1,0x2028da1f, + 0x0227bce7,0x4d642916,0x18fac300,0x50f18b82, + 0x2cb2cb11,0xb232e75c,0x4b3695f2,0xb28707de, + 0xa05fbcf6,0xcd4181e9,0xe150210c,0xe24ef1bd, + 0xb168c381,0xfde4e789,0x5c79b0d8,0x1e8bfd43, + 0x4d495001,0x38be4341,0x913cee1d,0x92a79c3f, + 0x089766be,0xbaeeadf4,0x1286becf,0xb6eacb19, + 0x2660c200,0x7565bde4,0x64241f7a,0x8248dca9, + 0xc3b3ad66,0x28136086,0x0bd8dfa8,0x356d1cf2, + 0x107789be,0xb3b2e9ce,0x0502aa8f,0x0bc0351e, + 0x166bf52a,0xeb12ff82,0xe3486911,0xd34d7516, + 0x4e7b3aff,0x5f43671b,0x9cf6e037,0x4981ac83, + 0x334266ce,0x8c9341b7,0xd0d854c0,0xcb3a6c88, + 0x47bc2829,0x4725ba37,0xa66ad22b,0x7ad61f1e, + 0x0c5cbafa,0x4437f107,0xb6e79962,0x42d2d816, + 0x0a961288,0xe1a5c06e,0x13749e67,0x72fc081a, + 0xb1d139f7,0xf9583745,0xcf19df58,0xbec3f756, + 0xc06eba30,0x07211b24,0x45c28829,0xc95e317f, + 0xbc8ec511,0x38bc46e9,0xc6e6fa14,0xbae8584a, + 0xad4ebc46,0x468f508b,0x7829435f,0xf124183b, + 0x821dba9f,0xaff60ff4,0xea2c4e6d,0x16e39264, + 0x92544a8b,0x009b4fc3,0xaba68ced,0x9ac96f78, + 0x06a5b79a,0xb2856e6e,0x1aec3ca9,0xbe838688, + 0x0e0804e9,0x55f1be56,0xe7e5363b,0xb3a1f25d, + 0xf7debb85,0x61fe033c,0x16746233,0x3c034c28, + 0xda6d0c74,0x79aac56c,0x3ce4e1ad,0x51f0c802, + 0x98f8f35a,0x1626a49f,0xeed82b29,0x1d382fe3, + 0x0c4fb99a,0xbb325778,0x3ec6d97b,0x6e77a6a9, + 0xcb658b5c,0xd45230c7,0x2bd1408b,0x60c03eb7, + 0xb9068d78,0xa33754f4,0xf430c87d,0xc8a71302, + 0xb96d8c32,0xebd4e7be,0xbe8b9d2d,0x7979fb06, + 0xe7225308,0x8b75cf77,0x11ef8da4,0xe083c858, + 0x8d6b786f,0x5a6317a6,0xfa5cf7a0,0x5dda0033, + 0xf28ebfb0,0xf5b9c310,0xa0eac280,0x08b9767a, + 0xa3d9d2b0,0x79d34217,0x021a718d,0x9ac6336a, + 0x2711fd60,0x438050e3,0x069908a8,0x3d7fedc4, + 0x826d2bef,0x4eeb8476,0x488dcf25,0x36c9d566, + 0x28e74e41,0xc2610aca,0x3d49a9cf,0xbae3b9df, + 0xb65f8de6,0x92aeaf64,0x3ac7d5e6,0x9ea80509, + 0xf22b017d,0xa4173f70,0xdd1e16c3,0x15e0d7f9, + 0x50b1b887,0x2b9f4fd5,0x625aba82,0x6a017962, + 0x2ec01b9c,0x15488aa9,0xd716e740,0x40055a2c, + 0x93d29a22,0xe32dbf9a,0x058745b9,0x3453dc1e, + 0xd699296e,0x496cff6f,0x1c9f4986,0xdfe2ed07, + 0xb87242d1,0x19de7eae,0x053e561a,0x15ad6f8c, + 0x66626c1c,0x7154c24c,0xea082b2a,0x93eb2939, + 0x17dcb0f0,0x58d4f2ae,0x9ea294fb,0x52cf564c, + 0x9883fe66,0x2ec40581,0x763953c3,0x01d6692e, + 0xd3a0c108,0xa1e7160e,0xe4f2dfa6,0x693ed285, + 0x74904698,0x4c2b0edd,0x4f757656,0x5d393378, + 0xa132234f,0x3d321c5d,0xc3f5e194,0x4b269301, + 0xc79f022f,0x3c997e7e,0x5e4f9504,0x3ffafbbd, + 0x76f7ad0e,0x296693f4,0x3d1fce6f,0xc61e45be, + 0xd3b5ab34,0xf72bf9b7,0x1b0434c0,0x4e72b567, + 0x5592a33d,0xb5229301,0xcfd2a87f,0x60aeb767, + 0x1814386b,0x30bcc33d,0x38a0c07d,0xfd1606f2, + 0xc363519b,0x589dd390,0x5479f8e6,0x1cb8d647, + 0x97fd61a9,0xea7759f4,0x2d57539d,0x569a58cf, + 0xe84e63ad,0x462e1b78,0x6580f87e,0xf3817914, + 0x91da55f4,0x40a230f3,0xd1988f35,0xb6e318d2, + 0x3ffa50bc,0x3d40f021,0xc3c0bdae,0x4958c24c, + 0x518f36b2,0x84b1d370,0x0fedce83,0x878ddada, + 0xf2a279c7,0x94e01be8,0x90716f4b,0x954b8aa3, + }; +OPENSSL_GLOBAL const CAST_LONG CAST_S_table7[256]={ + 0xe216300d,0xbbddfffc,0xa7ebdabd,0x35648095, + 0x7789f8b7,0xe6c1121b,0x0e241600,0x052ce8b5, + 0x11a9cfb0,0xe5952f11,0xece7990a,0x9386d174, + 0x2a42931c,0x76e38111,0xb12def3a,0x37ddddfc, + 0xde9adeb1,0x0a0cc32c,0xbe197029,0x84a00940, + 0xbb243a0f,0xb4d137cf,0xb44e79f0,0x049eedfd, + 0x0b15a15d,0x480d3168,0x8bbbde5a,0x669ded42, + 0xc7ece831,0x3f8f95e7,0x72df191b,0x7580330d, + 0x94074251,0x5c7dcdfa,0xabbe6d63,0xaa402164, + 0xb301d40a,0x02e7d1ca,0x53571dae,0x7a3182a2, + 0x12a8ddec,0xfdaa335d,0x176f43e8,0x71fb46d4, + 0x38129022,0xce949ad4,0xb84769ad,0x965bd862, + 0x82f3d055,0x66fb9767,0x15b80b4e,0x1d5b47a0, + 0x4cfde06f,0xc28ec4b8,0x57e8726e,0x647a78fc, + 0x99865d44,0x608bd593,0x6c200e03,0x39dc5ff6, + 0x5d0b00a3,0xae63aff2,0x7e8bd632,0x70108c0c, + 0xbbd35049,0x2998df04,0x980cf42a,0x9b6df491, + 0x9e7edd53,0x06918548,0x58cb7e07,0x3b74ef2e, + 0x522fffb1,0xd24708cc,0x1c7e27cd,0xa4eb215b, + 0x3cf1d2e2,0x19b47a38,0x424f7618,0x35856039, + 0x9d17dee7,0x27eb35e6,0xc9aff67b,0x36baf5b8, + 0x09c467cd,0xc18910b1,0xe11dbf7b,0x06cd1af8, + 0x7170c608,0x2d5e3354,0xd4de495a,0x64c6d006, + 0xbcc0c62c,0x3dd00db3,0x708f8f34,0x77d51b42, + 0x264f620f,0x24b8d2bf,0x15c1b79e,0x46a52564, + 0xf8d7e54e,0x3e378160,0x7895cda5,0x859c15a5, + 0xe6459788,0xc37bc75f,0xdb07ba0c,0x0676a3ab, + 0x7f229b1e,0x31842e7b,0x24259fd7,0xf8bef472, + 0x835ffcb8,0x6df4c1f2,0x96f5b195,0xfd0af0fc, + 0xb0fe134c,0xe2506d3d,0x4f9b12ea,0xf215f225, + 0xa223736f,0x9fb4c428,0x25d04979,0x34c713f8, + 0xc4618187,0xea7a6e98,0x7cd16efc,0x1436876c, + 0xf1544107,0xbedeee14,0x56e9af27,0xa04aa441, + 0x3cf7c899,0x92ecbae6,0xdd67016d,0x151682eb, + 0xa842eedf,0xfdba60b4,0xf1907b75,0x20e3030f, + 0x24d8c29e,0xe139673b,0xefa63fb8,0x71873054, + 0xb6f2cf3b,0x9f326442,0xcb15a4cc,0xb01a4504, + 0xf1e47d8d,0x844a1be5,0xbae7dfdc,0x42cbda70, + 0xcd7dae0a,0x57e85b7a,0xd53f5af6,0x20cf4d8c, + 0xcea4d428,0x79d130a4,0x3486ebfb,0x33d3cddc, + 0x77853b53,0x37effcb5,0xc5068778,0xe580b3e6, + 0x4e68b8f4,0xc5c8b37e,0x0d809ea2,0x398feb7c, + 0x132a4f94,0x43b7950e,0x2fee7d1c,0x223613bd, + 0xdd06caa2,0x37df932b,0xc4248289,0xacf3ebc3, + 0x5715f6b7,0xef3478dd,0xf267616f,0xc148cbe4, + 0x9052815e,0x5e410fab,0xb48a2465,0x2eda7fa4, + 0xe87b40e4,0xe98ea084,0x5889e9e1,0xefd390fc, + 0xdd07d35b,0xdb485694,0x38d7e5b2,0x57720101, + 0x730edebc,0x5b643113,0x94917e4f,0x503c2fba, + 0x646f1282,0x7523d24a,0xe0779695,0xf9c17a8f, + 0x7a5b2121,0xd187b896,0x29263a4d,0xba510cdf, + 0x81f47c9f,0xad1163ed,0xea7b5965,0x1a00726e, + 0x11403092,0x00da6d77,0x4a0cdd61,0xad1f4603, + 0x605bdfb0,0x9eedc364,0x22ebe6a8,0xcee7d28a, + 0xa0e736a0,0x5564a6b9,0x10853209,0xc7eb8f37, + 0x2de705ca,0x8951570f,0xdf09822b,0xbd691a6c, + 0xaa12e4f2,0x87451c0f,0xe0f6a27a,0x3ada4819, + 0x4cf1764f,0x0d771c2b,0x67cdb156,0x350d8384, + 0x5938fa0f,0x42399ef3,0x36997b07,0x0e84093d, + 0x4aa93e61,0x8360d87b,0x1fa98b0c,0x1149382c, + 0xe97625a5,0x0614d1b7,0x0e25244b,0x0c768347, + 0x589e8d82,0x0d2059d1,0xa466bb1e,0xf8da0a82, + 0x04f19130,0xba6e4ec0,0x99265164,0x1ee7230d, + 0x50b2ad80,0xeaee6801,0x8db2a283,0xea8bf59e, + }; diff -urN linux-2.4.29/net/ipsec/libcrypto/libmd5/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/Makefile --- linux-2.4.29/net/ipsec/libcrypto/libmd5/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/Makefile Thu Sep 5 05:31:27 2002 @@ -0,0 +1,136 @@ +# +# SSLeay/crypto/md5/Makefile +# + +DIR= md5 +TOP= ../.. +CC= cc +CPP= $(CC) -E +INCLUDES= +CFLAG=-g -I ../include -D__KERNEL__ -I/usr/src/linux/include +INSTALL_PREFIX= +OPENSSLDIR= /usr/local/ssl +INSTALLTOP=/usr/local/ssl +MAKE= make -f Makefile.ssl +MAKEDEPEND= $(TOP)/util/domd $(TOP) +MAKEFILE= Makefile.ssl +AR= ar r +RANLIB= ranlib +PERL= perl + +CFLAGS= $(INCLUDES) $(CFLAG) + +ASM-$(ARCH_ASM):=1 +ASM_X86=$(ASM-i586)$(ASM-i686) +ifneq ($(strip $(ASM_X86)),) +MD5_ASM_OBJ:=asm/mx86-elf.o +override CFLAGS += -DMD5_ASM +endif +# We let the C compiler driver to take care of .s files. This is done in +# order to be excused from maintaining a separate set of architecture +# dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC +# gcc, then the driver will automatically translate it to -xarch=v8plus +# and pass it down to assembler. +AS=$(CC) -c +ASFLAGS=$(CFLAGS) + +GENERAL=Makefile +TEST=md5test.c +APPS= + +LIB=libmd5.a +LIBSRC=md5_dgst.c md5_one.c hmac_md5.c +LIBOBJ=md5_dgst.o md5_one.o $(MD5_ASM_OBJ) hmac_md5.o + +SRC= $(LIBSRC) + +EXHEADER= md5.h +HEADER= md5_locl.h $(EXHEADER) + +ALL= $(GENERAL) $(SRC) $(HEADER) + +#top: +# (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all) + +all: lib + +lib: $(LIB) + +$(LIB): $(LIBOBJ) + $(AR) $(LIB) $(LIBOBJ) + $(RANLIB) $(LIB) + +# elf +asm/mx86-elf.o: asm/mx86unix.cpp + $(CPP) -DELF -x c asm/mx86unix.cpp | as -o asm/mx86-elf.o + +# solaris +asm/mx86-sol.o: asm/mx86unix.cpp + $(CC) -E -DSOL asm/mx86unix.cpp | sed 's/^#.*//' > asm/mx86-sol.s + as -o asm/mx86-sol.o asm/mx86-sol.s + rm -f asm/mx86-sol.s + +# a.out +asm/mx86-out.o: asm/mx86unix.cpp + $(CPP) -DOUT asm/mx86unix.cpp | as -o asm/mx86-out.o + +# bsdi +asm/mx86bsdi.o: asm/mx86unix.cpp + $(CPP) -DBSDI asm/mx86unix.cpp | sed 's/ :/:/' | as -o asm/mx86bsdi.o + +asm/mx86unix.cpp: asm/md5-586.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) md5-586.pl cpp >mx86unix.cpp) + +asm/md5-sparcv8plus.o: asm/md5-sparcv9.S + $(CC) $(ASFLAGS) -DMD5_BLOCK_DATA_ORDER -c \ + -o asm/md5-sparcv8plus.o asm/md5-sparcv9.S + +# Old GNU assembler doesn't understand V9 instructions, so we +# hire /usr/ccs/bin/as to do the job. Note that option is called +# *-gcc27, but even gcc 2>=8 users may experience similar problem +# if they didn't bother to upgrade GNU assembler. Such users should +# not choose this option, but be adviced to *remove* GNU assembler +# or upgrade it. +asm/md5-sparcv8plus-gcc27.o: asm/md5-sparcv9.S + $(CC) $(ASFLAGS) -DMD5_BLOCK_DATA_ORDER -E asm/md5-sparcv9.S | \ + /usr/ccs/bin/as -xarch=v8plus - -o asm/md5-sparcv8plus-gcc27.o + +asm/md5-sparcv9.o: asm/md5-sparcv9.S + $(CC) $(ASFLAGS) -DMD5_BLOCK_DATA_ORDER -c \ + -o asm/md5-sparcv9.o asm/md5-sparcv9.S + +files: + $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO + +links: + @$(TOP)/util/point.sh Makefile.ssl Makefile + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f asm/mx86unix.cpp *.o asm/*.o *.obj $(LIB) tags core .pure .nfs* *.old *.bak fluff + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff -urN linux-2.4.29/net/ipsec/libcrypto/libmd5/asm/md5-586.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/asm/md5-586.pl --- linux-2.4.29/net/ipsec/libcrypto/libmd5/asm/md5-586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/asm/md5-586.pl Thu Sep 5 05:35:58 2002 @@ -0,0 +1,306 @@ +#!/usr/local/bin/perl + +# Normal is the +# md5_block_x86(MD5_CTX *c, ULONG *X); +# version, non-normal is the +# md5_block_x86(MD5_CTX *c, ULONG *X,int blocks); + +$normal=0; + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],$0); + +$A="eax"; +$B="ebx"; +$C="ecx"; +$D="edx"; +$tmp1="edi"; +$tmp2="ebp"; +$X="esi"; + +# What we need to load into $tmp for the next round +%Ltmp1=("R0",&Np($C), "R1",&Np($C), "R2",&Np($C), "R3",&Np($D)); +@xo=( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, # R0 + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, # R1 + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, # R2 + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, # R3 + ); + +&md5_block("md5_block_asm_host_order"); +&asm_finish(); + +sub Np + { + local($p)=@_; + local(%n)=($A,$D,$B,$A,$C,$B,$D,$C); + return($n{$p}); + } + +sub R0 + { + local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_; + + &mov($tmp1,$C) if $pos < 0; + &mov($tmp2,&DWP($xo[$ki]*4,$K,"",0)) if $pos < 0; # very first one + + # body proper + + &comment("R0 $ki"); + &xor($tmp1,$d); # F function - part 2 + + &and($tmp1,$b); # F function - part 3 + &lea($a,&DWP($t,$a,$tmp2,1)); + + &xor($tmp1,$d); # F function - part 4 + + &add($a,$tmp1); + &mov($tmp1,&Np($c)) if $pos < 1; # next tmp1 for R0 + &mov($tmp1,&Np($c)) if $pos == 1; # next tmp1 for R1 + + &rotl($a,$s); + + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2); + + &add($a,$b); + } + +sub R1 + { + local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_; + + &comment("R1 $ki"); + + &lea($a,&DWP($t,$a,$tmp2,1)); + + &xor($tmp1,$b); # G function - part 2 + &and($tmp1,$d); # G function - part 3 + + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2); + &xor($tmp1,$c); # G function - part 4 + + &add($a,$tmp1); + &mov($tmp1,&Np($c)) if $pos < 1; # G function - part 1 + &mov($tmp1,&Np($c)) if $pos == 1; # G function - part 1 + + &rotl($a,$s); + + &add($a,$b); + } + +sub R2 + { + local($n,$pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_; + # This one is different, only 3 logical operations + +if (($n & 1) == 0) + { + &comment("R2 $ki"); + # make sure to do 'D' first, not 'B', else we clash with + # the last add from the previous round. + + &xor($tmp1,$d); # H function - part 2 + + &xor($tmp1,$b); # H function - part 3 + &lea($a,&DWP($t,$a,$tmp2,1)); + + &add($a,$tmp1); + + &rotl($a,$s); + + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)); + &mov($tmp1,&Np($c)); + } +else + { + &comment("R2 $ki"); + # make sure to do 'D' first, not 'B', else we clash with + # the last add from the previous round. + + &lea($a,&DWP($t,$a,$tmp2,1)); + + &add($b,$c); # MOVED FORWARD + &xor($tmp1,$d); # H function - part 2 + + &xor($tmp1,$b); # H function - part 3 + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2); + + &add($a,$tmp1); + &mov($tmp1,&Np($c)) if $pos < 1; # H function - part 1 + &mov($tmp1,-1) if $pos == 1; # I function - part 1 + + &rotl($a,$s); + + &add($a,$b); + } + } + +sub R3 + { + local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_; + + &comment("R3 $ki"); + + # ¬($tmp1) + &xor($tmp1,$d) if $pos < 0; # I function - part 2 + + &or($tmp1,$b); # I function - part 3 + &lea($a,&DWP($t,$a,$tmp2,1)); + + &xor($tmp1,$c); # I function - part 4 + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if $pos != 2; # load X/k value + &mov($tmp2,&wparam(0)) if $pos == 2; + + &add($a,$tmp1); + &mov($tmp1,-1) if $pos < 1; # H function - part 1 + &add($K,64) if $pos >=1 && !$normal; + + &rotl($a,$s); + + &xor($tmp1,&Np($d)) if $pos <= 0; # I function - part = first time + &mov($tmp1,&DWP( 0,$tmp2,"",0)) if $pos > 0; + &add($a,$b); + } + + +sub md5_block + { + local($name)=@_; + + &function_begin_B($name,"",3); + + # parameter 1 is the MD5_CTX structure. + # A 0 + # B 4 + # C 8 + # D 12 + + &push("esi"); + &push("edi"); + &mov($tmp1, &wparam(0)); # edi + &mov($X, &wparam(1)); # esi + &mov($C, &wparam(2)); + &push("ebp"); + &shl($C, 6); + &push("ebx"); + &add($C, $X); # offset we end at + &sub($C, 64); + &mov($A, &DWP( 0,$tmp1,"",0)); + &push($C); # Put on the TOS + &mov($B, &DWP( 4,$tmp1,"",0)); + &mov($C, &DWP( 8,$tmp1,"",0)); + &mov($D, &DWP(12,$tmp1,"",0)); + + &set_label("start") unless $normal; + &comment(""); + &comment("R0 section"); + + &R0(-2,$A,$B,$C,$D,$X, 0, 7,0xd76aa478); + &R0( 0,$D,$A,$B,$C,$X, 1,12,0xe8c7b756); + &R0( 0,$C,$D,$A,$B,$X, 2,17,0x242070db); + &R0( 0,$B,$C,$D,$A,$X, 3,22,0xc1bdceee); + &R0( 0,$A,$B,$C,$D,$X, 4, 7,0xf57c0faf); + &R0( 0,$D,$A,$B,$C,$X, 5,12,0x4787c62a); + &R0( 0,$C,$D,$A,$B,$X, 6,17,0xa8304613); + &R0( 0,$B,$C,$D,$A,$X, 7,22,0xfd469501); + &R0( 0,$A,$B,$C,$D,$X, 8, 7,0x698098d8); + &R0( 0,$D,$A,$B,$C,$X, 9,12,0x8b44f7af); + &R0( 0,$C,$D,$A,$B,$X,10,17,0xffff5bb1); + &R0( 0,$B,$C,$D,$A,$X,11,22,0x895cd7be); + &R0( 0,$A,$B,$C,$D,$X,12, 7,0x6b901122); + &R0( 0,$D,$A,$B,$C,$X,13,12,0xfd987193); + &R0( 0,$C,$D,$A,$B,$X,14,17,0xa679438e); + &R0( 1,$B,$C,$D,$A,$X,15,22,0x49b40821); + + &comment(""); + &comment("R1 section"); + &R1(-1,$A,$B,$C,$D,$X,16, 5,0xf61e2562); + &R1( 0,$D,$A,$B,$C,$X,17, 9,0xc040b340); + &R1( 0,$C,$D,$A,$B,$X,18,14,0x265e5a51); + &R1( 0,$B,$C,$D,$A,$X,19,20,0xe9b6c7aa); + &R1( 0,$A,$B,$C,$D,$X,20, 5,0xd62f105d); + &R1( 0,$D,$A,$B,$C,$X,21, 9,0x02441453); + &R1( 0,$C,$D,$A,$B,$X,22,14,0xd8a1e681); + &R1( 0,$B,$C,$D,$A,$X,23,20,0xe7d3fbc8); + &R1( 0,$A,$B,$C,$D,$X,24, 5,0x21e1cde6); + &R1( 0,$D,$A,$B,$C,$X,25, 9,0xc33707d6); + &R1( 0,$C,$D,$A,$B,$X,26,14,0xf4d50d87); + &R1( 0,$B,$C,$D,$A,$X,27,20,0x455a14ed); + &R1( 0,$A,$B,$C,$D,$X,28, 5,0xa9e3e905); + &R1( 0,$D,$A,$B,$C,$X,29, 9,0xfcefa3f8); + &R1( 0,$C,$D,$A,$B,$X,30,14,0x676f02d9); + &R1( 1,$B,$C,$D,$A,$X,31,20,0x8d2a4c8a); + + &comment(""); + &comment("R2 section"); + &R2( 0,-1,$A,$B,$C,$D,$X,32, 4,0xfffa3942); + &R2( 1, 0,$D,$A,$B,$C,$X,33,11,0x8771f681); + &R2( 2, 0,$C,$D,$A,$B,$X,34,16,0x6d9d6122); + &R2( 3, 0,$B,$C,$D,$A,$X,35,23,0xfde5380c); + &R2( 4, 0,$A,$B,$C,$D,$X,36, 4,0xa4beea44); + &R2( 5, 0,$D,$A,$B,$C,$X,37,11,0x4bdecfa9); + &R2( 6, 0,$C,$D,$A,$B,$X,38,16,0xf6bb4b60); + &R2( 7, 0,$B,$C,$D,$A,$X,39,23,0xbebfbc70); + &R2( 8, 0,$A,$B,$C,$D,$X,40, 4,0x289b7ec6); + &R2( 9, 0,$D,$A,$B,$C,$X,41,11,0xeaa127fa); + &R2(10, 0,$C,$D,$A,$B,$X,42,16,0xd4ef3085); + &R2(11, 0,$B,$C,$D,$A,$X,43,23,0x04881d05); + &R2(12, 0,$A,$B,$C,$D,$X,44, 4,0xd9d4d039); + &R2(13, 0,$D,$A,$B,$C,$X,45,11,0xe6db99e5); + &R2(14, 0,$C,$D,$A,$B,$X,46,16,0x1fa27cf8); + &R2(15, 1,$B,$C,$D,$A,$X,47,23,0xc4ac5665); + + &comment(""); + &comment("R3 section"); + &R3(-1,$A,$B,$C,$D,$X,48, 6,0xf4292244); + &R3( 0,$D,$A,$B,$C,$X,49,10,0x432aff97); + &R3( 0,$C,$D,$A,$B,$X,50,15,0xab9423a7); + &R3( 0,$B,$C,$D,$A,$X,51,21,0xfc93a039); + &R3( 0,$A,$B,$C,$D,$X,52, 6,0x655b59c3); + &R3( 0,$D,$A,$B,$C,$X,53,10,0x8f0ccc92); + &R3( 0,$C,$D,$A,$B,$X,54,15,0xffeff47d); + &R3( 0,$B,$C,$D,$A,$X,55,21,0x85845dd1); + &R3( 0,$A,$B,$C,$D,$X,56, 6,0x6fa87e4f); + &R3( 0,$D,$A,$B,$C,$X,57,10,0xfe2ce6e0); + &R3( 0,$C,$D,$A,$B,$X,58,15,0xa3014314); + &R3( 0,$B,$C,$D,$A,$X,59,21,0x4e0811a1); + &R3( 0,$A,$B,$C,$D,$X,60, 6,0xf7537e82); + &R3( 0,$D,$A,$B,$C,$X,61,10,0xbd3af235); + &R3( 0,$C,$D,$A,$B,$X,62,15,0x2ad7d2bb); + &R3( 2,$B,$C,$D,$A,$X,63,21,0xeb86d391); + + # &mov($tmp2,&wparam(0)); # done in the last R3 + # &mov($tmp1, &DWP( 0,$tmp2,"",0)); # done is the last R3 + + &add($A,$tmp1); + &mov($tmp1, &DWP( 4,$tmp2,"",0)); + + &add($B,$tmp1); + &mov($tmp1, &DWP( 8,$tmp2,"",0)); + + &add($C,$tmp1); + &mov($tmp1, &DWP(12,$tmp2,"",0)); + + &add($D,$tmp1); + &mov(&DWP( 0,$tmp2,"",0),$A); + + &mov(&DWP( 4,$tmp2,"",0),$B); + &mov($tmp1,&swtmp(0)) unless $normal; + + &mov(&DWP( 8,$tmp2,"",0),$C); + &mov(&DWP(12,$tmp2,"",0),$D); + + &cmp($tmp1,$X) unless $normal; # check count + &jge(&label("start")) unless $normal; + + &pop("eax"); # pop the temp variable off the stack + &pop("ebx"); + &pop("ebp"); + &pop("edi"); + &pop("esi"); + &ret(); + &function_end_B($name); + } + diff -urN linux-2.4.29/net/ipsec/libcrypto/libmd5/hmac_md5.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/hmac_md5.c --- linux-2.4.29/net/ipsec/libcrypto/libmd5/hmac_md5.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/hmac_md5.c Thu Sep 5 05:31:27 2002 @@ -0,0 +1,21 @@ +#include +#include +#include "hmac_generic.h" +#include "md5.h" +#include "hmac_md5.h" + +void inline md5_result(MD5_CTX *ctx, __u8 * hash, int hashlen) { + if (hashlen==MD5_HASHLEN) + MD5_Final(hash, ctx); + else { + __u8 hash_buf[MD5_HASHLEN]; + MD5_Final(hash_buf, ctx); + memcpy(hash, hash_buf, hashlen); + } +} +HMAC_SET_KEY_IMPL (md5_hmac_set_key, + md5_hmac_context, MD5_BLOCKSIZE, + MD5_Init, MD5_Update) +HMAC_HASH_IMPL (md5_hmac_hash, + md5_hmac_context, MD5_CTX, MD5_HASHLEN, + MD5_Update, md5_result) diff -urN linux-2.4.29/net/ipsec/libcrypto/libmd5/hmac_md5.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/hmac_md5.h --- linux-2.4.29/net/ipsec/libcrypto/libmd5/hmac_md5.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/hmac_md5.h Thu Sep 5 05:31:27 2002 @@ -0,0 +1,9 @@ +#include "md5.h" +typedef struct { + MD5_CTX ictx,octx; +} md5_hmac_context; +#define MD5_BLOCKSIZE 64 +#define MD5_HASHLEN 16 + +void md5_hmac_hash(md5_hmac_context *hctx, const __u8 * dat, int len, __u8 * hash, int hashlen); +void md5_hmac_set_key(md5_hmac_context *hctx, const __u8 * key, int keylen); diff -urN linux-2.4.29/net/ipsec/libcrypto/libmd5/md5.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/md5.h --- linux-2.4.29/net/ipsec/libcrypto/libmd5/md5.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/md5.h Fri Feb 7 14:14:26 2003 @@ -0,0 +1,122 @@ +/* crypto/md5/md5.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MD5_H +#define HEADER_MD5_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef NO_MD5 +#error MD5 is disabled. +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! MD5_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(WIN16) || defined(__LP32__) +#define MD5_LONG unsigned long +#elif defined(_CRAY) || defined(__ILP64__) +#define MD5_LONG unsigned long +#define MD5_LONG_LOG2 3 +#endif +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ + +/* des.h-like hack */ +#ifndef MD5_LONG +#ifdef __KERNEL__ +#include +#else +#include +#endif +#define MD5_LONG u_int32_t +#endif + +#define MD5_CBLOCK 64 +#define MD5_LBLOCK (MD5_CBLOCK/4) +#define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st + { + MD5_LONG A,B,C,D; + MD5_LONG Nl,Nh; + MD5_LONG data[MD5_LBLOCK]; + int num; + } MD5_CTX; + +void MD5_Init(MD5_CTX *c); +void MD5_Update(MD5_CTX *c, const void *data, unsigned long len); +void MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libmd5/md5_dgst.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/md5_dgst.c --- linux-2.4.29/net/ipsec/libcrypto/libmd5/md5_dgst.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/md5_dgst.c Fri Feb 7 14:14:26 2003 @@ -0,0 +1,321 @@ +/* crypto/md5/md5_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifdef __KERNEL__ +#include +#include +#else +#include +#endif +#include "md5_locl.h" + +/* Implemented from RFC1321 The MD5 Message-Digest Algorithm + */ + +#define INIT_DATA_A (unsigned long)0x67452301L +#define INIT_DATA_B (unsigned long)0xefcdab89L +#define INIT_DATA_C (unsigned long)0x98badcfeL +#define INIT_DATA_D (unsigned long)0x10325476L + +void MD5_Init(MD5_CTX *c) + { + c->A=INIT_DATA_A; + c->B=INIT_DATA_B; + c->C=INIT_DATA_C; + c->D=INIT_DATA_D; + c->Nl=0; + c->Nh=0; + c->num=0; + } + +#ifndef md5_block_host_order +void md5_block_host_order (MD5_CTX *c, const void *data, int num) + { + const MD5_LONG *X=data; + register unsigned long A,B,C,D; + /* + * In case you wonder why A-D are declared as long and not + * as MD5_LONG. Doing so results in slight performance + * boost on LP64 architectures. The catch is we don't + * really care if 32 MSBs of a 64-bit register get polluted + * with eventual overflows as we *save* only 32 LSBs in + * *either* case. Now declaring 'em long excuses the compiler + * from keeping 32 MSBs zeroed resulting in 13% performance + * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. + * Well, to be honest it should say that this *prevents* + * performance degradation. + * + * + */ + + A=c->A; + B=c->B; + C=c->C; + D=c->D; + + for (;num--;X+=HASH_LBLOCK) + { + /* Round 0 */ + R0(A,B,C,D,X[ 0], 7,0xd76aa478L); + R0(D,A,B,C,X[ 1],12,0xe8c7b756L); + R0(C,D,A,B,X[ 2],17,0x242070dbL); + R0(B,C,D,A,X[ 3],22,0xc1bdceeeL); + R0(A,B,C,D,X[ 4], 7,0xf57c0fafL); + R0(D,A,B,C,X[ 5],12,0x4787c62aL); + R0(C,D,A,B,X[ 6],17,0xa8304613L); + R0(B,C,D,A,X[ 7],22,0xfd469501L); + R0(A,B,C,D,X[ 8], 7,0x698098d8L); + R0(D,A,B,C,X[ 9],12,0x8b44f7afL); + R0(C,D,A,B,X[10],17,0xffff5bb1L); + R0(B,C,D,A,X[11],22,0x895cd7beL); + R0(A,B,C,D,X[12], 7,0x6b901122L); + R0(D,A,B,C,X[13],12,0xfd987193L); + R0(C,D,A,B,X[14],17,0xa679438eL); + R0(B,C,D,A,X[15],22,0x49b40821L); + /* Round 1 */ + R1(A,B,C,D,X[ 1], 5,0xf61e2562L); + R1(D,A,B,C,X[ 6], 9,0xc040b340L); + R1(C,D,A,B,X[11],14,0x265e5a51L); + R1(B,C,D,A,X[ 0],20,0xe9b6c7aaL); + R1(A,B,C,D,X[ 5], 5,0xd62f105dL); + R1(D,A,B,C,X[10], 9,0x02441453L); + R1(C,D,A,B,X[15],14,0xd8a1e681L); + R1(B,C,D,A,X[ 4],20,0xe7d3fbc8L); + R1(A,B,C,D,X[ 9], 5,0x21e1cde6L); + R1(D,A,B,C,X[14], 9,0xc33707d6L); + R1(C,D,A,B,X[ 3],14,0xf4d50d87L); + R1(B,C,D,A,X[ 8],20,0x455a14edL); + R1(A,B,C,D,X[13], 5,0xa9e3e905L); + R1(D,A,B,C,X[ 2], 9,0xfcefa3f8L); + R1(C,D,A,B,X[ 7],14,0x676f02d9L); + R1(B,C,D,A,X[12],20,0x8d2a4c8aL); + /* Round 2 */ + R2(A,B,C,D,X[ 5], 4,0xfffa3942L); + R2(D,A,B,C,X[ 8],11,0x8771f681L); + R2(C,D,A,B,X[11],16,0x6d9d6122L); + R2(B,C,D,A,X[14],23,0xfde5380cL); + R2(A,B,C,D,X[ 1], 4,0xa4beea44L); + R2(D,A,B,C,X[ 4],11,0x4bdecfa9L); + R2(C,D,A,B,X[ 7],16,0xf6bb4b60L); + R2(B,C,D,A,X[10],23,0xbebfbc70L); + R2(A,B,C,D,X[13], 4,0x289b7ec6L); + R2(D,A,B,C,X[ 0],11,0xeaa127faL); + R2(C,D,A,B,X[ 3],16,0xd4ef3085L); + R2(B,C,D,A,X[ 6],23,0x04881d05L); + R2(A,B,C,D,X[ 9], 4,0xd9d4d039L); + R2(D,A,B,C,X[12],11,0xe6db99e5L); + R2(C,D,A,B,X[15],16,0x1fa27cf8L); + R2(B,C,D,A,X[ 2],23,0xc4ac5665L); + /* Round 3 */ + R3(A,B,C,D,X[ 0], 6,0xf4292244L); + R3(D,A,B,C,X[ 7],10,0x432aff97L); + R3(C,D,A,B,X[14],15,0xab9423a7L); + R3(B,C,D,A,X[ 5],21,0xfc93a039L); + R3(A,B,C,D,X[12], 6,0x655b59c3L); + R3(D,A,B,C,X[ 3],10,0x8f0ccc92L); + R3(C,D,A,B,X[10],15,0xffeff47dL); + R3(B,C,D,A,X[ 1],21,0x85845dd1L); + R3(A,B,C,D,X[ 8], 6,0x6fa87e4fL); + R3(D,A,B,C,X[15],10,0xfe2ce6e0L); + R3(C,D,A,B,X[ 6],15,0xa3014314L); + R3(B,C,D,A,X[13],21,0x4e0811a1L); + R3(A,B,C,D,X[ 4], 6,0xf7537e82L); + R3(D,A,B,C,X[11],10,0xbd3af235L); + R3(C,D,A,B,X[ 2],15,0x2ad7d2bbL); + R3(B,C,D,A,X[ 9],21,0xeb86d391L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } + } +#endif + +#ifndef md5_block_data_order +#ifdef X +#undef X +#endif +void md5_block_data_order (MD5_CTX *c, const void *data_, int num) + { + const unsigned char *data=data_; + register unsigned long A,B,C,D,l; + /* + * In case you wonder why A-D are declared as long and not + * as MD5_LONG. Doing so results in slight performance + * boost on LP64 architectures. The catch is we don't + * really care if 32 MSBs of a 64-bit register get polluted + * with eventual overflows as we *save* only 32 LSBs in + * *either* case. Now declaring 'em long excuses the compiler + * from keeping 32 MSBs zeroed resulting in 13% performance + * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. + * Well, to be honest it should say that this *prevents* + * performance degradation. + * + * + */ +#ifndef MD32_XARRAY + /* See comment in crypto/sha/sha_locl.h for details. */ + unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; +# define X(i) XX##i +#else + MD5_LONG XX[MD5_LBLOCK]; +# define X(i) XX[i] +#endif + + A=c->A; + B=c->B; + C=c->C; + D=c->D; + + for (;num--;) + { + HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l; + /* Round 0 */ + R0(A,B,C,D,X( 0), 7,0xd76aa478L); HOST_c2l(data,l); X( 2)=l; + R0(D,A,B,C,X( 1),12,0xe8c7b756L); HOST_c2l(data,l); X( 3)=l; + R0(C,D,A,B,X( 2),17,0x242070dbL); HOST_c2l(data,l); X( 4)=l; + R0(B,C,D,A,X( 3),22,0xc1bdceeeL); HOST_c2l(data,l); X( 5)=l; + R0(A,B,C,D,X( 4), 7,0xf57c0fafL); HOST_c2l(data,l); X( 6)=l; + R0(D,A,B,C,X( 5),12,0x4787c62aL); HOST_c2l(data,l); X( 7)=l; + R0(C,D,A,B,X( 6),17,0xa8304613L); HOST_c2l(data,l); X( 8)=l; + R0(B,C,D,A,X( 7),22,0xfd469501L); HOST_c2l(data,l); X( 9)=l; + R0(A,B,C,D,X( 8), 7,0x698098d8L); HOST_c2l(data,l); X(10)=l; + R0(D,A,B,C,X( 9),12,0x8b44f7afL); HOST_c2l(data,l); X(11)=l; + R0(C,D,A,B,X(10),17,0xffff5bb1L); HOST_c2l(data,l); X(12)=l; + R0(B,C,D,A,X(11),22,0x895cd7beL); HOST_c2l(data,l); X(13)=l; + R0(A,B,C,D,X(12), 7,0x6b901122L); HOST_c2l(data,l); X(14)=l; + R0(D,A,B,C,X(13),12,0xfd987193L); HOST_c2l(data,l); X(15)=l; + R0(C,D,A,B,X(14),17,0xa679438eL); + R0(B,C,D,A,X(15),22,0x49b40821L); + /* Round 1 */ + R1(A,B,C,D,X( 1), 5,0xf61e2562L); + R1(D,A,B,C,X( 6), 9,0xc040b340L); + R1(C,D,A,B,X(11),14,0x265e5a51L); + R1(B,C,D,A,X( 0),20,0xe9b6c7aaL); + R1(A,B,C,D,X( 5), 5,0xd62f105dL); + R1(D,A,B,C,X(10), 9,0x02441453L); + R1(C,D,A,B,X(15),14,0xd8a1e681L); + R1(B,C,D,A,X( 4),20,0xe7d3fbc8L); + R1(A,B,C,D,X( 9), 5,0x21e1cde6L); + R1(D,A,B,C,X(14), 9,0xc33707d6L); + R1(C,D,A,B,X( 3),14,0xf4d50d87L); + R1(B,C,D,A,X( 8),20,0x455a14edL); + R1(A,B,C,D,X(13), 5,0xa9e3e905L); + R1(D,A,B,C,X( 2), 9,0xfcefa3f8L); + R1(C,D,A,B,X( 7),14,0x676f02d9L); + R1(B,C,D,A,X(12),20,0x8d2a4c8aL); + /* Round 2 */ + R2(A,B,C,D,X( 5), 4,0xfffa3942L); + R2(D,A,B,C,X( 8),11,0x8771f681L); + R2(C,D,A,B,X(11),16,0x6d9d6122L); + R2(B,C,D,A,X(14),23,0xfde5380cL); + R2(A,B,C,D,X( 1), 4,0xa4beea44L); + R2(D,A,B,C,X( 4),11,0x4bdecfa9L); + R2(C,D,A,B,X( 7),16,0xf6bb4b60L); + R2(B,C,D,A,X(10),23,0xbebfbc70L); + R2(A,B,C,D,X(13), 4,0x289b7ec6L); + R2(D,A,B,C,X( 0),11,0xeaa127faL); + R2(C,D,A,B,X( 3),16,0xd4ef3085L); + R2(B,C,D,A,X( 6),23,0x04881d05L); + R2(A,B,C,D,X( 9), 4,0xd9d4d039L); + R2(D,A,B,C,X(12),11,0xe6db99e5L); + R2(C,D,A,B,X(15),16,0x1fa27cf8L); + R2(B,C,D,A,X( 2),23,0xc4ac5665L); + /* Round 3 */ + R3(A,B,C,D,X( 0), 6,0xf4292244L); + R3(D,A,B,C,X( 7),10,0x432aff97L); + R3(C,D,A,B,X(14),15,0xab9423a7L); + R3(B,C,D,A,X( 5),21,0xfc93a039L); + R3(A,B,C,D,X(12), 6,0x655b59c3L); + R3(D,A,B,C,X( 3),10,0x8f0ccc92L); + R3(C,D,A,B,X(10),15,0xffeff47dL); + R3(B,C,D,A,X( 1),21,0x85845dd1L); + R3(A,B,C,D,X( 8), 6,0x6fa87e4fL); + R3(D,A,B,C,X(15),10,0xfe2ce6e0L); + R3(C,D,A,B,X( 6),15,0xa3014314L); + R3(B,C,D,A,X(13),21,0x4e0811a1L); + R3(A,B,C,D,X( 4), 6,0xf7537e82L); + R3(D,A,B,C,X(11),10,0xbd3af235L); + R3(C,D,A,B,X( 2),15,0x2ad7d2bbL); + R3(B,C,D,A,X( 9),21,0xeb86d391L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } + } +#endif + +#ifdef undef +int printit(unsigned long *l) + { + int i,ii; + + for (i=0; i<2; i++) + { + for (ii=0; ii<8; ii++) + { + fprintf(stderr,"%08lx ",l[i*8+ii]); + } + fprintf(stderr,"\n"); + } + } +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libmd5/md5_locl.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/md5_locl.h --- linux-2.4.29/net/ipsec/libcrypto/libmd5/md5_locl.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/md5_locl.h Fri Feb 7 14:14:26 2003 @@ -0,0 +1,177 @@ +/* crypto/md5/md5_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifdef __KERNEL__ +#include +#include +#include "md5.h" +#else +#include +#include +#include "md5.h" +#endif + +#ifndef MD5_LONG_LOG2 +#define MD5_LONG_LOG2 2 /* default to 32 bits */ +#endif + +#ifdef MD5_ASM +# if defined(__i386) || defined(_M_IX86) || defined(__INTEL__) +# define md5_block_host_order md5_block_asm_host_order +# elif defined(__sparc) && defined(ULTRASPARC) + void md5_block_asm_data_order_aligned (MD5_CTX *c, const MD5_LONG *p,int num); +# define HASH_BLOCK_DATA_ORDER_ALIGNED md5_block_asm_data_order_aligned +# endif +#endif + +void md5_block_host_order (MD5_CTX *c, const void *p,int num); +void md5_block_data_order (MD5_CTX *c, const void *p,int num); + +#if defined(__i386) || defined(_M_IX86) || defined(__INTEL__) +/* + * *_block_host_order is expected to handle aligned data while + * *_block_data_order - unaligned. As algorithm and host (x86) + * are in this case of the same "endianness" these two are + * otherwise indistinguishable. But normally you don't want to + * call the same function because unaligned access in places + * where alignment is expected is usually a "Bad Thing". Indeed, + * on RISCs you get punished with BUS ERROR signal or *severe* + * performance degradation. Intel CPUs are in turn perfectly + * capable of loading unaligned data without such drastic side + * effect. Yes, they say it's slower than aligned load, but no + * exception is generated and therefore performance degradation + * is *incomparable* with RISCs. What we should weight here is + * costs of unaligned access against costs of aligning data. + * According to my measurements allowing unaligned access results + * in ~9% performance improvement on Pentium II operating at + * 266MHz. I won't be surprised if the difference will be higher + * on faster systems:-) + * + * + */ +#define md5_block_data_order md5_block_host_order +#endif + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG MD5_LONG +#define HASH_LONG_LOG2 MD5_LONG_LOG2 +#define HASH_CTX MD5_CTX +#define HASH_CBLOCK MD5_CBLOCK +#define HASH_LBLOCK MD5_LBLOCK +#define HASH_UPDATE MD5_Update +#define HASH_TRANSFORM MD5_Transform +#define HASH_FINAL MD5_Final +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; HOST_l2c(ll,(s)); \ + ll=(c)->B; HOST_l2c(ll,(s)); \ + ll=(c)->C; HOST_l2c(ll,(s)); \ + ll=(c)->D; HOST_l2c(ll,(s)); \ + } while (0) +#define HASH_BLOCK_HOST_ORDER md5_block_host_order +#if !defined(L_ENDIAN) || defined(md5_block_data_order) +#define HASH_BLOCK_DATA_ORDER md5_block_data_order +/* + * Little-endians (Intel and Alpha) feel better without this. + * It looks like memcpy does better job than generic + * md5_block_data_order on copying-n-aligning input data. + * But frankly speaking I didn't expect such result on Alpha. + * On the other hand I've got this with egcs-1.0.2 and if + * program is compiled with another (better?) compiler it + * might turn out other way around. + * + * + */ +#endif + +#include "md32_common.h" + +/* +#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) +*/ + +/* As pointed out by Wei Dai , the above can be + * simplified to the code below. Wei attributes these optimizations + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. + */ +#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c)) +#define H(b,c,d) ((b) ^ (c) ^ (d)) +#define I(b,c,d) (((~(d)) | (b)) ^ (c)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; };\ + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R3(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+I((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; diff -urN linux-2.4.29/net/ipsec/libcrypto/libmd5/md5_one.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/md5_one.c --- linux-2.4.29/net/ipsec/libcrypto/libmd5/md5_one.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libmd5/md5_one.c Fri Feb 7 14:14:26 2003 @@ -0,0 +1,97 @@ +/* crypto/md5/md5_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif + +#include "md5.h" + +unsigned char *MD5(const unsigned char *d, unsigned long n, unsigned char *md) + { + MD5_CTX c; + static unsigned char m[MD5_DIGEST_LENGTH]; + + if (md == NULL) md=m; + MD5_Init(&c); +#ifndef CHARSET_EBCDIC + MD5_Update(&c,d,n); +#else + { + char temp[1024]; + unsigned long chunk; + + while (n > 0) + { + chunk = (n > sizeof(temp)) ? sizeof(temp) : n; + ebcdic2ascii(temp, d, chunk); + MD5_Update(&c,temp,chunk); + n -= chunk; + d += chunk; + } + } +#endif + MD5_Final(md,&c); + memset(&c,0,sizeof(c)); /* security consideration */ + return(md); + } + diff -urN linux-2.4.29/net/ipsec/libcrypto/libserpent/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/Makefile --- linux-2.4.29/net/ipsec/libcrypto/libserpent/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/Makefile Tue Jul 8 16:21:05 2003 @@ -0,0 +1,20 @@ +CFLAGS=-O3 -fomit-frame-pointer -D__KERNEL__ -Wall $(EXTRA_CFLAGS) +INC=-I../include +LIBOBJ=serpent.o serpent_cbc.o +BLIB=libserpent.a + +.c.o: + $(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c $< -o $@ + +$(BLIB): $(LIBOBJ) + /bin/rm -f $(BLIB) + ar cr $(BLIB) $(LIBOBJ) + -if test -s /bin/ranlib; then /bin/ranlib $(BLIB); \ + else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(BLIB); \ + else exit 0; fi; fi + +test: test_main.o $(BLIB) + $(CC) -o $@ $^ + +clean: + rm -f *.[oa] core $(TARGET) test diff -urN linux-2.4.29/net/ipsec/libcrypto/libserpent/serpent.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/serpent.c --- linux-2.4.29/net/ipsec/libcrypto/libserpent/serpent.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/serpent.c Tue Jan 25 14:43:00 2005 @@ -0,0 +1,994 @@ + +/* Optimized implementation of the Serpent AES candidate algorithm + * Designed by Anderson, Biham and Knudsen and Implemented by + * Gisle Sælensminde 2000. + * + * The implementation is based on the pentium optimised sboxes of + * Dag Arne Osvik. Even these sboxes are designed to be optimal for x86 + * processors they are efficient on other processors as well, but the speedup + * isn't so impressive compared to other implementations. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#ifdef __KERNEL__ +#include +#include +#include +#else +#include +#include +#endif + +#include "serpent.h" + +#define rotl(reg, val) ((reg << val) | (reg >> (32 - val))) +#define rotr(reg, val) ((reg >> val) | (reg << (32 - val))) + +#ifdef __cpu_to_be32 +#define BLOCK_SWAP +#define io_swap(x) __cpu_to_be32(x) +#else +#undef BLOCK_SWAP +#endif + +/* The sbox functions. The first four parameters is the input bits, and + * the last is a tempoary. These parameters are also used for output, but + * the bit order is permuted. The output bit order from S0 is + * (1 4 2 0 3), where 3 is the (now useless) tempoary. + */ + +#define S0(r0,r1,r2,r3,r4) \ + r3 = r3 ^ r0; \ + r4 = r1; \ + r1 = r1 & r3; \ + r4 = r4 ^ r2; \ + r1 = r1 ^ r0; \ + r0 = r0 | r3; \ + r0 = r0 ^ r4; \ + r4 = r4 ^ r3; \ + r3 = r3 ^ r2; \ + r2 = r2 | r1; \ + r2 = r2 ^ r4; \ + r4 = -1 ^ r4; \ + r4 = r4 | r1; \ + r1 = r1 ^ r3; \ + r1 = r1 ^ r4; \ + r3 = r3 | r0; \ + r1 = r1 ^ r3; \ + r4 = r4 ^ r3; + +#define S1(r0,r1,r2,r3,r4) \ + r1 = -1 ^ r1; \ + r4 = r0; \ + r0 = r0 ^ r1; \ + r4 = r4 | r1; \ + r4 = r4 ^ r3; \ + r3 = r3 & r0; \ + r2 = r2 ^ r4; \ + r3 = r3 ^ r1; \ + r3 = r3 | r2; \ + r0 = r0 ^ r4; \ + r3 = r3 ^ r0; \ + r1 = r1 & r2; \ + r0 = r0 | r1; \ + r1 = r1 ^ r4; \ + r0 = r0 ^ r2; \ + r4 = r4 | r3; \ + r0 = r0 ^ r4; \ + r4 = -1 ^ r4; \ + r1 = r1 ^ r3; \ + r4 = r4 & r2; \ + r1 = -1 ^ r1; \ + r4 = r4 ^ r0; \ + r1 = r1 ^ r4; + +#define S2(r0,r1,r2,r3,r4) \ + r4 = r0; \ + r0 = r0 & r2; \ + r0 = r0 ^ r3; \ + r2 = r2 ^ r1; \ + r2 = r2 ^ r0; \ + r3 = r3 | r4; \ + r3 = r3 ^ r1; \ + r4 = r4 ^ r2; \ + r1 = r3; \ + r3 = r3 | r4; \ + r3 = r3 ^ r0; \ + r0 = r0 & r1; \ + r4 = r4 ^ r0; \ + r1 = r1 ^ r3; \ + r1 = r1 ^ r4; \ + r4 = -1 ^ r4; + +#define S3(r0,r1,r2,r3,r4) \ + r4 = r0 ; \ + r0 = r0 | r3; \ + r3 = r3 ^ r1; \ + r1 = r1 & r4; \ + r4 = r4 ^ r2; \ + r2 = r2 ^ r3; \ + r3 = r3 & r0; \ + r4 = r4 | r1; \ + r3 = r3 ^ r4; \ + r0 = r0 ^ r1; \ + r4 = r4 & r0; \ + r1 = r1 ^ r3; \ + r4 = r4 ^ r2; \ + r1 = r1 | r0; \ + r1 = r1 ^ r2; \ + r0 = r0 ^ r3; \ + r2 = r1; \ + r1 = r1 | r3; \ + r1 = r1 ^ r0; + +#define S4(r0,r1,r2,r3,r4) \ + r1 = r1 ^ r3; \ + r3 = -1 ^ r3; \ + r2 = r2 ^ r3; \ + r3 = r3 ^ r0; \ + r4 = r1; \ + r1 = r1 & r3; \ + r1 = r1 ^ r2; \ + r4 = r4 ^ r3; \ + r0 = r0 ^ r4; \ + r2 = r2 & r4; \ + r2 = r2 ^ r0; \ + r0 = r0 & r1; \ + r3 = r3 ^ r0; \ + r4 = r4 | r1; \ + r4 = r4 ^ r0; \ + r0 = r0 | r3; \ + r0 = r0 ^ r2; \ + r2 = r2 & r3; \ + r0 = -1 ^ r0; \ + r4 = r4 ^ r2; + +#define S5(r0,r1,r2,r3,r4) \ + r0 = r0 ^ r1; \ + r1 = r1 ^ r3; \ + r3 = -1 ^ r3; \ + r4 = r1; \ + r1 = r1 & r0; \ + r2 = r2 ^ r3; \ + r1 = r1 ^ r2; \ + r2 = r2 | r4; \ + r4 = r4 ^ r3; \ + r3 = r3 & r1; \ + r3 = r3 ^ r0; \ + r4 = r4 ^ r1; \ + r4 = r4 ^ r2; \ + r2 = r2 ^ r0; \ + r0 = r0 & r3; \ + r2 = -1 ^ r2; \ + r0 = r0 ^ r4; \ + r4 = r4 | r3; \ + r2 = r2 ^ r4; + +#define S6(r0,r1,r2,r3,r4) \ + r2 = -1 ^ r2; \ + r4 = r3; \ + r3 = r3 & r0; \ + r0 = r0 ^ r4; \ + r3 = r3 ^ r2; \ + r2 = r2 | r4; \ + r1 = r1 ^ r3; \ + r2 = r2 ^ r0; \ + r0 = r0 | r1; \ + r2 = r2 ^ r1; \ + r4 = r4 ^ r0; \ + r0 = r0 | r3; \ + r0 = r0 ^ r2; \ + r4 = r4 ^ r3; \ + r4 = r4 ^ r0; \ + r3 = -1 ^ r3; \ + r2 = r2 & r4; \ + r2 = r2 ^ r3; + +#define S7(r0,r1,r2,r3,r4) \ + r4 = r2; \ + r2 = r2 & r1; \ + r2 = r2 ^ r3; \ + r3 = r3 & r1; \ + r4 = r4 ^ r2; \ + r2 = r2 ^ r1; \ + r1 = r1 ^ r0; \ + r0 = r0 | r4; \ + r0 = r0 ^ r2; \ + r3 = r3 ^ r1; \ + r2 = r2 ^ r3; \ + r3 = r3 & r0; \ + r3 = r3 ^ r4; \ + r4 = r4 ^ r2; \ + r2 = r2 & r0; \ + r4 = -1 ^ r4; \ + r2 = r2 ^ r4; \ + r4 = r4 & r0; \ + r1 = r1 ^ r3; \ + r4 = r4 ^ r1; + +/* The inverse sboxes */ + +#define I0(r0,r1,r2,r3,r4) \ + r2 = r2 ^ -1; \ + r4 = r1; \ + r1 = r1 | r0; \ + r4 = r4 ^ -1; \ + r1 = r1 ^ r2; \ + r2 = r2 | r4; \ + r1 = r1 ^ r3; \ + r0 = r0 ^ r4; \ + r2 = r2 ^ r0; \ + r0 = r0 & r3; \ + r4 = r4 ^ r0; \ + r0 = r0 | r1; \ + r0 = r0 ^ r2; \ + r3 = r3 ^ r4; \ + r2 = r2 ^ r1; \ + r3 = r3 ^ r0; \ + r3 = r3 ^ r1; \ + r2 = r2 & r3; \ + r4 = r4 ^ r2; + +#define I1(r0,r1,r2,r3,r4) \ + r4 = r1; \ + r1 = r1 ^ r3; \ + r3 = r3 & r1; \ + r4 = r4 ^ r2; \ + r3 = r3 ^ r0; \ + r0 = r0 | r1; \ + r2 = r2 ^ r3; \ + r0 = r0 ^ r4; \ + r0 = r0 | r2; \ + r1 = r1 ^ r3; \ + r0 = r0 ^ r1; \ + r1 = r1 | r3; \ + r1 = r1 ^ r0; \ + r4 = r4 ^ -1; \ + r4 = r4 ^ r1; \ + r1 = r1 | r0; \ + r1 = r1 ^ r0; \ + r1 = r1 | r4; \ + r3 = r3 ^ r1; + +#define I2(r0,r1,r2,r3,r4) \ + r2 = r2 ^ r3; \ + r3 = r3 ^ r0; \ + r4 = r3; \ + r3 = r3 & r2; \ + r3 = r3 ^ r1; \ + r1 = r1 | r2; \ + r1 = r1 ^ r4; \ + r4 = r4 & r3; \ + r2 = r2 ^ r3; \ + r4 = r4 & r0; \ + r4 = r4 ^ r2; \ + r2 = r2 & r1; \ + r2 = r2 | r0; \ + r3 = r3 ^ -1; \ + r2 = r2 ^ r3; \ + r0 = r0 ^ r3; \ + r0 = r0 & r1; \ + r3 = r3 ^ r4; \ + r3 = r3 ^ r0; + +#define I3(r0,r1,r2,r3,r4) \ + r4 = r2; \ + r2 = r2 ^ r1; \ + r0 = r0 ^ r2; \ + r4 = r4 & r2; \ + r4 = r4 ^ r0; \ + r0 = r0 & r1; \ + r1 = r1 ^ r3; \ + r3 = r3 | r4; \ + r2 = r2 ^ r3; \ + r0 = r0 ^ r3; \ + r1 = r1 ^ r4; \ + r3 = r3 & r2; \ + r3 = r3 ^ r1; \ + r1 = r1 ^ r0; \ + r1 = r1 | r2; \ + r0 = r0 ^ r3; \ + r1 = r1 ^ r4; \ + r0 = r0 ^ r1; + +#define I4(r0,r1,r2,r3,r4) \ + r4 = r2; \ + r2 = r2 & r3; \ + r2 = r2 ^ r1; \ + r1 = r1 | r3; \ + r1 = r1 & r0; \ + r4 = r4 ^ r2; \ + r4 = r4 ^ r1; \ + r1 = r1 & r2; \ + r0 = r0 ^ -1; \ + r3 = r3 ^ r4; \ + r1 = r1 ^ r3; \ + r3 = r3 & r0; \ + r3 = r3 ^ r2; \ + r0 = r0 ^ r1; \ + r2 = r2 & r0; \ + r3 = r3 ^ r0; \ + r2 = r2 ^ r4; \ + r2 = r2 | r3; \ + r3 = r3 ^ r0; \ + r2 = r2 ^ r1; + +#define I5(r0,r1,r2,r3,r4) \ + r1 = r1 ^ -1; \ + r4 = r3; \ + r2 = r2 ^ r1; \ + r3 = r3 | r0; \ + r3 = r3 ^ r2; \ + r2 = r2 | r1; \ + r2 = r2 & r0; \ + r4 = r4 ^ r3; \ + r2 = r2 ^ r4; \ + r4 = r4 | r0; \ + r4 = r4 ^ r1; \ + r1 = r1 & r2; \ + r1 = r1 ^ r3; \ + r4 = r4 ^ r2; \ + r3 = r3 & r4; \ + r4 = r4 ^ r1; \ + r3 = r3 ^ r0; \ + r3 = r3 ^ r4; \ + r4 = r4 ^ -1; + + +#define I6(r0,r1,r2,r3,r4) \ + r0 = r0 ^ r2; \ + r4 = r2; \ + r2 = r2 & r0; \ + r4 = r4 ^ r3; \ + r2 = r2 ^ -1; \ + r3 = r3 ^ r1; \ + r2 = r2 ^ r3; \ + r4 = r4 | r0; \ + r0 = r0 ^ r2; \ + r3 = r3 ^ r4; \ + r4 = r4 ^ r1; \ + r1 = r1 & r3; \ + r1 = r1 ^ r0; \ + r0 = r0 ^ r3; \ + r0 = r0 | r2; \ + r3 = r3 ^ r1; \ + r4 = r4 ^ r0; + +#define I7(r0,r1,r2,r3,r4) \ + r4 = r2; \ + r2 = r2 ^ r0; \ + r0 = r0 & r3; \ + r4 = r4 | r3; \ + r2 = r2 ^ -1; \ + r3 = r3 ^ r1; \ + r1 = r1 | r0; \ + r0 = r0 ^ r2; \ + r2 = r2 & r4; \ + r3 = r3 & r4; \ + r1 = r1 ^ r2; \ + r2 = r2 ^ r0; \ + r0 = r0 | r2; \ + r4 = r4 ^ r1; \ + r0 = r0 ^ r3; \ + r3 = r3 ^ r4; \ + r4 = r4 | r0; \ + r3 = r3 ^ r2; \ + r4 = r4 ^ r2; + +/* forward and inverse linear transformations */ + +#define LINTRANS(r0,r1,r2,r3,r4) \ + r0 = rotl(r0, 13); \ + r2 = rotl(r2, 3); \ + r3 = r3 ^ r2; \ + r4 = r0 << 3; \ + r1 = r1 ^ r0; \ + r3 = r3 ^ r4; \ + r1 = r1 ^ r2; \ + r3 = rotl(r3, 7); \ + r1 = rotl(r1, 1); \ + r2 = r2 ^ r3; \ + r4 = r1 << 7; \ + r0 = r0 ^ r1; \ + r2 = r2 ^ r4; \ + r0 = r0 ^ r3; \ + r2 = rotl(r2, 22); \ + r0 = rotl(r0, 5); + +#define ILINTRANS(r0,r1,r2,r3,r4) \ + r2 = rotr(r2, 22); \ + r0 = rotr(r0, 5); \ + r2 = r2 ^ r3; \ + r4 = r1 << 7; \ + r0 = r0 ^ r1; \ + r2 = r2 ^ r4; \ + r0 = r0 ^ r3; \ + r3 = rotr(r3, 7); \ + r1 = rotr(r1, 1); \ + r3 = r3 ^ r2; \ + r4 = r0 << 3; \ + r1 = r1 ^ r0; \ + r3 = r3 ^ r4; \ + r1 = r1 ^ r2; \ + r2 = rotr(r2, 3); \ + r0 = rotr(r0, 13); + + +#define KEYMIX(r0,r1,r2,r3,r4,IN) \ + r0 = r0 ^ l_key[IN+8]; \ + r1 = r1 ^ l_key[IN+9]; \ + r2 = r2 ^ l_key[IN+10]; \ + r3 = r3 ^ l_key[IN+11]; + +#define GETKEY(r0, r1, r2, r3, IN) \ + r0 = l_key[IN+8]; \ + r1 = l_key[IN+9]; \ + r2 = l_key[IN+10]; \ + r3 = l_key[IN+11]; + +#define SETKEY(r0, r1, r2, r3, IN) \ + l_key[IN+8] = r0; \ + l_key[IN+9] = r1; \ + l_key[IN+10] = r2; \ + l_key[IN+11] = r3; + +/* initialise the key schedule from the user supplied key */ + +int serpent_set_key(serpent_context *cx, const unsigned char *key, int key_len) +{ const u32 *in_key = (const u32 *)key; + /* l_key - storage for the key schedule */ + u32 *l_key = cx->keyinfo; + u32 i,lk,r0,r1,r2,r3,r4; + + if (key_len != 16 && key_len != 24 && key_len != 32) + return -1; /* unsupported key length */ + + key_len *= 8; + + i = 0; lk = (key_len + 31) / 32; + + while(i < lk) + { +#ifdef BLOCK_SWAP + l_key[i] = io_swap(in_key[lk - i - 1]); +#else + l_key[i] = in_key[i]; +#endif + i++; + } + + if (key_len < 256) + { + while(i < 8) + + l_key[i++] = 0; + + i = key_len / 32; lk = 1 << key_len % 32; + + l_key[i] &= lk - 1; + l_key[i] |= lk; + } + + for(i = 0; i < 132; ++i) + { + lk = l_key[i] ^ l_key[i + 3] ^ l_key[i + 5] + ^ l_key[i + 7] ^ 0x9e3779b9 ^ i; + + l_key[i + 8] = (lk << 11) | (lk >> 21); + } + + GETKEY(r0, r1, r2, r3, 0); + S3(r0,r1,r2,r3,r4); + SETKEY(r1, r2, r3, r4, 0) + + GETKEY(r0, r1, r2, r3, 4); + S2(r0,r1,r2,r3,r4); + SETKEY(r2, r3, r1, r4, 4) + + GETKEY(r0, r1, r2, r3, 8); + S1(r0,r1,r2,r3,r4); + SETKEY(r3, r1, r2, r0, 8) + + GETKEY(r0, r1, r2, r3, 12); + S0(r0,r1,r2,r3,r4); + SETKEY(r1, r4, r2, r0, 12) + + GETKEY(r0, r1, r2, r3, 16); + S7(r0,r1,r2,r3,r4); + SETKEY(r2, r4, r3, r0, 16) + + GETKEY(r0, r1, r2, r3, 20); + S6(r0,r1,r2,r3,r4) + SETKEY(r0, r1, r4, r2, 20) + + GETKEY(r0, r1, r2, r3, 24); + S5(r0,r1,r2,r3,r4); + SETKEY(r1, r3, r0, r2, 24) + + GETKEY(r0, r1, r2, r3, 28); + S4(r0,r1,r2,r3,r4) + SETKEY(r1, r4, r0, r3, 28) + + GETKEY(r0, r1, r2, r3, 32); + S3(r0,r1,r2,r3,r4); + SETKEY(r1, r2, r3, r4, 32) + + GETKEY(r0, r1, r2, r3, 36); + S2(r0,r1,r2,r3,r4); + SETKEY(r2, r3, r1, r4, 36) + + GETKEY(r0, r1, r2, r3, 40); + S1(r0,r1,r2,r3,r4); + SETKEY(r3, r1, r2, r0, 40) + + GETKEY(r0, r1, r2, r3, 44); + S0(r0,r1,r2,r3,r4); + SETKEY(r1, r4, r2, r0, 44) + + GETKEY(r0, r1, r2, r3, 48); + S7(r0,r1,r2,r3,r4); + SETKEY(r2, r4, r3, r0, 48) + + GETKEY(r0, r1, r2, r3, 52); + S6(r0,r1,r2,r3,r4) + SETKEY(r0, r1, r4, r2, 52) + + GETKEY(r0, r1, r2, r3, 56); + S5(r0,r1,r2,r3,r4); + SETKEY(r1, r3, r0, r2, 56) + + GETKEY(r0, r1, r2, r3, 60); + S4(r0,r1,r2,r3,r4) + SETKEY(r1, r4, r0, r3, 60) + + GETKEY(r0, r1, r2, r3, 64); + S3(r0,r1,r2,r3,r4); + SETKEY(r1, r2, r3, r4, 64) + + GETKEY(r0, r1, r2, r3, 68); + S2(r0,r1,r2,r3,r4); + SETKEY(r2, r3, r1, r4, 68) + + GETKEY(r0, r1, r2, r3, 72); + S1(r0,r1,r2,r3,r4); + SETKEY(r3, r1, r2, r0, 72) + + GETKEY(r0, r1, r2, r3, 76); + S0(r0,r1,r2,r3,r4); + SETKEY(r1, r4, r2, r0, 76) + + GETKEY(r0, r1, r2, r3, 80); + S7(r0,r1,r2,r3,r4); + SETKEY(r2, r4, r3, r0, 80) + + GETKEY(r0, r1, r2, r3, 84); + S6(r0,r1,r2,r3,r4) + SETKEY(r0, r1, r4, r2, 84) + + GETKEY(r0, r1, r2, r3, 88); + S5(r0,r1,r2,r3,r4); + SETKEY(r1, r3, r0, r2, 88) + + GETKEY(r0, r1, r2, r3, 92); + S4(r0,r1,r2,r3,r4) + SETKEY(r1, r4, r0, r3, 92) + + GETKEY(r0, r1, r2, r3, 96); + S3(r0,r1,r2,r3,r4); + SETKEY(r1, r2, r3, r4, 96) + + GETKEY(r0, r1, r2, r3, 100); + S2(r0,r1,r2,r3,r4); + SETKEY(r2, r3, r1, r4, 100) + + GETKEY(r0, r1, r2, r3, 104); + S1(r0,r1,r2,r3,r4); + SETKEY(r3, r1, r2, r0, 104) + + GETKEY(r0, r1, r2, r3, 108); + S0(r0,r1,r2,r3,r4); + SETKEY(r1, r4, r2, r0, 108) + + GETKEY(r0, r1, r2, r3, 112); + S7(r0,r1,r2,r3,r4); + SETKEY(r2, r4, r3, r0, 112) + + GETKEY(r0, r1, r2, r3, 116); + S6(r0,r1,r2,r3,r4) + SETKEY(r0, r1, r4, r2, 116) + + GETKEY(r0, r1, r2, r3, 120); + S5(r0,r1,r2,r3,r4); + SETKEY(r1, r3, r0, r2, 120) + + GETKEY(r0, r1, r2, r3, 124); + S4(r0,r1,r2,r3,r4) + SETKEY(r1, r4, r0, r3, 124) + + GETKEY(r0, r1, r2, r3, 128); + S3(r0,r1,r2,r3,r4); + SETKEY(r1, r2, r3, r4, 128) + + return 0; +}; + +/* Encryption and decryption functions. The rounds are fully inlined. + * The sboxes alters the bit order of the output, and the altered + * bit ordrer is used progressivly. */ + +/* encrypt a block of text */ + +int serpent_encrypt(serpent_context *cx, const u8 *in, + u8 *out) +{ u32 *l_key = cx->keyinfo; + const u32 *in_blk = (const u32 *) in; + u32 *out_blk = (u32 *) out; + u32 r0,r1,r2,r3,r4; + +#ifdef BLOCK_SWAP + r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]); + r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]); +#else + r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3]; +#endif + + /* round 1 */ + KEYMIX(r0,r1,r2,r3,r4,0); + S0(r0,r1,r2,r3,r4); + LINTRANS(r1,r4,r2,r0,r3); + + /* round 2 */ + KEYMIX(r1,r4,r2,r0,r3,4); + S1(r1,r4,r2,r0,r3); + LINTRANS(r0,r4,r2,r1,r3); + + /* round 3 */ + KEYMIX(r0,r4,r2,r1,r3,8); + S2(r0,r4,r2,r1,r3); + LINTRANS(r2,r1,r4,r3,r0); + + /* round 4 */ + KEYMIX(r2,r1,r4,r3,r0,12); + S3(r2,r1,r4,r3,r0); + LINTRANS(r1,r4,r3,r0,r2); + + /* round 5 */ + KEYMIX(r1,r4,r3,r0,r2,16); + S4(r1,r4,r3,r0,r2) + LINTRANS(r4,r2,r1,r0,r3); + + /* round 6 */ + KEYMIX(r4,r2,r1,r0,r3,20); + S5(r4,r2,r1,r0,r3); + LINTRANS(r2,r0,r4,r1,r3); + + /* round 7 */ + KEYMIX(r2,r0,r4,r1,r3,24); + S6(r2,r0,r4,r1,r3) + LINTRANS(r2,r0,r3,r4,r1); + + /* round 8 */ + KEYMIX(r2,r0,r3,r4,r1,28); + S7(r2,r0,r3,r4,r1); + LINTRANS(r3,r1,r4,r2,r0); + + /* round 9 */ + KEYMIX(r3,r1,r4,r2,r0,32); + S0(r3,r1,r4,r2,r0); + LINTRANS(r1,r0,r4,r3,r2); + + /* round 10 */ + KEYMIX(r1,r0,r4,r3,r2,36); + S1(r1,r0,r4,r3,r2); + LINTRANS(r3,r0,r4,r1,r2); + + /* round 11 */ + KEYMIX(r3,r0,r4,r1,r2,40); + S2(r3,r0,r4,r1,r2); + LINTRANS(r4,r1,r0,r2,r3); + + /* round 12 */ + KEYMIX(r4,r1,r0,r2,r3,44); + S3(r4,r1,r0,r2,r3); + LINTRANS(r1,r0,r2,r3,r4); + + /* round 13 */ + KEYMIX(r1,r0,r2,r3,r4,48); + S4(r1,r0,r2,r3,r4) + LINTRANS(r0,r4,r1,r3,r2); + + /* round 14 */ + KEYMIX(r0,r4,r1,r3,r2,52); + S5(r0,r4,r1,r3,r2); + LINTRANS(r4,r3,r0,r1,r2); + + /* round 15 */ + KEYMIX(r4,r3,r0,r1,r2,56); + S6(r4,r3,r0,r1,r2) + LINTRANS(r4,r3,r2,r0,r1); + + /* round 16 */ + KEYMIX(r4,r3,r2,r0,r1,60); + S7(r4,r3,r2,r0,r1); + LINTRANS(r2,r1,r0,r4,r3); + + /* round 17 */ + KEYMIX(r2,r1,r0,r4,r3,64); + S0(r2,r1,r0,r4,r3); + LINTRANS(r1,r3,r0,r2,r4); + + /* round 18 */ + KEYMIX(r1,r3,r0,r2,r4,68); + S1(r1,r3,r0,r2,r4); + LINTRANS(r2,r3,r0,r1,r4); + + /* round 19 */ + KEYMIX(r2,r3,r0,r1,r4,72); + S2(r2,r3,r0,r1,r4); + LINTRANS(r0,r1,r3,r4,r2); + + /* round 20 */ + KEYMIX(r0,r1,r3,r4,r2,76); + S3(r0,r1,r3,r4,r2); + LINTRANS(r1,r3,r4,r2,r0); + + /* round 21 */ + KEYMIX(r1,r3,r4,r2,r0,80); + S4(r1,r3,r4,r2,r0) + LINTRANS(r3,r0,r1,r2,r4); + + /* round 22 */ + KEYMIX(r3,r0,r1,r2,r4,84); + S5(r3,r0,r1,r2,r4); + LINTRANS(r0,r2,r3,r1,r4); + + /* round 23 */ + KEYMIX(r0,r2,r3,r1,r4,88); + S6(r0,r2,r3,r1,r4) + LINTRANS(r0,r2,r4,r3,r1); + + /* round 24 */ + KEYMIX(r0,r2,r4,r3,r1,92); + S7(r0,r2,r4,r3,r1); + LINTRANS(r4,r1,r3,r0,r2); + + /* round 25 */ + KEYMIX(r4,r1,r3,r0,r2,96); + S0(r4,r1,r3,r0,r2); + LINTRANS(r1,r2,r3,r4,r0); + + /* round 26 */ + KEYMIX(r1,r2,r3,r4,r0,100); + S1(r1,r2,r3,r4,r0); + LINTRANS(r4,r2,r3,r1,r0); + + /* round 27 */ + KEYMIX(r4,r2,r3,r1,r0,104); + S2(r4,r2,r3,r1,r0); + LINTRANS(r3,r1,r2,r0,r4); + + /* round 28 */ + KEYMIX(r3,r1,r2,r0,r4,108); + S3(r3,r1,r2,r0,r4); + LINTRANS(r1,r2,r0,r4,r3); + + /* round 29 */ + KEYMIX(r1,r2,r0,r4,r3,112); + S4(r1,r2,r0,r4,r3) + LINTRANS(r2,r3,r1,r4,r0); + + /* round 30 */ + KEYMIX(r2,r3,r1,r4,r0,116); + S5(r2,r3,r1,r4,r0); + LINTRANS(r3,r4,r2,r1,r0); + + /* round 31 */ + KEYMIX(r3,r4,r2,r1,r0,120); + S6(r3,r4,r2,r1,r0) + LINTRANS(r3,r4,r0,r2,r1); + + /* round 32 */ + KEYMIX(r3,r4,r0,r2,r1,124); + S7(r3,r4,r0,r2,r1); + KEYMIX(r0,r1,r2,r3,r4,128); + + +#ifdef BLOCK_SWAP + out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1); + out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3); +#else + out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3; +#endif + return 0; +}; + +/* decrypt a block of text */ + +int serpent_decrypt(serpent_context *cx, const u8 *in, + u8 *out) +{ u32 *l_key = cx->keyinfo; + const u32 *in_blk = (const u32 *)in; + u32 *out_blk = (u32 *)out; + u32 r0,r1,r2,r3,r4; + +#ifdef BLOCK_SWAP + r0 = io_swap(in_blk[3]); r1 = io_swap(in_blk[2]); + r2 = io_swap(in_blk[1]); r3 = io_swap(in_blk[0]); +#else + r0 = in_blk[0]; r1 = in_blk[1]; r2 = in_blk[2]; r3 = in_blk[3]; +#endif + + /* round 1 */ + KEYMIX(r0,r1,r2,r3,r4,128); + I7(r0,r1,r2,r3,r4); + KEYMIX(r3,r0,r1,r4,r2,124); + + /* round 2 */ + ILINTRANS(r3,r0,r1,r4,r2); + I6(r3,r0,r1,r4,r2); + KEYMIX(r0,r1,r2,r4,r3,120); + + /* round 3 */ + ILINTRANS(r0,r1,r2,r4,r3); + I5(r0,r1,r2,r4,r3); + KEYMIX(r1,r3,r4,r2,r0,116); + + /* round 4 */ + ILINTRANS(r1,r3,r4,r2,r0); + I4(r1,r3,r4,r2,r0); + KEYMIX(r1,r2,r4,r0,r3,112); + + /* round 5 */ + ILINTRANS(r1,r2,r4,r0,r3); + I3(r1,r2,r4,r0,r3); + KEYMIX(r4,r2,r0,r1,r3,108); + + /* round 6 */ + ILINTRANS(r4,r2,r0,r1,r3); + I2(r4,r2,r0,r1,r3); + KEYMIX(r2,r3,r0,r1,r4,104); + + /* round 7 */ + ILINTRANS(r2,r3,r0,r1,r4); + I1(r2,r3,r0,r1,r4); + KEYMIX(r4,r2,r1,r0,r3,100); + + /* round 8 */ + ILINTRANS(r4,r2,r1,r0,r3); + I0(r4,r2,r1,r0,r3); + KEYMIX(r4,r3,r2,r0,r1,96); + + /* round 9 */ + ILINTRANS(r4,r3,r2,r0,r1); + I7(r4,r3,r2,r0,r1); + KEYMIX(r0,r4,r3,r1,r2,92); + + /* round 10 */ + ILINTRANS(r0,r4,r3,r1,r2); + I6(r0,r4,r3,r1,r2); + KEYMIX(r4,r3,r2,r1,r0,88); + + /* round 11 */ + ILINTRANS(r4,r3,r2,r1,r0); + I5(r4,r3,r2,r1,r0); + KEYMIX(r3,r0,r1,r2,r4,84); + + /* round 12 */ + ILINTRANS(r3,r0,r1,r2,r4); + I4(r3,r0,r1,r2,r4); + KEYMIX(r3,r2,r1,r4,r0,80); + + /* round 13 */ + ILINTRANS(r3,r2,r1,r4,r0); + I3(r3,r2,r1,r4,r0); + KEYMIX(r1,r2,r4,r3,r0,76); + + /* round 14 */ + ILINTRANS(r1,r2,r4,r3,r0); + I2(r1,r2,r4,r3,r0); + KEYMIX(r2,r0,r4,r3,r1,72); + + /* round 15 */ + ILINTRANS(r2,r0,r4,r3,r1); + I1(r2,r0,r4,r3,r1); + KEYMIX(r1,r2,r3,r4,r0,68); + + /* round 16 */ + ILINTRANS(r1,r2,r3,r4,r0); + I0(r1,r2,r3,r4,r0); + KEYMIX(r1,r0,r2,r4,r3,64); + + /* round 17 */ + ILINTRANS(r1,r0,r2,r4,r3); + I7(r1,r0,r2,r4,r3); + KEYMIX(r4,r1,r0,r3,r2,60); + + /* round 18 */ + ILINTRANS(r4,r1,r0,r3,r2); + I6(r4,r1,r0,r3,r2); + KEYMIX(r1,r0,r2,r3,r4,56); + + /* round 19 */ + ILINTRANS(r1,r0,r2,r3,r4); + I5(r1,r0,r2,r3,r4); + KEYMIX(r0,r4,r3,r2,r1,52); + + /* round 20 */ + ILINTRANS(r0,r4,r3,r2,r1); + I4(r0,r4,r3,r2,r1); + KEYMIX(r0,r2,r3,r1,r4,48); + + /* round 21 */ + ILINTRANS(r0,r2,r3,r1,r4); + I3(r0,r2,r3,r1,r4); + KEYMIX(r3,r2,r1,r0,r4,44); + + /* round 22 */ + ILINTRANS(r3,r2,r1,r0,r4); + I2(r3,r2,r1,r0,r4); + KEYMIX(r2,r4,r1,r0,r3,40); + + /* round 23 */ + ILINTRANS(r2,r4,r1,r0,r3); + I1(r2,r4,r1,r0,r3); + KEYMIX(r3,r2,r0,r1,r4,36); + + /* round 24 */ + ILINTRANS(r3,r2,r0,r1,r4); + I0(r3,r2,r0,r1,r4); + KEYMIX(r3,r4,r2,r1,r0,32); + + /* round 25 */ + ILINTRANS(r3,r4,r2,r1,r0); + I7(r3,r4,r2,r1,r0); + KEYMIX(r1,r3,r4,r0,r2,28); + + /* round 26 */ + ILINTRANS(r1,r3,r4,r0,r2); + I6(r1,r3,r4,r0,r2); + KEYMIX(r3,r4,r2,r0,r1,24); + + /* round 27 */ + ILINTRANS(r3,r4,r2,r0,r1); + I5(r3,r4,r2,r0,r1); + KEYMIX(r4,r1,r0,r2,r3,20); + + /* round 28 */ + ILINTRANS(r4,r1,r0,r2,r3); + I4(r4,r1,r0,r2,r3); + KEYMIX(r4,r2,r0,r3,r1,16); + + /* round 29 */ + ILINTRANS(r4,r2,r0,r3,r1); + I3(r4,r2,r0,r3,r1); + KEYMIX(r0,r2,r3,r4,r1,12); + + /* round 30 */ + ILINTRANS(r0,r2,r3,r4,r1); + I2(r0,r2,r3,r4,r1); + KEYMIX(r2,r1,r3,r4,r0,8); + + /* round 31 */ + ILINTRANS(r2,r1,r3,r4,r0); + I1(r2,r1,r3,r4,r0); + KEYMIX(r0,r2,r4,r3,r1,4); + + /* round 32 */ + ILINTRANS(r0,r2,r4,r3,r1); + I0(r0,r2,r4,r3,r1); + KEYMIX(r0,r1,r2,r3,r4,0); + +#ifdef BLOCK_SWAP + out_blk[3] = io_swap(r0); out_blk[2] = io_swap(r1); + out_blk[1] = io_swap(r2); out_blk[0] = io_swap(r3); +#else + out_blk[0] = r0; out_blk[1] = r1; out_blk[2] = r2; out_blk[3] = r3; +#endif + return 0; +}; + + diff -urN linux-2.4.29/net/ipsec/libcrypto/libserpent/serpent.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/serpent.h --- linux-2.4.29/net/ipsec/libcrypto/libserpent/serpent.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/serpent.h Thu Sep 5 05:43:55 2002 @@ -0,0 +1,17 @@ +#ifndef SERPENT_H +#define SERPENT_H +#ifdef __KERNEL__ +#include +#else +#include +#define u32 u_int32_t +#define u8 u_int8_t +#endif +struct serpent_context { + u32 keyinfo[140]; /* storage for the key schedule */ +}; +typedef struct serpent_context serpent_context; +int serpent_set_key(serpent_context *ctx, const u8 * in_key, int key_len); +int serpent_decrypt(serpent_context *ctx, const u8 * in_blk, u8 * out_blk); +int serpent_encrypt(serpent_context *ctx, const u8 * in_blk, u8 * out_blk); +#endif /* SERPENT_H */ diff -urN linux-2.4.29/net/ipsec/libcrypto/libserpent/serpent_cbc.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/serpent_cbc.c --- linux-2.4.29/net/ipsec/libcrypto/libserpent/serpent_cbc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/serpent_cbc.c Thu Sep 5 05:43:55 2002 @@ -0,0 +1,8 @@ +#ifdef __KERNEL__ +#include +#else +#include +#endif +#include "serpent_cbc.h" +#include "cbc_generic.h" +CBC_IMPL_BLK16(serpent_cbc_encrypt, serpent_context, u_int8_t *, serpent_encrypt, serpent_decrypt); diff -urN linux-2.4.29/net/ipsec/libcrypto/libserpent/serpent_cbc.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/serpent_cbc.h --- linux-2.4.29/net/ipsec/libcrypto/libserpent/serpent_cbc.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/serpent_cbc.h Thu Sep 5 05:43:55 2002 @@ -0,0 +1,3 @@ +/* Glue header */ +#include "serpent.h" +int serpent_cbc_encrypt(serpent_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt); diff -urN linux-2.4.29/net/ipsec/libcrypto/libserpent/test_main.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/test_main.c --- linux-2.4.29/net/ipsec/libcrypto/libserpent/test_main.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libserpent/test_main.c Thu Sep 5 05:43:55 2002 @@ -0,0 +1,34 @@ +#include +#include +#include "serpent_cbc.h" +#define BLOCK_SIZE 16 +#define KEY_SIZE 128 /* bits */ +#define KEY "1234567890123456" +#define STR "hola guaso como estaisss ... 012" +#define STRSZ (sizeof(STR)-1) + +#define BLKLEN BLOCK_SIZE +#define CONTEXT_T serpent_context +static int pretty_print(const unsigned char *buf, int count) { + int i=0; + for (;i asm/sx86-sol.s + as -o asm/sx86-sol.o asm/sx86-sol.s + rm -f asm/sx86-sol.s + +# a.out +asm/sx86-out.o: asm/sx86unix.cpp + $(CPP) -DOUT asm/sx86unix.cpp | as -o asm/sx86-out.o + +# bsdi +asm/sx86bsdi.o: asm/sx86unix.cpp + $(CPP) -DBSDI asm/sx86unix.cpp | sed 's/ :/:/' | as -o asm/sx86bsdi.o + +asm/sx86unix.cpp: asm/sha1-586.pl ../perlasm/x86asm.pl + (cd asm; $(PERL) sha1-586.pl cpp $(PROCESSOR) >sx86unix.cpp) + +files: + $(PERL) $(TOP)/util/files.pl Makefile.ssl >> $(TOP)/MINFO + +links: + @$(TOP)/util/point.sh Makefile.ssl Makefile + @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER) + @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST) + @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS) + +install: + @for i in $(EXHEADER) ; \ + do \ + (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \ + chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \ + done; + +tags: + ctags $(SRC) + +tests: + +lint: + lint -DLINT $(INCLUDES) $(SRC)>fluff + +depend: + $(MAKEDEPEND) $(INCLUDES) $(DEPFLAG) $(PROGS) $(LIBSRC) + +dclean: + $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new + mv -f Makefile.new $(MAKEFILE) + +clean: + rm -f asm/sx86unix.cpp *.o *.obj $(LIB) tags core .pure .nfs* *.old *.bak fluff asm/*.o + +# DO NOT DELETE THIS LINE -- make depend depends on it. diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha1/asm/README linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/asm/README --- linux-2.4.29/net/ipsec/libcrypto/libsha1/asm/README Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/asm/README Thu Sep 5 05:35:58 2002 @@ -0,0 +1 @@ +C2.pl works diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha1/asm/sha1-586.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/asm/sha1-586.pl --- linux-2.4.29/net/ipsec/libcrypto/libsha1/asm/sha1-586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/asm/sha1-586.pl Thu Sep 5 05:35:58 2002 @@ -0,0 +1,538 @@ +#!/usr/local/bin/perl + +$normal=0; + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"sha1-586.pl",$ARGV[$#ARGV] eq "386"); + +$A="eax"; +$B="ecx"; +$C="ebx"; +$D="edx"; +$E="edi"; +$T="esi"; +$tmp1="ebp"; + +$off=9*4; + +@K=(0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6); + +&sha1_block_data("sha1_block_asm_data_order"); + +&asm_finish(); + +sub Nn + { + local($p)=@_; + local(%n)=($A,$T,$B,$A,$C,$B,$D,$C,$E,$D,$T,$E); + return($n{$p}); + } + +sub Np + { + local($p)=@_; + local(%n)=($A,$T,$B,$A,$C,$B,$D,$C,$E,$D,$T,$E); + local(%n)=($A,$B,$B,$C,$C,$D,$D,$E,$E,$T,$T,$A); + return($n{$p}); + } + +sub Na + { + local($n)=@_; + return( (($n )&0x0f), + (($n+ 2)&0x0f), + (($n+ 8)&0x0f), + (($n+13)&0x0f), + (($n+ 1)&0x0f)); + } + +sub X_expand + { + local($in)=@_; + + &comment("First, load the words onto the stack in network byte order"); + for ($i=0; $i<16; $i+=2) + { + &mov($A,&DWP(($i+0)*4,$in,"",0));# unless $i == 0; + &mov($B,&DWP(($i+1)*4,$in,"",0)); + &bswap($A); + &bswap($B); + &mov(&swtmp($i+0),$A); + &mov(&swtmp($i+1),$B); + } + + &comment("We now have the X array on the stack"); + &comment("starting at sp-4"); + } + +# Rules of engagement +# F is always trashable at the start, the running total. +# E becomes the next F so it can be trashed after it has been 'accumulated' +# F becomes A in the next round. We don't need to access it much. +# During the X update part, the result ends up in $X[$n0]. + +sub BODY_00_15 + { + local($pos,$K,$X,$n,$a,$b,$c,$d,$e,$f)=@_; + +return if $n & 1; + &comment("00_15 $n"); + + &mov($f,$c); + + &mov($tmp1,$a); + &xor($f,$d); # F2 + + &rotl($tmp1,5); # A2 + + &and($f,$b); # F3 + &add($tmp1,$e); + + &rotr($b,1); # B1 <- F + &mov($e,&swtmp($n)); # G1 + + &rotr($b,1); # B1 <- F + &xor($f,$d); # F4 + + &lea($tmp1,&DWP($K,$tmp1,$e,1)); + +############################ +# &BODY_40_59( 0,$K[2],$X,42,$A,$B,$C,$D,$E,$T); +# &BODY_40_59( 0,$K[2],$X,43,$T,$A,$B,$C,$D,$E); +$n++; + local($n0,$n1,$n2,$n3,$np)=&Na($n); + ($b,$c,$d,$e,$f,$a)=($a,$b,$c,$d,$e,$f); + + &mov($f,$c); + + &add($a,$tmp1); # MOVED DOWN + &xor($f,$d); # F2 + + &mov($tmp1,$a); + &and($f,$b); # F3 + + &rotl($tmp1,5); # A2 + + &add($tmp1,$e); + &mov($e,&swtmp($n)); # G1 + + &rotr($b,1); # B1 <- F + &xor($f,$d); # F4 + + &rotr($b,1); # B1 <- F + &lea($tmp1,&DWP($K,$tmp1,$e,1)); + + &add($f,$tmp1); + } + +sub BODY_16_19 + { + local($pos,$K,$X,$n,$a,$b,$c,$d,$e,$f)=@_; + local($n0,$n1,$n2,$n3,$np)=&Na($n); + +return if $n & 1; + &comment("16_19 $n"); + + &nop() if ($pos < 0); +&mov($tmp1,&swtmp($n0)); # X1 + &mov($f,&swtmp($n1)); # X2 +&xor($f,$tmp1); # X3 + &mov($tmp1,&swtmp($n2)); # X4 +&xor($f,$tmp1); # X5 + &mov($tmp1,&swtmp($n3)); # X6 +&xor($f,$tmp1); # X7 - slot + &mov($tmp1,$c); # F1 +&rotl($f,1); # X8 - slot + &xor($tmp1,$d); # F2 +&mov(&swtmp($n0),$f); # X9 - anytime + &and($tmp1,$b); # F3 +&lea($f,&DWP($K,$f,$e,1)); # tot=X+K+e + &xor($tmp1,$d); # F4 +&mov($e,$a); # A1 + &add($f,$tmp1); # tot+=F(); + +&rotl($e,5); # A2 + +&rotr($b,1); # B1 <- F + &add($f,$e); # tot+=a + +############################ +# &BODY_40_59( 0,$K[2],$X,42,$A,$B,$C,$D,$E,$T); +# &BODY_40_59( 0,$K[2],$X,43,$T,$A,$B,$C,$D,$E); +$n++; + local($n0,$n1,$n2,$n3,$np)=&Na($n); + ($b,$c,$d,$e,$f,$a)=($a,$b,$c,$d,$e,$f); + + +&mov($f,&swtmp($n0)); # X1 + &mov($tmp1,&swtmp($n1)); # X2 +&xor($f,$tmp1); # X3 + &mov($tmp1,&swtmp($n2)); # X4 +&xor($f,$tmp1); # X5 + &mov($tmp1,&swtmp($n3)); # X6 +&rotr($c,1); #&rotr($b,1); # B1 <- F # MOVED DOWN + &xor($f,$tmp1); # X7 - slot +&rotl($f,1); # X8 - slot + &mov($tmp1,$c); # F1 +&xor($tmp1,$d); # F2 + &mov(&swtmp($n0),$f); # X9 - anytime +&and($tmp1,$b); # F3 + &lea($f,&DWP($K,$f,$e,1)); # tot=X+K+e + +&xor($tmp1,$d); # F4 + &mov($e,$a); # A1 + +&rotl($e,5); # A2 + +&rotr($b,1); # B1 <- F + &add($f,$e); # tot+=a + +&rotr($b,1); # B1 <- F + &add($f,$tmp1); # tot+=F(); + + } + +sub BODY_20_39 + { + local($pos,$K,$X,$n,$a,$b,$c,$d,$e,$f)=@_; + + &comment("20_39 $n"); + local($n0,$n1,$n2,$n3,$np)=&Na($n); + +&mov($f,&swtmp($n0)); # X1 + &mov($tmp1,&swtmp($n1)); # X2 +&xor($f,$tmp1); # X3 + &mov($tmp1,&swtmp($n2)); # X4 +&xor($f,$tmp1); # X5 + &mov($tmp1,&swtmp($n3)); # X6 +&xor($f,$tmp1); # X7 - slot + &mov($tmp1,$b); # F1 +&rotl($f,1); # X8 - slot + &xor($tmp1,$c); # F2 +&mov(&swtmp($n0),$f); # X9 - anytime + &xor($tmp1,$d); # F3 + +&lea($f,&DWP($K,$f,$e,1)); # tot=X+K+e + &mov($e,$a); # A1 + +&rotl($e,5); # A2 + +if ($n != 79) # last loop + { + &rotr($b,1); # B1 <- F + &add($e,$tmp1); # tmp1=F()+a + + &rotr($b,1); # B2 <- F + &add($f,$e); # tot+=tmp1; + } +else + { + &add($e,$tmp1); # tmp1=F()+a + &mov($tmp1,&wparam(0)); + + &rotr($b,1); # B1 <- F + &add($f,$e); # tot+=tmp1; + + &rotr($b,1); # B2 <- F + } + } + +sub BODY_40_59 + { + local($pos,$K,$X,$n,$a,$b,$c,$d,$e,$f)=@_; + + &comment("40_59 $n"); + return if $n & 1; + local($n0,$n1,$n2,$n3,$np)=&Na($n); + +&mov($f,&swtmp($n0)); # X1 + &mov($tmp1,&swtmp($n1)); # X2 +&xor($f,$tmp1); # X3 + &mov($tmp1,&swtmp($n2)); # X4 +&xor($f,$tmp1); # X5 + &mov($tmp1,&swtmp($n3)); # X6 +&xor($f,$tmp1); # X7 - slot + &mov($tmp1,$b); # F1 +&rotl($f,1); # X8 - slot + &or($tmp1,$c); # F2 +&mov(&swtmp($n0),$f); # X9 - anytime + &and($tmp1,$d); # F3 + +&lea($f,&DWP($K,$f,$e,1)); # tot=X+K+e + &mov($e,$b); # F4 + +&rotr($b,1); # B1 <- F + &and($e,$c); # F5 + +&or($tmp1,$e); # F6 + &mov($e,$a); # A1 + +&rotl($e,5); # A2 + +&add($tmp1,$e); # tmp1=F()+a + +############################ +# &BODY_40_59( 0,$K[2],$X,42,$A,$B,$C,$D,$E,$T); +# &BODY_40_59( 0,$K[2],$X,43,$T,$A,$B,$C,$D,$E); +$n++; + local($n0,$n1,$n2,$n3,$np)=&Na($n); + ($b,$c,$d,$e,$f,$a)=($a,$b,$c,$d,$e,$f); + + &mov($f,&swtmp($n0)); # X1 +&add($a,$tmp1); # tot+=tmp1; # moved was add f,tmp1 + &mov($tmp1,&swtmp($n1)); # X2 +&xor($f,$tmp1); # X3 + &mov($tmp1,&swtmp($n2)); # X4 +&xor($f,$tmp1); # X5 + &mov($tmp1,&swtmp($n3)); # X6 +&rotr($c,1); # B2 <- F # moved was rotr b,1 + &xor($f,$tmp1); # X7 - slot +&rotl($f,1); # X8 - slot + &mov($tmp1,$b); # F1 +&mov(&swtmp($n0),$f); # X9 - anytime + &or($tmp1,$c); # F2 +&lea($f,&DWP($K,$f,$e,1)); # tot=X+K+e + &mov($e,$b); # F4 +&and($tmp1,$d); # F3 + &and($e,$c); # F5 + +&or($tmp1,$e); # F6 + &mov($e,$a); # A1 + +&rotl($e,5); # A2 + +&rotr($b,1); # B1 <- F + &add($tmp1,$e); # tmp1=F()+a + +&rotr($b,1); # B2 <- F + &add($f,$tmp1); # tot+=tmp1; + } + +sub BODY_60_79 + { + &BODY_20_39(@_); + } + +sub sha1_block_host + { + local($name)=@_; + + &function_begin_B($name,""); + + # parameter 1 is the MD5_CTX structure. + # A 0 + # B 4 + # C 8 + # D 12 + # E 16 + + &mov("ecx", &wparam(2)); + &push("esi"); + &shl("ecx",6); + &mov("esi", &wparam(1)); + &push("ebp"); + &add("ecx","esi"); # offset to leave on + &push("ebx"); + &mov("ebp", &wparam(0)); + &push("edi"); + &mov($D, &DWP(12,"ebp","",0)); + &stack_push(18+9); + &mov($E, &DWP(16,"ebp","",0)); + &mov($C, &DWP( 8,"ebp","",0)); + &mov(&swtmp(17),"ecx"); + + &comment("First we need to setup the X array"); + + for ($i=0; $i<16; $i+=2) + { + &mov($A,&DWP(($i+0)*4,"esi","",0));# unless $i == 0; + &mov($B,&DWP(($i+1)*4,"esi","",0)); + &mov(&swtmp($i+0),$A); + &mov(&swtmp($i+1),$B); + } + &jmp(&label("shortcut")); + &function_end_B($name); + } + + +sub sha1_block_data + { + local($name)=@_; + + &function_begin_B($name,""); + + # parameter 1 is the MD5_CTX structure. + # A 0 + # B 4 + # C 8 + # D 12 + # E 16 + + &mov("ecx", &wparam(2)); + &push("esi"); + &shl("ecx",6); + &mov("esi", &wparam(1)); + &push("ebp"); + &add("ecx","esi"); # offset to leave on + &push("ebx"); + &mov("ebp", &wparam(0)); + &push("edi"); + &mov($D, &DWP(12,"ebp","",0)); + &stack_push(18+9); + &mov($E, &DWP(16,"ebp","",0)); + &mov($C, &DWP( 8,"ebp","",0)); + &mov(&swtmp(17),"ecx"); + + &comment("First we need to setup the X array"); + + &set_label("start") unless $normal; + + &X_expand("esi"); + &mov(&wparam(1),"esi"); + + &set_label("shortcut", 0, 1); + &comment(""); + &comment("Start processing"); + + # odd start + &mov($A, &DWP( 0,"ebp","",0)); + &mov($B, &DWP( 4,"ebp","",0)); + $X="esp"; + &BODY_00_15(-2,$K[0],$X, 0,$A,$B,$C,$D,$E,$T); + &BODY_00_15( 0,$K[0],$X, 1,$T,$A,$B,$C,$D,$E); + &BODY_00_15( 0,$K[0],$X, 2,$E,$T,$A,$B,$C,$D); + &BODY_00_15( 0,$K[0],$X, 3,$D,$E,$T,$A,$B,$C); + &BODY_00_15( 0,$K[0],$X, 4,$C,$D,$E,$T,$A,$B); + &BODY_00_15( 0,$K[0],$X, 5,$B,$C,$D,$E,$T,$A); + &BODY_00_15( 0,$K[0],$X, 6,$A,$B,$C,$D,$E,$T); + &BODY_00_15( 0,$K[0],$X, 7,$T,$A,$B,$C,$D,$E); + &BODY_00_15( 0,$K[0],$X, 8,$E,$T,$A,$B,$C,$D); + &BODY_00_15( 0,$K[0],$X, 9,$D,$E,$T,$A,$B,$C); + &BODY_00_15( 0,$K[0],$X,10,$C,$D,$E,$T,$A,$B); + &BODY_00_15( 0,$K[0],$X,11,$B,$C,$D,$E,$T,$A); + &BODY_00_15( 0,$K[0],$X,12,$A,$B,$C,$D,$E,$T); + &BODY_00_15( 0,$K[0],$X,13,$T,$A,$B,$C,$D,$E); + &BODY_00_15( 0,$K[0],$X,14,$E,$T,$A,$B,$C,$D); + &BODY_00_15( 1,$K[0],$X,15,$D,$E,$T,$A,$B,$C); + &BODY_16_19(-1,$K[0],$X,16,$C,$D,$E,$T,$A,$B); + &BODY_16_19( 0,$K[0],$X,17,$B,$C,$D,$E,$T,$A); + &BODY_16_19( 0,$K[0],$X,18,$A,$B,$C,$D,$E,$T); + &BODY_16_19( 1,$K[0],$X,19,$T,$A,$B,$C,$D,$E); + + &BODY_20_39(-1,$K[1],$X,20,$E,$T,$A,$B,$C,$D); + &BODY_20_39( 0,$K[1],$X,21,$D,$E,$T,$A,$B,$C); + &BODY_20_39( 0,$K[1],$X,22,$C,$D,$E,$T,$A,$B); + &BODY_20_39( 0,$K[1],$X,23,$B,$C,$D,$E,$T,$A); + &BODY_20_39( 0,$K[1],$X,24,$A,$B,$C,$D,$E,$T); + &BODY_20_39( 0,$K[1],$X,25,$T,$A,$B,$C,$D,$E); + &BODY_20_39( 0,$K[1],$X,26,$E,$T,$A,$B,$C,$D); + &BODY_20_39( 0,$K[1],$X,27,$D,$E,$T,$A,$B,$C); + &BODY_20_39( 0,$K[1],$X,28,$C,$D,$E,$T,$A,$B); + &BODY_20_39( 0,$K[1],$X,29,$B,$C,$D,$E,$T,$A); + &BODY_20_39( 0,$K[1],$X,30,$A,$B,$C,$D,$E,$T); + &BODY_20_39( 0,$K[1],$X,31,$T,$A,$B,$C,$D,$E); + &BODY_20_39( 0,$K[1],$X,32,$E,$T,$A,$B,$C,$D); + &BODY_20_39( 0,$K[1],$X,33,$D,$E,$T,$A,$B,$C); + &BODY_20_39( 0,$K[1],$X,34,$C,$D,$E,$T,$A,$B); + &BODY_20_39( 0,$K[1],$X,35,$B,$C,$D,$E,$T,$A); + &BODY_20_39( 0,$K[1],$X,36,$A,$B,$C,$D,$E,$T); + &BODY_20_39( 0,$K[1],$X,37,$T,$A,$B,$C,$D,$E); + &BODY_20_39( 0,$K[1],$X,38,$E,$T,$A,$B,$C,$D); + &BODY_20_39( 1,$K[1],$X,39,$D,$E,$T,$A,$B,$C); + + &BODY_40_59(-1,$K[2],$X,40,$C,$D,$E,$T,$A,$B); + &BODY_40_59( 0,$K[2],$X,41,$B,$C,$D,$E,$T,$A); + &BODY_40_59( 0,$K[2],$X,42,$A,$B,$C,$D,$E,$T); + &BODY_40_59( 0,$K[2],$X,43,$T,$A,$B,$C,$D,$E); + &BODY_40_59( 0,$K[2],$X,44,$E,$T,$A,$B,$C,$D); + &BODY_40_59( 0,$K[2],$X,45,$D,$E,$T,$A,$B,$C); + &BODY_40_59( 0,$K[2],$X,46,$C,$D,$E,$T,$A,$B); + &BODY_40_59( 0,$K[2],$X,47,$B,$C,$D,$E,$T,$A); + &BODY_40_59( 0,$K[2],$X,48,$A,$B,$C,$D,$E,$T); + &BODY_40_59( 0,$K[2],$X,49,$T,$A,$B,$C,$D,$E); + &BODY_40_59( 0,$K[2],$X,50,$E,$T,$A,$B,$C,$D); + &BODY_40_59( 0,$K[2],$X,51,$D,$E,$T,$A,$B,$C); + &BODY_40_59( 0,$K[2],$X,52,$C,$D,$E,$T,$A,$B); + &BODY_40_59( 0,$K[2],$X,53,$B,$C,$D,$E,$T,$A); + &BODY_40_59( 0,$K[2],$X,54,$A,$B,$C,$D,$E,$T); + &BODY_40_59( 0,$K[2],$X,55,$T,$A,$B,$C,$D,$E); + &BODY_40_59( 0,$K[2],$X,56,$E,$T,$A,$B,$C,$D); + &BODY_40_59( 0,$K[2],$X,57,$D,$E,$T,$A,$B,$C); + &BODY_40_59( 0,$K[2],$X,58,$C,$D,$E,$T,$A,$B); + &BODY_40_59( 1,$K[2],$X,59,$B,$C,$D,$E,$T,$A); + + &BODY_60_79(-1,$K[3],$X,60,$A,$B,$C,$D,$E,$T); + &BODY_60_79( 0,$K[3],$X,61,$T,$A,$B,$C,$D,$E); + &BODY_60_79( 0,$K[3],$X,62,$E,$T,$A,$B,$C,$D); + &BODY_60_79( 0,$K[3],$X,63,$D,$E,$T,$A,$B,$C); + &BODY_60_79( 0,$K[3],$X,64,$C,$D,$E,$T,$A,$B); + &BODY_60_79( 0,$K[3],$X,65,$B,$C,$D,$E,$T,$A); + &BODY_60_79( 0,$K[3],$X,66,$A,$B,$C,$D,$E,$T); + &BODY_60_79( 0,$K[3],$X,67,$T,$A,$B,$C,$D,$E); + &BODY_60_79( 0,$K[3],$X,68,$E,$T,$A,$B,$C,$D); + &BODY_60_79( 0,$K[3],$X,69,$D,$E,$T,$A,$B,$C); + &BODY_60_79( 0,$K[3],$X,70,$C,$D,$E,$T,$A,$B); + &BODY_60_79( 0,$K[3],$X,71,$B,$C,$D,$E,$T,$A); + &BODY_60_79( 0,$K[3],$X,72,$A,$B,$C,$D,$E,$T); + &BODY_60_79( 0,$K[3],$X,73,$T,$A,$B,$C,$D,$E); + &BODY_60_79( 0,$K[3],$X,74,$E,$T,$A,$B,$C,$D); + &BODY_60_79( 0,$K[3],$X,75,$D,$E,$T,$A,$B,$C); + &BODY_60_79( 0,$K[3],$X,76,$C,$D,$E,$T,$A,$B); + &BODY_60_79( 0,$K[3],$X,77,$B,$C,$D,$E,$T,$A); + &BODY_60_79( 0,$K[3],$X,78,$A,$B,$C,$D,$E,$T); + &BODY_60_79( 2,$K[3],$X,79,$T,$A,$B,$C,$D,$E); + + &comment("End processing"); + &comment(""); + # D is the tmp value + + # E -> A + # T -> B + # A -> C + # B -> D + # C -> E + # D -> T + + # The last 2 have been moved into the last loop + # &mov($tmp1,&wparam(0)); + + &mov($D, &DWP(12,$tmp1,"",0)); + &add($D,$B); + &mov($B, &DWP( 4,$tmp1,"",0)); + &add($B,$T); + &mov($T, $A); + &mov($A, &DWP( 0,$tmp1,"",0)); + &mov(&DWP(12,$tmp1,"",0),$D); + + &add($A,$E); + &mov($E, &DWP(16,$tmp1,"",0)); + &add($E,$C); + &mov($C, &DWP( 8,$tmp1,"",0)); + &add($C,$T); + + &mov(&DWP( 0,$tmp1,"",0),$A); + &mov("esi",&wparam(1)); + &mov(&DWP( 8,$tmp1,"",0),$C); + &add("esi",64); + &mov("eax",&swtmp(17)); + &mov(&DWP(16,$tmp1,"",0),$E); + &cmp("esi","eax"); + &mov(&DWP( 4,$tmp1,"",0),$B); + &jl(&label("start")); + + &stack_pop(18+9); + &pop("edi"); + &pop("ebx"); + &pop("ebp"); + &pop("esi"); + &ret(); + + # it has to reside within sha1_block_asm_host_order body + # because it calls &jmp(&label("shortcut")); + &sha1_block_host("sha1_block_asm_host_order"); + + &function_end_B($name); + } + diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha1/hmac_sha1.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/hmac_sha1.c --- linux-2.4.29/net/ipsec/libcrypto/libsha1/hmac_sha1.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/hmac_sha1.c Thu Sep 5 05:32:56 2002 @@ -0,0 +1,26 @@ +#include +#include +#include "hmac_generic.h" +#include "sha.h" +#include "hmac_sha1.h" + +#if 0 +#define SHA1_Final SHA1Final +#define SHA1_Init SHA1Init +#define SHA1_Update SHA1Update +#endif +void inline sha1_result(SHA1_CTX *ctx, __u8 * hash, int hashlen) { + if (hashlen==SHA1_HASHLEN) + SHA1_Final(hash, ctx); + else { + __u8 hash_buf[SHA1_HASHLEN]; + SHA1_Final(hash_buf, ctx); + memcpy(hash, hash_buf, hashlen); + } +} +HMAC_SET_KEY_IMPL (sha1_hmac_set_key, + sha1_hmac_context, SHA1_BLOCKSIZE, + SHA1_Init, SHA1_Update) +HMAC_HASH_IMPL (sha1_hmac_hash, + sha1_hmac_context, SHA1_CTX, SHA1_HASHLEN, + SHA1_Update, sha1_result) diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha1/hmac_sha1.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/hmac_sha1.h --- linux-2.4.29/net/ipsec/libcrypto/libsha1/hmac_sha1.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/hmac_sha1.h Thu Sep 5 05:32:56 2002 @@ -0,0 +1,10 @@ +#include "sha.h" +#define SHA1_CTX SHA_CTX +typedef struct { + SHA1_CTX ictx,octx; +} sha1_hmac_context; +#define SHA1_BLOCKSIZE 64 +#define SHA1_HASHLEN 20 + +void sha1_hmac_hash(sha1_hmac_context *hctx, const __u8 * dat, int len, __u8 * hash, int hashlen); +void sha1_hmac_set_key(sha1_hmac_context *hctx, const __u8 * key, int keylen); diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha1/sha.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha.h --- linux-2.4.29/net/ipsec/libcrypto/libsha1/sha.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha.h Fri Feb 7 14:14:26 2003 @@ -0,0 +1,127 @@ +/* crypto/sha/sha.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SHA_H +#define HEADER_SHA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(NO_SHA) || (defined(NO_SHA0) && defined(NO_SHA1)) +#error SHA is disabled. +#endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! SHA_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#if defined(WIN16) || defined(__LP32__) +#define SHA_LONG unsigned long +#elif defined(_CRAY) || defined(__ILP64__) +#define SHA_LONG unsigned long +#define SHA_LONG_LOG2 3 +#endif + +/* des.h-like hack */ +#ifndef SHA_LONG +#ifdef __KERNEL__ +#include +#else +#include +#endif +#define SHA_LONG u_int32_t +#endif + +#define SHA_LBLOCK 16 +#define SHA_CBLOCK (SHA_LBLOCK*4) /* SHA treats input data as a + * contiguous array of 32 bit + * wide big-endian values. */ +#define SHA_LAST_BLOCK (SHA_CBLOCK-8) +#define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st + { + SHA_LONG h0,h1,h2,h3,h4; + SHA_LONG Nl,Nh; + SHA_LONG data[SHA_LBLOCK]; + int num; + } SHA_CTX; + +#ifndef NO_SHA0 +void SHA_Init(SHA_CTX *c); +void SHA_Update(SHA_CTX *c, const void *data, unsigned long len); +void SHA_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA(const unsigned char *d, unsigned long n,unsigned char *md); +void SHA_Transform(SHA_CTX *c, const unsigned char *data); +#endif +#ifndef NO_SHA1 +void SHA1_Init(SHA_CTX *c); +void SHA1_Update(SHA_CTX *c, const void *data, unsigned long len); +void SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); +#endif +#ifdef __cplusplus +} +#endif + +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha1/sha1_one.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha1_one.c --- linux-2.4.29/net/ipsec/libcrypto/libsha1/sha1_one.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha1_one.c Fri Feb 7 14:14:26 2003 @@ -0,0 +1,81 @@ +/* crypto/sha/sha1_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif +#include "sha.h" + +#ifndef NO_SHA1 +unsigned char *SHA1(const unsigned char *d, unsigned long n, unsigned char *md) + { + SHA_CTX c; + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) md=m; + SHA1_Init(&c); + SHA1_Update(&c,d,n); + SHA1_Final(md,&c); + memset(&c,0,sizeof(c)); + return(md); + } +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha1/sha1dgst.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha1dgst.c --- linux-2.4.29/net/ipsec/libcrypto/libsha1/sha1dgst.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha1dgst.c Fri Feb 7 14:14:26 2003 @@ -0,0 +1,78 @@ +/* crypto/sha/sha1dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#if !defined(NO_SHA1) && !defined(NO_SHA) + +#undef SHA_0 +#define SHA_1 + +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif + + +/* The implementation is in ../md32_common.h */ + +#include "sha_locl.h" + +#endif + diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha1/sha_dgst.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha_dgst.c --- linux-2.4.29/net/ipsec/libcrypto/libsha1/sha_dgst.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha_dgst.c Fri Feb 7 14:14:26 2003 @@ -0,0 +1,69 @@ +/* crypto/sha/sha1dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#if !defined(NO_SHA0) && !defined(NO_SHA) + +#undef SHA_1 +#define SHA_0 + +/* The implementation is in ../md32_common.h */ + +#include "sha_locl.h" + +#endif + diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha1/sha_locl.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha_locl.h --- linux-2.4.29/net/ipsec/libcrypto/libsha1/sha_locl.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha1/sha_locl.h Fri Feb 7 14:14:26 2003 @@ -0,0 +1,476 @@ +/* crypto/sha/sha_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifdef __KERNEL__ +#include +#include +#include "sha.h" +#else +#include +#include + +#include "sha.h" +#endif + +#ifndef SHA_LONG_LOG2 +#define SHA_LONG_LOG2 2 /* default to 32 bits */ +#endif + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_LONG SHA_LONG +#define HASH_LONG_LOG2 SHA_LONG_LOG2 +#define HASH_CTX SHA_CTX +#define HASH_CBLOCK SHA_CBLOCK +#define HASH_LBLOCK SHA_LBLOCK +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->h0; HOST_l2c(ll,(s)); \ + ll=(c)->h1; HOST_l2c(ll,(s)); \ + ll=(c)->h2; HOST_l2c(ll,(s)); \ + ll=(c)->h3; HOST_l2c(ll,(s)); \ + ll=(c)->h4; HOST_l2c(ll,(s)); \ + } while (0) + +#if defined(SHA_0) + +# define HASH_UPDATE SHA_Update +# define HASH_TRANSFORM SHA_Transform +# define HASH_FINAL SHA_Final +# define HASH_INIT SHA_Init +# define HASH_BLOCK_HOST_ORDER sha_block_host_order +# define HASH_BLOCK_DATA_ORDER sha_block_data_order +# define Xupdate(a,ix,ia,ib,ic,id) (ix=(a)=(ia^ib^ic^id)) + + void sha_block_host_order (SHA_CTX *c, const void *p,int num); + void sha_block_data_order (SHA_CTX *c, const void *p,int num); + +#elif defined(SHA_1) + +# define HASH_UPDATE SHA1_Update +# define HASH_TRANSFORM SHA1_Transform +# define HASH_FINAL SHA1_Final +# define HASH_INIT SHA1_Init +# define HASH_BLOCK_HOST_ORDER sha1_block_host_order +# define HASH_BLOCK_DATA_ORDER sha1_block_data_order +# if defined(__MWERKS__) && defined(__MC68K__) + /* Metrowerks for Motorola fails otherwise:-( */ +# define Xupdate(a,ix,ia,ib,ic,id) do { (a)=(ia^ib^ic^id); \ + ix=(a)=ROTATE((a),1); \ + } while (0) +# else +# define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \ + ix=(a)=ROTATE((a),1) \ + ) +# endif + +# ifdef SHA1_ASM +# if defined(__i386) || defined(_M_IX86) || defined(__INTEL__) +# define sha1_block_host_order sha1_block_asm_host_order +# define DONT_IMPLEMENT_BLOCK_HOST_ORDER +# define sha1_block_data_order sha1_block_asm_data_order +# define DONT_IMPLEMENT_BLOCK_DATA_ORDER +# define HASH_BLOCK_DATA_ORDER_ALIGNED sha1_block_asm_data_order +# endif +# endif + void sha1_block_host_order (SHA_CTX *c, const void *p,int num); + void sha1_block_data_order (SHA_CTX *c, const void *p,int num); + +#else +# error "Either SHA_0 or SHA_1 must be defined." +#endif + +#include "md32_common.h" + +#define INIT_DATA_h0 0x67452301UL +#define INIT_DATA_h1 0xefcdab89UL +#define INIT_DATA_h2 0x98badcfeUL +#define INIT_DATA_h3 0x10325476UL +#define INIT_DATA_h4 0xc3d2e1f0UL + +void HASH_INIT (SHA_CTX *c) + { + c->h0=INIT_DATA_h0; + c->h1=INIT_DATA_h1; + c->h2=INIT_DATA_h2; + c->h3=INIT_DATA_h3; + c->h4=INIT_DATA_h4; + c->Nl=0; + c->Nh=0; + c->num=0; + } + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +/* As pointed out by Wei Dai , F() below can be + * simplified to the code in F_00_19. Wei attributes these optimisations + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. + * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) + * I've just become aware of another tweak to be made, again from Wei Dai, + * in F_40_59, (x&a)|(y&a) -> (x|y)&a + */ +#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) +#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) +#define F_60_79(b,c,d) F_20_39(b,c,d) + +#define BODY_00_15(i,a,b,c,d,e,f,xi) \ + (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#ifdef X +#undef X +#endif +#ifndef MD32_XARRAY + /* + * Originally X was an array. As it's automatic it's natural + * to expect RISC compiler to accomodate at least part of it in + * the register bank, isn't it? Unfortunately not all compilers + * "find" this expectation reasonable:-( On order to make such + * compilers generate better code I replace X[] with a bunch of + * X0, X1, etc. See the function body below... + * + */ +# define X(i) XX##i +#else + /* + * However! Some compilers (most notably HP C) get overwhelmed by + * that many local variables so that we have to have the way to + * fall down to the original behavior. + */ +# define X(i) XX[i] +#endif + +#ifndef DONT_IMPLEMENT_BLOCK_HOST_ORDER +void HASH_BLOCK_HOST_ORDER (SHA_CTX *c, const void *d, int num) + { + const SHA_LONG *W=d; + register unsigned long A,B,C,D,E,T; +#ifndef MD32_XARRAY + unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; +#else + SHA_LONG XX[16]; +#endif + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + for (;;) + { + BODY_00_15( 0,A,B,C,D,E,T,W[ 0]); + BODY_00_15( 1,T,A,B,C,D,E,W[ 1]); + BODY_00_15( 2,E,T,A,B,C,D,W[ 2]); + BODY_00_15( 3,D,E,T,A,B,C,W[ 3]); + BODY_00_15( 4,C,D,E,T,A,B,W[ 4]); + BODY_00_15( 5,B,C,D,E,T,A,W[ 5]); + BODY_00_15( 6,A,B,C,D,E,T,W[ 6]); + BODY_00_15( 7,T,A,B,C,D,E,W[ 7]); + BODY_00_15( 8,E,T,A,B,C,D,W[ 8]); + BODY_00_15( 9,D,E,T,A,B,C,W[ 9]); + BODY_00_15(10,C,D,E,T,A,B,W[10]); + BODY_00_15(11,B,C,D,E,T,A,W[11]); + BODY_00_15(12,A,B,C,D,E,T,W[12]); + BODY_00_15(13,T,A,B,C,D,E,W[13]); + BODY_00_15(14,E,T,A,B,C,D,W[14]); + BODY_00_15(15,D,E,T,A,B,C,W[15]); + + BODY_16_19(16,C,D,E,T,A,B,X( 0),W[ 0],W[ 2],W[ 8],W[13]); + BODY_16_19(17,B,C,D,E,T,A,X( 1),W[ 1],W[ 3],W[ 9],W[14]); + BODY_16_19(18,A,B,C,D,E,T,X( 2),W[ 2],W[ 4],W[10],W[15]); + BODY_16_19(19,T,A,B,C,D,E,X( 3),W[ 3],W[ 5],W[11],X( 0)); + + BODY_20_31(20,E,T,A,B,C,D,X( 4),W[ 4],W[ 6],W[12],X( 1)); + BODY_20_31(21,D,E,T,A,B,C,X( 5),W[ 5],W[ 7],W[13],X( 2)); + BODY_20_31(22,C,D,E,T,A,B,X( 6),W[ 6],W[ 8],W[14],X( 3)); + BODY_20_31(23,B,C,D,E,T,A,X( 7),W[ 7],W[ 9],W[15],X( 4)); + BODY_20_31(24,A,B,C,D,E,T,X( 8),W[ 8],W[10],X( 0),X( 5)); + BODY_20_31(25,T,A,B,C,D,E,X( 9),W[ 9],W[11],X( 1),X( 6)); + BODY_20_31(26,E,T,A,B,C,D,X(10),W[10],W[12],X( 2),X( 7)); + BODY_20_31(27,D,E,T,A,B,C,X(11),W[11],W[13],X( 3),X( 8)); + BODY_20_31(28,C,D,E,T,A,B,X(12),W[12],W[14],X( 4),X( 9)); + BODY_20_31(29,B,C,D,E,T,A,X(13),W[13],W[15],X( 5),X(10)); + BODY_20_31(30,A,B,C,D,E,T,X(14),W[14],X( 0),X( 6),X(11)); + BODY_20_31(31,T,A,B,C,D,E,X(15),W[15],X( 1),X( 7),X(12)); + + BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13)); + BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14)); + BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15)); + BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0)); + BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1)); + BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2)); + BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3)); + BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4)); + + BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5)); + BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6)); + BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7)); + BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8)); + BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9)); + BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10)); + BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11)); + BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12)); + BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13)); + BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14)); + BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15)); + BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0)); + BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1)); + BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2)); + BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3)); + BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4)); + BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5)); + BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6)); + BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7)); + BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8)); + + BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9)); + BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10)); + BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11)); + BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12)); + BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13)); + BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14)); + BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15)); + BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0)); + BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1)); + BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2)); + BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3)); + BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4)); + BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5)); + BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6)); + BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7)); + BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8)); + BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9)); + BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10)); + BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11)); + BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12)); + + c->h0=(c->h0+E)&0xffffffffL; + c->h1=(c->h1+T)&0xffffffffL; + c->h2=(c->h2+A)&0xffffffffL; + c->h3=(c->h3+B)&0xffffffffL; + c->h4=(c->h4+C)&0xffffffffL; + + if (--num <= 0) break; + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + W+=SHA_LBLOCK; + } + } +#endif + +#ifndef DONT_IMPLEMENT_BLOCK_DATA_ORDER +void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, int num) + { + const unsigned char *data=p; + register unsigned long A,B,C,D,E,T,l; +#ifndef MD32_XARRAY + unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15; +#else + SHA_LONG XX[16]; +#endif + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + for (;;) + { + + HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l; + BODY_00_15( 0,A,B,C,D,E,T,X( 0)); HOST_c2l(data,l); X( 2)=l; + BODY_00_15( 1,T,A,B,C,D,E,X( 1)); HOST_c2l(data,l); X( 3)=l; + BODY_00_15( 2,E,T,A,B,C,D,X( 2)); HOST_c2l(data,l); X( 4)=l; + BODY_00_15( 3,D,E,T,A,B,C,X( 3)); HOST_c2l(data,l); X( 5)=l; + BODY_00_15( 4,C,D,E,T,A,B,X( 4)); HOST_c2l(data,l); X( 6)=l; + BODY_00_15( 5,B,C,D,E,T,A,X( 5)); HOST_c2l(data,l); X( 7)=l; + BODY_00_15( 6,A,B,C,D,E,T,X( 6)); HOST_c2l(data,l); X( 8)=l; + BODY_00_15( 7,T,A,B,C,D,E,X( 7)); HOST_c2l(data,l); X( 9)=l; + BODY_00_15( 8,E,T,A,B,C,D,X( 8)); HOST_c2l(data,l); X(10)=l; + BODY_00_15( 9,D,E,T,A,B,C,X( 9)); HOST_c2l(data,l); X(11)=l; + BODY_00_15(10,C,D,E,T,A,B,X(10)); HOST_c2l(data,l); X(12)=l; + BODY_00_15(11,B,C,D,E,T,A,X(11)); HOST_c2l(data,l); X(13)=l; + BODY_00_15(12,A,B,C,D,E,T,X(12)); HOST_c2l(data,l); X(14)=l; + BODY_00_15(13,T,A,B,C,D,E,X(13)); HOST_c2l(data,l); X(15)=l; + BODY_00_15(14,E,T,A,B,C,D,X(14)); + BODY_00_15(15,D,E,T,A,B,C,X(15)); + + BODY_16_19(16,C,D,E,T,A,B,X( 0),X( 0),X( 2),X( 8),X(13)); + BODY_16_19(17,B,C,D,E,T,A,X( 1),X( 1),X( 3),X( 9),X(14)); + BODY_16_19(18,A,B,C,D,E,T,X( 2),X( 2),X( 4),X(10),X(15)); + BODY_16_19(19,T,A,B,C,D,E,X( 3),X( 3),X( 5),X(11),X( 0)); + + BODY_20_31(20,E,T,A,B,C,D,X( 4),X( 4),X( 6),X(12),X( 1)); + BODY_20_31(21,D,E,T,A,B,C,X( 5),X( 5),X( 7),X(13),X( 2)); + BODY_20_31(22,C,D,E,T,A,B,X( 6),X( 6),X( 8),X(14),X( 3)); + BODY_20_31(23,B,C,D,E,T,A,X( 7),X( 7),X( 9),X(15),X( 4)); + BODY_20_31(24,A,B,C,D,E,T,X( 8),X( 8),X(10),X( 0),X( 5)); + BODY_20_31(25,T,A,B,C,D,E,X( 9),X( 9),X(11),X( 1),X( 6)); + BODY_20_31(26,E,T,A,B,C,D,X(10),X(10),X(12),X( 2),X( 7)); + BODY_20_31(27,D,E,T,A,B,C,X(11),X(11),X(13),X( 3),X( 8)); + BODY_20_31(28,C,D,E,T,A,B,X(12),X(12),X(14),X( 4),X( 9)); + BODY_20_31(29,B,C,D,E,T,A,X(13),X(13),X(15),X( 5),X(10)); + BODY_20_31(30,A,B,C,D,E,T,X(14),X(14),X( 0),X( 6),X(11)); + BODY_20_31(31,T,A,B,C,D,E,X(15),X(15),X( 1),X( 7),X(12)); + + BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13)); + BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14)); + BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15)); + BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0)); + BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1)); + BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2)); + BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3)); + BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4)); + + BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5)); + BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6)); + BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7)); + BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8)); + BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9)); + BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10)); + BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11)); + BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12)); + BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13)); + BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14)); + BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15)); + BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0)); + BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1)); + BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2)); + BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3)); + BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4)); + BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5)); + BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6)); + BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7)); + BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8)); + + BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9)); + BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10)); + BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11)); + BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12)); + BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13)); + BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14)); + BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15)); + BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0)); + BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1)); + BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2)); + BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3)); + BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4)); + BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5)); + BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6)); + BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7)); + BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8)); + BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9)); + BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10)); + BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11)); + BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12)); + + c->h0=(c->h0+E)&0xffffffffL; + c->h1=(c->h1+T)&0xffffffffL; + c->h2=(c->h2+A)&0xffffffffL; + c->h3=(c->h3+B)&0xffffffffL; + c->h4=(c->h4+C)&0xffffffffL; + + if (--num <= 0) break; + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + } + } +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha2/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/Makefile --- linux-2.4.29/net/ipsec/libcrypto/libsha2/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/Makefile Tue Jul 8 16:21:05 2003 @@ -0,0 +1,21 @@ +CFLAGS=-O3 -fomit-frame-pointer -I../include $(EXTRA_CFLAGS) + +LIBOBJ := hmac_sha2.o sha2.o + +BLIB := libsha2.a + +.S.o: + $(CC) $(AFLAGS) -c $< -o $@ + +$(BLIB): $(LIBOBJ) + /bin/rm -f $(BLIB) + ar cr $(BLIB) $(LIBOBJ) + -if test -s /bin/ranlib; then /bin/ranlib $(BLIB); \ + else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(BLIB); \ + else exit 0; fi; fi + +test: test_main.o $(BLIB) + $(CC) -o $@ $^ + +clean: + rm -f *.[oa] core $(TARGET) test diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha2/hmac_sha2.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/hmac_sha2.c --- linux-2.4.29/net/ipsec/libcrypto/libsha2/hmac_sha2.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/hmac_sha2.c Thu Sep 5 05:32:57 2002 @@ -0,0 +1,32 @@ +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif +#include "hmac_generic.h" +#include "sha2.h" +#include "hmac_sha2.h" + +void inline sha256_result(sha256_context *ctx, u_int8_t * hash, int hashlen) { + sha256_final(ctx); + memcpy(hash, &ctx->sha_out[0], hashlen); +} +void inline sha512_result(sha512_context *ctx, u_int8_t * hash, int hashlen) { + sha512_final(ctx); + memcpy(hash, &ctx->sha_out[0], hashlen); +} +HMAC_SET_KEY_IMPL (sha256_hmac_set_key, + sha256_hmac_context, SHA256_BLOCKSIZE, + sha256_init, sha256_write) +HMAC_HASH_IMPL (sha256_hmac_hash, + sha256_hmac_context, sha256_context, SHA256_HASHLEN, + sha256_write, sha256_result) + +HMAC_SET_KEY_IMPL (sha512_hmac_set_key, + sha512_hmac_context, SHA512_BLOCKSIZE, + sha512_init, sha512_write) +HMAC_HASH_IMPL (sha512_hmac_hash, + sha512_hmac_context, sha512_context, SHA512_HASHLEN, + sha512_write, sha512_result) diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha2/hmac_sha2.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/hmac_sha2.h --- linux-2.4.29/net/ipsec/libcrypto/libsha2/hmac_sha2.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/hmac_sha2.h Thu Sep 5 05:32:57 2002 @@ -0,0 +1,17 @@ +typedef struct { + sha256_context ictx,octx; +} sha256_hmac_context; +typedef struct { + sha512_context ictx,octx; +} sha512_hmac_context; +#define SHA256_BLOCKSIZE 64 +#define SHA256_HASHLEN 32 +#define SHA384_BLOCKSIZE 128 /* XXX ok? */ +#define SHA384_HASHLEN 48 +#define SHA512_BLOCKSIZE 128 +#define SHA512_HASHLEN 64 + +void sha256_hmac_hash(sha256_hmac_context *hctx, const u_int8_t * dat, int len, u_int8_t * hash, int hashlen); +void sha256_hmac_set_key(sha256_hmac_context *hctx, const u_int8_t * key, int keylen); +void sha512_hmac_hash(sha512_hmac_context *hctx, const u_int8_t * dat, int len, u_int8_t * hash, int hashlen); +void sha512_hmac_set_key(sha512_hmac_context *hctx, const u_int8_t * key, int keylen); diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha2/sha2.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/sha2.c --- linux-2.4.29/net/ipsec/libcrypto/libsha2/sha2.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/sha2.c Thu Sep 5 05:32:57 2002 @@ -0,0 +1,437 @@ +/* + * sha512.c + * + * Written by Jari Ruusu, April 16 2001 + * + * Copyright 2001 by Jari Ruusu. + * Redistribution of this file is permitted under the GNU Public License. + */ + +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#endif +#include "sha2.h" + +/* Define one or more of these. If none is defined, you get all of them */ +#if !defined(SHA256_NEEDED)&&!defined(SHA512_NEEDED)&&!defined(SHA384_NEEDED) +# define SHA256_NEEDED 1 +# define SHA512_NEEDED 1 +# define SHA384_NEEDED 1 +#endif + +#if defined(SHA256_NEEDED) +static const u_int32_t sha256_hashInit[8] = { + 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, + 0x1f83d9ab, 0x5be0cd19 +}; +static const u_int32_t sha256_K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; +#endif + +#if defined(SHA512_NEEDED) +static const u_int64_t sha512_hashInit[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; +#endif + +#if defined(SHA384_NEEDED) +static const u_int64_t sha384_hashInit[8] = { + 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL +}; +#endif + +#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED) +static const u_int64_t sha512_K[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, + 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, + 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, + 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, + 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, + 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, + 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, + 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, + 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, + 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, + 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, + 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, + 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; +#endif + +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#define R(x,y) ((y) >> (x)) + +#if defined(SHA256_NEEDED) +void sha256_init(sha256_context *ctx) +{ + memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H)); + ctx->sha_blocks = 0; + ctx->sha_bufCnt = 0; +} + +#define S(x,y) (((y) >> (x)) | ((y) << (32 - (x)))) +#define uSig0(x) ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x)))) +#define uSig1(x) ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x)))) +#define lSig0(x) ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x)))) +#define lSig1(x) ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x)))) + +static void sha256_transform(sha256_context *ctx, const unsigned char *datap) +{ + register int j; + u_int32_t a, b, c, d, e, f, g, h; + u_int32_t T1, T2, W[64], Wm2, Wm15; + + /* read the data, big endian byte order */ + j = 0; + do { + W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) | + (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_t)(datap[3])); + datap += 4; + } while(++j < 16); + + /* initialize variables a...h */ + a = ctx->sha_H[0]; + b = ctx->sha_H[1]; + c = ctx->sha_H[2]; + d = ctx->sha_H[3]; + e = ctx->sha_H[4]; + f = ctx->sha_H[5]; + g = ctx->sha_H[6]; + h = ctx->sha_H[7]; + + /* apply compression function */ + j = 0; + do { + if(j >= 16) { + Wm2 = W[j - 2]; + Wm15 = W[j - 15]; + W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16]; + } + T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j]; + T2 = uSig0(a) + Maj(a,b,c); + h = g; g = f; f = e; + e = d + T1; + d = c; c = b; b = a; + a = T1 + T2; + } while(++j < 64); + + /* compute intermediate hash value */ + ctx->sha_H[0] += a; + ctx->sha_H[1] += b; + ctx->sha_H[2] += c; + ctx->sha_H[3] += d; + ctx->sha_H[4] += e; + ctx->sha_H[5] += f; + ctx->sha_H[6] += g; + ctx->sha_H[7] += h; + + ctx->sha_blocks++; +} + +void sha256_write(sha256_context *ctx, const unsigned char *datap, int length) +{ + while(length > 0) { + if(!ctx->sha_bufCnt) { + while(length >= sizeof(ctx->sha_out)) { + sha256_transform(ctx, datap); + datap += sizeof(ctx->sha_out); + length -= sizeof(ctx->sha_out); + } + if(!length) return; + } + ctx->sha_out[ctx->sha_bufCnt] = *datap++; + length--; + if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) { + sha256_transform(ctx, &ctx->sha_out[0]); + ctx->sha_bufCnt = 0; + } + } +} + +void sha256_final(sha256_context *ctx) +{ + register int j; + u_int64_t bitLength; + u_int32_t i; + unsigned char padByte, *datap; + + bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3); + padByte = 0x80; + sha256_write(ctx, &padByte, 1); + + /* pad extra space with zeroes */ + padByte = 0; + while(ctx->sha_bufCnt != 56) { + sha256_write(ctx, &padByte, 1); + } + + /* write bit length, big endian byte order */ + ctx->sha_out[56] = bitLength >> 56; + ctx->sha_out[57] = bitLength >> 48; + ctx->sha_out[58] = bitLength >> 40; + ctx->sha_out[59] = bitLength >> 32; + ctx->sha_out[60] = bitLength >> 24; + ctx->sha_out[61] = bitLength >> 16; + ctx->sha_out[62] = bitLength >> 8; + ctx->sha_out[63] = bitLength; + sha256_transform(ctx, &ctx->sha_out[0]); + + /* return results in ctx->sha_out[0...31] */ + datap = &ctx->sha_out[0]; + j = 0; + do { + i = ctx->sha_H[j]; + datap[0] = i >> 24; + datap[1] = i >> 16; + datap[2] = i >> 8; + datap[3] = i; + datap += 4; + } while(++j < 8); + + /* clear sensitive information */ + memset(&ctx->sha_out[32], 0, sizeof(sha256_context) - 32); +} + +void sha256_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole) +{ + sha256_context ctx; + + if(ole < 1) return; + memset(ob, 0, ole); + if(ole > 32) ole = 32; + sha256_init(&ctx); + sha256_write(&ctx, ib, ile); + sha256_final(&ctx); + memcpy(ob, &ctx.sha_out[0], ole); + memset(&ctx, 0, sizeof(ctx)); +} + +#endif + +#if defined(SHA512_NEEDED) +void sha512_init(sha512_context *ctx) +{ + memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H)); + ctx->sha_blocks = 0; + ctx->sha_blocksMSB = 0; + ctx->sha_bufCnt = 0; +} +#endif + +#if defined(SHA512_NEEDED) || defined(SHA384_NEEDED) +#undef S +#undef uSig0 +#undef uSig1 +#undef lSig0 +#undef lSig1 +#define S(x,y) (((y) >> (x)) | ((y) << (64 - (x)))) +#define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x)))) +#define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x)))) +#define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x)))) +#define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x)))) + +static void sha512_transform(sha512_context *ctx, const unsigned char *datap) +{ + register int j; + u_int64_t a, b, c, d, e, f, g, h; + u_int64_t T1, T2, W[80], Wm2, Wm15; + + /* read the data, big endian byte order */ + j = 0; + do { + W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) | + (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) | + (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) | + (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_t)(datap[7])); + datap += 8; + } while(++j < 16); + + /* initialize variables a...h */ + a = ctx->sha_H[0]; + b = ctx->sha_H[1]; + c = ctx->sha_H[2]; + d = ctx->sha_H[3]; + e = ctx->sha_H[4]; + f = ctx->sha_H[5]; + g = ctx->sha_H[6]; + h = ctx->sha_H[7]; + + /* apply compression function */ + j = 0; + do { + if(j >= 16) { + Wm2 = W[j - 2]; + Wm15 = W[j - 15]; + W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16]; + } + T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j]; + T2 = uSig0(a) + Maj(a,b,c); + h = g; g = f; f = e; + e = d + T1; + d = c; c = b; b = a; + a = T1 + T2; + } while(++j < 80); + + /* compute intermediate hash value */ + ctx->sha_H[0] += a; + ctx->sha_H[1] += b; + ctx->sha_H[2] += c; + ctx->sha_H[3] += d; + ctx->sha_H[4] += e; + ctx->sha_H[5] += f; + ctx->sha_H[6] += g; + ctx->sha_H[7] += h; + + ctx->sha_blocks++; + if(!ctx->sha_blocks) ctx->sha_blocksMSB++; +} + +void sha512_write(sha512_context *ctx, const unsigned char *datap, int length) +{ + while(length > 0) { + if(!ctx->sha_bufCnt) { + while(length >= sizeof(ctx->sha_out)) { + sha512_transform(ctx, datap); + datap += sizeof(ctx->sha_out); + length -= sizeof(ctx->sha_out); + } + if(!length) return; + } + ctx->sha_out[ctx->sha_bufCnt] = *datap++; + length--; + if(++ctx->sha_bufCnt == sizeof(ctx->sha_out)) { + sha512_transform(ctx, &ctx->sha_out[0]); + ctx->sha_bufCnt = 0; + } + } +} + +void sha512_final(sha512_context *ctx) +{ + register int j; + u_int64_t bitLength, bitLengthMSB; + u_int64_t i; + unsigned char padByte, *datap; + + bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3); + bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54); + padByte = 0x80; + sha512_write(ctx, &padByte, 1); + + /* pad extra space with zeroes */ + padByte = 0; + while(ctx->sha_bufCnt != 112) { + sha512_write(ctx, &padByte, 1); + } + + /* write bit length, big endian byte order */ + ctx->sha_out[112] = bitLengthMSB >> 56; + ctx->sha_out[113] = bitLengthMSB >> 48; + ctx->sha_out[114] = bitLengthMSB >> 40; + ctx->sha_out[115] = bitLengthMSB >> 32; + ctx->sha_out[116] = bitLengthMSB >> 24; + ctx->sha_out[117] = bitLengthMSB >> 16; + ctx->sha_out[118] = bitLengthMSB >> 8; + ctx->sha_out[119] = bitLengthMSB; + ctx->sha_out[120] = bitLength >> 56; + ctx->sha_out[121] = bitLength >> 48; + ctx->sha_out[122] = bitLength >> 40; + ctx->sha_out[123] = bitLength >> 32; + ctx->sha_out[124] = bitLength >> 24; + ctx->sha_out[125] = bitLength >> 16; + ctx->sha_out[126] = bitLength >> 8; + ctx->sha_out[127] = bitLength; + sha512_transform(ctx, &ctx->sha_out[0]); + + /* return results in ctx->sha_out[0...63] */ + datap = &ctx->sha_out[0]; + j = 0; + do { + i = ctx->sha_H[j]; + datap[0] = i >> 56; + datap[1] = i >> 48; + datap[2] = i >> 40; + datap[3] = i >> 32; + datap[4] = i >> 24; + datap[5] = i >> 16; + datap[6] = i >> 8; + datap[7] = i; + datap += 8; + } while(++j < 8); + + /* clear sensitive information */ + memset(&ctx->sha_out[64], 0, sizeof(sha512_context) - 64); +} + +void sha512_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole) +{ + sha512_context ctx; + + if(ole < 1) return; + memset(ob, 0, ole); + if(ole > 64) ole = 64; + sha512_init(&ctx); + sha512_write(&ctx, ib, ile); + sha512_final(&ctx); + memcpy(ob, &ctx.sha_out[0], ole); + memset(&ctx, 0, sizeof(ctx)); +} +#endif + +#if defined(SHA384_NEEDED) +void sha384_init(sha512_context *ctx) +{ + memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H)); + ctx->sha_blocks = 0; + ctx->sha_blocksMSB = 0; + ctx->sha_bufCnt = 0; +} + +void sha384_hash_buffer(unsigned char *ib, int ile, unsigned char *ob, int ole) +{ + sha512_context ctx; + + if(ole < 1) return; + memset(ob, 0, ole); + if(ole > 48) ole = 48; + sha384_init(&ctx); + sha512_write(&ctx, ib, ile); + sha512_final(&ctx); + memcpy(ob, &ctx.sha_out[0], ole); + memset(&ctx, 0, sizeof(ctx)); +} +#endif diff -urN linux-2.4.29/net/ipsec/libcrypto/libsha2/sha2.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/sha2.h --- linux-2.4.29/net/ipsec/libcrypto/libsha2/sha2.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libsha2/sha2.h Thu Sep 5 05:32:57 2002 @@ -0,0 +1,52 @@ +#ifndef _SHA2_H +#define _SHA2_H +/* + * sha512.h + * + * Written by Jari Ruusu, April 16 2001 + * + * Copyright 2001 by Jari Ruusu. + * Redistribution of this file is permitted under the GNU Public License. + */ + +#ifdef __KERNEL__ +#include +#else +#include +#endif + +typedef struct { + unsigned char sha_out[64]; /* results are here, bytes 0...31 */ + u_int32_t sha_H[8]; + u_int64_t sha_blocks; + int sha_bufCnt; +} sha256_context; + +typedef struct { + unsigned char sha_out[128]; /* results are here, bytes 0...63 */ + u_int64_t sha_H[8]; + u_int64_t sha_blocks; + u_int64_t sha_blocksMSB; + int sha_bufCnt; +} sha512_context; + +/* no sha384_context, use sha512_context */ + +/* 256 bit hash, provides 128 bits of security against collision attacks */ +extern void sha256_init(sha256_context *); +extern void sha256_write(sha256_context *, const unsigned char *, int); +extern void sha256_final(sha256_context *); +extern void sha256_hash_buffer(unsigned char *, int, unsigned char *, int); + +/* 512 bit hash, provides 256 bits of security against collision attacks */ +extern void sha512_init(sha512_context *); +extern void sha512_write(sha512_context *, const unsigned char *, int); +extern void sha512_final(sha512_context *); +extern void sha512_hash_buffer(unsigned char *, int, unsigned char *, int); + +/* 384 bit hash, provides 192 bits of security against collision attacks */ +extern void sha384_init(sha512_context *); +/* no sha384_write(), use sha512_write() */ +/* no sha384_final(), use sha512_final(), result in ctx->sha_out[0...47] */ +extern void sha384_hash_buffer(unsigned char *, int, unsigned char *, int); +#endif /* _SHA2_H */ diff -urN linux-2.4.29/net/ipsec/libcrypto/libtwofish/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/Makefile --- linux-2.4.29/net/ipsec/libcrypto/libtwofish/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/Makefile Tue Jul 8 16:21:05 2003 @@ -0,0 +1,21 @@ +CFLAGS=-O3 -fomit-frame-pointer -D__KERNEL__ -Wall $(EXTRA_CFLAGS) +INC=-I../include + +LIBOBJ=twofish.o twofish_cbc.o +BLIB=libtwofish.a + +.c.o: + $(CC) $(CPPFLAGS) $(CFLAGS) $(INC) -c $< -o $@ + +$(BLIB): $(LIBOBJ) + /bin/rm -f $(BLIB) + ar cr $(BLIB) $(LIBOBJ) + -if test -s /bin/ranlib; then /bin/ranlib $(BLIB); \ + else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(BLIB); \ + else exit 0; fi; fi + +test: test_main.o $(BLIB) + $(CC) -o $@ $^ + +clean: + rm -f *.[oa] core $(TARGET) test diff -urN linux-2.4.29/net/ipsec/libcrypto/libtwofish/test_main.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/test_main.c --- linux-2.4.29/net/ipsec/libcrypto/libtwofish/test_main.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/test_main.c Thu Sep 5 05:41:17 2002 @@ -0,0 +1,34 @@ +#include +#include +#include "twofish_cbc.h" +#define BLOCK_SIZE 16 +#define KEY_SIZE 128 /* bits */ +#define KEY "1234567890123456" +#define STR "hola guaso como estaisss ... 012" +#define STRSZ (sizeof(STR)-1) + +#define BLKLEN BLOCK_SIZE +#define CONTEXT_T twofish_context +static int pretty_print(const unsigned char *buf, int count) { + int i=0; + for (;i + */ + +/* Twofish for GPG + * By Matthew Skala , July 26, 1998 + * 256-bit key length added March 20, 1999 + * Some modifications to reduce the text size by Werner Koch, April, 1998 + * + * The original author has disclaimed all copyright interest in this + * code and thus putting it in the public domain. + * + * This code is a "clean room" implementation, written from the paper + * _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey, + * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available + * through http://www.counterpane.com/twofish.html + * + * For background information on multiplication in finite fields, used for + * the matrix operations in the key schedule, see the book _Contemporary + * Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the + * Third Edition. + * + * Only the 128- and 256-bit key sizes are supported. This code is intended + * for GNU C on a 32-bit system, but it should work almost anywhere. Loops + * are unrolled, precomputation tables are used, etc., for maximum speed at + * some cost in memory consumption. */ + +#ifdef __KERNEL__ +#include +#include +#else +#include +#define u8 u_int8_t +#define u32 u_int32_t +#endif + +#if 0 /* shouldn't this be #ifdef rotl32 ? + * Look at wordops.h: It includes asm/wordops.h. + * Anyway, we have to search in the macros for rot's, + * since they seem to be defined in a generic way. */ +#define rotl rotl32 +#define rotr rotr32 +#else +#define rotl generic_rotl32 +#define rotr generic_rotr32 +#endif + +#include "twofish.h" +/* The large precomputed tables for the Twofish cipher (twofish.c) + * Taken from the same source as twofish.c + * Marc Mutz + */ + +/* These two tables are the q0 and q1 permutations, exactly as described in + * the Twofish paper. */ + +static const u8 q0[256] = { + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, + 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, + 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, + 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, + 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, + 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, + 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, + 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, + 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, + 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, + 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, + 0x4A, 0x5E, 0xC1, 0xE0 +}; + +static const u8 q1[256] = { + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, + 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, + 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, + 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, + 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, + 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, + 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, + 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, + 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, + 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, + 0x55, 0x09, 0xBE, 0x91 +}; + +/* These MDS tables are actually tables of MDS composed with q0 and q1, + * because it is only ever used that way and we can save some time by + * precomputing. Of course the main saving comes from precomputing the + * GF(2^8) multiplication involved in the MDS matrix multiply; by looking + * things up in these tables we reduce the matrix multiply to four lookups + * and three XORs. Semi-formally, the definition of these tables is: + * mds[0][i] = MDS (q1[i] 0 0 0)^T mds[1][i] = MDS (0 q0[i] 0 0)^T + * mds[2][i] = MDS (0 0 q1[i] 0)^T mds[3][i] = MDS (0 0 0 q0[i])^T + * where ^T means "transpose", the matrix multiply is performed in GF(2^8) + * represented as GF(2)[x]/v(x) where v(x)=x^8+x^6+x^5+x^3+1 as described + * by Schneier et al, and I'm casually glossing over the byte/word + * conversion issues. */ + +static const u32 mds[4][256] = { + {0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, + 0xE2E22BFB, 0x9E9EFAC8, 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, + 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, 0x3C3C57D6, 0x93938A32, + 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, + 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, + 0xB0B0B306, 0x7575DE3F, 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, + 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, 0xAEAE2C6D, 0x7F7FABC1, + 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5, + 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, + 0x3131272C, 0x808065A3, 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, + 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, 0x2A2A3638, 0xC4C49CB0, + 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796, + 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, + 0x6767C027, 0xE9E9AF8C, 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, + 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, 0x29294CCA, 0xF0F035E3, + 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8, + 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, + 0xC8C81DC3, 0x9999FFCC, 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, + 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, 0xB5B53D79, 0x09090F0C, + 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9, + 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, + 0xEDEDD07A, 0x4343FC17, 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, + 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, 0x5656E70B, 0xE3E3DA72, + 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E, + 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, + 0x8181942A, 0x91910149, 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, + 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, 0x7878AEC5, 0xC5C56D39, + 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01, + 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, + 0x55559DF9, 0x7E7E5A48, 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, + 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, 0x0606F48D, 0x404086E5, + 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64, + 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, + 0x2D2D333C, 0x3030D6A5, 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, + 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, 0xD9D97929, 0x8686912E, + 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E, + 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, + 0xC1C112CF, 0x8585EBDC, 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, + 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, 0xABABA212, 0x6F6F3EA2, + 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, + 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, + 0x04047FF6, 0x272746C2, 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, + 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91}, + + {0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, + 0xA3658080, 0x76DFE4E4, 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, + 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, 0x0D54E6E6, 0xC6432020, + 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, + 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, + 0x94B1FBFB, 0x485A7E7E, 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, + 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, 0x1945FDFD, 0x5BA33A3A, + 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757, + 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, + 0x9B53AAAA, 0x7C635D5D, 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, + 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, 0xC0F09090, 0x8CAFE9E9, + 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656, + 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, + 0xB499C3C3, 0xF1975B5B, 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, + 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, 0xCCFF9999, 0x95EA1414, + 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3, + 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, + 0xBF7E9595, 0xBA207D7D, 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, + 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, 0x81FB0F0F, 0x793DB5B5, + 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282, + 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, + 0x86135050, 0xE730F7F7, 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, + 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, 0x410B9F9F, 0x7B8B0202, + 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC, + 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, + 0xB1C72B2B, 0xAB6F8E8E, 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, + 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, 0x91EF1313, 0x85FE0808, + 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272, + 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, + 0x6929A9A9, 0x647D4F4F, 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, + 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, 0xAC87D1D1, 0x7F8E0505, + 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5, + 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, + 0x4C5F7979, 0x02B6B7B7, 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, + 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, 0x57AC3333, 0xC718CFCF, + 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3, + 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, + 0x99E51D1D, 0x34392323, 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, + 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, 0xC8FA9E9E, 0xA882D6D6, + 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, + 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, + 0x0FE25151, 0x00000000, 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, + 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8}, + + {0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, + 0xE2FBE22B, 0x9EC89EFA, 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, + 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, 0x3CD63C57, 0x9332938A, + 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, + 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, + 0xB006B0B3, 0x753F75DE, 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, + 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, 0xAE6DAE2C, 0x7FC17FAB, + 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA, + 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, + 0x312C3127, 0x80A38065, 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, + 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, 0x2A382A36, 0xC4B0C49C, + 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07, + 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, + 0x672767C0, 0xE98CE9AF, 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, + 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, 0x29CA294C, 0xF0E3F035, + 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96, + 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, + 0xC8C3C81D, 0x99CC99FF, 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, + 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, 0xB579B53D, 0x090C090F, + 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD, + 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, + 0xED7AEDD0, 0x431743FC, 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, + 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, 0x560B56E7, 0xE372E3DA, + 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85, + 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, + 0x812A8194, 0x91499101, 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, + 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, 0x78C578AE, 0xC539C56D, + 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B, + 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, + 0x55F9559D, 0x7E487E5A, 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, + 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, 0x068D06F4, 0x40E54086, + 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D, + 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, + 0x2D3C2D33, 0x30A530D6, 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, + 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, 0xD929D979, 0x862E8691, + 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D, + 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, + 0xC1CFC112, 0x85DC85EB, 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, + 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, 0xAB12ABA2, 0x6FA26F3E, + 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, + 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, + 0x04F6047F, 0x27C22746, 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, + 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF}, + + {0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, + 0x6580A365, 0xDFE476DF, 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, + 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, 0x54E60D54, 0x4320C643, + 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, + 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, + 0xB1FB94B1, 0x5A7E485A, 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, + 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, 0x45FD1945, 0xA33A5BA3, + 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216, + 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, + 0x53AA9B53, 0x635D7C63, 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, + 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, 0xF090C0F0, 0xAFE98CAF, + 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7, + 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, + 0x99C3B499, 0x975BF197, 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, + 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, 0xFF99CCFF, 0xEA1495EA, + 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C, + 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, + 0x7E95BF7E, 0x207DBA20, 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, + 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, 0xFB0F81FB, 0x3DB5793D, + 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE, + 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, + 0x13508613, 0x30F7E730, 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, + 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, 0x0B9F410B, 0x8B027B8B, + 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4, + 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, + 0xC72BB1C7, 0x6F8EAB6F, 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, + 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, 0xEF1391EF, 0xFE0885FE, + 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB, + 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, + 0x29A96929, 0x7D4F647D, 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, + 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, 0x87D1AC87, 0x8E057F8E, + 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8, + 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, + 0x5F794C5F, 0xB6B702B6, 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, + 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, 0xAC3357AC, 0x18CFC718, + 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA, + 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, + 0xE51D99E5, 0x39233439, 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, + 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, 0xFA9EC8FA, 0x82D6A882, + 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, + 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, + 0xE2510FE2, 0x00000000, 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, + 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8} +}; + +/* The exp_to_poly and poly_to_exp tables are used to perform efficient + * operations in GF(2^8) represented as GF(2)[x]/w(x) where + * w(x)=x^8+x^6+x^3+x^2+1. We care about doing that because it's part of the + * definition of the RS matrix in the key schedule. Elements of that field + * are polynomials of degree not greater than 7 and all coefficients 0 or 1, + * which can be represented naturally by bytes (just substitute x=2). In that + * form, GF(2^8) addition is the same as bitwise XOR, but GF(2^8) + * multiplication is inefficient without hardware support. To multiply + * faster, I make use of the fact x is a generator for the nonzero elements, + * so that every element p of GF(2)[x]/w(x) is either 0 or equal to (x)^n for + * some n in 0..254. Note that that caret is exponentiation in GF(2^8), + * *not* polynomial notation. So if I want to compute pq where p and q are + * in GF(2^8), I can just say: + * 1. if p=0 or q=0 then pq=0 + * 2. otherwise, find m and n such that p=x^m and q=x^n + * 3. pq=(x^m)(x^n)=x^(m+n), so add m and n and find pq + * The translations in steps 2 and 3 are looked up in the tables + * poly_to_exp (for step 2) and exp_to_poly (for step 3). To see this + * in action, look at the CALC_S macro. As additional wrinkles, note that + * one of my operands is always a constant, so the poly_to_exp lookup on it + * is done in advance; I included the original values in the comments so + * readers can have some chance of recognizing that this *is* the RS matrix + * from the Twofish paper. I've only included the table entries I actually + * need; I never do a lookup on a variable input of zero and the biggest + * exponents I'll ever see are 254 (variable) and 237 (constant), so they'll + * never sum to more than 491. I'm repeating part of the exp_to_poly table + * so that I don't have to do mod-255 reduction in the exponent arithmetic. + * Since I know my constant operands are never zero, I only have to worry + * about zero values in the variable operand, and I do it with a simple + * conditional branch. I know conditionals are expensive, but I couldn't + * see a non-horrible way of avoiding them, and I did manage to group the + * statements so that each if covers four group multiplications. */ + +static const u8 poly_to_exp[255] = { + 0x00, 0x01, 0x17, 0x02, 0x2E, 0x18, 0x53, 0x03, 0x6A, 0x2F, 0x93, 0x19, + 0x34, 0x54, 0x45, 0x04, 0x5C, 0x6B, 0xB6, 0x30, 0xA6, 0x94, 0x4B, 0x1A, + 0x8C, 0x35, 0x81, 0x55, 0xAA, 0x46, 0x0D, 0x05, 0x24, 0x5D, 0x87, 0x6C, + 0x9B, 0xB7, 0xC1, 0x31, 0x2B, 0xA7, 0xA3, 0x95, 0x98, 0x4C, 0xCA, 0x1B, + 0xE6, 0x8D, 0x73, 0x36, 0xCD, 0x82, 0x12, 0x56, 0x62, 0xAB, 0xF0, 0x47, + 0x4F, 0x0E, 0xBD, 0x06, 0xD4, 0x25, 0xD2, 0x5E, 0x27, 0x88, 0x66, 0x6D, + 0xD6, 0x9C, 0x79, 0xB8, 0x08, 0xC2, 0xDF, 0x32, 0x68, 0x2C, 0xFD, 0xA8, + 0x8A, 0xA4, 0x5A, 0x96, 0x29, 0x99, 0x22, 0x4D, 0x60, 0xCB, 0xE4, 0x1C, + 0x7B, 0xE7, 0x3B, 0x8E, 0x9E, 0x74, 0xF4, 0x37, 0xD8, 0xCE, 0xF9, 0x83, + 0x6F, 0x13, 0xB2, 0x57, 0xE1, 0x63, 0xDC, 0xAC, 0xC4, 0xF1, 0xAF, 0x48, + 0x0A, 0x50, 0x42, 0x0F, 0xBA, 0xBE, 0xC7, 0x07, 0xDE, 0xD5, 0x78, 0x26, + 0x65, 0xD3, 0xD1, 0x5F, 0xE3, 0x28, 0x21, 0x89, 0x59, 0x67, 0xFC, 0x6E, + 0xB1, 0xD7, 0xF8, 0x9D, 0xF3, 0x7A, 0x3A, 0xB9, 0xC6, 0x09, 0x41, 0xC3, + 0xAE, 0xE0, 0xDB, 0x33, 0x44, 0x69, 0x92, 0x2D, 0x52, 0xFE, 0x16, 0xA9, + 0x0C, 0x8B, 0x80, 0xA5, 0x4A, 0x5B, 0xB5, 0x97, 0xC9, 0x2A, 0xA2, 0x9A, + 0xC0, 0x23, 0x86, 0x4E, 0xBC, 0x61, 0xEF, 0xCC, 0x11, 0xE5, 0x72, 0x1D, + 0x3D, 0x7C, 0xEB, 0xE8, 0xE9, 0x3C, 0xEA, 0x8F, 0x7D, 0x9F, 0xEC, 0x75, + 0x1E, 0xF5, 0x3E, 0x38, 0xF6, 0xD9, 0x3F, 0xCF, 0x76, 0xFA, 0x1F, 0x84, + 0xA0, 0x70, 0xED, 0x14, 0x90, 0xB3, 0x7E, 0x58, 0xFB, 0xE2, 0x20, 0x64, + 0xD0, 0xDD, 0x77, 0xAD, 0xDA, 0xC5, 0x40, 0xF2, 0x39, 0xB0, 0xF7, 0x49, + 0xB4, 0x0B, 0x7F, 0x51, 0x15, 0x43, 0x91, 0x10, 0x71, 0xBB, 0xEE, 0xBF, + 0x85, 0xC8, 0xA1 +}; + +static const u8 exp_to_poly[492] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, 0x9A, 0x79, 0xF2, + 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, 0xF5, 0xA7, 0x03, + 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, 0x8B, 0x5B, 0xB6, + 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, 0xA4, 0x05, 0x0A, + 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, 0xED, 0x97, 0x63, + 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, 0x0F, 0x1E, 0x3C, + 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, 0xF4, 0xA5, 0x07, + 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, 0x22, 0x44, 0x88, + 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, 0xA2, 0x09, 0x12, + 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, 0xCC, 0xD5, 0xE7, + 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, 0x1B, 0x36, 0x6C, + 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, 0x32, 0x64, 0xC8, + 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, 0x5A, 0xB4, 0x25, + 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, 0xAC, 0x15, 0x2A, + 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, 0x91, 0x6F, 0xDE, + 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, 0x3F, 0x7E, 0xFC, + 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, 0xB1, 0x2F, 0x5E, + 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, 0x82, 0x49, 0x92, + 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, 0x71, 0xE2, 0x89, + 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB, 0xDB, 0xFB, 0xBB, + 0x3B, 0x76, 0xEC, 0x95, 0x67, 0xCE, 0xD1, 0xEF, 0x93, 0x6B, 0xD6, 0xE1, + 0x8F, 0x53, 0xA6, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x4D, + 0x9A, 0x79, 0xF2, 0xA9, 0x1F, 0x3E, 0x7C, 0xF8, 0xBD, 0x37, 0x6E, 0xDC, + 0xF5, 0xA7, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xCD, 0xD7, 0xE3, + 0x8B, 0x5B, 0xB6, 0x21, 0x42, 0x84, 0x45, 0x8A, 0x59, 0xB2, 0x29, 0x52, + 0xA4, 0x05, 0x0A, 0x14, 0x28, 0x50, 0xA0, 0x0D, 0x1A, 0x34, 0x68, 0xD0, + 0xED, 0x97, 0x63, 0xC6, 0xC1, 0xCF, 0xD3, 0xEB, 0x9B, 0x7B, 0xF6, 0xA1, + 0x0F, 0x1E, 0x3C, 0x78, 0xF0, 0xAD, 0x17, 0x2E, 0x5C, 0xB8, 0x3D, 0x7A, + 0xF4, 0xA5, 0x07, 0x0E, 0x1C, 0x38, 0x70, 0xE0, 0x8D, 0x57, 0xAE, 0x11, + 0x22, 0x44, 0x88, 0x5D, 0xBA, 0x39, 0x72, 0xE4, 0x85, 0x47, 0x8E, 0x51, + 0xA2, 0x09, 0x12, 0x24, 0x48, 0x90, 0x6D, 0xDA, 0xF9, 0xBF, 0x33, 0x66, + 0xCC, 0xD5, 0xE7, 0x83, 0x4B, 0x96, 0x61, 0xC2, 0xC9, 0xDF, 0xF3, 0xAB, + 0x1B, 0x36, 0x6C, 0xD8, 0xFD, 0xB7, 0x23, 0x46, 0x8C, 0x55, 0xAA, 0x19, + 0x32, 0x64, 0xC8, 0xDD, 0xF7, 0xA3, 0x0B, 0x16, 0x2C, 0x58, 0xB0, 0x2D, + 0x5A, 0xB4, 0x25, 0x4A, 0x94, 0x65, 0xCA, 0xD9, 0xFF, 0xB3, 0x2B, 0x56, + 0xAC, 0x15, 0x2A, 0x54, 0xA8, 0x1D, 0x3A, 0x74, 0xE8, 0x9D, 0x77, 0xEE, + 0x91, 0x6F, 0xDE, 0xF1, 0xAF, 0x13, 0x26, 0x4C, 0x98, 0x7D, 0xFA, 0xB9, + 0x3F, 0x7E, 0xFC, 0xB5, 0x27, 0x4E, 0x9C, 0x75, 0xEA, 0x99, 0x7F, 0xFE, + 0xB1, 0x2F, 0x5E, 0xBC, 0x35, 0x6A, 0xD4, 0xE5, 0x87, 0x43, 0x86, 0x41, + 0x82, 0x49, 0x92, 0x69, 0xD2, 0xE9, 0x9F, 0x73, 0xE6, 0x81, 0x4F, 0x9E, + 0x71, 0xE2, 0x89, 0x5F, 0xBE, 0x31, 0x62, 0xC4, 0xC5, 0xC7, 0xC3, 0xCB +}; + + +/* The table constants are indices of + * S-box entries, preprocessed through q0 and q1. */ +static const u8 calc_sb_tbl[512] = { + 0xA9, 0x75, 0x67, 0xF3, 0xB3, 0xC6, 0xE8, 0xF4, + 0x04, 0xDB, 0xFD, 0x7B, 0xA3, 0xFB, 0x76, 0xC8, + 0x9A, 0x4A, 0x92, 0xD3, 0x80, 0xE6, 0x78, 0x6B, + 0xE4, 0x45, 0xDD, 0x7D, 0xD1, 0xE8, 0x38, 0x4B, + 0x0D, 0xD6, 0xC6, 0x32, 0x35, 0xD8, 0x98, 0xFD, + 0x18, 0x37, 0xF7, 0x71, 0xEC, 0xF1, 0x6C, 0xE1, + 0x43, 0x30, 0x75, 0x0F, 0x37, 0xF8, 0x26, 0x1B, + 0xFA, 0x87, 0x13, 0xFA, 0x94, 0x06, 0x48, 0x3F, + 0xF2, 0x5E, 0xD0, 0xBA, 0x8B, 0xAE, 0x30, 0x5B, + 0x84, 0x8A, 0x54, 0x00, 0xDF, 0xBC, 0x23, 0x9D, + 0x19, 0x6D, 0x5B, 0xC1, 0x3D, 0xB1, 0x59, 0x0E, + 0xF3, 0x80, 0xAE, 0x5D, 0xA2, 0xD2, 0x82, 0xD5, + 0x63, 0xA0, 0x01, 0x84, 0x83, 0x07, 0x2E, 0x14, + 0xD9, 0xB5, 0x51, 0x90, 0x9B, 0x2C, 0x7C, 0xA3, + 0xA6, 0xB2, 0xEB, 0x73, 0xA5, 0x4C, 0xBE, 0x54, + 0x16, 0x92, 0x0C, 0x74, 0xE3, 0x36, 0x61, 0x51, + 0xC0, 0x38, 0x8C, 0xB0, 0x3A, 0xBD, 0xF5, 0x5A, + 0x73, 0xFC, 0x2C, 0x60, 0x25, 0x62, 0x0B, 0x96, + 0xBB, 0x6C, 0x4E, 0x42, 0x89, 0xF7, 0x6B, 0x10, + 0x53, 0x7C, 0x6A, 0x28, 0xB4, 0x27, 0xF1, 0x8C, + 0xE1, 0x13, 0xE6, 0x95, 0xBD, 0x9C, 0x45, 0xC7, + 0xE2, 0x24, 0xF4, 0x46, 0xB6, 0x3B, 0x66, 0x70, + 0xCC, 0xCA, 0x95, 0xE3, 0x03, 0x85, 0x56, 0xCB, + 0xD4, 0x11, 0x1C, 0xD0, 0x1E, 0x93, 0xD7, 0xB8, + 0xFB, 0xA6, 0xC3, 0x83, 0x8E, 0x20, 0xB5, 0xFF, + 0xE9, 0x9F, 0xCF, 0x77, 0xBF, 0xC3, 0xBA, 0xCC, + 0xEA, 0x03, 0x77, 0x6F, 0x39, 0x08, 0xAF, 0xBF, + 0x33, 0x40, 0xC9, 0xE7, 0x62, 0x2B, 0x71, 0xE2, + 0x81, 0x79, 0x79, 0x0C, 0x09, 0xAA, 0xAD, 0x82, + 0x24, 0x41, 0xCD, 0x3A, 0xF9, 0xEA, 0xD8, 0xB9, + 0xE5, 0xE4, 0xC5, 0x9A, 0xB9, 0xA4, 0x4D, 0x97, + 0x44, 0x7E, 0x08, 0xDA, 0x86, 0x7A, 0xE7, 0x17, + 0xA1, 0x66, 0x1D, 0x94, 0xAA, 0xA1, 0xED, 0x1D, + 0x06, 0x3D, 0x70, 0xF0, 0xB2, 0xDE, 0xD2, 0xB3, + 0x41, 0x0B, 0x7B, 0x72, 0xA0, 0xA7, 0x11, 0x1C, + 0x31, 0xEF, 0xC2, 0xD1, 0x27, 0x53, 0x90, 0x3E, + 0x20, 0x8F, 0xF6, 0x33, 0x60, 0x26, 0xFF, 0x5F, + 0x96, 0xEC, 0x5C, 0x76, 0xB1, 0x2A, 0xAB, 0x49, + 0x9E, 0x81, 0x9C, 0x88, 0x52, 0xEE, 0x1B, 0x21, + 0x5F, 0xC4, 0x93, 0x1A, 0x0A, 0xEB, 0xEF, 0xD9, + 0x91, 0xC5, 0x85, 0x39, 0x49, 0x99, 0xEE, 0xCD, + 0x2D, 0xAD, 0x4F, 0x31, 0x8F, 0x8B, 0x3B, 0x01, + 0x47, 0x18, 0x87, 0x23, 0x6D, 0xDD, 0x46, 0x1F, + 0xD6, 0x4E, 0x3E, 0x2D, 0x69, 0xF9, 0x64, 0x48, + 0x2A, 0x4F, 0xCE, 0xF2, 0xCB, 0x65, 0x2F, 0x8E, + 0xFC, 0x78, 0x97, 0x5C, 0x05, 0x58, 0x7A, 0x19, + 0xAC, 0x8D, 0x7F, 0xE5, 0xD5, 0x98, 0x1A, 0x57, + 0x4B, 0x67, 0x0E, 0x7F, 0xA7, 0x05, 0x5A, 0x64, + 0x28, 0xAF, 0x14, 0x63, 0x3F, 0xB6, 0x29, 0xFE, + 0x88, 0xF5, 0x3C, 0xB7, 0x4C, 0x3C, 0x02, 0xA5, + 0xB8, 0xCE, 0xDA, 0xE9, 0xB0, 0x68, 0x17, 0x44, + 0x55, 0xE0, 0x1F, 0x4D, 0x8A, 0x43, 0x7D, 0x69, + 0x57, 0x29, 0xC7, 0x2E, 0x8D, 0xAC, 0x74, 0x15, + 0xB7, 0x59, 0xC4, 0xA8, 0x9F, 0x0A, 0x72, 0x9E, + 0x7E, 0x6E, 0x15, 0x47, 0x22, 0xDF, 0x12, 0x34, + 0x58, 0x35, 0x07, 0x6A, 0x99, 0xCF, 0x34, 0xDC, + 0x6E, 0x22, 0x50, 0xC9, 0xDE, 0xC0, 0x68, 0x9B, + 0x65, 0x89, 0xBC, 0xD4, 0xDB, 0xED, 0xF8, 0xAB, + 0xC8, 0x12, 0xA8, 0xA2, 0x2B, 0x0D, 0x40, 0x52, + 0xDC, 0xBB, 0xFE, 0x02, 0x32, 0x2F, 0xA4, 0xA9, + 0xCA, 0xD7, 0x10, 0x61, 0x21, 0x1E, 0xF0, 0xB4, + 0xD3, 0x50, 0x5D, 0x04, 0x0F, 0xF6, 0x00, 0xC2, + 0x6F, 0x16, 0x9D, 0x25, 0x36, 0x86, 0x42, 0x56, + 0x4A, 0x55, 0x5E, 0x09, 0xC1, 0xBE, 0xE0, 0x91 +}; + +/* Macro to perform one column of the RS matrix multiplication. The + * parameters a, b, c, and d are the four bytes of output; i is the index + * of the key bytes, and w, x, y, and z, are the column of constants from + * the RS matrix, preprocessed through the poly_to_exp table. */ + +#define CALC_S(a, b, c, d, i, w, x, y, z) \ + if (key[i]) { \ + tmp = poly_to_exp[key[i] - 1]; \ + (a) ^= exp_to_poly[tmp + (w)]; \ + (b) ^= exp_to_poly[tmp + (x)]; \ + (c) ^= exp_to_poly[tmp + (y)]; \ + (d) ^= exp_to_poly[tmp + (z)]; \ + } + +/* Macros to calculate the key-dependent S-boxes for a 128-bit key using + * the S vector from CALC_S. CALC_SB_2 computes a single entry in all + * four S-boxes, where i is the index of the entry to compute, and a and b + * are the index numbers preprocessed through the q0 and q1 tables + * respectively. */ + +#define CALC_SB_2(i, a, b) \ + ctx->s[0][i] = mds[0][q0[(a) ^ sa] ^ se]; \ + ctx->s[1][i] = mds[1][q0[(b) ^ sb] ^ sf]; \ + ctx->s[2][i] = mds[2][q1[(a) ^ sc] ^ sg]; \ + ctx->s[3][i] = mds[3][q1[(b) ^ sd] ^ sh] + +/* Macro exactly like CALC_SB_2, but for 192-bit keys. */ + +#define CALC_SB192_2(i, a, b) \ + ctx->s[0][i] = mds[0][q0[q0[(b) ^ sa] ^ se] ^ si]; \ + ctx->s[1][i] = mds[1][q0[q1[(b) ^ sb] ^ sf] ^ sj]; \ + ctx->s[2][i] = mds[2][q1[q0[(a) ^ sc] ^ sg] ^ sk]; \ + ctx->s[3][i] = mds[3][q1[q1[(a) ^ sd] ^ sh] ^ sl]; + +/* Macro exactly like CALC_SB_2, but for 256-bit keys. */ + +#define CALC_SB256_2(i, a, b) \ + ctx->s[0][i] = mds[0][q0[q0[q1[(b) ^ sa] ^ se] ^ si] ^ sm]; \ + ctx->s[1][i] = mds[1][q0[q1[q1[(a) ^ sb] ^ sf] ^ sj] ^ sn]; \ + ctx->s[2][i] = mds[2][q1[q0[q0[(a) ^ sc] ^ sg] ^ sk] ^ so]; \ + ctx->s[3][i] = mds[3][q1[q1[q0[(b) ^ sd] ^ sh] ^ sl] ^ sp]; + +/* Macros to calculate the whitening and round subkeys. CALC_K_2 computes the + * last two stages of the h() function for a given index (either 2i or 2i+1). + * a, b, c, and d are the four bytes going into the last two stages. For + * 128-bit keys, this is the entire h() function and a and c are the index + * preprocessed through q0 and q1 respectively; for longer keys they are the + * output of previous stages. j is the index of the first key byte to use. + * CALC_K computes a pair of subkeys for 128-bit Twofish, by calling CALC_K_2 + * twice, doing the Psuedo-Hadamard Transform, and doing the necessary + * rotations. Its parameters are: a, the array to write the results into, + * j, the index of the first output entry, k and l, the preprocessed indices + * for index 2i, and m and n, the preprocessed indices for index 2i+1. + * CALC_K192_2 expands CALC_K_2 to handle 192-bit keys, by doing an + * additional lookup-and-XOR stage. The parameters a, b, c and d are the + * four bytes going into the last three stages. For 192-bit keys, c = d + * are the index preprocessed through q0, and a = b are the index + * preprocessed through q1; j is the index of the first key byte to use. + * CALC_K192 is identical to CALC_K but for using the CALC_K192_2 macro + * instead of CALC_K_2. + * CALC_K256_2 expands CALC_K192_2 to handle 256-bit keys, by doing an + * additional lookup-and-XOR stage. The parameters a and b are the index + * preprocessed through q0 and q1 respectively; j is the index of the first + * key byte to use. CALC_K256 is identical to CALC_K but for using the + * CALC_K256_2 macro instead of CALC_K_2. */ + +#define CALC_K_2(a, b, c, d, j) \ + mds[0][q0[a ^ key[(j) + 8]] ^ key[j]] \ + ^ mds[1][q0[b ^ key[(j) + 9]] ^ key[(j) + 1]] \ + ^ mds[2][q1[c ^ key[(j) + 10]] ^ key[(j) + 2]] \ + ^ mds[3][q1[d ^ key[(j) + 11]] ^ key[(j) + 3]] + +#define CALC_K(a, j, k, l, m, n) \ + x = CALC_K_2 (k, l, k, l, 0); \ + y = CALC_K_2 (m, n, m, n, 4); \ + y = (y << 8) + (y >> 24); \ + x += y; y += x; ctx->a[j] = x; \ + ctx->a[(j) + 1] = (y << 9) + (y >> 23) + +#define CALC_K192_2(a, b, c, d, j) \ + CALC_K_2 (q0[a ^ key[(j) + 16]], \ + q1[b ^ key[(j) + 17]], \ + q0[c ^ key[(j) + 18]], \ + q1[d ^ key[(j) + 19]], j) + +#define CALC_K192(a, j, k, l, m, n) \ + x = CALC_K192_2 (l, l, k, k, 0); \ + y = CALC_K192_2 (n, n, m, m, 4); \ + y = (y << 8) + (y >> 24); \ + x += y; y += x; ctx->a[j] = x; \ + ctx->a[(j) + 1] = (y << 9) + (y >> 23) + +#define CALC_K256_2(a, b, j) \ + CALC_K192_2 (q1[b ^ key[(j) + 24]], \ + q1[a ^ key[(j) + 25]], \ + q0[a ^ key[(j) + 26]], \ + q0[b ^ key[(j) + 27]], j) + +#define CALC_K256(a, j, k, l, m, n) \ + x = CALC_K256_2 (k, l, 0); \ + y = CALC_K256_2 (m, n, 4); \ + y = (y << 8) + (y >> 24); \ + x += y; y += x; ctx->a[j] = x; \ + ctx->a[(j) + 1] = (y << 9) + (y >> 23) + +/* Perform the key setup. */ + +int twofish_set_key (TWOFISH_context *ctx, + const unsigned char *key, int key_len) +{ + + int i, j, k; + + /* Temporaries for CALC_K. */ + u32 x, y; + + /* The S vector used to key the S-boxes, split up into individual bytes. + * 128-bit keys use only sa through sh; 256-bit use all of them. */ + u8 sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0; + u8 si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0; + + /* Temporary for CALC_S. */ + u8 tmp; + + /* Check key length. */ + if (key_len != 16 && key_len != 24 && key_len != 32) + return -1; /* unsupported key length */ + + /* Compute the first two words of the S vector. The magic numbers are + * the entries of the RS matrix, preprocessed through poly_to_exp. The + * numbers in the comments are the original (polynomial form) matrix + * entries. */ + CALC_S (sa, sb, sc, sd, 0, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ + CALC_S (sa, sb, sc, sd, 1, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ + CALC_S (sa, sb, sc, sd, 2, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ + CALC_S (sa, sb, sc, sd, 3, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ + CALC_S (sa, sb, sc, sd, 4, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ + CALC_S (sa, sb, sc, sd, 5, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ + CALC_S (sa, sb, sc, sd, 6, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ + CALC_S (sa, sb, sc, sd, 7, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ + CALC_S (se, sf, sg, sh, 8, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ + CALC_S (se, sf, sg, sh, 9, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ + CALC_S (se, sf, sg, sh, 10, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ + CALC_S (se, sf, sg, sh, 11, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ + CALC_S (se, sf, sg, sh, 12, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ + CALC_S (se, sf, sg, sh, 13, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ + CALC_S (se, sf, sg, sh, 14, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ + CALC_S (se, sf, sg, sh, 15, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ + + if (key_len == 24 || key_len == 32) { /* 192- or 256-bit key */ + /* Calculate the third word of the S vector */ + CALC_S (si, sj, sk, sl, 16, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ + CALC_S (si, sj, sk, sl, 17, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ + CALC_S (si, sj, sk, sl, 18, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ + CALC_S (si, sj, sk, sl, 19, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ + CALC_S (si, sj, sk, sl, 20, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ + CALC_S (si, sj, sk, sl, 21, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ + CALC_S (si, sj, sk, sl, 22, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ + CALC_S (si, sj, sk, sl, 23, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ + } + + if (key_len == 32) { /* 256-bit key */ + /* Calculate the fourth word of the S vector */ + CALC_S (sm, sn, so, sp, 24, 0x00, 0x2D, 0x01, 0x2D); /* 01 A4 02 A4 */ + CALC_S (sm, sn, so, sp, 25, 0x2D, 0xA4, 0x44, 0x8A); /* A4 56 A1 55 */ + CALC_S (sm, sn, so, sp, 26, 0x8A, 0xD5, 0xBF, 0xD1); /* 55 82 FC 87 */ + CALC_S (sm, sn, so, sp, 27, 0xD1, 0x7F, 0x3D, 0x99); /* 87 F3 C1 5A */ + CALC_S (sm, sn, so, sp, 28, 0x99, 0x46, 0x66, 0x96); /* 5A 1E 47 58 */ + CALC_S (sm, sn, so, sp, 29, 0x96, 0x3C, 0x5B, 0xED); /* 58 C6 AE DB */ + CALC_S (sm, sn, so, sp, 30, 0xED, 0x37, 0x4F, 0xE0); /* DB 68 3D 9E */ + CALC_S (sm, sn, so, sp, 31, 0xE0, 0xD0, 0x8C, 0x17); /* 9E E5 19 03 */ + + /* Compute the S-boxes. */ + for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) { + CALC_SB256_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); + } + + /* Calculate whitening and round subkeys. The constants are + * indices of subkeys, preprocessed through q0 and q1. */ + CALC_K256 (w, 0, 0xA9, 0x75, 0x67, 0xF3); + CALC_K256 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4); + CALC_K256 (w, 4, 0x04, 0xDB, 0xFD, 0x7B); + CALC_K256 (w, 6, 0xA3, 0xFB, 0x76, 0xC8); + CALC_K256 (k, 0, 0x9A, 0x4A, 0x92, 0xD3); + CALC_K256 (k, 2, 0x80, 0xE6, 0x78, 0x6B); + CALC_K256 (k, 4, 0xE4, 0x45, 0xDD, 0x7D); + CALC_K256 (k, 6, 0xD1, 0xE8, 0x38, 0x4B); + CALC_K256 (k, 8, 0x0D, 0xD6, 0xC6, 0x32); + CALC_K256 (k, 10, 0x35, 0xD8, 0x98, 0xFD); + CALC_K256 (k, 12, 0x18, 0x37, 0xF7, 0x71); + CALC_K256 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1); + CALC_K256 (k, 16, 0x43, 0x30, 0x75, 0x0F); + CALC_K256 (k, 18, 0x37, 0xF8, 0x26, 0x1B); + CALC_K256 (k, 20, 0xFA, 0x87, 0x13, 0xFA); + CALC_K256 (k, 22, 0x94, 0x06, 0x48, 0x3F); + CALC_K256 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA); + CALC_K256 (k, 26, 0x8B, 0xAE, 0x30, 0x5B); + CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00); + CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D); + } else if (key_len == 24) { /* 192-bit key */ + /* Compute the S-boxes. */ + for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) { + CALC_SB192_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); + } + + /* Calculate whitening and round subkeys. The constants are + * indices of subkeys, preprocessed through q0 and q1. */ + CALC_K192 (w, 0, 0xA9, 0x75, 0x67, 0xF3); + CALC_K192 (w, 2, 0xB3, 0xC6, 0xE8, 0xF4); + CALC_K192 (w, 4, 0x04, 0xDB, 0xFD, 0x7B); + CALC_K192 (w, 6, 0xA3, 0xFB, 0x76, 0xC8); + CALC_K192 (k, 0, 0x9A, 0x4A, 0x92, 0xD3); + CALC_K192 (k, 2, 0x80, 0xE6, 0x78, 0x6B); + CALC_K192 (k, 4, 0xE4, 0x45, 0xDD, 0x7D); + CALC_K192 (k, 6, 0xD1, 0xE8, 0x38, 0x4B); + CALC_K192 (k, 8, 0x0D, 0xD6, 0xC6, 0x32); + CALC_K192 (k, 10, 0x35, 0xD8, 0x98, 0xFD); + CALC_K192 (k, 12, 0x18, 0x37, 0xF7, 0x71); + CALC_K192 (k, 14, 0xEC, 0xF1, 0x6C, 0xE1); + CALC_K192 (k, 16, 0x43, 0x30, 0x75, 0x0F); + CALC_K192 (k, 18, 0x37, 0xF8, 0x26, 0x1B); + CALC_K192 (k, 20, 0xFA, 0x87, 0x13, 0xFA); + CALC_K192 (k, 22, 0x94, 0x06, 0x48, 0x3F); + CALC_K192 (k, 24, 0xF2, 0x5E, 0xD0, 0xBA); + CALC_K192 (k, 26, 0x8B, 0xAE, 0x30, 0x5B); + CALC_K192 (k, 28, 0x84, 0x8A, 0x54, 0x00); + CALC_K192 (k, 30, 0xDF, 0xBC, 0x23, 0x9D); + } else { /* 128-bit key */ + /* Compute the S-boxes. */ + for ( i = j = 0, k = 1; i < 256; i++, j += 2, k += 2 ) { + CALC_SB_2( i, calc_sb_tbl[j], calc_sb_tbl[k] ); + } + + /* Calculate whitening and round subkeys. The constants are + * indices of subkeys, preprocessed through q0 and q1. */ + CALC_K (w, 0, 0xA9, 0x75, 0x67, 0xF3); + CALC_K (w, 2, 0xB3, 0xC6, 0xE8, 0xF4); + CALC_K (w, 4, 0x04, 0xDB, 0xFD, 0x7B); + CALC_K (w, 6, 0xA3, 0xFB, 0x76, 0xC8); + CALC_K (k, 0, 0x9A, 0x4A, 0x92, 0xD3); + CALC_K (k, 2, 0x80, 0xE6, 0x78, 0x6B); + CALC_K (k, 4, 0xE4, 0x45, 0xDD, 0x7D); + CALC_K (k, 6, 0xD1, 0xE8, 0x38, 0x4B); + CALC_K (k, 8, 0x0D, 0xD6, 0xC6, 0x32); + CALC_K (k, 10, 0x35, 0xD8, 0x98, 0xFD); + CALC_K (k, 12, 0x18, 0x37, 0xF7, 0x71); + CALC_K (k, 14, 0xEC, 0xF1, 0x6C, 0xE1); + CALC_K (k, 16, 0x43, 0x30, 0x75, 0x0F); + CALC_K (k, 18, 0x37, 0xF8, 0x26, 0x1B); + CALC_K (k, 20, 0xFA, 0x87, 0x13, 0xFA); + CALC_K (k, 22, 0x94, 0x06, 0x48, 0x3F); + CALC_K (k, 24, 0xF2, 0x5E, 0xD0, 0xBA); + CALC_K (k, 26, 0x8B, 0xAE, 0x30, 0x5B); + CALC_K (k, 28, 0x84, 0x8A, 0x54, 0x00); + CALC_K (k, 30, 0xDF, 0xBC, 0x23, 0x9D); + } + + return 0; +} + +/* Macros to compute the g() function in the encryption and decryption + * rounds. G1 is the straight g() function; G2 includes the 8-bit + * rotation for the high 32-bit word. */ + +#define G1(a) \ + (ctx->s[0][(a) & 0xFF]) ^ (ctx->s[1][((a) >> 8) & 0xFF]) \ + ^ (ctx->s[2][((a) >> 16) & 0xFF]) ^ (ctx->s[3][(a) >> 24]) + +#define G2(b) \ + (ctx->s[1][(b) & 0xFF]) ^ (ctx->s[2][((b) >> 8) & 0xFF]) \ + ^ (ctx->s[3][((b) >> 16) & 0xFF]) ^ (ctx->s[0][(b) >> 24]) + +/* Encryption and decryption Feistel rounds. Each one calls the two g() + * macros, does the PHT, and performs the XOR and the appropriate bit + * rotations. The parameters are the round number (used to select subkeys), + * and the four 32-bit chunks of the text. */ + +#define ENCROUND(n, a, b, c, d) \ + x = G1 (a); y = G2 (b); \ + x += y; y += x + ctx->k[2 * (n) + 1]; \ + (c) ^= x + ctx->k[2 * (n)]; \ + (c) = ((c) >> 1) + ((c) << 31); \ + (d) = (((d) << 1)+((d) >> 31)) ^ y + +#define DECROUND(n, a, b, c, d) \ + x = G1 (a); y = G2 (b); \ + x += y; y += x; \ + (d) ^= y + ctx->k[2 * (n) + 1]; \ + (d) = ((d) >> 1) + ((d) << 31); \ + (c) = (((c) << 1)+((c) >> 31)); \ + (c) ^= (x + ctx->k[2 * (n)]) + +/* Encryption and decryption cycles; each one is simply two Feistel rounds + * with the 32-bit chunks re-ordered to simulate the "swap" */ + +#define ENCCYCLE(n) \ + ENCROUND (2 * (n), a, b, c, d); \ + ENCROUND (2 * (n) + 1, c, d, a, b) + +#define DECCYCLE(n) \ + DECROUND (2 * (n) + 1, c, d, a, b); \ + DECROUND (2 * (n), a, b, c, d) + +/* Macros to convert the input and output bytes into 32-bit words, + * and simultaneously perform the whitening step. INPACK packs word + * number n into the variable named by x, using whitening subkey number m. + * OUTUNPACK unpacks word number n from the variable named by x, using + * whitening subkey number m. */ + +#define INPACK(n, x, m) \ + x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \ + ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m] + +#define OUTUNPACK(n, x, m) \ + x ^= ctx->w[m]; \ + out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \ + out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24 + +/* Encrypt one block. in and out may be the same. */ + +int twofish_encrypt (TWOFISH_context *ctx, + const u8 *in, u8 *out) +{ + /* The four 32-bit chunks of the text. */ + u32 a, b, c, d; + + /* Temporaries used by the round function. */ + u32 x, y; + + /* Input whitening and packing. */ + INPACK (0, a, 0); + INPACK (1, b, 1); + INPACK (2, c, 2); + INPACK (3, d, 3); + + /* Encryption Feistel cycles. */ + ENCCYCLE (0); + ENCCYCLE (1); + ENCCYCLE (2); + ENCCYCLE (3); + ENCCYCLE (4); + ENCCYCLE (5); + ENCCYCLE (6); + ENCCYCLE (7); + + /* Output whitening and unpacking. */ + OUTUNPACK (0, c, 4); + OUTUNPACK (1, d, 5); + OUTUNPACK (2, a, 6); + OUTUNPACK (3, b, 7); + + return 0; +} + +/* Decrypt one block. in and out may be the same. */ + +int twofish_decrypt (TWOFISH_context *ctx, + const u8 *in, u8 *out) +{ + /* The four 32-bit chunks of the text. */ + u32 a, b, c, d; + + /* Temporaries used by the round function. */ + u32 x, y; + + /* Input whitening and packing. */ + INPACK (0, c, 4); + INPACK (1, d, 5); + INPACK (2, a, 6); + INPACK (3, b, 7); + + /* Encryption Feistel cycles. */ + DECCYCLE (7); + DECCYCLE (6); + DECCYCLE (5); + DECCYCLE (4); + DECCYCLE (3); + DECCYCLE (2); + DECCYCLE (1); + DECCYCLE (0); + + /* Output whitening and unpacking. */ + OUTUNPACK (0, a, 0); + OUTUNPACK (1, b, 1); + OUTUNPACK (2, c, 2); + OUTUNPACK (3, d, 3); + + return 0; +} + +/* eof */ diff -urN linux-2.4.29/net/ipsec/libcrypto/libtwofish/twofish.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/twofish.h --- linux-2.4.29/net/ipsec/libcrypto/libtwofish/twofish.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/twofish.h Thu Sep 5 05:41:18 2002 @@ -0,0 +1,20 @@ +#ifndef TWOFISH_H +#define TWOFISH_H +#ifdef __KERNEL__ +#include +#else +#include +#endif +/* Structure for an expanded Twofish key. s contains the key-dependent + * S-boxes composed with the MDS matrix; w contains the eight "whitening" + * subkeys, K[0] through K[7]. k holds the remaining, "round" subkeys. Note + * that k[i] corresponds to what the Twofish paper calls K[i+8]. */ +typedef struct { + u_int32_t s[4][256], w[8], k[32]; +} TWOFISH_context; + +typedef TWOFISH_context twofish_context; +int twofish_set_key(twofish_context *tf_ctx, const u_int8_t * in_key, int key_len); +int twofish_encrypt(twofish_context *tf_ctx, const u_int8_t * in, u_int8_t * out); +int twofish_decrypt(twofish_context * tf_ctx, const u_int8_t * in, u_int8_t * out); +#endif /* TWOFISH_H */ diff -urN linux-2.4.29/net/ipsec/libcrypto/libtwofish/twofish_cbc.c linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/twofish_cbc.c --- linux-2.4.29/net/ipsec/libcrypto/libtwofish/twofish_cbc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/twofish_cbc.c Thu Sep 5 05:41:18 2002 @@ -0,0 +1,8 @@ +#ifdef __KERNEL__ +#include +#else +#include +#endif +#include "twofish_cbc.h" +#include "cbc_generic.h" +CBC_IMPL_BLK16(twofish_cbc_encrypt, twofish_context, u_int8_t *, twofish_encrypt, twofish_decrypt); diff -urN linux-2.4.29/net/ipsec/libcrypto/libtwofish/twofish_cbc.h linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/twofish_cbc.h --- linux-2.4.29/net/ipsec/libcrypto/libtwofish/twofish_cbc.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/libtwofish/twofish_cbc.h Thu Sep 5 05:41:18 2002 @@ -0,0 +1,3 @@ +/* Glue header */ +#include "twofish.h" +int twofish_cbc_encrypt(twofish_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t* iv, int encrypt); diff -urN linux-2.4.29/net/ipsec/libcrypto/perlasm/LICENSE linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/LICENSE --- linux-2.4.29/net/ipsec/libcrypto/perlasm/LICENSE Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/LICENSE Thu Sep 5 05:26:32 2002 @@ -0,0 +1,127 @@ + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + diff -urN linux-2.4.29/net/ipsec/libcrypto/perlasm/alpha.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/alpha.pl --- linux-2.4.29/net/ipsec/libcrypto/perlasm/alpha.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/alpha.pl Thu Sep 5 05:26:32 2002 @@ -0,0 +1,434 @@ +#!/usr/local/bin/perl + +package alpha; +use Carp qw(croak cluck); + +$label="100"; + +$n_debug=0; +$smear_regs=1; +$reg_alloc=1; + +$align="3"; +$com_start="#"; + +sub main'asm_init_output { @out=(); } +sub main'asm_get_output { return(@out); } +sub main'get_labels { return(@labels); } +sub main'external_label { push(@labels,@_); } + +# General registers + +%regs=( 'r0', '$0', + 'r1', '$1', + 'r2', '$2', + 'r3', '$3', + 'r4', '$4', + 'r5', '$5', + 'r6', '$6', + 'r7', '$7', + 'r8', '$8', + 'r9', '$22', + 'r10', '$23', + 'r11', '$24', + 'r12', '$25', + 'r13', '$27', + 'r14', '$28', + 'r15', '$21', # argc == 5 + 'r16', '$20', # argc == 4 + 'r17', '$19', # argc == 3 + 'r18', '$18', # argc == 2 + 'r19', '$17', # argc == 1 + 'r20', '$16', # argc == 0 + 'r21', '$9', # save 0 + 'r22', '$10', # save 1 + 'r23', '$11', # save 2 + 'r24', '$12', # save 3 + 'r25', '$13', # save 4 + 'r26', '$14', # save 5 + + 'a0', '$16', + 'a1', '$17', + 'a2', '$18', + 'a3', '$19', + 'a4', '$20', + 'a5', '$21', + + 's0', '$9', + 's1', '$10', + 's2', '$11', + 's3', '$12', + 's4', '$13', + 's5', '$14', + 'zero', '$31', + 'sp', '$30', + ); + +$main'reg_s0="r21"; +$main'reg_s1="r22"; +$main'reg_s2="r23"; +$main'reg_s3="r24"; +$main'reg_s4="r25"; +$main'reg_s5="r26"; + +@reg=( '$0', '$1' ,'$2' ,'$3' ,'$4' ,'$5' ,'$6' ,'$7' ,'$8', + '$22','$23','$24','$25','$20','$21','$27','$28'); + + +sub main'sub { &out3("subq",@_); } +sub main'add { &out3("addq",@_); } +sub main'mov { &out3("bis",$_[0],$_[0],$_[1]); } +sub main'or { &out3("bis",@_); } +sub main'bis { &out3("bis",@_); } +sub main'br { &out1("br",@_); } +sub main'ld { &out2("ldq",@_); } +sub main'st { &out2("stq",@_); } +sub main'cmpult { &out3("cmpult",@_); } +sub main'cmplt { &out3("cmplt",@_); } +sub main'bgt { &out2("bgt",@_); } +sub main'ble { &out2("ble",@_); } +sub main'blt { &out2("blt",@_); } +sub main'mul { &out3("mulq",@_); } +sub main'muh { &out3("umulh",@_); } + +$main'QWS=8; + +sub main'asm_add + { + push(@out,@_); + } + +sub main'asm_finish + { + &main'file_end(); + print &main'asm_get_output(); + } + +sub main'asm_init + { + ($type,$fn)=@_; + $filename=$fn; + + &main'asm_init_output(); + &main'comment("Don't even think of reading this code"); + &main'comment("It was automatically generated by $filename"); + &main'comment("Which is a perl program used to generate the alpha assember."); + &main'comment("eric "); + &main'comment(""); + + $filename =~ s/\.pl$//; + &main'file($filename); + } + +sub conv + { + local($r)=@_; + local($v); + + return($regs{$r}) if defined($regs{$r}); + return($r); + } + +sub main'QWPw + { + local($off,$reg)=@_; + + return(&main'QWP($off*8,$reg)); + } + +sub main'QWP + { + local($off,$reg)=@_; + + $ret="$off(".&conv($reg).")"; + return($ret); + } + +sub out3 + { + local($name,$p1,$p2,$p3)=@_; + + $p1=&conv($p1); + $p2=&conv($p2); + $p3=&conv($p3); + push(@out,"\t$name\t"); + $l=length($p1)+1; + push(@out,$p1.","); + $ll=3-($l+9)/8; + $tmp1=sprintf("\t" x $ll); + push(@out,$tmp1); + + $l=length($p2)+1; + push(@out,$p2.","); + $ll=3-($l+9)/8; + $tmp1=sprintf("\t" x $ll); + push(@out,$tmp1); + + push(@out,&conv($p3)."\n"); + } + +sub out2 + { + local($name,$p1,$p2,$p3)=@_; + + $p1=&conv($p1); + $p2=&conv($p2); + push(@out,"\t$name\t"); + $l=length($p1)+1; + push(@out,$p1.","); + $ll=3-($l+9)/8; + $tmp1=sprintf("\t" x $ll); + push(@out,$tmp1); + + push(@out,&conv($p2)."\n"); + } + +sub out1 + { + local($name,$p1)=@_; + + $p1=&conv($p1); + push(@out,"\t$name\t".$p1."\n"); + } + +sub out0 + { + push(@out,"\t$_[0]\n"); + } + +sub main'file + { + local($file)=@_; + + local($tmp)=<<"EOF"; + # DEC Alpha assember + # Generated from perl scripts contains in SSLeay + .file 1 "$file.s" + .set noat +EOF + push(@out,$tmp); + } + +sub main'function_begin + { + local($func)=@_; + +print STDERR "$func\n"; + local($tmp)=<<"EOF"; + .text + .align $align + .globl $func + .ent $func +${func}: +${func}..ng: + .frame \$30,0,\$26,0 + .prologue 0 +EOF + push(@out,$tmp); + $stack=0; + } + +sub main'function_end + { + local($func)=@_; + + local($tmp)=<<"EOF"; + ret \$31,(\$26),1 + .end $func +EOF + push(@out,$tmp); + $stack=0; + %label=(); + } + +sub main'function_end_A + { + local($func)=@_; + + local($tmp)=<<"EOF"; + ret \$31,(\$26),1 +EOF + push(@out,$tmp); + } + +sub main'function_end_B + { + local($func)=@_; + + $func=$under.$func; + + push(@out,"\t.end $func\n"); + $stack=0; + %label=(); + } + +sub main'wparam + { + local($num)=@_; + + if ($num < 6) + { + $num=20-$num; + return("r$num"); + } + else + { return(&main'QWP($stack+$num*8,"sp")); } + } + +sub main'stack_push + { + local($num)=@_; + $stack+=$num*8; + &main'sub("sp",$num*8,"sp"); + } + +sub main'stack_pop + { + local($num)=@_; + $stack-=$num*8; + &main'add("sp",$num*8,"sp"); + } + +sub main'swtmp + { + return(&main'QWP(($_[0])*8,"sp")); + } + +# Should use swtmp, which is above sp. Linix can trash the stack above esp +#sub main'wtmp +# { +# local($num)=@_; +# +# return(&main'QWP(-($num+1)*4,"esp","",0)); +# } + +sub main'comment + { + foreach (@_) + { + if (/^\s*$/) + { push(@out,"\n"); } + else + { push(@out,"\t$com_start $_ $com_end\n"); } + } + } + +sub main'label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}=$label; + $label++; + } + return('$'.$label{$_[0]}); + } + +sub main'set_label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}=$label; + $label++; + } +# push(@out,".align $align\n") if ($_[1] != 0); + push(@out,'$'."$label{$_[0]}:\n"); + } + +sub main'file_end + { + } + +sub main'data_word + { + push(@out,"\t.long $_[0]\n"); + } + +@pool_free=(); +@pool_taken=(); +$curr_num=0; +$max=0; + +sub main'init_pool + { + local($args)=@_; + local($i); + + @pool_free=(); + for ($i=(14+(6-$args)); $i >= 0; $i--) + { + push(@pool_free,"r$i"); + } + print STDERR "START :register pool:@pool_free\n"; + $curr_num=$max=0; + } + +sub main'fin_pool + { + printf STDERR "END %2d:register pool:@pool_free\n",$max; + } + +sub main'GR + { + local($r)=@_; + local($i,@n,$_); + + foreach (@pool_free) + { + if ($r ne $_) + { push(@n,$_); } + else + { + $curr_num++; + $max=$curr_num if ($curr_num > $max); + } + } + @pool_free=@n; +print STDERR "GR:@pool_free\n" if $reg_alloc; + return(@_); + } + +sub main'NR + { + local($num)=@_; + local(@ret); + + $num=1 if $num == 0; + ($#pool_free >= ($num-1)) || croak "out of registers: want $num, have @pool_free"; + while ($num > 0) + { + push(@ret,pop @pool_free); + $curr_num++; + $max=$curr_num if ($curr_num > $max); + $num-- + } + print STDERR "nr @ret\n" if $n_debug; +print STDERR "NR:@pool_free\n" if $reg_alloc; + return(@ret); + + } + +sub main'FR + { + local(@r)=@_; + local(@a,$v,$w); + + print STDERR "fr @r\n" if $n_debug; +# cluck "fr @r"; + for $w (@pool_free) + { + foreach $v (@r) + { + croak "double register free of $v (@pool_free)" if $w eq $v; + } + } + foreach $v (@r) + { + croak "bad argument to FR" if ($v !~ /^r\d+$/); + if ($smear_regs) + { unshift(@pool_free,$v); } + else { push(@pool_free,$v); } + $curr_num--; + } +print STDERR "FR:@pool_free\n" if $reg_alloc; + } +1; diff -urN linux-2.4.29/net/ipsec/libcrypto/perlasm/cbc.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/cbc.pl --- linux-2.4.29/net/ipsec/libcrypto/perlasm/cbc.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/cbc.pl Thu Sep 5 05:26:32 2002 @@ -0,0 +1,342 @@ +#!/usr/local/bin/perl + +# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc) +# des_cblock (*input); +# des_cblock (*output); +# long length; +# des_key_schedule schedule; +# des_cblock (*ivec); +# int enc; +# +# calls +# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); +# + +#&cbc("des_ncbc_encrypt","des_encrypt",0); +#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt", +# 1,4,5,3,5,-1); +#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt", +# 0,4,5,3,5,-1); +#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3", +# 0,6,7,3,4,5); +# +# When doing a cipher that needs bigendian order, +# for encrypt, the iv is kept in bigendian form, +# while for decrypt, it is kept in little endian. +sub cbc + { + local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_; + # name is the function name + # enc_func and dec_func and the functions to call for encrypt/decrypt + # swap is true if byte order needs to be reversed + # iv_off is parameter number for the iv + # enc_off is parameter number for the encrypt/decrypt flag + # p1,p2,p3 are the offsets for parameters to be passed to the + # underlying calls. + + &function_begin_B($name,""); + &comment(""); + + $in="esi"; + $out="edi"; + $count="ebp"; + + &push("ebp"); + &push("ebx"); + &push("esi"); + &push("edi"); + + $data_off=4; + $data_off+=4 if ($p1 > 0); + $data_off+=4 if ($p2 > 0); + $data_off+=4 if ($p3 > 0); + + &mov($count, &wparam(2)); # length + + &comment("getting iv ptr from parameter $iv_off"); + &mov("ebx", &wparam($iv_off)); # Get iv ptr + + &mov($in, &DWP(0,"ebx","",0));# iv[0] + &mov($out, &DWP(4,"ebx","",0));# iv[1] + + &push($out); + &push($in); + &push($out); # used in decrypt for iv[1] + &push($in); # used in decrypt for iv[0] + + &mov("ebx", "esp"); # This is the address of tin[2] + + &mov($in, &wparam(0)); # in + &mov($out, &wparam(1)); # out + + # We have loaded them all, how lets push things + &comment("getting encrypt flag from parameter $enc_off"); + &mov("ecx", &wparam($enc_off)); # Get enc flag + if ($p3 > 0) + { + &comment("get and push parameter $p3"); + if ($enc_off != $p3) + { &mov("eax", &wparam($p3)); &push("eax"); } + else { &push("ecx"); } + } + if ($p2 > 0) + { + &comment("get and push parameter $p2"); + if ($enc_off != $p2) + { &mov("eax", &wparam($p2)); &push("eax"); } + else { &push("ecx"); } + } + if ($p1 > 0) + { + &comment("get and push parameter $p1"); + if ($enc_off != $p1) + { &mov("eax", &wparam($p1)); &push("eax"); } + else { &push("ecx"); } + } + &push("ebx"); # push data/iv + + &cmp("ecx",0); + &jz(&label("decrypt")); + + &and($count,0xfffffff8); + &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0] + &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1] + + &jz(&label("encrypt_finish")); + + ############################################################# + + &set_label("encrypt_loop"); + # encrypt start + # "eax" and "ebx" hold iv (or the last cipher text) + + &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes + &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes + + &xor("eax", "ecx"); + &xor("ebx", "edx"); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($enc_func); + + &mov("eax", &DWP($data_off,"esp","",0)); + &mov("ebx", &DWP($data_off+4,"esp","",0)); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP(0,$out,"",0),"eax"); + &mov(&DWP(4,$out,"",0),"ebx"); + + # eax and ebx are the next iv. + + &add($in, 8); + &add($out, 8); + + &sub($count, 8); + &jnz(&label("encrypt_loop")); + +###################################################################3 + &set_label("encrypt_finish"); + &mov($count, &wparam(2)); # length + &and($count, 7); + &jz(&label("finish")); + &xor("ecx","ecx"); + &xor("edx","edx"); + &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); + &jmp_ptr($count); + +&set_label("ej7"); + &xor("edx", "edx") if $ppro; # ppro friendly + &movb(&HB("edx"), &BP(6,$in,"",0)); + &shl("edx",8); +&set_label("ej6"); + &movb(&HB("edx"), &BP(5,$in,"",0)); +&set_label("ej5"); + &movb(&LB("edx"), &BP(4,$in,"",0)); +&set_label("ej4"); + &mov("ecx", &DWP(0,$in,"",0)); + &jmp(&label("ejend")); +&set_label("ej3"); + &movb(&HB("ecx"), &BP(2,$in,"",0)); + &xor("ecx", "ecx") if $ppro; # ppro friendly + &shl("ecx",8); +&set_label("ej2"); + &movb(&HB("ecx"), &BP(1,$in,"",0)); +&set_label("ej1"); + &movb(&LB("ecx"), &BP(0,$in,"",0)); +&set_label("ejend"); + + &xor("eax", "ecx"); + &xor("ebx", "edx"); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($enc_func); + + &mov("eax", &DWP($data_off,"esp","",0)); + &mov("ebx", &DWP($data_off+4,"esp","",0)); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP(0,$out,"",0),"eax"); + &mov(&DWP(4,$out,"",0),"ebx"); + + &jmp(&label("finish")); + + ############################################################# + ############################################################# + &set_label("decrypt",1); + # decrypt start + &and($count,0xfffffff8); + # The next 2 instructions are only for if the jz is taken + &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0] + &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1] + &jz(&label("decrypt_finish")); + + &set_label("decrypt_loop"); + &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes + &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put back + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($dec_func); + + &mov("eax", &DWP($data_off,"esp","",0)); # get return + &mov("ebx", &DWP($data_off+4,"esp","",0)); # + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] + &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] + + &xor("ecx", "eax"); + &xor("edx", "ebx"); + + &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, + &mov("ebx", &DWP(4,$in,"",0)); # next iv actually + + &mov(&DWP(0,$out,"",0),"ecx"); + &mov(&DWP(4,$out,"",0),"edx"); + + &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv + &mov(&DWP($data_off+12,"esp","",0), "ebx"); # + + &add($in, 8); + &add($out, 8); + + &sub($count, 8); + &jnz(&label("decrypt_loop")); +############################ ENDIT #######################3 + &set_label("decrypt_finish"); + &mov($count, &wparam(2)); # length + &and($count, 7); + &jz(&label("finish")); + + &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes + &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put back + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($dec_func); + + &mov("eax", &DWP($data_off,"esp","",0)); # get return + &mov("ebx", &DWP($data_off+4,"esp","",0)); # + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] + &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] + + &xor("ecx", "eax"); + &xor("edx", "ebx"); + + # this is for when we exit + &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, + &mov("ebx", &DWP(4,$in,"",0)); # next iv actually + +&set_label("dj7"); + &rotr("edx", 16); + &movb(&BP(6,$out,"",0), &LB("edx")); + &shr("edx",16); +&set_label("dj6"); + &movb(&BP(5,$out,"",0), &HB("edx")); +&set_label("dj5"); + &movb(&BP(4,$out,"",0), &LB("edx")); +&set_label("dj4"); + &mov(&DWP(0,$out,"",0), "ecx"); + &jmp(&label("djend")); +&set_label("dj3"); + &rotr("ecx", 16); + &movb(&BP(2,$out,"",0), &LB("ecx")); + &shl("ecx",16); +&set_label("dj2"); + &movb(&BP(1,$in,"",0), &HB("ecx")); +&set_label("dj1"); + &movb(&BP(0,$in,"",0), &LB("ecx")); +&set_label("djend"); + + # final iv is still in eax:ebx + &jmp(&label("finish")); + + +############################ FINISH #######################3 + &set_label("finish",1); + &mov("ecx", &wparam($iv_off)); # Get iv ptr + + ################################################# + $total=16+4; + $total+=4 if ($p1 > 0); + $total+=4 if ($p2 > 0); + $total+=4 if ($p3 > 0); + &add("esp",$total); + + &mov(&DWP(0,"ecx","",0), "eax"); # save iv + &mov(&DWP(4,"ecx","",0), "ebx"); # save iv + + &function_end_A($name); + + &set_label("cbc_enc_jmp_table",1); + &data_word("0"); + &data_word(&label("ej1")); + &data_word(&label("ej2")); + &data_word(&label("ej3")); + &data_word(&label("ej4")); + &data_word(&label("ej5")); + &data_word(&label("ej6")); + &data_word(&label("ej7")); + &set_label("cbc_dec_jmp_table",1); + &data_word("0"); + &data_word(&label("dj1")); + &data_word(&label("dj2")); + &data_word(&label("dj3")); + &data_word(&label("dj4")); + &data_word(&label("dj5")); + &data_word(&label("dj6")); + &data_word(&label("dj7")); + + &function_end_B($name); + + } + +1; diff -urN linux-2.4.29/net/ipsec/libcrypto/perlasm/readme linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/readme --- linux-2.4.29/net/ipsec/libcrypto/perlasm/readme Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/readme Thu Sep 5 05:26:32 2002 @@ -0,0 +1,124 @@ +The perl scripts in this directory are my 'hack' to generate +multiple different assembler formats via the one origional script. + +The way to use this library is to start with adding the path to this directory +and then include it. + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; + +The first thing we do is setup the file and type of assember + +&asm_init($ARGV[0],$0); + +The first argument is the 'type'. Currently +'cpp', 'sol', 'a.out', 'elf' or 'win32'. +Argument 2 is the file name. + +The reciprocal function is +&asm_finish() which should be called at the end. + +There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler, +and x86unix.pl which is the unix (gas) version. + +Functions of interest are: +&external_label("des_SPtrans"); declare and external variable +&LB(reg); Low byte for a register +&HB(reg); High byte for a register +&BP(off,base,index,scale) Byte pointer addressing +&DWP(off,base,index,scale) Word pointer addressing +&stack_push(num) Basically a 'sub esp, num*4' with extra +&stack_pop(num) inverse of stack_push +&function_begin(name,extra) Start a function with pushing of + edi, esi, ebx and ebp. extra is extra win32 + external info that may be required. +&function_begin_B(name,extra) Same as norma function_begin but no pushing. +&function_end(name) Call at end of function. +&function_end_A(name) Standard pop and ret, for use inside functions +&function_end_B(name) Call at end but with poping or 'ret'. +&swtmp(num) Address on stack temp word. +&wparam(num) Parameter number num, that was push + in C convention. This all works over pushes + and pops. +&comment("hello there") Put in a comment. +&label("loop") Refer to a label, normally a jmp target. +&set_label("loop") Set a label at this point. +&data_word(word) Put in a word of data. + +So how does this all hold together? Given + +int calc(int len, int *data) + { + int i,j=0; + + for (i=0; i"); +&comment(""); + + $filename =~ s/\.pl$//; + &file($filename); + } + +sub asm_finish_cpp + { + return unless $cpp; + + local($tmp,$i); + foreach $i (&get_labels()) + { + $tmp.="#define $i _$i\n"; + } + print <<"EOF"; +/* Run the C pre-processor over this file with one of the following defined + * ELF - elf object files, + * OUT - a.out object files, + * BSDI - BSDI style a.out object files + * SOL - Solaris style elf + */ + +#define TYPE(a,b) .type a,b +#define SIZE(a,b) .size a,b + +#if defined(OUT) || (defined(BSDI) && !defined(ELF)) +$tmp +#endif + +#ifdef OUT +#define OK 1 +#define ALIGN 4 +#endif + +#if defined(BSDI) && !defined(ELF) +#define OK 1 +#define ALIGN 4 +#undef SIZE +#undef TYPE +#define SIZE(a,b) +#define TYPE(a,b) +#endif + +#if defined(ELF) || defined(SOL) +#define OK 1 +#define ALIGN 16 +#endif + +#ifndef OK +You need to define one of +ELF - elf systems - linux-elf, NetBSD and DG-UX +OUT - a.out systems - linux-a.out and FreeBSD +SOL - solaris systems, which are elf with strange comment lines +BSDI - a.out with a very primative version of as. +#endif + +/* Let the Assembler begin :-) */ +EOF + } + +1; diff -urN linux-2.4.29/net/ipsec/libcrypto/perlasm/x86ms.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/x86ms.pl --- linux-2.4.29/net/ipsec/libcrypto/perlasm/x86ms.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/x86ms.pl Thu Sep 5 05:26:32 2002 @@ -0,0 +1,365 @@ +#!/usr/local/bin/perl + +package x86ms; + +$label="L000"; + +%lb=( 'eax', 'al', + 'ebx', 'bl', + 'ecx', 'cl', + 'edx', 'dl', + 'ax', 'al', + 'bx', 'bl', + 'cx', 'cl', + 'dx', 'dl', + ); + +%hb=( 'eax', 'ah', + 'ebx', 'bh', + 'ecx', 'ch', + 'edx', 'dh', + 'ax', 'ah', + 'bx', 'bh', + 'cx', 'ch', + 'dx', 'dh', + ); + +sub main'asm_init_output { @out=(); } +sub main'asm_get_output { return(@out); } +sub main'get_labels { return(@labels); } +sub main'external_label { push(@labels,@_); } + +sub main'LB + { + (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; + return($lb{$_[0]}); + } + +sub main'HB + { + (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; + return($hb{$_[0]}); + } + +sub main'BP + { + &get_mem("BYTE",@_); + } + +sub main'DWP + { + &get_mem("DWORD",@_); + } + +sub main'BC + { + return @_; + } + +sub main'DWC + { + return @_; + } + +sub main'stack_push + { + local($num)=@_; + $stack+=$num*4; + &main'sub("esp",$num*4); + } + +sub main'stack_pop + { + local($num)=@_; + $stack-=$num*4; + &main'add("esp",$num*4); + } + +sub get_mem + { + local($size,$addr,$reg1,$reg2,$idx)=@_; + local($t,$post); + local($ret)="$size PTR "; + + $addr =~ s/^\s+//; + if ($addr =~ /^(.+)\+(.+)$/) + { + $reg2=&conv($1); + $addr="_$2"; + } + elsif ($addr =~ /^[_a-zA-Z]/) + { + $addr="_$addr"; + } + + $reg1="$regs{$reg1}" if defined($regs{$reg1}); + $reg2="$regs{$reg2}" if defined($regs{$reg2}); + if (($addr ne "") && ($addr ne 0)) + { + if ($addr !~ /^-/) + { $ret.=$addr; } + else { $post=$addr; } + } + if ($reg2 ne "") + { + $t=""; + $t="*$idx" if ($idx != 0); + $reg1="+".$reg1 if ("$reg1$post" ne ""); + $ret.="[$reg2$t$reg1$post]"; + } + else + { + $ret.="[$reg1$post]" + } + return($ret); + } + +sub main'mov { &out2("mov",@_); } +sub main'movb { &out2("mov",@_); } +sub main'and { &out2("and",@_); } +sub main'or { &out2("or",@_); } +sub main'shl { &out2("shl",@_); } +sub main'shr { &out2("shr",@_); } +sub main'xor { &out2("xor",@_); } +sub main'xorb { &out2("xor",@_); } +sub main'add { &out2("add",@_); } +sub main'adc { &out2("adc",@_); } +sub main'sub { &out2("sub",@_); } +sub main'rotl { &out2("rol",@_); } +sub main'rotr { &out2("ror",@_); } +sub main'exch { &out2("xchg",@_); } +sub main'cmp { &out2("cmp",@_); } +sub main'lea { &out2("lea",@_); } +sub main'mul { &out1("mul",@_); } +sub main'div { &out1("div",@_); } +sub main'dec { &out1("dec",@_); } +sub main'inc { &out1("inc",@_); } +sub main'jmp { &out1("jmp",@_); } +sub main'jmp_ptr { &out1p("jmp",@_); } +sub main'je { &out1("je",@_); } +sub main'jle { &out1("jle",@_); } +sub main'jz { &out1("jz",@_); } +sub main'jge { &out1("jge",@_); } +sub main'jl { &out1("jl",@_); } +sub main'jb { &out1("jb",@_); } +sub main'jc { &out1("jc",@_); } +sub main'jnc { &out1("jnc",@_); } +sub main'jnz { &out1("jnz",@_); } +sub main'jne { &out1("jne",@_); } +sub main'jno { &out1("jno",@_); } +sub main'push { &out1("push",@_); $stack+=4; } +sub main'pop { &out1("pop",@_); $stack-=4; } +sub main'bswap { &out1("bswap",@_); &using486(); } +sub main'not { &out1("not",@_); } +sub main'call { &out1("call",'_'.$_[0]); } +sub main'ret { &out0("ret"); } +sub main'nop { &out0("nop"); } + +sub out2 + { + local($name,$p1,$p2)=@_; + local($l,$t); + + push(@out,"\t$name\t"); + $t=&conv($p1).","; + $l=length($t); + push(@out,$t); + $l=4-($l+9)/8; + push(@out,"\t" x $l); + push(@out,&conv($p2)); + push(@out,"\n"); + } + +sub out0 + { + local($name)=@_; + + push(@out,"\t$name\n"); + } + +sub out1 + { + local($name,$p1)=@_; + local($l,$t); + + push(@out,"\t$name\t".&conv($p1)."\n"); + } + +sub conv + { + local($p)=@_; + + $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; + return $p; + } + +sub using486 + { + return if $using486; + $using486++; + grep(s/\.386/\.486/,@out); + } + +sub main'file + { + local($file)=@_; + + local($tmp)=<<"EOF"; + TITLE $file.asm + .386 +.model FLAT +EOF + push(@out,$tmp); + } + +sub main'function_begin + { + local($func,$extra)=@_; + + push(@labels,$func); + + local($tmp)=<<"EOF"; +_TEXT SEGMENT +PUBLIC _$func +$extra +_$func PROC NEAR + push ebp + push ebx + push esi + push edi +EOF + push(@out,$tmp); + $stack=20; + } + +sub main'function_begin_B + { + local($func,$extra)=@_; + + local($tmp)=<<"EOF"; +_TEXT SEGMENT +PUBLIC _$func +$extra +_$func PROC NEAR +EOF + push(@out,$tmp); + $stack=4; + } + +sub main'function_end + { + local($func)=@_; + + local($tmp)=<<"EOF"; + pop edi + pop esi + pop ebx + pop ebp + ret +_$func ENDP +_TEXT ENDS +EOF + push(@out,$tmp); + $stack=0; + %label=(); + } + +sub main'function_end_B + { + local($func)=@_; + + local($tmp)=<<"EOF"; +_$func ENDP +_TEXT ENDS +EOF + push(@out,$tmp); + $stack=0; + %label=(); + } + +sub main'function_end_A + { + local($func)=@_; + + local($tmp)=<<"EOF"; + pop edi + pop esi + pop ebx + pop ebp + ret +EOF + push(@out,$tmp); + } + +sub main'file_end + { + push(@out,"END\n"); + } + +sub main'wparam + { + local($num)=@_; + + return(&main'DWP($stack+$num*4,"esp","",0)); + } + +sub main'swtmp + { + return(&main'DWP($_[0]*4,"esp","",0)); + } + +# Should use swtmp, which is above esp. Linix can trash the stack above esp +#sub main'wtmp +# { +# local($num)=@_; +# +# return(&main'DWP(-(($num+1)*4),"esp","",0)); +# } + +sub main'comment + { + foreach (@_) + { + push(@out,"\t; $_\n"); + } + } + +sub main'label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}="\$${label}${_[0]}"; + $label++; + } + return($label{$_[0]}); + } + +sub main'set_label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}="${label}${_[0]}"; + $label++; + } + if((defined $_[2]) && ($_[2] == 1)) + { + push(@out,"$label{$_[0]}::\n"); + } + else + { + push(@out,"$label{$_[0]}:\n"); + } + } + +sub main'data_word + { + push(@out,"\tDD\t$_[0]\n"); + } + +sub out1p + { + local($name,$p1)=@_; + local($l,$t); + + push(@out,"\t$name\t ".&conv($p1)."\n"); + } diff -urN linux-2.4.29/net/ipsec/libcrypto/perlasm/x86nasm.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/x86nasm.pl --- linux-2.4.29/net/ipsec/libcrypto/perlasm/x86nasm.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/x86nasm.pl Thu Sep 5 05:26:32 2002 @@ -0,0 +1,366 @@ +#!/usr/local/bin/perl + +package x86nasm; + +$label="L000"; + +%lb=( 'eax', 'al', + 'ebx', 'bl', + 'ecx', 'cl', + 'edx', 'dl', + 'ax', 'al', + 'bx', 'bl', + 'cx', 'cl', + 'dx', 'dl', + ); + +%hb=( 'eax', 'ah', + 'ebx', 'bh', + 'ecx', 'ch', + 'edx', 'dh', + 'ax', 'ah', + 'bx', 'bh', + 'cx', 'ch', + 'dx', 'dh', + ); + +%regs=( 'eax', 'eax', + 'ebx', 'ebx', + 'ecx', 'ecx', + 'edx', 'edx', + 'esi', 'esi', + 'edi', 'edi', + 'ebp', 'ebp', + 'esp', 'esp', + 'mm0', 'mm0', + 'mm1', 'mm1', + ); + +sub main::asm_init_output { @out=(); } +sub main::asm_get_output { return(@out); } +sub main::get_labels { return(@labels); } + +sub main::external_label +{ + push(@labels,@_); + foreach (@_) { + push(@out, "extern\t_$_\n"); + } +} + +sub main::LB + { + (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; + return($lb{$_[0]}); + } + +sub main::HB + { + (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; + return($hb{$_[0]}); + } + +sub main::BP + { + &get_mem("BYTE",@_); + } + +sub main::DWP + { + &get_mem("DWORD",@_); + } + +sub main::BC + { + return "BYTE @_"; + } + +sub main::DWC + { + return "DWORD @_"; + } + +sub main::stack_push + { + my($num)=@_; + $stack+=$num*4; + &main::sub("esp",$num*4); + } + +sub main::stack_pop + { + my($num)=@_; + $stack-=$num*4; + &main::add("esp",$num*4); + } + +sub get_mem + { + my($size,$addr,$reg1,$reg2,$idx)=@_; + my($t,$post); + my($ret)="["; + $addr =~ s/^\s+//; + if ($addr =~ /^(.+)\+(.+)$/) + { + if (defined($regs{$reg2})) { + $addr=join('+', &conv($1), "_$2"); + } else { + $reg2=&conv($1); + $addr="_$2"; + } + } + elsif ($addr =~ /^[_a-zA-Z]/) + { + $addr="_$addr"; + } + + $reg1="$regs{$reg1}" if defined($regs{$reg1}); + $reg2="$regs{$reg2}" if defined($regs{$reg2}); + if (($addr ne "") && ($addr ne 0)) + { + if ($addr !~ /^-/) + { $ret.="${addr}+"; } + else { $post=$addr; } + } + if ($reg2 ne "") + { + $t=""; + $t="*$idx" if ($idx != 0); + $reg1="+".$reg1 if ("$reg1$post" ne ""); + $ret.="$reg2$t$reg1$post]"; + } + else + { + $ret.="$reg1$post]" + } + return($ret); + } + +sub main::mov { &out2("mov",@_); } +sub main::movb { &out2("mov",@_); } +sub main::and { &out2("and",@_); } +sub main::or { &out2("or",@_); } +sub main::shl { &out2("shl",@_); } +sub main::shr { &out2("shr",@_); } +sub main::xor { &out2("xor",@_); } +sub main::xorb { &out2("xor",@_); } +sub main::add { &out2("add",@_); } +sub main::adc { &out2("adc",@_); } +sub main::sub { &out2("sub",@_); } +sub main::rotl { &out2("rol",@_); } +sub main::rotr { &out2("ror",@_); } +sub main::exch { &out2("xchg",@_); } +sub main::cmp { &out2("cmp",@_); } +sub main::lea { &out2("lea",@_); } +sub main::mul { &out1("mul",@_); } +sub main::div { &out1("div",@_); } +sub main::dec { &out1("dec",@_); } +sub main::inc { &out1("inc",@_); } +sub main::jmp { &out1("jmp",@_); } +sub main::jmp_ptr { &out1p("jmp",@_); } + +# This is a bit of a kludge: declare all branches as NEAR. +sub main::je { &out1("je NEAR",@_); } +sub main::jle { &out1("jle NEAR",@_); } +sub main::jz { &out1("jz NEAR",@_); } +sub main::jge { &out1("jge NEAR",@_); } +sub main::jl { &out1("jl NEAR",@_); } +sub main::jb { &out1("jb NEAR",@_); } +sub main::jc { &out1("jc NEAR",@_); } +sub main::jnc { &out1("jnc NEAR",@_); } +sub main::jnz { &out1("jnz NEAR",@_); } +sub main::jne { &out1("jne NEAR",@_); } +sub main::jno { &out1("jno NEAR",@_); } + +sub main::push { &out1("push",@_); $stack+=4; } +sub main::pop { &out1("pop",@_); $stack-=4; } +sub main::bswap { &out1("bswap",@_); &using486(); } +sub main::not { &out1("not",@_); } +sub main::call { &out1("call",'_'.$_[0]); } +sub main::ret { &out0("ret"); } +sub main::nop { &out0("nop"); } + +sub out2 + { + my($name,$p1,$p2)=@_; + my($l,$t); + + push(@out,"\t$name\t"); + $t=&conv($p1).","; + $l=length($t); + push(@out,$t); + $l=4-($l+9)/8; + push(@out,"\t" x $l); + push(@out,&conv($p2)); + push(@out,"\n"); + } + +sub out0 + { + my($name)=@_; + + push(@out,"\t$name\n"); + } + +sub out1 + { + my($name,$p1)=@_; + my($l,$t); + push(@out,"\t$name\t".&conv($p1)."\n"); + } + +sub conv + { + my($p)=@_; + $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; + return $p; + } + +sub using486 + { + return if $using486; + $using486++; + grep(s/\.386/\.486/,@out); + } + +sub main::file + { + push(@out, "segment .text\n"); + } + +sub main::function_begin + { + my($func,$extra)=@_; + + push(@labels,$func); + my($tmp)=<<"EOF"; +global _$func +_$func: + push ebp + push ebx + push esi + push edi +EOF + push(@out,$tmp); + $stack=20; + } + +sub main::function_begin_B + { + my($func,$extra)=@_; + my($tmp)=<<"EOF"; +global _$func +_$func: +EOF + push(@out,$tmp); + $stack=4; + } + +sub main::function_end + { + my($func)=@_; + + my($tmp)=<<"EOF"; + pop edi + pop esi + pop ebx + pop ebp + ret +EOF + push(@out,$tmp); + $stack=0; + %label=(); + } + +sub main::function_end_B + { + $stack=0; + %label=(); + } + +sub main::function_end_A + { + my($func)=@_; + + my($tmp)=<<"EOF"; + pop edi + pop esi + pop ebx + pop ebp + ret +EOF + push(@out,$tmp); + } + +sub main::file_end + { + } + +sub main::wparam + { + my($num)=@_; + + return(&main::DWP($stack+$num*4,"esp","",0)); + } + +sub main::swtmp + { + return(&main::DWP($_[0]*4,"esp","",0)); + } + +# Should use swtmp, which is above esp. Linix can trash the stack above esp +#sub main::wtmp +# { +# my($num)=@_; +# +# return(&main::DWP(-(($num+1)*4),"esp","",0)); +# } + +sub main::comment + { + foreach (@_) + { + push(@out,"\t; $_\n"); + } + } + +sub main::label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}="\$${label}${_[0]}"; + $label++; + } + return($label{$_[0]}); + } + +sub main::set_label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}="${label}${_[0]}"; + $label++; + } + push(@out,"$label{$_[0]}:\n"); + } + +sub main::data_word + { + push(@out,"\tDD\t$_[0]\n"); + } + +sub out1p + { + my($name,$p1)=@_; + my($l,$t); + + push(@out,"\t$name\t ".&conv($p1)."\n"); + } + +## +## Additional functions required for MMX and other ops +## +sub main::testb { &out2('test', @_) } +sub main::movzx { &out2('movzx', @_) } +sub main::movd { &out2('movd', @_) } +sub main::emms { &out0('emms', @_) } diff -urN linux-2.4.29/net/ipsec/libcrypto/perlasm/x86unix.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/x86unix.pl --- linux-2.4.29/net/ipsec/libcrypto/perlasm/x86unix.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libcrypto/perlasm/x86unix.pl Sat Oct 26 21:24:16 2002 @@ -0,0 +1,470 @@ +#!/usr/local/bin/perl + +package x86unix; + +$label="L000"; + +$align=($main::aout)?"4":"16"; +$under=($main::aout)?"_":""; +$com_start=($main::sol)?"/":"#"; + +sub main::asm_init_output { @out=(); } +sub main::asm_get_output { return(@out); } +sub main::get_labels { return(@labels); } +sub main::external_label { push(@labels,@_); } + +if ($main::cpp) + { + $align="ALIGN"; + $under=""; + $com_start='/*'; + $com_end='*/'; + } + +%lb=( 'eax', '%al', + 'ebx', '%bl', + 'ecx', '%cl', + 'edx', '%dl', + 'ax', '%al', + 'bx', '%bl', + 'cx', '%cl', + 'dx', '%dl', + ); + +%hb=( 'eax', '%ah', + 'ebx', '%bh', + 'ecx', '%ch', + 'edx', '%dh', + 'ax', '%ah', + 'bx', '%bh', + 'cx', '%ch', + 'dx', '%dh', + ); + +%regs=( 'eax', '%eax', + 'ebx', '%ebx', + 'ecx', '%ecx', + 'edx', '%edx', + 'esi', '%esi', + 'edi', '%edi', + 'ebp', '%ebp', + 'esp', '%esp', + 'mm0', '%mm0', + 'mm1', '%mm1', + ); + +%reg_val=( + 'eax', 0x00, + 'ebx', 0x03, + 'ecx', 0x01, + 'edx', 0x02, + 'esi', 0x06, + 'edi', 0x07, + 'ebp', 0x05, + 'esp', 0x04, + ); + +sub main::LB + { + (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; + return($lb{$_[0]}); + } + +sub main::HB + { + (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; + return($hb{$_[0]}); + } + +sub main::DWP + { + local($addr,$reg1,$reg2,$idx)=@_; + + $ret=""; + $addr =~ s/(^|[+ \t])([A-Za-z_]+[A-Za-z0-9_]+)($|[+ \t])/$1$under$2$3/; + $reg1="$regs{$reg1}" if defined($regs{$reg1}); + $reg2="$regs{$reg2}" if defined($regs{$reg2}); + $ret.=$addr if ($addr ne "") && ($addr ne 0); + if ($reg2 ne "") + { + if($idx ne "") + { $ret.="($reg1,$reg2,$idx)"; } + else + { $ret.="($reg1,$reg2)"; } + } + else + { $ret.="($reg1)" } + return($ret); + } + +sub main::BP + { + return(&main::DWP(@_)); + } + +sub main::BC + { + return @_; + } + +sub main::DWC + { + return @_; + } + +#sub main::BP +# { +# local($addr,$reg1,$reg2,$idx)=@_; +# +# $ret=""; +# +# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; +# $reg1="$regs{$reg1}" if defined($regs{$reg1}); +# $reg2="$regs{$reg2}" if defined($regs{$reg2}); +# $ret.=$addr if ($addr ne "") && ($addr ne 0); +# if ($reg2 ne "") +# { $ret.="($reg1,$reg2,$idx)"; } +# else +# { $ret.="($reg1)" } +# return($ret); +# } + +sub main::mov { &out2("movl",@_); } +sub main::movb { &out2("movb",@_); } +sub main::and { &out2("andl",@_); } +sub main::or { &out2("orl",@_); } +sub main::shl { &out2("sall",@_); } +sub main::shr { &out2("shrl",@_); } +sub main::xor { &out2("xorl",@_); } +sub main::xorb { &out2("xorb",@_); } +sub main::add { &out2("addl",@_); } +sub main::adc { &out2("adcl",@_); } +sub main::sub { &out2("subl",@_); } +sub main::rotl { &out2("roll",@_); } +sub main::rotr { &out2("rorl",@_); } +sub main::exch { &out2("xchg",@_); } +sub main::cmp { &out2("cmpl",@_); } +sub main::lea { &out2("leal",@_); } +sub main::mul { &out1("mull",@_); } +sub main::div { &out1("divl",@_); } +sub main::jmp { &out1("jmp",@_); } +sub main::jmp_ptr { &out1p("jmp",@_); } +sub main::je { &out1("je",@_); } +sub main::jle { &out1("jle",@_); } +sub main::jne { &out1("jne",@_); } +sub main::jnz { &out1("jnz",@_); } +sub main::jz { &out1("jz",@_); } +sub main::jge { &out1("jge",@_); } +sub main::jl { &out1("jl",@_); } +sub main::jb { &out1("jb",@_); } +sub main::jc { &out1("jc",@_); } +sub main::jnc { &out1("jnc",@_); } +sub main::jno { &out1("jno",@_); } +sub main::dec { &out1("decl",@_); } +sub main::inc { &out1("incl",@_); } +sub main::push { &out1("pushl",@_); $stack+=4; } +sub main::pop { &out1("popl",@_); $stack-=4; } +sub main::not { &out1("notl",@_); } +sub main::call { &out1("call",$under.$_[0]); } +sub main::ret { &out0("ret"); } +sub main::nop { &out0("nop"); } + +# The bswapl instruction is new for the 486. Emulate if i386. +sub main::bswap + { + if ($main::i386) + { + &main::comment("bswapl @_"); + &main::exch(main::HB(@_),main::LB(@_)); + &main::rotr(@_,16); + &main::exch(main::HB(@_),main::LB(@_)); + } + else + { + &out1("bswapl",@_); + } + } + +sub out2 + { + local($name,$p1,$p2)=@_; + local($l,$ll,$t); + local(%special)=( "roll",0xD1C0,"rorl",0xD1C8, + "rcll",0xD1D0,"rcrl",0xD1D8, + "shll",0xD1E0,"shrl",0xD1E8, + "sarl",0xD1F8); + + if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1)) + { + $op=$special{$name}|$reg_val{$p1}; + $tmp1=sprintf(".byte %d\n",($op>>8)&0xff); + $tmp2=sprintf(".byte %d\t",$op &0xff); + push(@out,$tmp1); + push(@out,$tmp2); + + $p2=&conv($p2); + $p1=&conv($p1); + &main::comment("$name $p2 $p1"); + return; + } + + push(@out,"\t$name\t"); + $t=&conv($p2).","; + $l=length($t); + push(@out,$t); + $ll=4-($l+9)/8; + $tmp1=sprintf("\t" x $ll); + push(@out,$tmp1); + push(@out,&conv($p1)."\n"); + } + +sub out1 + { + local($name,$p1)=@_; + local($l,$t); + local(%special)=("bswapl",0x0FC8); + + if ((defined($special{$name})) && defined($regs{$p1})) + { + $op=$special{$name}|$reg_val{$p1}; + $tmp1=sprintf(".byte %d\n",($op>>8)&0xff); + $tmp2=sprintf(".byte %d\t",$op &0xff); + push(@out,$tmp1); + push(@out,$tmp2); + + $p2=&conv($p2); + $p1=&conv($p1); + &main::comment("$name $p2 $p1"); + return; + } + + push(@out,"\t$name\t".&conv($p1)."\n"); + } + +sub out1p + { + local($name,$p1)=@_; + local($l,$t); + + push(@out,"\t$name\t*".&conv($p1)."\n"); + } + +sub out0 + { + push(@out,"\t$_[0]\n"); + } + +sub conv + { + local($p)=@_; + +# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; + + $p=$regs{$p} if (defined($regs{$p})); + + $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/; + $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/; + return $p; + } + +sub main::file + { + local($file)=@_; + + local($tmp)=<<"EOF"; + .file "$file.s" + .version "01.01" +EOF + push(@out,$tmp); + } + +sub main::function_begin + { + local($func)=@_; + + &main::external_label($func); + $func=$under.$func; + + local($tmp)=<<"EOF"; +.text + .align $align +.globl $func +EOF + push(@out,$tmp); + if ($main::cpp) + { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } + elsif ($main::gaswin) + { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } + else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } + push(@out,"$func:\n"); + $tmp=<<"EOF"; + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + +EOF + push(@out,$tmp); + $stack=20; + } + +sub main::function_begin_B + { + local($func,$extra)=@_; + + &main::external_label($func); + $func=$under.$func; + + local($tmp)=<<"EOF"; +.text + .align $align +.globl $func +EOF + push(@out,$tmp); + if ($main::cpp) + { push(@out,"\tTYPE($func,\@function)\n"); } + elsif ($main::gaswin) + { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } + else { push(@out,"\t.type $func,\@function\n"); } + push(@out,"$func:\n"); + $stack=4; + } + +sub main::function_end + { + local($func)=@_; + + $func=$under.$func; + + local($tmp)=<<"EOF"; + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.${func}_end: +EOF + push(@out,$tmp); + if ($main::cpp) + { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } + elsif ($main::gaswin) + { $tmp=push(@out,"\t.align 4\n"); } + else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); } + push(@out,".ident \"$func\"\n"); + $stack=0; + %label=(); + } + +sub main::function_end_A + { + local($func)=@_; + + local($tmp)=<<"EOF"; + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +EOF + push(@out,$tmp); + } + +sub main::function_end_B + { + local($func)=@_; + + $func=$under.$func; + + push(@out,".L_${func}_end:\n"); + if ($main::cpp) + { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } + elsif ($main::gaswin) + { push(@out,"\t.align 4\n"); } + else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } + push(@out,".ident \"desasm.pl\"\n"); + $stack=0; + %label=(); + } + +sub main::wparam + { + local($num)=@_; + + return(&main::DWP($stack+$num*4,"esp","",0)); + } + +sub main::stack_push + { + local($num)=@_; + $stack+=$num*4; + &main::sub("esp",$num*4); + } + +sub main::stack_pop + { + local($num)=@_; + $stack-=$num*4; + &main::add("esp",$num*4); + } + +sub main::swtmp + { + return(&main::DWP($_[0]*4,"esp","",0)); + } + +# Should use swtmp, which is above esp. Linix can trash the stack above esp +#sub main::wtmp +# { +# local($num)=@_; +# +# return(&main::DWP(-($num+1)*4,"esp","",0)); +# } + +sub main::comment + { + foreach (@_) + { + if (/^\s*$/) + { push(@out,"\n"); } + else + { push(@out,"\t$com_start $_ $com_end\n"); } + } + } + +sub main::label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}=".${label}${_[0]}"; + $label++; + } + return($label{$_[0]}); + } + +sub main::set_label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}=".${label}${_[0]}"; + $label++; + } + push(@out,".align $align\n") if ($_[1] != 0); + push(@out,"$label{$_[0]}:\n"); + } + +sub main::file_end + { + } + +sub main::data_word + { + push(@out,"\t.long $_[0]\n"); + } + +## +## Additional functions required for MMX and other ops +## +sub main::testb { &out2('testb', @_) } +sub main::movzx { &out2('movzx', @_) } +sub main::movd { &out2('movd', @_) } +sub main::emms { &out0('emms', @_) } diff -urN linux-2.4.29/net/ipsec/libdes/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/Makefile --- linux-2.4.29/net/ipsec/libdes/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/Makefile Thu Sep 5 05:13:20 2002 @@ -0,0 +1,268 @@ +include ../Makefile.inc + + +# You must select the correct terminal control system to be used to +# turn character echo off when reading passwords. There a 5 systems +# SGTTY - the old BSD system +# TERMIO - most system V boxes +# TERMIOS - SGI (ala IRIX). +# VMS - the DEC operating system +# MSDOS - we all know what it is :-) +# read_pwd.c makes a reasonable guess at what is correct. + +# Targets +# make - twidle the options yourself :-) +# make cc - standard cc options +# make gcc - standard gcc options +# make x86-elf - linux-elf etc +# make x86-out - linux-a.out, FreeBSD etc +# make x86-solaris +# make x86-bdsi + +# If you are on a DEC Alpha, edit des.h and change the DES_LONG +# define to 'unsigned int'. I have seen this give a %20 speedup. + +OPTS0= -DLIBDES_LIT -DRAND -DTERMIO #-DNOCONST + +# Version 1.94 has changed the strings_to_key function so that it is +# now compatible with MITs when the string is longer than 8 characters. +# If you wish to keep the old version, uncomment the following line. +# This will affect the -E/-D options on des(1). +#OPTS1= -DOLD_STR_TO_KEY + +# There are 4 possible performance options +# -DDES_PTR +# -DDES_RISC1 +# -DDES_RISC2 (only one of DES_RISC1 and DES_RISC2) +# -DDES_UNROLL +# after the initial build, run 'des_opts' to see which options are best +# for your platform. There are some listed in options.txt +#OPTS2= -DDES_PTR +#OPTS3= -DDES_RISC1 # or DES_RISC2 +#OPTS4= -DDES_UNROLL + +OPTS= $(OPTS0) $(OPTS1) $(OPTS2) $(OPTS3) $(OPTS4) + +MAKE=make -f Makefile +#CC=cc +#CFLAG= -O + +#CC=gcc +#CFLAG= -O4 -funroll-loops -fomit-frame-pointer +# normally overridden by FreeS/WAN Makefiles anyway +CFLAG= -O3 -fomit-frame-pointer + +CFLAGS=$(OPTS) $(CFLAG) +CPP=$(CC) -E +AS=as + +# Assember version of des_encrypt*(). +DES_ENC=des_enc.o fcrypt_b.o # normal C version +#DES_ENC=asm/dx86-elf.o asm/yx86-elf.o # elf format x86 +#DES_ENC=asm/dx86-out.o asm/yx86-out.o # a.out format x86 +#DES_ENC=asm/dx86-sol.o asm/yx86-sol.o # solaris format x86 +#DES_ENC=asm/dx86bsdi.o asm/yx86basi.o # bsdi format x86 + +LIBDIR=${DESTDIR}/usr/local/lib +BINDIR=${DESTDIR}/usr/local/bin +INCDIR=${DESTDIR}/usr/local/include +MANDIR=${DESTDIR}/usr/local/man +MAN1=1 +MAN3=3 +SHELL=/bin/sh +OBJ_LIT=cbc_enc.o ecb_enc.o $(DES_ENC) fcrypt.o set_key.o +OBJ_FULL=cbc_cksm.o $(OBJ_LIT) pcbc_enc.o \ + xcbc_enc.o qud_cksm.o \ + cfb64ede.o cfb64enc.o cfb_enc.o ecb3_enc.o \ + enc_read.o enc_writ.o ofb64ede.o ofb64enc.o ofb_enc.o \ + rand_key.o read_pwd.o read2pwd.o rpc_enc.o str2key.o supp.o + +GENERAL_LIT=COPYRIGHT INSTALL README VERSION Makefile des_crypt.man \ + des.doc options.txt asm +GENERAL_FULL=$(GENERAL_LIT) FILES Imakefile times vms.com KERBEROS MODES.DES \ + des.man DES.pm DES.pod DES.xs Makefile.PL dess.S des3s.S \ + Makefile.uni typemap t Makefile.ssl makefile.bc Makefile.lit \ + des.org des_locl.org +TESTING_LIT= destest speed des_opts +TESTING_FULL= rpw $(TESTING_LIT) +TESTING_SRC_LIT=destest.c speed.c des_opts.c +TESTING_SRC_FULL=rpw.c $(TESTING_SRC_LIT) +HEADERS_LIT=des_ver.h des.h des_locl.h podd.h sk.h spr.h +HEADERS_FULL= $(HEADERS_LIT) rpc_des.h +LIBDES_LIT=cbc_enc.c ecb_enc.c fcrypt.c set_key.c des_enc.c fcrypt_b.c +LIBDES_FULL= cbc_cksm.c pcbc_enc.c qud_cksm.c \ + cfb64ede.c cfb64enc.c cfb_enc.c ecb3_enc.c \ + enc_read.c enc_writ.c ofb64ede.c ofb64enc.c ofb_enc.c \ + rand_key.c rpc_enc.c str2key.c supp.c \ + xcbc_enc.c $(LIBDES_LIT) read_pwd.c read2pwd.c + +PERL= des.pl testdes.pl doIP doPC1 doPC2 PC1 PC2 shifts.pl + +OBJ= $(OBJ_LIT) +GENERAL=$(GENERAL_LIT) +TESTING=$(TESTING_LIT) +TESTING_SRC=$(TESTING_SRC_LIT) +HEADERS=$(HEADERS_LIT) +LIBDES= $(LIBDES_LIT) + +ALL= $(GENERAL) $(TESTING_SRC) $(LIBDES) $(PERL) $(HEADERS) + +DLIB= libdes.a + +.PHONY: all cc gcc x86-elf x86-out x86-solaris x86-bsdi test tar_lit \ + tar shar depend clean dclean install check checkprograms + +programs: $(DLIB) + +all: $(DLIB) $(TESTING) + +cc: + $(MAKE) CC=cc CFLAGS="-O $(OPTS) $(CFLAG)" all + +gcc: + $(MAKE) CC=gcc CFLAGS="-O3 -fomit-frame-pointer $(OPTS) $(CFLAG)" all + +x86-elf: + $(MAKE) DES_ENC='asm/dx86-elf.o asm/yx86-elf.o' CC='$(CC)' CFLAGS="-DELF $(OPTS) $(CFLAG)" all + +x86-out: + $(MAKE) DES_ENC='asm/dx86-out.o asm/yx86-out.o' CC='$(CC)' CFLAGS="-DOUT $(OPTS) $(CFLAG)" all + +x86-solaris: + $(MAKE) DES_ENC='asm/dx86-sol.o asm/yx86-sol.o' CC='$(CC)' CFLAGS="-DSOL $(OPTS) $(CFLAG)" all + +x86-bsdi: + $(MAKE) DES_ENC='asm/dx86bsdi.o asm/yx86bsdi.o' CC='$(CC)' CFLAGS="-DBSDI $(OPTS) $(CFLAG)" all + +# elf +asm/dx86-elf.o: asm/dx86unix.S + $(CPP) -DELF asm/dx86unix.S | $(AS) -o asm/dx86-elf.o + +asm/yx86-elf.o: asm/yx86unix.S + $(CPP) -DELF asm/yx86unix.S | $(AS) -o asm/yx86-elf.o + +# solaris +asm/dx86-sol.o: asm/dx86unix.S + $(CC) -E -DSOL asm/dx86unix.S | sed 's/^#.*//' > asm/dx86-sol.s + as -o asm/dx86-sol.o asm/dx86-sol.s + rm -f asm/dx86-sol.s + +asm/yx86-sol.o: asm/yx86unix.S + $(CC) -E -DSOL asm/yx86unix.S | sed 's/^#.*//' > asm/yx86-sol.s + as -o asm/yx86-sol.o asm/yx86-sol.s + rm -f asm/yx86-sol.s + +# a.out +asm/dx86-out.o: asm/dx86unix.S + $(CPP) -DOUT asm/dx86unix.S | $(AS) -o asm/dx86-out.o + +asm/yx86-out.o: asm/yx86unix.S + $(CPP) -DOUT asm/yx86unix.S | $(AS) -o asm/yx86-out.o + +# bsdi +asm/dx86bsdi.o: asm/dx86unix.S + $(CPP) -DBSDI asm/dx86unix.S | $(AS) -o asm/dx86bsdi.o + +asm/yx86bsdi.o: asm/yx86unix.S + $(CPP) -DBSDI asm/yx86unix.S | $(AS) -o asm/yx86bsdi.o + +asm/dx86unix.S: + (cd asm; perl des-586.pl cpp >dx86unix.S) + +asm/yx86unix.S: + (cd asm; perl crypt586.pl cpp >yx86unix.S) + +test: all + ./destest + +$(DLIB): $(OBJ) + /bin/rm -f $(DLIB) + ar cr $(DLIB) $(OBJ) + -if test -s /bin/ranlib; then /bin/ranlib $(DLIB); \ + else if test -s /usr/bin/ranlib; then /usr/bin/ranlib $(DLIB); \ + else exit 0; fi; fi + +des_opts: des_opts.o $(DLIB) + $(CC) $(CFLAGS) -o des_opts des_opts.o $(DLIB) + +destest: destest.o $(DLIB) + $(CC) $(CFLAGS) -o destest destest.o $(DLIB) + +rpw: rpw.o $(DLIB) + $(CC) $(CFLAGS) -o rpw rpw.o $(DLIB) + +speed: speed.o $(DLIB) + $(CC) $(CFLAGS) -o speed speed.o $(DLIB) + +des: des.o $(DLIB) + $(CC) $(CFLAGS) -o des des.o $(DLIB) + +tags: + ctags $(TESTING_SRC) $(LIBDES) + +tar_lit: + /bin/mv Makefile Makefile.tmp + /bin/cp Makefile.lit Makefile + tar chf libdes-l.tar $(LIBDES_LIT) $(HEADERS_LIT) \ + $(GENERAL_LIT) $(TESTING_SRC_LIT) + /bin/rm -f Makefile + /bin/mv Makefile.tmp Makefile + +tar: + tar chf libdes.tar $(ALL) + +shar: + shar $(ALL) >libdes.shar + +depend: + makedepend $(LIBDES) $(TESTING_SRC) + +clean: + /bin/rm -f *.o tags core $(TESTING) $(DLIB) .nfs* *.old *.bak asm/*.o \ + asm/*.S + +dclean: + sed -e '/^# DO NOT DELETE THIS LINE/ q' Makefile >Makefile.new + mv -f Makefile.new Makefile + +# Eric is probably going to choke when he next looks at this --tjh +install: + if test $(INSTALLTOP); then \ + echo SSL style install; \ + cp $(DLIB) $(INSTALLTOP)/lib; \ + if test -s /bin/ranlib; then \ + /bin/ranlib $(INSTALLTOP)/lib/$(DLIB); \ + else \ + if test -s /usr/bin/ranlib; then \ + /usr/bin/ranlib $(INSTALLTOP)/lib/$(DLIB); \ + fi; fi; \ + chmod 644 $(INSTALLTOP)/lib/$(DLIB); \ + cp des.h $(INSTALLTOP)/include; \ + chmod 644 $(INSTALLTOP)/include/des.h; \ + else \ + echo Standalone install; \ + mkdir -p ${LIBDIR}; \ + cp $(DLIB) $(LIBDIR)/$(DLIB); \ + if test -s /bin/ranlib; then \ + /bin/ranlib $(LIBDIR)/$(DLIB); \ + else \ + if test -s /usr/bin/ranlib; then \ + /usr/bin/ranlib $(LIBDIR)/$(DLIB); \ + fi; \ + fi; \ + chmod 644 $(LIBDIR)/$(DLIB); \ + mkdir -p ${MANDIR}/man${MAN3}; \ + cp des_crypt.man $(MANDIR)/man$(MAN3)/des_crypt.$(MAN3); \ + chmod 644 $(MANDIR)/man$(MAN3)/des_crypt.$(MAN3); \ + mkdir -p ${INCDIR}; \ + cp des.h $(INCDIR)/des.h; \ + chmod 644 $(INCDIR)/des.h; \ + fi + +check: + echo no checks in lib right now. + +checkprograms: + +# DO NOT DELETE THIS LINE -- make depend depends on it. + diff -urN linux-2.4.29/net/ipsec/libdes/asm/crypt586.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/crypt586.pl --- linux-2.4.29/net/ipsec/libdes/asm/crypt586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/crypt586.pl Thu Sep 5 05:13:20 2002 @@ -0,0 +1,204 @@ +#!/usr/local/bin/perl +# +# The inner loop instruction sequence and the IP/FP modifications are from +# Svend Olaf Mikkelsen +# I've added the stuff needed for crypt() but I've not worried about making +# things perfect. +# + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"crypt586.pl"); + +$L="edi"; +$R="esi"; + +&external_label("des_SPtrans"); +&fcrypt_body("fcrypt_body"); +&asm_finish(); + +sub fcrypt_body + { + local($name,$do_ip)=@_; + + &function_begin($name,"EXTRN _des_SPtrans:DWORD"); + + &comment(""); + &comment("Load the 2 words"); + $ks="ebp"; + + &xor( $L, $L); + &xor( $R, $R); + &mov($ks,&wparam(1)); + + &push(25); # add a variable + + &set_label("start"); + for ($i=0; $i<16; $i+=2) + { + &comment(""); + &comment("Round $i"); + &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); + + &comment(""); + &comment("Round ".sprintf("%d",$i+1)); + &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); + } + &mov("ebx", &swtmp(0)); + &mov("eax", $L); + &dec("ebx"); + &mov($L, $R); + &mov($R, "eax"); + &mov(&swtmp(0), "ebx"); + &jnz(&label("start")); + + &comment(""); + &comment("FP"); + &mov("edx",&wparam(0)); + + &FP_new($R,$L,"eax",3); + &mov(&DWP(0,"edx","",0),"eax"); + &mov(&DWP(4,"edx","",0),$L); + + &pop("ecx"); # remove variable + + &function_end($name); + } + +sub D_ENCRYPT + { + local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; + + &mov( $u, &wparam(2)); # 2 + &mov( $t, $R); + &shr( $t, 16); # 1 + &mov( $tmp2, &wparam(3)); # 2 + &xor( $t, $R); # 1 + + &and( $u, $t); # 2 + &and( $t, $tmp2); # 2 + + &mov( $tmp1, $u); + &shl( $tmp1, 16); # 1 + &mov( $tmp2, $t); + &shl( $tmp2, 16); # 1 + &xor( $u, $tmp1); # 2 + &xor( $t, $tmp2); # 2 + &mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2 + &xor( $u, $tmp1); + &mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2 + &xor( $u, $R); + &xor( $t, $R); + &xor( $t, $tmp2); + + &and( $u, "0xfcfcfcfc" ); # 2 + &xor( $tmp1, $tmp1); # 1 + &and( $t, "0xcfcfcfcf" ); # 2 + &xor( $tmp2, $tmp2); + &movb( &LB($tmp1), &LB($u) ); + &movb( &LB($tmp2), &HB($u) ); + &rotr( $t, 4 ); + &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); + &movb( &LB($tmp1), &LB($t) ); + &xor( $L, $ks); + &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); + &xor( $L, $ks); + &movb( &LB($tmp2), &HB($t) ); + &shr( $u, 16); + &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); + &xor( $L, $ks); + &movb( &LB($tmp1), &HB($u) ); + &shr( $t, 16); + &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); + &xor( $L, $ks); + &mov( $ks, &wparam(1)); + &movb( &LB($tmp2), &HB($t) ); + &and( $u, "0xff" ); + &and( $t, "0xff" ); + &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); + &xor( $L, $tmp1); + &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); + &xor( $L, $tmp1); + &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); + &xor( $L, $tmp1); + &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); + &xor( $L, $tmp1); + } + +sub n2a + { + sprintf("%d",$_[0]); + } + +# now has a side affect of rotating $a by $shift +sub R_PERM_OP + { + local($a,$b,$tt,$shift,$mask,$last)=@_; + + &rotl( $a, $shift ) if ($shift != 0); + &mov( $tt, $a ); + &xor( $a, $b ); + &and( $a, $mask ); + if ($notlast eq $b) + { + &xor( $b, $a ); + &xor( $tt, $a ); + } + else + { + &xor( $tt, $a ); + &xor( $b, $a ); + } + &comment(""); + } + +sub IP_new + { + local($l,$r,$tt,$lr)=@_; + + &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); + &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); + &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); + &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); + &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); + + if ($lr != 3) + { + if (($lr-3) < 0) + { &rotr($tt, 3-$lr); } + else { &rotl($tt, $lr-3); } + } + if ($lr != 2) + { + if (($lr-2) < 0) + { &rotr($r, 2-$lr); } + else { &rotl($r, $lr-2); } + } + } + +sub FP_new + { + local($l,$r,$tt,$lr)=@_; + + if ($lr != 2) + { + if (($lr-2) < 0) + { &rotl($r, 2-$lr); } + else { &rotr($r, $lr-2); } + } + if ($lr != 3) + { + if (($lr-3) < 0) + { &rotl($l, 3-$lr); } + else { &rotr($l, $lr-3); } + } + + &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); + &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); + &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); + &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); + &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); + &rotr($tt , 4); + } + diff -urN linux-2.4.29/net/ipsec/libdes/asm/des-586.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/des-586.pl --- linux-2.4.29/net/ipsec/libdes/asm/des-586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/des-586.pl Thu Sep 5 05:13:20 2002 @@ -0,0 +1,251 @@ +#!/usr/local/bin/perl +# +# The inner loop instruction sequence and the IP/FP modifications are from +# Svend Olaf Mikkelsen +# + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; +require "cbc.pl"; +require "desboth.pl"; + +# base code is in microsft +# op dest, source +# format. +# + +&asm_init($ARGV[0],"des-586.pl"); + +$L="edi"; +$R="esi"; + +&external_label("des_SPtrans"); +&des_encrypt("des_encrypt",1); +&des_encrypt("des_encrypt2",0); +&des_encrypt3("des_encrypt3",1); +&des_encrypt3("des_decrypt3",0); +&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1); +&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5); + +&asm_finish(); + +sub des_encrypt + { + local($name,$do_ip)=@_; + + &function_begin_B($name,"EXTRN _des_SPtrans:DWORD"); + + &push("esi"); + &push("edi"); + + &comment(""); + &comment("Load the 2 words"); + $ks="ebp"; + + if ($do_ip) + { + &mov($R,&wparam(0)); + &xor( "ecx", "ecx" ); + + &push("ebx"); + &push("ebp"); + + &mov("eax",&DWP(0,$R,"",0)); + &mov("ebx",&wparam(2)); # get encrypt flag + &mov($L,&DWP(4,$R,"",0)); + &comment(""); + &comment("IP"); + &IP_new("eax",$L,$R,3); + } + else + { + &mov("eax",&wparam(0)); + &xor( "ecx", "ecx" ); + + &push("ebx"); + &push("ebp"); + + &mov($R,&DWP(0,"eax","",0)); + &mov("ebx",&wparam(2)); # get encrypt flag + &rotl($R,3); + &mov($L,&DWP(4,"eax","",0)); + &rotl($L,3); + } + + &mov( $ks, &wparam(1) ); + &cmp("ebx","0"); + &je(&label("start_decrypt")); + + for ($i=0; $i<16; $i+=2) + { + &comment(""); + &comment("Round $i"); + &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); + + &comment(""); + &comment("Round ".sprintf("%d",$i+1)); + &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); + } + &jmp(&label("end")); + + &set_label("start_decrypt"); + + for ($i=15; $i>0; $i-=2) + { + &comment(""); + &comment("Round $i"); + &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); + &comment(""); + &comment("Round ".sprintf("%d",$i-1)); + &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx"); + } + + &set_label("end"); + + if ($do_ip) + { + &comment(""); + &comment("FP"); + &mov("edx",&wparam(0)); + &FP_new($L,$R,"eax",3); + + &mov(&DWP(0,"edx","",0),"eax"); + &mov(&DWP(4,"edx","",0),$R); + } + else + { + &comment(""); + &comment("Fixup"); + &rotr($L,3); # r + &mov("eax",&wparam(0)); + &rotr($R,3); # l + &mov(&DWP(0,"eax","",0),$L); + &mov(&DWP(4,"eax","",0),$R); + } + + &pop("ebp"); + &pop("ebx"); + &pop("edi"); + &pop("esi"); + &ret(); + + &function_end_B($name); + } + +sub D_ENCRYPT + { + local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_; + + &mov( $u, &DWP(&n2a($S*4),$ks,"",0)); + &xor( $tmp1, $tmp1); + &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0)); + &xor( $u, $R); + &xor( $t, $R); + &and( $u, "0xfcfcfcfc" ); + &and( $t, "0xcfcfcfcf" ); + &movb( &LB($tmp1), &LB($u) ); + &movb( &LB($tmp2), &HB($u) ); + &rotr( $t, 4 ); + &mov( $ks, &DWP(" $desSP",$tmp1,"",0)); + &movb( &LB($tmp1), &LB($t) ); + &xor( $L, $ks); + &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0)); + &xor( $L, $ks); ###### + &movb( &LB($tmp2), &HB($t) ); + &shr( $u, 16); + &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0)); + &xor( $L, $ks); ###### + &movb( &LB($tmp1), &HB($u) ); + &shr( $t, 16); + &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0)); + &xor( $L, $ks); + &mov( $ks, &wparam(1) ); + &movb( &LB($tmp2), &HB($t) ); + &and( $u, "0xff" ); + &and( $t, "0xff" ); + &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0)); + &xor( $L, $tmp1); + &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0)); + &xor( $L, $tmp1); + &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0)); + &xor( $L, $tmp1); + &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0)); + &xor( $L, $tmp1); + } + +sub n2a + { + sprintf("%d",$_[0]); + } + +# now has a side affect of rotating $a by $shift +sub R_PERM_OP + { + local($a,$b,$tt,$shift,$mask,$last)=@_; + + &rotl( $a, $shift ) if ($shift != 0); + &mov( $tt, $a ); + &xor( $a, $b ); + &and( $a, $mask ); + if (!$last eq $b) + { + &xor( $b, $a ); + &xor( $tt, $a ); + } + else + { + &xor( $tt, $a ); + &xor( $b, $a ); + } + &comment(""); + } + +sub IP_new + { + local($l,$r,$tt,$lr)=@_; + + &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); + &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); + &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); + &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); + &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); + + if ($lr != 3) + { + if (($lr-3) < 0) + { &rotr($tt, 3-$lr); } + else { &rotl($tt, $lr-3); } + } + if ($lr != 2) + { + if (($lr-2) < 0) + { &rotr($r, 2-$lr); } + else { &rotl($r, $lr-2); } + } + } + +sub FP_new + { + local($l,$r,$tt,$lr)=@_; + + if ($lr != 2) + { + if (($lr-2) < 0) + { &rotl($r, 2-$lr); } + else { &rotr($r, $lr-2); } + } + if ($lr != 3) + { + if (($lr-3) < 0) + { &rotl($l, 3-$lr); } + else { &rotr($l, $lr-3); } + } + + &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); + &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); + &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); + &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); + &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); + &rotr($tt , 4); + } + diff -urN linux-2.4.29/net/ipsec/libdes/asm/des686.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/des686.pl --- linux-2.4.29/net/ipsec/libdes/asm/des686.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/des686.pl Thu Sep 5 05:13:20 2002 @@ -0,0 +1,230 @@ +#!/usr/local/bin/perl + +$prog="des686.pl"; + +# base code is in microsft +# op dest, source +# format. +# + +# WILL NOT WORK ANYMORE WITH desboth.pl +require "desboth.pl"; + +if ( ($ARGV[0] eq "elf")) + { require "x86unix.pl"; } +elsif ( ($ARGV[0] eq "a.out")) + { $aout=1; require "x86unix.pl"; } +elsif ( ($ARGV[0] eq "sol")) + { $sol=1; require "x86unix.pl"; } +elsif ( ($ARGV[0] eq "cpp")) + { $cpp=1; require "x86unix.pl"; } +elsif ( ($ARGV[0] eq "win32")) + { require "x86ms.pl"; } +else + { + print STDERR <<"EOF"; +Pick one target type from + elf - linux, FreeBSD etc + a.out - old linux + sol - x86 solaris + cpp - format so x86unix.cpp can be used + win32 - Windows 95/Windows NT +EOF + exit(1); + } + +&comment("Don't even think of reading this code"); +&comment("It was automatically generated by $prog"); +&comment("Which is a perl program used to generate the x86 assember for"); +&comment("any of elf, a.out, Win32, or Solaris"); +&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+"); +&comment("eric "); +&comment(""); + +&file("dx86xxxx"); + +$L="edi"; +$R="esi"; + +&des_encrypt("des_encrypt",1); +&des_encrypt("des_encrypt2",0); + +&des_encrypt3("des_encrypt3",1); +&des_encrypt3("des_decrypt3",0); + +&file_end(); + +sub des_encrypt + { + local($name,$do_ip)=@_; + + &function_begin($name,"EXTRN _des_SPtrans:DWORD"); + + &comment(""); + &comment("Load the 2 words"); + &mov("eax",&wparam(0)); + &mov($L,&DWP(0,"eax","",0)); + &mov($R,&DWP(4,"eax","",0)); + + $ksp=&wparam(1); + + if ($do_ip) + { + &comment(""); + &comment("IP"); + &IP_new($L,$R,"eax"); + } + + &comment(""); + &comment("fixup rotate"); + &rotl($R,3); + &rotl($L,3); + &exch($L,$R); + + &comment(""); + &comment("load counter, key_schedule and enc flag"); + &mov("eax",&wparam(2)); # get encrypt flag + &mov("ebp",&wparam(1)); # get ks + &cmp("eax","0"); + &je(&label("start_decrypt")); + + # encrypting part + + for ($i=0; $i<16; $i+=2) + { + &comment(""); + &comment("Round $i"); + &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); + + &comment(""); + &comment("Round ".sprintf("%d",$i+1)); + &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); + } + &jmp(&label("end")); + + &set_label("start_decrypt"); + + for ($i=15; $i>0; $i-=2) + { + &comment(""); + &comment("Round $i"); + &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); + &comment(""); + &comment("Round ".sprintf("%d",$i-1)); + &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx"); + } + + &set_label("end"); + + &comment(""); + &comment("Fixup"); + &rotr($L,3); # r + &rotr($R,3); # l + + if ($do_ip) + { + &comment(""); + &comment("FP"); + &FP_new($R,$L,"eax"); + } + + &mov("eax",&wparam(0)); + &mov(&DWP(0,"eax","",0),$L); + &mov(&DWP(4,"eax","",0),$R); + + &function_end($name); + } + + +# The logic is to load R into 2 registers and operate on both at the same time. +# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte' +# while also masking the other copy and doing a lookup. We then also accumulate the +# L value in 2 registers then combine them at the end. +sub D_ENCRYPT + { + local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_; + + &mov( $u, &DWP(&n2a($S*4),$ks,"",0)); + &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0)); + &xor( $u, $R ); + &xor( $t, $R ); + &rotr( $t, 4 ); + + # the numbers at the end of the line are origional instruction order + &mov( $tmp2, $u ); # 1 2 + &mov( $tmp1, $t ); # 1 1 + &and( $tmp2, "0xfc" ); # 1 4 + &and( $tmp1, "0xfc" ); # 1 3 + &shr( $t, 8 ); # 1 5 + &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7 + &shr( $u, 8 ); # 1 6 + &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8 + + &mov( $tmp2, $u ); # 2 2 + &xor( $L, $tmp1 ); # 1 9 + &and( $tmp2, "0xfc" ); # 2 4 + &mov( $tmp1, $t ); # 2 1 + &and( $tmp1, "0xfc" ); # 2 3 + &shr( $t, 8 ); # 2 5 + &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7 + &shr( $u, 8 ); # 2 6 + &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8 + &mov( $tmp2, $u ); # 3 2 + + &xor( $L, $tmp1 ); # 2 9 + &and( $tmp2, "0xfc" ); # 3 4 + + &mov( $tmp1, $t ); # 3 1 + &shr( $u, 8 ); # 3 6 + &and( $tmp1, "0xfc" ); # 3 3 + &shr( $t, 8 ); # 3 5 + &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7 + &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8 + + &and( $t, "0xfc" ); # 4 1 + &xor( $L, $tmp1 ); # 3 9 + + &and( $u, "0xfc" ); # 4 2 + &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3 + &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4 + } + +sub PERM_OP + { + local($a,$b,$tt,$shift,$mask)=@_; + + &mov( $tt, $a ); + &shr( $tt, $shift ); + &xor( $tt, $b ); + &and( $tt, $mask ); + &xor( $b, $tt ); + &shl( $tt, $shift ); + &xor( $a, $tt ); + } + +sub IP_new + { + local($l,$r,$tt)=@_; + + &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f"); + &PERM_OP($l,$r,$tt,16,"0x0000ffff"); + &PERM_OP($r,$l,$tt, 2,"0x33333333"); + &PERM_OP($l,$r,$tt, 8,"0x00ff00ff"); + &PERM_OP($r,$l,$tt, 1,"0x55555555"); + } + +sub FP_new + { + local($l,$r,$tt)=@_; + + &PERM_OP($l,$r,$tt, 1,"0x55555555"); + &PERM_OP($r,$l,$tt, 8,"0x00ff00ff"); + &PERM_OP($l,$r,$tt, 2,"0x33333333"); + &PERM_OP($r,$l,$tt,16,"0x0000ffff"); + &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f"); + } + +sub n2a + { + sprintf("%d",$_[0]); + } diff -urN linux-2.4.29/net/ipsec/libdes/asm/desboth.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/desboth.pl --- linux-2.4.29/net/ipsec/libdes/asm/desboth.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/desboth.pl Thu Sep 5 05:13:20 2002 @@ -0,0 +1,79 @@ +#!/usr/local/bin/perl + +$L="edi"; +$R="esi"; + +sub des_encrypt3 + { + local($name,$enc)=@_; + + &function_begin_B($name,""); + &push("ebx"); + &mov("ebx",&wparam(0)); + + &push("ebp"); + &push("esi"); + + &push("edi"); + + &comment(""); + &comment("Load the data words"); + &mov($L,&DWP(0,"ebx","",0)); + &mov($R,&DWP(4,"ebx","",0)); + &stack_push(3); + + &comment(""); + &comment("IP"); + &IP_new($L,$R,"edx",0); + + # put them back + + if ($enc) + { + &mov(&DWP(4,"ebx","",0),$R); + &mov("eax",&wparam(1)); + &mov(&DWP(0,"ebx","",0),"edx"); + &mov("edi",&wparam(2)); + &mov("esi",&wparam(3)); + } + else + { + &mov(&DWP(4,"ebx","",0),$R); + &mov("esi",&wparam(1)); + &mov(&DWP(0,"ebx","",0),"edx"); + &mov("edi",&wparam(2)); + &mov("eax",&wparam(3)); + } + &mov(&swtmp(2), (($enc)?"1":"0")); + &mov(&swtmp(1), "eax"); + &mov(&swtmp(0), "ebx"); + &call("des_encrypt2"); + &mov(&swtmp(2), (($enc)?"0":"1")); + &mov(&swtmp(1), "edi"); + &mov(&swtmp(0), "ebx"); + &call("des_encrypt2"); + &mov(&swtmp(2), (($enc)?"1":"0")); + &mov(&swtmp(1), "esi"); + &mov(&swtmp(0), "ebx"); + &call("des_encrypt2"); + + &stack_pop(3); + &mov($L,&DWP(0,"ebx","",0)); + &mov($R,&DWP(4,"ebx","",0)); + + &comment(""); + &comment("FP"); + &FP_new($L,$R,"eax",0); + + &mov(&DWP(0,"ebx","",0),"eax"); + &mov(&DWP(4,"ebx","",0),$R); + + &pop("edi"); + &pop("esi"); + &pop("ebp"); + &pop("ebx"); + &ret(); + &function_end_B($name); + } + + diff -urN linux-2.4.29/net/ipsec/libdes/asm/perlasm/cbc.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/perlasm/cbc.pl --- linux-2.4.29/net/ipsec/libdes/asm/perlasm/cbc.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/perlasm/cbc.pl Thu Sep 5 05:13:20 2002 @@ -0,0 +1,342 @@ +#!/usr/local/bin/perl + +# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc) +# des_cblock (*input); +# des_cblock (*output); +# long length; +# des_key_schedule schedule; +# des_cblock (*ivec); +# int enc; +# +# calls +# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); +# + +#&cbc("des_ncbc_encrypt","des_encrypt",0); +#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt", +# 1,4,5,3,5,-1); +#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt", +# 0,4,5,3,5,-1); +#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3", +# 0,6,7,3,4,5); +# +# When doing a cipher that needs bigendian order, +# for encrypt, the iv is kept in bigendian form, +# while for decrypt, it is kept in little endian. +sub cbc + { + local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_; + # name is the function name + # enc_func and dec_func and the functions to call for encrypt/decrypt + # swap is true if byte order needs to be reversed + # iv_off is parameter number for the iv + # enc_off is parameter number for the encrypt/decrypt flag + # p1,p2,p3 are the offsets for parameters to be passed to the + # underlying calls. + + &function_begin_B($name,""); + &comment(""); + + $in="esi"; + $out="edi"; + $count="ebp"; + + &push("ebp"); + &push("ebx"); + &push("esi"); + &push("edi"); + + $data_off=4; + $data_off+=4 if ($p1 > 0); + $data_off+=4 if ($p2 > 0); + $data_off+=4 if ($p3 > 0); + + &mov($count, &wparam(2)); # length + + &comment("getting iv ptr from parameter $iv_off"); + &mov("ebx", &wparam($iv_off)); # Get iv ptr + + &mov($in, &DWP(0,"ebx","",0));# iv[0] + &mov($out, &DWP(4,"ebx","",0));# iv[1] + + &push($out); + &push($in); + &push($out); # used in decrypt for iv[1] + &push($in); # used in decrypt for iv[0] + + &mov("ebx", "esp"); # This is the address of tin[2] + + &mov($in, &wparam(0)); # in + &mov($out, &wparam(1)); # out + + # We have loaded them all, how lets push things + &comment("getting encrypt flag from parameter $enc_off"); + &mov("ecx", &wparam($enc_off)); # Get enc flag + if ($p3 > 0) + { + &comment("get and push parameter $p3"); + if ($enc_off != $p3) + { &mov("eax", &wparam($p3)); &push("eax"); } + else { &push("ecx"); } + } + if ($p2 > 0) + { + &comment("get and push parameter $p2"); + if ($enc_off != $p2) + { &mov("eax", &wparam($p2)); &push("eax"); } + else { &push("ecx"); } + } + if ($p1 > 0) + { + &comment("get and push parameter $p1"); + if ($enc_off != $p1) + { &mov("eax", &wparam($p1)); &push("eax"); } + else { &push("ecx"); } + } + &push("ebx"); # push data/iv + + &cmp("ecx",0); + &jz(&label("decrypt")); + + &and($count,0xfffffff8); + &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0] + &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1] + + &jz(&label("encrypt_finish")); + + ############################################################# + + &set_label("encrypt_loop"); + # encrypt start + # "eax" and "ebx" hold iv (or the last cipher text) + + &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes + &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes + + &xor("eax", "ecx"); + &xor("ebx", "edx"); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($enc_func); + + &mov("eax", &DWP($data_off,"esp","",0)); + &mov("ebx", &DWP($data_off+4,"esp","",0)); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP(0,$out,"",0),"eax"); + &mov(&DWP(4,$out,"",0),"ebx"); + + # eax and ebx are the next iv. + + &add($in, 8); + &add($out, 8); + + &sub($count, 8); + &jnz(&label("encrypt_loop")); + +###################################################################3 + &set_label("encrypt_finish"); + &mov($count, &wparam(2)); # length + &and($count, 7); + &jz(&label("finish")); + &xor("ecx","ecx"); + &xor("edx","edx"); + &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); + &jmp_ptr($count); + +&set_label("ej7"); + &xor("edx", "edx") if $ppro; # ppro friendly + &movb(&HB("edx"), &BP(6,$in,"",0)); + &shl("edx",8); +&set_label("ej6"); + &movb(&HB("edx"), &BP(5,$in,"",0)); +&set_label("ej5"); + &movb(&LB("edx"), &BP(4,$in,"",0)); +&set_label("ej4"); + &mov("ecx", &DWP(0,$in,"",0)); + &jmp(&label("ejend")); +&set_label("ej3"); + &movb(&HB("ecx"), &BP(2,$in,"",0)); + &xor("ecx", "ecx") if $ppro; # ppro friendly + &shl("ecx",8); +&set_label("ej2"); + &movb(&HB("ecx"), &BP(1,$in,"",0)); +&set_label("ej1"); + &movb(&LB("ecx"), &BP(0,$in,"",0)); +&set_label("ejend"); + + &xor("eax", "ecx"); + &xor("ebx", "edx"); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($enc_func); + + &mov("eax", &DWP($data_off,"esp","",0)); + &mov("ebx", &DWP($data_off+4,"esp","",0)); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP(0,$out,"",0),"eax"); + &mov(&DWP(4,$out,"",0),"ebx"); + + &jmp(&label("finish")); + + ############################################################# + ############################################################# + &set_label("decrypt",1); + # decrypt start + &and($count,0xfffffff8); + # The next 2 instructions are only for if the jz is taken + &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0] + &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1] + &jz(&label("decrypt_finish")); + + &set_label("decrypt_loop"); + &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes + &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put back + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($dec_func); + + &mov("eax", &DWP($data_off,"esp","",0)); # get return + &mov("ebx", &DWP($data_off+4,"esp","",0)); # + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] + &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] + + &xor("ecx", "eax"); + &xor("edx", "ebx"); + + &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, + &mov("ebx", &DWP(4,$in,"",0)); # next iv actually + + &mov(&DWP(0,$out,"",0),"ecx"); + &mov(&DWP(4,$out,"",0),"edx"); + + &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv + &mov(&DWP($data_off+12,"esp","",0), "ebx"); # + + &add($in, 8); + &add($out, 8); + + &sub($count, 8); + &jnz(&label("decrypt_loop")); +############################ ENDIT #######################3 + &set_label("decrypt_finish"); + &mov($count, &wparam(2)); # length + &and($count, 7); + &jz(&label("finish")); + + &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes + &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put back + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($dec_func); + + &mov("eax", &DWP($data_off,"esp","",0)); # get return + &mov("ebx", &DWP($data_off+4,"esp","",0)); # + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] + &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] + + &xor("ecx", "eax"); + &xor("edx", "ebx"); + + # this is for when we exit + &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, + &mov("ebx", &DWP(4,$in,"",0)); # next iv actually + +&set_label("dj7"); + &rotr("edx", 16); + &movb(&BP(6,$out,"",0), &LB("edx")); + &shr("edx",16); +&set_label("dj6"); + &movb(&BP(5,$out,"",0), &HB("edx")); +&set_label("dj5"); + &movb(&BP(4,$out,"",0), &LB("edx")); +&set_label("dj4"); + &mov(&DWP(0,$out,"",0), "ecx"); + &jmp(&label("djend")); +&set_label("dj3"); + &rotr("ecx", 16); + &movb(&BP(2,$out,"",0), &LB("ecx")); + &shl("ecx",16); +&set_label("dj2"); + &movb(&BP(1,$in,"",0), &HB("ecx")); +&set_label("dj1"); + &movb(&BP(0,$in,"",0), &LB("ecx")); +&set_label("djend"); + + # final iv is still in eax:ebx + &jmp(&label("finish")); + + +############################ FINISH #######################3 + &set_label("finish",1); + &mov("ecx", &wparam($iv_off)); # Get iv ptr + + ################################################# + $total=16+4; + $total+=4 if ($p1 > 0); + $total+=4 if ($p2 > 0); + $total+=4 if ($p3 > 0); + &add("esp",$total); + + &mov(&DWP(0,"ecx","",0), "eax"); # save iv + &mov(&DWP(4,"ecx","",0), "ebx"); # save iv + + &function_end_A($name); + + &set_label("cbc_enc_jmp_table",1); + &data_word("0"); + &data_word(&label("ej1")); + &data_word(&label("ej2")); + &data_word(&label("ej3")); + &data_word(&label("ej4")); + &data_word(&label("ej5")); + &data_word(&label("ej6")); + &data_word(&label("ej7")); + &set_label("cbc_dec_jmp_table",1); + &data_word("0"); + &data_word(&label("dj1")); + &data_word(&label("dj2")); + &data_word(&label("dj3")); + &data_word(&label("dj4")); + &data_word(&label("dj5")); + &data_word(&label("dj6")); + &data_word(&label("dj7")); + + &function_end_B($name); + + } + +1; diff -urN linux-2.4.29/net/ipsec/libdes/asm/perlasm/readme linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/perlasm/readme --- linux-2.4.29/net/ipsec/libdes/asm/perlasm/readme Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/perlasm/readme Thu Sep 5 05:13:20 2002 @@ -0,0 +1,124 @@ +The perl scripts in this directory are my 'hack' to generate +multiple different assembler formats via the one origional script. + +The way to use this library is to start with adding the path to this directory +and then include it. + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; + +The first thing we do is setup the file and type of assember + +&asm_init($ARGV[0],$0); + +The first argument is the 'type'. Currently +'cpp', 'sol', 'a.out', 'elf' or 'win32'. +Argument 2 is the file name. + +The reciprocal function is +&asm_finish() which should be called at the end. + +There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler, +and x86unix.pl which is the unix (gas) version. + +Functions of interest are: +&external_label("des_SPtrans"); declare and external variable +&LB(reg); Low byte for a register +&HB(reg); High byte for a register +&BP(off,base,index,scale) Byte pointer addressing +&DWP(off,base,index,scale) Word pointer addressing +&stack_push(num) Basically a 'sub esp, num*4' with extra +&stack_pop(num) inverse of stack_push +&function_begin(name,extra) Start a function with pushing of + edi, esi, ebx and ebp. extra is extra win32 + external info that may be required. +&function_begin_B(name,extra) Same as norma function_begin but no pushing. +&function_end(name) Call at end of function. +&function_end_A(name) Standard pop and ret, for use inside functions +&function_end_B(name) Call at end but with poping or 'ret'. +&swtmp(num) Address on stack temp word. +&wparam(num) Parameter number num, that was push + in C convention. This all works over pushes + and pops. +&comment("hello there") Put in a comment. +&label("loop") Refer to a label, normally a jmp target. +&set_label("loop") Set a label at this point. +&data_word(word) Put in a word of data. + +So how does this all hold together? Given + +int calc(int len, int *data) + { + int i,j=0; + + for (i=0; i"); +&comment(""); + + $filename =~ s/\.pl$//; + &file($filename); + } + +sub asm_finish_cpp + { + return unless $cpp; + + local($tmp,$i); + foreach $i (&get_labels()) + { + $tmp.="#define $i _$i\n"; + } + print <<"EOF"; +/* Run the C pre-processor over this file with one of the following defined + * ELF - elf object files, + * OUT - a.out object files, + * BSDI - BSDI style a.out object files + * SOL - Solaris style elf + */ + +#define TYPE(a,b) .type a,b +#define SIZE(a,b) .size a,b + +#if defined(OUT) || defined(BSDI) +$tmp +#endif + +#ifdef OUT +#define OK 1 +#define ALIGN 4 +#endif + +#ifdef BSDI +#define OK 1 +#define ALIGN 4 +#undef SIZE +#undef TYPE +#endif + +#if defined(ELF) || defined(SOL) +#define OK 1 +#define ALIGN 16 +#endif + +#ifndef OK +You need to define one of +ELF - elf systems - linux-elf, NetBSD and DG-UX +OUT - a.out systems - linux-a.out and FreeBSD +SOL - solaris systems, which are elf with strange comment lines +BSDI - a.out with a very primative version of as. +#endif + +/* Let the Assembler begin :-) */ +EOF + } + +1; diff -urN linux-2.4.29/net/ipsec/libdes/asm/perlasm/x86ms.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/perlasm/x86ms.pl --- linux-2.4.29/net/ipsec/libdes/asm/perlasm/x86ms.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/perlasm/x86ms.pl Thu Sep 5 05:13:20 2002 @@ -0,0 +1,345 @@ +#!/usr/local/bin/perl + +package x86ms; + +$label="L000"; + +%lb=( 'eax', 'al', + 'ebx', 'bl', + 'ecx', 'cl', + 'edx', 'dl', + 'ax', 'al', + 'bx', 'bl', + 'cx', 'cl', + 'dx', 'dl', + ); + +%hb=( 'eax', 'ah', + 'ebx', 'bh', + 'ecx', 'ch', + 'edx', 'dh', + 'ax', 'ah', + 'bx', 'bh', + 'cx', 'ch', + 'dx', 'dh', + ); + +sub main'asm_init_output { @out=(); } +sub main'asm_get_output { return(@out); } +sub main'get_labels { return(@labels); } +sub main'external_label { push(@labels,@_); } + +sub main'LB + { + (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; + return($lb{$_[0]}); + } + +sub main'HB + { + (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; + return($hb{$_[0]}); + } + +sub main'BP + { + &get_mem("BYTE",@_); + } + +sub main'DWP + { + &get_mem("DWORD",@_); + } + +sub main'stack_push + { + local($num)=@_; + $stack+=$num*4; + &main'sub("esp",$num*4); + } + +sub main'stack_pop + { + local($num)=@_; + $stack-=$num*4; + &main'add("esp",$num*4); + } + +sub get_mem + { + local($size,$addr,$reg1,$reg2,$idx)=@_; + local($t,$post); + local($ret)="$size PTR "; + + $addr =~ s/^\s+//; + if ($addr =~ /^(.+)\+(.+)$/) + { + $reg2=&conv($1); + $addr="_$2"; + } + elsif ($addr =~ /^[_a-zA-Z]/) + { + $addr="_$addr"; + } + + $reg1="$regs{$reg1}" if defined($regs{$reg1}); + $reg2="$regs{$reg2}" if defined($regs{$reg2}); + if (($addr ne "") && ($addr ne 0)) + { + if ($addr !~ /^-/) + { $ret.=$addr; } + else { $post=$addr; } + } + if ($reg2 ne "") + { + $t=""; + $t="*$idx" if ($idx != 0); + $reg1="+".$reg1 if ("$reg1$post" ne ""); + $ret.="[$reg2$t$reg1$post]"; + } + else + { + $ret.="[$reg1$post]" + } + return($ret); + } + +sub main'mov { &out2("mov",@_); } +sub main'movb { &out2("mov",@_); } +sub main'and { &out2("and",@_); } +sub main'or { &out2("or",@_); } +sub main'shl { &out2("shl",@_); } +sub main'shr { &out2("shr",@_); } +sub main'xor { &out2("xor",@_); } +sub main'xorb { &out2("xor",@_); } +sub main'add { &out2("add",@_); } +sub main'adc { &out2("adc",@_); } +sub main'sub { &out2("sub",@_); } +sub main'rotl { &out2("rol",@_); } +sub main'rotr { &out2("ror",@_); } +sub main'exch { &out2("xchg",@_); } +sub main'cmp { &out2("cmp",@_); } +sub main'lea { &out2("lea",@_); } +sub main'mul { &out1("mul",@_); } +sub main'div { &out1("div",@_); } +sub main'dec { &out1("dec",@_); } +sub main'inc { &out1("inc",@_); } +sub main'jmp { &out1("jmp",@_); } +sub main'jmp_ptr { &out1p("jmp",@_); } +sub main'je { &out1("je",@_); } +sub main'jle { &out1("jle",@_); } +sub main'jz { &out1("jz",@_); } +sub main'jge { &out1("jge",@_); } +sub main'jl { &out1("jl",@_); } +sub main'jb { &out1("jb",@_); } +sub main'jnz { &out1("jnz",@_); } +sub main'jne { &out1("jne",@_); } +sub main'push { &out1("push",@_); $stack+=4; } +sub main'pop { &out1("pop",@_); $stack-=4; } +sub main'bswap { &out1("bswap",@_); &using486(); } +sub main'not { &out1("not",@_); } +sub main'call { &out1("call",'_'.$_[0]); } +sub main'ret { &out0("ret"); } +sub main'nop { &out0("nop"); } + +sub out2 + { + local($name,$p1,$p2)=@_; + local($l,$t); + + push(@out,"\t$name\t"); + $t=&conv($p1).","; + $l=length($t); + push(@out,$t); + $l=4-($l+9)/8; + push(@out,"\t" x $l); + push(@out,&conv($p2)); + push(@out,"\n"); + } + +sub out0 + { + local($name)=@_; + + push(@out,"\t$name\n"); + } + +sub out1 + { + local($name,$p1)=@_; + local($l,$t); + + push(@out,"\t$name\t".&conv($p1)."\n"); + } + +sub conv + { + local($p)=@_; + + $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; + return $p; + } + +sub using486 + { + return if $using486; + $using486++; + grep(s/\.386/\.486/,@out); + } + +sub main'file + { + local($file)=@_; + + local($tmp)=<<"EOF"; + TITLE $file.asm + .386 +.model FLAT +EOF + push(@out,$tmp); + } + +sub main'function_begin + { + local($func,$extra)=@_; + + push(@labels,$func); + + local($tmp)=<<"EOF"; +_TEXT SEGMENT +PUBLIC _$func +$extra +_$func PROC NEAR + push ebp + push ebx + push esi + push edi +EOF + push(@out,$tmp); + $stack=20; + } + +sub main'function_begin_B + { + local($func,$extra)=@_; + + local($tmp)=<<"EOF"; +_TEXT SEGMENT +PUBLIC _$func +$extra +_$func PROC NEAR +EOF + push(@out,$tmp); + $stack=4; + } + +sub main'function_end + { + local($func)=@_; + + local($tmp)=<<"EOF"; + pop edi + pop esi + pop ebx + pop ebp + ret +_$func ENDP +_TEXT ENDS +EOF + push(@out,$tmp); + $stack=0; + %label=(); + } + +sub main'function_end_B + { + local($func)=@_; + + local($tmp)=<<"EOF"; +_$func ENDP +_TEXT ENDS +EOF + push(@out,$tmp); + $stack=0; + %label=(); + } + +sub main'function_end_A + { + local($func)=@_; + + local($tmp)=<<"EOF"; + pop edi + pop esi + pop ebx + pop ebp + ret +EOF + push(@out,$tmp); + } + +sub main'file_end + { + push(@out,"END\n"); + } + +sub main'wparam + { + local($num)=@_; + + return(&main'DWP($stack+$num*4,"esp","",0)); + } + +sub main'swtmp + { + return(&main'DWP($_[0]*4,"esp","",0)); + } + +# Should use swtmp, which is above esp. Linix can trash the stack above esp +#sub main'wtmp +# { +# local($num)=@_; +# +# return(&main'DWP(-(($num+1)*4),"esp","",0)); +# } + +sub main'comment + { + foreach (@_) + { + push(@out,"\t; $_\n"); + } + } + +sub main'label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}="\$${label}${_[0]}"; + $label++; + } + return($label{$_[0]}); + } + +sub main'set_label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}="${label}${_[0]}"; + $label++; + } + push(@out,"$label{$_[0]}:\n"); + } + +sub main'data_word + { + push(@out,"\tDD\t$_[0]\n"); + } + +sub out1p + { + local($name,$p1)=@_; + local($l,$t); + + push(@out,"\t$name\t ".&conv($p1)."\n"); + } diff -urN linux-2.4.29/net/ipsec/libdes/asm/perlasm/x86unix.pl linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/perlasm/x86unix.pl --- linux-2.4.29/net/ipsec/libdes/asm/perlasm/x86unix.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/asm/perlasm/x86unix.pl Wed Oct 16 02:43:20 2002 @@ -0,0 +1,402 @@ +#!/usr/local/bin/perl + +package x86unix; + +$label="L000"; + +$align=($main'aout)?"4":"16"; +$under=($main'aout)?"_":""; +$com_start=($main'sol)?"/":"#"; + +sub main'asm_init_output { @out=(); } +sub main'asm_get_output { return(@out); } +sub main'get_labels { return(@labels); } +sub main'external_label { push(@labels,@_); } + +if ($main'cpp) + { + $align="ALIGN"; + $under=""; + $com_start='/*'; + $com_end='*/'; + } + +%lb=( 'eax', '%al', + 'ebx', '%bl', + 'ecx', '%cl', + 'edx', '%dl', + 'ax', '%al', + 'bx', '%bl', + 'cx', '%cl', + 'dx', '%dl', + ); + +%hb=( 'eax', '%ah', + 'ebx', '%bh', + 'ecx', '%ch', + 'edx', '%dh', + 'ax', '%ah', + 'bx', '%bh', + 'cx', '%ch', + 'dx', '%dh', + ); + +%regs=( 'eax', '%eax', + 'ebx', '%ebx', + 'ecx', '%ecx', + 'edx', '%edx', + 'esi', '%esi', + 'edi', '%edi', + 'ebp', '%ebp', + 'esp', '%esp', + ); + +%reg_val=( + 'eax', 0x00, + 'ebx', 0x03, + 'ecx', 0x01, + 'edx', 0x02, + 'esi', 0x06, + 'edi', 0x07, + 'ebp', 0x05, + 'esp', 0x04, + ); + +sub main'LB + { + (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n"; + return($lb{$_[0]}); + } + +sub main'HB + { + (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n"; + return($hb{$_[0]}); + } + +sub main'DWP + { + local($addr,$reg1,$reg2,$idx)=@_; + + $ret=""; + $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; + $reg1="$regs{$reg1}" if defined($regs{$reg1}); + $reg2="$regs{$reg2}" if defined($regs{$reg2}); + $ret.=$addr if ($addr ne "") && ($addr ne 0); + if ($reg2 ne "") + { $ret.="($reg1,$reg2,$idx)"; } + else + { $ret.="($reg1)" } + return($ret); + } + +sub main'BP + { + return(&main'DWP(@_)); + } + +#sub main'BP +# { +# local($addr,$reg1,$reg2,$idx)=@_; +# +# $ret=""; +# +# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/; +# $reg1="$regs{$reg1}" if defined($regs{$reg1}); +# $reg2="$regs{$reg2}" if defined($regs{$reg2}); +# $ret.=$addr if ($addr ne "") && ($addr ne 0); +# if ($reg2 ne "") +# { $ret.="($reg1,$reg2,$idx)"; } +# else +# { $ret.="($reg1)" } +# return($ret); +# } + +sub main'mov { &out2("movl",@_); } +sub main'movb { &out2("movb",@_); } +sub main'and { &out2("andl",@_); } +sub main'or { &out2("orl",@_); } +sub main'shl { &out2("sall",@_); } +sub main'shr { &out2("shrl",@_); } +sub main'xor { &out2("xorl",@_); } +sub main'xorb { &out2("xorb",@_); } +sub main'add { &out2("addl",@_); } +sub main'adc { &out2("adcl",@_); } +sub main'sub { &out2("subl",@_); } +sub main'rotl { &out2("roll",@_); } +sub main'rotr { &out2("rorl",@_); } +sub main'exch { &out2("xchg",@_); } +sub main'cmp { &out2("cmpl",@_); } +sub main'lea { &out2("leal",@_); } +sub main'mul { &out1("mull",@_); } +sub main'div { &out1("divl",@_); } +sub main'jmp { &out1("jmp",@_); } +sub main'jmp_ptr { &out1p("jmp",@_); } +sub main'je { &out1("je",@_); } +sub main'jle { &out1("jle",@_); } +sub main'jne { &out1("jne",@_); } +sub main'jnz { &out1("jnz",@_); } +sub main'jz { &out1("jz",@_); } +sub main'jge { &out1("jge",@_); } +sub main'jl { &out1("jl",@_); } +sub main'jb { &out1("jb",@_); } +sub main'dec { &out1("decl",@_); } +sub main'inc { &out1("incl",@_); } +sub main'push { &out1("pushl",@_); $stack+=4; } +sub main'pop { &out1("popl",@_); $stack-=4; } +sub main'bswap { &out1("bswapl",@_); } +sub main'not { &out1("notl",@_); } +sub main'call { &out1("call",$under.$_[0]); } +sub main'ret { &out0("ret"); } +sub main'nop { &out0("nop"); } + +sub out2 + { + local($name,$p1,$p2)=@_; + local($l,$ll,$t); + local(%special)=( "roll",0xD1C0,"rorl",0xD1C8, + "rcll",0xD1D0,"rcrl",0xD1D8, + "shll",0xD1E0,"shrl",0xD1E8, + "sarl",0xD1F8); + + if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1)) + { + $op=$special{$name}|$reg_val{$p1}; + $tmp1=sprintf ".byte %d\n",($op>>8)&0xff; + $tmp2=sprintf ".byte %d\t",$op &0xff; + push(@out,$tmp1); + push(@out,$tmp2); + + $p2=&conv($p2); + $p1=&conv($p1); + &main'comment("$name $p2 $p1"); + return; + } + + push(@out,"\t$name\t"); + $t=&conv($p2).","; + $l=length($t); + push(@out,$t); + $ll=4-($l+9)/8; + $tmp1=sprintf "\t" x $ll; + push(@out,$tmp1); + push(@out,&conv($p1)."\n"); + } + +sub out1 + { + local($name,$p1)=@_; + local($l,$t); + + push(@out,"\t$name\t".&conv($p1)."\n"); + } + +sub out1p + { + local($name,$p1)=@_; + local($l,$t); + + push(@out,"\t$name\t*".&conv($p1)."\n"); + } + +sub out0 + { + push(@out,"\t$_[0]\n"); + } + +sub conv + { + local($p)=@_; + +# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/; + + $p=$regs{$p} if (defined($regs{$p})); + + $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/; + $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/; + return $p; + } + +sub main'file + { + local($file)=@_; + + local($tmp)=<<"EOF"; + .file "$file.s" + .version "01.01" +EOF + push(@out,$tmp); + } + +sub main'function_begin + { + local($func)=@_; + + $func=$under.$func; + + local($tmp)=<<"EOF"; +.text + .align $align +.globl $func +EOF + push(@out,$tmp); + if ($main'cpp) + { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } + else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } + push(@out,"$func:\n"); + $tmp=<<"EOF"; + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + +EOF + push(@out,$tmp); + $stack=20; + } + +sub main'function_begin_B + { + local($func,$extra)=@_; + + $func=$under.$func; + + local($tmp)=<<"EOF"; +.text + .align $align +.globl $func +EOF + push(@out,$tmp); + if ($main'cpp) + { push(@out,"\tTYPE($func,\@function)\n"); } + else { push(@out,"\t.type $func,\@function\n"); } + push(@out,"$func:\n"); + $stack=4; + } + +sub main'function_end + { + local($func)=@_; + + $func=$under.$func; + + local($tmp)=<<"EOF"; + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +.${func}_end: +EOF + push(@out,$tmp); + if ($main'cpp) + { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } + else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); } + push(@out,".ident \"$func\"\n"); + $stack=0; + %label=(); + } + +sub main'function_end_A + { + local($func)=@_; + + local($tmp)=<<"EOF"; + popl %edi + popl %esi + popl %ebx + popl %ebp + ret +EOF + push(@out,$tmp); + } + +sub main'function_end_B + { + local($func)=@_; + + $func=$under.$func; + + push(@out,".${func}_end:\n"); + if ($main'cpp) + { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); } + else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); } + push(@out,".ident \"desasm.pl\"\n"); + $stack=0; + %label=(); + } + +sub main'wparam + { + local($num)=@_; + + return(&main'DWP($stack+$num*4,"esp","",0)); + } + +sub main'stack_push + { + local($num)=@_; + $stack+=$num*4; + &main'sub("esp",$num*4); + } + +sub main'stack_pop + { + local($num)=@_; + $stack-=$num*4; + &main'add("esp",$num*4); + } + +sub main'swtmp + { + return(&main'DWP($_[0]*4,"esp","",0)); + } + +# Should use swtmp, which is above esp. Linix can trash the stack above esp +#sub main'wtmp +# { +# local($num)=@_; +# +# return(&main'DWP(-($num+1)*4,"esp","",0)); +# } + +sub main'comment + { + foreach (@_) + { + if (/^\s*$/) + { push(@out,"\n"); } + else + { push(@out,"\t$com_start $_ $com_end\n"); } + } + } + +sub main'label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}=".${label}${_[0]}"; + $label++; + } + return($label{$_[0]}); + } + +sub main'set_label + { + if (!defined($label{$_[0]})) + { + $label{$_[0]}=".${label}${_[0]}"; + $label++; + } + push(@out,".align $align\n") if ($_[1] != 0); + push(@out,"$label{$_[0]}:\n"); + } + +sub main'file_end + { + } + +sub main'data_word + { + push(@out,"\t.long $_[0]\n"); + } diff -urN linux-2.4.29/net/ipsec/libdes/cbc_enc.c linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/cbc_enc.c --- linux-2.4.29/net/ipsec/libdes/cbc_enc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/cbc_enc.c Thu Sep 5 05:13:20 2002 @@ -0,0 +1,135 @@ +/* crypto/des/cbc_enc.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +void des_cbc_encrypt(input, output, length, schedule, ivec, enc) +des_cblock (*input); +des_cblock (*output); +long length; +des_key_schedule schedule; +des_cblock (*ivec); +int enc; + { + register DES_LONG tin0,tin1; + register DES_LONG tout0,tout1,xor0,xor1; + register unsigned char *in,*out; + register long l=length; + DES_LONG tin[2]; + unsigned char *iv; + + in=(unsigned char *)input; + out=(unsigned char *)output; + iv=(unsigned char *)ivec; + + if (enc) + { + c2l(iv,tout0); + c2l(iv,tout1); + for (l-=8; l>=0; l-=8) + { + c2l(in,tin0); + c2l(in,tin1); + tin0^=tout0; tin[0]=tin0; + tin1^=tout1; tin[1]=tin1; + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); + tout0=tin[0]; l2c(tout0,out); + tout1=tin[1]; l2c(tout1,out); + } + if (l != -8) + { + c2ln(in,tin0,tin1,l+8); + tin0^=tout0; tin[0]=tin0; + tin1^=tout1; tin[1]=tin1; + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); + tout0=tin[0]; l2c(tout0,out); + tout1=tin[1]; l2c(tout1,out); + } + } + else + { + c2l(iv,xor0); + c2l(iv,xor1); + for (l-=8; l>=0; l-=8) + { + c2l(in,tin0); tin[0]=tin0; + c2l(in,tin1); tin[1]=tin1; + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); + tout0=tin[0]^xor0; + tout1=tin[1]^xor1; + l2c(tout0,out); + l2c(tout1,out); + xor0=tin0; + xor1=tin1; + } + if (l != -8) + { + c2l(in,tin0); tin[0]=tin0; + c2l(in,tin1); tin[1]=tin1; + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); + tout0=tin[0]^xor0; + tout1=tin[1]^xor1; + l2cn(tout0,tout1,out,l+8); + /* xor0=tin0; + xor1=tin1; */ + } + } + tin0=tin1=tout0=tout1=xor0=xor1=0; + tin[0]=tin[1]=0; + } + diff -urN linux-2.4.29/net/ipsec/libdes/des.h linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des.h --- linux-2.4.29/net/ipsec/libdes/des.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des.h Thu Apr 15 02:26:05 2004 @@ -0,0 +1,295 @@ +/* crypto/des/des.org */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * Always modify des.org since des.h is automatically generated from + * it during SSLeay configuration. + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ + +#ifndef HEADER_DES_H +#define HEADER_DES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +/* RCSID $Id: des.h,v 1.2 2004/04/15 00:26:05 ken Exp $ */ +/* This conditional for FreeS/WAN project. */ + +/* This just cannot work with a 64bit long, if you check the places using + * (DES_LONG*). So use a 32bit entity, even on 64bit systems. + */ +#define DES_LONG unsigned int +#endif + +typedef unsigned char des_cblock[8]; +typedef struct { des_cblock ks; } des_key_schedule[16]; + +#define DES_KEY_SZ (sizeof(des_cblock)) +#define DES_SCHEDULE_SZ (sizeof(des_key_schedule)) + +#define DES_ENCRYPT 1 +#define DES_DECRYPT 0 + +#define DES_CBC_MODE 0 +#define DES_PCBC_MODE 1 + +#define des_ecb2_encrypt(i,o,k1,k2,e) \ + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +#define C_Block des_cblock +#define Key_schedule des_key_schedule +#ifdef KERBEROS +#define ENCRYPT DES_ENCRYPT +#define DECRYPT DES_DECRYPT +#endif +#define KEY_SZ DES_KEY_SZ +#define string_to_key des_string_to_key +#define read_pw_string des_read_pw_string +#define random_key des_random_key +#define pcbc_encrypt des_pcbc_encrypt +#define set_key des_set_key +#define key_sched des_key_sched +#define ecb_encrypt des_ecb_encrypt +#define cbc_encrypt des_cbc_encrypt +#define ncbc_encrypt des_ncbc_encrypt +#define xcbc_encrypt des_xcbc_encrypt +#define cbc_cksum des_cbc_cksum +#define quad_cksum des_quad_cksum + +/* For compatibility with the MIT lib - eay 20/05/92 */ +typedef des_key_schedule bit_64; +#define des_fixup_key_parity des_set_odd_parity +#define des_check_key_parity check_parity + +extern int des_check_key; /* defaults to false */ +extern int des_rw_mode; /* defaults to DES_PCBC_MODE */ + +/* The next line is used to disable full ANSI prototypes, if your + * compiler has problems with the prototypes, make sure this line always + * evaluates to true :-) */ +#if defined(MSDOS) || defined(__STDC__) +#undef NOPROTO +#endif +#ifndef NOPROTO +char *des_options(void); +void des_ecb3_encrypt(des_cblock *input,des_cblock *output, + des_key_schedule ks1,des_key_schedule ks2, + des_key_schedule ks3, int enc); +DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output, + long length,des_key_schedule schedule,des_cblock *ivec); +void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length, + des_key_schedule schedule,des_cblock *ivec,int enc); +void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length, + des_key_schedule schedule,des_cblock *ivec,int enc); +void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length, + des_key_schedule schedule,des_cblock *ivec, + des_cblock *inw,des_cblock *outw,int enc); +void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits, + long length,des_key_schedule schedule,des_cblock *ivec,int enc); +void des_ecb_encrypt(des_cblock *input,des_cblock *output, + des_key_schedule ks,int enc); +void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc); +void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc); +void des_encrypt3(DES_LONG *data, des_key_schedule ks1, + des_key_schedule ks2, des_key_schedule ks3); +void des_decrypt3(DES_LONG *data, des_key_schedule ks1, + des_key_schedule ks2, des_key_schedule ks3); +void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, + long length, des_key_schedule ks1, des_key_schedule ks2, + des_key_schedule ks3, des_cblock *ivec, int enc); +void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule ks1, des_key_schedule ks2, + des_key_schedule ks3, des_cblock *ivec, int *num, int enc); +void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule ks1, des_key_schedule ks2, + des_key_schedule ks3, des_cblock *ivec, int *num); + +void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white), + des_cblock (*out_white)); + +int des_enc_read(int fd,char *buf,int len,des_key_schedule sched, + des_cblock *iv); +int des_enc_write(int fd,char *buf,int len,des_key_schedule sched, + des_cblock *iv); +char *des_fcrypt(const char *buf,const char *salt, char *ret); +#ifdef PERL5 +char *des_crypt(const char *buf,const char *salt); +#else +/* some stupid compilers complain because I have declared char instead + * of const char */ +#ifndef __KERNEL__ +#ifdef HEADER_DES_LOCL_H +char *crypt(const char *buf,const char *salt); +#else /* HEADER_DES_LOCL_H */ +char *crypt(void); +#endif /* HEADER_DES_LOCL_H */ +#endif /* __KERNEL__ */ +#endif /* PERL5 */ +void des_ofb_encrypt(unsigned char *in,unsigned char *out, + int numbits,long length,des_key_schedule schedule,des_cblock *ivec); +void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length, + des_key_schedule schedule,des_cblock *ivec,int enc); +DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output, + long length,int out_count,des_cblock *seed); +void des_random_seed(des_cblock key); +void des_random_key(des_cblock ret); +int des_read_password(des_cblock *key,char *prompt,int verify); +int des_read_2passwords(des_cblock *key1,des_cblock *key2, + char *prompt,int verify); +int des_read_pw_string(char *buf,int length,char *prompt,int verify); +void des_set_odd_parity(des_cblock *key); +int des_is_weak_key(des_cblock *key); +int des_set_key(des_cblock *key,des_key_schedule schedule); +int des_key_sched(des_cblock *key,des_key_schedule schedule); +void des_string_to_key(char *str,des_cblock *key); +void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2); +void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length, + des_key_schedule schedule, des_cblock *ivec, int *num, int enc); +void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length, + des_key_schedule schedule, des_cblock *ivec, int *num); +int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify); + +/* Extra functions from Mark Murray */ +/* The following functions are not in the normal unix build or the + * SSLeay build. When using the SSLeay build, use RAND_seed() + * and RAND_bytes() instead. */ +int des_new_random_key(des_cblock *key); +void des_init_random_number_generator(des_cblock *key); +void des_set_random_generator_seed(des_cblock *key); +void des_set_sequence_number(des_cblock new_sequence_number); +void des_generate_random_block(des_cblock *block); + +#else + +char *des_options(); +void des_ecb3_encrypt(); +DES_LONG des_cbc_cksum(); +void des_cbc_encrypt(); +void des_ncbc_encrypt(); +void des_xcbc_encrypt(); +void des_cfb_encrypt(); +void des_ede3_cfb64_encrypt(); +void des_ede3_ofb64_encrypt(); +void des_ecb_encrypt(); +void des_encrypt(); +void des_encrypt2(); +void des_encrypt3(); +void des_decrypt3(); +void des_ede3_cbc_encrypt(); +int des_enc_read(); +int des_enc_write(); +char *des_fcrypt(); +#ifdef PERL5 +char *des_crypt(); +#else +char *crypt(); +#endif +void des_ofb_encrypt(); +void des_pcbc_encrypt(); +DES_LONG des_quad_cksum(); +void des_random_seed(); +void des_random_key(); +int des_read_password(); +int des_read_2passwords(); +int des_read_pw_string(); +void des_set_odd_parity(); +int des_is_weak_key(); +int des_set_key(); +int des_key_sched(); +void des_string_to_key(); +void des_string_to_2keys(); +void des_cfb64_encrypt(); +void des_ofb64_encrypt(); +int des_read_pw(); +void des_xwhite_in2out(); + +/* Extra functions from Mark Murray */ +/* The following functions are not in the normal unix build or the + * SSLeay build. When using the SSLeay build, use RAND_seed() + * and RAND_bytes() instead. */ +#ifdef FreeBSD +int des_new_random_key(); +void des_init_random_number_generator(); +void des_set_random_generator_seed(); +void des_set_sequence_number(); +void des_generate_random_block(); +#endif + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff -urN linux-2.4.29/net/ipsec/libdes/des_enc.c linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des_enc.c --- linux-2.4.29/net/ipsec/libdes/des_enc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des_enc.c Thu Sep 5 05:13:20 2002 @@ -0,0 +1,502 @@ +/* crypto/des/des_enc.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +void des_encrypt(data, ks, enc) +DES_LONG *data; +des_key_schedule ks; +int enc; + { + register DES_LONG l,r,t,u; +#ifdef DES_PTR + register unsigned char *des_SP=(unsigned char *)des_SPtrans; +#endif +#ifndef DES_UNROLL + register int i; +#endif + register DES_LONG *s; + + r=data[0]; + l=data[1]; + + IP(r,l); + /* Things have been modified so that the initial rotate is + * done outside the loop. This required the + * des_SPtrans values in sp.h to be rotated 1 bit to the right. + * One perl script later and things have a 5% speed up on a sparc2. + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> + * for pointing this out. */ + /* clear the top bits on machines with 8byte longs */ + /* shift left by 2 */ + r=ROTATE(r,29)&0xffffffffL; + l=ROTATE(l,29)&0xffffffffL; + + s=(DES_LONG *)ks; + /* I don't know if it is worth the effort of loop unrolling the + * inner loop */ + if (enc) + { +#ifdef DES_UNROLL + D_ENCRYPT(l,r, 0); /* 1 */ + D_ENCRYPT(r,l, 2); /* 2 */ + D_ENCRYPT(l,r, 4); /* 3 */ + D_ENCRYPT(r,l, 6); /* 4 */ + D_ENCRYPT(l,r, 8); /* 5 */ + D_ENCRYPT(r,l,10); /* 6 */ + D_ENCRYPT(l,r,12); /* 7 */ + D_ENCRYPT(r,l,14); /* 8 */ + D_ENCRYPT(l,r,16); /* 9 */ + D_ENCRYPT(r,l,18); /* 10 */ + D_ENCRYPT(l,r,20); /* 11 */ + D_ENCRYPT(r,l,22); /* 12 */ + D_ENCRYPT(l,r,24); /* 13 */ + D_ENCRYPT(r,l,26); /* 14 */ + D_ENCRYPT(l,r,28); /* 15 */ + D_ENCRYPT(r,l,30); /* 16 */ +#else + for (i=0; i<32; i+=8) + { + D_ENCRYPT(l,r,i+0); /* 1 */ + D_ENCRYPT(r,l,i+2); /* 2 */ + D_ENCRYPT(l,r,i+4); /* 3 */ + D_ENCRYPT(r,l,i+6); /* 4 */ + } +#endif + } + else + { +#ifdef DES_UNROLL + D_ENCRYPT(l,r,30); /* 16 */ + D_ENCRYPT(r,l,28); /* 15 */ + D_ENCRYPT(l,r,26); /* 14 */ + D_ENCRYPT(r,l,24); /* 13 */ + D_ENCRYPT(l,r,22); /* 12 */ + D_ENCRYPT(r,l,20); /* 11 */ + D_ENCRYPT(l,r,18); /* 10 */ + D_ENCRYPT(r,l,16); /* 9 */ + D_ENCRYPT(l,r,14); /* 8 */ + D_ENCRYPT(r,l,12); /* 7 */ + D_ENCRYPT(l,r,10); /* 6 */ + D_ENCRYPT(r,l, 8); /* 5 */ + D_ENCRYPT(l,r, 6); /* 4 */ + D_ENCRYPT(r,l, 4); /* 3 */ + D_ENCRYPT(l,r, 2); /* 2 */ + D_ENCRYPT(r,l, 0); /* 1 */ +#else + for (i=30; i>0; i-=8) + { + D_ENCRYPT(l,r,i-0); /* 16 */ + D_ENCRYPT(r,l,i-2); /* 15 */ + D_ENCRYPT(l,r,i-4); /* 14 */ + D_ENCRYPT(r,l,i-6); /* 13 */ + } +#endif + } + + /* rotate and clear the top bits on machines with 8byte longs */ + l=ROTATE(l,3)&0xffffffffL; + r=ROTATE(r,3)&0xffffffffL; + + FP(r,l); + data[0]=l; + data[1]=r; + l=r=t=u=0; + } + +void des_encrypt2(data, ks, enc) +DES_LONG *data; +des_key_schedule ks; +int enc; + { + register DES_LONG l,r,t,u; +#ifdef DES_PTR + register unsigned char *des_SP=(unsigned char *)des_SPtrans; +#endif +#ifndef DES_UNROLL + register int i; +#endif + register DES_LONG *s; + + r=data[0]; + l=data[1]; + + /* Things have been modified so that the initial rotate is + * done outside the loop. This required the + * des_SPtrans values in sp.h to be rotated 1 bit to the right. + * One perl script later and things have a 5% speed up on a sparc2. + * Thanks to Richard Outerbridge <71755.204@CompuServe.COM> + * for pointing this out. */ + /* clear the top bits on machines with 8byte longs */ + r=ROTATE(r,29)&0xffffffffL; + l=ROTATE(l,29)&0xffffffffL; + + s=(DES_LONG *)ks; + /* I don't know if it is worth the effort of loop unrolling the + * inner loop */ + if (enc) + { +#ifdef DES_UNROLL + D_ENCRYPT(l,r, 0); /* 1 */ + D_ENCRYPT(r,l, 2); /* 2 */ + D_ENCRYPT(l,r, 4); /* 3 */ + D_ENCRYPT(r,l, 6); /* 4 */ + D_ENCRYPT(l,r, 8); /* 5 */ + D_ENCRYPT(r,l,10); /* 6 */ + D_ENCRYPT(l,r,12); /* 7 */ + D_ENCRYPT(r,l,14); /* 8 */ + D_ENCRYPT(l,r,16); /* 9 */ + D_ENCRYPT(r,l,18); /* 10 */ + D_ENCRYPT(l,r,20); /* 11 */ + D_ENCRYPT(r,l,22); /* 12 */ + D_ENCRYPT(l,r,24); /* 13 */ + D_ENCRYPT(r,l,26); /* 14 */ + D_ENCRYPT(l,r,28); /* 15 */ + D_ENCRYPT(r,l,30); /* 16 */ +#else + for (i=0; i<32; i+=8) + { + D_ENCRYPT(l,r,i+0); /* 1 */ + D_ENCRYPT(r,l,i+2); /* 2 */ + D_ENCRYPT(l,r,i+4); /* 3 */ + D_ENCRYPT(r,l,i+6); /* 4 */ + } +#endif + } + else + { +#ifdef DES_UNROLL + D_ENCRYPT(l,r,30); /* 16 */ + D_ENCRYPT(r,l,28); /* 15 */ + D_ENCRYPT(l,r,26); /* 14 */ + D_ENCRYPT(r,l,24); /* 13 */ + D_ENCRYPT(l,r,22); /* 12 */ + D_ENCRYPT(r,l,20); /* 11 */ + D_ENCRYPT(l,r,18); /* 10 */ + D_ENCRYPT(r,l,16); /* 9 */ + D_ENCRYPT(l,r,14); /* 8 */ + D_ENCRYPT(r,l,12); /* 7 */ + D_ENCRYPT(l,r,10); /* 6 */ + D_ENCRYPT(r,l, 8); /* 5 */ + D_ENCRYPT(l,r, 6); /* 4 */ + D_ENCRYPT(r,l, 4); /* 3 */ + D_ENCRYPT(l,r, 2); /* 2 */ + D_ENCRYPT(r,l, 0); /* 1 */ +#else + for (i=30; i>0; i-=8) + { + D_ENCRYPT(l,r,i-0); /* 16 */ + D_ENCRYPT(r,l,i-2); /* 15 */ + D_ENCRYPT(l,r,i-4); /* 14 */ + D_ENCRYPT(r,l,i-6); /* 13 */ + } +#endif + } + /* rotate and clear the top bits on machines with 8byte longs */ + data[0]=ROTATE(l,3)&0xffffffffL; + data[1]=ROTATE(r,3)&0xffffffffL; + l=r=t=u=0; + } + +void des_encrypt3(data,ks1,ks2,ks3) +DES_LONG *data; +des_key_schedule ks1; +des_key_schedule ks2; +des_key_schedule ks3; + { + register DES_LONG l,r; + + l=data[0]; + r=data[1]; + IP(l,r); + data[0]=l; + data[1]=r; + des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT); + des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT); + des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT); + l=data[0]; + r=data[1]; + FP(r,l); + data[0]=l; + data[1]=r; + } + +void des_decrypt3(data,ks1,ks2,ks3) +DES_LONG *data; +des_key_schedule ks1; +des_key_schedule ks2; +des_key_schedule ks3; + { + register DES_LONG l,r; + + l=data[0]; + r=data[1]; + IP(l,r); + data[0]=l; + data[1]=r; + des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT); + des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT); + des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT); + l=data[0]; + r=data[1]; + FP(r,l); + data[0]=l; + data[1]=r; + } + +#ifndef DES_DEFAULT_OPTIONS + +void des_ncbc_encrypt(input, output, length, schedule, ivec, enc) +des_cblock (*input); +des_cblock (*output); +long length; +des_key_schedule schedule; +des_cblock (*ivec); +int enc; + { + register DES_LONG tin0,tin1; + register DES_LONG tout0,tout1,xor0,xor1; + register unsigned char *in,*out; + register long l=length; + DES_LONG tin[2]; + unsigned char *iv; + + in=(unsigned char *)input; + out=(unsigned char *)output; + iv=(unsigned char *)ivec; + + if (enc) + { + c2l(iv,tout0); + c2l(iv,tout1); + for (l-=8; l>=0; l-=8) + { + c2l(in,tin0); + c2l(in,tin1); + tin0^=tout0; tin[0]=tin0; + tin1^=tout1; tin[1]=tin1; + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); + tout0=tin[0]; l2c(tout0,out); + tout1=tin[1]; l2c(tout1,out); + } + if (l != -8) + { + c2ln(in,tin0,tin1,l+8); + tin0^=tout0; tin[0]=tin0; + tin1^=tout1; tin[1]=tin1; + des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); + tout0=tin[0]; l2c(tout0,out); + tout1=tin[1]; l2c(tout1,out); + } + iv=(unsigned char *)ivec; + l2c(tout0,iv); + l2c(tout1,iv); + } + else + { + c2l(iv,xor0); + c2l(iv,xor1); + for (l-=8; l>=0; l-=8) + { + c2l(in,tin0); tin[0]=tin0; + c2l(in,tin1); tin[1]=tin1; + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); + tout0=tin[0]^xor0; + tout1=tin[1]^xor1; + l2c(tout0,out); + l2c(tout1,out); + xor0=tin0; + xor1=tin1; + } + if (l != -8) + { + c2l(in,tin0); tin[0]=tin0; + c2l(in,tin1); tin[1]=tin1; + des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT); + tout0=tin[0]^xor0; + tout1=tin[1]^xor1; + l2cn(tout0,tout1,out,l+8); + xor0=tin0; + xor1=tin1; + } + + iv=(unsigned char *)ivec; + l2c(xor0,iv); + l2c(xor1,iv); + } + tin0=tin1=tout0=tout1=xor0=xor1=0; + tin[0]=tin[1]=0; + } + +void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc) +des_cblock (*input); +des_cblock (*output); +long length; +des_key_schedule ks1; +des_key_schedule ks2; +des_key_schedule ks3; +des_cblock (*ivec); +int enc; + { + register DES_LONG tin0,tin1; + register DES_LONG tout0,tout1,xor0,xor1; + register unsigned char *in,*out; + register long l=length; + DES_LONG tin[2]; + unsigned char *iv; + + in=(unsigned char *)input; + out=(unsigned char *)output; + iv=(unsigned char *)ivec; + + if (enc) + { + c2l(iv,tout0); + c2l(iv,tout1); + for (l-=8; l>=0; l-=8) + { + c2l(in,tin0); + c2l(in,tin1); + tin0^=tout0; + tin1^=tout1; + + tin[0]=tin0; + tin[1]=tin1; + des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3); + tout0=tin[0]; + tout1=tin[1]; + + l2c(tout0,out); + l2c(tout1,out); + } + if (l != -8) + { + c2ln(in,tin0,tin1,l+8); + tin0^=tout0; + tin1^=tout1; + + tin[0]=tin0; + tin[1]=tin1; + des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3); + tout0=tin[0]; + tout1=tin[1]; + + l2c(tout0,out); + l2c(tout1,out); + } + iv=(unsigned char *)ivec; + l2c(tout0,iv); + l2c(tout1,iv); + } + else + { + register DES_LONG t0,t1; + + c2l(iv,xor0); + c2l(iv,xor1); + for (l-=8; l>=0; l-=8) + { + c2l(in,tin0); + c2l(in,tin1); + + t0=tin0; + t1=tin1; + + tin[0]=tin0; + tin[1]=tin1; + des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3); + tout0=tin[0]; + tout1=tin[1]; + + tout0^=xor0; + tout1^=xor1; + l2c(tout0,out); + l2c(tout1,out); + xor0=t0; + xor1=t1; + } + if (l != -8) + { + c2l(in,tin0); + c2l(in,tin1); + + t0=tin0; + t1=tin1; + + tin[0]=tin0; + tin[1]=tin1; + des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3); + tout0=tin[0]; + tout1=tin[1]; + + tout0^=xor0; + tout1^=xor1; + l2cn(tout0,tout1,out,l+8); + xor0=t0; + xor1=t1; + } + + iv=(unsigned char *)ivec; + l2c(xor0,iv); + l2c(xor1,iv); + } + tin0=tin1=tout0=tout1=xor0=xor1=0; + tin[0]=tin[1]=0; + } + +#endif /* DES_DEFAULT_OPTIONS */ diff -urN linux-2.4.29/net/ipsec/libdes/des_locl.h linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des_locl.h --- linux-2.4.29/net/ipsec/libdes/des_locl.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des_locl.h Thu Sep 5 05:13:20 2002 @@ -0,0 +1,515 @@ +/* crypto/des/des_locl.org */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * Always modify des_locl.org since des_locl.h is automatically generated from + * it during SSLeay configuration. + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ + +#ifndef HEADER_DES_LOCL_H +#define HEADER_DES_LOCL_H + +#if defined(WIN32) || defined(WIN16) +#ifndef MSDOS +#define MSDOS +#endif +#endif + +#include "des.h" + +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#define DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#define DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#define DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( sun ) /* Newer Sparc's */ + #define DES_PTR + #define DES_RISC1 + #define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ + #define DES_PTR + #define DES_RISC2 + #define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ + #define DES_PTR + #define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ + #define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ + #define DES_PTR + #define DES_RISC2 + #define DES_UNROLL +#elif defined( i386 ) /* x86 boxes, should be gcc */ + #define DES_PTR + #define DES_RISC1 + #define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ + +#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */ +#include +#include +#include +#include +#ifndef RAND +#define RAND +#endif +#undef NOPROTO +#endif + +#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS) +#ifndef __KERNEL__ +#include +#else +#include +#endif +#endif + +#ifndef RAND +#define RAND +#endif + +#ifdef linux +#undef RAND +#endif + +#ifdef MSDOS +#define getpid() 2 +#define RAND +#undef NOPROTO +#endif + +#if defined(NOCONST) +#define const +#endif + +#ifdef __STDC__ +#undef NOPROTO +#endif + +#ifdef RAND +#define srandom(s) srand(s) +#define random rand +#endif + +#define ITERATIONS 16 +#define HALF_ITERATIONS 8 + +/* used in des_read and des_write */ +#define MAXWRITE (1024*16) +#define BSIZE (MAXWRITE+4) + +#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ + case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ + case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ + case 5: l2|=((DES_LONG)(*(--(c)))); \ + case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ + case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ + case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ + case 1: l1|=((DES_LONG)(*(--(c)))); \ + } \ + } + +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* replacements for htonl and ntohl since I have no idea what to do + * when faced with machines with 8 byte longs. */ +#define HDRSIZE 4 + +#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))) + +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +#if defined(WIN32) +#define ROTATE(a,n) (_lrotr(a,n)) +#else +#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) +#endif + +/* Don't worry about the LOAD_DATA() stuff, that is used by + * fcrypt() to add it's little bit to the front */ + +#ifdef DES_FCRYPT + +#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ + { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } + +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ + t=R^(R>>16L); \ + u=t&E0; t&=E1; \ + tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ + tmp=(t<<16); t^=R^s[S+1]; t^=tmp +#else +#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) +#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ + u=R^s[S ]; \ + t=R^s[S+1] +#endif + +/* The changes to this macro may help or hinder, depending on the + * compiler and the achitecture. gcc2 always seems to do well :-). + * Inspired by Dana How + * DO NOT use the alternative version on machines with 8 byte longs. + * It does not seem to work on the Alpha, even when DES_LONG is 4 + * bytes, probably an issue of accessing non-word aligned objects :-( */ +#ifdef DES_PTR + +/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there + * is no reason to not xor all the sub items together. This potentially + * saves a register since things can be xored directly into L */ + +#if defined(DES_RISC1) || defined(DES_RISC2) +#ifdef DES_RISC1 +#define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,u3; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u2=(int)u>>8L; \ + u1=(int)u&0xfc; \ + u2&=0xfc; \ + t=ROTATE(t,4); \ + u>>=16L; \ + LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \ + u3=(int)(u>>8L); \ + u1=(int)u&0xfc; \ + u3&=0xfc; \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \ + u2=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u2&=0xfc; \ + t>>=16L; \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \ + u3=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u3&=0xfc; \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); } +#endif +#ifdef DES_RISC2 +#define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,s1,s2; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u2=(int)u>>8L; \ + u1=(int)u&0xfc; \ + u2&=0xfc; \ + t=ROTATE(t,4); \ + LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \ + s1=(int)(u>>16L); \ + s2=(int)(u>>24L); \ + s1&=0xfc; \ + s2&=0xfc; \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \ + u2=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u2&=0xfc; \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \ + s1=(int)(t>>16L); \ + s2=(int)(t>>24L); \ + s1&=0xfc; \ + s2&=0xfc; \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \ + LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); } +#endif +#else +#define D_ENCRYPT(LL,R,S) { \ + LOAD_DATA_tmp(R,S,u,t,E0,E1); \ + t=ROTATE(t,4); \ + LL^= \ + *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \ + *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \ + *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \ + *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \ + *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \ + *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \ + *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \ + *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); } +#endif + +#else /* original version */ + +#if defined(DES_RISC1) || defined(DES_RISC2) +#ifdef DES_RISC1 +#define D_ENCRYPT(LL,R,S) {\ + unsigned int u1,u2,u3; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u>>=2L; \ + t=ROTATE(t,6); \ + u2=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u2&=0x3f; \ + u>>=16L; \ + LL^=des_SPtrans[0][u1]; \ + LL^=des_SPtrans[2][u2]; \ + u3=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u3&=0x3f; \ + LL^=des_SPtrans[4][u1]; \ + LL^=des_SPtrans[6][u3]; \ + u2=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u2&=0x3f; \ + t>>=16L; \ + LL^=des_SPtrans[1][u1]; \ + LL^=des_SPtrans[3][u2]; \ + u3=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u3&=0x3f; \ + LL^=des_SPtrans[5][u1]; \ + LL^=des_SPtrans[7][u3]; } +#endif +#ifdef DES_RISC2 +#define D_ENCRYPT(LL,R,S) {\ + unsigned int u1,u2,s1,s2; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u>>=2L; \ + t=ROTATE(t,6); \ + u2=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u2&=0x3f; \ + LL^=des_SPtrans[0][u1]; \ + LL^=des_SPtrans[2][u2]; \ + s1=(int)u>>16L; \ + s2=(int)u>>24L; \ + s1&=0x3f; \ + s2&=0x3f; \ + LL^=des_SPtrans[4][s1]; \ + LL^=des_SPtrans[6][s2]; \ + u2=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u2&=0x3f; \ + LL^=des_SPtrans[1][u1]; \ + LL^=des_SPtrans[3][u2]; \ + s1=(int)t>>16; \ + s2=(int)t>>24L; \ + s1&=0x3f; \ + s2&=0x3f; \ + LL^=des_SPtrans[5][s1]; \ + LL^=des_SPtrans[7][s2]; } +#endif + +#else + +#define D_ENCRYPT(LL,R,S) {\ + LOAD_DATA_tmp(R,S,u,t,E0,E1); \ + t=ROTATE(t,4); \ + LL^=\ + des_SPtrans[0][(u>> 2L)&0x3f]^ \ + des_SPtrans[2][(u>>10L)&0x3f]^ \ + des_SPtrans[4][(u>>18L)&0x3f]^ \ + des_SPtrans[6][(u>>26L)&0x3f]^ \ + des_SPtrans[1][(t>> 2L)&0x3f]^ \ + des_SPtrans[3][(t>>10L)&0x3f]^ \ + des_SPtrans[5][(t>>18L)&0x3f]^ \ + des_SPtrans[7][(t>>26L)&0x3f]; } +#endif +#endif + + /* IP and FP + * The problem is more of a geometric problem that random bit fiddling. + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 + 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 + 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 + + 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 + 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 + 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 + 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 + + The output has been subject to swaps of the form + 0 1 -> 3 1 but the odd and even bits have been put into + 2 3 2 0 + different words. The main trick is to remember that + t=((l>>size)^r)&(mask); + r^=t; + l^=(t<>(n))^(b))&(m)),\ + (b)^=(t),\ + (a)^=((t)<<(n))) + +#define IP(l,r) \ + { \ + register DES_LONG tt; \ + PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ + PERM_OP(l,r,tt,16,0x0000ffffL); \ + PERM_OP(r,l,tt, 2,0x33333333L); \ + PERM_OP(l,r,tt, 8,0x00ff00ffL); \ + PERM_OP(r,l,tt, 1,0x55555555L); \ + } + +#define FP(l,r) \ + { \ + register DES_LONG tt; \ + PERM_OP(l,r,tt, 1,0x55555555L); \ + PERM_OP(r,l,tt, 8,0x00ff00ffL); \ + PERM_OP(l,r,tt, 2,0x33333333L); \ + PERM_OP(r,l,tt,16,0x0000ffffL); \ + PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ + } + +extern const DES_LONG des_SPtrans[8][64]; + +#ifndef NOPROTO +void fcrypt_body(DES_LONG *out,des_key_schedule ks, + DES_LONG Eswap0, DES_LONG Eswap1); +#else +void fcrypt_body(); +#endif + +#endif diff -urN linux-2.4.29/net/ipsec/libdes/des_opts.c linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des_opts.c --- linux-2.4.29/net/ipsec/libdes/des_opts.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des_opts.c Thu Sep 5 05:13:20 2002 @@ -0,0 +1,620 @@ +/* crypto/des/des_opts.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* define PART1, PART2, PART3 or PART4 to build only with a few of the options. + * This is for machines with 64k code segment size restrictions. */ + +#ifndef MSDOS +#define TIMES +#endif + +#include +#ifndef MSDOS +#include +#else +#include +extern void exit(); +#endif +#include +#ifndef VMS +#ifndef _IRIX +#include +#endif +#ifdef TIMES +#include +#include +#endif +#else /* VMS */ +#include +struct tms { + time_t tms_utime; + time_t tms_stime; + time_t tms_uchild; /* I dunno... */ + time_t tms_uchildsys; /* so these names are a guess :-) */ + } +#endif +#ifndef TIMES +#include +#endif + +#ifdef sun +#include +#include +#endif + +#include "des.h" +#include "spr.h" + +#define DES_DEFAULT_OPTIONS + +#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4) +#define PART1 +#define PART2 +#define PART3 +#define PART4 +#endif + +#ifdef PART1 + +#undef DES_UNROLL +#undef DES_RISC1 +#undef DES_RISC2 +#undef DES_PTR +#undef D_ENCRYPT +#define des_encrypt des_encrypt_u4_cisc_idx +#define des_encrypt2 des_encrypt2_u4_cisc_idx +#define des_encrypt3 des_encrypt3_u4_cisc_idx +#define des_decrypt3 des_decrypt3_u4_cisc_idx +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#define DES_UNROLL +#undef DES_RISC1 +#undef DES_RISC2 +#undef DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u16_cisc_idx +#define des_encrypt2 des_encrypt2_u16_cisc_idx +#define des_encrypt3 des_encrypt3_u16_cisc_idx +#define des_decrypt3 des_decrypt3_u16_cisc_idx +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#undef DES_UNROLL +#define DES_RISC1 +#undef DES_RISC2 +#undef DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u4_risc1_idx +#define des_encrypt2 des_encrypt2_u4_risc1_idx +#define des_encrypt3 des_encrypt3_u4_risc1_idx +#define des_decrypt3 des_decrypt3_u4_risc1_idx +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#endif + +#ifdef PART2 + +#undef DES_UNROLL +#undef DES_RISC1 +#define DES_RISC2 +#undef DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u4_risc2_idx +#define des_encrypt2 des_encrypt2_u4_risc2_idx +#define des_encrypt3 des_encrypt3_u4_risc2_idx +#define des_decrypt3 des_decrypt3_u4_risc2_idx +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#define DES_UNROLL +#define DES_RISC1 +#undef DES_RISC2 +#undef DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u16_risc1_idx +#define des_encrypt2 des_encrypt2_u16_risc1_idx +#define des_encrypt3 des_encrypt3_u16_risc1_idx +#define des_decrypt3 des_decrypt3_u16_risc1_idx +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#define DES_UNROLL +#undef DES_RISC1 +#define DES_RISC2 +#undef DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u16_risc2_idx +#define des_encrypt2 des_encrypt2_u16_risc2_idx +#define des_encrypt3 des_encrypt3_u16_risc2_idx +#define des_decrypt3 des_decrypt3_u16_risc2_idx +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#endif + +#ifdef PART3 + +#undef DES_UNROLL +#undef DES_RISC1 +#undef DES_RISC2 +#define DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u4_cisc_ptr +#define des_encrypt2 des_encrypt2_u4_cisc_ptr +#define des_encrypt3 des_encrypt3_u4_cisc_ptr +#define des_decrypt3 des_decrypt3_u4_cisc_ptr +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#define DES_UNROLL +#undef DES_RISC1 +#undef DES_RISC2 +#define DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u16_cisc_ptr +#define des_encrypt2 des_encrypt2_u16_cisc_ptr +#define des_encrypt3 des_encrypt3_u16_cisc_ptr +#define des_decrypt3 des_decrypt3_u16_cisc_ptr +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#undef DES_UNROLL +#define DES_RISC1 +#undef DES_RISC2 +#define DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u4_risc1_ptr +#define des_encrypt2 des_encrypt2_u4_risc1_ptr +#define des_encrypt3 des_encrypt3_u4_risc1_ptr +#define des_decrypt3 des_decrypt3_u4_risc1_ptr +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#endif + +#ifdef PART4 + +#undef DES_UNROLL +#undef DES_RISC1 +#define DES_RISC2 +#define DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u4_risc2_ptr +#define des_encrypt2 des_encrypt2_u4_risc2_ptr +#define des_encrypt3 des_encrypt3_u4_risc2_ptr +#define des_decrypt3 des_decrypt3_u4_risc2_ptr +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#define DES_UNROLL +#define DES_RISC1 +#undef DES_RISC2 +#define DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u16_risc1_ptr +#define des_encrypt2 des_encrypt2_u16_risc1_ptr +#define des_encrypt3 des_encrypt3_u16_risc1_ptr +#define des_decrypt3 des_decrypt3_u16_risc1_ptr +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#define DES_UNROLL +#undef DES_RISC1 +#define DES_RISC2 +#define DES_PTR +#undef D_ENCRYPT +#undef des_encrypt +#undef des_encrypt2 +#undef des_encrypt3 +#undef des_decrypt3 +#define des_encrypt des_encrypt_u16_risc2_ptr +#define des_encrypt2 des_encrypt2_u16_risc2_ptr +#define des_encrypt3 des_encrypt3_u16_risc2_ptr +#define des_decrypt3 des_decrypt3_u16_risc2_ptr +#undef HEADER_DES_LOCL_H +#include "des_enc.c" + +#endif + +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ +# ifndef VMS +# define HZ 100.0 +# else /* VMS */ +# define HZ 100.0 +# endif +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif + +#define BUFSIZE ((long)1024) +long run=0; + +#ifndef NOPROTO +double Time_F(int s); +#else +double Time_F(); +#endif + +#ifdef SIGALRM +#if defined(__STDC__) || defined(sgi) +#define SIGRETTYPE void +#else +#define SIGRETTYPE int +#endif + +#ifndef NOPROTO +SIGRETTYPE sig_done(int sig); +#else +SIGRETTYPE sig_done(); +#endif + +SIGRETTYPE sig_done(sig) +int sig; + { + signal(SIGALRM,sig_done); + run=0; +#ifdef LINT + sig=sig; +#endif + } +#endif + +#define START 0 +#define STOP 1 + +double Time_F(s) +int s; + { + double ret; +#ifdef TIMES + static struct tms tstart,tend; + + if (s == START) + { + times(&tstart); + return(0); + } + else + { + times(&tend); + ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; + return((ret == 0.0)?1e-6:ret); + } +#else /* !times() */ + static struct timeb tstart,tend; + long i; + + if (s == START) + { + ftime(&tstart); + return(0); + } + else + { + ftime(&tend); + i=(long)tend.millitm-(long)tstart.millitm; + ret=((double)(tend.time-tstart.time))+((double)i)/1000.0; + return((ret == 0.0)?1e-6:ret); + } +#endif + } + +#ifdef SIGALRM +#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10); +#else +#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb); +#endif + +#define time_it(func,name,index) \ + print_name(name); \ + Time_F(START); \ + for (count=0,run=1; COND(cb); count++) \ + { \ + unsigned long d[2]; \ + func(d,&(sch[0]),DES_ENCRYPT); \ + } \ + tm[index]=Time_F(STOP); \ + fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \ + tm[index]=((double)COUNT(cb))/tm[index]; + +#define print_it(name,index) \ + fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \ + tm[index]*8,1.0e6/tm[index]); + +int main(argc,argv) +int argc; +char **argv; + { + long count; + static unsigned char buf[BUFSIZE]; + static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; + static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12}; + static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; + des_key_schedule sch,sch2,sch3; + double d,tm[16],max=0; + int rank[16]; + char *str[16]; + int max_idx=0,i,num=0,j; +#ifndef SIGALARM + long ca,cb,cc,cd,ce; +#endif + + for (i=0; i<12; i++) + { + tm[i]=0.0; + rank[i]=0; + } + +#ifndef TIMES + fprintf(stderr,"To get the most acurate results, try to run this\n"); + fprintf(stderr,"program when this computer is idle.\n"); +#endif + + des_set_key((C_Block *)key,sch); + des_set_key((C_Block *)key2,sch2); + des_set_key((C_Block *)key3,sch3); + +#ifndef SIGALRM + fprintf(stderr,"First we calculate the approximate speed ...\n"); + des_set_key((C_Block *)key,sch); + count=10; + do { + long i; + unsigned long data[2]; + + count*=2; + Time_F(START); + for (i=count; i; i--) + des_encrypt(data,&(sch[0]),DES_ENCRYPT); + d=Time_F(STOP); + } while (d < 3.0); + ca=count; + cb=count*3; + cc=count*3*8/BUFSIZE+1; + cd=count*8/BUFSIZE+1; + + ce=count/20+1; +#define COND(d) (count != (d)) +#define COUNT(d) (d) +#else +#define COND(c) (run) +#define COUNT(d) (count) + signal(SIGALRM,sig_done); + alarm(10); +#endif + +#ifdef PART1 + time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0); + time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1); + time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2); + num+=3; +#endif +#ifdef PART2 + time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3); + time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4); + time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5); + num+=3; +#endif +#ifdef PART3 + time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6); + time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7); + time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8); + num+=3; +#endif +#ifdef PART4 + time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9); + time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10); + time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11); + num+=3; +#endif + +#ifdef PART1 + str[0]=" 4 c i"; + print_it("des_encrypt_u4_cisc_idx ",0); + max=tm[0]; + max_idx=0; + str[1]="16 c i"; + print_it("des_encrypt_u16_cisc_idx ",1); + if (max < tm[1]) { max=tm[1]; max_idx=1; } + str[2]=" 4 r1 i"; + print_it("des_encrypt_u4_risc1_idx ",2); + if (max < tm[2]) { max=tm[2]; max_idx=2; } +#endif +#ifdef PART2 + str[3]="16 r1 i"; + print_it("des_encrypt_u16_risc1_idx",3); + if (max < tm[3]) { max=tm[3]; max_idx=3; } + str[4]=" 4 r2 i"; + print_it("des_encrypt_u4_risc2_idx ",4); + if (max < tm[4]) { max=tm[4]; max_idx=4; } + str[5]="16 r2 i"; + print_it("des_encrypt_u16_risc2_idx",5); + if (max < tm[5]) { max=tm[5]; max_idx=5; } +#endif +#ifdef PART3 + str[6]=" 4 c p"; + print_it("des_encrypt_u4_cisc_ptr ",6); + if (max < tm[6]) { max=tm[6]; max_idx=6; } + str[7]="16 c p"; + print_it("des_encrypt_u16_cisc_ptr ",7); + if (max < tm[7]) { max=tm[7]; max_idx=7; } + str[8]=" 4 r1 p"; + print_it("des_encrypt_u4_risc1_ptr ",8); + if (max < tm[8]) { max=tm[8]; max_idx=8; } +#endif +#ifdef PART4 + str[9]="16 r1 p"; + print_it("des_encrypt_u16_risc1_ptr",9); + if (max < tm[9]) { max=tm[9]; max_idx=9; } + str[10]=" 4 r2 p"; + print_it("des_encrypt_u4_risc2_ptr ",10); + if (max < tm[10]) { max=tm[10]; max_idx=10; } + str[11]="16 r2 p"; + print_it("des_encrypt_u16_risc2_ptr",11); + if (max < tm[11]) { max=tm[11]; max_idx=11; } +#endif + printf("options des ecb/s\n"); + printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]); + d=tm[max_idx]; + tm[max_idx]= -2.0; + max= -1.0; + for (;;) + { + for (i=0; i<12; i++) + { + if (max < tm[i]) { max=tm[i]; j=i; } + } + if (max < 0.0) break; + printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0); + tm[j]= -2.0; + max= -1.0; + } + + switch (max_idx) + { + case 0: + printf("-DDES_DEFAULT_OPTIONS\n"); + break; + case 1: + printf("-DDES_UNROLL\n"); + break; + case 2: + printf("-DDES_RISC1\n"); + break; + case 3: + printf("-DDES_UNROLL -DDES_RISC1\n"); + break; + case 4: + printf("-DDES_RISC2\n"); + break; + case 5: + printf("-DDES_UNROLL -DDES_RISC2\n"); + break; + case 6: + printf("-DDES_PTR\n"); + break; + case 7: + printf("-DDES_UNROLL -DDES_PTR\n"); + break; + case 8: + printf("-DDES_RISC1 -DDES_PTR\n"); + break; + case 9: + printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n"); + break; + case 10: + printf("-DDES_RISC2 -DDES_PTR\n"); + break; + case 11: + printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n"); + break; + } + exit(0); +#if defined(LINT) || defined(MSDOS) + return(0); +#endif + } diff -urN linux-2.4.29/net/ipsec/libdes/des_ver.h linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des_ver.h --- linux-2.4.29/net/ipsec/libdes/des_ver.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/des_ver.h Thu Sep 5 05:13:20 2002 @@ -0,0 +1,60 @@ +/* crypto/des/des_ver.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +extern char *DES_version; /* SSLeay version string */ +extern char *libdes_version; /* old libdes version string */ diff -urN linux-2.4.29/net/ipsec/libdes/destest.c linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/destest.c --- linux-2.4.29/net/ipsec/libdes/destest.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/destest.c Thu Sep 5 05:13:20 2002 @@ -0,0 +1,871 @@ +/* crypto/des/destest.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#if defined(WIN32) || defined(WIN16) || defined(WINDOWS) +#ifndef MSDOS +#define MSDOS +#endif +#endif + +#include +#include +#ifndef MSDOS +#include +#else +#include +#endif +#include +#include "des.h" + +/* tisk tisk - the test keys don't all have odd parity :-( */ +/* test data */ +#define NUM_TESTS 34 +static unsigned char key_data[NUM_TESTS][8]={ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}, + {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57}, + {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E}, + {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86}, + {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E}, + {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6}, + {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE}, + {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6}, + {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE}, + {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16}, + {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F}, + {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46}, + {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E}, + {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76}, + {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07}, + {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F}, + {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7}, + {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF}, + {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6}, + {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF}, + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, + {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E}, + {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}}; + +static unsigned char plain_data[NUM_TESTS][8]={ + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42}, + {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA}, + {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72}, + {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A}, + {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2}, + {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A}, + {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2}, + {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A}, + {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02}, + {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A}, + {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32}, + {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA}, + {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62}, + {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2}, + {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA}, + {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92}, + {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A}, + {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2}, + {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, + {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}}; + +static unsigned char cipher_data[NUM_TESTS][8]={ + {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, + {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58}, + {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B}, + {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33}, + {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D}, + {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD}, + {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7}, + {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4}, + {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B}, + {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71}, + {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A}, + {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A}, + {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95}, + {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B}, + {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09}, + {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A}, + {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F}, + {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88}, + {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77}, + {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A}, + {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56}, + {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56}, + {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56}, + {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC}, + {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A}, + {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41}, + {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93}, + {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00}, + {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06}, + {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7}, + {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51}, + {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE}, + {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D}, + {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}}; + +static unsigned char cipher_ecb2[NUM_TESTS-1][8]={ + {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E}, + {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16}, + {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27}, + {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6}, + {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25}, + {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A}, + {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74}, + {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6}, + {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67}, + {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10}, + {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85}, + {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA}, + {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3}, + {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3}, + {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A}, + {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69}, + {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1}, + {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7}, + {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F}, + {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87}, + {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A}, + {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE}, + {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3}, + {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD}, + {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84}, + {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85}, + {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC}, + {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89}, + {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E}, + {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89}, + {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7}, + {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8}, + {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}}; + +static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87}; +static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; +static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10}; +static char cbc_data[40]="7654321 Now is the time for \0001"; + +static unsigned char cbc_ok[32]={ + 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, + 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb, + 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68, + 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; + +static unsigned char xcbc_ok[32]={ + 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48, + 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD, + 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76, + 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2, + }; + +static unsigned char cbc3_ok[32]={ + 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0, + 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC, + 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4, + 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75}; + +static unsigned char pcbc_ok[32]={ + 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4, + 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15, + 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f, + 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88}; + +static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; +static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8]; +static unsigned char plain[24]= + { + 0x4e,0x6f,0x77,0x20,0x69,0x73, + 0x20,0x74,0x68,0x65,0x20,0x74, + 0x69,0x6d,0x65,0x20,0x66,0x6f, + 0x72,0x20,0x61,0x6c,0x6c,0x20 + }; +static unsigned char cfb_cipher8[24]= { + 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8, + 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 }; +static unsigned char cfb_cipher16[24]={ + 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70, + 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B }; +static unsigned char cfb_cipher32[24]={ + 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD, + 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 }; +static unsigned char cfb_cipher48[24]={ + 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85, + 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F }; +static unsigned char cfb_cipher64[24]={ + 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B, + 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 }; + +static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; +static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; +static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8]; +static unsigned char ofb_cipher[24]= + { + 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51, + 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f, + 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3 + }; + +DES_LONG cbc_cksum_ret=0xB462FEF7L; +unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4}; + +#ifndef NOPROTO +static char *pt(unsigned char *p); +static int cfb_test(int bits, unsigned char *cfb_cipher); +static int cfb64_test(unsigned char *cfb_cipher); +static int ede_cfb64_test(unsigned char *cfb_cipher); +#else +static char *pt(); +static int cfb_test(); +static int cfb64_test(); +static int ede_cfb64_test(); +#endif + +int main(argc,argv) +int argc; +char *argv[]; + { + int i,j,err=0; + des_cblock in,out,outin,iv3; + des_key_schedule ks,ks2,ks3; + unsigned char cbc_in[40]; + unsigned char cbc_out[40]; + DES_LONG cs; + unsigned char qret[4][4],cret[8]; + DES_LONG lqret[4]; + int num; + char *str; + + printf("Doing ecb\n"); + for (i=0; i>4)&0xf]; + ret[i*2+1]=f[p[i]&0xf]; + } + ret[16]='\0'; + return(ret); + } + +#ifndef LIBDES_LIT + +static int cfb_test(bits, cfb_cipher) +int bits; +unsigned char *cfb_cipher; + { + des_key_schedule ks; + int i,err=0; + + des_key_sched((C_Block *)cfb_key,ks); + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks, + (C_Block *)cfb_tmp,DES_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt encrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks, + (C_Block *)cfb_tmp,DES_DECRYPT); + if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt decrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + return(err); + } + +static int cfb64_test(cfb_cipher) +unsigned char *cfb_cipher; + { + des_key_schedule ks; + int err=0,i,n; + + des_key_sched((C_Block *)cfb_key,ks); + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks, + (C_Block *)cfb_tmp,&n,DES_ENCRYPT); + des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), + (long)sizeof(plain)-12,ks, + (C_Block *)cfb_tmp,&n,DES_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt encrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks, + (C_Block *)cfb_tmp,&n,DES_DECRYPT); + des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), + (long)sizeof(plain)-17,ks, + (C_Block *)cfb_tmp,&n,DES_DECRYPT); + if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) + { + err=1; + printf("cfb_encrypt decrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf2[i]))); + } + return(err); + } + +static int ede_cfb64_test(cfb_cipher) +unsigned char *cfb_cipher; + { + des_key_schedule ks; + int err=0,i,n; + + des_key_sched((C_Block *)cfb_key,ks); + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks, + (C_Block *)cfb_tmp,&n,DES_ENCRYPT); + des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]), + (long)sizeof(plain)-12,ks,ks,ks, + (C_Block *)cfb_tmp,&n,DES_ENCRYPT); + if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0) + { + err=1; + printf("ede_cfb_encrypt encrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv)); + n=0; + des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks, + (C_Block *)cfb_tmp,&n,DES_DECRYPT); + des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]), + (long)sizeof(plain)-17,ks,ks,ks, + (C_Block *)cfb_tmp,&n,DES_DECRYPT); + if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0) + { + err=1; + printf("ede_cfb_encrypt decrypt error\n"); + for (i=0; i<24; i+=8) + printf("%s\n",pt(&(cfb_buf2[i]))); + } + return(err); + } + +#endif + diff -urN linux-2.4.29/net/ipsec/libdes/ecb_enc.c linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/ecb_enc.c --- linux-2.4.29/net/ipsec/libdes/ecb_enc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/ecb_enc.c Thu Sep 5 05:13:20 2002 @@ -0,0 +1,128 @@ +/* crypto/des/ecb_enc.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" +#include "spr.h" + +char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay"; +char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998"; + +/* RCSID $Id: ecb_enc.c,v 1.1.1.1 2002/09/05 03:13:20 ken Exp $ */ +/* This function ifdef'ed out for FreeS/WAN project. */ +#ifdef notdef +char *des_options() + { + static int init=1; + static char buf[32]; + + if (init) + { + char *ptr,*unroll,*risc,*size; + + init=0; +#ifdef DES_PTR + ptr="ptr"; +#else + ptr="idx"; +#endif +#if defined(DES_RISC1) || defined(DES_RISC2) +#ifdef DES_RISC1 + risc="risc1"; +#endif +#ifdef DES_RISC2 + risc="risc2"; +#endif +#else + risc="cisc"; +#endif +#ifdef DES_UNROLL + unroll="16"; +#else + unroll="4"; +#endif + if (sizeof(DES_LONG) != sizeof(long)) + size="int"; + else + size="long"; + sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size); + } + return(buf); + } +#endif + + +void des_ecb_encrypt(input, output, ks, enc) +des_cblock (*input); +des_cblock (*output); +des_key_schedule ks; +int enc; + { + register DES_LONG l; + register unsigned char *in,*out; + DES_LONG ll[2]; + + in=(unsigned char *)input; + out=(unsigned char *)output; + c2l(in,l); ll[0]=l; + c2l(in,l); ll[1]=l; + des_encrypt(ll,ks,enc); + l=ll[0]; l2c(l,out); + l=ll[1]; l2c(l,out); + l=ll[0]=ll[1]=0; + } + diff -urN linux-2.4.29/net/ipsec/libdes/fcrypt.c linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/fcrypt.c --- linux-2.4.29/net/ipsec/libdes/fcrypt.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/fcrypt.c Thu Sep 5 05:13:20 2002 @@ -0,0 +1,152 @@ +/* NOCW */ + +/* This version of crypt has been developed from my MIT compatable + * DES library. + * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au + * Eric Young (eay@cryptsoft.com) + */ + +/* Modification by Jens Kupferschmidt (Cu) + * I have included directive PARA for shared memory computers. + * I have included a directive LONGCRYPT to using this routine to cipher + * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN + * definition is the maximum of lenght of password and can changed. I have + * defined 24. + */ + +#include "des_locl.h" + +/* Added more values to handle illegal salt values the way normal + * crypt() implementations do. The patch was sent by + * Bjorn Gronvall + */ +static unsigned const char con_salt[128]={ +0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9, +0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1, +0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9, +0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1, +0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9, +0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01, +0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, +0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A, +0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12, +0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A, +0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22, +0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24, +0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C, +0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34, +0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C, +0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44, +}; + +static unsigned const char cov_2char[64]={ +0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35, +0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44, +0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C, +0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54, +0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62, +0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A, +0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72, +0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A +}; + +#ifndef NOPROTO +void fcrypt_body(DES_LONG *out,des_key_schedule ks, + DES_LONG Eswap0, DES_LONG Eswap1); + +#ifdef PERL5 +char *des_crypt(const char *buf,const char *salt); +#else +char *crypt(const char *buf,const char *salt); +#endif +#else +void fcrypt_body(); +#ifdef PERL5 +char *des_crypt(); +#else +char *crypt(); +#endif +#endif + +#ifdef PERL5 +char *des_crypt(buf,salt) +#else +char *crypt(buf,salt) +#endif +const char *buf; +const char *salt; + { + static char buff[14]; + + return(des_fcrypt(buf,salt,buff)); + } + + +char *des_fcrypt(buf,salt,ret) +const char *buf; +const char *salt; +char *ret; + { + unsigned int i,j,x,y; + DES_LONG Eswap0,Eswap1; + DES_LONG out[2],ll; + des_cblock key; + des_key_schedule ks; + unsigned char bb[9]; + unsigned char *b=bb; + unsigned char c,u; + + /* eay 25/08/92 + * If you call crypt("pwd","*") as often happens when you + * have * as the pwd field in /etc/passwd, the function + * returns *\0XXXXXXXXX + * The \0 makes the string look like * so the pwd "*" would + * crypt to "*". This was found when replacing the crypt in + * our shared libraries. People found that the disbled + * accounts effectivly had no passwd :-(. */ + x=ret[0]=((salt[0] == '\0')?'A':salt[0]); + Eswap0=con_salt[x]<<2; + x=ret[1]=((salt[1] == '\0')?'A':salt[1]); + Eswap1=con_salt[x]<<6; + +/* EAY +r=strlen(buf); +r=(r+7)/8; +*/ + for (i=0; i<8; i++) + { + c= *(buf++); + if (!c) break; + key[i]=(c<<1); + } + for (; i<8; i++) + key[i]=0; + + des_set_key((des_cblock *)(key),ks); + fcrypt_body(&(out[0]),ks,Eswap0,Eswap1); + + ll=out[0]; l2c(ll,b); + ll=out[1]; l2c(ll,b); + y=0; + u=0x80; + bb[8]=0; + for (i=2; i<13; i++) + { + c=0; + for (j=0; j<6; j++) + { + c<<=1; + if (bb[y] & u) c|=1; + u>>=1; + if (!u) + { + y++; + u=0x80; + } + } + ret[i]=cov_2char[c]; + } + ret[13]='\0'; + return(ret); + } + diff -urN linux-2.4.29/net/ipsec/libdes/fcrypt_b.c linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/fcrypt_b.c --- linux-2.4.29/net/ipsec/libdes/fcrypt_b.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/fcrypt_b.c Thu Sep 5 05:13:20 2002 @@ -0,0 +1,148 @@ +/* crypto/des/fcrypt_b.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* #include */ + +/* This version of crypt has been developed from my MIT compatable + * DES library. + * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au + * Eric Young (eay@cryptsoft.com) + */ + +#define DES_FCRYPT +#include "des_locl.h" +#undef DES_FCRYPT + +#undef PERM_OP +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ + (b)^=(t),\ + (a)^=((t)<<(n))) + +#undef HPERM_OP +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ + (a)=(a)^(t)^(t>>(16-(n))))\ + +void fcrypt_body(out, ks, Eswap0, Eswap1) +DES_LONG *out; +des_key_schedule ks; +DES_LONG Eswap0; +DES_LONG Eswap1; + { + register DES_LONG l,r,t,u; +#ifdef DES_PTR + register unsigned char *des_SP=(unsigned char *)des_SPtrans; +#endif + register DES_LONG *s; + register int j; + register DES_LONG E0,E1; + + l=0; + r=0; + + s=(DES_LONG *)ks; + E0=Eswap0; + E1=Eswap1; + + for (j=0; j<25; j++) + { +#ifdef DES_UNROLL + register int i; + + for (i=0; i<32; i+=8) + { + D_ENCRYPT(l,r,i+0); /* 1 */ + D_ENCRYPT(r,l,i+2); /* 2 */ + D_ENCRYPT(l,r,i+4); /* 1 */ + D_ENCRYPT(r,l,i+6); /* 2 */ + } +#else + D_ENCRYPT(l,r, 0); /* 1 */ + D_ENCRYPT(r,l, 2); /* 2 */ + D_ENCRYPT(l,r, 4); /* 3 */ + D_ENCRYPT(r,l, 6); /* 4 */ + D_ENCRYPT(l,r, 8); /* 5 */ + D_ENCRYPT(r,l,10); /* 6 */ + D_ENCRYPT(l,r,12); /* 7 */ + D_ENCRYPT(r,l,14); /* 8 */ + D_ENCRYPT(l,r,16); /* 9 */ + D_ENCRYPT(r,l,18); /* 10 */ + D_ENCRYPT(l,r,20); /* 11 */ + D_ENCRYPT(r,l,22); /* 12 */ + D_ENCRYPT(l,r,24); /* 13 */ + D_ENCRYPT(r,l,26); /* 14 */ + D_ENCRYPT(l,r,28); /* 15 */ + D_ENCRYPT(r,l,30); /* 16 */ +#endif + + t=l; + l=r; + r=t; + } + l=ROTATE(l,3)&0xffffffffL; + r=ROTATE(r,3)&0xffffffffL; + + PERM_OP(l,r,t, 1,0x55555555L); + PERM_OP(r,l,t, 8,0x00ff00ffL); + PERM_OP(l,r,t, 2,0x33333333L); + PERM_OP(r,l,t,16,0x0000ffffL); + PERM_OP(l,r,t, 4,0x0f0f0f0fL); + + out[0]=r; + out[1]=l; + } + diff -urN linux-2.4.29/net/ipsec/libdes/podd.h linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/podd.h --- linux-2.4.29/net/ipsec/libdes/podd.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/podd.h Thu Sep 5 05:13:20 2002 @@ -0,0 +1,75 @@ +/* crypto/des/podd.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +static const unsigned char odd_parity[256]={ + 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, + 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, + 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, + 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, + 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, + 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, + 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110, +112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127, +128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143, +145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158, +161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174, +176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191, +193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206, +208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223, +224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239, +241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254}; diff -urN linux-2.4.29/net/ipsec/libdes/set_key.c linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/set_key.c --- linux-2.4.29/net/ipsec/libdes/set_key.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/set_key.c Thu Sep 5 05:13:20 2002 @@ -0,0 +1,246 @@ +/* crypto/des/set_key.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* set_key.c v 1.4 eay 24/9/91 + * 1.4 Speed up by 400% :-) + * 1.3 added register declarations. + * 1.2 unrolled make_key_sched a bit more + * 1.1 added norm_expand_bits + * 1.0 First working version + */ +#include "des_locl.h" +#include "podd.h" +#include "sk.h" + +#ifndef NOPROTO +static int check_parity(des_cblock (*key)); +#else +static int check_parity(); +#endif + +int des_check_key=0; + +void des_set_odd_parity(key) +des_cblock (*key); + { + int i; + + for (i=0; i>(n))^(b))&(m)),\ + * (b)^=(t),\ + * (a)=((a)^((t)<<(n)))) + */ + +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ + (a)=(a)^(t)^(t>>(16-(n)))) + +/* return 0 if key parity is odd (correct), + * return -1 if key parity error, + * return -2 if illegal weak key. + */ +int des_set_key(key, schedule) +des_cblock (*key); +des_key_schedule schedule; + { + static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0}; + register DES_LONG c,d,t,s,t2; + register unsigned char *in; + register DES_LONG *k; + register int i; + + if (des_check_key) + { + if (!check_parity(key)) + return(-1); + + if (des_is_weak_key(key)) + return(-2); + } + + k=(DES_LONG *)schedule; + in=(unsigned char *)key; + + c2l(in,c); + c2l(in,d); + + /* do PC1 in 60 simple operations */ +/* PERM_OP(d,c,t,4,0x0f0f0f0fL); + HPERM_OP(c,t,-2, 0xcccc0000L); + HPERM_OP(c,t,-1, 0xaaaa0000L); + HPERM_OP(c,t, 8, 0x00ff0000L); + HPERM_OP(c,t,-1, 0xaaaa0000L); + HPERM_OP(d,t,-8, 0xff000000L); + HPERM_OP(d,t, 8, 0x00ff0000L); + HPERM_OP(d,t, 2, 0x33330000L); + d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L); + d=(d>>8)|((c&0xf0000000L)>>4); + c&=0x0fffffffL; */ + + /* I now do it in 47 simple operations :-) + * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) + * for the inspiration. :-) */ + PERM_OP (d,c,t,4,0x0f0f0f0fL); + HPERM_OP(c,t,-2,0xcccc0000L); + HPERM_OP(d,t,-2,0xcccc0000L); + PERM_OP (d,c,t,1,0x55555555L); + PERM_OP (c,d,t,8,0x00ff00ffL); + PERM_OP (d,c,t,1,0x55555555L); + d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) | + ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L)); + c&=0x0fffffffL; + + for (i=0; i>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); } + else + { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); } + c&=0x0fffffffL; + d&=0x0fffffffL; + /* could be a few less shifts but I am to lazy at this + * point in time to investigate */ + s= des_skb[0][ (c )&0x3f ]| + des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]| + des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]| + des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) | + ((c>>22L)&0x38)]; + t= des_skb[4][ (d )&0x3f ]| + des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]| + des_skb[6][ (d>>15L)&0x3f ]| + des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)]; + + /* table contained 0213 4657 */ + t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL; + *(k++)=ROTATE(t2,30)&0xffffffffL; + + t2=((s>>16L)|(t&0xffff0000L)); + *(k++)=ROTATE(t2,26)&0xffffffffL; + } + return(0); + } + +int des_key_sched(key, schedule) +des_cblock (*key); +des_key_schedule schedule; + { + return(des_set_key(key,schedule)); + } diff -urN linux-2.4.29/net/ipsec/libdes/sk.h linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/sk.h --- linux-2.4.29/net/ipsec/libdes/sk.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/sk.h Thu Sep 5 05:13:20 2002 @@ -0,0 +1,204 @@ +/* crypto/des/sk.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +static const DES_LONG des_skb[8][64]={ +{ +/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ +0x00000000L,0x00000010L,0x20000000L,0x20000010L, +0x00010000L,0x00010010L,0x20010000L,0x20010010L, +0x00000800L,0x00000810L,0x20000800L,0x20000810L, +0x00010800L,0x00010810L,0x20010800L,0x20010810L, +0x00000020L,0x00000030L,0x20000020L,0x20000030L, +0x00010020L,0x00010030L,0x20010020L,0x20010030L, +0x00000820L,0x00000830L,0x20000820L,0x20000830L, +0x00010820L,0x00010830L,0x20010820L,0x20010830L, +0x00080000L,0x00080010L,0x20080000L,0x20080010L, +0x00090000L,0x00090010L,0x20090000L,0x20090010L, +0x00080800L,0x00080810L,0x20080800L,0x20080810L, +0x00090800L,0x00090810L,0x20090800L,0x20090810L, +0x00080020L,0x00080030L,0x20080020L,0x20080030L, +0x00090020L,0x00090030L,0x20090020L,0x20090030L, +0x00080820L,0x00080830L,0x20080820L,0x20080830L, +0x00090820L,0x00090830L,0x20090820L,0x20090830L, +},{ +/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ +0x00000000L,0x02000000L,0x00002000L,0x02002000L, +0x00200000L,0x02200000L,0x00202000L,0x02202000L, +0x00000004L,0x02000004L,0x00002004L,0x02002004L, +0x00200004L,0x02200004L,0x00202004L,0x02202004L, +0x00000400L,0x02000400L,0x00002400L,0x02002400L, +0x00200400L,0x02200400L,0x00202400L,0x02202400L, +0x00000404L,0x02000404L,0x00002404L,0x02002404L, +0x00200404L,0x02200404L,0x00202404L,0x02202404L, +0x10000000L,0x12000000L,0x10002000L,0x12002000L, +0x10200000L,0x12200000L,0x10202000L,0x12202000L, +0x10000004L,0x12000004L,0x10002004L,0x12002004L, +0x10200004L,0x12200004L,0x10202004L,0x12202004L, +0x10000400L,0x12000400L,0x10002400L,0x12002400L, +0x10200400L,0x12200400L,0x10202400L,0x12202400L, +0x10000404L,0x12000404L,0x10002404L,0x12002404L, +0x10200404L,0x12200404L,0x10202404L,0x12202404L, +},{ +/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ +0x00000000L,0x00000001L,0x00040000L,0x00040001L, +0x01000000L,0x01000001L,0x01040000L,0x01040001L, +0x00000002L,0x00000003L,0x00040002L,0x00040003L, +0x01000002L,0x01000003L,0x01040002L,0x01040003L, +0x00000200L,0x00000201L,0x00040200L,0x00040201L, +0x01000200L,0x01000201L,0x01040200L,0x01040201L, +0x00000202L,0x00000203L,0x00040202L,0x00040203L, +0x01000202L,0x01000203L,0x01040202L,0x01040203L, +0x08000000L,0x08000001L,0x08040000L,0x08040001L, +0x09000000L,0x09000001L,0x09040000L,0x09040001L, +0x08000002L,0x08000003L,0x08040002L,0x08040003L, +0x09000002L,0x09000003L,0x09040002L,0x09040003L, +0x08000200L,0x08000201L,0x08040200L,0x08040201L, +0x09000200L,0x09000201L,0x09040200L,0x09040201L, +0x08000202L,0x08000203L,0x08040202L,0x08040203L, +0x09000202L,0x09000203L,0x09040202L,0x09040203L, +},{ +/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ +0x00000000L,0x00100000L,0x00000100L,0x00100100L, +0x00000008L,0x00100008L,0x00000108L,0x00100108L, +0x00001000L,0x00101000L,0x00001100L,0x00101100L, +0x00001008L,0x00101008L,0x00001108L,0x00101108L, +0x04000000L,0x04100000L,0x04000100L,0x04100100L, +0x04000008L,0x04100008L,0x04000108L,0x04100108L, +0x04001000L,0x04101000L,0x04001100L,0x04101100L, +0x04001008L,0x04101008L,0x04001108L,0x04101108L, +0x00020000L,0x00120000L,0x00020100L,0x00120100L, +0x00020008L,0x00120008L,0x00020108L,0x00120108L, +0x00021000L,0x00121000L,0x00021100L,0x00121100L, +0x00021008L,0x00121008L,0x00021108L,0x00121108L, +0x04020000L,0x04120000L,0x04020100L,0x04120100L, +0x04020008L,0x04120008L,0x04020108L,0x04120108L, +0x04021000L,0x04121000L,0x04021100L,0x04121100L, +0x04021008L,0x04121008L,0x04021108L,0x04121108L, +},{ +/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ +0x00000000L,0x10000000L,0x00010000L,0x10010000L, +0x00000004L,0x10000004L,0x00010004L,0x10010004L, +0x20000000L,0x30000000L,0x20010000L,0x30010000L, +0x20000004L,0x30000004L,0x20010004L,0x30010004L, +0x00100000L,0x10100000L,0x00110000L,0x10110000L, +0x00100004L,0x10100004L,0x00110004L,0x10110004L, +0x20100000L,0x30100000L,0x20110000L,0x30110000L, +0x20100004L,0x30100004L,0x20110004L,0x30110004L, +0x00001000L,0x10001000L,0x00011000L,0x10011000L, +0x00001004L,0x10001004L,0x00011004L,0x10011004L, +0x20001000L,0x30001000L,0x20011000L,0x30011000L, +0x20001004L,0x30001004L,0x20011004L,0x30011004L, +0x00101000L,0x10101000L,0x00111000L,0x10111000L, +0x00101004L,0x10101004L,0x00111004L,0x10111004L, +0x20101000L,0x30101000L,0x20111000L,0x30111000L, +0x20101004L,0x30101004L,0x20111004L,0x30111004L, +},{ +/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ +0x00000000L,0x08000000L,0x00000008L,0x08000008L, +0x00000400L,0x08000400L,0x00000408L,0x08000408L, +0x00020000L,0x08020000L,0x00020008L,0x08020008L, +0x00020400L,0x08020400L,0x00020408L,0x08020408L, +0x00000001L,0x08000001L,0x00000009L,0x08000009L, +0x00000401L,0x08000401L,0x00000409L,0x08000409L, +0x00020001L,0x08020001L,0x00020009L,0x08020009L, +0x00020401L,0x08020401L,0x00020409L,0x08020409L, +0x02000000L,0x0A000000L,0x02000008L,0x0A000008L, +0x02000400L,0x0A000400L,0x02000408L,0x0A000408L, +0x02020000L,0x0A020000L,0x02020008L,0x0A020008L, +0x02020400L,0x0A020400L,0x02020408L,0x0A020408L, +0x02000001L,0x0A000001L,0x02000009L,0x0A000009L, +0x02000401L,0x0A000401L,0x02000409L,0x0A000409L, +0x02020001L,0x0A020001L,0x02020009L,0x0A020009L, +0x02020401L,0x0A020401L,0x02020409L,0x0A020409L, +},{ +/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ +0x00000000L,0x00000100L,0x00080000L,0x00080100L, +0x01000000L,0x01000100L,0x01080000L,0x01080100L, +0x00000010L,0x00000110L,0x00080010L,0x00080110L, +0x01000010L,0x01000110L,0x01080010L,0x01080110L, +0x00200000L,0x00200100L,0x00280000L,0x00280100L, +0x01200000L,0x01200100L,0x01280000L,0x01280100L, +0x00200010L,0x00200110L,0x00280010L,0x00280110L, +0x01200010L,0x01200110L,0x01280010L,0x01280110L, +0x00000200L,0x00000300L,0x00080200L,0x00080300L, +0x01000200L,0x01000300L,0x01080200L,0x01080300L, +0x00000210L,0x00000310L,0x00080210L,0x00080310L, +0x01000210L,0x01000310L,0x01080210L,0x01080310L, +0x00200200L,0x00200300L,0x00280200L,0x00280300L, +0x01200200L,0x01200300L,0x01280200L,0x01280300L, +0x00200210L,0x00200310L,0x00280210L,0x00280310L, +0x01200210L,0x01200310L,0x01280210L,0x01280310L, +},{ +/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ +0x00000000L,0x04000000L,0x00040000L,0x04040000L, +0x00000002L,0x04000002L,0x00040002L,0x04040002L, +0x00002000L,0x04002000L,0x00042000L,0x04042000L, +0x00002002L,0x04002002L,0x00042002L,0x04042002L, +0x00000020L,0x04000020L,0x00040020L,0x04040020L, +0x00000022L,0x04000022L,0x00040022L,0x04040022L, +0x00002020L,0x04002020L,0x00042020L,0x04042020L, +0x00002022L,0x04002022L,0x00042022L,0x04042022L, +0x00000800L,0x04000800L,0x00040800L,0x04040800L, +0x00000802L,0x04000802L,0x00040802L,0x04040802L, +0x00002800L,0x04002800L,0x00042800L,0x04042800L, +0x00002802L,0x04002802L,0x00042802L,0x04042802L, +0x00000820L,0x04000820L,0x00040820L,0x04040820L, +0x00000822L,0x04000822L,0x00040822L,0x04040822L, +0x00002820L,0x04002820L,0x00042820L,0x04042820L, +0x00002822L,0x04002822L,0x00042822L,0x04042822L, +}}; diff -urN linux-2.4.29/net/ipsec/libdes/speed.c linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/speed.c --- linux-2.4.29/net/ipsec/libdes/speed.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/speed.c Thu Sep 5 05:13:20 2002 @@ -0,0 +1,329 @@ +/* crypto/des/speed.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ + +#ifndef MSDOS +#define TIMES +#endif + +#include +#ifndef MSDOS +#include +#else +#include +extern int exit(); +#endif +#include +#ifndef VMS +#ifndef _IRIX +#include +#endif +#ifdef TIMES +#include +#include +#endif +#else /* VMS */ +#include +struct tms { + time_t tms_utime; + time_t tms_stime; + time_t tms_uchild; /* I dunno... */ + time_t tms_uchildsys; /* so these names are a guess :-) */ + } +#endif +#ifndef TIMES +#include +#endif + +#ifdef sun +#include +#include +#endif + +#include "des.h" + +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ +# ifndef VMS +# define HZ 100.0 +# else /* VMS */ +# define HZ 100.0 +# endif +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif + +#define BUFSIZE ((long)1024) +long run=0; + +#ifndef NOPROTO +double Time_F(int s); +#else +double Time_F(); +#endif + +#ifdef SIGALRM +#if defined(__STDC__) || defined(sgi) || defined(_AIX) +#define SIGRETTYPE void +#else +#define SIGRETTYPE int +#endif + +#ifndef NOPROTO +SIGRETTYPE sig_done(int sig); +#else +SIGRETTYPE sig_done(); +#endif + +SIGRETTYPE sig_done(sig) +int sig; + { + signal(SIGALRM,sig_done); + run=0; +#ifdef LINT + sig=sig; +#endif + } +#endif + +#define START 0 +#define STOP 1 + +double Time_F(s) +int s; + { + double ret; +#ifdef TIMES + static struct tms tstart,tend; + + if (s == START) + { + times(&tstart); + return(0); + } + else + { + times(&tend); + ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ; + return((ret == 0.0)?1e-6:ret); + } +#else /* !times() */ + static struct timeb tstart,tend; + long i; + + if (s == START) + { + ftime(&tstart); + return(0); + } + else + { + ftime(&tend); + i=(long)tend.millitm-(long)tstart.millitm; + ret=((double)(tend.time-tstart.time))+((double)i)/1e3; + return((ret == 0.0)?1e-6:ret); + } +#endif + } + +int main(argc,argv) +int argc; +char **argv; + { + long count; + static unsigned char buf[BUFSIZE]; + static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; + static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12}; + static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34}; + des_key_schedule sch,sch2,sch3; + double a,b,c,d,e; +#ifndef SIGALRM + long ca,cb,cc,cd,ce; +#endif + +#ifndef TIMES + printf("To get the most acurate results, try to run this\n"); + printf("program when this computer is idle.\n"); +#endif + + des_set_key((C_Block *)key2,sch2); + des_set_key((C_Block *)key3,sch3); + +#ifndef SIGALRM + printf("First we calculate the approximate speed ...\n"); + des_set_key((C_Block *)key,sch); + count=10; + do { + long i; + DES_LONG data[2]; + + count*=2; + Time_F(START); + for (i=count; i; i--) + des_encrypt(data,&(sch[0]),DES_ENCRYPT); + d=Time_F(STOP); + } while (d < 3.0); + ca=count; + cb=count*3; + cc=count*3*8/BUFSIZE+1; + cd=count*8/BUFSIZE+1; + ce=count/20+1; + printf("Doing set_key %ld times\n",ca); +#define COND(d) (count != (d)) +#define COUNT(d) (d) +#else +#define COND(c) (run) +#define COUNT(d) (count) + signal(SIGALRM,sig_done); + printf("Doing set_key for 10 seconds\n"); + alarm(10); +#endif + + Time_F(START); + for (count=0,run=1; COND(ca); count++) + des_set_key((C_Block *)key,sch); + d=Time_F(STOP); + printf("%ld set_key's in %.2f seconds\n",count,d); + a=((double)COUNT(ca))/d; + +#ifdef SIGALRM + printf("Doing des_encrypt's for 10 seconds\n"); + alarm(10); +#else + printf("Doing des_encrypt %ld times\n",cb); +#endif + Time_F(START); + for (count=0,run=1; COND(cb); count++) + { + DES_LONG data[2]; + + des_encrypt(data,&(sch[0]),DES_ENCRYPT); + } + d=Time_F(STOP); + printf("%ld des_encrypt's in %.2f second\n",count,d); + b=((double)COUNT(cb)*8)/d; + +#ifdef SIGALRM + printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n", + BUFSIZE); + alarm(10); +#else + printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc, + BUFSIZE); +#endif + Time_F(START); + for (count=0,run=1; COND(cc); count++) + des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]), + (C_Block *)&(key[0]),DES_ENCRYPT); + d=Time_F(STOP); + printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n", + count,BUFSIZE,d); + c=((double)COUNT(cc)*BUFSIZE)/d; + +#ifdef SIGALRM + printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n", + BUFSIZE); + alarm(10); +#else + printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd, + BUFSIZE); +#endif + Time_F(START); + for (count=0,run=1; COND(cd); count++) + des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE, + &(sch[0]), + &(sch2[0]), + &(sch3[0]), + (C_Block *)&(key[0]), + DES_ENCRYPT); + d=Time_F(STOP); + printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n", + count,BUFSIZE,d); + d=((double)COUNT(cd)*BUFSIZE)/d; + +#ifdef SIGALRM + printf("Doing crypt for 10 seconds\n"); + alarm(10); +#else + printf("Doing crypt %ld times\n",ce); +#endif + Time_F(START); + for (count=0,run=1; COND(ce); count++) + crypt("testing1","ef"); + e=Time_F(STOP); + printf("%ld crypts in %.2f second\n",count,e); + e=((double)COUNT(ce))/e; + + printf("set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a); + printf("DES raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b); + printf("DES cbc bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c); + printf("DES ede cbc bytes per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d); + printf("crypt per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e); + exit(0); +#if defined(LINT) || defined(MSDOS) + return(0); +#endif + } diff -urN linux-2.4.29/net/ipsec/libdes/spr.h linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/spr.h --- linux-2.4.29/net/ipsec/libdes/spr.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libdes/spr.h Thu Sep 5 05:13:20 2002 @@ -0,0 +1,204 @@ +/* crypto/des/spr.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +const DES_LONG des_SPtrans[8][64]={ +{ +/* nibble 0 */ +0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, +0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, +0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, +0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, +0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, +0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, +0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, +0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, +0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, +0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, +0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, +0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, +0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, +0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, +0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, +0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, +},{ +/* nibble 1 */ +0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, +0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, +0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, +0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, +0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, +0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, +0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, +0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, +0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, +0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, +0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, +0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, +0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, +0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, +0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, +0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, +},{ +/* nibble 2 */ +0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, +0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, +0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, +0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, +0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, +0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, +0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, +0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, +0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, +0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, +0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, +0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, +0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, +0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, +0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, +0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, +},{ +/* nibble 3 */ +0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, +0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, +0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, +0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, +0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, +0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, +0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, +0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, +0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, +0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, +0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, +0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, +0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, +0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, +0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, +0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, +},{ +/* nibble 4 */ +0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, +0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, +0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, +0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, +0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, +0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, +0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, +0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, +0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, +0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, +0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, +0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, +0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, +0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, +0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, +0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, +},{ +/* nibble 5 */ +0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, +0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, +0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, +0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, +0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, +0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, +0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, +0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, +0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, +0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, +0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, +0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, +0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, +0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, +0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, +0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, +},{ +/* nibble 6 */ +0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, +0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, +0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, +0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, +0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, +0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, +0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, +0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, +0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, +0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, +0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, +0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, +0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, +0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, +0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, +0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, +},{ +/* nibble 7 */ +0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, +0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, +0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, +0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, +0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, +0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, +0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, +0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, +0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, +0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, +0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, +0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, +0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, +0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, +0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, +0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, +}}; diff -urN linux-2.4.29/net/ipsec/libopenswan/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/Makefile --- linux-2.4.29/net/ipsec/libopenswan/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/Makefile Wed Nov 19 03:29:45 2003 @@ -0,0 +1,65 @@ +# FreeS/WAN library +# Copyright (C) 1998-2002 Henry Spencer. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See . +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# RCSID $Id: Makefile.kernel,v 1.2 2003/11/19 02:29:45 mcr Exp $ + + + +include ../Makefile.inc +include ../Makefile.ver + + + +ifndef TOPDIR +TOPDIR := /usr/src/linux +endif + +L_TARGET := libkernel.a + +obj-y := addrtoa.o datatot.o goodmask.o \ + pfkey_v2_build.o pfkey_v2_debug.o pfkey_v2_ext_bits.o pfkey_v2_parse.o \ + prng.o rangetoa.o satoa.o \ + subnetof.o subnettoa.o ultoa.o version.o + +HDRS=openswan.h internal.h + +EXTRA_CFLAGS += -I. $(KLIPSCOMPILE) + +EXTRA_CFLAGS += -Wall +#EXTRA_CFLAGS += -Wconversion +#EXTRA_CFLAGS += -Wmissing-prototypes +EXTRA_CFLAGS += -Wpointer-arith +#EXTRA_CFLAGS += -Wcast-qual +#EXTRA_CFLAGS += -Wmissing-declarations +EXTRA_CFLAGS += -Wstrict-prototypes +#EXTRA_CFLAGS += -pedantic +#EXTRA_CFLAGS += -W +#EXTRA_CFLAGS += -Wwrite-strings +#EXTRA_CFLAGS += -Wbad-function-cast + +active-objs := $(sort $(obj-y) $(obj-m)) +L_OBJS := $(obj-y) +M_OBJS := $(obj-m) +MIX_OBJS := $(filter $(export-objs), $(active-objs)) + +include $(TOPDIR)/Rules.make + +$(obj-y): $(HDRS) + +# build version.c using version number from Makefile.ver +version.c: version.in.c + sed '/"/s/xxx/$(IPSECVERSION)/' version.in.c >$@ + +clean: + rm -f $(L_TARGET) *.o try* core *.core version.c + ( cd des && $(MAKE) clean ) diff -urN linux-2.4.29/net/ipsec/libopenswan/addrtoa.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/addrtoa.c --- linux-2.4.29/net/ipsec/libopenswan/addrtoa.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/addrtoa.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,68 @@ +/* + * addresses to ASCII + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: addrtoa.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +#define NBYTES 4 /* bytes in an address */ +#define PERBYTE 4 /* three digits plus a dot or NUL */ +#define BUFLEN (NBYTES*PERBYTE) + +#if BUFLEN != ADDRTOA_BUF +#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code" +#endif + +/* + - addrtoa - convert binary address to ASCII dotted decimal + */ +size_t /* space needed for full conversion */ +addrtoa(addr, format, dst, dstlen) +struct in_addr addr; +int format; /* character */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + unsigned long a = ntohl(addr.s_addr); + int i; + size_t n; + unsigned long byte; + char buf[BUFLEN]; + char *p; + + switch (format) { + case 0: + break; + default: + return 0; + break; + } + + p = buf; + for (i = NBYTES-1; i >= 0; i--) { + byte = (a >> (i*8)) & 0xff; + p += ultoa(byte, 10, p, PERBYTE); + if (i != 0) + *(p-1) = '.'; + } + n = p - buf; + + if (dstlen > 0) { + if (n > dstlen) + buf[dstlen - 1] = '\0'; + strcpy(dst, buf); + } + return n; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/addrtot.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/addrtot.c --- linux-2.4.29/net/ipsec/libopenswan/addrtot.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/addrtot.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,230 @@ +/* + * addresses to text + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: addrtot.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +#define IP4BYTES 4 /* bytes in an IPv4 address */ +#define PERBYTE 4 /* three digits plus a dot or NUL */ +#define IP6BYTES 16 /* bytes in an IPv6 address */ + +/* forwards */ +static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp); +static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp); +static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp); +static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp); +static size_t reverse62(const unsigned char *s, size_t len, char *b, char **dp); + +/* + - addrtot - convert binary address to text (dotted decimal or IPv6 string) + */ +size_t /* space needed for full conversion */ +addrtot(src, format, dst, dstlen) +const ip_address *src; +int format; /* character */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + const unsigned char *b; + size_t n; + char buf[1+ADDRTOT_BUF+1]; /* :address: */ + char *p; + int t = addrtypeof(src); +# define TF(t, f) (((t)<<8) | (f)) + + n = addrbytesptr(src, &b); + if (n == 0) + return 0; + + switch (TF(t, format)) { + case TF(AF_INET, 0): + n = normal4(b, n, buf, &p); + break; + case TF(AF_INET6, 0): + n = normal6(b, n, buf, &p); + break; + case TF(AF_INET, 'r'): + n = reverse4(b, n, buf, &p); + break; + case TF(AF_INET6, 'r'): + n = reverse6(b, n, buf, &p); + break; + case TF(AF_INET6, 'R'): + n = reverse62(b, n, buf, &p); + break; + default: /* including (AF_INET, 'R') */ + return 0; + break; + } + + if (dstlen > 0) { + if (dstlen < n) + p[dstlen - 1] = '\0'; + strcpy(dst, p); + } + return n; +} + +/* + - normal4 - normal IPv4 address-text conversion + */ +static size_t /* size of text, including NUL */ +normal4(srcp, srclen, buf, dstp) +const unsigned char *srcp; +size_t srclen; +char *buf; /* guaranteed large enough */ +char **dstp; /* where to put result pointer */ +{ + int i; + char *p; + + if (srclen != IP4BYTES) /* "can't happen" */ + return 0; + p = buf; + for (i = 0; i < IP4BYTES; i++) { + p += ultot(srcp[i], 10, p, PERBYTE); + if (i != IP4BYTES - 1) + *(p-1) = '.'; /* overwrites the NUL */ + } + *dstp = buf; + return p - buf; +} + +/* + - normal6 - normal IPv6 address-text conversion + */ +static size_t /* size of text, including NUL */ +normal6(srcp, srclen, buf, dstp) +const unsigned char *srcp; +size_t srclen; +char *buf; /* guaranteed large enough, plus 2 */ +char **dstp; /* where to put result pointer */ +{ + int i; + unsigned long piece; + char *p; + char *q; + + if (srclen != IP6BYTES) /* "can't happen" */ + return 0; + p = buf; + *p++ = ':'; + for (i = 0; i < IP6BYTES/2; i++) { + piece = (srcp[2*i] << 8) + srcp[2*i + 1]; + p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */ + *(p-1) = ':'; /* overwrites the NUL */ + } + *p = '\0'; + q = strstr(buf, ":0:0:"); + if (q != NULL) { /* zero squishing is possible */ + p = q + 1; + while (*p == '0' && *(p+1) == ':') + p += 2; + q++; + *q++ = ':'; /* overwrite first 0 */ + while (*p != '\0') + *q++ = *p++; + *q = '\0'; + if (!(*(q-1) == ':' && *(q-2) == ':')) + *--q = '\0'; /* strip final : unless :: */ + p = buf; + if (!(*p == ':' && *(p+1) == ':')) + p++; /* skip initial : unless :: */ + } else { + q = p; + *--q = '\0'; /* strip final : */ + p = buf + 1; /* skip initial : */ + } + *dstp = p; + return q - p + 1; +} + +/* + - reverse4 - IPv4 reverse-lookup conversion + */ +static size_t /* size of text, including NUL */ +reverse4(srcp, srclen, buf, dstp) +const unsigned char *srcp; +size_t srclen; +char *buf; /* guaranteed large enough */ +char **dstp; /* where to put result pointer */ +{ + int i; + char *p; + + if (srclen != IP4BYTES) /* "can't happen" */ + return 0; + p = buf; + for (i = IP4BYTES-1; i >= 0; i--) { + p += ultot(srcp[i], 10, p, PERBYTE); + *(p-1) = '.'; /* overwrites the NUL */ + } + strcpy(p, "IN-ADDR.ARPA."); + *dstp = buf; + return strlen(buf) + 1; +} + +/* + - reverse62 - obsolete IPv6 reverse-lookup conversion (RFC 1886) + * A trifle inefficient, really shouldn't use ultot... + */ +static size_t /* size of text, including NUL */ +reverse62(srcp, srclen, buf, dstp) +const unsigned char *srcp; +size_t srclen; +char *buf; /* guaranteed large enough */ +char **dstp; /* where to put result pointer */ +{ + int i; + unsigned long piece; + char *p; + + if (srclen != IP6BYTES) /* "can't happen" */ + return 0; + p = buf; + for (i = IP6BYTES-1; i >= 0; i--) { + piece = srcp[i]; + p += ultot(piece&0xf, 16, p, 2); + *(p-1) = '.'; + p += ultot(piece>>4, 16, p, 2); + *(p-1) = '.'; + } + strcpy(p, "IP6.INT."); + *dstp = buf; + return strlen(buf) + 1; +} + +/* + - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874) + */ +static size_t /* size of text, including NUL */ +reverse6(srcp, srclen, buf, dstp) +const unsigned char *srcp; +size_t srclen; +char *buf; /* guaranteed large enough */ +char **dstp; /* where to put result pointer */ +{ + char *p; + + if (srclen != IP6BYTES) /* "can't happen" */ + return 0; + strcpy(buf, "\\[x"); + p = buf + strlen(buf); + (void) datatot((const char *)srcp, srclen, 16, p, IP6BYTES*2 + 1); + strcat(buf, "].IP6.ARPA."); /* leave count implicit */ + *dstp = buf; + return strlen(buf) + 1; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/addrtypeof.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/addrtypeof.c --- linux-2.4.29/net/ipsec/libopenswan/addrtypeof.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/addrtypeof.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,94 @@ +/* + * extract parts of an ip_address + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: addrtypeof.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - addrtypeof - get the type of an ip_address + */ +int +addrtypeof(src) +const ip_address *src; +{ + return src->u.v4.sin_family; +} + +/* + - addrbytesptr - get pointer to the address bytes of an ip_address + */ +size_t /* 0 for error */ +addrbytesptr(src, dstp) +const ip_address *src; +const unsigned char **dstp; /* NULL means just a size query */ +{ + const unsigned char *p; + size_t n; + + switch (src->u.v4.sin_family) { + case AF_INET: + p = (const unsigned char *)&src->u.v4.sin_addr.s_addr; + n = 4; + break; + case AF_INET6: + p = (const unsigned char *)&src->u.v6.sin6_addr; + n = 16; + break; + default: + return 0; + break; + } + + if (dstp != NULL) + *dstp = p; + return n; +} + +/* + - addrlenof - get length of the address bytes of an ip_address + */ +size_t /* 0 for error */ +addrlenof(src) +const ip_address *src; +{ + return addrbytesptr(src, NULL); +} + +/* + - addrbytesof - get the address bytes of an ip_address + */ +size_t /* 0 for error */ +addrbytesof(src, dst, dstlen) +const ip_address *src; +unsigned char *dst; +size_t dstlen; +{ + const unsigned char *p; + size_t n; + size_t ncopy; + + n = addrbytesptr(src, &p); + if (n == 0) + return 0; + + if (dstlen > 0) { + ncopy = n; + if (ncopy > dstlen) + ncopy = dstlen; + memcpy(dst, p, ncopy); + } + return n; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/anyaddr.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/anyaddr.c --- linux-2.4.29/net/ipsec/libopenswan/anyaddr.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/anyaddr.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,146 @@ +/* + * special addresses + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: anyaddr.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* these are mostly fallbacks for the no-IPv6-support-in-library case */ +#ifndef IN6ADDR_ANY_INIT +#define IN6ADDR_ANY_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }} +#endif +#ifndef IN6ADDR_LOOPBACK_INIT +#define IN6ADDR_LOOPBACK_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }} +#endif + +static struct in6_addr v6any = IN6ADDR_ANY_INIT; +static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT; + +/* + - anyaddr - initialize to the any-address value + */ +err_t /* NULL for success, else string literal */ +anyaddr(af, dst) +int af; /* address family */ +ip_address *dst; +{ + uint32_t v4any = htonl(INADDR_ANY); + + switch (af) { + case AF_INET: + return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst); + break; + case AF_INET6: + return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst); + break; + default: + return "unknown address family in anyaddr/unspecaddr"; + break; + } +} + +/* + - unspecaddr - initialize to the unspecified-address value + */ +err_t /* NULL for success, else string literal */ +unspecaddr(af, dst) +int af; /* address family */ +ip_address *dst; +{ + return anyaddr(af, dst); +} + +/* + - loopbackaddr - initialize to the loopback-address value + */ +err_t /* NULL for success, else string literal */ +loopbackaddr(af, dst) +int af; /* address family */ +ip_address *dst; +{ + uint32_t v4loop = htonl(INADDR_LOOPBACK); + + switch (af) { + case AF_INET: + return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst); + break; + case AF_INET6: + return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst); + break; + default: + return "unknown address family in loopbackaddr"; + break; + } +} + +/* + - isanyaddr - test for the any-address value + */ +int +isanyaddr(src) +const ip_address *src; +{ + uint32_t v4any = htonl(INADDR_ANY); + int cmp; + + switch (src->u.v4.sin_family) { + case AF_INET: + cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any)); + break; + case AF_INET6: + cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any)); + break; + default: + return 0; + break; + } + + return (cmp == 0) ? 1 : 0; +} + +/* + - isunspecaddr - test for the unspecified-address value + */ +int +isunspecaddr(src) +const ip_address *src; +{ + return isanyaddr(src); +} + +/* + - isloopbackaddr - test for the loopback-address value + */ +int +isloopbackaddr(src) +const ip_address *src; +{ + uint32_t v4loop = htonl(INADDR_LOOPBACK); + int cmp; + + switch (src->u.v4.sin_family) { + case AF_INET: + cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop)); + break; + case AF_INET6: + cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop)); + break; + default: + return 0; + break; + } + + return (cmp == 0) ? 1 : 0; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/atoaddr.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atoaddr.c --- linux-2.4.29/net/ipsec/libopenswan/atoaddr.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atoaddr.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,238 @@ +/* + * conversion from ASCII forms of addresses to internal ones + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: atoaddr.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + * Define NOLEADINGZEROS to interpret 032 as an error, not as 32. There + * is deliberately no way to interpret it as 26 (i.e., as octal). + */ + +/* + * Legal characters in a domain name. Underscore technically is not, + * but is a common misunderstanding. + */ +static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_."; + +static const char *try8hex(const char *, size_t, struct in_addr *); +static const char *try8hosthex(const char *, size_t, struct in_addr *); +static const char *trydotted(const char *, size_t, struct in_addr *); +static const char *getbyte(const char **, const char *, int *); + +/* + - atoaddr - convert ASCII name or dotted-decimal address to binary address + */ +const char * /* NULL for success, else string literal */ +atoaddr(src, srclen, addrp) +const char *src; +size_t srclen; /* 0 means "apply strlen" */ +struct in_addr *addrp; +{ + struct hostent *h; + struct netent *ne = NULL; + const char *oops; +# define HEXLEN 10 /* strlen("0x11223344") */ +# ifndef ATOADDRBUF +# define ATOADDRBUF 100 +# endif + char namebuf[ATOADDRBUF]; + char *p = namebuf; + char *q; + + if (srclen == 0) + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + + /* might it be hex? */ + if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'x')) + return try8hex(src+2, srclen-2, addrp); + if (srclen == HEXLEN && *src == '0' && CIEQ(*(src+1), 'h')) + return try8hosthex(src+2, srclen-2, addrp); + + /* try it as dotted decimal */ + oops = trydotted(src, srclen, addrp); + if (oops == NULL) + return NULL; /* it worked */ + if (*oops != '?') + return oops; /* it *was* probably meant as a d.q. */ + + /* try it as a name -- first, NUL-terminate it */ + if (srclen > sizeof(namebuf)-1) { + p = (char *) MALLOC(srclen+1); + if (p == NULL) + return "unable to allocate temporary space for name"; + } + p[0] = '\0'; + strncat(p, src, srclen); + + /* next, check that it's a vaguely legal name */ + for (q = p; *q != '\0'; q++) + if (!isprint(*q)) + return "unprintable character in name"; + if (strspn(p, namechars) != srclen) + return "illegal (non-DNS-name) character in name"; + + /* try as host name, failing that as /etc/networks network name */ + h = gethostbyname(p); + if (h == NULL) + ne = getnetbyname(p); + if (p != namebuf) + FREE(p); + if (h == NULL && ne == NULL) + return "name lookup failed"; + + if (h != NULL) + memcpy(&addrp->s_addr, h->h_addr, sizeof(addrp->s_addr)); + else + addrp->s_addr = htonl(ne->n_net); + return NULL; +} + +/* + - try8hosthex - try conversion as an eight-digit host-order hex number + */ +const char * /* NULL for success, else string literal */ +try8hosthex(src, srclen, addrp) +const char *src; +size_t srclen; /* should be 8 */ +struct in_addr *addrp; +{ + const char *oops; + unsigned long addr; + + if (srclen != 8) + return "internal error, try8hex called with bad length"; + + oops = atoul(src, srclen, 16, &addr); + if (oops != NULL) + return oops; + + addrp->s_addr = addr; + return NULL; +} + +/* + - try8hex - try conversion as an eight-digit network-order hex number + */ +const char * /* NULL for success, else string literal */ +try8hex(src, srclen, addrp) +const char *src; +size_t srclen; /* should be 8 */ +struct in_addr *addrp; +{ + const char *oops; + + oops = try8hosthex(src, srclen, addrp); + if (oops != NULL) + return oops; + + addrp->s_addr = htonl(addrp->s_addr); + return NULL; +} + +/* + - trydotted - try conversion as dotted decimal + * + * If the first char of a complaint is '?', that means "didn't look like + * dotted decimal at all". + */ +const char * /* NULL for success, else string literal */ +trydotted(src, srclen, addrp) +const char *src; +size_t srclen; +struct in_addr *addrp; +{ + const char *stop = src + srclen; /* just past end */ + int byte; + const char *oops; + unsigned long addr; + int i; +# define NBYTES 4 +# define BYTE 8 + + addr = 0; + for (i = 0; i < NBYTES && src < stop; i++) { + oops = getbyte(&src, stop, &byte); + if (oops != NULL) { + if (*oops != '?') + return oops; /* bad number */ + if (i > 1) + return oops+1; /* failed number */ + return oops; /* with leading '?' */ + } + addr = (addr << BYTE) | byte; + if (i < 3 && src < stop && *src++ != '.') { + if (i == 0) + return "?syntax error in dotted-decimal address"; + else + return "syntax error in dotted-decimal address"; + } + } + addr <<= (NBYTES - i) * BYTE; + if (src != stop) + return "extra garbage on end of dotted-decimal address"; + + addrp->s_addr = htonl(addr); + return NULL; +} + +/* + - getbyte - try to scan a byte in dotted decimal + * A subtlety here is that all this arithmetic on ASCII digits really is + * highly portable -- ANSI C guarantees that digits 0-9 are contiguous. + * It's easier to just do it ourselves than set up for a call to atoul(). + * + * If the first char of a complaint is '?', that means "didn't look like a + * number at all". + */ +const char * /* NULL for success, else string literal */ +getbyte(srcp, stop, retp) +const char **srcp; /* *srcp is updated */ +const char *stop; /* first untouchable char */ +int *retp; /* return-value pointer */ +{ + char c; + const char *p; + int no; + + if (*srcp >= stop) + return "?empty number in dotted-decimal address"; + + if (stop - *srcp >= 3 && **srcp == '0' && CIEQ(*(*srcp+1), 'x')) + return "hex numbers not supported in dotted-decimal addresses"; +#ifdef NOLEADINGZEROS + if (stop - *srcp >= 2 && **srcp == '0' && isdigit(*(*srcp+1))) + return "octal numbers not supported in dotted-decimal addresses"; +#endif /* NOLEADINGZEROS */ + + /* must be decimal, if it's numeric at all */ + no = 0; + p = *srcp; + while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') { + no = no*10 + (c - '0'); + p++; + } + if (p == *srcp) + return "?non-numeric component in dotted-decimal address"; + *srcp = p; + if (no > 255) + return "byte overflow in dotted-decimal address"; + *retp = no; + return NULL; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/atoasr.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atoasr.c --- linux-2.4.29/net/ipsec/libopenswan/atoasr.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atoasr.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,212 @@ +/* + * convert from ASCII form of address/subnet/range to binary + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: atoasr.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - atoasr - convert ASCII to address, subnet, or range + */ +const char * /* NULL for success, else string literal */ +atoasr(src, srclen, typep, addrsp) +const char *src; +size_t srclen; /* 0 means "apply strlen" */ +char *typep; /* return type code: 'a', 's', 'r' */ +struct in_addr addrsp[2]; +{ + const char *punct; + const char *stop; + const char *oops; + + if (srclen == 0) + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + + /* subnet is easy to spot */ + punct = memchr(src, '/', srclen); + if (punct != NULL) { + *typep = 's'; + return atosubnet(src, srclen, &addrsp[0], &addrsp[1]); + } + + /* try for a range */ + stop = src + srclen; + for (punct = src; (punct = memchr(punct, '.', stop - punct)) != NULL; + punct++) + if (stop - punct > 3 && *(punct+1) == '.' && *(punct+2) == '.') + break; /* NOTE BREAK OUT */ + if (punct == NULL) { + /* didn't find the range delimiter, must be plain address */ + *typep = 'a'; + return atoaddr(src, srclen, &addrsp[0]); + } + + /* looks like a range */ + *typep = 'r'; + if (stop - punct > 4 && *(punct+3) == '.') + punct++; /* first dot is trailing dot of name */ + oops = atoaddr(src, punct - src, &addrsp[0]); + if (oops != NULL) + return oops; + oops = atoaddr(punct+3, stop - (punct+3), &addrsp[1]); + if (oops != NULL) + return oops; + if (ntohl(addrsp[0].s_addr) > ntohl(addrsp[1].s_addr)) + return "invalid range, begin > end"; + return NULL; +} + + + +#ifdef ATOASR_MAIN + +#include + +void regress(); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + struct in_addr a[2]; + char buf[100]; + const char *oops; + size_t n; + char type; + + if (argc < 2) { + fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n", + argv[0]); + exit(2); + } + + if (strcmp(argv[1], "-r") == 0) { + regress(); + fprintf(stderr, "regress() returned?!?\n"); + exit(1); + } + + oops = atoasr(argv[1], 0, &type, a); + if (oops != NULL) { + fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); + exit(1); + } + switch (type) { + case 'a': + n = addrtoa(a[0], 0, buf, sizeof(buf)); + break; + case 's': + n = subnettoa(a[0], a[1], 0, buf, sizeof(buf)); + break; + case 'r': + n = rangetoa(a, 0, buf, sizeof(buf)); + break; + default: + fprintf(stderr, "%s: unknown type '%c'\n", argv[0], type); + exit(1); + break; + } + if (n > sizeof(buf)) { + fprintf(stderr, "%s: reverse conversion of ", argv[0]); + fprintf(stderr, "%s ", inet_ntoa(a[0])); + fprintf(stderr, "%s", inet_ntoa(a[1])); + fprintf(stderr, " failed: need %ld bytes, have only %ld\n", + (long)n, (long)sizeof(buf)); + exit(1); + } + printf("%s\n", buf); + + exit(0); +} + +struct rtab { + char *input; + char *output; /* NULL means error expected */ +} rtab[] = { + "1.2.3.0", "1.2.3.0", + "1.2.3.0/255.255.255.0", "1.2.3.0/24", + "1.2.3.0...1.2.3.5", "1.2.3.0...1.2.3.5", + "1.2.3.4.5", NULL, + "1.2.3.4/", NULL, + "1.2.3.4...", NULL, + "1.2.3.4....", NULL, + "localhost./32", "127.0.0.1/32", + "localhost....127.0.0.3", "127.0.0.1...127.0.0.3", + "127.0.0.0...localhost.", "127.0.0.0...127.0.0.1", + "127.0.0.3...localhost.", NULL, + NULL, NULL +}; + +void +regress() +{ + struct rtab *r; + int status = 0; + struct in_addr a[2]; + struct in_addr m; + char in[100]; + char buf[100]; + const char *oops; + size_t n; + char type; + + for (r = rtab; r->input != NULL; r++) { + strcpy(in, r->input); + oops = atoasr(in, 0, &type, a); + if (oops != NULL && r->output == NULL) + {} /* okay, error expected */ + else if (oops != NULL) { + printf("`%s' atoasr failed: %s\n", r->input, oops); + status = 1; + } else if (r->output == NULL) { + printf("`%s' atoasr succeeded unexpectedly '%c'\n", + r->input, type); + status = 1; + } else { + switch (type) { + case 'a': + n = addrtoa(a[0], 0, buf, sizeof(buf)); + break; + case 's': + n = subnettoa(a[0], a[1], 0, buf, sizeof(buf)); + break; + case 'r': + n = rangetoa(a, 0, buf, sizeof(buf)); + break; + default: + fprintf(stderr, "`%s' unknown type '%c'\n", + r->input, type); + n = 0; + status = 1; + break; + } + if (n > sizeof(buf)) { + printf("`%s' '%c' reverse failed: need %ld\n", + r->input, type, (long)n); + status = 1; + } else if (n > 0 && strcmp(r->output, buf) != 0) { + printf("`%s' '%c' gave `%s', expected `%s'\n", + r->input, type, buf, r->output); + status = 1; + } + } + } + exit(status); +} + +#endif /* ATOASR_MAIN */ diff -urN linux-2.4.29/net/ipsec/libopenswan/atosa.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atosa.c --- linux-2.4.29/net/ipsec/libopenswan/atosa.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atosa.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,199 @@ +/* + * convert from ASCII form of SA ID to binary + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: atosa.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +static struct satype { + char *prefix; + size_t prelen; /* strlen(prefix) */ + int proto; +} satypes[] = { + { "ah", 2, SA_AH }, + { "esp", 3, SA_ESP }, + { "tun", 3, SA_IPIP }, + { "comp", 4, SA_COMP }, + { NULL, 0, 0, } +}; + +/* + - atosa - convert ASCII "ah507@10.0.0.1" to SA identifier + */ +const char * /* NULL for success, else string literal */ +atosa(src, srclen, sa) +const char *src; +size_t srclen; /* 0 means "apply strlen" */ +struct sa_id *sa; +{ + const char *at; + const char *addr; + const char *spi = NULL; + struct satype *sat; + unsigned long ul; + const char *oops; +# define MINLEN 5 /* ah0@0 is as short as it can get */ + static char ptname[] = PASSTHROUGHNAME; +# define PTNLEN (sizeof(ptname)-1) /* -1 for NUL */ + + if (srclen == 0) + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + if (srclen < MINLEN) + return "string too short to be SA specifier"; + if (srclen == PTNLEN && memcmp(src, ptname, PTNLEN) == 0) { + src = PASSTHROUGHIS; + srclen = strlen(src); + } + + at = memchr(src, '@', srclen); + if (at == NULL) + return "no @ in SA specifier"; + + for (sat = satypes; sat->prefix != NULL; sat++) + if (sat->prelen < srclen && + strncmp(src, sat->prefix, sat->prelen) == 0) { + sa->proto = sat->proto; + spi = src + sat->prelen; + break; /* NOTE BREAK OUT */ + } + if (sat->prefix == NULL) + return "SA specifier lacks valid protocol prefix"; + + if (spi >= at) + return "no SPI in SA specifier"; + oops = atoul(spi, at - spi, 13, &ul); + if (oops != NULL) + return oops; + sa->spi = htonl(ul); + + addr = at + 1; + oops = atoaddr(addr, srclen - (addr - src), &sa->dst); + if (oops != NULL) + return oops; + + return NULL; +} + + + +#ifdef ATOSA_MAIN + +#include + +void regress(); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + struct sa_id sa; + char buf[100]; + const char *oops; + size_t n; + + if (argc < 2) { + fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]); + exit(2); + } + + if (strcmp(argv[1], "-r") == 0) { + regress(); + fprintf(stderr, "regress() returned?!?\n"); + exit(1); + } + + oops = atosa(argv[1], 0, &sa); + if (oops != NULL) { + fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); + exit(1); + } + n = satoa(sa, 0, buf, sizeof(buf)); + if (n > sizeof(buf)) { + fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto); + fprintf(stderr, "%lu@", sa.spi); + fprintf(stderr, "%s", inet_ntoa(sa.dst)); + fprintf(stderr, " failed: need %ld bytes, have only %ld\n", + (long)n, (long)sizeof(buf)); + exit(1); + } + printf("%s\n", buf); + + exit(0); +} + +struct rtab { + char *input; + char *output; /* NULL means error expected */ +} rtab[] = { + "esp257@1.2.3.0", "esp257@1.2.3.0", + "ah0x20@1.2.3.4", "ah32@1.2.3.4", + "tun011@111.2.3.99", "tun11@111.2.3.99", + "", NULL, + "_", NULL, + "ah2.2", NULL, + "goo2@1.2.3.4", NULL, + "esp9@1.2.3.4", "esp9@1.2.3.4", + "espp9@1.2.3.4", NULL, + "es9@1.2.3.4", NULL, + "ah@1.2.3.4", NULL, + "esp7x7@1.2.3.4", NULL, + "esp77@1.0x2.3.4", NULL, + PASSTHROUGHNAME, PASSTHROUGHNAME, + NULL, NULL +}; + +void +regress() +{ + struct rtab *r; + int status = 0; + struct sa_id sa; + char in[100]; + char buf[100]; + const char *oops; + size_t n; + + for (r = rtab; r->input != NULL; r++) { + strcpy(in, r->input); + oops = atosa(in, 0, &sa); + if (oops != NULL && r->output == NULL) + {} /* okay, error expected */ + else if (oops != NULL) { + printf("`%s' atosa failed: %s\n", r->input, oops); + status = 1; + } else if (r->output == NULL) { + printf("`%s' atosa succeeded unexpectedly\n", + r->input); + status = 1; + } else { + n = satoa(sa, 'd', buf, sizeof(buf)); + if (n > sizeof(buf)) { + printf("`%s' satoa failed: need %ld\n", + r->input, (long)n); + status = 1; + } else if (strcmp(r->output, buf) != 0) { + printf("`%s' gave `%s', expected `%s'\n", + r->input, buf, r->output); + status = 1; + } + } + } + exit(status); +} + +#endif /* ATOSA_MAIN */ diff -urN linux-2.4.29/net/ipsec/libopenswan/atosubnet.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atosubnet.c --- linux-2.4.29/net/ipsec/libopenswan/atosubnet.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atosubnet.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,215 @@ +/* + * convert from ASCII form of subnet specification to binary + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: atosubnet.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +#ifndef DEFAULTSUBNET +#define DEFAULTSUBNET "%default" +#endif + +/* + - atosubnet - convert ASCII "addr/mask" to address and mask + * Mask can be integer bit count. + */ +const char * /* NULL for success, else string literal */ +atosubnet(src, srclen, addrp, maskp) +const char *src; +size_t srclen; /* 0 means "apply strlen" */ +struct in_addr *addrp; +struct in_addr *maskp; +{ + const char *slash; + const char *mask; + size_t mlen; + const char *oops; + unsigned long bc; + static char def[] = DEFAULTSUBNET; +# define DEFLEN (sizeof(def) - 1) /* -1 for NUL */ + static char defis[] = "0/0"; +# define DEFILEN (sizeof(defis) - 1) + + if (srclen == 0) + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + + if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) { + src = defis; + srclen = DEFILEN; + } + + slash = memchr(src, '/', srclen); + if (slash == NULL) + return "no / in subnet specification"; + mask = slash + 1; + mlen = srclen - (mask - src); + + oops = atoaddr(src, slash-src, addrp); + if (oops != NULL) + return oops; + + oops = atoul(mask, mlen, 10, &bc); + if (oops == NULL) { + /* atoul succeeded, it's a bit-count mask */ + if (bc > ABITS) + return "bit-count mask too large"; +#ifdef NOLEADINGZEROS + if (mlen > 1 && *mask == '0') + return "octal not allowed in mask"; +#endif /* NOLEADINGZEROS */ + *maskp = bitstomask((int)bc); + } else { + oops = atoaddr(mask, mlen, maskp); + if (oops != NULL) + return oops; + if (!goodmask(*maskp)) + return "non-contiguous mask"; + } + + addrp->s_addr &= maskp->s_addr; + return NULL; +} + + + +#ifdef ATOSUBNET_MAIN + +#include + +void regress(); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + struct in_addr a; + struct in_addr m; + char buf[100]; + const char *oops; + size_t n; + + if (argc < 2) { + fprintf(stderr, "Usage: %s {addr/mask|-r}\n", argv[0]); + exit(2); + } + + if (strcmp(argv[1], "-r") == 0) { + regress(); + fprintf(stderr, "regress() returned?!?\n"); + exit(1); + } + + oops = atosubnet(argv[1], 0, &a, &m); + if (oops != NULL) { + fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); + exit(1); + } + n = subnettoa(a, m, 0, buf, sizeof(buf)); + if (n > sizeof(buf)) { + fprintf(stderr, "%s: reverse conversion of ", argv[0]); + fprintf(stderr, "%s/", inet_ntoa(a)); + fprintf(stderr, "%s", inet_ntoa(m)); + fprintf(stderr, " failed: need %ld bytes, have only %ld\n", + (long)n, (long)sizeof(buf)); + exit(1); + } + printf("%s\n", buf); + + exit(0); +} + +struct rtab { + char *input; + char *output; /* NULL means error expected */ +} rtab[] = { + "1.2.3.0/255.255.255.0", "1.2.3.0/24", + "1.2.3.0/24", "1.2.3.0/24", + "1.2.3.1/255.255.255.240", "1.2.3.0/28", + "1.2.3.1/32", "1.2.3.1/32", + "1.2.3.1/0", "0.0.0.0/0", +/* "1.2.3.1/255.255.127.0", "1.2.3.0/255.255.127.0", */ + "1.2.3.1/255.255.127.0", NULL, + "128.009.000.032/32", "128.9.0.32/32", + "128.0x9.0.32/32", NULL, + "0x80090020/32", "128.9.0.32/32", + "0x800x0020/32", NULL, + "128.9.0.32/0xffFF0000", "128.9.0.0/16", + "128.9.0.32/0xff0000FF", NULL, + "128.9.0.32/0x0000ffFF", NULL, + "128.9.0.32/0x00ffFF0000", NULL, + "128.9.0.32/0xffFF", NULL, + "128.9.0.32.27/32", NULL, + "128.9.0k32/32", NULL, + "328.9.0.32/32", NULL, + "128.9..32/32", NULL, + "10/8", "10.0.0.0/8", + "10.0/8", "10.0.0.0/8", + "10.0.0/8", "10.0.0.0/8", + "10.0.1/24", "10.0.1.0/24", + "_", NULL, + "_/_", NULL, + "1.2.3.1", NULL, + "1.2.3.1/_", NULL, + "1.2.3.1/24._", NULL, + "1.2.3.1/99", NULL, + "localhost./32", "127.0.0.1/32", + "%default", "0.0.0.0/0", + NULL, NULL +}; + +void +regress() +{ + struct rtab *r; + int status = 0; + struct in_addr a; + struct in_addr m; + char in[100]; + char buf[100]; + const char *oops; + size_t n; + + for (r = rtab; r->input != NULL; r++) { + strcpy(in, r->input); + oops = atosubnet(in, 0, &a, &m); + if (oops != NULL && r->output == NULL) + {} /* okay, error expected */ + else if (oops != NULL) { + printf("`%s' atosubnet failed: %s\n", r->input, oops); + status = 1; + } else if (r->output == NULL) { + printf("`%s' atosubnet succeeded unexpectedly\n", + r->input); + status = 1; + } else { + n = subnettoa(a, m, 0, buf, sizeof(buf)); + if (n > sizeof(buf)) { + printf("`%s' subnettoa failed: need %ld\n", + r->input, (long)n); + status = 1; + } else if (strcmp(r->output, buf) != 0) { + printf("`%s' gave `%s', expected `%s'\n", + r->input, buf, r->output); + status = 1; + } + } + } + exit(status); +} + +#endif /* ATOSUBNET_MAIN */ diff -urN linux-2.4.29/net/ipsec/libopenswan/atoul.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atoul.c --- linux-2.4.29/net/ipsec/libopenswan/atoul.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/atoul.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,90 @@ +/* + * convert from ASCII form of unsigned long to binary + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: atoul.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - atoul - convert ASCII substring to unsigned long number + */ +const char * /* NULL for success, else string literal */ +atoul(src, srclen, base, resultp) +const char *src; +size_t srclen; /* 0 means strlen(src) */ +int base; /* 0 means figure it out */ +unsigned long *resultp; +{ + const char *stop; + static char hex[] = "0123456789abcdef"; + static char uchex[] = "0123456789ABCDEF"; + int d; + char c; + char *p; + unsigned long r; + unsigned long rlimit; + int dlimit; + + if (srclen == 0) + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + + if (base == 0 || base == 13) { + if (srclen > 2 && *src == '0' && CIEQ(*(src+1), 'x')) + return atoul(src+2, srclen-2, 16, resultp); + if (srclen > 1 && *src == '0' && base != 13) + return atoul(src+1, srclen-1, 8, resultp); + return atoul(src, srclen, 10, resultp); + } + if (base != 8 && base != 10 && base != 16) + return "unsupported number base"; + + r = 0; + stop = src + srclen; + if (base == 16) { + while (src < stop) { + c = *src++; + p = strchr(hex, c); + if (p != NULL) + d = p - hex; + else { + p = strchr(uchex, c); + if (p == NULL) + return "non-hex-digit in hex number"; + d = p - uchex; + } + r = (r << 4) | d; + } + /* defer length check to catch invalid digits first */ + if (srclen > sizeof(unsigned long) * 2) + return "hex number too long"; + } else { + rlimit = ULONG_MAX / base; + dlimit = (int)(ULONG_MAX - rlimit*base); + while (src < stop) { + c = *src++; + d = c - '0'; + if (d < 0 || d >= base) + return "non-digit in number"; + if (r > rlimit || (r == rlimit && d > dlimit)) + return "unsigned-long overflow"; + r = r*base + d; + } + } + + *resultp = r; + return NULL; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/copyright.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/copyright.c --- linux-2.4.29/net/ipsec/libopenswan/copyright.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/copyright.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,44 @@ +/* + * return IPsec copyright notice + * Copyright (C) 2001, 2002 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: copyright.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +static const char *co[] = { + "Copyright (C) 1999, 2000, 2001, 2002 Henry Spencer, Richard Guy Briggs,", + " D. Hugh Redelmeier, Sandy Harris, Claudia Schmeing,", + " Michael Richardson, Angelos D. Keromytis, John Ioannidis.", + "", + "This program is free software; you can redistribute it and/or modify it", + "under the terms of the GNU General Public License as published by the", + "Free Software Foundation; either version 2 of the License, or (at your", + "option) any later version. See .", + "", + "This program is distributed in the hope that it will be useful, but", + "WITHOUT ANY WARRANTY; without even the implied warranty of", + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General", + "Public License (file COPYING in the distribution) for more details.", + NULL +}; + +/* + - ipsec_copyright_notice - return copyright notice, as a vector of strings + */ +const char ** +ipsec_copyright_notice() +{ + return co; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/datatot.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/datatot.c --- linux-2.4.29/net/ipsec/libopenswan/datatot.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/datatot.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,233 @@ +/* + * convert from binary data (e.g. key) to text form + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: datatot.c,v 1.3 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +static void convert(const char *src, size_t nreal, int format, char *out); + +/* + - datatot - convert data bytes to text + */ +size_t /* true length (with NUL) for success */ +datatot(src, srclen, format, dst, dstlen) +const char *src; +size_t srclen; +int format; /* character indicating what format */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + size_t inblocksize; /* process this many bytes at a time */ + size_t outblocksize; /* producing this many */ + size_t breakevery; /* add a _ every this many (0 means don't) */ + size_t sincebreak; /* output bytes since last _ */ + char breakchar; /* character used to break between groups */ + char inblock[10]; /* enough for any format */ + char outblock[10]; /* enough for any format */ + char fake[1]; /* fake output area for dstlen == 0 */ + size_t needed; /* return value */ + char *stop; /* where the terminating NUL will go */ + size_t ntodo; /* remaining input */ + size_t nreal; + char *out; + char *prefix; + + breakevery = 0; + breakchar = '_'; + + switch (format) { + case 0: + case 'h': + format = 'x'; + breakevery = 8; + /* FALLTHROUGH */ + case 'x': + inblocksize = 1; + outblocksize = 2; + prefix = "0x"; + break; + case ':': + format = 'x'; + breakevery = 2; + breakchar = ':'; + /* FALLTHROUGH */ + case 16: + inblocksize = 1; + outblocksize = 2; + prefix = ""; + format = 'x'; + break; + case 's': + inblocksize = 3; + outblocksize = 4; + prefix = "0s"; + break; + case 64: /* beware, equals ' ' */ + inblocksize = 3; + outblocksize = 4; + prefix = ""; + format = 's'; + break; + default: + return 0; + break; + } + assert(inblocksize < sizeof(inblock)); + assert(outblocksize < sizeof(outblock)); + assert(breakevery % outblocksize == 0); + + if (srclen == 0) + return 0; + ntodo = srclen; + + if (dstlen == 0) { /* dispose of awkward special case */ + dst = fake; + dstlen = 1; + } + stop = dst + dstlen - 1; + + nreal = strlen(prefix); + needed = nreal; /* for starters */ + if (dstlen <= nreal) { /* prefix won't fit */ + strncpy(dst, prefix, dstlen - 1); + dst += dstlen - 1; + } else { + strcpy(dst, prefix); + dst += nreal; + } + assert(dst <= stop); + sincebreak = 0; + + while (ntodo > 0) { + if (ntodo < inblocksize) { /* incomplete input */ + memset(inblock, 0, sizeof(inblock)); + memcpy(inblock, src, ntodo); + src = inblock; + nreal = ntodo; + ntodo = inblocksize; + } else + nreal = inblocksize; + out = (outblocksize > stop - dst) ? outblock : dst; + + convert(src, nreal, format, out); + needed += outblocksize; + sincebreak += outblocksize; + if (dst < stop) { + if (out != dst) { + assert(outblocksize > stop - dst); + memcpy(dst, out, stop - dst); + dst = stop; + } else + dst += outblocksize; + } + + src += inblocksize; + ntodo -= inblocksize; + if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) { + if (dst < stop) + *dst++ = breakchar; + needed++; + sincebreak = 0; + } + } + + assert(dst <= stop); + *dst++ = '\0'; + needed++; + + return needed; +} + +/* + - convert - convert one input block to one output block + */ +static void +convert(src, nreal, format, out) +const char *src; +size_t nreal; /* how much of the input block is real */ +int format; +char *out; +{ + static char hex[] = "0123456789abcdef"; + static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + unsigned char c; + unsigned char c1, c2, c3; + + assert(nreal > 0); + switch (format) { + case 'x': + assert(nreal == 1); + c = (unsigned char)*src; + *out++ = hex[c >> 4]; + *out++ = hex[c & 0xf]; + break; + case 's': + c1 = (unsigned char)*src++; + c2 = (unsigned char)*src++; + c3 = (unsigned char)*src++; + *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */ + c = (c1 & 0x3) << 4; /* bottom 2 of c1... */ + c |= c2 >> 4; /* ...top 4 of c2 */ + *out++ = base64[c]; + if (nreal == 1) + *out++ = '='; + else { + c = (c2 & 0xf) << 2; /* bottom 4 of c2... */ + c |= c3 >> 6; /* ...top 2 of c3 */ + *out++ = base64[c]; + } + if (nreal <= 2) + *out++ = '='; + else + *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */ + break; + default: + assert(nreal == 0); /* unknown format */ + break; + } +} + +/* + - datatoa - convert data to ASCII + * backward-compatibility synonym for datatot + */ +size_t /* true length (with NUL) for success */ +datatoa(src, srclen, format, dst, dstlen) +const char *src; +size_t srclen; +int format; /* character indicating what format */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + return datatot(src, srclen, format, dst, dstlen); +} + +/* + - bytestoa - convert data bytes to ASCII + * backward-compatibility synonym for datatot + */ +size_t /* true length (with NUL) for success */ +bytestoa(src, srclen, format, dst, dstlen) +const char *src; +size_t srclen; +int format; /* character indicating what format */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + return datatot(src, srclen, format, dst, dstlen); +} diff -urN linux-2.4.29/net/ipsec/libopenswan/goodmask.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/goodmask.c --- linux-2.4.29/net/ipsec/libopenswan/goodmask.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/goodmask.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,97 @@ +/* + * minor utilities for subnet-mask manipulation + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: goodmask.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - goodmask - is this a good (^1*0*$) subnet mask? + * You are not expected to understand this. See Henry S. Warren Jr, + * "Functions realizable with word-parallel logical and two's-complement + * addition instructions", CACM 20.6 (June 1977), p.439. + */ +int /* predicate */ +goodmask(mask) +struct in_addr mask; +{ + unsigned long x = ntohl(mask.s_addr); + /* clear rightmost contiguous string of 1-bits */ +# define CRCS1B(x) (((x|(x-1))+1)&x) +# define TOPBIT (1UL << 31) + + /* either zero, or has one string of 1-bits which is left-justified */ + if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT))) + return 1; + return 0; +} + +/* + - masktobits - how many bits in this mask? + * The algorithm is essentially a binary search, but highly optimized + * for this particular task. + */ +int /* -1 means !goodmask() */ +masktobits(mask) +struct in_addr mask; +{ + unsigned long m = ntohl(mask.s_addr); + int masklen; + + if (!goodmask(mask)) + return -1; + + if (m&0x00000001UL) + return 32; + masklen = 0; + if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */ + masklen |= 0x10; + m <<= 16; + } + if (m&(0x00ff0000UL<<1)) { + masklen |= 0x08; + m <<= 8; + } + if (m&(0x0f000000UL<<1)) { + masklen |= 0x04; + m <<= 4; + } + if (m&(0x30000000UL<<1)) { + masklen |= 0x02; + m <<= 2; + } + if (m&(0x40000000UL<<1)) + masklen |= 0x01; + + return masklen; +} + +/* + - bitstomask - return a mask with this many high bits on + */ +struct in_addr +bitstomask(n) +int n; +{ + struct in_addr result; + + if (n > 0 && n <= ABITS) + result.s_addr = htonl(~((1UL << (ABITS - n)) - 1)); + else if (n == 0) + result.s_addr = 0; + else + result.s_addr = 0; /* best error report we can do */ + return result; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/initaddr.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/initaddr.c --- linux-2.4.29/net/ipsec/libopenswan/initaddr.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/initaddr.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,51 @@ +/* + * initialize address structure + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: initaddr.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - initaddr - initialize ip_address from bytes + */ +err_t /* NULL for success, else string literal */ +initaddr(src, srclen, af, dst) +const unsigned char *src; +size_t srclen; +int af; /* address family */ +ip_address *dst; +{ + switch (af) { + case AF_INET: + if (srclen != 4) + return "IPv4 address must be exactly 4 bytes"; + dst->u.v4.sin_family = af; + dst->u.v4.sin_port = 0; /* unused */ + memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen); + break; + case AF_INET6: + if (srclen != 16) + return "IPv6 address must be exactly 16 bytes"; + dst->u.v6.sin6_family = af; + dst->u.v6.sin6_flowinfo = 0; /* unused */ + dst->u.v6.sin6_port = 0; /* unused */ + memcpy((char *)&dst->u.v6.sin6_addr, src, srclen); + break; + default: + return "unknown address family in initaddr"; + break; + } + return NULL; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/initsaid.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/initsaid.c --- linux-2.4.29/net/ipsec/libopenswan/initsaid.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/initsaid.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,33 @@ +/* + * initialize SA ID structure + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: initsaid.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - initsaid - initialize SA ID from bits + */ +void +initsaid(addr, spi, proto, dst) +const ip_address *addr; +ipsec_spi_t spi; +int proto; +ip_said *dst; +{ + dst->dst = *addr; + dst->spi = spi; + dst->proto = proto; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/initsubnet.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/initsubnet.c --- linux-2.4.29/net/ipsec/libopenswan/initsubnet.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/initsubnet.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,95 @@ +/* + * initialize subnet structure + * Copyright (C) 2000, 2002 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: initsubnet.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - initsubnet - initialize ip_subnet from address and count + * + * The only hard part is checking for host-part bits turned on. + */ +err_t /* NULL for success, else string literal */ +initsubnet(addr, count, clash, dst) +const ip_address *addr; +int count; +int clash; /* '0' zero host-part bits, 'x' die on them */ +ip_subnet *dst; +{ + unsigned char *p; + int n; + int c; + unsigned m; + int die; + + dst->addr = *addr; + n = addrbytesptr(&dst->addr, (const unsigned char **)&p); + if (n == 0) + return "unknown address family"; + + switch (clash) { + case '0': + die = 0; + break; + case 'x': + die = 1; + break; + default: + return "unknown clash-control value in initsubnet"; + break; + } + + c = count / 8; + if (c > n) + return "impossible mask count"; + p += c; + n -= c; + + m = 0xff; + c = count % 8; + if (n > 0 && c != 0) /* partial byte */ + m >>= c; + for (; n > 0; n--) { + if ((*p & m) != 0) { + if (die) + return "improper subnet, host-part bits on"; + *p &= ~m; + } + m = 0xff; + p++; + } + + dst->maskbits = count; + return NULL; +} + +/* + - addrtosubnet - initialize ip_subnet from a single address + */ +err_t /* NULL for success, else string literal */ +addrtosubnet(addr, dst) +const ip_address *addr; +ip_subnet *dst; +{ + int n; + + dst->addr = *addr; + n = addrbytesptr(&dst->addr, (const unsigned char **)NULL); + if (n == 0) + return "unknown address family"; + dst->maskbits = n*8; + return NULL; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/internal.h linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/internal.h --- linux-2.4.29/net/ipsec/libopenswan/internal.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/internal.h Thu Sep 5 05:13:19 2002 @@ -0,0 +1,81 @@ +/* + * internal definitions for use within the library; do not export! + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: internal.h,v 1.1.1.1 2002/09/05 03:13:19 ken Exp $ + */ + +#ifndef ABITS +#define ABITS 32 /* bits in an IPv4 address */ +#endif + +/* case-independent ASCII character equality comparison */ +#define CIEQ(c1, c2) ( ((c1)&~040) == ((c2)&~040) ) + +/* syntax for passthrough SA */ +#ifndef PASSTHROUGHNAME +#define PASSTHROUGHNAME "%passthrough" +#define PASSTHROUGH4NAME "%passthrough4" +#define PASSTHROUGH6NAME "%passthrough6" +#define PASSTHROUGHIS "tun0@0.0.0.0" +#define PASSTHROUGH4IS "tun0@0.0.0.0" +#define PASSTHROUGH6IS "tun0@::" +#define PASSTHROUGHTYPE "tun" +#define PASSTHROUGHSPI 0 +#define PASSTHROUGHDST 0 +#endif + +/* + * Headers, greatly complicated by stupid and unnecessary inconsistencies + * between the user environment and the kernel environment. These are done + * here so that this mess need exist in only one place. + * + * It may seem like a -I or two could avoid most of this, but on closer + * inspection it is not quite that easy. + */ + +/* things that need to come from one place or the other, depending */ +#ifdef __KERNEL__ +#include +#include +#include +#include +#include +#define assert(foo) /* nothing */ +#else +#include +#include +#include +#include +#include +#endif + +/* things that exist only in userland */ +#ifndef __KERNEL__ + +/* You'd think this would be okay in the kernel too -- it's just a */ +/* bunch of constants -- but no, in RH5.1 it screws up other things. */ +/* (Credit: Mike Warfield tracked this problem down. Thanks Mike!) */ +/* Fortunately, we don't need it in the kernel subset of the library. */ +#include + +/* header files for things that should never be called in kernel */ +#include + +/* memory allocation, currently user-only, macro-ized just in case */ +#include +#define MALLOC(n) malloc(n) +#define FREE(p) free(p) + +#endif /* __KERNEL__ */ + diff -urN linux-2.4.29/net/ipsec/libopenswan/keyblobtoid.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/keyblobtoid.c --- linux-2.4.29/net/ipsec/libopenswan/keyblobtoid.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/keyblobtoid.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,148 @@ +/* + * generate printable key IDs + * Copyright (C) 2002 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: keyblobtoid.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - keyblobtoid - generate a printable key ID from an RFC 2537/3110 key blob + * Current algorithm is just to use first nine base64 digits. + */ +size_t +keyblobtoid(src, srclen, dst, dstlen) +const unsigned char *src; +size_t srclen; +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + char buf[KEYID_BUF]; + size_t ret; +# define NDIG 9 + + if (srclen < (NDIG*6 + 7)/8) { + strcpy(buf, "?len= ?"); + buf[5] = '0' + srclen; + ret = 0; + } else { + (void) datatot(src, srclen, 64, buf, NDIG+1); + ret = NDIG+1; + } + + if (dstlen > 0) { + if (strlen(buf)+1 > dstlen) + *(buf + dstlen - 1) = '\0'; + strcpy(dst, buf); + } + return ret; +} + +/* + - splitkeytoid - generate a printable key ID from exponent/modulus pair + * Just constructs the beginnings of a key blob and calls keyblobtoid(). + */ +size_t +splitkeytoid(e, elen, m, mlen, dst, dstlen) +const unsigned char *e; +size_t elen; +const unsigned char *m; +size_t mlen; +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + unsigned char buf[KEYID_BUF]; /* ample room */ + unsigned char *bufend = buf + sizeof(buf); + unsigned char *p; + size_t n; + + p = buf; + if (elen <= 255) + *p++ = elen; + else if ((elen &~ 0xffff) == 0) { + *p++ = 0; + *p++ = (elen>>8) & 0xff; + *p++ = elen & 0xff; + } else + return 0; /* unrepresentable exponent length */ + + n = bufend - p; + if (elen < n) + n = elen; + memcpy(p, e, n); + p += n; + + n = bufend - p; + if (n > 0) { + if (mlen < n) + n = mlen; + memcpy(p, m, n); + p += n; + } + + return keyblobtoid(buf, p - buf, dst, dstlen); +} + + + +#ifdef KEYID_MAIN + +#include + +void regress(); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + typedef unsigned char uc; + uc hexblob[] = "\x01\x03\x85\xf2\xd6\x76\x9b\x03\x59\xb6\x21\x52"; + uc hexe[] = "\x03"; + uc hexm[] = "\x85\xf2\xd6\x76\x9b\x03\x59\xb6\x21\x52\xef\x85"; + char b64nine[] = "AQOF8tZ2m"; + char b64six[] = "AQOF8t"; + char buf[100]; + size_t n; + char *b = b64nine; + size_t bl = strlen(b) + 1; + int st = 0; + + n = keyblobtoid(hexblob, strlen(hexblob), buf, sizeof(buf)); + if (n != bl) { + fprintf(stderr, "%s: keyblobtoid returned %d not %d\n", + argv[0], n, bl); + st = 1; + } + if (strcmp(buf, b) != 0) { + fprintf(stderr, "%s: keyblobtoid generated `%s' not `%s'\n", + argv[0], buf, b); + st = 1; + } + n = splitkeytoid(hexe, strlen(hexe), hexm, strlen(hexm), buf, + sizeof(buf)); + if (n != bl) { + fprintf(stderr, "%s: splitkeytoid returned %d not %d\n", + argv[0], n, bl); + st = 1; + } + if (strcmp(buf, b) != 0) { + fprintf(stderr, "%s: splitkeytoid generated `%s' not `%s'\n", + argv[0], buf, b); + st = 1; + } + exit(st); +} + +#endif /* KEYID_MAIN */ diff -urN linux-2.4.29/net/ipsec/libopenswan/openswan.h linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/openswan.h --- linux-2.4.29/net/ipsec/libopenswan/openswan.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/openswan.h Mon Mar 1 13:45:01 2004 @@ -0,0 +1,428 @@ +#ifndef _OPENSWAN_H +/* + * header file for Open library functions + * Copyright (C) 1998, 1999, 2000 Henry Spencer. + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs + * Copyright (C) 2003 Xelerance Corporation + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: openswan.h,v 1.3 2004/03/01 12:45:01 paul Exp $ + */ +#define _OPENSWAN_H /* seen it, no need to see it again */ + + + +/* + * We've just got to have some datatypes defined... And annoyingly, just + * where we get them depends on whether we're in userland or not. + */ +#ifdef __KERNEL__ + +# include +# include + +#else /* __KERNEL__ */ + +# include +# include + +# define uint8_t u_int8_t +# define uint16_t u_int16_t +# define uint32_t u_int32_t +# define uint64_t u_int64_t + +# define DEBUG_NO_STATIC static + +#endif /* __KERNEL__ */ + +/* + * Grab the kernel version to see if we have NET_21, and therefore + * IPv6. Some of this is repeated from ipsec_kversions.h. Of course, + * we aren't really testing if the kernel has IPv6, but rather if the + * the include files do. + */ +#include +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z)) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) +#define NET_21 +#endif + +#ifndef IPPROTO_COMP +# define IPPROTO_COMP 108 +#endif /* !IPPROTO_COMP */ + +#ifndef IPPROTO_INT +# define IPPROTO_INT 61 +#endif /* !IPPROTO_INT */ + +#ifdef CONFIG_IPSEC_DEBUG +# define DEBUG_NO_STATIC +#else /* CONFIG_IPSEC_DEBUG */ +# define DEBUG_NO_STATIC static +#endif /* CONFIG_IPSEC_DEBUG */ + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL /* KERNEL ifdef */ +#ifndef NAT_TRAVERSAL +#define NAT_TRAVERSAL +#endif +#endif +#ifdef NAT_TRAVERSAL +#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */ +#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */ +#endif + +/* + * Basic data types for the address-handling functions. + * ip_address and ip_subnet are supposed to be opaque types; do not + * use their definitions directly, they are subject to change! + */ + +/* first, some quick fakes in case we're on an old system with no IPv6 */ +#ifndef s6_addr16 +struct in6_addr { + union + { + __u8 u6_addr8[16]; + __u16 u6_addr16[8]; + __u32 u6_addr32[4]; + } in6_u; +#define s6_addr in6_u.u6_addr8 +#define s6_addr16 in6_u.u6_addr16 +#define s6_addr32 in6_u.u6_addr32 +}; +struct sockaddr_in6 { + unsigned short int sin6_family; /* AF_INET6 */ + __u16 sin6_port; /* Transport layer port # */ + __u32 sin6_flowinfo; /* IPv6 flow information */ + struct in6_addr sin6_addr; /* IPv6 address */ + __u32 sin6_scope_id; /* scope id (new in RFC2553) */ +}; +#endif /* !s6_addr16 */ + +/* then the main types */ +typedef struct { + union { + struct sockaddr_in v4; + struct sockaddr_in6 v6; + } u; +} ip_address; +typedef struct { + ip_address addr; + int maskbits; +} ip_subnet; + +/* and the SA ID stuff */ +#ifdef __KERNEL__ +typedef __u32 ipsec_spi_t; +#else +typedef u_int32_t ipsec_spi_t; +#endif +typedef struct { /* to identify an SA, we need: */ + ip_address dst; /* A. destination host */ + ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */ +# define SPI_PASS 256 /* magic values... */ +# define SPI_DROP 257 /* ...for use... */ +# define SPI_REJECT 258 /* ...with SA_INT */ +# define SPI_HOLD 259 +# define SPI_TRAP 260 +# define SPI_TRAPSUBNET 261 + int proto; /* C. protocol */ +# define SA_ESP 50 /* IPPROTO_ESP */ +# define SA_AH 51 /* IPPROTO_AH */ +# define SA_IPIP 4 /* IPPROTO_IPIP */ +# define SA_COMP 108 /* IPPROTO_COMP */ +# define SA_INT 61 /* IANA reserved for internal use */ +} ip_said; +struct sa_id { /* old v4-only version */ + struct in_addr dst; + ipsec_spi_t spi; + int proto; +}; + +/* misc */ +typedef const char *err_t; /* error message, or NULL for success */ +struct prng { /* pseudo-random-number-generator guts */ + unsigned char sbox[256]; + int i, j; + unsigned long count; +}; + + + +/* + * new IPv6-compatible functions + */ + +/* text conversions */ +err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst); +size_t ultot(unsigned long src, int format, char *buf, size_t buflen); +#define ULTOT_BUF (22+1) /* holds 64 bits in octal */ +err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst); +err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst); +size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen); +/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */ +#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1) +err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst); +size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen); +#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3) +err_t ttosa(const char *src, size_t srclen, ip_said *dst); +size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen); +#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF) +err_t ttodata(const char *src, size_t srclen, int base, char *buf, + size_t buflen, size_t *needed); +err_t ttodatav(const char *src, size_t srclen, int base, char *buf, + size_t buflen, size_t *needed, char *errp, size_t errlen); +#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */ +size_t datatot(const char *src, size_t srclen, int format, char *buf, + size_t buflen); +size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst, + size_t dstlen); +size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m, + size_t mlen, char *dst, size_t dstlen); +#define KEYID_BUF 10 /* up to 9 text digits plus NUL */ +err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port, + int *has_port_wildcard); + +/* initializations */ +void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst); +err_t loopbackaddr(int af, ip_address *dst); +err_t unspecaddr(int af, ip_address *dst); +err_t anyaddr(int af, ip_address *dst); +err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst); +err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst); +err_t addrtosubnet(const ip_address *addr, ip_subnet *dst); + +/* misc. conversions and related */ +err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst); +int addrtypeof(const ip_address *src); +int subnettypeof(const ip_subnet *src); +size_t addrlenof(const ip_address *src); +size_t addrbytesptr(const ip_address *src, const unsigned char **dst); +size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen); +int masktocount(const ip_address *src); +void networkof(const ip_subnet *src, ip_address *dst); +void maskof(const ip_subnet *src, ip_address *dst); + +/* tests */ +int sameaddr(const ip_address *a, const ip_address *b); +int addrcmp(const ip_address *a, const ip_address *b); +int samesubnet(const ip_subnet *a, const ip_subnet *b); +int addrinsubnet(const ip_address *a, const ip_subnet *s); +int subnetinsubnet(const ip_subnet *a, const ip_subnet *b); +int subnetishost(const ip_subnet *s); +int samesaid(const ip_said *a, const ip_said *b); +int sameaddrtype(const ip_address *a, const ip_address *b); +int samesubnettype(const ip_subnet *a, const ip_subnet *b); +int isanyaddr(const ip_address *src); +int isunspecaddr(const ip_address *src); +int isloopbackaddr(const ip_address *src); + +/* low-level grot */ +int portof(const ip_address *src); +void setportof(int port, ip_address *dst); +struct sockaddr *sockaddrof(ip_address *src); +size_t sockaddrlenof(const ip_address *src); + +/* PRNG */ +void prng_init(struct prng *prng, const unsigned char *key, size_t keylen); +void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen); +unsigned long prng_count(struct prng *prng); +void prng_final(struct prng *prng); + +/* odds and ends */ +const char *ipsec_version_code(void); +const char *ipsec_version_string(void); +const char **ipsec_copyright_notice(void); + + + +/* + * old functions, to be deleted eventually + */ + +/* unsigned long */ +const char * /* NULL for success, else string literal */ +atoul( + const char *src, + size_t srclen, /* 0 means strlen(src) */ + int base, /* 0 means figure it out */ + unsigned long *resultp +); +size_t /* space needed for full conversion */ +ultoa( + unsigned long n, + int base, + char *dst, + size_t dstlen +); +#define ULTOA_BUF 21 /* just large enough for largest result, */ + /* assuming 64-bit unsigned long! */ + +/* Internet addresses */ +const char * /* NULL for success, else string literal */ +atoaddr( + const char *src, + size_t srclen, /* 0 means strlen(src) */ + struct in_addr *addr +); +size_t /* space needed for full conversion */ +addrtoa( + struct in_addr addr, + int format, /* character; 0 means default */ + char *dst, + size_t dstlen +); +#define ADDRTOA_BUF 16 /* just large enough for largest result */ + +/* subnets */ +const char * /* NULL for success, else string literal */ +atosubnet( + const char *src, + size_t srclen, /* 0 means strlen(src) */ + struct in_addr *addr, + struct in_addr *mask +); +size_t /* space needed for full conversion */ +subnettoa( + struct in_addr addr, + struct in_addr mask, + int format, /* character; 0 means default */ + char *dst, + size_t dstlen +); +#define SUBNETTOA_BUF 32 /* large enough for worst case result */ + +/* ranges */ +const char * /* NULL for success, else string literal */ +atoasr( + const char *src, + size_t srclen, /* 0 means strlen(src) */ + char *type, /* 'a', 's', 'r' */ + struct in_addr *addrs /* two-element array */ +); +size_t /* space needed for full conversion */ +rangetoa( + struct in_addr *addrs, /* two-element array */ + int format, /* character; 0 means default */ + char *dst, + size_t dstlen +); +#define RANGETOA_BUF 34 /* large enough for worst case result */ + +/* data types for SA conversion functions */ + +/* SAs */ +const char * /* NULL for success, else string literal */ +atosa( + const char *src, + size_t srclen, /* 0 means strlen(src) */ + struct sa_id *sa +); +size_t /* space needed for full conversion */ +satoa( + struct sa_id sa, + int format, /* character; 0 means default */ + char *dst, + size_t dstlen +); +#define SATOA_BUF (3+ULTOA_BUF+ADDRTOA_BUF) + +/* generic data, e.g. keys */ +const char * /* NULL for success, else string literal */ +atobytes( + const char *src, + size_t srclen, /* 0 means strlen(src) */ + char *dst, + size_t dstlen, + size_t *lenp /* NULL means don't bother telling me */ +); +size_t /* 0 failure, else true size */ +bytestoa( + const char *src, + size_t srclen, + int format, /* character; 0 means default */ + char *dst, + size_t dstlen +); + +/* old versions of generic-data functions; deprecated */ +size_t /* 0 failure, else true size */ +atodata( + const char *src, + size_t srclen, /* 0 means strlen(src) */ + char *dst, + size_t dstlen +); +size_t /* 0 failure, else true size */ +datatoa( + const char *src, + size_t srclen, + int format, /* character; 0 means default */ + char *dst, + size_t dstlen +); + +/* part extraction and special addresses */ +struct in_addr +subnetof( + struct in_addr addr, + struct in_addr mask +); +struct in_addr +hostof( + struct in_addr addr, + struct in_addr mask +); +struct in_addr +broadcastof( + struct in_addr addr, + struct in_addr mask +); + +/* mask handling */ +int +goodmask( + struct in_addr mask +); +int +masktobits( + struct in_addr mask +); +struct in_addr +bitstomask( + int n +); + + + +/* + * general utilities + */ + +#ifndef __KERNEL__ +/* option pickup from files (userland only because of use of FILE) */ +const char *optionsfrom(const char *filename, int *argcp, char ***argvp, + int optind, FILE *errorreport); +#endif + +/* + * Debugging levels for pfkey_parse.c + */ +#define PF_KEY_DEBUG_PARSE_PROBLEM 1 +#define PF_KEY_DEBUG_PARSE_STRUCT 3 +#define PF_KEY_DEBUG_PARSE_FLOW 4 + + +#endif /* _OPENSWAN_H */ diff -urN linux-2.4.29/net/ipsec/libopenswan/optionsfrom.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/optionsfrom.c --- linux-2.4.29/net/ipsec/libopenswan/optionsfrom.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/optionsfrom.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,301 @@ +/* + * pick up more options from a file, in the middle of an option scan + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: optionsfrom.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +#include + +#define MAX 100 /* loop-detection limit */ + +/* internal work area */ +struct work { +# define LOTS 1024 + char buf[LOTS]; + char *line; + char *pending; +}; + +static const char *dowork(const char *, int *, char ***, int); +static const char *getanarg(FILE *, struct work *, char **); +static char *getline(FILE *, char *, size_t); + +/* + - optionsfrom - add some options, taken from a file, to argc/argv + * If errsto is non-NULL, does not return in event of error. + */ +const char * /* NULL for success, else string literal */ +optionsfrom(filename, argcp, argvp, optind, errsto) +const char *filename; +int *argcp; /* pointer to argc */ +char ***argvp; /* pointer to argv */ +int optind; /* current optind, number of next argument */ +FILE *errsto; /* where to report errors (NULL means return) */ +{ + const char *e; + static int nuses = 0; + + if (errsto != NULL) { + nuses++; + if (nuses >= MAX) { + fprintf(errsto, + "%s: optionsfrom called %d times, looping?\n", + (*argvp)[0], nuses); + exit(2); + } + } else + nuses = 0; + + e = dowork(filename, argcp, argvp, optind); + if (e != NULL && errsto != NULL) { + fprintf(errsto, "%s: optionsfrom failed: %s\n", (*argvp)[0], e); + exit(2); + } + return e; +} + +/* + - dowork - do all the real work of optionsfrom + * Does not alter the existing arguments, but does relocate and alter + * the argv pointer vector. + */ +static const char * /* NULL for success, else string literal */ +dowork(filename, argcp, argvp, optind) +const char *filename; +int *argcp; /* pointer to argc */ +char ***argvp; /* pointer to argv */ +int optind; /* current optind, number of next argument */ +{ + char **newargv; + char **tmp; + int newargc; + int next; /* place for next argument */ + int room; /* how many more new arguments we can hold */ +# define SOME 10 /* first guess at how many we'll need */ + FILE *f; + int i; + const char *p; + struct work wa; /* for getanarg() */ + + f = fopen(filename, "r"); + if (f == NULL) + return "unable to open file"; + + newargc = *argcp + SOME; + newargv = malloc((newargc+1) * sizeof(char *)); + if (newargv == NULL) + return "unable to allocate memory"; + memcpy(newargv, *argvp, optind * sizeof(char *)); + room = SOME; + next = optind; + + newargv[next] = NULL; + wa.pending = NULL; + while ((p = getanarg(f, &wa, &newargv[next])) == NULL) { + if (room == 0) { + newargc += SOME; + tmp = realloc(newargv, (newargc+1) * sizeof(char *)); + if (tmp == NULL) { + p = "out of space for new argv"; + break; /* NOTE BREAK OUT */ + } + newargv = tmp; + room += SOME; + } + next++; + room--; + } + if (p != NULL && !feof(f)) { /* error of some kind */ + for (i = optind+1; i <= next; i++) + if (newargv[i] != NULL) + free(newargv[i]); + free(newargv); + fclose(f); + return p; + } + + fclose(f); + memcpy(newargv + next, *argvp + optind, + (*argcp+1-optind) * sizeof(char *)); + *argcp += next - optind; + *argvp = newargv; + return NULL; +} + +/* + - getanarg - get a malloced argument from the file + */ +static const char * /* NULL for success, else string literal */ +getanarg(f, w, linep) +FILE *f; +struct work *w; +char **linep; /* where to store pointer if successful */ +{ + size_t len; + char *p; + char *endp; + + while (w->pending == NULL) { /* no pending line */ + if ((w->line = getline(f, w->buf, sizeof(w->buf))) == NULL) + return "error in line read"; /* caller checks EOF */ + if (w->line[0] != '#' && + *(w->line + strspn(w->line, " \t")) != '\0') + w->pending = w->line; + } + + if (w->pending == w->line && w->line[0] != '-') { + /* fresh plain line */ + w->pending = NULL; + p = w->line; + endp = p + strlen(p); + if (*p == '"' && endp > p+1 && *(endp-1) == '"') { + p++; + endp--; + *endp = '\0'; + } + if (w->line == w->buf) { + *linep = malloc(endp - p + 1); + if (*linep == NULL) + return "out of memory for new line"; + strcpy(*linep, p); + } else /* getline already malloced it */ + *linep = p; + return NULL; + } + + /* chip off a piece of a pending line */ + p = w->pending; + p += strspn(p, " \t"); + endp = p + strcspn(p, " \t"); + len = endp - p; + if (*endp != '\0') { + *endp++ = '\0'; + endp += strspn(endp, " \t"); + } + /* endp now points to next real character, or to line-end NUL */ + *linep = malloc(len + 1); + if (*linep == NULL) { + if (w->line != w->buf) + free(w->line); + return "out of memory for new argument"; + } + strcpy(*linep, p); + if (*endp == '\0') { + w->pending = NULL; + if (w->line != w->buf) + free(w->line); + } else + w->pending = endp; + return NULL; +} + +/* + - getline - read a line from the file, trim newline off + */ +static char * /* pointer to line, NULL for eof/error */ +getline(f, buf, bufsize) +FILE *f; +char *buf; /* buffer to use, if convenient */ +size_t bufsize; /* size of buf */ +{ + size_t len; + + if (fgets(buf, bufsize, f) == NULL) + return NULL; + len = strlen(buf); + + if (len < bufsize-1 || buf[bufsize-1] == '\n') { + /* it fit */ + buf[len-1] = '\0'; + return buf; + } + + /* oh crud, buffer overflow */ + /* for now, to hell with it */ + return NULL; +} + + + +#ifdef TEST + +#include + +char usage[] = "Usage: tester [--foo] [--bar] [--optionsfrom file] arg ..."; +struct option opts[] = { + "foo", 0, NULL, 'f', + "bar", 0, NULL, 'b', + "builtin", 0, NULL, 'B', + "optionsfrom", 1, NULL, '+', + "help", 0, NULL, 'h', + "version", 0, NULL, 'v', + 0, 0, NULL, 0, +}; + +int +main(argc, argv) +int argc; +char *argv[]; +{ + int opt; + extern char *optarg; + extern int optind; + int errflg = 0; + const char *p; + int i; + FILE *errs = NULL; + + while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF) + switch (opt) { + case 'f': + case 'b': + break; + case 'B': + errs = stderr; + break; + case '+': /* optionsfrom */ + p = optionsfrom(optarg, &argc, &argv, optind, errs); + if (p != NULL) { + fprintf(stderr, "%s: optionsfrom error: %s\n", + argv[0], p); + exit(1); + } + break; + case 'h': /* help */ + printf("%s\n", usage); + exit(0); + break; + case 'v': /* version */ + printf("1\n"); + exit(0); + break; + case '?': + default: + errflg = 1; + break; + } + if (errflg) { + fprintf(stderr, "%s\n", usage); + exit(2); + } + + for (i = 1; i < argc; i++) + printf("%d: `%s'\n", i, argv[i]); + exit(0); +} + + +#endif /* TEST */ diff -urN linux-2.4.29/net/ipsec/libopenswan/pfkey.h linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey.h --- linux-2.4.29/net/ipsec/libopenswan/pfkey.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey.h Mon Nov 17 00:22:48 2003 @@ -0,0 +1,419 @@ +/* + * FreeS/WAN specific PF_KEY headers + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: pfkey.h,v 1.6 2003/11/16 23:22:48 ken Exp $ + */ + +#ifndef __NET_IPSEC_PF_KEY_H +#define __NET_IPSEC_PF_KEY_H +#ifdef __KERNEL__ +extern void pfkey_proto_init(struct net_proto *pro); +extern struct proto_ops pfkey_proto_ops; +typedef struct sock pfkey_sock; +extern int debug_pfkey; + +extern /* void */ int pfkey_init(void); +extern /* void */ int pfkey_cleanup(void); + +extern struct sock *pfkey_sock_list; +struct socket_list +{ + struct socket *socketp; + struct socket_list *next; +}; +extern int pfkey_list_insert_socket(struct socket*, struct socket_list**); +extern int pfkey_list_remove_socket(struct socket*, struct socket_list**); +extern struct socket_list *pfkey_open_sockets; +extern struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1]; + +/* + * There is a field-by-field copy in klips/net/ipsec/ipsec_alg.h + * please keep in sync until we migrate all support stuff + * to ipsec_alg objects + */ +struct supported +{ + uint16_t supported_alg_exttype; + uint8_t supported_alg_id; + uint8_t supported_alg_ivlen; + uint16_t supported_alg_minbits; + uint16_t supported_alg_maxbits; +}; +extern struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1]; +struct supported_list +{ + struct supported *supportedp; + struct supported_list *next; +}; +extern int pfkey_list_insert_supported(struct supported*, struct supported_list**); +extern int pfkey_list_remove_supported(struct supported*, struct supported_list**); + +/* +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + */ +struct sockaddr_key +{ + uint16_t key_family; /* PF_KEY */ + uint16_t key_pad; /* not used */ + uint32_t key_pid; /* process ID */ +}; +/* +#endif */ /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + */ + +struct pfkey_extracted_data +{ + struct ipsec_sa* tdb; + struct ipsec_sa* tdb2; + struct eroute *eroute; +}; + +extern int pfkey_register_reply(int satype, struct sadb_msg *); +extern int pfkey_upmsg(struct socket *, struct sadb_msg *); +extern int pfkey_expire(struct ipsec_sa *, int); +extern int pfkey_acquire(struct ipsec_sa *); +#endif /* __KERNEL__ */ + +extern uint8_t satype2proto(uint8_t satype); +extern uint8_t proto2satype(uint8_t proto); +extern char* satype2name(uint8_t satype); +extern char* proto2name(uint8_t proto); + +struct key_opt +{ + uint32_t key_pid; /* process ID */ + struct sock *sk; +}; + +#define key_pid(sk) ((struct key_opt*)&((sk)->protinfo))->key_pid + +#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t)) +#define BITS_PER_OCTET 8 +#define OCTETBITS 8 +#define PFKEYBITS 64 +#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */ +#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */ + +#define PFKEYv2_MAX_MSGSIZE 4096 + +/* + * PF_KEYv2 permitted and required extensions in and out bitmaps + */ +struct pf_key_ext_parsers_def { + int (*parser)(struct sadb_ext*); + char *parser_name; +}; + + +extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/]; +#define EXT_BITS_IN 0 +#define EXT_BITS_OUT 1 +#define EXT_BITS_PERM 0 +#define EXT_BITS_REQ 1 + +extern void pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]); +extern void pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]); +extern void pfkey_msg_free(struct sadb_msg **pfkey_msg); + +extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg, + struct pf_key_ext_parsers_def *ext_parsers[], + struct sadb_ext **extensions, + int dir); + +/* + * PF_KEYv2 build function prototypes + */ + +int +pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext, + uint8_t msg_type, + uint8_t satype, + uint8_t msg_errno, + uint32_t seq, + uint32_t pid); + +int +pfkey_sa_build(struct sadb_ext ** pfkey_ext, + uint16_t exttype, + uint32_t spi, /* in network order */ + uint8_t replay_window, + uint8_t sa_state, + uint8_t auth, + uint16_t encrypt, + uint32_t flags); + +int +pfkey_lifetime_build(struct sadb_ext ** pfkey_ext, + uint16_t exttype, + uint32_t allocations, + uint64_t bytes, + uint64_t addtime, + uint64_t usetime, + uint32_t packets); + +int +pfkey_address_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint8_t proto, + uint8_t prefixlen, + struct sockaddr* address); + +int +pfkey_key_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint16_t key_bits, + char* key); + +int +pfkey_ident_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint16_t ident_type, + uint64_t ident_id, + uint8_t ident_len, + char* ident_string); + +int +pfkey_sens_build(struct sadb_ext** pfkey_ext, + uint32_t dpd, + uint8_t sens_level, + uint8_t sens_len, + uint64_t* sens_bitmap, + uint8_t integ_level, + uint8_t integ_len, + uint64_t* integ_bitmap); + +int +pfkey_prop_build(struct sadb_ext** pfkey_ext, + uint8_t replay, + unsigned int comb_num, + struct sadb_comb* comb); + +int +pfkey_supported_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + unsigned int alg_num, + struct sadb_alg* alg); + +int +pfkey_spirange_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint32_t min, + uint32_t max); + +int +pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext); + +int +pfkey_x_satype_build(struct sadb_ext** pfkey_ext, + uint8_t satype); + +int pfkey_x_protocol_build(struct sadb_ext **, uint8_t); + + +int +pfkey_x_debug_build(struct sadb_ext** pfkey_ext, + uint32_t tunnel, + uint32_t netlink, + uint32_t xform, + uint32_t eroute, + uint32_t spi, + uint32_t radij, + uint32_t esp, + uint32_t ah, + uint32_t rcv, + uint32_t pfkey, + uint32_t ipcomp, + uint32_t verbose); + +#ifdef NAT_TRAVERSAL +#ifdef __KERNEL__ +extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16); +#endif /* __KERNEL__ */ +int +pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext, + uint8_t type); +int +pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint16_t port); +#endif + +int +pfkey_msg_build(struct sadb_msg** pfkey_msg, + struct sadb_ext* extensions[], + int dir); + +/* in pfkey_v2_debug.c - routines to decode numbers -> strings */ +const char * +pfkey_v2_sadb_ext_string(int extnum); + +const char * +pfkey_v2_sadb_type_string(int sadb_type); + + +#endif /* __NET_IPSEC_PF_KEY_H */ + +/* + * $Log: pfkey.h,v $ + * Revision 1.6 2003/11/16 23:22:48 ken + * We are now Openswan + * + * Revision 1.5 2003/09/22 12:26:50 ken + * Fix switch() where break; was missing + * Fix a few typing errors with 8bit and 16bit ints + * + * Revision 1.4 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.3 2002/09/05 03:53:52 ken + * Added NAT-T Patch + * + * Revision 1.2 2002/09/05 03:22:11 ken + * Applied freeswan-alg-0.8.0-BASE-common.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:19 ken + * 1.98b + * + * Revision 1.36 2002/01/20 20:34:49 mcr + * added pfkey_v2_sadb_type_string to decode sadb_type to string. + * + * Revision 1.35 2001/11/27 05:27:47 mcr + * pfkey parses are now maintained by a structure + * that includes their name for debug purposes. + * + * Revision 1.34 2001/11/26 09:23:53 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.33 2001/11/06 19:47:47 rgb + * Added packet parameter to lifetime and comb structures. + * + * Revision 1.32 2001/09/08 21:13:34 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.31 2001/06/14 19:35:16 rgb + * Update copyright date. + * + * Revision 1.30 2001/02/27 07:04:52 rgb + * Added satype2name prototype. + * + * Revision 1.29 2001/02/26 19:59:33 rgb + * Ditch unused sadb_satype2proto[], replaced by satype2proto(). + * + * Revision 1.28 2000/10/10 20:10:19 rgb + * Added support for debug_ipcomp and debug_verbose to klipsdebug. + * + * Revision 1.27 2000/09/21 04:20:45 rgb + * Fixed array size off-by-one error. (Thanks Svenning!) + * + * Revision 1.26 2000/09/12 03:26:05 rgb + * Added pfkey_acquire prototype. + * + * Revision 1.25 2000/09/08 19:21:28 rgb + * Fix pfkey_prop_build() parameter to be only single indirection. + * + * Revision 1.24 2000/09/01 18:46:42 rgb + * Added a supported algorithms array lists, one per satype and registered + * existing algorithms. + * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to + * list. + * + * Revision 1.23 2000/08/27 01:55:26 rgb + * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code. + * + * Revision 1.22 2000/08/20 21:39:23 rgb + * Added kernel prototypes for kernel funcitions pfkey_upmsg() and + * pfkey_expire(). + * + * Revision 1.21 2000/08/15 17:29:23 rgb + * Fixes from SZI to untested pfkey_prop_build(). + * + * Revision 1.20 2000/05/10 20:14:19 rgb + * Fleshed out sensitivity, proposal and supported extensions. + * + * Revision 1.19 2000/03/16 14:07:23 rgb + * Renamed ALIGN macro to avoid fighting with others in kernel. + * + * Revision 1.18 2000/01/22 23:24:06 rgb + * Added prototypes for proto2satype(), satype2proto() and proto2name(). + * + * Revision 1.17 2000/01/21 06:26:59 rgb + * Converted from double tdb arguments to one structure (extr) + * containing pointers to all temporary information structures. + * Added klipsdebug switching capability. + * Dropped unused argument to pfkey_x_satype_build(). + * + * Revision 1.16 1999/12/29 21:17:41 rgb + * Changed pfkey_msg_build() I/F to include a struct sadb_msg** + * parameter for cleaner manipulation of extensions[] and to guard + * against potential memory leaks. + * Changed the I/F to pfkey_msg_free() for the same reason. + * + * Revision 1.15 1999/12/09 23:12:54 rgb + * Added macro for BITS_PER_OCTET. + * Added argument to pfkey_sa_build() to do eroutes. + * + * Revision 1.14 1999/12/08 20:33:25 rgb + * Changed sa_family_t to uint16_t for 2.0.xx compatibility. + * + * Revision 1.13 1999/12/07 19:53:40 rgb + * Removed unused first argument from extension parsers. + * Changed __u* types to uint* to avoid use of asm/types.h and + * sys/types.h in userspace code. + * Added function prototypes for pfkey message and extensions + * initialisation and cleanup. + * + * Revision 1.12 1999/12/01 22:19:38 rgb + * Change pfkey_sa_build to accept an SPI in network byte order. + * + * Revision 1.11 1999/11/27 11:55:26 rgb + * Added extern sadb_satype2proto to enable moving protocol lookup table + * to lib/pfkey_v2_parse.c. + * Delete unused, moved typedefs. + * Add argument to pfkey_msg_parse() for direction. + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. + * + * Revision 1.10 1999/11/23 22:29:21 rgb + * This file has been moved in the distribution from klips/net/ipsec to + * lib. + * Add macros for dealing with alignment and rounding up more opaquely. + * The uint_t type defines have been moved to openswan.h to avoid + * chicken-and-egg problems. + * Add macros for dealing with alignment and rounding up more opaque. + * Added prototypes for using extention header bitmaps. + * Added prototypes of all the build functions. + * + * Revision 1.9 1999/11/20 21:59:48 rgb + * Moved socketlist type declarations and prototypes for shared use. + * Slightly modified scope of sockaddr_key declaration. + * + * Revision 1.8 1999/11/17 14:34:25 rgb + * Protect sa_family_t from being used in userspace with GLIBC<2. + * + * Revision 1.7 1999/10/27 19:40:35 rgb + * Add a maximum PFKEY packet size macro. + * + * Revision 1.6 1999/10/26 16:58:58 rgb + * Created a sockaddr_key and key_opt socket extension structures. + * + * Revision 1.5 1999/06/10 05:24:41 rgb + * Renamed variables to reduce confusion. + * + * Revision 1.4 1999/04/29 15:21:11 rgb + * Add pfkey support to debugging. + * Add return values to init and cleanup functions. + * + * Revision 1.3 1999/04/15 17:58:07 rgb + * Add RCSID labels. + * + */ diff -urN linux-2.4.29/net/ipsec/libopenswan/pfkey_v2_build.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey_v2_build.c --- linux-2.4.29/net/ipsec/libopenswan/pfkey_v2_build.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey_v2_build.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,1516 @@ +/* + * RFC2367 PF_KEYv2 Key management API message parser + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: pfkey_v2_build.c,v 1.8 2003/11/16 23:22:48 ken Exp $ + */ + +/* + * Template from klips/net/ipsec/ipsec/ipsec_parser.c. + */ + +char pfkey_v2_build_c_version[] = "$Id: pfkey_v2_build.c,v 1.8 2003/11/16 23:22:48 ken Exp $"; + +/* + * Some ugly stuff to allow consistent debugging code for use in the + * kernel and in user space +*/ + +#ifdef __KERNEL__ + +# include /* for printk */ + +# include "../ipsec_kversion.h" /* for malloc switch */ +# ifdef MALLOC_SLAB +# include /* kmalloc() */ +# else /* MALLOC_SLAB */ +# include /* kmalloc() */ +# endif /* MALLOC_SLAB */ +# include /* error codes */ +# include /* size_t */ +# include /* mark_bh */ + +# include /* struct device, and other headers */ +# include /* eth_type_trans */ +# include /* struct iphdr */ +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +# include /* struct ipv6hdr */ +# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ + +# define MALLOC(size) kmalloc(size, GFP_ATOMIC) +# define FREE(obj) kfree(obj) +# include +#else /* __KERNEL__ */ + +# include +# include +# include +# include +# include /* memset */ + +# include +# include "../pluto/constants.h" +# include "../pluto/defs.h" /* for PRINTF_LIKE */ +# include "../pluto/log.h" /* for debugging and DBG_log */ + +extern unsigned int debugging; /* bits selecting what to report */ +unsigned int pfkey_lib_debug = 0; + +/* #define PLUTO */ + +# ifdef PLUTO +# define DEBUGGING(args...) { DBG_log("pfkey_lib_debug:" args); } +# else +# define DEBUGGING(args...) if(pfkey_lib_debug) { printf("pfkey_lib_debug:" args); } else { ; } +# endif +# define MALLOC(size) malloc(size) +# define FREE(obj) free(obj) +#endif /* __KERNEL__ */ + +#include +#include + +#ifdef __KERNEL__ +# include "../radij.h" /* rd_nodes */ +# include "../ipsec_encap.h" /* sockaddr_encap */ +# include "../ipsec_netlink.h" /* KLIPS_PRINT */ +# define DEBUGGING(args...) \ + KLIPS_PRINT(debug_pfkey, "klips_debug:" args) +/* ((debug_pfkey) ? printk(KERN_INFO "klips_debug:" format , ## args) : 0) */ +#endif /* __KERNEL__ */ + + +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) + +void +pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]) +{ + int i; + + for (i = 0; i != SADB_EXT_MAX + 1; i++) { + extensions[i] = NULL; + } +} + +void +pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]) +{ + int i; + + if(!extensions) { + return; + } + + if(extensions[0]) { + memset(extensions[0], 0, sizeof(struct sadb_msg)); + FREE(extensions[0]); + extensions[0] = NULL; + } + + for (i = 1; i != SADB_EXT_MAX + 1; i++) { + if(extensions[i]) { + memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); + FREE(extensions[i]); + extensions[i] = NULL; + } + } +} + +void +pfkey_msg_free(struct sadb_msg **pfkey_msg) +{ + if(*pfkey_msg) { + memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); + FREE(*pfkey_msg); + *pfkey_msg = NULL; + } +} + +/* Default extension builders taken from the KLIPS code */ + +int +pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext, + uint8_t msg_type, + uint8_t satype, + uint8_t msg_errno, + uint32_t seq, + uint32_t pid) +{ + int error = 0; + struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext; + + DEBUGGING( + "pfkey_msg_hdr_build:\n"); + DEBUGGING( + "pfkey_msg_hdr_build: " + "on_entry &pfkey_ext=%p pfkey_ext=%p *pfkey_ext=%p.\n", + &pfkey_ext, + pfkey_ext, + *pfkey_ext); + /* sanity checks... */ + if(pfkey_msg) { + DEBUGGING( + "pfkey_msg_hdr_build: " + "why is pfkey_msg already pointing to something?\n"); + SENDERR(EINVAL); + } + + if(!msg_type) { + DEBUGGING( + "pfkey_msg_hdr_build: " + "msg type not set, must be non-zero..\n"); + SENDERR(EINVAL); + } + + if(msg_type > SADB_MAX) { + DEBUGGING( + "pfkey_msg_hdr_build: " + "msg type too large:%d.\n", + msg_type); + SENDERR(EINVAL); + } + + if(satype > SADB_SATYPE_MAX) { + DEBUGGING( + "pfkey_msg_hdr_build: " + "satype %d > max %d\n", + satype, SADB_SATYPE_MAX); + SENDERR(EINVAL); + } + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_msg = (struct sadb_msg*) + MALLOC(sizeof(struct sadb_msg)))) { + DEBUGGING( + "pfkey_msg_hdr_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_msg, 0, sizeof(struct sadb_msg)); + + pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; + + pfkey_msg->sadb_msg_type = msg_type; + pfkey_msg->sadb_msg_satype = satype; + + pfkey_msg->sadb_msg_version = PF_KEY_V2; + pfkey_msg->sadb_msg_errno = msg_errno; + pfkey_msg->sadb_msg_reserved = 0; + pfkey_msg->sadb_msg_seq = seq; + pfkey_msg->sadb_msg_pid = pid; + DEBUGGING( + "pfkey_msg_hdr_build: " + "on_exit &pfkey_ext=%p pfkey_ext=%p *pfkey_ext=%p.\n", + &pfkey_ext, + pfkey_ext, + *pfkey_ext); +errlab: + return error; +} + +int +pfkey_sa_build(struct sadb_ext ** pfkey_ext, + uint16_t exttype, + uint32_t spi, /* in network order */ + uint8_t replay_window, + uint8_t sa_state, + uint8_t auth, + uint16_t encrypt, + uint32_t flags) +{ + int error = 0; + struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext; + + DEBUGGING( + "pfkey_sa_build: " + "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n", + ntohl(spi), /* in network order */ + replay_window, + sa_state, + auth, + encrypt, + flags); + /* sanity checks... */ + if(pfkey_sa) { + DEBUGGING( + "pfkey_sa_build: " + "why is pfkey_sa already pointing to something?\n"); + SENDERR(EINVAL); + } + + if(exttype != SADB_EXT_SA && + exttype != SADB_X_EXT_SA2) { + DEBUGGING( + "pfkey_sa_build: " + "invalid exttype=%d.\n", + exttype); + SENDERR(EINVAL); + } + + if(replay_window > 64) { + DEBUGGING( + "pfkey_sa_build: " + "replay window size: %d -- must be 0 <= size <= 64\n", + replay_window); + SENDERR(EINVAL); + } + + if(auth > SADB_AALG_MAX) { + DEBUGGING( + "pfkey_sa_build: " + "auth=%d > SADB_AALG_MAX=%d.\n", + auth, + SADB_AALG_MAX); + SENDERR(EINVAL); + } + + if(encrypt > SADB_EALG_MAX) { + DEBUGGING( + "pfkey_sa_build: " + "encrypt=%d > SADB_EALG_MAX=%d.\n", + encrypt, + SADB_EALG_MAX); + SENDERR(EINVAL); + } + + if(sa_state > SADB_SASTATE_MAX) { + DEBUGGING( + "pfkey_sa_build: " + "sa_state=%d exceeds MAX=%d.\n", + sa_state, + SADB_SASTATE_MAX); + SENDERR(EINVAL); + } + + if(sa_state == SADB_SASTATE_DEAD) { + DEBUGGING( + "pfkey_sa_build: " + "sa_state=%d is DEAD=%d is not allowed.\n", + sa_state, + SADB_SASTATE_DEAD); + SENDERR(EINVAL); + } + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_sa = (struct sadb_sa*) + MALLOC(sizeof(struct sadb_sa)))) { + DEBUGGING( + "pfkey_sa_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_sa, 0, sizeof(struct sadb_sa)); + + pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN; + pfkey_sa->sadb_sa_exttype = exttype; + pfkey_sa->sadb_sa_spi = spi; + pfkey_sa->sadb_sa_replay = replay_window; + pfkey_sa->sadb_sa_state = sa_state; + pfkey_sa->sadb_sa_auth = auth; + pfkey_sa->sadb_sa_encrypt = encrypt; + pfkey_sa->sadb_sa_flags = flags; + +errlab: + return error; +} + +int +pfkey_lifetime_build(struct sadb_ext ** pfkey_ext, + uint16_t exttype, + uint32_t allocations, + uint64_t bytes, + uint64_t addtime, + uint64_t usetime, + uint32_t packets) +{ + int error = 0; + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext; + + DEBUGGING( + "pfkey_lifetime_build:\n"); + /* sanity checks... */ + if(pfkey_lifetime) { + DEBUGGING( + "pfkey_lifetime_build: " + "why is pfkey_lifetime already pointing to something?\n"); + SENDERR(EINVAL); + } + + if(exttype != SADB_EXT_LIFETIME_CURRENT && + exttype != SADB_EXT_LIFETIME_HARD && + exttype != SADB_EXT_LIFETIME_SOFT) { + DEBUGGING( + "pfkey_lifetime_build: " + "invalid exttype=%d.\n", + exttype); + SENDERR(EINVAL); + } + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_lifetime = (struct sadb_lifetime*) + MALLOC(sizeof(struct sadb_lifetime)))) { + DEBUGGING( + "pfkey_lifetime_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime)); + + pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN; + pfkey_lifetime->sadb_lifetime_exttype = exttype; + pfkey_lifetime->sadb_lifetime_allocations = allocations; + pfkey_lifetime->sadb_lifetime_bytes = bytes; + pfkey_lifetime->sadb_lifetime_addtime = addtime; + pfkey_lifetime->sadb_lifetime_usetime = usetime; + pfkey_lifetime->sadb_x_lifetime_packets = packets; + +errlab: + return error; +} + +int +pfkey_address_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint8_t proto, + uint8_t prefixlen, + struct sockaddr* address) +{ + int error = 0; + int saddr_len = 0; + char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/]; + struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext; + + DEBUGGING( + "pfkey_address_build: " + "exttype=%d proto=%d prefixlen=%d\n", + exttype, + proto, + prefixlen); + /* sanity checks... */ + if(pfkey_address) { + DEBUGGING( + "pfkey_address_build: " + "why is pfkey_address already pointing to something?\n"); + SENDERR(EINVAL); + } + + if (!address) { + DEBUGGING("pfkey_address_build: " + "address is NULL\n"); + SENDERR(EINVAL); + } + + switch(exttype) { + case SADB_EXT_ADDRESS_SRC: + case SADB_EXT_ADDRESS_DST: + case SADB_EXT_ADDRESS_PROXY: + case SADB_X_EXT_ADDRESS_DST2: + case SADB_X_EXT_ADDRESS_SRC_FLOW: + case SADB_X_EXT_ADDRESS_DST_FLOW: + case SADB_X_EXT_ADDRESS_SRC_MASK: + case SADB_X_EXT_ADDRESS_DST_MASK: +#ifdef NAT_TRAVERSAL + case SADB_X_EXT_NAT_T_OA: +#endif + break; + default: + DEBUGGING( + "pfkey_address_build: " + "unrecognised ext_type=%d.\n", + exttype); + SENDERR(EINVAL); + } + + switch(address->sa_family) { + case AF_INET: + DEBUGGING( + "pfkey_address_build: " + "found address family AF_INET.\n"); + saddr_len = sizeof(struct sockaddr_in); + sprintf(ipaddr_txt, "%d.%d.%d.%d:%d" + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF + , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF + , ntohs(((struct sockaddr_in*)address)->sin_port)); + break; + case AF_INET6: + DEBUGGING( + "pfkey_address_build: " + "found address family AF_INET6.\n"); + saddr_len = sizeof(struct sockaddr_in6); + sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x" + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0]) + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1]) + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2]) + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3]) + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4]) + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5]) + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6]) + , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7]) + , ntohs(((struct sockaddr_in6*)address)->sin6_port)); + break; + default: + DEBUGGING( + "pfkey_address_build: " + "address->sa_family=%d not supported.\n", + address->sa_family); + SENDERR(EPFNOSUPPORT); + } + + DEBUGGING( + "pfkey_address_build: " + "found address=%s.\n", + ipaddr_txt); + if(prefixlen != 0) { + DEBUGGING( + "pfkey_address_build: " + "address prefixes not supported yet.\n"); + SENDERR(EAFNOSUPPORT); /* not supported yet */ + } + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_address = (struct sadb_address*) + MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN) ))) { + DEBUGGING( + "pfkey_lifetime_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_address, + 0, + ALIGN_N(sizeof(struct sadb_address) + saddr_len, + IPSEC_PFKEYv2_ALIGN)); + + pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len, + IPSEC_PFKEYv2_ALIGN); + + pfkey_address->sadb_address_exttype = exttype; + pfkey_address->sadb_address_proto = proto; + pfkey_address->sadb_address_prefixlen = prefixlen; + pfkey_address->sadb_address_reserved = 0; + + memcpy((char*)pfkey_address + sizeof(struct sadb_address), + address, + saddr_len); + +#if 0 + for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) { + pfkey_address_s_ska.sin_zero[i] = 0; + } +#endif + DEBUGGING( + "pfkey_address_build: " + "successful.\n"); + + errlab: + return error; +} + +int +pfkey_key_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint16_t key_bits, + char* key) +{ + int error = 0; + struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext; + + DEBUGGING( + "pfkey_key_build:\n"); + /* sanity checks... */ + if(pfkey_key) { + DEBUGGING( + "pfkey_key_build: " + "why is pfkey_key already pointing to something?\n"); + SENDERR(EINVAL); + } + + if(!key_bits) { + DEBUGGING( + "pfkey_key_build: " + "key_bits is zero, it must be non-zero.\n"); + SENDERR(EINVAL); + } + + if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) { + DEBUGGING( + "pfkey_key_build: " + "unsupported extension type=%d.\n", + exttype); + SENDERR(EINVAL); + } + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_key = (struct sadb_key*) + MALLOC(sizeof(struct sadb_key) + + DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN))) { + DEBUGGING( + "pfkey_key_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_key, + 0, + sizeof(struct sadb_key) + + DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN); + + pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits, + 64); + pfkey_key->sadb_key_exttype = exttype; + pfkey_key->sadb_key_bits = key_bits; + pfkey_key->sadb_key_reserved = 0; + memcpy((char*)pfkey_key + sizeof(struct sadb_key), + key, + DIVUP(key_bits, 8)); + +errlab: + return error; +} + +int +pfkey_ident_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint16_t ident_type, + uint64_t ident_id, + uint8_t ident_len, + char* ident_string) +{ + int error = 0; + struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext; + int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); + + DEBUGGING( + "pfkey_ident_build:\n"); + /* sanity checks... */ + if(pfkey_ident) { + DEBUGGING( + "pfkey_ident_build: " + "why is pfkey_ident already pointing to something?\n"); + SENDERR(EINVAL); + } + + if( ! ((exttype == SADB_EXT_IDENTITY_SRC) || + (exttype == SADB_EXT_IDENTITY_DST))) { + DEBUGGING( + "pfkey_ident_build: " + "unsupported extension type=%d.\n", + exttype); + SENDERR(EINVAL); + } + + if((ident_type == SADB_IDENTTYPE_RESERVED)) { + DEBUGGING( + "pfkey_ident_build: " + "ident_type must be non-zero.\n"); + SENDERR(EINVAL); + } + + if(ident_type > SADB_IDENTTYPE_MAX) { + DEBUGGING( + "pfkey_ident_build: " + "identtype=%d out of range.\n", + ident_type); + SENDERR(EINVAL); + } + + if(((ident_type == SADB_IDENTTYPE_PREFIX) || + (ident_type == SADB_IDENTTYPE_FQDN)) && + !ident_string) { + DEBUGGING( + "pfkey_ident_build: " + "string required to allocate size of extension.\n"); + SENDERR(EINVAL); + } + +#if 0 + if((ident_type == SADB_IDENTTYPE_USERFQDN) ) { + } +#endif + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_ident = (struct sadb_ident*) + MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN))) { + DEBUGGING( + "pfkey_ident_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN); + + pfkey_ident->sadb_ident_len = ident_len; + pfkey_ident->sadb_ident_exttype = exttype; + pfkey_ident->sadb_ident_type = ident_type; + pfkey_ident->sadb_ident_reserved = 0; + pfkey_ident->sadb_ident_id = ident_id; + memcpy((char*)pfkey_ident + sizeof(struct sadb_ident), + ident_string, + data_len); + +errlab: + return error; +} + +int +pfkey_sens_build(struct sadb_ext** pfkey_ext, + uint32_t dpd, + uint8_t sens_level, + uint8_t sens_len, + uint64_t* sens_bitmap, + uint8_t integ_level, + uint8_t integ_len, + uint64_t* integ_bitmap) +{ + int error = 0; + struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext; + int i; + uint64_t* bitmap; + + DEBUGGING( + "pfkey_sens_build:\n"); + /* sanity checks... */ + if(pfkey_sens) { + DEBUGGING( + "pfkey_sens_build: " + "why is pfkey_sens already pointing to something?\n"); + SENDERR(EINVAL); + } + + DEBUGGING( + "pfkey_sens_build: " + "Sorry, I can't build exttype=%d yet.\n", + (*pfkey_ext)->sadb_ext_type); + SENDERR(EINVAL); /* don't process these yet */ + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_sens = (struct sadb_sens*) + MALLOC(sizeof(struct sadb_sens) + + (sens_len + integ_len) * sizeof(uint64_t)))) { + DEBUGGING( + "pfkey_sens_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_sens, + 0, + sizeof(struct sadb_sens) + + (sens_len + integ_len) * sizeof(uint64_t)); + + pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) + + (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN; + pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY; + pfkey_sens->sadb_sens_dpd = dpd; + pfkey_sens->sadb_sens_sens_level = sens_level; + pfkey_sens->sadb_sens_sens_len = sens_len; + pfkey_sens->sadb_sens_integ_level = integ_level; + pfkey_sens->sadb_sens_integ_len = integ_len; + pfkey_sens->sadb_sens_reserved = 0; + + bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens)); + for(i = 0; i < sens_len; i++) { + *bitmap = sens_bitmap[i]; + bitmap++; + } + for(i = 0; i < integ_len; i++) { + *bitmap = integ_bitmap[i]; + bitmap++; + } + +errlab: + return error; +} + +int +pfkey_prop_build(struct sadb_ext** pfkey_ext, + uint8_t replay, + unsigned int comb_num, + struct sadb_comb* comb) +{ + int error = 0; + int i; + struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext; + struct sadb_comb *combp; + + DEBUGGING( + "pfkey_prop_build:\n"); + /* sanity checks... */ + if(pfkey_prop) { + DEBUGGING( + "pfkey_prop_build: " + "why is pfkey_prop already pointing to something?\n"); + SENDERR(EINVAL); + } + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_prop = (struct sadb_prop*) + MALLOC(sizeof(struct sadb_prop) + + comb_num * sizeof(struct sadb_comb)))) { + DEBUGGING( + "pfkey_prop_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_prop, + 0, + sizeof(struct sadb_prop) + + comb_num * sizeof(struct sadb_comb)); + + pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) + + comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN; + + pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL; + pfkey_prop->sadb_prop_replay = replay; + + for(i=0; i<3; i++) { + pfkey_prop->sadb_prop_reserved[i] = 0; + } + + combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop)); + for(i = 0; i < comb_num; i++) { + memcpy (combp, &(comb[i]), sizeof(struct sadb_comb)); + combp++; + } + +#if 0 + uint8_t sadb_comb_auth; + uint8_t sadb_comb_encrypt; + uint16_t sadb_comb_flags; + uint16_t sadb_comb_auth_minbits; + uint16_t sadb_comb_auth_maxbits; + uint16_t sadb_comb_encrypt_minbits; + uint16_t sadb_comb_encrypt_maxbits; + uint32_t sadb_comb_reserved; + uint32_t sadb_comb_soft_allocations; + uint32_t sadb_comb_hard_allocations; + uint64_t sadb_comb_soft_bytes; + uint64_t sadb_comb_hard_bytes; + uint64_t sadb_comb_soft_addtime; + uint64_t sadb_comb_hard_addtime; + uint64_t sadb_comb_soft_usetime; + uint64_t sadb_comb_hard_usetime; + uint32_t sadb_comb_soft_packets; + uint32_t sadb_comb_hard_packets; +#endif +errlab: + return error; +} + +int +pfkey_supported_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + unsigned int alg_num, + struct sadb_alg* alg) +{ + int error = 0; + unsigned int i; + struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext; + struct sadb_alg *pfkey_alg; + + /* sanity checks... */ + if(pfkey_supported) { + DEBUGGING( + "pfkey_supported_build: " + "why is pfkey_supported already pointing to something?\n"); + SENDERR(EINVAL); + } + + if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) { + DEBUGGING( + "pfkey_supported_build: " + "unsupported extension type=%d.\n", + exttype); + SENDERR(EINVAL); + } + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_supported = (struct sadb_supported*) + MALLOC(sizeof(struct sadb_supported) + + alg_num * + sizeof(struct sadb_alg)))) { + DEBUGGING( + "pfkey_supported_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_supported, + 0, + sizeof(struct sadb_supported) + + alg_num * + sizeof(struct sadb_alg)); + + pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) + + alg_num * + sizeof(struct sadb_alg)) / + IPSEC_PFKEYv2_ALIGN; + pfkey_supported->sadb_supported_exttype = exttype; + pfkey_supported->sadb_supported_reserved = 0; + + pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported)); + for(i = 0; i < alg_num; i++) { + memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg)); + pfkey_alg->sadb_alg_reserved = 0; + pfkey_alg++; + } + +#if 0 + DEBUGGING( + "pfkey_supported_build: " + "Sorry, I can't build exttype=%d yet.\n", + (*pfkey_ext)->sadb_ext_type); + SENDERR(EINVAL); /* don't process these yet */ + + uint8_t sadb_alg_id; + uint8_t sadb_alg_ivlen; + uint16_t sadb_alg_minbits; + uint16_t sadb_alg_maxbits; + uint16_t sadb_alg_reserved; +#endif +errlab: + return error; +} + +int +pfkey_spirange_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint32_t min, /* in network order */ + uint32_t max) /* in network order */ +{ + int error = 0; + struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext; + + /* sanity checks... */ + if(pfkey_spirange) { + DEBUGGING( + "pfkey_spirange_build: " + "why is pfkey_spirange already pointing to something?\n"); + SENDERR(EINVAL); + } + + if(ntohl(max) < ntohl(min)) { + DEBUGGING( + "pfkey_spirange_build: " + "minspi=%08x must be < maxspi=%08x.\n", + ntohl(min), + ntohl(max)); + SENDERR(EINVAL); + } + + if(ntohl(min) <= 255) { + DEBUGGING( + "pfkey_spirange_build: " + "minspi=%08x must be > 255.\n", + ntohl(min)); + SENDERR(EEXIST); + } + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_spirange = (struct sadb_spirange*) + MALLOC(sizeof(struct sadb_spirange)))) { + DEBUGGING( + "pfkey_spirange_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_spirange, + 0, + sizeof(struct sadb_spirange)); + + pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN; + + pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE; + pfkey_spirange->sadb_spirange_min = min; + pfkey_spirange->sadb_spirange_max = max; + pfkey_spirange->sadb_spirange_reserved = 0; + errlab: + return error; +} + +int +pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext) +{ + int error = 0; + struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext; + + /* sanity checks... */ + if(pfkey_x_kmprivate) { + DEBUGGING( + "pfkey_x_kmprivate_build: " + "why is pfkey_x_kmprivate already pointing to something?\n"); + SENDERR(EINVAL); + } + + pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0; + + DEBUGGING( + "pfkey_x_kmprivate_build: " + "Sorry, I can't build exttype=%d yet.\n", + (*pfkey_ext)->sadb_ext_type); + SENDERR(EINVAL); /* don't process these yet */ + + if(!(*pfkey_ext = (struct sadb_ext*) + pfkey_x_kmprivate = (struct sadb_x_kmprivate*) + MALLOC(sizeof(struct sadb_x_kmprivate)))) { + DEBUGGING( + "pfkey_x_kmprivate_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_x_kmprivate, + 0, + sizeof(struct sadb_x_kmprivate)); + + pfkey_x_kmprivate->sadb_x_kmprivate_len = + sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN; + + pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE; + pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0; +errlab: + return error; +} + +int +pfkey_x_satype_build(struct sadb_ext** pfkey_ext, + uint8_t satype) +{ + int error = 0; + int i; + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext; + + DEBUGGING( + "pfkey_x_satype_build:\n"); + /* sanity checks... */ + if(pfkey_x_satype) { + DEBUGGING( + "pfkey_x_satype_build: " + "why is pfkey_x_satype already pointing to something?\n"); + SENDERR(EINVAL); + } + + if(!satype) { + DEBUGGING( + "pfkey_x_satype_build: " + "SA type not set, must be non-zero.\n"); + SENDERR(EINVAL); + } + + if(satype > SADB_SATYPE_MAX) { + DEBUGGING( + "pfkey_x_satype_build: " + "satype %d > max %d\n", + satype, SADB_SATYPE_MAX); + SENDERR(EINVAL); + } + + if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_satype = (struct sadb_x_satype*) + MALLOC(sizeof(struct sadb_x_satype)))) { + DEBUGGING( + "pfkey_x_satype_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + memset(pfkey_x_satype, + 0, + sizeof(struct sadb_x_satype)); + + pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN; + + pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2; + pfkey_x_satype->sadb_x_satype_satype = satype; + for(i=0; i<3; i++) { + pfkey_x_satype->sadb_x_satype_reserved[i] = 0; + } + +errlab: + return error; +} + +int +pfkey_x_debug_build(struct sadb_ext** pfkey_ext, + uint32_t tunnel, + uint32_t netlink, + uint32_t xform, + uint32_t eroute, + uint32_t spi, + uint32_t radij, + uint32_t esp, + uint32_t ah, + uint32_t rcv, + uint32_t pfkey, + uint32_t ipcomp, + uint32_t verbose) +{ + int error = 0; + int i; + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext; + + DEBUGGING( + "pfkey_x_debug_build:\n"); + /* sanity checks... */ + if(pfkey_x_debug) { + DEBUGGING( + "pfkey_x_debug_build: " + "why is pfkey_x_debug already pointing to something?\n"); + SENDERR(EINVAL); + } + + DEBUGGING( + "pfkey_x_debug_build: " + "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", + tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose); + + if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_debug = (struct sadb_x_debug*) + MALLOC(sizeof(struct sadb_x_debug)))) { + DEBUGGING( + "pfkey_x_debug_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } +#if 0 + memset(pfkey_x_debug, + 0, + sizeof(struct sadb_x_debug)); +#endif + + pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN; + pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG; + + pfkey_x_debug->sadb_x_debug_tunnel = tunnel; + pfkey_x_debug->sadb_x_debug_netlink = netlink; + pfkey_x_debug->sadb_x_debug_xform = xform; + pfkey_x_debug->sadb_x_debug_eroute = eroute; + pfkey_x_debug->sadb_x_debug_spi = spi; + pfkey_x_debug->sadb_x_debug_radij = radij; + pfkey_x_debug->sadb_x_debug_esp = esp; + pfkey_x_debug->sadb_x_debug_ah = ah; + pfkey_x_debug->sadb_x_debug_rcv = rcv; + pfkey_x_debug->sadb_x_debug_pfkey = pfkey; + pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp; + pfkey_x_debug->sadb_x_debug_verbose = verbose; + + for(i=0; i<4; i++) { + pfkey_x_debug->sadb_x_debug_reserved[i] = 0; + } + +errlab: + return error; +} + +#ifdef NAT_TRAVERSAL +int +pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext, + uint8_t type) +{ + int error = 0; + int i; + struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext; + + DEBUGGING( + "pfkey_x_nat_t_type_build:\n"); + /* sanity checks... */ + if(pfkey_x_nat_t_type) { + DEBUGGING( + "pfkey_x_nat_t_type_build: " + "why is pfkey_x_nat_t_type already pointing to something?\n"); + SENDERR(EINVAL); + } + + DEBUGGING( + "pfkey_x_nat_t_type_build: " + "type=%d\n", type); + + if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*) + MALLOC(sizeof(struct sadb_x_nat_t_type)))) { + DEBUGGING( + "pfkey_x_nat_t_type_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + + pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN; + pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE; + pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type; + for(i=0; i<3; i++) { + pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0; + } + +errlab: + return error; +} +int +pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext, + uint16_t exttype, + uint16_t port) +{ + int error = 0; + struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext; + + DEBUGGING( + "pfkey_x_nat_t_port_build:\n"); + /* sanity checks... */ + if(pfkey_x_nat_t_port) { + DEBUGGING( + "pfkey_x_nat_t_port_build: " + "why is pfkey_x_nat_t_port already pointing to something?\n"); + SENDERR(EINVAL); + } + + switch(exttype) { + case SADB_X_EXT_NAT_T_SPORT: + case SADB_X_EXT_NAT_T_DPORT: + break; + default: + DEBUGGING( + "pfkey_nat_t_port_build: " + "unrecognised ext_type=%d.\n", + exttype); + SENDERR(EINVAL); + } + + DEBUGGING( + "pfkey_x_nat_t_port_build: " + "ext=%d, port=%d\n", exttype, port); + + if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*) + MALLOC(sizeof(struct sadb_x_nat_t_port)))) { + DEBUGGING( + "pfkey_x_nat_t_port_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + + pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN; + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype; + pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port; + pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0; + +errlab: + return error; +} +#endif + +int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext, + uint8_t protocol) +{ + int error = 0; + struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext; + DEBUGGING("pfkey_x_protocol_build: protocol=%u\n", protocol); + /* sanity checks... */ + if (p != 0) { + DEBUGGING("pfkey_x_protocol_build: bogus protocol pointer\n"); + SENDERR(EINVAL); + } + if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) { + DEBUGGING("pfkey_build: memory allocation failed\n"); + SENDERR(ENOMEM); + } + *pfkey_ext = (struct sadb_ext *)p; + p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t); + p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL; + p->sadb_protocol_proto = protocol; + p->sadb_protocol_flags = 0; + p->sadb_protocol_reserved2 = 0; + errlab: + return error; +} + +#if I_DONT_THINK_THIS_WILL_BE_USEFUL +int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*) + = +{ + NULL, /* pfkey_msg_build, */ + pfkey_sa_build, + pfkey_lifetime_build, + pfkey_lifetime_build, + pfkey_lifetime_build, + pfkey_address_build, + pfkey_address_build, + pfkey_address_build, + pfkey_key_build, + pfkey_key_build, + pfkey_ident_build, + pfkey_ident_build, + pfkey_sens_build, + pfkey_prop_build, + pfkey_supported_build, + pfkey_supported_build, + pfkey_spirange_build, + pfkey_x_kmprivate_build, + pfkey_x_satype_build, + pfkey_sa_build, + pfkey_address_build, + pfkey_address_build, + pfkey_address_build, + pfkey_address_build, + pfkey_address_build, + pfkey_x_ext_debug_build +}; +#endif + +int +pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir) +{ + int error = 0; + int ext; + int total_size; + struct sadb_ext *pfkey_ext; + int extensions_seen = 0; + struct sadb_ext *extensions_check[SADB_EXT_MAX + 1]; + + if(!extensions[0]) { + DEBUGGING( + "pfkey_msg_build: " + "extensions[0] must be specified (struct sadb_msg).\n"); + SENDERR(EINVAL); + } + + total_size = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; + for(ext = 1; ext <= SADB_EXT_MAX; ext++) { + if(extensions[ext]) { + total_size += (extensions[ext])->sadb_ext_len; + } + } + + if(!(*pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN))) { + DEBUGGING( + "pfkey_msg_build: " + "memory allocation failed\n"); + SENDERR(ENOMEM); + } + + DEBUGGING( + "pfkey_msg_build: " + "pfkey_msg=%p allocated %lu bytes, &(extensions[0])=%p\n", + *pfkey_msg, + (unsigned long) (total_size * IPSEC_PFKEYv2_ALIGN), + &(extensions[0])); + memcpy(*pfkey_msg, + extensions[0], + sizeof(struct sadb_msg)); + (*pfkey_msg)->sadb_msg_len = total_size; + (*pfkey_msg)->sadb_msg_reserved = 0; + extensions_seen = 1 ; + + pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg)); + + for(ext = 1; ext <= SADB_EXT_MAX; ext++) { + /* copy from extension[ext] to buffer */ + if(extensions[ext]) { + /* Is this type of extension permitted for this type of message? */ + if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] & + 1<sadb_msg_type], + 1<sadb_ext_len * IPSEC_PFKEYv2_ALIGN), + ext, + (extensions[ext]), + pfkey_ext); + memcpy(pfkey_ext, + extensions[ext], + (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); + ((char*)pfkey_ext) += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN; + /* Mark that we have seen this extension and remember the header location */ + extensions_seen |= ( 1 << ext ); + } + } + + /* check required extensions */ + DEBUGGING( + "pfkey_msg_build: " + "extensions permitted=%08x, seen=%08x, required=%08x.\n", + extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type], + extensions_seen, + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]); + + if((extensions_seen & + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) != + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) { + DEBUGGING( + "pfkey_msg_build: " + "required extensions missing:%08x.\n", + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] - + (extensions_seen & + extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) ); + SENDERR(EINVAL); + } + + if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) { + DEBUGGING( + "pfkey_msg_build: " + "Trouble parsing newly built pfkey message, error=%d.\n", + error); + SENDERR(-error); + } + +errlab: + + return error; +} + +/* + * $Log: pfkey_v2_build.c,v $ + * Revision 1.8 2003/11/16 23:22:48 ken + * We are now Openswan + * + * Revision 1.7 2003/10/17 09:26:35 ken + * 64bit fixes + * + * Revision 1.6 2003/09/30 00:26:02 ken + * Tuomo Soini's NAT-T 0.6 cleanup patch + * Fixes a number of #ifdefs around NAT-T, and brings a few other other cleanups in + * + * Revision 1.5 2003/09/22 12:26:50 ken + * Fix switch() where break; was missing + * Fix a few typing errors with 8bit and 16bit ints + * + * Revision 1.4 2003/02/07 13:14:25 ken + * Pullin jjo's ALG 0.8.1rc branch + * + * Revision 1.3.2.1 2003/02/07 01:47:12 jjo + * . some #ifdef's tweaking to allow compilation without NAT_TRAVERSAL + * + * Revision 1.3 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.2 2002/09/05 03:53:53 ken + * Added NAT-T Patch + * + * Revision 1.1.1.1 2002/09/05 03:13:20 ken + * 1.98b + * + * Revision 1.31 2002/01/29 22:25:35 rgb + * Re-add ipsec_kversion.h to keep MALLOC happy. + * + * Revision 1.30 2002/01/29 01:59:09 mcr + * removal of kversions.h - sources that needed it now use ipsec_param.h. + * updating of IPv6 structures to match latest in6.h version. + * removed dead code from openswan.h that also duplicated kversions.h + * code. + * + * Revision 1.29 2001/12/19 21:06:09 rgb + * Added port numbers to pfkey_address_build() debugging. + * + * Revision 1.28 2001/11/06 19:47:47 rgb + * Added packet parameter to lifetime and comb structures. + * + * Revision 1.27 2001/10/18 04:45:24 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/openswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.26 2001/09/08 21:13:34 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.25 2001/06/14 19:35:16 rgb + * Update copyright date. + * + * Revision 1.24 2001/03/20 03:49:45 rgb + * Ditch superfluous debug_pfkey declaration. + * Move misplaced openswan.h inclusion for kernel case. + * + * Revision 1.23 2001/03/16 07:41:50 rgb + * Put openswan.h include before pluto includes. + * + * Revision 1.22 2001/02/27 22:24:56 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.21 2000/11/17 18:10:30 rgb + * Fixed bugs mostly relating to spirange, to treat all spi variables as + * network byte order since this is the way PF_KEYv2 stored spis. + * + * Revision 1.20 2000/10/12 00:02:39 rgb + * Removed 'format, ##' nonsense from debug macros for RH7.0. + * + * Revision 1.19 2000/10/10 20:10:20 rgb + * Added support for debug_ipcomp and debug_verbose to klipsdebug. + * + * Revision 1.18 2000/09/12 18:59:54 rgb + * Added Gerhard's IPv6 support to pfkey parts of libfreeswan. + * + * Revision 1.17 2000/09/12 03:27:00 rgb + * Moved DEBUGGING definition to compile kernel with debug off. + * + * Revision 1.16 2000/09/08 19:22:12 rgb + * Fixed pfkey_prop_build() parameter to be only single indirection. + * Fixed struct alg copy. + * + * Revision 1.15 2000/08/20 21:40:01 rgb + * Added an address parameter sanity check to pfkey_address_build(). + * + * Revision 1.14 2000/08/15 17:29:23 rgb + * Fixes from SZI to untested pfkey_prop_build(). + * + * Revision 1.13 2000/06/02 22:54:14 rgb + * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. + * + * Revision 1.12 2000/05/10 19:24:01 rgb + * Fleshed out sensitivity, proposal and supported extensions. + * + * Revision 1.11 2000/03/16 14:07:23 rgb + * Renamed ALIGN macro to avoid fighting with others in kernel. + * + * Revision 1.10 2000/01/24 21:14:35 rgb + * Added disabled pluto pfkey lib debug flag. + * + * Revision 1.9 2000/01/21 06:27:32 rgb + * Added address cases for eroute flows. + * Removed unused code. + * Dropped unused argument to pfkey_x_satype_build(). + * Indented compiler directives for readability. + * Added klipsdebug switching capability. + * Fixed SADB_EXT_MAX bug not permitting last extension access. + * + * Revision 1.8 1999/12/29 21:17:41 rgb + * Changed pfkey_msg_build() I/F to include a struct sadb_msg** + * parameter for cleaner manipulation of extensions[] and to guard + * against potential memory leaks. + * Changed the I/F to pfkey_msg_free() for the same reason. + * + * Revision 1.7 1999/12/09 23:12:20 rgb + * Removed unused cruft. + * Added argument to pfkey_sa_build() to do eroutes. + * Fixed exttype check in as yet unused pfkey_lifetime_build(). + * + * Revision 1.6 1999/12/07 19:54:29 rgb + * Removed static pluto debug flag. + * Added functions for pfkey message and extensions initialisation + * and cleanup. + * + * Revision 1.5 1999/12/01 22:20:06 rgb + * Changed pfkey_sa_build to accept an SPI in network byte order. + * Added to quiet userspace compiler. + * Moved pfkey_lib_debug variable into the library. + * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work. + * Added extension assembly debugging. + * Isolated assignment with brackets to be sure of scope. + * + * Revision 1.4 1999/11/27 11:57:35 rgb + * Added ipv6 headers. + * Remove over-zealous algorithm sanity checkers from pfkey_sa_build. + * Debugging error messages added. + * Fixed missing auth and encrypt assignment bug. + * Add argument to pfkey_msg_parse() for direction. + * Move parse-after-build check inside pfkey_msg_build(). + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. + * Add CVS log entry to bottom of file. + * + */ diff -urN linux-2.4.29/net/ipsec/libopenswan/pfkey_v2_debug.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey_v2_debug.c --- linux-2.4.29/net/ipsec/libopenswan/pfkey_v2_debug.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey_v2_debug.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,170 @@ +/* + * @(#) pfkey version 2 debugging messages + * + * Copyright (C) 2001 Richard Guy Briggs + * and Michael Richardson + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: pfkey_v2_debug.c,v 1.3 2003/11/16 23:22:48 ken Exp $ + * + */ + +#ifdef __KERNEL__ + +# include /* for printk */ + +# include "../ipsec_kversion.h" /* for malloc switch */ +# ifdef MALLOC_SLAB +# include /* kmalloc() */ +# else /* MALLOC_SLAB */ +# include /* kmalloc() */ +# endif /* MALLOC_SLAB */ +# include /* error codes */ +# include /* size_t */ +# include /* mark_bh */ + +# include /* struct device, and other headers */ +# include /* eth_type_trans */ +extern int debug_pfkey; + +#else /* __KERNEL__ */ + +# include +# include +# include + +#endif /* __KERNEL__ */ + +#include "openswan.h" +#include "pfkeyv2.h" +#include "pfkey.h" + +/* + * This file provides ASCII translations of PF_KEY magic numbers. + * + */ + +static char *pfkey_sadb_ext_strings[]={ + "reserved", /* SADB_EXT_RESERVED 0 */ + "security-association", /* SADB_EXT_SA 1 */ + "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */ + "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */ + "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */ + "source-address", /* SADB_EXT_ADDRESS_SRC 5 */ + "destination-address", /* SADB_EXT_ADDRESS_DST 6 */ + "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */ + "authentication-key", /* SADB_EXT_KEY_AUTH 8 */ + "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */ + "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */ + "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */ + "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */ + "proposal", /* SADB_EXT_PROPOSAL 13 */ + "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */ + "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */ + "spi-range", /* SADB_EXT_SPIRANGE 16 */ + "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */ + "X-satype2", /* SADB_X_EXT_SATYPE2 18 */ + "X-security-association", /* SADB_X_EXT_SA2 19 */ + "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */ + "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */ + "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */ + "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */ + "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */ + "X-set-debug", /* SADB_X_EXT_DEBUG 25 */ +#ifdef NAT_TRAVERSAL + "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */ + "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */ + "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */ + "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */ +#endif +}; + +const char * +pfkey_v2_sadb_ext_string(int ext) +{ + if(ext < SADB_EXT_MAX) { + return pfkey_sadb_ext_strings[ext]; + } else { + return "unknown-ext"; + } +} + + +static char *pfkey_sadb_type_strings[]={ + "reserved", /* SADB_RESERVED */ + "getspi", /* SADB_GETSPI */ + "update", /* SADB_UPDATE */ + "add", /* SADB_ADD */ + "delete", /* SADB_DELETE */ + "get", /* SADB_GET */ + "acquire", /* SADB_ACQUIRE */ + "register", /* SADB_REGISTER */ + "expire", /* SADB_EXPIRE */ + "flush", /* SADB_FLUSH */ + "dump", /* SADB_DUMP */ + "x-promisc", /* SADB_X_PROMISC */ + "x-pchange", /* SADB_X_PCHANGE */ + "x-groupsa", /* SADB_X_GRPSA */ + "x-addflow(eroute)", /* SADB_X_ADDFLOW */ + "x-delflow(eroute)", /* SADB_X_DELFLOW */ + "x-debug", /* SADB_X_DEBUG */ +}; + +const char * +pfkey_v2_sadb_type_string(int sadb_type) +{ + if(sadb_type < SADB_MAX) { + return pfkey_sadb_type_strings[sadb_type]; + } else { + return "unknown-sadb-type"; + } +} + + + + +/* + * $Log: pfkey_v2_debug.c,v $ + * Revision 1.3 2003/11/16 23:22:48 ken + * We are now Openswan + * + * Revision 1.2 2002/09/05 03:53:53 ken + * Added NAT-T Patch + * + * Revision 1.1.1.1 2002/09/05 03:13:20 ken + * 1.98b + * + * Revision 1.4 2002/01/29 22:25:36 rgb + * Re-add ipsec_kversion.h to keep MALLOC happy. + * + * Revision 1.3 2002/01/29 01:59:09 mcr + * removal of kversions.h - sources that needed it now use ipsec_param.h. + * updating of IPv6 structures to match latest in6.h version. + * removed dead code from openswan.h that also duplicated kversions.h + * code. + * + * Revision 1.2 2002/01/20 20:34:50 mcr + * added pfkey_v2_sadb_type_string to decode sadb_type to string. + * + * Revision 1.1 2001/11/27 05:30:06 mcr + * initial set of debug strings for pfkey debugging. + * this will eventually only be included for debug builds. + * + * Revision 1.1 2001/09/21 04:12:03 mcr + * first compilable version. + * + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/libopenswan/pfkey_v2_ext_bits.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey_v2_ext_bits.c --- linux-2.4.29/net/ipsec/libopenswan/pfkey_v2_ext_bits.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey_v2_ext_bits.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,813 @@ +/* + * RFC2367 PF_KEYv2 Key management API message parser + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: pfkey_v2_ext_bits.c,v 1.7 2003/11/16 23:22:48 ken Exp $ + */ + +/* + * Template from klips/net/ipsec/ipsec/ipsec_parse.c. + */ + +char pfkey_v2_ext_bits_c_version[] = "$Id: pfkey_v2_ext_bits.c,v 1.7 2003/11/16 23:22:48 ken Exp $"; + +/* + * Some ugly stuff to allow consistent debugging code for use in the + * kernel and in user space +*/ + +#ifdef __KERNEL__ + +# include /* for printk */ + +# include "../ipsec_kversion.h" /* for malloc switch */ +# ifdef MALLOC_SLAB +# include /* kmalloc() */ +# else /* MALLOC_SLAB */ +# include /* kmalloc() */ +# endif /* MALLOC_SLAB */ +# include /* error codes */ +# include /* size_t */ +# include /* mark_bh */ + +# include /* struct device, and other headers */ +# include /* eth_type_trans */ +# include /* struct iphdr */ +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +# include +# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ + +#else /* __KERNEL__ */ + +# include +# include +# include +#endif + +#include +#include +#include + +unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = { + +/* INBOUND EXTENSIONS */ +{ + +/* PERMITTED IN */ +{ +/* SADB_RESERVED */ +0 +, +/* SADB_GETSPI */ +1< 0.5 - This looks weird... + * + * Revision 1.3 2002/12/12 03:32:08 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.2 2002/09/05 03:53:53 ken + * Added NAT-T Patch + * + * Revision 1.1.1.1 2002/09/05 03:13:20 ken + * 1.98b + * + * Revision 1.13 2002/01/29 22:25:36 rgb + * Re-add ipsec_kversion.h to keep MALLOC happy. + * + * Revision 1.12 2002/01/29 01:59:10 mcr + * removal of kversions.h - sources that needed it now use ipsec_param.h. + * updating of IPv6 structures to match latest in6.h version. + * removed dead code from openswan.h that also duplicated kversions.h + * code. + * + * Revision 1.11 2001/10/18 04:45:24 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/openswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.10 2001/09/08 21:13:35 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * + * Revision 1.9 2001/06/14 19:35:16 rgb + * Update copyright date. + * + * Revision 1.8 2001/03/26 23:07:36 rgb + * Remove requirement for auth and enc key from UPDATE. + * + * Revision 1.7 2000/09/12 22:35:37 rgb + * Restructured to remove unused extensions from CLEARFLOW messages. + * + * Revision 1.6 2000/09/09 06:39:01 rgb + * Added comments for clarity. + * + * Revision 1.5 2000/06/02 22:54:14 rgb + * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. + * + * Revision 1.4 2000/01/21 06:27:56 rgb + * Added address cases for eroute flows. + * Added comments for each message type. + * Added klipsdebug switching capability. + * Fixed GRPSA bitfields. + * + * Revision 1.3 1999/12/01 22:20:27 rgb + * Remove requirement for a proxy address in an incoming getspi message. + * + * Revision 1.2 1999/11/27 11:57:06 rgb + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. + * Add CVS log entry to bottom of file. + * Cleaned out unused bits. + * + */ diff -urN linux-2.4.29/net/ipsec/libopenswan/pfkey_v2_parse.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey_v2_parse.c --- linux-2.4.29/net/ipsec/libopenswan/pfkey_v2_parse.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkey_v2_parse.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,1705 @@ +/* + * RFC2367 PF_KEYv2 Key management API message parser + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: pfkey_v2_parse.c,v 1.10 2003/11/16 23:22:48 ken Exp $ + */ + +/* + * Template from klips/net/ipsec/ipsec/ipsec_parser.c. + */ + +char pfkey_v2_parse_c_version[] = "$Id: pfkey_v2_parse.c,v 1.10 2003/11/16 23:22:48 ken Exp $"; + +/* + * Some ugly stuff to allow consistent debugging code for use in the + * kernel and in user space +*/ + +#ifdef __KERNEL__ + +# include /* for printk */ + +# include "../ipsec_kversion.h" /* for malloc switch */ +# ifdef MALLOC_SLAB +# include /* kmalloc() */ +# else /* MALLOC_SLAB */ +# include /* kmalloc() */ +# endif /* MALLOC_SLAB */ +# include /* error codes */ +# include /* size_t */ +# include /* mark_bh */ + +# include /* struct device, and other headers */ +# include /* eth_type_trans */ +# include /* struct iphdr */ +# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +# include /* struct ipv6hdr */ +# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ +extern int debug_pfkey; + +# include + +#include "../ipsec_encap.h" + +#else /* __KERNEL__ */ + +# include +# include +# include + +# include +# include "../pluto/constants.h" +# include "../pluto/defs.h" /* for PRINTF_LIKE */ +# include "../pluto/log.h" /* for debugging and DBG_log */ + +extern unsigned int pfkey_lib_debug; /* bits selecting what to report */ + +/* #define PLUTO */ + +# ifdef PLUTO +# define DEBUGGING(level, args...) { DBG_log("pfkey_lib_debug:" args); } +# else +# define DEBUGGING(level, args...) if(pfkey_lib_debug >= level) { printf("pfkey_lib_debug:" args); } else { ; } +# endif + +#endif /* __KERNEL__ */ + + +#include +#include + +#ifdef __KERNEL__ +#if 0 +# include "../radij.h" /* rd_nodes */ +# include "../ipsec_encap.h" /* sockaddr_encap */ +#endif +# include "../ipsec_netlink.h" /* KLIPS_PRINT */ +# define DEBUGGING(level, args...) \ + KLIPS_PRINT((debug_pfkey >= level), "klips_debug:" args) +#endif /* __KERNEL__ */ + + +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) + +struct satype_tbl { + uint8_t proto; + uint8_t satype; + char* name; +} static satype_tbl[] = { +#ifdef __KERNEL__ + { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" }, + { IPPROTO_AH, SADB_SATYPE_AH, "AH" }, + { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, +#ifdef CONFIG_IPSEC_IPCOMP + { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" }, +#endif /* CONFIG_IPSEC_IPCOMP */ + { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" }, +#else /* __KERNEL__ */ + { SA_ESP, SADB_SATYPE_ESP, "ESP" }, + { SA_AH, SADB_SATYPE_AH, "AH" }, + { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" }, + { SA_COMP, SADB_X_SATYPE_COMP, "COMP" }, + { SA_INT, SADB_X_SATYPE_INT, "INT" }, +#endif /* __KERNEL__ */ + { 0, 0, "UNKNOWN" } +}; + +uint8_t satype2proto(uint8_t satype) { + int i =0; + + while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { + i++; + } + return satype_tbl[i].proto; +} + +uint8_t proto2satype(uint8_t proto) { + int i = 0; + + while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { + i++; + } + return satype_tbl[i].satype; +} + +char* satype2name(uint8_t satype) { + int i = 0; + + while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) { + i++; + } + return satype_tbl[i].name; +} + +char* proto2name(uint8_t proto) { + int i = 0; + + while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) { + i++; + } + return satype_tbl[i].name; +} + +/* Default extension parsers taken from the KLIPS code */ + +DEBUG_NO_STATIC int +pfkey_sa_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext; + + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, + "pfkey_sa_parse: entry\n"); + /* sanity checks... */ + if(!pfkey_sa) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sa_parse: " + "NULL pointer passed in.\n"); + SENDERR(EINVAL); + } + + if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sa_parse: " + "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n", + pfkey_sa->sadb_sa_len, + (int) sizeof(struct sadb_sa)); + SENDERR(EINVAL); + } + + if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sa_parse: " + "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n", + pfkey_sa->sadb_sa_encrypt, + SADB_EALG_MAX); + SENDERR(EINVAL); + } + + if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sa_parse: " + "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n", + pfkey_sa->sadb_sa_auth, + SADB_AALG_MAX); + SENDERR(EINVAL); + } + + if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sa_parse: " + "state=%d exceeds MAX=%d.\n", + pfkey_sa->sadb_sa_state, + SADB_SASTATE_MAX); + SENDERR(EINVAL); + } + + if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sa_parse: " + "state=%d is DEAD=%d.\n", + pfkey_sa->sadb_sa_state, + SADB_SASTATE_DEAD); + SENDERR(EINVAL); + } + + if(pfkey_sa->sadb_sa_replay > 64) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sa_parse: " + "replay window size: %d -- must be 0 <= size <= 64\n", + pfkey_sa->sadb_sa_replay); + SENDERR(EINVAL); + } + + if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) || + (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2))) + { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sa_parse: " + "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n", + pfkey_sa->sadb_sa_exttype, + SADB_EXT_SA, + SADB_X_EXT_SA2); + SENDERR(EINVAL); + } + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_sa_parse: " + "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d.\n", + pfkey_sa->sadb_sa_len, + pfkey_sa->sadb_sa_exttype, pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype), + (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi), + pfkey_sa->sadb_sa_replay, + pfkey_sa->sadb_sa_state, + pfkey_sa->sadb_sa_auth, + pfkey_sa->sadb_sa_encrypt, + pfkey_sa->sadb_sa_flags); + + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_lifetime_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext; + + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, + "pfkey_lifetime_parse:enter\n"); + /* sanity checks... */ + if(!pfkey_lifetime) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_lifetime_parse: " + "NULL pointer passed in.\n"); + SENDERR(EINVAL); + } + + if(pfkey_lifetime->sadb_lifetime_len != + sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_lifetime_parse: " + "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n", + pfkey_lifetime->sadb_lifetime_len, + (int) sizeof(struct sadb_lifetime)); + SENDERR(EINVAL); + } + + if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) && + (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) && + (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_lifetime_parse: " + "unexpected ext_type=%d.\n", + pfkey_lifetime->sadb_lifetime_exttype); + SENDERR(EINVAL); + } + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_address_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + int saddr_len = 0; + struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext; + struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address)); + char ipaddr_txt[ADDRTOT_BUF]; + + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, + "pfkey_address_parse:enter\n"); + /* sanity checks... */ + if(!pfkey_address) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_address_parse: " + "NULL pointer passed in.\n"); + SENDERR(EINVAL); + } + + if(pfkey_address->sadb_address_len < + (sizeof(struct sadb_address) + sizeof(struct sockaddr))/ + IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_address_parse: " + "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", + pfkey_address->sadb_address_len, + (int) sizeof(struct sadb_address), + (int) sizeof(struct sockaddr)); + SENDERR(EINVAL); + } + + if(pfkey_address->sadb_address_reserved) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_address_parse: " + "res=%d, must be zero.\n", + pfkey_address->sadb_address_reserved); + SENDERR(EINVAL); + } + + switch(pfkey_address->sadb_address_exttype) { + case SADB_EXT_ADDRESS_SRC: + case SADB_EXT_ADDRESS_DST: + case SADB_EXT_ADDRESS_PROXY: + case SADB_X_EXT_ADDRESS_DST2: + case SADB_X_EXT_ADDRESS_SRC_FLOW: + case SADB_X_EXT_ADDRESS_DST_FLOW: + case SADB_X_EXT_ADDRESS_SRC_MASK: + case SADB_X_EXT_ADDRESS_DST_MASK: +#ifdef NAT_TRAVERSAL + case SADB_X_EXT_NAT_T_OA: +#endif + break; + default: + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_address_parse: " + "unexpected ext_type=%d.\n", + pfkey_address->sadb_address_exttype); + SENDERR(EINVAL); + } + + switch(s->sa_family) { + case AF_INET: + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_address_parse: " + "found address family=%d, AF_INET.\n", + s->sa_family); + saddr_len = sizeof(struct sockaddr_in); + sprintf(ipaddr_txt, "%d.%d.%d.%d" + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF + , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF); + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_address_parse: " + "found address=%s.\n", + ipaddr_txt); + break; + case AF_INET6: + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_address_parse: " + "found address family=%d, AF_INET6.\n", + s->sa_family); + saddr_len = sizeof(struct sockaddr_in6); + sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x" + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0]) + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1]) + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2]) + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3]) + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4]) + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5]) + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6]) + , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7])); + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_address_parse: " + "found address=%s.\n", + ipaddr_txt); + break; + default: + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_address_parse: " + "s->sa_family=%d not supported.\n", + s->sa_family); + SENDERR(EPFNOSUPPORT); + } + + if(pfkey_address->sadb_address_len != + DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_address_parse: " + "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n", + pfkey_address->sadb_address_len, + (int) sizeof(struct sadb_address), + saddr_len); + SENDERR(EINVAL); + } + + if(pfkey_address->sadb_address_prefixlen != 0) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_address_parse: " + "address prefixes not supported yet.\n"); + SENDERR(EAFNOSUPPORT); /* not supported yet */ + } + + /* XXX check if port!=0 */ + + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, + "pfkey_address_parse: successful.\n"); + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_key_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext; + + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, + "pfkey_key_parse:enter\n"); + /* sanity checks... */ + + if(!pfkey_key) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_key_parse: " + "NULL pointer passed in.\n"); + SENDERR(EINVAL); + } + + if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_key_parse: " + "size wrong ext_len=%d, key_ext_len=%d.\n", + pfkey_key->sadb_key_len, + (int) sizeof(struct sadb_key)); + SENDERR(EINVAL); + } + + if(!pfkey_key->sadb_key_bits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_key_parse: " + "key length set to zero, must be non-zero.\n"); + SENDERR(EINVAL); + } + + if(pfkey_key->sadb_key_len != + DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits, + PFKEYBITS)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_key_parse: " + "key length=%d does not agree with extension length=%d.\n", + pfkey_key->sadb_key_bits, + pfkey_key->sadb_key_len); + SENDERR(EINVAL); + } + + if(pfkey_key->sadb_key_reserved) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_key_parse: " + "res=%d, must be zero.\n", + pfkey_key->sadb_key_reserved); + SENDERR(EINVAL); + } + + if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) || + (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_key_parse: " + "expecting extension type AUTH or ENCRYPT, got %d.\n", + pfkey_key->sadb_key_exttype); + SENDERR(EINVAL); + } + + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_key_parse: " + "success, found len=%d exttype=%d bits=%d reserved=%d.\n", + pfkey_key->sadb_key_len, + pfkey_key->sadb_key_exttype, + pfkey_key->sadb_key_bits, + pfkey_key->sadb_key_reserved); + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_ident_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext; + + /* sanity checks... */ + if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_ident_parse: " + "size wrong ext_len=%d, key_ext_len=%d.\n", + pfkey_ident->sadb_ident_len, + (int) sizeof(struct sadb_ident)); + SENDERR(EINVAL); + } + + if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_ident_parse: " + "ident_type=%d out of range, must be less than %d.\n", + pfkey_ident->sadb_ident_type, + SADB_IDENTTYPE_MAX); + SENDERR(EINVAL); + } + + if(pfkey_ident->sadb_ident_reserved) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_ident_parse: " + "res=%d, must be zero.\n", + pfkey_ident->sadb_ident_reserved); + SENDERR(EINVAL); + } + + /* string terminator/padding must be zero */ + if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) { + if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_ident_parse: " + "string padding must be zero, last is 0x%02x.\n", + *((char*)pfkey_ident + + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)); + SENDERR(EINVAL); + } + } + + if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) || + (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_key_parse: " + "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n", + pfkey_ident->sadb_ident_exttype); + SENDERR(EINVAL); + } + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_sens_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext; + + /* sanity checks... */ + if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sens_parse: " + "size wrong ext_len=%d, key_ext_len=%d.\n", + pfkey_sens->sadb_sens_len, + (int) sizeof(struct sadb_sens)); + SENDERR(EINVAL); + } + + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_sens_parse: " + "Sorry, I can't parse exttype=%d yet.\n", + pfkey_ext->sadb_ext_type); +#if 0 + SENDERR(EINVAL); /* don't process these yet */ +#endif + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_prop_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + int i, num_comb; + struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext; + struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop)); + + /* sanity checks... */ + if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) || + (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n", + pfkey_prop->sadb_prop_len, + (int) sizeof(struct sadb_prop), + (int) sizeof(struct sadb_comb)); + SENDERR(EINVAL); + } + + if(pfkey_prop->sadb_prop_replay > 64) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "replay window size: %d -- must be 0 <= size <= 64\n", + pfkey_prop->sadb_prop_replay); + SENDERR(EINVAL); + } + + for(i=0; i<3; i++) { + if(pfkey_prop->sadb_prop_reserved[i]) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "res[%d]=%d, must be zero.\n", + i, pfkey_prop->sadb_prop_reserved[i]); + SENDERR(EINVAL); + } + } + + num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb); + + for(i = 0; i < num_comb; i++) { + if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n", + i, + pfkey_comb->sadb_comb_auth, + SADB_AALG_MAX); + SENDERR(EINVAL); + } + + if(pfkey_comb->sadb_comb_auth) { + if(!pfkey_comb->sadb_comb_auth_minbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n", + i); + SENDERR(EINVAL); + } + if(!pfkey_comb->sadb_comb_auth_maxbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n", + i); + SENDERR(EINVAL); + } + if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n", + i, + pfkey_comb->sadb_comb_auth_minbits, + pfkey_comb->sadb_comb_auth_maxbits); + SENDERR(EINVAL); + } + } else { + if(pfkey_comb->sadb_comb_auth_minbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n", + i, + pfkey_comb->sadb_comb_auth_minbits); + SENDERR(EINVAL); + } + if(pfkey_comb->sadb_comb_auth_maxbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n", + i, + pfkey_comb->sadb_comb_auth_maxbits); + SENDERR(EINVAL); + } + } + + if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_comb_parse: " + "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n", + i, + pfkey_comb->sadb_comb_encrypt, + SADB_EALG_MAX); + SENDERR(EINVAL); + } + + if(pfkey_comb->sadb_comb_encrypt) { + if(!pfkey_comb->sadb_comb_encrypt_minbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n", + i); + SENDERR(EINVAL); + } + if(!pfkey_comb->sadb_comb_encrypt_maxbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n", + i); + SENDERR(EINVAL); + } + if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n", + i, + pfkey_comb->sadb_comb_encrypt_minbits, + pfkey_comb->sadb_comb_encrypt_maxbits); + SENDERR(EINVAL); + } + } else { + if(pfkey_comb->sadb_comb_encrypt_minbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n", + i, + pfkey_comb->sadb_comb_encrypt_minbits); + SENDERR(EINVAL); + } + if(pfkey_comb->sadb_comb_encrypt_maxbits) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n", + i, + pfkey_comb->sadb_comb_encrypt_maxbits); + SENDERR(EINVAL); + } + } + + /* XXX do sanity check on flags */ + + if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n", + i, + pfkey_comb->sadb_comb_soft_allocations, + pfkey_comb->sadb_comb_hard_allocations); + SENDERR(EINVAL); + } + + if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n", + i, + (unsigned long long int) pfkey_comb->sadb_comb_soft_bytes, + (unsigned long long int) pfkey_comb->sadb_comb_hard_bytes); + SENDERR(EINVAL); + } + + if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n", + i, + (unsigned long long int) pfkey_comb->sadb_comb_soft_addtime, + (unsigned long long int) pfkey_comb->sadb_comb_hard_addtime); + SENDERR(EINVAL); + } + + if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n", + i, + (unsigned long long int) pfkey_comb->sadb_comb_soft_usetime, + (unsigned long long int) pfkey_comb->sadb_comb_hard_usetime); + SENDERR(EINVAL); + } + + if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n", + i, + pfkey_comb->sadb_x_comb_soft_packets, + pfkey_comb->sadb_x_comb_hard_packets); + SENDERR(EINVAL); + } + + if(pfkey_comb->sadb_comb_reserved) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_prop_parse: " + "comb[%d].res=%d, must be zero.\n", + i, + pfkey_comb->sadb_comb_reserved); + SENDERR(EINVAL); + } + pfkey_comb++; + } + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_supported_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + unsigned int i, num_alg; + struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext; + struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported)); + + /* sanity checks... */ + if((pfkey_supported->sadb_supported_len < + sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) || + (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - + sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) { + + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_supported_parse: " + "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n", + pfkey_supported->sadb_supported_len, + (int) sizeof(struct sadb_supported), + (int) sizeof(struct sadb_alg)); + SENDERR(EINVAL); + } + + if(pfkey_supported->sadb_supported_reserved) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_supported_parse: " + "res=%d, must be zero.\n", + pfkey_supported->sadb_supported_reserved); + SENDERR(EINVAL); + } + + num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg); + + for(i = 0; i < num_alg; i++) { + /* process algo description */ + if(pfkey_alg->sadb_alg_reserved) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_supported_parse: " + "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n", + i, + pfkey_alg->sadb_alg_id, + pfkey_alg->sadb_alg_ivlen, + pfkey_alg->sadb_alg_minbits, + pfkey_alg->sadb_alg_maxbits, + pfkey_alg->sadb_alg_reserved); + SENDERR(EINVAL); + } + + /* XXX can alg_id auth/enc be determined from info given? + Yes, but OpenBSD's method does not iteroperate with rfc2367. + rgb, 2000-04-06 */ + + switch(pfkey_supported->sadb_supported_exttype) { + case SADB_EXT_SUPPORTED_AUTH: + if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_supported_parse: " + "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n", + i, + pfkey_alg->sadb_alg_id, + SADB_AALG_MAX); + SENDERR(EINVAL); + } + break; + case SADB_EXT_SUPPORTED_ENCRYPT: + if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_supported_parse: " + "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", + i, + pfkey_alg->sadb_alg_id, + SADB_EALG_MAX); + SENDERR(EINVAL); + } + break; + default: + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_supported_parse: " + "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n", + i, + pfkey_alg->sadb_alg_id, + SADB_EALG_MAX); + SENDERR(EINVAL); + } + pfkey_alg++; + } + + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_spirange_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext; + + /* sanity checks... */ + if(pfkey_spirange->sadb_spirange_len != + sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_spirange_parse: " + "size wrong ext_len=%d, key_ext_len=%d.\n", + pfkey_spirange->sadb_spirange_len, + (int) sizeof(struct sadb_spirange)); + SENDERR(EINVAL); + } + + if(pfkey_spirange->sadb_spirange_reserved) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_spirange_parse: " + "reserved=%d must be set to zero.\n", + pfkey_spirange->sadb_spirange_reserved); + SENDERR(EINVAL); + } + + if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_spirange_parse: " + "minspi=%08x must be < maxspi=%08x.\n", + ntohl(pfkey_spirange->sadb_spirange_min), + ntohl(pfkey_spirange->sadb_spirange_max)); + SENDERR(EINVAL); + } + + if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_spirange_parse: " + "minspi=%08x must be > 255.\n", + ntohl(pfkey_spirange->sadb_spirange_min)); + SENDERR(EEXIST); + } + + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext; + + /* sanity checks... */ + if(pfkey_x_kmprivate->sadb_x_kmprivate_len < + sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_kmprivate_parse: " + "size wrong ext_len=%d, key_ext_len=%d.\n", + pfkey_x_kmprivate->sadb_x_kmprivate_len, + (int) sizeof(struct sadb_x_kmprivate)); + SENDERR(EINVAL); + } + + if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_kmprivate_parse: " + "reserved=%d must be set to zero.\n", + pfkey_x_kmprivate->sadb_x_kmprivate_reserved); + SENDERR(EINVAL); + } + + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_kmprivate_parse: " + "Sorry, I can't parse exttype=%d yet.\n", + pfkey_ext->sadb_ext_type); + SENDERR(EINVAL); /* don't process these yet */ + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_satype_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + int i; + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext; + + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, + "pfkey_x_satype_parse: enter\n"); + /* sanity checks... */ + if(pfkey_x_satype->sadb_x_satype_len != + sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_satype_parse: " + "size wrong ext_len=%d, key_ext_len=%d.\n", + pfkey_x_satype->sadb_x_satype_len, + (int) sizeof(struct sadb_x_satype)); + SENDERR(EINVAL); + } + + if(!pfkey_x_satype->sadb_x_satype_satype) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_satype_parse: " + "satype is zero, must be non-zero.\n"); + SENDERR(EINVAL); + } + + if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_satype_parse: " + "satype %d > max %d, invalid.\n", + pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX); + SENDERR(EINVAL); + } + + if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_satype_parse: " + "proto lookup from satype=%d failed.\n", + pfkey_x_satype->sadb_x_satype_satype); + SENDERR(EINVAL); + } + + for(i = 0; i < 3; i++) { + if(pfkey_x_satype->sadb_x_satype_reserved[i]) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_satype_parse: " + "reserved[%d]=%d must be set to zero.\n", + i, pfkey_x_satype->sadb_x_satype_reserved[i]); + SENDERR(EINVAL); + } + } + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext) +{ + int error = 0; + int i; + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext; + + DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW, + "pfkey_x_debug_parse: enter\n"); + /* sanity checks... */ + if(pfkey_x_debug->sadb_x_debug_len != + sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_debug_parse: " + "size wrong ext_len=%d, key_ext_len=%d.\n", + pfkey_x_debug->sadb_x_debug_len, + (int) sizeof(struct sadb_x_debug)); + SENDERR(EINVAL); + } + + for(i = 0; i < 4; i++) { + if(pfkey_x_debug->sadb_x_debug_reserved[i]) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_x_debug_parse: " + "reserved[%d]=%d must be set to zero.\n", + i, pfkey_x_debug->sadb_x_debug_reserved[i]); + SENDERR(EINVAL); + } + } + +errlab: + return error; +} + +#ifdef NAT_TRAVERSAL +DEBUG_NO_STATIC int +pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext) +{ + return 0; +} +DEBUG_NO_STATIC int +pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext) +{ + return 0; +} +#endif + +DEBUG_NO_STATIC int +pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext) +{ + return 0; +} + +#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME}; + +DEFINEPARSER(pfkey_sa_parse); +DEFINEPARSER(pfkey_lifetime_parse); +DEFINEPARSER(pfkey_address_parse); +DEFINEPARSER(pfkey_key_parse); +DEFINEPARSER(pfkey_ident_parse); +DEFINEPARSER(pfkey_sens_parse); +DEFINEPARSER(pfkey_prop_parse); +DEFINEPARSER(pfkey_supported_parse); +DEFINEPARSER(pfkey_spirange_parse); +DEFINEPARSER(pfkey_x_kmprivate_parse); +DEFINEPARSER(pfkey_x_satype_parse); +DEFINEPARSER(pfkey_x_ext_debug_parse); +DEFINEPARSER(pfkey_x_ext_protocol_parse); +#ifdef NAT_TRAVERSAL +DEFINEPARSER(pfkey_x_ext_nat_t_type_parse); +DEFINEPARSER(pfkey_x_ext_nat_t_port_parse); +#endif + +struct pf_key_ext_parsers_def *ext_default_parsers[]= +{ + NULL, /* pfkey_msg_parse, */ + &pfkey_sa_parse_def, + &pfkey_lifetime_parse_def, + &pfkey_lifetime_parse_def, + &pfkey_lifetime_parse_def, + &pfkey_address_parse_def, + &pfkey_address_parse_def, + &pfkey_address_parse_def, + &pfkey_key_parse_def, + &pfkey_key_parse_def, + &pfkey_ident_parse_def, + &pfkey_ident_parse_def, + &pfkey_sens_parse_def, + &pfkey_prop_parse_def, + &pfkey_supported_parse_def, + &pfkey_supported_parse_def, + &pfkey_spirange_parse_def, + &pfkey_x_kmprivate_parse_def, + &pfkey_x_satype_parse_def, + &pfkey_sa_parse_def, + &pfkey_address_parse_def, + &pfkey_address_parse_def, + &pfkey_address_parse_def, + &pfkey_address_parse_def, + &pfkey_address_parse_def, + &pfkey_x_ext_debug_parse_def, + &pfkey_x_ext_protocol_parse_def +#ifdef NAT_TRAVERSAL + , + &pfkey_x_ext_nat_t_type_parse_def, + &pfkey_x_ext_nat_t_port_parse_def, + &pfkey_x_ext_nat_t_port_parse_def, + &pfkey_address_parse_def +#endif +}; + +int +pfkey_msg_parse(struct sadb_msg *pfkey_msg, + struct pf_key_ext_parsers_def *ext_parsers[], + struct sadb_ext *extensions[], + int dir) +{ + int error = 0; + int remain; + struct sadb_ext *pfkey_ext; + int extensions_seen = 0; + + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_msg_parse: " + "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", + pfkey_msg->sadb_msg_version, + pfkey_msg->sadb_msg_type, + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type), + pfkey_msg->sadb_msg_errno, + pfkey_msg->sadb_msg_satype, + satype2name(pfkey_msg->sadb_msg_satype), + pfkey_msg->sadb_msg_len, + pfkey_msg->sadb_msg_reserved, + pfkey_msg->sadb_msg_seq, + pfkey_msg->sadb_msg_pid); + + if(ext_parsers == NULL) ext_parsers = ext_default_parsers; + + pfkey_extensions_init(extensions); + + remain = pfkey_msg->sadb_msg_len; + remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; + + pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg + + sizeof(struct sadb_msg)); + + extensions[0] = (struct sadb_ext *) pfkey_msg; + + + if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "not PF_KEY_V2 msg, found %d, should be %d.\n", + pfkey_msg->sadb_msg_version, + PF_KEY_V2); + SENDERR(EINVAL); + } + + if(!pfkey_msg->sadb_msg_type) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "msg type not set, must be non-zero..\n"); + SENDERR(EINVAL); + } + + if(pfkey_msg->sadb_msg_type > SADB_MAX) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "msg type=%d > max=%d.\n", + pfkey_msg->sadb_msg_type, + SADB_MAX); + SENDERR(EINVAL); + } + + switch(pfkey_msg->sadb_msg_type) { + case SADB_GETSPI: + case SADB_UPDATE: + case SADB_ADD: + case SADB_DELETE: + case SADB_GET: + case SADB_X_GRPSA: + case SADB_X_ADDFLOW: + if(!satype2proto(pfkey_msg->sadb_msg_satype)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "satype %d conversion to proto failed for msg_type %d (%s).\n", + pfkey_msg->sadb_msg_satype, + pfkey_msg->sadb_msg_type, + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); + SENDERR(EINVAL); + } else { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n", + pfkey_msg->sadb_msg_satype, + satype2name(pfkey_msg->sadb_msg_satype), + satype2proto(pfkey_msg->sadb_msg_satype), + pfkey_msg->sadb_msg_type, + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); + } + case SADB_ACQUIRE: + case SADB_REGISTER: + case SADB_EXPIRE: + if(!pfkey_msg->sadb_msg_satype) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "satype is zero, must be non-zero for msg_type %d(%s).\n", + pfkey_msg->sadb_msg_type, + pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type)); + SENDERR(EINVAL); + } + default: + break; + } + + /* errno must not be set in downward messages */ + /* this is not entirely true... a response to an ACQUIRE could return an error */ + if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "errno set to %d.\n", + pfkey_msg->sadb_msg_errno); + SENDERR(EINVAL); + } + + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_msg_parse: " + "remain=%d, ext_type=%d(%s), ext_len=%d.\n", + remain, + pfkey_ext->sadb_ext_type, + pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type), + pfkey_ext->sadb_ext_len); + + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_msg_parse: " + "extensions permitted=%08x, required=%08x.\n", + extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); + + extensions_seen = 1; + + while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) { + /* Is there enough message left to support another extension header? */ + if(remain < pfkey_ext->sadb_ext_len) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "remain %d less than ext len %d.\n", + remain, pfkey_ext->sadb_ext_len); + SENDERR(EINVAL); + } + + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_msg_parse: " + "parsing ext type=%d remain=%d.\n", + pfkey_ext->sadb_ext_type, + remain); + + /* Is the extension header type valid? */ + if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "ext type %d invalid, SADB_EXT_MAX=%d.\n", + pfkey_ext->sadb_ext_type, SADB_EXT_MAX); + SENDERR(EINVAL); + } + + /* Have we already seen this type of extension? */ + if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0) + { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "ext type %d already seen.\n", + pfkey_ext->sadb_ext_type); + SENDERR(EINVAL); + } + + /* Do I even know about this type of extension? */ + if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "ext type %d unknown, ignoring.\n", + pfkey_ext->sadb_ext_type); + goto next_ext; + } + + /* Is this type of extension permitted for this type of message? */ + if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] & + 1<sadb_ext_type)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "ext type %d not permitted, exts_perm_in=%08x, 1<sadb_ext_type, + extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], + 1<sadb_ext_type); + SENDERR(EINVAL); + } + + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_msg_parse: " + "About to parse extension %d %p with parser %s.\n", + pfkey_ext->sadb_ext_type, + pfkey_ext, + ext_parsers[pfkey_ext->sadb_ext_type]->parser_name); + /* Parse the extension */ + if((error = + (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "extension parsing for type %d failed with error %d.\n", + pfkey_ext->sadb_ext_type, error); + SENDERR(-error); + } + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_msg_parse: " + "Extension %d parsed.\n", + pfkey_ext->sadb_ext_type); + + /* Mark that we have seen this extension and remember the header location */ + extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type ); + extensions[pfkey_ext->sadb_ext_type] = pfkey_ext; + + next_ext: + /* Calculate how much message remains */ + remain -= pfkey_ext->sadb_ext_len; + + if(!remain) { + break; + } + /* Find the next extension header */ + pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext + + pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN); + } + + if(remain) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "unexpected remainder of %d.\n", + remain); + /* why is there still something remaining? */ + SENDERR(EINVAL); + } + + /* check required extensions */ + DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT, + "pfkey_msg_parse: " + "extensions permitted=%08x, seen=%08x, required=%08x.\n", + extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type], + extensions_seen, + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]); + + /* don't check further if it is an error return message since it + may not have a body */ + if(pfkey_msg->sadb_msg_errno) { + SENDERR(-error); + } + + if((extensions_seen & + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) != + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "required extensions missing:%08x.\n", + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] - + (extensions_seen & + extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type])); + SENDERR(EINVAL); + } + + if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW) + && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW) + != SADB_X_EXT_ADDRESS_DELFLOW) + && (((extensions_seen & (1<sadb_sa_flags + & SADB_X_SAFLAGS_CLEARFLOW) + != SADB_X_SAFLAGS_CLEARFLOW))) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n", + SADB_X_EXT_ADDRESS_DELFLOW + - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW), + (1<sadb_msg_type) { + case SADB_ADD: + case SADB_UPDATE: + /* check maturity */ + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != + SADB_SASTATE_MATURE) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "state=%d for add or update should be MATURE=%d.\n", + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, + SADB_SASTATE_MATURE); + SENDERR(EINVAL); + } + + /* check AH and ESP */ + switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) { + case SADB_SATYPE_AH: + if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth != + SADB_AALG_NONE)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "auth alg is zero, must be non-zero for AH SAs.\n"); + SENDERR(EINVAL); + } + if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt != + SADB_EALG_NONE) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "AH handed encalg=%d, must be zero.\n", + ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt); + SENDERR(EINVAL); + } + break; + case SADB_SATYPE_ESP: + if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != + SADB_EALG_NONE)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n", + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); + SENDERR(EINVAL); + } + if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt == + SADB_EALG_NULL) && + (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth == + SADB_AALG_NONE) ) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "ESP handed encNULL+authNONE, illegal combination.\n"); + SENDERR(EINVAL); + } + break; + case SADB_X_SATYPE_COMP: + if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) && + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt != + SADB_EALG_NONE)) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n", + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); + SENDERR(EINVAL); + } + if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth != + SADB_AALG_NONE) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "COMP handed auth=%d, must be zero.\n", + ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth); + SENDERR(EINVAL); + } + break; + default: + break; + } + if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) { + DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, + "pfkey_msg_parse: " + "spi=%08x must be > 255.\n", + ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi)); + SENDERR(EINVAL); + } + default: + break; + } +errlab: + + return error; +} + +/* + * $Log: pfkey_v2_parse.c,v $ + * Revision 1.10 2003/11/16 23:22:48 ken + * We are now Openswan + * + * Revision 1.9 2003/10/17 09:45:09 ken + * 64bit fixes (mainly casts) + * + * Revision 1.8 2003/10/15 16:54:26 ken + * Move #endif to proper location + * + * Revision 1.7 2003/09/30 00:26:02 ken + * Tuomo Soini's NAT-T 0.6 cleanup patch + * Fixes a number of #ifdefs around NAT-T, and brings a few other other cleanups in + * + * Revision 1.6 2003/09/22 12:26:51 ken + * Fix switch() where break; was missing + * Fix a few typing errors with 8bit and 16bit ints + * + * Revision 1.5 2003/02/07 13:14:26 ken + * Pullin jjo's ALG 0.8.1rc branch + * + * Revision 1.4.2.1 2003/02/07 01:47:12 jjo + * . some #ifdef's tweaking to allow compilation without NAT_TRAVERSAL + * + * Revision 1.4 2002/12/26 02:30:48 ken + * Fix order of SADB definations + * + * Revision 1.3 2002/12/12 03:32:08 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.2 2002/09/05 03:53:53 ken + * Added NAT-T Patch + * + * Revision 1.1.1.1 2002/09/05 03:13:20 ken + * 1.98b + * + * Revision 1.42 2002/01/29 22:25:36 rgb + * Re-add ipsec_kversion.h to keep MALLOC happy. + * + * Revision 1.41 2002/01/29 01:59:10 mcr + * removal of kversions.h - sources that needed it now use ipsec_param.h. + * updating of IPv6 structures to match latest in6.h version. + * removed dead code from openswan.h that also duplicated kversions.h + * code. + * + * Revision 1.40 2002/01/20 20:34:50 mcr + * added pfkey_v2_sadb_type_string to decode sadb_type to string. + * + * Revision 1.39 2001/11/27 05:29:22 mcr + * pfkey parses are now maintained by a structure + * that includes their name for debug purposes. + * DEBUGGING() macro changed so that it takes a debug + * level so that pf_key() can use this to decode the + * structures without innundanting humans. + * Also uses pfkey_v2_sadb_ext_string() in messages. + * + * Revision 1.38 2001/11/06 19:47:47 rgb + * Added packet parameter to lifetime and comb structures. + * + * Revision 1.37 2001/10/18 04:45:24 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/openswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.36 2001/06/14 19:35:16 rgb + * Update copyright date. + * + * Revision 1.35 2001/05/03 19:44:51 rgb + * Standardise on SENDERR() macro. + * + * Revision 1.34 2001/03/16 07:41:51 rgb + * Put openswan.h include before pluto includes. + * + * Revision 1.33 2001/02/27 07:13:51 rgb + * Added satype2name() function. + * Added text to default satype_tbl entry. + * Added satype2name() conversions for most satype debug output. + * + * Revision 1.32 2001/02/26 20:01:09 rgb + * Added internal IP protocol 61 for magic SAs. + * Ditch unused sadb_satype2proto[], replaced by satype2proto(). + * Re-formatted debug output (split lines, consistent spacing). + * Removed acquire, register and expire requirements for a known satype. + * Changed message type checking to a switch structure. + * Verify expected NULL auth for IPCOMP. + * Enforced spi > 0x100 requirement, now that pass uses a magic SA for + * appropriate message types. + * + * Revision 1.31 2000/12/01 07:09:00 rgb + * Added ipcomp sanity check to require encalgo is set. + * + * Revision 1.30 2000/11/17 18:10:30 rgb + * Fixed bugs mostly relating to spirange, to treat all spi variables as + * network byte order since this is the way PF_KEYv2 stored spis. + * + * Revision 1.29 2000/10/12 00:02:39 rgb + * Removed 'format, ##' nonsense from debug macros for RH7.0. + * + * Revision 1.28 2000/09/20 16:23:04 rgb + * Remove over-paranoid extension check in the presence of sadb_msg_errno. + * + * Revision 1.27 2000/09/20 04:04:21 rgb + * Changed static functions to DEBUG_NO_STATIC to reveal function names in + * oopsen. + * + * Revision 1.26 2000/09/15 11:37:02 rgb + * Merge in heavily modified Svenning Soerensen's + * IPCOMP zlib deflate code. + * + * Revision 1.25 2000/09/12 22:35:37 rgb + * Restructured to remove unused extensions from CLEARFLOW messages. + * + * Revision 1.24 2000/09/12 18:59:54 rgb + * Added Gerhard's IPv6 support to pfkey parts of libfreeswan. + * + * Revision 1.23 2000/09/12 03:27:00 rgb + * Moved DEBUGGING definition to compile kernel with debug off. + * + * Revision 1.22 2000/09/09 06:39:27 rgb + * Restrict pfkey errno check to downward messages only. + * + * Revision 1.21 2000/09/08 19:22:34 rgb + * Enabled pfkey_sens_parse(). + * Added check for errno on downward acquire messages only. + * + * Revision 1.20 2000/09/01 18:48:23 rgb + * Fixed reserved check bug and added debug output in + * pfkey_supported_parse(). + * Fixed debug output label bug in pfkey_ident_parse(). + * + * Revision 1.19 2000/08/27 01:55:26 rgb + * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code. + * + * Revision 1.18 2000/08/24 17:00:36 rgb + * Ignore unknown extensions instead of failing. + * + * Revision 1.17 2000/06/02 22:54:14 rgb + * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support. + * + * Revision 1.16 2000/05/10 19:25:11 rgb + * Fleshed out proposal and supported extensions. + * + * Revision 1.15 2000/01/24 21:15:31 rgb + * Added disabled pluto pfkey lib debug flag. + * Added algo debugging reporting. + * + * Revision 1.14 2000/01/22 23:24:29 rgb + * Added new functions proto2satype() and satype2proto() and lookup + * table satype_tbl. Also added proto2name() since it was easy. + * + * Revision 1.13 2000/01/21 09:43:59 rgb + * Cast ntohl(spi) as (unsigned long int) to shut up compiler. + * + * Revision 1.12 2000/01/21 06:28:19 rgb + * Added address cases for eroute flows. + * Indented compiler directives for readability. + * Added klipsdebug switching capability. + * + * Revision 1.11 1999/12/29 21:14:59 rgb + * Fixed debug text cut and paste typo. + * + * Revision 1.10 1999/12/10 17:45:24 rgb + * Added address debugging. + * + * Revision 1.9 1999/12/09 23:11:42 rgb + * Ditched include since we no longer use memset(). + * Use new pfkey_extensions_init() instead of memset(). + * Added check for SATYPE in pfkey_msg_build(). + * Tidy up comments and debugging comments. + * + * Revision 1.8 1999/12/07 19:55:26 rgb + * Removed unused first argument from extension parsers. + * Removed static pluto debug flag. + * Moved message type and state checking to pfkey_msg_parse(). + * Changed print[fk] type from lx to x to quiet compiler. + * Removed redundant remain check. + * Changed __u* types to uint* to avoid use of asm/types.h and + * sys/types.h in userspace code. + * + * Revision 1.7 1999/12/01 22:20:51 rgb + * Moved pfkey_lib_debug variable into the library. + * Added pfkey version check into header parsing. + * Added check for SATYPE only for those extensions that require a + * non-zero value. + * + * Revision 1.6 1999/11/27 11:58:05 rgb + * Added ipv6 headers. + * Moved sadb_satype2proto protocol lookup table from + * klips/net/ipsec/pfkey_v2_parser.c. + * Enable lifetime_current checking. + * Debugging error messages added. + * Add argument to pfkey_msg_parse() for direction. + * Consolidated the 4 1-d extension bitmap arrays into one 4-d array. + * Add CVS log entry to bottom of file. + * Moved auth and enc alg check to pfkey_msg_parse(). + * Enable accidentally disabled spirange parsing. + * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/libopenswan/pfkeyv2.h linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkeyv2.h --- linux-2.4.29/net/ipsec/libopenswan/pfkeyv2.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/pfkeyv2.h Tue Sep 30 02:26:03 2003 @@ -0,0 +1,411 @@ +/* + * RCSID $Id: pfkeyv2.h,v 1.5 2003/09/30 00:26:03 ken Exp $ + */ + +/* +RFC 2367 PF_KEY Key Management API July 1998 + + +Appendix D: Sample Header File + +This file defines structures and symbols for the PF_KEY Version 2 +key management interface. It was written at the U.S. Naval Research +Laboratory. This file is in the public domain. The authors ask that +you leave this credit intact on any copies of this file. +*/ +#ifndef __PFKEY_V2_H +#define __PFKEY_V2_H 1 + +#define PF_KEY_V2 2 +#define PFKEYV2_REVISION 199806L + +#define SADB_RESERVED 0 +#define SADB_GETSPI 1 +#define SADB_UPDATE 2 +#define SADB_ADD 3 +#define SADB_DELETE 4 +#define SADB_GET 5 +#define SADB_ACQUIRE 6 +#define SADB_REGISTER 7 +#define SADB_EXPIRE 8 +#define SADB_FLUSH 9 +#define SADB_DUMP 10 +#define SADB_X_PROMISC 11 +#define SADB_X_PCHANGE 12 +#define SADB_X_GRPSA 13 +#define SADB_X_ADDFLOW 14 +#define SADB_X_DELFLOW 15 +#define SADB_X_DEBUG 16 +#ifdef NAT_TRAVERSAL +#define SADB_X_NAT_T_NEW_MAPPING 17 +#define SADB_MAX 17 +#else +#define SADB_MAX 16 +#endif + +struct sadb_msg { + uint8_t sadb_msg_version; + uint8_t sadb_msg_type; + uint8_t sadb_msg_errno; + uint8_t sadb_msg_satype; + uint16_t sadb_msg_len; + uint16_t sadb_msg_reserved; + uint32_t sadb_msg_seq; + uint32_t sadb_msg_pid; +}; + +struct sadb_ext { + uint16_t sadb_ext_len; + uint16_t sadb_ext_type; +}; + +struct sadb_sa { + uint16_t sadb_sa_len; + uint16_t sadb_sa_exttype; + uint32_t sadb_sa_spi; + uint8_t sadb_sa_replay; + uint8_t sadb_sa_state; + uint8_t sadb_sa_auth; + uint8_t sadb_sa_encrypt; + uint32_t sadb_sa_flags; +}; + +struct sadb_lifetime { + uint16_t sadb_lifetime_len; + uint16_t sadb_lifetime_exttype; + uint32_t sadb_lifetime_allocations; + uint64_t sadb_lifetime_bytes; + uint64_t sadb_lifetime_addtime; + uint64_t sadb_lifetime_usetime; + uint32_t sadb_x_lifetime_packets; + uint32_t sadb_x_lifetime_reserved; +}; + +struct sadb_address { + uint16_t sadb_address_len; + uint16_t sadb_address_exttype; + uint8_t sadb_address_proto; + uint8_t sadb_address_prefixlen; + uint16_t sadb_address_reserved; +}; + +struct sadb_key { + uint16_t sadb_key_len; + uint16_t sadb_key_exttype; + uint16_t sadb_key_bits; + uint16_t sadb_key_reserved; +}; + +struct sadb_ident { + uint16_t sadb_ident_len; + uint16_t sadb_ident_exttype; + uint16_t sadb_ident_type; + uint16_t sadb_ident_reserved; + uint64_t sadb_ident_id; +}; + +struct sadb_sens { + uint16_t sadb_sens_len; + uint16_t sadb_sens_exttype; + uint32_t sadb_sens_dpd; + uint8_t sadb_sens_sens_level; + uint8_t sadb_sens_sens_len; + uint8_t sadb_sens_integ_level; + uint8_t sadb_sens_integ_len; + uint32_t sadb_sens_reserved; +}; + +struct sadb_prop { + uint16_t sadb_prop_len; + uint16_t sadb_prop_exttype; + uint8_t sadb_prop_replay; + uint8_t sadb_prop_reserved[3]; +}; + +struct sadb_comb { + uint8_t sadb_comb_auth; + uint8_t sadb_comb_encrypt; + uint16_t sadb_comb_flags; + uint16_t sadb_comb_auth_minbits; + uint16_t sadb_comb_auth_maxbits; + uint16_t sadb_comb_encrypt_minbits; + uint16_t sadb_comb_encrypt_maxbits; + uint32_t sadb_comb_reserved; + uint32_t sadb_comb_soft_allocations; + uint32_t sadb_comb_hard_allocations; + uint64_t sadb_comb_soft_bytes; + uint64_t sadb_comb_hard_bytes; + uint64_t sadb_comb_soft_addtime; + uint64_t sadb_comb_hard_addtime; + uint64_t sadb_comb_soft_usetime; + uint64_t sadb_comb_hard_usetime; + uint32_t sadb_x_comb_soft_packets; + uint32_t sadb_x_comb_hard_packets; +}; + +struct sadb_supported { + uint16_t sadb_supported_len; + uint16_t sadb_supported_exttype; + uint32_t sadb_supported_reserved; +}; + +struct sadb_alg { + uint8_t sadb_alg_id; + uint8_t sadb_alg_ivlen; + uint16_t sadb_alg_minbits; + uint16_t sadb_alg_maxbits; + uint16_t sadb_alg_reserved; +}; + +struct sadb_spirange { + uint16_t sadb_spirange_len; + uint16_t sadb_spirange_exttype; + uint32_t sadb_spirange_min; + uint32_t sadb_spirange_max; + uint32_t sadb_spirange_reserved; +}; + +struct sadb_x_kmprivate { + uint16_t sadb_x_kmprivate_len; + uint16_t sadb_x_kmprivate_exttype; + uint32_t sadb_x_kmprivate_reserved; +}; + +struct sadb_x_satype { + uint16_t sadb_x_satype_len; + uint16_t sadb_x_satype_exttype; + uint8_t sadb_x_satype_satype; + uint8_t sadb_x_satype_reserved[3]; +}; + +struct sadb_x_debug { + uint16_t sadb_x_debug_len; + uint16_t sadb_x_debug_exttype; + uint32_t sadb_x_debug_tunnel; + uint32_t sadb_x_debug_netlink; + uint32_t sadb_x_debug_xform; + uint32_t sadb_x_debug_eroute; + uint32_t sadb_x_debug_spi; + uint32_t sadb_x_debug_radij; + uint32_t sadb_x_debug_esp; + uint32_t sadb_x_debug_ah; + uint32_t sadb_x_debug_rcv; + uint32_t sadb_x_debug_pfkey; + uint32_t sadb_x_debug_ipcomp; + uint32_t sadb_x_debug_verbose; + uint8_t sadb_x_debug_reserved[4]; +}; + +#ifdef NAT_TRAVERSAL +struct sadb_x_nat_t_type { + uint16_t sadb_x_nat_t_type_len; + uint16_t sadb_x_nat_t_type_exttype; + uint8_t sadb_x_nat_t_type_type; + uint8_t sadb_x_nat_t_type_reserved[3]; +}; +struct sadb_x_nat_t_port { + uint16_t sadb_x_nat_t_port_len; + uint16_t sadb_x_nat_t_port_exttype; + uint16_t sadb_x_nat_t_port_port; + uint16_t sadb_x_nat_t_port_reserved; +}; +#endif + +/* + * A protocol structure for passing through the transport level + * protocol. It contains more fields than are actually used/needed + * but it is this way to be compatible with the structure used in + * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h) + */ +struct sadb_protocol { + uint16_t sadb_protocol_len; + uint16_t sadb_protocol_exttype; + uint8_t sadb_protocol_proto; + uint8_t sadb_protocol_direction; + uint8_t sadb_protocol_flags; + uint8_t sadb_protocol_reserved2; +}; + +#define SADB_EXT_RESERVED 0 +#define SADB_EXT_SA 1 +#define SADB_EXT_LIFETIME_CURRENT 2 +#define SADB_EXT_LIFETIME_HARD 3 +#define SADB_EXT_LIFETIME_SOFT 4 +#define SADB_EXT_ADDRESS_SRC 5 +#define SADB_EXT_ADDRESS_DST 6 +#define SADB_EXT_ADDRESS_PROXY 7 +#define SADB_EXT_KEY_AUTH 8 +#define SADB_EXT_KEY_ENCRYPT 9 +#define SADB_EXT_IDENTITY_SRC 10 +#define SADB_EXT_IDENTITY_DST 11 +#define SADB_EXT_SENSITIVITY 12 +#define SADB_EXT_PROPOSAL 13 +#define SADB_EXT_SUPPORTED_AUTH 14 +#define SADB_EXT_SUPPORTED_ENCRYPT 15 +#define SADB_EXT_SPIRANGE 16 +#define SADB_X_EXT_KMPRIVATE 17 +#define SADB_X_EXT_SATYPE2 18 +#define SADB_X_EXT_SA2 19 +#define SADB_X_EXT_ADDRESS_DST2 20 +#define SADB_X_EXT_ADDRESS_SRC_FLOW 21 +#define SADB_X_EXT_ADDRESS_DST_FLOW 22 +#define SADB_X_EXT_ADDRESS_SRC_MASK 23 +#define SADB_X_EXT_ADDRESS_DST_MASK 24 +#define SADB_X_EXT_DEBUG 25 +#define SADB_X_EXT_PROTOCOL 26 +#ifdef NAT_TRAVERSAL +#define SADB_X_EXT_NAT_T_TYPE 27 +#define SADB_X_EXT_NAT_T_SPORT 28 +#define SADB_X_EXT_NAT_T_DPORT 29 +#define SADB_X_EXT_NAT_T_OA 30 +#define SADB_EXT_MAX 30 +#else +#define SADB_EXT_MAX 26 + +#endif + +/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */ +#define SADB_X_EXT_ADDRESS_DELFLOW \ + ( (1<. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: portof.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - portof - get the port field of an ip_address + */ +int /* network order */ +portof(src) +const ip_address *src; +{ + switch (src->u.v4.sin_family) { + case AF_INET: + return src->u.v4.sin_port; + break; + case AF_INET6: + return src->u.v6.sin6_port; + break; + default: + return -1; /* "can't happen" */ + break; + } +} + +/* + - setportof - set the port field of an ip_address + */ +void +setportof(port, dst) +int port; /* network order */ +ip_address *dst; +{ + switch (dst->u.v4.sin_family) { + case AF_INET: + dst->u.v4.sin_port = port; + break; + case AF_INET6: + dst->u.v6.sin6_port = port; + break; + } +} + +/* + - sockaddrof - get a pointer to the sockaddr hiding inside an ip_address + */ +struct sockaddr * +sockaddrof(src) +ip_address *src; +{ + switch (src->u.v4.sin_family) { + case AF_INET: + return (struct sockaddr *)&src->u.v4; + break; + case AF_INET6: + return (struct sockaddr *)&src->u.v6; + break; + default: + return NULL; /* "can't happen" */ + break; + } +} + +/* + - sockaddrlenof - get length of the sockaddr hiding inside an ip_address + */ +size_t /* 0 for error */ +sockaddrlenof(src) +const ip_address *src; +{ + switch (src->u.v4.sin_family) { + case AF_INET: + return sizeof(src->u.v4); + break; + case AF_INET6: + return sizeof(src->u.v6); + break; + default: + return 0; + break; + } +} diff -urN linux-2.4.29/net/ipsec/libopenswan/prng.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/prng.c --- linux-2.4.29/net/ipsec/libopenswan/prng.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/prng.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,202 @@ +/* + * crypto-class pseudorandom number generator + * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397 + * Copyright (C) 2002 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: prng.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - prng_init - initialize PRNG from a key + */ +void +prng_init(prng, key, keylen) +struct prng *prng; +const unsigned char *key; +size_t keylen; +{ + unsigned char k[256]; + int i, j; + unsigned const char *p; + unsigned const char *keyend = key + keylen; + unsigned char t; + + for (i = 0; i <= 255; i++) + prng->sbox[i] = i; + p = key; + for (i = 0; i <= 255; i++) { + k[i] = *p++; + if (p >= keyend) + p = key; + } + j = 0; + for (i = 0; i <= 255; i++) { + j = (j + prng->sbox[i] + k[i]) & 0xff; + t = prng->sbox[i]; + prng->sbox[i] = prng->sbox[j]; + prng->sbox[j] = t; + k[i] = 0; /* clear out key memory */ + } + prng->i = 0; + prng->j = 0; + prng->count = 0; +} + +/* + - prng_bytes - get some pseudorandom bytes from PRNG + */ +void +prng_bytes(prng, dst, dstlen) +struct prng *prng; +unsigned char *dst; +size_t dstlen; +{ + int i, j, t; + unsigned char *p = dst; + size_t remain = dstlen; +# define MAX 4000000000ul + + while (remain > 0) { + i = (prng->i + 1) & 0xff; + prng->i = i; + j = (prng->j + prng->sbox[i]) & 0xff; + prng->j = j; + t = prng->sbox[i]; + prng->sbox[i] = prng->sbox[j]; + prng->sbox[j] = t; + t = (t + prng->sbox[i]) & 0xff; + *p++ = prng->sbox[t]; + remain--; + } + if (prng->count < MAX - dstlen) + prng->count += dstlen; + else + prng->count = MAX; +} + +/* + - prnt_count - how many bytes have been extracted from PRNG so far? + */ +unsigned long +prng_count(prng) +struct prng *prng; +{ + return prng->count; +} + +/* + - prng_final - clear out PRNG to ensure nothing left in memory + */ +void +prng_final(prng) +struct prng *prng; +{ + int i; + + for (i = 0; i <= 255; i++) + prng->sbox[i] = 0; + prng->i = 0; + prng->j = 0; + prng->count = 0; /* just for good measure */ +} + + + +#ifdef PRNG_MAIN + +#include + +void regress(); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + struct prng pr; + unsigned char buf[100]; + unsigned char *p; + size_t n; + + if (argc < 2) { + fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]); + exit(2); + } + + if (strcmp(argv[1], "-r") == 0) { + regress(); + fprintf(stderr, "regress() returned?!?\n"); + exit(1); + } + + prng_init(&pr, argv[1], strlen(argv[1])); + prng_bytes(&pr, buf, 32); + printf("0x"); + for (p = buf, n = 32; n > 0; p++, n--) + printf("%02x", *p); + printf("\n%lu bytes\n", prng_count(&pr)); + prng_final(&pr); + exit(0); +} + +void +regress() +{ + struct prng pr; + unsigned char buf[100]; + unsigned char *p; + size_t n; + /* somewhat non-random sample key */ + unsigned char key[] = "here we go gathering nuts in May"; + /* first thirty bytes of output from that key */ + unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c" + "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71" + "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28"; + int nzero, none; + int show = 0; + + prng_init(&pr, key, strlen(key)); + prng_bytes(&pr, buf, sizeof(buf)); + for (p = buf, n = sizeof(buf); n > 0; p++, n--) { + if (*p == 0) + nzero++; + if (*p == 255) + none++; + } + if (nzero > 3 || none > 3) { + fprintf(stderr, "suspiciously non-random output!\n"); + show = 1; + } + if (memcmp(buf, good, strlen(good)) != 0) { + fprintf(stderr, "incorrect output!\n"); + show = 1; + } + if (show) { + fprintf(stderr, "0x"); + for (p = buf, n = sizeof(buf); n > 0; p++, n--) + fprintf(stderr, "%02x", *p); + fprintf(stderr, "\n"); + exit(1); + } + if (prng_count(&pr) != sizeof(buf)) { + fprintf(stderr, "got %u bytes, but count is %lu\n", + sizeof(buf), prng_count(&pr)); + exit(1); + } + prng_final(&pr); + exit(0); +} + +#endif /* PRNG_MAIN */ diff -urN linux-2.4.29/net/ipsec/libopenswan/rangetoa.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/rangetoa.c --- linux-2.4.29/net/ipsec/libopenswan/rangetoa.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/rangetoa.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,61 @@ +/* + * convert binary form of address range to ASCII + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: rangetoa.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - rangetoa - convert address range to ASCII + */ +size_t /* space needed for full conversion */ +rangetoa(addrs, format, dst, dstlen) +struct in_addr addrs[2]; +int format; /* character */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + size_t len; + size_t rest; + int n; + char *p; + + switch (format) { + case 0: + break; + default: + return 0; + break; + } + + len = addrtoa(addrs[0], 0, dst, dstlen); + if (len < dstlen) + for (p = dst + len - 1, n = 3; len < dstlen && n > 0; + p++, len++, n--) + *p = '.'; + else + p = NULL; + if (len < dstlen) + rest = dstlen - len; + else { + if (dstlen > 0) + *(dst + dstlen - 1) = '\0'; + rest = 0; + } + + len += addrtoa(addrs[1], 0, p, rest); + + return len; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/rangetosubnet.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/rangetosubnet.c --- linux-2.4.29/net/ipsec/libopenswan/rangetosubnet.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/rangetosubnet.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,228 @@ +/* + * express an address range as a subnet (if possible) + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: rangetosubnet.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - rangetosubnet - turn an address range into a subnet, if possible + * + * A range which is a valid subnet will have a network part which is the + * same in the from value and the to value, followed by a host part which + * is all 0 in the from value and all 1 in the to value. + */ +err_t +rangetosubnet(from, to, dst) +const ip_address *from; +const ip_address *to; +ip_subnet *dst; +{ + unsigned const char *fp; + unsigned const char *tp; + unsigned fb; + unsigned tb; + unsigned const char *f; + unsigned const char *t; + size_t n; + size_t n2; + int i; + int nnet; + unsigned m; + + if (addrtypeof(from) != addrtypeof(to)) + return "mismatched address types"; + n = addrbytesptr(from, &fp); + if (n == 0) + return "unknown address type"; + n2 = addrbytesptr(to, &tp); + if (n != n2) + return "internal size mismatch in rangetosubnet"; + + f = fp; + t = tp; + nnet = 0; + for (i = n; i > 0 && *f == *t; i--, f++, t++) + nnet += 8; + if (i > 0 && !(*f == 0x00 && *t == 0xff)) { /* mid-byte bdry. */ + fb = *f++; + tb = *t++; + i--; + m = 0x80; + while ((fb&m) == (tb&m)) { + fb &= ~m; + tb |= m; + m >>= 1; + nnet++; + } + if (fb != 0x00 || tb != 0xff) + return "not a valid subnet"; + } + for (; i > 0 && *f == 0x00 && *t == 0xff; i--, f++, t++) + continue; + + if (i != 0) + return "invalid subnet"; + + return initsubnet(from, nnet, 'x', dst); +} + + + +#ifdef RANGETOSUBNET_MAIN + +#include + +void regress(); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + ip_address start; + ip_address stop; + ip_subnet sub; + char buf[100]; + const char *oops; + size_t n; + int af; + int i; + + if (argc == 2 && strcmp(argv[1], "-r") == 0) { + regress(); + fprintf(stderr, "regress() returned?!?\n"); + exit(1); + } + + if (argc < 3) { + fprintf(stderr, "Usage: %s [-6] start stop\n", argv[0]); + fprintf(stderr, " or: %s -r\n", argv[0]); + exit(2); + } + + af = AF_INET; + i = 1; + if (strcmp(argv[i], "-6") == 0) { + af = AF_INET6; + i++; + } + + oops = ttoaddr(argv[i], 0, af, &start); + if (oops != NULL) { + fprintf(stderr, "%s: start conversion failed: %s\n", argv[0], oops); + exit(1); + } + oops = ttoaddr(argv[i+1], 0, af, &stop); + if (oops != NULL) { + fprintf(stderr, "%s: stop conversion failed: %s\n", argv[0], oops); + exit(1); + } + oops = rangetosubnet(&start, &stop, &sub); + if (oops != NULL) { + fprintf(stderr, "%s: rangetosubnet failed: %s\n", argv[0], oops); + exit(1); + } + n = subnettot(&sub, 0, buf, sizeof(buf)); + if (n > sizeof(buf)) { + fprintf(stderr, "%s: reverse conversion", argv[0]); + fprintf(stderr, " failed: need %ld bytes, have only %ld\n", + (long)n, (long)sizeof(buf)); + exit(1); + } + printf("%s\n", buf); + + exit(0); +} + +struct rtab { + int family; + char *start; + char *stop; + char *output; /* NULL means error expected */ +} rtab[] = { + 4, "1.2.3.0", "1.2.3.255", "1.2.3.0/24", + 4, "1.2.3.0", "1.2.3.7", "1.2.3.0/29", + 4, "1.2.3.240", "1.2.3.255", "1.2.3.240/28", + 4, "0.0.0.0", "255.255.255.255", "0.0.0.0/0", + 4, "1.2.3.4", "1.2.3.4", "1.2.3.4/32", + 4, "1.2.3.0", "1.2.3.254", NULL, + 4, "1.2.3.0", "1.2.3.126", NULL, + 4, "1.2.3.0", "1.2.3.125", NULL, + 4, "1.2.0.0", "1.2.255.255", "1.2.0.0/16", + 4, "1.2.0.0", "1.2.0.255", "1.2.0.0/24", + 4, "1.2.255.0", "1.2.255.255", "1.2.255.0/24", + 4, "1.2.255.0", "1.2.254.255", NULL, + 4, "1.2.255.1", "1.2.255.255", NULL, + 4, "1.2.0.1", "1.2.255.255", NULL, + 6, "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:ffff", "1:2:3:4:5:6:7:0/112", + 6, "1:2:3:4:5:6:7:0", "1:2:3:4:5:6:7:fff", "1:2:3:4:5:6:7:0/116", + 6, "1:2:3:4:5:6:7:f0", "1:2:3:4:5:6:7:ff", "1:2:3:4:5:6:7:f0/124", + 4, NULL, NULL, NULL, +}; + +void +regress() +{ + struct rtab *r; + int status = 0; + ip_address start; + ip_address stop; + ip_subnet sub; + char buf[100]; + const char *oops; + size_t n; + int af; + + for (r = rtab; r->start != NULL; r++) { + af = (r->family == 4) ? AF_INET : AF_INET6; + oops = ttoaddr(r->start, 0, af, &start); + if (oops != NULL) { + printf("surprise failure converting `%s'\n", r->start); + exit(1); + } + oops = ttoaddr(r->stop, 0, af, &stop); + if (oops != NULL) { + printf("surprise failure converting `%s'\n", r->stop); + exit(1); + } + oops = rangetosubnet(&start, &stop, &sub); + if (oops != NULL && r->output == NULL) + {} /* okay, error expected */ + else if (oops != NULL) { + printf("`%s'-`%s' rangetosubnet failed: %s\n", + r->start, r->stop, oops); + status = 1; + } else if (r->output == NULL) { + printf("`%s'-`%s' rangetosubnet succeeded unexpectedly\n", + r->start, r->stop); + status = 1; + } else { + n = subnettot(&sub, 0, buf, sizeof(buf)); + if (n > sizeof(buf)) { + printf("`%s'-`%s' subnettot failed: need %ld\n", + r->start, r->stop, (long)n); + status = 1; + } else if (strcmp(r->output, buf) != 0) { + printf("`%s'-`%s' gave `%s', expected `%s'\n", + r->start, r->stop, buf, r->output); + status = 1; + } + } + } + exit(status); +} + +#endif /* RANGETOSUBNET_MAIN */ diff -urN linux-2.4.29/net/ipsec/libopenswan/sameaddr.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/sameaddr.c --- linux-2.4.29/net/ipsec/libopenswan/sameaddr.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/sameaddr.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,190 @@ +/* + * comparisons + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: sameaddr.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +static int samenbits(const ip_address *a, const ip_address *b, int n); + +/* + - addrcmp - compare two addresses + * Caution, the order of the tests is subtle: doing type test before + * size test can yield cases where ac. + */ +int /* like memcmp */ +addrcmp(a, b) +const ip_address *a; +const ip_address *b; +{ + int at = addrtypeof(a); + int bt = addrtypeof(b); + const unsigned char *ap; + const unsigned char *bp; + size_t as = addrbytesptr(a, &ap); + size_t bs = addrbytesptr(b, &bp); + size_t n = (as < bs) ? as : bs; /* min(as, bs) */ + int c = memcmp(ap, bp, n); + + if (c != 0) /* bytes differ */ + return (c < 0) ? -1 : 1; + if (as != bs) /* comparison incomplete: lexical order */ + return (as < bs) ? -1 : 1; + if (at != bt) /* bytes same but not same type: break tie */ + return (at < bt) ? -1 : 1; + return 0; +} + +/* + - sameaddr - are two addresses the same? + */ +int +sameaddr(a, b) +const ip_address *a; +const ip_address *b; +{ + return (addrcmp(a, b) == 0) ? 1 : 0; +} + +/* + - samesubnet - are two subnets the same? + */ +int +samesubnet(a, b) +const ip_subnet *a; +const ip_subnet *b; +{ + if (!sameaddr(&a->addr, &b->addr)) /* also does type check */ + return 0; + if (a->maskbits != b->maskbits) + return 0; + return 1; +} + +/* + - subnetishost - is a subnet in fact a single host? + */ +int +subnetishost(a) +const ip_subnet *a; +{ + return (a->maskbits == addrlenof(&a->addr)*8) ? 1 : 0; +} + +/* + - samesaid - are two SA IDs the same? + */ +int +samesaid(a, b) +const ip_said *a; +const ip_said *b; +{ + if (a->spi != b->spi) /* test first, most likely to be different */ + return 0; + if (!sameaddr(&a->dst, &b->dst)) + return 0; + if (a->proto != b->proto) + return 0; + return 1; +} + +/* + - sameaddrtype - do two addresses have the same type? + */ +int +sameaddrtype(a, b) +const ip_address *a; +const ip_address *b; +{ + return (addrtypeof(a) == addrtypeof(b)) ? 1 : 0; +} + +/* + - samesubnettype - do two subnets have the same type? + */ +int +samesubnettype(a, b) +const ip_subnet *a; +const ip_subnet *b; +{ + return (subnettypeof(a) == subnettypeof(b)) ? 1 : 0; +} + +/* + - addrinsubnet - is this address in this subnet? + */ +int +addrinsubnet(a, s) +const ip_address *a; +const ip_subnet *s; +{ + if (addrtypeof(a) != subnettypeof(s)) + return 0; + if (!samenbits(a, &s->addr, s->maskbits)) + return 0; + return 1; +} + +/* + - subnetinsubnet - is one subnet within another? + */ +int +subnetinsubnet(a, b) +const ip_subnet *a; +const ip_subnet *b; +{ + if (subnettypeof(a) != subnettypeof(b)) + return 0; + if (a->maskbits < b->maskbits) /* a is bigger than b */ + return 0; + if (!samenbits(&a->addr, &b->addr, b->maskbits)) + return 0; + return 1; +} + +/* + - samenbits - do two addresses have the same first n bits? + */ +static int +samenbits(a, b, nbits) +const ip_address *a; +const ip_address *b; +int nbits; +{ + const unsigned char *ap; + const unsigned char *bp; + size_t n; + int m; + + if (addrtypeof(a) != addrtypeof(b)) + return 0; /* arbitrary */ + n = addrbytesptr(a, &ap); + if (n == 0) + return 0; /* arbitrary */ + (void) addrbytesptr(b, &bp); + if (nbits > n*8) + return 0; /* "can't happen" */ + + for (; nbits >= 8 && *ap == *bp; nbits -= 8, ap++, bp++) + continue; + if (nbits >= 8) + return 0; + if (nbits > 0) { /* partial byte */ + m = ~(0xff >> nbits); + if ((*ap & m) != (*bp & m)) + return 0; + } + return 1; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/satoa.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/satoa.c --- linux-2.4.29/net/ipsec/libopenswan/satoa.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/satoa.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,102 @@ +/* + * convert from binary form of SA ID to ASCII + * Copyright (C) 1998, 1999, 2001 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: satoa.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +static struct typename { + char type; + char *name; +} typenames[] = { + { SA_AH, "ah" }, + { SA_ESP, "esp" }, + { SA_IPIP, "tun" }, + { SA_COMP, "comp" }, + { SA_INT, "int" }, + { 0, NULL } +}; + +/* + - satoa - convert SA to ASCII "ah507@1.2.3.4" + */ +size_t /* space needed for full conversion */ +satoa(sa, format, dst, dstlen) +struct sa_id sa; +int format; /* character */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + size_t len = 0; /* 0 means not handled yet */ + int base; + struct typename *tn; + char buf[30+ADDRTOA_BUF]; + + switch (format) { + case 0: + base = 16; /* temporarily at least */ + break; + case 'd': + base = 10; + break; + default: + return 0; + break; + } + + for (tn = typenames; tn->name != NULL; tn++) + if (sa.proto == tn->type) + break; + if (tn->name == NULL) + return 0; + + if (strcmp(tn->name, PASSTHROUGHTYPE) == 0 && + sa.spi == PASSTHROUGHSPI && + sa.dst.s_addr == PASSTHROUGHDST) { + strcpy(buf, PASSTHROUGHNAME); + len = strlen(buf); + } else if (sa.proto == SA_INT && sa.dst.s_addr == 0) { + char *p; + + switch (ntohl(sa.spi)) { + case SPI_PASS: p = "%pass"; break; + case SPI_DROP: p = "%drop"; break; + case SPI_REJECT: p = "%reject"; break; + case SPI_HOLD: p = "%hold"; break; + case SPI_TRAP: p = "%trap"; break; + case SPI_TRAPSUBNET: p = "%trapsubnet"; break; + default: p = NULL; break; + } + if (p != NULL) { + strcpy(buf, p); + len = strlen(buf); + } + } + + if (len == 0) { + strcpy(buf, tn->name); + len = strlen(buf); + len += ultoa(ntohl(sa.spi), base, buf+len, sizeof(buf)-len); + *(buf+len-1) = '@'; + len += addrtoa(sa.dst, 0, buf+len, sizeof(buf)-len); + } + + if (dst != NULL) { + if (len > dstlen) + *(buf+dstlen-1) = '\0'; + strcpy(dst, buf); + } + return len; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/satot.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/satot.c --- linux-2.4.29/net/ipsec/libopenswan/satot.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/satot.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,132 @@ +/* + * convert from binary form of SA ID to text + * Copyright (C) 2000, 2001 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: satot.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +static struct typename { + char type; + char *name; +} typenames[] = { + { SA_AH, "ah" }, + { SA_ESP, "esp" }, + { SA_IPIP, "tun" }, + { SA_COMP, "comp" }, + { SA_INT, "int" }, + { 0, NULL } +}; + +/* + - satot - convert SA to text "ah507@1.2.3.4" + */ +size_t /* space needed for full conversion */ +satot(sa, format, dst, dstlen) +const ip_said *sa; +int format; /* character */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + size_t len = 0; /* 0 means "not recognized yet" */ + int base; + int showversion; /* use delimiter to show IP version? */ + struct typename *tn; + char *p; + char *pre; + char buf[10+1+ULTOT_BUF+ADDRTOT_BUF]; + char unk[10]; + + switch (format) { + case 0: + base = 16; + showversion = 1; + break; + case 'f': + base = 17; + showversion = 1; + break; + case 'x': + base = 'x'; + showversion = 0; + break; + case 'd': + base = 10; + showversion = 0; + break; + default: + return 0; + break; + } + + pre = NULL; + for (tn = typenames; tn->name != NULL; tn++) + if (sa->proto == tn->type) { + pre = tn->name; + break; /* NOTE BREAK OUT */ + } + if (pre == NULL) { /* unknown protocol */ + strcpy(unk, "unk"); + (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk), + sizeof(unk)-strlen(unk)); + pre = unk; + } + + if (strcmp(pre, PASSTHROUGHTYPE) == 0 && + sa->spi == PASSTHROUGHSPI && + isunspecaddr(&sa->dst)) { + strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ? + PASSTHROUGH4NAME : + PASSTHROUGH6NAME); + len = strlen(buf); + } + + if (sa->proto == SA_INT && addrtypeof(&sa->dst) == AF_INET && + isunspecaddr(&sa->dst)) { + switch (ntohl(sa->spi)) { + case SPI_PASS: p = "%pass"; break; + case SPI_DROP: p = "%drop"; break; + case SPI_REJECT: p = "%reject"; break; + case SPI_HOLD: p = "%hold"; break; + case SPI_TRAP: p = "%trap"; break; + case SPI_TRAPSUBNET: p = "%trapsubnet"; break; + default: p = NULL; break; + } + if (p != NULL) { + strcpy(buf, p); + len = strlen(buf); + } + } + + if (len == 0) { /* general case needed */ + strcpy(buf, pre); + len = strlen(buf); + if (showversion) { + *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' : + ':'; + len++; + *(buf+len) = '\0'; + } + len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len); + *(buf+len-1) = '@'; + len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len); + } + + if (dst != NULL) { + if (len > dstlen) + *(buf+dstlen-1) = '\0'; + strcpy(dst, buf); + } + return len; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/subnetof.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/subnetof.c --- linux-2.4.29/net/ipsec/libopenswan/subnetof.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/subnetof.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,60 @@ +/* + * minor network-address manipulation utilities + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: subnetof.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - subnetof - given address and mask, return subnet part + */ +struct in_addr +subnetof(addr, mask) +struct in_addr addr; +struct in_addr mask; +{ + struct in_addr result; + + result.s_addr = addr.s_addr & mask.s_addr; + return result; +} + +/* + - hostof - given address and mask, return host part + */ +struct in_addr +hostof(addr, mask) +struct in_addr addr; +struct in_addr mask; +{ + struct in_addr result; + + result.s_addr = addr.s_addr & ~mask.s_addr; + return result; +} + +/* + - broadcastof - given (network) address and mask, return broadcast address + */ +struct in_addr +broadcastof(addr, mask) +struct in_addr addr; +struct in_addr mask; +{ + struct in_addr result; + + result.s_addr = addr.s_addr | ~mask.s_addr; + return result; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/subnettoa.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/subnettoa.c --- linux-2.4.29/net/ipsec/libopenswan/subnettoa.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/subnettoa.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,62 @@ +/* + * convert binary form of subnet description to ASCII + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: subnettoa.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - subnettoa - convert address and mask to ASCII "addr/mask" + * Output expresses the mask as a bit count if possible, else dotted decimal. + */ +size_t /* space needed for full conversion */ +subnettoa(addr, mask, format, dst, dstlen) +struct in_addr addr; +struct in_addr mask; +int format; /* character */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + size_t len; + size_t rest; + int n; + char *p; + + switch (format) { + case 0: + break; + default: + return 0; + break; + } + + len = addrtoa(addr, 0, dst, dstlen); + if (len < dstlen) { + dst[len - 1] = '/'; + p = dst + len; + rest = dstlen - len; + } else { + p = NULL; + rest = 0; + } + + n = masktobits(mask); + if (n >= 0) + len += ultoa((unsigned long)n, 10, p, rest); + else + len += addrtoa(mask, 0, p, rest); + + return len; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/subnettot.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/subnettot.c --- linux-2.4.29/net/ipsec/libopenswan/subnettot.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/subnettot.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,56 @@ +/* + * convert binary form of subnet description to text + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: subnettot.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - subnettot - convert subnet to text "addr/bitcount" + */ +size_t /* space needed for full conversion */ +subnettot(sub, format, dst, dstlen) +const ip_subnet *sub; +int format; /* character */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + size_t len; + size_t rest; + char *p; + + switch (format) { + case 0: + break; + default: + return 0; + break; + } + + len = addrtot(&sub->addr, format, dst, dstlen); + if (len < dstlen) { + dst[len - 1] = '/'; + p = dst + len; + rest = dstlen - len; + } else { + p = NULL; + rest = 0; + } + + + len += ultoa((unsigned long)sub->maskbits, 10, p, rest); + + return len; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/subnettypeof.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/subnettypeof.c --- linux-2.4.29/net/ipsec/libopenswan/subnettypeof.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/subnettypeof.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,109 @@ +/* + * extract parts of an ip_subnet, and related + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: subnettypeof.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - subnettypeof - get the address type of an ip_subnet + */ +int +subnettypeof(src) +const ip_subnet *src; +{ + return src->addr.u.v4.sin_family; +} + +/* + - networkof - get the network address of a subnet + */ +void +networkof(src, dst) +const ip_subnet *src; +ip_address *dst; +{ + *dst = src->addr; +} + +/* + - maskof - get the mask of a subnet, as an address + */ +void +maskof(src, dst) +const ip_subnet *src; +ip_address *dst; +{ + int b; + unsigned char buf[16]; + size_t n = addrlenof(&src->addr); + unsigned char *p; + + if (src->maskbits > n*8 || n > sizeof(buf)) + return; /* "can't happen" */ + + p = buf; + for (b = src->maskbits; b >= 8; b -= 8) + *p++ = 0xff; + if (b != 0) + *p++ = (0xff << (8 - b)) & 0xff; + while (p - buf < n) + *p++ = 0; + + (void) initaddr(buf, n, addrtypeof(&src->addr), dst); +} + +/* + - masktocount - convert a mask, expressed as an address, to a bit count + */ +int /* -1 if not valid mask */ +masktocount(src) +const ip_address *src; +{ + int b; + unsigned const char *bp; + size_t n; + unsigned const char *p; + unsigned const char *stop; + + n = addrbytesptr(src, &bp); + if (n == 0) + return -1; + + p = bp; + stop = bp + n; + + n = 0; + while (p < stop && *p == 0xff) { + p++; + n += 8; + } + if (p < stop && *p != 0) { /* boundary in mid-byte */ + b = *p++; + while (b&0x80) { + b <<= 1; + n++; + } + if ((b&0xff) != 0) + return -1; /* bits not contiguous */ + } + while (p < stop && *p == 0) + p++; + + if (p != stop) + return -1; + + return n; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/ttoaddr.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttoaddr.c --- linux-2.4.29/net/ipsec/libopenswan/ttoaddr.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttoaddr.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,405 @@ +/* + * conversion from text forms of addresses to internal ones + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: ttoaddr.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + * Legal ASCII characters in a domain name. Underscore technically is not, + * but is a common misunderstanding. Non-ASCII characters are simply + * exempted from checking at the moment, to allow for UTF-8 encoded stuff; + * the purpose of this check is merely to catch blatant errors. + */ +static const char namechars[] = "abcdefghijklmnopqrstuvwxyz0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ-_."; +#define ISASCII(c) (((c) & 0x80) == 0) + +static err_t tryname(const char *, size_t, int, int, ip_address *); +static err_t tryhex(const char *, size_t, int, ip_address *); +static err_t trydotted(const char *, size_t, ip_address *); +static err_t getbyte(const char **, const char *, int *); +static err_t colon(const char *, size_t, ip_address *); +static err_t getpiece(const char **, const char *, unsigned *); + +/* + - ttoaddr - convert text name or dotted-decimal address to binary address + */ +err_t /* NULL for success, else string literal */ +ttoaddr(src, srclen, af, dst) +const char *src; +size_t srclen; /* 0 means "apply strlen" */ +int af; /* address family */ +ip_address *dst; +{ + err_t oops; +# define HEXLEN 10 /* strlen("0x11223344") */ + int nultermd; + + if (srclen == 0) { + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + nultermd = 1; + } else + nultermd = 0; /* at least, not *known* to be terminated */ + + switch (af) { + case AF_INET: + case AF_INET6: + break; + default: + return "invalid address family"; + } + + if (af == AF_INET && srclen == HEXLEN && *src == '0') { + if (*(src+1) == 'x' || *(src+1) == 'X') + return tryhex(src+2, srclen-2, 'x', dst); + if (*(src+1) == 'h' || *(src+1) == 'H') + return tryhex(src+2, srclen-2, 'h', dst); + } + + if (memchr(src, ':', srclen) != NULL) { + if (af != AF_INET6) + return "non-ipv6 address may not contain `:'"; + return colon(src, srclen, dst); + } + + if (af == AF_INET) { + oops = trydotted(src, srclen, dst); + if (oops == NULL) + return NULL; /* it worked */ + if (*oops != '?') + return oops; /* probably meant as d-d */ + } + + return tryname(src, srclen, nultermd, af, dst); +} + +/* + - tnatoaddr - convert text numeric address (only) to binary address + */ +err_t /* NULL for success, else string literal */ +tnatoaddr(src, srclen, af, dst) +const char *src; +size_t srclen; /* 0 means "apply strlen" */ +int af; /* address family */ +ip_address *dst; +{ + err_t oops; + + if (srclen == 0) { + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + } + + switch (af) { + case AF_INET6: + return colon(src, srclen, dst); + break; + case AF_INET: + oops = trydotted(src, srclen, dst); + if (oops == NULL) + return NULL; /* it worked */ + if (*oops != '?') + return oops; /* probably meant as d-d */ + return "does not appear to be numeric address"; + break; + default: + return "unknown address family in tnatoaddr"; + break; + } +} + +/* + - tryname - try it as a name + * Slightly complicated by lack of reliable NUL termination in source. + */ +static err_t +tryname(src, srclen, nultermd, af, dst) +const char *src; +size_t srclen; +int nultermd; /* is it known to be NUL-terminated? */ +int af; +ip_address *dst; +{ + struct hostent *h; + struct netent *ne = NULL; + char namebuf[100]; /* enough for most DNS names */ + const char *cp; + char *p = namebuf; + size_t n; + + for (cp = src, n = srclen; n > 0; cp++, n--) + if (ISASCII(*cp) && strchr(namechars, *cp) == NULL) + return "illegal (non-DNS-name) character in name"; + + if (nultermd) + cp = src; + else { + if (srclen+1 > sizeof(namebuf)) { + p = (char *) MALLOC(srclen+1); + if (p == NULL) + return "unable to get temporary space for name"; + } + p[0] = '\0'; /* strncpy semantics are wrong */ + strncat(p, src, srclen); + cp = (const char *)p; + } + + h = gethostbyname2(cp, af); + if (h == NULL && af == AF_INET) + ne = getnetbyname(cp); + if (p != namebuf) + FREE(p); + if (h == NULL && ne == NULL) + return "does not look numeric and name lookup failed"; + + if (h != NULL) { + if (h->h_addrtype != af) + return "address-type mismatch from gethostbyname2!!!"; + return initaddr((unsigned char *)h->h_addr, h->h_length, af, dst); + } else { + if (ne->n_addrtype != af) + return "address-type mismatch from getnetbyname!!!"; + ne->n_net = htonl(ne->n_net); + return initaddr((unsigned char *)&ne->n_net, sizeof(ne->n_net), + af, dst); + } +} + +/* + - tryhex - try conversion as an eight-digit hex number (AF_INET only) + */ +static err_t +tryhex(src, srclen, flavor, dst) +const char *src; +size_t srclen; /* should be 8 */ +int flavor; /* 'x' for network order, 'h' for host order */ +ip_address *dst; +{ + err_t oops; + unsigned long ul; + union { + uint32_t addr; + unsigned char buf[4]; + } u; + + if (srclen != 8) + return "internal error, tryhex called with bad length"; + + oops = ttoul(src, srclen, 16, &ul); + if (oops != NULL) + return oops; + + u.addr = (flavor == 'h') ? ul : htonl(ul); + return initaddr(u.buf, sizeof(u.buf), AF_INET, dst); +} + +/* + - trydotted - try conversion as dotted decimal (AF_INET only) + * + * If the first char of a complaint is '?', that means "didn't look like + * dotted decimal at all". + */ +static err_t +trydotted(src, srclen, dst) +const char *src; +size_t srclen; +ip_address *dst; +{ + const char *stop = src + srclen; /* just past end */ + int byte; + err_t oops; +# define NBYTES 4 + unsigned char buf[NBYTES]; + int i; + + memset(buf, 0, sizeof(buf)); + for (i = 0; i < NBYTES && src < stop; i++) { + oops = getbyte(&src, stop, &byte); + if (oops != NULL) { + if (*oops != '?') + return oops; /* bad number */ + if (i > 1) + return oops+1; /* failed number */ + return oops; /* with leading '?' */ + } + buf[i] = byte; + if (i < 3 && src < stop && *src++ != '.') { + if (i == 0) + return "?syntax error in dotted-decimal address"; + else + return "syntax error in dotted-decimal address"; + } + } + if (src != stop) + return "extra garbage on end of dotted-decimal address"; + + return initaddr(buf, sizeof(buf), AF_INET, dst); +} + +/* + - getbyte - try to scan a byte in dotted decimal + * A subtlety here is that all this arithmetic on ASCII digits really is + * highly portable -- ANSI C guarantees that digits 0-9 are contiguous. + * It's easier to just do it ourselves than set up for a call to ttoul(). + * + * If the first char of a complaint is '?', that means "didn't look like a + * number at all". + */ +err_t +getbyte(srcp, stop, retp) +const char **srcp; /* *srcp is updated */ +const char *stop; /* first untouchable char */ +int *retp; /* return-value pointer */ +{ + char c; + const char *p; + int no; + + if (*srcp >= stop) + return "?empty number in dotted-decimal address"; + + no = 0; + p = *srcp; + while (p < stop && no <= 255 && (c = *p) >= '0' && c <= '9') { + no = no*10 + (c - '0'); + p++; + } + if (p == *srcp) + return "?non-numeric component in dotted-decimal address"; + *srcp = p; + if (no > 255) + return "byte overflow in dotted-decimal address"; + *retp = no; + return NULL; +} + +/* + - colon - convert IPv6 "numeric" address + */ +static err_t +colon(src, srclen, dst) +const char *src; +size_t srclen; /* known to be >0 */ +ip_address *dst; +{ + const char *stop = src + srclen; /* just past end */ + unsigned piece; + int gapat; /* where was empty piece seen */ + err_t oops; +# define NPIECES 8 + unsigned char buf[NPIECES*2]; /* short may have wrong byte order */ + int i; + int j; +# define IT "IPv6 numeric address" + int naftergap; + + /* leading or trailing :: becomes single empty field */ + if (*src == ':') { /* legal only if leading :: */ + if (srclen == 1 || *(src+1) != ':') + return "illegal leading `:' in " IT; + if (srclen == 2) { + unspecaddr(AF_INET6, dst); + return NULL; + } + src++; /* past first but not second */ + srclen--; + } + if (*(stop-1) == ':') { /* legal only if trailing :: */ + if (srclen == 1 || *(stop-2) != ':') + return "illegal trailing `:' in " IT; + srclen--; /* leave one */ + } + + gapat = -1; + for (i = 0; i < NPIECES && src < stop; i++) { + oops = getpiece(&src, stop, &piece); + if (oops != NULL && *oops == ':') { /* empty field */ + if (gapat >= 0) + return "more than one :: in " IT; + gapat = i; + } else if (oops != NULL) + return oops; + buf[2*i] = piece >> 8; + buf[2*i + 1] = piece & 0xff; + if (i < NPIECES-1) { /* there should be more input */ + if (src == stop && gapat < 0) + return IT " ends prematurely"; + if (src != stop && *src++ != ':') + return "syntax error in " IT; + } + } + if (src != stop) + return "extra garbage on end of " IT; + + if (gapat < 0 && i < NPIECES) /* should have been caught earlier */ + return "incomplete " IT " (internal error)"; + if (gapat >= 0 && i == NPIECES) + return "non-abbreviating empty field in " IT; + if (gapat >= 0) { + naftergap = i - (gapat + 1); + for (i--, j = NPIECES-1; naftergap > 0; i--, j--, naftergap--) { + buf[2*j] = buf[2*i]; + buf[2*j + 1] = buf[2*i + 1]; + } + for (; j >= gapat; j--) + buf[2*j] = buf[2*j + 1] = 0; + } + + return initaddr(buf, sizeof(buf), AF_INET6, dst); +} + +/* + - getpiece - try to scan one 16-bit piece of an IPv6 address + */ +err_t /* ":" means "empty field seen" */ +getpiece(srcp, stop, retp) +const char **srcp; /* *srcp is updated */ +const char *stop; /* first untouchable char */ +unsigned *retp; /* return-value pointer */ +{ + const char *p; +# define NDIG 4 + int d; + unsigned long ret; + err_t oops; + + if (*srcp >= stop || **srcp == ':') { /* empty field */ + *retp = 0; + return ":"; + } + + p = *srcp; + d = 0; + while (p < stop && d < NDIG && isxdigit(*p)) { + p++; + d++; + } + if (d == 0) + return "non-hex field in IPv6 numeric address"; + if (p < stop && d == NDIG && isxdigit(*p)) + return "field in IPv6 numeric address longer than 4 hex digits"; + + oops = ttoul(*srcp, d, 16, &ret); + if (oops != NULL) /* shouldn't happen, really... */ + return oops; + + *srcp = p; + *retp = ret; + return NULL; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/ttodata.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttodata.c --- linux-2.4.29/net/ipsec/libopenswan/ttodata.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttodata.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,644 @@ +/* + * convert from text form of arbitrary data (e.g., keys) to binary + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: ttodata.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* converters and misc */ +static int unhex(const char *, char *, size_t); +static int unb64(const char *, char *, size_t); +static int untext(const char *, char *, size_t); +static const char *badch(const char *, int, char *, size_t); + +/* internal error codes for converters */ +#define SHORT (-2) /* internal buffer too short */ +#define BADPAD (-3) /* bad base64 padding */ +#define BADCH0 (-4) /* invalid character 0 */ +#define BADCH1 (-5) /* invalid character 1 */ +#define BADCH2 (-6) /* invalid character 2 */ +#define BADCH3 (-7) /* invalid character 3 */ +#define BADOFF(code) (BADCH0-(code)) + +/* + - ttodatav - convert text to data, with verbose error reports + * If some of this looks slightly odd, it's because it has changed + * repeatedly (from the original atodata()) without a major rewrite. + */ +const char * /* NULL on success, else literal or errp */ +ttodatav(src, srclen, base, dst, dstlen, lenp, errp, errlen) +const char *src; +size_t srclen; /* 0 means apply strlen() */ +int base; /* 0 means figure it out */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +size_t *lenp; /* where to record length (NULL is nowhere) */ +char *errp; /* error buffer */ +size_t errlen; +{ + size_t ingroup; /* number of input bytes converted at once */ + char buf[4]; /* output from conversion */ + int nbytes; /* size of output */ + int (*decode)(const char *, char *, size_t); + char *stop; + int ndone; + int i; + int underscoreok; + + if (srclen == 0) + srclen = strlen(src); + if (dstlen == 0) + dst = buf; /* point it somewhere valid */ + stop = dst + dstlen; + + if (base == 0) { + if (srclen < 2) + return "input too short to be valid"; + if (*src++ != '0') + return "input does not begin with format prefix"; + switch (*src++) { + case 'x': + case 'X': + base = 16; + break; + case 's': + case 'S': + base = 64; + break; + case 't': + case 'T': + base = 256; + break; + default: + return "unknown format prefix"; + break; + } + srclen -= 2; + } + switch (base) { + case 16: + ingroup = 2; + decode = unhex; + underscoreok = 1; + break; + case 64: + ingroup = 4; + decode = unb64; + underscoreok = 0; + break; + case 256: + ingroup = 1; + decode = untext; + underscoreok = 0; + break; + default: + return "unknown base"; + break; + } + + /* proceed */ + ndone = 0; + while (srclen >= ingroup) { + nbytes = (*decode)(src, buf, sizeof(buf)); + switch (nbytes) { + case BADCH0: + case BADCH1: + case BADCH2: + case BADCH3: + return badch(src, nbytes, errp, errlen); + break; + case SHORT: + return "internal buffer too short (\"can't happen\")"; + break; + case BADPAD: + return "bad (non-zero) padding at end of base64 input"; + break; + } + if (nbytes <= 0) + return "unknown internal error"; + for (i = 0; i < nbytes; i++) { + if (dst < stop) + *dst++ = buf[i]; + ndone++; + } + src += ingroup; + srclen -= ingroup; + if (underscoreok && srclen > 1 && *src == '_') { + /* srclen > 1 means not last character */ + src++; + srclen--; + } + } + if (srclen != 0) + return "input ends in mid-byte, perhaps truncated"; + if (ndone == 0) + return "no data bytes specified by input"; + if (lenp != NULL) + *lenp = ndone; + return NULL; +} + +/* + - ttodata - convert text to data + */ +const char * /* NULL on success, else literal */ +ttodata(src, srclen, base, dst, dstlen, lenp) +const char *src; +size_t srclen; /* 0 means apply strlen() */ +int base; /* 0 means figure it out */ +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +size_t *lenp; /* where to record length (NULL is nowhere) */ +{ + return ttodatav(src, srclen, base, dst, dstlen, lenp, (char *)NULL, + (size_t)0); +} + +/* + - atodata - convert ASCII to data + * backward-compatibility interface + */ +size_t /* 0 for failure, true length for success */ +atodata(src, srclen, dst, dstlen) +const char *src; +size_t srclen; +char *dst; +size_t dstlen; +{ + size_t len; + const char *err; + + err = ttodata(src, srclen, 0, dst, dstlen, &len); + if (err != NULL) + return 0; + return len; +} + +/* + - atobytes - convert ASCII to data bytes + * another backward-compatibility interface + */ +const char * +atobytes(src, srclen, dst, dstlen, lenp) +const char *src; +size_t srclen; +char *dst; +size_t dstlen; +size_t *lenp; +{ + return ttodata(src, srclen, 0, dst, dstlen, lenp); +} + +/* + - unhex - convert two ASCII hex digits to byte + */ +static int /* number of result bytes, or error code */ +unhex(src, dst, dstlen) +const char *src; /* known to be full length */ +char *dst; +size_t dstlen; /* not large enough is a failure */ +{ + char *p; + unsigned byte; + static char hex[] = "0123456789abcdef"; + + if (dstlen < 1) + return SHORT; + + p = strchr(hex, *src); + if (p == NULL) + p = strchr(hex, tolower(*src)); + if (p == NULL) + return BADCH0; + byte = (p - hex) << 4; + src++; + + p = strchr(hex, *src); + if (p == NULL) + p = strchr(hex, tolower(*src)); + if (p == NULL) + return BADCH1; + byte |= (p - hex); + + *dst = byte; + return 1; +} + +/* + - unb64 - convert four ASCII base64 digits to three bytes + * Note that a base64 digit group is padded out with '=' if it represents + * less than three bytes: one byte is dd==, two is ddd=, three is dddd. + */ +static int /* number of result bytes, or error code */ +unb64(src, dst, dstlen) +const char *src; /* known to be full length */ +char *dst; +size_t dstlen; +{ + char *p; + unsigned byte1; + unsigned byte2; + static char base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + if (dstlen < 3) + return SHORT; + + p = strchr(base64, *src++); + if (p == NULL) + return BADCH0; + byte1 = (p - base64) << 2; /* first six bits */ + + p = strchr(base64, *src++); + if (p == NULL) + return BADCH1; + byte2 = p - base64; /* next six: two plus four */ + *dst++ = byte1 | (byte2 >> 4); + byte1 = (byte2 & 0xf) << 4; + + p = strchr(base64, *src++); + if (p == NULL) { + if (*(src-1) == '=' && *src == '=') { + if (byte1 != 0) /* bad padding */ + return BADPAD; + return 1; + } + return BADCH2; + } + byte2 = p - base64; /* next six: four plus two */ + *dst++ = byte1 | (byte2 >> 2); + byte1 = (byte2 & 0x3) << 6; + + p = strchr(base64, *src++); + if (p == NULL) { + if (*(src-1) == '=') { + if (byte1 != 0) /* bad padding */ + return BADPAD; + return 2; + } + return BADCH3; + } + byte2 = p - base64; /* last six */ + *dst++ = byte1 | byte2; + return 3; +} + +/* + - untext - convert one ASCII character to byte + */ +static int /* number of result bytes, or error code */ +untext(src, dst, dstlen) +const char *src; /* known to be full length */ +char *dst; +size_t dstlen; /* not large enough is a failure */ +{ + if (dstlen < 1) + return SHORT; + + *dst = *src; + return 1; +} + +/* + - badch - produce a nice complaint about an unknown character + * + * If the compiler complains that the array bigenough[] has a negative + * size, that means the TTODATAV_BUF constant has been set too small. + */ +static const char * /* literal or errp */ +badch(src, errcode, errp, errlen) +const char *src; +int errcode; +char *errp; /* might be NULL */ +size_t errlen; +{ + static const char pre[] = "unknown character (`"; + static const char suf[] = "') in input"; + char buf[5]; +# define REQD (sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf)) + struct sizecheck { + char bigenough[TTODATAV_BUF - REQD]; /* see above */ + }; + char ch; + + if (errp == NULL || errlen < REQD) + return "unknown character in input"; + strcpy(errp, pre); + ch = *(src + BADOFF(errcode)); + if (isprint(ch)) { + buf[0] = ch; + buf[1] = '\0'; + } else { + buf[0] = '\\'; + buf[1] = ((ch & 0700) >> 6) + '0'; + buf[2] = ((ch & 0070) >> 3) + '0'; + buf[3] = ((ch & 0007) >> 0) + '0'; + buf[4] = '\0'; + } + strcat(errp, buf); + strcat(errp, suf); + return (const char *)errp; +} + + + +#ifdef TTODATA_MAIN + +#include + +void regress(); +void hexout(); + +/* + - main - convert first argument to hex, or run regression + */ +int +main(argc, argv) +int argc; +char *argv[]; +{ + char buf[1024]; + char buf2[1024]; + char err[512]; + size_t n; + size_t i; + char *p = buf; + char *p2 = buf2; + char *pgm = argv[0]; + const char *oops; + + if (argc < 2) { + fprintf(stderr, "Usage: %s {0x|0s|-r}\n", pgm); + exit(2); + } + + if (strcmp(argv[1], "-r") == 0) { + regress(pgm); /* should not return */ + fprintf(stderr, "%s: regress() returned?!?\n", pgm); + exit(1); + } + + oops = ttodatav(argv[1], 0, 0, buf, sizeof(buf), &n, err, sizeof(err)); + if (oops != NULL) { + fprintf(stderr, "%s: ttodata error `%s' in `%s'\n", pgm, + oops, argv[1]); + exit(1); + } + + if (n > sizeof(buf)) { + p = (char *)malloc((size_t)n); + if (p == NULL) { + fprintf(stderr, + "%s: unable to malloc %d bytes for result\n", + pgm, n); + exit(1); + } + oops = ttodata(argv[1], 0, 0, p, n, &n); + if (oops != NULL) { + fprintf(stderr, "%s: error `%s' in ttodata retry?!?\n", + pgm, oops); + exit(1); + } + } + + hexout(p, n, stdout); + printf("\n"); + + i = datatot(buf, n, 'h', buf2, sizeof(buf2)); + if (i == 0) { + fprintf(stderr, "%s: datatot reports error in `%s'\n", pgm, + argv[1]); + exit(1); + } + + if (i > sizeof(buf2)) { + p2 = (char *)malloc((size_t)i); + if (p == NULL) { + fprintf(stderr, + "%s: unable to malloc %d bytes for result\n", + pgm, i); + exit(1); + } + i = datatot(buf, n, 'h', p2, i); + if (i == 0) { + fprintf(stderr, "%s: error in datatoa retry?!?\n", pgm); + exit(1); + } + } + + printf("%s\n", p2); + + exit(0); +} + +/* + - hexout - output an arbitrary-length string in hex + */ +void +hexout(s, len, f) +const char *s; +size_t len; +FILE *f; +{ + size_t i; + + fprintf(f, "0x"); + for (i = 0; i < len; i++) + fprintf(f, "%02x", (unsigned char)s[i]); +} + +struct artab { + int base; + char *ascii; /* NULL for end */ + char *data; /* NULL for error expected */ +} atodatatab[] = { + 0, "", NULL, + 0, "0", NULL, + 0, "0x", NULL, + 0, "0xa", NULL, + 0, "0xab", "\xab", + 0, "0xabc", NULL, + 0, "0xabcd", "\xab\xcd", + 0, "0x0123456789", "\x01\x23\x45\x67\x89", + 0, "0x01x", NULL, + 0, "0xabcdef", "\xab\xcd\xef", + 0, "0xABCDEF", "\xab\xcd\xef", + 0, "0XaBc0eEd81f", "\xab\xc0\xee\xd8\x1f", + 0, "0XaBc0_eEd8", "\xab\xc0\xee\xd8", + 0, "0XaBc0_", NULL, + 0, "0X_aBc0", NULL, + 0, "0Xa_Bc0", NULL, + 16, "aBc0_eEd8", "\xab\xc0\xee\xd8", + 0, "0s", NULL, + 0, "0sA", NULL, + 0, "0sBA", NULL, + 0, "0sCBA", NULL, + 0, "0sDCBA", "\x0c\x20\x40", + 0, "0SDCBA", "\x0c\x20\x40", + 0, "0sDA==", "\x0c", + 0, "0sDC==", NULL, + 0, "0sDCA=", "\x0c\x20", + 0, "0sDCB=", NULL, + 0, "0sDCAZ", "\x0c\x20\x19", + 0, "0sDCAa", "\x0c\x20\x1a", + 0, "0sDCAz", "\x0c\x20\x33", + 0, "0sDCA0", "\x0c\x20\x34", + 0, "0sDCA9", "\x0c\x20\x3d", + 0, "0sDCA+", "\x0c\x20\x3e", + 0, "0sDCA/", "\x0c\x20\x3f", + 0, "0sAbraCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", + 64, "AbraCadabra+", "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", + 0, "0t", NULL, + 0, "0tabc_xyz", "abc_xyz", + 256, "abc_xyz", "abc_xyz", + 0, NULL, NULL, +}; + +struct drtab { + char *data; /* input; NULL for end */ + char format; + int buflen; /* -1 means big buffer */ + int outlen; /* -1 means strlen(ascii)+1 */ + char *ascii; /* NULL for error expected */ +} datatoatab[] = { + "", 'x', -1, -1, NULL, + "", 'X', -1, -1, NULL, + "", 'n', -1, -1, NULL, + "0", 'x', -1, -1, "0x30", + "0", 'x', 0, 5, "---", + "0", 'x', 1, 5, "", + "0", 'x', 2, 5, "0", + "0", 'x', 3, 5, "0x", + "0", 'x', 4, 5, "0x3", + "0", 'x', 5, 5, "0x30", + "0", 'x', 6, 5, "0x30", + "\xab\xcd", 'x', -1, -1, "0xabcd", + "\x01\x23\x45\x67\x89", 'x', -1, -1, "0x0123456789", + "\xab\xcd\xef", 'x', -1, -1, "0xabcdef", + "\xab\xc0\xee\xd8\x1f", 'x', -1, -1, "0xabc0eed81f", + "\x01\x02", 'h', -1, -1, "0x0102", + "\x01\x02\x03\x04\x05\x06", 'h', -1, -1, "0x01020304_0506", + "\xab\xc0\xee\xd8\x1f", 16, -1, -1, "abc0eed81f", + "\x0c\x20\x40", 's', -1, -1, "0sDCBA", + "\x0c\x20\x40", 's', 0, 7, "---", + "\x0c\x20\x40", 's', 1, 7, "", + "\x0c\x20\x40", 's', 2, 7, "0", + "\x0c\x20\x40", 's', 3, 7, "0s", + "\x0c\x20\x40", 's', 4, 7, "0sD", + "\x0c\x20\x40", 's', 5, 7, "0sDC", + "\x0c\x20\x40", 's', 6, 7, "0sDCB", + "\x0c\x20\x40", 's', 7, 7, "0sDCBA", + "\x0c\x20\x40", 's', 8, 7, "0sDCBA", + "\x0c", 's', -1, -1, "0sDA==", + "\x0c\x20", 's', -1, -1, "0sDCA=", + "\x0c\x20\x19", 's', -1, -1, "0sDCAZ", + "\x0c\x20\x1a", 's', -1, -1, "0sDCAa", + "\x0c\x20\x33", 's', -1, -1, "0sDCAz", + "\x0c\x20\x34", 's', -1, -1, "0sDCA0", + "\x0c\x20\x3d", 's', -1, -1, "0sDCA9", + "\x0c\x20\x3e", 's', -1, -1, "0sDCA+", + "\x0c\x20\x3f", 's', -1, -1, "0sDCA/", + "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 's', -1, -1, "0sAbraCadabra+", + "\x01\xba\xda\x09\xa7\x5a\x6e\xb6\xbe", 64, -1, -1, "AbraCadabra+", + NULL, 'x', -1, -1, NULL, +}; + +/* + - regress - regression-test ttodata() and datatot() + */ +void /* should not return at all, in fact */ +regress(pgm) +char *pgm; +{ + struct artab *r; + struct drtab *dr; + char buf[100]; + size_t n; + int status = 0; + size_t should; + const char *oops; + + for (r = atodatatab; r->ascii != NULL; r++) { + oops = ttodata(r->ascii, 0, r->base, buf, sizeof(buf), &n); + if (oops != NULL && r->data == NULL) + {} /* error expected */ + else if (oops != NULL) { + printf("`%s' gave error `%s', expecting %d `", r->ascii, + oops, strlen(r->data)); + hexout(r->data, strlen(r->data), stdout); + printf("'\n"); + status = 1; + } else if (r->data == NULL) { + printf("`%s' gave %d `", r->ascii, n); + hexout(buf, n, stdout); + printf("', expecting error\n"); + status = 1; + } else if (n != strlen(r->data)) { + printf("length wrong in `%s': got %d `", r->ascii, n); + hexout(buf, n, stdout); + printf("', expecting %d `", strlen(r->data)); + hexout(r->data, strlen(r->data), stdout); + printf("'\n"); + status = 1; + } else if (memcmp(buf, r->data, n) != 0) { + printf("`%s' gave %d `", r->ascii, n); + hexout(buf, n, stdout); + printf("', expecting %d `", strlen(r->data)); + hexout(r->data, strlen(r->data), stdout); + printf("'\n"); + status = 1; + } + fflush(stdout); + } + for (dr = datatoatab; dr->data != NULL; dr++) { + strcpy(buf, "---"); + n = datatot(dr->data, strlen(dr->data), dr->format, buf, + (dr->buflen == -1) ? sizeof(buf) : dr->buflen); + should = (dr->ascii == NULL) ? 0 : strlen(dr->ascii) + 1; + if (dr->outlen != -1) + should = dr->outlen; + if (n == 0 && dr->ascii == NULL) + {} /* error expected */ + else if (n == 0) { + printf("`"); + hexout(dr->data, strlen(dr->data), stdout); + printf("' %c gave error, expecting %d `%s'\n", + dr->format, should, dr->ascii); + status = 1; + } else if (dr->ascii == NULL) { + printf("`"); + hexout(dr->data, strlen(dr->data), stdout); + printf("' %c gave %d `%.*s', expecting error\n", + dr->format, n, n, buf); + status = 1; + } else if (n != should) { + printf("length wrong in `"); + hexout(dr->data, strlen(dr->data), stdout); + printf("': got %d `%s'", n, buf); + printf(", expecting %d `%s'\n", should, dr->ascii); + status = 1; + } else if (strcmp(buf, dr->ascii) != 0) { + printf("`"); + hexout(dr->data, strlen(dr->data), stdout); + printf("' gave %d `%s'", n, buf); + printf(", expecting %d `%s'\n", should, dr->ascii); + status = 1; + } + fflush(stdout); + } + exit(status); +} + +#endif /* TTODATA_MAIN */ diff -urN linux-2.4.29/net/ipsec/libopenswan/ttoprotoport.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttoprotoport.c --- linux-2.4.29/net/ipsec/libopenswan/ttoprotoport.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttoprotoport.c Mon Mar 1 13:47:48 2004 @@ -0,0 +1,104 @@ +/* + * conversion from protocol/port string to protocol and port + * Copyright (C) 2002 Mario Strasser , + * Zuercher Hochschule Winterthur, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: ttoprotoport.c,v 1.3 2004/03/01 12:47:48 paul Exp $ + */ + +#include "internal.h" +#include "openswan.h" + +/* + * ttoprotoport - converts from protocol/port string to protocol and port + */ +err_t +ttoprotoport(src, src_len, proto, port, has_port_wildcard) +char *src; /* input string */ +size_t src_len; /* length of input string, use strlen() if 0 */ +u_int8_t *proto; /* extracted protocol number */ +u_int16_t *port; /* extracted port number if it exists */ +int *has_port_wildcard; /* set if port is %any */ +{ + char *end, *service_name; + char proto_name[16]; + int proto_len; + long int l; + struct protoent *protocol; + struct servent *service; + + /* get the length of the string */ + if (!src_len) src_len = strlen(src); + + /* locate delimiter '/' between protocol and port */ + end = strchr(src, '/'); + if (end != NULL) { + proto_len = end - src; + service_name = end + 1; + } else { + proto_len = src_len; + service_name = src + src_len; + } + + /* copy protocol name*/ + memset(proto_name, '\0', sizeof(proto_name)); + memcpy(proto_name, src, proto_len); + + /* extract protocol by trying to resolve it by name */ + protocol = getprotobyname(proto_name); + if (protocol != NULL) { + *proto = protocol->p_proto; + } + else /* failed, now try it by number */ + { + l = strtol(proto_name, &end, 0); + + if (*proto_name && *end) + return " is neither a number nor a valid name"; + + if (l < 0 || l > 0xff) + return " must be between 0 and 255"; + + *proto = (u_int8_t)l; + } + + /* is there a port wildcard? */ + *has_port_wildcard = (strcmp(service_name, "%any") == 0); + + if (*has_port_wildcard) + { + *port = 0; + return NULL; + } + + + /* extract port by trying to resolve it by name */ + service = getservbyname(service_name, NULL); + if (service != NULL) { + *port = ntohs(service->s_port); + } + else /* failed, now try it by number */ + { + l = strtol(service_name, &end, 0); + + if (*service_name && *end) + return " is neither a number nor a valid name"; + + if (l < 0 || l > 0xffff) + return " must be between 0 and 65535"; + + *port = (u_int16_t)l; + } + return NULL; +} + diff -urN linux-2.4.29/net/ipsec/libopenswan/ttosa.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttosa.c --- linux-2.4.29/net/ipsec/libopenswan/ttosa.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttosa.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,282 @@ +/* + * convert from text form of SA ID to binary + * Copyright (C) 2000, 2001 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: ttosa.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +static struct satype { + char *prefix; + size_t prelen; /* strlen(prefix) */ + int proto; +} satypes[] = { + { "ah", 2, SA_AH }, + { "esp", 3, SA_ESP }, + { "tun", 3, SA_IPIP }, + { "comp", 4, SA_COMP }, + { "int", 3, SA_INT }, + { NULL, 0, 0, } +}; + +static struct magic { + char *name; + char *really; +} magic[] = { + { PASSTHROUGHNAME, PASSTHROUGH4IS }, + { PASSTHROUGH4NAME, PASSTHROUGH4IS }, + { PASSTHROUGH6NAME, PASSTHROUGH6IS }, + { "%pass", "int256@0.0.0.0" }, + { "%drop", "int257@0.0.0.0" }, + { "%reject", "int258@0.0.0.0" }, + { "%hold", "int259@0.0.0.0" }, + { "%trap", "int260@0.0.0.0" }, + { "%trapsubnet", "int261@0.0.0.0" }, + { NULL, NULL } +}; + +/* + - ttosa - convert text "ah507@10.0.0.1" to SA identifier + */ +err_t /* NULL for success, else string literal */ +ttosa(src, srclen, sa) +const char *src; +size_t srclen; /* 0 means "apply strlen" */ +ip_said *sa; +{ + const char *at; + const char *addr; + size_t alen; + const char *spi = NULL; + struct satype *sat; + unsigned long ul; + const char *oops; + struct magic *mp; + size_t nlen; +# define MINLEN 5 /* ah0@0 is as short as it can get */ + int af; + int base; + + if (srclen == 0) + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + if (srclen < MINLEN) + return "string too short to be SA identifier"; + if (*src == '%') { + for (mp = magic; mp->name != NULL; mp++) { + nlen = strlen(mp->name); + if (srclen == nlen && memcmp(src, mp->name, nlen) == 0) + break; + } + if (mp->name == NULL) + return "unknown % keyword"; + src = mp->really; + srclen = strlen(src); + } + + at = memchr(src, '@', srclen); + if (at == NULL) + return "no @ in SA specifier"; + + for (sat = satypes; sat->prefix != NULL; sat++) + if (sat->prelen < srclen && + strncmp(src, sat->prefix, sat->prelen) == 0) { + sa->proto = sat->proto; + spi = src + sat->prelen; + break; /* NOTE BREAK OUT */ + } + if (sat->prefix == NULL) + return "SA specifier lacks valid protocol prefix"; + + if (spi >= at) + return "no SPI in SA specifier"; + switch (*spi) { + case '.': + af = AF_INET; + spi++; + base = 16; + break; + case ':': + af = AF_INET6; + spi++; + base = 16; + break; + default: + af = AF_UNSPEC; /* not known yet */ + base = 0; + break; + } + if (spi >= at) + return "no SPI found in SA specifier"; + oops = ttoul(spi, at - spi, base, &ul); + if (oops != NULL) + return oops; + sa->spi = htonl(ul); + + addr = at + 1; + alen = srclen - (addr - src); + if (af == AF_UNSPEC) + af = (memchr(addr, ':', alen) != NULL) ? AF_INET6 : AF_INET; + oops = ttoaddr(addr, alen, af, &sa->dst); + if (oops != NULL) + return oops; + + return NULL; +} + + + +#ifdef TTOSA_MAIN + +#include + +void regress(); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + ip_said sa; + char buf[100]; + char buf2[100]; + const char *oops; + size_t n; + + if (argc < 2) { + fprintf(stderr, "Usage: %s {ahnnn@aaa|-r}\n", argv[0]); + exit(2); + } + + if (strcmp(argv[1], "-r") == 0) { + regress(); + fprintf(stderr, "regress() returned?!?\n"); + exit(1); + } + + oops = ttosa(argv[1], 0, &sa); + if (oops != NULL) { + fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); + exit(1); + } + n = satot(&sa, 0, buf, sizeof(buf)); + if (n > sizeof(buf)) { + fprintf(stderr, "%s: reverse conv of `%d'", argv[0], sa.proto); + fprintf(stderr, "%lx@", sa.spi); + (void) addrtot(&sa.dst, 0, buf2, sizeof(buf2)); + fprintf(stderr, "%s", buf2); + fprintf(stderr, " failed: need %ld bytes, have only %ld\n", + (long)n, (long)sizeof(buf)); + exit(1); + } + printf("%s\n", buf); + + exit(0); +} + +struct rtab { + int format; +# define FUDGE 0x1000 + char *input; + char *output; /* NULL means error expected */ +} rtab[] = { + 0, "esp257@1.2.3.0", "esp.101@1.2.3.0", + 0, "ah0x20@1.2.3.4", "ah.20@1.2.3.4", + 0, "tun20@1.2.3.4", "tun.14@1.2.3.4", + 0, "comp20@1.2.3.4", "comp.14@1.2.3.4", + 0, "esp257@::1", "esp:101@::1", + 0, "esp257@0bc:12de::1", "esp:101@bc:12de::1", + 0, "esp78@1049:1::8007:2040", "esp:4e@1049:1::8007:2040", + 0, "esp0x78@1049:1::8007:2040", "esp:78@1049:1::8007:2040", + 0, "ah78@1049:1::8007:2040", "ah:4e@1049:1::8007:2040", + 0, "ah0x78@1049:1::8007:2040", "ah:78@1049:1::8007:2040", + 0, "tun78@1049:1::8007:2040", "tun:4e@1049:1::8007:2040", + 0, "tun0x78@1049:1::8007:2040", "tun:78@1049:1::8007:2040", + 0, "duk99@3ffe:370:400:ff::9001:3001", NULL, + 0, "esp78x@1049:1::8007:2040", NULL, + 0, "esp0x78@1049:1:0xfff::8007:2040", NULL, + 0, "es78@1049:1::8007:2040", NULL, + 0, "", NULL, + 0, "_", NULL, + 0, "ah2.2", NULL, + 0, "goo2@1.2.3.4", NULL, + 0, "esp9@1.2.3.4", "esp.9@1.2.3.4", + 'f', "esp0xa9@1.2.3.4", "esp.000000a9@1.2.3.4", + 0, "espp9@1.2.3.4", NULL, + 0, "es9@1.2.3.4", NULL, + 0, "ah@1.2.3.4", NULL, + 0, "esp7x7@1.2.3.4", NULL, + 0, "esp77@1.0x2.3.4", NULL, + 0, PASSTHROUGHNAME, PASSTHROUGH4NAME, + 0, PASSTHROUGH6NAME, PASSTHROUGH6NAME, + 0, "%pass", "%pass", + 0, "int256@0.0.0.0", "%pass", + 0, "%drop", "%drop", + 0, "int257@0.0.0.0", "%drop", + 0, "%reject", "%reject", + 0, "int258@0.0.0.0", "%reject", + 0, "%hold", "%hold", + 0, "int259@0.0.0.0", "%hold", + 0, "%trap", "%trap", + 0, "int260@0.0.0.0", "%trap", + 0, "%trapsubnet", "%trapsubnet", + 0, "int261@0.0.0.0", "%trapsubnet", + 0, "int262@0.0.0.0", "int.106@0.0.0.0", + FUDGE, "esp9@1.2.3.4", "unk77.9@1.2.3.4", + 0, NULL, NULL +}; + +void +regress() +{ + struct rtab *r; + int status = 0; + ip_said sa; + char in[100]; + char buf[100]; + const char *oops; + size_t n; + + for (r = rtab; r->input != NULL; r++) { + strcpy(in, r->input); + oops = ttosa(in, 0, &sa); + if (oops != NULL && r->output == NULL) + {} /* okay, error expected */ + else if (oops != NULL) { + printf("`%s' ttosa failed: %s\n", r->input, oops); + status = 1; + } else if (r->output == NULL) { + printf("`%s' ttosa succeeded unexpectedly\n", + r->input); + status = 1; + } else { + if (r->format&FUDGE) + sa.proto = 77; + n = satot(&sa, (char)r->format, buf, sizeof(buf)); + if (n > sizeof(buf)) { + printf("`%s' satot failed: need %ld\n", + r->input, (long)n); + status = 1; + } else if (strcmp(r->output, buf) != 0) { + printf("`%s' gave `%s', expected `%s'\n", + r->input, buf, r->output); + status = 1; + } + } + } + exit(status); +} + +#endif /* TTOSA_MAIN */ diff -urN linux-2.4.29/net/ipsec/libopenswan/ttosubnet.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttosubnet.c --- linux-2.4.29/net/ipsec/libopenswan/ttosubnet.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttosubnet.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,294 @@ +/* + * convert from text form of subnet specification to binary + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: ttosubnet.c,v 1.3 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +#ifndef DEFAULTSUBNET +#define DEFAULTSUBNET "%default" +#endif + +/* + - ttosubnet - convert text "addr/mask" to address and mask + * Mask can be integer bit count. + */ +err_t +ttosubnet(src, srclen, af, dst) +const char *src; +size_t srclen; /* 0 means "apply strlen" */ +int af; /* AF_INET or AF_INET6 */ +ip_subnet *dst; +{ + const char *slash; + const char *colon; + const char *mask; + size_t mlen; + const char *oops; + unsigned long bc; + static char def[] = DEFAULTSUBNET; +# define DEFLEN (sizeof(def) - 1) /* -1 for NUL */ + static char defis4[] = "0/0"; +# define DEFIS4LEN (sizeof(defis4) - 1) + static char defis6[] = "::/0"; +# define DEFIS6LEN (sizeof(defis6) - 1) + ip_address addrtmp; + ip_address masktmp; + int nbits; + int i; + + if (srclen == 0) + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + + switch (af) { + case AF_INET: + nbits = 32; + break; + case AF_INET6: + nbits = 128; + break; + default: + return "unknown address family in ttosubnet"; + break; + } + + if (srclen == DEFLEN && strncmp(src, def, srclen) == 0) { + src = (af == AF_INET) ? defis4 : defis6; + srclen = (af == AF_INET) ? DEFIS4LEN : DEFIS6LEN; + } + + slash = memchr(src, '/', srclen); + if (slash == NULL) + return "no / in subnet specification"; + mask = slash + 1; + mlen = srclen - (mask - src); + + oops = ttoaddr(src, slash-src, af, &addrtmp); + if (oops != NULL) + return oops; + + /* extract port */ + colon = memchr(mask, ':', mlen); + if (colon == 0) + { + setportof(0, &addrtmp); + } + else + { + long port; + + oops = ttoul(colon+1, mlen-(colon-mask+1), 10, &port); + if (oops != NULL) + return oops; + setportof(htons(port), &addrtmp); + mlen = colon - mask; + } + + /*extract mask */ + oops = ttoul(mask, mlen, 10, &bc); + if (oops == NULL) { + /* ttoul succeeded, it's a bit-count mask */ + if (bc > nbits) + return "subnet mask bit count too large"; + i = bc; + } else { + oops = ttoaddr(mask, mlen, af, &masktmp); + if (oops != NULL) + return oops; + i = masktocount(&masktmp); + if (i < 0) + return "non-contiguous or otherwise erroneous mask"; + } + + return initsubnet(&addrtmp, i, '0', dst); +} + + + +#ifdef TTOSUBNET_MAIN + +#include + +void regress(); + +int +main(argc, argv) +int argc; +char *argv[]; +{ + ip_address a; + ip_subnet s; + char buf[100]; + char buf2[100]; + const char *oops; + size_t n; + int af; + char *p; + + if (argc < 2) { + fprintf(stderr, "Usage: %s [-6] addr/mask\n", argv[0]); + fprintf(stderr, " or: %s -r\n", argv[0]); + exit(2); + } + + if (strcmp(argv[1], "-r") == 0) { + regress(); + fprintf(stderr, "regress() returned?!?\n"); + exit(1); + } + + af = AF_INET; + p = argv[1]; + if (strcmp(argv[1], "-6") == 0) { + af = AF_INET6; + p = argv[2]; + } else if (strchr(argv[1], ':') != NULL) + af = AF_INET6; + + oops = ttosubnet(p, 0, af, &s); + if (oops != NULL) { + fprintf(stderr, "%s: conversion failed: %s\n", argv[0], oops); + exit(1); + } + n = subnettot(&s, 0, buf, sizeof(buf)); + if (n > sizeof(buf)) { + fprintf(stderr, "%s: reverse conversion of ", argv[0]); + (void) addrtot(&s.addr, 0, buf2, sizeof(buf2)); + fprintf(stderr, "%s/", buf2); + fprintf(stderr, "%d", s.maskbits); + fprintf(stderr, " failed: need %ld bytes, have only %ld\n", + (long)n, (long)sizeof(buf)); + exit(1); + } + printf("%s\n", buf); + + exit(0); +} + +struct rtab { + int family; + char *input; + char *output; /* NULL means error expected */ +} rtab[] = { + 4, "1.2.3.0/255.255.255.0", "1.2.3.0/24", + 4, "1.2.3.0/24", "1.2.3.0/24", + 4, "1.2.3.1/255.255.255.240", "1.2.3.0/28", + 4, "1.2.3.1/32", "1.2.3.1/32", + 4, "1.2.3.1/0", "0.0.0.0/0", +/* 4, "1.2.3.1/255.255.127.0", "1.2.3.0/255.255.127.0", */ + 4, "1.2.3.1/255.255.127.0", NULL, + 4, "128.009.000.032/32", "128.9.0.32/32", + 4, "128.0x9.0.32/32", NULL, + 4, "0x80090020/32", "128.9.0.32/32", + 4, "0x800x0020/32", NULL, + 4, "128.9.0.32/0xffFF0000", "128.9.0.0/16", + 4, "128.9.0.32/0xff0000FF", NULL, + 4, "128.9.0.32/0x0000ffFF", NULL, + 4, "128.9.0.32/0x00ffFF0000", NULL, + 4, "128.9.0.32/0xffFF", NULL, + 4, "128.9.0.32.27/32", NULL, + 4, "128.9.0k32/32", NULL, + 4, "328.9.0.32/32", NULL, + 4, "128.9..32/32", NULL, + 4, "10/8", "10.0.0.0/8", + 4, "10.0/8", "10.0.0.0/8", + 4, "10.0.0/8", "10.0.0.0/8", + 4, "10.0.1/24", "10.0.1.0/24", + 4, "_", NULL, + 4, "_/_", NULL, + 4, "1.2.3.1", NULL, + 4, "1.2.3.1/_", NULL, + 4, "1.2.3.1/24._", NULL, + 4, "1.2.3.1/99", NULL, + 4, "localhost./32", "127.0.0.1/32", + 4, "%default", "0.0.0.0/0", + 6, "3049:1::8007:2040/0", "::/0", + 6, "3049:1::8007:2040/128", "3049:1::8007:2040/128", + 6, "3049:1::192.168.0.1/128", NULL, /*"3049:1::c0a8:1/128",*/ + 6, "3049:1::8007::2040/128", NULL, + 6, "3049:1::8007:2040/ffff::0", "3049::/16", + 6, "3049:1::8007:2040/64", "3049:1::/64", + 6, "3049:1::8007:2040/ffff::", "3049::/16", + 6, "3049:1::8007:2040/0000:ffff::0", NULL, + 6, "3049:1::8007:2040/ff1f::0", NULL, + 6, "3049:1::8007:x:2040/128", NULL, + 6, "3049:1t::8007:2040/128", NULL, + 6, "3049:1::80071:2040/128", NULL, + 6, "::/21", "::/21", + 6, "::1/128", "::1/128", + 6, "1::/21", "1::/21", + 6, "1::2/128", "1::2/128", + 6, "1:0:0:0:0:0:0:2/128", "1::2/128", + 6, "1:0:0:0:3:0:0:2/128", "1::3:0:0:2/128", + 6, "1:0:0:3:0:0:0:2/128", "1::3:0:0:0:2/128", + 6, "1:0:3:0:0:0:0:2/128", "1:0:3::2/128", + 6, "abcd:ef01:2345:6789:0:00a:000:20/128", "abcd:ef01:2345:6789:0:a:0:20/128", + 6, "3049:1::8007:2040/ffff:ffff:", NULL, + 6, "3049:1::8007:2040/ffff:88::", NULL, + 6, "3049:12::9000:3200/ffff:fff0::", "3049:10::/28", + 6, "3049:12::9000:3200/28", "3049:10::/28", + 6, "3049:12::9000:3200/ff00:::", NULL, + 6, "3049:12::9000:3200/ffff:::", NULL, + 6, "3049:12::9000:3200/128_", NULL, + 6, "3049:12::9000:3200/", NULL, + 6, "%default", "::/0", + 4, NULL, NULL +}; + +void +regress() +{ + struct rtab *r; + int status = 0; + ip_address a; + ip_subnet s; + char in[100]; + char buf[100]; + const char *oops; + size_t n; + int af; + + for (r = rtab; r->input != NULL; r++) { + af = (r->family == 4) ? AF_INET : AF_INET6; + strcpy(in, r->input); + oops = ttosubnet(in, 0, af, &s); + if (oops != NULL && r->output == NULL) + {} /* okay, error expected */ + else if (oops != NULL) { + printf("`%s' ttosubnet failed: %s\n", r->input, oops); + status = 1; + } else if (r->output == NULL) { + printf("`%s' ttosubnet succeeded unexpectedly\n", + r->input); + status = 1; + } else { + n = subnettot(&s, 0, buf, sizeof(buf)); + if (n > sizeof(buf)) { + printf("`%s' subnettot failed: need %ld\n", + r->input, (long)n); + status = 1; + } else if (strcmp(r->output, buf) != 0) { + printf("`%s' gave `%s', expected `%s'\n", + r->input, buf, r->output); + status = 1; + } + } + } + exit(status); +} + +#endif /* TTOSUBNET_MAIN */ diff -urN linux-2.4.29/net/ipsec/libopenswan/ttoul.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttoul.c --- linux-2.4.29/net/ipsec/libopenswan/ttoul.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ttoul.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,91 @@ +/* + * convert from text form of unsigned long to binary + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: ttoul.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - ttoul - convert text substring to unsigned long number + */ +const char * /* NULL for success, else string literal */ +ttoul(src, srclen, base, resultp) +const char *src; +size_t srclen; /* 0 means strlen(src) */ +int base; /* 0 means figure it out */ +unsigned long *resultp; +{ + const char *stop; + static char hex[] = "0123456789abcdef"; + static char uchex[] = "0123456789ABCDEF"; + int d; + char c; + char *p; + unsigned long r; + unsigned long rlimit; + int dlimit; + + if (srclen == 0) + srclen = strlen(src); + if (srclen == 0) + return "empty string"; + + if (base == 0) { + if (srclen > 2 && *src == '0' && + (*(src+1) == 'x' || *(src+1) == 'X')) + return ttoul(src+2, srclen-2, 16, resultp); + if (srclen > 1 && *src == '0') + return ttoul(src+1, srclen-1, 8, resultp); + return ttoul(src, srclen, 10, resultp); + } + if (base != 8 && base != 10 && base != 16) + return "unsupported number base"; + + r = 0; + stop = src + srclen; + if (base == 16) { + while (src < stop) { + c = *src++; + p = strchr(hex, c); + if (p != NULL) + d = p - hex; + else { + p = strchr(uchex, c); + if (p == NULL) + return "non-hex digit in hex number"; + d = p - uchex; + } + r = (r << 4) | d; + } + /* defer length check to catch invalid digits first */ + if (srclen > sizeof(unsigned long) * 2) + return "hex number too long"; + } else { + rlimit = ULONG_MAX / base; + dlimit = (int)(ULONG_MAX - rlimit*base); + while (src < stop) { + c = *src++; + d = c - '0'; + if (d < 0 || d >= base) + return "non-digit in number"; + if (r > rlimit || (r == rlimit && d > dlimit)) + return "unsigned-long overflow"; + r = r*base + d; + } + } + + *resultp = r; + return NULL; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/ultoa.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ultoa.c --- linux-2.4.29/net/ipsec/libopenswan/ultoa.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ultoa.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,67 @@ +/* + * convert unsigned long to ASCII + * Copyright (C) 1998, 1999 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: ultoa.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - ultoa - convert unsigned long to decimal ASCII + */ +size_t /* length required for full conversion */ +ultoa(n, base, dst, dstlen) +unsigned long n; +int base; +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + char buf[3*sizeof(unsigned long) + 1]; + char *bufend = buf + sizeof(buf); + size_t len; + char *p; + static char hex[] = "0123456789abcdef"; + + p = bufend; + *--p = '\0'; + if (base == 10) { + do { + *--p = n%10 + '0'; + n /= 10; + } while (n != 0); + } else if (base == 16) { + do { + *--p = hex[n&0xf]; + n >>= 4; + } while (n != 0); + *--p = 'x'; + *--p = '0'; + } else if (base == 8) { + do { + *--p = (n&07) + '0'; + n >>= 3; + } while (n != 0); + *--p = '0'; + } else + *--p = '?'; + + len = bufend - p; + + if (dstlen > 0) { + if (len > dstlen) + *(p + dstlen - 1) = '\0'; + strcpy(dst, p); + } + return len; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/ultot.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ultot.c --- linux-2.4.29/net/ipsec/libopenswan/ultot.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/ultot.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,83 @@ +/* + * convert unsigned long to text + * Copyright (C) 2000 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: ultot.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +/* + - ultot - convert unsigned long to text + */ +size_t /* length required for full conversion */ +ultot(n, base, dst, dstlen) +unsigned long n; +int base; +char *dst; /* need not be valid if dstlen is 0 */ +size_t dstlen; +{ + char buf[3*sizeof(unsigned long) + 1]; + char *bufend = buf + sizeof(buf); + size_t len; + char *p; + static char hex[] = "0123456789abcdef"; +# define HEX32 (32/4) + + p = bufend; + *--p = '\0'; + switch (base) { + case 10: + case 'd': + do { + *--p = n%10 + '0'; + n /= 10; + } while (n != 0); + break; + case 16: + case 17: + case 'x': + do { + *--p = hex[n&0xf]; + n >>= 4; + } while (n != 0); + if (base == 17) + while (bufend - p < HEX32 + 1) + *--p = '0'; + if (base == 'x') { + *--p = 'x'; + *--p = '0'; + } + break; + case 8: + case 'o': + do { + *--p = (n&07) + '0'; + n >>= 3; + } while (n != 0); + if (base == 'o') + *--p = '0'; + break; + default: + return 0; + break; + } + + len = bufend - p; + if (dstlen > 0) { + if (len > dstlen) + *(p + dstlen - 1) = '\0'; + strcpy(dst, p); + } + return len; +} diff -urN linux-2.4.29/net/ipsec/libopenswan/version.in.c linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/version.in.c --- linux-2.4.29/net/ipsec/libopenswan/version.in.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/libopenswan/version.in.c Mon Nov 17 00:22:48 2003 @@ -0,0 +1,40 @@ +/* + * return IPsec version information + * Copyright (C) 2001 Henry Spencer. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Library General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + * License for more details. + * + * RCSID $Id: version.in.c,v 1.2 2003/11/16 23:22:48 ken Exp $ + */ +#include "internal.h" +#include "openswan.h" + +#define V "xxx" /* substituted in by Makefile */ +static const char freeswan_number[] = V; +static const char freeswan_string[] = "Linux FreeS/WAN " V; + +/* + - ipsec_version_code - return IPsec version number/code, as string + */ +const char * +ipsec_version_code() +{ + return freeswan_number; +} + +/* + - ipsec_version_string - return full version string + */ +const char * +ipsec_version_string() +{ + return freeswan_string; +} diff -urN linux-2.4.29/net/ipsec/pfkey_v2.c linux-2.4.29-openswan-1.0.9/net/ipsec/pfkey_v2.c --- linux-2.4.29/net/ipsec/pfkey_v2.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/pfkey_v2.c Thu Jun 17 10:47:11 2004 @@ -0,0 +1,2105 @@ +/* + * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: pfkey_v2.c,v 1.7 2004/06/17 08:47:11 ken Exp $ + */ + +/* + * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c. + * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c. + */ + +#define __NO_VERSION__ +#include +#include +#include +#include + +#include "ipsec_param.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* struct socket */ +#include +#include +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include +#include +#include +#include /* struct sock */ +/* #include */ +#include +#ifdef CONFIG_PROC_FS +# include +#endif /* CONFIG_PROC_FS */ + +#include + +#include +#ifdef NET_21 +# include +# include +#endif /* NET_21 */ + +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_sa.h" +#include "ipsec_netlink.h" + +#include +#include + +#include "ipsec_proto.h" + +#ifdef CONFIG_IPSEC_DEBUG +int debug_pfkey = 0; +extern int sysctl_ipsec_debug_verbose; +#endif /* CONFIG_IPSEC_DEBUG */ + +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) + +#ifndef SOCKOPS_WRAPPED +#define SOCKOPS_WRAPPED(name) name +#endif /* SOCKOPS_WRAPPED */ + +struct proto_ops SOCKOPS_WRAPPED(pfkey_ops); +struct sock *pfkey_sock_list = NULL; +struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1]; + +struct socket_list *pfkey_open_sockets = NULL; +struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1]; + +int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **); + +int +pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets) +{ + struct socket_list *socket_listp,*prev; + + if(!socketp) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_remove_socket: " + "NULL socketp handed in, failed.\n"); + return -EINVAL; + } + + if(!sockets) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_remove_socket: " + "NULL sockets list handed in, failed.\n"); + return -EINVAL; + } + + socket_listp = *sockets; + prev = NULL; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_remove_socket: " + "removing sock=%p\n", + socketp); + + while(socket_listp != NULL) { + if(socket_listp->socketp == socketp) { + if(prev != NULL) { + prev->next = socket_listp->next; + } else { + *sockets = socket_listp->next; + } + + kfree((void*)socket_listp); + + break; + } + prev = socket_listp; + socket_listp = socket_listp->next; + } + + return 0; +} + +int +pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets) +{ + struct socket_list *socket_listp; + + if(!socketp) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_insert_socket: " + "NULL socketp handed in, failed.\n"); + return -EINVAL; + } + + if(!sockets) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_insert_socket: " + "NULL sockets list handed in, failed.\n"); + return -EINVAL; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_insert_socket: " + "socketp=%p\n",socketp); + + if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_insert_socket: " + "memory allocation error.\n"); + return -ENOMEM; + } + + socket_listp->socketp = socketp; + socket_listp->next = *sockets; + *sockets = socket_listp; + + return 0; +} + +int +pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list) +{ + struct supported_list *supported_listp = *supported_list, *prev = NULL; + + if(!supported) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_remove_supported: " + "NULL supported handed in, failed.\n"); + return -EINVAL; + } + + if(!supported_list) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_remove_supported: " + "NULL supported_list handed in, failed.\n"); + return -EINVAL; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_remove_supported: " + "removing supported=%p\n", + supported); + + while(supported_listp != NULL) { + if(supported_listp->supportedp == supported) { + if(prev != NULL) { + prev->next = supported_listp->next; + } else { + *supported_list = supported_listp->next; + } + + kfree((void*)supported_listp); + + break; + } + prev = supported_listp; + supported_listp = supported_listp->next; + } + + return 0; +} + +int +pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list) +{ + struct supported_list *supported_listp; + + if(!supported) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_insert_supported: " + "NULL supported handed in, failed.\n"); + return -EINVAL; + } + + if(!supported_list) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_insert_supported: " + "NULL supported_list handed in, failed.\n"); + return -EINVAL; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_insert_supported: " + "incoming, supported=%p, supported_list=%p\n", + supported, + supported_list); + + supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL); + if(supported_listp == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_insert_supported: " + "memory allocation error.\n"); + return -ENOMEM; + } + + supported_listp->supportedp = supported; + supported_listp->next = *supported_list; + *supported_list = supported_listp; + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_list_insert_supported: " + "outgoing, supported=%p, supported_list=%p\n", + supported, + supported_list); + + return 0; +} + +#ifndef NET_21 +DEBUG_NO_STATIC void +pfkey_state_change(struct sock *sk) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_state_change: .\n"); + if(!sk->dead) { + wake_up_interruptible(sk->sleep); + } +} +#endif /* !NET_21 */ + +#ifndef NET_21 +DEBUG_NO_STATIC void +pfkey_data_ready(struct sock *sk, int len) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_data_ready: " + "sk=%p len=%d\n", + sk, + len); + if(!sk->dead) { + wake_up_interruptible(sk->sleep); + sock_wake_async(sk->socket, 1); + } +} + +DEBUG_NO_STATIC void +pfkey_write_space(struct sock *sk) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_write_space: .\n"); + if(!sk->dead) { + wake_up_interruptible(sk->sleep); + sock_wake_async(sk->socket, 2); + } +} +#endif /* !NET_21 */ + +DEBUG_NO_STATIC void +pfkey_insert_socket(struct sock *sk) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_insert_socket: " + "sk=%p\n", + sk); + cli(); + sk->next=pfkey_sock_list; + pfkey_sock_list=sk; + sti(); +} + +DEBUG_NO_STATIC void +pfkey_remove_socket(struct sock *sk) +{ + struct sock **s; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_remove_socket: .\n"); + cli(); + s=&pfkey_sock_list; + + while(*s!=NULL) { + if(*s==sk) { + *s=sk->next; + sk->next=NULL; + sti(); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_remove_socket: " + "succeeded.\n"); + return; + } + s=&((*s)->next); + } + sti(); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_remove_socket: " + "not found.\n"); + return; +} + +DEBUG_NO_STATIC void +pfkey_destroy_socket(struct sock *sk) +{ + struct sk_buff *skb; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_destroy_socket: .\n"); + pfkey_remove_socket(sk); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_destroy_socket: " + "pfkey_remove_socket called.\n"); + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_destroy_socket: " + "sk(%p)->(&%p)receive_queue.{next=%p,prev=%p}.\n", + sk, + &(sk->receive_queue), + sk->receive_queue.next, + sk->receive_queue.prev); + while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) { +#ifdef NET_21 +#ifdef CONFIG_IPSEC_DEBUG + if(debug_pfkey && sysctl_ipsec_debug_verbose) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_destroy_socket: " + "skb=%p dequeued.\n", skb); + printk(KERN_INFO "klips_debug:pfkey_destroy_socket: " + "pfkey_skb contents:"); + printk(" next:%p", skb->next); + printk(" prev:%p", skb->prev); + printk(" list:%p", skb->list); + printk(" sk:%p", skb->sk); + printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec); + printk(" dev:%p", skb->dev); + if(skb->dev) { + if(skb->dev->name) { + printk(" dev->name:%s", skb->dev->name); + } else { + printk(" dev->name:NULL?"); + } + } else { + printk(" dev:NULL"); + } + printk(" h:%p", skb->h.raw); + printk(" nh:%p", skb->nh.raw); + printk(" mac:%p", skb->mac.raw); + printk(" dst:%p", skb->dst); + if(sysctl_ipsec_debug_verbose) { + int i; + + printk(" cb"); + for(i=0; i<48; i++) { + printk(":%2x", skb->cb[i]); + } + } + printk(" len:%d", skb->len); + printk(" csum:%d", skb->csum); +#ifndef NETDEV_23 + printk(" used:%d", skb->used); + printk(" is_clone:%d", skb->is_clone); +#endif /* NETDEV_23 */ + printk(" cloned:%d", skb->cloned); + printk(" pkt_type:%d", skb->pkt_type); + printk(" ip_summed:%d", skb->ip_summed); + printk(" priority:%d", skb->priority); + printk(" protocol:%d", skb->protocol); + printk(" security:%d", skb->security); + printk(" truesize:%d", skb->truesize); + printk(" head:%p", skb->head); + printk(" data:%p", skb->data); + printk(" tail:%p", skb->tail); + printk(" end:%p", skb->end); + if(sysctl_ipsec_debug_verbose) { + unsigned int i; + printk(" data"); + for(i=(unsigned int)(skb->head); i<(unsigned int)(skb->end); i++) { + printk(":%2x", (unsigned char)(*(char*)(i))); + } + } + printk(" destructor:%p", skb->destructor); + printk("\n"); + } +#endif /* CONFIG_IPSEC_DEBUG */ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_destroy_socket: " + "skb=%p freed.\n", + skb); + kfree_skb(skb); + +#else /* NET_21 */ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_destroy_socket: " + "skb=%p dequeued and freed.\n", + skb); + kfree_skb(skb, FREE_WRITE); + +#endif /* NET_21 */ + } + + sk->dead = 1; + sk_free(sk); + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_destroy_socket: destroyed.\n"); +} + +int +pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg) +{ + int error = 0; + struct sk_buff * skb = NULL; + struct sock *sk; + + if(sock == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_upmsg: " + "NULL socket passed in.\n"); + return -EINVAL; + } + + if(pfkey_msg == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_upmsg: " + "NULL pfkey_msg passed in.\n"); + return -EINVAL; + } + +#ifdef NET_21 + sk = sock->sk; +#else /* NET_21 */ + sk = sock->data; +#endif /* NET_21 */ + + if(sk == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_upmsg: " + "NULL sock passed in.\n"); + return -EINVAL; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_upmsg: " + "allocating %d bytes...\n", + (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)); + if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_upmsg: " + "no buffers left to send up a message.\n"); + return -ENOBUFS; + } + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_upmsg: " + "...allocated at %p.\n", + skb); + + skb->dev = NULL; + + if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { + printk(KERN_WARNING "klips_error:pfkey_upmsg: " + "tried to skb_put %ld, %d available. This should never happen, please report.\n", + (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, + skb_tailroom(skb)); +#ifdef NET_21 + kfree_skb(skb); +#else /* NET_21 */ + kfree_skb(skb, FREE_WRITE); +#endif /* NET_21 */ + return -ENOBUFS; + } + skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); + memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN); + +#ifndef NET_21 + skb->free = 1; +#endif /* !NET_21 */ + + if((error = sock_queue_rcv_skb(sk, skb)) < 0) { + skb->sk=NULL; +#ifdef NET_21 + kfree_skb(skb); +#else /* NET_21 */ + kfree_skb(skb, FREE_WRITE); +#endif /* NET_21 */ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_upmsg: " + "error=%d calling sock_queue_rcv_skb with skb=%p.\n", + error, + skb); + return error; + } + return error; +} + +DEBUG_NO_STATIC int +pfkey_create(struct socket *sock, int protocol) +{ + struct sock *sk; + + if(sock == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_create: " + "socket NULL.\n"); + return -EINVAL; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_create: " + "sock=%p type:%d state:%d flags:%ld protocol:%d\n", + sock, + sock->type, + (unsigned int)(sock->state), + sock->flags, protocol); + + if(sock->type != SOCK_RAW) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_create: " + "only SOCK_RAW supported.\n"); + return -ESOCKTNOSUPPORT; + } + + if(protocol != PF_KEY_V2) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_create: " + "protocol not PF_KEY_V2.\n"); + return -EPROTONOSUPPORT; + } + + if((current->uid != 0)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_create: " + "must be root to open pfkey sockets.\n"); + return -EACCES; + } + +#ifdef NET_21 + sock->state = SS_UNCONNECTED; +#endif /* NET_21 */ + MOD_INC_USE_COUNT; +#ifdef NET_21 + if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL) +#else /* NET_21 */ + if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL) +#endif /* NET_21 */ + { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_create: " + "Out of memory trying to allocate.\n"); + MOD_DEC_USE_COUNT; + return -ENOMEM; + } + +#ifndef NET_21 + memset(sk, 0, sizeof(*sk)); +#endif /* !NET_21 */ + +#ifdef NET_21 + sock_init_data(sock, sk); + + sk->destruct = NULL; + sk->reuse = 1; + sock->ops = &SOCKOPS_WRAPPED(pfkey_ops); + + sk->zapped=0; + sk->family = PF_KEY; +/* sk->num = protocol; */ + sk->protocol = protocol; + key_pid(sk) = current->pid; + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_create: " + "sock->fasync_list=%p sk->sleep=%p.\n", + sock->fasync_list, + sk->sleep); +#else /* NET_21 */ + sk->type=sock->type; + init_timer(&sk->timer); + skb_queue_head_init(&sk->write_queue); + skb_queue_head_init(&sk->receive_queue); + skb_queue_head_init(&sk->back_log); + sk->rcvbuf=SK_RMEM_MAX; + sk->sndbuf=SK_WMEM_MAX; + sk->allocation=GFP_KERNEL; + sk->state=TCP_CLOSE; + sk->priority=SOPRI_NORMAL; + sk->state_change=pfkey_state_change; + sk->data_ready=pfkey_data_ready; + sk->write_space=pfkey_write_space; + sk->error_report=pfkey_state_change; + sk->mtu=4096; + sk->socket=sock; + sock->data=(void *)sk; + sk->sleep=sock->wait; +#endif /* NET_21 */ + + pfkey_insert_socket(sk); + pfkey_list_insert_socket(sock, &pfkey_open_sockets); + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_create: " + "Socket sock=%p sk=%p initialised.\n", sock, sk); + return 0; +} + +#ifndef NET_21 +DEBUG_NO_STATIC int +pfkey_dup(struct socket *newsock, struct socket *oldsock) +{ + struct sock *sk; + + if(newsock==NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_dup: " + "No new socket attached.\n"); + return -EINVAL; + } + + if(oldsock==NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_dup: " + "No old socket attached.\n"); + return -EINVAL; + } + +#ifdef NET_21 + sk=oldsock->sk; +#else /* NET_21 */ + sk=oldsock->data; +#endif /* NET_21 */ + + /* May not have data attached */ + if(sk==NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_dup: " + "No sock attached to old socket.\n"); + return -EINVAL; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_dup: .\n"); + + return pfkey_create(newsock, sk->protocol); +} +#endif /* !NET_21 */ + +DEBUG_NO_STATIC int +#ifdef NETDEV_23 +pfkey_release(struct socket *sock) +#else /* NETDEV_23 */ +pfkey_release(struct socket *sock, struct socket *peersock) +#endif /* NETDEV_23 */ +{ + struct sock *sk; + int i; + + if(sock==NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_release: " + "No socket attached.\n"); + return 0; /* -EINVAL; */ + } + +#ifdef NET_21 + sk=sock->sk; +#else /* NET_21 */ + sk=sock->data; +#endif /* NET_21 */ + + /* May not have data attached */ + if(sk==NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_release: " + "No sk attached to sock=%p.\n", sock); + return 0; /* -EINVAL; */ + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_release: " + "sock=%p sk=%p\n", sock, sk); + +#ifdef NET_21 + if(!sk->dead) +#endif /* NET_21 */ + if(sk->state_change) { + sk->state_change(sk); + } + +#ifdef NET_21 + sock->sk = NULL; +#else /* NET_21 */ + sock->data = NULL; +#endif /* NET_21 */ + + /* Try to flush out this socket. Throw out buffers at least */ + pfkey_destroy_socket(sk); + pfkey_list_remove_socket(sock, &pfkey_open_sockets); + for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) { + pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i])); + } + + MOD_DEC_USE_COUNT; + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_release: " + "succeeded.\n"); + + return 0; +} + +#ifndef NET_21 +DEBUG_NO_STATIC int +pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_bind: " + "operation not supported.\n"); + return -EINVAL; +} + +DEBUG_NO_STATIC int +pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_connect: " + "operation not supported.\n"); + return -EINVAL; +} + +DEBUG_NO_STATIC int +pfkey_socketpair(struct socket *a, struct socket *b) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_socketpair: " + "operation not supported.\n"); + return -EINVAL; +} + +DEBUG_NO_STATIC int +pfkey_accept(struct socket *sock, struct socket *newsock, int flags) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_aaccept: " + "operation not supported.\n"); + return -EINVAL; +} + +DEBUG_NO_STATIC int +pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, + int peer) +{ + struct sockaddr *ska = (struct sockaddr*)uaddr; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_getname: .\n"); + ska->sa_family = PF_KEY; + *uaddr_len = sizeof(*ska); + return 0; +} + +DEBUG_NO_STATIC int +pfkey_select(struct socket *sock, int sel_type, select_table *wait) +{ + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_select: " + ".sock=%p sk=%p sel_type=%d\n", + sock, + sock->data, + sel_type); + if(sock == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_select: " + "Null socket passed in.\n"); + return -EINVAL; + } + return datagram_select(sock->data, sel_type, wait); +} + +DEBUG_NO_STATIC int +pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ioctl: " + "not supported.\n"); + return -EINVAL; +} + +DEBUG_NO_STATIC int +pfkey_listen(struct socket *sock, int backlog) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_listen: " + "not supported.\n"); + return -EINVAL; +} +#endif /* !NET_21 */ + +DEBUG_NO_STATIC int +pfkey_shutdown(struct socket *sock, int mode) +{ + struct sock *sk; + + if(sock == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_shutdown: " + "NULL socket passed in.\n"); + return -EINVAL; + } + +#ifdef NET_21 + sk=sock->sk; +#else /* NET_21 */ + sk=sock->data; +#endif /* NET_21 */ + + if(sk == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_shutdown: " + "No sock attached to socket.\n"); + return -EINVAL; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_shutdown: " + "mode=%x.\n", mode); + mode++; + + if(mode&SEND_SHUTDOWN) { + sk->shutdown|=SEND_SHUTDOWN; + sk->state_change(sk); + } + + if(mode&RCV_SHUTDOWN) { + sk->shutdown|=RCV_SHUTDOWN; + sk->state_change(sk); + } + return 0; +} + +#ifndef NET_21 +DEBUG_NO_STATIC int +pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) +{ +#ifndef NET_21 + struct sock *sk; + + if(sock == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_setsockopt: " + "Null socket passed in.\n"); + return -EINVAL; + } + + sk=sock->data; + + if(sk == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_setsockopt: " + "Null sock passed in.\n"); + return -EINVAL; + } +#endif /* !NET_21 */ + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_setsockopt: .\n"); + if(level!=SOL_SOCKET) { + return -EOPNOTSUPP; + } +#ifdef NET_21 + return sock_setsockopt(sock, level, optname, optval, optlen); +#else /* NET_21 */ + return sock_setsockopt(sk, level, optname, optval, optlen); +#endif /* NET_21 */ +} + +DEBUG_NO_STATIC int +pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) +{ +#ifndef NET_21 + struct sock *sk; + + if(sock == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_setsockopt: " + "Null socket passed in.\n"); + return -EINVAL; + } + + sk=sock->data; + + if(sk == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_setsockopt: " + "Null sock passed in.\n"); + return -EINVAL; + } +#endif /* !NET_21 */ + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_getsockopt: .\n"); + if(level!=SOL_SOCKET) { + return -EOPNOTSUPP; + } +#ifdef NET_21 + return sock_getsockopt(sock, level, optname, optval, optlen); +#else /* NET_21 */ + return sock_getsockopt(sk, level, optname, optval, optlen); +#endif /* NET_21 */ +} + +DEBUG_NO_STATIC int +pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg) +{ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_fcntl: " + "not supported.\n"); + return -EINVAL; +} +#endif /* !NET_21 */ + +/* + * Send PF_KEY data down. + */ + +DEBUG_NO_STATIC int +#ifdef NET_21 +pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) +#else /* NET_21 */ +pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags) +#endif /* NET_21 */ +{ + struct sock *sk; + int error = 0; + struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL; + + if(sock == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "Null socket passed in.\n"); + SENDERR(EINVAL); + } + +#ifdef NET_21 + sk = sock->sk; +#else /* NET_21 */ + sk = sock->data; +#endif /* NET_21 */ + + if(sk == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "Null sock passed in.\n"); + SENDERR(EINVAL); + } + + if(msg == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "Null msghdr passed in.\n"); + SENDERR(EINVAL); + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: .\n"); + if(sk->err) { + error = sock_error(sk); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "sk->err is non-zero, returns %d.\n", + error); + SENDERR(-error); + } + + if((current->uid != 0)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "must be root to send messages to pfkey sockets.\n"); + SENDERR(EACCES); + } + +#ifdef NET_21 + if(msg->msg_control) +#else /* NET_21 */ + if(flags || msg->msg_control) +#endif /* NET_21 */ + { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "can't set flags or set msg_control.\n"); + SENDERR(EINVAL); + } + + if(sk->shutdown & SEND_SHUTDOWN) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "shutdown.\n"); + send_sig(SIGPIPE, current, 0); + SENDERR(EPIPE); + } + + if(len < sizeof(struct sadb_msg)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "bogus msg len of %d, too small.\n", len); + SENDERR(EMSGSIZE); + } + + if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "memory allocation error.\n"); + SENDERR(ENOBUFS); + } + + memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len); + + if(pfkey_msg->sadb_msg_version != PF_KEY_V2) { + KLIPS_PRINT(1 || debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "not PF_KEY_V2 msg, found %d, should be %d.\n", + pfkey_msg->sadb_msg_version, + PF_KEY_V2); + kfree((void*)pfkey_msg); + return -EINVAL; + } + + if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "bogus msg len of %d, not %d byte aligned.\n", + len, (int)IPSEC_PFKEYv2_ALIGN); + SENDERR(EMSGSIZE); + } + +#if 0 + /* This check is questionable, since a downward message could be + the result of an ACQUIRE either from kernel (PID==0) or + userspace (some other PID). */ + /* check PID */ + if(pfkey_msg->sadb_msg_pid != current->pid) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "pid (%d) does not equal sending process pid (%d).\n", + pfkey_msg->sadb_msg_pid, current->pid); + SENDERR(EINVAL); + } +#endif + + if(pfkey_msg->sadb_msg_reserved) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "reserved field must be zero, set to %d.\n", + pfkey_msg->sadb_msg_reserved); + SENDERR(EINVAL); + } + + if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "msg type too large or small:%d.\n", + pfkey_msg->sadb_msg_type); + SENDERR(EINVAL); + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "msg sent for parsing.\n"); + + if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) { + struct socket_list *pfkey_socketsp; + + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " + "pfkey_msg_parse returns %d.\n", + error); + + if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "memory allocation error.\n"); + SENDERR(ENOBUFS); + } + memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg)); + pfkey_reply->sadb_msg_errno = -error; + pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN; + + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + int error_upmsg = 0; + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " + "sending up error=%d message=%p to socket=%p.\n", + error, + pfkey_reply, + pfkey_socketsp->socketp); + if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " + "sending up error message to socket=%p failed with error=%d.\n", + pfkey_socketsp->socketp, + error_upmsg); + /* pfkey_msg_free(&pfkey_reply); */ + /* SENDERR(-error); */ + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: " + "sending up error message to socket=%p succeeded.\n", + pfkey_socketsp->socketp); + } + + pfkey_msg_free(&pfkey_reply); + + SENDERR(-error); + } + + errlab: + if (pfkey_msg) { + kfree((void*)pfkey_msg); + } + + if(error) { + return error; + } else { + return len; + } +} + +/* + * Receive PF_KEY data up. + */ + +DEBUG_NO_STATIC int +#ifdef NET_21 +pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) +#else /* NET_21 */ +pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len) +#endif /* NET_21 */ +{ + struct sock *sk; +#ifdef NET_21 + int noblock = flags & MSG_DONTWAIT; +#endif /* NET_21 */ + struct sk_buff *skb; + int error; + + if(sock == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_recvmsg: " + "Null socket passed in.\n"); + return -EINVAL; + } + +#ifdef NET_21 + sk = sock->sk; +#else /* NET_21 */ + sk = sock->data; +#endif /* NET_21 */ + + if(sk == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_recvmsg: " + "Null sock passed in for sock=%p.\n", sock); + return -EINVAL; + } + + if(msg == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_recvmsg: " + "Null msghdr passed in for sock=%p, sk=%p.\n", + sock, sk); + return -EINVAL; + } + + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_recvmsg: sock=%p sk=%p msg=%p size=%d.\n", + sock, sk, msg, size); + if(flags & ~MSG_PEEK) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "flags (%d) other than MSG_PEEK not supported.\n", + flags); + return -EOPNOTSUPP; + } + +#ifdef NET_21 + msg->msg_namelen = 0; /* sizeof(*ska); */ +#else /* NET_21 */ + if(addr_len) { + *addr_len = 0; /* sizeof(*ska); */ + } +#endif /* NET_21 */ + + if(sk->err) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sendmsg: " + "sk->err=%d.\n", sk->err); + return sock_error(sk); + } + + if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) { + return error; + } + + if(size > skb->len) { + size = skb->len; + } +#ifdef NET_21 + else if(size len) { + msg->msg_flags |= MSG_TRUNC; + } +#endif /* NET_21 */ + + skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size); + sk->stamp=skb->stamp; + + skb_free_datagram(sk, skb); + return size; +} + +#ifdef NET_21 +struct net_proto_family pfkey_family_ops = { + PF_KEY, + pfkey_create +}; + +struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = { +#ifdef NETDEV_23 + family: PF_KEY, + release: pfkey_release, + bind: sock_no_bind, + connect: sock_no_connect, + socketpair: sock_no_socketpair, + accept: sock_no_accept, + getname: sock_no_getname, + poll: datagram_poll, + ioctl: sock_no_ioctl, + listen: sock_no_listen, + shutdown: pfkey_shutdown, + setsockopt: sock_no_setsockopt, + getsockopt: sock_no_getsockopt, + sendmsg: pfkey_sendmsg, + recvmsg: pfkey_recvmsg, + mmap: sock_no_mmap, +#else /* NETDEV_23 */ + PF_KEY, + sock_no_dup, + pfkey_release, + sock_no_bind, + sock_no_connect, + sock_no_socketpair, + sock_no_accept, + sock_no_getname, + datagram_poll, + sock_no_ioctl, + sock_no_listen, + pfkey_shutdown, + sock_no_setsockopt, + sock_no_getsockopt, + sock_no_fcntl, + pfkey_sendmsg, + pfkey_recvmsg +#endif /* NETDEV_23 */ +}; + +#ifdef NETDEV_23 +#include +SOCKOPS_WRAP(pfkey, PF_KEY); +#endif /* NETDEV_23 */ + +#else /* NET_21 */ +struct proto_ops pfkey_proto_ops = { + PF_KEY, + pfkey_create, + pfkey_dup, + pfkey_release, + pfkey_bind, + pfkey_connect, + pfkey_socketpair, + pfkey_accept, + pfkey_getname, + pfkey_select, + pfkey_ioctl, + pfkey_listen, + pfkey_shutdown, + pfkey_setsockopt, + pfkey_getsockopt, + pfkey_fcntl, + pfkey_sendmsg, + pfkey_recvmsg +}; +#endif /* NET_21 */ + +#ifdef CONFIG_PROC_FS +#ifndef PROC_FS_2325 +DEBUG_NO_STATIC +#endif /* PROC_FS_2325 */ +int +pfkey_get_info(char *buffer, char **start, off_t offset, int length +#ifndef PROC_NO_DUMMY +, int dummy +#endif /* !PROC_NO_DUMMY */ +) +{ + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ + off_t begin=0; + int len=0; + struct sock *sk=pfkey_sock_list; + +#ifdef CONFIG_IPSEC_DEBUG + if(!sysctl_ipsec_debug_verbose) { +#endif /* CONFIG_IPSEC_DEBUG */ + len += ipsec_snprintf(buffer, length, + " sock pid socket next prev e n p sndbf Flags Type St\n"); +#ifdef CONFIG_IPSEC_DEBUG + } else { + len += ipsec_snprintf(buffer, length, + " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n"); + } +#endif /* CONFIG_IPSEC_DEBUG */ + + while(sk!=NULL) { +#ifdef CONFIG_IPSEC_DEBUG + if(!sysctl_ipsec_debug_verbose) { +#endif /* CONFIG_IPSEC_DEBUG */ + len += ipsec_snprintf(buffer+len, length-len, + "%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n", + sk, + key_pid(sk), + sk->socket, + sk->next, + sk->prev, + sk->err, + sk->num, + sk->protocol, + sk->sndbuf, + sk->socket->flags, + sk->socket->type, + sk->socket->state); +#ifdef CONFIG_IPSEC_DEBUG + } else { + len += ipsec_snprintf(buffer+len, length-len, + "%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n", + sk, + key_pid(sk), + sk->dead, + sk->sleep, + sk->socket, + sk->next, + sk->prev, + sk->err, + sk->reuse, + sk->zapped, + sk->num, + sk->protocol, + sk->sndbuf, + (unsigned int)sk->stamp.tv_sec, + (unsigned int)sk->stamp.tv_usec, + sk->socket->flags, + sk->socket->type, + sk->socket->state); + } +#endif /* CONFIG_IPSEC_DEBUG */ + + if (len >= max_content) { + /* we've done all that can fit -- stop loop */ + len = max_content; /* truncate crap */ + break; + } else { + const off_t pos = begin + len; /* file position of end of what we've generated */ + + if (pos <= offset) { + /* all is before first interesting character: + * discard, but note where we are. + */ + len = 0; + begin = pos; + } + } + /* Should this be here?? TIS */ + sk=sk->next; + } + + *start = buffer + (offset - begin); /* Start of wanted data */ + return len - (offset - begin); +} + +#ifndef PROC_FS_2325 +DEBUG_NO_STATIC +#endif /* PROC_FS_2325 */ +int +pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length +#ifndef PROC_NO_DUMMY +, int dummy +#endif /* !PROC_NO_DUMMY */ +) +{ + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ + off_t begin=0; + int len=0; + int satype; + struct supported_list *pfkey_supported_p; + + len += ipsec_snprintf(buffer, length, + "satype exttype alg_id ivlen minbits maxbits\n"); + + for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { + pfkey_supported_p = pfkey_supported_list[satype]; + while(pfkey_supported_p) { + len += ipsec_snprintf(buffer+len, length-len, + " %2d %2d %2d %3d %3d %3d\n", + satype, + pfkey_supported_p->supportedp->supported_alg_exttype, + pfkey_supported_p->supportedp->supported_alg_id, + pfkey_supported_p->supportedp->supported_alg_ivlen, + pfkey_supported_p->supportedp->supported_alg_minbits, + pfkey_supported_p->supportedp->supported_alg_maxbits); + + if (len >= max_content) { + /* we've done all that can fit -- stop loop */ + len = max_content; /* truncate crap */ + break; + } else { + const off_t pos = begin + len; /* file position of end of what we've generated */ + + if (pos <= offset) { + /* all is before first interesting character: + * discard, but note where we are. + */ + len = 0; + begin = pos; + } + } + + pfkey_supported_p = pfkey_supported_p->next; + } + } + *start = buffer + (offset - begin); /* Start of wanted data */ + return len - (offset - begin); +} + +#ifndef PROC_FS_2325 +DEBUG_NO_STATIC +#endif /* PROC_FS_2325 */ +int +pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length +#ifndef PROC_NO_DUMMY +, int dummy +#endif /* !PROC_NO_DUMMY */ +) +{ + const int max_content = length > 0? length-1 : 0; /* limit of useful snprintf output */ + off_t begin=0; + int len=0; + int satype; + struct socket_list *pfkey_sockets; + + len += ipsec_snprintf(buffer, length, + "satype socket pid sk\n"); + + for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) { + pfkey_sockets = pfkey_registered_sockets[satype]; + while(pfkey_sockets) { +#ifdef NET_21 + len += ipsec_snprintf(buffer+len, length-len, + " %2d %8p %5d %8p\n", + satype, + pfkey_sockets->socketp, + key_pid(pfkey_sockets->socketp->sk), + pfkey_sockets->socketp->sk); +#else /* NET_21 */ + len += ipsec_snprintf(buffer+len, length-len, + " %2d %8p N/A %8p\n", + satype, + pfkey_sockets->socketp, +#if 0 + key_pid((pfkey_sockets->socketp)->data), +#endif + (pfkey_sockets->socketp)->data); +#endif /* NET_21 */ + + if (len >= max_content) { + /* we've done all that can fit -- stop loop (could stop two) */ + len = max_content; /* truncate crap */ + break; + } else { + const off_t pos = begin + len; /* file position of end of what we've generated */ + + if (pos <= offset) { + /* all is before first interesting character: + * discard, but note where we are. + */ + len = 0; + begin = pos; + } + } + + pfkey_sockets = pfkey_sockets->next; + } + } + *start = buffer + (offset - begin); /* Start of wanted data */ + return len - (offset - begin); +} + +#ifndef PROC_FS_2325 +struct proc_dir_entry proc_net_pfkey = +{ + 0, + 6, "pf_key", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + pfkey_get_info +}; +struct proc_dir_entry proc_net_pfkey_supported = +{ + 0, + 16, "pf_key_supported", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + pfkey_supported_get_info +}; +struct proc_dir_entry proc_net_pfkey_registered = +{ + 0, + 17, "pf_key_registered", + S_IFREG | S_IRUGO, 1, 0, 0, + 0, &proc_net_inode_operations, + pfkey_registered_get_info +}; +#endif /* !PROC_FS_2325 */ +#endif /* CONFIG_PROC_FS */ + +DEBUG_NO_STATIC int +supported_add_all(int satype, struct supported supported[], int size) +{ + int i; + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:init_pfkey: " + "sizeof(supported_init_)[%d]/sizeof(struct supported)[%d]=%d.\n", + satype, + size, + (int)sizeof(struct supported), + (int)(size/sizeof(struct supported))); + + for(i = 0; i < size / sizeof(struct supported); i++) { + + KLIPS_PRINT(debug_pfkey, + "klips_debug:init_pfkey: " + "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", + i, + satype, + supported[i].supported_alg_exttype, + supported[i].supported_alg_id, + supported[i].supported_alg_ivlen, + supported[i].supported_alg_minbits, + supported[i].supported_alg_maxbits); + + error |= pfkey_list_insert_supported(&(supported[i]), + &(pfkey_supported_list[satype])); + } + return error; +} + +DEBUG_NO_STATIC int +supported_remove_all(int satype) +{ + int error = 0; + struct supported*supportedp; + + while(pfkey_supported_list[satype]) { + supportedp = pfkey_supported_list[satype]->supportedp; + KLIPS_PRINT(debug_pfkey, + "klips_debug:init_pfkey: " + "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", + satype, + supportedp->supported_alg_exttype, + supportedp->supported_alg_id, + supportedp->supported_alg_ivlen, + supportedp->supported_alg_minbits, + supportedp->supported_alg_maxbits); + + error |= pfkey_list_remove_supported(supportedp, + &(pfkey_supported_list[satype])); + } + return error; +} + +int +pfkey_init(void) +{ + int error = 0; + int i; + + static struct supported supported_init_ah[] = { +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128}, +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160} +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + }; + static struct supported supported_init_esp[] = { +#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128}, +#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}, +#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ +#ifdef CONFIG_IPSEC_ENC_3DES + {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168}, +#endif /* CONFIG_IPSEC_ENC_3DES */ + }; + static struct supported supported_init_ipip[] = { + {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32} +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32} + , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128} + , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128} +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ + }; +#ifdef CONFIG_IPSEC_IPCOMP + static struct supported supported_init_ipcomp[] = { + {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1} + }; +#endif /* CONFIG_IPSEC_IPCOMP */ + +#if 0 + printk(KERN_INFO + "klips_info:pfkey_init: " + "Openswan: initialising PF_KEYv2 domain sockets.\n"); +#endif + + for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) { + pfkey_registered_sockets[i] = NULL; + pfkey_supported_list[i] = NULL; + } + + error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah)); + error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp)); +#ifdef CONFIG_IPSEC_IPCOMP + error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp)); +#endif /* CONFIG_IPSEC_IPCOMP */ + error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip)); + +#ifdef NET_21 + error |= sock_register(&pfkey_family_ops); +#else /* NET_21 */ + error |= sock_register(pfkey_proto_ops.family, &pfkey_proto_ops); +#endif /* NET_21 */ + +#ifdef CONFIG_PROC_FS +# ifndef PROC_FS_2325 +# ifdef PROC_FS_21 + error |= proc_register(proc_net, &proc_net_pfkey); + error |= proc_register(proc_net, &proc_net_pfkey_supported); + error |= proc_register(proc_net, &proc_net_pfkey_registered); +# else /* PROC_FS_21 */ + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey); + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported); + error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered); +# endif /* PROC_FS_21 */ +# else /* !PROC_FS_2325 */ + proc_net_create ("pf_key", 0, pfkey_get_info); + proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info); + proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info); +# endif /* !PROC_FS_2325 */ +#endif /* CONFIG_PROC_FS */ + + return error; +} + +int +pfkey_cleanup(void) +{ + int error = 0; + + printk(KERN_INFO "klips_info:pfkey_cleanup: " + "shutting down PF_KEY domain sockets.\n"); +#ifdef NET_21 + error |= sock_unregister(PF_KEY); +#else /* NET_21 */ + error |= sock_unregister(pfkey_proto_ops.family); +#endif /* NET_21 */ + + error |= supported_remove_all(SADB_SATYPE_AH); + error |= supported_remove_all(SADB_SATYPE_ESP); +#ifdef CONFIG_IPSEC_IPCOMP + error |= supported_remove_all(SADB_X_SATYPE_COMP); +#endif /* CONFIG_IPSEC_IPCOMP */ + error |= supported_remove_all(SADB_X_SATYPE_IPIP); + +#ifdef CONFIG_PROC_FS +# ifndef PROC_FS_2325 + if (proc_net_unregister(proc_net_pfkey.low_ino) != 0) + printk("klips_debug:pfkey_cleanup: " + "cannot unregister /proc/net/pf_key\n"); + if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0) + printk("klips_debug:pfkey_cleanup: " + "cannot unregister /proc/net/pf_key_supported\n"); + if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0) + printk("klips_debug:pfkey_cleanup: " + "cannot unregister /proc/net/pf_key_registered\n"); +# else /* !PROC_FS_2325 */ + proc_net_remove ("pf_key"); + proc_net_remove ("pf_key_supported"); + proc_net_remove ("pf_key_registered"); +# endif /* !PROC_FS_2325 */ +#endif /* CONFIG_PROC_FS */ + + /* other module unloading cleanup happens here */ + return error; +} + +#ifdef MODULE +#if 0 +int +init_module(void) +{ + pfkey_init(); + return 0; +} + +void +cleanup_module(void) +{ + pfkey_cleanup(); +} +#endif /* 0 */ +#else /* MODULE */ +void +pfkey_proto_init(struct net_proto *pro) +{ + pfkey_init(); +} +#endif /* MODULE */ + +/* + * $Log: pfkey_v2.c,v $ + * Revision 1.7 2004/06/17 08:47:11 ken + * Remove bad /* string from comments + * + * Revision 1.6 2004/04/27 22:18:54 ken + * Backport of FreeS/WAN 2.06 ipsec_snprintf() and /proc/ipsec* fixes (ts/kb) + * + * Revision 1.5 2003/12/04 03:09:50 ken + * Cast safely for ia64 + * + * Revision 1.4 2003/11/25 00:25:34 ken + * Change references to Openswan + * + * Revision 1.3 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.2 2002/09/05 03:27:09 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:18 ken + * 1.98b + * + * Revision 1.68 2002/03/08 01:15:17 mcr + * put some internal structure only debug messages behind + * && sysctl_ipsec_debug_verbose. + * + * Revision 1.67 2002/01/29 17:17:57 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.66 2002/01/29 04:00:54 mcr + * more excise of kversions.h header. + * + * Revision 1.65 2002/01/29 02:13:18 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.64 2001/11/26 09:23:51 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.61.2.1 2001/09/25 02:28:44 mcr + * cleaned up includes. + * + * Revision 1.63 2001/11/12 19:38:00 rgb + * Continue trying other sockets even if one fails and return only original + * error. + * + * Revision 1.62 2001/10/18 04:45:22 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/freeswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.61 2001/09/20 15:32:59 rgb + * Min/max cleanup. + * + * Revision 1.60 2001/06/14 19:35:12 rgb + * Update copyright date. + * + * Revision 1.59 2001/06/13 15:35:48 rgb + * Fixed #endif comments. + * + * Revision 1.58 2001/05/04 16:37:24 rgb + * Remove erroneous checking of return codes for proc_net_* in 2.4. + * + * Revision 1.57 2001/05/03 19:43:36 rgb + * Initialise error return variable. + * Check error return codes in startup and shutdown. + * Standardise on SENDERR() macro. + * + * Revision 1.56 2001/04/21 23:05:07 rgb + * Define out skb->used for 2.4 kernels. + * + * Revision 1.55 2001/02/28 05:03:28 rgb + * Clean up and rationalise startup messages. + * + * Revision 1.54 2001/02/27 22:24:55 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.53 2001/02/27 06:48:18 rgb + * Fixed pfkey socket unregister log message to reflect type and function. + * + * Revision 1.52 2001/02/26 22:34:38 rgb + * Fix error return code that was getting overwritten by the error return + * code of an upmsg. + * + * Revision 1.51 2001/01/30 23:42:47 rgb + * Allow pfkey msgs from pid other than user context required for ACQUIRE + * and subsequent ADD or UDATE. + * + * Revision 1.50 2001/01/23 20:22:59 rgb + * 2.4 fix to remove removed is_clone member. + * + * Revision 1.49 2000/11/06 04:33:47 rgb + * Changed non-exported functions to DEBUG_NO_STATIC. + * + * Revision 1.48 2000/09/29 19:47:41 rgb + * Update copyright. + * + * Revision 1.47 2000/09/22 04:23:04 rgb + * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error. + * + * Revision 1.46 2000/09/21 04:20:44 rgb + * Fixed array size off-by-one error. (Thanks Svenning!) + * + * Revision 1.45 2000/09/20 04:01:26 rgb + * Changed static functions to DEBUG_NO_STATIC for revealing function names + * in oopsen. + * + * Revision 1.44 2000/09/19 00:33:17 rgb + * 2.0 fixes. + * + * Revision 1.43 2000/09/16 01:28:13 rgb + * Fixed use of 0 in p format warning. + * + * Revision 1.42 2000/09/16 01:09:41 rgb + * Fixed debug format warning for pointers that was expecting ints. + * + * Revision 1.41 2000/09/13 15:54:00 rgb + * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info(). + * Moved supported algos add and remove to functions. + * + * Revision 1.40 2000/09/12 18:49:28 rgb + * Added IPIP tunnel and IPCOMP register support. + * + * Revision 1.39 2000/09/12 03:23:49 rgb + * Converted #if0 debugs to sysctl. + * Removed debug_pfkey initialisations that prevented no_debug loading or + * linking. + * + * Revision 1.38 2000/09/09 06:38:02 rgb + * Return positive errno in pfkey_reply error message. + * + * Revision 1.37 2000/09/08 19:19:09 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * Clean-up of long-unused crud... + * Create pfkey error message on on failure. + * Give pfkey_list_{insert,remove}_{socket,supported}() some error + * checking. + * + * Revision 1.36 2000/09/01 18:49:38 rgb + * Reap experimental NET_21_ bits. + * Turned registered sockets list into an array of one list per satype. + * Remove references to deprecated sklist_{insert,remove}_socket. + * Removed leaking socket debugging code. + * Removed duplicate pfkey_insert_socket in pfkey_create. + * Removed all references to pfkey msg->msg_name, since it is not used for + * pfkey. + * Added a supported algorithms array lists, one per satype and registered + * existing algorithms. + * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to + * list. + * Only send pfkey_expire() messages to sockets registered for that satype. + * + * Revision 1.35 2000/08/24 17:03:00 rgb + * Corrected message size error return code for PF_KEYv2. + * Removed downward error prohibition. + * + * Revision 1.34 2000/08/21 16:32:26 rgb + * Re-formatted for cosmetic consistency and readability. + * + * Revision 1.33 2000/08/20 21:38:24 rgb + * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil) + * Extended the upward message initiation of pfkey_sendmsg(). (Momchil) + * + * Revision 1.32 2000/07/28 14:58:31 rgb + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. + * + * Revision 1.31 2000/05/16 03:04:00 rgb + * Updates for 2.3.99pre8 from MB. + * + * Revision 1.30 2000/05/10 19:22:21 rgb + * Use sklist private functions for 2.3.xx compatibility. + * + * Revision 1.29 2000/03/22 16:17:03 rgb + * Fixed SOCKOPS_WRAPPED macro for SMP (MB). + * + * Revision 1.28 2000/02/21 19:30:45 rgb + * Removed references to pkt_bridged for 2.3.47 compatibility. + * + * Revision 1.27 2000/02/14 21:07:00 rgb + * Fixed /proc/net/pf-key legend spacing. + * + * Revision 1.26 2000/01/22 03:46:59 rgb + * Fixed pfkey error return mechanism so that we are able to free the + * local copy of the pfkey_msg, plugging a memory leak and silencing + * the bad object free complaints. + * + * Revision 1.25 2000/01/21 06:19:44 rgb + * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT. + * Added debugging to pfkey_upmsg. + * + * Revision 1.24 2000/01/10 16:38:23 rgb + * MB fixups for 2.3.x. + * + * Revision 1.23 1999/12/09 23:22:16 rgb + * Added more instrumentation for debugging 2.0 socket + * selection/reading. + * Removed erroneous 2.0 wait==NULL check bug in select. + * + * Revision 1.22 1999/12/08 20:32:16 rgb + * Tidied up 2.0.xx support, after major pfkey work, eliminating + * msg->msg_name twiddling in the process, since it is not defined + * for PF_KEYv2. + * + * Revision 1.21 1999/12/01 22:17:19 rgb + * Set skb->dev to zero on new skb in case it is a reused skb. + * Added check for skb_put overflow and freeing to avoid upmsg on error. + * Added check for wrong pfkey version and freeing to avoid upmsg on + * error. + * Shut off content dumping in pfkey_destroy. + * Added debugging message for size of buffer allocated for upmsg. + * + * Revision 1.20 1999/11/27 12:11:00 rgb + * Minor clean-up, enabling quiet operation of pfkey if desired. + * + * Revision 1.19 1999/11/25 19:04:21 rgb + * Update proc_fs code for pfkey to use dynamic registration. + * + * Revision 1.18 1999/11/25 09:07:17 rgb + * Implemented SENDERR macro for propagating error codes. + * Fixed error return code bug. + * + * Revision 1.17 1999/11/23 23:07:20 rgb + * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer + * parses. (PJO) + * Sort out pfkey and freeswan headers, putting them in a library path. + * + * Revision 1.16 1999/11/20 22:00:22 rgb + * Moved socketlist type declarations and prototypes for shared use. + * Renamed reformatted and generically extended for use by other socket + * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket. + * + * Revision 1.15 1999/11/18 04:15:09 rgb + * Make pfkey_data_ready temporarily available for 2.2.x testing. + * Clean up pfkey_destroy_socket() debugging statements. + * Add Peter Onion's code to send messages up to all listening sockets. + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * Replaced all kernel version macros to shorter, readable form. + * Added CONFIG_PROC_FS compiler directives in case it is shut off. + * + * Revision 1.14 1999/11/17 16:01:00 rgb + * Make pfkey_data_ready temporarily available for 2.2.x testing. + * Clean up pfkey_destroy_socket() debugging statements. + * Add Peter Onion's code to send messages up to all listening sockets. + * Changed #include "../../../lib/freeswan.h" to #include + * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile. + * + * Revision 1.13 1999/10/27 19:59:51 rgb + * Removed af_unix comments that are no longer relevant. + * Added debug prink statements. + * Added to the /proc output in pfkey_get_info. + * Made most functions non-static to enable oops tracing. + * Re-enable skb dequeueing and freeing. + * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg(). + * + * Revision 1.12 1999/10/26 17:05:42 rgb + * Complete re-ordering based on proto_ops structure order. + * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity. + * Simplification to use built-in socket ops where possible for 2.2.x. + * Add shorter macros for compiler directives to visually clean-up. + * Add lots of sk skb dequeueing debugging statements. + * Added to the /proc output in pfkey_get_info. + * + * Revision 1.11 1999/09/30 02:55:10 rgb + * Bogus skb detection. + * Fix incorrect /proc/net/ipsec-eroute printk message. + * + * Revision 1.10 1999/09/21 15:22:13 rgb + * Temporary fix while I figure out the right way to destroy sockets. + * + * Revision 1.9 1999/07/08 19:19:44 rgb + * Fix pointer format warning. + * Fix missing member error under 2.0.xx kernels. + * + * Revision 1.8 1999/06/13 07:24:04 rgb + * Add more debugging. + * + * Revision 1.7 1999/06/10 05:24:17 rgb + * Clarified compiler directives. + * Renamed variables to reduce confusion. + * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support. + * Added lots of sanity checking. + * + * Revision 1.6 1999/06/03 18:59:50 rgb + * More updates to 2.2.x socket support. Almost works, oops at end of call. + * + * Revision 1.5 1999/05/25 22:44:05 rgb + * Start fixing 2.2 sockets. + * + * Revision 1.4 1999/04/29 15:21:34 rgb + * Move log to the end of the file. + * Eliminate min/max redefinition in #include . + * Correct path for pfkey #includes + * Standardise an error return method. + * Add debugging instrumentation. + * Move message type checking to pfkey_msg_parse(). + * Add check for errno incorrectly set. + * Add check for valid PID. + * Add check for reserved illegally set. + * Add check for message out of bounds. + * + * Revision 1.3 1999/04/15 17:58:07 rgb + * Add RCSID labels. + * + * Revision 1.2 1999/04/15 15:37:26 rgb + * Forward check changes from POST1_00 branch. + * + * Revision 1.1.2.2 1999/04/13 20:37:12 rgb + * Header Title correction. + * + * Revision 1.1.2.1 1999/03/26 20:58:55 rgb + * Add pfkeyv2 support to KLIPS. + * + * + * RFC 2367 + * PF_KEY_v2 Key Management API + */ diff -urN linux-2.4.29/net/ipsec/pfkey_v2_parser.c linux-2.4.29-openswan-1.0.9/net/ipsec/pfkey_v2_parser.c --- linux-2.4.29/net/ipsec/pfkey_v2_parser.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/pfkey_v2_parser.c Wed Nov 19 03:29:41 2003 @@ -0,0 +1,4636 @@ +/* + * @(#) RFC2367 PF_KEYv2 Key management API message parser + * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: pfkey_v2_parser.c,v 1.16 2003/11/19 02:29:41 mcr Exp $ + */ + +/* + * Template from klips/net/ipsec/ipsec/ipsec_netlink.c. + */ + +char pfkey_v2_parser_c_version[] = "$Id: pfkey_v2_parser.c,v 1.16 2003/11/19 02:29:41 mcr Exp $"; + +#include +#include +#include /* printk() */ + +#define IPSEC_KLIPS1_COMPAT +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include +#include +#include +#ifdef SPINLOCK +# ifdef SPINLOCK_23 +# include /* *lock* */ +# else /* SPINLOCK_23 */ +# include /* *lock* */ +# endif /* SPINLOCK_23 */ +#endif /* SPINLOCK */ +#ifdef NET_21 +# include +# include +# define ip_chk_addr inet_addr_type +# define IS_MYADDR RTN_LOCAL +#endif +#include +#include +#ifdef NETLINK_SOCK +# include +#else +# include +#endif + +#include /* get_random_bytes() */ + +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_sa.h" + +#include "ipsec_radij.h" +#include "ipsec_netlink.h" +#include "ipsec_xform.h" +#include "ipsec_ah.h" +#include "ipsec_esp.h" +#include "ipsec_tunnel.h" /* ..., ipsec_tunnel_start_xmit() */ +#include "ipsec_rcv.h" +#include "ipcomp.h" + +#include +#include + +#include "ipsec_proto.h" + +#include "ipsec_alg.h" + +#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0) + +struct sklist_t { + struct socket *sk; + struct sklist_t* next; +} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev; + +__u32 pfkey_msg_seq = 0; + +DEBUG_NO_STATIC int +pfkey_alloc_ipsec_sa(struct ipsec_sa** tdb) +{ + int error = 0; + if(*tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_alloc_ipsec_sa: " + "tdb struct already allocated\n"); + SENDERR(EEXIST); + } + + if((*tdb = kmalloc(sizeof(**tdb), GFP_ATOMIC) ) == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_alloc_ipsec_sa: " + "memory allocation error\n"); + SENDERR(ENOMEM); + } + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_alloc_ipsec_sa: " + "allocated tdb struct=%p.\n", tdb); + + memset((caddr_t)*tdb, 0, sizeof(**tdb)); + errlab: + return(error); +} + +DEBUG_NO_STATIC int +pfkey_alloc_eroute(struct eroute** eroute) +{ + int error = 0; + if(*eroute) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_alloc_eroute: " + "eroute struct already allocated\n"); + SENDERR(EEXIST); + } + + if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_alloc_eroute: " + "memory allocation error\n"); + SENDERR(ENOMEM); + } + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_alloc_eroute: " + "allocated eroute struct=%p.\n", eroute); + memset((caddr_t)*eroute, 0, sizeof(**eroute)); + (*eroute)->er_eaddr.sen_len = + (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap); + (*eroute)->er_eaddr.sen_family = + (*eroute)->er_emask.sen_family = AF_ENCAP; + (*eroute)->er_eaddr.sen_type = SENT_IP4; + (*eroute)->er_emask.sen_type = 255; + (*eroute)->er_pid = 0; + (*eroute)->er_count = 0; + (*eroute)->er_lasttime = jiffies/HZ; + + errlab: + return(error); +} + +DEBUG_NO_STATIC int +pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext; + int error = 0; + struct ipsec_sa* tdbp; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sa_process: .\n"); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sa_process: " + "extr or extr->tdb is NULL, fatal\n"); + SENDERR(EINVAL); + } + + switch(pfkey_ext->sadb_ext_type) { + case SADB_EXT_SA: + tdbp = extr->tdb; + break; + case SADB_X_EXT_SA2: + if(pfkey_alloc_ipsec_sa(&(extr->tdb2)) == ENOMEM) { + SENDERR(ENOMEM); + } + tdbp = extr->tdb2; + break; + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sa_process: " + "invalid exttype=%d.\n", + pfkey_ext->sadb_ext_type); + SENDERR(EINVAL); + } + + tdbp->tdb_said.spi = pfkey_sa->sadb_sa_spi; + tdbp->tdb_replaywin = pfkey_sa->sadb_sa_replay; + tdbp->tdb_state = pfkey_sa->sadb_sa_state; + tdbp->tdb_flags = pfkey_sa->sadb_sa_flags; + tdbp->tdb_replaywin_lastseq = tdbp->tdb_replaywin_bitmap = 0; + + switch(tdbp->tdb_said.proto) { + case IPPROTO_AH: + tdbp->tdb_authalg = pfkey_sa->sadb_sa_auth; + tdbp->tdb_encalg = SADB_EALG_NONE; + break; + case IPPROTO_ESP: + tdbp->tdb_authalg = pfkey_sa->sadb_sa_auth; + tdbp->tdb_encalg = pfkey_sa->sadb_sa_encrypt; +#ifdef CONFIG_IPSEC_ALG + ipsec_alg_sa_init(tdbp); +#endif /* CONFIG_IPSEC_ALG */ + break; + case IPPROTO_IPIP: + tdbp->tdb_authalg = AH_NONE; + tdbp->tdb_encalg = ESP_NONE; + break; +#ifdef CONFIG_IPSEC_IPCOMP + case IPPROTO_COMP: + tdbp->tdb_authalg = AH_NONE; + tdbp->tdb_encalg = pfkey_sa->sadb_sa_encrypt; + break; +#endif /* CONFIG_IPSEC_IPCOMP */ + case IPPROTO_INT: + tdbp->tdb_authalg = AH_NONE; + tdbp->tdb_encalg = ESP_NONE; + break; + case 0: + break; + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sa_process: " + "unknown proto=%d.\n", + tdbp->tdb_said.proto); + SENDERR(EINVAL); + } + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_lifetime_process: .\n"); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_lifetime_process: " + "extr or extr->tdb is NULL, fatal\n"); + SENDERR(EINVAL); + } + + switch(pfkey_lifetime->sadb_lifetime_exttype) { + case SADB_EXT_LIFETIME_CURRENT: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_lifetime_process: " + "lifetime_current not supported yet.\n"); + SENDERR(EINVAL); + break; + case SADB_EXT_LIFETIME_HARD: + ipsec_lifetime_update_hard(&extr->tdb->ips_life.ipl_allocations, + pfkey_lifetime->sadb_lifetime_allocations); + + ipsec_lifetime_update_hard(&extr->tdb->ips_life.ipl_bytes, + pfkey_lifetime->sadb_lifetime_bytes); + + ipsec_lifetime_update_hard(&extr->tdb->ips_life.ipl_addtime, + pfkey_lifetime->sadb_lifetime_addtime); + + ipsec_lifetime_update_hard(&extr->tdb->ips_life.ipl_usetime, + pfkey_lifetime->sadb_lifetime_usetime); + + break; + + case SADB_EXT_LIFETIME_SOFT: + ipsec_lifetime_update_soft(&extr->tdb->ips_life.ipl_allocations, + pfkey_lifetime->sadb_lifetime_allocations); + + ipsec_lifetime_update_soft(&extr->tdb->ips_life.ipl_bytes, + pfkey_lifetime->sadb_lifetime_bytes); + + ipsec_lifetime_update_soft(&extr->tdb->ips_life.ipl_addtime, + pfkey_lifetime->sadb_lifetime_addtime); + + ipsec_lifetime_update_soft(&extr->tdb->ips_life.ipl_usetime, + pfkey_lifetime->sadb_lifetime_usetime); + + break; + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_lifetime_process: " + "invalid exttype=%d.\n", + pfkey_ext->sadb_ext_type); + SENDERR(EINVAL); + } + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + int saddr_len = 0; + char ipaddr_txt[ADDRTOA_BUF]; + unsigned char **sap; + unsigned short * portp = 0; + struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext; + struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address)); + struct ipsec_sa* tdbp; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process:\n"); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "extr or extr->tdb is NULL, fatal\n"); + SENDERR(EINVAL); + } + + switch(s->sa_family) { + case AF_INET: + saddr_len = sizeof(struct sockaddr_in); + addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt)); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found address family=%d, AF_INET, %s.\n", + s->sa_family, + ipaddr_txt); + break; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + case AF_INET6: + saddr_len = sizeof(struct sockaddr_in6); + break; +#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */ + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "s->sa_family=%d not supported.\n", + s->sa_family); + SENDERR(EPFNOSUPPORT); + } + + switch(pfkey_address->sadb_address_exttype) { + case SADB_EXT_ADDRESS_SRC: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found src address.\n"); + sap = (unsigned char **)&(extr->tdb->tdb_addr_s); + extr->tdb->tdb_addr_s_size = saddr_len; + break; + case SADB_EXT_ADDRESS_DST: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found dst address.\n"); + sap = (unsigned char **)&(extr->tdb->tdb_addr_d); + extr->tdb->tdb_addr_d_size = saddr_len; + break; + case SADB_EXT_ADDRESS_PROXY: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found proxy address.\n"); + sap = (unsigned char **)&(extr->tdb->tdb_addr_p); + extr->tdb->tdb_addr_p_size = saddr_len; + break; + case SADB_X_EXT_ADDRESS_DST2: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found 2nd dst address.\n"); + if(pfkey_alloc_ipsec_sa(&(extr->tdb2)) == ENOMEM) { + SENDERR(ENOMEM); + } + sap = (unsigned char **)&(extr->tdb2->tdb_addr_d); + extr->tdb2->tdb_addr_d_size = saddr_len; + break; + case SADB_X_EXT_ADDRESS_SRC_FLOW: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found src flow address.\n"); + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { + SENDERR(ENOMEM); + } + sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src); + portp = &(extr->eroute->er_eaddr.sen_sport); + break; + case SADB_X_EXT_ADDRESS_DST_FLOW: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found dst flow address.\n"); + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { + SENDERR(ENOMEM); + } + sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst); + portp = &(extr->eroute->er_eaddr.sen_dport); + break; + case SADB_X_EXT_ADDRESS_SRC_MASK: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found src mask address.\n"); + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { + SENDERR(ENOMEM); + } + sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src); + portp = &(extr->eroute->er_emask.sen_sport); + break; + case SADB_X_EXT_ADDRESS_DST_MASK: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found dst mask address.\n"); + if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) { + SENDERR(ENOMEM); + } + sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst); + portp = &(extr->eroute->er_emask.sen_dport); + break; +#ifdef NAT_TRAVERSAL + case SADB_X_EXT_NAT_T_OA: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "found NAT-OA address.\n"); + sap = (unsigned char **)&(extr->tdb->ips_natt_oa); + extr->tdb->ips_natt_oa_size = saddr_len; + break; +#endif + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "unrecognised ext_type=%d.\n", + pfkey_address->sadb_address_exttype); + SENDERR(EINVAL); + } + + switch(pfkey_address->sadb_address_exttype) { + case SADB_EXT_ADDRESS_SRC: + case SADB_EXT_ADDRESS_DST: + case SADB_EXT_ADDRESS_PROXY: + case SADB_X_EXT_ADDRESS_DST2: +#ifdef NAT_TRAVERSAL + case SADB_X_EXT_NAT_T_OA: +#endif + if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) { + SENDERR(ENOMEM); + } + memcpy(*sap, s, saddr_len); + break; + default: + if(s->sa_family != AF_INET) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "s->sa_family=%d not supported.\n", + s->sa_family); + SENDERR(EPFNOSUPPORT); + } + (unsigned int)(*sap) = ((struct sockaddr_in*)s)->sin_addr.s_addr; + if (portp != 0) + *portp = ((struct sockaddr_in*)s)->sin_port; +#ifdef CONFIG_IPSEC_DEBUG + if(extr->eroute) { + char buf1[64], buf2[64]; + if (debug_pfkey) { + subnettoa(extr->eroute->er_eaddr.sen_ip_src, + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); + subnettoa(extr->eroute->er_eaddr.sen_ip_dst, + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_parse: " + "extr->eroute set to %s:%d->%s:%d\n", + buf1, + ntohs(extr->eroute->er_eaddr.sen_sport), + buf2, + ntohs(extr->eroute->er_eaddr.sen_dport)); + } + } +#endif /* CONFIG_IPSEC_DEBUG */ + } + + tdbp = extr->tdb; + switch(pfkey_address->sadb_address_exttype) { + case SADB_X_EXT_ADDRESS_DST2: + tdbp = extr->tdb2; + case SADB_EXT_ADDRESS_DST: + if(s->sa_family == AF_INET) { + tdbp->tdb_said.dst.s_addr = ((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr.s_addr; + addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr, + 0, + ipaddr_txt, + sizeof(ipaddr_txt)); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "tdb_said.dst set to %s.\n", + ipaddr_txt); + } else { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: " + "uh, tdb_said.dst doesn't do address family=%d yet, said will be invalid.\n", + s->sa_family); + } + default: + } + + /* XXX check if port!=0 */ + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_address_process: successful.\n"); + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_key_process: .\n"); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_key_process: " + "extr or extr->tdb is NULL, fatal\n"); + SENDERR(EINVAL); + } + + switch(pfkey_key->sadb_key_exttype) { + case SADB_EXT_KEY_AUTH: + if(!(extr->tdb->tdb_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_key_process: " + "memory allocation error.\n"); + SENDERR(ENOMEM); + } + extr->tdb->tdb_key_bits_a = pfkey_key->sadb_key_bits; + extr->tdb->tdb_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8); + memcpy(extr->tdb->tdb_key_a, + (char*)pfkey_key + sizeof(struct sadb_key), + extr->tdb->tdb_key_a_size); + break; + case SADB_EXT_KEY_ENCRYPT: /* Key(s) */ + if(!(extr->tdb->tdb_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_key_process: " + "memory allocation error.\n"); + SENDERR(ENOMEM); + } + extr->tdb->tdb_key_bits_e = pfkey_key->sadb_key_bits; + extr->tdb->tdb_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8); + memcpy(extr->tdb->tdb_key_e, + (char*)pfkey_key + sizeof(struct sadb_key), + extr->tdb->tdb_key_e_size); + break; + default: + SENDERR(EINVAL); + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_key_process: " + "success.\n"); +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext; + int data_len; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ident_process: .\n"); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ident_process: " + "extr or extr->tdb is NULL, fatal\n"); + SENDERR(EINVAL); + } + + switch(pfkey_ident->sadb_ident_exttype) { + case SADB_EXT_IDENTITY_SRC: + data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); + + extr->tdb->tdb_ident_s.type = pfkey_ident->sadb_ident_type; + extr->tdb->tdb_ident_s.id = pfkey_ident->sadb_ident_id; + extr->tdb->tdb_ident_s.len = pfkey_ident->sadb_ident_len; + if(data_len) { + if(!(extr->tdb->tdb_ident_s.data + = kmalloc(data_len, GFP_KERNEL))) { + SENDERR(ENOMEM); + } + memcpy(extr->tdb->tdb_ident_s.data, + (char*)pfkey_ident + sizeof(struct sadb_ident), + data_len); + } else { + extr->tdb->tdb_ident_s.data = NULL; + } + break; + case SADB_EXT_IDENTITY_DST: /* Identity(ies) */ + data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident); + + extr->tdb->tdb_ident_d.type = pfkey_ident->sadb_ident_type; + extr->tdb->tdb_ident_d.id = pfkey_ident->sadb_ident_id; + extr->tdb->tdb_ident_d.len = pfkey_ident->sadb_ident_len; + if(data_len) { + if(!(extr->tdb->tdb_ident_d.data + = kmalloc(data_len, GFP_KERNEL))) { + SENDERR(ENOMEM); + } + memcpy(extr->tdb->tdb_ident_d.data, + (char*)pfkey_ident + sizeof(struct sadb_ident), + data_len); + } else { + extr->tdb->tdb_ident_d.data = NULL; + } + break; + default: + SENDERR(EINVAL); + } +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_sens_process: " + "Sorry, I can't process exttype=%d yet.\n", + pfkey_ext->sadb_ext_type); + SENDERR(EINVAL); /* don't process these yet */ + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_prop_process: " + "Sorry, I can't process exttype=%d yet.\n", + pfkey_ext->sadb_ext_type); + SENDERR(EINVAL); /* don't process these yet */ + + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_supported_process: " + "Sorry, I can't process exttype=%d yet.\n", + pfkey_ext->sadb_ext_type); + SENDERR(EINVAL); /* don't process these yet */ + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_spirange_process: .\n"); +/* errlab: */ + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_kmprivate_process: " + "Sorry, I can't process exttype=%d yet.\n", + pfkey_ext->sadb_ext_type); + SENDERR(EINVAL); /* don't process these yet */ + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_satype_process: .\n"); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_satype_process: " + "extr or extr->tdb is NULL, fatal\n"); + SENDERR(EINVAL); + } + + if(pfkey_alloc_ipsec_sa(&(extr->tdb2)) == ENOMEM) { + SENDERR(ENOMEM); + } + if(!(extr->tdb2->tdb_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_satype_process: " + "proto lookup from satype=%d failed.\n", + pfkey_x_satype->sadb_x_satype_satype); + SENDERR(EINVAL); + } + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_satype_process: " + "protocol==%d decoded from satype==%d(%s).\n", + extr->tdb2->tdb_said.proto, + pfkey_x_satype->sadb_x_satype_satype, + satype2name(pfkey_x_satype->sadb_x_satype_satype)); + +errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext; + + if(!pfkey_x_debug) { + printk("klips_debug:pfkey_x_debug_process: " + "null pointer passed in\n"); + SENDERR(EINVAL); + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_debug_process: .\n"); + +#ifdef CONFIG_IPSEC_DEBUG + if(pfkey_x_debug->sadb_x_debug_netlink >> + (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) { + pfkey_x_debug->sadb_x_debug_netlink &= + ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1)); + debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel; + debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink; + debug_xform |= pfkey_x_debug->sadb_x_debug_xform; + debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute; + debug_spi |= pfkey_x_debug->sadb_x_debug_spi; + debug_radij |= pfkey_x_debug->sadb_x_debug_radij; + debug_esp |= pfkey_x_debug->sadb_x_debug_esp; + debug_ah |= pfkey_x_debug->sadb_x_debug_ah; + debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv; + debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey; +#ifdef CONFIG_IPSEC_IPCOMP + sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp; +#endif /* CONFIG_IPSEC_IPCOMP */ + sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose; + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_debug_process: " + "set\n"); + } else { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_debug_process: " + "unset\n"); + debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel; + debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink; + debug_xform &= pfkey_x_debug->sadb_x_debug_xform; + debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute; + debug_spi &= pfkey_x_debug->sadb_x_debug_spi; + debug_radij &= pfkey_x_debug->sadb_x_debug_radij; + debug_esp &= pfkey_x_debug->sadb_x_debug_esp; + debug_ah &= pfkey_x_debug->sadb_x_debug_ah; + debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv; + debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey; +#ifdef CONFIG_IPSEC_IPCOMP + sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp; +#endif /* CONFIG_IPSEC_IPCOMP */ + sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose; + } +#else /* CONFIG_IPSEC_DEBUG */ + printk("klips_debug:pfkey_x_debug_process: " + "debugging not enabled\n"); + SENDERR(EINVAL); +#endif /* CONFIG_IPSEC_DEBUG */ + +errlab: + return error; +} + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL +DEBUG_NO_STATIC int +pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext; + + if(!pfkey_x_nat_t_type) { + printk("klips_debug:pfkey_x_nat_t_type_process: " + "null pointer passed in\n"); + SENDERR(EINVAL); + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_nat_t_type_process: %d.\n", + pfkey_x_nat_t_type->sadb_x_nat_t_type_type); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_nat_t_type_process: " + "extr or extr->tdb is NULL, fatal\n"); + SENDERR(EINVAL); + } + + switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) { + case ESPINUDP_WITH_NON_IKE: /* with Non-IKE */ + case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */ + extr->tdb->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type; + break; + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_nat_t_type_process: " + "unknown type %d.\n", + pfkey_x_nat_t_type->sadb_x_nat_t_type_type); + SENDERR(EINVAL); + break; + } + +errlab: + return error; +} +DEBUG_NO_STATIC int +pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext; + + if(!pfkey_x_nat_t_port) { + printk("klips_debug:pfkey_x_nat_t_port_process: " + "null pointer passed in\n"); + SENDERR(EINVAL); + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n", + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype, + pfkey_x_nat_t_port->sadb_x_nat_t_port_port); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_nat_t_type_process: " + "extr or extr->tdb is NULL, fatal\n"); + SENDERR(EINVAL); + } + + switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) { + case SADB_X_EXT_NAT_T_SPORT: + extr->tdb->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port; + break; + case SADB_X_EXT_NAT_T_DPORT: + extr->tdb->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port; + break; + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_nat_t_port_process: " + "unknown exttype %d.\n", + pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype); + SENDERR(EINVAL); + break; + } + +errlab: + return error; +} +#endif + +DEBUG_NO_STATIC int +pfkey_x_protocol_process(struct sadb_ext *pfkey_ext, + struct pfkey_extracted_data *extr) +{ + int error = 0; + struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext; + + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr); + + if (extr == 0) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_protocol_process:" + "extr is NULL, fatal\n"); + SENDERR(EINVAL); + } + if (extr->eroute == 0) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_protocol_process:" + "extr->eroute is NULL, fatal\n"); + SENDERR(EINVAL); + } + extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto; + extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0; + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_protocol_process: protocol = %d.\n", + p->sadb_protocol_proto); + errlab: + return error; +} + + +DEBUG_NO_STATIC int +pfkey_ipsec_sa_init(struct ipsec_sa *tdbp, struct sadb_ext **extensions) +{ + int error = 0; + char sa[SATOA_BUF]; + size_t sa_len; + char ipaddr_txt[ADDRTOA_BUF]; + char ipaddr2_txt[ADDRTOA_BUF]; +#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1) + int i; + unsigned char kb[AHMD596_BLKLEN]; +#endif +#ifdef CONFIG_IPSEC_ALG + struct ipsec_alg_enc *ixt_e = NULL; + struct ipsec_alg_auth *ixt_a = NULL; +#endif /* CONFIG_IPSEC_ALG */ + + if(!tdbp) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "tdbp is NULL, fatal\n"); + SENDERR(EINVAL); + } + + sa_len = satoa(tdbp->tdb_said, 0, sa, SATOA_BUF); + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "(pfkey defined) called for SA:%s\n", + sa_len ? sa : " (error)"); + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "calling init routine of %s%s%s\n", + IPS_XFORM_NAME(tdbp)); + + switch(tdbp->tdb_said.proto) { + +#ifdef CONFIG_IPSEC_IPIP + case IPPROTO_IPIP: { + addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_s))->sin_addr, + 0, + ipaddr_txt, sizeof(ipaddr_txt)); + addrtoa(((struct sockaddr_in*)(tdbp->tdb_addr_d))->sin_addr, + 0, + ipaddr2_txt, sizeof(ipaddr_txt)); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "(pfkey defined) IPIP tdb set for %s->%s.\n", + ipaddr_txt, + ipaddr2_txt); + } + break; +#endif /* !CONFIG_IPSEC_IPIP */ +#ifdef CONFIG_IPSEC_AH + case IPPROTO_AH: + switch(tdbp->tdb_authalg) { +# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case AH_MD5: { + unsigned char *akp; + unsigned int aks; + MD5_CTX *ictx; + MD5_CTX *octx; + + if(tdbp->tdb_key_bits_a != (AHMD596_KLEN * 8)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, + tdbp->tdb_key_bits_a, AHMD596_KLEN * 8); + SENDERR(EINVAL); + } + +# if 0 /* we don't really want to print these unless there are really big problems */ + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_ipsec_sa_init: " + "hmac md5-96 key is 0x%08x %08x %08x %08x\n", + ntohl(*(((__u32 *)tdbp->tdb_key_a)+0)), + ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)), + ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)), + ntohl(*(((__u32 *)tdbp->tdb_key_a)+3))); +# endif + + tdbp->tdb_auth_bits = AHMD596_ALEN * 8; + + /* save the pointer to the key material */ + akp = tdbp->tdb_key_a; + aks = tdbp->tdb_key_a_size; + + if((tdbp->tdb_key_a = (caddr_t) + kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { + tdbp->tdb_key_a = akp; + SENDERR(ENOMEM); + } + tdbp->tdb_key_a_size = sizeof(struct md5_ctx); + + for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) { + kb[i] = akp[i] ^ HMAC_IPAD; + } + for (; i < AHMD596_BLKLEN; i++) { + kb[i] = HMAC_IPAD; + } + + ictx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->ictx); + MD5Init(ictx); + MD5Update(ictx, kb, AHMD596_BLKLEN); + + for (i = 0; i < AHMD596_BLKLEN; i++) { + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); + } + + octx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->octx); + MD5Init(octx); + MD5Update(octx, kb, AHMD596_BLKLEN); + +# if 0 /* we don't really want to print these unless there are really big problems */ + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_ipsec_sa_init: " + "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", + ((__u32*)ictx)[0], + ((__u32*)ictx)[1], + ((__u32*)ictx)[2], + ((__u32*)ictx)[3], + ((__u32*)octx)[0], + ((__u32*)octx)[1], + ((__u32*)octx)[2], + ((__u32*)octx)[3] ); +# endif + + /* zero key buffer -- paranoid */ + memset(akp, 0, aks); + kfree(akp); + } + break; +# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + case AH_SHA: { + unsigned char *akp; + unsigned int aks; + SHA1_CTX *ictx; + SHA1_CTX *octx; + + if(tdbp->tdb_key_bits_a != (AHSHA196_KLEN * 8)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, + tdbp->tdb_key_bits_a, AHSHA196_KLEN * 8); + SENDERR(EINVAL); + } + +# if 0 /* we don't really want to print these unless there are really big problems */ + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_ipsec_sa_init: " + "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", + ntohl(*(((__u32 *)tdbp->tdb_key_a)+0)), + ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)), + ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)), + ntohl(*(((__u32 *)tdbp->tdb_key_a)+3))); +# endif + + tdbp->tdb_auth_bits = AHSHA196_ALEN * 8; + + /* save the pointer to the key material */ + akp = tdbp->tdb_key_a; + aks = tdbp->tdb_key_a_size; + + if((tdbp->tdb_key_a = (caddr_t) + kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { + tdbp->tdb_key_a = akp; + SENDERR(ENOMEM); + } + tdbp->tdb_key_a_size = sizeof(struct sha1_ctx); + + for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) { + kb[i] = akp[i] ^ HMAC_IPAD; + } + for (; i < AHMD596_BLKLEN; i++) { + kb[i] = HMAC_IPAD; + } + + ictx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx); + SHA1Init(ictx); + SHA1Update(ictx, kb, AHSHA196_BLKLEN); + + for (i = 0; i < AHSHA196_BLKLEN; i++) { + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); + } + + octx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->octx); + SHA1Init(octx); + SHA1Update(octx, kb, AHSHA196_BLKLEN); + +# if 0 /* we don't really want to print these unless there are really big problems */ + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_ipsec_sa_init: " + "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", + ((__u32*)ictx)[0], + ((__u32*)ictx)[1], + ((__u32*)ictx)[2], + ((__u32*)ictx)[3], + ((__u32*)octx)[0], + ((__u32*)octx)[1], + ((__u32*)octx)[2], + ((__u32*)octx)[3] ); +# endif + /* zero key buffer -- paranoid */ + memset(akp, 0, aks); + kfree(akp); + } + break; +# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "authalg=%d support not available in the kernel", + tdbp->tdb_authalg); + SENDERR(EINVAL); + } + break; +#endif /* CONFIG_IPSEC_AH */ +#ifdef CONFIG_IPSEC_ESP + case IPPROTO_ESP: { +#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1) + unsigned char *akp; + unsigned int aks; +#endif +#if defined (CONFIG_IPSEC_ENC_3DES) + unsigned char *ekp; + unsigned int eks; +#endif + + tdbp->tdb_iv_size = 0; +#ifdef CONFIG_IPSEC_ALG + if ((ixt_e=IPSEC_ALG_SA_ESP_ENC(tdbp))) { + tdbp->tdb_iv_size = ixt_e->ixt_ivlen/8; + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_encalg) { +# ifdef CONFIG_IPSEC_ENC_3DES + case ESP_3DES: +# endif /* CONFIG_IPSEC_ENC_3DES */ +# if defined(CONFIG_IPSEC_ENC_3DES) + tdbp->tdb_iv_size = EMT_ESPDES_IV_SZ; +# endif /* defined(CONFIG_IPSEC_ENC_3DES) */ + case ESP_NONE: + break; + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "encalg=%d support not available in the kernel", + tdbp->tdb_encalg); + SENDERR(EINVAL); + } + + /* Create IV */ + if (tdbp->tdb_iv_size) { + if((tdbp->tdb_iv = (caddr_t) + kmalloc(tdbp->tdb_iv_size, GFP_ATOMIC)) == NULL) { + SENDERR(ENOMEM); + } + get_random_bytes((void *)tdbp->tdb_iv, tdbp->tdb_iv_size); + tdbp->tdb_iv_bits = tdbp->tdb_iv_size * 8; + } + +#ifdef CONFIG_IPSEC_ALG + if (ixt_e) { + if ((error=ipsec_alg_enc_key_create(tdbp)) < 0) + SENDERR(-error); + } else +#endif /* CONFIG_IPSEC_ALG */ + switch(tdbp->tdb_encalg) { +# ifdef CONFIG_IPSEC_ENC_3DES + case ESP_3DES: + if(tdbp->tdb_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, + tdbp->tdb_key_bits_e, EMT_ESP3DES_KEY_SZ * 8); + SENDERR(EINVAL); + } + + /* save encryption key pointer */ + ekp = tdbp->tdb_key_e; + eks = tdbp->tdb_key_e_size; + + if((tdbp->tdb_key_e = (caddr_t) + kmalloc(3 * sizeof(struct des_eks), GFP_ATOMIC)) == NULL) { + tdbp->tdb_key_e = ekp; + SENDERR(ENOMEM); + } + tdbp->tdb_key_e_size = 3 * sizeof(struct des_eks); + + for(i = 0; i < 3; i++) { +#if KLIPS_DIVULGE_CYPHER_KEY + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_ipsec_sa_init: " + "3des key %d/3 is 0x%08x%08x\n", + i + 1, + ntohl(*((__u32 *)ekp + i * 2)), + ntohl(*((__u32 *)ekp + i * 2 + 1))); +# endif +#if KLIPS_FIXES_DES_PARITY + /* force parity */ + des_set_odd_parity((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i)); +#endif + error = des_set_key((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i), + ((struct des_eks *)(tdbp->tdb_key_e))[i].ks); + if (error == -1) + printk("klips_debug:pfkey_ipsec_sa_init: " + "parity error in des key %d/3\n", + i + 1); + else if (error == -2) + printk("klips_debug:pfkey_ipsec_sa_init: " + "illegal weak des key %d/3\n", i + 1); + if (error) { + memset(ekp, 0, eks); + kfree(ekp); + SENDERR(EINVAL); + } + } + + /* paranoid */ + memset(ekp, 0, eks); + kfree(ekp); + break; +# endif /* CONFIG_IPSEC_ENC_3DES */ + case ESP_NONE: + break; + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "encalg=%d support not available in the kernel", + tdbp->tdb_encalg); + SENDERR(EINVAL); + } + +#ifdef CONFIG_IPSEC_ALG + if ((ixt_a=IPSEC_ALG_SA_ESP_AUTH(tdbp))) { + if ((error=ipsec_alg_auth_key_create(tdbp)) < 0) + SENDERR(-error); + } else +#endif /* CONFIG_IPSEC_ALG */ + + switch(tdbp->tdb_authalg) { +# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5 + case AH_MD5: { + MD5_CTX *ictx; + MD5_CTX *octx; + + if(tdbp->tdb_key_bits_a != (AHMD596_KLEN * 8)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, + tdbp->tdb_key_bits_a, + AHMD596_KLEN * 8); + SENDERR(EINVAL); + } + +# if 0 /* we don't really want to print these unless there are really big problems */ + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_ipsec_sa_init: " + "hmac md5-96 key is 0x%08x %08x %08x %08x\n", + ntohl(*(((__u32 *)(tdbp->tdb_key_a))+0)), + ntohl(*(((__u32 *)(tdbp->tdb_key_a))+1)), + ntohl(*(((__u32 *)(tdbp->tdb_key_a))+2)), + ntohl(*(((__u32 *)(tdbp->tdb_key_a))+3))); +# endif + tdbp->tdb_auth_bits = AHMD596_ALEN * 8; + + /* save the pointer to the key material */ + akp = tdbp->tdb_key_a; + aks = tdbp->tdb_key_a_size; + + if((tdbp->tdb_key_a = (caddr_t) + kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) { + tdbp->tdb_key_a = akp; + SENDERR(ENOMEM); + } + tdbp->tdb_key_a_size = sizeof(struct md5_ctx); + + for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) { + kb[i] = akp[i] ^ HMAC_IPAD; + } + for (; i < AHMD596_BLKLEN; i++) { + kb[i] = HMAC_IPAD; + } + + ictx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->ictx); + MD5Init(ictx); + MD5Update(ictx, kb, AHMD596_BLKLEN); + + for (i = 0; i < AHMD596_BLKLEN; i++) { + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); + } + + octx = &(((struct md5_ctx*)(tdbp->tdb_key_a))->octx); + MD5Init(octx); + MD5Update(octx, kb, AHMD596_BLKLEN); + +# if 0 /* we don't really want to print these unless there are really big problems */ + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_ipsec_sa_init: " + "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", + ((__u32*)ictx)[0], + ((__u32*)ictx)[1], + ((__u32*)ictx)[2], + ((__u32*)ictx)[3], + ((__u32*)octx)[0], + ((__u32*)octx)[1], + ((__u32*)octx)[2], + ((__u32*)octx)[3] ); +# endif + /* paranoid */ + memset(akp, 0, aks); + kfree(akp); + break; + } +# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */ +# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1 + case AH_SHA: { + SHA1_CTX *ictx; + SHA1_CTX *octx; + + if(tdbp->tdb_key_bits_a != (AHSHA196_KLEN * 8)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/, + tdbp->tdb_key_bits_a, + AHSHA196_KLEN * 8); + SENDERR(EINVAL); + } + +# if 0 /* we don't really want to print these unless there are really big problems */ + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_ipsec_sa_init: " + "hmac sha1-96 key is 0x%08x %08x %08x %08x\n", + ntohl(*(((__u32 *)tdbp->tdb_key_a)+0)), + ntohl(*(((__u32 *)tdbp->tdb_key_a)+1)), + ntohl(*(((__u32 *)tdbp->tdb_key_a)+2)), + ntohl(*(((__u32 *)tdbp->tdb_key_a)+3))); +# endif + tdbp->tdb_auth_bits = AHSHA196_ALEN * 8; + + /* save the pointer to the key material */ + akp = tdbp->tdb_key_a; + aks = tdbp->tdb_key_a_size; + + if((tdbp->tdb_key_a = (caddr_t) + kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) { + tdbp->tdb_key_a = akp; + SENDERR(ENOMEM); + } + tdbp->tdb_key_a_size = sizeof(struct sha1_ctx); + + for (i = 0; i < DIVUP(tdbp->tdb_key_bits_a, 8); i++) { + kb[i] = akp[i] ^ HMAC_IPAD; + } + for (; i < AHMD596_BLKLEN; i++) { + kb[i] = HMAC_IPAD; + } + + ictx = &(((struct sha1_ctx*)(tdbp->tdb_key_a))->ictx); + SHA1Init(ictx); + SHA1Update(ictx, kb, AHSHA196_BLKLEN); + + for (i = 0; i < AHSHA196_BLKLEN; i++) { + kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD); + } + + octx = &((struct sha1_ctx*)(tdbp->tdb_key_a))->octx; + SHA1Init(octx); + SHA1Update(octx, kb, AHSHA196_BLKLEN); + +# if 0 /* we don't really want to print these unless there are really big problems */ + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_ipsec_sa_init: " + "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n", + ((__u32*)ictx)[0], + ((__u32*)ictx)[1], + ((__u32*)ictx)[2], + ((__u32*)ictx)[3], + ((__u32*)octx)[0], + ((__u32*)octx)[1], + ((__u32*)octx)[2], + ((__u32*)octx)[3] ); +# endif + memset(akp, 0, aks); + kfree(akp); + break; + } +# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */ + case AH_NONE: + break; + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "authalg=%d support not available in the kernel.\n", + tdbp->tdb_authalg); + SENDERR(EINVAL); + } + } + break; +#endif /* !CONFIG_IPSEC_ESP */ +#ifdef CONFIG_IPSEC_IPCOMP + case IPPROTO_COMP: + tdbp->tdb_comp_adapt_tries = 0; + tdbp->tdb_comp_adapt_skip = 0; + tdbp->tdb_comp_ratio_cbytes = 0; + tdbp->tdb_comp_ratio_dbytes = 0; + break; +#endif /* CONFIG_IPSEC_IPCOMP */ + default: + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_ipsec_sa_init: " + "proto=%d unknown.\n", + tdbp->tdb_said.proto); + SENDERR(EINVAL); + } + + errlab: + return(error); +} + + +int +pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1]) +{ + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: " + "error=%d\n", + error); + if (!error) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" + "success.\n"); + return 1; + } else { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:" + "caught error %d\n", + error); + pfkey_extensions_free(extensions); + return 0; + } +} + + +DEBUG_NO_STATIC int +pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L); + int found_avail = 0; + struct ipsec_sa *tdbq; + char sa[SATOA_BUF]; + size_t sa_len; + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_reply = NULL; + struct socket_list *pfkey_socketsp; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_getspi_parse: .\n"); + + pfkey_extensions_init(extensions_reply); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_getspi_parse: " + "error, extr or extr->tdb pointer NULL\n"); + SENDERR(EINVAL); + } + + if(extensions[SADB_EXT_SPIRANGE]) { + minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min; + maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max; + } + + if(maxspi == minspi) { + extr->tdb->tdb_said.spi = maxspi; + if((tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said)))) { + sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_getspi_parse: " + "EMT_GETSPI found an old Tunnel Descriptor Block for SA: %s, delete it first.\n", + sa_len ? sa : " (error)"); + SENDERR(EEXIST); + } else { + found_avail = 1; + } + } else { + int i = 0; + __u32 rand_val; + __u32 spi_diff; + while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) { + get_random_bytes((void*) &(rand_val), + /* sizeof(extr->tdb->tdb_said.spi) */ + ( (spi_diff < (2^8)) ? 1 : + ( (spi_diff < (2^16)) ? 2 : + ( (spi_diff < (2^24)) ? 3 : + 4 ) ) ) ); + extr->tdb->tdb_said.spi = htonl(ntohl(minspi) + + (rand_val % + (spi_diff + 1))); + i++; + tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said)); + if(!tdbq) { + found_avail = 1; + } + } + } + + sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); + + if (!found_avail) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_getspi_parse: " + "found an old Tunnel Descriptor Block for SA: %s, delete it first.\n", + sa_len ? sa : " (error)"); + SENDERR(EEXIST); + } + + if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) { + extr->tdb->tdb_flags |= EMT_INBOUND; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_getspi_parse: " + "existing Tunnel Descriptor Block not found (this is good) for SA: %s, %s-bound, allocating.\n", + sa_len ? sa : " (error)", + extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out"); + + + /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/ + extr->tdb->tdb_rcvif = NULL; + extr->tdb->ips_life.ipl_addtime.ipl_count = jiffies/HZ; + + extr->tdb->tdb_state = SADB_SASTATE_LARVAL; + + if(!extr->tdb->ips_life.ipl_allocations.ipl_count) { + extr->tdb->ips_life.ipl_allocations.ipl_count += 1; + } + + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], + SADB_GETSPI, + satype, + 0, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), + extensions_reply) + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA], + SADB_EXT_SA, + extr->tdb->tdb_said.spi, + 0, + SADB_SASTATE_LARVAL, + 0, + 0, + 0), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_s), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_d), + extensions_reply) )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " + "failed to build the getspi reply message extensions\n"); + goto errlab; + } + + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " + "failed to build the getspi reply message\n"); + SENDERR(-error); + } + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " + "sending up getspi reply message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " + "sending up getspi reply message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + + if((error = ipsec_sa_put(extr->tdb))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: " + "failed to add the larval SA=%s with error=%d.\n", + sa_len ? sa : " (error)", + error); + SENDERR(-error); + } + extr->tdb = NULL; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_getspi_parse: " + "successful for SA: %s\n", + sa_len ? sa : " (error)"); + + errlab: + if (pfkey_reply) { + pfkey_msg_free(&pfkey_reply); + } + pfkey_extensions_free(extensions_reply); + return error; +} + +DEBUG_NO_STATIC int +pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct ipsec_sa* tdbq; + char sa[SATOA_BUF]; + size_t sa_len; + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_reply = NULL; + struct socket_list *pfkey_socketsp; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + struct ipsec_sa *nat_t_tdb_saved = NULL; +#endif + + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse: .\n"); + + pfkey_extensions_init(extensions_reply); + + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse: " + "error, sa_state=%d must be MATURE=%d\n", + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, + SADB_SASTATE_MATURE); + SENDERR(EINVAL); + } + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse: " + "error, extr or extr->tdb pointer NULL\n"); + SENDERR(EINVAL); + } + + sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); + + spin_lock_bh(&tdb_lock); + + tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said)); + if (!tdbq) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse: " + "reserved Tunnel Descriptor Block for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n", + sa_len ? sa : " (error)"); + SENDERR(ENOENT); + } + + if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) { + extr->tdb->tdb_flags |= EMT_INBOUND; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse: " + "existing Tunnel Descriptor Block found (this is good) for SA: %s, %s-bound, updating.\n", + sa_len ? sa : " (error)", + extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out"); + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if (extr->tdb->ips_natt_sport || extr->tdb->ips_natt_dport) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse: only updating NAT-T ports " + "(%u:%u -> %u:%u)\n", + tdbq->ips_natt_sport, tdbq->ips_natt_dport, + extr->tdb->ips_natt_sport, extr->tdb->ips_natt_dport); + + if (extr->tdb->ips_natt_sport) { + tdbq->ips_natt_sport = extr->tdb->ips_natt_sport; + if (tdbq->ips_addr_s->sa_family == AF_INET) { + ((struct sockaddr_in *)(tdbq->ips_addr_s))->sin_port = htons(extr->tdb->ips_natt_sport); + } + } + + if (extr->tdb->ips_natt_dport) { + tdbq->ips_natt_dport = extr->tdb->ips_natt_dport; + if (tdbq->ips_addr_d->sa_family == AF_INET) { + ((struct sockaddr_in *)(tdbq->ips_addr_d))->sin_port = htons(extr->tdb->ips_natt_dport); + } + } + + nat_t_tdb_saved = extr->tdb; + extr->tdb = tdbq; + } + else { +#endif + + + /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/ + extr->tdb->tdb_rcvif = NULL; + if ((error = pfkey_ipsec_sa_init(extr->tdb, extensions))) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse: " + "not successful for SA: %s, deleting.\n", + sa_len ? sa : " (error)"); + SENDERR(-error); + } + + extr->tdb->ips_life.ipl_addtime.ipl_count = tdbq->ips_life.ipl_addtime.ipl_count; + if((error = ipsec_sa_delchain(tdbq))) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse: " + "error=%d, trouble deleting intermediate tdb for SA=%s.\n", + error, + sa_len ? sa : " (error)"); + SENDERR(-error); + } +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + } +#endif + + spin_unlock_bh(&tdb_lock); + + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], + SADB_UPDATE, + satype, + 0, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), + extensions_reply) + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA], + SADB_EXT_SA, + extr->tdb->tdb_said.spi, + extr->tdb->tdb_replaywin, + extr->tdb->tdb_state, + extr->tdb->tdb_authalg, + extr->tdb->tdb_encalg, + extr->tdb->tdb_flags), + extensions_reply) + /* The 3 lifetime extentions should only be sent if non-zero. */ + && (extensions[SADB_EXT_LIFETIME_HARD] + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], + SADB_EXT_LIFETIME_HARD, + extr->tdb->ips_life.ipl_allocations.ipl_hard, + extr->tdb->ips_life.ipl_bytes.ipl_hard, + extr->tdb->ips_life.ipl_addtime.ipl_hard, + extr->tdb->ips_life.ipl_usetime.ipl_hard, + extr->tdb->ips_life.ipl_packets.ipl_hard), + extensions_reply) : 1) + && (extensions[SADB_EXT_LIFETIME_SOFT] + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], + SADB_EXT_LIFETIME_SOFT, + extr->tdb->ips_life.ipl_allocations.ipl_count, + extr->tdb->ips_life.ipl_bytes.ipl_count, + extr->tdb->ips_life.ipl_addtime.ipl_count, + extr->tdb->ips_life.ipl_usetime.ipl_count, + extr->tdb->ips_life.ipl_packets.ipl_count), + extensions_reply) : 1) + && (extr->tdb->ips_life.ipl_allocations.ipl_count + || extr->tdb->ips_life.ipl_bytes.ipl_count + || extr->tdb->ips_life.ipl_addtime.ipl_count + || extr->tdb->ips_life.ipl_usetime.ipl_count + || extr->tdb->ips_life.ipl_packets.ipl_count + + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], + SADB_EXT_LIFETIME_CURRENT, + extr->tdb->ips_life.ipl_allocations.ipl_count, + extr->tdb->ips_life.ipl_bytes.ipl_count, + extr->tdb->ips_life.ipl_addtime.ipl_count, + extr->tdb->ips_life.ipl_usetime.ipl_count, + extr->tdb->ips_life.ipl_packets.ipl_count), + extensions_reply) : 1) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_s), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_d), + extensions_reply) + && (extr->tdb->tdb_ident_s.data + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], + SADB_EXT_IDENTITY_SRC, + extr->tdb->tdb_ident_s.type, + extr->tdb->tdb_ident_s.id, + extr->tdb->tdb_ident_s.len, + extr->tdb->tdb_ident_s.data), + extensions_reply) : 1) + && (extr->tdb->tdb_ident_d.data + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], + SADB_EXT_IDENTITY_DST, + extr->tdb->tdb_ident_d.type, + extr->tdb->tdb_ident_d.id, + extr->tdb->tdb_ident_d.len, + extr->tdb->tdb_ident_d.data), + extensions_reply) : 1) +#if 0 + /* FIXME: This won't work yet because I have not finished + it. */ + && (extr->tdb->tdb_sens_ + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], + extr->tdb->tdb_sens_dpd, + extr->tdb->tdb_sens_sens_level, + extr->tdb->tdb_sens_sens_len, + extr->tdb->tdb_sens_sens_bitmap, + extr->tdb->tdb_sens_integ_level, + extr->tdb->tdb_sens_integ_len, + extr->tdb->tdb_sens_integ_bitmap), + extensions_reply) : 1) +#endif + )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " + "failed to build the update reply message extensions\n"); + SENDERR(-error); + } + + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " + "failed to build the update reply message\n"); + SENDERR(-error); + } + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " + "sending up update reply message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " + "sending up update reply message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if (nat_t_tdb_saved) { + /** + * As we _really_ update existing SA, we keep tdbq and need to delete + * parsed tdb (nat_t_tdb_saved, was extr->tdb). + * + * goto errlab with extr->tdb = nat_t_tdb_saved will free it. + */ + + extr->tdb = nat_t_tdb_saved; + + error = 0; + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse (NAT-T ports): " + "successful for SA: %s\n", + sa_len ? sa : " (error)"); + + goto errlab; + } +#endif + + if((error = ipsec_sa_put(extr->tdb))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: " + "failed to update the mature SA=%s with error=%d.\n", + sa_len ? sa : " (error)", + error); + SENDERR(-error); + } + extr->tdb = NULL; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_update_parse: " + "successful for SA: %s\n", + sa_len ? sa : " (error)"); + + errlab: + if (pfkey_reply) { + pfkey_msg_free(&pfkey_reply); + } + pfkey_extensions_free(extensions_reply); + return error; +} + +DEBUG_NO_STATIC int +pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct ipsec_sa* tdbq; + char sa[SATOA_BUF]; + size_t sa_len; + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_reply = NULL; + struct socket_list *pfkey_socketsp; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_add_parse: .\n"); + + pfkey_extensions_init(extensions_reply); + + if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_add_parse: " + "error, sa_state=%d must be MATURE=%d\n", + ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state, + SADB_SASTATE_MATURE); + SENDERR(EINVAL); + } + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_add_parse: " + "extr or extr->tdb pointer NULL\n"); + SENDERR(EINVAL); + } + + sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); + + tdbq = ipsec_sa_getbyid(&(extr->tdb->tdb_said)); + if (tdbq) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_add_parse: " + "found an old Tunnel Descriptor Block for SA%s, delete it first.\n", + sa_len ? sa : " (error)"); + SENDERR(EEXIST); + } + + if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) { + extr->tdb->tdb_flags |= EMT_INBOUND; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_add_parse: " + "existing Tunnel Descriptor Block not found (this is good) for SA%s, %s-bound, allocating.\n", + sa_len ? sa : " (error)", + extr->tdb->tdb_flags & EMT_INBOUND ? "in" : "out"); + + /* XXX extr->tdb->tdb_rcvif = &(enc_softc[em->em_if].enc_if);*/ + extr->tdb->tdb_rcvif = NULL; + + if ((error = pfkey_ipsec_sa_init(extr->tdb, extensions))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_add_parse: " + "not successful for SA: %s, deleting.\n", + sa_len ? sa : " (error)"); + SENDERR(-error); + } + + extr->tdb->ips_life.ipl_addtime.ipl_count = jiffies / HZ; + if(!extr->tdb->ips_life.ipl_allocations.ipl_count) { + extr->tdb->ips_life.ipl_allocations.ipl_count += 1; + } + + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], + SADB_ADD, + satype, + 0, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), + extensions_reply) + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA], + SADB_EXT_SA, + extr->tdb->tdb_said.spi, + extr->tdb->tdb_replaywin, + extr->tdb->tdb_state, + extr->tdb->tdb_authalg, + extr->tdb->tdb_encalg, + extr->tdb->tdb_flags), + extensions_reply) + /* The 3 lifetime extentions should only be sent if non-zero. */ + && (extensions[SADB_EXT_LIFETIME_HARD] + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], + SADB_EXT_LIFETIME_HARD, + extr->tdb->ips_life.ipl_allocations.ipl_hard, + extr->tdb->ips_life.ipl_bytes.ipl_hard, + extr->tdb->ips_life.ipl_addtime.ipl_hard, + extr->tdb->ips_life.ipl_usetime.ipl_hard, + extr->tdb->ips_life.ipl_packets.ipl_hard), + extensions_reply) : 1) + && (extensions[SADB_EXT_LIFETIME_SOFT] + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], + SADB_EXT_LIFETIME_SOFT, + extr->tdb->ips_life.ipl_allocations.ipl_soft, + extr->tdb->ips_life.ipl_bytes.ipl_soft, + extr->tdb->ips_life.ipl_addtime.ipl_soft, + extr->tdb->ips_life.ipl_usetime.ipl_soft, + extr->tdb->ips_life.ipl_packets.ipl_soft), + extensions_reply) : 1) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_s), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_d), + extensions_reply) + && (extr->tdb->tdb_ident_s.data + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], + SADB_EXT_IDENTITY_SRC, + extr->tdb->tdb_ident_s.type, + extr->tdb->tdb_ident_s.id, + extr->tdb->tdb_ident_s.len, + extr->tdb->tdb_ident_s.data), + extensions_reply) : 1) + && (extr->tdb->tdb_ident_d.data + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], + SADB_EXT_IDENTITY_DST, + extr->tdb->tdb_ident_d.type, + extr->tdb->tdb_ident_d.id, + extr->tdb->tdb_ident_d.len, + extr->tdb->tdb_ident_d.data), + extensions_reply) : 1) +#if 0 + /* FIXME: This won't work yet because I have not finished + it. */ + && (extr->tdb->tdb_sens_ + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], + extr->tdb->tdb_sens_dpd, + extr->tdb->tdb_sens_sens_level, + extr->tdb->tdb_sens_sens_len, + extr->tdb->tdb_sens_sens_bitmap, + extr->tdb->tdb_sens_integ_level, + extr->tdb->tdb_sens_integ_len, + extr->tdb->tdb_sens_integ_bitmap), + extensions_reply) : 1) +#endif + )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " + "failed to build the add reply message extensions\n"); + SENDERR(-error); + } + + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " + "failed to build the add reply message\n"); + SENDERR(-error); + } + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " + "sending up add reply message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " + "sending up add reply message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + + if((error = ipsec_sa_put(extr->tdb))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: " + "failed to add the mature SA=%s with error=%d.\n", + sa_len ? sa : " (error)", + error); + SENDERR(-error); + } + extr->tdb = NULL; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_add_parse: " + "successful for SA: %s\n", + sa_len ? sa : " (error)"); + + errlab: + if (pfkey_reply) { + pfkey_msg_free(&pfkey_reply); + } + pfkey_extensions_free(extensions_reply); + return error; +} + +DEBUG_NO_STATIC int +pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + struct ipsec_sa *tdbp; + char sa[SATOA_BUF]; + size_t sa_len; + int error = 0; + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_reply = NULL; + struct socket_list *pfkey_socketsp; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_delete_parse: .\n"); + + pfkey_extensions_init(extensions_reply); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_delete_parse: " + "extr or extr->tdb pointer NULL, fatal\n"); + SENDERR(EINVAL); + } + + sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); + + spin_lock_bh(&tdb_lock); + + tdbp = ipsec_sa_getbyid(&(extr->tdb->tdb_said)); + if (tdbp == NULL) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_delete_parse: " + "Tunnel Descriptor Block not found for SA:%s, could not delete.\n", + sa_len ? sa : " (error)"); + SENDERR(ESRCH); + } + + if((error = ipsec_sa_delchain(tdbp))) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_delete_parse: " + "error=%d returned trying to delete Tunnel Descriptor Block for SA:%s.\n", + error, + sa_len ? sa : " (error)"); + SENDERR(-error); + } + spin_unlock_bh(&tdb_lock); + + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], + SADB_DELETE, + satype, + 0, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), + extensions_reply) + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA], + SADB_EXT_SA, + extr->tdb->tdb_said.spi, + 0, + 0, + 0, + 0, + 0), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_s), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_d), + extensions_reply) + )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " + "failed to build the delete reply message extensions\n"); + SENDERR(-error); + } + + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " + "failed to build the delete reply message\n"); + SENDERR(-error); + } + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " + "sending up delete reply message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: " + "sending up delete reply message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + + errlab: + if (pfkey_reply) { + pfkey_msg_free(&pfkey_reply); + } + pfkey_extensions_free(extensions_reply); + return error; +} + +DEBUG_NO_STATIC int +pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct ipsec_sa *tdbp; + char sa[SATOA_BUF]; + size_t sa_len; + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_reply = NULL; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_get_parse: .\n"); + + pfkey_extensions_init(extensions_reply); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_get_parse: " + "extr or extr->tdb pointer NULL, fatal\n"); + SENDERR(EINVAL); + } + + sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); + + spin_lock_bh(&tdb_lock); + + tdbp = ipsec_sa_getbyid(&(extr->tdb->tdb_said)); + if (tdbp == NULL) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " + "Tunnel Descriptor Block not found for SA=%s, could not get.\n", + sa_len ? sa : " (error)"); + SENDERR(ESRCH); + } + + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], + SADB_GET, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype, + 0, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), + extensions_reply) + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA], + SADB_EXT_SA, + extr->tdb->tdb_said.spi, + extr->tdb->tdb_replaywin, + extr->tdb->tdb_state, + extr->tdb->tdb_authalg, + extr->tdb->tdb_encalg, + extr->tdb->tdb_flags), + extensions_reply) + /* The 3 lifetime extentions should only be sent if non-zero. */ + && (tdbp->ips_life.ipl_allocations.ipl_count + || tdbp->ips_life.ipl_bytes.ipl_count + || tdbp->ips_life.ipl_addtime.ipl_count + || tdbp->ips_life.ipl_usetime.ipl_count + || tdbp->ips_life.ipl_packets.ipl_count + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT], + SADB_EXT_LIFETIME_CURRENT, + tdbp->ips_life.ipl_allocations.ipl_count, + tdbp->ips_life.ipl_bytes.ipl_count, + tdbp->ips_life.ipl_addtime.ipl_count, + tdbp->ips_life.ipl_usetime.ipl_count, + tdbp->ips_life.ipl_packets.ipl_count), + extensions_reply) : 1) + && (tdbp->ips_life.ipl_allocations.ipl_hard + || tdbp->ips_life.ipl_bytes.ipl_hard + || tdbp->ips_life.ipl_addtime.ipl_hard + || tdbp->ips_life.ipl_usetime.ipl_hard + || tdbp->ips_life.ipl_packets.ipl_hard + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD], + SADB_EXT_LIFETIME_HARD, + tdbp->ips_life.ipl_allocations.ipl_hard, + tdbp->ips_life.ipl_bytes.ipl_hard, + tdbp->ips_life.ipl_addtime.ipl_hard, + tdbp->ips_life.ipl_usetime.ipl_hard, + tdbp->ips_life.ipl_packets.ipl_hard), + extensions_reply) : 1) + && (tdbp->ips_life.ipl_allocations.ipl_soft + || tdbp->ips_life.ipl_bytes.ipl_soft + || tdbp->ips_life.ipl_addtime.ipl_soft + || tdbp->ips_life.ipl_usetime.ipl_soft + || tdbp->ips_life.ipl_packets.ipl_soft + ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT], + SADB_EXT_LIFETIME_SOFT, + tdbp->ips_life.ipl_allocations.ipl_soft, + tdbp->ips_life.ipl_bytes.ipl_soft, + tdbp->ips_life.ipl_addtime.ipl_soft, + tdbp->ips_life.ipl_usetime.ipl_soft, + tdbp->ips_life.ipl_packets.ipl_soft), + extensions_reply) : 1) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_s), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_d), + extensions_reply) + && (extr->tdb->tdb_addr_p + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY], + SADB_EXT_ADDRESS_PROXY, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_p), + extensions_reply) : 1) +#if 0 + /* FIXME: This won't work yet because the keys are not + stored directly in the tdb. They are stored as + contexts. */ + && (extr->tdb->tdb_key_a_size + ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH], + SADB_EXT_KEY_AUTH, + extr->tdb->tdb_key_a_size * 8, + extr->tdb->tdb_key_a), + extensions_reply) : 1) + /* FIXME: This won't work yet because the keys are not + stored directly in the tdb. They are stored as + key schedules. */ + && (extr->tdb->tdb_key_e_size + ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT], + SADB_EXT_KEY_ENCRYPT, + extr->tdb->tdb_key_e_size * 8, + extr->tdb->tdb_key_e), + extensions_reply) : 1) +#endif + && (extr->tdb->tdb_ident_s.data + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC], + SADB_EXT_IDENTITY_SRC, + extr->tdb->tdb_ident_s.type, + extr->tdb->tdb_ident_s.id, + extr->tdb->tdb_ident_s.len, + extr->tdb->tdb_ident_s.data), + extensions_reply) : 1) + && (extr->tdb->tdb_ident_d.data + ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST], + SADB_EXT_IDENTITY_DST, + extr->tdb->tdb_ident_d.type, + extr->tdb->tdb_ident_d.id, + extr->tdb->tdb_ident_d.len, + extr->tdb->tdb_ident_d.data), + extensions_reply) : 1) +#if 0 + /* FIXME: This won't work yet because I have not finished + it. */ + && (extr->tdb->tdb_sens_ + ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY], + extr->tdb->tdb_sens_dpd, + extr->tdb->tdb_sens_sens_level, + extr->tdb->tdb_sens_sens_len, + extr->tdb->tdb_sens_sens_bitmap, + extr->tdb->tdb_sens_integ_level, + extr->tdb->tdb_sens_integ_len, + extr->tdb->tdb_sens_integ_bitmap), + extensions_reply) : 1) +#endif + )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " + "failed to build the get reply message extensions\n"); + spin_unlock_bh(&tdb_lock); + SENDERR(-error); + } + + spin_unlock_bh(&tdb_lock); + + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " + "failed to build the get reply message\n"); + SENDERR(-error); + } + + if((error = pfkey_upmsg(sk->socket, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " + "failed to send the get reply message\n"); + SENDERR(-error); + } + + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: " + "succeeded in sending get reply message.\n"); + + errlab: + if (pfkey_reply) { + pfkey_msg_free(&pfkey_reply); + } + pfkey_extensions_free(extensions_reply); + return error; +} + +DEBUG_NO_STATIC int +pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct socket_list *pfkey_socketsp; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_acquire_parse: .\n"); + + /* XXX I don't know if we want an upper bound, since userspace may + want to register itself for an satype > SADB_SATYPE_MAX. */ + if((satype == 0) || (satype > SADB_SATYPE_MAX)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_acquire_parse: " + "SATYPE=%d invalid.\n", + satype); + SENDERR(EINVAL); + } + + if(!(pfkey_registered_sockets[satype])) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " + "no sockets registered for SAtype=%d(%s).\n", + satype, + satype2name(satype)); + SENDERR(EPROTONOSUPPORT); + } + + for(pfkey_socketsp = pfkey_registered_sockets[satype]; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " + "sending up acquire reply message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: " + "sending up acquire reply message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_parse: .\n"); + + /* XXX I don't know if we want an upper bound, since userspace may + want to register itself for an satype > SADB_SATYPE_MAX. */ + if((satype == 0) || (satype > SADB_SATYPE_MAX)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_parse: " + "SATYPE=%d invalid.\n", + satype); + SENDERR(EINVAL); + } + + if(!pfkey_list_insert_socket(sk->socket, + &(pfkey_registered_sockets[satype]))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_parse: " + "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n", + satype, + satype2name(satype), + key_pid(sk)); + }; + + /* send up register msg with supported SATYPE algos */ + + error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]); + errlab: + return error; +} +int +pfkey_register_reply(int satype, struct sadb_msg *sadb_msg) +{ + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_reply = NULL; + struct socket_list *pfkey_socketsp; + struct supported_list *pfkey_supported_listp; + unsigned int alg_num_a = 0, alg_num_e = 0; + struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL; + int error = 0; + + pfkey_extensions_init(extensions_reply); + + if((satype == 0) || (satype > SADB_SATYPE_MAX)) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " + "SAtype=%d unspecified or unknown.\n", + satype); + SENDERR(EINVAL); + } + if(!(pfkey_registered_sockets[satype])) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " + "no sockets registered for SAtype=%d(%s).\n", + satype, + satype2name(satype)); + SENDERR(EPROTONOSUPPORT); + } + /* send up register msg with supported SATYPE algos */ + pfkey_supported_listp = pfkey_supported_list[satype]; + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_reply: " + "pfkey_supported_list[%d]=%p\n", + satype, + pfkey_supported_list[satype]); + while(pfkey_supported_listp) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_reply: " + "checking supported=%p\n", + pfkey_supported_listp); + if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_reply: " + "adding auth alg.\n"); + alg_num_a++; + } + if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_reply: " + "adding encrypt alg.\n"); + alg_num_e++; + } + pfkey_supported_listp = pfkey_supported_listp->next; + } + + if(alg_num_a) { + if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_reply: " + "auth alg memory allocation error\n"); + SENDERR(ENOMEM); + } + alg_ap = alg_a; + } + + if(alg_num_e) { + if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_reply: " + "enc alg memory allocation error\n"); + SENDERR(ENOMEM); + } + alg_ep = alg_e; + } + + pfkey_supported_listp = pfkey_supported_list[satype]; + while(pfkey_supported_listp) { + if(alg_num_a) { + if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) { + alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; + alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; + alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; + alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; + alg_ap->sadb_alg_reserved = 0; + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_register_reply: " + "adding auth=%p\n", + alg_ap); + alg_ap++; + } + } + if(alg_num_e) { + if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) { + alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id; + alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen; + alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits; + alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits; + alg_ep->sadb_alg_reserved = 0; + KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose, + "klips_debug:pfkey_register_reply: " + "adding encrypt=%p\n", + alg_ep); + alg_ep++; + } + } + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_register_reply: " + "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n", + satype, + satype2name(satype), + pfkey_supported_listp->supportedp->supported_alg_exttype, + pfkey_supported_listp->supportedp->supported_alg_id, + pfkey_supported_listp->supportedp->supported_alg_ivlen, + pfkey_supported_listp->supportedp->supported_alg_minbits, + pfkey_supported_listp->supportedp->supported_alg_maxbits); + pfkey_supported_listp = pfkey_supported_listp->next; + } + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], + SADB_REGISTER, + satype, + 0, + sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq, + sadb_msg? sadb_msg->sadb_msg_pid: current->pid), + extensions_reply) && + (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH], + SADB_EXT_SUPPORTED_AUTH, + alg_num_a, + alg_a), + extensions_reply) : 1) && + (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT], + SADB_EXT_SUPPORTED_ENCRYPT, + alg_num_e, + alg_e), + extensions_reply) : 1))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " + "failed to build the register message extensions_reply\n"); + SENDERR(-error); + } + + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " + "failed to build the register message\n"); + SENDERR(-error); + } + /* this should go to all registered sockets for that satype only */ + for(pfkey_socketsp = pfkey_registered_sockets[satype]; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " + "sending up acquire message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: " + "sending up register message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + + errlab: + if(alg_a) { + kfree(alg_a); + } + if(alg_e) { + kfree(alg_e); + } + if (pfkey_reply) { + pfkey_msg_free(&pfkey_reply); + } + pfkey_extensions_free(extensions_reply); + return error; +} + +DEBUG_NO_STATIC int +pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct socket_list *pfkey_socketsp; +#ifdef CONFIG_IPSEC_DEBUG + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; +#endif /* CONFIG_IPSEC_DEBUG */ + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_expire_parse: .\n"); + + if(pfkey_open_sockets) { + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " + "sending up expire reply message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: " + "sending up expire reply message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + } + + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + struct socket_list *pfkey_socketsp; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; + uint8_t proto = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_flush_parse: " + "flushing type %d SAs\n", + satype); + + if(satype && !(proto = satype2proto(satype))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_flush_parse: " + "satype %d lookup failed.\n", + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype); + SENDERR(EINVAL); + } + + if ((error = ipsec_sadb_cleanup(proto))) { + SENDERR(-error); + } + + if(pfkey_open_sockets) { + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " + "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + proto, + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: " + "sending up flush reply message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + } + + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_dump_parse: .\n"); + + SENDERR(ENOSYS); + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_promisc_parse: .\n"); + + SENDERR(ENOSYS); + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_pchange_parse: .\n"); + + SENDERR(ENOSYS); + errlab: + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + struct ipsec_sa *tdb1p, *tdb2p, *tdbp; + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_reply = NULL; + struct socket_list *pfkey_socketsp; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; + char sa1[SATOA_BUF], sa2[SATOA_BUF]; + size_t sa_len1, sa_len2 = 0; + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_grpsa_parse: .\n"); + + pfkey_extensions_init(extensions_reply); + + if(!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_grpsa_parse: " + "extr or extr->tdb is NULL, fatal.\n"); + SENDERR(EINVAL); + } + + sa_len1 = satoa(extr->tdb->tdb_said, 0, sa1, SATOA_BUF); + if(extr->tdb2) { + sa_len2 = satoa(extr->tdb2->tdb_said, 0, sa2, SATOA_BUF); + } + + spin_lock_bh(&tdb_lock); + + if(!(tdb1p = ipsec_sa_getbyid(&(extr->tdb->tdb_said)))) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_grpsa_parse: " + "reserved Tunnel Descriptor Block for SA: %s not found. Call SADB_ADD/UPDATE first.\n", + sa_len1 ? sa1 : " (error)"); + SENDERR(ENOENT); + } + if(extr->tdb2) { /* GRPSA */ + if(!(tdb2p = ipsec_sa_getbyid(&(extr->tdb2->tdb_said)))) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_grpsa_parse: " + "reserved Tunnel Descriptor Block for SA: %s not found. Call SADB_ADD/UPDATE first.\n", + sa_len2 ? sa2 : " (error)"); + SENDERR(ENOENT); + } + + /* Is either one already linked? */ + if(tdb1p->tdb_onext) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_grpsa_parse: " + "Tunnel Descriptor Block for SA: %s is already linked.\n", + sa_len1 ? sa1 : " (error)"); + SENDERR(EEXIST); + } + if(tdb2p->tdb_inext) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_grpsa_parse: " + "Tunnel Descriptor Block for SA: %s is already linked.\n", + sa_len2 ? sa2 : " (error)"); + SENDERR(EEXIST); + } + + /* Is extr->tdb already linked to extr->tdb2? */ + tdbp = tdb2p; + while(tdbp) { + if(tdbp == tdb1p) { + spin_unlock_bh(&tdb_lock); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_grpsa_parse: " + "Tunnel Descriptor Block for SA: %s is already linked to %s.\n", + sa_len1 ? sa1 : " (error)", + sa_len2 ? sa2 : " (error)"); + SENDERR(EEXIST); + } + tdbp = tdb2p->tdb_onext; + } + + /* link 'em */ + tdb1p->tdb_onext = tdb2p; + tdb2p->tdb_inext = tdb1p; + } else { /* UNGRPSA */ + while(tdb1p->tdb_onext) { + tdb1p = tdb1p->tdb_onext; + } + while(tdb1p->tdb_inext) { + tdbp = tdb1p; + tdb1p = tdb1p->tdb_inext; + tdbp->tdb_inext = NULL; + tdb1p->tdb_onext = NULL; + } + } + + spin_unlock_bh(&tdb_lock); + + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], + SADB_X_GRPSA, + satype, + 0, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), + extensions_reply) + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA], + SADB_EXT_SA, + extr->tdb->tdb_said.spi, + extr->tdb->tdb_replaywin, + extr->tdb->tdb_state, + extr->tdb->tdb_authalg, + extr->tdb->tdb_encalg, + extr->tdb->tdb_flags), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_d), + extensions_reply) + && (extr->tdb2 + ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2], + ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype + /* proto2satype(extr->tdb2->tdb_said.proto) */), + extensions_reply) + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_X_EXT_SA2], + SADB_X_EXT_SA2, + extr->tdb2->tdb_said.spi, + extr->tdb2->tdb_replaywin, + extr->tdb2->tdb_state, + extr->tdb2->tdb_authalg, + extr->tdb2->tdb_encalg, + extr->tdb2->tdb_flags), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2], + SADB_X_EXT_ADDRESS_DST2, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb2->tdb_addr_d), + extensions_reply) ) : 1 ) + )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " + "failed to build the x_grpsa reply message extensions\n"); + SENDERR(-error); + } + + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " + "failed to build the x_grpsa reply message\n"); + SENDERR(-error); + } + + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " + "sending up x_grpsa reply message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " + "sending up x_grpsa reply message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: " + "succeeded in sending x_grpsa reply message.\n"); + + errlab: + if (pfkey_reply) { + pfkey_msg_free(&pfkey_reply); + } + pfkey_extensions_free(extensions_reply); + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; +#ifdef CONFIG_IPSEC_DEBUG + char buf1[64], buf2[64]; +#endif /* CONFIG_IPSEC_DEBUG */ + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_reply = NULL; + struct socket_list *pfkey_socketsp; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; + ip_address srcflow, dstflow, srcmask, dstmask; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: .\n"); + + pfkey_extensions_init(extensions_reply); + + memset((caddr_t)&srcflow, 0, sizeof(srcflow)); + memset((caddr_t)&dstflow, 0, sizeof(dstflow)); + memset((caddr_t)&srcmask, 0, sizeof(srcmask)); + memset((caddr_t)&dstmask, 0, sizeof(dstmask)); + + if(!extr || !(extr->tdb) || !(extr->eroute)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "missing extr, tdb or eroute data.\n"); + SENDERR(EINVAL); + } + + srcflow.u.v4.sin_family = AF_INET; + dstflow.u.v4.sin_family = AF_INET; + srcmask.u.v4.sin_family = AF_INET; + dstmask.u.v4.sin_family = AF_INET; + srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; + dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; + srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; + dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; + +#ifdef CONFIG_IPSEC_DEBUG + if (debug_pfkey) { + subnettoa(extr->eroute->er_eaddr.sen_ip_src, + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); + subnettoa(extr->eroute->er_eaddr.sen_ip_dst, + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "calling breakeroute and/or makeroute for %s->%s\n", + buf1, buf2); + } +#endif /* CONFIG_IPSEC_DEBUG */ + if(extr->tdb->tdb_flags & SADB_X_SAFLAGS_INFLOW) { +/* if(ip_chk_addr((unsigned long)extr->tdb->tdb_said.dst.s_addr) == IS_MYADDR) */ + struct ipsec_sa *tdbp; + char sa[SATOA_BUF]; + size_t sa_len; + + if((tdbp = ipsec_sa_getbyid(&(extr->tdb->tdb_said))) == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "tdb not found, cannot set incoming policy.\n"); + SENDERR(ENOENT); + } + + while(tdbp && tdbp->tdb_said.proto != IPPROTO_IPIP) { + tdbp = tdbp->tdb_inext; + } + + if(tdbp == NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "SA chain does not have an IPIP SA, cannot set incoming policy.\n"); + SENDERR(ENOENT); + } + + sa_len = satoa(extr->tdb->tdb_said, 0, sa, SATOA_BUF); + +/* tdbp->tdb_flow_s.u.v4.sin_addr = srcflow.u.v4.sin_addr; + tdbp->tdb_flow_d.u.v4.sin_addr = dstflow.u.v4.sin_addr; + tdbp->tdb_mask_s.u.v4.sin_addr = srcmask.u.v4.sin_addr; + tdbp->tdb_mask_d.u.v4.sin_addr = dstmask.u.v4.sin_addr; */ + + tdbp->tdb_flags |= SADB_X_SAFLAGS_INFLOW; + tdbp->tdb_flow_s = srcflow; + tdbp->tdb_flow_d = dstflow; + tdbp->tdb_mask_s = srcmask; + tdbp->tdb_mask_d = dstmask; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "inbound eroute, setting incoming policy information in IPIP Tunnel Descriptor Block for SA: %s.\n", + sa_len ? sa : " (error)"); + } else { + struct sk_buff *first = NULL, *last = NULL; + + if(extr->tdb->tdb_flags & SADB_X_SAFLAGS_REPLACEFLOW) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "REPLACEFLOW flag set, calling breakeroute.\n"); + if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr), + &(extr->eroute->er_emask), + &first, &last))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "breakeroute returned %d. first=%p, last=%p\n", + error, + first, + last); + if(first != NULL) { + kfree_skb(first); + } + if(last != NULL) { + kfree_skb(last); + } + SENDERR(-error); + } + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "calling makeroute.\n"); + + if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr), + &(extr->eroute->er_emask), + extr->tdb->tdb_said, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid, + NULL, + &(extr->tdb->tdb_ident_s), + &(extr->tdb->tdb_ident_d)))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "makeroute returned %d.\n", error); + SENDERR(-error); + } + if(first != NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "first=%p HOLD packet re-injected.\n", + first); + /* ipsec_tunnel_start_xmit(first, first->dev); */ + DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL); + } + if(last != NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "last=%p HOLD packet re-injected.\n", + last); + /* ipsec_tunnel_start_xmit(last, last->dev); */ + DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL); + } + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "makeroute call successful.\n"); + + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], + SADB_X_ADDFLOW, + satype, + 0, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), + extensions_reply) + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA], + SADB_EXT_SA, + extr->tdb->tdb_said.spi, + extr->tdb->tdb_replaywin, + extr->tdb->tdb_state, + extr->tdb->tdb_authalg, + extr->tdb->tdb_encalg, + extr->tdb->tdb_flags), + extensions_reply) + && (extensions[SADB_EXT_ADDRESS_SRC] + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_s), + extensions_reply) : 1) + && (extensions[SADB_EXT_ADDRESS_DST] + ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + extr->tdb->tdb_addr_d), + extensions_reply) : 1) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], + SADB_X_EXT_ADDRESS_SRC_FLOW, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + (struct sockaddr*)&srcflow), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], + SADB_X_EXT_ADDRESS_DST_FLOW, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + (struct sockaddr*)&dstflow), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], + SADB_X_EXT_ADDRESS_SRC_MASK, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + (struct sockaddr*)&srcmask), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], + SADB_X_EXT_ADDRESS_DST_MASK, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + (struct sockaddr*)&dstmask), + extensions_reply) + )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " + "failed to build the x_addflow reply message extensions\n"); + SENDERR(-error); + } + + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " + "failed to build the x_addflow reply message\n"); + SENDERR(-error); + } + + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " + "sending up x_addflow reply message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: " + "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=%p succeeded.\n", + satype, + satype2name(satype), + extr->tdb->tdb_said.proto, + pfkey_socketsp->socketp); + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_addflow_parse: " + "extr->tdb cleaned up and freed.\n"); + + errlab: + if (pfkey_reply) { + pfkey_msg_free(&pfkey_reply); + } + pfkey_extensions_free(extensions_reply); + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; +#ifdef CONFIG_IPSEC_DEBUG + char buf1[64], buf2[64]; +#endif /* CONFIG_IPSEC_DEBUG */ + struct sadb_ext *extensions_reply[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_reply = NULL; + struct socket_list *pfkey_socketsp; + uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype; + ip_address srcflow, dstflow, srcmask, dstmask; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_delflow_parse: .\n"); + + pfkey_extensions_init(extensions_reply); + + memset((caddr_t)&srcflow, 0, sizeof(srcflow)); + memset((caddr_t)&dstflow, 0, sizeof(dstflow)); + memset((caddr_t)&srcmask, 0, sizeof(srcmask)); + memset((caddr_t)&dstmask, 0, sizeof(dstmask)); + + if(!extr || !(extr->tdb)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_delflow_parse: " + "extr, or extr->tdb is NULL, fatal\n"); + SENDERR(EINVAL); + } + + if(extr->tdb->tdb_flags & SADB_X_SAFLAGS_CLEARFLOW) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_delflow_parse: " + "CLEARFLOW flag set, calling cleareroutes.\n"); + if ((error = ipsec_cleareroutes())) + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_delflow_parse: " + "cleareroutes returned %d.\n", error); + SENDERR(-error); + } else { + struct sk_buff *first = NULL, *last = NULL; + + if(!(extr->eroute)) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_delflow_parse: " + "extr->eroute is NULL, fatal.\n"); + SENDERR(EINVAL); + } + + srcflow.u.v4.sin_family = AF_INET; + dstflow.u.v4.sin_family = AF_INET; + srcmask.u.v4.sin_family = AF_INET; + dstmask.u.v4.sin_family = AF_INET; + srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src; + dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst; + srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src; + dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst; + +#ifdef CONFIG_IPSEC_DEBUG + if (debug_pfkey) { + subnettoa(extr->eroute->er_eaddr.sen_ip_src, + extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1)); + subnettoa(extr->eroute->er_eaddr.sen_ip_dst, + extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2)); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_delflow_parse: " + "calling breakeroute for %s->%s\n", + buf1, buf2); + } +#endif /* CONFIG_IPSEC_DEBUG */ + if((error = ipsec_breakroute(&(extr->eroute->er_eaddr), + &(extr->eroute->er_emask), + &first, &last))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_delflow_parse: " + "breakeroute returned %d. first=%p, last=%p\n", + error, + first, + last); + if(first != NULL) { + kfree_skb(first); + } + if(last != NULL) { + kfree_skb(last); + } + SENDERR(-error); + } + if(first != NULL) { + kfree_skb(first); + } + if(last != NULL) { + kfree_skb(last); + } + } + + if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0], + SADB_X_DELFLOW, + satype, + 0, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq, + ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid), + extensions_reply) + && pfkey_safe_build(error = pfkey_sa_build(&extensions_reply[SADB_EXT_SA], + SADB_EXT_SA, + extr->tdb->tdb_said.spi, + extr->tdb->tdb_replaywin, + extr->tdb->tdb_state, + extr->tdb->tdb_authalg, + extr->tdb->tdb_encalg, + extr->tdb->tdb_flags), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW], + SADB_X_EXT_ADDRESS_SRC_FLOW, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + (struct sockaddr*)&srcflow), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW], + SADB_X_EXT_ADDRESS_DST_FLOW, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + (struct sockaddr*)&dstflow), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK], + SADB_X_EXT_ADDRESS_SRC_MASK, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + (struct sockaddr*)&srcmask), + extensions_reply) + && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK], + SADB_X_EXT_ADDRESS_DST_MASK, + 0, /*extr->tdb->tdb_said.proto,*/ + 0, + (struct sockaddr*)&dstmask), + extensions_reply) + )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " + "failed to build the x_delflow reply message extensions\n"); + SENDERR(-error); + } + + if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " + "failed to build the x_delflow reply message\n"); + SENDERR(-error); + } + + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " + "sending up x_delflow reply message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: " + "sending up x_delflow reply message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_delflow_parse: " + "extr->tdb cleaned up and freed.\n"); + + errlab: + if (pfkey_reply) { + pfkey_msg_free(&pfkey_reply); + } + pfkey_extensions_free(extensions_reply); + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + int error = 0; + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_x_msg_debug_parse: .\n"); + +/* errlab:*/ + return error; +} + +/* pfkey_expire expects the tdb table to be locked before being called. */ +int +pfkey_expire(struct ipsec_sa *tdbp, int hard) +{ + struct sadb_ext *extensions[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_msg = NULL; + struct socket_list *pfkey_socketsp; + int error = 0; + uint8_t satype; + + pfkey_extensions_init(extensions); + + if(!(satype = proto2satype(tdbp->tdb_said.proto))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_expire: " + "satype lookup for protocol %d lookup failed.\n", + tdbp->tdb_said.proto); + SENDERR(EINVAL); + } + + if(!pfkey_open_sockets) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " + "no sockets listening.\n"); + SENDERR(EPROTONOSUPPORT); + } + + if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], + SADB_EXPIRE, + satype, + 0, + ++pfkey_msg_seq, + 0), + extensions) + && pfkey_safe_build(error = pfkey_sa_build(&extensions[SADB_EXT_SA], + SADB_EXT_SA, + tdbp->tdb_said.spi, + tdbp->tdb_replaywin, + tdbp->tdb_state, + tdbp->tdb_authalg, + tdbp->tdb_encalg, + tdbp->tdb_flags), + extensions) + && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT], + SADB_EXT_LIFETIME_CURRENT, + tdbp->ips_life.ipl_allocations.ipl_count, + tdbp->ips_life.ipl_bytes.ipl_count, + tdbp->ips_life.ipl_addtime.ipl_count, + tdbp->ips_life.ipl_usetime.ipl_count, + tdbp->ips_life.ipl_packets.ipl_count), + extensions) + && (hard ? + pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD], + SADB_EXT_LIFETIME_HARD, + tdbp->ips_life.ipl_allocations.ipl_hard, + tdbp->ips_life.ipl_bytes.ipl_hard, + tdbp->ips_life.ipl_addtime.ipl_hard, + tdbp->ips_life.ipl_usetime.ipl_hard, + tdbp->ips_life.ipl_packets.ipl_hard), + extensions) + : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT], + SADB_EXT_LIFETIME_SOFT, + tdbp->ips_life.ipl_allocations.ipl_soft, + tdbp->ips_life.ipl_bytes.ipl_soft, + tdbp->ips_life.ipl_addtime.ipl_soft, + tdbp->ips_life.ipl_usetime.ipl_soft, + tdbp->ips_life.ipl_packets.ipl_soft), + extensions)) + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, + 0, /* tdbp->tdb_said.proto, */ + 0, + tdbp->tdb_addr_s), + extensions) + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + 0, /* tdbp->tdb_said.proto, */ + 0, + tdbp->tdb_addr_d), + extensions))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " + "failed to build the expire message extensions\n"); + spin_unlock(&tdb_lock); + goto errlab; + } + + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " + "failed to build the expire message\n"); + SENDERR(-error); + } + + for(pfkey_socketsp = pfkey_open_sockets; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " + "sending up expire message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: " + "sending up expire message for satype=%d(%s) (proto=%d) to socket=%p succeeded.\n", + satype, + satype2name(satype), + tdbp->tdb_said.proto, + pfkey_socketsp->socketp); + } + + errlab: + if (pfkey_msg) { + pfkey_msg_free(&pfkey_msg); + } + pfkey_extensions_free(extensions); + return error; +} + +int +pfkey_acquire(struct ipsec_sa *tdbp) +{ + struct sadb_ext *extensions[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_msg = NULL; + struct socket_list *pfkey_socketsp; + int error = 0; + struct sadb_comb comb[] = { + /* auth; encrypt; flags; */ + /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */ + /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */ + /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */ + /* soft_packets; hard_packets; */ + { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS, + 128, 128, 168, 168, + 0, 0, 0, 0, 0, + 57600, 86400, 57600, 86400, + 0, 0 }, + { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS, + 160, 160, 168, 168, + 0, 0, 0, 0, 0, + 57600, 86400, 57600, 86400, + 0, 0 } + }; + + /* XXX This should not be hard-coded. It should be taken from the spdb */ + uint8_t satype = SADB_SATYPE_ESP; + + pfkey_extensions_init(extensions); + + if((satype == 0) || (satype > SADB_SATYPE_MAX)) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " + "SAtype=%d unspecified or unknown.\n", + satype); + SENDERR(EINVAL); + } + + if(!(pfkey_registered_sockets[satype])) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " + "no sockets registered for SAtype=%d(%s).\n", + satype, + satype2name(satype)); + SENDERR(EPROTONOSUPPORT); + } + + if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0], + SADB_ACQUIRE, + satype, + 0, + ++pfkey_msg_seq, + 0), + extensions) + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, + tdbp->tdb_said.proto, + 0, + tdbp->tdb_addr_s), + extensions) + && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + tdbp->tdb_said.proto, + 0, + tdbp->tdb_addr_d), + extensions) +#if 0 + && (tdbp->tdb_addr_p + ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY], + SADB_EXT_ADDRESS_PROXY, + tdbp->tdb_said.proto, + 0, + tdbp->tdb_addr_p), + extensions) : 1) +#endif + && (tdbp->tdb_ident_s.type != SADB_IDENTTYPE_RESERVED + ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC], + SADB_EXT_IDENTITY_SRC, + tdbp->tdb_ident_s.type, + tdbp->tdb_ident_s.id, + tdbp->tdb_ident_s.len, + tdbp->tdb_ident_s.data), + extensions) : 1) + + && (tdbp->tdb_ident_d.type != SADB_IDENTTYPE_RESERVED + ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST], + SADB_EXT_IDENTITY_DST, + tdbp->tdb_ident_d.type, + tdbp->tdb_ident_d.id, + tdbp->tdb_ident_d.len, + tdbp->tdb_ident_d.data), + extensions) : 1) +#if 0 + /* FIXME: This won't work yet because I have not finished + it. */ + && (tdbp->tdb_sens_ + ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY], + tdbp->tdb_sens_dpd, + tdbp->tdb_sens_sens_level, + tdbp->tdb_sens_sens_len, + tdbp->tdb_sens_sens_bitmap, + tdbp->tdb_sens_integ_level, + tdbp->tdb_sens_integ_len, + tdbp->tdb_sens_integ_bitmap), + extensions) : 1) +#endif + && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL], + 64, /* replay */ + sizeof(comb)/sizeof(struct sadb_comb), + &(comb[0])), + extensions) + )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " + "failed to build the acquire message extensions\n"); + SENDERR(-error); + } + + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " + "failed to build the acquire message\n"); + SENDERR(-error); + } + +#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0 + if(sysctl_ipsec_regress_pfkey_lossage) { + return(0); + } +#endif + + /* this should go to all registered sockets for that satype only */ + for(pfkey_socketsp = pfkey_registered_sockets[satype]; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " + "sending up acquire message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: " + "sending up acquire message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + + errlab: + if (pfkey_msg) { + pfkey_msg_free(&pfkey_msg); + } + pfkey_extensions_free(extensions); + return error; +} + +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL +int +pfkey_nat_t_new_mapping(struct ipsec_sa *tdbp, struct sockaddr *ipaddr, + __u16 sport) +{ + struct sadb_ext *extensions[SADB_EXT_MAX+1]; + struct sadb_msg *pfkey_msg = NULL; + struct socket_list *pfkey_socketsp; + int error = 0; + uint8_t satype = (tdbp->tdb_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0; + + /* Construct SADB_X_NAT_T_NEW_MAPPING message */ + + pfkey_extensions_init(extensions); + + if((satype == 0) || (satype > SADB_SATYPE_MAX)) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " + "SAtype=%d unspecified or unknown.\n", + satype); + SENDERR(EINVAL); + } + + if(!(pfkey_registered_sockets[satype])) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " + "no sockets registered for SAtype=%d(%s).\n", + satype, + satype2name(satype)); + SENDERR(EPROTONOSUPPORT); + } + + if (!(pfkey_safe_build + (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING, + satype, 0, ++pfkey_msg_seq, 0), extensions) + /* SA */ + && pfkey_safe_build + (error = pfkey_sa_build(&extensions[SADB_EXT_SA], + SADB_EXT_SA, tdbp->tdb_said.spi, 0, 0, 0, 0, 0), extensions) + /* ADDRESS_SRC = old addr */ + && pfkey_safe_build + (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, tdbp->tdb_said.proto, 0, tdbp->tdb_addr_s), + extensions) + /* NAT_T_SPORT = old port */ + && pfkey_safe_build + (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT], + SADB_X_EXT_NAT_T_SPORT, tdbp->ips_natt_sport), extensions) + /* ADDRESS_DST = new addr */ + && pfkey_safe_build + (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, tdbp->tdb_said.proto, 0, ipaddr), extensions) + /* NAT_T_DPORT = new port */ + && pfkey_safe_build + (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT], + SADB_X_EXT_NAT_T_DPORT, sport), extensions) + )) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " + "failed to build the nat_t_new_mapping message extensions\n"); + SENDERR(-error); + } + + if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " + "failed to build the nat_t_new_mapping message\n"); + SENDERR(-error); + } + + /* this should go to all registered sockets for that satype only */ + for(pfkey_socketsp = pfkey_registered_sockets[satype]; + pfkey_socketsp; + pfkey_socketsp = pfkey_socketsp->next) { + if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " + "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp, + error); + SENDERR(-error); + } + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: " + "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n", + satype, + satype2name(satype), + pfkey_socketsp->socketp); + } + + errlab: + if (pfkey_msg) { + pfkey_msg_free(&pfkey_msg); + } + pfkey_extensions_free(extensions); + return error; +} + +DEBUG_NO_STATIC int +pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr) +{ + /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */ + return -EINVAL; +} +#endif + +DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) = +{ + NULL, /* pfkey_msg_process, */ + pfkey_sa_process, + pfkey_lifetime_process, + pfkey_lifetime_process, + pfkey_lifetime_process, + pfkey_address_process, + pfkey_address_process, + pfkey_address_process, + pfkey_key_process, + pfkey_key_process, + pfkey_ident_process, + pfkey_ident_process, + pfkey_sens_process, + pfkey_prop_process, + pfkey_supported_process, + pfkey_supported_process, + pfkey_spirange_process, + pfkey_x_kmprivate_process, + pfkey_x_satype_process, + pfkey_sa_process, + pfkey_address_process, + pfkey_address_process, + pfkey_address_process, + pfkey_address_process, + pfkey_address_process, + pfkey_x_debug_process, + pfkey_x_protocol_process +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + , + pfkey_x_nat_t_type_process, + pfkey_x_nat_t_port_process, + pfkey_x_nat_t_port_process, + pfkey_address_process +#endif +}; + + +DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr) + = +{ + NULL, /* RESERVED */ + pfkey_getspi_parse, + pfkey_update_parse, + pfkey_add_parse, + pfkey_delete_parse, + pfkey_get_parse, + pfkey_acquire_parse, + pfkey_register_parse, + pfkey_expire_parse, + pfkey_flush_parse, + pfkey_dump_parse, + pfkey_x_promisc_parse, + pfkey_x_pchange_parse, + pfkey_x_grpsa_parse, + pfkey_x_addflow_parse, + pfkey_x_delflow_parse, + pfkey_x_msg_debug_parse +#ifdef NAT_TRAVERSAL + , pfkey_x_nat_t_new_mapping_parse +#endif +}; + +int +pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr, + struct sadb_msg **pfkey_reply) +{ + struct sadb_ext *extensions[SADB_EXT_MAX+1]; + int error = 0; + int msg_type = pfkey_msg->sadb_msg_type; + int seq = pfkey_msg->sadb_msg_seq; + + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " + "building reply with type: %d\n", + msg_type); + pfkey_extensions_init(extensions); + if (!extr || !extr->tdb) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " + "bad TDB passed\n"); + return EINVAL; + } + error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0], + msg_type, + proto2satype(extr->tdb->tdb_said.proto), + 0, + seq, + pfkey_msg->sadb_msg_pid), + extensions) && + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & + 1 << SADB_EXT_SA) + || pfkey_safe_build(pfkey_sa_build(&extensions[SADB_EXT_SA], + SADB_EXT_SA, + extr->tdb->tdb_said.spi, + extr->tdb->tdb_replaywin, + extr->tdb->tdb_state, + extr->tdb->tdb_authalg, + extr->tdb->tdb_encalg, + extr->tdb->tdb_flags), + extensions)) && + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & + 1 << SADB_EXT_LIFETIME_CURRENT) + || pfkey_safe_build(pfkey_lifetime_build(&extensions + [SADB_EXT_LIFETIME_CURRENT], + SADB_EXT_LIFETIME_CURRENT, + extr->tdb->ips_life.ipl_allocations.ipl_count, + extr->tdb->ips_life.ipl_bytes.ipl_count, + extr->tdb->ips_life.ipl_addtime.ipl_count, + extr->tdb->ips_life.ipl_usetime.ipl_count, + extr->tdb->ips_life.ipl_packets.ipl_count), + extensions)) && + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & + 1 << SADB_EXT_ADDRESS_SRC) + || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], + SADB_EXT_ADDRESS_SRC, + extr->tdb->tdb_said.proto, + 0, + extr->tdb->tdb_addr_s), + extensions)) && + (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] & + 1 << SADB_EXT_ADDRESS_DST) + || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], + SADB_EXT_ADDRESS_DST, + extr->tdb->tdb_said.proto, + 0, + extr->tdb->tdb_addr_d), + extensions)); + + if (error == 0) { + KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: " + "building extensions failed\n"); + return EINVAL; + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_build_reply: " + "built extensions, proceed to build the message\n"); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_build_reply: " + "extensions[1]= %p\n", + extensions[1]); + error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT); + pfkey_extensions_free(extensions); + + return error; +} + +int +pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg, + struct sadb_msg **pfkey_reply) +{ + int error = 0; + int i; + struct sadb_ext *extensions[SADB_EXT_MAX+1]; + struct pfkey_extracted_data extr = {NULL, NULL, NULL}; + + pfkey_extensions_init(extensions); + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n", + pfkey_msg->sadb_msg_version, + pfkey_msg->sadb_msg_type, + pfkey_msg->sadb_msg_errno, + pfkey_msg->sadb_msg_satype, + satype2name(pfkey_msg->sadb_msg_satype), + pfkey_msg->sadb_msg_len, + pfkey_msg->sadb_msg_reserved, + pfkey_msg->sadb_msg_seq, + pfkey_msg->sadb_msg_pid); + + if((error = pfkey_alloc_ipsec_sa(&(extr.tdb)))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "something's really wrong, extr.tdb=%p should be NULL.\n", + extr.tdb); + SENDERR(-error); + } + + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "allocated extr->tdb=%p.\n", + extr.tdb); + + if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "satype %d > max %d\n", + pfkey_msg->sadb_msg_satype, + SADB_SATYPE_MAX); + SENDERR(EINVAL); + } + + switch(pfkey_msg->sadb_msg_type) { + case SADB_GETSPI: + case SADB_UPDATE: + case SADB_ADD: + case SADB_DELETE: + case SADB_X_GRPSA: + case SADB_X_ADDFLOW: + if(!(extr.tdb->tdb_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "satype %d lookup failed.\n", + pfkey_msg->sadb_msg_satype); + SENDERR(EINVAL); + } else { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "satype %d lookups to proto=%d.\n", + pfkey_msg->sadb_msg_satype, + extr.tdb->tdb_said.proto); + } + break; + default: + } + + /* The NULL below causes the default extension parsers to be used */ + /* Parse the extensions */ + if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN))) + { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "message parsing failed with error %d.\n", + error); + SENDERR(-error); + } + + /* Process the extensions */ + for(i=1; i <= SADB_EXT_MAX;i++) { + if(extensions[i] != NULL) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "processing ext %d %p with processor %p.\n", + i, extensions[i], ext_processors[i]); + if((error = ext_processors[i](extensions[i], &extr))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "extension processing for type %d failed with error %d.\n", + i, + error); + SENDERR(-error); + } + + } + + } + + /* Parse the message types */ + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "parsing message type %d with msg_parser %p.\n", + pfkey_msg->sadb_msg_type, + msg_parsers[pfkey_msg->sadb_msg_type]); + if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) { + KLIPS_PRINT(debug_pfkey, + "klips_debug:pfkey_msg_interp: " + "message parsing failed with error %d.\n", + error); + SENDERR(-error); + } + +#if 0 + error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply); + if (error) { + *pfkey_reply = NULL; + } +#endif + errlab: + if(extr.tdb != NULL) { + ipsec_sa_wipe(extr.tdb); + } + if(extr.tdb2 != NULL) { + ipsec_sa_wipe(extr.tdb2); + } + if (extr.eroute != NULL) { + kfree(extr.eroute); + } + return(error); +} + +/* + * $Log: pfkey_v2_parser.c,v $ + * Revision 1.16 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.15 2003/09/30 00:26:01 ken + * Tuomo Soini's NAT-T 0.6 cleanup patch + * Fixes a number of #ifdefs around NAT-T, and brings a few other other cleanups in + * + * Revision 1.14 2003/02/07 13:14:25 ken + * Pullin jjo's ALG 0.8.1rc branch + * + * Revision 1.13.2.1 2003/02/06 22:09:50 jjo + * sync to alg-0.8.1-rc4 + * + * Revision 1.13 2003/01/19 22:32:30 ken + * X.509 0.9.19 -> 0.9.20 + * + * Revision 1.12 2003/01/02 22:56:51 ken + * Relocate variable delcaration to correct function + * + * Revision 1.11 2003/01/02 22:48:42 ken + * Fix bad NAT-T 0.5 merge + * + * Revision 1.10 2003/01/02 21:54:27 ken + * NAT-T 0.5 + * + * Revision 1.9 2002/12/28 01:45:14 ken + * Remove extra , line + * + * Revision 1.8 2002/12/26 02:28:50 ken + * Fix order of SADB definations + * + * Revision 1.7 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.6 2002/10/16 00:21:47 ken + * Applied JuanJo's NULL Patch + * + * Revision 1.5 2002/10/16 00:16:50 ken + * Backed out David patch in prep for JuanJo's + * + * Revision 1.4 2002/10/15 17:52:48 ken + * Added David De Reu's NULL ALG Bugfix + * + * Revision 1.3 2002/09/05 03:53:52 ken + * Added NAT-T Patch + * + * Revision 1.2 2002/09/05 03:27:09 ken + * Applied freeswan-alg-0.8.0-BASE-klips.diff + * + * Revision 1.1.1.1 2002/09/05 03:13:18 ken + * 1.98b + * + * Revision 1.102 2002/03/08 01:15:17 mcr + * put some internal structure only debug messages behind + * && sysctl_ipsec_debug_verbose. + * + * Revision 1.101 2002/01/29 17:17:57 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.100 2002/01/29 04:00:54 mcr + * more excise of kversions.h header. + * + * Revision 1.99 2002/01/29 02:13:19 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.98 2002/01/12 02:57:57 mcr + * first regression test causes acquire messages to be lost + * 100% of the time. This is to help testing of pluto. + * + * Revision 1.97 2001/11/26 09:23:52 rgb + * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes. + * + * Revision 1.93.2.4 2001/10/23 04:20:27 mcr + * parity was forced on wrong structure! prototypes help here. + * + * Revision 1.93.2.3 2001/10/22 21:14:59 mcr + * include des.h, removed phony prototypes and fixed calling + * conventions to match real prototypes. + * + * Revision 1.93.2.2 2001/10/15 05:39:03 mcr + * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha. + * + * Revision 1.93.2.1 2001/09/25 02:30:14 mcr + * struct tdb -> struct ipsec_sa. + * use new lifetime structure. common format routines for debug. + * + * Revision 1.96 2001/11/06 20:47:54 rgb + * Fixed user context call to ipsec_dev_start_xmit() bug. Call + * dev_queue_xmit() instead. + * + * Revision 1.95 2001/11/06 19:47:46 rgb + * Added packet parameter to lifetime and comb structures. + * + * Revision 1.94 2001/10/18 04:45:23 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/freeswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.93 2001/09/20 15:32:59 rgb + * Min/max cleanup. + * + * Revision 1.92 2001/09/19 16:35:48 rgb + * PF_KEY ident fix for getspi from NetCelo (puttdb duplication). + * + * Revision 1.91 2001/09/15 16:24:06 rgb + * Re-inject first and last HOLD packet when an eroute REPLACE is done. + * + * Revision 1.90 2001/09/14 16:58:38 rgb + * Added support for storing the first and last packets through a HOLD. + * + * Revision 1.89 2001/09/08 21:14:07 rgb + * Added pfkey ident extension support for ISAKMPd. (NetCelo) + * Better state coherency (error management) between pf_key and IKE daemon. + * (NetCelo) + * + * Revision 1.88 2001/08/27 19:42:44 rgb + * Fix memory leak of encrypt and auth structs in pfkey register. + * + * Revision 1.87 2001/07/06 19:50:46 rgb + * Removed unused debugging code. + * Added inbound policy checking code for IPIP SAs. + * + * Revision 1.86 2001/06/20 06:26:04 rgb + * Changed missing SA errors from EEXIST to ENOENT and added debug output + * for already linked SAs. + * + * Revision 1.85 2001/06/15 04:57:02 rgb + * Remove single error return condition check and check for all errors in + * the case of a replace eroute delete operation. This means that + * applications must expect to be deleting something before replacing it + * and if nothing is found, complain. + * + * Revision 1.84 2001/06/14 19:35:12 rgb + * Update copyright date. + * + * Revision 1.83 2001/06/12 00:03:19 rgb + * Silence debug set/unset under normal conditions. + * + * Revision 1.82 2001/05/30 08:14:04 rgb + * Removed vestiges of esp-null transforms. + * + * Revision 1.81 2001/05/27 06:12:12 rgb + * Added structures for pid, packet count and last access time to eroute. + * Added packet count to beginning of /proc/net/ipsec_eroute. + * + * Revision 1.80 2001/05/03 19:43:59 rgb + * Check error return codes for all build function calls. + * Standardise on SENDERR() macro. + * + * Revision 1.79 2001/04/20 21:09:16 rgb + * Cleaned up fixed tdbwipes. + * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and + * delflow (Per Cederqvist) plugging memleaks. + * + * Revision 1.78 2001/04/19 19:02:39 rgb + * Fixed extr.tdb freeing, stealing it for getspi, update and add. + * Refined a couple of spinlocks, fixed the one in update. + * + * Revision 1.77 2001/04/18 20:26:16 rgb + * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp() + * instead of inside each message type parser. This fixes two memleaks. + * + * Revision 1.76 2001/04/17 23:51:18 rgb + * Quiet down pfkey_x_debug_process(). + * + * Revision 1.75 2001/03/29 01:55:05 rgb + * Fixed pfkey key init memleak. + * Fixed pfkey encryption key debug output. + * + * Revision 1.74 2001/03/27 05:29:14 rgb + * Debug output cleanup/silencing. + * + * Revision 1.73 2001/02/28 05:03:28 rgb + * Clean up and rationalise startup messages. + * + * Revision 1.72 2001/02/27 22:24:56 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.71 2001/02/27 06:59:30 rgb + * Added satype2name() conversions most places satype is debug printed. + * + * Revision 1.70 2001/02/26 22:37:08 rgb + * Fixed 'unknown proto' INT bug in new code. + * Added satype to protocol debugging instrumentation. + * + * Revision 1.69 2001/02/26 19:57:51 rgb + * Re-formatted debug output (split lines, consistent spacing). + * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup() + * with an satype instead of proto. + * Checked for satype consistency and fixed minor bugs. + * Fixed undetected ungrpspi bug that tried to upmsg a second tdb. + * Check for satype sanity in pfkey_expire(). + * Added satype sanity check to addflow. + * + * Revision 1.68 2001/02/12 23:14:40 rgb + * Remove double spin lock in pfkey_expire(). + * + * Revision 1.67 2001/01/31 19:23:40 rgb + * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete). + * + * Revision 1.66 2001/01/29 22:20:04 rgb + * Fix minor add upmsg lifetime bug. + * + * Revision 1.65 2001/01/24 06:12:33 rgb + * Fixed address extension compile bugs just introduced. + * + * Revision 1.64 2001/01/24 00:31:15 rgb + * Added upmsg for addflow/delflow. + * + * Revision 1.63 2001/01/23 22:02:55 rgb + * Added upmsg to x_grpsa. + * Fixed lifetimes extentions to add/update/get upmsg. + * + * Revision 1.62 2000/11/30 21:47:51 rgb + * Fix error return bug after returning from pfkey_tdb_init(). + * + * Revision 1.61 2000/11/17 18:10:29 rgb + * Fixed bugs mostly relating to spirange, to treat all spi variables as + * network byte order since this is the way PF_KEYv2 stored spis. + * + * Revision 1.60 2000/11/06 04:34:53 rgb + * Changed non-exported functions to DEBUG_NO_STATIC. + * Add Svenning's adaptive content compression. + * Ditched spin_lock_irqsave in favour of spin_lock/_bh. + * Fixed double unlock bug (Svenning). + * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}(). + * Fixed incorrect extension type (prop) in pfkey)acquire(). + * + * Revision 1.59 2000/10/11 15:25:12 rgb + * Fixed IPCOMP disabled compile bug. + * + * Revision 1.58 2000/10/11 14:54:03 rgb + * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey + * protocol violations of setting pfkey_address_build() protocol parameter + * to non-zero except in the case of pfkey_acquire(). + * + * Revision 1.57 2000/10/10 20:10:18 rgb + * Added support for debug_ipcomp and debug_verbose to klipsdebug. + * + * Revision 1.56 2000/10/06 20:24:36 rgb + * Fixes to pfkey_acquire to initialize extensions[] and use correct + * ipproto. + * + * Revision 1.55 2000/10/03 03:20:57 rgb + * Added brackets to get a?b:c scope right for pfkey_register reply. + * + * Revision 1.54 2000/09/29 19:49:30 rgb + * As-yet-unused-bits cleanup. + * + * Revision 1.53 2000/09/28 00:35:45 rgb + * Padded SATYPE printout in pfkey_register for vertical alignment. + * + * Revision 1.52 2000/09/20 16:21:58 rgb + * Cleaned up ident string alloc/free. + * + * Revision 1.51 2000/09/20 04:04:20 rgb + * Changed static functions to DEBUG_NO_STATIC to reveal function names in + * oopsen. + * + * Revision 1.50 2000/09/16 01:10:53 rgb + * Fixed unused var warning with debug off. + * + * Revision 1.49 2000/09/15 11:37:02 rgb + * Merge in heavily modified Svenning Soerensen's + * IPCOMP zlib deflate code. + * + * Revision 1.48 2000/09/15 04:57:57 rgb + * Cleaned up existing IPCOMP code before svenning addition. + * Initialize pfkey_reply and extensions_reply in case of early error in + * message parsing functions (thanks Kai!). + * + * Revision 1.47 2000/09/13 08:02:56 rgb + * Added KMd registration notification. + * + * Revision 1.46 2000/09/12 22:35:36 rgb + * Restructured to remove unused extensions from CLEARFLOW messages. + * + * Revision 1.45 2000/09/12 03:24:23 rgb + * Converted #if0 debugs to sysctl. + * + * Revision 1.44 2000/09/09 06:38:39 rgb + * Correct SADB message type for update, add and delete. + * + * Revision 1.43 2000/09/08 19:19:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * Removed all references to CONFIG_IPSEC_PFKEYv2. + * Put in sanity checks in most msg type parsers to catch invalid satypes + * and empty socket lists. + * Moved spin-locks in pfkey_get_parse() to simplify. + * Added pfkey_acquire(). + * Added upwards messages to update, add, delete, acquire_parse, + * expire_parse and flush. + * Fix pfkey_prop_build() parameter to be only single indirection. + * Changed all replies to use pfkey_reply. + * Check return code on puttdb() and deltdbchain() in getspi, update, + * add, delete. + * Fixed up all pfkey replies to open and registered sockets. + * + * Revision 1.42 2000/09/01 18:50:26 rgb + * Added a supported algorithms array lists, one per satype and registered + * existing algorithms. + * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to + * list. + * Only send pfkey_expire() messages to sockets registered for that satype. + * Added reply to pfkey_getspi_parse(). + * Added reply to pfkey_get_parse(). + * Fixed debug output label bug in pfkey_lifetime_process(). + * Cleaned up pfkey_sa_process a little. + * Moved pfkey_safe_build() above message type parsers to make it available + * for creating replies. + * Added comments for future work in pfkey_acquire_parse(). + * Fleshed out guts of pfkey_register_parse(). + * + * Revision 1.41 2000/08/24 16:58:11 rgb + * Fixed key debugging variables. + * Fixed error return code for a failed search. + * Changed order of pfkey_get operations. + * + * Revision 1.40 2000/08/21 16:32:27 rgb + * Re-formatted for cosmetic consistency and readability. + * + * Revision 1.39 2000/08/20 21:38:57 rgb + * Bugfixes to as-yet-unused pfkey_update_parse() and + * pfkey_register_parse(). (Momchil) + * Added functions pfkey_safe_build(), pfkey_expire() and + * pfkey_build_reply(). (Momchil) + * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil) + * + * Revision 1.38 2000/08/18 21:30:41 rgb + * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear. + * + * Revision 1.37 2000/08/18 18:18:02 rgb + * Cosmetic and descriptive changes made to debug test. + * getspi and update fixes from Momchil. + * + * Revision 1.36 2000/08/15 15:41:55 rgb + * Fixed the (as yet unused and untested) pfkey_getspi() routine. + * + * Revision 1.35 2000/08/01 14:51:52 rgb + * Removed _all_ remaining traces of DES. + * + * Revision 1.34 2000/07/28 14:58:32 rgb + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. + * + * Revision 1.33 2000/06/28 05:50:11 rgb + * Actually set iv_bits. + * + * Revision 1.32 2000/05/30 18:36:56 rgb + * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY + * FreeS/WAN, but fixes interop with other implementations. + * + * Revision 1.31 2000/03/16 14:05:48 rgb + * Fixed brace scope preventing non-debug compile. + * Added null parameter check for pfkey_x_debug(). + * + * Revision 1.30 2000/01/22 23:21:13 rgb + * Use new function satype2proto(). + * + * Revision 1.29 2000/01/22 08:40:21 rgb + * Invert condition to known value to avoid AF_INET6 in 2.0.36. + * + * Revision 1.28 2000/01/22 07:58:57 rgb + * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR. + * + * Revision 1.27 2000/01/22 03:48:01 rgb + * Added extr pointer component debugging. + * + * Revision 1.26 2000/01/21 09:41:25 rgb + * Changed a (void*) to (char*) cast to do proper pointer math. + * Don't call tdbwipe if tdb2 is NULL. + * + * Revision 1.25 2000/01/21 06:21:01 rgb + * Added address cases for eroute flows. + * Tidied up compiler directive indentation for readability. + * Added ictx,octx vars for simplification. + * Added macros for HMAC padding magic numbers. + * Converted from double tdb arguments to one structure (extr) + * containing pointers to all temporary information structures + * and checking for valid arguments to all ext processors and + * msg type parsers. + * Added spiungrp'ing. + * Added klipsdebug switching capability. + * Removed sa_process() check for zero protocol. + * Added address case for DST2 for grouping. + * Added/changed minor debugging instrumentation. + * Fixed spigrp for single said, ungrouping case. + * Added code to parse addflow and delflow messages. + * Removed redundant statements duplicating tdbwipe() functionality + * and causing double kfrees. + * Permit addflow to have a protocol of 0. + * + * Revision 1.24 1999/12/09 23:23:00 rgb + * Added check to pfkey_sa_process() to do eroutes. + * Converted to DIVUP() macro. + * Converted if() to switch() in pfkey_register_parse(). + * Use new pfkey_extensions_init() instead of memset(). + * + * Revision 1.23 1999/12/01 22:18:13 rgb + * Preset minspi and maxspi values in case and spirange extension is not + * included and check for the presence of an spirange extension before + * using it. Initialise tdb_sastate to LARVAL. + * Fixed debugging output typo. + * Fixed authentication context initialisation bugs (4 places). + * + * Revision 1.22 1999/11/27 11:53:08 rgb + * Moved pfkey_msg_parse prototype to pfkey.h + * Moved exts_permitted/required prototype to pfkey.h. + * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c. + * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never + * be called. + * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c + * Debugging error messages added. + * Enable lifetime_current checking. + * Remove illegal requirement for SA extension to be present in an + * originating GETSPI call. + * Re-instate requirement for UPDATE or ADD message to be MATURE. + * Add argument to pfkey_msg_parse() for direction. + * Fixed IPIP dst address bug and purged redundant, leaky code. + * + * Revision 1.21 1999/11/24 05:24:20 rgb + * hanged 'void*extensions' to 'struct sadb_ext*extensions'. + * Fixed indention. + * Ditched redundant replay check. + * Fixed debug message text from 'parse' to 'process'. + * Added more debug output. + * Forgot to zero extensions array causing bug, fixed. + * + * Revision 1.20 1999/11/23 23:08:13 rgb + * Move all common parsing code to lib/pfkey_v2_parse.c and rename + * remaining bits to *_process. (PJO) + * Add macros for dealing with alignment and rounding up more opaquely. + * Use provided macro ADDRTOA_BUF instead of hardcoded value. + * Sort out pfkey and freeswan headers, putting them in a library path. + * Corrected a couple of bugs in as-yet-inactive code. + * + * Revision 1.19 1999/11/20 22:01:10 rgb + * Add more descriptive error messages for non-zero reserved fields. + * Add more descriptive error message for spirange parsing. + * Start on supported extension parsing. + * Start on register and get message parsing. + * + * Revision 1.18 1999/11/18 04:09:20 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.17 1999/11/17 15:53:41 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.16 1999/10/26 16:57:43 rgb + * Add shorter macros for compiler directives to visually clean-up. + * Give ipv6 code meaningful compiler directive. + * Add comments to other #if 0 debug code. + * Remove unused *_bh_atomic() calls. + * Fix mis-placed spinlock. + * + * Revision 1.15 1999/10/16 18:27:10 rgb + * Clean-up unused cruft. + * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations. + * + * Revision 1.14 1999/10/08 18:37:34 rgb + * Fix end-of-line spacing to sate whining PHMs. + * + * Revision 1.13 1999/10/03 18:49:12 rgb + * Spinlock fixes for 2.0.xx and 2.3.xx. + * + * Revision 1.12 1999/10/01 15:44:54 rgb + * Move spinlock header include to 2.1> scope. + * + * Revision 1.11 1999/10/01 00:05:45 rgb + * Added tdb structure locking. + * Use 'jiffies' instead of do_get_timeofday(). + * Fix lifetime assignments. + * + * Revision 1.10 1999/09/21 15:24:45 rgb + * Rework spirange code to save entropy and prevent endless loops. + * + * Revision 1.9 1999/09/16 12:10:21 rgb + * Minor fixes to random spi selection for correctness and entropy conservation. + * + * Revision 1.8 1999/05/25 22:54:46 rgb + * Fix comparison that should be an assignment in an if. + * + * Revision 1.7 1999/05/09 03:25:37 rgb + * Fix bug introduced by 2.2 quick-and-dirty patch. + * + * Revision 1.6 1999/05/08 21:32:30 rgb + * Fix error return reporting. + * + * Revision 1.5 1999/05/05 22:02:33 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.4 1999/04/29 15:22:40 rgb + * Standardise an error return method. + * Add debugging instrumentation. + * Add check for existence of macros min/max. + * Add extensions permitted/required in/out filters. + * Add satype-to-protocol table. + * Add a second tdb pointer to each parser to accomodate GRPSA. + * Move AH & no_algo_set to GETSPI, UPDATE and ADD. + * Add OOO window check. + * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP. + * Add timestamp to lifetime parse. + * Fix address structure length checking bug. + * Fix address structure allocation bug (forgot to kmalloc!). + * Add checks for extension lengths. + * Add checks for extension reserved illegal values. + * Add check for spirange legal values. + * Add an extension type for parsing a second satype, SA and + * DST_ADDRESS. + * Make changes to tdb_init() template to get pfkey_tdb_init(), + * eliminating any mention of xformsw. + * Implement getspi, update and grpsa (not tested). + * Add stubs for as yet unimplemented message types. + * Add table of message parsers to substitute for msg_parse switch. + * + * Revision 1.3 1999/04/15 17:58:07 rgb + * Add RCSID labels. + * + * Revision 1.2 1999/04/15 15:37:26 rgb + * Forward check changes from POST1_00 branch. + * + * Revision 1.1.2.1 1999/03/26 20:58:56 rgb + * Add pfkeyv2 support to KLIPS. + * + * Local variables: + * c-file-style: "linux" + * End: + * + */ diff -urN linux-2.4.29/net/ipsec/radij.c linux-2.4.29-openswan-1.0.9/net/ipsec/radij.c --- linux-2.4.29/net/ipsec/radij.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/radij.c Thu Dec 4 03:53:24 2003 @@ -0,0 +1,1209 @@ +char radij_c_version[] = "RCSID $Id: radij.c,v 1.5 2003/12/04 02:53:24 ken Exp $"; + +/* + * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite + * + * Variable and procedure names have been modified so that they don't + * conflict with the original BSD code, as a small number of modifications + * have been introduced and we may want to reuse this code in BSD. + * + * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek + * chi or a German ch sound (as `doch', not as in `milch'), or even a + * spanish j as in Juan. It is not as far back in the throat like + * the corresponding Hebrew sound, nor is it a soft breath like the English h. + * It has nothing to do with the Dutch ij sound. + * + * Here is the appropriate copyright notice: + */ + +/* + * Copyright (c) 1988, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)radix.c 8.2 (Berkeley) 1/4/94 + */ + +/* + * Routines to build and maintain radix trees for routing lookups. + */ + +#include +#include +#include /* printk() */ + +#include "ipsec_param.h" + +#ifdef MALLOC_SLAB +# include /* kmalloc() */ +#else /* MALLOC_SLAB */ +# include /* kmalloc() */ +#endif /* MALLOC_SLAB */ +#include /* error codes */ +#include /* size_t */ +#include /* mark_bh */ + +#include /* struct device, and other headers */ +#include /* eth_type_trans */ +#include /* struct iphdr */ +#include +#ifdef NET_21 +# include +# include +#endif /* NET_21 */ +#include +#include + +#include + +#include "radij.h" +#include "ipsec_encap.h" +#include "ipsec_radij.h" +#include "ipsec_netlink.h" + +int maj_keylen; +struct radij_mask *rj_mkfreelist; +struct radij_node_head *mask_rjhead; +static int gotOddMasks; +static char *maskedKey; +static char *rj_zeroes, *rj_ones; + +#define rj_masktop (mask_rjhead->rnh_treetop) +#ifdef Bcmp +# undef Bcmp +#endif /* Bcmp */ +#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l)) +/* + * The data structure for the keys is a radix tree with one way + * branching removed. The index rj_b at an internal node n represents a bit + * position to be tested. The tree is arranged so that all descendants + * of a node n have keys whose bits all agree up to position rj_b - 1. + * (We say the index of n is rj_b.) + * + * There is at least one descendant which has a one bit at position rj_b, + * and at least one with a zero there. + * + * A route is determined by a pair of key and mask. We require that the + * bit-wise logical and of the key and mask to be the key. + * We define the index of a route to associated with the mask to be + * the first bit number in the mask where 0 occurs (with bit number 0 + * representing the highest order bit). + * + * We say a mask is normal if every bit is 0, past the index of the mask. + * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b, + * and m is a normal mask, then the route applies to every descendant of n. + * If the index(m) < rj_b, this implies the trailing last few bits of k + * before bit b are all 0, (and hence consequently true of every descendant + * of n), so the route applies to all descendants of the node as well. + * + * The present version of the code makes no use of normal routes, + * but similar logic shows that a non-normal mask m such that + * index(m) <= index(n) could potentially apply to many children of n. + * Thus, for each non-host route, we attach its mask to a list at an internal + * node as high in the tree as we can go. + */ + +struct radij_node * +rj_search(v_arg, head) + void *v_arg; + struct radij_node *head; +{ + register struct radij_node *x; + register caddr_t v; + + for (x = head, v = v_arg; x->rj_b >= 0;) { + if (x->rj_bmask & v[x->rj_off]) + x = x->rj_r; + else + x = x->rj_l; + } + return (x); +}; + +struct radij_node * +rj_search_m(v_arg, head, m_arg) + struct radij_node *head; + void *v_arg, *m_arg; +{ + register struct radij_node *x; + register caddr_t v = v_arg, m = m_arg; + + for (x = head; x->rj_b >= 0;) { + if ((x->rj_bmask & m[x->rj_off]) && + (x->rj_bmask & v[x->rj_off])) + x = x->rj_r; + else + x = x->rj_l; + } + return x; +}; + +int +rj_refines(m_arg, n_arg) + void *m_arg, *n_arg; +{ + register caddr_t m = m_arg, n = n_arg; + register caddr_t lim, lim2 = lim = n + *(u_char *)n; + int longer = (*(u_char *)n++) - (int)(*(u_char *)m++); + int masks_are_equal = 1; + + if (longer > 0) + lim -= longer; + while (n < lim) { + if (*n & ~(*m)) + return 0; + if (*n++ != *m++) + masks_are_equal = 0; + + } + while (n < lim2) + if (*n++) + return 0; + if (masks_are_equal && (longer < 0)) + for (lim2 = m - longer; m < lim2; ) + if (*m++) + return 1; + return (!masks_are_equal); +} + + +struct radij_node * +rj_match(v_arg, head) + void *v_arg; + struct radij_node_head *head; +{ + caddr_t v = v_arg; + register struct radij_node *t = head->rnh_treetop, *x; + register caddr_t cp = v, cp2, cp3; + caddr_t cplim, mstart; + struct radij_node *saved_t, *top = t; + int off = t->rj_off, vlen = *(u_char *)cp, matched_off; + + /* + * Open code rj_search(v, top) to avoid overhead of extra + * subroutine call. + */ + for (; t->rj_b >= 0; ) { + if (t->rj_bmask & cp[t->rj_off]) + t = t->rj_r; + else + t = t->rj_l; + } + /* + * See if we match exactly as a host destination + */ + KLIPS_PRINT(debug_radij, + "klips_debug:rj_match: " + "* See if we match exactly as a host destination\n"); + + cp += off; cp2 = t->rj_key + off; cplim = v + vlen; + for (; cp < cplim; cp++, cp2++) + if (*cp != *cp2) + goto on1; + /* + * This extra grot is in case we are explicitly asked + * to look up the default. Ugh! + */ + if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey) + t = t->rj_dupedkey; + return t; +on1: + matched_off = cp - v; + saved_t = t; + KLIPS_PRINT(debug_radij, + "klips_debug:rj_match: " + "** try to match a leaf, t=0x%p\n", t); + do { + if (t->rj_mask) { + /* + * Even if we don't match exactly as a hosts; + * we may match if the leaf we wound up at is + * a route to a net. + */ + cp3 = matched_off + t->rj_mask; + cp2 = matched_off + t->rj_key; + for (; cp < cplim; cp++) + if ((*cp2++ ^ *cp) & *cp3++) + break; + if (cp == cplim) + return t; + cp = matched_off + v; + } + } while ((t = t->rj_dupedkey)); + t = saved_t; + /* start searching up the tree */ + KLIPS_PRINT(debug_radij, + "klips_debug:rj_match: " + "*** start searching up the tree, t=0x%p\n", + t); + do { + register struct radij_mask *m; + + t = t->rj_p; + KLIPS_PRINT(debug_radij, + "klips_debug:rj_match: " + "**** t=0x%p\n", + t); + if ((m = t->rj_mklist)) { + /* + * After doing measurements here, it may + * turn out to be faster to open code + * rj_search_m here instead of always + * copying and masking. + */ + /* off = min(t->rj_off, matched_off); */ + off = t->rj_off; + if (matched_off < off) + off = matched_off; + mstart = maskedKey + off; + do { + cp2 = mstart; + cp3 = m->rm_mask + off; + KLIPS_PRINT(debug_radij, + "klips_debug:rj_match: " + "***** cp2=0x%p cp3=0x%p\n", + cp2, cp3); + for (cp = v + off; cp < cplim;) + *cp2++ = *cp++ & *cp3++; + x = rj_search(maskedKey, t); + while (x && x->rj_mask != m->rm_mask) + x = x->rj_dupedkey; + if (x && + (Bcmp(mstart, x->rj_key + off, + vlen - off) == 0)) + return x; + } while ((m = m->rm_mklist)); + } + } while (t != top); + KLIPS_PRINT(debug_radij, + "klips_debug:rj_match: " + "***** not found.\n"); + return 0; +}; + +#ifdef RJ_DEBUG +int rj_nodenum; +struct radij_node *rj_clist; +int rj_saveinfo; +DEBUG_NO_STATIC void traverse(struct radij_node *); +#ifdef RJ_DEBUG2 +int rj_debug = 1; +#else +int rj_debug = 0; +#endif /* RJ_DEBUG2 */ +#endif /* RJ_DEBUG */ + +struct radij_node * +rj_newpair(v, b, nodes) + void *v; + int b; + struct radij_node nodes[2]; +{ + register struct radij_node *tt = nodes, *t = tt + 1; + t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7); + t->rj_l = tt; t->rj_off = b >> 3; + tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t; + tt->rj_flags = t->rj_flags = RJF_ACTIVE; +#ifdef RJ_DEBUG + tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++; + tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt; +#endif /* RJ_DEBUG */ + return t; +} + +struct radij_node * +rj_insert(v_arg, head, dupentry, nodes) + void *v_arg; + struct radij_node_head *head; + int *dupentry; + struct radij_node nodes[2]; +{ + caddr_t v = v_arg; + struct radij_node *top = head->rnh_treetop; + int head_off = top->rj_off, vlen = (int)*((u_char *)v); + register struct radij_node *t = rj_search(v_arg, top); + register caddr_t cp = v + head_off; + register int b; + struct radij_node *tt; + /* + *find first bit at which v and t->rj_key differ + */ + { + register caddr_t cp2 = t->rj_key + head_off; + register int cmp_res; + caddr_t cplim = v + vlen; + + while (cp < cplim) + if (*cp2++ != *cp++) + goto on1; + *dupentry = 1; + return t; +on1: + *dupentry = 0; + cmp_res = (cp[-1] ^ cp2[-1]) & 0xff; + for (b = (cp - v) << 3; cmp_res; b--) + cmp_res >>= 1; + } + { + register struct radij_node *p, *x = top; + cp = v; + do { + p = x; + if (cp[x->rj_off] & x->rj_bmask) + x = x->rj_r; + else x = x->rj_l; + } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */ +#ifdef RJ_DEBUG + if (rj_debug) + printk("klips_debug:rj_insert: Going In:\n"), traverse(p); +#endif /* RJ_DEBUG */ + t = rj_newpair(v_arg, b, nodes); tt = t->rj_l; + if ((cp[p->rj_off] & p->rj_bmask) == 0) + p->rj_l = t; + else + p->rj_r = t; + x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */ + if ((cp[t->rj_off] & t->rj_bmask) == 0) { + t->rj_r = x; + } else { + t->rj_r = tt; t->rj_l = x; + } +#ifdef RJ_DEBUG + if (rj_debug) + printk("klips_debug:rj_insert: Coming out:\n"), traverse(p); +#endif /* RJ_DEBUG */ + } + return (tt); +} + +struct radij_node * +rj_addmask(n_arg, search, skip) + int search, skip; + void *n_arg; +{ + caddr_t netmask = (caddr_t)n_arg; + register struct radij_node *x; + register caddr_t cp, cplim; + register int b, mlen, j; + int maskduplicated; + + mlen = *(u_char *)netmask; + if (search) { + x = rj_search(netmask, rj_masktop); + mlen = *(u_char *)netmask; + if (Bcmp(netmask, x->rj_key, mlen) == 0) + return (x); + } + R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x)); + if (x == 0) + return (0); + Bzero(x, maj_keylen + 2 * sizeof (*x)); + cp = (caddr_t)(x + 2); + Bcopy(netmask, cp, mlen); + netmask = cp; + x = rj_insert(netmask, mask_rjhead, &maskduplicated, x); + /* + * Calculate index of mask. + */ + cplim = netmask + mlen; + for (cp = netmask + skip; cp < cplim; cp++) + if (*(u_char *)cp != 0xff) + break; + b = (cp - netmask) << 3; + if (cp != cplim) { + if (*cp != 0) { + gotOddMasks = 1; + for (j = 0x80; j; b++, j >>= 1) + if ((j & *cp) == 0) + break; + } + } + x->rj_b = -1 - b; + return (x); +} + +#if 0 +struct radij_node * +#endif +int +rj_addroute(v_arg, n_arg, head, treenodes) + void *v_arg, *n_arg; + struct radij_node_head *head; + struct radij_node treenodes[2]; +{ + caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg; + register struct radij_node *t, *x=NULL, *tt; + struct radij_node *saved_tt, *top = head->rnh_treetop; + short b = 0, b_leaf; + int mlen, keyduplicated; + caddr_t cplim; + struct radij_mask *m, **mp; + + /* + * In dealing with non-contiguous masks, there may be + * many different routes which have the same mask. + * We will find it useful to have a unique pointer to + * the mask to speed avoiding duplicate references at + * nodes and possibly save time in calculating indices. + */ + if (netmask) { + x = rj_search(netmask, rj_masktop); + mlen = *(u_char *)netmask; + if (Bcmp(netmask, x->rj_key, mlen) != 0) { + x = rj_addmask(netmask, 0, top->rj_off); + if (x == 0) + return -ENOMEM; /* (0) rgb */ + } + netmask = x->rj_key; + b = -1 - x->rj_b; + } + /* + * Deal with duplicated keys: attach node to previous instance + */ + saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes); + if (keyduplicated) { + do { + if (tt->rj_mask == netmask) + return -EEXIST; /* -ENXIO; (0) rgb */ + t = tt; + if (netmask == 0 || + (tt->rj_mask && rj_refines(netmask, tt->rj_mask))) + break; + } while ((tt = tt->rj_dupedkey)); + /* + * If the mask is not duplicated, we wouldn't + * find it among possible duplicate key entries + * anyway, so the above test doesn't hurt. + * + * We sort the masks for a duplicated key the same way as + * in a masklist -- most specific to least specific. + * This may require the unfortunate nuisance of relocating + * the head of the list. + */ + if (tt && t == saved_tt) { + struct radij_node *xx = x; + /* link in at head of list */ + (tt = treenodes)->rj_dupedkey = t; + tt->rj_flags = t->rj_flags; + tt->rj_p = x = t->rj_p; + if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt; + saved_tt = tt; x = xx; + } else { + (tt = treenodes)->rj_dupedkey = t->rj_dupedkey; + t->rj_dupedkey = tt; + } +#ifdef RJ_DEBUG + t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++; + tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt; +#endif /* RJ_DEBUG */ + t = saved_tt; + tt->rj_key = (caddr_t) v; + tt->rj_b = -1; + tt->rj_flags = t->rj_flags & ~RJF_ROOT; + } + /* + * Put mask in tree. + */ + if (netmask) { + tt->rj_mask = netmask; + tt->rj_b = x->rj_b; + } + t = saved_tt->rj_p; + b_leaf = -1 - t->rj_b; + if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r; + /* Promote general routes from below */ + if (x->rj_b < 0) { + if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) { + MKGet(m); + if (m) { + Bzero(m, sizeof *m); + m->rm_b = x->rj_b; + m->rm_mask = x->rj_mask; + x->rj_mklist = t->rj_mklist = m; + } + } + } else if (x->rj_mklist) { + /* + * Skip over masks whose index is > that of new node + */ + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) + if (m->rm_b >= b_leaf) + break; + t->rj_mklist = m; *mp = 0; + } + /* Add new route to highest possible ancestor's list */ + if ((netmask == 0) || (b > t->rj_b )) + return 0; /* tt rgb */ /* can't lift at all */ + b_leaf = tt->rj_b; + do { + x = t; + t = t->rj_p; + } while (b <= t->rj_b && x != top); + /* + * Search through routes associated with node to + * insert new route according to index. + * For nodes of equal index, place more specific + * masks first. + */ + cplim = netmask + mlen; + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) { + if (m->rm_b < b_leaf) + continue; + if (m->rm_b > b_leaf) + break; + if (m->rm_mask == netmask) { + m->rm_refs++; + tt->rj_mklist = m; + return 0; /* tt rgb */ + } + if (rj_refines(netmask, m->rm_mask)) + break; + } + MKGet(m); + if (m == 0) { + printk("klips_debug:rj_addroute: " + "Mask for route not entered\n"); + return 0; /* (tt) rgb */ + } + Bzero(m, sizeof *m); + m->rm_b = b_leaf; + m->rm_mask = netmask; + m->rm_mklist = *mp; + *mp = m; + tt->rj_mklist = m; + return 0; /* tt rgb */ +} + +int +rj_delete(v_arg, netmask_arg, head, node) + void *v_arg, *netmask_arg; + struct radij_node_head *head; + struct radij_node **node; +{ + register struct radij_node *t, *p, *x, *tt; + struct radij_mask *m, *saved_m, **mp; + struct radij_node *dupedkey, *saved_tt, *top; + caddr_t v, netmask; + int b, head_off, vlen; + + v = v_arg; + netmask = netmask_arg; + x = head->rnh_treetop; + tt = rj_search(v, x); + head_off = x->rj_off; + vlen = *(u_char *)v; + saved_tt = tt; + top = x; + if (tt == 0 || + Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off)) + return -EFAULT; /* (0) rgb */ + /* + * Delete our route from mask lists. + */ + if ((dupedkey = tt->rj_dupedkey)) { + if (netmask) + netmask = rj_search(netmask, rj_masktop)->rj_key; + while (tt->rj_mask != netmask) + if ((tt = tt->rj_dupedkey) == 0) + return -ENOENT; /* -ENXIO; (0) rgb */ + } + if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0) + goto on1; + if (m->rm_mask != tt->rj_mask) { + printk("klips_debug:rj_delete: " + "inconsistent annotation\n"); + goto on1; + } + if (--m->rm_refs >= 0) + goto on1; + b = -1 - tt->rj_b; + t = saved_tt->rj_p; + if (b > t->rj_b) + goto on1; /* Wasn't lifted at all */ + do { + x = t; + t = t->rj_p; + } while (b <= t->rj_b && x != top); + for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) + if (m == saved_m) { + *mp = m->rm_mklist; + MKFree(m); + break; + } + if (m == 0) + printk("klips_debug:rj_delete: " + "couldn't find our annotation\n"); +on1: + /* + * Eliminate us from tree + */ + if (tt->rj_flags & RJF_ROOT) + return -EFAULT; /* (0) rgb */ +#ifdef RJ_DEBUG + /* Get us out of the creation list */ + for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {} + if (t) t->rj_ybro = tt->rj_ybro; +#endif /* RJ_DEBUG */ + t = tt->rj_p; + if (dupedkey) { + if (tt == saved_tt) { + x = dupedkey; x->rj_p = t; + if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x; + } else { + for (x = p = saved_tt; p && p->rj_dupedkey != tt;) + p = p->rj_dupedkey; + if (p) p->rj_dupedkey = tt->rj_dupedkey; + else printk("klips_debug:rj_delete: " + "couldn't find us\n"); + } + t = tt + 1; + if (t->rj_flags & RJF_ACTIVE) { +#ifndef RJ_DEBUG + *++x = *t; p = t->rj_p; +#else + b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p; +#endif /* RJ_DEBUG */ + if (p->rj_l == t) p->rj_l = x; else p->rj_r = x; + x->rj_l->rj_p = x; x->rj_r->rj_p = x; + } + goto out; + } + if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l; + p = t->rj_p; + if (p->rj_r == t) p->rj_r = x; else p->rj_l = x; + x->rj_p = p; + /* + * Demote routes attached to us. + */ + if (t->rj_mklist) { + if (x->rj_b >= 0) { + for (mp = &x->rj_mklist; (m = *mp);) + mp = &m->rm_mklist; + *mp = t->rj_mklist; + } else { + for (m = t->rj_mklist; m;) { + struct radij_mask *mm = m->rm_mklist; + if (m == x->rj_mklist && (--(m->rm_refs) < 0)) { + x->rj_mklist = 0; + MKFree(m); + } else + printk("klips_debug:rj_delete: " + "Orphaned Mask %p at %p\n", m, x); + m = mm; + } + } + } + /* + * We may be holding an active internal node in the tree. + */ + x = tt + 1; + if (t != x) { +#ifndef RJ_DEBUG + *t = *x; +#else + b = t->rj_info; *t = *x; t->rj_info = b; +#endif /* RJ_DEBUG */ + t->rj_l->rj_p = t; t->rj_r->rj_p = t; + p = x->rj_p; + if (p->rj_l == x) p->rj_l = t; else p->rj_r = t; + } +out: + tt->rj_flags &= ~RJF_ACTIVE; + tt[1].rj_flags &= ~RJF_ACTIVE; + *node = tt; + return 0; /* (tt) rgb */ +} + +int +rj_walktree(h, f, w) + struct radij_node_head *h; + register int (*f)(struct radij_node *,void *); + void *w; +{ + int error; + struct radij_node *base, *next; + register struct radij_node *rn; + + if(!h || !f /* || !w */) { + return -ENODATA; + } + + rn = h->rnh_treetop; + /* + * This gets complicated because we may delete the node + * while applying the function f to it, so we need to calculate + * the successor node in advance. + */ + /* First time through node, go left */ + while (rn->rj_b >= 0) + rn = rn->rj_l; + for (;;) { +#ifdef CONFIG_IPSEC_DEBUG + if(debug_radij) { + printk("klips_debug:rj_walktree: " + "for: rn=%p rj_b=%d rj_flags=%x", + rn, + rn->rj_b, + rn->rj_flags); + rn->rj_b >= 0 ? + printk(" node off=%x\n", + rn->rj_off) : + printk(" leaf key = %08x->%08x\n", + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) + ; + } +#endif /* CONFIG_IPSEC_DEBUG */ + base = rn; + /* If at right child go back up, otherwise, go right */ + while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0) + rn = rn->rj_p; + /* Find the next *leaf* since next node might vanish, too */ + for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;) + rn = rn->rj_l; + next = rn; +#ifdef CONFIG_IPSEC_DEBUG + if(debug_radij) { + printk("klips_debug:rj_walktree: " + "processing leaves, rn=%p rj_b=%d rj_flags=%x", + rn, + rn->rj_b, + rn->rj_flags); + rn->rj_b >= 0 ? + printk(" node off=%x\n", + rn->rj_off) : + printk(" leaf key = %08x->%08x\n", + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) + ; + } +#endif /* CONFIG_IPSEC_DEBUG */ + /* Process leaves */ + while ((rn = base)) { + base = rn->rj_dupedkey; +#ifdef CONFIG_IPSEC_DEBUG + if(debug_radij) { + printk("klips_debug:rj_walktree: " + "while: base=%p rn=%p rj_b=%d rj_flags=%x", + base, + rn, + rn->rj_b, + rn->rj_flags); + rn->rj_b >= 0 ? + printk(" node off=%x\n", + rn->rj_off) : + printk(" leaf key = %08x->%08x\n", + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)) + ; + } +#endif /* CONFIG_IPSEC_DEBUG */ + if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w))) + return (-error); + } + rn = next; + if (rn->rj_flags & RJF_ROOT) + return (0); + } + /* NOTREACHED */ +} + +int +rj_inithead(head, off) + void **head; + int off; +{ + register struct radij_node_head *rnh; + register struct radij_node *t, *tt, *ttt; + if (*head) + return (1); + R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh)); + if (rnh == NULL) + return (0); + Bzero(rnh, sizeof (*rnh)); + *head = rnh; + t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes); + ttt = rnh->rnh_nodes + 2; + t->rj_r = ttt; + t->rj_p = t; + tt = t->rj_l; + tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE; + tt->rj_b = -1 - off; + *ttt = *tt; + ttt->rj_key = rj_ones; + rnh->rnh_addaddr = rj_addroute; + rnh->rnh_deladdr = rj_delete; + rnh->rnh_matchaddr = rj_match; + rnh->rnh_walktree = rj_walktree; + rnh->rnh_treetop = t; + return (1); +} + +void +rj_init() +{ + char *cp, *cplim; + + if (maj_keylen == 0) { + printk("klips_debug:rj_init: " + "radij functions require maj_keylen be set\n"); + return; + } + R_Malloc(rj_zeroes, char *, 3 * maj_keylen); + if (rj_zeroes == NULL) + panic("rj_init"); + Bzero(rj_zeroes, 3 * maj_keylen); + rj_ones = cp = rj_zeroes + maj_keylen; + maskedKey = cplim = rj_ones + maj_keylen; + while (cp < cplim) + *cp++ = -1; + if (rj_inithead((void **)&mask_rjhead, 0) == 0) + panic("rj_init 2"); +} + +void +rj_preorder(struct radij_node *rn, int l) +{ + int i; + + if (rn == NULL){ + printk("klips_debug:rj_preorder: " + "NULL pointer\n"); + return; + } + + if (rn->rj_b >= 0){ + rj_preorder(rn->rj_l, l+1); + rj_preorder(rn->rj_r, l+1); + printk("klips_debug:"); + for (i=0; irj_off); + } else { + printk("klips_debug:"); + for (i=0; irj_flags); + if (rn->rj_flags & RJF_ACTIVE) { + printk(" @key = %p", + rn->rj_key); + printk(" key = %08x->%08x", + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr), + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr)); + printk(" @mask = %p", + rn->rj_mask); + if (rn->rj_mask) + printk(" mask = %08x->%08x", + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr), + (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr)); +/* This printf not 64bit clean, and refuses to cast easily. + if (rn->rj_dupedkey) + printk(" dupedkey = %08x", + (u_int)rn->rj_dupedkey); +*/ + } + printk("\n"); + } +} + +#ifdef RJ_DEBUG +DEBUG_NO_STATIC void traverse(struct radij_node *p) +{ + rj_preorder(p, 0); +} +#endif /* RJ_DEBUG */ + +void +rj_dumptrees(void) +{ + rj_preorder(rnh->rnh_treetop, 0); +} + +void +rj_free_mkfreelist(void) +{ + struct radij_mask *mknp, *mknp2; + + mknp = rj_mkfreelist; + while(mknp) + { + mknp2 = mknp; + mknp = mknp->rm_mklist; + kfree(mknp2); + } +} + +int +radijcleartree(void) +{ + return rj_walktree(rnh, ipsec_rj_walker_delete, NULL); +} + +int +radijcleanup(void) +{ + int error = 0; + + error = radijcleartree(); + + rj_free_mkfreelist(); + +/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */ + if(mask_rjhead) { + kfree(mask_rjhead); + } + + if(rj_zeroes) { + kfree(rj_zeroes); + } + + if(rnh) { + kfree(rnh); + } + + return error; +} + +/* + * $Log: radij.c,v $ + * Revision 1.5 2003/12/04 02:53:24 ken + * Remove unsafe 64bit printk() + * + * Revision 1.4 2003/11/19 02:29:41 mcr + * renamed freeswan.h -> openswan.h and libfreeswan -> libopenswan. + * + * Revision 1.3 2003/01/19 22:32:30 ken + * X.509 0.9.19 -> 0.9.20 + * + * Revision 1.2 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.1.1.1 2002/09/05 03:13:18 ken + * 1.98b + * + * Revision 1.40 2002/01/29 17:17:58 mcr + * moved include of ipsec_param.h to after include of linux/kernel.h + * otherwise, it seems that some option that is set in ipsec_param.h + * screws up something subtle in the include path to kernel.h, and + * it complains on the snprintf() prototype. + * + * Revision 1.39 2002/01/29 04:00:55 mcr + * more excise of kversions.h header. + * + * Revision 1.38 2002/01/29 02:13:19 mcr + * introduction of ipsec_kversion.h means that include of + * ipsec_param.h must preceed any decisions about what files to + * include to deal with differences in kernel source. + * + * Revision 1.37 2001/10/18 04:45:23 rgb + * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h, + * lib/freeswan.h version macros moved to lib/kversions.h. + * Other compiler directive cleanups. + * + * Revision 1.36 2001/08/22 13:43:51 henry + * eliminate the single use of min() to avoid problems with Linus changing it + * + * Revision 1.35 2001/06/15 04:57:29 rgb + * Clarified error return codes. + * Changed mask add already exists to EEXIST. + * Changed mask delete did not exist to ENOENT. + * + * Revision 1.34 2001/05/03 19:44:26 rgb + * Fix sign of error return codes for rj_addroute(). + * + * Revision 1.33 2001/02/27 22:24:56 rgb + * Re-formatting debug output (line-splitting, joining, 1arg/line). + * Check for satoa() return codes. + * + * Revision 1.32 2001/02/27 06:23:15 rgb + * Debug line splitting. + * + * Revision 1.31 2000/11/06 04:35:21 rgb + * Clear table *before* releasing other items in radijcleanup. + * + * Revision 1.30 2000/09/20 04:07:40 rgb + * Changed static functions to DEBUG_NO_STATIC to reveal function names in + * oopsen. + * + * Revision 1.29 2000/09/12 03:25:02 rgb + * Moved radij_c_version printing to ipsec_version_get_info(). + * + * Revision 1.28 2000/09/08 19:12:56 rgb + * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG. + * + * Revision 1.27 2000/07/28 14:58:32 rgb + * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5. + * + * Revision 1.26 2000/05/10 23:11:37 rgb + * Comment out most of the startup version information. + * + * Revision 1.25 2000/01/21 06:21:47 rgb + * Change return codes to negative on error. + * + * Revision 1.24 1999/11/18 04:09:20 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.23 1999/11/17 15:53:41 rgb + * Changed all occurrences of #include "../../../lib/freeswan.h" + * to #include which works due to -Ilibfreeswan in the + * klips/net/ipsec/Makefile. + * + * Revision 1.22 1999/10/15 22:17:28 rgb + * Modify radijcleanup() to call radijcleartree(). + * + * Revision 1.21 1999/10/08 18:37:34 rgb + * Fix end-of-line spacing to sate whining PHMs. + * + * Revision 1.20 1999/10/01 15:44:54 rgb + * Move spinlock header include to 2.1> scope. + * + * Revision 1.19 1999/10/01 08:35:52 rgb + * Add spinlock include to shut up compiler for 2.0.38. + * + * Revision 1.18 1999/09/23 18:02:52 rgb + * De-alarm the search failure message so it doesn't sound so grave. + * + * Revision 1.17 1999/05/25 21:26:01 rgb + * Fix rj_walktree() sanity checking bug. + * + * Revision 1.16 1999/05/09 03:25:38 rgb + * Fix bug introduced by 2.2 quick-and-dirty patch. + * + * Revision 1.15 1999/05/05 22:02:33 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.14 1999/04/29 15:24:15 rgb + * Add sanity checking for null pointer arguments. + * Standardise an error return method. + * + * Revision 1.13 1999/04/11 00:29:02 henry + * GPL boilerplate + * + * Revision 1.12 1999/04/06 04:54:28 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.11 1999/02/17 16:52:53 rgb + * Convert DEBUG_IPSEC to KLIPS_PRINT + * Clean out unused cruft. + * + * Revision 1.10 1999/01/22 06:30:05 rgb + * Cruft clean-out. + * 64-bit clean-up. + * + * Revision 1.9 1998/12/01 13:22:04 rgb + * Added support for debug printing of version info. + * + * Revision 1.8 1998/11/30 13:22:55 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.7 1998/10/25 02:43:26 rgb + * Change return type on rj_addroute and rj_delete and add and argument + * to the latter to be able to transmit more infomation about errors. + * + * Revision 1.6 1998/10/19 14:30:06 rgb + * Added inclusion of freeswan.h. + * + * Revision 1.5 1998/10/09 04:33:27 rgb + * Added 'klips_debug' prefix to all klips printk debug statements. + * Fixed output formatting slightly. + * + * Revision 1.4 1998/07/28 00:06:59 rgb + * Add debug detail to tree traversing. + * + * Revision 1.3 1998/07/14 18:07:58 rgb + * Add a routine to clear the eroute tree. + * + * Revision 1.2 1998/06/25 20:03:22 rgb + * Cleanup #endif comments. Debug output for rj_init. + * + * Revision 1.1 1998/06/18 21:30:22 henry + * move sources from klips/src to klips/net/ipsec to keep stupid kernel + * build scripts happier about symlinks + * + * Revision 1.8 1998/05/25 20:34:15 rgb + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. + * + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and + * add ipsec_rj_walker_delete. + * + * Recover memory for eroute table on unload of module. + * + * Revision 1.7 1998/05/21 12:58:58 rgb + * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix. + * + * Revision 1.6 1998/04/23 20:57:29 rgb + * Cleaned up compiler warnings for unused debugging functions. + * + * Revision 1.5 1998/04/22 16:51:38 rgb + * Tidy up radij debug code from recent rash of modifications to debug code. + * + * Revision 1.4 1998/04/21 21:28:56 rgb + * Rearrange debug switches to change on the fly debug output from user + * space. Only kernel changes checked in at this time. radij.c was also + * changed to temporarily remove buggy debugging code in rj_delete causing + * an OOPS and hence, netlink device open errors. + * + * Revision 1.3 1998/04/14 17:30:37 rgb + * Fix up compiling errors for radij tree memory reclamation. + * + * Revision 1.2 1998/04/12 22:03:25 rgb + * Updated ESP-3DES-HMAC-MD5-96, + * ESP-DES-HMAC-MD5-96, + * AH-HMAC-MD5-96, + * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository + * from old standards (RFC182[5-9] to new (as of March 1998) drafts. + * + * Fixed eroute references in /proc/net/ipsec*. + * + * Started to patch module unloading memory leaks in ipsec_netlink and + * radij tree unloading. + * + * Revision 1.1 1998/04/09 03:06:15 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:03 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:39:04 ji + * Minor cleanups. + * Rationalized debugging code. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/radij.h linux-2.4.29-openswan-1.0.9/net/ipsec/radij.h --- linux-2.4.29/net/ipsec/radij.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/radij.h Sun Jan 19 23:32:30 2003 @@ -0,0 +1,283 @@ +/* + * RCSID $Id: radij.h,v 1.3 2003/01/19 22:32:30 ken Exp $ + */ + +/* + * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite + * + * Variable and procedure names have been modified so that they don't + * conflict with the original BSD code, as a small number of modifications + * have been introduced and we may want to reuse this code in BSD. + * + * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek + * chi or a German ch sound (as `doch', not as in `milch'), or even a + * spanish j as in Juan. It is not as far back in the throat like + * the corresponding Hebrew sound, nor is it a soft breath like the English h. + * It has nothing to do with the Dutch ij sound. + * + * Here is the appropriate copyright notice: + */ + +/* + * Copyright (c) 1988, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)radix.h 8.1 (Berkeley) 6/10/93 + */ + +#ifndef _RADIJ_H_ +#define _RADIJ_H_ + +/* +#define RJ_DEBUG +*/ + +#ifdef __KERNEL__ + +#ifndef __P +#ifdef __STDC__ +#define __P(x) x +#else +#define __P(x) () +#endif +#endif + +/* + * Radix search tree node layout. + */ + +struct radij_node +{ + struct radij_mask *rj_mklist; /* list of masks contained in subtree */ + struct radij_node *rj_p; /* parent */ + short rj_b; /* bit offset; -1-index(netmask) */ + char rj_bmask; /* node: mask for bit test*/ + u_char rj_flags; /* enumerated next */ +#define RJF_NORMAL 1 /* leaf contains normal route */ +#define RJF_ROOT 2 /* leaf is root leaf for tree */ +#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */ + union { + struct { /* leaf only data: */ + caddr_t rj_Key; /* object of search */ + caddr_t rj_Mask; /* netmask, if present */ + struct radij_node *rj_Dupedkey; + } rj_leaf; + struct { /* node only data: */ + int rj_Off; /* where to start compare */ + struct radij_node *rj_L;/* progeny */ + struct radij_node *rj_R;/* progeny */ + }rj_node; + } rj_u; +#ifdef RJ_DEBUG + int rj_info; + struct radij_node *rj_twin; + struct radij_node *rj_ybro; +#endif +}; + +#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey +#define rj_key rj_u.rj_leaf.rj_Key +#define rj_mask rj_u.rj_leaf.rj_Mask +#define rj_off rj_u.rj_node.rj_Off +#define rj_l rj_u.rj_node.rj_L +#define rj_r rj_u.rj_node.rj_R + +/* + * Annotations to tree concerning potential routes applying to subtrees. + */ + +extern struct radij_mask { + short rm_b; /* bit offset; -1-index(netmask) */ + char rm_unused; /* cf. rj_bmask */ + u_char rm_flags; /* cf. rj_flags */ + struct radij_mask *rm_mklist; /* more masks to try */ + caddr_t rm_mask; /* the mask */ + int rm_refs; /* # of references to this struct */ +} *rj_mkfreelist; + +#define MKGet(m) {\ + if (rj_mkfreelist) {\ + m = rj_mkfreelist; \ + rj_mkfreelist = (m)->rm_mklist; \ + } else \ + R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\ + +#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);} + +struct radij_node_head { + struct radij_node *rnh_treetop; + int rnh_addrsize; /* permit, but not require fixed keys */ + int rnh_pktsize; /* permit, but not require fixed keys */ +#if 0 + struct radij_node *(*rnh_addaddr) /* add based on sockaddr */ + __P((void *v, void *mask, + struct radij_node_head *head, struct radij_node nodes[])); +#endif + int (*rnh_addaddr) /* add based on sockaddr */ + __P((void *v, void *mask, + struct radij_node_head *head, struct radij_node nodes[])); + struct radij_node *(*rnh_addpkt) /* add based on packet hdr */ + __P((void *v, void *mask, + struct radij_node_head *head, struct radij_node nodes[])); +#if 0 + struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */ + __P((void *v, void *mask, struct radij_node_head *head)); +#endif + int (*rnh_deladdr) /* remove based on sockaddr */ + __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node)); + struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */ + __P((void *v, void *mask, struct radij_node_head *head)); + struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */ + __P((void *v, struct radij_node_head *head)); + struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */ + __P((void *v, struct radij_node_head *head)); + int (*rnh_walktree) /* traverse tree */ + __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w)); + struct radij_node rnh_nodes[3]; /* empty tree for common case */ +}; + + +#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n)) +#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n)) +#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n)) +#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n))) +#define Free(p) kfree((caddr_t)p); + +void rj_init __P((void)); +int rj_inithead __P((void **, int)); +int rj_refines __P((void *, void *)); +int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w)); +struct radij_node + *rj_addmask __P((void *, int, int)) /* , rgb */ ; +int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *, + struct radij_node [2])) /* , rgb */ ; +int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ; +struct radij_node /* rgb */ + *rj_insert __P((void *, struct radij_node_head *, int *, + struct radij_node [2])), + *rj_match __P((void *, struct radij_node_head *)), + *rj_newpair __P((void *, int, struct radij_node[2])), + *rj_search __P((void *, struct radij_node *)), + *rj_search_m __P((void *, struct radij_node *, void *)); + +void rj_deltree(struct radij_node_head *); +void rj_delnodes(struct radij_node *); +void rj_free_mkfreelist(void); +int radijcleartree(void); +int radijcleanup(void); + +extern struct radij_node_head *mask_rjhead; +extern int maj_keylen; +#endif /* __KERNEL__ */ + +#endif /* _RADIJ_H_ */ + + +/* + * $Log: radij.h,v $ + * Revision 1.3 2003/01/19 22:32:30 ken + * X.509 0.9.19 -> 0.9.20 + * + * Revision 1.2 2002/12/12 03:32:07 ken + * Upgraded to X.509 0.9.16 w/manual merges for NAT-T support + * + * Revision 1.1.1.1 2002/09/05 03:13:18 ken + * 1.98b + * + * Revision 1.11 2001/09/20 15:33:00 rgb + * Min/max cleanup. + * + * Revision 1.10 1999/11/18 04:09:20 rgb + * Replaced all kernel version macros to shorter, readable form. + * + * Revision 1.9 1999/05/05 22:02:33 rgb + * Add a quick and dirty port to 2.2 kernels by Marc Boucher . + * + * Revision 1.8 1999/04/29 15:24:58 rgb + * Add check for existence of macros min/max. + * + * Revision 1.7 1999/04/11 00:29:02 henry + * GPL boilerplate + * + * Revision 1.6 1999/04/06 04:54:29 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + * Revision 1.5 1999/01/22 06:30:32 rgb + * 64-bit clean-up. + * + * Revision 1.4 1998/11/30 13:22:55 rgb + * Rationalised all the klips kernel file headers. They are much shorter + * now and won't conflict under RH5.2. + * + * Revision 1.3 1998/10/25 02:43:27 rgb + * Change return type on rj_addroute and rj_delete and add and argument + * to the latter to be able to transmit more infomation about errors. + * + * Revision 1.2 1998/07/14 18:09:51 rgb + * Add a routine to clear eroute table. + * Added #ifdef __KERNEL__ directives to restrict scope of header. + * + * Revision 1.1 1998/06/18 21:30:22 henry + * move sources from klips/src to klips/net/ipsec to keep stupid kernel + * build scripts happier about symlinks + * + * Revision 1.4 1998/05/25 20:34:16 rgb + * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions. + * + * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and + * add ipsec_rj_walker_delete. + * + * Recover memory for eroute table on unload of module. + * + * Revision 1.3 1998/04/22 16:51:37 rgb + * Tidy up radij debug code from recent rash of modifications to debug code. + * + * Revision 1.2 1998/04/14 17:30:38 rgb + * Fix up compiling errors for radij tree memory reclamation. + * + * Revision 1.1 1998/04/09 03:06:16 henry + * sources moved up from linux/net/ipsec + * + * Revision 1.1.1.1 1998/04/08 05:35:04 henry + * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8 + * + * Revision 0.4 1997/01/15 01:28:15 ji + * No changes. + * + * Revision 0.3 1996/11/20 14:44:45 ji + * Release update only. + * + * Revision 0.2 1996/11/02 00:18:33 ji + * First limited release. + * + * + */ diff -urN linux-2.4.29/net/ipsec/sysctl_net_ipsec.c linux-2.4.29-openswan-1.0.9/net/ipsec/sysctl_net_ipsec.c --- linux-2.4.29/net/ipsec/sysctl_net_ipsec.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/sysctl_net_ipsec.c Thu Sep 5 05:13:18 2002 @@ -0,0 +1,190 @@ +/* + * sysctl interface to net IPSEC subsystem. + * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * RCSID $Id: sysctl_net_ipsec.c,v 1.1.1.1 2002/09/05 03:13:18 ken Exp $ + */ + +/* -*- linux-c -*- + * + * Initiated April 3, 1998, Richard Guy Briggs + */ + +#include +#include + +#include "ipsec_param.h" + +#ifdef CONFIG_SYSCTL + +#define NET_IPSEC 2112 /* Random number */ +#ifdef CONFIG_IPSEC_DEBUG +extern int debug_ah; +extern int debug_esp; +extern int debug_tunnel; +extern int debug_eroute; +extern int debug_spi; +extern int debug_radij; +extern int debug_netlink; +extern int debug_xform; +extern int debug_rcv; +extern int debug_pfkey; +extern int sysctl_ipsec_debug_verbose; +#ifdef CONFIG_IPSEC_IPCOMP +extern int sysctl_ipsec_debug_ipcomp; +#endif /* CONFIG_IPSEC_IPCOMP */ +#endif /* CONFIG_IPSEC_DEBUG */ + +extern int sysctl_ipsec_icmp; +extern int sysctl_ipsec_inbound_policy_check; +extern int sysctl_ipsec_tos; +int sysctl_ipsec_regress_pfkey_lossage; + +enum { +#ifdef CONFIG_IPSEC_DEBUG + NET_IPSEC_DEBUG_AH=1, + NET_IPSEC_DEBUG_ESP=2, + NET_IPSEC_DEBUG_TUNNEL=3, + NET_IPSEC_DEBUG_EROUTE=4, + NET_IPSEC_DEBUG_SPI=5, + NET_IPSEC_DEBUG_RADIJ=6, + NET_IPSEC_DEBUG_NETLINK=7, + NET_IPSEC_DEBUG_XFORM=8, + NET_IPSEC_DEBUG_RCV=9, + NET_IPSEC_DEBUG_PFKEY=10, + NET_IPSEC_DEBUG_VERBOSE=11, + NET_IPSEC_DEBUG_IPCOMP=12, +#endif /* CONFIG_IPSEC_DEBUG */ + NET_IPSEC_ICMP=13, + NET_IPSEC_INBOUND_POLICY_CHECK=14, + NET_IPSEC_TOS=15, + NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16, +}; + +static ctl_table ipsec_table[] = { +#ifdef CONFIG_IPSEC_DEBUG + { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose, + sizeof(int), 0644, NULL, &proc_dointvec}, +#ifdef CONFIG_IPSEC_IPCOMP + { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp, + sizeof(int), 0644, NULL, &proc_dointvec}, +#endif /* CONFIG_IPSEC_IPCOMP */ + +#ifdef CONFIG_IPSEC_REGRESS + { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage", + &sysctl_ipsec_regress_pfkey_lossage, + sizeof(int), 0644, NULL, &proc_dointvec}, +#endif /* CONFIG_IPSEC_REGRESS */ + +#endif /* CONFIG_IPSEC_DEBUG */ + { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check, + sizeof(int), 0644, NULL, &proc_dointvec}, + { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos, + sizeof(int), 0644, NULL, &proc_dointvec}, + {0} +}; + +static ctl_table ipsec_net_table[] = { + { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table }, + { 0 } +}; + +static ctl_table ipsec_root_table[] = { + { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table }, + { 0 } +}; + +static struct ctl_table_header *ipsec_table_header; + +int ipsec_sysctl_register(void) +{ + ipsec_table_header = register_sysctl_table(ipsec_root_table, 0); + if (!ipsec_table_header) { + return -ENOMEM; + } + return 0; +} + +void ipsec_sysctl_unregister(void) +{ + unregister_sysctl_table(ipsec_table_header); +} + +#endif /* CONFIG_SYSCTL */ + +/* + * $Log: sysctl_net_ipsec.c,v $ + * Revision 1.1.1.1 2002/09/05 03:13:18 ken + * 1.98b + * + * Revision 1.13 2002/01/12 02:58:32 mcr + * first regression test causes acquire messages to be lost + * 100% of the time. This is to help testing of pluto. + * + * Revision 1.12 2001/06/14 19:35:13 rgb + * Update copyright date. + * + * Revision 1.11 2001/02/26 19:58:13 rgb + * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs. + * + * Revision 1.10 2000/09/16 01:50:15 rgb + * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the + * linker won't blame rj_delete() for missing symbols. ;-> Damn statics... + * + * Revision 1.9 2000/09/15 23:17:51 rgb + * Moved stuff around to compile with debug off. + * + * Revision 1.8 2000/09/15 11:37:02 rgb + * Merge in heavily modified Svenning Soerensen's + * IPCOMP zlib deflate code. + * + * Revision 1.7 2000/09/15 07:37:15 rgb + * Munged silly log comment that was causing a warning. + * + * Revision 1.6 2000/09/15 04:58:23 rgb + * Added tos runtime switch. + * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames. + * + * Revision 1.5 2000/09/12 03:25:28 rgb + * Filled in and implemented sysctl. + * + * Revision 1.4 1999/04/11 00:29:03 henry + * GPL boilerplate + * + * Revision 1.3 1999/04/06 04:54:29 rgb + * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes + * patch shell fixes. + * + */ diff -urN linux-2.4.29/net/ipsec/zlib/Makefile linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/Makefile --- linux-2.4.29/net/ipsec/zlib/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/Makefile Thu Sep 5 05:13:22 2002 @@ -0,0 +1,112 @@ +# (kernel) Makefile for IPCOMP zlib deflate code +# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs. +# Copyright (C) 2000 Svenning Soerensen +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See . +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# RCSID $Id: Makefile,v 1.1.1.1 2002/09/05 03:13:22 ken Exp $ +# + + + +include ../Makefile.inc + + + +ifndef TOPDIR +TOPDIR := /usr/src/linux +endif + + +L_TARGET := zlib.a +obj-y := adler32.o deflate.o infblock.o infcodes.o inffast.o inflate.o inftrees.o infutil.o trees.o zutil.o + +EXTRA_CFLAGS += $(KLIPSCOMPILE) + +EXTRA_CFLAGS += -Wall +#EXTRA_CFLAGS += -Wconversion +#EXTRA_CFLAGS += -Wmissing-prototypes +EXTRA_CFLAGS += -Wpointer-arith +#EXTRA_CFLAGS += -Wcast-qual +#EXTRA_CFLAGS += -Wmissing-declarations +EXTRA_CFLAGS += -Wstrict-prototypes +#EXTRA_CFLAGS += -pedantic +#EXTRA_CFLAGS += -W +#EXTRA_CFLAGS += -Wwrite-strings +EXTRA_CFLAGS += -Wbad-function-cast +EXTRA_CFLAGS += -DIPCOMP_PREFIX + +.S.o: + $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o + +asm-obj-$(CONFIG_M586) += match586.o +asm-obj-$(CONFIG_M586TSC) += match586.o +asm-obj-$(CONFIG_M586MMX) += match586.o +asm-obj-$(CONFIG_M686) += match686.o +asm-obj-$(CONFIG_MPENTIUMIII) += match686.o +asm-obj-$(CONFIG_MPENTIUM4) += match686.o +asm-obj-$(CONFIG_MK6) += match586.o +asm-obj-$(CONFIG_MK7) += match686.o +asm-obj-$(CONFIG_MCRUSOE) += match586.o +asm-obj-$(CONFIG_MWINCHIPC6) += match586.o +asm-obj-$(CONFIG_MWINCHIP2) += match686.o +asm-obj-$(CONFIG_MWINCHIP3D) += match686.o + +obj-y += $(asm-obj-y) +ifneq ($(strip $(asm-obj-y)),) + EXTRA_CFLAGS += -DASMV +endif + +active-objs := $(sort $(obj-y) $(obj-m)) +L_OBJS := $(obj-y) +M_OBJS := $(obj-m) +MIX_OBJS := $(filter $(export-objs), $(active-objs)) + +include $(TOPDIR)/Rules.make + +$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h + + +clean: + -rm -f *.o *.a + +checkprograms: +programs: $(L_TARGET) + +# +# $Log: Makefile,v $ +# Revision 1.1.1.1 2002/09/05 03:13:22 ken +# 1.98b +# +# Revision 1.7 2002/03/27 23:34:35 mcr +# added programs: target +# +# Revision 1.6 2001/12/05 20:19:08 henry +# use new compile-control variable +# +# Revision 1.5 2001/11/27 16:38:08 mcr +# added new "checkprograms" target to deal with programs that +# are required for "make check", but that may not be ready to +# build for every user due to external dependancies. +# +# Revision 1.4 2001/10/24 14:46:24 henry +# Makefile.inc +# +# Revision 1.3 2001/04/21 23:05:24 rgb +# Update asm directives for 2.4 style makefiles. +# +# Revision 1.2 2001/01/29 22:22:00 rgb +# Convert to 2.4 new style with back compat. +# +# Revision 1.1.1.1 2000/09/29 18:51:33 rgb +# zlib_beginnings +# +# diff -urN linux-2.4.29/net/ipsec/zlib/adler32.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/adler32.c --- linux-2.4.29/net/ipsec/zlib/adler32.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/adler32.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,48 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: adler32.c,v 1.1.1.1 2002/09/05 03:13:22 ken Exp $ */ + +#include "zlib.h" + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff -urN linux-2.4.29/net/ipsec/zlib/deflate.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/deflate.c --- linux-2.4.29/net/ipsec/zlib/deflate.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/deflate.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,1351 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in ftp://ds.internic.net/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id: deflate.c,v 1.1.1.1 2002/09/05 03:13:22 ken Exp $ */ + +#include "deflate.h" + +local const char deflate_copyright[] = + " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +local block_state deflate_slow OF((deflate_state *s, int flush)); +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */ + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int noheader = 0; + static const char* my_version = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == Z_NULL) { + return Z_STREAM_ERROR; +/* strm->zalloc = zcalloc; + strm->opaque = (voidpf)0;*/ + } + if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */ + + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#ifdef FASTEST + level = 1; +#endif + + if (windowBits < 0) { /* undocumented feature: suppress zlib header */ + noheader = 1; + windowBits = -windowBits; + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 9 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->noheader = noheader; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + strm->msg = ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->status != INIT_STATE) return Z_STREAM_ERROR; + + s = strm->state; + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); +#ifndef USE_DICT_HEAD + dictionary += dictLength - length; /* use the tail of the dictionary */ +#endif + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->noheader < 0) { + s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */ + } + s->status = s->noheader ? BUSY_STATE : INIT_STATE; + strm->adler = 1; + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + + if (level == Z_DEFAULT_COMPRESSION) { + level = 6; + } + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the zlib header */ + if (s->status == INIT_STATE) { + + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags = (s->level-1) >> 1; + + if (level_flags > 3) level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = 1L; + } + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUFF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->noheader) return Z_STREAM_END; + + /* Write the zlib trailer (adler32) */ + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + s->noheader = -1; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + *dest = *source; + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + *ds = *ss; + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (!strm->state->noheader) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +} + +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +#ifndef FASTEST +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} + +#else /* FASTEST */ +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 only + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return len <= s->lookahead ? len : s->lookahead; +} +#endif /* FASTEST */ +#endif /* ASMV */ + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if strstart == 0 + * and lookahead == 1 (input done one byte at time) + */ + more--; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + } else if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in hash table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy != Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } + /* longest_match() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED || + (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR))) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} diff -urN linux-2.4.29/net/ipsec/zlib/deflate.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/deflate.h --- linux-2.4.29/net/ipsec/zlib/deflate.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/deflate.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,318 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: deflate.h,v 1.1.1.1 2002/09/05 03:13:22 ken Exp $ */ + +#ifndef _DEFLATE_H +#define _DEFLATE_H + +#include "zutil.h" + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + int noheader; /* suppress zlib header and adler32 */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* _DEFLATE_H */ diff -urN linux-2.4.29/net/ipsec/zlib/infblock.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infblock.c --- linux-2.4.29/net/ipsec/zlib/infblock.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infblock.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,403 @@ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* Table for deflate from PKZIP's appnote.txt. */ +local const uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +void inflate_blocks_reset(s, z, c) +inflate_blocks_statef *s; +z_streamp z; +uLongf *c; +{ + if (c != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens); + if (s->mode == CODES) + inflate_codes_free(s->sub.decode.codes, z); + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); + Tracev((stderr, "inflate: blocks reset\n")); +} + + +inflate_blocks_statef *inflate_blocks_new(z, c, w) +z_streamp z; +check_func c; +uInt w; +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->hufts = + (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) + { + ZFREE(z, s); + return Z_NULL; + } + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s->hufts); + ZFREE(z, s); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Tracev((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, Z_NULL); + return s; +} + + +int inflate_blocks(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Tracev((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Tracev((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td, z); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BAD; + z->msg = (char*)"invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) + { + s->mode = BAD; + z->msg = (char*)"invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BAD; + z->msg = (char*)"too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, s->hufts, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->bits; + c = h->base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + z->msg = (char*)"invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, + s->hufts, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + { + ZFREE(z, s->sub.trees.blens); + s->mode = BAD; + } + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.codes = c; + } + ZFREE(z, s->sub.trees.blens); + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONE; + case DONE: + r = Z_STREAM_END; + LEAVE + case BAD: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +int inflate_blocks_free(s, z) +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_blocks_reset(s, z, Z_NULL); + ZFREE(z, s->window); + ZFREE(z, s->hufts); + ZFREE(z, s); + Tracev((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + + +void inflate_set_dictionary(s, d, n) +inflate_blocks_statef *s; +const Bytef *d; +uInt n; +{ + zmemcpy(s->window, d, n); + s->read = s->write = s->window + n; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. + * IN assertion: s != Z_NULL + */ +int inflate_blocks_sync_point(s) +inflate_blocks_statef *s; +{ + return s->mode == LENS; +} diff -urN linux-2.4.29/net/ipsec/zlib/infblock.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infblock.h --- linux-2.4.29/net/ipsec/zlib/infblock.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infblock.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,39 @@ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +extern inflate_blocks_statef * inflate_blocks_new OF(( + z_streamp z, + check_func c, /* check function */ + uInt w)); /* window size */ + +extern int inflate_blocks OF(( + inflate_blocks_statef *, + z_streamp , + int)); /* initial return code */ + +extern void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_streamp , + uLongf *)); /* check value on output */ + +extern int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_streamp)); + +extern void inflate_set_dictionary OF(( + inflate_blocks_statef *s, + const Bytef *d, /* dictionary */ + uInt n)); /* dictionary length */ + +extern int inflate_blocks_sync_point OF(( + inflate_blocks_statef *s)); diff -urN linux-2.4.29/net/ipsec/zlib/infcodes.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infcodes.c --- linux-2.4.29/net/ipsec/zlib/infcodes.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infcodes.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,251 @@ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ +inflate_codes_mode; + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + inflate_codes_mode mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +z_streamp z; +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +int inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t + t->base; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = (char*)"invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ + f = q - c->sub.copy.dist; + while (f < s->window) /* modulo window size-"while" instead */ + f += s->end - s->window; /* of "if" handles invalid distances */ + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +void inflate_codes_free(c, z) +inflate_codes_statef *c; +z_streamp z; +{ + ZFREE(z, c); + Tracev((stderr, "inflate: codes free\n")); +} diff -urN linux-2.4.29/net/ipsec/zlib/infcodes.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infcodes.h --- linux-2.4.29/net/ipsec/zlib/infcodes.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infcodes.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,31 @@ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFCODES_H +#define _INFCODES_H + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +extern inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_streamp )); + +extern int inflate_codes OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +extern void inflate_codes_free OF(( + inflate_codes_statef *, + z_streamp )); + +#endif /* _INFCODES_H */ diff -urN linux-2.4.29/net/ipsec/zlib/inffast.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inffast.c --- linux-2.4.29/net/ipsec/zlib/inffast.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inffast.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,183 @@ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "infblock.h" +#include "infcodes.h" +#include "infutil.h" +#include "inffast.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<avail_in-n;c=(k>>3)>3:c;n+=c;p-=c;k-=c<<3;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +int inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl; +inflate_huft *td; /* need separate declaration for Borland C++ */ +inflate_blocks_statef *s; +z_streamp z; +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Bytef *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + r = q - d; + if (r < s->window) /* wrap if needed */ + { + do { + r += s->end - s->window; /* force pointer in window */ + } while (r < s->window); /* covers invalid distances */ + e = s->end - r; + if (c > e) + { + c -= e; /* wrapped copy */ + do { + *q++ = *r++; + } while (--e); + r = s->window; + do { + *q++ = *r++; + } while (--c); + } + else /* normal copy */ + { + *q++ = *r++; c--; + *q++ = *r++; c--; + do { + *q++ = *r++; + } while (--c); + } + } + else /* normal copy */ + { + *q++ = *r++; c--; + *q++ = *r++; c--; + do { + *q++ = *r++; + } while (--c); + } + break; + } + else if ((e & 64) == 0) + { + t += t->base; + e = (t += ((uInt)b & inflate_mask[e]))->exop; + } + else + { + z->msg = (char*)"invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + t += t->base; + if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = (char*)"invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} diff -urN linux-2.4.29/net/ipsec/zlib/inffast.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inffast.h --- linux-2.4.29/net/ipsec/zlib/inffast.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inffast.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,22 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFFAST_H +#define _INFFAST_H + +extern int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_streamp )); + +#endif /* _INFFAST_H */ diff -urN linux-2.4.29/net/ipsec/zlib/inffixed.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inffixed.h --- linux-2.4.29/net/ipsec/zlib/inffixed.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inffixed.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,151 @@ +/* inffixed.h -- table for decoding fixed codes + * Generated automatically by the maketree.c program + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local uInt fixed_bl = 9; +local uInt fixed_bd = 5; +local inflate_huft fixed_tl[] = { + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254}, + {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115}, + {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193}, + {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161}, + {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225}, + {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145}, + {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209}, + {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177}, + {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241}, + {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227}, + {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201}, + {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169}, + {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233}, + {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153}, + {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217}, + {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185}, + {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249}, + {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163}, + {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197}, + {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165}, + {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229}, + {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149}, + {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213}, + {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181}, + {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245}, + {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205}, + {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173}, + {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237}, + {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157}, + {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221}, + {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189}, + {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253}, + {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131}, + {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195}, + {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163}, + {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227}, + {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147}, + {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211}, + {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179}, + {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243}, + {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258}, + {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203}, + {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171}, + {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235}, + {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155}, + {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219}, + {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187}, + {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251}, + {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195}, + {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199}, + {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167}, + {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231}, + {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151}, + {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215}, + {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183}, + {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247}, + {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0}, + {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207}, + {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175}, + {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239}, + {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159}, + {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223}, + {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191}, + {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255} + }; +local inflate_huft fixed_td[] = { + {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097}, + {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385}, + {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193}, + {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577}, + {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145}, + {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577}, + {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289}, + {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577} + }; diff -urN linux-2.4.29/net/ipsec/zlib/inflate.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inflate.c --- linux-2.4.29/net/ipsec/zlib/inflate.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inflate.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,368 @@ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" + +struct inflate_blocks_state {int dummy;}; /* for buggy compilers */ + +typedef enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + DICT4, /* four dictionary check bytes to go */ + DICT3, /* three dictionary check bytes to go */ + DICT2, /* two dictionary check bytes to go */ + DICT1, /* one dictionary check byte to go */ + DICT0, /* waiting for inflateSetDictionary */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ +inflate_mode; + +/* inflate private state */ +struct internal_state { + + /* mode */ + inflate_mode mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +int ZEXPORT inflateReset(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, Z_NULL); + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + + +int ZEXPORT inflateEnd(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z); + ZFREE(z, z->state); + z->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + + +int ZEXPORT inflateInit2_(z, w, version, stream_size) +z_streamp z; +int w; +const char *version; +int stream_size; +{ + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != sizeof(z_stream)) + return Z_VERSION_ERROR; + + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; + z->msg = Z_NULL; + if (z->zalloc == Z_NULL) + { + return Z_STREAM_ERROR; +/* z->zalloc = zcalloc; + z->opaque = (voidpf)0; +*/ + } + if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */ + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Tracev((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int ZEXPORT inflateInit_(z, version, stream_size) +z_streamp z; +const char *version; +int stream_size; +{ + return inflateInit2_(z, DEF_WBITS, version, stream_size); +} + + +#define NEEDBYTE {if(z->avail_in==0)return r;r=f;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int ZEXPORT inflate(z, f) +z_streamp z; +int f; +{ + int r; + uInt b; + + if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED) + { + z->state->mode = BAD; + z->msg = (char*)"unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = (char*)"invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + b = NEXTBYTE; + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib header ok\n")); + if (!(b & PRESET_DICT)) + { + z->state->mode = BLOCKS; + break; + } + z->state->mode = DICT4; + case DICT4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = DICT3; + case DICT3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = DICT2; + case DICT2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = DICT1; + case DICT1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + z->adler = z->state->sub.check.need; + z->state->mode = DICT0; + return Z_NEED_DICT; + case DICT0: + z->state->mode = BAD; + z->msg = (char*)"need dictionary"; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_STREAM_ERROR; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r == Z_OK) + r = f; + if (r != Z_STREAM_END) + return r; + r = f; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = (char*)"incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Tracev((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } +#ifdef NEED_DUMMY_RETURN + return Z_STREAM_ERROR; /* Some dumb compilers complain without this */ +#endif +} + + +int ZEXPORT inflateSetDictionary(z, dictionary, dictLength) +z_streamp z; +const Bytef *dictionary; +uInt dictLength; +{ + uInt length = dictLength; + + if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0) + return Z_STREAM_ERROR; + + if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR; + z->adler = 1L; + + if (length >= ((uInt)1<state->wbits)) + { + length = (1<state->wbits)-1; + dictionary += dictLength - length; + } + inflate_set_dictionary(z->state->blocks, dictionary, length); + z->state->mode = BLOCKS; + return Z_OK; +} + + +int ZEXPORT inflateSync(z) +z_streamp z; +{ + uInt n; /* number of bytes to look at */ + Bytef *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != BAD) + { + z->state->mode = BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + static const Byte mark[4] = {0, 0, 0xff, 0xff}; + if (*p == mark[m]) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +} + + +/* Returns true if inflate is currently at the end of a block generated + * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH + * but removes the length bytes of the resulting empty stored block. When + * decompressing, PPP checks that at the end of input packet, inflate is + * waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(z) +z_streamp z; +{ + if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL) + return Z_STREAM_ERROR; + return inflate_blocks_sync_point(z->state->blocks); +} diff -urN linux-2.4.29/net/ipsec/zlib/inftrees.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inftrees.c --- linux-2.4.29/net/ipsec/zlib/inftrees.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inftrees.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,454 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#if !defined(BUILDFIXED) && !defined(STDC) +# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */ +#endif + +local const char inflate_copyright[] = + " inflate 1.1.4 Copyright 1995-2002 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ +struct internal_state {int dummy;}; /* for buggy compilers */ + +/* simplify the use of the inflate_huft type with some defines */ +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + const uIntf *, /* list of base values for non-simple codes */ + const uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + inflate_huft *, /* space for trees */ + uInt *, /* hufts used in space */ + uIntf * )); /* space for values */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* see note #13 above about 258 */ +local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */ + 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, 112, 112}; /* 112==invalid */ +local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local const uInt cpdext[30] = { /* Extra bits for distance codes */ + 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}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ + +local int huft_build(b, n, s, d, e, t, m, hp, hn, v) +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= 288) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +const uIntf *d; /* list of base values for non-simple codes */ +const uIntf *e; /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t; /* result: starting table */ +uIntf *m; /* maximum lookup bits, returns actual */ +inflate_huft *hp; /* space for trees */ +uInt *hn; /* hufts used in space */ +uIntf *v; /* working area: values in order of bit length */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), or Z_DATA_ERROR if the input is invalid. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + n = x[g]; /* set n to length of v */ + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = g - w; + z = z > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate new table */ + if (*hn + z > MANY) /* (note: doesn't matter for fixed) */ + return Z_DATA_ERROR; /* overflow of MANY */ + u[h] = q = hp + *hn; + *hn += z; + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + j = i >> (w - l); + r.base = (uInt)(q - u[h-1] - j); /* offset to this table */ + u[h-1][j] = r; /* connect to last table */ + } + else + *t = q; /* first table is returned result */ + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + mask = (1 << w) - 1; /* needed on HP, cc -O bug */ + while ((i & mask) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + mask = (1 << w) - 1; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +int inflate_trees_bits(c, bb, tb, hp, z) +uIntf *c; /* 19 code lengths */ +uIntf *bb; /* bits tree desired/actual depth */ +inflate_huft * FAR *tb; /* bits tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, + tb, bb, hp, &hn, v); + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR || *bb == 0) + { + z->msg = (char*)"incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +} + + +int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uIntf *c; /* that many (total) code lengths */ +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +inflate_huft *hp; /* space for trees */ +z_streamp z; /* for messages */ +{ + int r; + uInt hn = 0; /* hufts used in space */ + uIntf *v; /* work area for huft_build */ + + /* allocate work area */ + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + + /* build literal/length tree */ + r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v); + if (r != Z_OK || *bl == 0) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed literal/length tree"; + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; + } + + /* build distance tree */ + r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v); + if (r != Z_OK || (*bd == 0 && nl > 257)) + { + if (r == Z_DATA_ERROR) + z->msg = (char*)"oversubscribed distance tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + z->msg = (char*)"incomplete distance tree"; + r = Z_DATA_ERROR; + } + else if (r != Z_MEM_ERROR) + { + z->msg = (char*)"empty distance tree with lengths"; + r = Z_DATA_ERROR; + } + ZFREE(z, v); + return r; +#endif + } + + /* done */ + ZFREE(z, v); + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +#ifdef BUILDFIXED +local int fixed_built = 0; +#define FIXEDH 544 /* number of hufts used by fixed tables */ +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; +#else +#include "inffixed.h" +#endif + + +int inflate_trees_fixed(bl, bd, tl, td, z) +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +z_streamp z; /* for memory allocation */ +{ +#ifdef BUILDFIXED + /* build fixed tables if not already */ + if (!fixed_built) + { + int k; /* temporary variable */ + uInt f = 0; /* number of hufts used in fixed_mem */ + uIntf *c; /* length list for huft_build */ + uIntf *v; /* work area for huft_build */ + + /* allocate memory */ + if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + return Z_MEM_ERROR; + if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL) + { + ZFREE(z, c); + return Z_MEM_ERROR; + } + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 9; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, + fixed_mem, &f, v); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, + fixed_mem, &f, v); + + /* done */ + ZFREE(z, v); + ZFREE(z, c); + fixed_built = 1; + } +#endif + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} diff -urN linux-2.4.29/net/ipsec/zlib/inftrees.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inftrees.h --- linux-2.4.29/net/ipsec/zlib/inftrees.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/inftrees.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,63 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +#ifndef _INFTREES_H +#define _INFTREES_H + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit int's) */ + uInt base; /* literal, length base, distance base, + or table offset */ +}; + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 huft structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The actual maximum is not known, but the + value below is more than safe. */ +#define MANY 1440 + +extern int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + inflate_huft *, /* space for trees */ + z_streamp)); /* for messages */ + +extern int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_streamp)); /* for memory allocation */ + +#endif /* _INFTREES_H */ diff -urN linux-2.4.29/net/ipsec/zlib/infutil.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infutil.c --- linux-2.4.29/net/ipsec/zlib/infutil.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infutil.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,87 @@ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "infblock.h" +#include "inftrees.h" +#include "infcodes.h" +#include "infutil.h" + +struct inflate_codes_state {int dummy;}; /* for buggy compilers */ + +/* And'ing with mask[n] masks the lower n bits */ +uInt inflate_mask[17] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + + +/* copy as much as possible from the sliding window to the output area */ +int inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_streamp z; +int r; +{ + uInt n; + Bytef *p; + Bytef *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + z->adler = s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} diff -urN linux-2.4.29/net/ipsec/zlib/infutil.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infutil.h --- linux-2.4.29/net/ipsec/zlib/infutil.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/infutil.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,98 @@ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995-2002 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef _INFUTIL_H +#define _INFUTIL_H + +typedef enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONE, /* finished last block, done */ + BAD} /* got a data error--stuck here */ +inflate_block_mode; + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + inflate_block_mode mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + inflate_huft *hufts; /* single malloc for tree space */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (uInt)(qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ +extern uInt inflate_mask[17]; + +/* copy as much as possible from the sliding window to the output area */ +extern int inflate_flush OF(( + inflate_blocks_statef *, + z_streamp , + int)); + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#endif /* _INFUTIL_H */ diff -urN linux-2.4.29/net/ipsec/zlib/match586.S linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/match586.S --- linux-2.4.29/net/ipsec/zlib/match586.S Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/match586.S Thu Sep 5 05:13:22 2002 @@ -0,0 +1,357 @@ +/* match.s -- Pentium-optimized version of longest_match() + * Written for zlib 1.1.2 + * Copyright (C) 1998 Brian Raiter + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License. + */ + +#ifndef NO_UNDERLINE +#define match_init _ipcomp_match_init +#define longest_match _ipcomp_longest_match +#else +#define match_init ipcomp_match_init +#define longest_match ipcomp_longest_match +#endif + +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ + +#define wmask 0 /* local copy of s->wmask */ +#define window 4 /* local copy of s->window */ +#define windowbestlen 8 /* s->window + bestlen */ +#define chainlenscanend 12 /* high word: current chain len */ + /* low word: last bytes sought */ +#define scanstart 16 /* first two bytes of string */ +#define scanalign 20 /* dword-misalignment of string */ +#define nicematch 24 /* a good enough match size */ +#define bestlen 28 /* size of best match so far */ +#define scan 32 /* ptr to string wanting match */ + +#define LocalVarsSize (36) +/* saved ebx 36 */ +/* saved edi 40 */ +/* saved esi 44 */ +/* saved ebp 48 */ +/* return address 52 */ +#define deflatestate 56 /* the function arguments */ +#define curmatch 60 + +/* Offsets for fields in the deflate_state structure. These numbers + * are calculated from the definition of deflate_state, with the + * assumption that the compiler will dword-align the fields. (Thus, + * changing the definition of deflate_state could easily cause this + * program to crash horribly, without so much as a warning at + * compile time. Sigh.) + */ +#define dsWSize 36 +#define dsWMask 44 +#define dsWindow 48 +#define dsPrev 56 +#define dsMatchLen 88 +#define dsPrevMatch 92 +#define dsStrStart 100 +#define dsMatchStart 104 +#define dsLookahead 108 +#define dsPrevLen 112 +#define dsMaxChainLen 116 +#define dsGoodMatch 132 +#define dsNiceMatch 136 + + +.file "match.S" + +.globl match_init, longest_match + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ + +longest_match: + +/* Save registers that the compiler may be using, and adjust %esp to */ +/* make room for our stack frame. */ + + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + subl $LocalVarsSize, %esp + +/* Retrieve the function arguments. %ecx will hold cur_match */ +/* throughout the entire function. %edx will hold the pointer to the */ +/* deflate_state structure during the function's setup (before */ +/* entering the main loop). */ + + movl deflatestate(%esp), %edx + movl curmatch(%esp), %ecx + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch(%edx), %eax + movl dsLookahead(%edx), %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, nicematch(%esp) + +/* register Bytef *scan = s->window + s->strstart; */ + + movl dsWindow(%edx), %esi + movl %esi, window(%esp) + movl dsStrStart(%edx), %ebp + lea (%esi,%ebp), %edi + movl %edi, scan(%esp) + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + movl %edi, %eax + negl %eax + andl $3, %eax + movl %eax, scanalign(%esp) + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize(%edx), %eax + subl $MIN_LOOKAHEAD, %eax + subl %eax, %ebp + jg LimitPositive + xorl %ebp, %ebp +LimitPositive: + +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen(%edx), %eax + movl dsGoodMatch(%edx), %ebx + cmpl %ebx, %eax + movl dsMaxChainLen(%edx), %ebx + jl LastMatchGood + shrl $2, %ebx +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the scanend */ +/* scanend value, which it will always accompany. */ + + decl %ebx + shll $16, %ebx + +/* int best_len = s->prev_length; */ + + movl dsPrevLen(%edx), %eax + movl %eax, bestlen(%esp) + +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ + + addl %eax, %esi + movl %esi, windowbestlen(%esp) + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ + + movw (%edi), %bx + movw %bx, scanstart(%esp) + movw -1(%edi,%eax), %bx + movl %ebx, chainlenscanend(%esp) + +/* Posf *prev = s->prev; */ +/* uInt wmask = s->w_mask; */ + + movl dsPrev(%edx), %edi + movl dsWMask(%edx), %edx + mov %edx, wmask(%esp) + +/* Jump into the main loop. */ + + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + * + * Within this loop: + * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend) + * %ecx = curmatch + * %edx = curmatch & wmask + * %esi = windowbestlen - i.e., (window + bestlen) + * %edi = prev + * %ebp = limit + * + * Two optimization notes on the choice of instructions: + * + * The first instruction uses a 16-bit address, which costs an extra, + * unpairable cycle. This is cheaper than doing a 32-bit access and + * zeroing the high word, due to the 3-cycle misalignment penalty which + * would occur half the time. This also turns out to be cheaper than + * doing two separate 8-bit accesses, as the memory is so rarely in the + * L1 cache. + * + * The window buffer, however, apparently spends a lot of time in the + * cache, and so it is faster to retrieve the word at the end of the + * match string with two 8-bit loads. The instructions that test the + * word at the beginning of the match string, however, are executed + * much less frequently, and there it was cheaper to use 16-bit + * instructions, which avoided the necessity of saving off and + * subsequently reloading one of the other registers. + */ +LookupLoop: + /* 1 U & V */ + movw (%edi,%edx,2), %cx /* 2 U pipe */ + movl wmask(%esp), %edx /* 2 V pipe */ + cmpl %ebp, %ecx /* 3 U pipe */ + jbe LeaveNow /* 3 V pipe */ + subl $0x00010000, %ebx /* 4 U pipe */ + js LeaveNow /* 4 V pipe */ +LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */ + andl %ecx, %edx /* 5 V pipe */ + cmpb %bl, %al /* 6 U pipe */ + jnz LookupLoop /* 6 V pipe */ + movb (%esi,%ecx), %ah + cmpb %bh, %ah + jnz LookupLoop + movl window(%esp), %eax + movw (%eax,%ecx), %ax + cmpw scanstart(%esp), %ax + jnz LookupLoop + +/* Store the current value of chainlen. */ + + movl %ebx, chainlenscanend(%esp) + +/* Point %edi to the string under scrutiny, and %esi to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + movl window(%esp), %esi + movl scan(%esp), %edi + addl %ecx, %esi + movl scanalign(%esp), %eax + movl $(-MAX_MATCH_8), %edx + lea MAX_MATCH_8(%edi,%eax), %edi + lea MAX_MATCH_8(%esi,%eax), %esi + +/* Test the strings for equality, 8 bytes at a time. At the end, + * adjust %edx so that it is offset to the exact byte that mismatched. + * + * We already know at this point that the first three bytes of the + * strings match each other, and they can be safely passed over before + * starting the compare loop. So what this code does is skip over 0-3 + * bytes, as much as necessary in order to dword-align the %edi + * pointer. (%esi will still be misaligned three times out of four.) + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance. + */ +LoopCmps: + movl (%esi,%edx), %eax + movl (%edi,%edx), %ebx + xorl %ebx, %eax + jnz LeaveLoopCmps + movl 4(%esi,%edx), %eax + movl 4(%edi,%edx), %ebx + xorl %ebx, %eax + jnz LeaveLoopCmps4 + addl $8, %edx + jnz LoopCmps + jmp LenMaximum +LeaveLoopCmps4: addl $4, %edx +LeaveLoopCmps: testl $0x0000FFFF, %eax + jnz LenLower + addl $2, %edx + shrl $16, %eax +LenLower: subb $1, %al + adcl $0, %edx + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%edi,%edx), %eax + movl scan(%esp), %edi + subl %edi, %eax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + cmpl %ebx, %eax + jg LongerMatch + movl chainlenscanend(%esp), %ebx + movl windowbestlen(%esp), %esi + movl dsPrev(%edx), %edi + movl wmask(%esp), %edx + andl %ecx, %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: movl nicematch(%esp), %ebx + movl %eax, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + cmpl %ebx, %eax + jge LeaveNow + movl window(%esp), %esi + addl %eax, %esi + movl %esi, windowbestlen(%esp) + movl chainlenscanend(%esp), %ebx + movw -1(%edi,%eax), %bx + movl dsPrev(%edx), %edi + movl %ebx, chainlenscanend(%esp) + movl wmask(%esp), %edx + andl %ecx, %edx + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: movl deflatestate(%esp), %edx + movl $MAX_MATCH, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + movl dsLookahead(%edx), %eax + cmpl %eax, %ebx + jg LookaheadRet + movl %ebx, %eax +LookaheadRet: + +/* Restore the stack and return from whence we came. */ + + addl $LocalVarsSize, %esp + popl %ebx + popl %esi + popl %edi + popl %ebp +match_init: ret diff -urN linux-2.4.29/net/ipsec/zlib/match686.S linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/match686.S --- linux-2.4.29/net/ipsec/zlib/match686.S Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/match686.S Thu Sep 5 05:13:22 2002 @@ -0,0 +1,330 @@ +/* match.s -- Pentium-Pro-optimized version of longest_match() + * Written for zlib 1.1.2 + * Copyright (C) 1998 Brian Raiter + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License. + */ + +#ifndef NO_UNDERLINE +#define match_init _ipcomp_match_init +#define longest_match _ipcomp_longest_match +#else +#define match_init ipcomp_match_init +#define longest_match ipcomp_longest_match +#endif + +#define MAX_MATCH (258) +#define MIN_MATCH (3) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) +#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7) + +/* stack frame offsets */ + +#define chainlenwmask 0 /* high word: current chain len */ + /* low word: s->wmask */ +#define window 4 /* local copy of s->window */ +#define windowbestlen 8 /* s->window + bestlen */ +#define scanstart 16 /* first two bytes of string */ +#define scanend 12 /* last two bytes of string */ +#define scanalign 20 /* dword-misalignment of string */ +#define nicematch 24 /* a good enough match size */ +#define bestlen 28 /* size of best match so far */ +#define scan 32 /* ptr to string wanting match */ + +#define LocalVarsSize (36) +/* saved ebx 36 */ +/* saved edi 40 */ +/* saved esi 44 */ +/* saved ebp 48 */ +/* return address 52 */ +#define deflatestate 56 /* the function arguments */ +#define curmatch 60 + +/* Offsets for fields in the deflate_state structure. These numbers + * are calculated from the definition of deflate_state, with the + * assumption that the compiler will dword-align the fields. (Thus, + * changing the definition of deflate_state could easily cause this + * program to crash horribly, without so much as a warning at + * compile time. Sigh.) + */ +#define dsWSize 36 +#define dsWMask 44 +#define dsWindow 48 +#define dsPrev 56 +#define dsMatchLen 88 +#define dsPrevMatch 92 +#define dsStrStart 100 +#define dsMatchStart 104 +#define dsLookahead 108 +#define dsPrevLen 112 +#define dsMaxChainLen 116 +#define dsGoodMatch 132 +#define dsNiceMatch 136 + + +.file "match.S" + +.globl match_init, longest_match + +.text + +/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */ + +longest_match: + +/* Save registers that the compiler may be using, and adjust %esp to */ +/* make room for our stack frame. */ + + pushl %ebp + pushl %edi + pushl %esi + pushl %ebx + subl $LocalVarsSize, %esp + +/* Retrieve the function arguments. %ecx will hold cur_match */ +/* throughout the entire function. %edx will hold the pointer to the */ +/* deflate_state structure during the function's setup (before */ +/* entering the main loop). */ + + movl deflatestate(%esp), %edx + movl curmatch(%esp), %ecx + +/* uInt wmask = s->w_mask; */ +/* unsigned chain_length = s->max_chain_length; */ +/* if (s->prev_length >= s->good_match) { */ +/* chain_length >>= 2; */ +/* } */ + + movl dsPrevLen(%edx), %eax + movl dsGoodMatch(%edx), %ebx + cmpl %ebx, %eax + movl dsWMask(%edx), %eax + movl dsMaxChainLen(%edx), %ebx + jl LastMatchGood + shrl $2, %ebx +LastMatchGood: + +/* chainlen is decremented once beforehand so that the function can */ +/* use the sign flag instead of the zero flag for the exit test. */ +/* It is then shifted into the high word, to make room for the wmask */ +/* value, which it will always accompany. */ + + decl %ebx + shll $16, %ebx + orl %eax, %ebx + movl %ebx, chainlenwmask(%esp) + +/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */ + + movl dsNiceMatch(%edx), %eax + movl dsLookahead(%edx), %ebx + cmpl %eax, %ebx + jl LookaheadLess + movl %eax, %ebx +LookaheadLess: movl %ebx, nicematch(%esp) + +/* register Bytef *scan = s->window + s->strstart; */ + + movl dsWindow(%edx), %esi + movl %esi, window(%esp) + movl dsStrStart(%edx), %ebp + lea (%esi,%ebp), %edi + movl %edi, scan(%esp) + +/* Determine how many bytes the scan ptr is off from being */ +/* dword-aligned. */ + + movl %edi, %eax + negl %eax + andl $3, %eax + movl %eax, scanalign(%esp) + +/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */ +/* s->strstart - (IPos)MAX_DIST(s) : NIL; */ + + movl dsWSize(%edx), %eax + subl $MIN_LOOKAHEAD, %eax + subl %eax, %ebp + jg LimitPositive + xorl %ebp, %ebp +LimitPositive: + +/* int best_len = s->prev_length; */ + + movl dsPrevLen(%edx), %eax + movl %eax, bestlen(%esp) + +/* Store the sum of s->window + best_len in %esi locally, and in %esi. */ + + addl %eax, %esi + movl %esi, windowbestlen(%esp) + +/* register ush scan_start = *(ushf*)scan; */ +/* register ush scan_end = *(ushf*)(scan+best_len-1); */ +/* Posf *prev = s->prev; */ + + movzwl (%edi), %ebx + movl %ebx, scanstart(%esp) + movzwl -1(%edi,%eax), %ebx + movl %ebx, scanend(%esp) + movl dsPrev(%edx), %edi + +/* Jump into the main loop. */ + + movl chainlenwmask(%esp), %edx + jmp LoopEntry + +.balign 16 + +/* do { + * match = s->window + cur_match; + * if (*(ushf*)(match+best_len-1) != scan_end || + * *(ushf*)match != scan_start) continue; + * [...] + * } while ((cur_match = prev[cur_match & wmask]) > limit + * && --chain_length != 0); + * + * Here is the inner loop of the function. The function will spend the + * majority of its time in this loop, and majority of that time will + * be spent in the first ten instructions. + * + * Within this loop: + * %ebx = scanend + * %ecx = curmatch + * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask) + * %esi = windowbestlen - i.e., (window + bestlen) + * %edi = prev + * %ebp = limit + */ +LookupLoop: + andl %edx, %ecx + movzwl (%edi,%ecx,2), %ecx + cmpl %ebp, %ecx + jbe LeaveNow + subl $0x00010000, %edx + js LeaveNow +LoopEntry: movzwl -1(%esi,%ecx), %eax + cmpl %ebx, %eax + jnz LookupLoop + movl window(%esp), %eax + movzwl (%eax,%ecx), %eax + cmpl scanstart(%esp), %eax + jnz LookupLoop + +/* Store the current value of chainlen. */ + + movl %edx, chainlenwmask(%esp) + +/* Point %edi to the string under scrutiny, and %esi to the string we */ +/* are hoping to match it up with. In actuality, %esi and %edi are */ +/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */ +/* initialized to -(MAX_MATCH_8 - scanalign). */ + + movl window(%esp), %esi + movl scan(%esp), %edi + addl %ecx, %esi + movl scanalign(%esp), %eax + movl $(-MAX_MATCH_8), %edx + lea MAX_MATCH_8(%edi,%eax), %edi + lea MAX_MATCH_8(%esi,%eax), %esi + +/* Test the strings for equality, 8 bytes at a time. At the end, + * adjust %edx so that it is offset to the exact byte that mismatched. + * + * We already know at this point that the first three bytes of the + * strings match each other, and they can be safely passed over before + * starting the compare loop. So what this code does is skip over 0-3 + * bytes, as much as necessary in order to dword-align the %edi + * pointer. (%esi will still be misaligned three times out of four.) + * + * It should be confessed that this loop usually does not represent + * much of the total running time. Replacing it with a more + * straightforward "rep cmpsb" would not drastically degrade + * performance. + */ +LoopCmps: + movl (%esi,%edx), %eax + xorl (%edi,%edx), %eax + jnz LeaveLoopCmps + movl 4(%esi,%edx), %eax + xorl 4(%edi,%edx), %eax + jnz LeaveLoopCmps4 + addl $8, %edx + jnz LoopCmps + jmp LenMaximum +LeaveLoopCmps4: addl $4, %edx +LeaveLoopCmps: testl $0x0000FFFF, %eax + jnz LenLower + addl $2, %edx + shrl $16, %eax +LenLower: subb $1, %al + adcl $0, %edx + +/* Calculate the length of the match. If it is longer than MAX_MATCH, */ +/* then automatically accept it as the best possible match and leave. */ + + lea (%edi,%edx), %eax + movl scan(%esp), %edi + subl %edi, %eax + cmpl $MAX_MATCH, %eax + jge LenMaximum + +/* If the length of the match is not longer than the best match we */ +/* have so far, then forget it and return to the lookup loop. */ + + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + cmpl %ebx, %eax + jg LongerMatch + movl windowbestlen(%esp), %esi + movl dsPrev(%edx), %edi + movl scanend(%esp), %ebx + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* s->match_start = cur_match; */ +/* best_len = len; */ +/* if (len >= nice_match) break; */ +/* scan_end = *(ushf*)(scan+best_len-1); */ + +LongerMatch: movl nicematch(%esp), %ebx + movl %eax, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + cmpl %ebx, %eax + jge LeaveNow + movl window(%esp), %esi + addl %eax, %esi + movl %esi, windowbestlen(%esp) + movzwl -1(%edi,%eax), %ebx + movl dsPrev(%edx), %edi + movl %ebx, scanend(%esp) + movl chainlenwmask(%esp), %edx + jmp LookupLoop + +/* Accept the current string, with the maximum possible length. */ + +LenMaximum: movl deflatestate(%esp), %edx + movl $MAX_MATCH, bestlen(%esp) + movl %ecx, dsMatchStart(%edx) + +/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */ +/* return s->lookahead; */ + +LeaveNow: + movl deflatestate(%esp), %edx + movl bestlen(%esp), %ebx + movl dsLookahead(%edx), %eax + cmpl %eax, %ebx + jg LookaheadRet + movl %ebx, %eax +LookaheadRet: + +/* Restore the stack and return from whence we came. */ + + addl $LocalVarsSize, %esp + popl %ebx + popl %esi + popl %edi + popl %ebp +match_init: ret diff -urN linux-2.4.29/net/ipsec/zlib/trees.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/trees.c --- linux-2.4.29/net/ipsec/zlib/trees.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/trees.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,1214 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id: trees.c,v 1.1.1.1 2002/09/05 03:13:22 ken Exp $ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {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}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {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}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, const ct_data *ltree, + const ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +#define MAX(a,b) (a >= b ? a : b) +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if (tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is ascii or binary */ + if (s->data_type == Z_UNKNOWN) set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute first the block length in bytes*/ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, static_ltree, static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, s->dyn_ltree, s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + const ct_data *ltree; /* literal tree */ + const ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +local void set_data_type(s) + deflate_state *s; +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff -urN linux-2.4.29/net/ipsec/zlib/trees.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/trees.h --- linux-2.4.29/net/ipsec/zlib/trees.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/trees.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff -urN linux-2.4.29/net/ipsec/zlib/zconf.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/zconf.h --- linux-2.4.29/net/ipsec/zlib/zconf.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/zconf.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,309 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.h,v 1.1.1.1 2002/09/05 03:13:22 ken Exp $ */ + +#ifndef _ZCONF_H +#define _ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef IPCOMP_PREFIX +# define deflateInit_ ipcomp_deflateInit_ +# define deflate ipcomp_deflate +# define deflateEnd ipcomp_deflateEnd +# define inflateInit_ ipcomp_inflateInit_ +# define inflate ipcomp_inflate +# define inflateEnd ipcomp_inflateEnd +# define deflateInit2_ ipcomp_deflateInit2_ +# define deflateSetDictionary ipcomp_deflateSetDictionary +# define deflateCopy ipcomp_deflateCopy +# define deflateReset ipcomp_deflateReset +# define deflateParams ipcomp_deflateParams +# define inflateInit2_ ipcomp_inflateInit2_ +# define inflateSetDictionary ipcomp_inflateSetDictionary +# define inflateSync ipcomp_inflateSync +# define inflateSyncPoint ipcomp_inflateSyncPoint +# define inflateReset ipcomp_inflateReset +# define compress ipcomp_compress +# define compress2 ipcomp_compress2 +# define uncompress ipcomp_uncompress +# define adler32 ipcomp_adler32 +# define crc32 ipcomp_crc32 +# define get_crc_table ipcomp_get_crc_table +/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */ +# define inflate_blocks ipcomp_deflate_blocks +# define inflate_blocks_free ipcomp_deflate_blocks_free +# define inflate_blocks_new ipcomp_inflate_blocks_new +# define inflate_blocks_reset ipcomp_inflate_blocks_reset +# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point +# define inflate_set_dictionary ipcomp_inflate_set_dictionary +# define inflate_codes ipcomp_inflate_codes +# define inflate_codes_free ipcomp_inflate_codes_free +# define inflate_codes_new ipcomp_inflate_codes_new +# define inflate_fast ipcomp_inflate_fast +# define inflate_trees_bits ipcomp_inflate_trees_bits +# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic +# define inflate_trees_fixed ipcomp_inflate_trees_fixed +# define inflate_flush ipcomp_inflate_flush +# define inflate_mask ipcomp_inflate_mask +# define _dist_code _ipcomp_dist_code +# define _length_code _ipcomp_length_code +# define _tr_align _ipcomp_tr_align +# define _tr_flush_block _ipcomp_tr_flush_block +# define _tr_init _ipcomp_tr_init +# define _tr_stored_block _ipcomp_tr_stored_block +# define _tr_tally _ipcomp_tr_tally +# define zError ipcomp_zError +# define z_errmsg ipcomp_z_errmsg +# define zlibVersion ipcomp_zlibVersion +# define match_init ipcomp_match_init +# define longest_match ipcomp_longest_match +#endif + +#ifdef Z_PREFIX +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386) +# ifndef __32BIT__ +# define __32BIT__ +# endif +#endif +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#if defined(MSDOS) && !defined(__32BIT__) +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC) +# define STDC +#endif +#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__) +# ifndef STDC +# define STDC +# endif +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Old Borland C incorrectly complains about missing returns: */ +#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500) +# define NEED_DUMMY_RETURN +#endif + + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +#endif +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +# ifndef __32BIT__ +# define SMALL_MEDIUM +# define FAR _far +# endif +#endif + +/* Compile with -DZLIB_DLL for Windows DLL support */ +#if defined(ZLIB_DLL) +# if defined(_WINDOWS) || defined(WINDOWS) +# ifdef FAR +# undef FAR +# endif +# include +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR _cdecl _export +# endif +# endif +# if defined (__BORLANDC__) +# if (__BORLANDC__ >= 0x0500) && defined (WIN32) +# include +# define ZEXPORT __declspec(dllexport) WINAPI +# define ZEXPORTRVA __declspec(dllexport) WINAPIV +# else +# if defined (_Windows) && defined (__DLL__) +# define ZEXPORT _export +# define ZEXPORTVA _export +# endif +# endif +# endif +#endif + +#if defined (__BEOS__) +# if defined (ZLIB_DLL) +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +#endif + +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif +#ifndef ZEXTERN +# define ZEXTERN extern +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(MACOS) && !defined(TARGET_OS_MAC) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#ifdef HAVE_UNISTD_H +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(inflate_blocks,"INBL") +# pragma map(inflate_blocks_new,"INBLNE") +# pragma map(inflate_blocks_free,"INBLFR") +# pragma map(inflate_blocks_reset,"INBLRE") +# pragma map(inflate_codes_free,"INCOFR") +# pragma map(inflate_codes,"INCO") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_flush,"INFLU") +# pragma map(inflate_mask,"INMA") +# pragma map(inflate_set_dictionary,"INSEDI2") +# pragma map(ipcomp_inflate_copyright,"INCOPY") +# pragma map(inflate_trees_bits,"INTRBI") +# pragma map(inflate_trees_dynamic,"INTRDY") +# pragma map(inflate_trees_fixed,"INTRFI") +# pragma map(inflate_trees_free,"INTRFR") +#endif + +#endif /* _ZCONF_H */ diff -urN linux-2.4.29/net/ipsec/zlib/zlib.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/zlib.h --- linux-2.4.29/net/ipsec/zlib/zlib.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/zlib.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,893 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.1.4, March 11th, 2002 + + Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef _ZLIB_H +#define _ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.1.4" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +/* Allowed flush values; see deflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + 0.1% larger than avail_in plus 12 bytes. If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may some + introduce some output latency (reading input without producing any output) + except when forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much + output as possible to the output buffer. The flushing behavior of inflate is + not specified for values of the flush parameter other than Z_SYNC_FLUSH + and Z_FINISH, but the current implementation actually flushes as much output + as possible anyway. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + If a preset dictionary is needed at this point (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the + dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise + it sets strm->adler to the adler32 checksum of all output produced + so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or + an error code as described below. At the end of the stream, inflate() + checks that its computed adler32 checksum is equal to that saved by the + compressor and returns Z_STREAM_END only if the checksum is correct. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect + adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent + (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if no progress is possible or if there was not + enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR + case, the application may then call inflateSync to look for a good + compression block. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match). Filtered data consists mostly of small values with a + somewhat random distribution. In this case, the compression algorithm is + tuned to compress them better. The effect of Z_FILTERED is to force more + Huffman coding and less string matching; it is somewhat intermediate + between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects + the compression ratio but not the correctness of the compressed output even + if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the Adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. If a compressed stream with a larger window size is given as + input, inflate() will return with the error code Z_DATA_ERROR instead of + trying to allocate a larger window. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least 0.1% larger than + sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h". (See the description + of deflateInit2 for more information about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + const voidp buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int err)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* _ZLIB_H */ diff -urN linux-2.4.29/net/ipsec/zlib/zutil.c linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/zutil.c --- linux-2.4.29/net/ipsec/zlib/zutil.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/zutil.c Thu Sep 5 05:13:22 2002 @@ -0,0 +1,227 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zutil.c,v 1.1.1.1 2002/09/05 03:13:22 ken Exp $ */ + +#include "zutil.h" + +#define MY_ZCALLOC + +struct internal_state {int dummy;}; /* for buggy compilers */ + +#ifndef STDC +extern void exit OF((int)); +#endif + +const char *z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + +#ifdef __TURBOC__ +#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__) +/* Small and medium model in Turbo C are for now limited to near allocation + * with reduced MAX_WBITS and MAX_MEM_LEVEL + */ +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} +#endif +#endif /* __TURBOC__ */ + + +#if defined(M_I86) && !defined(__32BIT__) +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* MSC */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff -urN linux-2.4.29/net/ipsec/zlib/zutil.h linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/zutil.h --- linux-2.4.29/net/ipsec/zlib/zutil.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.29-openswan-1.0.9/net/ipsec/zlib/zutil.h Thu Sep 5 05:13:22 2002 @@ -0,0 +1,225 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: zutil.h,v 1.1.1.1 2002/09/05 03:13:22 ken Exp $ */ + +#ifndef _Z_UTIL_H +#define _Z_UTIL_H + +#include "zlib.h" + +#include +#define HAVE_MEMCPY + +#if 0 // #ifdef STDC +# include +# include +# include +#endif +#ifndef __KERNEL__ +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#ifdef MSDOS +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#ifdef WIN32 /* Window 95 & Windows NT */ +# define OS_CODE 0x0b +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0F +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# define fdopen(fd,type) _fdopen(fd,type) +#endif + + + /* Common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf, + uInt len)); +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* _Z_UTIL_H */ diff -urN linux-2.4.29/net/ipv4/af_inet.c linux-2.4.29-openswan-1.0.9/net/ipv4/af_inet.c --- linux-2.4.29/net/ipv4/af_inet.c Sun Dec 19 21:18:28 2004 +++ linux-2.4.29-openswan-1.0.9/net/ipv4/af_inet.c Sun Feb 6 16:32:39 2005 @@ -1207,6 +1207,17 @@ ip_mr_init(); #endif +#if defined(CONFIG_IPSEC) + { + extern /* void */ int ipsec_init(void); + /* + * Initialise AF_INET ESP and AH protocol support including + * e-routing and SA tables + */ + ipsec_init(); + } +#endif /* CONFIG_IPSEC */ + /* * Create all the /proc entries. */ diff -urN linux-2.4.29/net/ipv4/udp.c linux-2.4.29-openswan-1.0.9/net/ipv4/udp.c --- linux-2.4.29/net/ipv4/udp.c Mon Jan 31 22:01:10 2005 +++ linux-2.4.29-openswan-1.0.9/net/ipv4/udp.c Sun Feb 6 16:32:39 2005 @@ -860,6 +860,9 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) { +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + struct udp_opt *tp = &(sk->tp_pinfo.af_udp); +#endif /* * Charge it to the socket, dropping if the queue is full. */ @@ -877,6 +880,38 @@ } #endif +#ifdef CONFIG_IPSEC_NAT_TRAVERSAL + if (tp->esp_in_udp) { + /* + * Set skb->sk and xmit packet to ipsec_rcv. + * + * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP), + * restore skb->sk and fall back to sock_queue_rcv_skb + */ + struct inet_protocol *esp = NULL; + +#ifdef CONFIG_IPSEC_MODULE + for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)]; + (esp) && (esp->protocol != IPPROTO_ESP); + esp = esp->next); +#else + extern struct inet_protocol esp_protocol; + esp = &esp_protocol; +#endif + + if (esp && esp->handler) { + struct sock *sav_sk = skb->sk; + skb->sk = sk; + if (esp->handler(skb) == 0) { + skb->sk = sav_sk; + /* not sure we might count ESPinUDP as UDP... */ + UDP_INC_STATS_BH(UdpInDatagrams); + return 0; + } + skb->sk = sav_sk; + } + } +#endif if (sock_queue_rcv_skb(sk,skb)<0) { UDP_INC_STATS_BH(UdpInErrors); IP_INC_STATS_BH(IpInDiscards); @@ -1100,13 +1135,55 @@ return len; } +#if 1 +static int udp_setsockopt(struct sock *sk, int level, int optname, + char *optval, int optlen) +{ + struct udp_opt *tp = &(sk->tp_pinfo.af_udp); + int val; + int err = 0; + + if (level != SOL_UDP) + return ip_setsockopt(sk, level, optname, optval, optlen); + + if(optlenesp_in_udp = val; + break; +#endif + default: + err = -ENOPROTOOPT; + break; + } + + release_sock(sk); + return err; +} +#endif + struct proto udp_prot = { name: "UDP", close: udp_close, connect: udp_connect, disconnect: udp_disconnect, ioctl: udp_ioctl, +#if 1 + setsockopt: udp_setsockopt, +#else setsockopt: ip_setsockopt, +#endif getsockopt: ip_getsockopt, sendmsg: udp_sendmsg, recvmsg: udp_recvmsg,