diff --git a/docs/changes.txt b/docs/changes.txt index b50987305..6654225aa 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -21,6 +21,7 @@ - OpenCL kernels: Removed the use of 'volatile' in inline assembly instructions where it is not needed - OpenCL kernels: Switched array pointer types in function declarations in order to be compatible with OpenCL 2.0 - SIP cracking: Increased the nonce field to allow a salt of 1024 bytes +- TrueCrypt/VeraCrypt cracking: Do an entropy check on the TC/VC header on start ## ## Bugs diff --git a/include/interface.h b/include/interface.h index 521768cc7..df8dcbfd0 100644 --- a/include/interface.h +++ b/include/interface.h @@ -19,6 +19,12 @@ static const char LM_ZERO_HASH[] = "aad3b435b51404ee"; static const char LM_MASKED_PLAIN[] = "[notfound]"; +/** + * entropy check (truecrypt, veracrypt, ...) + */ + +static const float MIN_SUFFICIENT_ENTROPY_FILE = 7.0f; + /** * algo specific */ diff --git a/include/shared.h b/include/shared.h index c9dd5cbb5..541a50522 100644 --- a/include/shared.h +++ b/include/shared.h @@ -13,6 +13,7 @@ #include #include #include +#include bool overflow_check_u32_add (const u32 a, const u32 b); bool overflow_check_u32_mul (const u32 a, const u32 b); @@ -70,4 +71,7 @@ u64 round_up_multiple_64 (const u64 v, const u64 m); void hc_strncat (u8 *dst, u8 *src, const size_t n); +int count_char (const u8 *buf, const int len, const u8 c); +float get_entropy (const u8 *buf, const int len); + #endif // _SHARED_H diff --git a/include/types.h b/include/types.h index f84ccc38d..ad6783c1e 100644 --- a/include/types.h +++ b/include/types.h @@ -448,43 +448,44 @@ typedef enum outfile_fmt typedef enum parser_rc { - PARSER_OK = 0, - PARSER_COMMENT = -1, - PARSER_GLOBAL_ZERO = -2, - PARSER_GLOBAL_LENGTH = -3, - PARSER_HASH_LENGTH = -4, - PARSER_HASH_VALUE = -5, - PARSER_SALT_LENGTH = -6, - PARSER_SALT_VALUE = -7, - PARSER_SALT_ITERATION = -8, - PARSER_SEPARATOR_UNMATCHED = -9, - PARSER_SIGNATURE_UNMATCHED = -10, - PARSER_HCCAPX_FILE_SIZE = -11, - PARSER_HCCAPX_EAPOL_LEN = -12, - PARSER_PSAFE2_FILE_SIZE = -13, - PARSER_PSAFE3_FILE_SIZE = -14, - PARSER_TC_FILE_SIZE = -15, - PARSER_VC_FILE_SIZE = -16, - PARSER_SIP_AUTH_DIRECTIVE = -17, - PARSER_HASH_FILE = -18, - PARSER_HASH_ENCODING = -19, - PARSER_SALT_ENCODING = -20, - PARSER_LUKS_FILE_SIZE = -21, - PARSER_LUKS_MAGIC = -22, - PARSER_LUKS_VERSION = -23, - PARSER_LUKS_CIPHER_TYPE = -24, - PARSER_LUKS_CIPHER_MODE = -25, - PARSER_LUKS_HASH_TYPE = -26, - PARSER_LUKS_KEY_SIZE = -27, - PARSER_LUKS_KEY_DISABLED = -28, - PARSER_LUKS_KEY_STRIPES = -29, - PARSER_LUKS_HASH_CIPHER = -30, - PARSER_HCCAPX_SIGNATURE = -31, - PARSER_HCCAPX_VERSION = -32, - PARSER_HCCAPX_MESSAGE_PAIR = -33, - PARSER_TOKEN_ENCODING = -34, - PARSER_TOKEN_LENGTH = -35, - PARSER_UNKNOWN_ERROR = -255 + PARSER_OK = 0, + PARSER_COMMENT = -1, + PARSER_GLOBAL_ZERO = -2, + PARSER_GLOBAL_LENGTH = -3, + PARSER_HASH_LENGTH = -4, + PARSER_HASH_VALUE = -5, + PARSER_SALT_LENGTH = -6, + PARSER_SALT_VALUE = -7, + PARSER_SALT_ITERATION = -8, + PARSER_SEPARATOR_UNMATCHED = -9, + PARSER_SIGNATURE_UNMATCHED = -10, + PARSER_HCCAPX_FILE_SIZE = -11, + PARSER_HCCAPX_EAPOL_LEN = -12, + PARSER_PSAFE2_FILE_SIZE = -13, + PARSER_PSAFE3_FILE_SIZE = -14, + PARSER_TC_FILE_SIZE = -15, + PARSER_VC_FILE_SIZE = -16, + PARSER_SIP_AUTH_DIRECTIVE = -17, + PARSER_HASH_FILE = -18, + PARSER_HASH_ENCODING = -19, + PARSER_SALT_ENCODING = -20, + PARSER_LUKS_FILE_SIZE = -21, + PARSER_LUKS_MAGIC = -22, + PARSER_LUKS_VERSION = -23, + PARSER_LUKS_CIPHER_TYPE = -24, + PARSER_LUKS_CIPHER_MODE = -25, + PARSER_LUKS_HASH_TYPE = -26, + PARSER_LUKS_KEY_SIZE = -27, + PARSER_LUKS_KEY_DISABLED = -28, + PARSER_LUKS_KEY_STRIPES = -29, + PARSER_LUKS_HASH_CIPHER = -30, + PARSER_HCCAPX_SIGNATURE = -31, + PARSER_HCCAPX_VERSION = -32, + PARSER_HCCAPX_MESSAGE_PAIR = -33, + PARSER_TOKEN_ENCODING = -34, + PARSER_TOKEN_LENGTH = -35, + PARSER_INSUFFICIENT_ENTROPY = -36, + PARSER_UNKNOWN_ERROR = -255 } parser_rc_t; diff --git a/src/Makefile b/src/Makefile index ec57b35a6..058e07e6f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -228,6 +228,7 @@ LFLAGS_NATIVE := $(LFLAGS) LFLAGS_NATIVE += -lpthread LFLAGS_NATIVE += -ldl LFLAGS_NATIVE += -lrt +LFLAGS_NATIVE += -lm endif # Linux ifeq ($(UNAME),FreeBSD) @@ -236,6 +237,7 @@ CFLAGS_NATIVE := $(CFLAGS) CFLAGS_NATIVE += -I$(OPENCL_HEADERS_KHRONOS)/ LFLAGS_NATIVE := $(LFLAGS) LFLAGS_NATIVE += -lpthread +LFLAGS_NATIVE += -lm endif endif # FreeBSD @@ -300,9 +302,11 @@ CFLAGS_CROSS_WIN64 += -DWITH_HWMON LFLAGS_CROSS_LINUX32 := $(LFLAGS) LFLAGS_CROSS_LINUX32 += -lpthread LFLAGS_CROSS_LINUX32 += -ldl +LFLAGS_CROSS_LINUX32 += -lm LFLAGS_CROSS_LINUX64 := $(LFLAGS) LFLAGS_CROSS_LINUX64 += -lpthread LFLAGS_CROSS_LINUX64 += -ldl +LFLAGS_CROSS_LINUX64 += -lm LFLAGS_CROSS_WIN32 := $(LFLAGS) LFLAGS_CROSS_WIN32 += -Wl,--dynamicbase -Wl,--nxcompat LFLAGS_CROSS_WIN32 += -lpsapi diff --git a/src/interface.c b/src/interface.c index 08bad8425..f462ef44d 100644 --- a/src/interface.c +++ b/src/interface.c @@ -341,6 +341,7 @@ static const char *PA_032 = "Invalid hccapx version"; static const char *PA_033 = "Invalid hccapx message pair"; static const char *PA_034 = "Token encoding exception"; static const char *PA_035 = "Token length exception"; +static const char *PA_036 = "Insufficient entropy exception"; static const char *PA_255 = "Unknown error"; static const char *HT_00000 = "MD5"; @@ -6755,6 +6756,10 @@ int truecrypt_parse_hash_1k (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAY if (n != sizeof (buf)) return (PARSER_TC_FILE_SIZE); + const float entropy = get_entropy (buf, n); + + if (entropy < MIN_SUFFICIENT_ENTROPY_FILE) return (PARSER_INSUFFICIENT_ENTROPY); + memcpy (tc->salt_buf, buf, 64); memcpy (tc->data_buf, buf + 64, 512 - 64); @@ -6794,6 +6799,10 @@ int truecrypt_parse_hash_2k (u8 *input_buf, u32 input_len, hash_t *hash_buf, MAY if (n != sizeof (buf)) return (PARSER_TC_FILE_SIZE); + const float entropy = get_entropy (buf, n); + + if (entropy < MIN_SUFFICIENT_ENTROPY_FILE) return (PARSER_INSUFFICIENT_ENTROPY); + memcpy (tc->salt_buf, buf, 64); memcpy (tc->data_buf, buf + 64, 512 - 64); @@ -6833,6 +6842,10 @@ int veracrypt_parse_hash_200000 (u8 *input_buf, u32 input_len, hash_t *hash_buf, if (n != sizeof (buf)) return (PARSER_VC_FILE_SIZE); + const float entropy = get_entropy (buf, n); + + if (entropy < MIN_SUFFICIENT_ENTROPY_FILE) return (PARSER_INSUFFICIENT_ENTROPY); + memcpy (tc->salt_buf, buf, 64); memcpy (tc->data_buf, buf + 64, 512 - 64); @@ -6872,6 +6885,10 @@ int veracrypt_parse_hash_500000 (u8 *input_buf, u32 input_len, hash_t *hash_buf, if (n != sizeof (buf)) return (PARSER_VC_FILE_SIZE); + const float entropy = get_entropy (buf, n); + + if (entropy < MIN_SUFFICIENT_ENTROPY_FILE) return (PARSER_INSUFFICIENT_ENTROPY); + memcpy (tc->salt_buf, buf, 64); memcpy (tc->data_buf, buf + 64, 512 - 64); @@ -6911,6 +6928,10 @@ int veracrypt_parse_hash_327661 (u8 *input_buf, u32 input_len, hash_t *hash_buf, if (n != sizeof (buf)) return (PARSER_VC_FILE_SIZE); + const float entropy = get_entropy (buf, n); + + if (entropy < MIN_SUFFICIENT_ENTROPY_FILE) return (PARSER_INSUFFICIENT_ENTROPY); + memcpy (tc->salt_buf, buf, 64); memcpy (tc->data_buf, buf + 64, 512 - 64); @@ -6950,6 +6971,10 @@ int veracrypt_parse_hash_655331 (u8 *input_buf, u32 input_len, hash_t *hash_buf, if (n != sizeof (buf)) return (PARSER_VC_FILE_SIZE); + const float entropy = get_entropy (buf, n); + + if (entropy < MIN_SUFFICIENT_ENTROPY_FILE) return (PARSER_INSUFFICIENT_ENTROPY); + memcpy (tc->salt_buf, buf, 64); memcpy (tc->data_buf, buf + 64, 512 - 64); @@ -18255,6 +18280,7 @@ const char *strparser (const u32 parser_status) case PARSER_HCCAPX_MESSAGE_PAIR: return PA_033; case PARSER_TOKEN_ENCODING: return PA_034; case PARSER_TOKEN_LENGTH: return PA_035; + case PARSER_INSUFFICIENT_ENTROPY: return PA_036; } return PA_255; diff --git a/src/shared.c b/src/shared.c index 023d5a76f..9840422d2 100644 --- a/src/shared.c +++ b/src/shared.c @@ -679,3 +679,33 @@ void hc_strncat (u8 *dst, u8 *src, const size_t n) *dst_ptr = 0; } + +int count_char (const u8 *buf, const int len, const u8 c) +{ + int r = 0; + + for (int i = 0; i < len; i++) + { + if (buf[i] == c) r++; + } + + return r; +} + +float get_entropy (const u8 *buf, const int len) +{ + float entropy = 0.0; + + for (int c = 0; c < 256; c++) + { + const int r = count_char (buf, len, (const u8) c); + + if (r == 0) continue; + + float w = (float) r / len; + + entropy += -w * log2 (w); + } + + return entropy; +}