// cmd.h
bool cmd_receive(UsbCommand* cmd);
-bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, byte_t* data, size_t len);
+bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);
/// util.h
/*\r
* Proxmark send and receive commands\r
*\r
- * Copyright (c) 2010, Roel Verdult\r
+ * Copyright (c) 2012, Roel Verdult\r
* All rights reserved.\r
*\r
* Redistribution and use in source and binary forms, with or without\r
return true;\r
}\r
\r
-bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, byte_t* data, size_t len) {\r
+bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len) {\r
UsbCommand txcmd;\r
\r
// Compose the outgoing command frame\r
\r
// Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE\r
if (data && len) {\r
- memcpy(txcmd.d.asBytes,data,MIN(len,USB_CMD_DATA_SIZE));\r
+ memcpy(txcmd.d.asBytes,(byte_t*)data,MIN(len,USB_CMD_DATA_SIZE));\r
}\r
\r
// Send frame and make sure all bytes are transmitted\r
#include "usb_cdc.h"\r
\r
bool cmd_receive(UsbCommand* cmd);\r
-bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, byte_t* data, size_t len);\r
+bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);\r
\r
#endif // _PROXMARK_CMD_H_\r
\r
/* 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) + 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, 12);
-
+
// 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
// While the UID is not complete, the 3nd bit (from the right) is set in the SAK.
// SELECT_ALL
ReaderTransmit(sel_all,sizeof(sel_all));
if (!ReaderReceive(resp)) return 0;
-// Dbprintf("uid: %02x %02x %02x %02x",resp[0],resp[1],resp[2],resp[3]);
-
- if(uid_ptr) memcpy(uid_ptr + cascade_level*4, resp, 4);
-
+
+ // First backup the current uid
+ memcpy(uid_resp,resp,4);
+ uid_resp_len = 4;
+ // Dbprintf("uid: %02x %02x %02x %02x",uid_resp[0],uid_resp[1],uid_resp[2],uid_resp[3]);
+
// calculate crypto UID
- if(cuid_ptr) *cuid_ptr = bytes_to_num(resp, 4);
+ if(cuid_ptr) {
+ *cuid_ptr = bytes_to_num(uid_resp, 4);
+ }
// Construct SELECT UID command
memcpy(sel_uid+2,resp,5);
// Receive the SAK
if (!ReaderReceive(resp)) return 0;
sak = resp[0];
+
+ // Test if more parts of the uid are comming
+ if ((sak & 0x04) && uid_resp[0] == 0x88) {
+ // Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
+ // http://www.nxp.com/documents/application_note/AN10927.pdf
+ memcpy(uid_ptr, uid_ptr + 1, 3);
+ uid_resp_len = 3;
+ }
+
+ if(uid_ptr) {
+ memcpy(uid_ptr + (cascade_level*3), uid_resp, uid_resp_len);
+ }
+
+ if(p_hi14a_card) {
+ memcpy(p_hi14a_card->uid + (cascade_level*3), uid_resp, uid_resp_len);
+ p_hi14a_card->uidlen += uid_resp_len;
+ }
}
- if(resp_data) {
- resp_data->sak = sak;
- resp_data->ats_len = 0;
- }
- //-- this byte not UID, it CT. http://www.nxp.com/documents/application_note/AN10927.pdf page 3
- if (uid_ptr[0] == 0x88) {
- memcpy(uid_ptr, uid_ptr + 1, 7);
- uid_ptr[7] = 0;
+
+ if(p_hi14a_card) {
+ p_hi14a_card->sak = sak;
+ p_hi14a_card->ats_len = 0;
}
- if( (sak & 0x20) == 0)
+ if( (sak & 0x20) == 0) {
return 2; // non iso14443a compliant tag
+ }
// Request for answer to select
- if(resp_data) { // JCOP cards - if reader sent RATS then there is no MIFARE session at all!!!
+ if(p_hi14a_card) { // JCOP cards - if reader sent RATS then there is no MIFARE session at all!!!
AppendCrc14443a(rats, 2);
ReaderTransmit(rats, sizeof(rats));
if (!(len = ReaderReceive(resp))) return 0;
- memcpy(resp_data->ats, resp, sizeof(resp_data->ats));
- resp_data->ats_len = len;
+ memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats));
+ p_hi14a_card->ats_len = len;
}
// reset the PCB block number
iso14_pcb_blocknum = 0;
-
return 1;
}
iso14a_command_t param = c->arg[0];
uint8_t * cmd = c->d.asBytes;
size_t len = c->arg[1];
- uint32_t arg0;
- byte_t buf[48];
+ uint32_t arg0 = 0;
+ byte_t buf[USB_CMD_DATA_SIZE];
iso14a_clear_trace();
iso14a_set_tracing(true);
- if(param & ISO14A_REQUEST_TRIGGER) iso14a_set_trigger(1);
+ if(param & ISO14A_REQUEST_TRIGGER) {
+ iso14a_set_trigger(1);
+ }
if(param & ISO14A_CONNECT) {
iso14443a_setup();
- arg0 = iso14443a_select_card(buf, (iso14a_card_select_t *)(buf+12), NULL);
- cmd_send(CMD_ACK,arg0,0,0,buf,48);
+ 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_APDU) {
arg0 = iso14_apdu(cmd, len, buf);
- cmd_send(CMD_ACK,arg0,0,0,buf,48);
+ cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
// UsbSendPacket((void *)ack, sizeof(UsbCommand));
}
ReaderTransmit(cmd,len);
arg0 = ReaderReceive(buf);
// UsbSendPacket((void *)ack, sizeof(UsbCommand));
- cmd_send(CMD_ACK,arg0,0,0,buf,48);
+ 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();
\r
#include "usb_cdc.h"\r
#include "util.h"\r
+#include "config_gpio.h"\r
\r
#define MIN(a, b) (((a) < (b)) ? (a) : (b))\r
#define MAX(a, b) (((a) > (b)) ? (a) : (b))\r
byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;\r
\r
//*----------------------------------------------------------------------------\r
-//* \fn AT91F_USB_Disable\r
+//* \fn usb_disable\r
//* \brief This function deactivates the USB device\r
//*----------------------------------------------------------------------------\r
void usb_disable() {\r
- // Disconnect and reconnect USB controller for 100ms\r
- AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA24;\r
+ // Disconnect the USB device\r
+ AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;\r
SpinDelay(100);\r
\r
// Clear all lingering interrupts\r
}\r
\r
//*----------------------------------------------------------------------------\r
-//* \fn AT91F_USB_Enable\r
+//* \fn usb_enable\r
//* \brief This function Activates the USB device\r
//*----------------------------------------------------------------------------\r
void usb_enable() {\r
\r
// Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO\r
// Set in PIO mode and Configure in Output\r
- AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA16; // Set in PIO mode\r
- AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA16; // Configure as Output\r
+ AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode\r
+ AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output\r
\r
- // Clear for set the Pul up resistor\r
- AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA16;\r
+ // Clear for set the Pullup resistor\r
+ AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU;\r
\r
- // Disconnect and USB device\r
+ // Disconnect and reconnect USB controller for 100ms\r
usb_disable();\r
\r
// Wait for a short while\r
SpinDelay(100);\r
\r
// Reconnect USB reconnect\r
- AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA24;\r
- AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA24;\r
+ AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;\r
+ AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU;\r
}\r
\r
//*----------------------------------------------------------------------------\r
-//* \fn AT91F_UDP_IsConfigured\r
+//* \fn usb_check\r
//* \brief Test if the device is configured and handle enumeration\r
//*----------------------------------------------------------------------------\r
bool usb_check() {\r
}\r
\r
//*----------------------------------------------------------------------------\r
-//* \fn AT91F_UDP_Read\r
+//* \fn usb_read\r
//* \brief Read available data from Endpoint OUT\r
//*----------------------------------------------------------------------------\r
uint32_t usb_read(byte_t* data, size_t len) {\r
}\r
\r
//*----------------------------------------------------------------------------\r
-//* \fn AT91F_CDC_Write\r
+//* \fn usb_write\r
//* \brief Send through endpoint 2\r
//*----------------------------------------------------------------------------\r
uint32_t usb_write(const byte_t* data, const size_t len) {\r
UsbCommand resp;
WaitForResponse(CMD_ACK,&resp);
- uint8_t * uid = resp.d.asBytes;
- iso14a_card_select_t * card = (iso14a_card_select_t *)(uid + 12);
+ iso14a_card_select_t *card = (iso14a_card_select_t *)resp.d.asBytes;
+ uint8_t * uid = card->uid;
if(resp.arg[0] == 0) {
PrintAndLog("iso14443a card select failed");
}
PrintAndLog("ATQA : %02x %02x", card->atqa[0], card->atqa[1]);
- PrintAndLog(" UID : %s", sprint_hex(uid, 12));
+ PrintAndLog(" UID : %s", sprint_hex(card->uid, card->uidlen));
PrintAndLog(" SAK : %02x [%d]", card->sak, resp.arg[0]);
switch (card->sak) {
- case 0x00: PrintAndLog(" SAK : NXP MIFARE Ultralight | Ultralight C"); break;
- case 0x04: PrintAndLog(" SAK : NXP MIFARE (various !DESFire !DESFire EV1)"); break;
-
- case 0x08: PrintAndLog(" SAK : NXP MIFARE CLASSIC 1k | Plus 2k"); break;
- case 0x09: PrintAndLog(" SAK : NXP MIFARE Mini 0.3k"); break;
- case 0x10: PrintAndLog(" SAK : NXP MIFARE Plus 2k"); break;
- case 0x11: PrintAndLog(" SAK : NXP MIFARE Plus 4k"); break;
- case 0x18: PrintAndLog(" SAK : NXP MIFARE Classic 4k | Plus 4k"); break;
- case 0x20: PrintAndLog(" SAK : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k | JCOP 31/41"); break;
- case 0x24: PrintAndLog(" SAK : NXP MIFARE DESFire | DESFire EV1"); break;
- case 0x28: PrintAndLog(" SAK : JCOP31 or JCOP41 v2.3.1"); break;
- case 0x38: PrintAndLog(" SAK : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); break;
- case 0x88: PrintAndLog(" SAK : Infineon MIFARE CLASSIC 1K"); break;
- case 0x98: PrintAndLog(" SAK : Gemplus MPCOS"); break;
+ case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break;
+ case 0x04: PrintAndLog("TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); break;
+
+ case 0x08: PrintAndLog("TYPE : NXP MIFARE CLASSIC 1k | Plus 2k"); break;
+ case 0x09: PrintAndLog("TYPE : NXP MIFARE Mini 0.3k"); break;
+ case 0x10: PrintAndLog("TYPE : NXP MIFARE Plus 2k"); break;
+ case 0x11: PrintAndLog("TYPE : NXP MIFARE Plus 4k"); break;
+ case 0x18: PrintAndLog("TYPE : NXP MIFARE Classic 4k | Plus 4k"); break;
+ case 0x20: PrintAndLog("TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k | JCOP 31/41"); break;
+ case 0x24: PrintAndLog("TYPE : NXP MIFARE DESFire | DESFire EV1"); break;
+ case 0x28: PrintAndLog("TYPE : JCOP31 or JCOP41 v2.3.1"); break;
+ case 0x38: PrintAndLog("TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); break;
+ case 0x88: PrintAndLog("TYPE : Infineon MIFARE CLASSIC 1K"); break;
+ case 0x98: PrintAndLog("TYPE : Gemplus MPCOS"); break;
default: ;
}
if(resp.arg[0] == 1) {
}
}
}
- }
- else
- PrintAndLog("proprietary non-iso14443a card found, RATS not supported");
+ } else {
+ PrintAndLog("proprietary non iso14443a-4 card found, RATS not supported");
+ }
return resp.arg[0];
}
//-----------------------------------------------------------------------------
void UsbCommandReceived(UsbCommand *UC)
{
+ /*
// Debug
- // printf("UsbCommand length[len=%d]\n",sizeof(UsbCommand));
- // printf(" cmd[len=%d]: %x\n",sizeof(UC->cmd),UC->cmd);
- // printf(" arg0[len=%d]: %x\n",sizeof(UC->arg[0]),UC->arg[0]);
- // printf(" arg1[len=%d]: %x\n",sizeof(UC->arg[1]),UC->arg[1]);
- // printf(" arg2[len=%d]: %x\n",sizeof(UC->arg[2]),UC->arg[2]);
- // printf(" data[len=%d]: %02x%02x%02x...\n",sizeof(UC->d.asBytes),UC->d.asBytes[0],UC->d.asBytes[1],UC->d.asBytes[2]);
+ 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