Skip to content

Commit

Permalink
[nrf noup] entropy: Add fake entropy nRF PRNG driver
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
KAGA164 authored and nordicjm committed Apr 10, 2024
1 parent a76c880 commit c976657
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 0 deletions.
6 changes: 6 additions & 0 deletions boards/arm/nrf54h20dk_nrf54h20/nrf54h20dk_nrf54h20_cpuapp.dts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
zephyr,code-partition = &cpuapp_slot0_partition;
zephyr,flash = &mram1x;
zephyr,sram = &cpuapp_data;
zephyr,entropy = &prng;
};

aliases {
Expand Down Expand Up @@ -86,6 +87,11 @@
label = "Green LED 3";
};
};

prng: prng {
compatible = "nordic,entropy-prng";
status = "okay";
};
};

&cpuapp_ram0x_region {
Expand Down
6 changes: 6 additions & 0 deletions boards/arm/nrf54h20dk_nrf54h20/nrf54h20dk_nrf54h20_cpurad.dts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
zephyr,code-partition = &cpurad_slot0_partition;
zephyr,flash = &mram1x;
zephyr,sram = &cpurad_ram0;
zephyr,entropy = &prng;
};

prng: prng {
compatible = "nordic,entropy-prng";
status = "okay";
};
};

Expand Down
7 changes: 7 additions & 0 deletions drivers/entropy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_BT_HCI entropy_bt_hci.c)
zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_SE entropy_gecko_se.c)
zephyr_library_sources_ifdef(CONFIG_ENTROPY_PSA_CRYPTO_RNG entropy_psa_crypto.c)

if (CONFIG_FAKE_ENTROPY_NRF_PRNG)
zephyr_library_sources(fake_entropy_nrf_prng.c)

message(WARNING "\nA nRF PRNG is used, which does not produce real random bits."
"This is not secure and should therefore never be used in a product.")
endif()

if (CONFIG_BUILD_WITH_TFM)
target_include_directories(${ZEPHYR_CURRENT_LIBRARY} PRIVATE
$<TARGET_PROPERTY:tfm,TFM_BINARY_DIR>/api_ns/interface/include
Expand Down
1 change: 1 addition & 0 deletions drivers/entropy/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ source "drivers/entropy/Kconfig.gecko"
source "drivers/entropy/Kconfig.neorv32"
source "drivers/entropy/Kconfig.bt_hci"
source "drivers/entropy/Kconfig.psa_crypto"
source "drivers/entropy/Kconfig.nrf_prng"

config ENTROPY_HAS_DRIVER
bool
Expand Down
19 changes: 19 additions & 0 deletions drivers/entropy/Kconfig.nrf_prng
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# nRF fake entropy prng generator driver configuration

# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

if ENTROPY_GENERATOR

config FAKE_ENTROPY_NRF_PRNG
bool "A fake nRF entropy driver"
default y
depends on DT_HAS_NORDIC_ENTROPY_PRNG_ENABLED
depends on SOC_SERIES_NRF54HX
select ENTROPY_HAS_DRIVER
help
This is a super simple PRNG driver that can be used on nRF platforms that
do not have an entropy source.
This is NOT SAFE to use for cryptographic operations!

endif
101 changes: 101 additions & 0 deletions drivers/entropy/fake_entropy_nrf_prng.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/init.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <zephyr/drivers/entropy.h>

#define DT_DRV_COMPAT nordic_entropy_prng

/* This file implements a pseudo-RNG
* https://vigna.di.unimi.it/xorshift/xoshiro128plus.c
*/

static uint32_t s[4];

static inline uint32_t rotl(const uint32_t x, int k)
{
return (x << k) | (x >> (32 - k));
}

static uint32_t rng_next(void)
{
const uint32_t result = rotl(s[0] + s[3], 7) + s[0];

const uint32_t t = s[1] << 9;

s[2] ^= s[0];
s[3] ^= s[1];
s[1] ^= s[2];
s[0] ^= s[3];

s[2] ^= t;

s[3] = rotl(s[3], 11);

return result;
}

static int entropy_prng_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length)
{
ARG_UNUSED(dev);

while (length) {
/*
* Note that only 1 thread (Zephyr thread or HW models), runs at
* a time, therefore there is no need to use random_r()
*/
uint32_t value = rng_next();

size_t to_copy = MIN(length, sizeof(long));

memcpy(buffer, &value, to_copy);
buffer += to_copy;
length -= to_copy;
}

return 0;
}

static int entropy_prng_get_entropy_isr(const struct device *dev, uint8_t *buf, uint16_t len,
uint32_t flags)
{
ARG_UNUSED(flags);

int err;

/*
* entropy_prng_get_entropy() is also safe for ISRs
* and always produces data.
*/
err = entropy_prng_get_entropy(dev, buf, len);
if (err < 0) {
return err;
} else {
return len;
}
}

static int entropy_prng_init(const struct device *dev)
{
ARG_UNUSED(dev);

/* Picked some arbitrary initial seed. */
s[0] = 0xAF568BC0;
s[1] = 0xAC34307E;
s[2] = 0x9B7F6DD1;
s[3] = 0xD84319FC;
return 0;
}

static const struct entropy_driver_api entropy_prng_api_funcs = {
.get_entropy = entropy_prng_get_entropy, .get_entropy_isr = entropy_prng_get_entropy_isr};

DEVICE_DT_INST_DEFINE(0, entropy_prng_init, NULL, NULL, NULL, PRE_KERNEL_1,
CONFIG_ENTROPY_INIT_PRIORITY, &entropy_prng_api_funcs);
8 changes: 8 additions & 0 deletions dts/bindings/rng/nordic,nrf-prng.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2024 Nordic Semiconductor ASA
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause

description: This is a super simple PRNG

compatible: "nordic,entropy-prng"

include: base.yaml

0 comments on commit c976657

Please sign in to comment.