diff --git a/docs/changes.txt b/docs/changes.txt index 20d207bad..58785133b 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -8,6 +8,7 @@ - Refactor hashcat backend interface to allow adding compute API other than OpenCL - Added CUDA as a new compute API to hashcat backend (enables hashcat to run on NVIDIA Jetson or IBM POWER9) - Support use of all available GPU memory using CUDA backend +- Support use of all available CPU cores for hash-mode specific hooks - Support on-the-fly loading of compressed wordlists in zip and gzip format - Support for inline VeraCrypt PIM Brute-Force - Support deflate decompression for the 7-Zip hash-mode using zlib hook diff --git a/include/backend.h b/include/backend.h index 4d24cf4c0..8f9154d94 100644 --- a/include/backend.h +++ b/include/backend.h @@ -154,4 +154,7 @@ int backend_session_update_combinator (hashcat_ctx_t *hashcat_ctx); int backend_session_update_mp (hashcat_ctx_t *hashcat_ctx); int backend_session_update_mp_rl (hashcat_ctx_t *hashcat_ctx, const u32 css_cnt_l, const u32 css_cnt_r); +void *hook12_thread (void *p); +void *hook23_thread (void *p); + #endif // _BACKEND_H diff --git a/include/modules.h b/include/modules.h index 1e90e67dd..4e6fee69c 100644 --- a/include/modules.h +++ b/include/modules.h @@ -71,8 +71,8 @@ bool module_jit_cache_disable (MAYBE_UNUSED const hashconfig_t *ha u32 module_deep_comp_kernel (MAYBE_UNUSED const hashes_t *hashes, MAYBE_UNUSED const u32 salt_pos, MAYBE_UNUSED const u32 digest_pos); int module_hash_init_selftest (MAYBE_UNUSED const hashconfig_t *hashconfig, hash_t *hash); -void module_hook12 (hc_device_param_t *device_param, const void *hook_salts_buf, const u32 salt_pos, const u64 pws_cnt); -void module_hook23 (hc_device_param_t *device_param, const void *hook_salts_buf, const u32 salt_pos, const u64 pws_cnt); +void module_hook12 (hc_device_param_t *device_param, const void *hook_salts_buf, const u32 salt_pos, const u64 pw_pos); +void module_hook23 (hc_device_param_t *device_param, const void *hook_salts_buf, const u32 salt_pos, const u64 pw_pos); int module_build_plain_postprocess (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE_UNUSED const hashes_t *hashes, MAYBE_UNUSED const void *tmps, const u32 *src_buf, MAYBE_UNUSED const size_t src_sz, MAYBE_UNUSED const int src_len, u32 *dst_buf, MAYBE_UNUSED const size_t dst_sz); diff --git a/include/types.h b/include/types.h index f5e3b3dbc..7955690de 100644 --- a/include/types.h +++ b/include/types.h @@ -2461,6 +2461,22 @@ typedef struct thread_param } thread_param_t; +typedef struct hook_thread_param +{ + int tid; + int tsz; + + module_ctx_t *module_ctx; + + hc_device_param_t *device_param; + + void *hook_salts_buf; + + u32 salt_pos; + u64 pws_cnt; + +} hook_thread_param_t; + #define MAX_TOKENS 128 #define MAX_SIGNATURES 16 diff --git a/src/backend.c b/src/backend.c index 832175b8a..958c1259f 100644 --- a/src/backend.c +++ b/src/backend.c @@ -2877,7 +2877,42 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_clEnqueueReadBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_hooks, CL_TRUE, 0, device_param->size_hooks, device_param->hooks_buf, 0, NULL, NULL) == -1) return -1; } - module_ctx->module_hook12 (device_param, hashes->hook_salts_buf, salt_pos, pws_cnt); + const int hook_threads = (int) user_options->hook_threads; + + hook_thread_param_t *hook_threads_param = (hook_thread_param_t *) hccalloc (hook_threads, sizeof (hook_thread_param_t)); + + for (int i = 0; i < hook_threads; i++) + { + hook_thread_param_t *hook_thread_param = hook_threads_param + i; + + hook_thread_param->tid = i; + hook_thread_param->tsz = hook_threads; + + hook_thread_param->module_ctx = module_ctx; + + hook_thread_param->device_param = device_param; + + hook_thread_param->hook_salts_buf = hashes->hook_salts_buf; + + hook_thread_param->salt_pos = salt_pos; + + hook_thread_param->pws_cnt = pws_cnt; + } + + hc_thread_t *c_threads = (hc_thread_t *) calloc (hook_threads, sizeof (hc_thread_t)); + + for (int i = 0; i < hook_threads; i++) + { + hook_thread_param_t *hook_thread_param = hook_threads_param + i; + + hc_thread_create (c_threads[i], hook12_thread, hook_thread_param); + } + + hc_thread_wait (hook_threads, c_threads); + + hcfree (c_threads); + + hcfree (hook_threads_param); if (device_param->is_cuda == true) { @@ -2957,7 +2992,42 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_clEnqueueReadBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_hooks, CL_TRUE, 0, device_param->size_hooks, device_param->hooks_buf, 0, NULL, NULL) == -1) return -1; } - module_ctx->module_hook23 (device_param, hashes->hook_salts_buf, salt_pos, pws_cnt); + const int hook_threads = (int) user_options->hook_threads; + + hook_thread_param_t *hook_threads_param = (hook_thread_param_t *) hccalloc (hook_threads, sizeof (hook_thread_param_t)); + + for (int i = 0; i < hook_threads; i++) + { + hook_thread_param_t *hook_thread_param = hook_threads_param + i; + + hook_thread_param->tid = i; + hook_thread_param->tsz = hook_threads; + + hook_thread_param->module_ctx = module_ctx; + + hook_thread_param->device_param = device_param; + + hook_thread_param->hook_salts_buf = hashes->hook_salts_buf; + + hook_thread_param->salt_pos = salt_pos; + + hook_thread_param->pws_cnt = pws_cnt; + } + + hc_thread_t *c_threads = (hc_thread_t *) calloc (hook_threads, sizeof (hc_thread_t)); + + for (int i = 0; i < hook_threads; i++) + { + hook_thread_param_t *hook_thread_param = hook_threads_param + i; + + hc_thread_create (c_threads[i], hook23_thread, hook_thread_param); + } + + hc_thread_wait (hook_threads, c_threads); + + hcfree (c_threads); + + hcfree (hook_threads_param); if (device_param->is_cuda == true) { @@ -10131,3 +10201,39 @@ int backend_session_update_mp_rl (hashcat_ctx_t *hashcat_ctx, const u32 css_cnt_ return 0; } + +void *hook12_thread (void *p) +{ + hook_thread_param_t *hook_thread_param = (hook_thread_param_t *) p; + + module_ctx_t *module_ctx = hook_thread_param->module_ctx; + + const u64 tid = hook_thread_param->tid; + const u64 tsz = hook_thread_param->tsz; + const u64 pws_cnt = hook_thread_param->pws_cnt; + + for (u64 pw_pos = tid; pw_pos < pws_cnt; pw_pos += tsz) + { + module_ctx->module_hook12 (hook_thread_param->device_param, hook_thread_param->hook_salts_buf, hook_thread_param->salt_pos, pw_pos); + } + + return NULL; +} + +void *hook23_thread (void *p) +{ + hook_thread_param_t *hook_thread_param = (hook_thread_param_t *) p; + + module_ctx_t *module_ctx = hook_thread_param->module_ctx; + + const u64 tid = hook_thread_param->tid; + const u64 tsz = hook_thread_param->tsz; + const u64 pws_cnt = hook_thread_param->pws_cnt; + + for (u64 pw_pos = tid; pw_pos < pws_cnt; pw_pos += tsz) + { + module_ctx->module_hook23 (hook_thread_param->device_param, hook_thread_param->hook_salts_buf, hook_thread_param->salt_pos, pw_pos); + } + + return NULL; +} diff --git a/src/modules/module_11600.c b/src/modules/module_11600.c index c05058ab9..29f0ef400 100644 --- a/src/modules/module_11600.c +++ b/src/modules/module_11600.c @@ -94,7 +94,7 @@ typedef struct seven_zip_hook_salt static const char *SIGNATURE_SEVEN_ZIP = "$7z$"; -void module_hook23 (hc_device_param_t *device_param, const void *hook_salts_buf, const u32 salt_pos, const u64 pws_cnt) +void module_hook23 (hc_device_param_t *device_param, const void *hook_salts_buf, const u32 salt_pos, const u64 pw_pos) { seven_zip_hook_t *hook_items = (seven_zip_hook_t *) device_param->hooks_buf; @@ -105,67 +105,40 @@ void module_hook23 (hc_device_param_t *device_param, const void *hook_salts_buf, u32 *data_buf = seven_zip->data_buf; u32 unpack_size = seven_zip->unpack_size; - for (u64 pw_pos = 0; pw_pos < pws_cnt; pw_pos++) + // this hook data needs to be updated (the "hook_success" variable): + + seven_zip_hook_t *hook_item = &hook_items[pw_pos]; + + const u32 *ukey = (const u32 *) hook_item->ukey; + + // init AES + + AES_KEY aes_key; + + memset (&aes_key, 0, sizeof (aes_key)); + + aes256_set_decrypt_key (aes_key.rdk, ukey, (u32 *) te0, (u32 *) te1, (u32 *) te2, (u32 *) te3, (u32 *) td0, (u32 *) td1, (u32 *) td2, (u32 *) td3); + + int aes_len = seven_zip->aes_len; + + u32 data[4]; + u32 out[4]; + u32 iv[4]; + + iv[0] = seven_zip->iv_buf[0]; + iv[1] = seven_zip->iv_buf[1]; + iv[2] = seven_zip->iv_buf[2]; + iv[3] = seven_zip->iv_buf[3]; + + u32 out_full[81882]; + + // if aes_len > 16 we need to loop + + int i = 0; + int j = 0; + + for (i = 0, j = 0; i < aes_len - 16; i += 16, j += 4) { - // this hook data needs to be updated (the "hook_success" variable): - - seven_zip_hook_t *hook_item = &hook_items[pw_pos]; - - const u32 *ukey = (const u32 *) hook_item->ukey; - - // init AES - - AES_KEY aes_key; - - memset (&aes_key, 0, sizeof (aes_key)); - - aes256_set_decrypt_key (aes_key.rdk, ukey, (u32 *) te0, (u32 *) te1, (u32 *) te2, (u32 *) te3, (u32 *) td0, (u32 *) td1, (u32 *) td2, (u32 *) td3); - - int aes_len = seven_zip->aes_len; - - u32 data[4]; - u32 out[4]; - u32 iv[4]; - - iv[0] = seven_zip->iv_buf[0]; - iv[1] = seven_zip->iv_buf[1]; - iv[2] = seven_zip->iv_buf[2]; - iv[3] = seven_zip->iv_buf[3]; - - u32 out_full[81882]; - - // if aes_len > 16 we need to loop - - int i = 0; - int j = 0; - - for (i = 0, j = 0; i < aes_len - 16; i += 16, j += 4) - { - data[0] = data_buf[j + 0]; - data[1] = data_buf[j + 1]; - data[2] = data_buf[j + 2]; - data[3] = data_buf[j + 3]; - - aes256_decrypt (aes_key.rdk, data, out, (u32 *) td0, (u32 *) td1, (u32 *) td2, (u32 *) td3, (u32 *) td4); - - out[0] ^= iv[0]; - out[1] ^= iv[1]; - out[2] ^= iv[2]; - out[3] ^= iv[3]; - - iv[0] = data[0]; - iv[1] = data[1]; - iv[2] = data[2]; - iv[3] = data[3]; - - out_full[j + 0] = out[0]; - out_full[j + 1] = out[1]; - out_full[j + 2] = out[2]; - out_full[j + 3] = out[3]; - } - - // we need to run it at least once: - data[0] = data_buf[j + 0]; data[1] = data_buf[j + 1]; data[2] = data_buf[j + 2]; @@ -178,105 +151,129 @@ void module_hook23 (hc_device_param_t *device_param, const void *hook_salts_buf, out[2] ^= iv[2]; out[3] ^= iv[3]; + iv[0] = data[0]; + iv[1] = data[1]; + iv[2] = data[2]; + iv[3] = data[3]; + out_full[j + 0] = out[0]; out_full[j + 1] = out[1]; out_full[j + 2] = out[2]; out_full[j + 3] = out[3]; + } - /* - * check the CRC32 "hash" - */ + // we need to run it at least once: - u32 seven_zip_crc = seven_zip->crc; + data[0] = data_buf[j + 0]; + data[1] = data_buf[j + 1]; + data[2] = data_buf[j + 2]; + data[3] = data_buf[j + 3]; - u32 crc; + aes256_decrypt (aes_key.rdk, data, out, (u32 *) td0, (u32 *) td1, (u32 *) td2, (u32 *) td3, (u32 *) td4); - if (data_type == 0) // uncompressed + out[0] ^= iv[0]; + out[1] ^= iv[1]; + out[2] ^= iv[2]; + out[3] ^= iv[3]; + + out_full[j + 0] = out[0]; + out_full[j + 1] = out[1]; + out_full[j + 2] = out[2]; + out_full[j + 3] = out[3]; + + /* + * check the CRC32 "hash" + */ + + u32 seven_zip_crc = seven_zip->crc; + + u32 crc; + + if (data_type == 0) // uncompressed + { + crc = cpu_crc32_buffer ((u8 *) out_full, unpack_size); + } + else + { + u32 crc_len = seven_zip->crc_len; + + char *coder_attributes = seven_zip->coder_attributes; + + // input buffers and length + + u8 *compressed_data = (u8 *) out_full; + + SizeT compressed_data_len = aes_len; + + // output buffers and length + + unsigned char *decompressed_data; + + decompressed_data = (unsigned char *) hcmalloc (crc_len); + + SizeT decompressed_data_len = crc_len; + + int ret; + + if (data_type == 1) // LZMA1 { - crc = cpu_crc32_buffer ((u8 *) out_full, unpack_size); + ret = hc_lzma1_decompress (compressed_data, &compressed_data_len, decompressed_data, &decompressed_data_len, coder_attributes); } - else + else if (data_type == 7) // inflate using zlib (DEFLATE compression) { - u32 crc_len = seven_zip->crc_len; + ret = SZ_ERROR_DATA; - char *coder_attributes = seven_zip->coder_attributes; + z_stream inf; - // input buffers and length + inf.zalloc = Z_NULL; + inf.zfree = Z_NULL; + inf.opaque = Z_NULL; - u8 *compressed_data = (u8 *) out_full; + inf.avail_in = compressed_data_len; + inf.next_in = compressed_data; - SizeT compressed_data_len = aes_len; + inf.avail_out = decompressed_data_len; + inf.next_out = decompressed_data; - // output buffers and length + // inflate: - unsigned char *decompressed_data; + inflateInit2 (&inf, -MAX_WBITS); - decompressed_data = (unsigned char *) hcmalloc (crc_len); + int zlib_ret = inflate (&inf, Z_NO_FLUSH); - SizeT decompressed_data_len = crc_len; + inflateEnd (&inf); - int ret; - - if (data_type == 1) // LZMA1 + if ((zlib_ret == Z_OK) || (zlib_ret == Z_STREAM_END)) { - ret = hc_lzma1_decompress (compressed_data, &compressed_data_len, decompressed_data, &decompressed_data_len, coder_attributes); + ret = SZ_OK; } - else if (data_type == 7) // inflate using zlib (DEFLATE compression) - { - ret = SZ_ERROR_DATA; - - z_stream inf; - - inf.zalloc = Z_NULL; - inf.zfree = Z_NULL; - inf.opaque = Z_NULL; - - inf.avail_in = compressed_data_len; - inf.next_in = compressed_data; - - inf.avail_out = decompressed_data_len; - inf.next_out = decompressed_data; - - // inflate: - - inflateInit2 (&inf, -MAX_WBITS); - - int zlib_ret = inflate (&inf, Z_NO_FLUSH); - - inflateEnd (&inf); - - if ((zlib_ret == Z_OK) || (zlib_ret == Z_STREAM_END)) - { - ret = SZ_OK; - } - } - else // we only support LZMA2 in addition to LZMA1 - { - ret = hc_lzma2_decompress (compressed_data, &compressed_data_len, decompressed_data, &decompressed_data_len, coder_attributes); - } - - if (ret != SZ_OK) - { - hook_item->hook_success = 0; - - hcfree (decompressed_data); - - continue; - } - - crc = cpu_crc32_buffer (decompressed_data, crc_len); - - hcfree (decompressed_data); + } + else // we only support LZMA2 in addition to LZMA1 + { + ret = hc_lzma2_decompress (compressed_data, &compressed_data_len, decompressed_data, &decompressed_data_len, coder_attributes); } - if (crc == seven_zip_crc) - { - hook_item->hook_success = 1; - } - else + if (ret != SZ_OK) { hook_item->hook_success = 0; + + hcfree (decompressed_data); + + return; } + + crc = cpu_crc32_buffer (decompressed_data, crc_len); + + hcfree (decompressed_data); + } + + if (crc == seven_zip_crc) + { + hook_item->hook_success = 1; + } + else + { + hook_item->hook_success = 0; } } diff --git a/src/selftest.c b/src/selftest.c index 6265bed04..9e9e40f8e 100644 --- a/src/selftest.c +++ b/src/selftest.c @@ -455,7 +455,7 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_clEnqueueReadBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_hooks, CL_TRUE, 0, device_param->size_hooks, device_param->hooks_buf, 0, NULL, NULL) == -1) return -1; } - module_ctx->module_hook12 (device_param, hashes->st_hook_salts_buf, 0, 1); + module_ctx->module_hook12 (device_param, hashes->st_hook_salts_buf, 0, 0); if (device_param->is_cuda == true) { @@ -502,7 +502,7 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_clEnqueueReadBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_hooks, CL_TRUE, 0, device_param->size_hooks, device_param->hooks_buf, 0, NULL, NULL) == -1) return -1; } - module_ctx->module_hook23 (device_param, hashes->st_hook_salts_buf, 0, 1); + module_ctx->module_hook23 (device_param, hashes->st_hook_salts_buf, 0, 0); if (device_param->is_cuda == true) {