131 lines
3.4 KiB
C
131 lines
3.4 KiB
C
|
#include <crypto/aes.h>
|
||
|
#include <crypto/skcipher.h>
|
||
|
#include <linux/err.h>
|
||
|
#include <linux/string.h>
|
||
|
#include <linux/init.h>
|
||
|
#include <linux/module.h>
|
||
|
|
||
|
#include "fips140.h"
|
||
|
#include "fips140_test.h"
|
||
|
|
||
|
// TODO: to be removed
|
||
|
#if defined (__clang__)
|
||
|
#pragma clang optimize off
|
||
|
#elif defined (__GNUC__)
|
||
|
#pragma GCC push_options
|
||
|
#pragma GCC optimize ("O0")
|
||
|
#endif
|
||
|
|
||
|
int fips_enabled;
|
||
|
EXPORT_SYMBOL_GPL(fips_enabled);
|
||
|
#ifdef CONFIG_CRYPTO_FIPS_FUNC_TEST
|
||
|
static int functest_status;
|
||
|
#endif
|
||
|
|
||
|
static int __init fips140_post(void)
|
||
|
{
|
||
|
int err_kat = -1;
|
||
|
int err_integrity = -1;
|
||
|
|
||
|
fips_enabled = 0;
|
||
|
|
||
|
pr_info("FIPS : POST (%s)\n", SKC_VERSION_TEXT);
|
||
|
|
||
|
err_kat = fips140_kat();
|
||
|
err_integrity = do_integrity_check();
|
||
|
|
||
|
if (err_kat || err_integrity) {
|
||
|
pr_err("FIPS : POST - one or more selftests failed\n");
|
||
|
|
||
|
#ifdef CONFIG_CRYPTO_FIPS_FUNC_TEST
|
||
|
if (functest_status) {
|
||
|
pr_err("FIPS : POST - bypass panic because of functional test\n");
|
||
|
return -1;
|
||
|
}
|
||
|
else
|
||
|
panic("FIPS : POST - one or more selftests failed\n");
|
||
|
#else
|
||
|
panic("FIPS : POST - one or more selftests failed\n");
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
fips_enabled = 1;
|
||
|
pr_info("FIPS : POST - CRYPTO API started in FIPS approved mode : fips_enabled = %d\n", fips_enabled);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// When SKC_FUNC_TEST is defined, this function will be called instead of tcrypt_mode_init
|
||
|
// tcyprt_mode_init will be called as test case number
|
||
|
// after all tests are done, the normal POST test will start
|
||
|
#ifdef CONFIG_CRYPTO_FIPS_FUNC_TEST
|
||
|
static int __init fips140_post_func_test(void)
|
||
|
{
|
||
|
int i;
|
||
|
int err = -ENOMEM;
|
||
|
struct crypto_skcipher *tfm = NULL;
|
||
|
|
||
|
pr_info("FIPS FUNC : Functional test start\n");
|
||
|
|
||
|
functest_status = 1;
|
||
|
for (i = 0; i < SKC_FUNCTEST_KAT_CASE_NUM; i++) {
|
||
|
set_fips_functest_KAT_mode(i);
|
||
|
pr_info("FIPS FUNC : --------------------------------------------------\n");
|
||
|
pr_info("FIPS FUNC : Failure inducement case %d - [%s]\n", i + 1, get_fips_functest_mode());
|
||
|
pr_info("FIPS FUNC : --------------------------------------------------\n");
|
||
|
|
||
|
err = fips140_post();
|
||
|
|
||
|
pr_info("FIPS FUNC : (%d) POST done. SKC module FIPS status : fips140_post() returns %d | %s\n",
|
||
|
i+1, err, fips_enabled ? "passed" : "failed");
|
||
|
}
|
||
|
functest_status = 0;
|
||
|
|
||
|
for (i = 0; i < SKC_FUNCTEST_CONDITIONAL_CASE_NUM; i++) {
|
||
|
set_fips_functest_conditional_mode(i);
|
||
|
pr_info("FIPS FUNC : --------------------------------------------------\n");
|
||
|
pr_info("FIPS FUNC : conditional test case %d - [%s]\n", i + 1, get_fips_functest_mode());
|
||
|
pr_info("FIPS FUNC : --------------------------------------------------\n");
|
||
|
|
||
|
if (!strcmp("zeroization", get_fips_functest_mode())) {
|
||
|
uint8_t key[AES_KEYSIZE_256];
|
||
|
memset(key, 0xFE, AES_KEYSIZE_256);
|
||
|
tfm = crypto_alloc_skcipher("ecb(aes-ce)", 0, 0);
|
||
|
if (tfm) {
|
||
|
crypto_skcipher_setkey(tfm, key, AES_KEYSIZE_256);
|
||
|
crypto_free_skcipher(tfm);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
set_fips_functest_conditional_mode(-1);
|
||
|
|
||
|
pr_info("FIPS FUNC : Functional test end\n");
|
||
|
pr_info("FIPS FUNC : Normal POST start\n");
|
||
|
|
||
|
return fips140_post();
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
* If an init function is provided, an exit function must also be provided
|
||
|
* to allow module unload.
|
||
|
*/
|
||
|
static void __exit fips140_fini(void) { }
|
||
|
|
||
|
#ifdef CONFIG_CRYPTO_FIPS_FUNC_TEST
|
||
|
late_initcall(fips140_post_func_test);
|
||
|
#else
|
||
|
late_initcall(fips140_post);
|
||
|
#endif
|
||
|
module_exit(fips140_fini);
|
||
|
|
||
|
// TODO: to be removed
|
||
|
#if defined (__clang__)
|
||
|
#pragma clang optimize on
|
||
|
#elif defined (__GNUC__)
|
||
|
#pragma GCC reset_options
|
||
|
#endif
|
||
|
|
||
|
MODULE_LICENSE("GPL");
|
||
|
MODULE_DESCRIPTION("FIPS140 POST");
|