]> git.proxmox.com Git - mirror_edk2.git/blob - CryptoPkg/Library/OpensslLib/process_files.pl
CryptoPkg/OpensslLib: Commit the auto-generated assembly files for IA32
[mirror_edk2.git] / CryptoPkg / Library / OpensslLib / process_files.pl
1 #!/usr/bin/perl -w
2 #
3 # This script runs the OpenSSL Configure script, then processes the
4 # resulting file list into our local OpensslLib[Crypto].inf and also
5 # takes copies of opensslconf.h and dso_conf.h.
6 #
7 # This only needs to be done once by a developer when updating to a
8 # new version of OpenSSL (or changing options, etc.). Normal users
9 # do not need to do this, since the results are stored in the EDK2
10 # git repository for them.
11 #
12 # Due to the script wrapping required to process the OpenSSL
13 # configuration data, each native architecture must be processed
14 # individually by the maintainer (in addition to the standard version):
15 # ./process_files.pl
16 # ./process_files.pl X64
17 # ./process_files.pl [Arch]
18
19 use strict;
20 use Cwd;
21 use File::Copy;
22 use File::Basename;
23 use File::Path qw(make_path remove_tree);
24 use Text::Tabs;
25
26 my $comment_character;
27
28 #
29 # OpenSSL perlasm generator script does not transfer the copyright header
30 #
31 sub copy_license_header
32 {
33 my @args = split / /, shift; #Separate args by spaces
34 my $source = $args[1]; #Source file is second (after "perl")
35 my $target = pop @args; #Target file is always last
36 chop ($target); #Remove newline char
37
38 my $temp_file_name = "license.tmp";
39 open (my $source_file, "<" . $source) || die $source;
40 open (my $target_file, "<" . $target) || die $target;
41 open (my $temp_file, ">" . $temp_file_name) || die $temp_file_name;
42
43 #Add "generated file" warning
44 $source =~ s/^..//; #Remove leading "./"
45 print ($temp_file "$comment_character WARNING: do not edit!\r\n");
46 print ($temp_file "$comment_character Generated from $source\r\n");
47 print ($temp_file "$comment_character\r\n");
48
49 #Copy source file header to temp file
50 while (my $line = <$source_file>) {
51 next if ($line =~ /#!/); #Ignore shebang line
52 $line =~ s/#/$comment_character/; #Fix comment character for assembly
53 $line =~ s/\s+$/\r\n/; #Trim trailing whitepsace, fixup line endings
54 print ($temp_file $line);
55 last if ($line =~ /http/); #Last line of copyright header contains a web link
56 }
57 print ($temp_file "\r\n");
58 #Retrieve generated assembly contents
59 while (my $line = <$target_file>) {
60 $line =~ s/\s+$/\r\n/; #Trim trailing whitepsace, fixup line endings
61 print ($temp_file expand ($line)); #expand() replaces tabs with spaces
62 }
63
64 close ($source_file);
65 close ($target_file);
66 close ($temp_file);
67
68 move ($temp_file_name, $target) ||
69 die "Cannot replace \"" . $target . "\"!";
70 }
71
72 #
73 # Find the openssl directory name for use lib. We have to do this
74 # inside of BEGIN. The variables we create here, however, don't seem
75 # to be available to the main script, so we have to repeat the
76 # exercise.
77 #
78 my $inf_file;
79 my $OPENSSL_PATH;
80 my $uefi_config;
81 my $extension;
82 my $arch;
83 my @inf;
84 #
85 # Use PCD to conditionally enable certain openssl features.
86 # $conditional_feature contains pcd_name:fetures_names pairs
87 # of conditional features.
88 # @conditional_feature_dir contains relative_path:pcd_name pairs
89 # of conditional features in openssl, MUST correspond to the content
90 # in $conditional_feature.
91 #
92 # Configure list [openssl_configuration : new_define_list : new_file_list : pcd]
93 # 1. no-ec : {NO_EC, NO_ECDH, NO_ECDSA, NO_TLS1_3, NO_SM2} : {/ec/, /sm2/} : PcdOpensslEcEnabled
94 #
95 my %conditional_feature = ("PcdOpensslEcEnabled"=>["EC", "ECDH", "ECDSA", "TLS1_3", "SM2"]);
96 my %conditional_feature_dir = ("/ec/"=>"PcdOpensslEcEnabled", "/sm2/"=>"PcdOpensslEcEnabled");
97
98 BEGIN {
99 $inf_file = "OpensslLib.inf";
100 $uefi_config = "UEFI";
101 $arch = shift;
102
103 if (defined $arch) {
104 if (uc ($arch) eq "X64") {
105 $arch = "X64";
106 $inf_file = "OpensslLibX64.inf";
107 $uefi_config = "UEFI-x86_64";
108 $extension = "nasm";
109 $comment_character = ";";
110 } elsif (uc ($arch) eq "X64GCC") {
111 $arch = "X64Gcc";
112 $inf_file = "OpensslLibX64Gcc.inf";
113 $uefi_config = "UEFI-x86_64-GCC";
114 $extension = "S";
115 $comment_character = "#";
116 } elsif (uc ($arch) eq "IA32") {
117 $arch = "IA32";
118 $inf_file = "OpensslLibIa32.inf";
119 $uefi_config = "UEFI-x86";
120 $extension = "nasm";
121 $comment_character = ";";
122 } elsif (uc ($arch) eq "IA32GCC") {
123 $arch = "IA32Gcc";
124 $inf_file = "OpensslLibIa32Gcc.inf";
125 $uefi_config = "UEFI-x86-GCC";
126 $extension = "S";
127 $comment_character = "#";
128 } else {
129 die "Unsupported architecture \"" . $arch . "\"!";
130 }
131 if ($extension eq "nasm") {
132 if (`nasm -v 2>&1`) {
133 #Presence of nasm executable will trigger inclusion of AVX instructions
134 die "\nCannot run assembly generators with NASM in path!\n\n";
135 }
136 }
137
138 # Prepare assembly folder
139 if (-d $arch) {
140 opendir my $dir, $arch ||
141 die "Cannot open assembly folder \"" . $arch . "\"!";
142 while (defined (my $file = readdir $dir)) {
143 if (-d "$arch/$file") {
144 next if $file eq ".";
145 next if $file eq "..";
146 remove_tree ("$arch/$file", {safe => 1}) ||
147 die "Cannot clean assembly folder \"" . "$arch/$file" . "\"!";
148 }
149 }
150
151 } else {
152 mkdir $arch ||
153 die "Cannot create assembly folder \"" . $arch . "\"!";
154 }
155 }
156
157 # Read the contents of the inf file
158 open( FD, "<" . $inf_file ) ||
159 die "Cannot open \"" . $inf_file . "\"!";
160 @inf = (<FD>);
161 close(FD) ||
162 die "Cannot close \"" . $inf_file . "\"!";
163
164 foreach (@inf) {
165 if (/DEFINE\s+OPENSSL_PATH\s*=\s*([a-z]+)/) {
166
167 # We need to run Configure before we can include its result...
168 $OPENSSL_PATH = $1;
169
170 my $basedir = getcwd();
171
172 chdir($OPENSSL_PATH) ||
173 die "Cannot change to OpenSSL directory \"" . $OPENSSL_PATH . "\"";
174
175 # Configure UEFI
176 system(
177 "./Configure",
178 "--config=../UefiAsm.conf",
179 "$uefi_config",
180 "no-afalgeng",
181 "no-async",
182 "no-autoerrinit",
183 "no-autoload-config",
184 "no-bf",
185 "no-blake2",
186 "no-camellia",
187 "no-capieng",
188 "no-cast",
189 "no-chacha",
190 "no-cms",
191 "no-ct",
192 "no-deprecated",
193 "no-des",
194 "no-dgram",
195 "no-dsa",
196 "no-dynamic-engine",
197 "no-ec2m",
198 "no-engine",
199 "no-err",
200 "no-filenames",
201 "no-gost",
202 "no-hw",
203 "no-idea",
204 "no-md4",
205 "no-mdc2",
206 "no-pic",
207 "no-ocb",
208 "no-poly1305",
209 "no-posix-io",
210 "no-rc2",
211 "no-rc4",
212 "no-rfc3779",
213 "no-rmd160",
214 "no-scrypt",
215 "no-seed",
216 "no-sock",
217 "no-srp",
218 "no-ssl",
219 "no-stdio",
220 "no-threads",
221 "no-ts",
222 "no-ui",
223 "no-whirlpool",
224 # OpenSSL1_1_1b doesn't support default rand-seed-os for UEFI
225 # UEFI only support --with-rand-seed=none
226 "--with-rand-seed=none"
227 ) == 0 ||
228 die "OpenSSL Configure failed!\n";
229
230 # Generate opensslconf.h per config data
231 system(
232 "perl -I. -Mconfigdata util/dofile.pl " .
233 "include/openssl/opensslconf.h.in " .
234 "> include/openssl/opensslconf.h"
235 ) == 0 ||
236 die "Failed to generate opensslconf.h!\n";
237
238 # Generate dso_conf.h per config data
239 system(
240 "perl -I. -Mconfigdata util/dofile.pl " .
241 "include/crypto/dso_conf.h.in " .
242 "> include/crypto/dso_conf.h"
243 ) == 0 ||
244 die "Failed to generate dso_conf.h!\n";
245
246 chdir($basedir) ||
247 die "Cannot change to base directory \"" . $basedir . "\"";
248
249 push @INC, $1;
250 last;
251 }
252 }
253 }
254
255 #
256 # Retrieve file lists from OpenSSL configdata
257 #
258 use configdata qw/%unified_info/;
259 use configdata qw/%config/;
260 use configdata qw/%target/;
261
262 #
263 # Collect build flags from configdata
264 #
265 my $flags = "";
266 foreach my $f (@{$config{lib_defines}}) {
267 $flags .= " -D$f";
268 }
269
270 my @cryptofilelist = ();
271 my @sslfilelist = ();
272 my @asmfilelist = ();
273 my @asmbuild = ();
274 foreach my $product ((@{$unified_info{libraries}},
275 @{$unified_info{engines}})) {
276 foreach my $o (@{$unified_info{sources}->{$product}}) {
277 foreach my $s (@{$unified_info{sources}->{$o}}) {
278 # No need to add unused files in UEFI.
279 # So it can reduce porting time, compile time, library size.
280 next if $s =~ "crypto/bio/b_print.c";
281 next if $s =~ "crypto/rand/randfile.c";
282 next if $s =~ "crypto/store/";
283 next if $s =~ "crypto/err/err_all.c";
284 next if $s =~ "crypto/aes/aes_ecb.c";
285
286 if ($unified_info{generate}->{$s}) {
287 if (defined $arch) {
288 my $buildstring = "perl";
289 foreach my $arg (@{$unified_info{generate}->{$s}}) {
290 if ($arg =~ ".pl") {
291 $buildstring .= " ./openssl/$arg";
292 } elsif ($arg =~ "PERLASM_SCHEME") {
293 $buildstring .= " $target{perlasm_scheme}";
294 } elsif ($arg =~ "LIB_CFLAGS") {
295 $buildstring .= "$flags";
296 }
297 }
298 ($s, my $path, undef) = fileparse($s, qr/\.[^.]*/);
299 $buildstring .= " ./$arch/$path$s.$extension";
300 make_path ("./$arch/$path");
301 push @asmbuild, "$buildstring\n";
302 push @asmfilelist, " $arch/$path$s.$extension\r\n";
303 }
304 next;
305 }
306 if ($product =~ "libssl") {
307 push @sslfilelist, ' $(OPENSSL_PATH)/' . $s . "\r\n";
308 next;
309 }
310 push @cryptofilelist, ' $(OPENSSL_PATH)/' . $s;
311 foreach (keys(%conditional_feature_dir)) {
312 if ($s =~ $_) {
313 push @cryptofilelist, ' |*|*|*|gEfiCryptoPkgTokenSpaceGuid.' . $conditional_feature_dir{$_};
314 }
315 }
316 push @cryptofilelist, "\r\n";
317 }
318 }
319 }
320
321
322 #
323 # Update the perl script to generate the missing header files
324 #
325 my @dir_list = ();
326 for (sort keys %{$unified_info{dirinfo}}){
327 push @dir_list,$_;
328 }
329
330 my $dir = getcwd();
331 my @files = ();
332 my @headers = ();
333 chdir ("openssl");
334 foreach(@dir_list){
335 @files = glob($_."/*.h");
336 push @headers, @files;
337 }
338 chdir ($dir);
339
340 foreach (@headers){
341 if(/ssl/){
342 push @sslfilelist, ' $(OPENSSL_PATH)/' . $_ . "\r\n";
343 next;
344 }
345 push @cryptofilelist, ' $(OPENSSL_PATH)/' . $_;
346 foreach my $conditional_key (keys(%conditional_feature_dir)) {
347 if ($_ =~ $conditional_key) {
348 push @cryptofilelist, ' |*|*|*|gEfiCryptoPkgTokenSpaceGuid.' . $conditional_feature_dir{$conditional_key};
349 }
350 }
351 push @cryptofilelist, "\r\n";
352 }
353
354
355 #
356 # Generate assembly files
357 #
358 if (@asmbuild) {
359 print "\n--> Generating assembly files ... ";
360 foreach my $buildstring (@asmbuild) {
361 system ("$buildstring");
362 copy_license_header ($buildstring);
363 }
364 print "Done!";
365 }
366
367 #
368 # Update OpensslLib.inf with autogenerated file list
369 #
370 my @new_inf = ();
371 my $subbing = 0;
372 print "\n--> Updating $inf_file ... ";
373 foreach (@inf) {
374 if ($_ =~ "DEFINE OPENSSL_FLAGS_CONFIG") {
375 push @new_inf, " DEFINE OPENSSL_FLAGS_CONFIG =" . $flags . "\r\n";
376 next;
377 }
378 if ( $_ =~ "# Autogenerated files list starts here" ) {
379 push @new_inf, $_, @asmfilelist, @cryptofilelist, @sslfilelist;
380 $subbing = 1;
381 next;
382 }
383 if ( $_ =~ "# Autogenerated files list ends here" ) {
384 push @new_inf, $_;
385 $subbing = 0;
386 next;
387 }
388
389 push @new_inf, $_
390 unless ($subbing);
391 }
392
393 my $new_inf_file = $inf_file . ".new";
394 open( FD, ">" . $new_inf_file ) ||
395 die $new_inf_file;
396 print( FD @new_inf ) ||
397 die $new_inf_file;
398 close(FD) ||
399 die $new_inf_file;
400 rename( $new_inf_file, $inf_file ) ||
401 die "rename $inf_file";
402 print "Done!";
403
404 if (!defined $arch) {
405 #
406 # Update OpensslLibCrypto.inf with auto-generated file list (no libssl)
407 #
408 $inf_file = "OpensslLibCrypto.inf";
409
410 # Read the contents of the inf file
411 @inf = ();
412 @new_inf = ();
413 open( FD, "<" . $inf_file ) ||
414 die "Cannot open \"" . $inf_file . "\"!";
415 @inf = (<FD>);
416 close(FD) ||
417 die "Cannot close \"" . $inf_file . "\"!";
418
419 $subbing = 0;
420 print "\n--> Updating OpensslLibCrypto.inf ... ";
421 foreach (@inf) {
422 if ( $_ =~ "# Autogenerated files list starts here" ) {
423 push @new_inf, $_, @cryptofilelist;
424 $subbing = 1;
425 next;
426 }
427 if ( $_ =~ "# Autogenerated files list ends here" ) {
428 push @new_inf, $_;
429 $subbing = 0;
430 next;
431 }
432
433 push @new_inf, $_
434 unless ($subbing);
435 }
436
437 $new_inf_file = $inf_file . ".new";
438 open( FD, ">" . $new_inf_file ) ||
439 die $new_inf_file;
440 print( FD @new_inf ) ||
441 die $new_inf_file;
442 close(FD) ||
443 die $new_inf_file;
444 rename( $new_inf_file, $inf_file ) ||
445 die "rename $inf_file";
446 print "Done!";
447 }
448
449 #
450 # Copy opensslconf.h and dso_conf.h generated from OpenSSL Configuration
451 #
452 print "\n--> Duplicating opensslconf.h into Include/openssl ... ";
453 system(
454 "perl -pe 's/\\n/\\r\\n/' " .
455 "< " . $OPENSSL_PATH . "/include/openssl/opensslconf.h " .
456 "> " . $OPENSSL_PATH . "/../../Include/openssl/opensslconf_generated.h"
457 ) == 0 ||
458 die "Cannot copy opensslconf.h!";
459 print "Done!";
460
461 print "\n--> Duplicating dso_conf.h into Include/crypto ... ";
462 system(
463 "perl -pe 's/\\n/\\r\\n/' " .
464 "< " . $OPENSSL_PATH . "/include/crypto/dso_conf.h" .
465 "> " . $OPENSSL_PATH . "/../../Include/crypto/dso_conf.h"
466 ) == 0 ||
467 die "Cannot copy dso_conf.h!";
468 print "Done!";
469
470 #
471 # Add conditional feature to opensslconf.h
472 #
473 my $conf_file = "../Include/openssl/opensslconf.h";
474 my @conf_raw = ();
475 my @conditional_define = ();
476 print "\n--> Updating conditional feature in $conf_file ... ";
477
478 foreach my $pcd_name (keys(%conditional_feature)) {
479 push @conditional_define, "#if !FixedPcdGetBool ($pcd_name)\r\n";
480 foreach (@{$conditional_feature{$pcd_name}}) {
481 push @conditional_define, "# ifndef OPENSSL_NO_$_\r\n";
482 push @conditional_define, "# define OPENSSL_NO_$_\r\n";
483 push @conditional_define, "# endif\r\n";
484 }
485 push @conditional_define, "#endif\r\n";
486 }
487
488 open( FD, "<" . $conf_file ) ||
489 die $conf_file;
490 foreach (<FD>) {
491 # Insert conditional define to the begin of opensslconf.h
492 if ($_ =~ "Autogenerated conditional openssl feature list starts here") {
493 push @conf_raw, $_, @conditional_define;
494 $subbing = 1;
495 next;
496 }
497 if ($_ =~ "Autogenerated conditional openssl feature list ends here") {
498 push @conf_raw, $_;
499 $subbing = 0;
500 next;
501 }
502 push @conf_raw, $_
503 unless ($subbing);
504 }
505 close(FD) ||
506 die $conf_file;
507
508 open( FD, ">" . $conf_file ) ||
509 die $conf_file;
510 print( FD @conf_raw ) ||
511 die $conf_file;
512 close(FD) ||
513 die $conf_file;
514 print "Done!\n";
515
516 print "\nProcessing Files Done!\n";
517
518 exit(0);
519