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 @@ -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 @@ -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 @@ -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 @@ -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