mirror of
https://github.com/Proxmark/proxmark3.git
synced 2024-09-21 07:16:24 +08:00
fixed USB GPIO bug reported by gregy, and fixed 'hf 14a reader' command
This commit is contained in:
parent
ab6bf11f3f
commit
79a73ab2d1
|
@ -183,7 +183,7 @@ 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, 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
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Proxmark send and receive commands
|
||||
*
|
||||
* Copyright (c) 2010, Roel Verdult
|
||||
* Copyright (c) 2012, Roel Verdult
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -52,7 +52,7 @@ bool cmd_receive(UsbCommand* cmd) {
|
|||
return true;
|
||||
}
|
||||
|
||||
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) {
|
||||
UsbCommand txcmd;
|
||||
|
||||
// Compose the outgoing command frame
|
||||
|
@ -63,7 +63,7 @@ bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, byte_t*
|
|||
|
||||
// Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE
|
||||
if (data && len) {
|
||||
memcpy(txcmd.d.asBytes,data,MIN(len,USB_CMD_DATA_SIZE));
|
||||
memcpy(txcmd.d.asBytes,(byte_t*)data,MIN(len,USB_CMD_DATA_SIZE));
|
||||
}
|
||||
|
||||
// Send frame and make sure all bytes are transmitted
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include "usb_cdc.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);
|
||||
|
||||
#endif // _PROXMARK_CMD_H_
|
||||
|
||||
|
|
|
@ -1636,31 +1636,36 @@ 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) + 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.
|
||||
|
@ -1672,12 +1677,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;
|
||||
// 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);
|
||||
|
@ -1687,34 +1696,47 @@ 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(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( (sak & 0x20) == 0)
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1774,18 +1796,20 @@ void ReaderIso14443a(UsbCommand * c)
|
|||
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));
|
||||
}
|
||||
|
||||
|
@ -1799,7 +1823,7 @@ void ReaderIso14443a(UsbCommand * c)
|
|||
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -1811,13 +1835,16 @@ void ReaderIso14443a(UsbCommand * c)
|
|||
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();
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include "usb_cdc.h"
|
||||
#include "util.h"
|
||||
#include "config_gpio.h"
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
@ -217,12 +218,12 @@ byte_t btConnection = 0;
|
|||
byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_USB_Disable
|
||||
//* \fn usb_disable
|
||||
//* \brief This function deactivates the USB device
|
||||
//*----------------------------------------------------------------------------
|
||||
void usb_disable() {
|
||||
// Disconnect and reconnect USB controller for 100ms
|
||||
AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA24;
|
||||
// Disconnect the USB device
|
||||
AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;
|
||||
SpinDelay(100);
|
||||
|
||||
// Clear all lingering interrupts
|
||||
|
@ -232,7 +233,7 @@ void usb_disable() {
|
|||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_USB_Enable
|
||||
//* \fn usb_enable
|
||||
//* \brief This function Activates the USB device
|
||||
//*----------------------------------------------------------------------------
|
||||
void usb_enable() {
|
||||
|
@ -246,25 +247,25 @@ void usb_enable() {
|
|||
|
||||
// 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 = AT91C_PIO_PA16; // Set in PIO mode
|
||||
AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA16; // Configure as 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 Pul up resistor
|
||||
AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA16;
|
||||
// Clear for set the Pullup resistor
|
||||
AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU;
|
||||
|
||||
// Disconnect and USB device
|
||||
// Disconnect and reconnect USB controller for 100ms
|
||||
usb_disable();
|
||||
|
||||
// Wait for a short while
|
||||
SpinDelay(100);
|
||||
|
||||
// Reconnect USB reconnect
|
||||
AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA24;
|
||||
AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA24;
|
||||
AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;
|
||||
AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_UDP_IsConfigured
|
||||
//* \fn usb_check
|
||||
//* \brief Test if the device is configured and handle enumeration
|
||||
//*----------------------------------------------------------------------------
|
||||
bool usb_check() {
|
||||
|
@ -295,7 +296,7 @@ bool usb_poll()
|
|||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_UDP_Read
|
||||
//* \fn usb_read
|
||||
//* \brief Read available data from Endpoint OUT
|
||||
//*----------------------------------------------------------------------------
|
||||
uint32_t usb_read(byte_t* data, size_t len) {
|
||||
|
@ -328,7 +329,7 @@ uint32_t usb_read(byte_t* data, size_t len) {
|
|||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
//* \fn AT91F_CDC_Write
|
||||
//* \fn usb_write
|
||||
//* \brief Send through endpoint 2
|
||||
//*----------------------------------------------------------------------------
|
||||
uint32_t usb_write(const byte_t* data, const size_t len) {
|
||||
|
|
|
@ -168,8 +168,8 @@ int CmdHF14AReader(const char *Cmd)
|
|||
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");
|
||||
|
@ -177,24 +177,24 @@ int CmdHF14AReader(const char *Cmd)
|
|||
}
|
||||
|
||||
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 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) {
|
||||
|
@ -314,9 +314,9 @@ int CmdHF14AReader(const char *Cmd)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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];
|
||||
}
|
||||
|
|
|
@ -100,13 +100,15 @@ void CommandReceived(char *Cmd) {
|
|||
//-----------------------------------------------------------------------------
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue