diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2011-05-26 14:19:19 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2011-05-26 14:19:19 +0000 |
commit | 7207eca1ee06ad4b5b5ab7b16e57f5f4f61606dd (patch) | |
tree | 807dd0dc17677e2ba0a464548ac94096a4ca6933 | |
parent | 9c34782478f00faba7bac87bd03a0f4f1ee53747 (diff) |
The first of many changes to make OpenSSL 1.0.1 FIPS capable.
Add static build support to openssl utility.
Add new "fips" option to Configure.
Make use of installed fipsld and fips_standalone_sha1
Initialise FIPS error callbacks, locking and DRBG.
Doesn't do anything much yet: no crypto is redirected to the FIPS module.
Doesn't completely build either but the openssl utility can enter FIPS mode:
which doesn't do anything much either.
-rwxr-xr-x | Configure | 37 | ||||
-rw-r--r-- | Makefile.org | 27 | ||||
-rw-r--r-- | apps/Makefile | 2 | ||||
-rw-r--r-- | crypto/Makefile | 4 | ||||
-rw-r--r-- | crypto/cryptlib.c | 4 | ||||
-rw-r--r-- | crypto/crypto.h | 2 | ||||
-rw-r--r-- | crypto/err/err.h | 6 | ||||
-rw-r--r-- | crypto/o_init.c | 82 | ||||
-rw-r--r-- | crypto/rand/rand.h | 4 | ||||
-rw-r--r-- | crypto/rand/rand_lib.c | 97 |
10 files changed, 263 insertions, 2 deletions
@@ -628,6 +628,9 @@ my $openssldir=""; my $exe_ext=""; my $install_prefix= "$ENV{'INSTALL_PREFIX'}"; my $cross_compile_prefix=""; +my $fipsdir="/usr/local/ssl/fips-2.0/"; +my $fipslibdir=""; +my $baseaddr="0xFB00000"; my $no_threads=0; my $threads=0; my $no_shared=0; # but "no-shared" is default @@ -662,6 +665,7 @@ my $cmll_enc="camellia.o cmll_misc.o cmll_cbc.o"; my $processor=""; my $default_ranlib; my $perl; +my $fips=0; # All of the following is disabled by default (RC5 was enabled before 0.9.8): @@ -809,6 +813,10 @@ PROCESS_ARGS: } elsif (/^386$/) { $processor=386; } + elsif (/^fips$/) + { + $fips=1; + } elsif (/^rsaref$/) { # No RSAref support any more since it's not needed. @@ -853,6 +861,18 @@ PROCESS_ARGS: { $withargs{"zlib-include"}="-I$1"; } + elsif (/^--with-fipsdir=(.*)$/) + { + $fipsdir="$1/"; + } + elsif (/^--with-fipslibdir=(.*)$/) + { + $fipslibdir="$1/"; + } + elsif (/^--with-baseaddr=(.*)$/) + { + $baseaddr="$1"; + } elsif (/^--cross-compile-prefix=(.*)$/) { $cross_compile_prefix=$1; @@ -927,6 +947,11 @@ if (defined($disabled{"md5"}) || defined($disabled{"rsa"})) $disabled{"ssl2"} = "forced"; } +if ($fips && $fipslibdir eq "") + { + $fipslibdir = $fipsdir . "lib/"; + } + # SSL 3.0 and TLS requires MD5 and SHA and either RSA or DSA+DH if (defined($disabled{"md5"}) || defined($disabled{"sha"}) || (defined($disabled{"rsa"}) @@ -1385,6 +1410,12 @@ $cflags.=" -DOPENSSL_IA32_SSE2" if (!$no_sse2 && $bn_obj =~ /86/); $cflags.=" -DOPENSSL_BN_ASM_MONT" if ($bn_obj =~ /-mont/); +if ($fips) + { + $openssl_other_defines.="#define OPENSSL_FIPS\n"; + $cflags .= " -I\$(FIPSDIR)include"; + } + $cpuid_obj="mem_clr.o" unless ($cpuid_obj =~ /\.o$/); $des_obj=$des_enc unless ($des_obj =~ /\.o$/); $bf_obj=$bf_enc unless ($bf_obj =~ /\.o$/); @@ -1552,6 +1583,12 @@ while (<IN>) s/^LIBKRB5=.*/LIBKRB5=$withargs{"krb5-lib"}/; s/^LIBZLIB=.*/LIBZLIB=$withargs{"zlib-lib"}/; s/^ZLIB_INCLUDE=.*/ZLIB_INCLUDE=$withargs{"zlib-include"}/; + + s/^FIPSDIR=.*/FIPSDIR=$fipsdir/; + s/^FIPSLIBDIR=.*/FIPSLIBDIR=$fipslibdir/; + s/^FIPSCANLIB=.*/FIPSCANLIB=libcrypto/ if $fips; + s/^BASEADDR=.*/BASEADDR=$baseaddr/; + s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/; s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/; s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared); diff --git a/Makefile.org b/Makefile.org index c8869d14df..4f5b4351ff 100644 --- a/Makefile.org +++ b/Makefile.org @@ -109,6 +109,30 @@ LIBKRB5= ZLIB_INCLUDE= LIBZLIB= +# TOP level FIPS install directory. +FIPSDIR= + +# This is the location of fipscanister.o and friends. +# The FIPS module build will place it $(INSTALLTOP)/lib +# but since $(INSTALLTOP) can only take the default value +# when the module is built it will be in /usr/local/ssl/lib +# $(INSTALLTOP) for this build may be different so hard +# code the path. + +FIPSLIBDIR= + +# The location of the library which contains fipscanister.o +# normally it will be libcrypto unless fipsdso is set in which +# case it will be libfips. If not compiling in FIPS mode at all +# this is empty making it a useful test for a FIPS compile. + +FIPSCANLIB= + +# Shared library base address. Currently only used on Windows. +# + +BASEADDR= + DIRS= crypto ssl engines apps test tools ENGDIRS= ccgost SHLIBDIRS= crypto ssl @@ -205,6 +229,9 @@ BUILDENV= PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)' \ RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)' \ WP_ASM_OBJ='$(WP_ASM_OBJ)' \ PERLASM_SCHEME='$(PERLASM_SCHEME)' \ + FIPSLIBDIR='${FIPSLIBDIR}' \ + FIPSDIR='${FIPSDIR}' \ + FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}" \ THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES= # MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors, # which in turn eliminates ambiguities in variable treatment with -e. diff --git a/apps/Makefile b/apps/Makefile index bb384abdf3..658a09a2f2 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -153,6 +153,8 @@ $(EXE): progs.h $(E_OBJ) $(PROGRAM).o $(DLIBCRYPTO) $(DLIBSSL) $(RM) $(EXE) shlib_target=; if [ -n "$(SHARED_LIBS)" ]; then \ shlib_target="$(SHLIB_TARGET)"; \ + elif [ -n "$(FIPSCANLIB)" ]; then \ + FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)bin/fipsld; export CC FIPSLD_CC; \ fi; \ LIBRARIES="$(LIBSSL) $(LIBKRB5) $(LIBCRYPTO)" ; \ $(MAKE) -f $(TOP)/Makefile.shared -e \ diff --git a/crypto/Makefile b/crypto/Makefile index c2f356ece1..54c6b46ac0 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -34,8 +34,8 @@ GENERAL=Makefile README crypto-lib.com install.com LIB= $(TOP)/libcrypto.a SHARED_LIB= libcrypto$(SHLIB_EXT) -LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c -LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o uid.o o_time.o o_str.o o_dir.o o_fips.o $(CPUID_OBJ) +LIBSRC= cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c +LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o $(CPUID_OBJ) SRC= $(LIBSRC) diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index 14bae0d08c..a453475fdb 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c @@ -409,6 +409,10 @@ int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, void CRYPTO_set_locking_callback(void (*func)(int mode,int type, const char *file,int line)) { + /* Calling this here ensures initialisation before any threads + * are started. + */ + OPENSSL_init(); locking_callback=func; } diff --git a/crypto/crypto.h b/crypto/crypto.h index 2aa53a9855..0a34ef2ac2 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -550,6 +550,8 @@ int OPENSSL_isservice(void); int FIPS_mode(void); int FIPS_mode_set(int r); +void OPENSSL_init(void); + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. diff --git a/crypto/err/err.h b/crypto/err/err.h index 974cc9cc6f..3d71e4212e 100644 --- a/crypto/err/err.h +++ b/crypto/err/err.h @@ -137,6 +137,12 @@ extern "C" { #define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) #endif +#ifdef OPENSSL_FIPS +void FIPS_set_error_callbacks( + void (*put_cb)(int lib, int func,int reason,const char *file,int line), + void (*add_cb)(int num, va_list args) ); +#endif + #include <errno.h> #define ERR_TXT_MALLOCED 0x01 diff --git a/crypto/o_init.c b/crypto/o_init.c new file mode 100644 index 0000000000..db4cdc443b --- /dev/null +++ b/crypto/o_init.c @@ -0,0 +1,82 @@ +/* o_init.c */ +/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include <e_os.h> +#include <openssl/err.h> +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#include <openssl/rand.h> +#endif + +/* Perform any essential OpenSSL initialization operations. + * Currently only sets FIPS callbacks + */ + +void OPENSSL_init(void) + { + static int done = 0; + if (done) + return; + done = 1; +#ifdef OPENSSL_FIPS + FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock); + FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata); + FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free); + RAND_init_fips(); +#endif +#if 0 + fprintf(stderr, "Called OPENSSL_init\n"); +#endif + } + diff --git a/crypto/rand/rand.h b/crypto/rand/rand.h index ac6c021763..24aa7c0cb4 100644 --- a/crypto/rand/rand.h +++ b/crypto/rand/rand.h @@ -119,6 +119,10 @@ int RAND_event(UINT, WPARAM, LPARAM); #endif +#ifdef OPENSSL_FIPS +int RAND_init_fips(void); +#endif + /* BEGIN ERROR CODES */ /* The following lines are auto generated by the script mkerr.pl. Any changes * made after this point may be overwritten when the script is next run. diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 3cf9ed5050..655101e0ec 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -70,6 +70,11 @@ #include <openssl/engine.h> #endif +#ifdef OPENSSL_FIPS +#include <openssl/fips.h> +#include <openssl/fips_rand.h> +#endif + #ifndef OPENSSL_NO_ENGINE /* non-NULL if default_RAND_meth is ENGINE-provided */ static ENGINE *funct_ref =NULL; @@ -78,6 +83,10 @@ static const RAND_METHOD *default_RAND_meth = NULL; int RAND_set_rand_method(const RAND_METHOD *meth) { +#ifdef OPENSSL_FIPS + if (!FIPS_rand_set_method(meth)) + return 0; +#endif #ifndef OPENSSL_NO_ENGINE if(funct_ref) { @@ -180,3 +189,91 @@ int RAND_status(void) return meth->status(); return 0; } + +#ifdef OPENSSL_FIPS + +/* FIPS DRBG initialisation code. This sets up the DRBG for use by the + * rest of OpenSSL. + */ + +/* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather + * entropy internally through RAND_poll(). + */ + +static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) + { + /* Round up request to multiple of block size */ + min_len = ((min_len + 19) / 20) * 20; + *pout = OPENSSL_malloc(min_len); + if (!*pout) + return 0; + if (RAND_SSLeay()->bytes(*pout, min_len) <= 0) + { + OPENSSL_free(*pout); + *pout = NULL; + return 0; + } + return min_len; + } + +static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen) + { + OPENSSL_cleanse(out, olen); + OPENSSL_free(out); + } + +/* Set "additional input" when generating random data. This uses the + * current PID, a time value and a counter. + */ + +static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout) + { + /* Use of static variables is OK as this happens under a lock */ + static unsigned char buf[16]; + static unsigned long counter; + FIPS_get_timevec(buf, &counter); + *pout = buf; + return sizeof(buf); + } + +/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is + * correctly seeded by RAND_poll(). + */ + +static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen, + double entropy) + { + RAND_SSLeay()->add(in, inlen, entropy); + return 1; + } + +static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen) + { + RAND_SSLeay()->seed(in, inlen); + return 1; + } + +int RAND_init_fips(void) + { + DRBG_CTX *dctx; + size_t plen; + unsigned char pers[32], *p; + dctx = FIPS_get_default_drbg(); + FIPS_drbg_init(dctx, NID_aes_256_ctr, DRBG_FLAG_CTR_USE_DF); + FIPS_drbg_set_callbacks(dctx, + drbg_get_entropy, drbg_free_entropy, 20, + drbg_get_entropy, drbg_free_entropy); + FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0, + drbg_rand_seed, drbg_rand_add); + /* Personalisation string: a string followed by date time vector */ + strcpy((char *)pers, "OpenSSL DRBG2.0"); + plen = drbg_get_adin(dctx, &p); + memcpy(pers + 16, p, plen); + + FIPS_drbg_instantiate(dctx, pers, sizeof(pers)); + FIPS_rand_set_method(FIPS_drbg_method()); + return 1; + } + +#endif |