These patch series introduce a generic rng driver for Trustzone
based kernel driver which would like to communicate with ATF
SIP services.
Patch #1 initials SMC fid table for Mediatek SIP interfaces and
adds HWRNG related SMC call.
Patch #2..3 adds mtk-sec-rng kernel driver for Trustzone based SoCs.
For MediaTek SoCs on ARMv8 with TrustZone enabled, peripherals like
entropy sources is not accessible from normal world (linux) and
rather accessible from secure world (ATF/TEE) only.
This driver aims to provide a generic interface to ATF rng service.
changes since v1:
- rename mt67xx-rng to mtk-sec-rng since all MediaTek ARMv8 SoCs can reuse
this driver.
- refine coding style and unnecessary check.
changes since v2:
- remove unused comments.
- remove redundant variable.
changes since v3:
- add dt-bindings for MediaTek rng with TrustZone enabled.
- revise HWRNG SMC call fid.
changes since v4:
- move bindings to the arm/firmware directory.
- revise driver init flow to check more property.
Neal Liu (3):
soc: mediatek: add SMC fid table for SIP interface
dt-bindings: rng: add bindings for MediaTek ARMv8 SoCs
hwrng: add mtk-sec-rng driver
.../arm/firmware/mediatek,mtk-sec-rng.txt | 18 +++
drivers/char/hw_random/Kconfig | 16 +++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/mtk-sec-rng.c | 103 ++++++++++++++++++
include/linux/soc/mediatek/mtk_sip_svc.h | 33 ++++++
5 files changed, 171 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/firmware/mediatek,mtk-sec-rng.txt
create mode 100644 drivers/char/hw_random/mtk-sec-rng.c
create mode 100644 include/linux/soc/mediatek/mtk_sip_svc.h
--
2.18.0
For MediaTek SoCs on ARMv8 with TrustZone enabled, peripherals like
entropy sources is not accessible from normal world (linux) and
rather accessible from secure world (ATF/TEE) only. This driver aims
to provide a generic interface to ATF rng service.
Signed-off-by: Neal Liu <[email protected]>
---
drivers/char/hw_random/Kconfig | 16 ++++++
drivers/char/hw_random/Makefile | 1 +
drivers/char/hw_random/mtk-sec-rng.c | 103 ++++++++++++++++++++++++++++++++++
3 files changed, 120 insertions(+)
create mode 100644 drivers/char/hw_random/mtk-sec-rng.c
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 25a7d8f..f08c852 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -398,6 +398,22 @@ config HW_RANDOM_MTK
If unsure, say Y.
+config HW_RANDOM_MTK_SEC
+ tristate "MediaTek Security Random Number Generator support"
+ depends on HW_RANDOM
+ depends on ARCH_MEDIATEK || COMPILE_TEST
+ default HW_RANDOM
+ help
+ This driver provides kernel-side support for the Random Number
+ Generator hardware found on MediaTek SoCs. The difference with
+ mtk-rng is the Random Number Generator hardware is secure
+ access only.
+
+ To compile this driver as a module, choose M here. the
+ module will be called mtk-sec-rng.
+
+ If unsure, say Y.
+
config HW_RANDOM_S390
tristate "S390 True Random Number Generator support"
depends on S390
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 7c9ef4a..bee5412 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-rng.o
obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o
obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o
obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o
+obj-$(CONFIG_HW_RANDOM_MTK_SEC) += mtk-sec-rng.o
obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o
obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o
obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
diff --git a/drivers/char/hw_random/mtk-sec-rng.c b/drivers/char/hw_random/mtk-sec-rng.c
new file mode 100644
index 0000000..69ddeca
--- /dev/null
+++ b/drivers/char/hw_random/mtk-sec-rng.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 MediaTek Inc.
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/hw_random.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/soc/mediatek/mtk_sip_svc.h>
+
+#define MTK_SEC_RNG_MAGIC 0x74726e67
+#define SMC_RET_NUM 4
+#define MTK_SEC_RND_SIZE (sizeof(u32) * SMC_RET_NUM)
+
+static void mtk_sec_get_rnd(uint32_t *val)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(MTK_SIP_KERNEL_GET_RND,
+ MTK_SEC_RNG_MAGIC, 0, 0, 0, 0, 0, 0, &res);
+
+ val[0] = res.a0;
+ val[1] = res.a1;
+ val[2] = res.a2;
+ val[3] = res.a3;
+}
+
+static int mtk_sec_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+ u32 val[4] = {0};
+ int retval = 0;
+ int i;
+
+ while (max >= MTK_SEC_RND_SIZE) {
+ mtk_sec_get_rnd(val);
+
+ for (i = 0; i < SMC_RET_NUM; i++) {
+ *(u32 *)buf = val[i];
+ buf += sizeof(u32);
+ }
+
+ retval += MTK_SEC_RND_SIZE;
+ max -= MTK_SEC_RND_SIZE;
+ }
+
+ return retval;
+}
+
+static struct hwrng mtk_sec_rng = {
+ .name = "mtk_sec_rng",
+ .read = mtk_sec_rng_read,
+ .quality = 900,
+};
+
+static int mtk_sec_rng_probe(void)
+{
+ int ret;
+
+ ret = hwrng_register(&mtk_sec_rng);
+ if (ret) {
+ pr_err("Failed to register rng device: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __init mtk_sec_rng_driver_init(void)
+{
+ struct device_node *fw_np;
+ struct device_node *np;
+ const char *method;
+
+ fw_np = of_find_node_by_name(NULL, "firmware");
+ if (!fw_np)
+ return -ENODEV;
+
+ np = of_find_compatible_node(fw_np, NULL, "mediatek,mtk-sec-rng");
+ if (!np)
+ return -ENODEV;
+
+ if (of_property_read_string(np, "method", &method))
+ return -ENXIO;
+
+ if (strncmp("smc", method, strlen("smc")))
+ return -EINVAL;
+
+ return mtk_sec_rng_probe();
+}
+
+static void __exit mtk_sec_rng_driver_exit(void)
+{
+ hwrng_unregister(&mtk_sec_rng);
+}
+
+module_init(mtk_sec_rng_driver_init);
+module_exit(mtk_sec_rng_driver_exit);
+
+MODULE_DESCRIPTION("MediaTek Security Random Number Generator Driver");
+MODULE_AUTHOR("Neal Liu <[email protected]>");
+MODULE_LICENSE("GPL");
--
1.7.9.5
Hi Neal,
On Wed, Nov 27, 2019 at 3:23 PM Neal Liu <[email protected]> wrote:
>
> For MediaTek SoCs on ARMv8 with TrustZone enabled, peripherals like
> entropy sources is not accessible from normal world (linux) and
> rather accessible from secure world (ATF/TEE) only. This driver aims
> to provide a generic interface to ATF rng service.
>
I am working on several SoCs that also will need this kind of driver
to get entropy from Arm trusted firmware.
If you intend to make this a generic interface, please clean up the
references to MediaTek and give it a more generic name. For example
"Arm Trusted Firmware random number driver".
It will also be helpful if the SMC call number is configurable.
- Lars
On 2019-12-03 04:16, Florian Fainelli wrote:
> On 12/2/2019 11:11 AM, Marc Zyngier wrote:
>> On Mon, 2 Dec 2019 16:12:09 +0000
>> Ard Biesheuvel <[email protected]> wrote:
>>
>>> (adding some more arm64 folks)
>>>
>>> On Fri, 29 Nov 2019 at 11:30, Neal Liu <[email protected]>
>>> wrote:
>>>>
>>>> On Fri, 2019-11-29 at 18:02 +0800, Lars Persson wrote:
>>>>> Hi Neal,
>>>>>
>>>>> On Wed, Nov 27, 2019 at 3:23 PM Neal Liu <[email protected]>
>>>>> wrote:
>>>>>>
>>>>>> For MediaTek SoCs on ARMv8 with TrustZone enabled, peripherals
>>>>>> like
>>>>>> entropy sources is not accessible from normal world (linux) and
>>>>>> rather accessible from secure world (ATF/TEE) only. This driver
>>>>>> aims
>>>>>> to provide a generic interface to ATF rng service.
>>>>>>
>>>>>
>>>>> I am working on several SoCs that also will need this kind of
>>>>> driver
>>>>> to get entropy from Arm trusted firmware.
>>>>> If you intend to make this a generic interface, please clean up
>>>>> the
>>>>> references to MediaTek and give it a more generic name. For
>>>>> example
>>>>> "Arm Trusted Firmware random number driver".
>>>>>
>>>>> It will also be helpful if the SMC call number is configurable.
>>>>>
>>>>> - Lars
>>>>
>>>> Yes, I'm trying to make this to a generic interface. I'll try to
>>>> make
>>>> HW/platform related dependency to be configurable and let it more
>>>> generic.
>>>> Thanks for your suggestion.
>>>>
>>>
>>> I don't think it makes sense for each arm64 platform to expose an
>>> entropy source via SMC calls in a slightly different way, and model
>>> it
>>> as a h/w driver. Instead, we should try to standardize this, and
>>> perhaps expose it via the architectural helpers that already exist
>>> (get_random_seed_long() and friends), so they get plugged into the
>>> kernel random pool driver directly.
>>
>> Absolutely. I'd love to see a standard, ARM-specified, virtualizable
>> RNG that is abstracted from the HW.
>
> Do you think we could use virtio-rng on top of a modified virtio-mmio
> which instead of being backed by a hardware mailbox, could use
> hvc/smc
> calls to signal writes to shared memory and get notifications via an
> interrupt? This would also open up the doors to other virtio uses
> cases
> beyond just RNG (e.g.: console, block devices?). If this is
> completely
> stupid, then please disregard this comment.
The problem with a virtio device is that it is a ... device. What we
want
is to be able to have access to an entropy source extremely early in
the
kernel life, and devices tend to be available pretty late in the game.
This means we cannot plug them in the architectural helpers that Ard
mentions above.
What you're suggesting looks more like a new kind of virtio transport,
which is interesting, in a remarkably twisted way... ;-)
Thanks,
M.
--
Jazz is not dead. It just smells funny...