Merge pull request #311 from fgaudreault/master
authorJens Steube <jens.steube@gmail.com>
Tue, 26 Apr 2016 18:12:33 +0000 (20:12 +0200)
committerJens Steube <jens.steube@gmail.com>
Tue, 26 Apr 2016 18:12:33 +0000 (20:12 +0200)
Adding parser and basic kernels for -m 13500

1  2 
docs/changes.txt
include/shared.h
include/types.h
src/oclHashcat.c
src/shared.c

diff --combined docs/changes.txt
@@@ -149,11 -149,6 +149,11 @@@ File.: Hos
  Desc.: Use a fixed path for the potfile rather than session depending
  Issue: 99
  
 +Type.: Change
 +File.: Rules
 +Desc.: Removed some duplicate rules in T0XlCv1, d3ad0ne and dive. All rules were found due to superfluous white space differences
 +Issue: 301
 +
  Type.: Bug
  File.: Host
  Desc.: Fixed a bug in combination of --restore and a user immediately aborting the session after restart
@@@ -1801,3 -1796,7 +1801,7 @@@ Trac: #19
  Type: Change
  File: Host
  Desc: new default status-timer value is 10 seconds instead of 1 minute
+ Type: Feature
+ File: Kernel
+ Desc: Added new hash mode -m 13500 = PeopleSoft PS_TOKEN
diff --combined include/shared.h
@@@ -126,63 -126,56 +126,63 @@@ static inline int  CPU_ISSET (int num, 
   * shared stuff
   */
  
 -#define ETC_MAX               (60 * 60 * 24 * 365 * 10)
 +#define ETC_MAX                 (60 * 60 * 24 * 365 * 10)
  
 -#define DEVICES_MAX           128
 +#define DEVICES_MAX             128
  
 -#define CL_PLATFORMS_MAX      16
 +#define CL_PLATFORMS_MAX        16
  
 -#define CL_VENDOR_NV          "NVIDIA Corporation"
 -#define CL_VENDOR_AMD         "Advanced Micro Devices, Inc."
 -#define CL_VENDOR_APPLE       "Apple"
 -#define CL_VENDOR_POCL        "The pocl project"
 +#define CL_VENDOR_AMD           "Advanced Micro Devices, Inc."
 +#define CL_VENDOR_APPLE         "Apple"
 +#define CL_VENDOR_INTEL_BEIGNET "Intel"
 +#define CL_VENDOR_INTEL_SDK     "Intel(R) OpenCL"
 +#define CL_VENDOR_MESA          "Mesa"
 +#define CL_VENDOR_NV            "NVIDIA Corporation"
 +#define CL_VENDOR_POCL          "The pocl project"
  
 -#define VENDOR_ID_AMD         4098
 -#define VENDOR_ID_NV          4318
 -#define VENDOR_ID_APPLE_INTEL 4294967295
 -#define VENDOR_ID_APPLE_IRIS  16925952
 -#define VENDOR_ID_GENERIC     9999
 +#define VENDOR_ID_AMD           (1 << 0)
 +#define VENDOR_ID_APPLE         (1 << 1)
 +#define VENDOR_ID_INTEL_BEIGNET (1 << 2)
 +#define VENDOR_ID_INTEL_SDK     (1 << 3)
 +#define VENDOR_ID INTEL         (1 << 4)
 +#define VENDOR_ID_MESA          (1 << 5)
 +#define VENDOR_ID_NV            (1 << 6)
 +#define VENDOR_ID_POCL          (1 << 7)
 +#define VENDOR_ID_GENERIC       (1 << 31)
  
 -#define BLOCK_SIZE            64
 +#define BLOCK_SIZE              64
  
 -#define CHARSIZ               0x100
 -#define INFOSZ                CHARSIZ
 +#define CHARSIZ                 0x100
 +#define INFOSZ                  CHARSIZ
  
 -#define SP_HCSTAT             "hashcat.hcstat"
 -#define SP_PW_MIN             2
 -#define SP_PW_MAX             64
 -#define SP_ROOT_CNT           (SP_PW_MAX * CHARSIZ)
 -#define SP_MARKOV_CNT         (SP_PW_MAX * CHARSIZ * CHARSIZ)
 +#define SP_HCSTAT               "hashcat.hcstat"
 +#define SP_PW_MIN               2
 +#define SP_PW_MAX               64
 +#define SP_ROOT_CNT             (SP_PW_MAX * CHARSIZ)
 +#define SP_MARKOV_CNT           (SP_PW_MAX * CHARSIZ * CHARSIZ)
  
 -#define TUNING_DB_FILE        "hashcat_tuning.hctab"
 +#define TUNING_DB_FILE          "hashcat_tuning.hctab"
  
 -#define INDUCT_DIR            "induct"
 -#define OUTFILES_DIR          "outfiles"
 +#define INDUCT_DIR              "induct"
 +#define OUTFILES_DIR            "outfiles"
  
 -#define LOOPBACK_FILE         "hashcat.loopback"
 +#define LOOPBACK_FILE           "hashcat.loopback"
  
 -#define DICTSTAT_FILENAME     "hashcat.dictstat"
 -#define POTFILE_FILENAME      "hashcat.pot"
 +#define DICTSTAT_FILENAME       "hashcat.dictstat"
 +#define POTFILE_FILENAME        "hashcat.pot"
  
  /**
   * types
   */
  
  #ifdef _WIN
 -typedef LARGE_INTEGER         hc_timer_t;
 -typedef HANDLE                hc_thread_t;
 -typedef CRITICAL_SECTION      hc_thread_mutex_t;
 +typedef LARGE_INTEGER     hc_timer_t;
 +typedef HANDLE            hc_thread_t;
 +typedef CRITICAL_SECTION  hc_thread_mutex_t;
  #elif _POSIX
 -typedef struct timeval        hc_timer_t;
 -typedef pthread_t             hc_thread_t;
 -typedef pthread_mutex_t       hc_thread_mutex_t;
 +typedef struct timeval    hc_timer_t;
 +typedef pthread_t         hc_thread_t;
 +typedef pthread_mutex_t   hc_thread_mutex_t;
  #endif
  
  #include <types.h>
@@@ -355,6 -348,7 +355,7 @@@ extern hc_thread_mutex_t mux_display
  #define HT_13200  "AxCrypt"
  #define HT_13300  "AxCrypt in memory SHA1"
  #define HT_13400  "Keepass 1 (AES/Twofish) and Keepass 2 (AES)"
+ #define HT_13500  "PeopleSoft PS_TOKEN"
  
  #define HT_00011  "Joomla < 2.5.18"
  #define HT_00012  "PostgreSQL"
  #define DISPLAY_LEN_MAX_11100 10 + 32 + 1 + 8 + 1 + 32
  #define DISPLAY_LEN_MIN_11200 9 + 40 + 1 + 40
  #define DISPLAY_LEN_MAX_11200 9 + 40 + 1 + 40
 -#define DISPLAY_LEN_MIN_11300 1 + 7 + 1 + 2 + 1 + 96 + 1 + 2 + 1 + 16 + 1 + 1 + 1 + 2 + 1 + 96 + 1 + 2 + 1 + 66
 -#define DISPLAY_LEN_MAX_11300 1 + 7 + 1 + 2 + 1 + 96 + 1 + 2 + 1 + 16 + 1 + 6 + 1 + 2 + 1 + 96 + 1 + 2 + 1 + 66
 +#define DISPLAY_LEN_MIN_11300 1 + 7 + 1 + 2 + 1 + 96 + 1 + 2 + 1 + 16 + 1 + 1 + 1 + 2 + 1 + 96 + 1 + 1 + 1 + 2
 +#define DISPLAY_LEN_MAX_11300 1 + 7 + 1 + 2 + 1 + 96 + 1 + 2 + 1 + 16 + 1 + 6 + 1 + 2 + 1 + 96 + 1 + 3 + 1 + 512
  #define DISPLAY_LEN_MIN_11400 6 +   0 + 1 +   0 + 1 +   0 + 1 +   0 + 1 +   0 + 1 +   0 + 1 +   1 + 1 +   0 + 1 +  1 + 1 +  0 + 1 +  0 + 1 +  0 + 1 + 3 + 1 + 32
  #define DISPLAY_LEN_MAX_11400 6 + 512 + 1 + 512 + 1 + 116 + 1 + 116 + 1 + 246 + 1 + 245 + 1 + 246 + 1 + 245 + 1 + 50 + 1 + 50 + 1 + 50 + 1 + 50 + 1 + 3 + 1 + 32
  #define DISPLAY_LEN_MIN_11500 8 + 1 + 8
  #define DISPLAY_LEN_MAX_13300  1 + 12 + 1 + 40
  #define DISPLAY_LEN_MIN_13400  1 + 7 + 1 + 1 + 1 + 1 + 1 + 1 + 32 + 1 + 64 + 1 + 32 + 1 + 64 + 1 + 1 + 1 + 1
  #define DISPLAY_LEN_MAX_13400  1 + 7 + 1 + 1 + 10 + 1 + 3 + 1 + 64 + 1 + 64 + 1 + 32 + 1 + 64 + 1 + 4 + 1 + 600000 + 1 + 2 + 1 + 64
+ #define DISPLAY_LEN_MIN_13500 40 + 1 + 32
+ #define DISPLAY_LEN_MAX_13500 40 + 1 + 1024
  
  #define DISPLAY_LEN_MIN_11    32 + 1 + 16
  #define DISPLAY_LEN_MAX_11    32 + 1 + 32
@@@ -1601,6 -1597,7 +1604,7 @@@ int androidfde_samsung_parse_hash (cha
  int axcrypt_parse_hash            (char *input_buf, uint input_len, hash_t *hash_buf);
  int sha1axcrypt_parse_hash        (char *input_buf, uint input_len, hash_t *hash_buf);
  int keepass_parse_hash            (char *input_buf, uint input_len, hash_t *hash_buf);
+ int pstoken_parse_hash            (char *input_buf, uint input_len, hash_t *hash_buf);
  
  void load_kernel (const char *kernel_file, int num_devices, size_t *kernel_lengths, const u8 **kernel_sources);
  void writeProgramBin (char *dst, u8 *binary, size_t binary_size);
diff --combined include/types.h
@@@ -702,6 -702,13 +702,13 @@@ typedef struc
  
  } psafe3_t;
  
+ typedef struct 
+ {
+   u32 salt_buf[128];
+   u32 salt_len;
+ } pstoken_t;
  typedef struct
  {
    char    plain_buf[256];
@@@ -955,11 -962,11 +962,11 @@@ struct __hc_device_para
    uint    exec_pos;
    double  exec_ms[EXEC_CACHE];
  
 +  // this is "current" speed
 +
    uint    speed_pos;
    u64     speed_cnt[SPEED_CACHE];
 -  float   speed_ms[SPEED_CACHE];
 -
 -  hc_timer_t speed_rec[SPEED_CACHE];
 +  double  speed_ms[SPEED_CACHE];
  
    hc_timer_t timer_speed;
  
@@@ -1291,7 -1298,7 +1298,7 @@@ typedef struc
    hc_timer_t timer_running;         // timer on current dict
    hc_timer_t timer_paused;          // timer on current dict
  
 -  float   ms_paused;                // timer on current dict
 +  double  ms_paused;                // timer on current dict
  
    /**
      * hash_info and username
diff --combined src/oclHashcat.c
@@@ -33,7 -33,7 +33,7 @@@ double TARGET_MS_PROFILE[3]     = { 8, 
  #define MARKOV_DISABLE          0
  #define MARKOV_CLASSIC          0
  #define BENCHMARK               0
 -#define BENCHMARK_REPEATS       2
 +#define BENCHMARK_REPEATS       100
  #define RESTORE                 0
  #define RESTORE_TIMER           60
  #define RESTORE_DISABLE         0
  
  #define MAX_DICTSTAT            10000
  
- #define NUM_DEFAULT_BENCHMARK_ALGORITHMS 135
+ #define NUM_DEFAULT_BENCHMARK_ALGORITHMS 136
  
  #define global_free(attr)       \
  {                               \
@@@ -268,6 -268,7 +268,7 @@@ static uint default_benchmark_algorithm
    8700,
    9100,
    133,
+   13500,
    11600,
    12500,
    13000,
@@@ -696,6 -697,7 +697,7 @@@ const char *USAGE_BIG[] 
    "   8700 = Lotus Notes/Domino 6",
    "   9100 = Lotus Notes/Domino 8",
    "    133 = PeopleSoft",
+   "  13500 = PeopleSoft Token",
    "",
    "[[ Archives ]]",
    "",
@@@ -800,11 -802,17 +802,11 @@@ void status_display_automat (
  
      if (device_param->skipped) continue;
  
 -    u64   speed_cnt  = 0;
 -    float speed_ms   = 0;
 +    u64    speed_cnt  = 0;
 +    double speed_ms   = 0;
  
      for (int i = 0; i < SPEED_CACHE; i++)
      {
 -      float rec_ms;
 -
 -      hc_timer_get (device_param->speed_rec[i], rec_ms);
 -
 -      if (rec_ms > SPEED_MAXAGE) continue;
 -
        speed_cnt  += device_param->speed_cnt[i];
        speed_ms   += device_param->speed_ms[i];
      }
@@@ -1134,8 -1142,8 +1136,8 @@@ void status_display (
     * speed new
     */
  
 -  u64   speed_cnt[DEVICES_MAX] = { 0 };
 -  float speed_ms[DEVICES_MAX]  = { 0 };
 +  u64    speed_cnt[DEVICES_MAX] = { 0 };
 +  double speed_ms[DEVICES_MAX]  = { 0 };
  
    for (uint device_id = 0; device_id < data.devices_cnt; device_id++)
    {
  
      if (device_param->skipped) continue;
  
 -    // we need to clear values (set to 0) because in case the device does
 -    // not get new candidates it idles around but speed display would
 -    // show it as working.
 -    // if we instantly set it to 0 after reading it happens that the
 -    // speed can be shown as zero if the users refreshes too fast.
 -    // therefore, we add a timestamp when a stat was recorded and if its
 -    // too old we will not use it
 -
      speed_cnt[device_id] = 0;
      speed_ms[device_id]  = 0;
  
      for (int i = 0; i < SPEED_CACHE; i++)
      {
 -      float rec_ms;
 -
 -      hc_timer_get (device_param->speed_rec[i], rec_ms);
 -
 -      if (rec_ms > SPEED_MAXAGE) continue;
 -
        speed_cnt[device_id] += device_param->speed_cnt[i];
        speed_ms[device_id]  += device_param->speed_ms[i];
      }
     * timers
     */
  
 -  float ms_running = 0;
 +  double ms_running = 0;
  
    hc_timer_get (data.timer_running, ms_running);
  
 -  float ms_paused = data.ms_paused;
 +  double ms_paused = data.ms_paused;
  
    if (data.devices_status == STATUS_PAUSED)
    {
 -    float ms_paused_tmp = 0;
 +    double ms_paused_tmp = 0;
  
      hc_timer_get (data.timer_paused, ms_paused_tmp);
  
        }
      }
  
 -    float ms_real = ms_running - ms_paused;
 +    double ms_real = ms_running - ms_paused;
  
      float cpt_avg_min  = (float) data.cpt_total / ((ms_real / 1000) / 60);
      float cpt_avg_hour = (float) data.cpt_total / ((ms_real / 1000) / 3600);
  
  static void status_benchmark ()
  {
 -  if (data.devices_status == STATUS_INIT) return;
 +  if (data.devices_status == STATUS_INIT)     return;
    if (data.devices_status == STATUS_STARTING) return;
  
    if (data.words_cnt == 0) return;
  
 -  u64   speed_cnt[DEVICES_MAX] = { 0 };
 -  float speed_ms[DEVICES_MAX]  = { 0 };
 +  u64    speed_cnt[DEVICES_MAX] = { 0 };
 +  double speed_ms[DEVICES_MAX]  = { 0 };
  
    for (uint device_id = 0; device_id < data.devices_cnt; device_id++)
    {
  
      if (device_param->skipped) continue;
  
 -    speed_cnt[device_id] = 0;
 -    speed_ms[device_id]  = 0;
 -
 -    for (int i = 0; i < SPEED_CACHE; i++)
 -    {
 -      speed_cnt[device_id] += device_param->speed_cnt[i];
 -      speed_ms[device_id]  += device_param->speed_ms[i];
 -    }
 -
 -    speed_cnt[device_id] /= SPEED_CACHE;
 -    speed_ms[device_id]  /= SPEED_CACHE;
 +    speed_cnt[device_id] = device_param->speed_cnt[0];
 +    speed_ms[device_id]  = device_param->speed_ms[0];
    }
  
    float hashes_all_ms = 0;
@@@ -2436,7 -2467,7 +2438,7 @@@ static void run_kernel (const uint kern
  
    if (event_update)
    {
 -    float exec_time;
 +    double exec_time;
  
      hc_timer_get (timer, exec_time);
  
@@@ -2674,24 -2705,6 +2676,24 @@@ static void choose_kernel (hc_device_pa
        if (data.devices_status == STATUS_CRACKED) break;
        if (data.devices_status == STATUS_ABORTED) break;
        if (data.devices_status == STATUS_QUIT)    break;
 +
 +      /**
 +       * speed
 +       */
 +
 +      const float iter_part = (float) (loop_pos + loop_left) / iter;
 +
 +      const u64 perf_sum_all = pws_cnt * iter_part;
 +
 +      double speed_ms;
 +
 +      hc_timer_get (device_param->timer_speed, speed_ms);
 +
 +      const u32 speed_pos = device_param->speed_pos;
 +
 +      device_param->speed_cnt[speed_pos] = perf_sum_all;
 +
 +      device_param->speed_ms[speed_pos] = speed_ms;
      }
  
      if (opts_type & OPTS_TYPE_HOOK23)
@@@ -3292,34 -3305,9 +3294,34 @@@ static void run_cracker (hc_device_para
  
        if (data.benchmark == 1)
        {
 -        for (u32 i = 0; i < data.benchmark_repeats; i++)
 +        double exec_ms_avg_prev = get_avg_exec_time (device_param, EXEC_CACHE);
 +
 +        // a few caching rounds
 +
 +        for (u32 i = 0; i < 2; i++)
          {
 +          hc_timer_set (&device_param->timer_speed);
 +
            choose_kernel (device_param, data.attack_exec, data.attack_mode, data.opts_type, salt_buf, highest_pw_len, pws_cnt);
 +
 +          double exec_ms_avg = get_avg_exec_time (device_param, EXEC_CACHE);
 +
 +          exec_ms_avg_prev = exec_ms_avg;
 +        }
 +
 +        // benchmark_repeats became a maximum possible repeats
 +
 +        for (u32 i = 2; i < data.benchmark_repeats; i++)
 +        {
 +          hc_timer_set (&device_param->timer_speed);
 +
 +          choose_kernel (device_param, data.attack_exec, data.attack_mode, data.opts_type, salt_buf, highest_pw_len, pws_cnt);
 +
 +          double exec_ms_avg = get_avg_exec_time (device_param, EXEC_CACHE);
 +
 +          if ((exec_ms_avg_prev / exec_ms_avg) < 1.001) break;
 +
 +          exec_ms_avg_prev = exec_ms_avg;
          }
        }
  
  
        u64 perf_sum_all = (u64) pws_cnt * (u64) innerloop_left;
  
 -      if (data.benchmark == 1)
 -      {
 -        perf_sum_all = (perf_sum_all * data.benchmark_repeats) + perf_sum_all;
 -      }
 -
        hc_thread_mutex_lock (mux_counter);
  
        data.words_progress_done[salt_pos] += perf_sum_all;
         * speed
         */
  
 -      float speed_ms;
 +      double speed_ms;
  
        hc_timer_get (device_param->timer_speed, speed_ms);
  
  
        hc_thread_mutex_lock (mux_display);
  
 +      // current speed
 +
        device_param->speed_cnt[speed_pos] = perf_sum_all;
  
        device_param->speed_ms[speed_pos] = speed_ms;
  
 -      device_param->speed_rec[speed_pos] = device_param->timer_speed;
 -
        hc_thread_mutex_unlock (mux_display);
  
        speed_pos++;
@@@ -5971,7 -5964,7 +5973,7 @@@ int main (int argc, char **argv
      return (-1);
    }
  
-   if (hash_mode_chgd && hash_mode > 13400) // just added to remove compiler warnings for hash_mode_chgd
+   if (hash_mode_chgd && hash_mode > 13500) // just added to remove compiler warnings for hash_mode_chgd
    {
      log_error ("ERROR: Invalid hash-type specified");
  
                     dgst_pos3   = 3;
                     break;
  
+       case 13500:  hash_type   = HASH_TYPE_SHA1;
+                    salt_type   = SALT_TYPE_EMBEDDED;
+                    attack_exec = ATTACK_EXEC_INSIDE_KERNEL;
+                    opts_type   = OPTS_TYPE_PT_GENERATE_BE
+                                | OPTS_TYPE_PT_UNICODE
+                              | OPTS_TYPE_PT_ADD80;
+                    kern_type   = KERN_TYPE_SHA1_SLTPWU;
+                    dgst_size   = DGST_SIZE_4_5;
+                    parse_func  = pstoken_parse_hash;
+                    sort_by_digest = sort_by_digest_4_5;
+                    opti_type   = OPTI_TYPE_ZERO_BYTE
+                                | OPTI_TYPE_PRECOMPUTE_INIT
+                                | OPTI_TYPE_EARLY_SKIP
+                                | OPTI_TYPE_NOT_ITERATED
+                                | OPTI_TYPE_PREPENDED_SALT
+                                | OPTI_TYPE_RAW_HASH;
+                    dgst_pos0   = 3;
+                    dgst_pos1   = 4;
+                    dgst_pos2   = 2;
+                    dgst_pos3   = 1;
+                    break;
        default:     usage_mini_print (PROGNAME); return (-1);
      }
  
        case 13000:  esalt_size = sizeof (rar5_t);          break;
        case 13100:  esalt_size = sizeof (krb5tgs_t);       break;
        case 13400:  esalt_size = sizeof (keepass_t);       break;
+       case 13500:  esalt_size = sizeof (pstoken_t);       break;
      }
  
      data.esalt_size = esalt_size;
  
          switch (hash_mode)
          {
 -          case  1500: hashes_buf[0].salt->salt_len = 2;
 +          case  1500: hashes_buf[0].salt->salt_len    = 2;
 +                      hashes_buf[0].salt->salt_buf[0] = 388; // pure magic
                        break;
            case  1731: hashes_buf[0].salt->salt_len = 4;
                        break;
  
        hc_clGetDeviceIDs (data.ocl, platform, CL_DEVICE_TYPE_ALL, DEVICES_MAX, platform_devices, &platform_devices_cnt);
  
 +      char platform_vendor[INFOSZ] = { 0 };
 +
 +      hc_clGetPlatformInfo (data.ocl, platform, CL_PLATFORM_VENDOR, sizeof (platform_vendor), platform_vendor, NULL);
 +
 +      // find our own platform vendor because pocl and mesa are pushing original vendor_id through opencl
 +      // this causes trouble with vendor id based macros
 +      // we'll assign generic to those without special optimization available
 +
 +      cl_uint vendor_id = 0;
 +
 +      if (strcmp (platform_vendor, CL_VENDOR_AMD) == 0)
 +      {
 +        vendor_id = VENDOR_ID_AMD;
 +      }
 +      else if (strcmp (platform_vendor, CL_VENDOR_APPLE) == 0)
 +      {
 +        vendor_id = VENDOR_ID_GENERIC;
 +      }
 +      else if (strcmp (platform_vendor, CL_VENDOR_INTEL_BEIGNET) == 0)
 +      {
 +        vendor_id = VENDOR_ID_GENERIC;
 +      }
 +      else if (strcmp (platform_vendor, CL_VENDOR_INTEL_SDK) == 0)
 +      {
 +        vendor_id = VENDOR_ID_GENERIC;
 +      }
 +      else if (strcmp (platform_vendor, CL_VENDOR_MESA) == 0)
 +      {
 +        vendor_id = VENDOR_ID_GENERIC;
 +      }
 +      else if (strcmp (platform_vendor, CL_VENDOR_NV) == 0)
 +      {
 +        vendor_id = VENDOR_ID_NV;
 +      }
 +      else if (strcmp (platform_vendor, CL_VENDOR_POCL) == 0)
 +      {
 +        vendor_id = VENDOR_ID_GENERIC;
 +      }
 +      else
 +      {
 +        vendor_id = VENDOR_ID_GENERIC;
 +      }
 +
        for (uint platform_devices_id = 0; platform_devices_id < platform_devices_cnt; platform_devices_id++)
        {
          size_t param_value_size = 0;
  
          hc_device_param_t *device_param = &data.devices_param[device_id];
  
 +        device_param->vendor_id = vendor_id;
 +
          device_param->device = platform_devices[platform_devices_id];
  
          device_param->device_id = device_id;
  
          device_param->device_type = device_type;
  
 -        // vendor_id
 -
 -        cl_uint vendor_id = 0;
 -
 -        hc_clGetDeviceInfo (data.ocl, device_param->device, CL_DEVICE_VENDOR_ID, sizeof (vendor_id), &vendor_id, NULL);
 -
 -        device_param->vendor_id = vendor_id;
 -
          // device_name
  
          hc_clGetDeviceInfo (data.ocl, device_param->device, CL_DEVICE_NAME, 0, NULL, &param_value_size);
  
          myfree (device_opencl_version);
  
 -        if (strstr (device_version, "pocl"))
 -        {
 -          // pocl returns the real vendor_id in CL_DEVICE_VENDOR_ID which causes many problems because of hms and missing amd_bfe () etc
 -          // we need to overwrite vendor_id to avoid this. maybe open pocl issue?
 -
 -          cl_uint vendor_id = VENDOR_ID_GENERIC;
 -
 -          device_param->vendor_id = vendor_id;
 -        }
 -
          // vector_width
  
          cl_uint vector_width;
  
          if (device_param->skipped == 0)
          {
 -          if (strstr (device_version, "pocl"))
 -          {
 -            if (force == 0)
 -            {
 -              log_info ("");
 -              log_info ("ATTENTION! All pocl drivers are known to be broken due to broken LLVM <= 3.7");
 -              log_info ("You are STRONGLY encouraged not to use it");
 -              log_info ("You can use --force to override this but do not post error reports if you do so");
 -              log_info ("");
 -
 -              return (-1);
 -            }
 -          }
 -
            if (device_type & CL_DEVICE_TYPE_GPU)
            {
 -            if (vendor_id == VENDOR_ID_NV)
 -            {
 -              if (device_param->kernel_exec_timeout != 0)
 -              {
 -                if (data.quiet == 0) log_info ("Device #%u: WARNING! Kernel exec timeout is not disabled, it might cause you errors of code 702", device_id + 1);
 -                if (data.quiet == 0) log_info ("           See the wiki on how to disable it: https://hashcat.net/wiki/doku.php?id=timeout_patch");
 -              }
 -            }
 -            else if (vendor_id == VENDOR_ID_AMD)
 +            if (vendor_id == VENDOR_ID_AMD)
              {
                int catalyst_check = (force == 1) ? 0 : 1;
  
                  log_info ("You can use --force to override this but do not post error reports if you do so");
                  log_info ("");
  
 +                return (-1);
 +              }
 +            }
 +            else if (vendor_id == VENDOR_ID_NV)
 +            {
 +              if (device_param->kernel_exec_timeout != 0)
 +              {
 +                if (data.quiet == 0) log_info ("Device #%u: WARNING! Kernel exec timeout is not disabled, it might cause you errors of code 702", device_id + 1);
 +                if (data.quiet == 0) log_info ("           See the wiki on how to disable it: https://hashcat.net/wiki/doku.php?id=timeout_patch");
 +              }
 +            }
 +            else if (vendor_id == VENDOR_ID_POCL)
 +            {
 +              if (force == 0)
 +              {
 +                log_info ("");
 +                log_info ("ATTENTION! All pocl drivers are known to be broken due to broken LLVM <= 3.7");
 +                log_info ("You are STRONGLY encouraged not to use it");
 +                log_info ("You can use --force to override this but do not post error reports if you do so");
 +                log_info ("");
 +
                  return (-1);
                }
              }
      if (data.quiet == 0) log_info ("");
  
      /**
 -     * Inform user which algorithm is checked and at which workload setting
 +     * In benchmark-mode, inform user which algorithm is checked
       */
  
      if (benchmark == 1)
            device_param->speed_pos = 0;
  
            memset (device_param->speed_cnt, 0, SPEED_CACHE * sizeof (u64));
 -          memset (device_param->speed_ms,  0, SPEED_CACHE * sizeof (float));
 -          memset (device_param->speed_rec, 0, SPEED_CACHE * sizeof (hc_timer_t));
 +          memset (device_param->speed_ms,  0, SPEED_CACHE * sizeof (double));
  
            device_param->exec_pos = 0;
  
diff --combined src/shared.c
@@@ -5853,6 -5853,7 +5853,7 @@@ char *strhashtype (const uint hash_mode
      case 13200: return ((char *) HT_13200); break;
      case 13300: return ((char *) HT_13300); break;
      case 13400: return ((char *) HT_13400); break;
+     case 13500: return ((char *) HT_13500); break;
    }
  
    return ((char *) "Unknown");
@@@ -8479,6 -8480,31 +8480,31 @@@ void ascii_digest (char *out_buf, uint 
          sprintf (ptr_data, "%08x", ptr_keyfile[i]);
      }
    }
+   else if (hash_mode == 13500)
+   {
+     pstoken_t *pstokens = (pstoken_t *) data.esalts_buf;
+     pstoken_t *pstoken  = &pstokens[salt_pos];
+     uint mysalt = pstoken->salt_len > 512 ? 512 : pstoken->salt_len;
+     char pstoken_tmp[1024 + 1];
+     u8 *salt_buf_ptr = (u8 *) pstoken->salt_buf;
+     memset(pstoken_tmp, 0, sizeof (pstoken_tmp));
+     for (uint i = 0; i < mysalt; i++)
+     {
+       snprintf(&pstoken_tmp[i*2], 2, "%02x", salt_buf_ptr[i]);
+     }
+     snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x:%s",
+         digest_buf[0],
+         digest_buf[1],
+         digest_buf[2],
+         digest_buf[3],
+         digest_buf[4],
+       pstoken_tmp);
+   }
    else
    {
      if (hash_type == HASH_TYPE_MD4)
@@@ -8816,7 -8842,7 +8842,7 @@@ void ResumeThreads (
  {
    if (data.devices_status == STATUS_PAUSED)
    {
 -    float ms_paused;
 +    double ms_paused;
  
      hc_timer_get (data.timer_paused, ms_paused);
  
@@@ -11755,6 -11781,54 +11781,54 @@@ int sha1s_parse_hash (char *input_buf, 
    return (PARSER_OK);
  }
  
+ int pstoken_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
+ {
+   if (data.opts_type & OPTS_TYPE_ST_HEX)
+   {
+     if ((input_len < DISPLAY_LEN_MIN_13500) || (input_len > DISPLAY_LEN_MAX_13500)) return (PARSER_GLOBAL_LENGTH);
+   }
+   else
+   {
+     if ((input_len < DISPLAY_LEN_MIN_13500) || (input_len > DISPLAY_LEN_MAX_13500)) return (PARSER_GLOBAL_LENGTH);
+   }
+   u32 *digest = (u32 *) hash_buf->digest;
+   salt_t *salt = hash_buf->salt;
+   pstoken_t *pstoken = (pstoken_t *) hash_buf->esalt;
+   u8 pstoken_tmp[DISPLAY_LEN_MAX_13500 - 40 - 1];
+   memset(pstoken_tmp, 0, DISPLAY_LEN_MAX_13500 - 40 - 1);
+   digest[0] = hex_to_u32 ((const u8 *) &input_buf[ 0]);
+   digest[1] = hex_to_u32 ((const u8 *) &input_buf[ 8]);
+   digest[2] = hex_to_u32 ((const u8 *) &input_buf[16]);
+   digest[3] = hex_to_u32 ((const u8 *) &input_buf[24]);
+   digest[4] = hex_to_u32 ((const u8 *) &input_buf[32]);
+   if (input_buf[40] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
+   uint salt_len = input_len - 40 - 1;
+   char *salt_buf = input_buf + 40 + 1;
+   if (salt_len == UINT_MAX || salt_len % 2 != 0) return (PARSER_SALT_LENGTH);
+   for (uint i = 0; i < salt_len / 2; i++) 
+   { 
+     pstoken_tmp[i] = hex_to_u8 ((const u8 *) &salt_buf[i * 2]); 
+   }
+   salt_len /= 2;
+   salt->salt_len = salt_len;
+   pstoken->salt_len = salt_len;
+   memcpy(salt->salt_buf, pstoken_tmp, 16);
+   memcpy(pstoken->salt_buf, pstoken_tmp, salt_len);
+   return (PARSER_OK);
+ }
  int sha1b64_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
  {
    if ((input_len < DISPLAY_LEN_MIN_101) || (input_len > DISPLAY_LEN_MAX_101)) return (PARSER_GLOBAL_LENGTH);