mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge remote-tracking branch 'upstream/master'
Conflicts: client/cmdlf.c
This commit is contained in:
+1
-1
@@ -802,7 +802,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||
MifareUReadBlock(c->arg[0],c->d.asBytes);
|
||||
break;
|
||||
case CMD_MIFAREU_READCARD:
|
||||
MifareUReadCard(c->arg[0],c->d.asBytes);
|
||||
MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
|
||||
break;
|
||||
case CMD_MIFARE_READSC:
|
||||
MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ void ReaderMifare(bool first_try);
|
||||
int32_t dist_nt(uint32_t nt1, uint32_t nt2);
|
||||
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
|
||||
void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
|
||||
void MifareUReadCard(uint8_t arg0,uint8_t *datain);
|
||||
void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain);
|
||||
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
||||
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
|
||||
void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
|
||||
|
||||
+2
-2
@@ -744,7 +744,7 @@ void SnoopHitag(uint32_t type) {
|
||||
// Set up eavesdropping mode, frequency divisor which will drive the FPGA
|
||||
// and analog mux selection.
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
RELAY_OFF();
|
||||
@@ -968,7 +968,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
|
||||
// Set up simulator mode, frequency divisor which will drive the FPGA
|
||||
// and analog mux selection.
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
|
||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||
RELAY_OFF();
|
||||
|
||||
+1
-1
@@ -1812,7 +1812,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
|
||||
if (!ReaderReceive(resp, resp_par)) return 0;
|
||||
sak = resp[0];
|
||||
|
||||
// Test if more parts of the uid are comming
|
||||
// Test if more parts of the uid are coming
|
||||
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
|
||||
|
||||
+1319
-1319
File diff suppressed because it is too large
Load Diff
+82
-92
@@ -15,6 +15,7 @@
|
||||
|
||||
#include "mifarecmd.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Select, Authenticate, Read a MIFARE tag.
|
||||
@@ -86,48 +87,40 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
|
||||
void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
uint8_t blockNo = arg0;
|
||||
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
byte_t dataoutbuf[16];
|
||||
uint8_t uid[10];
|
||||
byte_t dataout[16] = {0x00};
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
while (true) {
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
break;
|
||||
iso14a_clear_trace();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
int len = iso14443a_select_card(uid, NULL, &cuid);
|
||||
if(!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||
//OnError(1);
|
||||
return;
|
||||
};
|
||||
|
||||
if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");
|
||||
break;
|
||||
len = mifare_ultra_readblock(cuid, blockNo, dataout);
|
||||
if(len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
|
||||
//OnError(2);
|
||||
return;
|
||||
};
|
||||
|
||||
if(mifare_ultra_halt(cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
break;
|
||||
len = mifare_ultra_halt(cuid);
|
||||
if(len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
|
||||
//OnError(3);
|
||||
return;
|
||||
};
|
||||
|
||||
isOK = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
|
||||
LED_B_OFF();
|
||||
cmd_send(CMD_ACK,1,0,0,dataout,16);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
@@ -200,58 +193,70 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
|
||||
void MifareUReadCard(uint8_t arg0, uint8_t *datain)
|
||||
void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
uint8_t sectorNo = arg0;
|
||||
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
byte_t dataoutbuf[16 * 4];
|
||||
uint8_t uid[10];
|
||||
uint32_t cuid;
|
||||
int Pages = arg1;
|
||||
int count_Pages = 0;
|
||||
byte_t dataout[176] = {0x00};;
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
// iso14a_set_tracing(false);
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
if (MF_DBGLEVEL >= MF_DBG_ALL)
|
||||
Dbprintf("Pages %d",Pages);
|
||||
|
||||
iso14a_clear_trace();
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
int len = iso14443a_select_card(uid, NULL, &cuid);
|
||||
|
||||
if (!len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Can't select card");
|
||||
//OnError(1);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Pages; i++){
|
||||
|
||||
len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i);
|
||||
|
||||
if (len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Read block %d error",i);
|
||||
//OnError(2);
|
||||
return;
|
||||
} else {
|
||||
count_Pages++;
|
||||
}
|
||||
}
|
||||
|
||||
len = mifare_ultra_halt(cuid);
|
||||
if (len) {
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Halt error");
|
||||
//OnError(3);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MF_DBGLEVEL >= MF_DBG_ALL) {
|
||||
Dbprintf("Pages read %d", count_Pages);
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
break;
|
||||
};
|
||||
for(int sec=0;sec<16;sec++){
|
||||
if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block %d error",sec);
|
||||
break;
|
||||
};
|
||||
}
|
||||
if(mifare_ultra_halt(cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
break;
|
||||
};
|
||||
|
||||
isOK = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);
|
||||
LED_B_OFF();
|
||||
|
||||
// Thats it...
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
len = 16*4; //64 bytes
|
||||
|
||||
// Read a UL-C
|
||||
if (Pages == 44 && count_Pages > 16)
|
||||
len = 176;
|
||||
|
||||
cmd_send(CMD_ACK, 1, 0, 0, dataout, len);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
|
||||
@@ -331,19 +336,16 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
uint8_t blockNo = arg0;
|
||||
byte_t blockdata[16];
|
||||
byte_t blockdata[16] = {0x00};
|
||||
|
||||
memset(blockdata,'\0',16);
|
||||
memcpy(blockdata, datain,16);
|
||||
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
uint8_t uid[10];
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
LED_A_ON();
|
||||
@@ -372,33 +374,25 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
|
||||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
LED_B_OFF();
|
||||
|
||||
|
||||
// Thats it...
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
// iso14a_set_tracing(TRUE);
|
||||
}
|
||||
|
||||
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
uint8_t blockNo = arg0;
|
||||
byte_t blockdata[4];
|
||||
byte_t blockdata[4] = {0x00};
|
||||
|
||||
memcpy(blockdata, datain,4);
|
||||
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
uint8_t uid[10];
|
||||
uint8_t uid[10] = {0x00};
|
||||
uint32_t cuid;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
LED_A_ON();
|
||||
@@ -427,11 +421,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
|
||||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
LED_B_OFF();
|
||||
|
||||
// Thats it...
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
}
|
||||
|
||||
+19
-20
@@ -149,7 +149,7 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
|
||||
return len;
|
||||
}
|
||||
|
||||
// mifare commands
|
||||
// mifare classic commands
|
||||
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested)
|
||||
{
|
||||
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);
|
||||
@@ -280,10 +280,8 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
|
||||
|
||||
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
// variables
|
||||
uint16_t len;
|
||||
uint8_t bt[2];
|
||||
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
|
||||
@@ -291,18 +289,21 @@ int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
// command MIFARE_CLASSIC_READBLOCK
|
||||
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len == 1) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
if (len != 18) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: card timeout. len: %x", len);
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Error: card timeout. len: %x", len);
|
||||
return 2;
|
||||
}
|
||||
|
||||
memcpy(bt, receivedAnswer + 16, 2);
|
||||
AppendCrc14443a(receivedAnswer, 16);
|
||||
if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd CRC response error.");
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd CRC response error.");
|
||||
return 3;
|
||||
}
|
||||
|
||||
@@ -360,10 +361,9 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
|
||||
|
||||
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
// variables
|
||||
uint16_t len;
|
||||
uint8_t par[3] = {0}; // enough for 18 parity bits
|
||||
uint8_t d_block[18];
|
||||
uint8_t d_block[18] = {0x00};
|
||||
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
|
||||
@@ -371,45 +371,43 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(d_block,'\0',18);
|
||||
memcpy(d_block, blockData, 16);
|
||||
AppendCrc14443a(d_block, 16);
|
||||
|
||||
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
|
||||
|
||||
// Receive the response
|
||||
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
|
||||
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
|
||||
{
|
||||
uint16_t len;
|
||||
uint8_t d_block[8];
|
||||
uint8_t d_block[8] = {0x00};
|
||||
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();
|
||||
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
|
||||
|
||||
// command MIFARE_CLASSIC_WRITEBLOCK
|
||||
memset(d_block,'\0',8);
|
||||
d_block[0]= blockNo;
|
||||
memcpy(d_block+1,blockData,4);
|
||||
AppendCrc14443a(d_block, 6);
|
||||
|
||||
//i know the data send here is correct
|
||||
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -423,7 +421,8 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
||||
|
||||
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len != 0) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len);
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("halt error. response len: %x", len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -438,10 +437,10 @@ int mifare_ultra_halt(uint32_t uid)
|
||||
|
||||
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len != 0) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len);
|
||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
||||
Dbprintf("halt error. response len: %x", len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,11 @@ int memcmp(const void *av, const void *bv, int len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void memxor(uint8_t * dest, uint8_t * src, size_t len) {
|
||||
for( ; len > 0; len--,dest++,src++)
|
||||
*dest ^= *src;
|
||||
}
|
||||
|
||||
int strlen(const char *str)
|
||||
{
|
||||
int l = 0;
|
||||
|
||||
@@ -19,6 +19,7 @@ int strlen(const char *str);
|
||||
RAMFUNC void *memcpy(void *dest, const void *src, int len);
|
||||
void *memset(void *dest, int c, int len);
|
||||
RAMFUNC int memcmp(const void *av, const void *bv, int len);
|
||||
void memxor(uint8_t * dest, uint8_t * src, size_t len);
|
||||
char *strncat(char *dest, const char *src, unsigned int n);
|
||||
char *strcat(char *dest, const char *src);
|
||||
void strreverse(char s[]);
|
||||
|
||||
@@ -13,6 +13,26 @@
|
||||
#include "string.h"
|
||||
#include "apps.h"
|
||||
|
||||
|
||||
|
||||
void print_result(char *name, uint8_t *buf, size_t len) {
|
||||
uint8_t *p = buf;
|
||||
|
||||
if ( len % 16 == 0 ) {
|
||||
for(; p-buf < len; p += 16)
|
||||
Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
name,
|
||||
p-buf,
|
||||
len,
|
||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
|
||||
);
|
||||
}
|
||||
else {
|
||||
for(; p-buf < len; p += 8)
|
||||
Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x", name, p-buf, len, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||
}
|
||||
}
|
||||
|
||||
size_t nbytes(size_t nbits) {
|
||||
return (nbits/8)+((nbits%8)>0);
|
||||
}
|
||||
@@ -45,6 +65,26 @@ uint64_t bytes_to_num(uint8_t* src, size_t len)
|
||||
return num;
|
||||
}
|
||||
|
||||
// RotateLeft - Ultralight, Desfire
|
||||
void rol(uint8_t *data, const size_t len){
|
||||
uint8_t first = data[0];
|
||||
for (size_t i = 0; i < len-1; i++) {
|
||||
data[i] = data[i+1];
|
||||
}
|
||||
data[len-1] = first;
|
||||
}
|
||||
void lsl (uint8_t *data, size_t len) {
|
||||
for (size_t n = 0; n < len - 1; n++) {
|
||||
data[n] = (data[n] << 1) | (data[n+1] >> 7);
|
||||
}
|
||||
data[len - 1] <<= 1;
|
||||
}
|
||||
|
||||
int32_t le24toh (uint8_t data[3])
|
||||
{
|
||||
return (data[2] << 16) | (data[1] << 8) | data[0];
|
||||
}
|
||||
|
||||
void LEDsoff()
|
||||
{
|
||||
LED_A_OFF();
|
||||
|
||||
@@ -27,10 +27,14 @@
|
||||
#define BUTTON_DOUBLE_CLICK -2
|
||||
#define BUTTON_ERROR -99
|
||||
|
||||
void print_result(char *name, uint8_t *buf, size_t len);
|
||||
size_t nbytes(size_t nbits);
|
||||
uint32_t SwapBits(uint32_t value, int nrbits);
|
||||
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
|
||||
uint64_t bytes_to_num(uint8_t* src, size_t len);
|
||||
void rol(uint8_t *data, const size_t len);
|
||||
void lsl (uint8_t *data, size_t len);
|
||||
int32_t le24toh (uint8_t data[3]);
|
||||
|
||||
void SpinDelay(int ms);
|
||||
void SpinDelayUs(int us);
|
||||
|
||||
@@ -103,13 +103,11 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
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;
|
||||
|
||||
@@ -125,10 +123,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
@@ -138,8 +134,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
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);
|
||||
cmd_send(CMD_NACK,0,0,0,0,0);
|
||||
} else {
|
||||
uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE;
|
||||
@@ -147,7 +141,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY |
|
||||
MC_FLASH_COMMAND_PAGEN(page_n) |
|
||||
AT91C_MC_FCMD_START_PROG;
|
||||
// arg0 = (address - ((uint32_t)flash_s));
|
||||
}
|
||||
|
||||
// Wait until flashing of page finishes
|
||||
@@ -155,15 +148,12 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
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;
|
||||
cmd_send(CMD_NACK,0,0,0,0,0);
|
||||
// UsbSendPacket(packet, len);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case CMD_HARDWARE_RESET: {
|
||||
// USB_D_PLUS_PULLUP_OFF();
|
||||
usb_disable();
|
||||
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
|
||||
} break;
|
||||
@@ -189,8 +179,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
} else {
|
||||
start_addr = end_addr = 0;
|
||||
dont_ack = 1;
|
||||
// c->cmd = CMD_NACK;
|
||||
// UsbSendPacket(packet, len);
|
||||
cmd_send(CMD_NACK,0,0,0,0,0);
|
||||
}
|
||||
}
|
||||
@@ -202,8 +190,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
}
|
||||
|
||||
if(!dont_ack) {
|
||||
// c->cmd = CMD_ACK;
|
||||
// UsbSendPacket(packet, len);
|
||||
cmd_send(CMD_ACK,arg0,0,0,0,0);
|
||||
}
|
||||
}
|
||||
@@ -219,23 +205,18 @@ static void flash_mode(int externally_entered)
|
||||
usb_enable();
|
||||
for (volatile size_t i=0; i<0x100000; i++);
|
||||
|
||||
// UsbStart();
|
||||
for(;;) {
|
||||
WDT_HIT();
|
||||
|
||||
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_disable();
|
||||
LED_B_ON();
|
||||
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
|
||||
|
||||
+3
-2
@@ -13,9 +13,9 @@ CXX=g++
|
||||
VPATH = ../common
|
||||
OBJDIR = obj
|
||||
|
||||
LDLIBS = -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm -lcrypto
|
||||
LDLIBS = -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
|
||||
LDFLAGS = $(COMMON_FLAGS)
|
||||
CFLAGS = -std=c99 -lcrypto -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
||||
CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
|
||||
LUAPLATFORM = generic
|
||||
|
||||
ifneq (,$(findstring MINGW,$(platform)))
|
||||
@@ -94,6 +94,7 @@ CMDSRCS = nonce2key/crapto1.c\
|
||||
scripting.c\
|
||||
cmdscript.c\
|
||||
pm3_bitlib.c\
|
||||
aes.c\
|
||||
|
||||
|
||||
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
|
||||
|
||||
+1454
File diff suppressed because it is too large
Load Diff
+257
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* \file aes.h
|
||||
*
|
||||
* \brief AES block cipher
|
||||
*
|
||||
* Copyright (C) 2006-2014, Brainspark B.V.
|
||||
*
|
||||
* This file is part of PolarSSL (http://www.polarssl.org)
|
||||
* Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
#ifndef POLARSSL_AES_H
|
||||
#define POLARSSL_AES_H
|
||||
|
||||
#if !defined(POLARSSL_CONFIG_FILE)
|
||||
#include "polarssl_config.h"
|
||||
#else
|
||||
#include POLARSSL_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
|
||||
#include <basetsd.h>
|
||||
typedef UINT32 uint32_t;
|
||||
#else
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
/* padlock.c and aesni.c rely on these values! */
|
||||
#define AES_ENCRYPT 1
|
||||
#define AES_DECRYPT 0
|
||||
|
||||
#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
|
||||
#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
|
||||
|
||||
#if !defined(POLARSSL_AES_ALT)
|
||||
// Regular implementation
|
||||
//
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief AES context structure
|
||||
*
|
||||
* \note buf is able to hold 32 extra bytes, which can be used:
|
||||
* - for alignment purposes if VIA padlock is used, and/or
|
||||
* - to simplify key expansion in the 256-bit case by
|
||||
* generating an extra round key
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int nr; /*!< number of rounds */
|
||||
uint32_t *rk; /*!< AES round keys */
|
||||
uint32_t buf[68]; /*!< unaligned data */
|
||||
}
|
||||
aes_context;
|
||||
|
||||
/**
|
||||
* \brief Initialize AES context
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
*/
|
||||
void aes_init( aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief Clear AES context
|
||||
*
|
||||
* \param ctx AES context to be cleared
|
||||
*/
|
||||
void aes_free( aes_context *ctx );
|
||||
|
||||
/**
|
||||
* \brief AES key schedule (encryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key encryption key
|
||||
* \param keysize must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int aes_setkey_enc( aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief AES key schedule (decryption)
|
||||
*
|
||||
* \param ctx AES context to be initialized
|
||||
* \param key decryption key
|
||||
* \param keysize must be 128, 192 or 256
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
|
||||
*/
|
||||
int aes_setkey_dec( aes_context *ctx, const unsigned char *key,
|
||||
unsigned int keysize );
|
||||
|
||||
/**
|
||||
* \brief AES-ECB block encryption/decryption
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param input 16-byte input block
|
||||
* \param output 16-byte output block
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_ecb( aes_context *ctx,
|
||||
int mode,
|
||||
const unsigned char input[16],
|
||||
unsigned char output[16] );
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CBC)
|
||||
/**
|
||||
* \brief AES-CBC buffer encryption/decryption
|
||||
* Length should be a multiple of the block
|
||||
* size (16 bytes)
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
|
||||
*/
|
||||
int aes_crypt_cbc( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* POLARSSL_CIPHER_MODE_CBC */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CFB)
|
||||
/**
|
||||
* \brief AES-CFB128 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv_off offset in IV (updated after use)
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_cfb128( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
size_t *iv_off,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
|
||||
/**
|
||||
* \brief AES-CFB8 buffer encryption/decryption.
|
||||
*
|
||||
* Note: Due to the nature of CFB you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param mode AES_ENCRYPT or AES_DECRYPT
|
||||
* \param length length of the input data
|
||||
* \param iv initialization vector (updated after use)
|
||||
* \param input buffer holding the input data
|
||||
* \param output buffer holding the output data
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_cfb8( aes_context *ctx,
|
||||
int mode,
|
||||
size_t length,
|
||||
unsigned char iv[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /*POLARSSL_CIPHER_MODE_CFB */
|
||||
|
||||
#if defined(POLARSSL_CIPHER_MODE_CTR)
|
||||
/**
|
||||
* \brief AES-CTR buffer encryption/decryption
|
||||
*
|
||||
* Warning: You have to keep the maximum use of your counter in mind!
|
||||
*
|
||||
* Note: Due to the nature of CTR you should use the same key schedule for
|
||||
* both encryption and decryption. So a context initialized with
|
||||
* aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
|
||||
*
|
||||
* \param ctx AES context
|
||||
* \param length The length of the data
|
||||
* \param nc_off The offset in the current stream_block (for resuming
|
||||
* within current cipher stream). The offset pointer to
|
||||
* should be 0 at the start of a stream.
|
||||
* \param nonce_counter The 128-bit nonce and counter.
|
||||
* \param stream_block The saved stream-block for resuming. Is overwritten
|
||||
* by the function.
|
||||
* \param input The input data stream
|
||||
* \param output The output data stream
|
||||
*
|
||||
* \return 0 if successful
|
||||
*/
|
||||
int aes_crypt_ctr( aes_context *ctx,
|
||||
size_t length,
|
||||
size_t *nc_off,
|
||||
unsigned char nonce_counter[16],
|
||||
unsigned char stream_block[16],
|
||||
const unsigned char *input,
|
||||
unsigned char *output );
|
||||
#endif /* POLARSSL_CIPHER_MODE_CTR */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* POLARSSL_AES_ALT */
|
||||
#include "aes_alt.h"
|
||||
#endif /* POLARSSL_AES_ALT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Checkup routine
|
||||
*
|
||||
* \return 0 if successful, or 1 if the test failed
|
||||
*/
|
||||
int aes_self_test( int verbose );
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* aes.h */
|
||||
+931
-916
File diff suppressed because it is too large
Load Diff
+5
-5
@@ -342,8 +342,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
|
||||
// Rough guess that this is a command from the reader
|
||||
// For iClass the command byte is not part of the CRC
|
||||
ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
||||
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
|
||||
}
|
||||
@@ -363,7 +362,6 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
char *crc = crcError ? "!crc" :" ";
|
||||
|
||||
@@ -371,8 +369,10 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
|
||||
|
||||
if(!isResponse)
|
||||
{
|
||||
if(iclass) annotateIclass(explanation,sizeof(explanation),frame,data_len);
|
||||
else annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
|
||||
if(iclass)
|
||||
annotateIclass(explanation,sizeof(explanation),frame,data_len);
|
||||
else
|
||||
annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
|
||||
}
|
||||
|
||||
int num_lines = (data_len - 1)/16 + 1;
|
||||
|
||||
+151
-15
@@ -27,6 +27,102 @@
|
||||
static int CmdHelp(const char *Cmd);
|
||||
static void waitCmd(uint8_t iLen);
|
||||
|
||||
// structure and database for uid -> tagtype lookups
|
||||
typedef struct {
|
||||
uint8_t uid;
|
||||
char* desc;
|
||||
} manufactureName;
|
||||
|
||||
const manufactureName manufactureMapping[] = {
|
||||
// ID, "Vendor Country"
|
||||
{ 0x01, "Motorola UK" },
|
||||
{ 0x02, "ST Microelectronics SA France" },
|
||||
{ 0x03, "Hitachi, Ltd Japan" },
|
||||
{ 0x04, "NXP Semiconductors Germany" },
|
||||
{ 0x05, "Infineon Technologies AG Germany" },
|
||||
{ 0x06, "Cylink USA" },
|
||||
{ 0x07, "Texas Instrument France" },
|
||||
{ 0x08, "Fujitsu Limited Japan" },
|
||||
{ 0x09, "Matsushita Electronics Corporation, Semiconductor Company Japan" },
|
||||
{ 0x0A, "NEC Japan" },
|
||||
{ 0x0B, "Oki Electric Industry Co. Ltd Japan" },
|
||||
{ 0x0C, "Toshiba Corp. Japan" },
|
||||
{ 0x0D, "Mitsubishi Electric Corp. Japan" },
|
||||
{ 0x0E, "Samsung Electronics Co. Ltd Korea" },
|
||||
{ 0x0F, "Hynix / Hyundai, Korea" },
|
||||
{ 0x10, "LG-Semiconductors Co. Ltd Korea" },
|
||||
{ 0x11, "Emosyn-EM Microelectronics USA" },
|
||||
{ 0x12, "INSIDE Technology France" },
|
||||
{ 0x13, "ORGA Kartensysteme GmbH Germany" },
|
||||
{ 0x14, "SHARP Corporation Japan" },
|
||||
{ 0x15, "ATMEL France" },
|
||||
{ 0x16, "EM Microelectronic-Marin SA Switzerland" },
|
||||
{ 0x17, "KSW Microtec GmbH Germany" },
|
||||
{ 0x18, "ZMD AG Germany" },
|
||||
{ 0x19, "XICOR, Inc. USA" },
|
||||
{ 0x1A, "Sony Corporation Japan Identifier Company Country" },
|
||||
{ 0x1B, "Malaysia Microelectronic Solutions Sdn. Bhd Malaysia" },
|
||||
{ 0x1C, "Emosyn USA" },
|
||||
{ 0x1D, "Shanghai Fudan Microelectronics Co. Ltd. P.R. China" },
|
||||
{ 0x1E, "Magellan Technology Pty Limited Australia" },
|
||||
{ 0x1F, "Melexis NV BO Switzerland" },
|
||||
{ 0x20, "Renesas Technology Corp. Japan" },
|
||||
{ 0x21, "TAGSYS France" },
|
||||
{ 0x22, "Transcore USA" },
|
||||
{ 0x23, "Shanghai belling corp., ltd. China" },
|
||||
{ 0x24, "Masktech Germany Gmbh Germany" },
|
||||
{ 0x25, "Innovision Research and Technology Plc UK" },
|
||||
{ 0x26, "Hitachi ULSI Systems Co., Ltd. Japan" },
|
||||
{ 0x27, "Cypak AB Sweden" },
|
||||
{ 0x28, "Ricoh Japan" },
|
||||
{ 0x29, "ASK France" },
|
||||
{ 0x2A, "Unicore Microsystems, LLC Russian Federation" },
|
||||
{ 0x2B, "Dallas Semiconductor/Maxim USA" },
|
||||
{ 0x2C, "Impinj, Inc. USA" },
|
||||
{ 0x2D, "RightPlug Alliance USA" },
|
||||
{ 0x2E, "Broadcom Corporation USA" },
|
||||
{ 0x2F, "MStar Semiconductor, Inc Taiwan, ROC" },
|
||||
{ 0x30, "BeeDar Technology Inc. USA" },
|
||||
{ 0x31, "RFIDsec Denmark" },
|
||||
{ 0x32, "Schweizer Electronic AG Germany" },
|
||||
{ 0x33, "AMIC Technology Corp Taiwan" },
|
||||
{ 0x34, "Mikron JSC Russia" },
|
||||
{ 0x35, "Fraunhofer Institute for Photonic Microsystems Germany" },
|
||||
{ 0x36, "IDS Microchip AG Switzerland" },
|
||||
{ 0x37, "Kovio USA" },
|
||||
{ 0x38, "HMT Microelectronic Ltd Switzerland Identifier Company Country" },
|
||||
{ 0x39, "Silicon Craft Technology Thailand" },
|
||||
{ 0x3A, "Advanced Film Device Inc. Japan" },
|
||||
{ 0x3B, "Nitecrest Ltd UK" },
|
||||
{ 0x3C, "Verayo Inc. USA" },
|
||||
{ 0x3D, "HID Global USA" },
|
||||
{ 0x3E, "Productivity Engineering Gmbh Germany" },
|
||||
{ 0x3F, "Austriamicrosystems AG (reserved) Austria" },
|
||||
{ 0x40, "Gemalto SA France" },
|
||||
{ 0x41, "Renesas Electronics Corporation Japan" },
|
||||
{ 0x42, "3Alogics Inc Korea" },
|
||||
{ 0x43, "Top TroniQ Asia Limited Hong Kong" },
|
||||
{ 0x44, "Gentag Inc (USA) USA" },
|
||||
{ 0x00, "no tag-info available" } // must be the last entry
|
||||
};
|
||||
|
||||
|
||||
// get a product description based on the UID
|
||||
// uid[8] tag uid
|
||||
// returns description of the best match
|
||||
char* getTagInfo(uint8_t uid) {
|
||||
|
||||
int i;
|
||||
int len = sizeof(manufactureMapping) / sizeof(manufactureName);
|
||||
|
||||
for ( i = 0; i < len; ++i )
|
||||
if ( uid == manufactureMapping[i].uid)
|
||||
return manufactureMapping[i].desc;
|
||||
|
||||
//No match, return default
|
||||
return manufactureMapping[len-1].desc;
|
||||
}
|
||||
|
||||
int CmdHF14AList(const char *Cmd)
|
||||
{
|
||||
PrintAndLog("Deprecated command, use 'hf list 14a' instead");
|
||||
@@ -65,6 +161,12 @@ int CmdHF14AReader(const char *Cmd)
|
||||
PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen));
|
||||
PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
|
||||
|
||||
// Double & triple sized UID, can be mapped to a manufacturer.
|
||||
// HACK: does this apply for Ultralight cards?
|
||||
if ( card.uidlen > 4 ) {
|
||||
PrintAndLog("MANUFACTURER : %s", getTagInfo(card.uid[0]));
|
||||
}
|
||||
|
||||
switch (card.sak) {
|
||||
case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break;
|
||||
case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break;
|
||||
@@ -83,7 +185,6 @@ int CmdHF14AReader(const char *Cmd)
|
||||
default: ;
|
||||
}
|
||||
|
||||
|
||||
// try to request ATS even if tag claims not to support it
|
||||
if (select_status == 2) {
|
||||
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
|
||||
@@ -98,13 +199,6 @@ int CmdHF14AReader(const char *Cmd)
|
||||
card.ats_len = resp.arg[0]; // note: ats_len includes CRC Bytes
|
||||
}
|
||||
|
||||
// disconnect
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = 0;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
|
||||
|
||||
if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
|
||||
bool ta1 = 0, tb1 = 0, tc1 = 0;
|
||||
int pos;
|
||||
@@ -243,6 +337,24 @@ int CmdHF14AReader(const char *Cmd)
|
||||
PrintAndLog("proprietary non iso14443-4 card found, RATS not supported");
|
||||
}
|
||||
|
||||
|
||||
// try to see if card responses to "chinese magic backdoor" commands.
|
||||
c.cmd = CMD_MIFARE_CIDENT;
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = 0;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
WaitForResponse(CMD_ACK,&resp);
|
||||
uint8_t isOK = resp.arg[0] & 0xff;
|
||||
PrintAndLog(" Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
|
||||
|
||||
// disconnect
|
||||
c.cmd = CMD_READER_ISO_14443a;
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = 0;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
|
||||
return select_status;
|
||||
}
|
||||
|
||||
@@ -397,19 +509,22 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
uint8_t active=0;
|
||||
uint8_t active_select=0;
|
||||
uint16_t numbits=0;
|
||||
uint16_t timeout=0;
|
||||
uint8_t bTimeout=0;
|
||||
char buf[5]="";
|
||||
int i=0;
|
||||
uint8_t data[100];
|
||||
uint8_t data[USB_CMD_DATA_SIZE];
|
||||
unsigned int datalen=0, temp;
|
||||
|
||||
if (strlen(cmd)<2) {
|
||||
PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] <number of bits> <0A 0B 0C ... hex>");
|
||||
PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] [-t] <number of bits> <0A 0B 0C ... hex>");
|
||||
PrintAndLog(" -r do not read response");
|
||||
PrintAndLog(" -c calculate and append CRC");
|
||||
PrintAndLog(" -p leave the signal field ON after receive");
|
||||
PrintAndLog(" -a active signal field ON without select");
|
||||
PrintAndLog(" -s active signal field ON with select");
|
||||
PrintAndLog(" -b number of bits to send. Useful for send partial byte");
|
||||
PrintAndLog(" -t timeout");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -442,6 +557,14 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
|
||||
i-=2;
|
||||
break;
|
||||
case 't':
|
||||
bTimeout=1;
|
||||
sscanf(cmd+i+2,"%d",&temp);
|
||||
timeout = temp & 0xFFFF;
|
||||
i+=3;
|
||||
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
|
||||
i+=2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Invalid option");
|
||||
return 0;
|
||||
@@ -459,15 +582,19 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
if (strlen(buf)>=2) {
|
||||
sscanf(buf,"%x",&temp);
|
||||
data[datalen]=(uint8_t)(temp & 0xff);
|
||||
datalen++;
|
||||
*buf=0;
|
||||
if (++datalen>sizeof(data)){
|
||||
if (crc)
|
||||
PrintAndLog("Buffer is full, we can't add CRC to your data");
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
PrintAndLog("Invalid char on input");
|
||||
return 0;
|
||||
}
|
||||
if(crc && datalen>0)
|
||||
if(crc && datalen>0 && datalen<sizeof(data)-2)
|
||||
{
|
||||
uint8_t first, second;
|
||||
ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
|
||||
@@ -481,13 +608,22 @@ int CmdHF14ACmdRaw(const char *cmd) {
|
||||
if(active)
|
||||
c.arg[0] |= ISO14A_NO_SELECT;
|
||||
}
|
||||
if(bTimeout){
|
||||
#define MAX_TIMEOUT 624*105 // max timeout is 624 ms
|
||||
c.arg[0] |= ISO14A_SET_TIMEOUT;
|
||||
c.arg[2] = timeout * 105; // each bit is about 9.4 us
|
||||
if(c.arg[2]>MAX_TIMEOUT) {
|
||||
c.arg[2] = MAX_TIMEOUT;
|
||||
PrintAndLog("Set timeout to 624 ms. The max we can wait for response");
|
||||
}
|
||||
}
|
||||
if(power)
|
||||
c.arg[0] |= ISO14A_NO_DISCONNECT;
|
||||
if(datalen>0)
|
||||
c.arg[0] |= ISO14A_RAW;
|
||||
|
||||
c.arg[1] = datalen;
|
||||
c.arg[2] = numbits;
|
||||
// Max buffer is USB_CMD_DATA_SIZE
|
||||
c.arg[1] = (datalen & 0xFFFF) | (numbits << 16);
|
||||
memcpy(c.d.asBytes,data,datalen);
|
||||
|
||||
SendCommand(&c);
|
||||
@@ -507,7 +643,7 @@ static void waitCmd(uint8_t iSelect)
|
||||
UsbCommand resp;
|
||||
char *hexout;
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
|
||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
||||
recv = resp.d.asBytes;
|
||||
uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0];
|
||||
PrintAndLog("received %i octets",iLen);
|
||||
|
||||
@@ -20,4 +20,5 @@ int CmdHF14AReader(const char *Cmd);
|
||||
int CmdHF14ASim(const char *Cmd);
|
||||
int CmdHF14ASnoop(const char *Cmd);
|
||||
|
||||
char* getTagInfo(uint8_t uid);
|
||||
#endif
|
||||
|
||||
+22
-16
@@ -23,7 +23,6 @@
|
||||
#include "cmdhf14b.h"
|
||||
#include "cmdmain.h"
|
||||
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
int CmdHF14BDemod(const char *Cmd)
|
||||
@@ -146,7 +145,7 @@ demodError:
|
||||
|
||||
int CmdHF14BList(const char *Cmd)
|
||||
{
|
||||
uint8_t got[960];
|
||||
uint8_t got[TRACE_BUFFER_SIZE];
|
||||
GetFromBigBuf(got,sizeof(got),0);
|
||||
WaitForResponse(CMD_ACK,NULL);
|
||||
|
||||
@@ -158,9 +157,8 @@ int CmdHF14BList(const char *Cmd)
|
||||
int prev = -1;
|
||||
|
||||
for(;;) {
|
||||
if(i >= 900) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(i >= TRACE_BUFFER_SIZE) { break; }
|
||||
|
||||
bool isResponse;
|
||||
int timestamp = *((uint32_t *)(got+i));
|
||||
@@ -177,7 +175,7 @@ int CmdHF14BList(const char *Cmd)
|
||||
if(len > 100) {
|
||||
break;
|
||||
}
|
||||
if(i + len >= 900) {
|
||||
if(i + len >= TRACE_BUFFER_SIZE) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -406,20 +404,27 @@ int CmdHF14BWrite( const char *Cmd){
|
||||
bool isSrix4k = true;
|
||||
char str[20];
|
||||
|
||||
if (cmdp == 'h' || cmdp == 'H') {
|
||||
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
|
||||
PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
|
||||
PrintAndLog("");
|
||||
PrintAndLog(" sample: hf 14b write 1 127 11223344");
|
||||
PrintAndLog(" sample: hf 14b write 1 255 11223344");
|
||||
PrintAndLog(" sample: hf 14b write 2 15 11223344");
|
||||
PrintAndLog(" sample: hf 14b write 2 255 11223344");
|
||||
PrintAndLog(" [1 = SRIX4K]");
|
||||
PrintAndLog(" [2 = SRI512]");
|
||||
PrintAndLog(" [BLOCK number depends on tag, special block == FF]");
|
||||
PrintAndLog(" sample: hf 14b write 1 7F 11223344");
|
||||
PrintAndLog(" : hf 14b write 1 FF 11223344");
|
||||
PrintAndLog(" : hf 14b write 2 15 11223344");
|
||||
PrintAndLog(" : hf 14b write 2 FF 11223344");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( param_getchar(Cmd, 0) == '2' )
|
||||
if ( cmdp == '2' )
|
||||
isSrix4k = false;
|
||||
|
||||
blockno = param_get8(Cmd, 1);
|
||||
//blockno = param_get8(Cmd, 1);
|
||||
|
||||
if ( param_gethex(Cmd,1, &blockno, 2) ) {
|
||||
PrintAndLog("Block number must include 2 HEX symbols");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( isSrix4k ){
|
||||
if ( blockno > 0x7f && blockno != 0xff ){
|
||||
@@ -439,11 +444,12 @@ int CmdHF14BWrite( const char *Cmd){
|
||||
}
|
||||
|
||||
if ( blockno == 0xff)
|
||||
PrintAndLog("Writing to special block %02X [ %s]", blockno, sprint_hex(data,4) );
|
||||
PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
|
||||
else
|
||||
PrintAndLog("Writing to block %02X [ %s]", blockno, sprint_hex(data,4) );
|
||||
PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
|
||||
|
||||
sprintf(str, "-c -p 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
|
||||
|
||||
CmdHF14BCmdRaw(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user