mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 21:33:47 -07:00
Syntaxt suger,
and some clean up in the "hf mf mifare" code. I removed the three strategies Pivi added to make the code easier and added a lot of comments to understand. the WDT bug is still there in this code. Needs further testing yet, before I commit the fix. So far the fix is quite stable on ubuntu, but on mingw/win is breaking still. Which at this point doesnt make any sense.
This commit is contained in:
parent
88e20c9f6d
commit
91c7a7ccb7
1 changed files with 176 additions and 238 deletions
|
@ -132,7 +132,6 @@ void iso14a_set_timeout(uint32_t timeout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void iso14a_set_ATS_timeout(uint8_t *ats) {
|
void iso14a_set_ATS_timeout(uint8_t *ats) {
|
||||||
|
|
||||||
uint8_t tb1;
|
uint8_t tb1;
|
||||||
uint8_t fwi;
|
uint8_t fwi;
|
||||||
uint32_t fwt;
|
uint32_t fwt;
|
||||||
|
@ -159,8 +158,7 @@ void iso14a_set_ATS_timeout(uint8_t *ats) {
|
||||||
// Generate the parity value for a byte sequence
|
// Generate the parity value for a byte sequence
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par)
|
void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par) {
|
||||||
{
|
|
||||||
uint16_t paritybit_cnt = 0;
|
uint16_t paritybit_cnt = 0;
|
||||||
uint16_t paritybyte_cnt = 0;
|
uint16_t paritybyte_cnt = 0;
|
||||||
uint8_t parityBits = 0;
|
uint8_t parityBits = 0;
|
||||||
|
@ -180,11 +178,9 @@ void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par)
|
||||||
|
|
||||||
// save remaining parity bits
|
// save remaining parity bits
|
||||||
par[paritybyte_cnt] = parityBits;
|
par[paritybyte_cnt] = parityBits;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppendCrc14443a(uint8_t* data, int len)
|
void AppendCrc14443a(uint8_t* data, int len) {
|
||||||
{
|
|
||||||
ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
|
ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,8 +215,7 @@ const bool Mod_Miller_LUT[] = {
|
||||||
#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
|
#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
|
||||||
#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
|
#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
|
||||||
|
|
||||||
void UartReset()
|
void UartReset() {
|
||||||
{
|
|
||||||
Uart.state = STATE_UNSYNCD;
|
Uart.state = STATE_UNSYNCD;
|
||||||
Uart.bitCount = 0;
|
Uart.bitCount = 0;
|
||||||
Uart.len = 0; // number of decoded data bytes
|
Uart.len = 0; // number of decoded data bytes
|
||||||
|
@ -235,8 +230,7 @@ void UartReset()
|
||||||
Uart.syncBit = 9999;
|
Uart.syncBit = 9999;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UartInit(uint8_t *data, uint8_t *parity)
|
void UartInit(uint8_t *data, uint8_t *parity) {
|
||||||
{
|
|
||||||
Uart.output = data;
|
Uart.output = data;
|
||||||
Uart.parity = parity;
|
Uart.parity = parity;
|
||||||
Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits
|
Uart.fourBits = 0x00000000; // clear the buffer for 4 Bits
|
||||||
|
@ -244,13 +238,10 @@ void UartInit(uint8_t *data, uint8_t *parity)
|
||||||
}
|
}
|
||||||
|
|
||||||
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
|
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
|
||||||
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) {
|
||||||
{
|
|
||||||
|
|
||||||
Uart.fourBits = (Uart.fourBits << 8) | bit;
|
Uart.fourBits = (Uart.fourBits << 8) | bit;
|
||||||
|
|
||||||
if (Uart.state == STATE_UNSYNCD) { // not yet synced
|
if (Uart.state == STATE_UNSYNCD) { // not yet synced
|
||||||
|
|
||||||
Uart.syncBit = 9999; // not set
|
Uart.syncBit = 9999; // not set
|
||||||
|
|
||||||
// 00x11111 2|3 ticks pause followed by 6|5 ticks unmodulated Sequence Z (a "0" or "start of communication")
|
// 00x11111 2|3 ticks pause followed by 6|5 ticks unmodulated Sequence Z (a "0" or "start of communication")
|
||||||
|
@ -275,12 +266,11 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||||
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 7)) == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0;
|
else if ((Uart.fourBits & (ISO14443A_STARTBIT_MASK >> 7)) == ISO14443A_STARTBIT_PATTERN >> 7) Uart.syncBit = 0;
|
||||||
|
|
||||||
if (Uart.syncBit != 9999) { // found a sync bit
|
if (Uart.syncBit != 9999) { // found a sync bit
|
||||||
Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
|
Uart.startTime = non_real_time ? non_real_time : (GetCountSspClk() & 0xfffffff8);
|
||||||
Uart.startTime -= Uart.syncBit;
|
Uart.startTime -= Uart.syncBit;
|
||||||
Uart.endTime = Uart.startTime;
|
Uart.endTime = Uart.startTime;
|
||||||
Uart.state = STATE_START_OF_COMMUNICATION;
|
Uart.state = STATE_START_OF_COMMUNICATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) {
|
if (IsMillerModulationNibble1(Uart.fourBits >> Uart.syncBit)) {
|
||||||
|
@ -366,9 +356,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE; // not finished yet, need more data
|
return FALSE; // not finished yet, need more data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,9 +389,7 @@ const bool Mod_Manchester_LUT[] = {
|
||||||
#define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
|
#define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
|
||||||
#define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)])
|
#define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)])
|
||||||
|
|
||||||
|
void DemodReset() {
|
||||||
void DemodReset()
|
|
||||||
{
|
|
||||||
Demod.state = DEMOD_UNSYNCD;
|
Demod.state = DEMOD_UNSYNCD;
|
||||||
Demod.len = 0; // number of decoded data bytes
|
Demod.len = 0; // number of decoded data bytes
|
||||||
Demod.parityLen = 0;
|
Demod.parityLen = 0;
|
||||||
|
@ -414,23 +400,19 @@ void DemodReset()
|
||||||
Demod.highCnt = 0;
|
Demod.highCnt = 0;
|
||||||
Demod.startTime = 0;
|
Demod.startTime = 0;
|
||||||
Demod.endTime = 0;
|
Demod.endTime = 0;
|
||||||
|
|
||||||
//
|
|
||||||
Demod.bitCount = 0;
|
Demod.bitCount = 0;
|
||||||
Demod.syncBit = 0xFFFF;
|
Demod.syncBit = 0xFFFF;
|
||||||
Demod.samples = 0;
|
Demod.samples = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DemodInit(uint8_t *data, uint8_t *parity)
|
void DemodInit(uint8_t *data, uint8_t *parity) {
|
||||||
{
|
|
||||||
Demod.output = data;
|
Demod.output = data;
|
||||||
Demod.parity = parity;
|
Demod.parity = parity;
|
||||||
DemodReset();
|
DemodReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
|
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
|
||||||
static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time)
|
static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) {
|
||||||
{
|
|
||||||
Demod.twoBits = (Demod.twoBits << 8) | bit;
|
Demod.twoBits = (Demod.twoBits << 8) | bit;
|
||||||
|
|
||||||
if (Demod.state == DEMOD_UNSYNCD) {
|
if (Demod.state == DEMOD_UNSYNCD) {
|
||||||
|
@ -458,7 +440,6 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
|
||||||
Demod.state = DEMOD_MANCHESTER_DATA;
|
Demod.state = DEMOD_MANCHESTER_DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half
|
if (IsManchesterModulationNibble1(Demod.twoBits >> Demod.syncBit)) { // modulation in first half
|
||||||
|
@ -541,8 +522,6 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||||
// Allocate memory from BigBuf for some buffers
|
// Allocate memory from BigBuf for some buffers
|
||||||
// free all previous allocations first
|
// free all previous allocations first
|
||||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
// init trace buffer
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
|
@ -667,7 +646,6 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||||
DemodReset();
|
DemodReset();
|
||||||
// And reset the Miller decoder including itS (now outdated) input buffer
|
// And reset the Miller decoder including itS (now outdated) input buffer
|
||||||
UartInit(receivedCmd, receivedCmdPar);
|
UartInit(receivedCmd, receivedCmdPar);
|
||||||
|
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
}
|
}
|
||||||
TagIsActive = (Demod.state != DEMOD_UNSYNCD);
|
TagIsActive = (Demod.state != DEMOD_UNSYNCD);
|
||||||
|
@ -688,14 +666,14 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
|
||||||
Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len);
|
Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len);
|
||||||
Dbprintf("traceLen=%d, Uart.output[0]=%08x", BigBuf_get_traceLen(), (uint32_t)Uart.output[0]);
|
Dbprintf("traceLen=%d, Uart.output[0]=%08x", BigBuf_get_traceLen(), (uint32_t)Uart.output[0]);
|
||||||
|
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
set_tracing(FALSE);
|
set_tracing(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Prepare tag messages
|
// Prepare tag messages
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity)
|
static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity) {
|
||||||
{
|
|
||||||
ToSendReset();
|
ToSendReset();
|
||||||
|
|
||||||
// Correction bit, might be removed when not needed
|
// Correction bit, might be removed when not needed
|
||||||
|
@ -742,17 +720,15 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par
|
||||||
++ToSendMax;
|
++ToSendMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len)
|
static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len) {
|
||||||
{
|
|
||||||
uint8_t par[MAX_PARITY_SIZE] = {0};
|
uint8_t par[MAX_PARITY_SIZE] = {0};
|
||||||
GetParity(cmd, len, par);
|
GetParity(cmd, len, par);
|
||||||
CodeIso14443aAsTagPar(cmd, len, par);
|
CodeIso14443aAsTagPar(cmd, len, par);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void Code4bitAnswerAsTag(uint8_t cmd) {
|
||||||
static void Code4bitAnswerAsTag(uint8_t cmd)
|
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
|
uint8_t b = cmd;
|
||||||
|
|
||||||
ToSendReset();
|
ToSendReset();
|
||||||
|
|
||||||
|
@ -769,7 +745,6 @@ static void Code4bitAnswerAsTag(uint8_t cmd)
|
||||||
// Send startbit
|
// Send startbit
|
||||||
ToSend[++ToSendMax] = SEC_D;
|
ToSend[++ToSendMax] = SEC_D;
|
||||||
|
|
||||||
uint8_t b = cmd;
|
|
||||||
for(i = 0; i < 4; i++) {
|
for(i = 0; i < 4; i++) {
|
||||||
if(b & 1) {
|
if(b & 1) {
|
||||||
ToSend[++ToSendMax] = SEC_D;
|
ToSend[++ToSendMax] = SEC_D;
|
||||||
|
@ -793,8 +768,7 @@ static void Code4bitAnswerAsTag(uint8_t cmd)
|
||||||
// Stop when button is pressed
|
// Stop when button is pressed
|
||||||
// Or return TRUE when command is captured
|
// Or return TRUE when command is captured
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len)
|
static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) {
|
||||||
{
|
|
||||||
// Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
|
// Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
|
||||||
// only, since we are receiving, not transmitting).
|
// only, since we are receiving, not transmitting).
|
||||||
// Signal field is off with the appropriate LED
|
// Signal field is off with the appropriate LED
|
||||||
|
@ -853,8 +827,6 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
|
||||||
// ----------- +
|
// ----------- +
|
||||||
// 166 bytes, since every bit that needs to be send costs us a byte
|
// 166 bytes, since every bit that needs to be send costs us a byte
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
// Prepare the tag modulation bits from the message
|
// Prepare the tag modulation bits from the message
|
||||||
CodeIso14443aAsTag(response_info->response,response_info->response_n);
|
CodeIso14443aAsTag(response_info->response,response_info->response_n);
|
||||||
|
|
||||||
|
@ -862,7 +834,7 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
|
||||||
if (ToSendMax > max_buffer_size) {
|
if (ToSendMax > max_buffer_size) {
|
||||||
Dbprintf("Out of memory, when modulating bits for tag answer:");
|
Dbprintf("Out of memory, when modulating bits for tag answer:");
|
||||||
Dbhexdump(response_info->response_n,response_info->response,false);
|
Dbhexdump(response_info->response_n,response_info->response,false);
|
||||||
return false;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the byte array, used for this modulation to the buffer position
|
// Copy the byte array, used for this modulation to the buffer position
|
||||||
|
@ -871,8 +843,7 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
|
||||||
// Store the number of bytes that were used for encoding/modulation and the time needed to transfer them
|
// Store the number of bytes that were used for encoding/modulation and the time needed to transfer them
|
||||||
response_info->modulation_n = ToSendMax;
|
response_info->modulation_n = ToSendMax;
|
||||||
response_info->ProxToAirDuration = LastProxToAirDuration;
|
response_info->ProxToAirDuration = LastProxToAirDuration;
|
||||||
|
return TRUE;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -905,8 +876,7 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
|
||||||
// Main loop of simulated tag: receive commands from reader, decide what
|
// Main loop of simulated tag: receive commands from reader, decide what
|
||||||
// response to send, and send it.
|
// response to send, and send it.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
void SimulateIso14443aTag(int tagType, int flags, byte_t* data) {
|
||||||
{
|
|
||||||
uint32_t counters[] = {0,0,0};
|
uint32_t counters[] = {0,0,0};
|
||||||
//Here, we collect UID,NT,AR,NR,UID2,NT2,AR2,NR2
|
//Here, we collect UID,NT,AR,NR,UID2,NT2,AR2,NR2
|
||||||
// This can be used in a reader-only attack.
|
// This can be used in a reader-only attack.
|
||||||
|
@ -1149,7 +1119,6 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
}
|
}
|
||||||
} else if(receivedCmd[0] == 0x3A) { // Received a FAST READ (ranged read)
|
} else if(receivedCmd[0] == 0x3A) { // Received a FAST READ (ranged read)
|
||||||
|
|
||||||
uint8_t emdata[MAX_FRAME_SIZE];
|
uint8_t emdata[MAX_FRAME_SIZE];
|
||||||
//first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
|
//first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
|
||||||
int start = (receivedCmd[1]+12) * 4;
|
int start = (receivedCmd[1]+12) * 4;
|
||||||
|
@ -1158,7 +1127,6 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
||||||
AppendCrc14443a(emdata, len);
|
AppendCrc14443a(emdata, len);
|
||||||
EmSendCmdEx(emdata, len+2, false);
|
EmSendCmdEx(emdata, len+2, false);
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
|
|
||||||
} else if(receivedCmd[0] == 0x3C && tagType == 7) { // Received a READ SIGNATURE --
|
} else if(receivedCmd[0] == 0x3C && tagType == 7) { // Received a READ SIGNATURE --
|
||||||
//first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
|
//first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
|
||||||
uint16_t start = 4 * 4;
|
uint16_t start = 4 * 4;
|
||||||
|
@ -1186,7 +1154,6 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
||||||
uint8_t ack[] = {0x0a};
|
uint8_t ack[] = {0x0a};
|
||||||
EmSendCmdEx(ack,sizeof(ack),false);
|
EmSendCmdEx(ack,sizeof(ack),false);
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
|
|
||||||
} else if(receivedCmd[0] == 0x3E && tagType == 7) { // Received a CHECK_TEARING_EVENT --
|
} else if(receivedCmd[0] == 0x3E && tagType == 7) { // Received a CHECK_TEARING_EVENT --
|
||||||
//first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
|
//first 12 blocks of emu are [getversion answer - check tearing - pack - 0x00 - signature]
|
||||||
uint8_t emdata[3];
|
uint8_t emdata[3];
|
||||||
|
@ -1222,10 +1189,8 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
||||||
uint32_t nonce = bytes_to_num(response5,4);
|
uint32_t nonce = bytes_to_num(response5,4);
|
||||||
uint32_t nr = bytes_to_num(receivedCmd,4);
|
uint32_t nr = bytes_to_num(receivedCmd,4);
|
||||||
uint32_t ar = bytes_to_num(receivedCmd+4,4);
|
uint32_t ar = bytes_to_num(receivedCmd+4,4);
|
||||||
//Dbprintf("Auth attempt {nonce}{nr}{ar}: %08x %08x %08x", nonce, nr, ar);
|
|
||||||
|
|
||||||
if(flags & FLAG_NR_AR_ATTACK )
|
if(flags & FLAG_NR_AR_ATTACK ) {
|
||||||
{
|
|
||||||
if(ar_nr_collected < 2){
|
if(ar_nr_collected < 2){
|
||||||
// Avoid duplicates... probably not necessary, nr should vary.
|
// Avoid duplicates... probably not necessary, nr should vary.
|
||||||
//if(ar_nr_responses[3] != nr){
|
//if(ar_nr_responses[3] != nr){
|
||||||
|
@ -1268,12 +1233,9 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
||||||
memset(ar_nr_responses, 0x00, len);
|
memset(ar_nr_responses, 0x00, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (receivedCmd[0] == 0x1a ) // ULC authentication
|
} else if (receivedCmd[0] == 0x1a ) { // ULC authentication
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (receivedCmd[0] == 0x1b) // NTAG / EV-1 authentication
|
else if (receivedCmd[0] == 0x1b) { // NTAG / EV-1 authentication
|
||||||
{
|
|
||||||
if ( tagType == 7 ) {
|
if ( tagType == 7 ) {
|
||||||
uint16_t start = 13; //first 4 blocks of emu are [getversion answer - check tearing - pack - 0x00]
|
uint16_t start = 13; //first 4 blocks of emu are [getversion answer - check tearing - pack - 0x00]
|
||||||
uint8_t emdata[4];
|
uint8_t emdata[4];
|
||||||
|
@ -1362,6 +1324,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
||||||
// Count number of other messages after a halt
|
// Count number of other messages after a halt
|
||||||
if(order != 6 && lastorder == 5) { happened2++; }
|
if(order != 6 && lastorder == 5) { happened2++; }
|
||||||
|
|
||||||
|
// comment this limit if you want to simulation longer
|
||||||
if(cmdsRecvd > 999) {
|
if(cmdsRecvd > 999) {
|
||||||
DbpString("1000 commands later...");
|
DbpString("1000 commands later...");
|
||||||
break;
|
break;
|
||||||
|
@ -1386,6 +1349,7 @@ void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
|
||||||
par);
|
par);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// comment this limit if you want to simulation longer
|
||||||
if (!tracing) {
|
if (!tracing) {
|
||||||
Dbprintf("Trace Full. Simulation stopped.");
|
Dbprintf("Trace Full. Simulation stopped.");
|
||||||
break;
|
break;
|
||||||
|
@ -1856,8 +1820,7 @@ int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parit
|
||||||
return Demod.len;
|
return Demod.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
|
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) {
|
||||||
{
|
|
||||||
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return FALSE;
|
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return FALSE;
|
||||||
//if (tracing) {
|
//if (tracing) {
|
||||||
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, FALSE);
|
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, FALSE);
|
||||||
|
@ -2029,23 +1992,25 @@ void iso14443a_setup(uint8_t fpga_minor_mode) {
|
||||||
// connect Demodulated Signal to ADC:
|
// connect Demodulated Signal to ADC:
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||||
|
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode);
|
||||||
|
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
// Signal field is on with the appropriate LED
|
// Signal field is on with the appropriate LED
|
||||||
if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD ||
|
if (fpga_minor_mode == FPGA_HF_ISO14443A_READER_MOD ||
|
||||||
fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN)
|
fpga_minor_mode == FPGA_HF_ISO14443A_READER_LISTEN)
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | fpga_minor_mode);
|
// Prepare the demodulation functions
|
||||||
|
|
||||||
DemodReset();
|
DemodReset();
|
||||||
UartReset();
|
UartReset();
|
||||||
|
|
||||||
iso14a_set_timeout(10*106); // 10ms default
|
iso14a_set_timeout(10*106); // 10ms default
|
||||||
|
|
||||||
|
//NextTransferTime = 2 * DELAY_ARM2AIR_AS_READER;
|
||||||
|
NextTransferTime = DELAY_ARM2AIR_AS_READER << 1;
|
||||||
|
|
||||||
// Start the timer
|
// Start the timer
|
||||||
StartCountSspClk();
|
StartCountSspClk();
|
||||||
|
|
||||||
NextTransferTime = 2*DELAY_ARM2AIR_AS_READER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
|
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
|
||||||
|
@ -2082,13 +2047,12 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data) {
|
||||||
// Read an ISO 14443a tag. Send out commands and store answers.
|
// Read an ISO 14443a tag. Send out commands and store answers.
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void ReaderIso14443a(UsbCommand *c)
|
void ReaderIso14443a(UsbCommand *c) {
|
||||||
{
|
|
||||||
iso14a_command_t param = c->arg[0];
|
iso14a_command_t param = c->arg[0];
|
||||||
uint8_t *cmd = c->d.asBytes;
|
|
||||||
size_t len = c->arg[1] & 0xffff;
|
size_t len = c->arg[1] & 0xffff;
|
||||||
size_t lenbits = c->arg[1] >> 16;
|
size_t lenbits = c->arg[1] >> 16;
|
||||||
uint32_t timeout = c->arg[2];
|
uint32_t timeout = c->arg[2];
|
||||||
|
uint8_t *cmd = c->d.asBytes;
|
||||||
uint32_t arg0 = 0;
|
uint32_t arg0 = 0;
|
||||||
byte_t buf[USB_CMD_DATA_SIZE] = {0x00};
|
byte_t buf[USB_CMD_DATA_SIZE] = {0x00};
|
||||||
uint8_t par[MAX_PARITY_SIZE] = {0x00};
|
uint8_t par[MAX_PARITY_SIZE] = {0x00};
|
||||||
|
@ -2106,7 +2070,7 @@ void ReaderIso14443a(UsbCommand *c)
|
||||||
if(!(param & ISO14A_NO_SELECT)) {
|
if(!(param & ISO14A_NO_SELECT)) {
|
||||||
iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
|
iso14a_card_select_t *card = (iso14a_card_select_t*)buf;
|
||||||
arg0 = iso14443a_select_card(NULL,card,NULL, true, 0);
|
arg0 = iso14443a_select_card(NULL,card,NULL, true, 0);
|
||||||
cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
|
cmd_send(CMD_ACK, arg0, card->uidlen, 0, buf, sizeof(iso14a_card_select_t));
|
||||||
// if it fails, the cmdhf14a.c client quites.. however this one still executes.
|
// if it fails, the cmdhf14a.c client quites.. however this one still executes.
|
||||||
if ( arg0 == 0 ) return;
|
if ( arg0 == 0 ) return;
|
||||||
}
|
}
|
||||||
|
@ -2162,7 +2126,6 @@ void ReaderIso14443a(UsbCommand *c)
|
||||||
if (param & ISO14A_REQUEST_TRIGGER)
|
if (param & ISO14A_REQUEST_TRIGGER)
|
||||||
iso14a_set_trigger(FALSE);
|
iso14a_set_trigger(FALSE);
|
||||||
|
|
||||||
|
|
||||||
if (param & ISO14A_NO_DISCONNECT)
|
if (param & ISO14A_NO_DISCONNECT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2177,22 +2140,20 @@ void ReaderIso14443a(UsbCommand *c)
|
||||||
// Therefore try in alternating directions.
|
// Therefore try in alternating directions.
|
||||||
int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
|
int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
|
||||||
|
|
||||||
uint16_t i;
|
|
||||||
uint32_t nttmp1, nttmp2;
|
|
||||||
|
|
||||||
if (nt1 == nt2) return 0;
|
if (nt1 == nt2) return 0;
|
||||||
|
|
||||||
nttmp1 = nt1;
|
uint16_t i;
|
||||||
nttmp2 = nt2;
|
uint32_t nttmp1 = nt1;
|
||||||
|
uint32_t nttmp2 = nt2;
|
||||||
|
|
||||||
for (i = 1; i < 32768; i++) {
|
for (i = 1; i < 32768; ++i) {
|
||||||
nttmp1 = prng_successor(nttmp1, 1);
|
nttmp1 = prng_successor(nttmp1, 1);
|
||||||
if (nttmp1 == nt2) return i;
|
if (nttmp1 == nt2) return i;
|
||||||
nttmp2 = prng_successor(nttmp2, 1);
|
nttmp2 = prng_successor(nttmp2, 1);
|
||||||
if (nttmp2 == nt1) return -i;
|
if (nttmp2 == nt1) return -i;
|
||||||
}
|
}
|
||||||
|
// either nt1 or nt2 are invalid nonces
|
||||||
return(-99999); // either nt1 or nt2 are invalid nonces
|
return(-99999);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2202,12 +2163,11 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
|
||||||
// Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime"
|
// Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime"
|
||||||
// (article by Nicolas T. Courtois, 2009)
|
// (article by Nicolas T. Courtois, 2009)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void ReaderMifare(bool first_try, uint8_t block )
|
void ReaderMifare(bool first_try, uint8_t block ) {
|
||||||
{
|
|
||||||
// Mifare AUTH
|
// Mifare AUTH
|
||||||
//uint8_t mf_auth[] = { 0x60,0x00,0xf5,0x7b };
|
//uint8_t mf_auth[] = { 0x60,0x00,0xf5,0x7b };
|
||||||
//uint8_t mf_auth[] = { 0x60,0x05, 0x58, 0x2c };
|
//uint8_t mf_auth[] = { 0x60,0x05, 0x58, 0x2c };
|
||||||
uint8_t mf_auth[] = { 0x60,0x00, 0x00, 0x00 };
|
uint8_t mf_auth[] = { MIFARE_AUTH_KEYA, block, 0x00, 0x00 };
|
||||||
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
|
||||||
uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0};
|
uint8_t uid[10] = {0,0,0,0,0,0,0,0,0,0};
|
||||||
uint8_t par_list[8] = {0,0,0,0,0,0,0,0};
|
uint8_t par_list[8] = {0,0,0,0,0,0,0,0};
|
||||||
|
@ -2215,30 +2175,25 @@ void ReaderMifare(bool first_try, uint8_t block )
|
||||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
||||||
uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
|
uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough
|
||||||
|
|
||||||
mf_auth[1] = block;
|
|
||||||
AppendCrc14443a(mf_auth, 2);
|
|
||||||
|
|
||||||
byte_t nt_diff = 0;
|
byte_t nt_diff = 0;
|
||||||
|
|
||||||
uint32_t nt = 0;
|
uint32_t nt = 0;
|
||||||
uint32_t previous_nt = 0;
|
uint32_t previous_nt = 0;
|
||||||
uint32_t halt_time = 0;
|
|
||||||
uint32_t cuid = 0;
|
uint32_t cuid = 0;
|
||||||
|
|
||||||
int catch_up_cycles = 0;
|
int32_t catch_up_cycles = 0;
|
||||||
int last_catch_up = 0;
|
int32_t last_catch_up = 0;
|
||||||
int isOK = 0;
|
int32_t isOK = 0;
|
||||||
|
int32_t nt_distance = 0;
|
||||||
|
|
||||||
uint16_t elapsed_prng_sequences = 1;
|
uint16_t elapsed_prng_sequences = 1;
|
||||||
uint16_t consecutive_resyncs = 0;
|
uint16_t consecutive_resyncs = 0;
|
||||||
uint16_t unexpected_random = 0;
|
uint16_t unexpected_random = 0;
|
||||||
uint16_t sync_tries = 0;
|
uint16_t sync_tries = 0;
|
||||||
uint16_t strategy = 0;
|
|
||||||
|
|
||||||
|
// static variables here, is re-used in the next call?
|
||||||
static uint32_t nt_attacked = 0;
|
static uint32_t nt_attacked = 0;
|
||||||
static uint32_t sync_time = 0;
|
static uint32_t sync_time = 0;
|
||||||
static int32_t sync_cycles = 0;
|
static uint32_t sync_cycles = 0;
|
||||||
static uint8_t par_low = 0;
|
static uint8_t par_low = 0;
|
||||||
static uint8_t mf_nr_ar3 = 0;
|
static uint8_t mf_nr_ar3 = 0;
|
||||||
|
|
||||||
|
@ -2247,23 +2202,21 @@ void ReaderMifare(bool first_try, uint8_t block )
|
||||||
#define MAX_SYNC_TRIES 32
|
#define MAX_SYNC_TRIES 32
|
||||||
#define MAX_STRATEGY 3
|
#define MAX_STRATEGY 3
|
||||||
|
|
||||||
// free eventually allocated BigBuf memory
|
|
||||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
LED_A_ON();
|
|
||||||
|
|
||||||
if (first_try)
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||||
|
|
||||||
|
AppendCrc14443a(mf_auth, 2);
|
||||||
|
|
||||||
if (first_try) {
|
if (first_try) {
|
||||||
sync_time = GetCountSspClk() & 0xfffffff8;
|
sync_time = GetCountSspClk() & 0xfffffff8;
|
||||||
sync_cycles = PRNG_SEQUENCE_LENGTH + 1100; //65536; //0x10000 // theory: Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
|
sync_cycles = PRNG_SEQUENCE_LENGTH + 1130; //65536; //0x10000 // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
|
||||||
mf_nr_ar3 = 0;
|
mf_nr_ar3 = 0;
|
||||||
nt_attacked = 0;
|
nt_attacked = 0;
|
||||||
|
par_low = 0;
|
||||||
|
|
||||||
|
Dbprintf("FIRST: sync_time - %08X", sync_time);
|
||||||
} else {
|
} else {
|
||||||
// we were unsuccessful on a previous call.
|
// we were unsuccessful on a previous call.
|
||||||
// Try another READER nonce (first 3 parity bits remain the same)
|
// Try another READER nonce (first 3 parity bits remain the same)
|
||||||
|
@ -2272,9 +2225,12 @@ void ReaderMifare(bool first_try, uint8_t block )
|
||||||
par[0] = par_low;
|
par[0] = par_low;
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_A_ON();
|
bool have_uid = FALSE;
|
||||||
|
uint8_t cascade_levels = 0;
|
||||||
|
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
for(uint16_t i = 0; TRUE; ++i) {
|
uint16_t i;
|
||||||
|
for(i = 0; TRUE; ++i) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
@ -2284,98 +2240,98 @@ void ReaderMifare(bool first_try, uint8_t block )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strategy == 2) {
|
// this part is from Piwi's faster nonce collecting part in Hardnested.
|
||||||
// test with additional halt command
|
if (!have_uid) { // need a full select cycle to get the uid first
|
||||||
halt_time = 0;
|
iso14a_card_select_t card_info;
|
||||||
int len = mifare_sendcmd_short(NULL, false, 0x50, 0x00, receivedAnswer, receivedAnswerPar, &halt_time);
|
if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {
|
||||||
|
if (MF_DBGLEVEL >= 4) Dbprintf("Mifare: Can't select card (ALL)");
|
||||||
if (len && MF_DBGLEVEL >= 3)
|
break;
|
||||||
Dbprintf("Unexpected response of %d bytes to halt command.", len);
|
|
||||||
}
|
}
|
||||||
|
switch (card_info.uidlen) {
|
||||||
if (strategy == 3) {
|
case 4 : cascade_levels = 1; break;
|
||||||
// test with FPGA power off/on
|
case 7 : cascade_levels = 2; break;
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
case 10: cascade_levels = 3; break;
|
||||||
SpinDelay(200);
|
default: break;
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
|
||||||
SpinDelay(100);
|
|
||||||
sync_time = GetCountSspClk() & 0xfffffff8;
|
|
||||||
WDT_HIT();
|
|
||||||
}
|
}
|
||||||
|
have_uid = TRUE;
|
||||||
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
} else { // no need for anticollision. We can directly select the card
|
||||||
if (MF_DBGLEVEL >= 2) Dbprintf("Mifare: Can't select card\n");
|
if(!iso14443a_select_card(uid, NULL, &cuid, false, cascade_levels)) {
|
||||||
|
if (MF_DBGLEVEL >= 4) Dbprintf("Mifare: Can't select card (UID)");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sending timeslot of ISO14443a frame
|
// Sending timeslot of ISO14443a frame
|
||||||
|
sync_time = (sync_time & 0xfffffff8 ) + sync_cycles + catch_up_cycles;
|
||||||
sync_time = (sync_time & 0xfffffff8) + sync_cycles + catch_up_cycles;
|
|
||||||
catch_up_cycles = 0;
|
catch_up_cycles = 0;
|
||||||
|
|
||||||
//catch_up_cycles = 0;
|
|
||||||
|
|
||||||
// if we missed the sync time already, advance to the next nonce repeat
|
// if we missed the sync time already, advance to the next nonce repeat
|
||||||
while(GetCountSspClk() > sync_time) {
|
while( GetCountSspClk() > sync_time) {
|
||||||
++elapsed_prng_sequences;
|
++elapsed_prng_sequences;
|
||||||
sync_time = (sync_time & 0xfffffff8) + sync_cycles;
|
sync_time = (sync_time & 0xfffffff8 ) + sync_cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked)
|
// Transmit MIFARE_CLASSIC_AUTH at synctime. Should result in returning the same tag nonce (== nt_attacked)
|
||||||
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
|
ReaderTransmit(mf_auth, sizeof(mf_auth), &sync_time);
|
||||||
|
|
||||||
// Receive the (4 Byte) "random" nonce
|
// Receive the (4 Byte) "random" nonce from TAG
|
||||||
if (!ReaderReceive(receivedAnswer, receivedAnswerPar))
|
if (!ReaderReceive(receivedAnswer, receivedAnswerPar))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Transmit reader nonce with fake par
|
|
||||||
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
|
|
||||||
|
|
||||||
previous_nt = nt;
|
previous_nt = nt;
|
||||||
nt = bytes_to_num(receivedAnswer, 4);
|
nt = bytes_to_num(receivedAnswer, 4);
|
||||||
|
|
||||||
|
// Transmit reader nonce with fake par
|
||||||
|
ReaderTransmitPar(mf_nr_ar, sizeof(mf_nr_ar), par, NULL);
|
||||||
|
|
||||||
|
WDT_HIT();
|
||||||
|
LED_B_ON();
|
||||||
if (first_try && previous_nt && !nt_attacked) { // we didn't calibrate our clock yet
|
if (first_try && previous_nt && !nt_attacked) { // we didn't calibrate our clock yet
|
||||||
int nt_distance = dist_nt(previous_nt, nt);
|
|
||||||
|
nt_distance = dist_nt(previous_nt, nt);
|
||||||
|
|
||||||
|
// if no distance between, then we are in sync.
|
||||||
if (nt_distance == 0) {
|
if (nt_distance == 0) {
|
||||||
nt_attacked = nt;
|
nt_attacked = nt;
|
||||||
} else {
|
} else {
|
||||||
if (nt_distance == -99999) { // invalid nonce received
|
if (nt_distance == -99999) { // invalid nonce received
|
||||||
unexpected_random++;
|
++unexpected_random;
|
||||||
if (unexpected_random > MAX_UNEXPECTED_RANDOM) {
|
if (unexpected_random > MAX_UNEXPECTED_RANDOM) {
|
||||||
isOK = -3; // Card has an unpredictable PRNG. Give up
|
isOK = -3; // Card has an unpredictable PRNG. Give up
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
if (sync_cycles <= 0) sync_cycles += PRNG_SEQUENCE_LENGTH;
|
||||||
|
LED_B_OFF();
|
||||||
continue; // continue trying...
|
continue; // continue trying...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++sync_tries > MAX_SYNC_TRIES) {
|
if (++sync_tries > MAX_SYNC_TRIES) {
|
||||||
if (strategy > MAX_STRATEGY || MF_DBGLEVEL < 3) {
|
|
||||||
isOK = -4; // Card's PRNG runs at an unexpected frequency or resets unexpectedly
|
isOK = -4; // Card's PRNG runs at an unexpected frequency or resets unexpectedly
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_cycles = (sync_cycles - nt_distance)/elapsed_prng_sequences;
|
sync_cycles = (sync_cycles - nt_distance)/elapsed_prng_sequences;
|
||||||
|
|
||||||
if (sync_cycles <= 0)
|
if (sync_cycles <= 0)
|
||||||
sync_cycles += PRNG_SEQUENCE_LENGTH;
|
sync_cycles += PRNG_SEQUENCE_LENGTH;
|
||||||
|
|
||||||
if (MF_DBGLEVEL >= 3)
|
if (MF_DBGLEVEL >= 4)
|
||||||
Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles);
|
Dbprintf("calibrating in cycle %d. nt_distance=%d, elapsed_prng_sequences=%d, new sync_cycles: %d\n", i, nt_distance, elapsed_prng_sequences, sync_cycles);
|
||||||
|
|
||||||
|
LED_B_OFF();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LED_B_OFF();
|
||||||
|
|
||||||
if ((nt != nt_attacked) && nt_attacked) { // we somehow lost sync. Try to catch up again...
|
if ((nt != nt_attacked) && nt_attacked) { // we somehow lost sync. Try to catch up again...
|
||||||
|
|
||||||
catch_up_cycles = -dist_nt(nt_attacked, nt);
|
catch_up_cycles = ABS(dist_nt(nt_attacked, nt));
|
||||||
if (catch_up_cycles == 99999) { // invalid nonce received. Don't resync on that one.
|
if (catch_up_cycles == 99999) { // invalid nonce received. Don't resync on that one.
|
||||||
catch_up_cycles = 0;
|
catch_up_cycles = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// average?
|
// average?
|
||||||
catch_up_cycles /= elapsed_prng_sequences;
|
catch_up_cycles /= elapsed_prng_sequences;
|
||||||
|
|
||||||
|
@ -2387,13 +2343,13 @@ void ReaderMifare(bool first_try, uint8_t block )
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consecutive_resyncs < 3) {
|
if (consecutive_resyncs < 3) {
|
||||||
if (MF_DBGLEVEL >= 3)
|
if (MF_DBGLEVEL >= 4)
|
||||||
Dbprintf("Lost sync in cycle %d. nt_distance=%d. Consecutive Resyncs = %d. Trying one time catch up...\n", i, -catch_up_cycles, consecutive_resyncs);
|
Dbprintf("Lost sync in cycle %d. nt_distance=%d. Consecutive Resyncs = %d. Trying one time catch up...\n", i, catch_up_cycles, consecutive_resyncs);
|
||||||
} else {
|
} else {
|
||||||
sync_cycles += catch_up_cycles;
|
sync_cycles += catch_up_cycles;
|
||||||
|
|
||||||
if (MF_DBGLEVEL >= 3)
|
if (MF_DBGLEVEL >= 4)
|
||||||
Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, -catch_up_cycles, sync_cycles);
|
Dbprintf("Lost sync in cycle %d for the fourth time consecutively (nt_distance = %d). Adjusting sync_cycles to %d.\n", i, catch_up_cycles, sync_cycles);
|
||||||
|
|
||||||
last_catch_up = 0;
|
last_catch_up = 0;
|
||||||
catch_up_cycles = 0;
|
catch_up_cycles = 0;
|
||||||
|
@ -2403,14 +2359,14 @@ void ReaderMifare(bool first_try, uint8_t block )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
|
// Receive answer. This will be a 4 Bit NACK when the 8 parity bits are OK after decoding
|
||||||
if (!ReaderReceive(receivedAnswer, receivedAnswerPar)) {
|
if (ReaderReceive(receivedAnswer, receivedAnswerPar)) {
|
||||||
catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer
|
catch_up_cycles = 8; // the PRNG is delayed by 8 cycles due to the NAC (4Bits = 0x05 encrypted) transfer
|
||||||
|
|
||||||
if (nt_diff == 0)
|
if (nt_diff == 0)
|
||||||
par_low = par[0] & 0xE0; // there is no need to check all parities for other nt_diff. Parity Bits for mf_nr_ar[0..2] won't change
|
par_low = par[0] & 0xE0; // there is no need to check all parities for other nt_diff. Parity Bits for mf_nr_ar[0..2] won't change
|
||||||
|
|
||||||
par_list[nt_diff] = SwapBits(par[0], 8);
|
par_list[nt_diff] = SwapBits(par[0], 8);
|
||||||
ks_list[nt_diff] = receivedAnswer[0] ^ 0x05;
|
ks_list[nt_diff] = receivedAnswer[0] ^ 0x05; // xor with NACK value to get keystream
|
||||||
|
|
||||||
// Test if the information is complete
|
// Test if the information is complete
|
||||||
if (nt_diff == 0x07) {
|
if (nt_diff == 0x07) {
|
||||||
|
@ -2436,30 +2392,23 @@ void ReaderMifare(bool first_try, uint8_t block )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset the resyncs since we got a complete transaction on right time.
|
||||||
consecutive_resyncs = 0;
|
consecutive_resyncs = 0;
|
||||||
}
|
} // end for loop
|
||||||
|
|
||||||
mf_nr_ar[3] &= 0x1F;
|
mf_nr_ar[3] &= 0x1F;
|
||||||
|
|
||||||
WDT_HIT();
|
if (MF_DBGLEVEL >= 1) Dbprintf("\nNumber of sent auth requestes: %u", i);
|
||||||
|
|
||||||
// reset sync_time.
|
|
||||||
if ( isOK == 1) {
|
|
||||||
sync_time = 0;
|
|
||||||
sync_cycles = 0;
|
|
||||||
mf_nr_ar3 = 0;
|
|
||||||
nt_attacked = 0;
|
|
||||||
par[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t buf[28] = {0x00};
|
uint8_t buf[28] = {0x00};
|
||||||
|
memset(buf, 0x00, sizeof(buf));
|
||||||
num_to_bytes(cuid, 4, buf);
|
num_to_bytes(cuid, 4, buf);
|
||||||
num_to_bytes(nt, 4, buf + 4);
|
num_to_bytes(nt, 4, buf + 4);
|
||||||
memcpy(buf + 8, par_list, 8);
|
memcpy(buf + 8, par_list, 8);
|
||||||
memcpy(buf + 16, ks_list, 8);
|
memcpy(buf + 16, ks_list, 8);
|
||||||
memcpy(buf + 24, mf_nr_ar, 4);
|
memcpy(buf + 24, mf_nr_ar, 4);
|
||||||
|
|
||||||
cmd_send(CMD_ACK,isOK,0,0,buf,28);
|
cmd_send(CMD_ACK, isOK, 0, 0, buf, sizeof(buf) );
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
@ -2476,8 +2425,7 @@ void ReaderMifare(bool first_try, uint8_t block )
|
||||||
* FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later
|
* FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later
|
||||||
*@param exitAfterNReads, exit simulation after n blocks have been read, 0 is inifite
|
*@param exitAfterNReads, exit simulation after n blocks have been read, 0 is inifite
|
||||||
*/
|
*/
|
||||||
void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *datain)
|
void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *datain) {
|
||||||
{
|
|
||||||
int cardSTATE = MFEMUL_NOFIELD;
|
int cardSTATE = MFEMUL_NOFIELD;
|
||||||
int _7BUID = 0;
|
int _7BUID = 0;
|
||||||
int vHf = 0; // in mV
|
int vHf = 0; // in mV
|
||||||
|
@ -2951,9 +2899,6 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
|
||||||
LEDsoff();
|
|
||||||
|
|
||||||
// Interactive mode flag, means we need to send ACK
|
// Interactive mode flag, means we need to send ACK
|
||||||
if(flags & FLAG_INTERACTIVE) {
|
if(flags & FLAG_INTERACTIVE) {
|
||||||
//May just aswell send the collected ar_nr in the response aswell
|
//May just aswell send the collected ar_nr in the response aswell
|
||||||
|
@ -2998,6 +2943,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
}
|
}
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen());
|
if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen());
|
||||||
|
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LEDsoff();
|
||||||
set_tracing(FALSE);
|
set_tracing(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3014,14 +2961,10 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
|
|
||||||
// free eventually allocated BigBuf memory
|
// free eventually allocated BigBuf memory
|
||||||
BigBuf_free(); BigBuf_Clear_ext(false);
|
BigBuf_free(); BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
// init trace buffer
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
|
|
||||||
// The command (reader -> tag) that we're receiving.
|
// The command (reader -> tag) that we're receiving.
|
||||||
// The length of a received command will in most cases be no more than 18 bytes.
|
|
||||||
// So 32 should be enough!
|
|
||||||
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||||
uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
||||||
|
|
||||||
|
@ -3057,14 +3000,14 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
// And now we loop, receiving samples.
|
// And now we loop, receiving samples.
|
||||||
for(uint32_t sniffCounter = 0; TRUE; ) {
|
for(uint32_t sniffCounter = 0; TRUE; ) {
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
WDT_HIT();
|
||||||
|
|
||||||
if(BUTTON_PRESS()) {
|
if(BUTTON_PRESS()) {
|
||||||
DbpString("cancelled by button");
|
DbpString("cancelled by button");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LED_A_ON();
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
if ((sniffCounter & 0x0000FFFF) == 0) { // from time to time
|
if ((sniffCounter & 0x0000FFFF) == 0) { // from time to time
|
||||||
// check if a transaction is completed (timeout after 2000ms).
|
// check if a transaction is completed (timeout after 2000ms).
|
||||||
// if yes, stop the DMA transfer and send what we have so far to the client
|
// if yes, stop the DMA transfer and send what we have so far to the client
|
||||||
|
@ -3101,7 +3044,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
|
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
|
||||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
|
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
|
||||||
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
|
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
|
||||||
Dbprintf("RxEmpty ERROR!!! data length:%d", dataLen); // temporary
|
Dbprintf("RxEmpty ERROR, data length:%d", dataLen); // temporary
|
||||||
}
|
}
|
||||||
// secondary buffer sets as primary, secondary buffer was stopped
|
// secondary buffer sets as primary, secondary buffer was stopped
|
||||||
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
|
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
|
||||||
|
@ -3121,10 +3064,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
|
|
||||||
if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break;
|
if (MfSniffLogic(receivedCmd, Uart.len, Uart.parity, Uart.bitCount, TRUE)) break;
|
||||||
|
|
||||||
/* And ready to receive another command. */
|
|
||||||
UartInit(receivedCmd, receivedCmdPar);
|
UartInit(receivedCmd, receivedCmdPar);
|
||||||
|
|
||||||
/* And also reset the demod code */
|
|
||||||
DemodReset();
|
DemodReset();
|
||||||
}
|
}
|
||||||
ReaderIsActive = (Uart.state != STATE_UNSYNCD);
|
ReaderIsActive = (Uart.state != STATE_UNSYNCD);
|
||||||
|
@ -3138,10 +3078,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
|
|
||||||
if (MfSniffLogic(receivedResponse, Demod.len, Demod.parity, Demod.bitCount, FALSE)) break;
|
if (MfSniffLogic(receivedResponse, Demod.len, Demod.parity, Demod.bitCount, FALSE)) break;
|
||||||
|
|
||||||
// And ready to receive another response.
|
|
||||||
DemodReset();
|
DemodReset();
|
||||||
|
|
||||||
// And reset the Miller decoder including its (now outdated) input buffer
|
|
||||||
UartInit(receivedCmd, receivedCmdPar);
|
UartInit(receivedCmd, receivedCmdPar);
|
||||||
}
|
}
|
||||||
TagIsActive = (Demod.state != DEMOD_UNSYNCD);
|
TagIsActive = (Demod.state != DEMOD_UNSYNCD);
|
||||||
|
@ -3159,7 +3096,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
|
|
||||||
FpgaDisableSscDma();
|
FpgaDisableSscDma();
|
||||||
MfSniffEnd();
|
MfSniffEnd();
|
||||||
LEDsoff();
|
|
||||||
Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.len=%x", maxDataLen, Uart.state, Uart.len);
|
Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.len=%x", maxDataLen, Uart.state, Uart.len);
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LEDsoff();
|
||||||
set_tracing(FALSE);
|
set_tracing(FALSE);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue