summer restructuring:
* .h include only the strict minimum for their own parsing * this forces all files to include explicitment their needs and not count on far streched dependencies * this helps Makefile to rebuild only the minimum * according to this rule, most standalone .h are now gone * big app.h is gone * remove seldom __cplusplus, if c++ happens, everything will have to be done properly anyway * all unrequired include were removed * split common/ into common/ (client+arm) and common_arm/ (os+bootloader) * bring zlib to common/ * bring stuff not really/not yet used in common back to armsrc/ or client/ * bring liblua into client/ * bring uart into client/ * move some portions of code around (dbprint, protocols,...) * rename unused files into *_disabled.[ch] to make it explicit * rename soft Uarts between 14a, 14b and iclass, so a standalone could use several without clash * remove PrintAndLogDevice * move deprecated-hid-flasher from client to tools * Makefiles * treat deps in armsrc/ as in client/ * client: stop on warning (-Werror), same as for armsrc/ Tested on: * all standalone modes * Linux
This commit is contained in:
@@ -250,7 +250,7 @@ void doMAC_N(uint8_t *address_data_p, uint8_t address_data_size, uint8_t *div_ke
|
||||
|
||||
#ifndef ON_DEVICE
|
||||
int testMAC() {
|
||||
PrintAndLogDevice(SUCCESS, "Testing MAC calculation...");
|
||||
PrintAndLogEx(SUCCESS, "Testing MAC calculation...");
|
||||
|
||||
//From the "dismantling.IClass" paper:
|
||||
uint8_t cc_nr[] = {0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0};
|
||||
@@ -262,9 +262,9 @@ int testMAC() {
|
||||
doMAC(cc_nr, div_key, calculated_mac);
|
||||
|
||||
if (memcmp(calculated_mac, correct_MAC, 4) == 0) {
|
||||
PrintAndLogDevice(SUCCESS, "MAC calculation OK!");
|
||||
PrintAndLogEx(SUCCESS, "MAC calculation OK!");
|
||||
} else {
|
||||
PrintAndLogDevice(FAILED, "FAILED: MAC calculation failed:");
|
||||
PrintAndLogEx(FAILED, "FAILED: MAC calculation failed:");
|
||||
printarr(" Calculated_MAC", calculated_mac, 4);
|
||||
printarr(" Correct_MAC ", correct_MAC, 4);
|
||||
return 1;
|
||||
|
||||
@@ -34,12 +34,15 @@
|
||||
*
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "cipherutils.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
|
||||
#include "fileutils.h"
|
||||
#include "cipherutils.h"
|
||||
/**
|
||||
*
|
||||
* @brief Return and remove the first bit (x0) in the stream : <x0 x1 x2 x3 ... xn >
|
||||
@@ -152,7 +155,7 @@ void printarr(const char *name, uint8_t *arr, int len) {
|
||||
cx += snprintf(output + cx, outsize - cx, "0x%02x,", *(arr + i)); //5 bytes per byte
|
||||
}
|
||||
snprintf(output + cx, outsize - cx, "};");
|
||||
PrintAndLogDevice(NORMAL, output);
|
||||
PrintAndLogEx(NORMAL, output);
|
||||
free(output);
|
||||
}
|
||||
|
||||
@@ -165,7 +168,7 @@ void printvar(const char *name, uint8_t *arr, int len) {
|
||||
cx += snprintf(output + cx, outsize - cx, "%02x", *(arr + i)); //2 bytes per byte
|
||||
}
|
||||
|
||||
PrintAndLogDevice(NORMAL, output);
|
||||
PrintAndLogEx(NORMAL, output);
|
||||
free(output);
|
||||
}
|
||||
|
||||
@@ -179,7 +182,7 @@ void printarr_human_readable(const char *title, uint8_t *arr, int len) {
|
||||
cx += snprintf(output + cx, outsize - cx, "\n%02x| ", i);
|
||||
cx += snprintf(output + cx, outsize - cx, "%02x ", *(arr + i));
|
||||
}
|
||||
PrintAndLogDevice(NORMAL, output);
|
||||
PrintAndLogEx(NORMAL, output);
|
||||
free(output);
|
||||
}
|
||||
|
||||
@@ -201,12 +204,12 @@ static int testBitStream() {
|
||||
}
|
||||
|
||||
if (memcmp(input, output, sizeof(input)) == 0) {
|
||||
PrintAndLogDevice(SUCCESS, " Bitstream test 1 ok");
|
||||
PrintAndLogEx(SUCCESS, " Bitstream test 1 ok");
|
||||
} else {
|
||||
PrintAndLogDevice(FAILED, " Bitstream test 1 failed");
|
||||
PrintAndLogEx(FAILED, " Bitstream test 1 failed");
|
||||
uint8_t i;
|
||||
for (i = 0 ; i < ARRAYLEN(input) ; i++) {
|
||||
PrintAndLogDevice(NORMAL, " IN %02x, OUT %02x", input[i], output[i]);
|
||||
PrintAndLogEx(NORMAL, " IN %02x, OUT %02x", input[i], output[i]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -231,12 +234,12 @@ static int testReversedBitstream() {
|
||||
}
|
||||
|
||||
if (memcmp(input, output, sizeof(input)) == 0) {
|
||||
PrintAndLogDevice(SUCCESS, " Bitstream test 2 ok");
|
||||
PrintAndLogEx(SUCCESS, " Bitstream test 2 ok");
|
||||
} else {
|
||||
PrintAndLogDevice(FAILED, " Bitstream test 2 failed");
|
||||
PrintAndLogEx(FAILED, " Bitstream test 2 failed");
|
||||
uint8_t i;
|
||||
for (i = 0 ; i < ARRAYLEN(input) ; i++) {
|
||||
PrintAndLogDevice(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]);
|
||||
PrintAndLogEx(NORMAL, " IN %02x, MIDDLE: %02x, OUT %02x", input[i], reverse[i], output[i]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -245,7 +248,7 @@ static int testReversedBitstream() {
|
||||
|
||||
|
||||
int testCipherUtils(void) {
|
||||
PrintAndLogDevice(INFO, "Testing some internals...");
|
||||
PrintAndLogEx(INFO, "Testing some internals...");
|
||||
int retval = 0;
|
||||
retval |= testBitStream();
|
||||
retval |= testReversedBitstream();
|
||||
|
||||
@@ -221,7 +221,7 @@ void hash2(uint8_t *key64, uint8_t *outp_keytable) {
|
||||
// Once again, key is on iclass-format
|
||||
desencrypt_iclass(key64, key64_negated, z[0]);
|
||||
|
||||
// PrintAndLogDevice(NORMAL, "\n"); PrintAndLogDevice(NORMAL, "High security custom key (Kcus):");
|
||||
// PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(NORMAL, "High security custom key (Kcus):");
|
||||
// printvar("z0 ", z[0],8);
|
||||
|
||||
uint8_t y[8][8] = {{0}, {0}};
|
||||
@@ -325,10 +325,10 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) {
|
||||
keytable[key_index[i]] |= BEING_CRACKED;
|
||||
|
||||
if (numbytes_to_recover > 3) {
|
||||
PrintAndLogDevice(FAILED, "The CSN requires > 3 byte bruteforce, not supported");
|
||||
PrintAndLogEx(FAILED, "The CSN requires > 3 byte bruteforce, not supported");
|
||||
printvar("[-] CSN", item.csn, 8);
|
||||
printvar("[-] HASH1", key_index, 8);
|
||||
PrintAndLogDevice(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
//Before we exit, reset the 'BEING_CRACKED' to zero
|
||||
keytable[bytes_to_recover[0]] &= ~BEING_CRACKED;
|
||||
keytable[bytes_to_recover[1]] &= ~BEING_CRACKED;
|
||||
@@ -351,9 +351,9 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) {
|
||||
*/
|
||||
|
||||
uint32_t endmask = 1 << 8 * numbytes_to_recover;
|
||||
PrintAndLogDevice(NORMAL, "----------------------------");
|
||||
PrintAndLogEx(NORMAL, "----------------------------");
|
||||
for (i = 0 ; i < numbytes_to_recover && numbytes_to_recover > 1; i++)
|
||||
PrintAndLogDevice(INFO, "Bruteforcing byte %d", bytes_to_recover[i]);
|
||||
PrintAndLogEx(INFO, "Bruteforcing byte %d", bytes_to_recover[i]);
|
||||
|
||||
while (!found && !(brute & endmask)) {
|
||||
|
||||
@@ -384,7 +384,7 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) {
|
||||
if (memcmp(calculated_MAC, item.mac, 4) == 0) {
|
||||
printf("\r\n");
|
||||
for (i = 0 ; i < numbytes_to_recover; i++) {
|
||||
PrintAndLogDevice(INFO, "%d: 0x%02x", bytes_to_recover[i], 0xFF & keytable[bytes_to_recover[i]]);
|
||||
PrintAndLogEx(INFO, "%d: 0x%02x", bytes_to_recover[i], 0xFF & keytable[bytes_to_recover[i]]);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
@@ -400,8 +400,8 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) {
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
PrintAndLogDevice(NORMAL, "\n");
|
||||
PrintAndLogDevice(WARNING, "Failed to recover %d bytes using the following CSN", numbytes_to_recover);
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
PrintAndLogEx(WARNING, "Failed to recover %d bytes using the following CSN", numbytes_to_recover);
|
||||
printvar("[!] CSN", item.csn, 8);
|
||||
errors++;
|
||||
|
||||
@@ -411,7 +411,7 @@ int bruteforceItem(dumpdata item, uint16_t keytable[]) {
|
||||
keytable[bytes_to_recover[i]] |= CRACK_FAILED;
|
||||
}
|
||||
} else {
|
||||
//PrintAndLogDevice(SUCCESS, "DES calcs: %u", brute);
|
||||
//PrintAndLogEx(SUCCESS, "DES calcs: %u", brute);
|
||||
for (i = 0; i < numbytes_to_recover; i++) {
|
||||
keytable[bytes_to_recover[i]] &= 0xFF;
|
||||
keytable[bytes_to_recover[i]] |= CRACKED;
|
||||
@@ -466,8 +466,8 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) {
|
||||
|
||||
mbedtls_des_setkey_enc(&ctx_e, key64_stdformat);
|
||||
mbedtls_des_crypt_ecb(&ctx_e, key64_negated, result);
|
||||
PrintAndLogDevice(NORMAL, "\n");
|
||||
PrintAndLogDevice(SUCCESS, "-- High security custom key (Kcus) --");
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
PrintAndLogEx(SUCCESS, "-- High security custom key (Kcus) --");
|
||||
printvar("[+] Standard format ", key64_stdformat, 8);
|
||||
printvar("[+] iClass format ", key64, 8);
|
||||
|
||||
@@ -475,11 +475,11 @@ int calculateMasterKey(uint8_t first16bytes[], uint64_t master_key[]) {
|
||||
memcpy(master_key, key64, 8);
|
||||
|
||||
if (memcmp(z_0, result, 4) != 0) {
|
||||
PrintAndLogDevice(WARNING, "Failed to verify calculated master key (k_cus)! Something is wrong.");
|
||||
PrintAndLogEx(WARNING, "Failed to verify calculated master key (k_cus)! Something is wrong.");
|
||||
return 1;
|
||||
} else {
|
||||
PrintAndLogDevice(NORMAL, "\n");
|
||||
PrintAndLogDevice(SUCCESS, "Key verified ok!\n");
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
PrintAndLogEx(SUCCESS, "Key verified ok!\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -505,7 +505,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
|
||||
}
|
||||
free(attack);
|
||||
t1 = msclock() - t1;
|
||||
PrintAndLogDevice(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000);
|
||||
PrintAndLogEx(SUCCESS, "time: %" PRIu64 " seconds", t1 / 1000);
|
||||
|
||||
// Pick out the first 16 bytes of the keytable.
|
||||
// The keytable is now in 16-bit ints, where the upper 8 bits
|
||||
@@ -517,7 +517,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
|
||||
first16bytes[i] = keytable[i] & 0xFF;
|
||||
|
||||
if (!(keytable[i] & CRACKED))
|
||||
PrintAndLogDevice(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i);
|
||||
PrintAndLogEx(WARNING, "Warning: we are missing byte %d, custom key calculation will fail...", i);
|
||||
}
|
||||
errors += calculateMasterKey(first16bytes, NULL);
|
||||
return errors;
|
||||
@@ -532,7 +532,7 @@ int bruteforceDump(uint8_t dump[], size_t dumpsize, uint16_t keytable[]) {
|
||||
int bruteforceFile(const char *filename, uint16_t keytable[]) {
|
||||
FILE *f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
PrintAndLogDevice(WARNING, "Failed to read from file '%s'", filename);
|
||||
PrintAndLogEx(WARNING, "Failed to read from file '%s'", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -541,14 +541,14 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) {
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
if (fsize <= 0) {
|
||||
PrintAndLogDevice(ERR, "Error, when getting filesize");
|
||||
PrintAndLogEx(ERR, "Error, when getting filesize");
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t *dump = calloc(fsize, sizeof(uint8_t));
|
||||
if (!dump) {
|
||||
PrintAndLogDevice(WARNING, "Failed to allocate memory");
|
||||
PrintAndLogEx(WARNING, "Failed to allocate memory");
|
||||
fclose(f);
|
||||
return 2;
|
||||
}
|
||||
@@ -557,7 +557,7 @@ int bruteforceFile(const char *filename, uint16_t keytable[]) {
|
||||
fclose(f);
|
||||
|
||||
if (bytes_read < fsize) {
|
||||
PrintAndLogDevice(WARNING, "Warning: could only read %d bytes (should be %d)", bytes_read, fsize);
|
||||
PrintAndLogEx(WARNING, "Warning: could only read %d bytes (should be %d)", bytes_read, fsize);
|
||||
}
|
||||
|
||||
uint8_t res = bruteforceDump(dump, fsize, keytable);
|
||||
@@ -585,7 +585,7 @@ static int _testBruteforce() {
|
||||
int errors = 0;
|
||||
if (true) {
|
||||
// First test
|
||||
PrintAndLogDevice(INFO, "Testing crack from dumpfile...");
|
||||
PrintAndLogEx(INFO, "Testing crack from dumpfile...");
|
||||
|
||||
/**
|
||||
Expected values for the dumpfile:
|
||||
@@ -612,7 +612,7 @@ static int _testBruteforce() {
|
||||
} else if (fileExists("client/loclass/iclass_dump.bin")) {
|
||||
errors |= bruteforceFile("client/loclass/iclass_dump.bin", keytable);
|
||||
} else {
|
||||
PrintAndLogDevice(ERR, "Error: The file iclass_dump.bin was not found!");
|
||||
PrintAndLogEx(ERR, "Error: The file iclass_dump.bin was not found!");
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
@@ -627,20 +627,20 @@ static int _test_iclass_key_permutation() {
|
||||
permutekey_rev(testcase_output, testcase_output_rev);
|
||||
|
||||
if (memcmp(testcase_output, testcase_output_correct, 8) != 0) {
|
||||
PrintAndLogDevice(ERR, "Error with iclass key permute!");
|
||||
PrintAndLogEx(ERR, "Error with iclass key permute!");
|
||||
printarr("testcase_output", testcase_output, 8);
|
||||
printarr("testcase_output_correct", testcase_output_correct, 8);
|
||||
return 1;
|
||||
|
||||
}
|
||||
if (memcmp(testcase, testcase_output_rev, 8) != 0) {
|
||||
PrintAndLogDevice(ERR, "Error with reverse iclass key permute");
|
||||
PrintAndLogEx(ERR, "Error with reverse iclass key permute");
|
||||
printarr("testcase", testcase, 8);
|
||||
printarr("testcase_output_rev", testcase_output_rev, 8);
|
||||
return 1;
|
||||
}
|
||||
|
||||
PrintAndLogDevice(SUCCESS, "Iclass key permutation OK!");
|
||||
PrintAndLogEx(SUCCESS, "Iclass key permutation OK!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -651,7 +651,7 @@ static int _testHash1() {
|
||||
hash1(csn, k);
|
||||
|
||||
if (memcmp(k, expected, 8) != 0) {
|
||||
PrintAndLogDevice(ERR, "Error with hash1!");
|
||||
PrintAndLogEx(ERR, "Error with hash1!");
|
||||
printarr("calculated", k, 8);
|
||||
printarr("expected", expected, 8);
|
||||
return 1;
|
||||
@@ -660,8 +660,8 @@ static int _testHash1() {
|
||||
}
|
||||
|
||||
int testElite() {
|
||||
PrintAndLogDevice(INFO, "Testing iClass Elite functinality...");
|
||||
PrintAndLogDevice(INFO, "Testing hash2");
|
||||
PrintAndLogEx(INFO, "Testing iClass Elite functinality...");
|
||||
PrintAndLogEx(INFO, "Testing hash2");
|
||||
uint8_t k_cus[8] = {0x5B, 0x7C, 0x62, 0xC4, 0x91, 0xC1, 0x1B, 0x39};
|
||||
|
||||
/**
|
||||
@@ -683,13 +683,13 @@ int testElite() {
|
||||
hash2(k_cus, keytable);
|
||||
printarr_human_readable("Hash2", keytable, 128);
|
||||
if (keytable[3] == 0xA1 && keytable[0x30] == 0xA3 && keytable[0x6F] == 0x95) {
|
||||
PrintAndLogDevice(SUCCESS, "Hash2 looks fine...");
|
||||
PrintAndLogEx(SUCCESS, "Hash2 looks fine...");
|
||||
}
|
||||
|
||||
int errors = 0 ;
|
||||
PrintAndLogDevice(INFO, "Testing hash1...");
|
||||
PrintAndLogEx(INFO, "Testing hash1...");
|
||||
errors += _testHash1();
|
||||
PrintAndLogDevice(INFO, "Testing key diversification ...");
|
||||
PrintAndLogEx(INFO, "Testing key diversification ...");
|
||||
errors += _test_iclass_key_permutation();
|
||||
errors += _testBruteforce();
|
||||
return errors;
|
||||
|
||||
@@ -36,6 +36,13 @@
|
||||
****************************************************************************/
|
||||
#include "fileutils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "pm3_cmd.h"
|
||||
#include "commonutil.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#ifndef ON_DEVICE
|
||||
|
||||
#define PATH_MAX_LENGTH 100
|
||||
@@ -100,14 +107,14 @@ int saveFile(const char *preferredName, const char *suffix, const void *data, si
|
||||
/*Opening file for writing in binary mode*/
|
||||
FILE *f = fopen(fileName, "wb");
|
||||
if (!f) {
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
free(fileName);
|
||||
return PM3_EFILE;
|
||||
}
|
||||
fwrite(data, 1, datalen, f);
|
||||
fflush(f);
|
||||
fclose(f);
|
||||
PrintAndLogDevice(SUCCESS, "saved %u bytes to binary file " _YELLOW_("%s"), datalen, fileName);
|
||||
PrintAndLogEx(SUCCESS, "saved %u bytes to binary file " _YELLOW_("%s"), datalen, fileName);
|
||||
free(fileName);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
@@ -127,7 +134,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t
|
||||
/*Opening file for writing in text mode*/
|
||||
FILE *f = fopen(fileName, "w+");
|
||||
if (!f) {
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
retval = PM3_EFILE;
|
||||
goto out;
|
||||
}
|
||||
@@ -150,7 +157,7 @@ int saveFileEML(const char *preferredName, uint8_t *data, size_t datalen, size_t
|
||||
}
|
||||
fflush(f);
|
||||
fclose(f);
|
||||
PrintAndLogDevice(SUCCESS, "saved %d blocks to text file " _YELLOW_("%s"), blocks, fileName);
|
||||
PrintAndLogEx(SUCCESS, "saved %d blocks to text file " _YELLOW_("%s"), blocks, fileName);
|
||||
|
||||
out:
|
||||
free(fileName);
|
||||
@@ -273,12 +280,12 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s
|
||||
|
||||
int res = json_dump_file(root, fileName, JSON_INDENT(2));
|
||||
if (res) {
|
||||
PrintAndLogDevice(FAILED, "error: can't save the file: " _YELLOW_("%s"), fileName);
|
||||
PrintAndLogEx(FAILED, "error: can't save the file: " _YELLOW_("%s"), fileName);
|
||||
json_decref(root);
|
||||
retval = 200;
|
||||
goto out;
|
||||
}
|
||||
PrintAndLogDevice(SUCCESS, "saved to json file " _YELLOW_("%s"), fileName);
|
||||
PrintAndLogEx(SUCCESS, "saved to json file " _YELLOW_("%s"), fileName);
|
||||
json_decref(root);
|
||||
|
||||
out:
|
||||
@@ -296,7 +303,7 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m
|
||||
|
||||
FILE *f = fopen(fileName, "rb");
|
||||
if (!f) {
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
free(fileName);
|
||||
return PM3_EFILE;
|
||||
}
|
||||
@@ -307,14 +314,14 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
if (fsize <= 0) {
|
||||
PrintAndLogDevice(FAILED, "error, when getting filesize");
|
||||
PrintAndLogEx(FAILED, "error, when getting filesize");
|
||||
retval = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
uint8_t *dump = calloc(fsize, sizeof(uint8_t));
|
||||
if (!dump) {
|
||||
PrintAndLogDevice(FAILED, "error, cannot allocate memory");
|
||||
PrintAndLogEx(FAILED, "error, cannot allocate memory");
|
||||
retval = 2;
|
||||
goto out;
|
||||
}
|
||||
@@ -322,21 +329,21 @@ int loadFile(const char *preferredName, const char *suffix, void *data, size_t m
|
||||
size_t bytes_read = fread(dump, 1, fsize, f);
|
||||
|
||||
if (bytes_read != fsize) {
|
||||
PrintAndLogDevice(FAILED, "error, bytes read mismatch file size");
|
||||
PrintAndLogEx(FAILED, "error, bytes read mismatch file size");
|
||||
free(dump);
|
||||
retval = 3;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bytes_read > maxdatalen) {
|
||||
PrintAndLogDevice(WARNING, "Warning, bytes read exceed calling array limit. Max bytes is %d bytes", maxdatalen);
|
||||
PrintAndLogEx(WARNING, "Warning, bytes read exceed calling array limit. Max bytes is %d bytes", maxdatalen);
|
||||
bytes_read = maxdatalen;
|
||||
}
|
||||
|
||||
memcpy((data), dump, bytes_read);
|
||||
free(dump);
|
||||
|
||||
PrintAndLogDevice(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, fileName);
|
||||
PrintAndLogEx(SUCCESS, "loaded %d bytes from binary file " _YELLOW_("%s"), bytes_read, fileName);
|
||||
|
||||
*datalen = bytes_read;
|
||||
|
||||
@@ -358,7 +365,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) {
|
||||
|
||||
FILE *f = fopen(fileName, "r");
|
||||
if (!f) {
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
retval = PM3_EFILE;
|
||||
goto out;
|
||||
}
|
||||
@@ -391,7 +398,7 @@ int loadFileEML(const char *preferredName, void *data, size_t *datalen) {
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
PrintAndLogDevice(SUCCESS, "loaded %d bytes from text file " _YELLOW_("%s"), counter, fileName);
|
||||
PrintAndLogEx(SUCCESS, "loaded %d bytes from text file " _YELLOW_("%s"), counter, fileName);
|
||||
|
||||
if (datalen)
|
||||
*datalen = counter;
|
||||
@@ -532,7 +539,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u
|
||||
|
||||
FILE *f = fopen(fileName, "r");
|
||||
if (!f) {
|
||||
PrintAndLogDevice(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
PrintAndLogEx(WARNING, "file not found or locked. '" _YELLOW_("%s")"'", fileName);
|
||||
retval = PM3_EFILE;
|
||||
goto out;
|
||||
}
|
||||
@@ -564,7 +571,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u
|
||||
counter += (keylen >> 1);
|
||||
}
|
||||
fclose(f);
|
||||
PrintAndLogDevice(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName);
|
||||
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%2d") "keys from dictionary file " _YELLOW_("%s"), *keycnt, fileName);
|
||||
|
||||
if (datalen)
|
||||
*datalen = counter;
|
||||
@@ -601,7 +608,7 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen) {
|
||||
*dumplen = new_dump_len;
|
||||
free(*dump);
|
||||
*dump = (uint8_t *) mfu_dump;
|
||||
PrintAndLogDevice(SUCCESS, "old mfu dump format, was converted on load to " _GREEN_("%d") " pages", mfu_dump->pages + 1);
|
||||
PrintAndLogEx(SUCCESS, "old mfu dump format, was converted on load to " _GREEN_("%d") " pages", mfu_dump->pages + 1);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -162,7 +162,7 @@ int loadFileDICTIONARY(const char *preferredName, void *data, size_t *datalen, u
|
||||
*/
|
||||
int convertOldMfuDump(uint8_t **dump, size_t *dumplen);
|
||||
|
||||
#define PrintAndLogDevice(level, format, args...) PrintAndLogEx(level, format , ## args)
|
||||
#define PrintAndLogEx(level, format, args...) PrintAndLogEx(level, format , ## args)
|
||||
#else
|
||||
|
||||
/**
|
||||
@@ -172,7 +172,7 @@ int convertOldMfuDump(uint8_t **dump, size_t *dumplen);
|
||||
* write also to a logfile. When doing so, just point this function to use PrintAndLog
|
||||
* @param fmt
|
||||
*/
|
||||
#define PrintAndLogDevice(level, format, args...) { }
|
||||
#define PrintAndLogEx(level, format, args...) { }
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -63,6 +63,9 @@ From "Dismantling iclass":
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
|
||||
#include "fileutils.h"
|
||||
#include "cipherutils.h"
|
||||
#include "mbedtls/des.h"
|
||||
@@ -218,7 +221,7 @@ static void printbegin() {
|
||||
if (debug_print < 2)
|
||||
return;
|
||||
|
||||
PrintAndLogDevice(NORMAL, " | x| y|z0|z1|z2|z3|z4|z5|z6|z7|");
|
||||
PrintAndLogEx(NORMAL, " | x| y|z0|z1|z2|z3|z4|z5|z6|z7|");
|
||||
}
|
||||
|
||||
static void printState(const char *desc, uint64_t c) {
|
||||
@@ -281,7 +284,7 @@ void hash0(uint64_t c, uint8_t k[8]) {
|
||||
if (x & 1) //Check if x7 is 1
|
||||
p = ~p;
|
||||
|
||||
if (debug_print >= 2) PrintAndLogDevice(DEBUG, "p:%02x", p);
|
||||
if (debug_print >= 2) PrintAndLogEx(DEBUG, "p:%02x", p);
|
||||
|
||||
BitstreamIn p_in = { &p, 8, 0 };
|
||||
uint8_t outbuffer[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
@@ -426,7 +429,7 @@ static int testDES(Testcase testcase, mbedtls_des_context ctx_enc, mbedtls_des_c
|
||||
|
||||
if (memcmp(testcase.uid, decrypted, 8) != 0) {
|
||||
//Decryption fail
|
||||
PrintAndLogDevice(FAILED, "Encryption <-> Decryption FAIL");
|
||||
PrintAndLogEx(FAILED, "Encryption <-> Decryption FAIL");
|
||||
printarr("Input", testcase.uid, 8);
|
||||
printarr("Decrypted", decrypted, 8);
|
||||
retval = 1;
|
||||
@@ -434,7 +437,7 @@ static int testDES(Testcase testcase, mbedtls_des_context ctx_enc, mbedtls_des_c
|
||||
|
||||
if (memcmp(des_encrypted_csn, testcase.t_key, 8) != 0) {
|
||||
//Encryption fail
|
||||
PrintAndLogDevice(FAILED, "Encryption != Expected result");
|
||||
PrintAndLogEx(FAILED, "Encryption != Expected result");
|
||||
printarr("Output", des_encrypted_csn, 8);
|
||||
printarr("Expected", testcase.t_key, 8);
|
||||
retval = 1;
|
||||
@@ -444,7 +447,7 @@ static int testDES(Testcase testcase, mbedtls_des_context ctx_enc, mbedtls_des_c
|
||||
|
||||
if (memcmp(div_key, testcase.div_key, 8) != 0) {
|
||||
//Key diversification fail
|
||||
PrintAndLogDevice(FAILED, "Div key != expected result");
|
||||
PrintAndLogEx(FAILED, "Div key != expected result");
|
||||
printarr(" csn ", testcase.uid, 8);
|
||||
printarr("{csn} ", des_encrypted_csn, 8);
|
||||
printarr("hash0 ", div_key, 8);
|
||||
@@ -469,13 +472,13 @@ static void des_checkParity(uint8_t *key) {
|
||||
bool parity = des_getParityBitFromKey(key[i]);
|
||||
if (parity != (key[i] & 0x1)) {
|
||||
fails++;
|
||||
PrintAndLogDevice(FAILED, "parity1 fail, byte %d [%02x] was %d, should be %d", i, key[i], (key[i] & 0x1), parity);
|
||||
PrintAndLogEx(FAILED, "parity1 fail, byte %d [%02x] was %d, should be %d", i, key[i], (key[i] & 0x1), parity);
|
||||
}
|
||||
}
|
||||
if (fails) {
|
||||
PrintAndLogDevice(FAILED, "parity fails: %d", fails);
|
||||
PrintAndLogEx(FAILED, "parity fails: %d", fails);
|
||||
} else {
|
||||
PrintAndLogDevice(SUCCESS, "Key syntax is with parity bits inside each byte");
|
||||
PrintAndLogEx(SUCCESS, "Key syntax is with parity bits inside each byte");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -554,15 +557,15 @@ static int testKeyDiversificationWithMasterkeyTestcases() {
|
||||
int i, error = 0;
|
||||
uint8_t empty[8] = {0};
|
||||
|
||||
PrintAndLogDevice(INFO, "Testing encryption/decryption");
|
||||
PrintAndLogEx(INFO, "Testing encryption/decryption");
|
||||
|
||||
for (i = 0; memcmp(testcases + i, empty, 8); i++)
|
||||
error += testDES(testcases[i], ctx_enc, ctx_dec);
|
||||
|
||||
if (error)
|
||||
PrintAndLogDevice(FAILED, "%d errors occurred (%d testcases)", error, i);
|
||||
PrintAndLogEx(FAILED, "%d errors occurred (%d testcases)", error, i);
|
||||
else
|
||||
PrintAndLogDevice(SUCCESS, "Hashing seems to work (%d testcases)", i);
|
||||
PrintAndLogEx(SUCCESS, "Hashing seems to work (%d testcases)", i);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -573,7 +576,7 @@ static void print64bits(const char *name, uint64_t val) {
|
||||
static uint64_t testCryptedCSN(uint64_t crypted_csn, uint64_t expected) {
|
||||
int retval = 0;
|
||||
uint8_t result[8] = {0};
|
||||
if (debug_print) PrintAndLogDevice(DEBUG, "debug_print %d", debug_print);
|
||||
if (debug_print) PrintAndLogEx(DEBUG, "debug_print %d", debug_print);
|
||||
if (debug_print) print64bits(" {csn} ", crypted_csn);
|
||||
|
||||
uint64_t crypted_csn_swapped = swapZvalues(crypted_csn);
|
||||
@@ -586,13 +589,13 @@ static uint64_t testCryptedCSN(uint64_t crypted_csn, uint64_t expected) {
|
||||
|
||||
if (resultbyte != expected) {
|
||||
if (debug_print) {
|
||||
PrintAndLogDevice(NORMAL, "\n");
|
||||
PrintAndLogDevice(FAILED, "FAIL!");
|
||||
PrintAndLogEx(NORMAL, "\n");
|
||||
PrintAndLogEx(FAILED, "FAIL!");
|
||||
print64bits(" expected ", expected);
|
||||
}
|
||||
retval = 1;
|
||||
} else {
|
||||
if (debug_print) PrintAndLogDevice(SUCCESS, "[OK]");
|
||||
if (debug_print) PrintAndLogEx(SUCCESS, "[OK]");
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
@@ -611,7 +614,7 @@ static int testDES2(uint64_t csn, uint64_t expected) {
|
||||
print64bits(" expected ", expected);
|
||||
|
||||
if (expected == crypt_csn) {
|
||||
PrintAndLogDevice(SUCCESS, "OK");
|
||||
PrintAndLogEx(SUCCESS, "OK");
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
@@ -626,13 +629,13 @@ static int testDES2(uint64_t csn, uint64_t expected) {
|
||||
static int doTestsWithKnownInputs() {
|
||||
// KSel from http://www.proxmark.org/forum/viewtopic.php?pid=10977#p10977
|
||||
int errors = 0;
|
||||
PrintAndLogDevice(SUCCESS, "Testing DES encryption");
|
||||
PrintAndLogEx(SUCCESS, "Testing DES encryption");
|
||||
uint8_t key[8] = {0x6c, 0x8d, 0x44, 0xf9, 0x2a, 0x2d, 0x01, 0xbf};
|
||||
|
||||
mbedtls_des_setkey_enc(&ctx_enc, key);
|
||||
testDES2(0xbbbbaaaabbbbeeee, 0xd6ad3ca619659e6b);
|
||||
|
||||
PrintAndLogDevice(SUCCESS, "Testing hashing algorithm");
|
||||
PrintAndLogEx(SUCCESS, "Testing hashing algorithm");
|
||||
|
||||
errors += testCryptedCSN(0x0102030405060708, 0x0bdd6512073c460a);
|
||||
errors += testCryptedCSN(0x1020304050607080, 0x0208211405f3381f);
|
||||
@@ -645,9 +648,9 @@ static int doTestsWithKnownInputs() {
|
||||
errors += testCryptedCSN(0x14e2adfc5bb7e134, 0x6ac90c6508bd9ea3);
|
||||
|
||||
if (errors)
|
||||
PrintAndLogDevice(FAILED, "%d errors occurred (9 testcases)", errors);
|
||||
PrintAndLogEx(FAILED, "%d errors occurred (9 testcases)", errors);
|
||||
else
|
||||
PrintAndLogDevice(SUCCESS, "Hashing seems to work (9 testcases)");
|
||||
PrintAndLogEx(SUCCESS, "Hashing seems to work (9 testcases)");
|
||||
return errors;
|
||||
}
|
||||
|
||||
@@ -683,10 +686,10 @@ static bool readKeyFile(uint8_t key[8]) {
|
||||
int doKeyTests(uint8_t debuglevel) {
|
||||
debug_print = debuglevel;
|
||||
|
||||
PrintAndLogDevice(INFO, "Checking if the master key is present (iclass_key.bin)...");
|
||||
PrintAndLogEx(INFO, "Checking if the master key is present (iclass_key.bin)...");
|
||||
uint8_t key[8] = {0};
|
||||
if (!readKeyFile(key)) {
|
||||
PrintAndLogDevice(FAILED, "Master key not present, will not be able to do all testcases");
|
||||
PrintAndLogEx(FAILED, "Master key not present, will not be able to do all testcases");
|
||||
} else {
|
||||
|
||||
//Test if it's the right key...
|
||||
@@ -696,19 +699,19 @@ int doKeyTests(uint8_t debuglevel) {
|
||||
j += key[i];
|
||||
|
||||
if (j != 185) {
|
||||
PrintAndLogDevice(INFO, "A key was loaded, but it does not seem to be the correct one. Aborting these tests");
|
||||
PrintAndLogEx(INFO, "A key was loaded, but it does not seem to be the correct one. Aborting these tests");
|
||||
} else {
|
||||
PrintAndLogDevice(SUCCESS, "Key present");
|
||||
PrintAndLogDevice(SUCCESS, "Checking key parity...");
|
||||
PrintAndLogEx(SUCCESS, "Key present");
|
||||
PrintAndLogEx(SUCCESS, "Checking key parity...");
|
||||
des_checkParity(key);
|
||||
mbedtls_des_setkey_enc(&ctx_enc, key);
|
||||
mbedtls_des_setkey_dec(&ctx_dec, key);
|
||||
// Test hashing functions
|
||||
PrintAndLogDevice(SUCCESS, "The following tests require the correct 8-byte master key");
|
||||
PrintAndLogEx(SUCCESS, "The following tests require the correct 8-byte master key");
|
||||
testKeyDiversificationWithMasterkeyTestcases();
|
||||
}
|
||||
}
|
||||
PrintAndLogDevice(SUCCESS, "Testing key diversification with non-sensitive keys...");
|
||||
PrintAndLogEx(SUCCESS, "Testing key diversification with non-sensitive keys...");
|
||||
doTestsWithKnownInputs();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user