Have modulewrapper print more of its build environment.

It's useful for auditing purposes if modulewrapper can print information
about the FIPS module within it. Also, we have a function,
`CRYPTO_has_asm`, which reports whether assembly code is enabled or not.
But that function wasn't implemented within the FIPS module and thus
it reported the condition of libcrypto instead. This change moves it into
the FIPS module so that it reports the condition there, which is what we
care about.

Change-Id: I66ac8936c6d8dd7b5260ec7a68405d58a63990fb
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/72327
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Auto-Submit: Adam Langley <agl@google.com>
diff --git a/crypto/crypto.c b/crypto/crypto.c
index 2e53e74..ead0543 100644
--- a/crypto/crypto.c
+++ b/crypto/crypto.c
@@ -17,8 +17,8 @@
 #include <assert.h>
 #include <stdio.h>
 
-#include "fipsmodule/rand/internal.h"
 #include "bcm_support.h"
+#include "fipsmodule/rand/internal.h"
 #include "internal.h"
 
 
@@ -132,14 +132,6 @@
 #endif
 }
 
-int CRYPTO_has_asm(void) {
-#if defined(OPENSSL_NO_ASM)
-  return 0;
-#else
-  return 1;
-#endif
-}
-
 void CRYPTO_pre_sandbox_init(void) {
   // Read from /proc/cpuinfo if needed.
   OPENSSL_init_cpuid();
diff --git a/crypto/fipsmodule/self_check/fips.c.inc b/crypto/fipsmodule/self_check/fips.c.inc
index ca6fb3a..920a6cb 100644
--- a/crypto/fipsmodule/self_check/fips.c.inc
+++ b/crypto/fipsmodule/self_check/fips.c.inc
@@ -30,6 +30,14 @@
 
 const char *FIPS_module_name(void) { return "BoringCrypto"; }
 
+int CRYPTO_has_asm(void) {
+#if defined(OPENSSL_NO_ASM)
+  return 0;
+#else
+  return 1;
+#endif
+}
+
 uint32_t FIPS_version(void) {
   return 0;
 }
diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h
index 384b94c..64bc0e7 100644
--- a/include/openssl/crypto.h
+++ b/include/openssl/crypto.h
@@ -181,7 +181,7 @@
 OPENSSL_EXPORT const char *FIPS_module_name(void);
 
 // FIPS_module_hash returns the 32-byte hash of the FIPS module.
-OPENSSL_EXPORT const uint8_t* FIPS_module_hash(void);
+OPENSSL_EXPORT const uint8_t *FIPS_module_hash(void);
 
 // FIPS_version returns the version of the FIPS module, or zero if the build
 // isn't exactly at a verified version. The version, expressed in base 10, will
diff --git a/util/fipstools/acvp/modulewrapper/main.cc b/util/fipstools/acvp/modulewrapper/main.cc
index 546091f..0997055 100644
--- a/util/fipstools/acvp/modulewrapper/main.cc
+++ b/util/fipstools/acvp/modulewrapper/main.cc
@@ -12,10 +12,11 @@
  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
 
+#include <inttypes.h>
 #include <stdio.h>
-#include <string>
 #include <string.h>
 #include <unistd.h>
+#include <string>
 
 #include <openssl/crypto.h>
 #include <openssl/span.h>
@@ -41,6 +42,34 @@
 #error "FIPS build not supported on this architecture"
 #endif
 
+    if (!FIPS_mode()) {
+      printf("Module not in FIPS mode\n");
+      abort();
+    }
+    printf("Module is in FIPS mode\n");
+
+    const uint32_t module_version = FIPS_version();
+    if (module_version == 0) {
+      printf("No module version set\n");
+      abort();
+    }
+    printf("Module: '%s', version: %" PRIu32 " hash:\n", FIPS_module_name(),
+           module_version);
+
+#if !defined(BORINGSSL_FIPS)
+    // |module_version| will be zero, so the non-FIPS build will never get
+    // this far.
+    printf("Non zero module version in non-FIPS build - should not happen!\n");
+    abort();
+#elif defined(OPENSSL_ASAN)
+    printf("(not available when compiled for ASAN)");
+#else
+    const uint8_t *module_hash = FIPS_module_hash();
+    for (size_t i = 0; i < SHA256_DIGEST_LENGTH; i++) {
+      printf("%02x", module_hash[i]);
+    }
+    printf("\n");
+#endif
     printf("Hardware acceleration enabled: %s\n",
            CRYPTO_has_asm() ? "yes" : "no");