Openwall GNU/*/Linux - a small security-enhanced Linux distro for servers
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sat, 21 Jul 2012 17:27:00 +0400
From: Solar Designer <solar@...nwall.com>
To: john-dev@...ts.openwall.com
Subject: Re: int crypt_all(count, salt)

myrice -

On Wed, Jul 18, 2012 at 01:52:03PM +0400, Solar Designer wrote:
> This is an intermediate step before even further changes to it.  (The
> next change to crypt_all() will likely be to make "int *count" - that
> is, let crypt_all() modify the count when it computes more hashes than
> there were keys, due to set_mask().  Yes, set_mask() is to be introduced
> at the same time with that change.)

As discussed on IRC yesterday, attached is a patch that implements "int
*count", but not set_mask() yet.  As discussed, for your initial
experiments you may hard-code generation of candidate passwords in your
hack of raw-md5-opencl - e.g., append [a-z][a-z] to all passwords -
which should be good enough for test runs and for us to see how to
enhance the interface further.

The crypt_all() description became rather complicated, unfortunately:

/* Computes the ciphertexts for given salt and plaintexts.
 * For implementation reasons, this may happen to always compute at least
 * min_keys_per_crypt ciphertexts even if the requested count is lower,
 * although it is preferable for implementations to obey the count whenever
 * practical and also for callers not to call crypt_all() with fewer than
 * min_keys_per_crypt keys whenever practical.
 * Returns the last output index for which there might be a match (against the
 * supplied salt's hashes) plus 1.  A return value of zero indicates no match.
 * Note that output indices don't have to match input indices (although they
 * may and usually do).  The indices passed to get_key(), get_hash[](),
 * cmp_one(), and cmp_exact() must be in the 0 to crypt_all() return value
 * minus 1 range, although for infrequent status reporting get_key() may also
 * be called on indices previously supplied to set_key() as well as on indices
 * up to the updated *count minus 1 even if they're beyond this range.
 * The count passed to cmp_all() must be equal to crypt_all()'s return value.
 * If an implementation does not use the salt parameter or if salt is NULL
 * (as it may be during self-test and benchmark), the return value must always
 * match *count the way it is after the crypt_all() call.
 * The count is passed by reference and must be updated by crypt_all() if it
 * computes other than the requested count (such as if it generates additional
 * candidate passwords on its own).  The updated count is used for c/s rate
 * calculation.  The return value is thus in the 0 to updated *count range. */
	int (*crypt_all)(int *count, struct db_salt *salt);

I've attached two files implementing the same changes:

john-1.7.9.6+crypt_all+LM-crypt_all-pcount-1.diff - relative to the
patches I posted before (applies on top of tree patched with
john-1.7.9.6-LM-1.diff along with all previous patches).

john-1.7.9.6-crypt_all-pcount-1.diff - applies on top of clean 1.7.9.6
as found in CVS.

Alexander

diff -u john-1.7.9.6-newform/src/AFS_fmt.c john-1.7.9.6-newform/src/AFS_fmt.c
--- john-1.7.9.6-newform/src/AFS_fmt.c	2012-07-18 04:12:23 +0000
+++ john-1.7.9.6-newform/src/AFS_fmt.c	2012-07-21 12:16:46 +0000
@@ -281,8 +281,9 @@
 	return buffer[index].key;
 }
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	int index, pos, length;
 	char xor[8];
 	ARCH_WORD_32 space[(PLAINTEXT_LENGTH + SALT_SIZE + 8) / 4 + 1];
diff -u john-1.7.9.6-newform/src/BF_fmt.c john-1.7.9.6-newform/src/BF_fmt.c
--- john-1.7.9.6-newform/src/BF_fmt.c	2012-07-18 04:12:29 +0000
+++ john-1.7.9.6-newform/src/BF_fmt.c	2012-07-21 12:19:26 +0000
@@ -225,8 +225,10 @@
 	return saved_key[index];
 }
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
+
 	if (keys_mode != saved_salt.subtype) {
 		int i;
 
diff -u john-1.7.9.6-newform/src/BSDI_fmt.c john-1.7.9.6-newform/src/BSDI_fmt.c
--- john-1.7.9.6-newform/src/BSDI_fmt.c	2012-07-18 03:37:07 +0000
+++ john-1.7.9.6-newform/src/BSDI_fmt.c	2012-07-21 12:18:38 +0000
@@ -315,8 +315,9 @@
 
 #if DES_BS
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	DES_bs_crypt(saved_count, count);
 	return count;
 }
@@ -333,8 +334,9 @@
 
 #else
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	int index;
 
 	if (current_salt != saved_salt)
diff -u john-1.7.9.6-newform/src/DES_bs.h john-1.7.9.6-newform/src/DES_bs.h
--- john-1.7.9.6-newform/src/DES_bs.h	2012-07-18 03:51:22 +0000
+++ john-1.7.9.6-newform/src/DES_bs.h	2012-07-21 12:38:31 +0000
@@ -149,7 +149,7 @@
 /*
  * Another special-case version: a non-zero IV, no salts, no iterations.
  */
-extern int DES_bs_crypt_LM(int keys_count, struct db_salt *salt);
+extern int DES_bs_crypt_LM(int *keys_count, struct db_salt *salt);
 
 /*
  * Converts an ASCII ciphertext to binary to be used with one of the
diff -u john-1.7.9.6-newform/src/DES_bs_b.c john-1.7.9.6-newform/src/DES_bs_b.c
--- john-1.7.9.6-newform/src/DES_bs_b.c	2012-07-18 09:03:48 +0000
+++ john-1.7.9.6-newform/src/DES_bs_b.c	2012-07-21 12:48:16 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-2001,2003,2010,2011 by Solar Designer
+ * Copyright (c) 1996-2001,2003,2010-2012 by Solar Designer
  */
 
 #include "arch.h"
@@ -1452,8 +1452,9 @@
 #define kd				[0]
 #endif
 
-int DES_bs_crypt_LM(int keys_count, struct db_salt *salt)
+int DES_bs_crypt_LM(int *pcount, struct db_salt *salt)
 {
+	int keys_count = *pcount;
 #if DES_bs_mt
 	int retval = (salt && salt->bitmap) ? 0 : keys_count;
 	int t, n = (keys_count + (DES_BS_DEPTH - 1)) / DES_BS_DEPTH;
diff -u john-1.7.9.6-newform/src/DES_fmt.c john-1.7.9.6-newform/src/DES_fmt.c
--- john-1.7.9.6-newform/src/DES_fmt.c	2012-07-18 04:01:18 +0000
+++ john-1.7.9.6-newform/src/DES_fmt.c	2012-07-21 12:19:55 +0000
@@ -195,8 +195,9 @@
 	DES_bs_set_salt(*(ARCH_WORD *)salt);
 }
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	DES_bs_crypt_25(count);
 	return count;
 }
@@ -269,8 +270,9 @@
 	DES_std_set_salt(*(ARCH_WORD *)salt);
 }
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	int index;
 
 	for (index = 0; index < count; index++)
diff -u john-1.7.9.6-newform/src/MD5_fmt.c john-1.7.9.6-newform/src/MD5_fmt.c
--- john-1.7.9.6-newform/src/MD5_fmt.c	2012-07-18 03:45:46 +0000
+++ john-1.7.9.6-newform/src/MD5_fmt.c	2012-07-21 12:20:13 +0000
@@ -195,8 +195,9 @@
 	return saved_key[index];
 }
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	MD5_std_crypt(count);
 	return count;
 }
diff -u john-1.7.9.6-newform/src/bench.c john-1.7.9.6-newform/src/bench.c
--- john-1.7.9.6-newform/src/bench.c	2012-07-18 03:20:44 +0000
+++ john-1.7.9.6-newform/src/bench.c	2012-07-21 12:45:11 +0000
@@ -97,7 +97,7 @@
 #endif
 	struct tms buf;
 	clock_t start_real, start_virtual, end_real, end_virtual;
-	int64 count;
+	int64 crypts;
 	char *ciphertext;
 	void *salt, *two_salts[2];
 	int index, max;
@@ -166,11 +166,13 @@
 	start_real = times(&buf);
 	start_virtual = buf.tms_utime + buf.tms_stime;
 	start_virtual += buf.tms_cutime + buf.tms_cstime;
-	count.lo = count.hi = 0;
+	crypts.lo = crypts.hi = 0;
 
 	index = salts;
 	max = format->params.max_keys_per_crypt;
 	do {
+		int count = max;
+
 		if (!--index) {
 			index = salts;
 			if (!(++current)->ciphertext)
@@ -179,10 +181,10 @@
 		}
 
 		if (salts > 1) format->methods.set_salt(two_salts[index & 1]);
-		(void)format->methods.crypt_all(max, NULL);
-		format->methods.cmp_all(binary, max);
+		format->methods.cmp_all(binary,
+		    format->methods.crypt_all(&count, NULL));
 
-		add32to64(&count, max);
+		add32to64(&crypts, count);
 #if !OS_TIMER
 		sig_timer_emu_tick();
 #endif
@@ -197,7 +199,7 @@
 
 	results->real = end_real - start_real;
 	results->virtual = end_virtual - start_virtual;
-	results->count = count;
+	results->crypts = crypts;
 
 	for (index = 0; index < 2; index++)
 		MEM_FREE(two_salts[index]);
@@ -205,12 +207,12 @@
 	return event_abort ? "" : NULL;
 }
 
-void benchmark_cps(int64 *count, clock_t time, char *buffer)
+void benchmark_cps(int64 *crypts, clock_t time, char *buffer)
 {
 	unsigned int cps_hi, cps_lo;
 	int64 tmp;
 
-	tmp = *count;
+	tmp = *crypts;
 	mul64by32(&tmp, clk_tck);
 	cps_hi = div64by32lo(&tmp, time);
 
@@ -282,8 +284,8 @@
 
 		puts("DONE");
 
-		benchmark_cps(&results_m.count, results_m.real, s_real);
-		benchmark_cps(&results_m.count, results_m.virtual, s_virtual);
+		benchmark_cps(&results_m.crypts, results_m.real, s_real);
+		benchmark_cps(&results_m.crypts, results_m.virtual, s_virtual);
 #if !defined(__DJGPP__) && !defined(__BEOS__)
 		printf("%s:\t%s c/s real, %s c/s virtual\n",
 			msg_m, s_real, s_virtual);
@@ -297,8 +299,8 @@
 			goto next;
 		}
 
-		benchmark_cps(&results_1.count, results_1.real, s_real);
-		benchmark_cps(&results_1.count, results_1.virtual, s_virtual);
+		benchmark_cps(&results_1.crypts, results_1.real, s_real);
+		benchmark_cps(&results_1.crypts, results_1.virtual, s_virtual);
 #if !defined(__DJGPP__) && !defined(__BEOS__)
 		printf("%s:\t%s c/s real, %s c/s virtual\n\n",
 			msg_1, s_real, s_virtual);
diff -u john-1.7.9.6-newform/src/best.c john-1.7.9.6-newform/src/best.c
--- john-1.7.9.6-newform/src/best.c	2012-07-17 16:53:12 +0000
+++ john-1.7.9.6-newform/src/best.c	2012-07-21 12:49:58 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-99,2003,2006,2011 by Solar Designer
+ * Copyright (c) 1996-99,2003,2006,2011,2012 by Solar Designer
  */
 
 /*
@@ -65,7 +65,7 @@
 
 		fprintf(stderr, "FAILED\n");
 	} else {
-		tmp = results.count;
+		tmp = results.crypts;
 		mul64by32(&tmp, clk_tck * 10);
 #ifdef _OPENMP
 		virtual = div64by32lo(&tmp, results.real);
@@ -73,8 +73,8 @@
 		virtual = div64by32lo(&tmp, results.virtual);
 #endif
 
-		benchmark_cps(&results.count, results.real, s_real);
-		benchmark_cps(&results.count, results.virtual, s_virtual);
+		benchmark_cps(&results.crypts, results.real, s_real);
+		benchmark_cps(&results.crypts, results.virtual, s_virtual);
 
 		fprintf(stderr, "%s c/s real, %s c/s virtual\n",
 			s_real, s_virtual);
diff -u john-1.7.9.6-newform/src/c3_fmt.c john-1.7.9.6-newform/src/c3_fmt.c
--- john-1.7.9.6-newform/src/c3_fmt.c	2012-07-18 04:12:39 +0000
+++ john-1.7.9.6-newform/src/c3_fmt.c	2012-07-21 12:20:25 +0000
@@ -341,8 +341,9 @@
 	return saved_key[index];
 }
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	int index;
 
 #if defined(_OPENMP) && defined(__GLIBC__)
diff -u john-1.7.9.6-newform/src/cracker.c john-1.7.9.6-newform/src/cracker.c
--- john-1.7.9.6-newform/src/cracker.c	2012-07-18 03:19:27 +0000
+++ john-1.7.9.6-newform/src/cracker.c	2012-07-21 12:35:04 +0000
@@ -233,7 +233,7 @@
 static int crk_password_loop(struct db_salt *salt)
 {
 	struct db_password *pw;
-	int match, index;
+	int count, match, index;
 
 #if !OS_TIMER
 	sig_timer_emu_tick();
@@ -244,11 +244,13 @@
 	if (event_pending)
 	if (crk_process_event()) return 1;
 
-	match = crk_methods.crypt_all(crk_key_index, salt);
+	count = crk_key_index;
+	match = crk_methods.crypt_all(&count, salt);
+	crk_last_key = count;
 
 	{
 		int64 effective_count;
-		mul32by32(&effective_count, salt->count, crk_key_index);
+		mul32by32(&effective_count, salt->count, count);
 		status_update_crypts(&effective_count);
 	}
 
@@ -298,7 +300,7 @@
 		if (crk_password_loop(salt)) return 1;
 	} while ((salt = salt->next));
 
-	crk_last_key = crk_key_index; crk_key_index = 0;
+	crk_key_index = 0;
 	crk_last_salt = NULL;
 	crk_fix_state();
 
@@ -401,7 +403,7 @@
 
 char *crk_get_key2(void)
 {
-	if (crk_key_index > 1)
+	if (crk_key_index > 1 && crk_key_index < crk_last_key)
 		return crk_methods.get_key(crk_key_index - 1);
 	else
 	if (crk_last_key > 1)
diff -u john-1.7.9.6-newform/src/dummy.c john-1.7.9.6-newform/src/dummy.c
--- john-1.7.9.6-newform/src/dummy.c	2012-07-18 03:39:54 +0000
+++ john-1.7.9.6-newform/src/dummy.c	2012-07-21 12:20:59 +0000
@@ -228,9 +228,9 @@
 	return saved_key[index];
 }
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
-	return count;
+	return *pcount;
 }
 
 static int cmp_all(void *binary, int count)
diff -u john-1.7.9.6-newform/src/formats.c john-1.7.9.6-newform/src/formats.c
--- john-1.7.9.6-newform/src/formats.c	2012-07-18 03:21:02 +0000
+++ john-1.7.9.6-newform/src/formats.c	2012-07-21 12:13:15 +0000
@@ -135,8 +135,11 @@
 		format->methods.set_salt(salt);
 		format->methods.set_key(current->plaintext, index);
 
-		if (format->methods.crypt_all(index + 1, NULL) != index + 1)
-			return "crypt_all";
+		{
+			int count = index + 1;
+			if (format->methods.crypt_all(&count, NULL) != count)
+				return "crypt_all";
+		}
 
 		for (size = 0; size < PASSWORD_HASH_SIZES; size++)
 		if (format->methods.binary_hash[size] &&
diff -u john-1.7.9.6-newform/src/formats.h john-1.7.9.6-newform/src/formats.h
--- john-1.7.9.6-newform/src/formats.h	2012-07-18 03:40:22 +0000
+++ john-1.7.9.6-newform/src/formats.h	2012-07-21 12:36:27 +0000
@@ -163,7 +163,12 @@
 /* Sets a plaintext, with index from 0 to fmt_params.max_keys_per_crypt - 1 */
 	void (*set_key)(char *key, int index);
 
-/* Returns a plaintext previously set with set_key() */
+/* Returns a plaintext previously set with and potentially altered by
+ * set_key() (e.g., converted to all-uppercase and truncated at 7 for LM
+ * hashes).  The plaintext may also have been generated or altered by
+ * crypt_all().  Depending on crypt_all() implementation, the index used here
+ * does not have to match an index previously used with set_key(), although
+ * for most formats it does.  See the description of crypt_all() below. */
 	char *(*get_key)(int index);
 
 /* Allow the previously set keys to be dropped if that would help improve
@@ -179,10 +184,21 @@
  * min_keys_per_crypt keys whenever practical.
  * Returns the last output index for which there might be a match (against the
  * supplied salt's hashes) plus 1.  A return value of zero indicates no match.
+ * Note that output indices don't have to match input indices (although they
+ * may and usually do).  The indices passed to get_key(), get_hash[](),
+ * cmp_one(), and cmp_exact() must be in the 0 to crypt_all() return value
+ * minus 1 range, although for infrequent status reporting get_key() may also
+ * be called on indices previously supplied to set_key() as well as on indices
+ * up to the updated *count minus 1 even if they're beyond this range.
+ * The count passed to cmp_all() must be equal to crypt_all()'s return value.
  * If an implementation does not use the salt parameter or if salt is NULL
  * (as it may be during self-test and benchmark), the return value must always
- * be exactly count. */
-	int (*crypt_all)(int count, struct db_salt *salt);
+ * match *count the way it is after the crypt_all() call.
+ * The count is passed by reference and must be updated by crypt_all() if it
+ * computes other than the requested count (such as if it generates additional
+ * candidate passwords on its own).  The updated count is used for c/s rate
+ * calculation.  The return value is thus in the 0 to updated *count range. */
+	int (*crypt_all)(int *count, struct db_salt *salt);
 
 /* These functions calculate a hash out of a ciphertext that has just been
  * generated with the crypt_all() method. To be used while cracking. */
diff -u john-1.7.9.6-newform/src/trip_fmt.c john-1.7.9.6-newform/src/trip_fmt.c
--- john-1.7.9.6-newform/src/trip_fmt.c	2012-07-18 03:52:13 +0000
+++ john-1.7.9.6-newform/src/trip_fmt.c	2012-07-21 12:20:41 +0000
@@ -481,8 +481,9 @@
 #endif
 }
 
-static int crypt_all(int count, struct db_salt *salt)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	crypt_link_by_salt(count);
 	crypt_traverse_by_salt(count);
 	return count;
diff -u john-1.7.9.6-newform/src/x86-64.S john-1.7.9.6-newform/src/x86-64.S
--- john-1.7.9.6-newform/src/x86-64.S	2012-07-18 07:28:35 +0000
+++ john-1.7.9.6-newform/src/x86-64.S	2012-07-21 13:08:57 +0000
@@ -1177,7 +1177,7 @@
 DO_ALIGN(6)
 .globl DES_bs_crypt_LM
 DES_bs_crypt_LM:
-	pushq %rdi
+	movl (%rdi),%r8d
 	movdqa mask01,%xmm7
 	movdqa mask02,%xmm8
 	leaq DES_bs_all_xkeys(%rip),v_ptr
@@ -1332,7 +1332,7 @@
 	S8(B(4), B(26), B(14), B(20))
 	subl $1,rounds
 	jnz DES_bs_crypt_LM_loop
-	popq %rax
+	xchgq %r8,%rax
 	ret
 
 #endif
diff -u john-1.7.9.6-newform/src/x86-mmx.S john-1.7.9.6-newform/src/x86-mmx.S
--- john-1.7.9.6-newform/src/x86-mmx.S	2012-07-18 03:54:59 +0000
+++ john-1.7.9.6-newform/src/x86-mmx.S	2012-07-21 12:39:48 +0000
@@ -1385,11 +1385,12 @@
 	S8(B(4), B(26), B(14), B(20))
 	decl rounds
 	jnz DES_bs_crypt_LM_loop
+	movl 8(%esp),%eax
 	popl %esi
-	movl 4(%esp),%eax
 #ifdef EMMS
 	emms
 #endif
+	movl (%eax),%eax
 	ret
 
 #endif
diff -u john-1.7.9.6-newform/src/x86-sse.S john-1.7.9.6-newform/src/x86-sse.S
--- john-1.7.9.6-newform/src/x86-sse.S	2012-07-18 03:56:35 +0000
+++ john-1.7.9.6-newform/src/x86-sse.S	2012-07-21 12:40:11 +0000
@@ -1383,8 +1383,9 @@
 	S8(B(4), B(26), B(14), B(20), a6_p)
 	decl rounds
 	jnz DES_bs_crypt_LM_loop
+	movl 8(%esp),%eax
 	popl %esi
-	movl 4(%esp),%eax
+	movl (%eax),%eax
 	ret
 
 #endif
only in patch2:
unchanged:
--- john-1.7.9.6/src/bench.h	2011-11-06 13:17:58 +0000
+++ john-1.7.9.6-newform/src/bench.h	2012-07-21 12:48:00 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-99,2006,2009,2011 by Solar Designer
+ * Copyright (c) 1996-99,2006,2009,2011,2012 by Solar Designer
  */
 
 /*
@@ -23,8 +23,8 @@ struct bench_results {
 /* Elapsed real and processor time */
 	clock_t real, virtual;
 
-/* Number of passwords tried */
-	int64 count;
+/* Number of ciphertexts computed */
+	int64 crypts;
 };
 
 /*
@@ -54,7 +54,7 @@ extern char *benchmark_format(struct fmt
 /*
  * Converts benchmarked c/s into an ASCII string.
  */
-extern void benchmark_cps(int64 *count, clock_t time, char *buffer);
+extern void benchmark_cps(int64 *crypts, clock_t time, char *buffer);
 
 /*
  * Benchmarks all the registered cracking algorithms and prints the results

diff -urp john-1.7.9.6/src/AFS_fmt.c john-1.7.9.6-newform/src/AFS_fmt.c
--- john-1.7.9.6/src/AFS_fmt.c	2012-07-15 09:32:01 +0000
+++ john-1.7.9.6-newform/src/AFS_fmt.c	2012-07-21 12:16:46 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-2001 by Solar Designer
+ * Copyright (c) 1996-2001,2012 by Solar Designer
  */
 
 #include <string.h>
@@ -281,8 +281,9 @@ static char *get_key(int index)
 	return buffer[index].key;
 }
 
-static void crypt_all(int count)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	int index, pos, length;
 	char xor[8];
 	ARCH_WORD_32 space[(PLAINTEXT_LENGTH + SALT_SIZE + 8) / 4 + 1];
@@ -378,6 +379,8 @@ static void crypt_all(int count)
 		buffer[index].aligned.binary[0] = block[0] | 0x01010101;
 		buffer[index].aligned.binary[1] = block[1] | 0x01010101;
 	}
+
+	return count;
 }
 
 static int cmp_all(void *binary, int count)
@@ -449,6 +452,8 @@ struct fmt_main fmt_AFS = {
 		tests
 	}, {
 		init,
+		fmt_default_done,
+		fmt_default_reset,
 		fmt_default_prepare,
 		valid,
 		fmt_default_split,
diff -urp john-1.7.9.6/src/BF_fmt.c john-1.7.9.6-newform/src/BF_fmt.c
--- john-1.7.9.6/src/BF_fmt.c	2012-07-15 09:33:40 +0000
+++ john-1.7.9.6-newform/src/BF_fmt.c	2012-07-21 12:19:26 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-2001,2008,2010,2011 by Solar Designer
+ * Copyright (c) 1996-2001,2008,2010-2012 by Solar Designer
  */
 
 #include <stdlib.h>
@@ -225,8 +225,10 @@ static char *get_key(int index)
 	return saved_key[index];
 }
 
-static void crypt_all(int count)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
+
 	if (keys_mode != saved_salt.subtype) {
 		int i;
 
@@ -237,6 +239,8 @@ static void crypt_all(int count)
 	}
 
 	BF_std_crypt(&saved_salt, count);
+
+	return count;
 }
 
 static int cmp_all(void *binary, int count)
@@ -292,6 +296,8 @@ struct fmt_main fmt_BF = {
 		tests
 	}, {
 		init,
+		fmt_default_done,
+		fmt_default_reset,
 		fmt_default_prepare,
 		valid,
 		fmt_default_split,
diff -urp john-1.7.9.6/src/BSDI_fmt.c john-1.7.9.6-newform/src/BSDI_fmt.c
--- john-1.7.9.6/src/BSDI_fmt.c	2012-07-15 09:35:10 +0000
+++ john-1.7.9.6-newform/src/BSDI_fmt.c	2012-07-21 12:18:38 +0000
@@ -315,9 +315,11 @@ static char *get_key(int index)
 
 #if DES_BS
 
-static void crypt_all(int count)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	DES_bs_crypt(saved_count, count);
+	return count;
 }
 
 static int cmp_one(void *binary, int index)
@@ -332,8 +334,9 @@ static int cmp_exact(char *source, int i
 
 #else
 
-static void crypt_all(int count)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	int index;
 
 	if (current_salt != saved_salt)
@@ -344,6 +347,8 @@ static void crypt_all(int count)
 
 	for (index = 0; index < count; index++)
 		DES_std_crypt(buffer[index].KS, buffer[index].binary);
+
+	return count;
 }
 
 static int cmp_all(void *binary, int count)
@@ -406,6 +411,8 @@ struct fmt_main fmt_BSDI = {
 		tests
 	}, {
 		init,
+		fmt_default_done,
+		fmt_default_reset,
 		fmt_default_prepare,
 		valid,
 		fmt_default_split,
diff -urp john-1.7.9.6/src/DES_bs.h john-1.7.9.6-newform/src/DES_bs.h
--- john-1.7.9.6/src/DES_bs.h	2012-07-14 13:36:44 +0000
+++ john-1.7.9.6-newform/src/DES_bs.h	2012-07-21 12:38:31 +0000
@@ -13,6 +13,9 @@
 #include "arch.h"
 #include "common.h"
 
+/* For struct db_salt */
+#include "loader.h"
+
 #ifndef DES_BS_ALGORITHM_NAME
 #define DES_BS_ALGORITHM_NAME		ARCH_BITS_STR "/" ARCH_BITS_STR " BS"
 #endif
@@ -146,7 +149,7 @@ extern void DES_bs_crypt_25(int keys_cou
 /*
  * Another special-case version: a non-zero IV, no salts, no iterations.
  */
-extern void DES_bs_crypt_LM(int keys_count);
+extern int DES_bs_crypt_LM(int *keys_count, struct db_salt *salt);
 
 /*
  * Converts an ASCII ciphertext to binary to be used with one of the
diff -urp john-1.7.9.6/src/DES_bs_b.c john-1.7.9.6-newform/src/DES_bs_b.c
--- john-1.7.9.6/src/DES_bs_b.c	2011-11-19 02:57:47 +0000
+++ john-1.7.9.6-newform/src/DES_bs_b.c	2012-07-21 12:48:16 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-2001,2003,2010,2011 by Solar Designer
+ * Copyright (c) 1996-2001,2003,2010-2012 by Solar Designer
  */
 
 #include "arch.h"
@@ -1452,14 +1452,16 @@ static MAYBE_INLINE void DES_bs_finalize
 #define kd				[0]
 #endif
 
-void DES_bs_crypt_LM(int keys_count)
+int DES_bs_crypt_LM(int *pcount, struct db_salt *salt)
 {
+	int keys_count = *pcount;
 #if DES_bs_mt
+	int retval = (salt && salt->bitmap) ? 0 : keys_count;
 	int t, n = (keys_count + (DES_BS_DEPTH - 1)) / DES_BS_DEPTH;
 #endif
 
 #ifdef _OPENMP
-#pragma omp parallel for default(none) private(t) shared(n, DES_bs_all_p, keys_count)
+#pragma omp parallel for default(none) private(t) shared(retval, n, DES_bs_all_p, keys_count, salt)
 #endif
 	for_each_t(n) {
 		ARCH_WORD **k;
@@ -1558,6 +1560,44 @@ void DES_bs_crypt_LM(int keys_count)
 
 			k += 96;
 		} while (--rounds);
+
+#if DES_bs_mt
+		if (!retval) {
+			int index, start, end;
+			start = t;
+#ifdef __GNUC__
+/* This integer division may be slow - need to revise */
+			start /= DES_bs_all_size;
+#endif
+			start *= DES_BS_DEPTH;
+			end = start + DES_BS_DEPTH;
+			if (end > keys_count)
+				end = keys_count;
+			for (index = start; index < end; index++) {
+				unsigned int hash = salt->index(index);
+				if (salt->bitmap[hash / (sizeof(*salt->bitmap) * 8)] &
+				    (1U << (hash % (sizeof(*salt->bitmap) * 8)))) {
+					struct db_password *pw;
+					pw = salt->hash[hash >> PASSWORD_HASH_SHR];
+					do {
+						if (DES_bs_cmp_one(pw->binary, 64, index)) {
+#pragma omp critical
+							retval = keys_count;
+							goto done;
+						}
+					} while ((pw = pw->next_hash));
+				}
+			}
+done:
+			;
+		}
+#endif
 	}
+
+#if DES_bs_mt
+	return retval;
+#else
+	return keys_count;
+#endif
 }
 #endif
diff -urp john-1.7.9.6/src/DES_fmt.c john-1.7.9.6-newform/src/DES_fmt.c
--- john-1.7.9.6/src/DES_fmt.c	2012-07-15 09:36:35 +0000
+++ john-1.7.9.6-newform/src/DES_fmt.c	2012-07-21 12:19:55 +0000
@@ -72,22 +72,22 @@ static struct {
 
 #endif
 
-#if DES_BS
-
-#if DES_bs_mt
+#if DES_BS && DES_bs_mt
 struct fmt_main fmt_DES;
 #endif
 
 static void init(struct fmt_main *self)
 {
+#if DES_BS
 	DES_bs_init(0, DES_bs_cpt);
 #if DES_bs_mt
 	fmt_DES.params.min_keys_per_crypt = DES_bs_min_kpc;
 	fmt_DES.params.max_keys_per_crypt = DES_bs_max_kpc;
 #endif
-}
-
+#else
+	DES_std_init();
 #endif
+}
 
 static int valid(char *ciphertext, struct fmt_main *self)
 {
@@ -195,6 +195,13 @@ static void set_salt(void *salt)
 	DES_bs_set_salt(*(ARCH_WORD *)salt);
 }
 
+static int crypt_all(int *pcount, struct db_salt *salt)
+{
+	int count = *pcount;
+	DES_bs_crypt_25(count);
+	return count;
+}
+
 static int cmp_one(void *binary, int index)
 {
 	return DES_bs_cmp_one((ARCH_WORD_32 *)binary, 32, index);
@@ -263,13 +270,16 @@ static void set_salt(void *salt)
 	DES_std_set_salt(*(ARCH_WORD *)salt);
 }
 
-static void crypt_all(int count)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	int index;
 
 	for (index = 0; index < count; index++)
 		DES_std_crypt(buffer[index].aligned.data.KS,
 			buffer[index].aligned.data.binary);
+
+	return count;
 }
 
 static int cmp_all(void *binary, int count)
@@ -364,11 +374,9 @@ struct fmt_main fmt_DES = {
 #endif
 		tests
 	}, {
-#if DES_BS
 		init,
-#else
-		DES_std_init,
-#endif
+		fmt_default_done,
+		fmt_default_reset,
 		fmt_default_prepare,
 		valid,
 		split,
@@ -398,11 +406,7 @@ struct fmt_main fmt_DES = {
 #endif
 		get_key,
 		fmt_default_clear_keys,
-#if DES_BS
-		DES_bs_crypt_25,
-#else
 		crypt_all,
-#endif
 		{
 			get_hash_0,
 			get_hash_1,
diff -urp john-1.7.9.6/src/LM_fmt.c john-1.7.9.6-newform/src/LM_fmt.c
--- john-1.7.9.6/src/LM_fmt.c	2012-07-15 09:37:34 +0000
+++ john-1.7.9.6-newform/src/LM_fmt.c	2012-07-18 01:46:12 +0000
@@ -210,6 +210,8 @@ struct fmt_main fmt_LM = {
 		tests
 	}, {
 		init,
+		fmt_default_done,
+		fmt_default_reset,
 		prepare,
 		valid,
 		split,
diff -urp john-1.7.9.6/src/MD5_fmt.c john-1.7.9.6-newform/src/MD5_fmt.c
--- john-1.7.9.6/src/MD5_fmt.c	2012-07-15 09:39:00 +0000
+++ john-1.7.9.6-newform/src/MD5_fmt.c	2012-07-21 12:20:13 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-2001,2008,2010,2011 by Solar Designer
+ * Copyright (c) 1996-2001,2008,2010-2012 by Solar Designer
  */
 
 #include <string.h>
@@ -195,6 +195,13 @@ static char *get_key(int index)
 	return saved_key[index];
 }
 
+static int crypt_all(int *pcount, struct db_salt *salt)
+{
+	int count = *pcount;
+	MD5_std_crypt(count);
+	return count;
+}
+
 static int cmp_all(void *binary, int count)
 {
 #if MD5_std_mt
@@ -247,6 +254,8 @@ struct fmt_main fmt_MD5 = {
 		tests
 	}, {
 		init,
+		fmt_default_done,
+		fmt_default_reset,
 		fmt_default_prepare,
 		valid,
 		fmt_default_split,
@@ -267,7 +276,7 @@ struct fmt_main fmt_MD5 = {
 		set_key,
 		get_key,
 		fmt_default_clear_keys,
-		MD5_std_crypt,
+		crypt_all,
 		{
 			get_hash_0,
 			get_hash_1,
diff -urp john-1.7.9.6/src/bench.c john-1.7.9.6-newform/src/bench.c
--- john-1.7.9.6/src/bench.c	2012-07-14 13:18:54 +0000
+++ john-1.7.9.6-newform/src/bench.c	2012-07-21 12:45:11 +0000
@@ -97,7 +97,7 @@ char *benchmark_format(struct fmt_main *
 #endif
 	struct tms buf;
 	clock_t start_real, start_virtual, end_real, end_virtual;
-	int64 count;
+	int64 crypts;
 	char *ciphertext;
 	void *salt, *two_salts[2];
 	int index, max;
@@ -166,11 +166,13 @@ char *benchmark_format(struct fmt_main *
 	start_real = times(&buf);
 	start_virtual = buf.tms_utime + buf.tms_stime;
 	start_virtual += buf.tms_cutime + buf.tms_cstime;
-	count.lo = count.hi = 0;
+	crypts.lo = crypts.hi = 0;
 
 	index = salts;
 	max = format->params.max_keys_per_crypt;
 	do {
+		int count = max;
+
 		if (!--index) {
 			index = salts;
 			if (!(++current)->ciphertext)
@@ -179,10 +181,10 @@ char *benchmark_format(struct fmt_main *
 		}
 
 		if (salts > 1) format->methods.set_salt(two_salts[index & 1]);
-		format->methods.crypt_all(max);
-		format->methods.cmp_all(binary, max);
+		format->methods.cmp_all(binary,
+		    format->methods.crypt_all(&count, NULL));
 
-		add32to64(&count, max);
+		add32to64(&crypts, count);
 #if !OS_TIMER
 		sig_timer_emu_tick();
 #endif
@@ -197,7 +199,7 @@ char *benchmark_format(struct fmt_main *
 
 	results->real = end_real - start_real;
 	results->virtual = end_virtual - start_virtual;
-	results->count = count;
+	results->crypts = crypts;
 
 	for (index = 0; index < 2; index++)
 		MEM_FREE(two_salts[index]);
@@ -205,12 +207,12 @@ char *benchmark_format(struct fmt_main *
 	return event_abort ? "" : NULL;
 }
 
-void benchmark_cps(int64 *count, clock_t time, char *buffer)
+void benchmark_cps(int64 *crypts, clock_t time, char *buffer)
 {
 	unsigned int cps_hi, cps_lo;
 	int64 tmp;
 
-	tmp = *count;
+	tmp = *crypts;
 	mul64by32(&tmp, clk_tck);
 	cps_hi = div64by32lo(&tmp, time);
 
@@ -270,20 +272,20 @@ int benchmark_all(void)
 		    &results_m))) {
 			puts(result);
 			failed++;
-			continue;
+			goto next;
 		}
 
 		if (msg_1)
 		if ((result = benchmark_format(format, 1, &results_1))) {
 			puts(result);
 			failed++;
-			continue;
+			goto next;
 		}
 
 		puts("DONE");
 
-		benchmark_cps(&results_m.count, results_m.real, s_real);
-		benchmark_cps(&results_m.count, results_m.virtual, s_virtual);
+		benchmark_cps(&results_m.crypts, results_m.real, s_real);
+		benchmark_cps(&results_m.crypts, results_m.virtual, s_virtual);
 #if !defined(__DJGPP__) && !defined(__BEOS__)
 		printf("%s:\t%s c/s real, %s c/s virtual\n",
 			msg_m, s_real, s_virtual);
@@ -294,11 +296,11 @@ int benchmark_all(void)
 
 		if (!msg_1) {
 			putchar('\n');
-			continue;
+			goto next;
 		}
 
-		benchmark_cps(&results_1.count, results_1.real, s_real);
-		benchmark_cps(&results_1.count, results_1.virtual, s_virtual);
+		benchmark_cps(&results_1.crypts, results_1.real, s_real);
+		benchmark_cps(&results_1.crypts, results_1.virtual, s_virtual);
 #if !defined(__DJGPP__) && !defined(__BEOS__)
 		printf("%s:\t%s c/s real, %s c/s virtual\n\n",
 			msg_1, s_real, s_virtual);
@@ -306,6 +308,9 @@ int benchmark_all(void)
 		printf("%s:\t%s c/s\n\n",
 			msg_1, s_real);
 #endif
+
+next:
+		fmt_done(format);
 	} while ((format = format->next) && !event_abort);
 
 	if (failed && total > 1 && !event_abort)
diff -urp john-1.7.9.6/src/bench.h john-1.7.9.6-newform/src/bench.h
--- john-1.7.9.6/src/bench.h	2011-11-06 13:17:58 +0000
+++ john-1.7.9.6-newform/src/bench.h	2012-07-21 12:48:00 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-99,2006,2009,2011 by Solar Designer
+ * Copyright (c) 1996-99,2006,2009,2011,2012 by Solar Designer
  */
 
 /*
@@ -23,8 +23,8 @@ struct bench_results {
 /* Elapsed real and processor time */
 	clock_t real, virtual;
 
-/* Number of passwords tried */
-	int64 count;
+/* Number of ciphertexts computed */
+	int64 crypts;
 };
 
 /*
@@ -54,7 +54,7 @@ extern char *benchmark_format(struct fmt
 /*
  * Converts benchmarked c/s into an ASCII string.
  */
-extern void benchmark_cps(int64 *count, clock_t time, char *buffer);
+extern void benchmark_cps(int64 *crypts, clock_t time, char *buffer);
 
 /*
  * Benchmarks all the registered cracking algorithms and prints the results
diff -urp john-1.7.9.6/src/best.c john-1.7.9.6-newform/src/best.c
--- john-1.7.9.6/src/best.c	2011-11-06 11:19:06 +0000
+++ john-1.7.9.6-newform/src/best.c	2012-07-21 12:49:58 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-99,2003,2006,2011 by Solar Designer
+ * Copyright (c) 1996-99,2003,2006,2011,2012 by Solar Designer
  */
 
 /*
@@ -65,7 +65,7 @@ int main(int argc, char **argv)
 
 		fprintf(stderr, "FAILED\n");
 	} else {
-		tmp = results.count;
+		tmp = results.crypts;
 		mul64by32(&tmp, clk_tck * 10);
 #ifdef _OPENMP
 		virtual = div64by32lo(&tmp, results.real);
@@ -73,13 +73,15 @@ int main(int argc, char **argv)
 		virtual = div64by32lo(&tmp, results.virtual);
 #endif
 
-		benchmark_cps(&results.count, results.real, s_real);
-		benchmark_cps(&results.count, results.virtual, s_virtual);
+		benchmark_cps(&results.crypts, results.real, s_real);
+		benchmark_cps(&results.crypts, results.virtual, s_virtual);
 
 		fprintf(stderr, "%s c/s real, %s c/s virtual\n",
 			s_real, s_virtual);
 	}
 
+	fmt_done(format);
+
 	printf("%lu\n", virtual);
 
 	return virtual ? 0 : 1;
diff -urp john-1.7.9.6/src/c3_fmt.c john-1.7.9.6-newform/src/c3_fmt.c
--- john-1.7.9.6/src/c3_fmt.c	2012-07-15 09:39:28 +0000
+++ john-1.7.9.6-newform/src/c3_fmt.c	2012-07-21 12:20:25 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 2009-2011 by Solar Designer
+ * Copyright (c) 2009-2012 by Solar Designer
  *
  * Generic crypt(3) support, as well as support for glibc's crypt_r(3) and
  * Solaris' MT-safe crypt(3C) with OpenMP parallelization.
@@ -341,8 +341,9 @@ static char *get_key(int index)
 	return saved_key[index];
 }
 
-static void crypt_all(int count)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	int index;
 
 #if defined(_OPENMP) && defined(__GLIBC__)
@@ -393,6 +394,8 @@ static void crypt_all(int count)
 		strnzcpy(crypt_out[index], crypt(saved_key[index], saved_salt),
 		    BINARY_SIZE);
 #endif
+
+	return count;
 }
 
 static int cmp_all(void *binary, int count)
@@ -434,6 +437,8 @@ struct fmt_main fmt_crypt = {
 		tests
 	}, {
 		fmt_default_init,
+		fmt_default_done,
+		fmt_default_reset,
 		fmt_default_prepare,
 		valid,
 		fmt_default_split,
diff -urp john-1.7.9.6/src/cracker.c john-1.7.9.6-newform/src/cracker.c
--- john-1.7.9.6/src/cracker.c	2012-07-14 13:36:44 +0000
+++ john-1.7.9.6-newform/src/cracker.c	2012-07-21 12:35:04 +0000
@@ -56,7 +56,15 @@ void crk_init(struct db_main *db, void (
 	char *where;
 	size_t size;
 
-	if (db->loaded)
+/*
+ * We should have already called fmt_self_test() from john.c.  This redundant
+ * self-test is only to catch some more obscure bugs in debugging builds (it
+ * is a no-op in normal builds).  Additionally, we skip it even in debugging
+ * builds if we're running in --stdout mode (there's no format involved then)
+ * or if the format has a custom reset() method (we've already called reset(db)
+ * from john.c, and we don't want to mess with the format's state).
+ */
+	if (db->loaded && db->format->methods.reset == fmt_default_reset)
 	if ((where = fmt_self_test(db->format))) {
 		log_event("! Self test failed (%s)", where);
 		fprintf(stderr, "Self test failed (%s)\n", where);
@@ -225,7 +233,7 @@ static int crk_process_event(void)
 static int crk_password_loop(struct db_salt *salt)
 {
 	struct db_password *pw;
-	int index;
+	int count, match, index;
 
 #if !OS_TIMER
 	sig_timer_emu_tick();
@@ -236,19 +244,24 @@ static int crk_password_loop(struct db_s
 	if (event_pending)
 	if (crk_process_event()) return 1;
 
-	crk_methods.crypt_all(crk_key_index);
+	count = crk_key_index;
+	match = crk_methods.crypt_all(&count, salt);
+	crk_last_key = count;
 
 	{
 		int64 effective_count;
-		mul32by32(&effective_count, salt->count, crk_key_index);
+		mul32by32(&effective_count, salt->count, count);
 		status_update_crypts(&effective_count);
 	}
 
+	if (!match)
+		return 0;
+
 	if (!salt->bitmap) {
 		pw = salt->list;
 		do {
-			if (crk_methods.cmp_all(pw->binary, crk_key_index))
-			for (index = 0; index < crk_key_index; index++)
+			if (crk_methods.cmp_all(pw->binary, match))
+			for (index = 0; index < match; index++)
 			if (crk_methods.cmp_one(pw->binary, index))
 			if (crk_methods.cmp_exact(crk_methods.source(
 			    pw->source, pw->binary), index)) {
@@ -259,7 +272,7 @@ static int crk_password_loop(struct db_s
 			}
 		} while ((pw = pw->next));
 	} else
-	for (index = 0; index < crk_key_index; index++) {
+	for (index = 0; index < match; index++) {
 		int hash = salt->index(index);
 		if (salt->bitmap[hash / (sizeof(*salt->bitmap) * 8)] &
 		    (1U << (hash % (sizeof(*salt->bitmap) * 8)))) {
@@ -287,7 +300,7 @@ static int crk_salt_loop(void)
 		if (crk_password_loop(salt)) return 1;
 	} while ((salt = salt->next));
 
-	crk_last_key = crk_key_index; crk_key_index = 0;
+	crk_key_index = 0;
 	crk_last_salt = NULL;
 	crk_fix_state();
 
@@ -390,7 +403,7 @@ char *crk_get_key1(void)
 
 char *crk_get_key2(void)
 {
-	if (crk_key_index > 1)
+	if (crk_key_index > 1 && crk_key_index < crk_last_key)
 		return crk_methods.get_key(crk_key_index - 1);
 	else
 	if (crk_last_key > 1)
diff -urp john-1.7.9.6/src/dummy.c john-1.7.9.6-newform/src/dummy.c
--- john-1.7.9.6/src/dummy.c	2012-07-15 09:42:38 +0000
+++ john-1.7.9.6-newform/src/dummy.c	2012-07-21 12:20:59 +0000
@@ -228,8 +228,9 @@ static char *get_key(int index)
 	return saved_key[index];
 }
 
-static void crypt_all(int count)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	return *pcount;
 }
 
 static int cmp_all(void *binary, int count)
@@ -276,6 +277,8 @@ struct fmt_main fmt_dummy = {
 		tests
 	}, {
 		fmt_default_init,
+		fmt_default_done,
+		fmt_default_reset,
 		fmt_default_prepare,
 		valid,
 		fmt_default_split,
diff -urp john-1.7.9.6/src/formats.c john-1.7.9.6-newform/src/formats.c
--- john-1.7.9.6/src/formats.c	2012-07-17 12:44:49 +0000
+++ john-1.7.9.6-newform/src/formats.c	2012-07-21 12:13:15 +0000
@@ -29,6 +29,14 @@ void fmt_init(struct fmt_main *format)
 	}
 }
 
+void fmt_done(struct fmt_main *format)
+{
+	if (format->private.initialized) {
+		format->methods.done();
+		format->private.initialized = 0;
+	}
+}
+
 static int is_poweroftwo(size_t align)
 {
 	return align != 0 && (align & (align - 1)) == 0;
@@ -49,6 +57,14 @@ static char *fmt_self_test_body(struct f
 	void *binary, *salt;
 	int binary_align_warned = 0, salt_align_warned = 0;
 
+/*
+ * Test each format just once unless we're debugging.
+ */
+#ifndef DEBUG
+	if (format->private.initialized == 2)
+		return NULL;
+#endif
+
 	if (format->params.plaintext_length < 1 ||
 	    format->params.plaintext_length > PLAINTEXT_BUFFER_SIZE - 3)
 		return "plaintext_length";
@@ -64,6 +80,8 @@ static char *fmt_self_test_body(struct f
 
 	fmt_init(format);
 
+	format->methods.reset(NULL);
+
 	if (!(current = format->params.tests)) return NULL;
 	ntests = 0;
 	while ((current++)->ciphertext)
@@ -117,7 +135,11 @@ static char *fmt_self_test_body(struct f
 		format->methods.set_salt(salt);
 		format->methods.set_key(current->plaintext, index);
 
-		format->methods.crypt_all(index + 1);
+		{
+			int count = index + 1;
+			if (format->methods.crypt_all(&count, NULL) != count)
+				return "crypt_all";
+		}
 
 		for (size = 0; size < PASSWORD_HASH_SIZES; size++)
 		if (format->methods.binary_hash[size] &&
@@ -166,6 +188,8 @@ static char *fmt_self_test_body(struct f
 		}
 	} while (done != 3);
 
+	format->private.initialized = 2;
+
 	return NULL;
 }
 
@@ -214,6 +238,14 @@ void fmt_default_init(struct fmt_main *s
 {
 }
 
+void fmt_default_done(void)
+{
+}
+
+void fmt_default_reset(struct db_main *db)
+{
+}
+
 char *fmt_default_prepare(char *fields[10], struct fmt_main *self)
 {
 	return fields[1];
diff -urp john-1.7.9.6/src/formats.h john-1.7.9.6-newform/src/formats.h
--- john-1.7.9.6/src/formats.h	2012-07-15 09:00:07 +0000
+++ john-1.7.9.6-newform/src/formats.h	2012-07-21 12:36:27 +0000
@@ -13,6 +13,13 @@
 #include "params.h"
 
 /*
+ * Some format methods accept pointers to these, yet we can't just include
+ * loader.h here because that would be a circular dependency.
+ */
+struct db_main;
+struct db_salt;
+
+/*
  * Format property flags.
  */
 /* Uses case-sensitive passwords */
@@ -100,6 +107,17 @@ struct fmt_methods {
  * shared underlying resource is used). */
 	void (*init)(struct fmt_main *self);
 
+/* De-initializes this format, which must have been previously initialized */
+	void (*done)(void);
+
+/* Called whenever the set of password hashes being cracked changes, such as
+ * after self-test, but before actual cracking starts.  When called before a
+ * self-test or benchmark rather than before actual cracking, db may be NULL.
+ * Normally, this is a no-op since a format implementation shouldn't mess with
+ * the database unnecessarily.  However, when there is a good reason to do so
+ * this may e.g. transfer the salts and hashes onto a GPU card. */
+	void (*reset)(struct db_main *db);
+
 /* Extracts the ciphertext string out of the input file fields.  Normally, this
  * will simply return field[1], but in some special cases it may use another
  * field (e.g., when the hash type is commonly used with PWDUMP rather than
@@ -145,7 +163,12 @@ struct fmt_methods {
 /* Sets a plaintext, with index from 0 to fmt_params.max_keys_per_crypt - 1 */
 	void (*set_key)(char *key, int index);
 
-/* Returns a plaintext previously set with set_key() */
+/* Returns a plaintext previously set with and potentially altered by
+ * set_key() (e.g., converted to all-uppercase and truncated at 7 for LM
+ * hashes).  The plaintext may also have been generated or altered by
+ * crypt_all().  Depending on crypt_all() implementation, the index used here
+ * does not have to match an index previously used with set_key(), although
+ * for most formats it does.  See the description of crypt_all() below. */
 	char *(*get_key)(int index);
 
 /* Allow the previously set keys to be dropped if that would help improve
@@ -153,10 +176,29 @@ struct fmt_methods {
  * a call to clear_keys() the keys are undefined. */
 	void (*clear_keys)(void);
 
-/* Calculates the ciphertexts for given salt and plaintexts. This may
- * always calculate at least min_keys_per_crypt ciphertexts regardless of
- * the requested count, for some formats. */
-	void (*crypt_all)(int count);
+/* Computes the ciphertexts for given salt and plaintexts.
+ * For implementation reasons, this may happen to always compute at least
+ * min_keys_per_crypt ciphertexts even if the requested count is lower,
+ * although it is preferable for implementations to obey the count whenever
+ * practical and also for callers not to call crypt_all() with fewer than
+ * min_keys_per_crypt keys whenever practical.
+ * Returns the last output index for which there might be a match (against the
+ * supplied salt's hashes) plus 1.  A return value of zero indicates no match.
+ * Note that output indices don't have to match input indices (although they
+ * may and usually do).  The indices passed to get_key(), get_hash[](),
+ * cmp_one(), and cmp_exact() must be in the 0 to crypt_all() return value
+ * minus 1 range, although for infrequent status reporting get_key() may also
+ * be called on indices previously supplied to set_key() as well as on indices
+ * up to the updated *count minus 1 even if they're beyond this range.
+ * The count passed to cmp_all() must be equal to crypt_all()'s return value.
+ * If an implementation does not use the salt parameter or if salt is NULL
+ * (as it may be during self-test and benchmark), the return value must always
+ * match *count the way it is after the crypt_all() call.
+ * The count is passed by reference and must be updated by crypt_all() if it
+ * computes other than the requested count (such as if it generates additional
+ * candidate passwords on its own).  The updated count is used for c/s rate
+ * calculation.  The return value is thus in the 0 to updated *count range. */
+	int (*crypt_all)(int *count, struct db_salt *salt);
 
 /* These functions calculate a hash out of a ciphertext that has just been
  * generated with the crypt_all() method. To be used while cracking. */
@@ -208,6 +250,11 @@ extern void fmt_register(struct fmt_main
 extern void fmt_init(struct fmt_main *format);
 
 /*
+ * De-initializes this format if it was previously initialized.
+ */
+extern void fmt_done(struct fmt_main *format);
+
+/*
  * Tests the format's methods for correct operation. Returns NULL on
  * success, method name on error.
  */
@@ -217,6 +264,8 @@ extern char *fmt_self_test(struct fmt_ma
  * Default methods.
  */
 extern void fmt_default_init(struct fmt_main *self);
+extern void fmt_default_done(void);
+extern void fmt_default_reset(struct db_main *db);
 extern char *fmt_default_prepare(char *fields[10], struct fmt_main *self);
 extern int fmt_default_valid(char *ciphertext, struct fmt_main *self);
 extern char *fmt_default_split(char *ciphertext, int index,
diff -urp john-1.7.9.6/src/john.c john-1.7.9.6-newform/src/john.c
--- john-1.7.9.6/src/john.c	2011-11-23 02:46:59 +0000
+++ john-1.7.9.6-newform/src/john.c	2012-07-18 02:00:20 +0000
@@ -1,6 +1,6 @@
 /*
  * This file is part of John the Ripper password cracker,
- * Copyright (c) 1996-2004,2006,2009-2011 by Solar Designer
+ * Copyright (c) 1996-2004,2006,2009-2012 by Solar Designer
  */
 
 #include <stdio.h>
@@ -316,8 +316,15 @@ static void john_run(void)
 		int remaining = database.password_count;
 
 		if (!(options.flags & FLG_STDOUT)) {
-			status_init(NULL, 1);
+			char *where = fmt_self_test(database.format);
+			if (where) {
+				fprintf(stderr, "Self test failed (%s)\n",
+				    where);
+				error();
+			}
+			database.format->methods.reset(&database);
 			log_init(LOG_NAME, POT_NAME, options.session);
+			status_init(NULL, 1);
 			john_log_format();
 			if (idle_requested(database.format))
 				log_event("- Configured to use otherwise idle "
@@ -368,16 +375,18 @@ static void john_run(void)
 
 static void john_done(void)
 {
-	path_done();
-
-	if ((options.flags & FLG_CRACKING_CHK) &&
-	    !(options.flags & FLG_STDOUT)) {
+	if ((options.flags & (FLG_CRACKING_CHK | FLG_STDOUT)) ==
+	    FLG_CRACKING_CHK) {
 		if (event_abort)
 			log_event("Session aborted");
 		else
 			log_event("Session completed");
+		fmt_done(database.format);
 	}
 	log_done();
+
+	path_done();
+
 	check_abort(0);
 }
 
diff -urp john-1.7.9.6/src/trip_fmt.c john-1.7.9.6-newform/src/trip_fmt.c
--- john-1.7.9.6/src/trip_fmt.c	2012-07-15 09:41:42 +0000
+++ john-1.7.9.6-newform/src/trip_fmt.c	2012-07-21 12:20:41 +0000
@@ -481,10 +481,12 @@ static MAYBE_INLINE void crypt_traverse_
 #endif
 }
 
-static void crypt_all(int count)
+static int crypt_all(int *pcount, struct db_salt *salt)
 {
+	int count = *pcount;
 	crypt_link_by_salt(count);
 	crypt_traverse_by_salt(count);
+	return count;
 }
 
 #if DES_BS
@@ -592,6 +594,8 @@ struct fmt_main fmt_trip = {
 		tests
 	}, {
 		init,
+		fmt_default_done,
+		fmt_default_reset,
 		fmt_default_prepare,
 		valid,
 		fmt_default_split,
diff -urp john-1.7.9.6/src/x86-64.S john-1.7.9.6-newform/src/x86-64.S
--- john-1.7.9.6/src/x86-64.S	2011-11-23 04:41:37 +0000
+++ john-1.7.9.6-newform/src/x86-64.S	2012-07-21 13:08:57 +0000
@@ -1,7 +1,7 @@
 /*
  * This file contains the core of a bitslice DES implementation for x86-64/SSE2.
  * It is part of John the Ripper password cracker,
- * Copyright (c) 2000-2001,2005,2006,2008,2011 by Solar Designer
+ * Copyright (c) 2000-2001,2005,2006,2008,2011,2012 by Solar Designer
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted.  (This is a heavily cut-down "BSD license".)
  *
@@ -1177,6 +1177,7 @@ DES_bs_finalize_keys_expand_loop:
 DO_ALIGN(6)
 .globl DES_bs_crypt_LM
 DES_bs_crypt_LM:
+	movl (%rdi),%r8d
 	movdqa mask01,%xmm7
 	movdqa mask02,%xmm8
 	leaq DES_bs_all_xkeys(%rip),v_ptr
@@ -1331,6 +1332,7 @@ DES_bs_crypt_LM_loop:
 	S8(B(4), B(26), B(14), B(20))
 	subl $1,rounds
 	jnz DES_bs_crypt_LM_loop
+	xchgq %r8,%rax
 	ret
 
 #endif
diff -urp john-1.7.9.6/src/x86-mmx.S john-1.7.9.6-newform/src/x86-mmx.S
--- john-1.7.9.6/src/x86-mmx.S	2011-10-21 10:42:30 +0000
+++ john-1.7.9.6-newform/src/x86-mmx.S	2012-07-21 12:39:48 +0000
@@ -1,7 +1,7 @@
 /*
  * This file contains the core of a bitslice DES implementation for x86/MMX.
  * It is part of John the Ripper password cracker,
- * Copyright (c) 2000-2001,2005,2006,2008,2011 by Solar Designer
+ * Copyright (c) 2000-2001,2005,2006,2008,2011,2012 by Solar Designer
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted.  (This is a heavily cut-down "BSD license".)
  *
@@ -1385,10 +1385,12 @@ DES_bs_crypt_LM_loop:
 	S8(B(4), B(26), B(14), B(20))
 	decl rounds
 	jnz DES_bs_crypt_LM_loop
+	movl 8(%esp),%eax
 	popl %esi
 #ifdef EMMS
 	emms
 #endif
+	movl (%eax),%eax
 	ret
 
 #endif
diff -urp john-1.7.9.6/src/x86-sse.S john-1.7.9.6-newform/src/x86-sse.S
--- john-1.7.9.6/src/x86-sse.S	2011-10-21 10:42:30 +0000
+++ john-1.7.9.6-newform/src/x86-sse.S	2012-07-21 12:40:11 +0000
@@ -1,7 +1,7 @@
 /*
  * This file contains the core of a bitslice DES implementation for x86/SSE2.
  * It is part of John the Ripper password cracker,
- * Copyright (c) 2000-2001,2005,2006,2008,2011 by Solar Designer
+ * Copyright (c) 2000-2001,2005,2006,2008,2011,2012 by Solar Designer
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted.  (This is a heavily cut-down "BSD license".)
  *
@@ -1383,7 +1383,9 @@ DES_bs_crypt_LM_loop:
 	S8(B(4), B(26), B(14), B(20), a6_p)
 	decl rounds
 	jnz DES_bs_crypt_LM_loop
+	movl 8(%esp),%eax
 	popl %esi
+	movl (%eax),%eax
 	ret
 
 #endif

Powered by blists - more mailing lists

Your e-mail address:

Powered by Openwall GNU/*/Linux - Powered by OpenVZ