mirror of
https://github.com/polhenarejos/pico-hsm.git
synced 2026-01-17 09:28:05 +00:00
Added press button to confirm. Everytime a private/secret key is loaded, the Pico HSM waits for BOOTSEL button press. This mechanism guarantees that no private/secret operations are made without user consent. To confirm the operation, the user must press the BOOTSEL button. In the meanwhile, the device gets into waiting state and no other operation is performed. After release the button, the operation continues normally.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
24b1d6807b
commit
878eae9787
3 changed files with 75 additions and 22 deletions
|
|
@ -29,7 +29,6 @@
|
|||
#include "tusb.h"
|
||||
#include "usb_descriptors.h"
|
||||
#include "device/usbd_pvt.h"
|
||||
#include "pico/util/queue.h"
|
||||
#include "pico/multicore.h"
|
||||
#include "random.h"
|
||||
#include "hsm2040.h"
|
||||
|
|
@ -94,7 +93,8 @@ app_t *current_app = NULL;
|
|||
|
||||
extern void card_thread();
|
||||
|
||||
static queue_t *card_comm;
|
||||
queue_t *card_comm = NULL;
|
||||
queue_t *ccid_comm = NULL;
|
||||
extern void low_flash_init_core1();
|
||||
|
||||
int register_app(app_t * (*select_aid)()) {
|
||||
|
|
@ -374,18 +374,28 @@ usbd_class_driver_t const *usbd_app_driver_get_cb(uint8_t *driver_count) {
|
|||
return &ccid_driver;
|
||||
}
|
||||
|
||||
enum {
|
||||
BLINK_NOT_MOUNTED = (250 << 16) | 250,
|
||||
BLINK_MOUNTED = (250 << 16) | 250,
|
||||
BLINK_SUSPENDED = (500 << 16) | 1000,
|
||||
BLINK_PROCESSING = (50 << 16) | 50,
|
||||
|
||||
BLINK_ALWAYS_ON = UINT32_MAX,
|
||||
BLINK_ALWAYS_OFF = 0
|
||||
};
|
||||
|
||||
static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
|
||||
|
||||
void led_set_blink(uint32_t mode) {
|
||||
blink_interval_ms = mode;
|
||||
}
|
||||
|
||||
void execute_tasks();
|
||||
|
||||
static void wait_button() {
|
||||
led_set_blink((1000 << 16) | 100);
|
||||
while (board_button_read() == false) {
|
||||
execute_tasks();
|
||||
//sleep_ms(10);
|
||||
}
|
||||
while (board_button_read() == true) {
|
||||
execute_tasks();
|
||||
//sleep_ms(10);
|
||||
}
|
||||
led_set_blink(BLINK_PROCESSING);
|
||||
}
|
||||
|
||||
void usb_tx_enable(const uint8_t *buf, uint32_t len)
|
||||
{
|
||||
if (len > 0) {
|
||||
|
|
@ -485,7 +495,7 @@ static enum ccid_state ccid_power_on(struct ccid *c)
|
|||
|
||||
DEBUG_INFO("ON\r\n");
|
||||
c->tx_busy = 1;
|
||||
blink_interval_ms = BLINK_MOUNTED;
|
||||
led_set_blink(BLINK_MOUNTED);
|
||||
return CCID_STATE_WAIT;
|
||||
}
|
||||
|
||||
|
|
@ -532,7 +542,7 @@ static enum ccid_state ccid_power_off(struct ccid *c)
|
|||
ccid_send_status (c);
|
||||
DEBUG_INFO ("OFF\r\n");
|
||||
c->tx_busy = 1;
|
||||
blink_interval_ms = BLINK_SUSPENDED;
|
||||
led_set_blink(BLINK_SUSPENDED);
|
||||
return CCID_STATE_START;
|
||||
}
|
||||
|
||||
|
|
@ -1376,7 +1386,7 @@ void prepare_ccid()
|
|||
}
|
||||
|
||||
int process_apdu() {
|
||||
blink_interval_ms = BLINK_PROCESSING;
|
||||
led_set_blink(BLINK_PROCESSING);
|
||||
if (!current_app) {
|
||||
if (INS(apdu) == 0xA4 && P1(apdu) == 0x04 && (P2(apdu) == 0x00 || P2(apdu) == 0x4)) { //select by AID
|
||||
for (int a = 0; a < num_apps; a++) {
|
||||
|
|
@ -1406,7 +1416,7 @@ static void card_init (void)
|
|||
|
||||
void card_thread()
|
||||
{
|
||||
queue_t *ccid_comm = (queue_t *)multicore_fifo_pop_blocking();
|
||||
ccid_comm = (queue_t *)multicore_fifo_pop_blocking();
|
||||
card_comm = (queue_t *)multicore_fifo_pop_blocking();
|
||||
|
||||
card_init ();
|
||||
|
|
@ -1531,7 +1541,7 @@ void ccid_task(void)
|
|||
{
|
||||
DEBUG_INFO ("ERR05\r\n");
|
||||
}
|
||||
blink_interval_ms = BLINK_MOUNTED;
|
||||
led_set_blink(BLINK_MOUNTED);
|
||||
}
|
||||
else if (m == EV_TX_FINISHED)
|
||||
{
|
||||
|
|
@ -1542,6 +1552,11 @@ void ccid_task(void)
|
|||
if (c->state == APDU_STATE_WAIT_COMMAND || c->state == APDU_STATE_COMMAND_CHAINING || c->state == APDU_STATE_RESULT_GET_RESPONSE)
|
||||
ccid_prepare_receive(c);
|
||||
}
|
||||
else if (m == EV_PRESS_BUTTON) {
|
||||
wait_button();
|
||||
uint32_t flag = EV_BUTTON_PRESSED;
|
||||
queue_try_add(&c->card_comm, &flag);
|
||||
}
|
||||
}
|
||||
else /* Timeout */
|
||||
{
|
||||
|
|
@ -1624,6 +1639,13 @@ extern void neug_task();
|
|||
|
||||
pico_unique_board_id_t unique_id;
|
||||
|
||||
void execute_tasks() {
|
||||
prev_millis = board_millis();
|
||||
ccid_task();
|
||||
tud_task(); // tinyusb device task
|
||||
led_blinking_task();
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct apdu *a = &apdu;
|
||||
|
|
@ -1660,10 +1682,7 @@ int main(void)
|
|||
|
||||
while (1)
|
||||
{
|
||||
prev_millis = board_millis();
|
||||
ccid_task();
|
||||
tud_task(); // tinyusb device task
|
||||
led_blinking_task();
|
||||
execute_tasks();
|
||||
neug_task();
|
||||
do_flash();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "tusb.h"
|
||||
#include "file.h"
|
||||
#include "pico/unique_id.h"
|
||||
#include "pico/util/queue.h"
|
||||
|
||||
#define USB_REQ_CCID 0xA1
|
||||
|
||||
|
|
@ -79,13 +80,18 @@ struct apdu {
|
|||
#define EV_EXEC_ACK_REQUIRED 4 /* OpenPGPcard Execution ACK required */
|
||||
#define EV_EXEC_FINISHED 8 /* OpenPGPcard Execution finished */
|
||||
#define EV_RX_DATA_READY 16 /* USB Rx data available */
|
||||
#define EV_PRESS_BUTTON 32
|
||||
|
||||
/* OpenPGPcard thread */
|
||||
/* SC HSM thread */
|
||||
#define EV_MODIFY_CMD_AVAILABLE 1
|
||||
#define EV_VERIFY_CMD_AVAILABLE 2
|
||||
#define EV_CMD_AVAILABLE 4
|
||||
#define EV_EXIT 8
|
||||
#define EV_PINPAD_INPUT_DONE 16
|
||||
#define EV_BUTTON_PRESSED 16
|
||||
|
||||
//Variables set by core1
|
||||
extern queue_t *ccid_comm;
|
||||
extern queue_t *card_comm;
|
||||
|
||||
enum ccid_state {
|
||||
CCID_STATE_NOCARD, /* No card available */
|
||||
|
|
@ -157,4 +163,16 @@ extern void low_flash_available();
|
|||
extern int flash_clear_file(file_t *file);
|
||||
|
||||
extern pico_unique_board_id_t unique_id;
|
||||
|
||||
enum {
|
||||
BLINK_NOT_MOUNTED = (250 << 16) | 250,
|
||||
BLINK_MOUNTED = (250 << 16) | 250,
|
||||
BLINK_SUSPENDED = (500 << 16) | 1000,
|
||||
BLINK_PROCESSING = (50 << 16) | 50,
|
||||
|
||||
BLINK_ALWAYS_ON = UINT32_MAX,
|
||||
BLINK_ALWAYS_OFF = 0
|
||||
};
|
||||
extern void led_set_blink(uint32_t mode);
|
||||
|
||||
#endif
|
||||
|
|
@ -101,6 +101,17 @@ uint16_t get_device_options() {
|
|||
return 0x0;
|
||||
}
|
||||
|
||||
extern uint32_t board_button_read(void);
|
||||
|
||||
static void wait_button() {
|
||||
uint32_t val = EV_PRESS_BUTTON;
|
||||
queue_try_add(ccid_comm, &val);
|
||||
do {
|
||||
queue_remove_blocking(card_comm, &val);
|
||||
}
|
||||
while (val != EV_BUTTON_PRESSED);
|
||||
}
|
||||
|
||||
static int cmd_select() {
|
||||
uint8_t p1 = P1(apdu);
|
||||
uint8_t p2 = P2(apdu);
|
||||
|
|
@ -1191,6 +1202,7 @@ static int cmd_key_gen() {
|
|||
}
|
||||
|
||||
int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
|
||||
wait_button();
|
||||
int key_size = file_read_uint16(fkey->data);
|
||||
uint8_t kdata[4096/8];
|
||||
memcpy(kdata, file_read(fkey->data+2), key_size);
|
||||
|
|
@ -1225,6 +1237,7 @@ int load_private_key_rsa(mbedtls_rsa_context *ctx, file_t *fkey) {
|
|||
}
|
||||
|
||||
int load_private_key_ecdsa(mbedtls_ecdsa_context *ctx, file_t *fkey) {
|
||||
wait_button();
|
||||
int key_size = file_read_uint16(fkey->data);
|
||||
uint8_t kdata[67]; //Worst case, 521 bit + 1byte
|
||||
memcpy(kdata, file_read(fkey->data+2), key_size);
|
||||
|
|
@ -1417,6 +1430,7 @@ static int cmd_key_wrap() {
|
|||
}
|
||||
else if (*dprkd == P15_KEYTYPE_AES) {
|
||||
uint8_t kdata[32]; //maximum AES key size
|
||||
wait_button();
|
||||
int key_size = file_read_uint16(ef->data), aes_type = HSM_KEY_AES;
|
||||
memcpy(kdata, file_read(ef->data+2), key_size);
|
||||
if (dkek_decrypt(kdata, key_size) != 0) {
|
||||
|
|
@ -1526,6 +1540,7 @@ static int cmd_decrypt_asym() {
|
|||
}
|
||||
else if (P2(apdu) == ALGO_EC_DH) {
|
||||
mbedtls_ecdh_context ctx;
|
||||
wait_button();
|
||||
int key_size = file_read_uint16(ef->data);
|
||||
uint8_t *kdata = (uint8_t *)calloc(1,key_size);
|
||||
memcpy(kdata, file_read(ef->data+2), key_size);
|
||||
|
|
@ -1580,6 +1595,7 @@ static int cmd_cipher_sym() {
|
|||
if ((apdu.cmd_apdu_data_len % 16) != 0) {
|
||||
return SW_WRONG_LENGTH();
|
||||
}
|
||||
wait_button();
|
||||
int key_size = file_read_uint16(ef->data);
|
||||
uint8_t kdata[32]; //maximum AES key size
|
||||
memcpy(kdata, file_read(ef->data+2), key_size);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue