diff --git a/CHANGELOG.md b/CHANGELOG.md index 82af9ead6..c660d2011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Changed `data num` - now can print reversed and inverse (@iceman1001) + - Fixed `hf mf sim -ix` never returning console (@datatags) + - Added standalone mode `hf_unisniff` combining 14a/14b/15 sniffing with extra flash save options (@hazardousvoltage) - Added encryption and other SL3 functions for Mifare Plus - more to come (@team-orangeBlue) - Fixed the corrupted data in real-time sampling (@wh201906) - Added a slider in the plot window for navigation (@wh201906) @@ -12,8 +15,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac - Changed `hf 14a info` - now reads and prints QL88 sigantures (@iceman1001) - Fixed `hf iclass dump` truncating AA2 blocks and improve reliability (@nvx) - Added some info about UMC in "doc/magic_cards_notes.md" (@temskiy) - - Added standalone mode `hf_unisniff` combining 14a/14b/15 sniffing with extra flash save options (@hazardousvoltage) - - Fixed `hf mf sim -ix` never returning console (@datatags) ## [Faraday.4.17511][2023-11-13] - Fixed Python support of `experimental_client_with_swig` (@doegox) diff --git a/armsrc/hitag2crack.c b/armsrc/hitag2crack.c index bd5fc2a94..138fdf451 100644 --- a/armsrc/hitag2crack.c +++ b/armsrc/hitag2crack.c @@ -339,7 +339,7 @@ bool hitag2crack_read_page(uint8_t *responsestr, uint8_t pagenum, uint8_t *nrar, // decrypt response hitag2crack_xor(response, e_response, keybits + 10, 32); // convert to hexstring - binarraytohex(responsestr, response, 32); + binarray_2_hex(responsestr, response, 32); return true; } else { UserMessage("hitag2crack_read_page:\r\n hitag2crack_send_e_cmd returned ERROR_RESPONSE\r\n"); @@ -424,7 +424,7 @@ bool hitag2crack_tx_rx(uint8_t *responsestr, uint8_t *msg, int len, int state, b } // convert response to hexstring - binarraytohex(responsestr, tmp + 5, 32); + binarray_2_hex(responsestr, tmp + 5, 32); return true; } else { #ifdef RFIDLER_DEBUG @@ -506,8 +506,8 @@ bool hitag2crack_decrypt_hex(uint8_t *response, uint8_t *hex) { binulong = hextoulong(hex); ulongtobinarray(bin, hitag2_crypt(binulong, 32), 32); - binarraytobinstring(binstr, bin, 32); - binarraytohex(binhex, bin, 32); + binarray_2_binstr(binstr, bin, 32); + binarray_2_hex(binhex, bin, 32); // UserMessage("ar = %s\r\n", binstr); // UserMessage("arhex = %s\r\n", binhex); @@ -532,7 +532,7 @@ bool hitag2crack_decrypt_bin(uint8_t *response, uint8_t *e_binstr) { binulong = binarraytoulong(e_bin, len); ulongtobinarray(bin, hitag2_crypt(binulong, len), len); - binarraytobinstring(binstr, bin, len); + binarray_2_binstr(binstr, bin, len); strcpy(response, binstr); return true; } @@ -646,7 +646,7 @@ bool hitag2_keystream(uint8_t *response, uint8_t *nrarhex) { } for (i = 0; i < 2048; i += 256) { - binarraytohex(keybitshex, keybits + i, 256); + binarray_2_hex(keybitshex, keybits + i, 256); UserMessage("%s\r\n", keybitshex); } diff --git a/armsrc/optimized_cipher.c b/armsrc/optimized_cipher.c index 68b36af85..c2ffa5da9 100644 --- a/armsrc/optimized_cipher.c +++ b/armsrc/optimized_cipher.c @@ -115,12 +115,12 @@ static void init_opt_select_LUT(void) { print_result("", opt_select_LUT, 256); } ***********************************************************************************/ - +/* #define opt__select(x,y,r) (4 & (((r & (r << 2)) >> 5) ^ ((r & ~(r << 2)) >> 4) ^ ( (r | r << 2) >> 3)))\ |(2 & (((r | r << 2) >> 6) ^ ( (r | r << 2) >> 1) ^ (r >> 5) ^ r ^ ((x^y) << 1)))\ |(1 & (((r & ~(r << 2)) >> 4) ^ ((r & (r << 2)) >> 3) ^ r ^ x)) -/* + * Some background on the expression above can be found here... uint8_t xopt__select(bool x, bool y, uint8_t r) { @@ -201,7 +201,9 @@ static void opt_suc(const uint8_t *k, State_t *s, const uint8_t *in, uint8_t len } //For tag MAC, an additional 32 zeroes if (add32Zeroes) { - for (int i = 0; i < 16; i++) { + for (int i = 0; i < 8; i++) { + opt_successor(k, s, 0); + opt_successor(k, s, 0); opt_successor(k, s, 0); opt_successor(k, s, 0); } diff --git a/armsrc/optimized_cipherutils.c b/armsrc/optimized_cipherutils.c index 3afba7164..66a618291 100644 --- a/armsrc/optimized_cipherutils.c +++ b/armsrc/optimized_cipherutils.c @@ -114,7 +114,7 @@ uint64_t x_bytes_to_num(uint8_t *src, size_t len) { return num; } -uint8_t reversebytes(uint8_t b) { +uint8_t reversebyte(uint8_t b) { b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; b = (b & 0xCC) >> 2 | (b & 0x33) << 2; b = (b & 0xAA) >> 1 | (b & 0x55) << 1; @@ -124,14 +124,14 @@ uint8_t reversebytes(uint8_t b) { void reverse_arraybytes(uint8_t *arr, size_t len) { size_t i; for (i = 0; i < len ; i++) { - arr[i] = reversebytes(arr[i]); + arr[i] = reversebyte(arr[i]); } } void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) { size_t i; for (i = 0; i < len ; i++) { - dest[i] = reversebytes(arr[i]); + dest[i] = reversebyte(arr[i]); } } diff --git a/armsrc/optimized_cipherutils.h b/armsrc/optimized_cipherutils.h index 1bef017a2..8d8a75f8c 100644 --- a/armsrc/optimized_cipherutils.h +++ b/armsrc/optimized_cipherutils.h @@ -57,7 +57,7 @@ int bitsLeft(BitstreamIn_t *stream); void push6bits(BitstreamOut_t *stream, uint8_t bits); void x_num_to_bytes(uint64_t n, size_t len, uint8_t *dest); uint64_t x_bytes_to_num(uint8_t *src, size_t len); -uint8_t reversebytes(uint8_t b); +uint8_t reversebyte(uint8_t b); void reverse_arraybytes(uint8_t *arr, size_t len); void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len); #endif // CIPHERUTILS_H diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 62b824304..74d6e3262 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -276,7 +276,7 @@ int printDemodBuff(uint8_t offset, bool strip_leading, bool invert, bool print_h if (print_hex) { p = (buf + offset); char hex[MAX_DEMODULATION_BITS + 1] = {0x00}; - int num_bits = binarraytohex(hex, sizeof(hex), (char *)p, len); + int num_bits = binarray_2_hex(hex, sizeof(hex), (char *)p, len); if (num_bits == 0) { p = NULL; free(buf); @@ -3281,6 +3281,7 @@ static int CmdNumCon(const char *Cmd) { arg_str0(NULL, "hex", "", "hexadecimal value"), arg_str0(NULL, "bin", "", "binary value"), arg_lit0("i", NULL, "print inverted value"), + arg_lit0("r", NULL, "print reversed value"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, false); @@ -3302,6 +3303,7 @@ static int CmdNumCon(const char *Cmd) { res |= CLIParamStrToBuf(arg_get_str(ctx, 3), (uint8_t *)bin, sizeof(bin), &blen); bool shall_invert = arg_get_lit(ctx, 4); + bool shall_reverse = arg_get_lit(ctx, 5); CLIParserFree(ctx); // sanity checks @@ -3343,11 +3345,6 @@ static int CmdNumCon(const char *Cmd) { mbedtls_mpi_init(&base); mbedtls_mpi_add_int(&base, &base, 10); - if (shall_invert) { - PrintAndLogEx(INFO, "should invert"); - MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&N, &N, &base)); - } - // printing typedef struct { const char *desc; @@ -3365,11 +3362,53 @@ static int CmdNumCon(const char *Cmd) { for (uint8_t i = 0; i < ARRAYLEN(radix); i++) { MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(&N, radix[i].radix, s, sizeof(s), &slen)); - if (slen > 0) { + if (slen) { PrintAndLogEx(SUCCESS, "%s%s", radix[i].desc, s); } } + // reverse + if (shall_reverse) { + PrintAndLogEx(SUCCESS, _CYAN_("Reversed")); + for (uint8_t i = 0; i < ARRAYLEN(radix); i++) { + MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(&N, radix[i].radix, s, sizeof(s), &slen)); + + str_reverse(s, strlen(s)); + + if (slen) { + PrintAndLogEx(SUCCESS, "%s%s", radix[i].desc, s); + } + } + } + + // invert + if (shall_invert) { + PrintAndLogEx(SUCCESS, _CYAN_("Inverted")); + for (uint8_t i = 0; i < ARRAYLEN(radix); i++) { + MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(&N, radix[i].radix, s, sizeof(s), &slen)); + if (slen == 0) { + continue; + } + + switch(i) { + case 0: +// MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&N, &N, &base)); + break; + case 1: + str_inverse_hex(s, strlen(s)); + PrintAndLogEx(SUCCESS, "%s%s", radix[i].desc, s); + break; + case 2: + str_inverse_bin(s, strlen(s)); + PrintAndLogEx(SUCCESS, "%s%s", radix[i].desc, s); + break; + default: + break; + } + } + } + + // check if number is a prime mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 6da027c32..340af551a 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1349,7 +1349,7 @@ static int iclass_decode_credentials_new_pacs(uint8_t *d) { } uint8_t n = PICOPASS_BLOCK_SIZE - offset - 2; - byte_2_binstr(binstr, d + offset + 2, n); + bytes_2_binstr(binstr, d + offset + 2, n); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "PACS......... " _GREEN_("%s"), sprint_hex_inrow(d + offset + 2, n)); @@ -4562,7 +4562,7 @@ static int CmdHFiClassSAM(const char *Cmd) { return PM3_EMALLOC; } - byte_2_binstr(binstr, d + 3, n); + bytes_2_binstr(binstr, d + 3, n); PrintAndLogEx(NORMAL, ""); PrintAndLogEx(SUCCESS, "PACS......... " _GREEN_("%s"), sprint_hex_inrow(d + 2, resp.length - 2)); diff --git a/client/src/cmdlft55xx.c b/client/src/cmdlft55xx.c index e181f8667..894ad3b5d 100644 --- a/client/src/cmdlft55xx.c +++ b/client/src/cmdlft55xx.c @@ -1677,7 +1677,7 @@ static int CmdT55xxDangerousRaw(const char *Cmd) { return PM3_EINVARG; } - int bs_len = binstring2binarray(ng.data, (char *)bin, bin_len); + int bs_len = binstr_2_binarray(ng.data, (char *)bin, bin_len); if (bs_len == 0) { return PM3_EINVARG; } diff --git a/client/src/fileutils.c b/client/src/fileutils.c index d8c4afe90..a17ca625b 100644 --- a/client/src/fileutils.c +++ b/client/src/fileutils.c @@ -986,7 +986,7 @@ int loadFileEML_safe(const char *preferredName, void **pdata, size_t *datalen) { if (line[0] == '#') continue; - strcleanrn(line, sizeof(line)); + str_cleanrn(line, sizeof(line)); res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen); if (res == 0) { @@ -1059,7 +1059,7 @@ int loadFileNFC_safe(const char *preferredName, void *data, size_t maxdatalen, s if (line[0] == '#') continue; - strcleanrn(line, sizeof(line)); + str_cleanrn(line, sizeof(line)); str_lower(line); if (str_startswith(line, "uid:")) { @@ -1306,7 +1306,7 @@ int loadFileMCT_safe(const char *preferredName, void **pdata, size_t *datalen) { if (line[0] == '+') continue; - strcleanrn(line, sizeof(line)); + str_cleanrn(line, sizeof(line)); res = param_gethex_to_eol(line, 0, buf, sizeof(buf), &hexlen); if (res == 0) { @@ -2261,7 +2261,7 @@ nfc_df_e detect_nfc_dump_format(const char *preferredName, bool verbose) { return PM3_EFILE; } - strcleanrn(line, sizeof(line)); + str_cleanrn(line, sizeof(line)); str_lower(line); if (str_startswith(line, "device type: ntag")) { diff --git a/client/src/loclass/cipherutils.h b/client/src/loclass/cipherutils.h index 160945f0d..f3dc9d5f3 100644 --- a/client/src/loclass/cipherutils.h +++ b/client/src/loclass/cipherutils.h @@ -63,7 +63,7 @@ void push6bits(BitstreamOut_t *stream, uint8_t bits); void EncryptDES(bool key[56], bool outBlk[64], bool inBlk[64], int verbose) ; void x_num_to_bytes(uint64_t n, size_t len, uint8_t *dest); uint64_t x_bytes_to_num(uint8_t *src, size_t len); -uint8_t reversebytes(uint8_t b); +uint8_t reversebyte(uint8_t b); void reverse_arraybytes(uint8_t *arr, size_t len); void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len); void printarr(const char *name, uint8_t *arr, int len); diff --git a/client/src/proxmark3.c b/client/src/proxmark3.c index 85b85f762..00e93c6d1 100644 --- a/client/src/proxmark3.c +++ b/client/src/proxmark3.c @@ -223,7 +223,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) { uint16_t script_cmd_len = 0; if (execCommand) { script_cmd_len = strlen(script_cmd); - strcreplace(script_cmd, script_cmd_len, ';', '\0'); + str_creplace(script_cmd, script_cmd_len, ';', '\0'); } bool stdinOnPipe = !isatty(STDIN_FILENO); char script_cmd_buf[256] = {0x00}; // iceman, needs lua script the same file_path_buffer as the rest @@ -312,7 +312,7 @@ check_script: prompt_ctx = PROXPROMPT_CTX_SCRIPTFILE; // remove linebreaks - strcleanrn(script_cmd_buf, sizeof(script_cmd_buf)); + str_cleanrn(script_cmd_buf, sizeof(script_cmd_buf)); cmd = str_dup(script_cmd_buf); if (cmd != NULL) { @@ -354,9 +354,9 @@ check_script: fromInteractive = false; script_cmd = script_cmd_buf; script_cmd_len = strlen(script_cmd); - strcreplace(script_cmd, script_cmd_len, ';', '\0'); + str_creplace(script_cmd, script_cmd_len, ';', '\0'); // remove linebreaks - strcleanrn(script_cmd, script_cmd_len); + str_cleanrn(script_cmd, script_cmd_len); goto check_script; } else { pm3line_check(check_comm); @@ -376,9 +376,9 @@ check_script: stayInCommandLoop = true; fromInteractive = true; script_cmd_len = strlen(script_cmd); - strcreplace(script_cmd, script_cmd_len, ';', '\0'); + str_creplace(script_cmd, script_cmd_len, ';', '\0'); // remove linebreaks - strcleanrn(script_cmd, script_cmd_len); + str_cleanrn(script_cmd, script_cmd_len); goto check_script; } fflush(NULL); diff --git a/client/src/util.c b/client/src/util.c index 205c2d32f..76a7b24ea 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -92,6 +92,30 @@ int kbd_enter_pressed(void) { } #endif +static char inv_b2s(char v, bool uppercase) { + + if (isxdigit(v) == 0) { + return '.'; + } + + uint8_t lut[] = { + 'f', 'e', 'd', 'c', + 'b', 'a', '9', '8', + '7', '6', '5', '4', + '3', '2', '1', '0' + }; + + uint8_t tmp = (tolower(v) - 'a' + 10); + if (isdigit(v)) { + tmp = (v - 0x30); + } + + if (uppercase) + return toupper(lut[tmp]); + else + return lut[tmp]; +} + static char b2s(uint8_t v, bool uppercase) { // clear higher bits v &= 0xF; @@ -938,12 +962,12 @@ int hextobinstring_n(char *target, char *source, int sourcelen) { if (length == 0) { return 0; } - binarraytobinstring(target, target, length); + binarray_2_binstr(target, target, length); return length; } // convert bytes to binary string -void byte_2_binstr(char *target, const uint8_t *source, size_t sourcelen) { +void bytes_2_binstr(char *target, const uint8_t *source, size_t sourcelen) { //uint8_t *p = *source; for (int i = 0 ; i < sourcelen; ++i) { uint8_t b = *(source++); @@ -961,7 +985,7 @@ void byte_2_binstr(char *target, const uint8_t *source, size_t sourcelen) { // convert binary array of 0x00/0x01 values to hex // return number of bits converted -int binarraytohex(char *target, const size_t targetlen, const char *source, size_t srclen) { +int binarray_2_hex(char *target, const size_t targetlen, const char *source, size_t srclen) { uint8_t i = 0, x = 0; uint32_t t = 0; // written target chars uint32_t r = 0; // consumed bits @@ -1007,14 +1031,14 @@ int binarraytohex(char *target, const size_t targetlen, const char *source, size } // convert binary array to human readable binary -void binarraytobinstring(char *target, char *source, int length) { +void binarray_2_binstr(char *target, char *source, int length) { for (int i = 0 ; i < length; ++i) { *(target++) = *(source++) + '0'; } *target = '\0'; } -int binstring2binarray(uint8_t *target, char *source, int length) { +int binstr_2_binarray(uint8_t *target, char *source, int length) { int count = 0; char *start = source; while (length--) { @@ -1171,13 +1195,13 @@ void clean_ascii(unsigned char *buf, size_t len) { } // replace \r \n to \0 -void strcleanrn(char *buf, size_t len) { - strcreplace(buf, len, '\n', '\0'); - strcreplace(buf, len, '\r', '\0'); +void str_cleanrn(char *buf, size_t len) { + str_creplace(buf, len, '\n', '\0'); + str_creplace(buf, len, '\r', '\0'); } // replace char in buffer -void strcreplace(char *buf, size_t len, char from, char to) { +void str_creplace(char *buf, size_t len, char from, char to) { for (size_t i = 0; i < len; i++) { if (buf[i] == from) buf[i] = to; @@ -1208,6 +1232,34 @@ size_t str_nlen(const char *src, size_t maxlen) { return len; } +void str_reverse(char *buf, size_t len) { + for (size_t i = 0; i < (len>>1); i++) { + char tmp = buf[i]; + buf[i] = buf[len - i - 1]; + buf[len - i - 1] = tmp; + } +} + +void str_inverse_hex(char *buf, size_t len) { + for (size_t i = 0; i < len; i++) { + buf[i] = inv_b2s(buf[i], true); + } +} + +void str_inverse_bin(char *buf, size_t len) { + for (size_t i = 0; i < len; i++) { + + char c = buf[i]; + if (c == '1') + buf[i] = '0'; + else if ( c == '0') + buf[i] = '1'; + else + buf[i] = '.'; + } +} + + /** * Converts a hex string to component "hi2", "hi" and "lo" 32-bit integers * one nibble at a time. diff --git a/client/src/util.h b/client/src/util.h index 1d6df987d..1949c1d53 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -117,11 +117,11 @@ int hextobinarray_n(char *target, char *source, int sourcelen); int hextobinstring(char *target, char *source); int hextobinstring_n(char *target, char *source, int sourcelen); -int binarraytohex(char *target, const size_t targetlen, const char *source, size_t srclen); -void binarraytobinstring(char *target, char *source, int length); -int binstring2binarray(uint8_t *target, char *source, int length); +int binarray_2_hex(char *target, const size_t targetlen, const char *source, size_t srclen); +void binarray_2_binstr(char *target, char *source, int length); +int binstr_2_binarray(uint8_t *target, char *source, int length); -void byte_2_binstr(char *target, const uint8_t *source, size_t sourcelen); +void bytes_2_binstr(char *target, const uint8_t *source, size_t sourcelen); void binstr_2_bytes(uint8_t *target, size_t *targetlen, const char *src); uint8_t GetParity(const uint8_t *bits, uint8_t type, int length); @@ -143,8 +143,12 @@ void strn_upper(char *s, size_t n); bool str_startswith(const char *s, const char *pre); // check for prefix in string bool str_endswith(const char *s, const char *suffix); // check for suffix in string void clean_ascii(unsigned char *buf, size_t len); -void strcleanrn(char *buf, size_t len); -void strcreplace(char *buf, size_t len, char from, char to); +void str_cleanrn(char *buf, size_t len); +void str_creplace(char *buf, size_t len, char from, char to); +void str_reverse(char *buf, size_t len); +void str_inverse_hex(char *buf, size_t len); +void str_inverse_bin(char *buf, size_t len); + char *str_dup(const char *src); char *str_ndup(const char *src, size_t len); size_t str_nlen(const char *src, size_t maxlen);