Skip to contentSkip to conversation

hwrng: add Microchip RNG90 support

PATCH In review Patrick Tudor 3 participants 6 messages Oct 24 – Oct 26

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover hwrng: add Microchip RNG90 support

The Microchip RNG90 is an I2C cryptographic random number generator at the fixed 0x40 address. It combines a physical noise source with a SHA-256 Hash_DRBG and returns a 256-bit result for each Random command. The device performs runtime health tests and self-tests before releasing output.

This series documents the compatible, adds the hwrng driver, and adds a KUnit suite using a scripted I2C adapter. The driver wakes and identifies the part, validates framing and CRCs, polls within data-sheet deadlines, recovers once from transport or synchronization failures, and withholds output after any device verdict or malformed response.

The data sheet specifies 128-bit security strength for each 256-bit result, but that does not establish entropy per output bit. The driver therefore starts at the hwrng framework's minimum nonzero quality of 1. An administrator can raise rng_quality after qualifying the complete platform and its operating conditions.

Validation against the base commit:

- dt_binding_check for trivial-devices.yaml
- full x86_64 defconfig build and a separate W=1 module rebuild
- UML KUnit: 32 tests passed

The driver was also exercised on physical RNG90 hardware through the in-tree hid-cp2112 adapter: three 500-block streams, hot unplug/replug, unbind/rebind, and S3 suspend/resume completed without driver errors.

---
Patrick Tudor (3):
dt-bindings: trivial-devices: add Microchip RNG90
hwrng: add Microchip RNG90 driver
hwrng: rng90: add KUnit tests

 .../devicetree/bindings/trivial-devices.yaml       |   2 +
 drivers/char/hw_random/Kconfig                     |  26 +
 drivers/char/hw_random/Makefile                    |   1 +
 drivers/char/hw_random/rng90-kunit.c               | 820 +++++++++++++++++++++
 drivers/char/hw_random/rng90.c                     | 555 ++++++++++++++
 5 files changed, 1404 insertions(+)

---
base-commit: 5b0764a53235d3c77e1ed674e836e1b3fe1a4b1f
change-id: 20261024-rng90-submit-v1-705c3c70a116

Best regards,

Signature · 1 line
Patrick Tudor <[email protected]>
#1 lore raw

PATCH 1/3 dt-bindings: trivial-devices: add Microchip RNG90

Document the Microchip RNG90 I2C cryptographic random number generator. The device needs only a compatible string and reg property, so the trivial-devices schema is sufficient.

---
 Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
 1 file changed, 2 insertions(+)
Documentation/devicetree/bindings/trivial-devices.yaml +2 -0
index 3b7876c5a..503e18b2b 100644
@@ -314,6 +314,8 @@ properties:
           - microchip,mcp4019-502
             # Microchip 7-bit Single I2C Digital POT (50k)
           - microchip,mcp4019-503
+            # Microchip RNG90 random number generator
+          - microchip,rng90
             # PWM Fan Speed Controller With Fan Fault Detection
           - microchip,tc654
             # PWM Fan Speed Controller With Fan Fault Detection
Signature · 1 line
2.56.0
Acked-by on v1 1/3
#2 lore raw

Re: [PATCH 1/3] dt-bindings: trivial-devices: add Microchip RNG90

Quoted 8 lines · Patrick Tudor

Document the Microchip RNG90 I2C cryptographic random number generator. The device needs only a compatible string and reg property, so the trivial-devices schema is sufficient.

---
 Documentation/devicetree/bindings/trivial-devices.yaml | 2 ++
 1 file changed, 2 insertions(+)

Best regards,
Krzysztof

#3 lore raw

PATCH 2/3 hwrng: add Microchip RNG90 driver

In reply to Patrick Tudor

Add support for the Microchip RNG90 cryptographic random number generator over I2C.

The driver wakes and identifies the device, frames Info and Random commands, polls bounded execution deadlines, verifies response lengths and CRCs, and handles device health and self-test failures without exposing rejected output.

Use the minimum nonzero hwrng quality because the data sheet specifies output security strength but does not quantify entropy per output bit. The value remains adjustable through the hwrng sysfs interface after platform qualification.

Tested on physical RNG90 hardware through the in-tree hid-cp2112 adapter.

---
 drivers/char/hw_random/Kconfig  |  15 ++
 drivers/char/hw_random/Makefile |   1 +
 drivers/char/hw_random/rng90.c  | 551 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 567 insertions(+)
drivers/char/hw_random/Kconfig +15 -0
index 1bf5e3f8a..af276d476 100644
@@ -88,6 +88,21 @@ config HW_RANDOM_ATMEL
 
 	  If unsure, say Y.
 
+config HW_RANDOM_RNG90
+	tristate "Microchip RNG90 I2C random number generator"
+	depends on I2C
+	select CRC16
+	select BITREVERSE
+	help
+	  Support the Microchip RNG90 random number generator on I2C at 0x40.
+	  Command responses are checked for framing, device errors and CRC.
+	  The driver uses the minimum nonzero hwrng entropy estimate because
+	  the device's security strength does not quantify entropy per output
+	  bit. Administrators can raise the estimate after qualification.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called rng90.
+
 config HW_RANDOM_BA431
 	tristate "Silex Insight BA431 Random Number Generator support"
 	depends on HAS_IOMEM
drivers/char/hw_random/Makefile +1 -0
index 8fce2aa6c..852848297 100644
@@ -10,6 +10,7 @@ obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o
 obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o
 obj-$(CONFIG_HW_RANDOM_AIROHA) += airoha-trng.o
 obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o
+obj-$(CONFIG_HW_RANDOM_RNG90) += rng90.o
 obj-$(CONFIG_HW_RANDOM_BA431) += ba431-rng.o
 obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o
 obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o
drivers/char/hw_random/rng90.c new file +551 -0

551 lines not on this page · raw message

Signature · 1 line
2.56.0
#4 lore raw

PATCH 3/3 hwrng: rng90: add KUnit tests

In reply to Patrick Tudor

Exercise the RNG90 driver through the I2C core with a scripted adapter. The 32 cases cover published CRC vectors, exact command framing, wake and busy behavior, response validation, bounded recovery, health-failure latching, nonblocking reads, suspend and resume, cleanup, and device removal.

Keep the tests built-in-only so their deterministic fixture data can never be registered with the hwrng core.

---
 drivers/char/hw_random/Kconfig       |  11 +
 drivers/char/hw_random/rng90-kunit.c | 820 +++++++++++++++++++++++++++++++++++
 drivers/char/hw_random/rng90.c       |   4 +
 3 files changed, 835 insertions(+)
drivers/char/hw_random/Kconfig +11 -0
index af276d476..e0e9eaa44 100644
@@ -103,6 +103,17 @@ config HW_RANDOM_RNG90
 	  To compile this driver as a module, choose M here: the module
 	  will be called rng90.
 
+config HW_RANDOM_RNG90_KUNIT_TEST
+	bool "KUnit tests for the RNG90 driver" if !KUNIT_ALL_TESTS
+	depends on KUNIT=y && HW_RANDOM_RNG90=y
+	default KUNIT_ALL_TESTS
+	help
+	  Exercise the real driver against a scripted I2C adapter, without
+	  RNG90 hardware.
+	  Tests cover command framing, CRC validation and polling behavior.
+	  They also cover recovery, health failures, and suspend and resume.
+	  No predictable test data is registered with the hwrng core.
+
 config HW_RANDOM_BA431
 	tristate "Silex Insight BA431 Random Number Generator support"
 	depends on HAS_IOMEM
drivers/char/hw_random/rng90-kunit.c new file +820 -0

820 lines not on this page · raw message

drivers/char/hw_random/rng90.c +4 -0
index ec9ee3e27..9bac89cc4 100644
@@ -549,3 +549,7 @@ module_i2c_driver(rng90_driver);
 MODULE_AUTHOR("Patrick Tudor <[email protected]>");
 MODULE_DESCRIPTION("Microchip RNG90 I2C hardware random number generator");
 MODULE_LICENSE("GPL");
+
+#if IS_ENABLED(CONFIG_HW_RANDOM_RNG90_KUNIT_TEST)
+#include "rng90-kunit.c"
+#endif
Signature · 1 line
2.56.0
#5 lore raw

Re: [PATCH 3/3] hwrng: rng90: add KUnit tests

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [Medium] hwrng: rng90: NULL dereference in rng90_test_exit() if rng90_test_init() fails --

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] hwrng: rng90: NULL dereference in rng90_test_exit() if rng90_test_init() fails --

commit 738c911c8957ee3bcb09ed18f6daa72a41daed79
Author: Patrick Tudor <[email protected]>

hwrng: rng90: add KUnit tests

This commit adds built-in KUnit tests for the RNG90 hardware random number generator driver using a scripted I2C adapter to exercise command framing, CRC validation, polling, recovery, health failures, and power management.

Quoted 6 lines
drivers/char/hw_random/rng90-kunit.c new file +0 -0
new file mode 100644
index 0000000000000..f6daffb2e3d97
@@ -0,0 +1,820 @@

[ ... ]

Quoted 38 lines
drivers/char/hw_random/rng90-kunit.c new file +38 -0
+static int rng90_test_init(struct kunit *test)
+{
+	struct rng90_test_context *ctx;
+	int ret;
+
+	ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+	test->priv = ctx;
+	ctx->test = test;
+	ctx->adapter.owner = THIS_MODULE;
+	ctx->adapter.algo = &rng90_test_algorithm;
+	ctx->adapter.algo_data = ctx;
+	strscpy(ctx->adapter.name, "rng90-kunit", sizeof(ctx->adapter.name));
+	ret = i2c_add_adapter(&ctx->adapter);
+	if (ret)
+		return ret;
+	ctx->client = i2c_new_dummy_device(&ctx->adapter, RNG90_ADDRESS);
+	if (IS_ERR(ctx->client)) {
+		ret = PTR_ERR(ctx->client);
+		i2c_del_adapter(&ctx->adapter);
+		return ret;
+	}
+	ctx->priv.client = ctx->client;
+	mutex_init(&ctx->priv.lock);
+	i2c_set_clientdata(ctx->client, &ctx->priv);
+	/* Never register this predictable test source with the hwrng core. */
+	return 0;
+}
+
+/* Verify the script was consumed, allowing a final busy step at the deadline. */
+static void rng90_test_settled(struct rng90_test_context *ctx)
+{
+	if (ctx->next < ctx->count &&
+	    ctx->steps[ctx->next].repeat == RNG90_TEST_BUSY &&
+	    ctx->steps[ctx->next].hits)
+		ctx->next++;
+	KUNIT_EXPECT_EQ(ctx->test, ctx->next, ctx->count);

drivers/char/hw_random/rng90-kunit.c line 156

Quoted 10 lines
drivers/char/hw_random/rng90-kunit.c new file +10 -0
+}
+
+static void rng90_test_exit(struct kunit *test)
+{
+	struct rng90_test_context *ctx = test->priv;
+
+	rng90_test_settled(ctx);
+	i2c_unregister_device(ctx->client);
+	i2c_del_adapter(&ctx->adapter);
+}

[Severity: Medium]
Can rng90_test_exit() dereference a null pointer or repeat adapter teardown if rng90_test_init() fails?

In KUnit, kunit_run_case_catch_errors() invokes kunit_try_run_case_cleanup() -> kunit_run_case_cleanup() -> suite->exit(test) even when suite->init(test) returns a non-zero error code.

If kunit_kzalloc() fails in rng90_test_init(), test->priv remains NULL, and rng90_test_exit() will dereference ctx in rng90_test_settled(ctx), i2c_unregister_device(ctx->client), and i2c_del_adapter(&ctx->adapter).

Additionally, test->priv = ctx is assigned before i2c_add_adapter() and i2c_new_dummy_device(). If i2c_new_dummy_device() fails, rng90_test_init() calls i2c_del_adapter(&ctx->adapter) and leaves ctx->client as an error pointer, after which rng90_test_exit() will run and call i2c_del_adapter(&ctx->adapter) a second time.

Would it make sense to assign test->priv = ctx only after initialization succeeds in rng90_test_init(), and check for !ctx in rng90_test_exit() before cleaning up?

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3