started implementation of libstrongswan code integrity check

This commit is contained in:
Andreas Steffen 2007-08-29 00:37:10 +00:00
parent 0e54968584
commit 55434a1ba5
8 changed files with 584 additions and 10 deletions

View File

@ -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 */

View 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

View File

@ -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;
}

View File

@ -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_*/

View File

@ -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
}

View File

@ -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
}

View File

@ -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);
}

View File

@ -89,6 +89,14 @@
* @ingroup crypto
*/
/**
* @defgroup fips fips
*
* Code integrity check of libstrongswan
*
* @ingroup libstrongswan
*/
/**
* @defgroup utils utils
*