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