Remove obsolete PRNG note. Add comment about use of SHA256 et al.
[openssl.git] / util / mk1mf.pl
index 7fde251256ac31f4bca795c24e09fa2c4af310a7..a21f6f45a74f126df85607285e594aaab6404870 100755 (executable)
@@ -15,6 +15,18 @@ my $engines = "";
 local $zlib_opt = 0;   # 0 = no zlib, 1 = static, 2 = dynamic
 local $zlib_lib = "";
 
+local $fips_canister_path = "";
+my $fips_premain_dso_exe_path = "";
+my $fips_premain_c_path = "";
+my $fips_sha1_exe_path = "";
+
+local $fipscanisterbuild = 0;
+local $fipsdso = 0;
+
+my $fipslibdir = "";
+my $baseaddr = "";
+
+my $ex_l_libs = "";
 
 open(IN,"<Makefile") || die "unable to open Makefile!\n";
 while(<IN>) {
@@ -42,6 +54,7 @@ $infile="MINFO";
        "FreeBSD","FreeBSD distribution",
        "OS2-EMX", "EMX GCC OS/2",
        "netware-clib", "CodeWarrior for NetWare - CLib - with WinSock Sockets",
+       "netware-clib-bsdsock", "CodeWarrior for NetWare - CLib - with BSD Sockets",
        "netware-libc", "CodeWarrior for NetWare - LibC - with WinSock Sockets",
        "netware-libc-bsdsock", "CodeWarrior for NetWare - LibC - with BSD Sockets",
        "default","cc under unix",
@@ -76,7 +89,7 @@ and [options] can be one of
        no-hw                                   - No hw
        nasm                                    - Use NASM for x86 asm
        nw-nasm                                 - Use NASM x86 asm for NetWare
-       nw-mwasm                                        - Use Metrowerks x86 asm for NetWare
+       nw-mwasm                                - Use Metrowerks x86 asm for NetWare
        gaswin                                  - Use GNU as with Mingw32
        no-socks                                - No socket code
        no-err                                  - No error strings
@@ -173,10 +186,10 @@ elsif ($platform eq "OS2-EMX")
        require 'OS2-EMX.pl';
        }
 elsif (($platform eq "netware-clib") || ($platform eq "netware-libc") ||
-       ($platform eq "netware-libc-bsdsock"))
+       ($platform eq "netware-clib-bsdsock") || ($platform eq "netware-libc-bsdsock"))
        {
        $LIBC=1 if $platform eq "netware-libc" || $platform eq "netware-libc-bsdsock";
-       $BSDSOCK=1 if $platform eq "netware-libc-bsdsock";
+       $BSDSOCK=1 if ($platform eq "netware-libc-bsdsock") || ($platform eq "netware-clib-bsdsock");
        require 'netware.pl';
        }
 else
@@ -218,6 +231,10 @@ $cflags.=" -DOPENSSL_NO_DH"   if $no_dh;
 $cflags.=" -DOPENSSL_NO_SOCK" if $no_sock;
 $cflags.=" -DOPENSSL_NO_SSL2" if $no_ssl2;
 $cflags.=" -DOPENSSL_NO_SSL3" if $no_ssl3;
+$cflags.=" -DOPENSSL_NO_TLSEXT" if $no_tlsext;
+$cflags.=" -DOPENSSL_NO_CMS" if $no_cms;
+$cflags.=" -DOPENSSL_NO_JPAKE" if $no_jpake;
+$cflags.=" -DOPENSSL_NO_CAPIENG" if $no_capieng;
 $cflags.=" -DOPENSSL_NO_ERR"  if $no_err;
 $cflags.=" -DOPENSSL_NO_KRB5" if $no_krb5;
 $cflags.=" -DOPENSSL_NO_EC"   if $no_ec;
@@ -225,7 +242,7 @@ $cflags.=" -DOPENSSL_NO_ECDSA" if $no_ecdsa;
 $cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
 $cflags.=" -DOPENSSL_NO_ENGINE"   if $no_engine;
 $cflags.=" -DOPENSSL_NO_HW"   if $no_hw;
-
+$cflags.=" -DOPENSSL_FIPS"    if $fips;
 $cflags.= " -DZLIB" if $zlib_opt;
 $cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
 
@@ -247,9 +264,9 @@ else
 
 $ex_libs="$l_flags$ex_libs" if ($l_flags ne "");
 
-
 %shlib_ex_cflags=("SSL" => " -DOPENSSL_BUILD_SHLIBSSL",
-                 "CRYPTO" => " -DOPENSSL_BUILD_SHLIBCRYPTO");
+                 "CRYPTO" => " -DOPENSSL_BUILD_SHLIBCRYPTO",
+                 "FIPS" => " -DOPENSSL_BUILD_SHLIBCRYPTO");
 
 if ($msdos)
        {
@@ -277,11 +294,21 @@ for (;;)
                {
                if ($lib ne "")
                        {
-                       $uc=$lib;
-                       $uc =~ s/^lib(.*)\.a/$1/;
-                       $uc =~ tr/a-z/A-Z/;
-                       $lib_nam{$uc}=$uc;
-                       $lib_obj{$uc}.=$libobj." ";
+                       if ($fips && $dir =~ /^fips/)
+                               {
+                               $uc = "FIPS";
+                               }
+                       else
+                               {
+                               $uc=$lib;
+                               $uc =~ s/^lib(.*)\.a/$1/;
+                               $uc =~ tr/a-z/A-Z/;
+                               }
+                       if (($uc ne "FIPS") || $fipscanisterbuild)
+                               {
+                               $lib_nam{$uc}=$uc;
+                               $lib_obj{$uc}.=$libobj." ";
+                               }
                        }
                last if ($val eq "FINISHED");
                $lib="";
@@ -324,32 +351,151 @@ for (;;)
        if ($key eq "LIBNAMES" && $dir eq "engines" && $no_static_engine)
                { $engines.=$val }
 
+       if ($key eq "FIPS_EX_OBJ")
+               { 
+               $fips_ex_obj=&var_add("crypto",$val,0);
+               }
+
+       if ($key eq "FIPSLIBDIR")
+               {
+               $fipslibdir=$val;
+               $fipslibdir =~ s/\/$//;
+               $fipslibdir =~ s/\//$o/g;
+               }
+
+       if ($key eq "BASEADDR")
+               { $baseaddr=$val;}
+
        if (!($_=<IN>))
                { $_="RELATIVE_DIRECTORY=FINISHED\n"; }
        }
 close(IN);
 
+if ($fips)
+       {
+        
+       foreach (split " ", $fips_ex_obj)
+               {
+               $fips_exclude_obj{$1} = 1 if (/\/([^\/]*)$/);
+               }
+
+       $fips_exclude_obj{"cpu_win32"} = 1;
+       $fips_exclude_obj{"bn_asm"} = 1;
+       $fips_exclude_obj{"des_enc"} = 1;
+       $fips_exclude_obj{"fcrypt_b"} = 1;
+       $fips_exclude_obj{"aes_core"} = 1;
+       $fips_exclude_obj{"aes_cbc"} = 1;
+
+       my @ltmp = split " ", $lib_obj{"CRYPTO"};
+
+
+       $lib_obj{"CRYPTO"} = "";
+
+       foreach(@ltmp)
+               {
+               if (/\/([^\/]*)$/ && exists $fips_exclude_obj{$1})
+                       {
+                       if ($fipscanisterbuild)
+                               {
+                               $lib_obj{"FIPS"} .= "$_ ";
+                               }
+                       }
+               else
+                       {
+                       $lib_obj{"CRYPTO"} .= "$_ ";
+                       }
+               }
+
+       }
+
+if ($fipscanisterbuild)
+       {
+       $fips_canister_path = "\$(LIB_D)${o}fipscanister.lib" if $fips_canister_path eq "";
+       $fips_premain_c_path = "\$(LIB_D)${o}fips_premain.c";
+       }
+else
+       {
+       if ($fips_canister_path eq "")
+               {
+               $fips_canister_path = "\$(FIPSLIB_D)${o}fipscanister.lib";
+               }
+
+       if ($fips_premain_c_path eq "")
+               {
+               $fips_premain_c_path = "\$(FIPSLIB_D)${o}fips_premain.c";
+               }
+       }
+
+if ($fips)
+       {
+       if ($fips_sha1_exe_path eq "")
+               {
+               $fips_sha1_exe_path =
+                       "\$(BIN_D)${o}fips_standalone_sha1$exep";
+               }
+       }
+       else
+       {
+       $fips_sha1_exe_path = "";
+       }
+
+if ($fips_premain_dso_exe_path eq "")
+       {
+       $fips_premain_dso_exe_path = "\$(BIN_D)${o}fips_premain_dso$exep";
+       }
+
+#      $ex_build_targets .= "\$(BIN_D)${o}\$(E_PREMAIN_DSO)$exep" if ($fips);
+
+#$ex_l_libs .= " \$(L_FIPS)" if $fipsdso;
+
+if ($fips)
+       {
+       if (!$shlib)
+               {
+               $ex_build_targets .= " \$(LIB_D)$o$crypto_compat \$(PREMAIN_DSO_EXE)";
+               $ex_l_libs .= " \$(O_FIPSCANISTER)";
+               $ex_libs_dep .= " \$(O_FIPSCANISTER)" if $fipscanisterbuild;
+               }
+       if ($fipscanisterbuild)
+               {
+               $fipslibdir = "\$(LIB_D)";
+               }
+       else
+               {
+               if ($fipslibdir eq "")
+                       {
+                       open (IN, "util/fipslib_path.txt") || fipslib_error();
+                       $fipslibdir = <IN>;
+                       chomp $fipslibdir;
+                       close IN;
+                       }
+               fips_check_files($fipslibdir,
+                               "fipscanister.lib", "fipscanister.lib.sha1",
+                               "fips_premain.c", "fips_premain.c.sha1");
+               }
+       }
+
 if ($shlib)
        {
        $extra_install= <<"EOF";
-       \$(CP) \$(O_SSL) \$(INSTALLTOP)${o}bin
-       \$(CP) \$(O_CRYPTO) \$(INSTALLTOP)${o}bin
-       \$(CP) \$(L_SSL) \$(INSTALLTOP)${o}lib
-       \$(CP) \$(L_CRYPTO) \$(INSTALLTOP)${o}lib
+       \$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}bin\"
+       \$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}bin\"
+       \$(CP) \"\$(L_SSL)\" \"\$(INSTALLTOP)${o}lib\"
+       \$(CP) \"\$(L_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
 EOF
        if ($no_static_engine)
                {
                $extra_install .= <<"EOF"
-       \$(MKDIR) \$(INSTALLTOP)${o}lib${o}engines
-       \$(CP) \$(E_SHLIB) \$(INSTALLTOP)${o}lib${o}engines
+       \$(MKDIR) \"\$(INSTALLTOP)${o}lib${o}engines\"
+       \$(CP) \"\$(E_SHLIB)\" \"\$(INSTALLTOP)${o}lib${o}engines\"
 EOF
                }
        }
 else
        {
        $extra_install= <<"EOF";
-       \$(CP) \$(O_SSL) \$(INSTALLTOP)${o}lib
-       \$(CP) \$(O_CRYPTO) \$(INSTALLTOP)${o}lib
+       \$(CP) \"\$(O_SSL)\" \"\$(INSTALLTOP)${o}lib\"
+       \$(CP) \"\$(O_CRYPTO)\" \"\$(INSTALLTOP)${o}lib\"
 EOF
        $ex_libs .= " $zlib_lib" if $zlib_opt == 1;
        }
@@ -394,7 +540,10 @@ SRC_D=$src_dir
 LINK=$link
 LFLAGS=$lflags
 RSC=$rsc
+FIPSLINK=\$(PERL) util${o}fipslink.pl
 
+AES_ASM_OBJ=$aes_asm_obj
+AES_ASM_SRC=$aes_asm_src
 BN_ASM_OBJ=$bn_asm_obj
 BN_ASM_SRC=$bn_asm_src
 BNCO_ASM_OBJ=$bnco_asm_obj
@@ -435,6 +584,17 @@ MKLIB=$bin_dir$mklib
 MLFLAGS=$mlflags
 ASM=$bin_dir$asm
 
+# FIPS validated module and support file locations
+
+E_PREMAIN_DSO=fips_premain_dso
+
+FIPSLIB_D=$fipslibdir
+BASEADDR=$baseaddr
+FIPS_PREMAIN_SRC=$fips_premain_c_path
+O_FIPSCANISTER=$fips_canister_path
+FIPS_SHA1_EXE=$fips_sha1_exe_path
+PREMAIN_DSO_EXE=$fips_premain_dso_exe_path
+
 ######################################################
 # You should not need to touch anything below this point
 ######################################################
@@ -442,6 +602,7 @@ ASM=$bin_dir$asm
 E_EXE=openssl
 SSL=$ssl
 CRYPTO=$crypto
+LIBFIPS=libosslfips
 
 # BIN_D  - Binary output directory
 # TEST_D - Binary test file output directory
@@ -462,12 +623,14 @@ INCL_D=\$(TMP_D)
 
 O_SSL=     \$(LIB_D)$o$plib\$(SSL)$shlibp
 O_CRYPTO=  \$(LIB_D)$o$plib\$(CRYPTO)$shlibp
+O_FIPS=    \$(LIB_D)$o$plib\$(LIBFIPS)$shlibp
 SO_SSL=    $plib\$(SSL)$so_shlibp
 SO_CRYPTO= $plib\$(CRYPTO)$so_shlibp
 L_SSL=     \$(LIB_D)$o$plib\$(SSL)$libp
 L_CRYPTO=  \$(LIB_D)$o$plib\$(CRYPTO)$libp
+L_FIPS=    \$(LIB_D)$o$plib\$(LIBFIPS)$libp
 
-L_LIBS= \$(L_SSL) \$(L_CRYPTO)
+L_LIBS= \$(L_SSL) \$(L_CRYPTO) $ex_l_libs
 
 ######################################################
 # Don't touch anything below this point
@@ -477,19 +640,19 @@ INC=-I\$(INC_D) -I\$(INCL_D)
 APP_CFLAGS=\$(INC) \$(CFLAG) \$(APP_CFLAG)
 LIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG)
 SHLIB_CFLAGS=\$(INC) \$(CFLAG) \$(LIB_CFLAG) \$(SHLIB_CFLAG)
-LIBS_DEP=\$(O_CRYPTO) \$(O_SSL)
+LIBS_DEP=\$(O_CRYPTO) \$(O_SSL) $ex_libs_dep
 
 #############################################
 EOF
 
 $rules=<<"EOF";
-all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers lib exe
+all: banner \$(TMP_D) \$(BIN_D) \$(TEST_D) \$(LIB_D) \$(INCO_D) headers \$(FIPS_SHA1_EXE) lib exe $ex_build_targets
 
 banner:
 $banner
 
 \$(TMP_D):
-       \$(MKDIR) \$(TMP_D)
+       \$(MKDIR) \"\$(TMP_D)\"
 # NB: uncomment out these lines if BIN_D, TEST_D and LIB_D are different
 #\$(BIN_D):
 #      \$(MKDIR) \$(BIN_D)
@@ -498,13 +661,13 @@ $banner
 #      \$(MKDIR) \$(TEST_D)
 
 \$(LIB_D):
-       \$(MKDIR) \$(LIB_D)
+       \$(MKDIR) \"\$(LIB_D)\"
 
 \$(INCO_D): \$(INC_D)
-       \$(MKDIR) \$(INCO_D)
+       \$(MKDIR) \"\$(INCO_D)\"
 
 \$(INC_D):
-       \$(MKDIR) \$(INC_D)
+       \$(MKDIR) \"\$(INC_D)\"
 
 headers: \$(HEADER) \$(EXHEADER)
        @
@@ -514,14 +677,14 @@ lib: \$(LIBS_DEP) \$(E_SHLIB)
 exe: \$(T_EXE) \$(BIN_D)$o\$(E_EXE)$exep
 
 install: all
-       \$(MKDIR) \$(INSTALLTOP)
-       \$(MKDIR) \$(INSTALLTOP)${o}bin
-       \$(MKDIR) \$(INSTALLTOP)${o}include
-       \$(MKDIR) \$(INSTALLTOP)${o}include${o}openssl
-       \$(MKDIR) \$(INSTALLTOP)${o}lib
-       \$(CP) \$(INCO_D)${o}*.\[ch\] \$(INSTALLTOP)${o}include${o}openssl
-       \$(CP) \$(BIN_D)$o\$(E_EXE)$exep \$(INSTALLTOP)${o}bin
-       \$(CP) apps${o}openssl.cnf \$(INSTALLTOP)
+       \$(MKDIR) \"\$(INSTALLTOP)\"
+       \$(MKDIR) \"\$(INSTALLTOP)${o}bin\"
+       \$(MKDIR) \"\$(INSTALLTOP)${o}include\"
+       \$(MKDIR) \"\$(INSTALLTOP)${o}include${o}openssl\"
+       \$(MKDIR) \"\$(INSTALLTOP)${o}lib\"
+       \$(CP) \"\$(INCO_D)${o}*.\[ch\]\" \"\$(INSTALLTOP)${o}include${o}openssl\"
+       \$(CP) \"\$(BIN_D)$o\$(E_EXE)$exep\" \"\$(INSTALLTOP)${o}bin\"
+       \$(CP) \"apps${o}openssl.cnf\" \"\$(INSTALLTOP)\"
 $extra_install
 
 
@@ -598,6 +761,26 @@ $rules.=&do_compile_rule("\$(OBJ_D)",$test,"\$(APP_CFLAGS)");
 $defs.=&do_defs("E_OBJ",$e_exe,"\$(OBJ_D)",$obj);
 $rules.=&do_compile_rule("\$(OBJ_D)",$e_exe,'-DMONOLITH $(APP_CFLAGS)');
 
+# Special case rules for fips_start and fips_end fips_premain_dso
+
+if ($fips)
+       {
+       if ($fipscanisterbuild)
+               {
+               $rules.=&cc_compile_target("\$(OBJ_D)${o}fips_start$obj",
+                       "fips${o}fips_canister.c",
+                       "-DFIPS_START \$(SHLIB_CFLAGS)");
+               $rules.=&cc_compile_target("\$(OBJ_D)${o}fips_end$obj",
+                       "fips${o}fips_canister.c", "\$(SHLIB_CFLAGS)");
+               }
+       $rules.=&cc_compile_target("\$(OBJ_D)${o}fips_standalone_sha1$obj",
+               "fips${o}sha${o}fips_standalone_sha1.c",
+               "\$(SHLIB_CFLAGS)");
+       $rules.=&cc_compile_target("\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj",
+               "fips${o}fips_premain.c",
+               "-DFINGERPRINT_PREMAIN_DSO_LOAD \$(SHLIB_CFLAGS)");
+       }
+
 foreach (values %lib_nam)
        {
        $lib_obj=$lib_obj{$_};
@@ -609,21 +792,40 @@ foreach (values %lib_nam)
                next;
                }
 
-       if (($bn_asm_obj ne "") && ($_ eq "CRYPTO"))
-               {
-               $lib_obj =~ s/\s\S*\/bn_asm\S*/ \$(BN_ASM_OBJ)/;
-               $rules.=&do_asm_rule($bn_asm_obj,$bn_asm_src);
-               }
-       if (($bnco_asm_obj ne "") && ($_ eq "CRYPTO"))
-               {
-               $lib_obj .= "\$(BNCO_ASM_OBJ)";
-               $rules.=&do_asm_rule($bnco_asm_obj,$bnco_asm_src);
-               }
-       if (($des_enc_obj ne "") && ($_ eq "CRYPTO"))
+       if ((!$fips && ($_ eq "CRYPTO")) || ($fips && ($_ eq "FIPS")))
                {
-               $lib_obj =~ s/\s\S*des_enc\S*/ \$(DES_ENC_OBJ)/;
-               $lib_obj =~ s/\s\S*\/fcrypt_b\S*\s*/ /;
-               $rules.=&do_asm_rule($des_enc_obj,$des_enc_src);
+               if ($cpuid_asm_obj ne "")
+                       {
+                       $lib_obj =~ s/(\S*\/cryptlib\S*)/$1 \$(CPUID_ASM_OBJ)/;
+                       $rules.=&do_asm_rule($cpuid_asm_obj,$cpuid_asm_src);
+                       }
+               if ($aes_asm_obj ne "")
+                       {
+                       $lib_obj =~ s/\s(\S*\/aes_core\S*)/ \$(AES_ASM_OBJ)/;
+                       $lib_obj =~ s/\s\S*\/aes_cbc\S*//;
+                       $rules.=&do_asm_rule($aes_asm_obj,$aes_asm_src);
+                       }
+               if ($sha1_asm_obj ne "")
+                       {
+                       $lib_obj =~ s/\s(\S*\/sha1dgst\S*)/ $1 \$(SHA1_ASM_OBJ)/;
+                       $rules.=&do_asm_rule($sha1_asm_obj,$sha1_asm_src);
+                       }
+               if ($bn_asm_obj ne "")
+                       {
+                       $lib_obj =~ s/\s\S*\/bn_asm\S*/ \$(BN_ASM_OBJ)/;
+                       $rules.=&do_asm_rule($bn_asm_obj,$bn_asm_src);
+                       }
+               if ($bnco_asm_obj ne "")
+                       {
+                       $lib_obj .= "\$(BNCO_ASM_OBJ)";
+                       $rules.=&do_asm_rule($bnco_asm_obj,$bnco_asm_src);
+                       }
+               if ($des_enc_obj ne "")
+                       {
+                       $lib_obj =~ s/\s\S*des_enc\S*/ \$(DES_ENC_OBJ)/;
+                       $lib_obj =~ s/\s\S*\/fcrypt_b\S*\s*/ /;
+                       $rules.=&do_asm_rule($des_enc_obj,$des_enc_src);
+                       }
                }
        if (($bf_enc_obj ne "") && ($_ eq "CRYPTO"))
                {
@@ -650,28 +852,19 @@ foreach (values %lib_nam)
                $lib_obj =~ s/\s(\S*\/md5_dgst\S*)/ $1 \$(MD5_ASM_OBJ)/;
                $rules.=&do_asm_rule($md5_asm_obj,$md5_asm_src);
                }
-       if (($sha1_asm_obj ne "") && ($_ eq "CRYPTO"))
-               {
-               $lib_obj =~ s/\s(\S*\/sha1dgst\S*)/ $1 \$(SHA1_ASM_OBJ)/;
-               $rules.=&do_asm_rule($sha1_asm_obj,$sha1_asm_src);
-               }
        if (($rmd160_asm_obj ne "") && ($_ eq "CRYPTO"))
                {
                $lib_obj =~ s/\s(\S*\/rmd_dgst\S*)/ $1 \$(RMD160_ASM_OBJ)/;
                $rules.=&do_asm_rule($rmd160_asm_obj,$rmd160_asm_src);
                }
-       if (($cpuid_asm_obj ne "") && ($_ eq "CRYPTO"))
-               {
-               $lib_obj =~ s/\s(\S*\/cversion\S*)/ $1 \$(CPUID_ASM_OBJ)/;
-               $rules.=&do_asm_rule($cpuid_asm_obj,$cpuid_asm_src);
-               }
        $defs.=&do_defs(${_}."OBJ",$lib_obj,"\$(OBJ_D)",$obj);
        $lib=($slib)?" \$(SHLIB_CFLAGS)".$shlib_ex_cflags{$_}:" \$(LIB_CFLAGS)";
        $rules.=&do_compile_rule("\$(OBJ_D)",$lib_obj{$_},$lib);
        }
 
 # hack to add version info on MSVC
-if (($platform eq "VC-WIN32") || ($platform eq "VC-NT")) {
+if (($platform eq "VC-WIN32") || ($platform eq "VC-WIN64A")
+       || ($platform eq "VC-WIN64I") || ($platform eq "VC-NT")) {
     $rules.= <<"EOF";
 \$(OBJ_D)\\\$(CRYPTO).res: ms\\version32.rc
        \$(RSC) /fo"\$(OBJ_D)\\\$(CRYPTO).res" /d CRYPTO ms\\version32.rc
@@ -679,15 +872,43 @@ if (($platform eq "VC-WIN32") || ($platform eq "VC-NT")) {
 \$(OBJ_D)\\\$(SSL).res: ms\\version32.rc
        \$(RSC) /fo"\$(OBJ_D)\\\$(SSL).res" /d SSL ms\\version32.rc
 
+\$(OBJ_D)\\\$(LIBFIPS).res: ms\\version32.rc
+       \$(RSC) /fo"\$(OBJ_D)\\\$(LIBFIPS).res" /d FIPS ms\\version32.rc
+
 EOF
 }
 
 $defs.=&do_defs("T_EXE",$test,"\$(TEST_D)",$exep);
 foreach (split(/\s+/,$test))
        {
+       my $t_libs;
        $t=&bname($_);
+       my $ltype;
+       # Check to see if test program is FIPS
+       if ($fips && /fips/)
+               {
+               # If fipsdso link to libosslfips.dll 
+               # otherwise perform static link to 
+               # $(O_FIPSCANISTER)
+               if ($fipsdso)
+                       {
+                       $t_libs = "\$(L_FIPS)";
+                       $ltype = 0;
+                       }
+               else
+                       {
+                       $t_libs = "\$(O_FIPSCANISTER)";
+                       $ltype = 2;
+                       }
+               }
+       else
+               {
+               $t_libs = "\$(L_LIBS)";
+               $ltype = 0;
+               }
+
        $tt="\$(OBJ_D)${o}$t${obj}";
-       $rules.=&do_link_rule("\$(TEST_D)$o$t$exep",$tt,"\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
+       $rules.=&do_link_rule("\$(TEST_D)$o$t$exep",$tt,"\$(LIBS_DEP)","$t_libs \$(EX_LIBS)", $ltype);
        }
 
 $defs.=&do_defs("E_SHLIB",$engines,"\$(ENG_D)",$shlibp);
@@ -701,9 +922,69 @@ foreach (split(/\s+/,$engines))
 
 
 $rules.= &do_lib_rule("\$(SSLOBJ)","\$(O_SSL)",$ssl,$shlib,"\$(SO_SSL)");
-$rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)");
 
-$rules.=&do_link_rule("\$(BIN_D)$o\$(E_EXE)$exep","\$(E_OBJ)","\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)");
+if ($fips)
+       {
+       if ($shlib)
+               {
+               if ($fipsdso)
+                       {
+                       $rules.= &do_lib_rule("\$(CRYPTOOBJ)",
+                                       "\$(O_CRYPTO)", "$crypto",
+                                       $shlib, "", "");
+                       $rules.= &do_lib_rule(
+                               "\$(O_FIPSCANISTER)",
+                               "\$(O_FIPS)", "\$(LIBFIPS)",
+                               $shlib, "\$(SO_CRYPTO)", "\$(BASEADDR)");
+                       $rules.= &do_sdef_rule();
+                       }
+               else
+                       {
+                       $rules.= &do_lib_rule(
+                               "\$(CRYPTOOBJ) \$(O_FIPSCANISTER)",
+                               "\$(O_CRYPTO)", "$crypto",
+                               $shlib, "\$(SO_CRYPTO)", "\$(BASEADDR)");
+                       }
+               }
+       else
+               {
+               $rules.= &do_lib_rule("\$(CRYPTOOBJ)",
+                       "\$(O_CRYPTO)",$crypto,$shlib,"\$(SO_CRYPTO)", "");
+               $rules.= &do_lib_rule("\$(CRYPTOOBJ) \$(FIPSOBJ)",
+                       "\$(LIB_D)$o$crypto_compat",$crypto,$shlib,"\$(SO_CRYPTO)", "");
+               }
+       }
+       else
+       {
+       $rules.= &do_lib_rule("\$(CRYPTOOBJ)","\$(O_CRYPTO)",$crypto,$shlib,
+                                                       "\$(SO_CRYPTO)");
+       }
+
+if ($fips)
+       {
+       if ($fipscanisterbuild)
+               {
+               $rules.= &do_rlink_rule("\$(O_FIPSCANISTER)",
+                                       "\$(OBJ_D)${o}fips_start$obj",
+                                       "\$(FIPSOBJ)",
+                                       "\$(OBJ_D)${o}fips_end$obj",
+                                       "\$(FIPS_SHA1_EXE)", "");
+               $rules.=&do_link_rule("\$(FIPS_SHA1_EXE)",
+                                       "\$(OBJ_D)${o}fips_standalone_sha1$obj \$(OBJ_D)${o}sha1dgst$obj \$(SHA1_ASM_OBJ)",
+                                       "","\$(EX_LIBS)", 1);
+               }
+       else
+               {
+               $rules.=&do_link_rule("\$(FIPS_SHA1_EXE)",
+                                       "\$(OBJ_D)${o}fips_standalone_sha1$obj \$(O_FIPSCANISTER)",
+                                       "","", 1);
+
+               }
+       $rules.=&do_link_rule("\$(PREMAIN_DSO_EXE)","\$(OBJ_D)${o}\$(E_PREMAIN_DSO)$obj \$(CRYPTOOBJ) \$(O_FIPSCANISTER)","","\$(EX_LIBS)", 1);
+       
+       }
+
+$rules.=&do_link_rule("\$(BIN_D)$o\$(E_EXE)$exep","\$(E_OBJ)","\$(LIBS_DEP)","\$(L_LIBS) \$(EX_LIBS)", ($fips && !$shlib) ? 2 : 0);
 
 print $defs;
 
@@ -740,6 +1021,9 @@ sub var_add
        return("") if $no_dsa  && $dir =~ /\/dsa/;
        return("") if $no_dh   && $dir =~ /\/dh/;
        return("") if $no_ec   && $dir =~ /\/ec/;
+       return("") if $no_cms  && $dir =~ /\/cms/;
+       return("") if $no_jpake  && $dir =~ /\/jpake/;
+       return("") if !$fips   && $dir =~ /^fips/;
        if ($no_des && $dir =~ /\/des/)
                {
                if ($val =~ /read_pwd/)
@@ -850,6 +1134,7 @@ sub do_defs
                elsif ($_ =~ /RC5_ENC/) { $t="$_ "; }
                elsif ($_ =~ /MD5_ASM/) { $t="$_ "; }
                elsif ($_ =~ /SHA1_ASM/){ $t="$_ "; }
+               elsif ($_ =~ /AES_ASM/){ $t="$_ "; }
                elsif ($_ =~ /RMD160_ASM/){ $t="$_ "; }
                elsif ($_ =~ /CPUID_ASM/){ $t="$_ "; }
                else    { $t="$location${o}$_$pf "; }
@@ -858,7 +1143,7 @@ sub do_defs
                $ret.=$t;
                }
        # hack to add version info on MSVC
-       if ($shlib && (($platform eq "VC-WIN32") || ($platform eq "VC-NT")))
+       if ($shlib && (($platform eq "VC-WIN32") || ($platfrom eq "VC-WIN64I") || ($platform eq "VC-WIN64A") || ($platform eq "VC-NT")))
                {
                if ($var eq "CRYPTOOBJ")
                        { $ret.="\$(OBJ_D)\\\$(CRYPTO).res "; }
@@ -960,7 +1245,7 @@ sub do_copy_rule
                if ($n =~ /bss_file/)
                        { $pp=".c"; }
                else    { $pp=$p; }
-               $ret.="$to${o}$n$pp: \$(SRC_D)$o$_$pp\n\t\$(CP) \$(SRC_D)$o$_$pp $to${o}$n$pp\n\n";
+               $ret.="$to${o}$n$pp: \$(SRC_D)$o$_$pp\n\t\$(CP) \"\$(SRC_D)$o$_$pp\" \"$to${o}$n$pp\"\n\n";
                }
        return($ret);
        }
@@ -998,11 +1283,16 @@ sub read_options
                "no-hmac" => \$no_hmac,
                "no-asm" => \$no_asm,
                "nasm" => \$nasm,
+               "ml64" => \$ml64,
                "nw-nasm" => \$nw_nasm,
                "nw-mwasm" => \$nw_mwasm,
                "gaswin" => \$gaswin,
                "no-ssl2" => \$no_ssl2,
                "no-ssl3" => \$no_ssl3,
+               "no-tlsext" => \$no_tlsext,
+               "no-cms" => \$no_cms,
+               "no-jpake" => \$no_jpake,
+               "no-capieng" => \$no_capieng,
                "no-err" => \$no_err,
                "no-sock" => \$no_sock,
                "no-krb5" => \$no_krb5,
@@ -1025,9 +1315,13 @@ sub read_options
                "shared" => 0,
                "no-gmp" => 0,
                "no-rfc3779" => 0,
+               "no-montasm" => 0,
                "no-shared" => 0,
                "no-zlib" => 0,
                "no-zlib-dynamic" => 0,
+               "fips" => \$fips,
+               "fipscanisterbuild" => [\$fips, \$fipscanisterbuild],
+               "fipsdso" => [\$fips, \$fipscanisterbuild, \$fipsdso],
                );
 
        if (exists $valid_options{$_})
@@ -1068,6 +1362,18 @@ sub read_options
                if (exists $valid_options{$t})
                        {return 1;}
                return 0;
+               }
+       # experimental-xxx is mostly like enable-xxx, but opensslconf.v
+       # will still set OPENSSL_NO_xxx unless we set OPENSSL_EXPERIMENTAL_xxx.
+       # (No need to fail if we don't know the algorithm -- this is for adventurous users only.)
+       elsif (/^experimental-/)
+               {
+               my $algo, $ALGO;
+               ($algo = $_) =~ s/^experimental-//;
+               ($ALGO = $algo) =~ tr/[a-z]/[A-Z]/;
+
+               $xcflags="-DOPENSSL_EXPERIMENTAL_$ALGO $xcflags";
+               
                }
        elsif (/^--with-krb5-flavor=(.*)$/)
                {
@@ -1092,3 +1398,31 @@ sub read_options
        else { return(0); }
        return(1);
        }
+
+sub fipslib_error
+       {
+       print STDERR "***FIPS module directory sanity check failed***\n";
+       print STDERR "FIPS module build failed, or was deleted\n";
+       print STDERR "Please rebuild FIPS module.\n"; 
+       exit 1;
+       }
+
+sub fips_check_files
+       {
+       my $dir = shift @_;
+       my $ret = 1;
+       if (!-d $dir)
+               {
+               print STDERR "FIPS module directory $dir does not exist\n";
+               fipslib_error();
+               }
+       foreach (@_)
+               {
+               if (!-f "$dir${o}$_")
+                       {
+                       print STDERR "FIPS module file $_ does not exist!\n";
+                       $ret = 0;
+                       }
+               }
+       fipslib_error() if ($ret == 0);
+       }