#include "proxmark3.h"
#include "apps.h"
#include "LCD.h"
+#include "fonts.h"
void LCDSend(unsigned int data)
{
LCDSend(PRAMWR); // Write to display
i=LCD_XRES*LCD_YRES;
while(i--) LCDSend(WHITE);
+
+ // test text on different colored backgrounds
+ LCDString(" The quick brown fox ", (char *)&FONT6x8,1,1+8*0,WHITE ,BLACK );
+ LCDString(" jumped over the ", (char *)&FONT6x8,1,1+8*1,BLACK ,WHITE );
+ LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED );
+ LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN );
+ LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE );
+ LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8,1,1+8*5,BLUE ,YELLOW);
+ LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8,1,1+8*6,BLACK ,CYAN );
+ LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
+
+ // color bands
+ LCDFill(0, 1+8* 8, 132, 8, BLACK);
+ LCDFill(0, 1+8* 9, 132, 8, WHITE);
+ LCDFill(0, 1+8*10, 132, 8, RED);
+ LCDFill(0, 1+8*11, 132, 8, GREEN);
+ LCDFill(0, 1+8*12, 132, 8, BLUE);
+ LCDFill(0, 1+8*13, 132, 8, YELLOW);
+ LCDFill(0, 1+8*14, 132, 8, CYAN);
+ LCDFill(0, 1+8*15, 132, 8, MAGENTA);
+
}
#remove one of the following defines and comment out the relevant line
#in the next section to remove that particular feature from compilation
-APP_CFLAGS = -O2 -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG
+APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG
#-DWITH_LCD
#SRC_LCD = fonts.c LCD.c
appmain.c printf.c \
util.c \
string.c \
- usb.c
+ usb_cdc.c \
+ cmd.c
# These are to be compiled in ARM mode
ARMSRC = fpgaloader.c \
// executes.
//-----------------------------------------------------------------------------
+#include "usb_cdc.h"
+#include "cmd.h"
+
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
#include <hitag2.h>
#ifdef WITH_LCD
-# include "fonts.h"
-# include "LCD.h"
+ #include "LCD.h"
#endif
#define abs(x) ( ((x)<0) ? -(x) : (x) )
void DbpString(char *str)
{
- /* this holds up stuff unless we're connected to usb */
- if (!UsbConnected())
- return;
-
- UsbCommand c;
- c.cmd = CMD_DEBUG_PRINT_STRING;
- c.arg[0] = strlen(str);
- if(c.arg[0] > sizeof(c.d.asBytes)) {
- c.arg[0] = sizeof(c.d.asBytes);
- }
- memcpy(c.d.asBytes, str, c.arg[0]);
-
- UsbSendPacket((uint8_t *)&c, sizeof(c));
- // TODO fix USB so stupid things like this aren't req'd
- SpinDelay(50);
+ byte_t len = strlen(str);
+ cmd_send(CMD_DEBUG_PRINT_STRING,len,0,0,(byte_t*)str,len);
+// /* this holds up stuff unless we're connected to usb */
+// if (!UsbConnected())
+// return;
+//
+// UsbCommand c;
+// c.cmd = CMD_DEBUG_PRINT_STRING;
+// c.arg[0] = strlen(str);
+// if(c.arg[0] > sizeof(c.d.asBytes)) {
+// c.arg[0] = sizeof(c.d.asBytes);
+// }
+// memcpy(c.d.asBytes, str, c.arg[0]);
+//
+// UsbSendPacket((uint8_t *)&c, sizeof(c));
+// // TODO fix USB so stupid things like this aren't req'd
+// SpinDelay(50);
}
#if 0
void DbpIntegers(int x1, int x2, int x3)
{
- /* this holds up stuff unless we're connected to usb */
- if (!UsbConnected())
- return;
-
- UsbCommand c;
- c.cmd = CMD_DEBUG_PRINT_INTEGERS;
- c.arg[0] = x1;
- c.arg[1] = x2;
- c.arg[2] = x3;
-
- UsbSendPacket((uint8_t *)&c, sizeof(c));
- // XXX
- SpinDelay(50);
+ cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0);
+// /* this holds up stuff unless we're connected to usb */
+// if (!UsbConnected())
+// return;
+//
+// UsbCommand c;
+// c.cmd = CMD_DEBUG_PRINT_INTEGERS;
+// c.arg[0] = x1;
+// c.arg[1] = x2;
+// c.arg[2] = x3;
+//
+// UsbSendPacket((uint8_t *)&c, sizeof(c));
+// // XXX
+// SpinDelay(50);
}
#endif
int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0
int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
- UsbCommand c;
+// UsbCommand c;
LED_B_ON();
DbpString("Measuring antenna characteristics, please wait...");
// can measure voltages up to 33000 mV
vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
- c.cmd = CMD_MEASURED_ANTENNA_TUNING;
- c.arg[0] = (vLf125 << 0) | (vLf134 << 16);
- c.arg[1] = vHf;
- c.arg[2] = peakf | (peakv << 16);
+// c.cmd = CMD_MEASURED_ANTENNA_TUNING;
+// c.arg[0] = (vLf125 << 0) | (vLf134 << 16);
+// c.arg[1] = vHf;
+// c.arg[2] = peakf | (peakv << 16);
DbpString("Measuring complete, sending report back to host");
-
- UsbSendPacket((uint8_t *)&c, sizeof(c));
+ cmd_send(CMD_MEASURED_ANTENNA_TUNING,vLf125|(vLf134<<16),vHf,peakf|(peakv<<16),0,0);
+// UsbSendPacket((uint8_t *)&c, sizeof(c));
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_A_OFF();
LED_B_OFF();
for (;;)
{
- UsbPoll(FALSE);
- WDT_HIT();
+// UsbPoll(FALSE);
+ usb_poll();
+ WDT_HIT();
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
void UsbPacketReceived(uint8_t *packet, int len)
{
UsbCommand *c = (UsbCommand *)packet;
- UsbCommand ack;
- ack.cmd = CMD_ACK;
+// Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]);
+
switch(c->cmd) {
#ifdef WITH_LF
case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
AcquireRawAdcSamples125k(c->arg[0]);
- UsbSendPacket((uint8_t*)&ack, sizeof(ack));
+ cmd_send(CMD_ACK,0,0,0,0,0);
break;
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
case CMD_HID_SIM_TAG:
CmdHIDsimTAG(c->arg[0], c->arg[1], 1); // Simulate HID tag by ID
break;
- case CMD_HID_CLONE_TAG: // Clone HID tag by ID to T55x7
- CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
+ case CMD_HID_CLONE_TAG: // Clone HID tag by ID to T55x7
+ CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
break;
case CMD_EM410X_WRITE_TAG:
WriteEM410x(c->arg[0], c->arg[1], c->arg[2]);
case CMD_INDALA_CLONE_TAG_L: // Clone Indala 224-bit tag by UID to T55x7
CopyIndala224toT55x7(c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]);
break;
- case CMD_T55XX_READ_BLOCK:
- T55xxReadBlock(c->arg[1], c->arg[2],c->d.asBytes[0]);
- break;
- case CMD_T55XX_WRITE_BLOCK:
- T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
- break;
- case CMD_T55XX_READ_TRACE: // Clone HID tag by ID to T55x7
- T55xxReadTrace();
- break;
- case CMD_PCF7931_READ: // Read PCF7931 tag
- ReadPCF7931();
- UsbSendPacket((uint8_t*)&ack, sizeof(ack));
- break;
- case CMD_EM4X_READ_WORD:
- EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
- break;
- case CMD_EM4X_WRITE_WORD:
- EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
- break;
+ case CMD_T55XX_READ_BLOCK:
+ T55xxReadBlock(c->arg[1], c->arg[2],c->d.asBytes[0]);
+ break;
+ case CMD_T55XX_WRITE_BLOCK:
+ T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
+ break;
+ case CMD_T55XX_READ_TRACE: // Clone HID tag by ID to T55x7
+ T55xxReadTrace();
+ break;
+ case CMD_PCF7931_READ: // Read PCF7931 tag
+ ReadPCF7931();
+ cmd_send(CMD_ACK,0,0,0,0,0);
+// UsbSendPacket((uint8_t*)&ack, sizeof(ack));
+ break;
+ case CMD_EM4X_READ_WORD:
+ EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
+ break;
+ case CMD_EM4X_WRITE_WORD:
+ EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
+ break;
#endif
#ifdef WITH_HITAG
SnoopIso14443a(c->arg[0]);
break;
case CMD_READER_ISO_14443a:
- ReaderIso14443a(c, &ack);
+ ReaderIso14443a(c);
break;
case CMD_SIMULATE_TAG_ISO_14443a:
SimulateIso14443aTag(c->arg[0], c->arg[1], c->arg[2]); // ## Simulate iso14443a tag - pass tag type & UID
break;
case CMD_EPA_PACE_COLLECT_NONCE:
- EPA_PACE_Collect_Nonce(c, &ack);
+ EPA_PACE_Collect_Nonce(c);
break;
case CMD_READER_MIFARE:
break;
case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: {
- UsbCommand n;
- if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
- n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
- } else {
- n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
- }
- n.arg[0] = c->arg[0];
- memcpy(n.d.asDwords, BigBuf+c->arg[0], 12*sizeof(uint32_t));
- LED_B_ON();
- UsbSendPacket((uint8_t *)&n, sizeof(n));
+// UsbCommand n;
+// if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
+// n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
+// } else {
+// n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
+// }
+// n.arg[0] = c->arg[0];
+ // memcpy(n.d.asBytes, BigBuf+c->arg[0], 48); // 12*sizeof(uint32_t)
+ // LED_B_ON();
+ // usb_write((uint8_t *)&n, sizeof(n));
+ // UsbSendPacket((uint8_t *)&n, sizeof(n));
+ // LED_B_OFF();
+
+ LED_B_ON();
+ for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
+ size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
+ cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len);
+ }
+ // Trigger a finish downloading signal with an ACK frame
+ cmd_send(CMD_ACK,0,0,0,0,0);
LED_B_OFF();
} break;
uint8_t *b = (uint8_t *)BigBuf;
memcpy(b+c->arg[0], c->d.asBytes, 48);
//Dbprintf("copied 48 bytes to %i",b+c->arg[0]);
- UsbSendPacket((uint8_t*)&ack, sizeof(ack));
+// UsbSendPacket((uint8_t*)&ack, sizeof(ack));
+ cmd_send(CMD_ACK,0,0,0,0,0);
} break;
case CMD_READ_MEM:
case CMD_SETUP_WRITE:
case CMD_FINISH_WRITE:
case CMD_HARDWARE_RESET: {
- USB_D_PLUS_PULLUP_OFF();
+ usb_disable();
SpinDelay(1000);
SpinDelay(1000);
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
if(common_area.flags.bootrom_present) {
common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
}
- USB_D_PLUS_PULLUP_OFF();
+ usb_disable();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
for(;;);
} break;
case CMD_DEVICE_INFO: {
- UsbCommand c;
- c.cmd = CMD_DEVICE_INFO;
- c.arg[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
- if(common_area.flags.bootrom_present) c.arg[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
- UsbSendPacket((uint8_t*)&c, sizeof(c));
+ uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
+ if(common_area.flags.bootrom_present) dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
+// UsbSendPacket((uint8_t*)&c, sizeof(c));
+ cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
} break;
default: {
LED_B_OFF();
LED_A_OFF();
- UsbStart();
+ // Init USB device`
+ usb_enable();
+// UsbStart();
// The FPGA gets its clock from us from PCK0 output, so set that up.
AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
FpgaDownloadAndGo();
StartTickCount();
-
+
#ifdef WITH_LCD
-
LCDInit();
-
- // test text on different colored backgrounds
- LCDString(" The quick brown fox ", (char *)&FONT6x8,1,1+8*0,WHITE ,BLACK );
- LCDString(" jumped over the ", (char *)&FONT6x8,1,1+8*1,BLACK ,WHITE );
- LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED );
- LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN );
- LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE );
- LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8,1,1+8*5,BLUE ,YELLOW);
- LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8,1,1+8*6,BLACK ,CYAN );
- LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
-
- // color bands
- LCDFill(0, 1+8* 8, 132, 8, BLACK);
- LCDFill(0, 1+8* 9, 132, 8, WHITE);
- LCDFill(0, 1+8*10, 132, 8, RED);
- LCDFill(0, 1+8*11, 132, 8, GREEN);
- LCDFill(0, 1+8*12, 132, 8, BLUE);
- LCDFill(0, 1+8*13, 132, 8, YELLOW);
- LCDFill(0, 1+8*14, 132, 8, CYAN);
- LCDFill(0, 1+8*15, 132, 8, MAGENTA);
-
#endif
+ byte_t rx[sizeof(UsbCommand)];
+ size_t rx_len;
+
for(;;) {
- UsbPoll(FALSE);
+ if (usb_poll()) {
+ rx_len = usb_read(rx,sizeof(UsbCommand));
+ if (rx_len) {
+ UsbPacketReceived(rx,rx_len);
+ }
+ }
+// UsbPoll(FALSE);
+
WDT_HIT();
#ifdef WITH_LF
#include <stddef.h>
#include "common.h"
#include "hitag2.h"
+#include "mifare.h"
// The large multi-purpose buffer, typically used to hold A/D samples,
// maybe processed in some way.
int IsBlock0PCF7931(uint8_t *Block);
int IsBlock1PCF7931(uint8_t *Block);
void ReadPCF7931();
-void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
-void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
+void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
+void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
/// iso14443.h
void SimulateIso14443Tag(void);
/// iso14443a.h
void RAMFUNC SnoopIso14443a(uint8_t param);
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd); // ## simulate iso14443a tag
-void ReaderIso14443a(UsbCommand * c, UsbCommand * ack);
+void ReaderIso14443a(UsbCommand * c);
// Also used in iclass.c
int RAMFUNC LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader);
uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
-void iso14a_set_trigger(int enable);
-void iso14a_clear_trace(void);
-void iso14a_set_tracing(int enable);
+void iso14a_set_trigger(bool enable);
+void iso14a_clear_trace();
+void iso14a_set_tracing(bool enable);
void RAMFUNC SniffMifare(uint8_t param);
/// epa.h
-void EPA_PACE_Collect_Nonce(UsbCommand * c, UsbCommand * ack);
+void EPA_PACE_Collect_Nonce(UsbCommand * c);
// mifarecmd.h
void ReaderMifare(uint32_t parameter);
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data);
void ReaderHitag(hitag_function htf, hitag_data* htd);
+// cmd.h
+bool cmd_receive(UsbCommand* cmd);
+bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);
+
/// util.h
#endif
//-----------------------------------------------------------------------------
#include "iso14443a.h"
-
#include "epa.h"
+#include "cmd.h"
// Protocol and Parameter Selection Request
// use regular (1x) speed in both directions
// Abort helper function for EPA_PACE_Collect_Nonce
// sets relevant data in ack, sends the response
//-----------------------------------------------------------------------------
-static void EPA_PACE_Collect_Nonce_Abort(UsbCommand *ack, uint8_t step, int func_return)
+static void EPA_PACE_Collect_Nonce_Abort(uint8_t step, int func_return)
{
- // step in which the failure occured
- ack->arg[0] = step;
- // last return code
- ack->arg[1] = func_return;
+// // step in which the failure occured
+// ack->arg[0] = step;
+// // last return code
+// ack->arg[1] = func_return;
// power down the field
EPA_Finish();
// send the USB packet
- UsbSendPacket((void *)ack, sizeof(UsbCommand));
+ cmd_send(CMD_ACK,step,func_return,0,0,0);
+//UsbSendPacket((void *)ack, sizeof(UsbCommand));
}
//-----------------------------------------------------------------------------
// Acquire one encrypted PACE nonce
//-----------------------------------------------------------------------------
-void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
+void EPA_PACE_Collect_Nonce(UsbCommand *c)
{
/*
* ack layout:
// return value of a function
int func_return;
- // initialize ack with 0s
- memset(ack->arg, 0, 12);
- memset(ack->d.asBytes, 0, 48);
+// // initialize ack with 0s
+// memset(ack->arg, 0, 12);
+// memset(ack->d.asBytes, 0, 48);
// set up communication
func_return = EPA_Setup();
if (func_return != 0) {
- EPA_PACE_Collect_Nonce_Abort(ack, 1, func_return);
+ EPA_PACE_Collect_Nonce_Abort(1, func_return);
return;
}
int card_access_length = EPA_Read_CardAccess(card_access, 256);
// the response has to be at least this big to hold the OID
if (card_access_length < 18) {
- EPA_PACE_Collect_Nonce_Abort(ack, 2, card_access_length);
+ EPA_PACE_Collect_Nonce_Abort(2, card_access_length);
return;
}
card_access_length,
&pace_version_info);
if (func_return != 0 || pace_version_info.version == 0) {
- EPA_PACE_Collect_Nonce_Abort(ack, 3, func_return);
+ EPA_PACE_Collect_Nonce_Abort(3, func_return);
return;
}
// check if the command succeeded
if (func_return < 0)
{
- EPA_PACE_Collect_Nonce_Abort(ack, 4, func_return);
+ EPA_PACE_Collect_Nonce_Abort(4, func_return);
return;
}
+
+ // all done, return
+ EPA_Finish();
// save received information
- ack->arg[1] = func_return;
- memcpy(ack->d.asBytes, nonce, func_return);
-
- // all done, return
- EPA_Finish();
- UsbSendPacket((void *)ack, sizeof(UsbCommand));
+// ack->arg[1] = func_return;
+// memcpy(ack->d.asBytes, nonce, func_return);
+// UsbSendPacket((void *)ack, sizeof(UsbCommand));
+ cmd_send(CMD_ACK,0,func_return,0,nonce,func_return);
}
//-----------------------------------------------------------------------------
// 8 bits per transfer, no loopback, MSB first, 1 transfer per sync
// pulse, no output sync, start on positive-going edge of sync
- AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) |
- AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
+ AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
// clock comes from TK pin, no clock output, outputs change on falling
// edge of TK, start on rising edge of TF
- AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) |
- SSC_CLOCK_MODE_START(5);
+ AT91C_BASE_SSC->SSC_TCMR = SSC_CLOCK_MODE_SELECT(2) | SSC_CLOCK_MODE_START(5);
// tx framing is the same as the rx framing
AT91C_BASE_SSC->SSC_TFMR = AT91C_BASE_SSC->SSC_RFMR;
bool bCrypto;
bool bAuthenticating;
bool bPwd;
+bool bSuccessful;
struct hitag2_tag {
uint32_t uid;
*txlen = 32;
memcpy(tx,password,4);
bPwd = true;
- memcpy(tag.sectors[blocknr],rx,4);
- blocknr++;
+ memcpy(tag.sectors[blocknr],rx,4);
+ blocknr++;
} else {
if(blocknr == 1){
blocknr++;
if (blocknr > 7) {
DbpString("Read succesful!");
- // We are done... for now
+ bSuccessful = true;
return false;
}
*txlen = 10;
case 0: {
// Stop if there is no answer while we are in crypto mode (after sending NrAr)
if (bCrypto) {
- DbpString("Authentication failed!");
- return false;
- }
- *txlen = 5;
- memcpy(tx,"\xc0",nbytes(*txlen));
+ // Failed during authentication
+ if (bAuthenticating) {
+ DbpString("Authentication failed!");
+ return false;
+ } else {
+ // Failed reading a block, could be (read/write) locked, skip block and re-authenticate
+ if (blocknr == 1) {
+ // Write the low part of the key in memory
+ memcpy(tag.sectors[1],key+2,4);
+ } else if (blocknr == 2) {
+ // Write the high part of the key in memory
+ tag.sectors[2][0] = 0x00;
+ tag.sectors[2][1] = 0x00;
+ tag.sectors[2][2] = key[0];
+ tag.sectors[2][3] = key[1];
+ } else {
+ // Just put zero's in the memory (of the unreadable block)
+ memset(tag.sectors[blocknr],0x00,4);
+ }
+ blocknr++;
+ bCrypto = false;
+ }
+ } else {
+ *txlen = 5;
+ memcpy(tx,"\xc0",nbytes(*txlen));
+ }
} break;
// Received UID, crypto tag answer
}
if (blocknr > 7) {
DbpString("Read succesful!");
- // We are done... for now
+ bSuccessful = true;
return false;
}
*txlen = 10;
int t_wait = HITAG_T_WAIT_MAX;
bool bStop;
bool bQuitTraceFull = false;
-
+
+ // Reset the return status
+ bSuccessful = false;
+
// Clean up trace and prepare it for storing frames
iso14a_set_tracing(TRUE);
iso14a_clear_trace();
lastbit = 1;
bStop = false;
- // Tag specific configuration settings (sof, timings, etc.)
- if (htf < 10){
- // hitagS settings
- reset_sof = 1;
- t_wait = 200;
- DbpString("Configured for hitagS reader");
- } else if (htf < 20) {
- // hitag1 settings
- reset_sof = 1;
- t_wait = 200;
- DbpString("Configured for hitag1 reader");
- } else if (htf < 30) {
- // hitag2 settings
- reset_sof = 4;
- t_wait = HITAG_T_WAIT_2;
- DbpString("Configured for hitag2 reader");
+ // Tag specific configuration settings (sof, timings, etc.)
+ if (htf < 10){
+ // hitagS settings
+ reset_sof = 1;
+ t_wait = 200;
+ DbpString("Configured for hitagS reader");
+ } else if (htf < 20) {
+ // hitag1 settings
+ reset_sof = 1;
+ t_wait = 200;
+ DbpString("Configured for hitag1 reader");
+ } else if (htf < 30) {
+ // hitag2 settings
+ reset_sof = 4;
+ t_wait = HITAG_T_WAIT_2;
+ DbpString("Configured for hitag2 reader");
} else {
- Dbprintf("Error, unknown hitag reader type: %d",htf);
- return;
- }
+ Dbprintf("Error, unknown hitag reader type: %d",htf);
+ return;
+ }
while(!bStop && !BUTTON_PRESS()) {
// Watchdog hit
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-
-// Dbprintf("frame received: %d",frame_count);
-// DbpString("All done");
+ Dbprintf("frame received: %d",frame_count);
+ DbpString("All done");
+ cmd_send(CMD_ACK,bSuccessful,0,0,(byte_t*)tag.sectors,48);
}
#include "apps.h"
#include "util.h"
#include "string.h"
+#include "cmd.h"
#include "iso14443crc.h"
#include "iso14443a.h"
};
-void iso14a_set_trigger(int enable) {
+void iso14a_set_trigger(bool enable) {
trigger = enable;
}
-void iso14a_clear_trace(void) {
- memset(trace, 0x44, TRACE_SIZE);
+void iso14a_clear_trace() {
+ memset(trace, 0x44, TRACE_SIZE);
traceLen = 0;
}
-void iso14a_set_tracing(int enable) {
+void iso14a_set_tracing(bool enable) {
tracing = enable;
}
respdata = &nack;
respsize = sizeof(nack); // 4-bit answer
} else if(receivedCmd[0] == 0x50) { // Received a HALT
- DbpString("Reader requested we HALT!:");
+// DbpString("Reader requested we HALT!:");
// Do not respond
resp = resp1; respLen = 0; order = 0;
respdata = NULL;
respdata = response6;
respsize = sizeof(response6);
} else {
- // Never seen this command before
- Dbprintf("Received (len=%d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- len,
- receivedCmd[0], receivedCmd[1], receivedCmd[2],
- receivedCmd[3], receivedCmd[4], receivedCmd[5],
- receivedCmd[6], receivedCmd[7], receivedCmd[8]);
- // Do not respond
- resp = resp1; respLen = 0; order = 0;
- respdata = NULL;
- respsize = 0;
+ if (order == 7 && len ==8) {
+ uint32_t nr = bytes_to_num(receivedCmd,4);
+ uint32_t ar = bytes_to_num(receivedCmd+4,4);
+ Dbprintf("Auth attempt {nr}{ar}: %08x %08x",nr,ar);
+ } else {
+ // Never seen this command before
+ Dbprintf("Received unknown command (len=%d):",len);
+ Dbhexdump(len,receivedCmd,false);
+ }
+ // Do not respond
+ resp = resp1; respLen = 0; order = 0;
+ respdata = NULL;
+ respsize = 0;
}
// Count number of wakeups received after a halt
/* performs iso14443a anticolision procedure
* fills the uid pointer unless NULL
* fills resp_data unless NULL */
-int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, uint32_t * cuid_ptr) {
+int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, uint32_t* cuid_ptr) {
uint8_t wupa[] = { 0x52 }; // 0x26 - REQA 0x52 - WAKE-UP
uint8_t sel_all[] = { 0x93,0x20 };
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
-
- uint8_t* resp = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
+ uint8_t* resp = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); // was 3560 - tied to other size changes
+ byte_t uid_resp[4];
+ size_t uid_resp_len;
uint8_t sak = 0x04; // cascade uid
int cascade_level = 0;
-
int len;
-
- // clear uid
- memset(uid_ptr, 0, 8);
-
+
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
ReaderTransmitShort(wupa);
// Receive the ATQA
if(!ReaderReceive(resp)) return 0;
-
- if(resp_data)
- memcpy(resp_data->atqa, resp, 2);
+// Dbprintf("atqa: %02x %02x",resp[0],resp[1]);
+
+ if(p_hi14a_card) {
+ memcpy(p_hi14a_card->atqa, resp, 2);
+ p_hi14a_card->uidlen = 0;
+ memset(p_hi14a_card->uid,0,10);
+ }
+ // clear uid
+ if (uid_ptr) {
+ memset(uid_ptr,0,10);
+ }
+
// OK we will select at least at cascade 1, lets see if first byte of UID was 0x88 in
// which case we need to make a cascade 2 request and select - this is a long UID
// While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
// SELECT_ALL
ReaderTransmit(sel_all,sizeof(sel_all));
if (!ReaderReceive(resp)) return 0;
- if(uid_ptr) memcpy(uid_ptr + cascade_level*4, resp, 4);
-
+
+ // First backup the current uid
+ memcpy(uid_resp,resp,4);
+ uid_resp_len = 4;
+ // Dbprintf("uid: %02x %02x %02x %02x",uid_resp[0],uid_resp[1],uid_resp[2],uid_resp[3]);
+
// calculate crypto UID
- if(cuid_ptr) *cuid_ptr = bytes_to_num(resp, 4);
+ if(cuid_ptr) {
+ *cuid_ptr = bytes_to_num(uid_resp, 4);
+ }
// Construct SELECT UID command
memcpy(sel_uid+2,resp,5);
// Receive the SAK
if (!ReaderReceive(resp)) return 0;
sak = resp[0];
+
+ // Test if more parts of the uid are comming
+ if ((sak & 0x04) && uid_resp[0] == 0x88) {
+ // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
+ // http://www.nxp.com/documents/application_note/AN10927.pdf
+ memcpy(uid_ptr, uid_ptr + 1, 3);
+ uid_resp_len = 3;
+ }
+
+ if(uid_ptr) {
+ memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
+ }
+
+ if(p_hi14a_card) {
+ memcpy(p_hi14a_card->uid + (cascade_level*3), uid_resp, uid_resp_len);
+ p_hi14a_card->uidlen += uid_resp_len;
+ }
}
- if(resp_data) {
- resp_data->sak = sak;
- resp_data->ats_len = 0;
- }
- //-- this byte not UID, it CT. http://www.nxp.com/documents/application_note/AN10927.pdf page 3
- if (uid_ptr[0] == 0x88) {
- memcpy(uid_ptr, uid_ptr + 1, 7);
- uid_ptr[7] = 0;
+
+ if(p_hi14a_card) {
+ p_hi14a_card->sak = sak;
+ p_hi14a_card->ats_len = 0;
}
- if( (sak & 0x20) == 0)
+ if( (sak & 0x20) == 0) {
return 2; // non iso14443a compliant tag
+ }
// Request for answer to select
- if(resp_data) { // JCOP cards - if reader sent RATS then there is no MIFARE session at all!!!
+ if(p_hi14a_card) { // JCOP cards - if reader sent RATS then there is no MIFARE session at all!!!
AppendCrc14443a(rats, 2);
ReaderTransmit(rats, sizeof(rats));
if (!(len = ReaderReceive(resp))) return 0;
- memcpy(resp_data->ats, resp, sizeof(resp_data->ats));
- resp_data->ats_len = len;
+ memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats));
+ p_hi14a_card->ats_len = len;
}
// reset the PCB block number
iso14_pcb_blocknum = 0;
-
return 1;
}
void iso14443a_setup() {
- // Setup SSC
- FpgaSetupSsc();
+ // Set up the synchronous serial port
+ FpgaSetupSsc();
// Start from off (no field generated)
// Signal field is off with the appropriate LED
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelay(200);
+ SpinDelay(50);
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
// Signal field is on with the appropriate LED
LED_D_ON();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
- SpinDelay(200);
+ SpinDelay(50);
iso14a_timeout = 2048; //default
}
// Read an ISO 14443a tag. Send out commands and store answers.
//
//-----------------------------------------------------------------------------
-void ReaderIso14443a(UsbCommand * c, UsbCommand * ack)
+void ReaderIso14443a(UsbCommand * c)
{
iso14a_command_t param = c->arg[0];
uint8_t * cmd = c->d.asBytes;
size_t len = c->arg[1];
- uint8_t *receiveBuf = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
+ uint32_t arg0 = 0;
+ byte_t buf[USB_CMD_DATA_SIZE];
+
+ iso14a_clear_trace();
+ iso14a_set_tracing(true);
- if(param & ISO14A_REQUEST_TRIGGER) iso14a_set_trigger(1);
+ if(param & ISO14A_REQUEST_TRIGGER) {
+ iso14a_set_trigger(1);
+ }
if(param & ISO14A_CONNECT) {
iso14443a_setup();
- ack->arg[0] = iso14443a_select_card(ack->d.asBytes, (iso14a_card_select_t *) (ack->d.asBytes+12), NULL);
- UsbSendPacket((void *)ack, sizeof(UsbCommand));
+ arg0 = iso14443a_select_card(NULL,(iso14a_card_select_t*)buf,NULL);
+ cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(iso14a_card_select_t));
+// UsbSendPacket((void *)ack, sizeof(UsbCommand));
}
if(param & ISO14A_SET_TIMEOUT) {
}
if(param & ISO14A_APDU) {
- memcpy(receiveBuf, ack->d.asBytes, len);
- ack->arg[0] = iso14_apdu(cmd, len, receiveBuf);
-
- while(ack->arg[0] > sizeof(ack->d))
- {
- memcpy(ack->d.asBytes, receiveBuf, sizeof(ack->d));
- UsbSendPacket((void *)ack, sizeof(UsbCommand));
-
- receiveBuf+=sizeof(ack->d);
- ack->arg[0]-=sizeof(ack->d);
- }
-
- memcpy(ack->d.asBytes, receiveBuf, ack->arg[0]);
- UsbSendPacket((void *)ack, sizeof(UsbCommand));
+ arg0 = iso14_apdu(cmd, len, buf);
+ cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
+// UsbSendPacket((void *)ack, sizeof(UsbCommand));
}
if(param & ISO14A_RAW) {
len += 2;
}
ReaderTransmit(cmd,len);
- ack->arg[0] = ReaderReceive(ack->d.asBytes);
- UsbSendPacket((void *)ack, sizeof(UsbCommand));
+ arg0 = ReaderReceive(buf);
+// UsbSendPacket((void *)ack, sizeof(UsbCommand));
+ cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
}
- if(param & ISO14A_REQUEST_TRIGGER) iso14a_set_trigger(0);
+ if(param & ISO14A_REQUEST_TRIGGER) {
+ iso14a_set_trigger(0);
+ }
- if(param & ISO14A_NO_DISCONNECT)
+ if(param & ISO14A_NO_DISCONNECT) {
return;
+ }
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
uint8_t mf_auth[] = { 0x60,0x00,0xf5,0x7b };
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
- uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes
+ uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET); // was 3560 - tied to other size changes
traceLen = 0;
tracing = false;
LogTrace(par_list, 8, 0, GetParity(par_list, 8), TRUE);
LogTrace(ks_list, 8, 0, GetParity(ks_list, 8), TRUE);
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
- memcpy(ack.d.asBytes + 0, uid, 4);
- memcpy(ack.d.asBytes + 4, nt, 4);
- memcpy(ack.d.asBytes + 8, par_list, 8);
- memcpy(ack.d.asBytes + 16, ks_list, 8);
+ byte_t buf[48];
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
+ memcpy(buf + 0, uid, 4);
+ memcpy(buf + 4, nt, 4);
+ memcpy(buf + 8, par_list, 8);
+ memcpy(buf + 16, ks_list, 8);
LED_B_ON();
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
+ cmd_send(CMD_ACK,isOK,0,0,buf,48);
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
// Thats it...
Dbprintf("maxDataLen=%x, Uart.state=%x, Uart.byteCnt=%x Uart.byteCntMax=%x", maxDataLen, Uart.state, Uart.byteCnt, Uart.byteCntMax);
LEDsoff();
-}
+}
\ No newline at end of file
extern void iso14443a_setup();
extern int iso14_apdu(uint8_t * cmd, size_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 void iso14a_set_trigger(int enable);
+extern void iso14a_set_trigger(bool enable);
extern void iso14a_set_timeout(uint32_t timeout);
-extern void iso14a_clear_tracelen(void);
-extern void iso14a_set_tracing(int enable);
+extern void iso14a_clear_tracelen();
+extern void iso14a_set_tracing(bool enable);
#endif /* __ISO14443A_H */
#include "apps.h"
#include "string.h"
#include "iso15693tools.h"
-
+#include "cmd.h"
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
int recvlen=0;
uint8_t *recvbuf=(uint8_t *)BigBuf;
- UsbCommand n;
+// UsbCommand n;
if (DEBUG) {
Dbprintf("SEND");
recvlen=SendDataTag(data,datalen,1,speed,(recv?&recvbuf:NULL));
if (recv) {
- n.cmd=/* CMD_ISO_15693_COMMAND_DONE */ CMD_ACK;
- n.arg[0]=recvlen>48?48:recvlen;
- memcpy(n.d.asBytes, recvbuf, 48);
+// n.cmd=/* CMD_ISO_15693_COMMAND_DONE */ CMD_ACK;
+// n.arg[0]=recvlen>48?48:recvlen;
+// memcpy(n.d.asBytes, recvbuf, 48);
LED_B_ON();
- UsbSendPacket((uint8_t *)&n, sizeof(n));
+ cmd_send(CMD_ACK,recvlen>48?48:recvlen,0,0,recvbuf,48);
+// UsbSendPacket((uint8_t *)&n, sizeof(n));
LED_B_OFF();
if (DEBUG) {
{
uint8_t *dest = (uint8_t *)BigBuf;
int m=0, n=0, i=0, idx=0, found=0, lastval=0;
- uint32_t hi2=0, hi=0, lo=0;
+ uint32_t hi2=0, hi=0, lo=0;
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
{
found=1;
idx+=6;
- if (found && (hi2|hi|lo)) {
- if (hi2 != 0){
- Dbprintf("TAG ID: %x%08x%08x (%d)",
- (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
- }
- else {
- Dbprintf("TAG ID: %x%08x (%d)",
- (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
- }
+ if (found && (hi2|hi|lo)) {
+ if (hi2 != 0){
+ Dbprintf("TAG ID: %x%08x%08x (%d)",
+ (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ }
+ else {
+ Dbprintf("TAG ID: %x%08x (%d)",
+ (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ }
/* if we're only looking for one tag */
if (findone)
{
*low = lo;
return;
}
- hi2=0;
+ hi2=0;
hi=0;
lo=0;
found=0;
}
if (found) {
if (dest[idx] && (!dest[idx+1]) ) {
- hi2=(hi2<<1)|(hi>>31);
+ hi2=(hi2<<1)|(hi>>31);
hi=(hi<<1)|(lo>>31);
lo=(lo<<1)|0;
} else if ( (!dest[idx]) && dest[idx+1]) {
- hi2=(hi2<<1)|(hi>>31);
+ hi2=(hi2<<1)|(hi>>31);
hi=(hi<<1)|(lo>>31);
lo=(lo<<1)|1;
} else {
found=0;
- hi2=0;
+ hi2=0;
hi=0;
lo=0;
}
found=1;
idx+=6;
if (found && (hi|lo)) {
- if (hi2 != 0){
- Dbprintf("TAG ID: %x%08x%08x (%d)",
- (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
- }
- else {
- Dbprintf("TAG ID: %x%08x (%d)",
- (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
- }
+ if (hi2 != 0){
+ Dbprintf("TAG ID: %x%08x%08x (%d)",
+ (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ }
+ else {
+ Dbprintf("TAG ID: %x%08x (%d)",
+ (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ }
/* if we're only looking for one tag */
if (findone)
{
}
}
-
/*------------------------------
* T5555/T5557/T5567 routines
*------------------------------
// Opcode
T55xxWriteBit(1);
T55xxWriteBit(0); //Page 0
- if (PwdMode == 1){
- // Pwd
- for (i = 0x80000000; i != 0; i >>= 1)
- T55xxWriteBit(Pwd & i);
- }
+ if (PwdMode == 1){
+ // Pwd
+ for (i = 0x80000000; i != 0; i >>= 1)
+ T55xxWriteBit(Pwd & i);
+ }
// Lock bit
T55xxWriteBit(0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
-
-// Read one card block in page 0
+// Read one card block in page 0
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
uint8_t *dest = (uint8_t *)BigBuf;
int m=0, i=0;
-
+
m = sizeof(BigBuf);
// Clear destination buffer before sending the command
memset(dest, 128, m);
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
-
+
LED_D_ON();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
-
+
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
SpinDelay(150);
-
+
// Now start writting
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
-
+
// Opcode
T55xxWriteBit(1);
T55xxWriteBit(0); //Page 0
// Pwd
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBit(Pwd & i);
- }
+ }
// Lock bit
T55xxWriteBit(0);
// Block
// Turn field on to read the response
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
-
- // Now do the acquisition
+
+ // Now do the acquisition
i = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// we don't care about actual value, only if it's more or less than a
// threshold essentially we capture zero crossings for later analysis
-// if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
+ // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
i++;
if (i >= m) break;
}
}
-
+
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
DbpString("DONE!");
}
// Read card traceability data (page 1)
-void T55xxReadTrace(void){
+void T55xxReadTrace(void){
uint8_t *dest = (uint8_t *)BigBuf;
int m=0, i=0;
-
+
m = sizeof(BigBuf);
// Clear destination buffer before sending the command
memset(dest, 128, m);
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
// Now set up the SSC to get the ADC samples that are now streaming at us.
FpgaSetupSsc();
-
+
LED_D_ON();
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
-
+
// Give it a bit of time for the resonant antenna to settle.
// And for the tag to fully power up
SpinDelay(150);
-
+
// Now start writting
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
-
+
// Opcode
T55xxWriteBit(1);
T55xxWriteBit(1); //Page 1
// Turn field on to read the response
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
-
- // Now do the acquisition
+
+ // Now do the acquisition
i = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
if (i >= m) break;
}
}
-
+
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
DbpString("DONE!");
// Copy HID id to card and setup block 0 config
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
{
- int data1, data2, data3, data4, data5, data6; //up to six blocks for long format
+ int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format
int last_block = 0;
-
+
if (longFMT){
// Ensure no more than 84 bits supplied
if (hi2>0xFFFFF) {
else
data1 |= (1<<((3-i)*2)); // 0 -> 01
}
-
+
data2 = 0;
for (int i=0;i<16;i++) {
if (hi2 & (1<<(15-i)))
else
data2 |= (1<<((15-i)*2)); // 0 -> 01
}
-
+
data3 = 0;
for (int i=0;i<16;i++) {
if (hi & (1<<(31-i)))
else
data3 |= (1<<((15-i)*2)); // 0 -> 01
}
-
+
data4 = 0;
for (int i=0;i<16;i++) {
if (hi & (1<<(15-i)))
else
data5 |= (1<<((15-i)*2)); // 0 -> 01
}
-
+
data6 = 0;
for (int i=0;i<16;i++) {
if (lo & (1<<(15-i)))
data6 |= (1<<((15-i)*2)); // 0 -> 01
}
}
- else {
+ else {
// Ensure no more than 44 bits supplied
if (hi>0xFFF) {
DbpString("Tags can only have 44 bits.");
return;
}
-
+
// Build the 3 data blocks for supplied 44bit ID
last_block = 3;
data1 = 0x1D000000; // load preamble
-
- for (int i=0;i<12;i++) {
- if (hi & (1<<(11-i)))
- data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10
- else
- data1 |= (1<<((11-i)*2)); // 0 -> 01
- }
-
+
+ for (int i=0;i<12;i++) {
+ if (hi & (1<<(11-i)))
+ data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10
+ else
+ data1 |= (1<<((11-i)*2)); // 0 -> 01
+ }
+
data2 = 0;
for (int i=0;i<16;i++) {
if (lo & (1<<(31-i)))
else
data2 |= (1<<((15-i)*2)); // 0 -> 01
}
-
+
data3 = 0;
for (int i=0;i<16;i++) {
if (lo & (1<<(15-i)))
data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
else
data3 |= (1<<((15-i)*2)); // 0 -> 01
- }
+ }
}
-
+
LED_D_ON();
// Program the data blocks for supplied ID
// and the block 0 for HID format
T55xxWriteBlock(data5,5,0,0);
T55xxWriteBlock(data6,6,0,0);
}
-
+
// Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long)
T55xxWriteBlock(T55x7_BITRATE_RF_50 |
- T55x7_MODULATION_FSK2a |
- last_block << T55x7_MAXBLOCK_SHIFT,
- 0,0,0);
+ T55x7_MODULATION_FSK2a |
+ last_block << T55x7_MAXBLOCK_SHIFT,
+ 0,0,0);
LED_D_OFF();
T55xxWriteBlock(T55x7_BITRATE_RF_32 |
T55x7_MODULATION_PSK1 |
2 << T55x7_MAXBLOCK_SHIFT,
- 0,0,0);
+ 0, 0, 0);
//Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
// T5567WriteBlock(0x603E1042,0);
}
+
#define abs(x) ( ((x)<0) ? -(x) : (x) )
#define max(x,y) ( x<y ? y:x)
int DemodPCF7931(uint8_t **outBlocks) {
- uint8_t BitStream[256];
- uint8_t Blocks[8][16];
- uint8_t *GraphBuffer = (uint8_t *)BigBuf;
- int GraphTraceLen = sizeof(BigBuf);
- int i, j, lastval, bitidx, half_switch;
- int clock = 64;
- int tolerance = clock / 8;
- int pmc, block_done;
- int lc, warnings = 0;
- int num_blocks = 0;
- int lmin=128, lmax=128;
- uint8_t dir;
-
- AcquireRawAdcSamples125k(0);
-
- lmin = 64;
- lmax = 192;
-
- i = 2;
-
- /* Find first local max/min */
- if(GraphBuffer[1] > GraphBuffer[0]) {
+ uint8_t BitStream[256];
+ uint8_t Blocks[8][16];
+ uint8_t *GraphBuffer = (uint8_t *)BigBuf;
+ int GraphTraceLen = sizeof(BigBuf);
+ int i, j, lastval, bitidx, half_switch;
+ int clock = 64;
+ int tolerance = clock / 8;
+ int pmc, block_done;
+ int lc, warnings = 0;
+ int num_blocks = 0;
+ int lmin=128, lmax=128;
+ uint8_t dir;
+
+ AcquireRawAdcSamples125k(0);
+
+ lmin = 64;
+ lmax = 192;
+
+ i = 2;
+
+ /* Find first local max/min */
+ if(GraphBuffer[1] > GraphBuffer[0]) {
while(i < GraphTraceLen) {
if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax)
- break;
+ break;
i++;
}
dir = 0;
- }
- else {
+ }
+ else {
while(i < GraphTraceLen) {
if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin)
- break;
+ break;
i++;
}
dir = 1;
- }
-
- lastval = i++;
- half_switch = 0;
- pmc = 0;
- block_done = 0;
-
- for (bitidx = 0; i < GraphTraceLen; i++)
- {
- if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin))
- {
- lc = i - lastval;
- lastval = i;
-
- // Switch depending on lc length:
- // Tolerance is 1/8 of clock rate (arbitrary)
- if (abs(lc-clock/4) < tolerance) {
- // 16T0
- if((i - pmc) == lc) { /* 16T0 was previous one */
- /* It's a PMC ! */
- i += (128+127+16+32+33+16)-1;
- lastval = i;
- pmc = 0;
- block_done = 1;
- }
- else {
- pmc = i;
- }
- } else if (abs(lc-clock/2) < tolerance) {
- // 32TO
- if((i - pmc) == lc) { /* 16T0 was previous one */
- /* It's a PMC ! */
- i += (128+127+16+32+33)-1;
- lastval = i;
- pmc = 0;
- block_done = 1;
- }
- else if(half_switch == 1) {
- BitStream[bitidx++] = 0;
- half_switch = 0;
- }
- else
- half_switch++;
- } else if (abs(lc-clock) < tolerance) {
- // 64TO
- BitStream[bitidx++] = 1;
- } else {
- // Error
- warnings++;
- if (warnings > 10)
- {
- Dbprintf("Error: too many detection errors, aborting.");
- return 0;
- }
- }
-
- if(block_done == 1) {
- if(bitidx == 128) {
- for(j=0; j<16; j++) {
- Blocks[num_blocks][j] = 128*BitStream[j*8+7]+
- 64*BitStream[j*8+6]+
- 32*BitStream[j*8+5]+
- 16*BitStream[j*8+4]+
- 8*BitStream[j*8+3]+
- 4*BitStream[j*8+2]+
- 2*BitStream[j*8+1]+
- BitStream[j*8];
- }
- num_blocks++;
- }
- bitidx = 0;
- block_done = 0;
- half_switch = 0;
- }
- if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0;
- else dir = 1;
}
- if(bitidx==255)
- bitidx=0;
- warnings = 0;
- if(num_blocks == 4) break;
+
+ lastval = i++;
+ half_switch = 0;
+ pmc = 0;
+ block_done = 0;
+
+ for (bitidx = 0; i < GraphTraceLen; i++)
+ {
+ if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin))
+ {
+ lc = i - lastval;
+ lastval = i;
+
+ // Switch depending on lc length:
+ // Tolerance is 1/8 of clock rate (arbitrary)
+ if (abs(lc-clock/4) < tolerance) {
+ // 16T0
+ if((i - pmc) == lc) { /* 16T0 was previous one */
+ /* It's a PMC ! */
+ i += (128+127+16+32+33+16)-1;
+ lastval = i;
+ pmc = 0;
+ block_done = 1;
+ }
+ else {
+ pmc = i;
+ }
+ } else if (abs(lc-clock/2) < tolerance) {
+ // 32TO
+ if((i - pmc) == lc) { /* 16T0 was previous one */
+ /* It's a PMC ! */
+ i += (128+127+16+32+33)-1;
+ lastval = i;
+ pmc = 0;
+ block_done = 1;
+ }
+ else if(half_switch == 1) {
+ BitStream[bitidx++] = 0;
+ half_switch = 0;
+ }
+ else
+ half_switch++;
+ } else if (abs(lc-clock) < tolerance) {
+ // 64TO
+ BitStream[bitidx++] = 1;
+ } else {
+ // Error
+ warnings++;
+ if (warnings > 10)
+ {
+ Dbprintf("Error: too many detection errors, aborting.");
+ return 0;
+ }
+ }
+
+ if(block_done == 1) {
+ if(bitidx == 128) {
+ for(j=0; j<16; j++) {
+ Blocks[num_blocks][j] = 128*BitStream[j*8+7]+
+ 64*BitStream[j*8+6]+
+ 32*BitStream[j*8+5]+
+ 16*BitStream[j*8+4]+
+ 8*BitStream[j*8+3]+
+ 4*BitStream[j*8+2]+
+ 2*BitStream[j*8+1]+
+ BitStream[j*8];
+ }
+ num_blocks++;
+ }
+ bitidx = 0;
+ block_done = 0;
+ half_switch = 0;
+ }
+ if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0;
+ else dir = 1;
}
- memcpy(outBlocks, Blocks, 16*num_blocks);
- return num_blocks;
+ if(bitidx==255)
+ bitidx=0;
+ warnings = 0;
+ if(num_blocks == 4) break;
+ }
+ memcpy(outBlocks, Blocks, 16*num_blocks);
+ return num_blocks;
}
int IsBlock0PCF7931(uint8_t *Block) {
- // Assume RFU means 0 :)
- if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled
+ // Assume RFU means 0 :)
+ if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled
return 1;
- if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ?
+ if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ?
return 1;
- return 0;
+ return 0;
}
int IsBlock1PCF7931(uint8_t *Block) {
- // Assume RFU means 0 :)
- if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0)
+ // Assume RFU means 0 :)
+ if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0)
if((Block[14] & 0x7f) <= 9 && Block[15] <= 9)
return 1;
-
- return 0;
+
+ return 0;
}
#define ALLOC 16
void ReadPCF7931() {
- uint8_t Blocks[8][17];
- uint8_t tmpBlocks[4][16];
- int i, j, ind, ind2, n;
- int num_blocks = 0;
- int max_blocks = 8;
- int ident = 0;
- int error = 0;
- int tries = 0;
-
- memset(Blocks, 0, 8*17*sizeof(uint8_t));
-
- do {
+ uint8_t Blocks[8][17];
+ uint8_t tmpBlocks[4][16];
+ int i, j, ind, ind2, n;
+ int num_blocks = 0;
+ int max_blocks = 8;
+ int ident = 0;
+ int error = 0;
+ int tries = 0;
+
+ memset(Blocks, 0, 8*17*sizeof(uint8_t));
+
+ do {
memset(tmpBlocks, 0, 4*16*sizeof(uint8_t));
n = DemodPCF7931((uint8_t**)tmpBlocks);
if(!n)
for(i=0; i<n; i++)
Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
- tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
+ tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
+ tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
if(!ident) {
for(i=0; i<n; i++) {
- if(IsBlock0PCF7931(tmpBlocks[i])) {
- // Found block 0 ?
- if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
- // Found block 1!
- // \o/
- ident = 1;
- memcpy(Blocks[0], tmpBlocks[i], 16);
- Blocks[0][ALLOC] = 1;
- memcpy(Blocks[1], tmpBlocks[i+1], 16);
- Blocks[1][ALLOC] = 1;
- max_blocks = max((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
- // Debug print
- Dbprintf("(dbg) Max blocks: %d", max_blocks);
- num_blocks = 2;
- // Handle following blocks
- for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
- if(j==n) j=0;
- if(j==i) break;
- memcpy(Blocks[ind2], tmpBlocks[j], 16);
- Blocks[ind2][ALLOC] = 1;
- }
- break;
- }
- }
+ if(IsBlock0PCF7931(tmpBlocks[i])) {
+ // Found block 0 ?
+ if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
+ // Found block 1!
+ // \o/
+ ident = 1;
+ memcpy(Blocks[0], tmpBlocks[i], 16);
+ Blocks[0][ALLOC] = 1;
+ memcpy(Blocks[1], tmpBlocks[i+1], 16);
+ Blocks[1][ALLOC] = 1;
+ max_blocks = max((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
+ // Debug print
+ Dbprintf("(dbg) Max blocks: %d", max_blocks);
+ num_blocks = 2;
+ // Handle following blocks
+ for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
+ if(j==n) j=0;
+ if(j==i) break;
+ memcpy(Blocks[ind2], tmpBlocks[j], 16);
+ Blocks[ind2][ALLOC] = 1;
+ }
+ break;
+ }
+ }
}
}
else {
for(i=0; i<n; i++) { // Look for identical block in known blocks
- if(memcmp(tmpBlocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { // Block is not full of 00
- for(j=0; j<max_blocks; j++) {
- if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
- // Found an identical block
- for(ind=i-1,ind2=j-1; ind >= 0; ind--,ind2--) {
- if(ind2 < 0)
- ind2 = max_blocks;
- if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
- // Dbprintf("Tmp %d -> Block %d", ind, ind2);
- memcpy(Blocks[ind2], tmpBlocks[ind], 16);
- Blocks[ind2][ALLOC] = 1;
- num_blocks++;
- if(num_blocks == max_blocks) goto end;
- }
- }
- for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) {
- if(ind2 > max_blocks)
- ind2 = 0;
- if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
- // Dbprintf("Tmp %d -> Block %d", ind, ind2);
- memcpy(Blocks[ind2], tmpBlocks[ind], 16);
- Blocks[ind2][ALLOC] = 1;
- num_blocks++;
- if(num_blocks == max_blocks) goto end;
- }
- }
- }
- }
- }
+ if(memcmp(tmpBlocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { // Block is not full of 00
+ for(j=0; j<max_blocks; j++) {
+ if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
+ // Found an identical block
+ for(ind=i-1,ind2=j-1; ind >= 0; ind--,ind2--) {
+ if(ind2 < 0)
+ ind2 = max_blocks;
+ if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
+ // Dbprintf("Tmp %d -> Block %d", ind, ind2);
+ memcpy(Blocks[ind2], tmpBlocks[ind], 16);
+ Blocks[ind2][ALLOC] = 1;
+ num_blocks++;
+ if(num_blocks == max_blocks) goto end;
+ }
+ }
+ for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) {
+ if(ind2 > max_blocks)
+ ind2 = 0;
+ if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
+ // Dbprintf("Tmp %d -> Block %d", ind, ind2);
+ memcpy(Blocks[ind2], tmpBlocks[ind], 16);
+ Blocks[ind2][ALLOC] = 1;
+ num_blocks++;
+ if(num_blocks == max_blocks) goto end;
+ }
+ }
+ }
+ }
+ }
}
}
tries++;
if (BUTTON_PRESS()) return;
- } while (num_blocks != max_blocks);
- end:
- Dbprintf("-----------------------------------------");
- Dbprintf("Memory content:");
- Dbprintf("-----------------------------------------");
- for(i=0; i<max_blocks; i++) {
+ } while (num_blocks != max_blocks);
+end:
+ Dbprintf("-----------------------------------------");
+ Dbprintf("Memory content:");
+ Dbprintf("-----------------------------------------");
+ for(i=0; i<max_blocks; i++) {
if(Blocks[i][ALLOC]==1)
Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
- Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
+ Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
+ Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
else
Dbprintf("<missing block %d>", i);
- }
- Dbprintf("-----------------------------------------");
-
- return ;
+ }
+ Dbprintf("-----------------------------------------");
+
+ return ;
}
//-----------------------------------
-// EM4469 / EM4305 routines
+// EM4469 / EM4305 routines
//-----------------------------------
-#define FWD_CMD_LOGIN 0xC //including the even parity, binary mirrored
-#define FWD_CMD_WRITE 0xA
-#define FWD_CMD_READ 0x9
-#define FWD_CMD_DISABLE 0x5
-
-
-uint8_t forwardLink_data[64]; //array of forwarded bits
-uint8_t * forward_ptr; //ptr for forward message preparation
-uint8_t fwd_bit_sz; //forwardlink bit counter
-uint8_t * fwd_write_ptr; //forwardlink bit pointer
-
-//====================================================================
-// prepares command bits
-// see EM4469 spec
-//====================================================================
-//--------------------------------------------------------------------
-uint8_t Prepare_Cmd( uint8_t cmd ) {
-//--------------------------------------------------------------------
-
- *forward_ptr++ = 0; //start bit
- *forward_ptr++ = 0; //second pause for 4050 code
-
- *forward_ptr++ = cmd;
- cmd >>= 1;
- *forward_ptr++ = cmd;
- cmd >>= 1;
- *forward_ptr++ = cmd;
+#define FWD_CMD_LOGIN 0xC //including the even parity, binary mirrored
+#define FWD_CMD_WRITE 0xA
+#define FWD_CMD_READ 0x9
+#define FWD_CMD_DISABLE 0x5
+
+
+uint8_t forwardLink_data[64]; //array of forwarded bits
+uint8_t * forward_ptr; //ptr for forward message preparation
+uint8_t fwd_bit_sz; //forwardlink bit counter
+uint8_t * fwd_write_ptr; //forwardlink bit pointer
+
+//====================================================================
+// prepares command bits
+// see EM4469 spec
+//====================================================================
+//--------------------------------------------------------------------
+uint8_t Prepare_Cmd( uint8_t cmd ) {
+ //--------------------------------------------------------------------
+
+ *forward_ptr++ = 0; //start bit
+ *forward_ptr++ = 0; //second pause for 4050 code
+
+ *forward_ptr++ = cmd;
+ cmd >>= 1;
+ *forward_ptr++ = cmd;
cmd >>= 1;
- *forward_ptr++ = cmd;
-
- return 6; //return number of emited bits
-}
-
-//====================================================================
-// prepares address bits
-// see EM4469 spec
-//====================================================================
-
-//--------------------------------------------------------------------
-uint8_t Prepare_Addr( uint8_t addr ) {
-//--------------------------------------------------------------------
-
- register uint8_t line_parity;
-
+ *forward_ptr++ = cmd;
+ cmd >>= 1;
+ *forward_ptr++ = cmd;
+
+ return 6; //return number of emited bits
+}
+
+//====================================================================
+// prepares address bits
+// see EM4469 spec
+//====================================================================
+
+//--------------------------------------------------------------------
+uint8_t Prepare_Addr( uint8_t addr ) {
+ //--------------------------------------------------------------------
+
+ register uint8_t line_parity;
+
uint8_t i;
line_parity = 0;
for(i=0;i<6;i++) {
- *forward_ptr++ = addr;
- line_parity ^= addr;
+ *forward_ptr++ = addr;
+ line_parity ^= addr;
addr >>= 1;
}
- *forward_ptr++ = (line_parity & 1);
-
- return 7; //return number of emited bits
-}
-
-//====================================================================
-// prepares data bits intreleaved with parity bits
-// see EM4469 spec
-//====================================================================
-
-//--------------------------------------------------------------------
-uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) {
-//--------------------------------------------------------------------
-
- register uint8_t line_parity;
- register uint8_t column_parity;
- register uint8_t i, j;
- register uint16_t data;
-
- data = data_low;
- column_parity = 0;
-
- for(i=0; i<4; i++) {
- line_parity = 0;
- for(j=0; j<8; j++) {
- line_parity ^= data;
- column_parity ^= (data & 1) << j;
- *forward_ptr++ = data;
- data >>= 1;
- }
- *forward_ptr++ = line_parity;
- if(i == 1)
- data = data_hi;
- }
-
- for(j=0; j<8; j++) {
- *forward_ptr++ = column_parity;
- column_parity >>= 1;
- }
- *forward_ptr = 0;
-
- return 45; //return number of emited bits
-}
-
-//====================================================================
-// Forward Link send function
-// Requires: forwarLink_data filled with valid bits (1 bit per byte)
-// fwd_bit_count set with number of bits to be sent
-//====================================================================
-void SendForward(uint8_t fwd_bit_count) {
+ *forward_ptr++ = (line_parity & 1);
+
+ return 7; //return number of emited bits
+}
- fwd_write_ptr = forwardLink_data;
- fwd_bit_sz = fwd_bit_count;
+//====================================================================
+// prepares data bits intreleaved with parity bits
+// see EM4469 spec
+//====================================================================
- LED_D_ON();
+//--------------------------------------------------------------------
+uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) {
+ //--------------------------------------------------------------------
+
+ register uint8_t line_parity;
+ register uint8_t column_parity;
+ register uint8_t i, j;
+ register uint16_t data;
+
+ data = data_low;
+ column_parity = 0;
+
+ for(i=0; i<4; i++) {
+ line_parity = 0;
+ for(j=0; j<8; j++) {
+ line_parity ^= data;
+ column_parity ^= (data & 1) << j;
+ *forward_ptr++ = data;
+ data >>= 1;
+ }
+ *forward_ptr++ = line_parity;
+ if(i == 1)
+ data = data_hi;
+ }
+
+ for(j=0; j<8; j++) {
+ *forward_ptr++ = column_parity;
+ column_parity >>= 1;
+ }
+ *forward_ptr = 0;
+
+ return 45; //return number of emited bits
+}
+//====================================================================
+// Forward Link send function
+// Requires: forwarLink_data filled with valid bits (1 bit per byte)
+// fwd_bit_count set with number of bits to be sent
+//====================================================================
+void SendForward(uint8_t fwd_bit_count) {
+
+ fwd_write_ptr = forwardLink_data;
+ fwd_bit_sz = fwd_bit_count;
+
+ LED_D_ON();
+
//Field on
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
-
- // Give it a bit of time for the resonant antenna to settle.
- // And for the tag to fully power up
- SpinDelay(150);
-
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
+
+ // Give it a bit of time for the resonant antenna to settle.
+ // And for the tag to fully power up
+ SpinDelay(150);
+
// force 1st mod pulse (start gap must be longer for 4305)
- fwd_bit_sz--; //prepare next bit modulation
- fwd_write_ptr++;
+ fwd_bit_sz--; //prepare next bit modulation
+ fwd_write_ptr++;
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
SpinDelayUs(55*8); //55 cycles off (8us each)for 4305
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);//field on
SpinDelayUs(16*8); //16 cycles on (8us each)
-
- // now start writting
- while(fwd_bit_sz-- > 0) { //prepare next bit modulation
- if(((*fwd_write_ptr++) & 1) == 1)
+
+ // now start writting
+ while(fwd_bit_sz-- > 0) { //prepare next bit modulation
+ if(((*fwd_write_ptr++) & 1) == 1)
SpinDelayUs(32*8); //32 cycles at 125Khz (8us each)
else {
//These timings work for 4469/4269/4305 (with the 55*8 above)
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
SpinDelayUs(23*8); //16-4 cycles off (8us each)
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);//field on
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);//field on
SpinDelayUs(9*8); //16 cycles on (8us each)
}
- }
+ }
}
-void Login (uint32_t Password) {
-
+void EM4xLogin(uint32_t Password) {
+
uint8_t fwd_bit_count;
-
- forward_ptr = forwardLink_data;
- fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN );
- fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 );
-
- SendForward(fwd_bit_count);
- //Wait for command to complete
- SpinDelay(20);
-
-}
+ forward_ptr = forwardLink_data;
+ fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN );
+ fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 );
+
+ SendForward(fwd_bit_count);
+
+ //Wait for command to complete
+ SpinDelay(20);
+
+}
-void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
-
+void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
+
uint8_t fwd_bit_count;
- uint8_t *dest = (uint8_t *)BigBuf;
- int m=0, i=0;
-
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int m=0, i=0;
+
//If password mode do login
- if (PwdMode == 1) Login(Pwd);
-
- forward_ptr = forwardLink_data;
- fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
- fwd_bit_count += Prepare_Addr( Address );
-
- m = sizeof(BigBuf);
+ if (PwdMode == 1) EM4xLogin(Pwd);
+
+ forward_ptr = forwardLink_data;
+ fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
+ fwd_bit_count += Prepare_Addr( Address );
+
+ m = sizeof(BigBuf);
// Clear destination buffer before sending the command
- memset(dest, 128, m);
- // Connect the A/D to the peak-detected low-frequency path.
- SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
- // Now set up the SSC to get the ADC samples that are now streaming at us.
- FpgaSetupSsc();
-
- SendForward(fwd_bit_count);
+ memset(dest, 128, m);
+ // Connect the A/D to the peak-detected low-frequency path.
+ SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
+ // Now set up the SSC to get the ADC samples that are now streaming at us.
+ FpgaSetupSsc();
- // Now do the acquisition
- i = 0;
- for(;;) {
- if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
- AT91C_BASE_SSC->SSC_THR = 0x43;
- }
- if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
- dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- i++;
- if (i >= m) break;
- }
- }
+ SendForward(fwd_bit_count);
+
+ // Now do the acquisition
+ i = 0;
+ for(;;) {
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
+ AT91C_BASE_SSC->SSC_THR = 0x43;
+ }
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
+ dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+ i++;
+ if (i >= m) break;
+ }
+ }
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- LED_D_OFF();
+ LED_D_OFF();
}
-void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
-
+void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
+
uint8_t fwd_bit_count;
-
+
//If password mode do login
- if (PwdMode == 1) Login(Pwd);
-
- forward_ptr = forwardLink_data;
- fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE );
- fwd_bit_count += Prepare_Addr( Address );
- fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 );
-
- SendForward(fwd_bit_count);
+ if (PwdMode == 1) EM4xLogin(Pwd);
- //Wait for write to complete
- SpinDelay(20);
+ forward_ptr = forwardLink_data;
+ fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE );
+ fwd_bit_count += Prepare_Addr( Address );
+ fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 );
+
+ SendForward(fwd_bit_count);
+
+ //Wait for write to complete
+ SpinDelay(20);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- LED_D_OFF();
+ LED_D_OFF();
}
-
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- memcpy(ack.d.asBytes, dataoutbuf, 16);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// memcpy(ack.d.asBytes, dataoutbuf, 16);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,0,0);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
-\r
- SpinDelay(100);\r
+ cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,32);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+// SpinDelay(100);\r
\r
- memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- LED_B_OFF(); \r
+// memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);\r
+ LED_B_OFF();\r
\r
// Thats it...\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- LED_B_OFF(); \r
+ cmd_send(CMD_ACK,isOK,0,0,0,0);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ LED_B_OFF();\r
\r
\r
// Thats it...\r
nestedVector nvector[NES_MAX_INFO + 1][11];\r
int nvectorcount[NES_MAX_INFO + 1];\r
int ncount = 0;\r
- UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
struct Crypto1State mpcs = {0, 0};\r
struct Crypto1State *pcs;\r
pcs = &mpcs;\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
+// UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
+\r
for (i = 0; i < NES_MAX_INFO; i++) {\r
if (nvectorcount[i] > 10) continue;\r
\r
ncount = nvectorcount[i] - j;\r
if (ncount > 5) ncount = 5; \r
\r
- ack.arg[0] = 0; // isEOF = 0\r
- ack.arg[1] = ncount;\r
- ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
- memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
+// ack.arg[0] = 0; // isEOF = 0\r
+// ack.arg[1] = ncount;\r
+// ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
+// memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
\r
- memcpy(ack.d.asBytes, &cuid, 4);\r
+ byte_t buf[48];\r
+ memset(buf, 0x00, sizeof(buf));\r
+ memcpy(buf, &cuid, 4);\r
for (m = 0; m < ncount; m++) {\r
- memcpy(ack.d.asBytes + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
- memcpy(ack.d.asBytes + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
+ memcpy(buf + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
+ memcpy(buf + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
}\r
\r
LED_B_ON();\r
- SpinDelay(100);\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- LED_B_OFF(); \r
+// SpinDelay(100);\r
+ cmd_send(CMD_ACK,0,ncount,targetBlockNo + (targetKeyType * 0x100),buf,48);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ LED_B_OFF();\r
}\r
}\r
\r
// finalize list\r
- ack.arg[0] = 1; // isEOF = 1\r
- ack.arg[1] = 0;\r
- ack.arg[2] = 0;\r
- memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
+// ack.arg[0] = 1; // isEOF = 1\r
+// ack.arg[1] = 0;\r
+// ack.arg[2] = 0;\r
+// memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
\r
LED_B_ON();\r
- SpinDelay(300);\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- LED_B_OFF(); \r
+// SpinDelay(300);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,1,0,0,0,0);\r
+ LED_B_OFF();\r
\r
if (MF_DBGLEVEL >= 4) DbpString("NESTED FINISHED");\r
\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
// Thats it...\r
}\r
\r
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
- UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
+// UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
\r
- emlGetMem(ack.d.asBytes, arg0, arg1); // data, block num, blocks count\r
+ byte_t buf[48];\r
+ emlGetMem(buf, arg0, arg1); // data, block num, blocks count\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,arg0,arg1,0,buf,48);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
}\r
\r
break;\r
}\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- if (isOK) memcpy(ack.d.asBytes, uid, 4);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// if (isOK) memcpy(ack.d.asBytes, uid, 4);\r
\r
// add trace trailer\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
if ((workFlags & 0x10) || (!isOK)) {\r
break;\r
}\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- if (isOK) memcpy(ack.d.asBytes, data, 18);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// if (isOK) memcpy(ack.d.asBytes, data, 18);\r
\r
// add trace trailer\r
memset(data, 0x44, 4);\r
LogTrace(data, 4, 0, 0, TRUE);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,data,18);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
if ((workFlags & 0x10) || (!isOK)) {\r
}\r
\r
int MfSniffEnd(void){\r
- UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
+// UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,0,0,0,0,0);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
return 0;\r
FpgaDisableSscDma();\r
\r
while (pckLen > 0) {\r
- pckSize = min(32, pckLen);\r
- UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}};\r
- memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize);\r
+ pckSize = MIN(32, pckLen);\r
+// UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}};\r
+// memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- SpinDelay(20);\r
+ cmd_send(CMD_ACK,1,pckSize,pckNum,trace + traceLen - pckLen,pckSize);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+// SpinDelay(20);\r
LED_B_OFF();\r
\r
pckLen -= pckSize;\r
pckNum++;\r
}\r
\r
- UsbCommand ack = {CMD_ACK, {2, 0, 0}};\r
+// UsbCommand ack = {CMD_ACK, {2, 0, 0}};\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,2,0,0,0,0);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
traceLen = 0;\r
#include <stdint.h>
#define RAMFUNC __attribute((long_call, section(".ramfunc")))
-
#define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
-#define min(a, b) (((a) > (b)) ? (b) : (a))
#define LED_RED 1
#define LED_ORANGE 2
# DO NOT use thumb mode in the phase 1 bootloader since that generates a section with glue code
ARMSRC =
-THUMBSRC = usb.c bootrom.c
+THUMBSRC = cmd.c usb_cdc.c bootrom.c
ASMSRC = ram-reset.s flash-reset.s
## There is a strange bug with the linker: Sometimes it will not emit the glue to call
## BootROM from ARM mode. The symbol is emitted, but the section will be filled with
## zeroes. As a temporary workaround, do not use thumb for the phase 2 bootloader
## -- Henryk Plötz <henryk@ploetzli.ch> 2009-09-01
-ARMSRC := $(ARMSRC) $(THUMBSRC)
-THUMBSRC :=
+# ARMSRC := $(ARMSRC) $(THUMBSRC)
+# THUMBSRC :=
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
APP_CFLAGS = -I.
//-----------------------------------------------------------------------------
#include <proxmark3.h>
+#include "usb_cdc.h"
+#include "cmd.h"
+//#include "usb_hid.h"
+
+void DbpString(char *str) {
+ byte_t len = 0;
+ while (str[len] != 0x00) {
+ len++;
+ }
+ cmd_send(CMD_DEBUG_PRINT_STRING,len,0,0,(byte_t*)str,len);
+}
struct common_area common_area __attribute__((section(".commonarea")));
unsigned int start_addr, end_addr, bootrom_unlocked;
static void Fatal(void)
{
- for(;;);
+ for(;;);
}
-void UsbPacketReceived(uint8_t *packet, int len)
-{
- int i, dont_ack=0;
- UsbCommand *c = (UsbCommand *)packet;
- volatile uint32_t *p;
-
- if(len != sizeof(*c)) {
- Fatal();
- }
-
- switch(c->cmd) {
- case CMD_DEVICE_INFO:
- dont_ack = 1;
- c->cmd = CMD_DEVICE_INFO;
- c->arg[0] = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM |
- DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH;
- if(common_area.flags.osimage_present) c->arg[0] |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;
- UsbSendPacket(packet, len);
- break;
-
- case CMD_SETUP_WRITE:
- /* The temporary write buffer of the embedded flash controller is mapped to the
- * whole memory region, only the last 8 bits are decoded.
- */
- p = (volatile uint32_t *)&_flash_start;
- for(i = 0; i < 12; i++) {
- p[i+c->arg[0]] = c->d.asDwords[i];
- }
- break;
-
- case CMD_FINISH_WRITE:
- p = (volatile uint32_t *)&_flash_start;
- for(i = 0; i < 4; i++) {
- p[i+60] = c->d.asDwords[i];
- }
-
- /* Check that the address that we are supposed to write to is within our allowed region */
- if( ((c->arg[0]+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (c->arg[0] < start_addr) ) {
- /* Disallow write */
- dont_ack = 1;
- c->cmd = CMD_NACK;
- UsbSendPacket(packet, len);
- } else {
- /* Translate address to flash page and do flash, update here for the 512k part */
- AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY |
- MC_FLASH_COMMAND_PAGEN((c->arg[0]-(int)&_flash_start)/AT91C_IFLASH_PAGE_SIZE) |
- AT91C_MC_FCMD_START_PROG;
- }
-
- uint32_t sr;
-
- while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY))
- ;
- if(sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) {
- dont_ack = 1;
- c->cmd = CMD_NACK;
- UsbSendPacket(packet, len);
- }
- break;
-
- case CMD_HARDWARE_RESET:
- USB_D_PLUS_PULLUP_OFF();
- AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
- break;
-
- case CMD_START_FLASH:
- if(c->arg[2] == START_FLASH_MAGIC) bootrom_unlocked = 1;
- else bootrom_unlocked = 0;
- {
- int prot_start = (int)&_bootrom_start;
- int prot_end = (int)&_bootrom_end;
- int allow_start = (int)&_flash_start;
- int allow_end = (int)&_flash_end;
- int cmd_start = c->arg[0];
- int cmd_end = c->arg[1];
-
- /* Only allow command if the bootrom is unlocked, or the parameters are outside of the protected
- * bootrom area. In any case they must be within the flash area.
- */
- if( (bootrom_unlocked || ((cmd_start >= prot_end) || (cmd_end < prot_start)))
- && (cmd_start >= allow_start) && (cmd_end <= allow_end) ) {
- start_addr = cmd_start;
- end_addr = cmd_end;
- } else {
- start_addr = end_addr = 0;
- dont_ack = 1;
- c->cmd = CMD_NACK;
- UsbSendPacket(packet, len);
- }
- }
- break;
-
- default:
- Fatal();
- break;
- }
-
- if(!dont_ack) {
- c->cmd = CMD_ACK;
- UsbSendPacket(packet, len);
- }
+void UsbPacketReceived(uint8_t *packet, int len) {
+ int i, dont_ack=0;
+ UsbCommand* c = (UsbCommand *)packet;
+ volatile uint32_t *p;
+
+ if(len != sizeof(UsbCommand)) {
+ Fatal();
+ }
+
+ uint32_t arg0 = (uint32_t)c->arg[0];
+
+ switch(c->cmd) {
+ case CMD_DEVICE_INFO: {
+ dont_ack = 1;
+// c->cmd = CMD_DEVICE_INFO;
+ arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM |
+ DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH;
+ if(common_area.flags.osimage_present) {
+ arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;
+ }
+// UsbSendPacket(packet, len);
+ cmd_send(CMD_DEVICE_INFO,arg0,1,2,0,0);
+ } break;
+
+ case CMD_SETUP_WRITE: {
+ /* The temporary write buffer of the embedded flash controller is mapped to the
+ * whole memory region, only the last 8 bits are decoded.
+ */
+ p = (volatile uint32_t *)&_flash_start;
+ for(i = 0; i < 12; i++) {
+ p[i+arg0] = c->d.asDwords[i];
+ }
+ } break;
+
+ case CMD_FINISH_WRITE: {
+ uint32_t* flash_mem = (uint32_t*)(&_flash_start);
+// p = (volatile uint32_t *)&_flash_start;
+ for (size_t j=0; j<2; j++) {
+ for(i = 0+(64*j); i < 64+(64*j); i++) {
+ //p[i+60] = c->d.asDwords[i];
+ flash_mem[i] = c->d.asDwords[i];
+ }
+
+ uint32_t flash_address = arg0 + (0x100*j);
+
+ /* Check that the address that we are supposed to write to is within our allowed region */
+ if( ((flash_address+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (flash_address < start_addr) ) {
+ /* Disallow write */
+ dont_ack = 1;
+ // c->cmd = CMD_NACK;
+ // UsbSendPacket(packet, len);
+ cmd_send(CMD_NACK,0,0,0,0,0);
+ } else {
+ uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE;
+ /* Translate address to flash page and do flash, update here for the 512k part */
+ AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY |
+ MC_FLASH_COMMAND_PAGEN(page_n) |
+ AT91C_MC_FCMD_START_PROG;
+ // arg0 = (address - ((uint32_t)flash_s));
+ }
+
+ // Wait until flashing of page finishes
+ uint32_t sr;
+ while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY));
+ if(sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) {
+ dont_ack = 1;
+ // c->cmd = CMD_NACK;
+ cmd_send(CMD_NACK,0,0,0,0,0);
+ // UsbSendPacket(packet, len);
+ }
+ }
+ } break;
+
+ case CMD_HARDWARE_RESET: {
+// USB_D_PLUS_PULLUP_OFF();
+ usb_disable();
+ AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
+ } break;
+
+ case CMD_START_FLASH: {
+ if(c->arg[2] == START_FLASH_MAGIC) bootrom_unlocked = 1;
+ else bootrom_unlocked = 0;
+ {
+ int prot_start = (int)&_bootrom_start;
+ int prot_end = (int)&_bootrom_end;
+ int allow_start = (int)&_flash_start;
+ int allow_end = (int)&_flash_end;
+ int cmd_start = c->arg[0];
+ int cmd_end = c->arg[1];
+
+ /* Only allow command if the bootrom is unlocked, or the parameters are outside of the protected
+ * bootrom area. In any case they must be within the flash area.
+ */
+ if( (bootrom_unlocked || ((cmd_start >= prot_end) || (cmd_end < prot_start)))
+ && (cmd_start >= allow_start) && (cmd_end <= allow_end) ) {
+ start_addr = cmd_start;
+ end_addr = cmd_end;
+ } else {
+ start_addr = end_addr = 0;
+ dont_ack = 1;
+// c->cmd = CMD_NACK;
+// UsbSendPacket(packet, len);
+ cmd_send(CMD_NACK,0,0,0,0,0);
+ }
+ }
+ } break;
+
+ default: {
+ Fatal();
+ } break;
+ }
+
+ if(!dont_ack) {
+// c->cmd = CMD_ACK;
+// UsbSendPacket(packet, len);
+ cmd_send(CMD_ACK,arg0,0,0,0,0);
+ }
}
static void flash_mode(int externally_entered)
start_addr = 0;
end_addr = 0;
bootrom_unlocked = 0;
+ byte_t rx[sizeof(UsbCommand)];
+ size_t rx_len;
+
+ usb_enable();
+ for (volatile size_t i=0; i<0x100000; i++);
- UsbStart();
+// UsbStart();
for(;;) {
WDT_HIT();
- UsbPoll(TRUE);
+ if (usb_poll()) {
+ rx_len = usb_read(rx,sizeof(UsbCommand));
+ if (rx_len) {
+// DbpString("starting to flash");
+ UsbPacketReceived(rx,rx_len);
+ }
+ }
+
+// UsbPoll(TRUE);
if(!externally_entered && !BUTTON_PRESS()) {
/* Perform a reset to leave flash mode */
- USB_D_PLUS_PULLUP_OFF();
+// USB_D_PLUS_PULLUP_OFF();
+ usb_disable();
LED_B_ON();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
for(;;);
}
}
-extern char _osimage_entry;
+extern uint32_t _osimage_entry;
void BootROM(void)
{
//------------
GPIO_LED_C |
GPIO_LED_D;
- USB_D_PLUS_PULLUP_OFF();
+// USB_D_PLUS_PULLUP_OFF();
+ usb_disable();
LED_D_OFF();
LED_C_ON();
LED_B_OFF();
flash_mode(1);
} else if(BUTTON_PRESS()) {
flash_mode(0);
- } else if(*(uint32_t*)&_osimage_entry == 0xffffffffU) {
+ } else if(_osimage_entry == 0xffffffffU) {
flash_mode(1);
} else {
// jump to Flash address of the osimage entry point (LSBit set for thumb mode)
- asm("bx %0\n" : : "r" ( ((int)&_osimage_entry) | 0x1 ) );
+ __asm("bx %0\n" : : "r" ( ((int)&_osimage_entry) | 0x1 ) );
}
}
+++ /dev/null
-//-----------------------------------------------------------------------------
-// Copyright (C) 2010 Hector Martin "marcan" <marcan@marcansoft.com>
-//
-// 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.
-//-----------------------------------------------------------------------------
-// Replacement stdint.h because GCC doesn't come with it yet (C99)
-//-----------------------------------------------------------------------------
-
-#ifndef __STDINT_H
-#define __STDINT_H
-
-typedef signed char int8_t;
-typedef short int int16_t;
-typedef int int32_t;
-typedef long long int int64_t;
-
-typedef unsigned char uint8_t;
-typedef unsigned short int uint16_t;
-typedef unsigned int uint32_t;
-typedef unsigned long long int uint64_t;
-
-typedef int intptr_t;
-typedef unsigned int uintptr_t;
-
-#endif /* __STDINT_H */
LDLIBS = -L/opt/local/lib -L/usr/local/lib -lusb -lreadline -lpthread
LDFLAGS = $(COMMON_FLAGS)
-CFLAGS = -std=gnu99 -I. -I../include -I../common -I/opt/local/include -Wall -Wno-unused-function $(COMMON_FLAGS) -g -O3
+CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -Wall -Wno-unused-function $(COMMON_FLAGS) -g -O4
ifneq (,$(findstring MINGW,$(platform)))
CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
QTLDLIBS = -framework QtGui -framework QtCore
MOC = moc
else
-CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall -O3
+CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall -O4
QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
MOC = $(shell pkg-config --variable=moc_location QtCore)
endif
data.c \
graph.c \
ui.c \
+ uart.c \
util.c \
cmddata.c \
cmdhf.c \
cmdhfmf.c \
cmdhw.c \
cmdlf.c \
- cmdlfem4x.c \
cmdlfhid.c \
+ cmdlfem4x.c \
cmdlfhitag.c \
cmdlfti.c \
cmdparser.c \
CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o)
RM = rm -f
-BINS = proxmark3 snooper cli flasher
+BINS = proxmark3 flasher #snooper cli
CLEAN = cli cli.exe flasher flasher.exe proxmark3 proxmark3.exe snooper snooper.exe $(CMDOBJS) $(OBJDIR)/*.o *.o *.moc.cpp
all: $(BINS)
all-static: snooper cli flasher
proxmark3: LDLIBS+=$(QTLDLIBS)
-proxmark3: $(OBJDIR)/proxmark3.o $(CMDOBJS) $(OBJDIR)/proxusb.o $(QTGUI)
+proxmark3: $(OBJDIR)/proxmark3.o $(CMDOBJS) $(OBJDIR)/uart.o $(QTGUI)
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
-snooper: $(OBJDIR)/snooper.o $(CMDOBJS) $(OBJDIR)/proxusb.o $(OBJDIR)/guidummy.o
+snooper: $(OBJDIR)/snooper.o $(CMDOBJS) $(OBJDIR)/uart.o $(OBJDIR)/guidummy.o
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
-cli: $(OBJDIR)/cli.o $(CMDOBJS) $(OBJDIR)/proxusb.o $(OBJDIR)/guidummy.o
+cli: $(OBJDIR)/cli.o $(CMDOBJS) $(OBJDIR)/uart.o $(OBJDIR)/guidummy.o
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
-flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(OBJDIR)/proxusb.o
+flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(OBJDIR)/uart.o
$(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@
$(OBJDIR)/%.o: %.c
#include <stdlib.h>
#include <string.h>
#include <limits.h>
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "data.h"
#include "ui.h"
#include "graph.h"
for (int i = 0; i < n; i += 12) {
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+ WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
for (int j = 0; j < 48; j++) {
for (int k = 0; k < 8; k++) {
for (int i = offset; i < n+offset; i += 12) {
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+ WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
for (int j = 0; j < 48; j += 8) {
PrintAndLog("%02x %02x %02x %02x %02x %02x %02x %02x",
sample_buf[j+0],
for (int i = 0; i < n; i += 12) {
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+ WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
for (int j = 0; j < 48; j++) {
GraphBuffer[cnt++] = ((int)sample_buf[j]) - 128;
}
//-----------------------------------------------------------------------------
#include <stdio.h>
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "graph.h"
#include "ui.h"
#include "cmdparser.h"
#include "util.h"
#include "iso14443crc.h"
#include "data.h"
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdhf14a.h"
#include "common.h"
#include "cmdmain.h"
-#include "sleep.h"
+#include "mifare.h"
static int CmdHelp(const char *Cmd);
{
uint8_t got[1920];
GetFromBigBuf(got,sizeof(got),0);
+ WaitForResponse(CMD_ACK,NULL);
PrintAndLog("recorded activity:");
PrintAndLog(" ETU :rssi: who bytes");
int CmdHF14AReader(const char *Cmd)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
- char param[256]={0};
-
- if( 3 == param_getstr(Cmd,0,param) && !strcmp("con",param))
- {
- c.arg[0]|=ISO14A_NO_DISCONNECT;
- PrintAndLog("KEEP connected!\n");
- }
-
- if( 3 == param_getstr(Cmd,0,param) && !strcmp("dis",param))
- {
- c.arg[0] = 0;
- PrintAndLog("disconnected!\n");
- SendCommand(&c);
- return 0;
- }
-
SendCommand(&c);
- UsbCommand * resp = WaitForResponse(CMD_ACK);
- uint8_t * uid = resp->d.asBytes;
- iso14a_card_select_t * card = (iso14a_card_select_t *)(uid + 12);
- if(resp->arg[0] == 0) {
+ UsbCommand resp;
+ WaitForResponse(CMD_ACK,&resp);
+
+ iso14a_card_select_t *card = (iso14a_card_select_t *)resp.d.asBytes;
+
+ if(resp.arg[0] == 0) {
PrintAndLog("iso14443a card select failed");
return 0;
}
PrintAndLog("ATQA : %02x %02x", card->atqa[0], card->atqa[1]);
- PrintAndLog(" UID : %s", sprint_hex(uid, 12));
- PrintAndLog(" SAK : %02x [%d]", card->sak, resp->arg[0]);
+ PrintAndLog(" UID : %s", sprint_hex(card->uid, card->uidlen));
+ PrintAndLog(" SAK : %02x [%d]", card->sak, resp.arg[0]);
switch (card->sak) {
- case 0x00: PrintAndLog(" SAK : NXP MIFARE Ultralight | Ultralight C"); break;
- case 0x04: PrintAndLog(" SAK : NXP MIFARE (various !DESFire !DESFire EV1)"); break;
-
- case 0x08: PrintAndLog(" SAK : NXP MIFARE CLASSIC 1k | Plus 2k"); break;
- case 0x09: PrintAndLog(" SAK : NXP MIFARE Mini 0.3k"); break;
- case 0x10: PrintAndLog(" SAK : NXP MIFARE Plus 2k"); break;
- case 0x11: PrintAndLog(" SAK : NXP MIFARE Plus 4k"); break;
- case 0x18: PrintAndLog(" SAK : NXP MIFARE Classic 4k | Plus 4k"); break;
- case 0x20: PrintAndLog(" SAK : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k | JCOP 31/41"); break;
- case 0x24: PrintAndLog(" SAK : NXP MIFARE DESFire | DESFire EV1"); break;
- case 0x28: PrintAndLog(" SAK : JCOP31 or JCOP41 v2.3.1"); break;
- case 0x38: PrintAndLog(" SAK : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); break;
- case 0x88: PrintAndLog(" SAK : Infineon MIFARE CLASSIC 1K"); break;
- case 0x98: PrintAndLog(" SAK : Gemplus MPCOS"); break;
+ case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break;
+ case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break;
+
+ case 0x08: PrintAndLog("TYPE : NXP MIFARE CLASSIC 1k | Plus 2k"); break;
+ case 0x09: PrintAndLog("TYPE : NXP MIFARE Mini 0.3k"); break;
+ case 0x10: PrintAndLog("TYPE : NXP MIFARE Plus 2k"); break;
+ case 0x11: PrintAndLog("TYPE : NXP MIFARE Plus 4k"); break;
+ case 0x18: PrintAndLog("TYPE : NXP MIFARE Classic 4k | Plus 4k"); break;
+ case 0x20: PrintAndLog("TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k | JCOP 31/41"); break;
+ case 0x24: PrintAndLog("TYPE : NXP MIFARE DESFire | DESFire EV1"); break;
+ case 0x28: PrintAndLog("TYPE : JCOP31 or JCOP41 v2.3.1"); break;
+ case 0x38: PrintAndLog("TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); break;
+ case 0x88: PrintAndLog("TYPE : Infineon MIFARE CLASSIC 1K"); break;
+ case 0x98: PrintAndLog("TYPE : Gemplus MPCOS"); break;
default: ;
}
- if(resp->arg[0] == 1) {
+ if(resp.arg[0] == 1) {
bool ta1 = 0, tb1 = 0, tc1 = 0;
int pos;
}
}
}
- }
- else
- PrintAndLog("proprietary non-iso14443a card found, RATS not supported");
+ } else {
+ PrintAndLog("proprietary non iso14443a-4 card found, RATS not supported");
+ }
- return resp->arg[0];
+ return resp.arg[0];
}
// Collect ISO14443 Type A UIDs
// execute anticollision procedure
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
SendCommand(&c);
- UsbCommand *resp = WaitForResponse(CMD_ACK);
- uint8_t *uid = resp->d.asBytes;
+
+ UsbCommand resp;
+ WaitForResponse(CMD_ACK,&resp);
+
+ uint8_t *uid = resp.d.asBytes;
iso14a_card_select_t *card = (iso14a_card_select_t *)(uid + 12);
// check if command failed
- if (resp->arg[0] == 0) {
+ if (resp.arg[0] == 0) {
PrintAndLog("Card select failed.");
} else {
// check if UID is 4 bytes
// Are we handling the (optional) second part uid?
if (long_uid > 0xffffffff) {
- PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014llx)",long_uid);
+ PrintAndLog("Emulating ISO/IEC 14443 type A tag with 7 byte UID (%014"llx")",long_uid);
// Store the second part
c.arg[2] = (long_uid & 0xffffffff);
long_uid >>= 32;
return 0;
}
-int CmdHF14AFuzz(const char *Cmd) {
- char formatstr[256] = {0},sendbuf[256] = {0};
- uint32_t start=0,end=0;
-
- if (param_getchar(Cmd, 0) == 0) {
- PrintAndLog("fuzz raw hex data to the card and show response <ONLY for develepers>");
- PrintAndLog("Usage: hf 14a fuzz <FORMAT> [<start index> <end index>]");
- PrintAndLog("FORMAT controls the output as in C printf");
- PrintAndLog("sample: hf 14a fuzz 909F");
- PrintAndLog(" hf 14a fuzz 00%02x00000000 0 0xFF");
- return 0;
- }
-
- start = param_get8ex(Cmd, 1, 0,16);
- end = param_get8ex(Cmd, 2, 0,16);
- param_getstr(Cmd, 0, formatstr);
-
- for( int i=start;i<=end;++i)
- {
- snprintf(sendbuf, sizeof(sendbuf), formatstr, i);
-
- int len = strlen(sendbuf)/2;
-
- UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_APDU|ISO14A_NO_DISCONNECT, len, 0}};
- param_gethex(sendbuf, 0, c.d.asBytes, len*2);
- PrintAndLog("len:%d raw:",len);
- PrintAndLog("%s",sprint_hex(c.d.asBytes, len));
- SendCommand(&c);
-
- UsbCommand * resp = WaitForResponse(CMD_ACK);
- PrintAndLog("res:%d",resp->arg[0]);
-
- while(resp->arg[0] > sizeof(resp->d))
- {
- PrintAndLog("%s", sprint_hex(resp->d.asBytes,sizeof(resp->d)));
-
- resp = WaitForResponse(CMD_ACK);
- }
- PrintAndLog("%s", sprint_hex(resp->d.asBytes,resp->arg[0]));
-
- PrintAndLog("");
-
- msleep(100);
- }
-
- return 0;
-}
-
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"cuids", CmdHF14ACUIDs, 0, "<n> Collect n>0 ISO14443 Type A UIDs in one go"},
{"sim", CmdHF14ASim, 0, "<UID> -- Fake ISO 14443a tag"},
{"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
- {"fuzz", CmdHF14AFuzz, 0, "Fuzz"},
{NULL, NULL, 0, NULL}
};
-int CmdHF14A(const char *Cmd)
-{
+int CmdHF14A(const char *Cmd) {
// flush
- while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
+ WaitForResponseTimeout(CMD_ACK,NULL,100);
// parse
CmdsParse(CommandTable, Cmd);
#include <string.h>
#include <stdint.h>
#include "iso14443crc.h"
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "data.h"
#include "graph.h"
#include "ui.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "data.h"
#include "graph.h"
#include "ui.h"
// returns 1 if suceeded
int getUID(uint8_t *buf)
{
- UsbCommand *r;
+ UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
uint8_t *req=c.d.asBytes;
SendCommand(&c);
- r=WaitForResponseTimeout(CMD_ACK,1000);
-
- if (r!=NULL) {
- recv = r->d.asBytes;
- if (r->arg[0]>=12 && ISO15_CRC_CHECK==Crc(recv,12)) {
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ recv = resp.d.asBytes;
+ if (resp.arg[0]>=12 && ISO15_CRC_CHECK==Crc(recv,12)) {
memcpy(buf,&recv[2],8);
return 1;
}
// Reads all memory pages
int CmdHF15DumpMem(const char*Cmd) {
- UsbCommand *r;
+ UsbCommand resp;
uint8_t uid[8];
uint8_t *recv=NULL;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
SendCommand(&c);
- r=WaitForResponseTimeout(CMD_ACK,1000);
-
- if (r!=NULL) {
- recv = r->d.asBytes;
- if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ recv = resp.d.asBytes;
+ if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
if (!(recv[0] & ISO15_RES_ERROR)) {
retry=0;
*output=0; // reset outputstring
sprintf(output, "Block %2i ",blocknum);
- for ( int i=1; i<r->arg[0]-2; i++) { // data in hex
+ for ( int i=1; i<resp.arg[0]-2; i++) { // data in hex
sprintf(output+strlen(output),"%02hX ",recv[i]);
}
strcat(output," ");
- for ( int i=1; i<r->arg[0]-2; i++) { // data in cleaned ascii
+ for ( int i=1; i<resp.arg[0]-2; i++) { // data in cleaned ascii
sprintf(output+strlen(output),"%c",(recv[i]>31 && recv[i]<127)?recv[i]:'.');
}
PrintAndLog("%s",output);
}
} // else PrintAndLog("crc");
} // else PrintAndLog("r null");
-
} // retry
- if (r && r->arg[0]<3)
- PrintAndLog("Lost Connection");
- else if (r && ISO15_CRC_CHECK!=Crc(r->d.asBytes,r->arg[0]))
- PrintAndLog("CRC Failed");
- else
- PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
+ // TODO: need fix
+// if (resp.arg[0]<3)
+// PrintAndLog("Lost Connection");
+// else if (ISO15_CRC_CHECK!=Crc(resp.d.asBytes,resp.arg[0]))
+// PrintAndLog("CRC Failed");
+// else
+// PrintAndLog("Tag returned Error %i: %s",recv[1],TagErrorStr(recv[1]));
return 0;
}
int CmdHF15CmdInquiry(const char *Cmd)
{
- UsbCommand *r;
+ UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
uint8_t *req=c.d.asBytes;
SendCommand(&c);
- r=WaitForResponseTimeout(CMD_ACK,1000);
-
- if (r!=NULL) {
- if (r->arg[0]>=12) {
- recv = r->d.asBytes;
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ if (resp.arg[0]>=12) {
+ recv = resp.d.asBytes;
PrintAndLog("UID=%s",sprintUID(NULL,&recv[2]));
PrintAndLog("Tag Info: %s",getTagInfo(&recv[2]));
} else {
- PrintAndLog("Response to short, just %i bytes. No tag?\n",r->arg[0]);
+ PrintAndLog("Response to short, just %i bytes. No tag?\n",resp.arg[0]);
}
} else {
PrintAndLog("timeout.");
int CmdHF15CmdRaw (const char *cmd) {
- UsbCommand *r;
+ UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
int reply=1;
SendCommand(&c);
if (reply) {
- r=WaitForResponseTimeout(CMD_ACK,1000);
-
- if (r!=NULL) {
- recv = r->d.asBytes;
- PrintAndLog("received %i octets",r->arg[0]);
- hexout = (char *)malloc(r->arg[0] * 3 + 1);
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ recv = resp.d.asBytes;
+ PrintAndLog("received %i octets",resp.arg[0]);
+ hexout = (char *)malloc(resp.arg[0] * 3 + 1);
if (hexout != NULL) {
- for (int i = 0; i < r->arg[0]; i++) { // data in hex
+ for (int i = 0; i < resp.arg[0]; i++) { // data in hex
sprintf(&hexout[i * 3], "%02hX ", recv[i]);
}
PrintAndLog("%s", hexout);
* get system information from tag/VICC
*/
int CmdHF15CmdSysinfo(const char *Cmd) {
- UsbCommand *r;
+ UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
uint8_t *req=c.d.asBytes;
SendCommand(&c);
- r=WaitForResponseTimeout(CMD_ACK,1000);
-
- if (r!=NULL && r->arg[0]>2) {
- recv = r->d.asBytes;
- if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && resp.arg[0]>2) {
+ recv = resp.d.asBytes;
+ if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
if (!(recv[0] & ISO15_RES_ERROR)) {
*output=0; // reset outputstring
- for ( i=1; i<r->arg[0]-2; i++) {
+ for ( i=1; i<resp.arg[0]-2; i++) {
sprintf(output+strlen(output),"%02hX ",recv[i]);
}
strcat(output,"\n\r");
* Read multiple blocks at once (not all tags support this)
*/
int CmdHF15CmdReadmulti(const char *Cmd) {
- UsbCommand *r;
+ UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
uint8_t *req=c.d.asBytes;
SendCommand(&c);
- r=WaitForResponseTimeout(CMD_ACK,1000);
-
- if (r!=NULL && r->arg[0]>2) {
- recv = r->d.asBytes;
- if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && resp.arg[0]>2) {
+ recv = resp.d.asBytes;
+ if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
if (!(recv[0] & ISO15_RES_ERROR)) {
*output=0; // reset outputstring
- for ( int i=1; i<r->arg[0]-2; i++) {
+ for ( int i=1; i<resp.arg[0]-2; i++) {
sprintf(output+strlen(output),"%02hX ",recv[i]);
}
strcat(output," ");
- for ( int i=1; i<r->arg[0]-2; i++) {
+ for ( int i=1; i<resp.arg[0]-2; i++) {
sprintf(output+strlen(output),"%c",recv[i]>31 && recv[i]<127?recv[i]:'.');
}
PrintAndLog("%s",output);
* Reads a single Block
*/
int CmdHF15CmdRead(const char *Cmd) {
- UsbCommand *r;
+ UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
uint8_t *req=c.d.asBytes;
SendCommand(&c);
- r=WaitForResponseTimeout(CMD_ACK,1000);
-
- if (r!=NULL && r->arg[0]>2) {
- recv = r->d.asBytes;
- if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1000) && resp.arg[0]>2) {
+ recv = resp.d.asBytes;
+ if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
if (!(recv[0] & ISO15_RES_ERROR)) {
*output=0; // reset outputstring
//sprintf(output, "Block %2i ",blocknum);
- for ( int i=1; i<r->arg[0]-2; i++) {
+ for ( int i=1; i<resp.arg[0]-2; i++) {
sprintf(output+strlen(output),"%02hX ",recv[i]);
}
strcat(output," ");
- for ( int i=1; i<r->arg[0]-2; i++) {
+ for ( int i=1; i<resp.arg[0]-2; i++) {
sprintf(output+strlen(output),"%c",recv[i]>31 && recv[i]<127?recv[i]:'.');
}
PrintAndLog("%s",output);
* Writes a single Block - might run into timeout, even when successful
*/
int CmdHF15CmdWrite(const char *Cmd) {
- UsbCommand *r;
+ UsbCommand resp;
uint8_t *recv;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
uint8_t *req=c.d.asBytes;
SendCommand(&c);
- r=WaitForResponseTimeout(CMD_ACK,2000);
-
- if (r!=NULL && r->arg[0]>2) {
- recv = r->d.asBytes;
- if (ISO15_CRC_CHECK==Crc(recv,r->arg[0])) {
+ if (WaitForResponseTimeout(CMD_ACK,&resp,2000) && resp.arg[0]>2) {
+ recv = resp.d.asBytes;
+ if (ISO15_CRC_CHECK==Crc(recv,resp.arg[0])) {
if (!(recv[0] & ISO15_RES_ERROR)) {
PrintAndLog("OK");
} else {
//-----------------------------------------------------------------------------
#include "util.h"
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "ui.h"
#include "cmdparser.h"
#include "common.h"
int CmdHFEPACollectPACENonces(const char *Cmd)
{
// requested nonce size
- uint8_t m = 0;
+ unsigned int m = 0;
// requested number of Nonces
unsigned int n = 0;
// delay between requests
unsigned int d = 0;
- sscanf(Cmd, "%hhu %u %u", &m, &n, &d);
+ sscanf(Cmd, "%u %u %u", &m, &n, &d);
// values are expected to be > 0
m = m > 0 ? m : 1;
n = n > 0 ? n : 1;
- PrintAndLog("Collecting %u %hhu-byte nonces", n, m);
+ PrintAndLog("Collecting %u %"hhu"-byte nonces", n, m);
PrintAndLog("Start: %u", time(NULL));
// repeat n times
for (unsigned int i = 0; i < n; i++) {
// execute PACE
UsbCommand c = {CMD_EPA_PACE_COLLECT_NONCE, {(int)m, 0, 0}};
SendCommand(&c);
- UsbCommand *resp = WaitForResponse(CMD_ACK);
+ UsbCommand resp;
+
+ WaitForResponse(CMD_ACK,&resp);
// check if command failed
- if (resp->arg[0] != 0) {
- PrintAndLog("Error in step %d, Return code: %d",
- resp->arg[0],
- (int)resp->arg[1]);
+ if (resp.arg[0] != 0) {
+ PrintAndLog("Error in step %d, Return code: %d",resp.arg[0],(int)resp.arg[1]);
} else {
- size_t nonce_length = resp->arg[1];
+ size_t nonce_length = resp.arg[1];
char *nonce = (char *) malloc(2 * nonce_length + 1);
for(int j = 0; j < nonce_length; j++) {
- snprintf(nonce + (2 * j), 3, "%02X", resp->d.asBytes[j]);
+ snprintf(nonce + (2 * j), 3, "%02X", resp.d.asBytes[j]);
}
// print nonce
- PrintAndLog("Length: %d, Nonce: %s",
- resp->arg[1], nonce);
+ PrintAndLog("Length: %d, Nonce: %s",resp.arg[1], nonce);
}
if (i < n - 1) {
sleep(d);
int CmdHFEPA(const char *Cmd)
{
// flush
- while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
+ WaitForResponseTimeout(CMD_ACK,NULL,100);
// parse
CmdsParse(CommandTable, Cmd);
return 0;
-}
+}
\ No newline at end of file
#include <string.h>
#include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type
#include "data.h"
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdhficlass.h"
#include <stdio.h>
#include <string.h>
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "data.h"
#include "ui.h"
#include "cmdparser.h"
for (i = 0; i < 256; i += 12, h += 48) {
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+ WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
for (j = 0; j < 48; j += 8) {
for (k = 0; k < 8; k++) {
c.d.asBytes[j] = data[j];
}
SendCommand(&c);
- WaitForResponse(CMD_ACK);
+ WaitForResponse(CMD_ACK, NULL);
offset += 8;
}
fclose(f);
for (int i = offset; i < n+offset; i += 12) {
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+ WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
for (int j = 0; j < 48; j += 8) {
fprintf(f, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
sample_buf[j+0],
c.arg[0] = 6;
c.arg[1] = 3;
c.arg[2] = 0;
- sscanf(Cmd, " %i %i %i", &c.arg[0], &c.arg[1], &c.arg[2]);
+ sscanf(Cmd, " %"lli" %"lli" %"lli, &c.arg[0], &c.arg[1], &c.arg[2]);
SendCommand(&c);
return 0;
}
int CmdLegicRfWrite(const char *Cmd)
{
UsbCommand c={CMD_WRITER_LEGIC_RF};
- int res = sscanf(Cmd, " 0x%x 0x%x", &c.arg[0], &c.arg[1]);
+ int res = sscanf(Cmd, " 0x%"llx" 0x%"llx, &c.arg[0], &c.arg[1]);
if(res != 2) {
PrintAndLog("Please specify the offset and length as two hex strings");
return -1;
int CmdLegicRfFill(const char *Cmd)
{
UsbCommand cmd ={CMD_WRITER_LEGIC_RF};
- int res = sscanf(Cmd, " 0x%x 0x%x 0x%x", &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]);
+ int res = sscanf(Cmd, " 0x%"llx" 0x%"llx" 0x%"llx, &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]);
if(res != 3) {
PrintAndLog("Please specify the offset, length and value as two hex strings");
return -1;
for(i = 0; i < 22; i++) {
c.arg[0] = i*48;
SendCommand(&c);
- WaitForResponse(CMD_ACK);
+ WaitForResponse(CMD_ACK,NULL);
}
SendCommand(&cmd);
return 0;
//-----------------------------------------------------------------------------\r
\r
#include "cmdhfmf.h"\r
-#include "proxmark3.h"\r
\r
static int CmdHelp(const char *Cmd);\r
\r
break;\r
}\r
\r
- UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);\r
- if (resp != NULL) {\r
- isOK = resp->arg[0] & 0xff;\r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {\r
+ isOK = resp.arg[0] & 0xff;\r
\r
- uid = (uint32_t)bytes_to_num(resp->d.asBytes + 0, 4);\r
- nt = (uint32_t)bytes_to_num(resp->d.asBytes + 4, 4);\r
- par_list = bytes_to_num(resp->d.asBytes + 8, 8);\r
- ks_list = bytes_to_num(resp->d.asBytes + 16, 8);\r
+ uid = (uint32_t)bytes_to_num(resp.d.asBytes + 0, 4);\r
+ nt = (uint32_t)bytes_to_num(resp.d.asBytes + 4, 4);\r
+ par_list = bytes_to_num(resp.d.asBytes + 8, 8);\r
+ ks_list = bytes_to_num(resp.d.asBytes + 16, 8);\r
\r
printf("\n\n");\r
PrintAndLog("isOk:%02x", isOK);\r
PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt); \r
} else {\r
printf("------------------------------------------------------------------\n");\r
- PrintAndLog("Key found:%012I64x \n", r_key);\r
+ PrintAndLog("Key found:%012"llx" \n", r_key);\r
\r
num_to_bytes(r_key, 6, keyBlock);\r
isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);\r
}\r
if (!isOK) \r
- PrintAndLog("Found valid key:%012I64x", r_key);\r
+ PrintAndLog("Found valid key:%012"llx, r_key);\r
else\r
{\r
if (isOK != 2) PrintAndLog("Found invalid key. ( Nt=%08x ,Trying use it to run again...", nt); \r
memcpy(c.d.asBytes, key, 6);\r
memcpy(c.d.asBytes + 10, bldata, 16);\r
SendCommand(&c);\r
- UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
-\r
- if (resp != NULL) {\r
- uint8_t isOK = resp->arg[0] & 0xff;\r
\r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ uint8_t isOK = resp.arg[0] & 0xff;\r
PrintAndLog("isOk:%02x", isOK);\r
} else {\r
PrintAndLog("Command execute timeout");\r
UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};\r
memcpy(c.d.asBytes, key, 6);\r
SendCommand(&c);\r
- UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
\r
- if (resp != NULL) {\r
- uint8_t isOK = resp->arg[0] & 0xff;\r
- uint8_t * data = resp->d.asBytes;\r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ uint8_t isOK = resp.arg[0] & 0xff;\r
+ uint8_t * data = resp.d.asBytes;\r
\r
if (isOK)\r
PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));\r
UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};\r
memcpy(c.d.asBytes, key, 6);\r
SendCommand(&c);\r
- UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
PrintAndLog(" ");\r
\r
- if (resp != NULL) {\r
- isOK = resp->arg[0] & 0xff;\r
- data = resp->d.asBytes;\r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ isOK = resp.arg[0] & 0xff;\r
+ data = resp.d.asBytes;\r
\r
PrintAndLog("isOk:%02x", isOK);\r
if (isOK) \r
PrintAndLog("Command1 execute timeout");\r
}\r
\r
- // response2\r
- resp = WaitForResponseTimeout(CMD_ACK, 500);\r
+ // response2\r
PrintAndLog(" ");\r
-\r
- if (resp != NULL) {\r
- isOK = resp->arg[0] & 0xff;\r
- data = resp->d.asBytes;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ isOK = resp.arg[0] & 0xff;\r
+ data = resp.d.asBytes;\r
\r
if (isOK) \r
for (i = 0; i < 2; i++) {\r
FILE *fin;\r
FILE *fout;\r
\r
- UsbCommand *resp;\r
+ UsbCommand resp;\r
\r
if ((fin = fopen("dumpkeys.bin","rb")) == NULL) {\r
PrintAndLog("Could not find file dumpkeys.bin");\r
UsbCommand c = {CMD_MIFARE_READBL, {4*i + 3, 0, 0}};\r
memcpy(c.d.asBytes, keyA[i], 6);\r
SendCommand(&c);\r
- resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
\r
- if (resp != NULL) {\r
- uint8_t isOK = resp->arg[0] & 0xff;\r
- uint8_t *data = resp->d.asBytes;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ uint8_t isOK = resp.arg[0] & 0xff;\r
+ uint8_t *data = resp.d.asBytes;\r
if (isOK){\r
rights[i][0] = ((data[7] & 0x10)>>4) | ((data[8] & 0x1)<<1) | ((data[8] & 0x10)>>2);\r
rights[i][1] = ((data[7] & 0x20)>>5) | ((data[8] & 0x2)<<0) | ((data[8] & 0x20)>>3);\r
PrintAndLog("|----- Dumping all blocks to file... -----|");\r
PrintAndLog("|-----------------------------------------|");\r
\r
+ \r
for (i=0 ; i<16 ; i++) {\r
for (j=0 ; j<4 ; j++) {\r
- if (j == 3){\r
+ bool received = false;\r
+ \r
+ if (j == 3){\r
UsbCommand c = {CMD_MIFARE_READBL, {i*4 + j, 0, 0}};\r
memcpy(c.d.asBytes, keyA[i], 6);\r
SendCommand(&c);\r
- resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+ received = WaitForResponseTimeout(CMD_ACK,&resp,1500);\r
}\r
else{\r
if ((rights[i][j] == 6) | (rights[i][j] == 5)) {\r
UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 1, 0}};\r
memcpy(c.d.asBytes, keyB[i], 6);\r
SendCommand(&c);\r
- resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+ received = WaitForResponseTimeout(CMD_ACK,&resp,1500);\r
}\r
else if (rights[i][j] == 7) {\r
PrintAndLog("Access rights do not allow reading of sector %d block %d",i,j);\r
UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 0, 0}};\r
memcpy(c.d.asBytes, keyA[i], 6);\r
SendCommand(&c);\r
- resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+ received = WaitForResponseTimeout(CMD_ACK,&resp,1500);\r
}\r
}\r
\r
- if (resp != NULL) {\r
- uint8_t isOK = resp->arg[0] & 0xff;\r
- uint8_t *data = resp->d.asBytes;\r
+ if (received) {\r
+ uint8_t isOK = resp.arg[0] & 0xff;\r
+ uint8_t *data = resp.d.asBytes;\r
if (j == 3) {\r
data[0] = (keyA[i][0]);\r
data[1] = (keyA[i][1]);\r
\r
memcpy(c.d.asBytes + 10, bldata, 16);\r
SendCommand(&c);\r
- UsbCommand *resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
\r
- if (resp != NULL) {\r
- uint8_t isOK = resp->arg[0] & 0xff;\r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ uint8_t isOK = resp.arg[0] & 0xff;\r
PrintAndLog("isOk:%02x", isOK);\r
} else {\r
PrintAndLog("Command execute timeout");\r
if (res)\r
res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);\r
if (!res) {\r
- PrintAndLog("Found valid key:%012I64x", key64);\r
+ PrintAndLog("Found valid key:%012"llx, key64);\r
\r
// transfer key to the emulator\r
if (transferToEml) {\r
if (res)\r
res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);\r
if (!res) {\r
- PrintAndLog("Found valid key:%012I64x", key64); \r
+ PrintAndLog("Found valid key:%012"llx, key64);\r
e_sector[trgBlockNo / 4].foundKey[trgKeyType] = 1;\r
e_sector[trgBlockNo / 4].Key[trgKeyType] = key64;\r
}\r
PrintAndLog("|sec|key A |res|key B |res|");\r
PrintAndLog("|---|----------------|---|----------------|---|");\r
for (i = 0; i < SectorsCnt; i++) {\r
- PrintAndLog("|%03d| %012I64x | %d | %012I64x | %d |", i, \r
+ PrintAndLog("|%03d| %012"llx" | %d | %012"llx" | %d |", i,\r
e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);\r
}\r
PrintAndLog("|---|----------------|---|----------------|---|");\r
}\r
memset(keyBlock + 6 * keycnt, 0, 6);\r
num_to_bytes(strtoll(buf, NULL, 16), 6, keyBlock + 6*keycnt);\r
- PrintAndLog("chk custom key[%d] %012I64x", keycnt, bytes_to_num(keyBlock + 6*keycnt, 6));\r
+ PrintAndLog("chk custom key[%d] %012"llx, keycnt, bytes_to_num(keyBlock + 6*keycnt, 6));\r
keycnt++;\r
}\r
} else {\r
res = mfCheckKeys(b, t, size, keyBlock +6*c, &key64);\r
if (res !=1) {\r
if (!res) {\r
- PrintAndLog("Found valid key:[%012I64x]",key64);\r
+ PrintAndLog("Found valid key:[%012"llx"]",key64);\r
if (transferToEml) {\r
uint8_t block[16];\r
mfEmlGetMem(block, get_trailer_block(b), 1);\r
}\r
keyA = bytes_to_num(data, 6);\r
keyB = bytes_to_num(data + 10, 6);\r
- PrintAndLog("|%03d| %012I64x | %012I64x |", i, keyA, keyB);\r
+ PrintAndLog("|%03d| %012"llx" | %012"llx" |", i, keyA, keyB);\r
}\r
PrintAndLog("|---|----------------|----------------|");\r
\r
break;\r
}\r
\r
- UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);\r
- if (resp != NULL) {\r
- res = resp->arg[0] & 0xff;\r
- len = resp->arg[1];\r
- num = resp->arg[2];\r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {\r
+ res = resp.arg[0] & 0xff;\r
+ len = resp.arg[1];\r
+ num = resp.arg[2];\r
\r
if (res == 0) return 0;\r
if (res == 1) {\r
bufPtr = buf;\r
memset(buf, 0x00, 3000);\r
}\r
- memcpy(bufPtr, resp->d.asBytes, len);\r
+ memcpy(bufPtr, resp.d.asBytes, len);\r
bufPtr += len;\r
pckNum++;\r
}\r
int CmdHFMF(const char *Cmd)\r
{\r
// flush\r
- while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;\r
+ WaitForResponseTimeout(CMD_ACK,NULL,100);\r
\r
CmdsParse(CommandTable, Cmd);\r
return 0;\r
#include "proxmark3.h"\r
#include "iso14443crc.h"\r
#include "data.h"\r
-#include "proxusb.h"\r
+//#include "proxusb.h"\r
#include "ui.h"\r
#include "cmdparser.h"\r
#include "common.h"\r
#include <string.h>
#include <limits.h>
#include "ui.h"
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "cmdparser.h"
#include "cmdhw.h"
#include <stdlib.h>
#include <string.h>
#include <limits.h>
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "data.h"
#include "graph.h"
#include "ui.h"
dummy[0]= ' ';
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
- sscanf(Cmd, "%i %i %i %s %s", &c.arg[0], &c.arg[1], &c.arg[2], (char *) &c.d.asBytes,(char *) &dummy+1);
+ sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1));
// in case they specified 'h'
strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
SendCommand(&c);
return 0;
}
SendCommand(&c);
- WaitForResponse(CMD_ACK);
+ WaitForResponse(CMD_ACK,NULL);
return 0;
}
c.d.asBytes[j] = GraphBuffer[i+j];
}
SendCommand(&c);
- WaitForResponse(CMD_ACK);
+ WaitForResponse(CMD_ACK,NULL);
}
PrintAndLog("Starting simulator...");
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
{
int Word = 16; //default to invalid word
UsbCommand c;
-
+
sscanf(Cmd, "%d", &Word);
-
+
if (Word > 15) {
- PrintAndLog("Word must be between 0 and 15");
- return 1;
- }
-
+ PrintAndLog("Word must be between 0 and 15");
+ return 1;
+ }
+
PrintAndLog("Reading word %d", Word);
-
+
c.cmd = CMD_EM4X_READ_WORD;
c.d.asBytes[0] = 0x0; //Normal mode
c.arg[0] = 0;
int Word = 16; //default to invalid word
int Password = 0xFFFFFFFF; //default to blank password
UsbCommand c;
-
+
sscanf(Cmd, "%d %x", &Word, &Password);
-
+
if (Word > 15) {
- PrintAndLog("Word must be between 0 and 15");
- return 1;
- }
-
+ PrintAndLog("Word must be between 0 and 15");
+ return 1;
+ }
+
PrintAndLog("Reading word %d with password %08X", Word, Password);
-
+
c.cmd = CMD_EM4X_READ_WORD;
c.d.asBytes[0] = 0x1; //Password mode
c.arg[0] = 0;
int CmdWriteWord(const char *Cmd)
{
int Word = 16; //default to invalid block
- int Data = 0xFFFFFFFF; //default to blank data
+ int Data = 0xFFFFFFFF; //default to blank data
UsbCommand c;
-
+
sscanf(Cmd, "%x %d", &Data, &Word);
-
+
if (Word > 15) {
- PrintAndLog("Word must be between 0 and 15");
- return 1;
- }
-
+ PrintAndLog("Word must be between 0 and 15");
+ return 1;
+ }
+
PrintAndLog("Writting word %d with data %08X", Word, Data);
-
+
c.cmd = CMD_EM4X_WRITE_WORD;
c.d.asBytes[0] = 0x0; //Normal mode
c.arg[0] = Data;
int CmdWriteWordPWD(const char *Cmd)
{
int Word = 8; //default to invalid word
- int Data = 0xFFFFFFFF; //default to blank data
+ int Data = 0xFFFFFFFF; //default to blank data
int Password = 0xFFFFFFFF; //default to blank password
UsbCommand c;
-
+
sscanf(Cmd, "%x %d %x", &Data, &Word, &Password);
-
+
if (Word > 15) {
- PrintAndLog("Word must be between 0 and 15");
- return 1;
- }
-
+ PrintAndLog("Word must be between 0 and 15");
+ return 1;
+ }
+
PrintAndLog("Writting word %d with data %08X and password %08X", Word, Data, Password);
-
+
c.cmd = CMD_EM4X_WRITE_WORD;
c.d.asBytes[0] = 0x1; //Password mode
c.arg[0] = Data;
}
+
static command_t CommandTable[] =
{
- {"help", CmdHelp, 1, "This help"},
- {"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
- {"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
- {"em410xwatch", CmdEM410xWatch, 0, "Watches for EM410x tags"},
- {"em410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> -- Write EM410x UID to T5555(Q5) or T55x7 tag"},
- {"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
- {"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
- {"readwordPWD", CmdReadWordPWD, 1, "<Word> <Password> -- Read EM4xxx word data in password mode"},
- {"writeword", CmdWriteWord, 1, "<Data> <Word> -- Write EM4xxx word data"},
+ {"help", CmdHelp, 1, "This help"},
+ {"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
+ {"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
+ {"em410xwatch", CmdEM410xWatch, 0, "Watches for EM410x tags"},
+ {"em410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> -- Write EM410x UID to T5555(Q5) or T55x7 tag"},
+ {"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
+ {"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
+ {"readwordPWD", CmdReadWordPWD, 1, "<Word> <Password> -- Read EM4xxx word data in password mode"},
+ {"writeword", CmdWriteWord, 1, "<Data> <Word> -- Write EM4xxx word data"},
{"writewordPWD", CmdWriteWordPWD, 1, "<Data> <Word> <Password> -- Write EM4xxx word data in password mode"},
{NULL, NULL, 0, NULL}
};
//-----------------------------------------------------------------------------
#include <stdio.h>
-#include "proxusb.h"
+#include <string.h>
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
}
int CmdHIDSim(const char *Cmd)
-{
- unsigned int hi = 0, lo = 0;
- int n = 0, i = 0;
-
- while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
- hi = (hi << 4) | (lo >> 28);
- lo = (lo << 4) | (n & 0xf);
- }
-
- PrintAndLog("Emulating tag with ID %x%16x", hi, lo);
-
- UsbCommand c = {CMD_HID_SIM_TAG, {hi, lo, 0}};
- SendCommand(&c);
- return 0;
-}
-
-int CmdHIDClone(const char *Cmd)
{
unsigned int hi2 = 0, hi = 0, lo = 0;
int n = 0, i = 0;
UsbCommand c;
if (strchr(Cmd,'l') != 0) {
- while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
+ while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
hi2 = (hi2 << 4) | (hi >> 28);
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (n & 0xf);
}
-
+
PrintAndLog("Cloning tag with long ID %x%08x%08x", hi2, hi, lo);
-
+
c.d.asBytes[0] = 1;
- }
- else {
- while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
+ }
+ else {
+ while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (n & 0xf);
}
-
+
PrintAndLog("Cloning tag with ID %x%08x", hi, lo);
-
+
hi2 = 0;
c.d.asBytes[0] = 0;
}
-
+
c.cmd = CMD_HID_CLONE_TAG;
- c.arg[0] = hi2;
- c.arg[1] = hi;
- c.arg[2] = lo;
+ c.arg[0] = hi2;
+ c.arg[1] = hi;
+ c.arg[2] = lo;
+
+// UsbCommand c = {CMD_HID_SIM_TAG, {hi, lo, 0}};
+ SendCommand(&c);
+ return 0;
+}
+
+int CmdHIDClone(const char *Cmd)
+{
+ unsigned int hi = 0, lo = 0;
+ int n = 0, i = 0;
+
+ while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
+ hi = (hi << 4) | (lo >> 28);
+ lo = (lo << 4) | (n & 0xf);
+ }
+
+ PrintAndLog("Cloning tag with ID %x%08x", hi, lo);
+ UsbCommand c = {CMD_HID_CLONE_TAG, {hi, lo}};
SendCommand(&c);
return 0;
}
#include <stdlib.h>
#include <string.h>
#include "data.h"
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "ui.h"
#include "cmdparser.h"
#include "common.h"
#include "util.h"
#include "hitag2.h"
+#include "sleep.h"
+#include "cmdmain.h"
static int CmdHelp(const char *Cmd);
{
uint8_t got[3000];
GetFromBigBuf(got,sizeof(got),0);
- char filename[256];
- FILE* pf;
-
- param_getstr(Cmd,0,filename);
-
- if (strlen(filename) > 0) {
- if ((pf = fopen(filename,"w")) == NULL) {
- PrintAndLog("Error: Could not open file [%s]",filename);
- return 1;
- }
- }
+ WaitForResponse(CMD_ACK,NULL);
PrintAndLog("recorded activity:");
PrintAndLog(" ETU :rssi: who bytes");
int i = 0;
int prev = -1;
+ char filename[256];
+ FILE* pf = NULL;
+
for (;;) {
if(i >= 1900) {
break;
line);
- if (strlen(filename) > 0) {
+ if (pf) {
fprintf(pf," +%7d: %s: %s %s %s",
(prev < 0 ? 0 : (timestamp - prev)),
metricString,
i += (len + 9);
}
- if (strlen(filename) > 0) {
+ if (pf) {
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
fclose(pf);
}
} break;
default: {
PrintAndLog("Error: unkown reader function %d",htf);
- PrintAndLog("Hitag reader functions",htf);
- PrintAndLog(" HitagS (0*)",htf);
- PrintAndLog(" Hitag1 (1*)",htf);
- PrintAndLog(" Hitag2 (2*)",htf);
- PrintAndLog(" 21 <password> (password mode)",htf);
- PrintAndLog(" 22 <nr> <ar> (authentication)",htf);
- PrintAndLog(" 23 <key> (authentication) key is in format: ISK high + ISK low",htf);
- PrintAndLog(" 25 (test recorded authentications)",htf);
+ PrintAndLog("Hitag reader functions");
+ PrintAndLog(" HitagS (0*)");
+ PrintAndLog(" Hitag1 (1*)");
+ PrintAndLog(" Hitag2 (2*)");
+ PrintAndLog(" 21 <password> (password mode)");
+ PrintAndLog(" 22 <nr> <ar> (authentication)");
+ PrintAndLog(" 23 <key> (authentication) key is in format: ISK high + ISK low");
+ PrintAndLog(" 25 (test recorded authentications)");
return 1;
} break;
}
// Copy the hitag2 function into the first argument
c.arg[0] = htf;
+ // Send the command to the proxmark
SendCommand(&c);
+
+ UsbCommand resp;
+ WaitForResponse(CMD_ACK,&resp);
+
+ // Check the return status, stored in the first argument
+ if (resp.arg[0] == false) return 1;
+
+ uint32_t id = bytes_to_num(resp.d.asBytes,4);
+ char filename[256];
+ FILE* pf = NULL;
+
+ sprintf(filename,"%08x_%04x.ht2",id,(rand() & 0xffff));
+ if ((pf = fopen(filename,"wb")) == NULL) {
+ PrintAndLog("Error: Could not open file [%s]",filename);
+ return 1;
+ }
+
+ // Write the 48 tag memory bytes to file and finalize
+ fwrite(resp.d.asBytes,1,48,pf);
+ fclose(pf);
+
+ PrintAndLog("Succesfully saved tag memory to [%s]",filename);
+
return 0;
}
#include <stdio.h>
#include <string.h>
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
{
UsbCommand c = {CMD_PCF7931_READ};
SendCommand(&c);
- WaitForResponse(CMD_ACK);
+ UsbCommand resp;
+ WaitForResponse(CMD_ACK,&resp);
return 0;
}
#include <stdio.h>\r
#include <string.h>\r
#include <inttypes.h>\r
-#include "proxusb.h"\r
+//#include "proxusb.h"\r
+#include "proxmark3.h"\r
#include "ui.h"\r
#include "graph.h"\r
#include "cmdparser.h"\r
#include <stdio.h>
#include <stdlib.h>
#include "crc16.h"
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "data.h"
#include "ui.h"
#include "graph.h"
UsbCommand c = {CMD_WRITE_TI_TYPE};
int res = 0;
- res = sscanf(Cmd, "0x%x 0x%x 0x%x ", &c.arg[0], &c.arg[1], &c.arg[2]);
+ res = sscanf(Cmd, "0x%"PRIu64"x 0x%"PRIu64"x 0x%"PRIu64"x ", &c.arg[0], &c.arg[1], &c.arg[2]);
if (res == 2) c.arg[2]=0;
if (res < 2)
PrintAndLog("Please specify the data as two hex strings, optionally the CRC as a third");
#include <string.h>
#include "sleep.h"
#include "cmdparser.h"
+#include "proxmark3.h"
#include "data.h"
#include "usb_cmd.h"
#include "ui.h"
#include "cmdhw.h"
#include "cmdlf.h"
#include "cmdmain.h"
+#include "util.h"
unsigned int current_command = CMD_UNKNOWN;
unsigned int received_command = CMD_UNKNOWN;
return 0;
}
-UsbCommand * WaitForResponseTimeout(uint32_t response_type, uint32_t ms_timeout) {
- UsbCommand * ret = NULL;
- int i=0;
+bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
- for(i=0; received_command != response_type && i < ms_timeout / 10; i++) {
+ // Wait until the command is received
+ for(size_t i=0; received_command != cmd && i < ms_timeout/10; i++) {
msleep(10); // XXX ugh
+ if (i == 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");
+ }
}
- // There was an evil BUG
- memcpy(¤t_response_user, ¤t_response, sizeof(UsbCommand));
- ret = ¤t_response_user;
+ // Check if timeout occured
+ if(received_command != cmd) return false;
- if(received_command != response_type)
- ret = NULL;
+ // Copy the received response (if supplied)
+ if (response) {
+ memcpy(response, ¤t_response, sizeof(UsbCommand));
+ }
- received_command = CMD_UNKNOWN;
+ // Reset the received command
+ received_command = CMD_UNKNOWN;
- return ret;
+ return true;
}
-UsbCommand * WaitForResponse(uint32_t response_type)
-{
- return WaitForResponseTimeout(response_type, -1);
+bool WaitForResponse(uint32_t cmd, UsbCommand* response) {
+ return WaitForResponseTimeout(cmd,response,-1);
}
//-----------------------------------------------------------------------------
// Entry point into our code: called whenever the user types a command and
// then presses Enter, which the full command line that they typed.
//-----------------------------------------------------------------------------
-void CommandReceived(char *Cmd)
-{
+void CommandReceived(char *Cmd) {
CmdsParse(CommandTable, Cmd);
}
//-----------------------------------------------------------------------------
void UsbCommandReceived(UsbCommand *UC)
{
+ /*
+ // Debug
+ printf("UsbCommand length[len=%zd]\n",sizeof(UsbCommand));
+ printf(" cmd[len=%zd]: %"llx"\n",sizeof(UC->cmd),UC->cmd);
+ printf(" arg0[len=%zd]: %"llx"\n",sizeof(UC->arg[0]),UC->arg[0]);
+ printf(" arg1[len=%zd]: %"llx"\n",sizeof(UC->arg[1]),UC->arg[1]);
+ printf(" arg2[len=%zd]: %"llx"\n",sizeof(UC->arg[2]),UC->arg[2]);
+ printf(" data[len=%zd]: %02x%02x%02x...\n",sizeof(UC->d.asBytes),UC->d.asBytes[0],UC->d.asBytes[1],UC->d.asBytes[2]);
+ */
+
// printf("%s(%x) current cmd = %x\n", __FUNCTION__, c->cmd, current_command);
- /* If we recognize a response, return to avoid further processing */
+ // If we recognize a response, return to avoid further processing
switch(UC->cmd) {
- // First check if we are handling a debug message
+ // First check if we are handling a debug message
case CMD_DEBUG_PRINT_STRING: {
- char s[100];
- if(UC->arg[0] > 70 || UC->arg[0] < 0) {
- UC->arg[0] = 0;
- }
- memcpy(s, UC->d.asBytes, UC->arg[0]);
- s[UC->arg[0]] = '\0';
+ char s[USB_CMD_DATA_SIZE+1];
+ size_t len = MIN(UC->arg[0],USB_CMD_DATA_SIZE);
+ memcpy(s,UC->d.asBytes,len);
+ s[len] = 0x00;
PrintAndLog("#db# %s ", s);
return;
} break;
PrintAndLog("# Your HF antenna is marginal.");
} break;
+ case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
+// printf("received samples: ");
+// print_hex(UC->d.asBytes,512);
+ sample_buf_len += UC->arg[1];
+// printf("samples: %zd offset: %d\n",sample_buf_len,UC->arg[0]);
+ memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
+ } break;
+
+
+// case CMD_ACK: {
+// PrintAndLog("Receive ACK\n");
+// } break;
+
default: {
// Maybe it's a response
switch(current_command) {
PrintAndLog("unrecognized command %08x\n", UC->cmd);
break;
}
- int i;
- for(i=0; i<48; i++) sample_buf[i] = UC->d.asBytes[i];
+// int i;
+ PrintAndLog("received samples %d\n",UC->arg[0]);
+ memcpy(sample_buf+UC->arg[0],UC->d.asBytes,48);
+ sample_buf_len += 48;
+// for(i=0; i<48; i++) sample_buf[i] = UC->d.asBytes[i];
received_command = UC->cmd;
} break;
default: {
} break;
}
- // Store the last received command
- received_command = UC->cmd;
- memcpy(¤t_response, UC, sizeof(UsbCommand));
+// // Store the last received command
+// memcpy(¤t_response, UC, sizeof(UsbCommand));
+// received_command = UC->cmd;
} break;
}
+ // Store the last received command
+ memcpy(¤t_response, UC, sizeof(UsbCommand));
received_command = UC->cmd;
/*
// Maybe it's a response:
void UsbCommandReceived(UsbCommand *UC);
void CommandReceived(char *Cmd);
-UsbCommand * WaitForResponseTimeout(uint32_t response_type, uint32_t ms_timeout);
-UsbCommand * WaitForResponse(uint32_t response_type);
+bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout);
+bool WaitForResponse(uint32_t cmd, UsbCommand* response);
#endif
#include <string.h>
#include "ui.h"
#include "cmdparser.h"
+#include "proxmark3.h"
void CmdsHelp(const command_t Commands[])
{
#include <stdint.h>
#include "data.h"
#include "ui.h"
-#include "proxusb.h"
+//#include "proxusb.h"
+#include "proxmark3.h"
#include "cmdmain.h"
-uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
+uint8_t* sample_buf;
+size_t sample_buf_len;
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
{
- start_index = ((start_index/12)*12);
- int n = (((bytes/4)/48)*48) + start_index;
+ sample_buf_len = 0;
+ sample_buf = dest;
+// start_index = ((start_index/12)*12);
+// int n = start_index + bytes;
/*
if (n % 48 != 0) {
PrintAndLog("bad len in GetFromBigBuf");
return;
}
*/
- for (int i = start_index; i < n; i += 12) {
+ UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
+ SendCommand(&c);
+/*
+ for (int i = start_index; i < n; i += 48) {
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
- memcpy(dest+(i*4), sample_buf, 48);
+// WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+// memcpy(dest+(i*4), sample_buf, 48);
}
+*/
}
#define SAMPLE_BUFFER_SIZE 64
-extern uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
+extern uint8_t* sample_buf;
+extern size_t sample_buf_len;
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include "proxmark3.h"
#include "sleep.h"
-#include "proxusb.h"
+//#include "proxusb.h"
#include "flash.h"
#include "elf.h"
#include "proxendian.h"
+#include "usb_cmd.h"
+
+void SendCommand(UsbCommand* txcmd);
+void ReceiveCommand(UsbCommand* rxcmd);
+void CloseProxmark();
+int OpenProxmark(size_t i);
// FIXME: what the fuckity fuck
unsigned int current_command = CMD_UNKNOWN;
#define BOOTLOADER_SIZE 0x2000
#define BOOTLOADER_END (FLASH_START + BOOTLOADER_SIZE)
-#define BLOCK_SIZE 0x100
+#define BLOCK_SIZE 0x200
static const uint8_t elf_ident[] = {
0x7f, 'E', 'L', 'F',
{
UsbCommand c;
c.cmd = CMD_DEVICE_INFO;
- SendCommand(&c);
-
+// SendCommand_(&c);
+ SendCommand(&c);
UsbCommand resp;
ReceiveCommand(&resp);
*state = resp.arg[0];
break;
default:
- fprintf(stderr, "Error: Couldn't get proxmark state, bad response type: 0x%04x\n", resp.cmd);
+ fprintf(stderr, "Error: Couldn't get proxmark state, bad response type: 0x%04"llx"\n", resp.cmd);
return -1;
break;
}
static int wait_for_ack(void)
{
- UsbCommand ack;
+ UsbCommand ack;
ReceiveCommand(&ack);
if (ack.cmd != CMD_ACK) {
- printf("Error: Unexpected reply 0x%04x (expected ACK)\n", ack.cmd);
+ printf("Error: Unexpected reply 0x%04"llx" (expected ACK)\n", ack.cmd);
return -1;
}
return 0;
c.arg[2] = 0;
}
SendCommand(&c);
+// SendCommand_(&c);
return wait_for_ack();
} else {
fprintf(stderr, "Note: Your bootloader does not understand the new START_FLASH command\n");
memset(block_buf, 0xFF, BLOCK_SIZE);
memcpy(block_buf, data, length);
-
- UsbCommand c = {CMD_SETUP_WRITE};
+ UsbCommand c;
+/*
+ c.cmd = {CMD_SETUP_WRITE};
for (int i = 0; i < 240; i += 48) {
memcpy(c.d.asBytes, block_buf + i, 48);
c.arg[0] = i / 4;
SendCommand(&c);
- if (wait_for_ack() < 0)
+// SendCommand_(&c);
+ if (wait_for_ack() < 0) {
return -1;
+ }
}
-
+*/
c.cmd = CMD_FINISH_WRITE;
c.arg[0] = address;
- memcpy(c.d.asBytes, block_buf+240, 16);
- SendCommand(&c);
- return wait_for_ack();
+// memcpy(c.d.asBytes, block_buf+240, 16);
+// SendCommand_(&c);
+ memcpy(c.d.asBytes, block_buf, length);
+ SendCommand(&c);
+ return wait_for_ack();
}
// Write a file's segments to Flash
// just reset the unit
int flash_stop_flashing(void) {
UsbCommand c = {CMD_HARDWARE_RESET};
- SendCommand(&c);
- return 0;
+// SendCommand_(&c);
+ SendCommand(&c);
+ return 0;
}
#include <stdlib.h>
#include <string.h>
#include "sleep.h"
-#include "proxusb.h"
+#include "proxmark3.h"
#include "flash.h"
+#include "uart.h"
+#include "usb_cmd.h"
+
+static serial_port sp;
+static char* serial_port_name;
+
+void cmd_debug(UsbCommand* UC) {
+ // Debug
+ printf("UsbCommand length[len=%zd]\n",sizeof(UsbCommand));
+ printf(" cmd[len=%zd]: %016"llx"\n",sizeof(UC->cmd),UC->cmd);
+ printf(" arg0[len=%zd]: %016"llx"\n",sizeof(UC->arg[0]),UC->arg[0]);
+ printf(" arg1[len=%zd]: %016"llx"\n",sizeof(UC->arg[1]),UC->arg[1]);
+ printf(" arg2[len=%zd]: %016"llx"\n",sizeof(UC->arg[2]),UC->arg[2]);
+ printf(" data[len=%zd]: ",sizeof(UC->d.asBytes));
+ for (size_t i=0; i<16; i++) {
+ printf("%02x",UC->d.asBytes[i]);
+ }
+ printf("...\n");
+}
+
+void SendCommand(UsbCommand* txcmd) {
+// printf("send: ");
+// cmd_debug(txcmd);
+ if (!uart_send(sp,(byte_t*)txcmd,sizeof(UsbCommand))) {
+ printf("Sending bytes to proxmark failed\n");
+ exit(1);
+ }
+}
+
+void ReceiveCommand(UsbCommand* rxcmd) {
+ byte_t* prxcmd = (byte_t*)rxcmd;
+ byte_t* prx = prxcmd;
+ size_t rxlen;
+ while (true) {
+ rxlen = sizeof(UsbCommand) - (prx-prxcmd);
+ if (uart_receive(sp,prx,&rxlen)) {
+// printf("received [%zd] bytes\n",rxlen);
+ prx += rxlen;
+ if ((prx-prxcmd) >= sizeof(UsbCommand)) {
+// printf("received: ");
+// cmd_debug(rxcmd);
+ return;
+ }
+ }
+ }
+}
+
+void CloseProxmark() {
+ // Clean up the port
+ uart_close(sp);
+}
+
+int OpenProxmark(size_t i) {
+ sp = uart_open(serial_port_name);
+ if (sp == INVALID_SERIAL_PORT) {
+ //poll once a second
+ msleep(100);
+ return 0;
+ }
+ return 1;
+}
static void usage(char *argv0)
{
- fprintf(stderr, "Usage: %s [-b] image.elf [image.elf...]\n\n", argv0);
+ fprintf(stderr, "Usage: %s <port> [-b] image.elf [image.elf...]\n\n", argv0);
fprintf(stderr, "\t-b\tEnable flashing of bootloader area (DANGEROUS)\n\n");
fprintf(stderr, "Example: %s path/to/osimage.elf path/to/fpgaimage.elf\n", argv0);
}
memset(files, 0, sizeof(files));
- if (argc < 2) {
+ if (argc < 3) {
usage(argv[0]);
return -1;
}
- for (int i = 1; i < argc; i++) {
+ for (int i = 2; i < argc; i++) {
if (argv[i][0] == '-') {
if (!strcmp(argv[i], "-b")) {
can_write_bl = 1;
}
}
- usb_init();
-
+ serial_port_name = argv[1];
fprintf(stderr, "Waiting for Proxmark to appear on USB...");
while (!OpenProxmark(0)) {
- sleep(1);
fprintf(stderr, ".");
}
fprintf(stderr, " Found.\n");
--- /dev/null
+/**
+ * Proxmark3 (debug) messages
+ *
+ * Copyright (c) 2012, Roel Verdult
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * @file messages.h
+ * @brief
+ */
+
+#ifndef _PROXMARK_MESSAGES_H_
+#define _PROXMARK_MESSAGES_H_
+
+// Useful macros
+#ifdef DEBUG
+// #define DBG(x, args...) printf("DBG %s:%d: " x "\n", __FILE__, __LINE__,## args )
+ #define DBG(x, ...) fprintf(stderr, "DBG %s:%d: " x "\n", __FILE__, __LINE__, ## __VA_ARGS__ )
+#else
+ #define DBG(...) {}
+#endif
+
+#define INFO(x, ...) printf("INFO: " x "\n", ## __VA_ARGS__ )
+#define WARN(x, ...) printf("WARNING: " x "\n", ## __VA_ARGS__ )
+#define ERR(x, ...) fprintf(stderr, "ERROR: " x "\n", ## __VA_ARGS__ )
+
+#endif // _PROXMARK_MESSAGES_H_
#include <stdlib.h> \r
#include <string.h>\r
#include "mifarehost.h"\r
+#include "proxmark3.h"\r
\r
// MIFARE\r
-\r
int compar_int(const void * a, const void * b) {\r
return (*(uint64_t*)b - *(uint64_t*)a);\r
}\r
fnVector * vector = NULL;\r
countKeys *ck;\r
int lenVector = 0;\r
- UsbCommand * resp = NULL;\r
+ UsbCommand resp;\r
\r
memset(resultKeys, 0x00, 16 * 6);\r
\r
// flush queue\r
- while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;\r
+ WaitForResponseTimeout(CMD_ACK,NULL,100);\r
\r
UsbCommand c = {CMD_MIFARE_NESTED, {blockNo, keyType, trgBlockNo + trgKeyType * 0x100}};\r
memcpy(c.d.asBytes, key, 6);\r
break;\r
}\r
\r
- resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
-\r
- if (resp != NULL) {\r
- isEOF = resp->arg[0] & 0xff;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ isEOF = resp.arg[0] & 0xff;\r
\r
if (isEOF) break;\r
\r
- len = resp->arg[1] & 0xff;\r
+ len = resp.arg[1] & 0xff;\r
if (len == 0) continue;\r
\r
- memcpy(&uid, resp->d.asBytes, 4); \r
- PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, resp->arg[2] & 0xff, (resp->arg[2] >> 8) & 0xff);\r
+ memcpy(&uid, resp.d.asBytes, 4);\r
+ PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, resp.arg[2] & 0xff, (resp.arg[2] >> 8) & 0xff);\r
vector = (fnVector *) realloc((void *)vector, (lenVector + len) * sizeof(fnVector) + 200);\r
if (vector == NULL) {\r
PrintAndLog("Memory allocation error for fnVector. len: %d bytes: %d", lenVector + len, (lenVector + len) * sizeof(fnVector)); \r
}\r
\r
for (i = 0; i < len; i++) {\r
- vector[lenVector + i].blockNo = resp->arg[2] & 0xff;\r
- vector[lenVector + i].keyType = (resp->arg[2] >> 8) & 0xff;\r
+ vector[lenVector + i].blockNo = resp.arg[2] & 0xff;\r
+ vector[lenVector + i].keyType = (resp.arg[2] >> 8) & 0xff;\r
vector[lenVector + i].uid = uid;\r
\r
- memcpy(&vector[lenVector + i].nt, (void *)(resp->d.asBytes + 8 + i * 8 + 0), 4);\r
- memcpy(&vector[lenVector + i].ks1, (void *)(resp->d.asBytes + 8 + i * 8 + 4), 4);\r
+ memcpy(&vector[lenVector + i].nt, (void *)(resp.d.asBytes + 8 + i * 8 + 0), 4);\r
+ memcpy(&vector[lenVector + i].ks1, (void *)(resp.d.asBytes + 8 + i * 8 + 4), 4);\r
}\r
\r
lenVector += len;\r
\r
UsbCommand c = {CMD_MIFARE_CHKKEYS, {blockNo, keyType, keycnt}};\r
memcpy(c.d.asBytes, keyBlock, 6 * keycnt);\r
-\r
SendCommand(&c);\r
\r
- UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 3000);\r
-\r
- if (resp == NULL) return 1;\r
- if ((resp->arg[0] & 0xff) != 0x01) return 2;\r
- *key = bytes_to_num(resp->d.asBytes, 6);\r
+ UsbCommand resp;\r
+ if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) return 1;\r
+ if ((resp.arg[0] & 0xff) != 0x01) return 2;\r
+ *key = bytes_to_num(resp.d.asBytes, 6);\r
return 0;\r
}\r
\r
\r
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {\r
UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}};\r
- \r
- SendCommand(&c);\r
-\r
- UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
+ SendCommand(&c);\r
\r
- if (resp == NULL) return 1;\r
- memcpy(data, resp->d.asBytes, blocksCount * 16); \r
+ UsbCommand resp;\r
+ if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) return 1;\r
+ memcpy(data, resp.d.asBytes, blocksCount * 16);\r
return 0;\r
}\r
\r
memcpy(c.d.asBytes, data, 16); \r
SendCommand(&c);\r
\r
- UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
-\r
- if (resp != NULL) {\r
- isOK = resp->arg[0] & 0xff;\r
- if (uid != NULL) memcpy(uid, resp->d.asBytes, 4); \r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ isOK = resp.arg[0] & 0xff;\r
+ if (uid != NULL) memcpy(uid, resp.d.asBytes, 4);\r
if (!isOK) return 2;\r
} else {\r
PrintAndLog("Command execute timeout");\r
UsbCommand c = {CMD_MIFARE_EML_CGETBLOCK, {params, 0, blockNo}};\r
SendCommand(&c);\r
\r
- UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);\r
-\r
- if (resp != NULL) {\r
- isOK = resp->arg[0] & 0xff;\r
- memcpy(data, resp->d.asBytes, 16); \r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
+ isOK = resp.arg[0] & 0xff;\r
+ memcpy(data, resp.d.asBytes, 16);\r
if (!isOK) return 2;\r
} else {\r
PrintAndLog("Command execute timeout");\r
#include "cmdmain.h"\r
#include "ui.h"\r
#include "data.h"\r
-#include "proxusb.h"\r
+//#include "proxusb.h"\r
#include "util.h"\r
#include "nonce2key/nonce2key.h"\r
#include "nonce2key/crapto1.h"\r
x ^= x >> 4;
return BIT(0x6996, x & 0xf);
#else
- asm( "movl %1, %%eax\n"
+ __asm( "movl %1, %%eax\n"
"mov %%ax, %%cx\n"
"shrl $0x10, %%eax\n"
"xor %%ax, %%cx\n"
// MIFARE Darkside hack
//-----------------------------------------------------------------------------
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#define llx PRIx64
+
#include "nonce2key.h"
#include "ui.h"
// Reset the last three significant bits of the reader nonce
nr &= 0xffffff1f;
- PrintAndLog("\nuid(%08x) nt(%08x) par(%016llx) ks(%016llx)\n\n",uid,nt,par_info,ks_info);
+ PrintAndLog("\nuid(%08x) nt(%08x) par(%016"llx") ks(%016"llx")\n\n",uid,nt,par_info,ks_info);
for (pos=0; pos<8; pos++)
{
#ifndef __NONCE2KEY_H
#define __NONCE2KEY_H
-#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include "crapto1.h"
#include <unistd.h>
#include <readline/readline.h>
#include <readline/history.h>
-#include "proxusb.h"
+//#include "proxusb.h"
#include "proxmark3.h"
#include "proxgui.h"
#include "cmdmain.h"
+#include "uart.h"
+#include "messages.h"
+#include "ui.h"
+
+static serial_port sp;
+static UsbCommand txcmd;
+static bool txcmd_pending = false;
+
+void SendCommand(UsbCommand *c) {
+#if 0
+ printf("Sending %d bytes\n", sizeof(UsbCommand));
+#endif
+/*
+ if (txcmd_pending) {
+ ERR("Sending command failed, previous command is still pending");
+ }
+*/
+ while(txcmd_pending);
+ txcmd = *c;
+ txcmd_pending = true;
+}
-struct usb_receiver_arg
-{
+struct receiver_arg {
int run;
};
-struct main_loop_arg
-{
+struct main_loop_arg {
int usb_present;
char *script_cmds_file;
};
-static void *usb_receiver(void *targ)
-{
- struct usb_receiver_arg *arg = (struct usb_receiver_arg*)targ;
- UsbCommand cmdbuf;
-
+//static void *usb_receiver(void *targ) {
+// struct receiver_arg *arg = (struct receiver_arg*)targ;
+// UsbCommand cmdbuf;
+//
+// while (arg->run) {
+// if (ReceiveCommandPoll(&cmdbuf)) {
+// UsbCommandReceived(&cmdbuf);
+// fflush(NULL);
+// }
+// }
+//
+// pthread_exit(NULL);
+// return NULL;
+//}
+
+byte_t rx[0x1000000];
+byte_t* prx = rx;
+
+static void *uart_receiver(void *targ) {
+ struct receiver_arg *arg = (struct receiver_arg*)targ;
+ size_t rxlen;
+ size_t cmd_count;
+
while (arg->run) {
- if (ReceiveCommandPoll(&cmdbuf)) {
- UsbCommandReceived(&cmdbuf);
- fflush(NULL);
+ rxlen = sizeof(UsbCommand);
+ if (uart_receive(sp,prx,&rxlen)) {
+ prx += rxlen;
+ if (((prx-rx) % sizeof(UsbCommand)) != 0) {
+ continue;
+ }
+ cmd_count = (prx-rx) / sizeof(UsbCommand);
+ // printf("received %d bytes, which represents %d commands\n",(prx-rx), cmd_count);
+ for (size_t i=0; i<cmd_count; i++) {
+ UsbCommandReceived((UsbCommand*)(rx+(i*sizeof(UsbCommand))));
+ }
+ }
+ prx = rx;
+
+ if(txcmd_pending) {
+ if (!uart_send(sp,(byte_t*)&txcmd,sizeof(UsbCommand))) {
+ PrintAndLog("Sending bytes to proxmark failed");
+ }
+ txcmd_pending = false;
}
}
-
+
pthread_exit(NULL);
return NULL;
}
-static void *main_loop(void *targ)
-{
- struct main_loop_arg *arg = (struct main_loop_arg*)targ;
- struct usb_receiver_arg rarg;
- char *cmd = NULL;
- pthread_t reader_thread;
-
- if (arg->usb_present == 1) {
- rarg.run=1;
- pthread_create(&reader_thread, NULL, &usb_receiver, &rarg);
- }
-
- FILE *script_file = NULL;
- char script_cmd_buf[256];
-
- if (arg->script_cmds_file)
+static void *main_loop(void *targ) {
+ struct main_loop_arg *arg = (struct main_loop_arg*)targ;
+ struct receiver_arg rarg;
+ char *cmd = NULL;
+ pthread_t reader_thread;
+
+ if (arg->usb_present == 1) {
+ rarg.run=1;
+ // pthread_create(&reader_thread, NULL, &usb_receiver, &rarg);
+ pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
+ }
+
+ FILE *script_file = NULL;
+ char script_cmd_buf[256];
+
+ if (arg->script_cmds_file)
+ {
+ script_file = fopen(arg->script_cmds_file, "r");
+ if (script_file)
{
- script_file = fopen(arg->script_cmds_file, "r");
- if (script_file)
- {
- printf("using 'scripting' commands file %s\n", arg->script_cmds_file);
- }
+ printf("using 'scripting' commands file %s\n", arg->script_cmds_file);
}
+ }
read_history(".history");
while(1)
+ {
+ // If there is a script file
+ if (script_file)
+ {
+ if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), script_file))
+ {
+ fclose(script_file);
+ script_file = NULL;
+ }
+ else
+ {
+ char *nl;
+ nl = strrchr(script_cmd_buf, '\r');
+ if (nl) *nl = '\0';
+ nl = strrchr(script_cmd_buf, '\n');
+ if (nl) *nl = '\0';
+
+ if ((cmd = (char*) malloc(strlen(script_cmd_buf) + 1)) != NULL)
{
- // If there is a script file
- if (script_file)
- {
- if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), script_file))
- {
- fclose(script_file);
- script_file = NULL;
- }
- else
- {
- char *nl;
- nl = strrchr(script_cmd_buf, '\r');
- if (nl) *nl = '\0';
- nl = strrchr(script_cmd_buf, '\n');
- if (nl) *nl = '\0';
-
- if ((cmd = (char*) malloc(strlen(script_cmd_buf) + 1)) != NULL)
- {
- memset(cmd, 0, strlen(script_cmd_buf));
- strcpy(cmd, script_cmd_buf);
- printf("%s\n", cmd);
- }
- }
- }
+ memset(cmd, 0, strlen(script_cmd_buf));
+ strcpy(cmd, script_cmd_buf);
+ printf("%s\n", cmd);
+ }
+ }
+ }
if (!script_file)
{
- cmd = readline(PROXPROMPT);
+ cmd = readline(PROXPROMPT);
}
if (cmd) {
while(cmd[strlen(cmd) - 1] == ' ')
- cmd[strlen(cmd) - 1] = 0x00;
+ cmd[strlen(cmd) - 1] = 0x00;
if (cmd[0] != 0x00) {
if (strncmp(cmd, "quit", 4) == 0) {
break;
}
}
-
+
write_history(".history");
-
- if (arg->usb_present == 1) {
- rarg.run = 0;
- pthread_join(reader_thread, NULL);
- }
-
- if (script_file)
- {
- fclose(script_file);
- script_file = NULL;
- }
-
- ExitGraphics();
- pthread_exit(NULL);
- return NULL;
+
+ if (arg->usb_present == 1) {
+ rarg.run = 0;
+ pthread_join(reader_thread, NULL);
+ }
+
+ if (script_file)
+ {
+ fclose(script_file);
+ script_file = NULL;
+ }
+
+ ExitGraphics();
+ pthread_exit(NULL);
+ return NULL;
}
-int main(int argc, char **argv)
-{
+int main(int argc, char* argv[]) {
+ srand(time(0));
+
+ if (argc < 2) {
+ printf("syntax: %s <port>\n\n",argv[0]);
+ return 1;
+ }
+
// Make sure to initialize
struct main_loop_arg marg = {
.usb_present = 0,
.script_cmds_file = NULL
};
pthread_t main_loop_t;
- usb_init();
-
- // If the user passed the filename of the 'script' to execute, get it
- if (argc > 1 && argv[1])
- {
- marg.script_cmds_file = argv[1];
- }
+/*
+ usb_init();
if (!OpenProxmark(1)) {
fprintf(stderr,"PROXMARK3: NOT FOUND!\n");
marg.usb_present = 0;
marg.usb_present = 1;
offline = 0;
}
+*/
+ sp = uart_open(argv[1]);
+ if (sp == INVALID_SERIAL_PORT) {
+ printf("ERROR: invalid serial port\n");
+ marg.usb_present = 0;
+ offline = 1;
+ } else {
+ marg.usb_present = 1;
+ offline = 0;
+ }
+ // If the user passed the filename of the 'script' to execute, get it
+ if (argc > 2 && argv[2]) {
+ marg.script_cmds_file = argv[2];
+ }
+
pthread_create(&main_loop_t, NULL, &main_loop, &marg);
InitGraphics(argc, argv);
pthread_join(main_loop_t, NULL);
- if (marg.usb_present == 1) {
- CloseProxmark();
- }
+// if (marg.usb_present == 1) {
+// CloseProxmark();
+// }
+
+ // Clean up the port
+ uart_close(sp);
+
return 0;
}
#ifndef PROXMARK3_H__
#define PROXMARK3_H__
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#define llx PRIx64
+#define lli PRIi64
+#define hhu PRIu8
+
+#include <usb.h>
+#include "usb_cmd.h"
+
#define PROXPROMPT "proxmark3> "
+void SendCommand(UsbCommand *c);
+
#endif
+++ /dev/null
-//-----------------------------------------------------------------------------
-// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
-// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
-//
-// 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.
-//-----------------------------------------------------------------------------
-// USB utilities
-//-----------------------------------------------------------------------------
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <unistd.h>
-#include <usb.h>
-#include <strings.h>
-#include <errno.h>
-
-#include "sleep.h"
-#include "proxusb.h"
-#include "proxmark3.h"
-#include "usb_cmd.h"
-
-// It seems to be missing for mingw
-#ifndef ETIMEDOUT
-#define ETIMEDOUT 116
-#endif
-
-usb_dev_handle *devh = NULL;
-static unsigned int claimed_iface = 0;
-unsigned char return_on_error = 0;
-unsigned char error_occured = 0;
-extern unsigned int current_command;
-
-void SendCommand(UsbCommand *c)
-{
- int ret;
-
-#if 0
- printf("Sending %d bytes\n", sizeof(UsbCommand));
-#endif
- current_command = c->cmd;
- ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(UsbCommand), 1000);
- if (ret<0) {
- error_occured = 1;
- if (return_on_error)
- return;
-
- fprintf(stderr, "write failed: %s!\nTrying to reopen device...\n",
- usb_strerror());
-
- if (devh) {
- usb_close(devh);
- devh = NULL;
- }
- while(!OpenProxmark(0)) { sleep(1); }
- printf(PROXPROMPT);
- fflush(NULL);
-
- return;
- }
-}
-
-bool ReceiveCommandPoll(UsbCommand *c)
-{
- int ret;
-
- memset(c, 0, sizeof (UsbCommand));
- ret = usb_bulk_read(devh, 0x82, (char*)c, sizeof(UsbCommand), 500);
- if (ret<0) {
- if (ret != -ETIMEDOUT) {
- error_occured = 1;
- if (return_on_error)
- return false;
-
- fprintf(stderr, "read failed: %s(%d)!\nTrying to reopen device...\n",
- usb_strerror(), ret);
-
- if (devh) {
- usb_close(devh);
- devh = NULL;
- }
- while(!OpenProxmark(0)) { sleep(1); }
- printf(PROXPROMPT);
- fflush(NULL);
-
- return false;
- }
- } else {
- if (ret && (ret < sizeof(UsbCommand))) {
- fprintf(stderr, "Read only %d instead of requested %d bytes!\n",
- ret, (int)sizeof(UsbCommand));
- }
- }
-
- return ret > 0;
-}
-
-void ReceiveCommand(UsbCommand *c)
-{
-// printf("%s()\n", __FUNCTION__);
- int retval = 0;
- do {
- retval = ReceiveCommandPoll(c);
- if (retval != 1) printf("ReceiveCommandPoll returned %d\n", retval);
- } while(retval<0);
-// printf("recv %x\n", c->cmd);
-}
-
-usb_dev_handle* findProxmark(int verbose, unsigned int *iface)
-{
- struct usb_bus *busses, *bus;
- usb_dev_handle *handle = NULL;
- struct prox_unit units[50];
- int iUnit = 0;
-
- usb_find_busses();
- usb_find_devices();
-
- busses = usb_get_busses();
-
- for (bus = busses; bus; bus = bus->next) {
- struct usb_device *dev;
-
- for (dev = bus->devices; dev; dev = dev->next) {
- struct usb_device_descriptor *desc = &(dev->descriptor);
-
- if ((desc->idProduct == 0x4b8f) && (desc->idVendor == 0x9ac4)) {
- handle = usb_open(dev);
- if (!handle) {
- if (verbose)
- fprintf(stderr, "open fabiled: %s!\n", usb_strerror());
- //return NULL;
- continue;
- }
- *iface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
-
- struct prox_unit unit = {handle, {0}};
- usb_get_string_simple(handle, desc->iSerialNumber, unit.serial_number, sizeof(unit.serial_number));
- units[iUnit++] = unit;
-
- //return handle;
- }
- }
- }
-
- if (iUnit > 0) {
- int iSelection = 0;
-
- fprintf(stdout, "\nConnected units:\n");
-
- for (int i = 0; i < iUnit; i++) {
- struct usb_device * dev = usb_device(units[i].handle);
- fprintf(stdout, "\t%d. SN: %s [%s/%s]\n", i+1, units[i].serial_number, dev->bus->dirname, dev->filename);
- }
- if (iUnit > 1) {
- while (iSelection < 1 || iSelection > iUnit) {
- fprintf(stdout, "Which unit do you want to connect to? ");
- fscanf(stdin, "%d", &iSelection);
- }
- }
- else
- iSelection = 1;
- iSelection --;
-
- for (int i = 0; i < iUnit; i++) {
- if (iSelection == i) continue;
- usb_close(units[i].handle);
- units[i].handle = NULL;
- }
-
- return units[iSelection].handle;
- }
-
- return NULL;
-}
-
-usb_dev_handle* OpenProxmark(int verbose)
-{
- int ret;
- usb_dev_handle *handle = NULL;
- unsigned int iface;
-
- handle = findProxmark(verbose, &iface);
- if (!handle)
- return NULL;
-
-#ifdef __linux__
- /* detach kernel driver first */
- ret = usb_detach_kernel_driver_np(handle, iface);
- /* don't complain if no driver attached */
- if (ret<0 && ret != -61 && verbose)
- fprintf(stderr, "detach kernel driver failed: (%d) %s!\n", ret, usb_strerror());
-#endif
-
- // Needed for Windows. Optional for Mac OS and Linux
- ret = usb_set_configuration(handle, 1);
- if (ret < 0) {
- if (verbose)
- fprintf(stderr, "configuration set failed: %s!\n", usb_strerror());
- return NULL;
- }
-
- ret = usb_claim_interface(handle, iface);
- if (ret < 0) {
- if (verbose)
- fprintf(stderr, "claim failed: %s!\n", usb_strerror());
- return NULL;
- }
- claimed_iface = iface;
- devh = handle;
- return handle;
-}
-
-void CloseProxmark(void)
-{
- usb_release_interface(devh, claimed_iface);
- usb_close(devh);
- devh = NULL;
-}
+++ /dev/null
-//-----------------------------------------------------------------------------
-// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
-//
-// 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.
-//-----------------------------------------------------------------------------
-// USB utilities
-//-----------------------------------------------------------------------------
-
-#ifndef PROXUSB_H__
-#define PROXUSB_H__
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <usb.h>
-#include "usb_cmd.h"
-
-extern unsigned char return_on_error;
-extern unsigned char error_occured;
-
-void SendCommand(UsbCommand *c);
-bool ReceiveCommandPoll(UsbCommand *c);
-void ReceiveCommand(UsbCommand *c);
-struct usb_dev_handle* FindProxmark(int verbose, unsigned int *iface);
-struct usb_dev_handle* OpenProxmark(int verbose);
-void CloseProxmark(void);
-
-struct prox_unit {
- usb_dev_handle *handle;
- char serial_number[256];
-};
-
-#endif
#ifndef SLEEP_H__
#define SLEEP_H__
-#ifdef WIN32
+#ifdef _WIN32
#include <windows.h>
#define sleep(n) Sleep(1000 * n)
#define msleep(n) Sleep(n)
--- /dev/null
+/*
+ * Proxmark3 generic uart / rs232/ serial port library
+ *
+ * Copyright (c) 2012, Roel Verdult
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @file uart.c
+ * @brief
+ *
+ * Partly based on uart-code written by Teunis van Beelen, available:
+ * http://www.teuniz.net/RS-232/index.html
+ *
+ */
+
+#include "uart.h"
+#include "messages.h"
+
+// Test if we are dealing with unix operating systems
+#ifndef _WIN32
+
+#include <termios.h>
+typedef struct termios term_info;
+typedef struct {
+ int fd; // Serial port file descriptor
+ term_info tiOld; // Terminal info before using the port
+ term_info tiNew; // Terminal info during the transaction
+} serial_port_unix;
+
+// Set time-out on 30 miliseconds
+const struct timeval timeout = {
+ .tv_sec = 0, // 0 second
+ .tv_usec = 30000 // 30000 micro seconds
+};
+
+// Work-around to claim uart interface using the c_iflag (software input processing) from the termios struct
+#define CCLAIMED 0x80000000
+
+serial_port uart_open(const char* pcPortName)
+{
+ serial_port_unix* sp = malloc(sizeof(serial_port_unix));
+
+ if (sp == 0) return INVALID_SERIAL_PORT;
+
+ sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);
+ if(sp->fd == -1)
+ {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ if(tcgetattr(sp->fd,&sp->tiOld) == -1)
+ {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ // Make sure the port is not claimed already
+ if (sp->tiOld.c_iflag & CCLAIMED)
+ {
+ uart_close(sp);
+ return CLAIMED_SERIAL_PORT;
+ }
+
+ // Copy the old terminal info struct
+ sp->tiNew = sp->tiOld;
+
+ sp->tiNew.c_cflag = CS8 | CLOCAL | CREAD;
+ sp->tiNew.c_iflag = CCLAIMED | IGNPAR;
+ sp->tiNew.c_oflag = 0;
+ sp->tiNew.c_lflag = 0;
+
+ sp->tiNew.c_cc[VMIN] = 0; // block until n bytes are received
+ sp->tiNew.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.)
+
+ if(tcsetattr(sp->fd,TCSANOW,&sp->tiNew) == -1)
+ {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ tcflush(sp->fd, TCIFLUSH);
+ return sp;
+}
+
+void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
+{
+ DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
+ // Set port speed (Input and Output)
+ speed_t stPortSpeed = B9600;
+ switch(uiPortSpeed) {
+ case 9600: stPortSpeed = B9600;
+ break;
+ case 19200: stPortSpeed = B19200;
+ break;
+ case 38400: stPortSpeed = B38400;
+ break;
+ case 57600: stPortSpeed = B57600;
+ break;
+ case 115200: stPortSpeed = B115200;
+ break;
+ case 230400: stPortSpeed = B230400;
+ break;
+#ifdef B460800
+ case 460800: stPortSpeed = B460800;
+ break;
+#endif
+ default:
+#ifdef B460800
+ ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
+#else
+ ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200 or 230400.", uiPortSpeed);
+#endif
+ };
+ const serial_port_unix* spu = (serial_port_unix*)sp;
+ cfsetispeed((struct termios*)&spu->tiNew, stPortSpeed);
+ cfsetospeed((struct termios*)&spu->tiNew, stPortSpeed);
+ if( tcsetattr(spu->fd, TCSADRAIN, &spu->tiNew) == -1)
+ {
+ ERR("Unable to apply new speed settings.");
+ }
+}
+
+uint32_t uart_get_speed(const serial_port sp)
+{
+ uint32_t uiPortSpeed = 0;
+ const serial_port_unix* spu = (serial_port_unix*)sp;
+ switch (cfgetispeed(&spu->tiNew))
+ {
+ case B9600: uiPortSpeed = 9600;
+ break;
+ case B19200: uiPortSpeed = 19200;
+ break;
+ case B38400: uiPortSpeed = 38400;
+ break;
+ case B57600: uiPortSpeed = 57600;
+ break;
+ case B115200: uiPortSpeed = 115200;
+ break;
+ case B230400: uiPortSpeed = 230400;
+ break;
+#ifdef B460800
+ case B460800: uiPortSpeed = 460800;
+ break;
+#endif
+ }
+
+ return uiPortSpeed;
+}
+
+void uart_close(const serial_port sp)
+{
+ tcsetattr(((serial_port_unix*)sp)->fd,TCSANOW,&((serial_port_unix*)sp)->tiOld);
+ close(((serial_port_unix*)sp)->fd);
+ free(sp);
+}
+
+bool uart_cts(const serial_port sp)
+{
+ char status;
+ if (ioctl(((serial_port_unix*)sp)->fd,TIOCMGET,&status) < 0) return false;
+ return (status & TIOCM_CTS);
+}
+
+bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
+{
+ int res;
+ int byteCount;
+ fd_set rfds;
+ struct timeval tv;
+
+ // Reset the output count
+ *pszRxLen = 0;
+
+ do {
+ // Reset file descriptor
+ FD_ZERO(&rfds);
+ FD_SET(((serial_port_unix*)sp)->fd,&rfds);
+ tv = timeout;
+ res = select(((serial_port_unix*)sp)->fd+1, &rfds, NULL, NULL, &tv);
+
+ // Read error
+ if (res < 0) {
+ DBG("RX error.");
+ return false;
+ }
+
+ // Read time-out
+ if (res == 0) {
+ if (*pszRxLen == 0) {
+ // Error, we received no data
+ DBG("RX time-out, buffer empty.");
+ return false;
+ } else {
+ // We received some data, but nothing more is available
+ return true;
+ }
+ }
+
+ // Retrieve the count of the incoming bytes
+ res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount);
+ if (res < 0) return false;
+
+ // There is something available, read the data
+ res = read(((serial_port_unix*)sp)->fd,pbtRx+(*pszRxLen),byteCount);
+
+ // Stop if the OS has some troubles reading the data
+ if (res <= 0) return false;
+
+ *pszRxLen += res;
+
+ } while (byteCount);
+
+ return true;
+}
+
+bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
+{
+ int32_t res;
+ size_t szPos = 0;
+ fd_set rfds;
+ struct timeval tv;
+
+ while (szPos < szTxLen)
+ {
+ // Reset file descriptor
+ FD_ZERO(&rfds);
+ FD_SET(((serial_port_unix*)sp)->fd,&rfds);
+ tv = timeout;
+ res = select(((serial_port_unix*)sp)->fd+1, NULL, &rfds, NULL, &tv);
+
+ // Write error
+ if (res < 0) {
+ DBG("TX error.");
+ return false;
+ }
+
+ // Write time-out
+ if (res == 0) {
+ DBG("TX time-out.");
+ return false;
+ }
+
+ // Send away the bytes
+ res = write(((serial_port_unix*)sp)->fd,pbtTx+szPos,szTxLen-szPos);
+
+ // Stop if the OS has some troubles sending the data
+ if (res <= 0) return false;
+
+ szPos += res;
+ }
+ return true;
+}
+
+#else
+// The windows serial port implementation
+
+typedef struct {
+ HANDLE hPort; // Serial port handle
+ DCB dcb; // Device control settings
+ COMMTIMEOUTS ct; // Serial port time-out configuration
+} serial_port_windows;
+
+void upcase(char *p) {
+ while(*p != '\0') {
+ if(*p >= 97 && *p <= 122) {
+ *p -= 32;
+ }
+ ++p;
+ }
+}
+
+serial_port uart_open(const char* pcPortName)
+{
+ char acPortName[255];
+ serial_port_windows* sp = malloc(sizeof(serial_port_windows));
+
+ // Copy the input "com?" to "\\.\COM?" format
+ sprintf(acPortName,"\\\\.\\%s",pcPortName);
+ upcase(acPortName);
+
+ // Try to open the serial port
+ sp->hPort = CreateFileA(acPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
+ if (sp->hPort == INVALID_HANDLE_VALUE)
+ {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ // Prepare the device control
+ 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;
+ }
+
+ // Update the active serial port
+ if(!SetCommState(sp->hPort,&sp->dcb))
+ {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ sp->ct.ReadIntervalTimeout = 0;
+ sp->ct.ReadTotalTimeoutMultiplier = 0;
+ sp->ct.ReadTotalTimeoutConstant = 30;
+ sp->ct.WriteTotalTimeoutMultiplier = 0;
+ sp->ct.WriteTotalTimeoutConstant = 30;
+
+ if(!SetCommTimeouts(sp->hPort,&sp->ct))
+ {
+ uart_close(sp);
+ return INVALID_SERIAL_PORT;
+ }
+
+ PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
+
+ return sp;
+}
+
+void uart_close(const serial_port sp)
+{
+ CloseHandle(((serial_port_windows*)sp)->hPort);
+ free(sp);
+}
+
+void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
+{
+ serial_port_windows* spw;
+
+ DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
+ // Set port speed (Input and Output)
+ switch(uiPortSpeed) {
+ case 9600:
+ case 19200:
+ case 38400:
+ case 57600:
+ case 115200:
+ case 230400:
+ case 460800:
+ break;
+ default:
+ ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed);
+ };
+
+ spw = (serial_port_windows*)sp;
+ spw->dcb.BaudRate = uiPortSpeed;
+ if (!SetCommState(spw->hPort, &spw->dcb))
+ {
+ ERR("Unable to apply new speed settings.");
+ }
+}
+
+uint32_t uart_get_speed(const serial_port sp)
+{
+ const serial_port_windows* spw = (serial_port_windows*)sp;
+ if (!GetCommState(spw->hPort, (serial_port)&spw->dcb))
+ return spw->dcb.BaudRate;
+
+ return 0;
+}
+
+bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
+{
+ ReadFile(((serial_port_windows*)sp)->hPort,pbtRx,*pszRxLen,(LPDWORD)pszRxLen,NULL);
+ return (*pszRxLen != 0);
+}
+
+bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
+{
+ DWORD dwTxLen = 0;
+ return WriteFile(((serial_port_windows*)sp)->hPort,pbtTx,szTxLen,&dwTxLen,NULL);
+ return (dwTxLen != 0);
+}
+
+#endif
--- /dev/null
+/*
+ * Proxmark3 generic uart / rs232/ serial port library
+ *
+ * Copyright (c) 2012, Roel Verdult
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the copyright holders nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @file uart.h
+ * @brief
+ *
+ */
+
+#ifndef _PROXMARK3_RS232_H_
+#define _PROXMARK3_RS232_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <stdint.h>
+#include <stdbool.h>
+
+typedef unsigned char byte_t;
+
+// Handle platform specific includes
+#ifndef _WIN32
+ #include <termios.h>
+ #include <sys/ioctl.h>
+ #include <unistd.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <limits.h>
+ #include <sys/time.h>
+#else
+ #include <windows.h>
+#endif
+
+// Define shortcut to types to make code more readable
+typedef void* serial_port;
+#define INVALID_SERIAL_PORT (void*)(~1)
+#define CLAIMED_SERIAL_PORT (void*)(~2)
+
+serial_port uart_open(const char* pcPortName);
+void uart_close(const serial_port sp);
+
+void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
+uint32_t uart_get_speed(const serial_port sp);
+
+bool uart_receive(const serial_port sp, byte_t* pbtRx, size_t* pszRxLen);
+bool uart_send(const serial_port sp, const byte_t* pbtTx, const size_t szTxLen);
+
+#endif // _PROXMARK3_RS232_H_
+
+
#include "util.h"
-#ifndef WIN32
+#ifndef _WIN32
#include <termios.h>
#include <sys/ioctl.h>
int ukbhit(void)
#include <ctype.h>
#include <time.h>
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+
int ukbhit(void);
void AddLogLine(char *fileName, char *extData, char *c);
INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES)
-CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=gnu99 $(APP_CFLAGS)
+CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS) -Os
LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n
LIBS = -lgcc
--- /dev/null
+/*\r
+ * Proxmark send and receive commands\r
+ *\r
+ * Copyright (c) 2012, Roel Verdult\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the copyright holders nor the\r
+ * names of its contributors may be used to endorse or promote products\r
+ * derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY\r
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * @file cmd.c\r
+ * @brief\r
+ */\r
+\r
+#include "cmd.h"\r
+#include "string.h"\r
+#include "proxmark3.h"\r
+\r
+//static UsbCommand txcmd;\r
+\r
+bool cmd_receive(UsbCommand* cmd) {\r
+ \r
+ // Check if there is a usb packet available\r
+ if (!usb_poll()) return false;\r
+ \r
+ // Try to retrieve the available command frame\r
+ size_t rxlen = usb_read((byte_t*)cmd,sizeof(UsbCommand));\r
+\r
+ // Check if the transfer was complete\r
+ if (rxlen != sizeof(UsbCommand)) return false;\r
+ \r
+ // Received command successfully\r
+ return true;\r
+}\r
+\r
+bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len) {\r
+ UsbCommand txcmd;\r
+\r
+ for (size_t i=0; i<sizeof(UsbCommand); i++) {\r
+ ((byte_t*)&txcmd)[i] = 0x00;\r
+ }\r
+ \r
+ // Compose the outgoing command frame\r
+ txcmd.cmd = cmd;\r
+ txcmd.arg[0] = arg0;\r
+ txcmd.arg[1] = arg1; \r
+ txcmd.arg[2] = arg2;\r
+\r
+ // Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE\r
+ if (data && len) {\r
+ len = MIN(len,USB_CMD_DATA_SIZE);\r
+ for (size_t i=0; i<len; i++) {\r
+ txcmd.d.asBytes[i] = ((byte_t*)data)[i];\r
+ }\r
+ }\r
+ \r
+ // Send frame and make sure all bytes are transmitted\r
+ if (usb_write((byte_t*)&txcmd,sizeof(UsbCommand)) != 0) return false;\r
+ \r
+ return true;\r
+}\r
+\r
+\r
--- /dev/null
+/*\r
+ * Proxmark send and receive commands\r
+ *\r
+ * Copyright (c) 2010, Roel Verdult\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the copyright holders nor the\r
+ * names of its contributors may be used to endorse or promote products\r
+ * derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY\r
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * @file cmd.h\r
+ * @brief\r
+ */\r
+\r
+#ifndef _PROXMARK_CMD_H_\r
+#define _PROXMARK_CMD_H_\r
+\r
+#include <common.h>\r
+#include <usb_cmd.h>\r
+#include "usb_cdc.h"\r
+\r
+bool cmd_receive(UsbCommand* cmd);\r
+bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);\r
+\r
+#endif // _PROXMARK_CMD_H_\r
+\r
+++ /dev/null
-//-----------------------------------------------------------------------------
-// Jonathan Westhues, split Aug 14 2005
-//
-// 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.
-//-----------------------------------------------------------------------------
-// The common USB driver used for both the bootloader and the application.
-//-----------------------------------------------------------------------------
-
-#include "proxmark3.h"
-
-#define min(a, b) (((a) > (b)) ? (b) : (a))
-
-#define USB_REPORT_PACKET_SIZE 64
-
-typedef struct PACKED {
- uint8_t bmRequestType;
- uint8_t bRequest;
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
-} UsbSetupData;
-
-#define USB_REQUEST_GET_STATUS 0
-#define USB_REQUEST_CLEAR_FEATURE 1
-#define USB_REQUEST_SET_FEATURE 3
-#define USB_REQUEST_SET_ADDRESS 5
-#define USB_REQUEST_GET_DESCRIPTOR 6
-#define USB_REQUEST_SET_DESCRIPTOR 7
-#define USB_REQUEST_GET_CONFIGURATION 8
-#define USB_REQUEST_SET_CONFIGURATION 9
-#define USB_REQUEST_GET_INTERFACE 10
-#define USB_REQUEST_SET_INTERFACE 11
-#define USB_REQUEST_SYNC_FRAME 12
-
-#define USB_DESCRIPTOR_TYPE_DEVICE 1
-#define USB_DESCRIPTOR_TYPE_CONFIGURATION 2
-#define USB_DESCRIPTOR_TYPE_STRING 3
-#define USB_DESCRIPTOR_TYPE_INTERFACE 4
-#define USB_DESCRIPTOR_TYPE_ENDPOINT 5
-#define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER 6
-#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONF 7
-#define USB_DESCRIPTOR_TYPE_INTERFACE_POWER 8
-#define USB_DESCRIPTOR_TYPE_HID 0x21
-#define USB_DESCRIPTOR_TYPE_HID_REPORT 0x22
-
-#define USB_DEVICE_CLASS_HID 0x03
-
-static const uint8_t HidReportDescriptor[] = {
- 0x06,0xA0,0xFF, // Usage Page (vendor defined) FFA0
- 0x09,0x01, // Usage (vendor defined)
- 0xA1,0x01, // Collection (Application)
- 0x09,0x02, // Usage (vendor defined)
- 0xA1,0x00, // Collection (Physical)
- 0x06,0xA1,0xFF, // Usage Page (vendor defined)
-
- //The,input report
- 0x09,0x03, // usage - vendor defined
- 0x09,0x04, // usage - vendor defined
- 0x15,0x80, // Logical Minimum (-128)
- 0x25,0x7F, // Logical Maximum (127)
- 0x35,0x00, // Physical Minimum (0)
- 0x45,0xFF, // Physical Maximum (255)
- 0x75,0x08, // Report Size (8) (bits)
- 0x95,0x40, // Report Count (64) (fields)
- 0x81,0x02, // Input (Data,Variable,Absolute)
-
- //The,output report
- 0x09,0x05, // usage - vendor defined
- 0x09,0x06, // usage - vendor defined
- 0x15,0x80, // Logical Minimum (-128)
- 0x25,0x7F, // Logical Maximum (127)
- 0x35,0x00, // Physical Minimum (0)
- 0x45,0xFF, // Physical Maximum (255)
- 0x75,0x08, // Report Size (8) (bits)
- 0x95,0x40, // Report Count (64) (fields)
- 0x91,0x02, // Output (Data,Variable,Absolute)
-
- 0xC0, // End Collection
-
- 0xC0, // End Collection
-};
-
-static const uint8_t DeviceDescriptor[] = {
- 0x12, // Descriptor length (18 bytes)
- 0x01, // Descriptor type (Device)
- 0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10)
- 0x00, // Class code (0)
- 0x00, // Subclass code (0)
- 0x00, // Protocol (No specific protocol)
- 0x08, // Maximum packet size for Endpoint 0 (8 bytes)
- 0xc4,0x9a, // Vendor ID (random numbers)
- 0x8f,0x4b, // Product ID (random numbers)
- 0x01,0x00, // Device release number (0001)
- 0x01, // Manufacturer string descriptor index
- 0x02, // Product string descriptor index
- 0x03, // Serial Number string descriptor index
- 0x01, // Number of possible configurations (1)
-};
-
-static const uint8_t ConfigurationDescriptor[] = {
- 0x09, // Descriptor length (9 bytes)
- 0x02, // Descriptor type (Configuration)
- 0x29,0x00, // Total data length (41 bytes)
- 0x01, // Interface supported (1)
- 0x01, // Configuration value (1)
- 0x00, // Index of string descriptor (None)
- 0x80, // Configuration (Bus powered)
- 250, // Maximum power consumption (500mA)
-
- //interface
- 0x09, // Descriptor length (9 bytes)
- 0x04, // Descriptor type (Interface)
- 0x00, // Number of interface (0)
- 0x00, // Alternate setting (0)
- 0x02, // Number of interface endpoint (2)
- 0x03, // Class code (HID)
- 0x00, // Subclass code ()
- 0x00, // Protocol code ()
- 0x00, // Index of string()
-
- // class
- 0x09, // Descriptor length (9 bytes)
- 0x21, // Descriptor type (HID)
- 0x00,0x01, // HID class release number (1.00)
- 0x00, // Localized country code (None)
- 0x01, // # of HID class dscrptr to follow (1)
- 0x22, // Report descriptor type (HID)
- // Total length of report descriptor
- sizeof(HidReportDescriptor),0x00,
-
- // endpoint 1
- 0x07, // Descriptor length (7 bytes)
- 0x05, // Descriptor type (Endpoint)
- 0x01, // Encoded address (Respond to OUT)
- 0x03, // Endpoint attribute (Interrupt transfer)
- 0x08,0x00, // Maximum packet size (8 bytes)
- 0x01, // Polling interval (1 ms)
-
- // endpoint 2
- 0x07, // Descriptor length (7 bytes)
- 0x05, // Descriptor type (Endpoint)
- 0x82, // Encoded address (Respond to IN)
- 0x03, // Endpoint attribute (Interrupt transfer)
- 0x08,0x00, // Maximum packet size (8 bytes)
- 0x01, // Polling interval (1 ms)
-};
-
-static const uint8_t StringDescriptor0[] = {
- 0x04, // Length
- 0x03, // Type is string
- 0x09, // English
- 0x04, // US
-};
-
-static const uint8_t StringDescriptor1[] = {
- 24, // Length
- 0x03, // Type is string
- 'J', 0x00,
- '.', 0x00,
- ' ', 0x00,
- 'W', 0x00,
- 'e', 0x00,
- 's', 0x00,
- 't', 0x00,
- 'h', 0x00,
- 'u', 0x00,
- 'e', 0x00,
- 's', 0x00,
-};
-
-static const uint8_t StringDescriptor2[] = {
- 54, // Length
- 0x03, // Type is string
- 'P', 0x00,
- 'r', 0x00,
- 'o', 0x00,
- 'x', 0x00,
- 'M', 0x00,
- 'a', 0x00,
- 'r', 0x00,
- 'k', 0x00,
- '-', 0x00,
- '3', 0x00,
- ' ', 0x00,
- 'R', 0x00,
- 'F', 0x00,
- 'I', 0x00,
- 'D', 0x00,
- ' ', 0x00,
- 'I', 0x00,
- 'n', 0x00,
- 's', 0x00,
- 't', 0x00,
- 'r', 0x00,
- 'u', 0x00,
- 'm', 0x00,
- 'e', 0x00,
- 'n', 0x00,
- 't', 0x00,
-};
-
-// Serial Number
-// TODO: Pick yours! Don't forget to modify the length, if needed.
-static const uint8_t StringDescriptor3[] = {
- 18, // Length
- 0x03, // Type is string
- 'C', 0x00,
- 'h', 0x00,
- 'a', 0x00,
- 'n', 0x00,
- 'g', 0x00,
- 'e', 0x00,
- 'M', 0x00,
- 'e', 0x00,
-};
-
-static const uint8_t * const StringDescriptors[] = {
- StringDescriptor0,
- StringDescriptor1,
- StringDescriptor2,
- StringDescriptor3,
-};
-
-
-static uint8_t UsbBuffer[64];
-static int UsbSoFarCount;
-
-static uint8_t CurrentConfiguration;
-
-static void UsbSendEp0(const uint8_t *data, int len)
-{
- int thisTime, i;
-
- do {
- thisTime = min(len, 8);
- len -= thisTime;
-
- for(i = 0; i < thisTime; i++) {
- AT91C_BASE_UDP->UDP_FDR[0] = *data;
- data++;
- }
-
- if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
- ;
- }
-
- AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
-
- do {
- if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) {
- // This means that the host is trying to write to us, so
- // abandon our write to them.
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RX_DATA_BK0;
- return;
- }
- } while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP));
- } while(len > 0);
-
- if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
- ;
- }
-}
-
-static void UsbSendZeroLength(void)
-{
- AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
-
- while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP))
- ;
-
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
-
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
- ;
-}
-
-static void UsbSendStall(void)
-{
- AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;
-
- while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT))
- ;
-
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_STALLSENT;
-
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT)
- ;
-}
-
-static void HandleRxdSetupData(void)
-{
- int i;
- UsbSetupData usd;
-
- for(i = 0; i < sizeof(usd); i++) {
- ((uint8_t *)&usd)[i] = AT91C_BASE_UDP->UDP_FDR[0];
- }
-
- if(usd.bmRequestType & 0x80) {
- AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_DIR;
- while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_DIR))
- ;
- }
-
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)
- ;
-
- switch(usd.bRequest) {
- case USB_REQUEST_GET_DESCRIPTOR:
- if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_DEVICE) {
- UsbSendEp0((uint8_t *)&DeviceDescriptor,
- min(sizeof(DeviceDescriptor), usd.wLength));
- } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_CONFIGURATION) {
- UsbSendEp0((uint8_t *)&ConfigurationDescriptor,
- min(sizeof(ConfigurationDescriptor), usd.wLength));
- } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_STRING) {
- const uint8_t *s = StringDescriptors[usd.wValue & 0xff];
- UsbSendEp0(s, min(s[0], usd.wLength));
- } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_HID_REPORT) {
- UsbSendEp0((uint8_t *)&HidReportDescriptor,
- min(sizeof(HidReportDescriptor), usd.wLength));
- } else {
- *((uint32_t *)0x00200000) = usd.wValue;
- }
- break;
-
- case USB_REQUEST_SET_ADDRESS:
- UsbSendZeroLength();
- AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN | usd.wValue ;
- if(usd.wValue != 0) {
- AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
- } else {
- AT91C_BASE_UDP->UDP_GLBSTATE = 0;
- }
- break;
-
- case USB_REQUEST_GET_CONFIGURATION:
- UsbSendEp0(&CurrentConfiguration, sizeof(CurrentConfiguration));
- break;
-
- case USB_REQUEST_GET_STATUS: {
- if(usd.bmRequestType & 0x80) {
- uint16_t w = 0;
- UsbSendEp0((uint8_t *)&w, sizeof(w));
- }
- break;
- }
- case USB_REQUEST_SET_CONFIGURATION:
- CurrentConfiguration = usd.wValue;
- if(CurrentConfiguration) {
- AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_CONFG;
- AT91C_BASE_UDP->UDP_CSR[1] = AT91C_UDP_EPEDS |
- AT91C_UDP_EPTYPE_INT_OUT;
- AT91C_BASE_UDP->UDP_CSR[2] = AT91C_UDP_EPEDS |
- AT91C_UDP_EPTYPE_INT_IN;
- } else {
- AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
- AT91C_BASE_UDP->UDP_CSR[1] = 0;
- AT91C_BASE_UDP->UDP_CSR[2] = 0;
- }
- UsbSendZeroLength();
- break;
-
- case USB_REQUEST_GET_INTERFACE: {
- uint8_t b = 0;
- UsbSendEp0(&b, sizeof(b));
- break;
- }
-
- case USB_REQUEST_SET_INTERFACE:
- UsbSendZeroLength();
- break;
-
- case USB_REQUEST_CLEAR_FEATURE:
- case USB_REQUEST_SET_FEATURE:
- UsbSendStall();
- break;
- case USB_REQUEST_SET_DESCRIPTOR:
- case USB_REQUEST_SYNC_FRAME:
- default:
- break;
- }
-}
-
-void UsbSendPacket(uint8_t *packet, int len)
-{
- int i, thisTime;
-
- while(len > 0) {
- thisTime = min(len, 8);
-
- for(i = 0; i < thisTime; i++) {
- AT91C_BASE_UDP->UDP_FDR[2] = packet[i];
- }
- AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
-
- while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)) {
- WDT_HIT();
- }
-
- AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
-
- while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) {
- WDT_HIT();
- }
-
- len -= thisTime;
- packet += thisTime;
- }
-}
-
-static void HandleRxdData(void)
-{
- int i, len;
-
- if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) {
- len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]);
-
- for(i = 0; i < len; i++) {
- UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1];
- UsbSoFarCount++;
- }
-
- AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK0;
- while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) {
- WDT_HIT();
- }
-
- if(UsbSoFarCount >= 64) {
- UsbPacketReceived(UsbBuffer, UsbSoFarCount);
- UsbSoFarCount = 0;
- }
- }
-
- if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) {
- len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]);
-
- for(i = 0; i < len; i++) {
- UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1];
- UsbSoFarCount++;
- }
-
- AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK1;
- while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) {
- WDT_HIT();
- }
-
- if(UsbSoFarCount >= 64) {
- UsbPacketReceived(UsbBuffer, UsbSoFarCount);
- UsbSoFarCount = 0;
- }
- }
-
- WDT_HIT();
-}
-
-void UsbStart(void)
-{
- volatile int i;
-
- UsbSoFarCount = 0;
-
- USB_D_PLUS_PULLUP_OFF();
-
- for(i = 0; i < 1000000; i++)
- ;
-
- USB_D_PLUS_PULLUP_ON();
-
- if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {
- AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
- }
-}
-
-int UsbConnected()
-{
- if (AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_CONFG)
- return TRUE;
- else
- return FALSE;
-}
-
-int UsbPoll(int blinkLeds)
-{
- int ret = FALSE;
-
- if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {
- AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
-
- // following a reset we should be ready to receive a setup packet
- AT91C_BASE_UDP->UDP_RSTEP = 0xf;
- AT91C_BASE_UDP->UDP_RSTEP = 0;
-
- AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN;
-
- AT91C_BASE_UDP->UDP_CSR[0] = AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS;
-
- CurrentConfiguration = 0;
-
- ret = TRUE;
- }
-
- if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(0)) {
- if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP) {
- HandleRxdSetupData();
- ret = TRUE;
- }
- }
-
- if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(1)) {
- HandleRxdData();
- ret = TRUE;
- }
-
- return ret;
-}
--- /dev/null
+/*\r
+ * at91sam7s USB CDC device implementation\r
+ *\r
+ * Copyright (c) 2012, Roel Verdult\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the copyright holders nor the\r
+ * names of its contributors may be used to endorse or promote products\r
+ * derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY\r
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * based on the "Basic USB Example" from ATMEL (doc6123.pdf)\r
+ *\r
+ * @file usb_cdc.c\r
+ * @brief\r
+ */\r
+\r
+#include "usb_cdc.h"\r
+#include "config_gpio.h"\r
+\r
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))\r
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))\r
+#define AT91C_EP_IN_SIZE 0x40\r
+#define AT91C_EP_OUT 1\r
+#define AT91C_EP_OUT_SIZE 0x40\r
+#define AT91C_EP_IN 2\r
+\r
+const char devDescriptor[] = {\r
+ /* Device descriptor */\r
+ 0x12, // bLength\r
+ 0x01, // bDescriptorType\r
+ 0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10)\r
+ 0x02, // bDeviceClass: CDC class code\r
+ 0x00, // bDeviceSubclass: CDC class sub code\r
+ 0x00, // bDeviceProtocol: CDC Device protocol\r
+ 0x08, // bMaxPacketSize0\r
+ 0x2d,0x2d, // Vendor ID (--)\r
+ 0x4d,0x50, // Product ID (PM), transmitted in reverse\r
+ 0x01,0x00, // Device release number (0001)\r
+ 0x01, // iManufacturer // 0x01\r
+ 0x00, // iProduct\r
+ 0x00, // SerialNumber\r
+ 0x01 // bNumConfigs\r
+};\r
+\r
+const char cfgDescriptor[] = {\r
+ /* ============== CONFIGURATION 1 =========== */\r
+ /* Configuration 1 descriptor */\r
+ 0x09, // CbLength\r
+ 0x02, // CbDescriptorType\r
+ 0x43, // CwTotalLength 2 EP + Control\r
+ 0x00,\r
+ 0x02, // CbNumInterfaces\r
+ 0x01, // CbConfigurationValue\r
+ 0x00, // CiConfiguration\r
+ 0xC0, // CbmAttributes 0xA0\r
+ 0x00, // CMaxPower\r
+\r
+ /* Communication Class Interface Descriptor Requirement */\r
+ 0x09, // bLength\r
+ 0x04, // bDescriptorType\r
+ 0x00, // bInterfaceNumber\r
+ 0x00, // bAlternateSetting\r
+ 0x01, // bNumEndpoints\r
+ 0x02, // bInterfaceClass\r
+ 0x02, // bInterfaceSubclass\r
+ 0x00, // bInterfaceProtocol\r
+ 0x00, // iInterface\r
+\r
+ /* Header Functional Descriptor */\r
+ 0x05, // bFunction Length\r
+ 0x24, // bDescriptor type: CS_INTERFACE\r
+ 0x00, // bDescriptor subtype: Header Func Desc\r
+ 0x10, // bcdCDC:1.1\r
+ 0x01,\r
+\r
+ /* ACM Functional Descriptor */\r
+ 0x04, // bFunctionLength\r
+ 0x24, // bDescriptor Type: CS_INTERFACE\r
+ 0x02, // bDescriptor Subtype: ACM Func Desc\r
+ 0x00, // bmCapabilities\r
+\r
+ /* Union Functional Descriptor */\r
+ 0x05, // bFunctionLength\r
+ 0x24, // bDescriptorType: CS_INTERFACE\r
+ 0x06, // bDescriptor Subtype: Union Func Desc\r
+ 0x00, // bMasterInterface: Communication Class Interface\r
+ 0x01, // bSlaveInterface0: Data Class Interface\r
+\r
+ /* Call Management Functional Descriptor */\r
+ 0x05, // bFunctionLength\r
+ 0x24, // bDescriptor Type: CS_INTERFACE\r
+ 0x01, // bDescriptor Subtype: Call Management Func Desc\r
+ 0x00, // bmCapabilities: D1 + D0\r
+ 0x01, // bDataInterface: Data Class Interface 1\r
+\r
+ /* Endpoint 1 descriptor */\r
+ 0x07, // bLength\r
+ 0x05, // bDescriptorType\r
+ 0x83, // bEndpointAddress, Endpoint 03 - IN\r
+ 0x03, // bmAttributes INT\r
+ 0x08, // wMaxPacketSize\r
+ 0x00,\r
+ 0xFF, // bInterval\r
+\r
+ /* Data Class Interface Descriptor Requirement */\r
+ 0x09, // bLength\r
+ 0x04, // bDescriptorType\r
+ 0x01, // bInterfaceNumber\r
+ 0x00, // bAlternateSetting\r
+ 0x02, // bNumEndpoints\r
+ 0x0A, // bInterfaceClass\r
+ 0x00, // bInterfaceSubclass\r
+ 0x00, // bInterfaceProtocol\r
+ 0x00, // iInterface\r
+\r
+ /* First alternate setting */\r
+ /* Endpoint 1 descriptor */\r
+ 0x07, // bLength\r
+ 0x05, // bDescriptorType\r
+ 0x01, // bEndpointAddress, Endpoint 01 - OUT\r
+ 0x02, // bmAttributes BULK\r
+ AT91C_EP_OUT_SIZE, // wMaxPacketSize\r
+ 0x00,\r
+ 0x00, // bInterval\r
+\r
+ /* Endpoint 2 descriptor */\r
+ 0x07, // bLength\r
+ 0x05, // bDescriptorType\r
+ 0x82, // bEndpointAddress, Endpoint 02 - IN\r
+ 0x02, // bmAttributes BULK\r
+ AT91C_EP_IN_SIZE, // wMaxPacketSize\r
+ 0x00,\r
+ 0x00 // bInterval\r
+};\r
+\r
+const char strDescriptor[] = {\r
+ 26, // Length\r
+ 0x03, // Type is string\r
+ 'p', 0x00,\r
+ 'r', 0x00,\r
+ 'o', 0x00,\r
+ 'x', 0x00,\r
+ 'm', 0x00,\r
+ 'a', 0x00,\r
+ 'r', 0x00,\r
+ 'k', 0x00,\r
+ '.', 0x00,\r
+ 'o', 0x00,\r
+ 'r', 0x00,\r
+ 'g', 0x00,\r
+};\r
+\r
+\r
+/* USB standard request code */\r
+#define STD_GET_STATUS_ZERO 0x0080\r
+#define STD_GET_STATUS_INTERFACE 0x0081\r
+#define STD_GET_STATUS_ENDPOINT 0x0082\r
+\r
+#define STD_CLEAR_FEATURE_ZERO 0x0100\r
+#define STD_CLEAR_FEATURE_INTERFACE 0x0101\r
+#define STD_CLEAR_FEATURE_ENDPOINT 0x0102\r
+\r
+#define STD_SET_FEATURE_ZERO 0x0300\r
+#define STD_SET_FEATURE_INTERFACE 0x0301\r
+#define STD_SET_FEATURE_ENDPOINT 0x0302\r
+\r
+#define STD_SET_ADDRESS 0x0500\r
+#define STD_GET_DESCRIPTOR 0x0680\r
+#define STD_SET_DESCRIPTOR 0x0700\r
+#define STD_GET_CONFIGURATION 0x0880\r
+#define STD_SET_CONFIGURATION 0x0900\r
+#define STD_GET_INTERFACE 0x0A81\r
+#define STD_SET_INTERFACE 0x0B01\r
+#define STD_SYNCH_FRAME 0x0C82\r
+\r
+/* CDC Class Specific Request Code */\r
+#define GET_LINE_CODING 0x21A1\r
+#define SET_LINE_CODING 0x2021\r
+#define SET_CONTROL_LINE_STATE 0x2221\r
+\r
+typedef struct {\r
+ unsigned int dwDTERRate;\r
+ char bCharFormat;\r
+ char bParityType;\r
+ char bDataBits;\r
+} AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;\r
+\r
+AT91S_CDC_LINE_CODING line = {\r
+ 115200, // baudrate\r
+ 0, // 1 Stop Bit\r
+ 0, // None Parity\r
+ 8}; // 8 Data bits\r
+\r
+void AT91F_CDC_Enumerate();\r
+\r
+AT91PS_UDP pUdp = AT91C_BASE_UDP;\r
+byte_t btConfiguration = 0;\r
+byte_t btConnection = 0;\r
+byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn usb_disable\r
+//* \brief This function deactivates the USB device\r
+//*----------------------------------------------------------------------------\r
+void usb_disable() {\r
+ // Disconnect the USB device\r
+ AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;\r
+// SpinDelay(100);\r
+ \r
+ // Clear all lingering interrupts\r
+ if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
+ pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
+ }\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn usb_enable\r
+//* \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
+ AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output\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
+// SpinDelay(100);\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
+//* \fn usb_check\r
+//* \brief Test if the device is configured and handle enumeration\r
+//*----------------------------------------------------------------------------\r
+bool usb_check() {\r
+ AT91_REG isr = pUdp->UDP_ISR;\r
+\r
+ if (isr & AT91C_UDP_ENDBUSRES) {\r
+ pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
+ // reset all endpoints\r
+ pUdp->UDP_RSTEP = (unsigned int)-1;\r
+ pUdp->UDP_RSTEP = 0;\r
+ // Enable the function\r
+ pUdp->UDP_FADDR = AT91C_UDP_FEN;\r
+ // Configure endpoint 0\r
+ pUdp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
+ }\r
+ else if (isr & AT91C_UDP_EPINT0) {\r
+ pUdp->UDP_ICR = AT91C_UDP_EPINT0;\r
+ AT91F_CDC_Enumerate();\r
+ }\r
+ return (btConfiguration) ? true : false;\r
+}\r
+\r
+\r
+bool usb_poll()\r
+{\r
+ if (!usb_check()) return false;\r
+ return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn usb_read\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
+ uint32_t packetSize, nbBytesRcv = 0;\r
+ uint32_t time_out = 0;\r
+ \r
+ while (len)\r
+ {\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
+ while(packetSize--)\r
+ data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];\r
+ pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);\r
+ if (bank == AT91C_UDP_RX_DATA_BK0)\r
+ {\r
+ bank = AT91C_UDP_RX_DATA_BK1;\r
+ } else {\r
+ bank = AT91C_UDP_RX_DATA_BK0;\r
+ }\r
+ }\r
+ if (time_out++ == 0x1fff) break;\r
+ }\r
+\r
+ btReceiveBank = bank;\r
+ return nbBytesRcv;\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn usb_write\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
+ uint32_t cpt = 0;\r
+\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
+ length -= cpt;\r
+ while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
+ pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;\r
+\r
+ while (length) {\r
+ // Fill the second bank\r
+ cpt = MIN(length, AT91C_EP_IN_SIZE-1);\r
+ length -= cpt;\r
+ while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\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
+ pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);\r
+ while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\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
+ pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);\r
+ while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\r
+\r
+ return length;\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn AT91F_USB_SendData\r
+//* \brief Send Data through the control endpoint\r
+//*----------------------------------------------------------------------------\r
+unsigned int csrTab[100];\r
+unsigned char csrIdx = 0;\r
+\r
+static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {\r
+ uint32_t cpt = 0;\r
+ AT91_REG csr;\r
+\r
+ do {\r
+ cpt = MIN(length, 8);\r
+ length -= cpt;\r
+\r
+ while (cpt--)\r
+ pUdp->UDP_FDR[0] = *pData++;\r
+\r
+ if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {\r
+ pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
+ while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);\r
+ }\r
+\r
+ pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;\r
+ do {\r
+ csr = pUdp->UDP_CSR[0];\r
+\r
+ // Data IN stage has been stopped by a status OUT\r
+ if (csr & AT91C_UDP_RX_DATA_BK0) {\r
+ pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);\r
+ return;\r
+ }\r
+ } while ( !(csr & AT91C_UDP_TXCOMP) );\r
+\r
+ } while (length);\r
+\r
+ if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {\r
+ pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
+ while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);\r
+ }\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn AT91F_USB_SendZlp\r
+//* \brief Send zero length packet through the control endpoint\r
+//*----------------------------------------------------------------------------\r
+void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {\r
+ pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;\r
+ while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) );\r
+ pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
+ while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn AT91F_USB_SendStall\r
+//* \brief Stall the control endpoint\r
+//*----------------------------------------------------------------------------\r
+void AT91F_USB_SendStall(AT91PS_UDP pUdp) {\r
+ pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;\r
+ while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) );\r
+ pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);\r
+ while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));\r
+}\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn AT91F_CDC_Enumerate\r
+//* \brief This function is a callback invoked when a SETUP packet is received\r
+//*----------------------------------------------------------------------------\r
+void AT91F_CDC_Enumerate() {\r
+ byte_t bmRequestType, bRequest;\r
+ uint16_t wValue, wIndex, wLength, wStatus;\r
+\r
+ if ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) )\r
+ return;\r
+\r
+ bmRequestType = pUdp->UDP_FDR[0];\r
+ bRequest = pUdp->UDP_FDR[0];\r
+ wValue = (pUdp->UDP_FDR[0] & 0xFF);\r
+ wValue |= (pUdp->UDP_FDR[0] << 8);\r
+ wIndex = (pUdp->UDP_FDR[0] & 0xFF);\r
+ wIndex |= (pUdp->UDP_FDR[0] << 8);\r
+ wLength = (pUdp->UDP_FDR[0] & 0xFF);\r
+ wLength |= (pUdp->UDP_FDR[0] << 8);\r
+\r
+ if (bmRequestType & 0x80) {\r
+ pUdp->UDP_CSR[0] |= AT91C_UDP_DIR;\r
+ while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_DIR) );\r
+ }\r
+ pUdp->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;\r
+ while ( (pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) );\r
+\r
+ // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1\r
+ switch ((bRequest << 8) | bmRequestType) {\r
+ case STD_GET_DESCRIPTOR:\r
+ if (wValue == 0x100) // Return Device Descriptor\r
+ AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength));\r
+ else if (wValue == 0x200) // Return Configuration Descriptor\r
+ AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));\r
+ else if ((wValue & 0x300) == 0x300) // Return String Descriptor\r
+ AT91F_USB_SendData(pUdp, strDescriptor, MIN(sizeof(strDescriptor), wLength));\r
+ else\r
+ AT91F_USB_SendStall(pUdp);\r
+ break;\r
+ case STD_SET_ADDRESS:\r
+ AT91F_USB_SendZlp(pUdp);\r
+ pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue);\r
+ pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;\r
+ break;\r
+ case STD_SET_CONFIGURATION:\r
+ btConfiguration = wValue;\r
+ AT91F_USB_SendZlp(pUdp);\r
+ pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;\r
+ pUdp->UDP_CSR[1] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;\r
+ pUdp->UDP_CSR[2] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;\r
+ pUdp->UDP_CSR[3] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;\r
+ break;\r
+ case STD_GET_CONFIGURATION:\r
+ AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));\r
+ break;\r
+ case STD_GET_STATUS_ZERO:\r
+ wStatus = 0;\r
+ AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+ break;\r
+ case STD_GET_STATUS_INTERFACE:\r
+ wStatus = 0;\r
+ AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+ break;\r
+ case STD_GET_STATUS_ENDPOINT:\r
+ wStatus = 0;\r
+ wIndex &= 0x0F;\r
+ if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) {\r
+ wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
+ AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+ }\r
+ else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == 0)) {\r
+ wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
+ AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+ }\r
+ else\r
+ AT91F_USB_SendStall(pUdp);\r
+ break;\r
+ case STD_SET_FEATURE_ZERO:\r
+ AT91F_USB_SendStall(pUdp);\r
+ break;\r
+ case STD_SET_FEATURE_INTERFACE:\r
+ AT91F_USB_SendZlp(pUdp);\r
+ break;\r
+ case STD_SET_FEATURE_ENDPOINT:\r
+ wIndex &= 0x0F;\r
+ if ((wValue == 0) && wIndex && (wIndex <= 3)) {\r
+ pUdp->UDP_CSR[wIndex] = 0;\r
+ AT91F_USB_SendZlp(pUdp);\r
+ }\r
+ else\r
+ AT91F_USB_SendStall(pUdp);\r
+ break;\r
+ case STD_CLEAR_FEATURE_ZERO:\r
+ AT91F_USB_SendStall(pUdp);\r
+ break;\r
+ case STD_CLEAR_FEATURE_INTERFACE:\r
+ AT91F_USB_SendZlp(pUdp);\r
+ break;\r
+ case STD_CLEAR_FEATURE_ENDPOINT:\r
+ wIndex &= 0x0F;\r
+ if ((wValue == 0) && wIndex && (wIndex <= 3)) {\r
+ if (wIndex == 1)\r
+ pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);\r
+ else if (wIndex == 2)\r
+ pUdp->UDP_CSR[2] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);\r
+ else if (wIndex == 3)\r
+ pUdp->UDP_CSR[3] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN);\r
+ AT91F_USB_SendZlp(pUdp);\r
+ }\r
+ else\r
+ AT91F_USB_SendStall(pUdp);\r
+ break;\r
+\r
+ // handle CDC class requests\r
+ case SET_LINE_CODING:\r
+ while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) );\r
+ pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);\r
+ AT91F_USB_SendZlp(pUdp);\r
+ break;\r
+ case GET_LINE_CODING:\r
+ AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));\r
+ break;\r
+ case SET_CONTROL_LINE_STATE:\r
+ btConnection = wValue;\r
+ AT91F_USB_SendZlp(pUdp);\r
+ break;\r
+ default:\r
+ AT91F_USB_SendStall(pUdp);\r
+ break;\r
+ }\r
+}\r
--- /dev/null
+/*\r
+ * at91sam7s USB CDC device implementation\r
+ *\r
+ * Copyright (c) 2012, Roel Verdult\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ * 3. Neither the name of the copyright holders nor the\r
+ * names of its contributors may be used to endorse or promote products\r
+ * derived from this software without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY\r
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY\r
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\r
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * based on the "Basic USB Example" from ATMEL (doc6123.pdf)\r
+ *\r
+ * @file usb_cdc.c\r
+ * @brief\r
+ */\r
+\r
+#ifndef _USB_CDC_H_\r
+#define _USB_CDC_H_\r
+\r
+#include <common.h>\r
+\r
+void usb_disable();\r
+void usb_enable();\r
+bool usb_check();\r
+bool usb_poll();\r
+uint32_t usb_read(byte_t* data, size_t len);\r
+uint32_t usb_write(const byte_t* data, const size_t len);\r
+\r
+#endif // _USB_CDC_H_\r
+\r
--- /dev/null
+[Version]
+Signature="$Windows NT$"
+Class=Ports
+ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider=%ProviderName%
+DriverVer=10/15/2009,1.0.0.0
+
+[MANUFACTURER]
+%ProviderName%=DeviceList, NTx86, NTamd64
+
+[DeviceList.NTx86]
+%DeviceName%=DriverInstall,USB\VID_2d2d&PID_504d
+
+[DeviceList.NTamd64]
+%DeviceName%=DriverInstall,USB\VID_2d2d&PID_504d
+
+[DriverInstall]
+include=mdmcpq.inf
+CopyFiles=FakeModemCopyFileSection
+AddReg=LowerFilterAddReg,SerialPropPageAddReg
+
+[DriverInstall.Services]
+include = mdmcpq.inf
+AddService = usbser, 0x00000002, LowerFilter_Service_Inst
+
+; This adds the serial port property tab to the device properties dialog
+[SerialPropPageAddReg]
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[Strings]
+ProviderName = "proxmark.org"
+DeviceName = "Proxmark3"
#ifndef __COMMON_H
#define __COMMON_H
+#include <stddef.h>
#include <stdint.h>
+#include <stdbool.h>
+#include <at91sam7s512.h>
typedef unsigned char byte_t;
-//-----------------------------------------------------------------------------
-// ISO 14443A
-//-----------------------------------------------------------------------------
-typedef struct {
- uint8_t atqa[2];
- uint8_t sak;
- uint8_t ats_len;
- uint8_t ats[20]; //FIXME: size?
-} __attribute__((__packed__)) iso14a_card_select_t;
-
-typedef enum ISO14A_COMMAND {
- ISO14A_CONNECT = 1,
- ISO14A_NO_DISCONNECT = 2,
- ISO14A_APDU = 4,
- ISO14A_RAW = 8,
- ISO14A_REQUEST_TRIGGER = 0x10,
- ISO14A_APPEND_CRC = 0x20,
- ISO14A_SET_TIMEOUT = 0x40
-} iso14a_command_t;
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
--- /dev/null
+//-----------------------------------------------------------------------------
+// (c) 2012 Roel Verdult
+//
+// 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.
+//-----------------------------------------------------------------------------
+// MIFARE type prototyping
+//-----------------------------------------------------------------------------
+
+#ifndef _MIFARE_H_
+#define _MIFARE_H_
+
+#include "common.h"
+
+//-----------------------------------------------------------------------------
+// ISO 14443A
+//-----------------------------------------------------------------------------
+typedef struct {
+ byte_t uid[10];
+ byte_t uidlen;
+ byte_t atqa[2];
+ byte_t sak;
+ byte_t ats_len;
+ byte_t ats[256];
+} __attribute__((__packed__)) iso14a_card_select_t;
+
+typedef enum ISO14A_COMMAND {
+ ISO14A_CONNECT = 1,
+ ISO14A_NO_DISCONNECT = 2,
+ ISO14A_APDU = 4,
+ ISO14A_RAW = 8,
+ ISO14A_REQUEST_TRIGGER = 0x10,
+ ISO14A_APPEND_CRC = 0x20,
+ ISO14A_SET_TIMEOUT = 0x40
+} iso14a_command_t;
+
+#endif // _MIFARE_H_
//#define PACKED __attribute__((__packed__))
-#define USB_D_PLUS_PULLUP_ON() { \
- HIGH(GPIO_USB_PU); \
- AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; \
- }
-#define USB_D_PLUS_PULLUP_OFF() AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU
-
#define LED_A_ON() HIGH(GPIO_LED_A)
#define LED_A_OFF() LOW(GPIO_LED_A)
#define LED_A_INV() INVBIT(GPIO_LED_A)
#define RELAY_ON() HIGH(GPIO_RELAY)
#define RELAY_OFF() LOW(GPIO_RELAY)
#define BUTTON_PRESS() !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON)
-//--------------------------------
-// USB declarations
-
-void UsbSendPacket(uint8_t *packet, int len);
-int UsbConnected();
-int UsbPoll(int blinkLeds);
-void UsbStart(void);
-
-// This function is provided by the apps/bootrom, and called from UsbPoll
-// if data are available.
-void UsbPacketReceived(uint8_t *packet, int len);
#define VERSION_INFORMATION_MAGIC 0x56334d50
struct version_information {
#define PACKED __attribute__((packed))
#endif
+#define USB_CMD_DATA_SIZE 512
+
typedef struct {
- uint32_t cmd;
- uint32_t arg[3];
- union {
- uint8_t asBytes[48];
- uint32_t asDwords[12];
- } d;
+ uint64_t cmd;
+ uint64_t arg[3];
+ union {
+ uint8_t asBytes[USB_CMD_DATA_SIZE];
+ uint32_t asDwords[USB_CMD_DATA_SIZE/4];
+ } d;
} PACKED UsbCommand;
// For the bootloader
#define CMD_PCF7931_READ 0x0217
#define CMD_EM4X_READ_WORD 0x0218
#define CMD_EM4X_WRITE_WORD 0x0219
-
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
// For the 13.56 MHz tags
CC = gcc
LD = gcc
CFLAGS = -Wall -Winline -O4
-LDFLAGS = -fPIC
+LDFLAGS =
OBJS = crapto1.o crypto1.o
HEADERS =
-EXES = mfkey
+EXES = mfkey64 mfkey32
LIBS =
all: $(OBJS) $(EXES) $(LIBS)
+ 1287: : a1 e4 58 ce 6e ea 41 e0
+ 64: 0: TAG 5c ad f4 39
-./mfkey 9c599b32 82a4166c a1e458ce 6eea41e0 5cadf439
+./mfkey64 9c599b32 82a4166c a1e458ce 6eea41e0 5cadf439
+++ /dev/null
-// Test-file: test2.c
-#include "crapto1.h"
-#include <stdio.h>
-
-int main (int argc, char *argv[]) {
- struct Crypto1State *revstate;
- uint64_t lfsr;
- uint8_t* plfsr = (uint8_t*)&lfsr;
- uint32_t uid; // serial number
- uint32_t nt; // tag challenge
- uint32_t nr_enc; // encrypted reader challenge
- uint32_t ar_enc; // encrypted reader response
- uint32_t at_enc; // encrypted tag response
- uint32_t ks2; // keystream used to encrypt reader response
- uint32_t ks3; // keystream used to encrypt tag response
-
- printf("MIFARE Classic key recovery\n\n");
-
- if (argc < 6) {
- printf(" syntax: %s <uid> <nt> <{nr}> <{ar}> <{at}>\n\n",argv[0]);
- return 1;
- }
-
- sscanf(argv[1],"%x",&uid);
- sscanf(argv[2],"%x",&nt);
- sscanf(argv[3],"%x",&nr_enc);
- sscanf(argv[4],"%x",&ar_enc);
- sscanf(argv[5],"%x",&at_enc);
-
- printf("Recovering key for:\n");
- printf(" uid: %08x\n",uid);
- printf(" nt: %08x\n",nt);
- printf(" {nr}: %08x\n",nr_enc);
- printf(" {ar}: %08x\n",ar_enc);
- printf(" {at}: %08x\n",at_enc);
-
-/*
- uint32_t uid = 0x9c599b32;
- uint32_t tag_challenge = 0x82a4166c;
- uint32_t nr_enc = 0xa1e458ce;
- uint32_t reader_response = 0x6eea41e0;
- uint32_t tag_response = 0x5cadf439;
-*/
- // Generate lfsr succesors of the tag challenge
- printf("\nLFSR succesors of the tag challenge:\n");
- printf(" nt': %08x\n",prng_successor(nt, 64));
- printf(" nt'': %08x\n",prng_successor(nt, 96));
-
- // Extract the keystream from the messages
- printf("\nKeystream used to generate {ar} and {at}:\n");
- ks2 = ar_enc ^ prng_successor(nt, 64);
- ks3 = at_enc ^ prng_successor(nt, 96);
- printf(" ks2: %08x\n",ks2);
- printf(" ks3: %08x\n",ks3);
-
- revstate = lfsr_recovery64(ks2, ks3);
- lfsr_rollback_word(revstate, 0, 0);
- lfsr_rollback_word(revstate, 0, 0);
- lfsr_rollback_word(revstate, nr_enc, 1);
- lfsr_rollback_word(revstate, uid ^ nt, 0);
- crypto1_get_lfsr(revstate, &lfsr);
- printf("\nFound Key: [%02x %02x %02x %02x %02x %02x]\n\n",plfsr[5],plfsr[4],plfsr[3],plfsr[2],plfsr[1],plfsr[0]);
- crypto1_destroy(revstate);
-
- return 0;
-}
--- /dev/null
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#define llx PRIx64
+#define lli PRIi64
+
+// Test-file: test2.c
+#include "crapto1.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (int argc, char *argv[]) {
+ struct Crypto1State *s,*t;
+ uint64_t key; // recovered key
+ uint32_t uid; // serial number
+ uint32_t nt; // tag challenge
+ uint32_t nr0_enc; // first encrypted reader challenge
+ uint32_t ar0_enc; // first encrypted reader response
+ uint32_t nr1_enc; // second encrypted reader challenge
+ uint32_t ar1_enc; // second encrypted reader response
+ uint32_t ks2; // keystream used to encrypt reader response
+
+ printf("MIFARE Classic key recovery - based 32 bits of keystream\n");
+ printf("Recover key from two 32-bit reader authentication answers only!\n\n");
+
+ if (argc < 7) {
+ printf(" syntax: %s <uid> <nt> <{nr_0}> <{ar_0}> <{nr_1}> <{ar_1}>\n\n",argv[0]);
+ return 1;
+ }
+
+ sscanf(argv[1],"%x",&uid);
+ sscanf(argv[2],"%x",&nt);
+ sscanf(argv[3],"%x",&nr0_enc);
+ sscanf(argv[4],"%x",&ar0_enc);
+ sscanf(argv[5],"%x",&nr1_enc);
+ sscanf(argv[6],"%x",&ar1_enc);
+
+ printf("Recovering key for:\n");
+ printf(" uid: %08x\n",uid);
+ printf(" nt: %08x\n",nt);
+ printf(" {nr_0}: %08x\n",nr0_enc);
+ printf(" {ar_0}: %08x\n",ar0_enc);
+ printf(" {nr_1}: %08x\n",nr1_enc);
+ printf(" {ar_1}: %08x\n",ar1_enc);
+
+ // Generate lfsr succesors of the tag challenge
+ printf("\nLFSR succesors of the tag challenge:\n");
+ printf(" nt': %08x\n",prng_successor(nt, 64));
+ printf(" nt'': %08x\n",prng_successor(nt, 96));
+
+ // Extract the keystream from the messages
+ printf("\nKeystream used to generate {ar} and {at}:\n");
+ ks2 = ar0_enc ^ prng_successor(nt, 64);
+ printf(" ks2: %08x\n",ks2);
+
+ s = lfsr_recovery32(ar0_enc ^ prng_successor(nt, 64), 0);
+
+ for(t = s; t->odd | t->even; ++t) {
+ lfsr_rollback_word(t, 0, 0);
+ lfsr_rollback_word(t, nr0_enc, 1);
+ lfsr_rollback_word(t, uid ^ nt, 0);
+ crypto1_get_lfsr(t, &key);
+ crypto1_word(t, uid ^ nt, 0);
+ crypto1_word(t, nr1_enc, 1);
+ if (ar1_enc == (crypto1_word(t, 0, 0) ^ prng_successor(nt, 64))) {
+ printf("\nFound Key: [%012"llx"]\n\n",key);
+ break;
+ }
+ }
+ free(s);
+
+ return 0;
+}
--- /dev/null
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#define llx PRIx64
+#define lli PRIi64
+
+// Test-file: test2.c
+#include "crapto1.h"
+#include <stdio.h>
+
+int main (int argc, char *argv[]) {
+ struct Crypto1State *revstate;
+ uint64_t key; // recovered key
+ uint32_t uid; // serial number
+ uint32_t nt; // tag challenge
+ uint32_t nr_enc; // encrypted reader challenge
+ uint32_t ar_enc; // encrypted reader response
+ uint32_t at_enc; // encrypted tag response
+ uint32_t ks2; // keystream used to encrypt reader response
+ uint32_t ks3; // keystream used to encrypt tag response
+
+ printf("MIFARE Classic key recovery - based 64 bits of keystream\n");
+ printf("Recover key from only one complete authentication!\n\n");
+
+ if (argc < 6) {
+ printf(" syntax: %s <uid> <nt> <{nr}> <{ar}> <{at}>\n\n",argv[0]);
+ return 1;
+ }
+
+ sscanf(argv[1],"%x",&uid);
+ sscanf(argv[2],"%x",&nt);
+ sscanf(argv[3],"%x",&nr_enc);
+ sscanf(argv[4],"%x",&ar_enc);
+ sscanf(argv[5],"%x",&at_enc);
+
+ printf("Recovering key for:\n");
+ printf(" uid: %08x\n",uid);
+ printf(" nt: %08x\n",nt);
+ printf(" {nr}: %08x\n",nr_enc);
+ printf(" {ar}: %08x\n",ar_enc);
+ printf(" {at}: %08x\n",at_enc);
+
+/*
+ uint32_t uid = 0x9c599b32;
+ uint32_t tag_challenge = 0x82a4166c;
+ uint32_t nr_enc = 0xa1e458ce;
+ uint32_t reader_response = 0x6eea41e0;
+ uint32_t tag_response = 0x5cadf439;
+*/
+ // Generate lfsr succesors of the tag challenge
+ printf("\nLFSR succesors of the tag challenge:\n");
+ printf(" nt': %08x\n",prng_successor(nt, 64));
+ printf(" nt'': %08x\n",prng_successor(nt, 96));
+
+ // Extract the keystream from the messages
+ printf("\nKeystream used to generate {ar} and {at}:\n");
+ ks2 = ar_enc ^ prng_successor(nt, 64);
+ ks3 = at_enc ^ prng_successor(nt, 96);
+ printf(" ks2: %08x\n",ks2);
+ printf(" ks3: %08x\n",ks3);
+
+ revstate = lfsr_recovery64(ks2, ks3);
+ lfsr_rollback_word(revstate, 0, 0);
+ lfsr_rollback_word(revstate, 0, 0);
+ lfsr_rollback_word(revstate, nr_enc, 1);
+ lfsr_rollback_word(revstate, uid ^ nt, 0);
+ crypto1_get_lfsr(revstate, &key);
+ printf("\nFound Key: [%012"llx"]\n\n",key);
+ crypto1_destroy(revstate);
+
+ return 0;
+}
#include "crapto1.h"
+#define __STDC_FORMAT_MACROS
#include <inttypes.h>
+#define llx PRIx64
#include <stdio.h>
typedef unsigned char byte_t;
}
sscanf(argv[1],"%08x",&uid);
sscanf(argv[2],"%08x",&nt);
- sscanf(argv[3],"%016llx",&par_info);
- sscanf(argv[4],"%016llx",&ks_info);
+ sscanf(argv[3],"%016"llx,&par_info);
+ sscanf(argv[4],"%016"llx,&ks_info);
// Reset the last three significant bits of the reader nonce
nr &= 0xffffff1f;
- printf("\nuid(%08x) nt(%08x) par(%016llx) ks(%016llx)\n\n",uid,nt,par_info,ks_info);
+ printf("\nuid(%08x) nt(%08x) par(%016"llx") ks(%016"llx")\n\n",uid,nt,par_info,ks_info);
for (pos=0; pos<8; pos++)
{
state = lfsr_common_prefix(nr,rr,ks3x,par);
lfsr_rollback_word(state,uid^nt,0);
crypto1_get_lfsr(state,&key_recovered);
- printf("\nkey recovered: %012llx\n\n",key_recovered);
+ printf("\nkey recovered: %012"llx"\n\n",key_recovered);
crypto1_destroy(state);
return 0;