summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/hammer/board.c29
-rw-r--r--include/rollback.h13
-rw-r--r--test/build.mk3
-rw-r--r--test/entropy.c60
-rw-r--r--test/entropy.tasklist17
5 files changed, 122 insertions, 0 deletions
diff --git a/board/hammer/board.c b/board/hammer/board.c
index d50634aab8..b9f21acf1d 100644
--- a/board/hammer/board.c
+++ b/board/hammer/board.c
@@ -9,12 +9,14 @@
#include "touchpad_elan.h"
#include "gpio.h"
#include "hooks.h"
+#include "hwtimer.h"
#include "i2c.h"
#include "keyboard_raw.h"
#include "keyboard_scan.h"
#include "pwm.h"
#include "pwm_chip.h"
#include "registers.h"
+#include "rollback.h"
#include "task.h"
#include "timer.h"
#include "update_fw.h"
@@ -135,3 +137,30 @@ void board_usb_wake(void)
gpio_set_flags(GPIO_BASE_DET, GPIO_INPUT);
interrupt_enable();
}
+
+/*
+ * Get entropy based on Clock Recovery System, which is enabled on hammer to
+ * synchronize USB SOF with internal oscillator.
+ */
+int board_get_entropy(void *buffer, int len)
+{
+ int i = 0;
+ uint8_t *data = buffer;
+ uint32_t start;
+ /* We expect one SOF per ms, so wait at most 2ms. */
+ const uint32_t timeout = 2*MSEC;
+
+ for (i = 0; i < len; i++) {
+ STM32_CRS_ICR |= STM32_CRS_ICR_SYNCOKC;
+ start = __hw_clock_source_read();
+ while (!(STM32_CRS_ISR & STM32_CRS_ISR_SYNCOKF)) {
+ if ((__hw_clock_source_read() - start) > timeout)
+ return 0;
+ usleep(500);
+ }
+ /* Pick 8 bits, including FEDIR and 7 LSB of FECAP. */
+ data[i] = STM32_CRS_ISR >> 15;
+ }
+
+ return 1;
+}
diff --git a/include/rollback.h b/include/rollback.h
index e33403b330..51f945e089 100644
--- a/include/rollback.h
+++ b/include/rollback.h
@@ -44,6 +44,19 @@ int rollback_add_entropy(uint8_t *data, unsigned int len);
*/
int rollback_lock(void);
+/**
+ * Obtain some weak entropy (i.e. not guaranteed to be high quality), based on
+ * sensors or timing events.
+ *
+ * Must be defined if CONFIG_ROLLBACK_SECRET_SIZE is set. May sleep.
+ *
+ * @param buffer Buffer to fill with entropy.
+ * @param len Buffer length.
+ *
+ * @return true if the buffer was filled, false on error.
+ */
+int board_get_entropy(void *buffer, int len);
+
#endif
#endif /* __CROS_EC_ROLLBACK_H */
diff --git a/test/build.mk b/test/build.mk
index b92e263e8f..807d0f57b7 100644
--- a/test/build.mk
+++ b/test/build.mk
@@ -12,6 +12,8 @@ test-list-y=pingpong timer_calib timer_dos timer_jump mutex utils utils_str
test-list-$(BOARD_BDS)+=
test-list-$(BOARD_PIT)+=kb_scan stress
+test-list-$(BOARD_HAMMER)+=entropy
+
# Samus has board-specific chipset code, and the tests don't
# compile with it. Disable them for now.
test-list-$(BOARD_SAMUS)=
@@ -85,6 +87,7 @@ charge_manager-y=charge_manager.o
charge_manager_drp_charging-y=charge_manager.o
charge_ramp-y+=charge_ramp.o
console_edit-y=console_edit.o
+entropy-y=entropy.o
extpwr_gpio-y=extpwr_gpio.o
fan-y=fan.o
flash-y=flash.o
diff --git a/test/entropy.c b/test/entropy.c
new file mode 100644
index 0000000000..f01a3dd0a0
--- /dev/null
+++ b/test/entropy.c
@@ -0,0 +1,60 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Tests entropy source.
+ */
+
+#include "console.h"
+#include "common.h"
+#include "rollback.h"
+#include "test_util.h"
+#include "timer.h"
+#include "util.h"
+#include "watchdog.h"
+
+static int buckets[256];
+
+void run_test(void)
+{
+ const int loopcount = 512;
+
+ uint8_t buffer[32];
+ timestamp_t t0, t1;
+ int i, j;
+
+ memset(buckets, 0, sizeof(buckets));
+
+ for (i = 0; i < loopcount; i++) {
+ t0 = get_time();
+ if (!board_get_entropy(buffer, sizeof(buffer))) {
+ ccprintf("Cannot get entropy\n");
+ test_fail();
+ return;
+ }
+ t1 = get_time();
+ if (i == 0)
+ ccprintf("Got %d bytes in %ld us\n",
+ sizeof(buffer), t1.val - t0.val);
+
+ for (j = 0; j < sizeof(buffer); j++)
+ buckets[buffer[j]]++;
+
+ watchdog_reload();
+ }
+
+ ccprintf("Total count: %d\n", loopcount * sizeof(buffer));
+ ccprintf("Buckets: ");
+ for (j = 0; j < 256; j++) {
+ ccprintf("%d;", buckets[j]);
+ cflush();
+ }
+ ccprintf("\n");
+ /*
+ * From the data above, entropy can be obtained with this command:
+ * tr ';' '\n' | awk 'BEGIN { e = 0; tot=16384.0 }
+ { p = $1/tot; if (p > 0) { e -= p*log(p)/log(2) } }
+ END { print e }'
+ */
+ test_pass();
+}
diff --git a/test/entropy.tasklist b/test/entropy.tasklist
new file mode 100644
index 0000000000..e76178ba0a
--- /dev/null
+++ b/test/entropy.tasklist
@@ -0,0 +1,17 @@
+/* Copyright 2017 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * List of enabled tasks in the priority order
+ *
+ * The first one has the lowest priority.
+ *
+ * For each task, use the macro TASK_TEST(n, r, d, s) where :
+ * 'n' in the name of the task
+ * 'r' in the main routine of the task
+ * 'd' in an opaque parameter passed to the routine at startup
+ * 's' is the stack size in bytes; must be a multiple of 8
+ */
+#define CONFIG_TEST_TASK_LIST