Crypto test failures in FIPS mode cause an immediate panic, but
on some system the cryptographic boundary extends beyond just
the Linux controlled domain.

Add a simple atomic notification chain to allow interested parties
to register to receive notification prior to us kicking the bucket.

Signed-off-by: Gilad Ben-Yossef <gi...@benyossef.com>
---
 crypto/fips.c        | 11 +++++++++++
 crypto/testmgr.c     |  4 +++-
 include/linux/fips.h |  7 +++++++
 3 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/crypto/fips.c b/crypto/fips.c
index 9dfed122d6da..b30a67b6c441 100644
--- a/crypto/fips.c
+++ b/crypto/fips.c
@@ -16,10 +16,14 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sysctl.h>
+#include <linux/notifier.h>
 
 int fips_enabled;
 EXPORT_SYMBOL_GPL(fips_enabled);
 
+ATOMIC_NOTIFIER_HEAD(fips_fail_notif_chain);
+EXPORT_SYMBOL_GPL(fips_fail_notif_chain);
+
 /* Process kernel command-line parameter at boot time. fips=0 or fips=1 */
 static int fips_enable(char *str)
 {
@@ -63,6 +67,13 @@ static void crypto_proc_fips_exit(void)
        unregister_sysctl_table(crypto_sysctls);
 }
 
+void fips_fail_notify(void)
+{
+       if (fips_enabled)
+               atomic_notifier_call_chain(&fips_fail_notif_chain, 0, NULL);
+}
+EXPORT_SYMBOL_GPL(fips_fail_notify);
+
 static int __init fips_init(void)
 {
        crypto_proc_fips_init();
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index d760f5cd35b2..fc2407d7a78f 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -5245,9 +5245,11 @@ int alg_test(const char *driver, const char *alg, u32 
type, u32 mask)
                                             type, mask);
 
 test_done:
-       if (rc && (fips_enabled || panic_on_fail))
+       if (rc && (fips_enabled || panic_on_fail)) {
+               fips_fail_notify();
                panic("alg: self-tests for %s (%s) failed in %s mode!\n",
                      driver, alg, fips_enabled ? "fips" : "panic_on_fail");
+       }
 
        if (fips_enabled && !rc)
                pr_info("alg: self-tests for %s (%s) passed\n", driver, alg);
diff --git a/include/linux/fips.h b/include/linux/fips.h
index afeeece92302..c6961e932fef 100644
--- a/include/linux/fips.h
+++ b/include/linux/fips.h
@@ -4,8 +4,15 @@
 
 #ifdef CONFIG_CRYPTO_FIPS
 extern int fips_enabled;
+extern struct atomic_notifier_head fips_fail_notif_chain;
+
+void fips_fail_notify(void);
+
 #else
 #define fips_enabled 0
+
+static inline void fips_fail_notify(void) {}
+
 #endif
 
 #endif
-- 
2.21.0

Reply via email to