proxmark
proxmark3
flasher
+fpga_compress
version.c
lua
luac
- Added 'hw status'. This command makes the ARM print out some runtime information. (holiman)
- Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman)
-### Changed
+### Changed
+- Revised workflow for StandAloneMode14a (Craig Young)
- Changed lf config's `threshold` to a graph (signed) metric and it will trigger on + or - value set to. (example: set to 50 and recording would begin at first graphed value of >= 50 or <= -50) (marshmellow)
- EPA functions (`hf epa`) now support both ISO 14443-A and 14443-B cards (frederikmoellers)
- 'hw version' only talks to ARM at startup, after that the info is cached. (pwpiwi)
uint32_t compressed_data_section_size = common_area.arg1;
cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString));
}
+
+// measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
+// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included.
+void printUSBSpeed(uint32_t SpeedTestBufferSize)
+{
+ Dbprintf("USB Speed:");
+ Dbprintf(" Sending %d bytes payload...", SpeedTestBufferSize);
+
+ uint8_t *test_data = BigBuf_get_addr();
+
+ uint32_t start_time = GetTickCount();
+
+ LED_B_ON();
+ for(size_t i=0; i < SpeedTestBufferSize; i += USB_CMD_DATA_SIZE) {
+ size_t len = MIN((SpeedTestBufferSize - i), USB_CMD_DATA_SIZE);
+ cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,0,len,0,test_data,len);
+ }
+ LED_B_OFF();
+
+ uint32_t end_time = GetTickCount();
+
+ Dbprintf(" Time elapsed: %dms, USB Transfer Speed PM3 -> Client = %d Bytes/s",
+ end_time - start_time,
+ 1000* SpeedTestBufferSize / (end_time - start_time));
+
+}
+
/**
* Prints runtime information about the PM3.
**/
-void SendStatus(void)
+void SendStatus(uint32_t SpeedTestBufferSize)
{
BigBuf_print_status();
Fpga_print_status();
printConfig(); //LF Sampling config
+ printUSBSpeed(SpeedTestBufferSize);
Dbprintf("Various");
- Dbprintf(" MF_DBGLEVEL......%d", MF_DBGLEVEL);
- Dbprintf(" ToSendMax........%d",ToSendMax);
- Dbprintf(" ToSendBit........%d",ToSendBit);
+ Dbprintf(" MF_DBGLEVEL........%d", MF_DBGLEVEL);
+ Dbprintf(" ToSendMax..........%d", ToSendMax);
+ Dbprintf(" ToSendBit..........%d", ToSendBit);
+ Dbprintf(" ToSend BUFFERSIZE..%d", TOSEND_BUFFER_SIZE);
+
+ cmd_send(CMD_ACK,1,0,0,0,0);
}
#if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF)
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
int selected = 0;
- int playing = 0;
+ int playing = 0, iGotoRecord = 0, iGotoClone = 0;
int cardRead[OPTS] = {0};
uint8_t readUID[10] = {0};
uint32_t uid_1st[OPTS]={0};
uint32_t uid_2nd[OPTS]={0};
+ uint32_t uid_tmp1 = 0;
+ uint32_t uid_tmp2 = 0;
+ iso14a_card_select_t hi14a_card[OPTS];
LED(selected + 1, 0);
{
usb_poll();
WDT_HIT();
-
- // Was our button held down or pressed?
- int button_pressed = BUTTON_HELD(1000);
SpinDelay(300);
- // Button was held for a second, begin recording
- if (button_pressed > 0 && cardRead[selected] == 0)
+ if (iGotoRecord == 1 || cardRead[selected] == 0)
{
+ iGotoRecord = 0;
LEDsoff();
LED(selected + 1, 0);
LED(LED_RED2, 0);
// record
Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
-
- // wait for button to be released
- while(BUTTON_PRESS())
- WDT_HIT();
/* need this delay to prevent catching some weird data */
SpinDelay(500);
/* Code for reading from 14a tag */
for ( ; ; )
{
WDT_HIT();
- if (!iso14443a_select_card(uid, NULL, &cuid))
+ if (BUTTON_PRESS()) {
+ if (cardRead[selected]) {
+ Dbprintf("Button press detected -- replaying card in bank[%d]", selected);
+ break;
+ }
+ else if (cardRead[(selected+1)%OPTS]) {
+ Dbprintf("Button press detected but no card in bank[%d] so playing from bank[%d]", selected, (selected+1)%OPTS);
+ selected = (selected+1)%OPTS;
+ break; // playing = 1;
+ }
+ else {
+ Dbprintf("Button press detected but no stored tag to play. (Ignoring button)");
+ SpinDelay(300);
+ }
+ }
+ if (!iso14443a_select_card(uid, &hi14a_card[selected], &cuid))
continue;
else
{
Dbprintf("Read UID:"); Dbhexdump(10,uid,0);
memcpy(readUID,uid,10*sizeof(uint8_t));
- uint8_t *dst = (uint8_t *)&uid_1st[selected];
+ uint8_t *dst = (uint8_t *)&uid_tmp1;
// Set UID byte order
for (int i=0; i<4; i++)
dst[i] = uid[3-i];
- dst = (uint8_t *)&uid_2nd[selected];
+ dst = (uint8_t *)&uid_tmp2;
for (int i=0; i<4; i++)
dst[i] = uid[7-i];
+ if (uid_1st[(selected+1)%OPTS] == uid_tmp1 && uid_2nd[(selected+1)%OPTS] == uid_tmp2) {
+ Dbprintf("Card selected has same UID as what is stored in the other bank. Skipping.");
+ }
+ else {
+ if (uid_tmp2) {
+ Dbprintf("Bank[%d] received a 7-byte UID",selected);
+ uid_1st[selected] = (uid_tmp1)>>8;
+ uid_2nd[selected] = (uid_tmp1<<24) + (uid_tmp2>>8);
+ }
+ else {
+ Dbprintf("Bank[%d] received a 4-byte UID",selected);
+ uid_1st[selected] = uid_tmp1;
+ uid_2nd[selected] = uid_tmp2;
+ }
break;
}
}
+ }
+ Dbprintf("ATQA = %02X%02X",hi14a_card[selected].atqa[0],hi14a_card[selected].atqa[1]);
+ Dbprintf("SAK = %02X",hi14a_card[selected].sak);
LEDsoff();
LED(LED_GREEN, 200);
LED(LED_ORANGE, 200);
LEDsoff();
LED(selected + 1, 0);
- // Finished recording
- // If we were previously playing, set playing off
- // so next button push begins playing what we recorded
- playing = 0;
+ // Next state is replay:
+ playing = 1;
cardRead[selected] = 1;
-
}
- /* MF UID clone */
- else if (button_pressed > 0 && cardRead[selected] == 1)
+ /* MF Classic UID clone */
+ else if (iGotoClone==1)
{
+ iGotoClone=0;
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 250);
break;
case CMD_MIFARE_CGETBLOCK:
MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
- //
break;
mfCSetUID provides example logic for UID set workflow:
*/
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
// arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo
- MifareCGetBlock(0x1F, 1, 0, oldBlock0);
+ MifareCGetBlock(0x3F, 1, 0, oldBlock0);
+ if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1] && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
+ Dbprintf("No changeable tag detected. Returning to replay mode for bank[%d]", selected);
+ playing = 1;
+ }
+ else {
Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
memcpy(newBlock0,oldBlock0,16);
// Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
// arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
MifareCSetBlock(0, 0xFF,0, newBlock0);
- MifareCGetBlock(0x1F, 1, 0, testBlock0);
+ MifareCGetBlock(0x3F, 1, 0, testBlock0);
if (memcmp(testBlock0,newBlock0,16)==0)
{
DbpString("Cloned successfull!");
cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
- }
- LEDsoff();
- LED(selected + 1, 0);
- // Finished recording
-
- // If we were previously playing, set playing off
- // so next button push begins playing what we recorded
playing = 0;
+ iGotoRecord = 1;
+ selected = (selected + 1) % OPTS;
+ }
+ else {
+ Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
+ playing = 1;
+ }
+ }
+ LEDsoff();
+ LED(selected + 1, 0);
}
// Change where to record (or begin playing)
- else if (button_pressed && cardRead[selected])
+ else if (playing==1) // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
{
- // Next option if we were previously playing
- if (playing)
- selected = (selected + 1) % OPTS;
- playing = !playing;
-
LEDsoff();
LED(selected + 1, 0);
{
LED(LED_GREEN, 0);
DbpString("Playing");
- while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec
+ for ( ; ; ) {
+ WDT_HIT();
+ int button_action = BUTTON_HELD(1000);
+ if (button_action == 0) { // No button action, proceed with sim
+ uint8_t data[512] = {0}; // in case there is a read command received we shouldn't break
+ uint8_t flags = ( uid_2nd[selected] > 0x00 ) ? FLAG_7B_UID_IN_DATA : FLAG_4B_UID_IN_DATA;
+ num_to_bytes(uid_1st[selected], 3, data);
+ num_to_bytes(uid_2nd[selected], 4, data);
+
Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected);
- SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL);
+ if (hi14a_card[selected].sak == 8 && hi14a_card[selected].atqa[0] == 4 && hi14a_card[selected].atqa[1] == 0) {
+ DbpString("Mifare Classic");
+ SimulateIso14443aTag(1, flags, data); // Mifare Classic
+ }
+ else if (hi14a_card[selected].sak == 0 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 0) {
+ DbpString("Mifare Ultralight");
+ SimulateIso14443aTag(2, flags, data); // Mifare Ultralight
+ }
+ else if (hi14a_card[selected].sak == 20 && hi14a_card[selected].atqa[0] == 0x44 && hi14a_card[selected].atqa[1] == 3) {
+ DbpString("Mifare DESFire");
+ SimulateIso14443aTag(3, flags, data); // Mifare DESFire
+ }
+ else {
+ Dbprintf("Unrecognized tag type -- defaulting to Mifare Classic emulation");
+ SimulateIso14443aTag(1, flags, data);
+ }
+ }
+ else if (button_action == BUTTON_SINGLE_CLICK) {
+ selected = (selected + 1) % OPTS;
+ Dbprintf("Done playing. Switching to record mode on bank %d",selected);
+ iGotoRecord = 1;
+ break;
}
- //cardRead[selected] = 1;
- Dbprintf("Done playing [Bank: %u]",selected);
+ else if (button_action == BUTTON_HOLD) {
+ Dbprintf("Playtime over. Begin cloning...");
+ iGotoClone = 1;
+ break;
+ }
+ WDT_HIT();
+ }
/* We pressed a button so ignore it here with a delay */
SpinDelay(300);
-
- // when done, we're done playing, move to next option
- selected = (selected + 1) % OPTS;
- playing = !playing;
LEDsoff();
LED(selected + 1, 0);
}
ReaderIso14443a(c);
break;
case CMD_SIMULATE_TAG_ISO_14443a:
- SimulateIso14443aTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); // ## Simulate iso14443a tag - pass tag type & UID
+ SimulateIso14443aTag(c->arg[0], c->arg[1], c->d.asBytes); // ## Simulate iso14443a tag - pass tag type & UID
break;
case CMD_EPA_PACE_COLLECT_NONCE:
ReaderIClass(c->arg[0]);
break;
case CMD_READER_ICLASS_REPLAY:
- ReaderIClass_Replay(c->arg[0], c->d.asBytes);
+ ReaderIClass_Replay(c->arg[0], c->d.asBytes);
break;
case CMD_ICLASS_EML_MEMSET:
emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
SendVersion();
break;
case CMD_STATUS:
- SendStatus();
+ SendStatus(c->arg[0]);
break;
case CMD_PING:
cmd_send(CMD_ACK,0,0,0,0,0);
case CMD_FINISH_WRITE:
case CMD_HARDWARE_RESET:
usb_disable();
- SpinDelay(1000);
- SpinDelay(1000);
+ SpinDelay(2000);
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
for(;;) {
// We're going to reset, and the bootrom will take control.
LCDInit();
#endif
- byte_t rx[sizeof(UsbCommand)];
+ byte_t rx[sizeof(UsbCommand)];
size_t rx_len;
for(;;) {
/// iso14443a.h
void RAMFUNC SniffIso14443a(uint8_t param);
-void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data);
+void SimulateIso14443aTag(int tagType, int flags, byte_t* data);
void ReaderIso14443a(UsbCommand * c);
// Also used in iclass.c
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
// Main loop of simulated tag: receive commands from reader, decide what
// response to send, and send it.
//-----------------------------------------------------------------------------
-void SimulateIso14443aTag(int tagType, int flags, int uid_2nd, byte_t* data)
+void SimulateIso14443aTag(int tagType, int flags, byte_t* data)
{
//Here, we collect UID,NT,AR,NR,UID2,NT2,AR2,NR2
if(!ReaderIsActive) { // no need to try decoding tag data if the reader is sending - and we cannot afford the time
// is this | 0x01 the error? & 0xfe in https://github.com/Proxmark/proxmark3/issues/103
- if(Handle14443bSamplesDemod(ci | 0x01, cq | 0x01)) {
+ if(Handle14443bSamplesDemod(ci & 0xfe, cq & 0xfe)) {
//Use samples as a time measurement
if(tracing)
// bit 2 - need HALT after sequence\r
// bit 3 - need init FPGA and field before sequence\r
// bit 4 - need reset FPGA and LED\r
+ // bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)\r
uint8_t workFlags = arg0;\r
uint8_t blockNo = arg2;\r
\r
}\r
\r
LED_B_ON();\r
+ if (workFlags & 0x20) {\r
+ if (isOK)\r
+ memcpy(datain, data, 18);\r
+ }\r
+ else\r
cmd_send(CMD_ACK,isOK,0,0,data,18);\r
LED_B_OFF();\r
\r
void StartTickCount()
{
-// must be 0x40, but on my cpu - included divider is optimal
-// 0x20 - 1 ms / bit
-// 0x40 - 2 ms / bit
-
- AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST + 0x001D; // was 0x003B
+ // This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
+ // We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register.
+ uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency
+ // set RealTimeCounter divider to count at 1kHz:
+ AT91C_BASE_RTTC->RTTC_RTMR = AT91C_RTTC_RTTRST | ((256000 + (mainf/2)) / mainf);
+ // note: worst case precision is approx 2.5%
}
/*
int CmdHF14BSim(const char *Cmd)
{
- UsbCommand c={CMD_SIMULATE_TAG_ISO_14443B};
+ UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443B};
clearCommandBuffer();
SendCommand(&c);
return 0;
#include "cmdhw.h"
#include "cmdmain.h"
#include "cmddata.h"
+#include "data.h"
/* low-level hardware control */
int CmdVersion(const char *Cmd)
{
-
clearCommandBuffer();
- UsbCommand c = {CMD_VERSION};
+ UsbCommand c = {CMD_VERSION};
static UsbCommand resp = {0, {0, 0, 0}};
if (resp.arg[0] == 0 && resp.arg[1] == 0) { // no cached information available
- SendCommand(&c);
- if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
- PrintAndLog("Prox/RFID mark3 RFID instrument");
- PrintAndLog((char*)resp.d.asBytes);
- lookupChipID(resp.arg[0], resp.arg[1]);
- }
+ SendCommand(&c);
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ PrintAndLog("Prox/RFID mark3 RFID instrument");
+ PrintAndLog((char*)resp.d.asBytes);
+ lookupChipID(resp.arg[0], resp.arg[1]);
+ }
} else {
PrintAndLog("[[[ Cached information ]]]\n");
PrintAndLog("Prox/RFID mark3 RFID instrument");
int CmdStatus(const char *Cmd)
{
- UsbCommand c = {CMD_STATUS};
+ uint8_t speed_test_buffer[USB_CMD_DATA_SIZE];
+ sample_buf = speed_test_buffer;
+ #define USB_SPEED_TEST_SIZE (100*USB_CMD_DATA_SIZE)
+
+ clearCommandBuffer();
+ UsbCommand c = {CMD_STATUS, {USB_SPEED_TEST_SIZE}};
SendCommand(&c);
+ UsbCommand resp;
+ if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
+ PrintAndLog("Status command failed. USB Speed Test timed out");
+ }
return 0;
}
+
int CmdPing(const char *Cmd)
{
clearCommandBuffer();
int getCommand(UsbCommand* response)
{
//If head == tail, there's nothing to read, or if we just got initialized
- if(cmd_head == cmd_tail){
- return 0;
- }
+ if(cmd_head == cmd_tail) return 0;
+
//Pick out the next unread command
UsbCommand* last_unread = &cmdBuffer[cmd_tail];
memcpy(response, last_unread, sizeof(UsbCommand));
cmd_tail = (cmd_tail +1 ) % CMD_BUFFER_SIZE;
return 1;
-
}
/**
*/
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
- UsbCommand resp;
-
- if (response == NULL)
- response = &resp;
+ UsbCommand resp;
+ if (response == NULL)
+ response = &resp;
- // Wait until the command is received
- for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
+ // Wait until the command is received
+ for(size_t dm_seconds=0; dm_seconds < ms_timeout/10; dm_seconds++) {
while(getCommand(response)) {
- if(response->cmd == cmd){
- return true;
- }
- }
- msleep(10); // XXX ugh
- if (dm_seconds == 200) { // Two seconds elapsed
- PrintAndLog("Waiting for a response from the proxmark...");
- PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
- }
+ if(response->cmd == cmd){
+ return true;
+ }
+ }
+ msleep(10); // XXX ugh
+ if (dm_seconds == 200) { // Two seconds elapsed
+ PrintAndLog("Waiting for a response from the proxmark...");
+ PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
+ }
}
- return false;
+ return false;
}
bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
+ return;
} break;
- default:
- break;
+ default: break;
}
-
storeCommand(UC);
}
{
UsbCommand c;
c.cmd = CMD_DEVICE_INFO;
- SendCommand(&c);
+ SendCommand(&c);
UsbCommand resp;
ReceiveCommand(&resp);
#define PACKED __attribute__((packed))
#endif
+#define USB_CMD_DATA_SIZE 512
+
typedef struct {
- uint32_t cmd;
- uint32_t arg[3];
+ uint64_t cmd;
+ uint64_t arg[3];
union {
- uint8_t asBytes[48];
- uint32_t asDwords[12];
+ uint8_t asBytes[USB_CMD_DATA_SIZE];
+ uint32_t asDwords[USB_CMD_DATA_SIZE/4];
} d;
} PACKED UsbCommand;
+// A struct used to send sample-configs over USB
+typedef struct{
+ uint8_t decimation;
+ uint8_t bits_per_sample;
+ bool averaging;
+ int divisor;
+ int trigger_threshold;
+} sample_config;
// For the bootloader
#define CMD_DEVICE_INFO 0x0000
#define CMD_STATUS 0x0108
#define CMD_PING 0x0109
-
// For low-frequency tags
#define CMD_READ_TI_TYPE 0x0202
#define CMD_WRITE_TI_TYPE 0x0203
#define CMD_IO_DEMOD_FSK 0x021A
#define CMD_IO_CLONE_TAG 0x021B
#define CMD_EM410X_DEMOD 0x021c
+// Sampling configuration for LF reader/snooper
#define CMD_SET_LF_SAMPLING_CONFIG 0x021d
#define CMD_FSK_SIM_TAG 0x021E
#define CMD_ASK_SIM_TAG 0x021F
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
#define CMD_READ_SRI512_TAG 0x0303
#define CMD_READ_SRIX4K_TAG 0x0304
+#define CMD_ISO_14443B_COMMAND 0x0305
#define CMD_READER_ISO_15693 0x0310
#define CMD_SIMTAG_ISO_15693 0x0311
#define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312
#define CMD_ISO_15693_COMMAND_DONE 0x0314
#define CMD_ISO_15693_FIND_AFI 0x0315
#define CMD_ISO_15693_DEBUG 0x0316
+#define CMD_LF_SNOOP_RAW_ADC_SAMPLES 0x0317
// For Hitag2 transponders
#define CMD_SNOOP_HITAG 0x0370
#define CMD_SNOOP_ICLASS 0x0392
#define CMD_SIMULATE_TAG_ICLASS 0x0393
#define CMD_READER_ICLASS 0x0394
+#define CMD_READER_ICLASS_REPLAY 0x0395
+#define CMD_ICLASS_ISO14443A_WRITE 0x0397
+#define CMD_ICLASS_EML_MEMSET 0x0398
// For measurements of the antenna tuning
#define CMD_MEASURE_ANTENNA_TUNING 0x0400
#define CMD_MIFARE_EML_MEMSET 0x0602
#define CMD_MIFARE_EML_MEMGET 0x0603
#define CMD_MIFARE_EML_CARDLOAD 0x0604
-#define CMD_MIFARE_EML_CSETBLOCK 0x0605
-#define CMD_MIFARE_EML_CGETBLOCK 0x0606
+
+// magic chinese card commands
+#define CMD_MIFARE_CSETBLOCK 0x0605
+#define CMD_MIFARE_CGETBLOCK 0x0606
+#define CMD_MIFARE_CIDENT 0x0607
#define CMD_SIMULATE_MIFARE_CARD 0x0610
#define CMD_MIFARE_NESTED 0x0612
#define CMD_MIFARE_READBL 0x0620
+#define CMD_MIFAREU_READBL 0x0720
#define CMD_MIFARE_READSC 0x0621
+#define CMD_MIFAREU_READCARD 0x0721
#define CMD_MIFARE_WRITEBL 0x0622
+#define CMD_MIFAREU_WRITEBL 0x0722
+#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723
+
#define CMD_MIFARE_CHKKEYS 0x0623
#define CMD_MIFARE_SNIFFER 0x0630
+//ultralightC
+#define CMD_MIFAREUC_AUTH 0x0724
+//0x0725 and 0x0726 no longer used
+#define CMD_MIFAREUC_SETPWD 0x0727
+
+
+// mifare desfire
+#define CMD_MIFARE_DESFIRE_READBL 0x0728
+#define CMD_MIFARE_DESFIRE_WRITEBL 0x0729
+#define CMD_MIFARE_DESFIRE_AUTH1 0x072a
+#define CMD_MIFARE_DESFIRE_AUTH2 0x072b
+#define CMD_MIFARE_DES_READER 0x072c
+#define CMD_MIFARE_DESFIRE_INFO 0x072d
+#define CMD_MIFARE_DESFIRE 0x072e
+
+#define CMD_MIFARE_COLLECT_NONCES 0x072f
#define CMD_UNKNOWN 0xFFFF
+
+//Mifare simulation flags
+#define FLAG_INTERACTIVE 0x01
+#define FLAG_4B_UID_IN_DATA 0x02
+#define FLAG_7B_UID_IN_DATA 0x04
+#define FLAG_NR_AR_ATTACK 0x08
+
+
+//Iclass reader flags
+#define FLAG_ICLASS_READER_ONLY_ONCE 0x01
+#define FLAG_ICLASS_READER_CC 0x02
+#define FLAG_ICLASS_READER_CSN 0x04
+#define FLAG_ICLASS_READER_CONF 0x08
+#define FLAG_ICLASS_READER_AA 0x10
+#define FLAG_ICLASS_READER_ONE_TRY 0x20
+
+
+
// CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions:
/* Whether a bootloader that understands the common_area is present */
#define DEVICE_INFO_FLAG_BOOTROM_PRESENT (1<<0)
local _reverse_lookup,k,v = {}
- for k, v in pairs(_commands) do
- _reverse_lookup[v] = k
- end
- _commands.tostring = function(command)
+for k, v in pairs(_commands) do
+ _reverse_lookup[v] = k
+end
+_commands.tostring = function(command)
if(type(command) == 'number') then
return ("%s (%d)"):format(_reverse_lookup[command]or "ERROR UNDEFINED!", command)
end
self.__index = self
o.cmd = o.cmd or _commands.CMD_UNKNOWN
- --o.arg1 = "test"
o.arg1 = o.arg1 or 0
o.arg2 = o.arg2 or 0
o.arg3 = o.arg3 or 0
else
print(("WARNING; data was NOT a (hex-) string, but was %s"):format(type(data)))
end
- o.data = data
-
+ o.data = data
return o
end,
- parse = function (packet)
- local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',packet)
+ parse = function(packet)
+ local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLLH512', packet)
return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data}
- end,
+ end
+
}
function Command:__tostring()
local output = ("%s\r\nargs : (%s, %s, %s)\r\ndata:\r\n%s\r\n"):format(
return outResults\r
end,\r
\r
+ ----ISO14443-B CRC\r
+ Crc14b = function(s)\r
+ if s == nil then return nil end\r
+ if #s == 0 then return nil end\r
+ if type(s) == 'string' then\r
+ local utils = require('utils')\r
+ local ascii = utils.ConvertHexToAscii(s)\r
+ local hashed = core.iso14443b_crc(ascii)\r
+ return utils.ConvertAsciiToHex(hashed)\r
+ end\r
+ return nil \r
+ end,\r
\r
------------ CRC-16 ccitt checksums\r
-- Takes a hex string and calculates a crc16\r
---\r
-- Convert Byte array to string of hex\r
ConvertBytesToHex = function(bytes)\r
- if #bytes == 0 then\r
- return ''\r
- end\r
+ if bytes == nil then return '' end\r
+ if #bytes == 0 then return '' end\r
local s={}\r
- for i = 1, #(bytes) do\r
+ for i = 1, #bytes do\r
s[i] = string.format("%02X",bytes[i]) \r
end\r
return table.concat(s)\r
end, \r
-- Convert byte array to string with ascii\r
ConvertBytesToAscii = function(bytes)\r
- if #bytes == 0 then\r
- return ''\r
- end\r
+ if bytes == nil then return '' end\r
+ if #bytes == 0 then return '' end\r
local s={}\r
for i = 1, #(bytes) do\r
s[i] = string.char(bytes[i]) \r
end,\r
\r
ConvertHexToAscii = function(s)\r
+ if s == nil then return '' end\r
+ if #s == 0 then return '' end\r
local t={}\r
- if s == nil then return t end\r
- if #s == 0 then return t end\r
for k in s:gmatch"(%x%x)" do\r
table.insert(t, string.char(tonumber(k,16)))\r
end\r
- return table.concat(t) \r
+ return table.concat(t) \r
+ end,\r
+ \r
+ ConvertAsciiToHex = function(s) \r
+ if s == nil then return '' end\r
+ if #s == 0 then return '' end\r
+ local t={}\r
+ for k in s:gmatch"(.)" do\r
+ table.insert(t, string.format("%02X", string.byte(k)))\r
+ end\r
+ return table.concat(t)\r
end,\r
\r
Chars2num = function(s)\r
#include "util.h"
#include "nonce2key/nonce2key.h"
#include "../common/iso15693tools.h"
+#include "iso14443crc.h"
#include "../common/crc16.h"
#include "../common/crc64.h"
#include "../common/sha1.h"
const char *data = luaL_checklstring(L, 1, &size);
if(size != sizeof(UsbCommand))
{
- printf("Got data size %d, expected %d" , (int) size,(int) sizeof(UsbCommand));
+ printf("Got data size %d, expected %d" , size, sizeof(UsbCommand));
lua_pushstring(L,"Wrong data size");
return 1;
}
-// UsbCommand c = (*data);
SendCommand((UsbCommand* )data);
return 0; // no return values
}
if(WaitForResponseTimeout(cmd, &response, ms_timeout))
{
//Push it as a string
- lua_pushlstring(L,(const char *)&response,sizeof(UsbCommand));
+ lua_pushlstring(L,(const char *)&response, sizeof(UsbCommand));
return 1;// return 1 to signal one return value
}else{
return 1;
}
+static int l_iso14443b_crc(lua_State *L)
+{
+ /* void ComputeCrc14443(int CrcType,
+ const unsigned char *Data, int Length,
+ unsigned char *TransmitFirst,
+ unsigned char *TransmitSecond)
+ */
+ unsigned char buf[USB_CMD_DATA_SIZE];
+ size_t len = 0;
+ const char *data = luaL_checklstring(L, 1, &len);
+ if (USB_CMD_DATA_SIZE < len)
+ len = USB_CMD_DATA_SIZE-2;
+
+ for (int i = 0; i < len; i += 2) {
+ sscanf(&data[i], "%02x", (unsigned int *)&buf[i / 2]);
+ }
+ ComputeCrc14443(CRC_14443_B, buf, len, &buf[len], &buf[len+1]);
+
+ lua_pushlstring(L, (const char *)&buf, len+2);
+ return 1;
+}
+
/*
Simple AES 128 cbc hook up to OpenSSL.
params: key, input
{"clearCommandBuffer", l_clearCommandBuffer},
{"console", l_CmdConsole},
{"iso15693_crc", l_iso15693_crc},
+ {"iso14443b_crc", l_iso14443b_crc},
{"aes128_decrypt", l_aes128decrypt_cbc},
{"aes128_decrypt_ecb", l_aes128decrypt_ecb},
{"aes128_encrypt", l_aes128encrypt_cbc},
-- Sends an instruction to do nothing, only disconnect
function disconnect()
- local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a,
- arg1 = 0, -- Nothing
- }
+ local command = Command:new{cmd = cmds.CMD_READER_ISO_14443a, arg1 = 0, }
-- We can ignore the response here, no ACK is returned for this command
-- Check /armsrc/iso14443a.c, ReaderIso14443a() for details
return lib14a.sendToDevice(command,true)
local DEBUG = false -- the debug flag
local RANDOM = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
-local band = bit32.band
-local bor = bit32.bor
-local lshift = bit32.lshift
-local rshift = bit32.rshift
-local byte = string.byte
-local char = string.char
-local sub = string.sub
-local format = string.format
-
-
-
local band = bit32.band
local bor = bit32.bor
local lshift = bit32.lshift
-- This is only meant to be used when errors occur
function oops(err)
print("ERROR: ",err)
+ return nil,err
end
---
-- Usage help
memset(&sp->dcb, 0, sizeof(DCB));
sp->dcb.DCBlength = sizeof(DCB);
if(!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb)) {
- uart_close(sp);
- return INVALID_SERIAL_PORT;
- }
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
// Update the active serial port
if(!SetCommState(sp->hPort,&sp->dcb)) {
//* \brief This function Activates the USB device\r
//*----------------------------------------------------------------------------\r
void usb_enable() {\r
- // Set the PLL USB Divider\r
- AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;\r
- \r
- // Specific Chip USB Initialisation\r
- // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock\r
- AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;\r
- AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);\r
- \r
- // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO\r
- // Set in PIO mode and Configure in Output\r
- AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode\r
+ // Set the PLL USB Divider\r
+ AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;\r
+\r
+ // Specific Chip USB Initialisation\r
+ // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock\r
+ AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;\r
+ AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);\r
+\r
+ // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO\r
+ // Set in PIO mode and Configure in Output\r
+ AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode\r
AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output\r
- \r
- // Clear for set the Pullup resistor\r
+\r
+ // Clear for set the Pullup resistor\r
AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU;\r
- \r
- // Disconnect and reconnect USB controller for 100ms\r
- usb_disable();\r
- \r
- // Wait for a short while\r
- for (volatile size_t i=0; i<0x100000; i++);\r
\r
- // Reconnect USB reconnect\r
- AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;\r
- AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU;\r
+ // Disconnect and reconnect USB controller for 100ms\r
+ usb_disable();\r
+\r
+ // Wait for a short while\r
+ for (volatile size_t i=0; i<0x100000; i++);\r
+ //sleep(1);\r
+ \r
+ // Reconnect USB reconnect\r
+ AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;\r
+ AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU;\r
}\r
\r
//*----------------------------------------------------------------------------\r
//* \brief Read available data from Endpoint OUT\r
//*----------------------------------------------------------------------------\r
uint32_t usb_read(byte_t* data, size_t len) {\r
- byte_t bank = btReceiveBank;\r
+ byte_t bank = btReceiveBank;\r
uint32_t packetSize, nbBytesRcv = 0;\r
- uint32_t time_out = 0;\r
+ uint32_t time_out = 0;\r
\r
while (len) {\r
if (!usb_check()) break;\r
\r
if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);\r
- len -= packetSize;\r
+ len -= packetSize;\r
while(packetSize--)\r
data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];\r
+ \r
pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);\r
- if (bank == AT91C_UDP_RX_DATA_BK0) {\r
+ \r
+ if (bank == AT91C_UDP_RX_DATA_BK0)\r
bank = AT91C_UDP_RX_DATA_BK1;\r
- } else {\r
- bank = AT91C_UDP_RX_DATA_BK0;\r
- }\r
+ else\r
+ bank = AT91C_UDP_RX_DATA_BK0; \r
}\r
- if (time_out++ == 0x1fff) break;\r
+ if (time_out++ == 0x1fff) break;\r
}\r
\r
btReceiveBank = bank;\r
//* \brief Send through endpoint 2\r
//*----------------------------------------------------------------------------\r
uint32_t usb_write(const byte_t* data, const size_t len) {\r
- size_t length = len;\r
+ size_t length = len;\r
uint32_t cpt = 0;\r
\r
- if (!length) return 0;\r
- if (!usb_check()) return 0;\r
+ if (!length) return 0;\r
+ if (!usb_check()) return 0;\r
\r
// Send the first packet\r
cpt = MIN(length, AT91C_EP_IN_SIZE-1);\r
// Wait for the the first bank to be sent\r
while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
if (!usb_check()) return length;\r
- }\r
+ }\r
pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);\r
+ \r
while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\r
+ \r
pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;\r
}\r
\r
// Wait for the end of transfer\r
while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
if (!usb_check()) return length;\r
- }\r
+ }\r
\r
pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);\r
while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\r