- Added downlink reference mode option r <mode> [ 0 - (or missing) default/fixed bit, 1 - long leading, 2 - leading 0 and 3 - 1 of 4 ] to `lf t55xx detect`, `lf t55xx read`, `lf t55xx write`, and `lf t55xx bruteforce`
- Added special option `r 4` to bruteforce, to try all downlink modes (0,1,2 and 3) for each password
- `hf mfu info` now checks the NXP Originality Signature if availabe (piwi)
+- Added `hf mf personalize` to personalize the UID option of Mifare Classic EV1 cards (piwi)
## [v3.1.0][2018-10-10]
#include "iso15693.h"
#include "lfsampling.h"
#include "BigBuf.h"
+#include "mifarecmd.h"
#include "mifareutil.h"
#include "mifaresim.h"
#include "pcf7931.h"
case CMD_MIFARE_WRITEBL:
MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
+ case CMD_MIFARE_PERSONALIZE_UID:
+ MifarePersonalizeUID(c->arg[0], c->arg[1], c->d.asBytes);
+ break;
//case CMD_MIFAREU_WRITEBL_COMPAT:
//MifareUWriteBlockCompat(c->arg[0], c->d.asBytes);
//break;
void EPA_PACE_Collect_Nonce(UsbCommand * c);
void EPA_PACE_Replay(UsbCommand *c);
-// mifarecmd.h
-void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
-void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
-void MifareUC_Auth(uint8_t arg0, uint8_t *datain);
-void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, 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 MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain);
-void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
-void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain);
-void MifareChkKeys(uint16_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain);
-void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareCWipe(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); // Work with "magic Chinese" card
-void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
-void MifareCIdent(); // is "magic chinese" card?
-void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
-
-//desfire
-void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain);
-void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain);
-
// mifaredesfire.h
-bool InitDesfireCard();
-void MifareSendCommand(uint8_t arg0,uint8_t arg1, uint8_t *datain);
-void MifareDesfireGetInformation();
-void MifareDES_Auth1(uint8_t arg0,uint8_t arg1,uint8_t arg2, uint8_t *datain);
-void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain);
-int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
-size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout);
+bool InitDesfireCard();
+void MifareSendCommand(uint8_t arg0,uint8_t arg1, uint8_t *datain);
+void MifareDesfireGetInformation();
+void MifareDES_Auth1(uint8_t arg0,uint8_t arg1,uint8_t arg2, uint8_t *datain);
+void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain);
+int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
+size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout);
/// iclass.h
bool iClass_ReadBlock(uint8_t blockNo, uint8_t *readdata);
void iClass_Dump(uint8_t blockno, uint8_t numblks);
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data);
-void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType);
+void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType);
// cmd.h
bool cmd_receive(UsbCommand* cmd);
\r
#include "mifarecmd.h"\r
\r
+#include <stdint.h>\r
+\r
+#include "proxmark3.h"\r
+#include "cmd.h"\r
+#include "crapto1/crapto1.h"\r
+#include "iso14443a.h"\r
+#include "BigBuf.h"\r
+#include "mifareutil.h"\r
+#include "apps.h"\r
+#include "protocols.h"\r
#include "util.h"\r
#include "parity.h"\r
#include "crc.h"\r
#include "fpgaloader.h"\r
\r
-#define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)\r
-#define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication \r
+#define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)\r
+#define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication\r
\r
/*\r
// the block number for the ISO14443-4 PCB\r
\r
while (true) {\r
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
break;\r
};\r
\r
if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
break;\r
};\r
\r
if(mifare_classic_readblock(pcs, cuid, blockNo, dataoutbuf)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");\r
break;\r
};\r
\r
if(mifare_classic_halt(pcs, cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
break;\r
};\r
\r
// ----------------------------- crypto1 destroy\r
crypto1_destroy(pcs);\r
\r
- if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");\r
+ if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");\r
\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);\r
isOK = 1;\r
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
isOK = 0;\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
}\r
\r
\r
if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {\r
isOK = 0;\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
}\r
\r
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {\r
if(mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf + 16 * blockNo)) {\r
isOK = 0;\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Read sector %2d block %2d error", sectorNo, blockNo);\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Read sector %2d block %2d error", sectorNo, blockNo);\r
break;\r
}\r
}\r
\r
if(mifare_classic_halt(pcs, cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
}\r
\r
// ----------------------------- crypto1 destroy\r
\r
while (true) {\r
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
break;\r
};\r
\r
if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
break;\r
};\r
\r
if(mifare_classic_writeblock(pcs, cuid, blockNo, blockdata)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
break;\r
};\r
\r
if(mifare_classic_halt(pcs, cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
break;\r
};\r
\r
// ----------------------------- crypto1 destroy\r
crypto1_destroy(pcs);\r
\r
- if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
+ if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,0,0);\r
if(mifare_ultra_writeblock_compat(blockNo, blockdata)) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");\r
OnError(0);\r
- return; };\r
+ return; };\r
\r
if(mifare_ultra_halt()) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
if (!have_uid) { // need a full select cycle to get the uid first\r
iso14a_card_select_t card_info;\r
if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (ALL)");\r
continue;\r
}\r
switch (card_info.uidlen) {\r
have_uid = true;\r
} else { // no need for anticollision. We can directly select the card\r
if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Can't select card (UID)");\r
continue;\r
}\r
}\r
\r
uint32_t nt1;\r
if (mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, NULL)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth1 error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth1 error");\r
continue;\r
}\r
\r
// nested authentication\r
uint16_t len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par_enc, NULL);\r
if (len != 4) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth2 error len=%d", len);\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("AcquireNonces: Auth2 error len=%d", len);\r
continue;\r
}\r
\r
ReaderTransmit(dummy_answer, 1, NULL);\r
\r
timeout = GetCountSspClk() + HARDNESTED_AUTHENTICATION_TIMEOUT;\r
- \r
+\r
num_nonces++;\r
if (num_nonces % 2) {\r
memcpy(buf+i, receivedAnswer, 4);\r
cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));\r
LED_B_OFF();\r
\r
- if (MF_DBGLEVEL >= 3) DbpString("AcquireEncryptedNonces finished");\r
+ if (MF_DBGLEVEL >= 3) DbpString("AcquireEncryptedNonces finished");\r
\r
if (field_off) {\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
int16_t isOK = 0;\r
#define NESTED_MAX_TRIES 12\r
uint16_t unsuccessfull_tries = 0;\r
- if (calibrate) { // for first call only. Otherwise reuse previous calibration\r
+ if (calibrate) { // for first call only. Otherwise reuse previous calibration\r
LED_B_ON();\r
WDT_HIT();\r
\r
\r
// prepare next select. No need to power down the card.\r
if(mifare_classic_halt(pcs, cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error");\r
rtr--;\r
continue;\r
}\r
\r
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");\r
rtr--;\r
continue;\r
};\r
\r
auth1_time = 0;\r
if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth1 error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth1 error");\r
rtr--;\r
continue;\r
};\r
auth2_time = 0;\r
}\r
if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_NESTED, &nt2, &auth2_time)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error");\r
rtr--;\r
continue;\r
};\r
\r
- nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160\r
+ nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160\r
for (i = 101; i < 1200; i++) {\r
nttmp = prng_successor(nttmp, 1);\r
if (nttmp == nt2) break;\r
if (MF_DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i);\r
} else {\r
unsuccessfull_tries++;\r
- if (unsuccessfull_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable)\r
+ if (unsuccessfull_tries > NESTED_MAX_TRIES) { // card isn't vulnerable to nested attack (random numbers are not predictable)\r
isOK = -3;\r
}\r
}\r
\r
// prepare next select. No need to power down the card.\r
if(mifare_classic_halt(pcs, cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error");\r
continue;\r
}\r
\r
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Can't select card");\r
continue;\r
};\r
\r
auth1_time = 0;\r
if(mifare_classic_authex(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST, &nt1, &auth1_time)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth1 error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth1 error");\r
continue;\r
};\r
\r
auth2_time = auth1_time + delta_time;\r
len = mifare_sendcmd_short(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, par, &auth2_time);\r
if (len != 4) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error len=%d", len);\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Auth2 error len=%d", len);\r
continue;\r
};\r
\r
ks1 = nt2 ^ nttest;\r
\r
if (valid_nonce(nttest, nt2, ks1, par_array)){\r
- if (ncount > 0) { // we are only interested in disambiguous nonces, try again\r
+ if (ncount > 0) { // we are only interested in disambiguous nonces, try again\r
if (MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (ambigous), ntdist=%d", i+1, j);\r
target_nt[i] = 0;\r
break;\r
cmd_send(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf));\r
LED_B_OFF();\r
\r
- if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED");\r
+ if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED");\r
\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
if (set14aTimeout){\r
iso14a_set_timeout(set14aTimeout * 10); // timeout: ms = x/106 35-minimum, 50-OK 106-recommended 500-safe\r
}\r
- \r
+\r
if (multisectorCheck) {\r
TKeyIndex keyIndex = {{0}};\r
uint8_t sectorCnt = blockNo;\r
LED_A_OFF();\r
}\r
\r
+\r
+//-----------------------------------------------------------------------------\r
+// MIFARE Personalize UID. Only for Mifare Classic EV1 7Byte UID\r
+//-----------------------------------------------------------------------------\r
+void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint8_t *data) {\r
+\r
+ uint8_t uid[10];\r
+ uint32_t cuid;\r
+ struct Crypto1State mpcs = {0, 0};\r
+ struct Crypto1State *pcs;\r
+ pcs = &mpcs;\r
+\r
+ LED_A_ON();\r
+ clear_trace();\r
+\r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+\r
+ bool isOK = false;\r
+ while (true) {\r
+ if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+ break;\r
+ }\r
+\r
+ uint8_t block_number = 0;\r
+ uint64_t key = bytes_to_num(data, 6);\r
+ if (mifare_classic_auth(pcs, cuid, block_number, keyType, key, AUTH_FIRST)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Auth error");\r
+ break;\r
+ }\r
+\r
+ uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
+ uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+ int len = mifare_sendcmd_short(pcs, true, MIFARE_EV1_PERSONAL_UID, perso_option, receivedAnswer, receivedAnswerPar, NULL);\r
+ if (len != 1 || receivedAnswer[0] != CARD_ACK) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
+ break;;\r
+ }\r
+ isOK = true;\r
+ break;\r
+ }\r
+\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ LED_D_OFF();\r
+\r
+ crypto1_destroy(pcs);\r
+\r
+ if (MF_DBGLEVEL >= 2) DbpString("PERSONALIZE UID FINISHED");\r
+\r
+ cmd_send(CMD_ACK, isOK, 0, 0, NULL, 0);\r
+\r
+ LED_A_OFF();\r
+}\r
+\r
//-----------------------------------------------------------------------------\r
// MIFARE commands set debug level\r
//\r
\r
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
isOK = false;\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
}\r
\r
for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {\r
if (sectorNo == 0){\r
if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {\r
isOK = false;\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth error", sectorNo);\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth error", sectorNo);\r
break;\r
}\r
} else {\r
if(isOK && mifare_classic_auth(pcs, cuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {\r
isOK = false;\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Sector[%2d]. Auth nested error", sectorNo);\r
break;\r
}\r
}\r
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {\r
if(isOK && mifare_classic_readblock(pcs, cuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {\r
isOK = false;\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Error reading sector %2d block %2d", sectorNo, blockNo);\r
break;\r
};\r
if (isOK) {\r
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {\r
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);\r
- } else { // sector trailer, keep the keys, set only the AC\r
+ } else { // sector trailer, keep the keys, set only the AC\r
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);\r
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);\r
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);\r
}\r
\r
if(mifare_classic_halt(pcs, cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
};\r
\r
// ----------------------------- crypto1 destroy\r
bool needWipe = cmdParams & 0x01;\r
bool needFill = cmdParams & 0x02;\r
bool gen1b = cmdParams & 0x04;\r
- \r
+\r
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
- \r
+\r
uint8_t block0[16] = {0x01, 0x02, 0x03, 0x04, 0x04, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBE, 0xAF};\r
uint8_t block1[16] = {0x00};\r
uint8_t blockK[16] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x77, 0x8F, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r
uint8_t d_block[18] = {0x00};\r
- \r
+\r
// card commands\r
uint8_t wupC1[] = { 0x40 };\r
uint8_t wupC2[] = { 0x43 };\r
uint8_t wipeC[] = { 0x41 };\r
- \r
+\r
// iso14443 setup\r
LED_A_ON();\r
LED_B_OFF();\r
// tracing\r
clear_trace();\r
set_tracing(true);\r
- \r
+\r
while (true){\r
// wipe\r
if (needWipe){\r
ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
break;\r
};\r
\r
ReaderTransmit(wipeC, sizeof(wipeC), NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
break;\r
};\r
\r
if(mifare_classic_halt(NULL, 0)) {\r
- if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
};\r
};\r
- \r
+\r
// put default data\r
if (needFill){\r
// select commands\r
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);\r
\r
- // gen1b magic tag : do no issue wupC2 and don't expect 0x0a response after SELECT_UID (after getting UID from chip in 'hf mf csetuid' command)\r
- if (!gen1b) { \r
+ // gen1b magic tag : do no issue wupC2 and don't expect CARD_ACK response after SELECT_UID (after getting UID from chip in 'hf mf csetuid' command)\r
+ if (!gen1b) {\r
\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
break;\r
};\r
\r
ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
break;\r
};\r
}\r
\r
// send blocks command\r
for (int blockNo = 0; blockNo < numBlocks; blockNo++) {\r
- if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
+ if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
break;\r
};\r
- \r
+\r
// check type of block and add crc\r
if (!isBlockTrailer(blockNo)){\r
memcpy(d_block, block1, 16);\r
\r
// send write command\r
ReaderTransmit(d_block, sizeof(d_block), NULL);\r
- if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
+ if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
break;\r
};\r
}\r
- \r
+\r
// halt\r
- // do no issue halt command for gen1b \r
+ // do no issue halt command for gen1b\r
if (!gen1b) {\r
if (mifare_classic_halt(NULL, 0)) {\r
- if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
break;\r
}\r
}\r
}\r
break;\r
- } \r
+ }\r
\r
// send USB response\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,NULL,0);\r
LED_B_OFF();\r
- \r
+\r
// reset fpga\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
- \r
+\r
return;\r
}\r
\r
// get UID from chip\r
if (workFlags & 0x01) {\r
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
// Continue, if we set wrong UID or wrong UID checksum or some ATQA or SAK we will can't select card. But we need to write block 0 to make card work.\r
//break;\r
};\r
\r
if(mifare_classic_halt(NULL, cuid)) {\r
- if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
// Continue, some magic tags misbehavies and send an answer to it.\r
// break;\r
};\r
// Wipe command don't work with gen1b\r
if (needWipe && !(workFlags & 0x40)){\r
ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
break;\r
};\r
\r
ReaderTransmit(wipeC, sizeof(wipeC), NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
break;\r
};\r
\r
if(mifare_classic_halt(NULL, 0)) {\r
- if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
// Continue, some magic tags misbehavies and send an answer to it.\r
- // break;\r
+ // break;\r
};\r
};\r
\r
if (workFlags & 0x02) {\r
ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
\r
- // gen1b magic tag : do no issue wupC2 and don't expect 0x0a response after SELECT_UID (after getting UID from chip in 'hf mf csetuid' command)\r
+ // gen1b magic tag : do no issue wupC2 and don't expect CARD_ACK response after SELECT_UID (after getting UID from chip in 'hf mf csetuid' command)\r
if (!(workFlags & 0x40)) {\r
\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
break;\r
};\r
\r
ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
break;\r
};\r
}\r
}\r
\r
- if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
+ if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
break;\r
};\r
\r
AppendCrc14443a(d_block, 16);\r
\r
ReaderTransmit(d_block, sizeof(d_block), NULL);\r
- if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
+ if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
break;\r
};\r
\r
// do no issue halt command for gen1b magic tag (#db# halt error. response len: 1)\r
if (!(workFlags & 0x40)) {\r
if (mifare_classic_halt(NULL, 0)) {\r
- if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL > 2) Dbprintf("Halt error");\r
// Continue, some magic tags misbehavies and send an answer to it.\r
// break;\r
}\r
while (true) {\r
if (workFlags & 0x02) {\r
ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
break;\r
};\r
// do no issue for gen1b magic tag\r
if (!(workFlags & 0x40)) {\r
ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != CARD_ACK)) {\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
break;\r
};\r
}\r
\r
// read block\r
if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");\r
+ if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");\r
break;\r
};\r
memcpy(data, receivedAnswer, 18);\r
// do no issue halt command for gen1b magic tag (#db# halt error. response len: 1)\r
if (!(workFlags & 0x40)) {\r
if (mifare_classic_halt(NULL, cuid)) {\r
- if (MF_DBGLEVEL > 1) Dbprintf("Halt error");\r
+ if (MF_DBGLEVEL > 1) Dbprintf("Halt error");\r
// Continue, some magic tags misbehavies and send an answer to it.\r
- // break;\r
+ // break;\r
}\r
}\r
}\r
\r
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
- \r
+\r
LED_A_ON();\r
LED_B_OFF();\r
LED_C_OFF();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
clear_trace();\r
- set_tracing(true); \r
+ set_tracing(true);\r
\r
ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(ReaderReceive(receivedAnswer, receivedAnswerPar) && (receivedAnswer[0] == 0x0a)) {\r
+ if(ReaderReceive(receivedAnswer, receivedAnswerPar) && (receivedAnswer[0] == CARD_ACK)) {\r
isOK = 2;\r
\r
ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
- if(ReaderReceive(receivedAnswer, receivedAnswerPar) && (receivedAnswer[0] == 0x0a)) {\r
+ if(ReaderReceive(receivedAnswer, receivedAnswerPar) && (receivedAnswer[0] == CARD_ACK)) {\r
isOK = 1;\r
};\r
};\r
\r
// From iceman1001: removed the if, since some magic tags misbehavies and send an answer to it.\r
mifare_classic_halt(NULL, 0);\r
- \r
+\r
LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,0,0);\r
LED_B_OFF();\r
\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
- LEDsoff(); \r
+ LEDsoff();\r
}\r
\r
//\r
}\r
\r
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");\r
- cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));\r
+ cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));\r
}\r
\r
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){\r
// Routines to support ISO 14443 type A.\r
//-----------------------------------------------------------------------------\r
\r
-#ifndef __MIFARECMD_H\r
-#define __MIFARECMD_H\r
+#ifndef MIFARECMD_H__\r
+#define MIFARECMD_H__\r
\r
-#include "proxmark3.h"\r
-#include "apps.h"\r
-#include "util.h"\r
+#include <stdint.h>\r
\r
-#include "iso14443crc.h"\r
-#include "iso14443a.h"\r
-#include "crapto1/crapto1.h"\r
-#include "mifareutil.h"\r
-#include "common.h"\r
+extern void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);\r
+extern void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);\r
+extern void MifareUC_Auth(uint8_t arg0, uint8_t *datain);\r
+extern void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain);\r
+extern void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);\r
+extern void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);\r
+//extern void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain);\r
+extern void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);\r
+extern void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);\r
+extern void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain);\r
+extern void MifareChkKeys(uint16_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain);\r
+extern void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);\r
+extern void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);\r
+extern void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);\r
+extern void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);\r
+extern void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);\r
+extern void MifareCWipe(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); // Work with "magic Chinese" card\r
+extern void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);\r
+extern void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);\r
+extern void MifareCIdent(); // is "magic chinese" card?\r
+extern void MifareUSetPwd(uint8_t arg0, uint8_t *datain);\r
+extern void MifarePersonalizeUID(uint8_t keyType, uint8_t perso_option, uint8_t *datain);\r
\r
+//desfire\r
+extern void Mifare_DES_Auth1(uint8_t arg0,uint8_t *datain);\r
+extern void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain);\r
\r
-#endif
\ No newline at end of file
+#endif\r
#include "iso14443a.h"\r
#include "crapto1/crapto1.h"\r
#include "mbedtls/des.h"\r
+#include "protocols.h"\r
\r
int MF_DBGLEVEL = MF_DBG_INFO;\r
\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
\r
// Transmit MIFARE_CLASSIC_AUTH\r
- len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing);\r
+ len = mifare_sendcmd_short(pcs, isNested, keyType & 0x01 ? MIFARE_AUTH_KEYB : MIFARE_AUTH_KEYA, blockNo, receivedAnswer, receivedAnswerPar, timing);\r
if (MF_DBGLEVEL >= 4) Dbprintf("rand tag nonce len: %x", len);\r
if (len != 4) return 1;\r
\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
\r
// command MIFARE_CLASSIC_READBLOCK\r
- len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
+ len = mifare_sendcmd_short(pcs, 1, MIFARE_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
if (len == 1) {\r
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
return 1;\r
\r
if (MF_DBGLEVEL >= MF_DBG_EXTENDED)\r
Dbprintf("EV1 Auth : %02x%02x%02x%02x", key[0], key[1], key[2], key[3]);\r
- len = mifare_sendcmd(0x1B, key, sizeof(key), resp, respPar, NULL);\r
+ len = mifare_sendcmd(MIFARE_ULEV1_AUTH, key, sizeof(key), resp, respPar, NULL);\r
//len = mifare_sendcmd_short_mfuev1auth(NULL, 0, 0x1B, key, resp, respPar, NULL);\r
if (len != 4) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x %u", resp[0], len);\r
uint8_t respPar[3] = {0,0,0};\r
\r
// REQUEST AUTHENTICATION\r
- len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, resp, respPar ,NULL);\r
+ len = mifare_sendcmd_short(NULL, 1, MIFARE_ULC_AUTH_1, 0x00, resp, respPar ,NULL);\r
if (len != 11) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);\r
return 0;\r
);\r
\r
//len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, rnd_ab, resp, respPar, NULL);\r
- len = mifare_sendcmd(0xAF, rnd_ab, sizeof(rnd_ab), resp, respPar, NULL);\r
+ len = mifare_sendcmd(MIFARE_ULC_AUTH_2, rnd_ab, sizeof(rnd_ab), resp, respPar, NULL);\r
if (len != 11) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);\r
return 0;\r
int result = 0;\r
\r
for (retries = 0; retries < MFU_MAX_RETRIES; retries++) {\r
- len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
+ len = mifare_sendcmd_short(NULL, 1, MIFARE_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
if (len == 1) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
result = 1;\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
\r
// command MIFARE_CLASSIC_WRITEBLOCK\r
- len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
+ len = mifare_sendcmd_short(pcs, 1, MIFARE_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
\r
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK\r
if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);\r
uint8_t receivedAnswer[MAX_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];\r
\r
- len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
+ len = mifare_sendcmd_short(NULL, true, MIFARE_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);\r
\r
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK\r
if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
\r
- len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);\r
+ len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, ISO14443A_CMD_HALT, 0x00, receivedAnswer, receivedAnswerPar, NULL);\r
if (len != 0) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
Dbprintf("halt error. response len: %x", len);\r
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
\r
- len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);\r
+ len = mifare_sendcmd_short(NULL, true, ISO14443A_CMD_HALT, 0x00, receivedAnswer, receivedAnswerPar, NULL);\r
if (len != 0) {\r
if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
Dbprintf("halt error. response len: %x", len);\r
#include "mifare/mad.h"\r
#include "mifare/ndef.h"\r
#include "emv/dump.h"\r
+#include "protocols.h"\r
\r
#define NESTED_SECTOR_RETRY 10 // how often we try mfested() until we give up\r
\r
PrintAndLog("--block no:%d, key type:%c, key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6));\r
PrintAndLog("--data: %s", sprint_hex(bldata, 16));\r
\r
- UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};\r
+ UsbCommand c = {CMD_MIFARE_WRITEBL, {blockNo, keyType, 0}};\r
memcpy(c.d.asBytes, key, 6);\r
memcpy(c.d.asBytes + 10, bldata, 16);\r
- SendCommand(&c);\r
+ SendCommand(&c);\r
\r
UsbCommand resp;\r
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
}\r
PrintAndLog("--block no:%d, key type:%c, key:%s ", blockNo, keyType?'B':'A', sprint_hex(key, 6));\r
\r
- UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};\r
+ UsbCommand c = {CMD_MIFARE_READBL, {blockNo, keyType, 0}};\r
memcpy(c.d.asBytes, key, 6);\r
- SendCommand(&c);\r
+ SendCommand(&c);\r
\r
UsbCommand resp;\r
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
return 2;\r
}\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
int CmdHF14AMfRdSc(const char *Cmd)\r
PrintAndLog("Command execute timeout");\r
}\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
uint8_t FirstBlockOfSector(uint8_t sectorNo)\r
bool createDumpFile = 0;\r
bool singleBlock = false; // Flag to ID if a single or multi key check\r
uint8_t keyFoundCount = 0; // Counter to display the number of keys found/transfered to emulator\r
- \r
+\r
sector_t *e_sector = NULL;\r
\r
keyBlock = calloc(stKeyBlock, 6);\r
return 1;\r
};\r
}\r
- \r
+\r
parseParamTDS(Cmd, 2, &transferToEml, &createDumpFile, &btimeout14a);\r
\r
if (singleBlock & createDumpFile) {\r
uint32_t max_keys = keycnt > USB_CMD_DATA_SIZE / 6 ? USB_CMD_DATA_SIZE / 6 : keycnt;\r
\r
// !SingleKey, so all key check (if SectorsCnt > 0)\r
- if (!singleBlock) { \r
+ if (!singleBlock) {\r
PrintAndLog("To cancel this operation press the button on the proxmark...");\r
printf("--");\r
for (uint32_t c = 0; c < keycnt; c += max_keys) {\r
PrintAndLog("Command execute timeout");\r
}\r
}\r
- } else { \r
+ } else {\r
int keyAB = keyType;\r
do {\r
for (uint32_t c = 0; c < keycnt; c += max_keys) {\r
clearTraceLog = false;\r
\r
if (res != 1) {\r
- if (!res) { \r
+ if (!res) {\r
// Use the common format below\r
// PrintAndLog("Found valid key:[%d:%c]%012" PRIx64, blockNo, (keyAB & 0x01)?'B':'A', key64);\r
foundAKey = true;\r
- \r
+\r
// Store the Single Key for display list\r
// For a single block check, SectorsCnt = Sector that contains the block\r
- e_sector[SectorsCnt-1].foundKey[(keyAB & 0x01)] = true; // flag key found \r
- e_sector[SectorsCnt-1].Key[(keyAB & 0x01)] = key64; // Save key data \r
- \r
+ e_sector[SectorsCnt-1].foundKey[(keyAB & 0x01)] = true; // flag key found\r
+ e_sector[SectorsCnt-1].Key[(keyAB & 0x01)] = key64; // Save key data\r
+\r
}\r
} else {\r
PrintAndLog("Command execute timeout");\r
for (uint16_t t = 0; t < 2; t++) {\r
if (e_sector[sectorNo].foundKey[t]) {\r
num_to_bytes(e_sector[sectorNo].Key[t], 6, block + t * 10);\r
- keyFoundCount++; // Key found count for information\r
+ keyFoundCount++; // Key found count for information\r
}\r
}\r
mfEmlSetMem(block, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);\r
fclose(fkeys);\r
PrintAndLog("Found keys have been dumped to file dumpkeys.bin. 0xffffffffffff has been inserted for unknown keys.");\r
}\r
- \r
+\r
free(e_sector);\r
free(keyBlock);\r
PrintAndLog("");\r
return 0;\r
}\r
\r
- UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}};\r
- SendCommand(&c);\r
+ UsbCommand c = {CMD_MIFARE_SET_DBGMODE, {dbgMode, 0, 0}};\r
+ SendCommand(&c);\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
int CmdHF14AMfEGet(const char *Cmd)\r
PrintAndLog("Command execute timeout");\r
}\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
int CmdHF14AMfEClear(const char *Cmd)\r
return 0;\r
}\r
\r
- UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};\r
- SendCommand(&c);\r
- return 0;\r
+ UsbCommand c = {CMD_MIFARE_EML_MEMCLR, {0, 0, 0}};\r
+ SendCommand(&c);\r
+ return 0;\r
}\r
\r
\r
\r
PrintAndLog("Saved %d blocks to file: %s", numBlocks, filename);\r
\r
- return 0;\r
+ return 0;\r
}\r
\r
\r
case '\0': numSectors = 16; break;\r
case '2' : numSectors = 32; break;\r
case '4' : numSectors = 40; break;\r
- case 'd' : \r
+ case 'd' :\r
case 'D' : createDumpFile = true; break;\r
}\r
cmdp++;\r
return 0;\r
}\r
\r
-static command_t CommandTable[] =\r
-{\r
- {"help", CmdHelp, 1, "This help"},\r
- {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},\r
- {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},\r
- {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},\r
- {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},\r
- {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},\r
- {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},\r
- {"auth4", CmdHF14AMfAuth4, 0, "ISO14443-4 AES authentication"},\r
- {"chk", CmdHF14AMfChk, 0, "Test block keys"},\r
- {"mifare", CmdHF14AMifare, 0, "Read parity error messages."},\r
- {"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"},\r
- {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},\r
- {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},\r
- {"sim", CmdHF14AMfSim, 0, "Simulate MIFARE card"},\r
- {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory"},\r
- {"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"},\r
- {"eset", CmdHF14AMfESet, 0, "Set simulator memory block"},\r
- {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"},\r
- {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"},\r
- {"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},\r
- {"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},\r
- {"cwipe", CmdHF14AMfCWipe, 0, "Wipe magic Chinese card"},\r
- {"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"},\r
- {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"},\r
- {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"},\r
- {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},\r
- {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},\r
- {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},\r
- {"decrypt", CmdDecryptTraceCmds, 1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},\r
- {"mad", CmdHF14AMfMAD, 0, "Checks and prints MAD"},\r
- {"ndef", CmdHFMFNDEF, 0, "Prints NDEF records from card"},\r
- {NULL, NULL, 0, NULL}\r
+int CmdHFMFPersonalize(const char *cmd) {\r
+\r
+ CLIParserInit("hf mf personalize",\r
+ "Personalize the UID of a Mifare Classic EV1 card. This is only possible if it is a 7Byte UID card and if it is not already personalized.",\r
+ "Usage:\n\thf mf personalize UIDF0 -> double size UID according to ISO/IEC14443-3\n"\r
+ "\thf mf personalize UIDF1 -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n"\r
+ "\thf mf personalize UIDF2 -> single size random ID according to ISO/IEC14443-3\n"\r
+ "\thf mf personalize UIDF3 -> single size NUID according to ISO/IEC14443-3\n"\r
+ "\thf mf personalize -t B -k B0B1B2B3B4B5 UIDF3 -> use key B = 0xB0B1B2B3B4B5 instead of default key A\n");\r
+\r
+ void *argtable[] = {\r
+ arg_param_begin,\r
+ arg_str0("tT", "keytype", "<A|B>", "key type (A or B) to authenticate sector 0 (default: A)"),\r
+ arg_str0("kK", "key", "<key (hex 6 Bytes)>", "key to authenticate sector 0 (default: FFFFFFFFFFFF)"),\r
+ arg_str1(NULL, NULL, "<UIDF0|UIDF1|UIDF2|UIDF3>", "Personalization Option"),\r
+ arg_param_end\r
+ };\r
+ CLIExecWithReturn(cmd, argtable, true);\r
+\r
+ char keytypestr[2] = "A";\r
+ uint8_t keytype = 0x00;\r
+ int keytypestr_len;\r
+ int res = CLIParamStrToBuf(arg_get_str(1), (uint8_t*)keytypestr, 1, &keytypestr_len);\r
+ if (res || (keytypestr[0] != 'a' && keytypestr[0] != 'A' && keytypestr[0] != 'b' && keytypestr[0] != 'B')) {\r
+ PrintAndLog("ERROR: not a valid key type. Key type must be A or B");\r
+ CLIParserFree();\r
+ return 1;\r
+ }\r
+ if (keytypestr[0] == 'B' || keytypestr[0] == 'b') {\r
+ keytype = 0x01;\r
+ }\r
+\r
+ uint8_t key[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};\r
+ int key_len;\r
+ res = CLIParamHexToBuf(arg_get_str(2), key, 6, &key_len);\r
+ if (res || (!res && key_len > 0 && key_len != 6)) {\r
+ PrintAndLog("ERROR: not a valid key. Key must be 12 hex digits");\r
+ CLIParserFree();\r
+ return 1;\r
+ }\r
+\r
+ char pers_optionstr[6];\r
+ int opt_len;\r
+ uint8_t pers_option;\r
+ res = CLIParamStrToBuf(arg_get_str(3), (uint8_t*)pers_optionstr, 5, &opt_len);\r
+ if (res || (!res && opt_len > 0 && opt_len != 5)\r
+ || (strncmp(pers_optionstr, "UIDF0", 5) && strncmp(pers_optionstr, "UIDF1", 5) && strncmp(pers_optionstr, "UIDF2", 5) && strncmp(pers_optionstr, "UIDF3", 5))) {\r
+ PrintAndLog("ERROR: invalid personalization option. Must be one of UIDF0, UIDF1, UIDF2, or UIDF3");\r
+ CLIParserFree();\r
+ return 1;\r
+ }\r
+ if (!strncmp(pers_optionstr, "UIDF0", 5)) {\r
+ pers_option = MIFARE_EV1_UIDF0;\r
+ } else if (!strncmp(pers_optionstr, "UIDF1", 5)) {\r
+ pers_option = MIFARE_EV1_UIDF1;\r
+ } else if (!strncmp(pers_optionstr, "UIDF2", 5)) {\r
+ pers_option = MIFARE_EV1_UIDF2;\r
+ } else {\r
+ pers_option = MIFARE_EV1_UIDF3;\r
+ }\r
+\r
+ CLIParserFree();\r
+\r
+ UsbCommand c = {CMD_MIFARE_PERSONALIZE_UID, {keytype, pers_option, 0}};\r
+ memcpy(c.d.asBytes, key, 6);\r
+ SendCommand(&c);\r
+\r
+ UsbCommand resp;\r
+ if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {\r
+ uint8_t isOK = resp.arg[0] & 0xff;\r
+ PrintAndLog("Personalization %s", isOK ? "FAILED" : "SUCCEEDED");\r
+ } else {\r
+ PrintAndLog("Command execute timeout");\r
+ }\r
+\r
+ return 0;\r
+}\r
+\r
+\r
+static command_t CommandTable[] = {\r
+ {"help", CmdHelp, 1, "This help"},\r
+ {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},\r
+ {"rdbl", CmdHF14AMfRdBl, 0, "Read MIFARE classic block"},\r
+ {"rdsc", CmdHF14AMfRdSc, 0, "Read MIFARE classic sector"},\r
+ {"dump", CmdHF14AMfDump, 0, "Dump MIFARE classic tag to binary file"},\r
+ {"restore", CmdHF14AMfRestore, 0, "Restore MIFARE classic binary file to BLANK tag"},\r
+ {"wrbl", CmdHF14AMfWrBl, 0, "Write MIFARE classic block"},\r
+ {"auth4", CmdHF14AMfAuth4, 0, "ISO14443-4 AES authentication"},\r
+ {"chk", CmdHF14AMfChk, 0, "Test block keys"},\r
+ {"mifare", CmdHF14AMifare, 0, "Read parity error messages."},\r
+ {"hardnested", CmdHF14AMfNestedHard, 0, "Nested attack for hardened Mifare cards"},\r
+ {"nested", CmdHF14AMfNested, 0, "Test nested authentication"},\r
+ {"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},\r
+ {"sim", CmdHF14AMfSim, 0, "Simulate MIFARE card"},\r
+ {"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory"},\r
+ {"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"},\r
+ {"eset", CmdHF14AMfESet, 0, "Set simulator memory block"},\r
+ {"eload", CmdHF14AMfELoad, 0, "Load from file emul dump"},\r
+ {"esave", CmdHF14AMfESave, 0, "Save to file emul dump"},\r
+ {"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},\r
+ {"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},\r
+ {"cwipe", CmdHF14AMfCWipe, 0, "Wipe magic Chinese card"},\r
+ {"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"},\r
+ {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"},\r
+ {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"},\r
+ {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},\r
+ {"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},\r
+ {"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},\r
+ {"decrypt", CmdDecryptTraceCmds, 1, "[nt] [ar_enc] [at_enc] [data] - to decrypt snoop or trace"},\r
+ {"mad", CmdHF14AMfMAD, 0, "Checks and prints MAD"},\r
+ {"ndef", CmdHFMFNDEF, 0, "Prints NDEF records from card"},\r
+ {"personalize", CmdHFMFPersonalize, 0, "Personalize UID (Mifare Classic EV1 only)"},\r
+ {NULL, NULL, 0, NULL}\r
};\r
\r
-int CmdHFMF(const char *Cmd)\r
-{\r
+\r
+int CmdHFMF(const char *Cmd) {\r
(void)WaitForResponseTimeout(CMD_ACK,NULL,100);\r
CmdsParse(CommandTable, Cmd);\r
return 0;\r
}\r
\r
-int CmdHelp(const char *Cmd)\r
-{\r
- CmdsHelp(CommandTable);\r
- return 0;\r
+\r
+int CmdHelp(const char *Cmd) {\r
+ CmdsHelp(CommandTable);\r
+ return 0;\r
}\r
#ifndef _WIN32
#include <termios.h>
-#include <sys/ioctl.h>
+#include <sys/ioctl.h>
#include <unistd.h>
int ukbhit(void)
Ntty.c_oflag = 0x0000; // output mode
Ntty.c_lflag &= ~ICANON; // control mode = raw
Ntty.c_cc[VMIN] = 1; // return if at least 1 character is in the queue
- Ntty.c_cc[VTIME] = 0; // no timeout. Wait forever
-
+ Ntty.c_cc[VTIME] = 0; // no timeout. Wait forever
+
if (0 == (error = tcsetattr(STDIN_FILENO, TCSANOW, &Ntty))) { // set new attributes
- error += ioctl(STDIN_FILENO, FIONREAD, &cnt); // get number of characters availabe
- error += tcsetattr(STDIN_FILENO, TCSANOW, &Otty); // reset attributes
+ error += ioctl(STDIN_FILENO, FIONREAD, &cnt); // get number of characters availabe
+ error += tcsetattr(STDIN_FILENO, TCSANOW, &Otty); // reset attributes
}
return ( error == 0 ? cnt : -1 );
// log files functions
void AddLogLine(char *file, char *extData, char *c) {
FILE *fLog = NULL;
- char filename[FILE_PATH_SIZE] = {0x00};
- int len = 0;
+ char filename[FILE_PATH_SIZE] = {0x00};
+ int len = 0;
+
+ len = strlen(file);
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+ memcpy(filename, file, len);
- len = strlen(file);
- if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
- memcpy(filename, file, len);
-
fLog = fopen(filename, "a");
if (!fLog) {
printf("Could not append log file %s", filename);
void FillFileNameByUID(char *fileName, uint8_t *uid, char *ext, int byteCount) {
char * fnameptr = fileName;
-
+
for (int j = 0; j < byteCount; j++, fnameptr += 2)
- sprintf(fnameptr, "%02x", (unsigned int) uid[j]);
- sprintf(fnameptr, "%s", ext);
+ sprintf(fnameptr, "%02x", (unsigned int) uid[j]);
+ sprintf(fnameptr, "%s", ext);
}
// fill buffer from structure [{uint8_t data, size_t length},...]
*dataLength = 0;
va_list valist;
va_start(valist, dataLength);
-
+
uint8_t *vdata = NULL;
size_t vlength = 0;
do{
vdata = va_arg(valist, uint8_t *);
if (!vdata)
break;
-
+
vlength = va_arg(valist, size_t);
if (*dataLength + vlength > maxDataLength) {
va_end(valist);
return 1;
}
-
+
memcpy(&data[*dataLength], vdata, vlength);
*dataLength += vlength;
-
+
} while (vdata);
-
+
va_end(valist);
return 0;
if (strlen(value) % 2)
return false;
-
+
return true;
}
-void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, const size_t hex_max_len,
+void hex_to_buffer(const uint8_t *buf, const uint8_t *hex_data, const size_t hex_len, const size_t hex_max_len,
const size_t min_str_len, const size_t spaces_between, bool uppercase) {
-
+
char *tmp = (char *)buf;
size_t i;
memset(tmp, 0x00, hex_max_len);
int maxLen = ( hex_len > hex_max_len) ? hex_max_len : hex_len;
for (i = 0; i < maxLen; ++i, tmp += 2 + spaces_between) {
- sprintf(tmp, (uppercase) ? "%02X" : "%02x", (unsigned int) hex_data[i]);
-
+ sprintf(tmp, (uppercase) ? "%02X" : "%02x", (unsigned int) hex_data[i]);
+
for (int j = 0; j < spaces_between; j++)
sprintf(tmp + 2 + j, " ");
}
-
+
i *= (2 + spaces_between);
int minStrLen = min_str_len > i ? min_str_len : 0;
if (minStrLen > hex_max_len)
minStrLen = hex_max_len;
- for(; i < minStrLen; i++, tmp += 1)
+ for(; i < minStrLen; i++, tmp += 1)
sprintf(tmp, " ");
return;
char *sprint_hex(const uint8_t *data, const size_t len) {
static char buf[4097] = {0};
-
+
hex_to_buffer((uint8_t *)buf, data, len, sizeof(buf) - 1, 0, 1, false);
return buf;
tmp[i] = ((c < 32) || (c == 127)) ? '.' : c;
++i;
}
-
+
int minStrLen = min_str_len > i ? min_str_len : 0;
- for(; i < minStrLen; ++i)
+ for(; i < minStrLen; ++i)
tmp[i] = ' ';
-
+
return buf;
}
char *sprint_ascii(const uint8_t *data, const size_t len) {
- return sprint_ascii_ex(data, len, 0);
+ return sprint_ascii_ex(data, len, 0);
}
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest)
return num;
}
-void num_to_bytebits(uint64_t n, size_t len, uint8_t *dest) {
+void num_to_bytebits(uint64_t n, size_t len, uint8_t *dest) {
while (len--) {
dest[len] = n & 1;
n >>= 1;
//assumes little endian
char *printBits(size_t const size, void const * const ptr)
{
- unsigned char *b = (unsigned char*) ptr;
- unsigned char byte;
+ unsigned char *b = (unsigned char*) ptr;
+ unsigned char byte;
static char buf[1024];
char *tmp = buf;
- int i, j;
-
- for (i=size-1;i>=0;i--)
- {
- for (j=7;j>=0;j--)
- {
- byte = b[i] & (1<<j);
- byte >>= j;
- sprintf(tmp, "%u", (unsigned int)byte);
+ int i, j;
+
+ for (i=size-1;i>=0;i--)
+ {
+ for (j=7;j>=0;j--)
+ {
+ byte = b[i] & (1<<j);
+ byte >>= j;
+ sprintf(tmp, "%u", (unsigned int)byte);
tmp++;
- }
- }
+ }
+ }
return buf;
}
{
int i;
int len = strlen(line);
-
+
*bg = 0;
*en = 0;
-
+
// skip spaces
while (line[*bg] ==' ' || line[*bg]=='\t') (*bg)++;
if (*bg >= len) {
for (i = 0; i < paramnum; i++) {
while (line[*bg]!=' ' && line[*bg]!='\t' && line[*bg] != '\0') (*bg)++;
while (line[*bg]==' ' || line[*bg]=='\t') (*bg)++;
-
+
if (line[*bg] == '\0') return 1;
}
-
+
*en = *bg;
while (line[*en] != ' ' && line[*en] != '\t' && line[*en] != '\0') (*en)++;
-
+
(*en)--;
return 0;
int param_getlength(const char *line, int paramnum)
{
int bg, en;
-
+
if (param_getptr(line, &bg, &en, paramnum)) return 0;
return en - bg + 1;
char param_getchar_indx(const char *line, int indx, int paramnum) {
int bg, en;
-
+
if (param_getptr(line, &bg, &en, paramnum)) return 0x00;
if (bg + indx > en)
return '\0';
-
+
return line[bg + indx];
}
int bg, en;
//TODO, check more thorougly
if (!param_getptr(line, &bg, &en, paramnum)) return 1;
- // return strtoul(&line[bg], NULL, 10) & 0xff;
+ // return strtoul(&line[bg], NULL, 10) & 0xff;
return 0;
}
{
int bg, en;
- if (!param_getptr(line, &bg, &en, paramnum))
+ if (!param_getptr(line, &bg, &en, paramnum))
return strtoul(&line[bg], NULL, base) & 0xff;
else
return deflt;
{
int bg, en;
- if (!param_getptr(line, &bg, &en, paramnum))
+ if (!param_getptr(line, &bg, &en, paramnum))
return strtoul(&line[bg], NULL, base);
else
return deflt;
{
int bg, en;
- if (!param_getptr(line, &bg, &en, paramnum))
+ if (!param_getptr(line, &bg, &en, paramnum))
return strtoull(&line[bg], NULL, base);
else
return deflt;
}
-int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt)
+int param_gethex(const char *line, int paramnum, uint8_t *data, int hexcnt)
{
int bg, en, temp, i;
if (hexcnt % 2)
return 1;
-
+
if (param_getptr(line, &bg, &en, paramnum)) return 1;
- if (en - bg + 1 != hexcnt)
+ if (en - bg + 1 != hexcnt)
return 1;
for(i = 0; i < hexcnt; i += 2) {
- if (!(isxdigit((unsigned char)line[bg + i]) && isxdigit((unsigned char)line[bg + i + 1])) ) return 1;
-
+ if (!(isxdigit((unsigned char)line[bg + i]) && isxdigit((unsigned char)line[bg + i + 1])) ) return 1;
+
sscanf((char[]){line[bg + i], line[bg + i + 1], 0}, "%X", &temp);
data[i / 2] = temp & 0xff;
- }
+ }
return 0;
}
int bg, en, temp, i;
//if (hexcnt % 2)
- // return 1;
-
+ // return 1;
+
if (param_getptr(line, &bg, &en, paramnum)) return 1;
if (en - bg + 1 > *hexcnt) return 1;
-
+
*hexcnt = en - bg + 1;
if (*hexcnt % 2) //error if not complete hex bytes
return 1;
for(i = 0; i < *hexcnt; i += 2) {
- if (!(isxdigit((unsigned char)line[bg + i]) && isxdigit((unsigned char)line[bg + i + 1])) ) return 1;
-
+ if (!(isxdigit((unsigned char)line[bg + i]) && isxdigit((unsigned char)line[bg + i + 1])) ) return 1;
+
sscanf((char[]){line[bg + i], line[bg + i + 1], 0}, "%X", &temp);
data[i / 2] = temp & 0xff;
- }
+ }
return 0;
}
if (param_getptr(line, &bg, &en, paramnum)) return 1;
*datalen = 0;
-
+
int indx = bg;
while (line[indx]) {
if (line[indx] == '\t' || line[indx] == ' ') {
indx++;
continue;
}
-
+
if (isxdigit((unsigned char)line[indx])) {
buf[strlen(buf) + 1] = 0x00;
buf[strlen(buf)] = line[indx];
} else {
// if we have symbols other than spaces and hex
return 1;
- }
+ }
if (*datalen >= maxdatalen) {
// if we dont have space in buffer and have symbols to translate
*buf = 0;
(*datalen)++;
}
-
+
indx++;
}
- if (strlen(buf) > 0)
+ if (strlen(buf) > 0)
//error when not completed hex bytes
return 3;
-
+
return 0;
}
{
int bg, en;
- if (param_getptr(line, &bg, &en, paramnum)) {
+ if (param_getptr(line, &bg, &en, paramnum)) {
return 0;
}
printf("out of bounds error: want %d bytes have %zd bytes\n", en - bg + 1 + 1, buffersize);
return 0;
}
-
+
memcpy(str, line + bg, en - bg + 1);
str[en - bg + 1] = 0;
-
+
return en - bg + 1;
}
// returns number of bits converted
int hextobinarray(char *target, char *source)
{
- int length, i, count= 0;
- char* start = source;
- char x;
-
- length = strlen(source);
- // process 4 bits (1 hex digit) at a time
- while(length--)
- {
- x= *(source++);
- // capitalize
- if (x >= 'a' && x <= 'f')
- x -= 32;
- // convert to numeric value
- if (x >= '0' && x <= '9')
- x -= '0';
- else if (x >= 'A' && x <= 'F')
- x -= 'A' - 10;
- else {
- printf("Discovered unknown character %c %d at idx %tu of %s\n", x, x, source - start, start);
- return 0;
- }
- // output
- for(i= 0 ; i < 4 ; ++i, ++count)
- *(target++)= (x >> (3 - i)) & 1;
- }
-
- return count;
+ int length, i, count= 0;
+ char* start = source;
+ char x;
+
+ length = strlen(source);
+ // process 4 bits (1 hex digit) at a time
+ while(length--)
+ {
+ x= *(source++);
+ // capitalize
+ if (x >= 'a' && x <= 'f')
+ x -= 32;
+ // convert to numeric value
+ if (x >= '0' && x <= '9')
+ x -= '0';
+ else if (x >= 'A' && x <= 'F')
+ x -= 'A' - 10;
+ else {
+ printf("Discovered unknown character %c %d at idx %tu of %s\n", x, x, source - start, start);
+ return 0;
+ }
+ // output
+ for(i= 0 ; i < 4 ; ++i, ++count)
+ *(target++)= (x >> (3 - i)) & 1;
+ }
+
+ return count;
}
// convert binary array of 0x00/0x01 values to hex (safe to do in place as target will always be shorter than source)
// return number of bits converted
int binarraytohex(char *target,char *source, int length)
{
- unsigned char i, x;
- int j = length;
+ unsigned char i, x;
+ int j = length;
- if(j % 4)
- return 0;
+ if(j % 4)
+ return 0;
- while(j)
- {
- for(i= x= 0 ; i < 4 ; ++i)
- x += ( source[i] << (3 - i));
- sprintf(target,"%X", (unsigned int)x);
- ++target;
- source += 4;
- j -= 4;
- }
- return length;
+ while(j)
+ {
+ for(i= x= 0 ; i < 4 ; ++i)
+ x += ( source[i] << (3 - i));
+ sprintf(target,"%X", (unsigned int)x);
+ ++target;
+ source += 4;
+ j -= 4;
+ }
+ return length;
}
// return parity bit required to match type
uint8_t GetParity( uint8_t *bits, uint8_t type, int length)
{
- int x;
+ int x;
- for(x= 0 ; length > 0 ; --length)
- x += bits[length - 1];
- x %= 2;
+ for(x= 0 ; length > 0 ; --length)
+ x += bits[length - 1];
+ x %= 2;
- return x ^ type;
+ return x ^ type;
}
// add HID parity to binary array: EVEN prefix for 1st half of ID, ODD suffix for 2nd half
void wiegand_add_parity(uint8_t *target, uint8_t *source, uint8_t length)
{
- *(target++)= GetParity(source, EVEN, length / 2);
- memcpy(target, source, length);
- target += length;
- *(target)= GetParity(source + length / 2, ODD, length / 2);
+ *(target++)= GetParity(source, EVEN, length / 2);
+ memcpy(target, source, length);
+ target += length;
+ *(target)= GetParity(source + length / 2, ODD, length / 2);
}
// xor two arrays together for len items. The dst array contains the new xored values.
void xor(unsigned char *dst, unsigned char *src, size_t len) {
for( ; len > 0; len--,dst++,src++)
- *dst ^= *src;
+ *dst ^= *src;
}
// RotateLeft - Ultralight, Desfire, works on byte level
// 00-01-02 >> 01-02-00
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;
+ uint8_t first = data[0];
+ for (size_t i = 0; i < len-1; i++) {
+ data[i] = data[i+1];
+ }
+ data[len-1] = first;
}
// Replace unprintable characters with a dot in char buffer
void clean_ascii(unsigned char *buf, size_t len) {
for (size_t i = 0; i < len; i++) {
- if (!isprint(buf[i]))
- buf[i] = '.';
+ if (!isprint(buf[i]))
+ buf[i] = '.';
}
}
// replace char in buffer
void strcreplace(char *buf, size_t len, char from, char to) {
for (size_t i = 0; i < len; i++) {
- if (buf[i] == from)
- buf[i] = to;
+ if (buf[i] == from)
+ buf[i] = to;
}
}
if ((str = (char*) malloc(strlen(buf) + 1)) != NULL) {
memset(str, 0, strlen(buf) + 1);
strcpy(str, buf);
- }
+ }
return str;
}
#define MIFARE_CMD_TRANSFER 0xB0
#define MIFARE_EV1_PERSONAL_UID 0x40
+#define MIFARE_EV1_UIDF0 0x00
+#define MIFARE_EV1_UIDF1 0x40
+#define MIFARE_EV1_UIDF2 0x20
+#define MIFARE_EV1_UIDF3 0x60
#define MIFARE_EV1_SETMODE 0x43
#define MIFARE_ULC_WRITE 0xA2
#define CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES 0x0613
#define CMD_MIFARE_READBL 0x0620
-#define CMD_MIFAREU_READBL 0x0720
#define CMD_MIFARE_READSC 0x0621
-#define CMD_MIFAREU_READCARD 0x0721
#define CMD_MIFARE_WRITEBL 0x0622
-#define CMD_MIFAREU_WRITEBL 0x0722
-#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723
-
#define CMD_MIFARE_CHKKEYS 0x0623
-
+#define CMD_MIFARE_PERSONALIZE_UID 0x0624
#define CMD_MIFARE_SNIFFER 0x0630
+
//ultralightC
+#define CMD_MIFAREU_READBL 0x0720
+#define CMD_MIFAREU_READCARD 0x0721
+#define CMD_MIFAREU_WRITEBL 0x0722
+#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723
#define CMD_MIFAREUC_AUTH 0x0724
//0x0725 and 0x0726 no longer used
#define CMD_MIFAREUC_SETPWD 0x0727