From 7dac1034e5db678e0b8a291b58d6f2eb2fdf07df Mon Sep 17 00:00:00 2001 From: Oleg Moiseenko Date: Wed, 1 Nov 2017 09:51:05 +0200 Subject: [PATCH] Add hf mf info, change hf mf reader (#452) * copy functionality from `hf 14a reader` to `hf 14a info` * added command `hf 14a reader` with simple anticollision-select procedure. * add parameters to `hf 14a reader`. may start and end acting as reader --- client/cmdhf14a.c | 78 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 09dcd34e..3f103f5f 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -133,7 +133,80 @@ int CmdHF14AList(const char *Cmd) return 0; } -int CmdHF14AReader(const char *Cmd) +int CmdHF14AReader(const char *Cmd) { + uint32_t cm = ISO14A_CONNECT; + bool disconnectAfter = false; + + int cmdp = 0; + while(param_getchar(Cmd, cmdp) != 0x00) { + switch(param_getchar(Cmd, cmdp)) { + case 'h': + case 'H': + PrintAndLog("Usage: hf 14a reader [d] [3]"); + PrintAndLog(" d drop the signal field after command executed"); + PrintAndLog(" x just drop the signal field"); + PrintAndLog(" 3 ISO14443-3 select only (skip RATS)"); + return 0; + case '3': + cm |= ISO14A_NO_RATS; + break; + case 'd': + case 'D': + disconnectAfter = true; + break; + case 'x': + case 'X': + disconnectAfter = true; + cm = cm - ISO14A_CONNECT; + break; + default: + PrintAndLog("Unknown command."); + return 1; + } + + cmdp++; + } + + if (!disconnectAfter) + cm |= ISO14A_NO_DISCONNECT; + + UsbCommand c = {CMD_READER_ISO_14443a, {cm, 0, 0}}; + SendCommand(&c); + + if (ISO14A_CONNECT & cm) { + UsbCommand resp; + WaitForResponse(CMD_ACK,&resp); + + iso14a_card_select_t card; + memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t)); + + uint64_t select_status = resp.arg[0]; // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision + + if(select_status == 0) { + PrintAndLog("iso14443a card select failed"); + return 1; + } + + if(select_status == 3) { + PrintAndLog("Card doesn't support standard iso14443-3 anticollision"); + PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + return 1; + } + + PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen)); + PrintAndLog("ATQA : %02x %02x", card.atqa[1], card.atqa[0]); + PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]); + if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes + PrintAndLog(" ATS : %s", sprint_hex(card.ats, card.ats_len)); + } + PrintAndLog("Card is selected. You can now start sending commands"); + } else { + PrintAndLog("Field dropped."); + } + return 0; +} + +int CmdHF14AInfo(const char *Cmd) { UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}}; SendCommand(&c); @@ -764,7 +837,8 @@ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"list", CmdHF14AList, 0, "[Deprecated] List ISO 14443a history"}, - {"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"}, + {"reader", CmdHF14AReader, 0, "Start acting like an ISO14443 Type A reader"}, + {"info", CmdHF14AInfo, 0, "Reads card and shows information about it"}, {"cuids", CmdHF14ACUIDs, 0, " Collect n>0 ISO14443 Type A UIDs in one go"}, {"sim", CmdHF14ASim, 0, " -- Simulate ISO 14443a tag"}, {"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"}, -- 2.39.2