Commit 94539213 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Add extra utilities from FIPS branch.

parent c5c42463
Loading
Loading
Loading
Loading

ms/segrenam.pl

0 → 100644
+65 −0
Original line number Diff line number Diff line
#!/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);
}

util/fipslink.pl

0 → 100644
+78 −0
Original line number Diff line number Diff line
#!/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 = <IN>;
	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); 
	}

util/mksdef.pl

0 → 100644
+87 −0
Original line number Diff line number Diff line

# 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 (<IN>)
	{
	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;
	}