Add a function to return a FIPS version.

We need a function that returns a version that links to a certificate.
Previously we have used the git hash as the version of our modules but
the source cannot contain its own hash. Thus this change defines a new
format for FIPS module versions which will be filled in once we're ready
to define a version.

Change-Id: Ie4641945119106bc47e8da94ed8a45a86abb6f92
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/51986
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/fipsmodule/self_check/fips.c b/crypto/fipsmodule/self_check/fips.c
index 2b9927f..11c9309 100644
--- a/crypto/fipsmodule/self_check/fips.c
+++ b/crypto/fipsmodule/self_check/fips.c
@@ -28,6 +28,10 @@
 
 int FIPS_mode_set(int on) { return on == FIPS_mode(); }
 
+uint32_t FIPS_version(void) {
+  return 0;
+}
+
 int FIPS_query_algorithm_status(const char *algorithm) {
 #if defined(BORINGSSL_FIPS)
   static const char kApprovedAlgorithms[][13] = {
diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h
index ce1e5ce..15db776 100644
--- a/include/openssl/crypto.h
+++ b/include/openssl/crypto.h
@@ -172,6 +172,14 @@
 // |BORINGSSL_FIPS| and zero otherwise.
 OPENSSL_EXPORT int FIPS_mode_set(int on);
 
+// 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
+// be a date in the form yyyymmddXX where XX is often "00", but can be
+// incremented if multiple versions are defined on a single day.
+//
+// (This format exceeds a |uint32_t| in the year 4294.)
+OPENSSL_EXPORT uint32_t FIPS_version(void);
+
 // FIPS_query_algorithm_status returns one if |algorithm| is FIPS validated in
 // the current BoringSSL and zero otherwise.
 OPENSSL_EXPORT int FIPS_query_algorithm_status(const char *algorithm);
diff --git a/util/fipstools/test_fips.c b/util/fipstools/test_fips.c
index b3d5521..e192b61 100644
--- a/util/fipstools/test_fips.c
+++ b/util/fipstools/test_fips.c
@@ -47,6 +47,13 @@
 int main(int argc, char **argv) {
   CRYPTO_library_init();
 
+  const uint32_t module_version = FIPS_version();
+  if (module_version == 0) {
+    printf("No module version set\n");
+    goto err;
+  }
+  printf("Module version: %" PRIu32 "\n", module_version);
+
   static const uint8_t kAESKey[16] = "BoringCrypto Key";
   static const uint8_t kPlaintext[64] =
       "BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext!";