From 50193c1e3eb7f904bdc4be84618b1b045539597b Mon Sep 17 00:00:00 2001 From: "Merlokbr@gmail.com" Date: Wed, 1 Jun 2011 14:12:11 +0000 Subject: [PATCH] 1. small bugfix in hf 14a mifare 2. now in cmd hf 14a mifare - blinks LED_C 3. bugfix in readblock 2. bugfix in USB CommandReceived 3. small improvements --- armsrc/iso14443a.c | 119 +++++++++++++++++++++++++++++++------------- armsrc/mifareutil.h | 10 ++++ client/cmdhf14a.c | 74 ++++++++++++++++++++++----- client/cmdhf14a.h | 3 ++ client/cmdmain.c | 7 ++- 5 files changed, 166 insertions(+), 47 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 7b709ab0..b64a1942 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1693,7 +1693,7 @@ void ReaderMifare(uint32_t parameter) byte_t par_mask = 0xff; byte_t par_low = 0; int led_on = TRUE; - uint8_t uid[7]; + uint8_t uid[8]; uint32_t cuid; tracing = FALSE; @@ -1702,13 +1702,15 @@ void ReaderMifare(uint32_t parameter) byte_t par_list[8] = {0,0,0,0,0,0,0,0}; byte_t ks_list[8] = {0,0,0,0,0,0,0,0}; num_to_bytes(parameter, 4, nt_attacked); - int isOK = 0; + int isOK = 0, isNULL = 0; while(TRUE) { + LED_C_ON(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(200); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + LED_C_OFF(); // Test if the action was cancelled if(BUTTON_PRESS()) { @@ -1730,6 +1732,9 @@ void ReaderMifare(uint32_t parameter) // Receive 4 bit answer if (ReaderReceive(receivedAnswer)) { + isNULL = (nt_attacked[0] = 0) && (nt_attacked[1] = 0) && (nt_attacked[2] = 0) && (nt_attacked[3] = 0); + if ( (isNULL != 0 ) && (memcmp(nt, nt_attacked, 4) != 0) ) continue; + if (nt_diff == 0) { LED_A_ON(); @@ -1738,8 +1743,6 @@ void ReaderMifare(uint32_t parameter) par_low = par & 0x07; } - if (memcmp(nt, nt_attacked, 4) != 0) continue; - led_on = !led_on; if(led_on) LED_B_ON(); else LED_B_OFF(); par_list[nt_diff] = par; @@ -1801,7 +1804,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // variables byte_t isOK = 0; byte_t dataoutbuf[16]; - uint8_t uid[7]; + uint8_t uid[8]; uint32_t cuid; struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; @@ -2075,7 +2078,8 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // variables uint8_t targetBlockNo = blockNo + 1; - int rtr, i, m, len; + uint8_t targetKeyType = keyType; + int rtr, i, j, m, len; int davg, dmin, dmax; uint8_t uid[8]; uint32_t cuid, nt1, nt2, nttmp, nttest, par, ks1; @@ -2083,6 +2087,7 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) nestedVector nvector[3][10]; int nvectorcount[3] = {10, 10, 10}; int ncount = 0; + UsbCommand ack = {CMD_ACK, {0, 0, 0}}; struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; @@ -2156,8 +2161,8 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) LED_C_ON(); // get crypted nonces for target sector - for (rtr = 0; rtr < 4; rtr++) { - Dbprintf("------------------------------"); + for (rtr = 0; rtr < 2; rtr++) { +// Dbprintf("------------------------------"); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(100); @@ -2179,14 +2184,14 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) }; // nested authentication - len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (keyType & 0x01), targetBlockNo, receivedAnswer, &par); + len = mifare_sendcmd_shortex(pcs, AUTH_NESTED, 0x60 + (targetKeyType & 0x01), targetBlockNo, receivedAnswer, &par); if (len != 4) { Dbprintf("Auth2 error len=%d", len); break; }; nt2 = bytes_to_num(receivedAnswer, 4); - Dbprintf("r=%d nt1=%08x nt2enc=%08x nt2par=%08x", rtr, nt1, nt2, par); +// Dbprintf("r=%d nt1=%08x nt2enc=%08x nt2par=%08x", rtr, nt1, nt2, par); // ----------------------- test /* uint32_t d_nt, d_ks1, d_ks2, d_ks3, reader_challenge; @@ -2234,23 +2239,25 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) ncount++; nvectorcount[2] = ncount; - Dbprintf("valid m=%d ks1=%08x nttest=%08x", m, ks1, nttest); +// Dbprintf("valid m=%d ks1=%08x nttest=%08x", m, ks1, nttest); } } // select vector with length less than got - m = 2; - if (nvectorcount[2] < nvectorcount[1]) m = 1; - if (nvectorcount[2] < nvectorcount[0]) m = 0; - if (m != 2) { - for (i = 0; i < nvectorcount[m]; i++) { - nvector[m][i] = nvector[2][i]; + if (nvectorcount[2] != 0) { + m = 2; + if (nvectorcount[2] < nvectorcount[1]) m = 1; + if (nvectorcount[2] < nvectorcount[0]) m = 0; + if (m != 2) { + for (i = 0; i < nvectorcount[m]; i++) { + nvector[m][i] = nvector[2][i]; + } + nvectorcount[m] = nvectorcount[2]; } - nvectorcount[m] = nvectorcount[2]; } - Dbprintf("vector count: 1=%d 2=%d 3=%d", nvectorcount[0], nvectorcount[1], nvectorcount[2]); +// Dbprintf("vector count: 1=%d 2=%d 3=%d", nvectorcount[0], nvectorcount[1], nvectorcount[2]); } LED_C_OFF(); @@ -2267,27 +2274,36 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) LogTrace(uid, 4, 0, 0, TRUE); for (i = 0; i < 2; i++) { - ncount = nvectorcount[i]; - if (ncount > 5) ncount = 5; //!!!!! needs to be 2 packets x 5 pairs (nt,ks1) - - // isEOF = 0 - UsbCommand ack = {CMD_ACK, {0, ncount, targetBlockNo}}; - memcpy(ack.d.asBytes, &cuid, 4); - for (m = 0; m < 5; m++) { - memcpy(ack.d.asBytes + 4 + m * 8 + 0, &nvector[i][m].nt, 4); - memcpy(ack.d.asBytes + 4 + m * 8 + 4, &nvector[i][m].ks1, 4); - } + for (j = 0; j < nvectorcount[i]; j += 5) { + ncount = nvectorcount[i] - j; + if (ncount > 5) ncount = 5; + + ack.arg[0] = 0; // isEOF = 0 + ack.arg[1] = ncount; + ack.arg[2] = targetBlockNo + (targetKeyType * 0x100); + memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes)); + + memcpy(ack.d.asBytes, &cuid, 4); + for (m = 0; m < ncount; m++) { + memcpy(ack.d.asBytes + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4); + memcpy(ack.d.asBytes + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4); + } - LED_B_ON(); - UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand)); - LED_B_OFF(); + LED_B_ON(); + SpinDelay(100); + UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand)); + LED_B_OFF(); + } } // finalize list - // isEOF = 1 - UsbCommand ack = {CMD_ACK, {1, 0, 0}}; + ack.arg[0] = 1; // isEOF = 1 + ack.arg[1] = 0; + ack.arg[2] = 0; + memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes)); LED_B_ON(); + SpinDelay(300); UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand)); LED_B_OFF(); @@ -2306,4 +2322,39 @@ void MifareNested(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) //----------------------------------------------------------------------------- void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { + int cardSTATE = MFEMUL_NOFIELD; + + while (true) { + + if(BUTTON_PRESS()) { + break; + } + + switch (cardSTATE) { + case MFEMUL_NOFIELD:{ + break; + } + case MFEMUL_IDLE:{ + break; + } + case MFEMUL_SELECT1:{ + break; + } + case MFEMUL_SELECT2:{ + break; + } + case MFEMUL_AUTH1:{ + break; + } + case MFEMUL_AUTH2:{ + break; + } + case MFEMUL_HALTED:{ + break; + } + + } + + } + } diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index d3307bb7..715dfe63 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -15,6 +15,16 @@ #define AUTH_FIRST 0 #define AUTH_NESTED 2 +//mifare emulate states +#define MFEMUL_NOFIELD 0 +#define MFEMUL_IDLE 1 +#define MFEMUL_SELECT1 2 +#define MFEMUL_SELECT2 3 +#define MFEMUL_AUTH1 4 +#define MFEMUL_AUTH2 5 +#define MFEMUL_HALTED 6 + +//functions uint8_t* mifare_get_bigbufptr(void); int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer); int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint32_t * parptr); diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index e0b1c3a9..46cfbebe 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -444,14 +444,19 @@ int CmdHF14AMfRdSc(const char *Cmd) int CmdHF14AMfNested(const char *Cmd) { - int i, temp; + int i, temp, len; uint8_t sectorNo = 0; uint8_t keyType = 0; uint8_t key[6] = {0, 0, 0, 0, 0, 0}; + uint8_t isEOF; + uint8_t * data; + uint32_t uid; + fnVector * vector = NULL; + int lenVector = 0; + UsbCommand * resp = NULL; const char *cmdp = Cmd; - if (strlen(Cmd)<3) { PrintAndLog("Usage: hf 14a nested "); PrintAndLog(" sample: hf 14a nested 0 A FFFFFFFFFFFF "); @@ -485,24 +490,69 @@ int CmdHF14AMfNested(const char *Cmd) cmdp++; } PrintAndLog(" sector no:%02x key type:%02x key:%s ", sectorNo, keyType, sprint_hex(key, 6)); + + // flush queue + while (WaitForResponseTimeout(CMD_ACK, 500) != NULL) ; UsbCommand c = {CMD_MIFARE_NESTED, {sectorNo, keyType, 0}}; memcpy(c.d.asBytes, key, 6); SendCommand(&c); - UsbCommand * resp = WaitForResponseTimeout(CMD_ACK, 1500); - PrintAndLog(" "); - if (resp != NULL) { - uint8_t isOK = resp->arg[0] & 0xff; - uint8_t * data = resp->d.asBytes; + PrintAndLog("\n"); + printf("-------------------------------------------------------------------------\n"); - PrintAndLog("isOk:%02x", isOK); - for (i = 0; i < 2; i++) { - PrintAndLog("data:%s", sprint_hex(data + i * 16, 16)); + // wait cycle + while (true) { + printf("."); + if (kbhit()) { + getchar(); + printf("\naborted via keyboard!\n"); + break; + } + + resp = WaitForResponseTimeout(CMD_ACK, 1500); + + if (resp != NULL) { + isEOF = resp->arg[0] & 0xff; + data = resp->d.asBytes; + + PrintAndLog("isEOF:%02x", isEOF); + for (i = 0; i < 2; i++) { + PrintAndLog("data:%s", sprint_hex(data + i * 16, 16)); + } + if (isEOF) break; + + len = resp->arg[1] & 0xff; + if (len == 0) continue; + + memcpy(&uid, resp->d.asBytes, 4); + PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%d", uid, len, resp->arg[2] & 0xff, (resp->arg[2] >> 8) & 0xff); + + vector = (fnVector *) realloc((void *)vector, (lenVector + len) * sizeof(fnVector) + 200); + if (vector == NULL) { + PrintAndLog("Memory allocation error for fnVector. len: %d bytes: %d", lenVector + len, (lenVector + len) * sizeof(fnVector)); + break; + } + + for (i = 0; i < len; i++) { + vector[lenVector + i].blockNo = resp->arg[2] & 0xff; + vector[lenVector + i].keyType = (resp->arg[2] >> 8) & 0xff; + vector[lenVector + i].uid = uid; + + memcpy(&vector[lenVector + i].nt, (void *)(resp->d.asBytes + 8 + i * 8 + 0), 4); + memcpy(&vector[lenVector + i].ks1, (void *)(resp->d.asBytes + 8 + i * 8 + 4), 4); + + PrintAndLog("i=%d nt:%08x ks1:%08x", i, vector[lenVector + i].nt, vector[lenVector + i].ks1); + } + + lenVector += len; } - } else { - PrintAndLog("Command execute timeout"); } + + + + // finalize + free(vector); return 0; } diff --git a/client/cmdhf14a.h b/client/cmdhf14a.h index eaab18cb..fdb8b959 100644 --- a/client/cmdhf14a.h +++ b/client/cmdhf14a.h @@ -1,4 +1,5 @@ //----------------------------------------------------------------------------- +// 2011, Merlok // Copyright (C) 2010 iZsh // // This code is licensed to you under the terms of the GNU GPL, version 2 or, @@ -11,6 +12,8 @@ #ifndef CMDHF14A_H__ #define CMDHF14A_H__ +typedef struct fnVector { uint8_t blockNo, keyType; uint32_t uid, nt, ks1; } fnVector; + int CmdHF14A(const char *Cmd); int CmdHF14AList(const char *Cmd); diff --git a/client/cmdmain.c b/client/cmdmain.c index 3388d75f..c27d8406 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -26,6 +26,7 @@ unsigned int current_command = CMD_UNKNOWN; unsigned int received_command = CMD_UNKNOWN; UsbCommand current_response; +UsbCommand current_response_user; static int CmdHelp(const char *Cmd); static int CmdQuit(const char *Cmd); @@ -55,12 +56,16 @@ int CmdQuit(const char *Cmd) } UsbCommand * WaitForResponseTimeout(uint32_t response_type, uint32_t ms_timeout) { - UsbCommand * ret = ¤t_response; + UsbCommand * ret = NULL; int i=0; for(i=0; received_command != response_type && i < ms_timeout / 10; i++) { msleep(10); // XXX ugh } + + // There was evil BUG + memcpy(¤t_response_user, ¤t_response, sizeof(UsbCommand)); + ret = ¤t_response_user; if(received_command != response_type) ret = NULL; -- 2.39.2