diff --git a/fido2/ctap.c b/fido2/ctap.c index 6b644f3..b84f9b7 100644 --- a/fido2/ctap.c +++ b/fido2/ctap.c @@ -324,7 +324,7 @@ static int is_matching_rk(CTAP_residentKey * rk, CTAP_residentKey * rk2) } -static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * auth_data_buf, int len, CTAP_userEntity * user, uint8_t credtype, int32_t algtype, int32_t * sz, int store) +static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * auth_data_buf, int len, CTAP_userEntity * user, uint8_t credtype, int32_t algtype, int32_t * sz, int store, bool fromNFC) { CborEncoder cose_key; int auth_data_sz, ret; @@ -350,8 +350,13 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au count = auth_data_update_count(&authData->head); device_set_status(CTAPHID_STATUS_UPNEEDED); - int but = ctap_user_presence_test(); - + // if NFC - not need to click a button + int but = 1; + if(!fromNFC) + { + but = ctap_user_presence_test(); + } + if (!but) { return CTAP2_ERR_OPERATION_DENIED; @@ -551,7 +556,7 @@ int ctap_authenticate_credential(struct rpId * rp, CTAP_credentialDescriptor * d -uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int length) +uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int length, bool fromNFC) { CTAP_makeCredential MC; int ret, i; @@ -621,7 +626,7 @@ uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int lengt int32_t auth_data_sz; ret = ctap_make_auth_data(&MC.rp, &map, auth_data_buf, sizeof(auth_data_buf), - &MC.user, MC.publicKeyCredentialType, MC.COSEAlgorithmIdentifier, &auth_data_sz, MC.rk); + &MC.user, MC.publicKeyCredentialType, MC.COSEAlgorithmIdentifier, &auth_data_sz, MC.rk, fromNFC); check_retr(ret); @@ -940,7 +945,7 @@ uint8_t ctap_get_next_assertion(CborEncoder * encoder) return 0; } -uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length) +uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length, bool fromNFC) { CTAP_getAssertion GA; uint8_t auth_data_buf[sizeof(CTAP_authDataHeader)]; @@ -992,7 +997,7 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length) ret = cbor_encoder_create_map(encoder, &map, map_size); check_ret(ret); - ret = ctap_make_auth_data(&GA.rp, &map, auth_data_buf, sizeof(auth_data_buf), NULL, 0,0,NULL, 0); + ret = ctap_make_auth_data(&GA.rp, &map, auth_data_buf, sizeof(auth_data_buf), NULL, 0,0,NULL, 0, fromNFC); check_retr(ret); /*for (int j = 0; j < GA.credLen; j++)*/ @@ -1358,7 +1363,7 @@ void ctap_response_init(CTAP_RESPONSE * resp) } -uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) +uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp, bool fromNFC) { CborEncoder encoder; uint8_t status = 0; @@ -1398,7 +1403,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) device_set_status(CTAPHID_STATUS_PROCESSING); printf1(TAG_CTAP,"CTAP_MAKE_CREDENTIAL\n"); t1 = millis(); - status = ctap_make_credential(&encoder, pkt_raw, length); + status = ctap_make_credential(&encoder, pkt_raw, length, fromNFC); t2 = millis(); printf1(TAG_TIME,"make_credential time: %d ms\n", t2-t1); @@ -1410,7 +1415,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) device_set_status(CTAPHID_STATUS_PROCESSING); printf1(TAG_CTAP,"CTAP_GET_ASSERTION\n"); t1 = millis(); - status = ctap_get_assertion(&encoder, pkt_raw, length); + status = ctap_get_assertion(&encoder, pkt_raw, length, fromNFC); t2 = millis(); printf1(TAG_TIME,"get_assertion time: %d ms\n", t2-t1); diff --git a/fido2/ctap.h b/fido2/ctap.h index 7448b44..2df795b 100644 --- a/fido2/ctap.h +++ b/fido2/ctap.h @@ -275,7 +275,7 @@ typedef struct void ctap_response_init(CTAP_RESPONSE * resp); -uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp); +uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp, bool fromNFC); // Encodes R,S signature to 2 der sequence of two integers. Sigder must be at least 72 bytes. // @return length of der signature diff --git a/fido2/log.c b/fido2/log.c index 01514db..e070a23 100644 --- a/fido2/log.c +++ b/fido2/log.c @@ -63,6 +63,7 @@ struct logtag tagtable[] = { {TAG_BOOT,"BOOT"}, {TAG_EXT,"EXT"}, {TAG_NFC,"NFC"}, + {TAG_NFC_APDU, "NAPDU"}, }; diff --git a/fido2/log.h b/fido2/log.h index a6f5097..ea056ad 100644 --- a/fido2/log.h +++ b/fido2/log.h @@ -38,29 +38,30 @@ void set_logging_tag(uint32_t tag); typedef enum { - TAG_GEN = (1 << 0), - TAG_MC = (1 << 1), - TAG_GA = (1 << 2), - TAG_CP = (1 << 3), - TAG_ERR = (1 << 4), - TAG_PARSE= (1 << 5), - TAG_CTAP = (1 << 6), - TAG_U2F = (1 << 7), - TAG_DUMP = (1 << 8), - TAG_GREEN = (1 << 9), - TAG_RED= (1 << 10), - TAG_TIME= (1 << 11), - TAG_HID = (1 << 12), - TAG_USB = (1 << 13), - TAG_WALLET = (1 << 14), - TAG_STOR = (1 << 15), - TAG_DUMP2 = (1 << 16), - TAG_BOOT = (1 << 17), - TAG_EXT = (1 << 17), - TAG_NFC = (1 << 18), + TAG_GEN = (1 << 0), + TAG_MC = (1 << 1), + TAG_GA = (1 << 2), + TAG_CP = (1 << 3), + TAG_ERR = (1 << 4), + TAG_PARSE = (1 << 5), + TAG_CTAP = (1 << 6), + TAG_U2F = (1 << 7), + TAG_DUMP = (1 << 8), + TAG_GREEN = (1 << 9), + TAG_RED = (1 << 10), + TAG_TIME = (1 << 11), + TAG_HID = (1 << 12), + TAG_USB = (1 << 13), + TAG_WALLET = (1 << 14), + TAG_STOR = (1 << 15), + TAG_DUMP2 = (1 << 16), + TAG_BOOT = (1 << 17), + TAG_EXT = (1 << 18), + TAG_NFC = (1 << 19), + TAG_NFC_APDU = (1 << 20), - TAG_NO_TAG = (1UL<<30), - TAG_FILENO = (1UL<<31) + TAG_NO_TAG = (1UL << 30), + TAG_FILENO = (1UL << 31) } LOG_TAG; #if DEBUG_LEVEL > 0 diff --git a/fido2/main.c b/fido2/main.c index 27b68a4..ad34ed8 100644 --- a/fido2/main.c +++ b/fido2/main.c @@ -40,24 +40,25 @@ int main(int argc, char * argv[]) uint32_t t1 = 0; set_logging_mask( - /*0*/ - TAG_GEN| - // TAG_MC | - // TAG_GA | - // TAG_WALLET | - TAG_STOR | - TAG_NFC | - // TAG_CP | - // TAG_CTAP| - // TAG_HID| - //TAG_U2F| - // TAG_PARSE | - // TAG_TIME| - // TAG_DUMP| - TAG_GREEN| - TAG_RED| - TAG_ERR - ); + /*0*/ + //TAG_GEN| + //TAG_MC | + //TAG_GA | + //TAG_WALLET | + TAG_STOR | + //TAG_NFC_APDU | + TAG_NFC | + //TAG_CP | + //TAG_CTAP| + //TAG_HID| + //TAG_U2F| + //TAG_PARSE | + //TAG_TIME| + //TAG_DUMP| + TAG_GREEN| + TAG_RED| + TAG_ERR + ); device_init(); // printf1(TAG_GEN,"init device\n"); diff --git a/targets/stm32l432/src/ams.c b/targets/stm32l432/src/ams.c index b0ab7d0..e218f34 100644 --- a/targets/stm32l432/src/ams.c +++ b/targets/stm32l432/src/ams.c @@ -268,7 +268,6 @@ void ams_print_int1(uint8_t int0) bool ams_init() { - uint8_t block[4]; LL_GPIO_SetPinMode(SOLO_AMS_CS_PORT,SOLO_AMS_CS_PIN,LL_GPIO_MODE_OUTPUT); @@ -283,25 +282,23 @@ bool ams_init() SELECT(); // delay(10); - // - if (0) - { - 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_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 != 0x14) + { + printf1(TAG_NFC, "Have wrong product type [0x%02x]. AMS3956 connection error.\n", productType); + return false; + } + printf1(TAG_NFC,"AMS3956 product type 0x%02x.\n", productType); + + // enable tunneling mode and RF configuration + ams_write_reg(AMS_REG_IC_CONF2, AMS_RFCFG_EN | AMS_TUN_MOD); + if (1) + { ams_read_eeprom_block(AMS_CONFIG_UID_ADDR, block); printf1(TAG_NFC,"UID: "); dump_hex1(TAG_NFC,block,4); diff --git a/targets/stm32l432/src/device.c b/targets/stm32l432/src/device.c index b0002ad..6d86a1d 100644 --- a/targets/stm32l432/src/device.c +++ b/targets/stm32l432/src/device.c @@ -70,6 +70,12 @@ void TIM6_DAC_IRQHandler() ctaphid_update_status(__device_status); } } + + // NFC sending WTX if needs + if (haveNFC) + { + WTX_timer_exec(); + } } // Global USB interrupt handler diff --git a/targets/stm32l432/src/nfc.c b/targets/stm32l432/src/nfc.c index a42b156..1ef554c 100644 --- a/targets/stm32l432/src/nfc.c +++ b/targets/stm32l432/src/nfc.c @@ -102,7 +102,8 @@ bool ams_receive_with_timeout(uint32_t timeout_ms, uint8_t * data, int maxlen, i { uint8_t len = buffer_status2 & AMS_BUF_LEN_MASK; ams_read_buffer(buf, len); - printf1(TAG_NFC,">> "); dump_hex1(TAG_NFC, buf, len); + printf1(TAG_NFC_APDU, ">> "); + dump_hex1(TAG_NFC_APDU, buf, len); *dlen = MIN(32, MIN(maxlen, len)); memcpy(data, buf, *dlen); @@ -127,7 +128,8 @@ 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); + printf1(TAG_NFC_APDU, "<< "); + dump_hex1(TAG_NFC_APDU, data, len); } bool nfc_write_response_ex(uint8_t req0, uint8_t * data, uint8_t len, uint16_t resp) @@ -226,43 +228,61 @@ void nfc_write_response_chaining(uint8_t req0, uint8_t * data, int len) // 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; +static uint32_t WTX_timer; + +bool WTX_process(int read_timeout); void WTX_clear() { WTX_sent = false; WTX_fail = false; + WTX_timer = 0; } bool WTX_on(int WTX_time) { WTX_clear(); - - // TODO: start interrupt - + WTX_timer = millis(); + return true; } -bool WTX_process(int read_timeout); - bool WTX_off() { - // TODO: stop interrupt - + WTX_timer = 0; + // read data if we sent WTX if (WTX_sent) { - if (!WTX_process(10)) + if (!WTX_process(100)) + { + printf1(TAG_NFC, "WTX-off get last WTX error\n"); return false; + } } if (WTX_fail) + { + printf1(TAG_NFC, "WTX-off fail\n"); return false; - + } + + WTX_clear(); return true; } +void WTX_timer_exec() +{ + // condition: (timer on) or (not expired[300ms]) + if ((WTX_timer <= 0) || WTX_timer + 300 > millis()) + return; + + WTX_process(10); + WTX_timer = millis(); +} + // executes twice a period. 1st for send WTX, 2nd for check the result -// read timeout must be 0 to call from int +// read timeout must be 10 ms to call from interrupt bool WTX_process(int read_timeout) { uint8_t wtx[] = {0xf2, 0x01}; @@ -279,7 +299,7 @@ bool WTX_process(int read_timeout) { uint8_t data[32]; int len; - if (ams_receive_with_timeout(read_timeout, data, sizeof(data), &len)) + if (!ams_receive_with_timeout(read_timeout, data, sizeof(data), &len)) { WTX_fail = true; return false; @@ -380,7 +400,7 @@ void nfc_process_iblock(uint8_t * buf, int len) CTAP_RESPONSE ctap_resp; int status; - printf1(TAG_NFC,">> "); + printf1(TAG_NFC,"Iblock: "); dump_hex1(TAG_NFC, buf, len); // TODO this needs to be organized better @@ -412,6 +432,7 @@ void nfc_process_iblock(uint8_t * buf, int len) // block = buf[0] & 1; // block = NFC_STATE.block_num; // block = !block; + // NFC_STATE.block_num = 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"); @@ -506,10 +527,11 @@ void nfc_process_iblock(uint8_t * buf, int len) WTX_on(WTX_TIME_DEFAULT); ctap_response_init(&ctap_resp); - status = ctap_request(payload, plen, &ctap_resp); + status = ctap_request(payload, plen, &ctap_resp, true); if (!WTX_off()) return; - printf1(TAG_NFC, "CTAP resp: %d len: %d\r\n", status, ctap_resp.length); + + printf1(TAG_NFC, "CTAP resp: 0x%02� len: %d\r\n", status, ctap_resp.length); if (status == CTAP1_ERR_SUCCESS) { @@ -591,7 +613,7 @@ void nfc_process_block(uint8_t * buf, int len) { if (buf[0] & 0x10) { - printf1(TAG_NFC, "NFC_CMD_IBLOCK chaining blen=%d len=%d\r\n", ibuflen, len); + printf1(TAG_NFC_APDU, "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)); @@ -599,8 +621,8 @@ void nfc_process_block(uint8_t * buf, int len) return; } - printf1(TAG_NFC,"i> "); - dump_hex1(TAG_NFC, buf, len); + printf1(TAG_NFC_APDU,"i> "); + dump_hex1(TAG_NFC_APDU, buf, len); if (len) { @@ -624,10 +646,10 @@ void nfc_process_block(uint8_t * buf, int len) 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_APDU, "NFC_CMD_IBLOCK chaining last block. blen=%d len=%d\r\n", ibuflen, len); - printf1(TAG_NFC,"i> "); - dump_hex1(TAG_NFC, buf, len); + printf1(TAG_NFC_APDU,"i> "); + dump_hex1(TAG_NFC_APDU, buf, len); nfc_process_iblock(ibuf, ibuflen); } else { @@ -657,7 +679,7 @@ void nfc_process_block(uint8_t * buf, int len) } else { - printf1(TAG_NFC, "NFC_CMD_SBLOCK, Unknown\r\n"); + printf1(TAG_NFC, "NFC_CMD_SBLOCK, Unknown. len[%d]\r\n", len); } dump_hex1(TAG_NFC, buf, len); } diff --git a/targets/stm32l432/src/nfc.h b/targets/stm32l432/src/nfc.h index 4859570..2388018 100644 --- a/targets/stm32l432/src/nfc.h +++ b/targets/stm32l432/src/nfc.h @@ -57,4 +57,6 @@ typedef enum APP_FIDO, } APPLETS; +void WTX_timer_exec(); + #endif diff --git a/targets/stm32l432/src/redirect.c b/targets/stm32l432/src/redirect.c index 12e47b5..ff03c1e 100644 --- a/targets/stm32l432/src/redirect.c +++ b/targets/stm32l432/src/redirect.c @@ -42,11 +42,20 @@ void _putchar(char c) int _write (int fd, const void *buf, long int len) { uint8_t * data = (uint8_t *) buf; + static uint8_t logbuf[1000] = {0}; + static int logbuflen = 0; + if (logbuflen + len > sizeof(logbuf)) { + int mlen = logbuflen + len - sizeof(logbuf); + memmove(logbuf, &logbuf[mlen], sizeof(logbuf) - mlen); + logbuflen -= mlen; + } + memcpy(&logbuf[logbuflen], data, len); + logbuflen += len; - - // Send out USB serial - CDC_Transmit_FS(data, len); - + // Send out USB serial + uint8_t res = CDC_Transmit_FS(logbuf, logbuflen); + if (res == USBD_OK) + logbuflen = 0; // Send out UART serial while(len--)