add authentication menu
This commit is contained in:
parent
e89e5a72f6
commit
38b90fcafc
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
#include "usb_descriptors.h"
|
#include "usb_descriptors.h"
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
|
#include "WjCryptLib_Sha256.h"
|
||||||
|
|
||||||
// get the length of an array
|
// get the length of an array
|
||||||
#define LENGTH(x) (sizeof(x) / sizeof((x)[0]))
|
#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
|
#define TIMEOUT_REPEAT (6U * 60) // maximum time after last repeat to hold the credentials, in minutes
|
||||||
|
|
||||||
static struct config_t {
|
static struct config_t {
|
||||||
uint8_t manuf_key[16]; // the key set by the manufacturer to authenticate the device
|
char manuf_key[16 + 1]; // 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 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)
|
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_global; // time to hold the credentials, in minutes
|
||||||
uint16_t timeout_repeat; // time after last repeat 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_HOME,
|
||||||
MENU_USER,
|
MENU_USER,
|
||||||
MENU_PASS,
|
MENU_PASS,
|
||||||
MENU_ENTER_MANUF,
|
MENU_MANUF,
|
||||||
MENU_ENTER_USER,
|
MENU_KEY,
|
||||||
MENU_AUTH_MANUF,
|
MENU_AUTH,
|
||||||
MENU_AUTH_USER,
|
|
||||||
MENU_TIMEOUT_GLOBAL,
|
MENU_TIMEOUT_GLOBAL,
|
||||||
MENU_TIMEOUT_REPEAT,
|
MENU_TIMEOUT_REPEAT,
|
||||||
} menu = MENU_HOME;
|
} menu = MENU_HOME;
|
||||||
|
@ -316,6 +316,20 @@ void cdc_task(void)
|
||||||
menu = MENU_TIMEOUT_REPEAT;
|
menu = MENU_TIMEOUT_REPEAT;
|
||||||
str = "\r\nenter repeat timeout in minutes: ";
|
str = "\r\nenter repeat timeout in minutes: ";
|
||||||
break;
|
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 '\r':
|
||||||
case '\n':
|
case '\n':
|
||||||
break; // nothing to do
|
break; // nothing to do
|
||||||
|
@ -372,6 +386,94 @@ void cdc_task(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case MENU_TIMEOUT_GLOBAL:
|
||||||
for (uint16_t j = 0; j < count; j++) {
|
for (uint16_t j = 0; j < count; j++) {
|
||||||
if ('\r' == buf[j] || '\n' == buf[j]) { // end received
|
if ('\r' == buf[j] || '\n' == buf[j]) { // end received
|
||||||
|
|
Loading…
Reference in New Issue