add authentication menu

This commit is contained in:
King Kévin 2024-04-15 04:10:36 +02:00
parent e89e5a72f6
commit 38b90fcafc
1 changed files with 108 additions and 6 deletions

View File

@ -34,6 +34,7 @@
#include "usb_descriptors.h"
#include "hid.h"
#include "WjCryptLib_Sha256.h"
// get the length of an array
#define LENGTH(x) (sizeof(x) / sizeof((x)[0]))
@ -53,8 +54,8 @@
#define TIMEOUT_REPEAT (6U * 60) // maximum time after last repeat to hold the credentials, in minutes
static struct config_t {
uint8_t manuf_key[16]; // the key set by the manufacturer to authenticate the device
uint8_t user_key[16]; // the key set by the user to authenticate the device
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
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
@ -96,10 +97,9 @@ enum {
MENU_HOME,
MENU_USER,
MENU_PASS,
MENU_ENTER_MANUF,
MENU_ENTER_USER,
MENU_AUTH_MANUF,
MENU_AUTH_USER,
MENU_MANUF,
MENU_KEY,
MENU_AUTH,
MENU_TIMEOUT_GLOBAL,
MENU_TIMEOUT_REPEAT,
} menu = MENU_HOME;
@ -316,6 +316,20 @@ void cdc_task(void)
menu = MENU_TIMEOUT_REPEAT;
str = "\r\nenter repeat timeout in minutes: ";
break;
case 'k': // set user key
i = 0; // reset index
menu = MENU_KEY;
str = "\r\nenter authentication key (up to 16 char): ";
break;
case 'a': // run authentication
if (0 == strlen(config.user_key) && 0 == strlen(config.manuf_key)) {
str = "\r\nno key set\r\n";
} else {
i = 0; // reset index
menu = MENU_AUTH;
str = "\r\nenter random string (up to 60 char): ";
}
break;
case '\r':
case '\n':
break; // nothing to do
@ -372,6 +386,94 @@ void cdc_task(void)
}
}
break;
case MENU_KEY:
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.user_key, 0, sizeof(config.user_key));
memcpy(config.user_key, tmp, i);
save_config();
str = "\r\nauthentication 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_AUTH:
for (uint16_t j = 0; j < count; j++) {
if ('\r' == buf[j] || '\n' == buf[j]) { // end received
tmp[i] = 0; // end string
if (strlen(tmp)) {
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));
memcpy(&hash_in[strlen(config.user_key)], tmp, strlen(tmp));
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;
}
}
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();
}
str = "\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_TIMEOUT_GLOBAL:
for (uint16_t j = 0; j < count; j++) {
if ('\r' == buf[j] || '\n' == buf[j]) { // end received