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.
This commit is contained in:
Dr. Stephen Henson 2011-05-26 14:19:19 +00:00
parent 9c34782478
commit 7207eca1ee
10 changed files with 263 additions and 2 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

82
crypto/o_init.c Normal file
View file

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

View file

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

View file

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