├── .gitignore ├── hardnested ├── tables.h ├── hardnested_bruteforce.h ├── hardnested_bitarray_core.h ├── hardnested_bf_core.h ├── hardnested_bruteforce.c ├── hardnested_bitarray_core.c └── hardnested_bf_core.c ├── pm3 ├── emojis_alt.h ├── commonutil.c ├── util_posix.h ├── util.h ├── util.c ├── ansi.h ├── commonutil.h ├── ui.h ├── common.h ├── util_posix.c └── ui.c ├── cmdhfmfhard.h ├── Makefile ├── README.md ├── crapto1.h ├── parity.h ├── hardnested_main.c ├── crypto1.c ├── LICENSE.md └── crapto1.c /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | bin/ 10 | build/ 11 | develop-eggs/ 12 | dist/ 13 | eggs/ 14 | lib/ 15 | lib64/ 16 | parts/ 17 | sdist/ 18 | var/ 19 | *.egg-info/ 20 | .installed.cfg 21 | *.egg 22 | wheelhouse/ 23 | 24 | # Installer logs 25 | pip-log.txt 26 | pip-delete-this-directory.txt 27 | 28 | # Unit test / coverage reports 29 | .tox/ 30 | .coverage 31 | .cache 32 | nosetests.xml 33 | coverage.xml 34 | .pytest_cache 35 | 36 | # Nested log files, recovered keys 37 | .nested.log 38 | *.keys 39 | -------------------------------------------------------------------------------- /hardnested/tables.h: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | /* 8 | * File: tables.h 9 | * Author: vk496 10 | * 11 | * Created on 15 de noviembre de 2018, 17:42 12 | */ 13 | 14 | #ifndef TABLES_H 15 | #define TABLES_H 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "../cmdhfmfhard.h" 26 | 27 | typedef struct bitflip_info { 28 | uint32_t len; 29 | uint8_t *input_buffer; 30 | } bitflip_info; 31 | 32 | typedef enum { 33 | EVEN_STATE = 0, 34 | ODD_STATE = 1 35 | } odd_even_t; 36 | 37 | 38 | bitflip_info get_bitflip(odd_even_t odd_num, uint16_t id); 39 | bool decompress(lzma_stream* strm); 40 | void lzma_init_inflate(lzma_stream *strm, uint8_t *inbuf, uint32_t inbuf_len, uint8_t *outbuf, uint32_t outbuf_len); 41 | void lzma_init_decoder(lzma_stream *strm); 42 | 43 | #endif /* TABLES_H */ 44 | 45 | -------------------------------------------------------------------------------- /pm3/emojis_alt.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | #ifndef EMOJIS_ALT_H__ 17 | #define EMOJIS_ALT_H__ 18 | 19 | typedef struct emoji_alt_s { 20 | const char *alias; 21 | const char *alttext; 22 | } emoji_alt_t; 23 | // emoji_alt_t array are expected to be NULL terminated 24 | 25 | static emoji_alt_t EmojiAltTable[] = { 26 | {":wink:", ";)"}, 27 | {NULL, NULL} 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /pm3/commonutil.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // Utility functions used in many places, not specific to any piece of code. 17 | //----------------------------------------------------------------------------- 18 | #include "commonutil.h" 19 | 20 | uint64_t bytes_to_num(uint8_t *src, size_t len) { 21 | uint64_t num = 0; 22 | while (len--) { 23 | num = (num << 8) | (*src); 24 | src++; 25 | } 26 | return num; 27 | } -------------------------------------------------------------------------------- /pm3/util_posix.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // utilities requiring Posix library functions 17 | //----------------------------------------------------------------------------- 18 | 19 | #ifndef UTIL_POSIX_H__ 20 | #define UTIL_POSIX_H__ 21 | 22 | #include "common.h" 23 | 24 | #ifdef _WIN32 25 | # include 26 | # define sleep(n) Sleep(1000 *(n)) 27 | # define msleep(n) Sleep((n)) 28 | #else 29 | void msleep(uint32_t n); // sleep n milliseconds 30 | #endif // _WIN32 31 | 32 | uint64_t msclock(void); // a milliseconds clock 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /pm3/util.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // utilities 17 | //----------------------------------------------------------------------------- 18 | #ifndef __UTIL_H_ 19 | #define __UTIL_H_ 20 | 21 | #include "common.h" 22 | 23 | #ifdef ANDROID 24 | #include 25 | #endif 26 | 27 | // used for save/load files 28 | #ifndef FILE_PATH_SIZE 29 | # define FILE_PATH_SIZE 1000 30 | #endif 31 | 32 | extern uint8_t g_debugMode; 33 | extern uint8_t g_printAndLog; 34 | 35 | #define PRINTANDLOG_PRINT 1 36 | #define PRINTANDLOG_LOG 2 37 | 38 | int num_CPUs(void); // number of logical CPUs 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /cmdhfmfhard.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // hf mf hardnested command 17 | //----------------------------------------------------------------------------- 18 | 19 | #ifndef CMDHFMFHARD_H__ 20 | #define CMDHFMFHARD_H__ 21 | 22 | #include "pm3/common.h" 23 | 24 | int 25 | mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, 26 | bool nonce_file_read, bool nonce_file_write, bool slow, uint64_t *foundkey, char *filename, uint32_t uid, char* path); 27 | void hardnested_print_progress(uint32_t nonces, const char *activity, float brute_force, uint64_t min_diff_print_time); 28 | 29 | #endif 30 | 31 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Compiler and flags 2 | CC = gcc 3 | CFLAGS = -Wall -fPIC -I. -I./pm3 -I./hardnested 4 | LDFLAGS = -static -llzma -lpthread -lm 5 | 6 | HARDNESTED_DIR = . 7 | 8 | # Source files 9 | HARDNESTED_SOURCES = $(HARDNESTED_DIR)/pm3/ui.c $(HARDNESTED_DIR)/pm3/util.c \ 10 | $(HARDNESTED_DIR)/cmdhfmfhard.c $(HARDNESTED_DIR)/pm3/commonutil.c \ 11 | $(HARDNESTED_DIR)/crapto1.c $(HARDNESTED_DIR)/crypto1.c \ 12 | $(HARDNESTED_DIR)/hardnested/hardnested_bf_core.c \ 13 | $(HARDNESTED_DIR)/hardnested/hardnested_bruteforce.c \ 14 | $(HARDNESTED_DIR)/hardnested/hardnested_bitarray_core.c \ 15 | $(HARDNESTED_DIR)/hardnested/tables.c \ 16 | $(HARDNESTED_DIR)/pm3/util_posix.c 17 | 18 | # Object files 19 | HARDNESTED_OBJECTS = $(HARDNESTED_SOURCES:.c=.o) 20 | 21 | # Dependency files 22 | HARDNESTED_DEPS = $(HARDNESTED_SOURCES:.c=.d) 23 | 24 | # Executable target 25 | EXECUTABLE = hardnested_main 26 | 27 | # Targets 28 | all: $(EXECUTABLE) 29 | 30 | $(EXECUTABLE): hardnested_main.c $(HARDNESTED_OBJECTS) 31 | $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) 32 | 33 | %.o: %.c 34 | $(CC) $(CFLAGS) -c $< -o $@ 35 | 36 | clean: 37 | rm -f $(HARDNESTED_OBJECTS) $(HARDNESTED_DEPS) $(EXECUTABLE) 38 | 39 | .PHONY: all clean 40 | 41 | # Include dependencies 42 | -include $(HARDNESTED_OBJECTS:.o=.d) 43 | 44 | # Generate dependencies 45 | %.d: %.c 46 | @$(CC) -MM $(CFLAGS) $< > $@.$$$$; \ 47 | sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ 48 | rm -f $@.$$$$ 49 | -------------------------------------------------------------------------------- /pm3/util.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // utilities 17 | //----------------------------------------------------------------------------- 18 | 19 | #include "util.h" 20 | 21 | // global client debug variable 22 | uint8_t g_debugMode = 0; 23 | // global client disable logging variable 24 | uint8_t g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG; 25 | // global client tell if a pending prompt is present 26 | 27 | #ifdef _WIN32 28 | #include 29 | #else 30 | #include 31 | #endif 32 | 33 | // determine number of logical CPU cores (use for multithreaded functions) 34 | int num_CPUs(void) { 35 | #if defined(_WIN32) 36 | #include 37 | SYSTEM_INFO sysinfo; 38 | GetSystemInfo(&sysinfo); 39 | return sysinfo.dwNumberOfProcessors; 40 | #else 41 | int count = sysconf(_SC_NPROCESSORS_ONLN); 42 | if (count <= 0) 43 | count = 1; 44 | return count; 45 | #endif 46 | } 47 | -------------------------------------------------------------------------------- /pm3/ansi.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | #ifndef __ANSI_H 17 | #define __ANSI_H 18 | 19 | // Not ANSI but dirty trick to specify we don't want a \n 20 | #define NOLF "\xff" 21 | 22 | #define AEND "\x1b[0m" 23 | 24 | #define _RED_(s) "\x1b[31m" s AEND 25 | #define _GREEN_(s) "\x1b[32m" s AEND 26 | #define _YELLOW_(s) "\x1b[33m" s AEND 27 | #define _BLUE_(s) "\x1b[34m" s AEND 28 | #define _CYAN_(s) "\x1b[36m" s AEND 29 | 30 | #if defined(HAVE_READLINE) 31 | // https://wiki.hackzine.org/development/misc/readline-color-prompt.html 32 | // Applications may indicate that the prompt contains 33 | // characters that take up no physical screen space when displayed by 34 | // bracketing a sequence of such characters with the special markers 35 | // RL_PROMPT_START_IGNORE = '\001' and RL_PROMPT_END_IGNORE = '\002' 36 | #define RL_ESC(a) "\001" a "\002" 37 | #else 38 | #define RL_ESC(a) a 39 | #endif // HAVE_READLINE 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /pm3/commonutil.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // Utility functions used in many places, not specific to any piece of code. 17 | //----------------------------------------------------------------------------- 18 | 19 | #ifndef __COMMONUTIL_H 20 | #define __COMMONUTIL_H 21 | 22 | #include "common.h" 23 | 24 | // endian change for 16bit 25 | #ifdef __GNUC__ 26 | #ifndef BSWAP_16 27 | #define BSWAP_16(x) __builtin_bswap16(x) 28 | #endif 29 | #else 30 | #ifdef _MSC_VER 31 | #ifndef BSWAP_16 32 | #define BSWAP_16(x) _byteswap_ushort(x) 33 | #endif 34 | #else 35 | #ifndef BSWAP_16 36 | # define BSWAP_16(x) ((( ((x) & 0xFF00 ) >> 8))| ( (((x) & 0x00FF) << 8))) 37 | #endif 38 | #endif 39 | #endif 40 | 41 | #ifndef BITMASK 42 | # define BITMASK(X) (1 << (X)) 43 | #endif 44 | #ifndef ARRAYLEN 45 | # define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0])) 46 | #endif 47 | 48 | #ifndef NTIME 49 | # define NTIME(n) for (int _index = 0; _index < n; _index++) 50 | #endif 51 | 52 | uint64_t bytes_to_num(uint8_t *src, size_t len); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /hardnested/hardnested_bruteforce.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) 2016, 2017 by piwi 3 | // 4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, 5 | // at your option, any later version. See the LICENSE.txt file for the text of 6 | // the license. 7 | //----------------------------------------------------------------------------- 8 | // Implements a card only attack based on crypto text (encrypted nonces 9 | // received during a nested authentication) only. Unlike other card only 10 | // attacks this doesn't rely on implementation errors but only on the 11 | // inherent weaknesses of the crypto1 cypher. Described in 12 | // Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened 13 | // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on 14 | // Computer and Communications Security, 2015 15 | //----------------------------------------------------------------------------- 16 | 17 | #ifndef HARDNESTED_BRUTEFORCE_H__ 18 | #define HARDNESTED_BRUTEFORCE_H__ 19 | 20 | #include 21 | #include 22 | 23 | #define NUM_SUMS 19 // number of possible sum property values 24 | 25 | typedef struct guess_sum_a8 { 26 | float prob; 27 | uint64_t num_states; 28 | uint16_t sum_a8_idx; 29 | } guess_sum_a8_t; 30 | 31 | typedef struct noncelistentry { 32 | uint32_t nonce_enc; 33 | uint8_t par_enc; 34 | void *next; 35 | } noncelistentry_t; 36 | 37 | typedef struct noncelist { 38 | uint16_t num; 39 | uint16_t Sum; 40 | guess_sum_a8_t sum_a8_guess[NUM_SUMS]; 41 | bool sum_a8_guess_dirty; 42 | float expected_num_brute_force; 43 | uint16_t BitFlips[0x400]; 44 | uint32_t *states_bitarray[2]; 45 | uint32_t num_states_bitarray[2]; 46 | bool all_bitflips_dirty[2]; 47 | noncelistentry_t *first; 48 | } noncelist_t; 49 | 50 | typedef struct { 51 | uint32_t *states[2]; 52 | uint32_t len[2]; 53 | void *next; 54 | } statelist_t; 55 | 56 | void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte); 57 | bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes, uint64_t *found_key); 58 | float brute_force_benchmark(void); 59 | uint8_t trailing_zeros(uint8_t byte); 60 | bool verify_key(uint32_t cuid, noncelist_t *nonces, const uint8_t *best_first_bytes, uint32_t odd, uint32_t even); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # HardnestedRecovery 2 | 3 | Program recovers keys from collected authorization challenges (nonces). 4 | You can collect nonces on Flipper Zero with the NFC app using [PR 3822](https://github.com/flipperdevices/flipperzero-firmware/pull/3822) 5 | 6 | ## Setup 7 | 8 | First, install dependencies (Ubuntu): 9 | 10 | `sudo apt update;sudo apt install -y build-essential liblzma-dev` 11 | 12 | Then compile the program: 13 | 14 | `make` 15 | 16 | ## Usage 17 | 18 | Using qFlipper or the Flipper Mobile App, download the nonces stored at (/ext/)nfc/.nested.log. Then recover the keys by running the program with the path to .nested.log on your computer: 19 | 20 | ```bash 21 | $ ./hardnested_main .nested.log 22 | ``` 23 | 24 | ## Example 25 | 26 | 27 | ``` 28 | $ ./hardnested_main .nested.log 29 | [=] Hardnested attack starting... 30 | [=] ---------+---------+---------------------------------------------------------+-----------------+------- 31 | [=] | | | Expected to brute force 32 | [=] Time | #nonces | Activity | #states | time 33 | [=] ---------+---------+---------------------------------------------------------+-----------------+------- 34 | [=] 0 | 0 | Start using 8 threads | | 35 | [=] 0 | 0 | Brute force benchmark: 124 million (2^26.9) keys/s | 140737488355328 | 13d 36 | [=] 1 | 0 | Using 235 precalculated bitflip state tables | 140737488355328 | 13d 37 | [=] 26 | 256 | Loading nonces from file | 641827520 | 5s 38 | [=] 42 | 512 | Loading nonces from file | 216530400 | 2s 39 | [=] 51 | 768 | Loading nonces from file | 216530400 | 2s 40 | [=] 54 | 1024 | Loading nonces from file | 216530400 | 2s 41 | [=] 60 | 1051 | Apply Sum property. Sum(a0) = 120 | 32340672 | 0s 42 | [=] 60 | 1051 | (Ignoring Sum(a8) properties) | 32340672 | 0s 43 | [=] 63 | 1051 | Brute force phase completed. Key found: A0A1A2A3A4A5 | 0 | 0s 44 | Key found for UID: aabbccdd, Sector: 1, Key type: A: a0a1a2a3a4a5 45 | ``` 46 | 47 | Copy each found key to the user dictionary on your Flipper device at (/ext/)nfc/assets/mf_classic_dict_user.nfc and re-read your tag using the NFC app. 48 | -------------------------------------------------------------------------------- /pm3/ui.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // UI utilities 17 | //----------------------------------------------------------------------------- 18 | 19 | #ifndef UI_H__ 20 | #define UI_H__ 21 | 22 | #include "common.h" 23 | #include "../pm3/ansi.h" 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | #define _USE_MATH_DEFINES 30 | 31 | typedef enum {STYLE_BAR, STYLE_MIXED, STYLE_VALUE} barMode_t; 32 | typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t; 33 | typedef enum emojiMode {EMO_ALIAS, EMO_EMOJI, EMO_ALTTEXT, EMO_NONE} emojiMode_t; 34 | typedef enum clientdebugLevel {cdbOFF, cdbSIMPLE, cdbFULL} clientdebugLevel_t; 35 | // typedef enum devicedebugLevel {ddbOFF, ddbERROR, ddbINFO, ddbDEBUG, ddbEXTENDED} devicedebugLevel_t; 36 | 37 | // last item spItemCount used to auto map to number of files 38 | typedef enum savePaths {spDefault, spDump, spTrace, spItemCount} savePaths_t; 39 | typedef struct {int x; int y; int h; int w;} qtWindow_t; 40 | 41 | typedef struct { 42 | bool preferences_loaded; 43 | bool stdinOnTTY; 44 | bool stdoutOnTTY; 45 | bool supports_colors; 46 | emojiMode_t emoji_mode; 47 | bool pm3_present; 48 | bool help_dump_mode; 49 | bool show_hints; 50 | bool dense_output; 51 | bool window_changed; // track if plot/overlay pos/size changed to save on exit 52 | qtWindow_t plot; 53 | qtWindow_t overlay; 54 | bool overlay_sliders; 55 | bool incognito; 56 | char *defaultPaths[spItemCount]; // Array should allow loop searching for files 57 | clientdebugLevel_t client_debug_level; 58 | barMode_t bar_mode; 59 | // uint8_t device_debug_level; 60 | uint16_t client_exe_delay; 61 | char *history_path; 62 | } session_arg_t; 63 | 64 | extern session_arg_t g_session; 65 | #ifndef M_PI 66 | #define M_PI 3.14159265358979323846264338327 67 | #endif 68 | #define MAX_PRINT_BUFFER 2048 69 | 70 | void PrintAndLogEx(logLevel_t level, const char *fmt, ...); 71 | void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter); 72 | void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode); 73 | 74 | #ifdef __cplusplus 75 | } 76 | #endif 77 | #endif 78 | -------------------------------------------------------------------------------- /crapto1.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) 2008-2014 bla 3 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 4 | // 5 | // This program is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // See LICENSE.txt for the text of the license. 16 | //----------------------------------------------------------------------------- 17 | #ifndef crypto01_INCLUDED 18 | #define crypto01_INCLUDED 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | struct Crypto1State {uint32_t odd, even;}; 25 | void crypto1_init(struct Crypto1State *state, uint64_t key); 26 | void crypto1_deinit(struct Crypto1State *); 27 | struct Crypto1State *crypto1_create(uint64_t key); 28 | void crypto1_destroy(struct Crypto1State *); 29 | void crypto1_get_lfsr(struct Crypto1State *, uint64_t *); 30 | uint8_t crypto1_bit(struct Crypto1State *, uint8_t, int); 31 | uint8_t crypto1_byte(struct Crypto1State *, uint8_t, int); 32 | uint32_t crypto1_word(struct Crypto1State *, uint32_t, int); 33 | uint32_t prng_successor(uint32_t x, uint32_t n); 34 | 35 | struct Crypto1State * 36 | lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par); 37 | uint32_t *lfsr_prefix_ks(const uint8_t ks[8], int isodd); 38 | 39 | 40 | uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb); 41 | uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb); 42 | uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb); 43 | int nonce_distance(uint32_t from, uint32_t to); 44 | bool validate_prng_nonce(uint32_t nonce); 45 | #define FOREACH_VALID_NONCE(N, FILTER, FSIZE)\ 46 | uint32_t __n = 0,__M = 0, N = 0;\ 47 | int __i;\ 48 | for(; __n < 1 << 16; N = prng_successor(__M = ++__n, 16))\ 49 | for(__i = FSIZE - 1; __i >= 0; __i--)\ 50 | if(BIT(FILTER, __i) ^ evenparity32(__M & 0xFF01))\ 51 | break;\ 52 | else if(__i)\ 53 | __M = prng_successor(__M, (__i == 7) ? 48 : 8);\ 54 | else 55 | 56 | #define LF_POLY_ODD (0x29CE5C) 57 | #define LF_POLY_EVEN (0x870804) 58 | #define BIT(x, n) ((x) >> (n) & 1) 59 | #define BEBIT(x, n) BIT(x, (n) ^ 24) 60 | static inline int filter(uint32_t const x) { 61 | uint32_t f; 62 | 63 | f = 0xf22c0 >> (x & 0xf) & 16; 64 | f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8; 65 | f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4; 66 | f |= 0x1e458 >> (x >> 12 & 0xf) & 2; 67 | f |= 0x0d938 >> (x >> 16 & 0xf) & 1; 68 | return BIT(0xEC57E80A, f); 69 | } 70 | #endif 71 | -------------------------------------------------------------------------------- /hardnested/hardnested_bitarray_core.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) 2016, 2017 by piwi 3 | // 4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, 5 | // at your option, any later version. See the LICENSE.txt file for the text of 6 | // the license. 7 | //----------------------------------------------------------------------------- 8 | // Implements a card only attack based on crypto text (encrypted nonces 9 | // received during a nested authentication) only. Unlike other card only 10 | // attacks this doesn't rely on implementation errors but only on the 11 | // inherent weaknesses of the crypto1 cypher. Described in 12 | // Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened 13 | // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on 14 | // Computer and Communications Security, 2015 15 | //----------------------------------------------------------------------------- 16 | // 17 | // brute forcing is based on @aczids bitsliced brute forcer 18 | // https://github.com/aczid/crypto1_bs with some modifications. Mainly: 19 | // - don't rollback. Start with 2nd byte of nonce instead 20 | // - reuse results of filter subfunctions 21 | // - reuse results of previous nonces if some first bits are identical 22 | // 23 | //----------------------------------------------------------------------------- 24 | // aczid's Copyright notice: 25 | // 26 | // Bit-sliced Crypto-1 brute-forcing implementation 27 | // Builds on the data structures returned by CraptEV1 craptev1_get_space(nonces, threshold, uid) 28 | /* 29 | Copyright (c) 2015-2016 Aram Verstegen 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to deal 33 | in the Software without restriction, including without limitation the rights 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in 39 | all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47 | THE SOFTWARE. 48 | */ 49 | 50 | #ifndef HARDNESTED_BITARRAY_CORE_H__ 51 | #define HARDNESTED_BITARRAY_CORE_H__ 52 | 53 | #include 54 | 55 | uint32_t *malloc_bitarray(uint32_t x); 56 | void free_bitarray(uint32_t *x); 57 | uint32_t bitcount(uint32_t a); 58 | uint32_t count_states(uint32_t *A); 59 | void bitarray_AND(uint32_t *A, uint32_t *B); 60 | void bitarray_low20_AND(uint32_t *A, uint32_t *B); 61 | uint32_t count_bitarray_AND(uint32_t *A, uint32_t *B); 62 | uint32_t count_bitarray_low20_AND(uint32_t *A, uint32_t *B); 63 | void bitarray_AND4(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D); 64 | void bitarray_OR(uint32_t *A, uint32_t *B); 65 | uint32_t count_bitarray_AND2(uint32_t *A, uint32_t *B); 66 | uint32_t count_bitarray_AND3(uint32_t *A, uint32_t *B, uint32_t *C); 67 | uint32_t count_bitarray_AND4(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D); 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /parity.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // Parity functions 17 | //----------------------------------------------------------------------------- 18 | 19 | // all functions defined in header file by purpose. Allows compiler optimizations. 20 | #include 21 | #ifndef __PARITY_H 22 | #define __PARITY_H 23 | #define _CRT_NONSTDC_NO_WARNINGS 24 | #define _CRT_SECURE_NO_WARNINGS 25 | #define _CRT_NON_CONFORMING_SWPRINTFS 26 | 27 | #define restrict __restrict 28 | #define inline __inline 29 | #include 30 | #include 31 | 32 | static const uint8_t g_odd_byte_parity[256] = { 33 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 34 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 35 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 36 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 37 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 38 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 39 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 40 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 41 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 42 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 43 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 44 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 45 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 46 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 47 | 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 48 | 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 49 | }; 50 | 51 | #define ODD_PARITY8(x) (g_odd_byte_parity[x]) 52 | #define EVEN_PARITY8(x) (!g_odd_byte_parity[x]) 53 | 54 | static inline uint8_t oddparity8(const uint8_t x) { 55 | return g_odd_byte_parity[x]; 56 | } 57 | 58 | static inline uint8_t evenparity8(const uint8_t x) { 59 | return !g_odd_byte_parity[x]; 60 | } 61 | 62 | static inline uint8_t evenparity16(uint16_t x) { 63 | #if !defined __GNUC__ 64 | x ^= x >> 8; 65 | return EVEN_PARITY8(x); 66 | #else 67 | return (__builtin_parity(x) & 0xFF); 68 | #endif 69 | } 70 | 71 | static inline uint8_t oddparity16(uint16_t x) { 72 | #if !defined __GNUC__ 73 | x ^= x >> 8; 74 | return ODD_PARITY8(x); 75 | #else 76 | return !__builtin_parity(x); 77 | #endif 78 | } 79 | 80 | static inline uint8_t evenparity32(uint32_t x) { 81 | #if _MSC_VER 82 | x ^= x >> 16; 83 | x ^= x >> 8; 84 | x ^= x >> 4; 85 | x &= 0xf; 86 | return (0x6996 >> x) & 1; 87 | #elif !defined __GNUC__ 88 | x ^= x >> 16; 89 | x ^= x >> 8; 90 | return EVEN_PARITY8(x); 91 | #else 92 | return (__builtin_parity(x) & 0xFF); 93 | #endif 94 | } 95 | 96 | static inline uint8_t oddparity32(uint32_t x) { 97 | #if _MSC_VER 98 | x ^= x >> 16; 99 | x ^= x >> 8; 100 | x ^= x >> 4; 101 | x &= 0xf; 102 | return ((0x6996 >> x) & 1) ^ 1; 103 | #elif !defined __GNUC__ 104 | x ^= x >> 16; 105 | x ^= x >> 8; 106 | return ODD_PARITY8(x); 107 | #else 108 | return !__builtin_parity(x); 109 | #endif 110 | } 111 | 112 | #endif /* __PARITY_H */ -------------------------------------------------------------------------------- /pm3/common.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // Interlib Definitions 17 | //----------------------------------------------------------------------------- 18 | 19 | #ifndef __COMMON_H 20 | #define __COMMON_H 21 | 22 | #include 23 | #include 24 | #include 25 | #include "util.h" // FILE_PATH_SIZE 26 | 27 | #ifdef _WIN32 28 | #define ABOVE "../" 29 | #define PATHSEP "/" 30 | #else 31 | #define ABOVE "../" 32 | #define PATHSEP "/" 33 | #endif 34 | 35 | #ifndef MIN 36 | # define MIN(a, b) (((a) < (b)) ? (a) : (b)) 37 | #endif 38 | 39 | #ifndef MAX 40 | # define MAX(a, b) (((a) > (b)) ? (a) : (b)) 41 | #endif 42 | 43 | #ifndef ABS 44 | # define ABS(a) ( ((a)<0) ? -(a) : (a) ) 45 | #endif 46 | 47 | #ifndef ROTR 48 | # define ROTR(x,n) (((uintmax_t)(x) >> (n)) | ((uintmax_t)(x) << ((sizeof(x) * 8) - (n)))) 49 | #endif 50 | 51 | #ifndef PM3_ROTL 52 | # define PM3_ROTL(x,n) (((uintmax_t)(x) << (n)) | ((uintmax_t)(x) >> ((sizeof(x) * 8) - (n)))) 53 | #endif 54 | 55 | // endian change for 64bit 56 | #ifdef __GNUC__ 57 | #ifndef BSWAP_64 58 | #define BSWAP_64(x) __builtin_bswap64(x) 59 | #endif 60 | #else 61 | #ifdef _MSC_VER 62 | #ifndef BSWAP_64 63 | #define BSWAP_64(x) _byteswap_uint64(x) 64 | #endif 65 | #else 66 | #ifndef BSWAP_64 67 | #define BSWAP_64(x) \ 68 | (((uint64_t)(x) << 56) | \ 69 | (((uint64_t)(x) << 40) & 0xff000000000000ULL) | \ 70 | (((uint64_t)(x) << 24) & 0xff0000000000ULL) | \ 71 | (((uint64_t)(x) << 8) & 0xff00000000ULL) | \ 72 | (((uint64_t)(x) >> 8) & 0xff000000ULL) | \ 73 | (((uint64_t)(x) >> 24) & 0xff0000ULL) | \ 74 | (((uint64_t)(x) >> 40) & 0xff00ULL) | \ 75 | ((uint64_t)(x) >> 56)) 76 | #endif 77 | #endif 78 | #endif 79 | 80 | // endian change for 32bit 81 | #ifdef __GNUC__ 82 | #ifndef BSWAP_32 83 | #define BSWAP_32(x) __builtin_bswap32(x) 84 | #endif 85 | #else 86 | #ifdef _MSC_VER 87 | #ifndef BSWAP_32 88 | #define BSWAP_32(x) _byteswap_ulong(x) 89 | #endif 90 | #else 91 | #ifndef BSWAP_32 92 | # define BSWAP_32(x) \ 93 | ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ 94 | (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) 95 | #endif 96 | #endif 97 | #endif 98 | 99 | // convert 2 bytes to U16 in little endian 100 | #ifndef BYTES2UINT16 101 | # define BYTES2UINT16(x) ((x[1] << 8) | (x[0])) 102 | #endif 103 | // convert 4 bytes to U32 in little endian 104 | #ifndef BYTES2UINT32 105 | # define BYTES2UINT32(x) ((x[3] << 24) | (x[2] << 16) | (x[1] << 8) | (x[0])) 106 | #endif 107 | 108 | // convert 4 bytes to U32 in big endian 109 | #ifndef BYTES2UINT32_BE 110 | # define BYTES2UINT32_BE(x) ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | (x[3])) 111 | #endif 112 | 113 | 114 | #define EVEN 0 115 | #define ODD 1 116 | 117 | // Nibble logic 118 | #ifndef NIBBLE_HIGH 119 | # define NIBBLE_HIGH(b) ( ((b) & 0xF0) >> 4 ) 120 | #endif 121 | 122 | #ifndef NIBBLE_LOW 123 | # define NIBBLE_LOW(b) ((b) & 0x0F ) 124 | #endif 125 | 126 | #ifndef CRUMB 127 | # define CRUMB(b,p) (((b & (0x3 << p) ) >> p ) & 0xF) 128 | #endif 129 | 130 | #ifndef SWAP_NIBBLE 131 | # define SWAP_NIBBLE(b) ( (NIBBLE_LOW(b)<< 4) | NIBBLE_HIGH(b)) 132 | #endif 133 | #endif 134 | -------------------------------------------------------------------------------- /hardnested/hardnested_bf_core.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) 2016, 2017 by piwi 3 | // 4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, 5 | // at your option, any later version. See the LICENSE.txt file for the text of 6 | // the license. 7 | //----------------------------------------------------------------------------- 8 | // Implements a card only attack based on crypto text (encrypted nonces 9 | // received during a nested authentication) only. Unlike other card only 10 | // attacks this doesn't rely on implementation errors but only on the 11 | // inherent weaknesses of the crypto1 cypher. Described in 12 | // Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened 13 | // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on 14 | // Computer and Communications Security, 2015 15 | //----------------------------------------------------------------------------- 16 | // 17 | // brute forcing is based on @aczids bitsliced brute forcer 18 | // https://github.com/aczid/crypto1_bs with some modifications. Mainly: 19 | // - don't rollback. Start with 2nd byte of nonce instead 20 | // - reuse results of filter subfunctions 21 | // - reuse results of previous nonces if some first bits are identical 22 | // 23 | //----------------------------------------------------------------------------- 24 | // aczid's Copyright notice: 25 | // 26 | // Bit-sliced Crypto-1 brute-forcing implementation 27 | // Builds on the data structures returned by CraptEV1 craptev1_get_space(nonces, threshold, uid) 28 | /* 29 | Copyright (c) 2015-2016 Aram Verstegen 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to deal 33 | in the Software without restriction, including without limitation the rights 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in 39 | all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47 | THE SOFTWARE. 48 | */ 49 | 50 | #ifndef HARDNESTED_BF_CORE_H__ 51 | #define HARDNESTED_BF_CORE_H__ 52 | 53 | #include "hardnested_bruteforce.h" // statelist_t 54 | 55 | #if ( defined (__i386__) || defined (__x86_64__) ) && \ 56 | ( !defined(__APPLE__) || \ 57 | (defined(__APPLE__) && (__clang_major__ > 8 || __clang_major__ == 8 && __clang_minor__ >= 1)) ) 58 | # define COMPILER_HAS_SIMD_X86 59 | # if defined(COMPILER_HAS_SIMD_X86) && ((__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2)) 60 | # define COMPILER_HAS_SIMD_AVX512 61 | # endif 62 | #endif 63 | 64 | // ARM64 mandates implementation of NEON 65 | #if defined(__arm64__) || defined(__aarch64__) 66 | #define COMPILER_HAS_SIMD_NEON 67 | #define arm_has_neon() (true) 68 | // ARMv7 or older, NEON is optional and autodetection is difficult 69 | #elif defined(__ARM_NEON) 70 | #define COMPILER_HAS_SIMD_NEON 71 | #define arm_has_neon() (false) 72 | #endif 73 | 74 | typedef enum { 75 | SIMD_AUTO, 76 | #if defined(COMPILER_HAS_SIMD_AVX512) 77 | SIMD_AVX512, 78 | #endif 79 | #if defined(COMPILER_HAS_SIMD_X86) 80 | SIMD_AVX2, 81 | SIMD_AVX, 82 | SIMD_SSE2, 83 | SIMD_MMX, 84 | #endif 85 | #if defined(COMPILER_HAS_SIMD_NEON) 86 | SIMD_NEON, 87 | #endif 88 | SIMD_NONE, 89 | } SIMDExecInstr; 90 | void SetSIMDInstr(SIMDExecInstr instr); 91 | SIMDExecInstr GetSIMDInstrAuto(void); 92 | 93 | uint64_t crack_states_bitsliced(uint32_t cuid, uint8_t *best_first_bytes, statelist_t *p, uint32_t *keys_found, uint64_t *num_keys_tested, uint32_t nonces_to_bruteforce, uint8_t *bf_test_nonce_2nd_byte, noncelist_t *nonces); 94 | void bitslice_test_nonces(uint32_t nonces_to_bruteforce, uint32_t *bf_test_nonce, uint8_t *bf_test_nonce_par); 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /pm3/util_posix.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // utilities requiring Posix library functions 17 | //----------------------------------------------------------------------------- 18 | 19 | // ensure availability even with -std=c99; must be included before 20 | #if !defined(_WIN32) 21 | //#define _POSIX_C_SOURCE 199309L // need nanosleep() 22 | #define _POSIX_C_SOURCE 200112L // need localtime_r() 23 | #else 24 | #include 25 | #endif 26 | 27 | #include "util_posix.h" 28 | #include 29 | #include 30 | 31 | 32 | // Timer functions 33 | #if !defined (_WIN32) 34 | #include 35 | 36 | static void nsleep(uint64_t n) { 37 | struct timespec timeout; 38 | timeout.tv_sec = n / 1000000000; 39 | timeout.tv_nsec = n % 1000000000; 40 | while (nanosleep(&timeout, &timeout) && errno == EINTR); 41 | } 42 | 43 | void msleep(uint32_t n) { 44 | nsleep(1000000 * (uint64_t)n); 45 | } 46 | #endif // _WIN32 47 | 48 | #ifdef __APPLE__ 49 | 50 | #ifndef CLOCK_MONOTONIC 51 | #define CLOCK_MONOTONIC (1) 52 | #endif 53 | #ifndef CLOCK_REALTIME 54 | #define CLOCK_REALTIME (2) 55 | #endif 56 | 57 | #include 58 | #include 59 | #include 60 | #include 61 | 62 | /* clock_gettime is not implemented on OSX prior to 10.12 */ 63 | int _civet_clock_gettime(int clk_id, struct timespec *t); 64 | 65 | int _civet_clock_gettime(int clk_id, struct timespec *t) { 66 | memset(t, 0, sizeof(*t)); 67 | if (clk_id == CLOCK_REALTIME) { 68 | struct timeval now; 69 | int rv = gettimeofday(&now, NULL); 70 | if (rv) { 71 | return rv; 72 | } 73 | t->tv_sec = now.tv_sec; 74 | t->tv_nsec = now.tv_usec * 1000; 75 | return 0; 76 | 77 | } else if (clk_id == CLOCK_MONOTONIC) { 78 | static uint64_t clock_start_time = 0; 79 | static mach_timebase_info_data_t timebase_info = {0, 0}; 80 | 81 | uint64_t now = mach_absolute_time(); 82 | 83 | if (clock_start_time == 0) { 84 | 85 | mach_timebase_info(&timebase_info); 86 | clock_start_time = now; 87 | } 88 | 89 | now = (uint64_t)((double)(now - clock_start_time) 90 | * (double)timebase_info.numer 91 | / (double)timebase_info.denom); 92 | 93 | t->tv_sec = now / 1000000000; 94 | t->tv_nsec = now % 1000000000; 95 | return 0; 96 | } 97 | return -1; // EINVAL - Clock ID is unknown 98 | } 99 | 100 | /* if clock_gettime is declared, then __CLOCK_AVAILABILITY will be defined */ 101 | #ifdef __CLOCK_AVAILABILITY 102 | /* If we compiled with Mac OSX 10.12 or later, then clock_gettime will be declared 103 | * but it may be NULL at runtime. So we need to check before using it. */ 104 | int _civet_safe_clock_gettime(int clk_id, struct timespec *t); 105 | 106 | int _civet_safe_clock_gettime(int clk_id, struct timespec *t) { 107 | if (clock_gettime) { 108 | return clock_gettime(clk_id, t); 109 | } 110 | return _civet_clock_gettime(clk_id, t); 111 | } 112 | #define clock_gettime _civet_safe_clock_gettime 113 | #else 114 | #define clock_gettime _civet_clock_gettime 115 | #endif 116 | 117 | #endif 118 | 119 | 120 | // a milliseconds timer for performance measurement 121 | uint64_t msclock(void) { 122 | #if defined(_WIN32) 123 | LARGE_INTEGER count, frequency; 124 | if (!QueryPerformanceFrequency(&frequency)) { 125 | // Handle error 126 | return 0; 127 | } 128 | if (!QueryPerformanceCounter(&count)) { 129 | // Handle error 130 | return 0; 131 | } 132 | return (count.QuadPart * 1000) / frequency.QuadPart; 133 | #else 134 | struct timespec t; 135 | clock_gettime(CLOCK_MONOTONIC, &t); 136 | return (1000 * (uint64_t)t.tv_sec + t.tv_nsec / 1000000); 137 | #endif 138 | } 139 | 140 | -------------------------------------------------------------------------------- /hardnested_main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "cmdhfmfhard.h" 9 | #include "crapto1.h" 10 | #include "parity.h" 11 | 12 | typedef enum { 13 | KEY_A, 14 | KEY_B 15 | } key_type_t; 16 | 17 | // Function prototypes 18 | int process_nonces(FILE *fp, uint32_t uid, uint8_t sector, key_type_t key_type); 19 | int write_nonces_to_temp_file(FILE *fp, FILE *temp_fp, uint32_t current_uid, uint8_t current_sector, key_type_t current_key_type); 20 | 21 | int main(int argc, char *argv[]) { 22 | if (argc != 2) { 23 | printf("Usage: %s \n", argv[0]); 24 | return 1; 25 | } 26 | 27 | FILE *fp = fopen(argv[1], "r"); 28 | if (fp == NULL) { 29 | perror("Error opening file"); 30 | return 1; 31 | } 32 | 33 | uint32_t current_uid = 0; 34 | uint8_t current_sector = 0; 35 | key_type_t current_key_type = KEY_A; 36 | char line[256]; 37 | long file_position = 0; 38 | 39 | while (1) { 40 | file_position = ftell(fp); 41 | if (fgets(line, sizeof(line), fp) == NULL) { 42 | break; // End of file 43 | } 44 | 45 | // Skip lines containing "dist" 46 | if (strstr(line, "dist") != NULL) { 47 | continue; 48 | } 49 | 50 | uint32_t uid; 51 | uint8_t sector; 52 | char key_type_str[2]; 53 | 54 | if (sscanf(line, "Sec %hhu key %1s cuid %x", §or, key_type_str, &uid) == 3) { 55 | key_type_t key_type = (key_type_str[0] == 'A') ? KEY_A : KEY_B; 56 | 57 | if (uid != current_uid || sector != current_sector || key_type != current_key_type) { 58 | if (current_uid != 0) { 59 | fseek(fp, 0, SEEK_SET); // Seek to the beginning of the file 60 | process_nonces(fp, current_uid, current_sector, current_key_type); 61 | fseek(fp, file_position, SEEK_SET); // Return to the current position 62 | } 63 | current_uid = uid; 64 | current_sector = sector; 65 | current_key_type = key_type; 66 | } 67 | } 68 | } 69 | 70 | if (current_uid != 0) { 71 | fseek(fp, 0, SEEK_SET); // Seek to the beginning of the file 72 | process_nonces(fp, current_uid, current_sector, current_key_type); 73 | } 74 | 75 | fclose(fp); 76 | return 0; 77 | } 78 | 79 | int process_nonces(FILE *fp, uint32_t uid, uint8_t sector, key_type_t key_type) { 80 | char temp_file[] = "temp_nonces.txt"; 81 | FILE *temp_fp = fopen(temp_file, "w"); 82 | if (temp_fp == NULL) { 83 | perror("Error creating temporary file"); 84 | return 1; 85 | } 86 | 87 | if (write_nonces_to_temp_file(fp, temp_fp, uid, sector, key_type) != 0) { 88 | fclose(temp_fp); 89 | remove(temp_file); 90 | return 1; 91 | } 92 | 93 | fclose(temp_fp); 94 | 95 | uint64_t foundkey = 0; 96 | int result = mfnestedhard(0, key_type, NULL, 0, 0, NULL, false, false, false, &foundkey, NULL, uid, temp_file); 97 | 98 | if (result == 1) { 99 | printf("Key found for UID: %08x, Sector: %d, Key type: %c: %012" PRIx64 "\n", 100 | uid, sector, (key_type == KEY_A) ? 'A' : 'B', foundkey); 101 | } else { 102 | printf("Key not found for UID: %08x, Sector: %d, Key type: %c\n", 103 | uid, sector, (key_type == KEY_A) ? 'A' : 'B'); 104 | } 105 | 106 | remove(temp_file); 107 | return 0; 108 | } 109 | 110 | int write_nonces_to_temp_file(FILE *fp, FILE *temp_fp, uint32_t current_uid, uint8_t current_sector, key_type_t current_key_type) { 111 | char line[256]; 112 | while (fgets(line, sizeof(line), fp) != NULL) { 113 | // Skip lines containing "dist" 114 | if (strstr(line, "dist") != NULL) { 115 | continue; 116 | } 117 | 118 | uint32_t line_uid; 119 | uint8_t line_sector; 120 | char line_key_type_str[2]; 121 | 122 | if (sscanf(line, "Sec %hhu key %1s cuid %x", &line_sector, line_key_type_str, &line_uid) == 3) { 123 | key_type_t line_key_type = (line_key_type_str[0] == 'A') ? KEY_A : KEY_B; 124 | if (line_uid == current_uid && line_sector == current_sector && line_key_type == current_key_type) { 125 | char ks0_str[9], par0_str[5]; 126 | if (sscanf(line, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %8s %*s %4s", ks0_str, par0_str) == 2) { 127 | uint32_t nt_enc = (uint32_t)strtoul(ks0_str, NULL, 16); 128 | uint8_t par_enc = (uint8_t)strtoul(par0_str, NULL, 2); 129 | fprintf(temp_fp, "%u|%u\n", nt_enc, par_enc); 130 | } 131 | } 132 | } 133 | } 134 | return 0; 135 | } 136 | -------------------------------------------------------------------------------- /crypto1.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) 2008-2014 bla 3 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 4 | // 5 | // This program is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // See LICENSE.txt for the text of the license. 16 | //----------------------------------------------------------------------------- 17 | #include 18 | #include "crapto1.h" 19 | #include "parity.h" 20 | 21 | #ifdef __OPTIMIZE_SIZE__ 22 | int filter(uint32_t const x) { 23 | uint32_t f; 24 | 25 | f = 0xf22c0 >> (x & 0xf) & 16; 26 | f |= 0x6c9c0 >> (x >> 4 & 0xf) & 8; 27 | f |= 0x3c8b0 >> (x >> 8 & 0xf) & 4; 28 | f |= 0x1e458 >> (x >> 12 & 0xf) & 2; 29 | f |= 0x0d938 >> (x >> 16 & 0xf) & 1; 30 | return BIT(0xEC57E80A, f); 31 | } 32 | #endif 33 | 34 | #define SWAPENDIAN(x)\ 35 | (x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16) 36 | 37 | void crypto1_init(struct Crypto1State *state, uint64_t key) { 38 | if (state == NULL) 39 | return; 40 | state->odd = 0; 41 | state->even = 0; 42 | for (int i = 47; i > 0; i -= 2) { 43 | state->odd = state->odd << 1 | BIT(key, (i - 1) ^ 7); 44 | state->even = state->even << 1 | BIT(key, i ^ 7); 45 | } 46 | } 47 | 48 | void crypto1_deinit(struct Crypto1State *state) { 49 | state->odd = 0; 50 | state->even = 0; 51 | } 52 | 53 | #if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks calloc()/free() 54 | 55 | struct Crypto1State *crypto1_create(uint64_t key) { 56 | struct Crypto1State *state = calloc(sizeof(*state), sizeof(uint8_t)); 57 | if (!state) return NULL; 58 | crypto1_init(state, key); 59 | return state; 60 | } 61 | 62 | void crypto1_destroy(struct Crypto1State *state) { 63 | free(state); 64 | } 65 | 66 | #endif 67 | 68 | void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr) { 69 | int i; 70 | for (*lfsr = 0, i = 23; i >= 0; --i) { 71 | *lfsr = *lfsr << 1 | BIT(state->odd, i ^ 3); 72 | *lfsr = *lfsr << 1 | BIT(state->even, i ^ 3); 73 | } 74 | } 75 | 76 | uint8_t crypto1_bit(struct Crypto1State *s, uint8_t in, int is_encrypted) { 77 | uint32_t feedin, t; 78 | uint8_t ret = filter(s->odd); 79 | 80 | feedin = ret & (!!is_encrypted); 81 | feedin ^= !!in; 82 | feedin ^= LF_POLY_ODD & s->odd; 83 | feedin ^= LF_POLY_EVEN & s->even; 84 | s->even = s->even << 1 | (evenparity32(feedin)); 85 | 86 | t = s->odd; 87 | s->odd = s->even; 88 | s->even = t; 89 | 90 | return ret; 91 | } 92 | 93 | uint8_t crypto1_byte(struct Crypto1State *s, uint8_t in, int is_encrypted) { 94 | uint8_t ret = 0; 95 | ret |= crypto1_bit(s, BIT(in, 0), is_encrypted) << 0; 96 | ret |= crypto1_bit(s, BIT(in, 1), is_encrypted) << 1; 97 | ret |= crypto1_bit(s, BIT(in, 2), is_encrypted) << 2; 98 | ret |= crypto1_bit(s, BIT(in, 3), is_encrypted) << 3; 99 | ret |= crypto1_bit(s, BIT(in, 4), is_encrypted) << 4; 100 | ret |= crypto1_bit(s, BIT(in, 5), is_encrypted) << 5; 101 | ret |= crypto1_bit(s, BIT(in, 6), is_encrypted) << 6; 102 | ret |= crypto1_bit(s, BIT(in, 7), is_encrypted) << 7; 103 | return ret; 104 | } 105 | 106 | uint32_t crypto1_word(struct Crypto1State *s, uint32_t in, int is_encrypted) { 107 | uint32_t ret = 0; 108 | // note: xor args have been swapped because some compilers emit a warning 109 | // for 10^x and 2^x as possible misuses for exponentiation. No comment. 110 | ret |= crypto1_bit(s, BEBIT(in, 0), is_encrypted) << (24 ^ 0); 111 | ret |= crypto1_bit(s, BEBIT(in, 1), is_encrypted) << (24 ^ 1); 112 | ret |= crypto1_bit(s, BEBIT(in, 2), is_encrypted) << (24 ^ 2); 113 | ret |= crypto1_bit(s, BEBIT(in, 3), is_encrypted) << (24 ^ 3); 114 | ret |= crypto1_bit(s, BEBIT(in, 4), is_encrypted) << (24 ^ 4); 115 | ret |= crypto1_bit(s, BEBIT(in, 5), is_encrypted) << (24 ^ 5); 116 | ret |= crypto1_bit(s, BEBIT(in, 6), is_encrypted) << (24 ^ 6); 117 | ret |= crypto1_bit(s, BEBIT(in, 7), is_encrypted) << (24 ^ 7); 118 | 119 | ret |= crypto1_bit(s, BEBIT(in, 8), is_encrypted) << (24 ^ 8); 120 | ret |= crypto1_bit(s, BEBIT(in, 9), is_encrypted) << (24 ^ 9); 121 | ret |= crypto1_bit(s, BEBIT(in, 10), is_encrypted) << (24 ^ 10); 122 | ret |= crypto1_bit(s, BEBIT(in, 11), is_encrypted) << (24 ^ 11); 123 | ret |= crypto1_bit(s, BEBIT(in, 12), is_encrypted) << (24 ^ 12); 124 | ret |= crypto1_bit(s, BEBIT(in, 13), is_encrypted) << (24 ^ 13); 125 | ret |= crypto1_bit(s, BEBIT(in, 14), is_encrypted) << (24 ^ 14); 126 | ret |= crypto1_bit(s, BEBIT(in, 15), is_encrypted) << (24 ^ 15); 127 | 128 | ret |= crypto1_bit(s, BEBIT(in, 16), is_encrypted) << (24 ^ 16); 129 | ret |= crypto1_bit(s, BEBIT(in, 17), is_encrypted) << (24 ^ 17); 130 | ret |= crypto1_bit(s, BEBIT(in, 18), is_encrypted) << (24 ^ 18); 131 | ret |= crypto1_bit(s, BEBIT(in, 19), is_encrypted) << (24 ^ 19); 132 | ret |= crypto1_bit(s, BEBIT(in, 20), is_encrypted) << (24 ^ 20); 133 | ret |= crypto1_bit(s, BEBIT(in, 21), is_encrypted) << (24 ^ 21); 134 | ret |= crypto1_bit(s, BEBIT(in, 22), is_encrypted) << (24 ^ 22); 135 | ret |= crypto1_bit(s, BEBIT(in, 23), is_encrypted) << (24 ^ 23); 136 | 137 | ret |= crypto1_bit(s, BEBIT(in, 24), is_encrypted) << (24 ^ 24); 138 | ret |= crypto1_bit(s, BEBIT(in, 25), is_encrypted) << (24 ^ 25); 139 | ret |= crypto1_bit(s, BEBIT(in, 26), is_encrypted) << (24 ^ 26); 140 | ret |= crypto1_bit(s, BEBIT(in, 27), is_encrypted) << (24 ^ 27); 141 | ret |= crypto1_bit(s, BEBIT(in, 28), is_encrypted) << (24 ^ 28); 142 | ret |= crypto1_bit(s, BEBIT(in, 29), is_encrypted) << (24 ^ 29); 143 | ret |= crypto1_bit(s, BEBIT(in, 30), is_encrypted) << (24 ^ 30); 144 | ret |= crypto1_bit(s, BEBIT(in, 31), is_encrypted) << (24 ^ 31); 145 | return ret; 146 | } 147 | 148 | /* prng_successor 149 | * helper used to obscure the keystream during authentication 150 | */ 151 | uint32_t prng_successor(uint32_t x, uint32_t n) { 152 | SWAPENDIAN(x); 153 | while (n--) 154 | x = x >> 1 | (x >> 16 ^ x >> 18 ^ x >> 19 ^ x >> 21) << 31; 155 | 156 | return SWAPENDIAN(x); 157 | } 158 | 159 | int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, const uint8_t *parity) { 160 | return ( 161 | (oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1, 16))) && \ 162 | (oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1, 8))) && \ 163 | (oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1, 0))) 164 | ) ? 1 : 0; 165 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /crapto1.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) 2008-2014 bla 3 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 4 | // 5 | // This program is free software: you can redistribute it and/or modify 6 | // it under the terms of the GNU General Public License as published by 7 | // the Free Software Foundation, either version 3 of the License, or 8 | // (at your option) any later version. 9 | // 10 | // This program is distributed in the hope that it will be useful, 11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | // GNU General Public License for more details. 14 | // 15 | // See LICENSE.txt for the text of the license. 16 | //----------------------------------------------------------------------------- 17 | #include "crapto1.h" 18 | 19 | #include 20 | #include "parity.h" 21 | 22 | /** update_contribution 23 | * helper, calculates the partial linear feedback contributions and puts in MSB 24 | */ 25 | static inline void update_contribution(uint32_t *item, const uint32_t mask1, const uint32_t mask2) { 26 | uint32_t p = *item >> 25; 27 | 28 | p = p << 1 | (evenparity32(*item & mask1)); 29 | p = p << 1 | (evenparity32(*item & mask2)); 30 | *item = p << 24 | (*item & 0xffffff); 31 | } 32 | 33 | /** extend_table 34 | * using a bit of the keystream extend the table of possible lfsr states 35 | */ 36 | static inline void extend_table(uint32_t *tbl, uint32_t **end, int bit, int m1, int m2, uint32_t in) { 37 | in <<= 24; 38 | for (*tbl <<= 1; tbl <= *end; *++tbl <<= 1) 39 | if (filter(*tbl) ^ filter(*tbl | 1)) { 40 | *tbl |= filter(*tbl) ^ bit; 41 | update_contribution(tbl, m1, m2); 42 | *tbl ^= in; 43 | } else if (filter(*tbl) == bit) { 44 | *++*end = tbl[1]; 45 | tbl[1] = tbl[0] | 1; 46 | update_contribution(tbl, m1, m2); 47 | *tbl++ ^= in; 48 | update_contribution(tbl, m1, m2); 49 | *tbl ^= in; 50 | } else 51 | *tbl-- = *(*end)--; 52 | } 53 | /** extend_table_simple 54 | * using a bit of the keystream extend the table of possible lfsr states 55 | */ 56 | static inline void extend_table_simple(uint32_t *tbl, uint32_t **end, int bit) { 57 | for (*tbl <<= 1; tbl <= *end; *++tbl <<= 1) { 58 | if (filter(*tbl) ^ filter(*tbl | 1)) { // replace 59 | *tbl |= filter(*tbl) ^ bit; 60 | } else if (filter(*tbl) == bit) { // insert 61 | *++*end = *++tbl; 62 | *tbl = tbl[-1] | 1; 63 | } else { // drop 64 | *tbl-- = *(*end)--; 65 | } 66 | } 67 | } 68 | 69 | 70 | /** lfsr_rollback_bit 71 | * Rollback the shift register in order to get previous states 72 | */ 73 | uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb) { 74 | int out; 75 | uint8_t ret; 76 | uint32_t t; 77 | 78 | s->odd &= 0xffffff; 79 | t = s->odd, s->odd = s->even, s->even = t; 80 | 81 | out = s->even & 1; 82 | out ^= LF_POLY_EVEN & (s->even >>= 1); 83 | out ^= LF_POLY_ODD & s->odd; 84 | out ^= !!in; 85 | out ^= (ret = filter(s->odd)) & (!!fb); 86 | 87 | s->even |= (evenparity32(out)) << 23; 88 | return ret; 89 | } 90 | /** lfsr_rollback_byte 91 | * Rollback the shift register in order to get previous states 92 | */ 93 | uint8_t lfsr_rollback_byte(struct Crypto1State *s, uint32_t in, int fb) { 94 | uint8_t ret = 0; 95 | ret |= lfsr_rollback_bit(s, BIT(in, 7), fb) << 7; 96 | ret |= lfsr_rollback_bit(s, BIT(in, 6), fb) << 6; 97 | ret |= lfsr_rollback_bit(s, BIT(in, 5), fb) << 5; 98 | ret |= lfsr_rollback_bit(s, BIT(in, 4), fb) << 4; 99 | ret |= lfsr_rollback_bit(s, BIT(in, 3), fb) << 3; 100 | ret |= lfsr_rollback_bit(s, BIT(in, 2), fb) << 2; 101 | ret |= lfsr_rollback_bit(s, BIT(in, 1), fb) << 1; 102 | ret |= lfsr_rollback_bit(s, BIT(in, 0), fb) << 0; 103 | return ret; 104 | } 105 | /** lfsr_rollback_word 106 | * Rollback the shift register in order to get previous states 107 | */ 108 | uint32_t lfsr_rollback_word(struct Crypto1State *s, uint32_t in, int fb) { 109 | 110 | uint32_t ret = 0; 111 | // note: xor args have been swapped because some compilers emit a warning 112 | // for 10^x and 2^x as possible misuses for exponentiation. No comment. 113 | ret |= lfsr_rollback_bit(s, BEBIT(in, 31), fb) << (24 ^ 31); 114 | ret |= lfsr_rollback_bit(s, BEBIT(in, 30), fb) << (24 ^ 30); 115 | ret |= lfsr_rollback_bit(s, BEBIT(in, 29), fb) << (24 ^ 29); 116 | ret |= lfsr_rollback_bit(s, BEBIT(in, 28), fb) << (24 ^ 28); 117 | ret |= lfsr_rollback_bit(s, BEBIT(in, 27), fb) << (24 ^ 27); 118 | ret |= lfsr_rollback_bit(s, BEBIT(in, 26), fb) << (24 ^ 26); 119 | ret |= lfsr_rollback_bit(s, BEBIT(in, 25), fb) << (24 ^ 25); 120 | ret |= lfsr_rollback_bit(s, BEBIT(in, 24), fb) << (24 ^ 24); 121 | 122 | ret |= lfsr_rollback_bit(s, BEBIT(in, 23), fb) << (24 ^ 23); 123 | ret |= lfsr_rollback_bit(s, BEBIT(in, 22), fb) << (24 ^ 22); 124 | ret |= lfsr_rollback_bit(s, BEBIT(in, 21), fb) << (24 ^ 21); 125 | ret |= lfsr_rollback_bit(s, BEBIT(in, 20), fb) << (24 ^ 20); 126 | ret |= lfsr_rollback_bit(s, BEBIT(in, 19), fb) << (24 ^ 19); 127 | ret |= lfsr_rollback_bit(s, BEBIT(in, 18), fb) << (24 ^ 18); 128 | ret |= lfsr_rollback_bit(s, BEBIT(in, 17), fb) << (24 ^ 17); 129 | ret |= lfsr_rollback_bit(s, BEBIT(in, 16), fb) << (24 ^ 16); 130 | 131 | ret |= lfsr_rollback_bit(s, BEBIT(in, 15), fb) << (24 ^ 15); 132 | ret |= lfsr_rollback_bit(s, BEBIT(in, 14), fb) << (24 ^ 14); 133 | ret |= lfsr_rollback_bit(s, BEBIT(in, 13), fb) << (24 ^ 13); 134 | ret |= lfsr_rollback_bit(s, BEBIT(in, 12), fb) << (24 ^ 12); 135 | ret |= lfsr_rollback_bit(s, BEBIT(in, 11), fb) << (24 ^ 11); 136 | ret |= lfsr_rollback_bit(s, BEBIT(in, 10), fb) << (24 ^ 10); 137 | ret |= lfsr_rollback_bit(s, BEBIT(in, 9), fb) << (24 ^ 9); 138 | ret |= lfsr_rollback_bit(s, BEBIT(in, 8), fb) << (24 ^ 8); 139 | 140 | ret |= lfsr_rollback_bit(s, BEBIT(in, 7), fb) << (24 ^ 7); 141 | ret |= lfsr_rollback_bit(s, BEBIT(in, 6), fb) << (24 ^ 6); 142 | ret |= lfsr_rollback_bit(s, BEBIT(in, 5), fb) << (24 ^ 5); 143 | ret |= lfsr_rollback_bit(s, BEBIT(in, 4), fb) << (24 ^ 4); 144 | ret |= lfsr_rollback_bit(s, BEBIT(in, 3), fb) << (24 ^ 3); 145 | ret |= lfsr_rollback_bit(s, BEBIT(in, 2), fb) << (24 ^ 2); 146 | ret |= lfsr_rollback_bit(s, BEBIT(in, 1), fb) << (24 ^ 1); 147 | ret |= lfsr_rollback_bit(s, BEBIT(in, 0), fb) << (24 ^ 0); 148 | return ret; 149 | } 150 | 151 | /** nonce_distance 152 | * x,y valid tag nonces, then prng_successor(x, nonce_distance(x, y)) = y 153 | */ 154 | static uint16_t *dist = 0; 155 | int nonce_distance(uint32_t from, uint32_t to) { 156 | if (!dist) { 157 | // allocation 2bytes * 0xFFFF times. 158 | dist = calloc(2 << 16, sizeof(uint8_t)); 159 | if (!dist) 160 | return -1; 161 | uint16_t x = 1; 162 | for (uint16_t i = 1; i; ++i) { 163 | dist[(x & 0xff) << 8 | x >> 8] = i; 164 | x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15; 165 | } 166 | } 167 | return (65535 + dist[to >> 16] - dist[from >> 16]) % 65535; 168 | } 169 | 170 | /** validate_prng_nonce 171 | * Determine if nonce is deterministic. ie: Suspectable to Darkside attack. 172 | * returns 173 | * true = weak prng 174 | * false = hardend prng 175 | */ 176 | bool validate_prng_nonce(uint32_t nonce) { 177 | // init prng table: 178 | if (nonce_distance(nonce, nonce) == -1) 179 | return false; 180 | return ((65535 - dist[nonce >> 16] + dist[nonce & 0xffff]) % 65535) == 16; 181 | } 182 | 183 | static uint32_t fastfwd[2][8] = { 184 | { 0, 0x4BC53, 0xECB1, 0x450E2, 0x25E29, 0x6E27A, 0x2B298, 0x60ECB}, 185 | { 0, 0x1D962, 0x4BC53, 0x56531, 0xECB1, 0x135D3, 0x450E2, 0x58980} 186 | }; 187 | 188 | /** lfsr_prefix_ks 189 | * 190 | * Is an exported helper function from the common prefix attack 191 | * Described in the "dark side" paper. It returns an -1 terminated array 192 | * of possible partial(21 bit) secret state. 193 | * The required keystream(ks) needs to contain the keystream that was used to 194 | * encrypt the NACK which is observed when varying only the 3 last bits of Nr 195 | * only correct iff [NR_3] ^ NR_3 does not depend on Nr_3 196 | */ 197 | uint32_t *lfsr_prefix_ks(const uint8_t ks[8], int isodd) { 198 | uint32_t *candidates = calloc(4 << 10, sizeof(uint8_t)); 199 | if (!candidates) return 0; 200 | 201 | int size = 0; 202 | 203 | for (int i = 0; i < 1 << 21; ++i) { 204 | int good = 1; 205 | for (uint32_t c = 0; good && c < 8; ++c) { 206 | uint32_t entry = i ^ fastfwd[isodd][c]; 207 | good &= (BIT(ks[c], isodd) == filter(entry >> 1)); 208 | good &= (BIT(ks[c], isodd + 2) == filter(entry)); 209 | } 210 | if (good) 211 | candidates[size++] = i; 212 | } 213 | 214 | candidates[size] = -1; 215 | 216 | return candidates; 217 | } 218 | 219 | /** check_pfx_parity 220 | * helper function which eliminates possible secret states using parity bits 221 | */ 222 | static struct Crypto1State *check_pfx_parity(uint32_t prefix, uint32_t rresp, uint8_t parities[8][8], uint32_t odd, uint32_t even, struct Crypto1State *sl, uint32_t no_par) { 223 | uint32_t good = 1; 224 | 225 | for (uint32_t c = 0; good && c < 8; ++c) { 226 | sl->odd = odd ^ fastfwd[1][c]; 227 | sl->even = even ^ fastfwd[0][c]; 228 | 229 | lfsr_rollback_bit(sl, 0, 0); 230 | lfsr_rollback_bit(sl, 0, 0); 231 | 232 | uint32_t ks3 = lfsr_rollback_bit(sl, 0, 0); 233 | uint32_t ks2 = lfsr_rollback_word(sl, 0, 0); 234 | uint32_t ks1 = lfsr_rollback_word(sl, prefix | c << 5, 1); 235 | 236 | if (no_par) 237 | break; 238 | 239 | uint32_t nr = ks1 ^ (prefix | c << 5); 240 | uint32_t rr = ks2 ^ rresp; 241 | 242 | good &= evenparity32(nr & 0x000000ff) ^ parities[c][3] ^ BIT(ks2, 24); 243 | good &= evenparity32(rr & 0xff000000) ^ parities[c][4] ^ BIT(ks2, 16); 244 | good &= evenparity32(rr & 0x00ff0000) ^ parities[c][5] ^ BIT(ks2, 8); 245 | good &= evenparity32(rr & 0x0000ff00) ^ parities[c][6] ^ BIT(ks2, 0); 246 | good &= evenparity32(rr & 0x000000ff) ^ parities[c][7] ^ ks3; 247 | } 248 | 249 | return sl + good; 250 | } 251 | 252 | #if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free() 253 | /** lfsr_common_prefix 254 | * Implementation of the common prefix attack. 255 | * Requires the 28 bit constant prefix used as reader nonce (pfx) 256 | * The reader response used (rr) 257 | * The keystream used to encrypt the observed NACK's (ks) 258 | * The parity bits (par) 259 | * It returns a zero terminated list of possible cipher states after the 260 | * tag nonce was fed in 261 | */ 262 | 263 | struct Crypto1State *lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par) { 264 | struct Crypto1State *statelist, *s; 265 | uint32_t *odd, *even, *o, *e, top; 266 | 267 | odd = lfsr_prefix_ks(ks, 1); 268 | even = lfsr_prefix_ks(ks, 0); 269 | 270 | s = statelist = calloc(1, (sizeof * statelist) << 24); // was << 20. Need more for no_par special attack. Enough??? 271 | if (!s || !odd || !even) { 272 | free(statelist); 273 | statelist = 0; 274 | goto out; 275 | } 276 | 277 | for (o = odd; *o + 1; ++o) 278 | for (e = even; *e + 1; ++e) 279 | for (top = 0; top < 64; ++top) { 280 | *o += 1 << 21; 281 | *e += (!(top & 7) + 1) << 21; 282 | s = check_pfx_parity(pfx, rr, par, *o, *e, s, no_par); 283 | } 284 | 285 | s->odd = s->even = 0; 286 | out: 287 | free(odd); 288 | free(even); 289 | return statelist; 290 | } 291 | #endif 292 | -------------------------------------------------------------------------------- /pm3/ui.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details. 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // See LICENSE.txt for the text of the license. 15 | //----------------------------------------------------------------------------- 16 | // UI utilities 17 | //----------------------------------------------------------------------------- 18 | 19 | /* Ensure strtok_r is available even with -std=c99; must be included before 20 | */ 21 | 22 | #include "ui.h" 23 | #include "commonutil.h" // ARRAYLEN 24 | #include // for Mingw readline 25 | #include 26 | #include 27 | 28 | #if defined(HAVE_READLINE) 29 | //Load readline after stdio.h 30 | #include 31 | #endif 32 | 33 | #include "util.h" 34 | 35 | #ifdef _WIN32 36 | # include // _mkdir 37 | #endif 38 | 39 | #include "emojis.h" 40 | #include "emojis_alt.h" 41 | #include 42 | 43 | session_arg_t g_session; 44 | 45 | static bool flushAfterWrite = false; 46 | static void fPrintAndLog(FILE *stream, const char *fmt, ...); 47 | 48 | #ifdef _WIN32 49 | #define MKDIR_CHK _mkdir(path) 50 | #define STRTOK strtok 51 | #else 52 | #define MKDIR_CHK mkdir(path, 0700) 53 | #define STRTOK strtok_r 54 | #endif 55 | 56 | static uint8_t PrintAndLogEx_spinidx = 0; 57 | 58 | void PrintAndLogEx(logLevel_t level, const char *fmt, ...) { 59 | 60 | // skip debug messages if client debugging is turned off i.e. 'DATA SETDEBUG -0' 61 | if (g_debugMode == 0 && level == DEBUG) 62 | return; 63 | 64 | // skip HINT messages if client has hints turned off i.e. 'HINT 0' 65 | if (g_session.show_hints == false && level == HINT) 66 | return; 67 | 68 | char prefix[40] = {0}; 69 | char buffer[MAX_PRINT_BUFFER] = {0}; 70 | char buffer2[MAX_PRINT_BUFFER + sizeof(prefix)] = {0}; 71 | char *token = NULL; 72 | char *tmp_ptr = NULL; 73 | FILE *stream = stdout; 74 | const char *spinner[] = {_YELLOW_("[\\]"), _YELLOW_("[|]"), _YELLOW_("[/]"), _YELLOW_("[-]")}; 75 | const char *spinner_emoji[] = {" :clock1: ", " :clock2: ", " :clock3: ", " :clock4: ", " :clock5: ", " :clock6: ", 76 | " :clock7: ", " :clock8: ", " :clock9: ", " :clock10: ", " :clock11: ", 77 | " :clock12: "}; 78 | switch (level) { 79 | case ERR: 80 | if (g_session.emoji_mode == EMO_EMOJI) 81 | strncpy(prefix, "[" _RED_("!!") "] :rotating_light: ", sizeof(prefix) - 1); 82 | else 83 | strncpy(prefix, "[" _RED_("!!") "] ", sizeof(prefix) - 1); 84 | stream = stderr; 85 | break; 86 | case FAILED: 87 | if (g_session.emoji_mode == EMO_EMOJI) 88 | strncpy(prefix, "[" _RED_("-") "] :no_entry: ", sizeof(prefix) - 1); 89 | else 90 | strncpy(prefix, "[" _RED_("-") "] ", sizeof(prefix) - 1); 91 | break; 92 | case DEBUG: 93 | strncpy(prefix, "[" _BLUE_("#") "] ", sizeof(prefix) - 1); 94 | break; 95 | case HINT: 96 | strncpy(prefix, "[" _YELLOW_("?") "] ", sizeof(prefix) - 1); 97 | break; 98 | case SUCCESS: 99 | strncpy(prefix, "[" _GREEN_("+") "] ", sizeof(prefix) - 1); 100 | break; 101 | case WARNING: 102 | if (g_session.emoji_mode == EMO_EMOJI) 103 | strncpy(prefix, "[" _CYAN_("!") "] :warning: ", sizeof(prefix) - 1); 104 | else 105 | strncpy(prefix, "[" _CYAN_("!") "] ", sizeof(prefix) - 1); 106 | break; 107 | case INFO: 108 | strncpy(prefix, "[" _YELLOW_("=") "] ", sizeof(prefix) - 1); 109 | break; 110 | case INPLACE: 111 | if (g_session.emoji_mode == EMO_EMOJI) { 112 | strncpy(prefix, spinner_emoji[PrintAndLogEx_spinidx], sizeof(prefix) - 1); 113 | PrintAndLogEx_spinidx++; 114 | if (PrintAndLogEx_spinidx >= ARRAYLEN(spinner_emoji)) 115 | PrintAndLogEx_spinidx = 0; 116 | } else { 117 | strncpy(prefix, spinner[PrintAndLogEx_spinidx], sizeof(prefix) - 1); 118 | PrintAndLogEx_spinidx++; 119 | if (PrintAndLogEx_spinidx >= ARRAYLEN(spinner)) 120 | PrintAndLogEx_spinidx = 0; 121 | } 122 | break; 123 | case NORMAL: 124 | // no prefixes for normal 125 | break; 126 | } 127 | 128 | va_list args; 129 | va_start(args, fmt); 130 | vsnprintf(buffer, sizeof(buffer), fmt, args); 131 | va_end(args); 132 | 133 | // no prefixes for normal & inplace 134 | if (level == NORMAL) { 135 | fPrintAndLog(stream, "%s", buffer); 136 | return; 137 | } 138 | 139 | if (strchr(buffer, '\n')) { 140 | 141 | const char delim[2] = "\n"; 142 | 143 | // line starts with newline 144 | if (buffer[0] == '\n') 145 | fPrintAndLog(stream, ""); 146 | 147 | token = STRTOK(buffer, delim, &tmp_ptr); 148 | 149 | while (token != NULL) { 150 | 151 | size_t size = strlen(buffer2); 152 | 153 | if (strlen(token)) 154 | snprintf(buffer2 + size, sizeof(buffer2) - size, "%s%s\n", prefix, token); 155 | else 156 | snprintf(buffer2 + size, sizeof(buffer2) - size, "\n"); 157 | 158 | token = STRTOK(NULL, delim, &tmp_ptr); 159 | } 160 | fPrintAndLog(stream, "%s", buffer2); 161 | } else { 162 | snprintf(buffer2, sizeof(buffer2), "%s%s", prefix, buffer); 163 | if (level == INPLACE) { 164 | char buffer3[sizeof(buffer2)] = {0}; 165 | char buffer4[sizeof(buffer2)] = {0}; 166 | memcpy_filter_ansi(buffer3, buffer2, sizeof(buffer2), !g_session.supports_colors); 167 | memcpy_filter_emoji(buffer4, buffer3, sizeof(buffer3), g_session.emoji_mode); 168 | fprintf(stream, "\r%s", buffer4); 169 | fflush(stream); 170 | } else { 171 | fPrintAndLog(stream, "%s", buffer2); 172 | } 173 | } 174 | } 175 | 176 | static void fPrintAndLog(FILE *stream, const char *fmt, ...) { 177 | va_list argptr; 178 | static FILE *logfile = NULL; 179 | static int logging = 1; 180 | char buffer[MAX_PRINT_BUFFER] = {0}; 181 | char buffer2[MAX_PRINT_BUFFER] = {0}; 182 | char buffer3[MAX_PRINT_BUFFER] = {0}; 183 | // lock this section to avoid interlacing prints from different threads 184 | bool linefeed = true; 185 | 186 | logging = 0; 187 | 188 | 189 | // If there is an incoming message from the hardware (eg: lf hid read) in 190 | // the background (while the prompt is displayed and accepting user input), 191 | // stash the prompt and bring it back later. 192 | #ifdef RL_STATE_READCMD 193 | // We are using GNU readline. libedit (OSX) doesn't support this flag. 194 | int need_hack = (rl_readline_state & RL_STATE_READCMD) > 0; 195 | char *saved_line; 196 | int saved_point; 197 | 198 | if (need_hack) { 199 | saved_point = rl_point; 200 | saved_line = rl_copy_text(0, rl_end); 201 | rl_save_prompt(); 202 | rl_replace_line("", 0); 203 | rl_redisplay(); 204 | } 205 | #endif 206 | 207 | va_start(argptr, fmt); 208 | vsnprintf(buffer, sizeof(buffer), fmt, argptr); 209 | va_end(argptr); 210 | if (strlen(buffer) > 0 && buffer[strlen(buffer) - 1] == NOLF[0]) { 211 | linefeed = false; 212 | buffer[strlen(buffer) - 1] = 0; 213 | } 214 | bool filter_ansi = !g_session.supports_colors; 215 | memcpy_filter_ansi(buffer2, buffer, sizeof(buffer), filter_ansi); 216 | if (g_printAndLog & PRINTANDLOG_PRINT) { 217 | memcpy_filter_emoji(buffer3, buffer2, sizeof(buffer2), g_session.emoji_mode); 218 | fprintf(stream, "%s", buffer3); 219 | if (linefeed) 220 | fprintf(stream, "\n"); 221 | } 222 | 223 | #ifdef RL_STATE_READCMD 224 | // We are using GNU readline. libedit (OSX) doesn't support this flag. 225 | if (need_hack) { 226 | rl_restore_prompt(); 227 | rl_replace_line(saved_line, 0); 228 | rl_point = saved_point; 229 | rl_redisplay(); 230 | free(saved_line); 231 | } 232 | #endif 233 | 234 | if ((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) { 235 | memcpy_filter_emoji(buffer3, buffer2, sizeof(buffer2), EMO_ALTTEXT); 236 | if (filter_ansi) { // already done 237 | fprintf(logfile, "%s", buffer3); 238 | } else { 239 | memcpy_filter_ansi(buffer, buffer3, sizeof(buffer3), true); 240 | fprintf(logfile, "%s", buffer); 241 | } 242 | if (linefeed) 243 | fprintf(logfile, "\n"); 244 | fflush(logfile); 245 | } 246 | 247 | if (flushAfterWrite) 248 | fflush(stdout); 249 | } 250 | 251 | void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter) { 252 | if (filter) { 253 | // Filter out ANSI sequences on these OS 254 | uint8_t *rdest = (uint8_t *) dest; 255 | uint8_t *rsrc = (uint8_t *) src; 256 | uint16_t si = 0; 257 | for (size_t i = 0; i < n; i++) { 258 | if ((i < n - 1) && (rsrc[i] == '\x1b') && (rsrc[i + 1] >= 0x40) && 259 | (rsrc[i + 1] <= 0x5F)) { // entering ANSI sequence 260 | 261 | i++; 262 | if ((i < n - 1) && (rsrc[i] == '[')) { // entering CSI sequence 263 | i++; 264 | 265 | while ((i < n - 1) && (rsrc[i] >= 0x30) && (rsrc[i] <= 0x3F)) { // parameter bytes 266 | i++; 267 | } 268 | 269 | while ((i < n - 1) && (rsrc[i] >= 0x20) && (rsrc[i] <= 0x2F)) { // intermediate bytes 270 | i++; 271 | } 272 | 273 | if ((rsrc[i] >= 0x40) && (rsrc[i] <= 0x7F)) { // final byte 274 | continue; 275 | } 276 | } else { 277 | continue; 278 | } 279 | } 280 | rdest[si++] = rsrc[i]; 281 | } 282 | } else { 283 | memcpy(dest, src, n); 284 | } 285 | } 286 | 287 | static bool 288 | emojify_token(const char *token, uint8_t token_length, const char **emojified_token, uint8_t *emojified_token_length, 289 | emojiMode_t mode) { 290 | int i = 0; 291 | while (EmojiTable[i].alias && EmojiTable[i].emoji) { 292 | if ((strlen(EmojiTable[i].alias) == token_length) && (0 == memcmp(EmojiTable[i].alias, token, token_length))) { 293 | switch (mode) { 294 | case EMO_EMOJI: { 295 | *emojified_token = EmojiTable[i].emoji; 296 | *emojified_token_length = strlen(EmojiTable[i].emoji); 297 | break; 298 | } 299 | case EMO_ALTTEXT: { 300 | int j = 0; 301 | *emojified_token_length = 0; 302 | while (EmojiAltTable[j].alias && EmojiAltTable[j].alttext) { 303 | if ((strlen(EmojiAltTable[j].alias) == token_length) && 304 | (0 == memcmp(EmojiAltTable[j].alias, token, token_length))) { 305 | *emojified_token = EmojiAltTable[j].alttext; 306 | *emojified_token_length = strlen(EmojiAltTable[j].alttext); 307 | break; 308 | } 309 | ++j; 310 | } 311 | break; 312 | } 313 | case EMO_NONE: { 314 | *emojified_token_length = 0; 315 | break; 316 | } 317 | case EMO_ALIAS: { // should never happen 318 | return false; 319 | } 320 | } 321 | return true; 322 | } 323 | ++i; 324 | } 325 | return false; 326 | } 327 | 328 | static bool token_charset(uint8_t c) { 329 | if ((c >= '0') && (c <= '9')) return true; 330 | if ((c >= 'a') && (c <= 'z')) return true; 331 | if ((c >= 'A') && (c <= 'Z')) return true; 332 | if ((c == '_') || (c == '+') || (c == '-')) return true; 333 | return false; 334 | } 335 | 336 | void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode) { 337 | if (mode == EMO_ALIAS) { 338 | memcpy(dest, src, n); 339 | } else { 340 | // tokenize emoji 341 | const char *emojified_token = NULL; 342 | uint8_t emojified_token_length = 0; 343 | char *current_token = NULL; 344 | uint8_t current_token_length = 0; 345 | char *rdest = (char *) dest; 346 | char *rsrc = (char *) src; 347 | uint16_t si = 0; 348 | for (size_t i = 0; i < n; i++) { 349 | char current_char = rsrc[i]; 350 | 351 | if (current_token_length == 0) { 352 | // starting a new token. 353 | if (current_char == ':') { 354 | current_token = rsrc + i; 355 | current_token_length = 1; 356 | } else { // not starting a new token. 357 | rdest[si++] = current_char; 358 | } 359 | } else { 360 | // finishing the current token. 361 | if (current_char == ':') { 362 | // nothing changed? we still need the ending ':' as it might serve for an upcoming emoji 363 | if (!emojify_token(current_token, current_token_length + 1, &emojified_token, 364 | &emojified_token_length, mode)) { 365 | memcpy(rdest + si, current_token, current_token_length); 366 | si += current_token_length; 367 | current_token = rsrc + i; 368 | current_token_length = 1; 369 | } else { 370 | memcpy(rdest + si, emojified_token, emojified_token_length); 371 | si += emojified_token_length; 372 | current_token_length = 0; 373 | } 374 | } else if (token_charset(current_char)) { // continuing the current token. 375 | current_token_length++; 376 | } else { // dropping the current token. 377 | current_token_length++; 378 | memcpy(rdest + si, current_token, current_token_length); 379 | si += current_token_length; 380 | current_token_length = 0; 381 | } 382 | } 383 | } 384 | if (current_token_length > 0) { 385 | memcpy(rdest + si, current_token, current_token_length); 386 | } 387 | } 388 | } -------------------------------------------------------------------------------- /hardnested/hardnested_bruteforce.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) 2016, 2017 by piwi 3 | // 4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, 5 | // at your option, any later version. See the LICENSE.txt file for the text of 6 | // the license. 7 | //----------------------------------------------------------------------------- 8 | // Implements a card only attack based on crypto text (encrypted nonces 9 | // received during a nested authentication) only. Unlike other card only 10 | // attacks this doesn't rely on implementation errors but only on the 11 | // inherent weaknesses of the crypto1 cypher. Described in 12 | // Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened 13 | // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on 14 | // Computer and Communications Security, 2015 15 | //----------------------------------------------------------------------------- 16 | // 17 | // brute forcing is based on @aczids bitsliced brute forcer 18 | // https://github.com/aczid/crypto1_bs with some modifications. Mainly: 19 | // - don't rollback. Start with 2nd byte of nonce instead 20 | // - reuse results of filter subfunctions 21 | // - reuse results of previous nonces if some first bits are identical 22 | // 23 | //----------------------------------------------------------------------------- 24 | // aczid's Copyright notice: 25 | // 26 | // Bit-sliced Crypto-1 brute-forcing implementation 27 | // Builds on the data structures returned by CraptEV1 craptev1_get_space(nonces, threshold, uid) 28 | /* 29 | Copyright (c) 2015-2016 Aram Verstegen 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to deal 33 | in the Software without restriction, including without limitation the rights 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in 39 | all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47 | THE SOFTWARE. 48 | */ 49 | 50 | #include "hardnested_bruteforce.h" 51 | 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | #include "hardnested_bf_core.h" 60 | #include "../pm3/ui.h" 61 | #include "../pm3/util_posix.h" 62 | #include "../crapto1.h" 63 | #include "../parity.h" 64 | #include "../cmdhfmfhard.h" 65 | #include "hardnested_benchmark_data.h" 66 | 67 | #define NUM_BRUTE_FORCE_THREADS (num_CPUs()) 68 | #ifdef _WIN32 69 | #define NUM_BRUTE_FORCE_THREADS_ALLOC 128 70 | #else 71 | #define NUM_BRUTE_FORCE_THREADS_ALLOC (num_CPUs()) 72 | #endif 73 | #define DEFAULT_BRUTE_FORCE_RATE (120000000.0) // if benchmark doesn't succeed 74 | #define TEST_BENCH_SIZE (6000) // number of odd and even states for brute force benchmark 75 | 76 | #ifdef _MSC_VER 77 | #include 78 | #include 79 | #include 80 | #include 81 | #include 82 | #define atomic_add(num, val) (InterlockedExchangeAdd64(num, val) + val) 83 | FILE *fmemopen(void *buf, size_t len, const char *type) 84 | { 85 | int fd; 86 | FILE *fp; 87 | char tp[MAX_PATH - 13]; 88 | char fn[MAX_PATH + 1]; 89 | int * pfd = &fd; 90 | int retner = -1; 91 | char tfname[] = "MemTF_"; 92 | if (!GetTempPathA(sizeof(tp), tp)) 93 | return NULL; 94 | if (!GetTempFileNameA(tp, tfname, 0, fn)) 95 | return NULL; 96 | retner = _sopen_s(pfd, fn, _O_CREAT | _O_SHORT_LIVED | _O_TEMPORARY | _O_RDWR | _O_BINARY | _O_NOINHERIT, _SH_DENYRW, _S_IREAD | _S_IWRITE); 97 | if (retner != 0) 98 | return NULL; 99 | if (fd == -1) 100 | return NULL; 101 | fp = _fdopen(fd, "wb+"); 102 | if (!fp) { 103 | _close(fd); 104 | return NULL; 105 | } 106 | /*File descriptors passed into _fdopen are owned by the returned FILE * stream.If _fdopen is successful, do not call _close on the file descriptor.Calling fclose on the returned FILE * also closes the file descriptor.*/ 107 | fwrite(buf, len, 1, fp); 108 | rewind(fp); 109 | return fp; 110 | } 111 | #else 112 | #define atomic_add __sync_fetch_and_add 113 | #endif 114 | // debugging options 115 | #define DEBUG_KEY_ELIMINATION 1 116 | // #define DEBUG_BRUTE_FORCE 117 | 118 | typedef enum { 119 | EVEN_STATE = 0, 120 | ODD_STATE = 1 121 | } odd_even_t; 122 | 123 | static uint32_t nonces_to_bruteforce = 0; 124 | static uint32_t bf_test_nonce[256]; 125 | static uint8_t bf_test_nonce_2nd_byte[256]; 126 | static uint8_t bf_test_nonce_par[256]; 127 | static uint32_t bucket_count = 0; 128 | static statelist_t *buckets[128]; 129 | static uint32_t keys_found = 0; 130 | static uint64_t num_keys_tested; 131 | static uint64_t found_bs_key = 0; 132 | 133 | inline uint8_t trailing_zeros(uint8_t byte) { 134 | static const uint8_t trailing_zeros_LUT[256] = { 135 | 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 136 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 137 | 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 138 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 139 | 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 140 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 141 | 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 142 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 143 | 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 144 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 145 | 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 146 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 147 | 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 148 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 149 | 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 150 | 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 151 | }; 152 | 153 | return trailing_zeros_LUT[byte]; 154 | } 155 | 156 | 157 | bool verify_key(uint32_t cuid, noncelist_t *nonces, const uint8_t *best_first_bytes, uint32_t odd, uint32_t even) { 158 | struct Crypto1State pcs; 159 | if (best_first_bytes == NULL) { 160 | return false; 161 | } 162 | for (uint16_t test_first_byte = 1; test_first_byte < 256; test_first_byte++) { 163 | noncelistentry_t *test_nonce = nonces[best_first_bytes[test_first_byte]].first; 164 | while (test_nonce != NULL) { 165 | pcs.odd = odd; 166 | pcs.even = even; 167 | lfsr_rollback_byte(&pcs, (cuid >> 24) ^ best_first_bytes[0], true); 168 | for (int8_t byte_pos = 3; byte_pos >= 0; byte_pos--) { 169 | uint8_t test_par_enc_bit = (test_nonce->par_enc >> byte_pos) & 0x01; // the encoded parity bit 170 | uint8_t test_byte_enc = (test_nonce->nonce_enc >> (8 * byte_pos)) & 0xff; // the encoded nonce byte 171 | uint8_t test_byte_dec = crypto1_byte(&pcs, test_byte_enc /* ^ (cuid >> (8*byte_pos)) */, true) ^ test_byte_enc; // decode the nonce byte 172 | uint8_t ks_par = filter(pcs.odd); // the keystream bit to encode/decode the parity bit 173 | uint8_t test_par_enc2 = ks_par ^ evenparity8(test_byte_dec); // determine the decoded byte's parity and encode it 174 | if (test_par_enc_bit != test_par_enc2) { 175 | return false; 176 | } 177 | } 178 | test_nonce = test_nonce->next; 179 | } 180 | } 181 | return true; 182 | } 183 | static void * 184 | #ifdef __has_attribute 185 | #if __has_attribute(force_align_arg_pointer) 186 | __attribute__((force_align_arg_pointer)) 187 | #endif 188 | #endif 189 | crack_states_thread(void *x) { 190 | struct arg { 191 | bool silent; 192 | int thread_ID; 193 | uint32_t cuid; 194 | uint32_t num_acquired_nonces; 195 | uint64_t maximum_states; 196 | noncelist_t *nonces; 197 | uint8_t *best_first_bytes; 198 | } *thread_arg; 199 | 200 | thread_arg = (struct arg *)x; 201 | const int thread_id = thread_arg->thread_ID; 202 | uint32_t current_bucket = thread_id; 203 | while (current_bucket < bucket_count) { 204 | statelist_t *bucket = buckets[current_bucket]; 205 | if (bucket) { 206 | #if defined (DEBUG_BRUTE_FORCE) 207 | PrintAndLogEx(INFO, "Thread " _YELLOW_("%u") " starts working on bucket " _YELLOW_("%u") "\n", thread_id, current_bucket); 208 | #endif 209 | const uint64_t key = crack_states_bitsliced(thread_arg->cuid, thread_arg->best_first_bytes, bucket, &keys_found, &num_keys_tested, nonces_to_bruteforce, bf_test_nonce_2nd_byte, thread_arg->nonces); 210 | if (key != -1) { 211 | atomic_add(&keys_found, 1); 212 | atomic_add(&found_bs_key, key); 213 | 214 | char progress_text[80]; 215 | char keystr[19]; 216 | snprintf(keystr, sizeof(keystr), "%012" PRIX64 " ", key); 217 | snprintf(progress_text, sizeof(progress_text), "Brute force phase completed. Key found: " _GREEN_("%s"), keystr); 218 | hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0); 219 | break; 220 | } else if (keys_found) { 221 | break; 222 | } else { 223 | if (!thread_arg->silent) { 224 | char progress_text[80]; 225 | snprintf(progress_text, sizeof(progress_text), "Brute force phase: %6.02f%%", 100.0 * (float)num_keys_tested / (float)(thread_arg->maximum_states)); 226 | float remaining_bruteforce = thread_arg->nonces[thread_arg->best_first_bytes[0]].expected_num_brute_force - (float)num_keys_tested / 2; 227 | hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, remaining_bruteforce, 5000); 228 | } 229 | } 230 | } 231 | current_bucket += NUM_BRUTE_FORCE_THREADS; 232 | } 233 | return NULL; 234 | } 235 | 236 | 237 | void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) { 238 | // we do bitsliced brute forcing with best_first_bytes[0] only. 239 | // Extract the corresponding 2nd bytes 240 | noncelistentry_t *test_nonce = nonces[best_first_byte].first; 241 | uint32_t i = 0; 242 | while (test_nonce != NULL) { 243 | bf_test_nonce[i] = test_nonce->nonce_enc; 244 | bf_test_nonce_par[i] = test_nonce->par_enc; 245 | bf_test_nonce_2nd_byte[i] = (test_nonce->nonce_enc >> 16) & 0xff; 246 | test_nonce = test_nonce->next; 247 | i++; 248 | } 249 | nonces_to_bruteforce = i; 250 | 251 | // printf("Nonces to bruteforce: %d\n", nonces_to_bruteforce); 252 | // printf("Common bits of first 4 2nd nonce bytes (before sorting): %u %u %u\n", 253 | // trailing_zeros(bf_test_nonce_2nd_byte[1] ^ bf_test_nonce_2nd_byte[0]), 254 | // trailing_zeros(bf_test_nonce_2nd_byte[2] ^ bf_test_nonce_2nd_byte[1]), 255 | // trailing_zeros(bf_test_nonce_2nd_byte[3] ^ bf_test_nonce_2nd_byte[2])); 256 | 257 | uint8_t best_4[4] = {0}; 258 | int sum_best = -1; 259 | for (uint32_t n1 = 0; n1 < nonces_to_bruteforce; n1++) { 260 | for (uint32_t n2 = 0; n2 < nonces_to_bruteforce; n2++) { 261 | if (n2 != n1) { 262 | for (uint32_t n3 = 0; n3 < nonces_to_bruteforce; n3++) { 263 | if ((n3 != n2 && n3 != n1) || nonces_to_bruteforce < 3 264 | // && trailing_zeros(bf_test_nonce_2nd_byte[n1] ^ bf_test_nonce_2nd_byte[n2]) 265 | // > trailing_zeros(bf_test_nonce_2nd_byte[n2] ^ bf_test_nonce_2nd_byte[n3]) 266 | ) { 267 | for (uint32_t n4 = 0; n4 < nonces_to_bruteforce; n4++) { 268 | if ((n4 != n3 && n4 != n2 && n4 != n1) || nonces_to_bruteforce < 4 269 | // && trailing_zeros(bf_test_nonce_2nd_byte[n2] ^ bf_test_nonce_2nd_byte[n3]) 270 | // > trailing_zeros(bf_test_nonce_2nd_byte[n3] ^ bf_test_nonce_2nd_byte[n4]) 271 | ) { 272 | int sum = nonces_to_bruteforce > 1 ? trailing_zeros(bf_test_nonce_2nd_byte[n1] ^ bf_test_nonce_2nd_byte[n2]) : 0.0 273 | + nonces_to_bruteforce > 2 ? trailing_zeros(bf_test_nonce_2nd_byte[n2] ^ bf_test_nonce_2nd_byte[n3]) : 0.0 274 | + nonces_to_bruteforce > 3 ? trailing_zeros(bf_test_nonce_2nd_byte[n3] ^ bf_test_nonce_2nd_byte[n4]) : 0.0; 275 | if (sum > sum_best) { 276 | sum_best = sum; 277 | best_4[0] = n1; 278 | best_4[1] = n2; 279 | best_4[2] = n3; 280 | best_4[3] = n4; 281 | } 282 | } 283 | } 284 | } 285 | } 286 | } 287 | } 288 | } 289 | 290 | uint32_t bf_test_nonce_temp[4]; 291 | uint8_t bf_test_nonce_par_temp[4]; 292 | uint8_t bf_test_nonce_2nd_byte_temp[4]; 293 | for (uint32_t j = 0; j < 4 && j < nonces_to_bruteforce; j++) { 294 | bf_test_nonce_temp[j] = bf_test_nonce[best_4[j]]; 295 | 296 | bf_test_nonce_par_temp[j] = bf_test_nonce_par[best_4[j]]; 297 | bf_test_nonce_2nd_byte_temp[j] = bf_test_nonce_2nd_byte[best_4[j]]; 298 | } 299 | for (uint32_t j = 0; j < 4 && j < nonces_to_bruteforce; j++) { 300 | bf_test_nonce[j] = bf_test_nonce_temp[j]; 301 | bf_test_nonce_par[j] = bf_test_nonce_par_temp[j]; 302 | bf_test_nonce_2nd_byte[j] = bf_test_nonce_2nd_byte_temp[j]; 303 | } 304 | } 305 | 306 | bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes, uint64_t *found_key) { 307 | #if defined (WRITE_BENCH_FILE) 308 | write_benchfile(candidates); 309 | #endif 310 | bool silent = (bf_rate != NULL); 311 | 312 | keys_found = 0; 313 | num_keys_tested = 0; 314 | found_bs_key = 0; 315 | 316 | bitslice_test_nonces(nonces_to_bruteforce, bf_test_nonce, bf_test_nonce_par); 317 | 318 | // count number of states to go 319 | bucket_count = 0; 320 | for (statelist_t *p = candidates; p != NULL; p = p->next) { 321 | if (p->states[ODD_STATE] != NULL && p->states[EVEN_STATE] != NULL) { 322 | buckets[bucket_count] = p; 323 | bucket_count++; 324 | } 325 | } 326 | 327 | uint64_t start_time = msclock(); 328 | 329 | #if defined(__linux__) || defined(__APPLE__) 330 | if (NUM_BRUTE_FORCE_THREADS < 0) 331 | return false; 332 | #endif 333 | 334 | pthread_t threads[NUM_BRUTE_FORCE_THREADS_ALLOC]; 335 | struct args { 336 | bool silent; 337 | int thread_ID; 338 | uint32_t cuid; 339 | uint32_t num_acquired_nonces; 340 | uint64_t maximum_states; 341 | noncelist_t *nonces; 342 | uint8_t *best_first_bytes; 343 | } thread_args[NUM_BRUTE_FORCE_THREADS_ALLOC]; 344 | 345 | for (uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++) { 346 | thread_args[i].thread_ID = i; 347 | thread_args[i].silent = silent; 348 | thread_args[i].cuid = cuid; 349 | thread_args[i].num_acquired_nonces = num_acquired_nonces; 350 | thread_args[i].maximum_states = maximum_states; 351 | thread_args[i].nonces = nonces; 352 | thread_args[i].best_first_bytes = best_first_bytes; 353 | pthread_create(&threads[i], NULL, crack_states_thread, (void *)&thread_args[i]); 354 | } 355 | for (uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++) { 356 | pthread_join(threads[i], 0); 357 | } 358 | 359 | uint64_t elapsed_time = msclock() - start_time; 360 | 361 | if (bf_rate != NULL) 362 | *bf_rate = (float)num_keys_tested / ((float)elapsed_time / 1000.0); 363 | 364 | if (keys_found > 0) 365 | *found_key = found_bs_key; 366 | 367 | return (keys_found != 0); 368 | } 369 | 370 | 371 | static bool read_bench_data(statelist_t *test_candidates) { 372 | size_t bytes_read = 0; 373 | uint32_t temp = 0; 374 | uint32_t num_states = 0; 375 | uint32_t states_read = 0; 376 | 377 | FILE *benchfile = fmemopen(client_resources_hardnested_bf_bench_data_bin, client_resources_hardnested_bf_bench_data_bin_len, "rb"); 378 | if (benchfile == NULL) { 379 | return false; 380 | } 381 | bytes_read = fread(&nonces_to_bruteforce, 1, sizeof(nonces_to_bruteforce), benchfile); 382 | if (bytes_read != sizeof(nonces_to_bruteforce)) { 383 | fclose(benchfile); 384 | return false; 385 | } 386 | for (uint32_t i = 0; i < nonces_to_bruteforce && i < 256; i++) { 387 | bytes_read = fread(&bf_test_nonce[i], 1, sizeof(uint32_t), benchfile); 388 | if (bytes_read != sizeof(uint32_t)) { 389 | fclose(benchfile); 390 | return false; 391 | } 392 | bf_test_nonce_2nd_byte[i] = (bf_test_nonce[i] >> 16) & 0xff; 393 | bytes_read = fread(&bf_test_nonce_par[i], 1, sizeof(uint8_t), benchfile); 394 | if (bytes_read != sizeof(uint8_t)) { 395 | fclose(benchfile); 396 | return false; 397 | } 398 | } 399 | bytes_read = fread(&num_states, 1, sizeof(uint32_t), benchfile); 400 | if (bytes_read != sizeof(uint32_t)) { 401 | fclose(benchfile); 402 | return false; 403 | } 404 | for (states_read = 0; states_read < MIN(num_states, TEST_BENCH_SIZE); states_read++) { 405 | bytes_read = fread(test_candidates->states[EVEN_STATE] + states_read, 1, sizeof(uint32_t), benchfile); 406 | if (bytes_read != sizeof(uint32_t)) { 407 | fclose(benchfile); 408 | return false; 409 | } 410 | } 411 | for (uint32_t i = states_read; i < TEST_BENCH_SIZE; i++) { 412 | test_candidates->states[EVEN_STATE][i] = test_candidates->states[EVEN_STATE][i - states_read]; 413 | } 414 | for (uint32_t i = states_read; i < num_states; i++) { 415 | bytes_read = fread(&temp, 1, sizeof(uint32_t), benchfile); 416 | if (bytes_read != sizeof(uint32_t)) { 417 | fclose(benchfile); 418 | return false; 419 | } 420 | } 421 | for (states_read = 0; states_read < MIN(num_states, TEST_BENCH_SIZE); states_read++) { 422 | bytes_read = fread(test_candidates->states[ODD_STATE] + states_read, 1, sizeof(uint32_t), benchfile); 423 | if (bytes_read != sizeof(uint32_t)) { 424 | fclose(benchfile); 425 | return false; 426 | } 427 | } 428 | for (uint32_t i = states_read; i < TEST_BENCH_SIZE; i++) { 429 | test_candidates->states[ODD_STATE][i] = test_candidates->states[ODD_STATE][i - states_read]; 430 | } 431 | 432 | fclose(benchfile); 433 | return true; 434 | } 435 | 436 | 437 | float brute_force_benchmark(void) { 438 | statelist_t test_candidates[NUM_BRUTE_FORCE_THREADS_ALLOC]; 439 | 440 | test_candidates[0].states[ODD_STATE] = calloc(1, (TEST_BENCH_SIZE + 1) * sizeof(uint32_t)); 441 | test_candidates[0].states[EVEN_STATE] = calloc(1, (TEST_BENCH_SIZE + 1) * sizeof(uint32_t)); 442 | for (uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS - 1; i++) { 443 | test_candidates[i].next = test_candidates + i + 1; 444 | test_candidates[i + 1].states[ODD_STATE] = test_candidates[0].states[ODD_STATE]; 445 | test_candidates[i + 1].states[EVEN_STATE] = test_candidates[0].states[EVEN_STATE]; 446 | } 447 | test_candidates[NUM_BRUTE_FORCE_THREADS - 1].next = NULL; 448 | 449 | if (!read_bench_data(test_candidates)) { 450 | return DEFAULT_BRUTE_FORCE_RATE; 451 | } 452 | 453 | for (uint32_t i = 0; i < NUM_BRUTE_FORCE_THREADS; i++) { 454 | test_candidates[i].len[ODD_STATE] = TEST_BENCH_SIZE; 455 | test_candidates[i].len[EVEN_STATE] = TEST_BENCH_SIZE; 456 | test_candidates[i].states[ODD_STATE][TEST_BENCH_SIZE] = -1; 457 | test_candidates[i].states[EVEN_STATE][TEST_BENCH_SIZE] = -1; 458 | } 459 | 460 | uint64_t maximum_states = TEST_BENCH_SIZE * TEST_BENCH_SIZE * (uint64_t)NUM_BRUTE_FORCE_THREADS; 461 | 462 | float bf_rate; 463 | uint64_t found_key = 0; 464 | brute_force_bs(&bf_rate, test_candidates, 0, 0, maximum_states, NULL, 0, &found_key); 465 | 466 | free(test_candidates[0].states[ODD_STATE]); 467 | free(test_candidates[0].states[EVEN_STATE]); 468 | test_candidates[0].len[ODD_STATE] = 0; 469 | test_candidates[0].len[EVEN_STATE] = 0; 470 | return bf_rate; 471 | } 472 | 473 | 474 | -------------------------------------------------------------------------------- /hardnested/hardnested_bitarray_core.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) 2016, 2017 by piwi 3 | // 4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, 5 | // at your option, any later version. See the LICENSE.txt file for the text of 6 | // the license.ch b 7 | //----------------------------------------------------------------------------- 8 | // Implements a card only attack based on crypto text (encrypted nonces 9 | // received during a nested authentication) only. Unlike other card only 10 | // attacks this doesn't rely on implementation errors but only on the 11 | // inherent weaknesses of the crypto1 cypher. Described in 12 | // Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened 13 | // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on 14 | // Computer and Communications Security, 2015 15 | //----------------------------------------------------------------------------- 16 | // some helper functions which can benefit from SIMD instructions or other special instructions 17 | // 18 | 19 | #include "hardnested_bitarray_core.h" 20 | #include "hardnested_bf_core.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #ifndef __APPLE__ 26 | #include 27 | #endif 28 | 29 | //// this needs to be compiled several times for each instruction set. 30 | //// For each instruction set, define a dedicated function name: 31 | //#if defined (__AVX512F__) 32 | //#define MALLOC_BITARRAY malloc_bitarray_AVX512 33 | //#define FREE_BITARRAY free_bitarray_AVX512 34 | //#define BITCOUNT bitcount_AVX512 35 | //#define COUNT_STATES count_states_AVX512 36 | //#define BITARRAY_AND bitarray_AND_AVX512 37 | //#define BITARRAY_LOW20_AND bitarray_low20_AND_AVX512 38 | //#define COUNT_BITARRAY_AND count_bitarray_AND_AVX512 39 | //#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_AVX512 40 | //#define BITARRAY_AND4 bitarray_AND4_AVX512 41 | //#define BITARRAY_OR bitarray_OR_AVX512 42 | //#define COUNT_BITARRAY_AND2 count_bitarray_AND2_AVX512 43 | //#define COUNT_BITARRAY_AND3 count_bitarray_AND3_AVX512 44 | //#define COUNT_BITARRAY_AND4 count_bitarray_AND4_AVX512 45 | //#elif defined (__AVX2__) 46 | //#define MALLOC_BITARRAY malloc_bitarray_AVX2 47 | //#define FREE_BITARRAY free_bitarray_AVX2 48 | //#define BITCOUNT bitcount_AVX2 49 | //#define COUNT_STATES count_states_AVX2 50 | //#define BITARRAY_AND bitarray_AND_AVX2 51 | //#define BITARRAY_LOW20_AND bitarray_low20_AND_AVX2 52 | //#define COUNT_BITARRAY_AND count_bitarray_AND_AVX2 53 | //#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_AVX2 54 | //#define BITARRAY_AND4 bitarray_AND4_AVX2 55 | //#define BITARRAY_OR bitarray_OR_AVX2 56 | //#define COUNT_BITARRAY_AND2 count_bitarray_AND2_AVX2 57 | //#define COUNT_BITARRAY_AND3 count_bitarray_AND3_AVX2 58 | //#define COUNT_BITARRAY_AND4 count_bitarray_AND4_AVX2 59 | //#elif defined (__AVX__) 60 | //#define MALLOC_BITARRAY malloc_bitarray_AVX 61 | //#define FREE_BITARRAY free_bitarray_AVX 62 | //#define BITCOUNT bitcount_AVX 63 | //#define COUNT_STATES count_states_AVX 64 | //#define BITARRAY_AND bitarray_AND_AVX 65 | //#define BITARRAY_LOW20_AND bitarray_low20_AND_AVX 66 | //#define COUNT_BITARRAY_AND count_bitarray_AND_AVX 67 | //#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_AVX 68 | //#define BITARRAY_AND4 bitarray_AND4_AVX 69 | //#define BITARRAY_OR bitarray_OR_AVX 70 | //#define COUNT_BITARRAY_AND2 count_bitarray_AND2_AVX 71 | //#define COUNT_BITARRAY_AND3 count_bitarray_AND3_AVX 72 | //#define COUNT_BITARRAY_AND4 count_bitarray_AND4_AVX 73 | //#elif defined (__SSE2__) 74 | //#define MALLOC_BITARRAY malloc_bitarray_SSE2 75 | //#define FREE_BITARRAY free_bitarray_SSE2 76 | //#define BITCOUNT bitcount_SSE2 77 | //#define COUNT_STATES count_states_SSE2 78 | //#define BITARRAY_AND bitarray_AND_SSE2 79 | //#define BITARRAY_LOW20_AND bitarray_low20_AND_SSE2 80 | //#define COUNT_BITARRAY_AND count_bitarray_AND_SSE2 81 | //#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_SSE2 82 | //#define BITARRAY_AND4 bitarray_AND4_SSE2 83 | //#define BITARRAY_OR bitarray_OR_SSE2 84 | //#define COUNT_BITARRAY_AND2 count_bitarray_AND2_SSE2 85 | //#define COUNT_BITARRAY_AND3 count_bitarray_AND3_SSE2 86 | //#define COUNT_BITARRAY_AND4 count_bitarray_AND4_SSE2 87 | //#elif defined (__MMX__) 88 | //#define MALLOC_BITARRAY malloc_bitarray_MMX 89 | //#define FREE_BITARRAY free_bitarray_MMX 90 | //#define BITCOUNT bitcount_MMX 91 | //#define COUNT_STATES count_states_MMX 92 | //#define BITARRAY_AND bitarray_AND_MMX 93 | //#define BITARRAY_LOW20_AND bitarray_low20_AND_MMX 94 | //#define COUNT_BITARRAY_AND count_bitarray_AND_MMX 95 | //#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_MMX 96 | //#define BITARRAY_AND4 bitarray_AND4_MMX 97 | //#define BITARRAY_OR bitarray_OR_MMX 98 | //#define COUNT_BITARRAY_AND2 count_bitarray_AND2_MMX 99 | //#define COUNT_BITARRAY_AND3 count_bitarray_AND3_MMX 100 | //#define COUNT_BITARRAY_AND4 count_bitarray_AND4_MMX 101 | //#elif defined (__ARM_NEON) && !defined (NOSIMD_BUILD) 102 | //#define MALLOC_BITARRAY malloc_bitarray_NEON 103 | //#define FREE_BITARRAY free_bitarray_NEON 104 | //#define BITCOUNT bitcount_NEON 105 | //#define COUNT_STATES count_states_NEON 106 | //#define BITARRAY_AND bitarray_AND_NEON 107 | //#define BITARRAY_LOW20_AND bitarray_low20_AND_NEON 108 | //#define COUNT_BITARRAY_AND count_bitarray_AND_NEON 109 | //#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_NEON 110 | //#define BITARRAY_AND4 bitarray_AND4_NEON 111 | //#define BITARRAY_OR bitarray_OR_NEON 112 | //#define COUNT_BITARRAY_AND2 count_bitarray_AND2_NEON 113 | //#define COUNT_BITARRAY_AND3 count_bitarray_AND3_NEON 114 | //#define COUNT_BITARRAY_AND4 count_bitarray_AND4_NEON 115 | //#else 116 | //#define MALLOC_BITARRAY malloc_bitarray_NOSIMD 117 | //#define FREE_BITARRAY free_bitarray_NOSIMD 118 | //#define BITCOUNT bitcount_NOSIMD 119 | //#define COUNT_STATES count_states_NOSIMD 120 | //#define BITARRAY_AND bitarray_AND_NOSIMD 121 | //#define BITARRAY_LOW20_AND bitarray_low20_AND_NOSIMD 122 | //#define COUNT_BITARRAY_AND count_bitarray_AND_NOSIMD 123 | //#define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_NOSIMD 124 | //#define BITARRAY_AND4 bitarray_AND4_NOSIMD 125 | //#define BITARRAY_OR bitarray_OR_NOSIMD 126 | //#define COUNT_BITARRAY_AND2 count_bitarray_AND2_NOSIMD 127 | //#define COUNT_BITARRAY_AND3 count_bitarray_AND3_NOSIMD 128 | //#define COUNT_BITARRAY_AND4 count_bitarray_AND4_NOSIMD 129 | //#endif 130 | 131 | 132 | #ifndef __BIGGEST_ALIGNMENT__ 133 | #include 134 | static const size_t __BIGGEST_ALIGNMENT__ = _Alignof(long double); 135 | #endif 136 | 137 | #ifdef _MSC_VER 138 | #include // For __popcnt64 139 | unsigned int __builtin_popcountl(unsigned long long x) { 140 | return __popcnt64(x); 141 | } 142 | #endif 143 | 144 | #ifdef _MSC_VER 145 | #include 146 | #define atomic_add(num, val) (InterlockedExchangeAdd(num, val) + val) 147 | #else 148 | #define atomic_add __sync_fetch_and_add 149 | #endif 150 | 151 | #define MALLOC_BITARRAY malloc_bitarray_NOSIMD 152 | #define FREE_BITARRAY free_bitarray_NOSIMD 153 | #define BITCOUNT bitcount_NOSIMD 154 | #define COUNT_STATES count_states_NOSIMD 155 | #define BITARRAY_AND bitarray_AND_NOSIMD 156 | #define BITARRAY_LOW20_AND bitarray_low20_AND_NOSIMD 157 | #define COUNT_BITARRAY_AND count_bitarray_AND_NOSIMD 158 | #define COUNT_BITARRAY_LOW20_AND count_bitarray_low20_AND_NOSIMD 159 | #define BITARRAY_AND4 bitarray_AND4_NOSIMD 160 | #define BITARRAY_OR bitarray_OR_NOSIMD 161 | #define COUNT_BITARRAY_AND2 count_bitarray_AND2_NOSIMD 162 | #define COUNT_BITARRAY_AND3 count_bitarray_AND3_NOSIMD 163 | #define COUNT_BITARRAY_AND4 count_bitarray_AND4_NOSIMD 164 | 165 | // typedefs and declaration of functions: 166 | typedef uint32_t *malloc_bitarray_t(uint32_t); 167 | malloc_bitarray_t malloc_bitarray_AVX512, malloc_bitarray_AVX2, malloc_bitarray_AVX, malloc_bitarray_SSE2, malloc_bitarray_MMX, malloc_bitarray_NOSIMD, malloc_bitarray_NEON, malloc_bitarray_dispatch; 168 | typedef void free_bitarray_t(uint32_t *); 169 | free_bitarray_t free_bitarray_AVX512, free_bitarray_AVX2, free_bitarray_AVX, free_bitarray_SSE2, free_bitarray_MMX, free_bitarray_NOSIMD, free_bitarray_NEON, free_bitarray_dispatch; 170 | typedef uint32_t bitcount_t(uint32_t); 171 | bitcount_t bitcount_AVX512, bitcount_AVX2, bitcount_AVX, bitcount_SSE2, bitcount_MMX, bitcount_NOSIMD, bitcount_NEON, bitcount_dispatch; 172 | typedef uint32_t count_states_t(uint32_t *); 173 | count_states_t count_states_AVX512, count_states_AVX2, count_states_AVX, count_states_SSE2, count_states_MMX, count_states_NOSIMD, count_states_NEON, count_states_dispatch; 174 | typedef void bitarray_AND_t(uint32_t[], uint32_t[]); 175 | bitarray_AND_t bitarray_AND_AVX512, bitarray_AND_AVX2, bitarray_AND_AVX, bitarray_AND_SSE2, bitarray_AND_MMX, bitarray_AND_NOSIMD, bitarray_AND_NEON, bitarray_AND_dispatch; 176 | typedef void bitarray_low20_AND_t(uint32_t *, uint32_t *); 177 | bitarray_low20_AND_t bitarray_low20_AND_AVX512, bitarray_low20_AND_AVX2, bitarray_low20_AND_AVX, bitarray_low20_AND_SSE2, bitarray_low20_AND_MMX, bitarray_low20_AND_NOSIMD, bitarray_low20_AND_NEON, bitarray_low20_AND_dispatch; 178 | typedef uint32_t count_bitarray_AND_t(uint32_t *, uint32_t *); 179 | count_bitarray_AND_t count_bitarray_AND_AVX512, count_bitarray_AND_AVX2, count_bitarray_AND_AVX, count_bitarray_AND_SSE2, count_bitarray_AND_MMX, count_bitarray_AND_NOSIMD, count_bitarray_AND_NEON, count_bitarray_AND_dispatch; 180 | typedef uint32_t count_bitarray_low20_AND_t(uint32_t *, uint32_t *); 181 | count_bitarray_low20_AND_t count_bitarray_low20_AND_AVX512, count_bitarray_low20_AND_AVX2, count_bitarray_low20_AND_AVX, count_bitarray_low20_AND_SSE2, count_bitarray_low20_AND_MMX, count_bitarray_low20_AND_NOSIMD, count_bitarray_low20_AND_NEON, count_bitarray_low20_AND_dispatch; 182 | typedef void bitarray_AND4_t(uint32_t *, uint32_t *, uint32_t *, uint32_t *); 183 | bitarray_AND4_t bitarray_AND4_AVX512, bitarray_AND4_AVX2, bitarray_AND4_AVX, bitarray_AND4_SSE2, bitarray_AND4_MMX, bitarray_AND4_NOSIMD, bitarray_AND4_NEON, bitarray_AND4_dispatch; 184 | typedef void bitarray_OR_t(uint32_t[], uint32_t[]); 185 | bitarray_OR_t bitarray_OR_AVX512, bitarray_OR_AVX2, bitarray_OR_AVX, bitarray_OR_SSE2, bitarray_OR_MMX, bitarray_OR_NOSIMD, bitarray_OR_NEON, bitarray_OR_dispatch; 186 | typedef uint32_t count_bitarray_AND2_t(uint32_t *, uint32_t *); 187 | count_bitarray_AND2_t count_bitarray_AND2_AVX512, count_bitarray_AND2_AVX2, count_bitarray_AND2_AVX, count_bitarray_AND2_SSE2, count_bitarray_AND2_MMX, count_bitarray_AND2_NOSIMD, count_bitarray_AND2_NEON, count_bitarray_AND2_dispatch; 188 | typedef uint32_t count_bitarray_AND3_t(uint32_t *, uint32_t *, uint32_t *); 189 | count_bitarray_AND3_t count_bitarray_AND3_AVX512, count_bitarray_AND3_AVX2, count_bitarray_AND3_AVX, count_bitarray_AND3_SSE2, count_bitarray_AND3_MMX, count_bitarray_AND3_NOSIMD, count_bitarray_AND3_NEON, count_bitarray_AND3_dispatch; 190 | typedef uint32_t count_bitarray_AND4_t(uint32_t *, uint32_t *, uint32_t *, uint32_t *); 191 | count_bitarray_AND4_t count_bitarray_AND4_AVX512, count_bitarray_AND4_AVX2, count_bitarray_AND4_AVX, count_bitarray_AND4_SSE2, count_bitarray_AND4_MMX, count_bitarray_AND4_NOSIMD, count_bitarray_AND4_NEON, count_bitarray_AND4_dispatch; 192 | 193 | 194 | inline uint32_t *MALLOC_BITARRAY(uint32_t x) { 195 | #if defined (_WIN32) 196 | return __builtin_assume_aligned(_aligned_malloc((x), __BIGGEST_ALIGNMENT__), __BIGGEST_ALIGNMENT__); 197 | #elif defined (__APPLE__) 198 | uint32_t *allocated_memory; 199 | if (posix_memalign((void **)&allocated_memory, __BIGGEST_ALIGNMENT__, x)) { 200 | return NULL; 201 | } else { 202 | return __builtin_assume_aligned(allocated_memory, __BIGGEST_ALIGNMENT__); 203 | } 204 | #else 205 | return __builtin_assume_aligned(memalign(__BIGGEST_ALIGNMENT__, (x)), __BIGGEST_ALIGNMENT__); 206 | #endif 207 | } 208 | 209 | 210 | inline void FREE_BITARRAY(uint32_t *x) { 211 | #ifdef _WIN32 212 | _aligned_free(x); 213 | #else 214 | free(x); 215 | #endif 216 | } 217 | 218 | 219 | inline uint32_t BITCOUNT(uint32_t a) { 220 | return __builtin_popcountl(a); 221 | } 222 | 223 | 224 | inline uint32_t COUNT_STATES(uint32_t *A) { 225 | uint32_t count = 0; 226 | for (uint32_t i = 0; i < (1 << 19); i++) { 227 | count += BITCOUNT(A[i]); 228 | } 229 | return count; 230 | } 231 | 232 | 233 | inline void BITARRAY_AND(uint32_t *restrict A, uint32_t *restrict B) { 234 | A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); 235 | B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); 236 | for (uint32_t i = 0; i < (1 << 19); i++) { 237 | A[i] &= B[i]; 238 | } 239 | } 240 | 241 | 242 | inline void BITARRAY_LOW20_AND(uint32_t *restrict A, uint32_t *restrict B) { 243 | uint16_t *a = (uint16_t *)__builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); 244 | uint16_t *b = (uint16_t *)__builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); 245 | 246 | for (uint32_t i = 0; i < (1 << 20); i++) { 247 | if (!b[i]) { 248 | a[i] = 0; 249 | } 250 | } 251 | } 252 | 253 | 254 | inline uint32_t COUNT_BITARRAY_AND(uint32_t *restrict A, uint32_t *restrict B) { 255 | A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); 256 | B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); 257 | uint32_t count = 0; 258 | for (uint32_t i = 0; i < (1 << 19); i++) { 259 | A[i] &= B[i]; 260 | count += BITCOUNT(A[i]); 261 | } 262 | return count; 263 | } 264 | 265 | 266 | inline uint32_t COUNT_BITARRAY_LOW20_AND(uint32_t *restrict A, uint32_t *restrict B) { 267 | uint16_t *a = (uint16_t *)__builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); 268 | uint16_t *b = (uint16_t *)__builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); 269 | uint32_t count = 0; 270 | 271 | for (uint32_t i = 0; i < (1 << 20); i++) { 272 | if (!b[i]) { 273 | a[i] = 0; 274 | } 275 | count += BITCOUNT(a[i]); 276 | } 277 | return count; 278 | } 279 | 280 | 281 | inline void BITARRAY_AND4(uint32_t *restrict A, uint32_t *restrict B, uint32_t *restrict C, uint32_t *restrict D) { 282 | A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); 283 | B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); 284 | C = __builtin_assume_aligned(C, __BIGGEST_ALIGNMENT__); 285 | D = __builtin_assume_aligned(D, __BIGGEST_ALIGNMENT__); 286 | for (uint32_t i = 0; i < (1 << 19); i++) { 287 | A[i] = B[i] & C[i] & D[i]; 288 | } 289 | } 290 | 291 | 292 | inline void BITARRAY_OR(uint32_t *restrict A, uint32_t *restrict B) { 293 | A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); 294 | B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); 295 | for (uint32_t i = 0; i < (1 << 19); i++) { 296 | A[i] |= B[i]; 297 | } 298 | } 299 | 300 | 301 | inline uint32_t COUNT_BITARRAY_AND2(uint32_t *restrict A, uint32_t *restrict B) { 302 | A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); 303 | B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); 304 | uint32_t count = 0; 305 | for (uint32_t i = 0; i < (1 << 19); i++) { 306 | count += BITCOUNT(A[i] & B[i]); 307 | } 308 | return count; 309 | } 310 | 311 | 312 | inline uint32_t COUNT_BITARRAY_AND3(uint32_t *restrict A, uint32_t *restrict B, uint32_t *restrict C) { 313 | A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); 314 | B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); 315 | C = __builtin_assume_aligned(C, __BIGGEST_ALIGNMENT__); 316 | uint32_t count = 0; 317 | for (uint32_t i = 0; i < (1 << 19); i++) { 318 | count += BITCOUNT(A[i] & B[i] & C[i]); 319 | } 320 | return count; 321 | } 322 | 323 | 324 | inline uint32_t COUNT_BITARRAY_AND4(uint32_t *restrict A, uint32_t *restrict B, uint32_t *restrict C, uint32_t *restrict D) { 325 | A = __builtin_assume_aligned(A, __BIGGEST_ALIGNMENT__); 326 | B = __builtin_assume_aligned(B, __BIGGEST_ALIGNMENT__); 327 | C = __builtin_assume_aligned(C, __BIGGEST_ALIGNMENT__); 328 | D = __builtin_assume_aligned(D, __BIGGEST_ALIGNMENT__); 329 | uint32_t count = 0; 330 | for (uint32_t i = 0; i < (1 << 19); i++) { 331 | count += BITCOUNT(A[i] & B[i] & C[i] & D[i]); 332 | } 333 | return count; 334 | } 335 | 336 | 337 | //#ifdef NOSIMD_BUILD 338 | 339 | // pointers to functions: 340 | malloc_bitarray_t *malloc_bitarray_function_p = &malloc_bitarray_dispatch; 341 | free_bitarray_t *free_bitarray_function_p = &free_bitarray_dispatch; 342 | bitcount_t *bitcount_function_p = &bitcount_dispatch; 343 | count_states_t *count_states_function_p = &count_states_dispatch; 344 | bitarray_AND_t *bitarray_AND_function_p = &bitarray_AND_dispatch; 345 | bitarray_low20_AND_t *bitarray_low20_AND_function_p = &bitarray_low20_AND_dispatch; 346 | count_bitarray_AND_t *count_bitarray_AND_function_p = &count_bitarray_AND_dispatch; 347 | count_bitarray_low20_AND_t *count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_dispatch; 348 | bitarray_AND4_t *bitarray_AND4_function_p = &bitarray_AND4_dispatch; 349 | bitarray_OR_t *bitarray_OR_function_p = &bitarray_OR_dispatch; 350 | count_bitarray_AND2_t *count_bitarray_AND2_function_p = &count_bitarray_AND2_dispatch; 351 | count_bitarray_AND3_t *count_bitarray_AND3_function_p = &count_bitarray_AND3_dispatch; 352 | count_bitarray_AND4_t *count_bitarray_AND4_function_p = &count_bitarray_AND4_dispatch; 353 | 354 | // determine the available instruction set at runtime and call the correct function 355 | uint32_t *malloc_bitarray_dispatch(uint32_t x) { 356 | //#if defined(COMPILER_HAS_SIMD_NEON) 357 | // if (arm_has_neon()) malloc_bitarray_function_p = &malloc_bitarray_NEON; 358 | // else 359 | //#endif 360 | // 361 | //#if defined(COMPILER_HAS_SIMD_AVX512) 362 | // if (__builtin_cpu_supports("avx512f")) malloc_bitarray_function_p = &malloc_bitarray_AVX512; 363 | // else 364 | //#endif 365 | //#if defined(COMPILER_HAS_SIMD_X86) 366 | // if (__builtin_cpu_supports("avx2")) malloc_bitarray_function_p = &malloc_bitarray_AVX2; 367 | // else if (__builtin_cpu_supports("avx")) malloc_bitarray_function_p = &malloc_bitarray_AVX; 368 | // else if (__builtin_cpu_supports("sse2")) malloc_bitarray_function_p = &malloc_bitarray_SSE2; 369 | // else if (__builtin_cpu_supports("mmx")) malloc_bitarray_function_p = &malloc_bitarray_MMX; 370 | // else 371 | //#endif 372 | // malloc_bitarray_function_p = &malloc_bitarray_NOSIMD; 373 | malloc_bitarray_function_p = &malloc_bitarray_NOSIMD; 374 | // call the most optimized function for this CPU 375 | return (*malloc_bitarray_function_p)(x); 376 | } 377 | 378 | void free_bitarray_dispatch(uint32_t *x) { 379 | //#if defined(COMPILER_HAS_SIMD_NEON) 380 | // if (arm_has_neon()) free_bitarray_function_p = &free_bitarray_NEON; 381 | // else 382 | //#endif 383 | // 384 | //#if defined(COMPILER_HAS_SIMD_AVX512) 385 | // if (__builtin_cpu_supports("avx512f")) free_bitarray_function_p = &free_bitarray_AVX512; 386 | // else 387 | //#endif 388 | //#if defined(COMPILER_HAS_SIMD_X86) 389 | // if (__builtin_cpu_supports("avx2")) free_bitarray_function_p = &free_bitarray_AVX2; 390 | // else if (__builtin_cpu_supports("avx")) free_bitarray_function_p = &free_bitarray_AVX; 391 | // else if (__builtin_cpu_supports("sse2")) free_bitarray_function_p = &free_bitarray_SSE2; 392 | // else if (__builtin_cpu_supports("mmx")) free_bitarray_function_p = &free_bitarray_MMX; 393 | // else 394 | //#endif 395 | // free_bitarray_function_p = &free_bitarray_NOSIMD; 396 | free_bitarray_function_p = &free_bitarray_NOSIMD; 397 | // call the most optimized function for this CPU 398 | (*free_bitarray_function_p)(x); 399 | } 400 | 401 | uint32_t bitcount_dispatch(uint32_t a) { 402 | //#if defined(COMPILER_HAS_SIMD_NEON) 403 | // if (arm_has_neon()) bitcount_function_p = &bitcount_NEON; 404 | // else 405 | //#endif 406 | // 407 | //#if defined(COMPILER_HAS_SIMD_AVX512) 408 | // if (__builtin_cpu_supports("avx512f")) bitcount_function_p = &bitcount_AVX512; 409 | // else 410 | //#endif 411 | //#if defined(COMPILER_HAS_SIMD_X86) 412 | // if (__builtin_cpu_supports("avx2")) bitcount_function_p = &bitcount_AVX2; 413 | // else if (__builtin_cpu_supports("avx")) bitcount_function_p = &bitcount_AVX; 414 | // else if (__builtin_cpu_supports("sse2")) bitcount_function_p = &bitcount_SSE2; 415 | // else if (__builtin_cpu_supports("mmx")) bitcount_function_p = &bitcount_MMX; 416 | // else 417 | //#endif 418 | // bitcount_function_p = &bitcount_NOSIMD; 419 | bitcount_function_p = &bitcount_NOSIMD; 420 | // call the most optimized function for this CPU 421 | return (*bitcount_function_p)(a); 422 | } 423 | 424 | uint32_t count_states_dispatch(uint32_t *bitarray) { 425 | //#if defined(COMPILER_HAS_SIMD_NEON) 426 | // if (arm_has_neon()) count_states_function_p = &count_states_NEON; 427 | // else 428 | //#endif 429 | // 430 | //#if defined(COMPILER_HAS_SIMD_AVX512) 431 | // if (__builtin_cpu_supports("avx512f")) count_states_function_p = &count_states_AVX512; 432 | // else 433 | //#endif 434 | //#if defined(COMPILER_HAS_SIMD_X86) 435 | // if (__builtin_cpu_supports("avx2")) count_states_function_p = &count_states_AVX2; 436 | // else if (__builtin_cpu_supports("avx")) count_states_function_p = &count_states_AVX; 437 | // else if (__builtin_cpu_supports("sse2")) count_states_function_p = &count_states_SSE2; 438 | // else if (__builtin_cpu_supports("mmx")) count_states_function_p = &count_states_MMX; 439 | // else 440 | //#endif 441 | // count_states_function_p = &count_states_NOSIMD; 442 | count_states_function_p = &count_states_NOSIMD; 443 | // call the most optimized function for this CPU 444 | return (*count_states_function_p)(bitarray); 445 | } 446 | 447 | void bitarray_AND_dispatch(uint32_t *A, uint32_t *B) { 448 | //#if defined(COMPILER_HAS_SIMD_NEON) 449 | // if (arm_has_neon()) bitarray_AND_function_p = &bitarray_AND_NEON; 450 | // else 451 | //#endif 452 | // 453 | //#if defined(COMPILER_HAS_SIMD_AVX512) 454 | // if (__builtin_cpu_supports("avx512f")) bitarray_AND_function_p = &bitarray_AND_AVX512; 455 | // else 456 | //#endif 457 | //#if defined(COMPILER_HAS_SIMD_X86) 458 | // if (__builtin_cpu_supports("avx2")) bitarray_AND_function_p = &bitarray_AND_AVX2; 459 | // else if (__builtin_cpu_supports("avx")) bitarray_AND_function_p = &bitarray_AND_AVX; 460 | // else if (__builtin_cpu_supports("sse2")) bitarray_AND_function_p = &bitarray_AND_SSE2; 461 | // else if (__builtin_cpu_supports("mmx")) bitarray_AND_function_p = &bitarray_AND_MMX; 462 | // else 463 | //#endif 464 | // bitarray_AND_function_p = &bitarray_AND_NOSIMD; 465 | bitarray_AND_function_p = &bitarray_AND_NOSIMD; 466 | // call the most optimized function for this CPU 467 | (*bitarray_AND_function_p)(A, B); 468 | } 469 | 470 | void bitarray_low20_AND_dispatch(uint32_t *A, uint32_t *B) { 471 | //#if defined(COMPILER_HAS_SIMD_NEON) 472 | // if (arm_has_neon()) bitarray_low20_AND_function_p = &bitarray_low20_AND_NEON; 473 | // else 474 | //#endif 475 | // 476 | //#if defined(COMPILER_HAS_SIMD_AVX512) 477 | // if (__builtin_cpu_supports("avx512f")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX512; 478 | // else 479 | //#endif 480 | //#if defined(COMPILER_HAS_SIMD_X86) 481 | // if (__builtin_cpu_supports("avx2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX2; 482 | // else if (__builtin_cpu_supports("avx")) bitarray_low20_AND_function_p = &bitarray_low20_AND_AVX; 483 | // else if (__builtin_cpu_supports("sse2")) bitarray_low20_AND_function_p = &bitarray_low20_AND_SSE2; 484 | // else if (__builtin_cpu_supports("mmx")) bitarray_low20_AND_function_p = &bitarray_low20_AND_MMX; 485 | // else 486 | //#endif 487 | // bitarray_low20_AND_function_p = &bitarray_low20_AND_NOSIMD; 488 | bitarray_low20_AND_function_p = &bitarray_low20_AND_NOSIMD; 489 | // call the most optimized function for this CPU 490 | (*bitarray_low20_AND_function_p)(A, B); 491 | } 492 | 493 | uint32_t count_bitarray_AND_dispatch(uint32_t *A, uint32_t *B) { 494 | //#if defined(COMPILER_HAS_SIMD_NEON) 495 | // if (arm_has_neon()) count_bitarray_AND_function_p = &count_bitarray_AND_NEON; 496 | // else 497 | //#endif 498 | // 499 | //#if defined(COMPILER_HAS_SIMD_AVX512) 500 | // if (__builtin_cpu_supports("avx512f")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX512; 501 | // else 502 | //#endif 503 | //#if defined(COMPILER_HAS_SIMD_X86) 504 | // if (__builtin_cpu_supports("avx2")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX2; 505 | // else if (__builtin_cpu_supports("avx")) count_bitarray_AND_function_p = &count_bitarray_AND_AVX; 506 | // else if (__builtin_cpu_supports("sse2")) count_bitarray_AND_function_p = &count_bitarray_AND_SSE2; 507 | // else if (__builtin_cpu_supports("mmx")) count_bitarray_AND_function_p = &count_bitarray_AND_MMX; 508 | // else 509 | //#endif 510 | // count_bitarray_AND_function_p = &count_bitarray_AND_NOSIMD; 511 | count_bitarray_AND_function_p = &count_bitarray_AND_NOSIMD; 512 | // call the most optimized function for this CPU 513 | return (*count_bitarray_AND_function_p)(A, B); 514 | } 515 | 516 | uint32_t count_bitarray_low20_AND_dispatch(uint32_t *A, uint32_t *B) { 517 | //#if defined(COMPILER_HAS_SIMD_NEON) 518 | // if (arm_has_neon()) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_NEON; 519 | // else 520 | //#endif 521 | // 522 | //#if defined(COMPILER_HAS_SIMD_AVX512) 523 | // if (__builtin_cpu_supports("avx512f")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX512; 524 | // else 525 | //#endif 526 | //#if defined(COMPILER_HAS_SIMD_X86) 527 | // if (__builtin_cpu_supports("avx2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX2; 528 | // else if (__builtin_cpu_supports("avx")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_AVX; 529 | // else if (__builtin_cpu_supports("sse2")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_SSE2; 530 | // else if (__builtin_cpu_supports("mmx")) count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_MMX; 531 | // else 532 | //#endif 533 | // count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_NOSIMD; 534 | count_bitarray_low20_AND_function_p = &count_bitarray_low20_AND_NOSIMD; 535 | // call the most optimized function for this CPU 536 | return (*count_bitarray_low20_AND_function_p)(A, B); 537 | } 538 | 539 | void bitarray_AND4_dispatch(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { 540 | //#if defined(COMPILER_HAS_SIMD_NEON) 541 | // if (arm_has_neon()) bitarray_AND4_function_p = &bitarray_AND4_NEON; 542 | // else 543 | //#endif 544 | // 545 | //#if defined(COMPILER_HAS_SIMD_AVX512) 546 | // if (__builtin_cpu_supports("avx512f")) bitarray_AND4_function_p = &bitarray_AND4_AVX512; 547 | // else 548 | //#endif 549 | //#if defined(COMPILER_HAS_SIMD_X86) 550 | // if (__builtin_cpu_supports("avx2")) bitarray_AND4_function_p = &bitarray_AND4_AVX2; 551 | // else if (__builtin_cpu_supports("avx")) bitarray_AND4_function_p = &bitarray_AND4_AVX; 552 | // else if (__builtin_cpu_supports("sse2")) bitarray_AND4_function_p = &bitarray_AND4_SSE2; 553 | // else if (__builtin_cpu_supports("mmx")) bitarray_AND4_function_p = &bitarray_AND4_MMX; 554 | // else 555 | //#endif 556 | // bitarray_AND4_function_p = &bitarray_AND4_NOSIMD; 557 | bitarray_AND4_function_p = &bitarray_AND4_NOSIMD; 558 | // call the most optimized function for this CPU 559 | (*bitarray_AND4_function_p)(A, B, C, D); 560 | } 561 | 562 | void bitarray_OR_dispatch(uint32_t *A, uint32_t *B) { 563 | //#if defined(COMPILER_HAS_SIMD_NEON) 564 | // if (arm_has_neon()) bitarray_OR_function_p = &bitarray_OR_NEON; 565 | // else 566 | //#endif 567 | // 568 | //#if defined(COMPILER_HAS_SIMD_AVX512) 569 | // if (__builtin_cpu_supports("avx512f")) bitarray_OR_function_p = &bitarray_OR_AVX512; 570 | // else 571 | //#endif 572 | //#if defined(COMPILER_HAS_SIMD_X86) 573 | // if (__builtin_cpu_supports("avx2")) bitarray_OR_function_p = &bitarray_OR_AVX2; 574 | // else if (__builtin_cpu_supports("avx")) bitarray_OR_function_p = &bitarray_OR_AVX; 575 | // else if (__builtin_cpu_supports("sse2")) bitarray_OR_function_p = &bitarray_OR_SSE2; 576 | // else if (__builtin_cpu_supports("mmx")) bitarray_OR_function_p = &bitarray_OR_MMX; 577 | // else 578 | //#endif 579 | // bitarray_OR_function_p = &bitarray_OR_NOSIMD; 580 | bitarray_OR_function_p = &bitarray_OR_NOSIMD; 581 | // call the most optimized function for this CPU 582 | (*bitarray_OR_function_p)(A, B); 583 | } 584 | 585 | uint32_t count_bitarray_AND2_dispatch(uint32_t *A, uint32_t *B) { 586 | //#if defined(COMPILER_HAS_SIMD_NEON) 587 | // if (arm_has_neon()) count_bitarray_AND2_function_p = &count_bitarray_AND2_NEON; 588 | // else 589 | //#endif 590 | // 591 | //#if defined(COMPILER_HAS_SIMD_AVX512) 592 | // if (__builtin_cpu_supports("avx512f")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX512; 593 | // else 594 | //#endif 595 | //#if defined(COMPILER_HAS_SIMD_X86) 596 | // if (__builtin_cpu_supports("avx2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX2; 597 | // else if (__builtin_cpu_supports("avx")) count_bitarray_AND2_function_p = &count_bitarray_AND2_AVX; 598 | // else if (__builtin_cpu_supports("sse2")) count_bitarray_AND2_function_p = &count_bitarray_AND2_SSE2; 599 | // else if (__builtin_cpu_supports("mmx")) count_bitarray_AND2_function_p = &count_bitarray_AND2_MMX; 600 | // else 601 | //#endif 602 | // count_bitarray_AND2_function_p = &count_bitarray_AND2_NOSIMD; 603 | count_bitarray_AND2_function_p = &count_bitarray_AND2_NOSIMD; 604 | // call the most optimized function for this CPU 605 | return (*count_bitarray_AND2_function_p)(A, B); 606 | } 607 | 608 | uint32_t count_bitarray_AND3_dispatch(uint32_t *A, uint32_t *B, uint32_t *C) { 609 | //#if defined(COMPILER_HAS_SIMD_NEON) 610 | // if (arm_has_neon()) count_bitarray_AND3_function_p = &count_bitarray_AND3_NEON; 611 | // else 612 | //#endif 613 | // 614 | //#if defined(COMPILER_HAS_SIMD_AVX512) 615 | // if (__builtin_cpu_supports("avx512f")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX512; 616 | // else 617 | //#endif 618 | //#if defined(COMPILER_HAS_SIMD_X86) 619 | // if (__builtin_cpu_supports("avx2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX2; 620 | // else if (__builtin_cpu_supports("avx")) count_bitarray_AND3_function_p = &count_bitarray_AND3_AVX; 621 | // else if (__builtin_cpu_supports("sse2")) count_bitarray_AND3_function_p = &count_bitarray_AND3_SSE2; 622 | // else if (__builtin_cpu_supports("mmx")) count_bitarray_AND3_function_p = &count_bitarray_AND3_MMX; 623 | // else 624 | //#endif 625 | // count_bitarray_AND3_function_p = &count_bitarray_AND3_NOSIMD; 626 | count_bitarray_AND3_function_p = &count_bitarray_AND3_NOSIMD; 627 | // call the most optimized function for this CPU 628 | return (*count_bitarray_AND3_function_p)(A, B, C); 629 | } 630 | 631 | uint32_t count_bitarray_AND4_dispatch(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { 632 | //#if defined(COMPILER_HAS_SIMD_NEON) 633 | // if (arm_has_neon()) count_bitarray_AND4_function_p = &count_bitarray_AND4_NEON; 634 | // else 635 | //#endif 636 | // 637 | //#if defined(COMPILER_HAS_SIMD_AVX512) 638 | // if (__builtin_cpu_supports("avx512f")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX512; 639 | // else 640 | //#endif 641 | //#if defined(COMPILER_HAS_SIMD_X86) 642 | // if (__builtin_cpu_supports("avx2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX2; 643 | // else if (__builtin_cpu_supports("avx")) count_bitarray_AND4_function_p = &count_bitarray_AND4_AVX; 644 | // else if (__builtin_cpu_supports("sse2")) count_bitarray_AND4_function_p = &count_bitarray_AND4_SSE2; 645 | // else if (__builtin_cpu_supports("mmx")) count_bitarray_AND4_function_p = &count_bitarray_AND4_MMX; 646 | // else 647 | //#endif 648 | // count_bitarray_AND4_function_p = &count_bitarray_AND4_NOSIMD; 649 | count_bitarray_AND4_function_p = &count_bitarray_AND4_NOSIMD; 650 | // call the most optimized function for this CPU 651 | return (*count_bitarray_AND4_function_p)(A, B, C, D); 652 | } 653 | 654 | 655 | ///////////////////////////////////////////////77 656 | // Entries to dispatched function calls 657 | 658 | uint32_t *malloc_bitarray(uint32_t x) { 659 | return (*malloc_bitarray_function_p)(x); 660 | } 661 | 662 | void free_bitarray(uint32_t *x) { 663 | (*free_bitarray_function_p)(x); 664 | } 665 | 666 | uint32_t bitcount(uint32_t a) { 667 | return (*bitcount_function_p)(a); 668 | } 669 | 670 | uint32_t count_states(uint32_t *A) { 671 | return (*count_states_function_p)(A); 672 | } 673 | 674 | void bitarray_AND(uint32_t *A, uint32_t *B) { 675 | (*bitarray_AND_function_p)(A, B); 676 | } 677 | 678 | void bitarray_low20_AND(uint32_t *A, uint32_t *B) { 679 | (*bitarray_low20_AND_function_p)(A, B); 680 | } 681 | 682 | uint32_t count_bitarray_AND(uint32_t *A, uint32_t *B) { 683 | return (*count_bitarray_AND_function_p)(A, B); 684 | } 685 | 686 | uint32_t count_bitarray_low20_AND(uint32_t *A, uint32_t *B) { 687 | return (*count_bitarray_low20_AND_function_p)(A, B); 688 | } 689 | 690 | void bitarray_AND4(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { 691 | (*bitarray_AND4_function_p)(A, B, C, D); 692 | } 693 | 694 | void bitarray_OR(uint32_t *A, uint32_t *B) { 695 | (*bitarray_OR_function_p)(A, B); 696 | } 697 | 698 | uint32_t count_bitarray_AND2(uint32_t *A, uint32_t *B) { 699 | return (*count_bitarray_AND2_function_p)(A, B); 700 | } 701 | 702 | uint32_t count_bitarray_AND3(uint32_t *A, uint32_t *B, uint32_t *C) { 703 | return (*count_bitarray_AND3_function_p)(A, B, C); 704 | } 705 | 706 | uint32_t count_bitarray_AND4(uint32_t *A, uint32_t *B, uint32_t *C, uint32_t *D) { 707 | return (*count_bitarray_AND4_function_p)(A, B, C, D); 708 | } 709 | 710 | //#endif 711 | // 712 | -------------------------------------------------------------------------------- /hardnested/hardnested_bf_core.c: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Copyright (C) 2016, 2017 by piwi 3 | // 4 | // This code is licensed to you under the terms of the GNU GPL, version 2 or, 5 | // at your option, any later version. See the LICENSE.txt file for the text of 6 | // the license. 7 | //----------------------------------------------------------------------------- 8 | // Implements a card only attack based on crypto text (encrypted nonces 9 | // received during a nested authentication) only. Unlike other card only 10 | // attacks this doesn't rely on implementation errors but only on the 11 | // inherent weaknesses of the crypto1 cypher. Described in 12 | // Carlo Meijer, Roel Verdult, "Ciphertext-only Cryptanalysis on Hardened 13 | // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on 14 | // Computer and Communications Security, 2015 15 | //----------------------------------------------------------------------------- 16 | // 17 | // brute forcing is based on @aczids bitsliced brute forcer 18 | // https://github.com/aczid/crypto1_bs with some modifications. Mainly: 19 | // - don't rollback. Start with 2nd byte of nonce instead 20 | // - reuse results of filter subfunctions 21 | // - reuse results of previous nonces if some first bits are identical 22 | // 23 | //----------------------------------------------------------------------------- 24 | // aczid's Copyright notice: 25 | // 26 | // Bit-sliced Crypto-1 brute-forcing implementation 27 | // Builds on the data structures returned by CraptEV1 craptev1_get_space(nonces, threshold, uid) 28 | /* 29 | Copyright (c) 2015-2016 Aram Verstegen 30 | 31 | Permission is hereby granted, free of charge, to any person obtaining a copy 32 | of this software and associated documentation files (the "Software"), to deal 33 | in the Software without restriction, including without limitation the rights 34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 35 | copies of the Software, and to permit persons to whom the Software is 36 | furnished to do so, subject to the following conditions: 37 | 38 | The above copyright notice and this permission notice shall be included in 39 | all copies or substantial portions of the Software. 40 | 41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 47 | THE SOFTWARE. 48 | */ 49 | 50 | #include "hardnested_bf_core.h" 51 | 52 | #include 53 | #include 54 | #include 55 | #ifndef __APPLE__ 56 | #include 57 | #endif 58 | #include 59 | #include 60 | #include "../crapto1.h" 61 | #include "../parity.h" 62 | #include "../pm3/ui.h" // PrintAndLogEx 63 | //#include "common.h" 64 | 65 | // bitslice type 66 | // while AVX supports 256 bit vector floating point operations, we need integer operations for boolean logic 67 | // same for AVX2 and 512 bit vectors 68 | // using larger vectors works but seems to generate more register pressure 69 | //#if defined(__AVX512F__) 70 | //#define MAX_BITSLICES 512 71 | //#elif defined(__AVX2__) 72 | //#define MAX_BITSLICES 256 73 | //#elif defined(__AVX__) 74 | //#define MAX_BITSLICES 128 75 | //#elif defined(__SSE2__) 76 | //#define MAX_BITSLICES 128 77 | //#elif defined(__ARM_NEON) && !defined(NOSIMD_BUILD) 78 | //#define MAX_BITSLICES 128 79 | //#else // MMX or SSE or NOSIMD 80 | //#define MAX_BITSLICES 64 81 | //#endif 82 | #define MAX_BITSLICES 64 83 | 84 | #define VECTOR_SIZE (MAX_BITSLICES/8) 85 | 86 | #ifdef _MSC_VER 87 | #include 88 | #define atomic_add(num, val) (InterlockedExchangeAdd(num, val) + val) 89 | #pragma pack(push, VECTOR_SIZE) 90 | typedef uint32_t bitslice_value_t; 91 | #pragma pack(pop) 92 | #else 93 | #define atomic_add __sync_fetch_and_add 94 | typedef uint32_t __attribute__((aligned(VECTOR_SIZE))) __attribute__((vector_size(VECTOR_SIZE))) bitslice_value_t; 95 | #endif 96 | 97 | 98 | typedef union { 99 | bitslice_value_t value; 100 | uint64_t bytes64[MAX_BITSLICES / 64]; 101 | uint8_t bytes[MAX_BITSLICES / 8]; 102 | } bitslice_t; 103 | 104 | // filter function (f20) 105 | // sourced from ``Wirelessly Pickpocketing a Mifare Classic Card'' by Flavio Garcia, Peter van Rossum, Roel Verdult and Ronny Wichers Schreur 106 | #define f20a(a,b,c,d) (((a|b)^(a&d))^(c&((a^b)|d))) 107 | #define f20b(a,b,c,d) (((a&b)|c)^((a^b)&(c|d))) 108 | #define f20c(a,b,c,d,e) ((a|((b|e)&(d^e)))^((a^(b&d))&((c^d)|(b&e)))) 109 | 110 | // bit indexing 111 | #define get_bit(n, word) (((word) >> (n)) & 1) 112 | #define get_vector_bit(slice, value) get_bit((slice)&0x3f, value.bytes64[(slice)>>6]) 113 | 114 | // size of crypto-1 state 115 | #define STATE_SIZE 48 116 | // size of nonce to be decrypted 117 | #define KEYSTREAM_SIZE 24 118 | 119 | // this needs to be compiled several times for each instruction set. 120 | // For each instruction set, define a dedicated function name: 121 | //#if defined (__AVX512F__) 122 | //#define BITSLICE_TEST_NONCES bitslice_test_nonces_AVX512 123 | //#define CRACK_STATES_BITSLICED crack_states_bitsliced_AVX512 124 | //#elif defined (__AVX2__) 125 | //#define BITSLICE_TEST_NONCES bitslice_test_nonces_AVX2 126 | //#define CRACK_STATES_BITSLICED crack_states_bitsliced_AVX2 127 | //#elif defined (__AVX__) 128 | //#define BITSLICE_TEST_NONCES bitslice_test_nonces_AVX 129 | //#define CRACK_STATES_BITSLICED crack_states_bitsliced_AVX 130 | //#elif defined (__SSE2__) 131 | //#define BITSLICE_TEST_NONCES bitslice_test_nonces_SSE2 132 | //#define CRACK_STATES_BITSLICED crack_states_bitsliced_SSE2 133 | //#elif defined (__MMX__) 134 | //#define BITSLICE_TEST_NONCES bitslice_test_nonces_MMX 135 | //#define CRACK_STATES_BITSLICED crack_states_bitsliced_MMX 136 | //#elif defined (__ARM_NEON) && !defined(NOSIMD_BUILD) 137 | //#define BITSLICE_TEST_NONCES bitslice_test_nonces_NEON 138 | //#define CRACK_STATES_BITSLICED crack_states_bitsliced_NEON 139 | //#else 140 | //#define BITSLICE_TEST_NONCES bitslice_test_nonces_NOSIMD 141 | //#define CRACK_STATES_BITSLICED crack_states_bitsliced_NOSIMD 142 | //#endif 143 | 144 | #define CRACK_STATES_BITSLICED crack_states_bitsliced_NOSIMD 145 | #define BITSLICE_TEST_NONCES bitslice_test_nonces_NOSIMD 146 | // typedefs and declaration of functions: 147 | typedef uint64_t crack_states_bitsliced_t(uint32_t, uint8_t *, statelist_t *, uint32_t *, uint64_t *, uint32_t, const uint8_t *, noncelist_t *); 148 | crack_states_bitsliced_t crack_states_bitsliced_AVX512; 149 | crack_states_bitsliced_t crack_states_bitsliced_AVX2; 150 | crack_states_bitsliced_t crack_states_bitsliced_AVX; 151 | crack_states_bitsliced_t crack_states_bitsliced_SSE2; 152 | crack_states_bitsliced_t crack_states_bitsliced_MMX; 153 | crack_states_bitsliced_t crack_states_bitsliced_NEON; 154 | crack_states_bitsliced_t crack_states_bitsliced_NOSIMD; 155 | crack_states_bitsliced_t crack_states_bitsliced_dispatch; 156 | 157 | typedef void bitslice_test_nonces_t(uint32_t, const uint32_t *, const uint8_t *); 158 | bitslice_test_nonces_t bitslice_test_nonces_AVX512; 159 | bitslice_test_nonces_t bitslice_test_nonces_AVX2; 160 | bitslice_test_nonces_t bitslice_test_nonces_AVX; 161 | bitslice_test_nonces_t bitslice_test_nonces_SSE2; 162 | bitslice_test_nonces_t bitslice_test_nonces_MMX; 163 | bitslice_test_nonces_t bitslice_test_nonces_NEON; 164 | bitslice_test_nonces_t bitslice_test_nonces_NOSIMD; 165 | bitslice_test_nonces_t bitslice_test_nonces_dispatch; 166 | 167 | #if defined (_WIN32) 168 | #define malloc_bitslice(x) __builtin_assume_aligned(_aligned_malloc((x), MAX_BITSLICES / 8), MAX_BITSLICES / 8) 169 | #define free_bitslice(x) _aligned_free(x) 170 | #elif defined (__APPLE__) 171 | static void *malloc_bitslice(size_t x) { 172 | char *allocated_memory; 173 | if (posix_memalign((void **)&allocated_memory, MAX_BITSLICES / 8, x)) { 174 | return NULL; 175 | } else { 176 | return __builtin_assume_aligned(allocated_memory, MAX_BITSLICES / 8); 177 | } 178 | } 179 | #define free_bitslice(x) free(x) 180 | #else 181 | //#define malloc_bitslice(x) memalign(MAX_BITSLICES / 8, (x)) 182 | #define malloc_bitslice(x) __builtin_assume_aligned(memalign(MAX_BITSLICES / 8, (x)), MAX_BITSLICES / 8); 183 | #define free_bitslice(x) free(x) 184 | #endif 185 | 186 | typedef enum { 187 | EVEN_STATE = 0, 188 | ODD_STATE = 1 189 | } odd_even_t; 190 | 191 | 192 | // arrays of bitsliced states with identical values in all slices 193 | static bitslice_t bitsliced_encrypted_nonces[256][KEYSTREAM_SIZE]; 194 | static bitslice_t bitsliced_encrypted_parity_bits[256][4]; 195 | // 1 and 0 vectors 196 | static bitslice_t bs_ones; 197 | static bitslice_t bs_zeroes; 198 | 199 | 200 | void BITSLICE_TEST_NONCES(uint32_t nonces_to_bruteforce, const uint32_t *bf_test_nonce, const uint8_t *bf_test_nonce_par) { 201 | 202 | // initialize 1 and 0 vectors 203 | memset(bs_ones.bytes, 0xff, VECTOR_SIZE); 204 | memset(bs_zeroes.bytes, 0x00, VECTOR_SIZE); 205 | 206 | // bitslice nonces' 2nd to 4th byte 207 | for (uint32_t i = 0; i < nonces_to_bruteforce; i++) { 208 | for (uint32_t bit_idx = 0; bit_idx < KEYSTREAM_SIZE; bit_idx++) { 209 | bool bit = get_bit(KEYSTREAM_SIZE - 1 - bit_idx, BSWAP_32(bf_test_nonce[i] << 8)); 210 | if (bit) { 211 | bitsliced_encrypted_nonces[i][bit_idx].value = bs_ones.value; 212 | } else { 213 | bitsliced_encrypted_nonces[i][bit_idx].value = bs_zeroes.value; 214 | } 215 | } 216 | } 217 | // bitslice nonces' parity (4 bits) 218 | for (uint32_t i = 0; i < nonces_to_bruteforce; i++) { 219 | for (uint32_t bit_idx = 0; bit_idx < 4; bit_idx++) { 220 | bool bit = get_bit(4 - 1 - bit_idx, bf_test_nonce_par[i]); 221 | if (bit) { 222 | bitsliced_encrypted_parity_bits[i][bit_idx].value = bs_ones.value; 223 | } else { 224 | bitsliced_encrypted_parity_bits[i][bit_idx].value = bs_zeroes.value; 225 | } 226 | } 227 | } 228 | 229 | } 230 | 231 | 232 | uint64_t CRACK_STATES_BITSLICED(uint32_t cuid, uint8_t *best_first_bytes, statelist_t *p, uint32_t *keys_found, 233 | uint64_t *num_keys_tested, uint32_t nonces_to_bruteforce, 234 | const uint8_t *bf_test_nonce_2nd_byte, noncelist_t *nonces) { 235 | 236 | // Unlike aczid's implementation this doesn't roll back at all when performing bitsliced bruteforce. 237 | // We know that the best first byte is already shifted in. Testing with the remaining three bytes of 238 | // the nonces is sufficient to eliminate most of them. The small rest is tested with a simple unsliced 239 | // brute forcing (including roll back). 240 | 241 | bitslice_t states[KEYSTREAM_SIZE + STATE_SIZE]; 242 | bitslice_t *restrict state_p; 243 | uint64_t key = -1; 244 | uint64_t bucket_states_tested = 0; 245 | uint32_t bucket_size[16384]; 246 | uint32_t bitsliced_blocks = 0; 247 | uint32_t const *restrict p_even_end = p->states[EVEN_STATE] + p->len[EVEN_STATE]; 248 | #if defined (DEBUG_BRUTE_FORCE) 249 | uint32_t elimination_step = 0; 250 | #define MAX_ELIMINATION_STEP 32 251 | uint64_t keys_eliminated[MAX_ELIMINATION_STEP] = {0}; 252 | #endif 253 | #ifdef DEBUG_KEY_ELIMINATION 254 | bool bucket_contains_test_key[(p->len[EVEN_STATE] - 1) / MAX_BITSLICES + 1]; 255 | #endif 256 | 257 | // constant ones/zeroes 258 | // bitslice_t bs_ones; 259 | memset(bs_ones.bytes, 0xff, VECTOR_SIZE); 260 | // bitslice_t bs_zeroes; 261 | memset(bs_zeroes.bytes, 0x00, VECTOR_SIZE); 262 | 263 | // bitslice all the even states 264 | bitslice_t **restrict bitsliced_even_states = (bitslice_t **)calloc(1, ((p->len[EVEN_STATE] - 1) / MAX_BITSLICES + 1) * sizeof(bitslice_t *)); 265 | if (bitsliced_even_states == NULL) { 266 | PrintAndLogEx(WARNING, "Out of memory error in brute_force. Aborting..."); 267 | exit(4); 268 | } 269 | bitslice_value_t *restrict bitsliced_even_feedback = malloc_bitslice(((p->len[EVEN_STATE] - 1) / MAX_BITSLICES + 1) * sizeof(bitslice_value_t)); 270 | if (bitsliced_even_feedback == NULL) { 271 | PrintAndLogEx(WARNING, "Out of memory error in brute_force. Aborting..."); 272 | exit(4); 273 | } 274 | for (uint32_t *restrict p_even = p->states[EVEN_STATE]; p_even < p_even_end; p_even += MAX_BITSLICES) { 275 | bitslice_t *restrict lstate_p = malloc_bitslice(STATE_SIZE / 2 * sizeof(bitslice_t)); 276 | if (lstate_p == NULL) { 277 | PrintAndLogEx(WARNING, "Out of memory error in brute_force. Aborting... \n"); 278 | exit(4); 279 | } 280 | memset(lstate_p, 0x00, STATE_SIZE / 2 * sizeof(bitslice_t)); // zero even bits 281 | // bitslice even half-states 282 | const uint32_t max_slices = (p_even_end - p_even) < MAX_BITSLICES ? p_even_end - p_even : MAX_BITSLICES; 283 | bucket_size[bitsliced_blocks] = max_slices; 284 | #ifdef DEBUG_KEY_ELIMINATION 285 | bucket_contains_test_key[bitsliced_blocks] = false; 286 | #endif 287 | uint32_t slice_idx; 288 | for (slice_idx = 0; slice_idx < max_slices; ++slice_idx) { 289 | uint32_t e = *(p_even + slice_idx); 290 | #ifdef DEBUG_KEY_ELIMINATION 291 | if (known_target_key != -1 && e == test_state[EVEN_STATE]) { 292 | bucket_contains_test_key[bitsliced_blocks] = true; 293 | // PrintAndLogEx(INFO, "bucket %d contains test key even state", bitsliced_blocks); 294 | // PrintAndLogEx(INFO, "in slice %d", slice_idx); 295 | } 296 | #endif 297 | for (uint32_t bit_idx = 0; bit_idx < STATE_SIZE / 2; bit_idx++, e >>= 1) { 298 | // set even bits 299 | if (e & 1) { 300 | lstate_p[bit_idx].bytes64[slice_idx >> 6] |= 1ull << (slice_idx & 0x3f); 301 | } 302 | } 303 | } 304 | // padding with last even state 305 | for (; slice_idx < MAX_BITSLICES; ++slice_idx) { 306 | uint32_t e = *(p_even_end - 1); 307 | for (uint32_t bit_idx = 0; bit_idx < STATE_SIZE / 2; bit_idx++, e >>= 1) { 308 | // set even bits 309 | if (e & 1) { 310 | lstate_p[bit_idx].bytes64[slice_idx >> 6] |= 1ull << (slice_idx & 0x3f); 311 | } 312 | } 313 | } 314 | bitsliced_even_states[bitsliced_blocks] = lstate_p; 315 | // bitsliced_even_feedback[bitsliced_blocks] = bs_ones; 316 | bitsliced_even_feedback[bitsliced_blocks] = lstate_p[(47 - 0) / 2].value ^ 317 | lstate_p[(47 - 10) / 2].value ^ lstate_p[(47 - 12) / 2].value ^ lstate_p[(47 - 14) / 2].value ^ 318 | lstate_p[(47 - 24) / 2].value ^ lstate_p[(47 - 42) / 2].value; 319 | bitsliced_blocks++; 320 | } 321 | // bitslice every odd state to every block of even states 322 | for (uint32_t const *restrict p_odd = p->states[ODD_STATE]; p_odd < p->states[ODD_STATE] + p->len[ODD_STATE]; ++p_odd) { 323 | // early abort 324 | if (*keys_found) { 325 | goto out; 326 | } 327 | 328 | // set odd state bits and pre-compute first keystream bit vector. This is the same for all blocks of even states 329 | 330 | state_p = &states[KEYSTREAM_SIZE]; 331 | uint32_t o = *p_odd; 332 | 333 | // pre-compute the odd feedback bit 334 | bool odd_feedback_bit = evenparity32(o & 0x29ce5c); 335 | const bitslice_value_t odd_feedback = odd_feedback_bit ? bs_ones.value : bs_zeroes.value; 336 | 337 | // set odd state bits 338 | for (uint32_t state_idx = 0; state_idx < STATE_SIZE; o >>= 1, state_idx += 2) { 339 | if (o & 1) { 340 | state_p[state_idx] = bs_ones; 341 | } else { 342 | state_p[state_idx] = bs_zeroes; 343 | } 344 | } 345 | 346 | bitslice_value_t crypto1_bs_f20b_2[16]; 347 | bitslice_value_t crypto1_bs_f20b_3[8]; 348 | 349 | crypto1_bs_f20b_2[0] = f20b(state_p[47 - 25].value, state_p[47 - 27].value, state_p[47 - 29].value, state_p[47 - 31].value); 350 | crypto1_bs_f20b_3[0] = f20b(state_p[47 - 41].value, state_p[47 - 43].value, state_p[47 - 45].value, state_p[47 - 47].value); 351 | 352 | bitslice_value_t ksb[8]; 353 | ksb[0] = f20c(f20a(state_p[47 - 9].value, state_p[47 - 11].value, state_p[47 - 13].value, state_p[47 - 15].value), 354 | f20b(state_p[47 - 17].value, state_p[47 - 19].value, state_p[47 - 21].value, state_p[47 - 23].value), 355 | crypto1_bs_f20b_2[0], 356 | f20a(state_p[47 - 33].value, state_p[47 - 35].value, state_p[47 - 37].value, state_p[47 - 39].value), 357 | crypto1_bs_f20b_3[0]); 358 | 359 | uint32_t *restrict p_even = p->states[EVEN_STATE]; 360 | for (uint32_t block_idx = 0; block_idx < bitsliced_blocks; ++block_idx, p_even += MAX_BITSLICES) { 361 | 362 | #ifdef DEBUG_KEY_ELIMINATION 363 | // if (known_target_key != -1 && bucket_contains_test_key[block_idx] && *p_odd == test_state[ODD_STATE]) { 364 | // PrintAndLogEx(INFO, "Now testing known target key."); 365 | // PrintAndLogEx(INFO, "block_idx = %d/%d", block_idx, bitsliced_blocks); 366 | // } 367 | #endif 368 | // add the even state bits 369 | const bitslice_t *restrict bitsliced_even_state = bitsliced_even_states[block_idx]; 370 | for (uint32_t state_idx = 1; state_idx < STATE_SIZE; state_idx += 2) { 371 | state_p[state_idx] = bitsliced_even_state[state_idx / 2]; 372 | } 373 | 374 | // pre-compute first feedback bit vector. This is the same for all nonces 375 | bitslice_value_t fbb[8]; 376 | fbb[0] = odd_feedback ^ bitsliced_even_feedback[block_idx]; 377 | 378 | // vector to contain test results (1 = passed, 0 = failed) 379 | bitslice_t results = bs_ones; 380 | 381 | // parity_bits 382 | bitslice_value_t par[8]; 383 | par[0] = bs_zeroes.value; 384 | uint32_t next_common_bits = 0; 385 | 386 | for (uint32_t tests = 0; tests < nonces_to_bruteforce; ++tests) { 387 | // common bits with preceding test nonce 388 | uint32_t common_bits = next_common_bits; //tests ? trailing_zeros(bf_test_nonce_2nd_byte[tests] ^ bf_test_nonce_2nd_byte[tests-1]) : 0; 389 | next_common_bits = tests < nonces_to_bruteforce - 1 ? trailing_zeros(bf_test_nonce_2nd_byte[tests] ^ bf_test_nonce_2nd_byte[tests + 1]) : 0; 390 | uint32_t parity_bit_idx = 1; // start checking with the parity of second nonce byte 391 | bitslice_value_t fb_bits = fbb[common_bits]; // start with precomputed feedback bits from previous nonce 392 | bitslice_value_t ks_bits = ksb[common_bits]; // dito for first keystream bits 393 | bitslice_value_t parity_bit_vector = par[common_bits]; // dito for first parity vector 394 | // bitslice_value_t fb_bits = fbb[0]; // start with precomputed feedback bits from previous nonce 395 | // bitslice_value_t ks_bits = ksb[0]; // dito for first keystream bits 396 | // bitslice_value_t parity_bit_vector = par[0]; // dito for first parity vector 397 | state_p -= common_bits; // and reuse the already calculated state bits 398 | // highest bit is transmitted/received first. We start with Bit 23 (highest bit of second nonce byte), 399 | // or the highest bit which differs from the previous nonce 400 | for (int32_t ks_idx = KEYSTREAM_SIZE - 1 - common_bits; ks_idx >= 0; --ks_idx) { 401 | 402 | // decrypt nonce bits 403 | const bitslice_value_t encrypted_nonce_bit_vector = bitsliced_encrypted_nonces[tests][ks_idx].value; 404 | const bitslice_value_t decrypted_nonce_bit_vector = encrypted_nonce_bit_vector ^ ks_bits; 405 | 406 | // compute real parity bits on the fly 407 | parity_bit_vector ^= decrypted_nonce_bit_vector; 408 | 409 | // update state 410 | state_p--; 411 | state_p[0].value = fb_bits ^ decrypted_nonce_bit_vector; 412 | 413 | // update crypto1 subfunctions 414 | bitslice_value_t f20a_1, f20b_1, f20b_2, f20a_2, f20b_3; 415 | f20a_2 = f20a(state_p[47 - 33].value, state_p[47 - 35].value, state_p[47 - 37].value, state_p[47 - 39].value); 416 | f20b_3 = f20b(state_p[47 - 41].value, state_p[47 - 43].value, state_p[47 - 45].value, state_p[47 - 47].value); 417 | if (ks_idx > KEYSTREAM_SIZE - 8) { 418 | f20a_1 = f20a(state_p[47 - 9].value, state_p[47 - 11].value, state_p[47 - 13].value, state_p[47 - 15].value); 419 | f20b_1 = f20b(state_p[47 - 17].value, state_p[47 - 19].value, state_p[47 - 21].value, state_p[47 - 23].value); 420 | f20b_2 = f20b(state_p[47 - 25].value, state_p[47 - 27].value, state_p[47 - 29].value, state_p[47 - 31].value); 421 | crypto1_bs_f20b_2[KEYSTREAM_SIZE - ks_idx] = f20b_2; 422 | crypto1_bs_f20b_3[KEYSTREAM_SIZE - ks_idx] = f20b_3; 423 | } else if (ks_idx > KEYSTREAM_SIZE - 16) { 424 | f20a_1 = f20a(state_p[47 - 9].value, state_p[47 - 11].value, state_p[47 - 13].value, state_p[47 - 15].value); 425 | f20b_1 = crypto1_bs_f20b_2[KEYSTREAM_SIZE - ks_idx - 8]; 426 | f20b_2 = f20b(state_p[47 - 25].value, state_p[47 - 27].value, state_p[47 - 29].value, state_p[47 - 31].value); 427 | crypto1_bs_f20b_2[KEYSTREAM_SIZE - ks_idx] = f20b_2; 428 | } else if (ks_idx > KEYSTREAM_SIZE - 24) { 429 | f20a_1 = f20a(state_p[47 - 9].value, state_p[47 - 11].value, state_p[47 - 13].value, state_p[47 - 15].value); 430 | f20b_1 = crypto1_bs_f20b_2[KEYSTREAM_SIZE - ks_idx - 8]; 431 | f20b_2 = crypto1_bs_f20b_3[KEYSTREAM_SIZE - ks_idx - 16]; 432 | } else { 433 | f20a_1 = f20a(state_p[47 - 9].value, state_p[47 - 11].value, state_p[47 - 13].value, state_p[47 - 15].value); 434 | f20b_1 = f20b(state_p[47 - 17].value, state_p[47 - 19].value, state_p[47 - 21].value, state_p[47 - 23].value); 435 | f20b_2 = f20b(state_p[47 - 25].value, state_p[47 - 27].value, state_p[47 - 29].value, state_p[47 - 31].value); 436 | } 437 | // update keystream bit 438 | ks_bits = f20c(f20a_1, f20b_1, f20b_2, f20a_2, f20b_3); 439 | 440 | // for each completed byte: 441 | if ((ks_idx & 0x07) == 0) { 442 | // get encrypted parity bits 443 | const bitslice_value_t encrypted_parity_bit_vector = bitsliced_encrypted_parity_bits[tests][parity_bit_idx++].value; 444 | 445 | // decrypt parity bits 446 | const bitslice_value_t decrypted_parity_bit_vector = encrypted_parity_bit_vector ^ ks_bits; 447 | 448 | // compare actual parity bits with decrypted parity bits and take count in results vector 449 | results.value &= ~parity_bit_vector ^ decrypted_parity_bit_vector; 450 | 451 | // make sure we still have a match in our set 452 | // if(memcmp(&results, &bs_zeroes, sizeof(bitslice_t)) == 0){ 453 | 454 | // this is much faster on my gcc, because somehow a memcmp needlessly spills/fills all the xmm registers to/from the stack - ??? 455 | // the short-circuiting also helps 456 | if (results.bytes64[0] == 0 457 | #if MAX_BITSLICES > 64 458 | && results.bytes64[1] == 0 459 | #endif 460 | #if MAX_BITSLICES > 128 461 | && results.bytes64[2] == 0 462 | && results.bytes64[3] == 0 463 | #endif 464 | #if MAX_BITSLICES > 256 465 | && results.bytes64[4] == 0 466 | && results.bytes64[5] == 0 467 | && results.bytes64[6] == 0 468 | && results.bytes64[7] == 0 469 | #endif 470 | ) { 471 | #if defined (DEBUG_BRUTE_FORCE) 472 | if (elimination_step < MAX_ELIMINATION_STEP) { 473 | keys_eliminated[elimination_step] += MAX_BITSLICES; 474 | } 475 | #endif 476 | #ifdef DEBUG_KEY_ELIMINATION 477 | if (known_target_key != -1 && bucket_contains_test_key[block_idx] && *p_odd == test_state[ODD_STATE]) { 478 | PrintAndLogEx(INFO, "Known target key eliminated in brute_force."); 479 | PrintAndLogEx(INFO, "block_idx = %d/%d, nonce = %d/%d", block_idx, bitsliced_blocks, tests, nonces_to_bruteforce); 480 | } 481 | #endif 482 | goto stop_tests; 483 | } 484 | // prepare for next nonce byte 485 | #if defined (DEBUG_BRUTE_FORCE) 486 | elimination_step++; 487 | #endif 488 | parity_bit_vector = bs_zeroes.value; 489 | } 490 | // update feedback bit vector 491 | if (ks_idx != 0) { 492 | fb_bits = 493 | (state_p[47 - 0].value ^ state_p[47 - 5].value ^ state_p[47 - 9].value ^ 494 | state_p[47 - 10].value ^ state_p[47 - 12].value ^ state_p[47 - 14].value ^ 495 | state_p[47 - 15].value ^ state_p[47 - 17].value ^ state_p[47 - 19].value ^ 496 | state_p[47 - 24].value ^ state_p[47 - 25].value ^ state_p[47 - 27].value ^ 497 | state_p[47 - 29].value ^ state_p[47 - 35].value ^ state_p[47 - 39].value ^ 498 | state_p[47 - 41].value ^ state_p[47 - 42].value ^ state_p[47 - 43].value); 499 | } 500 | // remember feedback and keystream vectors for later use 501 | uint8_t bit = KEYSTREAM_SIZE - ks_idx; 502 | if (bit <= MIN(next_common_bits, 7)) { // if needed and not yet stored 503 | fbb[bit] = fb_bits; 504 | ksb[bit] = ks_bits; 505 | par[bit] = parity_bit_vector; 506 | } 507 | } 508 | // prepare for next nonce. Revert to initial state 509 | state_p = &states[KEYSTREAM_SIZE]; 510 | } 511 | 512 | // all nonce tests were successful: we've found a possible key in this block! 513 | uint32_t *p_even_test = p_even; 514 | for (uint32_t results_word = 0; results_word < MAX_BITSLICES / 64; ++results_word) { 515 | uint64_t results64 = results.bytes64[results_word]; 516 | for (uint32_t results_bit = 0; results_bit < 64; results_bit++) { 517 | if (results64 & 0x01) { 518 | if (verify_key(cuid, nonces, best_first_bytes, *p_odd, *p_even_test)) { 519 | struct Crypto1State pcs; 520 | pcs.odd = *p_odd; 521 | pcs.even = *p_even_test; 522 | lfsr_rollback_byte(&pcs, (cuid >> 24) ^ best_first_bytes[0], true); 523 | crypto1_get_lfsr(&pcs, &key); 524 | bucket_states_tested += 64 * results_word + results_bit; 525 | goto out; 526 | } 527 | #ifdef DEBUG_KEY_ELIMINATION 528 | if (known_target_key != -1 && *p_even_test == test_state[EVEN_STATE] && *p_odd == test_state[ODD_STATE]) { 529 | PrintAndLogEx(INFO, "Known target key eliminated in brute_force verification."); 530 | PrintAndLogEx(INFO, "block_idx = %d/%d", block_idx, bitsliced_blocks); 531 | } 532 | #endif 533 | } 534 | #ifdef DEBUG_KEY_ELIMINATION 535 | if (known_target_key != -1 && *p_even_test == test_state[EVEN_STATE] && *p_odd == test_state[ODD_STATE]) { 536 | PrintAndLogEx(INFO, "Known target key eliminated in brute_force (results_bit == 0)."); 537 | PrintAndLogEx(INFO, "block_idx = %d/%d", block_idx, bitsliced_blocks); 538 | } 539 | #endif 540 | results64 >>= 1; 541 | p_even_test++; 542 | if (p_even_test == p_even_end) { 543 | goto stop_tests; 544 | } 545 | } 546 | } 547 | stop_tests: 548 | #if defined (DEBUG_BRUTE_FORCE) 549 | elimination_step = 0; 550 | #endif 551 | bucket_states_tested += bucket_size[block_idx]; 552 | // prepare to set new states 553 | state_p = &states[KEYSTREAM_SIZE]; 554 | } 555 | } 556 | out: 557 | for (uint32_t block_idx = 0; block_idx < bitsliced_blocks; ++block_idx) { 558 | free_bitslice(bitsliced_even_states[block_idx]); 559 | } 560 | free(bitsliced_even_states); 561 | free_bitslice(bitsliced_even_feedback); 562 | atomic_add(num_keys_tested, bucket_states_tested); 563 | 564 | #if defined (DEBUG_BRUTE_FORCE) 565 | for (uint32_t i = 0; i < MAX_ELIMINATION_STEP; i++) { 566 | PrintAndLogEx(INFO, "Eliminated after %2u test_bytes: %5.2f%%", i + 1, (float)keys_eliminated[i] / bucket_states_tested * 100); 567 | } 568 | #endif 569 | return key; 570 | } 571 | 572 | 573 | 574 | //#ifdef NOSIMD_BUILD 575 | 576 | // pointers to functions: 577 | crack_states_bitsliced_t *crack_states_bitsliced_function_p = &crack_states_bitsliced_dispatch; 578 | bitslice_test_nonces_t *bitslice_test_nonces_function_p = &bitslice_test_nonces_dispatch; 579 | 580 | static SIMDExecInstr intSIMDInstr = SIMD_AUTO; 581 | 582 | void SetSIMDInstr(SIMDExecInstr instr) { 583 | intSIMDInstr = instr; 584 | 585 | crack_states_bitsliced_function_p = &crack_states_bitsliced_dispatch; 586 | bitslice_test_nonces_function_p = &bitslice_test_nonces_dispatch; 587 | } 588 | 589 | static SIMDExecInstr GetSIMDInstr(void) { 590 | SIMDExecInstr instr; 591 | 592 | #if defined(COMPILER_HAS_SIMD_X86) 593 | __builtin_cpu_init(); 594 | #endif 595 | 596 | #if defined(COMPILER_HAS_SIMD_AVX512) 597 | if (__builtin_cpu_supports("avx512f")) 598 | instr = SIMD_AVX512; 599 | else 600 | #endif 601 | #if defined(COMPILER_HAS_SIMD_X86) 602 | if (__builtin_cpu_supports("avx2")) 603 | instr = SIMD_AVX2; 604 | else if (__builtin_cpu_supports("avx")) 605 | instr = SIMD_AVX; 606 | else if (__builtin_cpu_supports("sse2")) 607 | instr = SIMD_SSE2; 608 | else if (__builtin_cpu_supports("mmx")) 609 | instr = SIMD_MMX; 610 | else 611 | #endif 612 | #if defined(COMPILER_HAS_SIMD_NEON) 613 | if (arm_has_neon()) 614 | instr = SIMD_NEON; 615 | else 616 | #endif 617 | instr = SIMD_NONE; 618 | 619 | return instr; 620 | } 621 | 622 | SIMDExecInstr GetSIMDInstrAuto(void) { 623 | SIMDExecInstr instr = intSIMDInstr; 624 | if (instr == SIMD_AUTO) 625 | return GetSIMDInstr(); 626 | 627 | return instr; 628 | } 629 | 630 | // determine the available instruction set at runtime and call the correct function 631 | uint64_t crack_states_bitsliced_dispatch(uint32_t cuid, uint8_t *best_first_bytes, statelist_t *p, 632 | uint32_t *keys_found, uint64_t *num_keys_tested, 633 | uint32_t nonces_to_bruteforce, const uint8_t *bf_test_nonce_2nd_byte, 634 | noncelist_t *nonces) { 635 | // switch (GetSIMDInstrAuto()) { 636 | //#if defined(COMPILER_HAS_SIMD_AVX512) 637 | // case SIMD_AVX512: 638 | // crack_states_bitsliced_function_p = &crack_states_bitsliced_AVX512; 639 | // break; 640 | //#endif 641 | //#if defined(COMPILER_HAS_SIMD_X86) 642 | // case SIMD_AVX2: 643 | // crack_states_bitsliced_function_p = &crack_states_bitsliced_AVX2; 644 | // break; 645 | // case SIMD_AVX: 646 | // crack_states_bitsliced_function_p = &crack_states_bitsliced_AVX; 647 | // break; 648 | // case SIMD_SSE2: 649 | // crack_states_bitsliced_function_p = &crack_states_bitsliced_SSE2; 650 | // break; 651 | // case SIMD_MMX: 652 | // crack_states_bitsliced_function_p = &crack_states_bitsliced_MMX; 653 | // break; 654 | //#endif 655 | //#if defined(COMPILER_HAS_SIMD_NEON) 656 | // case SIMD_NEON: 657 | // crack_states_bitsliced_function_p = &crack_states_bitsliced_NEON; 658 | // break; 659 | //#endif 660 | // case SIMD_AUTO: 661 | // case SIMD_NONE: 662 | // crack_states_bitsliced_function_p = &crack_states_bitsliced_NOSIMD; 663 | // break; 664 | // } 665 | crack_states_bitsliced_function_p = &crack_states_bitsliced_NOSIMD; 666 | // call the most optimized function for this CPU 667 | return (*crack_states_bitsliced_function_p)(cuid, best_first_bytes, p, keys_found, num_keys_tested, nonces_to_bruteforce, bf_test_nonce_2nd_byte, nonces); 668 | } 669 | 670 | void bitslice_test_nonces_dispatch(uint32_t nonces_to_bruteforce, const uint32_t *bf_test_nonce, const uint8_t *bf_test_nonce_par) { 671 | // switch (GetSIMDInstrAuto()) { 672 | //#if defined(COMPILER_HAS_SIMD_AVX512) 673 | // case SIMD_AVX512: 674 | // bitslice_test_nonces_function_p = &bitslice_test_nonces_AVX512; 675 | // break; 676 | //#endif 677 | //#if defined(COMPILER_HAS_SIMD_X86) 678 | // case SIMD_AVX2: 679 | // bitslice_test_nonces_function_p = &bitslice_test_nonces_AVX2; 680 | // break; 681 | // case SIMD_AVX: 682 | // bitslice_test_nonces_function_p = &bitslice_test_nonces_AVX; 683 | // break; 684 | // case SIMD_SSE2: 685 | // bitslice_test_nonces_function_p = &bitslice_test_nonces_SSE2; 686 | // break; 687 | // case SIMD_MMX: 688 | // bitslice_test_nonces_function_p = &bitslice_test_nonces_MMX; 689 | // break; 690 | //#endif 691 | //#if defined(COMPILER_HAS_SIMD_NEON) 692 | // case SIMD_NEON: 693 | // bitslice_test_nonces_function_p = &bitslice_test_nonces_NEON; 694 | // break; 695 | //#endif 696 | // case SIMD_AUTO: 697 | // case SIMD_NONE: 698 | // bitslice_test_nonces_function_p = &bitslice_test_nonces_NOSIMD; 699 | // break; 700 | // } 701 | bitslice_test_nonces_function_p = &bitslice_test_nonces_NOSIMD; 702 | // call the most optimized function for this CPU 703 | (*bitslice_test_nonces_function_p)(nonces_to_bruteforce, bf_test_nonce, bf_test_nonce_par); 704 | } 705 | 706 | // Entries to dispatched function calls 707 | uint64_t crack_states_bitsliced(uint32_t cuid, uint8_t *best_first_bytes, statelist_t *p, uint32_t *keys_found, uint64_t *num_keys_tested, uint32_t nonces_to_bruteforce, uint8_t *bf_test_nonce_2nd_byte, noncelist_t *nonces) { 708 | return (*crack_states_bitsliced_function_p)(cuid, best_first_bytes, p, keys_found, num_keys_tested, nonces_to_bruteforce, bf_test_nonce_2nd_byte, nonces); 709 | } 710 | 711 | void bitslice_test_nonces(uint32_t nonces_to_bruteforce, uint32_t *bf_test_nonce, uint8_t *bf_test_nonce_par) { 712 | (*bitslice_test_nonces_function_p)(nonces_to_bruteforce, bf_test_nonce, bf_test_nonce_par); 713 | } 714 | 715 | //#endif 716 | --------------------------------------------------------------------------------