|
|
|
|
@@ -42,30 +42,36 @@ static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t act
|
|
|
|
|
| ((sector_trailer[8] >> 7) & 0x01);
|
|
|
|
|
switch (action) {
|
|
|
|
|
case AC_KEYA_READ: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYA_READ");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsTrailerAccessAllowed: AC_KEYA_READ");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
case AC_KEYA_WRITE: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYA_WRITE");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsTrailerAccessAllowed: AC_KEYA_WRITE");
|
|
|
|
|
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01))
|
|
|
|
|
|| (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03)));
|
|
|
|
|
}
|
|
|
|
|
case AC_KEYB_READ: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYB_READ");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsTrailerAccessAllowed: AC_KEYB_READ");
|
|
|
|
|
return (keytype == AUTHKEYA && (AC == 0x00 || AC == 0x02 || AC == 0x01));
|
|
|
|
|
}
|
|
|
|
|
case AC_KEYB_WRITE: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYB_WRITE");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsTrailerAccessAllowed: AC_KEYB_WRITE");
|
|
|
|
|
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01))
|
|
|
|
|
|| (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03)));
|
|
|
|
|
}
|
|
|
|
|
case AC_AC_READ: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_AC_READ");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsTrailerAccessAllowed: AC_AC_READ");
|
|
|
|
|
return ((keytype == AUTHKEYA)
|
|
|
|
|
|| (keytype == AUTHKEYB && !(AC == 0x00 || AC == 0x02 || AC == 0x01)));
|
|
|
|
|
}
|
|
|
|
|
case AC_AC_WRITE: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_AC_WRITE");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsTrailerAccessAllowed: AC_AC_WRITE");
|
|
|
|
|
return ((keytype == AUTHKEYA && (AC == 0x01))
|
|
|
|
|
|| (keytype == AUTHKEYB && (AC == 0x03 || AC == 0x05)));
|
|
|
|
|
}
|
|
|
|
|
@@ -93,46 +99,54 @@ static bool IsDataAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action
|
|
|
|
|
AC = ((sector_trailer[7] >> 2) & 0x04)
|
|
|
|
|
| ((sector_trailer[8] << 1) & 0x02)
|
|
|
|
|
| ((sector_trailer[8] >> 4) & 0x01);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: case 0x00 - %02x", AC);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsDataAccessAllowed: case 0x00 - %02x", AC);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x01: {
|
|
|
|
|
AC = ((sector_trailer[7] >> 3) & 0x04)
|
|
|
|
|
| ((sector_trailer[8] >> 0) & 0x02)
|
|
|
|
|
| ((sector_trailer[8] >> 5) & 0x01);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: case 0x01 - %02x", AC);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsDataAccessAllowed: case 0x01 - %02x", AC);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 0x02: {
|
|
|
|
|
AC = ((sector_trailer[7] >> 4) & 0x04)
|
|
|
|
|
| ((sector_trailer[8] >> 1) & 0x02)
|
|
|
|
|
| ((sector_trailer[8] >> 6) & 0x01);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: case 0x02 - %02x", AC);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsDataAccessAllowed: case 0x02 - %02x", AC);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: Error");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsDataAccessAllowed: Error");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (action) {
|
|
|
|
|
case AC_DATA_READ: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed - AC_DATA_READ: OK");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsDataAccessAllowed - AC_DATA_READ: OK");
|
|
|
|
|
return ((keytype == AUTHKEYA && !(AC == 0x03 || AC == 0x05 || AC == 0x07))
|
|
|
|
|
|| (keytype == AUTHKEYB && !(AC == 0x07)));
|
|
|
|
|
}
|
|
|
|
|
case AC_DATA_WRITE: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed - AC_DATA_WRITE: OK");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsDataAccessAllowed - AC_DATA_WRITE: OK");
|
|
|
|
|
return ((keytype == AUTHKEYA && (AC == 0x00))
|
|
|
|
|
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x04 || AC == 0x06 || AC == 0x03)));
|
|
|
|
|
}
|
|
|
|
|
case AC_DATA_INC: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed - AC_DATA_INC: OK");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("IsDataAccessAllowed - AC_DATA_INC: OK");
|
|
|
|
|
return ((keytype == AUTHKEYA && (AC == 0x00))
|
|
|
|
|
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06)));
|
|
|
|
|
}
|
|
|
|
|
case AC_DATA_DEC_TRANS_REST: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("AC_DATA_DEC_TRANS_REST: OK");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("AC_DATA_DEC_TRANS_REST: OK");
|
|
|
|
|
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x06 || AC == 0x01))
|
|
|
|
|
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06 || AC == 0x01)));
|
|
|
|
|
}
|
|
|
|
|
@@ -257,7 +271,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
|
|
|
|
if ((flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { // get UID from datain
|
|
|
|
|
memcpy(rUIDBCC1, datain, 4);
|
|
|
|
|
*uid_len = 4;
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MifareSimInit - FLAG_4B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_4B_UID_IN_DATA, flags, rUIDBCC1);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("MifareSimInit - FLAG_4B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_4B_UID_IN_DATA, flags, rUIDBCC1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// save CUID
|
|
|
|
|
@@ -275,7 +290,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
|
|
|
|
memcpy(&rUIDBCC1[1], datain, 3);
|
|
|
|
|
memcpy(rUIDBCC2, datain + 3, 4);
|
|
|
|
|
*uid_len = 7;
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MifareSimInit - FLAG_7B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_7B_UID_IN_DATA, flags, rUIDBCC1);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("MifareSimInit - FLAG_7B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_7B_UID_IN_DATA, flags, rUIDBCC1);
|
|
|
|
|
|
|
|
|
|
// save CUID
|
|
|
|
|
*cuid = bytes_to_num(rUIDBCC2, 4);
|
|
|
|
|
@@ -297,7 +313,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
|
|
|
|
memcpy(&rUIDBCC2[1], datain + 3, 3);
|
|
|
|
|
memcpy(rUIDBCC3, datain + 6, 4);
|
|
|
|
|
*uid_len = 10;
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MifareSimInit - FLAG_10B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_10B_UID_IN_DATA, flags, rUIDBCC1);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("MifareSimInit - FLAG_10B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_10B_UID_IN_DATA, flags, rUIDBCC1);
|
|
|
|
|
|
|
|
|
|
// save CUID
|
|
|
|
|
*cuid = bytes_to_num(rUIDBCC3, 4);
|
|
|
|
|
@@ -520,18 +537,21 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
|
|
|
|
if (res == 2) { //Field is off!
|
|
|
|
|
LEDsoff();
|
|
|
|
|
cardSTATE = MFEMUL_NOFIELD;
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("cardSTATE = MFEMUL_NOFIELD");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("cardSTATE = MFEMUL_NOFIELD");
|
|
|
|
|
continue;
|
|
|
|
|
} else if (res == 1) { // button pressed
|
|
|
|
|
button_pushed = true;
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Button pressed");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("Button pressed");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// WUPA in HALTED state or REQA or WUPA in any other state
|
|
|
|
|
if (receivedCmd_len == 1 && ((receivedCmd[0] == ISO14443A_CMD_REQA && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == ISO14443A_CMD_WUPA)) {
|
|
|
|
|
selTimer = GetTickCount();
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("EmSendPrecompiledCmd(&responses[ATQA]);");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("EmSendPrecompiledCmd(&responses[ATQA]);");
|
|
|
|
|
EmSendPrecompiledCmd(&responses[ATQA]);
|
|
|
|
|
|
|
|
|
|
// init crypto block
|
|
|
|
|
@@ -550,12 +570,15 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
|
|
|
|
|
|
|
|
|
switch (cardSTATE) {
|
|
|
|
|
case MFEMUL_NOFIELD:
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_NOFIELD");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("MFEMUL_NOFIELD");
|
|
|
|
|
case MFEMUL_HALTED:
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_HALTED");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("MFEMUL_HALTED");
|
|
|
|
|
case MFEMUL_IDLE: {
|
|
|
|
|
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_IDLE");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("MFEMUL_IDLE");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -649,7 +672,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
|
|
|
|
// WORK
|
|
|
|
|
case MFEMUL_WORK: {
|
|
|
|
|
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Enter in case");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("[MFEMUL_WORK] Enter in case");
|
|
|
|
|
|
|
|
|
|
if (receivedCmd_len == 0) {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
|
|
|
|
|
@@ -898,7 +922,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
|
|
|
|
LED_C_OFF();
|
|
|
|
|
cardSTATE = MFEMUL_HALTED;
|
|
|
|
|
cardAUTHKEY = AUTHKEYNONE;
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_HALTED");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_HALTED");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -911,10 +936,12 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
|
|
|
|
EmSendCmdPar(response, rats_len, response_par);
|
|
|
|
|
} else
|
|
|
|
|
EmSendCmd(rats, rats_len);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => ACK");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("[MFEMUL_WORK] RCV RATS => ACK");
|
|
|
|
|
} else {
|
|
|
|
|
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => NACK");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("[MFEMUL_WORK] RCV RATS => NACK");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@@ -929,28 +956,33 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
|
|
|
|
EmSendCmdPar(response, receivedCmd_len, response_par);
|
|
|
|
|
} else
|
|
|
|
|
EmSendCmd(receivedCmd_dec, receivedCmd_len);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK");
|
|
|
|
|
} else {
|
|
|
|
|
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK");
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// case MFEMUL_WORK => command not allowed
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Received command not allowed, nacking");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("Received command not allowed, nacking");
|
|
|
|
|
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// AUTH1
|
|
|
|
|
case MFEMUL_AUTH1: {
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_AUTH1] Enter case");
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("[MFEMUL_AUTH1] Enter case");
|
|
|
|
|
|
|
|
|
|
if (receivedCmd_len != 8) {
|
|
|
|
|
cardSTATE_TO_IDLE();
|
|
|
|
|
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len);
|
|
|
|
|
if (DBGLEVEL >= DBG_EXTENDED)
|
|
|
|
|
Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|