Skip to content

sys/random: add option to use HWRNG as source of randomness#14453

Merged
miri64 merged 2 commits intoRIOT-OS:masterfrom
benpicco:sys/random-hwrng
Jul 8, 2020
Merged

sys/random: add option to use HWRNG as source of randomness#14453
miri64 merged 2 commits intoRIOT-OS:masterfrom
benpicco:sys/random-hwrng

Conversation

@benpicco
Copy link
Contributor

@benpicco benpicco commented Jul 7, 2020

Contribution description

Add the prng_hwrng module to enable the HWRNG as source of all randomness, not just for seeding a PRNG.

saves ~260 bytes compared to using tinymt32.

Testing procedure

add USEMODULE += prng_hwrng to any application that uses the random module.

Issues/PRs references

@benpicco benpicco added Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation Area: sys Area: System labels Jul 7, 2020
@benpicco benpicco requested review from PeterKietzmann and pokgak July 7, 2020 13:58
@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jul 7, 2020
@miri64
Copy link
Member

miri64 commented Jul 7, 2020

Isn't this what #14324 is already trying?

USEMODULE += hashes
endif

ifneq (,$(filter prng_hwrng,$(USEMODULE)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really a PRNG if it is generating random numbers from hardware? ;-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea that feels like a hack - we could rename them all prng_% -> rng_impl_%

Having a single API for randomness in random.h makes sense - the caller doesn't care if that randomness is provided by a PRNG or a HWRNG

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They might, when it comes to timing, or when the deterministic behavior of a PRNG is actually required for some reason.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They might, when it comes to timing

In most cases the HWRNG will be plenty fast. It could be faster (#11924 😉), but hardly noticeable.

or when the deterministic behavior of a PRNG is actually required

Then the application should use a private instance of a PRNG.
The system RNG will be called by 'everyone', thereby severely hampering determinism.

Also mind you, this is just an option. An application developer can chose to select the HWRNG for everything and will get

  • cryptographically sound randomness
  • reduced code size

if they accept the drawbacks you mentioned.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if they accept the drawbacks you mentioned.

Perfect call-in for a documentation upgrade ;-).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add it to the documentation about the characteristics of the different PRNG implementations, but I couldn't find those either.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For most PRNG you can look it up in literature just searching for the name. This is not the case for the HWNRG.

@benpicco
Copy link
Contributor Author

benpicco commented Jul 7, 2020

I only skimmed #14324, but it looks like a replacement for when no HWRNG is available.

@PeterKietzmann
Copy link
Member

#14324 focuses entropy collection from alternative sources than a HWRNG, likely used for PRNG seeding. It is very unlikely however, that anyone would use them for more than seed generation due to the resource overhead.

I like the idea of this PR as an option to connect the HWRNG directly to random but basically agree that it mixes concepts. Ironically, some of our periph_hwrng implementations are actually (internally seeded) pseudo-random generators which mixes concepts as well since we typically assume a HWRNG to be a "true" random source.

IMO we miss separation between entropy sources, seed values, standard PRNGs and crypto PRNGs in RIOT and I am planning on improving the situation step by step. Back to this specific PR, I don't have a concrete opinion by now.

* - Simple Park-Miller PRNG
* - Musl C PRNG
* - Fortuna (CS)PRNG
* - Hardware Random Number Generator (non-seedable)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add it to the documentation about the characteristics of the different PRNG implementations, but I couldn't find those either.

I would just add it here with all the implications @PeterKietzmann mentioned with regards to true randomness and pseudo-randomness.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, is there more to add than 'read the data sheet of your MCU' 😃 ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least that the HWNRGs vary in how they generate random numbers and that not all are pseudo-number random generators but provide true randomness should also be added as a note.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit off-topic but anyway: One could spend a note here but IMO the HWRNG implementation should as well indicate its hardware random technology.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spend a note on what @PeterKietzmann?

@benpicco benpicco removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jul 8, 2020
@miri64 miri64 added Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines labels Jul 8, 2020
Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting an error when trying to compile:

$ USEMODULE=prng_hwnrg BOARD=iotlab-m3 IOTLAB_NODES=1 make -C tests/rng/ iotlab-exp
make: Entering directory '/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng'
Building application "tests_rng" for "iotlab-m3" with MCU "stm32".

"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/boards/iotlab-m3
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/boards/common/iotlab
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/core
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/cortexm_common
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/cortexm_common/periph
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32/bootloader
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32/periph
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32/stmclk
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32/vectors
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/drivers
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/drivers/periph_common
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/auto_init
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/div
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/fmt
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/isrpipe
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/luid
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/newlib_syscalls_default
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/pm_layered
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/random
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/shell
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/stdio_uart
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/test_utils/interactive_sync
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/tsrb
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/xtimer
/usr/lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/application_tests_rng/test.o: in function `test_init':
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/test.c:42: undefined reference to `random_init'
/usr/lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/application_tests_rng/test.o: in function `test_get_uint32':
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/test.c:88: undefined reference to `random_uint32'
/usr/lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/random/random.o: in function `auto_init_random':
/home/mlenders/Repositories/RIOT-OS/RIOT/sys/random/random.c:60: undefined reference to `random_init'
/usr/lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/random/random.o: in function `random_uint32_range':
/home/mlenders/Repositories/RIOT-OS/RIOT/sys/random/random.c:99: undefined reference to `random_uint32'
collect2: error: ld returned 1 exit status
make: *** [/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/../../Makefile.include:572: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/tests_rng.elf] Error 1
make: Leaving directory '/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng'

@benpicco
Copy link
Contributor Author

benpicco commented Jul 8, 2020

When I add USEMODULE += prng_hwrng to the Makefile I get

~/dev/RIOT/tests/rng (git)-[sys/random-hwrng] % make BOARD=iotlab-m3                                                                          :(
There are unsatisfied feature requirements: periph_hwrng
/home/benpicco/dev/RIOT/tests/rng/../../Makefile.include:886: *** You can let the build continue on expected errors by setting CONTINUE_ON_EXPECTED_ERRORS=1 to the command line.  Stop.

@miri64
Copy link
Member

miri64 commented Jul 8, 2020

When I add USEMODULE += prng_hwrng to the Makefile I get

~/dev/RIOT/tests/rng (git)-[sys/random-hwrng] % make BOARD=iotlab-m3                                                                          :(
There are unsatisfied feature requirements: periph_hwrng
/home/benpicco/dev/RIOT/tests/rng/../../Makefile.include:886: *** You can let the build continue on expected

I assumed the IoT-LAB has that feature. However, from how the module is structured, the linker should at least find the random_* functions and then complain about the hwnrg_ functions.

@miri64
Copy link
Member

miri64 commented Jul 8, 2020

USEMODULE=prng_hwnrg letters messed up ^^" its hw_rn_g

@miri64
Copy link
Member

miri64 commented Jul 8, 2020

Ok, now I get the more expected result:

$ USEMODULE=prng_hwrng BOARD=iotlab-m3 IOTLAB_NODES=1 make -C tests/rng/ iotlab-exp
make: Entering directory '/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng'
Building application "tests_rng" for "iotlab-m3" with MCU "stm32".

"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/boards/iotlab-m3
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/boards/common/iotlab
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/core
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/cortexm_common
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/cortexm_common/periph
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32/bootloader
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32/periph
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32/stmclk
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/cpu/stm32/vectors
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/drivers
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/drivers/periph_common
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/auto_init
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/div
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/fmt
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/isrpipe
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/luid
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/newlib_syscalls_default
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/pm_layered
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/random
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/shell
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/stdio_uart
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/test_utils/interactive_sync
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/tsrb
"make" -C /home/mlenders/Repositories/RIOT-OS/RIOT/sys/xtimer
/usr/lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/periph_common/init.o: in function `periph_init':
/home/mlenders/Repositories/RIOT-OS/RIOT/drivers/periph_common/init.c:77: undefined reference to `hwrng_init'
/usr/lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/application_tests_rng/test.o: in function `test_init':
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/test.c:46: undefined reference to `hwrng_init'
/usr/lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/application_tests_rng/test.o: in function `test_get_uint32':
/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/test.c:93: undefined reference to `hwrng_read'
/usr/lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/random/hwrng.o: in function `random_uint32':
/home/mlenders/Repositories/RIOT-OS/RIOT/sys/random/hwrng.c:27: undefined reference to `hwrng_read'
/usr/lib/gcc/arm-none-eabi/10.1.0/../../../../arm-none-eabi/bin/ld: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/random/random.o: in function `auto_init_random':
/home/mlenders/Repositories/RIOT-OS/RIOT/sys/random/random.c:52: undefined reference to `hwrng_read'
collect2: error: ld returned 1 exit status
make: *** [/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/../../Makefile.include:572: /home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/iotlab-m3/tests_rng.elf] Error 1
make: Leaving directory '/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng'

@miri64
Copy link
Member

miri64 commented Jul 8, 2020

Then let's use native. There tests/rng works:

make: Entering directory '/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng'


/home/mlenders/Repositories/RIOT-OS/RIOT/tests/rng/bin/native/tests_rng.elf 
RIOT native interrupts/signals initialized.
LED_RED_OFF
LED_GREEN_ON
RIOT native board initialized.
RIOT native hardware initialization complete.

main(): This is RIOT! (Version: 2020.07-devel-1820-g1330b-HEAD)
Starting shell...
> 
> 
> source 0
seed 1337
source 0
> seed 1337
Seed set to 1337
> fips
fips
Running FIPS 140-2 test, with seed 1337 using unknown PRNG.

- Monobit test: passed
- Poker test: passed
- Run test: passed
- Longrun test: passed

@miri64
Copy link
Member

miri64 commented Jul 8, 2020

Please squash!

Add the `prng_hwrng` module to enable the HWRNG as source of all randomness, not just
for seeding a PRNG.

saves ~260 bytes compared to using tinymt32.
@benpicco benpicco force-pushed the sys/random-hwrng branch from 1330b18 to 2f42347 Compare July 8, 2020 16:23
@benpicco
Copy link
Contributor Author

benpicco commented Jul 8, 2020

I tried on same54-xpro and there the HWRNG beats SHA1 PRNG

2020-07-08 18:21:56,022 # Running speed test, with seed 0 using SHA1 PRNG.
2020-07-08 18:21:56,023 # 
2020-07-08 18:21:56,027 # Running speed test for 10 seconds
2020-07-08 18:22:06,039 # Collected 263996 samples in 10.000122 seconds (103 KiB/s).
2020-07-08 18:26:10,795 # Running speed test, with seed 0 using Hardware RNG.
2020-07-08 18:26:10,795 # 
2020-07-08 18:26:10,799 # Running speed test for 10 seconds
2020-07-08 18:26:20,813 # Collected 3870965 samples in 10.000024 seconds (1512 KiB/s).
2020-07-08 18:26:29,431 #  distributions
2020-07-08 18:26:29,437 # Running distributions test, with seed 0 using Hardware RNG.
2020-07-08 18:26:29,437 # 
2020-07-08 18:26:29,539 # For 32-bit samples (min = 4946, max = 5158, avg = 5010):
2020-07-08 18:26:29,548 # 00: #########################################################################
2020-07-08 18:26:29,554 # 01: #########################################################################
2020-07-08 18:26:29,562 # 02: #########################################################################
2020-07-08 18:26:29,568 # 03: ##########################################################################
2020-07-08 18:26:29,574 # 04: #########################################################################
2020-07-08 18:26:29,583 # 05: ########################################################################
2020-07-08 18:26:29,589 # 06: ##########################################################################
2020-07-08 18:26:29,597 # 07: #########################################################################
2020-07-08 18:26:29,603 # 08: #########################################################################
2020-07-08 18:26:29,612 # 09: #########################################################################
2020-07-08 18:26:29,618 # 10: #########################################################################
2020-07-08 18:26:29,626 # 11: #########################################################################
2020-07-08 18:26:29,633 # 12: ##########################################################################
2020-07-08 18:26:29,638 # 13: ##########################################################################
2020-07-08 18:26:29,647 # 14: #########################################################################
2020-07-08 18:26:29,653 # 15: #########################################################################
2020-07-08 18:26:29,662 # 16: #########################################################################
2020-07-08 18:26:29,668 # 17: #########################################################################
2020-07-08 18:26:29,676 # 18: #########################################################################
2020-07-08 18:26:29,682 # 19: ##########################################################################
2020-07-08 18:26:29,691 # 20: #########################################################################
2020-07-08 18:26:29,697 # 21: #########################################################################
2020-07-08 18:26:29,703 # 22: #########################################################################
2020-07-08 18:26:29,711 # 23: #########################################################################
2020-07-08 18:26:29,717 # 24: ########################################################################
2020-07-08 18:26:29,726 # 25: #########################################################################
2020-07-08 18:26:29,732 # 26: #########################################################################
2020-07-08 18:26:29,740 # 27: #########################################################################
2020-07-08 18:26:29,747 # 28: ###########################################################################
2020-07-08 18:26:29,755 # 29: #########################################################################
2020-07-08 18:26:29,761 # 30: #########################################################################
2020-07-08 18:26:29,767 # 31: ##########################################################################
2020-07-08 18:28:09,870 #  fips
2020-07-08 18:28:09,873 # Running FIPS 140-2 test, with seed 0 using Hardware RNG.
2020-07-08 18:28:09,873 # 
2020-07-08 18:28:09,888 # - Monobit test: passed
2020-07-08 18:28:09,890 # - Poker test: passed
2020-07-08 18:28:09,891 # - Run test: passed
2020-07-08 18:28:09,894 # - Longrun test: passed

@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Jul 8, 2020
Copy link
Member

@miri64 miri64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

@miri64 miri64 merged commit 908ec47 into RIOT-OS:master Jul 8, 2020
@benpicco benpicco deleted the sys/random-hwrng branch July 8, 2020 17:43
@miri64 miri64 added this to the Release 2020.07 milestone Jul 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: sys Area: System CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants