diff -ruN john-1.6/doc/CHANGES john-1.6.34/doc/CHANGES --- john-1.6/doc/CHANGES 1970-01-01 01:00:00.000000000 +0100 +++ john-1.6.34/doc/CHANGES 2003-01-24 04:55:37.000000000 +0100 @@ -0,0 +1,16 @@ +The following major changes have been done since John 1.6: + +* Two MD5 hashes at a time for extra ILP on RISC: up to +80% on Alpha EV5. +* Significant improvements to the generic bitslice DES code: +20% on RISC. +* Bitslice DES code for x86 with MMX: more than twice faster on Intel MMX. +* Bitsliced the LM hash code as well: now several times faster. +* Generic Blowfish x86 assembly code in addition to the original Pentium +version: +15% on the Pentium Pro family (up to Pentium III), +20% on AMD. +* First attempt at vectorization support for bitslice DES. +* Better idle priority emulation with POSIX.1b (POSIX.4) scheduling calls. +* System-wide installation support for *BSD ports and Linux distributions. +* AIX, DU / Tru64 C2, HP-UX tcb files support in 'unshadow'. +* New make targets for Linux/PowerPC, FreeBSD/Alpha, SCO, OpenBSD/SPARC, +OpenBSD/VAX, NetBSD/VAX, Solaris/SPARC64, MacOS X, BeOS. +* Bug and portability fixes, and new bugs. +* Bonus: "Strip" cracker included in the default john.conf (john.ini). diff -ruN john-1.6/doc/LICENSING john-1.6.34/doc/LICENSING --- john-1.6/doc/LICENSING 1970-01-01 01:00:00.000000000 +0100 +++ john-1.6.34/doc/LICENSING 2002-05-08 20:05:53.000000000 +0200 @@ -0,0 +1,13 @@ +John the Ripper 1.7, when released, is going to be GPL'ed. However, +the licensing status of one source file -- x86-mmx.S -- is non-obvious +to me. I have explicit permission to use the S-box code found in this +file in John, but I'm not sure whether this was meant to imply that I +am free to put this code under a license of my choice. I haven't got +a reply regarding this so far. + +Portions of this code I've placed into the public domain as a separate +package designed to provide modern password hashing for your software +and your servers (where the GPL restrictions could be a problem). The +package can be found at: + + http://www.openwall.com/crypt/ diff -ruN john-1.6/run/john.conf john-1.6.34/run/john.conf --- john-1.6/run/john.conf 1970-01-01 01:00:00.000000000 +0100 +++ john-1.6.34/run/john.conf 2002-05-10 20:16:35.000000000 +0200 @@ -0,0 +1,576 @@ +# +# This file is part of John the Ripper password cracker, +# Copyright (c) 1996-2002 by Solar Designer +# + +[Options] +# Wordlist file name, to be used in batch mode +Wordfile = $JOHN/password.lst +# Use idle cycles only +Idle = N +# Crash recovery file saving delay in seconds +Save = 600 +# Beep when a password is found (who needs this anyway?) +Beep = N + +# "Single crack" mode rules +[List.Rules:Single] +# Simple rules come first... +: +-s x** +-c (?acQ +-c lQ +-s-c x**MlQ +# These were not included in crackers I've seen, but are pretty efficient, +# so I include them near the beginning +>6'6 +>7l'7 +>6/?ul'6 +>5'5 +# Weird order, eh? Can't do anything about it, the order is based on the +# number of successful cracks... +<*d +rc +<*dMcQ +>5/?ul'5 +uQ +r(?al +<*!?A[lc]p +<*cQd +>7/?u'7 +>4l'4 +<+(?lcr +<+r(?lcr +>3'3 +>4/?u'4 +>3/?ul'3 +uQr +<*lQf +# About 50% of single-mode-crackable passwords get cracked by now... +>2x12 +>3x13 +>4x14 +>5x15 +>6x16 +>7x17 +>8x18 +>3x22 +>4x23 +>5x24 +>6x25 +>7x26 +>8x27 +>9x28 +>4x32 +>5x33 +>6x34 +>7x35 +>8x36 +>9x37 +>2/?ulx12 +>3/?ulx13 +>4/?ulx14 +>5/?ulx15 +>6/?ulx16 +>7/?ulx17 +>8/?ulx18 +>3/?ulx22 +>4/?ulx23 +>5/?ulx24 +>6/?ulx25 +>7/?ulx26 +>8/?ulx27 +>9/?ulx28 +>4/?ulx32 +>5/?ulx33 +>6/?ulx34 +>7/?ulx35 +>8/?ulx36 +>9/?ulx37 +# Now to the suffix stuff... +<*l$[1-9!0a-z"-/:-@\[-`{-~] +<*(?ac$[1-9!0a-z"-/:-@\[-`{-~] +<*lr$[1-9!] +<*/?au$[1-9!] +<-l$!$! +<-(?ac$!$! +l$!<-$!$! +(?ac$!<-$!$! +# Removing vowels... +/?v@?v>2l +/?v@?v>2(?ac +/?v@?v>2<*d +# crack -> cracked, crack -> cracking +<*l[PI] +<*l[PI](?ac +# mary -> marie +<*(?a[lc])yro0ir$e +# marie -> mary +<*(?a[lc])er=1iD0o0yr +# The following 3l33t rules are based on original Crack's dicts.rules +l/asa4[:c] +l/ese3[:c] +l/lsl1[:c] +l/oso0[:c] +l/sss$[:c] +l/asa4/ese3[:c] +l/asa4/lsl1[:c] +l/asa4/oso0[:c] +l/asa4/sss$[:c] +l/ese3/lsl1[:c] +l/ese3/oso0[:c] +l/ese3/sss$[:c] +l/lsl1/oso0[:c] +l/lsl1/sss$[:c] +l/oso0/sss$[:c] +l/asa4/ese3/lsl1[:c] +l/asa4/ese3/oso0[:c] +l/asa4/ese3/sss$[:c] +l/asa4/lsl1/oso0[:c] +l/asa4/lsl1/sss$[:c] +l/asa4/oso0/sss$[:c] +l/ese3/lsl1/oso0[:c] +l/ese3/lsl1/sss$[:c] +l/ese3/oso0/sss$[:c] +l/lsl1/oso0/sss$[:c] +l/asa4/ese3/lsl1/oso0[:c] +l/asa4/ese3/lsl1/sss$[:c] +l/asa4/ese3/oso0/sss$[:c] +l/asa4/lsl1/oso0/sss$[:c] +l/ese3/lsl1/oso0/sss$[:c] +l/asa4/ese3/lsl1/oso0/sss$[:c] +# Now to the prefix stuff... +l^[1a-z2-90] +lQ^[A-Z] +^[A-Z] +l^["-/:-@\[-`{-~] +<9(?a[lc]^e^h^[tT] +<9(?a[lc]^y^m^[aA] +<9(?a[lc]^r^[mdMD] +<9(?a[lc]^.^r^[mdMD] +<9(?a[lc]^_^_ +<-!?Alp^[240-9] +# Some word pair rules... +# johnsmith -> JohnSmith, johnSmith +(?a2(?ac1[cl] +# JohnSmith -> john smith, john_smith, john-smith +1<-$[ _\-]+l +# JohnSmith -> John smith, John_smith, John-smith +1<-(?ac$[ _\-]2l +# JohnSmith -> john Smith, john_Smith, john-Smith +1<-l$[ _\-]2(?ac +# johnsmith -> John Smith, John_Smith, John-Smith +1<-(?ac$[ _\-]2(?ac +# Applying different simple rules to each of the two words +1[ur]2l +2(?ac1[ur] +1l2[ur] +1(?ac2[ur] +# jsmith -> smithj, etc... +(?a[lc][{}] +(?a[lc]}} +(?a[lc]{{ +# Toggle case... +T[1-7]Q +lMT[1-7]Q +>2[lu]MT0T2T4T6T8Q +# Deleting chars... +D[1-7]Q +D[1-7]Q/?ul +D[1-7]Q(?ac +# Inserting a dot... +>3(?a[lc]i[12]. +# More suffix stuff... +<-l$[190]$[0-9] +<-(?ac$[190]$[0-9] +<-l$[782]$[0-9] +<-(?ac$[782]$[0-9] +<*(?a[lc]$[A-Z] +# cracking -> CRACKiNG +u/IsIi +# Crack96 -> cRACK96 +CQ +# Crack96 -> cRACK(^ +SQ +# Crack96 -> CRaCK96 +/?vVQ +# Really weird charset conversions, like "england" -> "rmh;smf" +:[RL]Q +lQ[RL] +(?acQ[RL] +RRQ +LLQ +# Both prefixing and suffixing... +<-l^1$1 +<-l^!$! +<-l^@$@ +<-l^#$# +<-l^$$$ +<-l^%$% +<-l^^$^ +<-l^&$& +<-l^*$* +<-l^($) +<-l^-$- +<-l^=$= +<-l^_$_ +<-l^+$+ +<-l^.$. +<-l^?$? +<-l^{$} +<-l^\[$] +<-l^<$> +<-l^|$| +<-l^:$: +<-l^'$' +<-l^"$" +# The rest of two-digit suffix stuff, less common numbers... +<-l$[63-5]$[0-9] +<-(?ac$[63-5]$[0-9] +# Some three-digit numbers... +(?a[lc]$0<-$0$7 +(?a[lc]$1<-$1$1 +(?a[lc]$1<-$2$3 +(?a[lc]$2<-$2$2 +(?a[lc]$3<-$3$3 +(?a[lc]$4<-$4$4 +(?a[lc]$5<-$5$5 +(?a[lc]$6<-$6$6 +(?a[lc]$7<-$7$7 +(?a[lc]$8<-$8$8 +(?a[lc]$9<-$9$9 +# Some [birth] years... +l$1<-$9$[7-96-0]>- +l$2<-$0$0>- +l$1$9<-$[7-9]$[0-9] +l$2$0<-$0$[0-9] +l$1$9<-$[6-0]$[9-0] +# Uncomment the following lines if you're really crazy +;# Insert/overstrike some characters... +;!?Ali[1-6][a-z] +;!?Alo[0-7][a-z] +;# Toggle case everywhere... +;lMT[*7]T[*6]T[*5]T[*4]T[*3]T[*2]T[*1]T[*0]Q +;# Very slow stuff... +;l$[1-90]<-$[0-9]$[0-9] +;(?ac$[1-90]<-$[0-9]$[0-9] +;<-l$[a-z]$[a-z] +;<9l^[a-z]^[a-z] +;<-l^[a-z]$[a-z] + +# Wordlist mode rules +[List.Rules:Wordlist] +# Try words as they are +: +# Lowercase every pure alphanumeric word +-c >3!?XlQ +# Capitalize every pure alphanumeric word +-c >2(?a!?XcQ +# Lowercase and pluralize pure alphabetic words +<*>2!?Alp +# Lowercase pure alphabetic words and append '1' +<*>2!?Al$1 +# Capitalize pure alphabetic words and append '1' +-c <*>2!?Ac$1 +# Duplicate reasonably short pure alphabetic words (fred -> fredfred) +<7>1!?Ald +# Lowercase and reverse pure alphabetic words +>3!?AlMrQ +# Prefix pure alphabetic words with '1' +>2!?Al^1 +# Uppercase pure alphanumeric words +-c >2!?XuQ +# Lowercase pure alphabetic words and append a digit or simple punctuation +<*>2!?Al$[2!37954860.?] +# Words containing punctuation, which is then squeezed out, lowercase +/?p@?p>3l +# Words with vowels removed, lowercase +/?v@?v>3l +# Words containing whitespace, which is then squeezed out, lowercase +/?w@?w>3l +# Capitalize and duplicate short pure alphabetic words (fred -> FredFred) +-c <7>1!?Acd +# Capitalize and reverse pure alphabetic words (fred -> derF) +-c <+>2!?Acr +# Reverse and capitalize pure alphabetic words (fred -> Derf) +-c >2!?AMrQc +# Lowercase and reflect pure alphabetic words (fred -> fredderf) +<7>1!?AlMrQrf +# Uppercase the last letter of pure alphabetic words (fred -> freD) +-c <+>2!?AMrQcr +# Prefix pure alphabetic words with '2' or '4' +>2!?Al^[24] +# Capitalize pure alphabetic words and append a digit or simple punctuation +-c <*>2!?Ac$[2!3957468.?0] +# Prefix pure alphabetic words with digits +>2!?Al^[379568] +# Capitalize and pluralize pure alphabetic words of reasonable length +-c <*>2!?Acp +# Lowercase/capitalize pure alphabetic words of reasonable length and convert: +# crack -> cracked, crack -> cracking +<*>2!?Al[PI] +-c <*>2!?Ac[PI] +# Try the second half of split passwords +-s x** +-s-c x**MlQ + +# Incremental modes +[Incremental:All] +File = $JOHN/all.chr +MinLen = 0 +MaxLen = 8 +CharCount = 95 + +[Incremental:Alpha] +File = $JOHN/alpha.chr +MinLen = 1 +MaxLen = 8 +CharCount = 26 + +[Incremental:Digits] +File = $JOHN/digits.chr +MinLen = 1 +MaxLen = 8 +CharCount = 10 + +[Incremental:LanMan] +File = $JOHN/lanman.chr +MinLen = 0 +MaxLen = 7 +CharCount = 69 + +# Some pre-defined word filters +[List.External:Filter_Alpha] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if (c < 'a' || c > 'z') { + word = 0; return; + } +} + +[List.External:Filter_Digits] +void filter() +{ + int i, c; + + i = 0; + while (c = word[i++]) + if (c < '0' || c > '9') { + word = 0; return; + } +} + +[List.External:Filter_LanMan] +void filter() +{ + int i, c; + + word[7] = 0; // Truncate at 7 characters + + i = 0; // Convert to uppercase + while (c = word[i]) { + if (c >= 'a' && c <= 'z') word[i] &= 0xDF; + i++; + } +} + +# A simple cracker for LM hashes +[List.External:LanMan] +int length; // Current length + +void init() +{ + word[0] = 'A' - 1; // Start with "A" + word[length = 1] = 0; +} + +void generate() +{ + int i; + + i = length - 1; // Start from the last character + while (++word[i] > 'Z') // Try to increase it + if (i) // Overflow here, any more positions? + word[i--] = 'A'; // Yes, move to the left, and repeat + else // No + if (length < 7) { + word[i = ++length] = 0; // Switch to the next length + while (i--) + word[i] = 'A'; + return; + } else { + word = 0; return; // We're done + } +} + +void restore() +{ + length = 0; // Calculate the length + while (word[length]) length++; +} + +# Strip 0.5 ("Secure Tool for Recalling Important Passwords") cracker, +# based on analysis done by Thomas Roessler and Ian Goldberg. This will +# crack passwords you may have generated with Strip, other uses of Strip +# are unaffected. +# See http://www.zetetic.net/products.html for information on Strip. +[List.External:Strip] +int minlength, maxlength, mintype, maxtype; +int crack_seed, length, type; +int count, charset[128]; + +void init() +{ + int c; + +/* Password lengths to try; Strip can generate passwords of 4 to 16 + * characters, but traditional crypt(3) hashes are limited to 8. */ + minlength = 8; // 4 + maxlength = 8; // 16 + +/* Password types to try (Numeric, Alpha-Num, Alpha-Num w/ Meta). */ + mintype = 1; // 0 + maxtype = 1; // 2 + + crack_seed = 0x10000; + length = minlength - 1; + type = mintype; + + count = 0; + c = '0'; while (c <= '9') charset[count++] = c++; +} + +void generate() +{ + int seed, random; + int i, c; + + if (crack_seed > 0xffff) { + crack_seed = 0; + + if (++length > maxlength) { + length = minlength; + + if (++type > maxtype) { + word[0] = 0; + return; + } + } + + count = 10; + if (type >= 1) { + c = 'a'; while (c <= 'f') charset[count++] = c++; + c = 'h'; while (c <= 'z') charset[count++] = c++; + c = 'A'; while (c <= 'Z') charset[count++] = c++; + } + if (type == 2) { + charset[count++] = '!'; + c = '#'; while (c <= '&') charset[count++] = c++; + c = '('; while (c <= '/') charset[count++] = c++; + c = '<'; while (c <= '>') charset[count++] = c++; + charset[count++] = '?'; charset[count++] = '@'; + charset[count++] = '['; charset[count++] = ']'; + charset[count++] = '^'; charset[count++] = '_'; + c = '{'; while (c <= '~') charset[count++] = c++; + } + } + + seed = (crack_seed++ << 16 >> 16) * 22695477 + 1; + + i = 0; + while (i < length) { + random = ((seed = seed * 22695477 + 1) >> 16) & 0x7fff; + word[i++] = charset[random % count]; + } + + word[i] = 0; +} + +# Useful external mode example +[List.External:Double] +/* + * This cracking mode tries all the possible duplicated lowercase alphabetic + * "words" of up to 8 characters long. Since word halves are the same, it + * only has to try about 500,000 words. + */ + +/* Global variables: current length and word */ +int length, current[9]; + +/* Called at startup to initialize the global variables */ +void init() +{ + int i; + + i = length = 2; // Start with 4 character long words + while (i--) current[i] = 'a'; // Set our half-word to "aa" +} + +/* Generates a new word */ +void generate() +{ + int i; + +/* Export last generated word, duplicating it at the same time; here "word" + * is a pre-defined external variable. */ + word[(i = length) << 1] = 0; + while (i--) word[length + i] = word[i] = current[i]; + +/* Generate a new word */ + i = length - 1; // Start from the last character + while (++current[i] > 'z') // Try to increase it + if (i) // Overflow here, any more positions? + current[i--] = 'a'; // Yes, move to the left, and repeat + else { // No + current = 0; // Request a length switch + break; // Break out of the loop + } + +/* Switch to the next length, unless we were generating 8 character long + * words already. */ + if (!current && length < 4) { + i = ++length; + while (i--) current[i] = 'a'; + } +} + +/* Called when restoring an interrupted session */ +void restore() +{ + int i; + +/* Import the word back */ + i = 0; + while (current[i] = word[i]) i++; + +/* ...and calculate the half-word length */ + length = i >> 1; +} + +# Simple parallel processing example +[List.External:Parallel] +/* + * This word filter makes John process some of the words only, for running + * multiple instances on different CPUs. It can be used with any cracking + * mode except for "single crack". Note: this is not a good solution, but + * is just an example of what can be done with word filters. + */ + +int node, total; // This node's number, and node count +int number; // Current word number + +void init() +{ + node = 1; total = 2; // Node 1 of 2, change as appropriate + number = node - 1; // Speedup the filter a bit +} + +void filter() +{ + if (number++ % total) // Word for a different node? + word = 0; // Yes, skip it +} diff -ruN john-1.6/src/AFS_fmt.c john-1.6.34/src/AFS_fmt.c --- john-1.6/src/AFS_fmt.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/AFS_fmt.c 2001-06-16 08:08:33.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include @@ -90,7 +90,7 @@ } AFS_long_KS; static DES_binary AFS_long_IV_binary; -static void init() +static void init(void) { ARCH_WORD_32 block[2]; #if !ARCH_LITTLE_ENDIAN @@ -121,12 +121,12 @@ if (strncmp(ciphertext, "$K4$", 4)) return 0; - for (pos = &ciphertext[4]; atoi16[(ARCH_INDEX)*pos] != 0x7F; pos++); + for (pos = &ciphertext[4]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); if (*pos != ',' || pos - ciphertext != CIPHERTEXT_LENGTH) return 0; for (index = 0; index < 16; index += 2) { - value = (int)atoi16[(ARCH_INDEX)ciphertext[index + 4]] << 4; - value |= atoi16[(ARCH_INDEX)ciphertext[index + 5]]; + value = (int)atoi16[ARCH_INDEX(ciphertext[index + 4])] << 4; + value |= atoi16[ARCH_INDEX(ciphertext[index + 5])]; count = 0; if (value) @@ -153,8 +153,8 @@ known_long = 0; for (index = 0; index < 16; index += 2) { - value = (int)atoi16[(ARCH_INDEX)ciphertext[index + 4]] << 4; - value |= atoi16[(ARCH_INDEX)ciphertext[index + 5]]; + value = (int)atoi16[ARCH_INDEX(ciphertext[index + 4])] << 4; + value |= atoi16[ARCH_INDEX(ciphertext[index + 5])]; out[index >> 3] |= (value | 1) << ((index << 2) & 0x18); @@ -458,6 +458,7 @@ set_salt, set_key, get_key, + fmt_default_clear_keys, crypt_all, { get_hash_0, diff -ruN john-1.6/src/alpha.h john-1.6.34/src/alpha.h --- john-1.6/src/alpha.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/alpha.h 2000-05-08 09:05:05.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* @@ -10,15 +10,15 @@ #ifndef _JOHN_ARCH_H #define _JOHN_ARCH_H -#define ARCH_GENERIC 0 #define ARCH_WORD long #define ARCH_SIZE 8 #define ARCH_BITS 64 +#define ARCH_BITS_LOG 6 #define ARCH_BITS_STR "64" #define ARCH_LITTLE_ENDIAN 1 #define ARCH_INT_GT_32 0 #define ARCH_ALLOWS_UNALIGNED 0 -#define ARCH_INDEX unsigned long +#define ARCH_INDEX(x) ((unsigned long)(unsigned char)(x)) #define OS_TIMER 1 #define OS_FLOCK 1 @@ -32,9 +32,13 @@ #define DES_SCALE 1 #define DES_EXTB 1 #define DES_COPY 0 +#define DES_BS_ASM 0 #define DES_BS 1 +#define DES_BS_VECTOR 0 +#define DES_BS_EXPAND 1 #define MD5_ASM 0 +#define MD5_X2 1 #define MD5_IMM 0 #define BF_ASM 0 diff -ruN john-1.6/src/alpha.S john-1.6.34/src/alpha.S --- john-1.6/src/alpha.S 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/alpha.S 1999-09-22 05:25:30.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ /* @@ -12,8 +12,7 @@ * affect EV4. * * In reality, bitslice DES turned out to be faster almost everywhere, so - * these routines are now only used for BSDI setkey(), AFS and NT LM hash - * by default. + * these routines are now only used for BSDI setkey() and AFS by default. * * The following things were kept in mind while coding: * diff -ruN john-1.6/src/bench.c john-1.6.34/src/bench.c --- john-1.6/src/bench.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/bench.c 2001-07-26 16:55:13.000000000 +0200 @@ -1,8 +1,16 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ +#ifdef __ultrix__ +#define __POSIX +#define _POSIX_SOURCE +#endif + +#ifdef _SCO_C_DIALECT +#include +#endif #include #include #include @@ -20,7 +28,7 @@ #include "formats.h" #include "bench.h" -static int bench_running; +static volatile int bench_running; static void bench_handle_timer(int signum) { @@ -28,18 +36,20 @@ } static void bench_set_keys(struct fmt_main *format, - struct fmt_tests **current, int cond) + struct fmt_tests *current, int cond) { char *plaintext; int index, length; + format->methods.clear_keys(); + length = format->params.benchmark_length; for (index = 0; index < format->params.max_keys_per_crypt; index++) { do { - if (!(*current)->ciphertext) - *current = format->params.tests; - plaintext = (*current)->plaintext; - (*current)++; + if (!current->ciphertext) + current = format->params.tests; + plaintext = current->plaintext; + current++; if (cond > 0) { if ((int)strlen(plaintext) > length) break; @@ -54,9 +64,13 @@ } } -int benchmark_format(struct fmt_main *format, int salts, +char *benchmark_format(struct fmt_main *format, int salts, struct bench_results *results) { + static void *binary = NULL; + static int binary_size = 0; + static char s_error[64]; + char *where; struct fmt_tests *current; int cond; #if OS_TIMER @@ -67,10 +81,19 @@ unsigned ARCH_WORD count; char *ciphertext; void *salt, *two_salts[2]; - int index; + int index, max; - if (!(current = format->params.tests)) return 1; - if (fmt_self_test(format)) return 1; + if (!(current = format->params.tests)) return "FAILED (no data)"; + if ((where = fmt_self_test(format))) { + sprintf(s_error, "FAILED (%s)", where); + return s_error; + } + + if (format->params.binary_size > binary_size) { + binary_size = format->params.binary_size; + binary = mem_alloc_tiny(binary_size, MEM_ALIGN_WORD); + memset(binary, 0x55, binary_size); + } for (index = 0; index < 2; index++) { two_salts[index] = mem_alloc(format->params.salt_size); @@ -89,7 +112,7 @@ } else cond = 0; - bench_set_keys(format, ¤t, cond); + bench_set_keys(format, current, cond); #if OS_TIMER memset(&it, 0, sizeof(it)); @@ -111,14 +134,18 @@ count = 0; index = salts; + max = format->params.max_keys_per_crypt; do { if (!--index) { index = salts; - bench_set_keys(format, ¤t, cond); + if (!(++current)->ciphertext) + current = format->params.tests; + bench_set_keys(format, current, cond); } if (salts > 1) format->methods.set_salt(two_salts[index & 1]); - format->methods.crypt_all(format->params.max_keys_per_crypt); + format->methods.crypt_all(max); + format->methods.cmp_all(binary, max); count++; #if !OS_TIMER @@ -137,7 +164,7 @@ for (index = 0; index < 2; index++) mem_free(&two_salts[index]); - return event_abort ? -1 : 0; + return event_abort ? "" : NULL; } void benchmark_cps(unsigned ARCH_WORD count, clock_t time, char *buffer) @@ -150,13 +177,12 @@ sprintf(buffer, cps_hi < 100 ? "%lu.%lu" : "%lu", cps_hi, cps_lo); } -void benchmark_all() +void benchmark_all(void) { struct fmt_main *format; - char *msg_1, *msg_m; + char *result, *msg_1, *msg_m; struct bench_results results_1, results_m; char s_real[64], s_virtual[64]; - int result; if ((format = fmt_list)) do { @@ -182,15 +208,16 @@ msg_1 = "Long"; } - if ((result = benchmark_format(format, BENCHMARK_MANY, + if ((result = benchmark_format(format, + format->params.salt_size ? BENCHMARK_MANY : 1, &results_m))) { - if (result > 0) puts("FAILED"); else putchar('\n'); + puts(result); continue; } if (msg_1) if ((result = benchmark_format(format, 1, &results_1))) { - if (result > 0) puts("FAILED"); else putchar('\n'); + puts(result); continue; } @@ -198,12 +225,11 @@ benchmark_cps(results_m.count, results_m.real, s_real); benchmark_cps(results_m.count, results_m.virtual, s_virtual); - printf("%s:\t%s c/s" -#if !defined(__DJGPP__) && !defined(__CYGWIN32__) - " real, %s c/s virtual\n", +#if !defined(__DJGPP__) && !defined(__CYGWIN32__) && !defined(__BEOS__) + printf("%s:\t%s c/s real, %s c/s virtual\n", msg_m, s_real, s_virtual); #else - "\n", + printf("%s:\t%s c/s\n", msg_m, s_real); #endif @@ -214,12 +240,11 @@ benchmark_cps(results_1.count, results_1.real, s_real); benchmark_cps(results_1.count, results_1.virtual, s_virtual); - printf("%s:\t%s c/s" -#if !defined(__DJGPP__) && !defined(__CYGWIN32__) - " real, %s c/s virtual\n\n", +#if !defined(__DJGPP__) && !defined(__CYGWIN32__) && !defined(__BEOS__) + printf("%s:\t%s c/s real, %s c/s virtual\n\n", msg_1, s_real, s_virtual); #else - "\n\n", + printf("%s:\t%s c/s\n\n", msg_1, s_real); #endif } while ((format = format->next) && !event_abort); diff -ruN john-1.6/src/bench.h john-1.6.34/src/bench.h --- john-1.6/src/bench.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/bench.h 1999-10-16 15:52:31.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ /* @@ -27,11 +27,11 @@ }; /* - * Benchmarks the supplied cracking algorithm. Returns zero on success, a - * positive value if the self test fails or there's no self test for this - * algorithm, or a negative value if aborted. + * Benchmarks the supplied cracking algorithm. Returns NULL on success, + * an error message if the self test fails or there're no test vectors + * for this algorithm, or an empty string if aborted. */ -extern int benchmark_format(struct fmt_main *format, int salts, +extern char *benchmark_format(struct fmt_main *format, int salts, struct bench_results *results); /* @@ -44,6 +44,6 @@ * Benchmarks all the registered cracking algorithms and prints the results * to stdout. */ -extern void benchmark_all(); +extern void benchmark_all(void); #endif diff -ruN john-1.6/src/best.c john-1.6.34/src/best.c --- john-1.6/src/best.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/best.c 1999-06-08 05:33:20.000000000 +0200 @@ -1,12 +1,20 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ /* * Benchmark to detect the best algorithm for a particular architecture. */ +#ifdef __ultrix__ +#define __POSIX +#define _POSIX_SOURCE +#endif + +#ifdef _SCO_C_DIALECT +#include +#endif #include #include diff -ruN john-1.6/src/best.sh john-1.6.34/src/best.sh --- john-1.6/src/best.sh 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/best.sh 2000-06-25 07:07:28.000000000 +0200 @@ -1,7 +1,7 @@ #!/bin/sh # # This file is part of John the Ripper password cracker, -# Copyright (c) 1996-98 by Solar Designer +# Copyright (c) 1996-2000 by Solar Designer # [ $# -eq 4 ] || exit 1 @@ -11,13 +11,13 @@ MD5_DEPEND=$3 BF_DEPEND=$4 -# Detect the best standard DES algorithm +# Detect the best non-bitslice DES algorithm MAX=0 DES_BEST=1 for MODE in 1 2 3 4 5; do - if ./detect $MODE 1 0 0 0 > arch.h; then + if ./detect $MODE 1 0 0 0 0 > arch.h; then rm -f $DES_DEPEND bench echo "Compiling: DES benchmark (code version #$MODE)" $MAKE bench || exit 1 @@ -29,7 +29,7 @@ fi done -./detect $DES_BEST 0 0 0 0 > arch.h +./detect $DES_BEST 0 0 0 0 0 > arch.h rm -f $DES_DEPEND bench echo "Compiling: DES benchmark (code version #$DES_BEST, no key copying)" @@ -43,7 +43,7 @@ # Check if bitslice DES is faster -./detect $DES_BEST $DES_COPY 1 0 0 > arch.h +./detect $DES_BEST $DES_COPY 1 0 0 0 > arch.h rm -f $DES_DEPEND bench echo "Compiling: DES benchmark (bitslice)" @@ -59,7 +59,19 @@ MAX=`./bench 2` || exit 1 -./detect $DES_BEST $DES_COPY $DES_BS 1 0 > arch.h +./detect $DES_BEST $DES_COPY $DES_BS 1 0 0 > arch.h +rm -f $MD5_DEPEND bench + +echo "Compiling: MD5 benchmark (two hashes at a time)" +$MAKE bench || exit 1 +RES=`./bench 2` || exit 1 +if [ $RES -gt $MAX ]; then + MD5_X2=1 +else + MD5_X2=0 +fi + +./detect $DES_BEST $DES_COPY $DES_BS $MD5_X2 1 0 > arch.h rm -f $MD5_DEPEND bench echo "Compiling: MD5 benchmark (immediate values)" @@ -75,7 +87,7 @@ MAX=`./bench 3` || exit 1 -./detect $DES_BEST $DES_COPY $DES_BS $MD5_IMM 1 > arch.h +./detect $DES_BEST $DES_COPY $DES_BS $MD5_X2 $MD5_IMM 1 > arch.h rm -f $BF_DEPEND bench echo "Compiling: Blowfish benchmark (scale)" @@ -90,5 +102,5 @@ # Produce generic.h, make sure everything is rebuilt with detected options, # and do some cleanup -./detect $DES_BEST $DES_COPY $DES_BS $MD5_IMM $BF_SCALE > generic.h +./detect $DES_BEST $DES_COPY $DES_BS $MD5_X2 $MD5_IMM $BF_SCALE > generic.h rm -f $DES_DEPEND $MD5_DEPEND $BF_DEPEND bench detect best.o detect.o arch.h diff -ruN john-1.6/src/BF_fmt.c john-1.6.34/src/BF_fmt.c --- john-1.6/src/BF_fmt.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/BF_fmt.c 2001-06-16 08:08:58.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include @@ -59,9 +59,12 @@ if (ciphertext[6] != '$') return 0; - for (pos = &ciphertext[7]; atoi64[(ARCH_INDEX)*pos] != 0x7F; pos++); + for (pos = &ciphertext[7]; atoi64[ARCH_INDEX(*pos)] != 0x7F; pos++); if (*pos || pos - ciphertext != CIPHERTEXT_LENGTH) return 0; + if (BF_atoi64[ARCH_INDEX(*(pos - 1))] & 3) return 0; + if (BF_atoi64[ARCH_INDEX(ciphertext[28])] & 0xF) return 0; + return 1; } @@ -151,7 +154,7 @@ FMT_CASE | FMT_8_BIT, tests }, { - BF_std_init, + fmt_default_init, valid, fmt_default_split, (void *(*)(char *))BF_std_get_binary, @@ -165,6 +168,7 @@ set_salt, set_key, get_key, + fmt_default_clear_keys, crypt_all, { get_hash_0, diff -ruN john-1.6/src/BF_std.c john-1.6.34/src/BF_std.c --- john-1.6/src/BF_std.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/BF_std.c 2001-04-29 07:06:12.000000000 +0200 @@ -1,29 +1,36 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer + * + * A public domain version of this code, with reentrant and crypt(3) + * interfaces added, but optimizations specific to password cracking + * removed, is available at: + * + * http://www.openwall.com/crypt/ * * This implementation is compatible with OpenBSD bcrypt.c (version 2a) * by Niels Provos , and uses some of his * ideas. The password hashing algorithm was designed by David Mazieres - * . Some of the tricks in BF_ROUND might be inspired by - * Eric Young's Blowfish library (I can't be sure if I would think of - * something if I hadn't seen his code) -- SD. + * . + * + * There's a paper on the algorithm that explains its design decisions: + * + * http://www.usenix.org/events/usenix99/provos.html + * + * Some of the tricks in BF_ROUND might be inspired by Eric Young's + * Blowfish library (I can't be sure if I would think of something if I + * hadn't seen his code). */ #include #include #include "arch.h" +#include "common.h" #include "BF_std.h" BF_binary BF_out; -/* - * Magic IV for 64 Blowfish encryptions that we do at the end. - */ -static char BF_magic_b[24] = "OrpheanBeholderScryDoubt"; -static BF_binary BF_magic_w; - /* Number of Blowfish rounds, this is also hardcoded into a few places */ #define BF_N 16 @@ -34,21 +41,30 @@ BF_key P; }; -#if !BF_SCALE -#define BF_INDEX(S, i) \ - (*((BF_word *)(((unsigned char *)S) + (i)))) -#endif - /* Current Blowfish context */ #if BF_ASM extern #else static #endif -struct BF_ctx BF_current; +struct BF_ctx CC_CACHE_ALIGN BF_current; /* Current Blowfish key */ -static BF_key BF_exp_key, BF_init_key; +static BF_key CC_CACHE_ALIGN BF_exp_key; +#if defined(__linux__) && defined(__sparc__) +static BF_key BF_init_key; +#else +static BF_key CC_CACHE_ALIGN BF_init_key; +#endif + +/* + * Magic IV for 64 Blowfish encryptions that we do at the end. + * The string is "OrpheanBeholderScryDoubt" on big-endian. + */ +static BF_word BF_magic_w[6] = { + 0x4F727068, 0x65616E42, 0x65686F6C, + 0x64657253, 0x63727944, 0x6F756274 +}; /* * P-box and S-box tables initialized with digits of Pi. @@ -325,6 +341,20 @@ } }; +/* + * Same charset, different order -- can't use the common.c table here. + */ +unsigned char BF_atoi64[0x80] = { + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64, + 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64, + 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64 +}; + #if ARCH_LITTLE_ENDIAN static void BF_swap(BF_word *x, int count) @@ -344,12 +374,6 @@ #endif -void BF_std_init() -{ - memcpy(BF_magic_w, BF_magic_b, sizeof(BF_magic_w)); - BF_swap(BF_magic_w, 6); -} - #if BF_SCALE /* Architectures which can shift addresses left by 2 bits with no extra cost */ #define BF_ROUND(L, R, N) \ @@ -369,6 +393,8 @@ R ^= tmp3; #else /* Architectures with no complicated addressing modes supported */ +#define BF_INDEX(S, i) \ + (*((BF_word *)(((unsigned char *)S) + (i)))) #define BF_ROUND(L, R, N) \ tmp1 = L & 0xFF; \ tmp1 <<= 2; \ @@ -415,7 +441,7 @@ #if BF_ASM -extern void BF_body(); +extern void (*BF_body)(void); #else @@ -556,7 +582,7 @@ BF_out[1] = R; } -void BF_std_crypt_exact() +void BF_std_crypt_exact(void) { BF_word L, R; BF_word tmp1, tmp2, tmp3, tmp4; @@ -580,60 +606,37 @@ } /* - * Standard charset, but non-standard order, so we can't use the table - * generated in common.c here. - */ -static unsigned char BF_atoi64[0x80] = -{ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, - 0, 0, 0, 0, 0, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 0, 0, 0, 0, 0, 0, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 0, 0, 0, 0, 0 -}; - -/* * I'm not doing any error checking in the routines below since the * ciphertext should have already been checked to be fmt_BF.valid(). */ -static void BF_decode(void *buffer, int length, char *data) +static void BF_decode(BF_word *dst, char *src, int size) { - unsigned char *dptr = (unsigned char *)buffer; - unsigned char *end = (unsigned char *)buffer + length; - char *sptr = data; - unsigned char c1, c2, c3, c4; - - while (dptr < end) { - c1 = BF_atoi64[(ARCH_INDEX)*sptr++]; - c2 = BF_atoi64[(ARCH_INDEX)*sptr++]; + unsigned char *dptr = (unsigned char *)dst; + unsigned char *end = dptr + size; + unsigned char *sptr = (unsigned char *)src; + unsigned int c1, c2, c3, c4; + do { + c1 = BF_atoi64[ARCH_INDEX(*sptr++)]; + c2 = BF_atoi64[ARCH_INDEX(*sptr++)]; *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4); if (dptr >= end) break; - c3 = BF_atoi64[(ARCH_INDEX)*sptr++]; - + c3 = BF_atoi64[ARCH_INDEX(*sptr++)]; *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2); if (dptr >= end) break; - c4 = BF_atoi64[(ARCH_INDEX)*sptr++]; + c4 = BF_atoi64[ARCH_INDEX(*sptr++)]; *dptr++ = ((c3 & 0x03) << 6) | c4; - } + } while (dptr < end); } BF_word *BF_std_get_salt(char *ciphertext) { static BF_salt salt; - BF_decode(salt, 16, &ciphertext[7]); + BF_decode(salt, &ciphertext[7], 16); BF_swap(salt, 4); salt[4] = (BF_word)1 << atoi(&ciphertext[4]); @@ -645,9 +648,9 @@ { static BF_binary binary; - BF_decode(binary, 23, &ciphertext[29]); + binary[5] = 0; + BF_decode(binary, &ciphertext[29], 23); BF_swap(binary, 6); - binary[5] &= ~(BF_word)0xFF; return binary; diff -ruN john-1.6/src/BF_std.h john-1.6.34/src/BF_std.h --- john-1.6/src/BF_std.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/BF_std.h 2001-04-29 06:29:40.000000000 +0200 @@ -1,10 +1,10 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* - * Standard OpenBSD Blowfish implementation. + * OpenBSD-style Blowfish-based password hash implementation. */ #ifndef _JOHN_BF_STD_H @@ -30,12 +30,12 @@ */ extern BF_binary BF_out; -#define BF_ALGORITHM_NAME "32/" ARCH_BITS_STR - /* - * Initializes the internal structures. + * ASCII to binary conversion table, for use in BF_fmt.valid(). */ -extern void BF_std_init(); +extern unsigned char BF_atoi64[0x80]; + +#define BF_ALGORITHM_NAME "32/" ARCH_BITS_STR /* * Sets a key for BF_std_crypt(). @@ -50,7 +50,7 @@ /* * Calculates the rest of BF_out, for exact comparison. */ -extern void BF_std_crypt_exact(); +extern void BF_std_crypt_exact(void); /* * Returns the salt for BF_std_crypt(). diff -ruN john-1.6/src/BSDI_fmt.c john-1.6.34/src/BSDI_fmt.c --- john-1.6/src/BSDI_fmt.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/BSDI_fmt.c 2001-06-16 09:32:21.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include @@ -31,24 +31,22 @@ {"_J9..SDizh.vll5VED9g", "ab1234567"}, {"_J9..SDizRjWQ/zePPHc", "cr1234567"}, {"_J9..SDizxmRI1GjnQuE", "zxyDPWgydbQjgq"}, + {"_K9..SaltNrQgIYUAeoY", "726 even"}, {"_J9..SDSD5YGyRCr4W4c", ""}, {NULL} }; #if DES_BS -#include "memory.h" #include "DES_bs.h" #define ALGORITHM_NAME DES_BS_ALGORITHM_NAME -#define BINARY_BITS 16 - -#define BINARY_SIZE (BINARY_BITS * ARCH_SIZE) +#define BINARY_SIZE ARCH_SIZE #define SALT_SIZE (ARCH_SIZE * 2) -#define MIN_KEYS_PER_CRYPT ARCH_BITS -#define MAX_KEYS_PER_CRYPT ARCH_BITS +#define MIN_KEYS_PER_CRYPT DES_BS_DEPTH +#define MAX_KEYS_PER_CRYPT DES_BS_DEPTH #else @@ -64,12 +62,10 @@ #endif -int saved_count; +static int saved_count; static struct { -#if DES_BS - char final[8]; -#else +#if !DES_BS union { double dummy; struct { @@ -81,26 +77,12 @@ char key[PLAINTEXT_LENGTH]; } buffer[MAX_KEYS_PER_CRYPT]; -#if DES_BS - -struct fmt_main fmt_BSDI; -static int binary_bits = BINARY_BITS; -static int keys_changed; - -#endif - -static void init() +static void init(void) { DES_std_init(); #if DES_BS - if (mem_saving_level > 1) { - DES_bs_mem_saving = 1; - binary_bits = 32; - fmt_BSDI.params.binary_size = ARCH_SIZE; - } - - DES_bs_init(); + DES_bs_init(0); DES_std_set_salt(0); DES_count = 1; @@ -118,9 +100,11 @@ for (pos = &ciphertext[1]; pos < &ciphertext[9]; pos++) if (!*pos) return 0; - for (pos = &ciphertext[9]; atoi64[(ARCH_INDEX)*pos] != 0x7F; pos++); + for (pos = &ciphertext[9]; atoi64[ARCH_INDEX(*pos)] != 0x7F; pos++); if (*pos || pos - ciphertext != CIPHERTEXT_LENGTH) return 0; + if (atoi64[ARCH_INDEX(*(pos - 1))] & 3) return 0; + return 1; } @@ -142,17 +126,17 @@ static int binary_hash_0(void *binary) { - return DES_bs_binary_hash((ARCH_WORD *)binary, 4); + return *(ARCH_WORD *)binary & 0xF; } static int binary_hash_1(void *binary) { - return DES_bs_binary_hash((ARCH_WORD *)binary, 8); + return *(ARCH_WORD *)binary & 0xFF; } static int binary_hash_2(void *binary) { - return DES_bs_binary_hash((ARCH_WORD *)binary, 12); + return *(ARCH_WORD *)binary & 0xFFF; } static int get_hash_0(int index) @@ -283,8 +267,7 @@ } #if DES_BS - strnfcpy(buffer[index].final, final, 8); - keys_changed = 1; + DES_bs_set_key(final, index); #else memcpy(buffer[index].aligned.data.KS, DES_KS_current, sizeof(DES_KS)); #endif @@ -302,26 +285,18 @@ static void crypt_all(int count) { - int index; - - if (keys_changed) { - DES_bs_clear_keys(); - for (index = 0; index < count; index++) - DES_bs_set_key(buffer[index].final, index); - keys_changed = 0; - } - + DES_bs_expand_keys(); DES_bs_crypt(saved_count); } static int cmp_all(void *binary, int count) { - return DES_bs_cmp_all((ARCH_WORD *)binary, binary_bits); + return DES_bs_cmp_all((ARCH_WORD *)binary); } static int cmp_one(void *binary, int index) { - return DES_bs_cmp_one((ARCH_WORD *)binary, binary_bits, index); + return DES_bs_cmp_one((ARCH_WORD *)binary, 32, index); } static int cmp_exact(char *source, int index) @@ -393,7 +368,11 @@ SALT_SIZE, MIN_KEYS_PER_CRYPT, MAX_KEYS_PER_CRYPT, +#if DES_BS + FMT_CASE | FMT_BS, +#else FMT_CASE, +#endif tests }, { init, @@ -415,6 +394,11 @@ set_salt, set_key, get_key, +#if DES_BS + DES_bs_clear_keys, +#else + fmt_default_clear_keys, +#endif crypt_all, { get_hash_0, diff -ruN john-1.6/src/charset.c john-1.6.34/src/charset.c --- john-1.6/src/charset.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/charset.c 1999-04-14 12:50:36.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ #include @@ -123,7 +123,7 @@ current = plaintexts; do { for (ptr = (unsigned char *)current->data; *ptr; ptr++) - (*chars)[0][0][(ARCH_INDEX)(*ptr - CHARSET_MIN)]++; + (*chars)[0][0][ARCH_INDEX(*ptr - CHARSET_MIN)]++; } while ((current = current->next)); count = 0; @@ -159,15 +159,15 @@ (*chars) [CHARSET_SIZE] [CHARSET_SIZE] - [(ARCH_INDEX)(ptr[pos] - CHARSET_MIN)]++; + [ARCH_INDEX(ptr[pos] - CHARSET_MIN)]++; if (pos) (*chars) [CHARSET_SIZE] - [(ARCH_INDEX)(ptr[pos - 1] - CHARSET_MIN)] - [(ARCH_INDEX)(ptr[pos] - CHARSET_MIN)]++; + [ARCH_INDEX(ptr[pos - 1] - CHARSET_MIN)] + [ARCH_INDEX(ptr[pos] - CHARSET_MIN)]++; if (pos > 1) (*chars) - [(ARCH_INDEX)(ptr[pos - 2] - CHARSET_MIN)] - [(ARCH_INDEX)(ptr[pos - 1] - CHARSET_MIN)] - [(ARCH_INDEX)(ptr[pos] - CHARSET_MIN)]++; + [ARCH_INDEX(ptr[pos - 2] - CHARSET_MIN)] + [ARCH_INDEX(ptr[pos - 1] - CHARSET_MIN)] + [ARCH_INDEX(ptr[pos] - CHARSET_MIN)]++; } while ((current = current->next)); for (i = (pos > 1 ? 0 : CHARSET_SIZE); i <= CHARSET_SIZE; i++) diff -ruN john-1.6/src/charset.h john-1.6.34/src/charset.h --- john-1.6/src/charset.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/charset.h 2001-02-16 06:52:01.000000000 +0100 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -11,6 +11,7 @@ #define _JOHN_CHARSET_H #include "params.h" +#include "common.h" #include "loader.h" /* @@ -26,19 +27,19 @@ */ struct charset_header { /* CHARSET_VERSION */ - char version[4]; + char version[4] CC_PACKED; /* CHARSET_MIN, CHARSET_MAX */ - unsigned char min, max; + unsigned char min, max CC_PACKED; /* CHARSET_LENGTH */ - unsigned char length; + unsigned char length CC_PACKED; /* Number of different characters, up to (max - min + 1) */ - unsigned char count; + unsigned char count CC_PACKED; -/* File offsets for each length, 32 bit little endian */ - unsigned char offsets[CHARSET_LENGTH][4]; +/* File offsets for each length, 32-bit little endian */ + unsigned char offsets[CHARSET_LENGTH][4] CC_PACKED; /* * Cracking order. @@ -51,13 +52,9 @@ * up to CHARSET_SIZE characters large. */ unsigned char order - [CHARSET_LENGTH * (CHARSET_LENGTH + 1) / 2 * CHARSET_SIZE * 3]; -} -#if ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 2) - __attribute__ ((packed)); -#else - ; -#endif + [CHARSET_LENGTH * (CHARSET_LENGTH + 1) / 2 * CHARSET_SIZE * 3] + CC_PACKED; +} CC_PACKED; /* * Reads a charset file header. diff -ruN john-1.6/src/common.c john-1.6.34/src/common.c --- john-1.6/src/common.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/common.c 1999-09-22 05:48:17.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ #include @@ -18,7 +18,7 @@ static int initialized = 0; -void common_init() +void common_init(void) { char *pos; @@ -26,11 +26,11 @@ memset(atoi64, 0x7F, sizeof(atoi64)); for (pos = itoa64; pos <= &itoa64[63]; pos++) - atoi64[(ARCH_INDEX)*pos] = pos - itoa64; + atoi64[ARCH_INDEX(*pos)] = pos - itoa64; memset(atoi16, 0x7F, sizeof(atoi16)); for (pos = itoa16; pos <= &itoa16[15]; pos++) - atoi16[(ARCH_INDEX)*pos] = pos - itoa16; + atoi16[ARCH_INDEX(*pos)] = pos - itoa16; atoi16['A'] = atoi16['a']; atoi16['B'] = atoi16['b']; diff -ruN john-1.6/src/common.h john-1.6.34/src/common.h --- john-1.6/src/common.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/common.h 1999-09-22 05:39:10.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ /* @@ -11,6 +11,7 @@ #define _JOHN_COMMON_H #include "arch.h" +#include "memory.h" #if ARCH_INT_GT_32 typedef unsigned short ARCH_WORD_32; @@ -18,6 +19,19 @@ typedef unsigned int ARCH_WORD_32; #endif +#if ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 2) +#define CC_CACHE_ALIGN \ + __attribute__ ((aligned (MEM_ALIGN_CACHE))) +#else +#define CC_CACHE_ALIGN /* nothing */ +#endif + +#if ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 2) +#define CC_PACKED __attribute__ ((packed)) +#else +#define CC_PACKED /* nothing */ +#endif + /* * ASCII <-> binary conversion tables. */ @@ -27,6 +41,6 @@ /* * Initializes the tables. */ -extern void common_init(); +extern void common_init(void); #endif diff -ruN john-1.6/src/compiler.c john-1.6.34/src/compiler.c --- john-1.6/src/compiler.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/compiler.c 2000-08-26 05:50:54.000000000 +0200 @@ -1,11 +1,13 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ #include +#include #include #include +#include #include "arch.h" #include "params.h" @@ -21,6 +23,7 @@ "Expression is too complex", "Invalid array size", "Data section is too large", + "Integer constant out of range", "Duplicate identifier", "Keyword is used as an identifier", "Not in a function", @@ -34,7 +37,7 @@ int c_errno; union c_insn { - void (*op)(); + void (*op)(void); c_int *mem; c_int imm; union c_insn *pc; @@ -67,12 +70,12 @@ static char c_isident[0x100]; #define c_isstart(c) \ - (c_isident[(ARCH_INDEX)(c)] && ((c) < '0' || (c) > '9')) + (c_isident[ARCH_INDEX(c)] && ((c) < '0' || (c) > '9')) static int c_EOF; -static int (*c_ext_getchar)(); -static void (*c_ext_rewind)(); +static int (*c_ext_getchar)(void); +static void (*c_ext_rewind)(void); static char *c_reserved[] = { "void", @@ -98,7 +101,7 @@ int dir; int class; char *name; - void (*op)(); + void (*op)(void); }; #ifdef __GNUC__ @@ -107,7 +110,7 @@ static struct c_op c_ops[38]; #endif -static void c_init() +static void c_init(void) { int c; @@ -141,7 +144,7 @@ c_unget_buffer[c_unget_count++] = c; } -static char c_buffer_getchar() +static char c_buffer_getchar(void) { int c; @@ -195,12 +198,12 @@ return c; } -static char *c_gettoken() +static char *c_gettoken(void) { static char token[C_TOKEN_SIZE]; int pos = 0; - while (c_isident[(ARCH_INDEX)(token[pos++] = c_getchar(0))]) + while (c_isident[ARCH_INDEX(token[pos++] = c_getchar(0))]) if (pos >= C_TOKEN_SIZE) { c_errno = C_ERROR_TOOLONG; break; @@ -215,7 +218,8 @@ static int c_getint(char *token) { int value; - char *format; + long l_value; + char *error; if (token[0] == '\'') { if ((value = c_getchar(1)) == '\'') @@ -224,20 +228,20 @@ if (value == '\\') value = c_getchar(1); if (c_getchar(1) != '\'') c_errno = C_ERROR_UNEXPECTED; } else { - if (token[0] != '0') format = "%d"; else - if (token[1] != 'x') format = "%o"; else { - format = "%x"; - token += 2; - } - - if (sscanf((char *)token, format, &value) != 1) + errno = 0; + l_value = strtol(token, &error, 0); + value = (int)l_value; + if (errno == ERANGE || (long)value != l_value) + c_errno = C_ERROR_RANGE; + else + if (!*token || *error || errno) c_errno = C_ERROR_UNEXPECTED; } return value; } -static char c_skip_space() +static char c_skip_space(void) { char c; @@ -337,19 +341,20 @@ } } -static void (*c_op_return)(); -static void (*c_op_bz)(); -static void (*c_op_ba)(); -static void (*c_op_push_imm)(); -static void (*c_op_push_mem)(); -static void (*c_op_pop)(); - -static void (*c_op_push_imm_imm)(); -static void (*c_op_push_imm_mem)(); -static void (*c_op_push_mem_imm)(); -static void (*c_op_push_mem_mem)(); +static void (*c_op_return)(void); +static void (*c_op_bz)(void); +static void (*c_op_ba)(void); +static void (*c_op_push_imm)(void); +static void (*c_op_push_mem)(void); +static void (*c_op_pop)(void); + +static void (*c_op_push_imm_imm)(void); +static void (*c_op_push_imm_mem)(void); +static void (*c_op_push_mem_imm)(void); +static void (*c_op_push_mem_mem)(void); -static void (*c_push(void (*last)(), void (*op)(), union c_insn *value))() +static void (*c_push + (void (*last)(void), void (*op)(void), union c_insn *value))(void) { if (last == c_op_push_imm || last == c_op_push_mem) { if (last == c_op_push_imm) { @@ -454,7 +459,7 @@ int sp = 0; int balance = -1; int left = 0; - void (*last)() = (void (*)())0; + void (*last)(void) = (void (*)(void))0; if (term == ')') stack[sp++] = -1; do { @@ -497,7 +502,7 @@ left = 0; } else if (c != ' ') { - if (c_isident[(ARCH_INDEX)c]) + if (c_isident[ARCH_INDEX(c)]) var = c_find_ident(vars, NULL, token); else var = NULL; @@ -515,7 +520,7 @@ } if ((op = c_find_op(token, left)) < 0) { - if (c_isident[(ARCH_INDEX)c]) + if (c_isident[ARCH_INDEX(c)]) c_errno = C_ERROR_UNKNOWN; else c_errno = C_ERROR_UNEXPECTED; @@ -648,7 +653,7 @@ return c_errno; } -static int c_continue() +static int c_continue(void) { if (!c_loop_start) return c_errno = C_ERROR_NOTINLOOP; @@ -664,7 +669,7 @@ return c_errno; } -static int c_break(char term, struct c_ident *vars) +static int c_break(void) { struct c_fixup *fixup; @@ -737,7 +742,7 @@ } else if (!strcmp(token, "break")) { - if (c_break(term, locals)) break; + if (c_break()) break; } else if (!strcmp(token, "return")) { @@ -761,7 +766,7 @@ static void c_direct(union c_insn *addr); #endif -int c_compile(int (*ext_getchar)(), void (*ext_rewind)(), +int c_compile(int (*ext_getchar)(void), void (*ext_rewind)(void), struct c_ident *externs) { #ifdef __GNUC__ @@ -800,7 +805,7 @@ void c_execute(struct c_ident *fn) { #ifndef __GNUC__ - register void (*op)(); + register void (*op)(void); #endif if (!fn) return; @@ -1127,12 +1132,12 @@ #endif -static void c_f_op_return() +static void c_f_op_return(void) { c_pc = (c_sp -= 2)->pc; } -static void c_f_op_bz() +static void c_f_op_bz(void) { if ((c_sp -= 2)->imm) c_pc++; @@ -1140,36 +1145,36 @@ c_pc = c_pc->pc; } -static void c_f_op_ba() +static void c_f_op_ba(void) { c_pc = c_pc->pc; } -static void c_f_op_push_imm() +static void c_f_op_push_imm(void) { c_sp->imm = (c_pc++)->imm; c_sp += 2; } -static void c_f_op_push_mem() +static void c_f_op_push_mem(void) { (c_sp++)->imm = *c_pc->mem; (c_sp++)->mem = (c_pc++)->mem; } -static void c_f_op_pop() +static void c_f_op_pop(void) { c_sp -= 2; } -static void c_f_op_push_imm_imm() +static void c_f_op_push_imm_imm(void) { c_sp->imm = (c_pc++)->imm; (c_sp + 2)->imm = (c_pc++)->imm; c_sp += 4; } -static void c_f_op_push_imm_mem() +static void c_f_op_push_imm_mem(void) { c_sp->imm = (c_pc++)->imm; (c_sp + 2)->imm = *c_pc->mem; @@ -1177,7 +1182,7 @@ c_sp += 4; } -static void c_f_op_push_mem_imm() +static void c_f_op_push_mem_imm(void) { c_sp->imm = *c_pc->mem; (c_sp + 1)->mem = (c_pc++)->mem; @@ -1185,7 +1190,7 @@ c_sp += 4; } -static void c_f_op_push_mem_mem() +static void c_f_op_push_mem_mem(void) { c_sp->imm = *c_pc->mem; (c_sp + 1)->mem = (c_pc++)->mem; @@ -1194,220 +1199,220 @@ c_sp += 4; } -static void c_op_index() +static void c_op_index(void) { c_sp -= 2; (c_sp - 2)->imm = *((c_sp - 1)->mem += c_sp->imm); } -static void c_op_assign() +static void c_op_assign(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem = c_sp->imm; } -static void c_op_add_a() +static void c_op_add_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem += c_sp->imm; } -static void c_op_sub_a() +static void c_op_sub_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem -= c_sp->imm; } -static void c_op_mul_a() +static void c_op_mul_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem *= c_sp->imm; } -static void c_op_div_a() +static void c_op_div_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem /= c_sp->imm; } -static void c_op_mod_a() +static void c_op_mod_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem %= c_sp->imm; } -static void c_op_or_a() +static void c_op_or_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem |= c_sp->imm; } -static void c_op_xor_a() +static void c_op_xor_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem ^= c_sp->imm; } -static void c_op_and_a() +static void c_op_and_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem &= c_sp->imm; } -static void c_op_shl_a() +static void c_op_shl_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem <<= c_sp->imm; } -static void c_op_shr_a() +static void c_op_shr_a(void) { c_sp -= 2; (c_sp - 2)->imm = *(c_sp - 1)->mem >>= c_sp->imm; } -static void c_op_or_i() +static void c_op_or_i(void) { c_sp -= 2; (c_sp - 2)->imm |= c_sp->imm; } -static void c_op_and_b() +static void c_op_and_b(void) { c_sp -= 2; (c_sp - 2)->imm = (c_sp - 2)->imm && c_sp->imm; } -static void c_op_not_b() +static void c_op_not_b(void) { (c_sp - 2)->imm = !(c_sp - 2)->imm; } -static void c_op_eq() +static void c_op_eq(void) { c_sp -= 2; (c_sp - 2)->imm = (c_sp - 2)->imm == c_sp->imm; } -static void c_op_gt() +static void c_op_gt(void) { c_sp -= 2; (c_sp - 2)->imm = (c_sp - 2)->imm > c_sp->imm; } -static void c_op_lt() +static void c_op_lt(void) { c_sp -= 2; (c_sp - 2)->imm = (c_sp - 2)->imm < c_sp->imm; } -static void c_op_ge() +static void c_op_ge(void) { c_sp -= 2; (c_sp - 2)->imm = (c_sp - 2)->imm >= c_sp->imm; } -static void c_op_le() +static void c_op_le(void) { c_sp -= 2; (c_sp - 2)->imm = (c_sp - 2)->imm <= c_sp->imm; } -static void c_op_xor_i() +static void c_op_xor_i(void) { c_sp -= 2; (c_sp - 2)->imm ^= c_sp->imm; } -static void c_op_and_i() +static void c_op_and_i(void) { c_sp -= 2; (c_sp - 2)->imm &= c_sp->imm; } -static void c_op_shl() +static void c_op_shl(void) { c_sp -= 2; (c_sp - 2)->imm <<= c_sp->imm; } -static void c_op_shr() +static void c_op_shr(void) { c_sp -= 2; (c_sp - 2)->imm >>= c_sp->imm; } -static void c_op_add() +static void c_op_add(void) { c_sp -= 2; (c_sp - 2)->imm += c_sp->imm; } -static void c_op_sub() +static void c_op_sub(void) { c_sp -= 2; (c_sp - 2)->imm -= c_sp->imm; } -static void c_op_mul() +static void c_op_mul(void) { c_sp -= 2; (c_sp - 2)->imm *= c_sp->imm; } -static void c_op_div() +static void c_op_div(void) { c_sp -= 2; (c_sp - 2)->imm /= c_sp->imm; } -static void c_op_mod() +static void c_op_mod(void) { c_sp -= 2; (c_sp - 2)->imm %= c_sp->imm; } -static void c_op_not_i() +static void c_op_not_i(void) { (c_sp - 2)->imm = ~(c_sp - 2)->imm; } -static void c_op_neg() +static void c_op_neg(void) { (c_sp - 2)->imm = -(c_sp - 2)->imm; } -static void c_op_inc_l() +static void c_op_inc_l(void) { *(c_sp - 1)->mem = ++(c_sp - 2)->imm; } -static void c_op_dec_l() +static void c_op_dec_l(void) { *(c_sp - 1)->mem = --(c_sp - 2)->imm; } -static void c_op_inc_r() +static void c_op_inc_r(void) { *(c_sp - 1)->mem = (c_sp - 2)->imm + 1; } -static void c_op_dec_r() +static void c_op_dec_r(void) { *(c_sp - 1)->mem = (c_sp - 2)->imm - 1; } -static void (*c_op_return)() = c_f_op_return; -static void (*c_op_bz)() = c_f_op_bz; -static void (*c_op_ba)() = c_f_op_ba; -static void (*c_op_push_imm)() = c_f_op_push_imm; -static void (*c_op_push_mem)() = c_f_op_push_mem; -static void (*c_op_pop)() = c_f_op_pop; - -static void (*c_op_push_imm_imm)() = c_f_op_push_imm_imm; -static void (*c_op_push_imm_mem)() = c_f_op_push_imm_mem; -static void (*c_op_push_mem_imm)() = c_f_op_push_mem_imm; -static void (*c_op_push_mem_mem)() = c_f_op_push_mem_mem; +static void (*c_op_return)(void) = c_f_op_return; +static void (*c_op_bz)(void) = c_f_op_bz; +static void (*c_op_ba)(void) = c_f_op_ba; +static void (*c_op_push_imm)(void) = c_f_op_push_imm; +static void (*c_op_push_mem)(void) = c_f_op_push_mem; +static void (*c_op_pop)(void) = c_f_op_pop; + +static void (*c_op_push_imm_imm)(void) = c_f_op_push_imm_imm; +static void (*c_op_push_imm_mem)(void) = c_f_op_push_imm_mem; +static void (*c_op_push_mem_imm)(void) = c_f_op_push_mem_imm; +static void (*c_op_push_mem_mem)(void) = c_f_op_push_mem_mem; static struct c_op c_ops[] = { {1, C_LEFT_TO_RIGHT, C_CLASS_BINARY, "[", c_op_index}, diff -ruN john-1.6/src/compiler.h john-1.6.34/src/compiler.h --- john-1.6/src/compiler.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/compiler.h 2000-08-26 05:25:23.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* @@ -21,14 +21,15 @@ #define C_ERROR_TOOCOMPLEX 5 #define C_ERROR_ARRAYSIZE 6 #define C_ERROR_DATASIZE 7 -#define C_ERROR_DUPE 8 -#define C_ERROR_RESERVED 9 -#define C_ERROR_NOTINFUNC 10 -#define C_ERROR_NESTEDFUNC 11 -#define C_ERROR_NOTINIF 12 -#define C_ERROR_NOTINLOOP 13 -#define C_ERROR_EOF 14 -#define C_ERROR_INTERNAL 15 +#define C_ERROR_RANGE 8 +#define C_ERROR_DUPE 9 +#define C_ERROR_RESERVED 10 +#define C_ERROR_NOTINFUNC 11 +#define C_ERROR_NESTEDFUNC 12 +#define C_ERROR_NOTINIF 13 +#define C_ERROR_NOTINLOOP 14 +#define C_ERROR_EOF 15 +#define C_ERROR_INTERNAL 16 /* * Error names. @@ -63,7 +64,7 @@ * Runs the compiler, and allocates some memory for its output and the * program's data. Returns one of the error codes. */ -extern int c_compile(int (*ext_getchar)(), void (*ext_rewind)(), +extern int c_compile(int (*ext_getchar)(void), void (*ext_rewind)(void), struct c_ident *externs); /* diff -ruN john-1.6/src/config.c john-1.6.34/src/config.c --- john-1.6/src/config.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/config.c 2002-10-03 06:15:39.000000000 +0200 @@ -1,12 +1,13 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2002 by Solar Designer */ #include #include #include #include +#include #include "misc.h" #include "params.h" @@ -14,6 +15,7 @@ #include "memory.h" #include "config.h" +char *cfg_name = NULL; static struct cfg_section *cfg_database = NULL; static char *trim(char *s) @@ -112,7 +114,7 @@ error(); } -void cfg_init(char *name) +void cfg_init(char *name, int allow_missing) { FILE *file; char line[LINE_BUFFER_SIZE]; @@ -120,8 +122,10 @@ if (cfg_database) return; - if (!(file = fopen(path_expand(name), "r"))) + if (!(file = fopen(path_expand(name), "r"))) { + if (allow_missing && errno == ENOENT) return; pexit("fopen: %s", path_expand(name)); + } number = 0; while (fgetl(line, sizeof(line), file)) @@ -130,6 +134,8 @@ if (ferror(file)) pexit("fgets"); if (fclose(file)) pexit("fclose"); + + cfg_name = str_alloc_copy(path_expand(name)); } static struct cfg_section *cfg_get_section(char *section, char *subsection) @@ -191,10 +197,15 @@ int cfg_get_int(char *section, char *subsection, char *param) { - char *value; + char *s_value, *error; + long l_value; - if ((value = cfg_get_param(section, subsection, param))) - return atoi(value); + if ((s_value = cfg_get_param(section, subsection, param))) { + l_value = strtol(s_value, &error, 10); + if (!*s_value || *error || (l_value & ~0x3FFFFFFFL)) + return -1; + return (int)l_value; + } return -1; } @@ -209,10 +220,8 @@ case 'Y': case 't': case 'T': + case '1': return 1; - - default: - return atoi(value); } return 0; diff -ruN john-1.6/src/config.h john-1.6.34/src/config.h --- john-1.6/src/config.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/config.h 2000-03-15 00:23:25.000000000 +0100 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* @@ -46,9 +46,14 @@ }; /* - * Loads a configuration file. + * Name of the currently loaded configuration file, or NULL for none. */ -extern void cfg_init(char *name); +extern char *cfg_name; + +/* + * Loads a configuration file, or does nothing if one is already loaded. + */ +extern void cfg_init(char *name, int allow_missing); /* * Searches for a section with the supplied name, and returns its line list diff -ruN john-1.6/src/cracker.c john-1.6.34/src/cracker.c --- john-1.6/src/cracker.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/cracker.c 2002-09-05 07:56:20.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2002 by Solar Designer */ #include @@ -27,7 +27,7 @@ static struct fmt_methods crk_methods; static int crk_key_index, crk_last_key; static void *crk_last_salt; -static void (*crk_fix_state)(); +static void (*crk_fix_state)(void); static struct db_keys *crk_guesses; static int64 *crk_timestamps; static char crk_stdout_key[PLAINTEXT_BUFFER_SIZE]; @@ -36,11 +36,11 @@ { } -static void crk_dummy_fix_state() +static void crk_dummy_fix_state(void) { } -static void crk_init_salt() +static void crk_init_salt(void) { if (!crk_db->salts->next) { crk_methods.set_salt(crk_db->salts->salt); @@ -48,14 +48,15 @@ } } -void crk_init(struct db_main *db, void (*fix_state)(), +void crk_init(struct db_main *db, void (*fix_state)(void), struct db_keys *guesses) { + char *where; size_t size; if (db->loaded) - if (fmt_self_test(db->format)) { - fprintf(stderr, "Self test failed\n"); + if ((where = fmt_self_test(db->format))) { + fprintf(stderr, "Self test failed (%s)\n", where); error(); } @@ -105,7 +106,7 @@ crk_db->guess_count++; status.guess_count++; - if (crk_guesses) { + if (crk_guesses && !dupe) { strnfcpy(crk_guesses->ptr, key, crk_params.plaintext_length); crk_guesses->ptr += crk_params.plaintext_length; crk_guesses->count++; @@ -142,7 +143,7 @@ return 0; } -static int crk_process_event() +static int crk_process_event(void) { event_pending = 0; @@ -168,11 +169,11 @@ sig_timer_emu_tick(); #endif + idle_yield(); + if (event_pending) if (crk_process_event()) return 1; - idle_yield(0); - crk_methods.crypt_all(crk_key_index); status_update_crypts(salt->count * crk_key_index); @@ -204,7 +205,7 @@ return 0; } -static int crk_salt_loop() +static int crk_salt_loop(void) { struct db_salt *salt; @@ -218,6 +219,8 @@ crk_last_salt = NULL; crk_fix_state(); + crk_methods.clear_keys(); + return 0; } @@ -265,6 +268,8 @@ count = salt->keys->count; index = 0; + crk_methods.clear_keys(); + while (count--) { strnzcpy(key, ptr, crk_params.plaintext_length + 1); ptr += crk_params.plaintext_length; @@ -281,7 +286,7 @@ return 0; } -char *crk_get_key1() +char *crk_get_key1(void) { if (crk_db->loaded) return crk_methods.get_key(0); @@ -289,7 +294,7 @@ return crk_stdout_key; } -char *crk_get_key2() +char *crk_get_key2(void) { if (crk_key_index > 1) return crk_methods.get_key(crk_key_index - 1); @@ -300,7 +305,7 @@ return NULL; } -void crk_done() +void crk_done(void) { if (crk_db->loaded) { if (crk_key_index && crk_db->salts && !event_abort) diff -ruN john-1.6/src/cracker.h john-1.6.34/src/cracker.h --- john-1.6/src/cracker.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/cracker.h 1999-09-22 05:40:07.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ /* @@ -19,7 +19,7 @@ * the future. If guesses is not NULL, the cracker will save guessed keys * in there (the caller must make sure there's room). */ -extern void crk_init(struct db_main *db, void (*fix_state)(), +extern void crk_init(struct db_main *db, void (*fix_state)(void), struct db_keys *guesses); /* @@ -39,12 +39,12 @@ * Return current keys range, crk_get_key2() may return NULL if there's only * one key. Note: these functions may share a static result buffer. */ -extern char *crk_get_key1(); -extern char *crk_get_key2(); +extern char *crk_get_key1(void); +extern char *crk_get_key2(void); /* * Processes all the buffered keys (unless aborted). */ -extern void crk_done(); +extern void crk_done(void); #endif diff -ruN john-1.6/src/DES_bs_b.c john-1.6.34/src/DES_bs_b.c --- john-1.6/src/DES_bs_b.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/DES_bs_b.c 2001-06-16 08:57:44.000000000 +0200 @@ -1,77 +1,440 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer - */ - -/* - * Bitslice DES encryption. + * Copyright (c) 1996-2001 by Solar bdesigner */ #include "arch.h" + +#if !DES_BS_ASM #include "DES_bs.h" /* Include the S-boxes here, so that the compiler can inline them */ #include "DES_bs_s.c" #define b DES_bs_all.B -#define e DES_bs_all.E +#define e DES_bs_all.E.E + +#if DES_BS_VECTOR +#define kd [depth] +#define bd [depth] +#define ed [depth] +#define for_each_depth() \ + for (depth = 0; depth < DES_BS_VECTOR; depth++) +#else +#if DES_BS_EXPAND +#define kd +#else +#define kd [0] +#endif +#define bd +#define ed [0] +#define for_each_depth() +#endif -void DES_bs_body() +#define DES_bs_clear_block_8(i) \ + for_each_depth() { \ + b[i] bd = 0; \ + b[i + 1] bd = 0; \ + b[i + 2] bd = 0; \ + b[i + 3] bd = 0; \ + b[i + 4] bd = 0; \ + b[i + 5] bd = 0; \ + b[i + 6] bd = 0; \ + b[i + 7] bd = 0; \ + } + +#define DES_bs_clear_block() \ + DES_bs_clear_block_8(0); \ + DES_bs_clear_block_8(8); \ + DES_bs_clear_block_8(16); \ + DES_bs_clear_block_8(24); \ + DES_bs_clear_block_8(32); \ + DES_bs_clear_block_8(40); \ + DES_bs_clear_block_8(48); \ + DES_bs_clear_block_8(56); + +void DES_bs_crypt(int count) { - ARCH_WORD **k = DES_bs_all.Kp; - int count = 8; +#if DES_BS_EXPAND + DES_bs_vector *k; +#else + ARCH_WORD **k; +#endif + int iterations, rounds_and_swapped; +#if DES_BS_VECTOR + int depth; +#endif + + DES_bs_clear_block(); + +#if DES_BS_EXPAND + k = DES_bs_all.KS.v; +#else + k = DES_bs_all.KS.p; +#endif + rounds_and_swapped = 8; + iterations = count; + +start: + for_each_depth() + s1(e[0] ed ^ k[0] kd, e[1] ed ^ k[1] kd, e[2] ed ^ k[2] kd, + e[3] ed ^ k[3] kd, e[4] ed ^ k[4] kd, e[5] ed ^ k[5] kd, + &b[40] bd, &b[48] bd, &b[54] bd, &b[62] bd); + for_each_depth() + s2(e[6] ed ^ k[6] kd, e[7] ed ^ k[7] kd, e[8] ed ^ k[8] kd, + e[9] ed ^ k[9] kd, e[10] ed ^ k[10] kd, e[11] ed ^ k[11] kd, + &b[44] bd, &b[59] bd, &b[33] bd, &b[49] bd); + for_each_depth() + s3(e[12] ed ^ k[12] kd, e[13] ed ^ k[13] kd, e[14] ed ^ k[14] kd, + e[15] ed ^ k[15] kd, e[16] ed ^ k[16] kd, e[17] ed ^ k[17] kd, + &b[55] bd, &b[47] bd, &b[61] bd, &b[37] bd); + for_each_depth() + s4(e[18] ed ^ k[18] kd, e[19] ed ^ k[19] kd, e[20] ed ^ k[20] kd, + e[21] ed ^ k[21] kd, e[22] ed ^ k[22] kd, e[23] ed ^ k[23] kd, + &b[57] bd, &b[51] bd, &b[41] bd, &b[32] bd); + for_each_depth() + s5(e[24] ed ^ k[24] kd, e[25] ed ^ k[25] kd, e[26] ed ^ k[26] kd, + e[27] ed ^ k[27] kd, e[28] ed ^ k[28] kd, e[29] ed ^ k[29] kd, + &b[39] bd, &b[45] bd, &b[56] bd, &b[34] bd); + for_each_depth() + s6(e[30] ed ^ k[30] kd, e[31] ed ^ k[31] kd, e[32] ed ^ k[32] kd, + e[33] ed ^ k[33] kd, e[34] ed ^ k[34] kd, e[35] ed ^ k[35] kd, + &b[35] bd, &b[60] bd, &b[42] bd, &b[50] bd); + for_each_depth() + s7(e[36] ed ^ k[36] kd, e[37] ed ^ k[37] kd, e[38] ed ^ k[38] kd, + e[39] ed ^ k[39] kd, e[40] ed ^ k[40] kd, e[41] ed ^ k[41] kd, + &b[63] bd, &b[43] bd, &b[53] bd, &b[38] bd); + for_each_depth() + s8(e[42] ed ^ k[42] kd, e[43] ed ^ k[43] kd, e[44] ed ^ k[44] kd, + e[45] ed ^ k[45] kd, e[46] ed ^ k[46] kd, e[47] ed ^ k[47] kd, + &b[36] bd, &b[58] bd, &b[46] bd, &b[52] bd); + + if (rounds_and_swapped == 0x100) goto next; + +swap: + for_each_depth() + s1(e[48] ed ^ k[48] kd, e[49] ed ^ k[49] kd, e[50] ed ^ k[50] kd, + e[51] ed ^ k[51] kd, e[52] ed ^ k[52] kd, e[53] ed ^ k[53] kd, + &b[8] bd, &b[16] bd, &b[22] bd, &b[30] bd); + for_each_depth() + s2(e[54] ed ^ k[54] kd, e[55] ed ^ k[55] kd, e[56] ed ^ k[56] kd, + e[57] ed ^ k[57] kd, e[58] ed ^ k[58] kd, e[59] ed ^ k[59] kd, + &b[12] bd, &b[27] bd, &b[1] bd, &b[17] bd); + for_each_depth() + s3(e[60] ed ^ k[60] kd, e[61] ed ^ k[61] kd, e[62] ed ^ k[62] kd, + e[63] ed ^ k[63] kd, e[64] ed ^ k[64] kd, e[65] ed ^ k[65] kd, + &b[23] bd, &b[15] bd, &b[29] bd, &b[5] bd); + for_each_depth() + s4(e[66] ed ^ k[66] kd, e[67] ed ^ k[67] kd, e[68] ed ^ k[68] kd, + e[69] ed ^ k[69] kd, e[70] ed ^ k[70] kd, e[71] ed ^ k[71] kd, + &b[25] bd, &b[19] bd, &b[9] bd, &b[0] bd); + for_each_depth() + s5(e[72] ed ^ k[72] kd, e[73] ed ^ k[73] kd, e[74] ed ^ k[74] kd, + e[75] ed ^ k[75] kd, e[76] ed ^ k[76] kd, e[77] ed ^ k[77] kd, + &b[7] bd, &b[13] bd, &b[24] bd, &b[2] bd); + for_each_depth() + s6(e[78] ed ^ k[78] kd, e[79] ed ^ k[79] kd, e[80] ed ^ k[80] kd, + e[81] ed ^ k[81] kd, e[82] ed ^ k[82] kd, e[83] ed ^ k[83] kd, + &b[3] bd, &b[28] bd, &b[10] bd, &b[18] bd); + for_each_depth() + s7(e[84] ed ^ k[84] kd, e[85] ed ^ k[85] kd, e[86] ed ^ k[86] kd, + e[87] ed ^ k[87] kd, e[88] ed ^ k[88] kd, e[89] ed ^ k[89] kd, + &b[31] bd, &b[11] bd, &b[21] bd, &b[6] bd); + for_each_depth() + s8(e[90] ed ^ k[90] kd, e[91] ed ^ k[91] kd, e[92] ed ^ k[92] kd, + e[93] ed ^ k[93] kd, e[94] ed ^ k[94] kd, e[95] ed ^ k[95] kd, + &b[4] bd, &b[26] bd, &b[14] bd, &b[20] bd); + + k += 96; + + if (--rounds_and_swapped) goto start; + k -= (0x300 + 48); + rounds_and_swapped = 0x108; + if (--iterations) goto swap; + return; + +next: + k -= (0x300 - 48); + rounds_and_swapped = 8; + if (--iterations) goto start; +} + +void DES_bs_crypt_25(void) +{ +#if DES_BS_EXPAND + DES_bs_vector *k; +#else + ARCH_WORD **k; +#endif + int iterations, rounds_and_swapped; +#if DES_BS_VECTOR + int depth; +#endif + + DES_bs_clear_block(); + +#if DES_BS_EXPAND + k = DES_bs_all.KS.v; +#else + k = DES_bs_all.KS.p; +#endif + rounds_and_swapped = 8; + iterations = 25; + +start: + for_each_depth() + s1(e[0] ed ^ k[0] kd, e[1] ed ^ k[1] kd, e[2] ed ^ k[2] kd, + e[3] ed ^ k[3] kd, e[4] ed ^ k[4] kd, e[5] ed ^ k[5] kd, + &b[40] bd, &b[48] bd, &b[54] bd, &b[62] bd); + for_each_depth() + s2(e[6] ed ^ k[6] kd, e[7] ed ^ k[7] kd, e[8] ed ^ k[8] kd, + e[9] ed ^ k[9] kd, e[10] ed ^ k[10] kd, e[11] ed ^ k[11] kd, + &b[44] bd, &b[59] bd, &b[33] bd, &b[49] bd); + for_each_depth() + s3(b[7] bd ^ k[12] kd, b[8] bd ^ k[13] kd, b[9] bd ^ k[14] kd, + b[10] bd ^ k[15] kd, b[11] bd ^ k[16] kd, b[12] bd ^ k[17] kd, + &b[55] bd, &b[47] bd, &b[61] bd, &b[37] bd); + for_each_depth() + s4(b[11] bd ^ k[18] kd, b[12] bd ^ k[19] kd, b[13] bd ^ k[20] kd, + b[14] bd ^ k[21] kd, b[15] bd ^ k[22] kd, b[16] bd ^ k[23] kd, + &b[57] bd, &b[51] bd, &b[41] bd, &b[32] bd); + for_each_depth() + s5(e[24] ed ^ k[24] kd, e[25] ed ^ k[25] kd, e[26] ed ^ k[26] kd, + e[27] ed ^ k[27] kd, e[28] ed ^ k[28] kd, e[29] ed ^ k[29] kd, + &b[39] bd, &b[45] bd, &b[56] bd, &b[34] bd); + for_each_depth() + s6(e[30] ed ^ k[30] kd, e[31] ed ^ k[31] kd, e[32] ed ^ k[32] kd, + e[33] ed ^ k[33] kd, e[34] ed ^ k[34] kd, e[35] ed ^ k[35] kd, + &b[35] bd, &b[60] bd, &b[42] bd, &b[50] bd); + for_each_depth() + s7(b[23] bd ^ k[36] kd, b[24] bd ^ k[37] kd, b[25] bd ^ k[38] kd, + b[26] bd ^ k[39] kd, b[27] bd ^ k[40] kd, b[28] bd ^ k[41] kd, + &b[63] bd, &b[43] bd, &b[53] bd, &b[38] bd); + for_each_depth() + s8(b[27] bd ^ k[42] kd, b[28] bd ^ k[43] kd, b[29] bd ^ k[44] kd, + b[30] bd ^ k[45] kd, b[31] bd ^ k[46] kd, b[0] bd ^ k[47] kd, + &b[36] bd, &b[58] bd, &b[46] bd, &b[52] bd); + + if (rounds_and_swapped == 0x100) goto next; + +swap: + for_each_depth() + s1(e[48] ed ^ k[48] kd, e[49] ed ^ k[49] kd, e[50] ed ^ k[50] kd, + e[51] ed ^ k[51] kd, e[52] ed ^ k[52] kd, e[53] ed ^ k[53] kd, + &b[8] bd, &b[16] bd, &b[22] bd, &b[30] bd); + for_each_depth() + s2(e[54] ed ^ k[54] kd, e[55] ed ^ k[55] kd, e[56] ed ^ k[56] kd, + e[57] ed ^ k[57] kd, e[58] ed ^ k[58] kd, e[59] ed ^ k[59] kd, + &b[12] bd, &b[27] bd, &b[1] bd, &b[17] bd); + for_each_depth() + s3(b[39] bd ^ k[60] kd, b[40] bd ^ k[61] kd, b[41] bd ^ k[62] kd, + b[42] bd ^ k[63] kd, b[43] bd ^ k[64] kd, b[44] bd ^ k[65] kd, + &b[23] bd, &b[15] bd, &b[29] bd, &b[5] bd); + for_each_depth() + s4(b[43] bd ^ k[66] kd, b[44] bd ^ k[67] kd, b[45] bd ^ k[68] kd, + b[46] bd ^ k[69] kd, b[47] bd ^ k[70] kd, b[48] bd ^ k[71] kd, + &b[25] bd, &b[19] bd, &b[9] bd, &b[0] bd); + for_each_depth() + s5(e[72] ed ^ k[72] kd, e[73] ed ^ k[73] kd, e[74] ed ^ k[74] kd, + e[75] ed ^ k[75] kd, e[76] ed ^ k[76] kd, e[77] ed ^ k[77] kd, + &b[7] bd, &b[13] bd, &b[24] bd, &b[2] bd); + for_each_depth() + s6(e[78] ed ^ k[78] kd, e[79] ed ^ k[79] kd, e[80] ed ^ k[80] kd, + e[81] ed ^ k[81] kd, e[82] ed ^ k[82] kd, e[83] ed ^ k[83] kd, + &b[3] bd, &b[28] bd, &b[10] bd, &b[18] bd); + for_each_depth() + s7(b[55] bd ^ k[84] kd, b[56] bd ^ k[85] kd, b[57] bd ^ k[86] kd, + b[58] bd ^ k[87] kd, b[59] bd ^ k[88] kd, b[60] bd ^ k[89] kd, + &b[31] bd, &b[11] bd, &b[21] bd, &b[6] bd); + for_each_depth() + s8(b[59] bd ^ k[90] kd, b[60] bd ^ k[91] kd, b[61] bd ^ k[92] kd, + b[62] bd ^ k[93] kd, b[63] bd ^ k[94] kd, b[32] bd ^ k[95] kd, + &b[4] bd, &b[26] bd, &b[14] bd, &b[20] bd); + + k += 96; + + if (--rounds_and_swapped) goto start; + k -= (0x300 + 48); + rounds_and_swapped = 0x108; + if (--iterations) goto swap; + return; + +next: + k -= (0x300 - 48); + rounds_and_swapped = 8; + iterations--; + goto start; +} + +#undef kd +#if DES_BS_VECTOR +#define kd [depth] +#else +#define kd [0] +#endif + +void DES_bs_crypt_LM(void) +{ + ARCH_WORD **k; + int rounds; +#if DES_BS_VECTOR + int depth; +#endif + + for_each_depth() { + b[0] bd = 0; + b[1] bd = 0; + b[2] bd = 0; + b[3] bd = 0; + b[4] bd = 0; + b[5] bd = 0; + b[6] bd = 0; + b[7] bd = 0; + b[8] bd = ~(ARCH_WORD)0; + b[9] bd = ~(ARCH_WORD)0; + b[10] bd = ~(ARCH_WORD)0; + b[11] bd = 0; + b[12] bd = ~(ARCH_WORD)0; + b[13] bd = 0; + b[14] bd = 0; + b[15] bd = 0; + b[16] bd = 0; + b[17] bd = 0; + b[18] bd = 0; + b[19] bd = 0; + b[20] bd = 0; + b[21] bd = 0; + b[22] bd = 0; + b[23] bd = ~(ARCH_WORD)0; + b[24] bd = 0; + b[25] bd = 0; + b[26] bd = ~(ARCH_WORD)0; + b[27] bd = 0; + b[28] bd = 0; + b[29] bd = ~(ARCH_WORD)0; + b[30] bd = ~(ARCH_WORD)0; + b[31] bd = ~(ARCH_WORD)0; + b[32] bd = 0; + b[33] bd = 0; + b[34] bd = 0; + b[35] bd = ~(ARCH_WORD)0; + b[36] bd = 0; + b[37] bd = ~(ARCH_WORD)0; + b[38] bd = ~(ARCH_WORD)0; + b[39] bd = ~(ARCH_WORD)0; + b[40] bd = 0; + b[41] bd = 0; + b[42] bd = 0; + b[43] bd = 0; + b[44] bd = 0; + b[45] bd = ~(ARCH_WORD)0; + b[46] bd = 0; + b[47] bd = 0; + b[48] bd = ~(ARCH_WORD)0; + b[49] bd = ~(ARCH_WORD)0; + b[50] bd = 0; + b[51] bd = 0; + b[52] bd = 0; + b[53] bd = 0; + b[54] bd = ~(ARCH_WORD)0; + b[55] bd = 0; + b[56] bd = ~(ARCH_WORD)0; + b[57] bd = 0; + b[58] bd = ~(ARCH_WORD)0; + b[59] bd = 0; + b[60] bd = ~(ARCH_WORD)0; + b[61] bd = ~(ARCH_WORD)0; + b[62] bd = ~(ARCH_WORD)0; + b[63] bd = ~(ARCH_WORD)0; + } + + k = DES_bs_all.KS.p; + rounds = 8; do { - s1(*e[0] ^ *k[0], *e[1] ^ *k[1], *e[2] ^ *k[2], - *e[3] ^ *k[3], *e[4] ^ *k[4], *e[5] ^ *k[5], - &b[40], &b[48], &b[54], &b[62]); - s2(*e[6] ^ *k[6], *e[7] ^ *k[7], *e[8] ^ *k[8], - *e[9] ^ *k[9], *e[10] ^ *k[10], *e[11] ^ *k[11], - &b[44], &b[59], &b[33], &b[49]); - s3(*e[12] ^ *k[12], *e[13] ^ *k[13], *e[14] ^ *k[14], - *e[15] ^ *k[15], *e[16] ^ *k[16], *e[17] ^ *k[17], - &b[55], &b[47], &b[61], &b[37]); - s4(*e[18] ^ *k[18], *e[19] ^ *k[19], *e[20] ^ *k[20], - *e[21] ^ *k[21], *e[22] ^ *k[22], *e[23] ^ *k[23], - &b[57], &b[51], &b[41], &b[32]); - s5(*e[24] ^ *k[24], *e[25] ^ *k[25], *e[26] ^ *k[26], - *e[27] ^ *k[27], *e[28] ^ *k[28], *e[29] ^ *k[29], - &b[39], &b[45], &b[56], &b[34]); - s6(*e[30] ^ *k[30], *e[31] ^ *k[31], *e[32] ^ *k[32], - *e[33] ^ *k[33], *e[34] ^ *k[34], *e[35] ^ *k[35], - &b[35], &b[60], &b[42], &b[50]); - s7(*e[36] ^ *k[36], *e[37] ^ *k[37], *e[38] ^ *k[38], - *e[39] ^ *k[39], *e[40] ^ *k[40], *e[41] ^ *k[41], - &b[63], &b[43], &b[53], &b[38]); - s8(*e[42] ^ *k[42], *e[43] ^ *k[43], *e[44] ^ *k[44], - *e[45] ^ *k[45], *e[46] ^ *k[46], *e[47] ^ *k[47], - &b[36], &b[58], &b[46], &b[52]); - - s1(*e[48] ^ *k[48], *e[49] ^ *k[49], *e[50] ^ *k[50], - *e[51] ^ *k[51], *e[52] ^ *k[52], *e[53] ^ *k[53], - &b[8], &b[16], &b[22], &b[30]); - s2(*e[54] ^ *k[54], *e[55] ^ *k[55], *e[56] ^ *k[56], - *e[57] ^ *k[57], *e[58] ^ *k[58], *e[59] ^ *k[59], - &b[12], &b[27], &b[1], &b[17]); - s3(*e[60] ^ *k[60], *e[61] ^ *k[61], *e[62] ^ *k[62], - *e[63] ^ *k[63], *e[64] ^ *k[64], *e[65] ^ *k[65], - &b[23], &b[15], &b[29], &b[5]); - s4(*e[66] ^ *k[66], *e[67] ^ *k[67], *e[68] ^ *k[68], - *e[69] ^ *k[69], *e[70] ^ *k[70], *e[71] ^ *k[71], - &b[25], &b[19], &b[9], &b[0]); - s5(*e[72] ^ *k[72], *e[73] ^ *k[73], *e[74] ^ *k[74], - *e[75] ^ *k[75], *e[76] ^ *k[76], *e[77] ^ *k[77], - &b[7], &b[13], &b[24], &b[2]); - s6(*e[78] ^ *k[78], *e[79] ^ *k[79], *e[80] ^ *k[80], - *e[81] ^ *k[81], *e[82] ^ *k[82], *e[83] ^ *k[83], - &b[3], &b[28], &b[10], &b[18]); - s7(*e[84] ^ *k[84], *e[85] ^ *k[85], *e[86] ^ *k[86], - *e[87] ^ *k[87], *e[88] ^ *k[88], *e[89] ^ *k[89], - &b[31], &b[11], &b[21], &b[6]); - s8(*e[90] ^ *k[90], *e[91] ^ *k[91], *e[92] ^ *k[92], - *e[93] ^ *k[93], *e[94] ^ *k[94], *e[95] ^ *k[95], - &b[4], &b[26], &b[14], &b[20]); + for_each_depth() + s1(b[31] bd ^ k[0] kd, b[0] bd ^ k[1] kd, + b[1] bd ^ k[2] kd, b[2] bd ^ k[3] kd, + b[3] bd ^ k[4] kd, b[4] bd ^ k[5] kd, + &b[40] bd, &b[48] bd, &b[54] bd, &b[62] bd); + for_each_depth() + s2(b[3] bd ^ k[6] kd, b[4] bd ^ k[7] kd, + b[5] bd ^ k[8] kd, b[6] bd ^ k[9] kd, + b[7] bd ^ k[10] kd, b[8] bd ^ k[11] kd, + &b[44] bd, &b[59] bd, &b[33] bd, &b[49] bd); + for_each_depth() + s3(b[7] bd ^ k[12] kd, b[8] bd ^ k[13] kd, + b[9] bd ^ k[14] kd, b[10] bd ^ k[15] kd, + b[11] bd ^ k[16] kd, b[12] bd ^ k[17] kd, + &b[55] bd, &b[47] bd, &b[61] bd, &b[37] bd); + for_each_depth() + s4(b[11] bd ^ k[18] kd, b[12] bd ^ k[19] kd, + b[13] bd ^ k[20] kd, b[14] bd ^ k[21] kd, + b[15] bd ^ k[22] kd, b[16] bd ^ k[23] kd, + &b[57] bd, &b[51] bd, &b[41] bd, &b[32] bd); + for_each_depth() + s5(b[15] bd ^ k[24] kd, b[16] bd ^ k[25] kd, + b[17] bd ^ k[26] kd, b[18] bd ^ k[27] kd, + b[19] bd ^ k[28] kd, b[20] bd ^ k[29] kd, + &b[39] bd, &b[45] bd, &b[56] bd, &b[34] bd); + for_each_depth() + s6(b[19] bd ^ k[30] kd, b[20] bd ^ k[31] kd, + b[21] bd ^ k[32] kd, b[22] bd ^ k[33] kd, + b[23] bd ^ k[34] kd, b[24] bd ^ k[35] kd, + &b[35] bd, &b[60] bd, &b[42] bd, &b[50] bd); + for_each_depth() + s7(b[23] bd ^ k[36] kd, b[24] bd ^ k[37] kd, + b[25] bd ^ k[38] kd, b[26] bd ^ k[39] kd, + b[27] bd ^ k[40] kd, b[28] bd ^ k[41] kd, + &b[63] bd, &b[43] bd, &b[53] bd, &b[38] bd); + for_each_depth() + s8(b[27] bd ^ k[42] kd, b[28] bd ^ k[43] kd, + b[29] bd ^ k[44] kd, b[30] bd ^ k[45] kd, + b[31] bd ^ k[46] kd, b[0] bd ^ k[47] kd, + &b[36] bd, &b[58] bd, &b[46] bd, &b[52] bd); + + for_each_depth() + s1(b[63] bd ^ k[48] kd, b[32] bd ^ k[49] kd, + b[33] bd ^ k[50] kd, b[34] bd ^ k[51] kd, + b[35] bd ^ k[52] kd, b[36] bd ^ k[53] kd, + &b[8] bd, &b[16] bd, &b[22] bd, &b[30] bd); + for_each_depth() + s2(b[35] bd ^ k[54] kd, b[36] bd ^ k[55] kd, + b[37] bd ^ k[56] kd, b[38] bd ^ k[57] kd, + b[39] bd ^ k[58] kd, b[40] bd ^ k[59] kd, + &b[12] bd, &b[27] bd, &b[1] bd, &b[17] bd); + for_each_depth() + s3(b[39] bd ^ k[60] kd, b[40] bd ^ k[61] kd, + b[41] bd ^ k[62] kd, b[42] bd ^ k[63] kd, + b[43] bd ^ k[64] kd, b[44] bd ^ k[65] kd, + &b[23] bd, &b[15] bd, &b[29] bd, &b[5] bd); + for_each_depth() + s4(b[43] bd ^ k[66] kd, b[44] bd ^ k[67] kd, + b[45] bd ^ k[68] kd, b[46] bd ^ k[69] kd, + b[47] bd ^ k[70] kd, b[48] bd ^ k[71] kd, + &b[25] bd, &b[19] bd, &b[9] bd, &b[0] bd); + for_each_depth() + s5(b[47] bd ^ k[72] kd, b[48] bd ^ k[73] kd, + b[49] bd ^ k[74] kd, b[50] bd ^ k[75] kd, + b[51] bd ^ k[76] kd, b[52] bd ^ k[77] kd, + &b[7] bd, &b[13] bd, &b[24] bd, &b[2] bd); + for_each_depth() + s6(b[51] bd ^ k[78] kd, b[52] bd ^ k[79] kd, + b[53] bd ^ k[80] kd, b[54] bd ^ k[81] kd, + b[55] bd ^ k[82] kd, b[56] bd ^ k[83] kd, + &b[3] bd, &b[28] bd, &b[10] bd, &b[18] bd); + for_each_depth() + s7(b[55] bd ^ k[84] kd, b[56] bd ^ k[85] kd, + b[57] bd ^ k[86] kd, b[58] bd ^ k[87] kd, + b[59] bd ^ k[88] kd, b[60] bd ^ k[89] kd, + &b[31] bd, &b[11] bd, &b[21] bd, &b[6] bd); + for_each_depth() + s8(b[59] bd ^ k[90] kd, b[60] bd ^ k[91] kd, + b[61] bd ^ k[92] kd, b[62] bd ^ k[93] kd, + b[63] bd ^ k[94] kd, b[32] bd ^ k[95] kd, + &b[4] bd, &b[26] bd, &b[14] bd, &b[20] bd); k += 96; - } while (--count); + } while (--rounds); } +#endif diff -ruN john-1.6/src/DES_bs.c john-1.6.34/src/DES_bs.c --- john-1.6/src/DES_bs.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/DES_bs.c 2002-10-19 16:05:46.000000000 +0200 @@ -1,34 +1,121 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2002 by Solar Designer */ #include #include "arch.h" +#include "common.h" #include "DES_std.h" #include "DES_bs.h" -DES_bs_combined DES_bs_all; -int DES_bs_mem_saving = 0; +#if DES_BS_VECTOR +#define DEPTH [depth] +#define START [0] +#define init_depth() \ + register int depth; \ + depth = index >> ARCH_BITS_LOG; \ + index &= (ARCH_BITS - 1); +#define for_each_depth() \ + for (depth = 0; depth < DES_BS_VECTOR; depth++) +#else +#define DEPTH +#define START +#define init_depth() +#define for_each_depth() +#endif + +#if !DES_BS_ASM +DES_bs_combined CC_CACHE_ALIGN DES_bs_all; +#endif + +static unsigned char DES_LM_KP[56] = { + 1, 2, 3, 4, 5, 6, 7, + 10, 11, 12, 13, 14, 15, 0, + 19, 20, 21, 22, 23, 8, 9, + 28, 29, 30, 31, 16, 17, 18, + 37, 38, 39, 24, 25, 26, 27, + 46, 47, 32, 33, 34, 35, 36, + 55, 40, 41, 42, 43, 44, 45, + 48, 49, 50, 51, 52, 53, 54 +}; + +static unsigned char DES_LM_reverse[16] = { + 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 +}; + +#if DES_BS_ASM +extern void DES_bs_init_asm(void); +#endif -extern void DES_bs_body(); - -void DES_bs_init() +void DES_bs_init(int LM) { - int index, bit; + ARCH_WORD **k; + int round, index, bit; + int p, q, s; + int c; + + DES_bs_all.KS_updates = 0; + if (LM) + DES_bs_clear_keys_LM(); + else + DES_bs_clear_keys(); - for (index = 0; index < 0x300; index++) { - bit = DES_K_bits[index]; - bit -= bit >> 3; - DES_bs_all.Kp[index] = &DES_bs_all.K[55 - bit]; +#if DES_BS_EXPAND + if (LM) + k = DES_bs_all.KS.p; + else + k = DES_bs_all.KSp; +#else + k = DES_bs_all.KS.p; +#endif + + s = 0; + for (round = 0; round < 16; round++) { + s += DES_ROT[round]; + for (index = 0; index < 48; index++) { + p = DES_PC2[index]; + q = p < 28 ? 0 : 28; + p += s; + while (p >= 28) p -= 28; + bit = DES_PC1[p + q]; + bit ^= 070; + bit -= bit >> 3; + bit = 55 - bit; + if (LM) bit = DES_LM_KP[bit]; + *k++ = &DES_bs_all.K[bit] START; + } + } + +/* Initialize the array with right shifts needed to get past the first + * non-zero bit in the index. */ + for (bit = 0; bit <= 7; bit++) + for (index = 1 << bit; index < 0x100; index += 2 << bit) + DES_bs_all.s[index] = bit + 1; + +/* Special case: instead of doing an extra check in the loop below, we + * might instead overrun into DES_bs_all.B, which is harmless, as long + * as the order of fields is unchanged. */ + DES_bs_all.s[0] = 57; + + if (LM) { + for (c = 0; c < 0x100; c++) + if (c >= 'a' && c <= 'z') + DES_bs_all.E.extras.u[c] = c & ~0x20; + else + DES_bs_all.E.extras.u[c] = c; } + +#if DES_BS_ASM + DES_bs_init_asm(); +#endif } void DES_bs_set_salt(ARCH_WORD salt) { - register int src, dst; register ARCH_WORD mask; + register int src, dst; mask = 1; for (dst = 0; dst < 48; dst++) { @@ -38,158 +125,232 @@ if (dst < 24) src = dst + 24; else src = dst - 24; } else src = dst; - DES_bs_all.E[dst] = &DES_bs_all.B[DES_E[src]]; - DES_bs_all.E[dst + 48] = &DES_bs_all.B[DES_E[src] + 32]; + DES_bs_all.E.E[dst] = &DES_bs_all.B[DES_E[src]] START; + DES_bs_all.E.E[dst + 48] = &DES_bs_all.B[DES_E[src] + 32] START; mask <<= 1; } } -void DES_bs_clear_keys() +void DES_bs_clear_keys(void) +{ + if (DES_bs_all.KS_updates++ & 0xFFF) return; + DES_bs_all.KS_updates = 1; + memset(DES_bs_all.K, 0, sizeof(DES_bs_all.K)); + memset(DES_bs_all.keys, 0, sizeof(DES_bs_all.keys)); + DES_bs_all.keys_changed = 1; +} + +void DES_bs_clear_keys_LM(void) { + if (DES_bs_all.KS_updates++ & 0xFFF) return; + DES_bs_all.KS_updates = 1; memset(DES_bs_all.K, 0, sizeof(DES_bs_all.K)); +#if !DES_BS_VECTOR && ARCH_BITS >= 64 + memset(DES_bs_all.E.extras.keys, 0, sizeof(DES_bs_all.E.extras.keys)); +#else + memset(DES_bs_all.keys, 0, sizeof(DES_bs_all.keys)); +#endif } void DES_bs_set_key(char *key, int index) { - register char *ptr; - register int ofs, bit; - register ARCH_WORD value; + register unsigned char *new = (unsigned char *)key; + register unsigned char *old = DES_bs_all.keys[index]; + register ARCH_WORD xor, mask; + register int ofs, bit, shift; + + init_depth(); - ofs = 56; - for (ptr = key; *ptr && ofs; ptr++) { - bit = (ofs -= 7); - value = *ptr & 0x7F; + mask = (ARCH_WORD)1 << index; + ofs = -1; + while ((*new || *old) && ofs < 55) { + if ((xor = *new ^ *old)) { + xor &= 0x7F; + *old = *new; + bit = ofs; + do { + shift = DES_bs_all.s[xor]; + DES_bs_all.K[bit += shift] DEPTH ^= mask; + } while (xor >>= shift); + } - do { - DES_bs_all.K[bit++] |= (value & 1) << index; - } while (value >>= 1); + if (*new) new++; + old++; + ofs += 7; } + + DES_bs_all.keys_changed = 1; } -void DES_bs_crypt(int count) +void DES_bs_set_key_LM(char *key, int index) { - register int bit; - register ARCH_WORD R, L; + register unsigned char *new = (unsigned char *)key; +#if !DES_BS_VECTOR && ARCH_BITS >= 64 + register unsigned char *old = DES_bs_all.E.extras.keys[index]; +#else + register unsigned char *old = DES_bs_all.keys[index]; +#endif + register unsigned char plain; + register ARCH_WORD xor, mask; + register int ofs, bit, shift; - memset(DES_bs_all.B, 0, sizeof(DES_bs_all.B)); + init_depth(); - do { - DES_bs_body(); + mask = (ARCH_WORD)1 << index; + ofs = -1; + while ((*new || *old) && ofs < 55) { + plain = DES_bs_all.E.extras.u[ARCH_INDEX(*new)]; + if ((xor = plain ^ *old)) { + *old = plain; + bit = ofs; + do { + shift = DES_bs_all.s[xor]; + DES_bs_all.K[bit += shift] DEPTH ^= mask; + } while (xor >>= shift); + } + + if (*new) new++; + old++; + ofs += 8; + } +} - if (!--count) break; +#if DES_BS_EXPAND +void DES_bs_expand_keys(void) +{ + register int index; +#if DES_BS_VECTOR + register int depth; +#endif + + if (!DES_bs_all.keys_changed) return; + + for (index = 0; index < 0x300; index++) + for_each_depth() +#if DES_BS_VECTOR + DES_bs_all.KS.v[index] DEPTH = DES_bs_all.KSp[index] DEPTH; +#else + DES_bs_all.KS.v[index] = *DES_bs_all.KSp[index]; +#endif - for (bit = 0; bit < 32; bit++) { - R = DES_bs_all.B[bit]; - L = DES_bs_all.B[bit + 32]; - DES_bs_all.B[bit + 32] = R; - DES_bs_all.B[bit] = L; - } - } while (1); + DES_bs_all.keys_changed = 0; } +#endif -ARCH_WORD *DES_bs_get_binary(char *ciphertext) +static ARCH_WORD *DES_bs_get_binary_raw(ARCH_WORD *raw, int count) { - static ARCH_WORD out[64]; - ARCH_WORD *raw; - int bit; - int index, shift; - int value; - - raw = DES_raw_get_binary(ciphertext); - - out[1] = out[0] = 0; - for (bit = 0; bit < 64; bit++) { - index = bit >> 4; - -/* Swap L and R here instead of doing it one more time in DES_bs_crypt() */ - index ^= 2; - -/* Calculate the number of one of the 16 data bits in raw[index] */ - shift = ((bit & 0xC) << 1) + (bit & 3) + 1; - -/* Get the bit */ - value = (raw[index] >> shift) & 1; - - if (DES_bs_mem_saving) -/* Memory saving: pack the bits into two words */ - out[bit >> 5] |= value << (bit & 0x1F); - else -/* We either set or clear all the bits in every word */ - out[bit] = value ? ~(ARCH_WORD)0 : 0; - } + static ARCH_WORD out[2]; + +/* For odd iteration counts, swap L and R here instead of doing it one + * more time in DES_bs_crypt(). */ + count &= 1; + out[count] = raw[0]; + out[count ^ 1] = raw[1]; return out; } -int DES_bs_binary_hash(ARCH_WORD *binary, int count) +ARCH_WORD *DES_bs_get_binary(char *ciphertext) { - int bit, result; - - if (DES_bs_mem_saving) - return (int)*binary & ((1 << count) - 1); + return DES_bs_get_binary_raw( + DES_raw_get_binary(ciphertext), + DES_raw_get_count(ciphertext)); +} - result = 0; - for (bit = 0; bit < count; bit++) - if (binary[bit]) result |= 1 << bit; +ARCH_WORD *DES_bs_get_binary_LM(char *ciphertext) +{ + ARCH_WORD block[2], value; + int l, h; + int index; + + block[0] = block[1] = 0; + for (index = 0; index < 16; index += 2) { + l = atoi16[ARCH_INDEX(ciphertext[index])]; + h = atoi16[ARCH_INDEX(ciphertext[index + 1])]; + value = DES_LM_reverse[l] | (DES_LM_reverse[h] << 4); + block[index >> 3] |= value << ((index << 2) & 0x18); + } - return result; + return DES_bs_get_binary_raw(DES_do_IP(block), 1); } int DES_bs_get_hash(int index, int count) { - register int bit, result; - register ARCH_WORD mask; + register int result; - mask = (ARCH_WORD)1 << index; - result = 0; - for (bit = 0; bit < count; bit++) - if (DES_bs_all.B[bit] & mask) result |= 1 << bit; + init_depth(); + + result = (DES_bs_all.B[0] DEPTH >> index) & 1; + result |= ((DES_bs_all.B[1] DEPTH >> index) & 1) << 1; + result |= ((DES_bs_all.B[2] DEPTH >> index) & 1) << 2; + result |= ((DES_bs_all.B[3] DEPTH >> index) & 1) << 3; + if (count == 4) return result; + + result |= ((DES_bs_all.B[4] DEPTH >> index) & 1) << 4; + result |= ((DES_bs_all.B[5] DEPTH >> index) & 1) << 5; + result |= ((DES_bs_all.B[6] DEPTH >> index) & 1) << 6; + result |= ((DES_bs_all.B[7] DEPTH >> index) & 1) << 7; + if (count == 8) return result; + + result |= ((DES_bs_all.B[8] DEPTH >> index) & 1) << 8; + result |= ((DES_bs_all.B[9] DEPTH >> index) & 1) << 9; + result |= ((DES_bs_all.B[10] DEPTH >> index) & 1) << 10; + result |= ((DES_bs_all.B[11] DEPTH >> index) & 1) << 11; return result; } /* * The trick I used here allows to compare one ciphertext against all the - * DES_bs_crypt() outputs in just O(log2(ARCH_BITS)) operations. + * DES_bs_crypt() outputs in just O(log2(ARCH_BITS)) operations, assuming + * that DES_BS_VECTOR is 0 or 1. This routine isn't vectorized, yet. */ -int DES_bs_cmp_all(ARCH_WORD *binary, int count) +int DES_bs_cmp_all(ARCH_WORD *binary) { + register ARCH_WORD value, mask; register int bit; - register ARCH_WORD mask; +#if DES_BS_VECTOR + register int depth; +#endif + + for_each_depth() { + value = binary[0]; + + mask = DES_bs_all.B[0] DEPTH ^ -(value & 1); + mask |= DES_bs_all.B[1] DEPTH ^ -((value >> 1) & 1); + if (mask == ~(ARCH_WORD)0) goto next_depth; + mask |= DES_bs_all.B[2] DEPTH ^ -((value >> 2) & 1); + mask |= DES_bs_all.B[3] DEPTH ^ -((value >> 3) & 1); + if (mask == ~(ARCH_WORD)0) goto next_depth; + value >>= 4; + for (bit = 4; bit < 32; bit += 2) { + mask |= DES_bs_all.B[bit] DEPTH ^ + -(value & 1); + if (mask == ~(ARCH_WORD)0) goto next_depth; + mask |= DES_bs_all.B[bit + 1] DEPTH ^ + -((value >> 1) & 1); + if (mask == ~(ARCH_WORD)0) goto next_depth; + value >>= 2; + } - mask = 0; - if (DES_bs_mem_saving) - for (bit = 0; bit < ((count < 32) ? count : 32); bit++) { - mask |= DES_bs_all.B[bit] ^ - ((binary[0] & (1 << bit)) ? ~(ARCH_WORD)0 : 0); - if (mask == ~(ARCH_WORD)0) return 0; - } - else - for (bit = 0; bit < count; bit++) { - mask |= DES_bs_all.B[bit] ^ binary[bit]; - if (mask == ~(ARCH_WORD)0) return 0; + return 1; +next_depth: + ; } - return 1; + return 0; } int DES_bs_cmp_one(ARCH_WORD *binary, int count, int index) { register int bit; - register ARCH_WORD mask; - - if (DES_bs_mem_saving) { - for (bit = 0; bit < count; bit++) - if (((DES_bs_all.B[bit] >> index) ^ - (binary[bit >> 5] >> (bit & 0x1F))) & 1) return 0; - return 1; - } + init_depth(); - mask = (ARCH_WORD)1 << index; for (bit = 0; bit < count; bit++) - if ((DES_bs_all.B[bit] ^ binary[bit]) & mask) return 0; + if (((DES_bs_all.B[bit] DEPTH >> index) ^ + (binary[bit >> 5] >> (bit & 0x1F))) & 1) return 0; return 1; } diff -ruN john-1.6/src/DES_bs.h john-1.6.34/src/DES_bs.h --- john-1.6/src/DES_bs.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/DES_bs.h 2001-06-28 23:11:25.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -12,23 +12,57 @@ #include "arch.h" +#ifndef DES_BS_ALGORITHM_NAME #define DES_BS_ALGORITHM_NAME ARCH_BITS_STR "/" ARCH_BITS_STR " BS" +#endif -/* - * Non-zero when memory saving is enabled, with a performance impact. This - * should be either set at the very beginning, or never set at all. - */ -extern int DES_bs_mem_saving; +#if DES_BS_VECTOR +#define DES_BS_DEPTH (ARCH_BITS * DES_BS_VECTOR) +#else +#define DES_BS_DEPTH ARCH_BITS +#endif + +#if DES_BS_VECTOR +typedef ARCH_WORD DES_bs_vector[DES_BS_VECTOR]; +#else +#define DES_bs_vector ARCH_WORD +#endif /* * All bitslice DES parameters combined into one struct for more efficient - * cache usage. + * cache usage. Don't re-order unless you know what you're doing, as there + * is an optimization that would produce undefined results if you did. + * + * This must match the definition in x86-mmx.S. */ typedef struct { - ARCH_WORD *Kp[0x300]; /* Key schedule (key bit pointers) */ - ARCH_WORD *E[96]; /* Expansion function (data bit pointers) */ - ARCH_WORD K[56]; /* Keys */ - ARCH_WORD B[64]; /* Data blocks */ +#if DES_BS_EXPAND + ARCH_WORD *KSp[0x300]; /* Initial key schedule (key bit pointers) */ +#endif + union { + ARCH_WORD *p[0x300]; /* Key bit pointers */ +#if DES_BS_EXPAND + DES_bs_vector v[0x300]; /* Key bit values */ +#endif + } KS; /* Current key schedule */ + union { + ARCH_WORD *E[96]; /* Expansion function (data bit ptrs) */ + struct { +#if !DES_BS_VECTOR && ARCH_BITS >= 64 + unsigned char keys[DES_BS_DEPTH][8]; /* Current keys */ +#endif + unsigned char u[0x100]; /* Uppercase */ + } extras; /* Re-use the cache space for LM */ + } E; + DES_bs_vector K[56]; /* Keys */ + DES_bs_vector B[64]; /* Data blocks */ +#if DES_BS_ASM + DES_bs_vector tmp[16]; /* Miscellaneous temporary storage */ +#endif + unsigned char s[0x100]; /* Shift counts, used internally */ + int KS_updates; /* Key schedule updates counter */ + int keys_changed; /* If keys have changed since last expand */ + unsigned char keys[DES_BS_DEPTH][8]; /* Current keys */ } DES_bs_combined; extern DES_bs_combined DES_bs_all; @@ -36,7 +70,7 @@ /* * Initializes the internal structures. */ -extern void DES_bs_init(); +extern void DES_bs_init(int LM); /* * Sets a salt for DES_bs_crypt(). @@ -44,9 +78,12 @@ extern void DES_bs_set_salt(ARCH_WORD salt); /* - * Clears the bitslice keys, should be done before DES_bs_set_key() calls. + * Clears the bitslice keys if the key schedule has been updated too + * many times without being fully regenerated. This should be called + * whenever possible to reduce the impact of hardware faults. */ -extern void DES_bs_clear_keys(); +extern void DES_bs_clear_keys(void); +extern void DES_bs_clear_keys_LM(void); /* * Sets a key for DES_bs_crypt(). @@ -54,20 +91,44 @@ extern void DES_bs_set_key(char *key, int index); /* - * Main encryption routine, accepts the iteration count. + * Initializes the key schedule with actual key bits. Not for LM. + */ +#if DES_BS_EXPAND +extern void DES_bs_expand_keys(void); +#else +#define DES_bs_expand_keys() +#endif + +/* + * Sets a key for DES_bs_crypt_LM(). + */ +extern void DES_bs_set_key_LM(char *key, int index); + +/* + * Generic bitslice routine: 24 bit salts, variable iteration count. */ extern void DES_bs_crypt(int count); /* + * A simplified special-case version: 12 bit salts, 25 iterations. + */ +extern void DES_bs_crypt_25(void); + +/* + * Another special-case version: a non-zero IV, no salts, no iterations. + */ +extern void DES_bs_crypt_LM(void); + +/* * Converts an ASCII ciphertext to binary to be used with one of the * comparison functions. */ extern ARCH_WORD *DES_bs_get_binary(char *ciphertext); /* - * Calculates a hash for a ciphertext, for faster comparison. + * Similarly, for LM hashes. */ -extern int DES_bs_binary_hash(ARCH_WORD *binary, int count); +extern ARCH_WORD *DES_bs_get_binary_LM(char *ciphertext); /* * Calculates a hash for a DES_bs_crypt() output. @@ -75,14 +136,13 @@ extern int DES_bs_get_hash(int index, int count); /* - * Compares count bits of a given ciphertext against all the DES_bs_crypt() + * Compares 32 bits of a given ciphertext against all the DES_bs_crypt() * outputs and returns zero if no matches detected. */ -extern int DES_bs_cmp_all(ARCH_WORD *binary, int count); +extern int DES_bs_cmp_all(ARCH_WORD *binary); /* - * Same as the above, except the comparison is done against only one of the - * DES_bs_crypt() outputs. + * Compares count bits of a given ciphertext against one of the outputs. */ extern int DES_bs_cmp_one(ARCH_WORD *binary, int count, int index); diff -ruN john-1.6/src/DES_fmt.c john-1.6.34/src/DES_fmt.c --- john-1.6/src/DES_fmt.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/DES_fmt.c 2001-06-19 10:34:09.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include @@ -11,7 +11,7 @@ #include "formats.h" #define FORMAT_LABEL "des" -#define FORMAT_NAME "Standard DES" +#define FORMAT_NAME "Traditional DES" #define BENCHMARK_COMMENT "" #define BENCHMARK_LENGTH 0 @@ -31,18 +31,15 @@ #if DES_BS -#include "memory.h" #include "DES_bs.h" #define ALGORITHM_NAME DES_BS_ALGORITHM_NAME -#define BINARY_BITS 16 - -#define BINARY_SIZE (BINARY_BITS * ARCH_SIZE) +#define BINARY_SIZE ARCH_SIZE #define SALT_SIZE ARCH_SIZE -#define MIN_KEYS_PER_CRYPT ARCH_BITS -#define MAX_KEYS_PER_CRYPT ARCH_BITS +#define MIN_KEYS_PER_CRYPT DES_BS_DEPTH +#define MAX_KEYS_PER_CRYPT DES_BS_DEPTH #else @@ -58,10 +55,7 @@ #define MAX_KEYS_PER_CRYPT 0x80 #endif -#endif - static struct { -#if !DES_BS union { double dummy; struct { @@ -69,25 +63,16 @@ DES_binary binary; } data; } aligned; -#endif char key[PLAINTEXT_LENGTH]; } buffer[MAX_KEYS_PER_CRYPT]; -#if DES_BS +#endif -struct fmt_main fmt_DES; -static int binary_bits = BINARY_BITS; -static int keys_changed; - -static void init() -{ - if (mem_saving_level > 1) { - DES_bs_mem_saving = 1; - binary_bits = 32; - fmt_DES.params.binary_size = ARCH_SIZE; - } +#if DES_BS - DES_bs_init(); +static void init(void) +{ + DES_bs_init(0); } #endif @@ -98,14 +83,17 @@ if (!ciphertext[0] || !ciphertext[1]) return 0; - for (pos = &ciphertext[2]; atoi64[(ARCH_INDEX)*pos] != 0x7F; pos++); + for (pos = &ciphertext[2]; atoi64[ARCH_INDEX(*pos)] != 0x7F; pos++); if (*pos && *pos != ',') return 0; + if (atoi64[ARCH_INDEX(*(pos - 1))] & 3) return 0; + switch (pos - ciphertext) { case CIPHERTEXT_LENGTH_1: return 1; case CIPHERTEXT_LENGTH_2: + if (atoi64[ARCH_INDEX(ciphertext[12])] & 3) return 0; return 2; default: @@ -144,17 +132,17 @@ static int binary_hash_0(void *binary) { - return DES_bs_binary_hash((ARCH_WORD *)binary, 4); + return *(ARCH_WORD *)binary & 0xF; } static int binary_hash_1(void *binary) { - return DES_bs_binary_hash((ARCH_WORD *)binary, 8); + return *(ARCH_WORD *)binary & 0xFF; } static int binary_hash_2(void *binary) { - return DES_bs_binary_hash((ARCH_WORD *)binary, 12); + return *(ARCH_WORD *)binary & 0xFFF; } static int get_hash_0(int index) @@ -184,26 +172,18 @@ static void crypt_all(int count) { - int index; - - if (keys_changed) { - DES_bs_clear_keys(); - for (index = 0; index < count; index++) - DES_bs_set_key(buffer[index].key, index); - keys_changed = 0; - } - - DES_bs_crypt(25); + DES_bs_expand_keys(); + DES_bs_crypt_25(); } static int cmp_all(void *binary, int count) { - return DES_bs_cmp_all((ARCH_WORD *)binary, binary_bits); + return DES_bs_cmp_all((ARCH_WORD *)binary); } static int cmp_one(void *binary, int index) { - return DES_bs_cmp_one((ARCH_WORD *)binary, binary_bits, index); + return DES_bs_cmp_one((ARCH_WORD *)binary, 32, index); } static int cmp_exact(char *source, int index) @@ -303,23 +283,24 @@ #endif +#if !DES_BS static void set_key(char *key, int index) { -#if DES_BS - keys_changed = 1; -#else DES_std_set_key(key); memcpy(buffer[index].aligned.data.KS, DES_KS_current, sizeof(DES_KS)); -#endif - memcpy(buffer[index].key, key, PLAINTEXT_LENGTH); } +#endif static char *get_key(int index) { static char out[PLAINTEXT_LENGTH + 1]; +#if DES_BS + memcpy(out, DES_bs_all.keys[index], PLAINTEXT_LENGTH); +#else memcpy(out, buffer[index].key, PLAINTEXT_LENGTH); +#endif out[PLAINTEXT_LENGTH] = 0; return out; @@ -337,7 +318,11 @@ SALT_SIZE, MIN_KEYS_PER_CRYPT, MAX_KEYS_PER_CRYPT, +#if DES_BS + FMT_CASE | FMT_BS, +#else FMT_CASE, +#endif tests }, { #if DES_BS @@ -361,8 +346,17 @@ }, salt_hash, set_salt, +#if DES_BS + DES_bs_set_key, +#else set_key, +#endif get_key, +#if DES_BS + DES_bs_clear_keys, +#else + fmt_default_clear_keys, +#endif crypt_all, { get_hash_0, diff -ruN john-1.6/src/DES_std.c john-1.6.34/src/DES_std.c --- john-1.6/src/DES_std.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/DES_std.c 2001-02-16 06:50:21.000000000 +0100 @@ -1,26 +1,17 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include #include "arch.h" +#include "common.h" #include "DES_std.h" -#if ARCH_GENERIC - -#if ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7)) || (__GNUC__ > 2) -#define DES_ALIGN __attribute__ ((aligned (128))) -#else -#define DES_ALIGN /* nothing */ -#endif - -#endif - #if ARCH_BITS >= 64 -#if ARCH_GENERIC +#if !DES_ASM static union { double dummy; @@ -31,7 +22,7 @@ ARCH_WORD SPE_W[4][64 * 64]; #endif } data; -} DES_ALIGN DES_all; +} CC_CACHE_ALIGN DES_all; #else @@ -46,7 +37,7 @@ #else -#if ARCH_GENERIC +#if !DES_ASM static union { double dummy; @@ -60,7 +51,7 @@ ARCH_WORD SPE_W[4][64 * 64][2]; #endif } data; -} DES_ALIGN DES_all; +} CC_CACHE_ALIGN DES_all; #else @@ -80,7 +71,7 @@ #endif -#if ARCH_GENERIC +#if !DES_ASM #define DES_KS_copy DES_all.data.KS #define DES_SPE_F DES_all.data.SPE_F @@ -91,8 +82,8 @@ DES_binary DES_IV; ARCH_WORD DES_count; -DES_KS DES_ALIGN DES_KS_current; -DES_KS DES_ALIGN DES_KS_table[8][128]; +DES_KS CC_CACHE_ALIGN DES_KS_current; +DES_KS CC_CACHE_ALIGN DES_KS_table[8][128]; #endif @@ -100,7 +91,7 @@ static char DES_key[16]; #if DES_COPY -#if !ARCH_GENERIC +#if DES_ASM extern DES_KS DES_KS_copy; #endif unsigned ARCH_WORD *DES_out; @@ -122,7 +113,7 @@ #if (ARCH_BITS >= 64 && (DES_SCALE || !DES_MASK) || DES_128K) && \ DES_SIZE_FIX == 2 /* - * 64 bit architectures which can shift addresses left by 1 bit with no extra + * 64-bit architectures which can shift addresses left by 1 bit with no extra * time required (for example by adding a register to itself). */ #define DES_INDEX(SPE, i) \ @@ -130,7 +121,7 @@ #else #if DES_SIZE_FIX == 0 /* - * 64 bit architectures which can shift addresses left by 3 bits (but maybe + * 64-bit architectures which can shift addresses left by 3 bits (but maybe * not by 1) with no extra time required (for example by using the S8ADDQ * instruction on DEC Alphas; we would need an ADDQ anyway). */ @@ -160,7 +151,7 @@ #if DES_MASK #if ARCH_BITS >= 64 && !DES_SCALE && DES_SIZE_FIX == 2 /* - * This method might be good for some 64 bit architectures with no complicated + * This method might be good for some 64-bit architectures with no complicated * addressing modes supported. It would be the best one for DEC Alphas if they * didn't have the S8ADDQ instruction. */ @@ -192,12 +183,18 @@ #endif #define DES_KS_INDEX(i) (DES_KS_copy + (i * (16 / DES_SIZE))) -#define DES_TO_6_BIT(x) \ +#define DES_24_TO_32(x) \ (((x) & 077) | \ (((x) & 07700) << 2) | \ (((x) & 0770000) << 4) | \ (((x) & 077000000) << 6)) +#define DES_16_TO_32(x) \ + ((((x) & 0xF) << 1) | \ + (((x) & 0xF0) << 5) | \ + (((x) & 0xF00) << 9) | \ + (((x) & 0xF000) << 13)) + #if DES_128K #define DES_UNDO_SIZE_FIX(x) \ ((((x) >> 1) & 0xFF00FF00) | (((x) & 0x00FF00FF) >> 3)) @@ -294,58 +291,33 @@ 44, 45, 46, 47, 60, 61, 62, 63 }; -unsigned char DES_K_bits[0x300] = { - 9, 50, 33, 59, 48, 16, 32, 56, 1, 8, 18, 41, 2, 34, 25, 24, - 43, 57, 58, 0, 35, 26, 17, 40, 21, 27, 38, 53, 36, 3, 46, 29, - 4, 52, 22, 28, 60, 20, 37, 62, 14, 19, 44, 13, 12, 61, 54, 30, - 1, 42, 25, 51, 40, 8, 24, 48, 58, 0, 10, 33, 59, 26, 17, 16, - 35, 49, 50, 57, 56, 18, 9, 32, 13, 19, 30, 45, 28, 62, 38, 21, - 27, 44, 14, 20, 52, 12, 29, 54, 6, 11, 36, 5, 4, 53, 46, 22, - 50, 26, 9, 35, 24, 57, 8, 32, 42, 49, 59, 17, 43, 10, 1, 0, - 48, 33, 34, 41, 40, 2, 58, 16, 60, 3, 14, 29, 12, 46, 22, 5, - 11, 28, 61, 4, 36, 27, 13, 38, 53, 62, 20, 52, 19, 37, 30, 6, - 34, 10, 58, 48, 8, 41, 57, 16, 26, 33, 43, 1, 56, 59, 50, 49, - 32, 17, 18, 25, 24, 51, 42, 0, 44, 54, 61, 13, 27, 30, 6, 52, - 62, 12, 45, 19, 20, 11, 60, 22, 37, 46, 4, 36, 3, 21, 14, 53, - 18, 59, 42, 32, 57, 25, 41, 0, 10, 17, 56, 50, 40, 43, 34, 33, - 16, 1, 2, 9, 8, 35, 26, 49, 28, 38, 45, 60, 11, 14, 53, 36, - 46, 27, 29, 3, 4, 62, 44, 6, 21, 30, 19, 20, 54, 5, 61, 37, - 2, 43, 26, 16, 41, 9, 25, 49, 59, 1, 40, 34, 24, 56, 18, 17, - 0, 50, 51, 58, 57, 48, 10, 33, 12, 22, 29, 44, 62, 61, 37, 20, - 30, 11, 13, 54, 19, 46, 28, 53, 5, 14, 3, 4, 38, 52, 45, 21, - 51, 56, 10, 0, 25, 58, 9, 33, 43, 50, 24, 18, 8, 40, 2, 1, - 49, 34, 35, 42, 41, 32, 59, 17, 27, 6, 13, 28, 46, 45, 21, 4, - 14, 62, 60, 38, 3, 30, 12, 37, 52, 61, 54, 19, 22, 36, 29, 5, - 35, 40, 59, 49, 9, 42, 58, 17, 56, 34, 8, 2, 57, 24, 51, 50, - 33, 18, 48, 26, 25, 16, 43, 1, 11, 53, 60, 12, 30, 29, 5, 19, - 61, 46, 44, 22, 54, 14, 27, 21, 36, 45, 38, 3, 6, 20, 13, 52, - 56, 32, 51, 41, 1, 34, 50, 9, 48, 26, 0, 59, 49, 16, 43, 42, - 25, 10, 40, 18, 17, 8, 35, 58, 3, 45, 52, 4, 22, 21, 60, 11, - 53, 38, 36, 14, 46, 6, 19, 13, 28, 37, 30, 62, 61, 12, 5, 44, - 40, 16, 35, 25, 50, 18, 34, 58, 32, 10, 49, 43, 33, 0, 56, 26, - 9, 59, 24, 2, 1, 57, 48, 42, 54, 29, 36, 19, 6, 5, 44, 62, - 37, 22, 20, 61, 30, 53, 3, 60, 12, 21, 14, 46, 45, 27, 52, 28, - 24, 0, 48, 9, 34, 2, 18, 42, 16, 59, 33, 56, 17, 49, 40, 10, - 58, 43, 8, 51, 50, 41, 32, 26, 38, 13, 20, 3, 53, 52, 28, 46, - 21, 6, 4, 45, 14, 37, 54, 44, 27, 5, 61, 30, 29, 11, 36, 12, - 8, 49, 32, 58, 18, 51, 2, 26, 0, 43, 17, 40, 1, 33, 24, 59, - 42, 56, 57, 35, 34, 25, 16, 10, 22, 60, 4, 54, 37, 36, 12, 30, - 5, 53, 19, 29, 61, 21, 38, 28, 11, 52, 45, 14, 13, 62, 20, 27, - 57, 33, 16, 42, 2, 35, 51, 10, 49, 56, 1, 24, 50, 17, 8, 43, - 26, 40, 41, 48, 18, 9, 0, 59, 6, 44, 19, 38, 21, 20, 27, 14, - 52, 37, 3, 13, 45, 5, 22, 12, 62, 36, 29, 61, 60, 46, 4, 11, - 41, 17, 0, 26, 51, 48, 35, 59, 33, 40, 50, 8, 34, 1, 57, 56, - 10, 24, 25, 32, 2, 58, 49, 43, 53, 28, 3, 22, 5, 4, 11, 61, - 36, 21, 54, 60, 29, 52, 6, 27, 46, 20, 13, 45, 44, 30, 19, 62, - 25, 1, 49, 10, 35, 32, 48, 43, 17, 24, 34, 57, 18, 50, 41, 40, - 59, 8, 9, 16, 51, 42, 33, 56, 37, 12, 54, 6, 52, 19, 62, 45, - 20, 5, 38, 44, 13, 36, 53, 11, 30, 4, 60, 29, 28, 14, 3, 46, - 17, 58, 41, 2, 56, 24, 40, 35, 9, 16, 26, 49, 10, 42, 33, 32, - 51, 0, 1, 8, 43, 34, 25, 48, 29, 4, 46, 61, 44, 11, 54, 37, - 12, 60, 30, 36, 5, 28, 45, 3, 22, 27, 52, 21, 20, 6, 62, 38 +unsigned char DES_PC1[56] = { + 56, 48, 40, 32, 24, 16, 8, + 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, + 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, + 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, + 20, 12, 4, 27, 19, 11, 3 +}; + +unsigned char DES_ROT[16] = { + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 +}; + +unsigned char DES_PC2[48] = { + 13, 16, 10, 23, 0, 4, + 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, + 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, + 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, + 45, 41, 49, 35, 28, 31 }; -static void init_SPE() +static void init_SPE(void) { int box, index, row, column, bit; ARCH_WORD mask, l, h; @@ -366,14 +338,14 @@ h = l = 0; for (bit = 0; bit < 24; bit++) { if (((unsigned ARCH_WORD)0x80000000 >> - DES_P[DES_E[bit]]) & mask) + DES_P[ARCH_INDEX(DES_E[bit])]) & mask) l |= 1 << bit; if (((unsigned ARCH_WORD)0x80000000 >> - DES_P[DES_E[bit + 24]]) & mask) + DES_P[ARCH_INDEX(DES_E[bit + 24])]) & mask) h |= 1 << bit; } - l = DES_TO_6_BIT(l); h = DES_TO_6_BIT(h); + l = DES_24_TO_32(l); h = DES_24_TO_32(h); #if ARCH_BITS >= 64 DES_SPE[box][index] = @@ -386,7 +358,7 @@ } } -static void init_IP_E() +static void init_IP_E(void) { int src, dst, dst1, dst2; int chunk, mask, value; @@ -396,7 +368,7 @@ for (dst1 = 0; dst1 < 8; dst1++) for (dst2 = 0; dst2 < 6; dst2++) { dst = (dst1 << 3) + dst2; - src = DES_IP[DES_E[dst1 * 6 + dst2]]; + src = DES_IP[ARCH_INDEX(DES_E[dst1 * 6 + dst2])]; if (src >= 32) src -= 32; else src--; src ^= 7; @@ -415,7 +387,7 @@ } } -static void init_C_FP() +static void init_C_FP(void) { int src, dst; int chunk, mask, value; @@ -423,7 +395,7 @@ memset(DES_C_FP, 0, sizeof(DES_C_FP)); for (src = 0; src < 64; src++) { - dst = DES_IP[DES_C[src]] ^ 7; + dst = DES_IP[ARCH_INDEX(DES_C[src])] ^ 7; chunk = src >> 2; mask = 1 << (src & 3); @@ -440,12 +412,12 @@ } } -static void init_KS() +static void init_KS(void) { - int pos, chr, bit, ofs, index; + int pos, chr, round, bit, ofs; unsigned char block[64]; - unsigned char *k; - ARCH_WORD value; + ARCH_WORD value[2]; + int k, p, q, r, s; memset(block, 0, sizeof(block)); @@ -454,22 +426,31 @@ for (bit = 0; bit < 7; bit++) block[(pos << 3) + bit] = (chr >> (6 - bit)) & 1; - k = DES_K_bits; - for (index = 0; index < 32; index++) { - value = 0; - for (ofs = 0; ofs < 32; ofs += 8) - for (bit = 0; bit < 6; bit++) value |= - (ARCH_WORD)block[*k++] << (ofs + bit); - -#if ARCH_BITS >= 64 - if (index & 1) - DES_KS_table[pos][chr][index >> 1] |= - DES_DO_SIZE_FIX(value) << 32; - else - DES_KS_table[pos][chr][index >> 1] = - DES_DO_SIZE_FIX(value); -#else - DES_KS_table[pos][chr][index] = DES_DO_SIZE_FIX(value); + s = 0; + for (round = 0; round < 16; round++) { + s += DES_ROT[round]; + value[0] = value[1] = 0; + k = 0; + for (ofs = 0; ofs < 64; ofs += 8) + for (bit = 0; bit < 6; bit++) { + p = DES_PC2[k++]; + q = p < 28 ? 0 : 28; + p += s; + while (p >= 28) p -= 28; + r = DES_PC1[p + q]; + value[ofs >> 5] |= (ARCH_WORD)block[r] << + ((ofs & 31) + bit); + } + +#if ARCH_BITS >= 64 + DES_KS_table[pos][chr][round] = + DES_DO_SIZE_FIX(value[0]) | + (DES_DO_SIZE_FIX(value[1]) << 32); +#else + DES_KS_table[pos][chr][round << 1] = + DES_DO_SIZE_FIX(value[0]); + DES_KS_table[pos][chr][(round << 1) + 1] = + DES_DO_SIZE_FIX(value[1]); #endif } } @@ -479,7 +460,7 @@ memcpy(DES_KS_current, DES_KS_table, sizeof(DES_KS)); } -void DES_std_init() +void DES_std_init(void) { init_SPE(); init_IP_E(); @@ -618,12 +599,12 @@ #endif memcpy(DES_KS_current, - DES_KS_table[0][(ARCH_INDEX)(DES_key[0] = key[0] & 0x7F)], + DES_KS_table[0][ARCH_INDEX(DES_key[0] = key[0] & 0x7F)], sizeof(DES_KS)); pos = (DES_KS *)DES_KS_table[1][0]; for (i = 1; i < 8; i++) { - DES_xor_key1(pos[(ARCH_INDEX)(DES_key[i] = key[i] & 0x7F)]); + DES_xor_key1(pos[ARCH_INDEX(DES_key[i] = key[i] & 0x7F)]); pos += 128; } } @@ -635,7 +616,8 @@ register ARCH_WORD *value1, *value2; #endif - for (k = i = 0; (j = key[i]) && (l = DES_key[i]); i++) + j = key[0]; + for (k = i = 0; (l = DES_key[i]) && (j = key[i]); i++) if (j != l) k += 3; if (j) { @@ -650,7 +632,7 @@ if ((k < (j << 1)) && (++DES_KS_updates & 0xFFF)) { j = 0; l = 1; - for (i = 0; (k = key[i]) && i < 8; i++) { + for (i = 0; i < 8 && (k = key[i]); i++) { if (l) if (k == (l = DES_key[j++])) continue; @@ -669,7 +651,7 @@ sizeof(DES_KS)); if (k) - for (i = 1; (k = key[i]) && i < 8; i++) + for (i = 1; i < 8 && (k = key[i]); i++) DES_xor_key1(DES_KS_table[i][k & 0x7F]); } @@ -833,7 +815,7 @@ */ #if DES_MASK #if DES_SCALE -/* 64 bit, 4K, mask, scale */ +/* 64-bit, 4K, mask, scale */ #define DES_ROUND(L, H, B) \ T = DES_INDEX(DES_SPE_F[0], DES_D & DES_MASK_6); \ B ^= DES_INDEX(DES_SPE_F[1], (DES_D >> 8) & DES_MASK_6); \ @@ -851,7 +833,7 @@ * (which is done at compile time), I moved the extra shift out of the mask, * which allows doing this with special addressing modes, where possible. */ -/* 64 bit, 4K, mask, no scale */ +/* 64-bit, 4K, mask, no scale */ #define DES_ROUND(L, H, B) \ T = DES_INDEX(DES_SPE_F[0], (DES_D & (DES_MASK_6 >> 1)) << 1); \ B ^= DES_INDEX(DES_SPE_F[1], (DES_D >> 7) & DES_MASK_6); \ @@ -863,7 +845,7 @@ B ^= T ^ DES_INDEX(DES_SPE_F[7], (DES_D >> 55) & DES_MASK_6); #endif #else -/* 64 bit, 4K, store/load, scale */ +/* 64-bit, 4K, store/load, scale */ #define DES_ROUND(L, H, B) \ T = DES_INDEX(DES_SPE_F[0], DES_B0); \ B ^= DES_INDEX(DES_SPE_F[1], DES_B1); \ @@ -875,7 +857,7 @@ B ^= T ^ DES_INDEX(DES_SPE_F[7], DES_B7); #endif #else -/* 64 bit, 128K, mask, no scale */ +/* 64-bit, 128K, mask, no scale */ #define DES_ROUND(L, H, B) \ B ^= DES_INDEX(DES_SPE_W[0], DES_D & 0xFFFF); \ B ^= DES_INDEX(DES_SPE_W[1], (DES_D >>= 16) & 0xFFFF); \ @@ -885,7 +867,7 @@ #else #if !DES_128K #if DES_MASK -/* 32 bit, 4K, mask */ +/* 32-bit, 4K, mask */ #define DES_ROUND(L, H, B) \ L ^= DES_INDEX(DES_SPE_L[0], DES_Dl & DES_MASK_6); \ H ^= DES_INDEX(DES_SPE_H[0], DES_Dl & DES_MASK_6); \ @@ -904,7 +886,7 @@ L ^= DES_INDEX(DES_SPE_L[7], (DES_Dh >>= 8) & DES_MASK_6); \ H ^= DES_INDEX(DES_SPE_H[7], DES_Dh & DES_MASK_6); #else -/* 32 bit, 4K, store/load */ +/* 32-bit, 4K, store/load */ #define DES_ROUND(L, H, B) \ L ^= DES_INDEX(DES_SPE_L[0], DES_B0); \ H ^= DES_INDEX(DES_SPE_H[0], DES_B0); \ @@ -924,7 +906,7 @@ H ^= DES_INDEX(DES_SPE_H[7], DES_B7); #endif #else -/* 32 bit, 128K, mask */ +/* 32-bit, 128K, mask */ #define DES_ROUND(L, H, B) \ L ^= DES_INDEX_L(DES_SPE_W[0], DES_Dl & 0xFFFF); \ H ^= DES_INDEX_H(DES_SPE_W[0], DES_Dl & 0xFFFF); \ @@ -954,7 +936,7 @@ #endif #if DES_COPY -static void crypt_body() +static void crypt_body(void) #else void DES_std_crypt(DES_KS KS, DES_binary DES_out) #endif @@ -1064,12 +1046,12 @@ ARCH_WORD DES_raw_get_salt(char *ciphertext) { - if (ciphertext[13]) return DES_atoi64[(ARCH_INDEX)ciphertext[5]] | - ((ARCH_WORD)DES_atoi64[(ARCH_INDEX)ciphertext[6]] << 6) | - ((ARCH_WORD)DES_atoi64[(ARCH_INDEX)ciphertext[7]] << 12) | - ((ARCH_WORD)DES_atoi64[(ARCH_INDEX)ciphertext[8]] << 18); - else return DES_atoi64[(ARCH_INDEX)ciphertext[0]] | - ((ARCH_WORD)DES_atoi64[(ARCH_INDEX)ciphertext[1]] << 6); + if (ciphertext[13]) return DES_atoi64[ARCH_INDEX(ciphertext[5])] | + ((ARCH_WORD)DES_atoi64[ARCH_INDEX(ciphertext[6])] << 6) | + ((ARCH_WORD)DES_atoi64[ARCH_INDEX(ciphertext[7])] << 12) | + ((ARCH_WORD)DES_atoi64[ARCH_INDEX(ciphertext[8])] << 18); + else return DES_atoi64[ARCH_INDEX(ciphertext[0])] | + ((ARCH_WORD)DES_atoi64[ARCH_INDEX(ciphertext[1])] << 6); } ARCH_WORD DES_std_get_salt(char *ciphertext) @@ -1077,75 +1059,72 @@ ARCH_WORD salt; salt = DES_raw_get_salt(ciphertext); - salt = DES_TO_6_BIT(salt); + salt = DES_24_TO_32(salt); return DES_DO_SIZE_FIX(salt); } ARCH_WORD DES_raw_get_count(char *ciphertext) { - if (ciphertext[13]) return DES_atoi64[(ARCH_INDEX)ciphertext[1]] | - ((ARCH_WORD)DES_atoi64[(ARCH_INDEX)ciphertext[2]] << 6) | - ((ARCH_WORD)DES_atoi64[(ARCH_INDEX)ciphertext[3]] << 12) | - ((ARCH_WORD)DES_atoi64[(ARCH_INDEX)ciphertext[4]] << 18); + if (ciphertext[13]) return DES_atoi64[ARCH_INDEX(ciphertext[1])] | + ((ARCH_WORD)DES_atoi64[ARCH_INDEX(ciphertext[2])] << 6) | + ((ARCH_WORD)DES_atoi64[ARCH_INDEX(ciphertext[3])] << 12) | + ((ARCH_WORD)DES_atoi64[ARCH_INDEX(ciphertext[4])] << 18); else return 25; } -ARCH_WORD *DES_raw_get_binary(char *ciphertext) +ARCH_WORD *DES_do_IP(ARCH_WORD in[2]) { - static ARCH_WORD masks[8] = { - 0x1000, 0x0800, 0x0400, 0x0200, 0x0010, 0x0008, 0x0004, 0x0002 - }; + static ARCH_WORD out[2]; + int src, dst; - static ARCH_WORD out[4]; + out[0] = out[1] = 0; + for (dst = 0; dst < 64; dst++) { + src = DES_IP[dst ^ 0x20]; + + if (in[src >> 5] & (1 << (src & 0x1F))) + out[dst >> 5] |= 1 << (dst & 0x1F); + } + + return out; +} - int ofs, chr, bit, index, value; - unsigned char block[66], *ptr; - ARCH_WORD mask1, mask2; - ARCH_WORD Rl, Rh, Ll, Lh; +ARCH_WORD *DES_raw_get_binary(char *ciphertext) +{ + ARCH_WORD block[3]; + ARCH_WORD mask; + int ofs, chr, src, dst, value; if (ciphertext[13]) ofs = 9; else ofs = 2; - ptr = block; + block[0] = block[1] = 0; + dst = 0; for (chr = 0; chr < 11; chr++) { - value = DES_atoi64[(ARCH_INDEX)ciphertext[chr + ofs]]; - mask1 = 0x20; + value = DES_atoi64[ARCH_INDEX(ciphertext[chr + ofs])]; + mask = 0x20; - for (bit = 0; bit < 6; bit++) { - *ptr++ = value & mask1; - mask1 >>= 1; + for (src = 0; src < 6; src++) { + if (value & mask) + block[dst >> 5] |= 1 << (dst & 0x1F); + mask >>= 1; + dst++; } } - Lh = Ll = Rh = Rl = 0; - ptr = block; - - for (index = 0; index < 8; index++) { - mask2 = (mask1 = masks[index]) << 16; - - if (*ptr++) Rl |= mask1; - if (*ptr++) Ll |= mask1; - if (*ptr++) Rl |= mask2; - if (*ptr++) Ll |= mask2; - if (*ptr++) Rh |= mask1; - if (*ptr++) Lh |= mask1; - if (*ptr++) Rh |= mask2; - if (*ptr++) Lh |= mask2; - } - - out[0] = Rl; - out[1] = Rh; - out[2] = Ll; - out[3] = Lh; - - return out; + return DES_do_IP(block); } ARCH_WORD *DES_std_get_binary(char *ciphertext) { - ARCH_WORD *out; + static ARCH_WORD out[4]; + ARCH_WORD *raw; ARCH_WORD salt, mask; - out = DES_raw_get_binary(ciphertext); + raw = DES_raw_get_binary(ciphertext); + + out[0] = DES_16_TO_32(raw[0]); + out[1] = DES_16_TO_32(raw[0] >> 16); + out[2] = DES_16_TO_32(raw[1]); + out[3] = DES_16_TO_32(raw[1] >> 16); out[0] = DES_DO_SIZE_FIX(out[0]); out[1] = DES_DO_SIZE_FIX(out[1]); diff -ruN john-1.6/src/DES_std.h john-1.6.34/src/DES_std.h --- john-1.6/src/DES_std.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/DES_std.h 2000-03-24 22:22:20.000000000 +0100 @@ -1,10 +1,10 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* - * Standard DES implementation. + * "Standard" (non-bitslice) DES implementation. */ #ifndef _JOHN_DES_STD_H @@ -19,14 +19,12 @@ #endif /* - * Expansion table. + * Various DES tables exported for use by other implementations. */ extern unsigned char DES_E[48]; - -/* - * Key bits schedule. - */ -extern unsigned char DES_K_bits[0x300]; +extern unsigned char DES_PC1[56]; +extern unsigned char DES_ROT[16]; +extern unsigned char DES_PC2[48]; /* * Current key schedule. @@ -108,10 +106,9 @@ (DES_STD_HASH_1(x) | \ (((x) >> (DES_SIZE_FIX + 9)) & 0xF00)) +#ifndef DES_STD_ALGORITHM_NAME #if ARCH_BITS >= 64 #define DES_STD_ALGORITHM_BITS "48/" ARCH_BITS_STR -#elif DES_X2 -#define DES_STD_ALGORITHM_BITS "48/64" #else #define DES_STD_ALGORITHM_BITS "24/32" #endif @@ -122,11 +119,12 @@ #endif #define DES_STD_ALGORITHM_NAME \ DES_STD_ALGORITHM_BITS " " DES_STD_ALGORITHM_SIZE +#endif /* * Initializes the internal structures. */ -extern void DES_std_init(); +extern void DES_std_init(void); /* * Sets a salt for DES_std_crypt(). @@ -178,6 +176,13 @@ extern ARCH_WORD DES_raw_get_count(char *ciphertext); /* + * Does the Initial Permutation; to be used at startup only (doesn't + * require that DES_std_init() has been called, is not as fast as it + * could be). + */ +extern ARCH_WORD *DES_do_IP(ARCH_WORD in[2]); + +/* * Converts an ASCII ciphertext to binary. */ extern ARCH_WORD *DES_raw_get_binary(char *ciphertext); diff -ruN john-1.6/src/detect.c john-1.6.34/src/detect.c --- john-1.6/src/detect.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/detect.c 2000-05-08 09:04:46.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* @@ -12,8 +12,12 @@ int main(int argc, char **argv) { int value = 1; + int size_log; - if (argc != 6) return 1; + if (argc != 7) return 1; + + size_log = 0; + while (sizeof(long) * 8 != 1 << size_log) size_log++; puts( "/*\n" @@ -24,18 +28,18 @@ "#define _JOHN_ARCH_H\n"); printf( -"#define ARCH_GENERIC\t\t\t%d\n" "#define ARCH_WORD\t\t\tlong\n" "#define ARCH_SIZE\t\t\t%d\n" "#define ARCH_BITS\t\t\t%d\n" +"#define ARCH_BITS_LOG\t\t\t%d\n" "#define ARCH_BITS_STR\t\t\t\"%d\"\n" "#define ARCH_LITTLE_ENDIAN\t\t%d\n" "#define ARCH_INT_GT_32\t\t\t%d\n" "#define ARCH_ALLOWS_UNALIGNED\t\t0\n" #ifdef __alpha__ -"#define ARCH_INDEX\t\t\tunsigned long\n" +"#define ARCH_INDEX(x)\t\t\t((unsigned long)(unsigned char)(x))\n" #else -"#define ARCH_INDEX\t\t\tunsigned int\n" +"#define ARCH_INDEX(x)\t\t\t((unsigned int)(unsigned char)(x))\n" #endif "\n" #ifdef OS_TIMER @@ -49,13 +53,9 @@ "#define OS_FLOCK\t\t\t0\n" #endif "\n", -#ifdef DES_ASM - 0, -#else - 1, -#endif (int)sizeof(long), (int)(sizeof(long) * 8), + size_log, (int)(sizeof(long) * 8), (int)(*(char *)&value), (sizeof(int) > 4) ? 1 : 0); @@ -125,9 +125,13 @@ printf( "#define DES_COPY\t\t\t%c\n" +"#define DES_BS_ASM\t\t\t0\n" "#define DES_BS\t\t\t\t%c\n" +"#define DES_BS_VECTOR\t\t\t0\n" +"#define DES_BS_EXPAND\t\t\t1\n" "\n" "#define MD5_ASM\t\t\t\t0\n" +"#define MD5_X2\t\t\t\t%c\n" "#define MD5_IMM\t\t\t\t%c\n" "\n" "#define BF_ASM\t\t\t\t0\n" @@ -137,7 +141,8 @@ argv[2][0], argv[3][0], argv[4][0], - argv[5][0]); + argv[5][0], + argv[6][0]); return 0; } diff -ruN john-1.6/src/external.c john-1.6.34/src/external.c --- john-1.6/src/external.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/external.c 2001-06-16 09:46:21.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include @@ -8,7 +8,6 @@ #include "misc.h" #include "params.h" -#include "path.h" #include "signals.h" #include "compiler.h" #include "loader.h" @@ -20,7 +19,7 @@ static char int_word[PLAINTEXT_BUFFER_SIZE]; static char rec_word[PLAINTEXT_BUFFER_SIZE]; -static char *ext_mode = NULL; +char *ext_mode = NULL; static c_int ext_word[PLAINTEXT_BUFFER_SIZE]; @@ -30,13 +29,14 @@ ext_word }; -static struct c_ident *f_generate, *f_filter; +static struct c_ident *f_generate; +struct c_ident *f_filter; static struct cfg_list *ext_source; static struct cfg_line *ext_line; static int ext_pos; -static int ext_getchar() +static int ext_getchar(void) { char c; @@ -49,7 +49,7 @@ return '\n'; } -static void ext_rewind() +static void ext_rewind(void) { ext_line = ext_source->head; ext_pos = 0; @@ -66,7 +66,7 @@ if (!ext_line) ext_line = ext_source->tail; fprintf(stderr, "Compiler error in %s at line %d: %s\n", - path_expand(CFG_NAME), ext_line->number, + cfg_name, ext_line->number, c_errors[c_errno]); error(); } @@ -80,14 +80,12 @@ ext_mode = mode; } -int ext_filter(char *word) +int ext_filter_body(char *in, char *out) { unsigned char *internal; c_int *external; - if (!ext_mode || !f_filter) return 1; - - internal = (unsigned char *)word; + internal = (unsigned char *)in; external = ext_word; while (*internal) *external++ = *internal++; @@ -95,9 +93,9 @@ c_execute(f_filter); - if (word[0] && !ext_word[0]) return 0; + if (in[0] && !ext_word[0]) return 0; - internal = (unsigned char *)word; + internal = (unsigned char *)out; external = ext_word; while (*external) *internal++ = *external++; @@ -136,7 +134,7 @@ return 0; } -static void fix_state() +static void fix_state(void) { strcpy(rec_word, int_word); } diff -ruN john-1.6/src/external.h john-1.6.34/src/external.h --- john-1.6/src/external.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/external.h 2001-06-16 09:47:26.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -13,6 +13,12 @@ #include "loader.h" /* + * Defined for use in the ext_filter() macro, below. + */ +extern char *ext_mode; +extern struct c_ident *f_filter; + +/* * Initializes an external mode. */ extern void ext_init(char *mode); @@ -20,7 +26,13 @@ /* * Calls an external word filter. Returns 0 if the word is rejected. */ -extern int ext_filter(char *word); +#define ext_filter(word) \ + (!ext_mode || !f_filter || ext_filter_body(word, word)) + +/* + * The actual implementation of ext_filter(); use the macro instead. + */ +extern int ext_filter_body(char *in, char *out); /* * Runs the external mode cracker. diff -ruN john-1.6/src/formats.c john-1.6.34/src/formats.c --- john-1.6/src/formats.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/formats.c 2001-06-16 08:07:01.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include @@ -28,24 +28,28 @@ } } -int fmt_self_test(struct fmt_main *format) +char *fmt_self_test(struct fmt_main *format) { + static char s_size[32]; struct fmt_tests *current; char *ciphertext, *plaintext; - int size; + int index, max, size; void *binary, *salt; if (format->params.plaintext_length > PLAINTEXT_BUFFER_SIZE - 3) - return 1; + return "length"; - if (format->methods.valid("*")) return 1; + if (format->methods.valid("*")) return "valid"; fmt_init(format); - if (!(current = format->params.tests)) return 0; + if (!(current = format->params.tests)) return NULL; + index = 0; max = format->params.max_keys_per_crypt; + if (max > 2 && !(format->params.flags & FMT_BS)) max = 2; do { - if (format->methods.valid(current->ciphertext) != 1) break; + if (format->methods.valid(current->ciphertext) != 1) + return "valid"; ciphertext = format->methods.split(current->ciphertext, 0); plaintext = current->plaintext; @@ -53,30 +57,40 @@ salt = format->methods.salt(ciphertext); if ((unsigned int)format->methods.salt_hash(salt) >= - SALT_HASH_SIZE) break; + SALT_HASH_SIZE) + return "salt_hash"; format->methods.set_salt(salt); - format->methods.set_key(current->plaintext, 0); + format->methods.set_key(current->plaintext, index); - format->methods.crypt_all(1); + format->methods.crypt_all(index + 1); for (size = 0; size < 3; size++) - if (format->methods.get_hash[size](0) != - format->methods.binary_hash[size](binary)) break; - if (size < 3) break; - - if (!format->methods.cmp_all(binary, 1)) break; - if (!format->methods.cmp_one(binary, 0)) break; - if (!format->methods.cmp_exact(ciphertext, 0)) break; + if (format->methods.get_hash[size](index) != + format->methods.binary_hash[size](binary)) { + sprintf(s_size, "get_hash[%d]", size); + return s_size; + } + + if (!format->methods.cmp_all(binary, index + 1)) + return "cmp_all"; + if (!format->methods.cmp_one(binary, index)) + return "cmp_one"; + if (!format->methods.cmp_exact(ciphertext, index)) + return "cmp_exact"; + + if (strncmp(format->methods.get_key(index), plaintext, + format->params.plaintext_length)) + return "get_key"; - if (strncmp(format->methods.get_key(0), plaintext, - format->params.plaintext_length)) break; + index = (index << 1) + 1; /* 0, 1, 3, 7, 15, 31, 63, ... */ + if (index >= max) index = 0; } while ((++current)->ciphertext); - return current->ciphertext != NULL; + return NULL; } -void fmt_default_init() +void fmt_default_init(void) { } @@ -110,6 +124,10 @@ return 0; } +void fmt_default_clear_keys(void) +{ +} + int fmt_default_get_hash(int index) { return 0; diff -ruN john-1.6/src/formats.h john-1.6.34/src/formats.h --- john-1.6/src/formats.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/formats.h 2001-06-16 09:45:42.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -15,6 +15,7 @@ */ #define FMT_CASE 0x00000001 #define FMT_8_BIT 0x00000002 +#define FMT_BS 0x00010000 /* * A password to test the methods for correct operation. @@ -72,7 +73,7 @@ struct fmt_methods { /* Initializes the algorithm's internal structures, valid() is the only * method that is allowed to be called before a call to init(). */ - void (*init)(); + void (*init)(void); /* Checks if an ASCII ciphertext is valid for this format. Returns zero for * invalid ciphertexts, or a number of parts the ciphertext should be split @@ -107,6 +108,11 @@ /* Returns a plaintext previously set with set_key() */ char *(*get_key)(int index); +/* Allow the previously set keys to be dropped if that would help improve + * performance and/or reduce the impact of certain hardware faults. After + * 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. */ @@ -162,21 +168,22 @@ extern void fmt_init(struct fmt_main *format); /* - * Tests the format's methods for correct operation. Returns a non-zero value - * on error. + * Tests the format's methods for correct operation. Returns NULL on + * success, method name on error. */ -extern int fmt_self_test(struct fmt_main *format); +extern char *fmt_self_test(struct fmt_main *format); /* * Default methods. */ -extern void fmt_default_init(); +extern void fmt_default_init(void); extern int fmt_default_valid(char *ciphertext); extern char *fmt_default_split(char *ciphertext, int index); extern void *fmt_default_binary(char *ciphertext); extern void *fmt_default_salt(char *ciphertext); extern int fmt_default_binary_hash(void *binary); extern int fmt_default_salt_hash(void *salt); +extern void fmt_default_clear_keys(void); extern int fmt_default_get_hash(int index); /* diff -ruN john-1.6/src/getopt.c john-1.6.34/src/getopt.c --- john-1.6/src/getopt.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/getopt.c 2000-08-26 05:52:13.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ #include @@ -105,10 +105,9 @@ static int opt_check_one(struct opt_entry *list, opt_flags flg, char *opt) { - char *param; struct opt_entry *entry; - param = opt_find(list, opt, &entry); + opt_find(list, opt, &entry); if (!entry) return OPT_ERROR_UNKNOWN; if ((flg & entry->req_set) != entry->req_set || (flg & entry->req_clr)) diff -ruN john-1.6/src/idle.c john-1.6.34/src/idle.c --- john-1.6/src/idle.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/idle.c 2001-07-26 16:56:25.000000000 +0200 @@ -1,15 +1,15 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include -#ifdef __linux__ +#ifdef _POSIX_PRIORITY_SCHEDULING #include -#ifndef SCHED_IDLE -#define SCHED_IDLE 3 -#endif +#include +#include + static int use_yield = 0; #endif @@ -17,30 +17,68 @@ extern int nice(int); #endif +#ifdef __BEOS__ +#include +#endif + #include "params.h" #include "config.h" #include "options.h" +#include "signals.h" -void idle_init() +void idle_init(void) { -#ifdef __linux__ +#if defined(_POSIX_PRIORITY_SCHEDULING) && defined(SCHED_IDLE) struct sched_param param = {0}; #endif if (!cfg_get_bool(SECTION_OPTIONS, NULL, "Idle")) return; if (options.flags & FLG_STDOUT) return; +#ifndef __BEOS__ nice(20); +#else + set_thread_priority(getpid(), 1); +#endif -#ifdef __linux__ - use_yield = sched_setscheduler(getpid(), SCHED_IDLE, ¶m) ? 1 : 2; +#if defined(_POSIX_PRIORITY_SCHEDULING) && defined(SCHED_IDLE) + use_yield = sched_setscheduler(getpid(), SCHED_IDLE, ¶m) != 0; +#elif defined(_POSIX_PRIORITY_SCHEDULING) + use_yield = 1; #endif } -void idle_yield(int always) +void idle_yield(void) { -#ifdef __linux__ - if (use_yield) - if (use_yield == 1 || always) sched_yield(); +#ifdef _POSIX_PRIORITY_SCHEDULING + static int calls_per_tick = 0; + static int calls_since_tick = 0; + static int calls_since_adj = 0; + static clock_t last_adj = 0; + clock_t last_check; + clock_t current; + struct tms buf; + + if (!use_yield) return; + + if (++calls_since_tick < calls_per_tick) return; + calls_since_adj += calls_since_tick; + calls_since_tick = 0; + + current = times(&buf); + if (!last_adj) last_adj = current; + + if (current - last_adj >= CLK_TCK) { + calls_per_tick = calls_since_adj / (current - last_adj); + calls_since_adj = 0; + last_adj = current; + } + + do { + if (event_pending) break; + last_check = current; + sched_yield(); + current = times(&buf); + } while (current - last_check > 1 && current - last_adj < CLK_TCK); #endif } diff -ruN john-1.6/src/idle.h john-1.6.34/src/idle.h --- john-1.6/src/idle.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/idle.h 2001-05-08 22:37:37.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -14,12 +14,12 @@ * Sets this process to idle priority, if supported and enabled in the * configuration file. */ -extern void idle_init(); +extern void idle_init(void); /* * If the idle_init() call was unable to set the idle priority, this can * still be used to yield a timeslice if there's something else to do. */ -extern void idle_yield(int always); +extern void idle_yield(void); #endif diff -ruN john-1.6/src/inc.c john-1.6.34/src/inc.c --- john-1.6/src/inc.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/inc.c 2003-06-29 15:18:57.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2003 by Solar Designer */ #include @@ -28,6 +28,7 @@ typedef char (*chars_table) [CHARSET_SIZE + 1][CHARSET_SIZE + 1][CHARSET_SIZE + 1]; +static int rec_compat; static int rec_entry; static int rec_numbers[CHARSET_LENGTH]; @@ -38,17 +39,26 @@ { int pos; - fprintf(file, "%d\n", rec_entry); + fprintf(file, "%d\n%d\n%d\n", rec_entry, rec_compat, CHARSET_LENGTH); for (pos = 0; pos < CHARSET_LENGTH; pos++) fprintf(file, "%d\n", rec_numbers[pos]); } static int restore_state(FILE *file) { + int length; int pos; if (fscanf(file, "%d\n", &rec_entry) != 1) return 1; - for (pos = 0; pos < CHARSET_LENGTH; pos++) { + rec_compat = 1; + length = CHARSET_LENGTH; + if (rec_version >= 2) { + if (fscanf(file, "%d\n%d\n", &rec_compat, &length) != 2) + return 1; + if ((unsigned int)rec_compat > 1) return 1; + if ((unsigned int)length > CHARSET_LENGTH) return 1; + } + for (pos = 0; pos < length; pos++) { if (fscanf(file, "%d\n", &rec_numbers[pos]) != 1) return 1; if ((unsigned int)rec_numbers[pos] >= CHARSET_SIZE) return 1; } @@ -56,7 +66,7 @@ return 0; } -static void fix_state() +static void fix_state(void) { rec_entry = entry; memcpy(rec_numbers, numbers, sizeof(rec_numbers)); @@ -164,11 +174,11 @@ memset(present, 0, sizeof(present)); while (*dptr) { if (--count <= 1) return; - present[((ARCH_INDEX)*dptr++) - CHARSET_MIN] = 1; + present[ARCH_INDEX(*dptr++) - CHARSET_MIN] = 1; } while (*sptr) - if (!present[(ARCH_INDEX)*sptr - CHARSET_MIN]) { + if (!present[ARCH_INDEX(*sptr) - CHARSET_MIN]) { *dptr++ = *sptr++; if (--count <= 1) break; } else @@ -208,36 +218,86 @@ static int inc_key_loop(int length, int fixed, int count, char *char1, char2_table char2, chars_table *chars) { - char key[PLAINTEXT_BUFFER_SIZE]; + char key_i[PLAINTEXT_BUFFER_SIZE]; + char key_e[PLAINTEXT_BUFFER_SIZE]; + char *key; + char *chars_cache; + int numbers_cache; int pos; - key[length + 1] = 0; + key_i[length + 1] = 0; numbers[fixed] = count; - do { - key[0] = char1[numbers[0]]; + chars_cache = NULL; + +update_all: + pos = 0; +update_ending: + if (pos < 2) { + if (pos == 0) + key_i[0] = char1[numbers[0]]; if (length) - key[1] = (*char2)[key[0] - CHARSET_MIN][numbers[1]]; - for (pos = 2; pos <= length; pos++) - key[pos] = (*chars[pos - 2]) - [(ARCH_INDEX)key[pos - 2] - CHARSET_MIN] - [(ARCH_INDEX)key[pos - 1] - CHARSET_MIN] - [numbers[pos]]; - - if (ext_filter(key)) - if (crk_process_key(key)) return 1; - - if (length) { - pos = 0; - do { - if (pos == fixed) continue; - if (++numbers[pos] <= count - - ((pos < fixed) ? 1 : 0)) break; - numbers[pos] = 0; - } while (++pos <= length); - } else - if (++numbers[0] <= count) pos = 0; else break; - } while (pos <= length); + key_i[1] = (*char2)[key_i[0] - CHARSET_MIN][numbers[1]]; + pos = 2; + } + while (pos < length) { + key_i[pos] = (*chars[pos - 2]) + [ARCH_INDEX(key_i[pos - 2]) - CHARSET_MIN] + [ARCH_INDEX(key_i[pos - 1]) - CHARSET_MIN] + [numbers[pos]]; + pos++; + } + numbers_cache = numbers[length]; + if (pos == length) { + chars_cache = (*chars[pos - 2]) + [ARCH_INDEX(key_i[pos - 2]) - CHARSET_MIN] + [ARCH_INDEX(key_i[pos - 1]) - CHARSET_MIN]; +update_last: + key_i[length] = chars_cache[numbers_cache]; + } + + key = key_i; + if (!ext_mode || !f_filter || ext_filter_body(key_i, key = key_e)) + if (crk_process_key(key)) return 1; + + if (rec_compat) goto compat; + + pos = length; + if (fixed < length) { + if (++numbers_cache <= count) { + if (length >= 2) goto update_last; + numbers[length] = numbers_cache; + goto update_ending; + } + numbers[pos--] = 0; + while (pos > fixed) { + if (++numbers[pos] <= count) goto update_ending; + numbers[pos--] = 0; + } + } + while (pos-- > 0) { + if (++numbers[pos] < count) goto update_ending; + numbers[pos] = 0; + } + + return 0; + +compat: + pos = 0; + if (fixed) { + if (++numbers[0] < count) goto update_all; + if (!length && numbers[0] <= count) goto update_all; + numbers[0] = 0; + pos = 1; + while (pos < fixed) { + if (++numbers[pos] < count) goto update_all; + numbers[pos++] = 0; + } + } + while (++pos <= length) { + if (++numbers[pos] <= count) goto update_all; + numbers[pos] = 0; + } return 0; } @@ -279,6 +339,29 @@ max_length = CHARSET_LENGTH; max_count = cfg_get_int(SECTION_INC, mode, "CharCount"); + if (min_length > max_length) { + fprintf(stderr, "MinLen = %d exceeds MaxLen = %d\n", + min_length, max_length); + error(); + } + + if (max_length > CHARSET_LENGTH) { + fprintf(stderr, + "\n" + "MaxLen = %d exceeds the compile-time limit of %d\n\n" + "There're several good reasons why you probably don't " + "need to raise it:\n" + "- many hash types don't support passwords " + "(or password halves) longer than\n" + "7 or 8 characters;\n" + "- you probably don't have sufficient statistical " + "information to generate a\n" + "charset file for lengths beyond 8;\n" + "- the limitation applies to incremental mode only.\n", + max_length, CHARSET_LENGTH); + error(); + } + if (!(file = fopen(path_expand(charset), "rb"))) pexit("fopen: %s", path_expand(charset)); @@ -306,7 +389,7 @@ if (max_count < 0) max_count = CHARSET_SIZE; else if ((unsigned int)max_count > real_count) - fprintf(stderr,"Warning: only %d characters available\n", + fprintf(stderr, "Warning: only %d characters available\n", real_count); if (header->length >= 2) @@ -316,6 +399,7 @@ for (pos = 0; pos < (int)header->length - 2; pos++) chars[pos] = (chars_table)mem_alloc(sizeof(*chars[0])); + rec_compat = 0; rec_entry = 0; memset(rec_numbers, 0, sizeof(rec_numbers)); diff -ruN john-1.6/src/john.c john-1.6.34/src/john.c --- john-1.6/src/john.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/john.c 2002-04-11 19:58:45.000000000 +0200 @@ -1,9 +1,10 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2002 by Solar Designer */ #include +#include #include #include #include @@ -16,7 +17,6 @@ #include "list.h" #include "tty.h" #include "signals.h" -#include "idle.h" #include "common.h" #include "formats.h" #include "loader.h" @@ -33,7 +33,7 @@ #include "batch.h" #if CPU_DETECT -extern int CPU_detect(); +extern int CPU_detect(void); #endif extern struct fmt_main fmt_DES, fmt_BSDI, fmt_MD5, fmt_BF; @@ -54,7 +54,7 @@ fmt_register(format); } -static void john_register_all() +static void john_register_all(void) { if (options.format) strlwr(options.format); @@ -71,7 +71,7 @@ } } -static void john_load() +static void john_load(void) { struct list_entry *current; @@ -172,6 +172,13 @@ #if CPU_DETECT if (!CPU_detect()) { #if CPU_REQ +#if CPU_FALLBACK +#if defined(__DJGPP__) || defined(__CYGWIN32__) +#error CPU_FALLBACK is incompatible with the current DOS and Win32 code +#endif + execv(JOHN_SYSTEMWIDE_EXEC "/" CPU_FALLBACK_BINARY, argv); + perror("execv"); +#endif fprintf(stderr, "Sorry, %s is required\n", CPU_NAME); error(); #endif @@ -179,19 +186,26 @@ #endif path_init(argv); - cfg_init(CFG_NAME); + +#if JOHN_SYSTEMWIDE + cfg_init(CFG_PRIVATE_FULL_NAME, 1); + cfg_init(CFG_PRIVATE_ALT_NAME, 1); +#endif + cfg_init(CFG_FULL_NAME, 1); + cfg_init(CFG_ALT_NAME, 0); + status_init(NULL, 1); opt_init(argc, argv); john_register_all(); common_init(); - sig_init(idle_yield); + sig_init(); john_load(); } -static void john_run() +static void john_run(void) { if (options.flags & FLG_TEST_CHK) benchmark_all(); @@ -225,7 +239,7 @@ } } -static void john_done() +static void john_done(void) { path_done(); @@ -259,14 +273,6 @@ name[strlen(name) - 4] = 0; #endif - if (!strcmp(name, "john")) { - john_init(argc, argv); - john_run(); - john_done(); - - return 0; - } - if (!strcmp(name, "unshadow")) return unshadow(argc, argv); @@ -276,6 +282,9 @@ if (!strcmp(name, "unique")) return unique(argc, argv); - fprintf(stderr, "Sorry, I can't find myself\n"); - return 1; + john_init(argc, argv); + john_run(); + john_done(); + + return 0; } diff -ruN john-1.6/src/LM_fmt.c john-1.6.34/src/LM_fmt.c --- john-1.6/src/LM_fmt.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/LM_fmt.c 2001-08-19 05:06:18.000000000 +0200 @@ -1,12 +1,14 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include #include "arch.h" -#include "DES_std.h" +#include "misc.h" +#include "memory.h" +#include "DES_bs.h" #include "common.h" #include "formats.h" @@ -20,54 +22,44 @@ #define CIPHERTEXT_LENGTH 32 #define LM_EMPTY "AAD3B435B51404EE" +#define LM_EMPTY_LOWER "aad3b435b51404ee" static struct fmt_tests tests[] = { - {"$LM$1C3A2B6D939A1021", "AAA"}, + {"$LM$A9C604D244C4E99D", "AAAAAA"}, {"$LM$CBC501A4D2227783", "AAAAAAA"}, - {"$LM$CE045FF77F9D89E2", "ZZZZ"}, + {"$LM$3466C2B0487FE39A", "CRACKPO"}, + {"$LM$DBC5E5CBA8028091", "IMPUNIT"}, {LM_EMPTY LM_EMPTY, ""}, - {"$LM$7584248B8D2C9F9E", "A"}, + {"$LM$73CC402BD3E79175", "SCLEROS"}, + {"$LM$5ECD9236D21095CE", "YOKOHAM"}, + {"$LM$A5E6066DE61C3E35", "ZZZZZZZ"}, + {"$LM$1FB363FEB834C12D", "ZZZZZZ"}, {NULL} }; -#define ALGORITHM_NAME DES_STD_ALGORITHM_NAME +#define ALGORITHM_NAME DES_BS_ALGORITHM_NAME #define BINARY_SIZE ARCH_SIZE #define SALT_SIZE 0 -#define MIN_KEYS_PER_CRYPT 0x40 -#define MAX_KEYS_PER_CRYPT 0x40 +#define MIN_KEYS_PER_CRYPT DES_BS_DEPTH +#define MAX_KEYS_PER_CRYPT DES_BS_DEPTH -#define LM_IV_0 0x2153474B -#define LM_IV_1 0x25242340 - -static struct { - union { - double dummy; - DES_binary binary; - } aligned; - char key[PLAINTEXT_LENGTH + 1]; -} buffer[MAX_KEYS_PER_CRYPT]; - -static DES_binary LM_IV; - -static void init() -{ - DES_std_init(); - DES_std_set_salt(0); - DES_count = 1; - - DES_std_set_block(LM_IV_0, LM_IV_1); - memcpy(LM_IV, DES_IV, sizeof(DES_binary)); +static void init(void) +{ + DES_bs_init(1); } static int valid(char *ciphertext) { char *pos; + char lower[CIPHERTEXT_LENGTH - 16 + 1]; - for (pos = ciphertext; atoi16[(ARCH_INDEX)*pos] != 0x7F; pos++); + for (pos = ciphertext; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); if (!*pos && pos - ciphertext == CIPHERTEXT_LENGTH) { - if (strcmp(&ciphertext[16], LM_EMPTY)) + strcpy(lower, &ciphertext[16]); + strlwr(lower); + if (strcmp(lower, LM_EMPTY_LOWER)) return 2; else return 1; @@ -75,7 +67,7 @@ if (strncmp(ciphertext, "$LM$", 4)) return 0; - for (pos = &ciphertext[4]; atoi16[(ARCH_INDEX)*pos] != 0x7F; pos++); + for (pos = &ciphertext[4]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); if (*pos || pos - ciphertext != 20) return 0; return 1; @@ -103,149 +95,65 @@ static void *get_binary(char *ciphertext) { - static DES_binary out; - ARCH_WORD_32 block[2]; - int index, value; - - block[0] = block[1] = 0; - for (index = 0; index < 16; index += 2) { - value = (int)atoi16[(ARCH_INDEX)ciphertext[index + 4]] << 4; - value |= atoi16[(ARCH_INDEX)ciphertext[index + 5]]; - - block[index >> 3] |= value << ((index << 2) & 0x18); - } - - DES_std_set_block(block[0], block[1]); - memcpy(out, DES_IV, sizeof(DES_binary)); - - return out; + return DES_bs_get_binary_LM(ciphertext + 4); } static int binary_hash_0(void *binary) { - return DES_STD_HASH_0(*(ARCH_WORD *)binary); + return *(ARCH_WORD *)binary & 0xF; } static int binary_hash_1(void *binary) { - return DES_STD_HASH_1(*(ARCH_WORD *)binary); + return *(ARCH_WORD *)binary & 0xFF; } static int binary_hash_2(void *binary) { - return DES_STD_HASH_2(*(ARCH_WORD *)binary); + return *(ARCH_WORD *)binary & 0xFFF; } static int get_hash_0(int index) { - return DES_STD_HASH_0(buffer[index].aligned.binary[0]); + return DES_bs_get_hash(index, 4); } static int get_hash_1(int index) { - ARCH_WORD binary; - - binary = buffer[index].aligned.binary[0]; - return DES_STD_HASH_1(binary); + return DES_bs_get_hash(index, 8); } static int get_hash_2(int index) { - ARCH_WORD binary; - - binary = buffer[index].aligned.binary[0]; - return DES_STD_HASH_2(binary); + return DES_bs_get_hash(index, 12); } static void set_salt(void *salt) { } -static void crypt_all(int count) -{ - int index; - unsigned char *key7; - union { - char b[8]; - ARCH_WORD_32 w[2]; - } key8; - - for (index = 0; index < count; index++) { - key7 = (unsigned char *)buffer[index].key; - key8.b[0] = key7[0] >> 1; - key8.b[1] = ((key7[0] & 0x01) << 6) | (key7[1] >> 2); - key8.b[2] = ((key7[1] & 0x03) << 5) | (key7[2] >> 3); - key8.b[3] = ((key7[2] & 0x07) << 4) | (key7[3] >> 4); - key8.b[4] = ((key7[3] & 0x0F) << 3) | (key7[4] >> 5); - key8.b[5] = ((key7[4] & 0x1F) << 2) | (key7[5] >> 6); - key8.b[6] = ((key7[5] & 0x3F) << 1) | (key7[6] >> 7); - key8.b[7] = key7[6]; - key8.w[0] |= 0x80808080; - key8.w[1] |= 0x80808080; - - DES_std_set_key(key8.b); - - DES_IV[0] = LM_IV[0]; - DES_IV[1] = LM_IV[1]; -#if ARCH_BITS < 64 - DES_IV[2] = LM_IV[2]; - DES_IV[3] = LM_IV[3]; -#endif - - DES_std_crypt(DES_KS_current, buffer[index].aligned.binary); - } -} - static int cmp_all(void *binary, int count) { - int index; - - for (index = 0; index < count; index++) - if (*(unsigned ARCH_WORD *)binary == buffer[index].aligned.binary[0]) - return 1; - - return 0; + return DES_bs_cmp_all((ARCH_WORD *)binary); } static int cmp_one(void *binary, int index) { - return *(unsigned ARCH_WORD *)binary == - buffer[index].aligned.binary[0]; + return DES_bs_cmp_one((ARCH_WORD *)binary, 32, index); } static int cmp_exact(char *source, int index) { - ARCH_WORD *binary; - int word; - - binary = (ARCH_WORD *)get_binary(source); - - for (word = 0; word < 16 / DES_SIZE; word++) - if ((unsigned ARCH_WORD)binary[word] != - buffer[index].aligned.binary[word]) - return 0; - - return 1; -} - -static void set_key(char *key, int index) -{ - char *dst = buffer[index].key; - char *src = key; - int count = PLAINTEXT_LENGTH; - - do { - if (*src >= 'a' && *src <= 'z') - *dst++ = *src++ & ~0x20; - else - if ((*dst++ = *src)) src++; - } while (--count); - *dst = 0; + return DES_bs_cmp_one(get_binary(source), 64, index); } static char *get_key(int index) { - return buffer[index].key; +#if !DES_BS_VECTOR && ARCH_BITS >= 64 + return (char *)DES_bs_all.E.extras.keys[index]; +#else + return (char *)DES_bs_all.keys[index]; +#endif } struct fmt_main fmt_LM = { @@ -260,7 +168,7 @@ SALT_SIZE, MIN_KEYS_PER_CRYPT, MAX_KEYS_PER_CRYPT, - FMT_8_BIT, + FMT_8_BIT | FMT_BS, tests }, { init, @@ -275,9 +183,10 @@ }, fmt_default_salt_hash, set_salt, - set_key, + DES_bs_set_key_LM, get_key, - crypt_all, + DES_bs_clear_keys_LM, + (void (*)(int))DES_bs_crypt_LM, { get_hash_0, get_hash_1, diff -ruN john-1.6/src/loader.c john-1.6.34/src/loader.c --- john-1.6/src/loader.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/loader.c 2000-08-26 05:59:56.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ #include @@ -29,7 +29,7 @@ * Word separator characters for ldr_split_words(), used on GECOS fields. */ #define issep \ - "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\177\377" + "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\177" static char issep_map[0x100]; static int issep_initialized = 0; @@ -65,7 +65,7 @@ if (fclose(file)) pexit("fclose"); } -static void ldr_init_issep() +static void ldr_init_issep(void) { char *pos; @@ -75,7 +75,7 @@ memset(issep_map, 1, 33); for (pos = issep; *pos; pos++) - issep_map[(ARCH_INDEX)*pos] = 1; + issep_map[ARCH_INDEX(*pos)] = 1; issep_initialized = 1; } @@ -246,11 +246,11 @@ pos = src; do { word = pos; - while (*word && issep_map[(ARCH_INDEX)*word]) word++; + while (*word && issep_map[ARCH_INDEX(*word)]) word++; if (!*word) break; pos = word; - while (!issep_map[(ARCH_INDEX)*pos]) pos++; + while (!issep_map[ARCH_INDEX(*pos)]) pos++; if (*pos) *pos++ = 0; list_add_unique(dst, word); @@ -340,8 +340,7 @@ if (!current_salt) { last_salt = db->salt_hash[salt_hash]; current_salt = db->salt_hash[salt_hash] = - mem_alloc_tiny(sizeof(struct db_salt), - MEM_ALIGN_WORD); + mem_alloc_tiny(salt_size, MEM_ALIGN_WORD); current_salt->next = last_salt; current_salt->salt = mem_alloc_copy( @@ -541,6 +540,8 @@ for (size = 2; size >= 0; size--) if (current->count >= password_hash_thresholds[size]) break; + if ((db->format->params.flags & FMT_BS) && !size) size = -1; + if (size >= 0 && mem_saving_level < 2) { current->hash = mem_alloc_tiny( password_hash_sizes[size] * diff -ruN john-1.6/src/logger.c john-1.6.34/src/logger.c --- john-1.6/src/logger.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/logger.c 1999-09-22 05:57:17.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ #include @@ -41,7 +41,7 @@ cfg_beep = cfg_get_bool(SECTION_OPTIONS, NULL, "Beep"); } -static void log_write() +static void log_write(void) { int size; @@ -72,7 +72,7 @@ write_loop(fileno(stderr), "\007", 1); } -void log_flush() +void log_flush(void) { if (log_fd) { if (log_bufptr != log_buffer) log_write(); @@ -82,7 +82,7 @@ } } -void log_done() +void log_done(void) { if (log_fd) { log_flush(); diff -ruN john-1.6/src/logger.h john-1.6.34/src/logger.h --- john-1.6/src/logger.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/logger.h 1999-09-22 05:41:22.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ /* @@ -24,11 +24,11 @@ /* * Writes the log file buffer to disk. */ -extern void log_flush(); +extern void log_flush(void); /* * Closes the log file. */ -extern void log_done(); +extern void log_done(void); #endif diff -ruN john-1.6/src/Makefile john-1.6.34/src/Makefile --- john-1.6/src/Makefile 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/Makefile 2003-06-29 15:16:53.000000000 +0200 @@ -1,6 +1,6 @@ # # This file is part of John the Ripper password cracker, -# Copyright (c) 1996-98 by Solar Designer +# Copyright (c) 1996-2003 by Solar Designer # CPP = gcc @@ -10,6 +10,7 @@ CP = cp LN = ln -sf RM = rm -f +TR = tr SED = sed NULL = /dev/null CPPFLAGS = -E @@ -19,18 +20,18 @@ OPT_NORMAL = -funroll-loops OPT_INLINE = -finline-functions -JOHN_VERSION = 1.6 +JOHN_VERSION = 1.6.34 JOHN_ARCHIVE = john-$(JOHN_VERSION) JOHN_DIST = \ $(JOHN_ARCHIVE)/src/*.{c,h,S,sh,asm,com,diff} \ $(JOHN_ARCHIVE)/src/Makefile{,.dep} \ - $(JOHN_ARCHIVE)/run/{mailer,john.ini,*.chr,password.lst} \ + $(JOHN_ARCHIVE)/run/{mailer,john.conf,*.chr,password.lst} \ $(JOHN_ARCHIVE)/doc/* \ $(JOHN_ARCHIVE)/README -JOHN_OBJS_ORIG = \ - DES_fmt.o DES_std.o \ +JOHN_OBJS_MINIMAL = \ + DES_fmt.o DES_std.o DES_bs.o \ BSDI_fmt.o \ MD5_fmt.o MD5_std.o \ BF_fmt.o BF_std.o \ @@ -44,12 +45,13 @@ unafs.o \ unique.o +JOHN_OBJS_ORIG = \ + $(JOHN_OBJS_MINIMAL) \ + DES_bs_b.o + JOHN_OBJS = \ $(JOHN_OBJS_ORIG) -BITSLICE_OBJS = \ - DES_bs.o DES_bs_b.o - BENCH_DES_OBJS_ORIG = \ DES_fmt.o DES_std.o @@ -57,15 +59,15 @@ $(BENCH_DES_OBJS_ORIG) BENCH_MD5_OBJS_DEPEND = \ - MD5_std.o + MD5_fmt.o MD5_std.o BENCH_BF_OBJS_DEPEND = \ BF_std.o BENCH_OBJS = \ - $(BITSLICE_OBJS) \ $(BENCH_DES_OBJS_DEPEND) \ - MD5_fmt.o $(BENCH_MD5_OBJS_DEPEND) \ + DES_bs.o DES_bs_b.o \ + $(BENCH_MD5_OBJS_DEPEND) \ BF_fmt.o $(BENCH_BF_OBJS_DEPEND) \ bench.o best.o common.o config.o formats.o memory.o misc.o params.o \ path.o signals.o tty.o @@ -82,125 +84,135 @@ @echo "where SYSTEM can be one of the following:" @echo "linux-x86-any-elf Linux, x86, ELF binaries" @echo "linux-x86-mmx-elf Linux, x86 with MMX, ELF binaries" - @echo "linux-x86-k6-elf Linux, AMD K6, ELF binaries" @echo "linux-x86-any-a.out Linux, x86, a.out binaries" @echo "linux-alpha Linux, Alpha" - @echo "linux-sparc Linux, SPARC" - @echo "freebsd-x86-any-a.out FreeBSD, x86, a.out binaries" - @echo "freebsd-x86-k6-a.out FreeBSD, AMD K6, a.out binaries" + @echo "linux-sparc Linux, SPARC 32-bit" + @echo "linux-ppc Linux, PowerPC" @echo "freebsd-x86-any-elf FreeBSD, x86, ELF binaries" @echo "freebsd-x86-mmx-elf FreeBSD, x86 with MMX, ELF binaries" - @echo "freebsd-x86-k6-elf FreeBSD, AMD K6, ELF binaries" + @echo "freebsd-x86-any-a.out FreeBSD, x86, a.out binaries" + @echo "freebsd-alpha FreeBSD, Alpha" @echo "openbsd-x86-any OpenBSD, x86" - @echo "openbsd-x86-k6 OpenBSD, AMD K6" - @echo "solaris-sparc-gcc Solaris, SPARC, gcc" - @echo "solaris-sparc-v8-cc Solaris, SPARC V8, cc" - @echo "solaris-sparc-v9-cc Solaris, SPARC V9, cc" + @echo "openbsd-sparc OpenBSD, SPARC 32-bit" + @echo "openbsd-vax OpenBSD, VAX" + @echo "netbsd-vax NetBSD, VAX" + @echo "solaris-sparc-gcc Solaris, SPARC 32-bit, gcc" + @echo "solaris-sparc64-gcc Solaris, SPARC V9 64-bit, gcc" + @echo "solaris-sparc-v8-cc Solaris, SPARC V8 32-bit, cc" + @echo "solaris-sparc-v9-cc Solaris, SPARC V9 32-bit, cc" + @echo "solaris-sparc64-cc Solaris, SPARC V9 64-bit, cc" @echo "solaris-x86-any Solaris, x86, gcc" - @echo "solaris-x86-k6 Solaris, AMD K6, gcc" - @echo "digital-alpha-cc Digital UNIX, Alpha, cc" + @echo "sco-x86-any-gcc SCO, x86, gcc, ELF binaries" + @echo "sco-x86-any-cc SCO, x86, cc, ELF binaries" + @echo "tru64-alpha-cc Tru64 (Digital UNIX, OSF/1), Alpha, cc" @echo "aix-ppc-cc AIX, PowerPC, cc" + @echo "macosx-ppc-cc MacOS X, PowerPC, cc" @echo "hpux-pa-risc-gcc HP-UX, PA-RISC, gcc" - @echo "hpux-pa-risc-cc HP-UX, PA-RISC, cc" + @echo "hpux-pa-risc-cc HP-UX, PA-RISC, ANSI cc" @echo "irix-mips32-cc IRIX, MIPS 32-bit, cc" @echo "irix-mips64-cc IRIX, MIPS 64-bit, cc" + @echo "irix-mips64-r10k-cc IRIX, MIPS 64-bit (R10K), cc" @echo "dos-djgpp-x86-any DOS, DJGPP 2.x, x86" @echo "dos-djgpp-x86-mmx DOS, DJGPP 2.x, x86 with MMX" - @echo "dos-djgpp-x86-k6 DOS, DJGPP 2.x, AMD K6" @echo "win32-cygwin-x86-any Win32, Cygwin, x86" @echo "win32-cygwin-x86-mmx Win32, Cygwin, x86 with MMX" - @echo "win32-cygwin-x86-k6 Win32, Cygwin, AMD K6" - @echo "generic Any other UNIX system with gcc" + @echo "beos-x86-any BeOS, x86" + @echo "beos-x86-mmx BeOS, x86 with MMX" + @echo "generic Any other Unix system with gcc" linux-x86-any-elf: $(LN) x86-any.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -m486" + JOHN_OBJS="$(JOHN_OBJS) x86.o" linux-x86-mmx-elf: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -m486" - -linux-x86-k6-elf: - $(LN) x86-k6.h arch.h - $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS) x86.o" + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" linux-x86-any-a.out: $(LN) x86-any.h arch.h $(MAKE) $(PROJ) \ JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -m486" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG" linux-alpha: $(LN) alpha.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS) alpha.o" + JOHN_OBJS="$(JOHN_OBJS) alpha.o" -linux-alpha-very-slow-cache: - $(LN) alpha-4k.h arch.h +# This target is currently "undocumented" as ccc generates much slower +# code for the large unrolled loops in John; let's hope it gets fixed. +linux-alpha-ccc: + $(LN) alpha.h arch.h $(MAKE) $(PROJ) \ + CPP=ccc CC=ccc AS=ccc LD=ccc \ + CFLAGS="-c -Wf,-switch,noil_schedule" \ + OPT_NORMAL="-fast" \ + OPT_INLINE="-O2 -arch host" \ JOHN_OBJS="$(JOHN_OBJS) alpha.o" linux-sparc: - $(MAKE) HAMMER=use-linux-sparc sparc.h - ln -s sparc.h arch.h + $(MAKE) use-linux-sparc HAMMER=use-linux-sparc NAIL=sparc.h + $(LN) sparc.h arch.h $(MAKE) use-linux-sparc NAIL="$(PROJ)" use-linux-sparc: $(MAKE) $(NAIL) \ BENCH_DES_OBJS_DEPEND="$(BENCH_DES_OBJS_ORIG) sparc.o" \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS_ORIG) sparc.o" - -freebsd-x86-any-a.out: - $(LN) x86-any.h arch.h - $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -m486" \ - ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG -DBSD" + JOHN_OBJS="$(JOHN_OBJS_ORIG) sparc.o" -freebsd-x86-k6-a.out: - $(LN) x86-k6.h arch.h - $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS) x86.o" \ - ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG -DBSD" +linux-ppc: + $(LN) ppc.h arch.h + $(MAKE) $(PROJ) freebsd-x86-any-elf: $(LN) x86-any.h arch.h $(MAKE) $(PROJ) \ JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -m486" \ ASFLAGS="$(ASFLAGS) -DBSD" freebsd-x86-mmx-elf: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -m486" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" \ ASFLAGS="$(ASFLAGS) -DBSD" -freebsd-x86-k6-elf: - $(LN) x86-k6.h arch.h +freebsd-x86-any-a.out: + $(LN) x86-any.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS) x86.o" \ - ASFLAGS="$(ASFLAGS) -DBSD" + JOHN_OBJS="$(JOHN_OBJS) x86.o" \ + ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG -DBSD" + +freebsd-alpha: + $(LN) alpha.h arch.h + $(MAKE) $(PROJ) \ + JOHN_OBJS="$(JOHN_OBJS) alpha.o" openbsd-x86-any: $(LN) x86-any.h arch.h $(MAKE) $(PROJ) \ JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -m486" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG -DBSD" -openbsd-x86-k6: - $(LN) x86-k6.h arch.h - $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS) x86.o" \ - ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG -DBSD" +openbsd-sparc: + $(MAKE) use-openbsd-sparc HAMMER=use-openbsd-sparc NAIL=sparc.h + $(LN) sparc.h arch.h + $(MAKE) use-openbsd-sparc NAIL="$(PROJ)" + +use-openbsd-sparc: + $(MAKE) $(NAIL) \ + BENCH_DES_OBJS_DEPEND="$(BENCH_DES_OBJS_ORIG) sparc.o" \ + JOHN_OBJS="$(JOHN_OBJS_ORIG) sparc.o" \ + ASFLAGS="-c -DUNDERSCORES -DBSD" + +openbsd-vax: + $(LN) vax.h arch.h + $(MAKE) $(PROJ) + +netbsd-vax: + $(LN) vax.h arch.h + $(MAKE) $(PROJ) solaris-sparc-any: $(MAKE) $(HAMMER) NAIL=sparc.h @@ -220,27 +232,28 @@ use-solaris-sparc-gcc: $(MAKE) $(NAIL) \ BENCH_DES_OBJS_DEPEND="$(BENCH_DES_OBJS_ORIG) sparc.o" \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS_ORIG) sparc.o" + JOHN_OBJS="$(JOHN_OBJS_ORIG) sparc.o" \ + LDFLAGS="-s -lrt" use-solaris-sparc-v8-cc: $(MAKE) $(NAIL) \ BENCH_DES_OBJS_DEPEND="$(BENCH_DES_OBJS_ORIG) spro-sparc.o" \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS_ORIG) spro-sparc.o" \ + JOHN_OBJS="$(JOHN_OBJS_ORIG) spro-sparc.o" \ CPP=cc CC=cc AS=cc LD=cc \ CFLAGS="-c -xO4 -xarch=v8" \ - LDFLAGS="-s -lc" \ + LDFLAGS="-s -lc -lrt" \ OPT_NORMAL="" \ - OPT_INLINE="-xinline=S1,S2,S3,S4,S5,S6,S7,S8" + OPT_INLINE="-xinline=s1,s2,s3,s4,s5,s6,s7,s8" use-solaris-sparc-v9-cc: $(MAKE) $(NAIL) \ BENCH_DES_OBJS_DEPEND="$(BENCH_DES_OBJS_ORIG) spro-sparc.o" \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS_ORIG) spro-sparc.o" \ + JOHN_OBJS="$(JOHN_OBJS_ORIG) spro-sparc.o" \ CPP=cc CC=cc AS=cc LD=cc \ CFLAGS="-c -xO4 -xarch=v8plusa -xchip=ultra" \ - LDFLAGS="-s -lc" \ + LDFLAGS="-s -lc -lrt" \ OPT_NORMAL="" \ - OPT_INLINE="-xinline=S1,S2,S3,S4,S5,S6,S7,S8" + OPT_INLINE="-xinline=s1,s2,s3,s4,s5,s6,s7,s8" sparc.h: $(RM) arch.h @@ -250,66 +263,107 @@ # Older versions of spro cc didn't support .S files directly spro-sparc.o: sparc.S - $(CPP) $(CPPFLAGS) sparc.S > tmp.s + $(CPP) $(CPPFLAGS) sparc.S | $(SED) 's/% /%/g' > tmp.s $(AS) $(ASFLAGS) tmp.s -o spro-sparc.o $(RM) tmp.s +solaris-sparc64-cc: + $(LN) sparc64.h arch.h + $(MAKE) $(PROJ) \ + CPP=cc CC=cc AS=cc LD=cc \ + CFLAGS="-c -fast -xarch=native64" \ + LDFLAGS="-xarch=native64 -s -lc -lrt" \ + OPT_NORMAL="" \ + OPT_INLINE="-xinline=s1,s2,s3,s4,s5,s6,s7,s8" + +solaris-sparc64-gcc: + $(LN) sparc64.h arch.h + $(MAKE) $(PROJ) \ + CFLAGS="$(CFLAGS) -m64 -mcpu=ultrasparc" \ + LDFLAGS="-m64 -s -lrt" + solaris-x86-any: $(RM) arch.h ln -s x86-any.h arch.h $(MAKE) $(PROJ) \ SHELL=/bin/sh \ JOHN_OBJS="$(JOHN_OBJS) solaris-x86.o" \ - CFLAGS="$(CFLAGS) -m486" - -solaris-x86-k6: - $(RM) arch.h - ln -s x86-k6.h arch.h - $(MAKE) $(PROJ) \ - SHELL=/bin/sh \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS) solaris-x86.o" + LDFLAGS="-s -lc -lrt" # Solaris x86 got a broken assembler, with line length restriction (and some # other problems, that are worked around in x86.S) solaris-x86.o: x86.S - $(CPP) $(CPPFLAGS) -P -DSOLARIS x86.S | tr \; \\n > tmp.s + $(CPP) $(CPPFLAGS) -P -DDUMBAS x86.S | $(TR) \; \\n > tmp.s $(AS) $(ASFLAGS) tmp.s -o solaris-x86.o $(RM) tmp.s -digital-alpha-cc: +sco-x86-any-gcc: + $(RM) arch.h + ln -s x86-any.h arch.h + $(MAKE) $(PROJ) \ + SHELL=/bin/sh \ + JOHN_OBJS="$(JOHN_OBJS) sco-x86.o" + +sco-x86-any-cc: + $(RM) arch.h + ln -s x86-any.h arch.h + $(MAKE) $(PROJ) \ + SHELL=/bin/sh \ + JOHN_OBJS="$(JOHN_OBJS) sco-x86.o" \ + CPP=cc CC=cc AS=cc LD=cc \ + CFLAGS="-c -b elf -O3" \ + ASFLAGS="-c -b elf" \ + OPT_NORMAL="-K loop_unroll,no_inline" \ + OPT_INLINE="-K inline" + +# SCO is even worse than Solaris x86 +sco-x86.o: x86.S + $(CPP) $(CPPFLAGS) -DDUMBAS x86.S | \ + $(TR) \; \\n | $(SED) 's/\([%.]\) /\1/g' > tmp.s + $(AS) $(ASFLAGS) tmp.s -o sco-x86.o + $(RM) tmp.s + +tru64-alpha-cc: $(LN) alpha.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS) digital-alpha.o" \ + JOHN_OBJS="$(JOHN_OBJS) digipaq-alpha.o" \ CPP=cc CC=cc AS=cc LD=cc \ - CFLAGS="-c -O5 -tune host" \ + CFLAGS="-c -O4 -arch host" \ OPT_NORMAL="" \ OPT_INLINE="-inline all" -# DEC's cc and make use the .S suffix for a different purpose... -digital-alpha.o: alpha.S +# Digital/Compaq's cc and make use the .S suffix for a different purpose... +digipaq-alpha.o: alpha.S $(CPP) $(CPPFLAGS) alpha.S > tmp.s - $(AS) $(ASFLAGS) tmp.s -o digital-alpha.o + $(AS) $(ASFLAGS) tmp.s -o digipaq-alpha.o $(RM) tmp.s aix-ppc-cc: $(LN) ppc.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS)" \ CPP=cc CC=cc AS=cc LD=cc \ - CFLAGS="-c -qunroll -qarch=ppc -qtune=601 -qchars=signed" \ + CFLAGS="-c -qunroll -qarch=ppc -qchars=signed" \ LDFLAGS="-s -lbsd" \ OPT_NORMAL="-O2" \ OPT_INLINE="-O3 -Q=99 -w" +macosx-ppc-cc: + $(LN) ppc.h arch.h + $(MAKE) $(PROJ) \ + CPP=cc CC=cc AS=cc LD=cc \ + CFLAGS="-c -traditional-cpp" \ + LDFLAGS="" \ + OPT_NORMAL="-O2" \ + OPT_INLINE="-O3" + hpux-pa-risc-gcc: $(LN) pa-risc.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS)" + CFLAGS="-c -Wall -O3 -fomit-frame-pointer" hpux-pa-risc-cc: $(LN) pa-risc.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS)" \ CPP=cc CC=cc AS=cc LD=cc \ CFLAGS="-c -Aa -D_HPUX_SOURCE -DANSI_CPP" \ LDFLAGS="-s" \ @@ -319,7 +373,6 @@ irix-mips32-cc: $(LN) mips32.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS)" \ CPP=cc CC=cc AS=cc LD=cc \ CFLAGS="-c -O2 -32 -signed" \ LDFLAGS="-s -32" \ @@ -329,7 +382,15 @@ irix-mips64-cc: $(LN) mips64.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS)" \ + CPP=cc CC=cc AS=cc LD=cc \ + CFLAGS="-c -O2 -64 -mips3 -signed" \ + LDFLAGS="-s -64 -mips3" \ + OPT_NORMAL="-LNO:opt=1 -OPT:Olimit=2194" \ + OPT_INLINE="-INLINE:all" + +irix-mips64-r10k-cc: + $(LN) mips64.h arch.h + $(MAKE) $(PROJ) \ CPP=cc CC=cc AS=cc LD=cc \ CFLAGS="-c -O2 -64 -mips4 -r10000 -signed" \ LDFLAGS="-s -64 -mips4 -r10000" \ @@ -340,50 +401,40 @@ copy x86-any.h arch.h $(MAKE) $(PROJ_DOS) \ JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -m486" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG" dos-djgpp-x86-mmx: copy x86-mmx.h arch.h $(MAKE) $(PROJ_DOS) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -m486" \ - ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG" - -dos-djgpp-x86-k6: - copy x86-k6.h arch.h - copy nonstd.c DES_bs_s.c - $(MAKE) $(PROJ_DOS) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS) x86.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG" win32-cygwin-x86-any: $(CP) x86-any.h arch.h $(MAKE) $(PROJ_WIN32) \ JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -mpentium" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES" win32-cygwin-x86-mmx: $(CP) x86-mmx.h arch.h $(MAKE) $(PROJ_WIN32) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o" \ - CFLAGS="$(CFLAGS) -mpentium" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES" -win32-cygwin-x86-k6: - $(CP) x86-k6.h arch.h - $(CP) nonstd.c DES_bs_s.c - $(MAKE) $(PROJ_WIN32) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS) x86.o" \ - CFLAGS="-c -Wall -O -fomit-frame-pointer" \ - ASFLAGS="$(ASFLAGS) -DUNDERSCORES" +beos-x86-any: + $(LN) x86-any.h arch.h + $(MAKE) $(PROJ) \ + JOHN_OBJS="$(JOHN_OBJS) x86.o" + +beos-x86-mmx: + $(LN) x86-mmx.h arch.h + $(MAKE) $(PROJ) \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" generic: generic.h $(RM) arch.h ln -s generic.h arch.h - $(MAKE) $(PROJ) \ - JOHN_OBJS="$(BITSLICE_OBJS) $(JOHN_OBJS)" + $(MAKE) $(PROJ) generic.h: $(RM) arch.h @@ -401,12 +452,15 @@ $(LD) $(LDFLAGS) $(JOHN_OBJS) -o ../run/john ../run/unshadow: ../run/john + $(RM) ../run/unshadow ln -s john ../run/unshadow ../run/unafs: ../run/john + $(RM) ../run/unafs ln -s john ../run/unafs ../run/unique: ../run/john + $(RM) ../run/unique ln -s john ../run/unique ../run/john.bin: $(JOHN_OBJS) @@ -446,7 +500,7 @@ strip ../run/unique.exe # Inlining the S-boxes produces faster code, as long as they fit in the cache -# (that is, on RISC with at least 8 Kb of L1 code cache). +# (that is, on RISC with at least 8 KB of L1 code cache). DES_bs_b.o: DES_bs_b.c DES_bs_s.c $(CC) $(CFLAGS) $(OPT_INLINE) DES_bs_b.c diff -ruN john-1.6/src/math.h john-1.6.34/src/math.h --- john-1.6/src/math.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/math.h 2001-02-16 06:48:37.000000000 +0100 @@ -1,15 +1,18 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* - * 64 bit integer math functions. + * 64-bit integer math functions. */ #ifndef _JOHN_MATH_H #define _JOHN_MATH_H +#undef int64 +#define int64 _john_int64_t + typedef struct { unsigned int lo, hi; } int64; diff -ruN john-1.6/src/MD5_fmt.c john-1.6.34/src/MD5_fmt.c --- john-1.6/src/MD5_fmt.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/MD5_fmt.c 2001-11-13 12:34:32.000000000 +0100 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include @@ -23,8 +23,8 @@ #define BINARY_SIZE 4 #define SALT_SIZE 8 -#define MIN_KEYS_PER_CRYPT 1 -#define MAX_KEYS_PER_CRYPT 1 +#define MIN_KEYS_PER_CRYPT MD5_N +#define MAX_KEYS_PER_CRYPT MD5_N static struct fmt_tests tests[] = { {"$1$12345678$aIccj83HRDBo6ux1bVx7D1", "0123456789ABCDE"}, @@ -34,7 +34,7 @@ {NULL} }; -static char saved_key[PLAINTEXT_LENGTH + 1]; +static char saved_key[MD5_N][PLAINTEXT_LENGTH + 1]; static int valid(char *ciphertext) { @@ -43,12 +43,14 @@ if (strncmp(ciphertext, "$1$", 3)) return 0; for (pos = &ciphertext[3]; *pos && *pos != '$'; pos++); - if (!*pos || pos < &ciphertext[4] || pos > &ciphertext[11]) return 0; + if (!*pos || pos < &ciphertext[3] || pos > &ciphertext[11]) return 0; start = ++pos; - while (atoi64[(ARCH_INDEX)*pos] != 0x7F) pos++; + while (atoi64[ARCH_INDEX(*pos)] != 0x7F) pos++; if (*pos || pos - start != CIPHERTEXT_LENGTH) return 0; + if (atoi64[ARCH_INDEX(*(pos - 1))] & 0x3C) return 0; + return 1; } @@ -69,48 +71,53 @@ static int get_hash_0(int index) { - return MD5_out[0] & 0xF; + return MD5_out[index][0] & 0xF; } static int get_hash_1(int index) { - return MD5_out[0] & 0xFF; + return MD5_out[index][0] & 0xFF; } static int get_hash_2(int index) { - return MD5_out[0] & 0xFFF; + return MD5_out[index][0] & 0xFFF; } static int salt_hash(void *salt) { return - ((int)atoi64[(ARCH_INDEX)((char *)salt)[0]] | - ((int)atoi64[(ARCH_INDEX)((char *)salt)[1]] << 6)) & 0x3FF; + ((int)atoi64[ARCH_INDEX(((char *)salt)[0])] | + ((int)atoi64[ARCH_INDEX(((char *)salt)[1])] << 6)) & 0x3FF; } static void set_key(char *key, int index) { - MD5_std_set_key(key); + MD5_std_set_key(key, index); - strnfcpy(saved_key, key, PLAINTEXT_LENGTH); + strnfcpy(saved_key[index], key, PLAINTEXT_LENGTH); } static char *get_key(int index) { - saved_key[PLAINTEXT_LENGTH] = 0; + saved_key[index][PLAINTEXT_LENGTH] = 0; - return saved_key; + return saved_key[index]; } static int cmp_all(void *binary, int index) { - return *(MD5_word *)binary == MD5_out[0]; +#if MD5_X2 + return *(MD5_word *)binary == MD5_out[0][0] || + *(MD5_word *)binary == MD5_out[1][0]; +#else + return *(MD5_word *)binary == MD5_out[0][0]; +#endif } static int cmp_exact(char *source, int index) { - return !memcmp(MD5_std_get_binary(source), MD5_out, + return !memcmp(MD5_std_get_binary(source), MD5_out[index], sizeof(MD5_binary)); } @@ -129,7 +136,7 @@ FMT_CASE | FMT_8_BIT, tests }, { - fmt_default_init, + MD5_std_init, valid, fmt_default_split, (void *(*)(char *))MD5_std_get_binary, @@ -143,6 +150,7 @@ (void (*)(void *))MD5_std_set_salt, set_key, get_key, + fmt_default_clear_keys, (void (*)(int))MD5_std_crypt, { get_hash_0, diff -ruN john-1.6/src/MD5_std.c john-1.6.34/src/MD5_std.c --- john-1.6/src/MD5_std.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/MD5_std.c 2001-06-17 08:52:32.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer * * Based on the RSA Data Security, Inc. MD5 Message-Digest Algorithm and * FreeBSD MD5-based crypt(3) by Poul-Henning Kamp . @@ -14,12 +14,34 @@ #include "common.h" #include "MD5_std.h" -MD5_binary MD5_out; +MD5_std_combined CC_CACHE_ALIGN MD5_std_all; -typedef union { - MD5_word w[15]; - char b[60]; -} MD5_block; +#if !MD5_IMM +static MD5_data MD5_data_init = { + { + 0xd76aa477, 0xf8fa0bcc, 0xbcdb4dd9, 0xb18b7a77, + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + }, { + 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 + }, { + 0x77777777, 0x00ff00ff + } +}; +#endif #if !MD5_ASM @@ -40,11 +62,6 @@ #define S43 15 #define S44 21 -#define Ca 0x67452301 -#define Cb 0xefcdab89 -#define Cc 0x98badcfe -#define Cd 0x10325476 - #if MD5_IMM /* @@ -52,9 +69,9 @@ */ #define AC1 0xd76aa477 -#define AC2 0xe8c7b756 -#define AC3 0x242070db -#define AC4 0xc1bdceee +#define AC2pCd 0xf8fa0bcc +#define AC3pCc 0xbcdb4dd9 +#define AC4pCb 0xb18b7a77 #define AC5 0xf57c0faf #define AC6 0x4787c62a #define AC7 0xa8304613 @@ -115,40 +132,28 @@ #define AC62 0xbd3af235 #define AC63 0x2ad7d2bb #define AC64 0xeb86d391 + +#define Ca 0x67452301 +#define Cb 0xefcdab89 +#define Cc 0x98badcfe +#define Cd 0x10325476 + #define MASK1 0x77777777 +#define OOFFOOFF 0x00ff00ff + #else /* - * If we used immediate values on RISC with 32 bit instruction size, it would - * take 130 instructions to load all the 65 values. Keeping the values in an - * array instead reduces the instruction count to 67. + * If we used immediate values on RISC with 32-bit instruction size, it would + * take about twice more instructions to load all the values. */ -static MD5_word MD5_AC[65] = { - 0xd76aa477, 0xe8c7b756, 0x242070db, 0xc1bdceee, - 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, - 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, - 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, - 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, - 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, - 0x77777777 -}; - +#define MD5_AC MD5_std_all.data.AC #define AC1 MD5_AC[0] -#define AC2 MD5_AC[1] -#define AC3 MD5_AC[2] -#define AC4 MD5_AC[3] +#define AC2pCd MD5_AC[1] +#define AC3pCc MD5_AC[2] +#define AC4pCb MD5_AC[3] #define AC5 MD5_AC[4] #define AC6 MD5_AC[5] #define AC7 MD5_AC[6] @@ -209,7 +214,16 @@ #define AC62 MD5_AC[61] #define AC63 MD5_AC[62] #define AC64 MD5_AC[63] -#define MASK1 MD5_AC[64] + +#define MD5_IV MD5_std_all.data.IV +#define Ca MD5_IV[0] +#define Cb MD5_IV[1] +#define Cc MD5_IV[2] +#define Cd MD5_IV[3] + +#define MASK1 MD5_std_all.data.masks[0] + +#define OOFFOOFF MD5_std_all.data.masks[1] #endif @@ -225,7 +239,7 @@ * ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) \ - (x) = (((x) << (n)) | ((x) >> (32 - (n)))) + (x) = (((x) << (n)) | ((MD5_word)(x) >> (32 - (n)))) /* * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. @@ -252,16 +266,339 @@ ROTATE_LEFT ((a), (s)); \ (a) += (b); +#if MD5_X2 +static void MD5_body(MD5_word x0[15], MD5_word x1[15], + MD5_word out0[4], MD5_word out1[4]); +#else +static void MD5_body(MD5_word x[15], MD5_word out[4]); +#endif + +#else + +extern void MD5_body(MD5_word x[15], MD5_word out[4]); + +#endif + +static unsigned char PADDING[56] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +#if ARCH_LITTLE_ENDIAN + +#define MD5_swap(x, y, count) + +#else + +static void MD5_swap(MD5_word *x, MD5_word *y, int count) +{ + register MD5_word tmp, mask; + + mask = OOFFOOFF; + do { + tmp = *x++; + ROTATE_LEFT(tmp, 16); + *y++ = ((tmp & mask) << 8) | ((tmp >> 8) & mask); + } while (--count); +} + +#endif + +#define order MD5_std_all.order +#define pool MD5_std_all.pool +#define block MD5_std_all.block + +static void init_line(int line, int index, MD5_block *even, MD5_block *odd) +{ + order[line][index].even = even; + order[line][index].odd = odd; +} + +void MD5_std_init(void) +{ + int index; + MD5_pool *current; + +#if !MD5_IMM + MD5_std_all.data = MD5_data_init; +#endif + + for (index = 0, current = pool; index < MD5_N; index++, current++) { + init_line(0, index, ¤t->e.p, ¤t->o.psp); + init_line(1, index, ¤t->e.spp, ¤t->o.pp); + init_line(2, index, ¤t->e.spp, ¤t->o.psp); + init_line(3, index, ¤t->e.pp, ¤t->o.ps); + init_line(4, index, ¤t->e.spp, ¤t->o.pp); + init_line(5, index, ¤t->e.spp, ¤t->o.psp); + init_line(6, index, ¤t->e.pp, ¤t->o.psp); + init_line(7, index, ¤t->e.sp, ¤t->o.pp); + init_line(8, index, ¤t->e.spp, ¤t->o.psp); + init_line(9, index, ¤t->e.pp, ¤t->o.psp); + init_line(10, index, ¤t->e.spp, ¤t->o.p); + init_line(11, index, ¤t->e.spp, ¤t->o.psp); + init_line(12, index, ¤t->e.pp, ¤t->o.psp); + init_line(13, index, ¤t->e.spp, ¤t->o.pp); + init_line(14, index, ¤t->e.sp, ¤t->o.psp); + init_line(15, index, ¤t->e.pp, ¤t->o.psp); + init_line(16, index, ¤t->e.spp, ¤t->o.pp); + init_line(17, index, ¤t->e.spp, ¤t->o.ps); + init_line(18, index, ¤t->e.pp, ¤t->o.psp); + init_line(19, index, ¤t->e.spp, ¤t->o.pp); + init_line(20, index, ¤t->e.spp, ¤t->o.psp); + } +} + +void MD5_std_set_salt(char *salt) +{ + int length; + + for (length = 0; length < 8 && salt[length]; length++); + + memcpy(pool[0].s, salt, pool[0].l.s = length); +#if MD5_X2 + memcpy(pool[1].s, salt, pool[1].l.s = length); +#endif +} + +void MD5_std_set_key(char *key, int index) +{ + int length; + MD5_pool *current; + + for (length = 0; key[length] && length < 15; length++); + current = &pool[index]; + + memcpy(current->o.p.b, key, current->l.p = length); + memcpy(¤t->o.p.b[length + 16], PADDING, 40 - length); + current->o.p.w[14] = (length + 16) << 3; + + memcpy(current->o.pp.b, key, length); + memcpy(¤t->o.pp.b[length], key, length); + current->l.pp = length << 1; + memcpy(¤t->o.pp.b[current->l.pp + 16], PADDING, + 40 - current->l.pp); + current->o.pp.w[14] = (current->l.pp + 16) << 3; + + memcpy(¤t->e.p.b[16], key, length); + memcpy(¤t->e.p.b[16 + length], PADDING, 40 - length); + current->e.p.w[14] = (length + 16) << 3; + MD5_swap(current->e.p.w, current->e.p.w, 14); + + memcpy(¤t->e.pp.b[16], current->o.pp.b, current->l.pp); + memcpy(¤t->e.pp.b[16 + current->l.pp], PADDING, + 40 - current->l.pp); + current->e.pp.w[14] = (current->l.pp + 16) << 3; + MD5_swap(current->e.pp.w, current->e.pp.w, 14); + + order[1][index].length = current->l.pp; + order[4][index].length = current->l.pp; + order[7][index].length = current->l.pp; + order[10][index].length = length; + order[13][index].length = current->l.pp; + order[16][index].length = current->l.pp; + order[19][index].length = current->l.pp; +} + +void MD5_std_crypt(void) +{ + int length, index, mask; + MD5_pattern *line; +#if ARCH_LITTLE_ENDIAN + MD5_word *last0; +#endif +#if MD5_X2 + MD5_pool *key; +#if ARCH_LITTLE_ENDIAN + MD5_word *last1; +#endif +#endif + +#if MD5_X2 + for (index = 0, key = pool; index < MD5_N; index++, key++) { +#else +#define index 0 +#define key pool +#endif + memcpy(key->o.ps.b, key->o.p.b, key->l.p); + memcpy(&key->o.ps.b[key->l.p], key->s, key->l.s); + key->l.ps = key->l.p + key->l.s; + memcpy(&key->o.ps.b[key->l.ps + 16], PADDING, + 40 - key->l.ps); + key->o.ps.w[14] = (key->l.ps + 16) << 3; + + memcpy(key->o.psp.b, key->o.ps.b, key->l.ps); + memcpy(&key->o.psp.b[key->l.ps], key->o.p.b, key->l.p); + key->l.psp = key->l.ps + key->l.p; + memcpy(&key->o.psp.b[key->l.psp + 16], PADDING, + 40 - key->l.psp); + key->o.psp.w[14] = (key->l.psp + 16) << 3; + + memcpy(&key->e.sp.b[16], key->s, key->l.s); + memcpy(&key->e.sp.b[16 + key->l.s], key->o.p.b, + key->l.p); + memcpy(&key->e.sp.b[16 + key->l.ps], PADDING, + 40 - key->l.ps); + key->e.sp.w[14] = (key->l.ps + 16) << 3; + MD5_swap(key->e.sp.w, key->e.sp.w, 14); + + memcpy(&key->e.spp.b[16], key->s, key->l.s); + memcpy(&key->e.spp.b[16 + key->l.s], key->o.pp.b, + key->l.pp); + memcpy(&key->e.spp.b[16 + key->l.psp], PADDING, + 40 - key->l.psp); + key->e.spp.w[14] = (key->l.psp + 16) << 3; + MD5_swap(key->e.spp.w, key->e.spp.w, 14); + + order[0][index].length = key->l.psp; + order[2][index].length = key->l.psp; + order[3][index].length = key->l.ps; + order[5][index].length = key->l.psp; + order[6][index].length = key->l.psp; + order[8][index].length = key->l.psp; + order[9][index].length = key->l.psp; + order[11][index].length = key->l.psp; + order[12][index].length = key->l.psp; + order[14][index].length = key->l.psp; + order[15][index].length = key->l.psp; + order[17][index].length = key->l.ps; + order[18][index].length = key->l.psp; + order[20][index].length = key->l.psp; + + memcpy(&block[index], key->o.psp.b, key->l.psp); + memcpy(&block[index].b[key->l.psp], PADDING, 56 - key->l.psp); + block[index].w[14] = key->l.psp << 3; + MD5_swap(block[index].w, block[index].w, 14); +#if MD5_X2 + } + + MD5_body(block[0].w, block[1].w, MD5_out[0], MD5_out[1]); + MD5_swap(MD5_out[0], MD5_out[0], 8); +#else + MD5_body(block[0].w, MD5_out[0]); + MD5_swap(MD5_out[0], MD5_out[0], 4); +#endif + +#if MD5_X2 + for (index = 0, key = pool; index < MD5_N; index++, key++) { +#endif + memcpy(&block[index], key->o.p.b, key->l.p); + memcpy(&block[index].b[key->l.p], "$1$", 3); + memcpy(&block[index].b[key->l.p + 3], key->s, key->l.s); + memcpy(&block[index].b[key->l.ps + 3], + MD5_out[index], key->l.p); + length = key->l.psp + 3; + if ((mask = key->l.p)) + do { + block[index].b[length++] = + (mask & 1) ? 0 : key->o.p.b[0]; + } while (mask >>= 1); + memcpy(&block[index].b[length], PADDING, 56 - length); + block[index].w[14] = length << 3; + MD5_swap(block[index].w, block[index].w, 14); +#if MD5_X2 + } +#else +#undef index +#undef key +#endif + +#if MD5_X2 + MD5_body(block[0].w, block[1].w, + order[0][0].even->w, order[0][1].even->w); +#else + MD5_body(block[0].w, order[0][0].even->w); +#endif + + index = 500; line = order[0]; + do { +#if ARCH_LITTLE_ENDIAN +#if ARCH_ALLOWS_UNALIGNED +#if MD5_X2 + MD5_body(line[0].even->w, line[1].even->w, + (MD5_word *)&line[0].odd->b[line[0].length], + (MD5_word *)&line[1].odd->b[line[1].length]); +#else + MD5_body(line[0].even->w, + (MD5_word *)&line[0].odd->b[line[0].length]); +#endif +#else +#if MD5_X2 + MD5_body(line[0].even->w, line[1].even->w, + MD5_out[0], MD5_out[1]); + memcpy(&line[0].odd->b[line[0].length], MD5_out[0], 16); + memcpy(&line[1].odd->b[line[1].length], MD5_out[1], 16); +#else + if (((ARCH_WORD)&line[0].odd->b[line[0].length]) & 3) { + MD5_body(line[0].even->w, MD5_out[0]); + memcpy(&line[0].odd->b[line[0].length], + MD5_out[0], 16); + } else { + MD5_body(line[0].even->w, + (MD5_word *)&line[0].odd->b[line[0].length]); + } +#endif +#endif + last0 = line[0].odd->w; +#if MD5_X2 + last1 = line[1].odd->w; + if ((line += 2) > &order[20][MD5_N - 1]) line = order[0]; + MD5_body(last0, last1, line[0].even->w, line[1].even->w); +#else + if (++line > &order[20][0]) line = order[0]; + MD5_body(last0, line[0].even->w); +#endif +#else +#if MD5_X2 + MD5_body(line[0].even->w, line[1].even->w, + MD5_out[0], MD5_out[1]); + MD5_swap(MD5_out[0], MD5_out[0], 8); +#else + MD5_body(line[0].even->w, MD5_out[0]); + MD5_swap(MD5_out[0], MD5_out[0], 4); +#endif + memcpy(&line[0].odd->b[line[0].length], MD5_out[0], 16); +#if MD5_X2 + memcpy(&line[1].odd->b[line[1].length], MD5_out[1], 16); +#endif + MD5_swap(line[0].odd->w, block[0].w, 14); + block[0].w[14] = line[0].odd->w[14]; +#if MD5_X2 + MD5_swap(line[1].odd->w, block[1].w, 14); + block[1].w[14] = line[1].odd->w[14]; + if ((line += 2) > &order[20][MD5_N - 1]) line = order[0]; + MD5_body(block[0].w, block[1].w, + line[0].even->w, line[1].even->w); +#else + if (++line > &order[20][0]) line = order[0]; + MD5_body(block[0].w, line[0].even->w); +#endif +#endif + } while (--index); + + memcpy(MD5_out[0], line[0].even, 16); +#if MD5_X2 + memcpy(MD5_out[1], line[1].even, 16); +#endif +} + +#if !MD5_ASM + +#if !MD5_X2 + static void MD5_body(MD5_word x[15], MD5_word out[4]) { - register MD5_word a, b = Cb, c = Cc, d = Cd; + register unsigned ARCH_WORD a, b = Cb, c = Cc, d; /* Round 1 */ - a = AC1 + x[0]; ROTATE_LEFT (a, S11); a += b; /* 1 */ - d += (c ^ (a & MASK1)) + x[1] + AC2; + a = AC1 + x[0]; + ROTATE_LEFT (a, S11); a += b; /* 1 */ + d = (c ^ (a & MASK1)) + x[1] + AC2pCd; ROTATE_LEFT (d, S12); d += a; /* 2 */ - FF (c, d, a, b, x[ 2], S13, AC3); /* 3 */ - FF (b, c, d, a, x[ 3], S14, AC4); /* 4 */ + c = F(d, a, b) + x[2] + AC3pCc; + ROTATE_LEFT(c, S13); c += d; /* 3 */ + b = F(c, d, a) + x[3] + AC4pCb; + ROTATE_LEFT(b, S14); b += c; /* 4 */ FF (a, b, c, d, x[ 4], S11, AC5); /* 5 */ FF (d, a, b, c, x[ 5], S12, AC6); /* 6 */ FF (c, d, a, b, x[ 6], S13, AC7); /* 7 */ @@ -341,224 +678,180 @@ #else -extern void MD5_body(MD5_word x[15], MD5_word out[4]); - -#endif - -#if ARCH_LITTLE_ENDIAN - -#define MD5_swap(x, y, count) - -#else - -static void MD5_swap(MD5_word *x, MD5_word *y, int count) +static void MD5_body(MD5_word x0[15], MD5_word x1[15], + MD5_word out0[4], MD5_word out1[4]) { - MD5_word tmp; + register unsigned ARCH_WORD a0, b0 = Cb, c0 = Cc, d0; + register unsigned ARCH_WORD a1, b1, c1, d1; + register unsigned ARCH_WORD u, v; - do { - tmp = *x++; - ROTATE_LEFT(tmp, 16); - *y++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF); - } while (--count); -} - -#endif - -static unsigned char PADDING[56] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -static struct { - char s[8]; - struct { - int p, s, ps, pp, psp; - } l; - struct { - MD5_block p, sp, pp, spp; - } e; - struct { - MD5_block p, ps, pp, psp; - } o; -} patterns; - -struct pattern { - int length; - MD5_block *even, *odd; -}; - -static struct pattern order[21] = { - {0, &patterns.e.p, &patterns.o.psp}, - {0, &patterns.e.spp, &patterns.o.pp}, - {0, &patterns.e.spp, &patterns.o.psp}, - {0, &patterns.e.pp, &patterns.o.ps}, - {0, &patterns.e.spp, &patterns.o.pp}, - {0, &patterns.e.spp, &patterns.o.psp}, - {0, &patterns.e.pp, &patterns.o.psp}, - {0, &patterns.e.sp, &patterns.o.pp}, - {0, &patterns.e.spp, &patterns.o.psp}, - {0, &patterns.e.pp, &patterns.o.psp}, - {0, &patterns.e.spp, &patterns.o.p}, - {0, &patterns.e.spp, &patterns.o.psp}, - {0, &patterns.e.pp, &patterns.o.psp}, - {0, &patterns.e.spp, &patterns.o.pp}, - {0, &patterns.e.sp, &patterns.o.psp}, - {0, &patterns.e.pp, &patterns.o.psp}, - {0, &patterns.e.spp, &patterns.o.pp}, - {0, &patterns.e.spp, &patterns.o.ps}, - {0, &patterns.e.pp, &patterns.o.psp}, - {0, &patterns.e.spp, &patterns.o.pp}, - {0, &patterns.e.spp, &patterns.o.psp}, -}; - -void MD5_std_set_salt(char *salt) -{ - int length; - - for (length = 0; salt[length] && length < 8; length++); - - memcpy(patterns.s, salt, patterns.l.s = length); -} +/* Round 1 */ + a0 = (u = AC1) + x0[0]; + ROTATE_LEFT (a0, S11); a0 += b0; /* 1 */ + a1 = u + x1[0]; + ROTATE_LEFT (a1, S11); a1 += b0; /* 1 */ + d0 = (c0 ^ (a0 & (u = MASK1))) + x0[1] + (v = AC2pCd); + ROTATE_LEFT (d0, S12); d0 += a0; /* 2 */ + d1 = (c0 ^ (a1 & u)) + x1[1] + v; + ROTATE_LEFT (d1, S12); d1 += a1; /* 2 */ + c0 = F(d0, a0, b0) + x0[2] + (u = AC3pCc); + ROTATE_LEFT(c0, S13); c0 += d0; /* 3 */ + c1 = F(d1, a1, b0) + x1[2] + u; + ROTATE_LEFT(c1, S13); c1 += d1; /* 3 */ + b0 = F(c0, d0, a0) + x0[3] + (u = AC4pCb); + ROTATE_LEFT(b0, S14); b0 += c0; /* 4 */ + b1 = F(c1, d1, a1) + x1[3] + u; + ROTATE_LEFT(b1, S14); b1 += c1; /* 4 */ + FF (a0, b0, c0, d0, x0[ 4], S11, (u = AC5)); /* 5 */ + FF (a1, b1, c1, d1, x1[ 4], S11, u); /* 5 */ + FF (d0, a0, b0, c0, x0[ 5], S12, (u = AC6)); /* 6 */ + FF (d1, a1, b1, c1, x1[ 5], S12, u); /* 6 */ + FF (c0, d0, a0, b0, x0[ 6], S13, (u = AC7)); /* 7 */ + FF (c1, d1, a1, b1, x1[ 6], S13, u); /* 7 */ + FF (b0, c0, d0, a0, x0[ 7], S14, (u = AC8)); /* 8 */ + FF (b1, c1, d1, a1, x1[ 7], S14, u); /* 8 */ + FF (a0, b0, c0, d0, x0[ 8], S11, (u = AC9)); /* 9 */ + FF (a1, b1, c1, d1, x1[ 8], S11, u); /* 9 */ + FF (d0, a0, b0, c0, x0[ 9], S12, (u = AC10)); /* 10 */ + FF (d1, a1, b1, c1, x1[ 9], S12, u); /* 10 */ + FF (c0, d0, a0, b0, x0[10], S13, (u = AC11)); /* 11 */ + FF (c1, d1, a1, b1, x1[10], S13, u); /* 11 */ + FF (b0, c0, d0, a0, x0[11], S14, (u = AC12)); /* 12 */ + FF (b1, c1, d1, a1, x1[11], S14, u); /* 12 */ + FF (a0, b0, c0, d0, x0[12], S11, (u = AC13)); /* 13 */ + FF (a1, b1, c1, d1, x1[12], S11, u); /* 13 */ + FF (d0, a0, b0, c0, x0[13], S12, (u = AC14)); /* 14 */ + FF (d1, a1, b1, c1, x1[13], S12, u); /* 14 */ + FF (c0, d0, a0, b0, x0[14], S13, (u = AC15)); /* 15 */ + FF (c1, d1, a1, b1, x1[14], S13, u); /* 15 */ + b0 += F (c0, d0, a0) + (u = AC16); + ROTATE_LEFT (b0, S14); b0 += c0; /* 16 */ + b1 += F (c1, d1, a1) + u; + ROTATE_LEFT (b1, S14); b1 += c1; /* 16 */ -void MD5_std_set_key(char *key) -{ - int length; +/* Round 2 */ + GG (a0, b0, c0, d0, x0[ 1], S21, (u = AC17)); /* 17 */ + GG (a1, b1, c1, d1, x1[ 1], S21, u); /* 17 */ + GG (d0, a0, b0, c0, x0[ 6], S22, (u = AC18)); /* 18 */ + GG (d1, a1, b1, c1, x1[ 6], S22, u); /* 18 */ + GG (c0, d0, a0, b0, x0[11], S23, (u = AC19)); /* 19 */ + GG (c1, d1, a1, b1, x1[11], S23, u); /* 19 */ + GG (b0, c0, d0, a0, x0[ 0], S24, (u = AC20)); /* 20 */ + GG (b1, c1, d1, a1, x1[ 0], S24, u); /* 20 */ + GG (a0, b0, c0, d0, x0[ 5], S21, (u = AC21)); /* 21 */ + GG (a1, b1, c1, d1, x1[ 5], S21, u); /* 21 */ + GG (d0, a0, b0, c0, x0[10], S22, (u = AC22)); /* 22 */ + GG (d1, a1, b1, c1, x1[10], S22, u); /* 22 */ + c0 += G (d0, a0, b0) + (u = AC23); + ROTATE_LEFT (c0, S23); c0 += d0; /* 23 */ + c1 += G (d1, a1, b1) + u; + ROTATE_LEFT (c1, S23); c1 += d1; /* 23 */ + GG (b0, c0, d0, a0, x0[ 4], S24, (u = AC24)); /* 24 */ + GG (b1, c1, d1, a1, x1[ 4], S24, u); /* 24 */ + GG (a0, b0, c0, d0, x0[ 9], S21, (u = AC25)); /* 25 */ + GG (a1, b1, c1, d1, x1[ 9], S21, u); /* 25 */ + GG (d0, a0, b0, c0, x0[14], S22, (u = AC26)); /* 26 */ + GG (d1, a1, b1, c1, x1[14], S22, u); /* 26 */ + GG (c0, d0, a0, b0, x0[ 3], S23, (u = AC27)); /* 27 */ + GG (c1, d1, a1, b1, x1[ 3], S23, u); /* 27 */ + GG (b0, c0, d0, a0, x0[ 8], S24, (u = AC28)); /* 28 */ + GG (b1, c1, d1, a1, x1[ 8], S24, u); /* 28 */ + GG (a0, b0, c0, d0, x0[13], S21, (u = AC29)); /* 29 */ + GG (a1, b1, c1, d1, x1[13], S21, u); /* 29 */ + GG (d0, a0, b0, c0, x0[ 2], S22, (u = AC30)); /* 30 */ + GG (d1, a1, b1, c1, x1[ 2], S22, u); /* 30 */ + GG (c0, d0, a0, b0, x0[ 7], S23, (u = AC31)); /* 31 */ + GG (c1, d1, a1, b1, x1[ 7], S23, u); /* 31 */ + GG (b0, c0, d0, a0, x0[12], S24, (u = AC32)); /* 32 */ + GG (b1, c1, d1, a1, x1[12], S24, u); /* 32 */ - for (length = 0; key[length] && length < 15; length++); +/* Round 3 */ + HH (a0, b0, c0, d0, x0[ 5], S31, (u = AC33)); /* 33 */ + HH (a1, b1, c1, d1, x1[ 5], S31, u); /* 33 */ + HH (d0, a0, b0, c0, x0[ 8], S32, (u = AC34)); /* 34 */ + HH (d1, a1, b1, c1, x1[ 8], S32, u); /* 34 */ + HH (c0, d0, a0, b0, x0[11], S33, (u = AC35)); /* 35 */ + HH (c1, d1, a1, b1, x1[11], S33, u); /* 35 */ + HH (b0, c0, d0, a0, x0[14], S34, (u = AC36)); /* 36 */ + HH (b1, c1, d1, a1, x1[14], S34, u); /* 36 */ + HH (a0, b0, c0, d0, x0[ 1], S31, (u = AC37)); /* 37 */ + HH (a1, b1, c1, d1, x1[ 1], S31, u); /* 37 */ + HH (d0, a0, b0, c0, x0[ 4], S32, (u = AC38)); /* 38 */ + HH (d1, a1, b1, c1, x1[ 4], S32, u); /* 38 */ + HH (c0, d0, a0, b0, x0[ 7], S33, (u = AC39)); /* 39 */ + HH (c1, d1, a1, b1, x1[ 7], S33, u); /* 39 */ + HH (b0, c0, d0, a0, x0[10], S34, (u = AC40)); /* 40 */ + HH (b1, c1, d1, a1, x1[10], S34, u); /* 40 */ + HH (a0, b0, c0, d0, x0[13], S31, (u = AC41)); /* 41 */ + HH (a1, b1, c1, d1, x1[13], S31, u); /* 41 */ + HH (d0, a0, b0, c0, x0[ 0], S32, (u = AC42)); /* 42 */ + HH (d1, a1, b1, c1, x1[ 0], S32, u); /* 42 */ + HH (c0, d0, a0, b0, x0[ 3], S33, (u = AC43)); /* 43 */ + HH (c1, d1, a1, b1, x1[ 3], S33, u); /* 43 */ + HH (b0, c0, d0, a0, x0[ 6], S34, (u = AC44)); /* 44 */ + HH (b1, c1, d1, a1, x1[ 6], S34, u); /* 44 */ + HH (a0, b0, c0, d0, x0[ 9], S31, (u = AC45)); /* 45 */ + HH (a1, b1, c1, d1, x1[ 9], S31, u); /* 45 */ + HH (d0, a0, b0, c0, x0[12], S32, (u = AC46)); /* 46 */ + HH (d1, a1, b1, c1, x1[12], S32, u); /* 46 */ + c0 += H (d0, a0, b0) + (u = AC47); + ROTATE_LEFT (c0, S33); c0 += d0; /* 47 */ + c1 += H (d1, a1, b1) + u; + ROTATE_LEFT (c1, S33); c1 += d1; /* 47 */ + HH (b0, c0, d0, a0, x0[ 2], S34, (u = AC48)); /* 48 */ + HH (b1, c1, d1, a1, x1[ 2], S34, u); /* 48 */ - memcpy(patterns.o.p.b, key, patterns.l.p = length); - memcpy(&patterns.o.p.b[length + 16], PADDING, 40 - length); - patterns.o.p.w[14] = (length + 16) << 3; - - memcpy(patterns.o.pp.b, key, length); - memcpy(&patterns.o.pp.b[length], key, length); - patterns.l.pp = length << 1; - memcpy(&patterns.o.pp.b[patterns.l.pp + 16], PADDING, - 40 - patterns.l.pp); - patterns.o.pp.w[14] = (patterns.l.pp + 16) << 3; - - memcpy(&patterns.e.p.b[16], key, length); - memcpy(&patterns.e.p.b[16 + length], PADDING, 40 - length); - patterns.e.p.w[14] = (length + 16) << 3; - MD5_swap(patterns.e.p.w, patterns.e.p.w, 14); - - memcpy(&patterns.e.pp.b[16], patterns.o.pp.b, patterns.l.pp); - memcpy(&patterns.e.pp.b[16 + patterns.l.pp], PADDING, - 40 - patterns.l.pp); - patterns.e.pp.w[14] = (patterns.l.pp + 16) << 3; - MD5_swap(patterns.e.pp.w, patterns.e.pp.w, 14); - - order[1].length = patterns.l.pp; - order[4].length = patterns.l.pp; - order[7].length = patterns.l.pp; - order[10].length = length; - order[13].length = patterns.l.pp; - order[16].length = patterns.l.pp; - order[19].length = patterns.l.pp; +/* Round 4 */ + II (a0, b0, c0, d0, x0[ 0], S41, (u = AC49)); /* 49 */ + II (a1, b1, c1, d1, x1[ 0], S41, u); /* 49 */ + II (d0, a0, b0, c0, x0[ 7], S42, (u = AC50)); /* 50 */ + II (d1, a1, b1, c1, x1[ 7], S42, u); /* 50 */ + II (c0, d0, a0, b0, x0[14], S43, (u = AC51)); /* 51 */ + II (c1, d1, a1, b1, x1[14], S43, u); /* 51 */ + II (b0, c0, d0, a0, x0[ 5], S44, (u = AC52)); /* 52 */ + II (b1, c1, d1, a1, x1[ 5], S44, u); /* 52 */ + II (a0, b0, c0, d0, x0[12], S41, (u = AC53)); /* 53 */ + II (a1, b1, c1, d1, x1[12], S41, u); /* 53 */ + II (d0, a0, b0, c0, x0[ 3], S42, (u = AC54)); /* 54 */ + II (d1, a1, b1, c1, x1[ 3], S42, u); /* 54 */ + II (c0, d0, a0, b0, x0[10], S43, (u = AC55)); /* 55 */ + II (c1, d1, a1, b1, x1[10], S43, u); /* 55 */ + II (b0, c0, d0, a0, x0[ 1], S44, (u = AC56)); /* 56 */ + II (b1, c1, d1, a1, x1[ 1], S44, u); /* 56 */ + II (a0, b0, c0, d0, x0[ 8], S41, (u = AC57)); /* 57 */ + II (a1, b1, c1, d1, x1[ 8], S41, u); /* 57 */ + d0 += I (a0, b0, c0) + (u = AC58); + ROTATE_LEFT (d0, S42); d0 += a0; /* 58 */ + d1 += I (a1, b1, c1) + u; + ROTATE_LEFT (d1, S42); d1 += a1; /* 58 */ + II (c0, d0, a0, b0, x0[ 6], S43, (u = AC59)); /* 59 */ + II (c1, d1, a1, b1, x1[ 6], S43, u); /* 59 */ + II (b0, c0, d0, a0, x0[13], S44, (u = AC60)); /* 60 */ + II (b1, c1, d1, a1, x1[13], S44, u); /* 60 */ + II (a0, b0, c0, d0, x0[ 4], S41, (u = AC61)); /* 61 */ + II (a1, b1, c1, d1, x1[ 4], S41, u); /* 61 */ + II (d0, a0, b0, c0, x0[11], S42, (u = AC62)); /* 62 */ + II (d1, a1, b1, c1, x1[11], S42, u); /* 62 */ + II (c0, d0, a0, b0, x0[ 2], S43, (u = AC63)); /* 63 */ + II (c1, d1, a1, b1, x1[ 2], S43, u); /* 63 */ + II (b0, c0, d0, a0, x0[ 9], S44, (u = AC64)); /* 64 */ + II (b1, c1, d1, a1, x1[ 9], S44, u); /* 64 */ + + out1[3] = Cd + d1; + + out0[0] = Ca + a0; + out0[1] = Cb + b0; + out0[2] = Cc + c0; + out0[3] = Cd + d0; + + out1[0] = Ca + a1; + out1[1] = Cb + b1; + out1[2] = Cc + c1; } -void MD5_std_crypt() -{ - MD5_block block; - int length, index; - struct pattern *line; -#if ARCH_LITTLE_ENDIAN - MD5_word *last; #endif - memcpy(patterns.o.ps.b, patterns.o.p.b, patterns.l.p); - memcpy(&patterns.o.ps.b[patterns.l.p], patterns.s, patterns.l.s); - patterns.l.ps = patterns.l.p + patterns.l.s; - memcpy(&patterns.o.ps.b[patterns.l.ps + 16], PADDING, - 40 - patterns.l.ps); - patterns.o.ps.w[14] = (patterns.l.ps + 16) << 3; - - memcpy(patterns.o.psp.b, patterns.o.ps.b, patterns.l.ps); - memcpy(&patterns.o.psp.b[patterns.l.ps], patterns.o.p.b, patterns.l.p); - patterns.l.psp = patterns.l.ps + patterns.l.p; - memcpy(&patterns.o.psp.b[patterns.l.psp + 16], PADDING, - 40 - patterns.l.psp); - patterns.o.psp.w[14] = (patterns.l.psp + 16) << 3; - - memcpy(&patterns.e.sp.b[16], patterns.s, patterns.l.s); - memcpy(&patterns.e.sp.b[16 + patterns.l.s], patterns.o.p.b, - patterns.l.p); - memcpy(&patterns.e.sp.b[16 + patterns.l.ps], PADDING, - 40 - patterns.l.ps); - patterns.e.sp.w[14] = (patterns.l.ps + 16) << 3; - MD5_swap(patterns.e.sp.w, patterns.e.sp.w, 14); - - memcpy(&patterns.e.spp.b[16], patterns.s, patterns.l.s); - memcpy(&patterns.e.spp.b[16 + patterns.l.s], patterns.o.pp.b, - patterns.l.pp); - memcpy(&patterns.e.spp.b[16 + patterns.l.psp], PADDING, - 40 - patterns.l.psp); - patterns.e.spp.w[14] = (patterns.l.psp + 16) << 3; - MD5_swap(patterns.e.spp.w, patterns.e.spp.w, 14); - - order[0].length = patterns.l.psp; - order[2].length = patterns.l.psp; - order[3].length = patterns.l.ps; - order[5].length = patterns.l.psp; - order[6].length = patterns.l.psp; - order[8].length = patterns.l.psp; - order[9].length = patterns.l.psp; - order[11].length = patterns.l.psp; - order[12].length = patterns.l.psp; - order[14].length = patterns.l.psp; - order[15].length = patterns.l.psp; - order[17].length = patterns.l.ps; - order[18].length = patterns.l.psp; - order[20].length = patterns.l.psp; - - memcpy(&block, patterns.o.psp.b, patterns.l.psp); - memcpy(&block.b[patterns.l.psp], PADDING, 56 - patterns.l.psp); - block.w[14] = patterns.l.psp << 3; - MD5_swap(block.w, block.w, 14); - MD5_body(block.w, MD5_out); - MD5_swap(MD5_out, MD5_out, 4); - - memcpy(&block, patterns.o.p.b, patterns.l.p); - memcpy(&block.b[patterns.l.p], "$1$", 3); - memcpy(&block.b[patterns.l.p + 3], patterns.s, patterns.l.s); - memcpy(&block.b[patterns.l.ps + 3], MD5_out, patterns.l.p); - length = patterns.l.psp + 3; - if ((index = patterns.l.p)) - do { - block.b[length++] = (index & 1) ? 0 : patterns.o.p.b[0]; - } while (index >>= 1); - memcpy(&block.b[length], PADDING, 56 - length); - block.w[14] = length << 3; - MD5_swap(block.w, block.w, 14); - MD5_body(block.w, order[0].even->w); - - index = 500; line = order; - do { -#if ARCH_LITTLE_ENDIAN -#if ARCH_ALLOWS_UNALIGNED - MD5_body(line->even->w, - (MD5_word *)&line->odd->b[line->length]); -#else - MD5_body(line->even->w, MD5_out); - memcpy(&line->odd->b[line->length], MD5_out, 16); -#endif - last = line->odd->w; - if (++line >= order + 21) line = order; - MD5_body(last, line->even->w); -#else - MD5_body(line->even->w, MD5_out); - MD5_swap(MD5_out, MD5_out, 4); - memcpy(&line->odd->b[line->length], MD5_out, 16); - MD5_swap(line->odd->w, block.w, 14); - block.w[14] = line->odd->w[14]; - if (++line >= order + 21) line = order; - MD5_body(block.w, line->even->w); #endif - } while (--index); - - memcpy(MD5_out, line->even, 16); -} char *MD5_std_get_salt(char *ciphertext) { @@ -574,10 +867,10 @@ #define TO_BINARY(b1, b2, b3) \ value = \ - (MD5_word)atoi64[(ARCH_INDEX)pos[0]] | \ - ((MD5_word)atoi64[(ARCH_INDEX)pos[1]] << 6) | \ - ((MD5_word)atoi64[(ARCH_INDEX)pos[2]] << 12) | \ - ((MD5_word)atoi64[(ARCH_INDEX)pos[3]] << 18); \ + (MD5_word)atoi64[ARCH_INDEX(pos[0])] | \ + ((MD5_word)atoi64[ARCH_INDEX(pos[1])] << 6) | \ + ((MD5_word)atoi64[ARCH_INDEX(pos[2])] << 12) | \ + ((MD5_word)atoi64[ARCH_INDEX(pos[3])] << 18); \ pos += 4; \ out.b[b1] = value >> 16; \ out.b[b2] = value >> 8; \ @@ -600,8 +893,8 @@ TO_BINARY(3, 9, 15); TO_BINARY(4, 10, 5); out.b[11] = - (MD5_word)atoi64[(ARCH_INDEX)pos[0]] | - ((MD5_word)atoi64[(ARCH_INDEX)pos[1]] << 6); + (MD5_word)atoi64[ARCH_INDEX(pos[0])] | + ((MD5_word)atoi64[ARCH_INDEX(pos[1])] << 6); MD5_swap(out.w, out.w, 4); diff -ruN john-1.6/src/MD5_std.h john-1.6.34/src/MD5_std.h --- john-1.6/src/MD5_std.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/MD5_std.h 2000-06-25 07:06:03.000000000 +0200 @@ -1,10 +1,10 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* - * Standard FreeBSD MD5 implementation. + * FreeBSD-style MD5-based password hash implementation. */ #ifndef _JOHN_MD5_STD_H @@ -21,11 +21,77 @@ typedef MD5_word MD5_binary[4]; /* + * Various structures for internal use. + */ + +typedef union { + double dummy; + MD5_word w[15]; + char b[60]; +} MD5_block; + +typedef struct { + int length; + MD5_block *even, *odd; +} MD5_pattern; + +typedef struct { + char s[8]; + struct { + int p, s, ps, pp, psp; + } l; + struct { + MD5_block p, sp, pp, spp; + } e; + struct { + MD5_block p, ps, pp, psp; + } o; +} MD5_pool; + +#if !MD5_IMM +typedef struct { + MD5_word AC[64]; + MD5_word IV[4]; + MD5_word masks[2]; +} MD5_data; +#endif + +#if MD5_X2 +#define MD5_N 2 +#else +#define MD5_N 1 +#endif + +typedef struct { +#if !MD5_IMM + MD5_data data; + double dummy; +#endif + + MD5_binary out[MD5_N]; + + MD5_block block[MD5_N]; + MD5_pattern order[21][MD5_N]; + MD5_pool pool[MD5_N]; +} MD5_std_combined; + +extern MD5_std_combined MD5_std_all; + +/* * MD5_std_crypt() output buffer. */ -extern MD5_binary MD5_out; +#define MD5_out MD5_std_all.out +#if MD5_X2 +#define MD5_ALGORITHM_NAME "32/" ARCH_BITS_STR " X2" +#else #define MD5_ALGORITHM_NAME "32/" ARCH_BITS_STR +#endif + +/* + * Initializes the internal structures. + */ +extern void MD5_std_init(void); /* * Sets a salt for MD5_std_crypt(). @@ -36,12 +102,12 @@ * Sets a key for MD5_std_crypt(). * Currently only supports keys up to 15 characters long. */ -extern void MD5_std_set_key(char *key); +extern void MD5_std_set_key(char *key, int index); /* * Main encryption routine, sets MD5_out. */ -extern void MD5_std_crypt(); +extern void MD5_std_crypt(void); /* * Returns the salt for MD5_std_set_salt(). diff -ruN john-1.6/src/memory.h john-1.6.34/src/memory.h --- john-1.6/src/memory.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/memory.h 1999-06-19 05:34:13.000000000 +0200 @@ -19,6 +19,7 @@ */ #define MEM_ALIGN_NONE 1 #define MEM_ALIGN_WORD ARCH_SIZE +#define MEM_ALIGN_CACHE (ARCH_SIZE * 8) /* * Block size used by mem_alloc_tiny(). diff -ruN john-1.6/src/mips32.h john-1.6.34/src/mips32.h --- john-1.6/src/mips32.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/mips32.h 2000-05-08 09:05:13.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* @@ -10,15 +10,15 @@ #ifndef _JOHN_ARCH_H #define _JOHN_ARCH_H -#define ARCH_GENERIC 1 #define ARCH_WORD long #define ARCH_SIZE 4 #define ARCH_BITS 32 +#define ARCH_BITS_LOG 5 #define ARCH_BITS_STR "32" #define ARCH_LITTLE_ENDIAN 0 #define ARCH_INT_GT_32 0 #define ARCH_ALLOWS_UNALIGNED 0 -#define ARCH_INDEX unsigned int +#define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) #define OS_TIMER 1 #define OS_FLOCK 1 @@ -32,10 +32,14 @@ #define DES_SCALE 1 #define DES_EXTB 0 #define DES_COPY 1 +#define DES_BS_ASM 0 #define DES_BS 1 +#define DES_BS_VECTOR 0 +#define DES_BS_EXPAND 1 #define MD5_ASM 0 -#define MD5_IMM 1 +#define MD5_X2 1 +#define MD5_IMM 0 #define BF_ASM 0 #define BF_SCALE 0 diff -ruN john-1.6/src/mips64.h john-1.6.34/src/mips64.h --- john-1.6/src/mips64.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/mips64.h 2000-05-08 09:05:18.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* @@ -10,15 +10,15 @@ #ifndef _JOHN_ARCH_H #define _JOHN_ARCH_H -#define ARCH_GENERIC 1 #define ARCH_WORD long #define ARCH_SIZE 8 #define ARCH_BITS 64 +#define ARCH_BITS_LOG 6 #define ARCH_BITS_STR "64" #define ARCH_LITTLE_ENDIAN 0 #define ARCH_INT_GT_32 0 #define ARCH_ALLOWS_UNALIGNED 0 -#define ARCH_INDEX unsigned int +#define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) #define OS_TIMER 1 #define OS_FLOCK 1 @@ -32,10 +32,14 @@ #define DES_SCALE 0 #define DES_EXTB 0 #define DES_COPY 0 +#define DES_BS_ASM 0 #define DES_BS 1 +#define DES_BS_VECTOR 0 +#define DES_BS_EXPAND 1 #define MD5_ASM 0 -#define MD5_IMM 1 +#define MD5_X2 1 +#define MD5_IMM 0 #define BF_ASM 0 #define BF_SCALE 0 diff -ruN john-1.6/src/misc.c john-1.6.34/src/misc.c --- john-1.6/src/misc.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/misc.c 1999-09-22 05:57:40.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ #include @@ -10,7 +10,7 @@ #include #include -void error() +void error(void) { exit(1); } diff -ruN john-1.6/src/misc.h john-1.6.34/src/misc.h --- john-1.6/src/misc.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/misc.h 2001-10-22 06:46:52.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ /* @@ -15,7 +15,7 @@ /* * Exit on error. Terminates the process with non-zero exit status. */ -extern void error(); +extern void error(void); /* * Similar to perror(), but supports formatted output, and calls error(). @@ -35,24 +35,24 @@ /* * Similar to fgets(), but doesn't leave the newline character in the buffer, - * and skips to the end of long lines. Handles both UNIX and DOS style text + * and skips to the end of long lines. Handles both Unix and DOS style text * files correctly. */ extern char *fgetl(char *s, int size, FILE *stream); /* - * Similar to strncpy(), but terminates with only one null if there's room - * instead of null padding to the supplied size like strncpy() does. + * Similar to strncpy(), but terminates with only one NUL if there's room + * instead of padding to the supplied size like strncpy() does. */ extern char *strnfcpy(char *dst, char *src, int size); /* - * Similar to the above, but always null terminates the string. + * Similar to the above, but always NUL terminates the string. */ extern char *strnzcpy(char *dst, char *src, int size); /* - * Similar to strncat(), but total buffer size is supplied, and always null + * Similar to strncat(), but total buffer size is supplied, and always NUL * terminates the string. */ extern char *strnzcat(char *dst, char *src, int size); diff -ruN john-1.6/src/options.c john-1.6.34/src/options.c --- john-1.6/src/options.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/options.c 2003-01-15 03:59:01.000000000 +0100 @@ -1,12 +1,13 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2002 by Solar Designer */ #include #include #include +#include "arch.h" #include "misc.h" #include "params.h" #include "memory.h" @@ -66,9 +67,18 @@ {NULL} }; +#if DES_BS +/* nonstd.c and parts of x86-mmx.S aren't mine */ +#define JOHN_COPYRIGHT \ + "Solar Designer and others" +#else +#define JOHN_COPYRIGHT \ + "Solar Designer" +#endif + #define JOHN_USAGE \ -"\nJohn the Ripper Version " JOHN_VERSION \ -" Copyright (c) 1996-98 by Solar Designer\n" \ +"John the Ripper password cracker, version " JOHN_VERSION "\n" \ +"Copyright (c) 1996-2003 by " JOHN_COPYRIGHT "\n" \ "\n" \ "Usage: %s [OPTIONS] [PASSWORD-FILES]\n" \ "-single \"single crack\" mode\n" \ diff -ruN john-1.6/src/params.h john-1.6.34/src/params.h --- john-1.6/src/params.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/params.h 2003-06-29 15:05:05.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2003 by Solar Designer */ /* @@ -15,17 +15,32 @@ /* * John's version number. */ -#define JOHN_VERSION "1.6" +#define JOHN_VERSION "1.6.34" /* - * Crash recovery file format version number. + * Is this a system-wide installation? *BSD ports and Linux distributions + * will probably want to set this to 1 for their builds of John. + */ +#ifndef JOHN_SYSTEMWIDE +#define JOHN_SYSTEMWIDE 0 +#endif + +#if JOHN_SYSTEMWIDE +#define JOHN_SYSTEMWIDE_EXEC "/usr/libexec/john" +#define JOHN_SYSTEMWIDE_HOME "/usr/share/john" +#define JOHN_PRIVATE_HOME "~/.john" +#endif + +/* + * Crash recovery file format version strings. */ #define RECOVERY_VERSION_0 "REC0" #define RECOVERY_VERSION_1 "REC1" -#define RECOVERY_VERSION_CURRENT RECOVERY_VERSION_1 +#define RECOVERY_VERSION_2 "REC2" +#define RECOVERY_VERSION_CURRENT RECOVERY_VERSION_2 /* - * Charset file format version number. + * Charset file format version string. */ #define CHARSET_VERSION "CHR1" @@ -52,10 +67,18 @@ /* * File names. */ -#define LOG_NAME "~/john.pot" -#define CFG_NAME "~/john.ini" -#define RECOVERY_NAME "~/restore" -#define WORDLIST_NAME "~/password.lst" +#define CFG_FULL_NAME "$JOHN/john.conf" +#define CFG_ALT_NAME "$JOHN/john.ini" +#if JOHN_SYSTEMWIDE +#define CFG_PRIVATE_FULL_NAME JOHN_PRIVATE_HOME "/john.conf" +#define CFG_PRIVATE_ALT_NAME JOHN_PRIVATE_HOME "/john.ini" +#define LOG_NAME JOHN_PRIVATE_HOME "/john.pot" +#define RECOVERY_NAME JOHN_PRIVATE_HOME "/restore" +#else +#define LOG_NAME "$JOHN/john.pot" +#define RECOVERY_NAME "$JOHN/restore" +#endif +#define WORDLIST_NAME "$JOHN/password.lst" /* * Configuration file section names. diff -ruN john-1.6/src/pa-risc.h john-1.6.34/src/pa-risc.h --- john-1.6/src/pa-risc.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/pa-risc.h 2000-05-08 09:05:36.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* @@ -10,15 +10,15 @@ #ifndef _JOHN_ARCH_H #define _JOHN_ARCH_H -#define ARCH_GENERIC 1 #define ARCH_WORD long #define ARCH_SIZE 4 #define ARCH_BITS 32 +#define ARCH_BITS_LOG 5 #define ARCH_BITS_STR "32" #define ARCH_LITTLE_ENDIAN 0 #define ARCH_INT_GT_32 0 #define ARCH_ALLOWS_UNALIGNED 0 -#define ARCH_INDEX unsigned int +#define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) #define OS_TIMER 0 #define OS_FLOCK 1 @@ -32,9 +32,14 @@ #define DES_SCALE 1 #define DES_EXTB 1 #define DES_COPY 0 +#define DES_BS_ASM 0 #define DES_BS 1 +#define DES_BS_VECTOR 8 +#define DES_BS_EXPAND 0 +#define DES_BS_ALGORITHM_NAME "32/32x8V BS" #define MD5_ASM 0 +#define MD5_X2 1 #define MD5_IMM 0 #define BF_ASM 0 diff -ruN john-1.6/src/path.c john-1.6.34/src/path.c --- john-1.6/src/path.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/path.c 2000-03-15 00:42:04.000000000 +0100 @@ -1,50 +1,107 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ -#include #include #include "misc.h" #include "params.h" #include "memory.h" +#include "path.h" -static char *home_path = NULL; -static size_t home_path_length; +static char *john_home_path = NULL; +static int john_home_length; + +#if JOHN_SYSTEMWIDE +#include +#include +#include +#include +#include + +static char *user_home_path = NULL; +static int user_home_length; +#endif void path_init(char **argv) { +#if JOHN_SYSTEMWIDE + struct passwd *pw; +#ifdef JOHN_PRIVATE_HOME + char *private; +#endif +#else char *pos; +#endif - if (!argv[0]) error(); - - if (!home_path && (pos = strrchr(argv[0], '/'))) { - home_path_length = pos - argv[0] + 1; - if (home_path_length >= PATH_BUFFER_SIZE) - home_path_length = PATH_BUFFER_SIZE - 1; - - home_path = mem_alloc(PATH_BUFFER_SIZE); +#if JOHN_SYSTEMWIDE + john_home_path = mem_alloc(PATH_BUFFER_SIZE); + strnzcpy(john_home_path, JOHN_SYSTEMWIDE_HOME "/", PATH_BUFFER_SIZE); + john_home_length = strlen(john_home_path); + + if (user_home_path) return; + pw = getpwuid(getuid()); + endpwent(); + if (!pw) return; + + user_home_length = strlen(pw->pw_dir) + 1; + if (user_home_length >= PATH_BUFFER_SIZE) return; + + user_home_path = mem_alloc(PATH_BUFFER_SIZE); + memcpy(user_home_path, pw->pw_dir, user_home_length - 1); + user_home_path[user_home_length - 1] = '/'; + +#ifdef JOHN_PRIVATE_HOME + private = path_expand(JOHN_PRIVATE_HOME); + if (mkdir(private, S_IRUSR | S_IWUSR | S_IXUSR)) { + if (errno != EEXIST) pexit("mkdir: %s", private); + } else + fprintf(stderr, "Created directory: %s\n", private); +#endif +#else + if (argv[0]) + if (!john_home_path && (pos = strrchr(argv[0], '/'))) { + john_home_length = pos - argv[0] + 1; + if (john_home_length >= PATH_BUFFER_SIZE) return; - memcpy(home_path, argv[0], home_path_length); + john_home_path = mem_alloc(PATH_BUFFER_SIZE); + memcpy(john_home_path, argv[0], john_home_length); } +#endif } char *path_expand(char *name) { + if (!strncmp(name, "$JOHN/", 6)) { + if (john_home_path && + john_home_length + strlen(name) - 6 < PATH_BUFFER_SIZE) { + strnzcpy(&john_home_path[john_home_length], &name[6], + PATH_BUFFER_SIZE - john_home_length); + return john_home_path; + } + return name + 6; + } + +#if JOHN_SYSTEMWIDE if (!strncmp(name, "~/", 2)) { - if (home_path) { - strnzcpy(&home_path[home_path_length], &name[2], - PATH_BUFFER_SIZE - home_path_length); - - return home_path; - } else - return name + 2; - } else - return name; + if (user_home_path && + user_home_length + strlen(name) - 2 < PATH_BUFFER_SIZE) { + strnzcpy(&user_home_path[user_home_length], &name[2], + PATH_BUFFER_SIZE - user_home_length); + return user_home_path; + } + return name + 2; + } +#endif + + return name; } -void path_done() +void path_done(void) { - mem_free((void **)&home_path); + mem_free((void **)&john_home_path); +#if JOHN_SYSTEMWIDE + mem_free((void **)&user_home_path); +#endif } diff -ruN john-1.6/src/path.h john-1.6.34/src/path.h --- john-1.6/src/path.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/path.h 2000-03-14 23:12:53.000000000 +0100 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* @@ -16,13 +16,13 @@ extern void path_init(char **argv); /* - * Expands "~/" in a path name. + * Expands "$JOHN/" and "~/" in a path name. */ extern char *path_expand(char *name); /* * Frees the memory allocated in path_init(). */ -extern void path_done(); +extern void path_done(void); #endif diff -ruN john-1.6/src/ppc.h john-1.6.34/src/ppc.h --- john-1.6/src/ppc.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/ppc.h 2000-05-08 09:05:39.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2000 by Solar Designer */ /* @@ -10,15 +10,15 @@ #ifndef _JOHN_ARCH_H #define _JOHN_ARCH_H -#define ARCH_GENERIC 1 #define ARCH_WORD long #define ARCH_SIZE 4 #define ARCH_BITS 32 +#define ARCH_BITS_LOG 5 #define ARCH_BITS_STR "32" #define ARCH_LITTLE_ENDIAN 0 #define ARCH_INT_GT_32 0 #define ARCH_ALLOWS_UNALIGNED 0 -#define ARCH_INDEX unsigned int +#define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) #define OS_TIMER 1 #define OS_FLOCK 1 @@ -32,10 +32,14 @@ #define DES_SCALE 0 #define DES_EXTB 1 #define DES_COPY 0 +#define DES_BS_ASM 0 #define DES_BS 1 +#define DES_BS_VECTOR 0 +#define DES_BS_EXPAND 1 #define MD5_ASM 0 -#define MD5_IMM 1 +#define MD5_X2 1 +#define MD5_IMM 0 #define BF_ASM 0 #define BF_SCALE 0 diff -ruN john-1.6/src/recovery.c john-1.6.34/src/recovery.c --- john-1.6/src/recovery.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/recovery.c 2001-05-11 15:50:17.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include @@ -28,6 +28,7 @@ #include "recovery.h" char *rec_name = RECOVERY_NAME; +int rec_version = 0; int rec_argc = 0; char **rec_argv; @@ -37,7 +38,7 @@ static void (*rec_save_mode)(FILE *file); #if defined(LOCK_EX) && OS_FLOCK -static void rec_lock() +static void rec_lock(void) { if (flock(rec_fd, LOCK_EX | LOCK_NB)) { if (errno == EWOULDBLOCK) { @@ -68,7 +69,7 @@ rec_save_mode = save_mode; } -void rec_save() +void rec_save(void) { int save_format; long size; @@ -142,7 +143,6 @@ void rec_restore_args(int lock) { char line[LINE_BUFFER_SIZE]; - int version; int index, argc; char **argv; char *save_rec_name; @@ -155,8 +155,9 @@ if (!fgetl(line, sizeof(line), rec_file)) rec_format_error("fgets"); - version = 0; - if (!strcmp(line, RECOVERY_VERSION_1)) version = 1; else + rec_version = 0; + if (!strcmp(line, RECOVERY_VERSION_2)) rec_version = 2; else + if (!strcmp(line, RECOVERY_VERSION_1)) rec_version = 1; else if (strcmp(line, RECOVERY_VERSION_0)) rec_format_error("fgets"); if (fscanf(rec_file, "%d\n", &argc) != 1) rec_format_error("fscanf"); @@ -183,7 +184,7 @@ &status.crypts.hi) != 4) rec_format_error("fscanf"); if (!status_restored_time) status_restored_time = 1; - if (version == 0) { + if (rec_version == 0) { status.pass = 0; status.progress = -1; } else diff -ruN john-1.6/src/recovery.h john-1.6.34/src/recovery.h --- john-1.6/src/recovery.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/recovery.h 2001-05-11 15:51:13.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -20,6 +20,11 @@ extern char *rec_name; /* + * Crash recovery file format version number. + */ +extern int rec_version; + +/* * Original command line arguments. */ extern int rec_argc; @@ -34,7 +39,7 @@ /* * Saves the command line arguments and cracking mode specific information. */ -extern void rec_save(); +extern void rec_save(void); /* * Closes the crash recovery file. diff -ruN john-1.6/src/rules.c john-1.6.34/src/rules.c --- john-1.6/src/rules.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/rules.c 2002-05-08 20:07:17.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ #include @@ -9,7 +9,6 @@ #include "arch.h" #include "misc.h" #include "params.h" -#include "path.h" #include "memory.h" #include "formats.h" #include "loader.h" @@ -79,7 +78,7 @@ } #define POSITION { \ - if ((pos = rules_length[(ARCH_INDEX)RULE]) == INVALID_LENGTH) { \ + if ((pos = rules_length[ARCH_INDEX(RULE)]) == INVALID_LENGTH) { \ if (LAST) \ rules_errno = RULES_ERROR_POSITION; \ else \ @@ -90,15 +89,15 @@ #define CLASS(start, true, false) { \ if ((value = RULE) == '?') { \ - if (!(class = rules_classes[(ARCH_INDEX)RULE])) { \ + if (!(class = rules_classes[ARCH_INDEX(RULE)])) { \ if (LAST) \ rules_errno = RULES_ERROR_CLASS; \ else \ rules_errno = RULES_ERROR_END; \ return NULL; \ } \ - for (pos = (start); (ARCH_INDEX)in[pos]; pos++) \ - if (class[(ARCH_INDEX)in[pos]]) { \ + for (pos = (start); ARCH_INDEX(in[pos]); pos++) \ + if (class[ARCH_INDEX(in[pos])]) { \ true; \ } else { \ false; \ @@ -108,7 +107,7 @@ rules_errno = RULES_ERROR_END; \ return NULL; \ } \ - for (pos = (start); (ARCH_INDEX)in[pos]; pos++) \ + for (pos = (start); ARCH_INDEX(in[pos]); pos++) \ if (in[pos] == value) { \ true; \ } else { \ @@ -123,30 +122,30 @@ } #define CONV(conv) { \ - for (pos = 0; (out[pos] = (conv)[(ARCH_INDEX)in[pos]]); pos++); \ + for (pos = 0; (out[pos] = (conv)[ARCH_INDEX(in[pos])]); pos++); \ } static void rules_init_class(char name, char *valid) { char *pos, inv; - rules_classes[(ARCH_INDEX)name] = + rules_classes[ARCH_INDEX(name)] = mem_alloc_tiny(0x100, MEM_ALIGN_NONE); - memset(rules_classes[(ARCH_INDEX)name], 0, 0x100); - for (pos = valid; (ARCH_INDEX)*pos; pos++) - rules_classes[(ARCH_INDEX)name][(ARCH_INDEX)*pos] = 1; + memset(rules_classes[ARCH_INDEX(name)], 0, 0x100); + for (pos = valid; ARCH_INDEX(*pos); pos++) + rules_classes[ARCH_INDEX(name)][ARCH_INDEX(*pos)] = 1; if (name >= 'a' && name <= 'z') { inv = name & ~0x20; - rules_classes[(ARCH_INDEX)inv] = + rules_classes[ARCH_INDEX(inv)] = mem_alloc_tiny(0x100, MEM_ALIGN_NONE); - memset(rules_classes[(ARCH_INDEX)inv], 1, 0x100); - for (pos = valid; (ARCH_INDEX)*pos; pos++) - rules_classes[(ARCH_INDEX)inv][(ARCH_INDEX)*pos] = 0; + memset(rules_classes[ARCH_INDEX(inv)], 1, 0x100); + for (pos = valid; ARCH_INDEX(*pos); pos++) + rules_classes[ARCH_INDEX(inv)][ARCH_INDEX(*pos)] = 0; } } -static void rules_init_classes() +static void rules_init_classes(void) { memset(rules_classes, 0, sizeof(rules_classes)); @@ -172,12 +171,12 @@ for (pos = 0; pos < 0x100; pos++) conv[pos] = pos; while (*src) - conv[(ARCH_INDEX)*src++] = *dst++; + conv[ARCH_INDEX(*src++)] = *dst++; return conv; } -static void rules_init_convs() +static void rules_init_convs(void) { conv_shift = rules_init_conv(conv_source, CONV_SHIFT); conv_invert = rules_init_conv(conv_source, CONV_INVERT); @@ -276,7 +275,7 @@ in[RULE_WORD_SIZE - 1] = 0; switch (LAST) { -/* Crack v4.1 rules */ +/* Crack 4.1 rules */ case ':': case ' ': case '\t': @@ -303,12 +302,12 @@ case 'c': pos = 0; - if ((out[0] = conv_toupper[(ARCH_INDEX)in[0]])) + if ((out[0] = conv_toupper[ARCH_INDEX(in[0])])) while (in[++pos]) - out[pos] = conv_tolower[(ARCH_INDEX)in[pos]]; + out[pos] = conv_tolower[ARCH_INDEX(in[pos])]; out[pos] = 0; if (out[0] == 'M' && out[1] == 'c') - out[2] = conv_toupper[(ARCH_INDEX)out[2]]; + out[2] = conv_toupper[ARCH_INDEX(out[2])]; break; case 'r': @@ -426,7 +425,7 @@ out = in; break; -/* Crack v5.0 rules */ +/* Crack 5.0 rules */ case '[': if (in[0]) strcpy(out, &in[1]); else out[0] = 0; break; @@ -438,12 +437,12 @@ case 'C': pos = 0; - if ((out[0] = conv_tolower[(ARCH_INDEX)in[0]])) + if ((out[0] = conv_tolower[ARCH_INDEX(in[0])])) while (in[++pos]) - out[pos] = conv_toupper[(ARCH_INDEX)in[pos]]; + out[pos] = conv_toupper[ARCH_INDEX(in[pos])]; out[pos] = 0; if (out[0] == 'm' && out[1] == 'C') - out[2] = conv_tolower[(ARCH_INDEX)out[2]]; + out[2] = conv_tolower[ARCH_INDEX(out[2])]; break; case 't': @@ -481,7 +480,7 @@ case 'T': POSITION out = in; - out[pos] = conv_invert[(ARCH_INDEX)out[pos]]; + out[pos] = conv_invert[ARCH_INDEX(out[pos])]; break; case 'D': @@ -677,7 +676,7 @@ if (!(count = rules_check(start, split))) { fprintf(stderr, "Invalid rule in %s at line %d: %s\n", - path_expand(CFG_NAME), rules_line, + cfg_name, rules_line, rules_errors[rules_errno]); error(); } diff -ruN john-1.6/src/signals.c john-1.6.34/src/signals.c --- john-1.6/src/signals.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/signals.c 2001-05-08 02:59:05.000000000 +0200 @@ -1,8 +1,16 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ +#ifdef __ultrix__ +#define __POSIX +#define _POSIX_SOURCE +#endif + +#ifdef _SCO_C_DIALECT +#include +#endif #include #include #include @@ -24,12 +32,11 @@ #include "tty.h" #include "config.h" -int event_pending = 0, event_abort = 0, event_save = 0, event_status = 0; +volatile int event_pending = 0; +volatile int event_abort = 0, event_save = 0, event_status = 0; static int timer_save_interval, timer_save_value; -static void (*sig_yield)(int always); - #if !OS_TIMER #include @@ -44,7 +51,7 @@ timer_emu_count = 0; timer_emu_max = 0; } -void sig_timer_emu_tick() +void sig_timer_emu_tick(void) { static clock_t last = 0; clock_t current; @@ -73,9 +80,9 @@ #endif -static void sig_install_update(); +static void sig_install_update(void); -static void sig_handle_update() +static void sig_handle_update(int signum) { event_save = event_pending = 1; @@ -84,7 +91,7 @@ #endif } -static void sig_install_update() +static void sig_install_update(void) { #ifdef SA_RESTART struct sigaction sa; @@ -98,12 +105,12 @@ #endif } -static void sig_remove_update() +static void sig_remove_update(void) { signal(SIGHUP, SIG_IGN); } -void check_abort() +void check_abort(void) { if (event_abort) { fprintf(stderr, "Session aborted\n"); @@ -111,7 +118,7 @@ } } -static void sig_install_abort(); +static void sig_install_abort(void); #ifdef __CYGWIN32__ static BOOL sig_handle_abort(DWORD ctrltype) @@ -136,7 +143,7 @@ #endif } -static void sig_install_abort() +static void sig_install_abort(void) { #ifdef __DJGPP__ setcbrk(1); @@ -157,7 +164,7 @@ #endif } -static void sig_remove_abort() +static void sig_remove_abort(void) { signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); @@ -165,7 +172,7 @@ #ifdef __CYGWIN32__ -static int sig_getchar() +static int sig_getchar(void) { int c; @@ -183,7 +190,7 @@ #endif -static void sig_install_timer(); +static void sig_install_timer(void); static void sig_handle_timer(int signum) { @@ -207,13 +214,10 @@ sig_install_timer(); #endif - if (!event_pending && sig_yield) - sig_yield(1); - errno = saved_errno; } -static void sig_install_timer() +static void sig_install_timer(void) { #if !OS_TIMER signal(SIGALRM, sig_handle_timer); @@ -243,7 +247,7 @@ #endif } -static void sig_remove_timer() +static void sig_remove_timer(void) { #if OS_TIMER struct itimerval it; @@ -255,9 +259,9 @@ signal(SIGALRM, SIG_DFL); } -static void sig_done(); +static void sig_done(void); -void sig_init() +void sig_init(void) { timer_save_interval = cfg_get_int(SECTION_OPTIONS, NULL, "Save"); if (timer_save_interval < 0) @@ -274,7 +278,7 @@ sig_install_timer(); } -static void sig_done() +static void sig_done(void) { sig_remove_update(); sig_remove_abort(); diff -ruN john-1.6/src/signals.h john-1.6.34/src/signals.h --- john-1.6/src/signals.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/signals.h 2001-05-08 21:21:41.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -19,28 +19,29 @@ * to clear individual flags in a bitmask without a race condition on RISC, * or having to block the signals. */ -extern int event_pending; /* An event is pending */ -extern int event_abort; /* Abort requested */ -extern int event_save; /* Time to save the crash recovery file */ -extern int event_status; /* Status display requested */ +extern volatile int event_pending; /* An event is pending */ +extern volatile int event_abort; /* Abort requested */ +extern volatile int event_save; /* Save the crash recovery file */ +extern volatile int event_status; /* Status display requested */ #if !OS_TIMER /* * Timer emulation for systems with no setitimer(2). */ #include + extern void sig_timer_emu_init(clock_t interval); -extern void sig_timer_emu_tick(); +extern void sig_timer_emu_tick(void); #endif /* * Installs the signal handlers. */ -extern void sig_init(void (*yield)(int always)); +extern void sig_init(void); /* * Terminates the process if event_abort is set. */ -extern void check_abort(); +extern void check_abort(void); #endif diff -ruN john-1.6/src/single.c john-1.6.34/src/single.c --- john-1.6/src/single.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/single.c 2000-03-15 00:27:42.000000000 +0100 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ #include @@ -8,7 +8,6 @@ #include "misc.h" #include "params.h" -#include "path.h" #include "memory.h" #include "signals.h" #include "loader.h" @@ -33,7 +32,7 @@ fprintf(file, "%d\n", rec_rule); } -static int restore_rule_number() +static int restore_rule_number(void) { if (rule_ctx) for (rule_number = 0; rule_number < rec_rule; rule_number++) @@ -49,7 +48,7 @@ return restore_rule_number(); } -static int get_progress() +static int get_progress(void) { if (progress) return progress; @@ -75,7 +74,7 @@ memset((*keys)->hash, -1, hash_size); } -static void single_init() +static void single_init(void) { struct db_salt *salt; @@ -87,7 +86,7 @@ if (rpp_init(rule_ctx, SUBSECTION_SINGLE)) { fprintf(stderr, "No \"single crack\" mode rules found in %s\n", - path_expand(CFG_NAME)); + cfg_name); error(); } @@ -289,7 +288,7 @@ return 0; } -static void single_run() +static void single_run(void) { char *rule; struct db_salt *salt; @@ -315,7 +314,7 @@ } } -static void single_done() +static void single_done(void) { struct db_salt *salt; diff -ruN john-1.6/src/sparc64.h john-1.6.34/src/sparc64.h --- john-1.6/src/sparc64.h 1970-01-01 01:00:00.000000000 +0100 +++ john-1.6.34/src/sparc64.h 2003-01-24 04:41:40.000000000 +0100 @@ -0,0 +1,47 @@ +/* + * This file is part of John the Ripper password cracker, + * Copyright (c) 2003 by Solar Designer + */ + +/* + * Architecture specific parameters for SPARC V9, 64-bit. + */ + +#ifndef _JOHN_ARCH_H +#define _JOHN_ARCH_H + +#define ARCH_WORD long +#define ARCH_SIZE 8 +#define ARCH_BITS 64 +#define ARCH_BITS_LOG 6 +#define ARCH_BITS_STR "64" +#define ARCH_LITTLE_ENDIAN 0 +#define ARCH_INT_GT_32 0 +#define ARCH_ALLOWS_UNALIGNED 0 +#define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) + +#define OS_TIMER 1 +#define OS_FLOCK 1 + +#define CPU_DETECT 0 + +#define DES_ASM 0 +#define DES_128K 0 +#define DES_X2 0 +#define DES_MASK 1 +#define DES_SCALE 0 +#define DES_EXTB 0 +#define DES_COPY 1 +#define DES_BS_ASM 0 +#define DES_BS 1 +#define DES_BS_VECTOR 0 +#define DES_BS_EXPAND 1 + +#define MD5_ASM 0 +#define MD5_X2 1 +#define MD5_IMM 0 + +#define BF_ASM 0 +#define BF_SCALE 0 + +#endif diff -ruN john-1.6/src/sparc.S john-1.6.34/src/sparc.S --- john-1.6/src/sparc.S 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/sparc.S 2001-01-24 20:24:09.000000000 +0100 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -9,6 +9,29 @@ #include "arch.h" +#ifdef UNDERSCORES +#define DES_IV _DES_IV +#define DES_count _DES_count +#define DES_KS_current _DES_KS_current +#define DES_KS_table _DES_KS_table +#define DES_SPE_L _DES_SPE_L +#define DES_SPE_H _DES_SPE_H +#define DES_SPE_W _DES_SPE_W +#define DES_std_crypt _DES_std_crypt +#define DES_xor_key1 _DES_xor_key1 +#define DES_xor_key2 _DES_xor_key2 +#endif + +/* + * Load an address assuming that it is 1024-byte aligned if the section + * alignment for this platform is large enough. + */ +#ifdef BSD +#define LDAA(addr, reg) set (addr),reg +#else +#define LDAA(addr, reg) sethi %hi(addr),reg +#endif + /* * DES stuff. */ @@ -202,17 +225,17 @@ DES_std_crypt: #if DES_128K save %sp,-112,%sp - sethi %hi(DES_SPE_L+0x400),SPE_L_4 - sethi %hi(DES_SPE_W),SPE_0 - sethi %hi(DES_SPE_W+0x8000),SPE_1 - sethi %hi(DES_SPE_W+0x10000),SPE_2 - sethi %hi(DES_SPE_W+0x18000),SPE_3 + LDAA (DES_SPE_L+0x400,SPE_L_4) + LDAA (DES_SPE_W,SPE_0) + LDAA (DES_SPE_W+0x8000,SPE_1) + LDAA (DES_SPE_W+0x10000,SPE_2) + LDAA (DES_SPE_W+0x18000,SPE_3) set 0xFFFF,FFFF #else save %sp,-120,%sp st %i7,[%fp-24] - sethi %hi(DES_SPE_L),SPE_L_0 - sethi %hi(DES_SPE_L+0x400),SPE_L_4 + LDAA (DES_SPE_L,SPE_L_0) + LDAA (DES_SPE_L+0x400,SPE_L_4) add SPE_L_0,0x808,SPE_H_0 add SPE_L_0,0x100,SPE_L_1 add SPE_L_0,0x200,SPE_L_2 @@ -296,7 +319,7 @@ .align 16 .globl DES_xor_key1 DES_xor_key1: - sethi %hi(DES_KS_current),kp + LDAA (DES_KS_current,kp) DES_xor1(0,) DES_xor1(16,) DES_xor1(32,) @@ -328,7 +351,7 @@ .align 16 .globl DES_xor_key2 DES_xor_key2: - sethi %hi(DES_KS_current),kp + LDAA (DES_KS_current,kp) DES_xor2(0,) DES_xor2(16,) DES_xor2(32,) @@ -340,7 +363,12 @@ .data +#ifdef BSD +.align 8 +#else .align 1024 +#endif + .globl DES_SPE_L DES_SPE_L: .skip 0x800 @@ -363,9 +391,22 @@ DES_count: .skip 4 +#ifdef BSD + +#if DES_128K +.common DES_SPE_W, 0x20000, "bss" +#endif + +.common DES_KS_current, 128, "bss" +.common DES_KS_table, (8 * 128 * 16 * 8), "bss" + +#else + #if DES_128K .common DES_SPE_W, 0x20000, 1024 #endif .common DES_KS_current, 128, 1024 .common DES_KS_table, (8 * 128 * 16 * 8), 32 + +#endif diff -ruN john-1.6/src/sparc.sh john-1.6.34/src/sparc.sh --- john-1.6/src/sparc.sh 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/sparc.sh 2000-06-25 07:08:21.000000000 +0200 @@ -1,7 +1,7 @@ #!/bin/sh # # This file is part of John the Ripper password cracker, -# Copyright (c) 1996-98 by Solar Designer +# Copyright (c) 1996-2000 by Solar Designer # [ $# -eq 3 ] || exit 1 @@ -10,13 +10,13 @@ HAMMER=$2 DES_DEPEND=$3 -# Detect the best standard DES algorithm +# Detect the best non-bitslice DES algorithm MAX=0 DES_BEST=1 for MODE in 2 3; do - if ./detect $MODE 0 0 0 0 > arch.h; then + if ./detect $MODE 0 0 1 0 0 > arch.h; then rm -f $DES_DEPEND bench $MAKE $HAMMER NAIL=bench \ BENCH_DES_OBJS_DEPEND="$DES_DEPEND" || exit 1 @@ -30,7 +30,7 @@ # Check if bitslice DES is faster -./detect $DES_BEST 0 1 0 0 > arch.h +./detect $DES_BEST 0 1 1 0 0 > arch.h rm -f $DES_DEPEND bench $MAKE $HAMMER NAIL=bench BENCH_DES_OBJS_DEPEND="$DES_DEPEND" || exit 1 @@ -44,5 +44,5 @@ # Produce sparc.h, make sure everything is rebuilt with detected options, # and do some cleanup -./detect $DES_BEST 0 $DES_BS 0 0 > sparc.h +./detect $DES_BEST 0 $DES_BS 1 0 0 > sparc.h rm -f $DES_DEPEND bench detect best.o detect.o arch.h diff -ruN john-1.6/src/status.c john-1.6.34/src/status.c --- john-1.6/src/status.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/status.c 2001-06-08 23:11:07.000000000 +0200 @@ -1,8 +1,16 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ +#ifdef __ultrix__ +#define __POSIX +#define _POSIX_SOURCE +#endif + +#ifdef _SCO_C_DIALECT +#include +#endif #include #include #include @@ -10,7 +18,6 @@ #include "times.h" -#include "arch.h" #include "misc.h" #include "math.h" #include "params.h" @@ -20,22 +27,21 @@ struct status_main status; unsigned int status_restored_time = 0; -int (*status_get_progress)() = NULL; +int (*status_get_progress)(void) = NULL; -static clock_t get_time() +static clock_t get_time(void) { struct tms buf; return times(&buf); } -void status_init(int (*get_progress)(), int start) +void status_init(int (*get_progress)(void), int start) { if (start) { if (!status_restored_time) memset(&status, 0, sizeof(status)); - status.start_time = - get_time() - status_restored_time * CLK_TCK; + status.start_time = get_time(); } status_get_progress = get_progress; @@ -43,24 +49,51 @@ void status_update_crypts(unsigned int count) { + unsigned int saved_hi, time; + clock_t ticks; + + saved_hi = status.crypts.hi; add32to64(&status.crypts, count); + + if (status.crypts.hi != saved_hi) { + ticks = get_time() - status.start_time; + if (ticks > ((clock_t)1 << (sizeof(clock_t) * 8 - 2))) { + time = ticks / CLK_TCK; + status_restored_time += time; + status.start_time += (clock_t)time * CLK_TCK; + } + } } -unsigned int status_get_time() +unsigned int status_get_time(void) { - return (get_time() - status.start_time) / CLK_TCK; + return status_restored_time + + (get_time() - status.start_time) / CLK_TCK; } static char *status_get_cps(char *buffer) { - unsigned int time, cps_hi, cps_lo; + int use_ticks; + clock_t ticks; + unsigned long time; + unsigned int cps_hi, cps_lo; int64 tmp; - if (!(time = status_get_time())) time = 1; + use_ticks = !status.crypts.hi && !status_restored_time; - cps_hi = div64by32lo(&status.crypts, time); + ticks = get_time() - status.start_time; + if (use_ticks) + time = ticks; + else + time = status_restored_time + ticks / CLK_TCK; + if (!time) time = 1; + + tmp = status.crypts; + if (use_ticks) mul64by32(&tmp, CLK_TCK); + cps_hi = div64by32lo(&tmp, time); tmp = status.crypts; + if (use_ticks) mul64by32(&tmp, CLK_TCK); mul64by32(&tmp, 100); cps_lo = div64by32lo(&tmp, time) % 100; @@ -77,8 +110,8 @@ int64 current, next, rem; char *s_words_ptr; - s_words_ptr = &s_words[sizeof(s_words)]; - *--s_words_ptr = 0; + s_words_ptr = &s_words[sizeof(s_words) - 1]; + *s_words_ptr = 0; current = status.crypts; do { @@ -143,7 +176,7 @@ saved_key ? saved_key : ""); } -void status_print() +void status_print(void) { int percent_value; char s_percent[32]; diff -ruN john-1.6/src/status.h john-1.6.34/src/status.h --- john-1.6/src/status.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/status.h 2001-06-02 20:09:05.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -27,7 +27,7 @@ extern struct status_main status; -extern int (*status_get_progress)(); +extern int (*status_get_progress)(void); /* * Elapsed time of previous sessions, in seconds. @@ -35,11 +35,11 @@ extern unsigned int status_restored_time; /* - * If start is non-zero, sets start_time to current time minus - * status_restored_time, and the rest of fields to zero. Always - * initializes the get_progress() handler (can be NULL). + * If start is non-zero, sets start_time to current time and the rest of + * fields to zero. Always initializes the get_progress() handler (can be + * NULL). */ -extern void status_init(int (*get_progress)(), int start); +extern void status_init(int (*get_progress)(void), int start); /* * Updates the crypts count. @@ -48,16 +48,12 @@ /* * Returns the elapsed time in seconds. - * - * Currently this does not support running for more than 248 days total - * (assuming CLK_TCK is 100). However, this should survive uptimes of the - * box we are running on of more than 248 days. */ -extern unsigned int status_get_time(); +extern unsigned int status_get_time(void); /* * Prints current status to stdout. */ -extern void status_print(); +extern void status_print(void); #endif diff -ruN john-1.6/src/tty.c john-1.6.34/src/tty.c --- john-1.6/src/tty.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/tty.c 1999-09-22 06:01:15.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ #ifndef __DJGPP__ @@ -34,7 +34,7 @@ static struct termios saved_ti; #endif -void tty_init() +void tty_init(void) { #ifndef __DJGPP__ int fd; @@ -63,7 +63,7 @@ #endif } -int tty_getchar() +int tty_getchar(void) { #ifndef __DJGPP__ int c; @@ -90,7 +90,7 @@ return -1; } -void tty_done() +void tty_done(void) { #ifndef __DJGPP__ int fd; diff -ruN john-1.6/src/tty.h john-1.6.34/src/tty.h --- john-1.6/src/tty.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/tty.h 1999-09-22 05:44:00.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ /* @@ -14,16 +14,16 @@ * Initializes the terminal for unbuffered non-blocking input. Also registers * tty_done() via atexit(). */ -extern void tty_init(); +extern void tty_init(void); /* * Reads a character, returns -1 if no data available or on error. */ -extern int tty_getchar(); +extern int tty_getchar(void); /* * Restores the terminal parameters and closes the file descriptor. */ -extern void tty_done(); +extern void tty_done(void); #endif diff -ruN john-1.6/src/unique.c john-1.6.34/src/unique.c --- john-1.6/src/unique.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/unique.c 2002-11-05 21:49:46.000000000 +0100 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2002 by Solar Designer */ #include @@ -79,7 +79,7 @@ return hash; } -static void init_hash() +static void init_hash(void) { int index; @@ -87,7 +87,7 @@ buffer.hash[index] = ENTRY_END_HASH; } -static void read_buffer() +static void read_buffer(void) { char line[LINE_BUFFER_SIZE]; unsigned int ptr, current, *last; @@ -97,7 +97,7 @@ ptr = 0; while (fgetl(line, sizeof(line), stdin)) { last = &buffer.hash[line_hash(line)]; -#if ARCH_LITTLE_ENDIAN +#if ARCH_LITTLE_ENDIAN && !ARCH_INT_GT_32 current = *last; #else current = get_int(last); @@ -125,7 +125,7 @@ put_data(ptr, ENTRY_END_LIST); } -static void write_buffer() +static void write_buffer(void) { unsigned int ptr, hash; @@ -140,7 +140,7 @@ } } -static void clean_buffer() +static void clean_buffer(void) { char line[LINE_BUFFER_SIZE]; unsigned int current, *last; @@ -149,7 +149,11 @@ while (fgetl(line, sizeof(line), output)) { last = &buffer.hash[line_hash(line)]; +#if ARCH_LITTLE_ENDIAN && !ARCH_INT_GT_32 current = *last; +#else + current = get_int(last); +#endif while (current != ENTRY_END_HASH && current != ENTRY_DUPE) { if (!strcmp(line, &buffer.data[current + 4])) { put_int(last, get_data(current)); @@ -162,6 +166,9 @@ } if (ferror(output)) pexit("fgets"); + +/* Workaround a Solaris stdio bug. */ + if (fseek(output, 0, SEEK_END) < 0) pexit("fseek"); } static void unique_init(char *name) @@ -176,7 +183,7 @@ if (!(output = fdopen(fd, "w+"))) pexit("fdopen"); } -static void unique_run() +static void unique_run(void) { read_buffer(); write_buffer(); @@ -188,7 +195,7 @@ } } -static void unique_done() +static void unique_done(void) { if (fclose(output)) pexit("fclose"); } diff -ruN john-1.6/src/unshadow.c john-1.6.34/src/unshadow.c --- john-1.6/src/unshadow.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/unshadow.c 2001-10-19 14:52:19.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ #include @@ -51,23 +51,44 @@ static void process_shadow_line(char *line) { - char *pos1, *pos2; - struct shadow_entry **entry, *last; + static struct shadow_entry **entry = NULL; + struct shadow_entry *last; + char *login, *passwd, *tail; + + if (!(passwd = strchr(line, ':'))) { + while (*line == ' ' || *line == '\t') line++; + /* AIX */ + if (!strncmp(line, "password = ", 11) && entry) + (*entry)->passwd = str_alloc_copy(line + 11); + return; + } - if (!(pos1 = strchr(line, ':'))) return; - *pos1++ = 0; + login = line; + *passwd++ = 0; - if (!(pos2 = strchr(pos1, ':'))) - pos2 = pos1 + strlen(pos1); - if (pos2 - pos1 < 1) return; - *pos2 = 0; + /* DU / Tru64 C2, HP-UX tcb */ + if (!strncmp(passwd, "u_name=", 7)) { + if ((passwd = strstr(passwd, ":u_pwd="))) + passwd += 7; + } else + /* HP-UX tcb */ + if (!strncmp(passwd, "u_pwd=", 6) && entry) { + passwd += 6; + if ((tail = strchr(passwd, ':'))) + *tail = 0; + (*entry)->passwd = str_alloc_copy(passwd); + return; + } + + if (passwd && (tail = strchr(passwd, ':'))) + *tail = 0; - entry = &shadow_table[login_hash(line)]; + entry = &shadow_table[login_hash(login)]; last = *entry; *entry = mem_alloc_tiny(sizeof(struct shadow_entry), MEM_ALIGN_WORD); (*entry)->next = last; - (*entry)->login = str_alloc_copy(line); - (*entry)->passwd = str_alloc_copy(pos1); + (*entry)->login = str_alloc_copy(login); + (*entry)->passwd = passwd ? str_alloc_copy(passwd) : "*"; } static void process_passwd_line(char *line) @@ -81,7 +102,7 @@ if (!(pos2 = strchr(pos1, ':'))) pos2 = pos1 + strlen(pos1); - if ((current = shadow_table[login_hash(line)])) + if (pos2 > pos1 && (current = shadow_table[login_hash(line)])) do { if (!strcmp(current->login, line)) { printf("%s:%s%s\n", line, current->passwd, pos2); diff -ruN john-1.6/src/vax.h john-1.6.34/src/vax.h --- john-1.6/src/vax.h 1970-01-01 01:00:00.000000000 +0100 +++ john-1.6.34/src/vax.h 2000-08-24 00:16:43.000000000 +0200 @@ -0,0 +1,47 @@ +/* + * This file is part of John the Ripper password cracker, + * Copyright (c) 1996-2000 by Solar Designer + */ + +/* + * Architecture specific parameters for VAX. + */ + +#ifndef _JOHN_ARCH_H +#define _JOHN_ARCH_H + +#define ARCH_WORD long +#define ARCH_SIZE 4 +#define ARCH_BITS 32 +#define ARCH_BITS_LOG 5 +#define ARCH_BITS_STR "32" +#define ARCH_LITTLE_ENDIAN 1 +#define ARCH_INT_GT_32 0 +#define ARCH_ALLOWS_UNALIGNED 1 +#define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) + +#define OS_TIMER 1 +#define OS_FLOCK 1 + +#define CPU_DETECT 0 + +#define DES_ASM 0 +#define DES_128K 1 +#define DES_X2 0 +#define DES_MASK 1 +#define DES_SCALE 1 +#define DES_EXTB 1 +#define DES_COPY 1 +#define DES_BS_ASM 0 +#define DES_BS 1 +#define DES_BS_VECTOR 0 +#define DES_BS_EXPAND 1 + +#define MD5_ASM 0 +#define MD5_X2 0 +#define MD5_IMM 1 + +#define BF_ASM 0 +#define BF_SCALE 0 + +#endif diff -ruN john-1.6/src/wordlist.c john-1.6.34/src/wordlist.c --- john-1.6/src/wordlist.c 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/wordlist.c 2000-03-15 00:27:57.000000000 +0100 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-99 by Solar Designer */ #include @@ -36,7 +36,7 @@ fprintf(file, "%d\n%ld\n", rec_rule, rec_pos); } -static int restore_rule_number() +static int restore_rule_number(void) { if (rule_ctx) for (rule_number = 0; rule_number < rec_rule; rule_number++) @@ -45,7 +45,7 @@ return 0; } -static void restore_line_number() +static void restore_line_number(void) { char line[LINE_BUFFER_SIZE]; @@ -72,7 +72,7 @@ return 0; } -static void fix_state() +static void fix_state(void) { rec_rule = rule_number; @@ -87,7 +87,7 @@ } } -static int get_progress() +static int get_progress(void) { struct stat file_stat; long pos; @@ -138,7 +138,7 @@ if (rules) { if (rpp_init(rule_ctx = &ctx, SUBSECTION_WORDLIST)) { fprintf(stderr, "No wordlist mode rules found in %s\n", - path_expand(CFG_NAME)); + cfg_name); error(); } diff -ruN john-1.6/src/x86-any.h john-1.6.34/src/x86-any.h --- john-1.6/src/x86-any.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/x86-any.h 2001-07-26 17:00:00.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -10,17 +10,17 @@ #ifndef _JOHN_ARCH_H #define _JOHN_ARCH_H -#define ARCH_GENERIC 0 #define ARCH_WORD long #define ARCH_SIZE 4 #define ARCH_BITS 32 +#define ARCH_BITS_LOG 5 #define ARCH_BITS_STR "32" #define ARCH_LITTLE_ENDIAN 1 #define ARCH_INT_GT_32 0 #define ARCH_ALLOWS_UNALIGNED 1 -#define ARCH_INDEX unsigned int +#define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) -#ifdef __CYGWIN32__ +#if defined(__CYGWIN32__) || defined(__BEOS__) #define OS_TIMER 0 #else #define OS_TIMER 1 @@ -37,9 +37,13 @@ #define DES_SCALE 0 #define DES_EXTB 0 #define DES_COPY 1 +#define DES_BS_ASM 0 #define DES_BS 0 +#define DES_BS_VECTOR 0 +#define DES_BS_EXPAND 0 #define MD5_ASM 1 +#define MD5_X2 0 #define MD5_IMM 1 #define BF_ASM 1 diff -ruN john-1.6/src/x86-mmx.h john-1.6.34/src/x86-mmx.h --- john-1.6/src/x86-mmx.h 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/x86-mmx.h 2002-04-11 19:55:55.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2002 by Solar Designer */ /* @@ -10,17 +10,17 @@ #ifndef _JOHN_ARCH_H #define _JOHN_ARCH_H -#define ARCH_GENERIC 0 #define ARCH_WORD long #define ARCH_SIZE 4 #define ARCH_BITS 32 +#define ARCH_BITS_LOG 5 #define ARCH_BITS_STR "32" #define ARCH_LITTLE_ENDIAN 1 #define ARCH_INT_GT_32 0 #define ARCH_ALLOWS_UNALIGNED 1 -#define ARCH_INDEX unsigned int +#define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) -#ifdef __CYGWIN32__ +#if defined(__CYGWIN32__) || defined(__BEOS__) #define OS_TIMER 0 #else #define OS_TIMER 1 @@ -30,6 +30,12 @@ #define CPU_DETECT 1 #define CPU_REQ 1 #define CPU_NAME "MMX" +#ifndef CPU_FALLBACK +#define CPU_FALLBACK 0 +#endif +#if CPU_FALLBACK +#define CPU_FALLBACK_BINARY "john-non-mmx" +#endif #define DES_ASM 1 #define DES_128K 0 @@ -38,9 +44,15 @@ #define DES_SCALE 0 #define DES_EXTB 0 #define DES_COPY 1 -#define DES_BS 0 +#define DES_STD_ALGORITHM_NAME "48/64 4K MMX" +#define DES_BS_ASM 1 +#define DES_BS 1 +#define DES_BS_VECTOR 2 +#define DES_BS_EXPAND 1 +#define DES_BS_ALGORITHM_NAME "64/64 BS MMX" #define MD5_ASM 1 +#define MD5_X2 0 #define MD5_IMM 1 #define BF_ASM 1 diff -ruN john-1.6/src/x86-mmx.S john-1.6.34/src/x86-mmx.S --- john-1.6/src/x86-mmx.S 1970-01-01 01:00:00.000000000 +0100 +++ john-1.6.34/src/x86-mmx.S 2001-06-28 23:15:03.000000000 +0200 @@ -0,0 +1,1310 @@ +/* + * This file is part of John the Ripper password cracker, + * Copyright (c) 2000-2001 by Solar Designer and others: + * + * The MMX DES S-box code is by Bruce Ford and Rémi Guyomarch, originally + * for use in the distributed.net clients, included here with permission. + * Only minor modifications have been made to their S-box code. Optimized + * S-box expressions are based on work by Matthew Kwan (see nonstd.c). + * + * Note: there's some MMX code in x86.S as well. + */ + +#ifdef UNDERSCORES +#define DES_bs_all _DES_bs_all +#define DES_bs_init_asm _DES_bs_init_asm +#define DES_bs_crypt _DES_bs_crypt +#define DES_bs_crypt_25 _DES_bs_crypt_25 +#define DES_bs_crypt_LM _DES_bs_crypt_LM +#endif + +/* + * Some broken systems don't offer section alignments larger than 4 bytes, + * while for the MMX code we need at least an 8 byte alignment. ALIGN_FIX + * is here to work around this issue when we happen to get bad addresses. + */ +#ifndef ALIGN_FIX +#ifdef ALIGN_LOG +#define DO_ALIGN(log) .align (log) +#else +#define DO_ALIGN(log) .align (1 << (log)) +#endif +#else +#ifdef ALIGN_LOG +#define DO_ALIGN(log) .align (log); .space 4 +#else +#define DO_ALIGN(log) .align (1 << (log)); .space 4 +#endif +#endif + +#ifdef BSD +.data +#else +.bss +#endif + +.globl DES_bs_all +DO_ALIGN(5) +DES_bs_all: +DES_bs_all_KSp: +.space (0x300 * 4) +DES_bs_all_KS_p: +DES_bs_all_KS_v: +.space (0x300 * 8) +DES_bs_all_E: +.space (96 * 4) +DES_bs_all_K: +.space (56 * 8) +DES_bs_all_B: +.space (64 * 8) +DES_bs_all_tmp: +.space (16 * 8) +DES_bs_all_fields_not_used_here: +.space (0x100 + 4 + 4 + 64 * 8) +DES_bs_all_possible_alignment_gaps: +.space 0x100 + +#define E(i) DES_bs_all_E+(i)*4 +#define B(i) DES_bs_all_B+(i)*8 +#define tmp_at(i) DES_bs_all_tmp+(i)*8 + +#define pnot tmp_at(0) + +#define a1 %mm0 +#define a2 %mm1 +#define a3 %mm2 +#define a4 %mm3 +#define a5 %mm4 +#define a6 %mm5 + +#define S1_out1 %mm5 +#define S1_out2 %mm7 +#define S1_out3 %mm2 +#define S1_out4 %mm0 + +#define S1_a1 tmp_at(1) +#define S1_a3 tmp_at(2) +#define S1_a5 tmp_at(3) +#define S1_x1 tmp_at(4) +#define S1_x3 tmp_at(5) +#define S1_x4 tmp_at(6) +#define S1_x5 tmp_at(7) +#define S1_x6 tmp_at(8) +#define S1_x13 tmp_at(9) +#define S1_x14 tmp_at(10) +#define S1_x25 tmp_at(11) +#define S1_x26 tmp_at(12) +#define S1_x38 tmp_at(13) +#define S1_x55 tmp_at(14) +#define S1_x58 tmp_at(15) + +#define S1(out1, out2, out3, out4, extra) \ + movq %mm0,S1_a1; \ + movq %mm3,%mm6; \ + pxor pnot,%mm0; \ + pxor %mm2,%mm3; \ + pxor pnot,%mm6; \ + movq %mm0,%mm7; \ + extra; \ + movq %mm4,S1_a5; \ + por %mm2,%mm7; \ + movq %mm3,S1_x3; \ + movq %mm5,%mm4; \ + movq %mm6,S1_x1; \ + pxor %mm0,%mm3; \ + movq %mm7,S1_x5; \ + por %mm6,%mm0; \ + movq %mm2,S1_a3; \ + pand %mm6,%mm7; \ + movq %mm3,S1_x4; \ + por %mm3,%mm2; \ + pxor pnot,%mm2; \ + pand %mm0,%mm4; \ + movq %mm7,%mm6; \ + por %mm5,%mm2; \ + movq %mm7,S1_x6; \ + por %mm5,%mm6; \ + pxor %mm2,%mm7; \ + pxor %mm6,%mm3; \ + movq %mm2,S1_x25; \ + pxor %mm4,%mm6; \ + pand S1_a3,%mm4; \ + movq %mm6,%mm2; \ + pxor S1_a3,%mm6; \ + por %mm1,%mm2; \ + pand S1_x5,%mm6; \ + pxor %mm3,%mm2; \ + movq %mm4,S1_x38; \ + pxor %mm2,%mm0; \ + movq %mm7,S1_x26; \ + movq %mm5,%mm4; \ + movq %mm2,S1_x13; \ + por %mm0,%mm4; \ + movq S1_x1,%mm7; \ + por %mm1,%mm6; \ + movq %mm0,S1_x14; \ + movq %mm3,%mm2; \ + pandn S1_x3,%mm0; \ + pxor %mm7,%mm4; \ + por S1_x4,%mm5; \ + por %mm1,%mm0; \ + pxor S1_x38,%mm5; \ + pxor %mm0,%mm4; \ + movq S1_a5,%mm0; \ + pand %mm7,%mm2; \ + movq %mm6,S1_x55; \ + por %mm1,%mm2; \ + movq S1_x14,%mm6; \ + por %mm4,%mm0; \ + pand S1_x5,%mm6; \ + por %mm3,%mm7; \ + movq %mm5,S1_x58; \ + pxor %mm3,%mm6; \ + pxor S1_x6,%mm7; \ + movq %mm1,%mm5; \ + pxor S1_x26,%mm2; \ + pand %mm6,%mm5; \ + pand S1_a3,%mm6; \ + pxor %mm7,%mm5; \ + por S1_a5,%mm5; \ + movq S1_a1,%mm7; \ + pxor %mm2,%mm5; \ + movq S1_x4,%mm2; \ + por %mm3,%mm7; \ + por S1_x38,%mm2; \ + pxor %mm6,%mm3; \ + pxor S1_x25,%mm6; \ + pxor %mm4,%mm7; \ + movq S1_a3,%mm4; \ + por %mm1,%mm7; \ + por S1_x26,%mm4; \ + por %mm1,%mm6; \ + pxor S1_x14,%mm4; \ + pxor %mm2,%mm6; \ + movq S1_x13,%mm2; \ + pxor %mm4,%mm7; \ + pxor S1_x55,%mm3; \ + pxor %mm2,%mm0; \ + pxor out1,%mm5; \ + pand %mm3,%mm2; \ + movq S1_a5,%mm4; \ + pand %mm1,%mm2; \ + movq %mm5,out1; \ + pxor S1_x58,%mm2; \ + pand %mm4,%mm7; \ + pxor out4,%mm0; \ + pand %mm4,%mm2; \ + pxor out2,%mm7; \ + movq %mm0,out4; \ + pxor out3,%mm2; \ + pxor %mm6,%mm7; \ + pxor %mm3,%mm2; \ + movq %mm7,out2; \ + movq %mm2,out3 + +#define S2_out1 %mm1 +#undef S2_out2 +#define S2_out3 %mm7 +#define S2_out4 %mm2 + +#define S2_a1 tmp_at(1) +#define S2_a2 tmp_at(2) +#define S2_a3 tmp_at(3) +#define S2_a4 tmp_at(4) +#define S2_x3 tmp_at(5) +#define S2_x4 tmp_at(6) +#define S2_x5 tmp_at(7) +#define S2_x13 tmp_at(8) +#define S2_x18 tmp_at(9) +#define S2_x25 tmp_at(10) + +#define S2(out1, out2, out3, out4, extra) \ + movq %mm3,S2_a4; \ + movq %mm4,%mm6; \ + extra; \ + movq %mm0,S2_a1; \ + movq %mm4,%mm7; \ + pxor pnot,%mm0; \ + pxor %mm5,%mm6; \ + pxor pnot,%mm7; \ + movq %mm0,%mm3; \ + movq %mm2,S2_a3; \ + por %mm5,%mm7; \ + movq %mm6,S2_x3; \ + por %mm7,%mm3; \ + pxor %mm4,%mm7; \ + pxor %mm0,%mm6; \ + pand %mm1,%mm3; \ + por %mm7,%mm2; \ + movq %mm1,S2_a2; \ + pxor %mm5,%mm3; \ + movq %mm6,S2_x4; \ + pxor %mm1,%mm6; \ + movq %mm7,S2_x13; \ + pand %mm3,%mm1; \ + pand S2_a3,%mm3; \ + pxor %mm2,%mm1; \ + movq S2_x4,%mm7; \ + movq %mm1,%mm2; \ + pand S2_a4,%mm2; \ + pxor %mm6,%mm3; \ + movq %mm6,S2_x5; \ + pxor %mm2,%mm3; \ + movq S2_a1,%mm2; \ + por %mm5,%mm7; \ + por %mm2,%mm1; \ + pand %mm3,%mm7; \ + pxor out2,%mm3; \ + por %mm4,%mm2; \ + por S2_a3,%mm7; \ + movq %mm2,%mm6; \ + pxor S2_x13,%mm1; \ + por %mm5,%mm6; \ + movq %mm3,out2; \ + pand %mm0,%mm4; \ + movq S2_x13,%mm3; \ + por %mm0,%mm5; \ + movq %mm2,S2_x18; \ + pxor %mm6,%mm3; \ + movq S2_a2,%mm2; \ + pxor %mm6,%mm0; \ + pxor %mm2,%mm3; \ + pand %mm2,%mm0; \ + pxor %mm3,%mm7; \ + por %mm4,%mm2; \ + pxor S2_x3,%mm4; \ + pand %mm3,%mm6; \ + pxor %mm0,%mm4; \ + pxor %mm5,%mm6; \ + movq %mm7,S2_x25; \ + pand %mm3,%mm0; \ + movq S2_a3,%mm7; \ + pxor %mm2,%mm5; \ + pxor S2_x5,%mm0; \ + pand %mm4,%mm7; \ + pand S2_a2,%mm4; \ + pxor %mm5,%mm7; \ + por S2_a4,%mm7; \ + movq %mm1,%mm5; \ + por S2_a3,%mm5; \ + por %mm2,%mm1; \ + pand S2_x18,%mm2; \ + pxor %mm3,%mm4; \ + movq S2_a4,%mm3; \ + pand %mm4,%mm2; \ + pand S2_a3,%mm4; \ + pxor %mm5,%mm0; \ + pxor S2_x25,%mm7; \ + pxor %mm6,%mm4; \ + pxor out3,%mm7; \ + pand %mm3,%mm1; \ + por %mm3,%mm2; \ + pxor out1,%mm1; \ + pxor %mm4,%mm2; \ + pxor %mm0,%mm1; \ + pxor out4,%mm2; \ + movq %mm1,out1; \ + movq %mm7,out3; \ + movq %mm2,out4 + +#define S3_out1 %mm2 +#define S3_out2 %mm6 +#define S3_out3 %mm3 +#define S3_out4 %mm7 + +#define S3_a1 tmp_at(1) +#define S3_x2 tmp_at(2) +#define S3_x9 tmp_at(3) +#define S3_a5 tmp_at(4) +#define S3_x4 tmp_at(5) +#define S3_a6 tmp_at(6) +#define S3_x6 tmp_at(7) +#define S3_x5 tmp_at(8) +#define S3_x11 tmp_at(9) +#define S3_x12 tmp_at(10) +#define S3_x13 tmp_at(11) +#define S3_x54 tmp_at(12) +#define S3_x7 tmp_at(13) +#define S3_a4 tmp_at(14) +#define S3_a3 S3_a5 +#define S3_x38 S3_x4 + +#define S3(out1, out2, out3, out4, extra) \ + movq %mm0,S3_a1; \ + extra; \ + movq %mm4,%mm0; \ + movq %mm5,%mm6; \ + pxor pnot,%mm6; \ + movq %mm4,%mm7; \ + pxor %mm6,%mm7; \ + movq %mm6,S3_x2; \ + pand %mm2,%mm0; \ + movq %mm7,S3_x9; \ + pxor %mm5,%mm0; \ + movq %mm4,S3_a5; \ + pandn %mm3,%mm4; \ + movq %mm0,S3_x4; \ + por %mm3,%mm7; \ + movq S3_a5,%mm6; \ + pxor %mm4,%mm0; \ + movq %mm5,S3_a6; \ + pandn %mm2,%mm6; \ + movq %mm0,S3_x6; \ + pxor %mm6,%mm7; \ + movq S3_x2,%mm5; \ + pxor %mm1,%mm0; \ + movq %mm4,S3_x5; \ + movq %mm7,%mm4; \ + por S3_x4,%mm5; \ + pand %mm0,%mm4; \ + movq %mm7,S3_x11; \ + pxor %mm5,%mm6; \ + pxor S3_a5,%mm7; \ + por %mm1,%mm6; \ + movq %mm4,S3_x12; \ + pand %mm5,%mm4; \ + movq %mm7,S3_x13; \ + por %mm0,%mm7; \ + movq %mm4,S3_x54; \ + movq %mm2,%mm4; \ + pxor S3_x9,%mm4; \ + pand %mm3,%mm7; \ + movq %mm0,S3_x7; \ + pxor %mm3,%mm4; \ + pxor S3_a6,%mm5; \ + pxor %mm4,%mm6; \ + movq %mm3,S3_a4; \ + por %mm5,%mm3; \ + movq %mm2,S3_a3; \ + pxor %mm3,%mm5; \ + por %mm1,%mm5; \ + pxor %mm7,%mm2; \ + pxor S3_x12,%mm7; \ + movq %mm2,%mm4; \ + por S3_x5,%mm2; \ + pand %mm1,%mm7; \ + por S3_x4,%mm4; \ + por %mm1,%mm2; \ + pxor S3_x11,%mm7; \ + pxor %mm3,%mm2; \ + movq S3_a1,%mm3; \ + pxor S3_a4,%mm4; \ + pand %mm3,%mm7; \ + pxor S3_x7,%mm7; \ + por %mm3,%mm2; \ + movq %mm4,S3_x38; \ + pxor %mm6,%mm2; \ + pxor out4,%mm7; \ + por %mm1,%mm4; \ + movq S3_a3,%mm6; \ + movq %mm2,%mm3; \ + pxor S3_x9,%mm6; \ + por S3_x5,%mm6; \ + pxor S3_x38,%mm3; \ + pxor %mm6,%mm4; \ + movq S3_a6,%mm6; \ + pand S3_x11,%mm6; \ + movq %mm7,out4; \ + movq S3_x2,%mm0; \ + pxor %mm6,%mm3; \ + por S3_x6,%mm6; \ + pand %mm1,%mm3; \ + por S3_x38,%mm0; \ + pxor %mm6,%mm3; \ + pxor S3_x13,%mm0; \ + movq %mm5,%mm6; \ + por S3_a1,%mm3; \ + pxor %mm5,%mm0; \ + pand S3_x54,%mm6; \ + pxor %mm4,%mm3; \ + por S3_a1,%mm6; \ + pxor out3,%mm3; \ + pxor %mm0,%mm6; \ + pxor out1,%mm2; \ + movq %mm3,out3; \ + pxor out2,%mm6; \ + movq %mm2,out1; \ + movq %mm6,out2 + +#define S4_out1 %mm1 +#define S4_out2 %mm0 +#define S4_out3 %mm6 +#define S4_out4 %mm5 + +#define S4_a2 tmp_at(1) +#define S4_a3 tmp_at(2) +#define S4_a4 tmp_at(3) +#define S4_a6 tmp_at(4) + +#define S4(out1, out2, out3, out4, extra) \ + movq %mm2,%mm6; \ + movq %mm3,S4_a4; \ + movq %mm0,%mm7; \ + movq %mm1,S4_a2; \ + por %mm0,%mm6; \ + extra; \ + pand %mm4,%mm7; \ + movq %mm1,%mm3; \ + movq %mm5,S4_a6; \ + movq %mm2,S4_a3; \ + movq %mm4,%mm5; \ + pand %mm6,%mm5; \ + por %mm2,%mm3; \ + pxor pnot,%mm2; \ + pxor %mm5,%mm0; \ + pxor pnot,%mm0; \ + pxor %mm7,%mm6; \ + pxor %mm0,%mm3; \ + movq %mm1,%mm7; \ + pand %mm6,%mm7; \ + pxor %mm2,%mm5; \ + pxor %mm4,%mm2; \ + pand %mm5,%mm0; \ + pxor %mm7,%mm4; \ + pand %mm1,%mm5; \ + por %mm1,%mm2; \ + pxor %mm6,%mm5; \ + movq S4_a4,%mm1; \ + movq %mm0,%mm6; \ + pand %mm4,%mm1; \ + pxor %mm2,%mm6; \ + por S4_a4,%mm6; \ + pxor %mm3,%mm1; \ + pand S4_a2,%mm4; \ + pxor %mm5,%mm6; \ + movq S4_a6,%mm3; \ + pxor %mm0,%mm4; \ + pxor S4_a3,%mm7; \ + movq %mm3,%mm0; \ + pxor %mm2,%mm7; \ + pand %mm6,%mm0; \ + movq S4_a4,%mm2; \ + por %mm3,%mm6; \ + pxor %mm1,%mm0; \ + pand %mm2,%mm7; \ + pxor pnot,%mm1; \ + pxor %mm7,%mm4; \ + movq %mm4,%mm5; \ + pxor %mm1,%mm4; \ + pxor out1,%mm1; \ + por %mm4,%mm2; \ + pand S4_a2,%mm4; \ + pxor %mm6,%mm1; \ + pxor %mm0,%mm4; \ + pxor out3,%mm6; \ + pxor %mm4,%mm2; \ + pxor out2,%mm0; \ + pand %mm2,%mm3; \ + pxor %mm2,%mm6; \ + pxor %mm3,%mm5; \ + movq %mm1,out1; \ + pxor %mm5,%mm6; \ + movq %mm0,out2; \ + pxor out4,%mm5; \ + movq %mm6,out3; \ + movq %mm5,out4 + +#define S5_out1 %mm5 +#define S5_out2 %mm7 +#define S5_out3 %mm6 +#define S5_out4 %mm4 + +#define S5_a1 tmp_at(1) +#define S5_a2 tmp_at(2) +#define S5_a6 tmp_at(3) +#define S5_x2 tmp_at(4) +#define S5_x4 tmp_at(5) +#define S5_x5 tmp_at(6) +#define S5_x6 tmp_at(7) +#define S5_x7 tmp_at(8) +#define S5_x8 tmp_at(9) +#define S5_x9 tmp_at(10) +#define S5_x13 tmp_at(11) +#define S5_x16 tmp_at(12) +#define S5_x17 S5_a6 +#define S5_x21 S5_x7 +#define S5_x24 S5_x8 +#define S5_x28 S5_x17 +#define S5_x38 S5_x9 + +#define S5(out1, out2, out3, out4, extra) \ + movq %mm1,S5_a2; \ + movq %mm3,%mm6; \ + movq %mm2,%mm7; \ + pandn %mm2,%mm6; \ + pandn %mm0,%mm7; \ + movq %mm6,%mm1; \ + movq %mm0,S5_a1; \ + pxor %mm0,%mm1; \ + extra; \ + pxor %mm3,%mm0; \ + movq %mm1,S5_x2; \ + movq %mm5,S5_a6; \ + por %mm0,%mm6; \ + por %mm7,%mm5; \ + movq %mm6,S5_x7; \ + pxor %mm5,%mm1; \ + movq %mm5,S5_x4; \ + pand %mm2,%mm6; \ + movq S5_a6,%mm5; \ + pxor %mm3,%mm6; \ + pandn S5_x7,%mm5; \ + movq %mm0,S5_x6; \ + movq %mm7,%mm0; \ + movq %mm5,S5_x8; \ + pxor %mm2,%mm5; \ + movq %mm1,S5_x5; \ + pxor %mm3,%mm0; \ + movq %mm5,S5_x9; \ + pandn %mm6,%mm7; \ + por S5_a6,%mm0; \ + por %mm4,%mm5; \ + movq %mm6,S5_x13; \ + pxor %mm1,%mm5; \ + movq %mm0,S5_x16; \ + pxor %mm0,%mm7; \ + movq S5_a2,%mm0; \ + movq %mm4,%mm1; \ + movq %mm7,S5_x17; \ + por %mm7,%mm1; \ + pand S5_x5,%mm7; \ + pxor %mm6,%mm1; \ + pandn %mm1,%mm0; \ + movq %mm7,%mm6; \ + pandn S5_x7,%mm6; \ + pxor %mm0,%mm5; \ + pxor S5_x9,%mm7; \ + movq %mm3,%mm0; \ + movq %mm5,S5_x21; \ + movq %mm6,%mm5; \ + pandn S5_x8,%mm0; \ + pandn %mm1,%mm5; \ + pxor out3,%mm6; \ + pxor %mm2,%mm0; \ + movq S5_a1,%mm2; \ + movq %mm0,%mm1; \ + pxor S5_x9,%mm2; \ + pand %mm4,%mm1; \ + movq %mm7,S5_x38; \ + pxor %mm1,%mm6; \ + movq S5_x4,%mm1; \ + movq %mm2,%mm7; \ + pand S5_x2,%mm7; \ + pand %mm3,%mm1; \ + pxor S5_x17,%mm1; \ + pandn %mm4,%mm7; \ + movq %mm2,S5_x24; \ + pxor %mm7,%mm1; \ + movq out2,%mm7; \ + por %mm2,%mm3; \ + movq S5_a2,%mm2; \ + pxor %mm1,%mm7; \ + movq %mm3,S5_x28; \ + pandn %mm3,%mm2; \ + movq S5_x38,%mm3; \ + pxor %mm2,%mm7; \ + movq S5_x16,%mm2; \ + por %mm4,%mm3; \ + por S5_x13,%mm2; \ + por %mm5,%mm1; \ + pxor out1,%mm5; \ + pxor %mm3,%mm2; \ + por S5_a2,%mm2; \ + movq %mm7,out2; \ + pxor S5_x6,%mm1; \ + pxor %mm2,%mm6; \ + pandn %mm4,%mm1; \ + movq S5_x38,%mm2; \ + pxor S5_x24,%mm1; \ + movq %mm2,%mm3; \ + pxor S5_x21,%mm2; \ + pxor %mm1,%mm5; \ + pand S5_x6,%mm3; \ + pandn %mm4,%mm2; \ + pand S5_x28,%mm2; \ + pxor %mm0,%mm3; \ + pxor pnot,%mm6; \ + pxor %mm2,%mm3; \ + movq S5_x21,%mm4; \ + por S5_a2,%mm3; \ + movq %mm6,out3; \ + pxor out4,%mm4; \ + pxor %mm3,%mm5; \ + movq %mm4,out4; \ + movq %mm5,out1 + +#define S6_out1 %mm0 +#undef S6_out2 +#define S6_out3 %mm2 +#define S6_out4 %mm4 + +#define S6_a1 tmp_at(1) +#define S6_a2 tmp_at(2) +#define S6_a3 tmp_at(3) +#define S6_a4 tmp_at(4) +#define S6_x1 tmp_at(5) +#define S6_x2 tmp_at(6) +#define S6_x5 tmp_at(7) +#define S6_x6 tmp_at(8) +#define S6_x8 tmp_at(9) +#define S6_x15 tmp_at(10) +#define S6_x16 tmp_at(11) + +#define S6(out1, out2, out3, out4, extra) \ + movq %mm2,S6_a3; \ + extra; \ + movq %mm4,%mm6; \ + pxor pnot,%mm6; \ + movq %mm5,%mm7; \ + movq %mm1,S6_a2; \ + movq %mm4,%mm2; \ + movq %mm3,S6_a4; \ + pxor %mm1,%mm7; \ + pxor pnot,%mm1; \ + pxor %mm6,%mm7; \ + movq %mm6,S6_x2; \ + pxor %mm0,%mm7; \ + pand %mm5,%mm2; \ + movq %mm4,%mm6; \ + movq %mm1,S6_x1; \ + movq %mm5,%mm3; \ + pand S6_a2,%mm3; \ + pand %mm7,%mm6; \ + movq %mm0,S6_a1; \ + por %mm2,%mm1; \ + movq %mm2,S6_x6; \ + pand %mm6,%mm0; \ + movq %mm3,S6_x15; \ + pxor %mm0,%mm1; \ + movq S6_a4,%mm0; \ + movq %mm4,%mm2; \ + movq %mm6,S6_x8; \ + pand %mm1,%mm0; \ + movq %mm7,S6_x5; \ + pxor %mm3,%mm2; \ + movq S6_x2,%mm6; \ + pxor %mm7,%mm0; \ + movq S6_a1,%mm7; \ + pxor %mm5,%mm1; \ + movq %mm2,S6_x16; \ + pand %mm7,%mm2; \ + movq S6_a4,%mm3; \ + pxor %mm2,%mm6; \ + pxor S6_a2,%mm2; \ + pand %mm7,%mm1; \ + por %mm6,%mm3; \ + pxor %mm5,%mm6; \ + pxor %mm3,%mm1; \ + pand %mm6,%mm7; \ + pand S6_a3,%mm1; \ + pand %mm4,%mm6; \ + movq S6_x6,%mm3; \ + pxor %mm1,%mm0; \ + pxor out2,%mm0; \ + por %mm2,%mm3; \ + pand S6_a4,%mm3; \ + pxor %mm7,%mm4; \ + movq S6_x5,%mm1; \ + pxor %mm3,%mm4; \ + pxor pnot,%mm2; \ + por %mm4,%mm5; \ + movq %mm0,out2; \ + movq %mm5,%mm3; \ + pandn S6_a4,%mm3; \ + pxor %mm6,%mm1; \ + movq S6_x6,%mm0; \ + pxor %mm2,%mm3; \ + por S6_a4,%mm1; \ + pxor %mm3,%mm0; \ + pand S6_a3,%mm3; \ + pxor %mm1,%mm0; \ + por S6_x5,%mm6; \ + movq %mm7,%mm1; \ + pxor S6_x15,%mm7; \ + pxor %mm3,%mm4; \ + movq S6_a4,%mm3; \ + pxor %mm5,%mm7; \ + pand S6_x8,%mm5; \ + por %mm3,%mm7; \ + pxor S6_x6,%mm6; \ + por %mm3,%mm5; \ + por S6_x16,%mm1; \ + pxor %mm6,%mm5; \ + pxor S6_x1,%mm1; \ + movq S6_a3,%mm3; \ + pxor %mm1,%mm7; \ + pxor out4,%mm4; \ + por %mm3,%mm7; \ + pand %mm1,%mm2; \ + pxor out1,%mm0; \ + por %mm3,%mm2; \ + pxor %mm7,%mm0; \ + pxor %mm5,%mm2; \ + movq %mm4,out4; \ + pxor out3,%mm2; \ + movq %mm0,out1; \ + movq %mm2,out3 + +#define S7_out1 %mm7 +#define S7_out2 %mm1 +#define S7_out3 %mm3 +#define S7_out4 %mm0 + +#define S7_a1 tmp_at(1) +#define S7_a2 tmp_at(2) +#define S7_a4 tmp_at(3) +#define S7_a6 tmp_at(4) +#define S7_x6 tmp_at(5) +#define S7_x7 tmp_at(6) +#define S7_x8 tmp_at(7) +#define S7_x11 tmp_at(8) +#define S7_x13 tmp_at(9) +#define S7_x15 tmp_at(10) +#define S7_x25 tmp_at(11) +#define S7_x26 tmp_at(12) + +#define S7(out1, out2, out3, out4, extra) \ + movq %mm0,S7_a1; \ + movq %mm1,%mm6; \ + extra; \ + movq %mm1,S7_a2; \ + movq %mm3,%mm7; \ + movq %mm5,S7_a6; \ + pand %mm3,%mm6; \ + movq %mm3,S7_a4; \ + pxor %mm4,%mm6; \ + pxor pnot,%mm4; \ + pand %mm6,%mm7; \ + pand %mm4,%mm3; \ + movq %mm1,%mm5; \ + pxor %mm2,%mm6; \ + pxor %mm7,%mm5; \ + movq %mm7,S7_x6; \ + por %mm1,%mm4; \ + por %mm3,%mm1; \ + pxor %mm6,%mm7; \ + movq %mm5,S7_x7; \ + pand %mm2,%mm4; \ + pand %mm2,%mm5; \ + por %mm7,%mm3; \ + movq %mm1,S7_x13; \ + pxor %mm5,%mm0; \ + por S7_a6,%mm0; \ + pxor %mm4,%mm1; \ + movq %mm4,S7_x15; \ + pxor %mm6,%mm0; \ + movq %mm5,S7_x8; \ + movq %mm3,%mm4; \ + movq S7_a6,%mm6; \ + movq %mm0,%mm5; \ + pxor S7_x6,%mm5; \ + por %mm6,%mm4; \ + movq %mm7,S7_x25; \ + por %mm6,%mm5; \ + movq S7_a1,%mm7; \ + pxor %mm1,%mm5; \ + movq %mm3,S7_x26; \ + pand %mm5,%mm7; \ + movq %mm0,S7_x11; \ + pxor %mm0,%mm7; \ + movq S7_a4,%mm3; \ + movq %mm7,%mm0; \ + por S7_a2,%mm0; \ + pand %mm3,%mm1; \ + pand S7_x13,%mm3; \ + por S7_x7,%mm2; \ + pxor S7_x6,%mm0; \ + pxor %mm3,%mm2; \ + movq S7_a2,%mm3; \ + movq %mm0,%mm6; \ + pxor pnot,%mm3; \ + pxor S7_x15,%mm6; \ + por %mm3,%mm1; \ + pand S7_x26,%mm0; \ + pxor %mm6,%mm4; \ + pand S7_a6,%mm0; \ + por %mm3,%mm6; \ + por S7_a6,%mm6; \ + pand %mm5,%mm3; \ + pand S7_a6,%mm1; \ + pxor %mm3,%mm0; \ + por S7_a1,%mm0; \ + pxor %mm6,%mm2; \ + pxor S7_x11,%mm1; \ + pxor %mm4,%mm0; \ + movq S7_a1,%mm4; \ + pxor %mm2,%mm5; \ + movq S7_a4,%mm6; \ + por %mm2,%mm4; \ + pxor S7_x25,%mm6; \ + pxor %mm4,%mm1; \ + movq S7_a6,%mm4; \ + pand %mm1,%mm6; \ + movq S7_x6,%mm3; \ + pand %mm4,%mm6; \ + pxor S7_x15,%mm3; \ + pxor %mm5,%mm6; \ + pxor S7_x8,%mm2; \ + por %mm4,%mm3; \ + por S7_a1,%mm6; \ + pxor %mm2,%mm3; \ + pxor out1,%mm7; \ + pxor %mm6,%mm3; \ + pxor out2,%mm1; \ + movq %mm7,out1; \ + pxor out3,%mm3; \ + movq %mm1,out2; \ + pxor out4,%mm0; \ + movq %mm3,out3; \ + movq %mm0,out4 + +#define S8_out1 %mm6 +#define S8_out2 %mm2 +#define S8_out3 %mm5 +#define S8_out4 %mm1 + +#define S8_a1 tmp_at(1) +#define S8_a2 tmp_at(2) +#define S8_a4 tmp_at(3) +#define S8_a5 tmp_at(4) +#define S8_a6 tmp_at(5) +#define S8_x14 tmp_at(6) +#define S8_x22 tmp_at(7) +#define S8_x33 tmp_at(8) + +#define S8(out1, out2, out3, out4, extra) \ + movq %mm0,S8_a1; \ + extra; \ + movq %mm2,%mm6; \ + pxor pnot,%mm0; \ + movq %mm2,%mm7; \ + movq %mm3,S8_a4; \ + por %mm0,%mm7; \ + pxor pnot,%mm3; \ + pxor %mm0,%mm6; \ + movq %mm5,S8_a6; \ + movq %mm4,%mm5; \ + movq %mm1,S8_a2; \ + movq %mm7,%mm1; \ + movq %mm4,S8_a5; \ + pxor %mm3,%mm7; \ + por %mm6,%mm5; \ + por %mm7,%mm0; \ + pand %mm4,%mm1; \ + pandn %mm0,%mm2; \ + por %mm7,%mm4; \ + pxor %mm1,%mm2; \ + movq %mm5,S8_x22; \ + pand %mm3,%mm5; \ + por S8_a2,%mm2; \ + pxor %mm4,%mm7; \ + pxor %mm0,%mm3; \ + movq %mm4,%mm1; \ + pxor S8_x22,%mm7; \ + pxor %mm3,%mm1; \ + pxor %mm6,%mm4; \ + pxor %mm5,%mm2; \ + pxor S8_a1,%mm5; \ + pand %mm3,%mm6; \ + movq %mm1,S8_x14; \ + pand %mm4,%mm5; \ + movq %mm7,S8_x33; \ + movq %mm0,%mm1; \ + pand S8_a5,%mm3; \ + movq %mm0,%mm7; \ + pand S8_a5,%mm1; \ + pxor %mm3,%mm7; \ + pand S8_a2,%mm7; \ + pxor %mm1,%mm6; \ + movq S8_a6,%mm1; \ + pxor %mm4,%mm7; \ + por S8_a2,%mm6; \ + pandn %mm0,%mm4; \ + pxor S8_x14,%mm6; \ + pand %mm2,%mm1; \ + pxor S8_a1,%mm3; \ + pxor %mm6,%mm2; \ + por S8_a6,%mm6; \ + pxor %mm7,%mm1; \ + pxor S8_x22,%mm3; \ + pxor %mm7,%mm6; \ + por S8_a2,%mm4; \ + pand S8_a2,%mm5; \ + pxor %mm4,%mm3; \ + movq S8_a1,%mm4; \ + pand S8_x33,%mm4; \ + por S8_a4,%mm7; \ + pxor %mm4,%mm0; \ + pand S8_a2,%mm7; \ + pxor %mm0,%mm5; \ + movq S8_a6,%mm4; \ + por %mm0,%mm2; \ + pxor S8_x33,%mm7; \ + por %mm4,%mm5; \ + pxor out1,%mm6; \ + pand %mm4,%mm2; \ + pxor out4,%mm1; \ + pxor %mm7,%mm5; \ + pxor %mm3,%mm2; \ + pxor out3,%mm5; \ + movq %mm6,out1; \ + pxor out2,%mm2; \ + movq %mm1,out4; \ + movq %mm5,out3; \ + movq %mm2,out2 + +#define zero %mm0 + +#define DES_bs_clear_block_8(i) \ + movq zero,B(i); \ + movq zero,B(i + 1); \ + movq zero,B(i + 2); \ + movq zero,B(i + 3); \ + movq zero,B(i + 4); \ + movq zero,B(i + 5); \ + movq zero,B(i + 6); \ + movq zero,B(i + 7) + +#define DES_bs_clear_block \ + DES_bs_clear_block_8(0); \ + DES_bs_clear_block_8(8); \ + DES_bs_clear_block_8(16); \ + DES_bs_clear_block_8(24); \ + DES_bs_clear_block_8(32); \ + DES_bs_clear_block_8(40); \ + DES_bs_clear_block_8(48); \ + DES_bs_clear_block_8(56) + +#define k_ptr %edx +#define K(i) (i)*8(k_ptr) +#define k(i) (i)*4(k_ptr) + +#define a6_xor_ptr %esi +#define a6_p pxor (a6_xor_ptr),a6 +#define a6_v(i) pxor K(i),a6 + +#define tmp1 %ecx +#define tmp2 a6_xor_ptr + +#define xor_E(i) \ + movl E(i),tmp1; \ + movq K(i),a1; \ + movl E(i + 1),tmp2; \ + movq K(i + 1),a2; \ + pxor (tmp1),a1; \ + pxor (tmp2),a2; \ + movl E(i + 2),tmp1; \ + movq K(i + 2),a3; \ + movl E(i + 3),tmp2; \ + movq K(i + 3),a4; \ + pxor (tmp1),a3; \ + pxor (tmp2),a4; \ + movl E(i + 4),tmp1; \ + movq K(i + 4),a5; \ + movl E(i + 5),a6_xor_ptr; \ + movq K(i + 5),a6; \ + pxor (tmp1),a5 + +#define xor_B(b1, k1, b2, k2, b3, k3, b4, k4, b5, k5, b6) \ + movq B(b1),a1; \ + movq B(b2),a2; \ + pxor K(k1),a1; \ + movq B(b3),a3; \ + pxor K(k2),a2; \ + movq B(b4),a4; \ + pxor K(k3),a3; \ + movq B(b5),a5; \ + pxor K(k4),a4; \ + movq B(b6),a6; \ + pxor K(k5),a5 + +#define xor_B_KS_p(b1, k1, b2, k2, b3, k3, b4, k4, b5, k5, b6, k6) \ + movl k(k1),tmp1; \ + movl k(k2),tmp2; \ + movq B(b1),a1; \ + movq B(b2),a2; \ + pxor (tmp1),a1; \ + movl k(k3),tmp1; \ + pxor (tmp2),a2; \ + movl k(k4),tmp2; \ + movq B(b3),a3; \ + movq B(b4),a4; \ + pxor (tmp1),a3; \ + movl k(k5),tmp1; \ + pxor (tmp2),a4; \ + movq B(b5),a5; \ + movl k(k6),a6_xor_ptr; \ + movq B(b6),a6; \ + pxor (tmp1),a5 + +.data + +DO_ALIGN(3) +mm_ones: +.quad -1 + +.text + +DO_ALIGN(5) +.globl DES_bs_init_asm +DES_bs_init_asm: + movq mm_ones,%mm0 + movq %mm0,pnot + ret + +#define rounds_and_swapped %ebp +#define iterations %eax + +DO_ALIGN(5) +.globl DES_bs_crypt +DES_bs_crypt: + movl 4(%esp),iterations + pxor zero,zero + pushl %ebp + pushl %esi + movl $DES_bs_all_KS_v,k_ptr + DES_bs_clear_block + movl $8,rounds_and_swapped +DES_bs_crypt_start: + xor_E(0) + S1(B(40), B(48), B(54), B(62), a6_p) + xor_E(6) + S2(B(44), B(59), B(33), B(49), a6_p) + xor_E(12) + S3(B(55), B(47), B(61), B(37), a6_p) + xor_E(18) + S4(B(57), B(51), B(41), B(32), a6_p) + xor_E(24) + S5(B(39), B(45), B(56), B(34), a6_p) + xor_E(30) + S6(B(35), B(60), B(42), B(50), a6_p) + xor_E(36) + S7(B(63), B(43), B(53), B(38), a6_p) + xor_E(42) + S8(B(36), B(58), B(46), B(52), a6_p) + cmpl $0x100,rounds_and_swapped + je DES_bs_crypt_next +DES_bs_crypt_swap: + xor_E(48) + S1(B(8), B(16), B(22), B(30), a6_p) + xor_E(54) + S2(B(12), B(27), B(1), B(17), a6_p) + xor_E(60) + S3(B(23), B(15), B(29), B(5), a6_p) + xor_E(66) + S4(B(25), B(19), B(9), B(0), a6_p) + xor_E(72) + S5(B(7), B(13), B(24), B(2), a6_p) + xor_E(78) + S6(B(3), B(28), B(10), B(18), a6_p) + xor_E(84) + S7(B(31), B(11), B(21), B(6), a6_p) + xor_E(90) + addl $96*8,k_ptr + S8(B(4), B(26), B(14), B(20), a6_p) + decl rounds_and_swapped + jnz DES_bs_crypt_start + subl $0x300*8+48*8,k_ptr + movl $0x108,rounds_and_swapped + decl iterations + jnz DES_bs_crypt_swap + popl %esi + popl %ebp +#ifdef EMMS + emms +#endif + ret +DES_bs_crypt_next: + subl $0x300*8-48*8,k_ptr + movl $8,rounds_and_swapped + decl iterations + jnz DES_bs_crypt_start + popl %esi + popl %ebp +#ifdef EMMS + emms +#endif + ret + +DO_ALIGN(5) +.globl DES_bs_crypt_25 +DES_bs_crypt_25: + pxor zero,zero + pushl %ebp + pushl %esi + movl $DES_bs_all_KS_v,k_ptr + DES_bs_clear_block + movl $8,rounds_and_swapped + movl $25,iterations +DES_bs_crypt_25_start: + xor_E(0) + S1(B(40), B(48), B(54), B(62), a6_p) + xor_E(6) + S2(B(44), B(59), B(33), B(49), a6_p) + xor_B(7, 12, 8, 13, 9, 14, 10, 15, 11, 16, 12) + S3(B(55), B(47), B(61), B(37), a6_v(17)) + xor_B(11, 18, 12, 19, 13, 20, 14, 21, 15, 22, 16) + S4(B(57), B(51), B(41), B(32), a6_v(23)) + xor_E(24) + S5(B(39), B(45), B(56), B(34), a6_p) + xor_E(30) + S6(B(35), B(60), B(42), B(50), a6_p) + xor_B(23, 36, 24, 37, 25, 38, 26, 39, 27, 40, 28) + S7(B(63), B(43), B(53), B(38), a6_v(41)) + xor_B(27, 42, 28, 43, 29, 44, 30, 45, 31, 46, 0) + S8(B(36), B(58), B(46), B(52), a6_v(47)) + cmpl $0x100,rounds_and_swapped + je DES_bs_crypt_25_next +DES_bs_crypt_25_swap: + xor_E(48) + S1(B(8), B(16), B(22), B(30), a6_p) + xor_E(54) + S2(B(12), B(27), B(1), B(17), a6_p) + xor_B(39, 60, 40, 61, 41, 62, 42, 63, 43, 64, 44) + S3(B(23), B(15), B(29), B(5), a6_v(65)) + xor_B(43, 66, 44, 67, 45, 68, 46, 69, 47, 70, 48) + S4(B(25), B(19), B(9), B(0), a6_v(71)) + xor_E(72) + S5(B(7), B(13), B(24), B(2), a6_p) + xor_E(78) + S6(B(3), B(28), B(10), B(18), a6_p) + xor_B(55, 84, 56, 85, 57, 86, 58, 87, 59, 88, 60) + S7(B(31), B(11), B(21), B(6), a6_v(89)) + xor_B(59, 90, 60, 91, 61, 92, 62, 93, 63, 94, 32) + S8(B(4), B(26), B(14), B(20), a6_v(95)) + addl $96*8,k_ptr + decl rounds_and_swapped + jnz DES_bs_crypt_25_start + subl $0x300*8+48*8,k_ptr + movl $0x108,rounds_and_swapped + decl iterations + jnz DES_bs_crypt_25_swap + popl %esi + popl %ebp +#ifdef EMMS + emms +#endif + ret +DES_bs_crypt_25_next: + subl $0x300*8-48*8,k_ptr + movl $8,rounds_and_swapped + decl iterations + jmp DES_bs_crypt_25_start + +#define ones %mm1 + +#define rounds %eax + +DO_ALIGN(5) +.globl DES_bs_crypt_LM +DES_bs_crypt_LM: + pxor zero,zero + pushl %esi + movq pnot,ones + movl $DES_bs_all_KS_p,k_ptr + movq zero,B(0) + movq zero,B(1) + movq zero,B(2) + movq zero,B(3) + movq zero,B(4) + movq zero,B(5) + movq zero,B(6) + movq zero,B(7) + movq ones,B(8) + movq ones,B(9) + movq ones,B(10) + movq zero,B(11) + movq ones,B(12) + movq zero,B(13) + movq zero,B(14) + movq zero,B(15) + movq zero,B(16) + movq zero,B(17) + movq zero,B(18) + movq zero,B(19) + movq zero,B(20) + movq zero,B(21) + movq zero,B(22) + movq ones,B(23) + movq zero,B(24) + movq zero,B(25) + movq ones,B(26) + movq zero,B(27) + movq zero,B(28) + movq ones,B(29) + movq ones,B(30) + movq ones,B(31) + movq zero,B(32) + movq zero,B(33) + movq zero,B(34) + movq ones,B(35) + movq zero,B(36) + movq ones,B(37) + movq ones,B(38) + movq ones,B(39) + movq zero,B(40) + movq zero,B(41) + movq zero,B(42) + movq zero,B(43) + movq zero,B(44) + movq ones,B(45) + movq zero,B(46) + movq zero,B(47) + movq ones,B(48) + movq ones,B(49) + movq zero,B(50) + movq zero,B(51) + movq zero,B(52) + movq zero,B(53) + movq ones,B(54) + movq zero,B(55) + movq ones,B(56) + movq zero,B(57) + movq ones,B(58) + movq zero,B(59) + movq ones,B(60) + movq ones,B(61) + movq ones,B(62) + movq ones,B(63) + movl $8,rounds +DES_bs_crypt_LM_loop: + xor_B_KS_p(31, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5) + S1(B(40), B(48), B(54), B(62), a6_p) + xor_B_KS_p(3, 6, 4, 7, 5, 8, 6, 9, 7, 10, 8, 11) + S2(B(44), B(59), B(33), B(49), a6_p) + xor_B_KS_p(7, 12, 8, 13, 9, 14, 10, 15, 11, 16, 12, 17) + S3(B(55), B(47), B(61), B(37), a6_p) + xor_B_KS_p(11, 18, 12, 19, 13, 20, 14, 21, 15, 22, 16, 23) + S4(B(57), B(51), B(41), B(32), a6_p) + xor_B_KS_p(15, 24, 16, 25, 17, 26, 18, 27, 19, 28, 20, 29) + S5(B(39), B(45), B(56), B(34), a6_p) + xor_B_KS_p(19, 30, 20, 31, 21, 32, 22, 33, 23, 34, 24, 35) + S6(B(35), B(60), B(42), B(50), a6_p) + xor_B_KS_p(23, 36, 24, 37, 25, 38, 26, 39, 27, 40, 28, 41) + S7(B(63), B(43), B(53), B(38), a6_p) + xor_B_KS_p(27, 42, 28, 43, 29, 44, 30, 45, 31, 46, 0, 47) + S8(B(36), B(58), B(46), B(52), a6_p) + xor_B_KS_p(63, 48, 32, 49, 33, 50, 34, 51, 35, 52, 36, 53) + S1(B(8), B(16), B(22), B(30), a6_p) + xor_B_KS_p(35, 54, 36, 55, 37, 56, 38, 57, 39, 58, 40, 59) + S2(B(12), B(27), B(1), B(17), a6_p) + xor_B_KS_p(39, 60, 40, 61, 41, 62, 42, 63, 43, 64, 44, 65) + S3(B(23), B(15), B(29), B(5), a6_p) + xor_B_KS_p(43, 66, 44, 67, 45, 68, 46, 69, 47, 70, 48, 71) + S4(B(25), B(19), B(9), B(0), a6_p) + xor_B_KS_p(47, 72, 48, 73, 49, 74, 50, 75, 51, 76, 52, 77) + S5(B(7), B(13), B(24), B(2), a6_p) + xor_B_KS_p(51, 78, 52, 79, 53, 80, 54, 81, 55, 82, 56, 83) + S6(B(3), B(28), B(10), B(18), a6_p) + xor_B_KS_p(55, 84, 56, 85, 57, 86, 58, 87, 59, 88, 60, 89) + S7(B(31), B(11), B(21), B(6), a6_p) + xor_B_KS_p(59, 90, 60, 91, 61, 92, 62, 93, 63, 94, 32, 95) + addl $96*4,k_ptr + S8(B(4), B(26), B(14), B(20), a6_p) + decl rounds + jnz DES_bs_crypt_LM_loop + popl %esi +#ifdef EMMS + emms +#endif + ret diff -ruN john-1.6/src/x86.S john-1.6.34/src/x86.S --- john-1.6/src/x86.S 1998-12-03 01:29:50.000000000 +0100 +++ john-1.6.34/src/x86.S 2002-06-22 10:51:30.000000000 +0200 @@ -1,6 +1,6 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-98 by Solar Designer + * Copyright (c) 1996-2001 by Solar Designer */ /* @@ -35,7 +35,7 @@ #ifndef ALIGN_FIX #ifdef ALIGN_LOG #define DO_ALIGN(log) .align (log) -#elif defined(SOLARIS) +#elif defined(DUMBAS) #define DO_ALIGN(log) .align 1 << log #else #define DO_ALIGN(log) .align (1 << (log)) @@ -52,12 +52,15 @@ * DES stuff. * * Included are versions for: - * 1. MMX (Pentium MMX, Pentium II, some clones); + * 1. MMX (Pentium MMX and newer Intel x86 CPUs, some clones); * 2. Intel Pentium without MMX; * 3. The rest (good for Pentium Pro, 486, clones). * * MMX has to be enabled at compile time (via DES_X2 in arch.h), while #2 * or #3 is chosen based on CPUID info at runtime. + * + * Note: MMX code for the bitslice DES implementation is in x86-mmx.S, so + * you probably want to look in there instead. */ .text @@ -498,9 +501,9 @@ xorl DES_SPE_H+0x700(%edx),Rh DO_ALIGN(12) -DES_std_crypt_any: +DES_std_crypt_generic: DES_CRYPT_START -DES_loop_any: +DES_loop_generic: DES_2_ROUNDS_ANY(DES_KS_copy) DES_2_ROUNDS_ANY(DES_KS_copy+16) DES_2_ROUNDS_ANY(DES_KS_copy+32) @@ -521,7 +524,7 @@ decl DES_count_tmp movl %eax,Rh movl DES_KS_copy,%eax - jnz DES_loop_any + jnz DES_loop_generic DES_CRYPT_END #define DES_xor1(ofs) \ @@ -611,7 +614,7 @@ * Weird alignments to make sure KS address's bits 5-11 never match current * instruction pointer's bits 5-11. */ -#ifdef SOLARIS +#ifdef DUMBAS DO_ALIGN(12) .zero 0x1000 - 32 - 128 #elif defined(__DJGPP__) @@ -629,7 +632,7 @@ */ .globl DES_std_crypt DES_std_crypt: -.long DES_std_crypt_any +.long DES_std_crypt_generic DES_SavedL: .long 0 @@ -641,7 +644,7 @@ */ .globl DES_IV DES_IV: -#ifdef SOLARIS +#ifdef DUMBAS .zero 16 #else .space 16 @@ -657,7 +660,7 @@ DO_ALIGN(5) .globl DES_KS_copy DES_KS_copy: -#ifdef SOLARIS +#ifdef DUMBAS .zero 128 #else .space 128 @@ -681,7 +684,7 @@ .globl DES_SPE_L DES_SPE_L: -#ifdef SOLARIS +#ifdef DUMBAS .zero 0x800 #else .space 0x800 @@ -696,7 +699,7 @@ .globl DES_SPE_H DES_SPE_H: -#ifdef SOLARIS +#ifdef DUMBAS .zero 0x800 #else .space 0x800 @@ -708,7 +711,7 @@ .globl DES_KS_current DES_KS_current: -#ifdef SOLARIS +#ifdef DUMBAS .zero 128 #else .space 128 @@ -716,7 +719,7 @@ .globl DES_KS_table DES_KS_table: -#ifdef SOLARIS +#ifdef DUMBAS .zero 0x20000 #else .space (8 * 128 * 16 * 8) @@ -756,7 +759,7 @@ #undef tmp2 #define tmp1 %eax #define tmp2 %ecx -#ifdef SOLARIS +#ifdef DUMBAS #define x(i) i+i+i+i(%ebp) #else #define x(i) 4*i(%ebp) @@ -813,22 +816,43 @@ .globl MD5_body MD5_body: pushl %ebp + movl 8(%esp),%ebp pushl %ebx pushl %esi pushl %edi - movl 20(%esp),%ebp /* Round 1 */ - movl $0xd76aa477,a - movl $Cb,b - addl x(0),a - movl $Cc,c + movl x(0),a + movl x(1),d + addl $0xd76aa477,a roll $S11,a - movl $Cd,d - addl b,a - movl $0x77777777,tmp1 - FF (d, a, b, c, x( 1), S12, 0xe8c7b756) /* 2 */ - FF (c, d, a, b, x( 2), S13, 0x242070db) /* 3 */ - FF (b, c, d, a, x( 3), S14, 0xc1bdceee) /* 4 */ + addl $0xf8fa0bcc,d + addl $Cb,a + movl x(2),c + movl a,tmp1 + movl a,tmp2 + andl $0x77777777,tmp1 + xorl $Cb,tmp2 + xorl $Cc,tmp1 + addl $0xbcdb4dd9,c + addl tmp1,d + roll $S12,d + addl a,d + andl d,tmp2 + xorl $Cb,tmp2 + addl tmp2,c + movl d,tmp1 + roll $S13,c + xorl a,tmp1 + addl d,c + andl c,tmp1 + movl x(3),b + xorl a,tmp1 + addl $0xb18b7a77,b + addl tmp1,b + movl c,tmp1 + roll $S14,b + xorl d,tmp1 + addl c,b FF (a, b, c, d, x( 4), S11, 0xf57c0faf) /* 5 */ FF (d, a, b, c, x( 5), S12, 0x4787c62a) /* 6 */ FF (c, d, a, b, x( 6), S13, 0xa8304613) /* 7 */ @@ -953,118 +977,252 @@ * Blowfish stuff. */ +#ifdef DUMBAS +#define P(N) BF_current+0x1000+N+N+N+N +#else +#define P(N) BF_current+0x1000+4*N +#endif + +/* + * Intel Pentium optimized version, extra operations are used to avoid + * imperfect pairing. Also used on the Pentium 4. + */ + #undef L #undef R #undef tmp1 #undef tmp2 #define L %esi #define R %edi -#define tmp1 %ecx -#define tmp1_lo %cl -#define tmp2 %ebp - -#ifdef SOLARIS -#define P(N) BF_current+0x1000+N+N+N+N -#else -#define P(N) BF_current+0x1000+4*N -#endif +#define tmp1 %eax +#define tmp1_lo %al +#define tmp2 %ecx +#define tmp2_hi %ch +#define tmp3 %edx +#define tmp3_lo %dl +#define tmp4 %ebx +#define tmp4_hi %bh +#define tmp5 %ebp .text -#define BF_ROUND(L, R, N) \ - xorl L,%eax; \ +#define BF_ROUND_P5(L, R, N) \ + xorl L,tmp2; \ xorl tmp1,tmp1; \ - movl %eax,L; \ - shrl $16,%eax; \ - movl L,%edx; \ - movb %ah,tmp1_lo; \ - andl $0xFF,%eax; \ - movb %dh,%bl; \ - andl $0xFF,%edx; \ + movl tmp2,L; \ + shrl $16,tmp2; \ + movl L,tmp4; \ + movb tmp2_hi,tmp1_lo; \ + andl $0xFF,tmp2; \ + movb tmp4_hi,tmp3_lo; \ + andl $0xFF,tmp4; \ movl BF_current(,tmp1,4),tmp1; \ - movl BF_current+0x400(,%eax,4),tmp2; \ - addl tmp2,tmp1; \ - movl BF_current+0x800(,%ebx,4),tmp2; \ - xorl tmp2,tmp1; \ - movl BF_current+0xC00(,%edx,4),tmp2; \ - addl tmp1,tmp2; \ - movl P(N)+4,%eax; \ - xorl tmp2,R - -#define BF_ENCRYPT_START \ - BF_ROUND(L, R, 0); \ - BF_ROUND(R, L, 1); \ - BF_ROUND(L, R, 2); \ - BF_ROUND(R, L, 3); \ - BF_ROUND(L, R, 4); \ - BF_ROUND(R, L, 5); \ - BF_ROUND(L, R, 6); \ - BF_ROUND(R, L, 7); \ - BF_ROUND(L, R, 8); \ - BF_ROUND(R, L, 9); \ - BF_ROUND(L, R, 10); \ - BF_ROUND(R, L, 11); \ - BF_ROUND(L, R, 12); \ - BF_ROUND(R, L, 13); \ - BF_ROUND(L, R, 14); \ - BF_ROUND(R, L, 15); \ - movl BF_ptr,tmp2; \ - xorl L,%eax; \ + movl BF_current+0x400(,tmp2,4),tmp5; \ + addl tmp5,tmp1; \ + movl BF_current+0x800(,tmp3,4),tmp5; \ + xorl tmp5,tmp1; \ + movl BF_current+0xC00(,tmp4,4),tmp5; \ + addl tmp1,tmp5; \ + movl P(N)+4,tmp2; \ + xorl tmp5,R + +#define BF_ENCRYPT_START_P5 \ + BF_ROUND_P5(L, R, 0); \ + BF_ROUND_P5(R, L, 1); \ + BF_ROUND_P5(L, R, 2); \ + BF_ROUND_P5(R, L, 3); \ + BF_ROUND_P5(L, R, 4); \ + BF_ROUND_P5(R, L, 5); \ + BF_ROUND_P5(L, R, 6); \ + BF_ROUND_P5(R, L, 7); \ + BF_ROUND_P5(L, R, 8); \ + BF_ROUND_P5(R, L, 9); \ + BF_ROUND_P5(L, R, 10); \ + BF_ROUND_P5(R, L, 11); \ + BF_ROUND_P5(L, R, 12); \ + BF_ROUND_P5(R, L, 13); \ + BF_ROUND_P5(L, R, 14); \ + BF_ROUND_P5(R, L, 15); \ + movl BF_ptr,tmp5; \ + xorl L,tmp2; \ movl P(17),L -#define BF_ENCRYPT_END \ +#define BF_ENCRYPT_END_P5 \ xorl R,L; \ - movl %eax,R + movl tmp2,R DO_ALIGN(12) -.globl BF_body -BF_body: +.globl BF_body_P5 +BF_body_P5: pushl %ebp pushl %ebx pushl %esi pushl %edi xorl L,L xorl R,R - movl P(0),%eax - xorl %ebx,%ebx + movl P(0),tmp2 + xorl tmp3,tmp3 movl $P(0),BF_ptr -BF_loop_P: +BF_loop_P_P5: + BF_ENCRYPT_START_P5 + addl $8,tmp5 + BF_ENCRYPT_END_P5 + movl tmp5,BF_ptr + cmpl $P(18),tmp5 + movl L,-8(tmp5) + movl R,-4(tmp5) + movl P(0),tmp2 + jb BF_loop_P_P5 +#ifndef DONT_AVOID_PENTIUMPRO_FAMILY_PARTIAL_REGISTER_STALLS + xorl tmp3,tmp3 +#endif + movl $BF_current,BF_ptr +BF_loop_S_P5: + BF_ENCRYPT_START_P5 + BF_ENCRYPT_END_P5 + movl P(0),tmp2 + movl L,(tmp5) + movl R,4(tmp5) + BF_ENCRYPT_START_P5 + BF_ENCRYPT_END_P5 + movl P(0),tmp2 + movl L,8(tmp5) + movl R,12(tmp5) + BF_ENCRYPT_START_P5 + BF_ENCRYPT_END_P5 + movl P(0),tmp2 + movl L,16(tmp5) + movl R,20(tmp5) + BF_ENCRYPT_START_P5 + addl $32,tmp5 + BF_ENCRYPT_END_P5 + movl tmp5,BF_ptr + cmpl $BF_current+0x1000,tmp5 + movl P(0),tmp2 + movl L,-8(tmp5) + movl R,-4(tmp5) + jb BF_loop_S_P5 + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + +/* + * Generic x86 version. + */ + +#undef L +#undef R +#undef tmp1 +#undef tmp1_lo +#undef tmp2 +#undef tmp2_hi +#undef tmp3 +#undef tmp3_lo +#undef tmp4 +#undef tmp4_hi +#undef tmp5 +#define L %edx +#define L_lo %dl +#define L_hi %dh +#define R %ebx +#define R_lo %bl +#define R_hi %bh +#define tmp1 %eax +#define tmp2 %ecx +#define tmp2_hi %ch +#define tmp3 %esi +#define tmp4 %edi +#define ptr %ebp + +#define BF_ROUND_START(L, L_lo, L_hi) \ + shldl $16,L,tmp2; \ + movzbl L_hi,tmp3; \ + movzbl tmp2_hi,tmp1; \ + andl $0xFF,tmp2; \ + movzbl L_lo,tmp4; \ + movl BF_current(,tmp1,4),tmp1; \ + addl BF_current+0x400(,tmp2,4),tmp1 + +#define BF_ROUND_END(R, N) \ + xorl BF_current+0x800(,tmp3,4),tmp1; \ + addl BF_current+0xC00(,tmp4,4),tmp1; \ + xorl P(N)+4,R; \ + xorl tmp1,R + +#define BF_ROUND(L, L_lo, L_hi, R, N) \ + BF_ROUND_START(L, L_lo, L_hi); \ + BF_ROUND_END(R, N) + +#define BF_ENCRYPT_START \ + xorl P(0),L; \ + BF_ROUND(L, L_lo, L_hi, R, 0); \ + BF_ROUND(R, R_lo, R_hi, L, 1); \ + BF_ROUND(L, L_lo, L_hi, R, 2); \ + BF_ROUND(R, R_lo, R_hi, L, 3); \ + BF_ROUND(L, L_lo, L_hi, R, 4); \ + BF_ROUND(R, R_lo, R_hi, L, 5); \ + BF_ROUND(L, L_lo, L_hi, R, 6); \ + BF_ROUND(R, R_lo, R_hi, L, 7); \ + BF_ROUND(L, L_lo, L_hi, R, 8); \ + BF_ROUND(R, R_lo, R_hi, L, 9); \ + BF_ROUND(L, L_lo, L_hi, R, 10); \ + BF_ROUND(R, R_lo, R_hi, L, 11); \ + BF_ROUND(L, L_lo, L_hi, R, 12); \ + BF_ROUND(R, R_lo, R_hi, L, 13); \ + BF_ROUND(L, L_lo, L_hi, R, 14); \ + BF_ROUND_START(R, R_lo, R_hi); \ + movl R,tmp2; \ + movl P(16),R; \ + xorl BF_current+0x800(,tmp3,4),tmp1; \ + xorl L,R; \ + addl BF_current+0xC00(,tmp4,4),tmp1; \ + movl P(17),L; \ + xorl tmp1,R; \ + +#define BF_ENCRYPT_END \ + xorl tmp2,L + +DO_ALIGN(12) +.globl BF_body_generic +BF_body_generic: + pushl %ebp + pushl %ebx + pushl %esi + pushl %edi + xorl L,L + xorl R,R + movl $P(0),ptr +BF_loop_P_generic: BF_ENCRYPT_START - addl $8,tmp2 + addl $8,ptr BF_ENCRYPT_END - movl tmp2,BF_ptr - cmpl $P(18),tmp2 - movl L,-8(tmp2) - movl R,-4(tmp2) - movl P(0),%eax - jb BF_loop_P - xorl %ebx,%ebx - movl $BF_current,BF_ptr -BF_loop_S: + cmpl $P(18),ptr + movl L,-8(ptr) + movl R,-4(ptr) + jb BF_loop_P_generic + movl $BF_current,ptr +BF_loop_S_generic: BF_ENCRYPT_START BF_ENCRYPT_END - movl P(0),%eax - movl L,(tmp2) - movl R,4(tmp2) + movl L,(ptr) + movl R,4(ptr) BF_ENCRYPT_START BF_ENCRYPT_END - movl P(0),%eax - movl L,8(tmp2) - movl R,12(tmp2) + movl L,8(ptr) + movl R,12(ptr) BF_ENCRYPT_START BF_ENCRYPT_END - movl P(0),%eax - movl L,16(tmp2) - movl R,20(tmp2) + movl L,16(ptr) + movl R,20(ptr) BF_ENCRYPT_START - addl $32,tmp2 + addl $32,ptr BF_ENCRYPT_END - movl tmp2,BF_ptr - cmpl $BF_current+0x1000,tmp2 - movl P(0),%eax - movl L,-8(tmp2) - movl R,-4(tmp2) - jb BF_loop_S + cmpl $BF_current+0x1000,ptr + movl L,-8(ptr) + movl R,-4(ptr) + jb BF_loop_S_generic popl %edi popl %esi popl %ebx @@ -1077,7 +1235,7 @@ .bss #endif -#ifdef SOLARIS +#ifdef DUMBAS DO_ALIGN(12) .zero 0x1000 - 96 #elif defined(__DJGPP__) @@ -1091,7 +1249,7 @@ .globl BF_current BF_current: -#ifdef SOLARIS +#ifdef DUMBAS .zero 0x1000 + 72 #else .space (0x1000 + 72) @@ -1100,6 +1258,13 @@ BF_ptr: .long 0 +/* + * The function pointer, set by CPU_detect(). + */ +.globl BF_body +BF_body: +.long 0 + #ifdef __DJGPP__ .space 32 #endif @@ -1111,11 +1276,20 @@ #define EF_ID $0x00200000 #define CF_MMX $0x00800000 #define CV_INTEL $0x6C65746E +#define CV_AMD $0x444D4163 .text +#if !DES_X2 +#define cpuid \ + .byte 0x0F; \ + .byte 0xA2 +#endif + .globl CPU_detect CPU_detect: + pushl %ebx + movl $BF_body_generic,BF_body pushfl pushfl xorl EF_ID,(%esp) @@ -1125,30 +1299,51 @@ xorl (%esp),%eax popfl andl EF_ID,%eax - jz CPU_detect_ret + jz CPU_detect_ret /* 386/486 */ + xorl %eax,%eax + cpuid + testl %eax,%eax + jz CPU_detect_ret /* Newer 486's */ + pushl %ecx movl $1,%eax - pushl %ebx -#if DES_X2 cpuid - popl %ebx + popl %ecx +#if DES_X2 xchgl %edx,%eax andl CF_MMX,%eax -#else - .byte 0x0F - .byte 0xA2 - popl %ebx + jz CPU_detect_ret /* No MMX */ + xchgl %edx,%eax +#endif andb $0x0F,%ah - cmpb $5,%ah - jne CPU_detect_ret - xorl %eax,%eax - pushl %ebx - .byte 0x0F - .byte 0xA2 - popl %ebx + cmpl CV_AMD,%ecx + je CPU_detect_AMD /* Is an AMD processor */ cmpl CV_INTEL,%ecx - jne CPU_detect_ret - movl $DES_std_crypt_P5,%eax - movl %eax,DES_std_crypt + jne CPU_detect_yes /* Not an Intel or AMD */ + cmpb $5,%ah + je CPU_detect_P5 /* Intel Pentium */ + cmpb $15,%ah + je CPU_detect_P5 /* Intel Pentium 4 */ + jmp CPU_detect_yes /* Not one of the above */ +CPU_detect_AMD: + cmpb $6,%ah + jne CPU_detect_yes /* Not an AMD Athlon */ +CPU_detect_P5: +/* + * Enable Intel Pentium optimizations when running on one of: + * + * Intel Pentium + * Intel Pentium 4 + * AMD Athlon + * + */ +#if !DES_X2 + movl $DES_std_crypt_P5,DES_std_crypt +#endif + movl $BF_body_P5,BF_body +CPU_detect_yes: +#if DES_X2 + movb $1,%al #endif CPU_detect_ret: + popl %ebx ret