diff --git a/CHANGES b/CHANGES index f72c65f76..0b2d7c170 100644 --- a/CHANGES +++ b/CHANGES @@ -5,7 +5,8 @@ Changes between 0.9.7l and 0.9.7m-fips2 [xx XXX xxxx] *) New build option fipsdso to link fipscanister.o into a DSO called - libfips.so and modify build system to link against it. + libfips.so and modify build system to link against it. Preliminary changes + to VC++ build system to accomodate fipsdso. [Steve Henson] *) New version of RSA_{sign,verify} for FIPS code. This uses pregenerated diff --git a/Configure b/Configure index 73daa2f03..f001f693b 100755 --- a/Configure +++ b/Configure @@ -991,6 +991,8 @@ print "Configuring for $target\n"; my $IsWindows=scalar grep /^$target$/,@WinTargets; +$no_shared = 1 if ($IsWindows && $fipsdso); + $exe_ext=".exe" if ($target eq "Cygwin" || $target eq "DJGPP" || $target eq "mingw"); $exe_ext=".pm" if ($target eq "vos-gcc" or $target eq "debug-vos-gcc" or $target eq "vos-vcc" or $target eq "debug-vos-vcc"); $openssldir="/usr/local/ssl" if ($openssldir eq "" and $prefix eq ""); diff --git a/fips-1.0/Makefile b/fips-1.0/Makefile index 03e04ed6a..e318e3203 100644 --- a/fips-1.0/Makefile +++ b/fips-1.0/Makefile @@ -262,6 +262,8 @@ FIPS_EX_OBJ= ../crypto/aes/aes_cbc.o \ ../crypto/des/ecb_enc.o \ ../crypto/des/ofb64ede.o \ ../crypto/des/ofb64enc.o \ + ../crypto/des/fcrypt_b.o \ + ../crypto/des/fcrypt.o \ ../crypto/dh/dh_lib.o \ ../crypto/dsa/dsa_lib.o \ ../crypto/dsa/dsa_sign.o \ diff --git a/util/mk1mf.pl b/util/mk1mf.pl index f13842930..46e75b455 100755 --- a/util/mk1mf.pl +++ b/util/mk1mf.pl @@ -19,6 +19,7 @@ my $fips_premain_c_path = ""; my $fips_sha1_exe_path = ""; local $fipscanisterbuild = 0; +local $fipsdso = 0; my $fipslibdir = ""; my $baseaddr = ""; @@ -450,6 +451,8 @@ if ($fips_premain_dso_exe_path eq "") # $ex_build_targets .= "\$(BIN_D)${o}\$(E_PREMAIN_DSO)$exep" if ($fips); +$ex_l_libs .= " \$(L_FIPS)" if $fipsdso; + if ($fips) { if (!$shlib) @@ -587,6 +590,7 @@ PREMAIN_DSO_EXE=$fips_premain_dso_exe_path E_EXE=openssl SSL=$ssl CRYPTO=$crypto +LIBFIPS=libfips # BIN_D - Binary output directory # TEST_D - Binary test file output directory @@ -605,10 +609,12 @@ INCL_D=\$(TMP_D) O_SSL= \$(LIB_D)$o$plib\$(SSL)$shlibp O_CRYPTO= \$(LIB_D)$o$plib\$(CRYPTO)$shlibp +O_FIPS= \$(LIB_D)$o$plib\$(LIBFIPS)$shlibp SO_SSL= $plib\$(SSL)$so_shlibp SO_CRYPTO= $plib\$(CRYPTO)$so_shlibp L_SSL= \$(LIB_D)$o$plib\$(SSL)$libp L_CRYPTO= \$(LIB_D)$o$plib\$(CRYPTO)$libp +L_FIPS= \$(LIB_D)$o$plib\$(LIBFIPS)$libp L_LIBS= \$(L_SSL) \$(L_CRYPTO) $ex_l_libs @@ -841,10 +847,24 @@ if ($fips) { if ($shlib) { - $rules.= &do_lib_rule("\$(CRYPTOOBJ) \$(O_FIPSCANISTER)", - "\$(O_CRYPTO)", - "$crypto", - $shlib, "\$(SO_CRYPTO)", "\$(BASEADDR)"); + if ($fipsdso) + { + $rules.= &do_lib_rule("\$(CRYPTOOBJ)", + "\$(O_CRYPTO)", "$crypto", + $shlib, "", ""); + $rules.= &do_lib_rule( + "\$(O_FIPSCANISTER)", + "\$(O_FIPS)", "libfips", + $shlib, "\$(SO_CRYPTO)", "\$(BASEADDR)"); + $rules.= &do_sdef_rule(); + } + else + { + $rules.= &do_lib_rule( + "\$(CRYPTOOBJ) \$(O_FIPSCANISTER)", + "\$(O_CRYPTO)", "$crypto", + $shlib, "\$(SO_CRYPTO)", "\$(BASEADDR)"); + } } else { @@ -1189,6 +1209,12 @@ sub read_options $fips=1; $fipscanisterbuild=1; } + elsif (/^fipsdso$/) + { + $fips=1; + $fipscanisterbuild=1; + $fipsdso=1; + } elsif (/^([^=]*)=(.*)$/){ $VARS{$1}=$2; } elsif (/^-[lL].*$/) { $l_flags.="$_ "; } elsif ((!/^-help/) && (!/^-h/) && (!/^-\?/) && /^-.*$/) diff --git a/util/mkdef.pl b/util/mkdef.pl index 27d999bf7..b410bd51f 100755 --- a/util/mkdef.pl +++ b/util/mkdef.pl @@ -130,8 +130,7 @@ foreach (@ARGV, split(/ /, $options)) } $VMS=1 if $_ eq "VMS"; $OS2=1 if $_ eq "OS2"; - $fips=1 if $_ eq "fips"; - $fips=1 if $_ eq "fipscanisterbuild"; + $fips=1 if /^fips/; $do_ssl=1 if $_ eq "ssleay"; if ($_ eq "ssl") { diff --git a/util/mksdef.pl b/util/mksdef.pl new file mode 100644 index 000000000..33b999adf --- /dev/null +++ b/util/mksdef.pl @@ -0,0 +1,85 @@ + +# Perl script to split libeay32.def into two distinct DEF files for use in +# fipdso mode. It works out symbols in each case by running "link" command and +# parsing the output to find the list of missing symbols then splitting +# libeay32.def based on the result. + + +# Get list of unknown symbols + +my @deferr = `link @ARGV`; + +my $preamble = ""; +my @fipsdll; +my @fipsrest; +my %nosym; + +# Add symbols to a hash for easy lookup + +foreach (@deferr) + { + if (/^.*symbol (\S+)$/) + { + $nosym{$1} = 1; + } + } + +open (IN, "ms/libeay32.def") || die "Can't Open DEF file for splittling"; + +my $started = 0; + +# Parse libeay32.def into two arrays depending on whether the symbol matches +# the missing list. + + +foreach () + { + if (/^\s*(\S+)\s*\@/) + { + $started = 1; + if (exists $nosym{$1}) + { + push @fipsrest, $_; + } + else + { + push @fipsdll, "\t$1\n"; + } + } + $preamble .= $_ unless $started; + } + +close IN; + +# Hack! Add some additional exports needed to libcryptofips.dll +# + +push @fipsdll, "\tengine_table_unregister\n"; +push @fipsdll, "\tengine_table_register\n"; +push @fipsdll, "\tengine_table_cleanup\n"; +push @fipsdll, "\tengine_table_select\n"; +push @fipsdll, "\tengine_set_all_null\n"; + +# Write out DEF files for each array + +write_def("ms/libfips.def", "LIBFIPS", $preamble, \@fipsdll); +write_def("ms/libcryptofips.def", "LIBCRYPTOFIPS", $preamble, \@fipsrest); + + +sub write_def + { + my ($fnam, $defname, $preamble, $rdefs) = @_; + open (OUT, ">$fnam") || die "Can't Open DEF file $fnam for Writing\n"; + + $preamble =~ s/LIBEAY32/$defname/g; + $preamble =~ s/LIBEAY/$defname/g; + + print OUT $preamble; + foreach (@$rdefs) + { + print OUT $_; + } + close OUT; + } + + diff --git a/util/pl/VC-32.pl b/util/pl/VC-32.pl index 3f326ed96..d933a1f56 100644 --- a/util/pl/VC-32.pl +++ b/util/pl/VC-32.pl @@ -13,7 +13,14 @@ if ($fips && !$shlib) } else { - $crypto="libeay32"; + if ($fipsdso) + { + $crypto="libcryptofips"; + } + else + { + $crypto="libeay32"; + } } $o='\\'; @@ -119,6 +126,7 @@ sub do_lib_rule local($objs,$target,$name,$shlib,$ign,$base_addr) = @_; local($ret,$Name); + $taget =~ s/\//$o/g if $o ne '/'; ($Name=$name) =~ tr/a-z/A-Z/; my $base_arg; @@ -143,14 +151,29 @@ sub do_lib_rule } else { - local($ex)=($target =~ /O_SSL/)?' $(L_CRYPTO)':''; + my $ex = ""; + if ($target =~ /O_SSL/) + { + $ex = " \$(L_CRYPTO)"; + $ex .= " \$(L_FIPS)" if $fipsdso; + } + my $fipstarget; + if ($fipsdso) + { + $fipstarget = "O_FIPS"; + } + else + { + $fipstarget = "O_CRYPTO"; + } $ex.=' wsock32.lib gdi32.lib advapi32.lib user32.lib'; $ex.=" $zlib_lib" if $zlib_opt == 1 && $target =~ /O_CRYPTO/; - if ($fips && $target =~ /O_CRYPTO/) + if ($fips && $target =~ /$fipstarget/) { $ex.= $mwex unless $fipscanisterbuild; - $ret.="$target: $objs \$(PREMAIN_DSO_EXE)\n"; - $ret.="\tSET FIPS_LINK=\$(LINK)\n"; + $ret.="$target: $objs \$(PREMAIN_DSO_EXE)"; + $ret.=" ms/libfips.def" if $fipsdso; + $ret.="\n\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\n"; $ret.="\tSET PREMAIN_DSO_EXE=\$(PREMAIN_DSO_EXE)\n"; @@ -163,8 +186,13 @@ sub do_lib_rule } else { - $ret.="$target: $objs\n"; - $ret.="\t\$(LINK) \$(MLFLAGS) $base_arg $efile$target /def:ms/${Name}.def @<<\n \$(SHLIB_EX_OBJ) $objs $ex\n<<\n"; + $ret.="$target: $objs"; + if ($target =~ /O_CRYPTO/ && $fipsdso) + { + $ret .= " \$(O_FIPS)"; + $ex .= " \$(L_FIPS)"; + } + $ret.="\n\t\$(LINK) \$(MLFLAGS) $efile$target /def:ms/${Name}.def @<<\n \$(SHLIB_EX_OBJ) $objs $ex\n<<\n"; } } $ret.="\n"; @@ -173,7 +201,7 @@ sub do_lib_rule sub do_link_rule { - local($target,$files,$dep_libs,$libs,$standalone)=@_; + my($target,$files,$dep_libs,$libs,$standalone)=@_; local($ret,$_); $file =~ s/\//$o/g if $o ne '/'; $n=&bname($targer); @@ -222,5 +250,13 @@ sub do_rlink_rule return($ret); } +sub do_sdef_rule + { + my $ret = "ms/libfips.def: \$(O_FIPSCANISTER)\n"; + $ret.="\t\$(PERL) util/mksdef.pl \$(MLFLAGS) /out:dummy.dll /def:ms/libeay32.def @<<\n \$(O_FIPSCANISTER)\n<<\n"; + $ret.="\n"; + return $ret; + } + 1;