mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-19 12:59:44 -07:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
5249ff940f
15 changed files with 671 additions and 540 deletions
39
Makefile
39
Makefile
|
@ -1,17 +1,40 @@
|
||||||
include common/Makefile.common
|
GZIP=gzip
|
||||||
|
# Windows' echo echos its input verbatim, on Posix there is some
|
||||||
|
# amount of shell command line parsing going on. echo "" on
|
||||||
|
# Windows yields literal "", on Linux yields an empty line
|
||||||
|
ifeq ($(shell echo ""),)
|
||||||
|
# This is probably a proper system, so we can use uname
|
||||||
|
DELETE=rm -rf
|
||||||
|
FLASH_TOOL=client/flasher
|
||||||
|
platform=$(shell uname)
|
||||||
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
|
FLASH_PORT=com3
|
||||||
|
PATHSEP=\\#
|
||||||
|
else
|
||||||
FLASH_PORT=/dev/ttyACM0
|
FLASH_PORT=/dev/ttyACM0
|
||||||
|
PATHSEP=/
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
# Assume that we are running on native Windows
|
||||||
|
DELETE=del /q
|
||||||
|
FLASH_TOOL=client/flasher.exe
|
||||||
|
platform=Windows
|
||||||
|
FLASH_PORT=com3
|
||||||
|
PATHSEP=\\#
|
||||||
|
endif
|
||||||
|
|
||||||
all clean: %: client/% bootrom/% armsrc/% recovery/%
|
all clean: %: client/% bootrom/% armsrc/% recovery/% mfkey/%
|
||||||
|
|
||||||
bootrom/%: FORCE
|
bootrom/%: FORCE
|
||||||
$(MAKE) -C bootrom $(patsubst bootrom/%,%,$@)
|
$(MAKE) -C bootrom $(patsubst bootrom/%, %, $@)
|
||||||
armsrc/%: FORCE
|
armsrc/%: FORCE
|
||||||
$(MAKE) -C armsrc $(patsubst armsrc/%,%,$@)
|
$(MAKE) -C armsrc $(patsubst armsrc/%, %, $@)
|
||||||
client/%: FORCE
|
client/%: FORCE
|
||||||
$(MAKE) -C client $(patsubst client/%,%,$@)
|
$(MAKE) -C client $(patsubst client/%, %, $@)
|
||||||
recovery/%: FORCE
|
recovery/%: FORCE
|
||||||
$(MAKE) -C recovery $(patsubst recovery/%,%,$@)
|
$(MAKE) -C recovery $(patsubst recovery/%, %, $@)
|
||||||
|
mfkey/%: FORCE
|
||||||
|
$(MAKE) -C tools/mfkey $(patsubst mfkey/%, %, $@)
|
||||||
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
||||||
|
|
||||||
.PHONY: all clean help _test flash-bootrom flash-os flash-all FORCE
|
.PHONY: all clean help _test flash-bootrom flash-os flash-all FORCE
|
||||||
|
@ -28,6 +51,8 @@ help:
|
||||||
|
|
||||||
client: client/all
|
client: client/all
|
||||||
|
|
||||||
|
mfkey: mfkey/all
|
||||||
|
|
||||||
flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL)
|
flash-bootrom: bootrom/obj/bootrom.elf $(FLASH_TOOL)
|
||||||
$(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<)
|
$(FLASH_TOOL) $(FLASH_PORT) -b $(subst /,$(PATHSEP),$<)
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,9 @@ RESOURCES:
|
||||||
-or-
|
-or-
|
||||||
http://webchat.freenode.net/?channels=#proxmark3
|
http://webchat.freenode.net/?channels=#proxmark3
|
||||||
|
|
||||||
|
* The Homebrew formula repository
|
||||||
|
https://github.com/Proxmark/homebrew-proxmark3
|
||||||
|
|
||||||
DEVELOPMENT:
|
DEVELOPMENT:
|
||||||
|
|
||||||
The tools required to build or run the project will vary depending on
|
The tools required to build or run the project will vary depending on
|
||||||
|
|
|
@ -450,7 +450,7 @@ void StandAloneMode14a()
|
||||||
SpinDelay(300);
|
SpinDelay(300);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid))
|
if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid, true, 0))
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -530,7 +530,7 @@ int EPA_Setup()
|
||||||
// power up the field
|
// power up the field
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
|
||||||
// select the card
|
// select the card
|
||||||
return_code = iso14443a_select_card(uid, &card_select_info, NULL);
|
return_code = iso14443a_select_card(uid, &card_select_info, NULL, true, 0);
|
||||||
if (return_code == 1) {
|
if (return_code == 1) {
|
||||||
// send the PPS request
|
// send the PPS request
|
||||||
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
|
ReaderTransmit((uint8_t *)pps, sizeof(pps), NULL);
|
||||||
|
|
|
@ -10,19 +10,74 @@
|
||||||
// Routines to support ISO 14443 type A.
|
// Routines to support ISO 14443 type A.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "iso14443a.h"
|
||||||
|
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "cmd.h"
|
#include "cmd.h"
|
||||||
#include "iso14443crc.h"
|
#include "iso14443crc.h"
|
||||||
#include "iso14443a.h"
|
|
||||||
#include "crapto1/crapto1.h"
|
#include "crapto1/crapto1.h"
|
||||||
#include "mifareutil.h"
|
#include "mifareutil.h"
|
||||||
|
#include "mifaresniff.h"
|
||||||
#include "BigBuf.h"
|
#include "BigBuf.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "parity.h"
|
#include "parity.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enum {
|
||||||
|
DEMOD_UNSYNCD,
|
||||||
|
// DEMOD_HALF_SYNCD,
|
||||||
|
// DEMOD_MOD_FIRST_HALF,
|
||||||
|
// DEMOD_NOMOD_FIRST_HALF,
|
||||||
|
DEMOD_MANCHESTER_DATA
|
||||||
|
} state;
|
||||||
|
uint16_t twoBits;
|
||||||
|
uint16_t highCnt;
|
||||||
|
uint16_t bitCount;
|
||||||
|
uint16_t collisionPos;
|
||||||
|
uint16_t syncBit;
|
||||||
|
uint8_t parityBits;
|
||||||
|
uint8_t parityLen;
|
||||||
|
uint16_t shiftReg;
|
||||||
|
uint16_t samples;
|
||||||
|
uint16_t len;
|
||||||
|
uint32_t startTime, endTime;
|
||||||
|
uint8_t *output;
|
||||||
|
uint8_t *parity;
|
||||||
|
} tDemod;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MOD_NOMOD = 0,
|
||||||
|
MOD_SECOND_HALF,
|
||||||
|
MOD_FIRST_HALF,
|
||||||
|
MOD_BOTH_HALVES
|
||||||
|
} Modulation_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
enum {
|
||||||
|
STATE_UNSYNCD,
|
||||||
|
STATE_START_OF_COMMUNICATION,
|
||||||
|
STATE_MILLER_X,
|
||||||
|
STATE_MILLER_Y,
|
||||||
|
STATE_MILLER_Z,
|
||||||
|
// DROP_NONE,
|
||||||
|
// DROP_FIRST_HALF,
|
||||||
|
} state;
|
||||||
|
uint16_t shiftReg;
|
||||||
|
int16_t bitCount;
|
||||||
|
uint16_t len;
|
||||||
|
uint16_t byteCntMax;
|
||||||
|
uint16_t posCnt;
|
||||||
|
uint16_t syncBit;
|
||||||
|
uint8_t parityBits;
|
||||||
|
uint8_t parityLen;
|
||||||
|
uint32_t fourBits;
|
||||||
|
uint32_t startTime, endTime;
|
||||||
|
uint8_t *output;
|
||||||
|
uint8_t *parity;
|
||||||
|
} tUart;
|
||||||
|
|
||||||
static uint32_t iso14a_timeout;
|
static uint32_t iso14a_timeout;
|
||||||
int rsamples = 0;
|
int rsamples = 0;
|
||||||
|
@ -37,7 +92,7 @@ static uint8_t iso14_pcb_blocknum = 0;
|
||||||
#define REQUEST_GUARD_TIME (7000/16 + 1)
|
#define REQUEST_GUARD_TIME (7000/16 + 1)
|
||||||
// minimum time between last modulation of tag and next start bit from reader to tag: 1172 carrier cycles
|
// minimum time between last modulation of tag and next start bit from reader to tag: 1172 carrier cycles
|
||||||
#define FRAME_DELAY_TIME_PICC_TO_PCD (1172/16 + 1)
|
#define FRAME_DELAY_TIME_PICC_TO_PCD (1172/16 + 1)
|
||||||
// bool LastCommandWasRequest = FALSE;
|
// bool LastCommandWasRequest = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Total delays including SSC-Transfers between ARM and FPGA. These are in carrier clock cycles (1/13,56MHz)
|
// Total delays including SSC-Transfers between ARM and FPGA. These are in carrier clock cycles (1/13,56MHz)
|
||||||
|
@ -125,7 +180,6 @@ static uint32_t LastProxToAirDuration;
|
||||||
#define SEC_Y 0x00
|
#define SEC_Y 0x00
|
||||||
#define SEC_Z 0xc0
|
#define SEC_Z 0xc0
|
||||||
|
|
||||||
|
|
||||||
void iso14a_set_trigger(bool enable) {
|
void iso14a_set_trigger(bool enable) {
|
||||||
trigger = enable;
|
trigger = enable;
|
||||||
}
|
}
|
||||||
|
@ -223,8 +277,8 @@ static tUart Uart;
|
||||||
// 0111 - a 2 tick wide pause shifted left
|
// 0111 - a 2 tick wide pause shifted left
|
||||||
// 1001 - a 2 tick wide pause shifted right
|
// 1001 - a 2 tick wide pause shifted right
|
||||||
const bool Mod_Miller_LUT[] = {
|
const bool Mod_Miller_LUT[] = {
|
||||||
FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE,
|
false, true, false, true, false, false, false, true,
|
||||||
FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
|
false, true, false, false, false, false, false, false
|
||||||
};
|
};
|
||||||
#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)])
|
||||||
|
@ -334,13 +388,13 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
|
||||||
Uart.parityBits <<= 1; // add a (void) parity bit
|
Uart.parityBits <<= 1; // add a (void) parity bit
|
||||||
Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align parity bits
|
Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align parity bits
|
||||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it
|
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store it
|
||||||
return TRUE;
|
return true;
|
||||||
} else if (Uart.len & 0x0007) { // there are some parity bits to store
|
} else if (Uart.len & 0x0007) { // there are some parity bits to store
|
||||||
Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align remaining parity bits
|
Uart.parityBits <<= (8 - (Uart.len&0x0007)); // left align remaining parity bits
|
||||||
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them
|
Uart.parity[Uart.parityLen++] = Uart.parityBits; // and store them
|
||||||
}
|
}
|
||||||
if (Uart.len) {
|
if (Uart.len) {
|
||||||
return TRUE; // we are finished with decoding the raw data sequence
|
return true; // we are finished with decoding the raw data sequence
|
||||||
} else {
|
} else {
|
||||||
UartReset(); // Nothing received - start over
|
UartReset(); // Nothing received - start over
|
||||||
}
|
}
|
||||||
|
@ -368,7 +422,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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -393,8 +447,8 @@ static tDemod Demod;
|
||||||
// Lookup-Table to decide if 4 raw bits are a modulation.
|
// Lookup-Table to decide if 4 raw bits are a modulation.
|
||||||
// We accept three or four "1" in any position
|
// We accept three or four "1" in any position
|
||||||
const bool Mod_Manchester_LUT[] = {
|
const bool Mod_Manchester_LUT[] = {
|
||||||
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,
|
false, false, false, false, false, false, false, true,
|
||||||
FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, TRUE, TRUE
|
false, false, false, true, false, true, true, true
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
|
#define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
|
||||||
|
@ -499,13 +553,13 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
|
||||||
Demod.parityBits <<= 1; // add a (void) parity bit
|
Demod.parityBits <<= 1; // add a (void) parity bit
|
||||||
Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits
|
Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits
|
||||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
|
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
|
||||||
return TRUE;
|
return true;
|
||||||
} else if (Demod.len & 0x0007) { // there are some parity bits to store
|
} else if (Demod.len & 0x0007) { // there are some parity bits to store
|
||||||
Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits
|
Demod.parityBits <<= (8 - (Demod.len&0x0007)); // left align remaining parity bits
|
||||||
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
|
Demod.parity[Demod.parityLen++] = Demod.parityBits; // and store them
|
||||||
}
|
}
|
||||||
if (Demod.len) {
|
if (Demod.len) {
|
||||||
return TRUE; // we are finished with decoding the raw data sequence
|
return true; // we are finished with decoding the raw data sequence
|
||||||
} else { // nothing received. Start over
|
} else { // nothing received. Start over
|
||||||
DemodReset();
|
DemodReset();
|
||||||
}
|
}
|
||||||
|
@ -514,7 +568,7 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FALSE; // not finished yet, need more data
|
return false; // not finished yet, need more data
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -553,14 +607,14 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
|
|
||||||
// init trace buffer
|
// init trace buffer
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(true);
|
||||||
|
|
||||||
uint8_t *data = dmaBuf;
|
uint8_t *data = dmaBuf;
|
||||||
uint8_t previous_data = 0;
|
uint8_t previous_data = 0;
|
||||||
int maxDataLen = 0;
|
int maxDataLen = 0;
|
||||||
int dataLen = 0;
|
int dataLen = 0;
|
||||||
bool TagIsActive = FALSE;
|
bool TagIsActive = false;
|
||||||
bool ReaderIsActive = FALSE;
|
bool ReaderIsActive = false;
|
||||||
|
|
||||||
// Set up the demodulator for tag -> reader responses.
|
// Set up the demodulator for tag -> reader responses.
|
||||||
DemodInit(receivedResponse, receivedResponsePar);
|
DemodInit(receivedResponse, receivedResponsePar);
|
||||||
|
@ -574,11 +628,11 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
// We won't start recording the frames that we acquire until we trigger;
|
// We won't start recording the frames that we acquire until we trigger;
|
||||||
// a good trigger condition to get started is probably when we see a
|
// a good trigger condition to get started is probably when we see a
|
||||||
// response from the tag.
|
// response from the tag.
|
||||||
// triggered == FALSE -- to wait first for card
|
// triggered == false -- to wait first for card
|
||||||
bool triggered = !(param & 0x03);
|
bool triggered = !(param & 0x03);
|
||||||
|
|
||||||
// And now we loop, receiving samples.
|
// And now we loop, receiving samples.
|
||||||
for(uint32_t rsamples = 0; TRUE; ) {
|
for(uint32_t rsamples = 0; true; ) {
|
||||||
|
|
||||||
if(BUTTON_PRESS()) {
|
if(BUTTON_PRESS()) {
|
||||||
DbpString("cancelled by button");
|
DbpString("cancelled by button");
|
||||||
|
@ -627,7 +681,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
|
|
||||||
// check - if there is a short 7bit request from reader
|
// check - if there is a short 7bit request from reader
|
||||||
if ((!triggered) && (param & 0x02) && (Uart.len == 1) && (Uart.bitCount == 7)) triggered = TRUE;
|
if ((!triggered) && (param & 0x02) && (Uart.len == 1) && (Uart.bitCount == 7)) triggered = true;
|
||||||
|
|
||||||
if(triggered) {
|
if(triggered) {
|
||||||
if (!LogTrace(receivedCmd,
|
if (!LogTrace(receivedCmd,
|
||||||
|
@ -635,7 +689,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
Uart.startTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
||||||
Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
||||||
Uart.parity,
|
Uart.parity,
|
||||||
TRUE)) break;
|
true)) break;
|
||||||
}
|
}
|
||||||
/* And ready to receive another command. */
|
/* And ready to receive another command. */
|
||||||
UartReset();
|
UartReset();
|
||||||
|
@ -657,9 +711,9 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
||||||
Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
Demod.startTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
||||||
Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
Demod.endTime*16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
||||||
Demod.parity,
|
Demod.parity,
|
||||||
FALSE)) break;
|
false)) break;
|
||||||
|
|
||||||
if ((!triggered) && (param & 0x01)) triggered = TRUE;
|
if ((!triggered) && (param & 0x01)) triggered = true;
|
||||||
|
|
||||||
// And ready to receive another response.
|
// And ready to receive another response.
|
||||||
DemodReset();
|
DemodReset();
|
||||||
|
@ -789,7 +843,7 @@ static void Code4bitAnswerAsTag(uint8_t cmd)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Wait for commands from reader
|
// Wait for commands from reader
|
||||||
// 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)
|
||||||
{
|
{
|
||||||
|
@ -808,13 +862,13 @@ static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int
|
||||||
for(;;) {
|
for(;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if(BUTTON_PRESS()) return FALSE;
|
if(BUTTON_PRESS()) return false;
|
||||||
|
|
||||||
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
if(MillerDecoding(b, 0)) {
|
if(MillerDecoding(b, 0)) {
|
||||||
*len = Uart.len;
|
*len = Uart.len;
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1024,7 +1078,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(true);
|
||||||
|
|
||||||
// Prepare the responses of the anticollision phase
|
// Prepare the responses of the anticollision phase
|
||||||
// there will be not enough time to do this at the moment the reader sends it REQA
|
// there will be not enough time to do this at the moment the reader sends it REQA
|
||||||
|
@ -1078,7 +1132,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
} else if(receivedCmd[0] == 0x50) { // Received a HALT
|
} else if(receivedCmd[0] == 0x50) { // Received a HALT
|
||||||
|
|
||||||
if (tracing) {
|
if (tracing) {
|
||||||
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
}
|
}
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
} else if(receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61) { // Received an authentication request
|
} else if(receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61) { // Received an authentication request
|
||||||
|
@ -1092,7 +1146,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
}
|
}
|
||||||
} else if (order == 7 && len == 8) { // Received {nr] and {ar} (part of authentication)
|
} else if (order == 7 && len == 8) { // Received {nr] and {ar} (part of authentication)
|
||||||
if (tracing) {
|
if (tracing) {
|
||||||
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
}
|
}
|
||||||
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);
|
||||||
|
@ -1136,7 +1190,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
default: {
|
default: {
|
||||||
// Never seen this command before
|
// Never seen this command before
|
||||||
if (tracing) {
|
if (tracing) {
|
||||||
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
}
|
}
|
||||||
Dbprintf("Received unknown command (len=%d):",len);
|
Dbprintf("Received unknown command (len=%d):",len);
|
||||||
Dbhexdump(len,receivedCmd,false);
|
Dbhexdump(len,receivedCmd,false);
|
||||||
|
@ -1156,7 +1210,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
|
if (prepare_tag_modulation(&dynamic_response_info,DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
|
||||||
Dbprintf("Error preparing tag response");
|
Dbprintf("Error preparing tag response");
|
||||||
if (tracing) {
|
if (tracing) {
|
||||||
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(receivedCmd, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1450,7 +1504,7 @@ static int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen, bool correctionNe
|
||||||
|
|
||||||
// include correction bit if necessary
|
// include correction bit if necessary
|
||||||
if (Uart.parityBits & 0x01) {
|
if (Uart.parityBits & 0x01) {
|
||||||
correctionNeeded = TRUE;
|
correctionNeeded = true;
|
||||||
}
|
}
|
||||||
if(correctionNeeded) {
|
if(correctionNeeded) {
|
||||||
// 1236, so correction bit needed
|
// 1236, so correction bit needed
|
||||||
|
@ -1571,18 +1625,18 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start
|
||||||
uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20;
|
uint16_t exact_fdt = (approx_fdt - 20 + 32)/64 * 64 + 20;
|
||||||
reader_EndTime = tag_StartTime - exact_fdt;
|
reader_EndTime = tag_StartTime - exact_fdt;
|
||||||
reader_StartTime = reader_EndTime - reader_modlen;
|
reader_StartTime = reader_EndTime - reader_modlen;
|
||||||
if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, TRUE)) {
|
if (!LogTrace(reader_data, reader_len, reader_StartTime, reader_EndTime, reader_Parity, true)) {
|
||||||
return FALSE;
|
return false;
|
||||||
} else return(!LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, FALSE));
|
} else return(!LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, false));
|
||||||
} else {
|
} else {
|
||||||
return TRUE;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Wait a certain time for tag response
|
// Wait a certain time for tag response
|
||||||
// If a response is captured return TRUE
|
// If a response is captured return true
|
||||||
// If it takes too long return FALSE
|
// If it takes too long return false
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
|
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
|
||||||
{
|
{
|
||||||
|
@ -1608,9 +1662,9 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
|
||||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
if(ManchesterDecoding(b, offset, 0)) {
|
if(ManchesterDecoding(b, offset, 0)) {
|
||||||
NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD);
|
NextTransferTime = MAX(NextTransferTime, Demod.endTime - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER)/16 + FRAME_DELAY_TIME_PICC_TO_PCD);
|
||||||
return TRUE;
|
return true;
|
||||||
} else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) {
|
} else if (c++ > iso14a_timeout && Demod.state == DEMOD_UNSYNCD) {
|
||||||
return FALSE;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1628,7 +1682,7 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t
|
||||||
|
|
||||||
// Log reader command in trace buffer
|
// Log reader command in trace buffer
|
||||||
if (tracing) {
|
if (tracing) {
|
||||||
LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, TRUE);
|
LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1658,26 +1712,28 @@ void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
|
||||||
|
|
||||||
int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
|
int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
|
||||||
{
|
{
|
||||||
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return FALSE;
|
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) 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);
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
return Demod.len;
|
return Demod.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* performs iso14443a anticollision procedure
|
// performs iso14443a anticollision (optional) and card select procedure
|
||||||
* fills the uid pointer unless NULL
|
// fills the uid and cuid pointer unless NULL
|
||||||
* fills resp_data unless NULL */
|
// fills the card info record unless NULL
|
||||||
int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr) {
|
// if anticollision is false, then the UID must be provided in uid_ptr[]
|
||||||
|
// and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID)
|
||||||
|
int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades) {
|
||||||
uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP
|
uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP
|
||||||
uint8_t sel_all[] = { 0x93,0x20 };
|
uint8_t sel_all[] = { 0x93,0x20 };
|
||||||
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
|
||||||
|
@ -1692,7 +1748,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
|
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
|
||||||
ReaderTransmitBitsPar(wupa,7,0, NULL);
|
ReaderTransmitBitsPar(wupa, 7, NULL, NULL);
|
||||||
|
|
||||||
// Receive the ATQA
|
// Receive the ATQA
|
||||||
if(!ReaderReceive(resp, resp_par)) return 0;
|
if(!ReaderReceive(resp, resp_par)) return 0;
|
||||||
|
@ -1703,10 +1759,12 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
memset(p_hi14a_card->uid,0,10);
|
memset(p_hi14a_card->uid,0,10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (anticollision) {
|
||||||
// clear uid
|
// clear uid
|
||||||
if (uid_ptr) {
|
if (uid_ptr) {
|
||||||
memset(uid_ptr,0,10);
|
memset(uid_ptr,0,10);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check for proprietary anticollision:
|
// check for proprietary anticollision:
|
||||||
if ((resp[0] & 0x1F) == 0) {
|
if ((resp[0] & 0x1F) == 0) {
|
||||||
|
@ -1720,6 +1778,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
// SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97)
|
// SELECT_* (L1: 0x93, L2: 0x95, L3: 0x97)
|
||||||
sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2;
|
sel_uid[0] = sel_all[0] = 0x93 + cascade_level * 2;
|
||||||
|
|
||||||
|
if (anticollision) {
|
||||||
// SELECT_ALL
|
// SELECT_ALL
|
||||||
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
|
ReaderTransmit(sel_all, sizeof(sel_all), NULL);
|
||||||
if (!ReaderReceive(resp, resp_par)) return 0;
|
if (!ReaderReceive(resp, resp_par)) return 0;
|
||||||
|
@ -1755,6 +1814,14 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
} else { // no collision, use the response to SELECT_ALL as current uid
|
} else { // no collision, use the response to SELECT_ALL as current uid
|
||||||
memcpy(uid_resp, resp, 4);
|
memcpy(uid_resp, resp, 4);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (cascade_level < num_cascades - 1) {
|
||||||
|
uid_resp[0] = 0x88;
|
||||||
|
memcpy(uid_resp+1, uid_ptr+cascade_level*3, 3);
|
||||||
|
} else {
|
||||||
|
memcpy(uid_resp, uid_ptr+cascade_level*3, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
uid_resp_len = 4;
|
uid_resp_len = 4;
|
||||||
|
|
||||||
// calculate crypto UID. Always use last 4 Bytes.
|
// calculate crypto UID. Always use last 4 Bytes.
|
||||||
|
@ -1764,7 +1831,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
|
|
||||||
// Construct SELECT UID command
|
// Construct SELECT UID command
|
||||||
sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
|
sel_uid[1] = 0x70; // transmitting a full UID (1 Byte cmd, 1 Byte NVB, 4 Byte UID, 1 Byte BCC, 2 Bytes CRC)
|
||||||
memcpy(sel_uid+2, uid_resp, 4); // the UID
|
memcpy(sel_uid+2, uid_resp, 4); // the UID received during anticollision, or the provided UID
|
||||||
sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC
|
sel_uid[6] = sel_uid[2] ^ sel_uid[3] ^ sel_uid[4] ^ sel_uid[5]; // calculate and add BCC
|
||||||
AppendCrc14443a(sel_uid, 7); // calculate and add CRC
|
AppendCrc14443a(sel_uid, 7); // calculate and add CRC
|
||||||
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
|
ReaderTransmit(sel_uid, sizeof(sel_uid), NULL);
|
||||||
|
@ -1780,11 +1847,10 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||||
uid_resp[0] = uid_resp[1];
|
uid_resp[0] = uid_resp[1];
|
||||||
uid_resp[1] = uid_resp[2];
|
uid_resp[1] = uid_resp[2];
|
||||||
uid_resp[2] = uid_resp[3];
|
uid_resp[2] = uid_resp[3];
|
||||||
|
|
||||||
uid_resp_len = 3;
|
uid_resp_len = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uid_ptr) {
|
if(uid_ptr && anticollision) {
|
||||||
memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
|
memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1895,17 +1961,17 @@ void ReaderIso14443a(UsbCommand *c)
|
||||||
clear_trace();
|
clear_trace();
|
||||||
}
|
}
|
||||||
|
|
||||||
set_tracing(TRUE);
|
set_tracing(true);
|
||||||
|
|
||||||
if(param & ISO14A_REQUEST_TRIGGER) {
|
if(param & ISO14A_REQUEST_TRIGGER) {
|
||||||
iso14a_set_trigger(TRUE);
|
iso14a_set_trigger(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(param & ISO14A_CONNECT) {
|
if(param & ISO14A_CONNECT) {
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
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);
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1959,7 +2025,7 @@ 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) {
|
||||||
|
@ -2019,12 +2085,12 @@ void ReaderMifare(bool first_try)
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(true);
|
||||||
|
|
||||||
byte_t nt_diff = 0;
|
byte_t nt_diff = 0;
|
||||||
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
|
||||||
static byte_t par_low = 0;
|
static byte_t par_low = 0;
|
||||||
bool led_on = TRUE;
|
bool led_on = true;
|
||||||
uint8_t uid[10] ={0};
|
uint8_t uid[10] ={0};
|
||||||
uint32_t cuid;
|
uint32_t cuid;
|
||||||
|
|
||||||
|
@ -2074,7 +2140,7 @@ void ReaderMifare(bool first_try)
|
||||||
uint32_t select_time;
|
uint32_t select_time;
|
||||||
uint32_t halt_time;
|
uint32_t halt_time;
|
||||||
|
|
||||||
for(uint16_t i = 0; TRUE; i++) {
|
for(uint16_t i = 0; true; i++) {
|
||||||
|
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -2102,7 +2168,7 @@ void ReaderMifare(bool first_try)
|
||||||
SpinDelay(100);
|
SpinDelay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Mifare: Can't select card");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2283,7 +2349,7 @@ void ReaderMifare(bool first_try)
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
|
||||||
set_tracing(FALSE);
|
set_tracing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -2481,9 +2547,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
|
|
||||||
// clear trace
|
// clear trace
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(true);
|
||||||
|
|
||||||
bool finished = FALSE;
|
bool finished = false;
|
||||||
bool button_pushed = BUTTON_PRESS();
|
bool button_pushed = BUTTON_PRESS();
|
||||||
while (!button_pushed && !finished && !usb_poll_validate_length()) {
|
while (!button_pushed && !finished && !usb_poll_validate_length()) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -2529,7 +2595,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
case MFEMUL_NOFIELD:
|
case MFEMUL_NOFIELD:
|
||||||
case MFEMUL_HALTED:
|
case MFEMUL_HALTED:
|
||||||
case MFEMUL_IDLE:{
|
case MFEMUL_IDLE:{
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MFEMUL_SELECT1:{
|
case MFEMUL_SELECT1:{
|
||||||
|
@ -2570,7 +2636,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
}
|
}
|
||||||
case MFEMUL_SELECT3:{
|
case MFEMUL_SELECT3:{
|
||||||
if (!len) {
|
if (!len) {
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// select all cl3 - 0x97 0x20
|
// select all cl3 - 0x97 0x20
|
||||||
|
@ -2596,7 +2662,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
case MFEMUL_AUTH1:{
|
case MFEMUL_AUTH1:{
|
||||||
if( len != 8) {
|
if( len != 8) {
|
||||||
cardSTATE_TO_IDLE();
|
cardSTATE_TO_IDLE();
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2679,7 +2745,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
// reader to do a WUPA after a while. /Martin
|
// reader to do a WUPA after a while. /Martin
|
||||||
// -- which is the correct response. /piwi
|
// -- which is the correct response. /piwi
|
||||||
cardSTATE_TO_IDLE();
|
cardSTATE_TO_IDLE();
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2698,7 +2764,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
}
|
}
|
||||||
case MFEMUL_SELECT2:{
|
case MFEMUL_SELECT2:{
|
||||||
if (!len) {
|
if (!len) {
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// select all cl2 - 0x95 0x20
|
// select all cl2 - 0x95 0x20
|
||||||
|
@ -2728,7 +2794,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
|
|
||||||
// i guess there is a command). go into the work state.
|
// i guess there is a command). go into the work state.
|
||||||
if (len != 4) {
|
if (len != 4) {
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cardSTATE = MFEMUL_WORK;
|
cardSTATE = MFEMUL_WORK;
|
||||||
|
@ -2738,7 +2804,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
|
|
||||||
case MFEMUL_WORK:{
|
case MFEMUL_WORK:{
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2798,7 +2864,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
}
|
}
|
||||||
|
|
||||||
if(len != 4) {
|
if(len != 4) {
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2877,7 +2943,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
cardSTATE = MFEMUL_HALTED;
|
cardSTATE = MFEMUL_HALTED;
|
||||||
if (MF_DBGLEVEL >= 4) Dbprintf("--> HALTED. Selected time: %d ms", GetTickCount() - selTimer);
|
if (MF_DBGLEVEL >= 4) Dbprintf("--> HALTED. Selected time: %d ms", GetTickCount() - selTimer);
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// RATS
|
// RATS
|
||||||
|
@ -2898,7 +2964,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
cardSTATE = MFEMUL_WORK;
|
cardSTATE = MFEMUL_WORK;
|
||||||
} else {
|
} else {
|
||||||
cardSTATE_TO_IDLE();
|
cardSTATE_TO_IDLE();
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2911,7 +2977,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
cardSTATE_TO_IDLE();
|
cardSTATE_TO_IDLE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
cardINTREG = cardINTREG + ans;
|
cardINTREG = cardINTREG + ans;
|
||||||
cardSTATE = MFEMUL_WORK;
|
cardSTATE = MFEMUL_WORK;
|
||||||
break;
|
break;
|
||||||
|
@ -2924,7 +2990,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
cardSTATE_TO_IDLE();
|
cardSTATE_TO_IDLE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
cardINTREG = cardINTREG - ans;
|
cardINTREG = cardINTREG - ans;
|
||||||
cardSTATE = MFEMUL_WORK;
|
cardSTATE = MFEMUL_WORK;
|
||||||
break;
|
break;
|
||||||
|
@ -2937,7 +3003,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
||||||
cardSTATE_TO_IDLE();
|
cardSTATE_TO_IDLE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, TRUE);
|
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
cardSTATE = MFEMUL_WORK;
|
cardSTATE = MFEMUL_WORK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2999,7 +3065,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
// init trace buffer
|
// 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.
|
// The length of a received command will in most cases be no more than 18 bytes.
|
||||||
|
@ -3020,8 +3086,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
uint8_t previous_data = 0;
|
uint8_t previous_data = 0;
|
||||||
int maxDataLen = 0;
|
int maxDataLen = 0;
|
||||||
int dataLen = 0;
|
int dataLen = 0;
|
||||||
bool ReaderIsActive = FALSE;
|
bool ReaderIsActive = false;
|
||||||
bool TagIsActive = FALSE;
|
bool TagIsActive = false;
|
||||||
|
|
||||||
// Set up the demodulator for tag -> reader responses.
|
// Set up the demodulator for tag -> reader responses.
|
||||||
DemodInit(receivedResponse, receivedResponsePar);
|
DemodInit(receivedResponse, receivedResponsePar);
|
||||||
|
@ -3038,7 +3104,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
MfSniffInit();
|
MfSniffInit();
|
||||||
|
|
||||||
// And now we loop, receiving samples.
|
// And now we loop, receiving samples.
|
||||||
for(uint32_t sniffCounter = 0; TRUE; ) {
|
for(uint32_t sniffCounter = 0; true; ) {
|
||||||
|
|
||||||
if(BUTTON_PRESS()) {
|
if(BUTTON_PRESS()) {
|
||||||
DbpString("cancelled by button");
|
DbpString("cancelled by button");
|
||||||
|
@ -3056,8 +3122,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
sniffCounter = 0;
|
sniffCounter = 0;
|
||||||
data = dmaBuf;
|
data = dmaBuf;
|
||||||
maxDataLen = 0;
|
maxDataLen = 0;
|
||||||
ReaderIsActive = FALSE;
|
ReaderIsActive = false;
|
||||||
TagIsActive = FALSE;
|
TagIsActive = false;
|
||||||
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
|
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // set transfer address and number of bytes. Start transfer.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3099,7 +3165,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
|
uint8_t readerdata = (previous_data & 0xF0) | (*data >> 4);
|
||||||
if(MillerDecoding(readerdata, (sniffCounter-1)*4)) {
|
if(MillerDecoding(readerdata, (sniffCounter-1)*4)) {
|
||||||
LED_C_INV();
|
LED_C_INV();
|
||||||
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. */
|
/* And ready to receive another command. */
|
||||||
UartInit(receivedCmd, receivedCmdPar);
|
UartInit(receivedCmd, receivedCmdPar);
|
||||||
|
@ -3115,7 +3181,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
||||||
if(ManchesterDecoding(tagdata, 0, (sniffCounter-1)*4)) {
|
if(ManchesterDecoding(tagdata, 0, (sniffCounter-1)*4)) {
|
||||||
LED_C_INV();
|
LED_C_INV();
|
||||||
|
|
||||||
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.
|
// And ready to receive another response.
|
||||||
DemodReset();
|
DemodReset();
|
||||||
|
|
|
@ -13,63 +13,9 @@
|
||||||
#ifndef __ISO14443A_H
|
#ifndef __ISO14443A_H
|
||||||
#define __ISO14443A_H
|
#define __ISO14443A_H
|
||||||
|
|
||||||
#include "common.h"
|
#include <stdint.h>
|
||||||
#include "mifaresniff.h"
|
#include <stdbool.h>
|
||||||
|
#include "mifare.h"
|
||||||
typedef struct {
|
|
||||||
enum {
|
|
||||||
DEMOD_UNSYNCD,
|
|
||||||
// DEMOD_HALF_SYNCD,
|
|
||||||
// DEMOD_MOD_FIRST_HALF,
|
|
||||||
// DEMOD_NOMOD_FIRST_HALF,
|
|
||||||
DEMOD_MANCHESTER_DATA
|
|
||||||
} state;
|
|
||||||
uint16_t twoBits;
|
|
||||||
uint16_t highCnt;
|
|
||||||
uint16_t bitCount;
|
|
||||||
uint16_t collisionPos;
|
|
||||||
uint16_t syncBit;
|
|
||||||
uint8_t parityBits;
|
|
||||||
uint8_t parityLen;
|
|
||||||
uint16_t shiftReg;
|
|
||||||
uint16_t samples;
|
|
||||||
uint16_t len;
|
|
||||||
uint32_t startTime, endTime;
|
|
||||||
uint8_t *output;
|
|
||||||
uint8_t *parity;
|
|
||||||
} tDemod;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
MOD_NOMOD = 0,
|
|
||||||
MOD_SECOND_HALF,
|
|
||||||
MOD_FIRST_HALF,
|
|
||||||
MOD_BOTH_HALVES
|
|
||||||
} Modulation_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
enum {
|
|
||||||
STATE_UNSYNCD,
|
|
||||||
STATE_START_OF_COMMUNICATION,
|
|
||||||
STATE_MILLER_X,
|
|
||||||
STATE_MILLER_Y,
|
|
||||||
STATE_MILLER_Z,
|
|
||||||
// DROP_NONE,
|
|
||||||
// DROP_FIRST_HALF,
|
|
||||||
} state;
|
|
||||||
uint16_t shiftReg;
|
|
||||||
int16_t bitCount;
|
|
||||||
uint16_t len;
|
|
||||||
uint16_t byteCntMax;
|
|
||||||
uint16_t posCnt;
|
|
||||||
uint16_t syncBit;
|
|
||||||
uint8_t parityBits;
|
|
||||||
uint8_t parityLen;
|
|
||||||
uint32_t fourBits;
|
|
||||||
uint32_t startTime, endTime;
|
|
||||||
uint8_t *output;
|
|
||||||
uint8_t *parity;
|
|
||||||
} tUart;
|
|
||||||
|
|
||||||
|
|
||||||
extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
|
extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
|
||||||
extern void AppendCrc14443a(uint8_t *data, int len);
|
extern void AppendCrc14443a(uint8_t *data, int len);
|
||||||
|
@ -81,7 +27,6 @@ extern int ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
|
||||||
|
|
||||||
extern void iso14443a_setup(uint8_t fpga_minor_mode);
|
extern void iso14443a_setup(uint8_t fpga_minor_mode);
|
||||||
extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
|
extern int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, void *data);
|
||||||
extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr);
|
extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_data, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades);
|
||||||
extern void iso14a_set_trigger(bool enable);
|
extern void iso14a_set_trigger(bool enable);
|
||||||
|
|
||||||
#endif /* __ISO14443A_H */
|
#endif /* __ISO14443A_H */
|
||||||
|
|
|
@ -14,13 +14,18 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#include "mifarecmd.h"
|
#include "mifarecmd.h"
|
||||||
|
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "parity.h"
|
#include "parity.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
|
||||||
|
#define AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
|
||||||
|
#define PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication
|
||||||
|
|
||||||
|
|
||||||
// the block number for the ISO14443-4 PCB
|
// the block number for the ISO14443-4 PCB
|
||||||
uint8_t pcb_blocknum = 0;
|
static uint8_t pcb_blocknum = 0;
|
||||||
// Deselect card by sending a s-block. the crc is precalced for speed
|
// Deselect card by sending a s-block. the crc is precalced for speed
|
||||||
static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
|
static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
|
||||||
|
|
||||||
|
@ -54,7 +59,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
@ -101,7 +106,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
if(!iso14443a_select_card(NULL, NULL, NULL)) {
|
if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -136,7 +141,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
int len = iso14443a_select_card(NULL, NULL, NULL);
|
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);
|
||||||
if(!len) {
|
if(!len) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
|
||||||
OnError(1);
|
OnError(1);
|
||||||
|
@ -212,7 +217,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
isOK = 1;
|
isOK = 1;
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
isOK = 0;
|
isOK = 0;
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
}
|
}
|
||||||
|
@ -276,7 +281,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = iso14443a_select_card(NULL, NULL, NULL);
|
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0);
|
||||||
if (!len) {
|
if (!len) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len);
|
||||||
OnError(1);
|
OnError(1);
|
||||||
|
@ -378,7 +383,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
@ -432,7 +437,7 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain)
|
||||||
clear_trace();
|
clear_trace();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, NULL)) {
|
if(!iso14443a_select_card(uid, NULL, NULL, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -478,7 +483,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
if(!iso14443a_select_card(NULL, NULL, NULL)) {
|
if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -537,7 +542,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
if(!iso14443a_select_card(NULL, NULL, NULL)) {
|
if(!iso14443a_select_card(NULL, NULL, NULL, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -602,6 +607,135 @@ int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// acquire encrypted nonces in order to perform the attack described in
|
||||||
|
// Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened
|
||||||
|
// Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on
|
||||||
|
// Computer and Communications Security, 2015
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)
|
||||||
|
{
|
||||||
|
uint64_t ui64Key = 0;
|
||||||
|
uint8_t uid[10];
|
||||||
|
uint32_t cuid;
|
||||||
|
uint8_t cascade_levels = 0;
|
||||||
|
struct Crypto1State mpcs = {0, 0};
|
||||||
|
struct Crypto1State *pcs;
|
||||||
|
pcs = &mpcs;
|
||||||
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
|
int16_t isOK = 0;
|
||||||
|
uint8_t par_enc[1];
|
||||||
|
uint8_t nt_par_enc = 0;
|
||||||
|
uint8_t buf[USB_CMD_DATA_SIZE];
|
||||||
|
uint32_t timeout;
|
||||||
|
|
||||||
|
uint8_t blockNo = arg0 & 0xff;
|
||||||
|
uint8_t keyType = (arg0 >> 8) & 0xff;
|
||||||
|
uint8_t targetBlockNo = arg1 & 0xff;
|
||||||
|
uint8_t targetKeyType = (arg1 >> 8) & 0xff;
|
||||||
|
ui64Key = bytes_to_num(datain, 6);
|
||||||
|
bool initialize = flags & 0x0001;
|
||||||
|
bool slow = flags & 0x0002;
|
||||||
|
bool field_off = flags & 0x0004;
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
LED_C_OFF();
|
||||||
|
|
||||||
|
if (initialize) {
|
||||||
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
clear_trace();
|
||||||
|
set_tracing(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_C_ON();
|
||||||
|
|
||||||
|
uint16_t num_nonces = 0;
|
||||||
|
bool have_uid = false;
|
||||||
|
for (uint16_t i = 0; i <= USB_CMD_DATA_SIZE - 9; ) {
|
||||||
|
|
||||||
|
// Test if the action was cancelled
|
||||||
|
if(BUTTON_PRESS()) {
|
||||||
|
isOK = 2;
|
||||||
|
field_off = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!have_uid) { // need a full select cycle to get the uid first
|
||||||
|
iso14a_card_select_t card_info;
|
||||||
|
if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {
|
||||||
|
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (card_info.uidlen) {
|
||||||
|
case 4 : cascade_levels = 1; break;
|
||||||
|
case 7 : cascade_levels = 2; break;
|
||||||
|
case 10: cascade_levels = 3; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
have_uid = true;
|
||||||
|
} else { // no need for anticollision. We can directly select the card
|
||||||
|
if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {
|
||||||
|
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slow) {
|
||||||
|
timeout = GetCountSspClk() + PRE_AUTHENTICATION_LEADTIME;
|
||||||
|
while(GetCountSspClk() < timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t nt1;
|
||||||
|
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) {
|
||||||
|
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth1 error");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// nested authentication
|
||||||
|
uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par_enc, NULL);
|
||||||
|
if (len != 4) {
|
||||||
|
if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth2 error len=%d", len);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send a dummy byte as reader response in order to trigger the cards authentication timeout
|
||||||
|
uint8_t dummy_answer = 0;
|
||||||
|
ReaderTransmit(&dummy_answer, 1, NULL);
|
||||||
|
timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT;
|
||||||
|
|
||||||
|
num_nonces++;
|
||||||
|
if (num_nonces % 2) {
|
||||||
|
memcpy(buf+i, receivedAnswer, 4);
|
||||||
|
nt_par_enc = par_enc[0] & 0xf0;
|
||||||
|
} else {
|
||||||
|
nt_par_enc |= par_enc[0] >> 4;
|
||||||
|
memcpy(buf+i+4, receivedAnswer, 4);
|
||||||
|
memcpy(buf+i+8, &nt_par_enc, 1);
|
||||||
|
i += 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for the card to become ready again
|
||||||
|
while(GetCountSspClk() < timeout);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_C_OFF();
|
||||||
|
|
||||||
|
crypto1_destroy(pcs);
|
||||||
|
|
||||||
|
LED_B_ON();
|
||||||
|
cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));
|
||||||
|
LED_B_OFF();
|
||||||
|
|
||||||
|
if (MF_DBGLEVEL >= 3) DbpString("AcquireEncryptedNonces finished");
|
||||||
|
|
||||||
|
if (field_off) {
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LEDsoff();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// MIFARE nested authentication.
|
// MIFARE nested authentication.
|
||||||
//
|
//
|
||||||
|
@ -673,7 +807,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");
|
||||||
rtr--;
|
rtr--;
|
||||||
continue;
|
continue;
|
||||||
|
@ -747,7 +881,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
@ -829,14 +963,15 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
{
|
{
|
||||||
// params
|
|
||||||
uint8_t blockNo = arg0 & 0xff;
|
uint8_t blockNo = arg0 & 0xff;
|
||||||
uint8_t keyType = (arg0 >> 8) & 0xff;
|
uint8_t keyType = (arg0 >> 8) & 0xff;
|
||||||
bool clearTrace = arg1;
|
bool clearTrace = arg1;
|
||||||
uint8_t keyCount = arg2;
|
uint8_t keyCount = arg2;
|
||||||
uint64_t ui64Key = 0;
|
uint64_t ui64Key = 0;
|
||||||
|
|
||||||
// variables
|
bool have_uid = false;
|
||||||
|
uint8_t cascade_levels = 0;
|
||||||
|
uint32_t timeout = 0;
|
||||||
int i;
|
int i;
|
||||||
byte_t isOK = 0;
|
byte_t isOK = 0;
|
||||||
uint8_t uid[10];
|
uint8_t uid[10];
|
||||||
|
@ -855,30 +990,51 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
if (clearTrace) clear_trace();
|
if (clearTrace) clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(true);
|
||||||
|
|
||||||
for (i = 0; i < keyCount; i++) {
|
for (i = 0; i < keyCount; i++) {
|
||||||
if(mifare_classic_halt(pcs, cuid)) {
|
// if(mifare_classic_halt(pcs, cuid)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Halt error");
|
// if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Halt error");
|
||||||
}
|
// }
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
// Iceman: use piwi's faster nonce collecting part in hardnested.
|
||||||
|
if (!have_uid) { // need a full select cycle to get the uid first
|
||||||
|
iso14a_card_select_t card_info;
|
||||||
|
if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0)) {
|
||||||
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card");
|
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card");
|
||||||
break;
|
--i; // try same key once again
|
||||||
};
|
continue;
|
||||||
|
}
|
||||||
|
switch (card_info.uidlen) {
|
||||||
|
case 4 : cascade_levels = 1; break;
|
||||||
|
case 7 : cascade_levels = 2; break;
|
||||||
|
case 10: cascade_levels = 3; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
have_uid = true;
|
||||||
|
} else { // no need for anticollision. We can directly select the card
|
||||||
|
if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels)) {
|
||||||
|
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (UID)");
|
||||||
|
--i; // try same key once again
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ui64Key = bytes_to_num(datain + i * 6, 6);
|
ui64Key = bytes_to_num(datain + i * 6, 6);
|
||||||
if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
|
if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
|
||||||
|
uint8_t dummy_answer = 0;
|
||||||
|
ReaderTransmit(&dummy_answer, 1, NULL);
|
||||||
|
timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT;
|
||||||
|
|
||||||
|
// wait for the card to become ready again
|
||||||
|
while(GetCountSspClk() < timeout);
|
||||||
continue;
|
continue;
|
||||||
};
|
}
|
||||||
|
|
||||||
isOK = 1;
|
isOK = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------- crypto1 destroy
|
|
||||||
crypto1_destroy(pcs);
|
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);
|
cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
@ -955,7 +1111,7 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
|
|
||||||
bool isOK = true;
|
bool isOK = true;
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
isOK = false;
|
isOK = false;
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
}
|
}
|
||||||
|
@ -1048,14 +1204,14 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
|
||||||
// get UID from chip
|
// get UID from chip
|
||||||
if (workFlags & 0x01) {
|
if (workFlags & 0x01) {
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
@ -1167,7 +1323,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -1260,7 +1416,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
int len = iso14443a_select_card(uid, NULL, &cuid);
|
int len = iso14443a_select_card(uid, NULL, &cuid, true, 0);
|
||||||
if(!len) {
|
if(!len) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
|
|
115
client/Makefile
115
client/Makefile
|
@ -3,11 +3,15 @@
|
||||||
# at your option, any later version. See the LICENSE.txt file for the text of
|
# at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
# the license.
|
# the license.
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
include ../common/Makefile.common
|
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
CXX = g++
|
||||||
|
LD = g++
|
||||||
|
TAR = tar
|
||||||
|
TARFLAGS = -C .. --ignore-failed-read -rvf
|
||||||
|
RM = rm -f
|
||||||
|
MV = mv
|
||||||
|
|
||||||
CC=gcc
|
|
||||||
CXX=g++
|
|
||||||
#COMMON_FLAGS = -m32
|
#COMMON_FLAGS = -m32
|
||||||
VPATH = ../common ../zlib
|
VPATH = ../common ../zlib
|
||||||
OBJDIR = obj
|
OBJDIR = obj
|
||||||
|
@ -15,46 +19,52 @@ OBJDIR = obj
|
||||||
LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
|
LDLIBS = -L/opt/local/lib -L/usr/local/lib -lreadline -lpthread -lm
|
||||||
LUALIB = ../liblua/liblua.a
|
LUALIB = ../liblua/liblua.a
|
||||||
LDFLAGS = $(COMMON_FLAGS)
|
LDFLAGS = $(COMMON_FLAGS)
|
||||||
CFLAGS = -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../tools -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
CFLAGS = -std=c99 -D_ISOC99_SOURCE -I. -I../include -I../common -I../zlib -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
||||||
LUAPLATFORM = generic
|
LUAPLATFORM = generic
|
||||||
|
|
||||||
|
platform = $(shell uname)
|
||||||
ifneq (,$(findstring MINGW,$(platform)))
|
ifneq (,$(findstring MINGW,$(platform)))
|
||||||
CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
|
CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
|
||||||
MOC = $(QTDIR)/bin/moc
|
|
||||||
LUAPLATFORM = mingw
|
|
||||||
ifneq ($(wildcard $(QTDIR)/include/QtWidgets),)
|
ifneq ($(wildcard $(QTDIR)/include/QtWidgets),)
|
||||||
CXXFLAGS += -I$(QTDIR)/include/QtWidgets
|
CXXFLAGS += -I$(QTDIR)/include/QtWidgets
|
||||||
QTLDLIBS = -L$(QTDIR)/lib -lQt5Core -lQt5Gui -lQt5Widgets
|
QTLDLIBS = -L$(QTDIR)/lib -lQt5Core -lQt5Gui -lQt5Widgets
|
||||||
else
|
else
|
||||||
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
|
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
|
||||||
endif
|
endif
|
||||||
else ifeq ($(platform),Darwin)
|
MOC = $(QTDIR)/bin/moc
|
||||||
|
LUAPLATFORM = mingw
|
||||||
|
else
|
||||||
|
CXXFLAGS = $(shell pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null) -Wall -O4
|
||||||
|
QTLDLIBS = $(shell pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null)
|
||||||
|
MOC = $(shell pkg-config --variable=host_bins Qt5Core)/moc
|
||||||
|
ifeq ($(QTLDLIBS), )
|
||||||
CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall -O4
|
CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall -O4
|
||||||
QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
|
QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
|
||||||
MOC = $(shell pkg-config --variable=moc_location QtCore)
|
MOC = $(shell pkg-config --variable=moc_location QtCore)
|
||||||
|
endif
|
||||||
|
ifeq ($(platform),Darwin)
|
||||||
LUAPLATFORM = macosx
|
LUAPLATFORM = macosx
|
||||||
else
|
else
|
||||||
CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall -O4
|
|
||||||
QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
|
|
||||||
LUALIB += -ldl
|
LUALIB += -ldl
|
||||||
LDLIBS += -ltermcap -lncurses
|
LDLIBS += -ltermcap -lncurses
|
||||||
MOC = $(shell pkg-config --variable=moc_location QtCore)
|
|
||||||
# Below is a variant you can use if you have problems compiling with QT5 on ubuntu. see http://www.proxmark.org/forum/viewtopic.php?id=1661 for more info.
|
|
||||||
#MOC = /usr/lib/x86_64-linux-gnu/qt4/bin/moc
|
|
||||||
LUAPLATFORM = linux
|
LUAPLATFORM = linux
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(QTLDLIBS),)
|
ifneq ($(QTLDLIBS),)
|
||||||
QTGUI = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
|
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
|
||||||
CFLAGS += -DHAVE_GUI
|
CFLAGS += -DHAVE_GUI
|
||||||
LINK.o = $(LINK.cpp)
|
|
||||||
else
|
else
|
||||||
QTGUI = guidummy.o
|
QTGUIOBJS = $(OBJDIR)/guidummy.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
CORESRCS = uart.c \
|
# Flags to generate temporary dependency files
|
||||||
util.c \
|
DEPFLAGS = -MT $@ -MMD -MP -MF $(OBJDIR)/$*.Td
|
||||||
|
# make temporary to final dependeny files after successful compilation
|
||||||
|
POSTCOMPILE = $(MV) -f $(OBJDIR)/$*.Td $(OBJDIR)/$*.d
|
||||||
|
|
||||||
|
CORESRCS = uart.c \
|
||||||
|
util.c
|
||||||
|
|
||||||
CMDSRCS = crapto1/crapto1.c\
|
CMDSRCS = crapto1/crapto1.c\
|
||||||
crapto1/crypto1.c\
|
crapto1/crypto1.c\
|
||||||
|
@ -129,57 +139,82 @@ CMDSRCS = crapto1/crapto1.c\
|
||||||
reveng/getopt.c\
|
reveng/getopt.c\
|
||||||
|
|
||||||
ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c
|
ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c
|
||||||
ZLIB_FLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
|
ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
|
||||||
#-DDEBUG -Dverbose=1
|
#-DDEBUG -Dverbose=1
|
||||||
|
|
||||||
|
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp
|
||||||
|
|
||||||
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
||||||
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
|
||||||
ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o)
|
ZLIBOBJS = $(ZLIBSRCS:%.c=$(OBJDIR)/%.o)
|
||||||
|
|
||||||
RM = rm -f
|
BINS = proxmark3 flasher fpga_compress
|
||||||
BINS = proxmark3 flasher fpga_compress #snooper cli
|
WINBINS = $(patsubst %, %.exe, $(BINS))
|
||||||
CLEAN = cli cli.exe flasher flasher.exe proxmark3 proxmark3.exe fpga_compress fpga_compress.exe snooper snooper.exe $(CMDOBJS) $(OBJDIR)/*.o *.o *.moc.cpp
|
CLEAN = $(BINS) $(WINBINS) $(COREOBJS) $(CMDOBJS) $(ZLIBOBJS) $(QTGUIOBJS) $(OBJDIR)/*.o *.moc.cpp
|
||||||
|
|
||||||
all: lua_build $(BINS)
|
all: lua_build $(BINS)
|
||||||
|
|
||||||
all-static: LDLIBS:=-static $(LDLIBS)
|
all-static: LDLIBS:=-static $(LDLIBS)
|
||||||
all-static: snooper cli flasher fpga_compress
|
all-static: proxmark3 flasher fpga_compress
|
||||||
|
|
||||||
proxmark3: LDLIBS+=$(LUALIB) $(QTLDLIBS)
|
proxmark3: LDLIBS+=$(LUALIB) $(QTLDLIBS)
|
||||||
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUI)
|
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) lualibs/usb_cmd.lua
|
||||||
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
|
$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(LDLIBS) -o $@
|
||||||
|
|
||||||
snooper: $(OBJDIR)/snooper.o $(COREOBJS) $(CMDOBJS) $(OBJDIR)/guidummy.o
|
|
||||||
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
|
|
||||||
|
|
||||||
cli: $(OBJDIR)/cli.o $(COREOBJS) $(CMDOBJS) $(OBJDIR)/guidummy.o
|
|
||||||
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
|
|
||||||
|
|
||||||
flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS)
|
flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS)
|
||||||
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
|
$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
fpga_compress: $(OBJDIR)/fpga_compress.o $(ZLIBOBJS)
|
fpga_compress: $(OBJDIR)/fpga_compress.o $(ZLIBOBJS)
|
||||||
$(CXX) $(CXXFLAGS) $(ZLIB_FLAGS) $^ $(LDLIBS) -o $@
|
$(LD) $(LDFLAGS) $(ZLIBFLAGS) $^ $(LDLIBS) -o $@
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.c
|
|
||||||
$(CC) $(CFLAGS) $(ZLIB_FLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
$(OBJDIR)/%.o: %.cpp
|
|
||||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
|
||||||
|
|
||||||
proxguiqt.moc.cpp: proxguiqt.h
|
proxguiqt.moc.cpp: proxguiqt.h
|
||||||
$(MOC) -o$@ $^
|
$(MOC) -o$@ $^
|
||||||
|
|
||||||
|
lualibs/usb_cmd.lua: ../include/usb_cmd.h
|
||||||
|
awk -f usb_cmd_h2lua.awk $^ > $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) $(CLEAN)
|
$(RM) $(CLEAN)
|
||||||
cd ../liblua && make clean
|
cd ../liblua && make clean
|
||||||
|
|
||||||
tarbin: $(BINS)
|
tarbin: $(BINS)
|
||||||
$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%)
|
$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(BINS:%=client/%) $(WINBINS:%=client/%)
|
||||||
|
|
||||||
lua_build:
|
lua_build:
|
||||||
@echo Compiling liblua, using platform $(LUAPLATFORM)
|
@echo Compiling liblua, using platform $(LUAPLATFORM)
|
||||||
cd ../liblua && make $(LUAPLATFORM)
|
cd ../liblua && make $(LUAPLATFORM)
|
||||||
|
|
||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(OBJDIR)/%.o : %.c $(OBJDIR)/%.d
|
||||||
|
$(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $<
|
||||||
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
$(OBJDIR)/%.o : %.cpp $(OBJDIR)/%.d
|
||||||
|
$(CXX) $(DEPFLAGS) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
$(POSTCOMPILE)
|
||||||
|
|
||||||
|
|
||||||
|
#$(CMDOBJS) $(COREOBJS): $(notdir $(%.c)) %.d
|
||||||
|
# $(CC) $(DEPFLAGS) $(CFLAGS) -c -o $@ $<
|
||||||
|
# $(POSTCOMPILE)
|
||||||
|
|
||||||
|
#$(ZLIBOBJS): $(notdir $(%.c)) %.d
|
||||||
|
# $(CC) $(DEPFLAGS) $(CFLAGS) $(ZLIBFLAGS) -c -o $@ $<
|
||||||
|
# $(POSTCOMPILE)
|
||||||
|
|
||||||
|
#$(QTGUIOBJS): $(notdir $(%.cpp)) %.d
|
||||||
|
# $(CXX) $(DEPFLAGS) $(CXXFLAGS) -c -o $@ $<
|
||||||
|
# $(POSTCOMPILE)
|
||||||
|
|
||||||
|
DEPENDENCY_FILES = $(patsubst %.c, $(OBJDIR)/%.d, $(CORESRCS) $(CMDSRCS) $(ZLIBSRCS)) \
|
||||||
|
$(patsubst %.cpp, $(OBJDIR)/%.d, $(QTGUISRCS)) \
|
||||||
|
$(OBJDIR)/proxmark3.d $(OBJDIR)/flash.d $(OBJDIR)/flasher.d $(OBJDIR)/fpga_compress.d
|
||||||
|
|
||||||
|
$(DEPENDENCY_FILES): ;
|
||||||
|
.PRECIOUS: $(DEPENDENCY_FILES)
|
||||||
|
|
||||||
|
-include $(DEPENDENCY_FILES)
|
||||||
|
|
||||||
|
|
58
client/cli.c
58
client/cli.c
|
@ -1,58 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
|
||||||
// the license.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Command line binary
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "sleep.h"
|
|
||||||
#include "ui.h"
|
|
||||||
#include "proxusb.h"
|
|
||||||
#include "cmdmain.h"
|
|
||||||
|
|
||||||
#define HANDLE_ERROR if (error_occured) { \
|
|
||||||
error_occured = 0;\
|
|
||||||
break;\
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
if (argc != 3 && argc != 4)
|
|
||||||
{
|
|
||||||
printf("\n\tusage: cli <command 1> <command 2> [logfile (default cli.log)]\n");
|
|
||||||
printf("\n");
|
|
||||||
printf("\texample: cli hi14asnoop hi14alist h14a.log\n");
|
|
||||||
printf("\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
usb_init();
|
|
||||||
if (argc == 4)
|
|
||||||
SetLogFilename(argv[3]);
|
|
||||||
else
|
|
||||||
SetLogFilename("cli.log");
|
|
||||||
|
|
||||||
return_on_error = 1;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
while (!OpenProxmark(0)) { sleep(1); }
|
|
||||||
while (1) {
|
|
||||||
UsbCommand cmdbuf;
|
|
||||||
CommandReceived(argv[1]);
|
|
||||||
HANDLE_ERROR;
|
|
||||||
ReceiveCommand(&cmdbuf);
|
|
||||||
HANDLE_ERROR;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
ReceiveCommandPoll(&cmdbuf);
|
|
||||||
}
|
|
||||||
HANDLE_ERROR;
|
|
||||||
CommandReceived(argv[2]);
|
|
||||||
HANDLE_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseProxmark();
|
|
||||||
return 0;
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
void ShowGraphWindow(void)
|
extern "C" void ShowGraphWindow(void)
|
||||||
{
|
{
|
||||||
static int warned = 0;
|
static int warned = 0;
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ void ShowGraphWindow(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HideGraphWindow(void) {}
|
extern "C" void HideGraphWindow(void) {}
|
||||||
void RepaintGraphWindow(void) {}
|
extern "C" void RepaintGraphWindow(void) {}
|
||||||
void MainGraphics() {}
|
extern "C" void MainGraphics() {}
|
||||||
void InitGraphics(int argc, char **argv) {}
|
extern "C" void InitGraphics(int argc, char **argv) {}
|
||||||
void ExitGraphics(void) {}
|
extern "C" void ExitGraphics(void) {}
|
|
@ -1,164 +1,8 @@
|
||||||
--[[
|
--[[
|
||||||
These are command definitions. This file should correspond exactly to usb_cmd.h.
|
Handle Proxmark USB Commands
|
||||||
--]]
|
--]]
|
||||||
--// For the bootloader
|
|
||||||
local _commands = {
|
|
||||||
CMD_DEVICE_INFO = 0x0000,
|
|
||||||
CMD_SETUP_WRITE = 0x0001,
|
|
||||||
CMD_FINISH_WRITE = 0x0003,
|
|
||||||
CMD_HARDWARE_RESET = 0x0004,
|
|
||||||
CMD_START_FLASH = 0x0005,
|
|
||||||
CMD_NACK = 0x00fe,
|
|
||||||
CMD_ACK = 0x00ff,
|
|
||||||
|
|
||||||
--// For general mucking around
|
|
||||||
CMD_DEBUG_PRINT_STRING = 0x0100,
|
|
||||||
CMD_DEBUG_PRINT_INTEGERS = 0x0101,
|
|
||||||
CMD_DEBUG_PRINT_BYTES = 0x0102,
|
|
||||||
CMD_LCD_RESET = 0x0103,
|
|
||||||
CMD_LCD = 0x0104,
|
|
||||||
CMD_BUFF_CLEAR = 0x0105,
|
|
||||||
CMD_READ_MEM = 0x0106,
|
|
||||||
CMD_VERSION = 0x0107,
|
|
||||||
CMD_STATUS = 0x0108,
|
|
||||||
CMD_PING = 0x0109,
|
|
||||||
--// For low-frequency tags
|
|
||||||
CMD_READ_TI_TYPE = 0x0202,
|
|
||||||
CMD_WRITE_TI_TYPE = 0x0203,
|
|
||||||
CMD_DOWNLOADED_RAW_BITS_TI_TYPE = 0x0204,
|
|
||||||
CMD_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0205,
|
|
||||||
CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0206,
|
|
||||||
CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K = 0x0207,
|
|
||||||
CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K = 0x0208,
|
|
||||||
CMD_DOWNLOADED_SIM_SAMPLES_125K = 0x0209,
|
|
||||||
CMD_SIMULATE_TAG_125K = 0x020A,
|
|
||||||
CMD_HID_DEMOD_FSK = 0x020B,
|
|
||||||
CMD_HID_SIM_TAG = 0x020C,
|
|
||||||
CMD_SET_LF_DIVISOR = 0x020D,
|
|
||||||
CMD_LF_SIMULATE_BIDIR = 0x020E,
|
|
||||||
CMD_SET_ADC_MUX = 0x020F,
|
|
||||||
CMD_HID_CLONE_TAG = 0x0210,
|
|
||||||
CMD_EM410X_WRITE_TAG = 0x0211,
|
|
||||||
CMD_INDALA_CLONE_TAG = 0x0212,
|
|
||||||
--// for 224 bits UID
|
|
||||||
CMD_INDALA_CLONE_TAG_L = 0x0213,
|
|
||||||
CMD_T55XX_READ_BLOCK = 0x0214,
|
|
||||||
CMD_T55XX_WRITE_BLOCK = 0x0215,
|
|
||||||
CMD_T55XX_RESET_READ = 0x0216,
|
|
||||||
CMD_PCF7931_READ = 0x0217,
|
|
||||||
CMD_EM4X_READ_WORD = 0x0218,
|
|
||||||
CMD_EM4X_WRITE_WORD = 0x0219,
|
|
||||||
CMD_IO_DEMOD_FSK = 0x021A,
|
|
||||||
CMD_IO_CLONE_TAG = 0x021B,
|
|
||||||
CMD_EM410X_DEMOD = 0x021c,
|
|
||||||
CMD_SET_LF_SAMPLING_CONFIG = 0x021d,
|
|
||||||
CMD_FSK_SIM_TAG = 0x021E,
|
|
||||||
CMD_ASK_SIM_TAG = 0x021F,
|
|
||||||
CMD_PSK_SIM_TAG = 0x0220,
|
|
||||||
CMD_AWID_DEMOD_FSK = 0x0221,
|
|
||||||
CMD_VIKING_CLONE_TAG = 0x0223,
|
|
||||||
CMD_T55XX_WAKEUP = 0x0224,
|
|
||||||
CMD_COTAG = 0x0225,
|
|
||||||
--/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
|
||||||
|
|
||||||
--// For the 13.56 MHz tags
|
|
||||||
CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 = 0x0300,
|
|
||||||
CMD_READ_SRI512_TAG = 0x0303,
|
|
||||||
CMD_READ_SRIX4K_TAG = 0x0304,
|
|
||||||
CMD_READER_ISO_15693 = 0x0310,
|
|
||||||
CMD_SIMTAG_ISO_15693 = 0x0311,
|
|
||||||
CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 = 0x0312,
|
|
||||||
CMD_ISO_15693_COMMAND = 0x0313,
|
|
||||||
CMD_ISO_15693_COMMAND_DONE = 0x0314,
|
|
||||||
CMD_ISO_15693_FIND_AFI = 0x0315,
|
|
||||||
CMD_ISO_15693_DEBUG = 0x0316,
|
|
||||||
CMD_LF_SNOOP_RAW_ADC_SAMPLES = 0x0317,
|
|
||||||
|
|
||||||
--// For Hitag2 transponders
|
|
||||||
CMD_SNOOP_HITAG = 0x0370,
|
|
||||||
CMD_SIMULATE_HITAG = 0x0371,
|
|
||||||
CMD_READER_HITAG = 0x0372,
|
|
||||||
|
|
||||||
CMD_SIMULATE_TAG_ISO_14443B = 0x0381,
|
|
||||||
CMD_SNOOP_ISO_14443B = 0x0382,
|
|
||||||
CMD_SNOOP_ISO_14443a = 0x0383,
|
|
||||||
CMD_SIMULATE_TAG_ISO_14443a = 0x0384,
|
|
||||||
CMD_READER_ISO_14443a = 0x0385,
|
|
||||||
CMD_SIMULATE_TAG_LEGIC_RF = 0x0387,
|
|
||||||
CMD_READER_LEGIC_RF = 0x0388,
|
|
||||||
CMD_WRITER_LEGIC_RF = 0x0389,
|
|
||||||
CMD_EPA_PACE_COLLECT_NONCE = 0x038A,
|
|
||||||
--//CMD_EPA_ = 0x038B,
|
|
||||||
|
|
||||||
CMD_ICLASS_READCHECK = 0x038F,
|
|
||||||
CMD_ICLASS_CLONE = 0x0390,
|
|
||||||
CMD_ICLASS_DUMP = 0x0391,
|
|
||||||
CMD_SNOOP_ICLASS = 0x0392,
|
|
||||||
CMD_SIMULATE_TAG_ICLASS = 0x0393,
|
|
||||||
CMD_READER_ICLASS = 0x0394,
|
|
||||||
CMD_READER_ICLASS_REPLAY = 0x0395,
|
|
||||||
CMD_ICLASS_READBLOCK = 0x0396,
|
|
||||||
CMD_ICLASS_WRITEBLOCK = 0x0397,
|
|
||||||
CMD_ICLASS_EML_MEMSET = 0x0398,
|
|
||||||
CMD_ICLASS_AUTHENTICATION = 0x0399,
|
|
||||||
|
|
||||||
--// For measurements of the antenna tuning
|
|
||||||
CMD_MEASURE_ANTENNA_TUNING = 0x0400,
|
|
||||||
CMD_MEASURE_ANTENNA_TUNING_HF = 0x0401,
|
|
||||||
CMD_MEASURED_ANTENNA_TUNING = 0x0410,
|
|
||||||
CMD_LISTEN_READER_FIELD = 0x0420,
|
|
||||||
|
|
||||||
--// For direct FPGA control
|
|
||||||
CMD_FPGA_MAJOR_MODE_OFF = 0x0500,
|
|
||||||
|
|
||||||
--// For mifare commands
|
|
||||||
CMD_MIFARE_SET_DBGMODE = 0x0600,
|
|
||||||
CMD_MIFARE_EML_MEMCLR = 0x0601,
|
|
||||||
CMD_MIFARE_EML_MEMSET = 0x0602,
|
|
||||||
CMD_MIFARE_EML_MEMGET = 0x0603,
|
|
||||||
CMD_MIFARE_EML_CARDLOAD = 0x0604,
|
|
||||||
|
|
||||||
--// magic chinese card commands
|
|
||||||
CMD_MIFARE_CSETBLOCK = 0x0605,
|
|
||||||
CMD_MIFARE_CGETBLOCK = 0x0606,
|
|
||||||
CMD_MIFARE_CIDENT = 0x0607,
|
|
||||||
|
|
||||||
CMD_SIMULATE_MIFARE_CARD = 0x0610,
|
|
||||||
|
|
||||||
CMD_READER_MIFARE = 0x0611,
|
|
||||||
CMD_MIFARE_NESTED = 0x0612,
|
|
||||||
|
|
||||||
CMD_MIFARE_READBL = 0x0620,
|
|
||||||
CMD_MIFAREU_READBL = 0x0720,
|
|
||||||
|
|
||||||
CMD_MIFARE_READSC = 0x0621,
|
|
||||||
CMD_MIFAREU_READCARD = 0x0721,
|
|
||||||
|
|
||||||
CMD_MIFARE_WRITEBL = 0x0622,
|
|
||||||
CMD_MIFAREU_WRITEBL = 0x0722,
|
|
||||||
CMD_MIFAREU_WRITEBL_COMPAT = 0x0723,
|
|
||||||
|
|
||||||
CMD_MIFARE_CHKKEYS = 0x0623,
|
|
||||||
|
|
||||||
CMD_MIFARE_SNIFFER = 0x0630,
|
|
||||||
|
|
||||||
--//ultralightC
|
|
||||||
CMD_MIFAREUC_AUTH = 0x0724,
|
|
||||||
CMD_MIFAREUC_SETPWD = 0x0727,
|
|
||||||
CMD_MIFAREU_SETUID = 0x0728,
|
|
||||||
|
|
||||||
--// mifare desfire
|
|
||||||
CMD_MIFARE_DESFIRE_READBL = 0x0728,
|
|
||||||
CMD_MIFARE_DESFIRE_WRITEBL = 0x0729,
|
|
||||||
CMD_MIFARE_DESFIRE_AUTH1 = 0x072a,
|
|
||||||
CMD_MIFARE_DESFIRE_AUTH2 = 0x072b,
|
|
||||||
CMD_MIFARE_DES_READER = 0x072c,
|
|
||||||
CMD_MIFARE_DESFIRE_INFO = 0x072d,
|
|
||||||
CMD_MIFARE_DESFIRE = 0x072e,
|
|
||||||
|
|
||||||
CMD_UNKNOWN = 0xFFFF,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
local _commands = require('usb_cmd')
|
||||||
|
|
||||||
local _reverse_lookup,k,v = {}
|
local _reverse_lookup,k,v = {}
|
||||||
for k, v in pairs(_commands) do
|
for k, v in pairs(_commands) do
|
||||||
|
|
137
client/lualibs/usb_cmd.lua
Normal file
137
client/lualibs/usb_cmd.lua
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
--[[
|
||||||
|
These are Proxmark command definitions.
|
||||||
|
This file is automatically generated from usb_cmd.h - DON'T EDIT MANUALLY.
|
||||||
|
--]]
|
||||||
|
local __commands = {
|
||||||
|
CMD_DEVICE_INFO = 0x0000,
|
||||||
|
CMD_SETUP_WRITE = 0x0001,
|
||||||
|
CMD_FINISH_WRITE = 0x0003,
|
||||||
|
CMD_HARDWARE_RESET = 0x0004,
|
||||||
|
CMD_START_FLASH = 0x0005,
|
||||||
|
CMD_NACK = 0x00fe,
|
||||||
|
CMD_ACK = 0x00ff,
|
||||||
|
CMD_DEBUG_PRINT_STRING = 0x0100,
|
||||||
|
CMD_DEBUG_PRINT_INTEGERS = 0x0101,
|
||||||
|
CMD_DEBUG_PRINT_BYTES = 0x0102,
|
||||||
|
CMD_LCD_RESET = 0x0103,
|
||||||
|
CMD_LCD = 0x0104,
|
||||||
|
CMD_BUFF_CLEAR = 0x0105,
|
||||||
|
CMD_READ_MEM = 0x0106,
|
||||||
|
CMD_VERSION = 0x0107,
|
||||||
|
CMD_STATUS = 0x0108,
|
||||||
|
CMD_PING = 0x0109,
|
||||||
|
CMD_READ_TI_TYPE = 0x0202,
|
||||||
|
CMD_WRITE_TI_TYPE = 0x0203,
|
||||||
|
CMD_DOWNLOADED_RAW_BITS_TI_TYPE = 0x0204,
|
||||||
|
CMD_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0205,
|
||||||
|
CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K = 0x0206,
|
||||||
|
CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K = 0x0207,
|
||||||
|
CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K = 0x0208,
|
||||||
|
CMD_DOWNLOADED_SIM_SAMPLES_125K = 0x0209,
|
||||||
|
CMD_SIMULATE_TAG_125K = 0x020A,
|
||||||
|
CMD_HID_DEMOD_FSK = 0x020B,
|
||||||
|
CMD_HID_SIM_TAG = 0x020C,
|
||||||
|
CMD_SET_LF_DIVISOR = 0x020D,
|
||||||
|
CMD_LF_SIMULATE_BIDIR = 0x020E,
|
||||||
|
CMD_SET_ADC_MUX = 0x020F,
|
||||||
|
CMD_HID_CLONE_TAG = 0x0210,
|
||||||
|
CMD_EM410X_WRITE_TAG = 0x0211,
|
||||||
|
CMD_INDALA_CLONE_TAG = 0x0212,
|
||||||
|
CMD_INDALA_CLONE_TAG_L = 0x0213,
|
||||||
|
CMD_T55XX_READ_BLOCK = 0x0214,
|
||||||
|
CMD_T55XX_WRITE_BLOCK = 0x0215,
|
||||||
|
CMD_T55XX_RESET_READ = 0x0216,
|
||||||
|
CMD_PCF7931_READ = 0x0217,
|
||||||
|
CMD_PCF7931_WRITE = 0x0222,
|
||||||
|
CMD_EM4X_READ_WORD = 0x0218,
|
||||||
|
CMD_EM4X_WRITE_WORD = 0x0219,
|
||||||
|
CMD_IO_DEMOD_FSK = 0x021A,
|
||||||
|
CMD_IO_CLONE_TAG = 0x021B,
|
||||||
|
CMD_EM410X_DEMOD = 0x021c,
|
||||||
|
CMD_SET_LF_SAMPLING_CONFIG = 0x021d,
|
||||||
|
CMD_FSK_SIM_TAG = 0x021E,
|
||||||
|
CMD_ASK_SIM_TAG = 0x021F,
|
||||||
|
CMD_PSK_SIM_TAG = 0x0220,
|
||||||
|
CMD_AWID_DEMOD_FSK = 0x0221,
|
||||||
|
CMD_VIKING_CLONE_TAG = 0x0223,
|
||||||
|
CMD_T55XX_WAKEUP = 0x0224,
|
||||||
|
CMD_COTAG = 0x0225,
|
||||||
|
CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 = 0x0300,
|
||||||
|
CMD_READ_SRI512_TAG = 0x0303,
|
||||||
|
CMD_READ_SRIX4K_TAG = 0x0304,
|
||||||
|
CMD_ISO_14443B_COMMAND = 0x0305,
|
||||||
|
CMD_READER_ISO_15693 = 0x0310,
|
||||||
|
CMD_SIMTAG_ISO_15693 = 0x0311,
|
||||||
|
CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 = 0x0312,
|
||||||
|
CMD_ISO_15693_COMMAND = 0x0313,
|
||||||
|
CMD_ISO_15693_COMMAND_DONE = 0x0314,
|
||||||
|
CMD_ISO_15693_FIND_AFI = 0x0315,
|
||||||
|
CMD_ISO_15693_DEBUG = 0x0316,
|
||||||
|
CMD_LF_SNOOP_RAW_ADC_SAMPLES = 0x0317,
|
||||||
|
CMD_SNOOP_HITAG = 0x0370,
|
||||||
|
CMD_SIMULATE_HITAG = 0x0371,
|
||||||
|
CMD_READER_HITAG = 0x0372,
|
||||||
|
CMD_SIMULATE_HITAG_S = 0x0368,
|
||||||
|
CMD_TEST_HITAGS_TRACES = 0x0367,
|
||||||
|
CMD_READ_HITAG_S = 0x0373,
|
||||||
|
CMD_WR_HITAG_S = 0x0375,
|
||||||
|
CMD_EMU_HITAG_S = 0x0376,
|
||||||
|
CMD_SIMULATE_TAG_ISO_14443B = 0x0381,
|
||||||
|
CMD_SNOOP_ISO_14443B = 0x0382,
|
||||||
|
CMD_SNOOP_ISO_14443a = 0x0383,
|
||||||
|
CMD_SIMULATE_TAG_ISO_14443a = 0x0384,
|
||||||
|
CMD_READER_ISO_14443a = 0x0385,
|
||||||
|
CMD_SIMULATE_TAG_LEGIC_RF = 0x0387,
|
||||||
|
CMD_READER_LEGIC_RF = 0x0388,
|
||||||
|
CMD_WRITER_LEGIC_RF = 0x0389,
|
||||||
|
CMD_EPA_PACE_COLLECT_NONCE = 0x038A,
|
||||||
|
CMD_EPA_PACE_REPLAY = 0x038B,
|
||||||
|
CMD_ICLASS_READCHECK = 0x038F,
|
||||||
|
CMD_ICLASS_CLONE = 0x0390,
|
||||||
|
CMD_ICLASS_DUMP = 0x0391,
|
||||||
|
CMD_SNOOP_ICLASS = 0x0392,
|
||||||
|
CMD_SIMULATE_TAG_ICLASS = 0x0393,
|
||||||
|
CMD_READER_ICLASS = 0x0394,
|
||||||
|
CMD_READER_ICLASS_REPLAY = 0x0395,
|
||||||
|
CMD_ICLASS_READBLOCK = 0x0396,
|
||||||
|
CMD_ICLASS_WRITEBLOCK = 0x0397,
|
||||||
|
CMD_ICLASS_EML_MEMSET = 0x0398,
|
||||||
|
CMD_ICLASS_AUTHENTICATION = 0x0399,
|
||||||
|
CMD_MEASURE_ANTENNA_TUNING = 0x0400,
|
||||||
|
CMD_MEASURE_ANTENNA_TUNING_HF = 0x0401,
|
||||||
|
CMD_MEASURED_ANTENNA_TUNING = 0x0410,
|
||||||
|
CMD_LISTEN_READER_FIELD = 0x0420,
|
||||||
|
CMD_FPGA_MAJOR_MODE_OFF = 0x0500,
|
||||||
|
CMD_MIFARE_SET_DBGMODE = 0x0600,
|
||||||
|
CMD_MIFARE_EML_MEMCLR = 0x0601,
|
||||||
|
CMD_MIFARE_EML_MEMSET = 0x0602,
|
||||||
|
CMD_MIFARE_EML_MEMGET = 0x0603,
|
||||||
|
CMD_MIFARE_EML_CARDLOAD = 0x0604,
|
||||||
|
CMD_MIFARE_CSETBLOCK = 0x0605,
|
||||||
|
CMD_MIFARE_CGETBLOCK = 0x0606,
|
||||||
|
CMD_MIFARE_CIDENT = 0x0607,
|
||||||
|
CMD_SIMULATE_MIFARE_CARD = 0x0610,
|
||||||
|
CMD_READER_MIFARE = 0x0611,
|
||||||
|
CMD_MIFARE_NESTED = 0x0612,
|
||||||
|
CMD_MIFARE_READBL = 0x0620,
|
||||||
|
CMD_MIFAREU_READBL = 0x0720,
|
||||||
|
CMD_MIFARE_READSC = 0x0621,
|
||||||
|
CMD_MIFAREU_READCARD = 0x0721,
|
||||||
|
CMD_MIFARE_WRITEBL = 0x0622,
|
||||||
|
CMD_MIFAREU_WRITEBL = 0x0722,
|
||||||
|
CMD_MIFAREU_WRITEBL_COMPAT = 0x0723,
|
||||||
|
CMD_MIFARE_CHKKEYS = 0x0623,
|
||||||
|
CMD_MIFARE_SNIFFER = 0x0630,
|
||||||
|
CMD_MIFAREUC_AUTH = 0x0724,
|
||||||
|
CMD_MIFAREUC_SETPWD = 0x0727,
|
||||||
|
CMD_MIFARE_DESFIRE_READBL = 0x0728,
|
||||||
|
CMD_MIFARE_DESFIRE_WRITEBL = 0x0729,
|
||||||
|
CMD_MIFARE_DESFIRE_AUTH1 = 0x072a,
|
||||||
|
CMD_MIFARE_DESFIRE_AUTH2 = 0x072b,
|
||||||
|
CMD_MIFARE_DES_READER = 0x072c,
|
||||||
|
CMD_MIFARE_DESFIRE_INFO = 0x072d,
|
||||||
|
CMD_MIFARE_DESFIRE = 0x072e,
|
||||||
|
CMD_HF_SNIFFER = 0x0800,
|
||||||
|
CMD_UNKNOWN = 0xFFFF,
|
||||||
|
}
|
||||||
|
return __commands
|
|
@ -1,46 +0,0 @@
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
|
|
||||||
//
|
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
|
||||||
// the license.
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Snooper binary
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#include "ui.h"
|
|
||||||
#include "proxusb.h"
|
|
||||||
#include "cmdmain.h"
|
|
||||||
|
|
||||||
#define HANDLE_ERROR if (error_occured) { \
|
|
||||||
error_occured = 0;\
|
|
||||||
break;\
|
|
||||||
}
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
usb_init();
|
|
||||||
SetLogFilename("snooper.log");
|
|
||||||
|
|
||||||
return_on_error = 1;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
while (!OpenProxmark(0)) { sleep(1); }
|
|
||||||
while (1) {
|
|
||||||
UsbCommand cmdbuf;
|
|
||||||
CommandReceived("hf 14a snoop");
|
|
||||||
HANDLE_ERROR;
|
|
||||||
ReceiveCommand(&cmdbuf);
|
|
||||||
HANDLE_ERROR;
|
|
||||||
for (int i = 0; i < 5; ++i) {
|
|
||||||
ReceiveCommandPoll(&cmdbuf);
|
|
||||||
}
|
|
||||||
HANDLE_ERROR;
|
|
||||||
CommandReceived("hf 14a list");
|
|
||||||
HANDLE_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseProxmark();
|
|
||||||
return 0;
|
|
||||||
}
|
|
15
client/usb_cmd_h2lua.awk
Normal file
15
client/usb_cmd_h2lua.awk
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
BEGIN {
|
||||||
|
print "--[["
|
||||||
|
print "These are Proxmark command definitions."
|
||||||
|
print "This file is automatically generated from usb_cmd.h - DON'T EDIT MANUALLY."
|
||||||
|
print "--]]"
|
||||||
|
print "local __commands = {"
|
||||||
|
}
|
||||||
|
|
||||||
|
#$1 ~ /#define/ && $2 ~ /^CMD_([[:alnum:]_])+/ { print $2, "=", $3, "," }
|
||||||
|
$1 ~ /#define/ && $2 ~ /^CMD_[A-Za-z0-9_]+/ { sub(/\r/, ""); print $2, "=", $3 "," }
|
||||||
|
|
||||||
|
END {
|
||||||
|
print "}"
|
||||||
|
print "return __commands"
|
||||||
|
}
|
|
@ -634,13 +634,22 @@ void msleep(uint32_t n) {
|
||||||
// a milliseconds timer for performance measurement
|
// a milliseconds timer for performance measurement
|
||||||
uint64_t msclock() {
|
uint64_t msclock() {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
// WORKAROUND FOR MinGW (some versions - use if normal code does not compile)
|
||||||
|
// It has no _ftime_s and needs explicit inclusion of timeb.h
|
||||||
|
#include <sys/timeb.h>
|
||||||
struct _timeb t;
|
struct _timeb t;
|
||||||
if (_ftime_s(&t)) {
|
_ftime(&t);
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return 1000 * t.time + t.millitm;
|
return 1000 * t.time + t.millitm;
|
||||||
}
|
|
||||||
|
// NORMAL CODE (use _ftime_s)
|
||||||
|
//struct _timeb t;
|
||||||
|
//if (_ftime_s(&t)) {
|
||||||
|
// return 0;
|
||||||
|
//} else {
|
||||||
|
// return 1000 * t.time + t.millitm;
|
||||||
|
//}
|
||||||
#else
|
#else
|
||||||
struct timespec t;
|
struct timespec t;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue