add manuf key setting

This commit is contained in:
King Kévin 2024-04-15 04:51:01 +02:00
parent f5a36a6bb8
commit 0c30f50731
1 changed files with 94 additions and 46 deletions

View File

@ -54,14 +54,16 @@
#define TIMEOUT_REPEAT (6U * 60) // maximum time after last repeat to hold the credentials, in minutes
static struct config_t {
char manuf_key[16 + 1]; // the key set by the manufacturer to authenticate the device
char user_key[16 + 1]; // the key set by the user to authenticate the device
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
uint16_t timeout_repeat; // time after last repeat to hold the credentials, in minutes
uint8_t crc; // simple XOR CRC to check config validity
} config;
// TODO move manuf key to seperate page, in write protected space
// last available page of last sector to store config
#define FLASH_CONFIG_ADDR ((uint32_t)0x08000000 + 0x400 * 27)
@ -187,6 +189,41 @@ 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)
{
if (!b || !h || !len) {
return;
}
for (uint8_t i = 0; i < len; i++) {
uint8_t nibble = b[i] >> 4;
if (nibble <= 9) {
h[i * 2 + 0] = '0' + nibble;
} else {
h[i * 2 + 0] = 'a' + nibble - 0xa;
}
nibble = b[i] & 0xf;
if (nibble <= 9) {
h[i * 2 + 1] = '0' + nibble;
} else {
h[i * 2 + 1] = 'a' + nibble - 0xa;
}
}
}
// ensure string is sent
void tud_cdc_write_str_flush(const char* str)
{
while (tud_cdc_write_available() < CFG_TUD_CDC_TX_BUFSIZE) {
tud_task();
}
tud_cdc_write_str(str);
tud_cdc_write_flush();
while (tud_cdc_write_available() < CFG_TUD_CDC_TX_BUFSIZE) {
tud_task();
}
}
int main(void)
{
board_init();
@ -319,7 +356,12 @@ void cdc_task(void)
case 'k': // set user key
i = 0; // reset index
menu = MENU_KEY;
str = "\r\nenter authentication key (up to 16 char): ";
str = "\r\nenter authentication key (up to 32 char): ";
break;
case 'K': // set manufacturer key
i = 0; // reset index
menu = MENU_MANUF;
str = "\r\nenter manufacturer key (up to 32 char): ";
break;
case 'a': // run authentication
if (0 == strlen(config.user_key) && 0 == strlen(config.manuf_key)) {
@ -339,11 +381,7 @@ void cdc_task(void)
tud_cdc_write_flush();
echo = false;
for (uint8_t j = 0; j < LENGTH(help_str); j++) {
while (tud_cdc_write_available() < CFG_TUD_CDC_TX_BUFSIZE) {
tud_task();
} // wait until there is enough space for the complete string
tud_cdc_write_str(help_str[j]);
tud_cdc_write_flush();
tud_cdc_write_str_flush(help_str[j]);
}
}
break;
@ -386,6 +424,29 @@ void cdc_task(void)
}
}
break;
case MENU_MANUF:
echo = false; // keep secret
for (uint16_t j = 0; j < count; j++) {
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();
str = "\r\nmanufacturer key saved\r\n";
} else {
str = "\r\ninvalid input\r\n";
}
i = 0; // reset index
menu = MENU_HOME; // go to next menu
} else if (i >= sizeof(config.user_key) - 2) {
memset(tmp, 0, sizeof(tmp)); // clear password
str = "\r\nlimit reached\r\n";
} else {
tmp[i++] = buf[j]; // save password
}
}
break;
case MENU_KEY:
echo = false; // keep secret
for (uint16_t j = 0; j < count; j++) {
@ -414,6 +475,25 @@ void cdc_task(void)
if ('\r' == buf[j] || '\n' == buf[j]) { // end received
tmp[i] = 0; // end string
if (strlen(tmp)) {
echo = false; // we need to write now
if (strlen(config.manuf_key)) {
char uid[4 * 3 * 2 + 1];
b2h((uint8_t*)UID_BASE, uid, 4 * 3);
uid[sizeof(uid) - 1] = 0; // end string
tud_cdc_write_str_flush("\r\nenter into https://passkey.cuvoodoo.info/: ");
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));
SHA256_HASH hash_out;
Sha256Calculate(hash_in, strlen(config.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
tud_cdc_write_str_flush(hash_str); // luckily the USB packet len is the same as the string
}
if (strlen(config.user_key)) {
uint8_t hash_in[sizeof(config.user_key) + sizeof(tmp)];
memcpy(&hash_in[0], config.user_key, strlen(config.user_key));
@ -421,46 +501,14 @@ void cdc_task(void)
SHA256_HASH hash_out;
Sha256Calculate(hash_in, strlen(config.user_key) + strlen(tmp), &hash_out);
char hash_str[SHA256_HASH_SIZE * 2 + 1];
for (uint8_t k = 0; k < SHA256_HASH_SIZE; k++) {
uint8_t nibble = hash_out.bytes[k] >> 4;
if (nibble <= 9) {
hash_str[k * 2 + 0] = '0' + nibble;
} else {
hash_str[k * 2 + 0] = 'a' + nibble - 0xa;
}
nibble = hash_out.bytes[k] & 0xf;
if (nibble <= 9) {
hash_str[k * 2 + 1] = '0' + nibble;
} else {
hash_str[k * 2 + 1] = 'a' + nibble - 0xa;
}
}
b2h(hash_out.bytes, hash_str, SHA256_HASH_SIZE);
hash_str[SHA256_HASH_SIZE * 2] = 0; // end string
echo = false; // we need to write now
tud_cdc_write_str("\r\necho -n \"<key>");
tud_cdc_write_flush();
while (tud_cdc_write_available() < CFG_TUD_CDC_TX_BUFSIZE) {
tud_task();
}
tud_cdc_write_str(tmp);
tud_cdc_write_flush();
while (tud_cdc_write_available() < CFG_TUD_CDC_TX_BUFSIZE) {
tud_task();
}
tud_cdc_write_str("\" | sha256sum\r\n");
tud_cdc_write_flush();
while (tud_cdc_write_available() < CFG_TUD_CDC_TX_BUFSIZE) {
tud_task();
}
tud_cdc_write_str(hash_str); // luckily the USB packet len is the same as the string
tud_cdc_write_flush();
while (tud_cdc_write_available() < CFG_TUD_CDC_TX_BUFSIZE) {
tud_task();
}
tud_cdc_write_str("\r\n");
tud_cdc_write_flush();
tud_cdc_write_str_flush("\r\necho -n \"<key>");
tud_cdc_write_str_flush(tmp);
tud_cdc_write_str_flush("\" | sha256sum\r\n");
tud_cdc_write_str_flush(hash_str); // luckily the USB packet len is the same as the string
tud_cdc_write_str_flush("\r\n");
}
str = "\r\n";
} else {
str = "\r\ninvalid input\r\n";
}