#\r
# This script runs the OpenSSL Configure script, then processes the\r
# resulting file list into our local OpensslLib[Crypto].inf and also\r
-# takes a copy of opensslconf.h.\r
+# takes copies of opensslconf.h and dso_conf.h.\r
#\r
# This only needs to be done once by a developer when updating to a\r
# new version of OpenSSL (or changing options, etc.). Normal users\r
# do not need to do this, since the results are stored in the EDK2\r
# git repository for them.\r
#\r
+# Due to the script wrapping required to process the OpenSSL\r
+# configuration data, each native architecture must be processed\r
+# individually by the maintainer (in addition to the standard version):\r
+# ./process_files.pl\r
+# ./process_files.pl X64\r
+# ./process_files.pl [Arch]\r
+\r
use strict;\r
use Cwd;\r
use File::Copy;\r
+use File::Basename;\r
+use File::Path qw(make_path remove_tree);\r
+use Text::Tabs;\r
+\r
+my $comment_character;\r
+\r
+#\r
+# OpenSSL perlasm generator script does not transfer the copyright header\r
+#\r
+sub copy_license_header\r
+{\r
+ my @args = split / /, shift; #Separate args by spaces\r
+ my $source = $args[1]; #Source file is second (after "perl")\r
+ my $target = pop @args; #Target file is always last\r
+ chop ($target); #Remove newline char\r
+\r
+ my $temp_file_name = "license.tmp";\r
+ open (my $source_file, "<" . $source) || die $source;\r
+ open (my $target_file, "<" . $target) || die $target;\r
+ open (my $temp_file, ">" . $temp_file_name) || die $temp_file_name;\r
+\r
+ #Add "generated file" warning\r
+ $source =~ s/^..//; #Remove leading "./"\r
+ print ($temp_file "$comment_character WARNING: do not edit!\r\n");\r
+ print ($temp_file "$comment_character Generated from $source\r\n");\r
+ print ($temp_file "$comment_character\r\n");\r
+\r
+ #Copy source file header to temp file\r
+ while (my $line = <$source_file>) {\r
+ next if ($line =~ /#!/); #Ignore shebang line\r
+ $line =~ s/#/$comment_character/; #Fix comment character for assembly\r
+ $line =~ s/\s+$/\r\n/; #Trim trailing whitepsace, fixup line endings\r
+ print ($temp_file $line);\r
+ last if ($line =~ /http/); #Last line of copyright header contains a web link\r
+ }\r
+ print ($temp_file "\r\n");\r
+ #Retrieve generated assembly contents\r
+ while (my $line = <$target_file>) {\r
+ $line =~ s/\s+$/\r\n/; #Trim trailing whitepsace, fixup line endings\r
+ print ($temp_file expand ($line)); #expand() replaces tabs with spaces\r
+ }\r
+\r
+ close ($source_file);\r
+ close ($target_file);\r
+ close ($temp_file);\r
+\r
+ move ($temp_file_name, $target) ||\r
+ die "Cannot replace \"" . $target . "\"!";\r
+}\r
\r
#\r
# Find the openssl directory name for use lib. We have to do this\r
#\r
my $inf_file;\r
my $OPENSSL_PATH;\r
+my $uefi_config;\r
+my $extension;\r
+my $arch;\r
my @inf;\r
+#\r
+# Use PCD to conditionally enable certain openssl features.\r
+# $conditional_feature contains pcd_name:fetures_names pairs\r
+# of conditional features.\r
+# @conditional_feature_dir contains relative_path:pcd_name pairs\r
+# of conditional features in openssl, MUST correspond to the content\r
+# in $conditional_feature.\r
+#\r
+# Configure list [openssl_configuration : new_define_list : new_file_list : pcd]\r
+# 1. no-ec : {NO_EC, NO_ECDH, NO_ECDSA, NO_TLS1_3, NO_SM2} : {/ec/, /sm2/} : PcdOpensslEcEnabled\r
+#\r
+my %conditional_feature = ("PcdOpensslEcEnabled"=>["EC", "ECDH", "ECDSA", "TLS1_3", "SM2"]);\r
+my %conditional_feature_dir = ("/ec/"=>"PcdOpensslEcEnabled", "/sm2/"=>"PcdOpensslEcEnabled");\r
\r
BEGIN {\r
$inf_file = "OpensslLib.inf";\r
+ $uefi_config = "UEFI";\r
+ $arch = shift;\r
+\r
+ if (defined $arch) {\r
+ if (uc ($arch) eq "X64") {\r
+ $arch = "X64";\r
+ $inf_file = "OpensslLibX64.inf";\r
+ $uefi_config = "UEFI-x86_64";\r
+ $extension = "nasm";\r
+ $comment_character = ";";\r
+ } elsif (uc ($arch) eq "X64GCC") {\r
+ $arch = "X64Gcc";\r
+ $inf_file = "OpensslLibX64Gcc.inf";\r
+ $uefi_config = "UEFI-x86_64-GCC";\r
+ $extension = "S";\r
+ $comment_character = "#";\r
+ } elsif (uc ($arch) eq "IA32") {\r
+ $arch = "IA32";\r
+ $inf_file = "OpensslLibIa32.inf";\r
+ $uefi_config = "UEFI-x86";\r
+ $extension = "nasm";\r
+ $comment_character = ";";\r
+ } elsif (uc ($arch) eq "IA32GCC") {\r
+ $arch = "IA32Gcc";\r
+ $inf_file = "OpensslLibIa32Gcc.inf";\r
+ $uefi_config = "UEFI-x86-GCC";\r
+ $extension = "S";\r
+ $comment_character = "#";\r
+ } else {\r
+ die "Unsupported architecture \"" . $arch . "\"!";\r
+ }\r
+ if ($extension eq "nasm") {\r
+ if (`nasm -v 2>&1`) {\r
+ #Presence of nasm executable will trigger inclusion of AVX instructions\r
+ die "\nCannot run assembly generators with NASM in path!\n\n";\r
+ }\r
+ }\r
+\r
+ # Prepare assembly folder\r
+ if (-d $arch) {\r
+ opendir my $dir, $arch ||\r
+ die "Cannot open assembly folder \"" . $arch . "\"!";\r
+ while (defined (my $file = readdir $dir)) {\r
+ if (-d "$arch/$file") {\r
+ next if $file eq ".";\r
+ next if $file eq "..";\r
+ remove_tree ("$arch/$file", {safe => 1}) ||\r
+ die "Cannot clean assembly folder \"" . "$arch/$file" . "\"!";\r
+ }\r
+ }\r
+\r
+ } else {\r
+ mkdir $arch ||\r
+ die "Cannot create assembly folder \"" . $arch . "\"!";\r
+ }\r
+ }\r
\r
# Read the contents of the inf file\r
open( FD, "<" . $inf_file ) ||\r
# Configure UEFI\r
system(\r
"./Configure",\r
- "UEFI",\r
+ "--config=../UefiAsm.conf",\r
+ "$uefi_config",\r
"no-afalgeng",\r
- "no-asm",\r
"no-async",\r
- "no-autoalginit",\r
"no-autoerrinit",\r
+ "no-autoload-config",\r
"no-bf",\r
"no-blake2",\r
"no-camellia",\r
"no-cms",\r
"no-ct",\r
"no-deprecated",\r
+ "no-des",\r
"no-dgram",\r
"no-dsa",\r
"no-dynamic-engine",\r
- "no-ec",\r
"no-ec2m",\r
"no-engine",\r
"no-err",\r
"no-gost",\r
"no-hw",\r
"no-idea",\r
+ "no-md4",\r
"no-mdc2",\r
"no-pic",\r
"no-ocb",\r
"no-poly1305",\r
"no-posix-io",\r
"no-rc2",\r
+ "no-rc4",\r
"no-rfc3779",\r
"no-rmd160",\r
"no-scrypt",\r
"no-threads",\r
"no-ts",\r
"no-ui",\r
- "no-whirlpool"\r
+ "no-whirlpool",\r
+ # OpenSSL1_1_1b doesn't support default rand-seed-os for UEFI\r
+ # UEFI only support --with-rand-seed=none\r
+ "--with-rand-seed=none"\r
) == 0 ||\r
die "OpenSSL Configure failed!\n";\r
\r
) == 0 ||\r
die "Failed to generate opensslconf.h!\n";\r
\r
+ # Generate dso_conf.h per config data\r
+ system(\r
+ "perl -I. -Mconfigdata util/dofile.pl " .\r
+ "include/crypto/dso_conf.h.in " .\r
+ "> include/crypto/dso_conf.h"\r
+ ) == 0 ||\r
+ die "Failed to generate dso_conf.h!\n";\r
+\r
chdir($basedir) ||\r
die "Cannot change to base directory \"" . $basedir . "\"";\r
\r
# Retrieve file lists from OpenSSL configdata\r
#\r
use configdata qw/%unified_info/;\r
+use configdata qw/%config/;\r
+use configdata qw/%target/;\r
+\r
+#\r
+# Collect build flags from configdata\r
+#\r
+my $flags = "";\r
+foreach my $f (@{$config{lib_defines}}) {\r
+ $flags .= " -D$f";\r
+}\r
\r
my @cryptofilelist = ();\r
my @sslfilelist = ();\r
+my @asmfilelist = ();\r
+my @asmbuild = ();\r
foreach my $product ((@{$unified_info{libraries}},\r
@{$unified_info{engines}})) {\r
foreach my $o (@{$unified_info{sources}->{$product}}) {\r
foreach my $s (@{$unified_info{sources}->{$o}}) {\r
- next if ($unified_info{generate}->{$s});\r
+ # No need to add unused files in UEFI.\r
+ # So it can reduce porting time, compile time, library size.\r
next if $s =~ "crypto/bio/b_print.c";\r
+ next if $s =~ "crypto/rand/randfile.c";\r
+ next if $s =~ "crypto/store/";\r
+ next if $s =~ "crypto/err/err_all.c";\r
+ next if $s =~ "crypto/aes/aes_ecb.c";\r
+\r
+ if ($unified_info{generate}->{$s}) {\r
+ if (defined $arch) {\r
+ my $buildstring = "perl";\r
+ foreach my $arg (@{$unified_info{generate}->{$s}}) {\r
+ if ($arg =~ ".pl") {\r
+ $buildstring .= " ./openssl/$arg";\r
+ } elsif ($arg =~ "PERLASM_SCHEME") {\r
+ $buildstring .= " $target{perlasm_scheme}";\r
+ } elsif ($arg =~ "LIB_CFLAGS") {\r
+ $buildstring .= "$flags";\r
+ }\r
+ }\r
+ ($s, my $path, undef) = fileparse($s, qr/\.[^.]*/);\r
+ $buildstring .= " ./$arch/$path$s.$extension";\r
+ make_path ("./$arch/$path");\r
+ push @asmbuild, "$buildstring\n";\r
+ push @asmfilelist, " $arch/$path$s.$extension\r\n";\r
+ }\r
+ next;\r
+ }\r
if ($product =~ "libssl") {\r
push @sslfilelist, ' $(OPENSSL_PATH)/' . $s . "\r\n";\r
next;\r
}\r
- push @cryptofilelist, ' $(OPENSSL_PATH)/' . $s . "\r\n";\r
+ push @cryptofilelist, ' $(OPENSSL_PATH)/' . $s;\r
+ foreach (keys(%conditional_feature_dir)) {\r
+ if ($s =~ $_) {\r
+ push @cryptofilelist, ' |*|*|*|gEfiCryptoPkgTokenSpaceGuid.' . $conditional_feature_dir{$_};\r
+ }\r
+ }\r
+ push @cryptofilelist, "\r\n";\r
}\r
}\r
}\r
\r
+\r
+#\r
+# Update the perl script to generate the missing header files\r
+#\r
+my @dir_list = ();\r
+for (sort keys %{$unified_info{dirinfo}}){\r
+ push @dir_list,$_;\r
+}\r
+\r
+my $dir = getcwd();\r
+my @files = ();\r
+my @headers = ();\r
+chdir ("openssl");\r
+foreach(@dir_list){\r
+ @files = glob($_."/*.h");\r
+ push @headers, @files;\r
+}\r
+chdir ($dir);\r
+\r
+foreach (@headers){\r
+ if(/ssl/){\r
+ push @sslfilelist, ' $(OPENSSL_PATH)/' . $_ . "\r\n";\r
+ next;\r
+ }\r
+ push @cryptofilelist, ' $(OPENSSL_PATH)/' . $_;\r
+ foreach my $conditional_key (keys(%conditional_feature_dir)) {\r
+ if ($_ =~ $conditional_key) {\r
+ push @cryptofilelist, ' |*|*|*|gEfiCryptoPkgTokenSpaceGuid.' . $conditional_feature_dir{$conditional_key};\r
+ }\r
+ }\r
+ push @cryptofilelist, "\r\n";\r
+}\r
+\r
+\r
+#\r
+# Generate assembly files\r
+#\r
+if (@asmbuild) {\r
+ print "\n--> Generating assembly files ... ";\r
+ foreach my $buildstring (@asmbuild) {\r
+ system ("$buildstring");\r
+ copy_license_header ($buildstring);\r
+ }\r
+ print "Done!";\r
+}\r
+\r
#\r
# Update OpensslLib.inf with autogenerated file list\r
#\r
my @new_inf = ();\r
my $subbing = 0;\r
-print "\n--> Updating OpensslLib.inf ... ";\r
+print "\n--> Updating $inf_file ... ";\r
foreach (@inf) {\r
+ if ($_ =~ "DEFINE OPENSSL_FLAGS_CONFIG") {\r
+ push @new_inf, " DEFINE OPENSSL_FLAGS_CONFIG =" . $flags . "\r\n";\r
+ next;\r
+ }\r
if ( $_ =~ "# Autogenerated files list starts here" ) {\r
- push @new_inf, $_, @cryptofilelist, @sslfilelist;\r
+ push @new_inf, $_, @asmfilelist, @cryptofilelist, @sslfilelist;\r
$subbing = 1;\r
next;\r
}\r
die "rename $inf_file";\r
print "Done!";\r
\r
+if (!defined $arch) {\r
+ #\r
+ # Update OpensslLibCrypto.inf with auto-generated file list (no libssl)\r
+ #\r
+ $inf_file = "OpensslLibCrypto.inf";\r
+\r
+ # Read the contents of the inf file\r
+ @inf = ();\r
+ @new_inf = ();\r
+ open( FD, "<" . $inf_file ) ||\r
+ die "Cannot open \"" . $inf_file . "\"!";\r
+ @inf = (<FD>);\r
+ close(FD) ||\r
+ die "Cannot close \"" . $inf_file . "\"!";\r
+\r
+ $subbing = 0;\r
+ print "\n--> Updating OpensslLibCrypto.inf ... ";\r
+ foreach (@inf) {\r
+ if ( $_ =~ "# Autogenerated files list starts here" ) {\r
+ push @new_inf, $_, @cryptofilelist;\r
+ $subbing = 1;\r
+ next;\r
+ }\r
+ if ( $_ =~ "# Autogenerated files list ends here" ) {\r
+ push @new_inf, $_;\r
+ $subbing = 0;\r
+ next;\r
+ }\r
+\r
+ push @new_inf, $_\r
+ unless ($subbing);\r
+ }\r
+\r
+ $new_inf_file = $inf_file . ".new";\r
+ open( FD, ">" . $new_inf_file ) ||\r
+ die $new_inf_file;\r
+ print( FD @new_inf ) ||\r
+ die $new_inf_file;\r
+ close(FD) ||\r
+ die $new_inf_file;\r
+ rename( $new_inf_file, $inf_file ) ||\r
+ die "rename $inf_file";\r
+ print "Done!";\r
+}\r
+\r
#\r
-# Update OpensslLibCrypto.inf with auto-generated file list (no libssl)\r
+# Copy opensslconf.h and dso_conf.h generated from OpenSSL Configuration\r
#\r
-$inf_file = "OpensslLibCrypto.inf";\r
+print "\n--> Duplicating opensslconf.h into Include/openssl ... ";\r
+system(\r
+ "perl -pe 's/\\n/\\r\\n/' " .\r
+ "< " . $OPENSSL_PATH . "/include/openssl/opensslconf.h " .\r
+ "> " . $OPENSSL_PATH . "/../../Include/openssl/opensslconf_generated.h"\r
+ ) == 0 ||\r
+ die "Cannot copy opensslconf.h!";\r
+print "Done!";\r
\r
-# Read the contents of the inf file\r
-@inf = ();\r
-@new_inf = ();\r
-open( FD, "<" . $inf_file ) ||\r
- die "Cannot open \"" . $inf_file . "\"!";\r
-@inf = (<FD>);\r
-close(FD) ||\r
- die "Cannot close \"" . $inf_file . "\"!";\r
+print "\n--> Duplicating dso_conf.h into Include/crypto ... ";\r
+system(\r
+ "perl -pe 's/\\n/\\r\\n/' " .\r
+ "< " . $OPENSSL_PATH . "/include/crypto/dso_conf.h" .\r
+ "> " . $OPENSSL_PATH . "/../../Include/crypto/dso_conf.h"\r
+ ) == 0 ||\r
+ die "Cannot copy dso_conf.h!";\r
+print "Done!";\r
\r
-$subbing = 0;\r
-print "\n--> Updating OpensslLibCrypto.inf ... ";\r
-foreach (@inf) {\r
- if ( $_ =~ "# Autogenerated files list starts here" ) {\r
- push @new_inf, $_, @cryptofilelist;\r
+#\r
+# Add conditional feature to opensslconf.h\r
+#\r
+my $conf_file = "../Include/openssl/opensslconf.h";\r
+my @conf_raw = ();\r
+my @conditional_define = ();\r
+print "\n--> Updating conditional feature in $conf_file ... ";\r
+\r
+foreach my $pcd_name (keys(%conditional_feature)) {\r
+ push @conditional_define, "#if !FixedPcdGetBool ($pcd_name)\r\n";\r
+ foreach (@{$conditional_feature{$pcd_name}}) {\r
+ push @conditional_define, "# ifndef OPENSSL_NO_$_\r\n";\r
+ push @conditional_define, "# define OPENSSL_NO_$_\r\n";\r
+ push @conditional_define, "# endif\r\n";\r
+ }\r
+ push @conditional_define, "#endif\r\n";\r
+}\r
+\r
+open( FD, "<" . $conf_file ) ||\r
+ die $conf_file;\r
+foreach (<FD>) {\r
+ # Insert conditional define to the begin of opensslconf.h\r
+ if ($_ =~ "Autogenerated conditional openssl feature list starts here") {\r
+ push @conf_raw, $_, @conditional_define;\r
$subbing = 1;\r
next;\r
}\r
- if ( $_ =~ "# Autogenerated files list ends here" ) {\r
- push @new_inf, $_;\r
+ if ($_ =~ "Autogenerated conditional openssl feature list ends here") {\r
+ push @conf_raw, $_;\r
$subbing = 0;\r
next;\r
}\r
-\r
- push @new_inf, $_\r
+ push @conf_raw, $_\r
unless ($subbing);\r
}\r
-\r
-$new_inf_file = $inf_file . ".new";\r
-open( FD, ">" . $new_inf_file ) ||\r
- die $new_inf_file;\r
-print( FD @new_inf ) ||\r
- die $new_inf_file;\r
close(FD) ||\r
- die $new_inf_file;\r
-rename( $new_inf_file, $inf_file ) ||\r
- die "rename $inf_file";\r
-print "Done!";\r
+ die $conf_file;\r
\r
-#\r
-# Copy opensslconf.h generated from OpenSSL Configuration\r
-#\r
-print "\n--> Duplicating opensslconf.h into Include/openssl ... ";\r
-copy($OPENSSL_PATH . "/include/openssl/opensslconf.h",\r
- $OPENSSL_PATH . "/../../Include/openssl/") ||\r
- die "Cannot copy opensslconf.h!";\r
+open( FD, ">" . $conf_file ) ||\r
+ die $conf_file;\r
+print( FD @conf_raw ) ||\r
+ die $conf_file;\r
+close(FD) ||\r
+ die $conf_file;\r
print "Done!\n";\r
\r
print "\nProcessing Files Done!\n";\r