mirror of
https://github.com/e-ago/bitcracker.git
synced 2025-10-27 07:29:18 +00:00
opencl source code with Recovery Password attack
This commit is contained in:
parent
086823ed0e
commit
79e8015f23
15
src_OpenCL/Makefile
Executable file
15
src_OpenCL/Makefile
Executable file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
FLAGS=-Wextra
|
||||
NVIDIA_INCLUDE=-I/usr/local/cuda/include -L/usr/local/cuda/lib64
|
||||
COMMON_INCLUDE=-I/usr/include -L/usr/lib64 -L/usr/lib
|
||||
MAKE_INCLUDE=$(COMMON_INCLUDE) $(NVIDIA_INCLUDE) -cl-std=CL1.2 -O3
|
||||
|
||||
all:
|
||||
gcc $(MAKE_INCLUDE) $(FLAGS) -o bitcracker_opencl main.c opencl_attack.c utils.c w_blocks.c -lOpenCL
|
||||
# clang -framework OpenCL -o bitcracker_opencl main.c opencl_attack.c utils.c w_blocks.c
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf *.o
|
||||
rm -rf bitcracker_opencl
|
||||
238
src_OpenCL/bitcracker.h
Executable file
238
src_OpenCL/bitcracker.h
Executable file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* BitCracker: BitLocker password cracking tool, OpenCL version.
|
||||
* Copyright (C) 2013-2017 Elena Ago <elena dot ago at gmail dot com>
|
||||
* Massimo Bernaschi <massimo dot bernaschi at gmail dot com>
|
||||
*
|
||||
* This file is part of the BitCracker project: https://github.com/e-ago/bitcracker
|
||||
*
|
||||
* BitCracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BitCracker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BitCracker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/opencl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#include <CL/cl_ext.h>
|
||||
#pragma OPENCL EXTENSION cl_nv_device_attribute_query : enable
|
||||
#endif
|
||||
|
||||
#ifndef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV
|
||||
/* cl_nv_device_attribute_query extension - no extension #define since it has no functions */
|
||||
#define CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV 0x4000
|
||||
#define CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV 0x4001
|
||||
#define CL_DEVICE_REGISTERS_PER_BLOCK_NV 0x4002
|
||||
#define CL_DEVICE_WARP_SIZE_NV 0x4003
|
||||
#define CL_DEVICE_GPU_OVERLAP_NV 0x4004
|
||||
#define CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV 0x4005
|
||||
#define CL_DEVICE_INTEGRATED_MEMORY_NV 0x4006
|
||||
#endif
|
||||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define AUTHENTICATOR_LENGTH 16
|
||||
#define AES_CTX_LENGTH 256
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define SALT_SIZE 16
|
||||
#define MAC_SIZE 16
|
||||
#define NONCE_SIZE 12
|
||||
#define IV_SIZE 16
|
||||
|
||||
#define VMK_SIZE 60
|
||||
#define VMK_HEADER_SIZE 12
|
||||
#define VMK_BODY_SIZE 32
|
||||
#define VMK_FULL_SIZE 44
|
||||
|
||||
#define RECOVERY_KEY_SIZE_CHAR 56
|
||||
#define RECOVERY_PASS_BLOCKS 8
|
||||
#define MODE_USER_PASS 1
|
||||
#define MODE_RECV_PASS 2
|
||||
|
||||
#define PSW_CHAR_SIZE 64
|
||||
#define PSW_INT_SIZE 16 //32 for double passwords
|
||||
#define FIRST_LENGHT 27
|
||||
#define SECOND_LENGHT 55
|
||||
|
||||
#define BLOCK_UNIT 32
|
||||
#define HASH_SIZE_STRING 32
|
||||
#define DICT_BUFSIZE (50*1024*1024)
|
||||
#define MAX_PLEN 32
|
||||
|
||||
#ifndef UINT32_C
|
||||
#define UINT32_C(c) c ## UL
|
||||
#endif
|
||||
|
||||
#define HASH_SIZE 8 //32
|
||||
#define ROUND_SHA_NUM 64
|
||||
#define SINGLE_BLOCK_SHA_SIZE 64
|
||||
#define SINGLE_BLOCK_W_SIZE 64
|
||||
#define PADDING_SIZE 40
|
||||
#define ITERATION_NUMBER 0x100000
|
||||
#define WORD_SIZE 4
|
||||
#define INPUT_SIZE 2048
|
||||
#define FIXED_PART_INPUT_CHAIN_HASH 88
|
||||
#define MIN_INPUT_PASSWORD_LEN 8
|
||||
#define MAX_INPUT_PASSWORD_LEN 27
|
||||
|
||||
#define BLOCK_UNIT 32
|
||||
#define HASH_SIZE_STRING 32
|
||||
|
||||
#define HASH_TAG "$bitlocker$"
|
||||
#define HASH_TAG_LEN (sizeof(HASH_TAG) - 1)
|
||||
#define INPUT_HASH_SIZE 210
|
||||
|
||||
#define ATTACK_DEFAULT_THREADS 1024
|
||||
|
||||
#define BIT_SUCCESS 0
|
||||
#define BIT_FAILURE 1
|
||||
|
||||
#define MAX_SOURCE_SIZE (0x100000)
|
||||
|
||||
#define LOCAL_THREAD 768
|
||||
#define MAX_NUM_PLATFORMS 10
|
||||
#define MAX_DEVICE_NAME_SIZE 2048
|
||||
|
||||
static const char *getErrorString(cl_int error)
|
||||
{
|
||||
switch(error){
|
||||
// run-time and JIT compiler errors
|
||||
case 0: return "CL_SUCCESS";
|
||||
case -1: return "CL_DEVICE_NOT_FOUND";
|
||||
case -2: return "CL_DEVICE_NOT_AVAILABLE";
|
||||
case -3: return "CL_COMPILER_NOT_AVAILABLE";
|
||||
case -4: return "CL_MEM_OBJECT_ALLOCATION_FAILURE";
|
||||
case -5: return "CL_OUT_OF_RESOURCES";
|
||||
case -6: return "CL_OUT_OF_HOST_MEMORY";
|
||||
case -7: return "CL_PROFILING_INFO_NOT_AVAILABLE";
|
||||
case -8: return "CL_MEM_COPY_OVERLAP";
|
||||
case -9: return "CL_IMAGE_FORMAT_MISMATCH";
|
||||
case -10: return "CL_IMAGE_FORMAT_NOT_SUPPORTED";
|
||||
case -11: return "CL_BUILD_PROGRAM_FAILURE";
|
||||
case -12: return "CL_MAP_FAILURE";
|
||||
case -13: return "CL_MISALIGNED_SUB_BUFFER_OFFSET";
|
||||
case -14: return "CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST";
|
||||
case -15: return "CL_COMPILE_PROGRAM_FAILURE";
|
||||
case -16: return "CL_LINKER_NOT_AVAILABLE";
|
||||
case -17: return "CL_LINK_PROGRAM_FAILURE";
|
||||
case -18: return "CL_DEVICE_PARTITION_FAILED";
|
||||
case -19: return "CL_KERNEL_ARG_INFO_NOT_AVAILABLE";
|
||||
|
||||
// compile-time errors
|
||||
case -30: return "CL_INVALID_VALUE";
|
||||
case -31: return "CL_INVALID_DEVICE_TYPE";
|
||||
case -32: return "CL_INVALID_PLATFORM";
|
||||
case -33: return "CL_INVALID_DEVICE";
|
||||
case -34: return "CL_INVALID_CONTEXT";
|
||||
case -35: return "CL_INVALID_QUEUE_PROPERTIES";
|
||||
case -36: return "CL_INVALID_COMMAND_QUEUE";
|
||||
case -37: return "CL_INVALID_HOST_PTR";
|
||||
case -38: return "CL_INVALID_MEM_OBJECT";
|
||||
case -39: return "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR";
|
||||
case -40: return "CL_INVALID_IMAGE_SIZE";
|
||||
case -41: return "CL_INVALID_SAMPLER";
|
||||
case -42: return "CL_INVALID_BINARY";
|
||||
case -43: return "CL_INVALID_BUILD_OPTIONS";
|
||||
case -44: return "CL_INVALID_PROGRAM";
|
||||
case -45: return "CL_INVALID_PROGRAM_EXECUTABLE";
|
||||
case -46: return "CL_INVALID_KERNEL_NAME";
|
||||
case -47: return "CL_INVALID_KERNEL_DEFINITION";
|
||||
case -48: return "CL_INVALID_KERNEL";
|
||||
case -49: return "CL_INVALID_ARG_INDEX";
|
||||
case -50: return "CL_INVALID_ARG_VALUE";
|
||||
case -51: return "CL_INVALID_ARG_SIZE";
|
||||
case -52: return "CL_INVALID_KERNEL_ARGS";
|
||||
case -53: return "CL_INVALID_WORK_DIMENSION";
|
||||
case -54: return "CL_INVALID_WORK_GROUP_SIZE";
|
||||
case -55: return "CL_INVALID_WORK_ITEM_SIZE";
|
||||
case -56: return "CL_INVALID_GLOBAL_OFFSET";
|
||||
case -57: return "CL_INVALID_EVENT_WAIT_LIST";
|
||||
case -58: return "CL_INVALID_EVENT";
|
||||
case -59: return "CL_INVALID_OPERATION";
|
||||
case -60: return "CL_INVALID_GL_OBJECT";
|
||||
case -61: return "CL_INVALID_BUFFER_SIZE";
|
||||
case -62: return "CL_INVALID_MIP_LEVEL";
|
||||
case -63: return "CL_INVALID_GLOBAL_WORK_SIZE";
|
||||
case -64: return "CL_INVALID_PROPERTY";
|
||||
case -65: return "CL_INVALID_IMAGE_DESCRIPTOR";
|
||||
case -66: return "CL_INVALID_COMPILER_OPTIONS";
|
||||
case -67: return "CL_INVALID_LINKER_OPTIONS";
|
||||
case -68: return "CL_INVALID_DEVICE_PARTITION_COUNT";
|
||||
|
||||
// extension errors
|
||||
case -1000: return "CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR";
|
||||
case -1001: return "CL_PLATFORM_NOT_FOUND_KHR";
|
||||
case -1002: return "CL_INVALID_D3D10_DEVICE_KHR";
|
||||
case -1003: return "CL_INVALID_D3D10_RESOURCE_KHR";
|
||||
case -1004: return "CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR";
|
||||
case -1005: return "CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR";
|
||||
default: return "Unknown OpenCL error";
|
||||
}
|
||||
}
|
||||
|
||||
#define CL_ERROR(errNum) \
|
||||
if (errNum != CL_SUCCESS) \
|
||||
{ \
|
||||
fprintf(stdout, "Error in line %u in file %s: %s (%d)!!!\n\n", __LINE__, __FILE__, getErrorString(errNum), errNum); \
|
||||
exit(EXIT_FAILURE); \
|
||||
}
|
||||
|
||||
extern int gpu_id;
|
||||
extern int platform_id;
|
||||
extern int psw_x_thread;
|
||||
extern int tot_psw;
|
||||
extern size_t size_psw;
|
||||
extern int strict_check;
|
||||
extern int mac_comparison;
|
||||
extern int attack_mode;
|
||||
|
||||
extern int MAX_PASSWD_SINGLE_KERNEL;
|
||||
extern int DEV_NVIDIA;
|
||||
extern int DEV_INTEL;
|
||||
extern int DEV_AMD;
|
||||
extern int CC_SM50;
|
||||
//extern long int GPU_MAX_MEM_ALLOC_SIZE;
|
||||
extern int GPU_MAX_COMPUTE_UNITS;
|
||||
extern int GPU_MAX_WORKGROUP_SIZE;
|
||||
extern long int GPU_MAX_GLOBAL_MEM;
|
||||
|
||||
// OpenCL Vars
|
||||
extern cl_context cxGPUContext; // OpenCL context
|
||||
extern cl_command_queue cqCommandQueue;// OpenCL command que
|
||||
extern cl_platform_id cpPlatforms[MAX_NUM_PLATFORMS]; // OpenCL platform
|
||||
extern cl_uint uiNumDevices; // OpenCL total number of devices
|
||||
extern cl_device_id* cdDevices; // OpenCL device(s)
|
||||
|
||||
unsigned int * w_block_precomputed(unsigned char * salt);
|
||||
int readFilePassword(int ** buf_i, char ** buf_c, int maxNumPsw, FILE *fp);
|
||||
int parse_data(char *input_hash, unsigned char ** salt, unsigned char ** nonce, unsigned char ** vmk, unsigned char ** mac);
|
||||
char * opencl_attack(char *dname, unsigned int * w_blocks,
|
||||
unsigned char * encryptedVMK,
|
||||
unsigned char * nonce, unsigned char * encryptedMAC,
|
||||
int gridBlocks);
|
||||
|
||||
void setBufferPasswordSize(size_t avail, size_t * passwordBufferSize, int * numPassword);
|
||||
|
||||
void * Calloc(size_t len, size_t size);
|
||||
void print_hex(unsigned char hash[], int size);
|
||||
|
||||
2464
src_OpenCL/kernel_attack.cl
Executable file
2464
src_OpenCL/kernel_attack.cl
Executable file
File diff suppressed because it is too large
Load Diff
162
src_OpenCL/kernel_wblocks.cl
Executable file
162
src_OpenCL/kernel_wblocks.cl
Executable file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* BitCracker: BitLocker password cracking tool, OpenCL version.
|
||||
* Copyright (C) 2013-2017 Elena Ago <elena dot ago at gmail dot com>
|
||||
* Massimo Bernaschi <massimo dot bernaschi at gmail dot com>
|
||||
*
|
||||
* This file is part of the BitCracker project: https://github.com/e-ago/bitcracker
|
||||
*
|
||||
* BitCracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BitCracker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BitCracker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define AUTHENTICATOR_LENGTH 16
|
||||
#define AES_CTX_LENGTH 256
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define SALT_SIZE 16
|
||||
#define MAC_SIZE 16
|
||||
#define NONCE_SIZE 12
|
||||
#define IV_SIZE 16
|
||||
#define VMK_SIZE 44
|
||||
#define VMK_DECRYPT_SIZE 16
|
||||
#define DICT_BUFSIZE (50*1024*1024)
|
||||
#define MAX_PLEN 32
|
||||
#define UINT32_C(c) c ## UL
|
||||
|
||||
#define HASH_SIZE 8 //32
|
||||
#define ROUND_SHA_NUM 64
|
||||
#define SINGLE_BLOCK_SHA_SIZE 64
|
||||
#define SINGLE_BLOCK_W_SIZE 64
|
||||
#define PADDING_SIZE 40
|
||||
#define ITERATION_NUMBER 0x100000
|
||||
#define WORD_SIZE 4
|
||||
#define INPUT_SIZE 512
|
||||
#define FIXED_PART_INPUT_CHAIN_HASH 88
|
||||
#define MAX_INPUT_PASSWORD_LEN 16
|
||||
#define BLOCK_UNIT 32
|
||||
#define HASH_SIZE_STRING 32
|
||||
|
||||
#define CUDA_GRID_THREAD_X 32 /* 32 - 16*/
|
||||
#define CUDA_GRID_THREAD_Y 32
|
||||
#define MAX_SOURCE_SIZE (0x100000)
|
||||
|
||||
#define ROR(x, i) (((x) << (32 - (i))) | ((x) >> (i)))
|
||||
|
||||
#define LOADSCHEDULE_WPRE(i, j) \
|
||||
w_blocks_d[j] = \
|
||||
(unsigned int)block[i * 4 + 0] << 24 \
|
||||
| (unsigned int)block[i * 4 + 1] << 16 \
|
||||
| (unsigned int)block[i * 4 + 2] << 8 \
|
||||
| (unsigned int)block[i * 4 + 3];
|
||||
|
||||
#define SCHEDULE_WPRE(i) \
|
||||
w_blocks_d[i] = w_blocks_d[i - 16] + w_blocks_d[i - 7] \
|
||||
+ (ROR(w_blocks_d[i - 15], 7) ^ ROR(w_blocks_d[i - 15], 18) ^ (w_blocks_d[i - 15] >> 3)) \
|
||||
+ (ROR(w_blocks_d[i - 2], 17) ^ ROR(w_blocks_d[i - 2], 19) ^ (w_blocks_d[i - 2] >> 10));
|
||||
|
||||
|
||||
__kernel void opencl_bitcracker_wblocks(int totNumIteration, __global unsigned char * salt_d, __global unsigned char * padding_d, __global unsigned int * w_blocks_d)
|
||||
{
|
||||
unsigned long loop = get_global_id(0);
|
||||
unsigned char block[SINGLE_BLOCK_W_SIZE];
|
||||
|
||||
int i, j;
|
||||
|
||||
for(i=0; i<SALT_SIZE; i++)
|
||||
block[i] = salt_d[i];
|
||||
|
||||
i+=8;
|
||||
|
||||
for(j=0; j<40; i++, j++)
|
||||
block[i] = padding_d[j];
|
||||
|
||||
while(loop < ITERATION_NUMBER)
|
||||
{
|
||||
block[16] = (unsigned char) (loop >> (0*8));
|
||||
block[17] = (unsigned char) (loop >> (1*8));
|
||||
block[18] = (unsigned char) (loop >> (2*8));
|
||||
block[19] = (unsigned char) (loop >> (3*8));
|
||||
block[20] = (unsigned char) (loop >> (4*8));
|
||||
block[21] = (unsigned char) (loop >> (5*8));
|
||||
block[22] = (unsigned char) (loop >> (6*8));
|
||||
block[23] = (unsigned char) (loop >> (7*8));
|
||||
|
||||
LOADSCHEDULE_WPRE( 0, (SINGLE_BLOCK_W_SIZE*loop)+0)
|
||||
LOADSCHEDULE_WPRE( 1, (SINGLE_BLOCK_W_SIZE*loop)+1)
|
||||
LOADSCHEDULE_WPRE( 2, (SINGLE_BLOCK_W_SIZE*loop)+2)
|
||||
LOADSCHEDULE_WPRE( 3, (SINGLE_BLOCK_W_SIZE*loop)+3)
|
||||
LOADSCHEDULE_WPRE( 4, (SINGLE_BLOCK_W_SIZE*loop)+4)
|
||||
LOADSCHEDULE_WPRE( 5, (SINGLE_BLOCK_W_SIZE*loop)+5)
|
||||
LOADSCHEDULE_WPRE( 6, (SINGLE_BLOCK_W_SIZE*loop)+6)
|
||||
LOADSCHEDULE_WPRE( 7, (SINGLE_BLOCK_W_SIZE*loop)+7)
|
||||
LOADSCHEDULE_WPRE( 8, (SINGLE_BLOCK_W_SIZE*loop)+8)
|
||||
LOADSCHEDULE_WPRE( 9, (SINGLE_BLOCK_W_SIZE*loop)+9)
|
||||
LOADSCHEDULE_WPRE(10, (SINGLE_BLOCK_W_SIZE*loop)+10)
|
||||
LOADSCHEDULE_WPRE(11, (SINGLE_BLOCK_W_SIZE*loop)+11)
|
||||
LOADSCHEDULE_WPRE(12, (SINGLE_BLOCK_W_SIZE*loop)+12)
|
||||
LOADSCHEDULE_WPRE(13, (SINGLE_BLOCK_W_SIZE*loop)+13)
|
||||
LOADSCHEDULE_WPRE(14, (SINGLE_BLOCK_W_SIZE*loop)+14)
|
||||
LOADSCHEDULE_WPRE(15, (SINGLE_BLOCK_W_SIZE*loop)+15)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+16)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+17)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+18)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+19)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+20)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+21)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+22)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+23)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+24)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+25)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+26)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+27)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+28)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+29)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+30)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+31)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+32)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+33)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+34)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+35)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+36)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+37)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+38)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+39)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+40)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+41)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+42)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+43)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+44)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+45)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+46)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+47)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+48)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+49)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+50)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+51)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+52)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+53)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+54)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+55)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+56)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+57)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+58)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+59)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+60)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+61)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+62)
|
||||
SCHEDULE_WPRE((SINGLE_BLOCK_W_SIZE*loop)+63)
|
||||
|
||||
loop += get_global_size(0); //(blockDim.x * gridDim.x * blockDim.y * gridDim.y);
|
||||
}
|
||||
}
|
||||
440
src_OpenCL/main.c
Executable file
440
src_OpenCL/main.c
Executable file
@ -0,0 +1,440 @@
|
||||
/*
|
||||
* BitCracker: BitLocker password cracking tool, OpenCL version.
|
||||
* Copyright (C) 2013-2017 Elena Ago <elena dot ago at gmail dot com>
|
||||
* Massimo Bernaschi <massimo dot bernaschi at gmail dot com>
|
||||
*
|
||||
* This file is part of the BitCracker project: https://github.com/e-ago/bitcracker
|
||||
*
|
||||
* BitCracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BitCracker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BitCracker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "bitcracker.h"
|
||||
//#pragma OPENCL EXTENSION cl_nv_device_attribute_query : enable
|
||||
|
||||
int DEV_NVIDIA=0;
|
||||
int DEV_INTEL=0;
|
||||
int DEV_AMD=0;
|
||||
int CC_SM50=0;
|
||||
|
||||
int MAX_PASSWD_SINGLE_KERNEL=16;
|
||||
|
||||
long int GPU_MAX_MEM_ALLOC_SIZE=0;
|
||||
int GPU_MAX_COMPUTE_UNITS=16;
|
||||
int GPU_MAX_WORKGROUP_SIZE=0;
|
||||
long int GPU_MAX_GLOBAL_MEM=0;
|
||||
|
||||
int gpu_id=0;
|
||||
int platform_id=0;
|
||||
int psw_x_thread=8;
|
||||
int tot_psw=0;
|
||||
long int tot_word_mem=(SINGLE_BLOCK_SHA_SIZE * ITERATION_NUMBER * sizeof(uint32_t));
|
||||
int strict_check=0, mac_comparison=0, attack_mode=0;
|
||||
|
||||
// OpenCL Vars
|
||||
cl_context cxGPUContext; // OpenCL context
|
||||
cl_command_queue cqCommandQueue;// OpenCL command que
|
||||
cl_platform_id cpPlatforms[MAX_NUM_PLATFORMS]; // OpenCL platform
|
||||
cl_uint uiNumDevices; // OpenCL total number of devices
|
||||
cl_device_id* cdDevices; // OpenCL device(s)
|
||||
|
||||
|
||||
void usage(char *name)
|
||||
{
|
||||
printf("\nUsage: %s -f <hash_file> -d <dictionary_file>\n\n"
|
||||
"Options:\n\n"
|
||||
" -h"
|
||||
"\t\t\tShow this help\n"
|
||||
" -f"
|
||||
"\t\tPath to your input hash file (HashExtractor output)\n"
|
||||
" -d"
|
||||
"\t\tPath to dictionary or alphabet file\n"
|
||||
" -s"
|
||||
"\t\tStrict check (use only in case of false positives, faster solution)\n"
|
||||
" -m"
|
||||
"\t\tMAC comparison (use only in case of false positives, slower solution)\n"
|
||||
" -u"
|
||||
"\t\tAttack User Password authentication method\n"
|
||||
" -r"
|
||||
"\t\tAttack Recovery Password authentication method\n"
|
||||
" -p"
|
||||
"\t\tPlatform\n"
|
||||
" -g"
|
||||
"\t\tDevice number\n"
|
||||
" -t"
|
||||
"\t\tSet the number of password per thread threads\n"
|
||||
" -b"
|
||||
"\t\tSet the number of blocks\n\n", name);
|
||||
}
|
||||
|
||||
int checkDeviceStatistics()
|
||||
{
|
||||
int i, j;
|
||||
char* value;
|
||||
size_t valueSize, maxWorkGroup;
|
||||
cl_int platformCount;
|
||||
cl_platform_id* platforms;
|
||||
cl_int deviceCount;
|
||||
cl_device_id* devices;
|
||||
cl_int maxComputeUnits, deviceAddressBits;
|
||||
cl_ulong maxAllocSize, maxConstBufSize;
|
||||
cl_int ccMajor, ccMinor, registersPerBlock, warpSize, overlap;
|
||||
char dname[2048];
|
||||
int deviceFound=0;
|
||||
size_t avail, total;
|
||||
|
||||
// get all platforms
|
||||
clGetPlatformIDs(0, NULL, &platformCount);
|
||||
platforms = (cl_platform_id*) malloc(sizeof(cl_platform_id) * platformCount);
|
||||
clGetPlatformIDs(platformCount, platforms, NULL);
|
||||
|
||||
|
||||
for (i = 0; i < platformCount; i++)
|
||||
{
|
||||
// get all devices
|
||||
clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &deviceCount);
|
||||
devices = (cl_device_id*) malloc(sizeof(cl_device_id) * deviceCount);
|
||||
clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, deviceCount, devices, NULL);
|
||||
|
||||
printf("\n# Platform: %d, # Devices: %d\n", i, deviceCount);
|
||||
// for each device print critical attributes
|
||||
for (j = 0; j < deviceCount; j++)
|
||||
{
|
||||
|
||||
// print device name
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_NAME, 0, NULL, &valueSize);
|
||||
value = (char*) malloc(valueSize);
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_NAME, valueSize, value, NULL);
|
||||
|
||||
if (platform_id == i && gpu_id == j)
|
||||
{
|
||||
printf("\n====================================\nSelected device: %s (ID: %d) properties\n====================================\n\n", value, j);
|
||||
deviceFound=1;
|
||||
}
|
||||
else
|
||||
printf("\n====================================\nDevice %s (ID: %d) properties\n====================================\n\n", value, j);
|
||||
|
||||
free(value);
|
||||
|
||||
// print hardware device version
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_VERSION, 0, NULL, &valueSize);
|
||||
value = (char*) malloc(valueSize);
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_VERSION, valueSize, value, NULL);
|
||||
printf("OpenCL version supported: %s\n", value);
|
||||
free(value);
|
||||
|
||||
// print software driver version
|
||||
clGetDeviceInfo(devices[j], CL_DRIVER_VERSION, 0, NULL, &valueSize);
|
||||
value = (char*) malloc(valueSize);
|
||||
clGetDeviceInfo(devices[j], CL_DRIVER_VERSION, valueSize, value, NULL);
|
||||
printf("Software version: %s\n", value);
|
||||
free(value);
|
||||
|
||||
// print c version supported by compiler for device
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_OPENCL_C_VERSION, 0, NULL, &valueSize);
|
||||
value = (char*) malloc(valueSize);
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_OPENCL_C_VERSION, valueSize, value, NULL);
|
||||
printf("OpenCL C version: %s\n", value);
|
||||
free(value);
|
||||
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(maxAllocSize), &maxAllocSize, NULL);
|
||||
printf("Max Global Memory Size: %lld\n", maxAllocSize);
|
||||
GPU_MAX_GLOBAL_MEM=maxAllocSize;
|
||||
maxAllocSize=0;
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(maxAllocSize), &maxAllocSize, NULL);
|
||||
printf("Max Global Memory Alloc Size: %lld\n", maxAllocSize);
|
||||
GPU_MAX_MEM_ALLOC_SIZE=maxAllocSize;
|
||||
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof(maxConstBufSize), &maxConstBufSize, NULL);
|
||||
printf("Max Const Memory Buffer Size: %lld\n", maxConstBufSize);
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_ADDRESS_BITS, sizeof(deviceAddressBits), &deviceAddressBits, NULL);
|
||||
printf("Device Address Bits: %d\n", deviceAddressBits);
|
||||
|
||||
// print parallel compute units
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(maxComputeUnits), &maxComputeUnits, NULL);
|
||||
printf("Parallel compute units: %d\n", maxComputeUnits);
|
||||
GPU_MAX_COMPUTE_UNITS=maxComputeUnits;
|
||||
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(maxWorkGroup), &maxWorkGroup, NULL);
|
||||
printf("Max Workgroup Size: %zd\n", maxWorkGroup);
|
||||
GPU_MAX_WORKGROUP_SIZE=maxWorkGroup;
|
||||
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_VENDOR, sizeof(dname), dname, NULL);
|
||||
printf("Vendor: %s\n", dname);
|
||||
|
||||
if(strstr(dname, "NVIDIA") != NULL)
|
||||
{
|
||||
DEV_NVIDIA=1;
|
||||
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, sizeof(ccMajor), &ccMajor, NULL);
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV, sizeof(ccMinor), &ccMinor, NULL);
|
||||
printf("CC: %d.%d\n", ccMajor, ccMinor);
|
||||
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_REGISTERS_PER_BLOCK_NV, sizeof(registersPerBlock), ®istersPerBlock, NULL);
|
||||
printf("Registers per block: %d\n", registersPerBlock);
|
||||
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_WARP_SIZE_NV, sizeof(warpSize), &warpSize, NULL);
|
||||
printf("Warp Size: %d\n", warpSize);
|
||||
|
||||
clGetDeviceInfo(devices[j], CL_DEVICE_GPU_OVERLAP_NV, sizeof(overlap), &overlap, NULL);
|
||||
printf("Overlap Memory and Kernel: %d\n", overlap);
|
||||
}
|
||||
|
||||
if (strstr(dname, "Intel") != NULL) DEV_INTEL=1;
|
||||
if ((strstr(dname, "Advanced Micro") != NULL || strstr(dname, "AMD") != NULL || strstr(dname, "ATI") != NULL)) DEV_AMD=1;
|
||||
|
||||
if(deviceFound==1)
|
||||
{
|
||||
printf("\nFor this session, BitCracker requires at least %ld bytes of memory\n\n", (tot_word_mem));
|
||||
if(GPU_MAX_GLOBAL_MEM < tot_word_mem)
|
||||
{
|
||||
fprintf(stderr, "Not enough memory available on device. Minimum required: %zd Tot memory: %ld\n", (tot_word_mem), GPU_MAX_GLOBAL_MEM);
|
||||
return BIT_FAILURE;
|
||||
}
|
||||
|
||||
if(GPU_MAX_MEM_ALLOC_SIZE < tot_word_mem)
|
||||
{
|
||||
fprintf(stderr, "GPU_MAX_MEM_ALLOC_SIZE: %zd Mem chunk1: %zd\n", GPU_MAX_MEM_ALLOC_SIZE, tot_word_mem);
|
||||
return BIT_FAILURE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
free(devices);
|
||||
if(deviceFound == 1) break;
|
||||
}
|
||||
|
||||
free(platforms);
|
||||
|
||||
if(deviceFound == 0)
|
||||
{
|
||||
fprintf(stderr, "Device not found! Input platform: %d, input device: %d\n", platform_id, gpu_id);
|
||||
return BIT_FAILURE;
|
||||
}
|
||||
|
||||
return BIT_SUCCESS;
|
||||
}
|
||||
|
||||
int createClCtx()
|
||||
{
|
||||
cl_int clErr;
|
||||
char * gpuname;
|
||||
size_t gpunameSize;
|
||||
|
||||
// ------------------------------- OpenCL setup -------------------------------
|
||||
//Get an OpenCL platform
|
||||
cl_uint numPlatforms = 0;
|
||||
clErr = clGetPlatformIDs(MAX_NUM_PLATFORMS, cpPlatforms, &numPlatforms);
|
||||
CL_ERROR(clErr);
|
||||
|
||||
/* Get platform/device information */
|
||||
clErr = clGetDeviceIDs(cpPlatforms[platform_id], CL_DEVICE_TYPE_ALL, 0, NULL, &uiNumDevices);
|
||||
CL_ERROR(clErr);
|
||||
cdDevices = (cl_device_id *)malloc(uiNumDevices * sizeof(cl_device_id) );
|
||||
clErr = clGetDeviceIDs(cpPlatforms[platform_id], CL_DEVICE_TYPE_ALL, uiNumDevices, cdDevices, NULL);
|
||||
CL_ERROR(clErr);
|
||||
|
||||
// print device name
|
||||
clGetDeviceInfo(cdDevices[gpu_id], CL_DEVICE_NAME, 0, NULL, &gpunameSize);
|
||||
gpuname = (char*) malloc(gpunameSize);
|
||||
clGetDeviceInfo(cdDevices[gpu_id], CL_DEVICE_NAME, gpunameSize, gpuname, NULL);
|
||||
printf("Setting context on Platform %d, Device '%s' (ID: %d)\n", platform_id, gpuname, gpu_id);
|
||||
free(gpuname);
|
||||
|
||||
//Create the context
|
||||
cxGPUContext = clCreateContext(0, 1, &(cdDevices[gpu_id]), NULL, NULL, &clErr);
|
||||
CL_ERROR(clErr);
|
||||
|
||||
// Create a command-queue
|
||||
cqCommandQueue = clCreateCommandQueue(cxGPUContext, cdDevices[gpu_id], 0, &clErr);
|
||||
CL_ERROR(clErr);
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int destroyClCtx()
|
||||
{
|
||||
if(cqCommandQueue)clReleaseCommandQueue(cqCommandQueue);
|
||||
if(cxGPUContext)clReleaseContext(cxGPUContext);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
char * input_dictionary=NULL, * input_hash=NULL;
|
||||
unsigned char *salt, *nonce, *vmk, *mac;
|
||||
uint32_t * w_blocks_d;
|
||||
long int totGlobalMem;
|
||||
|
||||
//int threads = 0;
|
||||
int gridBlocks = 4, ret=0, opt=0;
|
||||
|
||||
gpu_id=0;
|
||||
platform_id=0;
|
||||
|
||||
printf("\n---------> BitCracker: BitLocker password cracking tool <---------\n");
|
||||
|
||||
if (argc < 4) {
|
||||
printf("Missing argument!\n");
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//*********************** Options ************************
|
||||
while (1) {
|
||||
opt = getopt(argc, argv, "hf:d:t:b:p:g:msru");
|
||||
if (opt == -1)
|
||||
break;
|
||||
switch (opt) {
|
||||
case 'b':
|
||||
gridBlocks = atoi(optarg);
|
||||
break;
|
||||
case 'd':
|
||||
if(strlen(optarg) >= INPUT_SIZE)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Dictionary file path is bigger than %d\n", INPUT_SIZE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
input_dictionary=(char *)Calloc(INPUT_SIZE, sizeof(char));
|
||||
strncpy(input_dictionary,optarg, strlen(optarg)+1);
|
||||
break;
|
||||
case 'f':
|
||||
if(strlen(optarg) >= INPUT_SIZE)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Inut hash file path is bigger than %d\n", INPUT_SIZE);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
input_hash=(char *)Calloc(INPUT_SIZE, sizeof(char));
|
||||
strncpy(input_hash, optarg, strlen(optarg)+1);
|
||||
break;
|
||||
case 'g':
|
||||
gpu_id = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
case 'm':
|
||||
mac_comparison = 1;
|
||||
break;
|
||||
case 'p':
|
||||
platform_id = atoi(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
if(attack_mode != 0)
|
||||
fprintf(stderr, "Warning: double attack type selection. Setting RECOVERY PASSWORD attack mode.\n");
|
||||
|
||||
attack_mode = MODE_RECV_PASS;
|
||||
|
||||
break;
|
||||
case 's':
|
||||
strict_check = 1;
|
||||
break;
|
||||
case 't':
|
||||
psw_x_thread = atoi(optarg);
|
||||
if(psw_x_thread <= 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: wrong password x thread number\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'u':
|
||||
if(attack_mode != 0)
|
||||
fprintf(stderr, "Warning: double attack type selection. Setting USER PASSWORD attack mode.\n");
|
||||
|
||||
attack_mode = MODE_USER_PASS;
|
||||
break;
|
||||
|
||||
default:
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
printf ("non-option ARGV-elements: ");
|
||||
while (optind < argc)
|
||||
printf ("%s ", argv[optind++]);
|
||||
putchar ('\n');
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (input_dictionary == NULL){
|
||||
printf("Missing dictionary file!\n");
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (input_hash == NULL){
|
||||
printf("Missing input hash file!\n");
|
||||
usage(argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if( attack_mode == 0 ) {
|
||||
printf("\nWarning: attack type not specified (-u or -r options). Setting USER PASSWORD as default attack type\n");
|
||||
attack_mode=MODE_USER_PASS;
|
||||
}
|
||||
|
||||
//***********************************************************
|
||||
|
||||
if(checkDeviceStatistics())
|
||||
{
|
||||
fprintf(stderr, "checkDeviceStatistics error... exit!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(createClCtx())
|
||||
{
|
||||
fprintf(stderr, "checkDeviceStatistics error... exit!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
//****************** Data from target file *******************
|
||||
printf("\n====================================\nExtracting data from disk image\n====================================\n\n");
|
||||
if(parse_data(input_hash, &salt, &nonce, &vmk, &mac) == BIT_FAILURE)
|
||||
{
|
||||
fprintf(stderr, "Input hash format error... exit!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if(mac_comparison == 1 && mac == NULL)
|
||||
{
|
||||
fprintf(stderr, "MAC comparison option selected but no MAC string found in input hash. MAC comparison not used!\n");
|
||||
mac_comparison=0;
|
||||
}
|
||||
//************************************************************
|
||||
|
||||
printf("\n\n====================================\nDictionary attack\n====================================\n\n");
|
||||
//****************** W block *******************
|
||||
uint32_t * w_blocks_h = w_block_precomputed(salt);
|
||||
if(!w_blocks_h)
|
||||
{
|
||||
fprintf(stderr, "Words error... exit!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
//**********************************************
|
||||
|
||||
//************* Dictionary Attack *************
|
||||
opencl_attack(input_dictionary, w_blocks_h, vmk, nonce, mac, gridBlocks);
|
||||
//*********************************************
|
||||
|
||||
cleanup:
|
||||
destroyClCtx();
|
||||
printf("\n\n");
|
||||
return 0;
|
||||
}
|
||||
427
src_OpenCL/opencl_attack.c
Executable file
427
src_OpenCL/opencl_attack.c
Executable file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
* BitCracker: BitLocker password cracking tool, OpenCL version.
|
||||
* Copyright (C) 2013-2017 Elena Ago <elena dot ago at gmail dot com>
|
||||
* Massimo Bernaschi <massimo dot bernaschi at gmail dot com>
|
||||
*
|
||||
* This file is part of the BitCracker project: https://github.com/e-ago/bitcracker
|
||||
*
|
||||
* BitCracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BitCracker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BitCracker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "bitcracker.h"
|
||||
|
||||
#define TIMER_DEF(n) struct timeval temp_1_##n={0,0}, temp_2_##n={0,0}
|
||||
#define TIMER_START(n) gettimeofday(&temp_1_##n, (struct timezone*)0)
|
||||
#define TIMER_STOP(n) gettimeofday(&temp_2_##n, (struct timezone*)0)
|
||||
#define TIMER_ELAPSED(n) ((temp_2_##n.tv_sec-temp_1_##n.tv_sec)*1.e6+(temp_2_##n.tv_usec-temp_1_##n.tv_usec))
|
||||
|
||||
int *deviceFound, *hostFound;
|
||||
char *hostPassword;
|
||||
int *hostPasswordInt, *devicePasswordInt;
|
||||
unsigned char outPsw[PSW_CHAR_SIZE+1];
|
||||
int outIndexPsw=0, match=0;
|
||||
|
||||
static int check_match() {
|
||||
int i=0;
|
||||
|
||||
if (hostFound[0] >= 0){
|
||||
snprintf((char*)outPsw, PSW_CHAR_SIZE+1, "%s", hostPassword+(hostFound[0]*PSW_CHAR_SIZE) );
|
||||
for(i=0; i<PSW_CHAR_SIZE; i++)
|
||||
if(outPsw[i] == 0x80 || outPsw[i] == 0xff) outPsw[i]='\0'; //0xffffff80
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char *opencl_attack(char *dname, unsigned int * w_blocks,
|
||||
unsigned char * encryptedVMK,
|
||||
unsigned char * nonce, unsigned char * encryptedMAC,
|
||||
int gridBlocks)
|
||||
{
|
||||
cl_device_id device_id;
|
||||
cl_program cpProgram;
|
||||
cl_kernel ckKernelAttack;
|
||||
char vmkIV[IV_SIZE], macIV[IV_SIZE], computeMacIV[IV_SIZE];
|
||||
cl_mem d_vmk, d_mac, d_macIV, d_computeMacIV;
|
||||
cl_mem devicePassword, deviceFound, w_blocks_d;
|
||||
cl_int ciErr1, ciErr2, ccMajor;
|
||||
size_t szGlobalWorkSize;
|
||||
size_t szLocalWorkSize;
|
||||
|
||||
int numReadPassword, tot_psw, ret, totReadPsw=0; //passwordBufferSize
|
||||
FILE *fp_kernel, *fp_file_passwords;
|
||||
//Really ugly...
|
||||
char fileNameAttack[] = "./src_OpenCL/kernel_attack.cl";
|
||||
size_t source_size_attack, source_size;
|
||||
char *source_str_attack;
|
||||
size_t len = 0;
|
||||
cl_int ret_cl = CL_SUCCESS, ret_cl_log = CL_SUCCESS, ret_info_kernel = CL_SUCCESS;
|
||||
char optProgram[128];
|
||||
|
||||
unsigned int vmkIV0, vmkIV4, vmkIV8, vmkIV12;
|
||||
unsigned int macIV0, macIV4, macIV8, macIV12;
|
||||
unsigned int cMacIV0, cMacIV4, cMacIV8, cMacIV12;
|
||||
|
||||
//------- READ CL FILE ------
|
||||
fp_kernel = fopen(fileNameAttack, "rb");
|
||||
if (!fp_kernel) {
|
||||
fprintf(stderr, "Failed to load kernel.\n");
|
||||
return NULL;
|
||||
}
|
||||
fseek(fp_kernel, 0, SEEK_END);
|
||||
source_size = ftell(fp_kernel);
|
||||
fseek(fp_kernel, 0, SEEK_SET);
|
||||
|
||||
source_str_attack = (char *)calloc(source_size+1, sizeof(char *));
|
||||
source_size_attack = fread(source_str_attack, sizeof(char), source_size, fp_kernel);
|
||||
if (source_size_attack != source_size)
|
||||
fprintf(stderr,
|
||||
"Error reading source: expected %zu, got %zu bytes.\n",
|
||||
source_size, source_size_attack);
|
||||
fclose(fp_kernel);
|
||||
// -----------------------
|
||||
|
||||
if(dname == NULL || encryptedVMK == NULL || w_blocks == NULL)
|
||||
{
|
||||
fprintf(stderr, "crack_dict input error\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-------- vmkIV setup ------
|
||||
memset(vmkIV, 0, IV_SIZE);
|
||||
vmkIV[0] = (unsigned char)(IV_SIZE - 1 - NONCE_SIZE - 1);
|
||||
memcpy(vmkIV + 1, nonce, NONCE_SIZE);
|
||||
if(IV_SIZE-1 - NONCE_SIZE - 1 < 0)
|
||||
{
|
||||
fprintf(stderr, "Attack nonce error\n");
|
||||
return NULL;
|
||||
}
|
||||
vmkIV[IV_SIZE-1] = 1;
|
||||
// -----------------------
|
||||
|
||||
if(mac_comparison == 1)
|
||||
{
|
||||
//-------- macIV setup ------
|
||||
memset(macIV, 0, IV_SIZE);
|
||||
macIV[0] = (unsigned char)(IV_SIZE - 1 - NONCE_SIZE - 1);
|
||||
memcpy(macIV + 1, nonce, NONCE_SIZE);
|
||||
if(IV_SIZE-1 - NONCE_SIZE - 1 < 0)
|
||||
{
|
||||
fprintf(stderr, "Attack nonce error\n");
|
||||
return NULL;
|
||||
}
|
||||
macIV[IV_SIZE-1] = 0;
|
||||
// -----------------------
|
||||
|
||||
//-------- computeMacIV setup ------
|
||||
memset(computeMacIV, 0, IV_SIZE);
|
||||
computeMacIV[0] = 0x3a;
|
||||
memcpy(computeMacIV + 1, nonce, NONCE_SIZE);
|
||||
if(IV_SIZE-1 - NONCE_SIZE - 1 < 0)
|
||||
{
|
||||
fprintf(stderr, "Attack nonce error\n");
|
||||
return NULL;
|
||||
}
|
||||
computeMacIV[IV_SIZE-1] = 0x2c;
|
||||
// -----------------------
|
||||
}
|
||||
|
||||
// ---- Open File Dictionary ----
|
||||
if (!memcmp(dname, "-\0", 2)) {
|
||||
fp_file_passwords= stdin;
|
||||
} else {
|
||||
fp_file_passwords= fopen(dname, "r");
|
||||
if (!fp_file_passwords) {
|
||||
fprintf(stderr, "Cannot open file %s.\n", dname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------- Kernel setup -------------------------------
|
||||
cpProgram = clCreateProgramWithSource(cxGPUContext, 1, (const char **)&source_str_attack, NULL /* (const size_t *)&source_size_attack*/, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
clGetDeviceInfo(cdDevices[gpu_id], CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV, sizeof(ccMajor), &ccMajor, NULL);
|
||||
CC_SM50=0;
|
||||
if(ccMajor >= 5) CC_SM50=1;
|
||||
|
||||
|
||||
memset(optProgram, 0, 128);
|
||||
if(DEV_NVIDIA == 1)
|
||||
snprintf(optProgram, 128, "-I . -cl-nv-verbose -D DEV_NVIDIA_SM50=%d -D STRICT_CHECK=%d -D ATTACK_MODE=%d", CC_SM50, strict_check, attack_mode);
|
||||
else
|
||||
snprintf(optProgram, 128, "-I . -D DEV_NVIDIA_SM50=0 -D STRICT_CHECK=%d -D ATTACK_MODE=%d", strict_check, attack_mode);
|
||||
|
||||
ciErr1 = clBuildProgram(cpProgram, 1, &(cdDevices[gpu_id]), optProgram, NULL, NULL);
|
||||
ret_cl = clGetProgramBuildInfo(cpProgram, cdDevices[gpu_id], CL_PROGRAM_BUILD_LOG, 0, NULL, &len);
|
||||
CL_ERROR(ret_cl);
|
||||
char *buffer = (char * )calloc(len+1, sizeof(char));
|
||||
ret_cl_log = clGetProgramBuildInfo(cpProgram, cdDevices[gpu_id], CL_PROGRAM_BUILD_LOG, len+1, (void *)buffer, NULL);
|
||||
CL_ERROR(ret_cl_log);
|
||||
if(ret_cl == CL_SUCCESS && ciErr1 != CL_SUCCESS)
|
||||
{
|
||||
printf("Kernel Attack Build Log: \n%s\n\n", buffer);
|
||||
CL_ERROR(ciErr1);
|
||||
}
|
||||
|
||||
if(mac_comparison == 1)
|
||||
{
|
||||
ckKernelAttack = clCreateKernel(cpProgram, "opencl_bitcracker_attack_mac", &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ckKernelAttack = clCreateKernel(cpProgram, "opencl_bitcracker_attack", &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
}
|
||||
|
||||
size_t workgroup_size;
|
||||
ret_info_kernel = clGetKernelWorkGroupInfo(ckKernelAttack, cdDevices[gpu_id], CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &workgroup_size, NULL);
|
||||
CL_ERROR(ret_info_kernel);
|
||||
|
||||
cl_ulong localMemSize;
|
||||
ret_info_kernel = clGetKernelWorkGroupInfo(ckKernelAttack, cdDevices[gpu_id], CL_KERNEL_LOCAL_MEM_SIZE, sizeof(cl_ulong), &localMemSize, NULL);
|
||||
CL_ERROR(ret_info_kernel);
|
||||
|
||||
size_t preferredWorkGroupSize;
|
||||
ret_info_kernel = clGetKernelWorkGroupInfo(ckKernelAttack, cdDevices[gpu_id], CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, sizeof(size_t), &preferredWorkGroupSize, NULL);
|
||||
CL_ERROR(ret_info_kernel);
|
||||
|
||||
cl_ulong privateMemSize;
|
||||
ret_info_kernel = clGetKernelWorkGroupInfo(ckKernelAttack, cdDevices[gpu_id], CL_KERNEL_PRIVATE_MEM_SIZE, sizeof(cl_ulong), &privateMemSize, NULL);
|
||||
CL_ERROR(ret_info_kernel);
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//-------- Initialize input data --------
|
||||
if(GPU_MAX_WORKGROUP_SIZE > (int)workgroup_size)
|
||||
GPU_MAX_WORKGROUP_SIZE = workgroup_size;
|
||||
|
||||
tot_psw = GPU_MAX_WORKGROUP_SIZE*gridBlocks*MAX_PASSWD_SINGLE_KERNEL;
|
||||
|
||||
hostPassword = (char *) Calloc(tot_psw*PSW_CHAR_SIZE, sizeof(char));
|
||||
hostPasswordInt = (int *) Calloc(tot_psw*PSW_INT_SIZE, sizeof(int));
|
||||
hostFound = (int *) Calloc(1, sizeof(int));
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------- Data setup -------------------------------
|
||||
d_vmk = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE, VMK_FULL_SIZE*sizeof(unsigned char), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
devicePassword = clCreateBuffer(cxGPUContext, CL_MEM_READ_ONLY, tot_psw*PSW_INT_SIZE*sizeof(unsigned int), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
deviceFound = clCreateBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, sizeof(unsigned int), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
w_blocks_d = clCreateBuffer(cxGPUContext, CL_MEM_READ_ONLY, SINGLE_BLOCK_SHA_SIZE * ITERATION_NUMBER * sizeof(unsigned int), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
if(mac_comparison == 1)
|
||||
{
|
||||
d_mac = clCreateBuffer(cxGPUContext, CL_MEM_READ_ONLY, MAC_SIZE * sizeof(char), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
d_macIV = clCreateBuffer(cxGPUContext, CL_MEM_READ_ONLY, IV_SIZE * sizeof(char), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
d_computeMacIV = clCreateBuffer(cxGPUContext, CL_MEM_READ_ONLY, IV_SIZE * sizeof(char), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
}
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------- Write buffers -------------------------------
|
||||
vmkIV0 = ((unsigned int *)(vmkIV))[0];
|
||||
vmkIV4 = ((unsigned int *)(vmkIV+4))[0];
|
||||
vmkIV8 = ((unsigned int *)(vmkIV+8))[0];
|
||||
vmkIV12 = ((unsigned int *)(vmkIV+12))[0];
|
||||
|
||||
if(mac_comparison == 1)
|
||||
{
|
||||
macIV0 = ((unsigned int *)(macIV))[0];
|
||||
macIV4 = ((unsigned int *)(macIV+4))[0];
|
||||
macIV8 = ((unsigned int *)(macIV+8))[0];
|
||||
macIV12 = ((unsigned int *)(macIV+12))[0];
|
||||
|
||||
cMacIV0 = ((unsigned int *)(computeMacIV))[0];
|
||||
cMacIV4 = ((unsigned int *)(computeMacIV+4))[0];
|
||||
cMacIV8 = ((unsigned int *)(computeMacIV+8))[0];
|
||||
cMacIV12 = ((unsigned int *)(computeMacIV+12))[0];
|
||||
}
|
||||
|
||||
ciErr1 = clEnqueueWriteBuffer(cqCommandQueue, w_blocks_d, CL_TRUE, 0, SINGLE_BLOCK_SHA_SIZE * ITERATION_NUMBER * sizeof(int), w_blocks, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 = clEnqueueWriteBuffer(cqCommandQueue, d_vmk, CL_TRUE, 0, VMK_FULL_SIZE*sizeof(char), encryptedVMK, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
if(mac_comparison == 1)
|
||||
{
|
||||
ciErr1 = clEnqueueWriteBuffer(cqCommandQueue, d_mac, CL_TRUE, 0, MAC_SIZE*sizeof(char), encryptedMAC, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 = clEnqueueWriteBuffer(cqCommandQueue, d_macIV, CL_TRUE, 0, IV_SIZE*sizeof(char), macIV, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 = clEnqueueWriteBuffer(cqCommandQueue, d_computeMacIV, CL_TRUE, 0, IV_SIZE*sizeof(char), computeMacIV, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
szLocalWorkSize = GPU_MAX_WORKGROUP_SIZE;
|
||||
szGlobalWorkSize = gridBlocks*szLocalWorkSize;
|
||||
|
||||
printf("Type of attack: %s\n\tLocal Work Size: %zd\n\tWork Group Number: %d\n\tGlobal Work Size: %zd\n\tPassword per thread: %d\n\tPassword per kernel: %d\n\tDictionary: %s\n\tStrict Check (-s): %s\n\tMAC Comparison (-m): %s\n\t\n\n",
|
||||
(attack_mode==MODE_USER_PASS)?"User Password":"Recovery Password", szLocalWorkSize, gridBlocks, szGlobalWorkSize, psw_x_thread, tot_psw, (fp_file_passwords == stdin)?"standard input":dname, (strict_check == 1)?"Yes":"No", (mac_comparison == 1)?"Yes":"No");
|
||||
|
||||
int iter=0;
|
||||
while(!feof(fp_file_passwords))
|
||||
{
|
||||
numReadPassword = readFilePassword(&hostPasswordInt, &hostPassword, tot_psw, fp_file_passwords);
|
||||
|
||||
ciErr1 = clEnqueueWriteBuffer(cqCommandQueue, devicePassword, CL_TRUE, 0, tot_psw*PSW_INT_SIZE*sizeof(unsigned int), hostPasswordInt, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
hostFound[0] = -1;
|
||||
ciErr1 = clEnqueueWriteBuffer(cqCommandQueue, deviceFound, CL_TRUE, 0, sizeof(int), hostFound, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 = clSetKernelArg(ckKernelAttack, 0, sizeof(cl_int), (void*)&numReadPassword);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 1, sizeof(cl_mem), (void*)&devicePassword);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 2, sizeof(cl_mem), (void*)&deviceFound);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 3, sizeof(cl_mem), (void*)&d_vmk);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 4, sizeof(cl_mem), (void*)&w_blocks_d);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 5, sizeof(cl_int), (void*)&vmkIV0);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 6, sizeof(cl_int), (void*)&vmkIV4);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 7, sizeof(cl_int), (void*)&vmkIV8);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 8, sizeof(cl_int), (void*)&vmkIV12);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
if(mac_comparison == 1)
|
||||
{
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 9, sizeof(cl_mem), (void*)&d_mac);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 10, sizeof(cl_int), (void*)&macIV0);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 11, sizeof(cl_int), (void*)&macIV4);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 12, sizeof(cl_int), (void*)&macIV8);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 13, sizeof(cl_int), (void*)&macIV12);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 14, sizeof(cl_int), (void*)&cMacIV0);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 15, sizeof(cl_int), (void*)&cMacIV4);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 16, sizeof(cl_int), (void*)&cMacIV8);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
ciErr1 |= clSetKernelArg(ckKernelAttack, 17, sizeof(cl_int), (void*)&cMacIV12);
|
||||
CL_ERROR(ciErr1);
|
||||
}
|
||||
// --------------------------------------------------------
|
||||
|
||||
time_t start,end;
|
||||
double dif;
|
||||
TIMER_DEF(0);
|
||||
|
||||
TIMER_START(0);
|
||||
time (&start);
|
||||
|
||||
ciErr1 = clEnqueueNDRangeKernel(cqCommandQueue, ckKernelAttack, 1, NULL, &szGlobalWorkSize, &szLocalWorkSize, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
/* Copy result to host */
|
||||
ciErr1 = clEnqueueReadBuffer(cqCommandQueue, deviceFound, CL_TRUE, 0, sizeof(unsigned int), hostFound, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
time (&end);
|
||||
TIMER_STOP(0);
|
||||
|
||||
dif = difftime (end,start);
|
||||
|
||||
printf("OpenCL Kernel execution #%d\n\tEffective number psw: %d\n\tPasswords Range:\n\t\t%s\n\t\t.....\n\t\t%s\n\tTime: %f sec\n\tPasswords x second: %10.2f pw/sec\n",
|
||||
iter, numReadPassword,
|
||||
(char *)(hostPassword),
|
||||
(char *)(hostPassword+(PSW_CHAR_SIZE*(numReadPassword-1))),
|
||||
TIMER_ELAPSED(0)/1.0E+6, numReadPassword/(TIMER_ELAPSED(0)/1.0E+6));
|
||||
|
||||
ret = clFlush(cqCommandQueue);
|
||||
ret = clFinish(cqCommandQueue);
|
||||
|
||||
totReadPsw += numReadPassword;
|
||||
|
||||
if (hostFound[0] >= 0) {
|
||||
match=check_match();
|
||||
break;
|
||||
}
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
||||
if(match==1)
|
||||
printf("\n\n================================================\nOpenCL attack completed\nPasswords evaluated: %d\nPassword found: [%s]\n================================================\n\n", totReadPsw, outPsw);
|
||||
else
|
||||
printf("\n\n================================================\nOpenCL attack completed\nPasswords evaluated: %d\nPassword not found!\n================================================\n\n", totReadPsw);
|
||||
|
||||
out1:
|
||||
printf("\nTot passwords evaluated: %d\n", totReadPsw);
|
||||
|
||||
/* Display result */
|
||||
if (fp_file_passwords != stdin)
|
||||
fclose(fp_file_passwords);
|
||||
|
||||
out:
|
||||
/* Finalization */
|
||||
if(ckKernelAttack)clReleaseKernel(ckKernelAttack);
|
||||
if(cpProgram)clReleaseProgram(cpProgram);
|
||||
if(w_blocks_d)clReleaseMemObject(w_blocks_d);
|
||||
if(devicePassword)clReleaseMemObject(devicePassword);
|
||||
if(d_vmk)clReleaseMemObject(d_vmk);
|
||||
if(deviceFound)clReleaseMemObject(deviceFound);
|
||||
|
||||
free(source_str_attack);
|
||||
|
||||
if(match==0)
|
||||
printf("Password not found\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
328
src_OpenCL/utils.c
Executable file
328
src_OpenCL/utils.c
Executable file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* BitCracker: BitLocker password cracking tool, OpenCL version.
|
||||
* Copyright (C) 2013-2017 Elena Ago <elena dot ago at gmail dot com>
|
||||
* Massimo Bernaschi <massimo dot bernaschi at gmail dot com>
|
||||
*
|
||||
* This file is part of the BitCracker project: https://github.com/e-ago/bitcracker
|
||||
*
|
||||
* BitCracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BitCracker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BitCracker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "bitcracker.h"
|
||||
|
||||
/* John The Ripper function */
|
||||
char *strtokm(char *s1, const char *delims)
|
||||
{
|
||||
static char *last = NULL;
|
||||
char *endp;
|
||||
|
||||
if (!s1)
|
||||
s1 = last;
|
||||
if (!s1 || *s1 == 0)
|
||||
return last = NULL;
|
||||
endp = strpbrk(s1, delims);
|
||||
if (endp) {
|
||||
*endp = '\0';
|
||||
last = endp + 1;
|
||||
} else
|
||||
last = NULL;
|
||||
return s1;
|
||||
}
|
||||
|
||||
void * Calloc(size_t len, size_t size) {
|
||||
void * ptr = NULL;
|
||||
if( size <= 0)
|
||||
{
|
||||
fprintf(stderr,"Critical error: memory size is 0\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ptr = (void *)calloc(len, size);
|
||||
if( ptr == NULL )
|
||||
{
|
||||
fprintf(stderr,"Critical error: Memory allocation\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void fillBuffer(FILE *fp, unsigned char *buffer, int size)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < size; k++)
|
||||
buffer[k] = (unsigned char)fgetc(fp);
|
||||
}
|
||||
|
||||
void print_hex(unsigned char *str, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; ++i)
|
||||
printf("%02x", str[i]);
|
||||
}
|
||||
|
||||
int parse_data(char *input_hash, unsigned char ** salt, unsigned char ** nonce, unsigned char ** vmk, unsigned char ** mac)
|
||||
{
|
||||
char * hash;
|
||||
char *p;
|
||||
int i, salt_size, iterations, vmk_size, nonce_size;
|
||||
FILE * fphash;
|
||||
char tmp[2];
|
||||
int j=0, auth_method=0;
|
||||
const char zero_string[17]="0000000000000000";
|
||||
|
||||
(*salt) = (unsigned char *) Calloc(SALT_SIZE, sizeof(unsigned char));
|
||||
(*nonce) = (unsigned char *) Calloc(NONCE_SIZE, sizeof(unsigned char));
|
||||
(*vmk) = (unsigned char *) Calloc(VMK_SIZE, sizeof(unsigned char));
|
||||
(*mac) = (unsigned char *) Calloc(MAC_SIZE, sizeof(unsigned char));
|
||||
|
||||
hash = (char *) Calloc(INPUT_HASH_SIZE, sizeof(char));
|
||||
|
||||
if(!input_hash)
|
||||
{
|
||||
fprintf(stderr, "No input hash provided\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
fphash = fopen(input_hash, "r");
|
||||
if (!fphash) {
|
||||
fprintf(stderr, "! %s : %s\n", input_hash, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
|
||||
fgets(hash, INPUT_HASH_SIZE, fphash);
|
||||
if(!hash)
|
||||
{
|
||||
fprintf(stderr, "No correct input hash provided\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
printf("Reading hash file \"%s\"\n%s", input_hash, hash);
|
||||
|
||||
if (strncmp(hash, HASH_TAG, HASH_TAG_LEN) != 0)
|
||||
{
|
||||
fprintf(stderr, "Wrong hash format\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
hash += HASH_TAG_LEN;
|
||||
p = strtokm(hash, "$"); // version
|
||||
|
||||
auth_method = atoi(p);
|
||||
if( (auth_method == 0 || auth_method == 1) && attack_mode == MODE_RECV_PASS)
|
||||
{
|
||||
fprintf(stderr, "Input Hash error: you choose the -r option (Recovery Password) but the input hash MUST be used with -u option (User Password).\n");
|
||||
goto out;
|
||||
}
|
||||
else if(auth_method == 2 && attack_mode == MODE_USER_PASS)
|
||||
{
|
||||
fprintf(stderr, "Input Hash error: you choose the -u option (User Password) but the input hash MUST be used with -r option (Recovery Password).\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = strtokm(NULL, "$"); // salt length
|
||||
salt_size = atoi(p);
|
||||
if(salt_size != SALT_SIZE)
|
||||
{
|
||||
fprintf(stderr, "Wrong Salt size\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = strtokm(NULL, "$"); // salt
|
||||
for (i = 0, j = 0; i < salt_size*2; i+=2, j++)
|
||||
{
|
||||
tmp[0] = p[i];
|
||||
tmp[1] = p[i+1];
|
||||
long int ret = strtol(tmp, NULL, 16);
|
||||
(*salt)[j] = (unsigned char)(ret);
|
||||
}
|
||||
|
||||
p = strtokm(NULL, "$"); // iterations
|
||||
iterations = atoi(p);
|
||||
if(iterations != ITERATION_NUMBER)
|
||||
{
|
||||
fprintf(stderr, "Wrong Iterations parameter\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = strtokm(NULL, "$"); // nonce length
|
||||
nonce_size = atoi(p);
|
||||
if(nonce_size != NONCE_SIZE)
|
||||
{
|
||||
fprintf(stderr, "Wrong Nonce size\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = strtokm(NULL, "$"); // nonce
|
||||
for (i = 0, j = 0; i < nonce_size*2; i+=2, j++)
|
||||
{
|
||||
tmp[0] = p[i];
|
||||
tmp[1] = p[i+1];
|
||||
long int ret = strtol(tmp, NULL, 16);
|
||||
(*nonce)[j] = (unsigned char)(ret);
|
||||
}
|
||||
|
||||
p = strtokm(NULL, "$"); // data_size
|
||||
|
||||
vmk_size = atoi(p);
|
||||
if(vmk_size != VMK_SIZE)
|
||||
{
|
||||
fprintf(stderr, "Wrong VMK size\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
p = strtokm(NULL, "$"); // data
|
||||
for (i = 0, j = 0; i < MAC_SIZE*2; i+=2, j++)
|
||||
{
|
||||
tmp[0] = p[i];
|
||||
tmp[1] = p[i+1];
|
||||
long int ret = strtol(tmp, NULL, 16);
|
||||
(*mac)[j] = (unsigned char)(ret);
|
||||
}
|
||||
|
||||
if(mac_comparison == 1 && !memcmp((*mac), zero_string, MAC_SIZE))
|
||||
{
|
||||
free(*mac);
|
||||
(*mac)=NULL;
|
||||
}
|
||||
|
||||
for (j=0; i < vmk_size*2; i+=2, j++)
|
||||
{
|
||||
tmp[0] = p[i];
|
||||
tmp[1] = p[i+1];
|
||||
long int ret = strtol(tmp, NULL, 16);
|
||||
(*vmk)[j] = (unsigned char)(ret);
|
||||
}
|
||||
|
||||
fclose(fphash);
|
||||
|
||||
return BIT_SUCCESS;
|
||||
|
||||
out:
|
||||
fclose(fphash);
|
||||
free(*salt);
|
||||
free(*nonce);
|
||||
free(*vmk);
|
||||
free(*mac);
|
||||
|
||||
return BIT_FAILURE;
|
||||
}
|
||||
int readFilePassword(int ** buf_i, char ** buf_c, int maxNumPsw, FILE *fp) {
|
||||
int i=0, j=0, k=0, size=0, count=0;
|
||||
char tmp[PSW_CHAR_SIZE], tmp2[PSW_CHAR_SIZE], *p;
|
||||
memset(tmp, 0, PSW_CHAR_SIZE);
|
||||
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
|
||||
if (fp == NULL || feof(fp) || buf_i == NULL)
|
||||
return -1;
|
||||
|
||||
while(fgets(tmp, PSW_CHAR_SIZE, fp) && (i < maxNumPsw)) {
|
||||
size = (strlen(tmp)-1);
|
||||
j=0; k=0; count=0;
|
||||
if(tmp[0] == '\n' || size < MIN_INPUT_PASSWORD_LEN || size > SECOND_LENGHT) continue;
|
||||
memcpy(( (*buf_c)+(i*PSW_CHAR_SIZE)), tmp, size);
|
||||
|
||||
//Recovery password
|
||||
if(attack_mode == MODE_RECV_PASS)
|
||||
{
|
||||
memset(tmp2, 0, PSW_CHAR_SIZE);
|
||||
p = strtokm(tmp, "-");
|
||||
do
|
||||
{
|
||||
//Dislocker, Recovery Password checks
|
||||
if( ((atoi(p) % 11) != 0) || (atoi(p) >= 720896) ) break;
|
||||
int8_t check_digit = (int8_t) ( p[0] - p[1] + p[2] - p[3] + p[4] - 48 ) % 11;
|
||||
if( check_digit < 0 ) check_digit = (int8_t) check_digit + 11;
|
||||
if( check_digit != (p[5] - 48)) break;
|
||||
|
||||
((uint16_t*)(tmp2+count))[0] = (uint16_t)(atoi(p) / 11);
|
||||
p = strtokm(NULL, "-");
|
||||
count+=2;
|
||||
|
||||
} while(p != NULL);
|
||||
|
||||
if(count != (RECOVERY_PASS_BLOCKS*2)) continue;
|
||||
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[0] = ( (((unsigned int)tmp2[0] ) << 24) & 0xFF000000) |
|
||||
( (((unsigned int)tmp2[0+1]) << 16) & 0x00FF0000) |
|
||||
( (((unsigned int)tmp2[0+2]) << 8) & 0x0000FF00) |
|
||||
( (((unsigned int)tmp2[0+3]) << 0) & 0x000000FF);
|
||||
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[1] = ( (((unsigned int)tmp2[4]) << 24) & 0xFF000000) |
|
||||
( (((unsigned int)tmp2[4+1]) << 16) & 0x00FF0000) |
|
||||
( (((unsigned int)tmp2[4+2]) << 8) & 0x0000FF00) |
|
||||
( (((unsigned int)tmp2[4+3]) << 0) & 0x000000FF);
|
||||
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[2] = ( (((unsigned int)tmp2[8]) << 24) & 0xFF000000) |
|
||||
( (((unsigned int)tmp2[8+1]) << 16) & 0x00FF0000) |
|
||||
( (((unsigned int)tmp2[8+2]) << 8) & 0x0000FF00) |
|
||||
( (((unsigned int)tmp2[8+3]) << 0) & 0x000000FF);
|
||||
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[3] = ( (((unsigned int)tmp2[12]) << 24) & 0xFF000000) |
|
||||
( (((unsigned int)tmp2[12+1]) << 16) & 0x00FF0000) |
|
||||
( (((unsigned int)tmp2[12+2]) << 8) & 0x0000FF00) |
|
||||
( (((unsigned int)tmp2[12+3]) << 0) & 0x000000FF);
|
||||
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[4] = 0x80000000;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[5] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[6] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[7] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[8] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[9] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[10] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[11] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[12] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[13] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[14] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE))[15] = 0x80;
|
||||
}
|
||||
else //User Password
|
||||
{
|
||||
tmp[size] = 0x80;
|
||||
do
|
||||
{
|
||||
((*buf_i)+(i*PSW_INT_SIZE)+j)[0] = ( (((unsigned int)tmp[k]) << 24) & 0xFF000000);
|
||||
k++;
|
||||
|
||||
if(k <= size)
|
||||
((*buf_i)+(i*PSW_INT_SIZE)+j)[0] = ((*buf_i)+(i*PSW_INT_SIZE)+j)[0] | ( (((unsigned int)tmp[k]) << 8) & 0x0000FF00);
|
||||
|
||||
j++;
|
||||
k++;
|
||||
} while(k <= size);
|
||||
|
||||
if(size <= FIRST_LENGHT)
|
||||
{
|
||||
((*buf_i)+(i*PSW_INT_SIZE)+14)[0] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE)+15)[0] = ((int)(((size*2) << 3) >> 8)) << 8 | ((int)((size*2) << 3));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Next release!
|
||||
fprintf(stderr, "ERROR!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
((*buf_i)+(i*PSW_INT_SIZE)+30)[0] = 0;
|
||||
((*buf_i)+(i*PSW_INT_SIZE)+31)[0] = ((uint8_t)(((size*2) << 3) >> 8)) << 8 | ((uint8_t)((size*2) << 3));
|
||||
}
|
||||
}
|
||||
|
||||
memset(tmp, 0, PSW_CHAR_SIZE);
|
||||
i++;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
178
src_OpenCL/w_blocks.c
Executable file
178
src_OpenCL/w_blocks.c
Executable file
@ -0,0 +1,178 @@
|
||||
/*
|
||||
* BitCracker: BitLocker password cracking tool, OpenCL version.
|
||||
* Copyright (C) 2013-2017 Elena Ago <elena dot ago at gmail dot com>
|
||||
* Massimo Bernaschi <massimo dot bernaschi at gmail dot com>
|
||||
*
|
||||
* This file is part of BitCracker.
|
||||
*
|
||||
* BitCracker is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BitCracker is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BitCracker. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "bitcracker.h"
|
||||
|
||||
unsigned int * w_block_precomputed(unsigned char * salt)
|
||||
{
|
||||
cl_device_id device_id;
|
||||
cl_program cpProgram;
|
||||
cl_kernel ckKernelWBlocks;
|
||||
cl_mem salt_d, padding_d, w_blocks_d;
|
||||
cl_int ciErr1;
|
||||
size_t szGlobalWorkSize;
|
||||
size_t szLocalWorkSize;
|
||||
int i;
|
||||
FILE *fp_kernel;
|
||||
time_t start,end;
|
||||
double dif;
|
||||
|
||||
//Very very ugly...
|
||||
const char fileNameWBlocks[] = "./src_OpenCL/kernel_wblocks.cl";
|
||||
size_t source_size_wbocks;
|
||||
char *source_str_wbocks;
|
||||
|
||||
unsigned char * padding;
|
||||
uint64_t msgLen;
|
||||
unsigned int * w_blocks_h;
|
||||
int iter_num;
|
||||
|
||||
size_t len = 0;
|
||||
cl_int ret = CL_SUCCESS, ret_cl_log = CL_SUCCESS, ret_info_kernel = CL_SUCCESS;
|
||||
|
||||
if(salt == NULL)
|
||||
return FALSE;
|
||||
|
||||
//------- READ CL FILE ------
|
||||
fp_kernel = fopen(fileNameWBlocks, "rb");
|
||||
if (!fp_kernel) {
|
||||
fprintf(stderr, "Failed to load kernel.\n");
|
||||
return NULL;
|
||||
}
|
||||
source_str_wbocks = (char *)malloc(MAX_SOURCE_SIZE);
|
||||
source_size_wbocks = fread(source_str_wbocks, 1, MAX_SOURCE_SIZE, fp_kernel);
|
||||
fclose(fp_kernel);
|
||||
// -----------------------
|
||||
|
||||
padding = (unsigned char *) Calloc(PADDING_SIZE, sizeof(unsigned char));
|
||||
padding[0] = 0x80;
|
||||
memset(padding+1, 0, 31);
|
||||
msgLen = (FIXED_PART_INPUT_CHAIN_HASH << 3);
|
||||
for (i = 0; i < 8; i++)
|
||||
padding[PADDING_SIZE-1-i] = (uint8_t)(msgLen >> (i * 8));
|
||||
|
||||
// ------------------------------- Data setup -------------------------------
|
||||
salt_d = clCreateBuffer(cxGPUContext, CL_MEM_READ_ONLY, SALT_SIZE * sizeof(char), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
padding_d = clCreateBuffer(cxGPUContext, CL_MEM_READ_ONLY, PADDING_SIZE * sizeof(char), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
w_blocks_d = clCreateBuffer(cxGPUContext, CL_MEM_WRITE_ONLY, SINGLE_BLOCK_SHA_SIZE * ITERATION_NUMBER * sizeof(int), NULL, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
w_blocks_h = (unsigned int *) Calloc((SINGLE_BLOCK_SHA_SIZE*ITERATION_NUMBER), sizeof(int));
|
||||
if(!w_blocks_h)
|
||||
goto out;
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------- Kernel setup -------------------------------
|
||||
cpProgram = clCreateProgramWithSource(cxGPUContext, 1, (const char **)&source_str_wbocks, (const size_t *)&source_size_wbocks, &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
ciErr1 = clBuildProgram(cpProgram, 1, &(cdDevices[gpu_id]), "-I .", NULL, NULL);
|
||||
ret = clGetProgramBuildInfo(cpProgram, cdDevices[gpu_id], CL_PROGRAM_BUILD_LOG, 0, NULL, &len);
|
||||
CL_ERROR(ret);
|
||||
char *buffer = calloc(len, sizeof(char));
|
||||
ret_cl_log = clGetProgramBuildInfo(cpProgram, cdDevices[gpu_id], CL_PROGRAM_BUILD_LOG, len, buffer, NULL);
|
||||
CL_ERROR(ret_cl_log);
|
||||
if(ret_cl_log == CL_SUCCESS && ciErr1 != CL_SUCCESS)
|
||||
{
|
||||
printf("Kernel Blocks Build Log: \n%s\n\n", buffer);
|
||||
CL_ERROR(ciErr1);
|
||||
}
|
||||
|
||||
ckKernelWBlocks = clCreateKernel(cpProgram, "opencl_bitcracker_wblocks", &ciErr1);
|
||||
CL_ERROR(ciErr1);
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------- Write static buffers -------------------------------
|
||||
ciErr1 = clEnqueueWriteBuffer(cqCommandQueue, salt_d, CL_TRUE, 0, SALT_SIZE * sizeof(unsigned char), salt, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
ciErr1 = clEnqueueWriteBuffer(cqCommandQueue, padding_d, CL_TRUE, 0, PADDING_SIZE * sizeof(unsigned char), padding, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
iter_num = ITERATION_NUMBER;
|
||||
ciErr1 = clSetKernelArg(ckKernelWBlocks, 0, sizeof(cl_int), (void*)&iter_num);
|
||||
CL_ERROR(ciErr1);
|
||||
ciErr1 = clSetKernelArg(ckKernelWBlocks, 1, sizeof(cl_mem), (void*)&salt_d);
|
||||
CL_ERROR(ciErr1);
|
||||
ciErr1 = clSetKernelArg(ckKernelWBlocks, 2, sizeof(cl_mem), (void*)&padding_d);
|
||||
CL_ERROR(ciErr1);
|
||||
ciErr1 = clSetKernelArg(ckKernelWBlocks, 3, sizeof(cl_mem), (void*)&w_blocks_d);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
// ---------------------- Launch kernel
|
||||
size_t workgroup_size;
|
||||
ret_info_kernel = clGetKernelWorkGroupInfo(ckKernelWBlocks, cdDevices[gpu_id], CL_KERNEL_WORK_GROUP_SIZE, sizeof(size_t), &workgroup_size, NULL);
|
||||
CL_ERROR(ret_info_kernel);
|
||||
|
||||
cl_ulong localMemSize;
|
||||
ret_info_kernel = clGetKernelWorkGroupInfo(ckKernelWBlocks, cdDevices[gpu_id], CL_KERNEL_LOCAL_MEM_SIZE, sizeof(cl_ulong), &localMemSize, NULL);
|
||||
CL_ERROR(ret_info_kernel);
|
||||
|
||||
size_t preferredWorkGroupSize;
|
||||
ret_info_kernel = clGetKernelWorkGroupInfo(ckKernelWBlocks, cdDevices[gpu_id], CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, sizeof(size_t), &preferredWorkGroupSize, NULL);
|
||||
CL_ERROR(ret_info_kernel);
|
||||
|
||||
cl_ulong privateMemSize;
|
||||
ret_info_kernel = clGetKernelWorkGroupInfo(ckKernelWBlocks, cdDevices[gpu_id], CL_KERNEL_PRIVATE_MEM_SIZE, sizeof(cl_ulong), &privateMemSize, NULL);
|
||||
CL_ERROR(ret_info_kernel);
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
//-------- Initialize input data --------
|
||||
szLocalWorkSize = workgroup_size;
|
||||
szGlobalWorkSize = 16*szLocalWorkSize;
|
||||
|
||||
time (&start);
|
||||
|
||||
ciErr1 = clEnqueueNDRangeKernel(cqCommandQueue, ckKernelWBlocks, 1, NULL, &szGlobalWorkSize, &szLocalWorkSize, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
ciErr1 = clEnqueueReadBuffer(cqCommandQueue, w_blocks_d, CL_TRUE, 0, SINGLE_BLOCK_SHA_SIZE*ITERATION_NUMBER*sizeof(unsigned int), w_blocks_h, 0, NULL, NULL);
|
||||
CL_ERROR(ciErr1);
|
||||
|
||||
time (&end);
|
||||
dif = difftime (end,start);
|
||||
|
||||
ret = clFlush(cqCommandQueue);
|
||||
ret = clFinish(cqCommandQueue);
|
||||
|
||||
out:
|
||||
|
||||
if(ckKernelWBlocks)clReleaseKernel(ckKernelWBlocks);
|
||||
if(cpProgram)clReleaseProgram(cpProgram);
|
||||
|
||||
clReleaseMemObject(salt_d);
|
||||
clReleaseMemObject(padding_d);
|
||||
clReleaseMemObject(w_blocks_d);
|
||||
|
||||
free(padding);
|
||||
free(source_str_wbocks);
|
||||
|
||||
/*
|
||||
* Useless
|
||||
* unsigned int * w_blocks_h = NULL;
|
||||
* w_blocks_h = (unsigned int *) Calloc((SINGLE_BLOCK_SHA_SIZE*ITERATION_NUMBER), sizeof(unsigned int));
|
||||
* BITCRACKER_CUDA_CHECK( cudaMemcpy(w_blocks_h, w_blocks_d, SINGLE_BLOCK_SHA_SIZE * ITERATION_NUMBER * sizeof(unsigned int), cudaMemcpyDeviceToHost) );
|
||||
*/
|
||||
|
||||
return w_blocks_h;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user