From 9fa6e368879d30835880b3bb0e87c8cf13dd9874 Mon Sep 17 00:00:00 2001 From: "Pavel V. Shatov (Meister)" Date: Sun, 12 Feb 2017 22:21:57 +0300 Subject: Various clean-ups * Added sample C program for STM32 to test the core in hardware * Parametrized math modules are now instantiated with explicit operand width for clarify (previously relied on default parameter values in underlying modules) * Fixed some comments --- stm32_driver/ecdsa256_driver_sample.c | 173 ++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 stm32_driver/ecdsa256_driver_sample.c (limited to 'stm32_driver/ecdsa256_driver_sample.c') diff --git a/stm32_driver/ecdsa256_driver_sample.c b/stm32_driver/ecdsa256_driver_sample.c new file mode 100644 index 0000000..cef4af0 --- /dev/null +++ b/stm32_driver/ecdsa256_driver_sample.c @@ -0,0 +1,173 @@ + // + // simple driver to test "ecdsa384" core in hardware + // + + // + // note, that the test program needs a custom bitstream where + // the core is located at offset 0 (without the core selector) + // + + // stm32 headers +#include "stm-init.h" +#include "stm-led.h" +#include "stm-fmc.h" + + // locations of core registers +#define CORE_ADDR_NAME0 (0x00 << 2) +#define CORE_ADDR_NAME1 (0x01 << 2) +#define CORE_ADDR_VERSION (0x02 << 2) +#define CORE_ADDR_CONTROL (0x08 << 2) +#define CORE_ADDR_STATUS (0x09 << 2) + + // locations of data buffers +#define CORE_ADDR_BUF_K (0x20 << 2) +#define CORE_ADDR_BUF_X (0x28 << 2) +#define CORE_ADDR_BUF_Y (0x30 << 2) + + // bit maps +#define CORE_CONTROL_BIT_NEXT 0x00000002 +#define CORE_STATUS_BIT_READY 0x00000002 + + // curve selection +#define USE_CURVE 1 + +#include "ecdsa_model.h" + +#define BUF_NUM_WORDS (OPERAND_WIDTH / (sizeof(uint32_t) << 3)) // 8 + + // + // test vectors + // +static const uint32_t p256_d[BUF_NUM_WORDS] = ECDSA_D; +static const uint32_t p256_qx[BUF_NUM_WORDS] = ECDSA_Q_X; +static const uint32_t p256_qy[BUF_NUM_WORDS] = ECDSA_Q_Y; + +static const uint32_t p256_k[BUF_NUM_WORDS] = ECDSA_K; +static const uint32_t p256_rx[BUF_NUM_WORDS] = ECDSA_R_X; +static const uint32_t p256_ry[BUF_NUM_WORDS] = ECDSA_R_Y; + +static const uint32_t p256_i[BUF_NUM_WORDS] = ECDSA_ONE; +static const uint32_t p256_gx[BUF_NUM_WORDS] = ECDSA_G_X; +static const uint32_t p256_gy[BUF_NUM_WORDS] = ECDSA_G_Y; + +static const uint32_t p256_z[BUF_NUM_WORDS] = ECDSA_ZERO; +static const uint32_t p256_n[BUF_NUM_WORDS] = ECDSA_N; + + // + // prototypes + // +void toggle_yellow_led(void); +int test_p256_multiplier(const uint32_t *k, const uint32_t *px, const uint32_t *py); + + // + // test routine + // +int main() +{ + int ok; + + stm_init(); + fmc_init(); + + led_on(LED_GREEN); + led_off(LED_RED); + + led_off(LED_YELLOW); + led_off(LED_BLUE); + + uint32_t core_name0; + uint32_t core_name1; + + fmc_read_32(CORE_ADDR_NAME0, &core_name0); + fmc_read_32(CORE_ADDR_NAME1, &core_name1); + + // "ecds", "a256" + if ((core_name0 != 0x65636473) || (core_name1 != 0x61323536)) + { + led_off(LED_GREEN); + led_on(LED_RED); + while (1); + } + + // repeat forever + while (1) + { + ok = 1; + ok = ok && test_p256_multiplier(p256_d, p256_qx, p256_qy); + ok = ok && test_p256_multiplier(p256_k, p256_rx, p256_ry); + ok = ok && test_p256_multiplier(p256_z, p256_z, p256_z); + ok = ok && test_p256_multiplier(p256_i, p256_gx, p256_gy); + ok = ok && test_p256_multiplier(p256_n, p256_z, p256_z); + + if (!ok) + { led_off(LED_GREEN); + led_on(LED_RED); + } + + toggle_yellow_led(); + } +} + + + // + // this routine uses the hardware multiplier to obtain Q(qx,qy), which is the + // scalar multiple of the base point, qx and qy are then compared to the values + // px and py (correct result known in advance) + // +int test_p256_multiplier(const uint32_t *k, const uint32_t *px, const uint32_t *py) +{ + int i, num_cyc; + uint32_t reg_control, reg_status; + uint32_t k_word, qx_word, qy_word; + + // fill k + for (i=0; i