From 3ea10bf4fba185a8bfbb33a8c67a69f70b95755a Mon Sep 17 00:00:00 2001 From: Fredrik Thulin Date: Fri, 8 Jul 2016 18:10:42 +0200 Subject: merge test code from projects/hsm/ --- projects/cli-test/mgmt-cli.c | 8 +- projects/cli-test/mgmt-cli.h | 9 +- projects/cli-test/mgmt-dfu.c | 13 ++- projects/cli-test/mgmt-dfu.h | 11 -- projects/cli-test/mgmt-fpga.c | 13 +-- projects/cli-test/mgmt-keystore.c | 151 ++++++++++++++++++++------- projects/cli-test/mgmt-masterkey.c | 209 +++++++++++++++++++++++++++++++++++++ projects/cli-test/mgmt-masterkey.h | 43 ++++++++ projects/cli-test/mgmt-misc.c | 13 +-- projects/cli-test/mgmt-show.c | 55 +++++++++- 10 files changed, 446 insertions(+), 79 deletions(-) create mode 100644 projects/cli-test/mgmt-masterkey.c create mode 100644 projects/cli-test/mgmt-masterkey.h (limited to 'projects/cli-test') diff --git a/projects/cli-test/mgmt-cli.c b/projects/cli-test/mgmt-cli.c index 9488398..a8461d3 100644 --- a/projects/cli-test/mgmt-cli.c +++ b/projects/cli-test/mgmt-cli.c @@ -60,7 +60,7 @@ void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *bu uart_send_string2(STM_UART_MGMT, crlf); } -int uart_cli_read(struct cli_def *cli __attribute__ ((unused)), void *buf, size_t count) +static int uart_cli_read(struct cli_def *cli __attribute__ ((unused)), void *buf, size_t count) { uint32_t timeout = 0xffffff; while (count && timeout) { @@ -76,13 +76,13 @@ int uart_cli_read(struct cli_def *cli __attribute__ ((unused)), void *buf, size_ return 1; } -int uart_cli_write(struct cli_def *cli __attribute__ ((unused)), const void *buf, size_t count) +static int uart_cli_write(struct cli_def *cli __attribute__ ((unused)), const void *buf, size_t count) { uart_send_bytes(STM_UART_MGMT, (uint8_t *) buf, count); return (int) count; } -int control_mgmt_uart_dma_rx(enum mgmt_cli_dma_state state) +int control_mgmt_uart_dma_rx(mgmt_cli_dma_state_t state) { if (state == DMA_RX_START) { if (uart_ringbuf.rx_state != DMA_RX_START) { @@ -102,7 +102,7 @@ int control_mgmt_uart_dma_rx(enum mgmt_cli_dma_state state) return 0; } -int embedded_cli_loop(struct cli_def *cli) +static int embedded_cli_loop(struct cli_def *cli) { unsigned char c; int n = 0; diff --git a/projects/cli-test/mgmt-cli.h b/projects/cli-test/mgmt-cli.h index 16c9fbd98..08dc731 100644 --- a/projects/cli-test/mgmt-cli.h +++ b/projects/cli-test/mgmt-cli.h @@ -68,19 +68,16 @@ cli_register_command2(cli, &cmd_##name##_s, NULL) -#define CLI_UART_RECVBUF_SIZE 256 /* This must be a power of 2 */ -#define CLI_UART_RECVBUF_MASK (CLI_UART_RECVBUF_SIZE - 1) - -enum mgmt_cli_dma_state { +typedef enum { DMA_RX_STOP, DMA_RX_START, -}; +} mgmt_cli_dma_state_t; extern void uart_cli_print(struct cli_def *cli __attribute__ ((unused)), const char *buf); extern int uart_cli_read(struct cli_def *cli __attribute__ ((unused)), void *buf, size_t count); extern int uart_cli_write(struct cli_def *cli __attribute__ ((unused)), const void *buf, size_t count); extern int embedded_cli_loop(struct cli_def *cli); extern void mgmt_cli_init(struct cli_def *cli); -extern int control_mgmt_uart_dma_rx(enum mgmt_cli_dma_state state); +extern int control_mgmt_uart_dma_rx(mgmt_cli_dma_state_t state); #endif /* __STM32_MGMT_CLI_H */ diff --git a/projects/cli-test/mgmt-dfu.c b/projects/cli-test/mgmt-dfu.c index 27fd722..e57c521 100644 --- a/projects/cli-test/mgmt-dfu.c +++ b/projects/cli-test/mgmt-dfu.c @@ -40,6 +40,11 @@ #include +#define DFU_FIRMWARE_ADDR ((uint32_t) &CRYPTECH_FIRMWARE_START) +#define DFU_FIRMWARE_END_ADDR ((uint32_t) &CRYPTECH_FIRMWARE_END) +#define DFU_UPLOAD_CHUNK_SIZE 256 +#define HARDWARE_EARLY_DFU_JUMP 0xBADABADA + extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); /* Linker symbols are strange in C. Make regular pointers for sanity. */ @@ -53,9 +58,7 @@ __IO uint32_t *dfu_msp_ptr = &CRYPTECH_FIRMWARE_START; */ __IO uint32_t *dfu_code_ptr = &CRYPTECH_FIRMWARE_START + 1; - - -int cmd_dfu_dump(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_dfu_dump(struct cli_def *cli, const char *command, char *argv[], int argc) { cli_print(cli, "First 256 bytes from DFU application address %p:\r\n", dfu_firmware); @@ -65,7 +68,7 @@ int cmd_dfu_dump(struct cli_def *cli, const char *command, char *argv[], int arg return CLI_OK; } -int cmd_dfu_erase(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_dfu_erase(struct cli_def *cli, const char *command, char *argv[], int argc) { int status; @@ -82,7 +85,7 @@ int cmd_dfu_erase(struct cli_def *cli, const char *command, char *argv[], int ar return CLI_OK; } -int cmd_dfu_jump(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_dfu_jump(struct cli_def *cli, const char *command, char *argv[], int argc) { uint32_t i; /* Load first byte from the DFU_FIRMWARE_PTR to verify it contains an IVT before diff --git a/projects/cli-test/mgmt-dfu.h b/projects/cli-test/mgmt-dfu.h index ac6589c..047e30a 100644 --- a/projects/cli-test/mgmt-dfu.h +++ b/projects/cli-test/mgmt-dfu.h @@ -43,17 +43,6 @@ extern uint32_t CRYPTECH_FIRMWARE_START; extern uint32_t CRYPTECH_FIRMWARE_END; extern uint32_t CRYPTECH_DFU_CONTROL; -#define DFU_FIRMWARE_ADDR ((uint32_t) &CRYPTECH_FIRMWARE_START) -#define DFU_FIRMWARE_END_ADDR ((uint32_t) &CRYPTECH_FIRMWARE_END) -#define DFU_UPLOAD_CHUNK_SIZE 256 -#define HARDWARE_EARLY_DFU_JUMP 0xBADABADA - -extern __IO uint32_t *dfu_control; -extern __IO uint32_t *dfu_firmware; -extern __IO uint32_t *dfu_msp_ptr; -extern __IO uint32_t *dfu_code_ptr; - - extern void configure_cli_dfu(struct cli_def *cli); #endif /* __STM32_CLI_MGMT_DFU_H */ diff --git a/projects/cli-test/mgmt-fpga.c b/projects/cli-test/mgmt-fpga.c index 8c1b2a8..059e4a9 100644 --- a/projects/cli-test/mgmt-fpga.c +++ b/projects/cli-test/mgmt-fpga.c @@ -43,16 +43,17 @@ #include -volatile uint32_t dfu_offset = 0; +static volatile uint32_t dfu_offset = 0; -int _flash_write_callback(uint8_t *buf, size_t len) { + +static int _flash_write_callback(uint8_t *buf, size_t len) { int res = fpgacfg_write_data(dfu_offset, buf, BITSTREAM_UPLOAD_CHUNK_SIZE) == 1; dfu_offset += BITSTREAM_UPLOAD_CHUNK_SIZE; return res; } -int cmd_fpga_bitstream_upload(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_fpga_bitstream_upload(struct cli_def *cli, const char *command, char *argv[], int argc) { uint8_t buf[BITSTREAM_UPLOAD_CHUNK_SIZE]; @@ -74,7 +75,7 @@ int cmd_fpga_bitstream_upload(struct cli_def *cli, const char *command, char *ar return CLI_OK; } -int cmd_fpga_bitstream_erase(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_fpga_bitstream_erase(struct cli_def *cli, const char *command, char *argv[], int argc) { fpgacfg_access_control(ALLOW_ARM); @@ -101,7 +102,7 @@ int cmd_fpga_bitstream_erase(struct cli_def *cli, const char *command, char *arg return CLI_OK; } -int cmd_fpga_reset(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_fpga_reset(struct cli_def *cli, const char *command, char *argv[], int argc) { fpgacfg_access_control(ALLOW_FPGA); fpgacfg_reset_fpga(RESET_FULL); @@ -110,7 +111,7 @@ int cmd_fpga_reset(struct cli_def *cli, const char *command, char *argv[], int a return CLI_OK; } -int cmd_fpga_reset_registers(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_fpga_reset_registers(struct cli_def *cli, const char *command, char *argv[], int argc) { fpgacfg_access_control(ALLOW_FPGA); fpgacfg_reset_fpga(RESET_REGISTERS); diff --git a/projects/cli-test/mgmt-keystore.c b/projects/cli-test/mgmt-keystore.c index 14d8e1b..128ae4c 100644 --- a/projects/cli-test/mgmt-keystore.c +++ b/projects/cli-test/mgmt-keystore.c @@ -57,8 +57,8 @@ int cmd_keystore_set_pin(struct cli_def *cli, const char *command, char *argv[], { const hal_ks_keydb_t *db; hal_user_t user; - hal_ks_pin_t pin; hal_error_t status; + hal_client_handle_t client = { -1 }; db = hal_ks_get_keydb(); @@ -67,28 +67,82 @@ int cmd_keystore_set_pin(struct cli_def *cli, const char *command, char *argv[], return CLI_OK; } - if (argc != 3) { + if (argc != 2) { cli_print(cli, "Wrong number of arguments (%i).", argc); - cli_print(cli, "Syntax: keystore set pin "); + cli_print(cli, "Syntax: keystore set pin "); return CLI_ERROR; } user = HAL_USER_NONE; - if (strcmp(argv[0], "user") == 0) user = HAL_USER_NORMAL; - if (strcmp(argv[0], "so") == 0) user = HAL_USER_SO; + if (strcmp(argv[0], "user") == 0) user = HAL_USER_NORMAL; + if (strcmp(argv[0], "so") == 0) user = HAL_USER_SO; if (strcmp(argv[0], "wheel") == 0) user = HAL_USER_WHEEL; if (user == HAL_USER_NONE) { cli_print(cli, "First argument must be 'user', 'so' or 'wheel' - not '%s'", argv[0]); return CLI_ERROR; } - pin.iterations = strtol(argv[1], NULL, 0); + status = hal_rpc_set_pin(client, user, argv[1], strlen(argv[1])); + if (status != LIBHAL_OK) { + cli_print(cli, "Failed setting PIN: %s", hal_error_string(status)); + return CLI_ERROR; + } + + return CLI_OK; +} + +int cmd_keystore_clear_pin(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + const hal_ks_keydb_t *db; + hal_user_t user; + hal_ks_pin_t pin; + hal_error_t status; + + db = hal_ks_get_keydb(); + + if (db == NULL) { + cli_print(cli, "Could not get a keydb from libhal"); + return CLI_OK; + } + + if (argc != 1) { + cli_print(cli, "Wrong number of arguments (%i).", argc); + cli_print(cli, "Syntax: keystore clear pin "); + return CLI_ERROR; + } - /* We don't actually PBKDF2 the given PIN yet, just testing */ - strncpy((char *) pin.pin, argv[2], sizeof(pin.pin)); + user = HAL_USER_NONE; + if (strcmp(argv[0], "user") == 0) user = HAL_USER_NORMAL; + if (strcmp(argv[0], "so") == 0) user = HAL_USER_SO; + if (strcmp(argv[0], "wheel") == 0) user = HAL_USER_WHEEL; + if (user == HAL_USER_NONE) { + cli_print(cli, "First argument must be 'user', 'so' or 'wheel' - not '%s'", argv[0]); + return CLI_ERROR; + } + memset(&pin, 0x0, sizeof(pin)); if ((status = hal_ks_set_pin(user, &pin)) != LIBHAL_OK) { - cli_print(cli, "Failed setting PIN: %s", hal_error_string(status)); + cli_print(cli, "Failed clearing PIN: %s", hal_error_string(status)); + return CLI_ERROR; + } + + return CLI_OK; +} + +int cmd_keystore_set_pin_iterations(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + hal_error_t status; + hal_client_handle_t client = { -1 }; + + if (argc != 1) { + cli_print(cli, "Wrong number of arguments (%i).", argc); + cli_print(cli, "Syntax: keystore set pin iterations "); + return CLI_ERROR; + } + + status = hal_set_pin_default_iterations(client, strtol(argv[0], NULL, 0)); + if (status != LIBHAL_OK) { + cli_print(cli, "Failed setting iterations: %s", hal_error_string(status)); return CLI_ERROR; } @@ -190,35 +244,6 @@ int cmd_keystore_show_data(struct cli_def *cli, const char *command, char *argv[ uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1); uart_send_string2(STM_UART_MGMT, (char *) "\r\n\r\n"); - for (i = 0; i < 8; i++) { - if (buf[i] == 0xff) break; /* never written */ - if (buf[i] != 0x55) break; /* something other than a tombstone */ - } - /* As a demo, tombstone byte after byte of the first 8 bytes in the keystore memory - * (as long as they do not appear to contain real data). - * If all of them are tombstones, erase the first sector to start over. - */ - - /* - if (i < 8) { - if (buf[i] == 0xff) { - cli_print(cli, "Tombstoning byte %li", i); - buf[i] = 0x55; - if ((i = keystore_write_data(0, buf, sizeof(buf))) != 1) { - cli_print(cli, "Failed writing data at offset 0: %li", i); - return CLI_ERROR; - } - } - } else { - cli_print(cli, "Erasing first sector since all the first 8 bytes are tombstones"); - if ((i = keystore_erase_sectors(1, 1)) != 1) { - cli_print(cli, "Failed erasing the first sector: %li", i); - return CLI_ERROR; - } - cli_print(cli, "Erase result: %li", i); - } - */ - return CLI_OK; } @@ -246,19 +271,60 @@ int cmd_keystore_show_keys(struct cli_def *cli, const char *command, char *argv[ cli_print(cli, "\nPins:"); cli_print(cli, "Wheel iterations: 0x%lx", db->wheel_pin.iterations); + cli_print(cli, "pin"); + uart_send_hexdump(STM_UART_MGMT, db->wheel_pin.pin, 0, sizeof(db->wheel_pin.pin) - 1); + cli_print(cli, "\nsalt"); + uart_send_hexdump(STM_UART_MGMT, db->wheel_pin.salt, 0, sizeof(db->wheel_pin.salt) - 1); + cli_print(cli, ""); + cli_print(cli, "SO iterations: 0x%lx", db->so_pin.iterations); + cli_print(cli, "pin"); + uart_send_hexdump(STM_UART_MGMT, db->so_pin.pin, 0, sizeof(db->so_pin.pin) - 1); + cli_print(cli, "\nsalt"); + uart_send_hexdump(STM_UART_MGMT, db->so_pin.salt, 0, sizeof(db->so_pin.salt) - 1); + cli_print(cli, ""); + cli_print(cli, "User iterations: 0x%lx", db->user_pin.iterations); + cli_print(cli, "pin"); + uart_send_hexdump(STM_UART_MGMT, db->user_pin.pin, 0, sizeof(db->user_pin.pin) - 1); + cli_print(cli, "\nsalt"); + uart_send_hexdump(STM_UART_MGMT, db->user_pin.salt, 0, sizeof(db->user_pin.salt) - 1); + cli_print(cli, ""); cli_print(cli, "\n"); return CLI_OK; } +int cmd_keystore_erase(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + int status; + + if (argc != 1) { + cli_print(cli, "Syntax: keystore erase YesIAmSure"); + return CLI_ERROR; + } + + if (strcmp(argv[0], "YesIAmSure") == 0) { + if ((status = keystore_erase_sectors(0, 1)) != 1) { + cli_print(cli, "Failed erasing keystore: %i", status); + } else { + cli_print(cli, "Keystore erased (first two sectors at least)"); + } + } else { + cli_print(cli, "Keystore NOT erased"); + } + + return CLI_OK; +} + void configure_cli_keystore(struct cli_def *cli) { /* keystore */ cli_command_root(keystore); /* keystore set */ cli_command_branch(keystore, set); + /* keystore clear */ + cli_command_branch(keystore, clear); /* keystore delete */ cli_command_branch(keystore, delete); /* keystore rename */ @@ -266,9 +332,18 @@ void configure_cli_keystore(struct cli_def *cli) /* keystore show */ cli_command_branch(keystore, show); + /* keystore erase */ + cli_command_node(keystore, erase, "Erase the whole keystore"); + /* keystore set pin */ cli_command_node(keystore_set, pin, "Set either 'wheel', 'user' or 'so' PIN"); + /* keystore set pin iterations */ + cli_command_node(keystore_set_pin, iterations, "Set PBKDF2 iterations for PINs"); + + /* keystore clear pin */ + cli_command_node(keystore_clear, pin, "Clear either 'wheel', 'user' or 'so' PIN"); + /* keystore set key */ cli_command_node(keystore_set, key, "Set a key"); diff --git a/projects/cli-test/mgmt-masterkey.c b/projects/cli-test/mgmt-masterkey.c new file mode 100644 index 0000000..7938e33 --- /dev/null +++ b/projects/cli-test/mgmt-masterkey.c @@ -0,0 +1,209 @@ +/* + * mgmt-masterkey.c + * ---------------- + * Masterkey CLI functions. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define HAL_OK CMSIS_HAL_OK + +#include "stm-init.h" +#include "stm-uart.h" +#include "mgmt-cli.h" +#include "mgmt-masterkey.h" + +/* Rename both CMSIS HAL_OK and libhal HAL_OK to disambiguate */ +#undef HAL_OK +#define LIBHAL_OK HAL_OK +#include +#include +#undef HAL_OK + +#include + +#define KEK_LENGTH (256 / 8) + + +static char * _status2str(const hal_error_t status) +{ + switch (status) { + case LIBHAL_OK: + return (char *) "Set"; + case HAL_ERROR_MASTERKEY_NOT_SET: + return (char *) "Not set"; + default: + return (char *) "Unknown"; + } +} + +static int _parse_hex_groups(uint8_t *buf, size_t len, char *argv[], int argc) +{ + int i; + uint32_t *dst = (uint32_t *) buf; + uint32_t *end = (uint32_t *) buf + len - 1; + char *err_ptr = NULL; + + if (! argc) return 0; + + for (i = 0; i < argc; i++) { + if (dst >= end) return -1; + *dst++ = strtol(argv[i], &err_ptr, 16); + if (*err_ptr) return -2; + } + + return 1; +} + +static int cmd_masterkey_status(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + hal_error_t status; + uint8_t buf[KEK_LENGTH] = {0}; + + cli_print(cli, "Status of master key:\n"); + + status = masterkey_volatile_read(NULL, 0); + cli_print(cli, " volatile: %s / %s", _status2str(status), hal_error_string(status)); + + status = masterkey_flash_read(NULL, 0); + cli_print(cli, " flash: %s / %s", _status2str(status), hal_error_string(status)); + + /* XXX Temporary gaping security hole while developing the master key functionality. + * REMOVE READ-OUT OF MASTER KEY. + */ + + status = masterkey_volatile_read(&buf[0], sizeof(buf)); + if (status == LIBHAL_OK || status == HAL_ERROR_MASTERKEY_NOT_SET) { + cli_print(cli, "\nVolatile read-out:\n"); + uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1); + cli_print(cli, "\n"); + } else { + cli_print(cli, "Failed reading from volatile memory: %s", hal_error_string(status)); + } + + status = masterkey_flash_read(&buf[0], sizeof(buf)); + if (status == LIBHAL_OK || status == HAL_ERROR_MASTERKEY_NOT_SET) { + cli_print(cli, "\nFlash read-out:\n"); + uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1); + cli_print(cli, "\n"); + } else { + cli_print(cli, "Failed reading from flash: %s", hal_error_string(status)); + } + + return CLI_OK; +} + +static int cmd_masterkey_set(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + uint8_t buf[KEK_LENGTH] = {0}; + hal_error_t err; + int i; + + if ((i = _parse_hex_groups(&buf[0], sizeof(buf), argv, argc)) != 1) { + cli_print(cli, "Failed parsing master key (%i)", i); + return CLI_OK; + } + + cli_print(cli, "Parsed key:\n"); + uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1); + cli_print(cli, "\n"); + + if ((err = masterkey_volatile_write(buf, sizeof(buf))) == LIBHAL_OK) { + cli_print(cli, "Master key set in volatile memory"); + } else { + cli_print(cli, "Failed writing key to volatile memory: %s", hal_error_string(err)); + } + return CLI_OK; +} + +static int cmd_masterkey_erase(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + hal_error_t err; + + if ((err = masterkey_volatile_erase(KEK_LENGTH)) == LIBHAL_OK) { + cli_print(cli, "Erased master key from volatile memory"); + } else { + cli_print(cli, "Failed erasing master key from volatile memory: %s", hal_error_string(err)); + } + return CLI_OK; +} + +static int cmd_masterkey_unsecure_set(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + uint8_t buf[KEK_LENGTH] = {0}; + hal_error_t err; + int i; + + if ((i = _parse_hex_groups(&buf[0], sizeof(buf), argv, argc)) != 1) { + cli_print(cli, "Failed parsing master key (%i)", i); + return CLI_OK; + } + + cli_print(cli, "Parsed key:\n"); + uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1); + cli_print(cli, "\n"); + + if ((err = masterkey_flash_write(buf, sizeof(buf))) == LIBHAL_OK) { + cli_print(cli, "Master key set in unsecure flash memory"); + } else { + cli_print(cli, "Failed writing key to unsecure flash memory: %s", hal_error_string(err)); + } + return CLI_OK; +} + +static int cmd_masterkey_unsecure_erase(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + hal_error_t err; + + if ((err = masterkey_flash_erase(KEK_LENGTH)) == LIBHAL_OK) { + cli_print(cli, "Erased unsecure master key from flash"); + } else { + cli_print(cli, "Failed erasing unsecure master key from flash: %s", hal_error_string(err)); + } + return CLI_OK; +} + +void configure_cli_masterkey(struct cli_def *cli) +{ + /* masterkey */ + cli_command_root(masterkey); + /* masterkey status */ + cli_command_node(masterkey, status, "Show status of master key in RAM/flash"); + + /* masterkey set */ + cli_command_node(masterkey, set, "Set the master key in the volatile Master Key Memory"); + /* masterkey erase */ + cli_command_node(masterkey, erase, "Erase the master key from the volatile Master Key Memory"); + + cli_command_branch(masterkey, unsecure); + /* masterkey unsecure set */ + cli_command_node(masterkey_unsecure, set, "Set master key in unprotected flash memory (if unsure, DON'T)"); + /* masterkey unsecure erase */ + cli_command_node(masterkey_unsecure, erase, "Erase master key from unprotected flash memory"); +} diff --git a/projects/cli-test/mgmt-masterkey.h b/projects/cli-test/mgmt-masterkey.h new file mode 100644 index 0000000..5d2624a --- /dev/null +++ b/projects/cli-test/mgmt-masterkey.h @@ -0,0 +1,43 @@ +/* + * mgmt-masterkey.h + * ----------- + * Management CLI masterkeyellaneous functions. + * + * Copyright (c) 2016, NORDUnet A/S All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of the NORDUnet nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __STM32_CLI_MGMT_MASTERKEY_H +#define __STM32_CLI_MGMT_MASTERKEY_H + +#include "stm-init.h" +#include + +extern void configure_cli_masterkey(struct cli_def *cli); + +#endif /* __STM32_CLI_MGMT_MASTERKEY_H */ diff --git a/projects/cli-test/mgmt-misc.c b/projects/cli-test/mgmt-misc.c index aea790a..67bc875 100644 --- a/projects/cli-test/mgmt-misc.c +++ b/projects/cli-test/mgmt-misc.c @@ -44,10 +44,9 @@ extern uint32_t update_crc(uint32_t crc, uint8_t *buf, int len); -volatile uint32_t demo_crc = 0; +static volatile uint32_t demo_crc = 0; - -int _count_bytes_callback(uint8_t *buf, size_t len) { +static int _count_bytes_callback(uint8_t *buf, size_t len) { demo_crc = update_crc(demo_crc, buf, len); return 1; } @@ -110,7 +109,7 @@ int cli_receive_data(struct cli_def *cli, uint8_t *buf, size_t len, cli_data_cal return CLI_OK; } -int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int argc) { uint8_t buf[FILETRANSFER_UPLOAD_CHUNK_SIZE]; @@ -120,11 +119,13 @@ int cmd_filetransfer(struct cli_def *cli, const char *command, char *argv[], int return CLI_OK; } -int cmd_reboot(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_reboot(struct cli_def *cli, const char *command, char *argv[], int argc) { cli_print(cli, "\n\n\nRebooting\n\n\n"); HAL_NVIC_SystemReset(); - while (1) {}; + + /*NOTREACHED*/ + return CLI_OK; } void configure_cli_misc(struct cli_def *cli) diff --git a/projects/cli-test/mgmt-show.c b/projects/cli-test/mgmt-show.c index 80a74cb..b918cce 100644 --- a/projects/cli-test/mgmt-show.c +++ b/projects/cli-test/mgmt-show.c @@ -54,7 +54,7 @@ #include -int cmd_show_cpuspeed(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_show_cpuspeed(struct cli_def *cli, const char *command, char *argv[], int argc) { volatile uint32_t hclk; @@ -65,18 +65,66 @@ int cmd_show_cpuspeed(struct cli_def *cli, const char *command, char *argv[], in return CLI_OK; } -int cmd_show_fpga_status(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_show_fpga_status(struct cli_def *cli, const char *command, char *argv[], int argc) { cli_print(cli, "FPGA has %sloaded a bitstream", fpgacfg_check_done() ? "":"NOT "); return CLI_OK; } -int cmd_show_keystore_status(struct cli_def *cli, const char *command, char *argv[], int argc) +static int cmd_show_keystore_status(struct cli_def *cli, const char *command, char *argv[], int argc) { cli_print(cli, "Keystore memory is %sonline", (keystore_check_id() != 1) ? "NOT ":""); return CLI_OK; } +static int cmd_show_keystore_data(struct cli_def *cli, const char *command, char *argv[], int argc) +{ + uint8_t buf[KEYSTORE_PAGE_SIZE]; + uint32_t i; + + if (keystore_check_id() != 1) { + cli_print(cli, "ERROR: The keystore memory is not accessible."); + } + + memset(buf, 0, sizeof(buf)); + if ((i = keystore_read_data(0, buf, sizeof(buf))) != 1) { + cli_print(cli, "Failed reading first page from keystore memory: %li", i); + return CLI_ERROR; + } + + cli_print(cli, "First page from keystore memory:\r\n"); + uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1); + uart_send_string2(STM_UART_MGMT, (char *) "\r\n\r\n"); + + for (i = 0; i < 8; i++) { + if (buf[i] == 0xff) break; /* never written */ + if (buf[i] != 0x55) break; /* something other than a tombstone */ + } + /* As a demo, tombstone byte after byte of the first 8 bytes in the keystore memory + * (as long as they do not appear to contain real data). + * If all of them are tombstones, erase the first sector to start over. + */ + if (i < 8) { + if (buf[i] == 0xff) { + cli_print(cli, "Tombstoning byte %li", i); + buf[i] = 0x55; + if ((i = keystore_write_data(0, buf, sizeof(buf))) != 1) { + cli_print(cli, "Failed writing data at offset 0: %li", i); + return CLI_ERROR; + } + } + } else { + cli_print(cli, "Erasing first sector since all the first 8 bytes are tombstones"); + if ((i = keystore_erase_sectors(1, 1)) != 1) { + cli_print(cli, "Failed erasing the first sector: %li", i); + return CLI_ERROR; + } + cli_print(cli, "Erase result: %li", i); + } + + return CLI_OK; +} + void configure_cli_show(struct cli_def *cli) { /* show */ @@ -92,4 +140,5 @@ void configure_cli_show(struct cli_def *cli) cli_command_branch(show, keystore); /* show keystore status*/ cli_command_node(show_keystore, status, "Show status of the keystore memory"); + cli_command_node(show_keystore, data, "Show the first page of the keystore memory"); } -- cgit v1.2.3