crypto: fips - add FIPS test failure notification chain
authorGilad Ben-Yossef <gilad@benyossef.com>
Tue, 2 Jul 2019 11:39:20 +0000 (14:39 +0300)
committerHerbert Xu <herbert@gondor.apana.org.au>
Fri, 26 Jul 2019 04:51:57 +0000 (14:51 +1000)
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 <gilad@benyossef.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/fips.c
crypto/testmgr.c
include/linux/fips.h

index c0b3a3c3452dd49da5756c8568706356ee7be4ed..7b1d8caee669292b5f039c5ab1047fddcf09966e 100644 (file)
 #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)
 {
@@ -58,6 +62,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();
index d0b5b33806a67cdf7aa27a5ac8cdea46cf469c00..8ba1e75cd97372b4cdae8c9303e75a691c82fa0c 100644 (file)
@@ -5240,9 +5240,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);
index afeeece9230244e776d4e82ec87b81f9ea2a533f..c6961e932fef3437f3a25b2853c9a4fa61fdd179 100644 (file)
@@ -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