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:
Philippe Teuwen
2019-08-08 16:57:33 +02:00
parent b7d412d27b
commit d19754567d
447 changed files with 2553 additions and 2599 deletions

View File

@@ -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;

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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...) { }

View File

@@ -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;
}