put manufacturer key to other page

This commit is contained in:
King Kévin 2024-04-15 07:55:33 +02:00
parent ddb100570d
commit 43b26806af
1 changed files with 75 additions and 22 deletions

View File

@ -50,12 +50,13 @@
#define BUTTON_DEBOUNCE (50U) // debounce time in ms
#define TIMEOUT_GLOBAL (24U * 60) // maximum time to hold the credentials, in minutes
#define TIMEOUT_REPEAT (6U * 60) // maximum time after last repeat to hold the credentials, in minutes
#define TIMEOUT_GLOBAL (12U * 60) // maximum time to hold the credentials, in minutes
#define TIMEOUT_REPEAT (3U * 60) // maximum time after last repeat to hold the credentials, in minutes
char manuf_key[32 + 1]; // the key set by the manufacturer to authenticate the device
static struct config_t {
uint8_t layout; // keyboard layout
char manuf_key[32 + 1]; // the key set by the manufacturer to authenticate the device
char user_key[32 + 1]; // the key set by the user to authenticate the device
bool button_swap; // the order of the buttons (which is for username or password)
uint16_t timeout_global; // time to hold the credentials, in minutes
@ -63,8 +64,8 @@ static struct config_t {
uint8_t crc; // simple XOR CRC to check config validity
} config;
// TODO move manuf key to seperate page, in write protected space
// page to store manufacturer key (can't be corrupter by save config)
#define FLASH_MANUF_ADDR ((uint32_t)0x08000000 + 0x400 * 26)
// last available page of last sector to store config
#define FLASH_CONFIG_ADDR ((uint32_t)0x08000000 + 0x400 * 27)
@ -138,6 +139,18 @@ uint32_t board_button2_read(void)
static void load_config(void)
{
memcpy(manuf_key, (uint8_t*)FLASH_MANUF_ADDR, sizeof(manuf_key));
bool manuf_ok = false;
for (uint8_t i = 0; i < sizeof(manuf_key); i++) {
if (0 == manuf_key[i]) {
manuf_ok = true;
break;
}
}
if (!manuf_ok) {
memset(manuf_key, 0, sizeof(manuf_key));
}
memcpy(&config, (uint8_t*)FLASH_CONFIG_ADDR, sizeof(config));
uint8_t crc = 0x42; // start with non-zero value to have a checksum work with empty config
for (uint16_t i = 0; i < sizeof(config); i++) {
@ -195,6 +208,33 @@ end:
HAL_FLASH_Lock();
}
static void save_manuf(void)
{
// save to flash
HAL_FLASH_Unlock();
FLASH_EraseInitTypeDef EraseInitStruct;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.PageAddress = FLASH_MANUF_ADDR;
EraseInitStruct.NbPages = 1;
uint32_t error;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &error) != HAL_OK) {
printf("earsing page failed\r\n");
goto end;
}
for (uint16_t i = 0; i < sizeof(manuf_key); i += 4) {
const uint32_t address = FLASH_CONFIG_ADDR + i;
uint32_t data;
memcpy(&data, (uint8_t*)&manuf_key[i], sizeof(data)); // works even if the data it not aligned
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data) != HAL_OK) {
printf("flash page failed\r\n");
goto end;
}
}
printf("manufacturer key saved\r\n");
end:
HAL_FLASH_Lock();
}
// convert bytes to ASCII hex (does not add end zero)
static void b2h(const uint8_t* b, char* h, uint8_t len)
{
@ -238,13 +278,20 @@ int main(void)
tud_init(BOARD_TUD_RHPORT);
printf("\r\npasskey v2\r\n");
load_config();
FLASH_OBProgramInitTypeDef ob;
HAL_FLASHEx_OBGetConfig(&ob);
if (OB_RDP_LEVEL_2 != ob.RDPLevel) {
printf("device not locked\r\n");
}
if (0 == strlen(manuf_key)) {
printf("manufacturer key not set\r\n");
}
if (board_init_after_tusb) {
board_init_after_tusb();
}
load_config();
while (true)
{
tud_task(); // tinyusb device task
@ -367,7 +414,7 @@ void cdc_task(void)
str = "\r\nenter authentication key (up to 32 char): ";
break;
case 'a': // run authentication
if (0 == strlen(config.user_key) && 0 == strlen(config.manuf_key)) {
if (0 == strlen(config.user_key) && 0 == strlen(manuf_key)) {
str = "\r\nno key set\r\n";
} else {
i = 0; // reset index
@ -390,9 +437,17 @@ void cdc_task(void)
break;
// hidden menu
case 'K': // set manufacturer key
i = 0; // reset index
menu = MENU_MANUF;
str = "\r\nenter manufacturer key (up to 32 char): ";
{
FLASH_OBProgramInitTypeDef ob;
HAL_FLASHEx_OBGetConfig(&ob);
if (OB_RDP_LEVEL_2 == ob.RDPLevel) {
str = "\r\ndevice locked\r\n";
} else {
i = 0; // reset index
menu = MENU_MANUF;
str = "\r\nenter manufacturer key (up to 32 char): ";
}
}
break;
case 'L': // lock device
{
@ -400,8 +455,6 @@ void cdc_task(void)
HAL_FLASHEx_OBGetConfig(&ob);
if (OB_RDP_LEVEL_2 == ob.RDPLevel) {
str = "\r\ndevice locked\r\n";
} else if (0 == strlen(config.manuf_key)) {
str = "\r\nset manufacturer key first\r\n";
} else {
str = "\r\nlocking device\r\n";
ob.RDPLevel = OB_RDP_LEVEL_2; // level 2, disabling debug, and write protecting option byte
@ -475,9 +528,9 @@ void cdc_task(void)
if ('\r' == buf[j] || '\n' == buf[j]) { // end received
tmp[i] = 0; // end key
if (strlen(tmp)) {
memset(config.manuf_key, 0, sizeof(config.manuf_key));
memcpy(config.manuf_key, tmp, i);
save_config();
memset(manuf_key, 0, sizeof(manuf_key));
memcpy(manuf_key, tmp, i);
save_manuf();
str = "\r\nmanufacturer key saved\r\n";
} else {
str = "\r\ninvalid input\r\n";
@ -522,7 +575,7 @@ void cdc_task(void)
tmp[i] = 0; // end string
if (strlen(tmp)) {
echo = false; // we need to write now
if (strlen(config.manuf_key)) {
if (strlen(manuf_key)) {
char uid[4 * 3 * 2 + 1];
b2h((uint8_t*)UID_BASE, uid, 4 * 3);
uid[sizeof(uid) - 1] = 0; // end string
@ -530,11 +583,11 @@ void cdc_task(void)
tud_cdc_write_str_flush(uid);
tud_cdc_write_str_flush(tmp);
tud_cdc_write_str_flush("\r\n");
uint8_t hash_in[sizeof(config.manuf_key) + sizeof(tmp)];
memcpy(&hash_in[0], config.manuf_key, strlen(config.manuf_key));
memcpy(&hash_in[strlen(config.user_key)], tmp, strlen(tmp));
uint8_t hash_in[sizeof(manuf_key) + sizeof(tmp)];
memcpy(&hash_in[0], manuf_key, strlen(manuf_key));
memcpy(&hash_in[strlen(manuf_key)], tmp, strlen(tmp));
SHA256_HASH hash_out;
Sha256Calculate(hash_in, strlen(config.manuf_key) + strlen(tmp), &hash_out);
Sha256Calculate(hash_in, strlen(manuf_key) + strlen(tmp), &hash_out);
char hash_str[SHA256_HASH_SIZE * 2 + 1];
b2h(hash_out.bytes, hash_str, SHA256_HASH_SIZE);
hash_str[SHA256_HASH_SIZE * 2] = 0; // end string