LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver
@ 2021-07-31 20:48 Andre Przywara
  2021-07-31 20:48 ` [PATCH v4 1/2] firmware: smccc: Register smccc_trng platform device Andre Przywara
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Andre Przywara @ 2021-07-31 20:48 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, Mark Rutland, Lorenzo Pieralisi, Sudeep Holla
  Cc: linux-crypto, linux-arm-kernel, linux-kernel,
	Benjamin Herrenschmidt, Ard Biesheuvel, Mark Brown, Will Deacon,
	Ali Saidi, Jon Nettleton

The "Arm True Random Number Generator Firmware Interface"[1] provides
an SMCCC based interface to a true hardware random number generator.
So far we are using that in arch_get_random_seed(), but it might be
useful to expose the entropy through the /dev/hwrng device as well. This
allows to assess the quality of the implementation, by using "rngtest"
from the rng-tools package, for example.

Patch 1 creates a platform device, triggered by the previous discovery
of the SMCCC TRNG service.
Patch 2 implements a hw_random platform driver, which is instantiated
through this said platform device.

The driver can be loaded as module, or built into the kernel.

[1] https://developer.arm.com/documentation/den0098/latest/

Changelog v3 ... v4:
- drop pointless driver loading message
- drop unneeded init() routine

Changelog v2 ... v3:
- split platform device and driver

Changelog v1 ... v2:
- fix building as a module
- de-register device upon exit
- mention module name in Kconfig

Andre Przywara (2):
  firmware: smccc: Register smccc_trng platform device
  hwrng: Add Arm SMCCC TRNG based driver

 drivers/char/hw_random/Kconfig          |  14 +++
 drivers/char/hw_random/Makefile         |   1 +
 drivers/char/hw_random/arm_smccc_trng.c | 123 ++++++++++++++++++++++++
 drivers/firmware/smccc/smccc.c          |  17 ++++
 4 files changed, 155 insertions(+)
 create mode 100644 drivers/char/hw_random/arm_smccc_trng.c

-- 
2.17.6


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v4 1/2] firmware: smccc: Register smccc_trng platform device
  2021-07-31 20:48 [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver Andre Przywara
@ 2021-07-31 20:48 ` Andre Przywara
  2021-07-31 20:48 ` [PATCH v4 2/2] hwrng: Add Arm SMCCC TRNG based driver Andre Przywara
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andre Przywara @ 2021-07-31 20:48 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, Mark Rutland, Lorenzo Pieralisi, Sudeep Holla
  Cc: linux-crypto, linux-arm-kernel, linux-kernel,
	Benjamin Herrenschmidt, Ard Biesheuvel, Mark Brown, Will Deacon,
	Ali Saidi, Jon Nettleton

At the moment we probe for the Random Number Generator SMCCC service,
and use that in the core code (arch_get_random). However the hardware
entropy can also be useful to access from userland, and be it to assess
its quality.

Register a platform device when the SMCCC TRNG service is detected, to
allow a hw_random driver to hook onto this.

The function registering the device is deliberately made in a way which
allows expansion, so other services that could be exposed via a platform
device (or some other interface), can be added here easily.

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 drivers/firmware/smccc/smccc.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c
index 9f937b125ab0..60ccf3e90d7d 100644
--- a/drivers/firmware/smccc/smccc.c
+++ b/drivers/firmware/smccc/smccc.c
@@ -9,6 +9,7 @@
 #include <linux/init.h>
 #include <linux/arm-smccc.h>
 #include <linux/kernel.h>
+#include <linux/platform_device.h>
 #include <asm/archrandom.h>
 
 static u32 smccc_version = ARM_SMCCC_VERSION_1_0;
@@ -42,3 +43,19 @@ u32 arm_smccc_get_version(void)
 	return smccc_version;
 }
 EXPORT_SYMBOL_GPL(arm_smccc_get_version);
+
+static int __init smccc_devices_init(void)
+{
+	struct platform_device *pdev;
+
+	if (smccc_trng_available) {
+		pdev = platform_device_register_simple("smccc_trng", -1,
+						       NULL, 0);
+		if (IS_ERR(pdev))
+			pr_err("smccc_trng: could not register device: %ld\n",
+			       PTR_ERR(pdev));
+	}
+
+	return 0;
+}
+device_initcall(smccc_devices_init);
-- 
2.17.6


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v4 2/2] hwrng: Add Arm SMCCC TRNG based driver
  2021-07-31 20:48 [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver Andre Przywara
  2021-07-31 20:48 ` [PATCH v4 1/2] firmware: smccc: Register smccc_trng platform device Andre Przywara
@ 2021-07-31 20:48 ` Andre Przywara
  2021-08-01 16:26 ` [PATCH v4 0/2] " Ard Biesheuvel
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Andre Przywara @ 2021-07-31 20:48 UTC (permalink / raw)
  To: Matt Mackall, Herbert Xu, Mark Rutland, Lorenzo Pieralisi, Sudeep Holla
  Cc: linux-crypto, linux-arm-kernel, linux-kernel,
	Benjamin Herrenschmidt, Ard Biesheuvel, Mark Brown, Will Deacon,
	Ali Saidi, Jon Nettleton

The "Arm True Random Number Generator Firmware Interface"[1] provides
an SMCCC based interface to a true hardware random number generator.
So far we are using that in arch_get_random_seed(), but it might be
useful to expose the entropy through the /dev/hwrng device as well. This
allows to assess the quality of the implementation, by using "rngtest"
from the rng-tools package, for example.

Add a simple platform driver implementing the hw_random interface.
The corresponding platform device is created by the SMCCC core code,
we just match it here by name and provide a module alias.

Since the firmware takes care about serialisation, this can happily
coexist with the arch_get_random_seed() bits.

[1] https://developer.arm.com/documentation/den0098/latest/

Signed-off-by: Andre Przywara <andre.przywara@arm.com>
---
 drivers/char/hw_random/Kconfig          |  14 +++
 drivers/char/hw_random/Makefile         |   1 +
 drivers/char/hw_random/arm_smccc_trng.c | 123 ++++++++++++++++++++++++
 3 files changed, 138 insertions(+)
 create mode 100644 drivers/char/hw_random/arm_smccc_trng.c

diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 3f166c8a4099..239eca4d6805 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -524,6 +524,20 @@ config HW_RANDOM_XIPHERA
 	  To compile this driver as a module, choose M here: the
 	  module will be called xiphera-trng.
 
+config HW_RANDOM_ARM_SMCCC_TRNG
+	tristate "Arm SMCCC TRNG firmware interface support"
+	depends on HAVE_ARM_SMCCC_DISCOVERY
+	default HW_RANDOM
+	help
+	  Say 'Y' to enable the True Random Number Generator driver using
+	  the Arm SMCCC TRNG firmware interface. This reads entropy from
+	  higher exception levels (firmware, hypervisor). Uses SMCCC for
+	  communicating with the firmware:
+	  https://developer.arm.com/documentation/den0098/latest/
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called arm_smccc_trng.
+
 endif # HW_RANDOM
 
 config UML_RANDOM
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index 8933fada74f2..a5a1c765a394 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -45,3 +45,4 @@ obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o
 obj-$(CONFIG_HW_RANDOM_NPCM) += npcm-rng.o
 obj-$(CONFIG_HW_RANDOM_CCTRNG) += cctrng.o
 obj-$(CONFIG_HW_RANDOM_XIPHERA) += xiphera-trng.o
+obj-$(CONFIG_HW_RANDOM_ARM_SMCCC_TRNG) += arm_smccc_trng.o
diff --git a/drivers/char/hw_random/arm_smccc_trng.c b/drivers/char/hw_random/arm_smccc_trng.c
new file mode 100644
index 000000000000..b24ac39a903b
--- /dev/null
+++ b/drivers/char/hw_random/arm_smccc_trng.c
@@ -0,0 +1,123 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Randomness driver for the ARM SMCCC TRNG Firmware Interface
+ * https://developer.arm.com/documentation/den0098/latest/
+ *
+ *  Copyright (C) 2020 Arm Ltd.
+ *
+ * The ARM TRNG firmware interface specifies a protocol to read entropy
+ * from a higher exception level, to abstract from any machine specific
+ * implemenations and allow easier use in hypervisors.
+ *
+ * The firmware interface is realised using the SMCCC specification.
+ */
+
+#include <linux/bits.h>
+#include <linux/device.h>
+#include <linux/hw_random.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/arm-smccc.h>
+
+#ifdef CONFIG_ARM64
+#define ARM_SMCCC_TRNG_RND	ARM_SMCCC_TRNG_RND64
+#define MAX_BITS_PER_CALL	(3 * 64UL)
+#else
+#define ARM_SMCCC_TRNG_RND	ARM_SMCCC_TRNG_RND32
+#define MAX_BITS_PER_CALL	(3 * 32UL)
+#endif
+
+/* We don't want to allow the firmware to stall us forever. */
+#define SMCCC_TRNG_MAX_TRIES	20
+
+#define SMCCC_RET_TRNG_INVALID_PARAMETER	-2
+#define SMCCC_RET_TRNG_NO_ENTROPY		-3
+
+static int copy_from_registers(char *buf, struct arm_smccc_res *res,
+			       size_t bytes)
+{
+	unsigned int chunk, copied;
+
+	if (bytes == 0)
+		return 0;
+
+	chunk = min(bytes, sizeof(long));
+	memcpy(buf, &res->a3, chunk);
+	copied = chunk;
+	if (copied >= bytes)
+		return copied;
+
+	chunk = min((bytes - copied), sizeof(long));
+	memcpy(&buf[copied], &res->a2, chunk);
+	copied += chunk;
+	if (copied >= bytes)
+		return copied;
+
+	chunk = min((bytes - copied), sizeof(long));
+	memcpy(&buf[copied], &res->a1, chunk);
+
+	return copied + chunk;
+}
+
+static int smccc_trng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+{
+	struct arm_smccc_res res;
+	u8 *buf = data;
+	unsigned int copied = 0;
+	int tries = 0;
+
+	while (copied < max) {
+		size_t bits = min_t(size_t, (max - copied) * BITS_PER_BYTE,
+				  MAX_BITS_PER_CALL);
+
+		arm_smccc_1_1_invoke(ARM_SMCCC_TRNG_RND, bits, &res);
+		if ((int)res.a0 < 0)
+			return (int)res.a0;
+
+		switch ((int)res.a0) {
+		case SMCCC_RET_SUCCESS:
+			copied += copy_from_registers(buf + copied, &res,
+						      bits / BITS_PER_BYTE);
+			tries = 0;
+			break;
+		case SMCCC_RET_TRNG_NO_ENTROPY:
+			if (!wait)
+				return copied;
+			tries++;
+			if (tries >= SMCCC_TRNG_MAX_TRIES)
+				return copied;
+			cond_resched();
+			break;
+		}
+	}
+
+	return copied;
+}
+
+static int smccc_trng_probe(struct platform_device *pdev)
+{
+	struct hwrng *trng;
+
+	trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
+	if (!trng)
+		return -ENOMEM;
+
+	trng->name = "smccc_trng";
+	trng->read = smccc_trng_read;
+
+	platform_set_drvdata(pdev, trng);
+
+	return devm_hwrng_register(&pdev->dev, trng);
+}
+
+static struct platform_driver smccc_trng_driver = {
+	.driver = {
+		.name		= "smccc_trng",
+	},
+	.probe		= smccc_trng_probe,
+};
+module_platform_driver(smccc_trng_driver);
+
+MODULE_ALIAS("platform:smccc_trng");
+MODULE_AUTHOR("Andre Przywara");
+MODULE_LICENSE("GPL");
-- 
2.17.6


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver
  2021-07-31 20:48 [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver Andre Przywara
  2021-07-31 20:48 ` [PATCH v4 1/2] firmware: smccc: Register smccc_trng platform device Andre Przywara
  2021-07-31 20:48 ` [PATCH v4 2/2] hwrng: Add Arm SMCCC TRNG based driver Andre Przywara
@ 2021-08-01 16:26 ` Ard Biesheuvel
  2021-08-02 10:40 ` Mark Brown
  2021-08-06 12:14 ` Herbert Xu
  4 siblings, 0 replies; 6+ messages in thread
From: Ard Biesheuvel @ 2021-08-01 16:26 UTC (permalink / raw)
  To: Andre Przywara
  Cc: Matt Mackall, Herbert Xu, Mark Rutland, Lorenzo Pieralisi,
	Sudeep Holla, Linux Crypto Mailing List, Linux ARM,
	Linux Kernel Mailing List, Benjamin Herrenschmidt, Mark Brown,
	Will Deacon, Ali Saidi, Jon Nettleton

On Sat, 31 Jul 2021 at 22:49, Andre Przywara <andre.przywara@arm.com> wrote:
>
> The "Arm True Random Number Generator Firmware Interface"[1] provides
> an SMCCC based interface to a true hardware random number generator.
> So far we are using that in arch_get_random_seed(), but it might be
> useful to expose the entropy through the /dev/hwrng device as well. This
> allows to assess the quality of the implementation, by using "rngtest"
> from the rng-tools package, for example.
>
> Patch 1 creates a platform device, triggered by the previous discovery
> of the SMCCC TRNG service.
> Patch 2 implements a hw_random platform driver, which is instantiated
> through this said platform device.
>
> The driver can be loaded as module, or built into the kernel.
>
> [1] https://developer.arm.com/documentation/den0098/latest/
>
> Changelog v3 ... v4:
> - drop pointless driver loading message
> - drop unneeded init() routine
>
> Changelog v2 ... v3:
> - split platform device and driver
>
> Changelog v1 ... v2:
> - fix building as a module
> - de-register device upon exit
> - mention module name in Kconfig
>
> Andre Przywara (2):
>   firmware: smccc: Register smccc_trng platform device
>   hwrng: Add Arm SMCCC TRNG based driver
>

Reviewed-by: Ard Biesheuvel <ardb@kernel.org>


>  drivers/char/hw_random/Kconfig          |  14 +++
>  drivers/char/hw_random/Makefile         |   1 +
>  drivers/char/hw_random/arm_smccc_trng.c | 123 ++++++++++++++++++++++++
>  drivers/firmware/smccc/smccc.c          |  17 ++++
>  4 files changed, 155 insertions(+)
>  create mode 100644 drivers/char/hw_random/arm_smccc_trng.c
>
> --
> 2.17.6
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver
  2021-07-31 20:48 [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver Andre Przywara
                   ` (2 preceding siblings ...)
  2021-08-01 16:26 ` [PATCH v4 0/2] " Ard Biesheuvel
@ 2021-08-02 10:40 ` Mark Brown
  2021-08-06 12:14 ` Herbert Xu
  4 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2021-08-02 10:40 UTC (permalink / raw)
  To: Andre Przywara
  Cc: Matt Mackall, Herbert Xu, Mark Rutland, Lorenzo Pieralisi,
	Sudeep Holla, linux-crypto, linux-arm-kernel, linux-kernel,
	Benjamin Herrenschmidt, Ard Biesheuvel, Will Deacon, Ali Saidi,
	Jon Nettleton

[-- Attachment #1: Type: text/plain, Size: 514 bytes --]

On Sat, Jul 31, 2021 at 09:48:43PM +0100, Andre Przywara wrote:
> The "Arm True Random Number Generator Firmware Interface"[1] provides
> an SMCCC based interface to a true hardware random number generator.
> So far we are using that in arch_get_random_seed(), but it might be
> useful to expose the entropy through the /dev/hwrng device as well. This
> allows to assess the quality of the implementation, by using "rngtest"
> from the rng-tools package, for example.

Reviewed-by: Mark Brown <broonie@kernel.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver
  2021-07-31 20:48 [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver Andre Przywara
                   ` (3 preceding siblings ...)
  2021-08-02 10:40 ` Mark Brown
@ 2021-08-06 12:14 ` Herbert Xu
  4 siblings, 0 replies; 6+ messages in thread
From: Herbert Xu @ 2021-08-06 12:14 UTC (permalink / raw)
  To: Andre Przywara
  Cc: Matt Mackall, Mark Rutland, Lorenzo Pieralisi, Sudeep Holla,
	linux-crypto, linux-arm-kernel, linux-kernel,
	Benjamin Herrenschmidt, Ard Biesheuvel, Mark Brown, Will Deacon,
	Ali Saidi, Jon Nettleton

On Sat, Jul 31, 2021 at 09:48:43PM +0100, Andre Przywara wrote:
> The "Arm True Random Number Generator Firmware Interface"[1] provides
> an SMCCC based interface to a true hardware random number generator.
> So far we are using that in arch_get_random_seed(), but it might be
> useful to expose the entropy through the /dev/hwrng device as well. This
> allows to assess the quality of the implementation, by using "rngtest"
> from the rng-tools package, for example.
> 
> Patch 1 creates a platform device, triggered by the previous discovery
> of the SMCCC TRNG service.
> Patch 2 implements a hw_random platform driver, which is instantiated
> through this said platform device.
> 
> The driver can be loaded as module, or built into the kernel.
> 
> [1] https://developer.arm.com/documentation/den0098/latest/
> 
> Changelog v3 ... v4:
> - drop pointless driver loading message
> - drop unneeded init() routine
> 
> Changelog v2 ... v3:
> - split platform device and driver
> 
> Changelog v1 ... v2:
> - fix building as a module
> - de-register device upon exit
> - mention module name in Kconfig
> 
> Andre Przywara (2):
>   firmware: smccc: Register smccc_trng platform device
>   hwrng: Add Arm SMCCC TRNG based driver
> 
>  drivers/char/hw_random/Kconfig          |  14 +++
>  drivers/char/hw_random/Makefile         |   1 +
>  drivers/char/hw_random/arm_smccc_trng.c | 123 ++++++++++++++++++++++++
>  drivers/firmware/smccc/smccc.c          |  17 ++++
>  4 files changed, 155 insertions(+)
>  create mode 100644 drivers/char/hw_random/arm_smccc_trng.c

All applied.  Thanks.
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-08-06 12:15 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-31 20:48 [PATCH v4 0/2] hwrng: Add Arm SMCCC TRNG based driver Andre Przywara
2021-07-31 20:48 ` [PATCH v4 1/2] firmware: smccc: Register smccc_trng platform device Andre Przywara
2021-07-31 20:48 ` [PATCH v4 2/2] hwrng: Add Arm SMCCC TRNG based driver Andre Przywara
2021-08-01 16:26 ` [PATCH v4 0/2] " Ard Biesheuvel
2021-08-02 10:40 ` Mark Brown
2021-08-06 12:14 ` Herbert Xu

This is a public inbox, see mirroring instructions
on how to clone and mirror all data and code used for this inbox