1
0
mirror of https://github.com/hashcat/hashcat.git synced 2024-12-23 15:18:16 +00:00

Use real dlopen() to load the module

This commit is contained in:
jsteube 2018-12-19 13:43:45 +01:00
parent fa0b8e643d
commit 7e1e1d34f8
9 changed files with 316 additions and 240 deletions

View File

@ -12,6 +12,9 @@
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <inttypes.h> #include <inttypes.h>
#include <dlfcn.h>
static const u32 MODULE_VERSION_MINIMUM = 520;
/** /**
* zero hashes shutcut * zero hashes shutcut
@ -122,8 +125,6 @@ typedef struct tc
} tc_t; } tc_t;
void seven_zip_hook_func (hc_device_param_t *device_param, void *hook_salts_buf, const u32 salt_pos, const u64 pws_cnt);
typedef struct wpa_eapol typedef struct wpa_eapol
{ {
u32 pke[32]; u32 pke[32];
@ -341,11 +342,9 @@ typedef struct luks
*/ */
const char *stroptitype (const u32 opti_type); const char *stroptitype (const u32 opti_type);
const char *strparser (const u32 parser_status);
int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const int out_size, const u32 salt_pos, const u32 digest_pos); int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const int out_size, const u32 salt_pos, const u32 digest_pos);
int input_tokenizer (const u8 *input_buf, const int input_len, token_t *token);
bool initialize_keyboard_layout_mapping (hashcat_ctx_t *hashcat_ctx, const char *filename, keyboard_layout_mapping_t *keyboard_layout_mapping, int *keyboard_layout_mapping_cnt); bool initialize_keyboard_layout_mapping (hashcat_ctx_t *hashcat_ctx, const char *filename, keyboard_layout_mapping_t *keyboard_layout_mapping, int *keyboard_layout_mapping_cnt);
int hashconfig_init (hashcat_ctx_t *hashcat_ctx); int hashconfig_init (hashcat_ctx_t *hashcat_ctx);

View File

@ -44,6 +44,6 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE
void hook12_func (hc_device_param_t *device_param, void *hook_salts_buf, const u32 salt_pos, const u64 pws_cnt); void hook12_func (hc_device_param_t *device_param, void *hook_salts_buf, const u32 salt_pos, const u64 pws_cnt);
void hook23_func (hc_device_param_t *device_param, void *hook_salts_buf, const u32 salt_pos, const u64 pws_cnt); void hook23_func (hc_device_param_t *device_param, void *hook_salts_buf, const u32 salt_pos, const u64 pws_cnt);
void module_register (module_ctx_t *module_ctx); void module_init (module_ctx_t *module_ctx);
#endif // _MODULES_H #endif // _MODULES_H

View File

@ -85,4 +85,8 @@ int select_write_timeout (int sockfd, const int sec);
int select_read_timeout_console (const int sec); int select_read_timeout_console (const int sec);
const char *strparser (const u32 parser_status);
int input_tokenizer (const u8 *input_buf, const int input_len, token_t *token);
#endif // _SHARED_H #endif // _SHARED_H

View File

@ -2232,6 +2232,11 @@ typedef struct event_ctx
typedef struct module_ctx typedef struct module_ctx
{ {
void *module_handle;
u32 module_version_current;
void (*module_init) (struct module_ctx *);
u32 (*module_attack_exec) (const hashconfig_t *, const user_options_t *, const user_options_extra_t *); u32 (*module_attack_exec) (const hashconfig_t *, const user_options_t *, const user_options_extra_t *);
void *(*module_benchmark_esalt) (const hashconfig_t *, const user_options_t *, const user_options_extra_t *); void *(*module_benchmark_esalt) (const hashconfig_t *, const user_options_t *, const user_options_extra_t *);
void *(*module_benchmark_hook_salt) (const hashconfig_t *, const user_options_t *, const user_options_extra_t *); void *(*module_benchmark_hook_salt) (const hashconfig_t *, const user_options_t *, const user_options_extra_t *);

View File

@ -11,6 +11,8 @@
#include "interface.h" #include "interface.h"
#include "shared.h" #include "shared.h"
static const u32 MODULE_VERSION_CURRENT = 520;
static const u32 ATTACK_EXEC = ATTACK_EXEC_INSIDE_KERNEL; static const u32 ATTACK_EXEC = ATTACK_EXEC_INSIDE_KERNEL;
static const u32 DGST_POS0 = 0; static const u32 DGST_POS0 = 0;
static const u32 DGST_POS1 = 3; static const u32 DGST_POS1 = 3;
@ -110,11 +112,10 @@ int module_hash_encode (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSE
return out_len; return out_len;
} }
void module_register (module_ctx_t *module_ctx) void module_init (module_ctx_t *module_ctx)
{ {
// undefined functions automatically call corresponding default functions // undefined functions automatically call corresponding default functions
module_ctx->module_attack_exec = module_attack_exec; module_ctx->module_attack_exec = module_attack_exec;
module_ctx->module_benchmark_esalt = NULL; module_ctx->module_benchmark_esalt = NULL;
module_ctx->module_benchmark_hook_salt = NULL; module_ctx->module_benchmark_hook_salt = NULL;
@ -153,5 +154,6 @@ void module_register (module_ctx_t *module_ctx)
module_ctx->module_st_hash = module_st_hash; module_ctx->module_st_hash = module_st_hash;
module_ctx->module_st_pass = NULL; module_ctx->module_st_pass = NULL;
module_ctx->module_tmp_size = NULL; module_ctx->module_tmp_size = NULL;
module_ctx->module_version_current = MODULE_VERSION_CURRENT;
module_ctx->module_warmup_disable = NULL; module_ctx->module_warmup_disable = NULL;
} }

View File

@ -531,7 +531,7 @@ ifeq ($(SHARED),1)
$(HASHCAT_FRONTEND): src/main.c $(HASHCAT_LIBRARY) $(HASHCAT_FRONTEND): src/main.c $(HASHCAT_LIBRARY)
$(CC) $(CFLAGS_NATIVE) $^ -o $@ $(HASHCAT_LIBRARY) $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\" $(CC) $(CFLAGS_NATIVE) $^ -o $@ $(HASHCAT_LIBRARY) $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\"
else else
$(HASHCAT_FRONTEND): src/main.c $(NATIVE_STATIC_OBJS) modules/m01000.so $(HASHCAT_FRONTEND): src/main.c $(NATIVE_STATIC_OBJS)
$(CC) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\" $(CC) $(CFLAGS_NATIVE) $^ -o $@ $(LFLAGS_NATIVE) -DCOMPTIME=$(COMPTIME) -DVERSION_TAG=\"$(VERSION_TAG)\" -DINSTALL_FOLDER=\"$(INSTALL_FOLDER)\" -DSHARED_FOLDER=\"$(SHARED_FOLDER)\" -DDOCUMENT_FOLDER=\"$(DOCUMENT_FOLDER)\"
endif endif
@ -539,8 +539,11 @@ endif
## native compiled modules ## native compiled modules
## ##
modules/m%.so: modules/m%.c MODULE_DEPEND := src/bitops.c src/convert.c src/interface.c src/shared.c
$(CC) -c $(CFLAGS_NATIVE) $< -o $@ -shared
modules/module_%.so: modules/module_%.c
$(CC) $(CFLAGS_NATIVE) $< -o $@ -shared -fPIC $(MODULE_DEPEND)
## ##
## cross compiled hashcat ## cross compiled hashcat

View File

@ -63,7 +63,7 @@ int benchmark_next (hashcat_ctx_t *hashcat_ctx)
for (int i = cur; i < 99999; i++) for (int i = cur; i < 99999; i++)
{ {
snprintf (modulefile, HCBUFSIZ_TINY, "%s/modules/m%05d.so", folder_config->shared_dir, i); snprintf (modulefile, HCBUFSIZ_TINY, "%s/modules/module_%05d.so", folder_config->shared_dir, i);
if (hc_path_exist (modulefile) == true) if (hc_path_exist (modulefile) == true)
{ {

View File

@ -54,179 +54,10 @@ static const char *OPTI_STR_USES_BITS_16 = "Uses-16-Bit";
static const char *OPTI_STR_USES_BITS_32 = "Uses-32-Bit"; static const char *OPTI_STR_USES_BITS_32 = "Uses-32-Bit";
static const char *OPTI_STR_USES_BITS_64 = "Uses-64-Bit"; static const char *OPTI_STR_USES_BITS_64 = "Uses-64-Bit";
static const char *PA_000 = "OK";
static const char *PA_001 = "Ignored due to comment";
static const char *PA_002 = "Ignored due to zero length";
static const char *PA_003 = "Line-length exception";
static const char *PA_004 = "Hash-length exception";
static const char *PA_005 = "Hash-value exception";
static const char *PA_006 = "Salt-length exception";
static const char *PA_007 = "Salt-value exception";
static const char *PA_008 = "Salt-iteration count exception";
static const char *PA_009 = "Separator unmatched";
static const char *PA_010 = "Signature unmatched";
static const char *PA_011 = "Invalid hccapx file size";
static const char *PA_012 = "Invalid hccapx eapol size";
static const char *PA_013 = "Invalid psafe2 filesize";
static const char *PA_014 = "Invalid psafe3 filesize";
static const char *PA_015 = "Invalid truecrypt filesize";
static const char *PA_016 = "Invalid veracrypt filesize";
static const char *PA_017 = "Invalid SIP directive, only MD5 is supported";
static const char *PA_018 = "Hash-file exception";
static const char *PA_019 = "Hash-encoding exception";
static const char *PA_020 = "Salt-encoding exception";
static const char *PA_021 = "Invalid LUKS filesize";
static const char *PA_022 = "Invalid LUKS identifier";
static const char *PA_023 = "Invalid LUKS version";
static const char *PA_024 = "Invalid or unsupported LUKS cipher type";
static const char *PA_025 = "Invalid or unsupported LUKS cipher mode";
static const char *PA_026 = "Invalid or unsupported LUKS hash type";
static const char *PA_027 = "Invalid LUKS key size";
static const char *PA_028 = "Disabled LUKS key detected";
static const char *PA_029 = "Invalid LUKS key AF stripes count";
static const char *PA_030 = "Invalid combination of LUKS hash type and cipher type";
static const char *PA_031 = "Invalid hccapx signature";
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";
/** /**
* parser * parser
*/ */
static int rounds_count_length (const char *input_buf, const int input_len)
{
if (input_len >= 9) // 9 is minimum because of "rounds=X$"
{
static const char *rounds = "rounds=";
if (memcmp (input_buf, rounds, 7) == 0)
{
char *next_pos = strchr (input_buf + 8, '$');
if (next_pos == NULL) return -1;
const int rounds_len = next_pos - input_buf;
return rounds_len;
}
}
return -1;
}
int input_tokenizer (const u8 *input_buf, const int input_len, token_t *token)
{
int len_left = input_len;
token->buf[0] = input_buf;
int token_idx;
for (token_idx = 0; token_idx < token->token_cnt - 1; token_idx++)
{
if (token->attr[token_idx] & TOKEN_ATTR_FIXED_LENGTH)
{
int len = token->len[token_idx];
if (len_left < len) return (PARSER_TOKEN_LENGTH);
token->buf[token_idx + 1] = token->buf[token_idx] + len;
len_left -= len;
}
else
{
if (token->attr[token_idx] & TOKEN_ATTR_OPTIONAL_ROUNDS)
{
const int len = rounds_count_length ((const char *) token->buf[token_idx], len_left);
token->opt_buf = token->buf[token_idx];
token->opt_len = len; // we want an eventual -1 in here, it's used later for verification
if (len > 0)
{
token->buf[token_idx] += len + 1; // +1 = separator
len_left -= len + 1; // +1 = separator
}
}
const u8 *next_pos = (const u8 *) strchr ((const char *) token->buf[token_idx], token->sep[token_idx]);
if (next_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
const int len = next_pos - token->buf[token_idx];
token->len[token_idx] = len;
token->buf[token_idx + 1] = next_pos + 1; // +1 = separator
len_left -= len + 1; // +1 = separator
}
}
if (token->attr[token_idx] & TOKEN_ATTR_FIXED_LENGTH)
{
int len = token->len[token_idx];
if (len_left != len) return (PARSER_TOKEN_LENGTH);
}
else
{
token->len[token_idx] = len_left;
}
// verify data
for (token_idx = 0; token_idx < token->token_cnt; token_idx++)
{
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_SIGNATURE)
{
bool matched = false;
for (int signature_idx = 0; signature_idx < token->signatures_cnt; signature_idx++)
{
if (memcmp (token->buf[token_idx], token->signatures_buf[signature_idx], token->len[token_idx]) == 0) matched = true;
}
if (matched == false) return (PARSER_SIGNATURE_UNMATCHED);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_LENGTH)
{
if (token->len[token_idx] < token->len_min[token_idx]) return (PARSER_TOKEN_LENGTH);
if (token->len[token_idx] > token->len_max[token_idx]) return (PARSER_TOKEN_LENGTH);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_HEX)
{
if (is_valid_hex_string (token->buf[token_idx], token->len[token_idx]) == false) return (PARSER_TOKEN_ENCODING);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_BASE64A)
{
if (is_valid_base64a_string (token->buf[token_idx], token->len[token_idx]) == false) return (PARSER_TOKEN_ENCODING);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_BASE64B)
{
if (is_valid_base64b_string (token->buf[token_idx], token->len[token_idx]) == false) return (PARSER_TOKEN_ENCODING);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_BASE64C)
{
if (is_valid_base64c_string (token->buf[token_idx], token->len[token_idx]) == false) return (PARSER_TOKEN_ENCODING);
}
}
return PARSER_OK;
}
static int sort_by_src_len (const void *p1, const void *p2) static int sort_by_src_len (const void *p1, const void *p2)
{ {
const keyboard_layout_mapping_t *k1 = (const keyboard_layout_mapping_t *) p1; const keyboard_layout_mapping_t *k1 = (const keyboard_layout_mapping_t *) p1;
@ -479,52 +310,6 @@ const char *stroptitype (const u32 opti_type)
return NULL; return NULL;
} }
const char *strparser (const u32 parser_status)
{
switch (parser_status)
{
case PARSER_OK: return PA_000;
case PARSER_COMMENT: return PA_001;
case PARSER_GLOBAL_ZERO: return PA_002;
case PARSER_GLOBAL_LENGTH: return PA_003;
case PARSER_HASH_LENGTH: return PA_004;
case PARSER_HASH_VALUE: return PA_005;
case PARSER_SALT_LENGTH: return PA_006;
case PARSER_SALT_VALUE: return PA_007;
case PARSER_SALT_ITERATION: return PA_008;
case PARSER_SEPARATOR_UNMATCHED: return PA_009;
case PARSER_SIGNATURE_UNMATCHED: return PA_010;
case PARSER_HCCAPX_FILE_SIZE: return PA_011;
case PARSER_HCCAPX_EAPOL_LEN: return PA_012;
case PARSER_PSAFE2_FILE_SIZE: return PA_013;
case PARSER_PSAFE3_FILE_SIZE: return PA_014;
case PARSER_TC_FILE_SIZE: return PA_015;
case PARSER_VC_FILE_SIZE: return PA_016;
case PARSER_SIP_AUTH_DIRECTIVE: return PA_017;
case PARSER_HASH_FILE: return PA_018;
case PARSER_HASH_ENCODING: return PA_019;
case PARSER_SALT_ENCODING: return PA_020;
case PARSER_LUKS_FILE_SIZE: return PA_021;
case PARSER_LUKS_MAGIC: return PA_022;
case PARSER_LUKS_VERSION: return PA_023;
case PARSER_LUKS_CIPHER_TYPE: return PA_024;
case PARSER_LUKS_CIPHER_MODE: return PA_025;
case PARSER_LUKS_HASH_TYPE: return PA_026;
case PARSER_LUKS_KEY_SIZE: return PA_027;
case PARSER_LUKS_KEY_DISABLED: return PA_028;
case PARSER_LUKS_KEY_STRIPES: return PA_029;
case PARSER_LUKS_HASH_CIPHER: return PA_030;
case PARSER_HCCAPX_SIGNATURE: return PA_031;
case PARSER_HCCAPX_VERSION: return PA_032;
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;
}
int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const int out_size, const u32 salt_pos, const u32 digest_pos) int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const int out_size, const u32 salt_pos, const u32 digest_pos)
{ {
const hashconfig_t *hashconfig = hashcat_ctx->hashconfig; const hashconfig_t *hashconfig = hashcat_ctx->hashconfig;
@ -848,6 +633,54 @@ int ascii_digest (hashcat_ctx_t *hashcat_ctx, char *out_buf, const int out_size,
} }
static bool module_load (hashcat_ctx_t *hashcat_ctx, module_ctx_t *module_ctx, const u32 hash_mode)
{
char *module_file = (char *) hcmalloc (HCBUFSIZ_TINY);
#if defined (_WIN)
#else
const folder_config_t *folder_config = hashcat_ctx->folder_config;
snprintf (module_file, HCBUFSIZ_TINY, "%s/modules/module_%05d.so", folder_config->shared_dir, hash_mode);
module_ctx->module_handle = dlopen (module_file, RTLD_LAZY);
if (module_ctx->module_handle == NULL)
{
event_log_error (hashcat_ctx, "%s", dlerror ());
return false;
}
module_ctx->module_init = dlsym (module_ctx->module_handle, "module_init");
if (module_ctx->module_init == NULL)
{
event_log_error (hashcat_ctx, "%s", dlerror ());
return false;
}
#endif
free (module_file);
return true;
}
static void module_unload (module_ctx_t *module_ctx)
{
#if defined (_WIN)
#else
dlclose (module_ctx->module_handle);
#endif
}
int hashconfig_init (hashcat_ctx_t *hashcat_ctx) int hashconfig_init (hashcat_ctx_t *hashcat_ctx)
{ {
const folder_config_t *folder_config = hashcat_ctx->folder_config; const folder_config_t *folder_config = hashcat_ctx->folder_config;
@ -888,7 +721,18 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx)
// finally, the real stuff // finally, the real stuff
module_register (module_ctx); const bool rc_load = module_load (hashcat_ctx, module_ctx, user_options->hash_mode);
if (rc_load == false) return -1;
module_ctx->module_init (module_ctx);
if (module_ctx->module_version_current < MODULE_VERSION_MINIMUM)
{
event_log_error (hashcat_ctx, "module version current (%u) older than minimum (%u)", module_ctx->module_version_current, MODULE_VERSION_MINIMUM);
return -1;
}
if (module_ctx->module_attack_exec) hashconfig->attack_exec = module_ctx->module_attack_exec (hashconfig, user_options, user_options_extra); if (module_ctx->module_attack_exec) hashconfig->attack_exec = module_ctx->module_attack_exec (hashconfig, user_options, user_options_extra);
if (module_ctx->module_dictstat_disable) hashconfig->dictstat_disable = module_ctx->module_dictstat_disable (hashconfig, user_options, user_options_extra); if (module_ctx->module_dictstat_disable) hashconfig->dictstat_disable = module_ctx->module_dictstat_disable (hashconfig, user_options, user_options_extra);
@ -1057,6 +901,9 @@ int hashconfig_init (hashcat_ctx_t *hashcat_ctx)
void hashconfig_destroy (hashcat_ctx_t *hashcat_ctx) void hashconfig_destroy (hashcat_ctx_t *hashcat_ctx)
{ {
hashconfig_t *hashconfig = hashcat_ctx->hashconfig; hashconfig_t *hashconfig = hashcat_ctx->hashconfig;
module_ctx_t *module_ctx = hashcat_ctx->module_ctx;
module_unload (module_ctx);
memset (hashconfig, 0, sizeof (hashconfig_t)); memset (hashconfig, 0, sizeof (hashconfig_t));
} }

View File

@ -5,12 +5,52 @@
#include "common.h" #include "common.h"
#include "types.h" #include "types.h"
#include "convert.h"
#include "shared.h" #include "shared.h"
#if defined (__CYGWIN__) #if defined (__CYGWIN__)
#include <sys/cygwin.h> #include <sys/cygwin.h>
#endif #endif
static const char *PA_000 = "OK";
static const char *PA_001 = "Ignored due to comment";
static const char *PA_002 = "Ignored due to zero length";
static const char *PA_003 = "Line-length exception";
static const char *PA_004 = "Hash-length exception";
static const char *PA_005 = "Hash-value exception";
static const char *PA_006 = "Salt-length exception";
static const char *PA_007 = "Salt-value exception";
static const char *PA_008 = "Salt-iteration count exception";
static const char *PA_009 = "Separator unmatched";
static const char *PA_010 = "Signature unmatched";
static const char *PA_011 = "Invalid hccapx file size";
static const char *PA_012 = "Invalid hccapx eapol size";
static const char *PA_013 = "Invalid psafe2 filesize";
static const char *PA_014 = "Invalid psafe3 filesize";
static const char *PA_015 = "Invalid truecrypt filesize";
static const char *PA_016 = "Invalid veracrypt filesize";
static const char *PA_017 = "Invalid SIP directive, only MD5 is supported";
static const char *PA_018 = "Hash-file exception";
static const char *PA_019 = "Hash-encoding exception";
static const char *PA_020 = "Salt-encoding exception";
static const char *PA_021 = "Invalid LUKS filesize";
static const char *PA_022 = "Invalid LUKS identifier";
static const char *PA_023 = "Invalid LUKS version";
static const char *PA_024 = "Invalid or unsupported LUKS cipher type";
static const char *PA_025 = "Invalid or unsupported LUKS cipher mode";
static const char *PA_026 = "Invalid or unsupported LUKS hash type";
static const char *PA_027 = "Invalid LUKS key size";
static const char *PA_028 = "Disabled LUKS key detected";
static const char *PA_029 = "Invalid LUKS key AF stripes count";
static const char *PA_030 = "Invalid combination of LUKS hash type and cipher type";
static const char *PA_031 = "Invalid hccapx signature";
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 inline int get_msb32 (const u32 v) static inline int get_msb32 (const u32 v)
{ {
int i; int i;
@ -793,3 +833,179 @@ int select_read_timeout_console (const int sec)
} }
#endif #endif
const char *strparser (const u32 parser_status)
{
switch (parser_status)
{
case PARSER_OK: return PA_000;
case PARSER_COMMENT: return PA_001;
case PARSER_GLOBAL_ZERO: return PA_002;
case PARSER_GLOBAL_LENGTH: return PA_003;
case PARSER_HASH_LENGTH: return PA_004;
case PARSER_HASH_VALUE: return PA_005;
case PARSER_SALT_LENGTH: return PA_006;
case PARSER_SALT_VALUE: return PA_007;
case PARSER_SALT_ITERATION: return PA_008;
case PARSER_SEPARATOR_UNMATCHED: return PA_009;
case PARSER_SIGNATURE_UNMATCHED: return PA_010;
case PARSER_HCCAPX_FILE_SIZE: return PA_011;
case PARSER_HCCAPX_EAPOL_LEN: return PA_012;
case PARSER_PSAFE2_FILE_SIZE: return PA_013;
case PARSER_PSAFE3_FILE_SIZE: return PA_014;
case PARSER_TC_FILE_SIZE: return PA_015;
case PARSER_VC_FILE_SIZE: return PA_016;
case PARSER_SIP_AUTH_DIRECTIVE: return PA_017;
case PARSER_HASH_FILE: return PA_018;
case PARSER_HASH_ENCODING: return PA_019;
case PARSER_SALT_ENCODING: return PA_020;
case PARSER_LUKS_FILE_SIZE: return PA_021;
case PARSER_LUKS_MAGIC: return PA_022;
case PARSER_LUKS_VERSION: return PA_023;
case PARSER_LUKS_CIPHER_TYPE: return PA_024;
case PARSER_LUKS_CIPHER_MODE: return PA_025;
case PARSER_LUKS_HASH_TYPE: return PA_026;
case PARSER_LUKS_KEY_SIZE: return PA_027;
case PARSER_LUKS_KEY_DISABLED: return PA_028;
case PARSER_LUKS_KEY_STRIPES: return PA_029;
case PARSER_LUKS_HASH_CIPHER: return PA_030;
case PARSER_HCCAPX_SIGNATURE: return PA_031;
case PARSER_HCCAPX_VERSION: return PA_032;
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;
}
static int rounds_count_length (const char *input_buf, const int input_len)
{
if (input_len >= 9) // 9 is minimum because of "rounds=X$"
{
static const char *rounds = "rounds=";
if (memcmp (input_buf, rounds, 7) == 0)
{
char *next_pos = strchr (input_buf + 8, '$');
if (next_pos == NULL) return -1;
const int rounds_len = next_pos - input_buf;
return rounds_len;
}
}
return -1;
}
int input_tokenizer (const u8 *input_buf, const int input_len, token_t *token)
{
int len_left = input_len;
token->buf[0] = input_buf;
int token_idx;
for (token_idx = 0; token_idx < token->token_cnt - 1; token_idx++)
{
if (token->attr[token_idx] & TOKEN_ATTR_FIXED_LENGTH)
{
int len = token->len[token_idx];
if (len_left < len) return (PARSER_TOKEN_LENGTH);
token->buf[token_idx + 1] = token->buf[token_idx] + len;
len_left -= len;
}
else
{
if (token->attr[token_idx] & TOKEN_ATTR_OPTIONAL_ROUNDS)
{
const int len = rounds_count_length ((const char *) token->buf[token_idx], len_left);
token->opt_buf = token->buf[token_idx];
token->opt_len = len; // we want an eventual -1 in here, it's used later for verification
if (len > 0)
{
token->buf[token_idx] += len + 1; // +1 = separator
len_left -= len + 1; // +1 = separator
}
}
const u8 *next_pos = (const u8 *) strchr ((const char *) token->buf[token_idx], token->sep[token_idx]);
if (next_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
const int len = next_pos - token->buf[token_idx];
token->len[token_idx] = len;
token->buf[token_idx + 1] = next_pos + 1; // +1 = separator
len_left -= len + 1; // +1 = separator
}
}
if (token->attr[token_idx] & TOKEN_ATTR_FIXED_LENGTH)
{
int len = token->len[token_idx];
if (len_left != len) return (PARSER_TOKEN_LENGTH);
}
else
{
token->len[token_idx] = len_left;
}
// verify data
for (token_idx = 0; token_idx < token->token_cnt; token_idx++)
{
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_SIGNATURE)
{
bool matched = false;
for (int signature_idx = 0; signature_idx < token->signatures_cnt; signature_idx++)
{
if (memcmp (token->buf[token_idx], token->signatures_buf[signature_idx], token->len[token_idx]) == 0) matched = true;
}
if (matched == false) return (PARSER_SIGNATURE_UNMATCHED);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_LENGTH)
{
if (token->len[token_idx] < token->len_min[token_idx]) return (PARSER_TOKEN_LENGTH);
if (token->len[token_idx] > token->len_max[token_idx]) return (PARSER_TOKEN_LENGTH);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_HEX)
{
if (is_valid_hex_string (token->buf[token_idx], token->len[token_idx]) == false) return (PARSER_TOKEN_ENCODING);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_BASE64A)
{
if (is_valid_base64a_string (token->buf[token_idx], token->len[token_idx]) == false) return (PARSER_TOKEN_ENCODING);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_BASE64B)
{
if (is_valid_base64b_string (token->buf[token_idx], token->len[token_idx]) == false) return (PARSER_TOKEN_ENCODING);
}
if (token->attr[token_idx] & TOKEN_ATTR_VERIFY_BASE64C)
{
if (is_valid_base64c_string (token->buf[token_idx], token->len[token_idx]) == false) return (PARSER_TOKEN_ENCODING);
}
}
return PARSER_OK;
}