diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-08-29 00:37:10 +0000 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2007-08-29 00:37:10 +0000 |
commit | 55434a1ba5efd1cef9878e6b99e05e03813a9056 (patch) | |
tree | 35626373d268acc475690c686c8e1c27e2725e50 | |
parent | 0e5496858459139877ee01f093d44be3f3384611 (diff) | |
download | strongswan-55434a1ba5efd1cef9878e6b99e05e03813a9056.tar.bz2 strongswan-55434a1ba5efd1cef9878e6b99e05e03813a9056.tar.xz |
started implementation of libstrongswan code integrity check
-rw-r--r-- | src/charon/daemon.c | 32 | ||||
-rw-r--r-- | src/libstrongswan/Makefile.am | 39 | ||||
-rw-r--r-- | src/libstrongswan/fips/fips.c | 79 | ||||
-rw-r--r-- | src/libstrongswan/fips/fips.h | 46 | ||||
-rw-r--r-- | src/libstrongswan/fips/fips_canister_end.c | 164 | ||||
-rw-r--r-- | src/libstrongswan/fips/fips_canister_start.c | 165 | ||||
-rw-r--r-- | src/libstrongswan/fips/fips_signer.c | 61 | ||||
-rw-r--r-- | src/libstrongswan/library.h | 8 |
8 files changed, 584 insertions, 10 deletions
diff --git a/src/charon/daemon.c b/src/charon/daemon.c index a860c7b41..5193c9162 100644 --- a/src/charon/daemon.c +++ b/src/charon/daemon.c @@ -52,6 +52,11 @@ 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 */ diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 292abc0a4..f6e7f64d6 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -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 index 000000000..121b70867 --- /dev/null +++ b/src/libstrongswan/fips/fips.c @@ -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 index 000000000..bda1c82b6 --- /dev/null +++ b/src/libstrongswan/fips/fips.h @@ -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 index 000000000..a70a067eb --- /dev/null +++ b/src/libstrongswan/fips/fips_canister_end.c @@ -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 index 000000000..45789179b --- /dev/null +++ b/src/libstrongswan/fips/fips_canister_start.c @@ -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 index 000000000..1ce021898 --- /dev/null +++ b/src/libstrongswan/fips/fips_signer.c @@ -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); +} diff --git a/src/libstrongswan/library.h b/src/libstrongswan/library.h index 1439ab850..74899a8c1 100644 --- a/src/libstrongswan/library.h +++ b/src/libstrongswan/library.h @@ -90,6 +90,14 @@ */ /** + * @defgroup fips fips + * + * Code integrity check of libstrongswan + * + * @ingroup libstrongswan + */ + +/** * @defgroup utils utils * * Generic helper classes. |