1 /*
2 * PST cracker patch for JtR. Hacked together during July of 2012 by
3 * Dhiru Kholia <dhiru.kholia at gmail.com>
4 *
5 * Optimizations and shift to pkzip CRC32 code done by JimF.
6 *
7 * This software is Copyright (c) 2012, Dhiru Kholia <dhiru.kholia at gmail.com>
8 * and it is hereby released to the general public under the following terms:
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted.
11 *
12 * Uses code from crc32_fmt_plug.c written by JimF.
13 */
14
15 #if FMT_EXTERNS_H
16 extern struct fmt_main fmt_pst;
17 #elif FMT_REGISTERS_H
18 john_register_one(&fmt_pst);
19 #else
20
21 #include <string.h>
22
23 #include "arch.h"
24 #if !FAST_FORMATS_OMP
25 #undef _OPENMP
26 #endif
27 #ifdef _OPENMP
28 #include <omp.h>
29 #endif
30
31 #include "misc.h"
32 #include "common.h"
33 #include "formats.h"
34 #include "crc32.h"
35
36 #define FORMAT_LABEL "PST"
37 #define FORMAT_NAME "custom CRC-32"
38 #define FORMAT_TAG "$pst$"
39 #define FORMAT_TAG_LEN (sizeof(FORMAT_TAG)-1)
40 #define ALGORITHM_NAME "32/" ARCH_BITS_STR
41 #define BENCHMARK_COMMENT ""
42 #define BENCHMARK_LENGTH 0x107
43 #define PLAINTEXT_LENGTH 8
44 #define BINARY_SIZE 4
45 #define SALT_SIZE 0
46 #define BINARY_ALIGN sizeof(uint32_t)
47 #define SALT_ALIGN 1
48 #define MIN_KEYS_PER_CRYPT 1
49 #define MAX_KEYS_PER_CRYPT 1024
50
51 #ifdef __MIC__
52 #ifndef OMP_SCALE
53 #define OMP_SCALE 1024
54 #endif
55 #else
56 #ifndef OMP_SCALE
57 #define OMP_SCALE 16 // Tuned w/ MKPC for core i7
58 #endif
59 #endif
60
61 static struct fmt_tests tests[] = {
62 {"$pst$a9290513", "openwall"}, /* "jfuck jw" works too ;) */
63 {"$pst$50e099bc", "password"},
64 {"$pst$00000000", ""},
65 {"$pst$e3da3318", "xxx"},
66 {"$pst$a655dd18", "XYz123"},
67 {"$pst$29b14070", "thisisalongstring"},
68 {"$pst$25b44615", "string with space"},
69 {NULL}
70 };
71
72 static char (*saved_key)[PLAINTEXT_LENGTH + 1];
73 static uint32_t (*crypt_out);
74
init(struct fmt_main * self)75 static void init(struct fmt_main *self)
76 {
77 omp_autotune(self, OMP_SCALE);
78
79 saved_key = mem_calloc(self->params.max_keys_per_crypt,
80 sizeof(*saved_key));
81 crypt_out = mem_calloc(self->params.max_keys_per_crypt,
82 sizeof(*crypt_out));
83 }
84
done(void)85 static void done(void)
86 {
87 MEM_FREE(crypt_out);
88 MEM_FREE(saved_key);
89 }
90
valid(char * ciphertext,struct fmt_main * self)91 static int valid(char *ciphertext, struct fmt_main *self)
92 {
93 char *p;
94 int extra;
95
96 if (strncmp(ciphertext, FORMAT_TAG, FORMAT_TAG_LEN))
97 return 0;
98 p = ciphertext + FORMAT_TAG_LEN;
99 if (hexlenl(p, &extra) != BINARY_SIZE * 2 || extra)
100 return 0;
101 return 1;
102 }
103
set_key(char * key,int index)104 static void set_key(char *key, int index) {
105 strnzcpyn(saved_key[index], key, sizeof(*saved_key));
106 }
107
cmp_all(void * binary,int count)108 static int cmp_all(void *binary, int count)
109 {
110 uint32_t crc=*((uint32_t*)binary), i;
111
112 for (i = 0; i < count; ++i)
113 if (crc == crypt_out[i]) return 1;
114 return 0;
115 }
116
cmp_one(void * binary,int index)117 static int cmp_one(void *binary, int index)
118 {
119 return *((uint32_t*)binary) == crypt_out[index];
120 }
121
cmp_exact(char * source,int index)122 static int cmp_exact(char *source, int index)
123 {
124 return 1;
125 }
126
crypt_all(int * pcount,struct db_salt * salt)127 static int crypt_all(int *pcount, struct db_salt *salt)
128 {
129 const int count = *pcount;
130 int i;
131
132 #ifdef _OPENMP
133 #pragma omp parallel for private(i)
134 #endif
135 for (i = 0; i < count; ++i) {
136 CRC32_t crc = 0;
137 unsigned char *p = (unsigned char*)saved_key[i];
138 while (*p)
139 crc = jtr_crc32(crc, *p++);
140 crypt_out[i] = crc;
141 }
142 return count;
143 }
144
get_binary(char * ciphertext)145 static void *get_binary(char *ciphertext)
146 {
147 static uint32_t *out;
148
149 if (!out)
150 out = mem_alloc_tiny(sizeof(uint32_t), MEM_ALIGN_WORD);
151 sscanf(&ciphertext[FORMAT_TAG_LEN], "%x", out);
152
153 return out;
154 }
155
get_key(int index)156 static char *get_key(int index)
157 {
158 return saved_key[index];
159 }
160
161 #define COMMON_GET_HASH_VAR crypt_out
162 #include "common-get-hash.h"
163
164 struct fmt_main fmt_pst = {
165 {
166 FORMAT_LABEL,
167 FORMAT_NAME,
168 ALGORITHM_NAME,
169 BENCHMARK_COMMENT,
170 BENCHMARK_LENGTH,
171 0,
172 PLAINTEXT_LENGTH,
173 BINARY_SIZE,
174 BINARY_ALIGN,
175 SALT_SIZE,
176 SALT_ALIGN,
177 MIN_KEYS_PER_CRYPT,
178 MAX_KEYS_PER_CRYPT,
179 #ifdef _OPENMP
180 FMT_OMP | FMT_OMP_BAD |
181 #endif
182 FMT_CASE | FMT_TRUNC | FMT_8_BIT | FMT_NOT_EXACT,
183 { NULL },
184 { FORMAT_TAG },
185 tests
186 }, {
187 init,
188 done,
189 fmt_default_reset,
190 fmt_default_prepare,
191 valid,
192 fmt_default_split,
193 get_binary,
194 fmt_default_salt,
195 { NULL },
196 fmt_default_source,
197 {
198 fmt_default_binary_hash_0,
199 fmt_default_binary_hash_1,
200 fmt_default_binary_hash_2,
201 fmt_default_binary_hash_3,
202 fmt_default_binary_hash_4,
203 fmt_default_binary_hash_5,
204 fmt_default_binary_hash_6
205 },
206 fmt_default_salt_hash,
207 NULL,
208 fmt_default_set_salt,
209 set_key,
210 get_key,
211 fmt_default_clear_keys,
212 crypt_all,
213 {
214 #define COMMON_GET_HASH_LINK
215 #include "common-get-hash.h"
216 },
217 cmp_all,
218 cmp_one,
219 cmp_exact
220 }
221 };
222
223 #endif /* plugin stanza */
224