summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/padlock
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2009-02-28 22:02:31 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2009-02-28 22:02:31 +0000
commit19364e11c66714324bd3d5d0dc9212db397085cb (patch)
treefe7f5e55f0474dad1d0c29ba7c0a6f4546c99c3a /src/libstrongswan/plugins/padlock
parentc7f1b0530b85bc7654e68992f25ed8ced5d0a80d (diff)
downloadvyos-strongswan-19364e11c66714324bd3d5d0dc9212db397085cb.tar.gz
vyos-strongswan-19364e11c66714324bd3d5d0dc9212db397085cb.zip
[svn-upgrade] Integrating new upstream version, strongswan (4.2.12)
Diffstat (limited to 'src/libstrongswan/plugins/padlock')
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.am3
-rw-r--r--src/libstrongswan/plugins/padlock/Makefile.in24
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_plugin.c136
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_rng.c136
-rw-r--r--src/libstrongswan/plugins/padlock/padlock_rng.h49
5 files changed, 326 insertions, 22 deletions
diff --git a/src/libstrongswan/plugins/padlock/Makefile.am b/src/libstrongswan/plugins/padlock/Makefile.am
index e2e76e9e6..e7c3ba486 100644
--- a/src/libstrongswan/plugins/padlock/Makefile.am
+++ b/src/libstrongswan/plugins/padlock/Makefile.am
@@ -7,6 +7,7 @@ plugin_LTLIBRARIES = libstrongswan-padlock.la
libstrongswan_padlock_la_SOURCES = padlock_plugin.h padlock_plugin.c \
padlock_aes_crypter.c padlock_aes_crypter.h \
- padlock_sha1_hasher.c padlock_sha1_hasher.h
+ padlock_sha1_hasher.c padlock_sha1_hasher.h \
+ padlock_rng.c padlock_rng.h
libstrongswan_padlock_la_LDFLAGS = -module
diff --git a/src/libstrongswan/plugins/padlock/Makefile.in b/src/libstrongswan/plugins/padlock/Makefile.in
index 1b032e3d4..290b4836d 100644
--- a/src/libstrongswan/plugins/padlock/Makefile.in
+++ b/src/libstrongswan/plugins/padlock/Makefile.in
@@ -51,7 +51,7 @@ pluginLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(plugin_LTLIBRARIES)
libstrongswan_padlock_la_LIBADD =
am_libstrongswan_padlock_la_OBJECTS = padlock_plugin.lo \
- padlock_aes_crypter.lo padlock_sha1_hasher.lo
+ padlock_aes_crypter.lo padlock_sha1_hasher.lo padlock_rng.lo
libstrongswan_padlock_la_OBJECTS = \
$(am_libstrongswan_padlock_la_OBJECTS)
libstrongswan_padlock_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
@@ -86,22 +86,17 @@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
-ECHO = @ECHO@
+DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
-F77 = @F77@
-FFLAGS = @FFLAGS@
+FGREP = @FGREP@
GPERF = @GPERF@
GREP = @GREP@
INSTALL = @INSTALL@
@@ -111,6 +106,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
IPSEC_ROUTING_TABLE = @IPSEC_ROUTING_TABLE@
IPSEC_ROUTING_TABLE_PRIO = @IPSEC_ROUTING_TABLE_PRIO@
+LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
@@ -119,12 +115,16 @@ LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LINUX_HEADERS = @LINUX_HEADERS@
+LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
MKDIR_P = @MKDIR_P@
+NM = @NM@
NMEDIT = @NMEDIT@
OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
@@ -147,8 +147,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -187,6 +186,7 @@ libstrongswan_plugins = @libstrongswan_plugins@
linuxdir = @linuxdir@
localedir = @localedir@
localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
nm_CFLAGS = @nm_CFLAGS@
@@ -215,7 +215,8 @@ AM_CFLAGS = -rdynamic
plugin_LTLIBRARIES = libstrongswan-padlock.la
libstrongswan_padlock_la_SOURCES = padlock_plugin.h padlock_plugin.c \
padlock_aes_crypter.c padlock_aes_crypter.h \
- padlock_sha1_hasher.c padlock_sha1_hasher.h
+ padlock_sha1_hasher.c padlock_sha1_hasher.h \
+ padlock_rng.c padlock_rng.h
libstrongswan_padlock_la_LDFLAGS = -module
all: all-am
@@ -289,6 +290,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_aes_crypter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_plugin.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_rng.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/padlock_sha1_hasher.Plo@am__quote@
.c.o:
diff --git a/src/libstrongswan/plugins/padlock/padlock_plugin.c b/src/libstrongswan/plugins/padlock/padlock_plugin.c
index 822acc4a2..d0b55bcd9 100644
--- a/src/libstrongswan/plugins/padlock/padlock_plugin.c
+++ b/src/libstrongswan/plugins/padlock/padlock_plugin.c
@@ -16,12 +16,37 @@
*/
#include "padlock_plugin.h"
-
-#include <library.h>
#include "padlock_aes_crypter.h"
#include "padlock_sha1_hasher.h"
+#include "padlock_rng.h"
+
+#include <stdio.h>
+
+#include <library.h>
+#include <debug.h>
typedef struct private_padlock_plugin_t private_padlock_plugin_t;
+typedef enum padlock_feature_t padlock_feature_t;
+
+/**
+ * Feature flags of padlock, received via cpuid()
+ */
+enum padlock_feature_t {
+ PADLOCK_RESERVED_1 = (1<<0),
+ PADLOCK_RESERVED_2 = (1<<1),
+ PADLOCK_RNG_AVAILABLE = (1<<2),
+ PADLOCK_RNG_ENABLED = (1<<3),
+ PADLOCK_RESERVED_3 = (1<<4),
+ PADLOCK_RESERVED_4 = (1<<5),
+ PADLOCK_ACE_AVAILABLE = (1<<6),
+ PADLOCK_ACE_ENABLED = (1<<7),
+ PADLOCK_ACE2_AVAILABLE = (1<<8),
+ PADLOCK_ACE2_ENABLED = (1<<9),
+ PADLOCK_PHE_AVAILABLE = (1<<10),
+ PADLOCK_PHE_ENABLED = (1<<11),
+ PADLOCK_PMM_AVAILABLE = (1<<12),
+ PADLOCK_PMM_ENABLED = (1<<13),
+};
/**
* private data of aes_plugin
@@ -32,17 +57,76 @@ struct private_padlock_plugin_t {
* public functions
*/
padlock_plugin_t public;
+
+ /**
+ * features supported by Padlock
+ */
+ padlock_feature_t features;
};
/**
+ * Get cpuid for info, return eax, ebx, ecx and edx. -fPIC requires to save ebx.
+ */
+#define cpuid(op, a, b, c, d)\
+ asm (\
+ "pushl %%ebx \n\t"\
+ "cpuid \n\t"\
+ "movl %%ebx, %1 \n\t"\
+ "popl %%ebx \n\t"\
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "a" (op));
+
+/**
+ * Get features supported by Padlock
+ */
+static padlock_feature_t get_padlock_features()
+{
+ char vendor[3 * sizeof(int) + 1];
+ int a, b, c, d;
+
+ cpuid(0, a, b, c, d);
+ /* VendorID string is in b-d-c (yes, in this order) */
+ snprintf(vendor, sizeof(vendor), "%.4s%.4s%.4s", &b, &d, &c);
+
+ /* check if we have a VIA chip */
+ if (streq(vendor, "CentaurHauls"))
+ {
+ cpuid(0xC0000000, a, b, c, d);
+ /* check Centaur Extended Feature Flags */
+ if (a >= 0xC0000001)
+ {
+ cpuid(0xC0000001, a, b, c, d);
+ return d;
+ }
+ }
+ DBG1("Padlock not found, CPU is %s\n", vendor);
+ return 0;
+}
+
+/**
* Implementation of aes_plugin_t.destroy
*/
static void destroy(private_padlock_plugin_t *this)
{
- lib->crypto->remove_crypter(lib->crypto,
- (crypter_constructor_t)padlock_aes_crypter_create);
- lib->crypto->remove_hasher(lib->crypto,
- (hasher_constructor_t)padlock_sha1_hasher_create);
+ if (this->features & PADLOCK_RNG_ENABLED)
+ {
+ lib->crypto->remove_rng(lib->crypto,
+ (rng_constructor_t)padlock_rng_create);
+ lib->crypto->remove_rng(lib->crypto,
+ (rng_constructor_t)padlock_rng_create);
+ lib->crypto->remove_rng(lib->crypto,
+ (rng_constructor_t)padlock_rng_create);
+ }
+ if (this->features & PADLOCK_ACE2_ENABLED)
+ {
+ lib->crypto->remove_crypter(lib->crypto,
+ (crypter_constructor_t)padlock_aes_crypter_create);
+ }
+ if (this->features & PADLOCK_PHE_ENABLED)
+ {
+ lib->crypto->remove_hasher(lib->crypto,
+ (hasher_constructor_t)padlock_sha1_hasher_create);
+ }
free(this);
}
@@ -55,10 +139,42 @@ plugin_t *plugin_create()
this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
- lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
- (crypter_constructor_t)padlock_aes_crypter_create);
- lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
- (hasher_constructor_t)padlock_sha1_hasher_create);
+ this->features = get_padlock_features();
+ if (!this->features)
+ {
+ free(this);
+ return NULL;
+ }
+ DBG1("Padlock found, supports:%s%s%s%s%s, enabled:%s%s%s%s%s",
+ this->features & PADLOCK_RNG_AVAILABLE ? " RNG" : "",
+ this->features & PADLOCK_ACE_AVAILABLE ? " ACE" : "",
+ this->features & PADLOCK_ACE2_AVAILABLE ? " ACE2" : "",
+ this->features & PADLOCK_PHE_AVAILABLE ? " PHE" : "",
+ this->features & PADLOCK_PMM_AVAILABLE ? " PMM" : "",
+ this->features & PADLOCK_RNG_ENABLED ? " RNG" : "",
+ this->features & PADLOCK_ACE_ENABLED ? " ACE" : "",
+ this->features & PADLOCK_ACE2_ENABLED ? " ACE2" : "",
+ this->features & PADLOCK_PHE_ENABLED ? " PHE" : "",
+ this->features & PADLOCK_PMM_ENABLED ? " PMM" : "");
+ if (this->features & PADLOCK_RNG_ENABLED)
+ {
+ lib->crypto->add_rng(lib->crypto, RNG_REAL,
+ (rng_constructor_t)padlock_rng_create);
+ lib->crypto->add_rng(lib->crypto, RNG_STRONG,
+ (rng_constructor_t)padlock_rng_create);
+ lib->crypto->add_rng(lib->crypto, RNG_WEAK,
+ (rng_constructor_t)padlock_rng_create);
+ }
+ if (this->features & PADLOCK_ACE2_ENABLED)
+ {
+ lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC,
+ (crypter_constructor_t)padlock_aes_crypter_create);
+ }
+ if (this->features & PADLOCK_PHE_ENABLED)
+ {
+ lib->crypto->add_hasher(lib->crypto, HASH_SHA1,
+ (hasher_constructor_t)padlock_sha1_hasher_create);
+ }
return &this->public.plugin;
}
diff --git a/src/libstrongswan/plugins/padlock/padlock_rng.c b/src/libstrongswan/plugins/padlock/padlock_rng.c
new file mode 100644
index 000000000..50d9f0c43
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_rng.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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$
+ */
+
+#include "padlock_rng.h"
+
+typedef struct private_padlock_rng_t private_padlock_rng_t;
+typedef enum padlock_quality_factor_t padlock_quality_factor_t;
+
+/**
+ * Padlock RNG quality factors
+ */
+enum padlock_quality_factor_t {
+ /* Lowest quality: Reads 8 bytes */
+ PADLOCK_QF0 = 0x00,
+ /* Medium quality: Reads 4 bytes */
+ PADLOCK_QF1 = 0x01,
+ /* Better quality: Reads 2 bytes */
+ PADLOCK_QF2 = 0x10,
+ /* Highest quality: Reads 1 byte */
+ PADLOCK_QF3 = 0x11,
+};
+
+/**
+ * Private data of an padlock_rng_t object.
+ */
+struct private_padlock_rng_t {
+
+ /**
+ * Public padlock_rng_t interface.
+ */
+ padlock_rng_t public;
+
+ /**
+ * Padlock quality factor
+ */
+ padlock_quality_factor_t quality;
+};
+
+/**
+ * Get bytes from Padlock RNG. buf should have space for (len + 7)
+ */
+static void rng(char *buf, int len, int quality)
+{
+ while (len > 0)
+ {
+ int status;
+
+ /* run XSTORE until we have all bytes needed. We do not use REP, as
+ * this should not be performance critical and it's easier this way. */
+ asm volatile (
+ ".byte 0x0F,0xA7,0xC0 \n\t"
+ : "=D"(buf), "=a"(status)
+ : "d"(quality), "D"(buf));
+
+ /* bits[0..4] of status word contains the number of bytes read */
+ len -= status & 0x1F;
+ }
+}
+
+/**
+ * Implementation of padlock_rng_t.allocate_bytes.
+ */
+static void allocate_bytes(private_padlock_rng_t *this, size_t bytes,
+ chunk_t *chunk)
+{
+ chunk->len = bytes;
+ /* padlock requires some additional bytes */
+ chunk->ptr = malloc(bytes + 7);
+
+ rng(chunk->ptr, chunk->len, this->quality);
+}
+
+/**
+ * Implementation of padlock_rng_t.get_bytes.
+ */
+static void get_bytes(private_padlock_rng_t *this, size_t bytes,
+ u_int8_t *buffer)
+{
+ chunk_t chunk;
+
+ /* Padlock needs a larger buffer than "bytes", we need a new buffer */
+ allocate_bytes(this, bytes, &chunk);
+ memcpy(buffer, chunk.ptr, bytes);
+ chunk_clear(&chunk);
+}
+
+/**
+ * Implementation of padlock_rng_t.destroy.
+ */
+static void destroy(private_padlock_rng_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+padlock_rng_t *padlock_rng_create(rng_quality_t quality)
+{
+ private_padlock_rng_t *this = malloc_thing(private_padlock_rng_t);
+
+ this->public.rng.get_bytes = (void (*) (rng_t *, size_t, u_int8_t*)) get_bytes;
+ this->public.rng.allocate_bytes = (void (*) (rng_t *, size_t, chunk_t*)) allocate_bytes;
+ this->public.rng.destroy = (void (*) (rng_t *))destroy;
+
+ /* map RNG quality to Padlock quality factor */
+ switch (quality)
+ {
+ case RNG_WEAK:
+ this->quality = PADLOCK_QF0;
+ break;
+ case RNG_STRONG:
+ this->quality = PADLOCK_QF1;
+ break;
+ case RNG_REAL:
+ this->quality = PADLOCK_QF3;
+ break;
+ }
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/plugins/padlock/padlock_rng.h b/src/libstrongswan/plugins/padlock/padlock_rng.h
new file mode 100644
index 000000000..a76ecd296
--- /dev/null
+++ b/src/libstrongswan/plugins/padlock/padlock_rng.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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$
+ */
+
+/**
+ * @defgroup padlock_rng padlock_rng
+ * @{ @ingroup padlock
+ */
+
+#ifndef PADLOCK_RNG_H_
+#define PADLOCK_RNG_H_
+
+#include <crypto/rngs/rng.h>
+
+typedef struct padlock_rng_t padlock_rng_t;
+
+/**
+ * Hardware-RNG based on via Padlock.
+ */
+struct padlock_rng_t {
+
+ /**
+ * Implements rng_t interface.
+ */
+ rng_t rng;
+};
+
+/**
+ * Create a padlock_rng instance.
+ *
+ * @param quality required quality of randomness
+ * @return created random_rng_t
+ */
+padlock_rng_t *padlock_rng_create(rng_quality_t quality);
+
+#endif /* PADLOCK_RNG_ @}*/