This commit is contained in:
Martin Willi
2006-04-28 09:07:55 +00:00
parent a06e45dc9c
commit 83cb0b0e8c
370 changed files with 35 additions and 194736 deletions
-12
View File
@@ -1,12 +0,0 @@
RCSID $Id: Config.in.fs2_0.patch,v 1.2 2004/03/30 14:15:03 as Exp $
--- linux/net/Config.in.preipsec Mon Jul 13 16:47:40 1998
+++ linux/net/Config.in Thu Sep 16 11:26:31 1999
@@ -24,4 +24,8 @@
if [ "$CONFIG_NETLINK" = "y" ]; then
bool 'Routing messages' CONFIG_RTNETLINK
fi
+tristate 'IP Security Protocol (strongSwan IPsec)' CONFIG_IPSEC
+if [ "$CONFIG_IPSEC" != "n" ]; then
+ source net/ipsec/Config.in
+fi
endmenu
-12
View File
@@ -1,12 +0,0 @@
RCSID $Id: Config.in.fs2_2.patch,v 1.2 2004/03/30 14:15:03 as Exp $
--- linux/net/Config.in.preipsec Thu Feb 25 13:46:47 1999
+++ linux/net/Config.in Sat Aug 28 02:24:59 1999
@@ -63,4 +63,8 @@
endmenu
fi
fi
+tristate 'IP Security Protocol (strongSwan IPsec)' CONFIG_IPSEC
+if [ "$CONFIG_IPSEC" != "n" ]; then
+ source net/ipsec/Config.in
+fi
endmenu
-13
View File
@@ -1,13 +0,0 @@
--- linux/net/Config.in.orig Fri Feb 9 14:34:13 2001
+++ linux/net/Config.in Thu Feb 22 19:40:08 2001
@@ -88,4 +88,10 @@
#bool 'Network code profiler' CONFIG_NET_PROFILE
endmenu
+tristate 'IP Security Protocol (strongSwan IPsec)' CONFIG_IPSEC
+define_tristate CONFIG_IPSEC m
+if [ "$CONFIG_IPSEC" != "n" ]; then
+ source net/ipsec/Config.in
+fi
+
endmenu
-20
View File
@@ -1,20 +0,0 @@
RCSID $Id: Makefile.fs2_0.patch,v 1.1 2004/03/15 20:35:26 as Exp $
--- linux/net/Makefile.preipsec Mon Jul 13 16:47:40 1998
+++ linux/net/Makefile Thu Sep 16 11:26:31 1999
@@ -64,6 +64,16 @@
endif
endif
+ifeq ($(CONFIG_IPSEC),y)
+ALL_SUB_DIRS += ipsec
+SUB_DIRS += ipsec
+else
+ ifeq ($(CONFIG_IPSEC),m)
+ ALL_SUB_DIRS += ipsec
+ MOD_SUB_DIRS += ipsec
+ endif
+endif
+
L_TARGET := network.a
L_OBJS := socket.o protocols.o sysctl_net.o $(join $(SUB_DIRS),$(SUB_DIRS:%=/%.o))
ifeq ($(CONFIG_NET),y)
-20
View File
@@ -1,20 +0,0 @@
RCSID $Id: Makefile.fs2_2.patch,v 1.1 2004/03/15 20:35:26 as Exp $
--- linux/net/Makefile.preipsec Tue Jun 20 17:32:27 2000
+++ linux/net/Makefile Fri Jun 30 14:44:38 2000
@@ -195,6 +195,16 @@
endif
endif
+ifeq ($(CONFIG_IPSEC),y)
+ALL_SUB_DIRS += ipsec
+SUB_DIRS += ipsec
+else
+ ifeq ($(CONFIG_IPSEC),m)
+ ALL_SUB_DIRS += ipsec
+ MOD_SUB_DIRS += ipsec
+ endif
+endif
+
# We must attach netsyms.o to socket.o, as otherwise there is nothing
# to pull the object file from the archive.
-10
View File
@@ -1,10 +0,0 @@
--- linux/net/Makefile.dist Mon Dec 17 12:18:26 2001
+++ linux/net/Makefile Tue Jan 22 11:10:24 2002
@@ -8,6 +8,7 @@
O_TARGET := network.o
mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched
+mod-subdirs += ipsec
export-objs := netsyms.o
subdir-y := core ethernet
-11
View File
@@ -1,11 +0,0 @@
RCSID $Id: Makefile.fs2_4.patch,v 1.1 2004/03/15 20:35:26 as Exp $
--- linux/net/Makefile.preipsec Mon Jun 11 22:15:27 2001
+++ linux/net/Makefile Tue Nov 6 21:07:43 2001
@@ -17,6 +17,7 @@
subdir-$(CONFIG_NET) += 802 sched
subdir-$(CONFIG_INET) += ipv4
subdir-$(CONFIG_NETFILTER) += ipv4/netfilter
+subdir-$(CONFIG_IPSEC) += ipsec
subdir-$(CONFIG_UNIX) += unix
subdir-$(CONFIG_IPV6) += ipv6
-25
View File
@@ -1,25 +0,0 @@
--- ./include/net/sock.h Fri Nov 2 17:39:16 2001
+++ ./include/net/sock.h Mon Jun 10 19:44:55 2002
@@ -201,6 +201,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 */
@@ -443,6 +449,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;
-27
View File
@@ -1,27 +0,0 @@
--- ./include/net/sock.h 2002/02/06 15:25:10 1.1
+++ ./include/net/sock.h 2002/05/22 12:14:56
@@ -488,7 +488,13 @@
} bictcp;
};
-
+#if 1
+#define UDP_OPT_IN_SOCK 1
+struct udp_opt {
+ __u32 esp_in_udp;
+};
+#endif
+
/*
* This structure really needs to be cleaned up.
* Most of it is for TCP, and not used by any of
@@ -655,6 +661,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;
-47
View File
@@ -1,47 +0,0 @@
.addrtoa.o.flags
.adler32.o.flags
.cbc_enc.o.flags
.datatot.o.flags
.deflate.o.flags
.des_enc.o.flags
.ecb_enc.o.flags
.goodmask.o.flags
.infblock.o.flags
.infcodes.o.flags
.inffast.o.flags
.inflate.o.flags
.inftrees.o.flags
.infutil.o.flags
.ipcomp.o.flags
.ipsec.o.flags
.ipsec_init.o.flags
.ipsec_life.o.flags
.ipsec_md5c.o.flags
.ipsec_proc.o.flags
.ipsec_radij.o.flags
.ipsec_rcv.o.flags
.ipsec_sa.o.flags
.ipsec_sha1.o.flags
.ipsec_tunnel.o.flags
.pfkey_v2.o.flags
.pfkey_v2_build.o.flags
.pfkey_v2_debug.o.flags
.pfkey_v2_ext_bits.o.flags
.pfkey_v2_ext_process.o.flags
.pfkey_v2_parse.o.flags
.pfkey_v2_parser.o.flags
.prng.o.flags
.radij.o.flags
.rangetoa.o.flags
.satoa.o.flags
.set_key.o.flags
.subnetof.o.flags
.subnettoa.o.flags
.sysctl_net_ipsec.o.flags
.trees.o.flags
.ultoa.o.flags
.version.o.flags
.zutil.o.flags
version.c
.*.o.flags
*.o
-41
View File
@@ -1,41 +0,0 @@
#
# 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 <http://www.fsf.org/copyleft/gpl.txt>.
#
# 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 2004/03/30 21:11:11 as Exp $
comment 'IPsec options (strongSwan)'
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
-529
View File
@@ -1,529 +0,0 @@
# Makefile for KLIPS kernel code as a module
# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
# Copyright (C) 2002 Michael Richardson <[email protected]>
#
# 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 <http://www.fsf.org/copyleft/gpl.txt>.
#
# 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.2 2004/03/22 21:53:19 as 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).
#
ifeq ($(strip $(KLIPSMODULE)),)
FREESWANSRCDIR=.
else
FREESWANSRCDIR=../../..
endif
-include ${FREESWANSRCDIR}/Makefile.ver
ifeq ($(strip $(KLIPS_TOP)),)
KLIPS_TOP=../..
endif
ifneq ($(strip $(KLIPSMODULE)),)
ifndef TOPDIR
TOPDIR:=/usr/src/linux
endif
export TOPDIR
endif
#
# This magic from User-Mode-Linux list. It gets list of -I options, as
# UML needs some extra, that varry by revision.
#
KERNEL_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(CFLAGS)' )
MODULE_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(MODFLAGS)' )
subdir- :=
subdir-n :=
subdir-y :=
subdir-m :=
MOD_DESTDIR:=net/ipsec
export TOPDIR
all: ipsec.o
foo:
echo KERNEL: ${KERNEL_CFLAGS}
echo MODULE: ${MODULE_CFLAGS}
ipsec.o: foo
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_xmit.o ipsec_rcv.o
obj-y += sysctl_net_ipsec.o
obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
#obj-y += version.o
LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des
VPATH+= ${LIBDESDIR}
include ${LIBDESDIR}/Makefile.objs
LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan
VPATH+=${LIBFREESWANDIR}
include ${LIBFREESWANDIR}/Makefile.objs
# IPcomp stuff
obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o
LIBZLIBSRCDIR=${KLIPS_TOP}/lib/zlib
VPATH+=${LIBZLIBSRCDIR}
# LIBCRYPTO Will be overriden eg. when doing "make module"
# from freeswan-2 src root
# Default value assumes already symlinked libcrypto under $TOPDIR/lib
LIBCRYPTO=$(TOPDIR)/lib/libcrypto
VPATH+=${LIBCRYPTO}
alg/static_init_mod.o: dummy
$(MAKE) -C alg CC='$(CC)' TOPDIR='$(TOPDIR)' \
'EXTRA_CFLAGS=$(EXTRA_CFLAGS)' \
static_init_mod.o
alg_modules: dummy
$(MAKE) $(MODULE_FLAGS) -C alg CC='$(CC)' TOPDIR='$(TOPDIR)' \
'LIBCRYPTO=$(LIBCRYPTO)' \
'EXTRA_CFLAGS=$(EXTRA_CFLAGS)' \
modules
# CFLAGS='$(CFLAGS)' \
# MODULE_CFLAGS='$(MODULE_CFLAGS)' KERNEL_CFLAGS='$(KERNEL_CFLAGS)' \
#
include ${LIBZLIBSRCDIR}/Makefile.objs
export-objs := radij.o
# New handling of KERNEL_CFLAGS and MODULE_CFLAGS introduced in 2.0
# tosses export-objs logic :(
CFLAGS_ipsec_alg.o += -DEXPORT_SYMTAB
obj-$(CONFIG_IPSEC_ALG) +=ipsec_alg.o alg/static_init_mod.o
export-objs += ipsec_alg.o
subdir-m += alg
EXTRA_CFLAGS += $(ALGO_FLAGS)
# include file with .h-style macros that would otherwise be created by
# config. Must occur before other includes.
ifneq ($(strip $(MODULE_DEF_INCLUDE)),)
EXTRA_CFLAGS += -include ${MODULE_DEF_INCLUDE}
endif
# 'override CFLAGS' should really be 'EXTRA_CFLAGS'
#EXTRA_CFLAGS += -nostdinc
EXTRA_CFLAGS += -I${KLIPS_TOP}/include
EXTRA_CFLAGS += -I${TOPDIR}/include
EXTRA_CFLAGS += -I${LIBZLIBSRCDIR}
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
#ifeq ($(CONFIG_IPSEC_ALG), y)
EXTRA_CFLAGS += -DCONFIG_IPSEC_ALG
#endif
# MOST of these flags are in KERNEL_CFLAGS already!
EXTRA_CFLAGS += $(KLIPSCOMPILE)
EXTRA_CFLAGS += -Wall
#EXTRA_CFLAGS += -Werror
#EXTRA_CFLAGS += -Wconversion
#EXTRA_CFLAGS += -Wmissing-prototypes
# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM
# include/linux/highmem.h has an inline function definition that uses void* arithmentic.
ifeq ($(CONFIG_NOHIGHMEM),y)
EXTRA_CFLAGS += -Wpointer-arith
endif
#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
ifneq ($(strip $(KLIPSMODULE)),)
# for when we aren't building in the kernel tree
EXTRA_CFLAGS += -DARCH=${ARCH}
EXTRA_CFLAGS += -DMODVERSIONS
EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h
EXTRA_CFLAGS += ${MODULE_CFLAGS}
endif
EXTRA_CFLAGS += ${KERNEL_CFLAGS}
# GCC 3.2 (and we presume any other 3.x) wants -falign-functions
# in place of the traditional -malign-functions. Getting this
# wrong leads to a warning, which is fatal due to our use of -Werror.
ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3)
override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS))
endif
obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o
obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o
###
### 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
#$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
USE_STANDARD_AS_RULE=true
clean:
$(MAKE) -C alg clean
-rm -f *.o
-rm -f .*.o.flags
-rm version.c
tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
etags *.c ../../include/*.h ../../include/freeswan/*.h
ctags *.c ../../include/*.h ../../include/freeswan/*.h
tar:
tar -cvf /dev/f1 .
#
# $Log: Makefile,v $
# Revision 1.2 2004/03/22 21:53:19 as
# merged alg-0.8.1 branch with HEAD
#
# Revision 1.1.4.1 2004/03/16 09:48:19 as
# alg-0.8.1rc12 patch merged
#
# Revision 1.1 2004/03/15 20:35:26 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.61 2003/06/22 21:07:46 mcr
# adjusted TAGS target in makefile to be useful in 2.00 source layout.
#
# Revision 1.60 2003/05/03 23:45:23 mcr
# rm .o.flags and generated version.c file.
#
# Revision 1.59 2003/02/12 19:32:47 rgb
# Added ipsec_xmit to the list of object files.
#
# Revision 1.58 2003/01/03 00:36:44 rgb
#
# Added emacs compile-command.
#
# Revision 1.57 2002/11/08 23:49:53 mcr
# use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list
# of include directories.
# This also eliminates some of the guesswork in the kernel
# configuration file.
#
# Revision 1.56 2002/11/08 23:23:18 mcr
# attempt to guess kernel compilation flags (i.e. list of -I)
# by using some magic targets in the kernel makefile.
#
# Revision 1.55 2002/11/08 10:13:33 mcr
# added additional include directories for module builds for 2.4.19.
#
# Revision 1.54 2002/10/20 06:10:30 build
# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues.
#
# Revision 1.53 2002/10/17 16:32:01 mcr
# enable standard AS rules.
#
# Revision 1.52 2002/10/06 06:13:44 sam
# Altering order of includes, so that architecture-specific header files,
# used for building RPM modules specifically, are processed first.
#
# Revision 1.51 2002/10/05 15:06:38 dhr
#
# - To allow for gcc3.2 (used in Red Hat Linux 8.0): adjust CFLAGS (set
# by kernel machinery) to use -falign-functions= in place of
# -malign-functions=. Eliminates a warning (fatal with -Werror).
#
# - When CONFIG_HIGHMEM is on, -Wpointer-arith will warn about
# include/linux/highmem.h. Since this is fatal with -Werror, we
# suppress -Wpointer-arith if CONFIG_HIGHMEM is set.
#
# Revision 1.50 2002/09/16 21:19:45 mcr
# enable -Werror for production - this helps a lot (found a bug in ipsec_rcv.c)
#
# Revision 1.49 2002/07/29 05:12:39 mcr
# get rid of some extraneous stuff, now handled by a prefix
# Makefile when building as a module.
#
# Revision 1.48 2002/07/28 23:13:49 mcr
# set KLIPS_TOP and use it instead of ../..
# if KLIPSMODULE, then include a bunch of stuff defined in Makefile.inc
# that gets us the "typical" configuration that we want.
#
# Revision 1.47 2002/06/02 21:51:41 mcr
# changed TOPDIR->FREESWANSRCDIR in all Makefiles.
# (note that linux/net/ipsec/Makefile uses TOPDIR because this is the
# kernel sense.)
#
# Revision 1.46 2002/05/14 02:35:51 rgb
# Added file pfkey_v2_ext_process.c.
#
# Revision 1.45 2002/05/13 17:21:40 mcr
# mkdep dies when given a -I to a directory that does not exist.
# arch/${ARCH}/include is for UM arch only, so include it for that
# ARCH only.
#
# Revision 1.44 2002/04/24 20:38:12 mcr
# moved more stuff behind $KLIPSMODULE=y to get static linking to work.
#
# Revision 1.43 2002/04/24 09:16:18 mcr
# include local Makefile.ver as well as FS_rootdir version.
#
# Revision 1.42 2002/04/24 08:50:08 mcr
# critical patch is to set TOPDIR with :=.
#
# Revision 1.40 2002/04/24 00:41:07 mcr
# Moved from ./klips/net/ipsec/Makefile,v
#
# 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 <[email protected]>
# 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 ***
#
#
# Local Variables:
# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
# End Variables:
#
-125
View File
@@ -1,125 +0,0 @@
IPSECVERSION=2.03
# vim:aw:ai
#
# null-patch, non-root GNUmakefile addon for freeswan modules compilation
#
# It will not "affect" normal KLIPS building because this GNUmakefile
# it's not copied to /usr/src/linux
#
# Author: JuanJo Ciarlante <[email protected]>
# $Id: Makefile.algtest,v 1.2 2004/03/22 21:53:19 as Exp $
#
# 1) Copy me to linux/net/ipsec
# 2)
# cd klibs/net/ipsec
# make prep TOPDIR=/path/to/usr/src/linux \
# [CONFIG=/path/to/.config | CONFIG=/dev/null]
# 3)
# make all TOPDIR=.... CONFIG=....
#CONFIG_IPSEC_ENC_3DES=y
#CONFIG_IPSEC_AUTH_HMAC_MD5=y
#CONFIG_IPSEC_AUTH_HMAC_SHA1=y
CONFIG_IPSEC_ALG_AES=m
ifndef TOPDIR
$(error You _must_ pass TOPDIR= and optionally CONFIG=)
endif
CONFIG=$(TOPDIR)/.config
include $(CONFIG)
ifdef CONFIG_USERMODE
ARCH=um
endif
CONFIG_IPSEC=m
CONFIG_IPSEC_MODULE=y
CONFIG_IPSEC_IPIP=y
CONFIG_IPSEC_AH=y
CONFIG_IPSEC_ESP=y
CONFIG_IPSEC_ALG=y
CONFIG_IPSEC_IPCOMP=y
CONFIG_M586 :=$(shell uname -m | sed -n "s/i586/y/p" )
CONFIG_M686 :=$(shell uname -m | sed -n "s/i686/y/p" )
export CONFIG_M586 CONFIG_M686
cflags-arch-$(CONFIG_M586) += -march=i586
cflags-arch-$(CONFIG_M586_TSC) += -march=i586
cflags-arch-$(CONFIG_M686) += -march=i686
cflags-arch-$(CONFIG_MPENTIUMIII) += -march=i686
cflags-arch-$(CONFIG_MK7) += -march=i686 -malign-functions=4
CFLAGS_ARCH := $(cflags-arch-y)
ifndef $(CONFIG_SHELL)
CONFIG_SHELL=/bin/bash
endif
export CONFIG_SHELL TOPDIR
ifdef CONFIG_SMP
EXTRA_CFLAGS += -D__SMP__
EXTRA_AFLAGS += -D__SMP__
endif
CFLAGS_IPSEC:=\
-DMODVERSIONS \
-DCONFIG_IPSEC_MODULE=1\
-DCONFIG_IPSEC_IPIP=1\
-DCONFIG_IPSEC_AH=1\
-DCONFIG_IPSEC_ESP=1\
-DCONFIG_IPSEC_IPCOMP=1\
-DCONFIG_IPSEC_DEBUG=1 \
-DCONFIG_IPSEC_ALG=1 \
# -DCONFIG_IPSEC_DEBUG=1 \
#
cflags-ipsec-$(CONFIG_IPSEC_ENC_3DES) += -DCONFIG_IPSEC_ENC_3DES=1
cflags-ipsec-$(CONFIG_IPSEC_ALG_AES) += -DCONFIG_IPSEC_ALG_AES=1
cflags-ipsec-$(CONFIG_IPSEC_AUTH_HMAC_MD5)+= -DCONFIG_IPSEC_AUTH_HMAC_MD5=1
cflags-ipsec-$(CONFIG_IPSEC_AUTH_HMAC_SHA1)+= -DCONFIG_IPSEC_AUTH_HMAC_SHA1=1
CFLAGS_IPSEC+=$(cflags-ipsec-y)
export CONFIG_IPSEC
export CONFIG_IPSEC_MODULE
# last bits over CFLAGS ...
CFLAGS+=$(KINCLUDE) $(CFLAGS_IPSEC) $(CFLAGS_ARCH) $(CFLAGS_KERNEL)
EXTRA_CFLAGS:=-I$(LOCALKLIPS) -I$(IPSEC_ROOT)/lib
# libdes options: OPTS1
OPTS1:=$(CFLAGS) $(EXTRA_CFLAGS)
export OPTS1 CFLAGS
#include Makefile
KERNEL_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(CFLAGS)' )
MODULE_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(MODFLAGS)' )
ALGO_FLAGS=$(CFLAGS_IPSEC)
export ALGO_FLAGS
all: modules alg_modules
modules:
$(MAKE) -C $(TOPDIR) SUBDIRS=$(PWD) modules
ifdef CONFIG_USERMODE
local_modversions_h:
> local_modversions.h
else
local_modversions_h:
(echo "#ifndef _LINUX_MODVERSIONS_H";\
echo "#define _LINUX_MODVERSIONS_H"; \
echo "#include <linux/modsetver.h>"; \
cd $(TOPDIR)/include/linux/modules; \
perl -ne 'print "#define __ver_$$1\t$$2$$3\n#define $$1\t_set_ver($$1)\n" if (/ (.*)_R(smp)?([a-z0-9]{8})\W/);' /proc/ksyms ;\
echo "#endif"; \
) > local_modversions.h
endif
un_local_modversions_h:
@rm -f local_modversions.h
all_alg_modules:
(cd alg && \
$(MAKE) CC='$(CC)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' \
LIBCRYPTO=$(LOCALKLIPS)/../../../lib/libcrypto \
all_alg_modules;)
.PHONY: local_modversions_h
-3
View File
@@ -1,3 +0,0 @@
if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
tristate ' AES encryption algorithm' CONFIG_IPSEC_ALG_AES
fi
@@ -1,3 +0,0 @@
if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
tristate ' BLOWFISH encryption algorithm' CONFIG_IPSEC_ALG_BLOWFISH
fi
@@ -1,3 +0,0 @@
if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
fi
@@ -1,3 +0,0 @@
if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
tristate ' SERPENT encryption algorithm' CONFIG_IPSEC_ALG_SERPENT
fi
-3
View File
@@ -1,3 +0,0 @@
if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
tristate ' HMAC_SHA2 auth algorithm' CONFIG_IPSEC_ALG_SHA2
fi
@@ -1,3 +0,0 @@
if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
tristate ' TWOFISH encryption algorithm' CONFIG_IPSEC_ALG_TWOFISH
fi
-7
View File
@@ -1,7 +0,0 @@
#Placeholder
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_cryptoapi.in
source net/ipsec/alg/Config.alg_sha2.in
-112
View File
@@ -1,112 +0,0 @@
# $Id: Makefile,v 1.2 2004/03/22 21:53:19 as Exp $
ifeq ($(strip $(KLIPSMODULE)),)
FREESWANSRCDIR=.
else
FREESWANSRCDIR=../../../..
endif
ifeq ($(strip $(KLIPS_TOP)),)
KLIPS_TOP=../../..
override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include
endif
ifeq ($(CONFIG_IPSEC_DEBUG),y)
override EXTRA_CFLAGS += -g
endif
# LIBCRYPTO normally comes as an argument from "parent" Makefile
# (this applies both to FS' "make module" and eg. Linux' "make modules"
# But make dep doest follow same evaluations, so we need this default:
LIBCRYPTO=$(TOPDIR)/lib/libcrypto
override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include
override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes
MOD_LIST_NAME := NET_MISC_MODULES
#O_TARGET := static_init.o
subdir- :=
subdir-n :=
subdir-y :=
subdir-m :=
obj-y := 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
# The algorithm makefiles may put dependences, short-circuit them
null:
makefiles=$(filter-out %.preipsec, $(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)
static_init_mod.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 $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
all_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)
#
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 .*.o.flags static_init.c
ifdef TOPDIR
include $(TOPDIR)/Rules.make
endif
-23
View File
@@ -1,23 +0,0 @@
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)' libaes.a ;)
-23
View File
@@ -1,23 +0,0 @@
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 ;)
@@ -1,14 +0,0 @@
MOD_CRYPTOAPI := ipsec_cryptoapi.o
ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
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
else
$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
endif
CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
$(LD) -r $(CRYPTOAPI_OBJS) -o $@
-21
View File
@@ -1,21 +0,0 @@
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 ;)
-22
View File
@@ -1,22 +0,0 @@
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 ;)
-21
View File
@@ -1,21 +0,0 @@
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 ;)
-253
View File
@@ -1,253 +0,0 @@
/*
* ipsec_alg AES cipher stubs
*
* Author: JuanJo Ciarlante <[email protected]>
*
* $Id: ipsec_alg_aes.c,v 1.2 2004/03/22 21:53:19 as 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 <[email protected]>
* Fixes list:
* PK: make XCBC comply with latest draft (keylength)
*
*/
#include <linux/config.h>
#include <linux/version.h>
/*
* 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 <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/string.h>
/* Check if __exit is defined, if not null it */
#ifndef __exit
#define __exit
#endif
/* Low freeswan header coupling */
#include "freeswan/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 <[email protected]>");
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, 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;
-142
View File
@@ -1,142 +0,0 @@
/* ipsec_alg BLOWFISH cipher stubs
*
* Author: JuanJo Ciarlante <[email protected]>
*
* 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*
* RCS ID $Id: ipsec_alg_blowfish.c,v 1.3 2004/09/17 18:57:30 as Exp $
*/
#include <linux/config.h>
#include <linux/version.h>
/*
* 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 <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/string.h>
/* Check if __exit is defined, if not null it */
#ifndef __exit
#define __exit
#endif
/* Low freeswan header coupling */
#include "freeswan/ipsec_alg.h"
#include "libblowfish/blowfish.h"
#define blowfish_context BF_KEY
#define ESP_BLOWFISH 7 /* truly _constant_ :) */
#define ESP_BLOWFISH_KEY_SZ_MIN 16 /* 128 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 max */
#define ESP_BLOWFISH_CBC_BLK_LEN 8 /* block size */
MODULE_AUTHOR("JuanJo Ciarlante <[email protected]>");
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, 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;
-421
View File
@@ -1,421 +0,0 @@
/*
* ipsec_alg to linux cryptoapi GLUE
*
* Authors: CODE.ar TEAM
* Harpo MAxx <[email protected]>
* JuanJo Ciarlante <[email protected]>
* Luciano Ruete <[email protected]>
*
* $Id: ipsec_alg_cryptoapi.c,v 1.3 2004/09/17 18:57:30 as 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 des_ede3=0 (everything but 3DES)
*/
#include <linux/config.h>
#include <linux/version.h>
/*
* 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 <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/string.h>
/* 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 found, install 2.4.22+ or 2.6.x"
#define NO_CRYPTOAPI_SUPPORT
#endif
/* Low freeswan header coupling */
#include "freeswan/ipsec_alg.h"
#include <linux/crypto.h>
#ifdef CRYPTO_API_VERSION_CODE
#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
#define NO_CRYPTOAPI_SUPPORT
#endif
#ifdef NO_CRYPTOAPI_SUPPORT
#warning "Building an unusable module :P"
/* Catch old CryptoAPI by not allowing module to load */
IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
{
printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
return -EINVAL;
}
#else
#include <asm/scatterlist.h>
#include <asm/pgtable.h>
#include <linux/mm.h>
#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 /* truly _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 des_ede3[] = {-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(des_ede3,"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(des_ede3, "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, 128, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
{ CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ 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;
#endif /* NO_CRYPTOAPI_SUPPORT */
-139
View File
@@ -1,139 +0,0 @@
/*
* ipsec_alg SERPENT cipher stubs
*
* Author: JuanJo Ciarlante <[email protected]>
*
* $Id: ipsec_alg_serpent.c,v 1.2 2004/03/22 21:53:19 as 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 <linux/config.h>
#include <linux/version.h>
/*
* 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 <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/string.h>
/* Check if __exit is defined, if not null it */
#ifndef __exit
#define __exit
#endif
/* Low freeswan header coupling */
#include "freeswan/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 <[email protected]>");
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, 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;
-185
View File
@@ -1,185 +0,0 @@
/*
* ipsec_alg SHA2 hash stubs
*
* Author: JuanJo Ciarlante <[email protected]>
*
* $Id: ipsec_alg_sha2.c,v 1.2 2004/03/22 21:53:19 as 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 <linux/config.h>
#include <linux/version.h>
/*
* 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 <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/string.h>
/* Check if __exit is defined, if not null it */
#ifndef __exit
#define __exit
#endif
/* Low freeswan header coupling */
#include "freeswan/ipsec_alg.h"
#include "libsha2/sha2.h"
#include "libsha2/hmac_sha2.h"
MODULE_AUTHOR("JuanJo Ciarlante <[email protected]>");
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;
-138
View File
@@ -1,138 +0,0 @@
/*
* ipsec_alg TWOFISH cipher stubs
*
* Author: JuanJo Ciarlante <[email protected]>
*
* $Id: ipsec_alg_twofish.c,v 1.2 2004/03/22 21:53:19 as 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 <linux/config.h>
#include <linux/version.h>
/*
* 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 <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h> /* printk() */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/string.h>
/* Check if __exit is defined, if not null it */
#ifndef __exit
#define __exit
#endif
/* Low freeswan header coupling */
#include "freeswan/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 <[email protected]>");
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, 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
@@ -1,18 +0,0 @@
#!/bin/sh
cat << EOF
#include <linux/kernel.h>
#include <linux/list.h>
#include "freeswan/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
-140
View File
@@ -1,140 +0,0 @@
#
# RCSID $Id: defconfig,v 1.2 2004/03/22 21:53:19 as 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=y
# 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
# modular algo extensions (and new ALGOs)
CONFIG_IPSEC_ALG=y
CONFIG_IPSEC_ALG_3DES=m
CONFIG_IPSEC_ALG_AES=m
CONFIG_IPSEC_ALG_TWOFISH=m
CONFIG_IPSEC_ALG_BLOWFISH=m
CONFIG_IPSEC_ALG_SERPENT=m
CONFIG_IPSEC_ALG_MD5=m
CONFIG_IPSEC_ALG_SHA1=m
CONFIG_IPSEC_ALG_SHA2=m
#CONFIG_IPSEC_ALG_CAST=n
#CONFIG_IPSEC_ALG_NULL=n
# Use CryptoAPI for ALG?
CONFIG_IPSEC_ALG_CRYPTOAPI=m
# IP Compression: new, probably still has minor bugs.
CONFIG_IPSEC_IPCOMP=y
# To enable userspace-switchable KLIPS debugging, say 'y'.
CONFIG_IPSEC_DEBUG=y
# NAT Traversal
CONFIG_IPSEC_NAT_TRAVERSAL=y
#
#
# $Log: defconfig,v $
# Revision 1.2 2004/03/22 21:53:19 as
# merged alg-0.8.1 branch with HEAD
#
# Revision 1.1.2.1.2.1 2004/03/16 09:48:19 as
# alg-0.8.1rc12 patch merged
#
# Revision 1.1.2.1 2004/03/15 22:30:06 as
# nat-0.6c patch merged
#
# Revision 1.1 2004/03/15 20:35:26 as
# added files from freeswan-2.04-x509-1.5.3
#
# Revision 1.22 2003/02/24 19:37:27 mcr
# changed default compilation mode to static.
#
# Revision 1.21 2002/04/24 07:36:27 mcr
# Moved from ./klips/net/ipsec/defconfig,v
#
# 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 <[email protected]>
# 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.
#
#
-725
View File
@@ -1,725 +0,0 @@
/*
* IPCOMP zlib interface code.
* Copyright (C) 2000 Svenning Soerensen <[email protected]>
* Copyright (C) 2000, 2001 Richard Guy Briggs <[email protected]>
*
* 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.2 2004/06/13 19:57:49 as Exp $";
/* SSS */
#include <linux/config.h>
#include <linux/version.h>
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include "freeswan/ipsec_param.h"
#ifdef MALLOC_SLAB
# include <linux/slab.h> /* kmalloc() */
#else /* MALLOC_SLAB */
# include <linux/malloc.h> /* kmalloc() */
#endif /* MALLOC_SLAB */
#include <linux/errno.h> /* error codes */
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h> /* struct device, and other headers */
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/ip.h> /* struct iphdr */
#include <linux/skbuff.h>
#include <freeswan.h>
#ifdef NET_21
# include <net/dst.h>
# include <asm/uaccess.h>
# include <linux/in6.h>
# define proto_priv cb
#endif /* NET21 */
#include <asm/checksum.h>
#include <net/ip.h>
#include "freeswan/radij.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/ipsec_sa.h"
#include "freeswan/ipsec_xform.h"
#include "freeswan/ipsec_tunnel.h"
#include "freeswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
#include "freeswan/ipcomp.h"
#include "zlib/zlib.h"
#include "zlib/zutil.h"
#include <pfkeyv2.h> /* 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 *ips, 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 == NULL) {
KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
"klips_debug:skb_compress: "
"passed in NULL skb, returning ERROR.\n");
if(flags != NULL) {
*flags |= IPCOMP_PARMERROR;
}
return skb;
}
if(ips == NULL) {
KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
"klips_debug:skb_compress: "
"passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
if(flags) {
*flags |= IPCOMP_PARMERROR;
}
return skb;
}
if (flags == NULL) {
KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
"klips_debug:skb_compress: "
"passed in NULL flags, returning ERROR.\n");
ipsec_kfree_skb(skb);
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 (ips->ips_comp_adapt_skip) {
KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
"klips_debug:skb_compress: "
"skipping compression: ips_comp_adapt_skip=%d.\n",
ips->ips_comp_adapt_skip);
ips->ips_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 (++(ips->ips_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);
ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
}
else if (ips->ips_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);
ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
ips->ips_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(ips->ips_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(ips->ips_said.spi),
ntohl(ips->ips_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 */
ips->ips_comp_adapt_skip = 0;
ips->ips_comp_adapt_tries = 0;
return skb;
}
struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, 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(!ips && sysctl_ipsec_inbound_policy_check) {
KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
"klips_error:skb_decompress: "
"passed in NULL ipsec_sa 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");
ipsec_kfree_skb(skb);
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
&& (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
"klips_error:skb_decompress: "
"called with incompatible IPCOMP packet (flags=%d, "
"cpi=%d), ips-compalg=%d, skipping decompression.\n",
ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
ips ? ips->ips_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;
ipsec_kfree_skb(nskb);
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",
ips ? ntohl(ips->ips_said.spi) : 0,
ips ? ntohl(ips->ips_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);
ipsec_kfree_skb(skb);
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 */
ipsec_kfree_skb(nskb);
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;
}
-927
View File
@@ -1,927 +0,0 @@
/*
* Modular extensions service and registration functions
*
* Author: JuanJo Ciarlante <[email protected]>
*
* Version: 0.8.1
*
* $Id: ipsec_alg.c,v 1.4 2004/06/13 19:57:49 as 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.
*
*/
#ifdef CONFIG_IPSEC_ALG
#define __NO_VERSION__
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/netdevice.h> /* struct device, and other headers */
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/ip.h> /* struct iphdr */
#include <linux/skbuff.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/types.h>
#include <linux/string.h> /* memcmp() */
#include <linux/random.h> /* get_random_bytes() */
#include <linux/errno.h> /* error codes */
#ifdef SPINLOCK
# ifdef SPINLOCK_23
# include <linux/spinlock.h> /* *lock* */
# else /* SPINLOCK_23 */
# include <asm/spinlock.h> /* *lock* */
# endif /* SPINLOCK_23 */
#endif /* SPINLOCK */
#ifdef NET_21
# include <asm/uaccess.h>
# include <linux/in6.h>
# define proto_priv cb
#endif /* NET21 */
#include "freeswan/ipsec_param.h"
#include <freeswan.h>
#include "freeswan/ipsec_sa.h"
#include "freeswan/radij.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/ipsec_radij.h"
#include "freeswan/ipsec_xform.h"
#include "freeswan/ipsec_tunnel.h"
#include "freeswan/ipsec_rcv.h"
#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
# include "freeswan/ipsec_ah.h"
#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
#ifdef CONFIG_IPSEC_ESP
# include "freeswan/ipsec_esp.h"
#endif /* !CONFIG_IPSEC_ESP */
#ifdef CONFIG_IPSEC_IPCOMP
# include "freeswan/ipcomp.h"
#endif /* CONFIG_IPSEC_COMP */
#include <pfkeyv2.h>
#include <pfkey.h>
#include "freeswan/ipsec_alg.h"
#ifndef CONFIG_IPSEC_ALG
#error This file _MUST_ be compiled with CONFIG_IPSEC_ALG enabled !
#endif
#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_e<keyminbits ||
sa_p->ips_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_a<keyminbits || sa_p->ips_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 <[email protected]>
*/
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\n", 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;
}
IPSEC_PROCFS_DEBUG_NO_STATIC
int
ipsec_xform_get_info(char *buffer,
char **start,
off_t offset,
int length IPSEC_PROC_LAST_ARG)
{
int len = 0;
off_t begin = 0;
int i;
struct list_head *head;
struct ipsec_alg *ixt;
KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
"klips_debug:ipsec_tncfg_get_info: "
"buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
buffer,
*start,
(int)offset,
length);
for(i = 0, head = ipsec_alg_hash_table; i< IPSEC_ALG_HASHSZ; i++, head++)
{
struct list_head *p;
for (p=head->next; p!=head; p=p->next)
{
ixt = list_entry(p, struct ipsec_alg, ixt_list);
len += ipsec_snprintf(buffer+len, length-len,
"VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_alg_id,
ixt->ixt_name, ixt->ixt_refcnt);
len += ipsec_snprintf(buffer+len, length-len,
"STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
ixt->ixt_state, ixt->ixt_blocksize,
ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits);
len += ipsec_snprintf(buffer+len, length-len,
"IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits);
switch(ixt->ixt_alg_type)
{
case IPSEC_ALG_TYPE_AUTH:
{
struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
len += ipsec_snprintf(buffer+len, length-len,
"KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
auth->ixt_a_keylen, auth->ixt_a_ctx_size,
auth->ixt_a_authlen);
break;
}
case IPSEC_ALG_TYPE_ENCRYPT:
{
struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
len += ipsec_snprintf(buffer+len, length-len,
"KEYLEN=%d CTXSIZE=%d ",
enc->ixt_e_keylen, enc->ixt_e_ctx_size);
break;
}
}
len += ipsec_snprintf(buffer+len, length-len, "\n");
}
}
*start = buffer + (offset - begin); /* Start of wanted data */
len -= (offset - begin); /* Start slop */
if (len > length)
len = length;
return len;
}
/*
* 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);
#endif /* CONFIG_IPSEC_ALG */
-755
View File
@@ -1,755 +0,0 @@
/*
* @(#) Initialization code.
* Copyright (C) 1996, 1997 John Ioannidis.
* Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs <[email protected]>
* 2001 Michael Richardson <[email protected]>
*
* 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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.3 2004/06/13 19:57:49 as Exp $";
#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include "freeswan/ipsec_param.h"
#ifdef MALLOC_SLAB
# include <linux/slab.h> /* kmalloc() */
#else /* MALLOC_SLAB */
# include <linux/malloc.h> /* kmalloc() */
#endif /* MALLOC_SLAB */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/interrupt.h> /* mark_bh */
#include <linux/netdevice.h> /* struct device, and other headers */
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/ip.h> /* struct iphdr */
#include <linux/in.h> /* struct sockaddr_in */
#include <linux/skbuff.h>
#include <linux/random.h> /* get_random_bytes() */
#include <freeswan.h>
#ifdef SPINLOCK
# ifdef SPINLOCK_23
# include <linux/spinlock.h> /* *lock* */
# else /* 23_SPINLOCK */
# include <asm/spinlock.h> /* *lock* */
# endif /* 23_SPINLOCK */
#endif /* SPINLOCK */
#ifdef NET_21
# include <asm/uaccess.h>
# include <linux/in6.h>
#endif /* NET_21 */
#include <asm/checksum.h>
#include <net/ip.h>
#ifdef CONFIG_PROC_FS
# include <linux/proc_fs.h>
#endif /* CONFIG_PROC_FS */
#ifdef NETLINK_SOCK
# include <linux/netlink.h>
#else
# include <net/netlink.h>
#endif
#include "freeswan/radij.h"
#include "freeswan/ipsec_life.h"
#include "freeswan/ipsec_stats.h"
#include "freeswan/ipsec_sa.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/ipsec_radij.h"
#include "freeswan/ipsec_xform.h"
#include "freeswan/ipsec_tunnel.h"
#include "freeswan/ipsec_rcv.h"
#include "freeswan/ipsec_ah.h"
#include "freeswan/ipsec_esp.h"
#ifdef CONFIG_IPSEC_IPCOMP
# include "freeswan/ipcomp.h"
#endif /* CONFIG_IPSEC_IPCOMP */
#include "freeswan/ipsec_proto.h"
#include "freeswan/ipsec_alg.h"
#include <pfkeyv2.h>
#include <pfkey.h>
#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("GPL");
#endif
#ifdef CONFIG_IPSEC_DEBUG
int debug_eroute = 0;
int debug_spi = 0;
int debug_netlink = 0;
#endif /* CONFIG_IPSEC_DEBUG */
struct prng ipsec_prng;
extern 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
static inline int
freeswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
{
#ifdef NETDEV_25
return inet_add_protocol(prot, protocol);
#else
inet_add_protocol(prot);
return 0;
#endif
}
static inline int
freeswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
{
#ifdef NETDEV_25
return inet_del_protocol(prot, protocol);
#else
inet_del_protocol(prot);
return 0;
#endif
}
/* void */
int
ipsec_init(void)
{
int error = 0;
unsigned char seed[256];
#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, FreeS/WAN IPSec version: %s\n",
ipsec_version_code());
error |= ipsec_proc_init();
#ifdef SPINLOCK
ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
#else /* SPINLOCK */
ipsec_sadb.sadb_lock = 0;
#endif /* SPINLOCK */
#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
freeswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP);
#endif /* CONFIG_IPSEC_ESP */
#ifdef CONFIG_IPSEC_AH
freeswan_inet_add_protocol(&ah_protocol, IPPROTO_AH);
#endif /* CONFIG_IPSEC_AH */
/* we never actually link IPCOMP to the stack */
#ifdef IPCOMP_USED_ALONE
#ifdef CONFIG_IPSEC_IPCOMP
freeswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP);
#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
get_random_bytes((void *)seed, sizeof(seed));
prng_init(&ipsec_prng, seed, sizeof(seed));
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();
KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
/* we never actually link IPCOMP to the stack */
#ifdef IPCOMP_USED_ALONE
#ifdef CONFIG_IPSEC_IPCOMP
if (freeswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
printk(KERN_INFO "klips_debug:ipsec_cleanup: "
"comp close: can't remove protocol\n");
#endif /* CONFIG_IPSEC_IPCOMP */
#endif /* IPCOMP_USED_ALONE */
#ifdef CONFIG_IPSEC_AH
if (freeswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
printk(KERN_INFO "klips_debug:ipsec_cleanup: "
"ah close: can't remove protocol\n");
#endif /* CONFIG_IPSEC_AH */
#ifdef CONFIG_IPSEC_ESP
if (freeswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 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_sadb_cleanup.\n");
error |= ipsec_sadb_cleanup(0);
error |= ipsec_sadb_free();
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();
prng_final(&ipsec_prng);
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.3 2004/06/13 19:57:49 as
* removed inclusion of ipsec_netlink.h
*
* Revision 1.2 2004/03/22 21:53:19 as
* merged alg-0.8.1 branch with HEAD
*
* Revision 1.1.4.1 2004/03/16 09:48:19 as
* alg-0.8.1rc12 patch merged
*
* Revision 1.1 2004/03/15 20:35:26 as
* added files from freeswan-2.04-x509-1.5.3
*
* Revision 1.89 2003/07/31 22:47:16 mcr
* preliminary (untested by FS-team) 2.5 patches.
*
* Revision 1.88 2003/06/22 20:05:36 mcr
* clarified why IPCOMP was not being registered, and put a new
* #ifdef in rather than #if 0.
*
* Revision 1.87 2002/09/20 15:40:51 rgb
* Added a lock to the global ipsec_sadb struct for future use.
* Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
* of freeing newly created structures when clearing the reftable upon startup
* to start from a known state.
*
* Revision 1.86 2002/08/15 18:39:15 rgb
* Move ipsec_prng outside debug code.
*
* Revision 1.85 2002/05/14 02:35:29 rgb
* Change reference to tdb to ipsa.
*
* Revision 1.84 2002/04/24 07:55:32 mcr
* #include patches and Makefiles for post-reorg compilation.
*
* Revision 1.83 2002/04/24 07:36:28 mcr
* Moved from ./klips/net/ipsec/ipsec_init.c,v
*
* Revision 1.82 2002/04/20 00:12:25 rgb
* Added esp IV CBC attack fix, disabled.
*
* Revision 1.81 2002/04/09 16:13:32 mcr
* switch license to straight GPL.
*
* 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 <[email protected]>
* 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 <freeswan.h> 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 <[email protected]>.
*
* 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:
*
*/
-210
View File
@@ -1,210 +0,0 @@
/*
* @(#) lifetime structure utilities
*
* Copyright (C) 2001 Richard Guy Briggs <[email protected]>
* and Michael Richardson <[email protected]>
*
* 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 2004/04/28 08:06:22 as 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 <linux/module.h>
#include <linux/config.h> /* for CONFIG_IP_FORWARD */
#include <linux/version.h>
#include <linux/kernel.h> /* printk() */
#include "freeswan/ipsec_param.h"
#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/skbuff.h>
#include <freeswan.h>
#include "freeswan/radij.h"
#include "freeswan/ipsec_life.h"
#include "freeswan/ipsec_xform.h"
#include "freeswan/ipsec_eroute.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/ipsec_radij.h"
#include "freeswan/ipsec_sa.h"
#include "freeswan/ipsec_tunnel.h"
#include "freeswan/ipsec_ipe4.h"
#include "freeswan/ipsec_ah.h"
#include "freeswan/ipsec_esp.h"
#ifdef CONFIG_IPSEC_IPCOMP
#include "freeswan/ipcomp.h"
#endif /* CONFIG_IPSEC_IPCOMP */
#include <pfkeyv2.h>
#include <pfkey.h>
#include "freeswan/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_lifetime_check: "
"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_lifetime_check: "
"soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
"soft expire message sent up, %s packet still processed.\n",
lifename,
IPS_XFORM_NAME(ips),
saname,
dir);
if(ips->ips_state != SADB_SASTATE_DYING) {
pfkey_expire(ips, 0);
}
ips->ips_state = SADB_SASTATE_DYING;
return ipsec_life_softdied;
}
return ipsec_life_okay;
}
/*
* This function takes a buffer (with length), a lifetime name and type,
* and formats a string to represent the current values of the lifetime.
*
* It returns the number of bytes that the format took (or would take,
* if the buffer were large enough: snprintf semantics).
* This is used in /proc routines and in debug output.
*/
int
ipsec_lifetime_format(char *buffer,
int buflen,
char *lifename,
enum ipsec_life_type timebaselife,
struct ipsec_lifetime64 *lifetime)
{
int len = 0;
__u64 count;
if(timebaselife == ipsec_life_timebased) {
count = jiffies/HZ - lifetime->ipl_count;
} else {
count = lifetime->ipl_count;
}
if(lifetime->ipl_count > 1 ||
lifetime->ipl_soft ||
lifetime->ipl_hard) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
len = ipsec_snprintf(buffer, buflen,
"%s(%Lu,%Lu,%Lu)",
lifename,
count,
lifetime->ipl_soft,
lifetime->ipl_hard);
#else /* XXX high 32 bits are not displayed */
len = ipsec_snprintf(buffer, buflen,
"%s(%lu,%lu,%lu)",
lifename,
(unsigned long)count,
(unsigned long)lifetime->ipl_soft,
(unsigned long)lifetime->ipl_hard);
#endif
}
return len;
}
void
ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
__u64 newvalue)
{
if(newvalue &&
(!lifetime->ipl_hard ||
(newvalue < lifetime->ipl_hard))) {
lifetime->ipl_hard = newvalue;
if(!lifetime->ipl_soft &&
(lifetime->ipl_hard < lifetime->ipl_soft)) {
lifetime->ipl_soft = lifetime->ipl_hard;
}
}
}
void
ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
__u64 newvalue)
{
if(newvalue &&
(!lifetime->ipl_soft ||
(newvalue < lifetime->ipl_soft))) {
lifetime->ipl_soft = newvalue;
if(lifetime->ipl_hard &&
(lifetime->ipl_hard < lifetime->ipl_soft)) {
lifetime->ipl_soft = lifetime->ipl_hard;
}
}
}
File diff suppressed because it is too large Load Diff
-448
View File
@@ -1,448 +0,0 @@
/*
* RCSID $Id: ipsec_md5c.c,v 1.1 2004/03/15 20:35:26 as 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 <asm/byteorder.h>
#include <linux/string.h>
#include "freeswan/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 <memory.h> here; <linux/string.h> 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(void *vcontext)
{
MD5_CTX *context = vcontext;
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 (vcontext, input, inputLen)
void *vcontext;
unsigned char *input; /* input block */
__u32 inputLen; /* length of input block */
{
MD5_CTX *context = vcontext;
__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, vcontext)
unsigned char digest[16]; /* message digest */
void *vcontext; /* context */
{
MD5_CTX *context = vcontext;
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 2004/03/15 20:35:26 as
* added files from freeswan-2.04-x509-1.5.3
*
* Revision 1.7 2002/09/10 01:45:14 mcr
* changed type of MD5_CTX and SHA1_CTX to void * so that
* the function prototypes would match, and could be placed
* into a pointer to a function.
*
* Revision 1.6 2002/04/24 07:55:32 mcr
* #include patches and Makefiles for post-reorg compilation.
*
* Revision 1.5 2002/04/24 07:36:28 mcr
* Moved from ./klips/net/ipsec/ipsec_md5c.c,v
*
* 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 <memory.h> 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.
*
*
*/
File diff suppressed because it is too large Load Diff
-550
View File
@@ -1,550 +0,0 @@
/*
* 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 2005/04/10 21:38:32 as Exp $
*/
#include <linux/config.h>
#include <linux/version.h>
#include <linux/kernel.h> /* printk() */
#include "freeswan/ipsec_param.h"
#ifdef MALLOC_SLAB
# include <linux/slab.h> /* kmalloc() */
#else /* MALLOC_SLAB */
# include <linux/malloc.h> /* kmalloc() */
#endif /* MALLOC_SLAB */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/interrupt.h> /* mark_bh */
#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/ip.h> /* struct iphdr */
#include <linux/skbuff.h>
#include <freeswan.h>
#ifdef SPINLOCK
# ifdef SPINLOCK_23
# include <linux/spinlock.h> /* *lock* */
# else /* 23_SPINLOCK */
# include <asm/spinlock.h> /* *lock* */
# endif /* 23_SPINLOCK */
#endif /* SPINLOCK */
#ifdef NET_21
# include <asm/uaccess.h>
# include <linux/in6.h>
#endif
#include <asm/checksum.h>
#include <net/ip.h>
#include "freeswan/ipsec_eroute.h"
#include "freeswan/ipsec_sa.h"
#include "freeswan/radij.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/radij.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/ipsec_radij.h"
#include "freeswan/ipsec_tunnel.h" /* struct ipsecpriv */
#include "freeswan/ipsec_xform.h"
#include <pfkeyv2.h>
#include <pfkey.h>
#include "freeswan/ipsec_proto.h"
#ifdef CONFIG_IPSEC_DEBUG
int debug_radij = 0;
#endif /* CONFIG_IPSEC_DEBUG */
struct radij_node_head *rnh = NULL;
#ifdef SPINLOCK
spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
#else /* SPINLOCK */
spinlock_t eroute_lock;
#endif /* SPINLOCK */
int
ipsec_radijinit(void)
{
maj_keylen = sizeof (struct sockaddr_encap);
rj_init();
if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
return -1;
return 0;
}
int
ipsec_radijcleanup(void)
{
int error;
spin_lock_bh(&eroute_lock);
error = radijcleanup();
spin_unlock_bh(&eroute_lock);
return error;
}
int
ipsec_cleareroutes(void)
{
int error;
spin_lock_bh(&eroute_lock);
error = radijcleartree();
spin_unlock_bh(&eroute_lock);
return error;
}
int
ipsec_breakroute(struct sockaddr_encap *eaddr,
struct sockaddr_encap *emask,
struct sk_buff **first,
struct sk_buff **last)
{
struct eroute *ro;
struct radij_node *rn;
int error;
#ifdef CONFIG_IPSEC_DEBUG
if (debug_eroute) {
char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
KLIPS_PRINT(debug_eroute,
"klips_debug:ipsec_breakroute: "
"attempting to delete eroute for %s:%d->%s:%d %d\n",
buf1, ntohs(eaddr->sen_sport),
buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
}
#endif /* CONFIG_IPSEC_DEBUG */
spin_lock_bh(&eroute_lock);
if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
spin_unlock_bh(&eroute_lock);
KLIPS_PRINT(debug_eroute,
"klips_debug:ipsec_breakroute: "
"node not found, eroute delete failed.\n");
return error;
}
spin_unlock_bh(&eroute_lock);
ro = (struct eroute *)rn;
KLIPS_PRINT(debug_eroute,
"klips_debug:ipsec_breakroute: "
"deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
ro,
ro->er_ident_s.data,
ro->er_ident_d.data,
ro->er_first,
ro->er_last);
if (ro->er_ident_s.data != NULL) {
kfree(ro->er_ident_s.data);
}
if (ro->er_ident_d.data != NULL) {
kfree(ro->er_ident_d.data);
}
if (ro->er_first != NULL) {
#if 0
struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
stats->tx_dropped--;
#endif
*first = ro->er_first;
}
if (ro->er_last != NULL) {
#if 0
struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
stats->tx_dropped--;
#endif
*last = ro->er_last;
}
if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
memset((caddr_t)rn, 0, sizeof (struct eroute));
kfree(rn);
return 0;
}
int
ipsec_makeroute(struct sockaddr_encap *eaddr,
struct sockaddr_encap *emask,
struct sa_id said,
uint32_t pid,
struct sk_buff *skb,
struct ident *ident_s,
struct ident *ident_d)
{
struct eroute *retrt;
int error;
char sa[SATOA_BUF];
size_t sa_len;
#ifdef CONFIG_IPSEC_DEBUG
if (debug_eroute) {
{
char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
sa_len = satoa(said, 0, sa, SATOA_BUF);
KLIPS_PRINT(debug_eroute,
"klips_debug:ipsec_makeroute: "
"attempting to allocate %lu bytes to insert eroute for %s:%d->%s:%d %d, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
(unsigned long) sizeof(struct eroute),
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"));
}
{
char buf1[sizeof(struct sockaddr_encap)*2 + 1];
char buf2[sizeof(struct sockaddr_encap)*2 + 1];
int i;
unsigned char *b1 = buf1,
*b2 = buf2,
*ea = (unsigned char *)eaddr,
*em = (unsigned char *)emask;
for (i=0; i<sizeof(struct sockaddr_encap); i++) {
sprintf(b1, "%02x", ea[i]);
sprintf(b2, "%02x", em[i]);
b1+=2;
b2+=2;
}
KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
}
}
#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;
{
struct sockaddr_encap **rkeyp = (struct sockaddr_encap**)&((retrt->er_rjt).rd_nodes->rj_key);
*rkeyp = &(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) {
KLIPS_PRINT(debug_eroute,
"klips_debug:ipsec_makeroute: "
"attempting to allocate %u bytes for ident_s.\n",
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) {
KLIPS_PRINT(debug_eroute,
"klips_debug:ipsec_makeroute: "
"attempting to allocate %u bytes for ident_d.\n",
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;
KLIPS_PRINT(debug_eroute,
"klips_debug:ipsec_makeroute: "
"calling rj_addroute now\n");
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 (error:%d)\n",
sa_len ? sa : " (error)", 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) {
char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
/*
subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
*/
subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
sa_len = satoa(retrt->er_said, 0, sa, SATOA_BUF);
KLIPS_PRINT(debug_eroute,
"klips_debug:ipsec_makeroute: "
"pid=%05d "
"count=%10d "
"lasttime=%6d "
"%-18s -> %-18s => %s\n",
retrt->er_pid,
retrt->er_count,
(int)(jiffies/HZ - retrt->er_lasttime),
buf1,
buf2,
sa_len ? sa : " (error)");
}
#endif /* CONFIG_IPSEC_DEBUG */
KLIPS_PRINT(debug_eroute,
"klips_debug:ipsec_makeroute: "
"succeeded.\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 && sysctl_ipsec_debug_verbose,
"klips_debug:ipsec_findroute: "
"found, points to proto=%d, spi=%x, dst=%x.\n",
((struct eroute*)rn)->er_said.proto,
ntohl(((struct eroute*)rn)->er_said.spi),
ntohl(((struct eroute*)rn)->er_said.dst.s_addr));
}
return (struct eroute *)rn;
}
#ifdef CONFIG_PROC_FS
/** ipsec_rj_walker_procprint: print one line of eroute table output.
*
* Theoretical BUG: if w->length is less than the length
* of some line we should produce, that line will never
* be finished. In effect, the "file" will stop part way
* through that line.
*/
int
ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
{
struct eroute *ro = (struct eroute *)rn;
struct rjtentry *rd = (struct rjtentry *)rn;
struct wsbuf *w = (struct wsbuf *)w0;
char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
char buf3[16];
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=0p%p, w0=0p%p\n",
rn,
w0);
if (rn->rj_b >= 0) {
return 0;
}
key = rd_key(rd);
mask = rd_mask(rd);
if (key == NULL || mask == NULL) {
return 0;
}
buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
if(key->sen_sport != 0) {
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));
if(key->sen_dport != 0) {
sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
}
buf3[0]='\0';
if(key->sen_proto != 0) {
sprintf(buf3, ":%d", key->sen_proto);
}
sa_len = satoa(ro->er_said, 0, sa, SATOA_BUF);
w->len += ipsec_snprintf(w->buffer + w->len,
w->length - w->len,
"%-10d "
"%-18s -> %-18s => %s%s\n",
ro->er_count,
buf1,
buf2,
sa_len ? sa : " (error)",
buf3);
{
/* snprintf can only fill the last character with NUL
* so the maximum useful character is w->length-1.
* However, if w->length == 0, we cannot go back.
* (w->length surely cannot be negative.)
*/
int max_content = w->length > 0? w->length-1 : 0;
if (w->len >= max_content) {
/* we've done all that can fit -- stop treewalking */
w->len = max_content; /* truncate crap */
return -ENOBUFS;
} else {
const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
if (pos <= w->offset) {
/* all is before first interesting character:
* discard, but note where we are.
*/
w->len = 0;
w->begin = pos;
}
return 0;
}
}
}
#endif /* CONFIG_PROC_FS */
int
ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
{
struct eroute *ro;
struct rjtentry *rd = (struct rjtentry *)rn;
struct radij_node *rn2;
int error;
struct sockaddr_encap *key, *mask;
key = rd_key(rd);
mask = rd_mask(rd);
if(!key || !mask) {
return -ENODATA;
}
#ifdef CONFIG_IPSEC_DEBUG
if(debug_radij) {
char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
KLIPS_PRINT(debug_radij,
"klips_debug:ipsec_rj_walker_delete: "
"deleting: %s -> %s\n",
buf1,
buf2);
}
#endif /* CONFIG_IPSEC_DEBUG */
if((error = rj_delete(key, mask, rnh, &rn2))) {
KLIPS_PRINT(debug_radij,
"klips_debug:ipsec_rj_walker_delete: "
"rj_delete failed with error=%d.\n", error);
return error;
}
if(rn2 != rn) {
printk("klips_debug:ipsec_rj_walker_delete: "
"tried to delete a different node?!? This should never happen!\n");
}
ro = (struct eroute *)rn;
if (ro->er_ident_s.data)
kfree(ro->er_ident_s.data);
if (ro->er_ident_d.data)
kfree(ro->er_ident_d.data);
memset((caddr_t)rn, 0, sizeof (struct eroute));
kfree(rn);
return 0;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-219
View File
@@ -1,219 +0,0 @@
/*
* RCSID $Id: ipsec_sha1.c,v 1.1 2004/03/15 20:35:26 as 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 <asm/byteorder.h>
#include <linux/string.h>
#include "freeswan/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(void *vcontext)
{
SHA1_CTX* context = vcontext;
/* 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(void *vcontext, unsigned char* data, __u32 len)
{
SHA1_CTX* context = vcontext;
__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], void *vcontext)
{
__u32 i, j;
unsigned char finalcount[8];
SHA1_CTX* context = vcontext;
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 2004/03/15 20:35:26 as
* added files from freeswan-2.04-x509-1.5.3
*
* Revision 1.8 2002/09/10 01:45:14 mcr
* changed type of MD5_CTX and SHA1_CTX to void * so that
* the function prototypes would match, and could be placed
* into a pointer to a function.
*
* Revision 1.7 2002/04/24 07:55:32 mcr
* #include patches and Makefiles for post-reorg compilation.
*
* Revision 1.6 2002/04/24 07:36:30 mcr
* Moved from ./klips/net/ipsec/ipsec_sha1.c,v
*
* 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
*
*
*/
File diff suppressed because it is too large Load Diff
-73
View File
@@ -1,73 +0,0 @@
/*
* 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* 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 2004/06/13 19:57:50 as Exp $
*/
#include <linux/config.h>
#include <linux/version.h>
#include <linux/kernel.h> /* printk() */
#include "freeswan/ipsec_param.h"
#ifdef MALLOC_SLAB
# include <linux/slab.h> /* kmalloc() */
#else /* MALLOC_SLAB */
# include <linux/malloc.h> /* kmalloc() */
#endif /* MALLOC_SLAB */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/interrupt.h> /* mark_bh */
#include <linux/netdevice.h> /* struct device, and other headers */
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/ip.h> /* struct iphdr */
#include <linux/skbuff.h>
#include <linux/random.h> /* get_random_bytes() */
#include <freeswan.h>
#ifdef SPINLOCK
# ifdef SPINLOCK_23
# include <linux/spinlock.h> /* *lock* */
# else /* SPINLOCK_23 */
# include <asm/spinlock.h> /* *lock* */
# endif /* SPINLOCK_23 */
#endif /* SPINLOCK */
#ifdef NET_21
# include <asm/uaccess.h>
# include <linux/in6.h>
#endif
#include <asm/checksum.h>
#include <net/ip.h>
#include "freeswan/radij.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/ipsec_radij.h"
#include "freeswan/ipsec_xform.h"
#include "freeswan/ipsec_ipe4.h"
#include "freeswan/ipsec_ah.h"
#include "freeswan/ipsec_esp.h"
#include <pfkeyv2.h>
#include <pfkey.h>
#ifdef CONFIG_IPSEC_DEBUG
int debug_xform = 0;
#endif /* CONFIG_IPSEC_DEBUG */
#ifdef SPINLOCK
spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
#else /* SPINLOCK */
spinlock_t tdb_lock;
#endif /* SPINLOCK */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
-851
View File
@@ -1,851 +0,0 @@
/*
* @(#) RFC2367 PF_KEYv2 Key management API message parser
* Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <[email protected]>
*
* 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 <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* RCSID $Id: pfkey_v2_ext_process.c,v 1.3 2004/06/13 19:57:50 as Exp $
*/
/*
* Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
*/
char pfkey_v2_ext_process_c_version[] = "$Id: pfkey_v2_ext_process.c,v 1.3 2004/06/13 19:57:50 as Exp $";
#include <linux/config.h>
#include <linux/version.h>
#include <linux/kernel.h> /* printk() */
#include "freeswan/ipsec_param.h"
#ifdef MALLOC_SLAB
# include <linux/slab.h> /* kmalloc() */
#else /* MALLOC_SLAB */
# include <linux/malloc.h> /* kmalloc() */
#endif /* MALLOC_SLAB */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/interrupt.h> /* mark_bh */
#include <linux/netdevice.h> /* struct device, and other headers */
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/ip.h> /* struct iphdr */
#include <linux/skbuff.h>
#include <freeswan.h>
#include <crypto/des.h>
#ifdef SPINLOCK
# ifdef SPINLOCK_23
# include <linux/spinlock.h> /* *lock* */
# else /* SPINLOCK_23 */
# include <asm/spinlock.h> /* *lock* */
# endif /* SPINLOCK_23 */
#endif /* SPINLOCK */
#ifdef NET_21
# include <asm/uaccess.h>
# include <linux/in6.h>
# define ip_chk_addr inet_addr_type
# define IS_MYADDR RTN_LOCAL
#endif
#include <asm/checksum.h>
#include <net/ip.h>
#ifdef NETLINK_SOCK
# include <linux/netlink.h>
#else
# include <net/netlink.h>
#endif
#include <linux/random.h> /* get_random_bytes() */
#include "freeswan/radij.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/ipsec_sa.h"
#include "freeswan/ipsec_radij.h"
#include "freeswan/ipsec_xform.h"
#include "freeswan/ipsec_ah.h"
#include "freeswan/ipsec_esp.h"
#include "freeswan/ipsec_tunnel.h"
#include "freeswan/ipsec_rcv.h"
#include "freeswan/ipcomp.h"
#include <pfkeyv2.h>
#include <pfkey.h>
#include "freeswan/ipsec_proto.h"
#include "freeswan/ipsec_alg.h"
#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
int
pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
int error = 0;
struct ipsec_sa* ipsp;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_sa_process: .\n");
if(!extr || !extr->ips) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_sa_process: "
"extr or extr->ips is NULL, fatal\n");
SENDERR(EINVAL);
}
switch(pfkey_ext->sadb_ext_type) {
case SADB_EXT_SA:
ipsp = extr->ips;
break;
case SADB_X_EXT_SA2:
if(extr->ips2 == NULL) {
extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
}
if(extr->ips2 == NULL) {
SENDERR(-error);
}
ipsp = extr->ips2;
break;
default:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_sa_process: "
"invalid exttype=%d.\n",
pfkey_ext->sadb_ext_type);
SENDERR(EINVAL);
}
ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
ipsp->ips_state = pfkey_sa->sadb_sa_state;
ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref;
switch(ipsp->ips_said.proto) {
case IPPROTO_AH:
ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
ipsp->ips_encalg = SADB_EALG_NONE;
break;
case IPPROTO_ESP:
ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
#ifdef CONFIG_IPSEC_ALG
ipsec_alg_sa_init(ipsp);
#endif /* CONFIG_IPSEC_ALG */
break;
case IPPROTO_IPIP:
ipsp->ips_authalg = AH_NONE;
ipsp->ips_encalg = ESP_NONE;
break;
#ifdef CONFIG_IPSEC_IPCOMP
case IPPROTO_COMP:
ipsp->ips_authalg = AH_NONE;
ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
break;
#endif /* CONFIG_IPSEC_IPCOMP */
case IPPROTO_INT:
ipsp->ips_authalg = AH_NONE;
ipsp->ips_encalg = ESP_NONE;
break;
case 0:
break;
default:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_sa_process: "
"unknown proto=%d.\n",
ipsp->ips_said.proto);
SENDERR(EINVAL);
}
errlab:
return error;
}
int
pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_lifetime_process: .\n");
if(!extr || !extr->ips) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_lifetime_process: "
"extr or extr->ips is NULL, fatal\n");
SENDERR(EINVAL);
}
switch(pfkey_lifetime->sadb_lifetime_exttype) {
case SADB_EXT_LIFETIME_CURRENT:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_lifetime_process: "
"lifetime_current not supported yet.\n");
SENDERR(EINVAL);
break;
case SADB_EXT_LIFETIME_HARD:
ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
pfkey_lifetime->sadb_lifetime_allocations);
ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
pfkey_lifetime->sadb_lifetime_bytes);
ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
pfkey_lifetime->sadb_lifetime_addtime);
ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
pfkey_lifetime->sadb_lifetime_usetime);
break;
case SADB_EXT_LIFETIME_SOFT:
ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
pfkey_lifetime->sadb_lifetime_allocations);
ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
pfkey_lifetime->sadb_lifetime_bytes);
ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
pfkey_lifetime->sadb_lifetime_addtime);
ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
pfkey_lifetime->sadb_lifetime_usetime);
break;
default:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_lifetime_process: "
"invalid exttype=%d.\n",
pfkey_ext->sadb_ext_type);
SENDERR(EINVAL);
}
errlab:
return error;
}
int
pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
int saddr_len = 0;
char ipaddr_txt[ADDRTOA_BUF];
unsigned char **sap;
unsigned short * portp = 0;
struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
struct ipsec_sa* ipsp;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process:\n");
if(!extr || !extr->ips) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"extr or extr->ips is NULL, fatal\n");
SENDERR(EINVAL);
}
switch(s->sa_family) {
case AF_INET:
saddr_len = sizeof(struct sockaddr_in);
addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found address family=%d, AF_INET, %s.\n",
s->sa_family,
ipaddr_txt);
break;
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case AF_INET6:
saddr_len = sizeof(struct sockaddr_in6);
break;
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
default:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"s->sa_family=%d not supported.\n",
s->sa_family);
SENDERR(EPFNOSUPPORT);
}
switch(pfkey_address->sadb_address_exttype) {
case SADB_EXT_ADDRESS_SRC:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found src address.\n");
sap = (unsigned char **)&(extr->ips->ips_addr_s);
extr->ips->ips_addr_s_size = saddr_len;
break;
case SADB_EXT_ADDRESS_DST:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found dst address.\n");
sap = (unsigned char **)&(extr->ips->ips_addr_d);
extr->ips->ips_addr_d_size = saddr_len;
break;
case SADB_EXT_ADDRESS_PROXY:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found proxy address.\n");
sap = (unsigned char **)&(extr->ips->ips_addr_p);
extr->ips->ips_addr_p_size = saddr_len;
break;
case SADB_X_EXT_ADDRESS_DST2:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found 2nd dst address.\n");
if(extr->ips2 == NULL) {
extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
}
if(extr->ips2 == NULL) {
SENDERR(-error);
}
sap = (unsigned char **)&(extr->ips2->ips_addr_d);
extr->ips2->ips_addr_d_size = saddr_len;
break;
case SADB_X_EXT_ADDRESS_SRC_FLOW:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found src flow address.\n");
if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
SENDERR(ENOMEM);
}
sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
portp = &(extr->eroute->er_eaddr.sen_sport);
break;
case SADB_X_EXT_ADDRESS_DST_FLOW:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found dst flow address.\n");
if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
SENDERR(ENOMEM);
}
sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
portp = &(extr->eroute->er_eaddr.sen_dport);
break;
case SADB_X_EXT_ADDRESS_SRC_MASK:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found src mask address.\n");
if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
SENDERR(ENOMEM);
}
sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
portp = &(extr->eroute->er_emask.sen_sport);
break;
case SADB_X_EXT_ADDRESS_DST_MASK:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found dst mask address.\n");
if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
SENDERR(ENOMEM);
}
sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
portp = &(extr->eroute->er_emask.sen_dport);
break;
#ifdef NAT_TRAVERSAL
case SADB_X_EXT_NAT_T_OA:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"found NAT-OA address.\n");
sap = (unsigned char **)&(extr->ips->ips_natt_oa);
extr->ips->ips_natt_oa_size = saddr_len;
break;
#endif
default:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"unrecognised ext_type=%d.\n",
pfkey_address->sadb_address_exttype);
SENDERR(EINVAL);
}
switch(pfkey_address->sadb_address_exttype) {
case SADB_EXT_ADDRESS_SRC:
case SADB_EXT_ADDRESS_DST:
case SADB_EXT_ADDRESS_PROXY:
case SADB_X_EXT_ADDRESS_DST2:
#ifdef NAT_TRAVERSAL
case SADB_X_EXT_NAT_T_OA:
#endif
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"allocating %d bytes for saddr.\n",
saddr_len);
if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
SENDERR(ENOMEM);
}
memcpy(*sap, s, saddr_len);
break;
default:
if(s->sa_family != AF_INET) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"s->sa_family=%d not supported.\n",
s->sa_family);
SENDERR(EPFNOSUPPORT);
}
(unsigned long)(*sap) = ((struct sockaddr_in*)s)->sin_addr.s_addr;
if (portp != 0)
*portp = ((struct sockaddr_in*)s)->sin_port;
#ifdef CONFIG_IPSEC_DEBUG
if(extr->eroute) {
char buf1[64], buf2[64];
if (debug_pfkey) {
subnettoa(extr->eroute->er_eaddr.sen_ip_src,
extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_parse: "
"extr->eroute set to %s:%d->%s:%d\n",
buf1,
ntohs(extr->eroute->er_eaddr.sen_sport),
buf2,
ntohs(extr->eroute->er_eaddr.sen_dport));
}
}
#endif /* CONFIG_IPSEC_DEBUG */
}
ipsp = extr->ips;
switch(pfkey_address->sadb_address_exttype) {
case SADB_X_EXT_ADDRESS_DST2:
ipsp = extr->ips2;
case SADB_EXT_ADDRESS_DST:
if(s->sa_family == AF_INET) {
ipsp->ips_said.dst.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
0,
ipaddr_txt,
sizeof(ipaddr_txt));
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"ips_said.dst set to %s.\n",
ipaddr_txt);
} else {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: "
"uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
s->sa_family);
}
default:
break;
}
/* XXX check if port!=0 */
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_address_process: successful.\n");
errlab:
return error;
}
int
pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_key_process: .\n");
if(!extr || !extr->ips) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_key_process: "
"extr or extr->ips is NULL, fatal\n");
SENDERR(EINVAL);
}
switch(pfkey_key->sadb_key_exttype) {
case SADB_EXT_KEY_AUTH:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_key_process: "
"allocating %d bytes for authkey.\n",
DIVUP(pfkey_key->sadb_key_bits, 8));
if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_key_process: "
"memory allocation error.\n");
SENDERR(ENOMEM);
}
extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
memcpy(extr->ips->ips_key_a,
(char*)pfkey_key + sizeof(struct sadb_key),
extr->ips->ips_key_a_size);
break;
case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_key_process: "
"allocating %d bytes for enckey.\n",
DIVUP(pfkey_key->sadb_key_bits, 8));
if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_key_process: "
"memory allocation error.\n");
SENDERR(ENOMEM);
}
extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
memcpy(extr->ips->ips_key_e,
(char*)pfkey_key + sizeof(struct sadb_key),
extr->ips->ips_key_e_size);
break;
default:
SENDERR(EINVAL);
}
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_key_process: "
"success.\n");
errlab:
return error;
}
int
pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
int data_len;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_ident_process: .\n");
if(!extr || !extr->ips) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_ident_process: "
"extr or extr->ips is NULL, fatal\n");
SENDERR(EINVAL);
}
switch(pfkey_ident->sadb_ident_exttype) {
case SADB_EXT_IDENTITY_SRC:
data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
if(data_len) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_ident_process: "
"allocating %d bytes for ident_s.\n",
data_len);
if(!(extr->ips->ips_ident_s.data
= kmalloc(data_len, GFP_KERNEL))) {
SENDERR(ENOMEM);
}
memcpy(extr->ips->ips_ident_s.data,
(char*)pfkey_ident + sizeof(struct sadb_ident),
data_len);
} else {
extr->ips->ips_ident_s.data = NULL;
}
break;
case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
if(data_len) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_ident_process: "
"allocating %d bytes for ident_d.\n",
data_len);
if(!(extr->ips->ips_ident_d.data
= kmalloc(data_len, GFP_KERNEL))) {
SENDERR(ENOMEM);
}
memcpy(extr->ips->ips_ident_d.data,
(char*)pfkey_ident + sizeof(struct sadb_ident),
data_len);
} else {
extr->ips->ips_ident_d.data = NULL;
}
break;
default:
SENDERR(EINVAL);
}
errlab:
return error;
}
int
pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_sens_process: "
"Sorry, I can't process exttype=%d yet.\n",
pfkey_ext->sadb_ext_type);
SENDERR(EINVAL); /* don't process these yet */
errlab:
return error;
}
int
pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_prop_process: "
"Sorry, I can't process exttype=%d yet.\n",
pfkey_ext->sadb_ext_type);
SENDERR(EINVAL); /* don't process these yet */
errlab:
return error;
}
int
pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_supported_process: "
"Sorry, I can't process exttype=%d yet.\n",
pfkey_ext->sadb_ext_type);
SENDERR(EINVAL); /* don't process these yet */
errlab:
return error;
}
int
pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_spirange_process: .\n");
/* errlab: */
return error;
}
int
pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_kmprivate_process: "
"Sorry, I can't process exttype=%d yet.\n",
pfkey_ext->sadb_ext_type);
SENDERR(EINVAL); /* don't process these yet */
errlab:
return error;
}
int
pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_satype_process: .\n");
if(!extr || !extr->ips) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_satype_process: "
"extr or extr->ips is NULL, fatal\n");
SENDERR(EINVAL);
}
if(extr->ips2 == NULL) {
extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
}
if(extr->ips2 == NULL) {
SENDERR(-error);
}
if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_satype_process: "
"proto lookup from satype=%d failed.\n",
pfkey_x_satype->sadb_x_satype_satype);
SENDERR(EINVAL);
}
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_satype_process: "
"protocol==%d decoded from satype==%d(%s).\n",
extr->ips2->ips_said.proto,
pfkey_x_satype->sadb_x_satype_satype,
satype2name(pfkey_x_satype->sadb_x_satype_satype));
errlab:
return error;
}
#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
int
pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
if(!pfkey_x_nat_t_type) {
printk("klips_debug:pfkey_x_nat_t_type_process: "
"null pointer passed in\n");
SENDERR(EINVAL);
}
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_nat_t_type_process: %d.\n",
pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
if(!extr || !extr->ips) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_nat_t_type_process: "
"extr or extr->ips is NULL, fatal\n");
SENDERR(EINVAL);
}
switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
case ESPINUDP_WITH_NON_IKE: /* with Non-IKE */
case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
break;
default:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_nat_t_type_process: "
"unknown type %d.\n",
pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
SENDERR(EINVAL);
break;
}
errlab:
return error;
}
int
pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
if(!pfkey_x_nat_t_port) {
printk("klips_debug:pfkey_x_nat_t_port_process: "
"null pointer passed in\n");
SENDERR(EINVAL);
}
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
if(!extr || !extr->ips) {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_nat_t_type_process: "
"extr or extr->ips is NULL, fatal\n");
SENDERR(EINVAL);
}
switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
case SADB_X_EXT_NAT_T_SPORT:
extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
break;
case SADB_X_EXT_NAT_T_DPORT:
extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
break;
default:
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_nat_t_port_process: "
"unknown exttype %d.\n",
pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
SENDERR(EINVAL);
break;
}
errlab:
return error;
}
#endif
int
pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
{
int error = 0;
struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
if(!pfkey_x_debug) {
printk("klips_debug:pfkey_x_debug_process: "
"null pointer passed in\n");
SENDERR(EINVAL);
}
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_debug_process: .\n");
#ifdef CONFIG_IPSEC_DEBUG
if(pfkey_x_debug->sadb_x_debug_netlink >>
(sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
pfkey_x_debug->sadb_x_debug_netlink &=
~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
#ifdef CONFIG_IPSEC_IPCOMP
sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
#endif /* CONFIG_IPSEC_IPCOMP */
sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_debug_process: "
"set\n");
} else {
KLIPS_PRINT(debug_pfkey,
"klips_debug:pfkey_x_debug_process: "
"unset\n");
debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
#ifdef CONFIG_IPSEC_IPCOMP
sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
#endif /* CONFIG_IPSEC_IPCOMP */
sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
}
#else /* CONFIG_IPSEC_DEBUG */
printk("klips_debug:pfkey_x_debug_process: "
"debugging not enabled\n");
SENDERR(EINVAL);
#endif /* CONFIG_IPSEC_DEBUG */
errlab:
return error;
}
File diff suppressed because it is too large Load Diff
-992
View File
@@ -1,992 +0,0 @@
char radij_c_version[] = "RCSID $Id: radij.c,v 1.2 2004/06/13 19:57:50 as Exp $";
/*
* This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
*
* Variable and procedure names have been modified so that they don't
* conflict with the original BSD code, as a small number of modifications
* have been introduced and we may want to reuse this code in BSD.
*
* The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
* chi or a German ch sound (as `doch', not as in `milch'), or even a
* spanish j as in Juan. It is not as far back in the throat like
* the corresponding Hebrew sound, nor is it a soft breath like the English h.
* It has nothing to do with the Dutch ij sound.
*
* Here is the appropriate copyright notice:
*/
/*
* Copyright (c) 1988, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)radix.c 8.2 (Berkeley) 1/4/94
*/
/*
* Routines to build and maintain radix trees for routing lookups.
*/
#include <linux/config.h>
#include <linux/version.h>
#include <linux/kernel.h> /* printk() */
#include "freeswan/ipsec_param.h"
#ifdef MALLOC_SLAB
# include <linux/slab.h> /* kmalloc() */
#else /* MALLOC_SLAB */
# include <linux/malloc.h> /* kmalloc() */
#endif /* MALLOC_SLAB */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/interrupt.h> /* mark_bh */
#include <linux/netdevice.h> /* struct device, and other headers */
#include <linux/etherdevice.h> /* eth_type_trans */
#include <linux/ip.h> /* struct iphdr */
#include <linux/skbuff.h>
#ifdef NET_21
# include <asm/uaccess.h>
# include <linux/in6.h>
#endif /* NET_21 */
#include <asm/checksum.h>
#include <net/ip.h>
#include <freeswan.h>
#include "freeswan/radij.h"
#include "freeswan/ipsec_encap.h"
#include "freeswan/ipsec_radij.h"
int maj_keylen;
struct radij_mask *rj_mkfreelist;
struct radij_node_head *mask_rjhead;
static int gotOddMasks;
static char *maskedKey;
static char *rj_zeroes, *rj_ones;
#define rj_masktop (mask_rjhead->rnh_treetop)
#ifdef Bcmp
# undef Bcmp
#endif /* Bcmp */
#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
/*
* The data structure for the keys is a radix tree with one way
* branching removed. The index rj_b at an internal node n represents a bit
* position to be tested. The tree is arranged so that all descendants
* of a node n have keys whose bits all agree up to position rj_b - 1.
* (We say the index of n is rj_b.)
*
* There is at least one descendant which has a one bit at position rj_b,
* and at least one with a zero there.
*
* A route is determined by a pair of key and mask. We require that the
* bit-wise logical and of the key and mask to be the key.
* We define the index of a route to associated with the mask to be
* the first bit number in the mask where 0 occurs (with bit number 0
* representing the highest order bit).
*
* We say a mask is normal if every bit is 0, past the index of the mask.
* If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
* and m is a normal mask, then the route applies to every descendant of n.
* If the index(m) < rj_b, this implies the trailing last few bits of k
* before bit b are all 0, (and hence consequently true of every descendant
* of n), so the route applies to all descendants of the node as well.
*
* The present version of the code makes no use of normal routes,
* but similar logic shows that a non-normal mask m such that
* index(m) <= index(n) could potentially apply to many children of n.
* Thus, for each non-host route, we attach its mask to a list at an internal
* node as high in the tree as we can go.
*/
struct radij_node *
rj_search(v_arg, head)
void *v_arg;
struct radij_node *head;
{
register struct radij_node *x;
register caddr_t v;
for (x = head, v = v_arg; x->rj_b >= 0;) {
if (x->rj_bmask & v[x->rj_off])
x = x->rj_r;
else
x = x->rj_l;
}
return (x);
};
struct radij_node *
rj_search_m(v_arg, head, m_arg)
struct radij_node *head;
void *v_arg, *m_arg;
{
register struct radij_node *x;
register caddr_t v = v_arg, m = m_arg;
for (x = head; x->rj_b >= 0;) {
if ((x->rj_bmask & m[x->rj_off]) &&
(x->rj_bmask & v[x->rj_off]))
x = x->rj_r;
else
x = x->rj_l;
}
return x;
};
int
rj_refines(m_arg, n_arg)
void *m_arg, *n_arg;
{
register caddr_t m = m_arg, n = n_arg;
register caddr_t lim, lim2 = lim = n + *(u_char *)n;
int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
int masks_are_equal = 1;
if (longer > 0)
lim -= longer;
while (n < lim) {
if (*n & ~(*m))
return 0;
if (*n++ != *m++)
masks_are_equal = 0;
}
while (n < lim2)
if (*n++)
return 0;
if (masks_are_equal && (longer < 0))
for (lim2 = m - longer; m < lim2; )
if (*m++)
return 1;
return (!masks_are_equal);
}
struct radij_node *
rj_match(v_arg, head)
void *v_arg;
struct radij_node_head *head;
{
caddr_t v = v_arg;
register struct radij_node *t = head->rnh_treetop, *x;
register caddr_t cp = v, cp2, cp3;
caddr_t cplim, mstart;
struct radij_node *saved_t, *top = t;
int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
/*
* Open code rj_search(v, top) to avoid overhead of extra
* subroutine call.
*/
for (; t->rj_b >= 0; ) {
if (t->rj_bmask & cp[t->rj_off])
t = t->rj_r;
else
t = t->rj_l;
}
/*
* See if we match exactly as a host destination
*/
KLIPS_PRINT(debug_radij,
"klips_debug:rj_match: "
"* See if we match exactly as a host destination\n");
cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
for (; cp < cplim; cp++, cp2++)
if (*cp != *cp2)
goto on1;
/*
* This extra grot is in case we are explicitly asked
* to look up the default. Ugh!
*/
if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
t = t->rj_dupedkey;
return t;
on1:
matched_off = cp - v;
saved_t = t;
KLIPS_PRINT(debug_radij,
"klips_debug:rj_match: "
"** try to match a leaf, t=0p%p\n", t);
do {
if (t->rj_mask) {
/*
* Even if we don't match exactly as a hosts;
* we may match if the leaf we wound up at is
* a route to a net.
*/
cp3 = matched_off + t->rj_mask;
cp2 = matched_off + t->rj_key;
for (; cp < cplim; cp++)
if ((*cp2++ ^ *cp) & *cp3++)
break;
if (cp == cplim)
return t;
cp = matched_off + v;
}
} while ((t = t->rj_dupedkey));
t = saved_t;
/* start searching up the tree */
KLIPS_PRINT(debug_radij,
"klips_debug:rj_match: "
"*** start searching up the tree, t=0p%p\n",
t);
do {
register struct radij_mask *m;
t = t->rj_p;
KLIPS_PRINT(debug_radij,
"klips_debug:rj_match: "
"**** t=0p%p\n",
t);
if ((m = t->rj_mklist)) {
/*
* After doing measurements here, it may
* turn out to be faster to open code
* rj_search_m here instead of always
* copying and masking.
*/
/* off = min(t->rj_off, matched_off); */
off = t->rj_off;
if (matched_off < off)
off = matched_off;
mstart = maskedKey + off;
do {
cp2 = mstart;
cp3 = m->rm_mask + off;
KLIPS_PRINT(debug_radij,
"klips_debug:rj_match: "
"***** cp2=0p%p cp3=0p%p\n",
cp2, cp3);
for (cp = v + off; cp < cplim;)
*cp2++ = *cp++ & *cp3++;
x = rj_search(maskedKey, t);
while (x && x->rj_mask != m->rm_mask)
x = x->rj_dupedkey;
if (x &&
(Bcmp(mstart, x->rj_key + off,
vlen - off) == 0))
return x;
} while ((m = m->rm_mklist));
}
} while (t != top);
KLIPS_PRINT(debug_radij,
"klips_debug:rj_match: "
"***** not found.\n");
return 0;
};
#ifdef RJ_DEBUG
int rj_nodenum;
struct radij_node *rj_clist;
int rj_saveinfo;
DEBUG_NO_STATIC void traverse(struct radij_node *);
#ifdef RJ_DEBUG2
int rj_debug = 1;
#else
int rj_debug = 0;
#endif /* RJ_DEBUG2 */
#endif /* RJ_DEBUG */
struct radij_node *
rj_newpair(v, b, nodes)
void *v;
int b;
struct radij_node nodes[2];
{
register struct radij_node *tt = nodes, *t = tt + 1;
t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
t->rj_l = tt; t->rj_off = b >> 3;
tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
tt->rj_flags = t->rj_flags = RJF_ACTIVE;
#ifdef RJ_DEBUG
tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
#endif /* RJ_DEBUG */
return t;
}
struct radij_node *
rj_insert(v_arg, head, dupentry, nodes)
void *v_arg;
struct radij_node_head *head;
int *dupentry;
struct radij_node nodes[2];
{
caddr_t v = v_arg;
struct radij_node *top = head->rnh_treetop;
int head_off = top->rj_off, vlen = (int)*((u_char *)v);
register struct radij_node *t = rj_search(v_arg, top);
register caddr_t cp = v + head_off;
register int b;
struct radij_node *tt;
/*
*find first bit at which v and t->rj_key differ
*/
{
register caddr_t cp2 = t->rj_key + head_off;
register int cmp_res;
caddr_t cplim = v + vlen;
while (cp < cplim)
if (*cp2++ != *cp++)
goto on1;
*dupentry = 1;
return t;
on1:
*dupentry = 0;
cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
for (b = (cp - v) << 3; cmp_res; b--)
cmp_res >>= 1;
}
{
register struct radij_node *p, *x = top;
cp = v;
do {
p = x;
if (cp[x->rj_off] & x->rj_bmask)
x = x->rj_r;
else x = x->rj_l;
} while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
#ifdef RJ_DEBUG
if (rj_debug)
printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
#endif /* RJ_DEBUG */
t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
if ((cp[p->rj_off] & p->rj_bmask) == 0)
p->rj_l = t;
else
p->rj_r = t;
x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
if ((cp[t->rj_off] & t->rj_bmask) == 0) {
t->rj_r = x;
} else {
t->rj_r = tt; t->rj_l = x;
}
#ifdef RJ_DEBUG
if (rj_debug)
printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
#endif /* RJ_DEBUG */
}
return (tt);
}
struct radij_node *
rj_addmask(n_arg, search, skip)
int search, skip;
void *n_arg;
{
caddr_t netmask = (caddr_t)n_arg;
register struct radij_node *x;
register caddr_t cp, cplim;
register int b, mlen, j;
int maskduplicated;
mlen = *(u_char *)netmask;
if (search) {
x = rj_search(netmask, rj_masktop);
mlen = *(u_char *)netmask;
if (Bcmp(netmask, x->rj_key, mlen) == 0)
return (x);
}
R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
if (x == 0)
return (0);
Bzero(x, maj_keylen + 2 * sizeof (*x));
cp = (caddr_t)(x + 2);
Bcopy(netmask, cp, mlen);
netmask = cp;
x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
/*
* Calculate index of mask.
*/
cplim = netmask + mlen;
for (cp = netmask + skip; cp < cplim; cp++)
if (*(u_char *)cp != 0xff)
break;
b = (cp - netmask) << 3;
if (cp != cplim) {
if (*cp != 0) {
gotOddMasks = 1;
for (j = 0x80; j; b++, j >>= 1)
if ((j & *cp) == 0)
break;
}
}
x->rj_b = -1 - b;
return (x);
}
#if 0
struct radij_node *
#endif
int
rj_addroute(v_arg, n_arg, head, treenodes)
void *v_arg, *n_arg;
struct radij_node_head *head;
struct radij_node treenodes[2];
{
caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
register struct radij_node *t, *x=NULL, *tt;
struct radij_node *saved_tt, *top = head->rnh_treetop;
short b = 0, b_leaf;
int mlen, keyduplicated;
caddr_t cplim;
struct radij_mask *m, **mp;
/*
* In dealing with non-contiguous masks, there may be
* many different routes which have the same mask.
* We will find it useful to have a unique pointer to
* the mask to speed avoiding duplicate references at
* nodes and possibly save time in calculating indices.
*/
if (netmask) {
x = rj_search(netmask, rj_masktop);
mlen = *(u_char *)netmask;
if (Bcmp(netmask, x->rj_key, mlen) != 0) {
x = rj_addmask(netmask, 0, top->rj_off);
if (x == 0)
return -ENOMEM; /* (0) rgb */
}
netmask = x->rj_key;
b = -1 - x->rj_b;
}
/*
* Deal with duplicated keys: attach node to previous instance
*/
saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
if (keyduplicated) {
do {
if (tt->rj_mask == netmask)
return -EEXIST; /* -ENXIO; (0) rgb */
t = tt;
if (netmask == 0 ||
(tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
break;
} while ((tt = tt->rj_dupedkey));
/*
* If the mask is not duplicated, we wouldn't
* find it among possible duplicate key entries
* anyway, so the above test doesn't hurt.
*
* We sort the masks for a duplicated key the same way as
* in a masklist -- most specific to least specific.
* This may require the unfortunate nuisance of relocating
* the head of the list.
*/
if (tt && t == saved_tt) {
struct radij_node *xx = x;
/* link in at head of list */
(tt = treenodes)->rj_dupedkey = t;
tt->rj_flags = t->rj_flags;
tt->rj_p = x = t->rj_p;
if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
saved_tt = tt; x = xx;
} else {
(tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
t->rj_dupedkey = tt;
}
#ifdef RJ_DEBUG
t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
#endif /* RJ_DEBUG */
t = saved_tt;
tt->rj_key = (caddr_t) v;
tt->rj_b = -1;
tt->rj_flags = t->rj_flags & ~RJF_ROOT;
}
/*
* Put mask in tree.
*/
if (netmask) {
tt->rj_mask = netmask;
tt->rj_b = x->rj_b;
}
t = saved_tt->rj_p;
b_leaf = -1 - t->rj_b;
if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
/* Promote general routes from below */
if (x->rj_b < 0) {
if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
MKGet(m);
if (m) {
Bzero(m, sizeof *m);
m->rm_b = x->rj_b;
m->rm_mask = x->rj_mask;
x->rj_mklist = t->rj_mklist = m;
}
}
} else if (x->rj_mklist) {
/*
* Skip over masks whose index is > that of new node
*/
for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
if (m->rm_b >= b_leaf)
break;
t->rj_mklist = m; *mp = 0;
}
/* Add new route to highest possible ancestor's list */
if ((netmask == 0) || (b > t->rj_b ))
return 0; /* tt rgb */ /* can't lift at all */
b_leaf = tt->rj_b;
do {
x = t;
t = t->rj_p;
} while (b <= t->rj_b && x != top);
/*
* Search through routes associated with node to
* insert new route according to index.
* For nodes of equal index, place more specific
* masks first.
*/
cplim = netmask + mlen;
for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
if (m->rm_b < b_leaf)
continue;
if (m->rm_b > b_leaf)
break;
if (m->rm_mask == netmask) {
m->rm_refs++;
tt->rj_mklist = m;
return 0; /* tt rgb */
}
if (rj_refines(netmask, m->rm_mask))
break;
}
MKGet(m);
if (m == 0) {
printk("klips_debug:rj_addroute: "
"Mask for route not entered\n");
return 0; /* (tt) rgb */
}
Bzero(m, sizeof *m);
m->rm_b = b_leaf;
m->rm_mask = netmask;
m->rm_mklist = *mp;
*mp = m;
tt->rj_mklist = m;
return 0; /* tt rgb */
}
int
rj_delete(v_arg, netmask_arg, head, node)
void *v_arg, *netmask_arg;
struct radij_node_head *head;
struct radij_node **node;
{
register struct radij_node *t, *p, *x, *tt;
struct radij_mask *m, *saved_m, **mp;
struct radij_node *dupedkey, *saved_tt, *top;
caddr_t v, netmask;
int b, head_off, vlen;
v = v_arg;
netmask = netmask_arg;
x = head->rnh_treetop;
tt = rj_search(v, x);
head_off = x->rj_off;
vlen = *(u_char *)v;
saved_tt = tt;
top = x;
if (tt == 0 ||
Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
return -EFAULT; /* (0) rgb */
/*
* Delete our route from mask lists.
*/
if ((dupedkey = tt->rj_dupedkey)) {
if (netmask)
netmask = rj_search(netmask, rj_masktop)->rj_key;
while (tt->rj_mask != netmask)
if ((tt = tt->rj_dupedkey) == 0)
return -ENOENT; /* -ENXIO; (0) rgb */
}
if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
goto on1;
if (m->rm_mask != tt->rj_mask) {
printk("klips_debug:rj_delete: "
"inconsistent annotation\n");
goto on1;
}
if (--m->rm_refs >= 0)
goto on1;
b = -1 - tt->rj_b;
t = saved_tt->rj_p;
if (b > t->rj_b)
goto on1; /* Wasn't lifted at all */
do {
x = t;
t = t->rj_p;
} while (b <= t->rj_b && x != top);
for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
if (m == saved_m) {
*mp = m->rm_mklist;
MKFree(m);
break;
}
if (m == 0)
printk("klips_debug:rj_delete: "
"couldn't find our annotation\n");
on1:
/*
* Eliminate us from tree
*/
if (tt->rj_flags & RJF_ROOT)
return -EFAULT; /* (0) rgb */
#ifdef RJ_DEBUG
/* Get us out of the creation list */
for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
if (t) t->rj_ybro = tt->rj_ybro;
#endif /* RJ_DEBUG */
t = tt->rj_p;
if (dupedkey) {
if (tt == saved_tt) {
x = dupedkey; x->rj_p = t;
if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
} else {
for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
p = p->rj_dupedkey;
if (p) p->rj_dupedkey = tt->rj_dupedkey;
else printk("klips_debug:rj_delete: "
"couldn't find us\n");
}
t = tt + 1;
if (t->rj_flags & RJF_ACTIVE) {
#ifndef RJ_DEBUG
*++x = *t; p = t->rj_p;
#else
b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
#endif /* RJ_DEBUG */
if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
x->rj_l->rj_p = x; x->rj_r->rj_p = x;
}
goto out;
}
if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
p = t->rj_p;
if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
x->rj_p = p;
/*
* Demote routes attached to us.
*/
if (t->rj_mklist) {
if (x->rj_b >= 0) {
for (mp = &x->rj_mklist; (m = *mp);)
mp = &m->rm_mklist;
*mp = t->rj_mklist;
} else {
for (m = t->rj_mklist; m;) {
struct radij_mask *mm = m->rm_mklist;
if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
x->rj_mklist = 0;
MKFree(m);
} else
printk("klips_debug:rj_delete: "
"Orphaned Mask 0p%p at 0p%p\n", m, x);
m = mm;
}
}
}
/*
* We may be holding an active internal node in the tree.
*/
x = tt + 1;
if (t != x) {
#ifndef RJ_DEBUG
*t = *x;
#else
b = t->rj_info; *t = *x; t->rj_info = b;
#endif /* RJ_DEBUG */
t->rj_l->rj_p = t; t->rj_r->rj_p = t;
p = x->rj_p;
if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
}
out:
tt->rj_flags &= ~RJF_ACTIVE;
tt[1].rj_flags &= ~RJF_ACTIVE;
*node = tt;
return 0; /* (tt) rgb */
}
int
rj_walktree(h, f, w)
struct radij_node_head *h;
register int (*f)(struct radij_node *,void *);
void *w;
{
int error;
struct radij_node *base, *next;
register struct radij_node *rn;
if(!h || !f /* || !w */) {
return -ENODATA;
}
rn = h->rnh_treetop;
/*
* This gets complicated because we may delete the node
* while applying the function f to it, so we need to calculate
* the successor node in advance.
*/
/* First time through node, go left */
while (rn->rj_b >= 0)
rn = rn->rj_l;
for (;;) {
#ifdef CONFIG_IPSEC_DEBUG
if(debug_radij) {
printk("klips_debug:rj_walktree: "
"for: rn=0p%p rj_b=%d rj_flags=%x",
rn,
rn->rj_b,
rn->rj_flags);
rn->rj_b >= 0 ?
printk(" node off=%x\n",
rn->rj_off) :
printk(" leaf key = %08x->%08x\n",
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
;
}
#endif /* CONFIG_IPSEC_DEBUG */
base = rn;
/* If at right child go back up, otherwise, go right */
while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
rn = rn->rj_p;
/* Find the next *leaf* since next node might vanish, too */
for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
rn = rn->rj_l;
next = rn;
#ifdef CONFIG_IPSEC_DEBUG
if(debug_radij) {
printk("klips_debug:rj_walktree: "
"processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
rn,
rn->rj_b,
rn->rj_flags);
rn->rj_b >= 0 ?
printk(" node off=%x\n",
rn->rj_off) :
printk(" leaf key = %08x->%08x\n",
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
;
}
#endif /* CONFIG_IPSEC_DEBUG */
/* Process leaves */
while ((rn = base)) {
base = rn->rj_dupedkey;
#ifdef CONFIG_IPSEC_DEBUG
if(debug_radij) {
printk("klips_debug:rj_walktree: "
"while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
base,
rn,
rn->rj_b,
rn->rj_flags);
rn->rj_b >= 0 ?
printk(" node off=%x\n",
rn->rj_off) :
printk(" leaf key = %08x->%08x\n",
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
;
}
#endif /* CONFIG_IPSEC_DEBUG */
if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
return (-error);
}
rn = next;
if (rn->rj_flags & RJF_ROOT)
return (0);
}
/* NOTREACHED */
}
int
rj_inithead(head, off)
void **head;
int off;
{
register struct radij_node_head *rnh;
register struct radij_node *t, *tt, *ttt;
if (*head)
return (1);
R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
if (rnh == NULL)
return (0);
Bzero(rnh, sizeof (*rnh));
*head = rnh;
t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
ttt = rnh->rnh_nodes + 2;
t->rj_r = ttt;
t->rj_p = t;
tt = t->rj_l;
tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
tt->rj_b = -1 - off;
*ttt = *tt;
ttt->rj_key = rj_ones;
rnh->rnh_addaddr = rj_addroute;
rnh->rnh_deladdr = rj_delete;
rnh->rnh_matchaddr = rj_match;
rnh->rnh_walktree = rj_walktree;
rnh->rnh_treetop = t;
return (1);
}
void
rj_init()
{
char *cp, *cplim;
if (maj_keylen == 0) {
printk("klips_debug:rj_init: "
"radij functions require maj_keylen be set\n");
return;
}
R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
if (rj_zeroes == NULL)
panic("rj_init");
Bzero(rj_zeroes, 3 * maj_keylen);
rj_ones = cp = rj_zeroes + maj_keylen;
maskedKey = cplim = rj_ones + maj_keylen;
while (cp < cplim)
*cp++ = -1;
if (rj_inithead((void **)&mask_rjhead, 0) == 0)
panic("rj_init 2");
}
void
rj_preorder(struct radij_node *rn, int l)
{
int i;
if (rn == NULL){
printk("klips_debug:rj_preorder: "
"NULL pointer\n");
return;
}
if (rn->rj_b >= 0){
rj_preorder(rn->rj_l, l+1);
rj_preorder(rn->rj_r, l+1);
printk("klips_debug:");
for (i=0; i<l; i++)
printk("*");
printk(" off = %d\n",
rn->rj_off);
} else {
printk("klips_debug:");
for (i=0; i<l; i++)
printk("@");
printk(" flags = %x",
(u_int)rn->rj_flags);
if (rn->rj_flags & RJF_ACTIVE) {
printk(" @key=0p%p",
rn->rj_key);
printk(" key = %08x->%08x",
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
printk(" @mask=0p%p",
rn->rj_mask);
if (rn->rj_mask)
printk(" mask = %08x->%08x",
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
(u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
if (rn->rj_dupedkey)
printk(" dupedkey = 0p%p",
rn->rj_dupedkey);
}
printk("\n");
}
}
#ifdef RJ_DEBUG
DEBUG_NO_STATIC void traverse(struct radij_node *p)
{
rj_preorder(p, 0);
}
#endif /* RJ_DEBUG */
void
rj_dumptrees(void)
{
rj_preorder(rnh->rnh_treetop, 0);
}
void
rj_free_mkfreelist(void)
{
struct radij_mask *mknp, *mknp2;
mknp = rj_mkfreelist;
while(mknp)
{
mknp2 = mknp;
mknp = mknp->rm_mklist;
kfree(mknp2);
}
}
int
radijcleartree(void)
{
return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
}
int
radijcleanup(void)
{
int error = 0;
error = radijcleartree();
rj_free_mkfreelist();
/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
if(mask_rjhead) {
kfree(mask_rjhead);
}
if(rj_zeroes) {
kfree(rj_zeroes);
}
if(rnh) {
kfree(rnh);
}
return error;
}
-196
View File
@@ -1,196 +0,0 @@
/*
* sysctl interface to net IPSEC subsystem.
* Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* RCSID $Id: sysctl_net_ipsec.c,v 1.1 2004/03/15 20:35:27 as Exp $
*/
/* -*- linux-c -*-
*
* Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
*/
#include <linux/mm.h>
#include <linux/sysctl.h>
#include "freeswan/ipsec_param.h"
#ifdef CONFIG_SYSCTL
#define NET_IPSEC 2112 /* Random number */
#ifdef CONFIG_IPSEC_DEBUG
extern int debug_ah;
extern int debug_esp;
extern int debug_tunnel;
extern int debug_eroute;
extern int debug_spi;
extern int debug_radij;
extern int debug_netlink;
extern int debug_xform;
extern int debug_rcv;
extern int debug_pfkey;
extern int sysctl_ipsec_debug_verbose;
#ifdef CONFIG_IPSEC_IPCOMP
extern int sysctl_ipsec_debug_ipcomp;
#endif /* CONFIG_IPSEC_IPCOMP */
#endif /* CONFIG_IPSEC_DEBUG */
extern int sysctl_ipsec_icmp;
extern int sysctl_ipsec_inbound_policy_check;
extern int sysctl_ipsec_tos;
int sysctl_ipsec_regress_pfkey_lossage;
enum {
#ifdef CONFIG_IPSEC_DEBUG
NET_IPSEC_DEBUG_AH=1,
NET_IPSEC_DEBUG_ESP=2,
NET_IPSEC_DEBUG_TUNNEL=3,
NET_IPSEC_DEBUG_EROUTE=4,
NET_IPSEC_DEBUG_SPI=5,
NET_IPSEC_DEBUG_RADIJ=6,
NET_IPSEC_DEBUG_NETLINK=7,
NET_IPSEC_DEBUG_XFORM=8,
NET_IPSEC_DEBUG_RCV=9,
NET_IPSEC_DEBUG_PFKEY=10,
NET_IPSEC_DEBUG_VERBOSE=11,
NET_IPSEC_DEBUG_IPCOMP=12,
#endif /* CONFIG_IPSEC_DEBUG */
NET_IPSEC_ICMP=13,
NET_IPSEC_INBOUND_POLICY_CHECK=14,
NET_IPSEC_TOS=15,
NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
};
static ctl_table ipsec_table[] = {
#ifdef CONFIG_IPSEC_DEBUG
{ NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
sizeof(int), 0644, NULL, &proc_dointvec},
#ifdef CONFIG_IPSEC_IPCOMP
{ NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
sizeof(int), 0644, NULL, &proc_dointvec},
#endif /* CONFIG_IPSEC_IPCOMP */
#ifdef CONFIG_IPSEC_REGRESS
{ NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
&sysctl_ipsec_regress_pfkey_lossage,
sizeof(int), 0644, NULL, &proc_dointvec},
#endif /* CONFIG_IPSEC_REGRESS */
#endif /* CONFIG_IPSEC_DEBUG */
{ NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
sizeof(int), 0644, NULL, &proc_dointvec},
{ NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
sizeof(int), 0644, NULL, &proc_dointvec},
{0}
};
static ctl_table ipsec_net_table[] = {
{ NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
{ 0 }
};
static ctl_table ipsec_root_table[] = {
{ CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
{ 0 }
};
static struct ctl_table_header *ipsec_table_header;
int ipsec_sysctl_register(void)
{
ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
if (!ipsec_table_header) {
return -ENOMEM;
}
return 0;
}
void ipsec_sysctl_unregister(void)
{
unregister_sysctl_table(ipsec_table_header);
}
#endif /* CONFIG_SYSCTL */
/*
* $Log: sysctl_net_ipsec.c,v $
* Revision 1.1 2004/03/15 20:35:27 as
* added files from freeswan-2.04-x509-1.5.3
*
* Revision 1.15 2002/04/24 07:55:32 mcr
* #include patches and Makefiles for post-reorg compilation.
*
* Revision 1.14 2002/04/24 07:36:35 mcr
* Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
*
* Revision 1.13 2002/01/12 02:58:32 mcr
* first regression test causes acquire messages to be lost
* 100% of the time. This is to help testing of pluto.
*
* Revision 1.12 2001/06/14 19:35:13 rgb
* Update copyright date.
*
* Revision 1.11 2001/02/26 19:58:13 rgb
* Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
*
* Revision 1.10 2000/09/16 01:50:15 rgb
* Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
* linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
*
* Revision 1.9 2000/09/15 23:17:51 rgb
* Moved stuff around to compile with debug off.
*
* Revision 1.8 2000/09/15 11:37:02 rgb
* Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
* IPCOMP zlib deflate code.
*
* Revision 1.7 2000/09/15 07:37:15 rgb
* Munged silly log comment that was causing a warning.
*
* Revision 1.6 2000/09/15 04:58:23 rgb
* Added tos runtime switch.
* Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
*
* Revision 1.5 2000/09/12 03:25:28 rgb
* Filled in and implemented sysctl.
*
* Revision 1.4 1999/04/11 00:29:03 henry
* GPL boilerplate
*
* Revision 1.3 1999/04/06 04:54:29 rgb
* Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
* patch shell fixes.
*
*/
-6
View File
@@ -1,6 +0,0 @@
TAGS:
etags *.c ../../include/*.h ../../include/freeswan/*.h
ctags *.c ../../include/*.h ../../include/freeswan/*.h
-21
View File
@@ -1,21 +0,0 @@
RCSID $Id: af_inet.c.fs2_0.patch,v 1.1 2004/03/15 20:35:27 as Exp $
--- ./net/ipv4/af_inet.c.preipsec Wed Jun 3 18:17:50 1998
+++ ./net/ipv4/af_inet.c Fri Sep 17 10:14:12 1999
@@ -1146,6 +1146,17 @@
ip_alias_init();
#endif
+#if defined(CONFIG_IPSEC)
+ {
+ extern /* void */ int ipsec_init(void);
+ /*
+ * Initialise AF_INET ESP and AH protocol support including
+ * e-routing and SA tables
+ */
+ ipsec_init();
+ }
+#endif /* CONFIG_IPSEC */
+
#ifdef CONFIG_INET_RARP
rarp_ioctl_hook = rarp_ioctl;
#endif
-21
View File
@@ -1,21 +0,0 @@
RCSID $Id: af_inet.c.fs2_2.patch,v 1.1 2004/03/15 20:35:27 as Exp $
--- ./net/ipv4/af_inet.c.preipsec Mon Aug 9 15:05:13 1999
+++ ./net/ipv4/af_inet.c Fri Sep 17 10:13:07 1999
@@ -1140,6 +1140,17 @@
ip_mr_init();
#endif
+#if defined(CONFIG_IPSEC)
+ {
+ extern /* void */ int ipsec_init(void);
+ /*
+ * Initialise AF_INET ESP and AH protocol support including
+ * e-routing and SA tables
+ */
+ ipsec_init();
+ }
+#endif /* CONFIG_IPSEC */
+
#ifdef CONFIG_INET_RARP
rarp_ioctl_hook = rarp_ioctl;
#endif
-21
View File
@@ -1,21 +0,0 @@
RCSID $Id: af_inet.c.fs2_4.patch,v 1.1 2004/03/15 20:35:27 as Exp $
--- ./net/ipv4/af_inet.c.preipsec Wed Apr 26 15:13:17 2000
+++ ./net/ipv4/af_inet.c Fri Jun 30 15:01:27 2000
@@ -1019,6 +1019,17 @@
ip_mr_init();
#endif
+#if defined(CONFIG_IPSEC)
+ {
+ extern /* void */ int ipsec_init(void);
+ /*
+ * Initialise AF_INET ESP and AH protocol support including
+ * e-routing and SA tables
+ */
+ ipsec_init();
+ }
+#endif /* CONFIG_IPSEC */
+
/*
* Create all the /proc entries.
*/
-108
View File
@@ -1,108 +0,0 @@
--- ./net/ipv4/udp.c Sun Mar 25 18:37:41 2001
+++ ./net/ipv4/udp.c Mon Jun 10 19:53:18 2002
@@ -965,6 +965,9 @@
static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
{
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+ struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
+#endif
/*
* Charge it to the socket, dropping if the queue is full.
*/
@@ -982,6 +985,38 @@
}
#endif
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+ if (tp->esp_in_udp) {
+ /*
+ * Set skb->sk and xmit packet to ipsec_rcv.
+ *
+ * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP),
+ * restore skb->sk and fall back to sock_queue_rcv_skb
+ */
+ struct inet_protocol *esp = NULL;
+
+#ifdef CONFIG_IPSEC_MODULE
+ for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)];
+ (esp) && (esp->protocol != IPPROTO_ESP);
+ esp = esp->next);
+#else
+ extern struct inet_protocol esp_protocol;
+ esp = &esp_protocol;
+#endif
+
+ if (esp && esp->handler) {
+ struct sock *sav_sk = skb->sk;
+ skb->sk = sk;
+ if (esp->handler(skb, 0) == 0) {
+ skb->sk = sav_sk;
+ /* not sure we might count ESPinUDP as UDP... */
+ udp_statistics.UdpInDatagrams++;
+ return 0;
+ }
+ skb->sk = sav_sk;
+ }
+ }
+#endif
if (sock_queue_rcv_skb(sk,skb)<0) {
udp_statistics.UdpInErrors++;
ip_statistics.IpInDiscards++;
@@ -1165,6 +1200,44 @@
return(0);
}
+#if 1
+static int udp_setsockopt(struct sock *sk, int level, int optname,
+ char *optval, int optlen)
+{
+ struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
+ int val;
+ int err = 0;
+
+ if (level != SOL_UDP)
+ return ip_setsockopt(sk, level, optname, optval, optlen);
+
+ if(optlen<sizeof(int))
+ return -EINVAL;
+
+ if (get_user(val, (int *)optval))
+ return -EFAULT;
+
+ lock_sock(sk);
+
+ switch(optname) {
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+#ifndef UDP_ESPINUDP
+#define UDP_ESPINUDP 100
+#endif
+ case UDP_ESPINUDP:
+ tp->esp_in_udp = val;
+ break;
+#endif
+ default:
+ err = -ENOPROTOOPT;
+ break;
+ }
+
+ release_sock(sk);
+ return err;
+}
+#endif
+
struct proto udp_prot = {
(struct sock *)&udp_prot, /* sklist_next */
(struct sock *)&udp_prot, /* sklist_prev */
@@ -1179,7 +1252,11 @@
NULL, /* init */
NULL, /* destroy */
NULL, /* shutdown */
+#if 1
+ udp_setsockopt, /* setsockopt */
+#else
ip_setsockopt, /* setsockopt */
+#endif
ip_getsockopt, /* getsockopt */
udp_sendmsg, /* sendmsg */
udp_recvmsg, /* recvmsg */
-107
View File
@@ -1,107 +0,0 @@
--- ./net/ipv4/udp.c 2002/02/26 14:54:22 1.2
+++ ./net/ipv4/udp.c 2002/05/22 12:14:58
@@ -777,6 +777,9 @@
static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
{
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+ struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
+#endif
/*
* Charge it to the socket, dropping if the queue is full.
*/
@@ -794,6 +797,38 @@
}
#endif
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+ if (tp->esp_in_udp) {
+ /*
+ * Set skb->sk and xmit packet to ipsec_rcv.
+ *
+ * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP),
+ * restore skb->sk and fall back to sock_queue_rcv_skb
+ */
+ struct inet_protocol *esp = NULL;
+
+#ifdef CONFIG_IPSEC_MODULE
+ for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)];
+ (esp) && (esp->protocol != IPPROTO_ESP);
+ esp = esp->next);
+#else
+ extern struct inet_protocol esp_protocol;
+ esp = &esp_protocol;
+#endif
+
+ if (esp && esp->handler) {
+ struct sock *sav_sk = skb->sk;
+ skb->sk = sk;
+ if (esp->handler(skb) == 0) {
+ skb->sk = sav_sk;
+ /* not sure we might count ESPinUDP as UDP... */
+ UDP_INC_STATS_BH(UdpInDatagrams);
+ return 0;
+ }
+ skb->sk = sav_sk;
+ }
+ }
+#endif
if (sock_queue_rcv_skb(sk,skb)<0) {
UDP_INC_STATS_BH(UdpInErrors);
IP_INC_STATS_BH(IpInDiscards);
@@ -1010,13 +1045,55 @@
return len;
}
+#if 1
+static int udp_setsockopt(struct sock *sk, int level, int optname,
+ char *optval, int optlen)
+{
+ struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
+ int val;
+ int err = 0;
+
+ if (level != SOL_UDP)
+ return ip_setsockopt(sk, level, optname, optval, optlen);
+
+ if(optlen<sizeof(int))
+ return -EINVAL;
+
+ if (get_user(val, (int *)optval))
+ return -EFAULT;
+
+ lock_sock(sk);
+
+ switch(optname) {
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+#ifndef UDP_ESPINUDP
+#define UDP_ESPINUDP 100
+#endif
+ case UDP_ESPINUDP:
+ tp->esp_in_udp = val;
+ break;
+#endif
+ default:
+ err = -ENOPROTOOPT;
+ break;
+ }
+
+ release_sock(sk);
+ return err;
+}
+#endif
+
struct proto udp_prot = {
name: "UDP",
close: udp_close,
connect: udp_connect,
disconnect: udp_disconnect,
ioctl: udp_ioctl,
+#if 1
+ setsockopt: udp_setsockopt,
+#else
setsockopt: ip_setsockopt,
+#endif
getsockopt: ip_getsockopt,
sendmsg: udp_sendmsg,
recvmsg: udp_recvmsg,