From 5d3eb444fbd608a53b5e1bc3796471a6d5ac039c Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 3 Oct 2019 16:15:47 +0200 Subject: [PATCH] chg 'hf mf nested' - uses NG. chg 'hw tune' - now also prints the 'lf config q' divisor voltage. --- armsrc/appmain.c | 75 ++++++++++++++++++++++++-------------- armsrc/lfsampling.c | 6 +-- armsrc/mifarecmd.c | 49 +++++++++++++++---------- armsrc/mifarecmd.h | 4 +- client/cmddata.c | 61 ++++++++++++++++++++----------- client/cmdhfmf.c | 12 +++--- client/cmdlf.c | 3 +- client/mifare/mifarehost.c | 54 ++++++++++++++++++++++----- 8 files changed, 175 insertions(+), 89 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index b778fa785..b67788bc5 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -143,11 +143,25 @@ uint16_t AvgAdc(int ch) { void MeasureAntennaTuning(void) { - uint8_t LF_Results[256]; - uint32_t i, peak = 0, peakv = 0, peakf = 0; - uint32_t v_lf125 = 0, v_lf134 = 0, v_hf = 0; // in mV + uint32_t peak = 0; + + // 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(); /* @@ -163,21 +177,26 @@ void MeasureAntennaTuning(void) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); SpinDelay(50); - for (i = 255; i >= 19; i--) { + for (uint8_t i = 255; i >= 19; i--) { WDT_HIT(); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); SpinDelay(20); uint32_t adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); - if (i == 95) - v_lf125 = adcval; // voltage at 125kHz - if (i == 89) - v_lf134 = adcval; // voltage at 134kHz + if (i == 96) + payload.v_lf125 = adcval; // voltage at 125kHz - LF_Results[i] = adcval >> 9; // scale int to fit in byte for graphing purposes - if (LF_Results[i] > peak) { - peakv = adcval; - peakf = i; - peak = LF_Results[i]; + if (i == 89) + payload.v_lf134 = adcval; // voltage at 134kHz + + if (i == sc->divisor) + 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); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); 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. - if (v_hf > MAX_ADC_HF_VOLTAGE - 300) { - v_hf = (MAX_ADC_HF_VOLTAGE_RDV40 * AvgAdc(ADC_CHAN_HF_RDV40)) >> 10; + if (payload.v_hf > MAX_ADC_HF_VOLTAGE - 300) { + 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); + reply_ng(CMD_MEASURE_ANTENNA_TUNING, PM3_SUCCESS, (uint8_t*)&payload, sizeof(payload)); LEDsoff(); } @@ -1083,7 +1095,16 @@ static void PacketReceived(PacketCommandNG *packet) { break; } 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; } case CMD_HF_MIFARE_CHKKEYS: { diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c index f1cea2aea..e8664aa47 100644 --- a/armsrc/lfsampling.c +++ b/armsrc/lfsampling.c @@ -24,11 +24,11 @@ Default LF config is set to: divisor = 95 (125kHz) trigger_threshold = 0 */ -sample_config config = { 1, 8, 1, 95, 0, 0 } ; +sample_config config = { 1, 8, 1, 96, 0, 0 } ; void printConfig() { 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(" [d] decimation..........%d", config.decimation); 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; while (true) { - if (checker == 1000) { + if (checker == 2000) { if (BUTTON_PRESS() || data_available()) break; else diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 4a469e6e1..d3f00c2ec 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -866,26 +866,20 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, // MIFARE nested authentication. // //----------------------------------------------------------------------------- -void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) { - // 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 +void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8_t targetKeyType, bool calibrate, uint8_t *key) { uint64_t ui64Key = 0; - - ui64Key = bytes_to_num(datain, 6); + ui64Key = bytes_to_num(key, 6); // variables uint16_t i, j, len; static uint16_t dmin, dmax; + + uint8_t par[1] = {0x00}; + uint8_t par_array[4] = {0x00}; uint8_t uid[10] = {0x00}; uint32_t cuid = 0, nt1, nt2, nttest, ks1; - uint8_t par[1] = {0x00}; uint32_t target_nt[2] = {0x00}, target_ks[2] = {0x00}; - uint8_t par_array[4] = {0x00}; uint16_t ncount = 0; struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; @@ -903,13 +897,15 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) BigBuf_free(); BigBuf_Clear_ext(false); - if (arg2) clear_trace(); + if (calibrate) + clear_trace(); + set_tracing(true); // statistics on nonce distance int16_t isOK = 0; #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(); WDT_HIT(); @@ -1061,15 +1057,28 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) crypto1_destroy(pcs); - uint8_t buf[4 + 4 * 4] = {0}; - memcpy(buf, &cuid, 4); - memcpy(buf + 4, &target_nt[0], 4); - memcpy(buf + 8, &target_ks[0], 4); - memcpy(buf + 12, &target_nt[1], 4); - memcpy(buf + 16, &target_ks[1], 4); + 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 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(); - 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(); if (DBGLEVEL >= 3) DbpString("NESTED FINISHED"); diff --git a/armsrc/mifarecmd.h b/armsrc/mifarecmd.h index d563e37a8..0b8e2acd3 100644 --- a/armsrc/mifarecmd.h +++ b/armsrc/mifarecmd.h @@ -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 MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); //void MifareUWriteBlockCompat(uint8_t arg0,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 MifareAcquireNonces(uint32_t arg0, uint32_t flags); void MifareChkKeys(uint8_t *datain); diff --git a/client/cmddata.c b/client/cmddata.c index 16d9d10de..12a937d79 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1654,52 +1654,69 @@ int CmdTuneSamples(const char *Cmd) { return PM3_ETIMEOUT; } } + + if (resp.status != PM3_SUCCESS) { + PrintAndLogEx(WARNING, "Antenna tuning failed"); + return PM3_ESOFT; + } + 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]; - uint32_t v_lf134 = resp.oldarg[0] >> 32; + struct p* package = (struct p*)resp.data.asBytes; - uint32_t v_hf = resp.oldarg[1]; - uint32_t peakf = resp.oldarg[2]; - uint32_t peakv = resp.oldarg[2] >> 32; + if (package->v_lf125 > NON_VOLTAGE) + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 125.00 kHz", (package->v_lf125 * ANTENNA_ERROR) / 1000.0); - if (v_lf125 > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 125.00 kHz", (v_lf125 * 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 (peakv > NON_VOLTAGE && peakf > 0) - PrintAndLogEx(SUCCESS, "LF optimal: %5.2f V - %6.2f kHz", (peakv * ANTENNA_ERROR) / 1000.0, 12000.0 / (peakf + 1)); + if (package->v_lf134 > NON_VOLTAGE) + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - 134.00 kHz", (package->v_lf134 * ANTENNA_ERROR) / 1000.0); + + if (package->v_lfconf > NON_VOLTAGE && package->divisor > 0) + PrintAndLogEx(SUCCESS, "LF antenna: %5.2f V - %d kHz", (package->v_lfconf * ANTENNA_ERROR) / 1000.0, (12000 / package->divisor)); + + 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]; memset(judgement, 0, sizeof(judgement)); // LF evaluation - if (peakv < LF_UNUSABLE_V) + if (package->peak_v < LF_UNUSABLE_V) sprintf(judgement, _RED_("UNUSABLE")); - else if (peakv < LF_MARGINAL_V) + else if (package->peak_v < LF_MARGINAL_V) sprintf(judgement, _YELLOW_("MARGINAL")); else sprintf(judgement, _GREEN_("OK")); PrintAndLogEx(NORMAL, "%sLF antenna is %s \n" - , (peakv < LF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") + , (package->peak_v < LF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") , judgement ); // HF evaluation - if (v_hf > NON_VOLTAGE) - PrintAndLogEx(SUCCESS, "HF antenna: %5.2f V - 13.56 MHz", (v_hf * ANTENNA_ERROR) / 1000.0); + if (package->v_hf > NON_VOLTAGE) + PrintAndLogEx(SUCCESS, "HF antenna: %5.2f V - 13.56 MHz", (package->v_hf * ANTENNA_ERROR) / 1000.0); memset(judgement, 0, sizeof(judgement)); - if (v_hf < HF_UNUSABLE_V) + if (package->v_hf < HF_UNUSABLE_V) sprintf(judgement, _RED_("UNUSABLE")); - else if (v_hf < HF_MARGINAL_V) + else if (package->v_hf < HF_MARGINAL_V) sprintf(judgement, _YELLOW_("MARGINAL")); else sprintf(judgement, _GREEN_("OK")); PrintAndLogEx(NORMAL, "%sHF antenna is %s" - , (v_hf < HF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") + , (package->v_hf < HF_UNUSABLE_V) ? _CYAN_("[!]") : _GREEN_("[+]") , judgement ); @@ -1707,12 +1724,12 @@ int CmdTuneSamples(const char *Cmd) { // even here, these values has 3% error. uint16_t test1 = 0; for (int i = 0; i < 256; i++) { - GraphBuffer[i] = resp.data.asBytes[i] - 128; - test1 += resp.data.asBytes[i]; + GraphBuffer[i] = package->results[i] - 128; + test1 += package->results[i]; } 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; ShowGraphWindow(); RepaintGraphWindow(); diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 744532a13..3043d19ed 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -4425,12 +4425,12 @@ static command_t CommandTable[] = { {"ecfill", CmdHF14AMfECFill, IfPm3Iso14443a, "Fill simulator memory with help of keys from simulator"}, {"ekeyprn", CmdHF14AMfEKeyPrn, IfPm3Iso14443a, "Print keys from simulator memory"}, {"-----------", CmdHelp, IfPm3Iso14443a, ""}, - {"csetuid", CmdHF14AMfCSetUID, IfPm3Iso14443a, "Set UID for magic Chinese card"}, - {"csetblk", CmdHF14AMfCSetBlk, IfPm3Iso14443a, "Write block - Magic Chinese card"}, - {"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block - Magic Chinese card"}, - {"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector - Magic Chinese card"}, - {"cload", CmdHF14AMfCLoad, IfPm3Iso14443a, "Load dump into magic Chinese card"}, - {"csave", CmdHF14AMfCSave, IfPm3Iso14443a, "Save dump from magic Chinese card into file or emulator"}, + {"csetuid", CmdHF14AMfCSetUID, IfPm3Iso14443a, "Set UID (magic chinese card)"}, + {"csetblk", CmdHF14AMfCSetBlk, IfPm3Iso14443a, "Write block (magic chinese card)"}, + {"cgetblk", CmdHF14AMfCGetBlk, IfPm3Iso14443a, "Read block (magic chinese card)"}, + {"cgetsc", CmdHF14AMfCGetSc, IfPm3Iso14443a, "Read sector (magic chinese card)"}, + {"cload", CmdHF14AMfCLoad, IfPm3Iso14443a, "Load dump (magic chinese card)"}, + {"csave", CmdHF14AMfCSave, IfPm3Iso14443a, "Save dump from magic chinese card into file or emulator"}, {"-----------", CmdHelp, IfPm3Iso14443a, ""}, {"mad", CmdHF14AMfMAD, IfPm3Iso14443a, "Checks and prints MAD"}, {"ndef", CmdHFMFNDEF, IfPm3Iso14443a, "Prints NDEF records from card"}, diff --git a/client/cmdlf.c b/client/cmdlf.c index 83d04e7c7..aa7823b34 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -1243,9 +1243,9 @@ static command_t CommandTable[] = { // {"verichip", CmdLFVerichip, AlwaysAvailable, "{ VeriChip RFIDs... }"}, {"viking", CmdLFViking, AlwaysAvailable, "{ Viking RFIDs... }"}, {"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"}, + {"", CmdHelp, AlwaysAvailable, ""}, {"config", CmdLFSetConfig, IfPm3Lf, "Set config for LF sampling, bit/sample, decimation, frequency"}, {"cmdread", CmdLFCommandRead, IfPm3Lf, " <'0' period> <'1' period> ['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"}, {"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)"}, @@ -1256,6 +1256,7 @@ static command_t CommandTable[] = { {"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"}, {"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"}, // {"vchdemod", CmdVchDemod, AlwaysAvailable, "['clone'] -- Demodulate samples for VeriChip"}, + {"flexdemod", CmdFlexdemod, AlwaysAvailable, "Demodulate samples for Motorola FlexPass"}, {NULL, NULL, NULL, NULL} }; diff --git a/client/mifare/mifarehost.c b/client/mifare/mifarehost.c index 7cfabf3ee..ba775d992 100644 --- a/client/mifare/mifarehost.c +++ b/client/mifare/mifarehost.c @@ -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) { uint16_t i; uint32_t uid; - PacketResponseNG resp; StateList_t statelists[2]; 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(); - SendCommandOLD(CMD_HF_MIFARE_NESTED, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate, key, 6); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return PM3_ETIMEOUT; + SendCommandNG(CMD_HF_MIFARE_NESTED, (uint8_t*)&payload, sizeof(payload)); + + 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 - 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++) { - statelists[i].blockNo = resp.oldarg[2] & 0xff; - statelists[i].keyType = (resp.oldarg[2] >> 8) & 0xff; + statelists[i].blockNo = package->block; + statelists[i].keyType = package->keytype; 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 pthread_t thread_id[2];