Introduce compatible write support to hf mfu wrbl

This commit is contained in:
Ave 2020-09-07 22:34:44 +03:00
commit f1146d360f
No known key found for this signature in database
GPG key ID: 398DD7BD03276F6D
7 changed files with 106 additions and 22 deletions

View file

@ -1237,6 +1237,10 @@ static void PacketReceived(PacketCommandNG *packet) {
MifareUWriteBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); MifareUWriteBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
break; break;
} }
case CMD_HF_MIFAREU_WRITEBL_COMPAT: {
MifareUWriteBlockCompat(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes);
break;
}
case CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES: { case CMD_HF_MIFARE_ACQ_ENCRYPTED_NONCES: {
MifareAcquireEncryptedNonces(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes); MifareAcquireEncryptedNonces(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes);
break; break;

View file

@ -554,6 +554,75 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
set_tracing(false); set_tracing(false);
} }
// Arg0 : Block to write to.
// Arg1 : 0 = use no authentication.
// 1 = use 0x1A authentication.
// 2 = use 0x1B authentication.
// datain : 16 first bytes is data to be written.
// : 4/16 next bytes is authentication key.
void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
uint8_t blockNo = arg0;
bool useKey = (arg1 == 1); //UL_C
bool usePwd = (arg1 == 2); //UL_EV1/NTAG
uint8_t blockdata[16] = {0x00};
memcpy(blockdata, datain, 16);
LEDsoff();
LED_A_ON();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace();
set_tracing(true);
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Can't select card");
OnError(0);
return;
};
// UL-C authentication
if (useKey) {
uint8_t key[16] = {0x00};
memcpy(key, datain + 16, sizeof(key));
if (!mifare_ultra_auth(key)) {
OnError(1);
return;
}
}
// UL-EV1 / NTAG authentication
if (usePwd) {
uint8_t pwd[4] = {0x00};
memcpy(pwd, datain + 16, 4);
uint8_t pack[4] = {0, 0, 0, 0};
if (!mifare_ul_ev1_auth(pwd, pack)) {
OnError(1);
return;
}
}
if (mifare_ultra_writeblock_compat(blockNo, blockdata)) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Write block error");
OnError(0);
return;
};
if (mifare_ultra_halt()) {
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error");
OnError(0);
return;
};
if (DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
set_tracing(false);
}
void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { void MifareUSetPwd(uint8_t arg0, uint8_t *datain) {
uint8_t pwd[16] = {0x00}; uint8_t pwd[16] = {0x00};

View file

@ -20,7 +20,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes);
void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, 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 *datain); void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
//void MifareUWriteBlockCompat(uint8_t arg0,uint8_t *datain); void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key); void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key);

View file

@ -446,37 +446,37 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
return 0; return 0;
} }
/* // command not needed, but left for future testing
int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) { int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
uint16_t len; // variables
uint8_t par[3] = {0}; // enough for 18 parity bits uint16_t len = 0;
uint8_t d_block[18] = {0x00};
uint8_t receivedAnswer[MAX_FRAME_SIZE]; uint8_t d_block[18];
uint8_t receivedAnswerPar[MAX_PARITY_SIZE]; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE] = {0x00};
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL); len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (DBGLEVEL >= DBG_ERROR) if (DBGLEVEL >= DBG_ERROR)
Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]); Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0], len);
return 1; return 1;
} }
memcpy(d_block, blockData, 16); memcpy(d_block, blockData, 16);
AddCrc14A(d_block, 16); AddCrc14A(d_block, 16);
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL); ReaderTransmit(d_block, sizeof(d_block), NULL);
// Receive the response
len = ReaderReceive(receivedAnswer, receivedAnswerPar); len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
if (DBGLEVEL >= DBG_ERROR) if (DBGLEVEL >= DBG_ERROR)
Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len); Dbprintf("Cmd Send Data Error: %02x %d", receivedAnswer[0], len);
return 2; return 2;
} }
return 0; return 0;
} }
*/
int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) {
uint16_t len = 0; uint16_t len = 0;

View file

@ -73,7 +73,7 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack); int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack);
int mifare_ultra_auth(uint8_t *keybytes); int mifare_ultra_auth(uint8_t *keybytes);
int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData); int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData);
//int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData); int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData); int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData);
int mifare_ultra_halt(void); int mifare_ultra_halt(void);

View file

@ -1474,8 +1474,9 @@ static int CmdHF14AMfUWrBl(const char *Cmd) {
uint8_t cmdp = 0; uint8_t cmdp = 0;
uint8_t keylen = 0; uint8_t keylen = 0;
uint8_t blockdata[20] = {0x00}; uint8_t blockdata[16] = {0x00};
uint8_t data[16] = {0x00}; uint8_t data[16] = {0x00};
uint8_t datalen = 4;
uint8_t authenticationkey[16] = {0x00}; uint8_t authenticationkey[16] = {0x00};
uint8_t *authKeyPtr = authenticationkey; uint8_t *authKeyPtr = authenticationkey;
@ -1517,9 +1518,13 @@ static int CmdHF14AMfUWrBl(const char *Cmd) {
break; break;
case 'd': case 'd':
if (param_gethex(Cmd, cmdp + 1, blockdata, 8)) { if (param_gethex(Cmd, cmdp + 1, blockdata, 8)) {
PrintAndLogEx(WARNING, "Block data must include 8 HEX symbols"); if (param_gethex(Cmd, cmdp + 1, blockdata, 32)) {
errors = true; PrintAndLogEx(WARNING, "Block data must include 8 or 32 HEX symbols");
break; errors = true;
break;
} else {
datalen = 16;
}
} }
cmdp += 2; cmdp += 2;
break; break;
@ -1559,9 +1564,8 @@ static int CmdHF14AMfUWrBl(const char *Cmd) {
PrintAndLogEx(NORMAL, "Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4)); PrintAndLogEx(NORMAL, "Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
//Send write Block //Send write Block
uint8_t cmddata[20]; uint8_t cmddata[32];
memcpy(cmddata, blockdata, 4); memcpy(cmddata, blockdata, datalen);
uint8_t datalen = 4;
uint8_t keytype = 0; uint8_t keytype = 0;
if (hasAuthKey) { if (hasAuthKey) {
keytype = 1; keytype = 1;
@ -1574,7 +1578,13 @@ static int CmdHF14AMfUWrBl(const char *Cmd) {
} }
clearCommandBuffer(); clearCommandBuffer();
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, blockNo, keytype, 0, cmddata, datalen); if (datalen == 16) {
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL_COMPAT, blockNo, keytype, 0, cmddata, datalen);
}
else
{
SendCommandMIX(CMD_HF_MIFAREU_WRITEBL, blockNo, keytype, 0, cmddata, datalen);
}
PacketResponseNG resp; PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
uint8_t isOK = resp.oldarg[0] & 0xff; uint8_t isOK = resp.oldarg[0] & 0xff;

View file

@ -618,6 +618,7 @@ typedef struct {
#define CMD_HF_MIFAREU_READCARD 0x0721 #define CMD_HF_MIFAREU_READCARD 0x0721
#define CMD_HF_MIFARE_WRITEBL 0x0622 #define CMD_HF_MIFARE_WRITEBL 0x0622
#define CMD_HF_MIFAREU_WRITEBL 0x0722 #define CMD_HF_MIFAREU_WRITEBL 0x0722
#define CMD_HF_MIFAREU_WRITEBL_COMPAT 0x0723
#define CMD_HF_MIFARE_CHKKEYS 0x0623 #define CMD_HF_MIFARE_CHKKEYS 0x0623
#define CMD_HF_MIFARE_SETMOD 0x0624 #define CMD_HF_MIFARE_SETMOD 0x0624