Finalized migration to new USB CDC interface

This commit is contained in:
roel@libnfc.org 2013-03-07 15:11:00 +00:00
commit 660d641a03
75 changed files with 3168 additions and 2298 deletions

View file

@ -9,6 +9,7 @@
#include "proxmark3.h"
#include "apps.h"
#include "LCD.h"
#include "fonts.h"
void LCDSend(unsigned int data)
{
@ -128,4 +129,25 @@ void LCDInit(void)
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);
}

View file

@ -10,7 +10,7 @@ APP_INCLUDES = apps.h
#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
@ -27,7 +27,8 @@ THUMBSRC = start.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 \

View file

@ -10,6 +10,9 @@
// executes.
//-----------------------------------------------------------------------------
#include "usb_cdc.h"
#include "cmd.h"
#include "proxmark3.h"
#include "apps.h"
#include "util.h"
@ -22,7 +25,6 @@
#include <hitag2.h>
#ifdef WITH_LCD
# include "fonts.h"
#include "LCD.h"
#endif
@ -77,39 +79,42 @@ void ToSendStuffBit(int b)
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
@ -194,7 +199,7 @@ void MeasureAntennaTuning(void)
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...");
@ -237,14 +242,14 @@ void MeasureAntennaTuning(void)
// 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();
@ -383,7 +388,8 @@ void SamyRun()
for (;;)
{
UsbPoll(FALSE);
// UsbPoll(FALSE);
usb_poll();
WDT_HIT();
// Was our button held down or pressed?
@ -613,14 +619,14 @@ void ListenReaderField(int limit)
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);
@ -668,7 +674,8 @@ void UsbPacketReceived(uint8_t *packet, int len)
break;
case CMD_PCF7931_READ: // Read PCF7931 tag
ReadPCF7931();
UsbSendPacket((uint8_t*)&ack, sizeof(ack));
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]);
@ -755,13 +762,13 @@ void UsbPacketReceived(uint8_t *packet, int len)
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:
@ -857,16 +864,26 @@ void UsbPacketReceived(uint8_t *packet, int len)
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));
// 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();
UsbSendPacket((uint8_t *)&n, sizeof(n));
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;
@ -874,7 +891,8 @@ void UsbPacketReceived(uint8_t *packet, int len)
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:
@ -909,7 +927,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
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;
@ -922,17 +940,16 @@ void UsbPacketReceived(uint8_t *packet, int len)
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: {
@ -958,7 +975,9 @@ void __attribute__((noreturn)) AppMain(void)
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;
@ -980,33 +999,21 @@ void __attribute__((noreturn)) AppMain(void)
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

View file

@ -16,6 +16,7 @@
#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.
@ -142,17 +143,17 @@ void RAMFUNC SnoopIso14443(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);
@ -189,6 +190,10 @@ void SnoopHitag(uint32_t type);
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

View file

@ -12,8 +12,8 @@
//-----------------------------------------------------------------------------
#include "iso14443a.h"
#include "epa.h"
#include "cmd.h"
// Protocol and Parameter Selection Request
// use regular (1x) speed in both directions
@ -211,24 +211,25 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
// 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:
@ -244,14 +245,14 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
// 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;
}
@ -264,7 +265,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
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;
}
@ -275,7 +276,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
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;
}
@ -290,17 +291,18 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c, UsbCommand *ack)
// 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;
}
// 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));
// save received information
// 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);
}
//-----------------------------------------------------------------------------

View file

@ -116,13 +116,11 @@ void FpgaSetupSsc(void)
// 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;

View file

@ -27,6 +27,7 @@ static bool bQuiet;
bool bCrypto;
bool bAuthenticating;
bool bPwd;
bool bSuccessful;
struct hitag2_tag {
uint32_t uid;
@ -491,7 +492,7 @@ bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
blocknr++;
if (blocknr > 7) {
DbpString("Read succesful!");
// We are done... for now
bSuccessful = true;
return false;
}
*txlen = 10;
@ -523,11 +524,32 @@ bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
case 0: {
// Stop if there is no answer while we are in crypto mode (after sending NrAr)
if (bCrypto) {
// 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
@ -553,7 +575,7 @@ bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
}
if (blocknr > 7) {
DbpString("Read succesful!");
// We are done... for now
bSuccessful = true;
return false;
}
*txlen = 10;
@ -1075,6 +1097,9 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
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();
@ -1336,7 +1361,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
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);
}

View file

@ -14,6 +14,7 @@
#include "apps.h"
#include "util.h"
#include "string.h"
#include "cmd.h"
#include "iso14443crc.h"
#include "iso14443a.h"
@ -64,16 +65,16 @@ const uint8_t OddByteParity[256] = {
};
void iso14a_set_trigger(int enable) {
void iso14a_set_trigger(bool enable) {
trigger = enable;
}
void iso14a_clear_trace(void) {
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;
}
@ -1132,7 +1133,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
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;
@ -1146,12 +1147,15 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
respdata = response6;
respsize = sizeof(response6);
} else {
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 (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]);
Dbprintf("Received unknown command (len=%d):",len);
Dbhexdump(len,receivedCmd,false);
}
// Do not respond
resp = resp1; respLen = 0; order = 0;
respdata = NULL;
@ -1635,29 +1639,35 @@ int ReaderReceivePar(uint8_t* receivedAnswer, uint32_t * parptr)
/* 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;
// Dbprintf("atqa: %02x %02x",resp[0],resp[1]);
if(resp_data)
memcpy(resp_data->atqa, resp, 2);
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
@ -1670,10 +1680,16 @@ int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, u
// 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);
@ -1683,45 +1699,58 @@ int iso14443a_select_card(uint8_t * uid_ptr, iso14a_card_select_t * resp_data, u
// Receive the SAK
if (!ReaderReceive(resp)) return 0;
sak = resp[0];
}
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;
// 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( (sak & 0x20) == 0)
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(p_hi14a_card) {
p_hi14a_card->sak = sak;
p_hi14a_card->ats_len = 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
// 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);
@ -1729,7 +1758,7 @@ void iso14443a_setup() {
// 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
}
@ -1765,19 +1794,26 @@ int iso14_apdu(uint8_t * cmd, size_t cmd_len, void * data) {
// 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];
if(param & ISO14A_REQUEST_TRIGGER) iso14a_set_trigger(1);
iso14a_clear_trace();
iso14a_set_tracing(true);
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) {
@ -1789,20 +1825,9 @@ void ReaderIso14443a(UsbCommand * c, UsbCommand * ack)
}
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) {
@ -1811,14 +1836,18 @@ void ReaderIso14443a(UsbCommand * c, UsbCommand * ack)
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();
@ -1834,7 +1863,7 @@ void ReaderMifare(uint32_t parameter)
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;
@ -1931,14 +1960,16 @@ void ReaderMifare(uint32_t parameter)
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...

View file

@ -91,10 +91,10 @@ extern int ReaderReceivePar(uint8_t* receivedAnswer, uint32_t * parptr);
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 */

View file

@ -63,7 +63,7 @@
#include "apps.h"
#include "string.h"
#include "iso15693tools.h"
#include "cmd.h"
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
@ -1260,7 +1260,7 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
int recvlen=0;
uint8_t *recvbuf=(uint8_t *)BigBuf;
UsbCommand n;
// UsbCommand n;
if (DEBUG) {
Dbprintf("SEND");
@ -1270,11 +1270,12 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
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) {

View file

@ -805,7 +805,6 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
}
}
/*------------------------------
* T5555/T5557/T5567 routines
*------------------------------
@ -926,7 +925,6 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
// Read one card block in page 0
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
@ -1047,7 +1045,7 @@ void T55xxReadTrace(void){
// 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){
@ -1296,6 +1294,7 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int
}
#define abs(x) ( ((x)<0) ? -(x) : (x) )
#define max(x,y) ( x<y ? y:x)
@ -1698,7 +1697,7 @@ void SendForward(uint8_t fwd_bit_count) {
}
}
void Login (uint32_t Password) {
void EM4xLogin(uint32_t Password) {
uint8_t fwd_bit_count;
@ -1720,7 +1719,7 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
int m=0, i=0;
//If password mode do login
if (PwdMode == 1) Login(Pwd);
if (PwdMode == 1) EM4xLogin(Pwd);
forward_ptr = forwardLink_data;
fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
@ -1757,7 +1756,7 @@ 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);
if (PwdMode == 1) EM4xLogin(Pwd);
forward_ptr = forwardLink_data;
fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE );
@ -1771,4 +1770,3 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}

View file

@ -78,11 +78,12 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
memcpy(ack.d.asBytes, dataoutbuf, 16);
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// memcpy(ack.d.asBytes, dataoutbuf, 16);
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,0,0);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
@ -170,16 +171,17 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,32);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
// SpinDelay(100);
SpinDelay(100);
memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
// memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);
LED_B_OFF();
// Thats it...
@ -256,10 +258,11 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,0,0);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
@ -301,7 +304,6 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
nestedVector nvector[NES_MAX_INFO + 1][11];
int nvectorcount[NES_MAX_INFO + 1];
int ncount = 0;
UsbCommand ack = {CMD_ACK, {0, 0, 0}};
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
@ -468,6 +470,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
// UsbCommand ack = {CMD_ACK, {0, 0, 0}};
for (i = 0; i < NES_MAX_INFO; i++) {
if (nvectorcount[i] > 10) continue;
@ -475,33 +479,37 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
ncount = nvectorcount[i] - j;
if (ncount > 5) ncount = 5;
ack.arg[0] = 0; // isEOF = 0
ack.arg[1] = ncount;
ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);
memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));
// ack.arg[0] = 0; // isEOF = 0
// ack.arg[1] = ncount;
// ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);
// memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));
memcpy(ack.d.asBytes, &cuid, 4);
byte_t buf[48];
memset(buf, 0x00, sizeof(buf));
memcpy(buf, &cuid, 4);
for (m = 0; m < ncount; m++) {
memcpy(ack.d.asBytes + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);
memcpy(ack.d.asBytes + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);
memcpy(buf + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);
memcpy(buf + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);
}
LED_B_ON();
SpinDelay(100);
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
// SpinDelay(100);
cmd_send(CMD_ACK,0,ncount,targetBlockNo + (targetKeyType * 0x100),buf,48);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
}
}
// finalize list
ack.arg[0] = 1; // isEOF = 1
ack.arg[1] = 0;
ack.arg[2] = 0;
memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));
// ack.arg[0] = 1; // isEOF = 1
// ack.arg[1] = 0;
// ack.arg[2] = 0;
// memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));
LED_B_ON();
SpinDelay(300);
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
// SpinDelay(300);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,1,0,0,0,0);
LED_B_OFF();
if (MF_DBGLEVEL >= 4) DbpString("NESTED FINISHED");
@ -575,11 +583,12 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
// Thats it...
@ -612,12 +621,14 @@ void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
}
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};
// UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};
emlGetMem(ack.d.asBytes, arg0, arg1); // data, block num, blocks count
byte_t buf[48];
emlGetMem(buf, arg0, arg1); // data, block num, blocks count
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,arg0,arg1,0,buf,48);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
}
@ -848,15 +859,16 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
break;
}
UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
if (isOK) memcpy(ack.d.asBytes, uid, 4);
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// if (isOK) memcpy(ack.d.asBytes, uid, 4);
// add trace trailer
memset(uid, 0x44, 4);
LogTrace(uid, 4, 0, 0, TRUE);
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,uid,4);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
if ((workFlags & 0x10) || (!isOK)) {
@ -938,15 +950,16 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
break;
}
UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
if (isOK) memcpy(ack.d.asBytes, data, 18);
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
// if (isOK) memcpy(ack.d.asBytes, data, 18);
// add trace trailer
memset(data, 0x44, 4);
LogTrace(data, 4, 0, 0, TRUE);
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,isOK,0,0,data,18);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
if ((workFlags & 0x10) || (!isOK)) {

View file

@ -31,10 +31,11 @@ int MfSniffInit(void){
}
int MfSniffEnd(void){
UsbCommand ack = {CMD_ACK, {0, 0, 0}};
// UsbCommand ack = {CMD_ACK, {0, 0, 0}};
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,0,0,0,0,0);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
return 0;
@ -166,23 +167,25 @@ int intMfSniffSend() {
FpgaDisableSscDma();
while (pckLen > 0) {
pckSize = min(32, pckLen);
UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}};
memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize);
pckSize = MIN(32, pckLen);
// UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}};
// memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize);
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
SpinDelay(20);
cmd_send(CMD_ACK,1,pckSize,pckNum,trace + traceLen - pckLen,pckSize);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
// SpinDelay(20);
LED_B_OFF();
pckLen -= pckSize;
pckNum++;
}
UsbCommand ack = {CMD_ACK, {2, 0, 0}};
// UsbCommand ack = {CMD_ACK, {2, 0, 0}};
LED_B_ON();
UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
cmd_send(CMD_ACK,2,0,0,0,0);
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
LED_B_OFF();
traceLen = 0;

View file

@ -15,9 +15,7 @@
#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

View file

@ -8,15 +8,15 @@
# 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.

View file

@ -7,6 +7,17 @@
//-----------------------------------------------------------------------------
#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;
@ -78,72 +89,86 @@ static void Fatal(void)
for(;;);
}
void UsbPacketReceived(uint8_t *packet, int len)
{
void UsbPacketReceived(uint8_t *packet, int len) {
int i, dont_ack=0;
UsbCommand* c = (UsbCommand *)packet;
volatile uint32_t *p;
if(len != sizeof(*c)) {
if(len != sizeof(UsbCommand)) {
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;
uint32_t arg0 = (uint32_t)c->arg[0];
case CMD_SETUP_WRITE:
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+c->arg[0]] = c->d.asDwords[i];
p[i+arg0] = c->d.asDwords[i];
}
break;
} break;
case CMD_FINISH_WRITE:
p = (volatile uint32_t *)&_flash_start;
for(i = 0; i < 4; i++) {
p[i+60] = c->d.asDwords[i];
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( ((c->arg[0]+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (c->arg[0] < start_addr) ) {
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);
// 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((c->arg[0]-(int)&_flash_start)/AT91C_IFLASH_PAGE_SIZE) |
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))
;
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);
// c->cmd = CMD_NACK;
cmd_send(CMD_NACK,0,0,0,0,0);
// UsbSendPacket(packet, len);
}
break;
}
} break;
case CMD_HARDWARE_RESET:
USB_D_PLUS_PULLUP_OFF();
case CMD_HARDWARE_RESET: {
// USB_D_PLUS_PULLUP_OFF();
usb_disable();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
break;
} break;
case CMD_START_FLASH:
case CMD_START_FLASH: {
if(c->arg[2] == START_FLASH_MAGIC) bootrom_unlocked = 1;
else bootrom_unlocked = 0;
{
@ -164,20 +189,22 @@ void UsbPacketReceived(uint8_t *packet, int len)
} else {
start_addr = end_addr = 0;
dont_ack = 1;
c->cmd = CMD_NACK;
UsbSendPacket(packet, len);
// c->cmd = CMD_NACK;
// UsbSendPacket(packet, len);
cmd_send(CMD_NACK,0,0,0,0,0);
}
}
break;
} break;
default:
default: {
Fatal();
break;
} break;
}
if(!dont_ack) {
c->cmd = CMD_ACK;
UsbSendPacket(packet, len);
// c->cmd = CMD_ACK;
// UsbSendPacket(packet, len);
cmd_send(CMD_ACK,arg0,0,0,0,0);
}
}
@ -186,16 +213,30 @@ 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;
UsbStart();
usb_enable();
for (volatile size_t i=0; i<0x100000; i++);
// 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(;;);
@ -207,7 +248,7 @@ static void flash_mode(int externally_entered)
}
}
extern char _osimage_entry;
extern uint32_t _osimage_entry;
void BootROM(void)
{
//------------
@ -251,7 +292,8 @@ 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();
@ -296,10 +338,10 @@ void BootROM(void)
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 ) );
}
}

View file

@ -1,27 +0,0 @@
//-----------------------------------------------------------------------------
// 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 */

View file

@ -14,7 +14,7 @@ OBJDIR = obj
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
@ -25,7 +25,7 @@ CXXFLAGS = -I/Library/Frameworks/QtGui.framework/Versions/Current/Headers -I/Lib
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
@ -50,6 +50,7 @@ CMDSRCS = \
data.c \
graph.c \
ui.c \
uart.c \
util.c \
cmddata.c \
cmdhf.c \
@ -62,8 +63,8 @@ CMDSRCS = \
cmdhfmf.c \
cmdhw.c \
cmdlf.c \
cmdlfem4x.c \
cmdlfhid.c \
cmdlfem4x.c \
cmdlfhitag.c \
cmdlfti.c \
cmdparser.c \
@ -74,7 +75,7 @@ CMDSRCS = \
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)
@ -83,16 +84,16 @@ all-static: LDLIBS:=-static $(LDLIBS)
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

View file

@ -12,7 +12,8 @@
#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"
@ -158,7 +159,7 @@ int CmdBitsamples(const char *Cmd)
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++) {
@ -418,7 +419,7 @@ int CmdHexsamples(const char *Cmd)
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],
@ -475,7 +476,7 @@ int CmdSamples(const char *Cmd)
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;
}

View file

@ -9,7 +9,8 @@
//-----------------------------------------------------------------------------
#include <stdio.h>
#include "proxusb.h"
//#include "proxusb.h"
#include "proxmark3.h"
#include "graph.h"
#include "ui.h"
#include "cmdparser.h"

View file

@ -16,13 +16,14 @@
#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);
@ -30,6 +31,7 @@ int CmdHF14AList(const char *Cmd)
{
uint8_t got[1920];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
PrintAndLog("recorded activity:");
PrintAndLog(" ETU :rssi: who bytes");
@ -161,54 +163,40 @@ void iso14a_set_timeout(uint32_t timeout) {
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);
UsbCommand resp;
WaitForResponse(CMD_ACK,&resp);
if(resp->arg[0] == 0) {
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 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break;
case 0x04: PrintAndLog("TYPE : 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 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;
@ -325,11 +313,11 @@ int CmdHF14AReader(const char *Cmd)
}
}
}
} else {
PrintAndLog("proprietary non iso14443a-4 card found, RATS not supported");
}
else
PrintAndLog("proprietary non-iso14443a card found, RATS not supported");
return resp->arg[0];
return resp.arg[0];
}
// Collect ISO14443 Type A UIDs
@ -347,12 +335,15 @@ int CmdHF14ACUIDs(const char *Cmd)
// 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
@ -400,7 +391,7 @@ int CmdHF14ASim(const char *Cmd)
// 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;
@ -478,54 +469,6 @@ int CmdHF14ASnoop(const char *Cmd) {
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"},
@ -534,14 +477,12 @@ static command_t CommandTable[] =
{"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);

View file

@ -14,7 +14,8 @@
#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"

View file

@ -26,7 +26,8 @@
#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"
@ -94,7 +95,7 @@ const productName uidmapping[] = {
// 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;
@ -111,11 +112,9 @@ int getUID(uint8_t *buf)
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;
}
@ -292,7 +291,7 @@ int CmdHF15Afi(const char *Cmd)
// 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?
@ -321,20 +320,18 @@ int CmdHF15DumpMem(const char*Cmd) {
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);
@ -346,14 +343,14 @@ int CmdHF15DumpMem(const char*Cmd) {
}
} // 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;
}
@ -392,7 +389,7 @@ int CmdHF15Help(const char *Cmd)
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;
@ -407,15 +404,13 @@ int CmdHF15CmdInquiry(const char *Cmd)
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.");
@ -440,7 +435,7 @@ int CmdHF15CmdDebug( const char *cmd) {
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;
@ -515,14 +510,12 @@ int CmdHF15CmdRaw (const char *cmd) {
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);
@ -635,7 +628,7 @@ int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd[], int iso15cmdle
* 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;
@ -670,14 +663,12 @@ int CmdHF15CmdSysinfo(const char *Cmd) {
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");
@ -725,7 +716,7 @@ int CmdHF15CmdSysinfo(const char *Cmd) {
* 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;
@ -773,18 +764,16 @@ int CmdHF15CmdReadmulti(const char *Cmd) {
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);
@ -806,7 +795,7 @@ int CmdHF15CmdReadmulti(const char *Cmd) {
* 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;
@ -848,19 +837,17 @@ int CmdHF15CmdRead(const char *Cmd) {
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);
@ -883,7 +870,7 @@ int CmdHF15CmdRead(const char *Cmd) {
* 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;
@ -943,11 +930,9 @@ int CmdHF15CmdWrite(const char *Cmd) {
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 {

View file

@ -9,7 +9,8 @@
//-----------------------------------------------------------------------------
#include "util.h"
#include "proxusb.h"
//#include "proxusb.h"
#include "proxmark3.h"
#include "ui.h"
#include "cmdparser.h"
#include "common.h"
@ -24,41 +25,40 @@ static int CmdHelp(const char *Cmd);
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);
@ -88,7 +88,7 @@ int CmdHelp(const char *Cmd)
int CmdHFEPA(const char *Cmd)
{
// flush
while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
WaitForResponseTimeout(CMD_ACK,NULL,100);
// parse
CmdsParse(CommandTable, Cmd);

View file

@ -14,7 +14,8 @@
#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"

View file

@ -10,7 +10,8 @@
#include <stdio.h>
#include <string.h>
#include "proxusb.h"
//#include "proxusb.h"
#include "proxmark3.h"
#include "data.h"
#include "ui.h"
#include "cmdparser.h"
@ -69,7 +70,7 @@ int CmdLegicDecode(const char *Cmd)
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++) {
@ -253,7 +254,7 @@ int CmdLegicLoad(const char *Cmd)
c.d.asBytes[j] = data[j];
}
SendCommand(&c);
WaitForResponse(CMD_ACK);
WaitForResponse(CMD_ACK, NULL);
offset += 8;
}
fclose(f);
@ -292,7 +293,7 @@ int CmdLegicSave(const char *Cmd)
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],
@ -323,7 +324,7 @@ int CmdLegicRfSim(const char *Cmd)
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;
}
@ -331,7 +332,7 @@ int CmdLegicRfSim(const char *Cmd)
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;
@ -343,7 +344,7 @@ int CmdLegicRfWrite(const char *Cmd)
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;
@ -357,7 +358,7 @@ int CmdLegicRfFill(const char *Cmd)
for(i = 0; i < 22; i++) {
c.arg[0] = i*48;
SendCommand(&c);
WaitForResponse(CMD_ACK);
WaitForResponse(CMD_ACK,NULL);
}
SendCommand(&cmd);
return 0;

View file

@ -9,7 +9,6 @@
//-----------------------------------------------------------------------------
#include "cmdhfmf.h"
#include "proxmark3.h"
static int CmdHelp(const char *Cmd);
@ -50,14 +49,14 @@ start:
break;
}
UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
if (resp != NULL) {
isOK = resp->arg[0] & 0xff;
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
isOK = resp.arg[0] & 0xff;
uid = (uint32_t)bytes_to_num(resp->d.asBytes + 0, 4);
nt = (uint32_t)bytes_to_num(resp->d.asBytes + 4, 4);
par_list = bytes_to_num(resp->d.asBytes + 8, 8);
ks_list = bytes_to_num(resp->d.asBytes + 16, 8);
uid = (uint32_t)bytes_to_num(resp.d.asBytes + 0, 4);
nt = (uint32_t)bytes_to_num(resp.d.asBytes + 4, 4);
par_list = bytes_to_num(resp.d.asBytes + 8, 8);
ks_list = bytes_to_num(resp.d.asBytes + 16, 8);
printf("\n\n");
PrintAndLog("isOk:%02x", isOK);
@ -77,13 +76,13 @@ start:
PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt);
} else {
printf("------------------------------------------------------------------\n");
PrintAndLog("Key found:%012I64x \n", r_key);
PrintAndLog("Key found:%012"llx" \n", r_key);
num_to_bytes(r_key, 6, keyBlock);
isOK = mfCheckKeys(0, 0, 1, keyBlock, &r_key);
}
if (!isOK)
PrintAndLog("Found valid key:%012I64x", r_key);
PrintAndLog("Found valid key:%012"llx, r_key);
else
{
if (isOK != 2) PrintAndLog("Found invalid key. ( Nt=%08x ,Trying use it to run again...", nt);
@ -131,11 +130,10 @@ int CmdHF14AMfWrBl(const char *Cmd)
memcpy(c.d.asBytes, key, 6);
memcpy(c.d.asBytes + 10, bldata, 16);
SendCommand(&c);
UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
if (resp != NULL) {
uint8_t isOK = resp->arg[0] & 0xff;
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
@ -175,11 +173,11 @@ int CmdHF14AMfRdBl(const char *Cmd)
UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};
memcpy(c.d.asBytes, key, 6);
SendCommand(&c);
UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
if (resp != NULL) {
uint8_t isOK = resp->arg[0] & 0xff;
uint8_t * data = resp->d.asBytes;
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
uint8_t * data = resp.d.asBytes;
if (isOK)
PrintAndLog("isOk:%02x data:%s", isOK, sprint_hex(data, 16));
@ -230,12 +228,12 @@ int CmdHF14AMfRdSc(const char *Cmd)
UsbCommand c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}};
memcpy(c.d.asBytes, key, 6);
SendCommand(&c);
UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
PrintAndLog(" ");
if (resp != NULL) {
isOK = resp->arg[0] & 0xff;
data = resp->d.asBytes;
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
isOK = resp.arg[0] & 0xff;
data = resp.d.asBytes;
PrintAndLog("isOk:%02x", isOK);
if (isOK)
@ -247,12 +245,10 @@ int CmdHF14AMfRdSc(const char *Cmd)
}
// response2
resp = WaitForResponseTimeout(CMD_ACK, 500);
PrintAndLog(" ");
if (resp != NULL) {
isOK = resp->arg[0] & 0xff;
data = resp->d.asBytes;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
isOK = resp.arg[0] & 0xff;
data = resp.d.asBytes;
if (isOK)
for (i = 0; i < 2; i++) {
@ -276,7 +272,7 @@ int CmdHF14AMfDump(const char *Cmd)
FILE *fin;
FILE *fout;
UsbCommand *resp;
UsbCommand resp;
if ((fin = fopen("dumpkeys.bin","rb")) == NULL) {
PrintAndLog("Could not find file dumpkeys.bin");
@ -307,11 +303,10 @@ int CmdHF14AMfDump(const char *Cmd)
UsbCommand c = {CMD_MIFARE_READBL, {4*i + 3, 0, 0}};
memcpy(c.d.asBytes, keyA[i], 6);
SendCommand(&c);
resp = WaitForResponseTimeout(CMD_ACK, 1500);
if (resp != NULL) {
uint8_t isOK = resp->arg[0] & 0xff;
uint8_t *data = resp->d.asBytes;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
uint8_t *data = resp.d.asBytes;
if (isOK){
rights[i][0] = ((data[7] & 0x10)>>4) | ((data[8] & 0x1)<<1) | ((data[8] & 0x10)>>2);
rights[i][1] = ((data[7] & 0x20)>>5) | ((data[8] & 0x2)<<0) | ((data[8] & 0x20)>>3);
@ -333,20 +328,23 @@ int CmdHF14AMfDump(const char *Cmd)
PrintAndLog("|----- Dumping all blocks to file... -----|");
PrintAndLog("|-----------------------------------------|");
for (i=0 ; i<16 ; i++) {
for (j=0 ; j<4 ; j++) {
bool received = false;
if (j == 3){
UsbCommand c = {CMD_MIFARE_READBL, {i*4 + j, 0, 0}};
memcpy(c.d.asBytes, keyA[i], 6);
SendCommand(&c);
resp = WaitForResponseTimeout(CMD_ACK, 1500);
received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
}
else{
if ((rights[i][j] == 6) | (rights[i][j] == 5)) {
UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 1, 0}};
memcpy(c.d.asBytes, keyB[i], 6);
SendCommand(&c);
resp = WaitForResponseTimeout(CMD_ACK, 1500);
received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
}
else if (rights[i][j] == 7) {
PrintAndLog("Access rights do not allow reading of sector %d block %d",i,j);
@ -355,13 +353,13 @@ int CmdHF14AMfDump(const char *Cmd)
UsbCommand c = {CMD_MIFARE_READBL, {i*4+j, 0, 0}};
memcpy(c.d.asBytes, keyA[i], 6);
SendCommand(&c);
resp = WaitForResponseTimeout(CMD_ACK, 1500);
received = WaitForResponseTimeout(CMD_ACK,&resp,1500);
}
}
if (resp != NULL) {
uint8_t isOK = resp->arg[0] & 0xff;
uint8_t *data = resp->d.asBytes;
if (received) {
uint8_t isOK = resp.arg[0] & 0xff;
uint8_t *data = resp.d.asBytes;
if (j == 3) {
data[0] = (keyA[i][0]);
data[1] = (keyA[i][1]);
@ -462,10 +460,10 @@ int CmdHF14AMfRestore(const char *Cmd)
memcpy(c.d.asBytes + 10, bldata, 16);
SendCommand(&c);
UsbCommand *resp = WaitForResponseTimeout(CMD_ACK, 1500);
if (resp != NULL) {
uint8_t isOK = resp->arg[0] & 0xff;
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
@ -575,7 +573,7 @@ int CmdHF14AMfNested(const char *Cmd)
if (res)
res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
if (!res) {
PrintAndLog("Found valid key:%012I64x", key64);
PrintAndLog("Found valid key:%012"llx, key64);
// transfer key to the emulator
if (transferToEml) {
@ -635,7 +633,7 @@ int CmdHF14AMfNested(const char *Cmd)
if (res)
res = mfCheckKeys(trgBlockNo, trgKeyType, 8, &keyBlock[6 * 8], &key64);
if (!res) {
PrintAndLog("Found valid key:%012I64x", key64);
PrintAndLog("Found valid key:%012"llx, key64);
e_sector[trgBlockNo / 4].foundKey[trgKeyType] = 1;
e_sector[trgBlockNo / 4].Key[trgKeyType] = key64;
}
@ -648,7 +646,7 @@ int CmdHF14AMfNested(const char *Cmd)
PrintAndLog("|sec|key A |res|key B |res|");
PrintAndLog("|---|----------------|---|----------------|---|");
for (i = 0; i < SectorsCnt; i++) {
PrintAndLog("|%03d| %012I64x | %d | %012I64x | %d |", i,
PrintAndLog("|%03d| %012"llx" | %d | %012"llx" | %d |", i,
e_sector[i].Key[0], e_sector[i].foundKey[0], e_sector[i].Key[1], e_sector[i].foundKey[1]);
}
PrintAndLog("|---|----------------|---|----------------|---|");
@ -845,7 +843,7 @@ int CmdHF14AMfChk(const char *Cmd)
}
memset(keyBlock + 6 * keycnt, 0, 6);
num_to_bytes(strtoll(buf, NULL, 16), 6, keyBlock + 6*keycnt);
PrintAndLog("chk custom key[%d] %012I64x", keycnt, bytes_to_num(keyBlock + 6*keycnt, 6));
PrintAndLog("chk custom key[%d] %012"llx, keycnt, bytes_to_num(keyBlock + 6*keycnt, 6));
keycnt++;
}
} else {
@ -875,7 +873,7 @@ int CmdHF14AMfChk(const char *Cmd)
res = mfCheckKeys(b, t, size, keyBlock +6*c, &key64);
if (res !=1) {
if (!res) {
PrintAndLog("Found valid key:[%012I64x]",key64);
PrintAndLog("Found valid key:[%012"llx"]",key64);
if (transferToEml) {
uint8_t block[16];
mfEmlGetMem(block, get_trailer_block(b), 1);
@ -1207,7 +1205,7 @@ int CmdHF14AMfEKeyPrn(const char *Cmd)
}
keyA = bytes_to_num(data, 6);
keyB = bytes_to_num(data + 10, 6);
PrintAndLog("|%03d| %012I64x | %012I64x |", i, keyA, keyB);
PrintAndLog("|%03d| %012"llx" | %012"llx" |", i, keyA, keyB);
}
PrintAndLog("|---|----------------|----------------|");
@ -1591,11 +1589,11 @@ int CmdHF14AMfSniff(const char *Cmd){
break;
}
UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 2000);
if (resp != NULL) {
res = resp->arg[0] & 0xff;
len = resp->arg[1];
num = resp->arg[2];
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
res = resp.arg[0] & 0xff;
len = resp.arg[1];
num = resp.arg[2];
if (res == 0) return 0;
if (res == 1) {
@ -1603,7 +1601,7 @@ int CmdHF14AMfSniff(const char *Cmd){
bufPtr = buf;
memset(buf, 0x00, 3000);
}
memcpy(bufPtr, resp->d.asBytes, len);
memcpy(bufPtr, resp.d.asBytes, len);
bufPtr += len;
pckNum++;
}
@ -1678,7 +1676,7 @@ static command_t CommandTable[] =
int CmdHFMF(const char *Cmd)
{
// flush
while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
WaitForResponseTimeout(CMD_ACK,NULL,100);
CmdsParse(CommandTable, Cmd);
return 0;

View file

@ -18,7 +18,7 @@
#include "proxmark3.h"
#include "iso14443crc.h"
#include "data.h"
#include "proxusb.h"
//#include "proxusb.h"
#include "ui.h"
#include "cmdparser.h"
#include "common.h"

View file

@ -13,7 +13,8 @@
#include <string.h>
#include <limits.h>
#include "ui.h"
#include "proxusb.h"
//#include "proxusb.h"
#include "proxmark3.h"
#include "cmdparser.h"
#include "cmdhw.h"

View file

@ -12,7 +12,8 @@
#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"
@ -37,7 +38,7 @@ int CmdLFCommandRead(const char *Cmd)
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);
@ -366,7 +367,7 @@ int CmdLFRead(const char *Cmd)
return 0;
}
SendCommand(&c);
WaitForResponse(CMD_ACK);
WaitForResponse(CMD_ACK,NULL);
return 0;
}
@ -403,7 +404,7 @@ int CmdLFSim(const char *Cmd)
c.d.asBytes[j] = GraphBuffer[i+j];
}
SendCommand(&c);
WaitForResponse(CMD_ACK);
WaitForResponse(CMD_ACK,NULL);
}
PrintAndLog("Starting simulator...");

View file

@ -11,7 +11,8 @@
#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"
@ -520,6 +521,7 @@ int CmdWriteWordPWD(const char *Cmd)
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},

View file

@ -9,7 +9,9 @@
//-----------------------------------------------------------------------------
#include <stdio.h>
#include "proxusb.h"
#include <string.h>
//#include "proxusb.h"
#include "proxmark3.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
@ -44,23 +46,6 @@ int CmdHIDDemodFSK(const char *Cmd)
}
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;
@ -94,6 +79,24 @@ int CmdHIDClone(const char *Cmd)
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;
}

View file

@ -12,12 +12,15 @@
#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);
@ -25,17 +28,7 @@ int CmdLFHitagList(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");
@ -44,6 +37,9 @@ int CmdLFHitagList(const char *Cmd)
int i = 0;
int prev = -1;
char filename[256];
FILE* pf = NULL;
for (;;) {
if(i >= 1900) {
break;
@ -114,7 +110,7 @@ int CmdLFHitagList(const char *Cmd)
line);
if (strlen(filename) > 0) {
if (pf) {
fprintf(pf," +%7d: %s: %s %s %s",
(prev < 0 ? 0 : (timestamp - prev)),
metricString,
@ -127,7 +123,7 @@ int CmdLFHitagList(const char *Cmd)
i += (len + 9);
}
if (strlen(filename) > 0) {
if (pf) {
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
fclose(pf);
}
@ -193,14 +189,14 @@ int CmdLFHitagReader(const char *Cmd) {
} 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;
}
@ -208,7 +204,31 @@ int CmdLFHitagReader(const char *Cmd) {
// 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;
}

View file

@ -10,7 +10,8 @@
#include <stdio.h>
#include <string.h>
#include "proxusb.h"
//#include "proxusb.h"
#include "proxmark3.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
@ -25,7 +26,8 @@ int CmdLFPCF7931Read(const char *Cmd)
{
UsbCommand c = {CMD_PCF7931_READ};
SendCommand(&c);
WaitForResponse(CMD_ACK);
UsbCommand resp;
WaitForResponse(CMD_ACK,&resp);
return 0;
}

View file

@ -10,7 +10,8 @@
#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"

View file

@ -11,7 +11,8 @@
#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"
@ -273,7 +274,7 @@ int CmdTIWrite(const char *Cmd)
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");

View file

@ -14,6 +14,7 @@
#include <string.h>
#include "sleep.h"
#include "cmdparser.h"
#include "proxmark3.h"
#include "data.h"
#include "usb_cmd.h"
#include "ui.h"
@ -22,6 +23,7 @@
#include "cmdhw.h"
#include "cmdlf.h"
#include "cmdmain.h"
#include "util.h"
unsigned int current_command = CMD_UNKNOWN;
unsigned int received_command = CMD_UNKNOWN;
@ -55,37 +57,40 @@ int CmdQuit(const char *Cmd)
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(&current_response_user, &current_response, sizeof(UsbCommand));
ret = &current_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, &current_response, sizeof(UsbCommand));
}
// 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);
}
@ -95,17 +100,25 @@ void CommandReceived(char *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
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;
@ -138,6 +151,19 @@ void UsbCommandReceived(UsbCommand *UC)
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) {
@ -146,19 +172,24 @@ void UsbCommandReceived(UsbCommand *UC)
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(&current_response, UC, sizeof(UsbCommand));
// // Store the last received command
// memcpy(&current_response, UC, sizeof(UsbCommand));
// received_command = UC->cmd;
} break;
}
// Store the last received command
memcpy(&current_response, UC, sizeof(UsbCommand));
received_command = UC->cmd;
/*
// Maybe it's a response:

View file

@ -15,7 +15,7 @@
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

View file

@ -12,6 +12,7 @@
#include <string.h>
#include "ui.h"
#include "cmdparser.h"
#include "proxmark3.h"
void CmdsHelp(const command_t Commands[])
{

View file

@ -12,25 +12,33 @@
#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);
}
*/
}

View file

@ -15,7 +15,8 @@
#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);

View file

@ -11,11 +11,18 @@
#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;
@ -26,7 +33,7 @@ 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',
@ -269,8 +276,8 @@ static int get_proxmark_state(uint32_t *state)
{
UsbCommand c;
c.cmd = CMD_DEVICE_INFO;
// SendCommand_(&c);
SendCommand(&c);
UsbCommand resp;
ReceiveCommand(&resp);
@ -290,7 +297,7 @@ static int get_proxmark_state(uint32_t *state)
*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;
}
@ -352,7 +359,7 @@ static int wait_for_ack(void)
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;
@ -384,6 +391,7 @@ int flash_start_flashing(int enable_bl_writes)
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");
@ -399,19 +407,24 @@ static int write_block(uint32_t address, uint8_t *data, uint32_t length)
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);
// memcpy(c.d.asBytes, block_buf+240, 16);
// SendCommand_(&c);
memcpy(c.d.asBytes, block_buf, length);
SendCommand(&c);
return wait_for_ack();
}
@ -473,6 +486,7 @@ void flash_free(flash_file_t *ctx)
// just reset the unit
int flash_stop_flashing(void) {
UsbCommand c = {CMD_HARDWARE_RESET};
// SendCommand_(&c);
SendCommand(&c);
return 0;
}

View file

@ -10,12 +10,73 @@
#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);
}
@ -31,12 +92,12 @@ int main(int argc, char **argv)
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;
@ -55,11 +116,9 @@ int main(int argc, char **argv)
}
}
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");

Binary file not shown.

39
client/messages.h Normal file
View file

@ -0,0 +1,39 @@
/**
* 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_

View file

@ -12,9 +12,9 @@
#include <stdlib.h>
#include <string.h>
#include "mifarehost.h"
#include "proxmark3.h"
// MIFARE
int compar_int(const void * a, const void * b) {
return (*(uint64_t*)b - *(uint64_t*)a);
}
@ -59,12 +59,12 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
fnVector * vector = NULL;
countKeys *ck;
int lenVector = 0;
UsbCommand * resp = NULL;
UsbCommand resp;
memset(resultKeys, 0x00, 16 * 6);
// flush queue
while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ;
WaitForResponseTimeout(CMD_ACK,NULL,100);
UsbCommand c = {CMD_MIFARE_NESTED, {blockNo, keyType, trgBlockNo + trgKeyType * 0x100}};
memcpy(c.d.asBytes, key, 6);
@ -81,18 +81,16 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
break;
}
resp = WaitForResponseTimeout(CMD_ACK, 1500);
if (resp != NULL) {
isEOF = resp->arg[0] & 0xff;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
isEOF = resp.arg[0] & 0xff;
if (isEOF) break;
len = resp->arg[1] & 0xff;
len = resp.arg[1] & 0xff;
if (len == 0) continue;
memcpy(&uid, resp->d.asBytes, 4);
PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, resp->arg[2] & 0xff, (resp->arg[2] >> 8) & 0xff);
memcpy(&uid, resp.d.asBytes, 4);
PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, resp.arg[2] & 0xff, (resp.arg[2] >> 8) & 0xff);
vector = (fnVector *) realloc((void *)vector, (lenVector + len) * sizeof(fnVector) + 200);
if (vector == NULL) {
PrintAndLog("Memory allocation error for fnVector. len: %d bytes: %d", lenVector + len, (lenVector + len) * sizeof(fnVector));
@ -100,12 +98,12 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
}
for (i = 0; i < len; i++) {
vector[lenVector + i].blockNo = resp->arg[2] & 0xff;
vector[lenVector + i].keyType = (resp->arg[2] >> 8) & 0xff;
vector[lenVector + i].blockNo = resp.arg[2] & 0xff;
vector[lenVector + i].keyType = (resp.arg[2] >> 8) & 0xff;
vector[lenVector + i].uid = uid;
memcpy(&vector[lenVector + i].nt, (void *)(resp->d.asBytes + 8 + i * 8 + 0), 4);
memcpy(&vector[lenVector + i].ks1, (void *)(resp->d.asBytes + 8 + i * 8 + 4), 4);
memcpy(&vector[lenVector + i].nt, (void *)(resp.d.asBytes + 8 + i * 8 + 0), 4);
memcpy(&vector[lenVector + i].ks1, (void *)(resp.d.asBytes + 8 + i * 8 + 4), 4);
}
lenVector += len;
@ -187,14 +185,12 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
UsbCommand c = {CMD_MIFARE_CHKKEYS, {blockNo, keyType, keycnt}};
memcpy(c.d.asBytes, keyBlock, 6 * keycnt);
SendCommand(&c);
UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 3000);
if (resp == NULL) return 1;
if ((resp->arg[0] & 0xff) != 0x01) return 2;
*key = bytes_to_num(resp->d.asBytes, 6);
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) return 1;
if ((resp.arg[0] & 0xff) != 0x01) return 2;
*key = bytes_to_num(resp.d.asBytes, 6);
return 0;
}
@ -202,13 +198,11 @@ int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * key
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {
UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}};
SendCommand(&c);
UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
if (resp == NULL) return 1;
memcpy(data, resp->d.asBytes, blocksCount * 16);
UsbCommand resp;
if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) return 1;
memcpy(data, resp.d.asBytes, blocksCount * 16);
return 0;
}
@ -241,11 +235,10 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint
memcpy(c.d.asBytes, data, 16);
SendCommand(&c);
UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
if (resp != NULL) {
isOK = resp->arg[0] & 0xff;
if (uid != NULL) memcpy(uid, resp->d.asBytes, 4);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
isOK = resp.arg[0] & 0xff;
if (uid != NULL) memcpy(uid, resp.d.asBytes, 4);
if (!isOK) return 2;
} else {
PrintAndLog("Command execute timeout");
@ -260,11 +253,10 @@ int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
UsbCommand c = {CMD_MIFARE_EML_CGETBLOCK, {params, 0, blockNo}};
SendCommand(&c);
UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500);
if (resp != NULL) {
isOK = resp->arg[0] & 0xff;
memcpy(data, resp->d.asBytes, 16);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
isOK = resp.arg[0] & 0xff;
memcpy(data, resp.d.asBytes, 16);
if (!isOK) return 2;
} else {
PrintAndLog("Command execute timeout");

View file

@ -15,7 +15,7 @@
#include "cmdmain.h"
#include "ui.h"
#include "data.h"
#include "proxusb.h"
//#include "proxusb.h"
#include "util.h"
#include "nonce2key/nonce2key.h"
#include "nonce2key/crapto1.h"

View file

@ -70,7 +70,7 @@ static inline int parity(uint32_t x)
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"

View file

@ -10,6 +10,10 @@
// MIFARE Darkside hack
//-----------------------------------------------------------------------------
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#define llx PRIx64
#include "nonce2key.h"
#include "ui.h"
@ -23,7 +27,7 @@ int nonce2key(uint32_t uid, uint32_t nt, uint64_t par_info, uint64_t ks_info, ui
// 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++)
{

View file

@ -13,7 +13,6 @@
#ifndef __NONCE2KEY_H
#define __NONCE2KEY_H
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include "crapto1.h"

View file

@ -16,31 +16,84 @@
#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"
struct usb_receiver_arg
{
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 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;
}
}
@ -48,16 +101,16 @@ static void *usb_receiver(void *targ)
return NULL;
}
static void *main_loop(void *targ)
{
static void *main_loop(void *targ) {
struct main_loop_arg *arg = (struct main_loop_arg*)targ;
struct usb_receiver_arg rarg;
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, &usb_receiver, &rarg);
pthread_create(&reader_thread, NULL, &uart_receiver, &rarg);
}
FILE *script_file = NULL;
@ -142,22 +195,23 @@ static void *main_loop(void *targ)
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];
}
if (!OpenProxmark(1)) {
fprintf(stderr,"PROXMARK3: NOT FOUND!\n");
marg.usb_present = 0;
@ -166,6 +220,21 @@ int main(int argc, char **argv)
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);
@ -174,8 +243,12 @@ int main(int argc, char **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;
}

View file

@ -12,6 +12,17 @@
#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

View file

@ -1,222 +0,0 @@
//-----------------------------------------------------------------------------
// 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;
}

View file

@ -1,34 +0,0 @@
//-----------------------------------------------------------------------------
// 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

View file

@ -11,7 +11,7 @@
#ifndef SLEEP_H__
#define SLEEP_H__
#ifdef WIN32
#ifdef _WIN32
#include <windows.h>
#define sleep(n) Sleep(1000 * n)
#define msleep(n) Sleep(n)

399
client/uart.c Normal file
View file

@ -0,0 +1,399 @@
/*
* 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

76
client/uart.h Normal file
View file

@ -0,0 +1,76 @@
/*
* 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_

View file

@ -10,7 +10,7 @@
#include "util.h"
#ifndef WIN32
#ifndef _WIN32
#include <termios.h>
#include <sys/ioctl.h>
int ukbhit(void)

View file

@ -16,6 +16,9 @@
#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);

View file

@ -65,7 +65,7 @@ VPATH = . ../common/ ../fpga/
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

81
common/cmd.c Normal file
View file

@ -0,0 +1,81 @@
/*
* Proxmark send and receive commands
*
* 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 cmd.c
* @brief
*/
#include "cmd.h"
#include "string.h"
#include "proxmark3.h"
//static UsbCommand txcmd;
bool cmd_receive(UsbCommand* cmd) {
// Check if there is a usb packet available
if (!usb_poll()) return false;
// Try to retrieve the available command frame
size_t rxlen = usb_read((byte_t*)cmd,sizeof(UsbCommand));
// Check if the transfer was complete
if (rxlen != sizeof(UsbCommand)) return false;
// Received command successfully
return true;
}
bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len) {
UsbCommand txcmd;
for (size_t i=0; i<sizeof(UsbCommand); i++) {
((byte_t*)&txcmd)[i] = 0x00;
}
// Compose the outgoing command frame
txcmd.cmd = cmd;
txcmd.arg[0] = arg0;
txcmd.arg[1] = arg1;
txcmd.arg[2] = arg2;
// Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE
if (data && len) {
len = MIN(len,USB_CMD_DATA_SIZE);
for (size_t i=0; i<len; i++) {
txcmd.d.asBytes[i] = ((byte_t*)data)[i];
}
}
// Send frame and make sure all bytes are transmitted
if (usb_write((byte_t*)&txcmd,sizeof(UsbCommand)) != 0) return false;
return true;
}

44
common/cmd.h Normal file
View file

@ -0,0 +1,44 @@
/*
* Proxmark send and receive commands
*
* Copyright (c) 2010, 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 cmd.h
* @brief
*/
#ifndef _PROXMARK_CMD_H_
#define _PROXMARK_CMD_H_
#include <common.h>
#include <usb_cmd.h>
#include "usb_cdc.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);
#endif // _PROXMARK_CMD_H_

View file

@ -1,523 +0,0 @@
//-----------------------------------------------------------------------------
// 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;
}

567
common/usb_cdc.c Normal file
View file

@ -0,0 +1,567 @@
/*
* at91sam7s USB CDC device implementation
*
* 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.
*
* based on the "Basic USB Example" from ATMEL (doc6123.pdf)
*
* @file usb_cdc.c
* @brief
*/
#include "usb_cdc.h"
#include "config_gpio.h"
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define AT91C_EP_IN_SIZE 0x40
#define AT91C_EP_OUT 1
#define AT91C_EP_OUT_SIZE 0x40
#define AT91C_EP_IN 2
const char devDescriptor[] = {
/* Device descriptor */
0x12, // bLength
0x01, // bDescriptorType
0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10)
0x02, // bDeviceClass: CDC class code
0x00, // bDeviceSubclass: CDC class sub code
0x00, // bDeviceProtocol: CDC Device protocol
0x08, // bMaxPacketSize0
0x2d,0x2d, // Vendor ID (--)
0x4d,0x50, // Product ID (PM), transmitted in reverse
0x01,0x00, // Device release number (0001)
0x01, // iManufacturer // 0x01
0x00, // iProduct
0x00, // SerialNumber
0x01 // bNumConfigs
};
const char cfgDescriptor[] = {
/* ============== CONFIGURATION 1 =========== */
/* Configuration 1 descriptor */
0x09, // CbLength
0x02, // CbDescriptorType
0x43, // CwTotalLength 2 EP + Control
0x00,
0x02, // CbNumInterfaces
0x01, // CbConfigurationValue
0x00, // CiConfiguration
0xC0, // CbmAttributes 0xA0
0x00, // CMaxPower
/* Communication Class Interface Descriptor Requirement */
0x09, // bLength
0x04, // bDescriptorType
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x01, // bNumEndpoints
0x02, // bInterfaceClass
0x02, // bInterfaceSubclass
0x00, // bInterfaceProtocol
0x00, // iInterface
/* Header Functional Descriptor */
0x05, // bFunction Length
0x24, // bDescriptor type: CS_INTERFACE
0x00, // bDescriptor subtype: Header Func Desc
0x10, // bcdCDC:1.1
0x01,
/* ACM Functional Descriptor */
0x04, // bFunctionLength
0x24, // bDescriptor Type: CS_INTERFACE
0x02, // bDescriptor Subtype: ACM Func Desc
0x00, // bmCapabilities
/* Union Functional Descriptor */
0x05, // bFunctionLength
0x24, // bDescriptorType: CS_INTERFACE
0x06, // bDescriptor Subtype: Union Func Desc
0x00, // bMasterInterface: Communication Class Interface
0x01, // bSlaveInterface0: Data Class Interface
/* Call Management Functional Descriptor */
0x05, // bFunctionLength
0x24, // bDescriptor Type: CS_INTERFACE
0x01, // bDescriptor Subtype: Call Management Func Desc
0x00, // bmCapabilities: D1 + D0
0x01, // bDataInterface: Data Class Interface 1
/* Endpoint 1 descriptor */
0x07, // bLength
0x05, // bDescriptorType
0x83, // bEndpointAddress, Endpoint 03 - IN
0x03, // bmAttributes INT
0x08, // wMaxPacketSize
0x00,
0xFF, // bInterval
/* Data Class Interface Descriptor Requirement */
0x09, // bLength
0x04, // bDescriptorType
0x01, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0x0A, // bInterfaceClass
0x00, // bInterfaceSubclass
0x00, // bInterfaceProtocol
0x00, // iInterface
/* First alternate setting */
/* Endpoint 1 descriptor */
0x07, // bLength
0x05, // bDescriptorType
0x01, // bEndpointAddress, Endpoint 01 - OUT
0x02, // bmAttributes BULK
AT91C_EP_OUT_SIZE, // wMaxPacketSize
0x00,
0x00, // bInterval
/* Endpoint 2 descriptor */
0x07, // bLength
0x05, // bDescriptorType
0x82, // bEndpointAddress, Endpoint 02 - IN
0x02, // bmAttributes BULK
AT91C_EP_IN_SIZE, // wMaxPacketSize
0x00,
0x00 // bInterval
};
const char strDescriptor[] = {
26, // Length
0x03, // Type is string
'p', 0x00,
'r', 0x00,
'o', 0x00,
'x', 0x00,
'm', 0x00,
'a', 0x00,
'r', 0x00,
'k', 0x00,
'.', 0x00,
'o', 0x00,
'r', 0x00,
'g', 0x00,
};
/* USB standard request code */
#define STD_GET_STATUS_ZERO 0x0080
#define STD_GET_STATUS_INTERFACE 0x0081
#define STD_GET_STATUS_ENDPOINT 0x0082
#define STD_CLEAR_FEATURE_ZERO 0x0100
#define STD_CLEAR_FEATURE_INTERFACE 0x0101
#define STD_CLEAR_FEATURE_ENDPOINT 0x0102
#define STD_SET_FEATURE_ZERO 0x0300
#define STD_SET_FEATURE_INTERFACE 0x0301
#define STD_SET_FEATURE_ENDPOINT 0x0302
#define STD_SET_ADDRESS 0x0500
#define STD_GET_DESCRIPTOR 0x0680
#define STD_SET_DESCRIPTOR 0x0700
#define STD_GET_CONFIGURATION 0x0880
#define STD_SET_CONFIGURATION 0x0900
#define STD_GET_INTERFACE 0x0A81
#define STD_SET_INTERFACE 0x0B01
#define STD_SYNCH_FRAME 0x0C82
/* CDC Class Specific Request Code */
#define GET_LINE_CODING 0x21A1
#define SET_LINE_CODING 0x2021
#define SET_CONTROL_LINE_STATE 0x2221
typedef struct {
unsigned int dwDTERRate;
char bCharFormat;
char bParityType;
char bDataBits;
} AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;
AT91S_CDC_LINE_CODING line = {
115200, // baudrate
0, // 1 Stop Bit
0, // None Parity
8}; // 8 Data bits
void AT91F_CDC_Enumerate();
AT91PS_UDP pUdp = AT91C_BASE_UDP;
byte_t btConfiguration = 0;
byte_t btConnection = 0;
byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
//*----------------------------------------------------------------------------
//* \fn usb_disable
//* \brief This function deactivates the USB device
//*----------------------------------------------------------------------------
void usb_disable() {
// Disconnect the USB device
AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;
// SpinDelay(100);
// Clear all lingering interrupts
if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {
pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
}
}
//*----------------------------------------------------------------------------
//* \fn usb_enable
//* \brief This function Activates the USB device
//*----------------------------------------------------------------------------
void usb_enable() {
// Set the PLL USB Divider
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;
// Specific Chip USB Initialisation
// Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock
AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
// Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
// Set in PIO mode and Configure in Output
AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode
AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output
// Clear for set the Pullup resistor
AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU;
// Disconnect and reconnect USB controller for 100ms
usb_disable();
// Wait for a short while
for (volatile size_t i=0; i<0x100000; i++);
// SpinDelay(100);
// Reconnect USB reconnect
AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;
AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU;
}
//*----------------------------------------------------------------------------
//* \fn usb_check
//* \brief Test if the device is configured and handle enumeration
//*----------------------------------------------------------------------------
bool usb_check() {
AT91_REG isr = pUdp->UDP_ISR;
if (isr & AT91C_UDP_ENDBUSRES) {
pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
// reset all endpoints
pUdp->UDP_RSTEP = (unsigned int)-1;
pUdp->UDP_RSTEP = 0;
// Enable the function
pUdp->UDP_FADDR = AT91C_UDP_FEN;
// Configure endpoint 0
pUdp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
}
else if (isr & AT91C_UDP_EPINT0) {
pUdp->UDP_ICR = AT91C_UDP_EPINT0;
AT91F_CDC_Enumerate();
}
return (btConfiguration) ? true : false;
}
bool usb_poll()
{
if (!usb_check()) return false;
return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);
}
//*----------------------------------------------------------------------------
//* \fn usb_read
//* \brief Read available data from Endpoint OUT
//*----------------------------------------------------------------------------
uint32_t usb_read(byte_t* data, size_t len) {
byte_t bank = btReceiveBank;
uint32_t packetSize, nbBytesRcv = 0;
uint32_t time_out = 0;
while (len)
{
if (!usb_check()) break;
if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {
packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);
len -= packetSize;
while(packetSize--)
data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];
pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);
if (bank == AT91C_UDP_RX_DATA_BK0)
{
bank = AT91C_UDP_RX_DATA_BK1;
} else {
bank = AT91C_UDP_RX_DATA_BK0;
}
}
if (time_out++ == 0x1fff) break;
}
btReceiveBank = bank;
return nbBytesRcv;
}
//*----------------------------------------------------------------------------
//* \fn usb_write
//* \brief Send through endpoint 2
//*----------------------------------------------------------------------------
uint32_t usb_write(const byte_t* data, const size_t len) {
size_t length = len;
uint32_t cpt = 0;
if (!length) return 0;
if (!usb_check()) return 0;
// Send the first packet
cpt = MIN(length, AT91C_EP_IN_SIZE-1);
length -= cpt;
while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
while (length) {
// Fill the second bank
cpt = MIN(length, AT91C_EP_IN_SIZE-1);
length -= cpt;
while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
// Wait for the the first bank to be sent
while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
if (!usb_check()) return length;
}
pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;
}
// Wait for the end of transfer
while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
if (!usb_check()) return length;
}
pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);
return length;
}
//*----------------------------------------------------------------------------
//* \fn AT91F_USB_SendData
//* \brief Send Data through the control endpoint
//*----------------------------------------------------------------------------
unsigned int csrTab[100];
unsigned char csrIdx = 0;
static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
uint32_t cpt = 0;
AT91_REG csr;
do {
cpt = MIN(length, 8);
length -= cpt;
while (cpt--)
pUdp->UDP_FDR[0] = *pData++;
if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
}
pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
do {
csr = pUdp->UDP_CSR[0];
// Data IN stage has been stopped by a status OUT
if (csr & AT91C_UDP_RX_DATA_BK0) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
return;
}
} while ( !(csr & AT91C_UDP_TXCOMP) );
} while (length);
if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
}
}
//*----------------------------------------------------------------------------
//* \fn AT91F_USB_SendZlp
//* \brief Send zero length packet through the control endpoint
//*----------------------------------------------------------------------------
void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {
pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) );
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);
}
//*----------------------------------------------------------------------------
//* \fn AT91F_USB_SendStall
//* \brief Stall the control endpoint
//*----------------------------------------------------------------------------
void AT91F_USB_SendStall(AT91PS_UDP pUdp) {
pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) );
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);
while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));
}
//*----------------------------------------------------------------------------
//* \fn AT91F_CDC_Enumerate
//* \brief This function is a callback invoked when a SETUP packet is received
//*----------------------------------------------------------------------------
void AT91F_CDC_Enumerate() {
byte_t bmRequestType, bRequest;
uint16_t wValue, wIndex, wLength, wStatus;
if ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) )
return;
bmRequestType = pUdp->UDP_FDR[0];
bRequest = pUdp->UDP_FDR[0];
wValue = (pUdp->UDP_FDR[0] & 0xFF);
wValue |= (pUdp->UDP_FDR[0] << 8);
wIndex = (pUdp->UDP_FDR[0] & 0xFF);
wIndex |= (pUdp->UDP_FDR[0] << 8);
wLength = (pUdp->UDP_FDR[0] & 0xFF);
wLength |= (pUdp->UDP_FDR[0] << 8);
if (bmRequestType & 0x80) {
pUdp->UDP_CSR[0] |= AT91C_UDP_DIR;
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_DIR) );
}
pUdp->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
while ( (pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) );
// Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
switch ((bRequest << 8) | bmRequestType) {
case STD_GET_DESCRIPTOR:
if (wValue == 0x100) // Return Device Descriptor
AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength));
else if (wValue == 0x200) // Return Configuration Descriptor
AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));
else if ((wValue & 0x300) == 0x300) // Return String Descriptor
AT91F_USB_SendData(pUdp, strDescriptor, MIN(sizeof(strDescriptor), wLength));
else
AT91F_USB_SendStall(pUdp);
break;
case STD_SET_ADDRESS:
AT91F_USB_SendZlp(pUdp);
pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue);
pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0;
break;
case STD_SET_CONFIGURATION:
btConfiguration = wValue;
AT91F_USB_SendZlp(pUdp);
pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
pUdp->UDP_CSR[1] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;
pUdp->UDP_CSR[2] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;
pUdp->UDP_CSR[3] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;
break;
case STD_GET_CONFIGURATION:
AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));
break;
case STD_GET_STATUS_ZERO:
wStatus = 0;
AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
break;
case STD_GET_STATUS_INTERFACE:
wStatus = 0;
AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
break;
case STD_GET_STATUS_ENDPOINT:
wStatus = 0;
wIndex &= 0x0F;
if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) {
wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
}
else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == 0)) {
wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
}
else
AT91F_USB_SendStall(pUdp);
break;
case STD_SET_FEATURE_ZERO:
AT91F_USB_SendStall(pUdp);
break;
case STD_SET_FEATURE_INTERFACE:
AT91F_USB_SendZlp(pUdp);
break;
case STD_SET_FEATURE_ENDPOINT:
wIndex &= 0x0F;
if ((wValue == 0) && wIndex && (wIndex <= 3)) {
pUdp->UDP_CSR[wIndex] = 0;
AT91F_USB_SendZlp(pUdp);
}
else
AT91F_USB_SendStall(pUdp);
break;
case STD_CLEAR_FEATURE_ZERO:
AT91F_USB_SendStall(pUdp);
break;
case STD_CLEAR_FEATURE_INTERFACE:
AT91F_USB_SendZlp(pUdp);
break;
case STD_CLEAR_FEATURE_ENDPOINT:
wIndex &= 0x0F;
if ((wValue == 0) && wIndex && (wIndex <= 3)) {
if (wIndex == 1)
pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);
else if (wIndex == 2)
pUdp->UDP_CSR[2] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
else if (wIndex == 3)
pUdp->UDP_CSR[3] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN);
AT91F_USB_SendZlp(pUdp);
}
else
AT91F_USB_SendStall(pUdp);
break;
// handle CDC class requests
case SET_LINE_CODING:
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) );
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);
AT91F_USB_SendZlp(pUdp);
break;
case GET_LINE_CODING:
AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));
break;
case SET_CONTROL_LINE_STATE:
btConnection = wValue;
AT91F_USB_SendZlp(pUdp);
break;
default:
AT91F_USB_SendStall(pUdp);
break;
}
}

48
common/usb_cdc.h Normal file
View file

@ -0,0 +1,48 @@
/*
* at91sam7s USB CDC device implementation
*
* 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.
*
* based on the "Basic USB Example" from ATMEL (doc6123.pdf)
*
* @file usb_cdc.c
* @brief
*/
#ifndef _USB_CDC_H_
#define _USB_CDC_H_
#include <common.h>
void usb_disable();
void usb_enable();
bool usb_check();
bool usb_poll();
uint32_t usb_read(byte_t* data, size_t len);
uint32_t usb_write(const byte_t* data, const size_t len);
#endif // _USB_CDC_H_

32
driver/proxmark3.inf Normal file
View file

@ -0,0 +1,32 @@
[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"

View file

@ -12,27 +12,13 @@
#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

38
include/mifare.h Normal file
View file

@ -0,0 +1,38 @@
//-----------------------------------------------------------------------------
// (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_

View file

@ -67,12 +67,6 @@
//#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)
@ -88,17 +82,6 @@
#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 {

View file

@ -23,12 +23,14 @@ typedef BYTE uint8_t;
#define PACKED __attribute__((packed))
#endif
#define USB_CMD_DATA_SIZE 512
typedef struct {
uint32_t cmd;
uint32_t arg[3];
uint64_t cmd;
uint64_t arg[3];
union {
uint8_t asBytes[48];
uint32_t asDwords[12];
uint8_t asBytes[USB_CMD_DATA_SIZE];
uint32_t asDwords[USB_CMD_DATA_SIZE/4];
} d;
} PACKED UsbCommand;
@ -77,7 +79,6 @@ typedef struct {
#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

View file

@ -1,11 +1,11 @@
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)

View file

@ -11,5 +11,5 @@
+ 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

72
tools/mfkey/mfkey32.c Executable file
View file

@ -0,0 +1,72 @@
#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;
}

View file

@ -1,11 +1,15 @@
#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 lfsr;
uint8_t* plfsr = (uint8_t*)&lfsr;
uint64_t key; // recovered key
uint32_t uid; // serial number
uint32_t nt; // tag challenge
uint32_t nr_enc; // encrypted reader challenge
@ -14,7 +18,8 @@ int main (int argc, char *argv[]) {
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");
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]);
@ -58,8 +63,8 @@ int main (int argc, char *argv[]) {
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_get_lfsr(revstate, &key);
printf("\nFound Key: [%012"llx"]\n\n",key);
crypto1_destroy(revstate);
return 0;

View file

@ -1,5 +1,7 @@
#include "crapto1.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#define llx PRIx64
#include <stdio.h>
typedef unsigned char byte_t;
@ -18,13 +20,13 @@ int main(const int argc, const char* argv[]) {
}
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++)
{
@ -50,7 +52,7 @@ int main(const int argc, const char* argv[]) {
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;