Fix OTP command issues in Linux.
Fixes #96. Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
@@ -111,7 +111,7 @@ typedef struct otp_config {
|
|||||||
}) otp_config_t;
|
}) otp_config_t;
|
||||||
|
|
||||||
#define otp_config_size sizeof(otp_config_t)
|
#define otp_config_size sizeof(otp_config_t)
|
||||||
uint16_t otp_status();
|
uint16_t otp_status(bool is_otp);
|
||||||
|
|
||||||
int otp_process_apdu();
|
int otp_process_apdu();
|
||||||
int otp_unload();
|
int otp_unload();
|
||||||
@@ -140,10 +140,7 @@ int otp_select(app_t *a, uint8_t force) {
|
|||||||
else {
|
else {
|
||||||
config_seq = 0;
|
config_seq = 0;
|
||||||
}
|
}
|
||||||
otp_status();
|
otp_status(false);
|
||||||
memmove(res_APDU, res_APDU + 1, 6);
|
|
||||||
res_APDU_size = 6;
|
|
||||||
apdu.ne = res_APDU_size;
|
|
||||||
return PICOKEY_OK;
|
return PICOKEY_OK;
|
||||||
}
|
}
|
||||||
return PICOKEY_ERR_FILE_NOT_FOUND;
|
return PICOKEY_ERR_FILE_NOT_FOUND;
|
||||||
@@ -339,22 +336,32 @@ int otp_unload() {
|
|||||||
return PICOKEY_OK;
|
return PICOKEY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t otp_status() {
|
uint16_t otp_status(bool is_otp) {
|
||||||
if (scanned == false) {
|
if (scanned == false) {
|
||||||
scan_all();
|
scan_all();
|
||||||
scanned = true;
|
scanned = true;
|
||||||
}
|
}
|
||||||
res_APDU_size = 0;
|
res_APDU_size = 0;
|
||||||
res_APDU[1] = PICO_FIDO_VERSION_MAJOR;
|
if (is_otp) {
|
||||||
res_APDU[2] = PICO_FIDO_VERSION_MINOR;
|
res_APDU_size++;
|
||||||
res_APDU[3] = 0;
|
}
|
||||||
res_APDU[4] = config_seq;
|
res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MAJOR;
|
||||||
res_APDU[5] = (CONFIG2_TOUCH | CONFIG1_TOUCH) |
|
res_APDU[res_APDU_size++] = PICO_FIDO_VERSION_MINOR;
|
||||||
|
res_APDU[res_APDU_size++] = 0;
|
||||||
|
res_APDU[res_APDU_size++] = config_seq;
|
||||||
|
res_APDU[res_APDU_size++] = (CONFIG2_TOUCH | CONFIG1_TOUCH) |
|
||||||
(file_has_data(search_dynamic_file(EF_OTP_SLOT1)) ? CONFIG1_VALID :
|
(file_has_data(search_dynamic_file(EF_OTP_SLOT1)) ? CONFIG1_VALID :
|
||||||
0x00) |
|
0x00) |
|
||||||
(file_has_data(search_dynamic_file(EF_OTP_SLOT2)) ? CONFIG2_VALID :
|
(file_has_data(search_dynamic_file(EF_OTP_SLOT2)) ? CONFIG2_VALID :
|
||||||
0x00);
|
0x00);
|
||||||
res_APDU[6] = 0;
|
res_APDU[res_APDU_size++] = 0;
|
||||||
|
if (is_otp) {
|
||||||
|
res_APDU_size = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
apdu.ne = res_APDU_size;
|
||||||
|
}
|
||||||
|
|
||||||
return SW_OK();
|
return SW_OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -363,6 +370,7 @@ bool check_crc(const otp_config_t *data) {
|
|||||||
return crc == 0xF0B8;
|
return crc == 0xF0B8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _is_otp = false;
|
||||||
int cmd_otp() {
|
int cmd_otp() {
|
||||||
uint8_t p1 = P1(apdu), p2 = P2(apdu);
|
uint8_t p1 = P1(apdu), p2 = P2(apdu);
|
||||||
if (p2 != 0x00) {
|
if (p2 != 0x00) {
|
||||||
@@ -386,13 +394,13 @@ int cmd_otp() {
|
|||||||
file_put_data(ef, apdu.data, otp_config_size + 8);
|
file_put_data(ef, apdu.data, otp_config_size + 8);
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
config_seq++;
|
config_seq++;
|
||||||
return otp_status();
|
return otp_status(_is_otp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Delete slot
|
// Delete slot
|
||||||
delete_file(ef);
|
delete_file(ef);
|
||||||
config_seq++;
|
config_seq++;
|
||||||
return otp_status();
|
return otp_status(_is_otp);
|
||||||
}
|
}
|
||||||
else if (p1 == 0x04 || p1 == 0x05) {
|
else if (p1 == 0x04 || p1 == 0x05) {
|
||||||
otp_config_t *odata = (otp_config_t *) apdu.data;
|
otp_config_t *odata = (otp_config_t *) apdu.data;
|
||||||
@@ -416,6 +424,7 @@ int cmd_otp() {
|
|||||||
file_put_data(ef, apdu.data, otp_config_size);
|
file_put_data(ef, apdu.data, otp_config_size);
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
}
|
}
|
||||||
|
return otp_status(_is_otp);
|
||||||
}
|
}
|
||||||
else if (p1 == 0x06) {
|
else if (p1 == 0x06) {
|
||||||
uint8_t tmp[otp_config_size + 8];
|
uint8_t tmp[otp_config_size + 8];
|
||||||
@@ -439,6 +448,7 @@ int cmd_otp() {
|
|||||||
delete_file(ef2);
|
delete_file(ef2);
|
||||||
}
|
}
|
||||||
low_flash_available();
|
low_flash_available();
|
||||||
|
return otp_status(_is_otp);
|
||||||
}
|
}
|
||||||
else if (p1 == 0x10) {
|
else if (p1 == 0x10) {
|
||||||
memcpy(res_APDU, pico_serial.id, 4);
|
memcpy(res_APDU, pico_serial.id, 4);
|
||||||
@@ -456,12 +466,7 @@ int cmd_otp() {
|
|||||||
}
|
}
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
if (p1 == 0x30 || p1 == 0x38) {
|
if (p1 == 0x30 || p1 == 0x38) {
|
||||||
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1),
|
mbedtls_md_hmac(mbedtls_md_info_from_type(MBEDTLS_MD_SHA1), otp_config->aes_key, KEY_SIZE, apdu.data, 8, res_APDU);
|
||||||
otp_config->aes_key,
|
|
||||||
KEY_SIZE,
|
|
||||||
apdu.data,
|
|
||||||
8,
|
|
||||||
res_APDU);
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
res_APDU_size = 20;
|
res_APDU_size = 20;
|
||||||
}
|
}
|
||||||
@@ -562,10 +567,12 @@ int otp_hid_set_report_cb(uint8_t itf,
|
|||||||
apdu.header[1] = 0x01;
|
apdu.header[1] = 0x01;
|
||||||
apdu.header[2] = slot_id;
|
apdu.header[2] = slot_id;
|
||||||
apdu.header[3] = 0;
|
apdu.header[3] = 0;
|
||||||
|
_is_otp = true;
|
||||||
int ret = otp_process_apdu();
|
int ret = otp_process_apdu();
|
||||||
if (ret == 0x9000 && res_APDU_size > 0) {
|
if (ret == 0x9000 && res_APDU_size > 0) {
|
||||||
otp_send_frame(apdu.rdata, apdu.rlen);
|
otp_send_frame(apdu.rdata, apdu.rlen);
|
||||||
}
|
}
|
||||||
|
_is_otp = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("[OTP] Bad CRC!\n");
|
printf("[OTP] Bad CRC!\n");
|
||||||
@@ -607,7 +614,7 @@ uint16_t otp_hid_get_report_cb(uint8_t itf,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res_APDU = buffer;
|
res_APDU = buffer;
|
||||||
otp_status();
|
otp_status(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return reqlen;
|
return reqlen;
|
||||||
|
|||||||
Reference in New Issue
Block a user