diff options
| author | Harinarayan Bhatta <hbhatta@nvidia.com> | 2021-07-16 00:14:00 -0400 |
|---|---|---|
| committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2021-10-04 10:41:59 -0400 |
| commit | 6df99be61d08babd56feeec4cd31e6a269bc496d (patch) | |
| tree | 57771445cf04741865e428c385a2925c707a8958 | |
| parent | 8eaae7f5c8647821846c217b5c8a8c6c0a10d1ee (diff) | |
hw_random: add tegra hw_random driver
Add Tegra HW random driver to support /dev/hwrng. This driver calls into
the tegra rng using the kernel crypto framework APIs.
Bug 3326341
Change-Id: I628632d52d24c29ea55eb5f6e2b86627b91594f6
Signed-off-by: Harinarayan Bhatta <hbhatta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2569911
Reviewed-by: Dmitry Pervushin <dpervushin@nvidia.com>
Reviewed-by: Rohit Upadhyay <rupadhyay@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
| -rw-r--r-- | drivers/char/hw_random/Kconfig | 18 | ||||
| -rw-r--r-- | drivers/char/hw_random/Makefile | 5 | ||||
| -rw-r--r-- | drivers/char/hw_random/tegra-rng.c | 78 |
3 files changed, 101 insertions, 0 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig new file mode 100644 index 000000000..279c3df3b --- /dev/null +++ b/drivers/char/hw_random/Kconfig | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | # | ||
| 2 | # Hardware Random Number Generator (RNG) configuration | ||
| 3 | # | ||
| 4 | |||
| 5 | if HW_RANDOM | ||
| 6 | |||
| 7 | config HW_RANDOM_TEGRA | ||
| 8 | tristate "Tegra Random Number Generator support" | ||
| 9 | depends on HW_RANDOM && CRYPTO_DEV_TEGRA_VIRTUAL_SE_INTERFACE | ||
| 10 | default HW_RANDOM | ||
| 11 | ---help--- | ||
| 12 | This driver provides kernel-side support for the Random Number | ||
| 13 | Generator hardware found on tegra. | ||
| 14 | |||
| 15 | If unsure, say N. | ||
| 16 | |||
| 17 | endif # HW_RANDOM | ||
| 18 | |||
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile new file mode 100644 index 000000000..449eadab7 --- /dev/null +++ b/drivers/char/hw_random/Makefile | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | # | ||
| 2 | # Makefile for HW Random Number Generator (RNG) device drivers. | ||
| 3 | # | ||
| 4 | |||
| 5 | obj-$(CONFIG_HW_RANDOM_TEGRA) += tegra-rng.o | ||
diff --git a/drivers/char/hw_random/tegra-rng.c b/drivers/char/hw_random/tegra-rng.c new file mode 100644 index 000000000..10d68dae2 --- /dev/null +++ b/drivers/char/hw_random/tegra-rng.c | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /* | ||
| 2 | * drivers/char/hw_random/tegra-rng.c | ||
| 3 | * | ||
| 4 | * hwrng dev node for NVIDIA tegra rng hardware | ||
| 5 | * | ||
| 6 | * Copyright (c) 2021, NVIDIA Corporation. All Rights Reserved. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
| 14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 16 | * more details. | ||
| 17 | */ | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/time.h> | ||
| 20 | #include <linux/delay.h> | ||
| 21 | #include <linux/hw_random.h> | ||
| 22 | #include <crypto/rng.h> | ||
| 23 | |||
| 24 | #define MODULE_NAME "tegra-rng" | ||
| 25 | #define RETRY_TIMEOUT_SECS 2 | ||
| 26 | |||
| 27 | static int tegra_rng_read(struct hwrng *h, void *data, size_t max, bool wait) | ||
| 28 | { | ||
| 29 | int ret; | ||
| 30 | struct crypto_rng *rng; | ||
| 31 | unsigned long t; | ||
| 32 | |||
| 33 | if (!wait) | ||
| 34 | return 0; | ||
| 35 | |||
| 36 | rng = crypto_alloc_rng("rng1-elp-tegra", | ||
| 37 | CRYPTO_ALG_TYPE_RNG, 0); | ||
| 38 | if (IS_ERR(rng)) { | ||
| 39 | pr_err("crypto_alloc_rng(rng1-elp-tegra) failed: %ld\n", | ||
| 40 | PTR_ERR(rng)); | ||
| 41 | return PTR_ERR(rng); | ||
| 42 | } | ||
| 43 | t = get_seconds(); | ||
| 44 | do { | ||
| 45 | ret = crypto_rng_get_bytes(rng, data, max); | ||
| 46 | if (ret != -EAGAIN) | ||
| 47 | break; | ||
| 48 | msleep_interruptible(20); | ||
| 49 | } while ((get_seconds() - t) <= RETRY_TIMEOUT_SECS); | ||
| 50 | |||
| 51 | /* crypto_rng_get_bytes returns 0 upon success */ | ||
| 52 | if (ret == 0) | ||
| 53 | ret = max; | ||
| 54 | |||
| 55 | crypto_free_rng(rng); | ||
| 56 | return ret; | ||
| 57 | } | ||
| 58 | |||
| 59 | static struct hwrng tegra_rng = { | ||
| 60 | .name = MODULE_NAME, | ||
| 61 | .read = tegra_rng_read, | ||
| 62 | }; | ||
| 63 | |||
| 64 | static int __init tegra_rng_init(void) | ||
| 65 | { | ||
| 66 | return hwrng_register(&tegra_rng); | ||
| 67 | } | ||
| 68 | module_init(tegra_rng_init); | ||
| 69 | |||
| 70 | static void __exit tegra_rng_exit(void) | ||
| 71 | { | ||
| 72 | hwrng_unregister(&tegra_rng); | ||
| 73 | } | ||
| 74 | module_exit(tegra_rng_exit); | ||
| 75 | |||
| 76 | MODULE_DESCRIPTION("RNG driver for Tegra devices"); | ||
| 77 | MODULE_AUTHOR("Harinarayan Bhatta <hbhatta@nvidia.com>"); | ||
| 78 | MODULE_LICENSE("GPL v2"); | ||
