mirror of
https://github.com/stnolting/neorv32.git
synced 2025-04-24 14:17:51 -04:00
Merge pull request #389 from stnolting/trng_update
🔒 [TRNG] add read data security feature
This commit is contained in:
commit
c76f98f296
5 changed files with 43 additions and 35 deletions
|
@ -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 |
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 -------------------------------------------------------
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue