summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Marble <tmarble@info9.net>2015-03-11 15:12:11 -0500
committerTom Marble <tmarble@info9.net>2015-03-11 15:12:11 -0500
commit9ae9bea5b59c8f0e012c6b58f95f7a6641ef9bdc (patch)
tree279a6b5f706cea820b0bb1d6344745e2d2260153
parentfce4e6926de7cb5ef6ea64a8db134c442b86153b (diff)
Added FIPS 140-2 sanity check to usbtrng-v2.0
-rw-r--r--src/drivers/ao_trng.c142
-rw-r--r--src/drivers/ao_trng.h3
-rw-r--r--src/usbtrng-v2.0/ao_usbtrng.c2
3 files changed, 143 insertions, 4 deletions
diff --git a/src/drivers/ao_trng.c b/src/drivers/ao_trng.c
index db742928..b8e25e28 100644
--- a/src/drivers/ao_trng.c
+++ b/src/drivers/ao_trng.c
@@ -20,6 +20,120 @@
#include <ao_crc.h>
#include <ao_trng.h>
+
+static struct ao_task ao_blink_red_task;
+static uint8_t ao_failed = 0;
+
+static void
+ao_blink_red(void)
+{
+ for (;;) {
+ while (!ao_failed)
+ ao_sleep(&ao_failed);
+ while (ao_failed) {
+ ao_led_toggle(AO_LED_RED);
+ ao_delay(AO_MS_TO_TICKS(500));
+ }
+ }
+}
+
+static struct ao_task ao_blink_green_task;
+static uint8_t ao_blinking_green = 0;
+
+static void
+ao_blink_green(void)
+{
+ for (;;) {
+ while (!ao_blinking_green)
+ ao_sleep(&ao_blinking_green);
+ while (ao_blinking_green) {
+ ao_led_toggle(AO_LED_GREEN);
+ ao_delay(AO_MS_TO_TICKS(1000));
+ }
+ }
+}
+
+
+static void
+ao_blink_green_toggle(void)
+{
+ ao_blinking_green = !ao_blinking_green;
+ if (!ao_blinking_green)
+ ao_led_off(AO_LED_GREEN);
+ ao_wakeup(&ao_blinking_green);
+}
+
+#define ADC_WORDS (AO_USB_IN_SIZE / sizeof (uint16_t))
+static uint16_t prev16 = 0;
+static uint16_t adc_values[ADC_WORDS];
+static uint8_t adc_i = ADC_WORDS;
+
+static uint16_t
+fetch16(uint8_t initialize)
+{
+ uint32_t *rnd;
+ uint8_t i;
+
+ if (ao_failed)
+ return 0;
+ if (initialize)
+ adc_i = ADC_WORDS;
+ if (adc_i == ADC_WORDS) {
+ rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE); /* one 16-bit value per output byte */
+ adc_i = 0;
+ for (i = 0; i < ADC_WORDS; i++) {
+ adc_values[i] = ao_crc_in_32_out_16(*rnd++);
+ }
+ }
+ if (initialize)
+ prev16 = adc_values[adc_i++];
+ if (adc_values[adc_i] == prev16) {
+ /* FAILED: how do we prevent spewing bad data? */
+ printf("FAILED value %d repeated\n", prev16);
+ ao_failed = 1;
+ ao_wakeup(&ao_failed);
+ return 0;
+ }
+ prev16 = adc_values[adc_i];
+ adc_i++;
+ return prev16;
+}
+
+static void
+ao_simulate_failure(void)
+{
+ if (adc_i == ADC_WORDS)
+ fetch16(0);
+ prev16 = adc_values[adc_i];
+}
+
+/* NOTE: the reset function also functions as the Power On Self Test */
+void
+ao_reset(void)
+{
+ uint32_t count;
+
+ printf("Power On Self Test\n"); /* DEBUGGING */
+ ao_failed = 0;
+ ao_led_off(AO_LED_RED);
+ ao_wakeup(&ao_failed);
+ fetch16(1);
+ /* get the first 1k bits and ensure there are no duplicates */
+ count = 1024 / sizeof (uint16_t);
+ while (count-- && !ao_failed) {
+ fetch16(0);
+ }
+ if (ao_failed) { /* show failure */
+ printf("FAILED self test\n");
+ } else { /* show success */
+ printf("PASS - operation NOMINAL\n");
+ /* this blocks! */
+ ao_led_on(AO_LED_GREEN);
+ ao_delay(AO_MS_TO_TICKS(1000));
+ ao_led_off(AO_LED_GREEN);
+ }
+}
+
static void
ao_trng_fetch(void)
{
@@ -29,7 +143,6 @@ ao_trng_fetch(void)
int usb_buf_id;
uint16_t i;
uint16_t *buf;
- uint32_t *rnd;
if (!buffer[0]) {
buffer[0] = ao_usb_alloc();
@@ -50,10 +163,9 @@ ao_trng_fetch(void)
ao_led_on(AO_LED_TRNG_READ);
while (count--) {
- rnd = (uint32_t *) ao_adc_get(AO_USB_IN_SIZE); /* one 16-bit value per output byte */
buf = buffer[usb_buf_id];
for (i = 0; i < AO_USB_IN_SIZE / sizeof (uint16_t); i++)
- *buf++ = ao_crc_in_32_out_16(*rnd++);
+ *buf++ = fetch16(0);
ao_adc_ack(AO_USB_IN_SIZE);
ao_led_toggle(AO_LED_TRNG_READ|AO_LED_TRNG_WRITE);
ao_usb_write(buffer[usb_buf_id], AO_USB_IN_SIZE);
@@ -64,13 +176,35 @@ ao_trng_fetch(void)
flush();
}
+static void
+ao_trng_word(void)
+{
+ printf("%d\n", fetch16(0));
+}
+
+static void
+ao_status(void)
+{
+ if (ao_failed)
+ printf("FAILED\n");
+ else
+ printf("NOMINAL\n");
+}
+
static const struct ao_cmds ao_trng_cmds[] = {
- { ao_trng_fetch, "f <kbytes>\0Fetch a block of numbers" },
+ { ao_trng_fetch, "f <kbytes>\0Fetch a block of numbers" },
+ { ao_trng_word, "F\0Fetch 16 bit unsigned int" },
+ { ao_reset, "R\0reset" },
+ { ao_blink_green_toggle, "G\0Toggle green LED blinking" },
+ { ao_status, "s\0show status" },
+ { ao_simulate_failure, "z\0simulate failure" },
{ 0, NULL },
};
void
ao_trng_init(void)
{
+ ao_add_task(&ao_blink_red_task, ao_blink_red, "blink_red");
+ ao_add_task(&ao_blink_green_task, ao_blink_green, "blink_green");
ao_cmd_register(ao_trng_cmds);
}
diff --git a/src/drivers/ao_trng.h b/src/drivers/ao_trng.h
index 78577428..089c70c6 100644
--- a/src/drivers/ao_trng.h
+++ b/src/drivers/ao_trng.h
@@ -21,4 +21,7 @@
void
ao_trng_init(void);
+void
+ao_reset(void);
+
#endif /* _AO_TRNG_H_ */
diff --git a/src/usbtrng-v2.0/ao_usbtrng.c b/src/usbtrng-v2.0/ao_usbtrng.c
index 42713b6e..d4a75197 100644
--- a/src/usbtrng-v2.0/ao_usbtrng.c
+++ b/src/usbtrng-v2.0/ao_usbtrng.c
@@ -40,4 +40,6 @@ void main(void)
ao_led_off(AO_LED_RED);
ao_start_scheduler();
+
+ ao_reset(); /* Power On Self Test */
}