Compare commits

5 Commits

Author SHA1 Message Date
Pol Henarejos
f009dc267c Adding --vid/--pid parameters.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-08-26 15:37:43 +02:00
Pol Henarejos
4137861a21 Update README.md
Added SP800-90B results.
2022-08-22 14:08:58 +02:00
Pol Henarejos
a79296b423 Added LED blinking methods.
It has three blink patterns depending on the state:
- Unmounted
- Mounted
- Processing

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-08-22 13:55:03 +02:00
Pol Henarejos
ad4119a653 Update README.md 2022-08-22 13:29:51 +02:00
Pol Henarejos
80b03d4e8e Removed unused libraries.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
2022-08-22 13:28:27 +02:00
4 changed files with 100 additions and 4 deletions

View File

@@ -1,6 +1,6 @@
# Raspberry Pi Pico Random Number Generator
** This fork includes an enhanced RNG to produce a true RNG. **
**This fork includes an enhanced RNG to transform a Pico onto a true hardware RNG.**
A basic random number generator that generates numbers from enviromental noise with the onboard DAC of the Raspberry Pi Pico. The project uses the Raspberry Pi Pico USB dev_lowlevel as a starting point. The Pico RNG is not meant to be FIPS 140-2 compliant as a stand-alone device by any means. However it does supply the Linux Kernel with random bits that is used with the appropriate entropy to achieve FIPS 140-2 compliant random numbers. Maybe one day the next gen Pico's will include an onboard crypto module.
@@ -89,8 +89,9 @@ Fig. 1 depicts the distribution of the bytes, from `0` to `255`. Ideally, it mus
Fig. 2 depicts the distribution of chi square tests and excess percentages. Ideally, the distribution of chi square tests must follow a chi square distribution with mean at `255`. Excess percentage distribution must follow a uniform distribution.
Pico-rng is also tested with `ent`, `rngtest` and `dieharder` tests. These are the results obtained with pico-rng:
Pico-rng is also tested with `ent`, `rngtest`, `sp800-90b` and `dieharder` tests. These are the results obtained with pico-rng:
### Ent
```
$ ent sample.rng
Entropy = 7.999999 bits per byte.
@@ -114,6 +115,7 @@ Serial correlation coefficient is 0.000006 (totally uncorrelated = 0.0).
These results show that pico-rng is pretty random.
### FIPS 140-2
```bash
$ cat sample.rng | rngtest
@@ -140,6 +142,27 @@ In these results, we have a total number of trials `429496 (429141+355)`.
- The acceptable result of Monobit test is `1` failed trial for every `9662` trials. For `429496` trials, the number of failed trials should be less than `429496/9662=44.45`.
- The acceptable result of Poker test is `1` failed trial for every `10078` trials. For `429496` trials, the number of failed trials should be less than `42.62`.
### SP800-90B
SP800-90b is the superseded version of FIPS 140-2 (`rngtest`). Can be obtained from here [https://github.com/usnistgov/SP800-90B_EntropyAssessment](https://github.com/usnistgov/SP800-90B_EntropyAssessment).
```bash
$ ./ea-iid sample.rng
Calculating baseline statistics...
H_original: 7.995587
H_bitstring: 0.999863
min(H_original, 8 X H_bitstring): 7.995587
** Passed chi square tests
** Passed length of longest repeated substring test
** Passed IID permutation tests
```
### Diehard
It is a set of different tests.
```bash
$ dieharder -a -g 201 -k 2 -Y 1 -m 2 -f sample.rng
#=============================================================================#

View File

@@ -2,7 +2,7 @@ add_executable(pico_rng
pico_rng.c
)
target_link_libraries(pico_rng PRIVATE pico_stdlib hardware_resets hardware_irq hardware_adc)
target_link_libraries(pico_rng PRIVATE pico_stdlib hardware_adc)
pico_enable_stdio_uart(pico_rng 1)
pico_add_extra_outputs(pico_rng)

View File

@@ -33,6 +33,22 @@ static inline uint32_t board_millis(void)
return to_ms_since_boot(get_absolute_time());
}
enum {
BLINK_NOT_MOUNTED = (250 << 16) | 250,
BLINK_MOUNTED = (250 << 16) | 250,
BLINK_SUSPENDED = (500 << 16) | 1000,
BLINK_PROCESSING = (50 << 16) | 50,
BLINK_ALWAYS_ON = UINT32_MAX,
BLINK_ALWAYS_OFF = 0
};
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
void led_set_blink(uint32_t mode) {
blink_interval_ms = mode;
}
// Device descriptors
#include "pico_rng.h"
@@ -521,6 +537,40 @@ void isr_usbctrl(void) {
}
}
void led_blinking_task() {
#ifdef PICO_DEFAULT_LED_PIN
static uint32_t start_ms = 0;
static uint8_t led_state = false;
static uint8_t led_color = PICO_DEFAULT_LED_PIN;
#ifdef PICO_DEFAULT_LED_PIN_INVERTED
uint32_t interval = !led_state ? blink_interval_ms & 0xffff : blink_interval_ms >> 16;
#else
uint32_t interval = led_state ? blink_interval_ms & 0xffff : blink_interval_ms >> 16;
#endif
// Blink every interval ms
if (board_millis() - start_ms < interval)
return; // not enough time
start_ms += interval;
gpio_put(led_color, led_state);
led_state ^= 1; // toggle
#endif
}
void led_off_all() {
#ifdef PIMORONI_TINY2040
gpio_put(TINY2040_LED_R_PIN, 1);
gpio_put(TINY2040_LED_G_PIN, 1);
gpio_put(TINY2040_LED_B_PIN, 1);
#else
#ifdef PICO_DEFAULT_LED_PIN
gpio_put(PICO_DEFAULT_LED_PIN, 0);
#endif
#endif
}
/**
* @brief EP0 in transfer complete. Either finish the SET_ADDRESS process, or receive a zero
* length status packet from the host.
@@ -559,6 +609,7 @@ void ep0_out_handler(uint8_t *buf, uint16_t len) {
* @param len the length of the random data in bytes
*/
void get_random_data(char *buf, uint16_t len) {
led_set_blink(BLINK_PROCESSING);
if (len > 64)
len = 64;
memset(buf, 0, len);
@@ -585,6 +636,7 @@ void get_random_data(char *buf, uint16_t len) {
}
memcpy(buf + i, &random_word, sizeof(random_word));
}
led_set_blink(BLINK_MOUNTED);
}
/**
@@ -610,6 +662,22 @@ int main(void) {
// Enable uart debug messages
stdio_init_all();
#ifdef PIMORONI_TINY2040
gpio_init(TINY2040_LED_R_PIN);
gpio_set_dir(TINY2040_LED_R_PIN, GPIO_OUT);
gpio_init(TINY2040_LED_G_PIN);
gpio_set_dir(TINY2040_LED_G_PIN, GPIO_OUT);
gpio_init(TINY2040_LED_B_PIN);
gpio_set_dir(TINY2040_LED_B_PIN, GPIO_OUT);
#else
#ifdef PICO_DEFAULT_LED_PIN
gpio_init(PICO_DEFAULT_LED_PIN);
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
#endif
#endif
led_off_all();
// ADC
adc_init();
adc_gpio_init(27);
@@ -623,6 +691,8 @@ int main(void) {
tight_loop_contents();
}
led_set_blink(BLINK_MOUNTED);
// Populate the TX buffer
get_random_data(ep1_buf, 64);
usb_start_transfer(usb_get_endpoint_configuration(EP1_IN_ADDR), ep1_buf, 64);
@@ -630,6 +700,7 @@ int main(void) {
// Everything is interrupt driven so just loop here
while (1) {
tight_loop_contents();
led_blinking_task();
}
return 0;

View File

@@ -13,6 +13,8 @@ parser = argparse.ArgumentParser(description="Raspberry Pi Pico Random Number Ge
parser.add_argument("--performance", action="store_true", help="Performance test the RNG.")
parser.add_argument("--endless", action="store_true", help="Outputs random bytes endlessly.")
parser.add_argument("--size", default="100", help="Number of bytes to output.")
parser.add_argument("--vid", default="0000", help="VID.")
parser.add_argument("--pid", default="0004", help="PID.")
args = parser.parse_args()
# If this is set, then the /dev/pico_rng file exists
@@ -24,7 +26,7 @@ if os.path.exists("/dev/pico_rng"):
# File does not exist, test with usb.core
if not rng_chardev:
# Get the device
rng = usb.core.find(idVendor=0x0000, idProduct=0x0004)
rng = usb.core.find(idVendor=int(args.vid, base=16), idProduct=int(args.pid, base=16))
assert rng is not None
# Get the configuration of the device