From 903e97a0ca6dd849a250d7fbbcbbb6e343aeb8b5 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Thu, 18 Nov 2021 16:09:09 -0800 Subject: [PATCH] ANDROID: fips140: refactor evaluation testing support It turns out that we have to add more code to the module to support lab evaluation testing, beyond the error injection support we currently have. Therefore, rename CONFIG_CRYPTO_FIPS140_MOD_ERROR_INJECTION to CONFIG_CRYPTO_FIPS140_MOD_EVAL_TESTING, and move the relevant code into a new file fips140-eval-testing.c which is conditionally compiled. Also rename the "broken_alg" module parameter to "fail_selftest" so that it is similar to "fail_integrity_check" which we'll be adding. Bug: 188620248 Change-Id: I01bcbf7525690e277854ba4ed8dd89e7cd08d98e Signed-off-by: Eric Biggers --- crypto/Kconfig | 12 ++++++------ crypto/Makefile | 3 +++ crypto/fips140-eval-testing.c | 31 +++++++++++++++++++++++++++++++ crypto/fips140-module.c | 12 +++--------- crypto/fips140-module.h | 23 +++++++++++++++++------ crypto/fips140-selftests.c | 6 +----- 6 files changed, 61 insertions(+), 26 deletions(-) create mode 100644 crypto/fips140-eval-testing.c 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;