diff -urN linux-2.4.26-rc2/Documentation/Configure.help linux-2.4.26-rc2-os-1.0.3/Documentation/Configure.help --- linux-2.4.26-rc2/Documentation/Configure.help Sun Apr 11 12:05:45 2004 +++ linux-2.4.26-rc2-os-1.0.3/Documentation/Configure.help Sun Apr 11 12:17:14 2004 @@ -6288,6 +6288,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.26-rc2/arch/i386/defconfig linux-2.4.26-rc2-os-1.0.3/arch/i386/defconfig --- linux-2.4.26-rc2/arch/i386/defconfig Sat Mar 20 10:08:17 2004 +++ linux-2.4.26-rc2-os-1.0.3/arch/i386/defconfig Sun Apr 11 12:16:33 2004 @@ -930,3 +930,135 @@ CONFIG_CRC32=y # CONFIG_ZLIB_INFLATE is not set # CONFIG_ZLIB_DEFLATE is not set + +# +# RCSID $Id: defconfig,v 1.5 2003/07/04 19:07:34 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 + +# 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.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.26-rc2/include/net/sock.h linux-2.4.26-rc2-os-1.0.3/include/net/sock.h --- linux-2.4.26-rc2/include/net/sock.h Sun Mar 28 13:51:24 2004 +++ linux-2.4.26-rc2-os-1.0.3/include/net/sock.h Sun Apr 11 12:16:33 2004 @@ -256,6 +256,12 @@ __u32 end_seq; }; +#if 1 +struct udp_opt { + __u32 esp_in_udp; +}; +#endif + struct tcp_opt { int tcp_header_len; /* Bytes of tcp header to send */ @@ -614,6 +620,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.26-rc2/net/Config.in linux-2.4.26-rc2-os-1.0.3/net/Config.in --- linux-2.4.26-rc2/net/Config.in Sat Dec 6 08:14:52 2003 +++ linux-2.4.26-rc2-os-1.0.3/net/Config.in Sun Apr 11 12:16:33 2004 @@ -102,4 +102,9 @@ tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN 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.26-rc2/net/Makefile linux-2.4.26-rc2-os-1.0.3/net/Makefile --- linux-2.4.26-rc2/net/Makefile Sat Mar 20 10:08:21 2004 +++ linux-2.4.26-rc2-os-1.0.3/net/Makefile Sun Apr 11 12:16:33 2004 @@ -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.26-rc2/net/ipsec/Config.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/Config.in --- linux-2.4.26-rc2/net/ipsec/Config.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/Makefile linux-2.4.26-rc2-os-1.0.3/net/ipsec/Makefile --- linux-2.4.26-rc2/net/ipsec/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/Makefile.inc linux-2.4.26-rc2-os-1.0.3/net/ipsec/Makefile.inc --- linux-2.4.26-rc2/net/ipsec/Makefile.inc Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/Makefile.ver linux-2.4.26-rc2-os-1.0.3/net/ipsec/Makefile.ver --- linux-2.4.26-rc2/net/ipsec/Makefile.ver Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/net/ipsec/Makefile.ver Sat Apr 3 18:42:43 2004 @@ -0,0 +1 @@ +IPSECVERSION=1.0.3 diff -urN linux-2.4.26-rc2/net/ipsec/alg/Config.alg_1des.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_1des.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_1des.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_3des.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_3des.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_3des.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_aes.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_aes.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_aes.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_blowfish.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_blowfish.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_blowfish.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_cast.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_cast.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_cast.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_cryptoapi.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_cryptoapi.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_cryptoapi.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_md5.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_md5.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_md5.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_null.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_null.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_null.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_serpent.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_serpent.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_serpent.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_sha1.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_sha1.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_sha1.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_sha2.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_sha2.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_sha2.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.alg_twofish.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.alg_twofish.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.alg_twofish.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Config.in linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Config.in --- linux-2.4.26-rc2/net/ipsec/alg/Config.in Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile --- linux-2.4.26-rc2/net/ipsec/alg/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_1des linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_1des --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_1des Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_3des linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_3des --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_3des Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_aes linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_aes --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_aes Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_blowfish linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_blowfish --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_blowfish Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_cast linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_cast --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_cast Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_cryptoapi linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_cryptoapi --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_cryptoapi Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_md5 linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_md5 --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_md5 Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_null linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_null --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_null Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_serpent linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_serpent --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_serpent Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_sha1 linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_sha1 --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_sha1 Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_sha2 linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_sha2 --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_sha2 Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/Makefile.alg_twofish linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/Makefile.alg_twofish --- linux-2.4.26-rc2/net/ipsec/alg/Makefile.alg_twofish Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_1des.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_1des.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_1des.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_3des.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_3des.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_3des.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_aes.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_aes.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_aes.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_blowfish.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_blowfish.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_blowfish.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_cast.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_cast.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_cast.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_cryptoapi.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_cryptoapi.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_cryptoapi.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_md5.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_md5.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_md5.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_null.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_null.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_null.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_serpent.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_serpent.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_serpent.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_sha1.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_sha1.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_sha1.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_sha2.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_sha2.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_sha2.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/ipsec_alg_twofish.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/ipsec_alg_twofish.c --- linux-2.4.26-rc2/net/ipsec/alg/ipsec_alg_twofish.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/alg/scripts/mk-static_init.c.sh linux-2.4.26-rc2-os-1.0.3/net/ipsec/alg/scripts/mk-static_init.c.sh --- linux-2.4.26-rc2/net/ipsec/alg/scripts/mk-static_init.c.sh Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/defconfig linux-2.4.26-rc2-os-1.0.3/net/ipsec/defconfig --- linux-2.4.26-rc2/net/ipsec/defconfig Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/net/ipsec/defconfig Fri Jul 4 21:07:34 2003 @@ -0,0 +1,132 @@ + +# +# RCSID $Id: defconfig,v 1.5 2003/07/04 19:07:34 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 + +# 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.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.26-rc2/net/ipsec/ipcomp.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipcomp.c --- linux-2.4.26-rc2/net/ipsec/ipcomp.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipcomp.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipcomp.h --- linux-2.4.26-rc2/net/ipsec/ipcomp.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_ah.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_ah.h --- linux-2.4.26-rc2/net/ipsec/ipsec_ah.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_alg.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_alg.c --- linux-2.4.26-rc2/net/ipsec/ipsec_alg.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_alg.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_alg.h --- linux-2.4.26-rc2/net/ipsec/ipsec_alg.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_encap.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_encap.h --- linux-2.4.26-rc2/net/ipsec/ipsec_encap.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_eroute.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_eroute.h --- linux-2.4.26-rc2/net/ipsec/ipsec_eroute.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_errs.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_errs.h --- linux-2.4.26-rc2/net/ipsec/ipsec_errs.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_esp.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_esp.h --- linux-2.4.26-rc2/net/ipsec/ipsec_esp.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_init.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_init.c --- linux-2.4.26-rc2/net/ipsec/ipsec_init.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_ipe4.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_ipe4.h --- linux-2.4.26-rc2/net/ipsec/ipsec_ipe4.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_kversion.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_kversion.h --- linux-2.4.26-rc2/net/ipsec/ipsec_kversion.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_life.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_life.c --- linux-2.4.26-rc2/net/ipsec/ipsec_life.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_life.c Thu Dec 4 03:55:36 2003 @@ -0,0 +1,248 @@ +/* + * @(#) 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.3 2003/12/04 02:55:36 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. + * 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 = 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 = 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.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.26-rc2/net/ipsec/ipsec_life.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_life.h --- linux-2.4.26-rc2/net/ipsec/ipsec_life.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_md5c.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_md5c.c --- linux-2.4.26-rc2/net/ipsec/ipsec_md5c.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_md5h.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_md5h.h --- linux-2.4.26-rc2/net/ipsec/ipsec_md5h.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_netlink.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_netlink.c --- linux-2.4.26-rc2/net/ipsec/ipsec_netlink.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_netlink.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_netlink.h --- linux-2.4.26-rc2/net/ipsec/ipsec_netlink.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_param.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_param.h --- linux-2.4.26-rc2/net/ipsec/ipsec_param.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_proc.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_proc.c --- linux-2.4.26-rc2/net/ipsec/ipsec_proc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_proc.c Thu Apr 1 20:57:09 2004 @@ -0,0 +1,796 @@ +/* + * @(#) /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.6 2004/04/01 18:57:09 paul 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 + +int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...) +{ + va_list args; + int i; + size_t possize; + + if(size < 0) possize = 0; + else possize=size; + + va_start(args, fmt); + i=vsnprintf(buf,possize,fmt,args); + va_end(args); + 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, 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 */ + w.len -= (offset - w.begin); /* Start slop */ + if (w.len > length) + w.len = length; + return w.len; +} + +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_spi_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + int len = 0; + off_t pos = 0, 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"); + + pos = begin + len; + if(pos < offset) { + len = 0; + begin = pos; + } + if (pos > offset + length) { + goto done_spi_i; + } + } + } + + done_spi_i: + spin_unlock_bh(&tdb_lock); + + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; + return len; +} + +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_spigrp_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + int len = 0; + off_t pos = 0, 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"); + pos = begin + len; + if(pos < offset) { + len = 0; + begin = pos; + } + if (pos > offset + length) { + goto done_spigrp_i; + } + } + } + } + + done_spigrp_i: + spin_unlock_bh(&tdb_lock); + + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; + return len; +} + +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_tncfg_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + int len = 0; + off_t pos = 0, 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++) { + sprintf(name, "ipsec%d", 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"); + + pos = begin + len; + if(pos < offset) { + len = 0; + begin = pos; + } + else if (pos > offset + length) { + break; + } + } + } + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; + return len; +} + +IPSEC_PROCFS_DEBUG_NO_STATIC +int +ipsec_version_get_info(char *buffer, + char **start, + off_t offset, + int length IPSEC_PROC_LAST_ARG) +{ + int len = 0; + off_t begin = 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 + + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; + return len; +} + +#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) +{ + int len = 0; + off_t begin = 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); + + *start = buffer + (offset - begin); /* Start of wanted data */ + len -= (offset - begin); /* Start slop */ + if (len > length) + len = length; + return len; +} +#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.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.26-rc2/net/ipsec/ipsec_proto.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_proto.h --- linux-2.4.26-rc2/net/ipsec/ipsec_proto.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_radij.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_radij.c --- linux-2.4.26-rc2/net/ipsec/ipsec_radij.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_radij.c Thu Apr 1 20:57:09 2004 @@ -0,0 +1,817 @@ +/* + * 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.5 2004/04/01 18:57:09 paul 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 = 0; + + 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 = 0; +#ifdef CONFIG_IPSEC_DEBUG + char buf1[64], buf2[64]; + + if (debug_eroute) { + 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 = 0; + char sa[SATOA_BUF]; + size_t sa_len; +#ifdef CONFIG_IPSEC_DEBUG + char buf1[64], buf2[64]; + + if (debug_eroute) { + 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 insert eroute for %s:%d->%s:%d %d, SA: %s, PID:%d, skb=%p, ident:%s->%s\n", + buf1, ntohs(eaddr->sen_sport), + buf2, ntohs(eaddr->sen_dport), + eaddr->sen_proto, + 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")); + } +#endif /* CONFIG_IPSEC_DEBUG */ + + retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC); + if (retrt == NULL) { + printk("klips_error:ipsec_makeroute: " + "not able to allocate kernel memory"); + return -ENOMEM; + } + memset((caddr_t)retrt, 0, sizeof (struct eroute)); + + retrt->er_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) { +/* + 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 +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[64], buf2[64]; + 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 == NULL) { + return 120; + } + + if (rn->rj_b >= 0) { + return 0; + } + + key = rd_key(rd); + mask = rd_mask(rd); + + if ((key == 0) || (mask == 0)) { + 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); +#define IPSEC_EROUTE_IDENT_ +#ifndef IPSEC_EROUTE_IDENT + w->len += ipsec_snprintf(w->buffer + w->len, w->length - w->len, +/* + "%05d " +*/ + "%-10d " +/* + "%6d " +*/ + "%-18s -> %-18s => %s:%d\n", +/* + ro->er_pid, +*/ + ro->er_count, +/* + jiffies / HZ - ro->er_lasttime, +*/ + buf1, + buf2, + sa_len ? sa : " (error)", + key->sen_proto); +#else /* IPSEC_EROUTE_IDENT */ + w->len += ipsec_snprintf(w->buffer + w->len, w->length - w->len, +/* + "%05d " +*/ + "%-10d " +/* + "%6d " +*/ + "%-18s -> %-18s => %s:%d (%s) (%s)\n", +/* + ro->er_pid, +*/ + ro->er_count, +/* + jiffies / HZ - ro->er_lasttime, +*/ + buf1, + buf2, + sa_len ? sa : " (error)", + key->sen_proto, + (ro->er_ident_s.data ? ro->er_ident_s.data : ""), + (ro->er_ident_d.data ? ro->er_ident_d.data : "")); +#endif /* IPSEC_EROUTE_IDENT */ + + w->pos = w->begin + w->len; + if(w->pos < w->offset) { + w->len = 0; + w->begin = w->pos; + } + if (w->pos > w->offset + w->length) { + return -ENOBUFS; + } + 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 = 0; + struct sockaddr_encap *key, *mask; +#ifdef CONFIG_IPSEC_DEBUG + char buf1[64] = { 0 }, buf2[64] = { 0 }; +#endif /* CONFIG_IPSEC_DEBUG */ + + if (rn == NULL) { + return 120; + } + + key = rd_key(rd); + mask = rd_mask(rd); + + if(!key || !mask) { + return -ENODATA; + } +#ifdef CONFIG_IPSEC_DEBUG + if(debug_radij) { + 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.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.26-rc2/net/ipsec/ipsec_radij.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_radij.h --- linux-2.4.26-rc2/net/ipsec/ipsec_radij.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_radij.h Wed Nov 19 03:29:41 2003 @@ -0,0 +1,166 @@ +/* + * @(#) 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.2 2003/11/19 02:29:41 mcr 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 *); + +struct wsbuf +{ + char *buffer; + int length; + off_t offset; + int len; + int prev_len; + off_t begin; + off_t pos; +}; + +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.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.26-rc2/net/ipsec/ipsec_rcv.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_rcv.c --- linux-2.4.26-rc2/net/ipsec/ipsec_rcv.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_rcv.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_rcv.h --- linux-2.4.26-rc2/net/ipsec/ipsec_rcv.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_sa.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_sa.c --- linux-2.4.26-rc2/net/ipsec/ipsec_sa.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_sa.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_sa.h --- linux-2.4.26-rc2/net/ipsec/ipsec_sa.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_sha1.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_sha1.c --- linux-2.4.26-rc2/net/ipsec/ipsec_sha1.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_sha1.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_sha1.h --- linux-2.4.26-rc2/net/ipsec/ipsec_sha1.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_stats.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_stats.h --- linux-2.4.26-rc2/net/ipsec/ipsec_stats.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_tunnel.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_tunnel.c --- linux-2.4.26-rc2/net/ipsec/ipsec_tunnel.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_tunnel.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_tunnel.h --- linux-2.4.26-rc2/net/ipsec/ipsec_tunnel.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_xform.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_xform.c --- linux-2.4.26-rc2/net/ipsec/ipsec_xform.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/ipsec_xform.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/ipsec_xform.h --- linux-2.4.26-rc2/net/ipsec/ipsec_xform.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/include/cbc_generic.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/include/cbc_generic.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/include/cbc_generic.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/include/hmac_generic.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/include/hmac_generic.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/include/hmac_generic.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/include/md32_common.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/include/md32_common.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/include/md32_common.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libaes/Makefile linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libaes/Makefile --- linux-2.4.26-rc2/net/ipsec/libcrypto/libaes/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libaes/aes.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libaes/aes.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libaes/aes.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libaes/aes.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libaes/aes.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libaes/aes.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libaes/aes_cbc.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libaes/aes_cbc.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libaes/aes_cbc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libaes/aes_cbc.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libaes/aes_cbc.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libaes/aes_cbc.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libaes/aes_xcbc_mac.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libaes/aes_xcbc_mac.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libaes/aes_xcbc_mac.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libaes/aes_xcbc_mac.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libaes/aes_xcbc_mac.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libaes/aes_xcbc_mac.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libaes/asm/aes-i586.S linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libaes/asm/aes-i586.S --- linux-2.4.26-rc2/net/ipsec/libcrypto/libaes/asm/aes-i586.S Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libaes/test_main.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libaes/test_main.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libaes/test_main.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/COPYRIGHT linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/COPYRIGHT --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/COPYRIGHT Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/INSTALL linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/INSTALL --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/INSTALL Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/Makefile linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/Makefile --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/README linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/README --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/README Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/VERSION linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/VERSION --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/VERSION Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/asm/bf-586.pl linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/asm/bf-586.pl --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/asm/bf-586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/asm/bf-686.pl linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/asm/bf-686.pl --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/asm/bf-686.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/asm/readme linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/asm/readme --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/asm/readme Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/bf_enc.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/bf_enc.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/bf_enc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/bf_locl.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/bf_locl.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/bf_locl.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/bf_pi.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/bf_pi.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/bf_pi.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/bf_skey.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/bf_skey.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/bf_skey.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libblowfish/blowfish.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libblowfish/blowfish.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libblowfish/blowfish.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libcast/Makefile linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libcast/Makefile --- linux-2.4.26-rc2/net/ipsec/libcrypto/libcast/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libcast/asm/cast-586.pl linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libcast/asm/cast-586.pl --- linux-2.4.26-rc2/net/ipsec/libcrypto/libcast/asm/cast-586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libcast/asm/readme linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libcast/asm/readme --- linux-2.4.26-rc2/net/ipsec/libcrypto/libcast/asm/readme Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libcast/c_enc.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libcast/c_enc.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libcast/c_enc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libcast/c_skey.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libcast/c_skey.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libcast/c_skey.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libcast/cast.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libcast/cast.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libcast/cast.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libcast/cast_lcl.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libcast/cast_lcl.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libcast/cast_lcl.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libcast/cast_s.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libcast/cast_s.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libcast/cast_s.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libmd5/Makefile linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libmd5/Makefile --- linux-2.4.26-rc2/net/ipsec/libcrypto/libmd5/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libmd5/asm/md5-586.pl linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libmd5/asm/md5-586.pl --- linux-2.4.26-rc2/net/ipsec/libcrypto/libmd5/asm/md5-586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libmd5/hmac_md5.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libmd5/hmac_md5.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libmd5/hmac_md5.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libmd5/hmac_md5.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libmd5/hmac_md5.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libmd5/hmac_md5.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libmd5/md5.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libmd5/md5.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libmd5/md5.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libmd5/md5_dgst.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libmd5/md5_dgst.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libmd5/md5_dgst.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libmd5/md5_locl.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libmd5/md5_locl.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libmd5/md5_locl.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libmd5/md5_one.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libmd5/md5_one.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libmd5/md5_one.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libserpent/Makefile linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libserpent/Makefile --- linux-2.4.26-rc2/net/ipsec/libcrypto/libserpent/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libserpent/serpent.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libserpent/serpent.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libserpent/serpent.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libserpent/serpent.c Tue Oct 1 15:47:14 2002 @@ -0,0 +1,995 @@ + +/* 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.26-rc2/net/ipsec/libcrypto/libserpent/serpent.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libserpent/serpent.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libserpent/serpent.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libserpent/serpent_cbc.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libserpent/serpent_cbc.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libserpent/serpent_cbc.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libserpent/serpent_cbc.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libserpent/serpent_cbc.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libserpent/serpent_cbc.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libserpent/test_main.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libserpent/test_main.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libserpent/test_main.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha1/asm/README linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/asm/README --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/asm/README Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/asm/README Thu Sep 5 05:35:58 2002 @@ -0,0 +1 @@ +C2.pl works diff -urN linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/asm/sha1-586.pl linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/asm/sha1-586.pl --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/asm/sha1-586.pl Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha1/hmac_sha1.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/hmac_sha1.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/hmac_sha1.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha1/hmac_sha1.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/hmac_sha1.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/hmac_sha1.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha1/sha.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/sha.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/sha.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha1/sha1_one.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/sha1_one.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/sha1_one.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha1/sha1dgst.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/sha1dgst.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/sha1dgst.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha1/sha_dgst.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/sha_dgst.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/sha_dgst.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha1/sha_locl.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha1/sha_locl.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha1/sha_locl.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha2/Makefile linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha2/Makefile --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha2/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha2/hmac_sha2.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha2/hmac_sha2.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha2/hmac_sha2.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha2/hmac_sha2.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha2/hmac_sha2.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha2/hmac_sha2.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha2/sha2.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha2/sha2.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha2/sha2.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libsha2/sha2.h linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libsha2/sha2.h --- linux-2.4.26-rc2/net/ipsec/libcrypto/libsha2/sha2.h Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libtwofish/Makefile linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libtwofish/Makefile --- linux-2.4.26-rc2/net/ipsec/libcrypto/libtwofish/Makefile Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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.26-rc2/net/ipsec/libcrypto/libtwofish/test_main.c linux-2.4.26-rc2-os-1.0.3/net/ipsec/libcrypto/libtwofish/test_main.c --- linux-2.4.26-rc2/net/ipsec/libcrypto/libtwofish/test_main.c Thu Jan 1 01:00:00 1970 +++ linux-2.4.26-rc2-os-1.0.3/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