Skip to content

Commit a902788

Browse files
KAGA164anangl
authored andcommitted
[nrf noup] entropy: Add fake entropy nRF PRNG driver
This adds temporary entropy driver simulation for nRF54h20 device since final entropy source is not available yet. TODO: Remove this commit when proper solution will be available. Jira: NCSDK-25947 Signed-off-by: Kamil Gawor <[email protected]> Signed-off-by: Robert Lubos <[email protected]> (cherry picked from commit c80ee99)
1 parent 83f3672 commit a902788

File tree

7 files changed

+147
-0
lines changed

7 files changed

+147
-0
lines changed

boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts

+6
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
zephyr,bt-hci-ipc = &ipc0;
3030
nordic,802154-spinel-ipc = &ipc0;
3131
zephyr,canbus = &can120;
32+
zephyr,entropy = &prng;
3233
};
3334

3435
aliases {
@@ -109,6 +110,11 @@
109110
pwms = <&pwm130 0 PWM_MSEC(20) PWM_POLARITY_NORMAL>;
110111
};
111112
};
113+
114+
prng: prng {
115+
compatible = "nordic,entropy-prng";
116+
status = "okay";
117+
};
112118
};
113119

114120
&cpuapp_ram0x_region {

boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@
2828
zephyr,ieee802154 = &cpurad_ieee802154;
2929
zephyr,bt-hci-ipc = &ipc0;
3030
nordic,802154-spinel-ipc = &ipc0;
31+
zephyr,entropy = &prng;
32+
};
33+
prng: prng {
34+
compatible = "nordic,entropy-prng";
35+
status = "okay";
3136
};
3237
aliases {
3338
ipc-to-cpusys = &cpurad_cpusys_ipc;

drivers/entropy/CMakeLists.txt

+7
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,11 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_SE entropy_gecko_se.
3434
zephyr_library_sources_ifdef(CONFIG_ENTROPY_PSA_CRYPTO_RNG entropy_psa_crypto.c)
3535
zephyr_library_sources_ifdef(CONFIG_ENTROPY_NPCX_DRBG entropy_npcx_drbg.c)
3636

37+
if (CONFIG_FAKE_ENTROPY_NRF_PRNG)
38+
zephyr_library_sources(fake_entropy_nrf_prng.c)
39+
40+
message(WARNING "\nA nRF PRNG is used, which does not produce real random bits."
41+
"This is not secure and should therefore never be used in a product.")
42+
endif()
43+
3744
zephyr_library_link_libraries_ifdef(CONFIG_BUILD_WITH_TFM tfm_api)

drivers/entropy/Kconfig

+1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ source "drivers/entropy/Kconfig.neorv32"
3636
source "drivers/entropy/Kconfig.bt_hci"
3737
source "drivers/entropy/Kconfig.psa_crypto"
3838
source "drivers/entropy/Kconfig.npcx"
39+
source "drivers/entropy/Kconfig.nrf_prng"
3940

4041
config ENTROPY_HAS_DRIVER
4142
bool

drivers/entropy/Kconfig.nrf_prng

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# nRF fake entropy prng generator driver configuration
2+
3+
# Copyright (c) 2024 Nordic Semiconductor ASA
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
if ENTROPY_GENERATOR
7+
8+
config FAKE_ENTROPY_NRF_PRNG
9+
bool "A fake nRF entropy driver"
10+
default y
11+
depends on DT_HAS_NORDIC_ENTROPY_PRNG_ENABLED
12+
depends on SOC_SERIES_NRF54HX
13+
select ENTROPY_HAS_DRIVER
14+
help
15+
This is a super simple PRNG driver that can be used on nRF platforms that
16+
do not have an entropy source.
17+
This is NOT SAFE to use for cryptographic operations!
18+
19+
endif
+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/init.h>
8+
#include <stdio.h>
9+
#include <stdlib.h>
10+
#include <string.h>
11+
#include <assert.h>
12+
#include <zephyr/drivers/entropy.h>
13+
14+
#define DT_DRV_COMPAT nordic_entropy_prng
15+
16+
/* This file implements a pseudo-RNG
17+
* https://vigna.di.unimi.it/xorshift/xoshiro128plus.c
18+
*/
19+
20+
static uint32_t s[4];
21+
22+
static inline uint32_t rotl(const uint32_t x, int k)
23+
{
24+
return (x << k) | (x >> (32 - k));
25+
}
26+
27+
static uint32_t rng_next(void)
28+
{
29+
const uint32_t result = rotl(s[0] + s[3], 7) + s[0];
30+
31+
const uint32_t t = s[1] << 9;
32+
33+
s[2] ^= s[0];
34+
s[3] ^= s[1];
35+
s[1] ^= s[2];
36+
s[0] ^= s[3];
37+
38+
s[2] ^= t;
39+
40+
s[3] = rotl(s[3], 11);
41+
42+
return result;
43+
}
44+
45+
static int entropy_prng_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length)
46+
{
47+
ARG_UNUSED(dev);
48+
49+
while (length) {
50+
/*
51+
* Note that only 1 thread (Zephyr thread or HW models), runs at
52+
* a time, therefore there is no need to use random_r()
53+
*/
54+
uint32_t value = rng_next();
55+
56+
size_t to_copy = MIN(length, sizeof(long));
57+
58+
memcpy(buffer, &value, to_copy);
59+
buffer += to_copy;
60+
length -= to_copy;
61+
}
62+
63+
return 0;
64+
}
65+
66+
static int entropy_prng_get_entropy_isr(const struct device *dev, uint8_t *buf, uint16_t len,
67+
uint32_t flags)
68+
{
69+
ARG_UNUSED(flags);
70+
71+
int err;
72+
73+
/*
74+
* entropy_prng_get_entropy() is also safe for ISRs
75+
* and always produces data.
76+
*/
77+
err = entropy_prng_get_entropy(dev, buf, len);
78+
if (err < 0) {
79+
return err;
80+
} else {
81+
return len;
82+
}
83+
}
84+
85+
static int entropy_prng_init(const struct device *dev)
86+
{
87+
ARG_UNUSED(dev);
88+
89+
/* Picked some arbitrary initial seed. */
90+
s[0] = 0xAF568BC0;
91+
s[1] = 0xAC34307E;
92+
s[2] = 0x9B7F6DD1;
93+
s[3] = 0xD84319FC;
94+
return 0;
95+
}
96+
97+
static const struct entropy_driver_api entropy_prng_api_funcs = {
98+
.get_entropy = entropy_prng_get_entropy, .get_entropy_isr = entropy_prng_get_entropy_isr};
99+
100+
DEVICE_DT_INST_DEFINE(0, entropy_prng_init, NULL, NULL, NULL, PRE_KERNEL_1,
101+
CONFIG_ENTROPY_INIT_PRIORITY, &entropy_prng_api_funcs);

dts/bindings/rng/nordic,nrf-prng.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
3+
4+
description: This is a super simple PRNG
5+
6+
compatible: "nordic,entropy-prng"
7+
8+
include: base.yaml

0 commit comments

Comments
 (0)