1 /*
2 * GOST 3411 cracker patch for JtR. Hacked together during
3 * May of 2012 by Dhiru Kholia <dhiru.kholia at gmail.com>,
4 * Sergey V. <sftp.mtuci at gmail com>, and JimF
5 *
6 * This software is Copyright (c) 2012, Dhiru Kholia <dhiru.kholia at gmail.com>,
7 * Sergey V. <sftp.mtuci at gmail com>, and JimF
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 modification,
10 * are permitted.
11 *
12 * Input Format => user:gost-hash;
13 * user:$gost$gost-hash;
14 * user:$gost-cp$gost-cryptopro-hash;
15 */
16
17 #if FMT_EXTERNS_H
18 extern struct fmt_main fmt_gost;
19 #elif FMT_REGISTERS_H
20 john_register_one(&fmt_gost);
21 #else
22
23 #include <string.h>
24
25 #ifdef _OPENMP
26 #include <omp.h>
27 #endif
28
29 #include "arch.h"
30 #include "misc.h"
31 #include "common.h"
32 #include "formats.h"
33 #include "params.h"
34 #include "options.h"
35 #include "gost.h"
36
37 #define FORMAT_LABEL "gost"
38 #define FORMAT_NAME "GOST R 34.11-94"
39
40 #define FORMAT_TAG "$gost$"
41 #define TAG_LENGTH (sizeof(FORMAT_TAG)-1)
42 #define FORMAT_TAG_CP "$gost-cp$"
43 #define TAG_CP_LENGTH (sizeof(FORMAT_TAG_CP)-1)
44 #if !defined(USE_GCC_ASM_IA32) && defined(USE_GCC_ASM_X64)
45 #define ALGORITHM_NAME "64/64"
46 #else
47 #define ALGORITHM_NAME "32/" ARCH_BITS_STR
48 #endif
49 #define BENCHMARK_COMMENT ""
50 #define BENCHMARK_LENGTH 0x507 // Actually unsalted but two variants
51 #define PLAINTEXT_LENGTH 125
52 #define CIPHERTEXT_LENGTH 64
53 #define BINARY_SIZE 32
54 #define SALT_SIZE 1
55 #define SALT_ALIGN 1
56 #define BINARY_ALIGN sizeof(uint32_t)
57 #define MIN_KEYS_PER_CRYPT 1
58 #define MAX_KEYS_PER_CRYPT 128
59
60 #ifndef OMP_SCALE
61 #define OMP_SCALE 2 // Tuned w/ MKPC for core i7
62 #endif
63
64 static struct fmt_tests gost_tests[] = {
65 {"ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d", ""},
66 {"d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd", "a"},
67 {FORMAT_TAG "ce85b99cc46752fffee35cab9a7b0278abb4c2d2055cff685af4912c49490f8d", ""},
68 {FORMAT_TAG "d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd", "a"},
69 {FORMAT_TAG "ad4434ecb18f2c99b60cbe59ec3d2469582b65273f48de72db2fde16a4889a4d", "message digest"},
70 {FORMAT_TAG "0886f91e7fcaff65eb2635a1a4c9f203003e0ce5ea74b72fc6462cc72649694e",
71 "This is very very long pass phrase for test gost hash function."},
72 {FORMAT_TAG_CP "981e5f3ca30c841487830f84fb433e13ac1101569b9c13584ac483234cd656c0", ""},
73 {FORMAT_TAG_CP "e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011", "a"},
74 {FORMAT_TAG_CP "bc6041dd2aa401ebfa6e9886734174febdb4729aa972d60f549ac39b29721ba0", "message digest"},
75 {FORMAT_TAG_CP "5394adfacb65a9ac5781c3080b244c955a9bf03befd51582c3850b8935f80762",
76 "This is very very long pass phrase for test gost hash function."},
77 {NULL}
78 };
79
80 static char (*saved_key)[PLAINTEXT_LENGTH + 1];
81 static uint32_t (*crypt_out)[8];
82 static int is_cryptopro; /* non 0 for CryptoPro hashes */
83
init(struct fmt_main * self)84 static void init(struct fmt_main *self)
85 {
86 omp_autotune(self, OMP_SCALE);
87
88 gost_init_table();
89 saved_key = mem_calloc(self->params.max_keys_per_crypt,
90 sizeof(*saved_key));
91 crypt_out = mem_calloc(self->params.max_keys_per_crypt,
92 sizeof(*crypt_out));
93 }
94
done(void)95 static void done(void)
96 {
97 MEM_FREE(crypt_out);
98 MEM_FREE(saved_key);
99 }
100
valid(char * ciphertext,struct fmt_main * self)101 static int valid(char *ciphertext, struct fmt_main *self)
102 {
103 char *p, *q;
104
105 p = ciphertext;
106
107 if (!strncmp(p, FORMAT_TAG, TAG_LENGTH))
108 p += TAG_LENGTH;
109 else if (!strncmp(p, FORMAT_TAG_CP, TAG_CP_LENGTH))
110 p += TAG_CP_LENGTH;
111
112 q = p;
113 while (atoi16[ARCH_INDEX(*q)] != 0x7F)
114 q++;
115
116 return !*q && q - p == CIPHERTEXT_LENGTH;
117 }
118
119
split(char * ciphertext,int index,struct fmt_main * self)120 static char *split(char *ciphertext, int index, struct fmt_main *self)
121 {
122 static char out[TAG_CP_LENGTH + CIPHERTEXT_LENGTH + 1];
123 char *cp=&out[TAG_LENGTH];
124 strcpy(out, FORMAT_TAG);
125 if (!strncmp(ciphertext, FORMAT_TAG, TAG_LENGTH))
126 ciphertext += TAG_LENGTH;
127 else if (!strncmp(ciphertext, FORMAT_TAG_CP, TAG_CP_LENGTH)) {
128 ciphertext += TAG_CP_LENGTH;
129 strcpy(out, FORMAT_TAG_CP);
130 cp=&out[TAG_CP_LENGTH];
131 }
132 memcpy(cp, ciphertext, CIPHERTEXT_LENGTH + 1);
133 strlwr(cp);
134 return out;
135 }
136
get_salt(char * ciphertext)137 static void *get_salt(char *ciphertext)
138 {
139 static char i;
140
141 if (!strncmp(ciphertext, FORMAT_TAG, TAG_LENGTH))
142 i=0;
143 else
144 i=1;
145 return &i;
146 }
147
set_salt(void * salt)148 static void set_salt(void *salt)
149 {
150 is_cryptopro = *(char*)salt;
151 }
152
get_binary(char * ciphertext)153 static void *get_binary(char *ciphertext)
154 {
155 static unsigned char *out;
156 char *p;
157 int i;
158
159 if (!out) out = mem_alloc_tiny(BINARY_SIZE, MEM_ALIGN_WORD);
160
161 if (!strncmp(ciphertext, FORMAT_TAG, TAG_LENGTH))
162 p = ciphertext + TAG_LENGTH;
163 else
164 p = ciphertext + TAG_CP_LENGTH;
165
166 for (i = 0; i < BINARY_SIZE; i++) {
167 out[i] =
168 (atoi16[ARCH_INDEX(*p)] << 4) |
169 atoi16[ARCH_INDEX(p[1])];
170 p += 2;
171 }
172
173 return out;
174 }
175
176 #define COMMON_GET_HASH_VAR crypt_out
177 #include "common-get-hash.h"
178
crypt_all(int * pcount,struct db_salt * salt)179 static int crypt_all(int *pcount, struct db_salt *salt)
180 {
181 const int count = *pcount;
182 int index;
183 #ifdef _OPENMP
184 #pragma omp parallel for
185 #endif
186 for (index = 0; index < count; index++) {
187 gost_ctx ctx;
188
189 if (is_cryptopro)
190 john_gost_cryptopro_init(&ctx);
191 else
192 john_gost_init(&ctx);
193 john_gost_update(&ctx, (const unsigned char*)saved_key[index],
194 strlen(saved_key[index]));
195
196 john_gost_final(&ctx, (unsigned char *)crypt_out[index]);
197 }
198
199 return count;
200 }
201
cmp_all(void * binary,int count)202 static int cmp_all(void *binary, int count)
203 {
204 int index;
205
206 for (index = 0; index < count; index++)
207 if (crypt_out[index][0] == *(uint32_t*)binary)
208 return 1;
209
210 return 0;
211 }
212
cmp_one(void * binary,int index)213 static int cmp_one(void *binary, int index)
214 {
215 return !memcmp(binary, crypt_out[index], BINARY_SIZE);
216 }
217
cmp_exact(char * source,int index)218 static int cmp_exact(char *source, int index)
219 {
220 return 1;
221 }
222
set_key(char * key,int index)223 static void set_key(char *key, int index)
224 {
225 strnzcpy(saved_key[index], key, sizeof(*saved_key));
226 }
227
get_key(int index)228 static char *get_key(int index)
229 {
230 return saved_key[index];
231 }
232
233 struct fmt_main fmt_gost = {
234 {
235 FORMAT_LABEL,
236 FORMAT_NAME,
237 ALGORITHM_NAME,
238 BENCHMARK_COMMENT,
239 BENCHMARK_LENGTH,
240 0,
241 PLAINTEXT_LENGTH,
242 BINARY_SIZE,
243 BINARY_ALIGN,
244 SALT_SIZE,
245 SALT_ALIGN,
246 MIN_KEYS_PER_CRYPT,
247 MAX_KEYS_PER_CRYPT,
248 FMT_CASE | FMT_8_BIT | FMT_OMP | FMT_SPLIT_UNIFIES_CASE,
249 { NULL },
250 { FORMAT_TAG, FORMAT_TAG_CP },
251 gost_tests
252 }, {
253 init,
254 done,
255 fmt_default_reset,
256 fmt_default_prepare,
257 valid,
258 split,
259 get_binary,
260 get_salt,
261 { NULL },
262 fmt_default_source,
263 {
264 fmt_default_binary_hash_0,
265 fmt_default_binary_hash_1,
266 fmt_default_binary_hash_2,
267 fmt_default_binary_hash_3,
268 fmt_default_binary_hash_4,
269 fmt_default_binary_hash_5,
270 fmt_default_binary_hash_6
271 },
272 fmt_default_salt_hash,
273 NULL,
274 set_salt,
275 set_key,
276 get_key,
277 fmt_default_clear_keys,
278 crypt_all,
279 {
280 #define COMMON_GET_HASH_LINK
281 #include "common-get-hash.h"
282 },
283 cmp_all,
284 cmp_one,
285 cmp_exact
286 }
287 };
288
289 #endif /* plugin stanza */
290