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"); | ||