diff --git a/crypto/Kconfig b/crypto/Kconfig index d726b1c3a7f8..fa1617a05578 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -53,14 +53,14 @@ config CRYPTO_FIPS140_MOD meet FIPS 140 and NIAP FPT_TST_EXT.1 requirements. It shouldn't be used if you don't need to meet these requirements. -config CRYPTO_FIPS140_MOD_ERROR_INJECTION - bool "Support injecting failures into the FIPS 140 self-tests" +config CRYPTO_FIPS140_MOD_EVAL_TESTING + bool "Enable evaluation testing features in FIPS 140 module" depends on CRYPTO_FIPS140_MOD help - This option adds a module parameter "broken_alg" to the fips140 module - which can be used to fail the self-tests for a particular algorithm, - causing a kernel panic. This option is for FIPS lab testing only, and - it shouldn't be enabled on production systems. + This option adds some features to the FIPS 140 module which are needed + for lab evaluation testing of the module, e.g. support for injecting + errors and support for a userspace interface to some of the module's + services. This option should not be enabled in production builds. config CRYPTO_ALGAPI tristate diff --git a/crypto/Makefile b/crypto/Makefile index 9ada957d4cbd..f8a3677d2eec 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -239,11 +239,14 @@ fips140-objs := \ fips140-refs.o \ fips140-selftests.o \ crypto-fips.a +fips140-$(CONFIG_CRYPTO_FIPS140_MOD_EVAL_TESTING) += \ + fips140-eval-testing.o obj-m += fips140.o CFLAGS_fips140-alg-registration.o += $(FIPS140_CFLAGS) CFLAGS_fips140-module.o += $(FIPS140_CFLAGS) CFLAGS_fips140-selftests.o += $(FIPS140_CFLAGS) +CFLAGS_fips140-eval-testing.o += $(FIPS140_CFLAGS) hostprogs-always-y := fips140_gen_hmac HOSTLDLIBS_fips140_gen_hmac := -lcrypto -lelf diff --git a/crypto/fips140-eval-testing.c b/crypto/fips140-eval-testing.c new file mode 100644 index 000000000000..fbcd4cc633d5 --- /dev/null +++ b/crypto/fips140-eval-testing.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2021 Google LLC + * + * This file can optionally be built into fips140.ko in order to support certain + * types of testing that the FIPS lab has to do to evaluate the module. It + * should not be included in production builds of the module. + */ + +#include + +#include "fips140-module.h" + +/* + * This option allows deliberately failing the self-tests for a particular + * algorithm. + */ +static char *fips140_fail_selftest; +module_param_named(fail_selftest, fips140_fail_selftest, charp, 0); + +/* Inject a self-test failure (via corrupting the result) if requested. */ +void fips140_inject_selftest_failure(const char *impl, u8 *result) +{ + if (fips140_fail_selftest && strcmp(impl, fips140_fail_selftest) == 0) + result[0] ^= 0xff; +} + +bool fips140_eval_testing_init(void) +{ + return true; +} diff --git a/crypto/fips140-module.c b/crypto/fips140-module.c index 5e42891fbd0d..4ebcf12a8b2a 100644 --- a/crypto/fips140-module.c +++ b/crypto/fips140-module.c @@ -29,15 +29,6 @@ #include "fips140-module.h" #include "internal.h" -/* - * This option allows deliberately failing the self-tests for a particular - * algorithm. This is for FIPS lab testing only. - */ -#ifdef CONFIG_CRYPTO_FIPS140_MOD_ERROR_INJECTION -char *fips140_broken_alg; -module_param_named(broken_alg, fips140_broken_alg, charp, 0); -#endif - /* * FIPS 140-2 prefers the use of HMAC with a public key over a plain hash. */ @@ -545,6 +536,9 @@ fips140_init(void) if (!update_fips140_library_routines()) goto panic; + if (!fips140_eval_testing_init()) + goto panic; + pr_info("module successfully loaded\n"); return 0; diff --git a/crypto/fips140-module.h b/crypto/fips140-module.h index b83547726a0f..92e2ff1ffbca 100644 --- a/crypto/fips140-module.h +++ b/crypto/fips140-module.h @@ -20,16 +20,27 @@ #define FIPS140_MODULE_NAME "Android Kernel Cryptographic Module" #define FIPS140_MODULE_VERSION UTS_RELEASE -#ifdef CONFIG_CRYPTO_FIPS140_MOD_ERROR_INJECTION -extern char *fips140_broken_alg; -#endif +/* fips140-eval-testing.c */ +#ifdef CONFIG_CRYPTO_FIPS140_MOD_EVAL_TESTING +void fips140_inject_selftest_failure(const char *impl, u8 *result); +bool fips140_eval_testing_init(void); +#else +static inline void fips140_inject_selftest_failure(const char *impl, u8 *result) +{ +} +static inline bool fips140_eval_testing_init(void) +{ + return true; +} +#endif /* !CONFIG_CRYPTO_FIPS140_MOD_EVAL_TESTING */ +/* fips140-module.c */ extern struct completion fips140_tests_done; extern struct task_struct *fips140_init_thread; - -bool __init __must_check fips140_run_selftests(void); - bool fips140_is_approved_service(const char *name); const char *fips140_module_version(void); +/* fips140-selftests.c */ +bool __init __must_check fips140_run_selftests(void); + #endif /* _CRYPTO_FIPS140_MODULE_H */ diff --git a/crypto/fips140-selftests.c b/crypto/fips140-selftests.c index 0ab388a9f213..56c503cacc41 100644 --- a/crypto/fips140-selftests.c +++ b/crypto/fips140-selftests.c @@ -146,11 +146,7 @@ static int __init __must_check fips_check_result(u8 *result, const u8 *expected_result, size_t result_size, const char *impl, const char *operation) { -#ifdef CONFIG_CRYPTO_FIPS140_MOD_ERROR_INJECTION - /* Inject a failure (via corrupting the result) if requested. */ - if (fips140_broken_alg && strcmp(impl, fips140_broken_alg) == 0) - result[0] ^= 0xff; -#endif + fips140_inject_selftest_failure(impl, result); if (memcmp(result, expected_result, result_size) != 0) { pr_err("wrong result from %s %s\n", impl, operation); return -EBADMSG;