diff --git a/docs/changes.txt b/docs/changes.txt index a914583f5..115489cb5 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -13,10 +13,11 @@ ## Features ## -- Added support to building Universal macOS binary on Apple Silicon -- Added support to use --debug-mode in attack-mode 9 (Association Attack) - Added guess data to --status-json output - Added hex format for --separator option +- Added new backend support for Metal, the OpenCL replacement API on Apple +- Added support to building Universal macOS binary on Apple Silicon +- Added support to use --debug-mode in attack-mode 9 (Association Attack) ## ## Bugs diff --git a/docs/credits.txt b/docs/credits.txt index 268719f2c..bb0f95a7d 100644 --- a/docs/credits.txt +++ b/docs/credits.txt @@ -21,6 +21,7 @@ Gabriele "matrix" Gristina (@gm4tr1x) * Multiple kernel modules * Compressed wordlist feature * OpenCL Info feature +* Apple Metal Runtime API feature * Apple macOS port * Apple Silicon support * Universal binary on Apple Silicon diff --git a/include/backend.h b/include/backend.h index c7e7de0a1..2f2a58f9c 100644 --- a/include/backend.h +++ b/include/backend.h @@ -40,43 +40,51 @@ 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 generate_source_kernel_filename (const bool slow_candidates, const u32 attack_exec, const u32 attack_kern, const u32 kern_type, const u32 opti_type, char *shared_dir, char *source_file); -void generate_cached_kernel_filename (const bool slow_candidates, const u32 attack_exec, const u32 attack_kern, const u32 kern_type, const u32 opti_type, char *cache_dir, const char *device_name_chksum, char *cached_file); +void generate_cached_kernel_filename (const bool slow_candidates, const u32 attack_exec, const u32 attack_kern, const u32 kern_type, const u32 opti_type, char *cache_dir, const char *device_name_chksum, char *cached_file, bool is_metal); void generate_source_kernel_shared_filename (char *shared_dir, char *source_file); -void generate_cached_kernel_shared_filename (char *cache_dir, const char *device_name_chksum, char *cached_file); +void generate_cached_kernel_shared_filename (char *cache_dir, const char *device_name_chksum, char *cached_file, bool is_metal); void generate_source_kernel_mp_filename (const u32 opti_type, const u64 opts_type, char *shared_dir, char *source_file); -void generate_cached_kernel_mp_filename (const u32 opti_type, const u64 opts_type, char *cache_dir, const char *device_name_chksum, char *cached_file); +void generate_cached_kernel_mp_filename (const u32 opti_type, const u64 opts_type, char *cache_dir, const char *device_name_chksum, char *cached_file, bool is_metal); void generate_source_kernel_amp_filename (const u32 attack_kern, char *shared_dir, char *source_file); -void generate_cached_kernel_amp_filename (const u32 attack_kern, char *cache_dir, const char *device_name_chksum, char *cached_file); +void generate_cached_kernel_amp_filename (const u32 attack_kern, char *cache_dir, const char *device_name_chksum, char *cached_file, bool is_metal); -int gidd_to_pw_t (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 gidd, pw_t *pw); +int gidd_to_pw_t (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 gidd, pw_t *pw); -int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u32 highest_pw_len, const u64 pws_pos, const u64 pws_cnt, const u32 fast_iteration, const u32 salt_pos); +int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u32 highest_pw_len, const u64 pws_pos, const u64 pws_cnt, const u32 fast_iteration, const u32 salt_pos); -int run_cuda_kernel_atinit (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 num); -int run_cuda_kernel_utf8toutf16le (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 num); -int run_cuda_kernel_memset (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 offset, const u8 value, const u64 size); -int run_cuda_kernel_memset32 (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 offset, const u32 value, const u64 size); -int run_cuda_kernel_bzero (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 size); +int run_cuda_kernel_atinit (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 num); +int run_cuda_kernel_utf8toutf16le (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 num); +int run_cuda_kernel_memset (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 offset, const u8 value, const u64 size); +int run_cuda_kernel_memset32 (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 offset, const u32 value, const u64 size); +int run_cuda_kernel_bzero (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, CUdeviceptr buf, const u64 size); -int run_hip_kernel_atinit (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 num); -int run_hip_kernel_utf8toutf16le (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 num); -int run_hip_kernel_memset (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 offset, const u8 value, const u64 size); -int run_hip_kernel_memset32 (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 offset, const u32 value, const u64 size); -int run_hip_kernel_bzero (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 size); +int run_hip_kernel_atinit (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 num); +int run_hip_kernel_utf8toutf16le (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 num); +int run_hip_kernel_memset (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 offset, const u8 value, const u64 size); +int run_hip_kernel_memset32 (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 offset, const u32 value, const u64 size); +int run_hip_kernel_bzero (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, hipDeviceptr_t buf, const u64 size); -int run_opencl_kernel_atinit (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 num); -int run_opencl_kernel_utf8toutf16le (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 num); -int run_opencl_kernel_memset (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 offset, const u8 value, const u64 size); -int run_opencl_kernel_memset32 (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 offset, const u32 value, const u64 size); -int run_opencl_kernel_bzero (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 size); +#if defined (__APPLE__) +int run_metal_kernel_atinit (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, mtl_mem buf, const u64 num); +int run_metal_kernel_utf8toutf16le (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, mtl_mem buf, const u64 num); +int run_metal_kernel_memset (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, mtl_mem buf, const u64 offset, const u8 value, const u64 size); +int run_metal_kernel_memset32 (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, mtl_mem buf, const u64 offset, const u32 value, const u64 size); +int run_metal_kernel_bzero (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, mtl_mem buf, const u64 size); +#endif -int run_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u32 kern_run, const u64 pws_pos, const u64 num, const u32 event_update, const u32 iteration); -int run_kernel_mp (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u32 kern_run, const u64 num); -int run_kernel_tm (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param); -int run_kernel_amp (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 num); -int run_kernel_decompress (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 num); -int run_copy (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 pws_cnt); -int run_cracker (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 pws_pos, const u64 pws_cnt); +int run_opencl_kernel_atinit (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 num); +int run_opencl_kernel_utf8toutf16le (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 num); +int run_opencl_kernel_memset (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 offset, const u8 value, const u64 size); +int run_opencl_kernel_memset32 (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 offset, const u32 value, const u64 size); +int run_opencl_kernel_bzero (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 size); + +int run_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u32 kern_run, const u64 pws_pos, const u64 num, const u32 event_update, const u32 iteration); +int run_kernel_mp (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u32 kern_run, const u64 num); +int run_kernel_tm (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param); +int run_kernel_amp (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 num); +int run_kernel_decompress (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 num); +int run_copy (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 pws_cnt); +int run_cracker (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 pws_pos, const u64 pws_cnt); void *hook12_thread (void *p); void *hook23_thread (void *p); diff --git a/include/ext_metal.h b/include/ext_metal.h new file mode 100644 index 000000000..1bb1425f8 --- /dev/null +++ b/include/ext_metal.h @@ -0,0 +1,118 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#ifndef _EXT_METAL_H +#define _EXT_METAL_H + +#if defined (__APPLE__) + +#include +#include + +#define mtl_device_id id +#define mtl_command_queue id +#define mtl_function id +#define mtl_pipeline id +#define mtl_mem id +#define mtl_library id +#define mtl_command_buffer id +#define mtl_command_encoder id +#define mtl_blit_command_encoder id +#define mtl_compute_command_encoder id + +typedef enum metalDeviceAttribute +{ + MTL_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT = 1, + MTL_DEVICE_ATTRIBUTE_UNIFIED_MEMORY, + MTL_DEVICE_ATTRIBUTE_WARP_SIZE, + MTL_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, + MTL_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, + MTL_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK, + MTL_DEVICE_ATTRIBUTE_CLOCK_RATE, + MTL_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK, + MTL_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY, + MTL_DEVICE_ATTRIBUTE_MAX_TRANSFER_RATE, + MTL_DEVICE_ATTRIBUTE_HEADLESS, + MTL_DEVICE_ATTRIBUTE_LOW_POWER, + MTL_DEVICE_ATTRIBUTE_REMOVABLE, + MTL_DEVICE_ATTRIBUTE_REGISTRY_ID, + MTL_DEVICE_ATTRIBUTE_PHYSICAL_LOCATION, + MTL_DEVICE_ATTRIBUTE_LOCATION_NUMBER, + +} metalDeviceAttribute_t; + +typedef enum metalDeviceLocation +{ + // MTLDeviceLocationBuiltIn + // The GPU is built into the device + MTL_DEVICE_LOCATION_BUILTIN = 0, + + // MTLDeviceLocationSlot + // The GPU is connected to a slot inside the computer + MTL_DEVICE_LOCATION_SLOT = 1, + + // MTLDeviceLocationExternal + // The GPU is connected via an external interface, such as Thunderbolt + MTL_DEVICE_LOCATION_EXTERNAL = 2, + + // MTLDeviceLocationUnspecified + // The GPU's location is not specified or cannot be determined + MTL_DEVICE_LOCATION_UNSPECIFIED = 4294967295, + +} metalDeviceLocation_t; + +typedef struct hc_metal +{ + CFArrayRef devices; + +} hc_metal_t; + +typedef hc_metal_t MTL_PTR; + +int mtl_init (void *hashcat_ctx); +void mtl_close (void *hashcat_ctx); + +int hc_mtlRuntimeGetVersionString (void *hashcat_ctx, char *runtimeVersion_str, size_t *size); + +int hc_mtlDeviceGetCount (void *hashcat_ctx, int *count); +int hc_mtlDeviceGet (void *hashcat_ctx, mtl_device_id *metal_device, int ordinal); +int hc_mtlDeviceGetName (void *hashcat_ctx, char *name, size_t len, mtl_device_id metal_device); +int hc_mtlDeviceGetAttribute (void *hashcat_ctx, int *pi, metalDeviceAttribute_t attrib, mtl_device_id metal_device); +int hc_mtlDeviceTotalMem (void *hashcat_ctx, size_t *bytes, mtl_device_id metal_device); +int hc_mtlDeviceMaxMemAlloc (void *hashcat_ctx, size_t *bytes, mtl_device_id metal_device); +int hc_mtlMemGetInfo (void *hashcat_ctx, size_t *mem_free, size_t *mem_total); + +int hc_mtlCreateCommandQueue (void *hashcat_ctx, mtl_device_id metal_device, mtl_command_queue *command_queue); +int hc_mtlCreateBuffer (void *hashcat_ctx, mtl_device_id metal_device, size_t size, void *ptr, mtl_mem *metal_buffer); + +int hc_mtlCreateKernel (void *hashcat_ctx, mtl_device_id metal_device, mtl_library metal_library, const char *func_name, mtl_function *metal_function, mtl_pipeline *metal_pipeline); + +int hc_mtlGetMaxTotalThreadsPerThreadgroup (void *hashcat_ctx, mtl_pipeline metal_pipeline, unsigned int *maxTotalThreadsPerThreadgroup); +int hc_mtlGetThreadExecutionWidth (void *hashcat_ctx, mtl_pipeline metal_pipeline, unsigned int *threadExecutionWidth); + +// copy buffer +int hc_mtlMemcpyDtoD (void *hashcat_ctx, mtl_command_queue command_queue, mtl_mem buf_dst, size_t buf_dst_off, mtl_mem buf_src, size_t buf_src_off, size_t buf_size); +// write +int hc_mtlMemcpyHtoD (void *hashcat_ctx, mtl_command_queue command_queue, mtl_mem buf_dst, size_t buf_dst_off, const void *buf_src, size_t buf_size); +// read +int hc_mtlMemcpyDtoH (void *hashcat_ctx, mtl_command_queue command_queue, void *buf_dst, mtl_mem buf_src, size_t buf_src_off, size_t buf_size); + +int hc_mtlReleaseMemObject (void *hashcat_ctx, mtl_mem metal_buffer); +int hc_mtlReleaseFunction (void *hashcat_ctx, mtl_function metal_function); +int hc_mtlReleaseLibrary (void *hashcat_ctx, mtl_function metal_library); +int hc_mtlReleaseCommandQueue (void *hashcat_ctx, mtl_command_queue command_queue); +int hc_mtlReleaseDevice (void *hashcat_ctx, mtl_device_id metal_device); + +int hc_mtlCreateLibraryWithSource (void *hashcat_ctx, mtl_device_id metal_device, const char *kernel_sources, const char *build_options_buf, const char *include_path, mtl_library *metal_library); +int hc_mtlCreateLibraryWithFile (void *hashcat_ctx, mtl_device_id metal_device, const char *cached_file, mtl_library *metal_library); + +int hc_mtlEncodeComputeCommand_pre (void *hashcat_ctx, mtl_pipeline metal_pipeline, mtl_command_queue metal_command_queue, mtl_command_buffer *metal_command_buffer, mtl_command_encoder *metal_command_encoder); +int hc_mtlSetCommandEncoderArg (void *hashcat_ctx, mtl_command_encoder metal_command_encoder, size_t off, size_t idx, mtl_mem buf, void *host_data, size_t host_data_size); + +int hc_mtlEncodeComputeCommand (void *hashcat_ctx, mtl_command_encoder metal_command_encoder, mtl_command_buffer metal_command_buffer, size_t global_work_size, size_t local_work_size, double *ms); + +#endif // __APPLE__ + +#endif // _EXT_METAL_H diff --git a/include/types.h b/include/types.h index 94d2f1505..9fe03e76d 100644 --- a/include/types.h +++ b/include/types.h @@ -660,6 +660,9 @@ typedef enum user_options_defaults NONCE_ERROR_CORRECTIONS = 8, BACKEND_IGNORE_CUDA = false, BACKEND_IGNORE_HIP = false, + #if defined (__APPLE__) + BACKEND_IGNORE_METAL = false, + #endif BACKEND_IGNORE_OPENCL = false, BACKEND_INFO = false, BACKEND_VECTOR_WIDTH = 0, @@ -711,116 +714,117 @@ typedef enum user_options_map IDX_BACKEND_DEVICES = 'd', IDX_BACKEND_IGNORE_CUDA = 0xff01, IDX_BACKEND_IGNORE_HIP = 0xff02, - IDX_BACKEND_IGNORE_OPENCL = 0xff03, + IDX_BACKEND_IGNORE_METAL = 0xff03, + IDX_BACKEND_IGNORE_OPENCL = 0xff04, IDX_BACKEND_INFO = 'I', - IDX_BACKEND_VECTOR_WIDTH = 0xff04, - IDX_BENCHMARK_ALL = 0xff05, + IDX_BACKEND_VECTOR_WIDTH = 0xff05, + IDX_BENCHMARK_ALL = 0xff06, IDX_BENCHMARK = 'b', - IDX_BITMAP_MAX = 0xff06, - IDX_BITMAP_MIN = 0xff07, + IDX_BITMAP_MAX = 0xff07, + IDX_BITMAP_MIN = 0xff08, #ifdef WITH_BRAIN IDX_BRAIN_CLIENT = 'z', - IDX_BRAIN_CLIENT_FEATURES = 0xff08, - IDX_BRAIN_HOST = 0xff09, - IDX_BRAIN_PASSWORD = 0xff0a, - IDX_BRAIN_PORT = 0xff0b, - IDX_BRAIN_SERVER = 0xff0c, - IDX_BRAIN_SERVER_TIMER = 0xff0d, - IDX_BRAIN_SESSION = 0xff0e, - IDX_BRAIN_SESSION_WHITELIST = 0xff0f, + IDX_BRAIN_CLIENT_FEATURES = 0xff09, + IDX_BRAIN_HOST = 0xff0a, + IDX_BRAIN_PASSWORD = 0xff0b, + IDX_BRAIN_PORT = 0xff0c, + IDX_BRAIN_SERVER = 0xff0d, + IDX_BRAIN_SERVER_TIMER = 0xff0e, + IDX_BRAIN_SESSION = 0xff0f, + IDX_BRAIN_SESSION_WHITELIST = 0xff10, #endif - IDX_CPU_AFFINITY = 0xff10, + IDX_CPU_AFFINITY = 0xff11, IDX_CUSTOM_CHARSET_1 = '1', IDX_CUSTOM_CHARSET_2 = '2', IDX_CUSTOM_CHARSET_3 = '3', IDX_CUSTOM_CHARSET_4 = '4', - IDX_DEBUG_FILE = 0xff11, - IDX_DEBUG_MODE = 0xff12, - IDX_DEPRECATED_CHECK_DISABLE = 0xff13, - IDX_ENCODING_FROM = 0xff14, - IDX_ENCODING_TO = 0xff15, - IDX_HASH_INFO = 0xff16, - IDX_FORCE = 0xff17, - IDX_HWMON_DISABLE = 0xff18, - IDX_HWMON_TEMP_ABORT = 0xff19, + IDX_DEBUG_FILE = 0xff12, + IDX_DEBUG_MODE = 0xff13, + IDX_DEPRECATED_CHECK_DISABLE = 0xff14, + IDX_ENCODING_FROM = 0xff15, + IDX_ENCODING_TO = 0xff16, + IDX_HASH_INFO = 0xff17, + IDX_FORCE = 0xff18, + IDX_HWMON_DISABLE = 0xff19, + IDX_HWMON_TEMP_ABORT = 0xff1a, IDX_HASH_MODE = 'm', - IDX_HCCAPX_MESSAGE_PAIR = 0xff1a, + IDX_HCCAPX_MESSAGE_PAIR = 0xff1b, IDX_HELP = 'h', - IDX_HEX_CHARSET = 0xff1b, - IDX_HEX_SALT = 0xff1c, - IDX_HEX_WORDLIST = 0xff1d, - IDX_HOOK_THREADS = 0xff1e, - IDX_IDENTIFY = 0xff1f, + IDX_HEX_CHARSET = 0xff1c, + IDX_HEX_SALT = 0xff1d, + IDX_HEX_WORDLIST = 0xff1e, + IDX_HOOK_THREADS = 0xff1f, + IDX_IDENTIFY = 0xff20, IDX_INCREMENT = 'i', - IDX_INCREMENT_MAX = 0xff20, - IDX_INCREMENT_MIN = 0xff21, - IDX_INDUCTION_DIR = 0xff22, - IDX_KEEP_GUESSING = 0xff23, + IDX_INCREMENT_MAX = 0xff21, + IDX_INCREMENT_MIN = 0xff22, + IDX_INDUCTION_DIR = 0xff23, + IDX_KEEP_GUESSING = 0xff24, IDX_KERNEL_ACCEL = 'n', IDX_KERNEL_LOOPS = 'u', IDX_KERNEL_THREADS = 'T', - IDX_KEYBOARD_LAYOUT_MAPPING = 0xff24, - IDX_KEYSPACE = 0xff25, - IDX_LEFT = 0xff26, + IDX_KEYBOARD_LAYOUT_MAPPING = 0xff25, + IDX_KEYSPACE = 0xff26, + IDX_LEFT = 0xff27, IDX_LIMIT = 'l', - IDX_LOGFILE_DISABLE = 0xff27, - IDX_LOOPBACK = 0xff28, - IDX_MACHINE_READABLE = 0xff29, - IDX_MARKOV_CLASSIC = 0xff2a, - IDX_MARKOV_DISABLE = 0xff2b, - IDX_MARKOV_HCSTAT2 = 0xff2c, - IDX_MARKOV_INVERSE = 0xff2d, + IDX_LOGFILE_DISABLE = 0xff28, + IDX_LOOPBACK = 0xff29, + IDX_MACHINE_READABLE = 0xff2a, + IDX_MARKOV_CLASSIC = 0xff2b, + IDX_MARKOV_DISABLE = 0xff2c, + IDX_MARKOV_HCSTAT2 = 0xff2d, + IDX_MARKOV_INVERSE = 0xff2e, IDX_MARKOV_THRESHOLD = 't', - IDX_NONCE_ERROR_CORRECTIONS = 0xff2e, + IDX_NONCE_ERROR_CORRECTIONS = 0xff2f, IDX_OPENCL_DEVICE_TYPES = 'D', IDX_OPTIMIZED_KERNEL_ENABLE = 'O', IDX_MULTIPLY_ACCEL_DISABLE = 'M', - IDX_OUTFILE_AUTOHEX_DISABLE = 0xff2f, - IDX_OUTFILE_CHECK_DIR = 0xff30, - IDX_OUTFILE_CHECK_TIMER = 0xff31, - IDX_OUTFILE_FORMAT = 0xff32, + IDX_OUTFILE_AUTOHEX_DISABLE = 0xff30, + IDX_OUTFILE_CHECK_DIR = 0xff31, + IDX_OUTFILE_CHECK_TIMER = 0xff32, + IDX_OUTFILE_FORMAT = 0xff33, IDX_OUTFILE = 'o', - IDX_POTFILE_DISABLE = 0xff33, - IDX_POTFILE_PATH = 0xff34, - IDX_PROGRESS_ONLY = 0xff35, - IDX_QUIET = 0xff36, - IDX_REMOVE = 0xff37, - IDX_REMOVE_TIMER = 0xff38, - IDX_RESTORE = 0xff39, - IDX_RESTORE_DISABLE = 0xff3a, - IDX_RESTORE_FILE_PATH = 0xff3b, + IDX_POTFILE_DISABLE = 0xff34, + IDX_POTFILE_PATH = 0xff35, + IDX_PROGRESS_ONLY = 0xff36, + IDX_QUIET = 0xff37, + IDX_REMOVE = 0xff38, + IDX_REMOVE_TIMER = 0xff39, + IDX_RESTORE = 0xff3a, + IDX_RESTORE_DISABLE = 0xff3b, + IDX_RESTORE_FILE_PATH = 0xff3c, IDX_RP_FILE = 'r', - IDX_RP_GEN_FUNC_MAX = 0xff3c, - IDX_RP_GEN_FUNC_MIN = 0xff3d, - IDX_RP_GEN_FUNC_SEL = 0xff3e, + IDX_RP_GEN_FUNC_MAX = 0xff3d, + IDX_RP_GEN_FUNC_MIN = 0xff3e, + IDX_RP_GEN_FUNC_SEL = 0xff3f, IDX_RP_GEN = 'g', - IDX_RP_GEN_SEED = 0xff3f, + IDX_RP_GEN_SEED = 0xff40, IDX_RULE_BUF_L = 'j', IDX_RULE_BUF_R = 'k', - IDX_RUNTIME = 0xff40, - IDX_SCRYPT_TMTO = 0xff41, + IDX_RUNTIME = 0xff41, + IDX_SCRYPT_TMTO = 0xff42, IDX_SEGMENT_SIZE = 'c', - IDX_SELF_TEST_DISABLE = 0xff42, + IDX_SELF_TEST_DISABLE = 0xff43, IDX_SEPARATOR = 'p', - IDX_SESSION = 0xff43, - IDX_SHOW = 0xff44, + IDX_SESSION = 0xff44, + IDX_SHOW = 0xff45, IDX_SKIP = 's', IDX_SLOW_CANDIDATES = 'S', - IDX_SPEED_ONLY = 0xff45, - IDX_SPIN_DAMP = 0xff46, - IDX_STATUS = 0xff47, - IDX_STATUS_JSON = 0xff48, - IDX_STATUS_TIMER = 0xff49, - IDX_STDOUT_FLAG = 0xff4a, - IDX_STDIN_TIMEOUT_ABORT = 0xff4b, - IDX_TRUECRYPT_KEYFILES = 0xff4c, - IDX_USERNAME = 0xff4d, - IDX_VERACRYPT_KEYFILES = 0xff4e, - IDX_VERACRYPT_PIM_START = 0xff4f, - IDX_VERACRYPT_PIM_STOP = 0xff50, + IDX_SPEED_ONLY = 0xff46, + IDX_SPIN_DAMP = 0xff47, + IDX_STATUS = 0xff48, + IDX_STATUS_JSON = 0xff49, + IDX_STATUS_TIMER = 0xff4a, + IDX_STDOUT_FLAG = 0xff4b, + IDX_STDIN_TIMEOUT_ABORT = 0xff4c, + IDX_TRUECRYPT_KEYFILES = 0xff4d, + IDX_USERNAME = 0xff4e, + IDX_VERACRYPT_KEYFILES = 0xff4f, + IDX_VERACRYPT_PIM_START = 0xff50, + IDX_VERACRYPT_PIM_STOP = 0xff51, IDX_VERSION_LOWER = 'v', IDX_VERSION = 'V', - IDX_WORDLIST_AUTOHEX_DISABLE = 0xff51, + IDX_WORDLIST_AUTOHEX_DISABLE = 0xff52, IDX_WORKLOAD_PROFILE = 'w', } user_options_map_t; @@ -1100,6 +1104,7 @@ typedef struct hc_fp #include "ext_cuda.h" #include "ext_hip.h" #include "ext_OpenCL.h" +#include "ext_metal.h" typedef struct hc_device_param { @@ -1601,6 +1606,129 @@ typedef struct hc_device_param hipDeviceptr_t hip_d_st_esalts_buf; hipDeviceptr_t hip_d_kernel_param; + // API: opencl and metal + + bool is_apple_silicon; + + // API: metal + + bool is_metal; + + #if defined (__APPLE__) + + int mtl_major; + int mtl_minor; + + int device_physical_location; + int device_location_number; + int device_registryID; + int device_max_transfer_rate; + int device_is_headless; + int device_is_low_power; + int device_is_removable; + + int metal_warp_size; + + mtl_device_id metal_device; + mtl_command_queue metal_command_queue; + + mtl_library metal_library; + mtl_library metal_library_shared; + mtl_library metal_library_mp; + mtl_library metal_library_amp; + + mtl_function metal_function1; + mtl_function metal_function12; + mtl_function metal_function2p; + mtl_function metal_function2; + mtl_function metal_function2e; + mtl_function metal_function23; + mtl_function metal_function3; + mtl_function metal_function4; + mtl_function metal_function_init2; + mtl_function metal_function_loop2p; + mtl_function metal_function_loop2; + mtl_function metal_function_mp; + mtl_function metal_function_mp_l; + mtl_function metal_function_mp_r; + mtl_function metal_function_amp; + mtl_function metal_function_tm; + mtl_function metal_function_memset; + mtl_function metal_function_bzero; + mtl_function metal_function_atinit; + mtl_function metal_function_utf8toutf16le; + mtl_function metal_function_decompress; + mtl_function metal_function_aux1; + mtl_function metal_function_aux2; + mtl_function metal_function_aux3; + mtl_function metal_function_aux4; + + mtl_pipeline metal_pipeline1; + mtl_pipeline metal_pipeline12; + mtl_pipeline metal_pipeline2p; + mtl_pipeline metal_pipeline2; + mtl_pipeline metal_pipeline2e; + mtl_pipeline metal_pipeline23; + mtl_pipeline metal_pipeline3; + mtl_pipeline metal_pipeline4; + mtl_pipeline metal_pipeline_init2; + mtl_pipeline metal_pipeline_loop2p; + mtl_pipeline metal_pipeline_loop2; + mtl_pipeline metal_pipeline_mp; + mtl_pipeline metal_pipeline_mp_l; + mtl_pipeline metal_pipeline_mp_r; + mtl_pipeline metal_pipeline_amp; + mtl_pipeline metal_pipeline_tm; + mtl_pipeline metal_pipeline_memset; + mtl_pipeline metal_pipeline_bzero; + mtl_pipeline metal_pipeline_atinit; + mtl_pipeline metal_pipeline_utf8toutf16le; + mtl_pipeline metal_pipeline_decompress; + mtl_pipeline metal_pipeline_aux1; + mtl_pipeline metal_pipeline_aux2; + mtl_pipeline metal_pipeline_aux3; + mtl_pipeline metal_pipeline_aux4; + + mtl_mem metal_d_pws_buf; + mtl_mem metal_d_pws_amp_buf; + mtl_mem metal_d_pws_comp_buf; + mtl_mem metal_d_pws_idx; + mtl_mem metal_d_rules; + mtl_mem metal_d_rules_c; + mtl_mem metal_d_combs; + mtl_mem metal_d_combs_c; + mtl_mem metal_d_bfs; + mtl_mem metal_d_bfs_c; + mtl_mem metal_d_tm_c; + mtl_mem metal_d_bitmap_s1_a; + mtl_mem metal_d_bitmap_s1_b; + mtl_mem metal_d_bitmap_s1_c; + mtl_mem metal_d_bitmap_s1_d; + mtl_mem metal_d_bitmap_s2_a; + mtl_mem metal_d_bitmap_s2_b; + mtl_mem metal_d_bitmap_s2_c; + mtl_mem metal_d_bitmap_s2_d; + mtl_mem metal_d_plain_bufs; + mtl_mem metal_d_digests_buf; + mtl_mem metal_d_digests_shown; + mtl_mem metal_d_salt_bufs; + mtl_mem metal_d_esalt_bufs; + mtl_mem metal_d_tmps; + mtl_mem metal_d_hooks; + mtl_mem metal_d_result; + mtl_mem metal_d_extra0_buf; + mtl_mem metal_d_extra1_buf; + mtl_mem metal_d_extra2_buf; + mtl_mem metal_d_extra3_buf; + mtl_mem metal_d_root_css_buf; + mtl_mem metal_d_markov_css_buf; + mtl_mem metal_d_st_digests_buf; + mtl_mem metal_d_st_salts_buf; + mtl_mem metal_d_st_esalts_buf; + mtl_mem metal_d_kernel_param; + + #endif // __APPLE__ + // API: opencl bool is_opencl; @@ -1708,6 +1836,7 @@ typedef struct backend_ctx void *cuda; void *hip; + void *mtl; void *ocl; void *nvrtc; @@ -1715,6 +1844,7 @@ typedef struct backend_ctx int backend_device_from_cuda[DEVICES_MAX]; // from cuda device index to backend device index int backend_device_from_hip[DEVICES_MAX]; // from hip device index to backend device index + int backend_device_from_metal[DEVICES_MAX]; // from metal device index to backend device index int backend_device_from_opencl[DEVICES_MAX]; // from opencl device index to backend device index int backend_device_from_opencl_platform[CL_PLATFORMS_MAX][DEVICES_MAX]; // from opencl device index to backend device index (by platform) @@ -1725,6 +1855,8 @@ typedef struct backend_ctx int cuda_devices_active; int hip_devices_cnt; int hip_devices_active; + int metal_devices_cnt; + int metal_devices_active; int opencl_devices_cnt; int opencl_devices_active; @@ -1766,6 +1898,13 @@ typedef struct backend_ctx int hip_runtimeVersion; int hip_driverVersion; + // metal + + int rc_metal_init; + + unsigned int metal_runtimeVersion; + char *metal_runtimeVersionStr; + // opencl cl_platform_id *opencl_platforms; @@ -2169,6 +2308,7 @@ typedef struct user_options bool markov_inverse; bool backend_ignore_cuda; bool backend_ignore_hip; + bool backend_ignore_metal; bool backend_ignore_opencl; bool backend_info; bool optimized_kernel_enable; diff --git a/src/Makefile b/src/Makefile index 4a5d419da..a26f5598c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -331,7 +331,11 @@ CFLAGS_NATIVE += -DMISSING_CLOCK_GETTIME endif LFLAGS_NATIVE := $(LFLAGS) +LFLAGS_NATIVE += -framework CoreFoundation +LFLAGS_NATIVE += -framework CoreGraphics +LFLAGS_NATIVE += -framework Foundation LFLAGS_NATIVE += -framework IOKit +LFLAGS_NATIVE += -framework Metal LFLAGS_NATIVE += -lpthread LFLAGS_NATIVE += -liconv @@ -385,6 +389,10 @@ EMU_OBJS_ALL += emu_inc_cipher_aes emu_inc_cipher_camellia emu_inc_ci OBJS_ALL := affinity autotune backend benchmark bitmap bitops combinator common convert cpt cpu_crc32 debugfile dictstat dispatch dynloader event ext_ADL ext_cuda ext_hip ext_nvapi ext_nvml ext_nvrtc ext_hiprtc ext_OpenCL ext_sysfs_amdgpu ext_sysfs_cpu ext_iokit ext_lzma filehandling folder hashcat hashes hlfmt hwmon induct interface keyboard_layout locking logfile loopback memory monitor mpsp outfile_check outfile pidfile potfile restore rp rp_cpu selftest slow_candidates shared status stdout straight terminal thread timer tuningdb usage user_options wordlist $(EMU_OBJS_ALL) +ifeq ($(UNAME),Darwin) +OBJS_ALL += ext_metal +endif + ifeq ($(ENABLE_BRAIN),1) OBJS_ALL += brain endif @@ -585,6 +593,9 @@ uninstall: obj/%.NATIVE.o: src/%.c $(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $< -o $@ -fpic +obj/%.NATIVE.o: src/%.m + $(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $< -o $@ -fpic + ifeq ($(USE_SYSTEM_LZMA),0) obj/%.LZMA.NATIVE.o: $(DEPS_LZMA_PATH)/%.c $(CC) -c $(CCFLAGS) $(CFLAGS_NATIVE) $(CFLAGS_LZMA) $< -o $@ -fpic diff --git a/src/autotune.c b/src/autotune.c index bcbdd0eb3..55c829802 100644 --- a/src/autotune.c +++ b/src/autotune.c @@ -238,6 +238,13 @@ static int autotune (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (run_hip_kernel_atinit (hashcat_ctx, device_param, device_param->hip_d_pws_buf, kernel_power_max) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_atinit (hashcat_ctx, device_param, device_param->metal_d_pws_buf, kernel_power_max) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_atinit (hashcat_ctx, device_param, device_param->opencl_d_pws_buf, kernel_power_max) == -1) return -1; @@ -264,6 +271,13 @@ static int autotune (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyDtoDAsync (hashcat_ctx, device_param->hip_d_rules_c, device_param->hip_d_rules, MIN (kernel_loops_max, KERNEL_RULES) * sizeof (kernel_rule_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_rules_c, 0, device_param->metal_d_rules, 0, MIN (kernel_loops_max, KERNEL_RULES) * sizeof (kernel_rule_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueCopyBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_rules, device_param->opencl_d_rules_c, 0, 0, MIN (kernel_loops_max, KERNEL_RULES) * sizeof (kernel_rule_t), 0, NULL, NULL) == -1) return -1; @@ -477,6 +491,17 @@ static int autotune (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_tmps, device_param->size_tmps) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_pws_buf, device_param->size_pws) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_plain_bufs, device_param->size_plains) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_digests_shown, device_param->size_shown) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_result, device_param->size_results) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_tmps, device_param->size_tmps) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_bzero (hashcat_ctx, device_param, device_param->opencl_d_pws_buf, device_param->size_pws) == -1) return -1; diff --git a/src/backend.c b/src/backend.c index 0aa098130..3b7c9b27c 100644 --- a/src/backend.c +++ b/src/backend.c @@ -65,6 +65,12 @@ static bool is_same_device (const hc_device_param_t *src, const hc_device_param_ if ((src->is_hip == true) && (dst->is_hip == true)) return false; + #if defined (__APPLE__) + // Metal can't have aliases + + if ((src->is_metal == true) && (dst->is_metal == true)) return false; + #endif + // But OpenCL can have aliases if ((src->is_opencl == true) && (dst->is_opencl == true)) @@ -131,7 +137,13 @@ static int backend_ctx_find_alias_devices (hashcat_ctx_t *hashcat_ctx) if (alias_device->is_hip == true) continue; - // this lets native OpenCL runtime survive over generic OpenCL runtime + #if defined (__APPLE__) + // this lets Metal devices survive over OpenCL + + if (alias_device->is_metal == true) continue; + #endif + + // this lets native OpenCL runtime survive over generic OpenCL runtime if (alias_device->opencl_device_type & CL_DEVICE_TYPE_CPU) { @@ -164,6 +176,9 @@ static bool is_same_device_type (const hc_device_param_t *src, const hc_device_p { if (src->is_cuda != dst->is_cuda) return false; if (src->is_hip != dst->is_hip) return false; + #if defined (__APPLE__) + if (src->is_metal != dst->is_metal) return false; + #endif if (src->is_opencl != dst->is_opencl) return false; if (strcmp (src->device_name, dst->device_name) != 0) return false; @@ -655,7 +670,7 @@ void generate_source_kernel_filename (const bool slow_candidates, const u32 atta } } -void generate_cached_kernel_filename (const bool slow_candidates, const u32 attack_exec, const u32 attack_kern, const u32 kern_type, const u32 opti_type, char *cache_dir, const char *device_name_chksum, char *cached_file) +void generate_cached_kernel_filename (const bool slow_candidates, const u32 attack_exec, const u32 attack_kern, const u32 kern_type, const u32 opti_type, char *cache_dir, const char *device_name_chksum, char *cached_file, bool is_metal) { if (opti_type & OPTI_TYPE_OPTIMIZED_KERNEL) { @@ -663,23 +678,23 @@ void generate_cached_kernel_filename (const bool slow_candidates, const u32 atta { if (slow_candidates == true) { - snprintf (cached_file, 255, "%s/kernels/m%05d_a0-optimized.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a0-optimized.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); } else { if (attack_kern == ATTACK_KERN_STRAIGHT) - snprintf (cached_file, 255, "%s/kernels/m%05d_a0-optimized.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a0-optimized.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); else if (attack_kern == ATTACK_KERN_COMBI) - snprintf (cached_file, 255, "%s/kernels/m%05d_a1-optimized.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a1-optimized.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); else if (attack_kern == ATTACK_KERN_BF) - snprintf (cached_file, 255, "%s/kernels/m%05d_a3-optimized.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a3-optimized.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); else if (attack_kern == ATTACK_KERN_NONE) - snprintf (cached_file, 255, "%s/kernels/m%05d_a0-optimized.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a0-optimized.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); } } else { - snprintf (cached_file, 255, "%s/kernels/m%05d-optimized.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d-optimized.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); } } else @@ -688,23 +703,23 @@ void generate_cached_kernel_filename (const bool slow_candidates, const u32 atta { if (slow_candidates == true) { - snprintf (cached_file, 255, "%s/kernels/m%05d_a0-pure.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a0-pure.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); } else { if (attack_kern == ATTACK_KERN_STRAIGHT) - snprintf (cached_file, 255, "%s/kernels/m%05d_a0-pure.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a0-pure.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); else if (attack_kern == ATTACK_KERN_COMBI) - snprintf (cached_file, 255, "%s/kernels/m%05d_a1-pure.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a1-pure.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); else if (attack_kern == ATTACK_KERN_BF) - snprintf (cached_file, 255, "%s/kernels/m%05d_a3-pure.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a3-pure.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); else if (attack_kern == ATTACK_KERN_NONE) - snprintf (cached_file, 255, "%s/kernels/m%05d_a0-pure.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d_a0-pure.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); } } else { - snprintf (cached_file, 255, "%s/kernels/m%05d-pure.%s.kernel", cache_dir, (int) kern_type, device_name_chksum); + snprintf (cached_file, 255, "%s/kernels/m%05d-pure.%s.%s", cache_dir, (int) kern_type, device_name_chksum, (is_metal == true) ? "metallib" : "kernel"); } } } @@ -714,9 +729,9 @@ void generate_source_kernel_shared_filename (char *shared_dir, char *source_file snprintf (source_file, 255, "%s/OpenCL/shared.cl", shared_dir); } -void generate_cached_kernel_shared_filename (char *cache_dir, const char *device_name_chksum_amp_mp, char *cached_file) +void generate_cached_kernel_shared_filename (char *cache_dir, const char *device_name_chksum_amp_mp, char *cached_file, bool is_metal) { - snprintf (cached_file, 255, "%s/kernels/shared.%s.kernel", cache_dir, device_name_chksum_amp_mp); + snprintf (cached_file, 255, "%s/kernels/shared.%s.%s", cache_dir, device_name_chksum_amp_mp, (is_metal == true) ? "metallib" : "kernel"); } void generate_source_kernel_mp_filename (const u32 opti_type, const u64 opts_type, char *shared_dir, char *source_file) @@ -731,15 +746,15 @@ void generate_source_kernel_mp_filename (const u32 opti_type, const u64 opts_typ } } -void generate_cached_kernel_mp_filename (const u32 opti_type, const u64 opts_type, char *cache_dir, const char *device_name_chksum_amp_mp, char *cached_file) +void generate_cached_kernel_mp_filename (const u32 opti_type, const u64 opts_type, char *cache_dir, const char *device_name_chksum_amp_mp, char *cached_file, bool is_metal) { if ((opti_type & OPTI_TYPE_BRUTE_FORCE) && (opts_type & OPTS_TYPE_PT_GENERATE_BE)) { - snprintf (cached_file, 255, "%s/kernels/markov_be.%s.kernel", cache_dir, device_name_chksum_amp_mp); + snprintf (cached_file, 255, "%s/kernels/markov_be.%s.%s", cache_dir, device_name_chksum_amp_mp, (is_metal == true) ? "metallib" : "kernel"); } else { - snprintf (cached_file, 255, "%s/kernels/markov_le.%s.kernel", cache_dir, device_name_chksum_amp_mp); + snprintf (cached_file, 255, "%s/kernels/markov_le.%s.%s", cache_dir, device_name_chksum_amp_mp, (is_metal == true) ? "metallib" : "kernel"); } } @@ -748,9 +763,9 @@ void generate_source_kernel_amp_filename (const u32 attack_kern, char *shared_di snprintf (source_file, 255, "%s/OpenCL/amp_a%u.cl", shared_dir, attack_kern); } -void generate_cached_kernel_amp_filename (const u32 attack_kern, char *cache_dir, const char *device_name_chksum_amp_mp, char *cached_file) +void generate_cached_kernel_amp_filename (const u32 attack_kern, char *cache_dir, const char *device_name_chksum_amp_mp, char *cached_file, bool is_metal) { - snprintf (cached_file, 255, "%s/kernels/amp_a%u.%s.kernel", cache_dir, attack_kern, device_name_chksum_amp_mp); + snprintf (cached_file, 255, "%s/kernels/amp_a%u.%s.%s", cache_dir, attack_kern, device_name_chksum_amp_mp, (is_metal == true) ? "metallib" : "kernel"); } int gidd_to_pw_t (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const u64 gidd, pw_t *pw) @@ -779,6 +794,13 @@ int gidd_to_pw_t (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, c if (hc_hipStreamSynchronize (hashcat_ctx, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, &pw_idx, device_param->metal_d_pws_idx, gidd * sizeof (pw_idx_t), sizeof (pw_idx_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { /* blocking */ @@ -805,6 +827,13 @@ int gidd_to_pw_t (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, c if (hc_hipStreamSynchronize (hashcat_ctx, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, pw->i, device_param->metal_d_pws_comp_buf, off * sizeof (u32), cnt * sizeof (u32)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { /* blocking */ @@ -868,6 +897,13 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_tm_c, size_tm) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_tm_c, size_tm) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_bzero (hashcat_ctx, device_param, device_param->opencl_d_tm_c, size_tm) == -1) return -1; @@ -885,6 +921,13 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_hipMemcpyDtoDAsync (hashcat_ctx, device_param->hip_d_bfs_c, device_param->hip_d_tm_c, size_tm, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bfs_c, 0, device_param->metal_d_tm_c, 0, size_tm) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueCopyBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_tm_c, device_param->opencl_d_bfs_c, 0, 0, size_tm, 0, NULL, NULL) == -1) return -1; @@ -953,6 +996,13 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_hipMemcpyDtoDAsync (hashcat_ctx, device_param->hip_d_pws_buf, device_param->hip_d_pws_amp_buf, pws_cnt * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_buf, 0, device_param->metal_d_pws_amp_buf, 0, pws_cnt * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueCopyBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_amp_buf, device_param->opencl_d_pws_buf, 0, 0, pws_cnt * sizeof (pw_t), 0, NULL, NULL) == -1) return -1; @@ -978,6 +1028,13 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (run_hip_kernel_utf8toutf16le (hashcat_ctx, device_param, device_param->hip_d_pws_buf, pws_cnt) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_utf8toutf16le (hashcat_ctx, device_param, device_param->metal_d_pws_buf, pws_cnt) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_utf8toutf16le (hashcat_ctx, device_param, device_param->opencl_d_pws_buf, pws_cnt) == -1) return -1; @@ -1004,6 +1061,13 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_hipStreamSynchronize (hashcat_ctx, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, device_param->hooks_buf, device_param->metal_d_hooks, 0, pws_cnt * hashconfig->hook_size) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { /* blocking */ @@ -1052,6 +1116,13 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_hooks, device_param->hooks_buf, pws_cnt * hashconfig->hook_size, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_hooks, 0, device_param->hooks_buf, pws_cnt * hashconfig->hook_size) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_hooks, CL_FALSE, 0, pws_cnt * hashconfig->hook_size, device_param->hooks_buf, 0, NULL, NULL) == -1) return -1; @@ -1150,6 +1221,13 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_hipStreamSynchronize (hashcat_ctx, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, device_param->hooks_buf, device_param->metal_d_hooks, 0, pws_cnt * hashconfig->hook_size) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { /* blocking */ @@ -1198,6 +1276,13 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_hooks, device_param->hooks_buf, pws_cnt * hashconfig->hook_size, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_hooks, 0, device_param->hooks_buf, pws_cnt * hashconfig->hook_size) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_hooks, CL_FALSE, 0, pws_cnt * hashconfig->hook_size, device_param->hooks_buf, 0, NULL, NULL) == -1) return -1; @@ -1372,6 +1457,13 @@ int choose_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_hooks, pws_cnt * hashconfig->hook_size) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_hooks, pws_cnt * hashconfig->hook_size) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_bzero (hashcat_ctx, device_param, device_param->opencl_d_hooks, pws_cnt * hashconfig->hook_size) == -1) return -1; @@ -1591,6 +1683,140 @@ int run_hip_kernel_bzero (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_ return 0; } +#if defined (__APPLE__) +int run_metal_kernel_atinit (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, id buf, const u64 num) +{ + u64 num_elements = num; + + device_param->kernel_params_atinit_buf64[1] = num_elements; + + const u64 kernel_threads = device_param->kernel_wgs_atinit; + + num_elements = round_up_multiple_32 (num_elements, kernel_threads); + + const size_t global_work_size[3] = { num_elements, 1, 1 }; + const size_t local_work_size[3] = { kernel_threads, 1, 1 }; + + id metal_command_buffer = NULL; + id metal_command_encoder = NULL; + + if (hc_mtlEncodeComputeCommand_pre (hashcat_ctx, device_param->metal_pipeline_atinit, device_param->metal_command_queue, &metal_command_buffer, &metal_command_encoder) == -1) return -1; + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 0, buf, NULL, 0) == -1) return -1; + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 1, NULL, device_param->kernel_params_atinit[1], sizeof (u64)) == -1) return -1; + + double ms = 0; + + if (hc_mtlEncodeComputeCommand (hashcat_ctx, metal_command_encoder, metal_command_buffer, global_work_size[0], local_work_size[0], &ms) == -1) return -1; + + return 0; +} + +int run_metal_kernel_utf8toutf16le (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, id buf, const u64 num) +{ + u64 num_elements = num; + + device_param->kernel_params_utf8toutf16le_buf64[1] = num_elements; + + const u64 kernel_threads = device_param->kernel_wgs_utf8toutf16le; + + num_elements = round_up_multiple_32 (num_elements, kernel_threads); + + const size_t global_work_size[3] = { num_elements, 1, 1 }; + const size_t local_work_size[3] = { kernel_threads, 1, 1 }; + + id metal_command_buffer = NULL; + id metal_command_encoder = NULL; + + if (hc_mtlEncodeComputeCommand_pre (hashcat_ctx, device_param->metal_pipeline_utf8toutf16le, device_param->metal_command_queue, &metal_command_buffer, &metal_command_encoder) == -1) return -1; + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 0, buf, NULL, 0) == -1) return -1; + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 1, NULL, device_param->kernel_params_utf8toutf16le[1], sizeof (u64)) == -1) return -1; + + double ms = 0; + + if (hc_mtlEncodeComputeCommand (hashcat_ctx, metal_command_encoder, metal_command_buffer, global_work_size[0], local_work_size[0], &ms) == -1) return -1; + + return 0; +} + +int run_metal_kernel_bzero (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, id buf, const u64 size) +{ + const u64 num16d = size / 16; + const u64 num16m = size % 16; + + // with apple GPU clEnqueueWriteBuffer() return CL_INVALID_VALUE, workaround + + if (num16d) + { + const u64 kernel_threads = device_param->kernel_wgs_bzero; + + u64 num_elements = round_up_multiple_32 (num16d, kernel_threads); + + id metal_command_buffer = NULL; + id metal_command_encoder = NULL; + + if (hc_mtlEncodeComputeCommand_pre (hashcat_ctx, device_param->metal_pipeline_bzero, device_param->metal_command_queue, &metal_command_buffer, &metal_command_encoder) == -1) return -1; + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 0, buf, NULL, 0) == -1) return -1; + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 1, NULL, (void *) &num16d, sizeof (u64)) == -1) return -1; + + const size_t global_work_size[3] = { num_elements, 1, 1 }; + const size_t local_work_size[3] = { kernel_threads, 1, 1 }; + + double ms = 0; + + if (hc_mtlEncodeComputeCommand (hashcat_ctx, metal_command_encoder, metal_command_buffer, global_work_size[0], local_work_size[0], &ms) == -1) return -1; + } + + if (num16m) + { + if (device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE && \ + (device_param->opencl_device_vendor_id == VENDOR_ID_INTEL_SDK || device_param->opencl_device_vendor_id == VENDOR_ID_APPLE) && \ + device_param->opencl_device_type & CL_DEVICE_TYPE_GPU) + { + u8 *bzeros_apple = (u8 *) hccalloc (num16m, sizeof (u8)); + + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, buf, num16d * 16, bzeros_apple, num16m) == -1) return -1; + + hcfree (bzeros_apple); + } + else + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, buf, num16d * 16, bzeros, num16m) == -1) return -1; + } + } + + return 0; +} + +int run_metal_kernel_memset32 (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, mtl_mem buf, const u64 offset, const u32 value, const u64 size) +{ + int rc; + + const u64 N = size / 4; + + /* check that the size is multiple of element size */ + if (size % 4 != 0) + { + return CL_INVALID_VALUE; + } + + u32 *tmp = (u32 *) hcmalloc (size); + + for (u64 i = 0; i < N; i++) + { + tmp[i] = value; + } + + rc = hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, buf, offset, tmp, size); + + hcfree (tmp); + + return rc; +} +#endif // __APPLE__ + int run_opencl_kernel_atinit (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, cl_mem buf, const u64 num) { u64 num_elements = num; @@ -2037,6 +2263,137 @@ int run_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, con } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + mtl_command_encoder metal_command_encoder = NULL; + mtl_command_buffer metal_command_buffer = NULL; + mtl_pipeline metal_pipeline = NULL; + + switch (kern_run) + { + case KERN_RUN_1: metal_pipeline = device_param->metal_pipeline1; break; + case KERN_RUN_12: metal_pipeline = device_param->metal_pipeline12; break; + case KERN_RUN_2P: metal_pipeline = device_param->metal_pipeline2p; break; + case KERN_RUN_2: metal_pipeline = device_param->metal_pipeline2; break; + case KERN_RUN_2E: metal_pipeline = device_param->metal_pipeline2e; break; + case KERN_RUN_23: metal_pipeline = device_param->metal_pipeline23; break; + case KERN_RUN_3: metal_pipeline = device_param->metal_pipeline3; break; + case KERN_RUN_4: metal_pipeline = device_param->metal_pipeline4; break; + case KERN_RUN_INIT2: metal_pipeline = device_param->metal_pipeline_init2; break; + case KERN_RUN_LOOP2P: metal_pipeline = device_param->metal_pipeline_loop2p; break; + case KERN_RUN_LOOP2: metal_pipeline = device_param->metal_pipeline_loop2; break; + case KERN_RUN_AUX1: metal_pipeline = device_param->metal_pipeline_aux1; break; + case KERN_RUN_AUX2: metal_pipeline = device_param->metal_pipeline_aux2; break; + case KERN_RUN_AUX3: metal_pipeline = device_param->metal_pipeline_aux3; break; + case KERN_RUN_AUX4: metal_pipeline = device_param->metal_pipeline_aux4; break; + } + + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_kernel_param, 0, &device_param->kernel_param, device_param->size_kernel_params) == -1) return -1; + + if (hc_mtlEncodeComputeCommand_pre (hashcat_ctx, metal_pipeline, device_param->metal_command_queue, &metal_command_buffer, &metal_command_encoder) == -1) return -1; + + // all buffers must be allocated + int tmp_buf_cnt = 0; + mtl_mem tmp_buf[25] = { 0 }; + + for (u32 i = 0; i <= 24; i++) + { + // allocate fake buffer if NULL + if (device_param->kernel_params[i] == NULL) + { + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, sizeof (u8), NULL, &tmp_buf[tmp_buf_cnt]) == -1) return -1; + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, tmp_buf[tmp_buf_cnt], NULL, 0) == -1) return -1; + tmp_buf_cnt++; + } + else + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, device_param->kernel_params[i], NULL, 0) == -1) return -1; + } + } + + if (kernel_threads == 0) kernel_threads = 1; + + num_elements = round_up_multiple_32 (num_elements, kernel_threads); + + if (kern_run == KERN_RUN_1) + { + if (hashconfig->opti_type & OPTI_TYPE_SLOW_HASH_SIMD_INIT) + { + num_elements = CEILDIV (num_elements, device_param->vector_width); + } + } + else if (kern_run == KERN_RUN_2) + { + if (hashconfig->opti_type & OPTI_TYPE_SLOW_HASH_SIMD_LOOP) + { + num_elements = CEILDIV (num_elements, device_param->vector_width); + } + } + else if (kern_run == KERN_RUN_3) + { + if (hashconfig->opti_type & OPTI_TYPE_SLOW_HASH_SIMD_COMP) + { + num_elements = CEILDIV (num_elements, device_param->vector_width); + } + } + else if (kern_run == KERN_RUN_INIT2) + { + if (hashconfig->opti_type & OPTI_TYPE_SLOW_HASH_SIMD_INIT2) + { + num_elements = CEILDIV (num_elements, device_param->vector_width); + } + } + else if (kern_run == KERN_RUN_LOOP2) + { + if (hashconfig->opti_type & OPTI_TYPE_SLOW_HASH_SIMD_LOOP2) + { + num_elements = CEILDIV (num_elements, device_param->vector_width); + } + } + + num_elements = round_up_multiple_32 (num_elements, kernel_threads); + + const size_t global_work_size[3] = { num_elements, 1, 1 }; + const size_t local_work_size[3] = { kernel_threads, 1, 1 }; + + double ms = 0; + + const int rc_cc = hc_mtlEncodeComputeCommand (hashcat_ctx, metal_command_encoder, metal_command_buffer, global_work_size[0], local_work_size[0], &ms); + + if (rc_cc != -1) + { + float exec_ms = (float) ms; + + if (event_update) + { + u32 exec_pos = device_param->exec_pos; + + device_param->exec_msec[exec_pos] = exec_ms; + + exec_pos++; + + if (exec_pos == EXEC_CACHE) + { + exec_pos = 0; + } + + device_param->exec_pos = exec_pos; + } + } + + // release tmp_buf + + for (int i = 0; i < tmp_buf_cnt; i++) + { + hc_mtlReleaseMemObject (hashcat_ctx, tmp_buf[i]); + tmp_buf[i] = NULL; + } + + if (rc_cc == -1) return -1; + } + #endif // __APPLE__ + if (device_param->is_opencl == true) { cl_kernel opencl_kernel = NULL; @@ -2294,6 +2651,82 @@ int run_kernel_mp (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_hipLaunchKernel (hashcat_ctx, hip_function, num_elements, 1, 1, kernel_threads, 1, 1, 0, device_param->hip_stream, hip_args, NULL) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + id metal_command_encoder = NULL; + id metal_command_buffer = NULL; + id metal_pipeline = NULL; + + switch (kern_run) + { + case KERN_RUN_MP: metal_pipeline = device_param->metal_pipeline_mp; break; + case KERN_RUN_MP_R: metal_pipeline = device_param->metal_pipeline_mp_r; break; + case KERN_RUN_MP_L: metal_pipeline = device_param->metal_pipeline_mp_l; break; + } + + if (hc_mtlEncodeComputeCommand_pre (hashcat_ctx, metal_pipeline, device_param->metal_command_queue, &metal_command_buffer, &metal_command_encoder) == -1) return -1; + + if (kern_run == KERN_RUN_MP) + { + for (int i = 0; i < 3; i++) + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, device_param->kernel_params_mp[i], NULL, 0) == -1) return -1; + } + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 3, NULL, device_param->kernel_params_mp[3], sizeof (u64)) == -1) return -1; + + for (int i = 4; i < 8; i++) + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, NULL, device_param->kernel_params_mp[i], sizeof (u32)) == -1) return -1; + } + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 8, NULL, device_param->kernel_params_mp[8], sizeof (u64)) == -1) return -1; + } + else if (kern_run == KERN_RUN_MP_R) + { + for (int i = 0; i < 3; i++) + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, device_param->kernel_params_mp_r[i], NULL, 0) == -1) return -1; + } + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 3, NULL, device_param->kernel_params_mp_r[3], sizeof (u64)) == -1) return -1; + + for (int i = 4; i < 8; i++) + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, NULL, device_param->kernel_params_mp_r[i], sizeof (u32)) == -1) return -1; + } + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 8, NULL, device_param->kernel_params_mp_r[8], sizeof (u64)) == -1) return -1; + } + else if (kern_run == KERN_RUN_MP_L) + { + for (int i = 0; i < 3; i++) + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, device_param->kernel_params_mp_l[i], NULL, 0) == -1) return -1; + } + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 3, NULL, device_param->kernel_params_mp_l[3], sizeof (u64)) == -1) return -1; + + for (int i = 4; i < 9; i++) + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, NULL, device_param->kernel_params_mp_l[i], sizeof (u32)) == -1) return -1; + } + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 9, NULL, device_param->kernel_params_mp_l[9], sizeof (u64)) == -1) return -1; + } + + num_elements = round_up_multiple_32 (num_elements, kernel_threads); + + const size_t global_work_size[3] = { num_elements, 1, 1 }; + const size_t local_work_size[3] = { kernel_threads, 1, 1 }; + + double ms = 0; + + if (hc_mtlEncodeComputeCommand (hashcat_ctx, metal_command_encoder, metal_command_buffer, global_work_size[0], local_work_size[0], &ms) == -1) return -1; + } + #endif // __APPLE__ + if (device_param->is_opencl == true) { cl_kernel opencl_kernel = NULL; @@ -2362,6 +2795,29 @@ int run_kernel_tm (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) if (hc_hipLaunchKernel (hashcat_ctx, hip_function, num_elements / kernel_threads, 1, 1, kernel_threads, 1, 1, 0, device_param->hip_stream, device_param->kernel_params_tm, NULL) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + const size_t global_work_size[3] = { num_elements, 1, 1 }; + const size_t local_work_size[3] = { kernel_threads, 1, 1 }; + + id metal_command_encoder = NULL; + id metal_command_buffer = NULL; + id metal_pipeline = device_param->metal_pipeline_tm; + + if (hc_mtlEncodeComputeCommand_pre (hashcat_ctx, metal_pipeline, device_param->metal_command_queue, &metal_command_buffer, &metal_command_encoder) == -1) return -1; + + for (int i = 0; i < 2; i++) + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, device_param->kernel_params_tm[i], NULL, 0) == -1) return -1; + } + + double ms = 0; + + if (hc_mtlEncodeComputeCommand (hashcat_ctx, metal_command_encoder, metal_command_buffer, global_work_size[0], local_work_size[0], &ms) == -1) return -1; + } + #endif // __APPLE__ + if (device_param->is_opencl == true) { cl_kernel cuda_kernel = device_param->opencl_kernel_tm; @@ -2401,6 +2857,62 @@ int run_kernel_amp (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, if (hc_hipLaunchKernel (hashcat_ctx, hip_function, num_elements, 1, 1, kernel_threads, 1, 1, 0, device_param->hip_stream, device_param->kernel_params_amp, NULL) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + num_elements = round_up_multiple_32 (num_elements, kernel_threads); + + const size_t global_work_size[3] = { num_elements, 1, 1 }; + const size_t local_work_size[3] = { kernel_threads, 1, 1 }; + + id metal_command_encoder = NULL; + id metal_command_buffer = NULL; + id metal_pipeline = device_param->metal_pipeline_amp; + + if (hc_mtlEncodeComputeCommand_pre (hashcat_ctx, metal_pipeline, device_param->metal_command_queue, &metal_command_buffer, &metal_command_encoder) == -1) return -1; + + // all buffers must be allocated + int tmp_buf_cnt = 0; + + mtl_mem tmp_buf[5] = { 0 }; + + for (int i = 0; i < 5; i++) + { + // allocate fake buffer if NULL + if (device_param->kernel_params_amp[i] == NULL) + { + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, sizeof (u8), NULL, &tmp_buf[tmp_buf_cnt]) == -1) return -1; + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, tmp_buf[tmp_buf_cnt], NULL, 0) == -1) return -1; + + tmp_buf_cnt++; + } + else + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, device_param->kernel_params_amp[i], NULL, 0) == -1) return -1; + } + } + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 5, NULL, device_param->kernel_params_amp[5], sizeof (u32)) == -1) return -1; + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 6, NULL, device_param->kernel_params_amp[6], sizeof (u64)) == -1) return -1; + + double ms = 0; + + const int rc_cc = hc_mtlEncodeComputeCommand (hashcat_ctx, metal_command_encoder, metal_command_buffer, global_work_size[0], local_work_size[0], &ms); + + // release tmp_buf + + for (int i = 0; i < tmp_buf_cnt; i++) + { + hc_mtlReleaseMemObject (hashcat_ctx, tmp_buf[i]); + + tmp_buf[i] = NULL; + } + + if (rc_cc == -1) return -1; + } + #endif // __APPLE__ + if (device_param->is_opencl == true) { num_elements = round_up_multiple_64 (num_elements, kernel_threads); @@ -2444,6 +2956,32 @@ int run_kernel_decompress (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device if (hc_hipLaunchKernel (hashcat_ctx, hip_function, num_elements, 1, 1, kernel_threads, 1, 1, 0, device_param->hip_stream, device_param->kernel_params_decompress, NULL) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + num_elements = round_up_multiple_32 (num_elements, kernel_threads); + + const size_t global_work_size[3] = { num_elements, 1, 1 }; + const size_t local_work_size[3] = { kernel_threads, 1, 1 }; + + id metal_command_buffer = NULL; + id metal_command_encoder = NULL; + + if (hc_mtlEncodeComputeCommand_pre (hashcat_ctx, device_param->metal_pipeline_decompress, device_param->metal_command_queue, &metal_command_buffer, &metal_command_encoder) == -1) return -1; + + for (int i = 0; i < 3; i++) + { + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, i, device_param->kernel_params_decompress[i], NULL, 0) == -1) return -1; + } + + if (hc_mtlSetCommandEncoderArg (hashcat_ctx, metal_command_encoder, 0, 3, NULL, device_param->kernel_params_decompress[3], sizeof (u64)) == -1) return -1; + + double ms = 0; + + if (hc_mtlEncodeComputeCommand (hashcat_ctx, metal_command_encoder, metal_command_buffer, global_work_size[0], local_work_size[0], &ms) == -1) return -1; + } + #endif // __APPLE__ + if (device_param->is_opencl == true) { num_elements = round_up_multiple_64 (num_elements, kernel_threads); @@ -2512,6 +3050,22 @@ int run_copy (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_idx, 0, device_param->pws_idx, pws_cnt * sizeof (pw_idx_t)) == -1) return -1; + + const pw_idx_t *pw_idx = device_param->pws_idx + pws_cnt; + + const u32 off = pw_idx->off; + + if (off) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_comp_buf, 0, device_param->pws_comp, off * sizeof (u32)) == -1) return -1; + } + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_idx, CL_FALSE, 0, pws_cnt * sizeof (pw_idx_t), device_param->pws_idx, 0, NULL, NULL) == -1) return -1; @@ -2560,6 +3114,22 @@ int run_copy (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_idx, 0, device_param->pws_idx, pws_cnt * sizeof (pw_idx_t)) == -1) return -1; + + const pw_idx_t *pw_idx = device_param->pws_idx + pws_cnt; + + const u32 off = pw_idx->off; + + if (off) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_comp_buf, 0, device_param->pws_comp, off * sizeof (u32)) == -1) return -1; + } + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_idx, CL_FALSE, 0, pws_cnt * sizeof (pw_idx_t), device_param->pws_idx, 0, NULL, NULL) == -1) return -1; @@ -2642,6 +3212,22 @@ int run_copy (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_idx, 0, device_param->pws_idx, pws_cnt * sizeof (pw_idx_t)) == -1) return -1; + + const pw_idx_t *pw_idx = device_param->pws_idx + pws_cnt; + + const u32 off = pw_idx->off; + + if (off) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_comp_buf, 0, device_param->pws_comp, off * sizeof (u32)) == -1) return -1; + } + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_idx, CL_FALSE, 0, pws_cnt * sizeof (pw_idx_t), device_param->pws_idx, 0, NULL, NULL) == -1) return -1; @@ -2690,6 +3276,22 @@ int run_copy (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_idx, 0, device_param->pws_idx, pws_cnt * sizeof (pw_idx_t)) == -1) return -1; + + const pw_idx_t *pw_idx = device_param->pws_idx + pws_cnt; + + const u32 off = pw_idx->off; + + if (off) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_comp_buf, 0, device_param->pws_comp, off * sizeof (u32)) == -1) return -1; + } + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_idx, CL_FALSE, 0, pws_cnt * sizeof (pw_idx_t), device_param->pws_idx, 0, NULL, NULL) == -1) return -1; @@ -2736,6 +3338,22 @@ int run_copy (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, const } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_idx, 0, device_param->pws_idx, pws_cnt * sizeof (pw_idx_t)) == -1) return -1; + + const pw_idx_t *pw_idx = device_param->pws_idx + pws_cnt; + + const u32 off = pw_idx->off; + + if (off) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_comp_buf, 0, device_param->pws_comp, off * sizeof (u32)) == -1) return -1; + } + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_idx, CL_FALSE, 0, pws_cnt * sizeof (pw_idx_t), device_param->pws_idx, 0, NULL, NULL) == -1) return -1; @@ -2967,6 +3585,13 @@ int run_cracker (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, co if (hc_hipMemcpyDtoDAsync (hashcat_ctx, device_param->hip_d_rules_c, device_param->hip_d_rules + (innerloop_pos * sizeof (kernel_rule_t)), innerloop_left * sizeof (kernel_rule_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_rules_c, 0, device_param->metal_d_rules, innerloop_pos * sizeof (kernel_rule_t), innerloop_left * sizeof (kernel_rule_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueCopyBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_rules, device_param->opencl_d_rules_c, innerloop_pos * sizeof (kernel_rule_t), 0, innerloop_left * sizeof (kernel_rule_t), 0, NULL, NULL) == -1) return -1; @@ -3092,6 +3717,13 @@ int run_cracker (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, co if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_combs_c, device_param->combs_buf, innerloop_left * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_combs_c, 0, device_param->combs_buf, innerloop_left * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_combs_c, CL_FALSE, 0, innerloop_left * sizeof (pw_t), device_param->combs_buf, 0, NULL, NULL) == -1) return -1; @@ -3115,6 +3747,13 @@ int run_cracker (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, co if (hc_hipMemcpyDtoDAsync (hashcat_ctx, device_param->hip_d_combs_c, device_param->hip_d_combs, innerloop_left * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_combs_c, 0, device_param->metal_d_combs, 0, innerloop_left * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueCopyBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_combs, device_param->opencl_d_combs_c, 0, 0, innerloop_left * sizeof (pw_t), 0, NULL, NULL) == -1) return -1; @@ -3138,6 +3777,13 @@ int run_cracker (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, co if (hc_hipMemcpyDtoDAsync (hashcat_ctx, device_param->hip_d_combs_c, device_param->hip_d_combs, innerloop_left * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_combs_c, 0, device_param->metal_d_combs, 0, innerloop_left * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueCopyBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_combs, device_param->opencl_d_combs_c, 0, 0, innerloop_left * sizeof (pw_t), 0, NULL, NULL) == -1) return -1; @@ -3264,6 +3910,13 @@ int run_cracker (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, co if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_combs_c, device_param->combs_buf, innerloop_left * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_combs_c, 0, device_param->combs_buf, innerloop_left * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_combs_c, CL_FALSE, 0, innerloop_left * sizeof (pw_t), device_param->combs_buf, 0, NULL, NULL) == -1) return -1; @@ -3287,6 +3940,13 @@ int run_cracker (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, co if (hc_hipMemcpyDtoDAsync (hashcat_ctx, device_param->hip_d_combs_c, device_param->hip_d_combs, innerloop_left * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_combs_c, 0, device_param->metal_d_combs, 0, innerloop_left * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueCopyBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_combs, device_param->opencl_d_combs_c, 0, 0, innerloop_left * sizeof (pw_t), 0, NULL, NULL) == -1) return -1; @@ -3312,6 +3972,13 @@ int run_cracker (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, co if (hc_hipMemcpyDtoDAsync (hashcat_ctx, device_param->hip_d_bfs_c, device_param->hip_d_bfs, innerloop_left * sizeof (bf_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bfs_c, 0, device_param->metal_d_bfs, 0, innerloop_left * sizeof (bf_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueCopyBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_bfs, device_param->opencl_d_bfs_c, 0, 0, innerloop_left * sizeof (bf_t), 0, NULL, NULL) == -1) return -1; @@ -3720,6 +4387,44 @@ int backend_ctx_init (hashcat_ctx_t *hashcat_ctx) } } + /** + * Init Metal runtime + */ + + int rc_metal_init = -1; + + #if defined (__APPLE__) + if (user_options->backend_ignore_metal == false) + { + MTL_PTR *mtl = (MTL_PTR *) hcmalloc (sizeof (MTL_PTR)); + + backend_ctx->mtl = mtl; + + rc_metal_init = mtl_init (hashcat_ctx); + + if (rc_metal_init == 0) + { + size_t version_len = 0; + + if (hc_mtlRuntimeGetVersionString (hashcat_ctx, NULL, &version_len) == -1) return -1; + + if (version_len == 0) return -1; + + backend_ctx->metal_runtimeVersionStr = (char *) hcmalloc (version_len + 1); + + if (hc_mtlRuntimeGetVersionString (hashcat_ctx, backend_ctx->metal_runtimeVersionStr, &version_len) == -1) return -1; + } + else + { + rc_metal_init = -1; + + backend_ctx->rc_metal_init = rc_metal_init; + + mtl_close (hashcat_ctx); + } + } + #endif // __APPLE__ + /** * Load and map OpenCL library calls */ @@ -3743,9 +4448,9 @@ int backend_ctx_init (hashcat_ctx_t *hashcat_ctx) * return if both CUDA and OpenCL initialization failed */ - if ((rc_cuda_init == -1) && (rc_hip_init == -1) && (rc_ocl_init == -1)) + if ((rc_cuda_init == -1) && (rc_hip_init == -1) && (rc_ocl_init == -1) && (rc_metal_init == -1)) { - event_log_error (hashcat_ctx, "ATTENTION! No OpenCL, HIP or CUDA installation found."); + event_log_error (hashcat_ctx, "ATTENTION! No OpenCL, Metal, HIP or CUDA installation found."); event_log_warning (hashcat_ctx, "You are probably missing the CUDA, HIP or OpenCL runtime installation."); event_log_warning (hashcat_ctx, NULL); @@ -3973,7 +4678,7 @@ int backend_ctx_init (hashcat_ctx_t *hashcat_ctx) if (IGNORE_DEVICE_NOT_FOUND) { - backend_ctx_t *backend_ctx = hashcat_ctx->backend_ctx; + //backend_ctx_t *backend_ctx = hashcat_ctx->backend_ctx; OCL_PTR *ocl = (OCL_PTR *) backend_ctx->ocl; @@ -4068,9 +4773,13 @@ int backend_ctx_init (hashcat_ctx_t *hashcat_ctx) * Final checks */ - if ((backend_ctx->cuda == NULL) && (backend_ctx->hip == NULL) && (backend_ctx->ocl == NULL)) + if ((backend_ctx->cuda == NULL) && (backend_ctx->hip == NULL) && (backend_ctx->ocl == NULL) && (backend_ctx->mtl == NULL)) { - event_log_error (hashcat_ctx, "ATTENTION! No OpenCL-compatible, HIP-compatible or CUDA-compatible platform found."); + #if defined (__APPLE__) + event_log_error (hashcat_ctx, "ATTENTION! No OpenCL, Metal, HIP or CUDA compatible platform found."); + #else + event_log_error (hashcat_ctx, "ATTENTION! No OpenCL, HIP or CUDA compatible platform found."); + #endif event_log_warning (hashcat_ctx, "You are probably missing the OpenCL, CUDA or HIP runtime installation."); event_log_warning (hashcat_ctx, NULL); @@ -4187,9 +4896,9 @@ int backend_ctx_devices_init (hashcat_ctx_t *hashcat_ctx, const int comptime) device_param->is_cuda = true; device_param->is_hip = false; + device_param->is_metal = false; device_param->is_opencl = false; - device_param->use_opencl12 = false; device_param->use_opencl20 = false; device_param->use_opencl21 = false; @@ -4442,16 +5151,22 @@ int backend_ctx_devices_init (hashcat_ctx_t *hashcat_ctx, const int comptime) if (device_param->sm_major < 5) { - if (user_options->quiet == false) event_log_warning (hashcat_ctx, "* Device #%u: This hardware has outdated CUDA compute capability (%u.%u).", device_id + 1, device_param->sm_major, device_param->sm_minor); - if (user_options->quiet == false) event_log_warning (hashcat_ctx, " For modern OpenCL performance, upgrade to hardware that supports"); - if (user_options->quiet == false) event_log_warning (hashcat_ctx, " CUDA compute capability version 5.0 (Maxwell) or higher."); + if (user_options->quiet == false) + { + event_log_warning (hashcat_ctx, "* Device #%u: This hardware has outdated CUDA compute capability (%u.%u).", device_id + 1, device_param->sm_major, device_param->sm_minor); + event_log_warning (hashcat_ctx, " For modern OpenCL performance, upgrade to hardware that supports"); + event_log_warning (hashcat_ctx, " CUDA compute capability version 5.0 (Maxwell) or higher."); + } } if (device_param->kernel_exec_timeout != 0) { - if (user_options->quiet == false) event_log_advice (hashcat_ctx, "* Device #%u: WARNING! Kernel exec timeout is not disabled.", device_id + 1); - if (user_options->quiet == false) event_log_advice (hashcat_ctx, " This may cause \"CL_OUT_OF_RESOURCES\" or related errors."); - if (user_options->quiet == false) event_log_advice (hashcat_ctx, " To disable the timeout, see: https://hashcat.net/q/timeoutpatch"); + if (user_options->quiet == false) + { + event_log_advice (hashcat_ctx, "* Device #%u: WARNING! Kernel exec timeout is not disabled.", device_id + 1); + event_log_advice (hashcat_ctx, " This may cause \"CL_OUT_OF_RESOURCES\" or related errors."); + event_log_advice (hashcat_ctx, " To disable the timeout, see: https://hashcat.net/q/timeoutpatch"); + } } } @@ -4566,6 +5281,7 @@ int backend_ctx_devices_init (hashcat_ctx_t *hashcat_ctx, const int comptime) device_param->is_cuda = false; device_param->is_hip = true; + device_param->is_metal = false; device_param->is_opencl = false; device_param->use_opencl12 = false; @@ -4826,16 +5542,22 @@ int backend_ctx_devices_init (hashcat_ctx_t *hashcat_ctx, const int comptime) if (device_param->sm_major < 5) { - if (user_options->quiet == false) event_log_warning (hashcat_ctx, "* Device #%u: This hardware has outdated CUDA compute capability (%u.%u).", device_id + 1, device_param->sm_major, device_param->sm_minor); - if (user_options->quiet == false) event_log_warning (hashcat_ctx, " For modern OpenCL performance, upgrade to hardware that supports"); - if (user_options->quiet == false) event_log_warning (hashcat_ctx, " CUDA compute capability version 5.0 (Maxwell) or higher."); + if (user_options->quiet == false) + { + event_log_warning (hashcat_ctx, "* Device #%u: This hardware has outdated CUDA compute capability (%u.%u).", device_id + 1, device_param->sm_major, device_param->sm_minor); + event_log_warning (hashcat_ctx, " For modern OpenCL performance, upgrade to hardware that supports"); + event_log_warning (hashcat_ctx, " CUDA compute capability version 5.0 (Maxwell) or higher."); + } } if (device_param->kernel_exec_timeout != 0) { - if (user_options->quiet == false) event_log_advice (hashcat_ctx, "* Device #%u: WARNING! Kernel exec timeout is not disabled.", device_id + 1); - if (user_options->quiet == false) event_log_advice (hashcat_ctx, " This may cause \"CL_OUT_OF_RESOURCES\" or related errors."); - if (user_options->quiet == false) event_log_advice (hashcat_ctx, " To disable the timeout, see: https://hashcat.net/q/timeoutpatch"); + if (user_options->quiet == false) + { + event_log_advice (hashcat_ctx, "* Device #%u: WARNING! Kernel exec timeout is not disabled.", device_id + 1); + event_log_advice (hashcat_ctx, " This may cause \"CL_OUT_OF_RESOURCES\" or related errors."); + event_log_advice (hashcat_ctx, " To disable the timeout, see: https://hashcat.net/q/timeoutpatch"); + } } } @@ -7179,50 +7901,23 @@ static bool load_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_p hcfree (build_log); } - if (CL_rc == -1) return false; - - // workaround opencl issue with Apple Silicon - - if (strncmp (device_param->device_name, "Apple M", 7) != 0) + if (rc_nvrtcCompileProgram == -1) { - cl_program t2[1]; + event_log_error (hashcat_ctx, "* Device #%u: Kernel %s build failed.", device_param->device_id + 1, source_file); - t2[0] = p1; - - cl_program fin; - - if (hc_clLinkProgram (hashcat_ctx, device_param->opencl_context, 1, &device_param->opencl_device, NULL, 1, t2, NULL, NULL, &fin) == -1) return false; - - // it seems errors caused by clLinkProgram() do not go into CL_PROGRAM_BUILD - // I couldn't find any information on the web explaining how else to retrieve the error messages from the linker - - *opencl_program = fin; - - hc_clReleaseProgram (hashcat_ctx, p1); + return false; } - if (cache_disable == false) - { - size_t binary_size; + size_t binary_size = 0; - if (hc_clGetProgramInfo (hashcat_ctx, *opencl_program, CL_PROGRAM_BINARY_SIZES, sizeof (size_t), &binary_size, NULL) == -1) return false; + if (hc_nvrtcGetPTXSize (hashcat_ctx, program, &binary_size) == -1) return false; - char *binary = (char *) hcmalloc (binary_size); + char *binary = (char *) hcmalloc (binary_size); - if (hc_clGetProgramInfo (hashcat_ctx, *opencl_program, CL_PROGRAM_BINARIES, sizeof (char *), &binary, NULL) == -1) return false; + if (hc_nvrtcGetPTX (hashcat_ctx, program, binary) == -1) return false; - if (write_kernel_binary (hashcat_ctx, cached_file, binary, binary_size) == false) return false; + if (hc_nvrtcDestroyProgram (hashcat_ctx, &program) == -1) return false; - hcfree (binary); - } - } - } - else - { - if (read_kernel_binary (hashcat_ctx, cached_file, kernel_lengths, kernel_sources) == false) return false; - - if (device_param->is_cuda == true) - { #define LOG_SIZE 8192 char *mod_info_log = (char *) hcmalloc (LOG_SIZE + 1); @@ -7259,7 +7954,82 @@ static bool load_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_p mod_cnt++; } - if (hc_cuModuleLoadDataEx (hashcat_ctx, cuda_module, kernel_sources[0], mod_cnt, mod_opts, mod_vals) == -1) + #if defined (WITH_CUBIN) + + char *jit_info_log = (char *) hcmalloc (LOG_SIZE + 1); + char *jit_error_log = (char *) hcmalloc (LOG_SIZE + 1); + + int jit_cnt = 6; + + CUjit_option jit_opts[7]; + void *jit_vals[7]; + + jit_opts[0] = CU_JIT_TARGET_FROM_CUCONTEXT; + jit_vals[0] = (void *) 0; + + jit_opts[1] = CU_JIT_LOG_VERBOSE; + jit_vals[1] = (void *) 1; + + jit_opts[2] = CU_JIT_INFO_LOG_BUFFER; + jit_vals[2] = (void *) jit_info_log; + + jit_opts[3] = CU_JIT_INFO_LOG_BUFFER_SIZE_BYTES; + jit_vals[3] = (void *) LOG_SIZE; + + jit_opts[4] = CU_JIT_ERROR_LOG_BUFFER; + jit_vals[4] = (void *) jit_error_log; + + jit_opts[5] = CU_JIT_ERROR_LOG_BUFFER_SIZE_BYTES; + jit_vals[5] = (void *) LOG_SIZE; + + if (hashconfig->opti_type & OPTI_TYPE_REGISTER_LIMIT) + { + jit_opts[6] = CU_JIT_MAX_REGISTERS; + jit_vals[6] = (void *) 128; + + jit_cnt++; + } + + CUlinkState state; + + if (hc_cuLinkCreate (hashcat_ctx, jit_cnt, jit_opts, jit_vals, &state) == -1) + { + event_log_error (hashcat_ctx, "* Device #%u: Kernel %s link failed. Error Log:", device_param->device_id + 1, source_file); + event_log_error (hashcat_ctx, "%s", jit_error_log); + event_log_error (hashcat_ctx, NULL); + + return false; + } + + if (hc_cuLinkAddData (hashcat_ctx, state, CU_JIT_INPUT_PTX, binary, binary_size, kernel_name, 0, NULL, NULL) == -1) + { + event_log_error (hashcat_ctx, "* Device #%u: Kernel %s link failed. Error Log:", device_param->device_id + 1, source_file); + event_log_error (hashcat_ctx, "%s", jit_error_log); + event_log_error (hashcat_ctx, NULL); + + return false; + } + + void *cubin = NULL; + + size_t cubin_size = 0; + + if (hc_cuLinkComplete (hashcat_ctx, state, &cubin, &cubin_size) == -1) + { + event_log_error (hashcat_ctx, "* Device #%u: Kernel %s link failed. Error Log:", device_param->device_id + 1, source_file); + event_log_error (hashcat_ctx, "%s", jit_error_log); + event_log_error (hashcat_ctx, NULL); + + return false; + } + + #if defined (DEBUG) + event_log_info (hashcat_ctx, "* Device #%u: Kernel %s link successful. Info Log:", device_param->device_id + 1, source_file); + event_log_info (hashcat_ctx, "%s", jit_info_log); + event_log_info (hashcat_ctx, NULL); + #endif + + if (hc_cuModuleLoadDataEx (hashcat_ctx, cuda_module, cubin, mod_cnt, mod_opts, mod_vals) == -1) { event_log_error (hashcat_ctx, "* Device #%u: Kernel %s load failed. Error Log:", device_param->device_id + 1, source_file); event_log_error (hashcat_ctx, "%s", mod_error_log); @@ -7274,12 +8044,132 @@ static bool load_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_p event_log_info (hashcat_ctx, NULL); #endif + if (cache_disable == false) + { + if (write_kernel_binary (hashcat_ctx, cached_file, cubin, cubin_size) == false) return false; + } + + if (hc_cuLinkDestroy (hashcat_ctx, state) == -1) return false; + + hcfree (jit_info_log); + hcfree (jit_error_log); + + #else + + if (hc_cuModuleLoadDataEx (hashcat_ctx, cuda_module, binary, mod_cnt, mod_opts, mod_vals) == -1) + { + event_log_error (hashcat_ctx, "* Device #%u: Kernel %s load failed. Error Log:", device_param->device_id + 1, source_file); + event_log_error (hashcat_ctx, "%s", mod_error_log); + event_log_error (hashcat_ctx, NULL); + + return false; + } + + #if defined (DEBUG) + event_log_info (hashcat_ctx, "* Device #%u: Kernel %s load successful. Info Log:", device_param->device_id + 1, source_file); + event_log_info (hashcat_ctx, "%s", mod_info_log); + event_log_info (hashcat_ctx, NULL); + #endif + + if (cache_disable == false) + { + if (write_kernel_binary (hashcat_ctx, cached_file, binary, binary_size) == false) return false; + } + + #endif + hcfree (mod_info_log); hcfree (mod_error_log); + + hcfree (binary); } if (device_param->is_hip == true) { + hiprtcProgram program; + + if (hc_hiprtcCreateProgram (hashcat_ctx, &program, kernel_sources[0], kernel_name, 0, NULL, NULL) == -1) return false; + + char **hiprtc_options = (char **) hccalloc (6 + strlen (build_options_buf) + 1, sizeof (char *)); // ... + + //hiprtc_options[0] = "--restrict"; + //hiprtc_options[1] = "--device-as-default-execution-space"; + //hiprtc_options[2] = "--gpu-architecture"; + + hc_asprintf (&hiprtc_options[0], "--gpu-max-threads-per-block=%d", (user_options->kernel_threads_chgd == true) ? user_options->kernel_threads : device_param->kernel_threads_max); + + /* 4.3 linux + hiprtc_options[1] = "-I"; + hiprtc_options[2] = "/opt/rocm/hip/bin/include"; + hiprtc_options[3] = "-I"; + hiprtc_options[4] = "/opt/rocm/include"; + hiprtc_options[5] = "-I"; + */ + + hiprtc_options[1] = "-nocudainc"; + hiprtc_options[2] = "-nocudalib"; + hiprtc_options[3] = ""; + hiprtc_options[4] = ""; + + // untested but it should work + #if defined (_WIN) || defined (__CYGWIN__) || defined (__MSYS__) + hc_asprintf (&hiprtc_options[5], "-D INCLUDE_PATH=%s", "OpenCL"); + #else + hc_asprintf (&hiprtc_options[5], "-D INCLUDE_PATH=%s", folder_config->cpath_real); + #endif + + char *hiprtc_options_string = hcstrdup (build_options_buf); + + const int num_options = 6 + hiprtc_make_options_array_from_string (hiprtc_options_string, hiprtc_options + 6); + + const int rc_hiprtcCompileProgram = hc_hiprtcCompileProgram (hashcat_ctx, program, num_options, (const char * const *) hiprtc_options); + + hcfree (hiprtc_options_string); + hcfree (hiprtc_options); + + size_t build_log_size = 0; + + hc_hiprtcGetProgramLogSize (hashcat_ctx, program, &build_log_size); + + #if defined (DEBUG) + if ((build_log_size > 1) || (rc_hiprtcCompileProgram == -1)) + #else + if (rc_hiprtcCompileProgram == -1) + #endif + { + char *build_log = (char *) hcmalloc (build_log_size + 1); + + if (hc_hiprtcGetProgramLog (hashcat_ctx, program, build_log) == -1) + { + hcfree (build_log); + + return false; + } + + build_log[build_log_size] = 0; + + puts (build_log); + + hcfree (build_log); + } + + if (rc_hiprtcCompileProgram == -1) + { + event_log_error (hashcat_ctx, "* Device #%u: Kernel %s build failed.", device_param->device_id + 1, source_file); + + return false; + } + + size_t binary_size = 0; + + if (hc_hiprtcGetCodeSize (hashcat_ctx, program, &binary_size) == -1) return false; + + char *binary = (char *) hcmalloc (binary_size); + + if (hc_hiprtcGetCode (hashcat_ctx, program, binary) == -1) return false; + + if (hc_hiprtcDestroyProgram (hashcat_ctx, &program) == -1) return false; + #define LOG_SIZE 8192 char *mod_info_log = (char *) hcmalloc (LOG_SIZE + 1); @@ -7308,7 +8198,7 @@ static bool load_kernel (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_p mod_opts[5] = hipJitOptionErrorLogBufferSizeBytes; mod_vals[5] = (void *) LOG_SIZE; - if (hc_hipModuleLoadDataEx (hashcat_ctx, hip_module, kernel_sources[0], mod_cnt, mod_opts, mod_vals) == -1) + if (hc_hipModuleLoadDataEx (hashcat_ctx, hip_module, binary, mod_cnt, mod_opts, mod_vals) == -1) { event_log_error (hashcat_ctx, "* Device #%u: Kernel %s load failed. Error Log:", device_param->device_id + 1, source_file); event_log_error (hashcat_ctx, "%s", mod_error_log); @@ -8421,6 +9311,313 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_preferred_wgs_multiple_utf8toutf16le = device_param->hip_warp_size; } + if (device_param->is_opencl == true) + { + // GPU memset + + if (hc_clCreateKernel (hashcat_ctx, device_param->opencl_program_shared, "gpu_memset", &device_param->opencl_kernel_memset) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_memset"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_cuda_kernel_wgs (hashcat_ctx, device_param->cuda_function_memset, &device_param->kernel_wgs_memset) == -1) return -1; + + if (get_cuda_kernel_local_mem_size (hashcat_ctx, device_param->cuda_function_memset, &device_param->kernel_local_mem_size_memset) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_memset = device_param->device_local_mem_size - device_param->kernel_local_mem_size_memset; + + device_param->kernel_preferred_wgs_multiple_memset = device_param->cuda_warp_size; + + // GPU bzero + + if (hc_cuModuleGetFunction (hashcat_ctx, &device_param->cuda_function_bzero, device_param->cuda_module_shared, "gpu_bzero") == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_bzero"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_cuda_kernel_wgs (hashcat_ctx, device_param->cuda_function_bzero, &device_param->kernel_wgs_bzero) == -1) return -1; + + if (get_cuda_kernel_local_mem_size (hashcat_ctx, device_param->cuda_function_bzero, &device_param->kernel_local_mem_size_bzero) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_bzero = device_param->device_local_mem_size - device_param->kernel_local_mem_size_bzero; + + device_param->kernel_preferred_wgs_multiple_bzero = device_param->cuda_warp_size; + + // GPU autotune init + + if (hc_cuModuleGetFunction (hashcat_ctx, &device_param->cuda_function_atinit, device_param->cuda_module_shared, "gpu_atinit") == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_atinit"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_cuda_kernel_wgs (hashcat_ctx, device_param->cuda_function_atinit, &device_param->kernel_wgs_atinit) == -1) return -1; + + if (get_cuda_kernel_local_mem_size (hashcat_ctx, device_param->cuda_function_atinit, &device_param->kernel_local_mem_size_atinit) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_atinit = device_param->device_local_mem_size - device_param->kernel_local_mem_size_atinit; + + device_param->kernel_preferred_wgs_multiple_atinit = device_param->cuda_warp_size; + + // CL_rc = hc_clSetKernelArg (hashcat_ctx, device_param->opencl_kernel_atinit, 0, sizeof (cl_mem), device_param->kernel_params_atinit[0]); if (CL_rc == -1) return -1; + // CL_rc = hc_clSetKernelArg (hashcat_ctx, device_param->opencl_kernel_atinit, 1, sizeof (cl_ulong), device_param->kernel_params_atinit[1]); if (CL_rc == -1) return -1; + + // GPU decompress + + if (hc_cuModuleGetFunction (hashcat_ctx, &device_param->cuda_function_decompress, device_param->cuda_module_shared, "gpu_decompress") == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_decompress"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_cuda_kernel_wgs (hashcat_ctx, device_param->cuda_function_decompress, &device_param->kernel_wgs_decompress) == -1) return -1; + + if (get_cuda_kernel_local_mem_size (hashcat_ctx, device_param->cuda_function_decompress, &device_param->kernel_local_mem_size_decompress) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_decompress = device_param->device_local_mem_size - device_param->kernel_local_mem_size_decompress; + + device_param->kernel_preferred_wgs_multiple_decompress = device_param->cuda_warp_size; + + // GPU utf8 to utf16le conversion + + if (hc_cuModuleGetFunction (hashcat_ctx, &device_param->cuda_function_utf8toutf16le, device_param->cuda_module_shared, "gpu_utf8_to_utf16") == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_utf8_to_utf16"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_cuda_kernel_wgs (hashcat_ctx, device_param->cuda_function_utf8toutf16le, &device_param->kernel_wgs_utf8toutf16le) == -1) return -1; + + if (get_cuda_kernel_local_mem_size (hashcat_ctx, device_param->cuda_function_utf8toutf16le, &device_param->kernel_local_mem_size_utf8toutf16le) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_utf8toutf16le = device_param->device_local_mem_size - device_param->kernel_local_mem_size_utf8toutf16le; + + device_param->kernel_preferred_wgs_multiple_utf8toutf16le = device_param->cuda_warp_size; + } + + if (device_param->is_hip == true) + { + // GPU memset + + if (hc_hipModuleGetFunction (hashcat_ctx, &device_param->hip_function_memset, device_param->hip_module_shared, "gpu_memset") == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_memset"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_hip_kernel_wgs (hashcat_ctx, device_param->hip_function_memset, &device_param->kernel_wgs_memset) == -1) return -1; + + if (get_hip_kernel_local_mem_size (hashcat_ctx, device_param->hip_function_memset, &device_param->kernel_local_mem_size_memset) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_memset = device_param->device_local_mem_size - device_param->kernel_local_mem_size_memset; + + device_param->kernel_preferred_wgs_multiple_memset = device_param->hip_warp_size; + + // GPU bzero + + if (hc_hipModuleGetFunction (hashcat_ctx, &device_param->hip_function_bzero, device_param->hip_module_shared, "gpu_bzero") == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_bzero"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_hip_kernel_wgs (hashcat_ctx, device_param->hip_function_bzero, &device_param->kernel_wgs_bzero) == -1) return -1; + + if (get_hip_kernel_local_mem_size (hashcat_ctx, device_param->hip_function_bzero, &device_param->kernel_local_mem_size_bzero) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_bzero = device_param->device_local_mem_size - device_param->kernel_local_mem_size_bzero; + + device_param->kernel_preferred_wgs_multiple_bzero = device_param->hip_warp_size; + + // GPU autotune init + + if (hc_hipModuleGetFunction (hashcat_ctx, &device_param->hip_function_atinit, device_param->hip_module_shared, "gpu_atinit") == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_atinit"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_hip_kernel_wgs (hashcat_ctx, device_param->hip_function_atinit, &device_param->kernel_wgs_atinit) == -1) return -1; + + if (get_hip_kernel_local_mem_size (hashcat_ctx, device_param->hip_function_atinit, &device_param->kernel_local_mem_size_atinit) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_atinit = device_param->device_local_mem_size - device_param->kernel_local_mem_size_atinit; + + device_param->kernel_preferred_wgs_multiple_atinit = device_param->hip_warp_size; + + // CL_rc = hc_clSetKernelArg (hashcat_ctx, device_param->opencl_kernel_atinit, 0, sizeof (cl_mem), device_param->kernel_params_atinit[0]); if (CL_rc == -1) return -1; + // CL_rc = hc_clSetKernelArg (hashcat_ctx, device_param->opencl_kernel_atinit, 1, sizeof (cl_ulong), device_param->kernel_params_atinit[1]); if (CL_rc == -1) return -1; + + // GPU decompress + + if (hc_hipModuleGetFunction (hashcat_ctx, &device_param->hip_function_decompress, device_param->hip_module_shared, "gpu_decompress") == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_decompress"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_hip_kernel_wgs (hashcat_ctx, device_param->hip_function_decompress, &device_param->kernel_wgs_decompress) == -1) return -1; + + if (get_hip_kernel_local_mem_size (hashcat_ctx, device_param->hip_function_decompress, &device_param->kernel_local_mem_size_decompress) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_decompress = device_param->device_local_mem_size - device_param->kernel_local_mem_size_decompress; + + device_param->kernel_preferred_wgs_multiple_decompress = device_param->hip_warp_size; + + // GPU utf8 to utf16le conversion + + if (hc_hipModuleGetFunction (hashcat_ctx, &device_param->hip_function_utf8toutf16le, device_param->hip_module_shared, "gpu_utf8_to_utf16") == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_utf8_to_utf16"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (get_hip_kernel_wgs (hashcat_ctx, device_param->hip_function_utf8toutf16le, &device_param->kernel_wgs_utf8toutf16le) == -1) return -1; + + if (get_hip_kernel_local_mem_size (hashcat_ctx, device_param->hip_function_utf8toutf16le, &device_param->kernel_local_mem_size_utf8toutf16le) == -1) return -1; + + device_param->kernel_dynamic_local_mem_size_utf8toutf16le = device_param->device_local_mem_size - device_param->kernel_local_mem_size_utf8toutf16le; + + device_param->kernel_preferred_wgs_multiple_utf8toutf16le = device_param->hip_warp_size; + } + + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + // GPU memset + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_shared, "gpu_memset", &device_param->metal_function_memset, &device_param->metal_pipeline_memset) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_memset"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_memset, &device_param->kernel_wgs_memset) == -1) return -1; + + device_param->kernel_local_mem_size_memset = 0; + device_param->kernel_dynamic_local_mem_size_memset = 0; + device_param->kernel_preferred_wgs_multiple_memset = device_param->metal_warp_size; + + // GPU bzero + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_shared, "gpu_bzero", &device_param->metal_function_bzero, &device_param->metal_pipeline_bzero) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_bzero"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_bzero, &device_param->kernel_wgs_bzero) == -1) return -1; + + device_param->kernel_local_mem_size_bzero = 0; + device_param->kernel_dynamic_local_mem_size_bzero = 0; + device_param->kernel_preferred_wgs_multiple_bzero = device_param->metal_warp_size; + + // GPU autotune init + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_shared, "gpu_atinit", &device_param->metal_function_atinit, &device_param->metal_pipeline_atinit) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_atinit"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_atinit, &device_param->kernel_wgs_atinit) == -1) return -1; + + device_param->kernel_local_mem_size_atinit = 0; + device_param->kernel_dynamic_local_mem_size_atinit = 0; + device_param->kernel_preferred_wgs_multiple_atinit = device_param->metal_warp_size; + + // GPU decompress + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_shared, "gpu_decompress", &device_param->metal_function_decompress, &device_param->metal_pipeline_decompress) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_decompress"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_decompress, &device_param->kernel_wgs_decompress) == -1) return -1; + + device_param->kernel_local_mem_size_decompress = 0; + device_param->kernel_dynamic_local_mem_size_decompress = 0; + device_param->kernel_preferred_wgs_multiple_decompress = device_param->metal_warp_size; + + // GPU utf8 to utf16le conversion + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_shared, "gpu_utf8_to_utf16", &device_param->metal_function_utf8toutf16le, &device_param->metal_pipeline_utf8toutf16le) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "gpu_utf8_to_utf16"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_utf8toutf16le, &device_param->kernel_wgs_utf8toutf16le) == -1) return -1; + + device_param->kernel_local_mem_size_utf8toutf16le = 0; + device_param->kernel_dynamic_local_mem_size_utf8toutf16le = 0; + device_param->kernel_preferred_wgs_multiple_utf8toutf16le = device_param->metal_warp_size; + } + #endif + if (device_param->is_opencl == true) { // GPU memset @@ -8588,10 +9785,11 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) const u32 extra_value = (user_options->attack_mode == ATTACK_MODE_ASSOCIATION) ? ATTACK_MODE_ASSOCIATION : ATTACK_MODE_NONE; - const size_t dnclen = snprintf (device_name_chksum, HCBUFSIZ_TINY, "%d-%d-%d-%d-%u-%s-%s-%s-%d-%u-%u-%u-%s", + const size_t dnclen = snprintf (device_name_chksum, HCBUFSIZ_TINY, "%d-%d-%d-%u-%d-%u-%s-%s-%s-%d-%u-%u-%u-%s", backend_ctx->comptime, backend_ctx->cuda_driver_version, backend_ctx->hip_runtimeVersion, + backend_ctx->metal_runtimeVersion, device_param->is_opencl, device_param->opencl_platform_vendor_id, device_param->device_name, @@ -8603,8 +9801,7 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) (user_options->kernel_threads_chgd == true) ? user_options->kernel_threads : device_param->kernel_threads_max, build_options_module_buf); - md5_ctx_t md5_ctx; - + memset (&md5_ctx, 0, sizeof (md5_ctx_t)); md5_init (&md5_ctx); md5_update (&md5_ctx, (u32 *) device_name_chksum, dnclen); md5_final (&md5_ctx); @@ -8632,13 +9829,17 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) char cached_file[256] = { 0 }; - generate_cached_kernel_filename (user_options->slow_candidates, hashconfig->attack_exec, user_options_extra->attack_kern, kern_type, hashconfig->opti_type, folder_config->cache_dir, device_name_chksum, cached_file); + generate_cached_kernel_filename (user_options->slow_candidates, hashconfig->attack_exec, user_options_extra->attack_kern, kern_type, hashconfig->opti_type, folder_config->cache_dir, device_name_chksum, cached_file, device_param->is_metal); /** * load kernel */ - const bool rc_load_kernel = load_kernel (hashcat_ctx, device_param, "main_kernel", source_file, cached_file, build_options_module_buf, cache_disable, &device_param->opencl_program, &device_param->cuda_module, &device_param->hip_module); + #if defined (__APPLE__) + const bool rc_load_kernel = load_kernel (hashcat_ctx, device_param, "main_kernel", source_file, cached_file, build_options_module_buf, cache_disable, &device_param->opencl_program, &device_param->cuda_module, &device_param->hip_module, &device_param->metal_library); + #else + const bool rc_load_kernel = load_kernel (hashcat_ctx, device_param, "main_kernel", source_file, cached_file, build_options_module_buf, cache_disable, &device_param->opencl_program, &device_param->cuda_module, &device_param->hip_module, NULL); + #endif if (rc_load_kernel == false) { @@ -8685,9 +9886,13 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) char cached_file[256] = { 0 }; - generate_cached_kernel_mp_filename (hashconfig->opti_type, hashconfig->opts_type, folder_config->cache_dir, device_name_chksum_amp_mp, cached_file); + generate_cached_kernel_mp_filename (hashconfig->opti_type, hashconfig->opts_type, folder_config->cache_dir, device_name_chksum_amp_mp, cached_file, device_param->is_metal); - const bool rc_load_kernel = load_kernel (hashcat_ctx, device_param, "mp_kernel", source_file, cached_file, build_options_buf, cache_disable, &device_param->opencl_program_mp, &device_param->cuda_module_mp, &device_param->hip_module_mp); + #if defined (__APPLE__) + const bool rc_load_kernel = load_kernel (hashcat_ctx, device_param, "mp_kernel", source_file, cached_file, build_options_buf, cache_disable, &device_param->opencl_program_mp, &device_param->cuda_module_mp, &device_param->hip_module_mp, &device_param->metal_library_mp); + #else + const bool rc_load_kernel = load_kernel (hashcat_ctx, device_param, "mp_kernel", source_file, cached_file, build_options_buf, cache_disable, &device_param->opencl_program_mp, &device_param->cuda_module_mp, &device_param->hip_module_mp, NULL); + #endif if (rc_load_kernel == false) { @@ -8734,9 +9939,13 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) char cached_file[256] = { 0 }; - generate_cached_kernel_amp_filename (user_options_extra->attack_kern, folder_config->cache_dir, device_name_chksum_amp_mp, cached_file); + generate_cached_kernel_amp_filename (user_options_extra->attack_kern, folder_config->cache_dir, device_name_chksum_amp_mp, cached_file, device_param->is_metal); - const bool rc_load_kernel = load_kernel (hashcat_ctx, device_param, "amp_kernel", source_file, cached_file, build_options_buf, cache_disable, &device_param->opencl_program_amp, &device_param->cuda_module_amp, &device_param->hip_module_amp); + #if defined (__APPLE__) + const bool rc_load_kernel = load_kernel (hashcat_ctx, device_param, "amp_kernel", source_file, cached_file, build_options_buf, cache_disable, &device_param->opencl_program_amp, &device_param->cuda_module_amp, &device_param->hip_module_amp, &device_param->metal_library_amp); + #else + const bool rc_load_kernel = load_kernel (hashcat_ctx, device_param, "amp_kernel", source_file, cached_file, build_options_buf, cache_disable, &device_param->opencl_program_amp, &device_param->cuda_module_amp, &device_param->hip_module_amp, NULL); + #endif if (rc_load_kernel == false) { @@ -9036,6 +10245,116 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, bitmap_ctx->bitmap_size, NULL, &device_param->metal_d_bitmap_s1_a) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, bitmap_ctx->bitmap_size, NULL, &device_param->metal_d_bitmap_s1_b) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, bitmap_ctx->bitmap_size, NULL, &device_param->metal_d_bitmap_s1_c) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, bitmap_ctx->bitmap_size, NULL, &device_param->metal_d_bitmap_s1_d) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, bitmap_ctx->bitmap_size, NULL, &device_param->metal_d_bitmap_s2_a) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, bitmap_ctx->bitmap_size, NULL, &device_param->metal_d_bitmap_s2_b) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, bitmap_ctx->bitmap_size, NULL, &device_param->metal_d_bitmap_s2_c) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, bitmap_ctx->bitmap_size, NULL, &device_param->metal_d_bitmap_s2_d) == -1) return -1; + + // shared + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_plains, NULL, &device_param->metal_d_plain_bufs) == -1) return -1; + + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_digests, NULL, &device_param->metal_d_digests_buf) == -1) return -1; + + // shared + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_shown, NULL, &device_param->metal_d_digests_shown) == -1) return -1; + + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_salts, NULL, &device_param->metal_d_salt_bufs) == -1) return -1; + + // shared + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_results, NULL, &device_param->metal_d_result) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_extra_buffer / 4, NULL, &device_param->metal_d_extra0_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_extra_buffer / 4, NULL, &device_param->metal_d_extra1_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_extra_buffer / 4, NULL, &device_param->metal_d_extra2_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_extra_buffer / 4, NULL, &device_param->metal_d_extra3_buf) == -1) return -1; + + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_st_digests, NULL, &device_param->metal_d_st_digests_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_st_salts, NULL, &device_param->metal_d_st_salts_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_kernel_params, NULL, &device_param->metal_d_kernel_param) == -1) return -1; + + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bitmap_s1_a, 0, bitmap_ctx->bitmap_s1_a, bitmap_ctx->bitmap_size) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bitmap_s1_b, 0, bitmap_ctx->bitmap_s1_b, bitmap_ctx->bitmap_size) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bitmap_s1_c, 0, bitmap_ctx->bitmap_s1_c, bitmap_ctx->bitmap_size) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bitmap_s1_d, 0, bitmap_ctx->bitmap_s1_d, bitmap_ctx->bitmap_size) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bitmap_s2_a, 0, bitmap_ctx->bitmap_s2_a, bitmap_ctx->bitmap_size) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bitmap_s2_b, 0, bitmap_ctx->bitmap_s2_b, bitmap_ctx->bitmap_size) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bitmap_s2_c, 0, bitmap_ctx->bitmap_s2_c, bitmap_ctx->bitmap_size) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bitmap_s2_d, 0, bitmap_ctx->bitmap_s2_d, bitmap_ctx->bitmap_size) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_digests_buf, 0, hashes->digests_buf, size_digests) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_salt_bufs, 0, hashes->salts_buf, size_salts) == -1) return -1; + + /** + * special buffers + */ + + if (user_options->slow_candidates == true) + { + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_rules_c, NULL, &device_param->metal_d_rules_c) == -1) return -1; + } + else + { + if (user_options_extra->attack_kern == ATTACK_KERN_STRAIGHT) + { + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_rules, NULL, &device_param->metal_d_rules) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_rules_c, NULL, &device_param->metal_d_rules_c) == -1) return -1; + + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_rules, 0, straight_ctx->kernel_rules_buf, size_rules) == -1) return -1; + } + else if (user_options_extra->attack_kern == ATTACK_KERN_COMBI) + { + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_combs, NULL, &device_param->metal_d_combs) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_combs, NULL, &device_param->metal_d_combs_c) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_root_css, NULL, &device_param->metal_d_root_css_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_markov_css, NULL, &device_param->metal_d_markov_css_buf) == -1) return -1; + } + else if (user_options_extra->attack_kern == ATTACK_KERN_BF) + { + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_bfs, NULL, &device_param->metal_d_bfs) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_bfs, NULL, &device_param->metal_d_bfs_c) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_tm, NULL, &device_param->metal_d_tm_c) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_root_css, NULL, &device_param->metal_d_root_css_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_markov_css, NULL, &device_param->metal_d_markov_css_buf) == -1) return -1; + } + } + + if (size_esalts) + { + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_esalts, NULL, &device_param->metal_d_esalt_bufs) == -1) return -1; + + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_esalt_bufs, 0, hashes->esalts_buf, size_esalts) == -1) return -1; + } + + if (hashconfig->st_hash != NULL) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_st_digests_buf, 0, hashes->st_digests_buf, size_st_digests) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_st_salts_buf, 0, hashes->st_salts_buf, size_st_salts) == -1) return -1; + + if (size_esalts) + { + // gpu only + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_st_esalts, NULL, &device_param->metal_d_st_esalts_buf) == -1) return -1; + + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_st_esalts_buf, 0, hashes->st_esalts_buf, size_st_esalts) == -1) return -1; + } + } + } + #endif // __APPLE__ + if (device_param->is_opencl == true) { if (hc_clCreateBuffer (hashcat_ctx, device_param->opencl_context, CL_MEM_READ_ONLY, bitmap_ctx->bitmap_size, NULL, &device_param->opencl_d_bitmap_s1_a) == -1) return -1; @@ -9205,6 +10524,37 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_params[24] = &device_param->hip_d_kernel_param; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params[ 0] = NULL; // device_param->metal_d_pws_buf; + device_param->kernel_params[ 1] = device_param->metal_d_rules_c; + device_param->kernel_params[ 2] = device_param->metal_d_combs_c; + device_param->kernel_params[ 3] = device_param->metal_d_bfs_c; + device_param->kernel_params[ 4] = NULL; // device_param->metal_d_tmps; + device_param->kernel_params[ 5] = NULL; // device_param->metal_d_hooks; + device_param->kernel_params[ 6] = device_param->metal_d_bitmap_s1_a; + device_param->kernel_params[ 7] = device_param->metal_d_bitmap_s1_b; + device_param->kernel_params[ 8] = device_param->metal_d_bitmap_s1_c; + device_param->kernel_params[ 9] = device_param->metal_d_bitmap_s1_d; + device_param->kernel_params[10] = device_param->metal_d_bitmap_s2_a; + device_param->kernel_params[11] = device_param->metal_d_bitmap_s2_b; + device_param->kernel_params[12] = device_param->metal_d_bitmap_s2_c; + device_param->kernel_params[13] = device_param->metal_d_bitmap_s2_d; + device_param->kernel_params[14] = device_param->metal_d_plain_bufs; + device_param->kernel_params[15] = device_param->metal_d_digests_buf; + device_param->kernel_params[16] = device_param->metal_d_digests_shown; + device_param->kernel_params[17] = device_param->metal_d_salt_bufs; + device_param->kernel_params[18] = device_param->metal_d_esalt_bufs; + device_param->kernel_params[19] = device_param->metal_d_result; + device_param->kernel_params[20] = device_param->metal_d_extra0_buf; + device_param->kernel_params[21] = device_param->metal_d_extra1_buf; + device_param->kernel_params[22] = device_param->metal_d_extra2_buf; + device_param->kernel_params[23] = device_param->metal_d_extra3_buf; + device_param->kernel_params[24] = device_param->metal_d_kernel_param; + } + #endif // __APPLE__ + if (device_param->is_opencl == true) { device_param->kernel_params[ 0] = NULL; // &device_param->opencl_d_pws_buf; @@ -9258,6 +10608,13 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_params_mp[0] = &device_param->hip_d_combs; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_mp[0] = device_param->metal_d_combs; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_mp[0] = &device_param->opencl_d_combs; @@ -9277,6 +10634,13 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_params_mp[0] = &device_param->hip_d_combs; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_mp[0] = device_param->metal_d_combs; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_mp[0] = &device_param->opencl_d_combs; @@ -9302,6 +10666,14 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_params_mp[2] = &device_param->hip_d_markov_css_buf; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_mp[1] = device_param->metal_d_root_css_buf; + device_param->kernel_params_mp[2] = device_param->metal_d_markov_css_buf; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_mp[1] = &device_param->opencl_d_root_css_buf; @@ -9339,6 +10711,14 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_params_mp_l[2] = &device_param->hip_d_markov_css_buf; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_mp_l[1] = device_param->metal_d_root_css_buf; + device_param->kernel_params_mp_l[2] = device_param->metal_d_markov_css_buf; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_mp_l[1] = &device_param->opencl_d_root_css_buf; @@ -9374,6 +10754,15 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_params_mp_r[2] = &device_param->hip_d_markov_css_buf; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_mp_r[0] = device_param->metal_d_bfs; + device_param->kernel_params_mp_r[1] = device_param->metal_d_root_css_buf; + device_param->kernel_params_mp_r[2] = device_param->metal_d_markov_css_buf; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_mp_r[0] = &device_param->opencl_d_bfs; @@ -9409,6 +10798,17 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_params_amp[4] = &device_param->hip_d_bfs_c; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_amp[0] = NULL; // device_param->metal_d_pws_buf; + device_param->kernel_params_amp[1] = NULL; // device_param->metal_d_pws_amp_buf; + device_param->kernel_params_amp[2] = device_param->metal_d_rules_c; + device_param->kernel_params_amp[3] = device_param->metal_d_combs_c; + device_param->kernel_params_amp[4] = device_param->metal_d_bfs_c; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_amp[0] = NULL; // &device_param->opencl_d_pws_buf; @@ -9433,6 +10833,14 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_params_tm[1] = &device_param->hip_d_tm_c; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_tm[0] = device_param->metal_d_bfs_c; + device_param->kernel_params_tm[1] = device_param->metal_d_tm_c; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_tm[0] = &device_param->opencl_d_bfs_c; @@ -9482,6 +10890,17 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) // : &device_param->hip_d_pws_amp_buf; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_decompress[0] = NULL; // device_param->metal_d_pws_idx; + device_param->kernel_params_decompress[1] = NULL; // device_param->metal_d_pws_comp_buf; + device_param->kernel_params_decompress[2] = NULL; // (hashconfig->attack_exec == ATTACK_EXEC_INSIDE_KERNEL) + // ? device_param->metal_d_pws_buf + // : device_param->metal_d_pws_amp_buf; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_decompress[0] = NULL; // &device_param->opencl_d_pws_idx; @@ -11149,6 +12568,795 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + char kernel_name[64] = { 0 }; + + if (hashconfig->attack_exec == ATTACK_EXEC_INSIDE_KERNEL) + { + if (hashconfig->opti_type & OPTI_TYPE_SINGLE_HASH) + { + if (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL) + { + // kernel1: m%05u_s%02d + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_s%02d", kern_type, 4); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function1, &device_param->metal_pipeline1) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline1, &device_param->kernel_wgs1) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline1, &device_param->kernel_preferred_wgs_multiple1) == -1) return -1; + + device_param->kernel_local_mem_size1 = 0; + + device_param->kernel_dynamic_local_mem_size1 = 0; + + // kernel2: m%05u_s%02d + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_s%02d", kern_type, 8); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function2, &device_param->metal_pipeline2) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline2, &device_param->kernel_wgs2) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline2, &device_param->kernel_preferred_wgs_multiple2) == -1) return -1; + + device_param->kernel_local_mem_size2 = 0; + + device_param->kernel_dynamic_local_mem_size2 = 0; + + // kernel3: m%05u_s%02d + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_s%02d", kern_type, 16); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function3, &device_param->metal_pipeline3) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline3, &device_param->kernel_wgs3) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline3, &device_param->kernel_preferred_wgs_multiple3) == -1) return -1; + + device_param->kernel_local_mem_size3 = 0; + + device_param->kernel_dynamic_local_mem_size3 = 0; + } + else + { + // kernel4: m%05u_sxx + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_sxx", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function4, &device_param->metal_pipeline4) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline4, &device_param->kernel_wgs4) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline4, &device_param->kernel_preferred_wgs_multiple4) == -1) return -1; + + device_param->kernel_local_mem_size4 = 0; + + device_param->kernel_dynamic_local_mem_size4 = 0; + } + } + else // multi + { + if (hashconfig->opti_type & OPTI_TYPE_OPTIMIZED_KERNEL) + { + // kernel1 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_m%02d", kern_type, 4); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function1, &device_param->metal_pipeline1) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline1, &device_param->kernel_wgs1) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline1, &device_param->kernel_preferred_wgs_multiple1) == -1) return -1; + + device_param->kernel_local_mem_size1 = 0; + + device_param->kernel_dynamic_local_mem_size1 = 0; + + // kernel2 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_m%02d", kern_type, 8); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function2, &device_param->metal_pipeline2) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline2, &device_param->kernel_wgs2) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline2, &device_param->kernel_preferred_wgs_multiple2) == -1) return -1; + + device_param->kernel_local_mem_size2 = 0; + + device_param->kernel_dynamic_local_mem_size2 = 0; + + // kernel3 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_m%02d", kern_type, 16); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function3, &device_param->metal_pipeline3) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline3, &device_param->kernel_wgs3) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline3, &device_param->kernel_preferred_wgs_multiple3) == -1) return -1; + + device_param->kernel_local_mem_size3 = 0; + + device_param->kernel_dynamic_local_mem_size3 = 0; + } + else + { + // kernel4 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_mxx", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function4, &device_param->metal_pipeline4) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline4, &device_param->kernel_wgs4) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline4, &device_param->kernel_preferred_wgs_multiple4) == -1) return -1; + + device_param->kernel_local_mem_size4 = 0; + + device_param->kernel_dynamic_local_mem_size4 = 0; + } + } + + if (user_options->slow_candidates == true) + { + } + else + { + if (user_options->attack_mode == ATTACK_MODE_BF) + { + if (hashconfig->opts_type & OPTS_TYPE_TM_KERNEL) + { + snprintf (kernel_name, sizeof (kernel_name), "m%05u_tm", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function_tm, &device_param->metal_pipeline_tm) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_tm, &device_param->kernel_wgs_tm) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_tm, &device_param->kernel_preferred_wgs_multiple_tm) == -1) return -1; + + device_param->kernel_local_mem_size_tm = 0; + + device_param->kernel_dynamic_local_mem_size_tm = 0; + } + } + } + } + else + { + // kernel1: m%05u_init + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_init", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function1, &device_param->metal_pipeline1) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline1, &device_param->kernel_wgs1) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline1, &device_param->kernel_preferred_wgs_multiple1) == -1) return -1; + + device_param->kernel_local_mem_size1 = 0; + + device_param->kernel_dynamic_local_mem_size1 = 0; + + // kernel2: m%05u_loop + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_loop", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function2, &device_param->metal_pipeline2) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline2, &device_param->kernel_wgs2) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline2, &device_param->kernel_preferred_wgs_multiple2) == -1) return -1; + + device_param->kernel_local_mem_size2 = 0; + + device_param->kernel_dynamic_local_mem_size2 = 0; + + // kernel3: m%05u_comp + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_comp", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function3, &device_param->metal_pipeline3) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline3, &device_param->kernel_wgs3) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline3, &device_param->kernel_preferred_wgs_multiple3) == -1) return -1; + + device_param->kernel_local_mem_size3 = 0; + + device_param->kernel_dynamic_local_mem_size3 = 0; + + if (hashconfig->opts_type & OPTS_TYPE_LOOP_PREPARE) + { + // kernel2p: m%05u_loop_prepare + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_loop_prepare", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function2p, &device_param->metal_pipeline2p) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline2p, &device_param->kernel_wgs2p) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline2p, &device_param->kernel_preferred_wgs_multiple2p) == -1) return -1; + + device_param->kernel_local_mem_size2p = 0; + + device_param->kernel_dynamic_local_mem_size2p = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_LOOP_EXTENDED) + { + // kernel2e: m%05u_loop_extended + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_loop_extended", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function2e, &device_param->metal_pipeline2e) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline2e, &device_param->kernel_wgs2e) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline2e, &device_param->kernel_preferred_wgs_multiple2e) == -1) return -1; + + device_param->kernel_local_mem_size2e = 0; + + device_param->kernel_dynamic_local_mem_size2e = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_HOOK12) + { + // kernel12: m%05u_hook12 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_hook12", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function12, &device_param->metal_pipeline12) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline12, &device_param->kernel_wgs12) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline12, &device_param->kernel_preferred_wgs_multiple12) == -1) return -1; + + device_param->kernel_local_mem_size12 = 0; + + device_param->kernel_dynamic_local_mem_size12 = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_HOOK23) + { + // kernel23: m%05u_hook23 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_hook23", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function23, &device_param->metal_pipeline23) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline23, &device_param->kernel_wgs23) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline23, &device_param->kernel_preferred_wgs_multiple23) == -1) return -1; + + device_param->kernel_local_mem_size23 = 0; + + device_param->kernel_dynamic_local_mem_size23 = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_INIT2) + { + // init2: m%05u_init2 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_init2", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function_init2, &device_param->metal_pipeline_init2) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_init2, &device_param->kernel_wgs_init2) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_init2, &device_param->kernel_preferred_wgs_multiple_init2) == -1) return -1; + + device_param->kernel_local_mem_size_init2 = 0; + + device_param->kernel_dynamic_local_mem_size_init2 = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_LOOP2_PREPARE) + { + // loop2 prepare: m%05u_loop2_prepare + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_loop2_prepare", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function_loop2p, &device_param->metal_pipeline_loop2p) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_loop2p, &device_param->kernel_wgs_loop2p) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_loop2p, &device_param->kernel_preferred_wgs_multiple_loop2p) == -1) return -1; + + device_param->kernel_local_mem_size_loop2p = 0; + + device_param->kernel_dynamic_local_mem_size_loop2p = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_LOOP2) + { + // loop2: m%05u_loop2 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_loop2", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function_loop2, &device_param->metal_pipeline_loop2) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_loop2, &device_param->kernel_wgs_loop2) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_loop2, &device_param->kernel_preferred_wgs_multiple_loop2) == -1) return -1; + + device_param->kernel_local_mem_size_loop2 = 0; + + device_param->kernel_dynamic_local_mem_size_loop2 = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_AUX1) + { + // aux1: m%05u_aux1 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_aux1", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function_aux1, &device_param->metal_pipeline_aux1) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_aux1, &device_param->kernel_wgs_aux1) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_aux1, &device_param->kernel_preferred_wgs_multiple_aux1) == -1) return -1; + + device_param->kernel_local_mem_size_aux1 = 0; + + device_param->kernel_dynamic_local_mem_size_aux1 = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_AUX2) + { + // aux2: m%05u_aux2 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_aux2", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function_aux2, &device_param->metal_pipeline_aux2) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_aux2, &device_param->kernel_wgs_aux2) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_aux2, &device_param->kernel_preferred_wgs_multiple_aux2) == -1) return -1; + + device_param->kernel_local_mem_size_aux2 = 0; + + device_param->kernel_dynamic_local_mem_size_aux2 = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_AUX3) + { + // aux3: m%05u_aux3 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_aux3", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function_aux3, &device_param->metal_pipeline_aux3) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_aux3, &device_param->kernel_wgs_aux3) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_aux3, &device_param->kernel_preferred_wgs_multiple_aux3) == -1) return -1; + + device_param->kernel_local_mem_size_aux3 = 0; + + device_param->kernel_dynamic_local_mem_size_aux3 = 0; + } + + if (hashconfig->opts_type & OPTS_TYPE_AUX4) + { + // aux4: m%05u_aux4 + + snprintf (kernel_name, sizeof (kernel_name), "m%05u_aux4", kern_type); + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library, kernel_name, &device_param->metal_function_aux4, &device_param->metal_pipeline_aux4) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, kernel_name); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_aux4, &device_param->kernel_wgs_aux4) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_aux4, &device_param->kernel_preferred_wgs_multiple_aux4) == -1) return -1; + + device_param->kernel_local_mem_size_aux4 = 0; + + device_param->kernel_dynamic_local_mem_size_aux4 = 0; + } + } + + // MP start + + if (user_options->slow_candidates == true) + { + } + else + { + if (user_options->attack_mode == ATTACK_MODE_BF) + { + // mp_l: l_markov + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_mp, "l_markov", &device_param->metal_function_mp_l, &device_param->metal_pipeline_mp_l) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "l_markov"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_mp_l, &device_param->kernel_wgs_mp_l) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_mp_l, &device_param->kernel_preferred_wgs_multiple_mp_l) == -1) return -1; + + device_param->kernel_local_mem_size_mp_l = 0; + + device_param->kernel_dynamic_local_mem_size_mp_l = 0; + + // mp_r: r_markov + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_mp, "r_markov", &device_param->metal_function_mp_r, &device_param->metal_pipeline_mp_r) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "r_markov"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_mp_r, &device_param->kernel_wgs_mp_r) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_mp_r, &device_param->kernel_preferred_wgs_multiple_mp_r) == -1) return -1; + + device_param->kernel_local_mem_size_mp_r = 0; + + device_param->kernel_dynamic_local_mem_size_mp_r = 0; + } + else if (user_options->attack_mode == ATTACK_MODE_HYBRID1) + { + // mp_c: C_markov + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_mp, "C_markov", &device_param->metal_function_mp, &device_param->metal_pipeline_mp) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "C_markov"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_mp, &device_param->kernel_wgs_mp) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_mp, &device_param->kernel_preferred_wgs_multiple_mp) == -1) return -1; + + device_param->kernel_local_mem_size_mp = 0; + + device_param->kernel_dynamic_local_mem_size_mp = 0; + } + else if (user_options->attack_mode == ATTACK_MODE_HYBRID2) + { + // mp_c: C_markov + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_mp, "C_markov", &device_param->metal_function_mp, &device_param->metal_pipeline_mp) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "C_markov"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_mp, &device_param->kernel_wgs_mp) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_mp, &device_param->kernel_preferred_wgs_multiple_mp) == -1) return -1; + + device_param->kernel_local_mem_size_mp = 0; + + device_param->kernel_dynamic_local_mem_size_mp = 0; + } + } + + if (user_options->slow_candidates == true) + { + } + else + { + if (hashconfig->attack_exec == ATTACK_EXEC_INSIDE_KERNEL) + { + // nothing to do + } + else + { + // amp + + if (hc_mtlCreateKernel (hashcat_ctx, device_param->metal_device, device_param->metal_library_amp, "amp", &device_param->metal_function_amp, &device_param->metal_pipeline_amp) == -1) + { + event_log_warning (hashcat_ctx, "* Device #%u: Kernel %s create failed.", device_param->device_id + 1, "amp"); + + backend_kernel_create_warnings++; + + device_param->skipped_warning = true; + continue; + } + + if (hc_mtlGetMaxTotalThreadsPerThreadgroup (hashcat_ctx, device_param->metal_pipeline_amp, &device_param->kernel_wgs_amp) == -1) return -1; + + if (hc_mtlGetThreadExecutionWidth (hashcat_ctx, device_param->metal_pipeline_amp, &device_param->kernel_preferred_wgs_multiple_amp) == -1) return -1; + + device_param->kernel_local_mem_size_amp = 0; + + device_param->kernel_dynamic_local_mem_size_amp = 0; + } + } + + // zero some data buffers + + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_plain_bufs, device_param->size_plains) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_digests_shown, device_param->size_shown) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_result, device_param->size_results) == -1) return -1; + + /** + * special buffers + */ + + if (user_options->slow_candidates == true) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_rules_c, size_rules_c) == -1) return -1; + } + else + { + if (user_options_extra->attack_kern == ATTACK_KERN_STRAIGHT) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_rules_c, size_rules_c) == -1) return -1; + } + else if (user_options_extra->attack_kern == ATTACK_KERN_COMBI) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_combs, size_combs) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_combs_c, size_combs) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_root_css_buf, size_root_css) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_markov_css_buf, size_markov_css) == -1) return -1; + } + else if (user_options_extra->attack_kern == ATTACK_KERN_BF) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_bfs, size_bfs) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_bfs_c, size_bfs) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_tm_c, size_tm) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_root_css_buf, size_root_css) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_markov_css_buf, size_markov_css) == -1) return -1; + } + } + + if (user_options->slow_candidates == true) + { + } + else + { + if ((user_options->attack_mode == ATTACK_MODE_HYBRID1) || (user_options->attack_mode == ATTACK_MODE_HYBRID2)) + { + /** + * prepare mp + */ + + if (user_options->attack_mode == ATTACK_MODE_HYBRID1) + { + device_param->kernel_params_mp_buf32[5] = 0; + device_param->kernel_params_mp_buf32[6] = 0; + device_param->kernel_params_mp_buf32[7] = 0; + + if (hashconfig->opts_type & OPTS_TYPE_PT_ADD01) device_param->kernel_params_mp_buf32[5] = full01; + if (hashconfig->opts_type & OPTS_TYPE_PT_ADD06) device_param->kernel_params_mp_buf32[5] = full06; + if (hashconfig->opts_type & OPTS_TYPE_PT_ADD80) device_param->kernel_params_mp_buf32[5] = full80; + if (hashconfig->opts_type & OPTS_TYPE_PT_ADDBITS14) device_param->kernel_params_mp_buf32[6] = 1; + if (hashconfig->opts_type & OPTS_TYPE_PT_ADDBITS15) device_param->kernel_params_mp_buf32[7] = 1; + } + else if (user_options->attack_mode == ATTACK_MODE_HYBRID2) + { + device_param->kernel_params_mp_buf32[5] = 0; + device_param->kernel_params_mp_buf32[6] = 0; + device_param->kernel_params_mp_buf32[7] = 0; + } + } + else if (user_options->attack_mode == ATTACK_MODE_BF) + { + /** + * prepare mp_r and mp_l + */ + + device_param->kernel_params_mp_l_buf32[6] = 0; + device_param->kernel_params_mp_l_buf32[7] = 0; + device_param->kernel_params_mp_l_buf32[8] = 0; + + if (hashconfig->opts_type & OPTS_TYPE_PT_ADD01) device_param->kernel_params_mp_l_buf32[6] = full01; + if (hashconfig->opts_type & OPTS_TYPE_PT_ADD06) device_param->kernel_params_mp_l_buf32[6] = full06; + if (hashconfig->opts_type & OPTS_TYPE_PT_ADD80) device_param->kernel_params_mp_l_buf32[6] = full80; + if (hashconfig->opts_type & OPTS_TYPE_PT_ADDBITS14) device_param->kernel_params_mp_l_buf32[7] = 1; + if (hashconfig->opts_type & OPTS_TYPE_PT_ADDBITS15) device_param->kernel_params_mp_l_buf32[8] = 1; + } + } + } + #endif // __APPLE__ + if (device_param->is_opencl == true) { // GPU autotune init @@ -12164,13 +14372,6 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) { const size_t undocumented_single_allocation_apple = 0x7fffffff; - if (bitmap_ctx->bitmap_size > undocumented_single_allocation_apple) memory_limit_hit = 1; - if (bitmap_ctx->bitmap_size > undocumented_single_allocation_apple) memory_limit_hit = 1; - if (bitmap_ctx->bitmap_size > undocumented_single_allocation_apple) memory_limit_hit = 1; - if (bitmap_ctx->bitmap_size > undocumented_single_allocation_apple) memory_limit_hit = 1; - if (bitmap_ctx->bitmap_size > undocumented_single_allocation_apple) memory_limit_hit = 1; - if (bitmap_ctx->bitmap_size > undocumented_single_allocation_apple) memory_limit_hit = 1; - if (bitmap_ctx->bitmap_size > undocumented_single_allocation_apple) memory_limit_hit = 1; if (bitmap_ctx->bitmap_size > undocumented_single_allocation_apple) memory_limit_hit = 1; if (size_bfs > undocumented_single_allocation_apple) memory_limit_hit = 1; if (size_combs > undocumented_single_allocation_apple) memory_limit_hit = 1; @@ -12337,6 +14538,25 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_hooks, device_param->size_hooks) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_pws, NULL, &device_param->metal_d_pws_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_pws_amp, NULL, &device_param->metal_d_pws_amp_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_pws_comp, NULL, &device_param->metal_d_pws_comp_buf) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_pws_idx, NULL, &device_param->metal_d_pws_idx) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_tmps, NULL, &device_param->metal_d_tmps) == -1) return -1; + if (hc_mtlCreateBuffer (hashcat_ctx, device_param->metal_device, size_hooks, NULL, &device_param->metal_d_hooks) == -1) return -1; + + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_pws_buf, device_param->size_pws) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_pws_amp_buf, device_param->size_pws_amp) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_pws_comp_buf, device_param->size_pws_comp) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_pws_idx, device_param->size_pws_idx) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_tmps, device_param->size_tmps) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_hooks, device_param->size_hooks) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clCreateBuffer (hashcat_ctx, device_param->opencl_context, CL_MEM_READ_WRITE, size_pws, NULL, &device_param->opencl_d_pws_buf) == -1) return -1; @@ -12379,7 +14599,6 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->scratch_buf = scratch_buf; #ifdef WITH_BRAIN - u8 *brain_link_in_buf = (u8 *) hcmalloc (size_brain_link_in); device_param->brain_link_in_buf = brain_link_in_buf; @@ -12415,6 +14634,15 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) device_param->kernel_params[ 5] = &device_param->hip_d_hooks; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params[ 0] = device_param->metal_d_pws_buf; + device_param->kernel_params[ 4] = device_param->metal_d_tmps; + device_param->kernel_params[ 5] = device_param->metal_d_hooks; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params[ 0] = &device_param->opencl_d_pws_buf; @@ -12453,6 +14681,15 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) //CL_rc = hc_clSetKernelArg (hashcat_ctx, device_param->opencl_kernel_mp, 0, sizeof (cl_mem), device_param->kernel_params_mp[0]); if (CL_rc == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_mp[0] = (hashconfig->attack_exec == ATTACK_EXEC_INSIDE_KERNEL) + ? device_param->metal_d_pws_buf + : device_param->metal_d_pws_amp_buf; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_mp[0] = (hashconfig->attack_exec == ATTACK_EXEC_INSIDE_KERNEL) @@ -12484,6 +14721,15 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) //CL_rc = hc_clSetKernelArg (hashcat_ctx, device_param->opencl_kernel_mp_l, 0, sizeof (cl_mem), device_param->kernel_params_mp_l[0]); if (CL_rc == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_mp_l[0] = (hashconfig->attack_exec == ATTACK_EXEC_INSIDE_KERNEL) + ? device_param->metal_d_pws_buf + : device_param->metal_d_pws_amp_buf; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_mp_l[0] = (hashconfig->attack_exec == ATTACK_EXEC_INSIDE_KERNEL) @@ -12518,6 +14764,14 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) //CL_rc = hc_clSetKernelArg (hashcat_ctx, device_param->opencl_kernel_amp, 1, sizeof (cl_mem), device_param->kernel_params_amp[1]); if (CL_rc == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_amp[0] = device_param->metal_d_pws_buf; + device_param->kernel_params_amp[1] = device_param->metal_d_pws_amp_buf; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_amp[0] = &device_param->opencl_d_pws_buf; @@ -12555,6 +14809,17 @@ int backend_session_begin (hashcat_ctx_t *hashcat_ctx) //CL_rc = hc_clSetKernelArg (hashcat_ctx, device_param->opencl_kernel_decompress, 2, sizeof (cl_mem), device_param->kernel_params_decompress[2]); if (CL_rc == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params_decompress[0] = device_param->metal_d_pws_idx; + device_param->kernel_params_decompress[1] = device_param->metal_d_pws_comp_buf; + device_param->kernel_params_decompress[2] = (hashconfig->attack_exec == ATTACK_EXEC_INSIDE_KERNEL) + ? device_param->metal_d_pws_buf + : device_param->metal_d_pws_amp_buf; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params_decompress[0] = &device_param->opencl_d_pws_idx; @@ -12919,6 +15184,153 @@ void backend_session_destroy (hashcat_ctx_t *hashcat_ctx) device_param->hip_context = NULL; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (device_param->metal_d_pws_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_pws_buf); + if (device_param->metal_d_pws_amp_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_pws_amp_buf); + if (device_param->metal_d_pws_comp_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_pws_comp_buf); + if (device_param->metal_d_pws_idx) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_pws_idx); + if (device_param->metal_d_rules) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_rules); + if (device_param->metal_d_rules_c) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_rules_c); + if (device_param->metal_d_combs) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_combs); + if (device_param->metal_d_combs_c) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_combs_c); + if (device_param->metal_d_bfs) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bfs); + if (device_param->metal_d_bfs_c) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bfs_c); + if (device_param->metal_d_bitmap_s1_a) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bitmap_s1_a); + if (device_param->metal_d_bitmap_s1_b) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bitmap_s1_b); + if (device_param->metal_d_bitmap_s1_c) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bitmap_s1_c); + if (device_param->metal_d_bitmap_s1_d) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bitmap_s1_d); + if (device_param->metal_d_bitmap_s2_a) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bitmap_s2_a); + if (device_param->metal_d_bitmap_s2_b) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bitmap_s2_b); + if (device_param->metal_d_bitmap_s2_c) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bitmap_s2_c); + if (device_param->metal_d_bitmap_s2_d) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_bitmap_s2_d); + if (device_param->metal_d_plain_bufs) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_plain_bufs); + if (device_param->metal_d_digests_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_digests_buf); + if (device_param->metal_d_digests_shown) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_digests_shown); + if (device_param->metal_d_salt_bufs) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_salt_bufs); + if (device_param->metal_d_esalt_bufs) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_esalt_bufs); + if (device_param->metal_d_tmps) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_tmps); + if (device_param->metal_d_hooks) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_hooks); + if (device_param->metal_d_result) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_result); + if (device_param->metal_d_extra0_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_extra0_buf); + if (device_param->metal_d_extra1_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_extra1_buf); + if (device_param->metal_d_extra2_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_extra2_buf); + if (device_param->metal_d_extra3_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_extra3_buf); + if (device_param->metal_d_root_css_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_root_css_buf); + if (device_param->metal_d_markov_css_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_markov_css_buf); + if (device_param->metal_d_tm_c) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_tm_c); + if (device_param->metal_d_st_digests_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_st_digests_buf); + if (device_param->metal_d_st_salts_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_st_salts_buf); + if (device_param->metal_d_st_esalts_buf) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_st_esalts_buf); + if (device_param->metal_d_kernel_param) hc_mtlReleaseMemObject (hashcat_ctx, device_param->metal_d_kernel_param); + + if (device_param->metal_function1) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function1); + if (device_param->metal_function12) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function12); + if (device_param->metal_function2p) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function2p); + if (device_param->metal_function2) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function2); + if (device_param->metal_function2e) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function2e); + if (device_param->metal_function23) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function23); + if (device_param->metal_function3) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function3); + if (device_param->metal_function4) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function4); + if (device_param->metal_function_init2) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_init2); + if (device_param->metal_function_loop2p) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_loop2p); + if (device_param->metal_function_loop2) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_loop2); + if (device_param->metal_function_mp) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_mp); + if (device_param->metal_function_mp_l) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_mp_l); + if (device_param->metal_function_mp_r) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_mp_r); + if (device_param->metal_function_tm) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_tm); + if (device_param->metal_function_amp) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_amp); + if (device_param->metal_function_memset) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_memset); + if (device_param->metal_function_bzero) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_bzero); + if (device_param->metal_function_atinit) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_atinit); + if (device_param->metal_function_utf8toutf16le) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_utf8toutf16le); + if (device_param->metal_function_decompress) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_decompress); + if (device_param->metal_function_aux1) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_aux1); + if (device_param->metal_function_aux2) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_aux2); + if (device_param->metal_function_aux3) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_aux3); + if (device_param->metal_function_aux4) hc_mtlReleaseFunction (hashcat_ctx, device_param->metal_function_aux4); + + if (device_param->metal_library) hc_mtlReleaseLibrary (hashcat_ctx, device_param->metal_library); + if (device_param->metal_library_mp) hc_mtlReleaseLibrary (hashcat_ctx, device_param->metal_library_mp); + if (device_param->metal_library_amp) hc_mtlReleaseLibrary (hashcat_ctx, device_param->metal_library_amp); + if (device_param->metal_library_shared) hc_mtlReleaseLibrary (hashcat_ctx, device_param->metal_library_shared); + + if (device_param->metal_command_queue) hc_mtlReleaseCommandQueue (hashcat_ctx, device_param->metal_command_queue); + + //if (device_param->metal_device) hc_mtlReleaseDevice (hashcat_ctx, device_param->metal_device); + + device_param->metal_d_pws_buf = NULL; + device_param->metal_d_pws_amp_buf = NULL; + device_param->metal_d_pws_comp_buf = NULL; + device_param->metal_d_pws_idx = NULL; + device_param->metal_d_rules = NULL; + device_param->metal_d_rules_c = NULL; + device_param->metal_d_combs = NULL; + device_param->metal_d_combs_c = NULL; + device_param->metal_d_bfs = NULL; + device_param->metal_d_bfs_c = NULL; + device_param->metal_d_bitmap_s1_a = NULL; + device_param->metal_d_bitmap_s1_b = NULL; + device_param->metal_d_bitmap_s1_c = NULL; + device_param->metal_d_bitmap_s1_d = NULL; + device_param->metal_d_bitmap_s2_a = NULL; + device_param->metal_d_bitmap_s2_b = NULL; + device_param->metal_d_bitmap_s2_c = NULL; + device_param->metal_d_bitmap_s2_d = NULL; + device_param->metal_d_plain_bufs = NULL; + device_param->metal_d_digests_buf = NULL; + device_param->metal_d_digests_shown = NULL; + device_param->metal_d_salt_bufs = NULL; + device_param->metal_d_esalt_bufs = NULL; + device_param->metal_d_tmps = NULL; + device_param->metal_d_hooks = NULL; + device_param->metal_d_result = NULL; + device_param->metal_d_extra0_buf = NULL; + device_param->metal_d_extra1_buf = NULL; + device_param->metal_d_extra2_buf = NULL; + device_param->metal_d_extra3_buf = NULL; + device_param->metal_d_root_css_buf = NULL; + device_param->metal_d_markov_css_buf = NULL; + device_param->metal_d_tm_c = NULL; + device_param->metal_d_st_digests_buf = NULL; + device_param->metal_d_st_salts_buf = NULL; + device_param->metal_d_st_esalts_buf = NULL; + device_param->metal_d_kernel_param = NULL; + device_param->metal_function1 = NULL; + device_param->metal_function12 = NULL; + device_param->metal_function2p = NULL; + device_param->metal_function2 = NULL; + device_param->metal_function2e = NULL; + device_param->metal_function23 = NULL; + device_param->metal_function3 = NULL; + device_param->metal_function4 = NULL; + device_param->metal_function_init2 = NULL; + device_param->metal_function_loop2p = NULL; + device_param->metal_function_loop2 = NULL; + device_param->metal_function_mp = NULL; + device_param->metal_function_mp_l = NULL; + device_param->metal_function_mp_r = NULL; + device_param->metal_function_tm = NULL; + device_param->metal_function_amp = NULL; + device_param->metal_function_memset = NULL; + device_param->metal_function_bzero = NULL; + device_param->metal_function_atinit = NULL; + device_param->metal_function_utf8toutf16le = NULL; + device_param->metal_function_decompress = NULL; + device_param->metal_function_aux1 = NULL; + device_param->metal_function_aux2 = NULL; + device_param->metal_function_aux3 = NULL; + device_param->metal_function_aux4 = NULL; + device_param->metal_library = NULL; + device_param->metal_library_mp = NULL; + device_param->metal_library_amp = NULL; + device_param->metal_library_shared = NULL; + device_param->metal_command_queue = NULL; + //device_param->metal_device = NULL; + } + #endif // __APPLE__ + if (device_param->is_opencl == true) { if (device_param->opencl_d_pws_buf) hc_clReleaseMemObject (hashcat_ctx, device_param->opencl_d_pws_buf); @@ -13207,6 +15619,14 @@ int backend_session_update_mp (hashcat_ctx_t *hashcat_ctx) if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_markov_css_buf, mask_ctx->markov_css_buf, device_param->size_markov_css, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_root_css_buf, 0, mask_ctx->root_css_buf, device_param->size_root_css) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_markov_css_buf, 0, mask_ctx->markov_css_buf, device_param->size_markov_css) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_root_css_buf, CL_FALSE, 0, device_param->size_root_css, mask_ctx->root_css_buf, 0, NULL, NULL) == -1) return -1; @@ -13255,6 +15675,14 @@ int backend_session_update_mp_rl (hashcat_ctx_t *hashcat_ctx, const u32 css_cnt_ if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_markov_css_buf, mask_ctx->markov_css_buf, device_param->size_markov_css, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_root_css_buf, 0, mask_ctx->root_css_buf, device_param->size_root_css) == -1) return -1; + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_markov_css_buf, 0, mask_ctx->markov_css_buf, device_param->size_markov_css) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_root_css_buf, CL_FALSE, 0, device_param->size_root_css, mask_ctx->root_css_buf, 0, NULL, NULL) == -1) return -1; diff --git a/src/ext_metal.m b/src/ext_metal.m new file mode 100644 index 000000000..a4a635c48 --- /dev/null +++ b/src/ext_metal.m @@ -0,0 +1,1433 @@ +/** + * Author......: See docs/credits.txt + * License.....: MIT + */ + +#include "common.h" +#include "types.h" +#include "memory.h" +#include "event.h" +#include "timer.h" +#include "ext_metal.h" + +#include + +#include +#include +#include + +typedef NS_ENUM(NSUInteger, hc_mtlFeatureSet) +{ + MTL_FEATURESET_MACOS_GPUFAMILY_1_V1 = 10000, + MTL_FEATURESET_MACOS_GPUFAMILY_1_V2 = 10001, + MTL_FEATURESET_MACOS_GPUFAMILY_1_V3 = 10003, + MTL_FEATURESET_MACOS_GPUFAMILY_1_V4 = 10004, + MTL_FEATURESET_MACOS_GPUFAMILY_2_V1 = 10005, + +} metalDeviceFeatureSet_macOS_t; + +typedef NS_ENUM(NSUInteger, hc_mtlLanguageVersion) +{ + MTL_LANGUAGEVERSION_1_0 = (1 << 16), + MTL_LANGUAGEVERSION_1_1 = (1 << 16) + 1, + MTL_LANGUAGEVERSION_1_2 = (1 << 16) + 2, + MTL_LANGUAGEVERSION_2_0 = (2 << 16), + MTL_LANGUAGEVERSION_2_1 = (2 << 16) + 1, + MTL_LANGUAGEVERSION_2_2 = (2 << 16) + 2, + MTL_LANGUAGEVERSION_2_3 = (2 << 16) + 3, + MTL_LANGUAGEVERSION_2_4 = (2 << 16) + 4, + +} metalLanguageVersion_t; + +static bool iokit_getGPUCore (void *hashcat_ctx, int *gpu_core) +{ + bool rc = false; + + CFMutableDictionaryRef matching = IOServiceMatching ("IOAccelerator"); + + io_service_t service = IOServiceGetMatchingService (kIOMasterPortDefault, matching); + + if (!service) + { + event_log_error (hashcat_ctx, "IOServiceGetMatchingService(): %08x", service); + + return rc; + } + + // "gpu-core-count" is present only on Apple Silicon + + CFNumberRef num = IORegistryEntryCreateCFProperty(service, CFSTR("gpu-core-count"), kCFAllocatorDefault, 0); + + int gc = 0; + + if (num == nil || CFNumberGetValue (num, kCFNumberIntType, &gc) == false) + { + //event_log_error (hashcat_ctx, "IORegistryEntryCreateCFProperty(): 'gpu-core-count' entry not found"); + } + else + { + *gpu_core = gc; + + rc = true; + } + + IOObjectRelease (service); + + return rc; +} + +static int hc_mtlInvocationHelper (id target, SEL selector, void *returnValue) +{ + if (target == nil) return -1; + if (selector == nil) return -1; + + if ([target respondsToSelector: selector]) + { + NSMethodSignature *signature = [object_getClass (target) instanceMethodSignatureForSelector: selector]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: signature]; + [invocation setTarget: target]; + [invocation setSelector: selector]; + [invocation invoke]; + [invocation getReturnValue: returnValue]; + + return 0; + } + + return -1; +} + +static int hc_mtlBuildOptionsToDict (void *hashcat_ctx, const char *build_options_buf, const char *include_path, NSMutableDictionary *build_options_dict) +{ + if (build_options_buf == nil) + { + event_log_error (hashcat_ctx, "%s(): build_options_buf is NULL", __func__); + return -1; + } + + if (build_options_dict == nil) + { + event_log_error (hashcat_ctx, "%s(): build_options_dict is NULL", __func__); + return -1; + } + + // NSString from build_options_buf + + NSString *options = [NSString stringWithCString: build_options_buf encoding: NSUTF8StringEncoding]; + + if (options == nil) + { + event_log_error (hashcat_ctx, "%s(): stringWithCString failed", __func__); + return -1; + } + + // replace '-D ' to '' + + options = [options stringByReplacingOccurrencesOfString:@"-D " withString:@""]; + + if (options == nil) + { + event_log_error (hashcat_ctx, "%s(): stringByReplacingOccurrencesOfString(-D) failed", __func__); + return -1; + } + + // replace '-I OpenCL ' to '' + + options = [options stringByReplacingOccurrencesOfString:@"-I OpenCL " withString:@""]; + + if (options == nil) + { + event_log_error (hashcat_ctx, "%s(): stringByReplacingOccurrencesOfString(-I OpenCL) failed", __func__); + return -1; + } + + //NSLog(@"options: '%@'", options); + + // creating NSDictionary from options + + NSArray *lines = [options componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + + for (NSString *aKeyValue in lines) + { + NSArray *components = [aKeyValue componentsSeparatedByString:@"="]; + + NSString *key = [components[0] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + NSString *value = nil; + + if ([components count] != 2) + { + if ([key isEqualToString:[NSString stringWithUTF8String:"KERNEL_STATIC"]] || + [key isEqualToString:[NSString stringWithUTF8String:"IS_APPLE_SILICON"]] || + [key isEqualToString:[NSString stringWithUTF8String:"DYNAMIC_LOCAL"]] || + [key isEqualToString:[NSString stringWithUTF8String:"_unroll"]] || + [key isEqualToString:[NSString stringWithUTF8String:"NO_UNROLL"]] || + [key isEqualToString:[NSString stringWithUTF8String:"FORCE_DISABLE_SHM"]]) + { + value = @"1"; + } + else + { + //event_log_warning (hashcat_ctx, "%s(): skipping malformed build option: %s", __func__, [key UTF8String]); + + continue; + } + } + else + { + value = [components[1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + } + + [build_options_dict setObject:value forKey:key]; + } + + // if set, add INCLUDE_PATH to hack Apple kernel build from source limitation on -I usage + if (include_path != nil) + { + NSString *path_key = @"INCLUDE_PATH"; + NSString *path_value = [NSString stringWithCString: include_path encoding: NSUTF8StringEncoding]; + + [build_options_dict setObject:path_value forKey:path_key]; + } + + //NSLog(@"Dict:\n%@", build_options_dict); + + return 0; +} + +int mtl_init (void *hashcat_ctx) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + memset (mtl, 0, sizeof (MTL_PTR)); + + mtl->devices = nil; + + if (MTLCreateSystemDefaultDevice() == nil) + { + event_log_error (hashcat_ctx, "Metal is not supported on this computer"); + + return -1; + } + + return 0; +} + +void mtl_close (void *hashcat_ctx) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl) + { + if (mtl->devices) + { + int count = (int) CFArrayGetCount (mtl->devices); + for (int i = 0; i < count; i++) + { + mtl_device_id device = (mtl_device_id) CFArrayGetValueAtIndex (mtl->devices, i); + if (device != nil) + { + hc_mtlReleaseDevice (hashcat_ctx, device); + } + } + mtl->devices = nil; + } + + hcfree (backend_ctx->mtl); + + backend_ctx->mtl = NULL; + } +} + +int hc_mtlDeviceGetCount (void *hashcat_ctx, int *count) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == nil) return -1; + + CFArrayRef devices = (CFArrayRef) MTLCopyAllDevices(); + + if (devices == nil) + { + event_log_error (hashcat_ctx, "metalDeviceGetCount(): empty device objects"); + + return -1; + } + + mtl->devices = devices; + + *count = CFArrayGetCount (devices); + + return 0; +} + +int hc_mtlDeviceGet (void *hashcat_ctx, mtl_device_id *metal_device, int ordinal) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == nil) return -1; + + if (mtl->devices == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid devices pointer", __func__); + + return -1; + } + + mtl_device_id device = (mtl_device_id) CFArrayGetValueAtIndex (mtl->devices, ordinal); + + if (device == nil) + { + event_log_error (hashcat_ctx, "metalDeviceGet(): invalid index"); + + return -1; + } + + *metal_device = device; + + return 0; +} + +int hc_mtlDeviceGetName (void *hashcat_ctx, char *name, size_t len, mtl_device_id metal_device) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_device == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid device", __func__); + + return -1; + } + + if (len <= 0) + { + event_log_error (hashcat_ctx, "%s(): buffer length", __func__); + + return -1; + } + + id device_name_ptr = [metal_device name]; + + if (device_name_ptr == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to get device name", __func__); + + return -1; + } + + const char *device_name_str = [device_name_ptr UTF8String]; + + if (device_name_str == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to get UTF8String from device name", __func__); + + return -1; + } + + const size_t device_name_len = strlen (device_name_str); + + if (device_name_len <= 0) + { + event_log_error (hashcat_ctx, "%s(): invalid device name length", __func__); + + return -1; + } + + if (strncpy (name, device_name_str, (device_name_len > len) ? len : device_name_len) != name) + { + event_log_error (hashcat_ctx, "%s(): strncpy failed", __func__); + + return -1; + } + + return 0; +} + +int hc_mtlDeviceGetAttribute (void *hashcat_ctx, int *pi, metalDeviceAttribute_t attrib, mtl_device_id metal_device) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_device == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid device", __func__); + + return -1; + } + + uint64_t val64 = 0; + bool valBool = false; + int valInt = 0; + + switch (attrib) + { + case MTL_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT: + // works only with Apple Silicon + if (iokit_getGPUCore (hashcat_ctx, pi) == false) *pi = 1; + break; + + case MTL_DEVICE_ATTRIBUTE_UNIFIED_MEMORY: + *pi = 0; + + SEL hasUnifiedMemorySelector = NSSelectorFromString(@"hasUnifiedMemory"); + + hc_mtlInvocationHelper (metal_device, hasUnifiedMemorySelector, &valBool); + + *pi = (valBool == true) ? 1 : 0; + + break; + + case MTL_DEVICE_ATTRIBUTE_WARP_SIZE: + // return a fake size of 32, it will be updated later + *pi = 32; + break; + + case MTL_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR: + *pi = 0; + + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_2_V1] == true) *pi = 2; + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_1_V4] == true) *pi = 1; + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_1_V3] == true) *pi = 1; + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_1_V2] == true) *pi = 1; + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_1_V1] == true) *pi = 1; + + if (*pi == 0) + { + //event_log_error (hashcat_ctx, "%s(): no feature sets supported", __func__); + return -1; + } + + break; + + case MTL_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR: + *pi = 0; + + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_2_V1] == true) *pi = 1; + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_1_V4] == true) *pi = 4; + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_1_V3] == true) *pi = 3; + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_1_V2] == true) *pi = 2; + if (*pi == 0 && [metal_device supportsFeatureSet:MTL_FEATURESET_MACOS_GPUFAMILY_1_V1] == true) *pi = 1; + + if (*pi == 0) + { + //event_log_error (hashcat_ctx, "%s(): no feature sets supported", __func__); + return -1; + } + + break; + + case MTL_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK: + // M1 max is 1024 + // [MTLComputePipelineState maxTotalThreadsPerThreadgroup] + *pi = 1024; + break; + + case MTL_DEVICE_ATTRIBUTE_CLOCK_RATE: + // unknown + *pi = 1000000; + break; + + case MTL_DEVICE_ATTRIBUTE_MAX_SHARED_MEMORY_PER_BLOCK: + // 32k + *pi = 32768; + break; + + case MTL_DEVICE_ATTRIBUTE_TOTAL_CONSTANT_MEMORY: + // Maximum function memory allocation for a buffer in the constant address space + // 64k + *pi = 64 * 1024; + break; + + case MTL_DEVICE_ATTRIBUTE_MAX_TRANSFER_RATE: + val64 = 0; + + SEL maxTransferRateSelector = NSSelectorFromString(@"maxTransferRate"); + + hc_mtlInvocationHelper (metal_device, maxTransferRateSelector, &val64); + + *pi = (val64 == 0) ? 0 : val64 / 125; // kb/s + + break; + + case MTL_DEVICE_ATTRIBUTE_HEADLESS: + valBool = [metal_device isHeadless]; + *pi = (valBool == true) ? 1 : 0; + break; + + case MTL_DEVICE_ATTRIBUTE_LOW_POWER: + valBool = [metal_device isLowPower]; + *pi = (valBool == true) ? 1 : 0; + break; + + case MTL_DEVICE_ATTRIBUTE_REMOVABLE: + valBool = [metal_device isRemovable]; + *pi = (valBool == true) ? 1 : 0; + break; + + case MTL_DEVICE_ATTRIBUTE_REGISTRY_ID: + *pi = (int) [metal_device registryID]; + break; + + case MTL_DEVICE_ATTRIBUTE_PHYSICAL_LOCATION: + *pi = 0; + + SEL locationSelector = NSSelectorFromString(@"location"); + valInt = 0; + + hc_mtlInvocationHelper (metal_device, locationSelector, &valInt); + + *pi = valInt; + + break; + + case MTL_DEVICE_ATTRIBUTE_LOCATION_NUMBER: + *pi = 0; + + SEL locationNumberSelector = NSSelectorFromString(@"locationNumber"); + + valInt = 0; + hc_mtlInvocationHelper (metal_device, locationNumberSelector, &valInt); + + *pi = valInt; + + break; + + default: + event_log_error (hashcat_ctx, "%s(): unknown attribute (%d)", __func__, attrib); + return -1; + } + + return 0; +} + +int hc_mtlMemGetInfo (void *hashcat_ctx, size_t *mem_free, size_t *mem_total) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + struct vm_statistics64 vm_stats; + vm_size_t page_size = 0; + unsigned int count = HOST_VM_INFO64_COUNT; + + mach_port_t port = mach_host_self(); + + if (host_page_size (port, &page_size) != KERN_SUCCESS) + { + event_log_error (hashcat_ctx, "metalMemGetInfo(): cannot get page_size"); + + return -1; + } + + if (host_statistics64 (port, HOST_VM_INFO64, (host_info64_t) &vm_stats, &count) != KERN_SUCCESS) + { + event_log_error (hashcat_ctx, "metalMemGetInfo(): cannot get vm_stats"); + + return -1; + } + + uint64_t mem_free_tmp = (uint64_t) (vm_stats.free_count - vm_stats.speculative_count) * page_size; + uint64_t mem_used_tmp = (uint64_t) (vm_stats.active_count + vm_stats.inactive_count + vm_stats.wire_count) * page_size; + + *mem_free = (size_t) mem_free_tmp; + *mem_total = (size_t) (mem_free_tmp + mem_used_tmp); + + return 0; +} + +int hc_mtlDeviceMaxMemAlloc (void *hashcat_ctx, size_t *bytes, mtl_device_id metal_device) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_device == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid device", __func__); + + return -1; + } + + uint64_t memsize = 0; + + SEL maxBufferLengthSelector = NSSelectorFromString(@"maxBufferLength"); + + if (hc_mtlInvocationHelper (metal_device, maxBufferLengthSelector, &memsize) == -1) return -1; + + if (memsize == 0) + { + event_log_error (hashcat_ctx, "%s(): invalid maxBufferLength", __func__); + + return -1; + } + + *bytes = (size_t) memsize; + + return 0; +} + +int hc_mtlDeviceTotalMem (void *hashcat_ctx, size_t *bytes, mtl_device_id metal_device) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_device == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid device", __func__); + + return -1; + } + + uint64_t memsize = 0; + + if (true) + { + memsize = [metal_device recommendedMaxWorkingSetSize]; + } + else + { + size_t len = sizeof (memsize); + + if (sysctlbyname ("hw.memsize", &memsize, &len, NULL, 0) != 0) + { + event_log_error (hashcat_ctx, "%s(): sysctlbyname(hw.memsize) failed", __func__); + + return -1; + } + } + + if (memsize == 0) + { + event_log_error (hashcat_ctx, "%s(): invalid memory size", __func__); + + return -1; + } + + *bytes = (size_t) memsize; + + return 0; +} + +int hc_mtlCreateCommandQueue (void *hashcat_ctx, mtl_device_id metal_device, mtl_command_queue *command_queue) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_device == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid device", __func__); + + return -1; + } + + mtl_command_queue queue = [metal_device newCommandQueue]; + + if (queue == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create newCommandQueue", __func__); + + return -1; + } + + *command_queue = queue; + + return 0; + +} + +int hc_mtlCreateKernel (void *hashcat_ctx, mtl_device_id metal_device, mtl_library metal_library, const char *func_name, mtl_function *metal_function, mtl_pipeline *metal_pipeline) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_device == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid device", __func__); + + return -1; + } + + if (metal_library == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid library", __func__); + + return -1; + } + + if (func_name == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid function name", __func__); + + return -1; + } + + NSError *error = nil; + + NSString *f_name = [NSString stringWithCString: func_name encoding: NSUTF8StringEncoding]; + + mtl_function mtl_func = [metal_library newFunctionWithName: f_name]; + + if (mtl_func == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create '%s' function", __func__, func_name); + + return -1; + } + + mtl_pipeline mtl_pipe = [metal_device newComputePipelineStateWithFunction: mtl_func error: &error]; + + if (error != nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create '%s' pipeline, %s", __func__, func_name, [[error localizedDescription] UTF8String]); + + return -1; + } + + if (mtl_pipe == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create '%s' pipeline", __func__, func_name); + + return -1; + } + + *metal_function = mtl_func; + *metal_pipeline = mtl_pipe; + + return 0; +} + +int hc_mtlGetMaxTotalThreadsPerThreadgroup (void *hashcat_ctx, mtl_pipeline metal_pipeline, unsigned int *maxTotalThreadsPerThreadgroup) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_pipeline == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid pipeline", __func__); + + return -1; + } + + *maxTotalThreadsPerThreadgroup = [metal_pipeline maxTotalThreadsPerThreadgroup]; + + return 0; +} + +int hc_mtlGetThreadExecutionWidth (void *hashcat_ctx, mtl_pipeline metal_pipeline, unsigned int *threadExecutionWidth) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_pipeline == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid pipeline", __func__); + + return -1; + } + + *threadExecutionWidth = [metal_pipeline threadExecutionWidth]; + + return 0; +} + +int hc_mtlCreateBuffer (void *hashcat_ctx, mtl_device_id metal_device, size_t size, void *ptr, mtl_mem *metal_buffer) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_device == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid device", __func__); + + return -1; + } + + mtl_mem buf = NULL; + + MTLResourceOptions bufferOptions = MTLResourceStorageModeShared; + + if (ptr == NULL) + { + buf = [metal_device newBufferWithLength:size options:bufferOptions]; + } + else + { + buf = [metal_device newBufferWithBytes:ptr length:size options:bufferOptions]; + } + + if (buf == nil) + { + event_log_error (hashcat_ctx, "%s(): %s failed (size: %zu)", __func__, (ptr == NULL) ? "newBufferWithLength" : "newBufferWithBytes", size); + + return -1; + } + + *metal_buffer = buf; + + return 0; +} + +int hc_mtlReleaseMemObject (void *hashcat_ctx, mtl_mem metal_buffer) +{ + backend_ctx_t *backend_ctx = ((hashcat_ctx_t *) hashcat_ctx)->backend_ctx; + + MTL_PTR *mtl = (MTL_PTR *) backend_ctx->mtl; + + if (mtl == NULL) return -1; + + if (metal_buffer == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal buffer", __func__); + + return -1; + } + + [metal_buffer setPurgeableState:MTLPurgeableStateEmpty]; + [metal_buffer release]; + + return 0; +} + +int hc_mtlReleaseFunction (void *hashcat_ctx, mtl_function metal_function) +{ + if (metal_function == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal function", __func__); + + return -1; + } + + [metal_function release]; + + return 0; +} + +int hc_mtlReleaseLibrary (void *hashcat_ctx, mtl_library metal_library) +{ + if (metal_library == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal library", __func__); + + return -1; + } + + [metal_library release]; + metal_library = nil; + + return 0; +} + +int hc_mtlReleaseCommandQueue (void *hashcat_ctx, mtl_command_queue command_queue) +{ + if (command_queue == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal command queue", __func__); + + return -1; + } + + [command_queue release]; + command_queue = nil; + + return 0; +} + +int hc_mtlReleaseDevice (void *hashcat_ctx, mtl_device_id metal_device) +{ + if (metal_device == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal device", __func__); + + return -1; + } + + [metal_device release]; + metal_device = nil; + + return 0; +} + +// device to device + +int hc_mtlMemcpyDtoD (void *hashcat_ctx, mtl_command_queue command_queue, mtl_mem buf_dst, size_t buf_dst_off, mtl_mem buf_src, size_t buf_src_off, size_t buf_size) +{ + if (command_queue == nil) + { + event_log_error (hashcat_ctx, "%s(): metal command queue is invalid", __func__); + return -1; + } + + if (buf_src == nil) + { + event_log_error (hashcat_ctx, "%s(): metal src buffer is invalid", __func__); + return -1; + } + + if (buf_src_off < 0) + { + event_log_error (hashcat_ctx, "%s(): src buffer offset is invalid", __func__); + return -1; + } + + if (buf_dst == nil) + { + event_log_error (hashcat_ctx, "%s(): metal dst buffer is invalid", __func__); + return -1; + } + + if (buf_dst_off < 0) + { + event_log_error (hashcat_ctx, "%s(): dst buffer offset is invalid", __func__); + return -1; + } + + if (buf_size <= 0) + { + event_log_error (hashcat_ctx, "%s(): buffer size is invalid", __func__); + return -1; + } + + id command_buffer = [command_queue commandBuffer]; + + if (command_buffer == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create a new command buffer", __func__); + return -1; + } + + id blit_encoder = [command_buffer blitCommandEncoder]; + + if (blit_encoder == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create a blit command encoder", __func__); + return -1; + } + + // copy + + [blit_encoder copyFromBuffer: buf_src sourceOffset: buf_src_off toBuffer: buf_dst destinationOffset: buf_dst_off size: buf_size]; + + // finish encoding and start the data transfer + + [blit_encoder endEncoding]; + [command_buffer commit]; + + // Wait for complete + + [command_buffer waitUntilCompleted]; + + return 0; +} + +// host to device + +int hc_mtlMemcpyHtoD (void *hashcat_ctx, mtl_command_queue command_queue, mtl_mem buf_dst, size_t buf_dst_off, const void *buf_src, size_t buf_size) +{ + if (command_queue == nil) + { + event_log_error (hashcat_ctx, "%s(): metal command queue is invalid", __func__); + return -1; + } + + if (buf_src == nil) + { + event_log_error (hashcat_ctx, "%s(): metal src buffer is invalid", __func__); + return -1; + } + + if (buf_dst == nil) + { + event_log_error (hashcat_ctx, "%s(): host dst buffer is invalid", __func__); + return -1; + } + + if (buf_size <= 0) + { + event_log_error (hashcat_ctx, "%s(): buffer size is invalid", __func__); + return -1; + } + + if (buf_dst_off < 0) + { + event_log_error (hashcat_ctx, "%s(): buffer dst offset is invalid", __func__); + return -1; + } + + void *buf_dst_ptr = [buf_dst contents]; + + if (buf_dst_ptr == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to get metal buffer data pointer", __func__); + + return -1; + } + + if (memcpy (buf_dst_ptr + buf_dst_off, buf_src, buf_size) != buf_dst_ptr + buf_dst_off) + { + event_log_error (hashcat_ctx, "%s(): memcpy failed", __func__); + + return -1; + } + + [buf_dst didModifyRange: NSMakeRange (buf_dst_off, buf_size)]; + + return 0; +} + +// device to host + +int hc_mtlMemcpyDtoH (void *hashcat_ctx, mtl_command_queue command_queue, void *buf_dst, mtl_mem buf_src, size_t buf_src_off, size_t buf_size) +{ + if (command_queue == nil) + { + event_log_error (hashcat_ctx, "%s(): metal command queue is invalid", __func__); + return -1; + } + + if (buf_src == nil) + { + event_log_error (hashcat_ctx, "%s(): metal src buffer is invalid", __func__); + return -1; + } + + if (buf_dst == nil) + { + event_log_error (hashcat_ctx, "%s(): host dst buffer is invalid", __func__); + return -1; + } + + if (buf_size <= 0) + { + event_log_error (hashcat_ctx, "%s(): buffer size is invalid", __func__); + return -1; + } + + id command_buffer = [command_queue commandBuffer]; + + if (command_buffer == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create a new command buffer", __func__); + return -1; + } + + id blit_encoder = [command_buffer blitCommandEncoder]; + + [blit_encoder synchronizeResource: buf_src]; + + // Finish encoding and start the data transfer to the CPU + + [blit_encoder endEncoding]; + [command_buffer commit]; + + // Wait for complete + + [command_buffer waitUntilCompleted]; + + // get src buf ptr + + void *buf_src_ptr = [buf_src contents]; + + if (buf_src_ptr == nil) + { + event_log_error (hashcat_ctx, "%s(): failed to get metal buffer data pointer", __func__); + + return -1; + } + + if (memcpy (buf_dst, buf_src_ptr + buf_src_off, buf_size) != buf_dst) + { + event_log_error (hashcat_ctx, "%s(): memcpy failed", __func__); + + return -1; + } + + return 0; +} + +int hc_mtlRuntimeGetVersionString (void *hashcat_ctx, char *runtimeVersion_str, size_t *size) +{ + CFURLRef plist_url = CFURLCreateWithFileSystemPath (kCFAllocatorDefault, CFSTR("/System/Library/Frameworks/Metal.framework/Versions/Current/Resources/version.plist"), kCFURLPOSIXPathStyle, false); + + if (plist_url == NULL) + { + event_log_error (hashcat_ctx, "%s(): CFURLCreateWithFileSystemPath() failed\n", __func__); + + return -1; + } + + CFReadStreamRef plist_stream = CFReadStreamCreateWithFile (NULL, plist_url); + + if (plist_stream == NULL) + { + event_log_error (hashcat_ctx, "%s(): CFReadStreamCreateWithFile() failed\n", __func__); + + CFRelease (plist_url); + + return -1; + } + + if (CFReadStreamOpen (plist_stream) == false) + { + event_log_error (hashcat_ctx, "%s(): CFReadStreamOpen() failed\n", __func__); + + CFRelease (plist_stream); + CFRelease (plist_url); + + return -1; + } + + CFPropertyListRef plist_prop = CFPropertyListCreateWithStream (NULL, plist_stream, 0, kCFPropertyListImmutable, NULL, NULL); + + if (plist_prop == NULL) + { + event_log_error (hashcat_ctx, "%s(): CFPropertyListCreateWithStream() failed\n", __func__); + + CFReadStreamClose (plist_stream); + + CFRelease (plist_stream); + CFRelease (plist_url); + return -1; + } + + CFStringRef runtime_version_str = CFRetain (CFDictionaryGetValue (plist_prop, CFSTR("CFBundleVersion"))); + + if (runtime_version_str != NULL) + { + if (runtimeVersion_str == NULL) + { + CFIndex len = CFStringGetLength (runtime_version_str); + CFIndex maxSize = CFStringGetMaximumSizeForEncoding (len, kCFStringEncodingUTF8) + 1; + *size = maxSize; + return 0; + } + + CFIndex maxSize = *size; + + if (CFStringGetCString (runtime_version_str, runtimeVersion_str, maxSize, kCFStringEncodingUTF8) == false) + { + event_log_error (hashcat_ctx, "%s(): CFStringGetCString() failed\n", __func__); + + hcfree (runtimeVersion_str); + + return -1; + } + + return 0; + } + + return -1; +} + +int hc_mtlEncodeComputeCommand_pre (void *hashcat_ctx, mtl_pipeline metal_pipeline, mtl_command_queue metal_command_queue, mtl_command_buffer *metal_command_buffer, mtl_command_encoder *metal_command_encoder) +{ + if (metal_pipeline == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal_pipeline", __func__); + + return -1; + } + + if (metal_command_queue == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal_command_queue", __func__); + + return -1; + } + + id metal_commandBuffer = [metal_command_queue commandBuffer]; + + if (metal_commandBuffer == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal_commandBuffer", __func__); + + return -1; + } + + id metal_commandEncoder = [metal_commandBuffer computeCommandEncoder]; + + if (metal_commandEncoder == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal_commandBuffer", __func__); + + return -1; + } + + [metal_commandEncoder setComputePipelineState: metal_pipeline]; + + *metal_command_buffer = metal_commandBuffer; + *metal_command_encoder = metal_commandEncoder; + + return 0; +} + +int hc_mtlSetCommandEncoderArg (void *hashcat_ctx, mtl_command_encoder metal_command_encoder, size_t off, size_t idx, mtl_mem buf, void *host_data, size_t host_data_size) +{ + if (metal_command_encoder == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal_command_encoder", __func__); + + return -1; + } + + if (buf == nil && host_data == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid buf/host_data", __func__); + + return -1; + } + + if (buf == nil) + { + if (host_data_size <= 0) + { + event_log_error (hashcat_ctx, "%s(): invalid host_data size", __func__); + + return -1; + } + } + else + { + if (off < 0) + { + event_log_error (hashcat_ctx, "%s(): invalid buf off", __func__); + + return -1; + } + } + + if (idx < 0) + { + event_log_error (hashcat_ctx, "%s(): invalid buf/host_data idx", __func__); + + return -1; + } + + if (host_data == nil) + { + [metal_command_encoder setBuffer: buf offset: off atIndex: idx]; + } + else + { + [metal_command_encoder setBytes: host_data length: host_data_size atIndex: idx]; + } + + return 0; +} + +int hc_mtlEncodeComputeCommand (void *hashcat_ctx, mtl_command_encoder metal_command_encoder, mtl_command_buffer metal_command_buffer, size_t global_work_size, size_t local_work_size, double *ms) +{ +/* + #define MTL_OPTS 3 + + #if MTL_OPTS == 0 + local_work_size = 1; + MTLSize threadsGroup = {global_work_size, 1, 1}; + MTLSize numThreadgroups = {local_work_size, 1, 1}; + #elif MTL_OPTS == 1 + MTLSize numThreadgroups = {local_work_size, 1, 1}; + MTLSize threadsGroup = { (global_work_size + local_work_size)/local_work_size, 1, 1}; + #else +*/ + MTLSize numThreadgroups = {local_work_size, 1, 1}; + MTLSize threadsGroup = {global_work_size, 1, 1}; +// #endif + + if (metal_command_encoder == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal_command_encoder", __func__); + + return -1; + } + + if (metal_command_buffer == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal_command_buffer", __func__); + + return -1; + } + +// #if MTL_OPTS == 0 +// [metal_command_encoder dispatchThreads: threadsGroup threadsPerThreadgroup: numThreadgroups]; +// #else + [metal_command_encoder dispatchThreadgroups: threadsGroup threadsPerThreadgroup: numThreadgroups]; +// #endif + + [metal_command_encoder endEncoding]; + [metal_command_buffer commit]; + [metal_command_buffer waitUntilCompleted]; + + CFTimeInterval myGPUStartTime = 0; + CFTimeInterval myGPUEndTime = 0; + + SEL myGPUStartTimeSelector = NSSelectorFromString(@"GPUStartTime"); + SEL myGPUEndTimeSelector = NSSelectorFromString(@"GPUEndTime"); + + if (hc_mtlInvocationHelper (metal_command_buffer, myGPUStartTimeSelector, &myGPUStartTime) == -1) return -1; + if (hc_mtlInvocationHelper (metal_command_buffer, myGPUEndTimeSelector, &myGPUEndTime) == -1) return -1; + + CFTimeInterval elapsed = myGPUEndTime - myGPUStartTime; + + *ms = (1000.0 * elapsed); + + return 0; +} + +int hc_mtlCreateLibraryWithFile (void *hashcat_ctx, mtl_device_id metal_device, const char *cached_file, mtl_library *metal_library) +{ + NSError *error = nil; + + if (metal_device == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metal device", __func__); + + return -1; + } + + if (cached_file == nil) + { + event_log_error (hashcat_ctx, "%s(): invalid metallib", __func__); + + return -1; + } + + NSString *k_string = [NSString stringWithCString: cached_file encoding: NSUTF8StringEncoding]; + + if (k_string != nil) + { + id r = [metal_device newLibraryWithFile: k_string error: &error]; + + if (error != nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create metal library from metallib, %s", __func__, [[error localizedDescription] UTF8String]); + return -1; + } + + *metal_library = r; + + return 0; + } + + return -1; +} + +int hc_mtlCreateLibraryWithSource (void *hashcat_ctx, mtl_device_id metal_device, const char *kernel_sources, const char *build_options_buf, const char *cpath, mtl_library *metal_library) +{ + NSError *error = nil; + + NSString *k_string = [NSString stringWithCString: kernel_sources encoding: NSUTF8StringEncoding]; + + if (k_string != nil) + { + MTLCompileOptions *compileOptions = [MTLCompileOptions new]; + + NSMutableDictionary *build_options_dict = nil; + + if (build_options_buf != nil) + { + //printf("using build_opts from arg:\n%s\n", build_options_buf); + + build_options_dict = [NSMutableDictionary dictionary]; //[[NSMutableDictionary alloc] init]; + + if (hc_mtlBuildOptionsToDict (hashcat_ctx, build_options_buf, cpath, build_options_dict) == -1) + { + event_log_error (hashcat_ctx, "%s(): failed to build options dictionary", __func__); + + [build_options_dict release]; + return -1; + } + + compileOptions.preprocessorMacros = build_options_dict; + } + + // todo: detect current os version and choose the right +// compileOptions.languageVersion = MTL_LANGUAGEVERSION_2_3; +/* + if (@available(macOS 12.0, *)) + { + compileOptions.languageVersion = MTL_LANGUAGEVERSION_2_4; + } + else if (@available(macOS 11.0, *)) + { + compileOptions.languageVersion = MTL_LANGUAGEVERSION_2_3; + } + else if (@available(macOS 10.15, *)) + { + compileOptions.languageVersion = MTL_LANGUAGEVERSION_2_2; + } + else if (@available(macOS 10.14, *)) + { + compileOptions.languageVersion = MTL_LANGUAGEVERSION_2_1; + } + else if (@available(macOS 10.13, *)) + { + compileOptions.languageVersion = MTL_LANGUAGEVERSION_2_0; + } + else if (@available(macOS 10.12, *)) + { + compileOptions.languageVersion = MTL_LANGUAGEVERSION_1_2; + } + else if (@available(macOS 10.11, *)) + { + compileOptions.languageVersion = MTL_LANGUAGEVERSION_1_1; + } +*/ + id r = [metal_device newLibraryWithSource: k_string options: compileOptions error: &error]; + + [compileOptions release]; + compileOptions = nil; + + if (build_options_dict != nil) + { + [build_options_dict release]; + build_options_dict = nil; + } + + if (error != nil) + { + event_log_error (hashcat_ctx, "%s(): failed to create metal library, %s", __func__, [[error localizedDescription] UTF8String]); + + return -1; + } + + *metal_library = r; + + return 0; + } + + return -1; +} diff --git a/src/hashes.c b/src/hashes.c index ffb47b182..3ec190812 100644 --- a/src/hashes.c +++ b/src/hashes.c @@ -355,6 +355,20 @@ int check_hash (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param, pla } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + rc = hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, tmps, device_param->metal_d_tmps, plain->gidvid * hashconfig->tmp_size, hashconfig->tmp_size); + + if (rc == -1) + { + hcfree (tmps); + + return -1; + } + } + #endif + if (device_param->is_opencl == true) { rc = hc_clEnqueueReadBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_tmps, CL_FALSE, plain->gidvid * hashconfig->tmp_size, hashconfig->tmp_size, tmps, 0, NULL, &opencl_event); @@ -574,6 +588,13 @@ int check_cracked (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) if (hc_hipStreamSynchronize (hashcat_ctx, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, &num_cracked, device_param->metal_d_result, 0, sizeof (u32)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { /* blocking */ @@ -624,6 +645,20 @@ int check_cracked (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + rc = hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, cracked, device_param->metal_d_plain_bufs, 0, num_cracked * sizeof (plain_t)); + + if (rc == -1) + { + hcfree (cracked); + + return -1; + } + } + #endif + if (device_param->is_opencl == true) { /* blocking */ @@ -703,6 +738,18 @@ int check_cracked (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) } } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + rc = run_metal_kernel_memset32 (hashcat_ctx, device_param, device_param->metal_d_digests_shown, salt_buf->digests_offset * sizeof (u32), 0, salt_buf->digests_cnt * sizeof (u32)); + + if (rc == -1) + { + break; + } + } + #endif + if (device_param->is_opencl == true) { /* NOTE: run_opencl_kernel_bzero() does not handle buffer offset */ @@ -751,6 +798,13 @@ int check_cracked (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param) if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_result, sizeof (u32)) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_result, sizeof (u32)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_bzero (hashcat_ctx, device_param, device_param->opencl_d_result, sizeof (u32)) == -1) return -1; diff --git a/src/modules/module_01500.c b/src/modules/module_01500.c index 35edcf92b..c4ccbc51c 100644 --- a/src/modules/module_01500.c +++ b/src/modules/module_01500.c @@ -151,7 +151,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY { if ((user_options->attack_mode == ATTACK_MODE_BF) && (hashes->salts_cnt == 1) && (user_options->slow_candidates == false)) { - hc_asprintf (&jit_build_options, "-DDESCRYPT_SALT=%u", hashes->salts_buf[0].salt_buf[0] & 0xfff); + hc_asprintf (&jit_build_options, "-D DESCRYPT_SALT=%u", hashes->salts_buf[0].salt_buf[0] & 0xfff); } return jit_build_options; @@ -161,7 +161,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY { if ((user_options->attack_mode == ATTACK_MODE_BF) && (hashes->salts_cnt == 1) && (user_options->slow_candidates == false)) { - hc_asprintf (&jit_build_options, "-DDESCRYPT_SALT=%u -D _unroll", hashes->salts_buf[0].salt_buf[0] & 0xfff); + hc_asprintf (&jit_build_options, "-D DESCRYPT_SALT=%u -D _unroll", hashes->salts_buf[0].salt_buf[0] & 0xfff); } } // ROCM @@ -169,7 +169,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY { if ((user_options->attack_mode == ATTACK_MODE_BF) && (hashes->salts_cnt == 1) && (user_options->slow_candidates == false)) { - hc_asprintf (&jit_build_options, "-DDESCRYPT_SALT=%u -D _unroll", hashes->salts_buf[0].salt_buf[0] & 0xfff); + hc_asprintf (&jit_build_options, "-D DESCRYPT_SALT=%u -D _unroll", hashes->salts_buf[0].salt_buf[0] & 0xfff); } } // ROCM @@ -177,7 +177,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY { if ((user_options->attack_mode == ATTACK_MODE_BF) && (hashes->salts_cnt == 1) && (user_options->slow_candidates == false)) { - hc_asprintf (&jit_build_options, "-DDESCRYPT_SALT=%u -D _unroll -fno-experimental-new-pass-manager", hashes->salts_buf[0].salt_buf[0] & 0xfff); + hc_asprintf (&jit_build_options, "-D DESCRYPT_SALT=%u -D _unroll -fno-experimental-new-pass-manager", hashes->salts_buf[0].salt_buf[0] & 0xfff); } else { @@ -188,7 +188,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY { if ((user_options->attack_mode == ATTACK_MODE_BF) && (hashes->salts_cnt == 1) && (user_options->slow_candidates == false)) { - hc_asprintf (&jit_build_options, "-DDESCRYPT_SALT=%u", hashes->salts_buf[0].salt_buf[0] & 0xfff); + hc_asprintf (&jit_build_options, "-D DESCRYPT_SALT=%u", hashes->salts_buf[0].salt_buf[0] & 0xfff); } } diff --git a/src/modules/module_06211.c b/src/modules/module_06211.c index 4217f28ed..43b455dba 100644 --- a/src/modules/module_06211.c +++ b/src/modules/module_06211.c @@ -77,7 +77,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_06212.c b/src/modules/module_06212.c index 3d482b1b4..f610dc775 100644 --- a/src/modules/module_06212.c +++ b/src/modules/module_06212.c @@ -77,7 +77,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_06213.c b/src/modules/module_06213.c index d6c164198..04803cc70 100644 --- a/src/modules/module_06213.c +++ b/src/modules/module_06213.c @@ -77,7 +77,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_06241.c b/src/modules/module_06241.c index 752cbf39c..8189b3fc6 100644 --- a/src/modules/module_06241.c +++ b/src/modules/module_06241.c @@ -78,7 +78,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_06242.c b/src/modules/module_06242.c index ee63223ce..6f93913dc 100644 --- a/src/modules/module_06242.c +++ b/src/modules/module_06242.c @@ -78,7 +78,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_06243.c b/src/modules/module_06243.c index acd26004a..164fe982f 100644 --- a/src/modules/module_06243.c +++ b/src/modules/module_06243.c @@ -78,7 +78,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_06800.c b/src/modules/module_06800.c index a897b4f69..d76376921 100644 --- a/src/modules/module_06800.c +++ b/src/modules/module_06800.c @@ -56,7 +56,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_08900.c b/src/modules/module_08900.c index bca25fc39..06507a856 100644 --- a/src/modules/module_08900.c +++ b/src/modules/module_08900.c @@ -56,7 +56,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } // amdgpu-pro-20.50-1234664-ubuntu-20.04 (legacy) @@ -266,7 +269,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY char *jit_build_options = NULL; - hc_asprintf (&jit_build_options, "-DSCRYPT_N=%u -DSCRYPT_R=%u -DSCRYPT_P=%u -DSCRYPT_TMTO=%" PRIu64 " -DSCRYPT_TMP_ELEM=%" PRIu64, + hc_asprintf (&jit_build_options, "-D SCRYPT_N=%u -D SCRYPT_R=%u -D SCRYPT_P=%u -D SCRYPT_TMTO=%" PRIu64 " -D SCRYPT_TMP_ELEM=%" PRIu64, hashes->salts_buf[0].scrypt_N, hashes->salts_buf[0].scrypt_r, hashes->salts_buf[0].scrypt_p, diff --git a/src/modules/module_09300.c b/src/modules/module_09300.c index cb61a0f6c..74c4fe913 100644 --- a/src/modules/module_09300.c +++ b/src/modules/module_09300.c @@ -56,7 +56,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; @@ -258,7 +261,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY char *jit_build_options = NULL; - hc_asprintf (&jit_build_options, "-DSCRYPT_N=%u -DSCRYPT_R=%u -DSCRYPT_P=%u -DSCRYPT_TMTO=%" PRIu64 " -DSCRYPT_TMP_ELEM=%" PRIu64, + hc_asprintf (&jit_build_options, "-D SCRYPT_N=%u -D SCRYPT_R=%u -D SCRYPT_P=%u -D SCRYPT_TMTO=%" PRIu64 " -D SCRYPT_TMP_ELEM=%" PRIu64, hashes->salts_buf[0].scrypt_N, hashes->salts_buf[0].scrypt_r, hashes->salts_buf[0].scrypt_p, diff --git a/src/modules/module_09500.c b/src/modules/module_09500.c index cbbaca530..5fb4be868 100644 --- a/src/modules/module_09500.c +++ b/src/modules/module_09500.c @@ -62,7 +62,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_09600.c b/src/modules/module_09600.c index a9831b9aa..d9753cbe2 100644 --- a/src/modules/module_09600.c +++ b/src/modules/module_09600.c @@ -65,7 +65,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_12700.c b/src/modules/module_12700.c index 419ab38e9..f69858246 100644 --- a/src/modules/module_12700.c +++ b/src/modules/module_12700.c @@ -60,7 +60,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13711.c b/src/modules/module_13711.c index df4b038ef..7d956350f 100644 --- a/src/modules/module_13711.c +++ b/src/modules/module_13711.c @@ -88,7 +88,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13712.c b/src/modules/module_13712.c index 585fde139..3093e80e2 100644 --- a/src/modules/module_13712.c +++ b/src/modules/module_13712.c @@ -88,7 +88,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13713.c b/src/modules/module_13713.c index c2d573f4d..3a53a4ef5 100644 --- a/src/modules/module_13713.c +++ b/src/modules/module_13713.c @@ -88,7 +88,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13721.c b/src/modules/module_13721.c index 2b54cf267..9db377617 100644 --- a/src/modules/module_13721.c +++ b/src/modules/module_13721.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } if (device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) diff --git a/src/modules/module_13722.c b/src/modules/module_13722.c index 4b3242ca4..4a899279e 100644 --- a/src/modules/module_13722.c +++ b/src/modules/module_13722.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } if (device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) diff --git a/src/modules/module_13723.c b/src/modules/module_13723.c index 3d28e8437..4871ca55a 100644 --- a/src/modules/module_13723.c +++ b/src/modules/module_13723.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } if (device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) diff --git a/src/modules/module_13733.c b/src/modules/module_13733.c index ac8b7c030..da0dbc473 100644 --- a/src/modules/module_13733.c +++ b/src/modules/module_13733.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AppleM1, OpenCL, MTLCompilerService never-end (pure/optimized kernel) if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13741.c b/src/modules/module_13741.c index f6df663e8..74c0283fd 100644 --- a/src/modules/module_13741.c +++ b/src/modules/module_13741.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13742.c b/src/modules/module_13742.c index 59aca8d53..0206b424b 100644 --- a/src/modules/module_13742.c +++ b/src/modules/module_13742.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13743.c b/src/modules/module_13743.c index cf58c6d44..093fbfd1f 100644 --- a/src/modules/module_13743.c +++ b/src/modules/module_13743.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13751.c b/src/modules/module_13751.c index fb999023a..57435bca3 100644 --- a/src/modules/module_13751.c +++ b/src/modules/module_13751.c @@ -88,7 +88,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13752.c b/src/modules/module_13752.c index 02fe05693..6cc3b9153 100644 --- a/src/modules/module_13752.c +++ b/src/modules/module_13752.c @@ -88,7 +88,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13753.c b/src/modules/module_13753.c index 443ba0274..f5fefbdc1 100644 --- a/src/modules/module_13753.c +++ b/src/modules/module_13753.c @@ -88,7 +88,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13761.c b/src/modules/module_13761.c index dd686887a..bb18d91f8 100644 --- a/src/modules/module_13761.c +++ b/src/modules/module_13761.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13762.c b/src/modules/module_13762.c index 116db35af..c75b98a49 100644 --- a/src/modules/module_13762.c +++ b/src/modules/module_13762.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_13763.c b/src/modules/module_13763.c index 070b8df21..43fac2ef3 100644 --- a/src/modules/module_13763.c +++ b/src/modules/module_13763.c @@ -89,7 +89,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_14700.c b/src/modules/module_14700.c index 5ce1ee308..8c447a784 100644 --- a/src/modules/module_14700.c +++ b/src/modules/module_14700.c @@ -66,7 +66,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_15200.c b/src/modules/module_15200.c index 976f6e349..66a994216 100644 --- a/src/modules/module_15200.c +++ b/src/modules/module_15200.c @@ -56,7 +56,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_15700.c b/src/modules/module_15700.c index 5f97873af..c448572e1 100644 --- a/src/modules/module_15700.c +++ b/src/modules/module_15700.c @@ -279,7 +279,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY char *jit_build_options = NULL; - hc_asprintf (&jit_build_options, "-DSCRYPT_N=%u -DSCRYPT_R=%u -DSCRYPT_P=%u -DSCRYPT_TMTO=%" PRIu64 " -DSCRYPT_TMP_ELEM=%" PRIu64, + hc_asprintf (&jit_build_options, "-D SCRYPT_N=%u -D SCRYPT_R=%u -D SCRYPT_P=%u -D SCRYPT_TMTO=%" PRIu64 " -D SCRYPT_TMP_ELEM=%" PRIu64, hashes->salts_buf[0].scrypt_N, hashes->salts_buf[0].scrypt_r, hashes->salts_buf[0].scrypt_p, diff --git a/src/modules/module_18900.c b/src/modules/module_18900.c index 436afdfd8..246ec4b46 100644 --- a/src/modules/module_18900.c +++ b/src/modules/module_18900.c @@ -71,7 +71,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_19600.c b/src/modules/module_19600.c index 29ccfe263..1e9861ad7 100644 --- a/src/modules/module_19600.c +++ b/src/modules/module_19600.c @@ -71,7 +71,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_19700.c b/src/modules/module_19700.c index beab1009b..b47ec6e40 100644 --- a/src/modules/module_19700.c +++ b/src/modules/module_19700.c @@ -71,7 +71,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_19800.c b/src/modules/module_19800.c index c7a50985a..5cab711b1 100644 --- a/src/modules/module_19800.c +++ b/src/modules/module_19800.c @@ -71,7 +71,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_19900.c b/src/modules/module_19900.c index 7b56ae41e..7a09d0f68 100644 --- a/src/modules/module_19900.c +++ b/src/modules/module_19900.c @@ -71,7 +71,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_20011.c b/src/modules/module_20011.c index 32b4c2d29..6a6f917d3 100644 --- a/src/modules/module_20011.c +++ b/src/modules/module_20011.c @@ -68,7 +68,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_20012.c b/src/modules/module_20012.c index 4c81a7ccc..f6ef86149 100644 --- a/src/modules/module_20012.c +++ b/src/modules/module_20012.c @@ -68,7 +68,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_20013.c b/src/modules/module_20013.c index f45e68ee7..d92ad4ca8 100644 --- a/src/modules/module_20013.c +++ b/src/modules/module_20013.c @@ -68,7 +68,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_22700.c b/src/modules/module_22700.c index 0aae58e78..462128712 100644 --- a/src/modules/module_22700.c +++ b/src/modules/module_22700.c @@ -266,7 +266,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY char *jit_build_options = NULL; - hc_asprintf (&jit_build_options, "-DSCRYPT_N=%u -DSCRYPT_R=%u -DSCRYPT_P=%u -DSCRYPT_TMTO=%" PRIu64 " -DSCRYPT_TMP_ELEM=%" PRIu64, + hc_asprintf (&jit_build_options, "-D SCRYPT_N=%u -D SCRYPT_R=%u -D SCRYPT_P=%u -D SCRYPT_TMTO=%" PRIu64 " -D SCRYPT_TMP_ELEM=%" PRIu64, hashes->salts_buf[0].scrypt_N, hashes->salts_buf[0].scrypt_r, hashes->salts_buf[0].scrypt_p, diff --git a/src/modules/module_23100.c b/src/modules/module_23100.c index db69c4947..ad5b36b95 100644 --- a/src/modules/module_23100.c +++ b/src/modules/module_23100.c @@ -67,7 +67,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_24500.c b/src/modules/module_24500.c index b6d7c380f..3dad9ce8d 100644 --- a/src/modules/module_24500.c +++ b/src/modules/module_24500.c @@ -68,7 +68,10 @@ bool module_unstable_warning (MAYBE_UNUSED const hashconfig_t *hashconfig, MAYBE // AMD Radeon Pro W5700X Compute Engine; 1.2 (Apr 22 2021 21:54:44); 11.3.1; 20E241 if ((device_param->opencl_platform_vendor_id == VENDOR_ID_APPLE) && (device_param->opencl_device_type & CL_DEVICE_TYPE_GPU)) { - return true; + if (device_param->is_metal == false) + { + return true; + } } return false; diff --git a/src/modules/module_27700.c b/src/modules/module_27700.c index 346b9f73d..ce33d36cb 100644 --- a/src/modules/module_27700.c +++ b/src/modules/module_27700.c @@ -264,7 +264,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY char *jit_build_options = NULL; - hc_asprintf (&jit_build_options, "-DSCRYPT_N=%u -DSCRYPT_R=%u -DSCRYPT_P=%u -DSCRYPT_TMTO=%" PRIu64 " -DSCRYPT_TMP_ELEM=%" PRIu64, + hc_asprintf (&jit_build_options, "-D SCRYPT_N=%u -D SCRYPT_R=%u -D SCRYPT_P=%u -D SCRYPT_TMTO=%" PRIu64 " -D SCRYPT_TMP_ELEM=%" PRIu64, hashes->salts_buf[0].scrypt_N, hashes->salts_buf[0].scrypt_r, hashes->salts_buf[0].scrypt_p, diff --git a/src/modules/module_28200.c b/src/modules/module_28200.c index 648a26403..c262bb55f 100644 --- a/src/modules/module_28200.c +++ b/src/modules/module_28200.c @@ -258,7 +258,7 @@ char *module_jit_build_options (MAYBE_UNUSED const hashconfig_t *hashconfig, MAY char *jit_build_options = NULL; - hc_asprintf (&jit_build_options, "-DSCRYPT_N=%u -DSCRYPT_R=%u -DSCRYPT_P=%u -DSCRYPT_TMTO=%" PRIu64 " -DSCRYPT_TMP_ELEM=%" PRIu64, + hc_asprintf (&jit_build_options, "-D SCRYPT_N=%u -D SCRYPT_R=%u -D SCRYPT_P=%u -D SCRYPT_TMTO=%" PRIu64 " -D SCRYPT_TMP_ELEM=%" PRIu64, hashes->salts_buf[0].scrypt_N, hashes->salts_buf[0].scrypt_r, hashes->salts_buf[0].scrypt_p, diff --git a/src/selftest.c b/src/selftest.c index 28b7b6d4f..977c38682 100644 --- a/src/selftest.c +++ b/src/selftest.c @@ -39,6 +39,15 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param device_param->kernel_params[18] = &device_param->hip_d_st_esalts_buf; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params[15] = device_param->metal_d_st_digests_buf; + device_param->kernel_params[17] = device_param->metal_d_st_salts_buf; + device_param->kernel_params[18] = device_param->metal_d_st_esalts_buf; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params[15] = &device_param->opencl_d_st_digests_buf; @@ -105,6 +114,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_pws_buf, &pw, 1 * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_buf, 0, &pw, 1 * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_buf, CL_FALSE, 0, 1 * sizeof (pw_t), &pw, 0, NULL, NULL) == -1) return -1; @@ -143,6 +159,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_pws_buf, &pw, 1 * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_buf, 0, &pw, 1 * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_buf, CL_FALSE, 0, 1 * sizeof (pw_t), &pw, 0, NULL, NULL) == -1) return -1; @@ -210,6 +233,15 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_pws_buf, &pw, 1 * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_combs_c, 0, &comb, 1 * sizeof (pw_t)) == -1) return -1; + + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_buf, 0, &pw, 1 * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_combs_c, CL_FALSE, 0, 1 * sizeof (pw_t), &comb, 0, NULL, NULL) == -1) return -1; @@ -248,6 +280,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_pws_buf, &pw, 1 * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_buf, 0, &pw, 1 * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_buf, CL_FALSE, 0, 1 * sizeof (pw_t), &pw, 0, NULL, NULL) == -1) return -1; @@ -302,6 +341,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_bfs_c, &bf, 1 * sizeof (bf_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_bfs_c, 0, &bf, 1 * sizeof (bf_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_bfs_c, CL_FALSE, 0, 1 * sizeof (bf_t), &bf, 0, NULL, NULL) == -1) return -1; @@ -401,6 +447,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_pws_buf, &pw, 1 * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_buf, 0, &pw, 1 * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_buf, CL_FALSE, 0, 1 * sizeof (pw_t), &pw, 0, NULL, NULL) == -1) return -1; @@ -432,6 +485,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_pws_buf, &pw, 1 * sizeof (pw_t), device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_pws_buf, 0, &pw, 1 * sizeof (pw_t)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_pws_buf, CL_FALSE, 0, 1 * sizeof (pw_t), &pw, 0, NULL, NULL) == -1) return -1; @@ -487,6 +547,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (run_hip_kernel_utf8toutf16le (hashcat_ctx, device_param, device_param->hip_d_pws_buf, 1) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_utf8toutf16le (hashcat_ctx, device_param, device_param->metal_d_pws_buf, 1) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_utf8toutf16le (hashcat_ctx, device_param, device_param->opencl_d_pws_buf, 1) == -1) return -1; @@ -513,6 +580,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipStreamSynchronize (hashcat_ctx, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, device_param->hooks_buf, device_param->metal_d_hooks, 0, device_param->size_hooks) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { /* blocking */ @@ -531,6 +605,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_hooks, device_param->hooks_buf, device_param->size_hooks, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_hooks, 0, device_param->hooks_buf, device_param->size_hooks) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_hooks, CL_FALSE, 0, device_param->size_hooks, device_param->hooks_buf, 0, NULL, NULL) == -1) return -1; @@ -591,6 +672,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipStreamSynchronize (hashcat_ctx, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, device_param->hooks_buf, device_param->metal_d_hooks, 0, device_param->size_hooks) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { /* blocking */ @@ -609,6 +697,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipMemcpyHtoDAsync (hashcat_ctx, device_param->hip_d_hooks, device_param->hooks_buf, device_param->size_hooks, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyHtoD (hashcat_ctx, device_param->metal_command_queue, device_param->metal_d_hooks, 0, device_param->hooks_buf, device_param->size_hooks) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueWriteBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_hooks, CL_FALSE, 0, device_param->size_hooks, device_param->hooks_buf, 0, NULL, NULL) == -1) return -1; @@ -701,6 +796,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (hc_hipEventRecord (hashcat_ctx, device_param->hip_event3, device_param->hip_stream) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (hc_mtlMemcpyDtoH (hashcat_ctx, device_param->metal_command_queue, &num_cracked, device_param->metal_d_result, 0, sizeof (u32)) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (hc_clEnqueueReadBuffer (hashcat_ctx, device_param->opencl_command_queue, device_param->opencl_d_result, CL_FALSE, 0, sizeof (u32), &num_cracked, 0, NULL, &opencl_event) == -1) return -1; @@ -747,6 +849,22 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_result, device_param->size_results) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + device_param->kernel_params[15] = device_param->metal_d_digests_buf; + device_param->kernel_params[17] = device_param->metal_d_salt_bufs; + device_param->kernel_params[18] = device_param->metal_d_esalt_bufs; + + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_pws_buf, device_param->size_pws) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_tmps, device_param->size_tmps) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_hooks, device_param->size_hooks) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_plain_bufs, device_param->size_plains) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_digests_shown, device_param->size_shown) == -1) return -1; + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_result, device_param->size_results) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { device_param->kernel_params[15] = &device_param->opencl_d_digests_buf; @@ -773,6 +891,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_rules_c, device_param->size_rules_c) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_rules_c, device_param->size_rules_c) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_bzero (hashcat_ctx, device_param, device_param->opencl_d_rules_c, device_param->size_rules_c) == -1) return -1; @@ -792,6 +917,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_rules_c, device_param->size_rules_c) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_rules_c, device_param->size_rules_c) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_bzero (hashcat_ctx, device_param, device_param->opencl_d_rules_c, device_param->size_rules_c) == -1) return -1; @@ -809,6 +941,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_combs_c, device_param->size_combs) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_combs_c, device_param->size_combs) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_bzero (hashcat_ctx, device_param, device_param->opencl_d_combs_c, device_param->size_combs) == -1) return -1; @@ -826,6 +965,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param if (run_hip_kernel_bzero (hashcat_ctx, device_param, device_param->hip_d_bfs_c, device_param->size_bfs) == -1) return -1; } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + if (run_metal_kernel_bzero (hashcat_ctx, device_param, device_param->metal_d_bfs_c, device_param->size_bfs) == -1) return -1; + } + #endif + if (device_param->is_opencl == true) { if (run_opencl_kernel_bzero (hashcat_ctx, device_param, device_param->opencl_d_bfs_c, device_param->size_bfs) == -1) return -1; @@ -866,6 +1012,13 @@ static int selftest (hashcat_ctx_t *hashcat_ctx, hc_device_param_t *device_param event_log_error (hashcat_ctx, "* Device #%u: ATTENTION! HIP kernel self-test failed.", device_param->device_id + 1); } + #if defined (__APPLE__) + if (device_param->is_metal == true) + { + event_log_error (hashcat_ctx, "* Device #%u: ATTENTION! Metal kernel self-test failed.", device_param->device_id + 1); + } + #endif + if (device_param->is_opencl == true) { event_log_error (hashcat_ctx, "* Device #%u: ATTENTION! OpenCL kernel self-test failed.", device_param->device_id + 1); diff --git a/src/terminal.c b/src/terminal.c index e40ae8b11..aab94cc84 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -972,6 +972,112 @@ void backend_info (hashcat_ctx_t *hashcat_ctx) } } + #if defined (__APPLE__) + if (backend_ctx->mtl) + { + event_log_info (hashcat_ctx, "Metal Info:"); + event_log_info (hashcat_ctx, "==========="); + event_log_info (hashcat_ctx, NULL); + + int metal_devices_cnt = backend_ctx->metal_devices_cnt; + int metal_runtimeVersion = backend_ctx->metal_runtimeVersion; + char *metal_runtimeVersionStr = backend_ctx->metal_runtimeVersionStr; + + if (metal_runtimeVersionStr != NULL) + { + event_log_info (hashcat_ctx, "Metal.Version.: %s", metal_runtimeVersionStr); + } + else + { + event_log_info (hashcat_ctx, "Metal.Version.: %d", metal_runtimeVersion); + } + + event_log_info (hashcat_ctx, NULL); + + for (int metal_devices_idx = 0; metal_devices_idx < metal_devices_cnt; metal_devices_idx++) + { + const int backend_devices_idx = backend_ctx->backend_device_from_metal[metal_devices_idx]; + + const hc_device_param_t *device_param = backend_ctx->devices_param + backend_devices_idx; + + int device_id = device_param->device_id; + int device_mtl_maj = device_param->mtl_major; + int device_mtl_min = device_param->mtl_minor; + int device_max_transfer_rate = device_param->device_max_transfer_rate; + int device_physical_location = device_param->device_physical_location; + int device_location_number = device_param->device_location_number; + int device_registryID = device_param->device_registryID; + int device_is_headless = device_param->device_is_headless; + int device_is_low_power = device_param->device_is_low_power; + int device_is_removable = device_param->device_is_removable; + + char *device_name = device_param->device_name; + + u32 device_processors = device_param->device_processors; + + u64 device_global_mem = device_param->device_global_mem; + u64 device_maxmem_alloc = device_param->device_maxmem_alloc; + u64 device_available_mem = device_param->device_available_mem; + u64 device_local_mem_size = device_param->device_local_mem_size; + + cl_device_type opencl_device_type = device_param->opencl_device_type; + cl_uint opencl_device_vendor_id = device_param->opencl_device_vendor_id; + char *opencl_device_vendor = device_param->opencl_device_vendor; + + if (device_param->device_id_alias_cnt) + { + event_log_info (hashcat_ctx, "Backend Device ID #%d (Alias: #%d)", device_id + 1, device_param->device_id_alias_buf[0] + 1); + } + else + { + event_log_info (hashcat_ctx, "Backend Device ID #%d", device_id + 1); + } + + event_log_info (hashcat_ctx, " Type...........: %s", ((opencl_device_type & CL_DEVICE_TYPE_CPU) ? "CPU" : ((opencl_device_type & CL_DEVICE_TYPE_GPU) ? "GPU" : "Accelerator"))); + event_log_info (hashcat_ctx, " Vendor.ID......: %u", opencl_device_vendor_id); + event_log_info (hashcat_ctx, " Vendor.........: %s", opencl_device_vendor); + event_log_info (hashcat_ctx, " Name...........: %s", device_name); + event_log_info (hashcat_ctx, " Processor(s)...: %u", device_processors); + event_log_info (hashcat_ctx, " Clock..........: N/A"); + event_log_info (hashcat_ctx, " Memory.Total...: %" PRIu64 " MB (limited to %" PRIu64 " MB allocatable in one block)", device_global_mem / 1024 / 1024, device_maxmem_alloc / 1024 / 1024); + event_log_info (hashcat_ctx, " Memory.Free....: %" PRIu64 " MB", device_available_mem / 1024 / 1024); + event_log_info (hashcat_ctx, " Local.Memory...: %" PRIu64 " KB", device_local_mem_size / 1024); + + switch (device_physical_location) + { + case MTL_DEVICE_LOCATION_BUILTIN: event_log_info (hashcat_ctx, " Phys.Location..: built-in"); break; + case MTL_DEVICE_LOCATION_SLOT: event_log_info (hashcat_ctx, " Phys.Location..: connected to slot %d", device_location_number); break; + case MTL_DEVICE_LOCATION_EXTERNAL: event_log_info (hashcat_ctx, " Phys.Location..: connected via an external interface (port %d)", device_location_number); break; + case MTL_DEVICE_LOCATION_UNSPECIFIED: event_log_info (hashcat_ctx, " Phys.Location..: unspecified"); break; + default: event_log_info (hashcat_ctx, " Phys.Location..: N/A"); break; + } + + if (device_mtl_maj > 0 && device_mtl_min > 0) + { + event_log_info (hashcat_ctx, " Feature.Set....: macOS GPU Family %d v%d", device_mtl_maj, device_mtl_min); + } + else + { + event_log_info (hashcat_ctx, " Feature.Set....: N/A"); + } + + event_log_info (hashcat_ctx, " Registry.ID....: %d", device_registryID); + + if (device_physical_location != MTL_DEVICE_LOCATION_BUILTIN) + { + event_log_info (hashcat_ctx, " Max.TX.Rate....: %d MB/sec", device_max_transfer_rate); + } + else + { + event_log_info (hashcat_ctx, " Max.TX.Rate....: N/A"); + } + + event_log_info (hashcat_ctx, " GPU.Properties.: headless %d, low-power %d, removable %d", device_is_headless, device_is_low_power, device_is_removable); + event_log_info (hashcat_ctx, NULL); + } + } + #endif + if (backend_ctx->ocl) { event_log_info (hashcat_ctx, "OpenCL Info:"); @@ -1187,6 +1293,59 @@ void backend_info_compact (hashcat_ctx_t *hashcat_ctx) event_log_info (hashcat_ctx, NULL); } + #if defined (__APPLE__) + /** + * Metal + */ + + if (backend_ctx->mtl) + { + int metal_devices_cnt = backend_ctx->metal_devices_cnt; + char *metal_runtimeVersionStr = backend_ctx->metal_runtimeVersionStr; + + size_t len = event_log_info (hashcat_ctx, "METAL API (Metal %s)", metal_runtimeVersionStr); + + char line[HCBUFSIZ_TINY] = { 0 }; + + memset (line, '=', len); + + line[len] = 0; + + event_log_info (hashcat_ctx, "%s", line); + + for (int metal_devices_idx = 0; metal_devices_idx < metal_devices_cnt; metal_devices_idx++) + { + const int backend_devices_idx = backend_ctx->backend_device_from_metal[metal_devices_idx]; + + const hc_device_param_t *device_param = backend_ctx->devices_param + backend_devices_idx; + + int device_id = device_param->device_id; + char *device_name = device_param->device_name; + u32 device_processors = device_param->device_processors; + u64 device_global_mem = device_param->device_global_mem; + u64 device_available_mem = device_param->device_available_mem; + + if ((device_param->skipped == false) && (device_param->skipped_warning == false)) + { + event_log_info (hashcat_ctx, "* Device #%u: %s, %" PRIu64 "/%" PRIu64 " MB, %uMCU", + device_id + 1, + device_name, + device_available_mem / 1024 / 1024, + device_global_mem / 1024 / 1024, + device_processors); + } + else + { + event_log_info (hashcat_ctx, "* Device #%u: %s, skipped", + device_id + 1, + device_name); + } + } + + event_log_info (hashcat_ctx, NULL); + } + #endif + /** * OpenCL */ diff --git a/src/usage.c b/src/usage.c index 69c35485a..514728fd2 100644 --- a/src/usage.c +++ b/src/usage.c @@ -95,6 +95,7 @@ static const char *const USAGE_BIG_PRE_HASHMODES[] = " --example-hashes | | Alias of --hash-info |", " --backend-ignore-cuda | | Do not try to open CUDA interface on startup |", " --backend-ignore-hip | | Do not try to open HIP interface on startup |", + " --backend-ignore-metal | | Do not try to open Metal interface on startup |", " --backend-ignore-opencl | | Do not try to open OpenCL interface on startup |", " -I, --backend-info | | Show info about detected backend API devices | -I", " -d, --backend-devices | Str | Backend devices to use, separated with commas | -d 1", diff --git a/src/user_options.c b/src/user_options.c index b55f4d83a..15076a3fe 100644 --- a/src/user_options.c +++ b/src/user_options.c @@ -35,6 +35,9 @@ static const struct option long_options[] = {"backend-devices", required_argument, NULL, IDX_BACKEND_DEVICES}, {"backend-ignore-cuda", no_argument, NULL, IDX_BACKEND_IGNORE_CUDA}, {"backend-ignore-hip", no_argument, NULL, IDX_BACKEND_IGNORE_HIP}, + #if defined (__APPLE__) + {"backend-ignore-metal", no_argument, NULL, IDX_BACKEND_IGNORE_METAL}, + #endif {"backend-ignore-opencl", no_argument, NULL, IDX_BACKEND_IGNORE_OPENCL}, {"backend-info", no_argument, NULL, IDX_BACKEND_INFO}, {"backend-vector-width", required_argument, NULL, IDX_BACKEND_VECTOR_WIDTH}, @@ -170,6 +173,9 @@ int user_options_init (hashcat_ctx_t *hashcat_ctx) user_options->backend_devices = NULL; user_options->backend_ignore_cuda = BACKEND_IGNORE_CUDA; user_options->backend_ignore_hip = BACKEND_IGNORE_HIP; + #if defined (__APPLE__) + user_options->backend_ignore_metal = BACKEND_IGNORE_METAL; + #endif user_options->backend_ignore_opencl = BACKEND_IGNORE_OPENCL; user_options->backend_info = BACKEND_INFO; user_options->backend_vector_width = BACKEND_VECTOR_WIDTH; @@ -455,6 +461,9 @@ int user_options_getopt (hashcat_ctx_t *hashcat_ctx, int argc, char **argv) case IDX_CPU_AFFINITY: user_options->cpu_affinity = optarg; break; case IDX_BACKEND_IGNORE_CUDA: user_options->backend_ignore_cuda = true; break; case IDX_BACKEND_IGNORE_HIP: user_options->backend_ignore_hip = true; break; + #if defined (__APPLE__) + case IDX_BACKEND_IGNORE_METAL: user_options->backend_ignore_metal = true; break; + #endif case IDX_BACKEND_IGNORE_OPENCL: user_options->backend_ignore_opencl = true; break; case IDX_BACKEND_INFO: user_options->backend_info = true; break; case IDX_BACKEND_DEVICES: user_options->backend_devices = optarg; break;