X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/660d641a03456e99ea83c68dbd3d03bae2b64573..195af47289761be82eeb4f6687a65f5ee8f38611:/armsrc/iso14443a.c diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 8e078140..5a01178d 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -898,13 +898,21 @@ static int GetIso14443aCommandFromReader(uint8_t *received, int *len, int maxLen } } } + static int EmSendCmd14443aRaw(uint8_t *resp, int respLen, int correctionNeeded); +int EmSend4bitEx(uint8_t resp, int correctionNeeded); +int EmSend4bit(uint8_t resp); +int EmSendCmdExPar(uint8_t *resp, int respLen, int correctionNeeded, uint32_t par); +int EmSendCmdExPar(uint8_t *resp, int respLen, int correctionNeeded, uint32_t par); +int EmSendCmdEx(uint8_t *resp, int respLen, int correctionNeeded); +int EmSendCmd(uint8_t *resp, int respLen); +int EmSendCmdPar(uint8_t *resp, int respLen, uint32_t par); //----------------------------------------------------------------------------- // Main loop of simulated tag: receive commands from reader, decide what // response to send, and send it. //----------------------------------------------------------------------------- -void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd) +void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) { // Enable and clear the trace tracing = TRUE; @@ -1024,7 +1032,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd) // Response to a read request - not implemented atm uint8_t *resp4 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*4)); - int resp4Len; +// int resp4Len; // Authenticate response - nonce uint8_t *resp5 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*5)); @@ -1048,7 +1056,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd) int cmdsRecvd = 0; uint8_t* respdata = NULL; int respsize = 0; - uint8_t nack = 0x04; +// uint8_t nack = 0x04; memset(receivedCmd, 0x44, RECV_CMD_SIZE); @@ -1077,7 +1085,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd) // Strange answer is an example of rare message size (3 bits) CodeStrangeAnswerAsTag(); - memcpy(resp4, ToSend, ToSendMax); resp4Len = ToSendMax; + memcpy(resp4, ToSend, ToSendMax);// resp4Len = ToSendMax; // Authentication answer (random nonce) CodeIso14443aAsTag(response5, sizeof(response5)); @@ -1100,6 +1108,11 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd) DbpString("button press"); break; } + + if (tracing) { + LogTrace(receivedCmd,len, 0, Uart.parityBits, TRUE); + } + // doob - added loads of debug strings so we can see what the reader is saying to us during the sim as hi14alist is not populated // Okay, look at the command now. lastorder = order; @@ -1128,10 +1141,13 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd) respdata = response3a; respsize = sizeof(response3a); } else if(receivedCmd[0] == 0x30) { // Received a (plain) READ - resp = resp4; respLen = resp4Len; order = 4; // Do nothing +// resp = resp4; respLen = resp4Len; order = 4; // Do nothing +// respdata = &nack; +// respsize = sizeof(nack); // 4-bit answer + EmSendCmdEx(data+(4*receivedCmd[0]),16,false); Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]); - respdata = &nack; - respsize = sizeof(nack); // 4-bit answer + // We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below + respLen = 0; } else if(receivedCmd[0] == 0x50) { // Received a HALT // DbpString("Reader requested we HALT!:"); // Do not respond @@ -1186,7 +1202,6 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd) } if (tracing) { - LogTrace(receivedCmd,len, 0, Uart.parityBits, TRUE); if (respdata != NULL) { LogTrace(respdata,respsize, 0, SwapBits(GetParity(respdata,respsize),respsize), FALSE); } @@ -1247,68 +1262,9 @@ static void TransmitFor14443a(const uint8_t *cmd, int len, int *samples, int *wa } //----------------------------------------------------------------------------- -// Code a 7-bit command without parity bit -// This is especially for 0x26 and 0x52 (REQA and WUPA) +// Prepare reader command (in bits, support short frames) to send to FPGA //----------------------------------------------------------------------------- -void ShortFrameFromReader(const uint8_t bt) -{ - int j; - int last; - uint8_t b; - - ToSendReset(); - - // Start of Communication (Seq. Z) - ToSend[++ToSendMax] = SEC_Z; - last = 0; - - b = bt; - for(j = 0; j < 7; j++) { - if(b & 1) { - // Sequence X - ToSend[++ToSendMax] = SEC_X; - last = 1; - } else { - if(last == 0) { - // Sequence Z - ToSend[++ToSendMax] = SEC_Z; - } - else { - // Sequence Y - ToSend[++ToSendMax] = SEC_Y; - last = 0; - } - } - b >>= 1; - } - - // End of Communication - if(last == 0) { - // Sequence Z - ToSend[++ToSendMax] = SEC_Z; - } - else { - // Sequence Y - ToSend[++ToSendMax] = SEC_Y; - last = 0; - } - // Sequence Y - ToSend[++ToSendMax] = SEC_Y; - - // Just to be sure! - ToSend[++ToSendMax] = SEC_Y; - ToSend[++ToSendMax] = SEC_Y; - ToSend[++ToSendMax] = SEC_Y; - - // Convert from last character reference to length - ToSendMax++; -} - -//----------------------------------------------------------------------------- -// Prepare reader command to send to FPGA -// -//----------------------------------------------------------------------------- -void CodeIso14443aAsReaderPar(const uint8_t * cmd, int len, uint32_t dwParity) +void CodeIso14443aBitsAsReaderPar(const uint8_t * cmd, int bits, uint32_t dwParity) { int i, j; int last; @@ -1320,12 +1276,14 @@ void CodeIso14443aAsReaderPar(const uint8_t * cmd, int len, uint32_t dwParity) ToSend[++ToSendMax] = SEC_Z; last = 0; + size_t bytecount = nbytes(bits); // Generate send structure for the data bits - for (i = 0; i < len; i++) { + for (i = 0; i < bytecount; i++) { // Get the current byte to send b = cmd[i]; + size_t bitsleft = MIN((bits-(i*8)),8); - for (j = 0; j < 8; j++) { + for (j = 0; j < bitsleft; j++) { if (b & 1) { // Sequence X ToSend[++ToSendMax] = SEC_X; @@ -1343,19 +1301,22 @@ void CodeIso14443aAsReaderPar(const uint8_t * cmd, int len, uint32_t dwParity) b >>= 1; } - // Get the parity bit - if ((dwParity >> i) & 0x01) { - // Sequence X - ToSend[++ToSendMax] = SEC_X; - last = 1; - } else { - if (last == 0) { - // Sequence Z - ToSend[++ToSendMax] = SEC_Z; + // Only transmit (last) parity bit if we transmitted a complete byte + if (j == 8) { + // Get the parity bit + if ((dwParity >> i) & 0x01) { + // Sequence X + ToSend[++ToSendMax] = SEC_X; + last = 1; } else { - // Sequence Y - ToSend[++ToSendMax] = SEC_Y; - last = 0; + if (last == 0) { + // Sequence Z + ToSend[++ToSendMax] = SEC_Z; + } else { + // Sequence Y + ToSend[++ToSendMax] = SEC_Y; + last = 0; + } } } } @@ -1381,6 +1342,14 @@ void CodeIso14443aAsReaderPar(const uint8_t * cmd, int len, uint32_t dwParity) ToSendMax++; } +//----------------------------------------------------------------------------- +// Prepare reader command to send to FPGA +//----------------------------------------------------------------------------- +void CodeIso14443aAsReaderPar(const uint8_t * cmd, int len, uint32_t dwParity) +{ + CodeIso14443aBitsAsReaderPar(cmd,len*8,dwParity); +} + //----------------------------------------------------------------------------- // Wait for commands from reader // Stop when button is pressed (return 1) or field was gone (return 2) @@ -1583,7 +1552,8 @@ void ReaderTransmitShort(const uint8_t* bt) int wait = 0; int samples = 0; - ShortFrameFromReader(*bt); +// ShortFrameFromReader(*bt); + CodeIso14443aBitsAsReaderPar(bt,7,0); // Select the card TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); @@ -1728,12 +1698,12 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u } // Request for answer to select - if(p_hi14a_card) { // JCOP cards - if reader sent RATS then there is no MIFARE session at all!!! - AppendCrc14443a(rats, 2); - ReaderTransmit(rats, sizeof(rats)); - - if (!(len = ReaderReceive(resp))) return 0; - + AppendCrc14443a(rats, 2); + ReaderTransmit(rats, sizeof(rats)); + + if (!(len = ReaderReceive(resp))) return 0; + + if(p_hi14a_card) { memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats)); p_hi14a_card->ats_len = len; }