cleaning up endless copy-paste of trace functionality

This commit is contained in:
roel@libnfc.org 2009-12-28 00:16:05 +00:00
parent 249deb42a0
commit d24438f85c

View file

@ -7,6 +7,10 @@
#include "apps.h" #include "apps.h"
#include "../common/iso14443_crc.c" #include "../common/iso14443_crc.c"
static BYTE *trace = (BYTE *) BigBuf;
static int traceLen = 0;
static int rsamples = 0;
typedef enum { typedef enum {
SEC_D = 1, SEC_D = 1,
SEC_E = 2, SEC_E = 2,
@ -16,6 +20,42 @@ typedef enum {
SEC_Z = 6 SEC_Z = 6
} SecType; } SecType;
static const BYTE OddByteParity[256] = {
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1
};
//-----------------------------------------------------------------------------
// Generate the parity value for a byte sequence
//
//-----------------------------------------------------------------------------
DWORD GetParity(const BYTE * pbtCmd, int iLen)
{
int i;
DWORD dwPar = 0;
// Generate the encrypted data
for (i = 0; i < iLen; i++) {
// Save the encrypted parity bit
dwPar |= ((OddByteParity[pbtCmd[i]]) << i);
}
return dwPar;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// The software UART that receives commands from the reader, and its state // The software UART that receives commands from the reader, and its state
// variables. // variables.
@ -538,8 +578,8 @@ void SnoopIso14443a(void)
// As we receive stuff, we copy it from receivedCmd or receivedResponse // As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations. // into trace, along with its length and other annotations.
BYTE *trace = (BYTE *)BigBuf; //BYTE *trace = (BYTE *)BigBuf;
int traceLen = 0; //int traceLen = 0;
// The DMA buffer, used to stream samples from the FPGA // The DMA buffer, used to stream samples from the FPGA
SBYTE *dmaBuf = ((SBYTE *)BigBuf) + DMA_BUFFER_OFFSET; SBYTE *dmaBuf = ((SBYTE *)BigBuf) + DMA_BUFFER_OFFSET;
@ -834,6 +874,27 @@ static void CodeStrangeAnswer()
//ToSendMax += 2; //ToSendMax += 2;
} }
int LogTrace(const BYTE * btBytes, int iLen, int iSamples, DWORD dwParity, BOOL bReader)
{
// Trace the random, i'm curious
rsamples += iSamples;
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = ((rsamples >> 24) & 0xff);
if (!bReader) {
trace[traceLen - 1] |= 0x80;
}
trace[traceLen++] = ((dwParity >> 0) & 0xff);
trace[traceLen++] = ((dwParity >> 8) & 0xff);
trace[traceLen++] = ((dwParity >> 16) & 0xff);
trace[traceLen++] = ((dwParity >> 24) & 0xff);
trace[traceLen++] = iLen;
memcpy(trace + traceLen, btBytes, iLen);
traceLen += iLen;
return (traceLen < TRACE_LENGTH);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Wait for commands from reader // Wait for commands from reader
// Stop when button is pressed // Stop when button is pressed
@ -1473,6 +1534,8 @@ static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *s
} }
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Read an ISO 14443a tag. Send out commands and store answers. // Read an ISO 14443a tag. Send out commands and store answers.
// //
@ -1531,9 +1594,10 @@ void ReaderIso14443a(DWORD parameter)
BYTE *receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes BYTE *receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes
BYTE *trace = (BYTE *)BigBuf; //BYTE *trace = (BYTE *)BigBuf;
int traceLen = 0; //int traceLen = 0;
int rsamples = 0; //int rsamples = 0;
traceLen = 0;
memset(trace, 0x44, 2000); // was 2000 - tied to oter size chnages memset(trace, 0x44, 2000); // was 2000 - tied to oter size chnages
// setting it to 3000 causes no tag responses to be detected (2900 is ok) // setting it to 3000 causes no tag responses to be detected (2900 is ok)
@ -1588,229 +1652,105 @@ void ReaderIso14443a(DWORD parameter)
int wait = 0; int wait = 0;
int elapsed = 0; int elapsed = 0;
for(;;) { while(1) {
// Send WUPA (or REQA) // Send WUPA (or REQA)
TransmitFor14443a(req1, req1Len, &tsamples, &wait); TransmitFor14443a(req1, req1Len, &tsamples, &wait);
// Store answer in buffer
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 1;
memcpy(trace+traceLen, cmd1, 1);
traceLen += 1;
if(traceLen > TRACE_LENGTH) goto done;
while(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) { // Store reader command in buffer
if(BUTTON_PRESS()) goto done; if (!LogTrace(cmd1,1,0,GetParity(cmd1,1),TRUE)) break;
// Test if the action was cancelled
if(BUTTON_PRESS()) {
break;
}
if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) continue;
// Log the ATQA
if (!LogTrace(receivedAnswer,Demod.len,samples,Demod.parityBits,FALSE)) break;
// No answer, just continue polling // Store reader command in buffer
TransmitFor14443a(req1, req1Len, &tsamples, &wait); if (!LogTrace(cmd2,2,0,GetParity(cmd2,2),TRUE)) break;
// Store answer in buffer TransmitFor14443a(req2, req2Len, &samples, &wait);
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 1;
memcpy(trace+traceLen, cmd1, 1);
traceLen += 1;
if(traceLen > TRACE_LENGTH) goto done;
}
// Store answer in buffer if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) continue;
rsamples = rsamples + (samples - Demod.samples);
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedAnswer, Demod.len);
traceLen += Demod.len;
if(traceLen > TRACE_LENGTH) goto done;
// Ask for card UID
TransmitFor14443a(req2, req2Len, &tsamples, &wait);
// Store answer in buffer
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 2;
memcpy(trace+traceLen, cmd2, 2);
traceLen += 2;
if(traceLen > TRACE_LENGTH) goto done;
if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {
continue;
}
// Store answer in buffer
rsamples = rsamples + (samples - Demod.samples);
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedAnswer, Demod.len);
traceLen += Demod.len;
if(traceLen > TRACE_LENGTH) goto done;
// Log the uid
if (!LogTrace(receivedAnswer,Demod.len,samples,Demod.parityBits,FALSE)) break;
// Construct SELECT UID command // Construct SELECT UID command
// First copy the 5 bytes (Mifare Classic) after the 93 70 // First copy the 5 bytes (Mifare Classic) after the 93 70
memcpy(cmd3+2,receivedAnswer,5); memcpy(cmd3+2,receivedAnswer,5);
// Secondly compute the two CRC bytes at the end // Secondly compute the two CRC bytes at the end
ComputeCrc14443(CRC_14443_A, cmd3, 7, &cmd3[7], &cmd3[8]); ComputeCrc14443(CRC_14443_A, cmd3, 7, &cmd3[7], &cmd3[8]);
// Prepare the bit sequence to modulate the subcarrier
// Store answer in buffer // Store reader command in buffer
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; if (!LogTrace(cmd3,9,0,GetParity(cmd5,9),TRUE)) break;
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 9;
memcpy(trace+traceLen, cmd3, 9);
traceLen += 9;
if(traceLen > TRACE_LENGTH) goto done;
CodeIso14443aAsReader(cmd3, sizeof(cmd3)); CodeIso14443aAsReader(cmd3, sizeof(cmd3));
memcpy(req3, ToSend, ToSendMax); req3Len = ToSendMax; memcpy(req3, ToSend, ToSendMax); req3Len = ToSendMax;
// Select the card // Select the card
TransmitFor14443a(req3, req3Len, &samples, &wait); TransmitFor14443a(req3, req3Len, &samples, &wait);
if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) { if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) continue;
continue;
}
// Store answer in buffer // Log the SAK
rsamples = rsamples + (samples - Demod.samples); if (!LogTrace(receivedAnswer,Demod.len,samples,Demod.parityBits,FALSE)) break;
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedAnswer, Demod.len);
traceLen += Demod.len;
if(traceLen > TRACE_LENGTH) goto done;
// OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in // OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in
// which case we need to make a cascade 2 request and select - this is a long UID // which case we need to make a cascade 2 request and select - this is a long UID
if (receivedAnswer[0] == 0x88) if (receivedAnswer[0] == 0x88)
{ {
// Do cascade level 2 stuff // Do cascade level 2 stuff
/////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////
// First issue a '95 20' identify request // First issue a '95 20' identify request
// Ask for card UID (part 2) // Ask for card UID (part 2)
TransmitFor14443a(req4, req4Len, &tsamples, &wait); TransmitFor14443a(req4, req4Len, &tsamples, &wait);
// Store answer in buffer
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 2;
memcpy(trace+traceLen, cmd4, 2);
traceLen += 2;
if(traceLen > TRACE_LENGTH) {
DbpString("Bugging out, just popped tracelength");
goto done;}
if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) { // Store reader command in buffer
continue; if (!LogTrace(cmd4,2,0,GetParity(cmd4,2),TRUE)) break;
}
// Store answer in buffer
rsamples = rsamples + (samples - Demod.samples);
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedAnswer, Demod.len);
traceLen += Demod.len;
if(traceLen > TRACE_LENGTH) goto done;
//////////////////////////////////////////////////////////////////
// Then Construct SELECT UID (cascasde 2) command
DbpString("Just about to copy the UID out of the cascade 2 id req");
// First copy the 5 bytes (Mifare Classic) after the 95 70
memcpy(cmd5+2,receivedAnswer,5);
// Secondly compute the two CRC bytes at the end
ComputeCrc14443(CRC_14443_A, cmd4, 7, &cmd5[7], &cmd5[8]);
// Prepare the bit sequence to modulate the subcarrier
// Store answer in buffer
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0;
trace[traceLen++] = 9;
memcpy(trace+traceLen, cmd5, 9);
traceLen += 9;
if(traceLen > TRACE_LENGTH) goto done;
CodeIso14443aAsReader(cmd5, sizeof(cmd5));
memcpy(req5, ToSend, ToSendMax); req5Len = ToSendMax;
// Select the card if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) continue;
TransmitFor14443a(req4, req4Len, &samples, &wait);
if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {
continue;
}
// Store answer in buffer //////////////////////////////////////////////////////////////////
rsamples = rsamples + (samples - Demod.samples); // Then Construct SELECT UID (cascasde 2) command
trace[traceLen++] = ((rsamples >> 0) & 0xff); DbpString("Just about to copy the UID out of the cascade 2 id req");
trace[traceLen++] = ((rsamples >> 8) & 0xff); // First copy the 5 bytes (Mifare Classic) after the 95 70
trace[traceLen++] = ((rsamples >> 16) & 0xff); memcpy(cmd5+2,receivedAnswer,5);
trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff); // Secondly compute the two CRC bytes at the end
trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff); ComputeCrc14443(CRC_14443_A, cmd4, 7, &cmd5[7], &cmd5[8]);
trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedAnswer, Demod.len);
traceLen += Demod.len;
if(traceLen > TRACE_LENGTH) goto done;
// Store reader command in buffer
if (!LogTrace(cmd5,9,0,GetParity(cmd5,9),TRUE)) break;
CodeIso14443aAsReader(cmd5, sizeof(cmd5));
memcpy(req5, ToSend, ToSendMax); req5Len = ToSendMax;
// Select the card
TransmitFor14443a(req4, req4Len, &samples, &wait);
if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) continue;
// Log the SAK
if (!LogTrace(receivedAnswer,Demod.len,samples,Demod.parityBits,FALSE)) break;
} }
// Secondly compute the two CRC bytes at the end // Secondly compute the two CRC bytes at the end
ComputeCrc14443(CRC_14443_A, cmd7, 2, &cmd7[2], &cmd7[3]); ComputeCrc14443(CRC_14443_A, cmd7, 2, &cmd7[2], &cmd7[3]);
CodeIso14443aAsReader(cmd7, sizeof(cmd7)); CodeIso14443aAsReader(cmd7, sizeof(cmd7));
memcpy(req7, ToSend, ToSendMax); req7Len = ToSendMax; memcpy(req7, ToSend, ToSendMax); req7Len = ToSendMax;
// Send authentication request (Mifare Classic) // Send authentication request (Mifare Classic)
TransmitFor14443a(req7, req7Len, &samples, &wait); TransmitFor14443a(req7, req7Len, &samples, &wait);
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; // Store reader command in buffer
trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; trace[traceLen++] = 0; if (!LogTrace(cmd7,4,0,GetParity(cmd7,4),TRUE)) break;
trace[traceLen++] = 4;
memcpy(trace+traceLen, cmd7, 4);
traceLen += 4;
if(traceLen > TRACE_LENGTH) goto done;
if(GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) {
rsamples++;
// We received probably a random, continue and trace!
}
else {
// Received nothing
continue;
}
// Trace the random, i'm curious if(!GetIso14443aAnswerFromTag(receivedAnswer, 100, &samples, &elapsed)) continue;
rsamples = rsamples + (samples - Demod.samples);
trace[traceLen++] = ((rsamples >> 0) & 0xff);
trace[traceLen++] = ((rsamples >> 8) & 0xff);
trace[traceLen++] = ((rsamples >> 16) & 0xff);
trace[traceLen++] = 0x80 | ((rsamples >> 24) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 0) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 8) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 16) & 0xff);
trace[traceLen++] = ((Demod.parityBits >> 24) & 0xff);
trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedAnswer, Demod.len);
traceLen += Demod.len;
if(traceLen > TRACE_LENGTH) goto done;
// Thats it... // We received probably a random, continue and trace!
if (!LogTrace(receivedAnswer,Demod.len,samples,Demod.parityBits,FALSE)) break;
} }
done: // Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
DbpIntegers(rsamples, 0xCC, 0xCC); DbpIntegers(rsamples, 0xCC, 0xCC);