Have a single function for FIPS test failures.

Change-Id: Iab7a738a8981de7c56d1585050e78699cb876dab
Reviewed-on: https://boringssl-review.googlesource.com/16467
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
diff --git a/crypto/fipsmodule/bcm.c b/crypto/fipsmodule/bcm.c
index ac9a407..f39661b 100644
--- a/crypto/fipsmodule/bcm.c
+++ b/crypto/fipsmodule/bcm.c
@@ -637,9 +637,13 @@
   return;
 
 err:
+  BORINGSSL_FIPS_abort();
+}
+
+void BORINGSSL_FIPS_abort(void) {
   for (;;) {
-    exit(1);
     abort();
+    exit(1);
   }
 }
 #endif  /* BORINGSSL_FIPS */
diff --git a/crypto/fipsmodule/rand/rand.c b/crypto/fipsmodule/rand/rand.c
index b627e06..a745252 100644
--- a/crypto/fipsmodule/rand/rand.c
+++ b/crypto/fipsmodule/rand/rand.c
@@ -141,17 +141,14 @@
    * generator test” which causes the program to randomly abort. Hopefully the
    * rate of failure is small enough not to be a problem in practice. */
   if (CRYPTO_memcmp(state->last_block, entropy, CRNGT_BLOCK_SIZE) == 0) {
-    for (;;) {
-      exit(1);
-      abort();
-    }
+    BORINGSSL_FIPS_abort();
   }
 
   for (size_t i = CRNGT_BLOCK_SIZE; i < sizeof(entropy);
        i += CRNGT_BLOCK_SIZE) {
     if (CRYPTO_memcmp(entropy + i - CRNGT_BLOCK_SIZE, entropy + i,
                       CRNGT_BLOCK_SIZE) == 0) {
-      abort();
+      BORINGSSL_FIPS_abort();
     }
   }
   OPENSSL_memcpy(state->last_block,
diff --git a/crypto/internal.h b/crypto/internal.h
index 1d5a25d..f58f1cf 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -631,6 +631,12 @@
   return memset(dst, c, n);
 }
 
+#if defined(BORINGSSL_FIPS)
+/* BORINGSSL_FIPS_abort is called when a FIPS power-on or continuous test
+ * fails. It prevents any further cryptographic operations by the current
+ * process. */
+void BORINGSSL_FIPS_abort(void) __attribute__((noreturn));
+#endif
 
 #if defined(__cplusplus)
 }  /* extern C */