Add 'fips-securitychecks' option and plumb this into the actual fips checks
[openssl.git] / Configure
index a0b9c22b6d08d33097852ce657d1150515a94570..22c0ecdabd1b162c247a8e223162d9127ff58b0a 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -20,6 +20,7 @@ use File::Path qw/mkpath/;
 use OpenSSL::fallback "$FindBin::Bin/external/perl/MODULES.txt";
 use OpenSSL::Glob;
 use OpenSSL::Template;
+use OpenSSL::config;
 
 # see INSTALL.md for instructions.
 
@@ -189,7 +190,7 @@ my $apitable = {
     # The numbering used changes from 3.0 and on because we updated
     # (solidified) our version numbering scheme at that point.
 
-    # From 3.0 and on, we internalise the given version number in dedcimal
+    # From 3.0 and on, we internalise the given version number in decimal
     # as MAJOR * 10000 + MINOR * 100 + 0
     "3.0.0" => 30000,
     "3.0"   => 30000,
@@ -204,6 +205,11 @@ my $apitable = {
     "0.9.8" =>   908,
 };
 
+# For OpenSSL::config::get_platform
+my %guess_opts = ();
+
+my $dryrun = 0;
+
 our %table = ();
 our %config = ();
 our %withargs = ();
@@ -232,12 +238,25 @@ sub resolve_config;
 # Unified build supports separate build dir
 my $srcdir = catdir(absolutedir(dirname($0))); # catdir ensures local syntax
 my $blddir = catdir(absolutedir("."));         # catdir ensures local syntax
+
+# File::Spec::Unix doesn't detect case insensitivity, so we make sure to
+# check if the source and build directory are really the same, and make
+# them so.  This avoids all kinds of confusion later on.
+# We must check @File::Spec::ISA rather than using File::Spec->isa() to
+# know if File::Spec ended up loading File::Spec::Unix.
+$srcdir = $blddir
+    if (grep(/::Unix$/, @File::Spec::ISA)
+        && samedir($srcdir, $blddir));
+
 my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
 
 my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
 
-$config{sourcedir} = abs2rel($srcdir);
-$config{builddir} = abs2rel($blddir);
+$config{sourcedir} = abs2rel($srcdir, $blddir);
+$config{builddir} = abs2rel($blddir, $blddir);
+# echo -n 'holy hand grenade of antioch' | openssl sha256
+$config{FIPSKEY} =
+    'f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813';
 
 # Collect reconfiguration information if needed
 my @argvcopy=@ARGV;
@@ -282,7 +301,7 @@ foreach ( reverse sort( 'aes', 'aria', 'bf', 'camellia', 'cast', 'des', 'dh',
 my %version = ();
 
 collect_information(
-    collect_from_file(catfile($srcdir,'VERSION')),
+    collect_from_file(catfile($srcdir,'VERSION.dat')),
     qr/\s*(\w+)\s*=\s*(.*?)\s*$/ =>
         sub {
             # Only define it if there is a value at all
@@ -295,7 +314,7 @@ collect_information(
             }
         },
     "OTHERWISE" =>
-        sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION" },
+        sub { die "Something wrong with this line:\n$_\nin $srcdir/VERSION.dat" },
     );
 
 $config{major} = $version{MAJOR} // 'unknown';
@@ -311,7 +330,7 @@ $config{release_date} = $version{RELEASE_DATE} // 'xx XXX xxxx';
 $config{version} = "$config{major}.$config{minor}.$config{patch}";
 $config{full_version} = "$config{version}$config{prerelease}$config{build_metadata}";
 
-die "erroneous version information in VERSION: ",
+die "erroneous version information in VERSION.dat: ",
     "$config{version}, $config{shlib_version}\n"
     unless (defined $version{MAJOR}
             && defined $version{MINOR}
@@ -402,6 +421,7 @@ my @disablables = (
     "external-tests",
     "filenames",
     "fips",
+    "fips-securitychecks",
     "fuzz-libfuzzer",
     "fuzz-afl",
     "gost",
@@ -581,9 +601,8 @@ my @disable_cascades = (
 
     "cmp"               => [ "crmf" ],
 
-    # Padlock engine uses low-level AES APIs which are deprecated
     sub { $disabled{"deprecated-3.0"} }
-          => [ "padlockeng" ]
+          => [ "engine" ]
     );
 
 # Avoid protocol support holes.  Also disable all versions below N, if version
@@ -608,8 +627,6 @@ while ((my $first, my $second) = (shift @list, shift @list)) {
 # To remove something from %disabled, use "enable-foo".
 # For symmetry, "disable-foo" is a synonym for "no-foo".
 
-&usage if ($#ARGV < 0);
-
 # For the "make variables" CPPINCLUDES and CPPDEFINES, we support lists with
 # platform specific list separators.  Users from those platforms should
 # recognise those separators from how you set up the PATH to find executables.
@@ -835,6 +852,22 @@ while (@argvcopy)
                 # No longer an automatic choice
                 $auto_threads = 0 if ($1 eq "threads");
                 }
+        elsif (/^-d$/)          # From older 'config'
+                {
+                $config{build_type} = "debug";
+                }
+        elsif (/^-v$/)          # From older 'config'
+                {
+                $guess_opts{verbose} = 1;
+                }
+        elsif (/^-w$/)          # From older 'config'
+                {
+                $guess_opts{nowait} = 1;
+                }
+        elsif (/^-t$/)          # From older 'config'
+                {
+                $dryrun = 1;
+                }
         elsif (/^--strict-warnings$/)
                 {
                 # Pretend that our strict flags is a C flag, and replace it
@@ -914,6 +947,16 @@ while (@argvcopy)
                             push @seed_sources, $x;
                             }
                         }
+                elsif (/^--fips-key=(.*)$/)
+                        {
+                        $user{FIPSKEY}=lc($1);
+                        die "Non-hex character in FIPS key\n"
+                           if $user{FIPSKEY} =~ /[^a-f0-9]/;
+                        die "FIPS key must have even number of characters\n"
+                           if length $1 & 1;
+                        die "FIPS key too long (64 bytes max)\n"
+                           if length $1 > 64;
+                        }
                 elsif (/^--cross-compile-prefix=(.*)$/)
                         {
                         $user{CROSS_COMPILE}=$1;
@@ -1068,6 +1111,23 @@ if (grep { /-rpath\b/ } ($user{LDFLAGS} ? @{$user{LDFLAGS}} : ())
         "***** any of asan, msan or ubsan\n";
 }
 
+# If no target was given, try guessing.
+unless ($target) {
+    my %system_config = OpenSSL::config::get_platform(%guess_opts, %user);
+
+    # The $system_config{disable} is used to populate %disabled with
+    # entries that aren't already there.
+    foreach ( @{$system_config{disable} // []} ) {
+        $disabled{$_} = 'system' unless defined $disabled{$_};
+    }
+    delete $system_config{disable};
+
+    # Override config entries with stuff from the guesser.
+    # It's assumed that this really is nothing new.
+    %config = ( %config, %system_config );
+    $target = $system_config{target};
+}
+
 sub disable {
     my $disable_type = shift;
 
@@ -1166,7 +1226,26 @@ if ($d) {
     }
 }
 
-&usage if !$table{$target} || $table{$target}->{template};
+if ($target) {
+    # It's possible that we have different config targets for specific
+    # toolchains, so we try to detect them, and go for the plain config
+    # target if not.
+    my $found;
+    foreach ( ( "$target-$user{CC}", "$target", undef ) ) {
+        $found=$_ if $table{$_} && !$table{$_}->{template};
+        last if $found;
+    }
+    $target = $found;
+} else {
+    # If we don't have a config target now, we try the C compiler as we
+    # fallback
+    my $cc = $user{CC} // 'cc';
+    $target = $cc if $table{$cc} && !$table{$cc}->{template};
+}
+
+&usage unless $target;
+
+exit 0 if $dryrun;              # From older 'config'
 
 $config{target} = $target;
 my %target = resolve_config($target);
@@ -1899,10 +1978,10 @@ if ($builder eq "unified") {
                 my $ac = 1;
                 my $ak = $a;
                 my $av = 1;
-                if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|) {
+                if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|x) {
                     $ac = ! $1;
-                    $ak = $1;
-                    $av = $2;
+                    $ak = $2;
+                    $av = $3;
                 }
                 foreach my $g (@goals) {
                     if ($ac) {
@@ -2660,7 +2739,7 @@ sub death_handler {
     my @message = ( <<"_____", @_ );
 
 Failure!  $build_file wasn't produced.
-Please read INSTALL.md and associated NOTES files.  You may also have to
+Please read INSTALL.md and associated NOTES-* files.  You may also have to
 look over your available compiler tool chain or change your configuration.
 
 _____
@@ -2994,7 +3073,6 @@ sub usage
                         }
                 print STDERR $i . " ";
                 }
-        print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
         exit(1);
         }
 
@@ -3181,6 +3259,27 @@ sub absolutedir {
     return realpath($dir);
 }
 
+# Check if all paths are one and the same, using stat.  They must both exist
+# We need this for the cases when File::Spec doesn't detect case insensitivity
+# (File::Spec::Unix assumes case sensitivity)
+sub samedir {
+    die "samedir expects two arguments\n" unless scalar @_ == 2;
+
+    my @stat0 = stat($_[0]);    # First argument
+    my @stat1 = stat($_[1]);    # Second argument
+
+    die "Couldn't stat $_[0]" unless @stat0;
+    die "Couldn't stat $_[1]" unless @stat1;
+
+    # Compare device number
+    return 0 unless ($stat0[0] == $stat1[0]);
+    # Compare "inode".  The perl manual recommends comparing as
+    # string rather than as number.
+    return 0 unless ($stat0[1] eq $stat1[1]);
+
+    return 1;                   # All the same
+}
+
 sub quotify {
     my %processors = (
         perl    => sub { my $x = shift;