From 94539213a121c25f3290a46efc9420c5cf48f339 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 18 Sep 2008 11:20:08 +0000 Subject: [PATCH] Add extra utilities from FIPS branch. --- ms/segrenam.pl | 65 ++++++++++++++++++++++++++++++++++++ util/fipslink.pl | 78 +++++++++++++++++++++++++++++++++++++++++++ util/mksdef.pl | 87 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 ms/segrenam.pl create mode 100644 util/fipslink.pl create mode 100644 util/mksdef.pl diff --git a/ms/segrenam.pl b/ms/segrenam.pl new file mode 100644 index 0000000000..2ab22a0459 --- /dev/null +++ b/ms/segrenam.pl @@ -0,0 +1,65 @@ +#!/usr/bin/env perl + +my $quiet = 1; + +unpack("L",pack("N",1))!=1 || die "only little-endian hosts are supported"; + +# first argument can specify custom suffix... +$suffix=(@ARGV[0]=~/^\$/) ? shift(@ARGV) : "\$m"; +################################################################# +# rename segments in COFF modules according to %map table below # +%map=( ".text" => "fipstx$suffix", # + ".text\$"=> "fipstx$suffix", # + ".rdata"=> "fipsrd$suffix", # + ".data" => "fipsda$suffix" ); # +################################################################# + +# collect file list +foreach (@ARGV) { + if (/\*/) { push(@files,glob($_)); } + else { push(@files,$_); } +} + +use Fcntl; +use Fcntl ":seek"; + +foreach (@files) { + $file=$_; + print "processing $file\n" unless $quiet; + + sysopen(FD,$file,O_RDWR|O_BINARY) || die "sysopen($file): $!"; + + # read IMAGE_DOS_HEADER + sysread(FD,$mz,64)==64 || die "$file is too short"; + @dos_header=unpack("a2C58I",$mz); + if (@dos_header[0] eq "MZ") { + $e_lfanew=pop(@dos_header); + sysseek(FD,$e_lfanew,SEEK_SET) || die "$file is too short"; + sysread(FD,$Magic,4)==4 || die "$file is too short"; + unpack("I",$Magic)==0x4550 || die "$file is not COFF image"; + } elsif ($file =~ /\.obj$/i) { + # .obj files have no IMAGE_DOS_HEADER + sysseek(FD,0,SEEK_SET) || die "unable to rewind $file"; + } else { next; } + + # read IMAGE_FILE_HEADER + sysread(FD,$coff,20)==20 || die "$file is too short"; + ($Machine,$NumberOfSections,$TimeDateStamp, + $PointerToSymbolTable,$NumberOfSysmbols, + $SizeOfOptionalHeader,$Characteristics)=unpack("SSIIISS",$coff); + + # skip over IMAGE_OPTIONAL_HEADER + sysseek(FD,$SizeOfOptionalHeader,SEEK_CUR) || die "$file is too short"; + + # traverse IMAGE_SECTION_HEADER table + for($i=0;$i<$NumberOfSections;$i++) { + sysread(FD,$SectionHeader,40)==40 || die "$file is too short"; + ($Name,@opaque)=unpack("Z8C*",$SectionHeader); + if ($map{$Name}) { + sysseek(FD,-40,SEEK_CUR) || die "unable to rewind $file"; + syswrite(FD,pack("a8C*",$map{$Name},@opaque))==40 || die "syswrite failed: $!"; + printf " %-8s -> %.8s\n",$Name,$map{$Name} unless $quiet; + } + } + close(FD); +} diff --git a/util/fipslink.pl b/util/fipslink.pl new file mode 100644 index 0000000000..3597bc1740 --- /dev/null +++ b/util/fipslink.pl @@ -0,0 +1,78 @@ +#!/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, $fips_libdir, $sha1_exe) + = check_env("FIPS_CC", "FIPS_CC_ARGS", "FIPS_LINK", "FIPS_TARGET", + "FIPSLIB_D", "FIPS_SHA1_EXE"); + + + +if (exists $ENV{"PREMAIN_DSO_EXE"}) + { + $fips_premain_dso = $ENV{"PREMAIN_DSO_EXE"}; + } + else + { + $fips_premain_dso = ""; + } + +check_hash($sha1_exe, "fips_premain.c"); +check_hash($sha1_exe, "fipscanister.lib"); + + +print "Integrity check OK\n"; + +print "$fips_cc $fips_cc_args $fips_libdir/fips_premain.c\n"; +system "$fips_cc $fips_cc_args $fips_libdir/fips_premain.c"; +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 $fips_libdir/fips_premain.c\n"; +system "$fips_cc -DHMAC_SHA1_SIG=\\\"$fips_hash\\\" $fips_cc_args $fips_libdir/fips_premain.c"; +die "Second stage Compile failure" if $? != 0; + + +print "$fips_link @ARGV\n"; +system "$fips_link @ARGV"; +die "Second stage Link failure" if $? != 0; + +sub check_hash + { + my ($sha1_exe, $filename) = @_; + my ($hashfile, $hashval); + + open(IN, "${fips_libdir}/${filename}.sha1") || die "Cannot open file hash file ${fips_libdir}/${filename}.sha1"; + $hashfile = ; + close IN; + $hashval = `$sha1_exe ${fips_libdir}/$filename`; + chomp $hashfile; + chomp $hashval; + $hashfile =~ s/^.*=\s+//; + $hashval =~ s/^.*=\s+//; + die "Invalid hash syntax in file" if (length($hashfile) != 40); + die "Invalid hash received for file" if (length($hashval) != 40); + die "***HASH VALUE MISMATCH FOR FILE $filename ***" if ($hashval ne $hashfile); + } + + diff --git a/util/mksdef.pl b/util/mksdef.pl new file mode 100644 index 0000000000..065dc675f1 --- /dev/null +++ b/util/mksdef.pl @@ -0,0 +1,87 @@ + +# 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 spliting"; + +my $started = 0; + +# Parse libeay32.def into two arrays depending on whether the symbol matches +# the missing list. + + +foreach () + { + if (/^\s*(\S+)\s*(\@\S+)\s*$/) + { + $started = 1; + if (exists $nosym{$1}) + { + push @fipsrest, $_; + } + else + { + my $imptmp = sprintf " %-39s %s\n", + "$1=libosslfips.$1", $2; + push @fipsrest, $imptmp; + push @fipsdll, "\t$1\n"; + } + } + $preamble .= $_ unless $started; + } + +close IN; + +# Hack! Add some additional exports needed for libcryptofips.dll +# + +push @fipsdll, "\tOPENSSL_showfatal\n"; +push @fipsdll, "\tOPENSSL_cpuid_setup\n"; + +# Write out DEF files for each array + +write_def("ms/libosslfips.def", "LIBOSSLFIPS", $preamble, \@fipsdll); +write_def("ms/libeayfips.def", "", $preamble, \@fipsrest); + + +sub write_def + { + my ($fnam, $defname, $preamble, $rdefs) = @_; + open (OUT, ">$fnam") || die "Can't Open DEF file $fnam for Writing\n"; + + if ($defname ne "") + { + $preamble =~ s/LIBEAY32/$defname/g; + $preamble =~ s/LIBEAY/$defname/g; + } + print OUT $preamble; + foreach (@$rdefs) + { + print OUT $_; + } + close OUT; + } + + -- 2.25.1