NIAP FPT_TST_EXT.1 [1] specification requires testing of a small set of cryptographic modules on boot for devices that need to be NIAP compliant. This is also a requirement for FIPS CMVP 140-2/140-3 certification. Currently testmgr adds significant boot time overhead when enabled; we measured 3-5 seconds for Android. This change adds a CONFIG_ option that allows testmgr to run a smaller subset of tests required by NIAP FPT_TST_EXT.1. [1] https://www.niap-ccevs.org/MMO/PP/-417-/#FPT_TST_EXT.1.1 Signed-off-by: Elena Petrova <lenaptr@xxxxxxxxxx> --- crypto/Kconfig | 19 +++++++++++++++++++ crypto/testmgr.c | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/crypto/Kconfig b/crypto/Kconfig index a367fcfeb5d4..4985406f1342 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -32,6 +32,17 @@ config CRYPTO_FIPS certification. You should say no unless you know what this is. +config CRYPTO_NIAP_FPT_TST_EXT_11 + bool "NIAP FPT_TST_EXT.1.1 compliance" + depends on CRYPTO_MANAGER + depends on CRYPTO_SHA512 && CRYPTO_HMAC + depends on CRYPTO_SHA256 + depends on CRYPTO_AES && CRYPTO_CBC + help + This option enables a set of self-tests to demonstrate + the correct operation of cryptographic functionality, as + required in NIAP FPT_TST_EXT.1.1. + config CRYPTO_ALGAPI tristate select CRYPTO_ALGAPI2 @@ -153,6 +164,14 @@ config CRYPTO_MANAGER_EXTRA_TESTS This is intended for developer use only, as these tests take much longer to run than the normal self tests. +config CRYPTO_MANAGER_NIAP_TESTS_ONLY + bool "Enable only NIAP FPT_TST_EXT.1 run-time self tests" + depends on !CRYPTO_MANAGER_DISABLE_TESTS && CRYPTO_NIAP_FPT_TST_EXT_11 + default y + help + Disable run-time self tests except for those required by + NIAP FPT_TST_EXT.1. + config CRYPTO_GF128MUL tristate diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 321e38eef51b..2abe140f265a 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -1919,6 +1919,7 @@ static int alg_test_hash(const struct alg_test_desc *desc, const char *driver, return err; } +#ifndef CONFIG_CRYPTO_MANAGER_NIAP_TESTS_ONLY static int test_aead_vec_cfg(int enc, const struct aead_testvec *vec, const char *vec_name, const struct testvec_config *cfg, @@ -2597,6 +2598,7 @@ static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, crypto_free_aead(tfm); return err; } +#endif /* !CONFIG_CRYPTO_MANAGER_NIAP_TESTS_ONLY */ static int test_cipher(struct crypto_cipher *tfm, int enc, const struct cipher_testvec *template, @@ -3166,6 +3168,7 @@ static int alg_test_skcipher(const struct alg_test_desc *desc, return err; } +#ifndef CONFIG_CRYPTO_MANAGER_NIAP_TESTS_ONLY static int test_comp(struct crypto_comp *tfm, const struct comp_testvec *ctemplate, const struct comp_testvec *dtemplate, @@ -3502,6 +3505,7 @@ static int test_cprng(struct crypto_rng *tfm, kfree(seed); return err; } +#endif /* !CONFIG_CRYPTO_MANAGER_NIAP_TESTS_ONLY */ static int alg_test_cipher(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) @@ -3525,6 +3529,7 @@ static int alg_test_cipher(const struct alg_test_desc *desc, return err; } +#ifndef CONFIG_CRYPTO_MANAGER_NIAP_TESTS_ONLY static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, u32 type, u32 mask) { @@ -4141,12 +4146,38 @@ static int alg_test_null(const struct alg_test_desc *desc, { return 0; } +#endif /* !CONFIG_CRYPTO_MANAGER_NIAP_TESTS_ONLY */ #define ____VECS(tv) .vecs = tv, .count = ARRAY_SIZE(tv) #define __VECS(tv) { ____VECS(tv) } /* Please keep this list sorted by algorithm name. */ static const struct alg_test_desc alg_test_descs[] = { +#ifdef CONFIG_CRYPTO_MANAGER_NIAP_TESTS_ONLY + /* Reduced list of algorithms for NIAP FPT_TST_EXT.1 */ + { + .alg = "cbc(aes)", + .test = alg_test_skcipher, + .fips_allowed = 1, + .suite = { + .cipher = __VECS(aes_cbc_tv_template) + }, + }, { + .alg = "hmac(sha512)", + .test = alg_test_hash, + .fips_allowed = 1, + .suite = { + .hash = __VECS(hmac_sha512_tv_template) + } + }, { + .alg = "sha256", + .test = alg_test_hash, + .fips_allowed = 1, + .suite = { + .hash = __VECS(sha256_tv_template) + } + } +#else /* !CONFIG_CRYPTO_MANAGER_NIAP_TESTS_ONLY */ { .alg = "adiantum(xchacha12,aes)", .generic_driver = "adiantum(xchacha12-generic,aes-generic,nhpoly1305-generic)", @@ -5544,6 +5575,7 @@ static const struct alg_test_desc alg_test_descs[] = { } } } +#endif /* !CONFIG_CRYPTO_MANAGER_NIAP_TESTS_ONLY */ }; static void alg_check_test_descs_order(void) @@ -5671,10 +5703,14 @@ int alg_test(const char *driver, const char *alg, u32 type, u32 mask) driver, alg, fips_enabled ? "fips" : "panic_on_fail"); } + if (IS_ENABLED(CONFIG_CRYPTO_NIAP_FPT_TST_EXT_11)) + panic("alg: self-tests for %s (%s) failed in NIAP mode!\n", + driver, alg); + WARN(1, "alg: self-tests for %s (%s) failed (rc=%d)", driver, alg, rc); } else { - if (fips_enabled) + if (fips_enabled || IS_ENABLED(CONFIG_CRYPTO_NIAP_FPT_TST_EXT_11)) pr_info("alg: self-tests for %s (%s) passed\n", driver, alg); } -- 2.30.0.284.gd98b1dd5eaa7-goog