From 4e0dc15dfd19c2919e229759f51361692edae3a0 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jan 2019 16:56:38 +0200 Subject: [PATCH 01/24] add historical bytes --- targets/stm32l432/src/nfc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index ed3e9d8..936f979 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -74,8 +74,8 @@ int answer_rats(uint8_t parameter) else NFC_STATE.max_frame_size = 32; - uint8_t res[3]; - res[0] = 3; + uint8_t res[3 + 11]; + res[0] = sizeof(res); res[1] = 2 | (1<<5); // 2 FSCI == 32 byte frame size, TB is enabled // frame wait time = (256 * 16 / 13.56MHz) * 2^FWI @@ -86,8 +86,10 @@ int answer_rats(uint8_t parameter) // FWI=14, FMT=4949ms (max) res[2] = (12<<4) | (0); // TB (FWI << 4) | (SGTI) - - nfc_write_frame(res,3); + // historical bytes + memcpy(&res[3], (uint8_t *)"SoloKey tap", 11); + + nfc_write_frame(res, sizeof(res)); return 0; } From ad9186c13baf8a0cb0de740dc3855bba542aac89 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jan 2019 17:57:42 +0200 Subject: [PATCH 02/24] SELECT works --- targets/stm32l432/src/nfc.c | 30 ++++++++---------------------- targets/stm32l432/src/nfc.h | 17 ++++++++++------- 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 936f979..d4f01e3 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -104,37 +104,24 @@ void rblock_acknowledge() // Selects application. Returns 1 if success, 0 otherwise int select_applet(uint8_t * aid, int len) { - if (memcmp(aid,AID_NDEF_TYPE_4,sizeof(AID_NDEF_TYPE_4)) == 0) + if (memcmp(aid,AID_FIDO,sizeof(AID_FIDO)) == 0) { - NFC_STATE.selected_applet = APP_NDEF_TYPE_4; - return 1; - } else if (memcmp(aid,AID_NDEF_MIFARE_TYPE_4,sizeof(AID_NDEF_MIFARE_TYPE_4)) == 0) - { - NFC_STATE.selected_applet = APP_MIFARE_TYPE_4; - return 1; - } else if (memcmp(aid,AID_CAPABILITY_CONTAINER,sizeof(AID_CAPABILITY_CONTAINER)) == 0) - { - NFC_STATE.selected_applet = APP_CAPABILITY_CONTAINER; - return 1; - } else if (memcmp(aid,AID_NDEF_TAG,sizeof(AID_NDEF_TAG)) == 0) - { - NFC_STATE.selected_applet = APP_NDEF_TAG; + NFC_STATE.selected_applet = APP_FIDO; return 1; } - return 0; } void nfc_process_iblock(uint8_t * buf, int len) { - APDU_HEADER * apdu = (APDU_HEADER *)(buf+1); + APDU_HEADER * apdu = (APDU_HEADER *)(buf + 1); uint8_t * payload = buf + 1 + 5; uint8_t plen = apdu->lc; int selected; uint8_t res[32]; - printf1(TAG_NFC,">> "); dump_hex1(TAG_NFC,buf,len); - + printf1(TAG_NFC,">> "); + dump_hex1(TAG_NFC, buf, len); // TODO this needs to be organized better switch(apdu->ins) @@ -162,13 +149,12 @@ void nfc_process_iblock(uint8_t * buf, int len) selected = select_applet(payload, plen); if (selected) { - // block = buf[0] & 1; // block = NFC_STATE.block_num; // block = !block; // NFC_STATE.block_num = block; - res[0] = NFC_CMD_IBLOCK | (buf[0] & 1); - res[1] = APDU_STATUS_SUCCESS>>8; + res[0] = NFC_CMD_IBLOCK | (buf[0] & 3); + res[1] = APDU_STATUS_SUCCESS >> 8; res[2] = APDU_STATUS_SUCCESS & 0xff; nfc_write_frame(res, 3); printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC,res, 3); @@ -231,8 +217,8 @@ void nfc_process_block(uint8_t * buf, int len) } else if (IS_IBLOCK(buf[0])) { - nfc_process_iblock(buf,len); printf1(TAG_NFC, "NFC_CMD_IBLOCK\r\n"); + nfc_process_iblock(buf, len); } else if (IS_RBLOCK(buf[0])) { diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index 8a91803..457b686 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -34,14 +34,15 @@ typedef struct #define NFC_CMD_PPSS 0xd0 #define IS_PPSS_CMD(x) (((x) & 0xf0) == NFC_CMD_PPSS) -#define NFC_CMD_IBLOCK 0x02 -#define IS_IBLOCK(x) (((x) & 0xe2) == NFC_CMD_IBLOCK) -#define NFC_CMD_RBLOCK 0xa2 -#define IS_RBLOCK(x) (((x) & 0xe6) == NFC_CMD_RBLOCK) -#define NFC_CMD_SBLOCK 0xc2 -#define IS_SBLOCK(x) (((x) & 0xc7) == NFC_CMD_SBLOCK) +#define NFC_CMD_IBLOCK 0x00 +#define IS_IBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_IBLOCK) && (((x) & 0x02) == 0x02) ) +#define NFC_CMD_RBLOCK 0x80 +#define IS_RBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_RBLOCK) && (((x) & 0x02) == 0x02) ) +#define NFC_CMD_SBLOCK 0xc0 +#define IS_SBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_SBLOCK) && (((x) & 0x02) == 0x02) ) -#define NFC_SBLOCK_DESELECT 0x30 +#define NFC_SBLOCK_DESELECT 0x32 +#define NFC_SBLOCK_WTX 0xf2 #define APDU_INS_SELECT 0xA4 #define APDU_INS_READ_BINARY 0xB0 @@ -50,6 +51,7 @@ typedef struct #define AID_NDEF_MIFARE_TYPE_4 "\xD2\x76\x00\x00\x85\x01\x00" #define AID_CAPABILITY_CONTAINER "\xE1\x03" #define AID_NDEF_TAG "\x11\x11" +#define AID_FIDO "\xa0\x00\x00\x06\x47\x2f\x00\x01" typedef enum { @@ -57,6 +59,7 @@ typedef enum APP_MIFARE_TYPE_4, APP_CAPABILITY_CONTAINER, APP_NDEF_TAG, + APP_FIDO, } APPLETS; #define APDU_STATUS_SUCCESS 0x9000 From d02206ba09387a8a414bdbd2e7dff5e20fc4374f Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jan 2019 18:19:23 +0200 Subject: [PATCH 03/24] SELECT works as expected and U2F GetVersion command done --- targets/stm32l432/src/nfc.c | 32 +++++++++++++++++++++++++++----- targets/stm32l432/src/nfc.h | 4 ++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index d4f01e3..5030ae5 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -154,17 +154,39 @@ void nfc_process_iblock(uint8_t * buf, int len) // block = !block; // NFC_STATE.block_num = block; res[0] = NFC_CMD_IBLOCK | (buf[0] & 3); - res[1] = APDU_STATUS_SUCCESS >> 8; - res[2] = APDU_STATUS_SUCCESS & 0xff; - nfc_write_frame(res, 3); - printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC,res, 3); + memcpy(&res[1], (uint8_t *)"U2F_V2", 6); + res[7] = APDU_STATUS_SUCCESS >> 8; + res[8] = APDU_STATUS_SUCCESS & 0xff; + nfc_write_frame(res, 3 + 6); + printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC,res, 3 + 6); } else { - printf1(TAG_NFC, "NOT selected\r\n"); + res[0] = NFC_CMD_IBLOCK | (buf[0] & 3); + res[1] = 0x6a; + res[2] = 0x82; + nfc_write_frame(res, 3); + printf1(TAG_NFC, "NOT selected\r\n"); dump_hex1(TAG_NFC,res, 3); } } break; + + case APDU_FIDO_U2F_VERSION: + printf1(TAG_NFC, "GetVersion command.\r\n"); + res[0] = NFC_CMD_IBLOCK | (buf[0] & 3); + memcpy(&res[1], (uint8_t *)"U2F_V2", 6); + res[7] = APDU_STATUS_SUCCESS >> 8; + res[8] = APDU_STATUS_SUCCESS & 0xff; + nfc_write_frame(res, 3 + 6); + printf1(TAG_NFC, "<< "); dump_hex1(TAG_NFC,res, 3 + 6); + break; + + case APDU_FIDO_U2F_REGISTER: + break; + + case APDU_FIDO_U2F_AUTHENTICATE: + break; + case APDU_INS_READ_BINARY: diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index 457b686..d42e1ce 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -44,6 +44,10 @@ typedef struct #define NFC_SBLOCK_DESELECT 0x32 #define NFC_SBLOCK_WTX 0xf2 +#define APDU_FIDO_U2F_REGISTER 0x01 +#define APDU_FIDO_U2F_AUTHENTICATE 0x02 +#define APDU_FIDO_U2F_VERSION 0x03 +#define APDU_FIDO_EXCHANGE 0x10 #define APDU_INS_SELECT 0xA4 #define APDU_INS_READ_BINARY 0xB0 From 45888c9a25adb4f918825b3005e5f6074596c82b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jan 2019 18:22:58 +0200 Subject: [PATCH 04/24] ins check is ok --- targets/stm32l432/src/nfc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 5030ae5..a5b1124 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -172,7 +172,7 @@ void nfc_process_iblock(uint8_t * buf, int len) break; case APDU_FIDO_U2F_VERSION: - printf1(TAG_NFC, "GetVersion command.\r\n"); + printf1(TAG_NFC, "U2F GetVersion command.\r\n"); res[0] = NFC_CMD_IBLOCK | (buf[0] & 3); memcpy(&res[1], (uint8_t *)"U2F_V2", 6); res[7] = APDU_STATUS_SUCCESS >> 8; @@ -182,9 +182,15 @@ void nfc_process_iblock(uint8_t * buf, int len) break; case APDU_FIDO_U2F_REGISTER: + printf1(TAG_NFC, "U2F Register command.\r\n"); break; case APDU_FIDO_U2F_AUTHENTICATE: + printf1(TAG_NFC, "U2F Authenticate command.\r\n"); + break; + + case APDU_FIDO_EXCHANGE: + printf1(TAG_NFC, "FIDO2 Exchange command.\r\n"); break; case APDU_INS_READ_BINARY: From d713167ec4a8e2349e2963c3f9ef58c05e9e1683 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jan 2019 19:21:31 +0200 Subject: [PATCH 05/24] works. needs to add chaining --- targets/stm32l432/src/nfc.c | 18 +++++++++++++++--- targets/stm32l432/src/nfc.h | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index a5b1124..6640179 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -120,6 +120,9 @@ void nfc_process_iblock(uint8_t * buf, int len) int selected; uint8_t res[32]; + CTAP_RESPONSE ctap_resp; + int status; + printf1(TAG_NFC,">> "); dump_hex1(TAG_NFC, buf, len); @@ -173,24 +176,33 @@ void nfc_process_iblock(uint8_t * buf, int len) case APDU_FIDO_U2F_VERSION: printf1(TAG_NFC, "U2F GetVersion command.\r\n"); + res[0] = NFC_CMD_IBLOCK | (buf[0] & 3); memcpy(&res[1], (uint8_t *)"U2F_V2", 6); res[7] = APDU_STATUS_SUCCESS >> 8; res[8] = APDU_STATUS_SUCCESS & 0xff; nfc_write_frame(res, 3 + 6); - printf1(TAG_NFC, "<< "); dump_hex1(TAG_NFC,res, 3 + 6); + printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC,res, 3 + 6); break; case APDU_FIDO_U2F_REGISTER: printf1(TAG_NFC, "U2F Register command.\r\n"); + break; case APDU_FIDO_U2F_AUTHENTICATE: printf1(TAG_NFC, "U2F Authenticate command.\r\n"); break; - case APDU_FIDO_EXCHANGE: - printf1(TAG_NFC, "FIDO2 Exchange command.\r\n"); + case APDU_FIDO_NFCCTAP_MSG: + printf1(TAG_NFC, "FIDO2 CTAP message.\r\n"); + + ctap_response_init(&ctap_resp); + status = ctap_request(payload, plen, &ctap_resp); + printf1(TAG_NFC, "status: %d\r\n", status); + + nfc_write_frame(ctap_resp.data, ctap_resp.length); + printf1(TAG_NFC, "<< "); dump_hex1(TAG_NFC, ctap_resp.data, ctap_resp.length); break; case APDU_INS_READ_BINARY: diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index d42e1ce..2eca2e8 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -47,7 +47,7 @@ typedef struct #define APDU_FIDO_U2F_REGISTER 0x01 #define APDU_FIDO_U2F_AUTHENTICATE 0x02 #define APDU_FIDO_U2F_VERSION 0x03 -#define APDU_FIDO_EXCHANGE 0x10 +#define APDU_FIDO_NFCCTAP_MSG 0x10 #define APDU_INS_SELECT 0xA4 #define APDU_INS_READ_BINARY 0xB0 From 67b0abde4bd609cd3eaa90bab334dc92a3cf5e13 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jan 2019 19:56:18 +0200 Subject: [PATCH 06/24] some refactoring --- targets/stm32l432/src/nfc.c | 69 +++++++++++++++++++++++++------------ targets/stm32l432/src/nfc.h | 5 ++- 2 files changed, 51 insertions(+), 23 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 6640179..0c2b3a6 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -8,6 +8,9 @@ #include "util.h" #include "device.h" +#include "ctap_errors.h" + + // Capability container @@ -57,6 +60,36 @@ void nfc_write_frame(uint8_t * data, uint8_t len) ams_write_buffer(data,len); ams_write_command(AMS_CMD_TRANSMIT_BUFFER); + printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC, data, len); +} + +void nfc_write_response_chaining(uint8_t req0, uint8_t * data, uint8_t len) +{ + nfc_write_frame(data, len); +} + +bool nfc_write_response_ex(uint8_t req0, uint8_t * data, uint8_t len, uint16_t resp) +{ + uint8_t res[32]; + + if (len > 32 - 3) + return false; + + res[0] = NFC_CMD_IBLOCK | (req0 & 3); + + if (len) + memcpy(&res[1], data, len); + + res[len + 1] = resp >> 8; + res[len + 2] = resp & 0xff; + nfc_write_frame(res, 3 + len); + + return true; +} + +bool nfc_write_response(uint8_t req0, uint16_t resp) +{ + return nfc_write_response_ex(req0, NULL, 0, resp); } int answer_rats(uint8_t parameter) @@ -142,8 +175,8 @@ void nfc_process_iblock(uint8_t * buf, int len) // NFC_STATE.selected_applet = APP_NDEF_TAG; // // Select NDEF file! // res[0] = NFC_CMD_IBLOCK | (buf[0] & 1); - // res[1] = APDU_STATUS_SUCCESS>>8; - // res[2] = APDU_STATUS_SUCCESS & 0xff; + // res[1] = SW_SUCCESS>>8; + // res[2] = SW_SUCCESS & 0xff; // nfc_write_frame(res, 3); // printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC,res, 3); // } @@ -156,19 +189,11 @@ void nfc_process_iblock(uint8_t * buf, int len) // block = NFC_STATE.block_num; // block = !block; // NFC_STATE.block_num = block; - res[0] = NFC_CMD_IBLOCK | (buf[0] & 3); - memcpy(&res[1], (uint8_t *)"U2F_V2", 6); - res[7] = APDU_STATUS_SUCCESS >> 8; - res[8] = APDU_STATUS_SUCCESS & 0xff; - nfc_write_frame(res, 3 + 6); - printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC,res, 3 + 6); + nfc_write_response_ex(buf[0], (uint8_t *)"U2F_V2", 6, SW_SUCCESS); } else { - res[0] = NFC_CMD_IBLOCK | (buf[0] & 3); - res[1] = 0x6a; - res[2] = 0x82; - nfc_write_frame(res, 3); + nfc_write_response(buf[0], SW_FILE_NOT_FOUND); printf1(TAG_NFC, "NOT selected\r\n"); dump_hex1(TAG_NFC,res, 3); } } @@ -177,12 +202,7 @@ void nfc_process_iblock(uint8_t * buf, int len) case APDU_FIDO_U2F_VERSION: printf1(TAG_NFC, "U2F GetVersion command.\r\n"); - res[0] = NFC_CMD_IBLOCK | (buf[0] & 3); - memcpy(&res[1], (uint8_t *)"U2F_V2", 6); - res[7] = APDU_STATUS_SUCCESS >> 8; - res[8] = APDU_STATUS_SUCCESS & 0xff; - nfc_write_frame(res, 3 + 6); - printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC,res, 3 + 6); + nfc_write_response_ex(buf[0], (uint8_t *)"U2F_V2", 6, SW_SUCCESS); break; case APDU_FIDO_U2F_REGISTER: @@ -201,8 +221,12 @@ void nfc_process_iblock(uint8_t * buf, int len) status = ctap_request(payload, plen, &ctap_resp); printf1(TAG_NFC, "status: %d\r\n", status); - nfc_write_frame(ctap_resp.data, ctap_resp.length); - printf1(TAG_NFC, "<< "); dump_hex1(TAG_NFC, ctap_resp.data, ctap_resp.length); + if (status == CTAP1_ERR_SUCCESS) + { + nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length); + } else { + nfc_write_response(buf[0], SW_INTERNAL_EXCEPTION | status); + } break; case APDU_INS_READ_BINARY: @@ -235,14 +259,15 @@ void nfc_process_iblock(uint8_t * buf, int len) } res[0] = NFC_CMD_IBLOCK | (buf[0] & 1); - res[1+plen] = APDU_STATUS_SUCCESS>>8; - res[2+plen] = APDU_STATUS_SUCCESS & 0xff; + res[1+plen] = SW_SUCCESS>>8; + res[2+plen] = SW_SUCCESS & 0xff; nfc_write_frame(res, 3+plen); printf1(TAG_NFC,"APDU_INS_READ_BINARY\r\n"); printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC,res, 3+plen); break; default: printf1(TAG_NFC, "Unknown INS %02x\r\n", apdu->ins); + nfc_write_response(buf[0], SW_INS_INVALID); break; } diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index 2eca2e8..803bf26 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -66,6 +66,9 @@ typedef enum APP_FIDO, } APPLETS; -#define APDU_STATUS_SUCCESS 0x9000 +#define SW_SUCCESS 0x9000 +#define SW_FILE_NOT_FOUND 0x6a82 +#define SW_INS_INVALID 0x6d00 +#define SW_INTERNAL_EXCEPTION 0x6f00 #endif From e8634a2d615a5224f72a745e0cdaf5653ddb026b Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jan 2019 20:04:44 +0200 Subject: [PATCH 07/24] add u2f errors --- targets/stm32l432/src/nfc.c | 3 +++ targets/stm32l432/src/nfc.h | 1 + 2 files changed, 4 insertions(+) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 0c2b3a6..3590d5d 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -208,10 +208,13 @@ void nfc_process_iblock(uint8_t * buf, int len) case APDU_FIDO_U2F_REGISTER: printf1(TAG_NFC, "U2F Register command.\r\n"); + nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED); break; case APDU_FIDO_U2F_AUTHENTICATE: printf1(TAG_NFC, "U2F Authenticate command.\r\n"); + + nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED); break; case APDU_FIDO_NFCCTAP_MSG: diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index 803bf26..d80155a 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -67,6 +67,7 @@ typedef enum } APPLETS; #define SW_SUCCESS 0x9000 +#define SW_COND_USE_NOT_SATISFIED 0x6985 #define SW_FILE_NOT_FOUND 0x6a82 #define SW_INS_INVALID 0x6d00 #define SW_INTERNAL_EXCEPTION 0x6f00 From 94fe58d020424f88d613c0a98dd0fbbf6ca84f29 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Thu, 24 Jan 2019 20:09:57 +0200 Subject: [PATCH 08/24] small fix --- targets/stm32l432/src/nfc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 3590d5d..b4f26f0 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -77,7 +77,7 @@ bool nfc_write_response_ex(uint8_t req0, uint8_t * data, uint8_t len, uint16_t r res[0] = NFC_CMD_IBLOCK | (req0 & 3); - if (len) + if (len && data) memcpy(&res[1], data, len); res[len + 1] = resp >> 8; @@ -222,7 +222,7 @@ void nfc_process_iblock(uint8_t * buf, int len) ctap_response_init(&ctap_resp); status = ctap_request(payload, plen, &ctap_resp); - printf1(TAG_NFC, "status: %d\r\n", status); + printf1(TAG_NFC, "CTAP resp: %d len: %d\r\n", status, ctap_resp.length); if (status == CTAP1_ERR_SUCCESS) { From 15de8dc4a6db920458c4efb29e3803e0702a260e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 25 Jan 2019 19:32:42 +0200 Subject: [PATCH 09/24] send response from key to pc in chaining mode. partially works. GetVersion must work with pc (proxmark have errors) --- targets/stm32l432/src/nfc.c | 135 +++++++++++++++++++++++++++++++++--- targets/stm32l432/src/nfc.h | 1 + 2 files changed, 128 insertions(+), 8 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index b4f26f0..d78b0ed 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -44,11 +44,66 @@ void nfc_state_init() void nfc_init() { - - nfc_state_init(); ams_init(); } +void process_int0(uint8_t int0) +{ + +} + +bool ams_wait_for_tx(uint32_t timeout_ms) +{ + uint32_t tstart = millis(); + while (tstart + timeout_ms > millis()) + { + uint8_t int0 = ams_read_reg(AMS_REG_INT0); + if (int0) process_int0(int0); + if (int0 & AMS_INT_TXE) + return true; + + delay(1); + } + + 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]; + *dlen = 0; + + uint32_t tstart = millis(); + while (tstart + timeout_ms > millis()) + { + uint8_t int0 = ams_read_reg(AMS_REG_INT0); + uint8_t buffer_status2 = ams_read_reg(AMS_REG_BUF2); + + if (buffer_status2 && (int0 & AMS_INT_RXE)) + { + if (buffer_status2 & AMS_BUF_INVALID) + { + printf1(TAG_NFC,"Buffer being updated!\r\n"); + } + else + { + uint8_t len = buffer_status2 & AMS_BUF_LEN_MASK; + ams_read_buffer(buf, len); + printf1(TAG_NFC,">> "); dump_hex1(TAG_NFC, buf, len); + + *dlen = MIN(32, MIN(maxlen, len)); + memcpy(data, buf, *dlen); + + return true; + } + } + + delay(1); + } + + return false; +} void nfc_write_frame(uint8_t * data, uint8_t len) { @@ -63,11 +118,6 @@ void nfc_write_frame(uint8_t * data, uint8_t len) printf1(TAG_NFC,"<< "); dump_hex1(TAG_NFC, data, len); } -void nfc_write_response_chaining(uint8_t req0, uint8_t * data, uint8_t len) -{ - nfc_write_frame(data, len); -} - bool nfc_write_response_ex(uint8_t req0, uint8_t * data, uint8_t len, uint16_t resp) { uint8_t res[32]; @@ -92,6 +142,72 @@ bool nfc_write_response(uint8_t req0, uint16_t resp) return nfc_write_response_ex(req0, NULL, 0, resp); } +void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len, uint16_t resp) +{ + uint8_t res[32 + 2]; + int sendlen = 0; + uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 3); +printf1(TAG_NFC,"-- chain \r\n"); + if (len <= 32) + { + nfc_write_response_ex(req0, data, len, resp); + } else { + do { + // transmit I block + int vlen = MIN(31, len - sendlen); + res[0] = iBlock; + memcpy(&res[1], &data[sendlen], vlen); + if (vlen + sendlen < len) + { + res[0] |= 0x10; + } else { + // here may be buffer overflow!!! + res[vlen + 1] = resp >> 8; + res[vlen + 2] = resp & 0xff; + vlen += 2; + } + + nfc_write_frame(res, vlen + 1); + sendlen += vlen; + + printf1(TAG_NFC,"-- slen: %d res0: %02x\r\n", sendlen, res[0]); + + // wait for transmit (32 bytes aprox 2,5ms) + if (!ams_wait_for_tx(10)) + { + printf1(TAG_NFC, "TX timeout. slen: %d \r\n", sendlen); + break; + } + + // receive R block + if (res[0] & 0x10) + { + uint8_t recbuf[32] = {0}; + int reclen; + if (!ams_receive_with_timeout(100, recbuf, sizeof(recbuf), &reclen)) + { + printf1(TAG_NFC, "R block RX timeout.\r\n"); + break; + } + + if (reclen != 1) + { + printf1(TAG_NFC, "R block length error. len: %d \r\n", reclen); + break; + } + + if (((recbuf[0] & 0x01) != (res[0] & 1)) && ((recbuf[0] & 0xf6) == 0xa2)) + { + printf1(TAG_NFC, "R block error. txdata: %02x rxdata: %02x \r\n", res[0], recbuf[0]); + //break; + } + } + + iBlock ^= 0x01; + } while (sendlen < len); + } +} + int answer_rats(uint8_t parameter) { @@ -226,7 +342,7 @@ void nfc_process_iblock(uint8_t * buf, int len) if (status == CTAP1_ERR_SUCCESS) { - nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length); + nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length, SW_SUCCESS); } else { nfc_write_response(buf[0], SW_INTERNAL_EXCEPTION | status); } @@ -329,6 +445,9 @@ void nfc_loop() { t1 = millis(); read_reg_block(&ams); + + process_int0(ams.regs.int0); + // if (memcmp(def,ams.buf,sizeof(AMS_DEVICE)) != 0) // { // printf1(TAG_NFC,"regs: "); dump_hex1(TAG_NFC,ams.buf,sizeof(AMS_DEVICE)); diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index d80155a..16257a7 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -67,6 +67,7 @@ typedef enum } APPLETS; #define SW_SUCCESS 0x9000 +#define SW_GET_RESPONSE 0x6100 //Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE. #define SW_COND_USE_NOT_SATISFIED 0x6985 #define SW_FILE_NOT_FOUND 0x6a82 #define SW_INS_INVALID 0x6d00 From cde6bc107a153b98b44b3e6f0a69daa572395273 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Fri, 25 Jan 2019 19:54:02 +0200 Subject: [PATCH 10/24] GetVersion works. not so clean. needs additional memory.... --- targets/stm32l432/src/nfc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index d78b0ed..3a6658f 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -342,7 +342,10 @@ void nfc_process_iblock(uint8_t * buf, int len) if (status == CTAP1_ERR_SUCCESS) { - nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length, SW_SUCCESS); + uint8_t ctapdata[1024] = {0}; + ctapdata[0] = status; + memcpy(&ctapdata[1], ctap_resp.data, ctap_resp.length); + nfc_write_response_chaining(buf[0], ctapdata, ctap_resp.length + 1, SW_SUCCESS); } else { nfc_write_response(buf[0], SW_INTERNAL_EXCEPTION | status); } From ffa42258274490f4872e0f4d0fb63dda3f9da269 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sat, 26 Jan 2019 19:07:12 +0200 Subject: [PATCH 11/24] chip have too less memory. so reusing ctap_resp buffer. --- targets/stm32l432/src/nfc.c | 42 +++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 3a6658f..e8f04ef 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -142,31 +142,33 @@ bool nfc_write_response(uint8_t req0, uint16_t resp) return nfc_write_response_ex(req0, NULL, 0, resp); } -void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len, uint16_t resp) +void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len) { uint8_t res[32 + 2]; int sendlen = 0; uint8_t iBlock = NFC_CMD_IBLOCK | (req0 & 3); -printf1(TAG_NFC,"-- chain \r\n"); - if (len <= 32) + + if (len <= 31) { - nfc_write_response_ex(req0, data, len, resp); + uint8_t res[32] = {0}; + res[0] = iBlock; + if (len && data) + memcpy(&res[1], data, len); + nfc_write_frame(res, len + 1); } else { do { // transmit I block int vlen = MIN(31, len - sendlen); res[0] = iBlock; memcpy(&res[1], &data[sendlen], vlen); + + // if not a last block if (vlen + sendlen < len) { res[0] |= 0x10; - } else { - // here may be buffer overflow!!! - res[vlen + 1] = resp >> 8; - res[vlen + 2] = resp & 0xff; - vlen += 2; } + // send data nfc_write_frame(res, vlen + 1); sendlen += vlen; @@ -179,7 +181,7 @@ printf1(TAG_NFC,"-- chain \r\n"); break; } - // receive R block + // if needs to receive R block (not a last block) if (res[0] & 0x10) { uint8_t recbuf[32] = {0}; @@ -196,10 +198,10 @@ printf1(TAG_NFC,"-- chain \r\n"); break; } - if (((recbuf[0] & 0x01) != (res[0] & 1)) && ((recbuf[0] & 0xf6) == 0xa2)) + if (((recbuf[0] & 0x01) == (res[0] & 1)) && ((recbuf[0] & 0xf6) == 0xa2)) { printf1(TAG_NFC, "R block error. txdata: %02x rxdata: %02x \r\n", res[0], recbuf[0]); - //break; + break; } } @@ -340,15 +342,19 @@ void nfc_process_iblock(uint8_t * buf, int len) status = ctap_request(payload, plen, &ctap_resp); printf1(TAG_NFC, "CTAP resp: %d len: %d\r\n", status, ctap_resp.length); - if (status == CTAP1_ERR_SUCCESS) + int ctaplen = ctap_resp.length + 3; + if (status == CTAP1_ERR_SUCCESS) { - uint8_t ctapdata[1024] = {0}; - ctapdata[0] = status; - memcpy(&ctapdata[1], ctap_resp.data, ctap_resp.length); - nfc_write_response_chaining(buf[0], ctapdata, ctap_resp.length + 1, SW_SUCCESS); + memmove(&ctap_resp.data[1], &ctap_resp.data[0], ctap_resp.length); + ctap_resp.length += 3; } else { - nfc_write_response(buf[0], SW_INTERNAL_EXCEPTION | status); + ctap_resp.length = 3; } + ctap_resp.data[0] = status; + ctap_resp.data[ctap_resp.length - 2] = SW_SUCCESS >> 8; + ctap_resp.data[ctap_resp.length - 1] = SW_SUCCESS & 0xff; + + nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length); break; case APDU_INS_READ_BINARY: From 3ba83f64079a923caa19b392a83ecf3e022e1a17 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sat, 26 Jan 2019 19:11:51 +0200 Subject: [PATCH 12/24] remove debug msg --- targets/stm32l432/src/nfc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index e8f04ef..ee8d4a0 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -171,9 +171,7 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len) // send data nfc_write_frame(res, vlen + 1); sendlen += vlen; - - printf1(TAG_NFC,"-- slen: %d res0: %02x\r\n", sendlen, res[0]); - + // wait for transmit (32 bytes aprox 2,5ms) if (!ams_wait_for_tx(10)) { From df671775ba33ef69c3caa85ac3e5dce7b8c72419 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sat, 26 Jan 2019 19:30:03 +0200 Subject: [PATCH 13/24] add some profiling. looks good. --- targets/stm32l432/src/nfc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index ee8d4a0..aee0bb9 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -239,6 +239,7 @@ int answer_rats(uint8_t parameter) memcpy(&res[3], (uint8_t *)"SoloKey tap", 11); nfc_write_frame(res, sizeof(res)); + ams_wait_for_tx(10); return 0; } @@ -268,6 +269,7 @@ void nfc_process_iblock(uint8_t * buf, int len) uint8_t plen = apdu->lc; int selected; uint8_t res[32]; + uint32_t t1; CTAP_RESPONSE ctap_resp; int status; @@ -306,7 +308,8 @@ void nfc_process_iblock(uint8_t * buf, int len) // block = !block; // NFC_STATE.block_num = block; nfc_write_response_ex(buf[0], (uint8_t *)"U2F_V2", 6, SW_SUCCESS); - } + printf1(TAG_NFC, "FIDO applet selected.\r\n"); + } else { nfc_write_response(buf[0], SW_FILE_NOT_FOUND); @@ -334,13 +337,13 @@ void nfc_process_iblock(uint8_t * buf, int len) break; case APDU_FIDO_NFCCTAP_MSG: - printf1(TAG_NFC, "FIDO2 CTAP message.\r\n"); + t1 = millis(); + printf1(TAG_NFC, "FIDO2 CTAP message. %d\r\n", t1); ctap_response_init(&ctap_resp); status = ctap_request(payload, plen, &ctap_resp); printf1(TAG_NFC, "CTAP resp: %d len: %d\r\n", status, ctap_resp.length); - int ctaplen = ctap_resp.length + 3; if (status == CTAP1_ERR_SUCCESS) { memmove(&ctap_resp.data[1], &ctap_resp.data[0], ctap_resp.length); @@ -352,7 +355,9 @@ void nfc_process_iblock(uint8_t * buf, int len) ctap_resp.data[ctap_resp.length - 2] = SW_SUCCESS >> 8; ctap_resp.data[ctap_resp.length - 1] = SW_SUCCESS & 0xff; + printf1(TAG_NFC,"CTAP processing %d (took %d)\r\n", millis(), millis() - t1); nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length); + printf1(TAG_NFC,"CTAP answered %d (took %d)\r\n", millis(), millis() - t1); break; case APDU_INS_READ_BINARY: @@ -503,6 +508,7 @@ void nfc_loop() printf1(TAG_NFC, "HLTA/Halt\r\n"); break; case NFC_CMD_RATS: + printf1(TAG_NFC,"RATS\r\n"); t1 = millis(); answer_rats(buf[1]); NFC_STATE.block_num = 1; From 6ca9f1946badb77239cd7e3e642657b12e9c9fc0 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sat, 26 Jan 2019 21:08:18 +0200 Subject: [PATCH 14/24] I block on receive --- targets/stm32l432/src/nfc.c | 55 +++++++++++++++++++++++++++++++++++-- targets/stm32l432/src/nfc.h | 5 ++-- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index aee0bb9..df0f9f3 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -407,14 +407,65 @@ void nfc_process_iblock(uint8_t * buf, int len) void nfc_process_block(uint8_t * buf, int len) { + static uint8_t ibuf[1024]; + static int ibuflen = 0; + + if (!len) + return; + if (IS_PPSS_CMD(buf[0])) { printf1(TAG_NFC, "NFC_CMD_PPSS\r\n"); } else if (IS_IBLOCK(buf[0])) { - printf1(TAG_NFC, "NFC_CMD_IBLOCK\r\n"); - nfc_process_iblock(buf, len); + if (buf[0] & 0x10) + { + printf1(TAG_NFC, "NFC_CMD_IBLOCK chaining blen=%d len=%d\r\n", ibuflen, len); + if (ibuflen + len > sizeof(ibuf)) + { + printf1(TAG_NFC, "I block memory error! must have %d but have only %d\r\n", ibuflen + len, sizeof(ibuf)); + nfc_write_response(buf[0], SW_INTERNAL_EXCEPTION); + return; + } + + printf1(TAG_NFC,"i> "); + dump_hex1(TAG_NFC, buf, len); + + if (len) + { + memcpy(&ibuf[ibuflen], &buf[1], len - 1); + ibuflen += len - 1; + } + + // send R block + uint8_t rb = NFC_CMD_RBLOCK | NFC_CMD_RBLOCK_ACK | (buf[0] & 3); + nfc_write_frame(&rb, 1); + } else { + if (ibuflen) + { + if (len) + { + memcpy(&ibuf[ibuflen], &buf[1], len - 1); + ibuflen += len - 1; + } + + memmove(&ibuf[1], ibuf, ibuflen); + ibuf[0] = buf[0]; + ibuflen++; + + printf1(TAG_NFC, "NFC_CMD_IBLOCK chaining last block. blen=%d len=%d\r\n", ibuflen, len); + + printf1(TAG_NFC,"i> "); + dump_hex1(TAG_NFC, buf, len); + + nfc_process_iblock(ibuf, ibuflen); + } else { + printf1(TAG_NFC, "NFC_CMD_IBLOCK\r\n"); + nfc_process_iblock(buf, len); + } + ibuflen = 0; + } } else if (IS_RBLOCK(buf[0])) { diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index 16257a7..c1c3042 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -37,6 +37,7 @@ typedef struct #define NFC_CMD_IBLOCK 0x00 #define IS_IBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_IBLOCK) && (((x) & 0x02) == 0x02) ) #define NFC_CMD_RBLOCK 0x80 +#define NFC_CMD_RBLOCK_ACK 0x20 #define IS_RBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_RBLOCK) && (((x) & 0x02) == 0x02) ) #define NFC_CMD_SBLOCK 0xc0 #define IS_SBLOCK(x) ( (((x) & 0xc0) == NFC_CMD_SBLOCK) && (((x) & 0x02) == 0x02) ) @@ -67,10 +68,10 @@ typedef enum } APPLETS; #define SW_SUCCESS 0x9000 -#define SW_GET_RESPONSE 0x6100 //Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE. +#define SW_GET_RESPONSE 0x6100 // Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE. #define SW_COND_USE_NOT_SATISFIED 0x6985 #define SW_FILE_NOT_FOUND 0x6a82 -#define SW_INS_INVALID 0x6d00 +#define SW_INS_INVALID 0x6d00 // Instruction code not supported or invalid #define SW_INTERNAL_EXCEPTION 0x6f00 #endif From e235402fb8b1d86528a90b2022e6582506946362 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sat, 26 Jan 2019 21:34:53 +0200 Subject: [PATCH 15/24] u2f register --- targets/stm32l432/src/app.h | 2 +- targets/stm32l432/src/nfc.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/targets/stm32l432/src/app.h b/targets/stm32l432/src/app.h index dadafc1..6afe0bb 100644 --- a/targets/stm32l432/src/app.h +++ b/targets/stm32l432/src/app.h @@ -38,7 +38,7 @@ //#define ENABLE_U2F_EXTENSIONS -// #define ENABLE_U2F +#define ENABLE_U2F #define DISABLE_CTAPHID_PING #define DISABLE_CTAPHID_WINK diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index df0f9f3..4551c28 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -326,8 +326,13 @@ void nfc_process_iblock(uint8_t * buf, int len) case APDU_FIDO_U2F_REGISTER: printf1(TAG_NFC, "U2F Register command.\r\n"); + ctap_response_init(&ctap_resp); + u2f_request(apdu, &ctap_resp); + status = ctap_resp.data[0]; + printf1(TAG_NFC, "U2F resp: %d len: %d\r\n", status, ctap_resp.length); - nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED); +// nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED); + nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length); break; case APDU_FIDO_U2F_AUTHENTICATE: From 1a656d60e4d6660533a2584994bdd169b7a0dd69 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sat, 26 Jan 2019 23:35:45 +0200 Subject: [PATCH 16/24] register works. but it needs to press a button.... --- targets/stm32l432/src/nfc.c | 22 +++++++++++++++++----- targets/stm32l432/src/nfc.h | 1 + 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 4551c28..ea2c985 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -7,6 +7,7 @@ #include "log.h" #include "util.h" #include "device.h" +#include "u2f.h" #include "ctap_errors.h" @@ -326,12 +327,23 @@ void nfc_process_iblock(uint8_t * buf, int len) case APDU_FIDO_U2F_REGISTER: printf1(TAG_NFC, "U2F Register command.\r\n"); + + if (plen != 64) + { + printf1(TAG_NFC, "U2F Register request length error. len=%d.\r\n", plen); + nfc_write_response(buf[0], SW_WRONG_LENGTH); + return; + } + + uint8_t u2fbuffer[7 + 64 + 1] = {0}; + memcpy(u2fbuffer, &buf[1], 4); + memcpy(&u2fbuffer[6], &buf[5], plen + 1); + dump_hex1(TAG_NFC,u2fbuffer, 7 + 64 + 1); + ctap_response_init(&ctap_resp); - u2f_request(apdu, &ctap_resp); - status = ctap_resp.data[0]; - printf1(TAG_NFC, "U2F resp: %d len: %d\r\n", status, ctap_resp.length); - -// nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED); + u2f_request((struct u2f_request_apdu *)u2fbuffer, &ctap_resp); + + printf1(TAG_NFC, "U2F resp len: %d\r\n", ctap_resp.length); nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length); break; diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index c1c3042..195804f 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -69,6 +69,7 @@ typedef enum #define SW_SUCCESS 0x9000 #define SW_GET_RESPONSE 0x6100 // Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE. +#define SW_WRONG_LENGTH 0x6700 #define SW_COND_USE_NOT_SATISFIED 0x6985 #define SW_FILE_NOT_FOUND 0x6a82 #define SW_INS_INVALID 0x6d00 // Instruction code not supported or invalid From a662a9a6192116c8bd3864bc7526cde43128eb2f Mon Sep 17 00:00:00 2001 From: merlokk Date: Sat, 26 Jan 2019 23:36:45 +0200 Subject: [PATCH 17/24] remove dump --- targets/stm32l432/src/nfc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index ea2c985..419808a 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -338,7 +338,6 @@ void nfc_process_iblock(uint8_t * buf, int len) uint8_t u2fbuffer[7 + 64 + 1] = {0}; memcpy(u2fbuffer, &buf[1], 4); memcpy(&u2fbuffer[6], &buf[5], plen + 1); - dump_hex1(TAG_NFC,u2fbuffer, 7 + 64 + 1); ctap_response_init(&ctap_resp); u2f_request((struct u2f_request_apdu *)u2fbuffer, &ctap_resp); From 3eddfbf8a989a5005e0d40f540fee49aff2404a0 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sat, 26 Jan 2019 23:44:51 +0200 Subject: [PATCH 18/24] u2f register works --- fido2/ctaphid.c | 2 +- fido2/u2f.c | 19 +++++++++++-------- fido2/u2f.h | 2 +- targets/stm32l432/src/nfc.c | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/fido2/ctaphid.c b/fido2/ctaphid.c index 3e6d5f1..f46b1be 100644 --- a/fido2/ctaphid.c +++ b/fido2/ctaphid.c @@ -670,7 +670,7 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw) } is_busy = 1; ctap_response_init(&ctap_resp); - u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp); + u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp, false); ctaphid_write_buffer_init(&wb); wb.cid = cid; diff --git a/fido2/u2f.c b/fido2/u2f.c index 2d79228..99c9abb 100644 --- a/fido2/u2f.c +++ b/fido2/u2f.c @@ -29,7 +29,7 @@ #include APP_CONFIG // void u2f_response_writeback(uint8_t * buf, uint8_t len); -static int16_t u2f_register(struct u2f_register_request * req); +static int16_t u2f_register(struct u2f_register_request * req, bool fromNFC); static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control); int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len); void u2f_reset_response(); @@ -37,7 +37,7 @@ void u2f_reset_response(); static CTAP_RESPONSE * _u2f_resp = NULL; -void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp) +void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp, bool fromNFC) { uint16_t rcode = 0; uint64_t t1,t2; @@ -69,7 +69,7 @@ void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp) else { t1 = millis(); - rcode = u2f_register((struct u2f_register_request*)req->payload); + rcode = u2f_register((struct u2f_register_request*)req->payload, fromNFC); t2 = millis(); printf1(TAG_TIME,"u2f_register time: %d ms\n", t2-t1); } @@ -254,7 +254,7 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c return U2F_SW_NO_ERROR; } -static int16_t u2f_register(struct u2f_register_request * req) +static int16_t u2f_register(struct u2f_register_request * req, bool fromNFC) { uint8_t i[] = {0x0,U2F_EC_FMT_UNCOMPRESSED}; @@ -266,10 +266,13 @@ static int16_t u2f_register(struct u2f_register_request * req) const uint16_t attest_size = attestation_cert_der_size; - if ( ! ctap_user_presence_test()) - { - return U2F_SW_CONDITIONS_NOT_SATISFIED; - } + if(!fromNFC) + { + if ( ! ctap_user_presence_test()) + { + return U2F_SW_CONDITIONS_NOT_SATISFIED; + } + } if ( u2f_new_keypair(&key_handle, req->app, pubkey) == -1) { diff --git a/fido2/u2f.h b/fido2/u2f.h index 94dbbb8..76c0ad0 100644 --- a/fido2/u2f.h +++ b/fido2/u2f.h @@ -111,7 +111,7 @@ struct u2f_authenticate_request // u2f_request send a U2F message to U2F protocol // @req U2F message -void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp); +void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp, bool fromNFC); int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len); diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 419808a..e3f06ac 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -340,7 +340,7 @@ void nfc_process_iblock(uint8_t * buf, int len) memcpy(&u2fbuffer[6], &buf[5], plen + 1); ctap_response_init(&ctap_resp); - u2f_request((struct u2f_request_apdu *)u2fbuffer, &ctap_resp); + u2f_request((struct u2f_request_apdu *)u2fbuffer, &ctap_resp, true); printf1(TAG_NFC, "U2F resp len: %d\r\n", ctap_resp.length); nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length); From 2feef8b043a8c00e45428c8fa52c2371ebf17712 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sat, 26 Jan 2019 23:53:13 +0200 Subject: [PATCH 19/24] add some profiling... --- targets/stm32l432/src/nfc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index e3f06ac..f8bd7fd 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -335,6 +335,7 @@ void nfc_process_iblock(uint8_t * buf, int len) return; } + t1 = millis(); uint8_t u2fbuffer[7 + 64 + 1] = {0}; memcpy(u2fbuffer, &buf[1], 4); memcpy(&u2fbuffer[6], &buf[5], plen + 1); @@ -343,8 +344,10 @@ void nfc_process_iblock(uint8_t * buf, int len) u2f_request((struct u2f_request_apdu *)u2fbuffer, &ctap_resp, true); 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); nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length); - break; + printf1(TAG_NFC,"U2F Register answered %d (took %d)\r\n", millis(), millis() - t1); + break; case APDU_FIDO_U2F_AUTHENTICATE: printf1(TAG_NFC, "U2F Authenticate command.\r\n"); From 1857482617051cd48c439278cfd1cfb9dede93e3 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sun, 27 Jan 2019 00:01:04 +0200 Subject: [PATCH 20/24] add some len check --- targets/stm32l432/src/nfc.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index f8bd7fd..5139218 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -352,6 +352,13 @@ void nfc_process_iblock(uint8_t * buf, int len) case APDU_FIDO_U2F_AUTHENTICATE: printf1(TAG_NFC, "U2F Authenticate command.\r\n"); + if (plen != 1 + 64 + 1 + buf[65]) + { + printf1(TAG_NFC, "U2F Authenticate request length error. len=%d keyhlen=%d.\r\n", plen, buf[65]); + nfc_write_response(buf[0], SW_WRONG_LENGTH); + return; + } + nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED); break; From 2049020b927b2770a4624cd1372d778a04ebb34e Mon Sep 17 00:00:00 2001 From: merlokk Date: Sun, 27 Jan 2019 11:44:33 +0200 Subject: [PATCH 21/24] refactoring --- fido2/apdu.h | 30 ++++++++++++++++++++++++++++++ fido2/ctaphid.c | 2 +- fido2/main.c | 2 +- fido2/u2f.c | 25 +++++++++++++++++++++---- fido2/u2f.h | 9 +++++++-- targets/stm32l432/Makefile | 2 +- targets/stm32l432/src/nfc.c | 11 +++-------- targets/stm32l432/src/nfc.h | 25 +------------------------ 8 files changed, 65 insertions(+), 41 deletions(-) create mode 100644 fido2/apdu.h diff --git a/fido2/apdu.h b/fido2/apdu.h new file mode 100644 index 0000000..d9687c7 --- /dev/null +++ b/fido2/apdu.h @@ -0,0 +1,30 @@ +#ifndef _APDU_H_ +#define _APDU_H_ + +#include + +typedef struct +{ + uint8_t cla; + uint8_t ins; + uint8_t p1; + uint8_t p2; + uint8_t lc; +} __attribute__((packed)) APDU_HEADER; + +#define APDU_FIDO_U2F_REGISTER 0x01 +#define APDU_FIDO_U2F_AUTHENTICATE 0x02 +#define APDU_FIDO_U2F_VERSION 0x03 +#define APDU_FIDO_NFCCTAP_MSG 0x10 +#define APDU_INS_SELECT 0xA4 +#define APDU_INS_READ_BINARY 0xB0 + +#define SW_SUCCESS 0x9000 +#define SW_GET_RESPONSE 0x6100 // Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE. +#define SW_WRONG_LENGTH 0x6700 +#define SW_COND_USE_NOT_SATISFIED 0x6985 +#define SW_FILE_NOT_FOUND 0x6a82 +#define SW_INS_INVALID 0x6d00 // Instruction code not supported or invalid +#define SW_INTERNAL_EXCEPTION 0x6f00 + +#endif //_APDU_H_ diff --git a/fido2/ctaphid.c b/fido2/ctaphid.c index f46b1be..3e6d5f1 100644 --- a/fido2/ctaphid.c +++ b/fido2/ctaphid.c @@ -670,7 +670,7 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw) } is_busy = 1; ctap_response_init(&ctap_resp); - u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp, false); + u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp); ctaphid_write_buffer_init(&wb); wb.cid = cid; diff --git a/fido2/main.c b/fido2/main.c index 51e15ec..35c4c6f 100644 --- a/fido2/main.c +++ b/fido2/main.c @@ -50,7 +50,7 @@ int main(int argc, char * argv[]) // TAG_CP | // TAG_CTAP| // TAG_HID| - /*TAG_U2F|*/ + //TAG_U2F| // TAG_PARSE | // TAG_TIME| // TAG_DUMP| diff --git a/fido2/u2f.c b/fido2/u2f.c index 99c9abb..eb24ae5 100644 --- a/fido2/u2f.c +++ b/fido2/u2f.c @@ -26,6 +26,7 @@ #include "log.h" #include "device.h" #include "wallet.h" +#include "apdu.h" #include APP_CONFIG // void u2f_response_writeback(uint8_t * buf, uint8_t len); @@ -37,13 +38,13 @@ void u2f_reset_response(); static CTAP_RESPONSE * _u2f_resp = NULL; -void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp, bool fromNFC) +void u2f_request_ex(APDU_HEADER *req, uint8_t *payload, uint32_t len, CTAP_RESPONSE * resp, bool fromNFC) { uint16_t rcode = 0; uint64_t t1,t2; - uint32_t len = ((req->LC3) | ((uint32_t)req->LC2 << 8) | ((uint32_t)req->LC1 << 16)); uint8_t byte; + ctap_response_init(resp); u2f_set_writeback_buffer(resp); if (req->cla != 0) @@ -69,7 +70,7 @@ void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp, bool fromNF else { t1 = millis(); - rcode = u2f_register((struct u2f_register_request*)req->payload, fromNFC); + rcode = u2f_register((struct u2f_register_request*)payload, fromNFC); t2 = millis(); printf1(TAG_TIME,"u2f_register time: %d ms\n", t2-t1); } @@ -77,7 +78,7 @@ void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp, bool fromNF case U2F_AUTHENTICATE: printf1(TAG_U2F, "U2F_AUTHENTICATE\n"); t1 = millis(); - rcode = u2f_authenticate((struct u2f_authenticate_request*)req->payload, req->p1); + rcode = u2f_authenticate((struct u2f_authenticate_request*)payload, req->p1); t2 = millis(); printf1(TAG_TIME,"u2f_authenticate time: %d ms\n", t2-t1); break; @@ -120,6 +121,22 @@ end: printf1(TAG_U2F,"u2f resp: "); dump_hex1(TAG_U2F, _u2f_resp->data, _u2f_resp->length); } +void u2f_request_nfc(uint8_t * req, int len, CTAP_RESPONSE * resp) +{ + if (len < 5 || !req) + return; + + uint32_t alen = req[4]; + + u2f_request_ex((APDU_HEADER *)req, &req[5], alen, resp, true); +} + +void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp) +{ + uint32_t len = ((req->LC3) | ((uint32_t)req->LC2 << 8) | ((uint32_t)req->LC1 << 16)); + + u2f_request_ex((APDU_HEADER *)req, &req[7], len, resp, false); +} int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len) { diff --git a/fido2/u2f.h b/fido2/u2f.h index 76c0ad0..3f4f689 100644 --- a/fido2/u2f.h +++ b/fido2/u2f.h @@ -110,8 +110,13 @@ struct u2f_authenticate_request }; // u2f_request send a U2F message to U2F protocol -// @req U2F message -void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp, bool fromNFC); +// @req U2F message +void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp); + +// u2f_request send a U2F message to NFC protocol +// @req data with iso7816 apdu message +// @len data length +void u2f_request_nfc(uint8_t * req, int len, CTAP_RESPONSE * resp); int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len); diff --git a/targets/stm32l432/Makefile b/targets/stm32l432/Makefile index 017998f..9df352c 100644 --- a/targets/stm32l432/Makefile +++ b/targets/stm32l432/Makefile @@ -8,7 +8,7 @@ all: $(MAKE) -f application.mk -j8 solo.hex PREFIX=$(PREFIX) DEBUG=$(DEBUG) EXTRA_DEFINES='-DFLASH_ROP=1' all-hacker: - $(MAKE) -f application.mk -j8 solo.hex PREFIX=$(PREFIX) DEBUG=$(DEBUG) EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0' + $(MAKE) -f application.mk solo.hex PREFIX=$(PREFIX) DEBUG=$(DEBUG) EXTRA_DEFINES='-DSOLO_HACKER -DFLASH_ROP=0' all-locked: $(MAKE) -f application.mk -j8 solo.hex PREFIX=$(PREFIX) EXTRA_DEFINES='-DFLASH_ROP=2' diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 5139218..1e2bfbf 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -336,12 +336,7 @@ void nfc_process_iblock(uint8_t * buf, int len) } t1 = millis(); - uint8_t u2fbuffer[7 + 64 + 1] = {0}; - memcpy(u2fbuffer, &buf[1], 4); - memcpy(&u2fbuffer[6], &buf[5], plen + 1); - - ctap_response_init(&ctap_resp); - u2f_request((struct u2f_request_apdu *)u2fbuffer, &ctap_resp, true); + u2f_request_nfc(&buf[1], len, &ctap_resp); 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); @@ -356,10 +351,10 @@ void nfc_process_iblock(uint8_t * buf, int len) { printf1(TAG_NFC, "U2F Authenticate request length error. len=%d keyhlen=%d.\r\n", plen, buf[65]); nfc_write_response(buf[0], SW_WRONG_LENGTH); - return; + //return; } - nfc_write_response(buf[0], SW_COND_USE_NOT_SATISFIED); + u2f_request_nfc(&buf[1], len, &ctap_resp); break; case APDU_FIDO_NFCCTAP_MSG: diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index 195804f..0079ea4 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -2,6 +2,7 @@ #define _NFC_H_ #include +#include "apdu.h" void nfc_loop(); void nfc_init(); @@ -18,15 +19,6 @@ typedef struct uint8_t tlv[8]; } __attribute__((packed)) CAPABILITY_CONTAINER; -typedef struct -{ - uint8_t cla; - uint8_t ins; - uint8_t p1; - uint8_t p2; - uint8_t lc; -} __attribute__((packed)) APDU_HEADER; - #define NFC_CMD_REQA 0x26 #define NFC_CMD_WUPA 0x52 #define NFC_CMD_HLTA 0x50 @@ -45,13 +37,6 @@ typedef struct #define NFC_SBLOCK_DESELECT 0x32 #define NFC_SBLOCK_WTX 0xf2 -#define APDU_FIDO_U2F_REGISTER 0x01 -#define APDU_FIDO_U2F_AUTHENTICATE 0x02 -#define APDU_FIDO_U2F_VERSION 0x03 -#define APDU_FIDO_NFCCTAP_MSG 0x10 -#define APDU_INS_SELECT 0xA4 -#define APDU_INS_READ_BINARY 0xB0 - #define AID_NDEF_TYPE_4 "\xD2\x76\x00\x00\x85\x01\x01" #define AID_NDEF_MIFARE_TYPE_4 "\xD2\x76\x00\x00\x85\x01\x00" #define AID_CAPABILITY_CONTAINER "\xE1\x03" @@ -67,12 +52,4 @@ typedef enum APP_FIDO, } APPLETS; -#define SW_SUCCESS 0x9000 -#define SW_GET_RESPONSE 0x6100 // Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE. -#define SW_WRONG_LENGTH 0x6700 -#define SW_COND_USE_NOT_SATISFIED 0x6985 -#define SW_FILE_NOT_FOUND 0x6a82 -#define SW_INS_INVALID 0x6d00 // Instruction code not supported or invalid -#define SW_INTERNAL_EXCEPTION 0x6f00 - #endif From 4c941997b429a67982b9e60210d263c2d3354db2 Mon Sep 17 00:00:00 2001 From: merlokk Date: Sun, 27 Jan 2019 23:35:20 +0200 Subject: [PATCH 22/24] check as3956 on startup --- fido2/main.c | 2 -- fido2/u2f.c | 2 +- targets/stm32l432/src/ams.c | 21 ++++++++++++++------- targets/stm32l432/src/ams.h | 15 +++++++++++++-- targets/stm32l432/src/device.c | 10 +++++++++- targets/stm32l432/src/nfc.c | 5 +++-- targets/stm32l432/src/nfc.h | 3 ++- 7 files changed, 42 insertions(+), 16 deletions(-) diff --git a/fido2/main.c b/fido2/main.c index 35c4c6f..3849633 100644 --- a/fido2/main.c +++ b/fido2/main.c @@ -65,8 +65,6 @@ int main(int argc, char * argv[]) usbhid_init(); printf1(TAG_GEN,"init usb\n"); - nfc_init(); - ctaphid_init(); printf1(TAG_GEN,"init ctaphid\n"); diff --git a/fido2/u2f.c b/fido2/u2f.c index eb24ae5..6d5e6eb 100644 --- a/fido2/u2f.c +++ b/fido2/u2f.c @@ -135,7 +135,7 @@ void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp) { uint32_t len = ((req->LC3) | ((uint32_t)req->LC2 << 8) | ((uint32_t)req->LC1 << 16)); - u2f_request_ex((APDU_HEADER *)req, &req[7], len, resp, false); + u2f_request_ex((APDU_HEADER *)req, req->payload, len, resp, false); } int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len) diff --git a/targets/stm32l432/src/ams.c b/targets/stm32l432/src/ams.c index 1b2c87a..a342513 100644 --- a/targets/stm32l432/src/ams.c +++ b/targets/stm32l432/src/ams.c @@ -28,7 +28,7 @@ static void wait_for_rx() } -static void ams_print_device(AMS_DEVICE * dev) +void ams_print_device(AMS_DEVICE * dev) { printf1(TAG_NFC, "AMS_DEVICE:\r\n"); printf1(TAG_NFC, " io_conf: %02x\r\n",dev->regs.io_conf); @@ -252,7 +252,7 @@ void ams_print_int1(uint8_t int0) printf1(tag,"\r\n"); } -void ams_init() +bool ams_init() { uint8_t block[4]; @@ -273,13 +273,19 @@ void ams_init() ams_write_command(AMS_CMD_DEFAULT); ams_write_command(AMS_CMD_CLEAR_BUFFER); + // check connection + uint8_t productType = ams_read_reg(AMS_REG_PRODUCT_TYPE); + if (!productType) + { + printf1(TAG_NFC,"Have no product type. Connection error."); + return false; + } + printf1(TAG_NFC,"Product type 0x%02x.", productType); + // enable tunneling mode and RF configuration ams_write_reg(AMS_REG_IC_CONF2, AMS_RFCFG_EN | AMS_TUN_MOD); - ams_read_eeprom_block(0, block); - printf1(TAG_NFC,"UID: "); dump_hex1(TAG_NFC,block,4); - - ams_read_eeprom_block(0, block); + ams_read_eeprom_block(AMS_CONFIG_UID_ADDR, block); printf1(TAG_NFC,"UID: "); dump_hex1(TAG_NFC,block,4); ams_read_eeprom_block(AMS_CONFIG_BLOCK0_ADDR, block); @@ -336,5 +342,6 @@ void ams_init() ams_read_eeprom_block(0x7F, block); printf1(TAG_NFC,"conf1: "); dump_hex1(TAG_NFC,block,4); } - + + return true; } diff --git a/targets/stm32l432/src/ams.h b/targets/stm32l432/src/ams.h index 361cb0d..ad3b94f 100644 --- a/targets/stm32l432/src/ams.h +++ b/targets/stm32l432/src/ams.h @@ -1,8 +1,12 @@ +// AS3956 interface +// https://ams.com/as3956 +// https://ams.com/documents/20143/36005/AS3956_DS000546_7-00.pdf + #ifndef _AMS_H_ #define _AMS_H_ #include -#include +#include #include "stm32l4xx_ll_gpio.h" @@ -35,7 +39,7 @@ typedef union #define SELECT() LL_GPIO_ResetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN) #define UNSELECT() LL_GPIO_SetOutputPin(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN) -void ams_init(); +bool ams_init(); void ams_read_buffer(uint8_t * data, int len); void ams_write_buffer(uint8_t * data, int len); @@ -92,7 +96,14 @@ void ams_write_reg(uint8_t addr, uint8_t tx); #define AMS_REG_BUF2 0x0c #define AMS_BUF_LEN_MASK 0x1f #define AMS_BUF_INVALID 0x80 +#define AMS_REG_BUF1 0x0d +// ... // +#define AMS_REG_PRODUCT_TYPE 0x1c +#define AMS_REG_PRODUCT_SUBTYPE 0x1d +#define AMS_REG_VERSION_MAJOR 0x1e +#define AMS_REG_VERSION_MINOR 0x1f +#define AMS_CONFIG_UID_ADDR 0x00 #define AMS_CONFIG_BLOCK0_ADDR 0x7e #define AMS_CONFIG_BLOCK1_ADDR 0x7f diff --git a/targets/stm32l432/src/device.c b/targets/stm32l432/src/device.c index 33d9113..b3fd58f 100644 --- a/targets/stm32l432/src/device.c +++ b/targets/stm32l432/src/device.c @@ -48,6 +48,7 @@ uint32_t __90_ms = 0; uint32_t __device_status = 0; uint32_t __last_update = 0; extern PCD_HandleTypeDef hpcd; +bool haveNFC = false; #define IS_BUTTON_PRESSED() (0 == (LL_GPIO_ReadInputPort(SOLO_BUTTON_PORT) & SOLO_BUTTON_PIN)) @@ -118,6 +119,12 @@ void device_init() #else flash_option_bytes_init(0); #endif + printf1(TAG_GEN,"init nfc\n"); + haveNFC = nfc_init(); + if (haveNFC) + printf1(TAG_GEN,"NFC OK.\n"); + else + printf1(TAG_GEN,"NFC not found.\n"); #endif printf1(TAG_GEN,"hello solo\r\n"); @@ -397,7 +404,8 @@ void device_manage() } #endif #ifndef IS_BOOTLOADER - nfc_loop(); + if(haveNFC) + nfc_loop(); #endif } diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 1e2bfbf..75ba0bf 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -43,11 +43,12 @@ void nfc_state_init() NFC_STATE.block_num = 1; } -void nfc_init() +bool nfc_init() { nfc_state_init(); - ams_init(); + return ams_init(); } + void process_int0(uint8_t int0) { diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index 0079ea4..b425b28 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -2,10 +2,11 @@ #define _NFC_H_ #include +#include #include "apdu.h" void nfc_loop(); -void nfc_init(); +bool nfc_init(); typedef struct { From f24058d2e8e140c4c8a2195d27900828fb28bd62 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Sun, 27 Jan 2019 23:58:35 +0200 Subject: [PATCH 23/24] u2f authenticate wrong length fix --- targets/stm32l432/src/nfc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 75ba0bf..5d9feaf 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -348,11 +348,12 @@ void nfc_process_iblock(uint8_t * buf, int len) case APDU_FIDO_U2F_AUTHENTICATE: printf1(TAG_NFC, "U2F Authenticate command.\r\n"); - if (plen != 1 + 64 + 1 + buf[65]) + if (plen != 64 + 1 + buf[6 + 64]) { - printf1(TAG_NFC, "U2F Authenticate request length error. len=%d keyhlen=%d.\r\n", plen, buf[65]); + delay(5); + printf1(TAG_NFC, "U2F Authenticate request length error. len=%d keyhlen=%d.\r\n", plen, buf[6 + 64]); nfc_write_response(buf[0], SW_WRONG_LENGTH); - //return; + return; } u2f_request_nfc(&buf[1], len, &ctap_resp); From cce25b2a1c04e882c59f43e466bb8d0bc1d08dd2 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 28 Jan 2019 00:04:17 +0200 Subject: [PATCH 24/24] u2f auth works --- fido2/u2f.c | 17 ++++++++++------- targets/stm32l432/src/nfc.c | 6 ++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/fido2/u2f.c b/fido2/u2f.c index 6d5e6eb..edc4451 100644 --- a/fido2/u2f.c +++ b/fido2/u2f.c @@ -31,7 +31,7 @@ // void u2f_response_writeback(uint8_t * buf, uint8_t len); static int16_t u2f_register(struct u2f_register_request * req, bool fromNFC); -static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control); +static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control, bool fromNFC); int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len); void u2f_reset_response(); @@ -78,7 +78,7 @@ void u2f_request_ex(APDU_HEADER *req, uint8_t *payload, uint32_t len, CTAP_RESPO case U2F_AUTHENTICATE: printf1(TAG_U2F, "U2F_AUTHENTICATE\n"); t1 = millis(); - rcode = u2f_authenticate((struct u2f_authenticate_request*)payload, req->p1); + rcode = u2f_authenticate((struct u2f_authenticate_request*)payload, req->p1, fromNFC); t2 = millis(); printf1(TAG_TIME,"u2f_authenticate time: %d ms\n", t2-t1); break; @@ -213,7 +213,7 @@ static int8_t u2f_appid_eq(struct u2f_key_handle * kh, uint8_t * appid) -static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control) +static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control, bool fromNFC) { uint8_t up = 1; @@ -245,10 +245,13 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c - if (ctap_user_presence_test() == 0) - { - return U2F_SW_CONDITIONS_NOT_SATISFIED; - } + if(!fromNFC) + { + if (ctap_user_presence_test() == 0) + { + return U2F_SW_CONDITIONS_NOT_SATISFIED; + } + } count = ctap_atomic_count(0); diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index 5d9feaf..0b4cf5c 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -356,7 +356,13 @@ void nfc_process_iblock(uint8_t * buf, int len) return; } + t1 = millis(); u2f_request_nfc(&buf[1], len, &ctap_resp); + + 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); + nfc_write_response_chaining(buf[0], ctap_resp.data, ctap_resp.length); + printf1(TAG_NFC,"U2F Authenticate answered %d (took %d)\r\n", millis(), millis() - t1); break; case APDU_FIDO_NFCCTAP_MSG: