mirror of
https://github.com/hashcat/hashcat.git
synced 2024-11-15 12:29:35 +00:00
20163 lines
532 KiB
C
20163 lines
532 KiB
C
/**
|
|
* Author......: Jens Steube <jens.steube@gmail.com>
|
|
* License.....: MIT
|
|
*/
|
|
|
|
#include <shared.h>
|
|
#include <limits.h>
|
|
|
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
|
|
|
/**
|
|
* tuning tools
|
|
*/
|
|
|
|
#define GET_ACCEL(x) GPU_ACCEL_AMD_ ## x
|
|
#define GET_LOOPS(x) GPU_LOOPS_AMD_ ## x
|
|
|
|
/**
|
|
* bit rotate
|
|
*/
|
|
|
|
uint32_t rotl32 (const uint32_t a, const uint n)
|
|
{
|
|
return ((a << n) | (a >> (32 - n)));
|
|
}
|
|
|
|
uint32_t rotr32 (const uint32_t a, const uint n)
|
|
{
|
|
return ((a >> n) | (a << (32 - n)));
|
|
}
|
|
|
|
uint64_t rotl64 (const uint64_t a, const uint n)
|
|
{
|
|
return ((a << n) | (a >> (64 - n)));
|
|
}
|
|
|
|
uint64_t rotr64 (const uint64_t a, const uint n)
|
|
{
|
|
return ((a >> n) | (a << (64 - n)));
|
|
}
|
|
|
|
/**
|
|
* ciphers for use on cpu
|
|
*/
|
|
|
|
#include "cpu-des.c"
|
|
#include "cpu-aes.c"
|
|
|
|
/**
|
|
* hashes for use on cpu
|
|
*/
|
|
|
|
#include "cpu-md5.c"
|
|
#include "cpu-sha256.c"
|
|
|
|
/**
|
|
* logging
|
|
*/
|
|
|
|
int last_len = 0;
|
|
|
|
void log_final (FILE *fp, const char *fmt, va_list ap)
|
|
{
|
|
if (last_len)
|
|
{
|
|
fputc ('\r', fp);
|
|
|
|
for (int i = 0; i < last_len; i++)
|
|
{
|
|
fputc (' ', fp);
|
|
}
|
|
|
|
fputc ('\r', fp);
|
|
}
|
|
|
|
char s[4096];
|
|
|
|
int max_len = (int) sizeof (s);
|
|
|
|
int len = vsnprintf (s, max_len, fmt, ap);
|
|
|
|
if (len > max_len) len = max_len;
|
|
|
|
fwrite (s, len, 1, fp);
|
|
|
|
fflush (fp);
|
|
|
|
last_len = len;
|
|
}
|
|
|
|
void log_out_nn (FILE *fp, const char *fmt, ...)
|
|
{
|
|
if (SUPPRESS_OUTPUT) return;
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
log_final (fp, fmt, ap);
|
|
|
|
va_end (ap);
|
|
}
|
|
|
|
void log_info_nn (const char *fmt, ...)
|
|
{
|
|
if (SUPPRESS_OUTPUT) return;
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
log_final (stdout, fmt, ap);
|
|
|
|
va_end (ap);
|
|
}
|
|
|
|
void log_error_nn (const char *fmt, ...)
|
|
{
|
|
if (SUPPRESS_OUTPUT) return;
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
log_final (stderr, fmt, ap);
|
|
|
|
va_end (ap);
|
|
}
|
|
|
|
void log_out (FILE *fp, const char *fmt, ...)
|
|
{
|
|
if (SUPPRESS_OUTPUT) return;
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
log_final (fp, fmt, ap);
|
|
|
|
va_end (ap);
|
|
|
|
fputc ('\n', fp);
|
|
|
|
last_len = 0;
|
|
}
|
|
|
|
void log_info (const char *fmt, ...)
|
|
{
|
|
if (SUPPRESS_OUTPUT) return;
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
log_final (stdout, fmt, ap);
|
|
|
|
va_end (ap);
|
|
|
|
fputc ('\n', stdout);
|
|
|
|
last_len = 0;
|
|
}
|
|
|
|
void log_error (const char *fmt, ...)
|
|
{
|
|
if (SUPPRESS_OUTPUT) return;
|
|
|
|
fputc ('\n', stderr);
|
|
fputc ('\n', stderr);
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
log_final (stderr, fmt, ap);
|
|
|
|
va_end (ap);
|
|
|
|
fputc ('\n', stderr);
|
|
fputc ('\n', stderr);
|
|
|
|
last_len = 0;
|
|
}
|
|
|
|
/**
|
|
* converter
|
|
*/
|
|
|
|
uint byte_swap_32 (const uint n)
|
|
{
|
|
return (n & 0xff000000) >> 24
|
|
| (n & 0x00ff0000) >> 8
|
|
| (n & 0x0000ff00) << 8
|
|
| (n & 0x000000ff) << 24;
|
|
}
|
|
|
|
uint64_t byte_swap_64 (const uint64_t n)
|
|
{
|
|
return (n & 0xff00000000000000ULL) >> 56
|
|
| (n & 0x00ff000000000000ULL) >> 40
|
|
| (n & 0x0000ff0000000000ULL) >> 24
|
|
| (n & 0x000000ff00000000ULL) >> 8
|
|
| (n & 0x00000000ff000000ULL) << 8
|
|
| (n & 0x0000000000ff0000ULL) << 24
|
|
| (n & 0x000000000000ff00ULL) << 40
|
|
| (n & 0x00000000000000ffULL) << 56;
|
|
}
|
|
|
|
char int_to_base32 (const char c)
|
|
{
|
|
static const char tbl[0x20] =
|
|
{
|
|
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
|
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
|
|
};
|
|
|
|
return tbl[(const uint8_t) c];
|
|
}
|
|
|
|
char base32_to_int (const char c)
|
|
{
|
|
if ((c >= 'A') && (c <= 'Z')) return c - 'A';
|
|
else if ((c >= '2') && (c <= '7')) return c - '2' + 26;
|
|
|
|
return 0;
|
|
}
|
|
|
|
char int_to_itoa32 (const char c)
|
|
{
|
|
static const char tbl[0x20] =
|
|
{
|
|
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
|
|
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
|
|
};
|
|
|
|
return tbl[(const uint8_t) c];
|
|
}
|
|
|
|
char itoa32_to_int (const char c)
|
|
{
|
|
if ((c >= '0') && (c <= '9')) return c - '0';
|
|
else if ((c >= 'a') && (c <= 'v')) return c - 'a' + 10;
|
|
|
|
return 0;
|
|
}
|
|
|
|
char int_to_itoa64 (const char c)
|
|
{
|
|
static const char tbl[0x40] =
|
|
{
|
|
0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
|
|
0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54,
|
|
0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
|
|
0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
|
|
};
|
|
|
|
return tbl[(const uint8_t) c];
|
|
}
|
|
|
|
char itoa64_to_int (const char c)
|
|
{
|
|
static const char tbl[0x100] =
|
|
{
|
|
0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21,
|
|
0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31,
|
|
0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x01,
|
|
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
|
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,
|
|
0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24,
|
|
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
|
|
0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x01, 0x02, 0x03, 0x04,
|
|
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
|
|
0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
|
|
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
|
|
0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x01, 0x02, 0x03, 0x04,
|
|
0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
|
|
0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
|
|
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
|
|
0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x01, 0x02, 0x03, 0x04,
|
|
};
|
|
|
|
return tbl[(const uint8_t) c];
|
|
}
|
|
|
|
char int_to_base64 (const char c)
|
|
{
|
|
static const char tbl[0x40] =
|
|
{
|
|
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,
|
|
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
|
|
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
|
|
0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2b, 0x2f,
|
|
};
|
|
|
|
return tbl[(const uint8_t) c];
|
|
}
|
|
|
|
char base64_to_int (const char c)
|
|
{
|
|
static const char tbl[0x100] =
|
|
{
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3f,
|
|
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
|
|
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
|
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
return tbl[(const uint8_t) c];
|
|
}
|
|
|
|
char int_to_bf64 (const char c)
|
|
{
|
|
static const char tbl[0x40] =
|
|
{
|
|
0x2e, 0x2f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
|
|
0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x61, 0x62, 0x63, 0x64,
|
|
0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74,
|
|
0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
|
|
};
|
|
|
|
return tbl[(const uint8_t) c];
|
|
}
|
|
|
|
char bf64_to_int (const char c)
|
|
{
|
|
static const char tbl[0x100] =
|
|
{
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
|
0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
|
|
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,
|
|
0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
};
|
|
|
|
return tbl[(const uint8_t) c];
|
|
}
|
|
|
|
char int_to_lotus64 (const char c)
|
|
{
|
|
if (c < 10) return '0' + c;
|
|
else if (c < 36) return 'A' + c - 10;
|
|
else if (c < 62) return 'a' + c - 36;
|
|
else if (c == 62) return '+';
|
|
else if (c == 63) return '/';
|
|
|
|
return 0;
|
|
}
|
|
|
|
char lotus64_to_int (const char c)
|
|
{
|
|
if ((c >= '0') && (c <= '9')) return c - '0';
|
|
else if ((c >= 'A') && (c <= 'Z')) return c - 'A' + 10;
|
|
else if ((c >= 'a') && (c <= 'z')) return c - 'a' + 36;
|
|
else if (c == '+') return 62;
|
|
else if (c == '/') return 63;
|
|
else
|
|
|
|
return 0;
|
|
}
|
|
|
|
int base32_decode (char (*f) (const char), char *in_buf, int in_len, char *out_buf)
|
|
{
|
|
char *in_ptr = in_buf;
|
|
|
|
char *out_ptr = out_buf;
|
|
|
|
for (int i = 0; i < in_len; i += 8)
|
|
{
|
|
char out_val0 = f (in_ptr[0] & 0x7f);
|
|
char out_val1 = f (in_ptr[1] & 0x7f);
|
|
char out_val2 = f (in_ptr[2] & 0x7f);
|
|
char out_val3 = f (in_ptr[3] & 0x7f);
|
|
char out_val4 = f (in_ptr[4] & 0x7f);
|
|
char out_val5 = f (in_ptr[5] & 0x7f);
|
|
char out_val6 = f (in_ptr[6] & 0x7f);
|
|
char out_val7 = f (in_ptr[7] & 0x7f);
|
|
|
|
out_ptr[0] = ((out_val0 << 3) & 0xf8) | ((out_val1 >> 2) & 0x07);
|
|
out_ptr[1] = ((out_val1 << 6) & 0xc0) | ((out_val2 << 1) & 0x3e) | ((out_val3 >> 4) & 0x01);
|
|
out_ptr[2] = ((out_val3 << 4) & 0xf0) | ((out_val4 >> 1) & 0x0f);
|
|
out_ptr[3] = ((out_val4 << 7) & 0x80) | ((out_val5 << 2) & 0x7c) | ((out_val6 >> 3) & 0x03);
|
|
out_ptr[4] = ((out_val6 << 5) & 0xe0) | ((out_val7 >> 0) & 0x1f);
|
|
|
|
in_ptr += 8;
|
|
out_ptr += 5;
|
|
}
|
|
|
|
for (int i = 0; i < in_len; i++)
|
|
{
|
|
if (in_buf[i] != '=') continue;
|
|
|
|
in_len = i;
|
|
}
|
|
|
|
int out_len = (in_len * 5) / 8;
|
|
|
|
return out_len;
|
|
}
|
|
|
|
int base32_encode (char (*f) (const char), char *in_buf, int in_len, char *out_buf)
|
|
{
|
|
char *in_ptr = in_buf;
|
|
|
|
char *out_ptr = out_buf;
|
|
|
|
for (int i = 0; i < in_len; i += 5)
|
|
{
|
|
char out_val0 = f ( ((in_ptr[0] >> 3) & 0x1f));
|
|
char out_val1 = f (((in_ptr[0] << 2) & 0x1c) | ((in_ptr[1] >> 6) & 0x03));
|
|
char out_val2 = f ( ((in_ptr[1] >> 1) & 0x1f));
|
|
char out_val3 = f (((in_ptr[1] << 4) & 0x10) | ((in_ptr[2] >> 4) & 0x0f));
|
|
char out_val4 = f (((in_ptr[2] << 1) & 0x1e) | ((in_ptr[3] >> 7) & 0x01));
|
|
char out_val5 = f ( ((in_ptr[3] >> 2) & 0x1f));
|
|
char out_val6 = f (((in_ptr[3] << 3) & 0x18) | ((in_ptr[4] >> 5) & 0x07));
|
|
char out_val7 = f ( ((in_ptr[4] >> 0) & 0x1f));
|
|
|
|
out_ptr[0] = out_val0 & 0x7f;
|
|
out_ptr[1] = out_val1 & 0x7f;
|
|
out_ptr[2] = out_val2 & 0x7f;
|
|
out_ptr[3] = out_val3 & 0x7f;
|
|
out_ptr[4] = out_val4 & 0x7f;
|
|
out_ptr[5] = out_val5 & 0x7f;
|
|
out_ptr[6] = out_val6 & 0x7f;
|
|
out_ptr[7] = out_val7 & 0x7f;
|
|
|
|
in_ptr += 5;
|
|
out_ptr += 8;
|
|
}
|
|
|
|
int out_len = (in_len * 8) / 5;
|
|
|
|
for (int i = 0; i < (7 - (in_len % 7)); i++)
|
|
{
|
|
out_len++;
|
|
|
|
out_buf[out_len] = '=';
|
|
}
|
|
|
|
return out_len;
|
|
}
|
|
|
|
int base64_decode (char (*f) (const char), char *in_buf, int in_len, char *out_buf)
|
|
{
|
|
char *in_ptr = in_buf;
|
|
|
|
char *out_ptr = out_buf;
|
|
|
|
for (int i = 0; i < in_len; i += 4)
|
|
{
|
|
char out_val0 = f (in_ptr[0] & 0x7f);
|
|
char out_val1 = f (in_ptr[1] & 0x7f);
|
|
char out_val2 = f (in_ptr[2] & 0x7f);
|
|
char out_val3 = f (in_ptr[3] & 0x7f);
|
|
|
|
out_ptr[0] = ((out_val0 << 2) & 0xfc) | ((out_val1 >> 4) & 0x03);
|
|
out_ptr[1] = ((out_val1 << 4) & 0xf0) | ((out_val2 >> 2) & 0x0f);
|
|
out_ptr[2] = ((out_val2 << 6) & 0xc0) | ((out_val3 >> 0) & 0x3f);
|
|
|
|
in_ptr += 4;
|
|
out_ptr += 3;
|
|
}
|
|
|
|
for (int i = 0; i < in_len; i++)
|
|
{
|
|
if (in_buf[i] != '=') continue;
|
|
|
|
in_len = i;
|
|
}
|
|
|
|
int out_len = (in_len * 6) / 8;
|
|
|
|
return out_len;
|
|
}
|
|
|
|
int base64_encode (char (*f) (const char), char *in_buf, int in_len, char *out_buf)
|
|
{
|
|
char *in_ptr = in_buf;
|
|
|
|
char *out_ptr = out_buf;
|
|
|
|
for (int i = 0; i < in_len; i += 3)
|
|
{
|
|
char out_val0 = f ( ((in_ptr[0] >> 2) & 0x3f));
|
|
char out_val1 = f (((in_ptr[0] << 4) & 0x30) | ((in_ptr[1] >> 4) & 0x0f));
|
|
char out_val2 = f (((in_ptr[1] << 2) & 0x3c) | ((in_ptr[2] >> 6) & 0x03));
|
|
char out_val3 = f ( ((in_ptr[2] >> 0) & 0x3f));
|
|
|
|
out_ptr[0] = out_val0 & 0x7f;
|
|
out_ptr[1] = out_val1 & 0x7f;
|
|
out_ptr[2] = out_val2 & 0x7f;
|
|
out_ptr[3] = out_val3 & 0x7f;
|
|
|
|
in_ptr += 3;
|
|
out_ptr += 4;
|
|
}
|
|
|
|
int out_len = (in_len * 8) / 6;
|
|
|
|
for (int i = 0; i < (3 - (in_len % 3)); i++)
|
|
{
|
|
out_len++;
|
|
|
|
out_buf[out_len] = '=';
|
|
}
|
|
|
|
return out_len;
|
|
}
|
|
|
|
static void AES128_decrypt_cbc (const uint key[4], const uint iv[4], const uint in[16], uint out[16])
|
|
{
|
|
AES_KEY skey;
|
|
|
|
AES_set_decrypt_key ((unsigned char *) key, 128, &skey);
|
|
|
|
uint _iv[4];
|
|
|
|
_iv[0] = iv[0];
|
|
_iv[1] = iv[1];
|
|
_iv[2] = iv[2];
|
|
_iv[3] = iv[3];
|
|
|
|
for (int i = 0; i < 16; i += 4)
|
|
{
|
|
uint _in[4];
|
|
uint _out[4];
|
|
|
|
_in[0] = in[i + 0];
|
|
_in[1] = in[i + 1];
|
|
_in[2] = in[i + 2];
|
|
_in[3] = in[i + 3];
|
|
|
|
AES_decrypt (&skey, (char *) _in, (char *) _out);
|
|
|
|
_out[0] ^= _iv[0];
|
|
_out[1] ^= _iv[1];
|
|
_out[2] ^= _iv[2];
|
|
_out[3] ^= _iv[3];
|
|
|
|
out[i + 0] = _out[0];
|
|
out[i + 1] = _out[1];
|
|
out[i + 2] = _out[2];
|
|
out[i + 3] = _out[3];
|
|
|
|
_iv[0] = _in[0];
|
|
_iv[1] = _in[1];
|
|
_iv[2] = _in[2];
|
|
_iv[3] = _in[3];
|
|
}
|
|
}
|
|
|
|
static void juniper_decrypt_hash (char *in, char *out)
|
|
{
|
|
// base64 decode
|
|
|
|
char base64_buf[100];
|
|
|
|
memset (base64_buf, 0, sizeof (base64_buf));
|
|
|
|
base64_decode (base64_to_int, in, DISPLAY_LEN_MIN_501, base64_buf);
|
|
|
|
// iv stuff
|
|
|
|
uint juniper_iv[4] = { 0 };
|
|
|
|
memcpy (juniper_iv, base64_buf, 12);
|
|
|
|
memcpy (out, juniper_iv, 12);
|
|
|
|
// reversed key
|
|
|
|
uint juniper_key[4];
|
|
|
|
juniper_key[0] = byte_swap_32 (0xa6707a7e);
|
|
juniper_key[1] = byte_swap_32 (0x8df91059);
|
|
juniper_key[2] = byte_swap_32 (0xdea70ae5);
|
|
juniper_key[3] = byte_swap_32 (0x2f9c2442);
|
|
|
|
// AES decrypt
|
|
|
|
uint *in_ptr = (uint *) (base64_buf + 12);
|
|
uint *out_ptr = (uint *) (out + 12);
|
|
|
|
AES128_decrypt_cbc (juniper_key, juniper_iv, in_ptr, out_ptr);
|
|
}
|
|
|
|
uint is_valid_hex_char (const char c)
|
|
{
|
|
if ((c >= '0') && (c <= '9')) return 1;
|
|
if ((c >= 'A') && (c <= 'F')) return 1;
|
|
if ((c >= 'a') && (c <= 'f')) return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
char hex_convert (const char c)
|
|
{
|
|
return (c & 15) + (c >> 6) * 9;
|
|
}
|
|
|
|
char hex_to_char (const char hex[2])
|
|
{
|
|
char v = 0;
|
|
|
|
v |= (hex_convert (hex[1]) << 0);
|
|
v |= (hex_convert (hex[0]) << 4);
|
|
|
|
return (v);
|
|
}
|
|
|
|
uint hex_to_uint (const char hex[8])
|
|
{
|
|
uint v = 0;
|
|
|
|
v |= hex_convert (hex[7]) << 0;
|
|
v |= hex_convert (hex[6]) << 4;
|
|
v |= hex_convert (hex[5]) << 8;
|
|
v |= hex_convert (hex[4]) << 12;
|
|
v |= hex_convert (hex[3]) << 16;
|
|
v |= hex_convert (hex[2]) << 20;
|
|
v |= hex_convert (hex[1]) << 24;
|
|
v |= hex_convert (hex[0]) << 28;
|
|
|
|
return (v);
|
|
}
|
|
|
|
uint64_t hex_to_uint64_t (const char hex[16])
|
|
{
|
|
uint64_t v = 0;
|
|
|
|
v |= ((uint64_t) hex_convert (hex[15]) << 0);
|
|
v |= ((uint64_t) hex_convert (hex[14]) << 4);
|
|
v |= ((uint64_t) hex_convert (hex[13]) << 8);
|
|
v |= ((uint64_t) hex_convert (hex[12]) << 12);
|
|
v |= ((uint64_t) hex_convert (hex[11]) << 16);
|
|
v |= ((uint64_t) hex_convert (hex[10]) << 20);
|
|
v |= ((uint64_t) hex_convert (hex[ 9]) << 24);
|
|
v |= ((uint64_t) hex_convert (hex[ 8]) << 28);
|
|
v |= ((uint64_t) hex_convert (hex[ 7]) << 32);
|
|
v |= ((uint64_t) hex_convert (hex[ 6]) << 36);
|
|
v |= ((uint64_t) hex_convert (hex[ 5]) << 40);
|
|
v |= ((uint64_t) hex_convert (hex[ 4]) << 44);
|
|
v |= ((uint64_t) hex_convert (hex[ 3]) << 48);
|
|
v |= ((uint64_t) hex_convert (hex[ 2]) << 52);
|
|
v |= ((uint64_t) hex_convert (hex[ 1]) << 56);
|
|
v |= ((uint64_t) hex_convert (hex[ 0]) << 60);
|
|
|
|
return (v);
|
|
}
|
|
|
|
void bin_to_hex_lower (uint v, char hex[8])
|
|
{
|
|
hex[0] = v >> 28 & 15;
|
|
hex[1] = v >> 24 & 15;
|
|
hex[2] = v >> 20 & 15;
|
|
hex[3] = v >> 16 & 15;
|
|
hex[4] = v >> 12 & 15;
|
|
hex[5] = v >> 8 & 15;
|
|
hex[6] = v >> 4 & 15;
|
|
hex[7] = v >> 0 & 15;
|
|
|
|
uint add;
|
|
|
|
hex[0] += 6; add = ((hex[0] & 0x10) >> 4) * 39; hex[0] += 42 + add;
|
|
hex[1] += 6; add = ((hex[1] & 0x10) >> 4) * 39; hex[1] += 42 + add;
|
|
hex[2] += 6; add = ((hex[2] & 0x10) >> 4) * 39; hex[2] += 42 + add;
|
|
hex[3] += 6; add = ((hex[3] & 0x10) >> 4) * 39; hex[3] += 42 + add;
|
|
hex[4] += 6; add = ((hex[4] & 0x10) >> 4) * 39; hex[4] += 42 + add;
|
|
hex[5] += 6; add = ((hex[5] & 0x10) >> 4) * 39; hex[5] += 42 + add;
|
|
hex[6] += 6; add = ((hex[6] & 0x10) >> 4) * 39; hex[6] += 42 + add;
|
|
hex[7] += 6; add = ((hex[7] & 0x10) >> 4) * 39; hex[7] += 42 + add;
|
|
}
|
|
|
|
void phpass_decode (unsigned char digest[16], unsigned char buf[22])
|
|
{
|
|
int l;
|
|
|
|
l = itoa64_to_int (buf[ 0]) << 0;
|
|
l |= itoa64_to_int (buf[ 1]) << 6;
|
|
l |= itoa64_to_int (buf[ 2]) << 12;
|
|
l |= itoa64_to_int (buf[ 3]) << 18;
|
|
|
|
digest[ 0] = (l >> 0) & 0xff;
|
|
digest[ 1] = (l >> 8) & 0xff;
|
|
digest[ 2] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 4]) << 0;
|
|
l |= itoa64_to_int (buf[ 5]) << 6;
|
|
l |= itoa64_to_int (buf[ 6]) << 12;
|
|
l |= itoa64_to_int (buf[ 7]) << 18;
|
|
|
|
digest[ 3] = (l >> 0) & 0xff;
|
|
digest[ 4] = (l >> 8) & 0xff;
|
|
digest[ 5] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 8]) << 0;
|
|
l |= itoa64_to_int (buf[ 9]) << 6;
|
|
l |= itoa64_to_int (buf[10]) << 12;
|
|
l |= itoa64_to_int (buf[11]) << 18;
|
|
|
|
digest[ 6] = (l >> 0) & 0xff;
|
|
digest[ 7] = (l >> 8) & 0xff;
|
|
digest[ 8] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[12]) << 0;
|
|
l |= itoa64_to_int (buf[13]) << 6;
|
|
l |= itoa64_to_int (buf[14]) << 12;
|
|
l |= itoa64_to_int (buf[15]) << 18;
|
|
|
|
digest[ 9] = (l >> 0) & 0xff;
|
|
digest[10] = (l >> 8) & 0xff;
|
|
digest[11] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[16]) << 0;
|
|
l |= itoa64_to_int (buf[17]) << 6;
|
|
l |= itoa64_to_int (buf[18]) << 12;
|
|
l |= itoa64_to_int (buf[19]) << 18;
|
|
|
|
digest[12] = (l >> 0) & 0xff;
|
|
digest[13] = (l >> 8) & 0xff;
|
|
digest[14] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[20]) << 0;
|
|
l |= itoa64_to_int (buf[21]) << 6;
|
|
|
|
digest[15] = (l >> 0) & 0xff;
|
|
}
|
|
|
|
void phpass_encode (unsigned char digest[16], unsigned char buf[22])
|
|
{
|
|
int l;
|
|
|
|
l = (digest[ 0] << 0) | (digest[ 1] << 8) | (digest[ 2] << 16);
|
|
|
|
buf[ 0] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 1] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 2] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 3] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 3] << 0) | (digest[ 4] << 8) | (digest[ 5] << 16);
|
|
|
|
buf[ 4] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 5] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 6] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 7] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 6] << 0) | (digest[ 7] << 8) | (digest[ 8] << 16);
|
|
|
|
buf[ 8] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 9] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[10] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[11] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 9] << 0) | (digest[10] << 8) | (digest[11] << 16);
|
|
|
|
buf[12] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[13] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[14] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[15] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[12] << 0) | (digest[13] << 8) | (digest[14] << 16);
|
|
|
|
buf[16] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[17] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[18] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[19] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[15] << 0);
|
|
|
|
buf[20] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[21] = int_to_itoa64 (l & 0x3f);
|
|
}
|
|
|
|
void md5crypt_decode (unsigned char digest[16], unsigned char buf[22])
|
|
{
|
|
int l;
|
|
|
|
l = itoa64_to_int (buf[ 0]) << 0;
|
|
l |= itoa64_to_int (buf[ 1]) << 6;
|
|
l |= itoa64_to_int (buf[ 2]) << 12;
|
|
l |= itoa64_to_int (buf[ 3]) << 18;
|
|
|
|
digest[ 0] = (l >> 16) & 0xff;
|
|
digest[ 6] = (l >> 8) & 0xff;
|
|
digest[12] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 4]) << 0;
|
|
l |= itoa64_to_int (buf[ 5]) << 6;
|
|
l |= itoa64_to_int (buf[ 6]) << 12;
|
|
l |= itoa64_to_int (buf[ 7]) << 18;
|
|
|
|
digest[ 1] = (l >> 16) & 0xff;
|
|
digest[ 7] = (l >> 8) & 0xff;
|
|
digest[13] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 8]) << 0;
|
|
l |= itoa64_to_int (buf[ 9]) << 6;
|
|
l |= itoa64_to_int (buf[10]) << 12;
|
|
l |= itoa64_to_int (buf[11]) << 18;
|
|
|
|
digest[ 2] = (l >> 16) & 0xff;
|
|
digest[ 8] = (l >> 8) & 0xff;
|
|
digest[14] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[12]) << 0;
|
|
l |= itoa64_to_int (buf[13]) << 6;
|
|
l |= itoa64_to_int (buf[14]) << 12;
|
|
l |= itoa64_to_int (buf[15]) << 18;
|
|
|
|
digest[ 3] = (l >> 16) & 0xff;
|
|
digest[ 9] = (l >> 8) & 0xff;
|
|
digest[15] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[16]) << 0;
|
|
l |= itoa64_to_int (buf[17]) << 6;
|
|
l |= itoa64_to_int (buf[18]) << 12;
|
|
l |= itoa64_to_int (buf[19]) << 18;
|
|
|
|
digest[ 4] = (l >> 16) & 0xff;
|
|
digest[10] = (l >> 8) & 0xff;
|
|
digest[ 5] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[20]) << 0;
|
|
l |= itoa64_to_int (buf[21]) << 6;
|
|
|
|
digest[11] = (l >> 0) & 0xff;
|
|
}
|
|
|
|
void md5crypt_encode (unsigned char digest[16], unsigned char buf[22])
|
|
{
|
|
int l;
|
|
|
|
l = (digest[ 0] << 16) | (digest[ 6] << 8) | (digest[12] << 0);
|
|
|
|
buf[ 0] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 1] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 2] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 3] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 1] << 16) | (digest[ 7] << 8) | (digest[13] << 0);
|
|
|
|
buf[ 4] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 5] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 6] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 7] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 2] << 16) | (digest[ 8] << 8) | (digest[14] << 0);
|
|
|
|
buf[ 8] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 9] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[10] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[11] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 3] << 16) | (digest[ 9] << 8) | (digest[15] << 0);
|
|
|
|
buf[12] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[13] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[14] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[15] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 4] << 16) | (digest[10] << 8) | (digest[ 5] << 0);
|
|
|
|
buf[16] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[17] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[18] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[19] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[11] << 0);
|
|
|
|
buf[20] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[21] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
}
|
|
|
|
void sha512crypt_decode (unsigned char digest[64], unsigned char buf[86])
|
|
{
|
|
int l;
|
|
|
|
l = itoa64_to_int (buf[ 0]) << 0;
|
|
l |= itoa64_to_int (buf[ 1]) << 6;
|
|
l |= itoa64_to_int (buf[ 2]) << 12;
|
|
l |= itoa64_to_int (buf[ 3]) << 18;
|
|
|
|
digest[ 0] = (l >> 16) & 0xff;
|
|
digest[21] = (l >> 8) & 0xff;
|
|
digest[42] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 4]) << 0;
|
|
l |= itoa64_to_int (buf[ 5]) << 6;
|
|
l |= itoa64_to_int (buf[ 6]) << 12;
|
|
l |= itoa64_to_int (buf[ 7]) << 18;
|
|
|
|
digest[22] = (l >> 16) & 0xff;
|
|
digest[43] = (l >> 8) & 0xff;
|
|
digest[ 1] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 8]) << 0;
|
|
l |= itoa64_to_int (buf[ 9]) << 6;
|
|
l |= itoa64_to_int (buf[10]) << 12;
|
|
l |= itoa64_to_int (buf[11]) << 18;
|
|
|
|
digest[44] = (l >> 16) & 0xff;
|
|
digest[ 2] = (l >> 8) & 0xff;
|
|
digest[23] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[12]) << 0;
|
|
l |= itoa64_to_int (buf[13]) << 6;
|
|
l |= itoa64_to_int (buf[14]) << 12;
|
|
l |= itoa64_to_int (buf[15]) << 18;
|
|
|
|
digest[ 3] = (l >> 16) & 0xff;
|
|
digest[24] = (l >> 8) & 0xff;
|
|
digest[45] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[16]) << 0;
|
|
l |= itoa64_to_int (buf[17]) << 6;
|
|
l |= itoa64_to_int (buf[18]) << 12;
|
|
l |= itoa64_to_int (buf[19]) << 18;
|
|
|
|
digest[25] = (l >> 16) & 0xff;
|
|
digest[46] = (l >> 8) & 0xff;
|
|
digest[ 4] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[20]) << 0;
|
|
l |= itoa64_to_int (buf[21]) << 6;
|
|
l |= itoa64_to_int (buf[22]) << 12;
|
|
l |= itoa64_to_int (buf[23]) << 18;
|
|
|
|
digest[47] = (l >> 16) & 0xff;
|
|
digest[ 5] = (l >> 8) & 0xff;
|
|
digest[26] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[24]) << 0;
|
|
l |= itoa64_to_int (buf[25]) << 6;
|
|
l |= itoa64_to_int (buf[26]) << 12;
|
|
l |= itoa64_to_int (buf[27]) << 18;
|
|
|
|
digest[ 6] = (l >> 16) & 0xff;
|
|
digest[27] = (l >> 8) & 0xff;
|
|
digest[48] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[28]) << 0;
|
|
l |= itoa64_to_int (buf[29]) << 6;
|
|
l |= itoa64_to_int (buf[30]) << 12;
|
|
l |= itoa64_to_int (buf[31]) << 18;
|
|
|
|
digest[28] = (l >> 16) & 0xff;
|
|
digest[49] = (l >> 8) & 0xff;
|
|
digest[ 7] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[32]) << 0;
|
|
l |= itoa64_to_int (buf[33]) << 6;
|
|
l |= itoa64_to_int (buf[34]) << 12;
|
|
l |= itoa64_to_int (buf[35]) << 18;
|
|
|
|
digest[50] = (l >> 16) & 0xff;
|
|
digest[ 8] = (l >> 8) & 0xff;
|
|
digest[29] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[36]) << 0;
|
|
l |= itoa64_to_int (buf[37]) << 6;
|
|
l |= itoa64_to_int (buf[38]) << 12;
|
|
l |= itoa64_to_int (buf[39]) << 18;
|
|
|
|
digest[ 9] = (l >> 16) & 0xff;
|
|
digest[30] = (l >> 8) & 0xff;
|
|
digest[51] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[40]) << 0;
|
|
l |= itoa64_to_int (buf[41]) << 6;
|
|
l |= itoa64_to_int (buf[42]) << 12;
|
|
l |= itoa64_to_int (buf[43]) << 18;
|
|
|
|
digest[31] = (l >> 16) & 0xff;
|
|
digest[52] = (l >> 8) & 0xff;
|
|
digest[10] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[44]) << 0;
|
|
l |= itoa64_to_int (buf[45]) << 6;
|
|
l |= itoa64_to_int (buf[46]) << 12;
|
|
l |= itoa64_to_int (buf[47]) << 18;
|
|
|
|
digest[53] = (l >> 16) & 0xff;
|
|
digest[11] = (l >> 8) & 0xff;
|
|
digest[32] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[48]) << 0;
|
|
l |= itoa64_to_int (buf[49]) << 6;
|
|
l |= itoa64_to_int (buf[50]) << 12;
|
|
l |= itoa64_to_int (buf[51]) << 18;
|
|
|
|
digest[12] = (l >> 16) & 0xff;
|
|
digest[33] = (l >> 8) & 0xff;
|
|
digest[54] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[52]) << 0;
|
|
l |= itoa64_to_int (buf[53]) << 6;
|
|
l |= itoa64_to_int (buf[54]) << 12;
|
|
l |= itoa64_to_int (buf[55]) << 18;
|
|
|
|
digest[34] = (l >> 16) & 0xff;
|
|
digest[55] = (l >> 8) & 0xff;
|
|
digest[13] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[56]) << 0;
|
|
l |= itoa64_to_int (buf[57]) << 6;
|
|
l |= itoa64_to_int (buf[58]) << 12;
|
|
l |= itoa64_to_int (buf[59]) << 18;
|
|
|
|
digest[56] = (l >> 16) & 0xff;
|
|
digest[14] = (l >> 8) & 0xff;
|
|
digest[35] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[60]) << 0;
|
|
l |= itoa64_to_int (buf[61]) << 6;
|
|
l |= itoa64_to_int (buf[62]) << 12;
|
|
l |= itoa64_to_int (buf[63]) << 18;
|
|
|
|
digest[15] = (l >> 16) & 0xff;
|
|
digest[36] = (l >> 8) & 0xff;
|
|
digest[57] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[64]) << 0;
|
|
l |= itoa64_to_int (buf[65]) << 6;
|
|
l |= itoa64_to_int (buf[66]) << 12;
|
|
l |= itoa64_to_int (buf[67]) << 18;
|
|
|
|
digest[37] = (l >> 16) & 0xff;
|
|
digest[58] = (l >> 8) & 0xff;
|
|
digest[16] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[68]) << 0;
|
|
l |= itoa64_to_int (buf[69]) << 6;
|
|
l |= itoa64_to_int (buf[70]) << 12;
|
|
l |= itoa64_to_int (buf[71]) << 18;
|
|
|
|
digest[59] = (l >> 16) & 0xff;
|
|
digest[17] = (l >> 8) & 0xff;
|
|
digest[38] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[72]) << 0;
|
|
l |= itoa64_to_int (buf[73]) << 6;
|
|
l |= itoa64_to_int (buf[74]) << 12;
|
|
l |= itoa64_to_int (buf[75]) << 18;
|
|
|
|
digest[18] = (l >> 16) & 0xff;
|
|
digest[39] = (l >> 8) & 0xff;
|
|
digest[60] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[76]) << 0;
|
|
l |= itoa64_to_int (buf[77]) << 6;
|
|
l |= itoa64_to_int (buf[78]) << 12;
|
|
l |= itoa64_to_int (buf[79]) << 18;
|
|
|
|
digest[40] = (l >> 16) & 0xff;
|
|
digest[61] = (l >> 8) & 0xff;
|
|
digest[19] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[80]) << 0;
|
|
l |= itoa64_to_int (buf[81]) << 6;
|
|
l |= itoa64_to_int (buf[82]) << 12;
|
|
l |= itoa64_to_int (buf[83]) << 18;
|
|
|
|
digest[62] = (l >> 16) & 0xff;
|
|
digest[20] = (l >> 8) & 0xff;
|
|
digest[41] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[84]) << 0;
|
|
l |= itoa64_to_int (buf[85]) << 6;
|
|
|
|
digest[63] = (l >> 0) & 0xff;
|
|
}
|
|
|
|
void sha512crypt_encode (unsigned char digest[64], unsigned char buf[86])
|
|
{
|
|
int l;
|
|
|
|
l = (digest[ 0] << 16) | (digest[21] << 8) | (digest[42] << 0);
|
|
|
|
buf[ 0] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 1] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 2] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 3] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[22] << 16) | (digest[43] << 8) | (digest[ 1] << 0);
|
|
|
|
buf[ 4] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 5] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 6] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 7] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[44] << 16) | (digest[ 2] << 8) | (digest[23] << 0);
|
|
|
|
buf[ 8] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 9] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[10] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[11] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 3] << 16) | (digest[24] << 8) | (digest[45] << 0);
|
|
|
|
buf[12] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[13] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[14] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[15] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[25] << 16) | (digest[46] << 8) | (digest[ 4] << 0);
|
|
|
|
buf[16] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[17] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[18] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[19] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[47] << 16) | (digest[ 5] << 8) | (digest[26] << 0);
|
|
|
|
buf[20] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[21] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[22] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[23] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 6] << 16) | (digest[27] << 8) | (digest[48] << 0);
|
|
|
|
buf[24] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[25] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[26] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[27] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[28] << 16) | (digest[49] << 8) | (digest[ 7] << 0);
|
|
|
|
buf[28] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[29] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[30] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[31] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[50] << 16) | (digest[ 8] << 8) | (digest[29] << 0);
|
|
|
|
buf[32] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[33] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[34] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[35] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 9] << 16) | (digest[30] << 8) | (digest[51] << 0);
|
|
|
|
buf[36] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[37] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[38] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[39] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[31] << 16) | (digest[52] << 8) | (digest[10] << 0);
|
|
|
|
buf[40] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[41] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[42] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[43] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[53] << 16) | (digest[11] << 8) | (digest[32] << 0);
|
|
|
|
buf[44] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[45] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[46] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[47] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[12] << 16) | (digest[33] << 8) | (digest[54] << 0);
|
|
|
|
buf[48] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[49] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[50] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[51] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[34] << 16) | (digest[55] << 8) | (digest[13] << 0);
|
|
|
|
buf[52] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[53] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[54] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[55] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[56] << 16) | (digest[14] << 8) | (digest[35] << 0);
|
|
|
|
buf[56] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[57] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[58] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[59] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[15] << 16) | (digest[36] << 8) | (digest[57] << 0);
|
|
|
|
buf[60] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[61] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[62] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[63] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[37] << 16) | (digest[58] << 8) | (digest[16] << 0);
|
|
|
|
buf[64] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[65] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[66] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[67] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[59] << 16) | (digest[17] << 8) | (digest[38] << 0);
|
|
|
|
buf[68] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[69] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[70] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[71] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[18] << 16) | (digest[39] << 8) | (digest[60] << 0);
|
|
|
|
buf[72] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[73] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[74] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[75] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[40] << 16) | (digest[61] << 8) | (digest[19] << 0);
|
|
|
|
buf[76] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[77] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[78] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[79] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[62] << 16) | (digest[20] << 8) | (digest[41] << 0);
|
|
|
|
buf[80] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[81] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[82] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[83] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = 0 | 0 | (digest[63] << 0);
|
|
|
|
buf[84] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[85] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
}
|
|
|
|
void sha1aix_decode (unsigned char digest[20], unsigned char buf[27])
|
|
{
|
|
int l;
|
|
|
|
l = itoa64_to_int (buf[ 0]) << 0;
|
|
l |= itoa64_to_int (buf[ 1]) << 6;
|
|
l |= itoa64_to_int (buf[ 2]) << 12;
|
|
l |= itoa64_to_int (buf[ 3]) << 18;
|
|
|
|
digest[ 2] = (l >> 0) & 0xff;
|
|
digest[ 1] = (l >> 8) & 0xff;
|
|
digest[ 0] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 4]) << 0;
|
|
l |= itoa64_to_int (buf[ 5]) << 6;
|
|
l |= itoa64_to_int (buf[ 6]) << 12;
|
|
l |= itoa64_to_int (buf[ 7]) << 18;
|
|
|
|
digest[ 5] = (l >> 0) & 0xff;
|
|
digest[ 4] = (l >> 8) & 0xff;
|
|
digest[ 3] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 8]) << 0;
|
|
l |= itoa64_to_int (buf[ 9]) << 6;
|
|
l |= itoa64_to_int (buf[10]) << 12;
|
|
l |= itoa64_to_int (buf[11]) << 18;
|
|
|
|
digest[ 8] = (l >> 0) & 0xff;
|
|
digest[ 7] = (l >> 8) & 0xff;
|
|
digest[ 6] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[12]) << 0;
|
|
l |= itoa64_to_int (buf[13]) << 6;
|
|
l |= itoa64_to_int (buf[14]) << 12;
|
|
l |= itoa64_to_int (buf[15]) << 18;
|
|
|
|
digest[11] = (l >> 0) & 0xff;
|
|
digest[10] = (l >> 8) & 0xff;
|
|
digest[ 9] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[16]) << 0;
|
|
l |= itoa64_to_int (buf[17]) << 6;
|
|
l |= itoa64_to_int (buf[18]) << 12;
|
|
l |= itoa64_to_int (buf[19]) << 18;
|
|
|
|
digest[14] = (l >> 0) & 0xff;
|
|
digest[13] = (l >> 8) & 0xff;
|
|
digest[12] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[20]) << 0;
|
|
l |= itoa64_to_int (buf[21]) << 6;
|
|
l |= itoa64_to_int (buf[22]) << 12;
|
|
l |= itoa64_to_int (buf[23]) << 18;
|
|
|
|
digest[17] = (l >> 0) & 0xff;
|
|
digest[16] = (l >> 8) & 0xff;
|
|
digest[15] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[24]) << 0;
|
|
l |= itoa64_to_int (buf[25]) << 6;
|
|
l |= itoa64_to_int (buf[26]) << 12;
|
|
|
|
digest[19] = (l >> 8) & 0xff;
|
|
digest[18] = (l >> 16) & 0xff;
|
|
}
|
|
|
|
void sha1aix_encode (unsigned char digest[20], unsigned char buf[27])
|
|
{
|
|
int l;
|
|
|
|
l = (digest[ 2] << 0) | (digest[ 1] << 8) | (digest[ 0] << 16);
|
|
|
|
buf[ 0] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 1] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 2] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 3] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 5] << 0) | (digest[ 4] << 8) | (digest[ 3] << 16);
|
|
|
|
buf[ 4] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 5] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 6] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 7] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 8] << 0) | (digest[ 7] << 8) | (digest[ 6] << 16);
|
|
|
|
buf[ 8] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 9] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[10] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[11] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[11] << 0) | (digest[10] << 8) | (digest[ 9] << 16);
|
|
|
|
buf[12] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[13] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[14] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[15] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[14] << 0) | (digest[13] << 8) | (digest[12] << 16);
|
|
|
|
buf[16] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[17] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[18] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[19] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[17] << 0) | (digest[16] << 8) | (digest[15] << 16);
|
|
|
|
buf[20] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[21] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[22] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[23] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = 0 | (digest[19] << 8) | (digest[18] << 16);
|
|
|
|
buf[24] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[25] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[26] = int_to_itoa64 (l & 0x3f);
|
|
}
|
|
|
|
void sha256aix_decode (unsigned char digest[32], unsigned char buf[43])
|
|
{
|
|
int l;
|
|
|
|
l = itoa64_to_int (buf[ 0]) << 0;
|
|
l |= itoa64_to_int (buf[ 1]) << 6;
|
|
l |= itoa64_to_int (buf[ 2]) << 12;
|
|
l |= itoa64_to_int (buf[ 3]) << 18;
|
|
|
|
digest[ 2] = (l >> 0) & 0xff;
|
|
digest[ 1] = (l >> 8) & 0xff;
|
|
digest[ 0] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 4]) << 0;
|
|
l |= itoa64_to_int (buf[ 5]) << 6;
|
|
l |= itoa64_to_int (buf[ 6]) << 12;
|
|
l |= itoa64_to_int (buf[ 7]) << 18;
|
|
|
|
digest[ 5] = (l >> 0) & 0xff;
|
|
digest[ 4] = (l >> 8) & 0xff;
|
|
digest[ 3] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 8]) << 0;
|
|
l |= itoa64_to_int (buf[ 9]) << 6;
|
|
l |= itoa64_to_int (buf[10]) << 12;
|
|
l |= itoa64_to_int (buf[11]) << 18;
|
|
|
|
digest[ 8] = (l >> 0) & 0xff;
|
|
digest[ 7] = (l >> 8) & 0xff;
|
|
digest[ 6] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[12]) << 0;
|
|
l |= itoa64_to_int (buf[13]) << 6;
|
|
l |= itoa64_to_int (buf[14]) << 12;
|
|
l |= itoa64_to_int (buf[15]) << 18;
|
|
|
|
digest[11] = (l >> 0) & 0xff;
|
|
digest[10] = (l >> 8) & 0xff;
|
|
digest[ 9] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[16]) << 0;
|
|
l |= itoa64_to_int (buf[17]) << 6;
|
|
l |= itoa64_to_int (buf[18]) << 12;
|
|
l |= itoa64_to_int (buf[19]) << 18;
|
|
|
|
digest[14] = (l >> 0) & 0xff;
|
|
digest[13] = (l >> 8) & 0xff;
|
|
digest[12] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[20]) << 0;
|
|
l |= itoa64_to_int (buf[21]) << 6;
|
|
l |= itoa64_to_int (buf[22]) << 12;
|
|
l |= itoa64_to_int (buf[23]) << 18;
|
|
|
|
digest[17] = (l >> 0) & 0xff;
|
|
digest[16] = (l >> 8) & 0xff;
|
|
digest[15] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[24]) << 0;
|
|
l |= itoa64_to_int (buf[25]) << 6;
|
|
l |= itoa64_to_int (buf[26]) << 12;
|
|
l |= itoa64_to_int (buf[27]) << 18;
|
|
|
|
digest[20] = (l >> 0) & 0xff;
|
|
digest[19] = (l >> 8) & 0xff;
|
|
digest[18] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[28]) << 0;
|
|
l |= itoa64_to_int (buf[29]) << 6;
|
|
l |= itoa64_to_int (buf[30]) << 12;
|
|
l |= itoa64_to_int (buf[31]) << 18;
|
|
|
|
digest[23] = (l >> 0) & 0xff;
|
|
digest[22] = (l >> 8) & 0xff;
|
|
digest[21] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[32]) << 0;
|
|
l |= itoa64_to_int (buf[33]) << 6;
|
|
l |= itoa64_to_int (buf[34]) << 12;
|
|
l |= itoa64_to_int (buf[35]) << 18;
|
|
|
|
digest[26] = (l >> 0) & 0xff;
|
|
digest[25] = (l >> 8) & 0xff;
|
|
digest[24] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[36]) << 0;
|
|
l |= itoa64_to_int (buf[37]) << 6;
|
|
l |= itoa64_to_int (buf[38]) << 12;
|
|
l |= itoa64_to_int (buf[39]) << 18;
|
|
|
|
digest[29] = (l >> 0) & 0xff;
|
|
digest[28] = (l >> 8) & 0xff;
|
|
digest[27] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[40]) << 0;
|
|
l |= itoa64_to_int (buf[41]) << 6;
|
|
l |= itoa64_to_int (buf[42]) << 12;
|
|
|
|
//digest[32] = (l >> 0) & 0xff;
|
|
digest[31] = (l >> 8) & 0xff;
|
|
digest[30] = (l >> 16) & 0xff;
|
|
}
|
|
|
|
void sha256aix_encode (unsigned char digest[32], unsigned char buf[43])
|
|
{
|
|
int l;
|
|
|
|
l = (digest[ 2] << 0) | (digest[ 1] << 8) | (digest[ 0] << 16);
|
|
|
|
buf[ 0] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 1] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 2] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 3] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 5] << 0) | (digest[ 4] << 8) | (digest[ 3] << 16);
|
|
|
|
buf[ 4] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 5] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 6] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 7] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 8] << 0) | (digest[ 7] << 8) | (digest[ 6] << 16);
|
|
|
|
buf[ 8] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 9] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[10] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[11] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[11] << 0) | (digest[10] << 8) | (digest[ 9] << 16);
|
|
|
|
buf[12] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[13] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[14] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[15] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[14] << 0) | (digest[13] << 8) | (digest[12] << 16);
|
|
|
|
buf[16] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[17] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[18] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[19] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[17] << 0) | (digest[16] << 8) | (digest[15] << 16);
|
|
|
|
buf[20] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[21] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[22] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[23] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[20] << 0) | (digest[19] << 8) | (digest[18] << 16);
|
|
|
|
buf[24] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[25] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[26] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[27] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[23] << 0) | (digest[22] << 8) | (digest[21] << 16);
|
|
|
|
buf[28] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[29] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[30] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[31] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[26] << 0) | (digest[25] << 8) | (digest[24] << 16);
|
|
|
|
buf[32] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[33] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[34] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[35] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[29] << 0) | (digest[28] << 8) | (digest[27] << 16);
|
|
|
|
buf[36] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[37] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[38] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[39] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = 0 | (digest[31] << 8) | (digest[30] << 16);
|
|
|
|
buf[40] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[41] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[42] = int_to_itoa64 (l & 0x3f);
|
|
}
|
|
|
|
void sha512aix_decode (unsigned char digest[64], unsigned char buf[86])
|
|
{
|
|
int l;
|
|
|
|
l = itoa64_to_int (buf[ 0]) << 0;
|
|
l |= itoa64_to_int (buf[ 1]) << 6;
|
|
l |= itoa64_to_int (buf[ 2]) << 12;
|
|
l |= itoa64_to_int (buf[ 3]) << 18;
|
|
|
|
digest[ 2] = (l >> 0) & 0xff;
|
|
digest[ 1] = (l >> 8) & 0xff;
|
|
digest[ 0] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 4]) << 0;
|
|
l |= itoa64_to_int (buf[ 5]) << 6;
|
|
l |= itoa64_to_int (buf[ 6]) << 12;
|
|
l |= itoa64_to_int (buf[ 7]) << 18;
|
|
|
|
digest[ 5] = (l >> 0) & 0xff;
|
|
digest[ 4] = (l >> 8) & 0xff;
|
|
digest[ 3] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 8]) << 0;
|
|
l |= itoa64_to_int (buf[ 9]) << 6;
|
|
l |= itoa64_to_int (buf[10]) << 12;
|
|
l |= itoa64_to_int (buf[11]) << 18;
|
|
|
|
digest[ 8] = (l >> 0) & 0xff;
|
|
digest[ 7] = (l >> 8) & 0xff;
|
|
digest[ 6] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[12]) << 0;
|
|
l |= itoa64_to_int (buf[13]) << 6;
|
|
l |= itoa64_to_int (buf[14]) << 12;
|
|
l |= itoa64_to_int (buf[15]) << 18;
|
|
|
|
digest[11] = (l >> 0) & 0xff;
|
|
digest[10] = (l >> 8) & 0xff;
|
|
digest[ 9] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[16]) << 0;
|
|
l |= itoa64_to_int (buf[17]) << 6;
|
|
l |= itoa64_to_int (buf[18]) << 12;
|
|
l |= itoa64_to_int (buf[19]) << 18;
|
|
|
|
digest[14] = (l >> 0) & 0xff;
|
|
digest[13] = (l >> 8) & 0xff;
|
|
digest[12] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[20]) << 0;
|
|
l |= itoa64_to_int (buf[21]) << 6;
|
|
l |= itoa64_to_int (buf[22]) << 12;
|
|
l |= itoa64_to_int (buf[23]) << 18;
|
|
|
|
digest[17] = (l >> 0) & 0xff;
|
|
digest[16] = (l >> 8) & 0xff;
|
|
digest[15] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[24]) << 0;
|
|
l |= itoa64_to_int (buf[25]) << 6;
|
|
l |= itoa64_to_int (buf[26]) << 12;
|
|
l |= itoa64_to_int (buf[27]) << 18;
|
|
|
|
digest[20] = (l >> 0) & 0xff;
|
|
digest[19] = (l >> 8) & 0xff;
|
|
digest[18] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[28]) << 0;
|
|
l |= itoa64_to_int (buf[29]) << 6;
|
|
l |= itoa64_to_int (buf[30]) << 12;
|
|
l |= itoa64_to_int (buf[31]) << 18;
|
|
|
|
digest[23] = (l >> 0) & 0xff;
|
|
digest[22] = (l >> 8) & 0xff;
|
|
digest[21] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[32]) << 0;
|
|
l |= itoa64_to_int (buf[33]) << 6;
|
|
l |= itoa64_to_int (buf[34]) << 12;
|
|
l |= itoa64_to_int (buf[35]) << 18;
|
|
|
|
digest[26] = (l >> 0) & 0xff;
|
|
digest[25] = (l >> 8) & 0xff;
|
|
digest[24] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[36]) << 0;
|
|
l |= itoa64_to_int (buf[37]) << 6;
|
|
l |= itoa64_to_int (buf[38]) << 12;
|
|
l |= itoa64_to_int (buf[39]) << 18;
|
|
|
|
digest[29] = (l >> 0) & 0xff;
|
|
digest[28] = (l >> 8) & 0xff;
|
|
digest[27] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[40]) << 0;
|
|
l |= itoa64_to_int (buf[41]) << 6;
|
|
l |= itoa64_to_int (buf[42]) << 12;
|
|
l |= itoa64_to_int (buf[43]) << 18;
|
|
|
|
digest[32] = (l >> 0) & 0xff;
|
|
digest[31] = (l >> 8) & 0xff;
|
|
digest[30] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[44]) << 0;
|
|
l |= itoa64_to_int (buf[45]) << 6;
|
|
l |= itoa64_to_int (buf[46]) << 12;
|
|
l |= itoa64_to_int (buf[47]) << 18;
|
|
|
|
digest[35] = (l >> 0) & 0xff;
|
|
digest[34] = (l >> 8) & 0xff;
|
|
digest[33] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[48]) << 0;
|
|
l |= itoa64_to_int (buf[49]) << 6;
|
|
l |= itoa64_to_int (buf[50]) << 12;
|
|
l |= itoa64_to_int (buf[51]) << 18;
|
|
|
|
digest[38] = (l >> 0) & 0xff;
|
|
digest[37] = (l >> 8) & 0xff;
|
|
digest[36] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[52]) << 0;
|
|
l |= itoa64_to_int (buf[53]) << 6;
|
|
l |= itoa64_to_int (buf[54]) << 12;
|
|
l |= itoa64_to_int (buf[55]) << 18;
|
|
|
|
digest[41] = (l >> 0) & 0xff;
|
|
digest[40] = (l >> 8) & 0xff;
|
|
digest[39] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[56]) << 0;
|
|
l |= itoa64_to_int (buf[57]) << 6;
|
|
l |= itoa64_to_int (buf[58]) << 12;
|
|
l |= itoa64_to_int (buf[59]) << 18;
|
|
|
|
digest[44] = (l >> 0) & 0xff;
|
|
digest[43] = (l >> 8) & 0xff;
|
|
digest[42] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[60]) << 0;
|
|
l |= itoa64_to_int (buf[61]) << 6;
|
|
l |= itoa64_to_int (buf[62]) << 12;
|
|
l |= itoa64_to_int (buf[63]) << 18;
|
|
|
|
digest[47] = (l >> 0) & 0xff;
|
|
digest[46] = (l >> 8) & 0xff;
|
|
digest[45] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[64]) << 0;
|
|
l |= itoa64_to_int (buf[65]) << 6;
|
|
l |= itoa64_to_int (buf[66]) << 12;
|
|
l |= itoa64_to_int (buf[67]) << 18;
|
|
|
|
digest[50] = (l >> 0) & 0xff;
|
|
digest[49] = (l >> 8) & 0xff;
|
|
digest[48] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[68]) << 0;
|
|
l |= itoa64_to_int (buf[69]) << 6;
|
|
l |= itoa64_to_int (buf[70]) << 12;
|
|
l |= itoa64_to_int (buf[71]) << 18;
|
|
|
|
digest[53] = (l >> 0) & 0xff;
|
|
digest[52] = (l >> 8) & 0xff;
|
|
digest[51] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[72]) << 0;
|
|
l |= itoa64_to_int (buf[73]) << 6;
|
|
l |= itoa64_to_int (buf[74]) << 12;
|
|
l |= itoa64_to_int (buf[75]) << 18;
|
|
|
|
digest[56] = (l >> 0) & 0xff;
|
|
digest[55] = (l >> 8) & 0xff;
|
|
digest[54] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[76]) << 0;
|
|
l |= itoa64_to_int (buf[77]) << 6;
|
|
l |= itoa64_to_int (buf[78]) << 12;
|
|
l |= itoa64_to_int (buf[79]) << 18;
|
|
|
|
digest[59] = (l >> 0) & 0xff;
|
|
digest[58] = (l >> 8) & 0xff;
|
|
digest[57] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[80]) << 0;
|
|
l |= itoa64_to_int (buf[81]) << 6;
|
|
l |= itoa64_to_int (buf[82]) << 12;
|
|
l |= itoa64_to_int (buf[83]) << 18;
|
|
|
|
digest[62] = (l >> 0) & 0xff;
|
|
digest[61] = (l >> 8) & 0xff;
|
|
digest[60] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[84]) << 0;
|
|
l |= itoa64_to_int (buf[85]) << 6;
|
|
|
|
digest[63] = (l >> 16) & 0xff;
|
|
}
|
|
|
|
void sha512aix_encode (unsigned char digest[64], unsigned char buf[86])
|
|
{
|
|
int l;
|
|
|
|
l = (digest[ 2] << 0) | (digest[ 1] << 8) | (digest[ 0] << 16);
|
|
|
|
buf[ 0] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 1] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 2] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 3] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 5] << 0) | (digest[ 4] << 8) | (digest[ 3] << 16);
|
|
|
|
buf[ 4] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 5] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 6] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 7] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 8] << 0) | (digest[ 7] << 8) | (digest[ 6] << 16);
|
|
|
|
buf[ 8] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 9] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[10] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[11] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[11] << 0) | (digest[10] << 8) | (digest[ 9] << 16);
|
|
|
|
buf[12] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[13] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[14] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[15] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[14] << 0) | (digest[13] << 8) | (digest[12] << 16);
|
|
|
|
buf[16] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[17] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[18] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[19] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[17] << 0) | (digest[16] << 8) | (digest[15] << 16);
|
|
|
|
buf[20] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[21] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[22] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[23] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[20] << 0) | (digest[19] << 8) | (digest[18] << 16);
|
|
|
|
buf[24] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[25] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[26] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[27] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[23] << 0) | (digest[22] << 8) | (digest[21] << 16);
|
|
|
|
buf[28] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[29] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[30] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[31] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[26] << 0) | (digest[25] << 8) | (digest[24] << 16);
|
|
|
|
buf[32] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[33] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[34] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[35] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[29] << 0) | (digest[28] << 8) | (digest[27] << 16);
|
|
|
|
buf[36] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[37] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[38] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[39] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[32] << 0) | (digest[31] << 8) | (digest[30] << 16);
|
|
|
|
buf[40] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[41] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[42] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[43] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[35] << 0) | (digest[34] << 8) | (digest[33] << 16);
|
|
|
|
buf[44] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[45] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[46] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[47] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[38] << 0) | (digest[37] << 8) | (digest[36] << 16);
|
|
|
|
buf[48] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[49] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[50] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[51] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[41] << 0) | (digest[40] << 8) | (digest[39] << 16);
|
|
|
|
buf[52] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[53] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[54] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[55] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[44] << 0) | (digest[43] << 8) | (digest[42] << 16);
|
|
|
|
buf[56] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[57] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[58] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[59] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[47] << 0) | (digest[46] << 8) | (digest[45] << 16);
|
|
|
|
buf[60] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[61] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[62] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[63] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[50] << 0) | (digest[49] << 8) | (digest[48] << 16);
|
|
|
|
buf[64] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[65] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[66] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[67] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[53] << 0) | (digest[52] << 8) | (digest[51] << 16);
|
|
|
|
buf[68] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[69] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[70] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[71] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[56] << 0) | (digest[55] << 8) | (digest[54] << 16);
|
|
|
|
buf[72] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[73] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[74] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[75] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[59] << 0) | (digest[58] << 8) | (digest[57] << 16);
|
|
|
|
buf[76] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[77] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[78] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[79] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[62] << 0) | (digest[61] << 8) | (digest[60] << 16);
|
|
|
|
buf[80] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[81] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[82] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[83] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = 0 | 0 | (digest[63] << 16);
|
|
|
|
buf[84] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[85] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
}
|
|
|
|
void sha256crypt_decode (unsigned char digest[32], unsigned char buf[43])
|
|
{
|
|
int l;
|
|
|
|
l = itoa64_to_int (buf[ 0]) << 0;
|
|
l |= itoa64_to_int (buf[ 1]) << 6;
|
|
l |= itoa64_to_int (buf[ 2]) << 12;
|
|
l |= itoa64_to_int (buf[ 3]) << 18;
|
|
|
|
digest[ 0] = (l >> 16) & 0xff;
|
|
digest[10] = (l >> 8) & 0xff;
|
|
digest[20] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 4]) << 0;
|
|
l |= itoa64_to_int (buf[ 5]) << 6;
|
|
l |= itoa64_to_int (buf[ 6]) << 12;
|
|
l |= itoa64_to_int (buf[ 7]) << 18;
|
|
|
|
digest[21] = (l >> 16) & 0xff;
|
|
digest[ 1] = (l >> 8) & 0xff;
|
|
digest[11] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 8]) << 0;
|
|
l |= itoa64_to_int (buf[ 9]) << 6;
|
|
l |= itoa64_to_int (buf[10]) << 12;
|
|
l |= itoa64_to_int (buf[11]) << 18;
|
|
|
|
digest[12] = (l >> 16) & 0xff;
|
|
digest[22] = (l >> 8) & 0xff;
|
|
digest[ 2] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[12]) << 0;
|
|
l |= itoa64_to_int (buf[13]) << 6;
|
|
l |= itoa64_to_int (buf[14]) << 12;
|
|
l |= itoa64_to_int (buf[15]) << 18;
|
|
|
|
digest[ 3] = (l >> 16) & 0xff;
|
|
digest[13] = (l >> 8) & 0xff;
|
|
digest[23] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[16]) << 0;
|
|
l |= itoa64_to_int (buf[17]) << 6;
|
|
l |= itoa64_to_int (buf[18]) << 12;
|
|
l |= itoa64_to_int (buf[19]) << 18;
|
|
|
|
digest[24] = (l >> 16) & 0xff;
|
|
digest[ 4] = (l >> 8) & 0xff;
|
|
digest[14] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[20]) << 0;
|
|
l |= itoa64_to_int (buf[21]) << 6;
|
|
l |= itoa64_to_int (buf[22]) << 12;
|
|
l |= itoa64_to_int (buf[23]) << 18;
|
|
|
|
digest[15] = (l >> 16) & 0xff;
|
|
digest[25] = (l >> 8) & 0xff;
|
|
digest[ 5] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[24]) << 0;
|
|
l |= itoa64_to_int (buf[25]) << 6;
|
|
l |= itoa64_to_int (buf[26]) << 12;
|
|
l |= itoa64_to_int (buf[27]) << 18;
|
|
|
|
digest[ 6] = (l >> 16) & 0xff;
|
|
digest[16] = (l >> 8) & 0xff;
|
|
digest[26] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[28]) << 0;
|
|
l |= itoa64_to_int (buf[29]) << 6;
|
|
l |= itoa64_to_int (buf[30]) << 12;
|
|
l |= itoa64_to_int (buf[31]) << 18;
|
|
|
|
digest[27] = (l >> 16) & 0xff;
|
|
digest[ 7] = (l >> 8) & 0xff;
|
|
digest[17] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[32]) << 0;
|
|
l |= itoa64_to_int (buf[33]) << 6;
|
|
l |= itoa64_to_int (buf[34]) << 12;
|
|
l |= itoa64_to_int (buf[35]) << 18;
|
|
|
|
digest[18] = (l >> 16) & 0xff;
|
|
digest[28] = (l >> 8) & 0xff;
|
|
digest[ 8] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[36]) << 0;
|
|
l |= itoa64_to_int (buf[37]) << 6;
|
|
l |= itoa64_to_int (buf[38]) << 12;
|
|
l |= itoa64_to_int (buf[39]) << 18;
|
|
|
|
digest[ 9] = (l >> 16) & 0xff;
|
|
digest[19] = (l >> 8) & 0xff;
|
|
digest[29] = (l >> 0) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[40]) << 0;
|
|
l |= itoa64_to_int (buf[41]) << 6;
|
|
l |= itoa64_to_int (buf[42]) << 12;
|
|
|
|
digest[31] = (l >> 8) & 0xff;
|
|
digest[30] = (l >> 0) & 0xff;
|
|
}
|
|
|
|
void sha256crypt_encode (unsigned char digest[32], unsigned char buf[43])
|
|
{
|
|
int l;
|
|
|
|
l = (digest[ 0] << 16) | (digest[10] << 8) | (digest[20] << 0);
|
|
|
|
buf[ 0] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 1] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 2] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 3] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[21] << 16) | (digest[ 1] << 8) | (digest[11] << 0);
|
|
|
|
buf[ 4] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 5] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 6] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 7] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[12] << 16) | (digest[22] << 8) | (digest[ 2] << 0);
|
|
|
|
buf[ 8] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 9] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[10] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[11] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 3] << 16) | (digest[13] << 8) | (digest[23] << 0);
|
|
|
|
buf[12] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[13] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[14] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[15] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[24] << 16) | (digest[ 4] << 8) | (digest[14] << 0);
|
|
|
|
buf[16] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[17] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[18] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[19] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[15] << 16) | (digest[25] << 8) | (digest[ 5] << 0);
|
|
|
|
buf[20] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[21] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[22] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[23] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 6] << 16) | (digest[16] << 8) | (digest[26] << 0);
|
|
|
|
buf[24] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[25] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[26] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[27] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[27] << 16) | (digest[ 7] << 8) | (digest[17] << 0);
|
|
|
|
buf[28] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[29] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[30] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[31] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[18] << 16) | (digest[28] << 8) | (digest[ 8] << 0);
|
|
|
|
buf[32] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[33] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[34] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[35] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = (digest[ 9] << 16) | (digest[19] << 8) | (digest[29] << 0);
|
|
|
|
buf[36] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[37] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[38] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[39] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
|
|
l = 0 | (digest[31] << 8) | (digest[30] << 0);
|
|
|
|
buf[40] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[41] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[42] = int_to_itoa64 (l & 0x3f);
|
|
}
|
|
|
|
void drupal7_decode (unsigned char digest[64], unsigned char buf[44])
|
|
{
|
|
int l;
|
|
|
|
l = itoa64_to_int (buf[ 0]) << 0;
|
|
l |= itoa64_to_int (buf[ 1]) << 6;
|
|
l |= itoa64_to_int (buf[ 2]) << 12;
|
|
l |= itoa64_to_int (buf[ 3]) << 18;
|
|
|
|
digest[ 0] = (l >> 0) & 0xff;
|
|
digest[ 1] = (l >> 8) & 0xff;
|
|
digest[ 2] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 4]) << 0;
|
|
l |= itoa64_to_int (buf[ 5]) << 6;
|
|
l |= itoa64_to_int (buf[ 6]) << 12;
|
|
l |= itoa64_to_int (buf[ 7]) << 18;
|
|
|
|
digest[ 3] = (l >> 0) & 0xff;
|
|
digest[ 4] = (l >> 8) & 0xff;
|
|
digest[ 5] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[ 8]) << 0;
|
|
l |= itoa64_to_int (buf[ 9]) << 6;
|
|
l |= itoa64_to_int (buf[10]) << 12;
|
|
l |= itoa64_to_int (buf[11]) << 18;
|
|
|
|
digest[ 6] = (l >> 0) & 0xff;
|
|
digest[ 7] = (l >> 8) & 0xff;
|
|
digest[ 8] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[12]) << 0;
|
|
l |= itoa64_to_int (buf[13]) << 6;
|
|
l |= itoa64_to_int (buf[14]) << 12;
|
|
l |= itoa64_to_int (buf[15]) << 18;
|
|
|
|
digest[ 9] = (l >> 0) & 0xff;
|
|
digest[10] = (l >> 8) & 0xff;
|
|
digest[11] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[16]) << 0;
|
|
l |= itoa64_to_int (buf[17]) << 6;
|
|
l |= itoa64_to_int (buf[18]) << 12;
|
|
l |= itoa64_to_int (buf[19]) << 18;
|
|
|
|
digest[12] = (l >> 0) & 0xff;
|
|
digest[13] = (l >> 8) & 0xff;
|
|
digest[14] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[20]) << 0;
|
|
l |= itoa64_to_int (buf[21]) << 6;
|
|
l |= itoa64_to_int (buf[22]) << 12;
|
|
l |= itoa64_to_int (buf[23]) << 18;
|
|
|
|
digest[15] = (l >> 0) & 0xff;
|
|
digest[16] = (l >> 8) & 0xff;
|
|
digest[17] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[24]) << 0;
|
|
l |= itoa64_to_int (buf[25]) << 6;
|
|
l |= itoa64_to_int (buf[26]) << 12;
|
|
l |= itoa64_to_int (buf[27]) << 18;
|
|
|
|
digest[18] = (l >> 0) & 0xff;
|
|
digest[19] = (l >> 8) & 0xff;
|
|
digest[20] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[28]) << 0;
|
|
l |= itoa64_to_int (buf[29]) << 6;
|
|
l |= itoa64_to_int (buf[30]) << 12;
|
|
l |= itoa64_to_int (buf[31]) << 18;
|
|
|
|
digest[21] = (l >> 0) & 0xff;
|
|
digest[22] = (l >> 8) & 0xff;
|
|
digest[23] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[32]) << 0;
|
|
l |= itoa64_to_int (buf[33]) << 6;
|
|
l |= itoa64_to_int (buf[34]) << 12;
|
|
l |= itoa64_to_int (buf[35]) << 18;
|
|
|
|
digest[24] = (l >> 0) & 0xff;
|
|
digest[25] = (l >> 8) & 0xff;
|
|
digest[26] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[36]) << 0;
|
|
l |= itoa64_to_int (buf[37]) << 6;
|
|
l |= itoa64_to_int (buf[38]) << 12;
|
|
l |= itoa64_to_int (buf[39]) << 18;
|
|
|
|
digest[27] = (l >> 0) & 0xff;
|
|
digest[28] = (l >> 8) & 0xff;
|
|
digest[29] = (l >> 16) & 0xff;
|
|
|
|
l = itoa64_to_int (buf[40]) << 0;
|
|
l |= itoa64_to_int (buf[41]) << 6;
|
|
l |= itoa64_to_int (buf[42]) << 12;
|
|
l |= itoa64_to_int (buf[43]) << 18;
|
|
|
|
digest[30] = (l >> 0) & 0xff;
|
|
digest[31] = (l >> 8) & 0xff;
|
|
digest[32] = (l >> 16) & 0xff;
|
|
|
|
digest[33] = 0;
|
|
digest[34] = 0;
|
|
digest[35] = 0;
|
|
digest[36] = 0;
|
|
digest[37] = 0;
|
|
digest[38] = 0;
|
|
digest[39] = 0;
|
|
digest[40] = 0;
|
|
digest[41] = 0;
|
|
digest[42] = 0;
|
|
digest[43] = 0;
|
|
digest[44] = 0;
|
|
digest[45] = 0;
|
|
digest[46] = 0;
|
|
digest[47] = 0;
|
|
digest[48] = 0;
|
|
digest[49] = 0;
|
|
digest[50] = 0;
|
|
digest[51] = 0;
|
|
digest[52] = 0;
|
|
digest[53] = 0;
|
|
digest[54] = 0;
|
|
digest[55] = 0;
|
|
digest[56] = 0;
|
|
digest[57] = 0;
|
|
digest[58] = 0;
|
|
digest[59] = 0;
|
|
digest[60] = 0;
|
|
digest[61] = 0;
|
|
digest[62] = 0;
|
|
digest[63] = 0;
|
|
}
|
|
|
|
void drupal7_encode (unsigned char digest[64], unsigned char buf[43])
|
|
{
|
|
int l;
|
|
|
|
l = (digest[ 0] << 0) | (digest[ 1] << 8) | (digest[ 2] << 16);
|
|
|
|
buf[ 0] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 1] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 2] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 3] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 3] << 0) | (digest[ 4] << 8) | (digest[ 5] << 16);
|
|
|
|
buf[ 4] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 5] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 6] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 7] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 6] << 0) | (digest[ 7] << 8) | (digest[ 8] << 16);
|
|
|
|
buf[ 8] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[ 9] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[10] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[11] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[ 9] << 0) | (digest[10] << 8) | (digest[11] << 16);
|
|
|
|
buf[12] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[13] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[14] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[15] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[12] << 0) | (digest[13] << 8) | (digest[14] << 16);
|
|
|
|
buf[16] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[17] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[18] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[19] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[15] << 0) | (digest[16] << 8) | (digest[17] << 16);
|
|
|
|
buf[20] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[21] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[22] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[23] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[18] << 0) | (digest[19] << 8) | (digest[20] << 16);
|
|
|
|
buf[24] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[25] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[26] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[27] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[21] << 0) | (digest[22] << 8) | (digest[23] << 16);
|
|
|
|
buf[28] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[29] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[30] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[31] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[24] << 0) | (digest[25] << 8) | (digest[26] << 16);
|
|
|
|
buf[32] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[33] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[34] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[35] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[27] << 0) | (digest[28] << 8) | (digest[29] << 16);
|
|
|
|
buf[36] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[37] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[38] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[39] = int_to_itoa64 (l & 0x3f);
|
|
|
|
l = (digest[30] << 0) | (digest[31] << 8) | (digest[32] << 16);
|
|
|
|
buf[40] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[41] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
buf[42] = int_to_itoa64 (l & 0x3f); l >>= 6;
|
|
//buf[43] = int_to_itoa64 (l & 0x3f);
|
|
}
|
|
|
|
/**
|
|
* tty
|
|
*/
|
|
|
|
#ifdef LINUX
|
|
static struct termio savemodes;
|
|
static int havemodes = 0;
|
|
|
|
int tty_break()
|
|
{
|
|
struct termio modmodes;
|
|
|
|
if (ioctl (fileno (stdin), TCGETA, &savemodes) < 0) return -1;
|
|
|
|
havemodes = 1;
|
|
|
|
modmodes = savemodes;
|
|
modmodes.c_lflag &= ~ICANON;
|
|
modmodes.c_cc[VMIN] = 1;
|
|
modmodes.c_cc[VTIME] = 0;
|
|
|
|
return ioctl (fileno (stdin), TCSETAW, &modmodes);
|
|
}
|
|
|
|
int tty_getchar()
|
|
{
|
|
fd_set rfds;
|
|
|
|
FD_ZERO (&rfds);
|
|
|
|
FD_SET (fileno (stdin), &rfds);
|
|
|
|
struct timeval tv;
|
|
|
|
tv.tv_sec = 1;
|
|
tv.tv_usec = 0;
|
|
|
|
int retval = select (1, &rfds, NULL, NULL, &tv);
|
|
|
|
if (retval == 0) return 0;
|
|
if (retval == -1) return -1;
|
|
|
|
return getchar();
|
|
}
|
|
|
|
int tty_fix()
|
|
{
|
|
if (!havemodes) return 0;
|
|
|
|
return ioctl (fileno (stdin), TCSETAW, &savemodes);
|
|
}
|
|
#endif
|
|
|
|
#ifdef OSX
|
|
static struct termios savemodes;
|
|
static int havemodes = 0;
|
|
|
|
int tty_break()
|
|
{
|
|
struct termios modmodes;
|
|
|
|
if (ioctl (fileno (stdin), TIOCGETA, &savemodes) < 0) return -1;
|
|
|
|
havemodes = 1;
|
|
|
|
modmodes = savemodes;
|
|
modmodes.c_lflag &= ~ICANON;
|
|
modmodes.c_cc[VMIN] = 1;
|
|
modmodes.c_cc[VTIME] = 0;
|
|
|
|
return ioctl (fileno (stdin), TIOCSETAW, &modmodes);
|
|
}
|
|
|
|
int tty_getchar()
|
|
{
|
|
fd_set rfds;
|
|
|
|
FD_ZERO (&rfds);
|
|
|
|
FD_SET (fileno (stdin), &rfds);
|
|
|
|
struct timeval tv;
|
|
|
|
tv.tv_sec = 1;
|
|
tv.tv_usec = 0;
|
|
|
|
int retval = select (1, &rfds, NULL, NULL, &tv);
|
|
|
|
if (retval == 0) return 0;
|
|
if (retval == -1) return -1;
|
|
|
|
return getchar();
|
|
}
|
|
|
|
int tty_fix()
|
|
{
|
|
if (!havemodes) return 0;
|
|
|
|
return ioctl (fileno (stdin), TIOCSETAW, &savemodes);
|
|
}
|
|
#endif
|
|
|
|
#ifdef WIN
|
|
static DWORD saveMode = 0;
|
|
|
|
int tty_break()
|
|
{
|
|
HANDLE stdinHandle = GetStdHandle (STD_INPUT_HANDLE);
|
|
|
|
GetConsoleMode (stdinHandle, &saveMode);
|
|
SetConsoleMode (stdinHandle, ENABLE_PROCESSED_INPUT);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int tty_getchar()
|
|
{
|
|
HANDLE stdinHandle = GetStdHandle (STD_INPUT_HANDLE);
|
|
|
|
DWORD rc = WaitForSingleObject (stdinHandle, 1000);
|
|
|
|
if (rc == WAIT_TIMEOUT) return 0;
|
|
if (rc == WAIT_ABANDONED) return -1;
|
|
if (rc == WAIT_FAILED) return -1;
|
|
|
|
// The whole ReadConsoleInput () part is a workaround.
|
|
// For some unknown reason, maybe a mingw bug, a random signal
|
|
// is sent to stdin which unblocks WaitForSingleObject () and sets rc 0.
|
|
// Then it wants to read with getche () a keyboard input
|
|
// which has never been made.
|
|
|
|
INPUT_RECORD buf[100];
|
|
|
|
DWORD num = 0;
|
|
|
|
ReadConsoleInput (stdinHandle, buf, 100, &num);
|
|
|
|
FlushConsoleInputBuffer (stdinHandle);
|
|
|
|
for (uint i = 0; i < num; i++)
|
|
{
|
|
if (buf[i].EventType != KEY_EVENT) continue;
|
|
|
|
KEY_EVENT_RECORD KeyEvent = buf[i].Event.KeyEvent;
|
|
|
|
if (KeyEvent.bKeyDown != TRUE) continue;
|
|
|
|
return KeyEvent.uChar.AsciiChar;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int tty_fix()
|
|
{
|
|
HANDLE stdinHandle = GetStdHandle (STD_INPUT_HANDLE);
|
|
|
|
SetConsoleMode (stdinHandle, saveMode);
|
|
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* mem alloc
|
|
*/
|
|
|
|
#define MSG_ENOMEM "Insufficient memory available"
|
|
|
|
void *mycalloc (size_t nmemb, size_t size)
|
|
{
|
|
void *p = calloc (nmemb, size);
|
|
|
|
if (p == NULL)
|
|
{
|
|
log_error ("ERROR: %s", MSG_ENOMEM);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
return (p);
|
|
}
|
|
|
|
void *mymalloc (size_t size)
|
|
{
|
|
void *p = malloc (size);
|
|
|
|
if (p == NULL)
|
|
{
|
|
log_error ("ERROR: %s", MSG_ENOMEM);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
memset (p, 0, size);
|
|
|
|
return (p);
|
|
}
|
|
|
|
void myfree (void *ptr)
|
|
{
|
|
if (ptr == NULL) return;
|
|
|
|
free (ptr);
|
|
}
|
|
|
|
void *myrealloc (void *ptr, size_t oldsz, size_t add)
|
|
{
|
|
void *p = realloc (ptr, oldsz + add);
|
|
|
|
if (p == NULL)
|
|
{
|
|
log_error ("ERROR: %s", MSG_ENOMEM);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
memset ((char *) p + oldsz, 0, add);
|
|
|
|
return (p);
|
|
}
|
|
|
|
char *mystrdup (const char *s)
|
|
{
|
|
const size_t len = strlen (s);
|
|
|
|
char *b = (char *) mymalloc (len + 1);
|
|
|
|
memcpy (b, s, len);
|
|
|
|
return (b);
|
|
}
|
|
|
|
FILE *logfile_open (char *logfile)
|
|
{
|
|
FILE *fp = fopen (logfile, "ab");
|
|
|
|
if (fp == NULL)
|
|
{
|
|
fp = stdout;
|
|
}
|
|
|
|
return fp;
|
|
}
|
|
|
|
void logfile_close (FILE *fp)
|
|
{
|
|
if (fp == stdout) return;
|
|
|
|
fclose (fp);
|
|
}
|
|
|
|
void logfile_append (const char *fmt, ...)
|
|
{
|
|
if (data.logfile_disable == 1) return;
|
|
|
|
FILE *fp = logfile_open (data.logfile);
|
|
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
|
|
vfprintf (fp, fmt, ap);
|
|
|
|
va_end (ap);
|
|
|
|
fputc ('\n', fp);
|
|
|
|
fflush (fp);
|
|
|
|
logfile_close (fp);
|
|
}
|
|
|
|
int logfile_generate_id ()
|
|
{
|
|
const int n = rand ();
|
|
|
|
time_t t;
|
|
|
|
time (&t);
|
|
|
|
return t + n;
|
|
}
|
|
|
|
char *logfile_generate_topid ()
|
|
{
|
|
const int id = logfile_generate_id ();
|
|
|
|
char *topid = (char *) mymalloc (1 + 16 + 1);
|
|
|
|
sprintf (topid, "TOP%08x", id);
|
|
|
|
return topid;
|
|
}
|
|
|
|
char *logfile_generate_subid ()
|
|
{
|
|
const int id = logfile_generate_id ();
|
|
|
|
char *subid = (char *) mymalloc (1 + 16 + 1);
|
|
|
|
sprintf (subid, "SUB%08x", id);
|
|
|
|
return subid;
|
|
}
|
|
|
|
/**
|
|
* system
|
|
*/
|
|
|
|
#ifdef _WIN
|
|
void fsync (int fd)
|
|
{
|
|
HANDLE h = (HANDLE) _get_osfhandle (fd);
|
|
|
|
FlushFileBuffers (h);
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* thermal
|
|
*/
|
|
|
|
#ifdef _WIN
|
|
int hm_get_adapter_index_nv (HM_ADAPTER_NV nvGPUHandle[DEVICES_MAX])
|
|
{
|
|
NvU32 pGpuCount;
|
|
|
|
if (hc_NvAPI_EnumPhysicalGPUs (nvGPUHandle, &pGpuCount) != NVAPI_OK) return (0);
|
|
|
|
if (pGpuCount == 0)
|
|
{
|
|
log_info ("WARN: No NvAPI adapters found");
|
|
|
|
return (0);
|
|
}
|
|
|
|
return (pGpuCount);
|
|
}
|
|
#endif
|
|
|
|
#ifdef LINUX
|
|
int hm_get_adapter_index_nv (HM_ADAPTER_NV nvGPUHandle[DEVICES_MAX])
|
|
{
|
|
int pGpuCount = 0;
|
|
|
|
for (uint i = 0; i < DEVICES_MAX; i++)
|
|
{
|
|
if (hc_NVML_nvmlDeviceGetHandleByIndex (data.hm_dll, 1, i, &nvGPUHandle[i]) != NVML_SUCCESS) break;
|
|
|
|
//can be used to determine if the device by index matches the cuda device by index
|
|
//char name[100]; memset (name, 0, sizeof (name));
|
|
//hc_NVML_nvmlDeviceGetName (data.hm_dll, nvGPUHandle[i], name, sizeof (name) - 1);
|
|
|
|
pGpuCount++;
|
|
}
|
|
|
|
if (pGpuCount == 0)
|
|
{
|
|
log_info ("WARN: No NVML adapters found");
|
|
|
|
return (0);
|
|
}
|
|
|
|
return (pGpuCount);
|
|
}
|
|
#endif
|
|
|
|
void hm_close (HM_LIB hm_dll)
|
|
{
|
|
#ifdef _POSIX
|
|
dlclose (hm_dll);
|
|
|
|
#elif _WIN
|
|
FreeLibrary (hm_dll);
|
|
|
|
#endif
|
|
}
|
|
|
|
HM_LIB hm_init ()
|
|
{
|
|
HM_LIB hm_dll = NULL;
|
|
|
|
if (data.vendor_id == VENDOR_ID_AMD)
|
|
{
|
|
#ifdef _POSIX
|
|
hm_dll = dlopen ("libatiadlxx.so", RTLD_LAZY | RTLD_GLOBAL);
|
|
|
|
#elif _WIN
|
|
hm_dll = LoadLibrary ("atiadlxx.dll");
|
|
|
|
if (hm_dll == NULL)
|
|
{
|
|
hm_dll = LoadLibrary ("atiadlxy.dll");
|
|
}
|
|
|
|
#endif
|
|
}
|
|
|
|
#ifdef LINUX
|
|
if (data.vendor_id == VENDOR_ID_NV)
|
|
{
|
|
hm_dll = dlopen ("libnvidia-ml.so", RTLD_LAZY | RTLD_GLOBAL);
|
|
}
|
|
#endif
|
|
|
|
return hm_dll;
|
|
}
|
|
|
|
int get_adapters_num_amd (HM_LIB hm_dll, int *iNumberAdapters)
|
|
{
|
|
if (hc_ADL_Adapter_NumberOfAdapters_Get (hm_dll, iNumberAdapters) != ADL_OK) return -1;
|
|
|
|
if (iNumberAdapters == 0)
|
|
{
|
|
log_info ("WARN: No ADL adapters found.");
|
|
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
int hm_show_performance_level (HM_LIB hm_dll, int iAdapterIndex)
|
|
{
|
|
ADLODPerformanceLevels *lpOdPerformanceLevels = NULL;
|
|
ADLODParameters lpOdParameters;
|
|
|
|
lpOdParameters.iSize = sizeof (ADLODParameters);
|
|
size_t plevels_size = 0;
|
|
|
|
if (hc_ADL_Overdrive_ODParameters_Get (hm_dll, iAdapterIndex, &lpOdParameters) != ADL_OK) return -1;
|
|
|
|
log_info ("[DEBUG] %s, adapter %d performance level (%d) : %s %s",
|
|
__func__, iAdapterIndex,
|
|
lpOdParameters.iNumberOfPerformanceLevels,
|
|
(lpOdParameters.iActivityReportingSupported) ? "activity reporting" : "",
|
|
(lpOdParameters.iDiscretePerformanceLevels) ? "discrete performance levels" : "performance ranges");
|
|
|
|
plevels_size = sizeof (ADLODPerformanceLevels) + sizeof (ADLODPerformanceLevel) * (lpOdParameters.iNumberOfPerformanceLevels - 1);
|
|
|
|
lpOdPerformanceLevels = (ADLODPerformanceLevels *) mymalloc (plevels_size);
|
|
|
|
lpOdPerformanceLevels->iSize = sizeof (ADLODPerformanceLevels) + sizeof (ADLODPerformanceLevel) * (lpOdParameters.iNumberOfPerformanceLevels - 1);
|
|
|
|
if (hc_ADL_Overdrive_ODPerformanceLevels_Get (hm_dll, iAdapterIndex, 0, lpOdPerformanceLevels) != ADL_OK) return -1;
|
|
|
|
for (int j = 0; j < lpOdParameters.iNumberOfPerformanceLevels; j++)
|
|
log_info ("[DEBUG] %s, adapter %d, level %d : engine %d, memory %d, voltage: %d",
|
|
__func__, iAdapterIndex, j,
|
|
lpOdPerformanceLevels->aLevels[j].iEngineClock / 100, lpOdPerformanceLevels->aLevels[j].iMemoryClock / 100, lpOdPerformanceLevels->aLevels[j].iVddc);
|
|
|
|
myfree (lpOdPerformanceLevels);
|
|
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
LPAdapterInfo hm_get_adapter_info_amd (HM_LIB hm_dll, int iNumberAdapters)
|
|
{
|
|
size_t AdapterInfoSize = iNumberAdapters * sizeof (AdapterInfo);
|
|
|
|
LPAdapterInfo lpAdapterInfo = (LPAdapterInfo) mymalloc (AdapterInfoSize);
|
|
|
|
if (hc_ADL_Adapter_AdapterInfo_Get (hm_dll, lpAdapterInfo, AdapterInfoSize) != ADL_OK) return NULL;
|
|
|
|
return lpAdapterInfo;
|
|
}
|
|
|
|
/*
|
|
//
|
|
// does not help at all, since AMD does not assign different bus id, device id when we have multi GPU setups
|
|
//
|
|
|
|
int hm_get_opencl_device_index (hm_attrs_t *hm_device, uint num_adl_adapters, int bus_num, int dev_num)
|
|
{
|
|
uint32_t idx = -1;
|
|
|
|
for (uint i = 0; i < num_adl_adapters; i++)
|
|
{
|
|
int opencl_bus_num = hm_device[i].busid;
|
|
int opencl_dev_num = hm_device[i].devid;
|
|
|
|
if ((opencl_bus_num == bus_num) && (opencl_dev_num == dev_num))
|
|
{
|
|
idx = i;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (idx >= DEVICES_MAX) return -1;
|
|
|
|
return idx;
|
|
}
|
|
|
|
void hm_get_opencl_busid_devid (hm_attrs_t *hm_device, uint opencl_num_devices, cl_device_id *devices)
|
|
{
|
|
for (uint i = 0; i < opencl_num_devices; i++)
|
|
{
|
|
cl_device_topology_amd device_topology;
|
|
|
|
hc_clGetDeviceInfo (devices[i], CL_DEVICE_TOPOLOGY_AMD, sizeof (device_topology), &device_topology, NULL);
|
|
|
|
hm_device[i].busid = device_topology.pcie.bus;
|
|
hm_device[i].devid = device_topology.pcie.device;
|
|
}
|
|
}
|
|
*/
|
|
|
|
void hm_sort_adl_adapters_by_busid_devid (uint32_t *valid_adl_device_list, int num_adl_adapters, LPAdapterInfo lpAdapterInfo)
|
|
{
|
|
// basically bubble sort
|
|
|
|
for (int i = 0; i < num_adl_adapters; i++)
|
|
{
|
|
for (int j = 0; j < num_adl_adapters - 1; j++)
|
|
{
|
|
// get info of adapter [x]
|
|
|
|
uint32_t adapter_index_x = valid_adl_device_list[j];
|
|
AdapterInfo info_x = lpAdapterInfo[adapter_index_x];
|
|
|
|
uint32_t bus_num_x = info_x.iBusNumber;
|
|
uint32_t dev_num_x = info_x.iDeviceNumber;
|
|
|
|
// get info of adapter [y]
|
|
|
|
uint32_t adapter_index_y = valid_adl_device_list[j + 1];
|
|
AdapterInfo info_y = lpAdapterInfo[adapter_index_y];
|
|
|
|
uint32_t bus_num_y = info_y.iBusNumber;
|
|
uint32_t dev_num_y = info_y.iDeviceNumber;
|
|
|
|
uint need_swap = 0;
|
|
|
|
if (bus_num_y < bus_num_x)
|
|
{
|
|
need_swap = 1;
|
|
}
|
|
else if (bus_num_y == bus_num_x)
|
|
{
|
|
if (dev_num_y < dev_num_x)
|
|
{
|
|
need_swap = 1;
|
|
}
|
|
}
|
|
|
|
if (need_swap == 1)
|
|
{
|
|
uint32_t temp = valid_adl_device_list[j + 1];
|
|
|
|
valid_adl_device_list[j + 1] = valid_adl_device_list[j];
|
|
valid_adl_device_list[j + 0] = temp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
uint32_t *hm_get_list_valid_adl_adapters (int iNumberAdapters, int *num_adl_adapters, LPAdapterInfo lpAdapterInfo)
|
|
{
|
|
*num_adl_adapters = 0;
|
|
|
|
uint32_t *adl_adapters = NULL;
|
|
|
|
int *bus_numbers = NULL;
|
|
int *device_numbers = NULL;
|
|
|
|
for (int i = 0; i < iNumberAdapters; i++)
|
|
{
|
|
AdapterInfo info = lpAdapterInfo[i];
|
|
|
|
if ((info.strUDID == NULL) || (strlen (info.strUDID) < 1)) continue;
|
|
|
|
#ifdef WIN
|
|
if (info.iVendorID != 1002) continue;
|
|
#else
|
|
if (info.iVendorID != 0x1002) continue;
|
|
#endif
|
|
|
|
if (info.iBusNumber < 0) continue;
|
|
if (info.iDeviceNumber < 0) continue;
|
|
|
|
int found = 0;
|
|
|
|
for (int pos = 0; pos < *num_adl_adapters; pos++)
|
|
{
|
|
if ((bus_numbers[pos] == info.iBusNumber) && (device_numbers[pos] == info.iDeviceNumber))
|
|
{
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (found) continue;
|
|
|
|
// add it to the list
|
|
|
|
adl_adapters = (uint32_t *) myrealloc (adl_adapters, (*num_adl_adapters) * sizeof (int), sizeof (int));
|
|
|
|
adl_adapters[*num_adl_adapters] = i;
|
|
|
|
// rest is just bookkeeping
|
|
|
|
bus_numbers = (int*) myrealloc (bus_numbers, (*num_adl_adapters) * sizeof (int), sizeof (int));
|
|
device_numbers = (int*) myrealloc (device_numbers, (*num_adl_adapters) * sizeof (int), sizeof (int));
|
|
|
|
bus_numbers[*num_adl_adapters] = info.iBusNumber;
|
|
device_numbers[*num_adl_adapters] = info.iDeviceNumber;
|
|
|
|
(*num_adl_adapters)++;
|
|
}
|
|
|
|
myfree (bus_numbers);
|
|
myfree (device_numbers);
|
|
|
|
// sort the list by increasing bus id, device id number
|
|
|
|
hm_sort_adl_adapters_by_busid_devid (adl_adapters, *num_adl_adapters, lpAdapterInfo);
|
|
|
|
return adl_adapters;
|
|
}
|
|
|
|
int hm_check_fanspeed_control (HM_LIB hm_dll, hm_attrs_t *hm_device, uint32_t *valid_adl_device_list, int num_adl_adapters, LPAdapterInfo lpAdapterInfo)
|
|
{
|
|
// loop through all valid devices
|
|
|
|
for (int i = 0; i < num_adl_adapters; i++)
|
|
{
|
|
uint32_t adapter_index = valid_adl_device_list[i];
|
|
|
|
// get AdapterInfo
|
|
|
|
AdapterInfo info = lpAdapterInfo[adapter_index];
|
|
|
|
// unfortunately this doesn't work since bus id and dev id are not unique
|
|
// int opencl_device_index = hm_get_opencl_device_index (hm_device, num_adl_adapters, info.iBusNumber, info.iDeviceNumber);
|
|
// if (opencl_device_index == -1) continue;
|
|
|
|
int opencl_device_index = i;
|
|
|
|
// if (hm_show_performance_level (hm_dll, info.iAdapterIndex) != 0) return -1;
|
|
|
|
// get fanspeed info
|
|
|
|
if (hm_device[opencl_device_index].od_version == 5)
|
|
{
|
|
ADLFanSpeedInfo FanSpeedInfo;
|
|
|
|
memset (&FanSpeedInfo, 0, sizeof (ADLFanSpeedInfo));
|
|
|
|
FanSpeedInfo.iSize = sizeof (ADLFanSpeedInfo);
|
|
|
|
if (hc_ADL_Overdrive5_FanSpeedInfo_Get (hm_dll, info.iAdapterIndex, 0, &FanSpeedInfo) != ADL_OK) return -1;
|
|
|
|
// check read and write capability in fanspeedinfo
|
|
|
|
if ((FanSpeedInfo.iFlags & ADL_DL_FANCTRL_SUPPORTS_PERCENT_READ) &&
|
|
(FanSpeedInfo.iFlags & ADL_DL_FANCTRL_SUPPORTS_PERCENT_WRITE))
|
|
{
|
|
hm_device[opencl_device_index].fan_supported = 1;
|
|
}
|
|
else
|
|
{
|
|
hm_device[opencl_device_index].fan_supported = 0;
|
|
}
|
|
}
|
|
else // od_version == 6
|
|
{
|
|
ADLOD6FanSpeedInfo faninfo;
|
|
|
|
memset (&faninfo, 0, sizeof (faninfo));
|
|
|
|
if (hc_ADL_Overdrive6_FanSpeed_Get (hm_dll, info.iAdapterIndex, &faninfo) != ADL_OK) return -1;
|
|
|
|
// check read capability in fanspeedinfo
|
|
|
|
if (faninfo.iSpeedType & ADL_OD6_FANSPEED_TYPE_PERCENT)
|
|
{
|
|
hm_device[opencl_device_index].fan_supported = 1;
|
|
}
|
|
else
|
|
{
|
|
hm_device[opencl_device_index].fan_supported = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hm_get_overdrive_version (HM_LIB hm_dll, hm_attrs_t *hm_device, uint32_t *valid_adl_device_list, int num_adl_adapters, LPAdapterInfo lpAdapterInfo)
|
|
{
|
|
for (int i = 0; i < num_adl_adapters; i++)
|
|
{
|
|
uint32_t adapter_index = valid_adl_device_list[i];
|
|
|
|
// get AdapterInfo
|
|
|
|
AdapterInfo info = lpAdapterInfo[adapter_index];
|
|
|
|
// get overdrive version
|
|
|
|
int od_supported = 0;
|
|
int od_enabled = 0;
|
|
int od_version = 0;
|
|
|
|
if (hc_ADL_Overdrive_Caps (hm_dll, info.iAdapterIndex, &od_supported, &od_enabled, &od_version) != ADL_OK) return -1;
|
|
|
|
// store the overdrive version in hm_device
|
|
|
|
// unfortunately this doesn't work since bus id and dev id are not unique
|
|
// int opencl_device_index = hm_get_opencl_device_index (hm_device, num_adl_adapters, info.iBusNumber, info.iDeviceNumber);
|
|
// if (opencl_device_index == -1) continue;
|
|
|
|
int opencl_device_index = i;
|
|
|
|
hm_device[opencl_device_index].od_version = od_version;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hm_get_adapter_index_amd (hm_attrs_t *hm_device, uint32_t *valid_adl_device_list, int num_adl_adapters, LPAdapterInfo lpAdapterInfo)
|
|
{
|
|
for (int i = 0; i < num_adl_adapters; i++)
|
|
{
|
|
uint32_t adapter_index = valid_adl_device_list[i];
|
|
|
|
// get AdapterInfo
|
|
|
|
AdapterInfo info = lpAdapterInfo[adapter_index];
|
|
|
|
// store the iAdapterIndex in hm_device
|
|
|
|
// unfortunately this doesn't work since bus id and dev id are not unique
|
|
// int opencl_device_index = hm_get_opencl_device_index (hm_device, num_adl_adapters, info.iBusNumber, info.iDeviceNumber);
|
|
// if (opencl_device_index == -1) continue;
|
|
|
|
int opencl_device_index = i;
|
|
|
|
hm_device[opencl_device_index].adapter_index.amd = info.iAdapterIndex;
|
|
}
|
|
|
|
return num_adl_adapters;
|
|
}
|
|
|
|
int hm_get_temperature_with_device_id (const uint device_id)
|
|
{
|
|
if (data.vendor_id == VENDOR_ID_AMD)
|
|
{
|
|
if (data.hm_dll)
|
|
{
|
|
if (data.hm_device[device_id].od_version == 5)
|
|
{
|
|
ADLTemperature Temperature;
|
|
|
|
Temperature.iSize = sizeof (ADLTemperature);
|
|
|
|
if (hc_ADL_Overdrive5_Temperature_Get (data.hm_dll, data.hm_device[device_id].adapter_index.amd, 0, &Temperature) != ADL_OK) return -1;
|
|
|
|
return Temperature.iTemperature / 1000;
|
|
}
|
|
else if (data.hm_device[device_id].od_version == 6)
|
|
{
|
|
int Temperature = 0;
|
|
|
|
if (hc_ADL_Overdrive6_Temperature_Get (data.hm_dll, data.hm_device[device_id].adapter_index.amd, &Temperature) != ADL_OK) return -1;
|
|
|
|
return Temperature / 1000;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (data.vendor_id == VENDOR_ID_NV)
|
|
{
|
|
#ifdef LINUX
|
|
int temperature = 0;
|
|
|
|
hc_NVML_nvmlDeviceGetTemperature (data.hm_dll, data.hm_device[device_id].adapter_index.nv, NVML_TEMPERATURE_GPU, (unsigned int *) &temperature);
|
|
|
|
return temperature;
|
|
#endif
|
|
|
|
#ifdef WIN
|
|
NV_GPU_THERMAL_SETTINGS pThermalSettings;
|
|
|
|
pThermalSettings.version = NV_GPU_THERMAL_SETTINGS_VER;
|
|
pThermalSettings.count = NVAPI_MAX_THERMAL_SENSORS_PER_GPU;
|
|
pThermalSettings.sensor[0].controller = NVAPI_THERMAL_CONTROLLER_UNKNOWN;
|
|
pThermalSettings.sensor[0].target = NVAPI_THERMAL_TARGET_GPU;
|
|
|
|
if (hc_NvAPI_GPU_GetThermalSettings (data.hm_device[device_id].adapter_index.nv, 0, &pThermalSettings) != NVAPI_OK) return -1;
|
|
|
|
return pThermalSettings.sensor[0].currentTemp;
|
|
#endif
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int hm_get_fanspeed_with_device_id (const uint device_id)
|
|
{
|
|
if (data.hm_device[device_id].fan_supported == 1)
|
|
{
|
|
if (data.vendor_id == VENDOR_ID_AMD)
|
|
{
|
|
if (data.hm_dll)
|
|
{
|
|
if (data.hm_device[device_id].od_version == 5)
|
|
{
|
|
ADLFanSpeedValue lpFanSpeedValue;
|
|
|
|
memset (&lpFanSpeedValue, 0, sizeof (lpFanSpeedValue));
|
|
|
|
lpFanSpeedValue.iSize = sizeof (lpFanSpeedValue);
|
|
lpFanSpeedValue.iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
|
|
lpFanSpeedValue.iFlags = ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED;
|
|
|
|
if (hc_ADL_Overdrive5_FanSpeed_Get (data.hm_dll, data.hm_device[device_id].adapter_index.amd, 0, &lpFanSpeedValue) != ADL_OK) return -1;
|
|
|
|
return lpFanSpeedValue.iFanSpeed;
|
|
}
|
|
else // od_version == 6
|
|
{
|
|
ADLOD6FanSpeedInfo faninfo;
|
|
|
|
memset (&faninfo, 0, sizeof (faninfo));
|
|
|
|
if (hc_ADL_Overdrive6_FanSpeed_Get (data.hm_dll, data.hm_device[device_id].adapter_index.amd, &faninfo) != ADL_OK) return -1;
|
|
|
|
return faninfo.iFanSpeedPercent;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (data.vendor_id == VENDOR_ID_NV)
|
|
{
|
|
#ifdef LINUX
|
|
int speed = 0;
|
|
|
|
hc_NVML_nvmlDeviceGetFanSpeed (data.hm_dll, 1, data.hm_device[device_id].adapter_index.nv, (unsigned int *) &speed);
|
|
|
|
return speed;
|
|
#endif
|
|
|
|
#ifdef WIN
|
|
NvU32 speed = 0;
|
|
|
|
hc_NvAPI_GPU_GetTachReading (data.hm_device[device_id].adapter_index.nv, &speed);
|
|
|
|
return speed;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int hm_get_utilization_with_device_id (const uint device_id)
|
|
{
|
|
if (data.vendor_id == VENDOR_ID_AMD)
|
|
{
|
|
if (data.hm_dll)
|
|
{
|
|
ADLPMActivity PMActivity;
|
|
|
|
PMActivity.iSize = sizeof (ADLPMActivity);
|
|
|
|
if (hc_ADL_Overdrive_CurrentActivity_Get (data.hm_dll, data.hm_device[device_id].adapter_index.amd, &PMActivity) != ADL_OK) return -1;
|
|
|
|
return PMActivity.iActivityPercent;
|
|
}
|
|
}
|
|
|
|
if (data.vendor_id == VENDOR_ID_NV)
|
|
{
|
|
#ifdef LINUX
|
|
nvmlUtilization_t utilization;
|
|
|
|
hc_NVML_nvmlDeviceGetUtilizationRates (data.hm_dll, data.hm_device[device_id].adapter_index.nv, &utilization);
|
|
|
|
return utilization.gpu;
|
|
#endif
|
|
|
|
#ifdef WIN
|
|
NV_GPU_DYNAMIC_PSTATES_INFO_EX pDynamicPstatesInfoEx;
|
|
|
|
pDynamicPstatesInfoEx.version = NV_GPU_DYNAMIC_PSTATES_INFO_EX_VER;
|
|
|
|
if (hc_NvAPI_GPU_GetDynamicPstatesInfoEx (data.hm_device[device_id].adapter_index.nv, &pDynamicPstatesInfoEx) != NVAPI_OK) return -1;
|
|
|
|
return pDynamicPstatesInfoEx.utilization[0].percentage;
|
|
#endif
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int hm_set_fanspeed_with_device_id_amd (const uint device_id, const int fanspeed)
|
|
{
|
|
if (data.hm_device[device_id].fan_supported == 1)
|
|
{
|
|
if (data.hm_dll)
|
|
{
|
|
if (data.hm_device[device_id].od_version == 5)
|
|
{
|
|
ADLFanSpeedValue lpFanSpeedValue;
|
|
|
|
memset (&lpFanSpeedValue, 0, sizeof (lpFanSpeedValue));
|
|
|
|
lpFanSpeedValue.iSize = sizeof (lpFanSpeedValue);
|
|
lpFanSpeedValue.iSpeedType = ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
|
|
lpFanSpeedValue.iFlags = ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED;
|
|
lpFanSpeedValue.iFanSpeed = fanspeed;
|
|
|
|
if (hc_ADL_Overdrive5_FanSpeed_Set (data.hm_dll, data.hm_device[device_id].adapter_index.amd, 0, &lpFanSpeedValue) != ADL_OK) return -1;
|
|
|
|
return 0;
|
|
}
|
|
else // od_version == 6
|
|
{
|
|
ADLOD6FanSpeedValue fan_speed_value;
|
|
|
|
memset (&fan_speed_value, 0, sizeof (fan_speed_value));
|
|
|
|
fan_speed_value.iSpeedType = ADL_OD6_FANSPEED_TYPE_PERCENT;
|
|
fan_speed_value.iFanSpeed = fanspeed;
|
|
|
|
if (hc_ADL_Overdrive6_FanSpeed_Set (data.hm_dll, data.hm_device[device_id].adapter_index.amd, &fan_speed_value) != ADL_OK) return -1;
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* maskprocessor
|
|
*/
|
|
|
|
void mp_css_to_uniq_tbl (uint css_cnt, cs_t *css, uint uniq_tbls[SP_PW_MAX][CHARSIZ])
|
|
{
|
|
/* generates a lookup table where key is the char itself for fastest possible lookup performance */
|
|
|
|
if (css_cnt > SP_PW_MAX)
|
|
{
|
|
log_error ("ERROR: mask length is too long");
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
for (uint css_pos = 0; css_pos < css_cnt; css_pos++)
|
|
{
|
|
uint *uniq_tbl = uniq_tbls[css_pos];
|
|
|
|
uint *cs_buf = css[css_pos].cs_buf;
|
|
uint cs_len = css[css_pos].cs_len;
|
|
|
|
for (uint cs_pos = 0; cs_pos < cs_len; cs_pos++)
|
|
{
|
|
uint c = cs_buf[cs_pos] & 0xff;
|
|
|
|
uniq_tbl[c] = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void mp_add_cs_buf (uint *in_buf, size_t in_len, cs_t *css, int css_cnt)
|
|
{
|
|
cs_t *cs = &css[css_cnt];
|
|
|
|
size_t css_uniq_sz = CHARSIZ * sizeof (uint);
|
|
|
|
uint *css_uniq = (uint *) mymalloc (css_uniq_sz);
|
|
|
|
memset (css_uniq, 0, css_uniq_sz);
|
|
|
|
size_t i;
|
|
|
|
for (i = 0; i < cs->cs_len; i++)
|
|
{
|
|
const uint u = cs->cs_buf[i];
|
|
|
|
css_uniq[u] = 1;
|
|
}
|
|
|
|
for (i = 0; i < in_len; i++)
|
|
{
|
|
uint u = in_buf[i] & 0xff;
|
|
|
|
if (data.opts_type & OPTS_TYPE_PT_UPPER) u = toupper (u);
|
|
|
|
if (css_uniq[u] == 1) continue;
|
|
|
|
css_uniq[u] = 1;
|
|
|
|
cs->cs_buf[cs->cs_len] = u;
|
|
|
|
cs->cs_len++;
|
|
}
|
|
|
|
myfree (css_uniq);
|
|
}
|
|
|
|
void mp_expand (char *in_buf, size_t in_len, cs_t *mp_sys, cs_t *mp_usr, int mp_usr_offset, int interpret)
|
|
{
|
|
size_t in_pos;
|
|
|
|
for (in_pos = 0; in_pos < in_len; in_pos++)
|
|
{
|
|
uint p0 = in_buf[in_pos] & 0xff;
|
|
|
|
if (interpret == 1 && p0 == '?')
|
|
{
|
|
in_pos++;
|
|
|
|
if (in_pos == in_len) break;
|
|
|
|
uint p1 = in_buf[in_pos] & 0xff;
|
|
|
|
switch (p1)
|
|
{
|
|
case 'l': mp_add_cs_buf (mp_sys[0].cs_buf, mp_sys[0].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case 'u': mp_add_cs_buf (mp_sys[1].cs_buf, mp_sys[1].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case 'd': mp_add_cs_buf (mp_sys[2].cs_buf, mp_sys[2].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case 's': mp_add_cs_buf (mp_sys[3].cs_buf, mp_sys[3].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case 'a': mp_add_cs_buf (mp_sys[4].cs_buf, mp_sys[4].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case 'b': mp_add_cs_buf (mp_sys[5].cs_buf, mp_sys[5].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case '1': if (mp_usr[0].cs_len == 0) { log_error ("ERROR: Custom-charset 1 is undefined\n"); exit (-1); }
|
|
mp_add_cs_buf (mp_usr[0].cs_buf, mp_usr[0].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case '2': if (mp_usr[1].cs_len == 0) { log_error ("ERROR: Custom-charset 2 is undefined\n"); exit (-1); }
|
|
mp_add_cs_buf (mp_usr[1].cs_buf, mp_usr[1].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case '3': if (mp_usr[2].cs_len == 0) { log_error ("ERROR: Custom-charset 3 is undefined\n"); exit (-1); }
|
|
mp_add_cs_buf (mp_usr[2].cs_buf, mp_usr[2].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case '4': if (mp_usr[3].cs_len == 0) { log_error ("ERROR: Custom-charset 4 is undefined\n"); exit (-1); }
|
|
mp_add_cs_buf (mp_usr[3].cs_buf, mp_usr[3].cs_len, mp_usr, mp_usr_offset);
|
|
break;
|
|
case '?': mp_add_cs_buf (&p0, 1, mp_usr, mp_usr_offset);
|
|
break;
|
|
default: log_error ("Syntax error: %s", in_buf);
|
|
exit (-1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (data.hex_charset)
|
|
{
|
|
in_pos++;
|
|
|
|
if (in_pos == in_len)
|
|
{
|
|
log_error ("ERROR: the hex-charset option always expects couples of exactly 2 hexadecimal chars, failed mask: %s", in_buf);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
uint p1 = in_buf[in_pos] & 0xff;
|
|
|
|
if ((is_valid_hex_char (p0) == 0) || (is_valid_hex_char (p1) == 0))
|
|
{
|
|
log_error ("ERROR: invalid hex character detected in mask %s", in_buf);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
uint chr = 0;
|
|
|
|
chr = hex_convert (p1) << 0;
|
|
chr |= hex_convert (p0) << 4;
|
|
|
|
mp_add_cs_buf (&chr, 1, mp_usr, mp_usr_offset);
|
|
}
|
|
else
|
|
{
|
|
uint chr = p0;
|
|
|
|
mp_add_cs_buf (&chr, 1, mp_usr, mp_usr_offset);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
uint64_t mp_get_sum (uint css_cnt, cs_t *css)
|
|
{
|
|
uint64_t sum = 1;
|
|
|
|
for (uint css_pos = 0; css_pos < css_cnt; css_pos++)
|
|
{
|
|
sum *= css[css_pos].cs_len;
|
|
}
|
|
|
|
return (sum);
|
|
}
|
|
|
|
cs_t *mp_gen_css (char *mask_buf, size_t mask_len, cs_t *mp_sys, cs_t *mp_usr, uint *css_cnt)
|
|
{
|
|
cs_t *css = (cs_t *) mycalloc (256, sizeof (cs_t));
|
|
|
|
uint mask_pos;
|
|
uint css_pos;
|
|
|
|
for (mask_pos = 0, css_pos = 0; mask_pos < mask_len; mask_pos++, css_pos++)
|
|
{
|
|
char p0 = mask_buf[mask_pos];
|
|
|
|
if (p0 == '?')
|
|
{
|
|
mask_pos++;
|
|
|
|
if (mask_pos == mask_len) break;
|
|
|
|
char p1 = mask_buf[mask_pos];
|
|
|
|
uint chr = p1;
|
|
|
|
switch (p1)
|
|
{
|
|
case 'l': mp_add_cs_buf (mp_sys[0].cs_buf, mp_sys[0].cs_len, css, css_pos);
|
|
break;
|
|
case 'u': mp_add_cs_buf (mp_sys[1].cs_buf, mp_sys[1].cs_len, css, css_pos);
|
|
break;
|
|
case 'd': mp_add_cs_buf (mp_sys[2].cs_buf, mp_sys[2].cs_len, css, css_pos);
|
|
break;
|
|
case 's': mp_add_cs_buf (mp_sys[3].cs_buf, mp_sys[3].cs_len, css, css_pos);
|
|
break;
|
|
case 'a': mp_add_cs_buf (mp_sys[4].cs_buf, mp_sys[4].cs_len, css, css_pos);
|
|
break;
|
|
case 'b': mp_add_cs_buf (mp_sys[5].cs_buf, mp_sys[5].cs_len, css, css_pos);
|
|
break;
|
|
case '1': if (mp_usr[0].cs_len == 0) { log_error ("ERROR: Custom-charset 1 is undefined\n"); exit (-1); }
|
|
mp_add_cs_buf (mp_usr[0].cs_buf, mp_usr[0].cs_len, css, css_pos);
|
|
break;
|
|
case '2': if (mp_usr[1].cs_len == 0) { log_error ("ERROR: Custom-charset 2 is undefined\n"); exit (-1); }
|
|
mp_add_cs_buf (mp_usr[1].cs_buf, mp_usr[1].cs_len, css, css_pos);
|
|
break;
|
|
case '3': if (mp_usr[2].cs_len == 0) { log_error ("ERROR: Custom-charset 3 is undefined\n"); exit (-1); }
|
|
mp_add_cs_buf (mp_usr[2].cs_buf, mp_usr[2].cs_len, css, css_pos);
|
|
break;
|
|
case '4': if (mp_usr[3].cs_len == 0) { log_error ("ERROR: Custom-charset 4 is undefined\n"); exit (-1); }
|
|
mp_add_cs_buf (mp_usr[3].cs_buf, mp_usr[3].cs_len, css, css_pos);
|
|
break;
|
|
case '?': mp_add_cs_buf (&chr, 1, css, css_pos);
|
|
break;
|
|
default: log_error ("ERROR: syntax error: %s", mask_buf);
|
|
exit (-1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (data.hex_charset)
|
|
{
|
|
mask_pos++;
|
|
|
|
// if there is no 2nd hex character, show an error:
|
|
|
|
if (mask_pos == mask_len)
|
|
{
|
|
log_error ("ERROR: the hex-charset option always expects couples of exactly 2 hexadecimal chars, failed mask: %s", mask_buf);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
char p1 = mask_buf[mask_pos];
|
|
|
|
// if they are not valid hex character, show an error:
|
|
|
|
if ((is_valid_hex_char (p0) == 0) || (is_valid_hex_char (p1) == 0))
|
|
{
|
|
log_error ("ERROR: invalid hex character detected in mask %s", mask_buf);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
uint chr = 0;
|
|
|
|
chr |= hex_convert (p1) << 0;
|
|
chr |= hex_convert (p0) << 4;
|
|
|
|
mp_add_cs_buf (&chr, 1, css, css_pos);
|
|
}
|
|
else
|
|
{
|
|
uint chr = p0;
|
|
|
|
mp_add_cs_buf (&chr, 1, css, css_pos);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (css_pos == 0)
|
|
{
|
|
log_error ("ERROR: invalid mask length (0)");
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
*css_cnt = css_pos;
|
|
|
|
return (css);
|
|
}
|
|
|
|
void mp_exec (uint64_t val, char *buf, cs_t *css, int css_cnt)
|
|
{
|
|
for (int i = 0; i < css_cnt; i++)
|
|
{
|
|
uint len = css[i].cs_len;
|
|
uint64_t next = val / len;
|
|
uint pos = val % len;
|
|
buf[i] = (char) css[i].cs_buf[pos] & 0xff;
|
|
val = next;
|
|
}
|
|
}
|
|
|
|
void mp_cut_at (char *mask, uint max)
|
|
{
|
|
uint i;
|
|
uint j;
|
|
uint mask_len = strlen (mask);
|
|
|
|
for (i = 0, j = 0; i < mask_len && j < max; i++, j++)
|
|
{
|
|
if (mask[i] == '?') i++;
|
|
}
|
|
|
|
mask[i] = 0;
|
|
}
|
|
|
|
void mp_setup_sys (cs_t *mp_sys)
|
|
{
|
|
uint pos;
|
|
uint chr;
|
|
uint donec[CHARSIZ];
|
|
|
|
memset (donec, 0, sizeof (donec));
|
|
|
|
for (pos = 0, chr = 'a'; chr <= 'z'; chr++) { donec[chr] = 1;
|
|
mp_sys[0].cs_buf[pos++] = chr;
|
|
mp_sys[0].cs_len = pos; }
|
|
|
|
for (pos = 0, chr = 'A'; chr <= 'Z'; chr++) { donec[chr] = 1;
|
|
mp_sys[1].cs_buf[pos++] = chr;
|
|
mp_sys[1].cs_len = pos; }
|
|
|
|
for (pos = 0, chr = '0'; chr <= '9'; chr++) { donec[chr] = 1;
|
|
mp_sys[2].cs_buf[pos++] = chr;
|
|
mp_sys[2].cs_len = pos; }
|
|
|
|
for (pos = 0, chr = 0x20; chr <= 0x7e; chr++) { if (donec[chr]) continue;
|
|
mp_sys[3].cs_buf[pos++] = chr;
|
|
mp_sys[3].cs_len = pos; }
|
|
|
|
for (pos = 0, chr = 0x20; chr <= 0x7e; chr++) { mp_sys[4].cs_buf[pos++] = chr;
|
|
mp_sys[4].cs_len = pos; }
|
|
|
|
for (pos = 0, chr = 0x00; chr <= 0xff; chr++) { mp_sys[5].cs_buf[pos++] = chr;
|
|
mp_sys[5].cs_len = pos; }
|
|
}
|
|
|
|
void mp_setup_usr (cs_t *mp_sys, cs_t *mp_usr, char *buf, uint index)
|
|
{
|
|
FILE *fp = fopen (buf, "rb");
|
|
|
|
if (fp == NULL || feof (fp)) // feof() in case if file is empty
|
|
{
|
|
mp_expand (buf, strlen (buf), mp_sys, mp_usr, index, 1);
|
|
}
|
|
else
|
|
{
|
|
char mp_file[1024];
|
|
|
|
memset (mp_file, 0, sizeof (mp_file));
|
|
|
|
size_t len = fread (mp_file, 1, sizeof (mp_file) - 1, fp);
|
|
|
|
fclose (fp);
|
|
|
|
len = in_superchop (mp_file);
|
|
|
|
if (len == 0)
|
|
{
|
|
log_info ("WARNING: charset file corrupted");
|
|
|
|
mp_expand (buf, strlen (buf), mp_sys, mp_usr, index, 1);
|
|
}
|
|
else
|
|
{
|
|
mp_expand (mp_file, len, mp_sys, mp_usr, index, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void mp_reset_usr (cs_t *mp_usr, uint index)
|
|
{
|
|
mp_usr[index].cs_len = 0;
|
|
|
|
memset (mp_usr[index].cs_buf, 0, sizeof (mp_usr[index].cs_buf));
|
|
}
|
|
|
|
char *mp_get_truncated_mask (char *mask_buf, size_t mask_len, uint len)
|
|
{
|
|
char *new_mask_buf = (char *) mymalloc (256);
|
|
|
|
uint mask_pos;
|
|
|
|
uint css_pos;
|
|
|
|
for (mask_pos = 0, css_pos = 0; mask_pos < mask_len; mask_pos++, css_pos++)
|
|
{
|
|
if (css_pos == len) break;
|
|
|
|
char p0 = mask_buf[mask_pos];
|
|
|
|
new_mask_buf[mask_pos] = p0;
|
|
|
|
if (p0 == '?')
|
|
{
|
|
mask_pos++;
|
|
|
|
if (mask_pos == mask_len) break;
|
|
|
|
new_mask_buf[mask_pos] = mask_buf[mask_pos];
|
|
}
|
|
else
|
|
{
|
|
if (data.hex_charset)
|
|
{
|
|
mask_pos++;
|
|
|
|
if (mask_pos == mask_len)
|
|
{
|
|
log_error ("ERROR: the hex-charset option always expects couples of exactly 2 hexadecimal chars, failed mask: %s", mask_buf);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
char p1 = mask_buf[mask_pos];
|
|
|
|
// if they are not valid hex character, show an error:
|
|
|
|
if ((is_valid_hex_char (p0) == 0) || (is_valid_hex_char (p1) == 0))
|
|
{
|
|
log_error ("ERROR: invalid hex character detected in mask: %s", mask_buf);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
new_mask_buf[mask_pos] = p1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (css_pos == len) return (new_mask_buf);
|
|
|
|
myfree (new_mask_buf);
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
/**
|
|
* statprocessor
|
|
*/
|
|
|
|
uint64_t sp_get_sum (uint start, uint stop, cs_t *root_css_buf)
|
|
{
|
|
uint64_t sum = 1;
|
|
|
|
uint i;
|
|
|
|
for (i = start; i < stop; i++)
|
|
{
|
|
sum *= root_css_buf[i].cs_len;
|
|
}
|
|
|
|
return (sum);
|
|
}
|
|
|
|
void sp_exec (uint64_t ctx, char *pw_buf, cs_t *root_css_buf, cs_t *markov_css_buf, uint start, uint stop)
|
|
{
|
|
uint64_t v = ctx;
|
|
|
|
cs_t *cs = &root_css_buf[start];
|
|
|
|
uint i;
|
|
|
|
for (i = start; i < stop; i++)
|
|
{
|
|
const uint64_t m = v % cs->cs_len;
|
|
const uint64_t d = v / cs->cs_len;
|
|
|
|
v = d;
|
|
|
|
const uint k = cs->cs_buf[m];
|
|
|
|
pw_buf[i - start] = (char) k;
|
|
|
|
cs = &markov_css_buf[(i * CHARSIZ) + k];
|
|
}
|
|
}
|
|
|
|
int sp_comp_val (const void *p1, const void *p2)
|
|
{
|
|
hcstat_table_t *b1 = (hcstat_table_t *) p1;
|
|
hcstat_table_t *b2 = (hcstat_table_t *) p2;
|
|
|
|
return b2->val - b1->val;
|
|
}
|
|
|
|
void sp_setup_tbl (const char *install_dir, char *hcstat, uint disable, uint classic, hcstat_table_t *root_table_buf, hcstat_table_t *markov_table_buf)
|
|
{
|
|
uint i;
|
|
uint j;
|
|
uint k;
|
|
|
|
/**
|
|
* Initialize hcstats
|
|
*/
|
|
|
|
uint64_t *root_stats_buf = (uint64_t *) mycalloc (SP_ROOT_CNT, sizeof (uint64_t));
|
|
|
|
uint64_t *root_stats_ptr = root_stats_buf;
|
|
|
|
uint64_t *root_stats_buf_by_pos[SP_PW_MAX];
|
|
|
|
for (i = 0; i < SP_PW_MAX; i++)
|
|
{
|
|
root_stats_buf_by_pos[i] = root_stats_ptr;
|
|
|
|
root_stats_ptr += CHARSIZ;
|
|
}
|
|
|
|
uint64_t *markov_stats_buf = (uint64_t *) mycalloc (SP_MARKOV_CNT, sizeof (uint64_t));
|
|
|
|
uint64_t *markov_stats_ptr = markov_stats_buf;
|
|
|
|
uint64_t *markov_stats_buf_by_key[SP_PW_MAX][CHARSIZ];
|
|
|
|
for (i = 0; i < SP_PW_MAX; i++)
|
|
{
|
|
for (j = 0; j < CHARSIZ; j++)
|
|
{
|
|
markov_stats_buf_by_key[i][j] = markov_stats_ptr;
|
|
|
|
markov_stats_ptr += CHARSIZ;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load hcstats File
|
|
*/
|
|
|
|
if (hcstat == NULL)
|
|
{
|
|
char hcstat_tmp[256];
|
|
|
|
memset (hcstat_tmp, 0, sizeof (hcstat_tmp));
|
|
|
|
snprintf (hcstat_tmp, sizeof (hcstat_tmp) - 1, "%s/%s", install_dir, SP_HCSTAT);
|
|
|
|
hcstat = hcstat_tmp;
|
|
}
|
|
|
|
FILE *fd = fopen (hcstat, "rb");
|
|
|
|
if (fd == NULL)
|
|
{
|
|
log_error ("%s: %s", hcstat, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
if (fread (root_stats_buf, sizeof (uint64_t), SP_ROOT_CNT, fd) != SP_ROOT_CNT)
|
|
{
|
|
log_error ("%s: Could not load data", hcstat);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
if (fread (markov_stats_buf, sizeof (uint64_t), SP_MARKOV_CNT, fd) != SP_MARKOV_CNT)
|
|
{
|
|
log_error ("%s: Could not load data", hcstat);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
fclose (fd);
|
|
|
|
/**
|
|
* Markov modifier of hcstat_table on user request
|
|
*/
|
|
|
|
if (disable)
|
|
{
|
|
memset (root_stats_buf, 0, SP_ROOT_CNT * sizeof (uint64_t));
|
|
memset (markov_stats_buf, 0, SP_MARKOV_CNT * sizeof (uint64_t));
|
|
}
|
|
|
|
if (classic)
|
|
{
|
|
/* Add all stats to first position */
|
|
|
|
for (i = 1; i < SP_PW_MAX; i++)
|
|
{
|
|
uint64_t *out = root_stats_buf_by_pos[0];
|
|
uint64_t *in = root_stats_buf_by_pos[i];
|
|
|
|
for (j = 0; j < CHARSIZ; j++)
|
|
{
|
|
*out++ += *in++;
|
|
}
|
|
}
|
|
|
|
for (i = 1; i < SP_PW_MAX; i++)
|
|
{
|
|
uint64_t *out = markov_stats_buf_by_key[0][0];
|
|
uint64_t *in = markov_stats_buf_by_key[i][0];
|
|
|
|
for (j = 0; j < CHARSIZ; j++)
|
|
{
|
|
for (k = 0; k < CHARSIZ; k++)
|
|
{
|
|
*out++ += *in++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* copy them to all pw_positions */
|
|
|
|
for (i = 1; i < SP_PW_MAX; i++)
|
|
{
|
|
memcpy (root_stats_buf_by_pos[i], root_stats_buf_by_pos[0], CHARSIZ * sizeof (uint64_t));
|
|
}
|
|
|
|
for (i = 1; i < SP_PW_MAX; i++)
|
|
{
|
|
memcpy (markov_stats_buf_by_key[i][0], markov_stats_buf_by_key[0][0], CHARSIZ * CHARSIZ * sizeof (uint64_t));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialize tables
|
|
*/
|
|
|
|
hcstat_table_t *root_table_ptr = root_table_buf;
|
|
|
|
hcstat_table_t *root_table_buf_by_pos[SP_PW_MAX];
|
|
|
|
for (i = 0; i < SP_PW_MAX; i++)
|
|
{
|
|
root_table_buf_by_pos[i] = root_table_ptr;
|
|
|
|
root_table_ptr += CHARSIZ;
|
|
}
|
|
|
|
hcstat_table_t *markov_table_ptr = markov_table_buf;
|
|
|
|
hcstat_table_t *markov_table_buf_by_key[SP_PW_MAX][CHARSIZ];
|
|
|
|
for (i = 0; i < SP_PW_MAX; i++)
|
|
{
|
|
for (j = 0; j < CHARSIZ; j++)
|
|
{
|
|
markov_table_buf_by_key[i][j] = markov_table_ptr;
|
|
|
|
markov_table_ptr += CHARSIZ;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Convert hcstat to tables
|
|
*/
|
|
|
|
for (i = 0; i < SP_ROOT_CNT; i++)
|
|
{
|
|
uint key = i % CHARSIZ;
|
|
|
|
root_table_buf[i].key = key;
|
|
root_table_buf[i].val = root_stats_buf[i];
|
|
}
|
|
|
|
for (i = 0; i < SP_MARKOV_CNT; i++)
|
|
{
|
|
uint key = i % CHARSIZ;
|
|
|
|
markov_table_buf[i].key = key;
|
|
markov_table_buf[i].val = markov_stats_buf[i];
|
|
}
|
|
|
|
myfree (root_stats_buf);
|
|
myfree (markov_stats_buf);
|
|
|
|
/**
|
|
* Finally sort them
|
|
*/
|
|
|
|
for (i = 0; i < SP_PW_MAX; i++)
|
|
{
|
|
qsort (root_table_buf_by_pos[i], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val);
|
|
}
|
|
|
|
for (i = 0; i < SP_PW_MAX; i++)
|
|
{
|
|
for (j = 0; j < CHARSIZ; j++)
|
|
{
|
|
qsort (markov_table_buf_by_key[i][j], CHARSIZ, sizeof (hcstat_table_t), sp_comp_val);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sp_tbl_to_css (hcstat_table_t *root_table_buf, hcstat_table_t *markov_table_buf, cs_t *root_css_buf, cs_t *markov_css_buf, uint threshold, uint uniq_tbls[SP_PW_MAX][CHARSIZ])
|
|
{
|
|
/**
|
|
* Convert tables to css
|
|
*/
|
|
|
|
for (uint i = 0; i < SP_ROOT_CNT; i++)
|
|
{
|
|
uint pw_pos = i / CHARSIZ;
|
|
|
|
cs_t *cs = &root_css_buf[pw_pos];
|
|
|
|
if (cs->cs_len == threshold) continue;
|
|
|
|
uint key = root_table_buf[i].key;
|
|
|
|
if (uniq_tbls[pw_pos][key] == 0) continue;
|
|
|
|
cs->cs_buf[cs->cs_len] = key;
|
|
|
|
cs->cs_len++;
|
|
}
|
|
|
|
/**
|
|
* Convert table to css
|
|
*/
|
|
|
|
for (uint i = 0; i < SP_MARKOV_CNT; i++)
|
|
{
|
|
uint c = i / CHARSIZ;
|
|
|
|
cs_t *cs = &markov_css_buf[c];
|
|
|
|
if (cs->cs_len == threshold) continue;
|
|
|
|
uint pw_pos = c / CHARSIZ;
|
|
|
|
uint key = markov_table_buf[i].key;
|
|
|
|
if ((pw_pos + 1) < SP_PW_MAX) if (uniq_tbls[pw_pos + 1][key] == 0) continue;
|
|
|
|
cs->cs_buf[cs->cs_len] = key;
|
|
|
|
cs->cs_len++;
|
|
}
|
|
|
|
/*
|
|
for (uint i = 0; i < 8; i++)
|
|
{
|
|
for (uint j = 0x20; j < 0x80; j++)
|
|
{
|
|
cs_t *ptr = &markov_css_buf[(i * CHARSIZ) + j];
|
|
|
|
printf ("pos:%u key:%u len:%u\n", i, j, ptr->cs_len);
|
|
|
|
for (uint k = 0; k < 10; k++)
|
|
{
|
|
printf (" %u\n", ptr->cs_buf[k]);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
void sp_stretch_root (hcstat_table_t *in, hcstat_table_t *out)
|
|
{
|
|
for (uint i = 0; i < SP_PW_MAX; i += 2)
|
|
{
|
|
memcpy (out, in, CHARSIZ * sizeof (hcstat_table_t));
|
|
|
|
out += CHARSIZ;
|
|
in += CHARSIZ;
|
|
|
|
out->key = 0;
|
|
out->val = 1;
|
|
|
|
out++;
|
|
|
|
for (uint j = 1; j < CHARSIZ; j++)
|
|
{
|
|
out->key = j;
|
|
out->val = 0;
|
|
|
|
out++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sp_stretch_markov (hcstat_table_t *in, hcstat_table_t *out)
|
|
{
|
|
for (uint i = 0; i < SP_PW_MAX; i += 2)
|
|
{
|
|
memcpy (out, in, CHARSIZ * CHARSIZ * sizeof (hcstat_table_t));
|
|
|
|
out += CHARSIZ * CHARSIZ;
|
|
in += CHARSIZ * CHARSIZ;
|
|
|
|
for (uint j = 0; j < CHARSIZ; j++)
|
|
{
|
|
out->key = 0;
|
|
out->val = 1;
|
|
|
|
out++;
|
|
|
|
for (uint k = 1; k < CHARSIZ; k++)
|
|
{
|
|
out->key = k;
|
|
out->val = 0;
|
|
|
|
out++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* mixed shared functions
|
|
*/
|
|
|
|
void dump_hex (const char *s, size_t size)
|
|
{
|
|
size_t i;
|
|
|
|
for (i = 0; i < size; i++)
|
|
{
|
|
log_info_nn ("%02x ", (unsigned char) s[i]);
|
|
}
|
|
|
|
log_info ("");
|
|
}
|
|
|
|
void usage_mini_print (const char *progname)
|
|
{
|
|
for (uint i = 0; USAGE_MINI[i] != NULL; i++) log_info (USAGE_MINI[i], progname);
|
|
}
|
|
|
|
void usage_big_print (const char *progname)
|
|
{
|
|
for (uint i = 0; USAGE_BIG[i] != NULL; i++) log_info (USAGE_BIG[i], progname);
|
|
}
|
|
|
|
char *get_install_dir (const char *progname)
|
|
{
|
|
char *install_dir = mystrdup (progname);
|
|
char *last_slash = NULL;
|
|
|
|
if ((last_slash = strrchr (install_dir, '/')) != NULL)
|
|
{
|
|
*last_slash = 0;
|
|
}
|
|
else if ((last_slash = strrchr (install_dir, '\\')) != NULL)
|
|
{
|
|
*last_slash = 0;
|
|
}
|
|
else
|
|
{
|
|
install_dir[0] = '.';
|
|
install_dir[1] = 0;
|
|
}
|
|
|
|
return (install_dir);
|
|
}
|
|
|
|
char *get_profile_dir (const char *homedir)
|
|
{
|
|
#define DOT_HASHCAT ".hashcat"
|
|
|
|
char *profile_dir = (char *) mymalloc (strlen (homedir) + 1 + strlen (DOT_HASHCAT) + 1);
|
|
|
|
sprintf (profile_dir, "%s/%s", homedir, DOT_HASHCAT);
|
|
|
|
return profile_dir;
|
|
}
|
|
|
|
char *get_session_dir (const char *profile_dir, const char *session)
|
|
{
|
|
char *session_dir = (char *) mymalloc (strlen (profile_dir) + 1 + strlen (session) + 1);
|
|
|
|
sprintf (session_dir, "%s/%s", profile_dir, session);
|
|
|
|
return session_dir;
|
|
}
|
|
|
|
void truecrypt_crc32 (char *file, unsigned char keytab[64])
|
|
{
|
|
uint crc = ~0;
|
|
|
|
FILE *fd = fopen (file, "rb");
|
|
|
|
if (fd == NULL)
|
|
{
|
|
log_error ("%s: %s", file, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
#define MAX_KEY_SIZE (1024 * 1024)
|
|
|
|
char *buf = (char *) mymalloc (MAX_KEY_SIZE);
|
|
|
|
int nread = fread (buf, 1, MAX_KEY_SIZE, fd);
|
|
|
|
int kpos = 0;
|
|
|
|
for (int fpos = 0; fpos < nread; fpos++)
|
|
{
|
|
crc = crc32tab[(crc ^ buf[fpos]) & 0xff] ^ (crc >> 8);
|
|
|
|
keytab[kpos++] += (crc >> 24) & 0xff;
|
|
keytab[kpos++] += (crc >> 16) & 0xff;
|
|
keytab[kpos++] += (crc >> 8) & 0xff;
|
|
keytab[kpos++] += (crc >> 0) & 0xff;
|
|
|
|
if (kpos >= 64) kpos = 0;
|
|
}
|
|
|
|
myfree (buf);
|
|
|
|
fclose(fd);
|
|
}
|
|
|
|
void set_cpu_affinity (char *cpu_affinity)
|
|
{
|
|
#ifdef WIN
|
|
DWORD_PTR aff_mask = 0;
|
|
#endif
|
|
|
|
#ifdef LINUX
|
|
cpu_set_t cpuset;
|
|
|
|
CPU_ZERO (&cpuset);
|
|
#endif
|
|
|
|
if (cpu_affinity)
|
|
{
|
|
char *devices = strdup (cpu_affinity);
|
|
|
|
char *next = strtok (devices, ",");
|
|
|
|
do
|
|
{
|
|
uint cpu_id = atoi (next);
|
|
|
|
if (cpu_id == 0)
|
|
{
|
|
#ifdef WIN
|
|
aff_mask = 0;
|
|
#endif
|
|
|
|
#ifdef LINUX
|
|
CPU_ZERO (&cpuset);
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
|
|
if (cpu_id > 32)
|
|
{
|
|
log_error ("ERROR: invalid cpu_id %u specified", cpu_id);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
#ifdef WIN
|
|
aff_mask |= 1 << (cpu_id - 1);
|
|
#endif
|
|
|
|
#ifdef LINUX
|
|
CPU_SET ((cpu_id - 1), &cpuset);
|
|
#endif
|
|
|
|
} while ((next = strtok (NULL, ",")) != NULL);
|
|
|
|
free (devices);
|
|
}
|
|
|
|
#ifdef WIN
|
|
SetProcessAffinityMask (GetCurrentProcess (), aff_mask);
|
|
SetThreadAffinityMask (GetCurrentThread (), aff_mask);
|
|
#endif
|
|
|
|
#ifdef LINUX
|
|
pthread_t thread = pthread_self ();
|
|
pthread_setaffinity_np (thread, sizeof (cpu_set_t), &cpuset);
|
|
#endif
|
|
}
|
|
|
|
void *rulefind (const void *key, void *base, int nmemb, size_t size, int (*compar) (const void *, const void *))
|
|
{
|
|
char *element, *end;
|
|
|
|
end = (char *) base + nmemb * size;
|
|
|
|
for (element = (char *) base; element < end; element += size)
|
|
if (!compar (element, key))
|
|
return element;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int sort_by_salt (const void *v1, const void *v2)
|
|
{
|
|
const salt_t *s1 = (const salt_t *) v1;
|
|
const salt_t *s2 = (const salt_t *) v2;
|
|
|
|
const int res1 = s1->salt_len - s2->salt_len;
|
|
|
|
if (res1 != 0) return (res1);
|
|
|
|
const int res2 = s1->salt_iter - s2->salt_iter;
|
|
|
|
if (res2 != 0) return (res2);
|
|
|
|
uint n;
|
|
|
|
n = 12;
|
|
|
|
while (n--)
|
|
{
|
|
if (s1->salt_buf[n] > s2->salt_buf[n]) return ( 1);
|
|
if (s1->salt_buf[n] < s2->salt_buf[n]) return (-1);
|
|
}
|
|
|
|
n = 8;
|
|
|
|
while (n--)
|
|
{
|
|
if (s1->salt_buf_pc[n] > s2->salt_buf_pc[n]) return ( 1);
|
|
if (s1->salt_buf_pc[n] < s2->salt_buf_pc[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_salt_buf (const void *v1, const void *v2)
|
|
{
|
|
const pot_t *p1 = (const pot_t *) v1;
|
|
const pot_t *p2 = (const pot_t *) v2;
|
|
|
|
const hash_t *h1 = &p1->hash;
|
|
const hash_t *h2 = &p2->hash;
|
|
|
|
const salt_t *s1 = h1->salt;
|
|
const salt_t *s2 = h2->salt;
|
|
|
|
uint n = 12;
|
|
|
|
while (n--)
|
|
{
|
|
if (s1->salt_buf[n] > s2->salt_buf[n]) return ( 1);
|
|
if (s1->salt_buf[n] < s2->salt_buf[n]) return (-1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sort_by_hash_t_salt (const void *v1, const void *v2)
|
|
{
|
|
const hash_t *h1 = (const hash_t *) v1;
|
|
const hash_t *h2 = (const hash_t *) v2;
|
|
|
|
const salt_t *s1 = h1->salt;
|
|
const salt_t *s2 = h2->salt;
|
|
|
|
// testphase: this should work
|
|
uint n = 12;
|
|
|
|
while (n--)
|
|
{
|
|
if (s1->salt_buf[n] > s2->salt_buf[n]) return ( 1);
|
|
if (s1->salt_buf[n] < s2->salt_buf[n]) return (-1);
|
|
}
|
|
|
|
/* original code, seems buggy since salt_len can be very big (had a case with 131 len)
|
|
also it thinks salt_buf[x] is a char but its a uint so salt_len should be / 4
|
|
if (s1->salt_len > s2->salt_len) return ( 1);
|
|
if (s1->salt_len < s2->salt_len) return (-1);
|
|
|
|
uint n = s1->salt_len;
|
|
|
|
while (n--)
|
|
{
|
|
if (s1->salt_buf[n] > s2->salt_buf[n]) return ( 1);
|
|
if (s1->salt_buf[n] < s2->salt_buf[n]) return (-1);
|
|
}
|
|
*/
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sort_by_hash_t_salt_hccap (const void *v1, const void *v2)
|
|
{
|
|
const hash_t *h1 = (const hash_t *) v1;
|
|
const hash_t *h2 = (const hash_t *) v2;
|
|
|
|
const salt_t *s1 = h1->salt;
|
|
const salt_t *s2 = h2->salt;
|
|
|
|
// 12 - 2 (since last 2 uints contain the digest)
|
|
uint n = 10;
|
|
|
|
while (n--)
|
|
{
|
|
if (s1->salt_buf[n] > s2->salt_buf[n]) return ( 1);
|
|
if (s1->salt_buf[n] < s2->salt_buf[n]) return (-1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sort_by_hash_no_salt (const void *v1, const void *v2)
|
|
{
|
|
const hash_t *h1 = (const hash_t *) v1;
|
|
const hash_t *h2 = (const hash_t *) v2;
|
|
|
|
const void *d1 = h1->digest;
|
|
const void *d2 = h2->digest;
|
|
|
|
return data.sort_by_digest (d1, d2);
|
|
}
|
|
|
|
int sort_by_hash (const void *v1, const void *v2)
|
|
{
|
|
const hash_t *h1 = (const hash_t *) v1;
|
|
const hash_t *h2 = (const hash_t *) v2;
|
|
|
|
if (data.isSalted)
|
|
{
|
|
const salt_t *s1 = h1->salt;
|
|
const salt_t *s2 = h2->salt;
|
|
|
|
int res = sort_by_salt (s1, s2);
|
|
|
|
if (res != 0) return (res);
|
|
}
|
|
|
|
const void *d1 = h1->digest;
|
|
const void *d2 = h2->digest;
|
|
|
|
return data.sort_by_digest (d1, d2);
|
|
}
|
|
|
|
int sort_by_pot (const void *v1, const void *v2)
|
|
{
|
|
const pot_t *p1 = (const pot_t *) v1;
|
|
const pot_t *p2 = (const pot_t *) v2;
|
|
|
|
const hash_t *h1 = &p1->hash;
|
|
const hash_t *h2 = &p2->hash;
|
|
|
|
return sort_by_hash (h1, h2);
|
|
}
|
|
|
|
int sort_by_mtime (const void *p1, const void *p2)
|
|
{
|
|
const char **f1 = (const char **) p1;
|
|
const char **f2 = (const char **) p2;
|
|
|
|
struct stat s1; stat (*f1, &s1);
|
|
struct stat s2; stat (*f2, &s2);
|
|
|
|
return s2.st_mtime - s1.st_mtime;
|
|
}
|
|
|
|
int sort_by_cpu_rule (const void *p1, const void *p2)
|
|
{
|
|
const cpu_rule_t *r1 = (const cpu_rule_t *) p1;
|
|
const cpu_rule_t *r2 = (const cpu_rule_t *) p2;
|
|
|
|
return memcmp (r1, r2, sizeof (cpu_rule_t));
|
|
}
|
|
|
|
int sort_by_gpu_rule (const void *p1, const void *p2)
|
|
{
|
|
const gpu_rule_t *r1 = (const gpu_rule_t *) p1;
|
|
const gpu_rule_t *r2 = (const gpu_rule_t *) p2;
|
|
|
|
return memcmp (r1, r2, sizeof (gpu_rule_t));
|
|
}
|
|
|
|
int sort_by_stringptr (const void *p1, const void *p2)
|
|
{
|
|
const char **s1 = (const char **) p1;
|
|
const char **s2 = (const char **) p2;
|
|
|
|
return strcmp (*s1, *s2);
|
|
}
|
|
|
|
int sort_by_dictstat (const void *s1, const void *s2)
|
|
{
|
|
dictstat_t *d1 = (dictstat_t *) s1;
|
|
dictstat_t *d2 = (dictstat_t *) s2;
|
|
|
|
#ifdef _POSIX
|
|
d2->stat.st_atim = d1->stat.st_atim;
|
|
#else
|
|
d2->stat.st_atime = d1->stat.st_atime;
|
|
#endif
|
|
|
|
return memcmp (&d1->stat, &d2->stat, sizeof (struct stat));
|
|
}
|
|
|
|
int sort_by_bitmap (const void *p1, const void *p2)
|
|
{
|
|
const bitmap_result_t *b1 = (const bitmap_result_t *) p1;
|
|
const bitmap_result_t *b2 = (const bitmap_result_t *) p2;
|
|
|
|
return b1->collisions - b2->collisions;
|
|
}
|
|
|
|
int sort_by_digest_4_2 (const void *v1, const void *v2)
|
|
{
|
|
const uint32_t *d1 = (const uint32_t *) v1;
|
|
const uint32_t *d2 = (const uint32_t *) v2;
|
|
|
|
uint n = 2;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_4_4 (const void *v1, const void *v2)
|
|
{
|
|
const uint32_t *d1 = (const uint32_t *) v1;
|
|
const uint32_t *d2 = (const uint32_t *) v2;
|
|
|
|
uint n = 4;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_4_5 (const void *v1, const void *v2)
|
|
{
|
|
const uint32_t *d1 = (const uint32_t *) v1;
|
|
const uint32_t *d2 = (const uint32_t *) v2;
|
|
|
|
uint n = 5;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_4_6 (const void *v1, const void *v2)
|
|
{
|
|
const uint32_t *d1 = (const uint32_t *) v1;
|
|
const uint32_t *d2 = (const uint32_t *) v2;
|
|
|
|
uint n = 6;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_4_8 (const void *v1, const void *v2)
|
|
{
|
|
const uint32_t *d1 = (const uint32_t *) v1;
|
|
const uint32_t *d2 = (const uint32_t *) v2;
|
|
|
|
uint n = 8;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_4_16 (const void *v1, const void *v2)
|
|
{
|
|
const uint32_t *d1 = (const uint32_t *) v1;
|
|
const uint32_t *d2 = (const uint32_t *) v2;
|
|
|
|
uint n = 16;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_4_32 (const void *v1, const void *v2)
|
|
{
|
|
const uint32_t *d1 = (const uint32_t *) v1;
|
|
const uint32_t *d2 = (const uint32_t *) v2;
|
|
|
|
uint n = 32;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_4_64 (const void *v1, const void *v2)
|
|
{
|
|
const uint32_t *d1 = (const uint32_t *) v1;
|
|
const uint32_t *d2 = (const uint32_t *) v2;
|
|
|
|
uint n = 64;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_8_8 (const void *v1, const void *v2)
|
|
{
|
|
const uint64_t *d1 = (const uint64_t *) v1;
|
|
const uint64_t *d2 = (const uint64_t *) v2;
|
|
|
|
uint n = 8;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_8_16 (const void *v1, const void *v2)
|
|
{
|
|
const uint64_t *d1 = (const uint64_t *) v1;
|
|
const uint64_t *d2 = (const uint64_t *) v2;
|
|
|
|
uint n = 16;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_8_25 (const void *v1, const void *v2)
|
|
{
|
|
const uint64_t *d1 = (const uint64_t *) v1;
|
|
const uint64_t *d2 = (const uint64_t *) v2;
|
|
|
|
uint n = 25;
|
|
|
|
while (n--)
|
|
{
|
|
if (d1[n] > d2[n]) return ( 1);
|
|
if (d1[n] < d2[n]) return (-1);
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
int sort_by_digest_p0p1 (const void *v1, const void *v2)
|
|
{
|
|
const uint32_t *d1 = (const uint32_t *) v1;
|
|
const uint32_t *d2 = (const uint32_t *) v2;
|
|
|
|
const uint dgst_pos0 = data.dgst_pos0;
|
|
const uint dgst_pos1 = data.dgst_pos1;
|
|
const uint dgst_pos2 = data.dgst_pos2;
|
|
const uint dgst_pos3 = data.dgst_pos3;
|
|
|
|
if (d1[dgst_pos3] > d2[dgst_pos3]) return ( 1);
|
|
if (d1[dgst_pos3] < d2[dgst_pos3]) return (-1);
|
|
if (d1[dgst_pos2] > d2[dgst_pos2]) return ( 1);
|
|
if (d1[dgst_pos2] < d2[dgst_pos2]) return (-1);
|
|
if (d1[dgst_pos1] > d2[dgst_pos1]) return ( 1);
|
|
if (d1[dgst_pos1] < d2[dgst_pos1]) return (-1);
|
|
if (d1[dgst_pos0] > d2[dgst_pos0]) return ( 1);
|
|
if (d1[dgst_pos0] < d2[dgst_pos0]) return (-1);
|
|
|
|
return (0);
|
|
}
|
|
|
|
void format_debug (char * debug_file, uint debug_mode, unsigned char *orig_plain_ptr, uint orig_plain_len, unsigned char *mod_plain_ptr, uint mod_plain_len, char *rule_buf, int rule_len)
|
|
{
|
|
uint outfile_autohex = data.outfile_autohex;
|
|
|
|
unsigned char *rule_ptr = (unsigned char *) rule_buf;
|
|
|
|
FILE *debug_fp = NULL;
|
|
|
|
if (debug_file != NULL)
|
|
{
|
|
debug_fp = fopen (debug_file, "ab");
|
|
}
|
|
else
|
|
{
|
|
debug_fp = stderr;
|
|
}
|
|
|
|
if (debug_fp == NULL)
|
|
{
|
|
log_info ("WARNING: Could not open debug-file for writing");
|
|
}
|
|
else
|
|
{
|
|
if ((debug_mode == 2) || (debug_mode == 3) || (debug_mode == 4))
|
|
{
|
|
format_plain (debug_fp, orig_plain_ptr, orig_plain_len, outfile_autohex);
|
|
|
|
if ((debug_mode == 3) || (debug_mode == 4)) fputc (':', debug_fp);
|
|
}
|
|
|
|
fwrite (rule_ptr, rule_len, 1, debug_fp);
|
|
|
|
if (debug_mode == 4)
|
|
{
|
|
fputc (':', debug_fp);
|
|
|
|
format_plain (debug_fp, mod_plain_ptr, mod_plain_len, outfile_autohex);
|
|
}
|
|
|
|
fputc ('\n', debug_fp);
|
|
|
|
if (debug_file != NULL) fclose (debug_fp);
|
|
}
|
|
}
|
|
|
|
void format_plain (FILE *fp, unsigned char *plain_ptr, uint plain_len, uint outfile_autohex)
|
|
{
|
|
int needs_hexify = 0;
|
|
|
|
if (outfile_autohex == 1)
|
|
{
|
|
for (uint i = 0; i < plain_len; i++)
|
|
{
|
|
if (plain_ptr[i] < 0x20)
|
|
{
|
|
needs_hexify = 1;
|
|
|
|
break;
|
|
}
|
|
|
|
if (plain_ptr[i] > 0x7f)
|
|
{
|
|
needs_hexify = 1;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (needs_hexify == 1)
|
|
{
|
|
fprintf (fp, "$HEX[");
|
|
|
|
for (uint i = 0; i < plain_len; i++)
|
|
{
|
|
fprintf (fp, "%02x", plain_ptr[i]);
|
|
}
|
|
|
|
fprintf (fp, "]");
|
|
}
|
|
else
|
|
{
|
|
fwrite (plain_ptr, plain_len, 1, fp);
|
|
}
|
|
}
|
|
|
|
void format_output (FILE *out_fp, char *out_buf, unsigned char *plain_ptr, const uint plain_len, const uint64_t crackpos, unsigned char *username, const uint user_len)
|
|
{
|
|
uint outfile_format = data.outfile_format;
|
|
|
|
char separator = data.separator;
|
|
|
|
if (outfile_format & OUTFILE_FMT_HASH)
|
|
{
|
|
fprintf (out_fp, "%s", out_buf);
|
|
|
|
if (outfile_format & (OUTFILE_FMT_PLAIN | OUTFILE_FMT_HEXPLAIN | OUTFILE_FMT_CRACKPOS))
|
|
{
|
|
fputc (separator, out_fp);
|
|
}
|
|
}
|
|
else if (data.username)
|
|
{
|
|
if (username != NULL)
|
|
{
|
|
for (uint i = 0; i < user_len; i++)
|
|
{
|
|
fprintf (out_fp, "%c", username[i]);
|
|
}
|
|
|
|
if (outfile_format & (OUTFILE_FMT_PLAIN | OUTFILE_FMT_HEXPLAIN | OUTFILE_FMT_CRACKPOS))
|
|
{
|
|
fputc (separator, out_fp);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (outfile_format & OUTFILE_FMT_PLAIN)
|
|
{
|
|
format_plain (out_fp, plain_ptr, plain_len, data.outfile_autohex);
|
|
|
|
if (outfile_format & (OUTFILE_FMT_HEXPLAIN | OUTFILE_FMT_CRACKPOS))
|
|
{
|
|
fputc (separator, out_fp);
|
|
}
|
|
}
|
|
|
|
if (outfile_format & OUTFILE_FMT_HEXPLAIN)
|
|
{
|
|
for (uint i = 0; i < plain_len; i++)
|
|
{
|
|
fprintf (out_fp, "%02x", plain_ptr[i]);
|
|
}
|
|
|
|
if (outfile_format & (OUTFILE_FMT_CRACKPOS))
|
|
{
|
|
fputc (separator, out_fp);
|
|
}
|
|
}
|
|
|
|
if (outfile_format & OUTFILE_FMT_CRACKPOS)
|
|
{
|
|
#ifdef _WIN
|
|
__mingw_fprintf (out_fp, "%llu", crackpos);
|
|
#endif
|
|
|
|
#ifdef _POSIX
|
|
#ifdef __x86_64__
|
|
fprintf (out_fp, "%lu", crackpos);
|
|
#else
|
|
fprintf (out_fp, "%llu", crackpos);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
fputc ('\n', out_fp);
|
|
}
|
|
|
|
void handle_show_request (pot_t *pot, uint pot_cnt, char *input_buf, int input_len, hash_t *hashes_buf, int (*sort_by_pot) (const void *, const void *), FILE *out_fp)
|
|
{
|
|
pot_t pot_key;
|
|
|
|
pot_key.hash.salt = hashes_buf->salt;
|
|
pot_key.hash.digest = hashes_buf->digest;
|
|
|
|
pot_t *pot_ptr = (pot_t *) bsearch (&pot_key, pot, pot_cnt, sizeof (pot_t), sort_by_pot);
|
|
|
|
if (pot_ptr)
|
|
{
|
|
log_info_nn ("");
|
|
|
|
input_buf[input_len] = 0;
|
|
|
|
// user
|
|
unsigned char *username = NULL;
|
|
uint user_len = 0;
|
|
|
|
if (data.username)
|
|
{
|
|
user_t *user = hashes_buf->hash_info->user;
|
|
|
|
if (user)
|
|
{
|
|
username = (unsigned char *) (user->user_name);
|
|
|
|
user_len = user->user_len;
|
|
}
|
|
}
|
|
|
|
// do output the line
|
|
format_output (out_fp, input_buf, (unsigned char *) pot_ptr->plain_buf, pot_ptr->plain_len, 0, username, user_len);
|
|
}
|
|
}
|
|
|
|
#define LM_WEAK_HASH "\x4e\xcf\x0d\x0c\x0a\xe2\xfb\xc1"
|
|
#define LM_MASKED_PLAIN "[notfound]"
|
|
|
|
void handle_show_request_lm (pot_t *pot, uint pot_cnt, char *input_buf, int input_len, hash_t *hash_left, hash_t *hash_right, int (*sort_by_pot) (const void *, const void *), FILE *out_fp)
|
|
{
|
|
// left
|
|
|
|
pot_t pot_left_key;
|
|
|
|
pot_left_key.hash.salt = hash_left->salt;
|
|
pot_left_key.hash.digest = hash_left->digest;
|
|
|
|
pot_t *pot_left_ptr = (pot_t *) bsearch (&pot_left_key, pot, pot_cnt, sizeof (pot_t), sort_by_pot);
|
|
|
|
// right
|
|
|
|
uint weak_hash_found = 0;
|
|
|
|
pot_t pot_right_key;
|
|
|
|
pot_right_key.hash.salt = hash_right->salt;
|
|
pot_right_key.hash.digest = hash_right->digest;
|
|
|
|
pot_t *pot_right_ptr = (pot_t *) bsearch (&pot_right_key, pot, pot_cnt, sizeof (pot_t), sort_by_pot);
|
|
|
|
if (pot_right_ptr == NULL)
|
|
{
|
|
// special case, if "weak hash"
|
|
|
|
if (memcmp (hash_right->digest, LM_WEAK_HASH, 8) == 0)
|
|
{
|
|
weak_hash_found = 1;
|
|
|
|
pot_right_ptr = (pot_t *) mycalloc (1, sizeof (pot_t));
|
|
|
|
// in theory this is not needed, but we are paranoia:
|
|
|
|
memset (pot_right_ptr->plain_buf, 0, sizeof (pot_right_ptr->plain_buf));
|
|
pot_right_ptr->plain_len = 0;
|
|
}
|
|
}
|
|
|
|
if ((pot_left_ptr == NULL) && (pot_right_ptr == NULL))
|
|
{
|
|
if (weak_hash_found == 1) myfree (pot_right_ptr); // this shouldn't happen at all: if weak_hash_found == 1, than pot_right_ptr is not NULL for sure
|
|
|
|
return;
|
|
}
|
|
|
|
// at least one half was found:
|
|
|
|
log_info_nn ("");
|
|
|
|
input_buf[input_len] = 0;
|
|
|
|
// user
|
|
|
|
unsigned char *username = NULL;
|
|
uint user_len = 0;
|
|
|
|
if (data.username)
|
|
{
|
|
user_t *user = hash_left->hash_info->user;
|
|
|
|
if (user)
|
|
{
|
|
username = (unsigned char *) (user->user_name);
|
|
|
|
user_len = user->user_len;
|
|
}
|
|
}
|
|
|
|
// mask the part which was not found
|
|
|
|
uint left_part_masked = 0;
|
|
uint right_part_masked = 0;
|
|
|
|
uint mask_plain_len = strlen (LM_MASKED_PLAIN);
|
|
|
|
if (pot_left_ptr == NULL)
|
|
{
|
|
left_part_masked = 1;
|
|
|
|
pot_left_ptr = (pot_t *) mycalloc (1, sizeof (pot_t));
|
|
|
|
memset (pot_left_ptr->plain_buf, 0, sizeof (pot_left_ptr->plain_buf));
|
|
|
|
memcpy (pot_left_ptr->plain_buf, LM_MASKED_PLAIN, mask_plain_len);
|
|
pot_left_ptr->plain_len = mask_plain_len;
|
|
}
|
|
|
|
if (pot_right_ptr == NULL)
|
|
{
|
|
right_part_masked = 1;
|
|
|
|
pot_right_ptr = (pot_t *) mycalloc (1, sizeof (pot_t));
|
|
|
|
memset (pot_right_ptr->plain_buf, 0, sizeof (pot_right_ptr->plain_buf));
|
|
|
|
memcpy (pot_right_ptr->plain_buf, LM_MASKED_PLAIN, mask_plain_len);
|
|
pot_right_ptr->plain_len = mask_plain_len;
|
|
}
|
|
|
|
// create the pot_ptr out of pot_left_ptr and pot_right_ptr
|
|
|
|
pot_t pot_ptr;
|
|
|
|
pot_ptr.plain_len = pot_left_ptr->plain_len + pot_right_ptr->plain_len;
|
|
|
|
memcpy (pot_ptr.plain_buf, pot_left_ptr->plain_buf, pot_left_ptr->plain_len);
|
|
|
|
memcpy (pot_ptr.plain_buf + pot_left_ptr->plain_len, pot_right_ptr->plain_buf, pot_right_ptr->plain_len);
|
|
|
|
// do output the line
|
|
|
|
format_output (out_fp, input_buf, (unsigned char *) pot_ptr.plain_buf, pot_ptr.plain_len, 0, username, user_len);
|
|
|
|
if (weak_hash_found == 1) myfree (pot_right_ptr);
|
|
|
|
if (left_part_masked == 1) myfree (pot_left_ptr);
|
|
if (right_part_masked == 1) myfree (pot_right_ptr);
|
|
}
|
|
|
|
void handle_left_request (pot_t *pot, uint pot_cnt, char *input_buf, int input_len, hash_t *hashes_buf, int (*sort_by_pot) (const void *, const void *), FILE *out_fp)
|
|
{
|
|
pot_t pot_key;
|
|
|
|
memcpy (&pot_key.hash, hashes_buf, sizeof (hash_t));
|
|
|
|
pot_t *pot_ptr = (pot_t *) bsearch (&pot_key, pot, pot_cnt, sizeof (pot_t), sort_by_pot);
|
|
|
|
if (pot_ptr == NULL)
|
|
{
|
|
log_info_nn ("");
|
|
|
|
input_buf[input_len] = 0;
|
|
|
|
format_output (out_fp, input_buf, NULL, 0, 0, NULL, 0);
|
|
}
|
|
}
|
|
|
|
void handle_left_request_lm (pot_t *pot, uint pot_cnt, char *input_buf, int input_len, hash_t *hash_left, hash_t *hash_right, int (*sort_by_pot) (const void *, const void *), FILE *out_fp)
|
|
{
|
|
// left
|
|
|
|
pot_t pot_left_key;
|
|
|
|
memcpy (&pot_left_key.hash, hash_left, sizeof (hash_t));
|
|
|
|
pot_t *pot_left_ptr = (pot_t *) bsearch (&pot_left_key, pot, pot_cnt, sizeof (pot_t), sort_by_pot);
|
|
|
|
// right
|
|
|
|
pot_t pot_right_key;
|
|
|
|
memcpy (&pot_right_key.hash, hash_right, sizeof (hash_t));
|
|
|
|
pot_t *pot_right_ptr = (pot_t *) bsearch (&pot_right_key, pot, pot_cnt, sizeof (pot_t), sort_by_pot);
|
|
|
|
uint weak_hash_found = 0;
|
|
|
|
if (pot_right_ptr == NULL)
|
|
{
|
|
// special case, if "weak hash"
|
|
|
|
if (memcmp (hash_right->digest, LM_WEAK_HASH, 8) == 0)
|
|
{
|
|
weak_hash_found = 1;
|
|
|
|
// we just need that pot_right_ptr is not a NULL pointer
|
|
|
|
pot_right_ptr = (pot_t *) mycalloc (1, sizeof (pot_t));
|
|
}
|
|
}
|
|
|
|
if ((pot_left_ptr != NULL) && (pot_right_ptr != NULL))
|
|
{
|
|
if (weak_hash_found == 1) myfree (pot_right_ptr);
|
|
|
|
return;
|
|
}
|
|
|
|
// ... at least one part was not cracked
|
|
|
|
log_info_nn ("");
|
|
|
|
input_buf[input_len] = 0;
|
|
|
|
// only show the hash part which is still not cracked
|
|
|
|
uint user_len = input_len - 32;
|
|
|
|
char hash_output[user_len + 33];
|
|
|
|
memset (hash_output, 0, sizeof (hash_output));
|
|
|
|
memcpy (hash_output, input_buf, input_len);
|
|
|
|
if (pot_left_ptr != NULL)
|
|
{
|
|
// only show right part (because left part was already found)
|
|
|
|
memcpy (hash_output + user_len, input_buf + user_len + 16, 16);
|
|
|
|
hash_output[user_len + 16] = 0;
|
|
}
|
|
|
|
if (pot_right_ptr != NULL)
|
|
{
|
|
// only show left part (because right part was already found)
|
|
|
|
memcpy (hash_output + user_len, input_buf + user_len, 16);
|
|
|
|
hash_output[user_len + 16] = 0;
|
|
}
|
|
|
|
format_output (out_fp, hash_output, NULL, 0, 0, NULL, 0);
|
|
|
|
if (weak_hash_found == 1) myfree (pot_right_ptr);
|
|
}
|
|
|
|
uint devices_to_devicemask (char *gpu_devices)
|
|
{
|
|
uint gpu_devicemask = 0;
|
|
|
|
if (gpu_devices)
|
|
{
|
|
char *devices = strdup (gpu_devices);
|
|
|
|
char *next = strtok (devices, ",");
|
|
|
|
do
|
|
{
|
|
uint gpu_id = atoi (next);
|
|
|
|
if (gpu_id < 1 || gpu_id > 8)
|
|
{
|
|
log_error ("ERROR: invalid gpu_id %u specified", gpu_id);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
gpu_devicemask |= 1 << (gpu_id - 1);
|
|
|
|
} while ((next = strtok (NULL, ",")) != NULL);
|
|
|
|
free (devices);
|
|
}
|
|
|
|
return gpu_devicemask;
|
|
}
|
|
|
|
uint get_random_num (uint min, uint max)
|
|
{
|
|
if (min == max) return (min);
|
|
|
|
return (uint) ((rand () % (max - min)) + min);
|
|
}
|
|
|
|
uint32_t mydivc32 (const uint32_t dividend, const uint32_t divisor)
|
|
{
|
|
uint32_t quotient = dividend / divisor;
|
|
|
|
if (dividend % divisor) quotient++;
|
|
|
|
return quotient;
|
|
}
|
|
|
|
uint64_t mydivc64 (const uint64_t dividend, const uint64_t divisor)
|
|
{
|
|
uint64_t quotient = dividend / divisor;
|
|
|
|
if (dividend % divisor) quotient++;
|
|
|
|
return quotient;
|
|
}
|
|
|
|
void format_timer_display (struct tm *tm, char *buf, size_t len)
|
|
{
|
|
const char *time_entities_s[] = { "year", "day", "hour", "min", "sec" };
|
|
const char *time_entities_m[] = { "years", "days", "hours", "mins", "secs" };
|
|
|
|
if (tm->tm_year - 70)
|
|
{
|
|
char *time_entity1 = ((tm->tm_year - 70) == 1) ? (char *) time_entities_s[0] : (char *) time_entities_m[0];
|
|
char *time_entity2 = ( tm->tm_yday == 1) ? (char *) time_entities_s[1] : (char *) time_entities_m[1];
|
|
|
|
snprintf (buf, len - 1, "%d %s, %d %s", tm->tm_year - 70, time_entity1, tm->tm_yday, time_entity2);
|
|
}
|
|
else if (tm->tm_yday)
|
|
{
|
|
char *time_entity1 = (tm->tm_yday == 1) ? (char *) time_entities_s[1] : (char *) time_entities_m[1];
|
|
char *time_entity2 = (tm->tm_hour == 1) ? (char *) time_entities_s[2] : (char *) time_entities_m[2];
|
|
|
|
snprintf (buf, len - 1, "%d %s, %d %s", tm->tm_yday, time_entity1, tm->tm_hour, time_entity2);
|
|
}
|
|
else if (tm->tm_hour)
|
|
{
|
|
char *time_entity1 = (tm->tm_hour == 1) ? (char *) time_entities_s[2] : (char *) time_entities_m[2];
|
|
char *time_entity2 = (tm->tm_min == 1) ? (char *) time_entities_s[3] : (char *) time_entities_m[3];
|
|
|
|
snprintf (buf, len - 1, "%d %s, %d %s", tm->tm_hour, time_entity1, tm->tm_min, time_entity2);
|
|
}
|
|
else if (tm->tm_min)
|
|
{
|
|
char *time_entity1 = (tm->tm_min == 1) ? (char *) time_entities_s[3] : (char *) time_entities_m[3];
|
|
char *time_entity2 = (tm->tm_sec == 1) ? (char *) time_entities_s[4] : (char *) time_entities_m[4];
|
|
|
|
snprintf (buf, len - 1, "%d %s, %d %s", tm->tm_min, time_entity1, tm->tm_sec, time_entity2);
|
|
}
|
|
else
|
|
{
|
|
char *time_entity1 = (tm->tm_sec == 1) ? (char *) time_entities_s[4] : (char *) time_entities_m[4];
|
|
|
|
snprintf (buf, len - 1, "%d %s", tm->tm_sec, time_entity1);
|
|
}
|
|
}
|
|
|
|
void format_speed_display (float val, char *buf, size_t len)
|
|
{
|
|
if (val <= 0)
|
|
{
|
|
buf[0] = '0';
|
|
buf[1] = ' ';
|
|
buf[2] = 0;
|
|
|
|
return;
|
|
}
|
|
|
|
char units[7] = { ' ', 'k', 'M', 'G', 'T', 'P', 'E' };
|
|
|
|
uint level = 0;
|
|
|
|
while (val > 99999)
|
|
{
|
|
val /= 1000;
|
|
|
|
level++;
|
|
}
|
|
|
|
/* generate output */
|
|
|
|
if (level == 0)
|
|
{
|
|
snprintf (buf, len - 1, "%.0f ", val);
|
|
}
|
|
else
|
|
{
|
|
snprintf (buf, len - 1, "%.1f %c", val, units[level]);
|
|
}
|
|
}
|
|
|
|
void lowercase (char *buf, int len)
|
|
{
|
|
for (int i = 0; i < len; i++) buf[i] = tolower (buf[i]);
|
|
}
|
|
|
|
void uppercase (char *buf, int len)
|
|
{
|
|
for (int i = 0; i < len; i++) buf[i] = toupper (buf[i]);
|
|
}
|
|
|
|
int fgetl (FILE *fp, char *line_buf)
|
|
{
|
|
int line_len = 0;
|
|
|
|
while (!feof (fp))
|
|
{
|
|
const int c = fgetc (fp);
|
|
|
|
if (c == EOF) break;
|
|
|
|
line_buf[line_len] = (char) c;
|
|
|
|
line_len++;
|
|
|
|
if (line_len == BUFSIZ) line_len--;
|
|
|
|
if (c == '\n') break;
|
|
}
|
|
|
|
if (line_len == 0) return 0;
|
|
|
|
if (line_buf[line_len - 1] == '\n')
|
|
{
|
|
line_len--;
|
|
|
|
line_buf[line_len] = 0;
|
|
}
|
|
|
|
if (line_len == 0) return 0;
|
|
|
|
if (line_buf[line_len - 1] == '\r')
|
|
{
|
|
line_len--;
|
|
|
|
line_buf[line_len] = 0;
|
|
}
|
|
|
|
return (line_len);
|
|
}
|
|
|
|
int in_superchop (char *buf)
|
|
{
|
|
int len = strlen (buf);
|
|
|
|
while (len)
|
|
{
|
|
if (buf[len - 1] == '\n')
|
|
{
|
|
len--;
|
|
|
|
continue;
|
|
}
|
|
|
|
if (buf[len - 1] == '\r')
|
|
{
|
|
len--;
|
|
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
buf[len] = 0;
|
|
|
|
return len;
|
|
}
|
|
|
|
char **scan_directory (const char *path)
|
|
{
|
|
char *tmp_path = mystrdup (path);
|
|
|
|
size_t tmp_path_len = strlen (tmp_path);
|
|
|
|
while (tmp_path[tmp_path_len - 1] == '/' || tmp_path[tmp_path_len - 1] == '\\')
|
|
{
|
|
tmp_path[tmp_path_len - 1] = 0;
|
|
|
|
tmp_path_len = strlen (tmp_path);
|
|
}
|
|
|
|
char **files = NULL;
|
|
|
|
int num_files = 0;
|
|
|
|
DIR *d;
|
|
|
|
if ((d = opendir (tmp_path)) != NULL)
|
|
{
|
|
struct dirent *de;
|
|
|
|
while ((de = readdir (d)) != NULL)
|
|
{
|
|
if ((strcmp (de->d_name, ".") == 0) || (strcmp (de->d_name, "..") == 0)) continue;
|
|
|
|
int path_size = strlen (tmp_path) + 1 + strlen (de->d_name);
|
|
|
|
char *path_file = (char *) mymalloc (path_size + 1);
|
|
|
|
snprintf (path_file, path_size + 1, "%s/%s", tmp_path, de->d_name);
|
|
|
|
path_file[path_size] = 0;
|
|
|
|
DIR *d_test;
|
|
|
|
if ((d_test = opendir (path_file)) != NULL)
|
|
{
|
|
closedir (d_test);
|
|
|
|
myfree (path_file);
|
|
}
|
|
else
|
|
{
|
|
files = (char **) myrealloc (files, num_files * sizeof (char *), sizeof (char *));
|
|
|
|
num_files++;
|
|
|
|
files[num_files - 1] = path_file;
|
|
}
|
|
}
|
|
|
|
closedir (d);
|
|
}
|
|
else if (errno == ENOTDIR)
|
|
{
|
|
files = (char **) myrealloc (files, num_files * sizeof (char *), sizeof (char *));
|
|
|
|
num_files++;
|
|
|
|
files[num_files - 1] = mystrdup (path);
|
|
}
|
|
|
|
files = (char **) myrealloc (files, num_files * sizeof (char *), sizeof (char *));
|
|
|
|
num_files++;
|
|
|
|
files[num_files - 1] = NULL;
|
|
|
|
myfree (tmp_path);
|
|
|
|
return (files);
|
|
}
|
|
|
|
int count_dictionaries (char **dictionary_files)
|
|
{
|
|
if (dictionary_files == NULL) return 0;
|
|
|
|
int cnt = 0;
|
|
|
|
for (int d = 0; dictionary_files[d] != NULL; d++)
|
|
{
|
|
cnt++;
|
|
}
|
|
|
|
return (cnt);
|
|
}
|
|
|
|
char *stroptitype (const uint opti_type)
|
|
{
|
|
switch (opti_type)
|
|
{
|
|
case OPTI_TYPE_ZERO_BYTE: return ((char *) OPTI_STR_ZERO_BYTE); break;
|
|
case OPTI_TYPE_PRECOMPUTE_INIT: return ((char *) OPTI_STR_PRECOMPUTE_INIT); break;
|
|
case OPTI_TYPE_PRECOMPUTE_MERKLE: return ((char *) OPTI_STR_PRECOMPUTE_MERKLE); break;
|
|
case OPTI_TYPE_PRECOMPUTE_PERMUT: return ((char *) OPTI_STR_PRECOMPUTE_PERMUT); break;
|
|
case OPTI_TYPE_MEET_IN_MIDDLE: return ((char *) OPTI_STR_MEET_IN_MIDDLE); break;
|
|
case OPTI_TYPE_EARLY_SKIP: return ((char *) OPTI_STR_EARLY_SKIP); break;
|
|
case OPTI_TYPE_NOT_SALTED: return ((char *) OPTI_STR_NOT_SALTED); break;
|
|
case OPTI_TYPE_NOT_ITERATED: return ((char *) OPTI_STR_NOT_ITERATED); break;
|
|
case OPTI_TYPE_PREPENDED_SALT: return ((char *) OPTI_STR_PREPENDED_SALT); break;
|
|
case OPTI_TYPE_APPENDED_SALT: return ((char *) OPTI_STR_APPENDED_SALT); break;
|
|
case OPTI_TYPE_SINGLE_HASH: return ((char *) OPTI_STR_SINGLE_HASH); break;
|
|
case OPTI_TYPE_SINGLE_SALT: return ((char *) OPTI_STR_SINGLE_SALT); break;
|
|
case OPTI_TYPE_BRUTE_FORCE: return ((char *) OPTI_STR_BRUTE_FORCE); break;
|
|
case OPTI_TYPE_RAW_HASH: return ((char *) OPTI_STR_RAW_HASH); break;
|
|
}
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
char *strparser (const uint parser_status)
|
|
{
|
|
switch (parser_status)
|
|
{
|
|
case PARSER_OK: return ((char *) PA_000); break;
|
|
case PARSER_COMMENT: return ((char *) PA_001); break;
|
|
case PARSER_GLOBAL_ZERO: return ((char *) PA_002); break;
|
|
case PARSER_GLOBAL_LENGTH: return ((char *) PA_003); break;
|
|
case PARSER_HASH_LENGTH: return ((char *) PA_004); break;
|
|
case PARSER_HASH_VALUE: return ((char *) PA_005); break;
|
|
case PARSER_SALT_LENGTH: return ((char *) PA_006); break;
|
|
case PARSER_SALT_VALUE: return ((char *) PA_007); break;
|
|
case PARSER_SALT_ITERATION: return ((char *) PA_008); break;
|
|
case PARSER_SEPARATOR_UNMATCHED: return ((char *) PA_009); break;
|
|
case PARSER_SIGNATURE_UNMATCHED: return ((char *) PA_010); break;
|
|
case PARSER_HCCAP_FILE_SIZE: return ((char *) PA_011); break;
|
|
case PARSER_HCCAP_EAPOL_SIZE: return ((char *) PA_012); break;
|
|
case PARSER_PSAFE2_FILE_SIZE: return ((char *) PA_013); break;
|
|
case PARSER_PSAFE3_FILE_SIZE: return ((char *) PA_014); break;
|
|
case PARSER_TC_FILE_SIZE: return ((char *) PA_015); break;
|
|
case PARSER_SIP_AUTH_DIRECTIVE: return ((char *) PA_016); break;
|
|
}
|
|
|
|
return ((char *) PA_255);
|
|
}
|
|
|
|
char *strhashtype (const uint hash_mode)
|
|
{
|
|
switch (hash_mode)
|
|
{
|
|
case 0: return ((char *) HT_00000); break;
|
|
case 10: return ((char *) HT_00010); break;
|
|
case 11: return ((char *) HT_00011); break;
|
|
case 12: return ((char *) HT_00012); break;
|
|
case 20: return ((char *) HT_00020); break;
|
|
case 21: return ((char *) HT_00021); break;
|
|
case 22: return ((char *) HT_00022); break;
|
|
case 23: return ((char *) HT_00023); break;
|
|
case 30: return ((char *) HT_00030); break;
|
|
case 40: return ((char *) HT_00040); break;
|
|
case 50: return ((char *) HT_00050); break;
|
|
case 60: return ((char *) HT_00060); break;
|
|
case 100: return ((char *) HT_00100); break;
|
|
case 101: return ((char *) HT_00101); break;
|
|
case 110: return ((char *) HT_00110); break;
|
|
case 111: return ((char *) HT_00111); break;
|
|
case 112: return ((char *) HT_00112); break;
|
|
case 120: return ((char *) HT_00120); break;
|
|
case 121: return ((char *) HT_00121); break;
|
|
case 122: return ((char *) HT_00122); break;
|
|
case 124: return ((char *) HT_00124); break;
|
|
case 130: return ((char *) HT_00130); break;
|
|
case 131: return ((char *) HT_00131); break;
|
|
case 132: return ((char *) HT_00132); break;
|
|
case 133: return ((char *) HT_00133); break;
|
|
case 140: return ((char *) HT_00140); break;
|
|
case 141: return ((char *) HT_00141); break;
|
|
case 150: return ((char *) HT_00150); break;
|
|
case 160: return ((char *) HT_00160); break;
|
|
case 190: return ((char *) HT_00190); break;
|
|
case 200: return ((char *) HT_00200); break;
|
|
case 300: return ((char *) HT_00300); break;
|
|
case 400: return ((char *) HT_00400); break;
|
|
case 500: return ((char *) HT_00500); break;
|
|
case 501: return ((char *) HT_00501); break;
|
|
case 900: return ((char *) HT_00900); break;
|
|
case 910: return ((char *) HT_00910); break;
|
|
case 1000: return ((char *) HT_01000); break;
|
|
case 1100: return ((char *) HT_01100); break;
|
|
case 1400: return ((char *) HT_01400); break;
|
|
case 1410: return ((char *) HT_01410); break;
|
|
case 1420: return ((char *) HT_01420); break;
|
|
case 1421: return ((char *) HT_01421); break;
|
|
case 1430: return ((char *) HT_01430); break;
|
|
case 1440: return ((char *) HT_01440); break;
|
|
case 1441: return ((char *) HT_01441); break;
|
|
case 1450: return ((char *) HT_01450); break;
|
|
case 1460: return ((char *) HT_01460); break;
|
|
case 1500: return ((char *) HT_01500); break;
|
|
case 1600: return ((char *) HT_01600); break;
|
|
case 1700: return ((char *) HT_01700); break;
|
|
case 1710: return ((char *) HT_01710); break;
|
|
case 1711: return ((char *) HT_01711); break;
|
|
case 1720: return ((char *) HT_01720); break;
|
|
case 1722: return ((char *) HT_01722); break;
|
|
case 1730: return ((char *) HT_01730); break;
|
|
case 1731: return ((char *) HT_01731); break;
|
|
case 1740: return ((char *) HT_01740); break;
|
|
case 1750: return ((char *) HT_01750); break;
|
|
case 1760: return ((char *) HT_01760); break;
|
|
case 1800: return ((char *) HT_01800); break;
|
|
case 2100: return ((char *) HT_02100); break;
|
|
case 2400: return ((char *) HT_02400); break;
|
|
case 2410: return ((char *) HT_02410); break;
|
|
case 2500: return ((char *) HT_02500); break;
|
|
case 2600: return ((char *) HT_02600); break;
|
|
case 2611: return ((char *) HT_02611); break;
|
|
case 2612: return ((char *) HT_02612); break;
|
|
case 2711: return ((char *) HT_02711); break;
|
|
case 2811: return ((char *) HT_02811); break;
|
|
case 3000: return ((char *) HT_03000); break;
|
|
case 3100: return ((char *) HT_03100); break;
|
|
case 3200: return ((char *) HT_03200); break;
|
|
case 3710: return ((char *) HT_03710); break;
|
|
case 3711: return ((char *) HT_03711); break;
|
|
case 3800: return ((char *) HT_03800); break;
|
|
case 4300: return ((char *) HT_04300); break;
|
|
case 4400: return ((char *) HT_04400); break;
|
|
case 4500: return ((char *) HT_04500); break;
|
|
case 4700: return ((char *) HT_04700); break;
|
|
case 4800: return ((char *) HT_04800); break;
|
|
case 4900: return ((char *) HT_04900); break;
|
|
case 5000: return ((char *) HT_05000); break;
|
|
case 5100: return ((char *) HT_05100); break;
|
|
case 5200: return ((char *) HT_05200); break;
|
|
case 5300: return ((char *) HT_05300); break;
|
|
case 5400: return ((char *) HT_05400); break;
|
|
case 5500: return ((char *) HT_05500); break;
|
|
case 5600: return ((char *) HT_05600); break;
|
|
case 5700: return ((char *) HT_05700); break;
|
|
case 5800: return ((char *) HT_05800); break;
|
|
case 6000: return ((char *) HT_06000); break;
|
|
case 6100: return ((char *) HT_06100); break;
|
|
case 6211: return ((char *) HT_06211); break;
|
|
case 6212: return ((char *) HT_06212); break;
|
|
case 6213: return ((char *) HT_06213); break;
|
|
case 6221: return ((char *) HT_06221); break;
|
|
case 6222: return ((char *) HT_06222); break;
|
|
case 6223: return ((char *) HT_06223); break;
|
|
case 6231: return ((char *) HT_06231); break;
|
|
case 6232: return ((char *) HT_06232); break;
|
|
case 6233: return ((char *) HT_06233); break;
|
|
case 6241: return ((char *) HT_06241); break;
|
|
case 6242: return ((char *) HT_06242); break;
|
|
case 6243: return ((char *) HT_06243); break;
|
|
case 6300: return ((char *) HT_06300); break;
|
|
case 6400: return ((char *) HT_06400); break;
|
|
case 6500: return ((char *) HT_06500); break;
|
|
case 6600: return ((char *) HT_06600); break;
|
|
case 6700: return ((char *) HT_06700); break;
|
|
case 6800: return ((char *) HT_06800); break;
|
|
case 6900: return ((char *) HT_06900); break;
|
|
case 7100: return ((char *) HT_07100); break;
|
|
case 7200: return ((char *) HT_07200); break;
|
|
case 7300: return ((char *) HT_07300); break;
|
|
case 7400: return ((char *) HT_07400); break;
|
|
case 7500: return ((char *) HT_07500); break;
|
|
case 7600: return ((char *) HT_07600); break;
|
|
case 7700: return ((char *) HT_07700); break;
|
|
case 7800: return ((char *) HT_07800); break;
|
|
case 7900: return ((char *) HT_07900); break;
|
|
case 8000: return ((char *) HT_08000); break;
|
|
case 8100: return ((char *) HT_08100); break;
|
|
case 8200: return ((char *) HT_08200); break;
|
|
case 8300: return ((char *) HT_08300); break;
|
|
case 8400: return ((char *) HT_08400); break;
|
|
case 8500: return ((char *) HT_08500); break;
|
|
case 8600: return ((char *) HT_08600); break;
|
|
case 8700: return ((char *) HT_08700); break;
|
|
case 8800: return ((char *) HT_08800); break;
|
|
case 8900: return ((char *) HT_08900); break;
|
|
case 9000: return ((char *) HT_09000); break;
|
|
case 9100: return ((char *) HT_09100); break;
|
|
case 9200: return ((char *) HT_09200); break;
|
|
case 9300: return ((char *) HT_09300); break;
|
|
case 9400: return ((char *) HT_09400); break;
|
|
case 9500: return ((char *) HT_09500); break;
|
|
case 9600: return ((char *) HT_09600); break;
|
|
case 9700: return ((char *) HT_09700); break;
|
|
case 9710: return ((char *) HT_09710); break;
|
|
case 9720: return ((char *) HT_09720); break;
|
|
case 9800: return ((char *) HT_09800); break;
|
|
case 9810: return ((char *) HT_09810); break;
|
|
case 9820: return ((char *) HT_09820); break;
|
|
case 9900: return ((char *) HT_09900); break;
|
|
case 10000: return ((char *) HT_10000); break;
|
|
case 10100: return ((char *) HT_10100); break;
|
|
case 10200: return ((char *) HT_10200); break;
|
|
case 10300: return ((char *) HT_10300); break;
|
|
case 10400: return ((char *) HT_10400); break;
|
|
case 10410: return ((char *) HT_10410); break;
|
|
case 10420: return ((char *) HT_10420); break;
|
|
case 10500: return ((char *) HT_10500); break;
|
|
case 10600: return ((char *) HT_10600); break;
|
|
case 10700: return ((char *) HT_10700); break;
|
|
case 10800: return ((char *) HT_10800); break;
|
|
case 10900: return ((char *) HT_10900); break;
|
|
case 11000: return ((char *) HT_11000); break;
|
|
case 11100: return ((char *) HT_11100); break;
|
|
case 11200: return ((char *) HT_11200); break;
|
|
case 11300: return ((char *) HT_11300); break;
|
|
case 11400: return ((char *) HT_11400); break;
|
|
case 11500: return ((char *) HT_11500); break;
|
|
case 11600: return ((char *) HT_11600); break;
|
|
case 11700: return ((char *) HT_11700); break;
|
|
case 11800: return ((char *) HT_11800); break;
|
|
case 11900: return ((char *) HT_11900); break;
|
|
case 12000: return ((char *) HT_12000); break;
|
|
case 12100: return ((char *) HT_12100); break;
|
|
case 12200: return ((char *) HT_12200); break;
|
|
case 12300: return ((char *) HT_12300); break;
|
|
case 12400: return ((char *) HT_12400); break;
|
|
case 12500: return ((char *) HT_12500); break;
|
|
case 12600: return ((char *) HT_12600); break;
|
|
case 12700: return ((char *) HT_12700); break;
|
|
case 12800: return ((char *) HT_12800); break;
|
|
}
|
|
|
|
return ((char *) "Unknown");
|
|
}
|
|
|
|
char *strstatus (const uint devices_status)
|
|
{
|
|
switch (devices_status)
|
|
{
|
|
case STATUS_INIT: return ((char *) ST_0000); break;
|
|
case STATUS_STARTING: return ((char *) ST_0001); break;
|
|
case STATUS_RUNNING: return ((char *) ST_0002); break;
|
|
case STATUS_PAUSED: return ((char *) ST_0003); break;
|
|
case STATUS_EXHAUSTED: return ((char *) ST_0004); break;
|
|
case STATUS_CRACKED: return ((char *) ST_0005); break;
|
|
case STATUS_ABORTED: return ((char *) ST_0006); break;
|
|
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;
|
|
}
|
|
|
|
return ((char *) "Unknown");
|
|
}
|
|
|
|
void ascii_digest (char out_buf[4096], uint salt_pos, uint digest_pos)
|
|
{
|
|
uint hash_type = data.hash_type;
|
|
uint hash_mode = data.hash_mode;
|
|
uint salt_type = data.salt_type;
|
|
uint opts_type = data.opts_type;
|
|
uint opti_type = data.opti_type;
|
|
uint dgst_size = data.dgst_size;
|
|
|
|
char *hashfile = data.hashfile;
|
|
|
|
uint len = 4096;
|
|
|
|
uint digest_buf[64];
|
|
|
|
uint64_t *digest_buf64 = (uint64_t *) digest_buf;
|
|
|
|
char *digests_buf_ptr = (char *) data.digests_buf;
|
|
|
|
memcpy (digest_buf, digests_buf_ptr + (data.salts_buf[salt_pos].digests_offset * dgst_size) + (digest_pos * dgst_size), dgst_size);
|
|
|
|
if (opti_type & OPTI_TYPE_PRECOMPUTE_PERMUT)
|
|
{
|
|
uint tt;
|
|
|
|
switch (hash_type)
|
|
{
|
|
case HASH_TYPE_DESCRYPT:
|
|
FP (digest_buf[1], digest_buf[0], tt);
|
|
break;
|
|
|
|
case HASH_TYPE_DESRACF:
|
|
digest_buf[0] = ROTATE_LEFT (digest_buf[0], 29);
|
|
digest_buf[1] = ROTATE_LEFT (digest_buf[1], 29);
|
|
|
|
FP (digest_buf[1], digest_buf[0], tt);
|
|
break;
|
|
|
|
case HASH_TYPE_LM:
|
|
FP (digest_buf[1], digest_buf[0], tt);
|
|
break;
|
|
|
|
case HASH_TYPE_NETNTLM:
|
|
digest_buf[0] = ROTATE_LEFT (digest_buf[0], 29);
|
|
digest_buf[1] = ROTATE_LEFT (digest_buf[1], 29);
|
|
digest_buf[2] = ROTATE_LEFT (digest_buf[2], 29);
|
|
digest_buf[3] = ROTATE_LEFT (digest_buf[3], 29);
|
|
|
|
FP (digest_buf[1], digest_buf[0], tt);
|
|
FP (digest_buf[3], digest_buf[2], tt);
|
|
break;
|
|
|
|
case HASH_TYPE_BSDICRYPT:
|
|
digest_buf[0] = ROTATE_LEFT (digest_buf[0], 31);
|
|
digest_buf[1] = ROTATE_LEFT (digest_buf[1], 31);
|
|
|
|
FP (digest_buf[1], digest_buf[0], tt);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (opti_type & OPTI_TYPE_PRECOMPUTE_MERKLE)
|
|
{
|
|
switch (hash_type)
|
|
{
|
|
case HASH_TYPE_MD4:
|
|
digest_buf[0] += MD4M_A;
|
|
digest_buf[1] += MD4M_B;
|
|
digest_buf[2] += MD4M_C;
|
|
digest_buf[3] += MD4M_D;
|
|
break;
|
|
|
|
case HASH_TYPE_MD5:
|
|
digest_buf[0] += MD5M_A;
|
|
digest_buf[1] += MD5M_B;
|
|
digest_buf[2] += MD5M_C;
|
|
digest_buf[3] += MD5M_D;
|
|
break;
|
|
|
|
case HASH_TYPE_SHA1:
|
|
digest_buf[0] += SHA1M_A;
|
|
digest_buf[1] += SHA1M_B;
|
|
digest_buf[2] += SHA1M_C;
|
|
digest_buf[3] += SHA1M_D;
|
|
digest_buf[4] += SHA1M_E;
|
|
break;
|
|
|
|
case HASH_TYPE_SHA256:
|
|
digest_buf[0] += SHA256M_A;
|
|
digest_buf[1] += SHA256M_B;
|
|
digest_buf[2] += SHA256M_C;
|
|
digest_buf[3] += SHA256M_D;
|
|
digest_buf[4] += SHA256M_E;
|
|
digest_buf[5] += SHA256M_F;
|
|
digest_buf[6] += SHA256M_G;
|
|
digest_buf[7] += SHA256M_H;
|
|
break;
|
|
|
|
case HASH_TYPE_SHA384:
|
|
digest_buf64[0] += SHA384M_A;
|
|
digest_buf64[1] += SHA384M_B;
|
|
digest_buf64[2] += SHA384M_C;
|
|
digest_buf64[3] += SHA384M_D;
|
|
digest_buf64[4] += SHA384M_E;
|
|
digest_buf64[5] += SHA384M_F;
|
|
digest_buf64[6] += 0;
|
|
digest_buf64[7] += 0;
|
|
break;
|
|
|
|
case HASH_TYPE_SHA512:
|
|
digest_buf64[0] += SHA512M_A;
|
|
digest_buf64[1] += SHA512M_B;
|
|
digest_buf64[2] += SHA512M_C;
|
|
digest_buf64[3] += SHA512M_D;
|
|
digest_buf64[4] += SHA512M_E;
|
|
digest_buf64[5] += SHA512M_F;
|
|
digest_buf64[6] += SHA512M_G;
|
|
digest_buf64[7] += SHA512M_H;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (opts_type & OPTS_TYPE_PT_GENERATE_LE)
|
|
{
|
|
if (dgst_size == DGST_SIZE_4_2)
|
|
{
|
|
for (int i = 0; i < 2; i++) digest_buf[i] = byte_swap_32 (digest_buf[i]);
|
|
}
|
|
else if (dgst_size == DGST_SIZE_4_4)
|
|
{
|
|
for (int i = 0; i < 4; i++) digest_buf[i] = byte_swap_32 (digest_buf[i]);
|
|
}
|
|
else if (dgst_size == DGST_SIZE_4_5)
|
|
{
|
|
for (int i = 0; i < 5; i++) digest_buf[i] = byte_swap_32 (digest_buf[i]);
|
|
}
|
|
else if (dgst_size == DGST_SIZE_4_6)
|
|
{
|
|
for (int i = 0; i < 6; i++) digest_buf[i] = byte_swap_32 (digest_buf[i]);
|
|
}
|
|
else if (dgst_size == DGST_SIZE_4_8)
|
|
{
|
|
for (int i = 0; i < 8; i++) digest_buf[i] = byte_swap_32 (digest_buf[i]);
|
|
}
|
|
else if ((dgst_size == DGST_SIZE_4_16) || (dgst_size == DGST_SIZE_8_8)) // same size, same result :)
|
|
{
|
|
if (hash_type == HASH_TYPE_WHIRLPOOL)
|
|
{
|
|
for (int i = 0; i < 16; i++) digest_buf[i] = byte_swap_32 (digest_buf[i]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_SHA384)
|
|
{
|
|
for (int i = 0; i < 8; i++) digest_buf64[i] = byte_swap_64 (digest_buf64[i]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_SHA512)
|
|
{
|
|
for (int i = 0; i < 8; i++) digest_buf64[i] = byte_swap_64 (digest_buf64[i]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_GOST)
|
|
{
|
|
for (int i = 0; i < 16; i++) digest_buf[i] = byte_swap_32 (digest_buf[i]);
|
|
}
|
|
}
|
|
else if (dgst_size == DGST_SIZE_4_64)
|
|
{
|
|
for (int i = 0; i < 64; i++) digest_buf[i] = byte_swap_32 (digest_buf[i]);
|
|
}
|
|
else if (dgst_size == DGST_SIZE_8_25)
|
|
{
|
|
for (int i = 0; i < 25; i++) digest_buf64[i] = byte_swap_64 (digest_buf64[i]);
|
|
}
|
|
}
|
|
|
|
uint isSalted = ((data.salt_type == SALT_TYPE_INTERN)
|
|
| (data.salt_type == SALT_TYPE_EXTERN)
|
|
| (data.salt_type == SALT_TYPE_EMBEDDED));
|
|
|
|
salt_t salt;
|
|
|
|
if (isSalted)
|
|
{
|
|
memset (&salt, 0, sizeof (salt_t));
|
|
|
|
memcpy (&salt, &data.salts_buf[salt_pos], sizeof (salt_t));
|
|
|
|
char *ptr = (char *) salt.salt_buf;
|
|
|
|
uint len = salt.salt_len;
|
|
|
|
if (opti_type & OPTI_TYPE_PRECOMPUTE_PERMUT)
|
|
{
|
|
uint tt;
|
|
|
|
switch (hash_type)
|
|
{
|
|
case HASH_TYPE_NETNTLM:
|
|
|
|
salt.salt_buf[0] = ROTATE_RIGHT (salt.salt_buf[0], 3);
|
|
salt.salt_buf[1] = ROTATE_RIGHT (salt.salt_buf[1], 3);
|
|
|
|
FP (salt.salt_buf[1], salt.salt_buf[0], tt);
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (opts_type & OPTS_TYPE_ST_UNICODE)
|
|
{
|
|
for (uint i = 0, j = 0; i < len; i += 1, j += 2)
|
|
{
|
|
ptr[i] = ptr[j];
|
|
}
|
|
|
|
len = len / 2;
|
|
}
|
|
|
|
if (opts_type & OPTS_TYPE_ST_GENERATE_LE)
|
|
{
|
|
uint max = salt.salt_len / 4;
|
|
|
|
if (len % 4) max++;
|
|
|
|
for (uint i = 0; i < max; i++)
|
|
{
|
|
salt.salt_buf[i] = byte_swap_32 (salt.salt_buf[i]);
|
|
}
|
|
}
|
|
|
|
if (opts_type & OPTS_TYPE_ST_HEX)
|
|
{
|
|
char tmp[64];
|
|
|
|
memset (tmp, 0, sizeof (tmp));
|
|
|
|
for (uint i = 0, j = 0; i < len; i += 1, j += 2)
|
|
{
|
|
sprintf (tmp + j, "%02x", (unsigned char) ptr[i]);
|
|
}
|
|
|
|
len = len * 2;
|
|
|
|
memcpy (ptr, tmp, len);
|
|
}
|
|
|
|
uint memset_size = ((48 - (int) len) > 0) ? (48 - len) : 0;
|
|
|
|
memset (ptr + len, 0, memset_size);
|
|
|
|
salt.salt_len = len;
|
|
}
|
|
|
|
//
|
|
// some modes require special encoding
|
|
//
|
|
|
|
uint out_buf_plain[256];
|
|
uint out_buf_salt[256];
|
|
|
|
char tmp_buf[1024];
|
|
|
|
memset (out_buf_plain, 0, sizeof (out_buf_plain));
|
|
memset (out_buf_salt, 0, sizeof (out_buf_salt));
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
char *ptr_plain = (char *) out_buf_plain;
|
|
char *ptr_salt = (char *) out_buf_salt;
|
|
|
|
if (hash_mode == 22)
|
|
{
|
|
char username[30];
|
|
|
|
memset (username, 0, sizeof (username));
|
|
|
|
memcpy (username, salt.salt_buf, salt.salt_len - 22);
|
|
|
|
char sig[6] = { 'n', 'r', 'c', 's', 't', 'n' };
|
|
|
|
uint16_t *ptr = (uint16_t *) digest_buf;
|
|
|
|
tmp_buf[ 0] = sig[0];
|
|
tmp_buf[ 1] = int_to_base64 (((ptr[1]) >> 12) & 0x3f);
|
|
tmp_buf[ 2] = int_to_base64 (((ptr[1]) >> 6) & 0x3f);
|
|
tmp_buf[ 3] = int_to_base64 (((ptr[1]) >> 0) & 0x3f);
|
|
tmp_buf[ 4] = int_to_base64 (((ptr[0]) >> 12) & 0x3f);
|
|
tmp_buf[ 5] = int_to_base64 (((ptr[0]) >> 6) & 0x3f);
|
|
tmp_buf[ 6] = sig[1];
|
|
tmp_buf[ 7] = int_to_base64 (((ptr[0]) >> 0) & 0x3f);
|
|
tmp_buf[ 8] = int_to_base64 (((ptr[3]) >> 12) & 0x3f);
|
|
tmp_buf[ 9] = int_to_base64 (((ptr[3]) >> 6) & 0x3f);
|
|
tmp_buf[10] = int_to_base64 (((ptr[3]) >> 0) & 0x3f);
|
|
tmp_buf[11] = int_to_base64 (((ptr[2]) >> 12) & 0x3f);
|
|
tmp_buf[12] = sig[2];
|
|
tmp_buf[13] = int_to_base64 (((ptr[2]) >> 6) & 0x3f);
|
|
tmp_buf[14] = int_to_base64 (((ptr[2]) >> 0) & 0x3f);
|
|
tmp_buf[15] = int_to_base64 (((ptr[5]) >> 12) & 0x3f);
|
|
tmp_buf[16] = int_to_base64 (((ptr[5]) >> 6) & 0x3f);
|
|
tmp_buf[17] = sig[3];
|
|
tmp_buf[18] = int_to_base64 (((ptr[5]) >> 0) & 0x3f);
|
|
tmp_buf[19] = int_to_base64 (((ptr[4]) >> 12) & 0x3f);
|
|
tmp_buf[20] = int_to_base64 (((ptr[4]) >> 6) & 0x3f);
|
|
tmp_buf[21] = int_to_base64 (((ptr[4]) >> 0) & 0x3f);
|
|
tmp_buf[22] = int_to_base64 (((ptr[7]) >> 12) & 0x3f);
|
|
tmp_buf[23] = sig[4];
|
|
tmp_buf[24] = int_to_base64 (((ptr[7]) >> 6) & 0x3f);
|
|
tmp_buf[25] = int_to_base64 (((ptr[7]) >> 0) & 0x3f);
|
|
tmp_buf[26] = int_to_base64 (((ptr[6]) >> 12) & 0x3f);
|
|
tmp_buf[27] = int_to_base64 (((ptr[6]) >> 6) & 0x3f);
|
|
tmp_buf[28] = int_to_base64 (((ptr[6]) >> 0) & 0x3f);
|
|
tmp_buf[29] = sig[5];
|
|
|
|
snprintf (out_buf, len-1, "%s:%s",
|
|
tmp_buf,
|
|
username);
|
|
}
|
|
else if (hash_mode == 23)
|
|
{
|
|
// do not show the \nskyper\n part in output
|
|
|
|
char *salt_buf_ptr = (char *) salt.salt_buf;
|
|
|
|
salt_buf_ptr[salt.salt_len - 8] = 0;
|
|
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x:%s",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
salt_buf_ptr);
|
|
}
|
|
else if (hash_mode == 101)
|
|
{
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
|
|
memcpy (tmp_buf, digest_buf, 20);
|
|
|
|
base64_encode (int_to_base64, tmp_buf, 20, ptr_plain);
|
|
|
|
snprintf (out_buf, len-1, "{SHA}%s", ptr_plain);
|
|
}
|
|
else if (hash_mode == 111)
|
|
{
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
|
|
memcpy (tmp_buf, digest_buf, 20);
|
|
memcpy (tmp_buf + 20, salt.salt_buf, salt.salt_len);
|
|
|
|
base64_encode (int_to_base64, tmp_buf, 20 + salt.salt_len, ptr_plain);
|
|
|
|
snprintf (out_buf, len-1, "{SSHA}%s", ptr_plain);
|
|
}
|
|
else if (hash_mode == 122)
|
|
{
|
|
snprintf (out_buf, len-1, "%s%08x%08x%08x%08x%08x",
|
|
(unsigned char *) salt.salt_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_mode == 124)
|
|
{
|
|
snprintf (out_buf, len-1, "sha1$%s$%08x%08x%08x%08x%08x",
|
|
(unsigned char *) salt.salt_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_mode == 131)
|
|
{
|
|
snprintf (out_buf, len-1, "0x0100%s%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
(unsigned char *) salt.salt_buf,
|
|
0, 0, 0, 0, 0,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_mode == 132)
|
|
{
|
|
snprintf (out_buf, len-1, "0x0100%s%08x%08x%08x%08x%08x",
|
|
(unsigned char *) salt.salt_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_mode == 133)
|
|
{
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
|
|
memcpy (tmp_buf, digest_buf, 20);
|
|
|
|
base64_encode (int_to_base64, tmp_buf, 20, ptr_plain);
|
|
|
|
snprintf (out_buf, len-1, "%s", ptr_plain);
|
|
}
|
|
else if (hash_mode == 141)
|
|
{
|
|
memcpy (tmp_buf, salt.salt_buf, salt.salt_len);
|
|
|
|
base64_encode (int_to_base64, tmp_buf, salt.salt_len, ptr_salt);
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
|
|
memcpy (tmp_buf, digest_buf, 20);
|
|
|
|
base64_encode (int_to_base64, tmp_buf, 20, ptr_plain);
|
|
|
|
ptr_plain[27] = 0;
|
|
|
|
snprintf (out_buf, len-1, "%s%s*%s", SIGNATURE_EPISERVER, ptr_salt, ptr_plain);
|
|
}
|
|
else if (hash_mode == 400)
|
|
{
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
|
|
phpass_encode ((unsigned char *) digest_buf, (unsigned char *) ptr_plain);
|
|
|
|
snprintf (out_buf, len-1, "%s%s%s", (char *) salt.salt_sign, (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else if (hash_mode == 500)
|
|
{
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
|
|
md5crypt_encode ((unsigned char *) digest_buf, (unsigned char *) ptr_plain);
|
|
|
|
if (salt.salt_iter == ROUNDS_MD5CRYPT)
|
|
{
|
|
snprintf (out_buf, len-1, "$1$%s$%s", (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else
|
|
{
|
|
snprintf (out_buf, len-1, "$1$rounds=%i$%s$%s", salt.salt_iter, (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
}
|
|
else if (hash_mode == 501)
|
|
{
|
|
uint digest_idx = salt.digests_offset + digest_pos;
|
|
|
|
hashinfo_t **hashinfo_ptr = data.hash_info;
|
|
char *hash_buf = hashinfo_ptr[digest_idx]->orighash;
|
|
|
|
snprintf (out_buf, len-1, "%s", hash_buf);
|
|
}
|
|
else if (hash_mode == 1421)
|
|
{
|
|
uint8_t *salt_ptr = (uint8_t *) salt.salt_buf;
|
|
|
|
snprintf (out_buf, len-1, "%c%c%c%c%c%c%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
salt_ptr[0],
|
|
salt_ptr[1],
|
|
salt_ptr[2],
|
|
salt_ptr[3],
|
|
salt_ptr[4],
|
|
salt_ptr[5],
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4],
|
|
digest_buf[5],
|
|
digest_buf[6],
|
|
digest_buf[7]);
|
|
}
|
|
else if (hash_mode == 1441)
|
|
{
|
|
memcpy (tmp_buf, salt.salt_buf, salt.salt_len);
|
|
|
|
base64_encode (int_to_base64, tmp_buf, salt.salt_len, ptr_salt);
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
digest_buf[5] = byte_swap_32 (digest_buf[5]);
|
|
digest_buf[6] = byte_swap_32 (digest_buf[6]);
|
|
digest_buf[7] = byte_swap_32 (digest_buf[7]);
|
|
|
|
memcpy (tmp_buf, digest_buf, 32);
|
|
|
|
base64_encode (int_to_base64, tmp_buf, 32, ptr_plain);
|
|
|
|
ptr_plain[43] = 0;
|
|
|
|
snprintf (out_buf, len-1, "%s%s*%s", SIGNATURE_EPISERVER4, ptr_salt, ptr_plain);
|
|
}
|
|
else if (hash_mode == 1500)
|
|
{
|
|
out_buf[0] = salt.salt_sign[0] & 0xff;
|
|
out_buf[1] = salt.salt_sign[1] & 0xff;
|
|
//original method, but changed because of this ticket: https://hashcat.net/trac/ticket/269
|
|
//out_buf[0] = int_to_itoa64 ((salt.salt_buf[0] >> 0) & 0x3f);
|
|
//out_buf[1] = int_to_itoa64 ((salt.salt_buf[0] >> 6) & 0x3f);
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
|
|
memcpy (tmp_buf, digest_buf, 8);
|
|
|
|
base64_encode (int_to_itoa64, tmp_buf, 8, ptr_plain);
|
|
|
|
snprintf (out_buf + 2, len-1-2, "%s", ptr_plain);
|
|
|
|
out_buf[13] = 0;
|
|
}
|
|
else if (hash_mode == 1600)
|
|
{
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
|
|
md5crypt_encode ((unsigned char *) digest_buf, (unsigned char *) ptr_plain);
|
|
|
|
if (salt.salt_iter == ROUNDS_MD5CRYPT)
|
|
{
|
|
snprintf (out_buf, len-1, "$apr1$%s$%s", (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else
|
|
{
|
|
snprintf (out_buf, len-1, "$apr1$rounds=%i$%s$%s", salt.salt_iter, (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
}
|
|
else if (hash_mode == 1711)
|
|
{
|
|
// the encoder is a bit too intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf64[0] = byte_swap_64 (digest_buf64[0]);
|
|
digest_buf64[1] = byte_swap_64 (digest_buf64[1]);
|
|
digest_buf64[2] = byte_swap_64 (digest_buf64[2]);
|
|
digest_buf64[3] = byte_swap_64 (digest_buf64[3]);
|
|
digest_buf64[4] = byte_swap_64 (digest_buf64[4]);
|
|
digest_buf64[5] = byte_swap_64 (digest_buf64[5]);
|
|
digest_buf64[6] = byte_swap_64 (digest_buf64[6]);
|
|
digest_buf64[7] = byte_swap_64 (digest_buf64[7]);
|
|
|
|
memcpy (tmp_buf, digest_buf, 64);
|
|
memcpy (tmp_buf + 64, salt.salt_buf, salt.salt_len);
|
|
|
|
base64_encode (int_to_base64, tmp_buf, 64 + salt.salt_len, ptr_plain);
|
|
|
|
snprintf (out_buf, len-1, "%s%s", SIGNATURE_SHA512B64S, ptr_plain);
|
|
}
|
|
else if (hash_mode == 1722)
|
|
{
|
|
uint *ptr = digest_buf;
|
|
|
|
snprintf (out_buf, len-1, "%s%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
(unsigned char *) salt.salt_buf,
|
|
ptr[ 1], ptr[ 0],
|
|
ptr[ 3], ptr[ 2],
|
|
ptr[ 5], ptr[ 4],
|
|
ptr[ 7], ptr[ 6],
|
|
ptr[ 9], ptr[ 8],
|
|
ptr[11], ptr[10],
|
|
ptr[13], ptr[12],
|
|
ptr[15], ptr[14]);
|
|
}
|
|
else if (hash_mode == 1731)
|
|
{
|
|
uint *ptr = digest_buf;
|
|
|
|
snprintf (out_buf, len-1, "0x0200%s%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
(unsigned char *) salt.salt_buf,
|
|
ptr[ 1], ptr[ 0],
|
|
ptr[ 3], ptr[ 2],
|
|
ptr[ 5], ptr[ 4],
|
|
ptr[ 7], ptr[ 6],
|
|
ptr[ 9], ptr[ 8],
|
|
ptr[11], ptr[10],
|
|
ptr[13], ptr[12],
|
|
ptr[15], ptr[14]);
|
|
}
|
|
else if (hash_mode == 1800)
|
|
{
|
|
// temp workaround
|
|
|
|
digest_buf64[0] = byte_swap_64 (digest_buf64[0]);
|
|
digest_buf64[1] = byte_swap_64 (digest_buf64[1]);
|
|
digest_buf64[2] = byte_swap_64 (digest_buf64[2]);
|
|
digest_buf64[3] = byte_swap_64 (digest_buf64[3]);
|
|
digest_buf64[4] = byte_swap_64 (digest_buf64[4]);
|
|
digest_buf64[5] = byte_swap_64 (digest_buf64[5]);
|
|
digest_buf64[6] = byte_swap_64 (digest_buf64[6]);
|
|
digest_buf64[7] = byte_swap_64 (digest_buf64[7]);
|
|
|
|
sha512crypt_encode ((unsigned char *) digest_buf64, (unsigned char *) ptr_plain);
|
|
|
|
if (salt.salt_iter == ROUNDS_SHA512CRYPT)
|
|
{
|
|
snprintf (out_buf, len-1, "$6$%s$%s", (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else
|
|
{
|
|
snprintf (out_buf, len-1, "$6$rounds=%i$%s$%s", salt.salt_iter, (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
}
|
|
else if (hash_mode == 2100)
|
|
{
|
|
uint pos = 0;
|
|
|
|
snprintf (out_buf + pos, len-1, "%s%i#",
|
|
SIGNATURE_DCC2,
|
|
salt.salt_iter + 1);
|
|
|
|
uint signature_len = strlen (out_buf);
|
|
|
|
pos += signature_len;
|
|
len -= signature_len;
|
|
|
|
char *salt_ptr = (char *) salt.salt_buf;
|
|
|
|
for (uint i = 0; i < salt.salt_len; i++, pos++, len--) snprintf (out_buf + pos, len-1, "%c", salt_ptr[i]);
|
|
|
|
snprintf (out_buf + pos, len-1, "#%08x%08x%08x%08x",
|
|
byte_swap_32 (digest_buf[0]),
|
|
byte_swap_32 (digest_buf[1]),
|
|
byte_swap_32 (digest_buf[2]),
|
|
byte_swap_32 (digest_buf[3]));
|
|
}
|
|
else if ((hash_mode == 2400) || (hash_mode == 2410))
|
|
{
|
|
memcpy (tmp_buf, digest_buf, 16);
|
|
|
|
// the encoder is a bit too intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
|
|
out_buf[ 0] = int_to_itoa64 ((digest_buf[0] >> 0) & 0x3f);
|
|
out_buf[ 1] = int_to_itoa64 ((digest_buf[0] >> 6) & 0x3f);
|
|
out_buf[ 2] = int_to_itoa64 ((digest_buf[0] >> 12) & 0x3f);
|
|
out_buf[ 3] = int_to_itoa64 ((digest_buf[0] >> 18) & 0x3f);
|
|
|
|
out_buf[ 4] = int_to_itoa64 ((digest_buf[1] >> 0) & 0x3f);
|
|
out_buf[ 5] = int_to_itoa64 ((digest_buf[1] >> 6) & 0x3f);
|
|
out_buf[ 6] = int_to_itoa64 ((digest_buf[1] >> 12) & 0x3f);
|
|
out_buf[ 7] = int_to_itoa64 ((digest_buf[1] >> 18) & 0x3f);
|
|
|
|
out_buf[ 8] = int_to_itoa64 ((digest_buf[2] >> 0) & 0x3f);
|
|
out_buf[ 9] = int_to_itoa64 ((digest_buf[2] >> 6) & 0x3f);
|
|
out_buf[10] = int_to_itoa64 ((digest_buf[2] >> 12) & 0x3f);
|
|
out_buf[11] = int_to_itoa64 ((digest_buf[2] >> 18) & 0x3f);
|
|
|
|
out_buf[12] = int_to_itoa64 ((digest_buf[3] >> 0) & 0x3f);
|
|
out_buf[13] = int_to_itoa64 ((digest_buf[3] >> 6) & 0x3f);
|
|
out_buf[14] = int_to_itoa64 ((digest_buf[3] >> 12) & 0x3f);
|
|
out_buf[15] = int_to_itoa64 ((digest_buf[3] >> 18) & 0x3f);
|
|
|
|
out_buf[16] = 0;
|
|
}
|
|
else if (hash_mode == 2500)
|
|
{
|
|
wpa_t *wpas = (wpa_t *) data.esalts_buf;
|
|
|
|
wpa_t *wpa = &wpas[salt_pos];
|
|
|
|
uint pke[25];
|
|
|
|
char *pke_ptr = (char *) pke;
|
|
|
|
for (uint i = 0; i < 25; i++)
|
|
{
|
|
pke[i] = byte_swap_32 (wpa->pke[i]);
|
|
}
|
|
|
|
unsigned char mac1[6];
|
|
unsigned char mac2[6];
|
|
|
|
memcpy (mac1, pke_ptr + 23, 6);
|
|
memcpy (mac2, pke_ptr + 29, 6);
|
|
|
|
snprintf (out_buf, len-1, "%s:%02x%02x%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x",
|
|
(char *) salt.salt_buf,
|
|
mac1[0],
|
|
mac1[1],
|
|
mac1[2],
|
|
mac1[3],
|
|
mac1[4],
|
|
mac1[5],
|
|
mac2[0],
|
|
mac2[1],
|
|
mac2[2],
|
|
mac2[3],
|
|
mac2[4],
|
|
mac2[5]);
|
|
}
|
|
else if (hash_mode == 4400)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x",
|
|
byte_swap_32 (digest_buf[0]),
|
|
byte_swap_32 (digest_buf[1]),
|
|
byte_swap_32 (digest_buf[2]),
|
|
byte_swap_32 (digest_buf[3]));
|
|
}
|
|
else if (hash_mode == 4700)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x",
|
|
byte_swap_32 (digest_buf[0]),
|
|
byte_swap_32 (digest_buf[1]),
|
|
byte_swap_32 (digest_buf[2]),
|
|
byte_swap_32 (digest_buf[3]),
|
|
byte_swap_32 (digest_buf[4]));
|
|
}
|
|
else if (hash_mode == 4800)
|
|
{
|
|
uint8_t chap_id_byte = (uint8_t) salt.salt_buf[4];
|
|
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x:%08x%08x%08x%08x:%02x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
byte_swap_32 (salt.salt_buf[0]),
|
|
byte_swap_32 (salt.salt_buf[1]),
|
|
byte_swap_32 (salt.salt_buf[2]),
|
|
byte_swap_32 (salt.salt_buf[3]),
|
|
chap_id_byte);
|
|
}
|
|
else if (hash_mode == 4900)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x",
|
|
byte_swap_32 (digest_buf[0]),
|
|
byte_swap_32 (digest_buf[1]),
|
|
byte_swap_32 (digest_buf[2]),
|
|
byte_swap_32 (digest_buf[3]),
|
|
byte_swap_32 (digest_buf[4]));
|
|
}
|
|
else if (hash_mode == 5100)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1]);
|
|
}
|
|
else if (hash_mode == 5200)
|
|
{
|
|
snprintf (out_buf, len-1, "%s", hashfile);
|
|
}
|
|
else if (hash_mode == 5300)
|
|
{
|
|
ikepsk_t *ikepsks = (ikepsk_t *) data.esalts_buf;
|
|
|
|
ikepsk_t *ikepsk = &ikepsks[salt_pos];
|
|
|
|
int buf_len = len -1;
|
|
|
|
// msg_buf
|
|
|
|
uint ikepsk_msg_len = ikepsk->msg_len / 4;
|
|
|
|
for (uint i = 0; i < ikepsk_msg_len; i++)
|
|
{
|
|
if ((i == 32) || (i == 64) || (i == 66) || (i == 68) || (i == 108))
|
|
{
|
|
snprintf (out_buf, buf_len, ":");
|
|
|
|
buf_len--;
|
|
out_buf++;
|
|
}
|
|
|
|
snprintf (out_buf, buf_len, "%08x", byte_swap_32 (ikepsk->msg_buf[i]));
|
|
|
|
buf_len -= 8;
|
|
out_buf += 8;
|
|
}
|
|
|
|
// nr_buf
|
|
|
|
uint ikepsk_nr_len = ikepsk->nr_len / 4;
|
|
|
|
for (uint i = 0; i < ikepsk_nr_len; i++)
|
|
{
|
|
if ((i == 0) || (i == 5))
|
|
{
|
|
snprintf (out_buf, buf_len, ":");
|
|
|
|
buf_len--;
|
|
out_buf++;
|
|
}
|
|
|
|
snprintf (out_buf, buf_len, "%08x", byte_swap_32 (ikepsk->nr_buf[i]));
|
|
|
|
buf_len -= 8;
|
|
out_buf += 8;
|
|
}
|
|
|
|
// digest_buf
|
|
|
|
for (uint i = 0; i < 4; i++)
|
|
{
|
|
if (i == 0)
|
|
{
|
|
snprintf (out_buf, buf_len, ":");
|
|
|
|
buf_len--;
|
|
out_buf++;
|
|
}
|
|
|
|
snprintf (out_buf, buf_len, "%08x", digest_buf[i]);
|
|
|
|
buf_len -= 8;
|
|
out_buf += 8;
|
|
}
|
|
}
|
|
else if (hash_mode == 5400)
|
|
{
|
|
ikepsk_t *ikepsks = (ikepsk_t *) data.esalts_buf;
|
|
|
|
ikepsk_t *ikepsk = &ikepsks[salt_pos];
|
|
|
|
int buf_len = len -1;
|
|
|
|
// msg_buf
|
|
|
|
uint ikepsk_msg_len = ikepsk->msg_len / 4;
|
|
|
|
for (uint i = 0; i < ikepsk_msg_len; i++)
|
|
{
|
|
if ((i == 32) || (i == 64) || (i == 66) || (i == 68) || (i == 108))
|
|
{
|
|
snprintf (out_buf, buf_len, ":");
|
|
|
|
buf_len--;
|
|
out_buf++;
|
|
}
|
|
|
|
snprintf (out_buf, buf_len, "%08x", byte_swap_32 (ikepsk->msg_buf[i]));
|
|
|
|
buf_len -= 8;
|
|
out_buf += 8;
|
|
}
|
|
|
|
// nr_buf
|
|
|
|
uint ikepsk_nr_len = ikepsk->nr_len / 4;
|
|
|
|
for (uint i = 0; i < ikepsk_nr_len; i++)
|
|
{
|
|
if ((i == 0) || (i == 5))
|
|
{
|
|
snprintf (out_buf, buf_len, ":");
|
|
|
|
buf_len--;
|
|
out_buf++;
|
|
}
|
|
|
|
snprintf (out_buf, buf_len, "%08x", byte_swap_32 (ikepsk->nr_buf[i]));
|
|
|
|
buf_len -= 8;
|
|
out_buf += 8;
|
|
}
|
|
|
|
// digest_buf
|
|
|
|
for (uint i = 0; i < 5; i++)
|
|
{
|
|
if (i == 0)
|
|
{
|
|
snprintf (out_buf, buf_len, ":");
|
|
|
|
buf_len--;
|
|
out_buf++;
|
|
}
|
|
|
|
snprintf (out_buf, buf_len, "%08x", digest_buf[i]);
|
|
|
|
buf_len -= 8;
|
|
out_buf += 8;
|
|
}
|
|
}
|
|
else if (hash_mode == 5500)
|
|
{
|
|
netntlm_t *netntlms = (netntlm_t *) data.esalts_buf;
|
|
|
|
netntlm_t *netntlm = &netntlms[salt_pos];
|
|
|
|
char user_buf[64];
|
|
char domain_buf[64];
|
|
char srvchall_buf[1024];
|
|
char clichall_buf[1024];
|
|
|
|
memset (user_buf, 0, sizeof (user_buf));
|
|
memset (domain_buf, 0, sizeof (domain_buf));
|
|
memset (srvchall_buf, 0, sizeof (srvchall_buf));
|
|
memset (clichall_buf, 0, sizeof (clichall_buf));
|
|
|
|
for (uint i = 0, j = 0; j < netntlm->user_len; i += 1, j += 2)
|
|
{
|
|
char *ptr = (char *) netntlm->userdomain_buf;
|
|
|
|
user_buf[i] = ptr[j];
|
|
}
|
|
|
|
for (uint i = 0, j = 0; j < netntlm->domain_len; i += 1, j += 2)
|
|
{
|
|
char *ptr = (char *) netntlm->userdomain_buf;
|
|
|
|
domain_buf[i] = ptr[netntlm->user_len + j];
|
|
}
|
|
|
|
for (uint i = 0, j = 0; i < netntlm->srvchall_len; i += 1, j += 2)
|
|
{
|
|
char *ptr = (char *) netntlm->chall_buf;
|
|
|
|
sprintf (srvchall_buf + j, "%02x", (uint8_t) ptr[i]);
|
|
}
|
|
|
|
for (uint i = 0, j = 0; i < netntlm->clichall_len; i += 1, j += 2)
|
|
{
|
|
char *ptr = (char *) netntlm->chall_buf;
|
|
|
|
sprintf (clichall_buf + j, "%02x", (uint8_t) ptr[netntlm->srvchall_len + i]);
|
|
}
|
|
|
|
snprintf (out_buf, len-1, "%s::%s:%s:%08x%08x%08x%08x%08x%08x:%s",
|
|
user_buf,
|
|
domain_buf,
|
|
srvchall_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
byte_swap_32 (salt.salt_buf_pc[0]),
|
|
byte_swap_32 (salt.salt_buf_pc[1]),
|
|
clichall_buf);
|
|
}
|
|
else if (hash_mode == 5600)
|
|
{
|
|
netntlm_t *netntlms = (netntlm_t *) data.esalts_buf;
|
|
|
|
netntlm_t *netntlm = &netntlms[salt_pos];
|
|
|
|
char user_buf[64];
|
|
char domain_buf[64];
|
|
char srvchall_buf[1024];
|
|
char clichall_buf[1024];
|
|
|
|
memset (user_buf, 0, sizeof (user_buf));
|
|
memset (domain_buf, 0, sizeof (domain_buf));
|
|
memset (srvchall_buf, 0, sizeof (srvchall_buf));
|
|
memset (clichall_buf, 0, sizeof (clichall_buf));
|
|
|
|
for (uint i = 0, j = 0; j < netntlm->user_len; i += 1, j += 2)
|
|
{
|
|
char *ptr = (char *) netntlm->userdomain_buf;
|
|
|
|
user_buf[i] = ptr[j];
|
|
}
|
|
|
|
for (uint i = 0, j = 0; j < netntlm->domain_len; i += 1, j += 2)
|
|
{
|
|
char *ptr = (char *) netntlm->userdomain_buf;
|
|
|
|
domain_buf[i] = ptr[netntlm->user_len + j];
|
|
}
|
|
|
|
for (uint i = 0, j = 0; i < netntlm->srvchall_len; i += 1, j += 2)
|
|
{
|
|
char *ptr = (char *) netntlm->chall_buf;
|
|
|
|
sprintf (srvchall_buf + j, "%02x", (uint8_t) ptr[i]);
|
|
}
|
|
|
|
for (uint i = 0, j = 0; i < netntlm->clichall_len; i += 1, j += 2)
|
|
{
|
|
char *ptr = (char *) netntlm->chall_buf;
|
|
|
|
sprintf (clichall_buf + j, "%02x", (uint8_t) ptr[netntlm->srvchall_len + i]);
|
|
}
|
|
|
|
snprintf (out_buf, len-1, "%s::%s:%s:%08x%08x%08x%08x:%s",
|
|
user_buf,
|
|
domain_buf,
|
|
srvchall_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
clichall_buf);
|
|
}
|
|
else if (hash_mode == 5700)
|
|
{
|
|
// the encoder is a bit too intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
digest_buf[5] = byte_swap_32 (digest_buf[5]);
|
|
digest_buf[6] = byte_swap_32 (digest_buf[6]);
|
|
digest_buf[7] = byte_swap_32 (digest_buf[7]);
|
|
|
|
memcpy (tmp_buf, digest_buf, 32);
|
|
|
|
base64_encode (int_to_itoa64, tmp_buf, 32, ptr_plain);
|
|
|
|
ptr_plain[43] = 0;
|
|
|
|
snprintf (out_buf, len-1, "%s", ptr_plain);
|
|
}
|
|
else if (hash_mode == 5800)
|
|
{
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if ((hash_mode >= 6200) && (hash_mode <= 6299))
|
|
{
|
|
snprintf (out_buf, len-1, "%s", hashfile);
|
|
}
|
|
else if (hash_mode == 6300)
|
|
{
|
|
// the encoder is a bit to intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
|
|
md5crypt_encode ((unsigned char *) digest_buf, (unsigned char *) ptr_plain);
|
|
|
|
snprintf (out_buf, len-1, "{smd5}%s$%s", (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else if (hash_mode == 6400)
|
|
{
|
|
sha256aix_encode ((unsigned char *) digest_buf, (unsigned char *) ptr_plain);
|
|
|
|
snprintf (out_buf, len-1, "{ssha256}%02d$%s$%s", salt.salt_sign[0], (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else if (hash_mode == 6500)
|
|
{
|
|
sha512aix_encode ((unsigned char *) digest_buf64, (unsigned char *) ptr_plain);
|
|
|
|
snprintf (out_buf, len-1, "{ssha512}%02d$%s$%s", salt.salt_sign[0], (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else if (hash_mode == 6600)
|
|
{
|
|
agilekey_t *agilekeys = (agilekey_t *) data.esalts_buf;
|
|
|
|
agilekey_t *agilekey = &agilekeys[salt_pos];
|
|
|
|
salt.salt_buf[0] = byte_swap_32 (salt.salt_buf[0]);
|
|
salt.salt_buf[1] = byte_swap_32 (salt.salt_buf[1]);
|
|
|
|
uint buf_len = len - 1;
|
|
|
|
uint off = snprintf (out_buf, buf_len, "%d:%08x%08x:", salt.salt_iter + 1, salt.salt_buf[0], salt.salt_buf[1]);
|
|
buf_len -= 22;
|
|
|
|
for (uint i = 0, j = off; i < 1040; i++, j += 2)
|
|
{
|
|
snprintf (out_buf + j, buf_len, "%02x", agilekey->cipher[i]);
|
|
|
|
buf_len -= 2;
|
|
}
|
|
}
|
|
else if (hash_mode == 6700)
|
|
{
|
|
sha1aix_encode ((unsigned char *) digest_buf, (unsigned char *) ptr_plain);
|
|
|
|
snprintf (out_buf, len-1, "{ssha1}%02d$%s$%s", salt.salt_sign[0], (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else if (hash_mode == 6800)
|
|
{
|
|
snprintf (out_buf, len-1, "%s", (char *) salt.salt_buf);
|
|
}
|
|
else if (hash_mode == 7100)
|
|
{
|
|
uint *ptr = digest_buf;
|
|
|
|
pbkdf2_sha512_t *pbkdf2_sha512s = (pbkdf2_sha512_t *) data.esalts_buf;
|
|
|
|
pbkdf2_sha512_t *pbkdf2_sha512 = &pbkdf2_sha512s[salt_pos];
|
|
|
|
uint esalt[16];
|
|
|
|
esalt[0] = byte_swap_32 (pbkdf2_sha512->salt_buf[0]);
|
|
esalt[1] = byte_swap_32 (pbkdf2_sha512->salt_buf[1]);
|
|
esalt[2] = byte_swap_32 (pbkdf2_sha512->salt_buf[2]);
|
|
esalt[3] = byte_swap_32 (pbkdf2_sha512->salt_buf[3]);
|
|
esalt[4] = byte_swap_32 (pbkdf2_sha512->salt_buf[4]);
|
|
esalt[5] = byte_swap_32 (pbkdf2_sha512->salt_buf[5]);
|
|
esalt[6] = byte_swap_32 (pbkdf2_sha512->salt_buf[6]);
|
|
esalt[7] = byte_swap_32 (pbkdf2_sha512->salt_buf[7]);
|
|
|
|
snprintf (out_buf, len-1, "%s%i$%08x%08x%08x%08x%08x%08x%08x%08x$%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
SIGNATURE_SHA512OSX,
|
|
salt.salt_iter + 1,
|
|
esalt[ 0], esalt[ 1],
|
|
esalt[ 2], esalt[ 3],
|
|
esalt[ 4], esalt[ 5],
|
|
esalt[ 6], esalt[ 7],
|
|
ptr [ 1], ptr [ 0],
|
|
ptr [ 3], ptr [ 2],
|
|
ptr [ 5], ptr [ 4],
|
|
ptr [ 7], ptr [ 6],
|
|
ptr [ 9], ptr [ 8],
|
|
ptr [11], ptr [10],
|
|
ptr [13], ptr [12],
|
|
ptr [15], ptr [14]);
|
|
}
|
|
else if (hash_mode == 7200)
|
|
{
|
|
uint *ptr = digest_buf;
|
|
|
|
pbkdf2_sha512_t *pbkdf2_sha512s = (pbkdf2_sha512_t *) data.esalts_buf;
|
|
|
|
pbkdf2_sha512_t *pbkdf2_sha512 = &pbkdf2_sha512s[salt_pos];
|
|
|
|
uint len_used = 0;
|
|
|
|
snprintf (out_buf + len_used, len - len_used - 1, "%s%i.", SIGNATURE_SHA512GRUB, salt.salt_iter + 1);
|
|
|
|
len_used = strlen (out_buf);
|
|
|
|
unsigned char *salt_buf_ptr = (unsigned char *) pbkdf2_sha512->salt_buf;
|
|
|
|
for (uint i = 0; i < salt.salt_len; i++, len_used += 2)
|
|
{
|
|
snprintf (out_buf + len_used, len - len_used - 1, "%02x", salt_buf_ptr[i]);
|
|
}
|
|
|
|
snprintf (out_buf + len_used, len - len_used - 1, ".%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
ptr [ 1], ptr [ 0],
|
|
ptr [ 3], ptr [ 2],
|
|
ptr [ 5], ptr [ 4],
|
|
ptr [ 7], ptr [ 6],
|
|
ptr [ 9], ptr [ 8],
|
|
ptr [11], ptr [10],
|
|
ptr [13], ptr [12],
|
|
ptr [15], ptr [14]);
|
|
}
|
|
else if (hash_mode == 7300)
|
|
{
|
|
rakp_t *rakps = (rakp_t *) data.esalts_buf;
|
|
|
|
rakp_t *rakp = &rakps[salt_pos];
|
|
|
|
for (uint i = 0, j = 0; (i * 4) < rakp->salt_len; i += 1, j += 8)
|
|
{
|
|
sprintf (out_buf + j, "%08x", rakp->salt_buf[i]);
|
|
}
|
|
|
|
snprintf (out_buf + rakp->salt_len * 2, len - 1, ":%08x%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_mode == 7400)
|
|
{
|
|
// the encoder is a bit too intelligent, it expects the input data in the wrong BOM
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
digest_buf[5] = byte_swap_32 (digest_buf[5]);
|
|
digest_buf[6] = byte_swap_32 (digest_buf[6]);
|
|
digest_buf[7] = byte_swap_32 (digest_buf[7]);
|
|
|
|
sha256crypt_encode ((unsigned char *) digest_buf, (unsigned char *) ptr_plain);
|
|
|
|
if (salt.salt_iter == ROUNDS_SHA256CRYPT)
|
|
{
|
|
snprintf (out_buf, len-1, "$5$%s$%s", (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else
|
|
{
|
|
snprintf (out_buf, len-1, "$5$rounds=%i$%s$%s", salt.salt_iter, (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
}
|
|
else if (hash_mode == 7500)
|
|
{
|
|
krb5pa_t *krb5pas = (krb5pa_t *) data.esalts_buf;
|
|
|
|
krb5pa_t *krb5pa = &krb5pas[salt_pos];
|
|
|
|
uint8_t *ptr_timestamp = (uint8_t *) krb5pa->timestamp;
|
|
uint8_t *ptr_checksum = (uint8_t *) krb5pa->checksum;
|
|
|
|
char data[128];
|
|
|
|
char *ptr_data = data;
|
|
|
|
for (uint i = 0; i < 36; i++, ptr_data += 2)
|
|
{
|
|
sprintf (ptr_data, "%02x", ptr_timestamp[i]);
|
|
}
|
|
|
|
for (uint i = 0; i < 16; i++, ptr_data += 2)
|
|
{
|
|
sprintf (ptr_data, "%02x", ptr_checksum[i]);
|
|
}
|
|
|
|
*ptr_data = 0;
|
|
|
|
snprintf (out_buf, len-1, "%s$%s$%s$%s$%s",
|
|
SIGNATURE_KRB5PA,
|
|
(char *) krb5pa->user,
|
|
(char *) krb5pa->realm,
|
|
(char *) krb5pa->salt,
|
|
data);
|
|
}
|
|
else if (hash_mode == 7700)
|
|
{
|
|
snprintf (out_buf, len-1, "%s$%08X%08X",
|
|
(char *) salt.salt_buf,
|
|
digest_buf[0],
|
|
digest_buf[1]);
|
|
}
|
|
else if (hash_mode == 7800)
|
|
{
|
|
snprintf (out_buf, len-1, "%s$%08X%08X%08X%08X%08X",
|
|
(char *) salt.salt_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_mode == 7900)
|
|
{
|
|
drupal7_encode ((unsigned char *) digest_buf64, (unsigned char *) ptr_plain);
|
|
|
|
// ugly hack start
|
|
|
|
char *tmp = (char *) salt.salt_buf_pc;
|
|
|
|
ptr_plain[42] = tmp[0];
|
|
|
|
// ugly hack end
|
|
|
|
ptr_plain[43] = 0;
|
|
|
|
snprintf (out_buf, len-1, "%s%s%s", (char *) salt.salt_sign, (char *) salt.salt_buf, (char *) ptr_plain);
|
|
}
|
|
else if (hash_mode == 8000)
|
|
{
|
|
snprintf (out_buf, len-1, "0xc007%s%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
(unsigned char *) salt.salt_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4],
|
|
digest_buf[5],
|
|
digest_buf[6],
|
|
digest_buf[7]);
|
|
}
|
|
else if (hash_mode == 8100)
|
|
{
|
|
salt.salt_buf[0] = byte_swap_32 (salt.salt_buf[0]);
|
|
salt.salt_buf[1] = byte_swap_32 (salt.salt_buf[1]);
|
|
|
|
snprintf (out_buf, len-1, "1%s%08x%08x%08x%08x%08x",
|
|
(unsigned char *) salt.salt_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_mode == 8200)
|
|
{
|
|
cloudkey_t *cloudkeys = (cloudkey_t *) data.esalts_buf;
|
|
|
|
cloudkey_t *cloudkey = &cloudkeys[salt_pos];
|
|
|
|
char data_buf[4096];
|
|
|
|
for (int i = 0, j = 0; i < 512; i += 1, j += 8)
|
|
{
|
|
sprintf (data_buf + j, "%08x", cloudkey->data_buf[i]);
|
|
}
|
|
|
|
data_buf[cloudkey->data_len * 2] = 0;
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
digest_buf[5] = byte_swap_32 (digest_buf[5]);
|
|
digest_buf[6] = byte_swap_32 (digest_buf[6]);
|
|
digest_buf[7] = byte_swap_32 (digest_buf[7]);
|
|
|
|
salt.salt_buf[0] = byte_swap_32 (salt.salt_buf[0]);
|
|
salt.salt_buf[1] = byte_swap_32 (salt.salt_buf[1]);
|
|
salt.salt_buf[2] = byte_swap_32 (salt.salt_buf[2]);
|
|
salt.salt_buf[3] = byte_swap_32 (salt.salt_buf[3]);
|
|
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x%08x%08x%08x:%08x%08x%08x%08x:%u:%s",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4],
|
|
digest_buf[5],
|
|
digest_buf[6],
|
|
digest_buf[7],
|
|
salt.salt_buf[0],
|
|
salt.salt_buf[1],
|
|
salt.salt_buf[2],
|
|
salt.salt_buf[3],
|
|
salt.salt_iter + 1,
|
|
data_buf);
|
|
}
|
|
else if (hash_mode == 8300)
|
|
{
|
|
// todo
|
|
|
|
char digest_buf_c[33];
|
|
|
|
base32_encode (int_to_itoa32, (char *) digest_buf, 32, digest_buf_c);
|
|
|
|
digest_buf_c[32] = 0;
|
|
|
|
// domain
|
|
|
|
const uint salt_pc_len = salt.salt_buf_pc[7]; // what a hack
|
|
|
|
char domain_buf_c[33];
|
|
|
|
memcpy (domain_buf_c, (char *) salt.salt_buf_pc, salt_pc_len);
|
|
|
|
for (uint i = 0; i < salt_pc_len; i++)
|
|
{
|
|
const char next = domain_buf_c[i];
|
|
|
|
domain_buf_c[i] = '.';
|
|
|
|
i += next;
|
|
}
|
|
|
|
domain_buf_c[salt_pc_len] = 0;
|
|
|
|
// final
|
|
|
|
snprintf (out_buf, len-1, "%s:%s:%s:%u", digest_buf_c, domain_buf_c, (char *) salt.salt_buf, salt.salt_iter);
|
|
}
|
|
else if (hash_mode == 8500)
|
|
{
|
|
snprintf (out_buf, len-1, "%s*%s*%08X%08X", SIGNATURE_RACF, (char *) salt.salt_buf, digest_buf[0], digest_buf[1]);
|
|
}
|
|
else if (hash_mode == 2612)
|
|
{
|
|
snprintf (out_buf, len-1, "%s%s$%08x%08x%08x%08x",
|
|
SIGNATURE_PHPS,
|
|
(char *) salt.salt_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3]);
|
|
}
|
|
else if (hash_mode == 3711)
|
|
{
|
|
char *salt_ptr = (char *) salt.salt_buf;
|
|
|
|
salt_ptr[salt.salt_len - 1] = 0;
|
|
|
|
snprintf (out_buf, len-1, "%s%s$%08x%08x%08x%08x",
|
|
SIGNATURE_MEDIAWIKI_B,
|
|
salt_ptr,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3]);
|
|
}
|
|
else if (hash_mode == 8800)
|
|
{
|
|
androidfde_t *androidfdes = (androidfde_t *) data.esalts_buf;
|
|
|
|
androidfde_t *androidfde = &androidfdes[salt_pos];
|
|
|
|
char tmp[3073];
|
|
|
|
for (uint i = 0, j = 0; i < 384; i += 1, j += 8)
|
|
{
|
|
sprintf (tmp + j, "%08x", androidfde->data[i]);
|
|
}
|
|
|
|
tmp[3072] = 0;
|
|
|
|
snprintf (out_buf, len-1, "%s16$%08x%08x%08x%08x$16$%08x%08x%08x%08x$%s",
|
|
SIGNATURE_ANDROIDFDE,
|
|
byte_swap_32 (salt.salt_buf[0]),
|
|
byte_swap_32 (salt.salt_buf[1]),
|
|
byte_swap_32 (salt.salt_buf[2]),
|
|
byte_swap_32 (salt.salt_buf[3]),
|
|
byte_swap_32 (digest_buf[0]),
|
|
byte_swap_32 (digest_buf[1]),
|
|
byte_swap_32 (digest_buf[2]),
|
|
byte_swap_32 (digest_buf[3]),
|
|
tmp);
|
|
}
|
|
else if (hash_mode == 8900)
|
|
{
|
|
uint N = salt.scrypt_N;
|
|
uint r = salt.scrypt_r;
|
|
uint p = salt.scrypt_p;
|
|
|
|
char base64_salt[32];
|
|
|
|
memset (base64_salt, 0, 32);
|
|
|
|
base64_encode (int_to_base64, (char *) salt.salt_buf, salt.salt_len, base64_salt + 0);
|
|
|
|
memset (tmp_buf, 0, 46);
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
digest_buf[5] = byte_swap_32 (digest_buf[5]);
|
|
digest_buf[6] = byte_swap_32 (digest_buf[6]);
|
|
digest_buf[7] = byte_swap_32 (digest_buf[7]);
|
|
digest_buf[8] = 0; // needed for base64_encode ()
|
|
|
|
base64_encode (int_to_base64, (char *) digest_buf, 32, tmp_buf + 0);
|
|
|
|
snprintf (out_buf, len-1, "%s:%i:%i:%i:%s:%s",
|
|
SIGNATURE_SCRYPT,
|
|
N,
|
|
r,
|
|
p,
|
|
base64_salt,
|
|
tmp_buf);
|
|
}
|
|
else if (hash_mode == 9000)
|
|
{
|
|
snprintf (out_buf, len-1, "%s", hashfile);
|
|
}
|
|
else if (hash_mode == 9200)
|
|
{
|
|
// salt
|
|
|
|
pbkdf2_sha256_t *pbkdf2_sha256s = (pbkdf2_sha256_t *) data.esalts_buf;
|
|
|
|
pbkdf2_sha256_t *pbkdf2_sha256 = &pbkdf2_sha256s[salt_pos];
|
|
|
|
unsigned char *salt_buf_ptr = (unsigned char *) pbkdf2_sha256->salt_buf;
|
|
|
|
// hash
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
digest_buf[5] = byte_swap_32 (digest_buf[5]);
|
|
digest_buf[6] = byte_swap_32 (digest_buf[6]);
|
|
digest_buf[7] = byte_swap_32 (digest_buf[7]);
|
|
digest_buf[8] = 0; // needed for base64_encode ()
|
|
|
|
char tmp_buf[64];
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_encode (int_to_itoa64, (char *) digest_buf, 32, tmp_buf);
|
|
tmp_buf[43] = 0; // cut it here
|
|
|
|
// output
|
|
|
|
snprintf (out_buf, len-1, "%s%s$%s", SIGNATURE_CISCO8, salt_buf_ptr, tmp_buf);
|
|
}
|
|
else if (hash_mode == 9300)
|
|
{
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
digest_buf[5] = byte_swap_32 (digest_buf[5]);
|
|
digest_buf[6] = byte_swap_32 (digest_buf[6]);
|
|
digest_buf[7] = byte_swap_32 (digest_buf[7]);
|
|
digest_buf[8] = 0; // needed for base64_encode ()
|
|
|
|
char tmp_buf[64];
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_encode (int_to_itoa64, (char *) digest_buf, 32, tmp_buf);
|
|
tmp_buf[43] = 0; // cut it here
|
|
|
|
unsigned char *salt_buf_ptr = (unsigned char *) salt.salt_buf;
|
|
|
|
snprintf (out_buf, len-1, "%s%s$%s", SIGNATURE_CISCO9, salt_buf_ptr, tmp_buf);
|
|
}
|
|
else if (hash_mode == 9400)
|
|
{
|
|
office2007_t *office2007s = (office2007_t *) data.esalts_buf;
|
|
|
|
office2007_t *office2007 = &office2007s[salt_pos];
|
|
|
|
snprintf (out_buf, len-1, "%s*%u*%u*%u*%u*%08x%08x%08x%08x*%08x%08x%08x%08x*%08x%08x%08x%08x%08x",
|
|
SIGNATURE_OFFICE2007,
|
|
2007,
|
|
20,
|
|
office2007->keySize,
|
|
16,
|
|
salt.salt_buf[0],
|
|
salt.salt_buf[1],
|
|
salt.salt_buf[2],
|
|
salt.salt_buf[3],
|
|
office2007->encryptedVerifier[0],
|
|
office2007->encryptedVerifier[1],
|
|
office2007->encryptedVerifier[2],
|
|
office2007->encryptedVerifier[3],
|
|
office2007->encryptedVerifierHash[0],
|
|
office2007->encryptedVerifierHash[1],
|
|
office2007->encryptedVerifierHash[2],
|
|
office2007->encryptedVerifierHash[3],
|
|
office2007->encryptedVerifierHash[4]);
|
|
}
|
|
else if (hash_mode == 9500)
|
|
{
|
|
office2010_t *office2010s = (office2010_t *) data.esalts_buf;
|
|
|
|
office2010_t *office2010 = &office2010s[salt_pos];
|
|
|
|
snprintf (out_buf, len-1, "%s*%u*%u*%u*%u*%08x%08x%08x%08x*%08x%08x%08x%08x*%08x%08x%08x%08x%08x%08x%08x%08x", SIGNATURE_OFFICE2010, 2010, 100000, 128, 16,
|
|
|
|
salt.salt_buf[0],
|
|
salt.salt_buf[1],
|
|
salt.salt_buf[2],
|
|
salt.salt_buf[3],
|
|
office2010->encryptedVerifier[0],
|
|
office2010->encryptedVerifier[1],
|
|
office2010->encryptedVerifier[2],
|
|
office2010->encryptedVerifier[3],
|
|
office2010->encryptedVerifierHash[0],
|
|
office2010->encryptedVerifierHash[1],
|
|
office2010->encryptedVerifierHash[2],
|
|
office2010->encryptedVerifierHash[3],
|
|
office2010->encryptedVerifierHash[4],
|
|
office2010->encryptedVerifierHash[5],
|
|
office2010->encryptedVerifierHash[6],
|
|
office2010->encryptedVerifierHash[7]);
|
|
}
|
|
else if (hash_mode == 9600)
|
|
{
|
|
office2013_t *office2013s = (office2013_t *) data.esalts_buf;
|
|
|
|
office2013_t *office2013 = &office2013s[salt_pos];
|
|
|
|
snprintf (out_buf, len-1, "%s*%u*%u*%u*%u*%08x%08x%08x%08x*%08x%08x%08x%08x*%08x%08x%08x%08x%08x%08x%08x%08x", SIGNATURE_OFFICE2013, 2013, 100000, 256, 16,
|
|
|
|
salt.salt_buf[0],
|
|
salt.salt_buf[1],
|
|
salt.salt_buf[2],
|
|
salt.salt_buf[3],
|
|
office2013->encryptedVerifier[0],
|
|
office2013->encryptedVerifier[1],
|
|
office2013->encryptedVerifier[2],
|
|
office2013->encryptedVerifier[3],
|
|
office2013->encryptedVerifierHash[0],
|
|
office2013->encryptedVerifierHash[1],
|
|
office2013->encryptedVerifierHash[2],
|
|
office2013->encryptedVerifierHash[3],
|
|
office2013->encryptedVerifierHash[4],
|
|
office2013->encryptedVerifierHash[5],
|
|
office2013->encryptedVerifierHash[6],
|
|
office2013->encryptedVerifierHash[7]);
|
|
}
|
|
else if (hash_mode == 9700)
|
|
{
|
|
oldoffice01_t *oldoffice01s = (oldoffice01_t *) data.esalts_buf;
|
|
|
|
oldoffice01_t *oldoffice01 = &oldoffice01s[salt_pos];
|
|
|
|
snprintf (out_buf, len-1, "%s*%08x%08x%08x%08x*%08x%08x%08x%08x*%08x%08x%08x%08x",
|
|
(oldoffice01->version == 0) ? SIGNATURE_OLDOFFICE0 : SIGNATURE_OLDOFFICE1,
|
|
byte_swap_32 (salt.salt_buf[0]),
|
|
byte_swap_32 (salt.salt_buf[1]),
|
|
byte_swap_32 (salt.salt_buf[2]),
|
|
byte_swap_32 (salt.salt_buf[3]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[0]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[1]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[2]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[3]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[0]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[1]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[2]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[3]));
|
|
}
|
|
else if (hash_mode == 9710)
|
|
{
|
|
oldoffice01_t *oldoffice01s = (oldoffice01_t *) data.esalts_buf;
|
|
|
|
oldoffice01_t *oldoffice01 = &oldoffice01s[salt_pos];
|
|
|
|
snprintf (out_buf, len-1, "%s*%08x%08x%08x%08x*%08x%08x%08x%08x*%08x%08x%08x%08x",
|
|
(oldoffice01->version == 0) ? SIGNATURE_OLDOFFICE0 : SIGNATURE_OLDOFFICE1,
|
|
byte_swap_32 (salt.salt_buf[0]),
|
|
byte_swap_32 (salt.salt_buf[1]),
|
|
byte_swap_32 (salt.salt_buf[2]),
|
|
byte_swap_32 (salt.salt_buf[3]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[0]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[1]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[2]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[3]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[0]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[1]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[2]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[3]));
|
|
}
|
|
else if (hash_mode == 9720)
|
|
{
|
|
oldoffice01_t *oldoffice01s = (oldoffice01_t *) data.esalts_buf;
|
|
|
|
oldoffice01_t *oldoffice01 = &oldoffice01s[salt_pos];
|
|
|
|
uint8_t *rc4key = (uint8_t *) oldoffice01->rc4key;
|
|
|
|
snprintf (out_buf, len-1, "%s*%08x%08x%08x%08x*%08x%08x%08x%08x*%08x%08x%08x%08x:%02x%02x%02x%02x%02x",
|
|
(oldoffice01->version == 0) ? SIGNATURE_OLDOFFICE0 : SIGNATURE_OLDOFFICE1,
|
|
byte_swap_32 (salt.salt_buf[0]),
|
|
byte_swap_32 (salt.salt_buf[1]),
|
|
byte_swap_32 (salt.salt_buf[2]),
|
|
byte_swap_32 (salt.salt_buf[3]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[0]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[1]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[2]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifier[3]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[0]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[1]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[2]),
|
|
byte_swap_32 (oldoffice01->encryptedVerifierHash[3]),
|
|
rc4key[0],
|
|
rc4key[1],
|
|
rc4key[2],
|
|
rc4key[3],
|
|
rc4key[4]);
|
|
}
|
|
else if (hash_mode == 9800)
|
|
{
|
|
oldoffice34_t *oldoffice34s = (oldoffice34_t *) data.esalts_buf;
|
|
|
|
oldoffice34_t *oldoffice34 = &oldoffice34s[salt_pos];
|
|
|
|
snprintf (out_buf, len-1, "%s*%08x%08x%08x%08x*%08x%08x%08x%08x*%08x%08x%08x%08x%08x",
|
|
(oldoffice34->version == 3) ? SIGNATURE_OLDOFFICE3 : SIGNATURE_OLDOFFICE4,
|
|
salt.salt_buf[0],
|
|
salt.salt_buf[1],
|
|
salt.salt_buf[2],
|
|
salt.salt_buf[3],
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[0]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[1]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[2]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[3]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[0]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[1]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[2]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[3]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[4]));
|
|
}
|
|
else if (hash_mode == 9810)
|
|
{
|
|
oldoffice34_t *oldoffice34s = (oldoffice34_t *) data.esalts_buf;
|
|
|
|
oldoffice34_t *oldoffice34 = &oldoffice34s[salt_pos];
|
|
|
|
snprintf (out_buf, len-1, "%s*%08x%08x%08x%08x*%08x%08x%08x%08x*%08x%08x%08x%08x%08x",
|
|
(oldoffice34->version == 3) ? SIGNATURE_OLDOFFICE3 : SIGNATURE_OLDOFFICE4,
|
|
salt.salt_buf[0],
|
|
salt.salt_buf[1],
|
|
salt.salt_buf[2],
|
|
salt.salt_buf[3],
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[0]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[1]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[2]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[3]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[0]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[1]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[2]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[3]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[4]));
|
|
}
|
|
else if (hash_mode == 9820)
|
|
{
|
|
oldoffice34_t *oldoffice34s = (oldoffice34_t *) data.esalts_buf;
|
|
|
|
oldoffice34_t *oldoffice34 = &oldoffice34s[salt_pos];
|
|
|
|
uint8_t *rc4key = (uint8_t *) oldoffice34->rc4key;
|
|
|
|
snprintf (out_buf, len-1, "%s*%08x%08x%08x%08x*%08x%08x%08x%08x*%08x%08x%08x%08x%08x:%02x%02x%02x%02x%02x",
|
|
(oldoffice34->version == 3) ? SIGNATURE_OLDOFFICE3 : SIGNATURE_OLDOFFICE4,
|
|
salt.salt_buf[0],
|
|
salt.salt_buf[1],
|
|
salt.salt_buf[2],
|
|
salt.salt_buf[3],
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[0]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[1]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[2]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifier[3]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[0]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[1]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[2]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[3]),
|
|
byte_swap_32 (oldoffice34->encryptedVerifierHash[4]),
|
|
rc4key[0],
|
|
rc4key[1],
|
|
rc4key[2],
|
|
rc4key[3],
|
|
rc4key[4]);
|
|
}
|
|
else if (hash_mode == 10000)
|
|
{
|
|
// salt
|
|
|
|
pbkdf2_sha256_t *pbkdf2_sha256s = (pbkdf2_sha256_t *) data.esalts_buf;
|
|
|
|
pbkdf2_sha256_t *pbkdf2_sha256 = &pbkdf2_sha256s[salt_pos];
|
|
|
|
unsigned char *salt_buf_ptr = (unsigned char *) pbkdf2_sha256->salt_buf;
|
|
|
|
// hash
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
digest_buf[2] = byte_swap_32 (digest_buf[2]);
|
|
digest_buf[3] = byte_swap_32 (digest_buf[3]);
|
|
digest_buf[4] = byte_swap_32 (digest_buf[4]);
|
|
digest_buf[5] = byte_swap_32 (digest_buf[5]);
|
|
digest_buf[6] = byte_swap_32 (digest_buf[6]);
|
|
digest_buf[7] = byte_swap_32 (digest_buf[7]);
|
|
digest_buf[8] = 0; // needed for base64_encode ()
|
|
|
|
char tmp_buf[64];
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_encode (int_to_base64, (char *) digest_buf, 32, tmp_buf);
|
|
|
|
// output
|
|
|
|
snprintf (out_buf, len-1, "%s%i$%s$%s", SIGNATURE_DJANGOPBKDF2, salt.salt_iter + 1, salt_buf_ptr, tmp_buf);
|
|
}
|
|
else if (hash_mode == 10100)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x:%u:%u:%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
2,
|
|
4,
|
|
byte_swap_32 (salt.salt_buf[0]),
|
|
byte_swap_32 (salt.salt_buf[1]),
|
|
byte_swap_32 (salt.salt_buf[2]),
|
|
byte_swap_32 (salt.salt_buf[3]));
|
|
}
|
|
else if (hash_mode == 10200)
|
|
{
|
|
cram_md5_t *cram_md5s = (cram_md5_t *) data.esalts_buf;
|
|
|
|
cram_md5_t *cram_md5 = &cram_md5s[salt_pos];
|
|
|
|
// challenge
|
|
|
|
char challenge[100];
|
|
|
|
memset (challenge, 0, sizeof (challenge));
|
|
|
|
base64_encode (int_to_base64, (char *) salt.salt_buf, salt.salt_len, challenge);
|
|
|
|
// response
|
|
|
|
char tmp_buf[100];
|
|
|
|
uint tmp_len = snprintf (tmp_buf, 100, "%s %08x%08x%08x%08x",
|
|
(char *) cram_md5->user,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3]);
|
|
|
|
char response[100];
|
|
|
|
memset (response, 0, sizeof (response));
|
|
|
|
base64_encode (int_to_base64, (char *) tmp_buf, tmp_len, response);
|
|
|
|
snprintf (out_buf, len-1, "%s%s$%s", SIGNATURE_CRAM_MD5, challenge, response);
|
|
}
|
|
else if (hash_mode == 10300)
|
|
{
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
memcpy (tmp_buf + 0, digest_buf, 20);
|
|
memcpy (tmp_buf + 20, salt.salt_buf, salt.salt_len);
|
|
|
|
uint tmp_len = 20 + salt.salt_len;
|
|
|
|
// base64 encode it
|
|
|
|
char base64_encoded[100];
|
|
|
|
memset (base64_encoded, 0, sizeof (base64_encoded));
|
|
|
|
base64_encode (int_to_base64, (char *) tmp_buf, tmp_len, base64_encoded);
|
|
|
|
snprintf (out_buf, len-1, "%s%i}%s", SIGNATURE_SAPH_SHA1, salt.salt_iter + 1, base64_encoded);
|
|
}
|
|
else if (hash_mode == 10400)
|
|
{
|
|
pdf_t *pdfs = (pdf_t *) data.esalts_buf;
|
|
|
|
pdf_t *pdf = &pdfs[salt_pos];
|
|
|
|
snprintf (out_buf, len-1, "$pdf$%d*%d*%d*%d*%d*%d*%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
|
|
pdf->V,
|
|
pdf->R,
|
|
40,
|
|
pdf->P,
|
|
pdf->enc_md,
|
|
pdf->id_len,
|
|
byte_swap_32 (pdf->id_buf[0]),
|
|
byte_swap_32 (pdf->id_buf[1]),
|
|
byte_swap_32 (pdf->id_buf[2]),
|
|
byte_swap_32 (pdf->id_buf[3]),
|
|
pdf->u_len,
|
|
byte_swap_32 (pdf->u_buf[0]),
|
|
byte_swap_32 (pdf->u_buf[1]),
|
|
byte_swap_32 (pdf->u_buf[2]),
|
|
byte_swap_32 (pdf->u_buf[3]),
|
|
byte_swap_32 (pdf->u_buf[4]),
|
|
byte_swap_32 (pdf->u_buf[5]),
|
|
byte_swap_32 (pdf->u_buf[6]),
|
|
byte_swap_32 (pdf->u_buf[7]),
|
|
pdf->o_len,
|
|
byte_swap_32 (pdf->o_buf[0]),
|
|
byte_swap_32 (pdf->o_buf[1]),
|
|
byte_swap_32 (pdf->o_buf[2]),
|
|
byte_swap_32 (pdf->o_buf[3]),
|
|
byte_swap_32 (pdf->o_buf[4]),
|
|
byte_swap_32 (pdf->o_buf[5]),
|
|
byte_swap_32 (pdf->o_buf[6]),
|
|
byte_swap_32 (pdf->o_buf[7])
|
|
);
|
|
}
|
|
else if (hash_mode == 10410)
|
|
{
|
|
pdf_t *pdfs = (pdf_t *) data.esalts_buf;
|
|
|
|
pdf_t *pdf = &pdfs[salt_pos];
|
|
|
|
snprintf (out_buf, len-1, "$pdf$%d*%d*%d*%d*%d*%d*%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
|
|
pdf->V,
|
|
pdf->R,
|
|
40,
|
|
pdf->P,
|
|
pdf->enc_md,
|
|
pdf->id_len,
|
|
byte_swap_32 (pdf->id_buf[0]),
|
|
byte_swap_32 (pdf->id_buf[1]),
|
|
byte_swap_32 (pdf->id_buf[2]),
|
|
byte_swap_32 (pdf->id_buf[3]),
|
|
pdf->u_len,
|
|
byte_swap_32 (pdf->u_buf[0]),
|
|
byte_swap_32 (pdf->u_buf[1]),
|
|
byte_swap_32 (pdf->u_buf[2]),
|
|
byte_swap_32 (pdf->u_buf[3]),
|
|
byte_swap_32 (pdf->u_buf[4]),
|
|
byte_swap_32 (pdf->u_buf[5]),
|
|
byte_swap_32 (pdf->u_buf[6]),
|
|
byte_swap_32 (pdf->u_buf[7]),
|
|
pdf->o_len,
|
|
byte_swap_32 (pdf->o_buf[0]),
|
|
byte_swap_32 (pdf->o_buf[1]),
|
|
byte_swap_32 (pdf->o_buf[2]),
|
|
byte_swap_32 (pdf->o_buf[3]),
|
|
byte_swap_32 (pdf->o_buf[4]),
|
|
byte_swap_32 (pdf->o_buf[5]),
|
|
byte_swap_32 (pdf->o_buf[6]),
|
|
byte_swap_32 (pdf->o_buf[7])
|
|
);
|
|
}
|
|
else if (hash_mode == 10420)
|
|
{
|
|
pdf_t *pdfs = (pdf_t *) data.esalts_buf;
|
|
|
|
pdf_t *pdf = &pdfs[salt_pos];
|
|
|
|
uint8_t *rc4key = (uint8_t *) pdf->rc4key;
|
|
|
|
snprintf (out_buf, len-1, "$pdf$%d*%d*%d*%d*%d*%d*%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x:%02x%02x%02x%02x%02x",
|
|
|
|
pdf->V,
|
|
pdf->R,
|
|
40,
|
|
pdf->P,
|
|
pdf->enc_md,
|
|
pdf->id_len,
|
|
byte_swap_32 (pdf->id_buf[0]),
|
|
byte_swap_32 (pdf->id_buf[1]),
|
|
byte_swap_32 (pdf->id_buf[2]),
|
|
byte_swap_32 (pdf->id_buf[3]),
|
|
pdf->u_len,
|
|
byte_swap_32 (pdf->u_buf[0]),
|
|
byte_swap_32 (pdf->u_buf[1]),
|
|
byte_swap_32 (pdf->u_buf[2]),
|
|
byte_swap_32 (pdf->u_buf[3]),
|
|
byte_swap_32 (pdf->u_buf[4]),
|
|
byte_swap_32 (pdf->u_buf[5]),
|
|
byte_swap_32 (pdf->u_buf[6]),
|
|
byte_swap_32 (pdf->u_buf[7]),
|
|
pdf->o_len,
|
|
byte_swap_32 (pdf->o_buf[0]),
|
|
byte_swap_32 (pdf->o_buf[1]),
|
|
byte_swap_32 (pdf->o_buf[2]),
|
|
byte_swap_32 (pdf->o_buf[3]),
|
|
byte_swap_32 (pdf->o_buf[4]),
|
|
byte_swap_32 (pdf->o_buf[5]),
|
|
byte_swap_32 (pdf->o_buf[6]),
|
|
byte_swap_32 (pdf->o_buf[7]),
|
|
rc4key[0],
|
|
rc4key[1],
|
|
rc4key[2],
|
|
rc4key[3],
|
|
rc4key[4]
|
|
);
|
|
}
|
|
else if (hash_mode == 10500)
|
|
{
|
|
pdf_t *pdfs = (pdf_t *) data.esalts_buf;
|
|
|
|
pdf_t *pdf = &pdfs[salt_pos];
|
|
|
|
if (pdf->id_len == 32)
|
|
{
|
|
snprintf (out_buf, len-1, "$pdf$%d*%d*%d*%d*%d*%d*%08x%08x%08x%08x%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
|
|
pdf->V,
|
|
pdf->R,
|
|
128,
|
|
pdf->P,
|
|
pdf->enc_md,
|
|
pdf->id_len,
|
|
byte_swap_32 (pdf->id_buf[0]),
|
|
byte_swap_32 (pdf->id_buf[1]),
|
|
byte_swap_32 (pdf->id_buf[2]),
|
|
byte_swap_32 (pdf->id_buf[3]),
|
|
byte_swap_32 (pdf->id_buf[4]),
|
|
byte_swap_32 (pdf->id_buf[5]),
|
|
byte_swap_32 (pdf->id_buf[6]),
|
|
byte_swap_32 (pdf->id_buf[7]),
|
|
pdf->u_len,
|
|
byte_swap_32 (pdf->u_buf[0]),
|
|
byte_swap_32 (pdf->u_buf[1]),
|
|
byte_swap_32 (pdf->u_buf[2]),
|
|
byte_swap_32 (pdf->u_buf[3]),
|
|
byte_swap_32 (pdf->u_buf[4]),
|
|
byte_swap_32 (pdf->u_buf[5]),
|
|
byte_swap_32 (pdf->u_buf[6]),
|
|
byte_swap_32 (pdf->u_buf[7]),
|
|
pdf->o_len,
|
|
byte_swap_32 (pdf->o_buf[0]),
|
|
byte_swap_32 (pdf->o_buf[1]),
|
|
byte_swap_32 (pdf->o_buf[2]),
|
|
byte_swap_32 (pdf->o_buf[3]),
|
|
byte_swap_32 (pdf->o_buf[4]),
|
|
byte_swap_32 (pdf->o_buf[5]),
|
|
byte_swap_32 (pdf->o_buf[6]),
|
|
byte_swap_32 (pdf->o_buf[7])
|
|
);
|
|
}
|
|
else
|
|
{
|
|
snprintf (out_buf, len-1, "$pdf$%d*%d*%d*%d*%d*%d*%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x*%d*%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
|
|
pdf->V,
|
|
pdf->R,
|
|
128,
|
|
pdf->P,
|
|
pdf->enc_md,
|
|
pdf->id_len,
|
|
byte_swap_32 (pdf->id_buf[0]),
|
|
byte_swap_32 (pdf->id_buf[1]),
|
|
byte_swap_32 (pdf->id_buf[2]),
|
|
byte_swap_32 (pdf->id_buf[3]),
|
|
pdf->u_len,
|
|
byte_swap_32 (pdf->u_buf[0]),
|
|
byte_swap_32 (pdf->u_buf[1]),
|
|
byte_swap_32 (pdf->u_buf[2]),
|
|
byte_swap_32 (pdf->u_buf[3]),
|
|
byte_swap_32 (pdf->u_buf[4]),
|
|
byte_swap_32 (pdf->u_buf[5]),
|
|
byte_swap_32 (pdf->u_buf[6]),
|
|
byte_swap_32 (pdf->u_buf[7]),
|
|
pdf->o_len,
|
|
byte_swap_32 (pdf->o_buf[0]),
|
|
byte_swap_32 (pdf->o_buf[1]),
|
|
byte_swap_32 (pdf->o_buf[2]),
|
|
byte_swap_32 (pdf->o_buf[3]),
|
|
byte_swap_32 (pdf->o_buf[4]),
|
|
byte_swap_32 (pdf->o_buf[5]),
|
|
byte_swap_32 (pdf->o_buf[6]),
|
|
byte_swap_32 (pdf->o_buf[7])
|
|
);
|
|
}
|
|
}
|
|
else if (hash_mode == 10600)
|
|
{
|
|
uint digest_idx = salt.digests_offset + digest_pos;
|
|
|
|
hashinfo_t **hashinfo_ptr = data.hash_info;
|
|
char *hash_buf = hashinfo_ptr[digest_idx]->orighash;
|
|
|
|
snprintf (out_buf, len-1, "%s", hash_buf);
|
|
}
|
|
else if (hash_mode == 10700)
|
|
{
|
|
uint digest_idx = salt.digests_offset + digest_pos;
|
|
|
|
hashinfo_t **hashinfo_ptr = data.hash_info;
|
|
char *hash_buf = hashinfo_ptr[digest_idx]->orighash;
|
|
|
|
snprintf (out_buf, len-1, "%s", hash_buf);
|
|
}
|
|
else if (hash_mode == 10900)
|
|
{
|
|
uint digest_idx = salt.digests_offset + digest_pos;
|
|
|
|
hashinfo_t **hashinfo_ptr = data.hash_info;
|
|
char *hash_buf = hashinfo_ptr[digest_idx]->orighash;
|
|
|
|
snprintf (out_buf, len-1, "%s", hash_buf);
|
|
}
|
|
else if (hash_mode == 11100)
|
|
{
|
|
uint32_t salt_challenge = salt.salt_buf[0];
|
|
|
|
salt_challenge = byte_swap_32 (salt_challenge);
|
|
|
|
unsigned char *user_name = (unsigned char *) (salt.salt_buf + 1);
|
|
|
|
snprintf (out_buf, len-1, "%s%s*%08x*%08x%08x%08x%08x",
|
|
SIGNATURE_POSTGRESQL_AUTH,
|
|
user_name,
|
|
salt_challenge,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3]);
|
|
}
|
|
else if (hash_mode == 11200)
|
|
{
|
|
snprintf (out_buf, len-1, "%s%s*%08x%08x%08x%08x%08x",
|
|
SIGNATURE_MYSQL_AUTH,
|
|
(unsigned char *) salt.salt_buf,
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_mode == 11300)
|
|
{
|
|
bitcoin_wallet_t *bitcoin_wallets = (bitcoin_wallet_t *) data.esalts_buf;
|
|
|
|
bitcoin_wallet_t *bitcoin_wallet = &bitcoin_wallets[salt_pos];
|
|
|
|
const uint cry_master_len = bitcoin_wallet->cry_master_len;
|
|
const uint ckey_len = bitcoin_wallet->ckey_len;
|
|
const uint public_key_len = bitcoin_wallet->public_key_len;
|
|
|
|
char *cry_master_buf = (char *) mymalloc ((cry_master_len * 2) + 1);
|
|
char *ckey_buf = (char *) mymalloc ((ckey_len * 2) + 1);
|
|
char *public_key_buf = (char *) mymalloc ((public_key_len * 2) + 1);
|
|
|
|
for (uint i = 0, j = 0; i < cry_master_len; i += 1, j += 2)
|
|
{
|
|
const uint8_t *ptr = (const uint8_t *) bitcoin_wallet->cry_master_buf;
|
|
|
|
sprintf (cry_master_buf + j, "%02x", ptr[i]);
|
|
}
|
|
|
|
for (uint i = 0, j = 0; i < ckey_len; i += 1, j += 2)
|
|
{
|
|
const uint8_t *ptr = (const uint8_t *) bitcoin_wallet->ckey_buf;
|
|
|
|
sprintf (ckey_buf + j, "%02x", ptr[i]);
|
|
}
|
|
|
|
for (uint i = 0, j = 0; i < public_key_len; i += 1, j += 2)
|
|
{
|
|
const uint8_t *ptr = (const uint8_t *) bitcoin_wallet->public_key_buf;
|
|
|
|
sprintf (public_key_buf + j, "%02x", ptr[i]);
|
|
}
|
|
|
|
snprintf (out_buf, len-1, "%s%d$%s$%d$%s$%d$%d$%s$%d$%s",
|
|
SIGNATURE_BITCOIN_WALLET,
|
|
cry_master_len * 2,
|
|
cry_master_buf,
|
|
salt.salt_len,
|
|
(unsigned char *) salt.salt_buf,
|
|
salt.salt_iter + 1,
|
|
ckey_len * 2,
|
|
ckey_buf,
|
|
public_key_len * 2,
|
|
public_key_buf
|
|
);
|
|
|
|
free (cry_master_buf);
|
|
free (ckey_buf);
|
|
free (public_key_buf);
|
|
}
|
|
else if (hash_mode == 11400)
|
|
{
|
|
uint digest_idx = salt.digests_offset + digest_pos;
|
|
|
|
hashinfo_t **hashinfo_ptr = data.hash_info;
|
|
char *hash_buf = hashinfo_ptr[digest_idx]->orighash;
|
|
|
|
snprintf (out_buf, len-1, "%s", hash_buf);
|
|
}
|
|
else if (hash_mode == 11600)
|
|
{
|
|
seven_zip_t *seven_zips = (seven_zip_t *) data.esalts_buf;
|
|
|
|
seven_zip_t *seven_zip = &seven_zips[salt_pos];
|
|
|
|
const uint data_len = seven_zip->data_len;
|
|
|
|
char *data_buf = (char *) mymalloc ((data_len * 2) + 1);
|
|
|
|
for (uint i = 0, j = 0; i < data_len; i += 1, j += 2)
|
|
{
|
|
const uint8_t *ptr = (const uint8_t *) seven_zip->data_buf;
|
|
|
|
sprintf (data_buf + j, "%02x", ptr[i]);
|
|
}
|
|
|
|
snprintf (out_buf, len-1, "%s%u$%u$%u$%s$%u$%08x%08x%08x%08x$%u$%u$%u$%s",
|
|
SIGNATURE_SEVEN_ZIP,
|
|
0,
|
|
salt.salt_sign[0],
|
|
0,
|
|
(char *) seven_zip->salt_buf,
|
|
seven_zip->iv_len,
|
|
seven_zip->iv_buf[0],
|
|
seven_zip->iv_buf[1],
|
|
seven_zip->iv_buf[2],
|
|
seven_zip->iv_buf[3],
|
|
seven_zip->crc,
|
|
seven_zip->data_len,
|
|
seven_zip->unpack_size,
|
|
data_buf);
|
|
|
|
free (data_buf);
|
|
}
|
|
else if (hash_mode == 11700)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4],
|
|
digest_buf[5],
|
|
digest_buf[6],
|
|
digest_buf[7]);
|
|
}
|
|
else if (hash_mode == 11800)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
digest_buf[ 0],
|
|
digest_buf[ 1],
|
|
digest_buf[ 2],
|
|
digest_buf[ 3],
|
|
digest_buf[ 4],
|
|
digest_buf[ 5],
|
|
digest_buf[ 6],
|
|
digest_buf[ 7],
|
|
digest_buf[ 8],
|
|
digest_buf[ 9],
|
|
digest_buf[10],
|
|
digest_buf[11],
|
|
digest_buf[12],
|
|
digest_buf[13],
|
|
digest_buf[14],
|
|
digest_buf[15]);
|
|
}
|
|
else if (hash_mode == 11900)
|
|
{
|
|
uint digest_idx = salt.digests_offset + digest_pos;
|
|
|
|
hashinfo_t **hashinfo_ptr = data.hash_info;
|
|
char *hash_buf = hashinfo_ptr[digest_idx]->orighash;
|
|
|
|
snprintf (out_buf, len-1, "%s", hash_buf);
|
|
}
|
|
else if (hash_mode == 12000)
|
|
{
|
|
uint digest_idx = salt.digests_offset + digest_pos;
|
|
|
|
hashinfo_t **hashinfo_ptr = data.hash_info;
|
|
char *hash_buf = hashinfo_ptr[digest_idx]->orighash;
|
|
|
|
snprintf (out_buf, len-1, "%s", hash_buf);
|
|
}
|
|
else if (hash_mode == 12100)
|
|
{
|
|
uint digest_idx = salt.digests_offset + digest_pos;
|
|
|
|
hashinfo_t **hashinfo_ptr = data.hash_info;
|
|
char *hash_buf = hashinfo_ptr[digest_idx]->orighash;
|
|
|
|
snprintf (out_buf, len-1, "%s", hash_buf);
|
|
}
|
|
else if (hash_mode == 12200)
|
|
{
|
|
uint *ptr_digest = digest_buf;
|
|
uint *ptr_salt = salt.salt_buf;
|
|
|
|
snprintf (out_buf, len-1, "%s0$1$%08x%08x$%08x%08x",
|
|
SIGNATURE_ECRYPTFS,
|
|
ptr_salt[0],
|
|
ptr_salt[1],
|
|
ptr_digest[0],
|
|
ptr_digest[1]);
|
|
}
|
|
else if (hash_mode == 12300)
|
|
{
|
|
uint *ptr_digest = digest_buf;
|
|
uint *ptr_salt = salt.salt_buf;
|
|
|
|
snprintf (out_buf, len-1, "%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
|
|
ptr_digest[ 0], ptr_digest[ 1],
|
|
ptr_digest[ 2], ptr_digest[ 3],
|
|
ptr_digest[ 4], ptr_digest[ 5],
|
|
ptr_digest[ 6], ptr_digest[ 7],
|
|
ptr_digest[ 8], ptr_digest[ 9],
|
|
ptr_digest[10], ptr_digest[11],
|
|
ptr_digest[12], ptr_digest[13],
|
|
ptr_digest[14], ptr_digest[15],
|
|
ptr_salt[0],
|
|
ptr_salt[1],
|
|
ptr_salt[2],
|
|
ptr_salt[3]);
|
|
}
|
|
else if (hash_mode == 12400)
|
|
{
|
|
// encode iteration count
|
|
|
|
char salt_iter[5];
|
|
|
|
salt_iter[0] = int_to_itoa64 ((salt.salt_iter ) & 0x3f);
|
|
salt_iter[1] = int_to_itoa64 ((salt.salt_iter >> 6) & 0x3f);
|
|
salt_iter[2] = int_to_itoa64 ((salt.salt_iter >> 12) & 0x3f);
|
|
salt_iter[3] = int_to_itoa64 ((salt.salt_iter >> 18) & 0x3f);
|
|
salt_iter[4] = 0;
|
|
|
|
// encode salt
|
|
|
|
ptr_salt[0] = int_to_itoa64 ((salt.salt_buf[0] ) & 0x3f);
|
|
ptr_salt[1] = int_to_itoa64 ((salt.salt_buf[0] >> 6) & 0x3f);
|
|
ptr_salt[2] = int_to_itoa64 ((salt.salt_buf[0] >> 12) & 0x3f);
|
|
ptr_salt[3] = int_to_itoa64 ((salt.salt_buf[0] >> 18) & 0x3f);
|
|
ptr_salt[4] = 0;
|
|
|
|
// encode digest
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
digest_buf[0] = byte_swap_32 (digest_buf[0]);
|
|
digest_buf[1] = byte_swap_32 (digest_buf[1]);
|
|
|
|
memcpy (tmp_buf, digest_buf, 8);
|
|
|
|
base64_encode (int_to_itoa64, tmp_buf, 8, ptr_plain);
|
|
|
|
ptr_plain[11] = 0;
|
|
|
|
// fill the resulting buffer
|
|
|
|
snprintf (out_buf, len - 1, "_%s%s%s", salt_iter, ptr_salt, ptr_plain);
|
|
}
|
|
else if (hash_mode == 12500)
|
|
{
|
|
snprintf (out_buf, len - 1, "%s*0*%08x%08x*%08x%08x%08x%08x",
|
|
SIGNATURE_RAR3,
|
|
byte_swap_32 (salt.salt_buf[0]),
|
|
byte_swap_32 (salt.salt_buf[1]),
|
|
salt.salt_buf[2],
|
|
salt.salt_buf[3],
|
|
salt.salt_buf[4],
|
|
salt.salt_buf[5]);
|
|
}
|
|
else if (hash_mode == 12600)
|
|
{
|
|
snprintf (out_buf, len - 1, "%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
digest_buf[0] + salt.salt_buf_pc[0],
|
|
digest_buf[1] + salt.salt_buf_pc[1],
|
|
digest_buf[2] + salt.salt_buf_pc[2],
|
|
digest_buf[3] + salt.salt_buf_pc[3],
|
|
digest_buf[4] + salt.salt_buf_pc[4],
|
|
digest_buf[5] + salt.salt_buf_pc[5],
|
|
digest_buf[6] + salt.salt_buf_pc[6],
|
|
digest_buf[7] + salt.salt_buf_pc[7]);
|
|
}
|
|
else if (hash_mode == 12700)
|
|
{
|
|
uint digest_idx = salt.digests_offset + digest_pos;
|
|
|
|
hashinfo_t **hashinfo_ptr = data.hash_info;
|
|
char *hash_buf = hashinfo_ptr[digest_idx]->orighash;
|
|
|
|
snprintf (out_buf, len-1, "%s", hash_buf);
|
|
}
|
|
else if (hash_mode == 12800)
|
|
{
|
|
const uint8_t *ptr = (const uint8_t *) salt.salt_buf;
|
|
|
|
snprintf (out_buf, len-1, "%s,%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x,%d,%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
SIGNATURE_MS_DRSR,
|
|
ptr[0],
|
|
ptr[1],
|
|
ptr[2],
|
|
ptr[3],
|
|
ptr[4],
|
|
ptr[5],
|
|
ptr[6],
|
|
ptr[7],
|
|
ptr[8],
|
|
ptr[9],
|
|
salt.salt_iter + 1,
|
|
byte_swap_32 (digest_buf[0]),
|
|
byte_swap_32 (digest_buf[1]),
|
|
byte_swap_32 (digest_buf[2]),
|
|
byte_swap_32 (digest_buf[3]),
|
|
byte_swap_32 (digest_buf[4]),
|
|
byte_swap_32 (digest_buf[5]),
|
|
byte_swap_32 (digest_buf[6]),
|
|
byte_swap_32 (digest_buf[7])
|
|
);
|
|
}
|
|
else
|
|
{
|
|
if (hash_type == HASH_TYPE_MD4)
|
|
{
|
|
snprintf (out_buf, 255, "%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_MD5)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_SHA1)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_SHA256)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4],
|
|
digest_buf[5],
|
|
digest_buf[6],
|
|
digest_buf[7]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_SHA384)
|
|
{
|
|
uint *ptr = digest_buf;
|
|
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
ptr[ 1], ptr[ 0],
|
|
ptr[ 3], ptr[ 2],
|
|
ptr[ 5], ptr[ 4],
|
|
ptr[ 7], ptr[ 6],
|
|
ptr[ 9], ptr[ 8],
|
|
ptr[11], ptr[10]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_SHA512)
|
|
{
|
|
uint *ptr = digest_buf;
|
|
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
ptr[ 1], ptr[ 0],
|
|
ptr[ 3], ptr[ 2],
|
|
ptr[ 5], ptr[ 4],
|
|
ptr[ 7], ptr[ 6],
|
|
ptr[ 9], ptr[ 8],
|
|
ptr[11], ptr[10],
|
|
ptr[13], ptr[12],
|
|
ptr[15], ptr[14]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_LM)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_ORACLEH)
|
|
{
|
|
snprintf (out_buf, len-1, "%08X%08X",
|
|
digest_buf[0],
|
|
digest_buf[1]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_BCRYPT)
|
|
{
|
|
base64_encode (int_to_bf64, (char *) salt.salt_buf, 16, tmp_buf + 0);
|
|
base64_encode (int_to_bf64, (char *) digest_buf, 23, tmp_buf + 22);
|
|
|
|
tmp_buf[22 + 31] = 0; // base64_encode wants to pad
|
|
|
|
snprintf (out_buf, len-1, "%s$%s", (char *) salt.salt_sign, tmp_buf);
|
|
}
|
|
else if (hash_type == HASH_TYPE_KECCAK)
|
|
{
|
|
uint *ptr = digest_buf;
|
|
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
ptr[ 1], ptr[ 0],
|
|
ptr[ 3], ptr[ 2],
|
|
ptr[ 5], ptr[ 4],
|
|
ptr[ 7], ptr[ 6],
|
|
ptr[ 9], ptr[ 8],
|
|
ptr[11], ptr[10],
|
|
ptr[13], ptr[12],
|
|
ptr[15], ptr[14],
|
|
ptr[17], ptr[16],
|
|
ptr[19], ptr[18],
|
|
ptr[21], ptr[20],
|
|
ptr[23], ptr[22],
|
|
ptr[25], ptr[24],
|
|
ptr[27], ptr[26],
|
|
ptr[29], ptr[28],
|
|
ptr[31], ptr[30],
|
|
ptr[33], ptr[32],
|
|
ptr[35], ptr[34],
|
|
ptr[37], ptr[36],
|
|
ptr[39], ptr[38],
|
|
ptr[41], ptr[30],
|
|
ptr[43], ptr[42],
|
|
ptr[45], ptr[44],
|
|
ptr[47], ptr[46],
|
|
ptr[49], ptr[48]
|
|
);
|
|
|
|
out_buf[salt.keccak_mdlen * 2] = 0;
|
|
}
|
|
else if (hash_type == HASH_TYPE_RIPEMD160)
|
|
{
|
|
snprintf (out_buf, 255, "%08x%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_WHIRLPOOL)
|
|
{
|
|
digest_buf[ 0] = digest_buf[ 0];
|
|
digest_buf[ 1] = digest_buf[ 1];
|
|
digest_buf[ 2] = digest_buf[ 2];
|
|
digest_buf[ 3] = digest_buf[ 3];
|
|
digest_buf[ 4] = digest_buf[ 4];
|
|
digest_buf[ 5] = digest_buf[ 5];
|
|
digest_buf[ 6] = digest_buf[ 6];
|
|
digest_buf[ 7] = digest_buf[ 7];
|
|
digest_buf[ 8] = digest_buf[ 8];
|
|
digest_buf[ 9] = digest_buf[ 9];
|
|
digest_buf[10] = digest_buf[10];
|
|
digest_buf[11] = digest_buf[11];
|
|
digest_buf[12] = digest_buf[12];
|
|
digest_buf[13] = digest_buf[13];
|
|
digest_buf[14] = digest_buf[14];
|
|
digest_buf[15] = digest_buf[15];
|
|
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
digest_buf[ 0],
|
|
digest_buf[ 1],
|
|
digest_buf[ 2],
|
|
digest_buf[ 3],
|
|
digest_buf[ 4],
|
|
digest_buf[ 5],
|
|
digest_buf[ 6],
|
|
digest_buf[ 7],
|
|
digest_buf[ 8],
|
|
digest_buf[ 9],
|
|
digest_buf[10],
|
|
digest_buf[11],
|
|
digest_buf[12],
|
|
digest_buf[13],
|
|
digest_buf[14],
|
|
digest_buf[15]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_GOST)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3],
|
|
digest_buf[4],
|
|
digest_buf[5],
|
|
digest_buf[6],
|
|
digest_buf[7]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_MYSQL)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_LOTUS5)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x%08x%08x%08x",
|
|
digest_buf[0],
|
|
digest_buf[1],
|
|
digest_buf[2],
|
|
digest_buf[3]);
|
|
}
|
|
else if (hash_type == HASH_TYPE_LOTUS6)
|
|
{
|
|
digest_buf[ 0] = byte_swap_32 (digest_buf[ 0]);
|
|
digest_buf[ 1] = byte_swap_32 (digest_buf[ 1]);
|
|
digest_buf[ 2] = byte_swap_32 (digest_buf[ 2]);
|
|
digest_buf[ 3] = byte_swap_32 (digest_buf[ 3]);
|
|
|
|
char buf[16];
|
|
|
|
memcpy (buf + 0, salt.salt_buf, 5);
|
|
memcpy (buf + 5, digest_buf, 9);
|
|
|
|
buf[3] -= -4;
|
|
|
|
base64_encode (int_to_lotus64, buf, 14, tmp_buf);
|
|
|
|
tmp_buf[18] = salt.salt_buf_pc[7];
|
|
tmp_buf[19] = 0;
|
|
|
|
snprintf (out_buf, len-1, "(G%s)", tmp_buf);
|
|
}
|
|
else if (hash_type == HASH_TYPE_LOTUS8)
|
|
{
|
|
char buf[52];
|
|
|
|
memset (buf, 0, sizeof (buf));
|
|
|
|
// salt
|
|
|
|
memcpy (buf + 0, salt.salt_buf, 16);
|
|
|
|
buf[3] -= -4;
|
|
|
|
// iteration
|
|
|
|
snprintf (buf + 16, 11, "%010i", salt.salt_iter + 1);
|
|
|
|
// chars
|
|
|
|
buf[26] = salt.salt_buf_pc[0];
|
|
buf[27] = salt.salt_buf_pc[1];
|
|
|
|
// digest
|
|
|
|
memcpy (buf + 28, digest_buf, 8);
|
|
|
|
base64_encode (int_to_lotus64, buf, 36, tmp_buf);
|
|
|
|
tmp_buf[49] = 0;
|
|
|
|
snprintf (out_buf, len-1, "(H%s)", tmp_buf);
|
|
}
|
|
else if (hash_type == HASH_TYPE_CRC32)
|
|
{
|
|
snprintf (out_buf, len-1, "%08x", byte_swap_32 (digest_buf[0]));
|
|
}
|
|
}
|
|
|
|
if (salt_type == SALT_TYPE_INTERN)
|
|
{
|
|
size_t pos = strlen (out_buf);
|
|
|
|
out_buf[pos] = data.separator;
|
|
|
|
char *ptr = (char *) salt.salt_buf;
|
|
|
|
memcpy (out_buf + pos + 1, ptr, salt.salt_len);
|
|
|
|
out_buf[pos + 1 + salt.salt_len] = 0;
|
|
}
|
|
}
|
|
|
|
void to_hccap_t (hccap_t *hccap, uint salt_pos, uint digest_pos)
|
|
{
|
|
memset (hccap, 0, sizeof (hccap_t));
|
|
|
|
salt_t *salt = &data.salts_buf[salt_pos];
|
|
|
|
memcpy (hccap->essid, salt->salt_buf, salt->salt_len);
|
|
|
|
wpa_t *wpas = (wpa_t *) data.esalts_buf;
|
|
wpa_t *wpa = &wpas[salt_pos];
|
|
|
|
hccap->keyver = wpa->keyver;
|
|
|
|
hccap->eapol_size = wpa->eapol_size;
|
|
|
|
if (wpa->keyver != 1)
|
|
{
|
|
uint eapol_tmp[64];
|
|
|
|
for (uint i = 0; i < 64; i++)
|
|
{
|
|
eapol_tmp[i] = byte_swap_32 (wpa->eapol[i]);
|
|
}
|
|
|
|
memcpy (hccap->eapol, eapol_tmp, wpa->eapol_size);
|
|
}
|
|
else
|
|
{
|
|
memcpy (hccap->eapol, wpa->eapol, wpa->eapol_size);
|
|
}
|
|
|
|
uint pke_tmp[25];
|
|
|
|
for (int i = 5; i < 25; i++)
|
|
{
|
|
pke_tmp[i] = byte_swap_32 (wpa->pke[i]);
|
|
}
|
|
|
|
char *pke_ptr = (char *) pke_tmp;
|
|
|
|
memcpy (hccap->mac1, pke_ptr + 23, 6);
|
|
memcpy (hccap->mac2, pke_ptr + 29, 6);
|
|
memcpy (hccap->nonce1, pke_ptr + 67, 32);
|
|
memcpy (hccap->nonce2, pke_ptr + 35, 32);
|
|
|
|
char *digests_buf_ptr = (char *) data.digests_buf;
|
|
|
|
uint dgst_size = data.dgst_size;
|
|
|
|
uint *digest_ptr = (uint *) (digests_buf_ptr + (data.salts_buf[salt_pos].digests_offset * dgst_size) + (digest_pos * dgst_size));
|
|
|
|
if (wpa->keyver != 1)
|
|
{
|
|
uint digest_tmp[4];
|
|
|
|
digest_tmp[0] = byte_swap_32 (digest_ptr[0]);
|
|
digest_tmp[1] = byte_swap_32 (digest_ptr[1]);
|
|
digest_tmp[2] = byte_swap_32 (digest_ptr[2]);
|
|
digest_tmp[3] = byte_swap_32 (digest_ptr[3]);
|
|
|
|
memcpy (hccap->keymic, digest_tmp, 16);
|
|
}
|
|
else
|
|
{
|
|
memcpy (hccap->keymic, digest_ptr, 16);
|
|
}
|
|
}
|
|
|
|
void SuspendThreads ()
|
|
{
|
|
if (data.devices_status == STATUS_RUNNING)
|
|
{
|
|
hc_timer_set (&data.timer_paused);
|
|
|
|
data.devices_status = STATUS_PAUSED;
|
|
|
|
log_info ("Paused");
|
|
}
|
|
}
|
|
|
|
void ResumeThreads ()
|
|
{
|
|
if (data.devices_status == STATUS_PAUSED)
|
|
{
|
|
float ms_paused;
|
|
|
|
hc_timer_get (data.timer_paused, ms_paused);
|
|
|
|
data.ms_paused += ms_paused;
|
|
|
|
data.devices_status = STATUS_RUNNING;
|
|
|
|
log_info ("Resumed");
|
|
}
|
|
}
|
|
|
|
void bypass ()
|
|
{
|
|
if (data.devices_status != STATUS_RUNNING) return;
|
|
|
|
data.devices_status = STATUS_BYPASS;
|
|
|
|
log_info ("Next dictionary / mask in queue selected, bypassing current one");
|
|
}
|
|
|
|
void stop_at_checkpoint ()
|
|
{
|
|
if (data.devices_status != STATUS_STOP_AT_CHECKPOINT)
|
|
{
|
|
if (data.devices_status != STATUS_RUNNING) return;
|
|
}
|
|
|
|
// this feature only makes sense if --restore-disable was not specified
|
|
|
|
if (data.restore_disable == 1)
|
|
{
|
|
log_info ("WARNING: this feature is disabled when --restore-disable was specified");
|
|
|
|
return;
|
|
}
|
|
|
|
// check if monitoring of Restore Point updates should be enabled or disabled
|
|
|
|
if (data.devices_status != STATUS_STOP_AT_CHECKPOINT)
|
|
{
|
|
data.devices_status = STATUS_STOP_AT_CHECKPOINT;
|
|
|
|
// save the current restore point value
|
|
|
|
data.checkpoint_cur_words = get_lowest_words_done ();
|
|
|
|
log_info ("Checkpoint enabled: will quit at next Restore Point update");
|
|
}
|
|
else
|
|
{
|
|
data.devices_status = STATUS_RUNNING;
|
|
|
|
// reset the global value for checkpoint checks
|
|
|
|
data.checkpoint_cur_words = 0;
|
|
|
|
log_info ("Checkpoint disabled: Restore Point updates will no longer be monitored");
|
|
}
|
|
}
|
|
|
|
void myabort ()
|
|
{
|
|
if (data.devices_status == STATUS_INIT) return;
|
|
if (data.devices_status == STATUS_STARTING) return;
|
|
|
|
data.devices_status = STATUS_ABORTED;
|
|
}
|
|
|
|
void myquit ()
|
|
{
|
|
if (data.devices_status == STATUS_INIT) return;
|
|
if (data.devices_status == STATUS_STARTING) return;
|
|
|
|
data.devices_status = STATUS_QUIT;
|
|
}
|
|
|
|
void load_kernel (const char *kernel_file, int num_devices, size_t *kernel_lengths, const unsigned char **kernel_sources)
|
|
{
|
|
FILE *fp;
|
|
|
|
if ((fp = fopen (kernel_file, "rb")) != NULL)
|
|
{
|
|
struct stat st;
|
|
|
|
memset (&st, 0, sizeof (st));
|
|
|
|
stat (kernel_file, &st);
|
|
|
|
unsigned char *buf = (unsigned char *) mymalloc (st.st_size + 1);
|
|
|
|
size_t num_read = fread (buf, sizeof (unsigned char), st.st_size, fp);
|
|
|
|
if (num_read != (size_t) st.st_size)
|
|
{
|
|
log_error ("ERROR: %s: %s", kernel_file, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
fclose (fp);
|
|
|
|
buf[st.st_size] = 0;
|
|
|
|
for (int i = 0; i < num_devices; i++)
|
|
{
|
|
kernel_lengths[i] = (size_t) st.st_size;
|
|
|
|
kernel_sources[i] = buf;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
log_error ("ERROR: %s: %s", kernel_file, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void writeProgramBin (char *dst, unsigned char *binary, size_t binary_size)
|
|
{
|
|
FILE *fp = fopen (dst, "wb");
|
|
|
|
fwrite (binary, sizeof (unsigned char), binary_size, fp);
|
|
|
|
fflush (fp);
|
|
fclose (fp);
|
|
}
|
|
|
|
/**
|
|
* restore
|
|
*/
|
|
|
|
restore_data_t *init_restore (int argc, char **argv)
|
|
{
|
|
restore_data_t *rd = (restore_data_t *) mymalloc (sizeof (restore_data_t));
|
|
|
|
if (data.restore_disable == 0)
|
|
{
|
|
FILE *fp = fopen (data.eff_restore_file, "rb");
|
|
|
|
if (fp)
|
|
{
|
|
size_t nread = fread (rd, sizeof (restore_data_t), 1, fp);
|
|
|
|
if (nread != 1)
|
|
{
|
|
log_error ("ERROR: cannot read %s", data.eff_restore_file);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
fclose (fp);
|
|
|
|
if (rd->pid)
|
|
{
|
|
char pidbin[BUFSIZ];
|
|
|
|
int pidbin_len;
|
|
|
|
#ifdef _POSIX
|
|
memset (pidbin, 0, sizeof (pidbin));
|
|
|
|
snprintf (pidbin, sizeof (pidbin) - 1, "/proc/%d/cmdline", rd->pid);
|
|
|
|
FILE *fd = fopen (pidbin, "rb");
|
|
|
|
if (fd)
|
|
{
|
|
pidbin_len = fread (pidbin, 1, BUFSIZ, fd);
|
|
|
|
pidbin[pidbin_len] = 0;
|
|
|
|
fclose (fd);
|
|
|
|
char *argv0_r = strrchr (argv[0], '/');
|
|
|
|
char *pidbin_r = strrchr (pidbin, '/');
|
|
|
|
if (argv0_r == NULL) argv0_r = argv[0];
|
|
|
|
if (pidbin_r == NULL) pidbin_r = pidbin;
|
|
|
|
if (strcmp (argv0_r, pidbin_r) == 0)
|
|
{
|
|
log_error ("ERROR: already an instance %s running on pid %d", pidbin, rd->pid);
|
|
|
|
exit (-1);
|
|
}
|
|
}
|
|
|
|
#elif _WIN
|
|
HANDLE hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, rd->pid);
|
|
|
|
char pidbin2[BUFSIZ];
|
|
|
|
int pidbin2_len;
|
|
|
|
memset (pidbin2, 0, sizeof (pidbin2));
|
|
|
|
pidbin_len = GetModuleFileName (NULL, pidbin, BUFSIZ);
|
|
pidbin2_len = GetModuleFileNameEx (hProcess, NULL, pidbin2, BUFSIZ);
|
|
|
|
pidbin[pidbin_len] = 0;
|
|
pidbin2[pidbin2_len] = 0;
|
|
|
|
if (pidbin2_len)
|
|
{
|
|
if (strcmp (pidbin, pidbin2) == 0)
|
|
{
|
|
log_error ("ERROR: already an instance %s running on pid %d", pidbin2, rd->pid);
|
|
|
|
exit (-1);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (rd->version_bin < RESTORE_MIN)
|
|
{
|
|
log_error ("ERROR: cannot use outdated %s. Please remove it.", data.eff_restore_file);
|
|
|
|
exit (-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
memset (rd, 0, sizeof (restore_data_t));
|
|
|
|
rd->version_bin = VERSION_BIN;
|
|
|
|
#ifdef _POSIX
|
|
rd->pid = getpid ();
|
|
#elif _WIN
|
|
rd->pid = GetCurrentProcessId ();
|
|
#endif
|
|
|
|
if (getcwd (rd->cwd, 255) == NULL)
|
|
{
|
|
myfree (rd);
|
|
|
|
return (NULL);
|
|
}
|
|
|
|
rd->argc = argc;
|
|
rd->argv = argv;
|
|
|
|
return (rd);
|
|
}
|
|
|
|
void read_restore (const char *eff_restore_file, restore_data_t *rd)
|
|
{
|
|
FILE *fp = fopen (eff_restore_file, "rb");
|
|
|
|
if (fp == NULL)
|
|
{
|
|
log_error ("ERROR: restore file '%s': %s", eff_restore_file, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
if (fread (rd, sizeof (restore_data_t), 1, fp) != 1)
|
|
{
|
|
log_error ("ERROR: cannot read %s", eff_restore_file);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
rd->argv = (char **) mycalloc (rd->argc, sizeof (char *));
|
|
|
|
for (uint i = 0; i < rd->argc; i++)
|
|
{
|
|
char buf[BUFSIZ];
|
|
|
|
if (fgets (buf, BUFSIZ - 1, fp) == NULL)
|
|
{
|
|
log_error ("ERROR: cannot read %s", eff_restore_file);
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
size_t len = strlen (buf);
|
|
|
|
if (len) buf[len - 1] = 0;
|
|
|
|
rd->argv[i] = mystrdup (buf);
|
|
}
|
|
|
|
fclose (fp);
|
|
|
|
char new_cwd[256];
|
|
|
|
char *nwd = getcwd (new_cwd, sizeof (new_cwd));
|
|
|
|
if (nwd == NULL)
|
|
{
|
|
log_error ("Restore file is corrupted");
|
|
}
|
|
|
|
if (strncmp (new_cwd, rd->cwd, sizeof (new_cwd)) != 0)
|
|
{
|
|
if (getcwd (rd->cwd, sizeof (rd->cwd)) == NULL)
|
|
{
|
|
log_error ("ERROR: could not determine current user path: %s", strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
log_info ("WARNING: Found old restore file, updating path to %s...", new_cwd);
|
|
}
|
|
|
|
|
|
if (chdir (rd->cwd))
|
|
{
|
|
log_error ("ERROR: cannot chdir to %s: %s", rd->cwd, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
}
|
|
|
|
uint64_t get_lowest_words_done ()
|
|
{
|
|
uint64_t words_cur = -1;
|
|
|
|
for (uint device_id = 0; device_id < data.devices_cnt; device_id++)
|
|
{
|
|
hc_device_param_t *device_param = &data.devices_param[device_id];
|
|
|
|
const uint64_t words_done = device_param->words_done;
|
|
|
|
if (words_done < words_cur) words_cur = words_done;
|
|
}
|
|
|
|
// It's possible that a GPU's workload isn't finished right after a restore-case.
|
|
// In that case, this function would return 0 and overwrite the real restore point
|
|
// There's also data.words_cur which is set to rd->words_cur but it changes while
|
|
// the attack is running therefore we should stick to rd->words_cur.
|
|
// Note that -s influences rd->words_cur we should keep a close look on that.
|
|
|
|
if (words_cur < data.rd->words_cur) words_cur = data.rd->words_cur;
|
|
|
|
return words_cur;
|
|
}
|
|
|
|
void write_restore (const char *new_restore_file, restore_data_t *rd)
|
|
{
|
|
uint64_t words_cur = get_lowest_words_done ();
|
|
|
|
rd->words_cur = words_cur;
|
|
|
|
FILE *fp = fopen (new_restore_file, "wb");
|
|
|
|
if (fp == NULL)
|
|
{
|
|
log_error ("ERROR: %s: %s", new_restore_file, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
if (setvbuf (fp, NULL, _IONBF, 0))
|
|
{
|
|
log_error ("ERROR: setvbuf file '%s': %s", new_restore_file, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
fwrite (rd, sizeof (restore_data_t), 1, fp);
|
|
|
|
for (uint i = 0; i < rd->argc; i++)
|
|
{
|
|
fprintf (fp, "%s", rd->argv[i]);
|
|
fputc ('\n', fp);
|
|
}
|
|
|
|
fflush (fp);
|
|
|
|
fsync (fileno (fp));
|
|
|
|
fclose (fp);
|
|
}
|
|
|
|
void cycle_restore ()
|
|
{
|
|
const char *eff_restore_file = data.eff_restore_file;
|
|
const char *new_restore_file = data.new_restore_file;
|
|
|
|
restore_data_t *rd = data.rd;
|
|
|
|
write_restore (new_restore_file, rd);
|
|
|
|
struct stat st;
|
|
|
|
memset (&st, 0, sizeof(st));
|
|
|
|
if (stat (eff_restore_file, &st) == 0)
|
|
{
|
|
if (unlink (eff_restore_file))
|
|
{
|
|
log_info ("WARN: unlink file '%s': %s", eff_restore_file, strerror (errno));
|
|
}
|
|
}
|
|
|
|
if (rename (new_restore_file, eff_restore_file))
|
|
{
|
|
log_info ("WARN: rename file '%s' to '%s': %s", new_restore_file, eff_restore_file, strerror (errno));
|
|
}
|
|
}
|
|
|
|
void check_checkpoint ()
|
|
{
|
|
// if (data.restore_disable == 1) break; (this is already implied by previous checks)
|
|
|
|
uint64_t words_cur = get_lowest_words_done ();
|
|
|
|
if (words_cur != data.checkpoint_cur_words)
|
|
{
|
|
myabort ();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* adjustments
|
|
*/
|
|
|
|
uint set_gpu_accel (uint hash_mode)
|
|
{
|
|
switch (hash_mode)
|
|
{
|
|
case 0: return GET_ACCEL (0);
|
|
case 10: return GET_ACCEL (10);
|
|
case 11: return GET_ACCEL (11);
|
|
case 12: return GET_ACCEL (12);
|
|
case 20: return GET_ACCEL (20);
|
|
case 21: return GET_ACCEL (21);
|
|
case 22: return GET_ACCEL (22);
|
|
case 23: return GET_ACCEL (23);
|
|
case 30: return GET_ACCEL (30);
|
|
case 40: return GET_ACCEL (40);
|
|
case 50: return GET_ACCEL (50);
|
|
case 60: return GET_ACCEL (60);
|
|
case 100: return GET_ACCEL (100);
|
|
case 101: return GET_ACCEL (101);
|
|
case 110: return GET_ACCEL (110);
|
|
case 111: return GET_ACCEL (111);
|
|
case 112: return GET_ACCEL (112);
|
|
case 120: return GET_ACCEL (120);
|
|
case 121: return GET_ACCEL (121);
|
|
case 122: return GET_ACCEL (122);
|
|
case 124: return GET_ACCEL (124);
|
|
case 130: return GET_ACCEL (130);
|
|
case 131: return GET_ACCEL (131);
|
|
case 132: return GET_ACCEL (132);
|
|
case 133: return GET_ACCEL (133);
|
|
case 140: return GET_ACCEL (140);
|
|
case 141: return GET_ACCEL (141);
|
|
case 150: return GET_ACCEL (150);
|
|
case 160: return GET_ACCEL (160);
|
|
case 190: return GET_ACCEL (190);
|
|
case 200: return GET_ACCEL (200);
|
|
case 300: return GET_ACCEL (300);
|
|
case 400: return GET_ACCEL (400);
|
|
case 500: return GET_ACCEL (500);
|
|
case 501: return GET_ACCEL (501);
|
|
case 900: return GET_ACCEL (900);
|
|
case 910: return GET_ACCEL (910);
|
|
case 1000: return GET_ACCEL (1000);
|
|
case 1100: return GET_ACCEL (1100);
|
|
case 1400: return GET_ACCEL (1400);
|
|
case 1410: return GET_ACCEL (1410);
|
|
case 1420: return GET_ACCEL (1420);
|
|
case 1421: return GET_ACCEL (1421);
|
|
case 1430: return GET_ACCEL (1430);
|
|
case 1440: return GET_ACCEL (1440);
|
|
case 1441: return GET_ACCEL (1441);
|
|
case 1450: return GET_ACCEL (1450);
|
|
case 1460: return GET_ACCEL (1460);
|
|
case 1500: return GET_ACCEL (1500);
|
|
case 1600: return GET_ACCEL (1600);
|
|
case 1700: return GET_ACCEL (1700);
|
|
case 1710: return GET_ACCEL (1710);
|
|
case 1711: return GET_ACCEL (1711);
|
|
case 1720: return GET_ACCEL (1720);
|
|
case 1722: return GET_ACCEL (1722);
|
|
case 1730: return GET_ACCEL (1730);
|
|
case 1731: return GET_ACCEL (1731);
|
|
case 1740: return GET_ACCEL (1740);
|
|
case 1750: return GET_ACCEL (1750);
|
|
case 1760: return GET_ACCEL (1760);
|
|
case 1800: return GET_ACCEL (1800);
|
|
case 2100: return GET_ACCEL (2100);
|
|
case 2400: return GET_ACCEL (2400);
|
|
case 2410: return GET_ACCEL (2410);
|
|
case 2500: return GET_ACCEL (2500);
|
|
case 2600: return GET_ACCEL (2600);
|
|
case 2611: return GET_ACCEL (2611);
|
|
case 2612: return GET_ACCEL (2612);
|
|
case 2711: return GET_ACCEL (2711);
|
|
case 2811: return GET_ACCEL (2811);
|
|
case 3000: return GET_ACCEL (3000);
|
|
case 3100: return GET_ACCEL (3100);
|
|
case 3200: return GET_ACCEL (3200);
|
|
case 3710: return GET_ACCEL (3710);
|
|
case 3711: return GET_ACCEL (3711);
|
|
case 3800: return GET_ACCEL (3800);
|
|
case 4300: return GET_ACCEL (4300);
|
|
case 4400: return GET_ACCEL (4400);
|
|
case 4500: return GET_ACCEL (4500);
|
|
case 4700: return GET_ACCEL (4700);
|
|
case 4800: return GET_ACCEL (4800);
|
|
case 4900: return GET_ACCEL (4900);
|
|
case 5000: return GET_ACCEL (5000);
|
|
case 5100: return GET_ACCEL (5100);
|
|
case 5200: return GET_ACCEL (5200);
|
|
case 5300: return GET_ACCEL (5300);
|
|
case 5400: return GET_ACCEL (5400);
|
|
case 5500: return GET_ACCEL (5500);
|
|
case 5600: return GET_ACCEL (5600);
|
|
case 5700: return GET_ACCEL (5700);
|
|
case 5800: return GET_ACCEL (5800);
|
|
case 6000: return GET_ACCEL (6000);
|
|
case 6100: return GET_ACCEL (6100);
|
|
case 6211: return GET_ACCEL (6211);
|
|
case 6212: return GET_ACCEL (6212);
|
|
case 6213: return GET_ACCEL (6213);
|
|
case 6221: return GET_ACCEL (6221);
|
|
case 6222: return GET_ACCEL (6222);
|
|
case 6223: return GET_ACCEL (6223);
|
|
case 6231: return GET_ACCEL (6231);
|
|
case 6232: return GET_ACCEL (6232);
|
|
case 6233: return GET_ACCEL (6233);
|
|
case 6241: return GET_ACCEL (6241);
|
|
case 6242: return GET_ACCEL (6242);
|
|
case 6243: return GET_ACCEL (6243);
|
|
case 6300: return GET_ACCEL (6300);
|
|
case 6400: return GET_ACCEL (6400);
|
|
case 6500: return GET_ACCEL (6500);
|
|
case 6600: return GET_ACCEL (6600);
|
|
case 6700: return GET_ACCEL (6700);
|
|
case 6800: return GET_ACCEL (6800);
|
|
case 6900: return GET_ACCEL (6900);
|
|
case 7100: return GET_ACCEL (7100);
|
|
case 7200: return GET_ACCEL (7200);
|
|
case 7300: return GET_ACCEL (7300);
|
|
case 7400: return GET_ACCEL (7400);
|
|
case 7500: return GET_ACCEL (7500);
|
|
case 7600: return GET_ACCEL (7600);
|
|
case 7700: return GET_ACCEL (7700);
|
|
case 7800: return GET_ACCEL (7800);
|
|
case 7900: return GET_ACCEL (7900);
|
|
case 8000: return GET_ACCEL (8000);
|
|
case 8100: return GET_ACCEL (8100);
|
|
case 8200: return GET_ACCEL (8200);
|
|
case 8300: return GET_ACCEL (8300);
|
|
case 8400: return GET_ACCEL (8400);
|
|
case 8500: return GET_ACCEL (8500);
|
|
case 8600: return GET_ACCEL (8600);
|
|
case 8700: return GET_ACCEL (8700);
|
|
case 8800: return GET_ACCEL (8800);
|
|
case 8900: return GET_ACCEL (8900);
|
|
case 9000: return GET_ACCEL (9000);
|
|
case 9100: return GET_ACCEL (9100);
|
|
case 9200: return GET_ACCEL (9200);
|
|
case 9300: return GET_ACCEL (9300);
|
|
case 9400: return GET_ACCEL (9400);
|
|
case 9500: return GET_ACCEL (9500);
|
|
case 9600: return GET_ACCEL (9600);
|
|
case 9700: return GET_ACCEL (9700);
|
|
case 9710: return GET_ACCEL (9710);
|
|
case 9720: return GET_ACCEL (9720);
|
|
case 9800: return GET_ACCEL (9800);
|
|
case 9810: return GET_ACCEL (9810);
|
|
case 9820: return GET_ACCEL (9820);
|
|
case 9900: return GET_ACCEL (9900);
|
|
case 10000: return GET_ACCEL (10000);
|
|
case 10100: return GET_ACCEL (10100);
|
|
case 10200: return GET_ACCEL (10200);
|
|
case 10300: return GET_ACCEL (10300);
|
|
case 10400: return GET_ACCEL (10400);
|
|
case 10410: return GET_ACCEL (10410);
|
|
case 10420: return GET_ACCEL (10420);
|
|
case 10500: return GET_ACCEL (10500);
|
|
case 10600: return GET_ACCEL (10600);
|
|
case 10700: return GET_ACCEL (10700);
|
|
case 10800: return GET_ACCEL (10800);
|
|
case 10900: return GET_ACCEL (10900);
|
|
case 11000: return GET_ACCEL (11000);
|
|
case 11100: return GET_ACCEL (11100);
|
|
case 11200: return GET_ACCEL (11200);
|
|
case 11300: return GET_ACCEL (11300);
|
|
case 11400: return GET_ACCEL (11400);
|
|
case 11500: return GET_ACCEL (11500);
|
|
case 11600: return GET_ACCEL (11600);
|
|
case 11700: return GET_ACCEL (11700);
|
|
case 11800: return GET_ACCEL (11800);
|
|
case 11900: return GET_ACCEL (11900);
|
|
case 12000: return GET_ACCEL (12000);
|
|
case 12100: return GET_ACCEL (12100);
|
|
case 12200: return GET_ACCEL (12200);
|
|
case 12300: return GET_ACCEL (12300);
|
|
case 12400: return GET_ACCEL (12400);
|
|
case 12500: return GET_ACCEL (12500);
|
|
case 12600: return GET_ACCEL (12600);
|
|
case 12700: return GET_ACCEL (12700);
|
|
case 12800: return GET_ACCEL (12800);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
uint set_gpu_loops (uint hash_mode)
|
|
{
|
|
switch (hash_mode)
|
|
{
|
|
case 0: return GET_LOOPS (0);
|
|
case 10: return GET_LOOPS (10);
|
|
case 11: return GET_LOOPS (11);
|
|
case 12: return GET_LOOPS (12);
|
|
case 20: return GET_LOOPS (20);
|
|
case 21: return GET_LOOPS (21);
|
|
case 22: return GET_LOOPS (22);
|
|
case 23: return GET_LOOPS (23);
|
|
case 30: return GET_LOOPS (30);
|
|
case 40: return GET_LOOPS (40);
|
|
case 50: return GET_LOOPS (50);
|
|
case 60: return GET_LOOPS (60);
|
|
case 100: return GET_LOOPS (100);
|
|
case 101: return GET_LOOPS (101);
|
|
case 110: return GET_LOOPS (110);
|
|
case 111: return GET_LOOPS (111);
|
|
case 112: return GET_LOOPS (112);
|
|
case 120: return GET_LOOPS (120);
|
|
case 121: return GET_LOOPS (121);
|
|
case 122: return GET_LOOPS (122);
|
|
case 124: return GET_LOOPS (124);
|
|
case 130: return GET_LOOPS (130);
|
|
case 131: return GET_LOOPS (131);
|
|
case 132: return GET_LOOPS (132);
|
|
case 133: return GET_LOOPS (133);
|
|
case 140: return GET_LOOPS (140);
|
|
case 141: return GET_LOOPS (141);
|
|
case 150: return GET_LOOPS (150);
|
|
case 160: return GET_LOOPS (160);
|
|
case 190: return GET_LOOPS (190);
|
|
case 200: return GET_LOOPS (200);
|
|
case 300: return GET_LOOPS (300);
|
|
case 400: return GET_LOOPS (400);
|
|
case 500: return GET_LOOPS (500);
|
|
case 501: return GET_LOOPS (501);
|
|
case 900: return GET_LOOPS (900);
|
|
case 910: return GET_LOOPS (910);
|
|
case 1000: return GET_LOOPS (1000);
|
|
case 1100: return GET_LOOPS (1100);
|
|
case 1400: return GET_LOOPS (1400);
|
|
case 1410: return GET_LOOPS (1410);
|
|
case 1420: return GET_LOOPS (1420);
|
|
case 1421: return GET_LOOPS (1421);
|
|
case 1430: return GET_LOOPS (1430);
|
|
case 1440: return GET_LOOPS (1440);
|
|
case 1441: return GET_LOOPS (1441);
|
|
case 1450: return GET_LOOPS (1450);
|
|
case 1460: return GET_LOOPS (1460);
|
|
case 1500: return GET_LOOPS (1500);
|
|
case 1600: return GET_LOOPS (1600);
|
|
case 1700: return GET_LOOPS (1700);
|
|
case 1710: return GET_LOOPS (1710);
|
|
case 1711: return GET_LOOPS (1711);
|
|
case 1720: return GET_LOOPS (1720);
|
|
case 1722: return GET_LOOPS (1722);
|
|
case 1730: return GET_LOOPS (1730);
|
|
case 1731: return GET_LOOPS (1731);
|
|
case 1740: return GET_LOOPS (1740);
|
|
case 1750: return GET_LOOPS (1750);
|
|
case 1760: return GET_LOOPS (1760);
|
|
case 1800: return GET_LOOPS (1800);
|
|
case 2100: return GET_LOOPS (2100);
|
|
case 2400: return GET_LOOPS (2400);
|
|
case 2410: return GET_LOOPS (2410);
|
|
case 2500: return GET_LOOPS (2500);
|
|
case 2600: return GET_LOOPS (2600);
|
|
case 2611: return GET_LOOPS (2611);
|
|
case 2612: return GET_LOOPS (2612);
|
|
case 2711: return GET_LOOPS (2711);
|
|
case 2811: return GET_LOOPS (2811);
|
|
case 3000: return GET_LOOPS (3000);
|
|
case 3100: return GET_LOOPS (3100);
|
|
case 3200: return GET_LOOPS (3200);
|
|
case 3710: return GET_LOOPS (3710);
|
|
case 3711: return GET_LOOPS (3711);
|
|
case 3800: return GET_LOOPS (3800);
|
|
case 4300: return GET_LOOPS (4300);
|
|
case 4400: return GET_LOOPS (4400);
|
|
case 4500: return GET_LOOPS (4500);
|
|
case 4700: return GET_LOOPS (4700);
|
|
case 4800: return GET_LOOPS (4800);
|
|
case 4900: return GET_LOOPS (4900);
|
|
case 5000: return GET_LOOPS (5000);
|
|
case 5100: return GET_LOOPS (5100);
|
|
case 5200: return GET_LOOPS (5200);
|
|
case 5300: return GET_LOOPS (5300);
|
|
case 5400: return GET_LOOPS (5400);
|
|
case 5500: return GET_LOOPS (5500);
|
|
case 5600: return GET_LOOPS (5600);
|
|
case 5700: return GET_LOOPS (5700);
|
|
case 5800: return GET_LOOPS (5800);
|
|
case 6000: return GET_LOOPS (6000);
|
|
case 6100: return GET_LOOPS (6100);
|
|
case 6211: return GET_LOOPS (6211);
|
|
case 6212: return GET_LOOPS (6212);
|
|
case 6213: return GET_LOOPS (6213);
|
|
case 6221: return GET_LOOPS (6221);
|
|
case 6222: return GET_LOOPS (6222);
|
|
case 6223: return GET_LOOPS (6223);
|
|
case 6231: return GET_LOOPS (6231);
|
|
case 6232: return GET_LOOPS (6232);
|
|
case 6233: return GET_LOOPS (6233);
|
|
case 6241: return GET_LOOPS (6241);
|
|
case 6242: return GET_LOOPS (6242);
|
|
case 6243: return GET_LOOPS (6243);
|
|
case 6300: return GET_LOOPS (6300);
|
|
case 6400: return GET_LOOPS (6400);
|
|
case 6500: return GET_LOOPS (6500);
|
|
case 6600: return GET_LOOPS (6600);
|
|
case 6700: return GET_LOOPS (6700);
|
|
case 6800: return GET_LOOPS (6800);
|
|
case 6900: return GET_LOOPS (6900);
|
|
case 7100: return GET_LOOPS (7100);
|
|
case 7200: return GET_LOOPS (7200);
|
|
case 7300: return GET_LOOPS (7300);
|
|
case 7400: return GET_LOOPS (7400);
|
|
case 7500: return GET_LOOPS (7500);
|
|
case 7600: return GET_LOOPS (7600);
|
|
case 7700: return GET_LOOPS (7700);
|
|
case 7800: return GET_LOOPS (7800);
|
|
case 7900: return GET_LOOPS (7900);
|
|
case 8000: return GET_LOOPS (8000);
|
|
case 8100: return GET_LOOPS (8100);
|
|
case 8200: return GET_LOOPS (8200);
|
|
case 8300: return GET_LOOPS (8300);
|
|
case 8400: return GET_LOOPS (8400);
|
|
case 8500: return GET_LOOPS (8500);
|
|
case 8600: return GET_LOOPS (8600);
|
|
case 8700: return GET_LOOPS (8700);
|
|
case 8800: return GET_LOOPS (8800);
|
|
case 8900: return GET_LOOPS (8900);
|
|
case 9000: return GET_LOOPS (9000);
|
|
case 9100: return GET_LOOPS (9100);
|
|
case 9200: return GET_LOOPS (9200);
|
|
case 9300: return GET_LOOPS (9300);
|
|
case 9400: return GET_LOOPS (9400);
|
|
case 9500: return GET_LOOPS (9500);
|
|
case 9600: return GET_LOOPS (9600);
|
|
case 9700: return GET_LOOPS (9700);
|
|
case 9710: return GET_LOOPS (9710);
|
|
case 9720: return GET_LOOPS (9720);
|
|
case 9800: return GET_LOOPS (9800);
|
|
case 9810: return GET_LOOPS (9810);
|
|
case 9820: return GET_LOOPS (9820);
|
|
case 9900: return GET_LOOPS (9900);
|
|
case 10000: return GET_LOOPS (10000);
|
|
case 10100: return GET_LOOPS (10100);
|
|
case 10200: return GET_LOOPS (10200);
|
|
case 10300: return GET_LOOPS (10300);
|
|
case 10400: return GET_LOOPS (10400);
|
|
case 10410: return GET_LOOPS (10410);
|
|
case 10420: return GET_LOOPS (10420);
|
|
case 10500: return GET_LOOPS (10500);
|
|
case 10600: return GET_LOOPS (10600);
|
|
case 10700: return GET_LOOPS (10700);
|
|
case 10800: return GET_LOOPS (10800);
|
|
case 10900: return GET_LOOPS (10900);
|
|
case 11000: return GET_LOOPS (11000);
|
|
case 11100: return GET_LOOPS (11100);
|
|
case 11200: return GET_LOOPS (11200);
|
|
case 11300: return GET_LOOPS (11300);
|
|
case 11400: return GET_LOOPS (11400);
|
|
case 11500: return GET_LOOPS (11500);
|
|
case 11600: return GET_LOOPS (11600);
|
|
case 11700: return GET_LOOPS (11700);
|
|
case 11800: return GET_LOOPS (11800);
|
|
case 11900: return GET_LOOPS (11900);
|
|
case 12000: return GET_LOOPS (12000);
|
|
case 12100: return GET_LOOPS (12100);
|
|
case 12200: return GET_LOOPS (12200);
|
|
case 12300: return GET_LOOPS (12300);
|
|
case 12400: return GET_LOOPS (12400);
|
|
case 12500: return GET_LOOPS (12500);
|
|
case 12600: return GET_LOOPS (12600);
|
|
case 12700: return GET_LOOPS (12700);
|
|
case 12800: return GET_LOOPS (12800);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* parser
|
|
*/
|
|
|
|
uint parse_and_store_salt (char *out, char *in, uint salt_len)
|
|
{
|
|
char tmp[256];
|
|
|
|
if (salt_len > sizeof(tmp))
|
|
{
|
|
return UINT_MAX;
|
|
}
|
|
|
|
memset (tmp, 0, sizeof (tmp));
|
|
memcpy (tmp, in, salt_len);
|
|
|
|
if (data.opts_type & OPTS_TYPE_ST_HEX)
|
|
{
|
|
if ((salt_len % 2) == 0)
|
|
{
|
|
uint new_salt_len = salt_len / 2;
|
|
|
|
for (uint i = 0, j = 0; i < new_salt_len; i += 1, j += 2)
|
|
{
|
|
char p0 = tmp[j + 0];
|
|
char p1 = tmp[j + 1];
|
|
|
|
tmp[i] = hex_convert (p1) << 0;
|
|
tmp[i] |= hex_convert (p0) << 4;
|
|
}
|
|
|
|
salt_len = new_salt_len;
|
|
}
|
|
else
|
|
{
|
|
return UINT_MAX;
|
|
}
|
|
}
|
|
else if (data.opts_type & OPTS_TYPE_ST_BASE64)
|
|
{
|
|
salt_len = base64_decode (base64_to_int, in, salt_len, tmp);
|
|
}
|
|
|
|
memset (tmp + salt_len, 0, sizeof (tmp) - salt_len);
|
|
|
|
if (data.opts_type & OPTS_TYPE_ST_UNICODE)
|
|
{
|
|
if (salt_len < 20)
|
|
{
|
|
uint *tmp_uint = (uint *) tmp;
|
|
|
|
tmp_uint[9] = ((tmp_uint[4] >> 8) & 0x00FF0000) | ((tmp_uint[4] >> 16) & 0x000000FF);
|
|
tmp_uint[8] = ((tmp_uint[4] << 8) & 0x00FF0000) | ((tmp_uint[4] >> 0) & 0x000000FF);
|
|
tmp_uint[7] = ((tmp_uint[3] >> 8) & 0x00FF0000) | ((tmp_uint[3] >> 16) & 0x000000FF);
|
|
tmp_uint[6] = ((tmp_uint[3] << 8) & 0x00FF0000) | ((tmp_uint[3] >> 0) & 0x000000FF);
|
|
tmp_uint[5] = ((tmp_uint[2] >> 8) & 0x00FF0000) | ((tmp_uint[2] >> 16) & 0x000000FF);
|
|
tmp_uint[4] = ((tmp_uint[2] << 8) & 0x00FF0000) | ((tmp_uint[2] >> 0) & 0x000000FF);
|
|
tmp_uint[3] = ((tmp_uint[1] >> 8) & 0x00FF0000) | ((tmp_uint[1] >> 16) & 0x000000FF);
|
|
tmp_uint[2] = ((tmp_uint[1] << 8) & 0x00FF0000) | ((tmp_uint[1] >> 0) & 0x000000FF);
|
|
tmp_uint[1] = ((tmp_uint[0] >> 8) & 0x00FF0000) | ((tmp_uint[0] >> 16) & 0x000000FF);
|
|
tmp_uint[0] = ((tmp_uint[0] << 8) & 0x00FF0000) | ((tmp_uint[0] >> 0) & 0x000000FF);
|
|
|
|
salt_len = salt_len * 2;
|
|
}
|
|
else
|
|
{
|
|
return UINT_MAX;
|
|
}
|
|
}
|
|
|
|
if (data.opts_type & OPTS_TYPE_ST_LOWER)
|
|
{
|
|
lowercase (tmp, salt_len);
|
|
}
|
|
|
|
if (data.opts_type & OPTS_TYPE_ST_UPPER)
|
|
{
|
|
uppercase (tmp, salt_len);
|
|
}
|
|
|
|
uint len = salt_len;
|
|
|
|
if (data.opts_type & OPTS_TYPE_ST_ADD80)
|
|
{
|
|
tmp[len++] = 0x80;
|
|
}
|
|
|
|
if (data.opts_type & OPTS_TYPE_ST_ADD01)
|
|
{
|
|
tmp[len++] = 0x01;
|
|
}
|
|
|
|
if (data.opts_type & OPTS_TYPE_ST_GENERATE_LE)
|
|
{
|
|
uint *tmp_uint = (uint *) tmp;
|
|
|
|
uint max = len / 4;
|
|
|
|
if (len % 4) max++;
|
|
|
|
for (uint i = 0; i < max; i++)
|
|
{
|
|
tmp_uint[i] = byte_swap_32 (tmp_uint[i]);
|
|
}
|
|
|
|
// Important: we may need to increase the length of memcpy since
|
|
// we don't want to "loose" some swapped bytes (could happen if
|
|
// they do not perfectly fit in the 4-byte blocks)
|
|
// Memcpy does always copy the bytes in the BE order, but since
|
|
// we swapped them, some important bytes could be in positions
|
|
// we normally skip with the original len
|
|
|
|
if (len % 4) len += 4 - (len % 4);
|
|
}
|
|
|
|
memcpy (out, tmp, len);
|
|
|
|
return (salt_len);
|
|
}
|
|
|
|
int bcrypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_3200) || (input_len > DISPLAY_LEN_MAX_3200)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_BCRYPT1, input_buf, 4)) && (memcmp (SIGNATURE_BCRYPT2, input_buf, 4)) && (memcmp (SIGNATURE_BCRYPT3, input_buf, 4))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
memcpy ((char *) salt->salt_sign, input_buf, 6);
|
|
|
|
char *iter_pos = input_buf + 4;
|
|
|
|
salt->salt_iter = 1 << atoi (iter_pos);
|
|
|
|
char *salt_pos = strchr (iter_pos, '$');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
uint salt_len = 16;
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (bf64_to_int, salt_pos, 22, tmp_buf);
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
memcpy (salt_buf_ptr, tmp_buf, 16);
|
|
|
|
salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]);
|
|
salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]);
|
|
salt->salt_buf[2] = byte_swap_32 (salt->salt_buf[2]);
|
|
salt->salt_buf[3] = byte_swap_32 (salt->salt_buf[3]);
|
|
|
|
char *hash_pos = salt_pos + 22;
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (bf64_to_int, hash_pos, 31, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 24);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
digest[5] = byte_swap_32 (digest[5]);
|
|
|
|
digest[5] &= ~0xff; // its just 23 not 24 !
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int cisco4_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_5700) || (input_len > DISPLAY_LEN_MAX_5700)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (itoa64_to_int, input_buf, 43, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 32);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
digest[5] = byte_swap_32 (digest[5]);
|
|
digest[6] = byte_swap_32 (digest[6]);
|
|
digest[7] = byte_swap_32 (digest[7]);
|
|
|
|
digest[0] -= SHA256M_A;
|
|
digest[1] -= SHA256M_B;
|
|
digest[2] -= SHA256M_C;
|
|
digest[3] -= SHA256M_D;
|
|
digest[4] -= SHA256M_E;
|
|
digest[5] -= SHA256M_F;
|
|
digest[6] -= SHA256M_G;
|
|
digest[7] -= SHA256M_H;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int lm_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_3000) || (input_len > DISPLAY_LEN_MAX_3000)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
|
|
uint tt;
|
|
|
|
IP (digest[0], digest[1], tt);
|
|
|
|
digest[0] = digest[0];
|
|
digest[1] = digest[1];
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int osx1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_122) || (input_len > DISPLAY_LEN_MAX_122)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *hash_pos = input_buf + 8;
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_pos[32]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
uint salt_len = 8;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, input_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int osx512_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1722) || (input_len > DISPLAY_LEN_MAX_1722)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *hash_pos = input_buf + 8;
|
|
|
|
digest[0] = hex_to_uint64_t (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint64_t (&hash_pos[ 16]);
|
|
digest[2] = hex_to_uint64_t (&hash_pos[ 32]);
|
|
digest[3] = hex_to_uint64_t (&hash_pos[ 48]);
|
|
digest[4] = hex_to_uint64_t (&hash_pos[ 64]);
|
|
digest[5] = hex_to_uint64_t (&hash_pos[ 80]);
|
|
digest[6] = hex_to_uint64_t (&hash_pos[ 96]);
|
|
digest[7] = hex_to_uint64_t (&hash_pos[112]);
|
|
|
|
digest[0] -= SHA512M_A;
|
|
digest[1] -= SHA512M_B;
|
|
digest[2] -= SHA512M_C;
|
|
digest[3] -= SHA512M_D;
|
|
digest[4] -= SHA512M_E;
|
|
digest[5] -= SHA512M_F;
|
|
digest[6] -= SHA512M_G;
|
|
digest[7] -= SHA512M_H;
|
|
|
|
uint salt_len = 8;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, input_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int osc_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_21H) || (input_len > DISPLAY_LEN_MAX_21H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_21) || (input_len > DISPLAY_LEN_MAX_21)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int netscreen_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_22H) || (input_len > DISPLAY_LEN_MAX_22H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_22) || (input_len > DISPLAY_LEN_MAX_22)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
// unscramble
|
|
|
|
char clean_input_buf[32];
|
|
|
|
char sig[6] = { 'n', 'r', 'c', 's', 't', 'n' };
|
|
int pos[6] = { 0, 6, 12, 17, 23, 29 };
|
|
|
|
for (int i = 0, j = 0, k = 0; i < 30; i++)
|
|
{
|
|
if (i == pos[j])
|
|
{
|
|
if (sig[j] != input_buf[i]) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
clean_input_buf[k] = input_buf[i];
|
|
|
|
k++;
|
|
}
|
|
}
|
|
|
|
// base64 decode
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char a, b, c, d, e, f;
|
|
|
|
a = base64_to_int (clean_input_buf[ 0] & 0x7f);
|
|
b = base64_to_int (clean_input_buf[ 1] & 0x7f);
|
|
c = base64_to_int (clean_input_buf[ 2] & 0x7f);
|
|
d = base64_to_int (clean_input_buf[ 3] & 0x7f);
|
|
e = base64_to_int (clean_input_buf[ 4] & 0x7f);
|
|
f = base64_to_int (clean_input_buf[ 5] & 0x7f);
|
|
|
|
digest[0] = (((a << 12) | (b << 6) | (c)) << 16)
|
|
| (((d << 12) | (e << 6) | (f)) << 0);
|
|
|
|
a = base64_to_int (clean_input_buf[ 6] & 0x7f);
|
|
b = base64_to_int (clean_input_buf[ 7] & 0x7f);
|
|
c = base64_to_int (clean_input_buf[ 8] & 0x7f);
|
|
d = base64_to_int (clean_input_buf[ 9] & 0x7f);
|
|
e = base64_to_int (clean_input_buf[10] & 0x7f);
|
|
f = base64_to_int (clean_input_buf[11] & 0x7f);
|
|
|
|
digest[1] = (((a << 12) | (b << 6) | (c)) << 16)
|
|
| (((d << 12) | (e << 6) | (f)) << 0);
|
|
|
|
a = base64_to_int (clean_input_buf[12] & 0x7f);
|
|
b = base64_to_int (clean_input_buf[13] & 0x7f);
|
|
c = base64_to_int (clean_input_buf[14] & 0x7f);
|
|
d = base64_to_int (clean_input_buf[15] & 0x7f);
|
|
e = base64_to_int (clean_input_buf[16] & 0x7f);
|
|
f = base64_to_int (clean_input_buf[17] & 0x7f);
|
|
|
|
digest[2] = (((a << 12) | (b << 6) | (c)) << 16)
|
|
| (((d << 12) | (e << 6) | (f)) << 0);
|
|
|
|
a = base64_to_int (clean_input_buf[18] & 0x7f);
|
|
b = base64_to_int (clean_input_buf[19] & 0x7f);
|
|
c = base64_to_int (clean_input_buf[20] & 0x7f);
|
|
d = base64_to_int (clean_input_buf[21] & 0x7f);
|
|
e = base64_to_int (clean_input_buf[22] & 0x7f);
|
|
f = base64_to_int (clean_input_buf[23] & 0x7f);
|
|
|
|
digest[3] = (((a << 12) | (b << 6) | (c)) << 16)
|
|
| (((d << 12) | (e << 6) | (f)) << 0);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
if (input_buf[30] != ':') return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 30 - 1;
|
|
|
|
char *salt_buf = input_buf + 30 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
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);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
memcpy (salt_buf_ptr + salt_len, ":Administration Tools:", 22);
|
|
|
|
salt->salt_len += 22;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int smf_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_121H) || (input_len > DISPLAY_LEN_MAX_121H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_121) || (input_len > DISPLAY_LEN_MAX_121)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
if (input_buf[40] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 40 - 1;
|
|
|
|
char *salt_buf = input_buf + 40 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int dcc2_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_2100H) || (input_len > DISPLAY_LEN_MAX_2100H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_2100) || (input_len > DISPLAY_LEN_MAX_2100)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
if (memcmp (SIGNATURE_DCC2, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
char *iter_pos = input_buf + 6;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
salt->salt_iter = atoi (iter_pos) - 1;
|
|
|
|
char *salt_pos = strchr (iter_pos, '#');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *digest_pos = strchr (salt_pos, '#');
|
|
|
|
if (digest_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
digest_pos++;
|
|
|
|
uint salt_len = digest_pos - salt_pos - 1;
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&digest_pos[ 0]);
|
|
digest[1] = hex_to_uint (&digest_pos[ 8]);
|
|
digest[2] = hex_to_uint (&digest_pos[16]);
|
|
digest[3] = hex_to_uint (&digest_pos[24]);
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int wpa_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
wpa_t *wpa = (wpa_t *) hash_buf->esalt;
|
|
|
|
hccap_t in;
|
|
|
|
memcpy (&in, input_buf, input_len);
|
|
|
|
if (in.eapol_size < 1 || in.eapol_size > 255) return (PARSER_HCCAP_EAPOL_SIZE);
|
|
|
|
memcpy (digest, in.keymic, 16);
|
|
|
|
/*
|
|
http://www.one-net.eu/jsw/j_sec/m_ptype.html
|
|
The phrase "Pairwise key expansion"
|
|
Access Point Address (Referred to as Authenticator Address AA)
|
|
Supplicant Address (referred to as Supplicant Address SA)
|
|
Access Point Nonce (referred to as Authenticator Anonce)
|
|
Wireless Device Nonce (referred to as Supplicant Nonce Snonce)
|
|
*/
|
|
|
|
uint salt_len = strlen (in.essid);
|
|
|
|
memcpy (salt->salt_buf, in.essid, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
salt->salt_iter = ROUNDS_WPA2 - 1;
|
|
|
|
unsigned char *pke_ptr = (unsigned char *) wpa->pke;
|
|
|
|
memcpy (pke_ptr, "Pairwise key expansion", 23);
|
|
|
|
if (memcmp (in.mac1, in.mac2, 6) < 0)
|
|
{
|
|
memcpy (pke_ptr + 23, in.mac1, 6);
|
|
memcpy (pke_ptr + 29, in.mac2, 6);
|
|
}
|
|
else
|
|
{
|
|
memcpy (pke_ptr + 23, in.mac2, 6);
|
|
memcpy (pke_ptr + 29, in.mac1, 6);
|
|
}
|
|
|
|
if (memcmp (in.nonce1, in.nonce2, 32) < 0)
|
|
{
|
|
memcpy (pke_ptr + 35, in.nonce1, 32);
|
|
memcpy (pke_ptr + 67, in.nonce2, 32);
|
|
}
|
|
else
|
|
{
|
|
memcpy (pke_ptr + 35, in.nonce2, 32);
|
|
memcpy (pke_ptr + 67, in.nonce1, 32);
|
|
}
|
|
|
|
for (int i = 0; i < 25; i++)
|
|
{
|
|
wpa->pke[i] = byte_swap_32 (wpa->pke[i]);
|
|
}
|
|
|
|
wpa->keyver = in.keyver;
|
|
|
|
if (wpa->keyver > 255)
|
|
{
|
|
log_info ("ATTENTION!");
|
|
log_info (" The WPA/WPA2 key version in your .hccap file is invalid!");
|
|
log_info (" This could be due to a recent aircrack-ng bug.");
|
|
log_info (" The key version was automatically reset to a reasonable value.");
|
|
log_info ("");
|
|
|
|
wpa->keyver &= 0xff;
|
|
}
|
|
|
|
wpa->eapol_size = in.eapol_size;
|
|
|
|
unsigned char *eapol_ptr = (unsigned char *) wpa->eapol;
|
|
|
|
memcpy (eapol_ptr, in.eapol, wpa->eapol_size);
|
|
|
|
memset (eapol_ptr + wpa->eapol_size, 0, 256 - wpa->eapol_size);
|
|
|
|
eapol_ptr[wpa->eapol_size] = (unsigned char) 0x80;
|
|
|
|
if (wpa->keyver == 1)
|
|
{
|
|
// nothing to do
|
|
}
|
|
else
|
|
{
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
for (int i = 0; i < 64; i++)
|
|
{
|
|
wpa->eapol[i] = byte_swap_32 (wpa->eapol[i]);
|
|
}
|
|
}
|
|
|
|
salt->salt_buf[10] = digest[1];
|
|
salt->salt_buf[11] = digest[2];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int psafe2_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
if (input_len == 0)
|
|
{
|
|
log_error ("Password Safe v2 container not specified");
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
FILE *fp = fopen (input_buf, "rb");
|
|
|
|
if (fp == NULL)
|
|
{
|
|
log_error ("%s: %s", input_buf, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t random[2];
|
|
uint32_t hash[5];
|
|
uint32_t salt[5]; // unused, but makes better valid check
|
|
uint32_t iv[2]; // unused, but makes better valid check
|
|
|
|
} psafe2_hdr;
|
|
|
|
psafe2_hdr buf;
|
|
|
|
int n = fread (&buf, sizeof (psafe2_hdr), 1, fp);
|
|
|
|
fclose (fp);
|
|
|
|
if (n != 1) return (PARSER_PSAFE2_FILE_SIZE);
|
|
|
|
salt->salt_buf[0] = buf.random[0];
|
|
salt->salt_buf[1] = buf.random[1];
|
|
|
|
salt->salt_len = 8;
|
|
salt->salt_iter = 1000;
|
|
|
|
digest[0] = byte_swap_32 (buf.hash[0]);
|
|
digest[1] = byte_swap_32 (buf.hash[1]);
|
|
digest[2] = byte_swap_32 (buf.hash[2]);
|
|
digest[3] = byte_swap_32 (buf.hash[3]);
|
|
digest[4] = byte_swap_32 (buf.hash[4]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int psafe3_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
if (input_len == 0)
|
|
{
|
|
log_error (".psafe3 not specified");
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
FILE *fp = fopen (input_buf, "rb");
|
|
|
|
if (fp == NULL)
|
|
{
|
|
log_error ("%s: %s", input_buf, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
psafe3_t in;
|
|
|
|
int n = fread (&in, sizeof (psafe3_t), 1, fp);
|
|
|
|
fclose (fp);
|
|
|
|
data.hashfile = input_buf; // we will need this in case it gets cracked
|
|
|
|
if (memcmp (SIGNATURE_PSAFE3, in.signature, 4)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
if (n != 1) return (PARSER_PSAFE3_FILE_SIZE);
|
|
|
|
salt->salt_iter = in.iterations + 1;
|
|
|
|
salt->salt_buf[0] = in.salt_buf[0];
|
|
salt->salt_buf[1] = in.salt_buf[1];
|
|
salt->salt_buf[2] = in.salt_buf[2];
|
|
salt->salt_buf[3] = in.salt_buf[3];
|
|
salt->salt_buf[4] = in.salt_buf[4];
|
|
salt->salt_buf[5] = in.salt_buf[5];
|
|
salt->salt_buf[6] = in.salt_buf[6];
|
|
salt->salt_buf[7] = in.salt_buf[7];
|
|
|
|
salt->salt_len = 32;
|
|
|
|
digest[0] = in.hash_buf[0];
|
|
digest[1] = in.hash_buf[1];
|
|
digest[2] = in.hash_buf[2];
|
|
digest[3] = in.hash_buf[3];
|
|
digest[4] = in.hash_buf[4];
|
|
digest[5] = in.hash_buf[5];
|
|
digest[6] = in.hash_buf[6];
|
|
digest[7] = in.hash_buf[7];
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
digest[5] = byte_swap_32 (digest[5]);
|
|
digest[6] = byte_swap_32 (digest[6]);
|
|
digest[7] = byte_swap_32 (digest[7]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int phpass_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_400) || (input_len > DISPLAY_LEN_MAX_400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_PHPASS1, input_buf, 3)) && (memcmp (SIGNATURE_PHPASS2, input_buf, 3))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *iter_pos = input_buf + 3;
|
|
|
|
uint salt_iter = 1 << itoa64_to_int (iter_pos[0]);
|
|
|
|
if (salt_iter > 0x80000000) return (PARSER_SALT_ITERATION);
|
|
|
|
memcpy ((char *) salt->salt_sign, input_buf, 4);
|
|
|
|
salt->salt_iter = salt_iter;
|
|
|
|
char *salt_pos = iter_pos + 1;
|
|
|
|
uint salt_len = 8;
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char *hash_pos = salt_pos + salt_len;
|
|
|
|
phpass_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md5crypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if (memcmp (SIGNATURE_MD5CRYPT, input_buf, 3)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 3;
|
|
|
|
uint iterations_len = 0;
|
|
|
|
if (memcmp (salt_pos, "rounds=", 7) == 0)
|
|
{
|
|
salt_pos += 7;
|
|
|
|
for (iterations_len = 0; salt_pos[0] >= '0' && salt_pos[0] <= '9' && iterations_len < 7; iterations_len++, salt_pos += 1) continue;
|
|
|
|
if (iterations_len == 0 ) return (PARSER_SALT_ITERATION);
|
|
if (salt_pos[0] != '$') return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
salt_pos[0] = 0x0;
|
|
|
|
salt->salt_iter = atoi (salt_pos - iterations_len);
|
|
|
|
salt_pos += 1;
|
|
|
|
iterations_len += 8;
|
|
}
|
|
else
|
|
{
|
|
salt->salt_iter = ROUNDS_MD5CRYPT;
|
|
}
|
|
|
|
if ((input_len < DISPLAY_LEN_MIN_500) || (input_len > (DISPLAY_LEN_MAX_500 + iterations_len))) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len > 8) return (PARSER_SALT_LENGTH);
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
hash_pos++;
|
|
|
|
uint hash_len = input_len - 3 - iterations_len - salt_len - 1;
|
|
|
|
if (hash_len != 22) return (PARSER_HASH_LENGTH);
|
|
|
|
md5crypt_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md5apr1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if (memcmp (SIGNATURE_MD5APR1, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 6;
|
|
|
|
uint iterations_len = 0;
|
|
|
|
if (memcmp (salt_pos, "rounds=", 7) == 0)
|
|
{
|
|
salt_pos += 7;
|
|
|
|
for (iterations_len = 0; salt_pos[0] >= '0' && salt_pos[0] <= '9' && iterations_len < 7; iterations_len++, salt_pos += 1) continue;
|
|
|
|
if (iterations_len == 0 ) return (PARSER_SALT_ITERATION);
|
|
if (salt_pos[0] != '$') return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
salt_pos[0] = 0x0;
|
|
|
|
salt->salt_iter = atoi (salt_pos - iterations_len);
|
|
|
|
salt_pos += 1;
|
|
|
|
iterations_len += 8;
|
|
}
|
|
else
|
|
{
|
|
salt->salt_iter = ROUNDS_MD5CRYPT;
|
|
}
|
|
|
|
if ((input_len < DISPLAY_LEN_MIN_1600) || (input_len > DISPLAY_LEN_MAX_1600 + iterations_len)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len > 8) return (PARSER_SALT_LENGTH);
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
hash_pos++;
|
|
|
|
md5crypt_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int episerver_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_141) || (input_len > DISPLAY_LEN_MAX_141)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_EPISERVER, input_buf, 14)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 14;
|
|
|
|
char *hash_pos = strchr (salt_pos, '*');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
hash_pos++;
|
|
|
|
uint salt_len = hash_pos - salt_pos - 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char tmp_buf[100]; memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (base64_to_int, hash_pos, 27, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 20);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int descrypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1500) || (input_len > DISPLAY_LEN_MAX_1500)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
unsigned char c12 = itoa64_to_int (input_buf[12]);
|
|
|
|
if (c12 & 3) return (PARSER_HASH_VALUE);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
// for ascii_digest
|
|
salt->salt_sign[0] = input_buf[0];
|
|
salt->salt_sign[1] = input_buf[1];
|
|
|
|
salt->salt_buf[0] = itoa64_to_int (input_buf[0])
|
|
| itoa64_to_int (input_buf[1]) << 6;
|
|
|
|
salt->salt_len = 2;
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (itoa64_to_int, input_buf + 2, 11, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 8);
|
|
|
|
uint tt;
|
|
|
|
IP (digest[0], digest[1], tt);
|
|
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md4_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_900) || (input_len > DISPLAY_LEN_MAX_900)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD4M_A;
|
|
digest[1] -= MD4M_B;
|
|
digest[2] -= MD4M_C;
|
|
digest[3] -= MD4M_D;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md4s_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_910H) || (input_len > DISPLAY_LEN_MAX_910H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_910) || (input_len > DISPLAY_LEN_MAX_910)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD4M_A;
|
|
digest[1] -= MD4M_B;
|
|
digest[2] -= MD4M_C;
|
|
digest[3] -= MD4M_D;
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md5_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_0) || (input_len > DISPLAY_LEN_MAX_0)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md5half_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_5100) || (input_len > DISPLAY_LEN_MAX_5100)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[0]);
|
|
digest[1] = hex_to_uint (&input_buf[8]);
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md5s_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_10H) || (input_len > DISPLAY_LEN_MAX_10H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10) || (input_len > DISPLAY_LEN_MAX_10)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md5pix_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_2400) || (input_len > DISPLAY_LEN_MAX_2400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = itoa64_to_int (input_buf[ 0]) << 0
|
|
| itoa64_to_int (input_buf[ 1]) << 6
|
|
| itoa64_to_int (input_buf[ 2]) << 12
|
|
| itoa64_to_int (input_buf[ 3]) << 18;
|
|
digest[1] = itoa64_to_int (input_buf[ 4]) << 0
|
|
| itoa64_to_int (input_buf[ 5]) << 6
|
|
| itoa64_to_int (input_buf[ 6]) << 12
|
|
| itoa64_to_int (input_buf[ 7]) << 18;
|
|
digest[2] = itoa64_to_int (input_buf[ 8]) << 0
|
|
| itoa64_to_int (input_buf[ 9]) << 6
|
|
| itoa64_to_int (input_buf[10]) << 12
|
|
| itoa64_to_int (input_buf[11]) << 18;
|
|
digest[3] = itoa64_to_int (input_buf[12]) << 0
|
|
| itoa64_to_int (input_buf[13]) << 6
|
|
| itoa64_to_int (input_buf[14]) << 12
|
|
| itoa64_to_int (input_buf[15]) << 18;
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
digest[0] &= 0x00ffffff;
|
|
digest[1] &= 0x00ffffff;
|
|
digest[2] &= 0x00ffffff;
|
|
digest[3] &= 0x00ffffff;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md5asa_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_2410H) || (input_len > DISPLAY_LEN_MAX_2410H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_2410) || (input_len > DISPLAY_LEN_MAX_2410)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = itoa64_to_int (input_buf[ 0]) << 0
|
|
| itoa64_to_int (input_buf[ 1]) << 6
|
|
| itoa64_to_int (input_buf[ 2]) << 12
|
|
| itoa64_to_int (input_buf[ 3]) << 18;
|
|
digest[1] = itoa64_to_int (input_buf[ 4]) << 0
|
|
| itoa64_to_int (input_buf[ 5]) << 6
|
|
| itoa64_to_int (input_buf[ 6]) << 12
|
|
| itoa64_to_int (input_buf[ 7]) << 18;
|
|
digest[2] = itoa64_to_int (input_buf[ 8]) << 0
|
|
| itoa64_to_int (input_buf[ 9]) << 6
|
|
| itoa64_to_int (input_buf[10]) << 12
|
|
| itoa64_to_int (input_buf[11]) << 18;
|
|
digest[3] = itoa64_to_int (input_buf[12]) << 0
|
|
| itoa64_to_int (input_buf[13]) << 6
|
|
| itoa64_to_int (input_buf[14]) << 12
|
|
| itoa64_to_int (input_buf[15]) << 18;
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
digest[0] &= 0x00ffffff;
|
|
digest[1] &= 0x00ffffff;
|
|
digest[2] &= 0x00ffffff;
|
|
digest[3] &= 0x00ffffff;
|
|
|
|
if (input_buf[16] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 16 - 1;
|
|
|
|
char *salt_buf = input_buf + 16 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
void transform_netntlmv1_key (const uint8_t *nthash, uint8_t *key)
|
|
{
|
|
key[0] = (nthash[0] >> 0);
|
|
key[1] = (nthash[0] << 7) | (nthash[1] >> 1);
|
|
key[2] = (nthash[1] << 6) | (nthash[2] >> 2);
|
|
key[3] = (nthash[2] << 5) | (nthash[3] >> 3);
|
|
key[4] = (nthash[3] << 4) | (nthash[4] >> 4);
|
|
key[5] = (nthash[4] << 3) | (nthash[5] >> 5);
|
|
key[6] = (nthash[5] << 2) | (nthash[6] >> 6);
|
|
key[7] = (nthash[6] << 1);
|
|
|
|
key[0] |= 0x01;
|
|
key[1] |= 0x01;
|
|
key[2] |= 0x01;
|
|
key[3] |= 0x01;
|
|
key[4] |= 0x01;
|
|
key[5] |= 0x01;
|
|
key[6] |= 0x01;
|
|
key[7] |= 0x01;
|
|
}
|
|
|
|
int netntlmv1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_5500) || (input_len > DISPLAY_LEN_MAX_5500)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
netntlm_t *netntlm = (netntlm_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *user_pos = input_buf;
|
|
|
|
char *unused_pos = strchr (user_pos, ':');
|
|
|
|
if (unused_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint user_len = unused_pos - user_pos;
|
|
|
|
if (user_len > 60) return (PARSER_SALT_LENGTH);
|
|
|
|
unused_pos++;
|
|
|
|
char *domain_pos = strchr (unused_pos, ':');
|
|
|
|
if (domain_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint unused_len = domain_pos - unused_pos;
|
|
|
|
if (unused_len != 0) return (PARSER_SALT_LENGTH);
|
|
|
|
domain_pos++;
|
|
|
|
char *srvchall_pos = strchr (domain_pos, ':');
|
|
|
|
if (srvchall_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint domain_len = srvchall_pos - domain_pos;
|
|
|
|
if (domain_len > 45) return (PARSER_SALT_LENGTH);
|
|
|
|
srvchall_pos++;
|
|
|
|
char *hash_pos = strchr (srvchall_pos, ':');
|
|
|
|
if (srvchall_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint srvchall_len = hash_pos - srvchall_pos;
|
|
|
|
// if (srvchall_len != 0) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
char *clichall_pos = strchr (hash_pos, ':');
|
|
|
|
if (clichall_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint hash_len = clichall_pos - hash_pos;
|
|
|
|
if (hash_len != 48) return (PARSER_HASH_LENGTH);
|
|
|
|
clichall_pos++;
|
|
|
|
uint clichall_len = input_len - user_len - 1 - unused_len - 1 - domain_len - 1 - srvchall_len - 1 - hash_len - 1;
|
|
|
|
if (clichall_len != 16) return (PARSER_SALT_LENGTH);
|
|
|
|
/**
|
|
* store some data for later use
|
|
*/
|
|
|
|
netntlm->user_len = user_len * 2;
|
|
netntlm->domain_len = domain_len * 2;
|
|
netntlm->srvchall_len = srvchall_len / 2;
|
|
netntlm->clichall_len = clichall_len / 2;
|
|
|
|
char *userdomain_ptr = (char *) netntlm->userdomain_buf;
|
|
char *chall_ptr = (char *) netntlm->chall_buf;
|
|
|
|
/**
|
|
* handle username and domainname
|
|
*/
|
|
|
|
for (uint i = 0; i < user_len; i++)
|
|
{
|
|
*userdomain_ptr++ = user_pos[i];
|
|
*userdomain_ptr++ = 0;
|
|
}
|
|
|
|
for (uint i = 0; i < domain_len; i++)
|
|
{
|
|
*userdomain_ptr++ = domain_pos[i];
|
|
*userdomain_ptr++ = 0;
|
|
}
|
|
|
|
/**
|
|
* handle server challenge encoding
|
|
*/
|
|
|
|
for (uint i = 0; i < srvchall_len; i += 2)
|
|
{
|
|
const char p0 = srvchall_pos[i + 0];
|
|
const char p1 = srvchall_pos[i + 1];
|
|
|
|
*chall_ptr++ = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
/**
|
|
* handle client challenge encoding
|
|
*/
|
|
|
|
for (uint i = 0; i < clichall_len; i += 2)
|
|
{
|
|
const char p0 = clichall_pos[i + 0];
|
|
const char p1 = clichall_pos[i + 1];
|
|
|
|
*chall_ptr++ = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
/**
|
|
* store data
|
|
*/
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
uint salt_len = parse_and_store_salt (salt_buf_ptr, clichall_pos, clichall_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
/* special case, last 8 byte do not need to be checked since they are brute-forced next */
|
|
|
|
uint digest_tmp[2];
|
|
|
|
digest_tmp[0] = hex_to_uint (&hash_pos[32]);
|
|
digest_tmp[1] = hex_to_uint (&hash_pos[40]);
|
|
|
|
digest_tmp[0] = byte_swap_32 (digest_tmp[0]);
|
|
digest_tmp[1] = byte_swap_32 (digest_tmp[1]);
|
|
|
|
/* special case 2: ESS */
|
|
|
|
if (srvchall_len == 48)
|
|
{
|
|
if ((netntlm->chall_buf[2] == 0) && (netntlm->chall_buf[3] == 0) && (netntlm->chall_buf[4] == 0) && (netntlm->chall_buf[5] == 0))
|
|
{
|
|
uint w[16];
|
|
|
|
w[ 0] = netntlm->chall_buf[6];
|
|
w[ 1] = netntlm->chall_buf[7];
|
|
w[ 2] = netntlm->chall_buf[0];
|
|
w[ 3] = netntlm->chall_buf[1];
|
|
w[ 4] = 0x80;
|
|
w[ 5] = 0;
|
|
w[ 6] = 0;
|
|
w[ 7] = 0;
|
|
w[ 8] = 0;
|
|
w[ 9] = 0;
|
|
w[10] = 0;
|
|
w[11] = 0;
|
|
w[12] = 0;
|
|
w[13] = 0;
|
|
w[14] = 16 * 8;
|
|
w[15] = 0;
|
|
|
|
uint dgst[4];
|
|
|
|
dgst[0] = MAGIC_A;
|
|
dgst[1] = MAGIC_B;
|
|
dgst[2] = MAGIC_C;
|
|
dgst[3] = MAGIC_D;
|
|
|
|
md5_64 (w, dgst);
|
|
|
|
salt->salt_buf[0] = dgst[0];
|
|
salt->salt_buf[1] = dgst[1];
|
|
}
|
|
}
|
|
|
|
/* precompute netntlmv1 exploit start */
|
|
|
|
for (uint i = 0; i < 0x10000; i++)
|
|
{
|
|
uint key_md4[2] = { i, 0 };
|
|
uint key_des[2] = { 0, 0 };
|
|
|
|
transform_netntlmv1_key ((uint8_t *) key_md4, (uint8_t *) key_des);
|
|
|
|
uint Kc[16];
|
|
uint Kd[16];
|
|
|
|
_des_keysetup (key_des, Kc, Kd, c_skb);
|
|
|
|
uint data3[2] = { salt->salt_buf[0], salt->salt_buf[1] };
|
|
|
|
_des_encrypt (data3, Kc, Kd, c_SPtrans);
|
|
|
|
if (data3[0] != digest_tmp[0]) continue;
|
|
if (data3[1] != digest_tmp[1]) continue;
|
|
|
|
salt->salt_buf[2] = i;
|
|
|
|
salt->salt_len = 24;
|
|
|
|
break;
|
|
}
|
|
|
|
salt->salt_buf_pc[0] = digest_tmp[0];
|
|
salt->salt_buf_pc[1] = digest_tmp[1];
|
|
|
|
/* precompute netntlmv1 exploit stop */
|
|
|
|
uint32_t tt;
|
|
|
|
IP (digest[0], digest[1], tt);
|
|
IP (digest[2], digest[3], tt);
|
|
|
|
digest[0] = ROTATE_RIGHT (digest[0], 29);
|
|
digest[1] = ROTATE_RIGHT (digest[1], 29);
|
|
digest[2] = ROTATE_RIGHT (digest[2], 29);
|
|
digest[3] = ROTATE_RIGHT (digest[3], 29);
|
|
|
|
IP (salt->salt_buf[0], salt->salt_buf[1], tt);
|
|
|
|
salt->salt_buf[0] = ROTATE_LEFT (salt->salt_buf[0], 3);
|
|
salt->salt_buf[1] = ROTATE_LEFT (salt->salt_buf[1], 3);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int netntlmv2_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_5600) || (input_len > DISPLAY_LEN_MAX_5600)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
netntlm_t *netntlm = (netntlm_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *user_pos = input_buf;
|
|
|
|
char *unused_pos = strchr (user_pos, ':');
|
|
|
|
if (unused_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint user_len = unused_pos - user_pos;
|
|
|
|
if (user_len > 60) return (PARSER_SALT_LENGTH);
|
|
|
|
unused_pos++;
|
|
|
|
char *domain_pos = strchr (unused_pos, ':');
|
|
|
|
if (domain_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint unused_len = domain_pos - unused_pos;
|
|
|
|
if (unused_len != 0) return (PARSER_SALT_LENGTH);
|
|
|
|
domain_pos++;
|
|
|
|
char *srvchall_pos = strchr (domain_pos, ':');
|
|
|
|
if (srvchall_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint domain_len = srvchall_pos - domain_pos;
|
|
|
|
if (domain_len > 45) return (PARSER_SALT_LENGTH);
|
|
|
|
srvchall_pos++;
|
|
|
|
char *hash_pos = strchr (srvchall_pos, ':');
|
|
|
|
if (srvchall_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint srvchall_len = hash_pos - srvchall_pos;
|
|
|
|
if (srvchall_len != 16) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
char *clichall_pos = strchr (hash_pos, ':');
|
|
|
|
if (clichall_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint hash_len = clichall_pos - hash_pos;
|
|
|
|
if (hash_len != 32) return (PARSER_HASH_LENGTH);
|
|
|
|
clichall_pos++;
|
|
|
|
uint clichall_len = input_len - user_len - 1 - unused_len - 1 - domain_len - 1 - srvchall_len - 1 - hash_len - 1;
|
|
|
|
if (clichall_len > 1024) return (PARSER_SALT_LENGTH);
|
|
|
|
if (clichall_len % 2) return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* store some data for later use
|
|
*/
|
|
|
|
netntlm->user_len = user_len * 2;
|
|
netntlm->domain_len = domain_len * 2;
|
|
netntlm->srvchall_len = srvchall_len / 2;
|
|
netntlm->clichall_len = clichall_len / 2;
|
|
|
|
char *userdomain_ptr = (char *) netntlm->userdomain_buf;
|
|
char *chall_ptr = (char *) netntlm->chall_buf;
|
|
|
|
/**
|
|
* handle username and domainname
|
|
*/
|
|
|
|
for (uint i = 0; i < user_len; i++)
|
|
{
|
|
*userdomain_ptr++ = toupper (user_pos[i]);
|
|
*userdomain_ptr++ = 0;
|
|
}
|
|
|
|
for (uint i = 0; i < domain_len; i++)
|
|
{
|
|
*userdomain_ptr++ = domain_pos[i];
|
|
*userdomain_ptr++ = 0;
|
|
}
|
|
|
|
*userdomain_ptr++ = 0x80;
|
|
|
|
/**
|
|
* handle server challenge encoding
|
|
*/
|
|
|
|
for (uint i = 0; i < srvchall_len; i += 2)
|
|
{
|
|
const char p0 = srvchall_pos[i + 0];
|
|
const char p1 = srvchall_pos[i + 1];
|
|
|
|
*chall_ptr++ = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
/**
|
|
* handle client challenge encoding
|
|
*/
|
|
|
|
for (uint i = 0; i < clichall_len; i += 2)
|
|
{
|
|
const char p0 = clichall_pos[i + 0];
|
|
const char p1 = clichall_pos[i + 1];
|
|
|
|
*chall_ptr++ = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
*chall_ptr++ = 0x80;
|
|
|
|
/**
|
|
* handle hash itself
|
|
*/
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
/**
|
|
* reuse challange data as salt_buf, its the buffer that is most likely unique
|
|
*/
|
|
|
|
salt->salt_buf[0] = 0;
|
|
salt->salt_buf[1] = 0;
|
|
salt->salt_buf[2] = 0;
|
|
salt->salt_buf[3] = 0;
|
|
salt->salt_buf[4] = 0;
|
|
salt->salt_buf[5] = 0;
|
|
salt->salt_buf[6] = 0;
|
|
salt->salt_buf[7] = 0;
|
|
|
|
uint *uptr;
|
|
|
|
uptr = (uint *) netntlm->userdomain_buf;
|
|
|
|
for (uint i = 0; i < 16; i += 16)
|
|
{
|
|
md5_64 (uptr, salt->salt_buf);
|
|
}
|
|
|
|
uptr = (uint *) netntlm->chall_buf;
|
|
|
|
for (uint i = 0; i < 256; i += 16)
|
|
{
|
|
md5_64 (uptr, salt->salt_buf);
|
|
}
|
|
|
|
salt->salt_len = 16;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int joomla_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_11H) || (input_len > DISPLAY_LEN_MAX_11H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11) || (input_len > DISPLAY_LEN_MAX_11)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int postgresql_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_12H) || (input_len > DISPLAY_LEN_MAX_12H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_12) || (input_len > DISPLAY_LEN_MAX_12)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md5md5_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_2600) || (input_len > DISPLAY_LEN_MAX_2600)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
/**
|
|
* This is a virtual salt. While the algorithm is basically not salted
|
|
* we can exploit the salt buffer to set the 0x80 and the w[14] value.
|
|
* This way we can save a special md5md5 kernel and reuse the one from vbull.
|
|
*/
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
uint salt_len = parse_and_store_salt (salt_buf_ptr, (char *) "", 0);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int vb3_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_2611H) || (input_len > DISPLAY_LEN_MAX_2611H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_2611) || (input_len > DISPLAY_LEN_MAX_2611)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int vb30_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_2711H) || (input_len > DISPLAY_LEN_MAX_2711H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_2711) || (input_len > DISPLAY_LEN_MAX_2711)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int dcc_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_1100H) || (input_len > DISPLAY_LEN_MAX_1100H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1100) || (input_len > DISPLAY_LEN_MAX_1100)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD4M_A;
|
|
digest[1] -= MD4M_B;
|
|
digest[2] -= MD4M_C;
|
|
digest[3] -= MD4M_D;
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int ipb2_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_2811H) || (input_len > DISPLAY_LEN_MAX_2811H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_2811) || (input_len > DISPLAY_LEN_MAX_2811)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
uint salt_pc_block[16];
|
|
|
|
memset (salt_pc_block, 0, sizeof (salt_pc_block));
|
|
|
|
char *salt_pc_block_ptr = (char *) salt_pc_block;
|
|
|
|
salt_len = parse_and_store_salt (salt_pc_block_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt_pc_block_ptr[salt_len] = (unsigned char) 0x80;
|
|
|
|
salt_pc_block[14] = salt_len * 8;
|
|
|
|
uint salt_pc_digest[4];
|
|
|
|
salt_pc_digest[0] = MAGIC_A;
|
|
salt_pc_digest[1] = MAGIC_B;
|
|
salt_pc_digest[2] = MAGIC_C;
|
|
salt_pc_digest[3] = MAGIC_D;
|
|
|
|
md5_64 (salt_pc_block, salt_pc_digest);
|
|
|
|
salt_pc_digest[0] = byte_swap_32 (salt_pc_digest[0]);
|
|
salt_pc_digest[1] = byte_swap_32 (salt_pc_digest[1]);
|
|
salt_pc_digest[2] = byte_swap_32 (salt_pc_digest[2]);
|
|
salt_pc_digest[3] = byte_swap_32 (salt_pc_digest[3]);
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
memcpy (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
char *salt_buf_pc_ptr = (char *) salt->salt_buf_pc;
|
|
|
|
bin_to_hex_lower (salt_pc_digest[0], salt_buf_pc_ptr + 0);
|
|
bin_to_hex_lower (salt_pc_digest[1], salt_buf_pc_ptr + 8);
|
|
bin_to_hex_lower (salt_pc_digest[2], salt_buf_pc_ptr + 16);
|
|
bin_to_hex_lower (salt_pc_digest[3], salt_buf_pc_ptr + 24);
|
|
|
|
salt->salt_len = 32; // changed, was salt_len before -- was a bug? 32 should be correct
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_100) || (input_len > DISPLAY_LEN_MAX_100)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha1linkedin_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_100) || (input_len > DISPLAY_LEN_MAX_100)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
|
|
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)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_110H) || (input_len > DISPLAY_LEN_MAX_110H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_110) || (input_len > DISPLAY_LEN_MAX_110)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
if (input_buf[40] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 40 - 1;
|
|
|
|
char *salt_buf = input_buf + 40 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = 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);
|
|
|
|
if (memcmp (SIGNATURE_SHA1B64, input_buf, 5)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (base64_to_int, input_buf + 5, input_len - 5, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 20);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha1b64s_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_111) || (input_len > DISPLAY_LEN_MAX_111)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SSHA1B64_lower, input_buf, 6) && memcmp (SIGNATURE_SSHA1B64_upper, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
int tmp_len = base64_decode (base64_to_int, input_buf + 6, input_len - 6, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 20);
|
|
|
|
salt->salt_len = tmp_len - 20;
|
|
|
|
memcpy (salt->salt_buf, tmp_buf + 20, salt->salt_len);
|
|
|
|
if (data.opts_type & OPTS_TYPE_ST_ADD80)
|
|
{
|
|
char *ptr = (char *) salt->salt_buf;
|
|
|
|
ptr[salt->salt_len] = 0x80;
|
|
}
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int mssql2000_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_131) || (input_len > DISPLAY_LEN_MAX_131)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_MSSQL, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_buf = input_buf + 6;
|
|
|
|
uint salt_len = 8;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char *hash_pos = input_buf + 6 + 8 + 40;
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_pos[32]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int mssql2005_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_132) || (input_len > DISPLAY_LEN_MAX_132)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_MSSQL, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_buf = input_buf + 6;
|
|
|
|
uint salt_len = 8;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char *hash_pos = input_buf + 6 + 8;
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_pos[32]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int mssql2012_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1731) || (input_len > DISPLAY_LEN_MAX_1731)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_MSSQL2012, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_buf = input_buf + 6;
|
|
|
|
uint salt_len = 8;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char *hash_pos = input_buf + 6 + 8;
|
|
|
|
digest[0] = hex_to_uint64_t (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint64_t (&hash_pos[ 16]);
|
|
digest[2] = hex_to_uint64_t (&hash_pos[ 32]);
|
|
digest[3] = hex_to_uint64_t (&hash_pos[ 48]);
|
|
digest[4] = hex_to_uint64_t (&hash_pos[ 64]);
|
|
digest[5] = hex_to_uint64_t (&hash_pos[ 80]);
|
|
digest[6] = hex_to_uint64_t (&hash_pos[ 96]);
|
|
digest[7] = hex_to_uint64_t (&hash_pos[112]);
|
|
|
|
digest[0] -= SHA512M_A;
|
|
digest[1] -= SHA512M_B;
|
|
digest[2] -= SHA512M_C;
|
|
digest[3] -= SHA512M_D;
|
|
digest[4] -= SHA512M_E;
|
|
digest[5] -= SHA512M_F;
|
|
digest[6] -= SHA512M_G;
|
|
digest[7] -= SHA512M_H;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int oracleh_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_3100H) || (input_len > DISPLAY_LEN_MAX_3100H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_3100) || (input_len > DISPLAY_LEN_MAX_3100)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
|
|
if (input_buf[16] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 16 - 1;
|
|
|
|
char *salt_buf = input_buf + 16 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int oracles_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_112) || (input_len > DISPLAY_LEN_MAX_112)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
if (input_buf[40] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 40 - 1;
|
|
|
|
char *salt_buf = input_buf + 40 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int oraclet_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_12300) || (input_len > DISPLAY_LEN_MAX_12300)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *hash_pos = input_buf;
|
|
|
|
digest[ 0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[ 1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[ 2] = hex_to_uint (&hash_pos[ 16]);
|
|
digest[ 3] = hex_to_uint (&hash_pos[ 24]);
|
|
digest[ 4] = hex_to_uint (&hash_pos[ 32]);
|
|
digest[ 5] = hex_to_uint (&hash_pos[ 40]);
|
|
digest[ 6] = hex_to_uint (&hash_pos[ 48]);
|
|
digest[ 7] = hex_to_uint (&hash_pos[ 56]);
|
|
digest[ 8] = hex_to_uint (&hash_pos[ 64]);
|
|
digest[ 9] = hex_to_uint (&hash_pos[ 72]);
|
|
digest[10] = hex_to_uint (&hash_pos[ 80]);
|
|
digest[11] = hex_to_uint (&hash_pos[ 88]);
|
|
digest[12] = hex_to_uint (&hash_pos[ 96]);
|
|
digest[13] = hex_to_uint (&hash_pos[104]);
|
|
digest[14] = hex_to_uint (&hash_pos[112]);
|
|
digest[15] = hex_to_uint (&hash_pos[120]);
|
|
|
|
char *salt_pos = input_buf + 128;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&salt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&salt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&salt_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&salt_pos[24]);
|
|
|
|
salt->salt_iter = ROUNDS_ORACLET - 1;
|
|
salt->salt_len = 16;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha256_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1400) || (input_len > DISPLAY_LEN_MAX_1400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
digest[5] = hex_to_uint (&input_buf[40]);
|
|
digest[6] = hex_to_uint (&input_buf[48]);
|
|
digest[7] = hex_to_uint (&input_buf[56]);
|
|
|
|
digest[0] -= SHA256M_A;
|
|
digest[1] -= SHA256M_B;
|
|
digest[2] -= SHA256M_C;
|
|
digest[3] -= SHA256M_D;
|
|
digest[4] -= SHA256M_E;
|
|
digest[5] -= SHA256M_F;
|
|
digest[6] -= SHA256M_G;
|
|
digest[7] -= SHA256M_H;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha256s_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_1410H) || (input_len > DISPLAY_LEN_MAX_1410H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1410) || (input_len > DISPLAY_LEN_MAX_1410)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
digest[5] = hex_to_uint (&input_buf[40]);
|
|
digest[6] = hex_to_uint (&input_buf[48]);
|
|
digest[7] = hex_to_uint (&input_buf[56]);
|
|
|
|
digest[0] -= SHA256M_A;
|
|
digest[1] -= SHA256M_B;
|
|
digest[2] -= SHA256M_C;
|
|
digest[3] -= SHA256M_D;
|
|
digest[4] -= SHA256M_E;
|
|
digest[5] -= SHA256M_F;
|
|
digest[6] -= SHA256M_G;
|
|
digest[7] -= SHA256M_H;
|
|
|
|
if (input_buf[64] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 64 - 1;
|
|
|
|
char *salt_buf = input_buf + 64 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha384_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10800) || (input_len > DISPLAY_LEN_MAX_10800)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint64_t (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint64_t (&input_buf[ 16]);
|
|
digest[2] = hex_to_uint64_t (&input_buf[ 32]);
|
|
digest[3] = hex_to_uint64_t (&input_buf[ 48]);
|
|
digest[4] = hex_to_uint64_t (&input_buf[ 64]);
|
|
digest[5] = hex_to_uint64_t (&input_buf[ 80]);
|
|
digest[6] = 0;
|
|
digest[7] = 0;
|
|
|
|
digest[0] -= SHA384M_A;
|
|
digest[1] -= SHA384M_B;
|
|
digest[2] -= SHA384M_C;
|
|
digest[3] -= SHA384M_D;
|
|
digest[4] -= SHA384M_E;
|
|
digest[5] -= SHA384M_F;
|
|
digest[6] -= 0;
|
|
digest[7] -= 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha512_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1700) || (input_len > DISPLAY_LEN_MAX_1700)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint64_t (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint64_t (&input_buf[ 16]);
|
|
digest[2] = hex_to_uint64_t (&input_buf[ 32]);
|
|
digest[3] = hex_to_uint64_t (&input_buf[ 48]);
|
|
digest[4] = hex_to_uint64_t (&input_buf[ 64]);
|
|
digest[5] = hex_to_uint64_t (&input_buf[ 80]);
|
|
digest[6] = hex_to_uint64_t (&input_buf[ 96]);
|
|
digest[7] = hex_to_uint64_t (&input_buf[112]);
|
|
|
|
digest[0] -= SHA512M_A;
|
|
digest[1] -= SHA512M_B;
|
|
digest[2] -= SHA512M_C;
|
|
digest[3] -= SHA512M_D;
|
|
digest[4] -= SHA512M_E;
|
|
digest[5] -= SHA512M_F;
|
|
digest[6] -= SHA512M_G;
|
|
digest[7] -= SHA512M_H;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha512s_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_1710H) || (input_len > DISPLAY_LEN_MAX_1710H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1710) || (input_len > DISPLAY_LEN_MAX_1710)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint64_t (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint64_t (&input_buf[ 16]);
|
|
digest[2] = hex_to_uint64_t (&input_buf[ 32]);
|
|
digest[3] = hex_to_uint64_t (&input_buf[ 48]);
|
|
digest[4] = hex_to_uint64_t (&input_buf[ 64]);
|
|
digest[5] = hex_to_uint64_t (&input_buf[ 80]);
|
|
digest[6] = hex_to_uint64_t (&input_buf[ 96]);
|
|
digest[7] = hex_to_uint64_t (&input_buf[112]);
|
|
|
|
digest[0] -= SHA512M_A;
|
|
digest[1] -= SHA512M_B;
|
|
digest[2] -= SHA512M_C;
|
|
digest[3] -= SHA512M_D;
|
|
digest[4] -= SHA512M_E;
|
|
digest[5] -= SHA512M_F;
|
|
digest[6] -= SHA512M_G;
|
|
digest[7] -= SHA512M_H;
|
|
|
|
if (input_buf[128] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 128 - 1;
|
|
|
|
char *salt_buf = input_buf + 128 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha512crypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if (memcmp (SIGNATURE_SHA512CRYPT, input_buf, 3)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 3;
|
|
|
|
uint iterations_len = 0;
|
|
|
|
if (memcmp (salt_pos, "rounds=", 7) == 0)
|
|
{
|
|
salt_pos += 7;
|
|
|
|
for (iterations_len = 0; salt_pos[0] >= '0' && salt_pos[0] <= '9' && iterations_len < 7; iterations_len++, salt_pos += 1) continue;
|
|
|
|
if (iterations_len == 0 ) return (PARSER_SALT_ITERATION);
|
|
if (salt_pos[0] != '$') return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
salt_pos[0] = 0x0;
|
|
|
|
salt->salt_iter = atoi (salt_pos - iterations_len);
|
|
|
|
salt_pos += 1;
|
|
|
|
iterations_len += 8;
|
|
}
|
|
else
|
|
{
|
|
salt->salt_iter = ROUNDS_SHA512CRYPT;
|
|
}
|
|
|
|
if ((input_len < DISPLAY_LEN_MIN_1800) || (input_len > DISPLAY_LEN_MAX_1800 + iterations_len)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len > 16) return (PARSER_SALT_LENGTH);
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
hash_pos++;
|
|
|
|
sha512crypt_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int keccak_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_5000) || (input_len > DISPLAY_LEN_MAX_5000)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (input_len % 16) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
uint keccak_mdlen = input_len / 2;
|
|
|
|
for (uint i = 0; i < keccak_mdlen / 8; i++)
|
|
{
|
|
digest[i] = hex_to_uint64_t (&input_buf[i * 16]);
|
|
|
|
digest[i] = byte_swap_64 (digest[i]);
|
|
}
|
|
|
|
salt->keccak_mdlen = keccak_mdlen;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int ikepsk_md5_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_5300) || (input_len > DISPLAY_LEN_MAX_5300)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
ikepsk_t *ikepsk = (ikepsk_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* Parse that strange long line
|
|
*/
|
|
|
|
char *in_off[9];
|
|
|
|
size_t in_len[9];
|
|
|
|
in_off[0] = strtok (input_buf, ":");
|
|
|
|
in_len[0] = strlen (in_off[0]);
|
|
|
|
size_t i;
|
|
|
|
for (i = 1; i < 9; i++)
|
|
{
|
|
in_off[i] = strtok (NULL, ":");
|
|
|
|
if (in_off[i] == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
in_len[i] = strlen (in_off[i]);
|
|
}
|
|
|
|
char *ptr;
|
|
|
|
ptr = (char *) ikepsk->msg_buf;
|
|
|
|
for (i = 0; i < in_len[0]; i += 2) *ptr++ = hex_to_char (in_off[0] + i);
|
|
for (i = 0; i < in_len[1]; i += 2) *ptr++ = hex_to_char (in_off[1] + i);
|
|
for (i = 0; i < in_len[2]; i += 2) *ptr++ = hex_to_char (in_off[2] + i);
|
|
for (i = 0; i < in_len[3]; i += 2) *ptr++ = hex_to_char (in_off[3] + i);
|
|
for (i = 0; i < in_len[4]; i += 2) *ptr++ = hex_to_char (in_off[4] + i);
|
|
for (i = 0; i < in_len[5]; i += 2) *ptr++ = hex_to_char (in_off[5] + i);
|
|
|
|
*ptr = 0x80;
|
|
|
|
ikepsk->msg_len = (in_len[0] + in_len[1] + in_len[2] + in_len[3] + in_len[4] + in_len[5]) / 2;
|
|
|
|
ptr = (char *) ikepsk->nr_buf;
|
|
|
|
for (i = 0; i < in_len[6]; i += 2) *ptr++ = hex_to_char (in_off[6] + i);
|
|
for (i = 0; i < in_len[7]; i += 2) *ptr++ = hex_to_char (in_off[7] + i);
|
|
|
|
*ptr = 0x80;
|
|
|
|
ikepsk->nr_len = (in_len[6] + in_len[7]) / 2;
|
|
|
|
/**
|
|
* Store to database
|
|
*/
|
|
|
|
ptr = in_off[8];
|
|
|
|
digest[0] = hex_to_uint (&ptr[ 0]);
|
|
digest[1] = hex_to_uint (&ptr[ 8]);
|
|
digest[2] = hex_to_uint (&ptr[16]);
|
|
digest[3] = hex_to_uint (&ptr[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
salt->salt_len = 32;
|
|
|
|
salt->salt_buf[0] = ikepsk->nr_buf[0];
|
|
salt->salt_buf[1] = ikepsk->nr_buf[1];
|
|
salt->salt_buf[2] = ikepsk->nr_buf[2];
|
|
salt->salt_buf[3] = ikepsk->nr_buf[3];
|
|
salt->salt_buf[4] = ikepsk->nr_buf[4];
|
|
salt->salt_buf[5] = ikepsk->nr_buf[5];
|
|
salt->salt_buf[6] = ikepsk->nr_buf[6];
|
|
salt->salt_buf[7] = ikepsk->nr_buf[7];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int ikepsk_sha1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_5400) || (input_len > DISPLAY_LEN_MAX_5400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
ikepsk_t *ikepsk = (ikepsk_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* Parse that strange long line
|
|
*/
|
|
|
|
char *in_off[9];
|
|
|
|
size_t in_len[9];
|
|
|
|
in_off[0] = strtok (input_buf, ":");
|
|
|
|
in_len[0] = strlen (in_off[0]);
|
|
|
|
size_t i;
|
|
|
|
for (i = 1; i < 9; i++)
|
|
{
|
|
in_off[i] = strtok (NULL, ":");
|
|
|
|
if (in_off[i] == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
in_len[i] = strlen (in_off[i]);
|
|
}
|
|
|
|
char *ptr;
|
|
|
|
ptr = (char *) ikepsk->msg_buf;
|
|
|
|
for (i = 0; i < in_len[0]; i += 2) *ptr++ = hex_to_char (in_off[0] + i);
|
|
for (i = 0; i < in_len[1]; i += 2) *ptr++ = hex_to_char (in_off[1] + i);
|
|
for (i = 0; i < in_len[2]; i += 2) *ptr++ = hex_to_char (in_off[2] + i);
|
|
for (i = 0; i < in_len[3]; i += 2) *ptr++ = hex_to_char (in_off[3] + i);
|
|
for (i = 0; i < in_len[4]; i += 2) *ptr++ = hex_to_char (in_off[4] + i);
|
|
for (i = 0; i < in_len[5]; i += 2) *ptr++ = hex_to_char (in_off[5] + i);
|
|
|
|
*ptr = 0x80;
|
|
|
|
ikepsk->msg_len = (in_len[0] + in_len[1] + in_len[2] + in_len[3] + in_len[4] + in_len[5]) / 2;
|
|
|
|
ptr = (char *) ikepsk->nr_buf;
|
|
|
|
for (i = 0; i < in_len[6]; i += 2) *ptr++ = hex_to_char (in_off[6] + i);
|
|
for (i = 0; i < in_len[7]; i += 2) *ptr++ = hex_to_char (in_off[7] + i);
|
|
|
|
*ptr = 0x80;
|
|
|
|
ikepsk->nr_len = (in_len[6] + in_len[7]) / 2;
|
|
|
|
/**
|
|
* Store to database
|
|
*/
|
|
|
|
ptr = in_off[8];
|
|
|
|
digest[0] = hex_to_uint (&ptr[ 0]);
|
|
digest[1] = hex_to_uint (&ptr[ 8]);
|
|
digest[2] = hex_to_uint (&ptr[16]);
|
|
digest[3] = hex_to_uint (&ptr[24]);
|
|
digest[4] = hex_to_uint (&ptr[32]);
|
|
|
|
salt->salt_len = 32;
|
|
|
|
salt->salt_buf[0] = ikepsk->nr_buf[0];
|
|
salt->salt_buf[1] = ikepsk->nr_buf[1];
|
|
salt->salt_buf[2] = ikepsk->nr_buf[2];
|
|
salt->salt_buf[3] = ikepsk->nr_buf[3];
|
|
salt->salt_buf[4] = ikepsk->nr_buf[4];
|
|
salt->salt_buf[5] = ikepsk->nr_buf[5];
|
|
salt->salt_buf[6] = ikepsk->nr_buf[6];
|
|
salt->salt_buf[7] = ikepsk->nr_buf[7];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int ripemd160_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_6000) || (input_len > DISPLAY_LEN_MAX_6000)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int whirlpool_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_6100) || (input_len > DISPLAY_LEN_MAX_6100)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[ 0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[ 1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[ 2] = hex_to_uint (&input_buf[ 16]);
|
|
digest[ 3] = hex_to_uint (&input_buf[ 24]);
|
|
digest[ 4] = hex_to_uint (&input_buf[ 32]);
|
|
digest[ 5] = hex_to_uint (&input_buf[ 40]);
|
|
digest[ 6] = hex_to_uint (&input_buf[ 48]);
|
|
digest[ 7] = hex_to_uint (&input_buf[ 56]);
|
|
digest[ 8] = hex_to_uint (&input_buf[ 64]);
|
|
digest[ 9] = hex_to_uint (&input_buf[ 72]);
|
|
digest[10] = hex_to_uint (&input_buf[ 80]);
|
|
digest[11] = hex_to_uint (&input_buf[ 88]);
|
|
digest[12] = hex_to_uint (&input_buf[ 96]);
|
|
digest[13] = hex_to_uint (&input_buf[104]);
|
|
digest[14] = hex_to_uint (&input_buf[112]);
|
|
digest[15] = hex_to_uint (&input_buf[120]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int androidpin_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_5800) || (input_len > DISPLAY_LEN_MAX_5800)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&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;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
salt->salt_iter = ROUNDS_ANDROIDPIN - 1;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int truecrypt_parse_hash_1k (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
tc_t *tc = (tc_t *) hash_buf->esalt;
|
|
|
|
if (input_len == 0)
|
|
{
|
|
log_error ("TrueCrypt container not specified");
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
FILE *fp = fopen (input_buf, "rb");
|
|
|
|
if (fp == NULL)
|
|
{
|
|
log_error ("%s: %s", input_buf, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
char buf[512];
|
|
|
|
int n = fread (buf, 1, sizeof (buf), fp);
|
|
|
|
fclose (fp);
|
|
|
|
if (n != 512) return (PARSER_TC_FILE_SIZE);
|
|
|
|
memcpy (tc->salt_buf, buf, 64);
|
|
|
|
memcpy (tc->data_buf, buf + 64, 512 - 64);
|
|
|
|
salt->salt_buf[0] = tc->salt_buf[0];
|
|
|
|
salt->salt_len = 4;
|
|
|
|
salt->salt_iter = 1000 - 1;
|
|
|
|
digest[0] = tc->data_buf[0];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int truecrypt_parse_hash_2k (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
tc_t *tc = (tc_t *) hash_buf->esalt;
|
|
|
|
if (input_len == 0)
|
|
{
|
|
log_error ("TrueCrypt container not specified");
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
FILE *fp = fopen (input_buf, "rb");
|
|
|
|
if (fp == NULL)
|
|
{
|
|
log_error ("%s: %s", input_buf, strerror (errno));
|
|
|
|
exit (-1);
|
|
}
|
|
|
|
char buf[512];
|
|
|
|
int n = fread (buf, 1, sizeof (buf), fp);
|
|
|
|
fclose (fp);
|
|
|
|
if (n != 512) return (PARSER_TC_FILE_SIZE);
|
|
|
|
memcpy (tc->salt_buf, buf, 64);
|
|
|
|
memcpy (tc->data_buf, buf + 64, 512 - 64);
|
|
|
|
salt->salt_buf[0] = tc->salt_buf[0];
|
|
|
|
salt->salt_len = 4;
|
|
|
|
salt->salt_iter = 2000 - 1;
|
|
|
|
digest[0] = tc->data_buf[0];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int md5aix_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_6300) || (input_len > DISPLAY_LEN_MAX_6300)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_MD5AIX, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 6;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len < 8) return (PARSER_SALT_LENGTH);
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
salt->salt_iter = 1000;
|
|
|
|
hash_pos++;
|
|
|
|
md5crypt_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha1aix_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_6700) || (input_len > DISPLAY_LEN_MAX_6700)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SHA1AIX, input_buf, 7)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *iter_pos = input_buf + 7;
|
|
|
|
char *salt_pos = strchr (iter_pos, '$');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len < 16) return (PARSER_SALT_LENGTH);
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char salt_iter[3] = { iter_pos[0], iter_pos[1], 0 };
|
|
|
|
salt->salt_sign[0] = atoi (salt_iter);
|
|
|
|
salt->salt_iter = (1 << atoi (salt_iter)) - 1;
|
|
|
|
hash_pos++;
|
|
|
|
sha1aix_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha256aix_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_6400) || (input_len > DISPLAY_LEN_MAX_6400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SHA256AIX, input_buf, 9)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *iter_pos = input_buf + 9;
|
|
|
|
char *salt_pos = strchr (iter_pos, '$');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len < 16) return (PARSER_SALT_LENGTH);
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char salt_iter[3] = { iter_pos[0], iter_pos[1], 0 };
|
|
|
|
salt->salt_sign[0] = atoi (salt_iter);
|
|
|
|
salt->salt_iter = (1 << atoi (salt_iter)) - 1;
|
|
|
|
hash_pos++;
|
|
|
|
sha256aix_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
digest[5] = byte_swap_32 (digest[5]);
|
|
digest[6] = byte_swap_32 (digest[6]);
|
|
digest[7] = byte_swap_32 (digest[7]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha512aix_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_6500) || (input_len > DISPLAY_LEN_MAX_6500)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SHA512AIX, input_buf, 9)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *iter_pos = input_buf + 9;
|
|
|
|
char *salt_pos = strchr (iter_pos, '$');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len < 16) return (PARSER_SALT_LENGTH);
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char salt_iter[3] = { iter_pos[0], iter_pos[1], 0 };
|
|
|
|
salt->salt_sign[0] = atoi (salt_iter);
|
|
|
|
salt->salt_iter = (1 << atoi (salt_iter)) - 1;
|
|
|
|
hash_pos++;
|
|
|
|
sha512aix_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
digest[0] = byte_swap_64 (digest[0]);
|
|
digest[1] = byte_swap_64 (digest[1]);
|
|
digest[2] = byte_swap_64 (digest[2]);
|
|
digest[3] = byte_swap_64 (digest[3]);
|
|
digest[4] = byte_swap_64 (digest[4]);
|
|
digest[5] = byte_swap_64 (digest[5]);
|
|
digest[6] = byte_swap_64 (digest[6]);
|
|
digest[7] = byte_swap_64 (digest[7]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int agilekey_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_6600) || (input_len > DISPLAY_LEN_MAX_6600)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
agilekey_t *agilekey = (agilekey_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *iterations_pos = input_buf;
|
|
|
|
char *saltbuf_pos = strchr (iterations_pos, ':');
|
|
|
|
if (saltbuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint iterations_len = saltbuf_pos - iterations_pos;
|
|
|
|
if (iterations_len > 6) return (PARSER_SALT_LENGTH);
|
|
|
|
saltbuf_pos++;
|
|
|
|
char *cipherbuf_pos = strchr (saltbuf_pos, ':');
|
|
|
|
if (cipherbuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint saltbuf_len = cipherbuf_pos - saltbuf_pos;
|
|
|
|
if (saltbuf_len != 16) return (PARSER_SALT_LENGTH);
|
|
|
|
uint cipherbuf_len = input_len - iterations_len - 1 - saltbuf_len - 1;
|
|
|
|
if (cipherbuf_len != 2080) return (PARSER_HASH_LENGTH);
|
|
|
|
cipherbuf_pos++;
|
|
|
|
/**
|
|
* pbkdf2 iterations
|
|
*/
|
|
|
|
salt->salt_iter = atoi (iterations_pos) - 1;
|
|
|
|
/**
|
|
* handle salt encoding
|
|
*/
|
|
|
|
char *saltbuf_ptr = (char *) salt->salt_buf;
|
|
|
|
for (uint i = 0; i < saltbuf_len; i += 2)
|
|
{
|
|
const char p0 = saltbuf_pos[i + 0];
|
|
const char p1 = saltbuf_pos[i + 1];
|
|
|
|
*saltbuf_ptr++ = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
salt->salt_len = saltbuf_len / 2;
|
|
|
|
/**
|
|
* handle cipher encoding
|
|
*/
|
|
|
|
uint *tmp = (uint *) mymalloc (32);
|
|
|
|
char *cipherbuf_ptr = (char *) tmp;
|
|
|
|
for (uint i = 2016; i < cipherbuf_len; i += 2)
|
|
{
|
|
const char p0 = cipherbuf_pos[i + 0];
|
|
const char p1 = cipherbuf_pos[i + 1];
|
|
|
|
*cipherbuf_ptr++ = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
// iv is stored at salt_buf 4 (length 16)
|
|
// data is stored at salt_buf 8 (length 16)
|
|
|
|
salt->salt_buf[ 4] = byte_swap_32 (tmp[0]);
|
|
salt->salt_buf[ 5] = byte_swap_32 (tmp[1]);
|
|
salt->salt_buf[ 6] = byte_swap_32 (tmp[2]);
|
|
salt->salt_buf[ 7] = byte_swap_32 (tmp[3]);
|
|
|
|
salt->salt_buf[ 8] = byte_swap_32 (tmp[4]);
|
|
salt->salt_buf[ 9] = byte_swap_32 (tmp[5]);
|
|
salt->salt_buf[10] = byte_swap_32 (tmp[6]);
|
|
salt->salt_buf[11] = byte_swap_32 (tmp[7]);
|
|
|
|
free (tmp);
|
|
|
|
for (uint i = 0, j = 0; i < 1040; i += 1, j += 2)
|
|
{
|
|
const char p0 = cipherbuf_pos[j + 0];
|
|
const char p1 = cipherbuf_pos[j + 1];
|
|
|
|
agilekey->cipher[i] = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
/**
|
|
* digest buf
|
|
*/
|
|
|
|
digest[0] = 0x10101010;
|
|
digest[1] = 0x10101010;
|
|
digest[2] = 0x10101010;
|
|
digest[3] = 0x10101010;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int lastpass_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_6800) || (input_len > DISPLAY_LEN_MAX_6800)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *hashbuf_pos = input_buf;
|
|
|
|
char *iterations_pos = strchr (hashbuf_pos, ':');
|
|
|
|
if (iterations_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint hash_len = iterations_pos - hashbuf_pos;
|
|
|
|
if ((hash_len != 32) && (hash_len != 64)) return (PARSER_HASH_LENGTH);
|
|
|
|
iterations_pos++;
|
|
|
|
char *saltbuf_pos = strchr (iterations_pos, ':');
|
|
|
|
if (saltbuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint iterations_len = saltbuf_pos - iterations_pos;
|
|
|
|
saltbuf_pos++;
|
|
|
|
uint salt_len = input_len - hash_len - 1 - iterations_len - 1;
|
|
|
|
if (salt_len > 32) return (PARSER_SALT_LENGTH);
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, saltbuf_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
salt->salt_iter = atoi (iterations_pos) - 1;
|
|
|
|
digest[0] = hex_to_uint (&hashbuf_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hashbuf_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hashbuf_pos[16]);
|
|
digest[3] = hex_to_uint (&hashbuf_pos[24]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int gost_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_6900) || (input_len > DISPLAY_LEN_MAX_6900)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
digest[5] = hex_to_uint (&input_buf[40]);
|
|
digest[6] = hex_to_uint (&input_buf[48]);
|
|
digest[7] = hex_to_uint (&input_buf[56]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
digest[5] = byte_swap_32 (digest[5]);
|
|
digest[6] = byte_swap_32 (digest[6]);
|
|
digest[7] = byte_swap_32 (digest[7]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha256crypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if (memcmp (SIGNATURE_SHA256CRYPT, input_buf, 3)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 3;
|
|
|
|
uint iterations_len = 0;
|
|
|
|
if (memcmp (salt_pos, "rounds=", 7) == 0)
|
|
{
|
|
salt_pos += 7;
|
|
|
|
for (iterations_len = 0; salt_pos[0] >= '0' && salt_pos[0] <= '9' && iterations_len < 7; iterations_len++, salt_pos += 1) continue;
|
|
|
|
if (iterations_len == 0 ) return (PARSER_SALT_ITERATION);
|
|
if (salt_pos[0] != '$') return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
salt_pos[0] = 0x0;
|
|
|
|
salt->salt_iter = atoi (salt_pos - iterations_len);
|
|
|
|
salt_pos += 1;
|
|
|
|
iterations_len += 8;
|
|
}
|
|
else
|
|
{
|
|
salt->salt_iter = ROUNDS_SHA256CRYPT;
|
|
}
|
|
|
|
if ((input_len < DISPLAY_LEN_MIN_7400) || (input_len > DISPLAY_LEN_MAX_7400 + iterations_len)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len > 16) return (PARSER_SALT_LENGTH);
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
hash_pos++;
|
|
|
|
sha256crypt_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha512osx_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
uint max_len = DISPLAY_LEN_MAX_7100 + (2 * 128);
|
|
|
|
if ((input_len < DISPLAY_LEN_MIN_7100) || (input_len > max_len)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SHA512OSX, input_buf, 4)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pbkdf2_sha512_t *pbkdf2_sha512 = (pbkdf2_sha512_t *) hash_buf->esalt;
|
|
|
|
char *iter_pos = input_buf + 4;
|
|
|
|
char *salt_pos = strchr (iter_pos, '$');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
if (((input_len - (hash_pos - input_buf) - 1) % 128) != 0) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
digest[0] = hex_to_uint64_t (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint64_t (&hash_pos[ 16]);
|
|
digest[2] = hex_to_uint64_t (&hash_pos[ 32]);
|
|
digest[3] = hex_to_uint64_t (&hash_pos[ 48]);
|
|
digest[4] = hex_to_uint64_t (&hash_pos[ 64]);
|
|
digest[5] = hex_to_uint64_t (&hash_pos[ 80]);
|
|
digest[6] = hex_to_uint64_t (&hash_pos[ 96]);
|
|
digest[7] = hex_to_uint64_t (&hash_pos[112]);
|
|
|
|
uint salt_len = hash_pos - salt_pos - 1;
|
|
|
|
if ((salt_len % 2) != 0) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len / 2;
|
|
|
|
pbkdf2_sha512->salt_buf[0] = hex_to_uint (&salt_pos[ 0]);
|
|
pbkdf2_sha512->salt_buf[1] = hex_to_uint (&salt_pos[ 8]);
|
|
pbkdf2_sha512->salt_buf[2] = hex_to_uint (&salt_pos[16]);
|
|
pbkdf2_sha512->salt_buf[3] = hex_to_uint (&salt_pos[24]);
|
|
pbkdf2_sha512->salt_buf[4] = hex_to_uint (&salt_pos[32]);
|
|
pbkdf2_sha512->salt_buf[5] = hex_to_uint (&salt_pos[40]);
|
|
pbkdf2_sha512->salt_buf[6] = hex_to_uint (&salt_pos[48]);
|
|
pbkdf2_sha512->salt_buf[7] = hex_to_uint (&salt_pos[56]);
|
|
|
|
pbkdf2_sha512->salt_buf[0] = byte_swap_32 (pbkdf2_sha512->salt_buf[0]);
|
|
pbkdf2_sha512->salt_buf[1] = byte_swap_32 (pbkdf2_sha512->salt_buf[1]);
|
|
pbkdf2_sha512->salt_buf[2] = byte_swap_32 (pbkdf2_sha512->salt_buf[2]);
|
|
pbkdf2_sha512->salt_buf[3] = byte_swap_32 (pbkdf2_sha512->salt_buf[3]);
|
|
pbkdf2_sha512->salt_buf[4] = byte_swap_32 (pbkdf2_sha512->salt_buf[4]);
|
|
pbkdf2_sha512->salt_buf[5] = byte_swap_32 (pbkdf2_sha512->salt_buf[5]);
|
|
pbkdf2_sha512->salt_buf[6] = byte_swap_32 (pbkdf2_sha512->salt_buf[6]);
|
|
pbkdf2_sha512->salt_buf[7] = byte_swap_32 (pbkdf2_sha512->salt_buf[7]);
|
|
pbkdf2_sha512->salt_buf[8] = 0x01000000;
|
|
pbkdf2_sha512->salt_buf[9] = 0x80;
|
|
|
|
salt->salt_buf[0] = pbkdf2_sha512->salt_buf[0];
|
|
|
|
salt->salt_iter = atoi (iter_pos) - 1;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int episerver4_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1441) || (input_len > DISPLAY_LEN_MAX_1441)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_EPISERVER4, input_buf, 14)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 14;
|
|
|
|
char *hash_pos = strchr (salt_pos, '*');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
hash_pos++;
|
|
|
|
uint salt_len = hash_pos - salt_pos - 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char tmp_buf[100]; memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (base64_to_int, hash_pos, 43, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 32);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
digest[5] = byte_swap_32 (digest[5]);
|
|
digest[6] = byte_swap_32 (digest[6]);
|
|
digest[7] = byte_swap_32 (digest[7]);
|
|
|
|
digest[0] -= SHA256M_A;
|
|
digest[1] -= SHA256M_B;
|
|
digest[2] -= SHA256M_C;
|
|
digest[3] -= SHA256M_D;
|
|
digest[4] -= SHA256M_E;
|
|
digest[5] -= SHA256M_F;
|
|
digest[6] -= SHA256M_G;
|
|
digest[7] -= SHA256M_H;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha512grub_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
uint max_len = DISPLAY_LEN_MAX_7200 + (8 * 128);
|
|
|
|
if ((input_len < DISPLAY_LEN_MIN_7200) || (input_len > max_len)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SHA512GRUB, input_buf, 19)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pbkdf2_sha512_t *pbkdf2_sha512 = (pbkdf2_sha512_t *) hash_buf->esalt;
|
|
|
|
char *iter_pos = input_buf + 19;
|
|
|
|
char *salt_pos = strchr (iter_pos, '.');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, '.');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
if (((input_len - (hash_pos - input_buf) - 1) % 128) != 0) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
digest[0] = hex_to_uint64_t (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint64_t (&hash_pos[ 16]);
|
|
digest[2] = hex_to_uint64_t (&hash_pos[ 32]);
|
|
digest[3] = hex_to_uint64_t (&hash_pos[ 48]);
|
|
digest[4] = hex_to_uint64_t (&hash_pos[ 64]);
|
|
digest[5] = hex_to_uint64_t (&hash_pos[ 80]);
|
|
digest[6] = hex_to_uint64_t (&hash_pos[ 96]);
|
|
digest[7] = hex_to_uint64_t (&hash_pos[112]);
|
|
|
|
uint salt_len = hash_pos - salt_pos - 1;
|
|
|
|
salt_len /= 2;
|
|
|
|
char *salt_buf_ptr = (char *) pbkdf2_sha512->salt_buf;
|
|
|
|
uint i;
|
|
|
|
for (i = 0; i < salt_len; i++)
|
|
{
|
|
salt_buf_ptr[i] = hex_to_char (&salt_pos[i * 2]);
|
|
}
|
|
|
|
salt_buf_ptr[salt_len + 3] = 0x01;
|
|
salt_buf_ptr[salt_len + 4] = 0x80;
|
|
|
|
salt->salt_buf[0] = pbkdf2_sha512->salt_buf[0];
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
salt->salt_iter = atoi (iter_pos) - 1;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sha512b64s_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1711) || (input_len > DISPLAY_LEN_MAX_1711)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SHA512B64S, input_buf, 9)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char tmp_buf[120];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
int tmp_len = base64_decode (base64_to_int, input_buf + 9, input_len - 9, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 64);
|
|
|
|
digest[0] = byte_swap_64 (digest[0]);
|
|
digest[1] = byte_swap_64 (digest[1]);
|
|
digest[2] = byte_swap_64 (digest[2]);
|
|
digest[3] = byte_swap_64 (digest[3]);
|
|
digest[4] = byte_swap_64 (digest[4]);
|
|
digest[5] = byte_swap_64 (digest[5]);
|
|
digest[6] = byte_swap_64 (digest[6]);
|
|
digest[7] = byte_swap_64 (digest[7]);
|
|
|
|
digest[0] -= SHA512M_A;
|
|
digest[1] -= SHA512M_B;
|
|
digest[2] -= SHA512M_C;
|
|
digest[3] -= SHA512M_D;
|
|
digest[4] -= SHA512M_E;
|
|
digest[5] -= SHA512M_F;
|
|
digest[6] -= SHA512M_G;
|
|
digest[7] -= SHA512M_H;
|
|
|
|
salt->salt_len = tmp_len - 64;
|
|
|
|
memcpy (salt->salt_buf, tmp_buf + 64, salt->salt_len);
|
|
|
|
if (data.opts_type & OPTS_TYPE_ST_ADD80)
|
|
{
|
|
char *ptr = (char *) salt->salt_buf;
|
|
|
|
ptr[salt->salt_len] = 0x80;
|
|
}
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int hmacmd5_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_50H) || (input_len > DISPLAY_LEN_MAX_50H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_50) || (input_len > DISPLAY_LEN_MAX_50)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int hmacsha1_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_150H) || (input_len > DISPLAY_LEN_MAX_150H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_150) || (input_len > DISPLAY_LEN_MAX_150)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&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;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int hmacsha256_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_1450H) || (input_len > DISPLAY_LEN_MAX_1450H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1450) || (input_len > DISPLAY_LEN_MAX_1450)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
digest[5] = hex_to_uint (&input_buf[40]);
|
|
digest[6] = hex_to_uint (&input_buf[48]);
|
|
digest[7] = hex_to_uint (&input_buf[56]);
|
|
|
|
if (input_buf[64] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 64 - 1;
|
|
|
|
char *salt_buf = input_buf + 64 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int hmacsha512_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_1750H) || (input_len > DISPLAY_LEN_MAX_1750H)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
else
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1750) || (input_len > DISPLAY_LEN_MAX_1750)) return (PARSER_GLOBAL_LENGTH);
|
|
}
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint64_t (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint64_t (&input_buf[ 16]);
|
|
digest[2] = hex_to_uint64_t (&input_buf[ 32]);
|
|
digest[3] = hex_to_uint64_t (&input_buf[ 48]);
|
|
digest[4] = hex_to_uint64_t (&input_buf[ 64]);
|
|
digest[5] = hex_to_uint64_t (&input_buf[ 80]);
|
|
digest[6] = hex_to_uint64_t (&input_buf[ 96]);
|
|
digest[7] = hex_to_uint64_t (&input_buf[112]);
|
|
|
|
if (input_buf[128] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 128 - 1;
|
|
|
|
char *salt_buf = input_buf + 128 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int krb5pa_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_7500) || (input_len > DISPLAY_LEN_MAX_7500)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_KRB5PA, input_buf, 10)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
krb5pa_t *krb5pa = (krb5pa_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *user_pos = input_buf + 10 + 1;
|
|
|
|
char *realm_pos = strchr (user_pos, '$');
|
|
|
|
if (realm_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint user_len = realm_pos - user_pos;
|
|
|
|
if (user_len >= 64) return (PARSER_SALT_LENGTH);
|
|
|
|
realm_pos++;
|
|
|
|
char *salt_pos = strchr (realm_pos, '$');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint realm_len = salt_pos - realm_pos;
|
|
|
|
if (realm_len >= 64) return (PARSER_SALT_LENGTH);
|
|
|
|
salt_pos++;
|
|
|
|
char *data_pos = strchr (salt_pos, '$');
|
|
|
|
if (data_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = data_pos - salt_pos;
|
|
|
|
if (salt_len >= 128) return (PARSER_SALT_LENGTH);
|
|
|
|
data_pos++;
|
|
|
|
uint data_len = input_len - 10 - 1 - user_len - 1 - realm_len - 1 - salt_len - 1;
|
|
|
|
if (data_len != ((36 + 16) * 2)) return (PARSER_SALT_LENGTH);
|
|
|
|
/**
|
|
* copy data
|
|
*/
|
|
|
|
memcpy (krb5pa->user, user_pos, user_len);
|
|
memcpy (krb5pa->realm, realm_pos, realm_len);
|
|
memcpy (krb5pa->salt, salt_pos, salt_len);
|
|
|
|
char *timestamp_ptr = (char *) krb5pa->timestamp;
|
|
|
|
for (uint i = 0; i < (36 * 2); i += 2)
|
|
{
|
|
const char p0 = data_pos[i + 0];
|
|
const char p1 = data_pos[i + 1];
|
|
|
|
*timestamp_ptr++ = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
char *checksum_ptr = (char *) krb5pa->checksum;
|
|
|
|
for (uint i = (36 * 2); i < ((36 + 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;
|
|
}
|
|
|
|
/**
|
|
* copy some data to generic buffers to make sorting happy
|
|
*/
|
|
|
|
salt->salt_buf[0] = krb5pa->timestamp[0];
|
|
salt->salt_buf[1] = krb5pa->timestamp[1];
|
|
salt->salt_buf[2] = krb5pa->timestamp[2];
|
|
salt->salt_buf[3] = krb5pa->timestamp[3];
|
|
salt->salt_buf[4] = krb5pa->timestamp[4];
|
|
salt->salt_buf[5] = krb5pa->timestamp[5];
|
|
salt->salt_buf[6] = krb5pa->timestamp[6];
|
|
salt->salt_buf[7] = krb5pa->timestamp[7];
|
|
salt->salt_buf[8] = krb5pa->timestamp[8];
|
|
|
|
salt->salt_len = 36;
|
|
|
|
digest[0] = krb5pa->checksum[0];
|
|
digest[1] = krb5pa->checksum[1];
|
|
digest[2] = krb5pa->checksum[2];
|
|
digest[3] = krb5pa->checksum[3];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sapb_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_7700) || (input_len > DISPLAY_LEN_MAX_7700)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *salt_pos = input_buf;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len >= 40) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
uint hash_len = input_len - 1 - salt_len;
|
|
|
|
if (hash_len != 16) return (PARSER_HASH_LENGTH);
|
|
|
|
/**
|
|
* valid some data
|
|
*/
|
|
|
|
uint user_len = 0;
|
|
|
|
for (uint i = 0; i < salt_len; i++)
|
|
{
|
|
if (salt_pos[i] == ' ') continue;
|
|
|
|
user_len++;
|
|
}
|
|
|
|
// SAP user names cannot be longer than 12 characters
|
|
if (user_len > 12) return (PARSER_SALT_LENGTH);
|
|
|
|
// SAP user name cannot start with ! or ?
|
|
if (salt_pos[0] == '!' || salt_pos[0] == '?') return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* copy data
|
|
*/
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[0]);
|
|
digest[1] = hex_to_uint (&hash_pos[8]);
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sapg_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_7800) || (input_len > DISPLAY_LEN_MAX_7800)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *salt_pos = input_buf;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len >= 40) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
uint hash_len = input_len - 1 - salt_len;
|
|
|
|
if (hash_len != 40) return (PARSER_HASH_LENGTH);
|
|
|
|
/**
|
|
* valid some data
|
|
*/
|
|
|
|
uint user_len = 0;
|
|
|
|
for (uint i = 0; i < salt_len; i++)
|
|
{
|
|
if (salt_pos[i] == ' ') continue;
|
|
|
|
user_len++;
|
|
}
|
|
|
|
// SAP user names cannot be longer than 12 characters
|
|
if (user_len > 12) return (PARSER_SALT_LENGTH);
|
|
|
|
// SAP user name cannot start with ! or ?
|
|
if (salt_pos[0] == '!' || salt_pos[0] == '?') return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* copy data
|
|
*/
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_pos[32]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int drupal7_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_7900) || (input_len > DISPLAY_LEN_MAX_7900)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_DRUPAL7, input_buf, 3)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *iter_pos = input_buf + 3;
|
|
|
|
uint salt_iter = 1 << itoa64_to_int (iter_pos[0]);
|
|
|
|
if (salt_iter > 0x80000000) return (PARSER_SALT_ITERATION);
|
|
|
|
memcpy ((char *) salt->salt_sign, input_buf, 4);
|
|
|
|
salt->salt_iter = salt_iter;
|
|
|
|
char *salt_pos = iter_pos + 1;
|
|
|
|
uint salt_len = 8;
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char *hash_pos = salt_pos + salt_len;
|
|
|
|
drupal7_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
// ugly hack start
|
|
|
|
char *tmp = (char *) salt->salt_buf_pc;
|
|
|
|
tmp[0] = hash_pos[42];
|
|
|
|
// ugly hack end
|
|
|
|
digest[ 0] = byte_swap_64 (digest[ 0]);
|
|
digest[ 1] = byte_swap_64 (digest[ 1]);
|
|
digest[ 2] = byte_swap_64 (digest[ 2]);
|
|
digest[ 3] = byte_swap_64 (digest[ 3]);
|
|
digest[ 4] = 0;
|
|
digest[ 5] = 0;
|
|
digest[ 6] = 0;
|
|
digest[ 7] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sybasease_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_8000) || (input_len > DISPLAY_LEN_MAX_8000)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SYBASEASE, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_buf = input_buf + 6;
|
|
|
|
uint salt_len = 16;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
char *hash_pos = input_buf + 6 + 16;
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_pos[32]);
|
|
digest[5] = hex_to_uint (&hash_pos[40]);
|
|
digest[6] = hex_to_uint (&hash_pos[48]);
|
|
digest[7] = hex_to_uint (&hash_pos[56]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int mysql323_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_200) || (input_len > DISPLAY_LEN_MAX_200)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int rakp_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_7300) || (input_len > DISPLAY_LEN_MAX_7300)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
rakp_t *rakp = (rakp_t *) hash_buf->esalt;
|
|
|
|
char *saltbuf_pos = input_buf;
|
|
|
|
char *hashbuf_pos = strchr (saltbuf_pos, ':');
|
|
|
|
if (hashbuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint saltbuf_len = hashbuf_pos - saltbuf_pos;
|
|
|
|
if (saltbuf_len < 64) return (PARSER_SALT_LENGTH);
|
|
if (saltbuf_len > 512) return (PARSER_SALT_LENGTH);
|
|
|
|
if (saltbuf_len & 1) return (PARSER_SALT_LENGTH); // muss gerade sein wegen hex
|
|
|
|
hashbuf_pos++;
|
|
|
|
uint hashbuf_len = input_len - saltbuf_len - 1;
|
|
|
|
if (hashbuf_len != 40) return (PARSER_HASH_LENGTH);
|
|
|
|
char *salt_ptr = (char *) saltbuf_pos;
|
|
char *rakp_ptr = (char *) rakp->salt_buf;
|
|
|
|
uint i;
|
|
uint j;
|
|
|
|
for (i = 0, j = 0; i < saltbuf_len; i += 2, j += 1)
|
|
{
|
|
rakp_ptr[j] = hex_to_char (&salt_ptr[i]);
|
|
}
|
|
|
|
rakp_ptr[j] = 0x80;
|
|
|
|
rakp->salt_len = j;
|
|
|
|
for (i = 0; i < 64; i++)
|
|
{
|
|
rakp->salt_buf[i] = byte_swap_32 (rakp->salt_buf[i]);
|
|
}
|
|
|
|
salt->salt_buf[0] = rakp->salt_buf[0];
|
|
salt->salt_buf[1] = rakp->salt_buf[1];
|
|
salt->salt_buf[2] = rakp->salt_buf[2];
|
|
salt->salt_buf[3] = rakp->salt_buf[3];
|
|
salt->salt_buf[4] = rakp->salt_buf[4];
|
|
salt->salt_buf[5] = rakp->salt_buf[5];
|
|
salt->salt_buf[6] = rakp->salt_buf[6];
|
|
salt->salt_buf[7] = rakp->salt_buf[7];
|
|
|
|
salt->salt_len = 32; // muss min. 32 haben
|
|
|
|
digest[0] = hex_to_uint (&hashbuf_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hashbuf_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hashbuf_pos[16]);
|
|
digest[3] = hex_to_uint (&hashbuf_pos[24]);
|
|
digest[4] = hex_to_uint (&hashbuf_pos[32]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int netscaler_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_8100) || (input_len > DISPLAY_LEN_MAX_8100)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
if (memcmp (SIGNATURE_NETSCALER, input_buf, 1)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
char *salt_pos = input_buf + 1;
|
|
|
|
memcpy (salt->salt_buf, salt_pos, 8);
|
|
|
|
salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]);
|
|
salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]);
|
|
|
|
salt->salt_len = 8;
|
|
|
|
char *hash_pos = salt_pos + 8;
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_pos[32]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int chap_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_4800) || (input_len > DISPLAY_LEN_MAX_4800)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
char *salt_buf_ptr = input_buf + 32 + 1;
|
|
|
|
uint32_t *salt_buf = salt->salt_buf;
|
|
|
|
salt_buf[0] = hex_to_uint (&salt_buf_ptr[ 0]);
|
|
salt_buf[1] = hex_to_uint (&salt_buf_ptr[ 8]);
|
|
salt_buf[2] = hex_to_uint (&salt_buf_ptr[16]);
|
|
salt_buf[3] = hex_to_uint (&salt_buf_ptr[24]);
|
|
|
|
salt_buf[0] = byte_swap_32 (salt_buf[0]);
|
|
salt_buf[1] = byte_swap_32 (salt_buf[1]);
|
|
salt_buf[2] = byte_swap_32 (salt_buf[2]);
|
|
salt_buf[3] = byte_swap_32 (salt_buf[3]);
|
|
|
|
salt->salt_len = 16 + 1;
|
|
|
|
if (input_buf[65] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
char *idbyte_buf_ptr = input_buf + 32 + 1 + 32 + 1;
|
|
|
|
salt_buf[4] = hex_to_char (&idbyte_buf_ptr[0]) & 0xff;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int cloudkey_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_8200) || (input_len > DISPLAY_LEN_MAX_8200)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
cloudkey_t *cloudkey = (cloudkey_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *hashbuf_pos = input_buf;
|
|
|
|
char *saltbuf_pos = strchr (hashbuf_pos, ':');
|
|
|
|
if (saltbuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
const uint hashbuf_len = saltbuf_pos - hashbuf_pos;
|
|
|
|
if (hashbuf_len != 64) return (PARSER_HASH_LENGTH);
|
|
|
|
saltbuf_pos++;
|
|
|
|
char *iteration_pos = strchr (saltbuf_pos, ':');
|
|
|
|
if (iteration_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
const uint saltbuf_len = iteration_pos - saltbuf_pos;
|
|
|
|
if (saltbuf_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
iteration_pos++;
|
|
|
|
char *databuf_pos = strchr (iteration_pos, ':');
|
|
|
|
if (databuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
const uint iteration_len = databuf_pos - iteration_pos;
|
|
|
|
if (iteration_len < 1) return (PARSER_SALT_ITERATION);
|
|
if (iteration_len > 8) return (PARSER_SALT_ITERATION);
|
|
|
|
const uint databuf_len = input_len - hashbuf_len - 1 - saltbuf_len - 1 - iteration_len - 1;
|
|
|
|
if (databuf_len < 1) return (PARSER_SALT_LENGTH);
|
|
if (databuf_len > 2048) return (PARSER_SALT_LENGTH);
|
|
|
|
databuf_pos++;
|
|
|
|
// digest
|
|
|
|
digest[0] = hex_to_uint (&hashbuf_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hashbuf_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hashbuf_pos[16]);
|
|
digest[3] = hex_to_uint (&hashbuf_pos[24]);
|
|
digest[4] = hex_to_uint (&hashbuf_pos[32]);
|
|
digest[5] = hex_to_uint (&hashbuf_pos[40]);
|
|
digest[6] = hex_to_uint (&hashbuf_pos[48]);
|
|
digest[7] = hex_to_uint (&hashbuf_pos[56]);
|
|
|
|
// salt
|
|
|
|
char *saltbuf_ptr = (char *) salt->salt_buf;
|
|
|
|
for (uint i = 0; i < saltbuf_len; i += 2)
|
|
{
|
|
const char p0 = saltbuf_pos[i + 0];
|
|
const char p1 = saltbuf_pos[i + 1];
|
|
|
|
*saltbuf_ptr++ = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
salt->salt_buf[4] = 0x01000000;
|
|
salt->salt_buf[5] = 0x80;
|
|
|
|
salt->salt_len = saltbuf_len / 2;
|
|
|
|
// iteration
|
|
|
|
salt->salt_iter = atoi (iteration_pos) - 1;
|
|
|
|
// data
|
|
|
|
char *databuf_ptr = (char *) cloudkey->data_buf;
|
|
|
|
for (uint i = 0; i < databuf_len; i += 2)
|
|
{
|
|
const char p0 = databuf_pos[i + 0];
|
|
const char p1 = databuf_pos[i + 1];
|
|
|
|
*databuf_ptr++ = hex_convert (p1) << 0
|
|
| hex_convert (p0) << 4;
|
|
}
|
|
|
|
*databuf_ptr++ = 0x80;
|
|
|
|
for (uint i = 0; i < 512; i++)
|
|
{
|
|
cloudkey->data_buf[i] = byte_swap_32 (cloudkey->data_buf[i]);
|
|
}
|
|
|
|
cloudkey->data_len = databuf_len / 2;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int nsec3_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_8300) || (input_len > DISPLAY_LEN_MAX_8300)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *hashbuf_pos = input_buf;
|
|
|
|
char *domainbuf_pos = strchr (hashbuf_pos, ':');
|
|
|
|
if (domainbuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
const uint hashbuf_len = domainbuf_pos - hashbuf_pos;
|
|
|
|
if (hashbuf_len != 32) return (PARSER_HASH_LENGTH);
|
|
|
|
domainbuf_pos++;
|
|
|
|
if (domainbuf_pos[0] != '.') return (PARSER_SALT_VALUE);
|
|
|
|
char *saltbuf_pos = strchr (domainbuf_pos, ':');
|
|
|
|
if (saltbuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
const uint domainbuf_len = saltbuf_pos - domainbuf_pos;
|
|
|
|
if (domainbuf_len >= 32) return (PARSER_SALT_LENGTH);
|
|
|
|
saltbuf_pos++;
|
|
|
|
char *iteration_pos = strchr (saltbuf_pos, ':');
|
|
|
|
if (iteration_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
const uint saltbuf_len = iteration_pos - saltbuf_pos;
|
|
|
|
if (saltbuf_len >= 28) return (PARSER_SALT_LENGTH); // 28 = 32 - 4; 4 = length
|
|
|
|
if ((domainbuf_len + saltbuf_len) >= 48) return (PARSER_SALT_LENGTH);
|
|
|
|
iteration_pos++;
|
|
|
|
const uint iteration_len = input_len - hashbuf_len - 1 - domainbuf_len - 1 - saltbuf_len - 1;
|
|
|
|
if (iteration_len < 1) return (PARSER_SALT_ITERATION);
|
|
if (iteration_len > 5) return (PARSER_SALT_ITERATION);
|
|
|
|
// ok, the plan for this algorithm is the following:
|
|
// we have 2 salts here, the domain-name and a random salt
|
|
// while both are used in the initial transformation,
|
|
// only the random salt is used in the following iterations
|
|
// so we create two buffer, one that includes domain-name (stored into salt_buf_pc[])
|
|
// and one that includes only the real salt (stored into salt_buf[]).
|
|
// the domain-name length is put into array position 7 of salt_buf_pc[] since there is not salt_pc_len
|
|
|
|
char tmp_buf[100]; memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base32_decode (itoa32_to_int, hashbuf_pos, 32, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 20);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
|
|
// domain
|
|
|
|
char *salt_buf_pc_ptr = (char *) salt->salt_buf_pc;
|
|
|
|
memcpy (salt_buf_pc_ptr, domainbuf_pos, domainbuf_len);
|
|
|
|
char *len_ptr = NULL;
|
|
|
|
for (uint i = 0; i < domainbuf_len; i++)
|
|
{
|
|
if (salt_buf_pc_ptr[i] == '.')
|
|
{
|
|
len_ptr = &salt_buf_pc_ptr[i];
|
|
|
|
*len_ptr = 0;
|
|
}
|
|
else
|
|
{
|
|
*len_ptr += 1;
|
|
}
|
|
}
|
|
|
|
salt->salt_buf_pc[7] = domainbuf_len;
|
|
|
|
// "real" salt
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
const uint salt_len = parse_and_store_salt (salt_buf_ptr, saltbuf_pos, saltbuf_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
// iteration
|
|
|
|
salt->salt_iter = atoi (iteration_pos);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int wbb3_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_8400) || (input_len > DISPLAY_LEN_MAX_8400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&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;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int racf_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
const uint8_t ascii_to_ebcdic[] =
|
|
{
|
|
0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, 0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
|
0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
|
|
0x40, 0x4f, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
|
|
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
|
|
0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
|
|
0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0x4a, 0xe0, 0x5a, 0x5f, 0x6d,
|
|
0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
|
|
0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xc0, 0x6a, 0xd0, 0xa1, 0x07,
|
|
0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
|
|
0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08, 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xe1,
|
|
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
|
|
0x58, 0x59, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
|
|
0x76, 0x77, 0x78, 0x80, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e,
|
|
0x9f, 0xa0, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
|
|
0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xda, 0xdb,
|
|
0xdc, 0xdd, 0xde, 0xdf, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
|
|
};
|
|
|
|
if ((input_len < DISPLAY_LEN_MIN_8500) || (input_len > DISPLAY_LEN_MAX_8500)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_RACF, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 6 + 1;
|
|
|
|
char *digest_pos = strchr (salt_pos, '*');
|
|
|
|
if (digest_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = digest_pos - salt_pos;
|
|
|
|
if (salt_len > 8) return (PARSER_SALT_LENGTH);
|
|
|
|
uint hash_len = input_len - 1 - salt_len - 1 - 6;
|
|
|
|
if (hash_len != 16) return (PARSER_HASH_LENGTH);
|
|
|
|
digest_pos++;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
char *salt_buf_pc_ptr = (char *) salt->salt_buf_pc;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
for (uint i = 0; i < salt_len; i++)
|
|
{
|
|
salt_buf_pc_ptr[i] = ascii_to_ebcdic[(int) salt_buf_ptr[i]];
|
|
}
|
|
for (uint i = salt_len; i < 8; i++)
|
|
{
|
|
salt_buf_pc_ptr[i] = 0x40;
|
|
}
|
|
|
|
uint tt;
|
|
|
|
IP (salt->salt_buf_pc[0], salt->salt_buf_pc[1], tt);
|
|
|
|
salt->salt_buf_pc[0] = ROTATE_LEFT (salt->salt_buf_pc[0], 3u);
|
|
salt->salt_buf_pc[1] = ROTATE_LEFT (salt->salt_buf_pc[1], 3u);
|
|
|
|
digest[0] = hex_to_uint (&digest_pos[ 0]);
|
|
digest[1] = hex_to_uint (&digest_pos[ 8]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
|
|
IP (digest[0], digest[1], tt);
|
|
|
|
digest[0] = ROTATE_RIGHT (digest[0], 29);
|
|
digest[1] = ROTATE_RIGHT (digest[1], 29);
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int lotus5_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_8600) || (input_len > DISPLAY_LEN_MAX_8600)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int lotus6_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_8700) || (input_len > DISPLAY_LEN_MAX_8700)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((input_buf[0] != '(') || (input_buf[1] != 'G') || (input_buf[21] != ')')) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char tmp_buf[120];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (lotus64_to_int, input_buf + 2, input_len - 3, tmp_buf);
|
|
|
|
tmp_buf[3] += -4; // dont ask!
|
|
|
|
memcpy (salt->salt_buf, tmp_buf, 5);
|
|
|
|
salt->salt_len = 5;
|
|
|
|
memcpy (digest, tmp_buf + 5, 9);
|
|
|
|
// yes, only 9 byte are needed to crack, but 10 to display
|
|
|
|
salt->salt_buf_pc[7] = input_buf[20];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int lotus8_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9100) || (input_len > DISPLAY_LEN_MAX_9100)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((input_buf[0] != '(') || (input_buf[1] != 'H') || (input_buf[DISPLAY_LEN_MAX_9100 - 1] != ')')) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char tmp_buf[120];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (lotus64_to_int, input_buf + 2, input_len - 3, tmp_buf);
|
|
|
|
tmp_buf[3] += -4; // dont ask!
|
|
|
|
// salt
|
|
|
|
memcpy (salt->salt_buf, tmp_buf, 16);
|
|
|
|
salt->salt_len = 16; // Attention: in theory we have 2 salt_len, one for the -m 8700 part (len: 8), 2nd for the 9100 part (len: 16)
|
|
|
|
// iteration
|
|
|
|
char tmp_iter_buf[11];
|
|
|
|
memcpy (tmp_iter_buf, tmp_buf + 16, 10);
|
|
|
|
tmp_iter_buf[10] = 0;
|
|
|
|
salt->salt_iter = atoi (tmp_iter_buf);
|
|
|
|
if (salt->salt_iter < 1) // well, the limit hopefully is much higher
|
|
{
|
|
return (PARSER_SALT_ITERATION);
|
|
}
|
|
|
|
salt->salt_iter--; // first round in init
|
|
|
|
// 2 additional bytes for display only
|
|
|
|
salt->salt_buf_pc[0] = tmp_buf[26];
|
|
salt->salt_buf_pc[1] = tmp_buf[27];
|
|
|
|
// digest
|
|
|
|
memcpy (digest, tmp_buf + 28, 8);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int hmailserver_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_1421) || (input_len > DISPLAY_LEN_MAX_1421)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_buf_pos = input_buf;
|
|
|
|
char *hash_buf_pos = salt_buf_pos + 6;
|
|
|
|
digest[0] = hex_to_uint (&hash_buf_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_buf_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_buf_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_buf_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_buf_pos[32]);
|
|
digest[5] = hex_to_uint (&hash_buf_pos[40]);
|
|
digest[6] = hex_to_uint (&hash_buf_pos[48]);
|
|
digest[7] = hex_to_uint (&hash_buf_pos[56]);
|
|
|
|
digest[0] -= SHA256M_A;
|
|
digest[1] -= SHA256M_B;
|
|
digest[2] -= SHA256M_C;
|
|
digest[3] -= SHA256M_D;
|
|
digest[4] -= SHA256M_E;
|
|
digest[5] -= SHA256M_F;
|
|
digest[6] -= SHA256M_G;
|
|
digest[7] -= SHA256M_H;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
const uint salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf_pos, 6);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int phps_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_2612) || (input_len > DISPLAY_LEN_MAX_2612)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
if (memcmp (SIGNATURE_PHPS, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_buf = input_buf + 6;
|
|
|
|
char *digest_buf = strchr (salt_buf, '$');
|
|
|
|
if (digest_buf == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = digest_buf - salt_buf;
|
|
|
|
digest_buf++; // skip the '$' symbol
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
digest[0] = hex_to_uint (&digest_buf[ 0]);
|
|
digest[1] = hex_to_uint (&digest_buf[ 8]);
|
|
digest[2] = hex_to_uint (&digest_buf[16]);
|
|
digest[3] = hex_to_uint (&digest_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int mediawiki_b_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_3711) || (input_len > DISPLAY_LEN_MAX_3711)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_MEDIAWIKI_B, input_buf, 3)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_buf = input_buf + 3;
|
|
|
|
char *digest_buf = strchr (salt_buf, '$');
|
|
|
|
if (digest_buf == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = digest_buf - salt_buf;
|
|
|
|
digest_buf++; // skip the '$' symbol
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt_buf_ptr[salt_len] = 0x2d;
|
|
|
|
salt->salt_len = salt_len + 1;
|
|
|
|
digest[0] = hex_to_uint (&digest_buf[ 0]);
|
|
digest[1] = hex_to_uint (&digest_buf[ 8]);
|
|
digest[2] = hex_to_uint (&digest_buf[16]);
|
|
digest[3] = hex_to_uint (&digest_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int peoplesoft_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_133) || (input_len > DISPLAY_LEN_MAX_133)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (base64_to_int, input_buf, input_len, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 20);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int skype_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_23) || (input_len > DISPLAY_LEN_MAX_23)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
if (input_buf[32] != ':') return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
/*
|
|
* add static "salt" part
|
|
*/
|
|
|
|
memcpy (salt_buf_ptr + salt_len, "\nskyper\n", 8);
|
|
|
|
salt_len += 8;
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int androidfde_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_8800) || (input_len > DISPLAY_LEN_MAX_8800)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_ANDROIDFDE, input_buf, 5)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
androidfde_t *androidfde = (androidfde_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *saltlen_pos = input_buf + 1 + 3 + 1;
|
|
|
|
char *saltbuf_pos = strchr (saltlen_pos, '$');
|
|
|
|
if (saltbuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint saltlen_len = saltbuf_pos - saltlen_pos;
|
|
|
|
if (saltlen_len != 2) return (PARSER_SALT_LENGTH);
|
|
|
|
saltbuf_pos++;
|
|
|
|
char *keylen_pos = strchr (saltbuf_pos, '$');
|
|
|
|
if (keylen_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint saltbuf_len = keylen_pos - saltbuf_pos;
|
|
|
|
if (saltbuf_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
keylen_pos++;
|
|
|
|
char *keybuf_pos = strchr (keylen_pos, '$');
|
|
|
|
if (keybuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint keylen_len = keybuf_pos - keylen_pos;
|
|
|
|
if (keylen_len != 2) return (PARSER_SALT_LENGTH);
|
|
|
|
keybuf_pos++;
|
|
|
|
char *databuf_pos = strchr (keybuf_pos, '$');
|
|
|
|
if (databuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint keybuf_len = databuf_pos - keybuf_pos;
|
|
|
|
if (keybuf_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
databuf_pos++;
|
|
|
|
uint data_len = input_len - 1 - 3 - 1 - saltlen_len - 1 - saltbuf_len - 1 - keylen_len - 1 - keybuf_len - 1;
|
|
|
|
if (data_len != 3072) return (PARSER_SALT_LENGTH);
|
|
|
|
/**
|
|
* copy data
|
|
*/
|
|
|
|
digest[0] = hex_to_uint (&keybuf_pos[ 0]);
|
|
digest[1] = hex_to_uint (&keybuf_pos[ 8]);
|
|
digest[2] = hex_to_uint (&keybuf_pos[16]);
|
|
digest[3] = hex_to_uint (&keybuf_pos[24]);
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&saltbuf_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&saltbuf_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&saltbuf_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&saltbuf_pos[24]);
|
|
|
|
salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]);
|
|
salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]);
|
|
salt->salt_buf[2] = byte_swap_32 (salt->salt_buf[2]);
|
|
salt->salt_buf[3] = byte_swap_32 (salt->salt_buf[3]);
|
|
|
|
salt->salt_len = 16;
|
|
salt->salt_iter = ROUNDS_ANDROIDFDE - 1;
|
|
|
|
for (uint i = 0, j = 0; i < 3072; i += 8, j += 1)
|
|
{
|
|
androidfde->data[j] = hex_to_uint (&databuf_pos[i]);
|
|
}
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int scrypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_8900) || (input_len > DISPLAY_LEN_MAX_8900)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SCRYPT, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
// first is the N salt parameter
|
|
|
|
char *N_pos = input_buf + 6;
|
|
|
|
if (N_pos[0] != ':') return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
N_pos++;
|
|
|
|
salt->scrypt_N = atoi (N_pos);
|
|
|
|
// r
|
|
|
|
char *r_pos = strchr (N_pos, ':');
|
|
|
|
if (r_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
r_pos++;
|
|
|
|
salt->scrypt_r = atoi (r_pos);
|
|
|
|
// p
|
|
|
|
char *p_pos = strchr (r_pos, ':');
|
|
|
|
if (p_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
p_pos++;
|
|
|
|
salt->scrypt_p = atoi (p_pos);
|
|
|
|
// salt
|
|
|
|
char *saltbuf_pos = strchr (p_pos, ':');
|
|
|
|
if (saltbuf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
saltbuf_pos++;
|
|
|
|
char *hash_pos = strchr (saltbuf_pos, ':');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
hash_pos++;
|
|
|
|
// base64 decode
|
|
|
|
char tmp_buf[32];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
int tmp_len = base64_decode (base64_to_int, saltbuf_pos, hash_pos - saltbuf_pos, tmp_buf);
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
memcpy (salt_buf_ptr, tmp_buf, tmp_len);
|
|
|
|
salt->salt_len = tmp_len;
|
|
salt->salt_iter = 1;
|
|
|
|
// digest - base64 decode
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
tmp_len = input_len - (hash_pos - input_buf);
|
|
|
|
if (tmp_len != 44) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
base64_decode (base64_to_int, hash_pos, tmp_len, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 32);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int juniper_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_501) || (input_len > DISPLAY_LEN_MAX_501)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char decrypted[76]; // iv + hash
|
|
|
|
juniper_decrypt_hash (input_buf, decrypted);
|
|
|
|
char *md5crypt_hash = decrypted + 12;
|
|
|
|
if (memcmp (md5crypt_hash, "$1$danastre$", 12)) return (PARSER_SALT_VALUE);
|
|
|
|
salt->salt_iter = ROUNDS_MD5CRYPT;
|
|
|
|
char *salt_pos = md5crypt_hash + 3;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$'); // or simply salt_pos + 8
|
|
|
|
salt->salt_len = hash_pos - salt_pos; // should be 8
|
|
|
|
memcpy ((char *) salt->salt_buf, salt_pos, salt->salt_len);
|
|
|
|
hash_pos++;
|
|
|
|
md5crypt_decode ((unsigned char *) digest, (unsigned char *) hash_pos);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int cisco8_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9200) || (input_len > DISPLAY_LEN_MAX_9200)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_CISCO8, input_buf, 3)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pbkdf2_sha256_t *pbkdf2_sha256 = (pbkdf2_sha256_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
// first is *raw* salt
|
|
|
|
char *salt_pos = input_buf + 3;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len != 14) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
char *salt_buf_ptr = (char *) pbkdf2_sha256->salt_buf;
|
|
|
|
memcpy (salt_buf_ptr, salt_pos, 14);
|
|
|
|
salt_buf_ptr[17] = 0x01;
|
|
salt_buf_ptr[18] = 0x80;
|
|
|
|
// add some stuff to normal salt to make sorted happy
|
|
|
|
salt->salt_buf[0] = pbkdf2_sha256->salt_buf[0];
|
|
salt->salt_buf[1] = pbkdf2_sha256->salt_buf[1];
|
|
salt->salt_buf[2] = pbkdf2_sha256->salt_buf[2];
|
|
salt->salt_buf[3] = pbkdf2_sha256->salt_buf[3];
|
|
|
|
salt->salt_len = salt_len;
|
|
salt->salt_iter = ROUNDS_CISCO8 - 1;
|
|
|
|
// base64 decode hash
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
uint hash_len = input_len - 3 - salt_len - 1;
|
|
|
|
int tmp_len = base64_decode (itoa64_to_int, hash_pos, hash_len, tmp_buf);
|
|
|
|
if (tmp_len != 32) return (PARSER_HASH_LENGTH);
|
|
|
|
memcpy (digest, tmp_buf, 32);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
digest[5] = byte_swap_32 (digest[5]);
|
|
digest[6] = byte_swap_32 (digest[6]);
|
|
digest[7] = byte_swap_32 (digest[7]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int cisco9_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9300) || (input_len > DISPLAY_LEN_MAX_9300)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_CISCO9, input_buf, 3)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
// first is *raw* salt
|
|
|
|
char *salt_pos = input_buf + 3;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len != 14) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
hash_pos++;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
memcpy (salt_buf_ptr, salt_pos, salt_len);
|
|
salt_buf_ptr[salt_len] = 0;
|
|
|
|
// base64 decode hash
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
uint hash_len = input_len - 3 - salt_len - 1;
|
|
|
|
int tmp_len = base64_decode (itoa64_to_int, hash_pos, hash_len, tmp_buf);
|
|
|
|
if (tmp_len != 32) return (PARSER_HASH_LENGTH);
|
|
|
|
memcpy (digest, tmp_buf, 32);
|
|
|
|
// fixed:
|
|
salt->scrypt_N = 16384;
|
|
salt->scrypt_r = 1;
|
|
salt->scrypt_p = 1;
|
|
salt->salt_iter = 1;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int office2007_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9400) || (input_len > DISPLAY_LEN_MAX_9400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_OFFICE2007, input_buf, 8)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
office2007_t *office2007 = (office2007_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *version_pos = input_buf + 8 + 1;
|
|
|
|
char *verifierHashSize_pos = strchr (version_pos, '*');
|
|
|
|
if (verifierHashSize_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t version_len = verifierHashSize_pos - version_pos;
|
|
|
|
if (version_len != 4) return (PARSER_SALT_LENGTH);
|
|
|
|
verifierHashSize_pos++;
|
|
|
|
char *keySize_pos = strchr (verifierHashSize_pos, '*');
|
|
|
|
if (keySize_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t verifierHashSize_len = keySize_pos - verifierHashSize_pos;
|
|
|
|
if (verifierHashSize_len != 2) return (PARSER_SALT_LENGTH);
|
|
|
|
keySize_pos++;
|
|
|
|
char *saltSize_pos = strchr (keySize_pos, '*');
|
|
|
|
if (saltSize_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t keySize_len = saltSize_pos - keySize_pos;
|
|
|
|
if (keySize_len != 3) return (PARSER_SALT_LENGTH);
|
|
|
|
saltSize_pos++;
|
|
|
|
char *osalt_pos = strchr (saltSize_pos, '*');
|
|
|
|
if (osalt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t saltSize_len = osalt_pos - saltSize_pos;
|
|
|
|
if (saltSize_len != 2) return (PARSER_SALT_LENGTH);
|
|
|
|
osalt_pos++;
|
|
|
|
char *encryptedVerifier_pos = strchr (osalt_pos, '*');
|
|
|
|
if (encryptedVerifier_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t osalt_len = encryptedVerifier_pos - osalt_pos;
|
|
|
|
if (osalt_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifier_pos++;
|
|
|
|
char *encryptedVerifierHash_pos = strchr (encryptedVerifier_pos, '*');
|
|
|
|
if (encryptedVerifierHash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t encryptedVerifier_len = encryptedVerifierHash_pos - encryptedVerifier_pos;
|
|
|
|
if (encryptedVerifier_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifierHash_pos++;
|
|
|
|
uint32_t encryptedVerifierHash_len = input_len - 8 - 1 - version_len - 1 - verifierHashSize_len - 1 - keySize_len - 1 - saltSize_len - 1 - osalt_len - 1 - encryptedVerifier_len - 1;
|
|
|
|
if (encryptedVerifierHash_len != 40) return (PARSER_SALT_LENGTH);
|
|
|
|
const uint version = atoi (version_pos);
|
|
|
|
if (version != 2007) return (PARSER_SALT_VALUE);
|
|
|
|
const uint verifierHashSize = atoi (verifierHashSize_pos);
|
|
|
|
if (verifierHashSize != 20) return (PARSER_SALT_VALUE);
|
|
|
|
const uint keySize = atoi (keySize_pos);
|
|
|
|
if ((keySize != 128) && (keySize != 256)) return (PARSER_SALT_VALUE);
|
|
|
|
office2007->keySize = keySize;
|
|
|
|
const uint saltSize = atoi (saltSize_pos);
|
|
|
|
if (saltSize != 16) return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* salt
|
|
*/
|
|
|
|
salt->salt_len = 16;
|
|
salt->salt_iter = ROUNDS_OFFICE2007;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&osalt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&osalt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&osalt_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&osalt_pos[24]);
|
|
|
|
/**
|
|
* esalt
|
|
*/
|
|
|
|
office2007->encryptedVerifier[0] = hex_to_uint (&encryptedVerifier_pos[ 0]);
|
|
office2007->encryptedVerifier[1] = hex_to_uint (&encryptedVerifier_pos[ 8]);
|
|
office2007->encryptedVerifier[2] = hex_to_uint (&encryptedVerifier_pos[16]);
|
|
office2007->encryptedVerifier[3] = hex_to_uint (&encryptedVerifier_pos[24]);
|
|
|
|
office2007->encryptedVerifierHash[0] = hex_to_uint (&encryptedVerifierHash_pos[ 0]);
|
|
office2007->encryptedVerifierHash[1] = hex_to_uint (&encryptedVerifierHash_pos[ 8]);
|
|
office2007->encryptedVerifierHash[2] = hex_to_uint (&encryptedVerifierHash_pos[16]);
|
|
office2007->encryptedVerifierHash[3] = hex_to_uint (&encryptedVerifierHash_pos[24]);
|
|
office2007->encryptedVerifierHash[4] = hex_to_uint (&encryptedVerifierHash_pos[32]);
|
|
|
|
/**
|
|
* digest
|
|
*/
|
|
|
|
digest[0] = office2007->encryptedVerifierHash[0];
|
|
digest[1] = office2007->encryptedVerifierHash[1];
|
|
digest[2] = office2007->encryptedVerifierHash[2];
|
|
digest[3] = office2007->encryptedVerifierHash[3];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int office2010_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9500) || (input_len > DISPLAY_LEN_MAX_9500)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_OFFICE2010, input_buf, 8)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
office2010_t *office2010 = (office2010_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *version_pos = input_buf + 8 + 1;
|
|
|
|
char *spinCount_pos = strchr (version_pos, '*');
|
|
|
|
if (spinCount_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t version_len = spinCount_pos - version_pos;
|
|
|
|
if (version_len != 4) return (PARSER_SALT_LENGTH);
|
|
|
|
spinCount_pos++;
|
|
|
|
char *keySize_pos = strchr (spinCount_pos, '*');
|
|
|
|
if (keySize_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t spinCount_len = keySize_pos - spinCount_pos;
|
|
|
|
if (spinCount_len != 6) return (PARSER_SALT_LENGTH);
|
|
|
|
keySize_pos++;
|
|
|
|
char *saltSize_pos = strchr (keySize_pos, '*');
|
|
|
|
if (saltSize_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t keySize_len = saltSize_pos - keySize_pos;
|
|
|
|
if (keySize_len != 3) return (PARSER_SALT_LENGTH);
|
|
|
|
saltSize_pos++;
|
|
|
|
char *osalt_pos = strchr (saltSize_pos, '*');
|
|
|
|
if (osalt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t saltSize_len = osalt_pos - saltSize_pos;
|
|
|
|
if (saltSize_len != 2) return (PARSER_SALT_LENGTH);
|
|
|
|
osalt_pos++;
|
|
|
|
char *encryptedVerifier_pos = strchr (osalt_pos, '*');
|
|
|
|
if (encryptedVerifier_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t osalt_len = encryptedVerifier_pos - osalt_pos;
|
|
|
|
if (osalt_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifier_pos++;
|
|
|
|
char *encryptedVerifierHash_pos = strchr (encryptedVerifier_pos, '*');
|
|
|
|
if (encryptedVerifierHash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t encryptedVerifier_len = encryptedVerifierHash_pos - encryptedVerifier_pos;
|
|
|
|
if (encryptedVerifier_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifierHash_pos++;
|
|
|
|
uint32_t encryptedVerifierHash_len = input_len - 8 - 1 - version_len - 1 - spinCount_len - 1 - keySize_len - 1 - saltSize_len - 1 - osalt_len - 1 - encryptedVerifier_len - 1;
|
|
|
|
if (encryptedVerifierHash_len != 64) return (PARSER_SALT_LENGTH);
|
|
|
|
const uint version = atoi (version_pos);
|
|
|
|
if (version != 2010) return (PARSER_SALT_VALUE);
|
|
|
|
const uint spinCount = atoi (spinCount_pos);
|
|
|
|
if (spinCount != 100000) return (PARSER_SALT_VALUE);
|
|
|
|
const uint keySize = atoi (keySize_pos);
|
|
|
|
if (keySize != 128) return (PARSER_SALT_VALUE);
|
|
|
|
const uint saltSize = atoi (saltSize_pos);
|
|
|
|
if (saltSize != 16) return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* salt
|
|
*/
|
|
|
|
salt->salt_len = 16;
|
|
salt->salt_iter = spinCount;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&osalt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&osalt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&osalt_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&osalt_pos[24]);
|
|
|
|
/**
|
|
* esalt
|
|
*/
|
|
|
|
office2010->encryptedVerifier[0] = hex_to_uint (&encryptedVerifier_pos[ 0]);
|
|
office2010->encryptedVerifier[1] = hex_to_uint (&encryptedVerifier_pos[ 8]);
|
|
office2010->encryptedVerifier[2] = hex_to_uint (&encryptedVerifier_pos[16]);
|
|
office2010->encryptedVerifier[3] = hex_to_uint (&encryptedVerifier_pos[24]);
|
|
|
|
office2010->encryptedVerifierHash[0] = hex_to_uint (&encryptedVerifierHash_pos[ 0]);
|
|
office2010->encryptedVerifierHash[1] = hex_to_uint (&encryptedVerifierHash_pos[ 8]);
|
|
office2010->encryptedVerifierHash[2] = hex_to_uint (&encryptedVerifierHash_pos[16]);
|
|
office2010->encryptedVerifierHash[3] = hex_to_uint (&encryptedVerifierHash_pos[24]);
|
|
office2010->encryptedVerifierHash[4] = hex_to_uint (&encryptedVerifierHash_pos[32]);
|
|
office2010->encryptedVerifierHash[5] = hex_to_uint (&encryptedVerifierHash_pos[40]);
|
|
office2010->encryptedVerifierHash[6] = hex_to_uint (&encryptedVerifierHash_pos[48]);
|
|
office2010->encryptedVerifierHash[7] = hex_to_uint (&encryptedVerifierHash_pos[56]);
|
|
|
|
/**
|
|
* digest
|
|
*/
|
|
|
|
digest[0] = office2010->encryptedVerifierHash[0];
|
|
digest[1] = office2010->encryptedVerifierHash[1];
|
|
digest[2] = office2010->encryptedVerifierHash[2];
|
|
digest[3] = office2010->encryptedVerifierHash[3];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int office2013_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9600) || (input_len > DISPLAY_LEN_MAX_9600)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_OFFICE2013, input_buf, 8)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
office2013_t *office2013 = (office2013_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *version_pos = input_buf + 8 + 1;
|
|
|
|
char *spinCount_pos = strchr (version_pos, '*');
|
|
|
|
if (spinCount_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t version_len = spinCount_pos - version_pos;
|
|
|
|
if (version_len != 4) return (PARSER_SALT_LENGTH);
|
|
|
|
spinCount_pos++;
|
|
|
|
char *keySize_pos = strchr (spinCount_pos, '*');
|
|
|
|
if (keySize_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t spinCount_len = keySize_pos - spinCount_pos;
|
|
|
|
if (spinCount_len != 6) return (PARSER_SALT_LENGTH);
|
|
|
|
keySize_pos++;
|
|
|
|
char *saltSize_pos = strchr (keySize_pos, '*');
|
|
|
|
if (saltSize_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t keySize_len = saltSize_pos - keySize_pos;
|
|
|
|
if (keySize_len != 3) return (PARSER_SALT_LENGTH);
|
|
|
|
saltSize_pos++;
|
|
|
|
char *osalt_pos = strchr (saltSize_pos, '*');
|
|
|
|
if (osalt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t saltSize_len = osalt_pos - saltSize_pos;
|
|
|
|
if (saltSize_len != 2) return (PARSER_SALT_LENGTH);
|
|
|
|
osalt_pos++;
|
|
|
|
char *encryptedVerifier_pos = strchr (osalt_pos, '*');
|
|
|
|
if (encryptedVerifier_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t osalt_len = encryptedVerifier_pos - osalt_pos;
|
|
|
|
if (osalt_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifier_pos++;
|
|
|
|
char *encryptedVerifierHash_pos = strchr (encryptedVerifier_pos, '*');
|
|
|
|
if (encryptedVerifierHash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t encryptedVerifier_len = encryptedVerifierHash_pos - encryptedVerifier_pos;
|
|
|
|
if (encryptedVerifier_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifierHash_pos++;
|
|
|
|
uint32_t encryptedVerifierHash_len = input_len - 8 - 1 - version_len - 1 - spinCount_len - 1 - keySize_len - 1 - saltSize_len - 1 - osalt_len - 1 - encryptedVerifier_len - 1;
|
|
|
|
if (encryptedVerifierHash_len != 64) return (PARSER_SALT_LENGTH);
|
|
|
|
const uint version = atoi (version_pos);
|
|
|
|
if (version != 2013) return (PARSER_SALT_VALUE);
|
|
|
|
const uint spinCount = atoi (spinCount_pos);
|
|
|
|
if (spinCount != 100000) return (PARSER_SALT_VALUE);
|
|
|
|
const uint keySize = atoi (keySize_pos);
|
|
|
|
if (keySize != 256) return (PARSER_SALT_VALUE);
|
|
|
|
const uint saltSize = atoi (saltSize_pos);
|
|
|
|
if (saltSize != 16) return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* salt
|
|
*/
|
|
|
|
salt->salt_len = 16;
|
|
salt->salt_iter = spinCount;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&osalt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&osalt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&osalt_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&osalt_pos[24]);
|
|
|
|
/**
|
|
* esalt
|
|
*/
|
|
|
|
office2013->encryptedVerifier[0] = hex_to_uint (&encryptedVerifier_pos[ 0]);
|
|
office2013->encryptedVerifier[1] = hex_to_uint (&encryptedVerifier_pos[ 8]);
|
|
office2013->encryptedVerifier[2] = hex_to_uint (&encryptedVerifier_pos[16]);
|
|
office2013->encryptedVerifier[3] = hex_to_uint (&encryptedVerifier_pos[24]);
|
|
|
|
office2013->encryptedVerifierHash[0] = hex_to_uint (&encryptedVerifierHash_pos[ 0]);
|
|
office2013->encryptedVerifierHash[1] = hex_to_uint (&encryptedVerifierHash_pos[ 8]);
|
|
office2013->encryptedVerifierHash[2] = hex_to_uint (&encryptedVerifierHash_pos[16]);
|
|
office2013->encryptedVerifierHash[3] = hex_to_uint (&encryptedVerifierHash_pos[24]);
|
|
office2013->encryptedVerifierHash[4] = hex_to_uint (&encryptedVerifierHash_pos[32]);
|
|
office2013->encryptedVerifierHash[5] = hex_to_uint (&encryptedVerifierHash_pos[40]);
|
|
office2013->encryptedVerifierHash[6] = hex_to_uint (&encryptedVerifierHash_pos[48]);
|
|
office2013->encryptedVerifierHash[7] = hex_to_uint (&encryptedVerifierHash_pos[56]);
|
|
|
|
/**
|
|
* digest
|
|
*/
|
|
|
|
digest[0] = office2013->encryptedVerifierHash[0];
|
|
digest[1] = office2013->encryptedVerifierHash[1];
|
|
digest[2] = office2013->encryptedVerifierHash[2];
|
|
digest[3] = office2013->encryptedVerifierHash[3];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int oldoffice01_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9700) || (input_len > DISPLAY_LEN_MAX_9700)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_OLDOFFICE0, input_buf, 12)) && (memcmp (SIGNATURE_OLDOFFICE1, input_buf, 12))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
oldoffice01_t *oldoffice01 = (oldoffice01_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *version_pos = input_buf + 11;
|
|
|
|
char *osalt_pos = strchr (version_pos, '*');
|
|
|
|
if (osalt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t version_len = osalt_pos - version_pos;
|
|
|
|
if (version_len != 1) return (PARSER_SALT_LENGTH);
|
|
|
|
osalt_pos++;
|
|
|
|
char *encryptedVerifier_pos = strchr (osalt_pos, '*');
|
|
|
|
if (encryptedVerifier_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t osalt_len = encryptedVerifier_pos - osalt_pos;
|
|
|
|
if (osalt_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifier_pos++;
|
|
|
|
char *encryptedVerifierHash_pos = strchr (encryptedVerifier_pos, '*');
|
|
|
|
if (encryptedVerifierHash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t encryptedVerifier_len = encryptedVerifierHash_pos - encryptedVerifier_pos;
|
|
|
|
if (encryptedVerifier_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifierHash_pos++;
|
|
|
|
uint32_t encryptedVerifierHash_len = input_len - 11 - version_len - 1 - osalt_len - 1 - encryptedVerifier_len - 1;
|
|
|
|
if (encryptedVerifierHash_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
const uint version = *version_pos - 0x30;
|
|
|
|
if (version != 0 && version != 1) return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* esalt
|
|
*/
|
|
|
|
oldoffice01->version = version;
|
|
|
|
oldoffice01->encryptedVerifier[0] = hex_to_uint (&encryptedVerifier_pos[ 0]);
|
|
oldoffice01->encryptedVerifier[1] = hex_to_uint (&encryptedVerifier_pos[ 8]);
|
|
oldoffice01->encryptedVerifier[2] = hex_to_uint (&encryptedVerifier_pos[16]);
|
|
oldoffice01->encryptedVerifier[3] = hex_to_uint (&encryptedVerifier_pos[24]);
|
|
|
|
oldoffice01->encryptedVerifier[0] = byte_swap_32 (oldoffice01->encryptedVerifier[0]);
|
|
oldoffice01->encryptedVerifier[1] = byte_swap_32 (oldoffice01->encryptedVerifier[1]);
|
|
oldoffice01->encryptedVerifier[2] = byte_swap_32 (oldoffice01->encryptedVerifier[2]);
|
|
oldoffice01->encryptedVerifier[3] = byte_swap_32 (oldoffice01->encryptedVerifier[3]);
|
|
|
|
oldoffice01->encryptedVerifierHash[0] = hex_to_uint (&encryptedVerifierHash_pos[ 0]);
|
|
oldoffice01->encryptedVerifierHash[1] = hex_to_uint (&encryptedVerifierHash_pos[ 8]);
|
|
oldoffice01->encryptedVerifierHash[2] = hex_to_uint (&encryptedVerifierHash_pos[16]);
|
|
oldoffice01->encryptedVerifierHash[3] = hex_to_uint (&encryptedVerifierHash_pos[24]);
|
|
|
|
oldoffice01->encryptedVerifierHash[0] = byte_swap_32 (oldoffice01->encryptedVerifierHash[0]);
|
|
oldoffice01->encryptedVerifierHash[1] = byte_swap_32 (oldoffice01->encryptedVerifierHash[1]);
|
|
oldoffice01->encryptedVerifierHash[2] = byte_swap_32 (oldoffice01->encryptedVerifierHash[2]);
|
|
oldoffice01->encryptedVerifierHash[3] = byte_swap_32 (oldoffice01->encryptedVerifierHash[3]);
|
|
|
|
/**
|
|
* salt
|
|
*/
|
|
|
|
salt->salt_len = 16;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&osalt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&osalt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&osalt_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&osalt_pos[24]);
|
|
|
|
salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]);
|
|
salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]);
|
|
salt->salt_buf[2] = byte_swap_32 (salt->salt_buf[2]);
|
|
salt->salt_buf[3] = byte_swap_32 (salt->salt_buf[3]);
|
|
|
|
// this is a workaround as office produces multiple documents with the same salt
|
|
|
|
salt->salt_len += 32;
|
|
|
|
salt->salt_buf[ 4] = oldoffice01->encryptedVerifier[0];
|
|
salt->salt_buf[ 5] = oldoffice01->encryptedVerifier[1];
|
|
salt->salt_buf[ 6] = oldoffice01->encryptedVerifier[2];
|
|
salt->salt_buf[ 7] = oldoffice01->encryptedVerifier[3];
|
|
salt->salt_buf[ 8] = oldoffice01->encryptedVerifierHash[0];
|
|
salt->salt_buf[ 9] = oldoffice01->encryptedVerifierHash[1];
|
|
salt->salt_buf[10] = oldoffice01->encryptedVerifierHash[2];
|
|
salt->salt_buf[11] = oldoffice01->encryptedVerifierHash[3];
|
|
|
|
/**
|
|
* digest
|
|
*/
|
|
|
|
digest[0] = oldoffice01->encryptedVerifierHash[0];
|
|
digest[1] = oldoffice01->encryptedVerifierHash[1];
|
|
digest[2] = oldoffice01->encryptedVerifierHash[2];
|
|
digest[3] = oldoffice01->encryptedVerifierHash[3];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int oldoffice01cm1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
return oldoffice01_parse_hash (input_buf, input_len, hash_buf);
|
|
}
|
|
|
|
int oldoffice01cm2_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9720) || (input_len > DISPLAY_LEN_MAX_9720)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_OLDOFFICE0, input_buf, 12)) && (memcmp (SIGNATURE_OLDOFFICE1, input_buf, 12))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
oldoffice01_t *oldoffice01 = (oldoffice01_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *version_pos = input_buf + 11;
|
|
|
|
char *osalt_pos = strchr (version_pos, '*');
|
|
|
|
if (osalt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t version_len = osalt_pos - version_pos;
|
|
|
|
if (version_len != 1) return (PARSER_SALT_LENGTH);
|
|
|
|
osalt_pos++;
|
|
|
|
char *encryptedVerifier_pos = strchr (osalt_pos, '*');
|
|
|
|
if (encryptedVerifier_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t osalt_len = encryptedVerifier_pos - osalt_pos;
|
|
|
|
if (osalt_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifier_pos++;
|
|
|
|
char *encryptedVerifierHash_pos = strchr (encryptedVerifier_pos, '*');
|
|
|
|
if (encryptedVerifierHash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t encryptedVerifier_len = encryptedVerifierHash_pos - encryptedVerifier_pos;
|
|
|
|
if (encryptedVerifier_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifierHash_pos++;
|
|
|
|
char *rc4key_pos = strchr (encryptedVerifierHash_pos, ':');
|
|
|
|
if (rc4key_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t encryptedVerifierHash_len = rc4key_pos - encryptedVerifierHash_pos;
|
|
|
|
if (encryptedVerifierHash_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
rc4key_pos++;
|
|
|
|
uint32_t rc4key_len = input_len - 11 - version_len - 1 - osalt_len - 1 - encryptedVerifier_len - 1 - encryptedVerifierHash_len - 1;
|
|
|
|
if (rc4key_len != 10) return (PARSER_SALT_LENGTH);
|
|
|
|
const uint version = *version_pos - 0x30;
|
|
|
|
if (version != 0 && version != 1) return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* esalt
|
|
*/
|
|
|
|
oldoffice01->version = version;
|
|
|
|
oldoffice01->encryptedVerifier[0] = hex_to_uint (&encryptedVerifier_pos[ 0]);
|
|
oldoffice01->encryptedVerifier[1] = hex_to_uint (&encryptedVerifier_pos[ 8]);
|
|
oldoffice01->encryptedVerifier[2] = hex_to_uint (&encryptedVerifier_pos[16]);
|
|
oldoffice01->encryptedVerifier[3] = hex_to_uint (&encryptedVerifier_pos[24]);
|
|
|
|
oldoffice01->encryptedVerifier[0] = byte_swap_32 (oldoffice01->encryptedVerifier[0]);
|
|
oldoffice01->encryptedVerifier[1] = byte_swap_32 (oldoffice01->encryptedVerifier[1]);
|
|
oldoffice01->encryptedVerifier[2] = byte_swap_32 (oldoffice01->encryptedVerifier[2]);
|
|
oldoffice01->encryptedVerifier[3] = byte_swap_32 (oldoffice01->encryptedVerifier[3]);
|
|
|
|
oldoffice01->encryptedVerifierHash[0] = hex_to_uint (&encryptedVerifierHash_pos[ 0]);
|
|
oldoffice01->encryptedVerifierHash[1] = hex_to_uint (&encryptedVerifierHash_pos[ 8]);
|
|
oldoffice01->encryptedVerifierHash[2] = hex_to_uint (&encryptedVerifierHash_pos[16]);
|
|
oldoffice01->encryptedVerifierHash[3] = hex_to_uint (&encryptedVerifierHash_pos[24]);
|
|
|
|
oldoffice01->encryptedVerifierHash[0] = byte_swap_32 (oldoffice01->encryptedVerifierHash[0]);
|
|
oldoffice01->encryptedVerifierHash[1] = byte_swap_32 (oldoffice01->encryptedVerifierHash[1]);
|
|
oldoffice01->encryptedVerifierHash[2] = byte_swap_32 (oldoffice01->encryptedVerifierHash[2]);
|
|
oldoffice01->encryptedVerifierHash[3] = byte_swap_32 (oldoffice01->encryptedVerifierHash[3]);
|
|
|
|
oldoffice01->rc4key[1] = 0;
|
|
oldoffice01->rc4key[0] = 0;
|
|
|
|
oldoffice01->rc4key[0] |= hex_convert (rc4key_pos[0]) << 28;
|
|
oldoffice01->rc4key[0] |= hex_convert (rc4key_pos[1]) << 24;
|
|
oldoffice01->rc4key[0] |= hex_convert (rc4key_pos[2]) << 20;
|
|
oldoffice01->rc4key[0] |= hex_convert (rc4key_pos[3]) << 16;
|
|
oldoffice01->rc4key[0] |= hex_convert (rc4key_pos[4]) << 12;
|
|
oldoffice01->rc4key[0] |= hex_convert (rc4key_pos[5]) << 8;
|
|
oldoffice01->rc4key[0] |= hex_convert (rc4key_pos[6]) << 4;
|
|
oldoffice01->rc4key[0] |= hex_convert (rc4key_pos[7]) << 0;
|
|
oldoffice01->rc4key[1] |= hex_convert (rc4key_pos[8]) << 28;
|
|
oldoffice01->rc4key[1] |= hex_convert (rc4key_pos[9]) << 24;
|
|
|
|
oldoffice01->rc4key[0] = byte_swap_32 (oldoffice01->rc4key[0]);
|
|
oldoffice01->rc4key[1] = byte_swap_32 (oldoffice01->rc4key[1]);
|
|
|
|
/**
|
|
* salt
|
|
*/
|
|
|
|
salt->salt_len = 16;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&osalt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&osalt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&osalt_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&osalt_pos[24]);
|
|
|
|
salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]);
|
|
salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]);
|
|
salt->salt_buf[2] = byte_swap_32 (salt->salt_buf[2]);
|
|
salt->salt_buf[3] = byte_swap_32 (salt->salt_buf[3]);
|
|
|
|
// this is a workaround as office produces multiple documents with the same salt
|
|
|
|
salt->salt_len += 32;
|
|
|
|
salt->salt_buf[ 4] = oldoffice01->encryptedVerifier[0];
|
|
salt->salt_buf[ 5] = oldoffice01->encryptedVerifier[1];
|
|
salt->salt_buf[ 6] = oldoffice01->encryptedVerifier[2];
|
|
salt->salt_buf[ 7] = oldoffice01->encryptedVerifier[3];
|
|
salt->salt_buf[ 8] = oldoffice01->encryptedVerifierHash[0];
|
|
salt->salt_buf[ 9] = oldoffice01->encryptedVerifierHash[1];
|
|
salt->salt_buf[10] = oldoffice01->encryptedVerifierHash[2];
|
|
salt->salt_buf[11] = oldoffice01->encryptedVerifierHash[3];
|
|
|
|
/**
|
|
* digest
|
|
*/
|
|
|
|
digest[0] = oldoffice01->rc4key[0];
|
|
digest[1] = oldoffice01->rc4key[1];
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int oldoffice34_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9800) || (input_len > DISPLAY_LEN_MAX_9800)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_OLDOFFICE3, input_buf, 12)) && (memcmp (SIGNATURE_OLDOFFICE4, input_buf, 12))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
oldoffice34_t *oldoffice34 = (oldoffice34_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *version_pos = input_buf + 11;
|
|
|
|
char *osalt_pos = strchr (version_pos, '*');
|
|
|
|
if (osalt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t version_len = osalt_pos - version_pos;
|
|
|
|
if (version_len != 1) return (PARSER_SALT_LENGTH);
|
|
|
|
osalt_pos++;
|
|
|
|
char *encryptedVerifier_pos = strchr (osalt_pos, '*');
|
|
|
|
if (encryptedVerifier_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t osalt_len = encryptedVerifier_pos - osalt_pos;
|
|
|
|
if (osalt_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifier_pos++;
|
|
|
|
char *encryptedVerifierHash_pos = strchr (encryptedVerifier_pos, '*');
|
|
|
|
if (encryptedVerifierHash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t encryptedVerifier_len = encryptedVerifierHash_pos - encryptedVerifier_pos;
|
|
|
|
if (encryptedVerifier_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifierHash_pos++;
|
|
|
|
uint32_t encryptedVerifierHash_len = input_len - 11 - version_len - 1 - osalt_len - 1 - encryptedVerifier_len - 1;
|
|
|
|
if (encryptedVerifierHash_len != 40) return (PARSER_SALT_LENGTH);
|
|
|
|
const uint version = *version_pos - 0x30;
|
|
|
|
if (version != 3 && version != 4) return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* esalt
|
|
*/
|
|
|
|
oldoffice34->version = version;
|
|
|
|
oldoffice34->encryptedVerifier[0] = hex_to_uint (&encryptedVerifier_pos[ 0]);
|
|
oldoffice34->encryptedVerifier[1] = hex_to_uint (&encryptedVerifier_pos[ 8]);
|
|
oldoffice34->encryptedVerifier[2] = hex_to_uint (&encryptedVerifier_pos[16]);
|
|
oldoffice34->encryptedVerifier[3] = hex_to_uint (&encryptedVerifier_pos[24]);
|
|
|
|
oldoffice34->encryptedVerifier[0] = byte_swap_32 (oldoffice34->encryptedVerifier[0]);
|
|
oldoffice34->encryptedVerifier[1] = byte_swap_32 (oldoffice34->encryptedVerifier[1]);
|
|
oldoffice34->encryptedVerifier[2] = byte_swap_32 (oldoffice34->encryptedVerifier[2]);
|
|
oldoffice34->encryptedVerifier[3] = byte_swap_32 (oldoffice34->encryptedVerifier[3]);
|
|
|
|
oldoffice34->encryptedVerifierHash[0] = hex_to_uint (&encryptedVerifierHash_pos[ 0]);
|
|
oldoffice34->encryptedVerifierHash[1] = hex_to_uint (&encryptedVerifierHash_pos[ 8]);
|
|
oldoffice34->encryptedVerifierHash[2] = hex_to_uint (&encryptedVerifierHash_pos[16]);
|
|
oldoffice34->encryptedVerifierHash[3] = hex_to_uint (&encryptedVerifierHash_pos[24]);
|
|
oldoffice34->encryptedVerifierHash[4] = hex_to_uint (&encryptedVerifierHash_pos[32]);
|
|
|
|
oldoffice34->encryptedVerifierHash[0] = byte_swap_32 (oldoffice34->encryptedVerifierHash[0]);
|
|
oldoffice34->encryptedVerifierHash[1] = byte_swap_32 (oldoffice34->encryptedVerifierHash[1]);
|
|
oldoffice34->encryptedVerifierHash[2] = byte_swap_32 (oldoffice34->encryptedVerifierHash[2]);
|
|
oldoffice34->encryptedVerifierHash[3] = byte_swap_32 (oldoffice34->encryptedVerifierHash[3]);
|
|
oldoffice34->encryptedVerifierHash[4] = byte_swap_32 (oldoffice34->encryptedVerifierHash[4]);
|
|
|
|
/**
|
|
* salt
|
|
*/
|
|
|
|
salt->salt_len = 16;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&osalt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&osalt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&osalt_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&osalt_pos[24]);
|
|
|
|
// this is a workaround as office produces multiple documents with the same salt
|
|
|
|
salt->salt_len += 32;
|
|
|
|
salt->salt_buf[ 4] = oldoffice34->encryptedVerifier[0];
|
|
salt->salt_buf[ 5] = oldoffice34->encryptedVerifier[1];
|
|
salt->salt_buf[ 6] = oldoffice34->encryptedVerifier[2];
|
|
salt->salt_buf[ 7] = oldoffice34->encryptedVerifier[3];
|
|
salt->salt_buf[ 8] = oldoffice34->encryptedVerifierHash[0];
|
|
salt->salt_buf[ 9] = oldoffice34->encryptedVerifierHash[1];
|
|
salt->salt_buf[10] = oldoffice34->encryptedVerifierHash[2];
|
|
salt->salt_buf[11] = oldoffice34->encryptedVerifierHash[3];
|
|
|
|
/**
|
|
* digest
|
|
*/
|
|
|
|
digest[0] = oldoffice34->encryptedVerifierHash[0];
|
|
digest[1] = oldoffice34->encryptedVerifierHash[1];
|
|
digest[2] = oldoffice34->encryptedVerifierHash[2];
|
|
digest[3] = oldoffice34->encryptedVerifierHash[3];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int oldoffice34cm1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if (memcmp (SIGNATURE_OLDOFFICE3, input_buf, 12)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
return oldoffice34_parse_hash (input_buf, input_len, hash_buf);
|
|
}
|
|
|
|
int oldoffice34cm2_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9820) || (input_len > DISPLAY_LEN_MAX_9820)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_OLDOFFICE3, input_buf, 12)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
oldoffice34_t *oldoffice34 = (oldoffice34_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *version_pos = input_buf + 11;
|
|
|
|
char *osalt_pos = strchr (version_pos, '*');
|
|
|
|
if (osalt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t version_len = osalt_pos - version_pos;
|
|
|
|
if (version_len != 1) return (PARSER_SALT_LENGTH);
|
|
|
|
osalt_pos++;
|
|
|
|
char *encryptedVerifier_pos = strchr (osalt_pos, '*');
|
|
|
|
if (encryptedVerifier_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t osalt_len = encryptedVerifier_pos - osalt_pos;
|
|
|
|
if (osalt_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifier_pos++;
|
|
|
|
char *encryptedVerifierHash_pos = strchr (encryptedVerifier_pos, '*');
|
|
|
|
if (encryptedVerifierHash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t encryptedVerifier_len = encryptedVerifierHash_pos - encryptedVerifier_pos;
|
|
|
|
if (encryptedVerifier_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
encryptedVerifierHash_pos++;
|
|
|
|
char *rc4key_pos = strchr (encryptedVerifierHash_pos, ':');
|
|
|
|
if (rc4key_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t encryptedVerifierHash_len = rc4key_pos - encryptedVerifierHash_pos;
|
|
|
|
if (encryptedVerifierHash_len != 40) return (PARSER_SALT_LENGTH);
|
|
|
|
rc4key_pos++;
|
|
|
|
uint32_t rc4key_len = input_len - 11 - version_len - 1 - osalt_len - 1 - encryptedVerifier_len - 1 - encryptedVerifierHash_len - 1;
|
|
|
|
if (rc4key_len != 10) return (PARSER_SALT_LENGTH);
|
|
|
|
const uint version = *version_pos - 0x30;
|
|
|
|
if (version != 3 && version != 4) return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* esalt
|
|
*/
|
|
|
|
oldoffice34->version = version;
|
|
|
|
oldoffice34->encryptedVerifier[0] = hex_to_uint (&encryptedVerifier_pos[ 0]);
|
|
oldoffice34->encryptedVerifier[1] = hex_to_uint (&encryptedVerifier_pos[ 8]);
|
|
oldoffice34->encryptedVerifier[2] = hex_to_uint (&encryptedVerifier_pos[16]);
|
|
oldoffice34->encryptedVerifier[3] = hex_to_uint (&encryptedVerifier_pos[24]);
|
|
|
|
oldoffice34->encryptedVerifier[0] = byte_swap_32 (oldoffice34->encryptedVerifier[0]);
|
|
oldoffice34->encryptedVerifier[1] = byte_swap_32 (oldoffice34->encryptedVerifier[1]);
|
|
oldoffice34->encryptedVerifier[2] = byte_swap_32 (oldoffice34->encryptedVerifier[2]);
|
|
oldoffice34->encryptedVerifier[3] = byte_swap_32 (oldoffice34->encryptedVerifier[3]);
|
|
|
|
oldoffice34->encryptedVerifierHash[0] = hex_to_uint (&encryptedVerifierHash_pos[ 0]);
|
|
oldoffice34->encryptedVerifierHash[1] = hex_to_uint (&encryptedVerifierHash_pos[ 8]);
|
|
oldoffice34->encryptedVerifierHash[2] = hex_to_uint (&encryptedVerifierHash_pos[16]);
|
|
oldoffice34->encryptedVerifierHash[3] = hex_to_uint (&encryptedVerifierHash_pos[24]);
|
|
oldoffice34->encryptedVerifierHash[4] = hex_to_uint (&encryptedVerifierHash_pos[32]);
|
|
|
|
oldoffice34->encryptedVerifierHash[0] = byte_swap_32 (oldoffice34->encryptedVerifierHash[0]);
|
|
oldoffice34->encryptedVerifierHash[1] = byte_swap_32 (oldoffice34->encryptedVerifierHash[1]);
|
|
oldoffice34->encryptedVerifierHash[2] = byte_swap_32 (oldoffice34->encryptedVerifierHash[2]);
|
|
oldoffice34->encryptedVerifierHash[3] = byte_swap_32 (oldoffice34->encryptedVerifierHash[3]);
|
|
oldoffice34->encryptedVerifierHash[4] = byte_swap_32 (oldoffice34->encryptedVerifierHash[4]);
|
|
|
|
oldoffice34->rc4key[1] = 0;
|
|
oldoffice34->rc4key[0] = 0;
|
|
|
|
oldoffice34->rc4key[0] |= hex_convert (rc4key_pos[0]) << 28;
|
|
oldoffice34->rc4key[0] |= hex_convert (rc4key_pos[1]) << 24;
|
|
oldoffice34->rc4key[0] |= hex_convert (rc4key_pos[2]) << 20;
|
|
oldoffice34->rc4key[0] |= hex_convert (rc4key_pos[3]) << 16;
|
|
oldoffice34->rc4key[0] |= hex_convert (rc4key_pos[4]) << 12;
|
|
oldoffice34->rc4key[0] |= hex_convert (rc4key_pos[5]) << 8;
|
|
oldoffice34->rc4key[0] |= hex_convert (rc4key_pos[6]) << 4;
|
|
oldoffice34->rc4key[0] |= hex_convert (rc4key_pos[7]) << 0;
|
|
oldoffice34->rc4key[1] |= hex_convert (rc4key_pos[8]) << 28;
|
|
oldoffice34->rc4key[1] |= hex_convert (rc4key_pos[9]) << 24;
|
|
|
|
oldoffice34->rc4key[0] = byte_swap_32 (oldoffice34->rc4key[0]);
|
|
oldoffice34->rc4key[1] = byte_swap_32 (oldoffice34->rc4key[1]);
|
|
|
|
/**
|
|
* salt
|
|
*/
|
|
|
|
salt->salt_len = 16;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&osalt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&osalt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&osalt_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&osalt_pos[24]);
|
|
|
|
// this is a workaround as office produces multiple documents with the same salt
|
|
|
|
salt->salt_len += 32;
|
|
|
|
salt->salt_buf[ 4] = oldoffice34->encryptedVerifier[0];
|
|
salt->salt_buf[ 5] = oldoffice34->encryptedVerifier[1];
|
|
salt->salt_buf[ 6] = oldoffice34->encryptedVerifier[2];
|
|
salt->salt_buf[ 7] = oldoffice34->encryptedVerifier[3];
|
|
salt->salt_buf[ 8] = oldoffice34->encryptedVerifierHash[0];
|
|
salt->salt_buf[ 9] = oldoffice34->encryptedVerifierHash[1];
|
|
salt->salt_buf[10] = oldoffice34->encryptedVerifierHash[2];
|
|
salt->salt_buf[11] = oldoffice34->encryptedVerifierHash[3];
|
|
|
|
/**
|
|
* digest
|
|
*/
|
|
|
|
digest[0] = oldoffice34->rc4key[0];
|
|
digest[1] = oldoffice34->rc4key[1];
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int radmin2_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_9900) || (input_len > DISPLAY_LEN_MAX_9900)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int djangosha1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_124) || (input_len > DISPLAY_LEN_MAX_124)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_DJANGOSHA1, input_buf, 5)) && (memcmp (SIGNATURE_DJANGOSHA1, input_buf, 5))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *signature_pos = input_buf;
|
|
|
|
char *salt_pos = strchr (signature_pos, '$');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t signature_len = salt_pos - signature_pos;
|
|
|
|
if (signature_len != 4) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len > 32) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
uint32_t hash_len = input_len - signature_len - 1 - salt_len - 1;
|
|
|
|
if (hash_len != 40) return (PARSER_SALT_LENGTH);
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_pos[32]);
|
|
|
|
digest[0] -= SHA1M_A;
|
|
digest[1] -= SHA1M_B;
|
|
digest[2] -= SHA1M_C;
|
|
digest[3] -= SHA1M_D;
|
|
digest[4] -= SHA1M_E;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
memcpy (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int djangopbkdf2_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10000) || (input_len > DISPLAY_LEN_MAX_10000)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_DJANGOPBKDF2, input_buf, 14)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pbkdf2_sha256_t *pbkdf2_sha256 = (pbkdf2_sha256_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *iter_pos = input_buf + 14;
|
|
|
|
const int iter = atoi (iter_pos);
|
|
|
|
if (iter < 1) return (PARSER_SALT_ITERATION);
|
|
|
|
salt->salt_iter = iter - 1;
|
|
|
|
char *salt_pos = strchr (iter_pos, '$');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
const uint salt_len = hash_pos - salt_pos;
|
|
|
|
hash_pos++;
|
|
|
|
char *salt_buf_ptr = (char *) pbkdf2_sha256->salt_buf;
|
|
|
|
memcpy (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
salt_buf_ptr[salt_len + 3] = 0x01;
|
|
salt_buf_ptr[salt_len + 4] = 0x80;
|
|
|
|
// add some stuff to normal salt to make sorted happy
|
|
|
|
salt->salt_buf[0] = pbkdf2_sha256->salt_buf[0];
|
|
salt->salt_buf[1] = pbkdf2_sha256->salt_buf[1];
|
|
salt->salt_buf[2] = pbkdf2_sha256->salt_buf[2];
|
|
salt->salt_buf[3] = pbkdf2_sha256->salt_buf[3];
|
|
salt->salt_buf[4] = salt->salt_iter;
|
|
|
|
// base64 decode hash
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
uint hash_len = input_len - (hash_pos - input_buf);
|
|
|
|
if (hash_len != 44) return (PARSER_HASH_LENGTH);
|
|
|
|
base64_decode (base64_to_int, hash_pos, hash_len, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 32);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
digest[5] = byte_swap_32 (digest[5]);
|
|
digest[6] = byte_swap_32 (digest[6]);
|
|
digest[7] = byte_swap_32 (digest[7]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int siphash_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10100) || (input_len > DISPLAY_LEN_MAX_10100)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
|
|
if (input_buf[16] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
if (input_buf[18] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
if (input_buf[20] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
char iter_c = input_buf[17];
|
|
char iter_d = input_buf[19];
|
|
|
|
// atm only defaults, let's see if there's more request
|
|
if (iter_c != '2') return (PARSER_SALT_ITERATION);
|
|
if (iter_d != '4') return (PARSER_SALT_ITERATION);
|
|
|
|
char *salt_buf = input_buf + 16 + 1 + 1 + 1 + 1 + 1;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&salt_buf[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&salt_buf[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&salt_buf[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&salt_buf[24]);
|
|
|
|
salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]);
|
|
salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]);
|
|
salt->salt_buf[2] = byte_swap_32 (salt->salt_buf[2]);
|
|
salt->salt_buf[3] = byte_swap_32 (salt->salt_buf[3]);
|
|
|
|
salt->salt_len = 16;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int crammd5_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10200) || (input_len > DISPLAY_LEN_MAX_10200)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_CRAM_MD5, input_buf, 10)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
cram_md5_t *cram_md5 = (cram_md5_t *) hash_buf->esalt;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 10;
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
uint salt_len = hash_pos - salt_pos;
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
hash_pos++;
|
|
|
|
uint hash_len = input_len - 10 - salt_len - 1;
|
|
|
|
// base64 decode salt
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
salt_len = base64_decode (base64_to_int, salt_pos, salt_len, tmp_buf);
|
|
|
|
if (salt_len > 55) return (PARSER_SALT_LENGTH);
|
|
|
|
tmp_buf[salt_len] = 0x80;
|
|
|
|
memcpy (&salt->salt_buf, tmp_buf, salt_len + 1);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
// base64 decode salt
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
hash_len = base64_decode (base64_to_int, hash_pos, hash_len, tmp_buf);
|
|
|
|
uint user_len = hash_len - 32;
|
|
|
|
char *tmp_hash = tmp_buf + user_len;
|
|
|
|
user_len--; // skip the trailing space
|
|
|
|
digest[0] = hex_to_uint (&tmp_hash[ 0]);
|
|
digest[1] = hex_to_uint (&tmp_hash[ 8]);
|
|
digest[2] = hex_to_uint (&tmp_hash[16]);
|
|
digest[3] = hex_to_uint (&tmp_hash[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
// store username for host only (output hash if cracked)
|
|
|
|
memset (cram_md5->user, 0, sizeof (cram_md5->user));
|
|
memcpy (cram_md5->user, tmp_buf, user_len);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int saph_sha1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10300) || (input_len > DISPLAY_LEN_MAX_10300)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SAPH_SHA1, input_buf, 10)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *iter_pos = input_buf + 10;
|
|
|
|
uint32_t iter = atoi (iter_pos);
|
|
|
|
if (iter < 1)
|
|
{
|
|
return (PARSER_SALT_ITERATION);
|
|
}
|
|
|
|
iter--; // first iteration is special
|
|
|
|
salt->salt_iter = iter;
|
|
|
|
char *base64_pos = strchr (iter_pos, '}');
|
|
|
|
if (base64_pos == NULL)
|
|
{
|
|
return (PARSER_SIGNATURE_UNMATCHED);
|
|
}
|
|
|
|
base64_pos++;
|
|
|
|
// base64 decode salt
|
|
|
|
uint32_t base64_len = input_len - (base64_pos - input_buf);
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
uint32_t decoded_len = base64_decode (base64_to_int, base64_pos, base64_len, tmp_buf);
|
|
|
|
if (decoded_len < 24)
|
|
{
|
|
return (PARSER_SALT_LENGTH);
|
|
}
|
|
|
|
// copy the salt
|
|
|
|
uint salt_len = decoded_len - 20;
|
|
|
|
if (salt_len < 4) return (PARSER_SALT_LENGTH);
|
|
if (salt_len > 16) return (PARSER_SALT_LENGTH);
|
|
|
|
memcpy (&salt->salt_buf, tmp_buf + 20, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
// set digest
|
|
|
|
uint32_t *digest_ptr = (uint32_t*) tmp_buf;
|
|
|
|
digest[0] = byte_swap_32 (digest_ptr[0]);
|
|
digest[1] = byte_swap_32 (digest_ptr[1]);
|
|
digest[2] = byte_swap_32 (digest_ptr[2]);
|
|
digest[3] = byte_swap_32 (digest_ptr[3]);
|
|
digest[4] = byte_swap_32 (digest_ptr[4]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int redmine_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_7600) || (input_len > DISPLAY_LEN_MAX_7600)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&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;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int pdf11_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10400) || (input_len > DISPLAY_LEN_MAX_10400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_PDF, input_buf, 5)) && (memcmp (SIGNATURE_PDF, input_buf, 5))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pdf_t *pdf = (pdf_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *V_pos = input_buf + 5;
|
|
|
|
char *R_pos = strchr (V_pos, '*');
|
|
|
|
if (R_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t V_len = R_pos - V_pos;
|
|
|
|
R_pos++;
|
|
|
|
char *bits_pos = strchr (R_pos, '*');
|
|
|
|
if (bits_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t R_len = bits_pos - R_pos;
|
|
|
|
bits_pos++;
|
|
|
|
char *P_pos = strchr (bits_pos, '*');
|
|
|
|
if (P_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t bits_len = P_pos - bits_pos;
|
|
|
|
P_pos++;
|
|
|
|
char *enc_md_pos = strchr (P_pos, '*');
|
|
|
|
if (enc_md_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t P_len = enc_md_pos - P_pos;
|
|
|
|
enc_md_pos++;
|
|
|
|
char *id_len_pos = strchr (enc_md_pos, '*');
|
|
|
|
if (id_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t enc_md_len = id_len_pos - enc_md_pos;
|
|
|
|
id_len_pos++;
|
|
|
|
char *id_buf_pos = strchr (id_len_pos, '*');
|
|
|
|
if (id_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t id_len_len = id_buf_pos - id_len_pos;
|
|
|
|
id_buf_pos++;
|
|
|
|
char *u_len_pos = strchr (id_buf_pos, '*');
|
|
|
|
if (u_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t id_buf_len = u_len_pos - id_buf_pos;
|
|
|
|
if (id_buf_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
u_len_pos++;
|
|
|
|
char *u_buf_pos = strchr (u_len_pos, '*');
|
|
|
|
if (u_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t u_len_len = u_buf_pos - u_len_pos;
|
|
|
|
u_buf_pos++;
|
|
|
|
char *o_len_pos = strchr (u_buf_pos, '*');
|
|
|
|
if (o_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t u_buf_len = o_len_pos - u_buf_pos;
|
|
|
|
if (u_buf_len != 64) return (PARSER_SALT_LENGTH);
|
|
|
|
o_len_pos++;
|
|
|
|
char *o_buf_pos = strchr (o_len_pos, '*');
|
|
|
|
if (o_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t o_len_len = o_buf_pos - o_len_pos;
|
|
|
|
o_buf_pos++;
|
|
|
|
uint32_t o_buf_len = input_len - 5 - V_len - 1 - R_len - 1 - bits_len - 1 - P_len - 1 - enc_md_len - 1 - id_len_len - 1 - id_buf_len - 1 - u_len_len - 1 - u_buf_len - 1 - o_len_len - 1;
|
|
|
|
if (o_buf_len != 64) return (PARSER_SALT_LENGTH);
|
|
|
|
// validate data
|
|
|
|
const int V = atoi (V_pos);
|
|
const int R = atoi (R_pos);
|
|
const int P = atoi (P_pos);
|
|
|
|
if (V != 1) return (PARSER_SALT_VALUE);
|
|
if (R != 2) return (PARSER_SALT_VALUE);
|
|
|
|
const int enc_md = atoi (enc_md_pos);
|
|
|
|
if ((enc_md != 0) && (enc_md != 1)) return (PARSER_SALT_VALUE);
|
|
|
|
const int id_len = atoi (id_len_pos);
|
|
const int u_len = atoi (u_len_pos);
|
|
const int o_len = atoi (o_len_pos);
|
|
|
|
if (id_len != 16) return (PARSER_SALT_VALUE);
|
|
if (u_len != 32) return (PARSER_SALT_VALUE);
|
|
if (o_len != 32) return (PARSER_SALT_VALUE);
|
|
|
|
const int bits = atoi (bits_pos);
|
|
|
|
if (bits != 40) return (PARSER_SALT_VALUE);
|
|
|
|
// copy data to esalt
|
|
|
|
pdf->V = V;
|
|
pdf->R = R;
|
|
pdf->P = P;
|
|
|
|
pdf->enc_md = enc_md;
|
|
|
|
pdf->id_buf[0] = hex_to_uint (&id_buf_pos[ 0]);
|
|
pdf->id_buf[1] = hex_to_uint (&id_buf_pos[ 8]);
|
|
pdf->id_buf[2] = hex_to_uint (&id_buf_pos[16]);
|
|
pdf->id_buf[3] = hex_to_uint (&id_buf_pos[24]);
|
|
pdf->id_len = id_len;
|
|
|
|
pdf->u_buf[0] = hex_to_uint (&u_buf_pos[ 0]);
|
|
pdf->u_buf[1] = hex_to_uint (&u_buf_pos[ 8]);
|
|
pdf->u_buf[2] = hex_to_uint (&u_buf_pos[16]);
|
|
pdf->u_buf[3] = hex_to_uint (&u_buf_pos[24]);
|
|
pdf->u_buf[4] = hex_to_uint (&u_buf_pos[32]);
|
|
pdf->u_buf[5] = hex_to_uint (&u_buf_pos[40]);
|
|
pdf->u_buf[6] = hex_to_uint (&u_buf_pos[48]);
|
|
pdf->u_buf[7] = hex_to_uint (&u_buf_pos[56]);
|
|
pdf->u_len = u_len;
|
|
|
|
pdf->o_buf[0] = hex_to_uint (&o_buf_pos[ 0]);
|
|
pdf->o_buf[1] = hex_to_uint (&o_buf_pos[ 8]);
|
|
pdf->o_buf[2] = hex_to_uint (&o_buf_pos[16]);
|
|
pdf->o_buf[3] = hex_to_uint (&o_buf_pos[24]);
|
|
pdf->o_buf[4] = hex_to_uint (&o_buf_pos[32]);
|
|
pdf->o_buf[5] = hex_to_uint (&o_buf_pos[40]);
|
|
pdf->o_buf[6] = hex_to_uint (&o_buf_pos[48]);
|
|
pdf->o_buf[7] = hex_to_uint (&o_buf_pos[56]);
|
|
pdf->o_len = o_len;
|
|
|
|
pdf->id_buf[0] = byte_swap_32 (pdf->id_buf[0]);
|
|
pdf->id_buf[1] = byte_swap_32 (pdf->id_buf[1]);
|
|
pdf->id_buf[2] = byte_swap_32 (pdf->id_buf[2]);
|
|
pdf->id_buf[3] = byte_swap_32 (pdf->id_buf[3]);
|
|
|
|
pdf->u_buf[0] = byte_swap_32 (pdf->u_buf[0]);
|
|
pdf->u_buf[1] = byte_swap_32 (pdf->u_buf[1]);
|
|
pdf->u_buf[2] = byte_swap_32 (pdf->u_buf[2]);
|
|
pdf->u_buf[3] = byte_swap_32 (pdf->u_buf[3]);
|
|
pdf->u_buf[4] = byte_swap_32 (pdf->u_buf[4]);
|
|
pdf->u_buf[5] = byte_swap_32 (pdf->u_buf[5]);
|
|
pdf->u_buf[6] = byte_swap_32 (pdf->u_buf[6]);
|
|
pdf->u_buf[7] = byte_swap_32 (pdf->u_buf[7]);
|
|
|
|
pdf->o_buf[0] = byte_swap_32 (pdf->o_buf[0]);
|
|
pdf->o_buf[1] = byte_swap_32 (pdf->o_buf[1]);
|
|
pdf->o_buf[2] = byte_swap_32 (pdf->o_buf[2]);
|
|
pdf->o_buf[3] = byte_swap_32 (pdf->o_buf[3]);
|
|
pdf->o_buf[4] = byte_swap_32 (pdf->o_buf[4]);
|
|
pdf->o_buf[5] = byte_swap_32 (pdf->o_buf[5]);
|
|
pdf->o_buf[6] = byte_swap_32 (pdf->o_buf[6]);
|
|
pdf->o_buf[7] = byte_swap_32 (pdf->o_buf[7]);
|
|
|
|
// we use ID for salt, maybe needs to change, we will see...
|
|
|
|
salt->salt_buf[0] = pdf->id_buf[0];
|
|
salt->salt_buf[1] = pdf->id_buf[1];
|
|
salt->salt_buf[2] = pdf->id_buf[2];
|
|
salt->salt_buf[3] = pdf->id_buf[3];
|
|
salt->salt_len = pdf->id_len;
|
|
|
|
digest[0] = pdf->u_buf[0];
|
|
digest[1] = pdf->u_buf[1];
|
|
digest[2] = pdf->u_buf[2];
|
|
digest[3] = pdf->u_buf[3];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int pdf11cm1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
return pdf11_parse_hash (input_buf, input_len, hash_buf);
|
|
}
|
|
|
|
int pdf11cm2_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10420) || (input_len > DISPLAY_LEN_MAX_10420)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_PDF, input_buf, 5)) && (memcmp (SIGNATURE_PDF, input_buf, 5))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pdf_t *pdf = (pdf_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *V_pos = input_buf + 5;
|
|
|
|
char *R_pos = strchr (V_pos, '*');
|
|
|
|
if (R_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t V_len = R_pos - V_pos;
|
|
|
|
R_pos++;
|
|
|
|
char *bits_pos = strchr (R_pos, '*');
|
|
|
|
if (bits_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t R_len = bits_pos - R_pos;
|
|
|
|
bits_pos++;
|
|
|
|
char *P_pos = strchr (bits_pos, '*');
|
|
|
|
if (P_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t bits_len = P_pos - bits_pos;
|
|
|
|
P_pos++;
|
|
|
|
char *enc_md_pos = strchr (P_pos, '*');
|
|
|
|
if (enc_md_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t P_len = enc_md_pos - P_pos;
|
|
|
|
enc_md_pos++;
|
|
|
|
char *id_len_pos = strchr (enc_md_pos, '*');
|
|
|
|
if (id_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t enc_md_len = id_len_pos - enc_md_pos;
|
|
|
|
id_len_pos++;
|
|
|
|
char *id_buf_pos = strchr (id_len_pos, '*');
|
|
|
|
if (id_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t id_len_len = id_buf_pos - id_len_pos;
|
|
|
|
id_buf_pos++;
|
|
|
|
char *u_len_pos = strchr (id_buf_pos, '*');
|
|
|
|
if (u_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t id_buf_len = u_len_pos - id_buf_pos;
|
|
|
|
if (id_buf_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
u_len_pos++;
|
|
|
|
char *u_buf_pos = strchr (u_len_pos, '*');
|
|
|
|
if (u_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t u_len_len = u_buf_pos - u_len_pos;
|
|
|
|
u_buf_pos++;
|
|
|
|
char *o_len_pos = strchr (u_buf_pos, '*');
|
|
|
|
if (o_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t u_buf_len = o_len_pos - u_buf_pos;
|
|
|
|
if (u_buf_len != 64) return (PARSER_SALT_LENGTH);
|
|
|
|
o_len_pos++;
|
|
|
|
char *o_buf_pos = strchr (o_len_pos, '*');
|
|
|
|
if (o_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t o_len_len = o_buf_pos - o_len_pos;
|
|
|
|
o_buf_pos++;
|
|
|
|
char *rc4key_pos = strchr (o_buf_pos, ':');
|
|
|
|
if (rc4key_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t o_buf_len = rc4key_pos - o_buf_pos;
|
|
|
|
if (o_buf_len != 64) return (PARSER_SALT_LENGTH);
|
|
|
|
rc4key_pos++;
|
|
|
|
uint32_t rc4key_len = input_len - 5 - V_len - 1 - R_len - 1 - bits_len - 1 - P_len - 1 - enc_md_len - 1 - id_len_len - 1 - id_buf_len - 1 - u_len_len - 1 - u_buf_len - 1 - o_len_len - 1 - o_buf_len - 1;
|
|
|
|
if (rc4key_len != 10) return (PARSER_SALT_LENGTH);
|
|
|
|
// validate data
|
|
|
|
const int V = atoi (V_pos);
|
|
const int R = atoi (R_pos);
|
|
const int P = atoi (P_pos);
|
|
|
|
if (V != 1) return (PARSER_SALT_VALUE);
|
|
if (R != 2) return (PARSER_SALT_VALUE);
|
|
|
|
const int enc_md = atoi (enc_md_pos);
|
|
|
|
if ((enc_md != 0) && (enc_md != 1)) return (PARSER_SALT_VALUE);
|
|
|
|
const int id_len = atoi (id_len_pos);
|
|
const int u_len = atoi (u_len_pos);
|
|
const int o_len = atoi (o_len_pos);
|
|
|
|
if (id_len != 16) return (PARSER_SALT_VALUE);
|
|
if (u_len != 32) return (PARSER_SALT_VALUE);
|
|
if (o_len != 32) return (PARSER_SALT_VALUE);
|
|
|
|
const int bits = atoi (bits_pos);
|
|
|
|
if (bits != 40) return (PARSER_SALT_VALUE);
|
|
|
|
// copy data to esalt
|
|
|
|
pdf->V = V;
|
|
pdf->R = R;
|
|
pdf->P = P;
|
|
|
|
pdf->enc_md = enc_md;
|
|
|
|
pdf->id_buf[0] = hex_to_uint (&id_buf_pos[ 0]);
|
|
pdf->id_buf[1] = hex_to_uint (&id_buf_pos[ 8]);
|
|
pdf->id_buf[2] = hex_to_uint (&id_buf_pos[16]);
|
|
pdf->id_buf[3] = hex_to_uint (&id_buf_pos[24]);
|
|
pdf->id_len = id_len;
|
|
|
|
pdf->u_buf[0] = hex_to_uint (&u_buf_pos[ 0]);
|
|
pdf->u_buf[1] = hex_to_uint (&u_buf_pos[ 8]);
|
|
pdf->u_buf[2] = hex_to_uint (&u_buf_pos[16]);
|
|
pdf->u_buf[3] = hex_to_uint (&u_buf_pos[24]);
|
|
pdf->u_buf[4] = hex_to_uint (&u_buf_pos[32]);
|
|
pdf->u_buf[5] = hex_to_uint (&u_buf_pos[40]);
|
|
pdf->u_buf[6] = hex_to_uint (&u_buf_pos[48]);
|
|
pdf->u_buf[7] = hex_to_uint (&u_buf_pos[56]);
|
|
pdf->u_len = u_len;
|
|
|
|
pdf->o_buf[0] = hex_to_uint (&o_buf_pos[ 0]);
|
|
pdf->o_buf[1] = hex_to_uint (&o_buf_pos[ 8]);
|
|
pdf->o_buf[2] = hex_to_uint (&o_buf_pos[16]);
|
|
pdf->o_buf[3] = hex_to_uint (&o_buf_pos[24]);
|
|
pdf->o_buf[4] = hex_to_uint (&o_buf_pos[32]);
|
|
pdf->o_buf[5] = hex_to_uint (&o_buf_pos[40]);
|
|
pdf->o_buf[6] = hex_to_uint (&o_buf_pos[48]);
|
|
pdf->o_buf[7] = hex_to_uint (&o_buf_pos[56]);
|
|
pdf->o_len = o_len;
|
|
|
|
pdf->id_buf[0] = byte_swap_32 (pdf->id_buf[0]);
|
|
pdf->id_buf[1] = byte_swap_32 (pdf->id_buf[1]);
|
|
pdf->id_buf[2] = byte_swap_32 (pdf->id_buf[2]);
|
|
pdf->id_buf[3] = byte_swap_32 (pdf->id_buf[3]);
|
|
|
|
pdf->u_buf[0] = byte_swap_32 (pdf->u_buf[0]);
|
|
pdf->u_buf[1] = byte_swap_32 (pdf->u_buf[1]);
|
|
pdf->u_buf[2] = byte_swap_32 (pdf->u_buf[2]);
|
|
pdf->u_buf[3] = byte_swap_32 (pdf->u_buf[3]);
|
|
pdf->u_buf[4] = byte_swap_32 (pdf->u_buf[4]);
|
|
pdf->u_buf[5] = byte_swap_32 (pdf->u_buf[5]);
|
|
pdf->u_buf[6] = byte_swap_32 (pdf->u_buf[6]);
|
|
pdf->u_buf[7] = byte_swap_32 (pdf->u_buf[7]);
|
|
|
|
pdf->o_buf[0] = byte_swap_32 (pdf->o_buf[0]);
|
|
pdf->o_buf[1] = byte_swap_32 (pdf->o_buf[1]);
|
|
pdf->o_buf[2] = byte_swap_32 (pdf->o_buf[2]);
|
|
pdf->o_buf[3] = byte_swap_32 (pdf->o_buf[3]);
|
|
pdf->o_buf[4] = byte_swap_32 (pdf->o_buf[4]);
|
|
pdf->o_buf[5] = byte_swap_32 (pdf->o_buf[5]);
|
|
pdf->o_buf[6] = byte_swap_32 (pdf->o_buf[6]);
|
|
pdf->o_buf[7] = byte_swap_32 (pdf->o_buf[7]);
|
|
|
|
pdf->rc4key[1] = 0;
|
|
pdf->rc4key[0] = 0;
|
|
|
|
pdf->rc4key[0] |= hex_convert (rc4key_pos[0]) << 28;
|
|
pdf->rc4key[0] |= hex_convert (rc4key_pos[1]) << 24;
|
|
pdf->rc4key[0] |= hex_convert (rc4key_pos[2]) << 20;
|
|
pdf->rc4key[0] |= hex_convert (rc4key_pos[3]) << 16;
|
|
pdf->rc4key[0] |= hex_convert (rc4key_pos[4]) << 12;
|
|
pdf->rc4key[0] |= hex_convert (rc4key_pos[5]) << 8;
|
|
pdf->rc4key[0] |= hex_convert (rc4key_pos[6]) << 4;
|
|
pdf->rc4key[0] |= hex_convert (rc4key_pos[7]) << 0;
|
|
pdf->rc4key[1] |= hex_convert (rc4key_pos[8]) << 28;
|
|
pdf->rc4key[1] |= hex_convert (rc4key_pos[9]) << 24;
|
|
|
|
pdf->rc4key[0] = byte_swap_32 (pdf->rc4key[0]);
|
|
pdf->rc4key[1] = byte_swap_32 (pdf->rc4key[1]);
|
|
|
|
// we use ID for salt, maybe needs to change, we will see...
|
|
|
|
salt->salt_buf[0] = pdf->id_buf[0];
|
|
salt->salt_buf[1] = pdf->id_buf[1];
|
|
salt->salt_buf[2] = pdf->id_buf[2];
|
|
salt->salt_buf[3] = pdf->id_buf[3];
|
|
salt->salt_buf[4] = pdf->u_buf[0];
|
|
salt->salt_buf[5] = pdf->u_buf[1];
|
|
salt->salt_buf[6] = pdf->o_buf[0];
|
|
salt->salt_buf[7] = pdf->o_buf[1];
|
|
salt->salt_len = pdf->id_len + 16;
|
|
|
|
digest[0] = pdf->rc4key[0];
|
|
digest[1] = pdf->rc4key[1];
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int pdf14_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10500) || (input_len > DISPLAY_LEN_MAX_10500)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_PDF, input_buf, 5)) && (memcmp (SIGNATURE_PDF, input_buf, 5))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pdf_t *pdf = (pdf_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *V_pos = input_buf + 5;
|
|
|
|
char *R_pos = strchr (V_pos, '*');
|
|
|
|
if (R_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t V_len = R_pos - V_pos;
|
|
|
|
R_pos++;
|
|
|
|
char *bits_pos = strchr (R_pos, '*');
|
|
|
|
if (bits_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t R_len = bits_pos - R_pos;
|
|
|
|
bits_pos++;
|
|
|
|
char *P_pos = strchr (bits_pos, '*');
|
|
|
|
if (P_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t bits_len = P_pos - bits_pos;
|
|
|
|
P_pos++;
|
|
|
|
char *enc_md_pos = strchr (P_pos, '*');
|
|
|
|
if (enc_md_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t P_len = enc_md_pos - P_pos;
|
|
|
|
enc_md_pos++;
|
|
|
|
char *id_len_pos = strchr (enc_md_pos, '*');
|
|
|
|
if (id_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t enc_md_len = id_len_pos - enc_md_pos;
|
|
|
|
id_len_pos++;
|
|
|
|
char *id_buf_pos = strchr (id_len_pos, '*');
|
|
|
|
if (id_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t id_len_len = id_buf_pos - id_len_pos;
|
|
|
|
id_buf_pos++;
|
|
|
|
char *u_len_pos = strchr (id_buf_pos, '*');
|
|
|
|
if (u_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t id_buf_len = u_len_pos - id_buf_pos;
|
|
|
|
if ((id_buf_len != 32) && (id_buf_len != 64)) return (PARSER_SALT_LENGTH);
|
|
|
|
u_len_pos++;
|
|
|
|
char *u_buf_pos = strchr (u_len_pos, '*');
|
|
|
|
if (u_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t u_len_len = u_buf_pos - u_len_pos;
|
|
|
|
u_buf_pos++;
|
|
|
|
char *o_len_pos = strchr (u_buf_pos, '*');
|
|
|
|
if (o_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t u_buf_len = o_len_pos - u_buf_pos;
|
|
|
|
if (u_buf_len != 64) return (PARSER_SALT_LENGTH);
|
|
|
|
o_len_pos++;
|
|
|
|
char *o_buf_pos = strchr (o_len_pos, '*');
|
|
|
|
if (o_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t o_len_len = o_buf_pos - o_len_pos;
|
|
|
|
o_buf_pos++;
|
|
|
|
uint32_t o_buf_len = input_len - 5 - V_len - 1 - R_len - 1 - bits_len - 1 - P_len - 1 - enc_md_len - 1 - id_len_len - 1 - id_buf_len - 1 - u_len_len - 1 - u_buf_len - 1 - o_len_len - 1;
|
|
|
|
if (o_buf_len != 64) return (PARSER_SALT_LENGTH);
|
|
|
|
// validate data
|
|
|
|
const int V = atoi (V_pos);
|
|
const int R = atoi (R_pos);
|
|
const int P = atoi (P_pos);
|
|
|
|
int vr_ok = 0;
|
|
|
|
if ((V == 2) && (R == 3)) vr_ok = 1;
|
|
if ((V == 4) && (R == 4)) vr_ok = 1;
|
|
|
|
if (vr_ok == 0) return (PARSER_SALT_VALUE);
|
|
|
|
const int id_len = atoi (id_len_pos);
|
|
const int u_len = atoi (u_len_pos);
|
|
const int o_len = atoi (o_len_pos);
|
|
|
|
if ((id_len != 16) && (id_len != 32)) return (PARSER_SALT_VALUE);
|
|
|
|
if (u_len != 32) return (PARSER_SALT_VALUE);
|
|
if (o_len != 32) return (PARSER_SALT_VALUE);
|
|
|
|
const int bits = atoi (bits_pos);
|
|
|
|
if (bits != 128) return (PARSER_SALT_VALUE);
|
|
|
|
int enc_md = 1;
|
|
|
|
if (R >= 4)
|
|
{
|
|
enc_md = atoi (enc_md_pos);
|
|
}
|
|
|
|
// copy data to esalt
|
|
|
|
pdf->V = V;
|
|
pdf->R = R;
|
|
pdf->P = P;
|
|
|
|
pdf->enc_md = enc_md;
|
|
|
|
pdf->id_buf[0] = hex_to_uint (&id_buf_pos[ 0]);
|
|
pdf->id_buf[1] = hex_to_uint (&id_buf_pos[ 8]);
|
|
pdf->id_buf[2] = hex_to_uint (&id_buf_pos[16]);
|
|
pdf->id_buf[3] = hex_to_uint (&id_buf_pos[24]);
|
|
|
|
if (id_len == 32)
|
|
{
|
|
pdf->id_buf[4] = hex_to_uint (&id_buf_pos[32]);
|
|
pdf->id_buf[5] = hex_to_uint (&id_buf_pos[40]);
|
|
pdf->id_buf[6] = hex_to_uint (&id_buf_pos[48]);
|
|
pdf->id_buf[7] = hex_to_uint (&id_buf_pos[56]);
|
|
}
|
|
|
|
pdf->id_len = id_len;
|
|
|
|
pdf->u_buf[0] = hex_to_uint (&u_buf_pos[ 0]);
|
|
pdf->u_buf[1] = hex_to_uint (&u_buf_pos[ 8]);
|
|
pdf->u_buf[2] = hex_to_uint (&u_buf_pos[16]);
|
|
pdf->u_buf[3] = hex_to_uint (&u_buf_pos[24]);
|
|
pdf->u_buf[4] = hex_to_uint (&u_buf_pos[32]);
|
|
pdf->u_buf[5] = hex_to_uint (&u_buf_pos[40]);
|
|
pdf->u_buf[6] = hex_to_uint (&u_buf_pos[48]);
|
|
pdf->u_buf[7] = hex_to_uint (&u_buf_pos[56]);
|
|
pdf->u_len = u_len;
|
|
|
|
pdf->o_buf[0] = hex_to_uint (&o_buf_pos[ 0]);
|
|
pdf->o_buf[1] = hex_to_uint (&o_buf_pos[ 8]);
|
|
pdf->o_buf[2] = hex_to_uint (&o_buf_pos[16]);
|
|
pdf->o_buf[3] = hex_to_uint (&o_buf_pos[24]);
|
|
pdf->o_buf[4] = hex_to_uint (&o_buf_pos[32]);
|
|
pdf->o_buf[5] = hex_to_uint (&o_buf_pos[40]);
|
|
pdf->o_buf[6] = hex_to_uint (&o_buf_pos[48]);
|
|
pdf->o_buf[7] = hex_to_uint (&o_buf_pos[56]);
|
|
pdf->o_len = o_len;
|
|
|
|
pdf->id_buf[0] = byte_swap_32 (pdf->id_buf[0]);
|
|
pdf->id_buf[1] = byte_swap_32 (pdf->id_buf[1]);
|
|
pdf->id_buf[2] = byte_swap_32 (pdf->id_buf[2]);
|
|
pdf->id_buf[3] = byte_swap_32 (pdf->id_buf[3]);
|
|
|
|
if (id_len == 32)
|
|
{
|
|
pdf->id_buf[4] = byte_swap_32 (pdf->id_buf[4]);
|
|
pdf->id_buf[5] = byte_swap_32 (pdf->id_buf[5]);
|
|
pdf->id_buf[6] = byte_swap_32 (pdf->id_buf[6]);
|
|
pdf->id_buf[7] = byte_swap_32 (pdf->id_buf[7]);
|
|
}
|
|
|
|
pdf->u_buf[0] = byte_swap_32 (pdf->u_buf[0]);
|
|
pdf->u_buf[1] = byte_swap_32 (pdf->u_buf[1]);
|
|
pdf->u_buf[2] = byte_swap_32 (pdf->u_buf[2]);
|
|
pdf->u_buf[3] = byte_swap_32 (pdf->u_buf[3]);
|
|
pdf->u_buf[4] = byte_swap_32 (pdf->u_buf[4]);
|
|
pdf->u_buf[5] = byte_swap_32 (pdf->u_buf[5]);
|
|
pdf->u_buf[6] = byte_swap_32 (pdf->u_buf[6]);
|
|
pdf->u_buf[7] = byte_swap_32 (pdf->u_buf[7]);
|
|
|
|
pdf->o_buf[0] = byte_swap_32 (pdf->o_buf[0]);
|
|
pdf->o_buf[1] = byte_swap_32 (pdf->o_buf[1]);
|
|
pdf->o_buf[2] = byte_swap_32 (pdf->o_buf[2]);
|
|
pdf->o_buf[3] = byte_swap_32 (pdf->o_buf[3]);
|
|
pdf->o_buf[4] = byte_swap_32 (pdf->o_buf[4]);
|
|
pdf->o_buf[5] = byte_swap_32 (pdf->o_buf[5]);
|
|
pdf->o_buf[6] = byte_swap_32 (pdf->o_buf[6]);
|
|
pdf->o_buf[7] = byte_swap_32 (pdf->o_buf[7]);
|
|
|
|
// precompute rc4 data for later use
|
|
|
|
uint padding[8] =
|
|
{
|
|
0x5e4ebf28,
|
|
0x418a754e,
|
|
0x564e0064,
|
|
0x0801faff,
|
|
0xb6002e2e,
|
|
0x803e68d0,
|
|
0xfea90c2f,
|
|
0x7a695364
|
|
};
|
|
|
|
// md5
|
|
|
|
uint salt_pc_block[32];
|
|
|
|
char *salt_pc_ptr = (char *) salt_pc_block;
|
|
|
|
memcpy (salt_pc_ptr, padding, 32);
|
|
memcpy (salt_pc_ptr + 32, pdf->id_buf, pdf->id_len);
|
|
|
|
uint salt_pc_digest[4];
|
|
|
|
md5_complete_no_limit (salt_pc_digest, salt_pc_block, 32 + pdf->id_len);
|
|
|
|
pdf->rc4data[0] = salt_pc_digest[0];
|
|
pdf->rc4data[1] = salt_pc_digest[1];
|
|
|
|
// we use ID for salt, maybe needs to change, we will see...
|
|
|
|
salt->salt_buf[0] = pdf->id_buf[0];
|
|
salt->salt_buf[1] = pdf->id_buf[1];
|
|
salt->salt_buf[2] = pdf->id_buf[2];
|
|
salt->salt_buf[3] = pdf->id_buf[3];
|
|
salt->salt_buf[4] = pdf->u_buf[0];
|
|
salt->salt_buf[5] = pdf->u_buf[1];
|
|
salt->salt_buf[6] = pdf->o_buf[0];
|
|
salt->salt_buf[7] = pdf->o_buf[1];
|
|
salt->salt_len = pdf->id_len + 16;
|
|
|
|
salt->salt_iter = ROUNDS_PDF14;
|
|
|
|
digest[0] = pdf->u_buf[0];
|
|
digest[1] = pdf->u_buf[1];
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int pdf17l3_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
int ret = pdf17l8_parse_hash (input_buf, input_len, hash_buf);
|
|
|
|
if (ret != PARSER_OK)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] -= SHA256M_A;
|
|
digest[1] -= SHA256M_B;
|
|
digest[2] -= SHA256M_C;
|
|
digest[3] -= SHA256M_D;
|
|
digest[4] -= SHA256M_E;
|
|
digest[5] -= SHA256M_F;
|
|
digest[6] -= SHA256M_G;
|
|
digest[7] -= SHA256M_H;
|
|
|
|
salt->salt_buf[2] = 0x80;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int pdf17l8_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10600) || (input_len > DISPLAY_LEN_MAX_10600)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if ((memcmp (SIGNATURE_PDF, input_buf, 5)) && (memcmp (SIGNATURE_PDF, input_buf, 5))) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pdf_t *pdf = (pdf_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *V_pos = input_buf + 5;
|
|
|
|
char *R_pos = strchr (V_pos, '*');
|
|
|
|
if (R_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t V_len = R_pos - V_pos;
|
|
|
|
R_pos++;
|
|
|
|
char *bits_pos = strchr (R_pos, '*');
|
|
|
|
if (bits_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t R_len = bits_pos - R_pos;
|
|
|
|
bits_pos++;
|
|
|
|
char *P_pos = strchr (bits_pos, '*');
|
|
|
|
if (P_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t bits_len = P_pos - bits_pos;
|
|
|
|
P_pos++;
|
|
|
|
char *enc_md_pos = strchr (P_pos, '*');
|
|
|
|
if (enc_md_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t P_len = enc_md_pos - P_pos;
|
|
|
|
enc_md_pos++;
|
|
|
|
char *id_len_pos = strchr (enc_md_pos, '*');
|
|
|
|
if (id_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t enc_md_len = id_len_pos - enc_md_pos;
|
|
|
|
id_len_pos++;
|
|
|
|
char *id_buf_pos = strchr (id_len_pos, '*');
|
|
|
|
if (id_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t id_len_len = id_buf_pos - id_len_pos;
|
|
|
|
id_buf_pos++;
|
|
|
|
char *u_len_pos = strchr (id_buf_pos, '*');
|
|
|
|
if (u_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t id_buf_len = u_len_pos - id_buf_pos;
|
|
|
|
u_len_pos++;
|
|
|
|
char *u_buf_pos = strchr (u_len_pos, '*');
|
|
|
|
if (u_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t u_len_len = u_buf_pos - u_len_pos;
|
|
|
|
u_buf_pos++;
|
|
|
|
char *o_len_pos = strchr (u_buf_pos, '*');
|
|
|
|
if (o_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t u_buf_len = o_len_pos - u_buf_pos;
|
|
|
|
o_len_pos++;
|
|
|
|
char *o_buf_pos = strchr (o_len_pos, '*');
|
|
|
|
if (o_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t o_len_len = o_buf_pos - o_len_pos;
|
|
|
|
o_buf_pos++;
|
|
|
|
char *last = strchr (o_buf_pos, '*');
|
|
|
|
if (last == NULL) last = input_buf + input_len;
|
|
|
|
uint32_t o_buf_len = last - o_buf_pos;
|
|
|
|
// validate data
|
|
|
|
const int V = atoi (V_pos);
|
|
const int R = atoi (R_pos);
|
|
|
|
int vr_ok = 0;
|
|
|
|
if ((V == 5) && (R == 5)) vr_ok = 1;
|
|
if ((V == 5) && (R == 6)) vr_ok = 1;
|
|
|
|
if (vr_ok == 0) return (PARSER_SALT_VALUE);
|
|
|
|
const int bits = atoi (bits_pos);
|
|
|
|
if (bits != 256) return (PARSER_SALT_VALUE);
|
|
|
|
int enc_md = atoi (enc_md_pos);
|
|
|
|
if (enc_md != 1) return (PARSER_SALT_VALUE);
|
|
|
|
const uint id_len = atoi (id_len_pos);
|
|
const uint u_len = atoi (u_len_pos);
|
|
const uint o_len = atoi (o_len_pos);
|
|
|
|
if (V_len > 6) return (PARSER_SALT_LENGTH);
|
|
if (R_len > 6) return (PARSER_SALT_LENGTH);
|
|
if (P_len > 6) return (PARSER_SALT_LENGTH);
|
|
if (id_len_len > 6) return (PARSER_SALT_LENGTH);
|
|
if (u_len_len > 6) return (PARSER_SALT_LENGTH);
|
|
if (o_len_len > 6) return (PARSER_SALT_LENGTH);
|
|
if (bits_len > 6) return (PARSER_SALT_LENGTH);
|
|
if (enc_md_len > 6) return (PARSER_SALT_LENGTH);
|
|
|
|
if ((id_len * 2) != id_buf_len) return (PARSER_SALT_VALUE);
|
|
if ((u_len * 2) != u_buf_len) return (PARSER_SALT_VALUE);
|
|
if ((o_len * 2) != o_buf_len) return (PARSER_SALT_VALUE);
|
|
|
|
// copy data to esalt
|
|
|
|
if (u_len < 40) return (PARSER_SALT_VALUE);
|
|
|
|
for (int i = 0, j = 0; i < 8 + 2; i += 1, j += 8)
|
|
{
|
|
pdf->u_buf[i] = hex_to_uint (&u_buf_pos[j]);
|
|
}
|
|
|
|
salt->salt_buf[0] = pdf->u_buf[8];
|
|
salt->salt_buf[1] = pdf->u_buf[9];
|
|
|
|
salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]);
|
|
salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]);
|
|
|
|
salt->salt_len = 8;
|
|
salt->salt_iter = ROUNDS_PDF17L8;
|
|
|
|
digest[0] = pdf->u_buf[0];
|
|
digest[1] = pdf->u_buf[1];
|
|
digest[2] = pdf->u_buf[2];
|
|
digest[3] = pdf->u_buf[3];
|
|
digest[4] = pdf->u_buf[4];
|
|
digest[5] = pdf->u_buf[5];
|
|
digest[6] = pdf->u_buf[6];
|
|
digest[7] = pdf->u_buf[7];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int pbkdf2_sha256_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_10900) || (input_len > DISPLAY_LEN_MAX_10900)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_PBKDF2_SHA256, input_buf, 7)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pbkdf2_sha256_t *pbkdf2_sha256 = (pbkdf2_sha256_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
// iterations
|
|
|
|
char *iter_pos = input_buf + 7;
|
|
|
|
uint32_t iter = atoi (iter_pos);
|
|
|
|
if (iter < 1) return (PARSER_SALT_ITERATION);
|
|
if (iter > 999999) return (PARSER_SALT_ITERATION);
|
|
|
|
// first is *raw* salt
|
|
|
|
char *salt_pos = strchr (iter_pos, ':');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, ':');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len > 64) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
uint32_t hash_b64_len = input_len - (hash_pos - input_buf);
|
|
|
|
if (hash_b64_len > 88) return (PARSER_HASH_LENGTH);
|
|
|
|
// decode salt
|
|
|
|
char *salt_buf_ptr = (char *) pbkdf2_sha256->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt_buf_ptr[salt_len + 3] = 0x01;
|
|
salt_buf_ptr[salt_len + 4] = 0x80;
|
|
|
|
salt->salt_len = salt_len;
|
|
salt->salt_iter = iter - 1;
|
|
|
|
// decode hash
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
int hash_len = base64_decode (base64_to_int, hash_pos, hash_b64_len, tmp_buf);
|
|
|
|
if (hash_len < 16) return (PARSER_HASH_LENGTH);
|
|
|
|
memcpy (digest, tmp_buf, 16);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
// add some stuff to normal salt to make sorted happy
|
|
|
|
salt->salt_buf[0] = pbkdf2_sha256->salt_buf[0];
|
|
salt->salt_buf[1] = pbkdf2_sha256->salt_buf[1];
|
|
salt->salt_buf[2] = pbkdf2_sha256->salt_buf[2];
|
|
salt->salt_buf[3] = pbkdf2_sha256->salt_buf[3];
|
|
salt->salt_buf[4] = salt->salt_iter;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int prestashop_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11000) || (input_len > DISPLAY_LEN_MAX_11000)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
if (input_buf[32] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 32 - 1;
|
|
|
|
char *salt_buf = input_buf + 32 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int postgresql_auth_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11100) || (input_len > DISPLAY_LEN_MAX_11100)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_POSTGRESQL_AUTH, input_buf, 10)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *user_pos = input_buf + 10;
|
|
|
|
char *salt_pos = strchr (user_pos, '*');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, '*');
|
|
|
|
hash_pos++;
|
|
|
|
uint hash_len = input_len - (hash_pos - input_buf);
|
|
|
|
if (hash_len != 32) return (PARSER_HASH_LENGTH);
|
|
|
|
uint user_len = salt_pos - user_pos - 1;
|
|
|
|
uint salt_len = hash_pos - salt_pos - 1;
|
|
|
|
if (salt_len != 8) return (PARSER_SALT_LENGTH);
|
|
|
|
/*
|
|
* store digest
|
|
*/
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
digest[0] -= MD5M_A;
|
|
digest[1] -= MD5M_B;
|
|
digest[2] -= MD5M_C;
|
|
digest[3] -= MD5M_D;
|
|
|
|
/*
|
|
* store salt
|
|
*/
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
// first 4 bytes are the "challenge"
|
|
|
|
salt_buf_ptr[0] = hex_to_char (&salt_pos[0]);
|
|
salt_buf_ptr[1] = hex_to_char (&salt_pos[2]);
|
|
salt_buf_ptr[2] = hex_to_char (&salt_pos[4]);
|
|
salt_buf_ptr[3] = hex_to_char (&salt_pos[6]);
|
|
|
|
// append the user name
|
|
|
|
user_len = parse_and_store_salt (salt_buf_ptr + 4, user_pos, user_len);
|
|
|
|
salt->salt_len = 4 + user_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int mysql_auth_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11200) || (input_len > DISPLAY_LEN_MAX_11200)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_MYSQL_AUTH, input_buf, 9)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
char *salt_pos = input_buf + 9;
|
|
|
|
char *hash_pos = strchr (salt_pos, '*');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
hash_pos++;
|
|
|
|
uint hash_len = input_len - (hash_pos - input_buf);
|
|
|
|
if (hash_len != 40) return (PARSER_HASH_LENGTH);
|
|
|
|
uint salt_len = hash_pos - salt_pos - 1;
|
|
|
|
if (salt_len != 40) return (PARSER_SALT_LENGTH);
|
|
|
|
/*
|
|
* store digest
|
|
*/
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_pos[32]);
|
|
|
|
/*
|
|
* store salt
|
|
*/
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int bitcoin_wallet_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11300) || (input_len > DISPLAY_LEN_MAX_11300)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_BITCOIN_WALLET, input_buf, 9)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
bitcoin_wallet_t *bitcoin_wallet = (bitcoin_wallet_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *cry_master_len_pos = input_buf + 9;
|
|
|
|
char *cry_master_buf_pos = strchr (cry_master_len_pos, '$');
|
|
|
|
if (cry_master_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t cry_master_len_len = cry_master_buf_pos - cry_master_len_pos;
|
|
|
|
cry_master_buf_pos++;
|
|
|
|
char *cry_salt_len_pos = strchr (cry_master_buf_pos, '$');
|
|
|
|
if (cry_salt_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t cry_master_buf_len = cry_salt_len_pos - cry_master_buf_pos;
|
|
|
|
cry_salt_len_pos++;
|
|
|
|
char *cry_salt_buf_pos = strchr (cry_salt_len_pos, '$');
|
|
|
|
if (cry_salt_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t cry_salt_len_len = cry_salt_buf_pos - cry_salt_len_pos;
|
|
|
|
cry_salt_buf_pos++;
|
|
|
|
char *cry_rounds_pos = strchr (cry_salt_buf_pos, '$');
|
|
|
|
if (cry_rounds_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t cry_salt_buf_len = cry_rounds_pos - cry_salt_buf_pos;
|
|
|
|
cry_rounds_pos++;
|
|
|
|
char *ckey_len_pos = strchr (cry_rounds_pos, '$');
|
|
|
|
if (ckey_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t cry_rounds_len = ckey_len_pos - cry_rounds_pos;
|
|
|
|
ckey_len_pos++;
|
|
|
|
char *ckey_buf_pos = strchr (ckey_len_pos, '$');
|
|
|
|
if (ckey_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t ckey_len_len = ckey_buf_pos - ckey_len_pos;
|
|
|
|
ckey_buf_pos++;
|
|
|
|
char *public_key_len_pos = strchr (ckey_buf_pos, '$');
|
|
|
|
if (public_key_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t ckey_buf_len = public_key_len_pos - ckey_buf_pos;
|
|
|
|
public_key_len_pos++;
|
|
|
|
char *public_key_buf_pos = strchr (public_key_len_pos, '$');
|
|
|
|
if (public_key_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t public_key_len_len = public_key_buf_pos - public_key_len_pos;
|
|
|
|
public_key_buf_pos++;
|
|
|
|
uint32_t public_key_buf_len = input_len - 1 - 7 - 1 - cry_master_len_len - 1 - cry_master_buf_len - 1 - cry_salt_len_len - 1 - cry_salt_buf_len - 1 - cry_rounds_len - 1 - ckey_len_len - 1 - ckey_buf_len - 1 - public_key_len_len - 1;
|
|
|
|
const uint cry_master_len = atoi (cry_master_len_pos);
|
|
const uint cry_salt_len = atoi (cry_salt_len_pos);
|
|
const uint ckey_len = atoi (ckey_len_pos);
|
|
const uint public_key_len = atoi (public_key_len_pos);
|
|
|
|
if (cry_master_buf_len != cry_master_len) return (PARSER_SALT_VALUE);
|
|
if (cry_salt_buf_len != cry_salt_len) return (PARSER_SALT_VALUE);
|
|
if (ckey_buf_len != ckey_len) return (PARSER_SALT_VALUE);
|
|
if (public_key_buf_len != public_key_len) return (PARSER_SALT_VALUE);
|
|
|
|
for (uint i = 0, j = 0; i < cry_master_len; i += 1, j += 8)
|
|
{
|
|
bitcoin_wallet->cry_master_buf[i] = hex_to_uint (&cry_master_buf_pos[j]);
|
|
|
|
bitcoin_wallet->cry_master_buf[i] = byte_swap_32 (bitcoin_wallet->cry_master_buf[i]);
|
|
}
|
|
|
|
for (uint i = 0, j = 0; i < ckey_len; i += 1, j += 8)
|
|
{
|
|
bitcoin_wallet->ckey_buf[i] = hex_to_uint (&ckey_buf_pos[j]);
|
|
|
|
bitcoin_wallet->ckey_buf[i] = byte_swap_32 (bitcoin_wallet->ckey_buf[i]);
|
|
}
|
|
|
|
for (uint i = 0, j = 0; i < public_key_len; i += 1, j += 8)
|
|
{
|
|
bitcoin_wallet->public_key_buf[i] = hex_to_uint (&public_key_buf_pos[j]);
|
|
|
|
bitcoin_wallet->public_key_buf[i] = byte_swap_32 (bitcoin_wallet->public_key_buf[i]);
|
|
}
|
|
|
|
bitcoin_wallet->cry_master_len = cry_master_len / 2;
|
|
bitcoin_wallet->ckey_len = ckey_len / 2;
|
|
bitcoin_wallet->public_key_len = public_key_len / 2;
|
|
|
|
/*
|
|
* store digest (should be unique enought, hopefully)
|
|
*/
|
|
|
|
digest[0] = bitcoin_wallet->cry_master_buf[0];
|
|
digest[1] = bitcoin_wallet->cry_master_buf[1];
|
|
digest[2] = bitcoin_wallet->cry_master_buf[2];
|
|
digest[3] = bitcoin_wallet->cry_master_buf[3];
|
|
|
|
/*
|
|
* store salt
|
|
*/
|
|
|
|
if (cry_rounds_len >= 7) return (PARSER_SALT_VALUE);
|
|
|
|
const uint cry_rounds = atoi (cry_rounds_pos);
|
|
|
|
salt->salt_iter = cry_rounds - 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
const uint salt_len = parse_and_store_salt (salt_buf_ptr, cry_salt_buf_pos, cry_salt_buf_len);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int sip_auth_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11400) || (input_len > DISPLAY_LEN_MAX_11400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SIP_AUTH, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
sip_t *sip = (sip_t *) hash_buf->esalt;
|
|
|
|
// work with a temporary copy of input_buf (s.t. we can manipulate it directly)
|
|
|
|
char temp_input_buf[input_len + 1];
|
|
|
|
memset (temp_input_buf, 0, sizeof (temp_input_buf));
|
|
memcpy (temp_input_buf, input_buf, input_len);
|
|
|
|
// URI_server:
|
|
|
|
char *URI_server_pos = temp_input_buf + 6;
|
|
|
|
char *URI_client_pos = strchr (URI_server_pos, '*');
|
|
|
|
if (URI_client_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
URI_client_pos[0] = 0;
|
|
URI_client_pos++;
|
|
|
|
uint URI_server_len = strlen (URI_server_pos);
|
|
|
|
if (URI_server_len > 512) return (PARSER_SALT_LENGTH);
|
|
|
|
// URI_client:
|
|
|
|
char *user_pos = strchr (URI_client_pos, '*');
|
|
|
|
if (user_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
user_pos[0] = 0;
|
|
user_pos++;
|
|
|
|
uint URI_client_len = strlen (URI_client_pos);
|
|
|
|
if (URI_client_len > 512) return (PARSER_SALT_LENGTH);
|
|
|
|
// user:
|
|
|
|
char *realm_pos = strchr (user_pos, '*');
|
|
|
|
if (realm_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
realm_pos[0] = 0;
|
|
realm_pos++;
|
|
|
|
uint user_len = strlen (user_pos);
|
|
|
|
if (user_len > 116) return (PARSER_SALT_LENGTH);
|
|
|
|
// realm:
|
|
|
|
char *method_pos = strchr (realm_pos, '*');
|
|
|
|
if (method_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
method_pos[0] = 0;
|
|
method_pos++;
|
|
|
|
uint realm_len = strlen (realm_pos);
|
|
|
|
if (realm_len > 116) return (PARSER_SALT_LENGTH);
|
|
|
|
// method:
|
|
|
|
char *URI_prefix_pos = strchr (method_pos, '*');
|
|
|
|
if (URI_prefix_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
URI_prefix_pos[0] = 0;
|
|
URI_prefix_pos++;
|
|
|
|
uint method_len = strlen (method_pos);
|
|
|
|
if (method_len > 246) return (PARSER_SALT_LENGTH);
|
|
|
|
// URI_prefix:
|
|
|
|
char *URI_resource_pos = strchr (URI_prefix_pos, '*');
|
|
|
|
if (URI_resource_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
URI_resource_pos[0] = 0;
|
|
URI_resource_pos++;
|
|
|
|
uint URI_prefix_len = strlen (URI_prefix_pos);
|
|
|
|
if (URI_prefix_len > 245) return (PARSER_SALT_LENGTH);
|
|
|
|
// URI_resource:
|
|
|
|
char *URI_suffix_pos = strchr (URI_resource_pos, '*');
|
|
|
|
if (URI_suffix_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
URI_suffix_pos[0] = 0;
|
|
URI_suffix_pos++;
|
|
|
|
uint URI_resource_len = strlen (URI_resource_pos);
|
|
|
|
if (URI_resource_len < 1) return (PARSER_SALT_LENGTH);
|
|
if (URI_resource_len > 246) return (PARSER_SALT_LENGTH);
|
|
|
|
// URI_suffix:
|
|
|
|
char *nonce_pos = strchr (URI_suffix_pos, '*');
|
|
|
|
if (nonce_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
nonce_pos[0] = 0;
|
|
nonce_pos++;
|
|
|
|
uint URI_suffix_len = strlen (URI_suffix_pos);
|
|
|
|
if (URI_suffix_len > 245) return (PARSER_SALT_LENGTH);
|
|
|
|
// nonce:
|
|
|
|
char *nonce_client_pos = strchr (nonce_pos, '*');
|
|
|
|
if (nonce_client_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
nonce_client_pos[0] = 0;
|
|
nonce_client_pos++;
|
|
|
|
uint nonce_len = strlen (nonce_pos);
|
|
|
|
if (nonce_len < 1) return (PARSER_SALT_LENGTH);
|
|
if (nonce_len > 50) return (PARSER_SALT_LENGTH);
|
|
|
|
// nonce_client:
|
|
|
|
char *nonce_count_pos = strchr (nonce_client_pos, '*');
|
|
|
|
if (nonce_count_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
nonce_count_pos[0] = 0;
|
|
nonce_count_pos++;
|
|
|
|
uint nonce_client_len = strlen (nonce_client_pos);
|
|
|
|
if (nonce_client_len > 50) return (PARSER_SALT_LENGTH);
|
|
|
|
// nonce_count:
|
|
|
|
char *qop_pos = strchr (nonce_count_pos, '*');
|
|
|
|
if (qop_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
qop_pos[0] = 0;
|
|
qop_pos++;
|
|
|
|
uint nonce_count_len = strlen (nonce_count_pos);
|
|
|
|
if (nonce_count_len > 50) return (PARSER_SALT_LENGTH);
|
|
|
|
// qop:
|
|
|
|
char *directive_pos = strchr (qop_pos, '*');
|
|
|
|
if (directive_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
directive_pos[0] = 0;
|
|
directive_pos++;
|
|
|
|
uint qop_len = strlen (qop_pos);
|
|
|
|
if (qop_len > 50) return (PARSER_SALT_LENGTH);
|
|
|
|
// directive
|
|
|
|
char *digest_pos = strchr (directive_pos, '*');
|
|
|
|
if (digest_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
digest_pos[0] = 0;
|
|
digest_pos++;
|
|
|
|
uint directive_len = strlen (directive_pos);
|
|
|
|
if (directive_len != 3) return (PARSER_SALT_LENGTH);
|
|
|
|
if (memcmp (directive_pos, "MD5", 3))
|
|
{
|
|
log_info ("ERROR: only the MD5 directive is currently supported\n");
|
|
|
|
return (PARSER_SIP_AUTH_DIRECTIVE);
|
|
}
|
|
|
|
/*
|
|
* first (pre-)compute: HA2 = md5 ($method . ":" . $uri)
|
|
*/
|
|
|
|
uint md5_len = 0;
|
|
|
|
uint md5_max_len = 4 * 64;
|
|
|
|
uint md5_remaining_len = md5_max_len;
|
|
|
|
uint tmp_md5_buf[md5_max_len / 4];
|
|
|
|
memset (tmp_md5_buf, 0, sizeof (tmp_md5_buf));
|
|
|
|
char *tmp_md5_ptr = (char *) tmp_md5_buf;
|
|
|
|
snprintf (tmp_md5_ptr, md5_remaining_len, "%s:", method_pos);
|
|
|
|
md5_len += method_len + 1;
|
|
tmp_md5_ptr += method_len + 1;
|
|
|
|
if (URI_prefix_len > 0)
|
|
{
|
|
md5_remaining_len = md5_max_len - md5_len;
|
|
|
|
snprintf (tmp_md5_ptr, md5_remaining_len + 1, "%s:", URI_prefix_pos);
|
|
|
|
md5_len += URI_prefix_len + 1;
|
|
tmp_md5_ptr += URI_prefix_len + 1;
|
|
}
|
|
|
|
md5_remaining_len = md5_max_len - md5_len;
|
|
|
|
snprintf (tmp_md5_ptr, md5_remaining_len + 1, "%s", URI_resource_pos);
|
|
|
|
md5_len += URI_resource_len;
|
|
tmp_md5_ptr += URI_resource_len;
|
|
|
|
if (URI_suffix_len > 0)
|
|
{
|
|
md5_remaining_len = md5_max_len - md5_len;
|
|
|
|
snprintf (tmp_md5_ptr, md5_remaining_len + 1, ":%s", URI_suffix_pos);
|
|
|
|
md5_len += 1 + URI_suffix_len;
|
|
}
|
|
|
|
uint tmp_digest[4];
|
|
|
|
md5_complete_no_limit (tmp_digest, tmp_md5_buf, md5_len);
|
|
|
|
tmp_digest[0] = byte_swap_32 (tmp_digest[0]);
|
|
tmp_digest[1] = byte_swap_32 (tmp_digest[1]);
|
|
tmp_digest[2] = byte_swap_32 (tmp_digest[2]);
|
|
tmp_digest[3] = byte_swap_32 (tmp_digest[3]);
|
|
|
|
/*
|
|
* esalt
|
|
*/
|
|
|
|
char *esalt_buf_ptr = (char *) sip->esalt_buf;
|
|
|
|
uint esalt_len = 0;
|
|
|
|
uint max_esalt_len = sizeof (sip->esalt_buf); // 151 = (64 + 64 + 55) - 32, where 32 is the hexadecimal MD5 HA1 hash
|
|
|
|
// there are 2 possibilities for the esalt:
|
|
|
|
if ((strcmp (qop_pos, "auth") == 0) || (strcmp (qop_pos, "auth-int") == 0))
|
|
{
|
|
esalt_len = 1 + nonce_len + 1 + nonce_count_len + 1 + nonce_client_len + 1 + qop_len + 1 + 32;
|
|
|
|
if (esalt_len > max_esalt_len) return (PARSER_SALT_LENGTH);
|
|
|
|
snprintf (esalt_buf_ptr, max_esalt_len, ":%s:%s:%s:%s:%08x%08x%08x%08x",
|
|
nonce_pos,
|
|
nonce_count_pos,
|
|
nonce_client_pos,
|
|
qop_pos,
|
|
tmp_digest[0],
|
|
tmp_digest[1],
|
|
tmp_digest[2],
|
|
tmp_digest[3]);
|
|
}
|
|
else
|
|
{
|
|
esalt_len = 1 + nonce_len + 1 + 32;
|
|
|
|
if (esalt_len > max_esalt_len) return (PARSER_SALT_LENGTH);
|
|
|
|
snprintf (esalt_buf_ptr, max_esalt_len, ":%s:%08x%08x%08x%08x",
|
|
nonce_pos,
|
|
tmp_digest[0],
|
|
tmp_digest[1],
|
|
tmp_digest[2],
|
|
tmp_digest[3]);
|
|
}
|
|
|
|
// add 0x80 to esalt
|
|
|
|
esalt_buf_ptr[esalt_len] = 0x80;
|
|
|
|
sip->esalt_len = esalt_len;
|
|
|
|
/*
|
|
* actual salt
|
|
*/
|
|
|
|
char *sip_salt_ptr = (char *) sip->salt_buf;
|
|
|
|
uint salt_len = user_len + 1 + realm_len + 1;
|
|
|
|
uint max_salt_len = 119;
|
|
|
|
if (salt_len > max_salt_len) return (PARSER_SALT_LENGTH);
|
|
|
|
snprintf (sip_salt_ptr, max_salt_len + 1, "%s:%s:", user_pos, realm_pos);
|
|
|
|
sip->salt_len = salt_len;
|
|
|
|
/*
|
|
* fake salt (for sorting)
|
|
*/
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
max_salt_len = 55;
|
|
|
|
uint fake_salt_len = salt_len;
|
|
|
|
if (fake_salt_len > max_salt_len)
|
|
{
|
|
fake_salt_len = max_salt_len;
|
|
}
|
|
|
|
snprintf (salt_buf_ptr, max_salt_len + 1, "%s:%s:", user_pos, realm_pos);
|
|
|
|
salt->salt_len = fake_salt_len;
|
|
|
|
/*
|
|
* digest
|
|
*/
|
|
|
|
digest[0] = hex_to_uint (&digest_pos[ 0]);
|
|
digest[1] = hex_to_uint (&digest_pos[ 8]);
|
|
digest[2] = hex_to_uint (&digest_pos[16]);
|
|
digest[3] = hex_to_uint (&digest_pos[24]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int crc32_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11500) || (input_len > DISPLAY_LEN_MAX_11500)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (input_buf[8] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
// digest
|
|
|
|
char *digest_pos = input_buf;
|
|
|
|
digest[0] = hex_to_uint (&digest_pos[0]);
|
|
digest[1] = 0;
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
// salt
|
|
|
|
char *salt_buf = input_buf + 8 + 1;
|
|
|
|
uint salt_len = 8;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int seven_zip_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11600) || (input_len > DISPLAY_LEN_MAX_11600)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_SEVEN_ZIP, input_buf, 4)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
seven_zip_t *seven_zip = (seven_zip_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *p_buf_pos = input_buf + 4;
|
|
|
|
char *NumCyclesPower_pos = strchr (p_buf_pos, '$');
|
|
|
|
if (NumCyclesPower_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t p_buf_len = NumCyclesPower_pos - p_buf_pos;
|
|
|
|
NumCyclesPower_pos++;
|
|
|
|
char *salt_len_pos = strchr (NumCyclesPower_pos, '$');
|
|
|
|
if (salt_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t NumCyclesPower_len = salt_len_pos - NumCyclesPower_pos;
|
|
|
|
salt_len_pos++;
|
|
|
|
char *salt_buf_pos = strchr (salt_len_pos, '$');
|
|
|
|
if (salt_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_len_len = salt_buf_pos - salt_len_pos;
|
|
|
|
salt_buf_pos++;
|
|
|
|
char *iv_len_pos = strchr (salt_buf_pos, '$');
|
|
|
|
if (iv_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_buf_len = iv_len_pos - salt_buf_pos;
|
|
|
|
iv_len_pos++;
|
|
|
|
char *iv_buf_pos = strchr (iv_len_pos, '$');
|
|
|
|
if (iv_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t iv_len_len = iv_buf_pos - iv_len_pos;
|
|
|
|
iv_buf_pos++;
|
|
|
|
char *crc_buf_pos = strchr (iv_buf_pos, '$');
|
|
|
|
if (crc_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t iv_buf_len = crc_buf_pos - iv_buf_pos;
|
|
|
|
crc_buf_pos++;
|
|
|
|
char *data_len_pos = strchr (crc_buf_pos, '$');
|
|
|
|
if (data_len_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t crc_buf_len = data_len_pos - crc_buf_pos;
|
|
|
|
data_len_pos++;
|
|
|
|
char *unpack_size_pos = strchr (data_len_pos, '$');
|
|
|
|
if (unpack_size_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t data_len_len = unpack_size_pos - data_len_pos;
|
|
|
|
unpack_size_pos++;
|
|
|
|
char *data_buf_pos = strchr (unpack_size_pos, '$');
|
|
|
|
if (data_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t unpack_size_len = data_buf_pos - unpack_size_pos;
|
|
|
|
data_buf_pos++;
|
|
|
|
uint32_t data_buf_len = input_len - 1 - 2 - 1 - p_buf_len - 1 - NumCyclesPower_len - 1 - salt_len_len - 1 - salt_buf_len - 1 - iv_len_len - 1 - iv_buf_len - 1 - crc_buf_len - 1 - data_len_len - 1 - unpack_size_len - 1;
|
|
|
|
const uint iter = atoi (NumCyclesPower_pos);
|
|
const uint crc = atoi (crc_buf_pos);
|
|
const uint p_buf = atoi (p_buf_pos);
|
|
const uint salt_len = atoi (salt_len_pos);
|
|
const uint iv_len = atoi (iv_len_pos);
|
|
const uint unpack_size = atoi (unpack_size_pos);
|
|
const uint data_len = atoi (data_len_pos);
|
|
|
|
/**
|
|
* verify some data
|
|
*/
|
|
|
|
if (p_buf != 0) return (PARSER_SALT_VALUE);
|
|
if (salt_len != 0) return (PARSER_SALT_VALUE);
|
|
|
|
if ((data_len * 2) != data_buf_len) return (PARSER_SALT_VALUE);
|
|
|
|
if (data_len > 384) return (PARSER_SALT_VALUE);
|
|
|
|
if (unpack_size > data_len) return (PARSER_SALT_VALUE);
|
|
|
|
/**
|
|
* store data
|
|
*/
|
|
|
|
seven_zip->iv_buf[0] = hex_to_uint (&iv_buf_pos[ 0]);
|
|
seven_zip->iv_buf[1] = hex_to_uint (&iv_buf_pos[ 8]);
|
|
seven_zip->iv_buf[2] = hex_to_uint (&iv_buf_pos[16]);
|
|
seven_zip->iv_buf[3] = hex_to_uint (&iv_buf_pos[24]);
|
|
|
|
seven_zip->iv_len = iv_len;
|
|
|
|
memcpy (seven_zip->salt_buf, salt_buf_pos, salt_buf_len); // we just need that for later ascii_digest()
|
|
|
|
seven_zip->salt_len = 0;
|
|
|
|
seven_zip->crc = crc;
|
|
|
|
for (uint i = 0, j = 0; j < data_buf_len; i += 1, j += 8)
|
|
{
|
|
seven_zip->data_buf[i] = hex_to_uint (&data_buf_pos[j]);
|
|
|
|
seven_zip->data_buf[i] = byte_swap_32 (seven_zip->data_buf[i]);
|
|
}
|
|
|
|
seven_zip->data_len = data_len;
|
|
|
|
seven_zip->unpack_size = unpack_size;
|
|
|
|
// real salt
|
|
|
|
salt->salt_buf[0] = seven_zip->data_buf[0];
|
|
salt->salt_buf[1] = seven_zip->data_buf[1];
|
|
salt->salt_buf[2] = seven_zip->data_buf[2];
|
|
salt->salt_buf[3] = seven_zip->data_buf[3];
|
|
|
|
salt->salt_len = 16;
|
|
|
|
salt->salt_sign[0] = iter;
|
|
|
|
salt->salt_iter = 1 << iter;
|
|
|
|
/**
|
|
* digest
|
|
*/
|
|
|
|
digest[0] = crc;
|
|
digest[1] = 0;
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int gost2012sbog_256_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11700) || (input_len > DISPLAY_LEN_MAX_11700)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
digest[5] = hex_to_uint (&input_buf[40]);
|
|
digest[6] = hex_to_uint (&input_buf[48]);
|
|
digest[7] = hex_to_uint (&input_buf[56]);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
digest[4] = byte_swap_32 (digest[4]);
|
|
digest[5] = byte_swap_32 (digest[5]);
|
|
digest[6] = byte_swap_32 (digest[6]);
|
|
digest[7] = byte_swap_32 (digest[7]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int gost2012sbog_512_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11800) || (input_len > DISPLAY_LEN_MAX_11800)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
digest[ 0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[ 1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[ 2] = hex_to_uint (&input_buf[ 16]);
|
|
digest[ 3] = hex_to_uint (&input_buf[ 24]);
|
|
digest[ 4] = hex_to_uint (&input_buf[ 32]);
|
|
digest[ 5] = hex_to_uint (&input_buf[ 40]);
|
|
digest[ 6] = hex_to_uint (&input_buf[ 48]);
|
|
digest[ 7] = hex_to_uint (&input_buf[ 56]);
|
|
digest[ 8] = hex_to_uint (&input_buf[ 64]);
|
|
digest[ 9] = hex_to_uint (&input_buf[ 72]);
|
|
digest[10] = hex_to_uint (&input_buf[ 80]);
|
|
digest[11] = hex_to_uint (&input_buf[ 88]);
|
|
digest[12] = hex_to_uint (&input_buf[ 96]);
|
|
digest[13] = hex_to_uint (&input_buf[104]);
|
|
digest[14] = hex_to_uint (&input_buf[112]);
|
|
digest[15] = hex_to_uint (&input_buf[120]);
|
|
|
|
digest[ 0] = byte_swap_32 (digest[ 0]);
|
|
digest[ 1] = byte_swap_32 (digest[ 1]);
|
|
digest[ 2] = byte_swap_32 (digest[ 2]);
|
|
digest[ 3] = byte_swap_32 (digest[ 3]);
|
|
digest[ 4] = byte_swap_32 (digest[ 4]);
|
|
digest[ 5] = byte_swap_32 (digest[ 5]);
|
|
digest[ 6] = byte_swap_32 (digest[ 6]);
|
|
digest[ 7] = byte_swap_32 (digest[ 7]);
|
|
digest[ 8] = byte_swap_32 (digest[ 8]);
|
|
digest[ 9] = byte_swap_32 (digest[ 9]);
|
|
digest[10] = byte_swap_32 (digest[10]);
|
|
digest[11] = byte_swap_32 (digest[11]);
|
|
digest[12] = byte_swap_32 (digest[12]);
|
|
digest[13] = byte_swap_32 (digest[13]);
|
|
digest[14] = byte_swap_32 (digest[14]);
|
|
digest[15] = byte_swap_32 (digest[15]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int pbkdf2_md5_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_11900) || (input_len > DISPLAY_LEN_MAX_11900)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_PBKDF2_MD5, input_buf, 4)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pbkdf2_md5_t *pbkdf2_md5 = (pbkdf2_md5_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
// iterations
|
|
|
|
char *iter_pos = input_buf + 4;
|
|
|
|
uint32_t iter = atoi (iter_pos);
|
|
|
|
if (iter < 1) return (PARSER_SALT_ITERATION);
|
|
if (iter > 999999) return (PARSER_SALT_ITERATION);
|
|
|
|
// first is *raw* salt
|
|
|
|
char *salt_pos = strchr (iter_pos, ':');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, ':');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len > 64) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
uint32_t hash_b64_len = input_len - (hash_pos - input_buf);
|
|
|
|
if (hash_b64_len > 88) return (PARSER_HASH_LENGTH);
|
|
|
|
// decode salt
|
|
|
|
char *salt_buf_ptr = (char *) pbkdf2_md5->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt_buf_ptr[salt_len + 3] = 0x01;
|
|
salt_buf_ptr[salt_len + 4] = 0x80;
|
|
|
|
salt->salt_len = salt_len;
|
|
salt->salt_iter = iter - 1;
|
|
|
|
// decode hash
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
int hash_len = base64_decode (base64_to_int, hash_pos, hash_b64_len, tmp_buf);
|
|
|
|
if (hash_len < 16) return (PARSER_HASH_LENGTH);
|
|
|
|
memcpy (digest, tmp_buf, 16);
|
|
|
|
// add some stuff to normal salt to make sorted happy
|
|
|
|
salt->salt_buf[0] = pbkdf2_md5->salt_buf[0];
|
|
salt->salt_buf[1] = pbkdf2_md5->salt_buf[1];
|
|
salt->salt_buf[2] = pbkdf2_md5->salt_buf[2];
|
|
salt->salt_buf[3] = pbkdf2_md5->salt_buf[3];
|
|
salt->salt_buf[4] = salt->salt_iter;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int pbkdf2_sha1_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_12000) || (input_len > DISPLAY_LEN_MAX_12000)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_PBKDF2_SHA1, input_buf, 5)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pbkdf2_sha1_t *pbkdf2_sha1 = (pbkdf2_sha1_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
// iterations
|
|
|
|
char *iter_pos = input_buf + 5;
|
|
|
|
uint32_t iter = atoi (iter_pos);
|
|
|
|
if (iter < 1) return (PARSER_SALT_ITERATION);
|
|
if (iter > 999999) return (PARSER_SALT_ITERATION);
|
|
|
|
// first is *raw* salt
|
|
|
|
char *salt_pos = strchr (iter_pos, ':');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, ':');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len > 64) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
uint32_t hash_b64_len = input_len - (hash_pos - input_buf);
|
|
|
|
if (hash_b64_len > 88) return (PARSER_HASH_LENGTH);
|
|
|
|
// decode salt
|
|
|
|
char *salt_buf_ptr = (char *) pbkdf2_sha1->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt_buf_ptr[salt_len + 3] = 0x01;
|
|
salt_buf_ptr[salt_len + 4] = 0x80;
|
|
|
|
salt->salt_len = salt_len;
|
|
salt->salt_iter = iter - 1;
|
|
|
|
// decode hash
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
int hash_len = base64_decode (base64_to_int, hash_pos, hash_b64_len, tmp_buf);
|
|
|
|
if (hash_len < 16) return (PARSER_HASH_LENGTH);
|
|
|
|
memcpy (digest, tmp_buf, 16);
|
|
|
|
digest[0] = byte_swap_32 (digest[0]);
|
|
digest[1] = byte_swap_32 (digest[1]);
|
|
digest[2] = byte_swap_32 (digest[2]);
|
|
digest[3] = byte_swap_32 (digest[3]);
|
|
|
|
// add some stuff to normal salt to make sorted happy
|
|
|
|
salt->salt_buf[0] = pbkdf2_sha1->salt_buf[0];
|
|
salt->salt_buf[1] = pbkdf2_sha1->salt_buf[1];
|
|
salt->salt_buf[2] = pbkdf2_sha1->salt_buf[2];
|
|
salt->salt_buf[3] = pbkdf2_sha1->salt_buf[3];
|
|
salt->salt_buf[4] = salt->salt_iter;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int pbkdf2_sha512_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_12100) || (input_len > DISPLAY_LEN_MAX_12100)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_PBKDF2_SHA512, input_buf, 7)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint64_t *digest = (uint64_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
pbkdf2_sha512_t *pbkdf2_sha512 = (pbkdf2_sha512_t *) hash_buf->esalt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
// iterations
|
|
|
|
char *iter_pos = input_buf + 7;
|
|
|
|
uint32_t iter = atoi (iter_pos);
|
|
|
|
if (iter < 1) return (PARSER_SALT_ITERATION);
|
|
if (iter > 999999) return (PARSER_SALT_ITERATION);
|
|
|
|
// first is *raw* salt
|
|
|
|
char *salt_pos = strchr (iter_pos, ':');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
salt_pos++;
|
|
|
|
char *hash_pos = strchr (salt_pos, ':');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len > 64) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
uint32_t hash_b64_len = input_len - (hash_pos - input_buf);
|
|
|
|
if (hash_b64_len > 88) return (PARSER_HASH_LENGTH);
|
|
|
|
// decode salt
|
|
|
|
char *salt_buf_ptr = (char *) pbkdf2_sha512->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_pos, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt_buf_ptr[salt_len + 3] = 0x01;
|
|
salt_buf_ptr[salt_len + 4] = 0x80;
|
|
|
|
salt->salt_len = salt_len;
|
|
salt->salt_iter = iter - 1;
|
|
|
|
// decode hash
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
int hash_len = base64_decode (base64_to_int, hash_pos, hash_b64_len, tmp_buf);
|
|
|
|
if (hash_len < 16) return (PARSER_HASH_LENGTH);
|
|
|
|
memcpy (digest, tmp_buf, 64);
|
|
|
|
digest[0] = byte_swap_64 (digest[0]);
|
|
digest[1] = byte_swap_64 (digest[1]);
|
|
digest[2] = byte_swap_64 (digest[2]);
|
|
digest[3] = byte_swap_64 (digest[3]);
|
|
digest[4] = byte_swap_64 (digest[4]);
|
|
digest[5] = byte_swap_64 (digest[5]);
|
|
digest[6] = byte_swap_64 (digest[6]);
|
|
digest[7] = byte_swap_64 (digest[7]);
|
|
|
|
// add some stuff to normal salt to make sorted happy
|
|
|
|
salt->salt_buf[0] = pbkdf2_sha512->salt_buf[0];
|
|
salt->salt_buf[1] = pbkdf2_sha512->salt_buf[1];
|
|
salt->salt_buf[2] = pbkdf2_sha512->salt_buf[2];
|
|
salt->salt_buf[3] = pbkdf2_sha512->salt_buf[3];
|
|
salt->salt_buf[4] = salt->salt_iter;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int ecryptfs_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_12200) || (input_len > DISPLAY_LEN_MAX_12200)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_ECRYPTFS, input_buf, 10)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint *digest = (uint *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *salt_pos = input_buf + 10 + 2 + 2; // skip over "0$" and "1$"
|
|
|
|
char *hash_pos = strchr (salt_pos, '$');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_len = hash_pos - salt_pos;
|
|
|
|
if (salt_len != 16) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
uint32_t hash_len = input_len - 10 - 2 - 2 - salt_len - 1;
|
|
|
|
if (hash_len != 16) return (PARSER_HASH_LENGTH);
|
|
|
|
// decode hash
|
|
|
|
digest[ 0] = hex_to_uint (&hash_pos[0]);
|
|
digest[ 1] = hex_to_uint (&hash_pos[8]);
|
|
digest[ 2] = 0;
|
|
digest[ 3] = 0;
|
|
digest[ 4] = 0;
|
|
digest[ 5] = 0;
|
|
digest[ 6] = 0;
|
|
digest[ 7] = 0;
|
|
digest[ 8] = 0;
|
|
digest[ 9] = 0;
|
|
digest[10] = 0;
|
|
digest[11] = 0;
|
|
digest[12] = 0;
|
|
digest[13] = 0;
|
|
digest[14] = 0;
|
|
digest[15] = 0;
|
|
|
|
// decode salt
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&salt_pos[0]);
|
|
salt->salt_buf[1] = hex_to_uint (&salt_pos[8]);
|
|
|
|
salt->salt_iter = ROUNDS_ECRYPTFS;
|
|
salt->salt_len = 8;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int bsdicrypt_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_12400) || (input_len > DISPLAY_LEN_MAX_12400)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_BSDICRYPT, input_buf, 1)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
unsigned char c19 = itoa64_to_int (input_buf[19]);
|
|
|
|
if (c19 & 3) return (PARSER_HASH_VALUE);
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
// iteration count
|
|
|
|
salt->salt_iter = itoa64_to_int (input_buf[1])
|
|
| itoa64_to_int (input_buf[2]) << 6
|
|
| itoa64_to_int (input_buf[3]) << 12
|
|
| itoa64_to_int (input_buf[4]) << 18;
|
|
|
|
// set salt
|
|
|
|
salt->salt_buf[0] = itoa64_to_int (input_buf[5])
|
|
| itoa64_to_int (input_buf[6]) << 6
|
|
| itoa64_to_int (input_buf[7]) << 12
|
|
| itoa64_to_int (input_buf[8]) << 18;
|
|
|
|
salt->salt_len = 4;
|
|
|
|
char tmp_buf[100];
|
|
|
|
memset (tmp_buf, 0, sizeof (tmp_buf));
|
|
|
|
base64_decode (itoa64_to_int, input_buf + 9, 11, tmp_buf);
|
|
|
|
memcpy (digest, tmp_buf, 8);
|
|
|
|
uint tt;
|
|
|
|
IP (digest[0], digest[1], tt);
|
|
|
|
digest[0] = ROTATE_RIGHT (digest[0], 31);
|
|
digest[1] = ROTATE_RIGHT (digest[1], 31);
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int rar3hp_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_12500) || (input_len > DISPLAY_LEN_MAX_12500)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_RAR3, input_buf, 6)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *type_pos = input_buf + 6 + 1;
|
|
|
|
char *salt_pos = strchr (type_pos, '*');
|
|
|
|
if (salt_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t type_len = salt_pos - type_pos;
|
|
|
|
if (type_len != 1) return (PARSER_SALT_LENGTH);
|
|
|
|
salt_pos++;
|
|
|
|
char *crypted_pos = strchr (salt_pos, '*');
|
|
|
|
if (crypted_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_len = crypted_pos - salt_pos;
|
|
|
|
if (salt_len != 16) return (PARSER_SALT_LENGTH);
|
|
|
|
crypted_pos++;
|
|
|
|
uint32_t crypted_len = input_len - 6 - 1 - type_len - 1 - salt_len - 1;
|
|
|
|
if (crypted_len != 32) return (PARSER_SALT_LENGTH);
|
|
|
|
/**
|
|
* copy data
|
|
*/
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&salt_pos[0]);
|
|
salt->salt_buf[1] = hex_to_uint (&salt_pos[8]);
|
|
|
|
salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]);
|
|
salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]);
|
|
|
|
salt->salt_buf[2] = hex_to_uint (&crypted_pos[ 0]);
|
|
salt->salt_buf[3] = hex_to_uint (&crypted_pos[ 8]);
|
|
salt->salt_buf[4] = hex_to_uint (&crypted_pos[16]);
|
|
salt->salt_buf[5] = hex_to_uint (&crypted_pos[24]);
|
|
|
|
salt->salt_len = 24;
|
|
salt->salt_iter = ROUNDS_RAR3;
|
|
|
|
// there's no hash for rar3. the data which is in crypted_pos is some encrypted data and
|
|
// if it matches the value \xc4\x3d\x7b\x00\x40\x07\x00 after decrypt we know that we successfully cracked it.
|
|
|
|
digest[0] = 0xc43d7b00;
|
|
digest[1] = 0x40070000;
|
|
digest[2] = 0;
|
|
digest[3] = 0;
|
|
|
|
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);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
digest[0] = hex_to_uint (&input_buf[ 0]);
|
|
digest[1] = hex_to_uint (&input_buf[ 8]);
|
|
digest[2] = hex_to_uint (&input_buf[16]);
|
|
digest[3] = hex_to_uint (&input_buf[24]);
|
|
digest[4] = hex_to_uint (&input_buf[32]);
|
|
digest[5] = hex_to_uint (&input_buf[40]);
|
|
digest[6] = hex_to_uint (&input_buf[48]);
|
|
digest[7] = hex_to_uint (&input_buf[56]);
|
|
|
|
if (input_buf[64] != data.separator) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint salt_len = input_len - 64 - 1;
|
|
|
|
char *salt_buf = input_buf + 64 + 1;
|
|
|
|
char *salt_buf_ptr = (char *) salt->salt_buf;
|
|
|
|
salt_len = parse_and_store_salt (salt_buf_ptr, salt_buf, salt_len);
|
|
|
|
if (salt_len == UINT_MAX) return (PARSER_SALT_LENGTH);
|
|
|
|
salt->salt_len = salt_len;
|
|
|
|
/**
|
|
* we can precompute the first sha256 transform
|
|
*/
|
|
|
|
uint w[16];
|
|
|
|
w[ 0] = byte_swap_32 (salt->salt_buf[ 0]);
|
|
w[ 1] = byte_swap_32 (salt->salt_buf[ 1]);
|
|
w[ 2] = byte_swap_32 (salt->salt_buf[ 2]);
|
|
w[ 3] = byte_swap_32 (salt->salt_buf[ 3]);
|
|
w[ 4] = byte_swap_32 (salt->salt_buf[ 4]);
|
|
w[ 5] = byte_swap_32 (salt->salt_buf[ 5]);
|
|
w[ 6] = byte_swap_32 (salt->salt_buf[ 6]);
|
|
w[ 7] = byte_swap_32 (salt->salt_buf[ 7]);
|
|
w[ 8] = byte_swap_32 (salt->salt_buf[ 8]);
|
|
w[ 9] = byte_swap_32 (salt->salt_buf[ 9]);
|
|
w[10] = byte_swap_32 (salt->salt_buf[10]);
|
|
w[11] = byte_swap_32 (salt->salt_buf[11]);
|
|
w[12] = byte_swap_32 (salt->salt_buf[12]);
|
|
w[13] = byte_swap_32 (salt->salt_buf[13]);
|
|
w[14] = byte_swap_32 (salt->salt_buf[14]);
|
|
w[15] = byte_swap_32 (salt->salt_buf[15]);
|
|
|
|
uint pc256[8];
|
|
|
|
pc256[0] = SHA256M_A;
|
|
pc256[1] = SHA256M_B;
|
|
pc256[2] = SHA256M_C;
|
|
pc256[3] = SHA256M_D;
|
|
pc256[4] = SHA256M_E;
|
|
pc256[5] = SHA256M_F;
|
|
pc256[6] = SHA256M_G;
|
|
pc256[7] = SHA256M_H;
|
|
|
|
sha256_64 (w, pc256);
|
|
|
|
salt->salt_buf_pc[0] = pc256[0];
|
|
salt->salt_buf_pc[1] = pc256[1];
|
|
salt->salt_buf_pc[2] = pc256[2];
|
|
salt->salt_buf_pc[3] = pc256[3];
|
|
salt->salt_buf_pc[4] = pc256[4];
|
|
salt->salt_buf_pc[5] = pc256[5];
|
|
salt->salt_buf_pc[6] = pc256[6];
|
|
salt->salt_buf_pc[7] = pc256[7];
|
|
|
|
digest[0] -= pc256[0];
|
|
digest[1] -= pc256[1];
|
|
digest[2] -= pc256[2];
|
|
digest[3] -= pc256[3];
|
|
digest[4] -= pc256[4];
|
|
digest[5] -= pc256[5];
|
|
digest[6] -= pc256[6];
|
|
digest[7] -= pc256[7];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int mywallet_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_12700) || (input_len > DISPLAY_LEN_MAX_12700)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_MYWALLET, input_buf, 12)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *data_len_pos = input_buf + 1 + 10 + 1;
|
|
|
|
char *data_buf_pos = strchr (data_len_pos, '$');
|
|
|
|
if (data_buf_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t data_len_len = data_buf_pos - data_len_pos;
|
|
|
|
if (data_len_len < 1) return (PARSER_SALT_LENGTH);
|
|
if (data_len_len > 5) return (PARSER_SALT_LENGTH);
|
|
|
|
data_buf_pos++;
|
|
|
|
uint32_t data_buf_len = input_len - 1 - 10 - 1 - data_len_len - 1;
|
|
|
|
if (data_buf_len < 64) return (PARSER_HASH_LENGTH);
|
|
|
|
if (data_buf_len % 16) return (PARSER_HASH_LENGTH);
|
|
|
|
uint32_t data_len = atoi (data_len_pos);
|
|
|
|
if ((data_len * 2) != data_buf_len) return (PARSER_HASH_LENGTH);
|
|
|
|
/**
|
|
* salt
|
|
*/
|
|
|
|
char *salt_pos = data_buf_pos;
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&salt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&salt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&salt_pos[16]);
|
|
salt->salt_buf[3] = hex_to_uint (&salt_pos[24]);
|
|
|
|
// this is actually the CT, which is also the hash later (if matched)
|
|
|
|
salt->salt_buf[4] = hex_to_uint (&salt_pos[32]);
|
|
salt->salt_buf[5] = hex_to_uint (&salt_pos[40]);
|
|
salt->salt_buf[6] = hex_to_uint (&salt_pos[48]);
|
|
salt->salt_buf[7] = hex_to_uint (&salt_pos[56]);
|
|
|
|
salt->salt_len = 32; // note we need to fix this to 16 in kernel
|
|
|
|
salt->salt_iter = 10 - 1;
|
|
|
|
/**
|
|
* digest buf
|
|
*/
|
|
|
|
digest[0] = salt->salt_buf[4];
|
|
digest[1] = salt->salt_buf[5];
|
|
digest[2] = salt->salt_buf[6];
|
|
digest[3] = salt->salt_buf[7];
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
int ms_drsr_parse_hash (char *input_buf, uint input_len, hash_t *hash_buf)
|
|
{
|
|
if ((input_len < DISPLAY_LEN_MIN_12800) || (input_len > DISPLAY_LEN_MAX_12800)) return (PARSER_GLOBAL_LENGTH);
|
|
|
|
if (memcmp (SIGNATURE_MS_DRSR, input_buf, 11)) return (PARSER_SIGNATURE_UNMATCHED);
|
|
|
|
uint32_t *digest = (uint32_t *) hash_buf->digest;
|
|
|
|
salt_t *salt = hash_buf->salt;
|
|
|
|
/**
|
|
* parse line
|
|
*/
|
|
|
|
char *salt_pos = input_buf + 11 + 1;
|
|
|
|
char *iter_pos = strchr (salt_pos, ',');
|
|
|
|
if (iter_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t salt_len = iter_pos - salt_pos;
|
|
|
|
if (salt_len != 20) return (PARSER_SALT_LENGTH);
|
|
|
|
iter_pos++;
|
|
|
|
char *hash_pos = strchr (iter_pos, ',');
|
|
|
|
if (hash_pos == NULL) return (PARSER_SEPARATOR_UNMATCHED);
|
|
|
|
uint32_t iter_len = hash_pos - iter_pos;
|
|
|
|
if (iter_len > 5) return (PARSER_SALT_LENGTH);
|
|
|
|
hash_pos++;
|
|
|
|
uint32_t hash_len = input_len - 11 - 1 - salt_len - 1 - iter_len - 1;
|
|
|
|
if (hash_len != 64) return (PARSER_HASH_LENGTH);
|
|
|
|
/**
|
|
* salt
|
|
*/
|
|
|
|
salt->salt_buf[0] = hex_to_uint (&salt_pos[ 0]);
|
|
salt->salt_buf[1] = hex_to_uint (&salt_pos[ 8]);
|
|
salt->salt_buf[2] = hex_to_uint (&salt_pos[16]) & 0xffff0000;
|
|
salt->salt_buf[3] = 0x00018000;
|
|
|
|
salt->salt_buf[0] = byte_swap_32 (salt->salt_buf[0]);
|
|
salt->salt_buf[1] = byte_swap_32 (salt->salt_buf[1]);
|
|
salt->salt_buf[2] = byte_swap_32 (salt->salt_buf[2]);
|
|
salt->salt_buf[3] = byte_swap_32 (salt->salt_buf[3]);
|
|
|
|
salt->salt_len = salt_len / 2;
|
|
|
|
salt->salt_iter = atoi (iter_pos) - 1;
|
|
|
|
/**
|
|
* digest buf
|
|
*/
|
|
|
|
digest[0] = hex_to_uint (&hash_pos[ 0]);
|
|
digest[1] = hex_to_uint (&hash_pos[ 8]);
|
|
digest[2] = hex_to_uint (&hash_pos[16]);
|
|
digest[3] = hex_to_uint (&hash_pos[24]);
|
|
digest[4] = hex_to_uint (&hash_pos[32]);
|
|
digest[5] = hex_to_uint (&hash_pos[40]);
|
|
digest[6] = hex_to_uint (&hash_pos[48]);
|
|
digest[7] = hex_to_uint (&hash_pos[56]);
|
|
|
|
return (PARSER_OK);
|
|
}
|
|
|
|
/**
|
|
* parallel running threads
|
|
*/
|
|
|
|
#ifdef WIN
|
|
|
|
BOOL WINAPI sigHandler_default (DWORD sig)
|
|
{
|
|
switch (sig)
|
|
{
|
|
case CTRL_CLOSE_EVENT:
|
|
|
|
/*
|
|
* special case see: https://stackoverflow.com/questions/3640633/c-setconsolectrlhandler-routine-issue/5610042#5610042
|
|
* if the user interacts w/ the user-interface (GUI/cmd), we need to do the finalization job within this signal handler
|
|
* function otherwise it is to late (e.g. after returning from this function)
|
|
*/
|
|
|
|
myabort ();
|
|
|
|
SetConsoleCtrlHandler (NULL, TRUE);
|
|
|
|
hc_sleep (10);
|
|
|
|
return TRUE;
|
|
|
|
case CTRL_C_EVENT:
|
|
case CTRL_LOGOFF_EVENT:
|
|
case CTRL_SHUTDOWN_EVENT:
|
|
|
|
myabort ();
|
|
|
|
SetConsoleCtrlHandler (NULL, TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL WINAPI sigHandler_benchmark (DWORD sig)
|
|
{
|
|
switch (sig)
|
|
{
|
|
case CTRL_CLOSE_EVENT:
|
|
|
|
myabort ();
|
|
|
|
SetConsoleCtrlHandler (NULL, TRUE);
|
|
|
|
hc_sleep (10);
|
|
|
|
return TRUE;
|
|
|
|
case CTRL_C_EVENT:
|
|
case CTRL_LOGOFF_EVENT:
|
|
case CTRL_SHUTDOWN_EVENT:
|
|
|
|
myquit ();
|
|
|
|
SetConsoleCtrlHandler (NULL, TRUE);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void hc_signal (BOOL WINAPI (callback) (DWORD))
|
|
{
|
|
if (callback == NULL)
|
|
{
|
|
SetConsoleCtrlHandler ((PHANDLER_ROUTINE) callback, FALSE);
|
|
}
|
|
else
|
|
{
|
|
SetConsoleCtrlHandler ((PHANDLER_ROUTINE) callback, TRUE);
|
|
}
|
|
}
|
|
|
|
#else
|
|
|
|
void sigHandler_default (int sig)
|
|
{
|
|
myabort ();
|
|
|
|
signal (sig, NULL);
|
|
}
|
|
|
|
void sigHandler_benchmark (int sig)
|
|
{
|
|
myquit ();
|
|
|
|
signal (sig, NULL);
|
|
}
|
|
|
|
void hc_signal (void (callback) (int))
|
|
{
|
|
if (callback == NULL) callback = SIG_DFL;
|
|
|
|
signal (SIGINT, callback);
|
|
signal (SIGTERM, callback);
|
|
signal (SIGABRT, callback);
|
|
}
|
|
|
|
#endif
|
|
|
|
void status_display ();
|
|
|
|
void *thread_keypress (void *p)
|
|
{
|
|
int benchmark = *((int *) p);
|
|
|
|
uint quiet = data.quiet;
|
|
|
|
tty_break();
|
|
|
|
while ((data.devices_status != STATUS_EXHAUSTED) && (data.devices_status != STATUS_CRACKED) && (data.devices_status != STATUS_ABORTED) && (data.devices_status != STATUS_QUIT))
|
|
{
|
|
int ch = tty_getchar();
|
|
|
|
if (ch == -1) break;
|
|
|
|
if (ch == 0) continue;
|
|
|
|
#ifdef _POSIX
|
|
if (ch != '\n')
|
|
#endif
|
|
|
|
hc_thread_mutex_lock (mux_display);
|
|
|
|
log_info ("");
|
|
|
|
switch (ch)
|
|
{
|
|
case 's':
|
|
case '\n':
|
|
|
|
log_info ("");
|
|
|
|
status_display ();
|
|
|
|
log_info ("");
|
|
|
|
if (quiet == 0) fprintf (stdout, "%s", PROMPT);
|
|
if (quiet == 0) fflush (stdout);
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
|
|
log_info ("");
|
|
|
|
bypass ();
|
|
|
|
log_info ("");
|
|
|
|
if (quiet == 0) fprintf (stdout, "%s", PROMPT);
|
|
if (quiet == 0) fflush (stdout);
|
|
|
|
break;
|
|
|
|
case 'p':
|
|
|
|
log_info ("");
|
|
|
|
SuspendThreads ();
|
|
|
|
log_info ("");
|
|
|
|
if (quiet == 0) fprintf (stdout, "%s", PROMPT);
|
|
if (quiet == 0) fflush (stdout);
|
|
|
|
break;
|
|
|
|
case 'r':
|
|
|
|
log_info ("");
|
|
|
|
ResumeThreads ();
|
|
|
|
log_info ("");
|
|
|
|
if (quiet == 0) fprintf (stdout, "%s", PROMPT);
|
|
if (quiet == 0) fflush (stdout);
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
log_info ("");
|
|
|
|
if (benchmark == 1) break;
|
|
|
|
stop_at_checkpoint ();
|
|
|
|
log_info ("");
|
|
|
|
if (quiet == 0) fprintf (stdout, "%s", PROMPT);
|
|
if (quiet == 0) fflush (stdout);
|
|
|
|
break;
|
|
|
|
case 'q':
|
|
|
|
log_info ("");
|
|
|
|
if (benchmark == 1)
|
|
{
|
|
myquit ();
|
|
}
|
|
else
|
|
{
|
|
myabort ();
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
hc_thread_mutex_unlock (mux_display);
|
|
}
|
|
|
|
tty_fix();
|
|
|
|
return (p);
|
|
}
|
|
|
|
/**
|
|
* rules common
|
|
*/
|
|
|
|
bool class_num (char c)
|
|
{
|
|
return ((c >= '0') && (c <= '9'));
|
|
}
|
|
|
|
bool class_lower (char c)
|
|
{
|
|
return ((c >= 'a') && (c <= 'z'));
|
|
}
|
|
|
|
bool class_upper (char c)
|
|
{
|
|
return ((c >= 'A') && (c <= 'Z'));
|
|
}
|
|
|
|
bool class_alpha (char c)
|
|
{
|
|
return (class_lower (c) || class_upper (c));
|
|
}
|
|
|
|
char conv_ctoi (char c)
|
|
{
|
|
if (class_num (c))
|
|
{
|
|
return c - '0';
|
|
}
|
|
else if (class_upper (c))
|
|
{
|
|
return c - 'A' + (char) 10;
|
|
}
|
|
|
|
return (char) (-1);
|
|
}
|
|
|
|
char conv_itoc (char c)
|
|
{
|
|
if (c < 10)
|
|
{
|
|
return c + '0';
|
|
}
|
|
else if (c < 37)
|
|
{
|
|
return c + 'A' - (char) 10;
|
|
}
|
|
|
|
return (char) (-1);
|
|
}
|
|
|
|
/**
|
|
* GPU rules
|
|
*/
|
|
|
|
#define INCR_POS if (++rule_pos == rule_len) return (-1)
|
|
#define SET_NAME(rule,val) (rule)->cmds[rule_cnt] = ((val) & 0xff) << 0
|
|
#define SET_P0(rule,val) INCR_POS; (rule)->cmds[rule_cnt] |= ((val) & 0xff) << 8
|
|
#define SET_P1(rule,val) INCR_POS; (rule)->cmds[rule_cnt] |= ((val) & 0xff) << 16
|
|
#define MAX_GPU_RULES 14
|
|
#define GET_NAME(rule) rule_cmd = (((rule)->cmds[rule_cnt] >> 0) & 0xff)
|
|
#define GET_P0(rule) INCR_POS; rule_buf[rule_pos] = (((rule)->cmds[rule_cnt] >> 8) & 0xff)
|
|
#define GET_P1(rule) INCR_POS; rule_buf[rule_pos] = (((rule)->cmds[rule_cnt] >> 16) & 0xff)
|
|
|
|
#define SET_P0_CONV(rule,val) INCR_POS; (rule)->cmds[rule_cnt] |= ((conv_ctoi (val)) & 0xff) << 8
|
|
#define SET_P1_CONV(rule,val) INCR_POS; (rule)->cmds[rule_cnt] |= ((conv_ctoi (val)) & 0xff) << 16
|
|
#define GET_P0_CONV(rule) INCR_POS; rule_buf[rule_pos] = conv_itoc (((rule)->cmds[rule_cnt] >> 8) & 0xff)
|
|
#define GET_P1_CONV(rule) INCR_POS; rule_buf[rule_pos] = conv_itoc (((rule)->cmds[rule_cnt] >> 16) & 0xff)
|
|
|
|
int cpu_rule_to_gpu_rule (char rule_buf[BUFSIZ], uint rule_len, gpu_rule_t *rule)
|
|
{
|
|
uint rule_pos;
|
|
uint rule_cnt;
|
|
|
|
for (rule_pos = 0, rule_cnt = 0; rule_pos < rule_len && rule_cnt < MAX_GPU_RULES; rule_pos++, rule_cnt++)
|
|
{
|
|
switch (rule_buf[rule_pos])
|
|
{
|
|
case ' ':
|
|
rule_cnt--;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_NOOP:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_LREST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_UREST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_LREST_UFIRST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_UREST_LFIRST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TREST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TOGGLE_AT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REVERSE:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEWORD:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEWORD_TIMES:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REFLECT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_ROTATE_LEFT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_ROTATE_RIGHT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_APPEND:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0 (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PREPEND:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0 (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_FIRST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_LAST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_AT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_EXTRACT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
SET_P1_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_OMIT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
SET_P1_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_INSERT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
SET_P1 (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_OVERSTRIKE:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
SET_P1 (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TRUNCATE_AT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0 (rule, rule_buf[rule_pos]);
|
|
SET_P1 (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PURGECHAR:
|
|
return (-1);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TOGGLECASE_REC:
|
|
return (-1);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_FIRST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_LAST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_ALL:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_FIRST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_LAST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_AT:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
SET_P1_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_SHIFTL:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_SHIFTR:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_INCR:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_DECR:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE_NP1:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE_NM1:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEBLOCK_FIRST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEBLOCK_LAST:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
SET_P0_CONV (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TITLE:
|
|
SET_NAME (rule, rule_buf[rule_pos]);
|
|
break;
|
|
|
|
default:
|
|
return (-1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rule_pos < rule_len) return (-1);
|
|
|
|
return (0);
|
|
}
|
|
|
|
int gpu_rule_to_cpu_rule (char rule_buf[BUFSIZ], gpu_rule_t *rule)
|
|
{
|
|
uint rule_cnt;
|
|
uint rule_pos;
|
|
uint rule_len = BUFSIZ - 1; // maximum possible len
|
|
|
|
char rule_cmd;
|
|
|
|
for (rule_cnt = 0, rule_pos = 0; rule_pos < rule_len && rule_cnt < MAX_GPU_RULES; rule_pos++, rule_cnt++)
|
|
{
|
|
GET_NAME (rule);
|
|
|
|
if (rule_cnt > 0) rule_buf[rule_pos++] = ' ';
|
|
|
|
switch (rule_cmd)
|
|
{
|
|
case RULE_OP_MANGLE_NOOP:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_LREST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_UREST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_LREST_UFIRST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_UREST_LFIRST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TREST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TOGGLE_AT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REVERSE:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEWORD:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEWORD_TIMES:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REFLECT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_ROTATE_LEFT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_ROTATE_RIGHT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_APPEND:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0 (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PREPEND:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0 (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_FIRST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_LAST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_AT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_EXTRACT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
GET_P1_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_OMIT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
GET_P1_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_INSERT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
GET_P1 (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_OVERSTRIKE:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
GET_P1 (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TRUNCATE_AT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0 (rule);
|
|
GET_P1 (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PURGECHAR:
|
|
return (-1);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TOGGLECASE_REC:
|
|
return (-1);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_FIRST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_LAST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_ALL:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_FIRST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_LAST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_AT:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
GET_P1_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_SHIFTL:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_SHIFTR:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_INCR:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_DECR:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE_NP1:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE_NM1:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEBLOCK_FIRST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEBLOCK_LAST:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
GET_P0_CONV (rule);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TITLE:
|
|
rule_buf[rule_pos] = rule_cmd;
|
|
break;
|
|
|
|
case 0:
|
|
return rule_pos - 1;
|
|
break;
|
|
|
|
default:
|
|
return (-1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rule_cnt > 0)
|
|
{
|
|
return rule_pos;
|
|
}
|
|
|
|
return (-1);
|
|
}
|
|
|
|
/**
|
|
* CPU rules : this is from hashcat sources, cpu based rules
|
|
*/
|
|
|
|
#define NEXT_RULEPOS(rp) if (++(rp) == rule_len) return (RULE_RC_SYNTAX_ERROR)
|
|
#define NEXT_RPTOI(r,rp,up) if (((up) = conv_ctoi ((r)[(rp)])) == -1) return (RULE_RC_SYNTAX_ERROR)
|
|
|
|
#define MANGLE_TOGGLE_AT(a,p) if (class_alpha ((a)[(p)])) (a)[(p)] ^= 0x20
|
|
#define MANGLE_LOWER_AT(a,p) if (class_upper ((a)[(p)])) (a)[(p)] ^= 0x20
|
|
#define MANGLE_UPPER_AT(a,p) if (class_lower ((a)[(p)])) (a)[(p)] ^= 0x20
|
|
|
|
/* #define MANGLE_SWITCH(a,l,r) { char c = (l); arr[(r)] = arr[(l)]; arr[(l)] = c; } */
|
|
/* #define MANGLE_SWITCH(a,l,r) { char c = (l); (a)[(r)] = (a)[(l)]; (a)[(l)] = c; } */
|
|
#define MANGLE_SWITCH(a,l,r) { char c = (a)[(r)]; (a)[(r)] = (a)[(l)]; (a)[(l)] = c; }
|
|
|
|
int mangle_lrest (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
int pos;
|
|
|
|
for (pos = 0; pos < arr_len; pos++) MANGLE_LOWER_AT (arr, pos);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_urest (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
int pos;
|
|
|
|
for (pos = 0; pos < arr_len; pos++) MANGLE_UPPER_AT (arr, pos);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_trest (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
int pos;
|
|
|
|
for (pos = 0; pos < arr_len; pos++) MANGLE_TOGGLE_AT (arr, pos);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_reverse (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
int l;
|
|
int r;
|
|
|
|
for (l = 0; l < arr_len; l++)
|
|
{
|
|
r = arr_len - 1 - l;
|
|
|
|
if (l >= r) break;
|
|
|
|
MANGLE_SWITCH (arr, l, r);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_double (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
if ((arr_len * 2) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
memcpy (&arr[arr_len], arr, (size_t) arr_len);
|
|
|
|
return (arr_len * 2);
|
|
}
|
|
|
|
int mangle_double_times (char arr[BLOCK_SIZE], int arr_len, int times)
|
|
{
|
|
if (((arr_len * times) + arr_len) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
int orig_len = arr_len;
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < times; i++)
|
|
{
|
|
memcpy (&arr[arr_len], arr, orig_len);
|
|
|
|
arr_len += orig_len;
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_reflect (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
if ((arr_len * 2) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
mangle_double (arr, arr_len);
|
|
|
|
mangle_reverse (arr + arr_len, arr_len);
|
|
|
|
return (arr_len * 2);
|
|
}
|
|
|
|
int mangle_rotate_left (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
int l;
|
|
int r;
|
|
|
|
for (l = 0, r = arr_len - 1; r > 0; r--)
|
|
{
|
|
MANGLE_SWITCH (arr, l, r);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_rotate_right (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
int l;
|
|
int r;
|
|
|
|
for (l = 0, r = arr_len - 1; l < r; l++)
|
|
{
|
|
MANGLE_SWITCH (arr, l, r);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_append (char arr[BLOCK_SIZE], int arr_len, char c)
|
|
{
|
|
if ((arr_len + 1) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
arr[arr_len] = c;
|
|
|
|
return (arr_len + 1);
|
|
}
|
|
|
|
int mangle_prepend (char arr[BLOCK_SIZE], int arr_len, char c)
|
|
{
|
|
if ((arr_len + 1) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = arr_len - 1; arr_pos > -1; arr_pos--)
|
|
{
|
|
arr[arr_pos + 1] = arr[arr_pos];
|
|
}
|
|
|
|
arr[0] = c;
|
|
|
|
return (arr_len + 1);
|
|
}
|
|
|
|
int mangle_delete_at (char arr[BLOCK_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = upos; arr_pos < arr_len - 1; arr_pos++)
|
|
{
|
|
arr[arr_pos] = arr[arr_pos + 1];
|
|
}
|
|
|
|
return (arr_len - 1);
|
|
}
|
|
|
|
int mangle_extract (char arr[BLOCK_SIZE], int arr_len, int upos, int ulen)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
if ((upos + ulen) > arr_len) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = 0; arr_pos < ulen; arr_pos++)
|
|
{
|
|
arr[arr_pos] = arr[upos + arr_pos];
|
|
}
|
|
|
|
return (ulen);
|
|
}
|
|
|
|
int mangle_omit (char arr[BLOCK_SIZE], int arr_len, int upos, int ulen)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
if ((upos + ulen) >= arr_len) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = upos; arr_pos < arr_len - ulen; arr_pos++)
|
|
{
|
|
arr[arr_pos] = arr[arr_pos + ulen];
|
|
}
|
|
|
|
return (arr_len - ulen);
|
|
}
|
|
|
|
int mangle_insert (char arr[BLOCK_SIZE], int arr_len, int upos, char c)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
if ((arr_len + 1) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = arr_len - 1; arr_pos > upos - 1; arr_pos--)
|
|
{
|
|
arr[arr_pos + 1] = arr[arr_pos];
|
|
}
|
|
|
|
arr[upos] = c;
|
|
|
|
return (arr_len + 1);
|
|
}
|
|
|
|
int mangle_insert_multi (char arr[BLOCK_SIZE], int arr_len, int arr_pos, char arr2[BLOCK_SIZE], int arr2_len, int arr2_pos, int arr2_cpy)
|
|
{
|
|
if ((arr_len + arr2_cpy) > BLOCK_SIZE) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (arr_pos > arr_len) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (arr2_pos > arr2_len) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if ((arr2_pos + arr2_cpy) > arr2_len) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (arr2_cpy < 1) return (RULE_RC_SYNTAX_ERROR);
|
|
|
|
memcpy (arr2, arr2 + arr2_pos, arr2_len - arr2_pos);
|
|
|
|
memcpy (arr2 + arr2_cpy, arr + arr_pos, arr_len - arr_pos);
|
|
|
|
memcpy (arr + arr_pos, arr2, arr_len - arr_pos + arr2_cpy);
|
|
|
|
return (arr_len + arr2_cpy);
|
|
}
|
|
|
|
int mangle_overstrike (char arr[BLOCK_SIZE], int arr_len, int upos, char c)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] = c;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_truncate_at (char arr[BLOCK_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
memset (arr + upos, 0, arr_len - upos);
|
|
|
|
return (upos);
|
|
}
|
|
|
|
int mangle_replace (char arr[BLOCK_SIZE], int arr_len, char oldc, char newc)
|
|
{
|
|
int arr_pos;
|
|
|
|
for (arr_pos = 0; arr_pos < arr_len; arr_pos++)
|
|
{
|
|
if (arr[arr_pos] != oldc) continue;
|
|
|
|
arr[arr_pos] = newc;
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_purgechar (char arr[BLOCK_SIZE], int arr_len, char c)
|
|
{
|
|
int arr_pos;
|
|
|
|
int ret_len;
|
|
|
|
for (ret_len = 0, arr_pos = 0; arr_pos < arr_len; arr_pos++)
|
|
{
|
|
if (arr[arr_pos] == c) continue;
|
|
|
|
arr[ret_len] = arr[arr_pos];
|
|
|
|
ret_len++;
|
|
}
|
|
|
|
return (ret_len);
|
|
}
|
|
|
|
int mangle_dupeblock_prepend (char arr[BLOCK_SIZE], int arr_len, int ulen)
|
|
{
|
|
if (ulen > arr_len) return (arr_len);
|
|
|
|
if ((arr_len + ulen) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
char cs[100];
|
|
|
|
memcpy (cs, arr, ulen);
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ulen; i++)
|
|
{
|
|
char c = cs[i];
|
|
|
|
arr_len = mangle_insert (arr, arr_len, i, c);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_dupeblock_append (char arr[BLOCK_SIZE], int arr_len, int ulen)
|
|
{
|
|
if (ulen > arr_len) return (arr_len);
|
|
|
|
if ((arr_len + ulen) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
int upos = arr_len - ulen;
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ulen; i++)
|
|
{
|
|
char c = arr[upos + i];
|
|
|
|
arr_len = mangle_append (arr, arr_len, c);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_dupechar_at (char arr[BLOCK_SIZE], int arr_len, int upos, int ulen)
|
|
{
|
|
if ( arr_len == 0) return (arr_len);
|
|
if ((arr_len + ulen) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
char c = arr[upos];
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ulen; i++)
|
|
{
|
|
arr_len = mangle_insert (arr, arr_len, upos, c);
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_dupechar (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
if ( arr_len == 0) return (arr_len);
|
|
if ((arr_len + arr_len) >= BLOCK_SIZE) return (arr_len);
|
|
|
|
int arr_pos;
|
|
|
|
for (arr_pos = arr_len - 1; arr_pos > -1; arr_pos--)
|
|
{
|
|
int new_pos = arr_pos * 2;
|
|
|
|
arr[new_pos] = arr[arr_pos];
|
|
|
|
arr[new_pos + 1] = arr[arr_pos];
|
|
}
|
|
|
|
return (arr_len * 2);
|
|
}
|
|
|
|
int mangle_switch_at_check (char arr[BLOCK_SIZE], int arr_len, int upos, int upos2)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
if (upos2 >= arr_len) return (arr_len);
|
|
|
|
MANGLE_SWITCH (arr, upos, upos2);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_switch_at (char arr[BLOCK_SIZE], int arr_len, int upos, int upos2)
|
|
{
|
|
MANGLE_SWITCH (arr, upos, upos2);
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_chr_shiftl (uint8_t arr[BLOCK_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] <<= 1;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_chr_shiftr (uint8_t arr[BLOCK_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] >>= 1;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_chr_incr (uint8_t arr[BLOCK_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] += 1;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_chr_decr (uint8_t arr[BLOCK_SIZE], int arr_len, int upos)
|
|
{
|
|
if (upos >= arr_len) return (arr_len);
|
|
|
|
arr[upos] -= 1;
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int mangle_title (char arr[BLOCK_SIZE], int arr_len)
|
|
{
|
|
int upper_next = 1;
|
|
|
|
int pos;
|
|
|
|
for (pos = 0; pos < arr_len; pos++)
|
|
{
|
|
if (arr[pos] == ' ')
|
|
{
|
|
upper_next = 1;
|
|
|
|
continue;
|
|
}
|
|
|
|
if (upper_next)
|
|
{
|
|
upper_next = 0;
|
|
|
|
MANGLE_UPPER_AT (arr, pos);
|
|
}
|
|
else
|
|
{
|
|
MANGLE_LOWER_AT (arr, pos);
|
|
}
|
|
}
|
|
|
|
return (arr_len);
|
|
}
|
|
|
|
int generate_random_rule (char rule_buf[RP_RULE_BUFSIZ], uint32_t rp_gen_func_min, uint32_t rp_gen_func_max)
|
|
{
|
|
uint32_t rp_gen_num = get_random_num (rp_gen_func_min, rp_gen_func_max);
|
|
|
|
uint32_t j;
|
|
|
|
uint32_t rule_pos = 0;
|
|
|
|
for (j = 0; j < rp_gen_num; j++)
|
|
{
|
|
uint32_t r = 0;
|
|
uint32_t p1 = 0;
|
|
uint32_t p2 = 0;
|
|
uint32_t p3 = 0;
|
|
|
|
switch ((char) get_random_num (0, 9))
|
|
{
|
|
case 0:
|
|
r = get_random_num (0, sizeof (grp_op_nop));
|
|
rule_buf[rule_pos++] = grp_op_nop[r];
|
|
break;
|
|
|
|
case 1:
|
|
r = get_random_num (0, sizeof (grp_op_pos_p0));
|
|
rule_buf[rule_pos++] = grp_op_pos_p0[r];
|
|
p1 = get_random_num (0, sizeof (grp_pos));
|
|
rule_buf[rule_pos++] = grp_pos[p1];
|
|
break;
|
|
|
|
case 2:
|
|
r = get_random_num (0, sizeof (grp_op_pos_p1));
|
|
rule_buf[rule_pos++] = grp_op_pos_p1[r];
|
|
p1 = get_random_num (1, 6);
|
|
rule_buf[rule_pos++] = grp_pos[p1];
|
|
break;
|
|
|
|
case 3:
|
|
r = get_random_num (0, sizeof (grp_op_chr));
|
|
rule_buf[rule_pos++] = grp_op_chr[r];
|
|
p1 = get_random_num (0x20, 0x7e);
|
|
rule_buf[rule_pos++] = (char) p1;
|
|
break;
|
|
|
|
case 4:
|
|
r = get_random_num (0, sizeof (grp_op_chr_chr));
|
|
rule_buf[rule_pos++] = grp_op_chr_chr[r];
|
|
p1 = get_random_num (0x20, 0x7e);
|
|
rule_buf[rule_pos++] = (char) p1;
|
|
p2 = get_random_num (0x20, 0x7e);
|
|
while (p1 == p2)
|
|
p2 = get_random_num (0x20, 0x7e);
|
|
rule_buf[rule_pos++] = (char) p2;
|
|
break;
|
|
|
|
case 5:
|
|
r = get_random_num (0, sizeof (grp_op_pos_chr));
|
|
rule_buf[rule_pos++] = grp_op_pos_chr[r];
|
|
p1 = get_random_num (0, sizeof (grp_pos));
|
|
rule_buf[rule_pos++] = grp_pos[p1];
|
|
p2 = get_random_num (0x20, 0x7e);
|
|
rule_buf[rule_pos++] = (char) p2;
|
|
break;
|
|
|
|
case 6:
|
|
r = get_random_num (0, sizeof (grp_op_pos_pos0));
|
|
rule_buf[rule_pos++] = grp_op_pos_pos0[r];
|
|
p1 = get_random_num (0, sizeof (grp_pos));
|
|
rule_buf[rule_pos++] = grp_pos[p1];
|
|
p2 = get_random_num (0, sizeof (grp_pos));
|
|
while (p1 == p2)
|
|
p2 = get_random_num (0, sizeof (grp_pos));
|
|
rule_buf[rule_pos++] = grp_pos[p2];
|
|
break;
|
|
|
|
case 7:
|
|
r = get_random_num (0, sizeof (grp_op_pos_pos1));
|
|
rule_buf[rule_pos++] = grp_op_pos_pos1[r];
|
|
p1 = get_random_num (0, sizeof (grp_pos));
|
|
rule_buf[rule_pos++] = grp_pos[p1];
|
|
p2 = get_random_num (1, sizeof (grp_pos));
|
|
while (p1 == p2)
|
|
p2 = get_random_num (1, sizeof (grp_pos));
|
|
rule_buf[rule_pos++] = grp_pos[p2];
|
|
break;
|
|
|
|
case 8:
|
|
r = get_random_num (0, sizeof (grp_op_pos1_pos2_pos3));
|
|
rule_buf[rule_pos++] = grp_op_pos1_pos2_pos3[r];
|
|
p1 = get_random_num (0, sizeof (grp_pos));
|
|
rule_buf[rule_pos++] = grp_pos[p1];
|
|
p2 = get_random_num (1, sizeof (grp_pos));
|
|
rule_buf[rule_pos++] = grp_pos[p1];
|
|
p3 = get_random_num (0, sizeof (grp_pos));
|
|
rule_buf[rule_pos++] = grp_pos[p3];
|
|
break;
|
|
}
|
|
}
|
|
|
|
return (rule_pos);
|
|
}
|
|
|
|
int _old_apply_rule (char *rule, int rule_len, char in[BLOCK_SIZE], int in_len, char out[BLOCK_SIZE])
|
|
{
|
|
char mem[BLOCK_SIZE];
|
|
|
|
if (in == NULL) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (out == NULL) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (in_len < 1) return (RULE_RC_REJECT_ERROR);
|
|
|
|
if (rule_len < 1) return (RULE_RC_REJECT_ERROR);
|
|
|
|
int out_len = in_len;
|
|
int mem_len = in_len;
|
|
|
|
memcpy (out, in, out_len);
|
|
|
|
int rule_pos;
|
|
|
|
for (rule_pos = 0; rule_pos < rule_len; rule_pos++)
|
|
{
|
|
int upos; int upos2;
|
|
int ulen;
|
|
|
|
switch (rule[rule_pos])
|
|
{
|
|
case ' ':
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_NOOP:
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_LREST:
|
|
out_len = mangle_lrest (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_UREST:
|
|
out_len = mangle_urest (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_LREST_UFIRST:
|
|
out_len = mangle_lrest (out, out_len);
|
|
if (out_len) MANGLE_UPPER_AT (out, 0);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_UREST_LFIRST:
|
|
out_len = mangle_urest (out, out_len);
|
|
if (out_len) MANGLE_LOWER_AT (out, 0);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TREST:
|
|
out_len = mangle_trest (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TOGGLE_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if (upos < out_len) MANGLE_TOGGLE_AT (out, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REVERSE:
|
|
out_len = mangle_reverse (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEWORD:
|
|
out_len = mangle_double (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEWORD_TIMES:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_double_times (out, out_len, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REFLECT:
|
|
out_len = mangle_reflect (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_ROTATE_LEFT:
|
|
mangle_rotate_left (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_ROTATE_RIGHT:
|
|
mangle_rotate_right (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_APPEND:
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_append (out, out_len, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PREPEND:
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_prepend (out, out_len, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_FIRST:
|
|
out_len = mangle_delete_at (out, out_len, 0);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_LAST:
|
|
out_len = mangle_delete_at (out, out_len, (out_len) ? out_len - 1 : 0);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DELETE_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
out_len = mangle_delete_at (out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_EXTRACT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_extract (out, out_len, upos, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_OMIT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_omit (out, out_len, upos, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_INSERT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_insert (out, out_len, upos, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_OVERSTRIKE:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_overstrike (out, out_len, upos, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TRUNCATE_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
out_len = mangle_truncate_at (out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_replace (out, out_len, rule[rule_pos - 1], rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PURGECHAR:
|
|
NEXT_RULEPOS (rule_pos);
|
|
out_len = mangle_purgechar (out, out_len, rule[rule_pos]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TOGGLECASE_REC:
|
|
/* todo */
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_FIRST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_dupechar_at (out, out_len, 0, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_LAST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_dupechar_at (out, out_len, out_len - 1, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPECHAR_ALL:
|
|
out_len = mangle_dupechar (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEBLOCK_FIRST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_dupeblock_prepend (out, out_len, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_DUPEBLOCK_LAST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
out_len = mangle_dupeblock_append (out, out_len, ulen);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_FIRST:
|
|
if (out_len >= 2) mangle_switch_at (out, out_len, 0, 1);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_LAST:
|
|
if (out_len >= 2) mangle_switch_at (out, out_len, out_len - 1, out_len - 2);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_SWITCH_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos2);
|
|
out_len = mangle_switch_at_check (out, out_len, upos, upos2);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_SHIFTL:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
mangle_chr_shiftl ((uint8_t *) out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_SHIFTR:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
mangle_chr_shiftr ((uint8_t *) out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_INCR:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
mangle_chr_incr ((uint8_t *) out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_CHR_DECR:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
mangle_chr_decr ((uint8_t *) out, out_len, upos);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE_NP1:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if ((upos >= 0) && ((upos + 1) < out_len)) mangle_overstrike (out, out_len, upos, out[upos + 1]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_REPLACE_NM1:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if ((upos >= 1) && ((upos + 0) < out_len)) mangle_overstrike (out, out_len, upos, out[upos - 1]);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_TITLE:
|
|
out_len = mangle_title (out, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_EXTRACT_MEMORY:
|
|
if (mem_len < 1) return (RULE_RC_REJECT_ERROR);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, ulen);
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos2);
|
|
if ((out_len = mangle_insert_multi (out, out_len, upos2, mem, mem_len, upos, ulen)) < 1) return (out_len);
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_APPEND_MEMORY:
|
|
if (mem_len < 1) return (RULE_RC_REJECT_ERROR);
|
|
if ((out_len + mem_len) > BLOCK_SIZE) return (RULE_RC_REJECT_ERROR);
|
|
memcpy (out + out_len, mem, mem_len);
|
|
out_len += mem_len;
|
|
break;
|
|
|
|
case RULE_OP_MANGLE_PREPEND_MEMORY:
|
|
if (mem_len < 1) return (RULE_RC_REJECT_ERROR);
|
|
if ((mem_len + out_len) > BLOCK_SIZE) return (RULE_RC_REJECT_ERROR);
|
|
memcpy (mem + mem_len, out, out_len);
|
|
out_len += mem_len;
|
|
memcpy (out, mem, out_len);
|
|
break;
|
|
|
|
case RULE_OP_MEMORIZE_WORD:
|
|
memcpy (mem, out, out_len);
|
|
mem_len = out_len;
|
|
break;
|
|
|
|
case RULE_OP_REJECT_LESS:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if (out_len > upos) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_GREATER:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if (out_len < upos) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_CONTAIN:
|
|
NEXT_RULEPOS (rule_pos);
|
|
if (strchr (out, rule[rule_pos]) != NULL) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_NOT_CONTAIN:
|
|
NEXT_RULEPOS (rule_pos);
|
|
if (strchr (out, rule[rule_pos]) == NULL) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_EQUAL_FIRST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
if (out[0] != rule[rule_pos]) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_EQUAL_LAST:
|
|
NEXT_RULEPOS (rule_pos);
|
|
if (out[out_len - 1] != rule[rule_pos]) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_EQUAL_AT:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if ((upos + 1) > out_len) return (RULE_RC_REJECT_ERROR);
|
|
NEXT_RULEPOS (rule_pos);
|
|
if (out[upos] != rule[rule_pos]) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_CONTAINS:
|
|
NEXT_RULEPOS (rule_pos);
|
|
NEXT_RPTOI (rule, rule_pos, upos);
|
|
if ((upos + 1) > out_len) return (RULE_RC_REJECT_ERROR);
|
|
NEXT_RULEPOS (rule_pos);
|
|
int c; int cnt; for (c = 0, cnt = 0; c < out_len; c++) if (out[c] == rule[rule_pos]) cnt++;
|
|
if (cnt < upos) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
case RULE_OP_REJECT_MEMORY:
|
|
if ((out_len == mem_len) && (memcmp (out, mem, out_len) == 0)) return (RULE_RC_REJECT_ERROR);
|
|
break;
|
|
|
|
default:
|
|
return (RULE_RC_SYNTAX_ERROR);
|
|
break;
|
|
}
|
|
}
|
|
|
|
memset (out + out_len, 0, BLOCK_SIZE - out_len);
|
|
|
|
return (out_len);
|
|
}
|