summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2003-11-05 10:44:19 +0000
committerLennart Poettering <lennart@poettering.net>2003-11-05 10:44:19 +0000
commit7ec5099b5f5c79419a54a6cdedea618d98b60569 (patch)
treef1bed2425e622919435fe4580b15dbfddb3137bf
parent8bc528bfd9d8c17d25eec2ca1686513679ba3e55 (diff)
Commit initial version
git-svn-id: file:///home/lennart/svn/public/seppl/trunk@2 91a2fd9b-5dcb-0310-a70a-d71e310228e6
-rw-r--r--Makefile.am1
-rwxr-xr-xbootstrap.sh46
-rw-r--r--conf/Makefile.am31
-rwxr-xr-xconf/seppl.init.in106
-rw-r--r--configure.ac148
-rw-r--r--kernel/Makefile.in61
-rw-r--r--kernel/ipt_CRYPT.c190
-rw-r--r--kernel/ipt_CRYPT.h32
-rw-r--r--kernel/ipt_DECRYPT.c197
-rw-r--r--kernel/ipt_DECRYPT.h28
-rw-r--r--kernel/seppl.c429
-rw-r--r--kernel/seppl.h60
-rw-r--r--kernel/seppl_protocol.h27
-rwxr-xr-xkernel/test.sh39
-rw-r--r--libs/Makefile.am28
-rw-r--r--libs/libipt_CRYPT.c114
-rw-r--r--libs/libipt_DECRYPT.c75
-rw-r--r--utils/Makefile.am22
-rwxr-xr-xutils/seppl-gen-key110
-rwxr-xr-xutils/seppl-ls198
-rw-r--r--utils/seppl_common.py105
21 files changed, 2047 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..ae9033f
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS=kernel libs utils conf
diff --git a/bootstrap.sh b/bootstrap.sh
new file mode 100755
index 0000000..148356b
--- /dev/null
+++ b/bootstrap.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+# $Id: bootstrap.sh 58 2003-10-20 21:57:59Z lennart $
+
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+run_versioned() {
+ local P
+ type -p "$1-$2" &> /dev/null && P="$1-$2" || local P="$1"
+
+ shift 2
+ "$P" "$@"
+}
+
+if [ "x$1" = "xam" ] ; then
+ set -ex
+ run_versioned automake 1.7 -a -c
+ ./config.status
+else
+ set -ex
+ rm -rf autom4te.cache
+ rm -f config.cache
+
+ run_versioned aclocal 1.7
+ libtoolize -c --force
+ autoheader
+ run_versioned automake 1.7 -a -c
+ autoconf -Wall
+
+ ./configure --sysconfdir=/etc "$@"
+
+ make clean
+fi
diff --git a/conf/Makefile.am b/conf/Makefile.am
new file mode 100644
index 0000000..98667e2
--- /dev/null
+++ b/conf/Makefile.am
@@ -0,0 +1,31 @@
+# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $
+#
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+noinst_DATA = seppl.init
+EXTRA_DIST = seppl.init.in
+CLEANFILES = seppl.init
+
+seppl.init: seppl.init.in Makefile
+ sed -e 's,@sysconfdir\@,$(sysconfdir),g' -e 's,@sbindir\@,$(sbindir),g' $< > $@
+ chmod 755 $@
+
+install-data-local: seppl.init
+ $(INSTALL) -b -D -m755 seppl.init ${DESTDIR}/${sysconfdir}/init.d/seppl
+
+uninstall-local:
+ rm -f ${DESTDIR}/${sysconfdir}/init.d/seppl
diff --git a/conf/seppl.init.in b/conf/seppl.init.in
new file mode 100755
index 0000000..79ee4d5
--- /dev/null
+++ b/conf/seppl.init.in
@@ -0,0 +1,106 @@
+#! /bin/sh
+
+# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $
+#
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+
+PROCFILE="/proc/net/seppl_keyring"
+SEPPLLS="@sbindir@/seppl-ls"
+KEYDIR="@sysconfdir@/seppl"
+
+test -d "$KEYDIR" || exit 1
+test -x "$SEPPLLS" || exit 1
+
+load_keys() {
+ echo -n "Configuring SEPPL keys: "
+ for K in "$KEYDIR"/* ; do
+ if test -f "$K" ; then
+ if ( "$SEPPLLS" -f $K > "$PROCFILE" ) 2> /dev/null ; then
+ echo -n "$K "
+ else
+ echo "failed"
+ exit 1
+ fi
+ fi
+ done
+ echo "."
+}
+
+clear_keys() {
+ echo -n "Clearing SEPPL keys: "
+ ( echo "clear" > "$PROCFILE" ) 2> /dev/null
+ if test -s "$PROCFILE" ; then
+ echo "failure"
+ exit 1
+ fi
+ echo "success"
+}
+
+
+load_modules() {
+ echo -n "Loading SEPPL module: "
+ modprobe seppl &> /dev/null
+ if ! test -f "$PROCFILE" ; then
+ echo "failure"
+ exit 1
+ fi
+ echo "success"
+}
+
+unload_modules() {
+ echo -n "Unloading SEPPL modules: "
+ modprobe -r ipt_CRYPT &> /dev/null
+ modprobe -r ipt_DECRYPT &> /dev/null
+ modprobe -r seppl &> /dev/null
+ if test -f "$PROCFILE" ; then
+ echo "failure"
+ exit 1
+ fi
+ echo "success"
+}
+
+case "$1" in
+ start)
+ load_modules
+ load_keys
+ ;;
+
+ stop)
+ clear_keys
+ unload_modules
+ ;;
+
+ force-reload|reload)
+ clear_keys
+ load_keys
+ ;;
+
+ restart)
+ $0 stop
+ sleep 1
+ $0 start
+ ;;
+
+ *)
+ echo "Usage: $0 {start|stop|restart|force-reload|reload}"
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..d5e5ef7
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,148 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+# $Id: configure.ac 58 2003-10-20 21:57:59Z lennart $
+
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+AC_PREREQ(2.57)
+AC_INIT([seppl], [0.2], [mzfrccy (at) 0pointer (dot) de])
+AC_CONFIG_SRCDIR([kernel/seppl.c])
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE([foreign -Wall])
+AC_DISABLE_STATIC
+AC_PROG_LIBTOOL
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+
+AC_SUBST(PACKAGE_URL, [http://0pointer.de/lennart/projects/seppl/])
+
+# If using GCC specifiy some additional parameters
+if test "x$GCC" = "xyes" ; then
+ CFLAGS="$CFLAGS -pipe -Wall"
+fi
+
+if type -p stow > /dev/null && test -d /usr/local/stow ; then
+ AC_MSG_NOTICE([*** Found /usr/local/stow: installing to /usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION} ***])
+ AC_PREFIX_DEFAULT([/usr/local/stow/${PACKAGE_NAME}-${PACKAGE_VERSION}])
+fi
+
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_CHECK_FUNCS([memset])
+AC_C_CONST
+
+# Check for directory with kernel source...
+AC_MSG_CHECKING(for directory with kernel source)
+AC_ARG_WITH(kernel,
+ [ --with-kernel=dir give the directory with kernel sources]
+ [ [/usr/src/linux]],
+ KERNELDIR="$withval",
+ if test -d "/lib/modules/`uname -r`/build" -o -L "/lib/modules/`uname -r`/build"; then
+ KERNELDIR="/lib/modules/`uname -r`/build"
+ else
+ KERNELDIR="/usr/src/linux"
+ fi
+)
+AC_SUBST(KERNELDIR)
+AC_MSG_RESULT([$KERNELDIR])
+
+# Check for crypto.h
+AC_MSG_CHECKING(for crypto.h)
+if ! test -r $KERNELDIR/include/linux/crypto.h; then
+ cat << EOF
+The file $KERNELDIR/include/linux/crypto.h does not exist.
+Please, install the package with full kernel sources for 2.4.22 for your distribution
+or use --with-kernel=dir option to specify another directory with kernel
+sources (default is /usr/src/linux).
+EOF
+ exit 1
+fi
+AC_MSG_RESULT([found])
+
+# Check for directory for kernel modules...
+AC_MSG_CHECKING(for directory for kernel modules)
+AC_ARG_WITH(moddir,
+ AC_HELP_STRING([--with-moddir=dir], [Give the directory to install kernel modules to]),
+ KERNELMODDIR="$withval",
+ if test -d "/lib/modules/`uname -r`/" -o -L "/lib/modules/`uname -r`/"; then
+ KERNELMODDIR="/lib/modules/`uname -r`/"
+ else
+ AC_MSG_ERROR([[*** Sorry, failed to find kernel module directory ***]])
+ fi
+)
+AC_SUBST(KERNELMODDIR)
+AC_MSG_RESULT([$KERNELMODDIR])
+
+# iptables checks
+AC_CHECK_HEADER(iptables.h,, [AC_MSG_ERROR([*** Sorry, failed to find iptables.h, you should install iptables-dev ***])])
+
+# Set libiptdir
+AC_MSG_CHECKING(for /lib/iptables)
+if ! test -d /lib/iptables ; then
+ AC_MSG_ERROR([*** Sorry, failed to find iptables plugin directory ***])
+fi
+LIB_IPTABLES_DIR=/lib/iptables
+AC_SUBST(LIB_IPTABLES_DIR)
+AC_MSG_RESULT([$LIB_IPTABLES_DIR])
+
+AM_PATH_PYTHON([2.1])
+
+# LYNX documentation generation
+AC_ARG_ENABLE(lynx,
+ AC_HELP_STRING([--disable-lynx], [Turn off lynx usage for documentation generation]),
+[case "${enableval}" in
+ yes) lynx=yes ;;
+ no) lynx=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --disable-lynx) ;;
+esac],[lynx=yes])
+
+if test x$lynx = xyes ; then
+ AC_CHECK_PROG(have_lynx, lynx, yes, no)
+
+ if test x$have_lynx = xno ; then
+ AC_MSG_ERROR([*** Sorry, you have to install lynx or use --disable-lynx ***])
+ fi
+fi
+
+AM_CONDITIONAL([USE_LYNX], [test "x$lynx" = xyes])
+
+# XMLTOMAN manpage generation
+AC_ARG_ENABLE(xmltoman,
+ AC_HELP_STRING([--disable-xmltoman], [Disable rebuilding of man pages with xmltoman]),
+[case "${enableval}" in
+ yes) xmltoman=yes ;;
+ no) xmltoman=no ;;
+ *) AC_MSG_ERROR([bad value ${enableval} for --disable-xmltoman]) ;;
+esac],[xmltoman=yes])
+
+if test x$xmltoman = xyes ; then
+ AC_CHECK_PROG(have_xmltoman, xmltoman, yes, no)
+
+ if test x$have_xmltoman = xno ; then
+ AC_MSG_WARN([*** Not rebuilding man pages as xmltoman is not found ***])
+ xmltoman=no
+ fi
+fi
+
+AM_CONDITIONAL([USE_XMLTOMAN], [test "x$xmltoman" = xyes])
+
+AC_CONFIG_FILES([kernel/Makefile libs/Makefile Makefile utils/Makefile conf/Makefile ]) # doc/Makefile doc/README.html])
+AC_OUTPUT
diff --git a/kernel/Makefile.in b/kernel/Makefile.in
new file mode 100644
index 0000000..3be3826
--- /dev/null
+++ b/kernel/Makefile.in
@@ -0,0 +1,61 @@
+# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $
+#
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+# This Makefile is NOT created by automake!
+
+KERNELDIR=@KERNELDIR@
+SEPPL_MODDIR=@KERNELMODDIR@/seppl
+PACKAGE=@PACKAGE@
+VERSION=@VERSION@
+DISTFILES=seppl.c seppl.h ipt_CRYPT.c ipt_CRYPT.h ipt_DECRYPT.c ipt_DECRYPT.h test.sh Makefile.in seppl_protocol.h
+distdir = ../$(PACKAGE)-$(VERSION)
+CFLAGS=-Wall -g -O2
+KERNEL_CFLAGS= -I$(KERNELDIR)/include -DLINUX -DMODULE -D__KERNEL__ -DEXPORT_SYMTAB -DPACKAGE_BUGREPORT="\"@PACKAGE_BUGREPORT@\""
+
+all: Makefile ipt_CRYPT.o ipt_DECRYPT.o seppl.o
+
+Makefile: Makefile.in
+ cd .. && ./config.status kernel/Makefile
+
+ipt_CRYPT.o: ipt_CRYPT.c
+ $(CC) $(CFLAGS) -c $^ -o $@ $(KERNEL_CFLAGS)
+
+ipt_DECRYPT.o: ipt_DECRYPT.c
+ $(CC) $(CFLAGS) -c $^ -o $@ $(KERNEL_CFLAGS)
+
+seppl.o: seppl.c
+ $(CC) $(CFLAGS) -c $^ -o $@ $(KERNEL_CFLAGS)
+
+install:
+ mkdir -p $(SEPPL_MODDIR)
+ install -m644 seppl.o ipt_CRYPT.o ipt_DECRYPT.o $(SEPPL_MODDIR)
+
+distdir:
+ mkdir -p $(distdir)
+ cp -p $(DISTFILES) $(distdir)
+
+mostlyclean: clean
+distclean: clean
+
+maintainer-clean: clean
+ rm -f Makefile
+
+clean:
+ rm -f *.o
+
+.PHONY: all clean maintainer-clean mostlyclean distclean distdir install
diff --git a/kernel/ipt_CRYPT.c b/kernel/ipt_CRYPT.c
new file mode 100644
index 0000000..9f7d055
--- /dev/null
+++ b/kernel/ipt_CRYPT.c
@@ -0,0 +1,190 @@
+/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */
+
+/***
+ This file is part of seppl
+
+ seppl 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.
+
+ seppl 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.
+
+ You should have received a copy of the GNU General Public License
+ along with seppl; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+***/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/ip.h>
+#include <net/checksum.h>
+struct in_device;
+#include <net/route.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <asm/scatterlist.h>
+
+#include "seppl.h"
+#include "ipt_CRYPT.h"
+
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+#ifdef MODULE_DESCRIPTION
+MODULE_DESCRIPTION("SEPPL iptables Encryption Target");
+#endif
+#ifdef MODULE_AUTHOR
+MODULE_AUTHOR("Lennart Poettering <"PACKAGE_BUGREPORT">");
+#endif
+
+static unsigned int ipt_CRYPT_target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, const void *_ti, void *userinfo) {
+ const struct ipt_crypt_info *ti = _ti;
+ struct iphdr *ih = (*pskb)->nh.iph;
+ unsigned d, new_l, crypt_l, ihl = ih->ihl<<2;
+ struct seppl_uncrypt_hdr *uh;
+ struct seppl_crypt_hdr *ch;
+ u8 *iv, *pl;
+ int ivs = ti->key->ivsize;
+ int bs = ti->key->blocksize;
+ struct sock *sk;
+ struct scatterlist sg[1];
+
+ // Calculate new packet size
+ new_l = ihl + sizeof(struct seppl_uncrypt_hdr) + ivs + ((sizeof(struct seppl_crypt_hdr) + ntohs(ih->tot_len) - ihl + bs - 1) / bs) * bs;
+ d = new_l - htons(ih->tot_len);
+ crypt_l = new_l - ihl - sizeof(struct seppl_uncrypt_hdr) - ivs;
+
+ //DEBUGP("CRYPT: tot_len=%i, new_l=%i, d=%i, crypt_l=%i\n", htons(ih->tot_len), new_l, d, crypt_l);
+
+ // Copy the skb if needed and increase it correctly
+ if (skb_tailroom(*pskb) < d || skb_cloned(*pskb)) {
+ struct sk_buff *n;
+
+ if (!(n = skb_copy_expand(*pskb, skb_headroom(*pskb), d, GFP_ATOMIC))) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_CRYPT: Unable to allocate larger skb, dropping packet.\n");
+
+ return NF_DROP;
+ }
+
+ if ((*pskb)->sk)
+ skb_set_owner_w(n, (*pskb)->sk);
+
+ kfree_skb(*pskb);
+ *pskb = n;
+ ih = (*pskb)->nh.iph;
+ }
+
+ skb_put(*pskb, d);
+
+ // Calculate some pointers
+ //ih = ... /* IP-Header */
+ uh = (struct seppl_uncrypt_hdr*) ((u8*) ih + ihl); /* Unencrypted header */
+ iv = ((u8*) uh) + sizeof(struct seppl_uncrypt_hdr); /* IV */
+ ch = (struct seppl_crypt_hdr*) (iv + ivs); /* Crypted header */
+ pl = ((u8*) ch) + sizeof(struct seppl_crypt_hdr); /* Payload */
+
+ // Copy the payload
+ memmove(pl, uh, ntohs(ih->tot_len) - ihl);
+
+ // Fill the uncrypted header
+ uh->algorithm = ti->key->algorithm;
+ strncpy(uh->key_name, ti->key->name, 7);
+
+ // Copy the IV
+ seppl_copy_iv(ti->key, iv);
+
+ // Fill the crypted header
+ ch->ident = 0x00;
+ ch->saved_protocol = ih->protocol;
+ ch->saved_tot_len = ih->tot_len;
+ ch->saved_frag_off = ih->frag_off;
+
+ // Fill the IP header
+ ih->protocol = SEPPL_PROTOCOL;
+ ih->tot_len = htons(new_l);
+ ih->frag_off = 0;
+
+ // Checksum FIXME: Is this really needed?
+ ih->check = 0;
+ ih->check = ip_fast_csum((char *) ih, ih->ihl);
+
+ // Crypt
+ sg[0].page = virt_to_page((void*) ch);
+ sg[0].offset = (((long) (void *) ch) & ~PAGE_MASK);
+ sg[0].length = crypt_l;
+
+ crypto_cipher_set_iv(ti->key->tfm, iv, ti->key->ivsize);
+
+ if (crypto_cipher_encrypt(ti->key->tfm, sg, sg, sg[0].length)) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_CRYPT: encrypt() failure\n");
+ return NF_DROP;
+ }
+
+ // Finish
+ (*pskb)->ip_summed = CHECKSUM_NONE;
+ (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
+
+ return IPT_CONTINUE;
+}
+
+static int ipt_CRYPT_check(const char *table, const struct ipt_entry *e, void *_ti, unsigned int ti_size, unsigned int hook_mask) {
+ struct ipt_crypt_info *ti = _ti;
+
+ if (ti_size != IPT_ALIGN(sizeof(struct ipt_crypt_info))) {
+ printk(KERN_ERR "ipt_CRYPT: Structure too small\n");
+ return 0;
+ }
+
+ if (strcmp(table, "mangle") != 0) {
+ printk(KERN_ERR "ipt_CRYPT: Not in mangle table\n");
+ return 0;
+ }
+
+ if ((hook_mask & ~(1 << NF_IP_POST_ROUTING)) != 0) {
+ printk(KERN_ERR "ipt_CRYPT: Not in POSTROUTING chain\n");
+ return 0;
+ }
+
+ if (!(ti->key = seppl_claim_key(ti->algorithm, ti->name))) {
+ printk(KERN_ERR "ipt_CRYPT: Cannot find key\n");
+ return 0;
+ }
+
+ return 1;
+}
+
+static void ipt_CRYPT_destroy(void *_ti, unsigned int ti_size) {
+ struct ipt_crypt_info *ti = _ti;
+
+ seppl_release_key(ti->key);
+}
+
+static struct ipt_target ipt_CRYPT_reg = {
+ { NULL, NULL },
+ "CRYPT",
+ ipt_CRYPT_target,
+ ipt_CRYPT_check,
+ ipt_CRYPT_destroy,
+ THIS_MODULE
+};
+
+static int __init init(void) {
+ return ipt_register_target(&ipt_CRYPT_reg);
+}
+
+static void __exit fini(void) {
+ ipt_unregister_target(&ipt_CRYPT_reg);
+}
+
+module_init(init);
+module_exit(fini);
+
+EXPORT_NO_SYMBOLS;
diff --git a/kernel/ipt_CRYPT.h b/kernel/ipt_CRYPT.h
new file mode 100644
index 0000000..f1602be
--- /dev/null
+++ b/kernel/ipt_CRYPT.h
@@ -0,0 +1,32 @@
+#ifndef _IPT_CRYPT_H
+#define _IPT_CRYPT_H
+
+/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */
+
+/***
+ This file is part of seppl
+
+ seppl 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.
+
+ seppl 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.
+
+ You should have received a copy of the GNU General Public License
+ along with seppl; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+***/
+
+struct ipt_crypt_info {
+ unsigned char algorithm;
+ char name[7];
+
+ struct seppl_key *key;
+};
+
+#endif
diff --git a/kernel/ipt_DECRYPT.c b/kernel/ipt_DECRYPT.c
new file mode 100644
index 0000000..75db2bd
--- /dev/null
+++ b/kernel/ipt_DECRYPT.c
@@ -0,0 +1,197 @@
+/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */
+
+/***
+ This file is part of seppl
+
+ seppl 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.
+
+ seppl 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.
+
+ You should have received a copy of the GNU General Public License
+ along with seppl; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+***/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h>
+#include <net/ip.h>
+#include <net/checksum.h>
+struct in_device;
+#include <net/route.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <asm/scatterlist.h>
+
+#include "seppl.h"
+#include "ipt_DECRYPT.h"
+
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+#ifdef MODULE_DESCRIPTION
+MODULE_DESCRIPTION ("SEPPL iptables Decryption Target");
+#endif
+#ifdef MODULE_AUTHOR
+MODULE_AUTHOR("Lennart Poettering <"PACKAGE_BUGREPORT">");
+#endif
+
+static unsigned int ipt_DECRYPT_target(struct sk_buff **pskb, unsigned int hooknum, const struct net_device *in, const struct net_device *out, const void *_ti, void *userinfo) {
+ struct iphdr *ih = (*pskb)->nh.iph;
+ unsigned ihl = ih->ihl<<2;
+ struct seppl_key *key;
+ struct seppl_uncrypt_hdr *uh;
+ struct seppl_crypt_hdr *ch;
+ u8* iv, *pl;
+ int ivs;
+ int crypt_l, bs;
+ struct scatterlist sg[1];
+
+ if (ih->protocol != SEPPL_PROTOCOL) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_DECRYPT: Incorrect protocol\n");
+ return NF_DROP;
+ }
+
+ if (ntohs(ih->tot_len) <= ihl+sizeof(struct seppl_uncrypt_hdr)) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_DECRYPT: Packet too short (1)\n");
+ return NF_DROP;
+ }
+
+ uh = (struct seppl_uncrypt_hdr*) ((u8*) ih + ihl); /* Unencrypted header */
+
+ if (!(key = seppl_claim_key(uh->algorithm, uh->key_name))) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_DECRYPT: Recieved packet with unknown decryption key.\n");
+ return NF_DROP;
+ }
+
+ ivs = key->ivsize;
+ bs = key->blocksize;
+
+ if (ntohs(ih->tot_len) <= ihl+sizeof(struct seppl_uncrypt_hdr)+ivs+sizeof(struct seppl_crypt_hdr)) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_DECRYPT: Packet too short (2)\n");
+ seppl_release_key(key);
+ return NF_DROP;
+ }
+
+ crypt_l = ntohs(ih->tot_len)-ihl-sizeof(struct seppl_uncrypt_hdr)-ivs;
+
+ if (crypt_l % bs) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_DECRYPT: Packet too short (3)\n");
+ seppl_release_key(key);
+ return NF_DROP;
+ }
+
+ iv = ((u8*) uh) + sizeof(struct seppl_uncrypt_hdr); /* IV */
+ ch = (struct seppl_crypt_hdr*) (iv + ivs); /* Crypted header */
+ pl = ((u8*) ch) + sizeof(struct seppl_crypt_hdr); /* Payload */
+
+ sg[0].page = virt_to_page(ch);
+ sg[0].offset = ((long) ch & ~PAGE_MASK);
+ sg[0].length = crypt_l;
+
+ crypto_cipher_set_iv(key->tfm, iv, key->ivsize);
+
+ if (crypto_cipher_decrypt(key->tfm, sg, sg, sg[0].length)) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_DECRYPT: decrypt() failure\n");
+ seppl_release_key(key);
+ return NF_DROP;
+ }
+
+ seppl_release_key(key);
+
+ if (ch->ident != 0x00) {
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_DECRYPT: Key not matching\n");
+ return NF_DROP;
+ }
+
+ if (ntohs(ch->saved_tot_len) >
+ ntohs(ih->tot_len) -
+ sizeof(struct seppl_uncrypt_hdr)-
+ ivs-
+ sizeof(struct seppl_crypt_hdr)) {
+
+ if (net_ratelimit())
+ printk(KERN_ERR "ipt_DECRYPT: Packet too short (4)");
+ return NF_DROP;
+ }
+
+ //DEBUGP("DECRYPT: tot_len=%i, real_l=%i, crypt_l=%i\n", htons(ih->tot_len), ntohs(ch->saved_tot_len), crypt_l);
+
+ // Restore the IP header
+ ih->protocol = ch->saved_protocol;
+ ih->tot_len = ch->saved_tot_len;
+ ih->frag_off = ch->saved_frag_off;
+
+ // The pay load
+ memmove(uh, pl, ntohs(ih->tot_len)-ihl);
+
+ // Checksum
+ ih->check = 0;
+ ih->check = ip_fast_csum((char *) ih, ih->ihl);
+
+ skb_trim(*pskb, ntohs(ih->tot_len));
+
+ // Finish
+ (*pskb)->ip_summed = CHECKSUM_NONE;
+ (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
+
+ return IPT_CONTINUE;
+}
+
+static int ipt_DECRYPT_check(const char *table, const struct ipt_entry *e, void *_ti, unsigned int ti_size, unsigned int hook_mask) {
+ if (ti_size != IPT_ALIGN(sizeof(struct ipt_decrypt_info))) {
+ printk(KERN_ERR "ipt_DECRYPT: Structure too small");
+ return 0;
+ }
+
+ if (strcmp(table, "mangle") != 0) {
+ printk(KERN_ERR "ipt_DECRYPT: Not in mangle table\n");
+ return 0;
+ }
+
+ if ((hook_mask & ~(1 << NF_IP_PRE_ROUTING)) != 0) {
+ printk(KERN_ERR "ipt_DECRYPT: Not in PREROUTING chain");
+ return 0;
+ }
+
+ return 1;
+}
+
+static struct ipt_target ipt_DECRYPT_reg = {
+ { NULL, NULL },
+ "DECRYPT",
+ ipt_DECRYPT_target,
+ ipt_DECRYPT_check,
+ NULL,
+ THIS_MODULE
+};
+
+static int __init init(void) {
+ if (ipt_register_target(&ipt_DECRYPT_reg))
+ return -EINVAL;
+
+ return 0;
+}
+
+static void __exit fini(void) {
+ ipt_unregister_target(&ipt_DECRYPT_reg);
+}
+
+module_init(init);
+module_exit(fini);
+
+EXPORT_NO_SYMBOLS;
diff --git a/kernel/ipt_DECRYPT.h b/kernel/ipt_DECRYPT.h
new file mode 100644
index 0000000..41f202a
--- /dev/null
+++ b/kernel/ipt_DECRYPT.h
@@ -0,0 +1,28 @@
+#ifndef _IPT_DECRYPT_H
+#define _IPT_DECRYPT_H
+
+/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */
+
+/***
+ This file is part of seppl
+
+ seppl 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.
+
+ seppl 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.
+
+ You should have received a copy of the GNU General Public License
+ along with seppl; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+***/
+
+struct ipt_decrypt_info {
+};
+
+#endif
diff --git a/kernel/seppl.c b/kernel/seppl.c
new file mode 100644
index 0000000..de59eb1
--- /dev/null
+++ b/kernel/seppl.c
@@ -0,0 +1,429 @@
+/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */
+
+/***
+ This file is part of seppl
+
+ seppl 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.
+
+ seppl 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.
+
+ You should have received a copy of the GNU General Public License
+ along with seppl; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+***/
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/interrupt.h>
+#include <linux/string.h>
+#include <linux/random.h>
+#include <linux/kmod.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+
+#include "seppl.h"
+
+#ifdef MODULE_LICENSE
+MODULE_LICENSE("GPL");
+#endif
+#ifdef MODULE_DESCRIPTION
+MODULE_DESCRIPTION ("SEPPL Key Manager");
+#endif
+#ifdef MODULE_AUTHOR
+MODULE_AUTHOR("Lennart Poettering <"PACKAGE_BUGREPORT">");
+#endif
+
+static struct seppl_key *keyring = NULL;
+static spinlock_t keyring_lock = SPIN_LOCK_UNLOCKED;
+
+#define PROC_FILE_NAME "seppl_keyring"
+static struct proc_dir_entry* proc_file = NULL;
+
+
+struct cipher_info {
+ char *name;
+ int bits;
+};
+
+#define CIPHER_DICT_MAX 2
+
+static const struct cipher_info cipher_dict[CIPHER_DICT_MAX] = {
+ { "aes-cbc", 128 },
+ { "aes-cbc", 192 }
+};
+
+const struct cipher_info *seppl_find_cipher(u8 id) {
+ if (id < CIPHER_DICT_MAX)
+ return &cipher_dict[id];
+
+ return NULL;
+}
+
+struct seppl_key* seppl_find_key(u8 algorithm, const char *name, int r) {
+ struct seppl_key *key = NULL, *l;
+
+ for (l = keyring; l; l = l->next)
+ if (l->algorithm == algorithm && strncmp(l->name, name, sizeof(l->name)) == 0)
+ if (!r || atomic_read(&l->ready)) {
+ key = l;
+ break;
+ }
+
+ return key;
+}
+
+struct seppl_key* seppl_claim_key(u8 algorithm, const char *name) {
+ struct seppl_key *key = NULL;
+
+ spin_lock_bh(&keyring_lock); // FIXME: BH?
+
+ if ((key = seppl_find_key(algorithm, name, 1))) {
+ atomic_inc(&key->usage);
+ MOD_INC_USE_COUNT;
+ }
+
+ spin_unlock_bh(&keyring_lock);
+
+ return key;
+}
+
+void seppl_release_key(struct seppl_key* key) {
+ atomic_dec(&key->usage);
+ MOD_DEC_USE_COUNT;
+}
+
+// not spinlocked!
+static void seppl_next_iv(struct seppl_key *key) {
+ unsigned int i, m = key->ivsize;
+
+ for (i = 0; i < m ; i++) {
+ key->iv[i]++;
+ if (key->iv[i] != 0) break;
+ }
+}
+
+void seppl_copy_iv(struct seppl_key *key, u8* iv) {
+ spin_lock_bh(&key->iv_spinlock); // FIXME: BH?
+
+ memcpy(iv, key->iv, key->ivsize);
+ seppl_next_iv(key);
+
+ spin_unlock_bh(&key->iv_spinlock);
+}
+
+int seppl_add_key(u8 algorithm, const char *name, const u8 *key_data) {
+ struct seppl_key* key = NULL;
+ int r = -EINVAL;
+ int locked = 1;
+
+ spin_lock(&keyring_lock);
+
+ if ((key = seppl_find_key(algorithm, name, 0))) {
+
+ if (!atomic_read(&key->ready)) {
+ printk(KERN_ERR "SEPPL: Tried to replace incomplete key.\n");
+ goto finish;
+ }
+
+ memcpy(key->key, key_data, key->keysize);
+ if (crypto_cipher_setkey(key->tfm, key->key, key->keysize)) {
+ printk(KERN_ERR "SEPPL: Failed to set cipher key.\n");
+ goto finish;
+ }
+
+ printk(KERN_INFO "SEPPL: Replaced key sucessfully.\n");
+
+ r = 0;
+ goto finish;
+ } else {
+ const struct cipher_info* cinfo;
+
+ if (!(cinfo = seppl_find_cipher(algorithm))) {
+ printk(KERN_ERR "SEPPL: Unknown cipher\n");
+ goto finish;
+ }
+
+ if(!(key = kmalloc(sizeof(struct seppl_key), GFP_KERNEL))) {
+ r = -ENOMEM;
+ printk(KERN_ERR "SEPPL: kmalloc() failed\n");
+ goto finish;
+ }
+
+ key->algorithm = algorithm;
+ memset(key->name, 0, 7);
+ strncpy(key->name, name, 7);
+ atomic_set(&key->ready, 0);
+ key->next = keyring;
+ keyring = key;
+
+ spin_unlock(&keyring_lock);
+ locked = 0;
+
+ key->key = key->iv = NULL;
+ key->tfm = NULL;
+
+ atomic_set(&key->usage, 0);
+ spin_lock_init(&key->iv_spinlock);
+
+ if (!(key->tfm = crypto_alloc_tfm("aes", CRYPTO_TFM_MODE_CBC))) {
+ printk(KERN_ERR "SEPPL: Failed to load cipher.\n");
+ goto cleanup;
+ }
+
+ /* Fill in key */
+ if (!(key->key = kmalloc(key->keysize = cinfo->bits/8, GFP_KERNEL))) {
+ r = -ENOMEM;
+ printk(KERN_ERR "SEPPL: kmalloc() failed #2\n");
+ goto cleanup;
+ }
+ memcpy(key->key, key_data, key->keysize);
+
+ if (crypto_cipher_setkey(key->tfm, key->key, key->keysize)) {
+ printk(KERN_ERR "SEPPL: Failed to set cipher key.\n");
+ goto cleanup;
+ }
+
+ /* Fill in iv */
+ if (!(key->iv = kmalloc(key->ivsize = crypto_tfm_alg_ivsize(key->tfm), GFP_KERNEL))) {
+ r = -ENOMEM;
+ printk(KERN_ERR "SEPPL: kmalloc() failed #3\n");
+ goto cleanup;
+ }
+ get_random_bytes(key->iv, key->ivsize);
+
+ key->blocksize = crypto_tfm_alg_blocksize(key->tfm);
+
+ proc_file->size += 8 + key->keysize;
+ atomic_set(&key->ready, 1);
+
+ printk(KERN_INFO "SEPPL: Added key sucessfully.\n");
+
+ r = 0;
+ goto finish;
+ }
+
+cleanup:
+
+ if (key) {
+ struct seppl_key *i;
+
+ spin_lock(&keyring_lock);
+
+ if (keyring == key)
+ keyring = key->next;
+ else {
+ for (i = keyring; i; i = i->next) {
+ if (i->next == key) {
+ i->next = key->next;
+ break;
+ }
+ }
+ }
+
+ spin_unlock(&keyring_lock);
+
+ if (key->tfm)
+ crypto_free_tfm(key->tfm);
+
+ if (key->key)
+ kfree(key->key);
+
+ if (key->iv)
+ kfree(key->key);
+
+ kfree(key);
+ }
+
+finish:
+
+ if (locked)
+ spin_unlock(&keyring_lock);
+
+ return r;
+}
+
+void seppl_clear_keyring(void) {
+ struct seppl_key *key, *prev;
+
+ printk(KERN_INFO "SEPPL: Clearing keyring\n");
+
+ spin_lock(&keyring_lock);
+
+ prev = NULL;
+ key = keyring;
+ while (key) {
+ if (atomic_read(&key->ready) && !atomic_read(&key->usage)) {
+ struct seppl_key *k;
+
+ atomic_set(&key->ready, 0);
+
+ proc_file->size -= 8 + key->keysize;
+
+ if (prev)
+ prev->next = key->next;
+ else
+ keyring = key->next;
+
+ crypto_free_tfm(key->tfm);
+ kfree(key->key);
+ kfree(key->iv);
+
+ k = key;
+ key = key->next;
+ kfree(k);
+
+ continue;
+ }
+
+ prev = key;
+ key = key->next;
+ }
+
+ spin_unlock(&keyring_lock);
+}
+
+#ifndef MIN
+#define MIN(a,b) ((a)>(b)?(b):(a))
+#endif
+
+static int seppl_proc_read_func(char* page, char** start, off_t off, int count, int* eof, void* data) {
+ struct seppl_key *key;
+ char *e = page;
+ int d = 0;
+
+ MOD_INC_USE_COUNT;
+ spin_lock(&keyring_lock);
+
+ for (key = keyring; key; key = key->next) {
+ if (count <= 0) break;
+
+ *e = key->algorithm;
+ e ++; count--;
+
+ if (count <= 0) break;
+
+ memcpy(e, key->name, d = MIN(7, count));
+ e += d; count -= d;
+
+ if (count <= 0) break;
+
+ memcpy(e, key->key, d = MIN(key->keysize, count));
+ e += d; count -= d;
+
+ if (count <= 0) break;
+
+ if (key->next == 0)
+ if (eof)
+ *eof = 1;
+ }
+
+ spin_unlock(&keyring_lock);
+ MOD_DEC_USE_COUNT;
+
+ return e-page;
+}
+
+
+static int seppl_proc_write_func(struct file* file, const char* buffer, unsigned long count, void* data) {
+ int r = -EINVAL;
+ u8* buf = NULL;
+ MOD_INC_USE_COUNT;
+
+ count = count > 10*1024 ? 10*1024 : count;
+
+ if (!(buf = kmalloc(count, GFP_ATOMIC))) {
+ r = -ENOMEM;
+ goto finish;
+ }
+
+ if (copy_from_user(buf, buffer, count))
+ goto finish;
+
+ if (strcmp((char*) buf, "clear\n") == 0) {
+ seppl_clear_keyring();
+ r = strlen(buf);
+ } else {
+ unsigned long n = count;
+ u8* p = buf;
+
+ while (n >= 8) {
+ const struct cipher_info* ci = seppl_find_cipher(*p);
+ int l, t;
+
+ if (!ci) {
+ printk(KERN_ERR "SEPPL: Unknown cipher\n");
+ goto finish;
+ }
+
+ l = 8+ci->bits/8;
+
+ if (n < l) {
+ printk(KERN_ERR "SEPPL: Key data too short\n");
+ goto finish;
+ }
+
+ if ((t = seppl_add_key(*p, p+1, p+8)) < 0) {
+ r = t;
+ goto finish;
+ }
+
+ p += l;
+ n -= l;
+ }
+
+ if (n) {
+ printk(KERN_ERR "SEPPL: Data too short (%li)\n", n);
+ goto finish;
+ }
+
+ r = (int) count;
+ }
+
+finish:
+
+ if (buf)
+ kfree(buf);
+
+ MOD_DEC_USE_COUNT;
+ return r;
+}
+
+static int __init init(void) {
+ if (!(proc_file = create_proc_entry(PROC_FILE_NAME, 0600, proc_net)))
+ return -ENOMEM;
+
+ proc_file->read_proc = seppl_proc_read_func;
+ proc_file->write_proc = seppl_proc_write_func;
+ proc_file->owner = THIS_MODULE;
+ proc_file->size = 0;
+
+ printk("SEPPL: Loaded.\n");
+
+ return 0;
+}
+
+static void __exit fini(void) {
+ seppl_clear_keyring();
+
+ if (keyring)
+ printk("SEPPL: Something wicked happened.\n");
+
+ remove_proc_entry(PROC_FILE_NAME, proc_net);
+
+ printk("SEPPL: Unloaded.\n");
+}
+
+module_init(init);
+module_exit(fini);
+
+EXPORT_SYMBOL(seppl_copy_iv);
+EXPORT_SYMBOL(seppl_claim_key);
+EXPORT_SYMBOL(seppl_release_key);
+
diff --git a/kernel/seppl.h b/kernel/seppl.h
new file mode 100644
index 0000000..edc0d29
--- /dev/null
+++ b/kernel/seppl.h
@@ -0,0 +1,60 @@
+#ifndef _SEPPL_MODULE_H
+#define _SEPPL_MODULE_H
+
+/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */
+
+/***
+ This file is part of seppl
+
+ seppl 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.
+
+ seppl 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.
+
+ You should have received a copy of the GNU General Public License
+ along with seppl; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+***/
+
+#include <linux/spinlock.h>
+#include <linux/crypto.h>
+
+#if 0
+#define DEBUGP printk
+#else
+#define DEBUGP(format, args...)
+#endif
+
+#include "seppl_protocol.h"
+
+struct seppl_key {
+ u8 algorithm;
+ char name[7];
+ atomic_t ready;
+ atomic_t usage;
+
+ struct crypto_tfm *tfm;
+ spinlock_t iv_spinlock;
+ u8 *iv;
+ u8 *key;
+
+ unsigned int ivsize;
+ unsigned int keysize;
+ unsigned int blocksize;
+
+ struct seppl_key *next;
+};
+
+struct seppl_key* seppl_claim_key(u8 algorithm, const char *name);
+void seppl_release_key(struct seppl_key *key);
+void seppl_copy_iv(struct seppl_key *key, u8* iv);
+void seppl_clean_keys(void);
+int seppl_add_key(u8 algorithm, const char *name, const u8* key_data);
+
+#endif
diff --git a/kernel/seppl_protocol.h b/kernel/seppl_protocol.h
new file mode 100644
index 0000000..08d4fa6
--- /dev/null
+++ b/kernel/seppl_protocol.h
@@ -0,0 +1,27 @@
+#ifndef _SEPPL_H
+#define _SEPPL_H
+
+#define SEPPL_PROTOCOL 177
+
+// Packet layout:
+// 1. IP-Header PLAIN
+// 2. Uncrypted header PLAIN
+// 3. iv PLAIN
+// 4. Crypted header CRYPTED
+// 5. Payload (with TCP/UDP/...-Header) CRYPTED
+// 6. Padding CRYPTED
+
+struct seppl_uncrypt_hdr {
+ uint8_t algorithm;
+ char key_name[7];
+} __attribute__((packed)) uncrypt_hdr;
+
+struct seppl_crypt_hdr{
+ uint8_t ident; // 0x00
+ uint8_t saved_protocol;
+ uint16_t saved_tot_len;
+ uint16_t saved_frag_off;
+} __attribute__((packed)) crypt_hdr;
+
+
+#endif
diff --git a/kernel/test.sh b/kernel/test.sh
new file mode 100755
index 0000000..fc41522
--- /dev/null
+++ b/kernel/test.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $
+#
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+dmesg -n 7
+
+iptables -t mangle -F POSTROUTING
+iptables -t mangle -F PREROUTING
+
+sync
+
+make unload
+sleep 2
+make load
+
+../utils/seppl-ls -f /etc/seppl/ring2.keys > /proc/net/seppl_keyring
+../utils/seppl-ls
+
+iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -d 10.0.0.0/8 -j TCPMSS --set-mss $((1500-40-8-6-16))
+iptables -t mangle -A POSTROUTING -d 10.0.0.0/8 -j CRYPT --key `hostname`
+iptables -t mangle -A PREROUTING -d 10.0.0.0/8 -j DECRYPT
+
+iptables -t mangle -L
diff --git a/libs/Makefile.am b/libs/Makefile.am
new file mode 100644
index 0000000..28de14f
--- /dev/null
+++ b/libs/Makefile.am
@@ -0,0 +1,28 @@
+# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $
+#
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+AM_CPPFLAGS=-I../kernel
+iptlibdir = $(LIB_IPTABLES_DIR)
+
+iptlib_LTLIBRARIES = libipt_CRYPT.la libipt_DECRYPT.la
+
+libipt_CRYPT_la_SOURCES = libipt_CRYPT.c
+libipt_CRYPT_la_LDFLAGS = -Wc,-nostartfiles -module
+
+libipt_DECRYPT_la_SOURCES = libipt_DECRYPT.c
+libipt_DECRYPT_la_LDFLAGS = -Wc,-nostartfiles -module
diff --git a/libs/libipt_CRYPT.c b/libs/libipt_CRYPT.c
new file mode 100644
index 0000000..7e171f3
--- /dev/null
+++ b/libs/libipt_CRYPT.c
@@ -0,0 +1,114 @@
+/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */
+
+/***
+ This file is part of seppl
+
+ seppl 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.
+
+ seppl 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.
+
+ You should have received a copy of the GNU General Public License
+ along with seppl; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+***/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+#include "ipt_CRYPT.h"
+
+
+/* Function which prints out usage message. */
+static void help(void) {
+ printf("CRYPT options:\n"
+ " --algorithm algo Select algorithm\n"
+ " --key key Select key\n");
+}
+
+static struct option opts[] = {
+ { "algorithm", 1, 0, 'a' },
+ { "key", 1, 0, 'k' },
+ { 0 }
+};
+
+static void init(struct ipt_entry_target *t, unsigned int *nfcache) {
+ struct ipt_crypt_info *crypt = (struct ipt_crypt_info *) t->data;
+
+ memset(crypt, 0, sizeof(struct ipt_crypt_info));
+ strncpy(crypt->name, "def", 7);
+
+ *nfcache |= NFC_UNKNOWN;
+}
+
+static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) {
+ struct ipt_crypt_info *crypt = (struct ipt_crypt_info *)(*target)->data;
+
+ switch(c) {
+ case 'a':
+ crypt->algorithm = atoi(optarg);
+ return 1;
+
+ case 'k':
+ strncpy(crypt->name, optarg, 7);
+ return 1;
+
+ }
+
+ return 0;
+}
+
+static void final_check(unsigned int flags) {
+}
+
+static void print(const struct ipt_ip *ip, const struct ipt_entry_target *target, int numeric) {
+ const struct ipt_crypt_info *crypt = (const struct ipt_crypt_info *)target->data;
+ char txt[8];
+
+ strncpy(txt, crypt->name, 7);
+ txt[7] = 0;
+
+ printf("key: %s algo: %i\n", txt, crypt->algorithm);
+}
+
+static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target) {
+ const struct ipt_crypt_info *crypt = (const struct ipt_crypt_info *)target->data;
+ char txt[8];
+
+ strncpy(txt, crypt->name, 7);
+ txt[7] = 0;
+
+ printf("--algorithm %i ", crypt->algorithm);
+ printf("--key '%s'", txt);
+
+}
+
+static struct iptables_target crypt = {
+ NULL,
+ "CRYPT",
+ "1.2.8",
+ IPT_ALIGN(sizeof(struct ipt_crypt_info)),
+ IPT_ALIGN(sizeof(struct ipt_crypt_info)),
+ &help,
+ &init,
+ &parse,
+ &final_check,
+ &print,
+ &save,
+ opts
+};
+
+void _init(void) {
+ register_target(&crypt);
+}
diff --git a/libs/libipt_DECRYPT.c b/libs/libipt_DECRYPT.c
new file mode 100644
index 0000000..a9a5fc9
--- /dev/null
+++ b/libs/libipt_DECRYPT.c
@@ -0,0 +1,75 @@
+/* $Id: newmail.c 31 2003-10-22 22:59:07Z lennart $ */
+
+/***
+ This file is part of seppl
+
+ seppl 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.
+
+ seppl 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.
+
+ You should have received a copy of the GNU General Public License
+ along with seppl; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+***/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ip_tables.h>
+
+#include "ipt_DECRYPT.h"
+
+
+/* Function which prints out usage message. */
+static void help(void) {
+ printf("DECRYPT options: none");
+}
+
+static struct option opts[] = {
+ { 0 }
+};
+
+static void init(struct ipt_entry_target *t, unsigned int *nfcache) {
+ *nfcache |= NFC_UNKNOWN;
+}
+
+static int parse(int c, char **argv, int invert, unsigned int *flags, const struct ipt_entry *entry, struct ipt_entry_target **target) {
+ return 0;
+}
+
+static void final_check(unsigned int flags) {
+}
+
+static void print(const struct ipt_ip *ip, const struct ipt_entry_target *target, int numeric) {
+}
+
+static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target) {
+}
+
+static struct iptables_target decrypt = {
+ NULL,
+ "DECRYPT",
+ "1.2.8",
+ IPT_ALIGN(sizeof(struct ipt_decrypt_info)),
+ IPT_ALIGN(sizeof(struct ipt_decrypt_info)),
+ &help,
+ &init,
+ &parse,
+ &final_check,
+ &print,
+ &save,
+ opts
+};
+
+void _init(void) {
+ register_target(&decrypt);
+}
diff --git a/utils/Makefile.am b/utils/Makefile.am
new file mode 100644
index 0000000..49726f1
--- /dev/null
+++ b/utils/Makefile.am
@@ -0,0 +1,22 @@
+# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $
+#
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+sbin_SCRIPTS=seppl-ls seppl-gen-key
+python_PYTHON=seppl_common.py
+
+EXTRA_DIST=seppl-ls seppl-gen-key
diff --git a/utils/seppl-gen-key b/utils/seppl-gen-key
new file mode 100755
index 0000000..cc5817e
--- /dev/null
+++ b/utils/seppl-gen-key
@@ -0,0 +1,110 @@
+#!/usr/bin/python
+
+# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $
+#
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+from seppl_common import *
+import getopt, sys
+
+def genkey(a, name, f):
+
+ n, b = find_alg_by_number(a)
+
+ if b == 0:
+ return -1
+
+ fd = open("/dev/random", "r+")
+ key = fd.read(b/8)
+ fd.close()
+
+ if (len(key) != b/8):
+ sys.stderr("ERROR: Cannot generate randomness.\n")
+ return
+
+ if f == dump_key_xml:
+ print "<seppl-keyring>"
+
+ f(a, name, key)
+
+ if f == dump_key_xml:
+ print "</seppl-keyring>"
+
+ return 0
+
+algorithm = "aes"
+bits = 128
+name = "def"
+func = dump_key_xml
+
+def usage():
+ global algorithm, bits, name, func
+ x = { dump_key_xml : "disable", dump_key_bin : "enable" }
+
+ print "%s:" % sys.argv[0]
+ print " -h --help Show this help"
+ print " -x --no-xml No xml output (%s)" % x[func]
+ print " -a --algorithm ALGORITHM Specify algorithm (%s)" % algorithm
+ print " -b --bits BITS Specify key length (%s)" % bits
+ print " -n --name NAME Specify key name (%s)" % name
+
+
+def main():
+ global algorithm, bits, name, func
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "hxa:b:n:", ["help", "no-xml", "algorithm=", "bits=", "name="])
+ except getopt.GetoptError:
+ usage()
+ sys.exit(1)
+
+ u = 0;
+
+ for o, a in opts:
+ if o in ("-h", "--help"):
+ u = 1
+
+ if o in ("-x", "--no-xml"):
+ func = dump_key_bin
+
+ if o in ("-a", "--algorithm"):
+ algorithm = a
+
+ if o in ("-b", "--bits"):
+ bits = int(a)
+
+ if o in ("-n", "--name"):
+ name = a[:7]
+
+ if u:
+ usage()
+ sys.exit(0)
+
+
+ a = find_alg_by_name(algorithm, bits)
+
+ if a == -1:
+ sys.stderr.write("ERROR: Cipher not available\n")
+ sys.exit(2)
+
+ genkey(a, name, func)
+
+if __name__ == "__main__":
+ main()
+
+
+
diff --git a/utils/seppl-ls b/utils/seppl-ls
new file mode 100755
index 0000000..b05b949
--- /dev/null
+++ b/utils/seppl-ls
@@ -0,0 +1,198 @@
+#!/usr/bin/python
+
+# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $
+#
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+import getopt, sys
+
+from seppl_common import *
+import xml.sax, xml.sax.handler
+
+name = None
+algorithm = None
+bits = 0
+reverse = 0
+PROC_FILE_NAME = "/proc/net/seppl_keyring"
+file = None
+
+class KeyContentHandler(xml.sax.handler.ContentHandler):
+
+ last = None
+
+ def startElement(self, name, attrs):
+ self.last = name
+
+ if name != "key":
+ return
+
+ self.name = ""
+ self.algorithm = ""
+ self.bits = ""
+ self.data = ""
+
+ def endElement(self, n):
+ global name, algorithm, bits
+ self.last = None
+
+ if n != "key":
+ return
+
+ if self.name == "":
+ self.name = "def"
+
+ if self.algorithm == "":
+ self.algorithm = "aes"
+
+ if self.bits == "":
+ self.bits = 128
+ else:
+ self.bits = int(self.bits)
+
+ a = find_alg_by_name(self.algorithm, self.bits)
+ if a == -1:
+ raise xml.sax.SAXNotRecognizedException("Cipher not known")
+
+ key = parse_key(self.data)
+ if key is None or len(key) != self.bits/8:
+ raise xml.sax.SAXNotRecognizedException("Could not parse key data.")
+
+ if (name is None or name == self.name) and (algorithm is None or algorithm == self.algorithm) and (bits == 0 or bits == self.bits):
+ dump_key_bin(a, self.name, key)
+
+ def characters(self, content):
+ content = content.strip()
+
+ if len(content) == 0:
+ return
+
+ if self.last == "name":
+ self.name += content
+ return
+ if self.last == "algorithm":
+ self.algorithm += content
+ return
+ if self.last == "bits":
+ self.bits += content
+ return
+ if self.last == "data":
+ self.data += content
+ return
+
+ raise xml.sax.SAXNotRecognizedException("Malformed XML structure |%s|%s|" % (self.last, content))
+
+def usage():
+ global name, algorithm, bits, reverse, file
+
+ print "%s:" % sys.argv[0]
+ print " -h --help Show this help"
+ print " -r --reverse Convert XML to binary, instead of the other way round (%s)" % { 0 : "disabled", 1 : "enabled" }[reverse]
+ print " -a --algorithm ALGORITHM Show only keys with algorithm (%s)" % algorithm
+ print " -b --bits BITS Show only keys with bit length (%s)" % bits
+ print " -n --name NAME Show only keys with name (%s)" % name
+ print " -f --file FILE Specify file (- for STDIN) (%s)" % file
+ pass
+
+def main():
+ global name, algorithm, bits, reverse, file
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "hn:a:b:rf:", ["help", "name=", "algorithm=", "bits=", "reverse", "file"])
+ except getopt.GetoptError:
+ usage()
+ sys.exit(2)
+
+ u = 0
+
+ for o, a in opts:
+ if o in ("-h", "--help"):
+ u = 1
+
+ if o in ("-n", "--name"):
+ name = a[:7]
+
+ if o in ("-a", "--algorithm"):
+ algorithm = a
+
+ if o in ("-b", "--bits"):
+ bits = int(a)
+
+ if o in ("-r", "--reverse"):
+ reverse = 1
+
+ if o in ("-f", "--file"):
+ file = a
+
+ if file is None:
+ if reverse:
+ file = "-"
+ else:
+ file = PROC_FILE_NAME
+
+ if u:
+ usage()
+ sys.exit(0)
+
+
+ if file == "-":
+ buf = sys.stdin.read();
+ else:
+ try:
+ fd = open(file, "r+")
+ buf = fd.read();
+ fd.close()
+ except IOError, e:
+ sys.stderr.write("Could not open proc-file (%s).\n" % str(e))
+ sys.exit(2)
+
+
+ if len(buf) == 0:
+ sys.exit(0)
+
+ if buf[0] == '<':
+ reverse = 1
+
+ if not reverse:
+
+ print "<seppl-keyring>"
+ while len(buf) >= 8:
+ a, _name = unpack("B7s", buf[:8])
+ n, b = find_alg_by_number(a)
+
+ if (b == 0):
+ sys.stderr.write("ERROR: Unknown cipher. Please update.\n")
+ break
+
+ _name = _name.replace("\000", "")
+
+ if (name is None or name == _name) and (algorithm is None or algorithm == n) and (bits == 0 or b == bits):
+ dump_key_xml(a, _name, buf[8:b/8+8])
+
+ buf = buf[8+b/8:]
+ print "</seppl-keyring>"
+ else:
+ try:
+ xml.sax.parseString(buf, KeyContentHandler())
+ except xml.sax.SAXException, e:
+ sys.stderr.write("Parse error (%s)\n" %str(e))
+
+
+if __name__ == "__main__":
+ main()
+
+
+
diff --git a/utils/seppl_common.py b/utils/seppl_common.py
new file mode 100644
index 0000000..c8fe5ca
--- /dev/null
+++ b/utils/seppl_common.py
@@ -0,0 +1,105 @@
+#!/usr/bin/perl
+
+# $Id: Makefile.am 40 2003-10-27 18:32:45Z lennart $
+#
+# This file is part of seppl.
+#
+# seppl 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.
+#
+# seppl 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.
+#
+# You should have received a copy of the GNU General Public License
+# along with seppl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+
+from struct import *
+import re, string, sys
+
+algs = { 0 : ('aes', 128), 1 : ('aes', 192) }
+
+def find_alg_by_number(a):
+ global algs
+
+ if algs.has_key(a):
+ return algs[a];
+ else:
+ return ('unknown', 0)
+
+def find_alg_by_name(n, b):
+ global algs
+
+ for i in algs.keys():
+ if algs[i][0] == n and algs[i][1] == b:
+ return i
+
+ return -1
+
+def strhex(s):
+ r = ""
+ for i in range(len(s)):
+ (b,) = unpack("B", s[i])
+ r = "%s:%02x" % (r, b)
+
+ return r[1:]
+
+def dump_key_xml(a, name, key):
+ alg, bits = find_alg_by_number(a)
+
+ if bits == 0:
+ sys.stderr.write("ERROR: Algorithm not found\n")
+ return -1
+
+ print "<key>"
+ print " <name>%s</name>" % name
+ print " <algorithm>%s</algorithm>" % alg
+ print " <bits>%u</bits>" % bits
+ print " <data>%s</data>" % strhex(key)
+ print "</key>"
+
+ return 0
+
+def dump_key_bin(a, name, key):
+ alg, bits = find_alg_by_number(a)
+
+ if bits == 0:
+ sys.stderr.write("ERROR: Algorithm not found\n")
+ return -1
+
+ if len(key) != bits/8:
+ sys.stderr.write("ERROR: Key has wrong size\n")
+ return -1
+
+ name = name.encode("iso8859-1", 'ignore')
+
+ sys.stdout.write(pack("B7s", a, name[:7]))
+ sys.stdout.write(key)
+ sys.stdout.flush()
+
+def parse_key(data):
+
+ k = ""
+
+ r = re.compile("^([0-9A-Fa-f][0-9A-Fa-f])")
+
+ while len(data) > 0:
+ m = r.match(data+":")
+
+ if m == None:
+ return None
+
+ k += pack("B", string.atoi(m.group(0), 16))
+
+ data = data[3:]
+
+ return k
+
+
+
+
+