summaryrefslogtreecommitdiff
path: root/programs/pluto/alg
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2006-05-22 05:12:18 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2006-05-22 05:12:18 +0000
commitaa0f5b38aec14428b4b80e06f90ff781f8bca5f1 (patch)
tree95f3d0c8cb0d59d88900dbbd72110d7ab6e15b2a /programs/pluto/alg
parent7c383bc22113b23718be89fe18eeb251942d7356 (diff)
downloadvyos-strongswan-aa0f5b38aec14428b4b80e06f90ff781f8bca5f1.tar.gz
vyos-strongswan-aa0f5b38aec14428b4b80e06f90ff781f8bca5f1.zip
Import initial strongswan 2.7.0 version into SVN.
Diffstat (limited to 'programs/pluto/alg')
-rw-r--r--programs/pluto/alg/Config.ike_alg9
-rw-r--r--programs/pluto/alg/Makefile93
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_aes14
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_blowfish13
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_serpent13
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_sha213
-rw-r--r--programs/pluto/alg/Makefile.ike_alg_twofish13
-rw-r--r--programs/pluto/alg/ike_alg_aes.c68
-rw-r--r--programs/pluto/alg/ike_alg_blowfish.c52
-rw-r--r--programs/pluto/alg/ike_alg_serpent.c70
-rw-r--r--programs/pluto/alg/ike_alg_sha2.c61
-rw-r--r--programs/pluto/alg/ike_alg_twofish.c85
12 files changed, 504 insertions, 0 deletions
diff --git a/programs/pluto/alg/Config.ike_alg b/programs/pluto/alg/Config.ike_alg
new file mode 100644
index 000000000..0fcda4cad
--- /dev/null
+++ b/programs/pluto/alg/Config.ike_alg
@@ -0,0 +1,9 @@
+##
+## IKE algorithms config. for static linking into pluto
+## By now 3DES,MD5 and SHA1 are already present in pluto.
+##
+CONFIG_IKE_ALG_AES=y
+CONFIG_IKE_ALG_BLOWFISH=y
+CONFIG_IKE_ALG_SERPENT=y
+CONFIG_IKE_ALG_TWOFISH=y
+CONFIG_IKE_ALG_SHA2=y
diff --git a/programs/pluto/alg/Makefile b/programs/pluto/alg/Makefile
new file mode 100644
index 000000000..9732cc80e
--- /dev/null
+++ b/programs/pluto/alg/Makefile
@@ -0,0 +1,93 @@
+# pluto/alg Makefile
+# Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
+#
+# 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.
+#
+# $Id: Makefile,v 1.3 2004/06/23 04:45:20 as Exp $
+
+Make.common: ../Makefile
+ make -s -C .. showdefs > $@
+
+-include Make.common
+include Config.ike_alg
+
+LIBCRYPTO:=../../../lib/libcrypto
+ALLFLAGS=$(CPPFLAGS) $(CFLAGS) -I .. -I- -I ../../../linux/include -I $(LIBCRYPTO)
+LIBALG := libalg.o
+
+all : $(LIBALG)
+
+include $(wildcard Makefile.ike_alg_*)
+#include $(wildcard Makefile.ike_alg_[ab]*)
+
+ALG_DIRS:=$(ALG_DIRS-y)
+ALG_LIBS:=$(ALG_LIBS-y)
+ALG_SRCS:=$(ALG_SRCS-y)
+ALG_OBJS:=$(ALG_OBJS-y)
+$(LIBALG): ike_alginit.o $(ALG_OBJS) $(ALG_LIBS)
+ $(LD) -r -o $@ $^
+
+# Search for IKE_ALG_INIT_NAME: in ike_alg_*.c to
+# build ike_alginit.c:ike_alginit()
+
+ike_alginit.c: $(ALG_SRCS) Makefile Config.ike_alg
+ @awk ' \
+ BEGIN { print "extern int ike_alg_init(void); \
+ int ike_alg_init(void) {" } \
+ /IKE_ALG_INIT_NAME:/ \
+ { print "{ extern int " $$2" (void); " $$2 "();}" } \
+ END { print "return 0;}" } \
+ ' $(ALG_SRCS) /dev/null > $@
+
+clean :
+ @for i in $(ALG_DIRS);do make -C $$i clean;done
+ rm -f *.[oa] ike_alginit.c Make.common
+
+gatherdeps:
+ @ls $(ALG_SRCS) | grep '\.c' | sed -e 's/\(.*\)\.c$$/\1.o: \1.c/'
+ @echo
+ @ls $(ALG_SRCS) | grep '\.c' | xargs grep '^#[ ]*include[ ]*"' | \
+ sed -n -e '/#include.*"lib/d' \
+ -e 's/\.c:#[ ]*include[ ]*"/.o: ..\//' -e 's/".*//p'
+
+# Dependencies generated by "make gatherdeps":
+
+ike_alg_aes.o: ike_alg_aes.c
+ike_alg_blowfish.o: ike_alg_blowfish.c
+ike_alg_serpent.o: ike_alg_serpent.c
+ike_alg_sha2.o: ike_alg_sha2.c
+ike_alg_twofish.o: ike_alg_twofish.c
+
+ike_alg_aes.o: ../constants.h
+ike_alg_aes.o: ../defs.h
+ike_alg_aes.o: ../log.h
+ike_alg_aes.o: ../alg_info.h
+ike_alg_aes.o: ../ike_alg.h
+ike_alg_blowfish.o: ../constants.h
+ike_alg_blowfish.o: ../defs.h
+ike_alg_blowfish.o: ../log.h
+ike_alg_blowfish.o: ../alg_info.h
+ike_alg_blowfish.o: ../ike_alg.h
+ike_alg_serpent.o: ../constants.h
+ike_alg_serpent.o: ../defs.h
+ike_alg_serpent.o: ../log.h
+ike_alg_serpent.o: ../alg_info.h
+ike_alg_serpent.o: ../ike_alg.h
+ike_alg_sha2.o: ../constants.h
+ike_alg_sha2.o: ../defs.h
+ike_alg_sha2.o: ../log.h
+ike_alg_sha2.o: ../alg_info.h
+ike_alg_sha2.o: ../ike_alg.h
+ike_alg_twofish.o: ../constants.h
+ike_alg_twofish.o: ../defs.h
+ike_alg_twofish.o: ../log.h
+ike_alg_twofish.o: ../alg_info.h
+ike_alg_twofish.o: ../ike_alg.h
diff --git a/programs/pluto/alg/Makefile.ike_alg_aes b/programs/pluto/alg/Makefile.ike_alg_aes
new file mode 100644
index 000000000..12009ba5c
--- /dev/null
+++ b/programs/pluto/alg/Makefile.ike_alg_aes
@@ -0,0 +1,14 @@
+ALG:=aes
+CONFIG_YES:=$(CONFIG_IKE_ALG_AES)
+DIR_AES:=$(LIBCRYPTO)/libaes
+
+ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_AES)
+ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_AES)/libaes.a
+ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
+ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
+
+$(DIR_AES)/libaes.a:
+ make -C $(DIR_AES) CFLAGS="$(CFLAGS)" libaes.a
+
+ike_alg_$(ALG).o: ike_alg_$(ALG).c
+ $(CC) -I $(LIBCRYPTO) -I$(DIR_AES) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/Makefile.ike_alg_blowfish b/programs/pluto/alg/Makefile.ike_alg_blowfish
new file mode 100644
index 000000000..c3af6199b
--- /dev/null
+++ b/programs/pluto/alg/Makefile.ike_alg_blowfish
@@ -0,0 +1,13 @@
+ALG:=blowfish
+CONFIG_YES:=$(CONFIG_IKE_ALG_BLOWFISH)
+DIR_BLOWFISH:=$(LIBCRYPTO)/libblowfish
+ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_BLOWFISH)
+ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_BLOWFISH)/libblowfish.a
+ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
+ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
+
+$(DIR_BLOWFISH)/libblowfish.a:
+ make -C $(DIR_BLOWFISH) CFLAGS="$(CFLAGS)" libblowfish.a
+
+ike_alg_$(ALG).o: ike_alg_$(ALG).c
+ $(CC) -I $(LIBCRYPTO) -I$(DIR_BLOWFISH) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/Makefile.ike_alg_serpent b/programs/pluto/alg/Makefile.ike_alg_serpent
new file mode 100644
index 000000000..3395ac0ea
--- /dev/null
+++ b/programs/pluto/alg/Makefile.ike_alg_serpent
@@ -0,0 +1,13 @@
+ALG:=serpent
+CONFIG_YES:=$(CONFIG_IKE_ALG_SERPENT)
+DIR_SERPENT:=$(LIBCRYPTO)/libserpent
+ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_SERPENT)
+ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_SERPENT)/libserpent.a
+ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
+ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
+
+$(DIR_SERPENT)/libserpent.a:
+ make -C $(DIR_SERPENT) CFLAGS="$(CFLAGS)" libserpent.a
+
+ike_alg_$(ALG).o: ike_alg_$(ALG).c
+ $(CC) -I $(LIBCRYPTO) -I$(DIR_SERPENT) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/Makefile.ike_alg_sha2 b/programs/pluto/alg/Makefile.ike_alg_sha2
new file mode 100644
index 000000000..67e68a667
--- /dev/null
+++ b/programs/pluto/alg/Makefile.ike_alg_sha2
@@ -0,0 +1,13 @@
+ALG:=sha2
+CONFIG_YES:=$(CONFIG_IKE_ALG_SHA2)
+DIR_SHA2:=$(LIBCRYPTO)/libsha2
+ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_SHA2)
+ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_SHA2)/libsha2.a
+ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
+ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
+
+$(DIR_SHA2)/libsha2.a:
+ make -C $(DIR_SHA2) libsha2.a
+
+ike_alg_$(ALG).o: ike_alg_$(ALG).c
+ $(CC) -I $(LIBCRYPTO) -I$(DIR_SHA2) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/Makefile.ike_alg_twofish b/programs/pluto/alg/Makefile.ike_alg_twofish
new file mode 100644
index 000000000..dcd30dd3e
--- /dev/null
+++ b/programs/pluto/alg/Makefile.ike_alg_twofish
@@ -0,0 +1,13 @@
+ALG:=twofish
+CONFIG_YES:=$(CONFIG_IKE_ALG_TWOFISH)
+DIR_TWOFISH:=$(LIBCRYPTO)/libtwofish
+ALG_DIRS-$(CONFIG_YES) := $(ALG_DIRS-$(CONFIG_YES)) $(DIR_TWOFISH)
+ALG_LIBS-$(CONFIG_YES) := $(ALG_LIBS-$(CONFIG_YES)) $(DIR_TWOFISH)/libtwofish.a
+ALG_SRCS-$(CONFIG_YES) := $(ALG_SRCS-$(CONFIG_YES)) ike_alg_$(ALG).c
+ALG_OBJS-$(CONFIG_YES) := $(ALG_OBJS-$(CONFIG_YES)) ike_alg_$(ALG).o
+
+$(DIR_TWOFISH)/libtwofish.a:
+ make -C $(DIR_TWOFISH) CFLAGS="$(CFLAGS)" libtwofish.a
+
+ike_alg_$(ALG).o: ike_alg_$(ALG).c
+ $(CC) -I $(LIBCRYPTO) -I$(DIR_TWOFISH) $(COPTS) $(ALLFLAGS) -c $<
diff --git a/programs/pluto/alg/ike_alg_aes.c b/programs/pluto/alg/ike_alg_aes.c
new file mode 100644
index 000000000..44de09b4c
--- /dev/null
+++ b/programs/pluto/alg/ike_alg_aes.c
@@ -0,0 +1,68 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <freeswan.h>
+
+#include "constants.h"
+#include "defs.h"
+#include "log.h"
+#include "libaes/aes_cbc.h"
+#include "alg_info.h"
+#include "ike_alg.h"
+
+#define AES_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
+#define AES_KEY_MIN_LEN 128
+#define AES_KEY_DEF_LEN 128
+#define AES_KEY_MAX_LEN 256
+
+static void
+do_aes(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
+{
+ aes_context aes_ctx;
+ char iv_bak[AES_CBC_BLOCK_SIZE];
+ char *new_iv = NULL; /* logic will avoid copy to NULL */
+
+ aes_set_key(&aes_ctx, key, key_size, 0);
+
+ /*
+ * my AES cbc does not touch passed IV (optimization for
+ * ESP handling), so I must "emulate" des-like IV
+ * crunching
+ */
+ if (!enc)
+ memcpy(new_iv=iv_bak, (char*) buf + buf_len - AES_CBC_BLOCK_SIZE
+ , AES_CBC_BLOCK_SIZE);
+
+ AES_cbc_encrypt(&aes_ctx, buf, buf, buf_len, iv, enc);
+
+ if (enc)
+ new_iv = (char*) buf + buf_len-AES_CBC_BLOCK_SIZE;
+
+ memcpy(iv, new_iv, AES_CBC_BLOCK_SIZE);
+}
+
+struct encrypt_desc algo_aes =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_AES_CBC,
+ algo_next: NULL,
+ enc_ctxsize: sizeof(aes_context),
+ enc_blocksize: AES_CBC_BLOCK_SIZE,
+ keyminlen: AES_KEY_MIN_LEN,
+ keydeflen: AES_KEY_DEF_LEN,
+ keymaxlen: AES_KEY_MAX_LEN,
+ do_crypt: do_aes,
+};
+
+int ike_alg_aes_init(void);
+
+int
+ike_alg_aes_init(void)
+{
+ int ret = ike_alg_register_enc(&algo_aes);
+ return ret;
+}
+/*
+IKE_ALG_INIT_NAME: ike_alg_aes_init
+*/
diff --git a/programs/pluto/alg/ike_alg_blowfish.c b/programs/pluto/alg/ike_alg_blowfish.c
new file mode 100644
index 000000000..2bbef051b
--- /dev/null
+++ b/programs/pluto/alg/ike_alg_blowfish.c
@@ -0,0 +1,52 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <freeswan.h>
+
+#include "constants.h"
+#include "defs.h"
+#include "log.h"
+#include "libblowfish/blowfish.h"
+#include "alg_info.h"
+#include "ike_alg.h"
+
+#define BLOWFISH_CBC_BLOCK_SIZE 8 /* block size */
+#define BLOWFISH_KEY_MIN_LEN 128
+#define BLOWFISH_KEY_MAX_LEN 448
+
+
+static void
+do_blowfish(u_int8_t *buf, size_t buf_len, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
+{
+ BF_KEY bf_ctx;
+
+ BF_set_key(&bf_ctx, key_size , key);
+ BF_cbc_encrypt(buf, buf, buf_len, &bf_ctx, iv, enc);
+}
+
+struct encrypt_desc algo_blowfish =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_BLOWFISH_CBC,
+ algo_next: NULL,
+ enc_ctxsize: sizeof(BF_KEY),
+ enc_blocksize: BLOWFISH_CBC_BLOCK_SIZE,
+ keyminlen: BLOWFISH_KEY_MIN_LEN,
+ keydeflen: BLOWFISH_KEY_MIN_LEN,
+ keymaxlen: BLOWFISH_KEY_MAX_LEN,
+ do_crypt: do_blowfish,
+};
+
+int ike_alg_blowfish_init(void);
+
+int
+ike_alg_blowfish_init(void)
+{
+ int ret = ike_alg_register_enc(&algo_blowfish);
+
+ return ret;
+}
+/*
+IKE_ALG_INIT_NAME: ike_alg_blowfish_init
+*/
diff --git a/programs/pluto/alg/ike_alg_serpent.c b/programs/pluto/alg/ike_alg_serpent.c
new file mode 100644
index 000000000..fb01caa41
--- /dev/null
+++ b/programs/pluto/alg/ike_alg_serpent.c
@@ -0,0 +1,70 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <freeswan.h>
+
+#include "constants.h"
+#include "defs.h"
+#include "log.h"
+#include "libserpent/serpent_cbc.h"
+#include "alg_info.h"
+#include "ike_alg.h"
+
+#define SERPENT_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
+#define SERPENT_KEY_MIN_LEN 128
+#define SERPENT_KEY_DEF_LEN 128
+#define SERPENT_KEY_MAX_LEN 256
+
+static void
+do_serpent(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
+{
+ serpent_context serpent_ctx;
+ char iv_bak[SERPENT_CBC_BLOCK_SIZE];
+ char *new_iv = NULL; /* logic will avoid copy to NULL */
+
+
+ serpent_set_key(&serpent_ctx, key, key_size);
+ /*
+ * my SERPENT cbc does not touch passed IV (optimization for
+ * ESP handling), so I must "emulate" des-like IV
+ * crunching
+ */
+ if (!enc)
+ memcpy(new_iv=iv_bak,
+ (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE,
+ SERPENT_CBC_BLOCK_SIZE);
+
+ serpent_cbc_encrypt(&serpent_ctx, buf, buf, buf_size, iv, enc);
+
+ if (enc)
+ new_iv = (char*) buf + buf_size-SERPENT_CBC_BLOCK_SIZE;
+
+ memcpy(iv, new_iv, SERPENT_CBC_BLOCK_SIZE);
+}
+
+struct encrypt_desc encrypt_desc_serpent =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_SERPENT_CBC,
+ algo_next: NULL,
+ enc_ctxsize: sizeof(struct serpent_context),
+ enc_blocksize: SERPENT_CBC_BLOCK_SIZE,
+ keyminlen: SERPENT_KEY_MIN_LEN,
+ keydeflen: SERPENT_KEY_DEF_LEN,
+ keymaxlen: SERPENT_KEY_MAX_LEN,
+ do_crypt: do_serpent,
+};
+
+int ike_alg_serpent_init(void);
+
+int
+ike_alg_serpent_init(void)
+{
+ int ret = ike_alg_register_enc(&encrypt_desc_serpent);
+
+ return ret;
+}
+/*
+IKE_ALG_INIT_NAME: ike_alg_serpent_init
+*/
diff --git a/programs/pluto/alg/ike_alg_sha2.c b/programs/pluto/alg/ike_alg_sha2.c
new file mode 100644
index 000000000..ad24f7cf0
--- /dev/null
+++ b/programs/pluto/alg/ike_alg_sha2.c
@@ -0,0 +1,61 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <freeswan.h>
+
+#include "constants.h"
+#include "defs.h"
+#include "log.h"
+#include "libsha2/sha2.h"
+#include "alg_info.h"
+#include "ike_alg.h"
+
+#define SHA2_256_DIGEST_SIZE (256/BITS_PER_BYTE)
+#define SHA2_512_DIGEST_SIZE (512/BITS_PER_BYTE)
+
+static void sha256_hash_final(u_char *hash, sha256_context *ctx)
+{
+ sha256_final(ctx);
+ memcpy(hash, &ctx->sha_out[0], SHA2_256_DIGEST_SIZE);
+}
+static void sha512_hash_final(u_char *hash, sha512_context *ctx)
+{
+ sha512_final(ctx);
+ memcpy(hash, &ctx->sha_out[0], SHA2_512_DIGEST_SIZE);
+}
+struct hash_desc hash_desc_sha2_256 = {
+ algo_type: IKE_ALG_HASH,
+ algo_id: OAKLEY_SHA2_256,
+ algo_next: NULL,
+ hash_ctx_size: sizeof(sha256_context),
+ hash_init: (void (*)(void *))sha256_init,
+ hash_update: (void (*)(void *, const u_char *, size_t ))sha256_write,
+ hash_final:(void (*)(u_char *, void *))sha256_hash_final,
+ hash_digest_size: SHA2_256_DIGEST_SIZE,
+};
+struct hash_desc hash_desc_sha2_512 = {
+ algo_type: IKE_ALG_HASH,
+ algo_id: OAKLEY_SHA2_512,
+ algo_next: NULL,
+ hash_ctx_size: sizeof(sha512_context),
+ hash_init: (void (*)(void *))sha512_init,
+ hash_update: (void (*)(void *, const u_char *, size_t ))sha512_write,
+ hash_final:(void (*)(u_char *, void *))sha512_hash_final,
+ hash_digest_size: SHA2_512_DIGEST_SIZE,
+};
+int ike_alg_sha2_init(void);
+int
+ike_alg_sha2_init(void)
+{
+ int ret;
+ ret = ike_alg_register_hash(&hash_desc_sha2_256);
+ if (ret)
+ goto out;
+ ret = ike_alg_register_hash(&hash_desc_sha2_512);
+out:
+ return ret;
+}
+/*
+IKE_ALG_INIT_NAME: ike_alg_sha2_init
+*/
diff --git a/programs/pluto/alg/ike_alg_twofish.c b/programs/pluto/alg/ike_alg_twofish.c
new file mode 100644
index 000000000..1788bc394
--- /dev/null
+++ b/programs/pluto/alg/ike_alg_twofish.c
@@ -0,0 +1,85 @@
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <freeswan.h>
+
+#include "constants.h"
+#include "defs.h"
+#include "log.h"
+#include "libtwofish/twofish_cbc.h"
+#include "alg_info.h"
+#include "ike_alg.h"
+
+#define TWOFISH_CBC_BLOCK_SIZE (128/BITS_PER_BYTE)
+#define TWOFISH_KEY_MIN_LEN 128
+#define TWOFISH_KEY_DEF_LEN 128
+#define TWOFISH_KEY_MAX_LEN 256
+
+static void
+do_twofish(u_int8_t *buf, size_t buf_size, u_int8_t *key, size_t key_size, u_int8_t *iv, bool enc)
+{
+ twofish_context twofish_ctx;
+ char iv_bak[TWOFISH_CBC_BLOCK_SIZE];
+ char *new_iv = NULL; /* logic will avoid copy to NULL */
+
+ twofish_set_key(&twofish_ctx, key, key_size);
+ /*
+ * my TWOFISH cbc does not touch passed IV (optimization for
+ * ESP handling), so I must "emulate" des-like IV
+ * crunching
+ */
+ if (!enc)
+ memcpy(new_iv=iv_bak,
+ (char*) buf + buf_size-TWOFISH_CBC_BLOCK_SIZE,
+ TWOFISH_CBC_BLOCK_SIZE);
+
+ twofish_cbc_encrypt(&twofish_ctx, buf, buf, buf_size, iv, enc);
+
+ if (enc)
+ new_iv = (char*) buf + buf_size-TWOFISH_CBC_BLOCK_SIZE;
+
+ memcpy(iv, new_iv, TWOFISH_CBC_BLOCK_SIZE);
+}
+
+struct encrypt_desc encrypt_desc_twofish =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_TWOFISH_CBC,
+ algo_next: NULL,
+ enc_ctxsize: sizeof(twofish_context),
+ enc_blocksize: TWOFISH_CBC_BLOCK_SIZE,
+ keydeflen: TWOFISH_KEY_MIN_LEN,
+ keyminlen: TWOFISH_KEY_DEF_LEN,
+ keymaxlen: TWOFISH_KEY_MAX_LEN,
+ do_crypt: do_twofish,
+};
+
+struct encrypt_desc encrypt_desc_twofish_ssh =
+{
+ algo_type: IKE_ALG_ENCRYPT,
+ algo_id: OAKLEY_TWOFISH_CBC_SSH,
+ algo_next: NULL,
+ enc_ctxsize: sizeof(twofish_context),
+ enc_blocksize: TWOFISH_CBC_BLOCK_SIZE,
+ keydeflen: TWOFISH_KEY_MIN_LEN,
+ keyminlen: TWOFISH_KEY_DEF_LEN,
+ keymaxlen: TWOFISH_KEY_MAX_LEN,
+ do_crypt: do_twofish,
+};
+
+int ike_alg_twofish_init(void);
+
+int
+ike_alg_twofish_init(void)
+{
+ int ret = ike_alg_register_enc(&encrypt_desc_twofish);
+
+ if (ike_alg_register_enc(&encrypt_desc_twofish_ssh) < 0)
+ plog("ike_alg_twofish_init(): Experimental OAKLEY_TWOFISH_CBC_SSH activation failed");
+
+ return ret;
+}
+/*
+IKE_ALG_INIT_NAME: ike_alg_twofish_init
+*/