FIX: 'hf iclass sim 2'

FIX: 'hf iclass sim 4'
FIX: 'hf iclass loclass' - this fixes the bug where loclass assumes the epurse value is all zeros, while it now should save the epurse value during the simulation if it is updated/read.

I assume a empty valid epurse, while an all zero epurse is too much easy to detect as a anomaly.
This commit is contained in:
iceman1001 2018-02-04 00:52:29 +01:00
commit dc25f9212f
5 changed files with 69 additions and 65 deletions

View file

@ -1159,19 +1159,20 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
// In this mode, a number of csns are within datain. We'll simulate each one, one at a time // In this mode, a number of csns are within datain. We'll simulate each one, one at a time
// in order to collect MAC's from the reader. This can later be used in an offlne-attack // in order to collect MAC's from the reader. This can later be used in an offlne-attack
// in order to obtain the keys, as in the "dismantling iclass"-paper. // in order to obtain the keys, as in the "dismantling iclass"-paper.
#define EPURSE_MAC_SIZE 16
int i = 0; int i = 0;
for (; i < numberOfCSNS && i*8 + 8 < USB_CMD_DATA_SIZE; i++) { for (; i < numberOfCSNS && i * EPURSE_MAC_SIZE + 8 < USB_CMD_DATA_SIZE; i++) {
// The usb data is 512 bytes, fitting 65 8-byte CSNs in there. // The usb data is 512 bytes, fitting 65 8-byte CSNs in there.
memcpy(emulator, datain + (i*8), 8); memcpy(emulator, datain + (i*8), 8);
if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses+i*8)) { if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses+i * EPURSE_MAC_SIZE)) {
// Button pressed // Button pressed
cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i*8); cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE);
goto out; goto out;
} }
} }
cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i*8); cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i, 0, mac_responses, i * EPURSE_MAC_SIZE);
} else if (simType == 3){ } else if (simType == 3){
//This is 'full sim' mode, where we use the emulator storage for data. //This is 'full sim' mode, where we use the emulator storage for data.
@ -1192,26 +1193,26 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain
// attack below is same as SIM 2, but we run the CSN twice to collected the mac for both keys. // attack below is same as SIM 2, but we run the CSN twice to collected the mac for both keys.
int i = 0; int i = 0;
// The usb data is 512 bytes, fitting 65 8-byte CSNs in there. iceman fork uses 9 CSNS // The usb data is 512 bytes, fitting 65 8-byte CSNs in there. iceman fork uses 9 CSNS
for (; i < numberOfCSNS && i*8 + 8 < USB_CMD_DATA_SIZE; i++) { for (; i < numberOfCSNS && i * EPURSE_MAC_SIZE + 8 < USB_CMD_DATA_SIZE; i++) {
memcpy(emulator, datain + (i*8), 8); memcpy(emulator, datain + (i*8), 8);
// keyroll 1 // keyroll 1
if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i*8 )) { if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + i * EPURSE_MAC_SIZE )) {
cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * 8 * 2); cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2);
// Button pressed // Button pressed
goto out; goto out;
} }
// keyroll 2 // keyroll 2
if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + (i + numberOfCSNS) * 8 )) { if (doIClassSimulation(MODE_EXIT_AFTER_MAC, mac_responses + (i + numberOfCSNS) * EPURSE_MAC_SIZE )) {
cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * 8 * 2); cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * EPURSE_MAC_SIZE* 2);
// Button pressed // Button pressed
goto out; goto out;
} }
} }
// double the amount of collected data. // double the amount of collected data.
cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * 8 * 2 ); cmd_send(CMD_ACK, CMD_SIMULATE_TAG_ICLASS, i*2, 0, mac_responses, i * EPURSE_MAC_SIZE * 2 );
} else { } else {
// We may want a mode here where we hardcode the csns to use (from proxclone). // We may want a mode here where we hardcode the csns to use (from proxclone).
@ -1255,6 +1256,7 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
uint8_t diversified_key[8] = { 0 }; uint8_t diversified_key[8] = { 0 };
// e-Purse // e-Purse
uint8_t card_challenge_data[8] = { 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff }; uint8_t card_challenge_data[8] = { 0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
//uint8_t card_challenge_data[8] = { 0 };
if (simulationMode == MODE_FULLSIM) { if (simulationMode == MODE_FULLSIM) {
//The diversified key should be stored on block 3 //The diversified key should be stored on block 3
//Get the diversified key from emulator memory //Get the diversified key from emulator memory
@ -1265,7 +1267,11 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
//Precalculate the cipher state, feeding it the CC //Precalculate the cipher state, feeding it the CC
cipher_state = opt_doTagMAC_1(card_challenge_data, diversified_key); cipher_state = opt_doTagMAC_1(card_challenge_data, diversified_key);
} }
// set epurse of sim2,4 attack
if (reader_mac_buf != NULL) {
memcpy(reader_mac_buf, card_challenge_data, 8);
}
int exitLoop = 0; int exitLoop = 0;
// Reader 0a // Reader 0a
// Tag 0f // Tag 0f
@ -1320,50 +1326,26 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
// First card answer: SOF // First card answer: SOF
CodeIClassTagSOF(); CodeIClassTagSOF();
memcpy(resp_sof, ToSend, ToSendMax); resp_sof_Len = ToSendMax; memcpy(resp_sof, ToSend, ToSendMax); resp_sof_Len = ToSendMax;
// if ( MF_DBGLEVEL == MF_DBG_EXTENDED) {
// DbpString("SOF");
// PrintToSendBuffer();
// }
// Anticollision CSN // Anticollision CSN
CodeIClassTagAnswer(anticoll_data, sizeof(anticoll_data)); CodeIClassTagAnswer(anticoll_data, sizeof(anticoll_data));
memcpy(resp_anticoll, ToSend, ToSendMax); resp_anticoll_len = ToSendMax; memcpy(resp_anticoll, ToSend, ToSendMax); resp_anticoll_len = ToSendMax;
// if ( MF_DBGLEVEL == MF_DBG_EXTENDED) {
// DbpString("ANTI COLL CSN");
// PrintToSendBuffer();
// }
// CSN // CSN
CodeIClassTagAnswer(csn_data, sizeof(csn_data)); CodeIClassTagAnswer(csn_data, sizeof(csn_data));
memcpy(resp_csn, ToSend, ToSendMax); resp_csn_len = ToSendMax; memcpy(resp_csn, ToSend, ToSendMax); resp_csn_len = ToSendMax;
// if ( MF_DBGLEVEL == MF_DBG_EXTENDED) {
// DbpString("CSN");
// PrintToSendBuffer();
// }
// Configuration // Configuration
CodeIClassTagAnswer(conf_data, sizeof(conf_data)); CodeIClassTagAnswer(conf_data, sizeof(conf_data));
memcpy(resp_conf, ToSend, ToSendMax); resp_conf_len = ToSendMax; memcpy(resp_conf, ToSend, ToSendMax); resp_conf_len = ToSendMax;
// if ( MF_DBGLEVEL == MF_DBG_EXTENDED) {
// DbpString("Configuration");
// PrintToSendBuffer();
// }
// e-Purse // e-Purse
CodeIClassTagAnswer(card_challenge_data, sizeof(card_challenge_data)); CodeIClassTagAnswer(card_challenge_data, sizeof(card_challenge_data));
memcpy(resp_cc, ToSend, ToSendMax); resp_cc_len = ToSendMax; memcpy(resp_cc, ToSend, ToSendMax); resp_cc_len = ToSendMax;
// if ( MF_DBGLEVEL == MF_DBG_EXTENDED) {
// DbpString("e-Purse");
// PrintToSendBuffer();
// }
// Application Issuer Area // Application Issuer Area
CodeIClassTagAnswer(aia_data, sizeof(aia_data)); CodeIClassTagAnswer(aia_data, sizeof(aia_data));
memcpy(resp_aia, ToSend, ToSendMax); resp_aia_len = ToSendMax; memcpy(resp_aia, ToSend, ToSendMax); resp_aia_len = ToSendMax;
// if ( MF_DBGLEVEL == MF_DBG_EXTENDED) {
// DbpString("Application Issuer Data");
// PrintToSendBuffer();
// }
//This is used for responding to READ-block commands or other data which is dynamically generated //This is used for responding to READ-block commands or other data which is dynamically generated
//First the 'trace'-data, not encoded for FPGA //First the 'trace'-data, not encoded for FPGA
@ -1435,6 +1417,10 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
modulated_response = resp_cc; modulated_response_size = resp_cc_len; modulated_response = resp_cc; modulated_response_size = resp_cc_len;
trace_data = card_challenge_data; trace_data = card_challenge_data;
trace_data_size = sizeof(card_challenge_data); trace_data_size = sizeof(card_challenge_data);
// set epurse of sim2,4 attack
if (reader_mac_buf != NULL) {
memcpy(reader_mac_buf, card_challenge_data, 8);
}
break; break;
case 5:// Application Issuer Area (0c 05) case 5:// Application Issuer Area (0c 05)
modulated_response = resp_aia; modulated_response_size = resp_aia_len; modulated_response = resp_aia; modulated_response_size = resp_aia_len;
@ -1498,7 +1484,7 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
Dbprintf("[+] CSN: %02x .... %02x OK", csn[0], csn[7]); Dbprintf("[+] CSN: %02x .... %02x OK", csn[0], csn[7]);
} }
if (reader_mac_buf != NULL) { if (reader_mac_buf != NULL) {
memcpy(reader_mac_buf, receivedCmd+1, 8); memcpy(reader_mac_buf + 8, receivedCmd+1, 8);
} }
exitLoop = true; exitLoop = true;
} }

View file

@ -238,8 +238,11 @@ int usage_hf_iclass_lookup(void) {
PrintAndLog(" u CSN"); PrintAndLog(" u CSN");
PrintAndLog(" p EPURSE"); PrintAndLog(" p EPURSE");
PrintAndLog(" m macs"); PrintAndLog(" m macs");
PrintAndLog(" r raw");
PrintAndLog(" e elite");
PrintAndLog("Samples:"); PrintAndLog("Samples:");
PrintAndLog(" hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic"); PrintAndLog(" hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic");
PrintAndLog(" hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic e");
return 0; return 0;
} }
@ -360,7 +363,7 @@ int CmdHFiClassSim(const char *Cmd) {
PrintAndLog("[+] press keyboard to cancel"); PrintAndLog("[+] press keyboard to cancel");
UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType, NUM_CSNS}}; UsbCommand c = {CMD_SIMULATE_TAG_ICLASS, {simType, NUM_CSNS}};
UsbCommand resp = {0}; UsbCommand resp = {0};
memcpy(c.d.asBytes, csns, 8*NUM_CSNS); memcpy(c.d.asBytes, csns, 8 * NUM_CSNS);
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
@ -390,13 +393,16 @@ int CmdHFiClassSim(const char *Cmd) {
return 2; return 2;
} }
memset(dump, 0, datalen);//<-- Need zeroes for the CC-field memset(dump, 0, datalen);//<-- Need zeroes for the EPURSE - field (offical)
uint8_t i = 0; uint8_t i = 0;
for (i = 0 ; i < NUM_CSNS ; i++) { for (i = 0 ; i < NUM_CSNS ; i++) {
//copy CSN //copy CSN
memcpy(dump + i*24, csns + i*8, 8); memcpy(dump + i*24, csns + i*8, 8);
//8 zero bytes here then comes NR_MAC (eight bytes from the response) ( 8b csn + 8 empty== 16) //copy epurse
memcpy(dump + i*24 + 16, resp.d.asBytes + i*8, 8); memcpy(dump + i*24 + 8, resp.d.asBytes + i*16, 8);
// NR_MAC (eight bytes from the response) ( 8b csn + 8b epurse == 16)
memcpy(dump + i*24 + 16, resp.d.asBytes + i*16 + 8, 8);
} }
/** Now, save to dumpfile **/ /** Now, save to dumpfile **/
saveFile("iclass_mac_attack", "bin", dump, datalen); saveFile("iclass_mac_attack", "bin", dump, datalen);
@ -445,10 +451,12 @@ int CmdHFiClassSim(const char *Cmd) {
//Need zeroes for the CC-field //Need zeroes for the CC-field
memset(dump, 0, datalen); memset(dump, 0, datalen);
for (uint8_t i = 0; i < NUM_CSNS ; i++) { for (uint8_t i = 0; i < NUM_CSNS ; i++) {
// Copy CSN // copy CSN
memcpy(dump + i*MAC_ITEM_SIZE, csns + i*8, 8); //CSN memcpy(dump + i*MAC_ITEM_SIZE, csns + i*8, 8); //CSN
//8 zero bytes here then comes NR_MAC (eight bytes from the response) ( 8b csn + 8 empty== 16) // copy EPURSE
memcpy(dump + i*MAC_ITEM_SIZE + 16, resp.d.asBytes + i*8, 8); memcpy(dump + i*MAC_ITEM_SIZE + 8, resp.d.asBytes + i * 16, 8);
// copy NR_MAC (eight bytes from the response) ( 8b csn + 8b epurse == 16)
memcpy(dump + i*MAC_ITEM_SIZE + 16, resp.d.asBytes + i * 16 + 8, 8);
} }
saveFile("iclass_mac_attack_keyroll_A", "bin", dump, datalen); saveFile("iclass_mac_attack_keyroll_A", "bin", dump, datalen);
@ -456,11 +464,13 @@ int CmdHFiClassSim(const char *Cmd) {
memset(dump, 0, datalen); memset(dump, 0, datalen);
uint8_t resp_index = 0; uint8_t resp_index = 0;
for (uint8_t i = 0; i < NUM_CSNS; i++) { for (uint8_t i = 0; i < NUM_CSNS; i++) {
resp_index = (i + NUM_CSNS) * 8; resp_index = (i + NUM_CSNS) * 16;
// Copy CSN // Copy CSN
memcpy(dump + i*MAC_ITEM_SIZE, csns + i*8, 8); memcpy(dump + i*MAC_ITEM_SIZE, csns + i*8, 8);
//8 zero bytes here then comes NR_MAC (eight bytes from the response) ( 8b csn + 8 empty== 16) // copy EPURSE
memcpy(dump + i*MAC_ITEM_SIZE + 16, resp.d.asBytes + resp_index, 8); memcpy(dump + i*MAC_ITEM_SIZE + 8, resp.d.asBytes + resp_index, 8);
// copy NR_MAC (eight bytes from the response) ( 8b csn + 8 epurse == 16)
memcpy(dump + i*MAC_ITEM_SIZE + 16, resp.d.asBytes + resp_index + 8, 8);
resp_index++; resp_index++;
} }
saveFile("iclass_mac_attack_keyroll_B", "bin", dump, datalen); saveFile("iclass_mac_attack_keyroll_B", "bin", dump, datalen);
@ -800,9 +810,9 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v
if (CCNR != NULL) if (CCNR != NULL)
memcpy(CCNR, data+16, 8); memcpy(CCNR, data+16, 8);
// if (isOK > 0) { if (isOK > 0) {
// if (verbose) PrintAndLog("CSN: %s",sprint_hex(CSN,8)); PrintAndLog("CCNR: %s MISSING NCN",sprint_hex(CCNR, 8));
// } }
if (isOK <= 1){ if (isOK <= 1){
PrintAndLog("(%d) Failed to obtain CC! Aborting...", isOK); PrintAndLog("(%d) Failed to obtain CC! Aborting...", isOK);
@ -1926,6 +1936,8 @@ int CmdHFiClassCheckKeys(const char *Cmd) {
} }
PrintAndLog("[+] Generating diversified keys and MAC"); PrintAndLog("[+] Generating diversified keys and MAC");
PrintAndLog("[+] CSN | %s", sprint_hex( CSN, sizeof(CSN) ));
PrintAndLog("[+] CCNR | %s", sprint_hex( CCNR, sizeof(CCNR) ));
res = GenerateMacFromKeyFile( CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, pre ); res = GenerateMacFromKeyFile( CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, pre );
if ( res > 0) { if ( res > 0) {
free(keyBlock); free(keyBlock);
@ -2039,6 +2051,7 @@ int CmdHFiClassLookUp(const char *Cmd) {
uint8_t CSN[8]; uint8_t CSN[8];
uint8_t EPURSE[8]; uint8_t EPURSE[8];
uint8_t MACS[8]; uint8_t MACS[8];
uint8_t CCNR[12];
uint8_t MAC_TAG[4] = {0x00,0x00,0x00,0x00}; uint8_t MAC_TAG[4] = {0x00,0x00,0x00,0x00};
// elite key, raw key, standard key // elite key, raw key, standard key
@ -2122,10 +2135,15 @@ int CmdHFiClassLookUp(const char *Cmd) {
if (errors) return usage_hf_iclass_lookup(); if (errors) return usage_hf_iclass_lookup();
PrintAndLog("[+] CSN %s", sprint_hex( CSN, sizeof(CSN) )); // stupid copy.. CCNR is a combo of epurse and reader nonce
PrintAndLog("[+] Epurse %s", sprint_hex( EPURSE, sizeof(EPURSE) )); memcpy(CCNR, EPURSE, 8);
PrintAndLog("[+] MACS %s", sprint_hex( MACS, sizeof(MACS) )); memcpy(CCNR+8, MACS, 4);
PrintAndLog("[+] MAC_TAG %s", sprint_hex( MAC_TAG, sizeof(MAC_TAG) ));
PrintAndLog("[+] CSN | %s", sprint_hex( CSN, sizeof(CSN) ));
PrintAndLog("[+] Epurse | %s", sprint_hex( EPURSE, sizeof(EPURSE) ));
PrintAndLog("[+] MACS | %s", sprint_hex( MACS, sizeof(MACS) ));
PrintAndLog("[+] CCNR | %s", sprint_hex( CCNR, sizeof(CCNR) ));
PrintAndLog("[+] MAC_TAG | %s", sprint_hex( MAC_TAG, sizeof(MAC_TAG) ));
int res = LoadDictionaryKeyFile( filename, &keyBlock, &keycnt); int res = LoadDictionaryKeyFile( filename, &keyBlock, &keycnt);
if ( res > 0) { if ( res > 0) {
@ -2140,7 +2158,7 @@ int CmdHFiClassLookUp(const char *Cmd) {
} }
PrintAndLog("[-] Generating diversified keys and MAC"); PrintAndLog("[-] Generating diversified keys and MAC");
res = GenerateFromKeyFile( CSN, EPURSE, use_raw, use_elite, keyBlock, keycnt, prekey ); res = GenerateFromKeyFile( CSN, CCNR, use_raw, use_elite, keyBlock, keycnt, prekey );
if ( res > 0) { if ( res > 0) {
free(keyBlock); free(keyBlock);
free(prekey); free(prekey);

View file

@ -226,17 +226,17 @@ void doMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4])
uint8_t div_key[8]; uint8_t div_key[8];
//cc_nr=(uint8_t*)malloc(length+1); //cc_nr=(uint8_t*)malloc(length+1);
memcpy(cc_nr,cc_nr_p,12); memcpy(cc_nr, cc_nr_p, 12);
memcpy(div_key,div_key_p,8); memcpy(div_key, div_key_p, 8);
reverse_arraybytes(cc_nr,12); reverse_arraybytes(cc_nr, 12);
BitstreamIn bitstream = {cc_nr,12 * 8,0}; BitstreamIn bitstream = {cc_nr, 12 * 8, 0};
uint8_t dest []= {0,0,0,0,0,0,0,0}; uint8_t dest []= {0,0,0,0,0,0,0,0};
BitstreamOut out = { dest, sizeof(dest)*8, 0 }; BitstreamOut out = { dest, sizeof(dest)*8, 0 };
MAC(div_key,bitstream, out); MAC(div_key,bitstream, out);
//The output MAC must also be reversed //The output MAC must also be reversed
reverse_arraybytes(dest, sizeof(dest)); reverse_arraybytes(dest, sizeof(dest));
memcpy(mac,dest,4); memcpy(mac, dest, 4);
//free(cc_nr); //free(cc_nr);
return; return;
} }

View file

@ -271,9 +271,9 @@ int _readFromDump(uint8_t dump[], dumpdata* item, uint8_t i) {
memcpy(item, dump+i*itemsize, itemsize); memcpy(item, dump+i*itemsize, itemsize);
if (true) { if (true) {
printvar("csn", item->csn,8); printvar("csn", item->csn, sizeof(item->csn));
printvar("cc_nr", item->cc_nr,12); printvar("cc_nr", item->cc_nr, sizeof(item->cc_nr));
printvar("mac", item->mac,4); printvar("mac", item->mac, sizeof(item->mac));
} }
return 0; return 0;
} }
@ -355,6 +355,7 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) {
prnlog("[+] Bruteforcing byte %d", bytes_to_recover[i]); prnlog("[+] Bruteforcing byte %d", bytes_to_recover[i]);
while (!found && !(brute & endmask)) { while (!found && !(brute & endmask)) {
//Update the keytable with the brute-values //Update the keytable with the brute-values
for (i=0; i < numbytes_to_recover; i++) { for (i=0; i < numbytes_to_recover; i++) {
keytable[bytes_to_recover[i]] &= 0xFF00; keytable[bytes_to_recover[i]] &= 0xFF00;
@ -380,7 +381,7 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) {
// success // success
if (memcmp(calculated_MAC, item.mac, 4) == 0) { if (memcmp(calculated_MAC, item.mac, 4) == 0) {
//printf("\r\n"); printf("\r\n");
for (i =0 ; i < numbytes_to_recover; i++) { for (i =0 ; i < numbytes_to_recover; i++) {
prnlog("[=] %d: 0x%02x", bytes_to_recover[i], 0xFF & keytable[bytes_to_recover[i]]); prnlog("[=] %d: 0x%02x", bytes_to_recover[i], 0xFF & keytable[bytes_to_recover[i]]);
} }

View file

@ -84,8 +84,7 @@ typedef struct {
uint8_t csn[8]; uint8_t csn[8];
uint8_t cc_nr[12]; uint8_t cc_nr[12];
uint8_t mac[4]; uint8_t mac[4];
} dumpdata;
}dumpdata;
/** /**
* @brief Performs brute force attack against a dump-data item, containing csn, cc_nr and mac. * @brief Performs brute force attack against a dump-data item, containing csn, cc_nr and mac.