/**
* Authors.....: Jens Steube <jens.steube@gmail.com>
* Gabriele Gristina <matrix@hashcat.net>
+ * magnum <john.magnum@hushmail.com>
*
* License.....: MIT
*/
* basic bit handling
*/
+u32 is_power_of_2(u32 v)
+{
+ return (v && !(v & (v - 1)));
+}
+
u32 rotl32 (const u32 a, const u32 n)
{
return ((a << n) | (a >> (32 - n)));
#if defined(LINUX) && defined(HAVE_NVML)
int temperature = 0;
- hm_NVML_nvmlDeviceGetTemperature (data.hm_nv, data.hm_device[device_id].adapter_index.nv, NVML_TEMPERATURE_GPU, (unsigned int *) &temperature);
+ hm_NVML_nvmlDeviceGetTemperature (data.hm_nv, data.hm_device[device_id].adapter_index.nv, NVML_TEMPERATURE_GPU, (uint *) &temperature);
return temperature;
#endif
#if defined(LINUX) && defined(HAVE_NVML)
int speed = 0;
- hm_NVML_nvmlDeviceGetFanSpeed (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, (unsigned int *) &speed);
+ hm_NVML_nvmlDeviceGetFanSpeed (data.hm_nv, 1, data.hm_device[device_id].adapter_index.nv, (uint *) &speed);
return speed;
#endif
return NULL;
}
+int sort_by_u32 (const void *v1, const void *v2)
+{
+ const u32 *s1 = (const u32 *) v1;
+ const u32 *s2 = (const u32 *) v2;
+
+ return *s1 - *s2;
+}
+
int sort_by_salt (const void *v1, const void *v2)
{
const salt_t *s1 = (const salt_t *) v1;
if (res3 != 0) return (res3);
- const int res4 = t1->workload_profile
- - t2->workload_profile;
-
- if (res4 != 0) return (res4);
-
return 0;
}
case 12800: return ((char *) HT_12800); break;
case 12900: return ((char *) HT_12900); break;
case 13000: return ((char *) HT_13000); break;
+ case 13100: return ((char *) HT_13100); break;
+ case 13200: return ((char *) HT_13200); break;
+ case 13300: return ((char *) HT_13300); break;
}
return ((char *) "Unknown");
case STATUS_QUIT: return ((char *) ST_0007); break;
case STATUS_BYPASS: return ((char *) ST_0008); break;
case STATUS_STOP_AT_CHECKPOINT: return ((char *) ST_0009); break;
+ case STATUS_AUTOTUNE: return ((char *) ST_0010); break;
}
return ((char *) "Unknown");
byte_swap_32 (digest_buf[1])
);
}
+ else if (hash_mode == 13100)
+ {
+ krb5tgs_t *krb5tgss = (krb5tgs_t *) data.esalts_buf;
+
+ krb5tgs_t *krb5tgs = &krb5tgss[salt_pos];
+
+ u8 *ptr_checksum = (u8 *) krb5tgs->checksum;
+ u8 *ptr_edata2 = (u8 *) krb5tgs->edata2;
+
+ char data[2560 * 4 * 2] = { 0 };
+
+ char *ptr_data = data;
+
+ for (uint i = 0; i < 16; i++, ptr_data += 2)
+ sprintf (ptr_data, "%02x", ptr_checksum[i]);
+
+ /* skip '$' */
+ ptr_data++;
+
+ for (uint i = 0; i < krb5tgs->edata2_len; i++, ptr_data += 2)
+ sprintf (ptr_data, "%02x", ptr_edata2[i]);
+
+ snprintf (out_buf, len-1, "%s$%s$%s$%s",
+ SIGNATURE_KRB5TGS,
+ (char *) krb5tgs->account_info,
+ data,
+ data + 33);
+ }
+ else if (hash_mode == 13200)
+ {
+ snprintf (out_buf, len-1, "%s*%d*%08x%08x%08x%08x*%08x%08x%08x%08x%08x%08x",
+ SIGNATURE_AXCRYPT,
+ salt.salt_iter,
+ salt.salt_buf[0],
+ salt.salt_buf[1],
+ salt.salt_buf[2],
+ salt.salt_buf[3],
+ salt.salt_buf[4],
+ salt.salt_buf[5],
+ salt.salt_buf[6],
+ salt.salt_buf[7],
+ salt.salt_buf[8],
+ salt.salt_buf[9]);
+ }
+ else if (hash_mode == 13300)
+ {
+ snprintf (out_buf, len-1, "%s$%08x%08x%08x%08x",
+ SIGNATURE_AXCRYPT_SHA1,
+ digest_buf[0],
+ digest_buf[1],
+ digest_buf[2],
+ digest_buf[3]);
+ }
else
{
if (hash_type == HASH_TYPE_MD4)
tuning_db->alias_cnt++;
}
- else if (token_cnt == 7)
+ else if (token_cnt == 6)
{
if ((token_ptr[1][0] != '0') &&
(token_ptr[1][0] != '1') &&
if ((token_ptr[3][0] != '1') &&
(token_ptr[3][0] != '2') &&
- (token_ptr[3][0] != '3') &&
- (token_ptr[3][0] != '*'))
+ (token_ptr[3][0] != '4') &&
+ (token_ptr[3][0] != '8') &&
+ (token_ptr[3][0] != 'N'))
{
- log_info ("WARNING: Tuning-db: Invalid workload_profile '%c' in Line '%u'", token_ptr[3][0], line_num);
-
- continue;
- }
-
- if ((token_ptr[4][0] != '1') &&
- (token_ptr[4][0] != '2') &&
- (token_ptr[4][0] != '4') &&
- (token_ptr[4][0] != '8') &&
- (token_ptr[4][0] != 'N'))
- {
- log_info ("WARNING: Tuning-db: Invalid vector_width '%c' in Line '%u'", token_ptr[4][0], line_num);
+ log_info ("WARNING: Tuning-db: Invalid vector_width '%c' in Line '%u'", token_ptr[3][0], line_num);
continue;
}
int attack_mode = -1;
int hash_type = -1;
- int workload_profile = -1;
int vector_width = -1;
int kernel_accel = -1;
int kernel_loops = -1;
if (token_ptr[1][0] != '*') attack_mode = atoi (token_ptr[1]);
if (token_ptr[2][0] != '*') hash_type = atoi (token_ptr[2]);
- if (token_ptr[3][0] != '*') workload_profile = atoi (token_ptr[3]);
- if (token_ptr[4][0] != 'N') vector_width = atoi (token_ptr[4]);
-
- kernel_accel = atoi (token_ptr[5]);
+ if (token_ptr[3][0] != 'N') vector_width = atoi (token_ptr[3]);
- if ((kernel_accel < 1) || (kernel_accel > 1024))
+ if (token_ptr[4][0] != 'A')
{
- log_info ("WARNING: Tuning-db: Invalid kernel_accel '%d' in Line '%u'", kernel_accel, line_num);
+ kernel_accel = atoi (token_ptr[4]);
- continue;
- }
+ if ((kernel_accel < 1) || (kernel_accel > 1024))
+ {
+ log_info ("WARNING: Tuning-db: Invalid kernel_accel '%d' in Line '%u'", kernel_accel, line_num);
- kernel_loops = atoi (token_ptr[6]);
+ continue;
+ }
+ }
+ else
+ {
+ kernel_accel = 0;
+ }
- if ((kernel_loops < 1) || (kernel_loops > 1024))
+ if (token_ptr[5][0] != 'A')
{
- log_info ("WARNING: Tuning-db: Invalid kernel_loops '%d' in Line '%u'", kernel_loops, line_num);
+ kernel_loops = atoi (token_ptr[5]);
- continue;
+ if ((kernel_loops < 1) || (kernel_loops > 1024))
+ {
+ log_info ("WARNING: Tuning-db: Invalid kernel_loops '%d' in Line '%u'", kernel_loops, line_num);
+
+ continue;
+ }
+ }
+ else
+ {
+ kernel_loops = 0;
}
tuning_db_entry_t *entry = &tuning_db->entry_buf[tuning_db->entry_cnt];
- entry->device_name = mystrdup (device_name);
- entry->attack_mode = attack_mode;
- entry->hash_type = hash_type;
- entry->workload_profile = workload_profile;
- entry->vector_width = vector_width;
- entry->kernel_accel = kernel_accel;
- entry->kernel_loops = kernel_loops;
+ entry->device_name = mystrdup (device_name);
+ entry->attack_mode = attack_mode;
+ entry->hash_type = hash_type;
+ entry->vector_width = vector_width;
+ entry->kernel_accel = kernel_accel;
+ entry->kernel_loops = kernel_loops;
tuning_db->entry_cnt++;
}
else
{
- // todo: some warning message
+ log_info ("WARNING: Tuning-db: Invalid number of token in Line '%u'", line_num);
continue;
}
return tuning_db;
}
-tuning_db_entry_t *tuning_db_search (tuning_db_t *tuning_db, char *device_name, int attack_mode, int hash_type, int workload_profile)
+tuning_db_entry_t *tuning_db_search (tuning_db_t *tuning_db, hc_device_param_t *device_param, int attack_mode, int hash_type)
{
static tuning_db_entry_t s;
// first we need to convert all spaces in the device_name to underscore
- char *device_name_nospace = strdup (device_name);
+ char *device_name_nospace = strdup (device_param->device_name);
int device_name_length = strlen (device_name_nospace);
// bsearch is not ideal but fast enough
- s.device_name = device_name_nospace;
- s.attack_mode = attack_mode;
- s.hash_type = hash_type;
- s.workload_profile = workload_profile;
+ s.device_name = device_name_nospace;
+ s.attack_mode = attack_mode;
+ s.hash_type = hash_type;
tuning_db_entry_t *entry = NULL;
- // this will produce all 2^4 combinations required
+ // this will produce all 2^3 combinations required
- for (i = 0; i < 16; i++)
+ for (i = 0; i < 8; i++)
{
- s.device_name = (i & 1) ? "*" : device_name_nospace;
- s.attack_mode = (i & 2) ? -1 : attack_mode;
- s.hash_type = (i & 4) ? -1 : hash_type;
- s.workload_profile = (i & 8) ? -1 : workload_profile;
+ s.device_name = (i & 1) ? "*" : device_name_nospace;
+ s.attack_mode = (i & 2) ? -1 : attack_mode;
+ s.hash_type = (i & 4) ? -1 : hash_type;
entry = bsearch (&s, tuning_db->entry_buf, tuning_db->entry_cnt, sizeof (tuning_db_entry_t), sort_by_tuning_db_entry);
if (entry != NULL) break;
- // in non-wildcard mode also check the alias_name
+ // in non-wildcard mode do some additional checks:
- if (((i & 1) == 0) && (alias_name != NULL))
+ if ((i & 1) == 0)
{
- s.device_name = alias_name;
+ // in case we have an alias-name
- entry = bsearch (&s, tuning_db->entry_buf, tuning_db->entry_cnt, sizeof (tuning_db_entry_t), sort_by_tuning_db_entry);
+ if (alias_name != NULL)
+ {
+ s.device_name = alias_name;
- if (entry != NULL) break;
- }
- }
+ entry = bsearch (&s, tuning_db->entry_buf, tuning_db->entry_cnt, sizeof (tuning_db_entry_t), sort_by_tuning_db_entry);
- // if still not found use some defaults
+ if (entry != NULL) break;
+ }
- if (entry == NULL)
- {
- s.vector_width = TUNING_DB_DEFAULT_VECTOR_WIDTH;
- s.kernel_accel = TUNING_DB_DEFAULT_KERNEL_ACCEL;
- s.kernel_loops = TUNING_DB_DEFAULT_KERNEL_LOOPS;
+ // or by device type
- return &s;
+ if (device_param->device_type & CL_DEVICE_TYPE_CPU)
+ {
+ s.device_name = "DEVICE_TYPE_CPU";
+ }
+ else if (device_param->device_type & CL_DEVICE_TYPE_GPU)
+ {
+ s.device_name = "DEVICE_TYPE_GPU";
+ }
+ else if (device_param->device_type & CL_DEVICE_TYPE_ACCELERATOR)
+ {
+ s.device_name = "DEVICE_TYPE_ACCELERATOR";
+ }
+
+ entry = bsearch (&s, tuning_db->entry_buf, tuning_db->entry_cnt, sizeof (tuning_db_entry_t), sort_by_tuning_db_entry);
+
+ if (entry != NULL) break;
+ }
}
// free converted device_name
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
- // max. salt length: salt_buf[32] => 32 - 22 (":Administration Tools:") = 10
- if (salt_len > 10) return (PARSER_SALT_LENGTH);
+ // max. salt length: 55 (max for MD5) - 22 (":Administration Tools:") - 1 (0x80) = 32
+ // 32 - 4 bytes (to fit w0lr for all attack modes) = 28
+
+ if (salt_len > 28) return (PARSER_SALT_LENGTH);
salt->salt_len = salt_len;
uint salt_len = strlen (in.essid);
+ if (salt_len > 36)
+ {
+ log_info ("WARNING: the length of the ESSID is too long. The hccap file may be invalid or corrupted");
+
+ return (PARSER_SALT_LENGTH);
+ }
+
memcpy (salt->salt_buf, in.essid, salt_len);
salt->salt_len = salt_len;
}
}
- salt->salt_buf[10] = digest[1];
- salt->salt_buf[11] = digest[2];
+ uint32_t *p0 = (uint32_t *) in.essid;
+ uint32_t c0 = 0;
+ uint32_t c1 = 0;
+
+ for (uint i = 0; i < sizeof (in.essid) / sizeof (uint32_t); i++) c0 ^= *p0++;
+ for (uint i = 0; i < sizeof (wpa->pke) / sizeof (wpa->pke[0]); i++) c1 ^= wpa->pke[i];
+
+ salt->salt_buf[10] = c0;
+ salt->salt_buf[11] = c1;
return (PARSER_OK);
}
int md5crypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
{
+ if (input_len < DISPLAY_LEN_MIN_500) return (PARSER_GLOBAL_LENGTH);
+
if (memcmp (SIGNATURE_MD5CRYPT, input_buf, 3)) return (PARSER_SIGNATURE_UNMATCHED);
u32 *digest = (u32 *) hash_buf->digest;
salt->salt_iter = ROUNDS_MD5CRYPT;
}
- if ((input_len < DISPLAY_LEN_MIN_500) || (input_len > (DISPLAY_LEN_MAX_500 + iterations_len))) return (PARSER_GLOBAL_LENGTH);
+ if (input_len > (DISPLAY_LEN_MAX_500 + iterations_len)) return (PARSER_GLOBAL_LENGTH);
char *hash_pos = strchr (salt_pos, '$');
char *hash_pos = strchr (srvchall_pos, ':');
- if (srvchall_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
+ if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
uint srvchall_len = hash_pos - srvchall_pos;
char *hash_pos = strchr (srvchall_pos, ':');
- if (srvchall_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
+ if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
uint srvchall_len = hash_pos - srvchall_pos;
return (PARSER_OK);
}
+int sha1axcrypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
+{
+ if ((input_len < DISPLAY_LEN_MIN_13300) || (input_len > DISPLAY_LEN_MAX_13300)) return (PARSER_GLOBAL_LENGTH);
+
+ if (memcmp (SIGNATURE_AXCRYPT_SHA1, input_buf, 13)) return (PARSER_SIGNATURE_UNMATCHED);
+
+ u32 *digest = (u32 *) hash_buf->digest;
+
+ input_buf +=14;
+
+ 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] = 0x00000000;
+
+ return (PARSER_OK);
+}
+
int sha1s_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
{
if (data.opts_type & OPTS_TYPE_ST_HEX)
int tmp_len = base64_decode (base64_to_int, (const u8 *) input_buf + 6, input_len - 6, tmp_buf);
+ if (tmp_len < 20) return (PARSER_HASH_LENGTH);
+
memcpy (digest, tmp_buf, 20);
- salt->salt_len = tmp_len - 20;
+ int salt_len = tmp_len - 20;
+
+ if (salt_len < 0) return (PARSER_SALT_LENGTH);
+
+ salt->salt_len = salt_len;
memcpy (salt->salt_buf, tmp_buf + 20, salt->salt_len);
in_off[0] = strtok (input_buf, ":");
+ if (in_off[0] == NULL) return (PARSER_SEPARATOR_UNMATCHED);
+
in_len[0] = strlen (in_off[0]);
size_t i;
in_off[0] = strtok (input_buf, ":");
+ if (in_off[0] == NULL) return (PARSER_SEPARATOR_UNMATCHED);
+
in_len[0] = strlen (in_off[0]);
size_t i;
int tmp_len = base64_decode (base64_to_int, (const u8 *) input_buf + 9, input_len - 9, tmp_buf);
+ if (tmp_len < 64) return (PARSER_HASH_LENGTH);
+
memcpy (digest, tmp_buf, 64);
digest[0] = byte_swap_64 (digest[0]);
digest[6] -= SHA512M_G;
digest[7] -= SHA512M_H;
- salt->salt_len = tmp_len - 64;
+ int salt_len = tmp_len - 64;
+
+ if (salt_len < 0) return (PARSER_SALT_LENGTH);
+
+ salt->salt_len = salt_len;
memcpy (salt->salt_buf, tmp_buf + 64, salt->salt_len);
u32 *digest = (u32 *) hash_buf->digest;
+ salt_t *salt = hash_buf->salt;
+
u8 tmp_buf[100] = { 0 };
base64_decode (base64_to_int, (const u8 *) input_buf, input_len, tmp_buf);
digest[3] -= SHA1M_D;
digest[4] -= SHA1M_E;
+ salt->salt_buf[0] = 0x80;
+
+ salt->salt_len = 0;
+
return (PARSER_OK);
}
return (PARSER_OK);
}
+int krb5tgs_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
+{
+ if ((input_len < DISPLAY_LEN_MIN_13100) || (input_len > DISPLAY_LEN_MAX_13100)) return (PARSER_GLOBAL_LENGTH);
+
+ if (memcmp (SIGNATURE_KRB5TGS, input_buf, 11)) return (PARSER_SIGNATURE_UNMATCHED);
+
+ u32 *digest = (u32 *) hash_buf->digest;
+
+ salt_t *salt = hash_buf->salt;
+
+ krb5tgs_t *krb5tgs = (krb5tgs_t *) hash_buf->esalt;
+
+ /**
+ * parse line
+ */
+
+ /* Skip '$' */
+ char *account_pos = input_buf + 11 + 1;
+
+ char *data_pos;
+
+ uint data_len;
+
+ if (account_pos[0] == '*')
+ {
+ account_pos++;
+
+ data_pos = strchr (account_pos, '*');
+
+ /* Skip '*' */
+ data_pos++;
+
+ if (data_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
+
+ uint account_len = data_pos - account_pos + 1;
+
+ if (account_len >= 512) return (PARSER_SALT_LENGTH);
+
+ /* Skip '$' */
+ data_pos++;
+
+ data_len = input_len - 11 - 1 - account_len - 2;
+
+ memcpy (krb5tgs->account_info, account_pos - 1, account_len);
+ }
+ else
+ {
+ /* assume $krb5tgs$23$checksum$edata2 */
+ data_pos = account_pos;
+
+ memcpy (krb5tgs->account_info, "**", 3);
+
+ data_len = input_len - 11 - 1 - 1;
+ }
+
+ if (data_len < ((16 + 32) * 2)) return (PARSER_SALT_LENGTH);
+
+ char *checksum_ptr = (char *) krb5tgs->checksum;
+
+ for (uint i = 0; i < 16 * 2; i += 2)
+ {
+ const char p0 = data_pos[i + 0];
+ const char p1 = data_pos[i + 1];
+
+ *checksum_ptr++ = hex_convert (p1) << 0
+ | hex_convert (p0) << 4;
+ }
+
+ char *edata_ptr = (char *) krb5tgs->edata2;
+
+ krb5tgs->edata2_len = (data_len - 32) / 2 ;
+
+ /* skip '$' */
+ for (uint i = 16 * 2 + 1; i < (krb5tgs->edata2_len * 2) + (16 * 2 + 1); i += 2)
+ {
+ const char p0 = data_pos[i + 0];
+ const char p1 = data_pos[i + 1];
+ *edata_ptr++ = hex_convert (p1) << 0
+ | hex_convert (p0) << 4;
+ }
+
+ /* this is needed for hmac_md5 */
+ *edata_ptr++ = 0x80;
+
+ salt->salt_buf[0] = krb5tgs->checksum[0];
+ salt->salt_buf[1] = krb5tgs->checksum[1];
+ salt->salt_buf[2] = krb5tgs->checksum[2];
+ salt->salt_buf[3] = krb5tgs->checksum[3];
+
+ salt->salt_len = 32;
+
+ digest[0] = krb5tgs->checksum[0];
+ digest[1] = krb5tgs->checksum[1];
+ digest[2] = krb5tgs->checksum[2];
+ digest[3] = krb5tgs->checksum[3];
+
+ return (PARSER_OK);
+}
+
+int axcrypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
+{
+ if ((input_len < DISPLAY_LEN_MIN_13200) || (input_len > DISPLAY_LEN_MAX_13200)) return (PARSER_GLOBAL_LENGTH);
+
+ if (memcmp (SIGNATURE_AXCRYPT, input_buf, 11)) return (PARSER_SIGNATURE_UNMATCHED);
+
+ u32 *digest = (u32 *) hash_buf->digest;
+
+ salt_t *salt = hash_buf->salt;
+
+ /**
+ * parse line
+ */
+
+ /* Skip '*' */
+ char *wrapping_rounds_pos = input_buf + 11 + 1;
+
+ char *salt_pos;
+
+ char *wrapped_key_pos;
+
+ char *data_pos;
+
+ salt->salt_iter = atoi (wrapping_rounds_pos);
+
+ salt_pos = strchr (wrapping_rounds_pos, '*');
+
+ if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
+
+ uint wrapping_rounds_len = salt_pos - wrapping_rounds_pos;
+
+ /* Skip '*' */
+ salt_pos++;
+
+ data_pos = salt_pos;
+
+ wrapped_key_pos = strchr (salt_pos, '*');
+
+ if (wrapped_key_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
+
+ uint salt_len = wrapped_key_pos - salt_pos;
+
+ if (salt_len != 32) return (PARSER_SALT_LENGTH);
+
+ /* Skip '*' */
+ wrapped_key_pos++;
+
+ uint wrapped_key_len = input_len - 11 - 1 - wrapping_rounds_len - 1 - salt_len - 1;
+
+ if (wrapped_key_len != 48) return (PARSER_SALT_LENGTH);
+
+ salt->salt_buf[0] = hex_to_u32 ((const u8 *) &data_pos[ 0]);
+ salt->salt_buf[1] = hex_to_u32 ((const u8 *) &data_pos[ 8]);
+ salt->salt_buf[2] = hex_to_u32 ((const u8 *) &data_pos[16]);
+ salt->salt_buf[3] = hex_to_u32 ((const u8 *) &data_pos[24]);
+
+ data_pos += 33;
+
+ salt->salt_buf[4] = hex_to_u32 ((const u8 *) &data_pos[ 0]);
+ salt->salt_buf[5] = hex_to_u32 ((const u8 *) &data_pos[ 8]);
+ salt->salt_buf[6] = hex_to_u32 ((const u8 *) &data_pos[16]);
+ salt->salt_buf[7] = hex_to_u32 ((const u8 *) &data_pos[24]);
+ salt->salt_buf[8] = hex_to_u32 ((const u8 *) &data_pos[32]);
+ salt->salt_buf[9] = hex_to_u32 ((const u8 *) &data_pos[40]);
+
+ salt->salt_len = 40;
+
+ digest[0] = salt->salt_buf[0];
+ digest[1] = salt->salt_buf[1];
+ digest[2] = salt->salt_buf[2];
+ digest[3] = salt->salt_buf[3];
+
+ return (PARSER_OK);
+}
+
int cf10_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
{
if ((input_len < DISPLAY_LEN_MIN_12600) || (input_len > DISPLAY_LEN_MAX_12600)) return (PARSER_GLOBAL_LENGTH);