mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-20 21:33:19 -07:00
Merge remote-tracking branch 'origin/master' into PenturaLabs-iclass-research
This commit is contained in:
commit
e6ee6c4cd1
15 changed files with 1249 additions and 734 deletions
|
@ -507,6 +507,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
|
|||
LEDsoff();
|
||||
// init trace buffer
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
// We won't start recording the frames that we acquire until we trigger;
|
||||
// a good trigger condition to get started is probably when we see a
|
||||
|
@ -1861,10 +1862,9 @@ void ReaderIso14443a(UsbCommand *c)
|
|||
if(param & ISO14A_APPEND_CRC) {
|
||||
AppendCrc14443a(cmd,len);
|
||||
len += 2;
|
||||
lenbits += 16;
|
||||
if (lenbits) lenbits += 16;
|
||||
}
|
||||
if(lenbits>0) {
|
||||
|
||||
ReaderTransmitBitsPar(cmd,lenbits,GetParity(cmd,lenbits/8), NULL);
|
||||
} else {
|
||||
ReaderTransmit(cmd,len, NULL);
|
||||
|
@ -2206,9 +2206,12 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
|
||||
if (MF_DBGLEVEL >= 1) {
|
||||
if (!_7BUID) {
|
||||
Dbprintf("4B UID: %02x%02x%02x%02x",rUIDBCC1[0] , rUIDBCC1[1] , rUIDBCC1[2] , rUIDBCC1[3]);
|
||||
Dbprintf("4B UID: %02x%02x%02x%02x",
|
||||
rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]);
|
||||
} else {
|
||||
Dbprintf("7B UID: (%02x)%02x%02x%02x%02x%02x%02x%02x",rUIDBCC1[0] , rUIDBCC1[1] , rUIDBCC1[2] , rUIDBCC1[3],rUIDBCC2[0],rUIDBCC2[1] ,rUIDBCC2[2] , rUIDBCC2[3]);
|
||||
Dbprintf("7B UID: (%02x)%02x%02x%02x%02x%02x%02x%02x",
|
||||
rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3],
|
||||
rUIDBCC2[0], rUIDBCC2[1] ,rUIDBCC2[2], rUIDBCC2[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2276,7 +2279,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
// select card
|
||||
if (len == 9 &&
|
||||
(receivedCmd[0] == 0x93 && receivedCmd[1] == 0x70 && memcmp(&receivedCmd[2], rUIDBCC1, 4) == 0)) {
|
||||
EmSendCmd(_7BUID?rSAK1:rSAK, sizeof(_7BUID?rSAK1:rSAK));
|
||||
EmSendCmd(_7BUID?rSAK1:rSAK, _7BUID?sizeof(rSAK1):sizeof(rSAK));
|
||||
cuid = bytes_to_num(rUIDBCC1, 4);
|
||||
if (!_7BUID) {
|
||||
cardSTATE = MFEMUL_WORK;
|
||||
|
@ -2318,10 +2321,13 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
|
||||
// test if auth OK
|
||||
if (cardRr != prng_successor(nonce, 64)){
|
||||
if (MF_DBGLEVEL >= 2) Dbprintf("AUTH FAILED. cardRr=%08x, succ=%08x",cardRr, prng_successor(nonce, 64));
|
||||
if (MF_DBGLEVEL >= 2) Dbprintf("AUTH FAILED for sector %d with key %c. cardRr=%08x, succ=%08x",
|
||||
cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B',
|
||||
cardRr, prng_successor(nonce, 64));
|
||||
// Shouldn't we respond anything here?
|
||||
// Right now, we don't nack or anything, which causes the
|
||||
// reader to do a WUPA after a while. /Martin
|
||||
// -- which is the correct response. /piwi
|
||||
cardSTATE_TO_IDLE();
|
||||
LogTrace(Uart.output, Uart.len, Uart.startTime*16 - DELAY_AIR2ARM_AS_TAG, Uart.parityBits, TRUE);
|
||||
LogTrace(NULL, 0, Uart.endTime*16 - DELAY_AIR2ARM_AS_TAG, 0, TRUE);
|
||||
|
@ -2335,7 +2341,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
EmSendCmd(rAUTH_AT, sizeof(rAUTH_AT));
|
||||
LED_C_ON();
|
||||
cardSTATE = MFEMUL_WORK;
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("AUTH COMPLETED. sector=%d, key=%d time=%d", cardAUTHSC, cardAUTHKEY, GetTickCount() - authTimer);
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("AUTH COMPLETED for sector %d with key %c. time=%d",
|
||||
cardAUTHSC, cardAUTHKEY == 0 ? 'A' : 'B',
|
||||
GetTickCount() - authTimer);
|
||||
break;
|
||||
}
|
||||
case MFEMUL_SELECT2:{
|
||||
|
@ -2393,12 +2401,12 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY));
|
||||
|
||||
if (!encrypted_data) { // first authentication
|
||||
if (MF_DBGLEVEL >= 2) Dbprintf("Reader authenticating for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY );
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("Reader authenticating for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY );
|
||||
|
||||
crypto1_word(pcs, cuid ^ nonce, 0);//Update crypto state
|
||||
num_to_bytes(nonce, 4, rAUTH_AT); // Send nonce
|
||||
} else { // nested authentication
|
||||
if (MF_DBGLEVEL >= 2) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY );
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("Reader doing nested authentication for block %d (0x%02x) with key %d",receivedCmd[1] ,receivedCmd[1],cardAUTHKEY );
|
||||
ans = nonce ^ crypto1_word(pcs, cuid ^ nonce, 0);
|
||||
num_to_bytes(ans, 4, rAUTH_AT);
|
||||
}
|
||||
|
@ -2429,9 +2437,9 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
|
||||
if(receivedCmd[0] == 0x30 // read block
|
||||
|| receivedCmd[0] == 0xA0 // write block
|
||||
|| receivedCmd[0] == 0xC0
|
||||
|| receivedCmd[0] == 0xC1
|
||||
|| receivedCmd[0] == 0xC2 // inc dec restore
|
||||
|| receivedCmd[0] == 0xC0 // inc
|
||||
|| receivedCmd[0] == 0xC1 // dec
|
||||
|| receivedCmd[0] == 0xC2 // restore
|
||||
|| receivedCmd[0] == 0xB0) { // transfer
|
||||
if (receivedCmd[1] >= 16 * 4) {
|
||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||
|
@ -2447,7 +2455,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
}
|
||||
// read block
|
||||
if (receivedCmd[0] == 0x30) {
|
||||
if (MF_DBGLEVEL >= 2) {
|
||||
if (MF_DBGLEVEL >= 4) {
|
||||
Dbprintf("Reader reading block %d (0x%02x)",receivedCmd[1],receivedCmd[1]);
|
||||
}
|
||||
emlGetMem(response, receivedCmd[1], 1);
|
||||
|
@ -2463,7 +2471,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
}
|
||||
// write block
|
||||
if (receivedCmd[0] == 0xA0) {
|
||||
if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0xA0 write block %d (%02x)",receivedCmd[1],receivedCmd[1]);
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("RECV 0xA0 write block %d (%02x)",receivedCmd[1],receivedCmd[1]);
|
||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK));
|
||||
cardSTATE = MFEMUL_WRITEBL2;
|
||||
cardWRBL = receivedCmd[1];
|
||||
|
@ -2471,7 +2479,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
}
|
||||
// increment, decrement, restore
|
||||
if (receivedCmd[0] == 0xC0 || receivedCmd[0] == 0xC1 || receivedCmd[0] == 0xC2) {
|
||||
if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0x%02x inc(0xC1)/dec(0xC0)/restore(0xC2) block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("RECV 0x%02x inc(0xC1)/dec(0xC0)/restore(0xC2) block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
|
||||
if (emlCheckValBl(receivedCmd[1])) {
|
||||
if (MF_DBGLEVEL >= 2) Dbprintf("Reader tried to operate on block, but emlCheckValBl failed, nacking");
|
||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||
|
@ -2489,7 +2497,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
|
|||
}
|
||||
// transfer
|
||||
if (receivedCmd[0] == 0xB0) {
|
||||
if (MF_DBGLEVEL >= 2) Dbprintf("RECV 0x%02x transfer block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
|
||||
if (MF_DBGLEVEL >= 4) Dbprintf("RECV 0x%02x transfer block %d (%02x)",receivedCmd[0],receivedCmd[1],receivedCmd[1]);
|
||||
if (emlSetValBl(cardINTREG, cardINTBLOCK, receivedCmd[1]))
|
||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||
else
|
||||
|
@ -2624,7 +2632,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
|
|||
// C(red) A(yellow) B(green)
|
||||
LEDsoff();
|
||||
// init trace buffer
|
||||
iso14a_clear_trace();
|
||||
iso14a_clear_trace();
|
||||
iso14a_set_tracing(TRUE);
|
||||
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
// The length of a received command will in most cases be no more than 18 bytes.
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "apps.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Select, Authenticaate, Read an MIFARE tag.
|
||||
// Select, Authenticate, Read a MIFARE tag.
|
||||
// read block
|
||||
//-----------------------------------------------------------------------------
|
||||
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
|
@ -35,7 +35,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
pcs = &mpcs;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
iso14a_clear_trace();
|
||||
// iso14a_set_tracing(false);
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
@ -46,22 +46,22 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
|
||||
while (true) {
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_classic_halt(pcs, cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
break;
|
||||
};
|
||||
|
||||
|
@ -74,20 +74,11 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
|
||||
|
||||
// add trace trailer
|
||||
memset(uid, 0x44, 4);
|
||||
LogTrace(uid, 4, 0, 0, TRUE);
|
||||
|
||||
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
|
||||
// memcpy(ack.d.asBytes, dataoutbuf, 16);
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
|
||||
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
|
||||
LED_B_OFF();
|
||||
|
||||
|
||||
// Thats it...
|
||||
// Thats it...
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
// iso14a_set_tracing(TRUE);
|
||||
|
@ -148,9 +139,10 @@ void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
|
|||
LEDsoff();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Select, Authenticaate, Read an MIFARE tag.
|
||||
// read sector (data = 4 x 16 bytes = 64 bytes)
|
||||
// Select, Authenticate, Read a MIFARE tag.
|
||||
// read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes)
|
||||
//-----------------------------------------------------------------------------
|
||||
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
{
|
||||
|
@ -161,8 +153,8 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
ui64Key = bytes_to_num(datain, 6);
|
||||
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
byte_t dataoutbuf[16 * 4];
|
||||
byte_t isOK;
|
||||
byte_t dataoutbuf[16 * 16];
|
||||
uint8_t uid[10];
|
||||
uint32_t cuid;
|
||||
struct Crypto1State mpcs = {0, 0};
|
||||
|
@ -170,7 +162,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
pcs = &mpcs;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
iso14a_clear_trace();
|
||||
// iso14a_set_tracing(false);
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
@ -179,72 +171,47 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
while (true) {
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
isOK = 1;
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
isOK = 0;
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf + 16 * 0)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 0 error");
|
||||
break;
|
||||
};
|
||||
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf + 16 * 1)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 1 error");
|
||||
break;
|
||||
};
|
||||
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf + 16 * 2)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 2 error");
|
||||
break;
|
||||
};
|
||||
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf + 16 * 3)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 3 error");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_classic_halt(pcs, cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
break;
|
||||
};
|
||||
|
||||
isOK = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
|
||||
isOK = 0;
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");
|
||||
}
|
||||
|
||||
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
|
||||
if(mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf + 16 * blockNo)) {
|
||||
isOK = 0;
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read sector %2d block %2d error", sectorNo, blockNo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(mifare_classic_halt(pcs, cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------- crypto1 destroy
|
||||
crypto1_destroy(pcs);
|
||||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");
|
||||
|
||||
// add trace trailer
|
||||
memset(uid, 0x44, 4);
|
||||
LogTrace(uid, 4, 0, 0, TRUE);
|
||||
|
||||
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
|
||||
// memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,32);
|
||||
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
|
||||
// SpinDelay(100);
|
||||
|
||||
// memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);
|
||||
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16*NumBlocksPerSector(sectorNo));
|
||||
LED_B_OFF();
|
||||
|
||||
// Thats it...
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
// iso14a_set_tracing(TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void MifareUReadCard(uint8_t arg0, uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
|
@ -288,25 +255,19 @@ void MifareUReadCard(uint8_t arg0, uint8_t *datain)
|
|||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");
|
||||
|
||||
// add trace trailer
|
||||
memset(uid, 0x44, 4);
|
||||
LogTrace(uid, 4, 0, 0, TRUE);
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);
|
||||
//cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);
|
||||
LED_B_OFF();
|
||||
|
||||
// Thats it...
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
// iso14a_set_tracing(TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Select, Authenticaate, Read an MIFARE tag.
|
||||
// Select, Authenticate, Write a MIFARE tag.
|
||||
// read block
|
||||
//-----------------------------------------------------------------------------
|
||||
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||
|
@ -368,15 +329,8 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||
|
||||
// add trace trailer
|
||||
memset(uid, 0x44, 4);
|
||||
LogTrace(uid, 4, 0, 0, TRUE);
|
||||
|
||||
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
|
||||
LED_B_OFF();
|
||||
|
||||
|
||||
|
@ -387,6 +341,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
|
||||
}
|
||||
|
||||
|
||||
void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
|
||||
{
|
||||
// params
|
||||
|
@ -433,13 +388,8 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
|
|||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||
|
||||
// add trace trailer
|
||||
memset(uid, 0x44, 4);
|
||||
LogTrace(uid, 4, 0, 0, TRUE);
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
LED_B_OFF();
|
||||
|
||||
|
||||
|
@ -447,71 +397,67 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
|
|||
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];
|
||||
|
||||
// params
|
||||
uint8_t blockNo = arg0;
|
||||
byte_t blockdata[4];
|
||||
|
||||
memcpy(blockdata, datain,4);
|
||||
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
uint8_t uid[10];
|
||||
uint32_t cuid;
|
||||
// variables
|
||||
byte_t isOK = 0;
|
||||
uint8_t uid[10];
|
||||
uint32_t cuid;
|
||||
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
// iso14a_set_tracing(false);
|
||||
// clear trace
|
||||
iso14a_clear_trace();
|
||||
// iso14a_set_tracing(false);
|
||||
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
|
||||
LED_A_ON();
|
||||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
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;
|
||||
};
|
||||
while (true) {
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
|
||||
break;
|
||||
};
|
||||
if(mifare_ultra_special_writeblock(cuid, blockNo, blockdata)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
|
||||
break;
|
||||
};
|
||||
|
||||
if(mifare_ultra_halt(cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
break;
|
||||
};
|
||||
if(mifare_ultra_halt(cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
break;
|
||||
};
|
||||
|
||||
isOK = 1;
|
||||
break;
|
||||
}
|
||||
isOK = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||
|
||||
// add trace trailer
|
||||
memset(uid, 0x44, 4);
|
||||
LogTrace(uid, 4, 0, 0, TRUE);
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
|
||||
LED_B_OFF();
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||
LED_B_OFF();
|
||||
|
||||
|
||||
// Thats it...
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
// Thats it...
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
// iso14a_set_tracing(TRUE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Return 1 if the nonce is invalid else return 0
|
||||
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
|
||||
return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \
|
||||
|
@ -520,7 +466,6 @@ int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, byte_t * parity) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MIFARE nested authentication.
|
||||
//
|
||||
|
@ -769,18 +714,11 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
LED_B_OFF();
|
||||
LED_C_OFF();
|
||||
|
||||
// SpinDelay(300);
|
||||
for (i = 0; i < keyCount; i++) {
|
||||
// FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
// SpinDelay(100);
|
||||
// FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
|
||||
// prepare next select by sending a HALT. There is no need to power down the card.
|
||||
if(mifare_classic_halt(pcs, cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Halt error");
|
||||
}
|
||||
|
||||
// SpinDelay(50);
|
||||
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card");
|
||||
break;
|
||||
|
@ -798,10 +736,6 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
|||
// ----------------------------- crypto1 destroy
|
||||
crypto1_destroy(pcs);
|
||||
|
||||
// add trace trailer
|
||||
memset(uid, 0x44, 4);
|
||||
LogTrace(uid, 4, 0, 0, TRUE);
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);
|
||||
LED_B_OFF();
|
||||
|
@ -823,6 +757,7 @@ void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
|||
Dbprintf("Debug level: %d", MF_DBGLEVEL);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Work with emulator memory
|
||||
//
|
||||
|
@ -831,29 +766,29 @@ void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
|||
emlClearMem();
|
||||
}
|
||||
|
||||
|
||||
void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
|
||||
emlSetMem(datain, arg0, arg1); // data, block num, blocks count
|
||||
}
|
||||
|
||||
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
|
||||
// UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};
|
||||
|
||||
byte_t buf[48];
|
||||
emlGetMem(buf, arg0, arg1); // data, block num, blocks count
|
||||
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
|
||||
|
||||
byte_t buf[48];
|
||||
emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4)
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,arg0,arg1,0,buf,48);
|
||||
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
|
||||
cmd_send(CMD_ACK,arg0,arg1,0,buf,48);
|
||||
LED_B_OFF();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Load a card into the emulator memory
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
|
||||
int i;
|
||||
uint8_t sectorNo = 0;
|
||||
uint8_t numSectors = arg0;
|
||||
uint8_t keyType = arg1;
|
||||
uint64_t ui64Key = 0;
|
||||
uint32_t cuid;
|
||||
|
@ -876,63 +811,51 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
|||
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;
|
||||
};
|
||||
bool isOK = true;
|
||||
|
||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||
isOK = false;
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
sectorNo = i;
|
||||
ui64Key = emlGetKey(sectorNo, keyType);
|
||||
|
||||
if (!i){
|
||||
if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_FIRST)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth error", i);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(mifare_classic_auth(pcs, cuid, sectorNo * 4, keyType, ui64Key, AUTH_NESTED)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%d]. Auth nested error", i);
|
||||
break;
|
||||
for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {
|
||||
ui64Key = emlGetKey(sectorNo, keyType);
|
||||
if (sectorNo == 0){
|
||||
if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
|
||||
isOK = false;
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth error", sectorNo);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {
|
||||
isOK = false;
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
|
||||
if(isOK && mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
|
||||
isOK = false;
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);
|
||||
break;
|
||||
};
|
||||
if (isOK) {
|
||||
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
|
||||
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
||||
} else { // sector trailer, keep the keys, set only the AC
|
||||
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
||||
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
|
||||
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 0, dataoutbuf)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 0 error");
|
||||
break;
|
||||
};
|
||||
emlSetMem(dataoutbuf, sectorNo * 4 + 0, 1);
|
||||
|
||||
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 1, dataoutbuf)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 1 error");
|
||||
break;
|
||||
};
|
||||
emlSetMem(dataoutbuf, sectorNo * 4 + 1, 1);
|
||||
|
||||
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 2, dataoutbuf)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 2 error");
|
||||
break;
|
||||
};
|
||||
emlSetMem(dataoutbuf, sectorNo * 4 + 2, 1);
|
||||
|
||||
// get block 3 bytes 6-9
|
||||
if(mifare_classic_readblock(pcs, cuid, sectorNo * 4 + 3, dataoutbuf)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Read block 3 error");
|
||||
break;
|
||||
};
|
||||
emlGetMem(dataoutbuf2, sectorNo * 4 + 3, 1);
|
||||
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
|
||||
emlSetMem(dataoutbuf2, sectorNo * 4 + 3, 1);
|
||||
}
|
||||
|
||||
if(mifare_classic_halt(pcs, cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
break;
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(mifare_classic_halt(pcs, cuid)) {
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
||||
};
|
||||
|
||||
// ----------------------------- crypto1 destroy
|
||||
crypto1_destroy(pcs);
|
||||
|
@ -942,16 +865,8 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
|||
|
||||
if (MF_DBGLEVEL >= 2) DbpString("EMUL FILL SECTORS FINISHED");
|
||||
|
||||
// add trace trailer
|
||||
memset(uid, 0x44, 4);
|
||||
LogTrace(uid, 4, 0, 0, TRUE);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MIFARE 1k emulator
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)
|
||||
|
@ -1074,22 +989,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
|||
break;
|
||||
}
|
||||
|
||||
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
|
||||
// if (isOK) memcpy(ack.d.asBytes, uid, 4);
|
||||
|
||||
// add trace trailer
|
||||
/**
|
||||
* Removed by Martin, the uid is overwritten with 0x44,
|
||||
* which can 't be intended.
|
||||
*
|
||||
* memset(uid, 0x44, 4);
|
||||
* LogTrace(uid, 4, 0, 0, TRUE);
|
||||
**/
|
||||
|
||||
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,uid,4);
|
||||
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
|
||||
cmd_send(CMD_ACK,isOK,0,0,uid,4);
|
||||
LED_B_OFF();
|
||||
|
||||
if ((workFlags & 0x10) || (!isOK)) {
|
||||
|
@ -1099,6 +1000,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
|
||||
|
||||
// params
|
||||
|
@ -1171,20 +1073,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
|||
break;
|
||||
}
|
||||
|
||||
// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};
|
||||
// if (isOK) memcpy(ack.d.asBytes, data, 18);
|
||||
|
||||
// add trace trailer
|
||||
/*
|
||||
* Removed by Martin, this piece of overwrites the 'data' variable
|
||||
* which is sent two lines down, and is obviously not correct.
|
||||
*
|
||||
* memset(data, 0x44, 4);
|
||||
* LogTrace(data, 4, 0, 0, TRUE);
|
||||
*/
|
||||
LED_B_ON();
|
||||
cmd_send(CMD_ACK,isOK,0,0,data,18);
|
||||
// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));
|
||||
cmd_send(CMD_ACK,isOK,0,0,data,18);
|
||||
LED_B_OFF();
|
||||
|
||||
if ((workFlags & 0x10) || (!isOK)) {
|
||||
|
|
|
@ -453,6 +453,27 @@ int mifare_ultra_halt(uint32_t uid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards),
|
||||
// plus evtl. 8 sectors with 16 blocks each (4k cards)
|
||||
uint8_t NumBlocksPerSector(uint8_t sectorNo)
|
||||
{
|
||||
if (sectorNo < 32)
|
||||
return 4;
|
||||
else
|
||||
return 16;
|
||||
}
|
||||
|
||||
uint8_t FirstBlockOfSector(uint8_t sectorNo)
|
||||
{
|
||||
if (sectorNo < 32)
|
||||
return sectorNo * 4;
|
||||
else
|
||||
return 32*4 + (sectorNo - 32) * 16;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// work with emulator memory
|
||||
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) {
|
||||
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
|
||||
|
@ -522,7 +543,7 @@ uint64_t emlGetKey(int sectorNum, int keyType) {
|
|||
uint8_t key[6];
|
||||
uint8_t* emCARD = eml_get_bigbufptr_cardmem();
|
||||
|
||||
memcpy(key, emCARD + 3 * 16 + sectorNum * 4 * 16 + keyType * 10, 6);
|
||||
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
|
||||
return bytes_to_num(key, 6);
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,10 @@ uint8_t* mifare_get_bigbufptr(void);
|
|||
uint8_t* eml_get_bigbufptr_sendbuf(void);
|
||||
uint8_t* eml_get_bigbufptr_recbuf(void);
|
||||
|
||||
// Mifare memory structure
|
||||
uint8_t NumBlocksPerSector(uint8_t sectorNo);
|
||||
uint8_t FirstBlockOfSector(uint8_t sectorNo);
|
||||
|
||||
// emulator functions
|
||||
void emlClearMem(void);
|
||||
void emlSetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue