/** ****************************************************************************** * File Name : main.c * Date : 08/07/2015 17:46:00 * Description : Main program body ****************************************************************************** * * COPYRIGHT(c) 2015 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. 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. * 3. Neither the name of STMicroelectronics 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. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f4xx_hal.h" #include "stm-init.h" #ifdef HAL_GPIO_MODULE_ENABLED #include "stm-led.h" #endif #ifdef HAL_UART_MODULE_ENABLED #include "stm-uart.h" #endif #ifdef HAL_I2C_MODULE_ENABLED #include "stm-rtc.h" #endif #ifdef HAL_SPI_MODULE_ENABLED #include "stm-fpgacfg.h" #include "stm-keystore.h" #endif /* Private variables ---------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ #ifdef HAL_GPIO_MODULE_ENABLED static void MX_GPIO_Init(void); #endif #ifdef HAL_UART_MODULE_ENABLED static void MX_USART1_UART_Init(void); static void MX_USART2_UART_Init(void); #endif #ifdef HAL_DMA_MODULE_ENABLED static void MX_DMA_Init(void); #endif #ifdef HAL_I2C_MODULE_ENABLED static void MX_I2C2_Init(void); #endif #ifdef HAL_SPI_MODULE_ENABLED static void MX_SPI1_Init(void); static void MX_SPI2_Init(void); #endif void stm_init(void) { /* MCU Configuration----------------------------------------------------------*/ /* System interrupt init*/ /* Sets the priority grouping field */ HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0); HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); /* Initialize all configured peripherals */ #ifdef HAL_GPIO_MODULE_ENABLED MX_GPIO_Init(); #ifdef HAL_SPI_MODULE_ENABLED /* Give the FPGA access to it's bitstream ASAP (maybe this should actually * be done in the application, before calling stm_init()). */ fpgacfg_access_control(ALLOW_FPGA); #endif #endif #ifdef HAL_DMA_MODULE_ENABLED MX_DMA_Init(); #endif #ifdef HAL_UART_MODULE_ENABLED MX_USART1_UART_Init(); MX_USART2_UART_Init(); #endif #ifdef HAL_I2C_MODULE_ENABLED MX_I2C2_Init(); #endif #ifdef HAL_SPI_MODULE_ENABLED MX_SPI1_Init(); MX_SPI2_Init(); #endif } #ifdef HAL_UART_MODULE_ENABLED /* USART1 init function */ static void MX_USART1_UART_Init(void) { huart_mgmt.Instance = USART1; huart_mgmt.Init.BaudRate = USART_MGMT_BAUD_RATE; huart_mgmt.Init.WordLength = UART_WORDLENGTH_8B; huart_mgmt.Init.StopBits = UART_STOPBITS_1; huart_mgmt.Init.Parity = UART_PARITY_NONE; huart_mgmt.Init.Mode = UART_MODE_TX_RX; huart_mgmt.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS; huart_mgmt.Init.OverSampling = UART_OVERSAMPLING_16; #ifdef HAL_DMA_MODULE_ENABLED __HAL_LINKDMA(&huart_mgmt, hdmarx, hdma_usart_mgmt_rx); #endif if (HAL_UART_Init(&huart_mgmt) != HAL_OK) { /* Initialization Error */ Error_Handler(); } } /* USART2 init function */ static void MX_USART2_UART_Init(void) { huart_user.Instance = USART2; huart_user.Init.BaudRate = USART_USER_BAUD_RATE; huart_user.Init.WordLength = UART_WORDLENGTH_8B; huart_user.Init.StopBits = UART_STOPBITS_1; huart_user.Init.Parity = UART_PARITY_NONE; huart_user.Init.Mode = UART_MODE_TX_RX; huart_user.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS; huart_user.Init.OverSampling = UART_OVERSAMPLING_16; #ifdef HAL_DMA_MODULE_ENABLED __HAL_LINKDMA(&huart_user, hdmarx, hdma_usart_user_rx); #endif if (HAL_UART_Init(&huart_user) != HAL_OK) { /* Initialization Error */ Error_Handler(); } } #endif #ifdef HAL_GPIO_MODULE_ENABLED /* Configure General Purpose Input/Output pins */ static void MX_GPIO_Init(void) { /* GPIO Ports Clock Enable */ LED_CLK_ENABLE(); /* Configure LED GPIO pins */ gpio_output(LED_PORT, LED_RED | LED_YELLOW | LED_GREEN | LED_BLUE, GPIO_PIN_RESET); #ifdef HAL_SPI_MODULE_ENABLED /* Set up GPIOs to manage access to the FPGA config memory. * FPGACFG_GPIO_INIT is defined in stm-fpgacfg.h. */ FPGACFG_GPIO_INIT(); /* Set up GPIOs for the keystore memory. * KEYSTORE_GPIO_INIT is defined in stm-keystore.h. */ KEYSTORE_GPIO_INIT(); #endif /* HAL_SPI_MODULE_ENABLED */ } #undef gpio_output #endif #ifdef HAL_DMA_MODULE_ENABLED /** * Enable DMA controller clock */ static void MX_DMA_Init(void) { /* DMA controller clock enable */ __HAL_RCC_DMA2_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE(); /* DMA interrupt init */ /* USER UART RX */ HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); /* MGMT UART RX */ HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0); HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn); } #endif /* HAL_DMA_MODULE_ENABLED */ #ifdef HAL_I2C_MODULE_ENABLED /* I2C2 init function (external RTC chip) */ void MX_I2C2_Init(void) { hi2c_rtc.Instance = I2C2; hi2c_rtc.Init.ClockSpeed = 10000; hi2c_rtc.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c_rtc.Init.OwnAddress1 = 0; /* Will operate as Master */ hi2c_rtc.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c_rtc.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED; hi2c_rtc.Init.OwnAddress2 = 0; hi2c_rtc.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED; hi2c_rtc.Init.NoStretchMode = I2C_NOSTRETCH_DISABLED; if (HAL_I2C_Init(&hi2c_rtc) != HAL_OK) { Error_Handler(); } } #endif #ifdef HAL_SPI_MODULE_ENABLED /* SPI1 (keystore memory) init function */ void MX_SPI1_Init(void) { hspi_keystore.Instance = SPI1; hspi_keystore.Init.Mode = SPI_MODE_MASTER; hspi_keystore.Init.Direction = SPI_DIRECTION_2LINES; hspi_keystore.Init.DataSize = SPI_DATASIZE_8BIT; hspi_keystore.Init.CLKPolarity = SPI_POLARITY_LOW; hspi_keystore.Init.CLKPhase = SPI_PHASE_1EDGE; hspi_keystore.Init.NSS = SPI_NSS_SOFT; hspi_keystore.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; hspi_keystore.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi_keystore.Init.TIMode = SPI_TIMODE_DISABLE; hspi_keystore.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi_keystore.Init.CRCPolynomial = 10; HAL_SPI_Init(&hspi_keystore); } /* SPI2 (FPGA config memory) init function */ void MX_SPI2_Init(void) { hspi_fpgacfg.Instance = SPI2; hspi_fpgacfg.Init.Mode = SPI_MODE_MASTER; hspi_fpgacfg.Init.Direction = SPI_DIRECTION_2LINES; hspi_fpgacfg.Init.DataSize = SPI_DATASIZE_8BIT; hspi_fpgacfg.Init.CLKPolarity = SPI_POLARITY_LOW; hspi_fpgacfg.Init.CLKPhase = SPI_PHASE_1EDGE; hspi_fpgacfg.Init.NSS = SPI_NSS_SOFT; hspi_fpgacfg.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; hspi_fpgacfg.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi_fpgacfg.Init.TIMode = SPI_TIMODE_DISABLE; hspi_fpgacfg.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi_fpgacfg.Init.CRCPolynomial = 10; HAL_SPI_Init(&hspi_fpgacfg); } #endif /* HAL_SPI_MODULE_ENABLED */ /** * @brief This function is executed in case of error occurrence. * @param None * @retval None */ void Error_Handler(void) { #ifdef HAL_GPIO_MODULE_ENABLED HAL_GPIO_WritePin(LED_PORT, LED_RED, GPIO_PIN_SET); #endif while (1) { ; } } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 0f707cd0bd10fc96bc50fb81ba0248915b5e2'>76a0f70
f66d4bc
















ab32270
f66d4bc







76a0f70
f66d4bc


4b5afd6
76a0f70
f66d4bc
4b5afd6
76a0f70
f66d4bc
f66d4bc


ab32270
4b5afd6
f66d4bc

76a0f70
f66d4bc

ab32270








f66d4bc

ab32270









f66d4bc
ab32270

f66d4bc
ab32270
f66d4bc



ab32270

4b5afd6
ab32270

f66d4bc

76a0f70

4b5afd6
f66d4bc

76a0f70
f66d4bc





4b5afd6
f66d4bc



76a0f70

4b5afd6
f66d4bc

76a0f70
f66d4bc





e3fe7d8

f66d4bc
e3fe7d8
f66d4bc

e3fe7d8

f66d4bc
e3fe7d8


f66d4bc
f66d4bc
e3fe7d8

f66d4bc
e3fe7d8
f66d4bc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187

































                                                                           
                                                                
                           



                           
 


                        

                                                                  
             


                   
                                                   

                     
                   
                              
                                     
















                                                                              
                                                







                                                                                                 
                       


                                              
                                            
                                                                                         
 
                                         
                                                                                         
 


                  
                                                                      
                                                                                                  

                                  
                    

          








                                                                                  

     









                                                                                                             
 

                                                             
            
                                                                                            



                  

                                                                                              
                                                                               

 

                                                                                                

                    
                                                                  

                                                                 
                                                                                                    





                                                                                                       
                                                                         



                                                                                                         

                    
                                                               

                                                                
                                                                                                   





                                                 

                                                                                           
                          
                                                                                                                 

                       

                                                                                                                         
                         


                                                                                                                                 
 
                                

                                                                                                                                                    
                                  
                                                                                                                                         
 
/*
 * 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.
 */

/* Rename both CMSIS HAL_OK and libhal HAL_OK to disambiguate */
#define HAL_OK CMSIS_HAL_OK
#include "stm-init.h"
#include "stm-uart.h"
#include "mgmt-cli.h"
#include "mgmt-masterkey.h"

#undef HAL_OK
#define LIBHAL_OK HAL_OK
#include <hal.h>
#warning Refactor so we do not need to include hal_internal.h here
#include <hal_internal.h>
#undef HAL_OK

#include <stdlib.h>

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++ = strtoul(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;

    cli_print(cli, "Status of master key:\n");

    status = hal_mkm_volatile_read(NULL, 0);
    cli_print(cli, "  volatile: %s / %s", _status2str(status), hal_error_string(status));

    status = hal_mkm_flash_read(NULL, 0);
    cli_print(cli, "     flash: %s / %s", _status2str(status), hal_error_string(status));

    return CLI_OK;
}

static int _masterkey_set(struct cli_def *cli, char *argv[], int argc,
                          char *label, hal_error_t (*writer)(const uint8_t * const, const size_t))
{
    uint8_t buf[KEK_LENGTH] = {0};
    hal_error_t err;
    int i;

    if (argc == 0) {
        /* fill master key with yummy randomness */
        if ((err = hal_get_random(NULL, buf, sizeof(buf))) != LIBHAL_OK) {
            cli_print(cli, "Error getting random key: %s", hal_error_string(err));
            return CLI_ERROR;
        }
        cli_print(cli, "Random key:\n");
        uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1);
        cli_print(cli, "\n");
    }

    else {
        if ((i = _parse_hex_groups(&buf[0], sizeof(buf), argv, argc)) != 1) {
            cli_print(cli, "Failed parsing master key, expected up to 8 groups of 32-bit hex chars (%i)", i);
            return CLI_ERROR;
        }

        cli_print(cli, "Parsed key:\n");
        uart_send_hexdump(STM_UART_MGMT, buf, 0, sizeof(buf) - 1);
        cli_print(cli, "\n");
    }

    if ((err = writer(buf, sizeof(buf))) == LIBHAL_OK) {
	cli_print(cli, "Master key set in %s memory", label);
    } else {
	cli_print(cli, "Failed writing key to %s memory: %s", label, hal_error_string(err));
    }
    return CLI_OK;
}

static int cmd_masterkey_set(struct cli_def *cli, const char *command, char *argv[], int argc)
{
    return _masterkey_set(cli, argv, argc, "volatile", hal_mkm_volatile_write);
}

static int cmd_masterkey_erase(struct cli_def *cli, const char *command, char *argv[], int argc)
{
    hal_error_t err;

    if ((err = hal_mkm_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)
{
    return _masterkey_set(cli, argv, argc, "flash", hal_mkm_flash_write);
}

static int cmd_masterkey_unsecure_erase(struct cli_def *cli, const char *command, char *argv[], int argc)
{
    hal_error_t err;

    if ((err = hal_mkm_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)
{
    struct cli_command *c = cli_register_command(cli, NULL, "masterkey", NULL, 0, 0, NULL);

    /* masterkey status */
    cli_register_command(cli, c, "status", cmd_masterkey_status, 0, 0, "Show status of master key in RAM/flash");

    /* masterkey set */
    cli_register_command(cli, c, "set", cmd_masterkey_set, 0, 0, "Set the master key in the volatile Master Key Memory");

    /* masterkey erase */
    cli_register_command(cli, c, "erase", cmd_masterkey_erase, 0, 0, "Erase the master key from the volatile Master Key Memory");

    struct cli_command *c_unsecure = cli_register_command(cli, c, "unsecure", NULL, 0, 0, NULL);

    /* masterkey unsecure set */
    cli_register_command(cli, c_unsecure, "set", cmd_masterkey_unsecure_set, 0, 0, "Set master key in unprotected flash memory (if unsure, DON'T)");

    /* masterkey unsecure erase */
    cli_register_command(cli, c_unsecure, "erase", cmd_masterkey_unsecure_erase, 0, 0, "Erase master key from unprotected flash memory");
}