Skip to content

Commit

Permalink
fix hf mf cload - now it allows for proper GDM ic to load mfc ev1 s…
Browse files Browse the repository at this point in the history
…ignature data. On uscuid ic which are more locked down it will failed with a message. Dont forget to enable signature for the gdm ic.
  • Loading branch information
iceman1001 committed Jan 15, 2025
1 parent f0bdcf3 commit cb7109e
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 13 deletions.
35 changes: 24 additions & 11 deletions armsrc/mifarecmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -2704,8 +2704,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
while (true) {
// read UID and return to client with write
if (workFlags & MAGIC_UID) {
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == 0) {
if (g_dbglevel >= DBG_INFO) Dbprintf("Can't select card");
errormsg = MAGIC_UID;
mifare_classic_halt(NULL);
break;
Expand All @@ -2717,7 +2717,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
if (workFlags & MAGIC_WIPE) {
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
if (g_dbglevel >= DBG_INFO) Dbprintf("wupC1 error");
errormsg = MAGIC_WIPE;
break;
}
Expand All @@ -2730,7 +2730,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {

ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wipeC error");
if (g_dbglevel >= DBG_INFO) Dbprintf("wipeC error");
errormsg = MAGIC_WIPE;
break;
}
Expand All @@ -2742,14 +2742,14 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
if (workFlags & MAGIC_GDM_ALT_WUPC) {
ReaderTransmitBitsPar(wupGDM1, 7, NULL, NULL);
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM1 error");
if (g_dbglevel >= DBG_INFO) Dbprintf("wupGDM1 error");
errormsg = MAGIC_WUPC;
break;
}

ReaderTransmit(wupGDM2, sizeof(wupC2), NULL);
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM2 error");
if (g_dbglevel >= DBG_INFO) Dbprintf("wupGDM2 error");
errormsg = MAGIC_WUPC;
break;
}
Expand All @@ -2774,18 +2774,31 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
}
}

if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("write block send command error");
errormsg = 4;
break;
// Write signature blocks using GDM write command
if (blockNo >= MIFARE_1K_MAXBLOCK && blockNo < MIFARE_1K_EV1_MAXBLOCK) {

blockNo %= 0x40;
if ((mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_MAGIC_GDM_WRITEBLOCK, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_INFO) Dbprintf("Magic write block send command error");
errormsg = 4;
break;
}

} else {

if ((mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_INFO) Dbprintf("write block send command error");
errormsg = 5;
break;
}
}

memcpy(data, datain, 16);
AddCrc14A(data, 16);

ReaderTransmit(data, sizeof(data), NULL);
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("write block send data error");
if (g_dbglevel >= DBG_INFO) Dbprintf("write block send data error");
errormsg = 0;
break;
}
Expand Down
14 changes: 14 additions & 0 deletions armsrc/mifareutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,27 @@
#define MIFARE_4K_MAXBLOCK 256
#define MIFARE_2K_MAXBLOCK 128
#define MIFARE_1K_MAXBLOCK 64
#define MIFARE_1K_EV1_MAXBLOCK (MIFARE_1K_MAXBLOCK + 8)
#define MIFARE_MINI_MAXBLOCK 20

#define MIFARE_MINI_MAXSECTOR 5
#define MIFARE_1K_MAXSECTOR 16
#define MIFARE_1K_EV1_MAXSECTOR (MIFARE_1K_MAXSECTOR + 2)
#define MIFARE_2K_MAXSECTOR 32
#define MIFARE_4K_MAXSECTOR 40

#define MIFARE_4K_MAX_BYTES 4096
#define MIFARE_2K_MAX_BYTES 2048
#define MIFARE_1K_MAX_BYTES 1024
#define MIFARE_1K_EV1_MAX_BYTES (MIFARE_1K_MAX_BYTES + 128)
#define MIFARE_MINI_MAX_BYTES 320

#define MIFARE_MINI_MAX_KEY_SIZE (MIFARE_MINI_MAXSECTOR * 2 * MIFARE_KEY_SIZE)
#define MIFARE_1K_MAX_KEY_SIZE (MIFARE_1K_MAXSECTOR * 2 * MIFARE_KEY_SIZE)
#define MIFARE_1K_EV1_MAX_KEY_SIZE (MIFARE_1K_EV1_MAXSECTOR * 2 * MIFARE_KEY_SIZE)
#define MIFARE_2K_MAX_KEY_SIZE (MIFARE_2K_MAXSECTOR * 2 * MIFARE_KEY_SIZE)
#define MIFARE_4K_MAX_KEY_SIZE (MIFARE_4K_MAXSECTOR * 2 * MIFARE_KEY_SIZE)

#define MIFARE_BLOCK_SIZE 16

//mifare emulator states
Expand Down
1 change: 1 addition & 0 deletions client/src/cmdhfmf.c
Original file line number Diff line number Diff line change
Expand Up @@ -5498,6 +5498,7 @@ static int CmdHF14AMfCLoad(const char *Cmd) {

if (mf_chinese_set_block(blockno, data + (MFBLOCK_SIZE * blockno), NULL, flags)) {
PrintAndLogEx(WARNING, "Can't set magic card block: %d", blockno);
PrintAndLogEx(HINT, "Verify that it is a GDM and not USCUID deriviate");
free(data);
return PM3_ESOFT;
}
Expand Down
15 changes: 13 additions & 2 deletions client/src/mifare/mifarehost.c
Original file line number Diff line number Diff line change
Expand Up @@ -1211,16 +1211,27 @@ int mf_chinese_set_block(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t p
SendCommandMIX(CMD_HF_MIFARE_CSETBL, params, blockNo, 0, data, MFBLOCK_SIZE);
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 3500)) {
uint8_t isOK = resp.oldarg[0] & 0xff;
uint8_t isOK = resp.oldarg[0] & 0xFF;
if (uid != NULL) {
memcpy(uid, resp.data.asBytes, 4);
}

if (!isOK) {

uint8_t reason = (resp.oldarg[1] & 0xFF);
if ( reason == 4) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(WARNING, "GDM magic write signature block failed");
} else if (reason == 5) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(WARNING, "Write block failed");
}

return PM3_EUNDEF;
}
} else {
PrintAndLogEx(WARNING, "command execution time out");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(WARNING, "Command execution time out");
return PM3_ETIMEOUT;
}
return PM3_SUCCESS;
Expand Down

0 comments on commit cb7109e

Please sign in to comment.