diff --git a/fips/fips_locl.h b/fips/fips_locl.h index 5d4a3dd3a5..bbddfaab82 100644 --- a/fips/fips_locl.h +++ b/fips/fips_locl.h @@ -63,6 +63,7 @@ void fips_set_started(void); int fips_is_owning_thread(void); int fips_set_owning_thread(void); int fips_clear_owning_thread(void); +unsigned char *fips_signature_witness(void); #ifdef __cplusplus } diff --git a/fips/fipshashes.c b/fips/fipshashes.c index 9d9dbef7dc..c129d1250d 100644 --- a/fips/fipshashes.c +++ b/fips/fipshashes.c @@ -3,6 +3,7 @@ const char * const FIPS_source_hashes[] = { "HMAC-SHA1(fips_err_wrapper.c)= d3e2be316062510312269e98f964cb87e7577898", "HMAC-SHA1(fips.h)= 57d602d18efe0594f806fbcc64269e9440638ef4", "HMAC-SHA1(fips_err.h)= e0649ee1d60c8162f7eeb293f89f3b63ac85202a", +"HMAC-SHA1(fips_locl.h)= f90a23c7f68642727012bbfd48ed58706383ad71", "HMAC-SHA1(fips_canister.c)= da6d0f5daf9594881fd060773a5f3e057ba302ff", "HMAC-SHA1(fips_premain.c)= 6a08d15c578f1258246181bf52134ae974aa5a80", "HMAC-SHA1(aes/fips_aes_core.c)= b70bbbd675efe0613da0d57055310926a0104d55", diff --git a/util/fipslink.pl b/util/fipslink.pl new file mode 100644 index 0000000000..aa9928c053 --- /dev/null +++ b/util/fipslink.pl @@ -0,0 +1,53 @@ +#!/usr/bin/perl + +sub check_env + { + my @ret; + foreach (@_) + { + die "Environment variable $_ not defined!\n" unless exists $ENV{$_}; + push @ret, $ENV{$_}; + } + return @ret; + } + + +my ($fips_cc,$fips_cc_args, $fips_link,$fips_target) + = check_env("FIPS_CC", "FIPS_CC_ARGS", "FIPS_LINK", "FIPS_TARGET"); + + + +if (exists $ENV{"FIPS_PREMAIN_DSO"}) + { + $fips_premain_dso = $ENV{"FIPS_PREMAIN_DSO"}; + } + else + { + $fips_premain_dso = ""; + } + + +print "$fips_cc $fips_cc_args\n"; +system "$fips_cc $fips_cc_args"; +die "First stage Compile failure" if $? != 0; + +print "$fips_link @ARGV\n"; +system "$fips_link @ARGV"; +die "First stage Link failure" if $? != 0; + + +print "$fips_premain_dso $fips_target\n"; +$fips_hash=`$fips_premain_dso $fips_target`; +chomp $fips_hash; +die "Get hash failure" if $? != 0; + + +print "$fips_cc -DHMAC_SHA1_SIG=\\\"$fips_hash\\\" $fips_cc_args\n"; +system "$fips_cc -DHMAC_SHA1_SIG=\\\"$fips_hash\\\" $fips_cc_args"; +die "Second stage Compile failure" if $? != 0; + + +print "$fips_link @ARGV\n"; +system "$fips_link @ARGV"; +die "Second stage Link failure" if $? != 0; + diff --git a/util/mk1mf.pl b/util/mk1mf.pl index 0e1c180273..cf302bb66e 100755 --- a/util/mk1mf.pl +++ b/util/mk1mf.pl @@ -108,6 +108,7 @@ $inc_def="outinc"; $tmp_def="tmp"; $mkdir="-mkdir"; +$mkcanister="ld -r -o"; ($ssl,$crypto)=("ssl","crypto"); $ranlib="echo ranlib"; @@ -285,9 +286,16 @@ for (;;) { if ($lib ne "") { - $uc=$lib; - $uc =~ s/^lib(.*)\.a/$1/; - $uc =~ tr/a-z/A-Z/; + if ($fips && $dir =~ /^fips/) + { + $uc = "FIPS"; + } + else + { + $uc=$lib; + $uc =~ s/^lib(.*)\.a/$1/; + $uc =~ tr/a-z/A-Z/; + } $lib_nam{$uc}=$uc; $lib_obj{$uc}.=$libobj." "; } @@ -382,6 +390,8 @@ EX_LIBS=$ex_libs SRC_D=$src_dir LINK=$link +PERL=perl +FIPSLINK=\$(PERL) util${o}fipslink.pl LFLAGS=$lflags BN_ASM_OBJ=$bn_asm_obj @@ -420,12 +430,14 @@ MKDIR=$mkdir MKLIB=$bin_dir$mklib MLFLAGS=$mlflags ASM=$bin_dir$asm +MKCANISTER=$mkcanister ###################################################### # You should not need to touch anything below this point ###################################################### E_EXE=openssl +E_PREMAIN_DSO=fips_premain_dso SSL=$ssl CRYPTO=$crypto @@ -446,6 +458,7 @@ INCL_D=\$(TMP_D) O_SSL= \$(LIB_D)$o$plib\$(SSL)$shlibp O_CRYPTO= \$(LIB_D)$o$plib\$(CRYPTO)$shlibp +O_FIPSCANISTER= \$(LIB_D)${o}fipscanister$obj SO_SSL= $plib\$(SSL)$so_shlibp SO_CRYPTO= $plib\$(CRYPTO)$so_shlibp L_SSL= \$(LIB_D)$o$plib\$(SSL)$libp @@ -577,6 +590,21 @@ $rules.=&do_compile_rule("\$(OBJ_D)",$test,"\$(APP_CFLAGS)"); $defs.=&do_defs("E_OBJ",$e_exe,"\$(OBJ_D)",$obj); $rules.=&do_compile_rule("\$(OBJ_D)",$e_exe,'-DMONOLITH $(APP_CFLAGS)'); +# Special case rules for fips_start and fips_end fips_premain_dso + +if ($fips) + { + $rules.=&cc_compile_target("\$(OBJ_D)${o}fips_start$obj", + "fips${o}fips_canister.c", "-DFIPS_START \$(SHLIB_CFLAGS)"); + $rules.=&cc_compile_target("\$(OBJ_D)${o}fips_end$obj", + "fips${o}fips_canister.c", "\$(SHLIB_CFLAGS)"); + $rules.=&cc_compile_target("\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj", + "fips${o}fips_premain.c", + "-DFINGERPRINT_PREMAIN_DSO_LOAD \$(SHLIB_CFLAGS)"); + } + + + foreach (values %lib_nam) { $lib_obj=$lib_obj{$_}; @@ -653,10 +681,34 @@ foreach (split(/\s+/,$test)) } $rules.= &do_lib_rule("\$(SSLOBJ)","\$(O_SSL)",$ssl,$shlib,"\$(SO_SSL)"); -$rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)"); + if ($fips) { + if ($shlib) + { + $rules.= &do_lib_rule("\$(CRYPTOOBJ) \$(O_FIPSCANISTER)", + "\$(O_CRYPTO)",$crypto,$shlib, "\$(SO_CRYPTO)", + "0xFB00000", "\$(BIN_D)$o\$(E_PREMAIN_DSO)$exep", + "fips${o}fips_premain.c"); + } + else + { + $rules.= &do_lib_rule("\$(CRYPTOOBJ) \$(O_FIPSCANISTER)", + "\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)", ""); + } + } + else + { + $rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib, + "\$(SO_CRYPTO)"); + } + + +if ($fips) + { + $rules.= &do_rlink_rule("\$(O_FIPSCANISTER)", "\$(OBJ_D)${o}fips_start$obj \$(FIPSOBJ) \$(OBJ_D)${o}fips_end$obj"); + $rules.=&do_link_rule("\$(BIN_D)$o\$(E_PREMAIN_DSO)$exep","\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj \$(CRYPTOOBJ) \$(O_FIPCANISTER)","","\$(EX_LIBS) \$(O_FIPSCANISTER)"); $rules.=&do_link_rule("\$(BIN_D)$o\$(E_EXE)$exep","\$(E_OBJ)","\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)","\$(BIN_D)$o.sha1","\$(BIN_D)$o\$(E_EXE)$exep"); } else diff --git a/util/pl/VC-32.pl b/util/pl/VC-32.pl index ca9514f135..96889929b6 100644 --- a/util/pl/VC-32.pl +++ b/util/pl/VC-32.pl @@ -103,11 +103,21 @@ $cflags.=" /Fd$out_def"; sub do_lib_rule { - local($objs,$target,$name,$shlib)=@_; + local($objs,$target,$name,$shlib,$ign,$base_addr, $fips_get_sig, $fips_premain_src)=@_; local($ret,$Name); $taget =~ s/\//$o/g if $o ne '/'; ($Name=$name) =~ tr/a-z/A-Z/; + my $base_arg; + if ($base_addr ne "") + { + $base_arg= " /base:$base_addr"; + } + else + { + $base_arg = ""; + } + # $target="\$(LIB_D)$o$target"; $ret.="$target: $objs\n"; @@ -122,7 +132,21 @@ sub do_lib_rule local($ex)=($target =~ /O_SSL/)?' $(L_CRYPTO)':''; $ex.=' wsock32.lib gdi32.lib advapi32.lib user32.lib'; $ex.=" $zlib_lib" if $zlib_opt == 1 && $target =~ /O_CRYPTO/; - $ret.="\t\$(LINK) \$(MLFLAGS) $efile$target /def:ms/${Name}.def @<<\n \$(SHLIB_EX_OBJ) $objs $ex\n<<\n"; + if (defined $fips_get_sig) + { + $ret.="\tSET FIPS_LINK=\$(LINK)\n"; + $ret.="\tSET FIPS_CC=\$(CC)\n"; + $ret.="\tSET FIPS_CC_ARGS=/Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c \$(SRC_D)${o}fips${o}fips_premain.c\n"; + $ret.="\tSET FIPS_PREMAIN_DSO=$fips_get_sig\n"; + $ret.="\tSET FIPS_TARGET=$target\n"; + $ret.="\t\$(FIPSLINK) \$(MLFLAGS) $base_arg $efile$target "; + $ret.="/def:ms/${Name}.def @<<\n \$(SHLIB_EX_OBJ) $objs "; + $ret.="\$(OBJ_D)${o}fips_premain.obj $ex\n<<\n"; + } + else + { + $ret.="\t\$(LINK) \$(MLFLAGS) $base_arg $efile$target /def:ms/${Name}.def @<<\n \$(SHLIB_EX_OBJ) $objs $ex\n<<\n"; + } } $ret.="\n"; return($ret); @@ -136,14 +160,39 @@ sub do_link_rule $file =~ s/\//$o/g if $o ne '/'; $n=&bname($targer); $ret.="$target: $files $dep_libs\n"; - $ret.=" \$(LINK) \$(LFLAGS) $efile$target @<<\n"; - $ret.=" \$(APP_EX_OBJ) $files $libs\n<<\n"; - if (defined $sha1file) + if ($fips && !$shlib) { - $ret.=" $openssl sha1 -hmac etaonrishdlcupfm -binary $target > $sha1file"; + $ret.="$target: $files $dep_libs\n"; + $ret.="\tSET FIPS_LINK=\$(LINK)\n"; + $ret.="\tSET FIPS_CC=\$(CC)\n"; + $ret.="\tSET FIPS_CC_ARGS=/Fo\$(OBJ_D)${o}fips_premain.obj \$(SHLIB_CFLAGS) -c \$(SRC_D)${o}fips${o}fips_premain.c\n"; + $ret.="\tSET FIPS_PREMAIN_DSO=\n"; + $ret.="\tSET FIPS_TARGET=$target\n"; + $ret.=" \$(FIPSLINK) \$(LFLAGS) $efile$target @<<\n"; + $ret.=" \$(APP_EX_OBJ) $files \$(OBJ_D)${o}fips_premain.obj $libs\n<<\n"; } + else + { + $ret.=" \$(LINK) \$(LFLAGS) $efile$target @<<\n"; + } + $ret.=" \$(APP_EX_OBJ) $files $libs\n<<\n"; $ret.="\n"; return($ret); } +sub do_rlink_rule + { + local($target,$files,$dep_libs,$libs)=@_; + local($ret,$_); + + $file =~ s/\//$o/g if $o ne '/'; + $n=&bname($targer); + $ret.="$target: $files $dep_libs\n"; + $ret.=" \$(MKCANISTER) $target <<\n"; + $ret.="INPUT($files)\n<<\n"; + $ret.="\n"; + return($ret); + } + + 1;