1 /*
2  * MSCHAPv2_fmt.c -- Microsoft PPP CHAP Extensions, Version 2
3  *
4  * Written by JoMo-Kun <jmk at foofus.net> in 2010
5  * and placed in the public domain.
6  *
7  * Modified for performance, OMP and utf-8 support
8  * by magnum 2010-2011, no rights reserved
9  *
10  * Modified for using Bitsliced DES by Deepika Dutta Mishra
11  * <dipikadutta at gmail.com> in 2012, no rights reserved.
12  *
13  * Support for freeradius-wep-patch challenge/response format
14  * added by Linus Lüssing in 2012 and is licensed under CC0/PD terms:
15  *  To the extent possible under law, Linus Lüssing has waived all copyright
16  *  and related or neighboring rights to this work. This work is published from: Germany.
17  *
18  * This algorithm is designed for performing brute-force cracking of the
19  * MSCHAPv2 challenge/response sets exchanged during network-based
20  * authentication attempts. The captured challenge/response set from these
21  * attempts should be stored using the following format:
22  *
23  * USERNAME:::AUTHENTICATOR CHALLENGE:MSCHAPv2 RESPONSE:PEER CHALLENGE
24  * USERNAME::DOMAIN:AUTHENTICATOR CHALLENGE:MSCHAPv2 RESPONSE:PEER CHALLENGE
25  * DOMAIN\USERNAME:::AUTHENTICATOR CHALLENGE:MSCHAPv2 RESPONSE:PEER CHALLENGE
26  * :::MSCHAPv2 CHALLENGE:MSCHAPv2 RESPONSE:
27  *
28  * For example:
29  * User:::5B5D7C7D7B3F2F3E3C2C602132262628:82309ECD8D708B5EA08FAA3981CD83544233114A3D85D6DF:21402324255E262A28295F2B3A337C7E
30  * domain\fred:::56d64cbe7bad61349a0b752335100eaf:d7d829d9545cef1d631b4e568ffb7586050fa3a4d02dbc0b:7f8a466cff2a6bf0c80218bbf56d76bc
31  *
32  * http://freeradius.org/rfc/rfc2759.txt
33  *
34  */
35 
36 #if FMT_EXTERNS_H
37 extern struct fmt_main fmt_MSCHAPv2_old;
38 #elif FMT_REGISTERS_H
39 john_register_one(&fmt_MSCHAPv2_old);
40 #else
41 
42 #include <string.h>
43 #ifdef _OPENMP
44 #include <omp.h>
45 #endif
46 
47 #include "arch.h"
48 #include "DES_std.h"
49 #include "DES_bs.h"
50 #include "misc.h"
51 #include "common.h"
52 #include "formats.h"
53 #include "options.h"
54 #include "memory.h"
55 #include "sha.h"
56 #include "unicode.h"
57 
58 #ifndef uchar
59 #define uchar unsigned char
60 #endif
61 
62 #define FORMAT_LABEL         "mschapv2-naive"
63 #define FORMAT_NAME          "MSCHAPv2 C/R"
64 #define FORMAT_TAG           "$MSCHAPv2$"
65 #define FORMAT_TAG_LEN       (sizeof(FORMAT_TAG)-1)
66 #define ALGORITHM_NAME       "MD4 " DES_BS_ALGORITHM_NAME " naive"
67 #define BENCHMARK_COMMENT    ""
68 #define BENCHMARK_LENGTH     7
69 #define PLAINTEXT_LENGTH     125 /* lmcons.h - PWLEN (256) ? 127 ? */
70 #define USERNAME_LENGTH      256 /* lmcons.h - UNLEN (256) / LM20_UNLEN (20) */
71 #define DOMAIN_LENGTH        15  /* lmcons.h - CNLEN / DNLEN */
72 #define BINARY_SIZE          24
73 #define BINARY_ALIGN         4
74 #define CHALLENGE_LENGTH     64
75 #define SALT_SIZE            8
76 #define SALT_ALIGN           4
77 #define CIPHERTEXT_LENGTH    48
78 #define TOTAL_LENGTH         13 + USERNAME_LENGTH + CHALLENGE_LENGTH + CIPHERTEXT_LENGTH
79 
80 #define MIN_KEYS_PER_CRYPT      DES_BS_DEPTH
81 #define MAX_KEYS_PER_CRYPT      DES_BS_DEPTH
82 
83 static struct fmt_tests tests[] = {
84 	{"", "Cricket8",       {"testuser1",   "", "",    "d07054459a1fdbc266a006f0220e6fac", "33c8331a9b03b7e003f09dd253d740a2bead544143cc8bde", "3545cb1d89b507a5de104435e81b14a4"} },
85 	{"$MSCHAPv2$4c092fd3fd98236502e8591100046326$b912ce522524d33123a982cf330a57f8e953fa7974042b5d$6a4915d0ce61d42be533640a75391925$1111", "2222"},
86 	{"$MSCHAPv2$5B5D7C7D7B3F2F3E3C2C602132262628$82309ECD8D708B5EA08FAA3981CD83544233114A3D85D6DF$21402324255E262A28295F2B3A337C7E$User", "clientPass"},
87 	{"$MSCHAPv2$d07054459a1fdbc266a006f0220e6fac$33c8331a9b03b7e003f09dd253d740a2bead544143cc8bde$3545cb1d89b507a5de104435e81b14a4$testuser1", "Cricket8"},
88 	{"$MSCHAPv2$56d64cbe7bad61349a0b752335100eaf$d7d829d9545cef1d631b4e568ffb7586050fa3a4d02dbc0b$7f8a466cff2a6bf0c80218bbf56d76bc$fred", "OMG!BBQ!11!one"}, /* domain\fred */
89 	{"$MSCHAPv2$b3c42db475b881d3c52ff3923d7b3bf8$f07c7a4eb391f5debe32d814679a5a69661b86b33227c4f8$6321f8649b971bd11ce8d5cb22a4a738$bOb", "asdblahblahblahblahblahblahblahblah"}, /* WorkGroup\bOb */
90 	{"$MSCHAPv2$d94e7c7972b2376b28c268583e162de7$eba25a3b04d2c7085d01f842e2befc91745c40db0f792356$0677ca7318fd7f65ae1b4f58c9f4f400$lameuser", ""}, /* no password */
91 	{"$MSCHAPv2$8710da60ebfc4cab$c4e3bb55904c966927ee68e5f1472e1f5d8ec165713b5360$$foo4", "bar4" },
92 	{"$MSCHAPv2$8710da60ebfc4cab$c4e3bb55904c966927ee68e5f1472e1f5d8ec165713b5360$$", "bar4" },
93 
94 	/* Ettercap generated three test vectors */
95 	{"$MSCHAPv2$3D79CC8CDC0261D4$B700770725F87739ADB110B310D9A289CDBB550ADCA6CB86$solar", "solarisalwaysbusy"},
96 	{"$MSCHAPv2$BA75EB14EFBFBF25$ED8CC90FD40FAA2D6BCD0ABD0B1F562FD777DF6C5609C98B$lulu", "password"},
97 	{"$MSCHAPv2$95A87FA62EBCD2E3C8B09E1B448A6C72$ED8CC90FD40FAA2D6BCD0ABD0B1F562FD777DF6C5609C98B$E2AE0995EAAC6CEFF0D9757428B51509$lulu", "password"},
98 
99 	/* Single test vector from chapcrack's sample pcap file */
100 	{"$MSCHAPv2$6D0E1C056CD94D5F$1C93ABCE815400686BAECA315F348469256420598A73AD49$moxie", "bPCFyF2uL1p5Lg5yrKmqmY"},
101 
102 	{"", "clientPass",     {"User",        "", "",    "5B5D7C7D7B3F2F3E3C2C602132262628", "82309ECD8D708B5EA08FAA3981CD83544233114A3D85D6DF", "21402324255E262A28295F2B3A337C7E"} },
103 	{"", "OMG!BBQ!11!one", {"domain\\fred", "", "",   "56d64cbe7bad61349a0b752335100eaf", "d7d829d9545cef1d631b4e568ffb7586050fa3a4d02dbc0b", "7f8a466cff2a6bf0c80218bbf56d76bc"} }, /* domain\fred */
104 	{"", "",               {"lameuser", "", "domain", "d94e7c7972b2376b28c268583e162de7", "eba25a3b04d2c7085d01f842e2befc91745c40db0f792356", "0677ca7318fd7f65ae1b4f58c9f4f400"} }, /* no password */
105 	{"", "asdblahblahblahblahblahblahblahblah", {"WorkGroup\\bOb", "", "", "b3c42db475b881d3c52ff3923d7b3bf8", "f07c7a4eb391f5debe32d814679a5a69661b86b33227c4f8", "6321f8649b971bd11ce8d5cb22a4a738"} }, /* WorkGroup\bOb */
106 
107 	{NULL}
108 };
109 
110 static char (*saved_plain)[PLAINTEXT_LENGTH + 1];
111 static int (*saved_len);
112 static uchar (*saved_key)[21];
113 static uchar *challenge;
114 static int keys_prepared;
115 static void set_salt(void *salt);
116 static char *long_to_short(char *orig); /* used to cannonicalize the format */
117 
init(struct fmt_main * self)118 static void init(struct fmt_main *self)
119 {
120 	/* LM =2 for DES encryption with no salt and no iterations */
121 	DES_bs_init(2, DES_bs_cpt);
122 #if DES_bs_mt
123 	self->params.min_keys_per_crypt = DES_bs_min_kpc;
124 	self->params.max_keys_per_crypt = DES_bs_max_kpc;
125 #endif
126 	saved_plain = mem_calloc(self->params.max_keys_per_crypt,
127 	                         sizeof(*saved_plain));
128 	saved_len   = mem_calloc(self->params.max_keys_per_crypt,
129 	                         sizeof(*saved_len));
130 	saved_key   = mem_calloc(self->params.max_keys_per_crypt,
131 	                         sizeof(*saved_key));
132 }
133 
done(void)134 static void done(void)
135 {
136 	MEM_FREE(saved_key);
137 	MEM_FREE(saved_len);
138 	MEM_FREE(saved_plain);
139 }
140 
valid_long(char * ciphertext)141 static int valid_long(char *ciphertext)
142 {
143 	char *pos, *pos2;
144 
145 	if (ciphertext == NULL) return 0;
146 	else if (strncmp(ciphertext, FORMAT_TAG, FORMAT_TAG_LEN)!=0) return 0;
147 
148 	if (strlen(ciphertext) > TOTAL_LENGTH)
149 		return 0;
150 
151 	/* Validate Authenticator/Server Challenge Length */
152 	pos = &ciphertext[FORMAT_TAG_LEN];
153 	for (pos2 = pos; *pos2 != '$'; pos2++)
154 		if (atoi16[ARCH_INDEX(*pos2)] == 0x7F)
155 			return 0;
156 
157 	if ( !(*pos2 && (pos2 - pos == CHALLENGE_LENGTH / 2)) )
158 		return 0;
159 
160 	/* Validate MSCHAPv2 Response Length */
161 	pos2++; pos = pos2;
162 	for (; *pos2 != '$'; pos2++)
163 		if (atoi16[ARCH_INDEX(*pos2)] == 0x7F)
164 			return 0;
165 
166 	if ( !(*pos2 && (pos2 - pos == CIPHERTEXT_LENGTH)) )
167 		return 0;
168 
169 	/* Validate Peer/Client Challenge Length */
170 	pos2++; pos = pos2;
171 	for (; *pos2 != '$'; pos2++)
172 		if (atoi16[ARCH_INDEX(*pos2)] == 0x7F)
173 			return 0;
174 
175 	if ( !(*pos2 && (pos2 - pos == CHALLENGE_LENGTH / 2)) )
176 		return 0;
177 
178 	/* Validate Username Length */
179 	if (strlen(++pos2) > USERNAME_LENGTH)
180 		return 0;
181 
182 	return 1;
183 }
184 
valid_short(char * ciphertext)185 static int valid_short(char *ciphertext)
186 {
187 	char *pos, *pos2;
188 
189 	if (ciphertext == NULL) return 0;
190 	else if (strncmp(ciphertext, FORMAT_TAG, FORMAT_TAG_LEN)!=0) return 0;
191 
192 	if (strlen(ciphertext) > TOTAL_LENGTH)
193 		return 0;
194 
195 	/* Validate MSCHAPv2 Challenge Length */
196 	pos = &ciphertext[FORMAT_TAG_LEN];
197 	for (pos2 = pos; *pos2 != '$'; pos2++)
198 		if (atoi16[ARCH_INDEX(*pos2)] == 0x7F)
199 			return 0;
200 
201 	if ( !(*pos2 && (pos2 - pos == CHALLENGE_LENGTH / 4)) )
202 		return 0;
203 
204 	/* Validate MSCHAPv2 Response Length */
205 	pos2++; pos = pos2;
206 	for (; *pos2 != '$'; pos2++)
207 		if (atoi16[ARCH_INDEX(*pos2)] == 0x7F)
208 			return 0;
209 
210 	if ( !(*pos2 && (pos2 - pos == CIPHERTEXT_LENGTH)) )
211 		return 0;
212 
213 	return 1;
214 }
215 
valid(char * ciphertext,struct fmt_main * pFmt)216 static int valid(char *ciphertext, struct fmt_main *pFmt)
217 {
218 	return  valid_short(ciphertext) ||
219 		valid_long(ciphertext);
220 }
221 
prepare_long(char * split_fields[10])222 static char *prepare_long(char *split_fields[10])
223 {
224 	char *username, *cp;
225 
226 	/* DOMAIN\USERNAME -or - USERNAME -- ignore DOMAIN */
227 	if ((username = strstr(split_fields[0], "\\")) == NULL)
228 		username = split_fields[0];
229 	else
230 		username++;
231 
232 	cp = mem_alloc(FORMAT_TAG_LEN+strlen(split_fields[3])+1+strlen(split_fields[4])+1+strlen(split_fields[5])+1+strlen(username)+1);
233 	sprintf(cp, "%s%s$%s$%s$%s", FORMAT_TAG, split_fields[3], split_fields[4], split_fields[5], username);
234 	if (valid_long(cp)) {
235 		char *cp2 = str_alloc_copy(cp);
236 		MEM_FREE(cp);
237 		return cp2;
238 	}
239 	MEM_FREE(cp);
240 	return split_fields[1];
241 }
242 
prepare_short(char * split_fields[10])243 static char *prepare_short(char *split_fields[10])
244 {
245 	char *cp;
246 
247 	cp = mem_alloc(FORMAT_TAG_LEN+strlen(split_fields[3])+1+strlen(split_fields[4])+1+1+1);
248 	sprintf(cp, "%s%s$%s$$", FORMAT_TAG, split_fields[3], split_fields[4]);
249 	if (valid_short(cp)) {
250 		char *cp2 = str_alloc_copy(cp);
251 		MEM_FREE(cp);
252 		return cp2;
253 	}
254 	MEM_FREE(cp);
255 	return split_fields[1];
256 }
257 
prepare(char * split_fields[10],struct fmt_main * pFmt)258 static char *prepare(char *split_fields[10], struct fmt_main *pFmt)
259 {
260 	char *ret;
261 
262 	if (!strncmp(split_fields[1], FORMAT_TAG, FORMAT_TAG_LEN)) {
263 		// check for a short format that has any extra trash fields, and if so remove them.
264 		char *cp1, *cp2, *cp3;
265 		cp1 = split_fields[1];
266 		cp1 += FORMAT_TAG_LEN;
267 		cp2 = strchr(cp1, '$');
268 		ret = NULL;
269 		if (cp2 && cp2-cp1 == CHALLENGE_LENGTH/4) {
270 			++cp2;
271 			cp3 = strchr(cp2, '$');
272 			if (cp3 && cp3-cp2 == CIPHERTEXT_LENGTH && (strlen(cp3) > 2 || cp3[2] != '$')) {
273 				ret = str_alloc_copy(split_fields[1]);
274 				ret[(cp3-split_fields[1])+1] = '$';
275 				ret[(cp3-split_fields[1])+2] = 0;
276 				//printf("Here is the cut item: %s\n", ret);
277 			}
278 		}
279 	}
280 	else if (split_fields[0] && split_fields[3] && split_fields[4] && split_fields[5] &&
281 	        strlen(split_fields[3]) == CHALLENGE_LENGTH/2 &&
282 	        strlen(split_fields[4]) == CIPHERTEXT_LENGTH &&
283 	        strlen(split_fields[5]) == CHALLENGE_LENGTH/2)
284 		ret = prepare_long(split_fields);
285 	else if (split_fields[0] && split_fields[3] && split_fields[4] &&
286 	        strlen(split_fields[3]) == CHALLENGE_LENGTH/4 &&
287 	        strlen(split_fields[4]) == CIPHERTEXT_LENGTH)
288 		ret = prepare_short(split_fields);
289 	else
290 		ret = NULL;
291 
292 	if (ret && valid_long(ret))
293 		ret = long_to_short(ret);
294 	else if (valid_long(split_fields[1]))
295 		ret = long_to_short(split_fields[1]);
296 
297 	return ret ? ret : split_fields[1];
298 }
299 
split(char * ciphertext,int index,struct fmt_main * self)300 static char *split(char *ciphertext, int index, struct fmt_main *self)
301 {
302 	static char *out;
303 	int i, j = 0;
304 
305 	if (!out) out = mem_alloc_tiny(TOTAL_LENGTH + 1, MEM_ALIGN_WORD);
306 
307 	memset(out, 0, TOTAL_LENGTH + 1);
308 	memcpy(out, ciphertext, strlen(ciphertext));
309 
310 	/* convert hashes to lower-case - exclude $MSCHAPv2 and USERNAME */
311 	for (i = FORMAT_TAG_LEN; i < TOTAL_LENGTH + 1 && j < 3; i++) {
312 		if (out[i] >= 'A' && out[i] <= 'Z')
313 			out[i] |= 0x20;
314 		else if (out[i] == '$')
315 			j++;
316 	}
317 
318 	if (valid_long(out))
319 		return long_to_short(out);
320 
321 	return out;
322 }
323 
generate_des_format(uchar * binary)324 static uint32_t *generate_des_format(uchar* binary)
325 {
326 	static uint32_t out[6];
327 	ARCH_WORD block[6];
328 	int chr, src,dst,i;
329 	uchar value, mask;
330 	ARCH_WORD *ptr;
331 
332 	memset(block, 0, sizeof(block));
333 
334 	for (chr = 0; chr < 24; chr=chr + 8)
335 	{
336 		dst = 0;
337 		for (i=0; i<8; i++)
338 		{
339 			value = binary[chr + i];
340 			mask = 0x80;
341 
342 			for (src = 0; src < 8; src++) {
343 				if (value & mask)
344 					block[(chr/4) + (dst>>5)]|= 1U << (dst & 0x1F);
345 				mask >>= 1;
346 				dst++;
347 			}
348 		}
349 	}
350 
351 	/* Apply initial permutation on ciphertext blocks */
352 	for (i=0; i<6; i=i+2)
353 	{
354 		ptr = DES_do_IP(&block[i]);
355 		out[i] = ptr[1];
356 		out[i+1] = ptr[0];
357 	}
358 
359 	return out;
360 }
361 
get_binary(char * ciphertext)362 static void *get_binary(char *ciphertext)
363 {
364 	uchar binary[BINARY_SIZE];
365 	int i;
366 	uint32_t *ptr;
367 
368 	if (valid_short(ciphertext))
369 		ciphertext += FORMAT_TAG_LEN + CHALLENGE_LENGTH / 4 + 1; /* Skip - $MSCHAPv2$, MSCHAPv2 Challenge */
370 	else
371 		ciphertext += FORMAT_TAG_LEN + CHALLENGE_LENGTH / 2 + 1; /* Skip - $MSCHAPv2$, Authenticator Challenge */
372 
373 	for (i=0; i<BINARY_SIZE; i++) {
374 		binary[i] = (atoi16[ARCH_INDEX(ciphertext[i*2])])<<4;
375 		binary[i] |= (atoi16[ARCH_INDEX(ciphertext[i*2+1])]);
376 	}
377 
378 	/* Set binary in DES format */
379 	ptr = generate_des_format(binary);
380 	return ptr;
381 }
382 
setup_des_key(unsigned char key_56[],int index)383 inline static void setup_des_key(unsigned char key_56[], int index)
384 {
385 	char key[8];
386 
387 	/* Right shift key bytes by 1 to bring in openssl format */
388 	/* Each byte of key is xored with 0x80 to pass check for 0 in DES_bs_set_key() */
389 
390 	key[0] = (key_56[0] >> 1) | 0x80;
391 	key[1] = (((key_56[0] << 7) | (key_56[1] >> 1)) >>1) | 0x80;
392 	key[2] = (((key_56[1] << 6) | (key_56[2] >> 2)) >>1) | 0x80;
393 	key[3] = (((key_56[2] << 5) | (key_56[3] >> 3)) >>1) | 0x80;
394 	key[4] = (((key_56[3] << 4) | (key_56[4] >> 4)) >>1) | 0x80;
395 	key[5] = (((key_56[4] << 3) | (key_56[5] >> 5)) >>1) | 0x80;
396 	key[6] = (((key_56[5] << 2) | (key_56[6] >> 6)) >>1) | 0x80;
397 	key[7] = ((key_56[6] << 1) >>1 ) | 0x80;
398 
399 	DES_bs_set_key((char*)key, index);
400 }
401 
402 /* Calculate the MSCHAPv2 response for the given challenge, using the
403    specified authentication identity (username), password and client
404    nonce.
405 */
crypt_all(int * pcount,struct db_salt * salt)406 static int crypt_all(int *pcount, struct db_salt *salt)
407 {
408 	const int count = *pcount;
409 	int i;
410 
411 	if (!keys_prepared) {
412 #ifdef _OPENMP
413 #pragma omp parallel for
414 #endif
415 		for (i = 0; i < count; i++) {
416 			int len;
417 
418 			/* Generate 16-byte NTLM hash */
419 			len = E_md4hash((uchar *) saved_plain[i], saved_len[i],
420 			        saved_key[i]);
421 
422 			if (len <= 0)
423 				saved_plain[i][-len] = 0; // match truncation
424 
425 			/* NULL-padding the 16-byte hash to 21-bytes is made
426 			   in cmp_exact if needed */
427 
428 			setup_des_key(saved_key[i], i);
429 		}
430 		keys_prepared = 1;
431 	}
432 
433 	/* Bitsliced des encryption */
434 	DES_bs_crypt_plain(count);
435 
436 	return count;
437 }
438 
cmp_all(void * binary,int count)439 static int cmp_all(void *binary, int count)
440 {
441 	return DES_bs_cmp_all((uint32_t *)binary, count);
442 }
443 
cmp_one(void * binary,int index)444 static int cmp_one(void *binary, int index)
445 {
446 	return DES_bs_cmp_one((uint32_t *)binary, 32, index);
447 }
448 
cmp_exact(char * source,int index)449 static int cmp_exact(char *source, int index)
450 {
451 	uint32_t *binary = get_binary(source);
452 
453 	if (!DES_bs_cmp_one(binary, 64, index))
454 		return 0;
455 
456 	setup_des_key(&saved_key[index][7], 0);
457 	DES_bs_crypt_plain(1);
458 	if (!DES_bs_cmp_one(&binary[2], 64, 0))
459 	{
460 		setup_des_key(saved_key[0], 0);
461 		DES_bs_crypt_plain(1);
462 		return 0;
463 	}
464 
465 	/* NULL-pad 16-byte NTLM hash to 21-bytes (postponed until now) */
466 	memset(&saved_key[index][16], 0, 5);
467 
468 	setup_des_key(&saved_key[index][14], 0);
469 	DES_bs_crypt_plain(1);
470 	if (!DES_bs_cmp_one(&binary[4], 64, 0))
471 	{
472 		setup_des_key(saved_key[0], 0);
473 		DES_bs_crypt_plain(1);
474 		return 0;
475 	}
476 
477 	setup_des_key(saved_key[0], 0);
478 	DES_bs_crypt_plain(1);
479 	return 1;
480 }
481 
482 /* Either the cipherext already contains the MSCHAPv2 Challenge (4 Bytes) or
483    we are going to calculate it via:
484    sha1(|Peer/Client Challenge (8 Bytes)|Authenticator/Server Challenge (8 Bytes)|Username (<=256)|)
485 
486    NOTE, we now ONLY call this function the the short form. The long form gets converted into the short
487    form in either prepare or split function.  The short form is cannonical form (Change made July, 2014, JimF)
488 */
get_salt(char * ciphertext)489 static void *get_salt(char *ciphertext)
490 {
491 	static union {
492 		unsigned char u8[SALT_SIZE];
493 		uint32_t u32[SALT_SIZE / 4];
494 	} binary_salt;
495 	int i, cnt;
496 	uchar j;
497 	char *pos = NULL;
498 	unsigned char temp[SALT_SIZE];
499 
500 	pos = ciphertext + FORMAT_TAG_LEN;
501 
502 	for (i = 0; i < SALT_SIZE; i++)
503 		binary_salt.u8[i] = (atoi16[ARCH_INDEX(pos[i*2])] << 4) + atoi16[ARCH_INDEX(pos[i*2+1])];
504 
505 	/* Apply IP to salt */
506 	memset(temp, 0, SALT_SIZE);
507 	for (i = 0; i < 64; i++) {
508 		cnt = DES_IP[i ^ 0x20];
509 		j = (uchar)((binary_salt.u8[cnt >> 3] >> (7 - (cnt & 7))) & 1);
510 		temp[i/8] |= j << (7 - (i % 8));
511 	}
512 
513 	memcpy(binary_salt.u8, temp, SALT_SIZE);
514 	return (void*)binary_salt.u32;
515 }
516 
517 /*
518  * This function will convert long hashes, into short ones (the short is now cannonical format)
519  * converts
520  *   $MSCHAPv2$95a87fa62ebcd2e3c8b09e1b448a6c72$ed8cc90fd40faa2d6bcd0abd0b1f562fd777df6c5609c98b$e2ae0995eaac6ceff0d9757428b51509$lulu
521  * into
522  *   $MSCHAPv2$ba75eb14efbfbf25$ed8cc90fd40faa2d6bcd0abd0b1f562fd777df6c5609c98b$$
523  *
524  * This code was moved from get_salt().
525  */
long_to_short(char * ciphertext)526 static char *long_to_short(char *ciphertext) {
527 	static char Buf[TOTAL_LENGTH+1];	// larger than we need, but not a big deal
528 	static SHA_CTX ctx;
529 	unsigned char tmp[16];
530 	unsigned char digest[20];
531 	char *pos = NULL;
532 	int i;
533 	SHA1_Init(&ctx);
534 
535 	/* Peer Challenge */
536 	pos = ciphertext + FORMAT_TAG_LEN + 16*2 + 1 + 24*2 + 1; /* Skip $MSCHAPv2$, Authenticator Challenge and Response Hash */
537 
538 	memset(tmp, 0, 16);
539 	for (i = 0; i < 16; i++)
540 		tmp[i] = (atoi16[ARCH_INDEX(pos[i*2])] << 4) + atoi16[ARCH_INDEX(pos[i*2+1])];
541 
542 	SHA1_Update(&ctx, tmp, 16);
543 
544 	/* Authenticator Challenge */
545 	pos = ciphertext + FORMAT_TAG_LEN; /* Skip $MSCHAPv2$ */
546 
547 	memset(tmp, 0, 16);
548 	for (i = 0; i < 16; i++)
549 		tmp[i] = (atoi16[ARCH_INDEX(pos[i*2])] << 4) + atoi16[ARCH_INDEX(pos[i*2+1])];
550 
551 	SHA1_Update(&ctx, tmp, 16);
552 
553 	/* Username - Only the user name (as presented by the peer and
554 	   excluding any prepended domain name) is used as input to SHAUpdate()
555 	*/
556 	pos = ciphertext + FORMAT_TAG_LEN + 16*2 + 1 + 24*2 + 1 + 16*2 + 1; /* Skip $MSCHAPv2$, Authenticator, Response and Peer */
557 	SHA1_Update(&ctx, pos, strlen(pos));
558 
559 	SHA1_Final(digest, &ctx);
560 
561 	// Ok, now we re-make our ciphertext buffer, into the short cannonical form.
562 	strcpy(Buf, FORMAT_TAG);
563 	pos = Buf + FORMAT_TAG_LEN;
564 	for (i = 0; i < SALT_SIZE; i++) {
565 		//binary_salt.u8[i] = (atoi16[ARCH_INDEX(pos[i*2])] << 4) + atoi16[ARCH_INDEX(pos[i*2+1])];
566 		pos[(i<<1)] = itoa16[digest[i]>>4];
567 		pos[(i<<1)+1] = itoa16[digest[i]&0xF];
568 	}
569 	memcpy(&pos[16], &ciphertext[42], CIPHERTEXT_LENGTH+2);
570 	pos[16+CIPHERTEXT_LENGTH+2] = '$';
571 	pos[16+CIPHERTEXT_LENGTH+3] = 0;
572 	//printf("short=%s  original=%s\n", Buf, ciphertext);
573 	return Buf;
574 }
575 
set_salt(void * salt)576 static void set_salt(void *salt)
577 {
578 	challenge = salt;
579 	DES_bs_generate_plaintext(challenge);
580 }
581 
mschapv2_set_key(char * key,int index)582 static void mschapv2_set_key(char *key, int index)
583 {
584 	saved_len[index] = strnzcpyn(saved_plain[index], key, sizeof(*saved_plain));
585 	keys_prepared = 0;
586 }
587 
get_key(int index)588 static char *get_key(int index)
589 {
590 	return saved_plain[index];
591 }
592 
salt_hash(void * salt)593 static int salt_hash(void *salt)
594 {
595 	return *(uint32_t *)salt & (SALT_HASH_SIZE - 1);
596 }
597 
598 struct fmt_main fmt_MSCHAPv2_old = {
599 	{
600 		FORMAT_LABEL,
601 		FORMAT_NAME,
602 		ALGORITHM_NAME,
603 		BENCHMARK_COMMENT,
604 		BENCHMARK_LENGTH,
605 		0,
606 		PLAINTEXT_LENGTH,
607 		BINARY_SIZE,
608 		BINARY_ALIGN,
609 		SALT_SIZE,
610 		SALT_ALIGN,
611 		MIN_KEYS_PER_CRYPT,
612 		MAX_KEYS_PER_CRYPT,
613 #if DES_BS
614 		FMT_BS |
615 #if DES_bs_mt
616 		FMT_OMP | FMT_OMP_BAD |
617 #endif
618 #endif
619 		FMT_CASE | FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE | FMT_UNICODE | FMT_ENC,
620 		{ NULL },
621 		{ FORMAT_TAG },
622 		tests
623 	}, {
624 		init,
625 		done,
626 		fmt_default_reset,
627 		prepare,
628 		valid,
629 		split,
630 		get_binary,
631 		get_salt,
632 		{ NULL },
633 		fmt_default_source,
634 		{
635 			fmt_default_binary_hash_0,
636 			fmt_default_binary_hash_1,
637 			fmt_default_binary_hash_2,
638 			fmt_default_binary_hash_3,
639 			fmt_default_binary_hash_4,
640 			fmt_default_binary_hash_5,
641 			fmt_default_binary_hash_6
642 		},
643 		salt_hash,
644 		NULL,
645 		set_salt,
646 		mschapv2_set_key,
647 		get_key,
648 		fmt_default_clear_keys,
649 		crypt_all,
650 		{
651 			DES_bs_get_hash_0,
652 			DES_bs_get_hash_1,
653 			DES_bs_get_hash_2,
654 			DES_bs_get_hash_3,
655 			DES_bs_get_hash_4,
656 			DES_bs_get_hash_5,
657 			DES_bs_get_hash_6
658 		},
659 		cmp_all,
660 		cmp_one,
661 		cmp_exact
662 	}
663 };
664 
665 #endif /* plugin stanza */
666