Merge pull request #96 from merlokk/nfc2

small fixes in NFC branch
This commit is contained in:
Conor Patrick 2019-02-02 00:16:07 -05:00 committed by GitHub
commit b7bc50bc4f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 143 additions and 17 deletions

View File

@ -229,12 +229,12 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
}
else
{
return U2F_SW_WRONG_DATA;
return U2F_SW_WRONG_PAYLOAD;
}
}
if (
control != U2F_AUTHENTICATE_SIGN ||
req->khl != U2F_KEY_HANDLE_SIZE ||
(control != U2F_AUTHENTICATE_SIGN && control != U2F_AUTHENTICATE_SIGN_NO_USER) ||
req->khl != U2F_KEY_HANDLE_SIZE ||
u2f_appid_eq(&req->kh, req->app) != 0 || // Order of checks is important
u2f_load_key(&req->kh, req->app) != 0
@ -243,9 +243,11 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
return U2F_SW_WRONG_PAYLOAD;
}
// dont-enforce-user-presence-and-sign
if (control == U2F_AUTHENTICATE_SIGN_NO_USER)
up = 0;
if(!fromNFC)
if(!fromNFC && up)
{
if (ctap_user_presence_test() == 0)
{
@ -254,21 +256,26 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
}
count = ctap_atomic_count(0);
uint8_t vcount[4];
vcount[3] = (count) & 0xff;
vcount[2] = (count >> 8) & 0xff;
vcount[1] = (count >> 16) & 0xff;
vcount[0] = (count >> 24) & 0xff;
crypto_sha256_init();
crypto_sha256_update(req->app,32);
crypto_sha256_update(&up,1);
crypto_sha256_update((uint8_t *)&count,4);
crypto_sha256_update(req->chal,32);
crypto_sha256_update(req->app, 32);
crypto_sha256_update(&up, 1);
crypto_sha256_update(vcount, 4);
crypto_sha256_update(req->chal, 32);
crypto_sha256_final(hash);
printf1(TAG_U2F, "sha256: "); dump_hex1(TAG_U2F,hash,32);
printf1(TAG_U2F, "sha256: "); dump_hex1(TAG_U2F, hash, 32);
crypto_ecc256_sign(hash, 32, sig);
u2f_response_writeback(&up,1);
u2f_response_writeback((uint8_t *)&count,4);
u2f_response_writeback(&up, 1);
u2f_response_writeback(vcount, 4);
dump_signature_der(sig);
return U2F_SW_NO_ERROR;

View File

@ -53,6 +53,7 @@
// U2F Authenticate
#define U2F_AUTHENTICATE_CHECK 0x7
#define U2F_AUTHENTICATE_SIGN 0x3
#define U2F_AUTHENTICATE_SIGN_NO_USER 0x8
// Command status responses

View File

@ -70,7 +70,6 @@ bool ams_wait_for_tx(uint32_t timeout_ms)
return false;
}
//bool ams_receive_with_timeout(10, recbuf, sizeof(recbuf), &reclen))
bool ams_receive_with_timeout(uint32_t timeout_ms, uint8_t * data, int maxlen, int *dlen)
{
uint8_t buf[32];
@ -210,6 +209,82 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len)
}
}
// WTX on/off:
// sends/receives WTX frame to reader every `WTX_time` time in ms
// works via timer interrupts
// WTX: f2 01 91 40 === f2(S-block + WTX, frame without CID) 01(from iso - multiply WTX from ATS by 1) <2b crc16>
static bool WTX_sent;
static bool WTX_fail;
void WTX_clear()
{
WTX_sent = false;
WTX_fail = false;
}
bool WTX_on(int WTX_time)
{
WTX_clear();
// TODO: start interrupt
return true;
}
bool WTX_process(int read_timeout);
bool WTX_off()
{
// TODO: stop interrupt
// read data if we sent WTX
if (WTX_sent)
{
if (!WTX_process(10))
return false;
}
if (WTX_fail)
return false;
return true;
}
// executes twice a period. 1st for send WTX, 2nd for check the result
// read timeout must be 0 to call from int
bool WTX_process(int read_timeout)
{
uint8_t wtx[] = {0xf2, 0x01};
if (WTX_fail)
return false;
if (!WTX_sent)
{
nfc_write_frame(wtx, sizeof(wtx));
WTX_sent = true;
return true;
}
else
{
uint8_t data[32];
int len;
if (ams_receive_with_timeout(read_timeout, data, sizeof(data), &len))
{
WTX_fail = true;
return false;
}
if (len != 2 || data[0] != 0xf2 || data[1] != 0x01)
{
WTX_fail = true;
return false;
}
WTX_sent = false;
return true;
}
}
int answer_rats(uint8_t parameter)
{
@ -341,12 +416,22 @@ void nfc_process_iblock(uint8_t * buf, int len)
break;
case APDU_FIDO_U2F_VERSION:
if (NFC_STATE.selected_applet != APP_FIDO) {
nfc_write_response(buf[0], SW_INS_INVALID);
break;
}
printf1(TAG_NFC, "U2F GetVersion command.\r\n");
nfc_write_response_ex(buf[0], (uint8_t *)"U2F_V2", 6, SW_SUCCESS);
break;
case APDU_FIDO_U2F_REGISTER:
if (NFC_STATE.selected_applet != APP_FIDO) {
nfc_write_response(buf[0], SW_INS_INVALID);
break;
}
printf1(TAG_NFC, "U2F Register command.\r\n");
if (plen != 64)
@ -357,7 +442,10 @@ void nfc_process_iblock(uint8_t * buf, int len)
}
t1 = millis();
WTX_on(WTX_TIME_DEFAULT);
u2f_request_nfc(&buf[1], len, &ctap_resp);
if (!WTX_off())
return;
printf1(TAG_NFC, "U2F resp len: %d\r\n", ctap_resp.length);
printf1(TAG_NFC,"U2F Register processing %d (took %d)\r\n", millis(), millis() - t1);
@ -366,6 +454,11 @@ void nfc_process_iblock(uint8_t * buf, int len)
break;
case APDU_FIDO_U2F_AUTHENTICATE:
if (NFC_STATE.selected_applet != APP_FIDO) {
nfc_write_response(buf[0], SW_INS_INVALID);
break;
}
printf1(TAG_NFC, "U2F Authenticate command.\r\n");
if (plen != 64 + 1 + buf[6 + 64])
@ -377,7 +470,10 @@ void nfc_process_iblock(uint8_t * buf, int len)
}
t1 = millis();
WTX_on(WTX_TIME_DEFAULT);
u2f_request_nfc(&buf[1], len, &ctap_resp);
if (!WTX_off())
return;
printf1(TAG_NFC, "U2F resp len: %d\r\n", ctap_resp.length);
printf1(TAG_NFC,"U2F Authenticate processing %d (took %d)\r\n", millis(), millis() - t1);
@ -386,11 +482,19 @@ void nfc_process_iblock(uint8_t * buf, int len)
break;
case APDU_FIDO_NFCCTAP_MSG:
if (NFC_STATE.selected_applet != APP_FIDO) {
nfc_write_response(buf[0], SW_INS_INVALID);
break;
}
t1 = millis();
printf1(TAG_NFC, "FIDO2 CTAP message. %d\r\n", t1);
WTX_on(WTX_TIME_DEFAULT);
ctap_response_init(&ctap_resp);
status = ctap_request(payload, plen, &ctap_resp);
if (!WTX_off())
return;
printf1(TAG_NFC, "CTAP resp: %d len: %d\r\n", status, ctap_resp.length);
if (status == CTAP1_ERR_SUCCESS)
@ -421,7 +525,7 @@ void nfc_process_iblock(uint8_t * buf, int len)
printf1(TAG_ERR, "Truncating requested CC length %d\r\n", apdu->lc);
plen = 15;
}
nfc_write_response_ex(buf[0], &NFC_CC, plen, SW_SUCCESS);
nfc_write_response_ex(buf[0], (uint8_t *)&NFC_CC, plen, SW_SUCCESS);
ams_wait_for_tx(10);
break;
case APP_NDEF_TAG:
@ -450,10 +554,17 @@ void nfc_process_iblock(uint8_t * buf, int len)
}
static uint8_t ibuf[1024];
static int ibuflen = 0;
void clear_ibuf()
{
ibuflen = 0;
memset(ibuf, 0, sizeof(ibuf));
}
void nfc_process_block(uint8_t * buf, int len)
{
static uint8_t ibuf[1024];
static int ibuflen = 0;
if (!len)
return;
@ -509,7 +620,7 @@ void nfc_process_block(uint8_t * buf, int len)
// printf1(TAG_NFC, "NFC_CMD_IBLOCK\r\n");
nfc_process_iblock(buf, len);
}
ibuflen = 0;
clear_ibuf();
}
}
else if (IS_RBLOCK(buf[0]))
@ -527,6 +638,8 @@ void nfc_process_block(uint8_t * buf, int len)
ams_wait_for_tx(2);
ams_write_command(AMS_CMD_SLEEP);
nfc_state_init();
clear_ibuf();
WTX_clear();
}
else
{
@ -610,6 +723,8 @@ void nfc_loop()
t1 = millis();
answer_rats(buf[1]);
NFC_STATE.block_num = 1;
clear_ibuf();
WTX_clear();
printf1(TAG_NFC,"RATS answered %d (took %d)\r\n",millis(), millis() - t1);
break;
default:

View File

@ -20,6 +20,9 @@ typedef struct
uint8_t tlv[8];
} __attribute__((packed)) CAPABILITY_CONTAINER;
// WTX time in ms
#define WTX_TIME_DEFAULT 300
#define NFC_CMD_REQA 0x26
#define NFC_CMD_WUPA 0x52
#define NFC_CMD_HLTA 0x50