summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarinarayan Bhatta <hbhatta@nvidia.com>2021-07-16 00:14:00 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2021-10-04 10:41:59 -0400
commit6df99be61d08babd56feeec4cd31e6a269bc496d (patch)
tree57771445cf04741865e428c385a2925c707a8958
parent8eaae7f5c8647821846c217b5c8a8c6c0a10d1ee (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/Kconfig18
-rw-r--r--drivers/char/hw_random/Makefile5
-rw-r--r--drivers/char/hw_random/tegra-rng.c78
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
5if HW_RANDOM
6
7config 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
17endif # 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
5obj-$(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
27static 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
59static struct hwrng tegra_rng = {
60 .name = MODULE_NAME,
61 .read = tegra_rng_read,
62};
63
64static int __init tegra_rng_init(void)
65{
66 return hwrng_register(&tegra_rng);
67}
68module_init(tegra_rng_init);
69
70static void __exit tegra_rng_exit(void)
71{
72 hwrng_unregister(&tegra_rng);
73}
74module_exit(tegra_rng_exit);
75
76MODULE_DESCRIPTION("RNG driver for Tegra devices");
77MODULE_AUTHOR("Harinarayan Bhatta <hbhatta@nvidia.com>");
78MODULE_LICENSE("GPL v2");