mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
chg 'hf mf nested' - uses NG. chg 'hw tune' - now also prints the 'lf config q' divisor voltage.
This commit is contained in:
parent
eccf0d3bbc
commit
5d3eb444fb
8 changed files with 175 additions and 89 deletions
|
@ -143,11 +143,25 @@ uint16_t AvgAdc(int ch) {
|
||||||
|
|
||||||
void MeasureAntennaTuning(void) {
|
void MeasureAntennaTuning(void) {
|
||||||
|
|
||||||
uint8_t LF_Results[256];
|
uint32_t peak = 0;
|
||||||
uint32_t i, peak = 0, peakv = 0, peakf = 0;
|
|
||||||
uint32_t v_lf125 = 0, v_lf134 = 0, v_hf = 0; // in mV
|
// in mVolt
|
||||||
|
struct p {
|
||||||
|
uint32_t v_lf134;
|
||||||
|
uint32_t v_lf125;
|
||||||
|
uint32_t v_lfconf;
|
||||||
|
uint32_t v_hf;
|
||||||
|
uint32_t peak_v;
|
||||||
|
uint32_t peak_f;
|
||||||
|
int divisor;
|
||||||
|
uint8_t results[256];
|
||||||
|
} PACKED payload;
|
||||||
|
|
||||||
|
memset(payload.results, 0, sizeof(payload.results));
|
||||||
|
|
||||||
|
sample_config *sc = getSamplingConfig();
|
||||||
|
payload.divisor = sc->divisor;
|
||||||
|
|
||||||
memset(LF_Results, 0, sizeof(LF_Results));
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -163,21 +177,26 @@ void MeasureAntennaTuning(void) {
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||||
SpinDelay(50);
|
SpinDelay(50);
|
||||||
|
|
||||||
for (i = 255; i >= 19; i--) {
|
for (uint8_t i = 255; i >= 19; i--) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
|
||||||
SpinDelay(20);
|
SpinDelay(20);
|
||||||
uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
|
uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
|
||||||
if (i == 95)
|
if (i == 96)
|
||||||
v_lf125 = adcval; // voltage at 125kHz
|
payload.v_lf125 = adcval; // voltage at 125kHz
|
||||||
if (i == 89)
|
|
||||||
v_lf134 = adcval; // voltage at 134kHz
|
|
||||||
|
|
||||||
LF_Results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes
|
if (i == 89)
|
||||||
if (LF_Results[i] > peak) {
|
payload.v_lf134 = adcval; // voltage at 134kHz
|
||||||
peakv = adcval;
|
|
||||||
peakf = i;
|
if (i == sc->divisor)
|
||||||
peak = LF_Results[i];
|
payload.v_lfconf = adcval; // voltage at `lf config q`
|
||||||
|
|
||||||
|
payload.results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes
|
||||||
|
|
||||||
|
if (payload.results[i] > peak) {
|
||||||
|
payload.peak_v = adcval;
|
||||||
|
payload.peak_f = i;
|
||||||
|
peak = payload.results[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,23 +205,16 @@ void MeasureAntennaTuning(void) {
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
|
||||||
SpinDelay(50);
|
SpinDelay(50);
|
||||||
v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
|
|
||||||
|
payload.v_hf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
|
||||||
|
|
||||||
// RDV40 will hit the roof, try other ADC channel used in that hardware revision.
|
// RDV40 will hit the roof, try other ADC channel used in that hardware revision.
|
||||||
if (v_hf > MAX_ADC_HF_VOLTAGE - 300) {
|
if (payload.v_hf > MAX_ADC_HF_VOLTAGE - 300) {
|
||||||
v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10;
|
payload.v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t arg0 = v_lf134;
|
|
||||||
arg0 <<= 32;
|
|
||||||
arg0 |= v_lf125;
|
|
||||||
|
|
||||||
uint64_t arg2 = peakv;
|
|
||||||
arg2 <<= 32;
|
|
||||||
arg2 |= peakf;
|
|
||||||
|
|
||||||
reply_mix(CMD_MEASURE_ANTENNA_TUNING, arg0, v_hf, arg2, LF_Results, 256);
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
reply_ng(CMD_MEASURE_ANTENNA_TUNING, PM3_SUCCESS, (uint8_t*)&payload, sizeof(payload));
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1083,7 +1095,16 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_MIFARE_NESTED: {
|
case CMD_HF_MIFARE_NESTED: {
|
||||||
MifareNested(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2], packet->data.asBytes);
|
struct p {
|
||||||
|
uint8_t block;
|
||||||
|
uint8_t keytype;
|
||||||
|
uint8_t target_block;
|
||||||
|
uint8_t target_keytype;
|
||||||
|
bool calibrate;
|
||||||
|
uint8_t key[6];
|
||||||
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
MifareNested(payload->block, payload->keytype, payload->target_block, payload->target_keytype, payload->calibrate, payload->key);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_HF_MIFARE_CHKKEYS: {
|
case CMD_HF_MIFARE_CHKKEYS: {
|
||||||
|
|
|
@ -24,11 +24,11 @@ Default LF config is set to:
|
||||||
divisor = 95 (125kHz)
|
divisor = 95 (125kHz)
|
||||||
trigger_threshold = 0
|
trigger_threshold = 0
|
||||||
*/
|
*/
|
||||||
sample_config config = { 1, 8, 1, 95, 0, 0 } ;
|
sample_config config = { 1, 8, 1, 96, 0, 0 } ;
|
||||||
|
|
||||||
void printConfig() {
|
void printConfig() {
|
||||||
DbpString(_BLUE_("LF Sampling config"));
|
DbpString(_BLUE_("LF Sampling config"));
|
||||||
Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d kHz")")", config.divisor, 12000 / (config.divisor + 1));
|
Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d kHz")")", config.divisor, 12000 / config.divisor);
|
||||||
Dbprintf(" [b] bps.................%d", config.bits_per_sample);
|
Dbprintf(" [b] bps.................%d", config.bits_per_sample);
|
||||||
Dbprintf(" [d] decimation..........%d", config.decimation);
|
Dbprintf(" [d] decimation..........%d", config.decimation);
|
||||||
Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No");
|
Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No");
|
||||||
|
@ -151,7 +151,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
||||||
uint16_t checker = 0;
|
uint16_t checker = 0;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (checker == 1000) {
|
if (checker == 2000) {
|
||||||
if (BUTTON_PRESS() || data_available())
|
if (BUTTON_PRESS() || data_available())
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
|
|
|
@ -866,26 +866,20 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
|
||||||
// MIFARE nested authentication.
|
// MIFARE nested authentication.
|
||||||
//
|
//
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) {
|
void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key) {
|
||||||
// params
|
|
||||||
uint8_t blockNo = arg0 & 0xff;
|
|
||||||
uint8_t keyType = (arg0 >> 8) & 0xff;
|
|
||||||
uint8_t targetBlockNo = arg1 & 0xff;
|
|
||||||
uint8_t targetKeyType = (arg1 >> 8) & 0xff;
|
|
||||||
// calibrate = arg2
|
|
||||||
uint64_t ui64Key = 0;
|
uint64_t ui64Key = 0;
|
||||||
|
ui64Key = bytes_to_num(key, 6);
|
||||||
ui64Key = bytes_to_num(datain, 6);
|
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
uint16_t i, j, len;
|
uint16_t i, j, len;
|
||||||
static uint16_t dmin, dmax;
|
static uint16_t dmin, dmax;
|
||||||
|
|
||||||
|
uint8_t par[1] = {0x00};
|
||||||
|
uint8_t par_array[4] = {0x00};
|
||||||
uint8_t uid[10] = {0x00};
|
uint8_t uid[10] = {0x00};
|
||||||
uint32_t cuid = 0, nt1, nt2, nttest, ks1;
|
uint32_t cuid = 0, nt1, nt2, nttest, ks1;
|
||||||
uint8_t par[1] = {0x00};
|
|
||||||
uint32_t target_nt[2] = {0x00}, target_ks[2] = {0x00};
|
uint32_t target_nt[2] = {0x00}, target_ks[2] = {0x00};
|
||||||
|
|
||||||
uint8_t par_array[4] = {0x00};
|
|
||||||
uint16_t ncount = 0;
|
uint16_t ncount = 0;
|
||||||
struct Crypto1State mpcs = {0, 0};
|
struct Crypto1State mpcs = {0, 0};
|
||||||
struct Crypto1State *pcs;
|
struct Crypto1State *pcs;
|
||||||
|
@ -903,13 +897,15 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
if (arg2) clear_trace();
|
if (calibrate)
|
||||||
|
clear_trace();
|
||||||
|
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
// statistics on nonce distance
|
// statistics on nonce distance
|
||||||
int16_t isOK = 0;
|
int16_t isOK = 0;
|
||||||
#define NESTED_MAX_TRIES 12
|
#define NESTED_MAX_TRIES 12
|
||||||
if (arg2) { // calibrate: for first call only. Otherwise reuse previous calibration
|
if (calibrate) { // calibrate: for first call only. Otherwise reuse previous calibration
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
@ -1061,15 +1057,28 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
||||||
|
|
||||||
crypto1_destroy(pcs);
|
crypto1_destroy(pcs);
|
||||||
|
|
||||||
uint8_t buf[4 + 4 * 4] = {0};
|
struct p {
|
||||||
memcpy(buf, &cuid, 4);
|
int16_t isOK;
|
||||||
memcpy(buf + 4, &target_nt[0], 4);
|
uint8_t block;
|
||||||
memcpy(buf + 8, &target_ks[0], 4);
|
uint8_t keytype;
|
||||||
memcpy(buf + 12, &target_nt[1], 4);
|
uint8_t cuid[4];
|
||||||
memcpy(buf + 16, &target_ks[1], 4);
|
uint8_t nt_a[4];
|
||||||
|
uint8_t ks_a[4];
|
||||||
|
uint8_t nt_b[4];
|
||||||
|
uint8_t ks_b[4];
|
||||||
|
} PACKED payload;
|
||||||
|
payload.isOK = isOK;
|
||||||
|
payload.block = targetBlockNo;
|
||||||
|
payload.keytype = targetKeyType;
|
||||||
|
|
||||||
|
memcpy(payload.cuid, &cuid, 4);
|
||||||
|
memcpy(payload.nt_a, &target_nt[0], 4);
|
||||||
|
memcpy(payload.ks_a, &target_ks[0], 4);
|
||||||
|
memcpy(payload.nt_b, &target_nt[1], 4);
|
||||||
|
memcpy(payload.ks_b, &target_ks[1], 4);
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
reply_mix(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf));
|
reply_ng(CMD_HF_MIFARE_NESTED, PM3_SUCCESS, (uint8_t*)&payload, sizeof(payload));
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
|
||||||
if (DBGLEVEL >= 3) DbpString("NESTED FINISHED");
|
if (DBGLEVEL >= 3) DbpString("NESTED FINISHED");
|
||||||
|
|
|
@ -21,8 +21,10 @@ 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 *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(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key);
|
||||||
|
|
||||||
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain);
|
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain);
|
||||||
void MifareAcquireNonces(uint32_t arg0, uint32_t flags);
|
void MifareAcquireNonces(uint32_t arg0, uint32_t flags);
|
||||||
void MifareChkKeys(uint8_t *datain);
|
void MifareChkKeys(uint8_t *datain);
|
||||||
|
|
|
@ -1654,52 +1654,69 @@ int CmdTuneSamples(const char *Cmd) {
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resp.status != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(WARNING, "Antenna tuning failed");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "\n");
|
PrintAndLogEx(NORMAL, "\n");
|
||||||
|
// in mVolt
|
||||||
|
struct p {
|
||||||
|
uint32_t v_lf134;
|
||||||
|
uint32_t v_lf125;
|
||||||
|
uint32_t v_lfconf;
|
||||||
|
uint32_t v_hf;
|
||||||
|
uint32_t peak_v;
|
||||||
|
uint32_t peak_f;
|
||||||
|
int divisor;
|
||||||
|
uint8_t results[256];
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
uint32_t v_lf125 = resp.oldarg[0];
|
struct p* package = (struct p*)resp.data.asBytes;
|
||||||
uint32_t v_lf134 = resp.oldarg[0] >> 32;
|
|
||||||
|
|
||||||
uint32_t v_hf = resp.oldarg[1];
|
if (package->v_lf125 > NON_VOLTAGE)
|
||||||
uint32_t peakf = resp.oldarg[2];
|
PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 125.00 kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0);
|
||||||
uint32_t peakv = resp.oldarg[2] >> 32;
|
|
||||||
|
|
||||||
if (v_lf125 > NON_VOLTAGE)
|
if (package->v_lf134 > NON_VOLTAGE)
|
||||||
PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 125.00 kHz", (v_lf125 * ANTENNA_ERROR) / 1000.0);
|
PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 134.00 kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0);
|
||||||
if (v_lf134 > NON_VOLTAGE)
|
|
||||||
PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 134.00 kHz", (v_lf134 * ANTENNA_ERROR) / 1000.0);
|
if (package->v_lfconf > NON_VOLTAGE && package->divisor > 0)
|
||||||
if (peakv > NON_VOLTAGE && peakf > 0)
|
PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %d kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, (12000 / package->divisor));
|
||||||
PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (peakv * ANTENNA_ERROR) / 1000.0, 12000.0 / (peakf + 1));
|
|
||||||
|
if (package->peak_v > NON_VOLTAGE && package->peak_f > 0)
|
||||||
|
PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (package->peak_v * ANTENNA_ERROR) / 1000.0, 12000.0 / (package->peak_f + 1));
|
||||||
|
|
||||||
char judgement[20];
|
char judgement[20];
|
||||||
memset(judgement, 0, sizeof(judgement));
|
memset(judgement, 0, sizeof(judgement));
|
||||||
// LF evaluation
|
// LF evaluation
|
||||||
if (peakv < LF_UNUSABLE_V)
|
if (package->peak_v < LF_UNUSABLE_V)
|
||||||
sprintf(judgement, _RED_("UNUSABLE"));
|
sprintf(judgement, _RED_("UNUSABLE"));
|
||||||
else if (peakv < LF_MARGINAL_V)
|
else if (package->peak_v < LF_MARGINAL_V)
|
||||||
sprintf(judgement, _YELLOW_("MARGINAL"));
|
sprintf(judgement, _YELLOW_("MARGINAL"));
|
||||||
else
|
else
|
||||||
sprintf(judgement, _GREEN_("OK"));
|
sprintf(judgement, _GREEN_("OK"));
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "%sLF antenna is %s \n"
|
PrintAndLogEx(NORMAL, "%sLF antenna is %s \n"
|
||||||
, (peakv < LF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]")
|
, (package->peak_v < LF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]")
|
||||||
, judgement
|
, judgement
|
||||||
);
|
);
|
||||||
|
|
||||||
// HF evaluation
|
// HF evaluation
|
||||||
if (v_hf > NON_VOLTAGE)
|
if (package->v_hf > NON_VOLTAGE)
|
||||||
PrintAndLogEx(SUCCESS, "HF antenna: %5.2f V - 13.56 MHz", (v_hf * ANTENNA_ERROR) / 1000.0);
|
PrintAndLogEx(SUCCESS, "HF antenna: %5.2f V - 13.56 MHz", (package->v_hf * ANTENNA_ERROR) / 1000.0);
|
||||||
|
|
||||||
memset(judgement, 0, sizeof(judgement));
|
memset(judgement, 0, sizeof(judgement));
|
||||||
|
|
||||||
if (v_hf < HF_UNUSABLE_V)
|
if (package->v_hf < HF_UNUSABLE_V)
|
||||||
sprintf(judgement, _RED_("UNUSABLE"));
|
sprintf(judgement, _RED_("UNUSABLE"));
|
||||||
else if (v_hf < HF_MARGINAL_V)
|
else if (package->v_hf < HF_MARGINAL_V)
|
||||||
sprintf(judgement, _YELLOW_("MARGINAL"));
|
sprintf(judgement, _YELLOW_("MARGINAL"));
|
||||||
else
|
else
|
||||||
sprintf(judgement, _GREEN_("OK"));
|
sprintf(judgement, _GREEN_("OK"));
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "%sHF antenna is %s"
|
PrintAndLogEx(NORMAL, "%sHF antenna is %s"
|
||||||
, (v_hf < HF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]")
|
, (package->v_hf < HF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]")
|
||||||
, judgement
|
, judgement
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1707,12 +1724,12 @@ int CmdTuneSamples(const char *Cmd) {
|
||||||
// even here, these values has 3% error.
|
// even here, these values has 3% error.
|
||||||
uint16_t test1 = 0;
|
uint16_t test1 = 0;
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
GraphBuffer[i] = resp.data.asBytes[i] - 128;
|
GraphBuffer[i] = package->results[i] - 128;
|
||||||
test1 += resp.data.asBytes[i];
|
test1 += package->results[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test1 > 0) {
|
if (test1 > 0) {
|
||||||
PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor 89 is 134kHz, 95 is 125kHz.\n\n");
|
PrintAndLogEx(SUCCESS, "\nDisplaying LF tuning graph. Divisor 89 is 134kHz, 96 is 125kHz.\n\n");
|
||||||
GraphTraceLen = 256;
|
GraphTraceLen = 256;
|
||||||
ShowGraphWindow();
|
ShowGraphWindow();
|
||||||
RepaintGraphWindow();
|
RepaintGraphWindow();
|
||||||
|
|
|
@ -4425,12 +4425,12 @@ static command_t CommandTable[] = {
|
||||||
{"ecfill", CmdHF14AMfECFill, IfPm3Iso14443a, "Fill simulator memory with help of keys from simulator"},
|
{"ecfill", CmdHF14AMfECFill, IfPm3Iso14443a, "Fill simulator memory with help of keys from simulator"},
|
||||||
{"ekeyprn", CmdHF14AMfEKeyPrn, IfPm3Iso14443a, "Print keys from simulator memory"},
|
{"ekeyprn", CmdHF14AMfEKeyPrn, IfPm3Iso14443a, "Print keys from simulator memory"},
|
||||||
{"-----------", CmdHelp, IfPm3Iso14443a, ""},
|
{"-----------", CmdHelp, IfPm3Iso14443a, ""},
|
||||||
{"csetuid", CmdHF14AMfCSetUID, IfPm3Iso14443a, "Set UID for magic Chinese card"},
|
{"csetuid", CmdHF14AMfCSetUID, IfPm3Iso14443a, "Set UID (magic chinese card)"},
|
||||||
{"csetblk", CmdHF14AMfCSetBlk, IfPm3Iso14443a, "Write block - Magic Chinese card"},
|
{"csetblk", CmdHF14AMfCSetBlk, IfPm3Iso14443a, "Write block (magic chinese card)"},
|
||||||
{"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block - Magic Chinese card"},
|
{"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block (magic chinese card)"},
|
||||||
{"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector - Magic Chinese card"},
|
{"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector (magic chinese card)"},
|
||||||
{"cload", CmdHF14AMfCLoad, IfPm3Iso14443a, "Load dump into magic Chinese card"},
|
{"cload", CmdHF14AMfCLoad, IfPm3Iso14443a, "Load dump (magic chinese card)"},
|
||||||
{"csave", CmdHF14AMfCSave, IfPm3Iso14443a, "Save dump from magic Chinese card into file or emulator"},
|
{"csave", CmdHF14AMfCSave, IfPm3Iso14443a, "Save dump from magic chinese card into file or emulator"},
|
||||||
{"-----------", CmdHelp, IfPm3Iso14443a, ""},
|
{"-----------", CmdHelp, IfPm3Iso14443a, ""},
|
||||||
{"mad", CmdHF14AMfMAD, IfPm3Iso14443a, "Checks and prints MAD"},
|
{"mad", CmdHF14AMfMAD, IfPm3Iso14443a, "Checks and prints MAD"},
|
||||||
{"ndef", CmdHFMFNDEF, IfPm3Iso14443a, "Prints NDEF records from card"},
|
{"ndef", CmdHFMFNDEF, IfPm3Iso14443a, "Prints NDEF records from card"},
|
||||||
|
|
|
@ -1243,9 +1243,9 @@ static command_t CommandTable[] = {
|
||||||
// {"verichip", CmdLFVerichip, AlwaysAvailable, "{ VeriChip RFIDs... }"},
|
// {"verichip", CmdLFVerichip, AlwaysAvailable, "{ VeriChip RFIDs... }"},
|
||||||
{"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"},
|
{"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"},
|
||||||
{"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"},
|
{"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"},
|
||||||
|
{"", CmdHelp, AlwaysAvailable, ""},
|
||||||
{"config", CmdLFSetConfig, IfPm3Lf, "Set config for LF sampling, bit/sample, decimation, frequency"},
|
{"config", CmdLFSetConfig, IfPm3Lf, "Set config for LF sampling, bit/sample, decimation, frequency"},
|
||||||
{"cmdread", CmdLFCommandRead, IfPm3Lf, "<off period> <'0' period> <'1' period> <command> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"},
|
{"cmdread", CmdLFCommandRead, IfPm3Lf, "<off period> <'0' period> <'1' period> <command> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"},
|
||||||
{"flexdemod", CmdFlexdemod, AlwaysAvailable, "Demodulate samples for FlexPass"},
|
|
||||||
{"read", CmdLFRead, IfPm3Lf, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
{"read", CmdLFRead, IfPm3Lf, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
||||||
{"search", CmdLFfind, AlwaysAvailable, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"},
|
{"search", CmdLFfind, AlwaysAvailable, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"},
|
||||||
{"sim", CmdLFSim, IfPm3Lf, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
{"sim", CmdLFSim, IfPm3Lf, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||||
|
@ -1256,6 +1256,7 @@ static command_t CommandTable[] = {
|
||||||
{"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"},
|
{"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"},
|
||||||
{"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"},
|
{"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"},
|
||||||
// {"vchdemod", CmdVchDemod, AlwaysAvailable, "['clone'] -- Demodulate samples for VeriChip"},
|
// {"vchdemod", CmdVchDemod, AlwaysAvailable, "['clone'] -- Demodulate samples for VeriChip"},
|
||||||
|
{"flexdemod", CmdFlexdemod, AlwaysAvailable, "Demodulate samples for Motorola FlexPass"},
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -339,27 +339,63 @@ __attribute__((force_align_arg_pointer))
|
||||||
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate) {
|
int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *resultKey, bool calibrate) {
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint32_t uid;
|
uint32_t uid;
|
||||||
PacketResponseNG resp;
|
|
||||||
StateList_t statelists[2];
|
StateList_t statelists[2];
|
||||||
struct Crypto1State *p1, *p2, *p3, *p4;
|
struct Crypto1State *p1, *p2, *p3, *p4;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t block;
|
||||||
|
uint8_t keytype;
|
||||||
|
uint8_t target_block;
|
||||||
|
uint8_t target_keytype;
|
||||||
|
bool calibrate;
|
||||||
|
uint8_t key[6];
|
||||||
|
} PACKED payload;
|
||||||
|
payload.block = blockNo;
|
||||||
|
payload.keytype = keyType;
|
||||||
|
payload.target_block = trgBlockNo;
|
||||||
|
payload.target_keytype = trgKeyType;
|
||||||
|
payload.calibrate = calibrate;
|
||||||
|
memcpy(payload.key, key, sizeof(payload.key));
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandOLD(CMD_HF_MIFARE_NESTED, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate, key, 6);
|
SendCommandNG(CMD_HF_MIFARE_NESTED, (uint8_t*)&payload, sizeof(payload));
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return PM3_ETIMEOUT;
|
|
||||||
|
if (!WaitForResponseTimeout(CMD_HF_MIFARE_NESTED, &resp, 1500)) return PM3_ETIMEOUT;
|
||||||
|
|
||||||
|
if (resp.status != PM3_SUCCESS)
|
||||||
|
return PM3_ESOFT;
|
||||||
|
|
||||||
|
struct p {
|
||||||
|
int16_t isOK;
|
||||||
|
uint8_t block;
|
||||||
|
uint8_t keytype;
|
||||||
|
uint8_t cuid[4];
|
||||||
|
uint8_t nt_a[4];
|
||||||
|
uint8_t ks_a[4];
|
||||||
|
uint8_t nt_b[4];
|
||||||
|
uint8_t ks_b[4];
|
||||||
|
} PACKED;
|
||||||
|
struct p* package = (struct p*)resp.data.asBytes;
|
||||||
|
|
||||||
// error during nested
|
// error during nested
|
||||||
if (resp.oldarg[0]) return resp.oldarg[0];
|
if (package->isOK) return package->isOK;
|
||||||
|
|
||||||
memcpy(&uid, resp.data.asBytes, 4);
|
memcpy(&uid, package->cuid, sizeof(package->cuid));
|
||||||
|
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
statelists[i].blockNo = resp.oldarg[2] & 0xff;
|
statelists[i].blockNo = package->block;
|
||||||
statelists[i].keyType = (resp.oldarg[2] >> 8) & 0xff;
|
statelists[i].keyType = package->keytype;
|
||||||
statelists[i].uid = uid;
|
statelists[i].uid = uid;
|
||||||
memcpy(&statelists[i].nt, (void *)(resp.data.asBytes + 4 + i * 8 + 0), 4);
|
|
||||||
memcpy(&statelists[i].ks1, (void *)(resp.data.asBytes + 4 + i * 8 + 4), 4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(&statelists[0].nt, package->nt_a, sizeof(package->nt_a));
|
||||||
|
memcpy(&statelists[0].ks1, package->ks_a, sizeof(package->ks_a));
|
||||||
|
|
||||||
|
memcpy(&statelists[1].nt, package->nt_b, sizeof(package->nt_b));
|
||||||
|
memcpy(&statelists[1].ks1, package->ks_b, sizeof(package->ks_b));
|
||||||
|
|
||||||
|
|
||||||
// calc keys
|
// calc keys
|
||||||
pthread_t thread_id[2];
|
pthread_t thread_id[2];
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue