Merge pull request #389 from stnolting/trng_update

🔒 [TRNG] add read data security feature
This commit is contained in:
Stephan Nolting 2022-08-19 09:50:41 +02:00 committed by GitHub
commit c76f98f296
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 43 additions and 35 deletions

View file

@ -26,12 +26,13 @@ mimpid = 0x01040312 => 01.04.03.12 => Version 01.04.03.12 => v1.4.3.12
* :sparkles: = new feature
* :test_tube: = new (experimental) feature
* :warning: = (major) change that might impact compatibility with previous versions
* :lock: = security issue
* :lock: = security-related
* :rocket: = release
| Date (*dd.mm.yyyy*) | Version | Comment |
|:-------------------:|:-------:|:--------|
| 18.08.2022 | 1.7.5.5 | :lock: add **TRNG** read data protection; [#389](https://github.com/stnolting/neorv32/pull/389) |
| 18.08.2022 | 1.7.5.4 | minor rtl cleanup in **PWM** module; [#388](https://github.com/stnolting/neorv32/pull/388) |
| 17.08.2022 | 1.7.5.3 | optimized **CPU front-end** - faster instruction fetch; [#387](https://github.com/stnolting/neorv32/pull/387) |
| 16.08.2022 | 1.7.5.2 | relocate TWI tri-state drivers; [#]386()https://github.com/stnolting/neorv32/pull/386 |

View file

@ -17,17 +17,15 @@
**Theory of Operation**
The NEORV32 true random number generator provides _physical_ true random numbers.
The NEORV32 true random number generator provides _physically_ true random numbers.
Instead of using a pseudo RNG like a LFSR, the TRNG uses a simple, straight-forward ring
oscillator concept as physical entropy source. Hence, voltage, thermal and also semiconductor manufacturing
fluctuations are used to provide a true physical entropy source.
The TRNG features a platform independent architecture without FPGA-specific primitives, macros or
attributes so it can be synthesized for _any_ FPGA.
The TRNG is based on the **neoTRNG V2**, which is a "spin-off project" of the
NEORV32 processor. More detailed information about the neoTRNG, it's architecture and a
detailed evaluation of the random number quality can be found it it's repository: https://github.com/stnolting/neoTRNG
attributes so it can be synthesized for _any_ FPGA. Ir is based on the **neoTRNG V2**, which is a "spin-off project" of the
NEORV32 processor. More detailed information about the neoTRNG, its architecture and a
detailed evaluation of the random number quality can be found it the neoTRNG repository: https://github.com/stnolting/neoTRNG
.Inferring Latches
[NOTE]
@ -36,17 +34,29 @@ as this is what we actually want: the TRNG is based on latches, which implement
.Simulation
[IMPORTANT]
When simulating the processor the TRNG is automatically set to "simulation mode". In this mode, the physical entropy
sources (= the ring oscillators) are replaced by a simple **pseudo RNG (LFSR)** providing very weak random data only.
When simulating the processor the NEORV32 TRNG is automatically set to "simulation mode". In this mode, the physical entropy
sources (= the ring oscillators) are replaced by a simple **pseudo RNG (LFSR)** providing weak pseudo-random data only.
The _TRNG_CTRL_SIM_MODE_ flag of the control register is set if simulation mode is active.
**Using the TRNG**
The TRNG features a single register for status and data access. When the _TRNG_CTRL_EN_ control register (`CTRL`)
bit is set, the TRNG is enabled and starts operation. As soon as the _TRNG_CTRL_VALID_ bit is set a random data byte
is available and can be obtained from the lowest 8 bits of the `CTRL` register
(_TRNG_CTRL_DATA_MSB_ : _TRNG_CTRL_DATA_LSB_).
The TRNG features a single control register `CTRL` for control, status check and data access. When the _TRNG_CTRL_EN_
bit is set, the TRNG is enabled and starts operation.
.TRNG Reset
[NOTE]
The TRNG core does not provide a dedicated reset. In order to ensure correct operations, the TRNG should be
disabled (=reset) by clearing the _TRNG_CTRL_EN_ and waiting some 1000s clock cycles before re-enabling it.
As soon as the _TRNG_CTRL_VALID_ bit is set a new random data byte is available and can be obtained from the lowest 8 bits
of the `CTRL` register (_TRNG_CTRL_DATA_MSB_ : _TRNG_CTRL_DATA_LSB_). If this bit is cleared, there is no valid data available
and the lowest 8 bit of the `CTRL` register are set to all-zero.
.Read Access Security
[NOTE]
The random data byte (_TRNG_CTRL_DATA_) in the control register is automatically cleared after each read access
to prevent software from reading the _same_ random data byte more than once.
An optional random data FIFO can be configured using the <<_io_trng_fifo>> generic. This FIFO automatically samples
new random data from the TRNG to provide some kind of _random data pool_ for applications, which require a large number
@ -54,12 +64,7 @@ of RND data in a short time. The minimal and default value for <<_io_trng_fifo>>
than a real FIFO); the generic has to be a power of two.
The random data FIFO can be cleared at any time either by disabling the TRNG via the _TRNG_CTRL_EN_ flag or by
setting the _TRNG_CTRL_FIFO_CLR_ flag. Note that this falg is write-only and auto clears after being set.
.TRNG Reset
[NOTE]
The TRNG core does not provide a dedicated reset. In order to ensure correct operations, the TRNG should be
disabled (=reset) by clearing the _TRNG_CTRL_EN_ and waiting some 1000s clock cycles before re-enabling it.
setting the _TRNG_CTRL_FIFO_CLR_ flag. Note that this flag is write-only and auto clears after being set.
**Register Map**
@ -70,7 +75,7 @@ disabled (=reset) by clearing the _TRNG_CTRL_EN_ and waiting some 1000s clock cy
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
.5+<| `0xffffffb8` .5+<| `NEORV32_TRNG.CTRL` <|`7:0` _TRNG_CTRL_DATA_MSB_ : _TRNG_CTRL_DATA_MSB_ ^| r/- <| 8-bit random data
<|`28` _TRNG_CTRL_FIFO_CLR_ ^| -/w <| clear data FIFO when set (auto clears)
<|`28` _TRNG_CTRL_FIFO_CLR_ ^| -/w <| flush random data FIFO when set (auto clears)
<|`29` _TRNG_CTRL_SIM_MODE_ ^| r/- <| simulation mode (PRNG!)
<|`30` _TRNG_CTRL_EN_ ^| r/w <| TRNG enable
<|`31` _TRNG_CTRL_VALID_ ^| r/- <| random data is valid when set

View file

@ -63,7 +63,7 @@ package neorv32_package is
-- Architecture Constants (do not modify!) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070504"; -- NEORV32 version - no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01070505"; -- NEORV32 version - no touchy!
constant archid_c : natural := 19; -- official RISC-V architecture ID - hands off!
-- Check if we're inside the Matrix -------------------------------------------------------

View file

@ -163,7 +163,9 @@ begin
-- read access --
data_o <= (others => '0');
if (rden = '1') then
data_o(ctrl_data_msb_c downto ctrl_data_lsb_c) <= fifo.rdata;
if (fifo.avail = '1') then -- make sure the same RND data byte cannot be read twice
data_o(ctrl_data_msb_c downto ctrl_data_lsb_c) <= fifo.rdata;
end if;
data_o(ctrl_sim_mode_c) <= bool_to_ulogic_f(sim_mode_c);
data_o(ctrl_en_c) <= enable;
data_o(ctrl_valid_c) <= fifo.avail;
@ -180,7 +182,7 @@ begin
NUM_INV_START => num_inv_start_c,
NUM_INV_INC => num_inv_inc_c,
NUM_INV_DELAY => num_inv_delay_c,
POST_PROC_EN => true, -- post-processing enabled!
POST_PROC_EN => true, -- post-processing enabled to improve "random quality"
IS_SIM => sim_mode_c
)
port map (
@ -191,7 +193,7 @@ begin
);
-- Data FIFO ------------------------------------------------------------------------------
-- Data FIFO ("Random Pool") --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
rnd_pool_fifo_inst: neorv32_fifo
generic map (

View file

@ -61,7 +61,7 @@ int neorv32_trng_available(void) {
/**********************************************************************//**
* Enable true random number generator. The TRNG control register bits are listed in #NEORV32_TRNG_CTRL_enum.
* Enable TRNG.
**************************************************************************/
void neorv32_trng_enable(void) {
@ -69,23 +69,25 @@ void neorv32_trng_enable(void) {
NEORV32_TRNG.CTRL = 0; // reset
// wait for all internal components to reset
for (i=0; i<256; i++) {
asm volatile ("nop");
}
NEORV32_TRNG.CTRL = 1 << TRNG_CTRL_EN; // activate
// "warm-up"
for (i=0; i<256; i++) {
asm volatile ("nop");
}
// clear random "pool"
// flush random data "pool"
neorv32_trng_fifo_clear();
}
/**********************************************************************//**
* Disable true random number generator.
* Disable TRNG.
**************************************************************************/
void neorv32_trng_disable(void) {
@ -94,28 +96,26 @@ void neorv32_trng_disable(void) {
/**********************************************************************//**
* Clear TRNG random data "pool" (data FIFO).
* Flush TRNG random data FIFO.
**************************************************************************/
void neorv32_trng_fifo_clear(void) {
NEORV32_TRNG.CTRL |= 1 << TRNG_CTRL_FIFO_CLR; // auto clears
NEORV32_TRNG.CTRL |= 1 << TRNG_CTRL_FIFO_CLR; // bit auto clears
}
/**********************************************************************//**
* Get random data byte from TRNG.
*
* @param[in,out] data uint8_t pointer for storing random data byte.
* @param[in,out] data uint8_t pointer for storing random data byte. Will be set to zero if no valid data available.
* @return Data is valid when 0 and invalid otherwise.
**************************************************************************/
int neorv32_trng_get(uint8_t *data) {
uint32_t ct_reg;
uint32_t tmp = NEORV32_TRNG.CTRL;
*data = (uint8_t)(tmp >> TRNG_CTRL_DATA_LSB);
ct_reg = NEORV32_TRNG.CTRL;
if (ct_reg & (1<<TRNG_CTRL_VALID)) { // output data valid?
*data = (uint8_t)(ct_reg >> TRNG_CTRL_DATA_LSB);
if (tmp & (1<<TRNG_CTRL_VALID)) { // output data valid?
return 0; // valid data
}
else {