diff options
-rw-r--r-- | board/hammer/board.c | 29 | ||||
-rw-r--r-- | include/rollback.h | 13 | ||||
-rw-r--r-- | test/build.mk | 3 | ||||
-rw-r--r-- | test/entropy.c | 60 | ||||
-rw-r--r-- | test/entropy.tasklist | 17 |
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 |