started implementation of libstrongswan code integrity check
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 29 Aug 2007 00:37:10 +0000 (00:37 -0000)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 29 Aug 2007 00:37:10 +0000 (00:37 -0000)
src/charon/daemon.c
src/libstrongswan/Makefile.am
src/libstrongswan/fips/fips.c [new file with mode: 0644]
src/libstrongswan/fips/fips.h [new file with mode: 0644]
src/libstrongswan/fips/fips_canister_end.c [new file with mode: 0644]
src/libstrongswan/fips/fips_canister_start.c [new file with mode: 0644]
src/libstrongswan/fips/fips_signer.c [new file with mode: 0644]
src/libstrongswan/library.h

index a860c7b..5193c91 100644 (file)
 extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
 #endif /* NO_CAPSET_DEFINED */
 
+#ifdef INTEGRITY_TEST
+#include <fips/fips.h>
+#include <fips_signature.h>
+#endif /* INTEGRITY_TEST */
+
 typedef struct private_daemon_t private_daemon_t;
 
 /**
@@ -254,9 +259,9 @@ static void drop_capabilities(private_daemon_t *this, bool full)
 }
 
 /**
- * Initialize the daemon, optional with a strict crl policy
+ * Initialize the daemon
  */
-static void initialize(private_daemon_t *this, bool syslog, level_t levels[])
+static bool initialize(private_daemon_t *this, bool syslog, level_t levels[])
 {
        signal_t signal;
        
@@ -288,6 +293,19 @@ static void initialize(private_daemon_t *this, bool syslog, level_t levels[])
        }
        
        DBG1(DBG_DMN, "starting charon (strongSwan Version %s)", VERSION);
+
+#ifdef INTEGRITY_TEST
+       DBG1(DBG_DMN, "integrity check of libstrongswan code");
+       if (fips_verify_hmac_signature(hmac_signature, hmac_key) != SUCCESS)
+       {
+               DBG1(DBG_DMN, "  integrity check failed");
+               return FALSE;
+       }
+       else
+       {
+               DBG1(DBG_DMN, "  integrity check succeeded");
+       }
+#endif /* INTEGRITY_TEST */
        
        this->public.ike_sa_manager = ike_sa_manager_create();
        this->public.processor = processor_create();
@@ -308,7 +326,7 @@ static void initialize(private_daemon_t *this, bool syslog, level_t levels[])
        this->public.socket = socket_create(IKEV2_UDP_PORT, IKEV2_NATT_PORT);
        this->public.sender = sender_create();
        this->public.receiver = receiver_create();
-       
+       return TRUE;
 }
 
 /**
@@ -508,7 +526,13 @@ int main(int argc, char *argv[])
        }
        
        /* initialize daemon */
-       initialize(private_charon, use_syslog, levels);
+       if (!initialize(private_charon, use_syslog, levels))
+       {
+               DBG1(DBG_DMN, "initialization failed - aborting charon");
+               destroy(private_charon);
+               exit(-1);
+       }
+
        /* initialize fetcher_t class */
        fetcher_initialize();
        /* load pluggable EAP modules */
index 292abc0..f6e7f64 100644 (file)
@@ -1,6 +1,14 @@
 lib_LTLIBRARIES = libstrongswan.la
 
-libstrongswan_la_SOURCES = \
+if USE_INTEGRITY_TEST
+  libstrongswan_la_SOURCES = \
+  fips/fips_canister_start.c \
+  fips/fips.c fips/fips.h
+else
+  libstrongswan_la_SOURCES =
+endif
+
+libstrongswan_la_SOURCES += \
 credential_store.h \
 library.c library.h \
 chunk.c chunk.h \
@@ -16,8 +24,8 @@ crypto/ca.c crypto/ca.h \
 crypto/certinfo.c crypto/certinfo.h \
 crypto/crl.c crypto/crl.h \
 crypto/crypters/crypter.c crypto/crypters/crypter.h \
-crypto/crypters/aes_cbc_crypter.c  crypto/crypters/aes_cbc_crypter.h\
-crypto/crypters/des_crypter.c  crypto/crypters/des_crypter.h\
+crypto/crypters/aes_cbc_crypter.c crypto/crypters/aes_cbc_crypter.h \
+crypto/crypters/des_crypter.c crypto/crypters/des_crypter.h \
 crypto/diffie_hellman.c crypto/diffie_hellman.h \
 crypto/hashers/hasher.h crypto/hashers/hasher.c \
 crypto/hashers/sha1_hasher.c crypto/hashers/sha1_hasher.h \
@@ -43,12 +51,14 @@ utils/lexparser.c utils/lexparser.h \
 utils/linked_list.c utils/linked_list.h \
 utils/randomizer.c utils/randomizer.h
 
+if USE_INTEGRITY_TEST
+  libstrongswan_la_SOURCES += \
+  fips/fips_canister_end.c
+endif
+
 libstrongswan_la_LIBADD = -lgmp -lpthread
 
 INCLUDES = -I$(top_srcdir)/src/libstrongswan
-EXTRA_DIST = asn1/oid.txt asn1/oid.pl
-BUILT_SOURCES = asn1/oid.c asn1/oid.h
-MAINTAINERCLEANFILES = asn1/oid.c asn1/oid.h
 
 if USE_LEAK_DETECTIVE
   libstrongswan_la_LIBADD += -ldl
@@ -63,8 +73,25 @@ if USE_LIBLDAP
   libstrongswan_la_LIBADD += -lldap -llber
 endif
 
+EXTRA_DIST = asn1/oid.txt asn1/oid.pl
+BUILT_SOURCES = asn1/oid.c asn1/oid.h
+MAINTAINERCLEANFILES = asn1/oid.c asn1/oid.h
+
 asn1/oid.c :   asn1/oid.txt asn1/oid.pl
                cd asn1 && $(PERL) oid.pl
 
 asn1/oid.h :   asn1/oid.txt asn1/oid.pl
                cd asn1 && $(PERL) oid.pl
+
+# build fips_signer which in turn builds fips_signature.h
+#########################################################
+noinst_PROGRAMS = fips_signer
+fips_signer_SOURCES = fips/fips_signer.c
+fips_signer_LDADD = libstrongswan.la
+
+BUILT_SOURCES += fips_signature.h
+CLEANFILES = fips_signature.h fips_signer
+
+fips_signature.h : fips_signer
+                  ./fips_signer
+
diff --git a/src/libstrongswan/fips/fips.c b/src/libstrongswan/fips/fips.c
new file mode 100644 (file)
index 0000000..121b708
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * @file fips.c
+ * 
+ * @brief Implementation of the libstrongswan integrity test.
+ * 
+ */
+
+/*
+ * Copyright (C) 2007 Bruno Krieg, Daniel Wydler
+ * 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.
+ */
+
+#include "fips.h"
+#include <debug.h>
+#include <crypto/signers/hmac_signer.h>
+
+extern const unsigned char FIPS_rodata_start[];
+extern const unsigned char FIPS_rodata_end[];
+extern const void *FIPS_text_start();
+extern const void *FIPS_text_end();
+
+/**
+ * Described in header
+ */
+char* fips_compute_hmac_signature(const char *key)
+{
+       chunk_t hmac_key = { key, strlen(key) };
+
+    hmac_signer_t *signer = hmac_signer_create(HASH_SHA1, HASH_SIZE_SHA1);
+
+    DBG1("  TEXT:   %p + %6d = %p",
+                FIPS_text_start(),
+               (int)( (size_t)FIPS_text_end() - (size_t)FIPS_text_start() ),
+               FIPS_text_end());
+    DBG1("  RODATA: %p + %6d = %p",
+               FIPS_rodata_start,
+        (int)( (size_t)FIPS_rodata_end - (size_t)FIPS_rodata_start ),
+        FIPS_rodata_end);
+
+       if (signer == NULL)
+       {
+           DBG1("  fips hmac signer could not be created");
+               return NULL;
+       }
+       signer->signer_interface.set_key((signer_t *)signer, hmac_key);
+       signer->signer_interface.destroy((signer_t *)signer);
+       return strdup("01020304050607080901011121314151617181920");
+}
+
+/**
+ * Described in header
+ */
+status_t fips_verify_hmac_signature(const char *signature,
+                                                                       const char *key)
+{
+       status_t status;
+       char *current_signature = fips_compute_hmac_signature(key);
+
+       if (current_signature == NULL)
+       {
+               status = FAILED;
+       }
+       else
+       {
+               status = streq(signature, current_signature)? SUCCESS:VERIFY_ERROR;
+               free(current_signature);
+       }
+       return status;
+}
diff --git a/src/libstrongswan/fips/fips.h b/src/libstrongswan/fips/fips.h
new file mode 100644 (file)
index 0000000..bda1c82
--- /dev/null
@@ -0,0 +1,46 @@
+/**
+ * @file fips.h
+ * 
+ * @brief Interface of the libstrongswan integrity test
+ *
+ * @ingroup fips
+ */
+
+/*
+ * Copyright (C) 2007 Bruno Krieg, Daniel Wydler
+ * 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.
+ */
+
+#ifndef FIPS_H_
+#define FIPS_H_
+
+#include <library.h>
+
+/**
+ * @brief compute SHA-1 HMAC signature over RODATA and TEXT sections of libstrongswan
+ *
+ * @param  key         key used for SHA-1 HMAC signature in string format
+ * @return             SHA-1 HMAC signature in HEX format
+ */
+char* fips_compute_hmac_signature(const char *key);
+
+/**
+ * @brief verify HMAC signature over RODATA and TEXT sections of libstrongswan
+ *
+ * @param  signature   signature value from fips_hmac.h in HEX format
+ * @param  key         key used for SHA-1 HMAC signature in string format
+ * @return             SUCCESS if signatures agree
+ */
+status_t fips_verify_hmac_signature(const char *signature, const char *key);
+
+#endif /*FIPS_H_*/
diff --git a/src/libstrongswan/fips/fips_canister_end.c b/src/libstrongswan/fips/fips_canister_end.c
new file mode 100644 (file)
index 0000000..a70a067
--- /dev/null
@@ -0,0 +1,164 @@
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
+ * and usage in source and binary forms are granted according to the
+ * OpenSSL license.
+ */
+
+#include <stdio.h>
+#if defined(__DECC)
+# include <c_asm.h>
+# pragma __nostandard
+#endif
+
+#if !defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
+# if   (defined(__sun) && (defined(__sparc) || defined(__sparcv9)))    || \
+       (defined(__sgi) && (defined(__mips) || defined(mips)))          || \
+       (defined(__osf__) && defined(__alpha))                          || \
+       (defined(__linux) && (defined(__arm) || defined(__arm__)))      || \
+       (defined(__i386) || defined(__i386__))                          || \
+       (defined(__x86_64) || defined(__x86_64__))                      || \
+       (defined(vax) || defined(__vax__))
+#  define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION
+# endif
+#endif
+
+#define FIPS_ref_point FIPS_text_end
+/* Some compilers put string literals into a separate segment. As we
+ * are mostly interested to hash AES tables in .rodata, we declare
+ * reference points accordingly. In case you wonder, the values are
+ * big-endian encoded variable names, just to prevent these arrays
+ * from being merged by linker. */
+const unsigned int FIPS_rodata_end[]=
+       { 0x46495053, 0x5f726f64, 0x6174615f, 0x656e645b };
+
+
+/*
+ * I declare reference function as static in order to avoid certain
+ * pitfalls in -dynamic linker behaviour...
+ */
+static void *instruction_pointer(void)
+{ void *ret=NULL;
+/* These are ABI-neutral CPU-specific snippets. ABI-neutrality means
+ * that they are designed to work under any OS running on particular
+ * CPU, which is why you don't find any #ifdef THIS_OR_THAT_OS in
+ * this function. */
+#if    defined(INSTRUCTION_POINTER_IMPLEMENTED)
+    INSTRUCTION_POINTER_IMPLEMENTED(ret);
+#elif  defined(__GNUC__) && __GNUC__>=2
+# if   defined(__alpha) || defined(__alpha__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "br     %0,1f\n1:" : "=r"(ret) );
+# elif defined(__i386) || defined(__i386__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "call 1f\n1:    popl %0" : "=r"(ret) );
+    ret = (void *)((size_t)ret&~3UL); /* align for better performance */
+# elif defined(__ia64) || defined(__ia64__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "mov    %0=ip" : "=r"(ret) );
+# elif defined(__hppa) || defined(__hppa__) || defined(__pa_risc)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "blr    %%r0,%0\n\tnop" : "=r"(ret) );
+    ret = (void *)((size_t)ret&~3UL); /* mask privilege level */
+# elif defined(__mips) || defined(__mips__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    void *scratch;
+    __asm __volatile ( "move   %1,$31\n\t"     /* save ra */
+                       "bal    .+8; nop\n\t"
+                       "move   %0,$31\n\t"
+                       "move   $31,%1"         /* restore ra */
+                       : "=r"(ret),"=r"(scratch) );
+# elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \
+       defined(__POWERPC__) || defined(_POWER) || defined(__PPC__) || \
+       defined(__PPC64__) || defined(__powerpc64__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    void *scratch;
+    __asm __volatile ( "mfspr  %1,8\n\t"       /* save lr */
+                       "bl     .+4\n\t"
+                       "mfspr  %0,8\n\t"       /* mflr ret */
+                       "mtspr  8,%1"           /* restore lr */
+                       : "=r"(ret),"=r"(scratch) );
+# elif defined(__sparc) || defined(__sparc__) || defined(__sparcv9)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    void *scratch;
+    __asm __volatile ( "mov    %%o7,%1\n\t"
+                       "call   .+8; nop\n\t"
+                       "mov    %%o7,%0\n\t"
+                       "mov    %1,%%o7"
+                       : "=r"(ret),"=r"(scratch) );
+# elif defined(__x86_64) || defined(__x86_64__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "leaq   0(%%rip),%0" : "=r"(ret) );
+    ret = (void *)((size_t)ret&~3UL); /* align for better performance */
+# endif
+#elif  defined(__DECC) && defined(__alpha)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    ret = (void *)(size_t)asm("br %v0,1f\n1:");
+#elif   defined(_MSC_VER) && defined(_M_IX86)
+#   undef INSTRUCTION_POINTER_IMPLEMENTED
+    void *scratch;
+    _asm {
+            call    self
+    self:   pop     eax
+            mov     scratch,eax
+         }
+    ret = (void *)((size_t)scratch&~3UL);
+#endif
+  return ret;
+}
+
+/*
+ * This function returns pointer to an instruction in the vicinity of
+ * its entry point, but not outside this object module. This guarantees
+ * that sequestered code is covered...
+ */
+void *FIPS_ref_point()
+{
+#if    defined(INSTRUCTION_POINTER_IMPLEMENTED)
+    return instruction_pointer();
+/* Below we essentially cover vendor compilers which do not support
+ * inline assembler... */
+#elif  defined(_AIX)
+    struct { void *ip,*gp,*env; } *p = (void *)instruction_pointer;
+    return p->ip;
+#elif  defined(_HPUX_SOURCE)
+# if   defined(__hppa) || defined(__hppa__)
+    struct { void *i[4]; } *p = (void *)FIPS_ref_point;
+
+    if (sizeof(p) == 8)        /* 64-bit */
+       return p->i[2];
+    else if ((size_t)p & 2)
+    {  p = (void *)((size_t)p&~3UL);
+       return p->i[0];
+    }
+    else
+       return (void *)p;
+# elif defined(__ia64) || defined(__ia64__)
+    struct { unsigned long long ip,gp; } *p=(void *)instruction_pointer;
+    return (void *)(size_t)p->ip;
+# endif
+#elif  (defined(__VMS) || defined(VMS)) && !(defined(vax) || defined(__vax__))
+    /* applies to both alpha and ia64 */
+    struct { unsigned __int64 opaque,ip; } *p=(void *)instruction_pointer;
+    return (void *)(size_t)p->ip;
+#elif  defined(__VOS__)
+    /* applies to both pa-risc and ia32 */
+    struct { void *dp,*ip,*gp; } *p = (void *)instruction_pointer;
+    return p->ip;
+#elif  defined(_WIN32)
+# if   defined(_WIN64) && defined(_M_IA64)
+    struct { void *ip,*gp; } *p = (void *)FIPS_ref_point;
+    return p->ip;
+# else
+    return (void *)FIPS_ref_point;
+# endif
+/*
+ * In case you wonder why there is no #ifdef __linux. All Linux targets
+ * are GCC-based and therefore are covered by instruction_pointer above
+ * [well, some are covered by by the one below]...
+ */ 
+#elif  defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
+    return (void *)instruction_pointer;
+#else
+    return NULL;
+#endif
+}
diff --git a/src/libstrongswan/fips/fips_canister_start.c b/src/libstrongswan/fips/fips_canister_start.c
new file mode 100644 (file)
index 0000000..4578917
--- /dev/null
@@ -0,0 +1,165 @@
+/* ====================================================================
+ * Copyright (c) 2005 The OpenSSL Project. Rights for redistribution
+ * and usage in source and binary forms are granted according to the
+ * OpenSSL license.
+ */
+
+#include <stdio.h>
+#if defined(__DECC)
+# include <c_asm.h>
+# pragma __nostandard
+#endif
+
+#if !defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
+# if   (defined(__sun) && (defined(__sparc) || defined(__sparcv9)))    || \
+       (defined(__sgi) && (defined(__mips) || defined(mips)))          || \
+       (defined(__osf__) && defined(__alpha))                          || \
+       (defined(__linux) && (defined(__arm) || defined(__arm__)))      || \
+       (defined(__i386) || defined(__i386__))                          || \
+       (defined(__x86_64) || defined(__x86_64__))                      || \
+       (defined(vax) || defined(__vax__))
+#  define POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION
+# endif
+#endif
+
+
+#define FIPS_ref_point FIPS_text_start
+/* Some compilers put string literals into a separate segment. As we
+ * are mostly interested to hash AES tables in .rodata, we declare
+ * reference points accordingly. In case you wonder, the values are
+ * big-endian encoded variable names, just to prevent these arrays
+ * from being merged by linker. */
+const unsigned int FIPS_rodata_start[]=
+       { 0x46495053, 0x5f726f64, 0x6174615f, 0x73746172 };
+
+
+/*
+ * I declare reference function as static in order to avoid certain
+ * pitfalls in -dynamic linker behaviour...
+ */
+static void *instruction_pointer(void)
+{ void *ret=NULL;
+/* These are ABI-neutral CPU-specific snippets. ABI-neutrality means
+ * that they are designed to work under any OS running on particular
+ * CPU, which is why you don't find any #ifdef THIS_OR_THAT_OS in
+ * this function. */
+#if    defined(INSTRUCTION_POINTER_IMPLEMENTED)
+    INSTRUCTION_POINTER_IMPLEMENTED(ret);
+#elif  defined(__GNUC__) && __GNUC__>=2
+# if   defined(__alpha) || defined(__alpha__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "br     %0,1f\n1:" : "=r"(ret) );
+# elif defined(__i386) || defined(__i386__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "call 1f\n1:    popl %0" : "=r"(ret) );
+    ret = (void *)((size_t)ret&~3UL); /* align for better performance */
+# elif defined(__ia64) || defined(__ia64__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "mov    %0=ip" : "=r"(ret) );
+# elif defined(__hppa) || defined(__hppa__) || defined(__pa_risc)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "blr    %%r0,%0\n\tnop" : "=r"(ret) );
+    ret = (void *)((size_t)ret&~3UL); /* mask privilege level */
+# elif defined(__mips) || defined(__mips__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    void *scratch;
+    __asm __volatile ( "move   %1,$31\n\t"     /* save ra */
+                       "bal    .+8; nop\n\t"
+                       "move   %0,$31\n\t"
+                       "move   $31,%1"         /* restore ra */
+                       : "=r"(ret),"=r"(scratch) );
+# elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \
+       defined(__POWERPC__) || defined(_POWER) || defined(__PPC__) || \
+       defined(__PPC64__) || defined(__powerpc64__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    void *scratch;
+    __asm __volatile ( "mfspr  %1,8\n\t"       /* save lr */
+                       "bl     .+4\n\t"
+                       "mfspr  %0,8\n\t"       /* mflr ret */
+                       "mtspr  8,%1"           /* restore lr */
+                       : "=r"(ret),"=r"(scratch) );
+# elif defined(__sparc) || defined(__sparc__) || defined(__sparcv9)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    void *scratch;
+    __asm __volatile ( "mov    %%o7,%1\n\t"
+                       "call   .+8; nop\n\t"
+                       "mov    %%o7,%0\n\t"
+                       "mov    %1,%%o7"
+                       : "=r"(ret),"=r"(scratch) );
+# elif defined(__x86_64) || defined(__x86_64__)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    __asm __volatile ( "leaq   0(%%rip),%0" : "=r"(ret) );
+    ret = (void *)((size_t)ret&~3UL); /* align for better performance */
+# endif
+#elif  defined(__DECC) && defined(__alpha)
+#   define INSTRUCTION_POINTER_IMPLEMENTED
+    ret = (void *)(size_t)asm("br %v0,1f\n1:");
+#elif   defined(_MSC_VER) && defined(_M_IX86)
+#   undef INSTRUCTION_POINTER_IMPLEMENTED
+    void *scratch;
+    _asm {
+            call    self
+    self:   pop     eax
+            mov     scratch,eax
+         }
+    ret = (void *)((size_t)scratch&~3UL);
+#endif
+  return ret;
+}
+
+/*
+ * This function returns pointer to an instruction in the vicinity of
+ * its entry point, but not outside this object module. This guarantees
+ * that sequestered code is covered...
+ */
+void *FIPS_ref_point()
+{
+#if    defined(INSTRUCTION_POINTER_IMPLEMENTED)
+    return instruction_pointer();
+/* Below we essentially cover vendor compilers which do not support
+ * inline assembler... */
+#elif  defined(_AIX)
+    struct { void *ip,*gp,*env; } *p = (void *)instruction_pointer;
+    return p->ip;
+#elif  defined(_HPUX_SOURCE)
+# if   defined(__hppa) || defined(__hppa__)
+    struct { void *i[4]; } *p = (void *)FIPS_ref_point;
+
+    if (sizeof(p) == 8)        /* 64-bit */
+       return p->i[2];
+    else if ((size_t)p & 2)
+    {  p = (void *)((size_t)p&~3UL);
+       return p->i[0];
+    }
+    else
+       return (void *)p;
+# elif defined(__ia64) || defined(__ia64__)
+    struct { unsigned long long ip,gp; } *p=(void *)instruction_pointer;
+    return (void *)(size_t)p->ip;
+# endif
+#elif  (defined(__VMS) || defined(VMS)) && !(defined(vax) || defined(__vax__))
+    /* applies to both alpha and ia64 */
+    struct { unsigned __int64 opaque,ip; } *p=(void *)instruction_pointer;
+    return (void *)(size_t)p->ip;
+#elif  defined(__VOS__)
+    /* applies to both pa-risc and ia32 */
+    struct { void *dp,*ip,*gp; } *p = (void *)instruction_pointer;
+    return p->ip;
+#elif  defined(_WIN32)
+# if   defined(_WIN64) && defined(_M_IA64)
+    struct { void *ip,*gp; } *p = (void *)FIPS_ref_point;
+    return p->ip;
+# else
+    return (void *)FIPS_ref_point;
+# endif
+/*
+ * In case you wonder why there is no #ifdef __linux. All Linux targets
+ * are GCC-based and therefore are covered by instruction_pointer above
+ * [well, some are covered by by the one below]...
+ */ 
+#elif  defined(POINTER_TO_FUNCTION_IS_POINTER_TO_1ST_INSTRUCTION)
+    return (void *)instruction_pointer;
+#else
+    return NULL;
+#endif
+}
diff --git a/src/libstrongswan/fips/fips_signer.c b/src/libstrongswan/fips/fips_signer.c
new file mode 100644 (file)
index 0000000..1ce0218
--- /dev/null
@@ -0,0 +1,61 @@
+/**
+ * @file fips_signer.c
+ * 
+ * @brief Computes a HMAC signature and stores it in fips_signature.h.
+ * 
+ */
+
+/*
+ * Copyright (C) 2007 Bruno Krieg, Daniel Wydler
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * 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 <stdio.h>
+#include "fips.h"
+
+int main(int argc, char* argv[])
+{
+       FILE *f;
+       char *hmac_key = "strongSwan Version " VERSION;
+       char *hmac_signature = fips_compute_hmac_signature(hmac_key);
+
+       if (hmac_signature == NULL)
+       {
+               exit(1);
+       }
+
+       /**
+     * write computed HMAC signature to fips_signature.h
+        */
+       f = fopen("fips_signature.h", "wt");
+
+       if (f == NULL)
+       {
+               exit(1);
+       }
+       fprintf(f, "/* HMAC signature computed over TEXT and RODATA of libstrongswan\n");
+       fprintf(f, " *\n");
+       fprintf(f, " * This file has been automatically generated by fips_signer\n");
+       fprintf(f, " * Do not edit manually!\n");
+       fprintf(f, " */\n");
+       fprintf(f, "\n");
+       fprintf(f, "#ifndef FIPS_SIGNATURE_H_\n");
+       fprintf(f, "#define FIPS_SIGNATURE_H_\n");
+       fprintf(f, "\n");
+       fprintf(f, "const char *hmac_key =\"%s\";\n", hmac_key);
+       fprintf(f, "const char *hmac_signature =\"%s\";\n", hmac_signature);
+       fprintf(f, "\n");
+       fprintf(f, "#endif /* FIPS_SIGNATURE_H_ */\n");
+       fclose(f);
+       exit(0);
+}
index 1439ab8..74899a8 100644 (file)
  */
 
 /**
+ * @defgroup fips fips
+ *
+ * Code integrity check of libstrongswan
+ *
+ * @ingroup libstrongswan
+ */
+
+/**
  * @defgroup utils utils
  *
  * Generic helper classes.