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

myrice, all -

I've revised crypt_all() to be as follows:

/* 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.
 * 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);

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.)

Attached to this message are 3 patches:

john-1.7.9.6+reset-crypt_all-2.diff - makes the crypt_all() declaration
and semantics changes to match the description above, patch relative to
john-1.7.9.6-reset-1.diff that I posted before.

john-1.7.9.6-LM-1.diff - makes use of the above changes to speed up LM
hash cracking in OpenMP-enabled builds.  This is a quick and dirty
implementation not taking full advantage of the crypt_all() changes yet,
but it does illustrate how the interface may be used.  This implements
initial hash comparisons within the same parallel region that computes
the hashes, and by the same threads that computed the hashes (so it
can't happen that one thread computed a hash, but another does the
comparison, which would be slower).  I've actually measured an almost 2x
speedup in a certain OpenMP-enabled build running against 10k hashes.
For the sake of simplicity, I am using the existing salt->index() hash
function, although this involves converting from thread offset + index
in thread to global index and back.  A "standalone" implementation (like
one running on GPU) would implement a hash function of its own and would
access its own bitmap, hash table, etc.  I primarily had myrice's
project in mind when working on this example.  In fact, I wouldn't be
working on it right now otherwise.

john-1.7.9.6-crypt_all+LM-1.diff is the same as above, but relative to
clean 1.7.9.6 as found in CVS.

myrice - if you'd like to experiment with these new interfaces on
bleeding codebase (so that you can use them with a GPU format), you may
move all *_fmt_plug.c files out of the tree so that you have fewer
formats to modify to use the new conventions (or disable manually in
Makefile and john.c).  I actually recommend that you do this.  You may
also proceed to experiment with your own formats interface changes in
a similar way (and propose successful ones in here).

Thanks,

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 01:45:58 +0000
+++ john-1.7.9.6-newform/src/AFS_fmt.c	2012-07-18 04:12:23 +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,7 +281,7 @@
 	return buffer[index].key;
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	int index, pos, length;
 	char xor[8];
@@ -378,6 +378,8 @@
 		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)
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 01:46:04 +0000
+++ john-1.7.9.6-newform/src/BF_fmt.c	2012-07-18 04:12:29 +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,7 +225,7 @@
 	return saved_key[index];
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	if (keys_mode != saved_salt.subtype) {
 		int i;
@@ -237,6 +237,8 @@
 	}
 
 	BF_std_crypt(&saved_salt, count);
+
+	return count;
 }
 
 static int cmp_all(void *binary, int count)
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 01:46:06 +0000
+++ john-1.7.9.6-newform/src/BSDI_fmt.c	2012-07-18 03:37:07 +0000
@@ -315,9 +315,10 @@
 
 #if DES_BS
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	DES_bs_crypt(saved_count, count);
+	return count;
 }
 
 static int cmp_one(void *binary, int index)
@@ -332,7 +333,7 @@
 
 #else
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	int index;
 
@@ -344,6 +345,8 @@
 
 	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)
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 01:46:10 +0000
+++ john-1.7.9.6-newform/src/DES_fmt.c	2012-07-18 04:01:18 +0000
@@ -72,22 +72,22 @@
 
 #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,12 @@
 	DES_bs_set_salt(*(ARCH_WORD *)salt);
 }
 
+static int crypt_all(int count, struct db_salt *salt)
+{
+	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 +269,15 @@
 	DES_std_set_salt(*(ARCH_WORD *)salt);
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	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 +372,7 @@
 #endif
 		tests
 	}, {
-#if DES_BS
 		init,
-#else
-		DES_std_init,
-#endif
 		fmt_default_done,
 		fmt_default_reset,
 		fmt_default_prepare,
@@ -400,11 +404,7 @@
 #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 -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 01:46:15 +0000
+++ john-1.7.9.6-newform/src/MD5_fmt.c	2012-07-18 03:45:46 +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,12 @@
 	return saved_key[index];
 }
 
+static int crypt_all(int count, struct db_salt *salt)
+{
+	MD5_std_crypt(count);
+	return count;
+}
+
 static int cmp_all(void *binary, int count)
 {
 #if MD5_std_mt
@@ -269,7 +275,7 @@
 		set_key,
 		get_key,
 		fmt_default_clear_keys,
-		MD5_std_crypt,
+		crypt_all,
 		{
 			get_hash_0,
 			get_hash_1,
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-17 16:51:27 +0000
+++ john-1.7.9.6-newform/src/bench.c	2012-07-18 03:20:44 +0000
@@ -179,7 +179,7 @@
 		}
 
 		if (salts > 1) format->methods.set_salt(two_salts[index & 1]);
-		format->methods.crypt_all(max);
+		(void)format->methods.crypt_all(max, NULL);
 		format->methods.cmp_all(binary, max);
 
 		add32to64(&count, max);
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 01:46:18 +0000
+++ john-1.7.9.6-newform/src/c3_fmt.c	2012-07-18 04:12:39 +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,7 +341,7 @@
 	return saved_key[index];
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	int index;
 
@@ -393,6 +393,8 @@
 		strnzcpy(crypt_out[index], crypt(saved_key[index], saved_salt),
 		    BINARY_SIZE);
 #endif
+
+	return count;
 }
 
 static int cmp_all(void *binary, int count)
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 01:59:45 +0000
+++ john-1.7.9.6-newform/src/cracker.c	2012-07-18 03:19:27 +0000
@@ -233,7 +233,7 @@
 static int crk_password_loop(struct db_salt *salt)
 {
 	struct db_password *pw;
-	int index;
+	int match, index;
 
 #if !OS_TIMER
 	sig_timer_emu_tick();
@@ -244,7 +244,7 @@
 	if (event_pending)
 	if (crk_process_event()) return 1;
 
-	crk_methods.crypt_all(crk_key_index);
+	match = crk_methods.crypt_all(crk_key_index, salt);
 
 	{
 		int64 effective_count;
@@ -252,11 +252,14 @@
 		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)) {
@@ -267,7 +270,7 @@
 			}
 		} 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)))) {
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 01:46:22 +0000
+++ john-1.7.9.6-newform/src/dummy.c	2012-07-18 03:39:54 +0000
@@ -228,8 +228,9 @@
 	return saved_key[index];
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
+	return count;
 }
 
 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 01:48:21 +0000
+++ john-1.7.9.6-newform/src/formats.c	2012-07-18 03:21:02 +0000
@@ -135,7 +135,8 @@
 		format->methods.set_salt(salt);
 		format->methods.set_key(current->plaintext, index);
 
-		format->methods.crypt_all(index + 1);
+		if (format->methods.crypt_all(index + 1, NULL) != index + 1)
+			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 01:44:33 +0000
+++ john-1.7.9.6-newform/src/formats.h	2012-07-18 03:40:22 +0000
@@ -13,10 +13,11 @@
 #include "params.h"
 
 /*
- * The reset() format method accepts a pointer to struct db_main, yet we can't
- * just include loader.h here because that would be a circular dependency.
+ * 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.
@@ -170,10 +171,18 @@
  * 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.
+ * 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);
 
 /* 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 01:46:20 +0000
+++ john-1.7.9.6-newform/src/trip_fmt.c	2012-07-18 03:52:13 +0000
@@ -481,10 +481,11 @@
 #endif
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	crypt_link_by_salt(count);
 	crypt_traverse_by_salt(count);
+	return count;
 }
 
 #if DES_BS
only in patch2:
unchanged:
--- 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-18 03:51:22 +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
only in patch2:
unchanged:
--- 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-18 03:51:00 +0000
@@ -1452,7 +1452,7 @@ 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 keys_count, struct db_salt *salt)
 {
 #if DES_bs_mt
 	int t, n = (keys_count + (DES_BS_DEPTH - 1)) / DES_BS_DEPTH;
@@ -1559,5 +1559,7 @@ void DES_bs_crypt_LM(int keys_count)
 			k += 96;
 		} while (--rounds);
 	}
+
+	return keys_count;
 }
 #endif
only in patch2:
unchanged:
--- 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-18 07:28:35 +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:
+	pushq %rdi
 	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
+	popq %rax
 	ret
 
 #endif
only in patch2:
unchanged:
--- 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-18 03:54:59 +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".)
  *
@@ -1386,6 +1386,7 @@ DES_bs_crypt_LM_loop:
 	decl rounds
 	jnz DES_bs_crypt_LM_loop
 	popl %esi
+	movl 4(%esp),%eax
 #ifdef EMMS
 	emms
 #endif
only in patch2:
unchanged:
--- 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-18 03:56:35 +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".)
  *
@@ -1384,6 +1384,7 @@ DES_bs_crypt_LM_loop:
 	decl rounds
 	jnz DES_bs_crypt_LM_loop
 	popl %esi
+	movl 4(%esp),%eax
 	ret
 
 #endif

diff -urp john-1.7.9.6-c2/src/DES_bs_b.c john-1.7.9.6/src/DES_bs_b.c
--- john-1.7.9.6-c2/src/DES_bs_b.c	2012-07-18 03:51:00 +0000
+++ john-1.7.9.6/src/DES_bs_b.c	2012-07-18 09:03:48 +0000
@@ -1455,11 +1455,12 @@ static MAYBE_INLINE void DES_bs_finalize
 int DES_bs_crypt_LM(int keys_count, struct db_salt *salt)
 {
 #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,8 +1559,44 @@ int DES_bs_crypt_LM(int keys_count, stru
 
 			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/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-18 04:12:23 +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,7 +281,7 @@ static char *get_key(int index)
 	return buffer[index].key;
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	int index, pos, length;
 	char xor[8];
@@ -378,6 +378,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 +451,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-18 04:12:29 +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,7 +225,7 @@ static char *get_key(int index)
 	return saved_key[index];
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	if (keys_mode != saved_salt.subtype) {
 		int i;
@@ -237,6 +237,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 +294,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-18 03:37:07 +0000
@@ -315,9 +315,10 @@ static char *get_key(int index)
 
 #if DES_BS
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	DES_bs_crypt(saved_count, count);
+	return count;
 }
 
 static int cmp_one(void *binary, int index)
@@ -332,7 +333,7 @@ static int cmp_exact(char *source, int i
 
 #else
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	int index;
 
@@ -344,6 +345,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 +409,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-18 03:51:22 +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-18 09:03:48 +0000
@@ -1452,14 +1452,15 @@ 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 keys_count, struct db_salt *salt)
 {
 #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 +1559,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-18 04:01:18 +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,12 @@ static void set_salt(void *salt)
 	DES_bs_set_salt(*(ARCH_WORD *)salt);
 }
 
+static int crypt_all(int count, struct db_salt *salt)
+{
+	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 +269,15 @@ static void set_salt(void *salt)
 	DES_std_set_salt(*(ARCH_WORD *)salt);
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	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 +372,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 +404,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-18 03:45:46 +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,12 @@ static char *get_key(int index)
 	return saved_key[index];
 }
 
+static int crypt_all(int count, struct db_salt *salt)
+{
+	MD5_std_crypt(count);
+	return count;
+}
+
 static int cmp_all(void *binary, int count)
 {
 #if MD5_std_mt
@@ -247,6 +253,8 @@ struct fmt_main fmt_MD5 = {
 		tests
 	}, {
 		init,
+		fmt_default_done,
+		fmt_default_reset,
 		fmt_default_prepare,
 		valid,
 		fmt_default_split,
@@ -267,7 +275,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-18 03:20:44 +0000
@@ -179,7 +179,7 @@ char *benchmark_format(struct fmt_main *
 		}
 
 		if (salts > 1) format->methods.set_salt(two_salts[index & 1]);
-		format->methods.crypt_all(max);
+		(void)format->methods.crypt_all(max, NULL);
 		format->methods.cmp_all(binary, max);
 
 		add32to64(&count, max);
@@ -270,14 +270,14 @@ 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");
@@ -294,7 +294,7 @@ int benchmark_all(void)
 
 		if (!msg_1) {
 			putchar('\n');
-			continue;
+			goto next;
 		}
 
 		benchmark_cps(&results_1.count, results_1.real, s_real);
@@ -306,6 +306,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/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-17 16:53:12 +0000
@@ -80,6 +80,8 @@ int main(int argc, char **argv)
 			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-18 04:12:39 +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,7 +341,7 @@ static char *get_key(int index)
 	return saved_key[index];
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	int index;
 
@@ -393,6 +393,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 +436,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-18 03:19:27 +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 match, index;
 
 #if !OS_TIMER
 	sig_timer_emu_tick();
@@ -236,7 +244,7 @@ static int crk_password_loop(struct db_s
 	if (event_pending)
 	if (crk_process_event()) return 1;
 
-	crk_methods.crypt_all(crk_key_index);
+	match = crk_methods.crypt_all(crk_key_index, salt);
 
 	{
 		int64 effective_count;
@@ -244,11 +252,14 @@ static int crk_password_loop(struct db_s
 		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 +270,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)))) {
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-18 03:39:54 +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 count, struct db_salt *salt)
 {
+	return count;
 }
 
 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-18 03:21:02 +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,8 @@ 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);
+		if (format->methods.crypt_all(index + 1, NULL) != index + 1)
+			return "crypt_all";
 
 		for (size = 0; size < PASSWORD_HASH_SIZES; size++)
 		if (format->methods.binary_hash[size] &&
@@ -166,6 +185,8 @@ static char *fmt_self_test_body(struct f
 		}
 	} while (done != 3);
 
+	format->private.initialized = 2;
+
 	return NULL;
 }
 
@@ -214,6 +235,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-18 03:40:22 +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
@@ -153,10 +171,18 @@ 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.
+ * 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);
 
 /* 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 +234,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 +248,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-18 03:52:13 +0000
@@ -481,10 +481,11 @@ static MAYBE_INLINE void crypt_traverse_
 #endif
 }
 
-static void crypt_all(int count)
+static int crypt_all(int count, struct db_salt *salt)
 {
 	crypt_link_by_salt(count);
 	crypt_traverse_by_salt(count);
+	return count;
 }
 
 #if DES_BS
@@ -592,6 +593,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-18 07:28:35 +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:
+	pushq %rdi
 	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
+	popq %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-18 03:54:59 +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".)
  *
@@ -1386,6 +1386,7 @@ DES_bs_crypt_LM_loop:
 	decl rounds
 	jnz DES_bs_crypt_LM_loop
 	popl %esi
+	movl 4(%esp),%eax
 #ifdef EMMS
 	emms
 #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-18 03:56:35 +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".)
  *
@@ -1384,6 +1384,7 @@ DES_bs_crypt_LM_loop:
 	decl rounds
 	jnz DES_bs_crypt_LM_loop
 	popl %esi
+	movl 4(%esp),%eax
 	ret
 
 #endif

Powered by blists - more mailing lists

Your e-mail address:

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