fixed USB GPIO bug reported by gregy, and fixed 'hf 14a reader' command

This commit is contained in:
roel@libnfc.org 2013-02-27 13:23:38 +00:00
parent ab6bf11f3f
commit 79a73ab2d1
7 changed files with 111 additions and 81 deletions

View file

@ -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

View file

@ -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

View file

@ -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_

View file

@ -1636,30 +1636,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) + 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
@ -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( (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;
}
@ -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();

View file

@ -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) {

View file

@ -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-4 card found, RATS not supported");
}
else
PrintAndLog("proprietary non-iso14443a card found, RATS not supported");
return resp.arg[0];
}

View file

@ -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