Check keys in hf mf nested and hf mf chk (#414)

Improve hf mf chk and hf mf nested
* hf mf chk. added interrupt of procedure by usb
* extract mifare default keys into separate module
* arm side multisector `hf mf chk`
* hf mf nested. change key search procedure
* hf mf nested. added key check after we have found a key.
* small fix hf list f
* hf mf chk. add timeout (arm side) and some tweaks.
This commit is contained in:
Oleg Moiseenko 2017-10-15 22:19:34 +03:00 committed by pwpiwi
commit 275d9e61c2
14 changed files with 375 additions and 218 deletions

View file

@ -20,10 +20,6 @@
#include "parity.h"
#include "crc.h"
#define AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
#define PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication
// the block number for the ISO14443-4 PCB
static uint8_t pcb_blocknum = 0;
// Deselect card by sending a s-block. the crc is precalced for speed
@ -961,24 +957,14 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
// MIFARE check keys. key count up to 85.
//
//-----------------------------------------------------------------------------
void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
void MifareChkKeys(uint16_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
{
uint8_t blockNo = arg0 & 0xff;
uint8_t keyType = (arg0 >> 8) & 0xff;
bool clearTrace = arg1;
bool clearTrace = arg1 & 0x01;
bool multisectorCheck = arg1 & 0x02;
uint8_t set14aTimeout = (arg1 >> 8) & 0xff;
uint8_t keyCount = arg2;
uint64_t ui64Key = 0;
bool have_uid = false;
uint8_t cascade_levels = 0;
uint32_t timeout = 0;
int i;
byte_t isOK = 0;
uint8_t uid[10];
uint32_t cuid;
struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs;
pcs = &mpcs;
// clear debug level
int OLD_MF_DBGLEVEL = MF_DBGLEVEL;
@ -992,52 +978,33 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
if (clearTrace) clear_trace();
set_tracing(true);
for (i = 0; i < keyCount; i++) {
// if(mifare_classic_halt(pcs, cuid)) {
// if (MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Halt error");
// }
// Iceman: use piwi's faster nonce collecting part in hardnested.
if (!have_uid) { // need a full select cycle to get the uid first
iso14a_card_select_t card_info;
if(!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card");
--i; // try same key once again
continue;
}
switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break;
case 7 : cascade_levels = 2; break;
case 10: cascade_levels = 3; break;
default: break;
}
have_uid = true;
} else { // no need for anticollision. We can directly select the card
if(!iso14443a_select_card(uid, NULL, NULL, false, cascade_levels, true)) {
if (OLD_MF_DBGLEVEL >= 1) Dbprintf("ChkKeys: Can't select card (UID)");
--i; // try same key once again
continue;
}
}
ui64Key = bytes_to_num(datain + i * 6, 6);
if(mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
uint8_t dummy_answer = 0;
ReaderTransmit(&dummy_answer, 1, NULL);
timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT;
// wait for the card to become ready again
while(GetCountSspClk() < timeout);
continue;
}
isOK = 1;
break;
if (set14aTimeout){
iso14a_set_timeout(set14aTimeout * 10); // timeout: ms = x/106 35-minimum, 50-OK 106-recommended 500-safe
}
if (multisectorCheck) {
TKeyIndex keyIndex = {{0}};
uint8_t sectorCnt = blockNo;
int res = MifareMultisectorChk(datain, keyCount, sectorCnt, keyType, OLD_MF_DBGLEVEL, &keyIndex);
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);
LED_B_OFF();
LED_B_ON();
if (res >= 0) {
cmd_send(CMD_ACK, 1, 0, 0, keyIndex, 80);
} else {
cmd_send(CMD_ACK, 0, 0, 0, NULL, 0);
}
LED_B_OFF();
} else {
int res = MifareChkBlockKeys(datain, keyCount, blockNo, keyType, OLD_MF_DBGLEVEL);
LED_B_ON();
if (res > 0) {
cmd_send(CMD_ACK, 1, 0, 0, datain + (res - 1) * 6, 6);
} else {
cmd_send(CMD_ACK, 0, 0, 0, NULL, 0);
}
LED_B_OFF();
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();