diff --git a/configure.in b/configure.in index 81249920f..89a32febb 100644 --- a/configure.in +++ b/configure.in @@ -208,7 +208,6 @@ fi if test x$eap_aka = xtrue; then fips_prf=true; - sha1=true; simaka=true; fi @@ -218,7 +217,9 @@ if test x$eap_sim = xtrue; then fi if test x$fips_prf = xtrue; then - sha1=true; + if test x$openssl = xfalse; then + sha1=true; + fi fi if test x$smp = xtrue; then @@ -676,9 +677,6 @@ if test x$md5 = xtrue; then libstrongswan_plugins=${libstrongswan_plugins}" md5" pluto_plugins=${pluto_plugins}" md5" fi -if test x$fips_prf = xtrue; then - libstrongswan_plugins=${libstrongswan_plugins}" fips-prf" -fi if test x$random = xtrue; then libstrongswan_plugins=${libstrongswan_plugins}" random" pluto_plugins=${pluto_plugins}" random" @@ -730,6 +728,9 @@ if test x$gcrypt = xtrue; then libstrongswan_plugins=${libstrongswan_plugins}" gcrypt" pluto_plugins=${pluto_plugins}" gcrypt" fi +if test x$fips_prf = xtrue; then + libstrongswan_plugins=${libstrongswan_plugins}" fips-prf" +fi if test x$xcbc = xtrue; then libstrongswan_plugins=${libstrongswan_plugins}" xcbc" fi diff --git a/src/libstrongswan/Makefile.am b/src/libstrongswan/Makefile.am index 351e79913..2b80e619b 100644 --- a/src/libstrongswan/Makefile.am +++ b/src/libstrongswan/Makefile.am @@ -171,13 +171,6 @@ if MONOLITHIC endif endif -if USE_FIPS_PRF - SUBDIRS += plugins/fips_prf -if MONOLITHIC - libstrongswan_la_LIBADD += plugins/fips_prf/libstrongswan-fips-prf.la -endif -endif - if USE_GMP SUBDIRS += plugins/gmp if MONOLITHIC @@ -304,6 +297,13 @@ if MONOLITHIC endif endif +if USE_FIPS_PRF + SUBDIRS += plugins/fips_prf +if MONOLITHIC + libstrongswan_la_LIBADD += plugins/fips_prf/libstrongswan-fips-prf.la +endif +endif + if USE_AGENT SUBDIRS += plugins/agent if MONOLITHIC diff --git a/src/libstrongswan/plugins/openssl/Makefile.am b/src/libstrongswan/plugins/openssl/Makefile.am index eee1ca5c0..a50799798 100644 --- a/src/libstrongswan/plugins/openssl/Makefile.am +++ b/src/libstrongswan/plugins/openssl/Makefile.am @@ -14,6 +14,7 @@ libstrongswan_openssl_la_SOURCES = \ openssl_util.c openssl_util.h \ openssl_crypter.c openssl_crypter.h \ openssl_hasher.c openssl_hasher.h \ + openssl_sha1_prf.c openssl_sha1_prf.h \ openssl_diffie_hellman.c openssl_diffie_hellman.h \ openssl_rsa_private_key.c openssl_rsa_private_key.h \ openssl_rsa_public_key.c openssl_rsa_public_key.h \ diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c index 941b643cf..165f83ccb 100644 --- a/src/libstrongswan/plugins/openssl/openssl_plugin.c +++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c @@ -27,6 +27,7 @@ #include "openssl_util.h" #include "openssl_crypter.h" #include "openssl_hasher.h" +#include "openssl_sha1_prf.h" #include "openssl_diffie_hellman.h" #include "openssl_ec_diffie_hellman.h" #include "openssl_rsa_private_key.h" @@ -170,6 +171,8 @@ static void destroy(private_openssl_plugin_t *this) (crypter_constructor_t)openssl_crypter_create); lib->crypto->remove_hasher(lib->crypto, (hasher_constructor_t)openssl_hasher_create); + lib->crypto->remove_prf(lib->crypto, + (prf_constructor_t)openssl_sha1_prf_create); lib->crypto->remove_dh(lib->crypto, (dh_constructor_t)openssl_diffie_hellman_create); lib->crypto->remove_dh(lib->crypto, @@ -256,6 +259,10 @@ plugin_t *openssl_plugin_create() lib->crypto->add_hasher(lib->crypto, HASH_SHA512, (hasher_constructor_t)openssl_hasher_create); + /* prf */ + lib->crypto->add_prf(lib->crypto, PRF_KEYED_SHA1, + (prf_constructor_t)openssl_sha1_prf_create); + /* (ec) diffie hellman */ lib->crypto->add_dh(lib->crypto, MODP_2048_BIT, (dh_constructor_t)openssl_diffie_hellman_create); diff --git a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c new file mode 100644 index 000000000..b65388010 --- /dev/null +++ b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2010 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 . + * + * 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 "openssl_sha1_prf.h" + +#include + +typedef struct private_openssl_sha1_prf_t private_openssl_sha1_prf_t; + +/** + * Private data of an openssl_sha1_prf_t object. + */ +struct private_openssl_sha1_prf_t { + + /** + * Public openssl_sha1_prf_t interface. + */ + openssl_sha1_prf_t public; + + /** + * SHA1 context + */ + SHA_CTX ctx; +}; + +METHOD(prf_t, get_bytes, void, + private_openssl_sha1_prf_t *this, chunk_t seed, u_int8_t *bytes) +{ + SHA1_Update(&this->ctx, seed.ptr, seed.len); + + if (bytes) + { + u_int32_t *hash = (u_int32_t*)bytes; + + hash[0] = htonl(this->ctx.h0); + hash[1] = htonl(this->ctx.h1); + hash[2] = htonl(this->ctx.h2); + hash[3] = htonl(this->ctx.h3); + hash[4] = htonl(this->ctx.h4); + } +} + +METHOD(prf_t, get_block_size, size_t, + private_openssl_sha1_prf_t *this) +{ + return HASH_SIZE_SHA1; +} + +METHOD(prf_t, allocate_bytes, void, + private_openssl_sha1_prf_t *this, chunk_t seed, chunk_t *chunk) +{ + if (chunk) + { + *chunk = chunk_alloc(HASH_SIZE_SHA1); + get_bytes(this, seed, chunk->ptr); + } + else + { + get_bytes(this, seed, NULL); + } +} + +METHOD(prf_t, get_key_size, size_t, + private_openssl_sha1_prf_t *this) +{ + return HASH_SIZE_SHA1; +} + +METHOD(prf_t, set_key, void, + private_openssl_sha1_prf_t *this, chunk_t key) +{ + SHA1_Init(&this->ctx); + + if (key.len >= 4) + { + this->ctx.h0 ^= untoh32(key.ptr); + } + if (key.len >= 8) + { + this->ctx.h1 ^= untoh32(key.ptr + 4); + } + if (key.len >= 12) + { + this->ctx.h2 ^= untoh32(key.ptr + 8); + } + if (key.len >= 16) + { + this->ctx.h3 ^= untoh32(key.ptr + 12); + } + if (key.len >= 20) + { + this->ctx.h4 ^= untoh32(key.ptr + 16); + } +} + +METHOD(prf_t, destroy, void, + private_openssl_sha1_prf_t *this) +{ + free(this); +} + +/** + * See header + */ +openssl_sha1_prf_t *openssl_sha1_prf_create(pseudo_random_function_t algo) +{ + private_openssl_sha1_prf_t *this; + + if (algo != PRF_KEYED_SHA1) + { + return NULL; + } + + INIT(this, + .public.prf = { + .get_block_size = _get_block_size, + .get_bytes = _get_bytes, + .allocate_bytes = _allocate_bytes, + .get_key_size = _get_key_size, + .set_key = _set_key, + .destroy = _destroy, + }, + ); + + return &this->public; +} + diff --git a/src/libstrongswan/plugins/openssl/openssl_sha1_prf.h b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.h new file mode 100644 index 000000000..9a24e7ee1 --- /dev/null +++ b/src/libstrongswan/plugins/openssl/openssl_sha1_prf.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010 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 . + * + * 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. + */ + +/** + * @defgroup openssl_sha1_prf openssl_sha1_prf + * @{ @ingroup sha1_p + */ + +#ifndef OPENSSL_SHA1_PRF_H_ +#define OPENSSL_SHA1_PRF_H_ + +typedef struct openssl_sha1_prf_t openssl_sha1_prf_t; + +#include + +/** + * Implementation of prf_t interface using keyed SHA1 algorithm as used + * in EAP-AKA/FIPS_PRF. + */ +struct openssl_sha1_prf_t { + + /** + * Implements prf_t interface. + */ + prf_t prf; +}; + +/** + * Creates a new openssl_sha1_prf_t. + * + * @param algo algorithm, must be PRF_KEYED_SHA1 + * @return sha1_keyed_prf_tobject + */ +openssl_sha1_prf_t *openssl_sha1_prf_create(pseudo_random_function_t algo); + +#endif /** OPENSSL_SHA1_PRF_H_ @}*/