return true;
}
+static bool hitag2_read_uid(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
+ // Reset the transmission frame length
+ *txlen = 0;
+
+ // Try to find out which command was send by selecting on length (in bits)
+ switch (rxlen) {
+ // No answer, try to resurrect
+ case 0: {
+ // Just starting or if there is no answer
+ *txlen = 5;
+ memcpy(tx,"\xc0",nbytes(*txlen));
+ } break;
+ // Received UID
+ case 32: {
+ // Check if we received answer tag (at)
+ if (bAuthenticating) {
+ bAuthenticating = false;
+ } else {
+ // Store the received block
+ memcpy(tag.sectors[blocknr],rx,4);
+ blocknr++;
+ }
+ if (blocknr > 0) {
+ //DbpString("Read successful!");
+ bSuccessful = true;
+ return false;
+ }
+ } break;
+ // Unexpected response
+ default: {
+ Dbprintf("Uknown frame length: %d",rxlen);
+ return false;
+ } break;
+ }
+ return true;
+}
void SnoopHitag(uint32_t type) {
int frame_count;
set_tracing(TRUE);
clear_trace();
- DbpString("Starting Hitag reader family");
+ //DbpString("Starting Hitag reader family");
// Check configuration
switch(htf) {
case RHT2F_PASSWORD: {
Dbprintf("List identifier in password mode");
memcpy(password,htd->pwd.password,4);
- blocknr = 0;
+ blocknr = 0;
bQuitTraceFull = false;
bQuiet = false;
bPwd = false;
} break;
-
case RHT2F_AUTHENTICATE: {
DbpString("Authenticating using nr,ar pair:");
memcpy(NrAr,htd->auth.NrAr,8);
bAuthenticating = false;
bQuitTraceFull = true;
} break;
-
case RHT2F_CRYPTO: {
DbpString("Authenticating using key:");
memcpy(key,htd->crypto.key,6); //HACK; 4 or 6?? I read both in the code.
bAuthenticating = false;
bQuitTraceFull = true;
} break;
-
case RHT2F_TEST_AUTH_ATTEMPTS: {
Dbprintf("Testing %d authentication attempts",(auth_table_len/8));
auth_table_pos = 0;
bQuiet = false;
bCrypto = false;
} break;
-
+ case RHT2F_UID_ONLY: {
+ blocknr = 0;
+ bQuiet = false;
+ bCrypto = false;
+ bAuthenticating = false;
+ } break;
default: {
Dbprintf("Error, unknown function: %d",htf);
return;
// hitagS settings
reset_sof = 1;
t_wait = 200;
- DbpString("Configured for hitagS reader");
+ //DbpString("Configured for hitagS reader");
} else if (htf < 20) {
// hitag1 settings
reset_sof = 1;
t_wait = 200;
- DbpString("Configured for hitag1 reader");
+ //DbpString("Configured for hitag1 reader");
} else if (htf < 30) {
// hitag2 settings
reset_sof = 4;
t_wait = HITAG_T_WAIT_2;
- DbpString("Configured for hitag2 reader");
+ //DbpString("Configured for hitag2 reader");
} else {
Dbprintf("Error, unknown hitag reader type: %d",htf);
return;
}
-
+ uint8_t attempt_count=0;
while(!bStop && !BUTTON_PRESS()) {
// Watchdog hit
WDT_HIT();
case RHT2F_TEST_AUTH_ATTEMPTS: {
bStop = !hitag2_test_auth_attempts(rx,rxlen,tx,&txlen);
} break;
+ case RHT2F_UID_ONLY: {
+ bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen);
+ attempt_count++; //attempt 3 times to get uid then quit
+ if (!bStop && attempt_count == 3) bStop = true;
+ } break;
default: {
Dbprintf("Error, unknown function: %d",htf);
return;
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);
}
for(j = 0; j < 4; j++) {
for(k = 0; k < 4; k++) {
if(k == (b & 3)) {
- ToSend[++ToSendMax] = 0x0f;
+ ToSend[++ToSendMax] = 0xf0;
}
else {
ToSend[++ToSendMax] = 0x00;
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Reset trace buffer
- set_tracing(TRUE);
- clear_trace();
+ set_tracing(TRUE);
+ clear_trace();
// Setup SSC
FpgaSetupSsc();
return read_status;
}
-uint8_t handshakeIclassTag(uint8_t *card_data){
+uint8_t handshakeIclassTag(uint8_t *card_data) {
return handshakeIclassTag_ext(card_data, false);
}
}
bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) {
- uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
//uint8_t readblockdata[10];
//write[1] = blockNo;
memcpy(write+2, data, 12); // data + mac
+ char *wrCmd = (char *)(write+1);
+ uint16_t wrCrc = iclass_crc16(wrCmd, 13);
+ write[14] = wrCrc >> 8;
+ write[15] = wrCrc & 0xff;
uint8_t resp[] = {0,0,0,0,0,0,0,0,0,0};
- bool isOK;
+ bool isOK = false;
+
isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
- if (isOK) {
+ if (isOK) { //if reader responded correctly
//Dbprintf("WriteResp: %02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",resp[0],resp[1],resp[2],resp[3],resp[4],resp[5],resp[6],resp[7],resp[8],resp[9]);
- if (memcmp(write+2,resp,8)) {
- //error try again
- isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
+ if (memcmp(write+2,resp,8)) { //if response is not equal to write values
+ if (blockNo != 3 && blockNo != 4) { //if not programming key areas (note key blocks don't get programmed with actual key data it is xor data)
+ //error try again
+ isOK = sendCmdGetResponseWithRetries(write,sizeof(write),resp,sizeof(resp),10);
+ }
+
}
}
return isOK;
-int usage_lf_cmdread()
+int usage_lf_cmdread(void)
{
PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> [H] ");
PrintAndLog("Options: ");
return 0;
}
-int usage_lf_read()
+int usage_lf_read(void)
{
PrintAndLog("Usage: lf read");
PrintAndLog("Options: ");
PrintAndLog("Use 'lf config' to set parameters.");
return 0;
}
-int usage_lf_snoop()
+int usage_lf_snoop(void)
{
PrintAndLog("Usage: lf snoop");
PrintAndLog("Options: ");
return 0;
}
-int usage_lf_config()
+int usage_lf_config(void)
{
PrintAndLog("Usage: lf config [H|<divisor>] [b <bps>] [d <decim>] [a 0|1]");
PrintAndLog("Options: ");
return 0;
}
-// by marshmellow - sim ask data given clock, fcHigh, fcLow, invert
+// by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert
// - allow pull data from DemodBuffer
int CmdLFfskSim(const char *Cmd)
{
return 1;
}
+ ans=CmdLFHitagReader("26");
+ if (ans==0) {
+ return 1;
+ }
+
PrintAndLog("\nNo Known Tags Found!\n");
if (testRaw=='u' || testRaw=='U'){
//test unknown tag formats (raw mode)
} break;
case RHT2F_CRYPTO: {
num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
-// num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
+ // num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
} break;
case RHT2F_TEST_AUTH_ATTEMPTS: {
// No additional parameters needed
} break;
+ case RHT2F_UID_ONLY: {
+ // No additional parameters needed
+ } break;
default: {
- PrintAndLog("Error: unkown reader function %d",htf);
- PrintAndLog("Hitag reader functions");
+ PrintAndLog("\nError: unkown reader function %d",htf);
+ PrintAndLog("");
+ PrintAndLog("Usage: hitag reader <Reader Function #>");
+ PrintAndLog("Reader Functions:");
PrintAndLog(" HitagS (0*)");
PrintAndLog(" 01 <nr> <ar> (Challenge) read all pages from a Hitag S tag");
PrintAndLog(" 02 <key> (set to 0 if no authentication is needed) read all pages from a Hitag S tag");
PrintAndLog(" 22 <nr> <ar> (authentication)");
PrintAndLog(" 23 <key> (authentication) key is in format: ISK high + ISK low");
PrintAndLog(" 25 (test recorded authentications)");
+ PrintAndLog(" 26 just read UID");
return 1;
} break;
}
// Copy the hitag2 function into the first argument
c.arg[0] = htf;
- // Send the command to the proxmark
- SendCommand(&c);
-
- UsbCommand resp;
- WaitForResponse(CMD_ACK,&resp);
-
- // Check the return status, stored in the first argument
- if (resp.arg[0] == false) return 1;
-
- uint32_t id = bytes_to_num(resp.d.asBytes,4);
- char filename[256];
- FILE* pf = NULL;
-
- sprintf(filename,"%08x_%04x.ht2",id,(rand() & 0xffff));
- if ((pf = fopen(filename,"wb")) == NULL) {
- PrintAndLog("Error: Could not open file [%s]",filename);
- return 1;
- }
-
- // Write the 48 tag memory bytes to file and finalize
- fwrite(resp.d.asBytes,1,48,pf);
- fclose(pf);
+ // Send the command to the proxmark
+ SendCommand(&c);
- PrintAndLog("Succesfully saved tag memory to [%s]",filename);
-
- return 0;
+ 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);
+
+ if (htf == RHT2F_UID_ONLY){
+ PrintAndLog("Valid Hitag2 tag found - UID: %08x",id);
+ } else {
+ 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;
}
#define _HITAG2_H_
typedef enum {
- RHTSF_CHALLENGE = 01,
- RHTSF_KEY = 02,
+ RHTSF_CHALLENGE = 01,
+ RHTSF_KEY = 02,
WHTSF_CHALLENGE = 03,
WHTSF_KEY = 04,
RHT2F_PASSWORD = 21,
RHT2F_AUTHENTICATE = 22,
RHT2F_CRYPTO = 23,
RHT2F_TEST_AUTH_ATTEMPTS = 25,
+ RHT2F_UID_ONLY = 26
} hitag_function;
typedef struct {