From: "Victoria Milhoan (b42089)" <vicki.milhoan@xxxxxxxxxxxxx> CAAM includes a Random Number Generator. This change adds a kernel configuration option to test the RNG's capabilities via the hw_random framework. Signed-off-by: Victoria Milhoan <vicki.milhoan@xxxxxxxxxxxxx> Signed-off-by: Dan Douglass <dan.douglass@xxxxxxx> Signed-off-by: Vipul Kumar <vipul_kumar@xxxxxxxxxx> Signed-off-by: Horia Geantă <horia.geanta@xxxxxxx> Signed-off-by: Meenakshi Aggarwal <meenakshi.aggarwal@xxxxxxx> --- drivers/crypto/caam/Kconfig | 9 +++++++ drivers/crypto/caam/caamrng.c | 48 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/drivers/crypto/caam/Kconfig b/drivers/crypto/caam/Kconfig index ec6a9e6ad4d2..c631f99e415f 100644 --- a/drivers/crypto/caam/Kconfig +++ b/drivers/crypto/caam/Kconfig @@ -162,6 +162,15 @@ config CRYPTO_DEV_FSL_CAAM_PRNG_API config CRYPTO_DEV_FSL_CAAM_BLOB_GEN bool +config CRYPTO_DEV_FSL_CAAM_RNG_TEST + bool "Test caam rng" + select CRYPTO_DEV_FSL_CAAM_RNG_API + help + Selecting this will enable a self-test to run for the + caam RNG. + This test is several minutes long and executes + just before the RNG is registered with the hw_random API. + endif # CRYPTO_DEV_FSL_CAAM_JR endif # CRYPTO_DEV_FSL_CAAM diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c index 50eb55da45c2..b3d14a7f4dd1 100644 --- a/drivers/crypto/caam/caamrng.c +++ b/drivers/crypto/caam/caamrng.c @@ -172,6 +172,50 @@ static void caam_cleanup(struct hwrng *rng) kfifo_free(&ctx->fifo); } +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST +static inline void test_len(struct hwrng *rng, size_t len, bool wait) +{ + u8 *buf; + int read_len; + struct caam_rng_ctx *ctx = to_caam_rng_ctx(rng); + struct device *dev = ctx->ctrldev; + + buf = kcalloc(CAAM_RNG_MAX_FIFO_STORE_SIZE, sizeof(u8), GFP_KERNEL); + + while (len > 0) { + read_len = rng->read(rng, buf, len, wait); + + if (read_len < 0 || (read_len == 0 && wait)) { + dev_err(dev, "RNG Read FAILED received %d bytes\n", + read_len); + kfree(buf); + return; + } + + print_hex_dump_debug("random bytes@: ", + DUMP_PREFIX_ADDRESS, 16, 4, + buf, read_len, 1); + + len = len - read_len; + } + + kfree(buf); +} + +static inline void test_mode_once(struct hwrng *rng, bool wait) +{ + test_len(rng, 32, wait); + test_len(rng, 64, wait); + test_len(rng, 128, wait); +} + +static void self_test(struct hwrng *rng) +{ + pr_info("Executing RNG SELF-TEST with wait\n"); + test_mode_once(rng, true); +} +#endif + static int caam_init(struct hwrng *rng) { struct caam_rng_ctx *ctx = to_caam_rng_ctx(rng); @@ -258,6 +302,10 @@ int caam_rng_init(struct device *ctrldev) return ret; } +#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_RNG_TEST + self_test(&ctx->rng); +#endif + devres_close_group(ctrldev, caam_rng_init); return 0; } -- 2.25.1