This patch for John the Ripper adds a lot of code, documentation, and data contributed by the user community. This is not "official" John the Ripper code. It is very easy for new code to be added to this patch: the quality requirements are low. This means that you get a lot of functionality that is not "mature" enough or is otherwise inappropriate for the official JtR, which in turn also means that bugs in this code are to be expected, etc. How to apply this patch to JtR: http://openwall.info/wiki/john/how-to-extract-tarballs-and-apply-patches Licensing info: http://openwall.info/wiki/john/licensing How to contribute more code: http://openwall.info/wiki/how-to-make-patches diff -urpN john-1.7.3.4.orig/doc/EPi.patch.README john-1.7.3.4/doc/EPi.patch.README --- john-1.7.3.4.orig/doc/EPi.patch.README 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/doc/EPi.patch.README 2008-01-26 15:03:46 +0000 @@ -0,0 +1,33 @@ += Intro +======= + +EPiServer is a popular webbased content management system from Elektropost (http://www.episerver.com). +You can dump the password hashes using the SQL syntax "select name, salt, hash from tblSID". The tblSID +tabel stores interesting things such as usernames, salt and password hashes, but also passwords in cleartext. +If a password can be found in cleartext it is found in the password column of tblSID. + += Install +========= + +Copy the epibf_X.Y-john_1.7.2.patch (where X and Y needs to be replaced with the version you downloaded) +to your john source directory, e.g. john-1.7.2/src and then run "patch -p2 < epibf_X.Y-john_1.7.2.patch" (remember the X and Y). +The patch will create a file called EPI_fmt.c, some files for SHA1 support as well as update some of johns +files in order to incorporate the patch with john. + += Usage +======= + +This patch needs the format of the password file to be: : . (Currently you need to include +an inital 0x of both salt and hash.) + +--- Contents of an example epipasswd file --- + +webadmin:0x6631F625DEC28716FC24FA3CC1B3E2055E4281F4465226905C10D3456035 0x4F25D9BD24B81D85B1F2D106037C71CD2C828168 +epiuser:0x48F9BA13F54CE7AF669C76EEBC6BEA4564EBB77F1866CA5F2B297F7159C1 0xDA4260812C195025B4442C5C84E0F890122B285A + +-------------- End -------------------------- + +You can then run "john epipasswd", the format will be autodetected. +In case you'd like to check the performance of the patch try "john --test --format:epi". + +-johannes diff -urpN john-1.7.3.4.orig/doc/HDAA_README john-1.7.3.4/doc/HDAA_README --- john-1.7.3.4.orig/doc/HDAA_README 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/doc/HDAA_README 2008-07-21 10:55:30 +0000 @@ -0,0 +1,38 @@ + HTTP Digest access authentication + --------------------------------- + + + +- How to create the password string : +------------------------------------- + + +user:$MAGIC$response$user$realm$method$uri$nonce$nonceCount$ClientNonce$qop + +'$' is use as separator, you can change it in HDAA_fmt.c + + +Example of password string : + +user:$response$679066476e67b5c7c4e88f04be567f8b$user$myrealm$GET$/$8c12bd8f728afe56d45a0ce846b70e5a$00000001$4b61913cec32e2c9$auth + +Here the magic is '$response$' + + + + + +- Demonstration : +----------------- + +Tested on a : AMD Athlon(tm) 64 Processor 3000+ + +$ cat ./htdigest +moi:$response$faa6cb7d676e5b7c17fcbf966436aa0c$moi$myrealm$GET$/$af32592775d27b1cd06356b3a0db9ddf$00000001$8e1d49754a25aea7$auth +user:$response$679066476e67b5c7c4e88f04be567f8b$user$myrealm$GET$/$8c12bd8f728afe56d45a0ce846b70e5a$00000001$4b61913cec32e2c9$auth + +$ ./john ./htdigest +Loaded 2 password hashes with 2 different salts (HTTP Digest access authentication [HDAA-MD5]) +kikou (moi) +nocode (user) +guesses: 2 time: 0:00:01:27 (3) c/s: 670223 trying: nocode diff -urpN john-1.7.3.4.orig/doc/MARKOV john-1.7.3.4/doc/MARKOV --- john-1.7.3.4.orig/doc/MARKOV 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/doc/MARKOV 2007-11-02 11:37:50 +0000 @@ -0,0 +1,122 @@ +BASIC USAGE +The Markov mode is based from [1], tested and applied to "classical" password +cracking in [2]. This mode similar to the "wordlist" mode because it will only +crack a fixed quantity of passwords. Its parameters are: + +--markov:LEVEL:START:END:LENGTH + +Where: +* LEVEL is the "Markov level". This value is the maximum strength of passwords +that are going to be cracked. When LEVEL increases, the quantity of passwords +that are going to be tested increases exponentially. +* START is the index of the first password that is going to be tested, starting +with 0. +* END is the index of the last password that is going to be tested. When it is +set to 0, it will represent the last possible password. +* LENGTH is the maximum length of the tested passwords. + +using --markov:100:0:0:12 will let john check every password whose length is 12 +or less and whose "Markov strength" is 100 or less. + + +SELECTING THE PARAMETERS +The "LEVEL" parameter should be selected based on the desired maximum running +time. In order to select the appropriate LEVEL, the following steps should be +followed: +1/ Run the -single and -wordlist modes of john, as they will find many passwords +for a low price +2/ Run john with a low markov level on the file, using the time utility. For +example: +******************************************************************************* +time john -markov:180 test +Loaded 156 password hashes with no different salts (NT LM DES [128/128 BS SSE2]) +Warning: MaxLen = 12 is too large for the current hash type, reduced to 7 +MKV start (lvl=180 len=7 pwd=30449568) +guesses: 0 time: 0:00:00:10 99% c/s: 475013K trying: + +real 0m10.707s +user 0m10.621s +sys 0m0.012s +******************************************************************************* +This means that john can test 2.8M (30449568/10.707) passwords / seconds. It +should be noted that with salted passwords the cracking speed will increase with +every cracked password. This number should be corrected based on the experience +of the user. +3/ Evaluate the quantity of passwords that could be cracked during the selected +time. Using the previous example, a cracking time of 3 hours will lead to a +quantity of passwords of 30714M passwords (30449568/10.707*3600*3). +4/ Use the genmkpwd command to find the corresponding level. Using the previous +example, with a maximum password length of 12 (stupid because LM has a maximum +length of 7 ...): +******************************************************************************* +genmkvpwd stats 0 12 +[...] +lvl=245 (5904 Kb for nbparts) 26 G possible passwords (26528306250) +lvl=246 (5928 Kb for nbparts) 29 G possible passwords (29373638087) +lvl=247 (5952 Kb for nbparts) 32 G possible passwords (32524537496) +[...] +******************************************************************************* +Here, the selected level will be 246 (the higher level where the number of +possible passwords is less than 30714M). +5/ Run john: +******************************************************************************* +john -markov:246:0:0:12 test +******************************************************************************* + + +DISTRIBUTING WORK +The START and END parameter could be used to distribute work among many CPUs. +The preferred method is to evaluate the combined cracking speed of all CPUs +(adding the step 2 result for every CPUs available) and follow the previous +method. +At step 5, share the cracking space among all CPUs, where is share is +proportionnal with the CPU's cracking speed. + + +CONFIGURATION OPTIONS +New options are available in the john.conf file: +Statsfile - This is the path of the "stat" file. +MkvLvl - the default level +MkvMaxLen - the default length + + +WHAT IS THE STAT FILE? +The markov mode is based on statistical data from real passwords. This data is +stored in the "stat" file. In order to generate a custom stat file, it is +recommanded to use the new calc_stat command: + +./calc_stat "dictionnary file" stats + + +MKVCALCPROBA USAGE +This program is used to generate statistics about cracked passwords. It accepts +as input the "stat" file and a file with a single cracked password per line. +Here is a sample output: + +******************************************************************************* +./mkvcalcproba stats /tmp/passwordlist +test 33+16+28+20 97 4 40030907 45 +password 29+16+30+22+51+25+24+30 227 8 2698006565378672 177 +32'[[! 55+24+98+1000+23+29 1229 6 39949021871 1169 +charsetsize = 92 +******************************************************************************* + +Its output is tab separated and should open nicely in spreadsheets. Here is the +meaning of the column: +1/ Cracked password, reprinted from the file +2/ Sum of all "markov probabilities" of every letter of the word. This is +supposed to help identify which parts of the password makes them strong. The +number "1000" is written when no 1st/2nd letter combinations were found in the +stat file (for exemple ' then [ here). +3/ Markov strength +4/ Password length +5/ Rank when bruteforced "stupidly" (a, b, c, ..., aa, ab, ac ...) considering +that letters are ordered given their appearance probability and the given +charsetsize (92) +6/ Markov strength of the password where the two first letters are removed + + +REFERENCES + +[1] http://www.cs.utexas.edu/~shmat/shmat_ccs05pwd.ps +[2] http://actes.sstic.org/SSTIC07/Password_Cracking/ diff -urpN john-1.7.3.4.orig/run/genincstats.rb john-1.7.3.4/run/genincstats.rb --- john-1.7.3.4.orig/run/genincstats.rb 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/run/genincstats.rb 2008-04-14 12:53:04 +0000 @@ -0,0 +1,78 @@ +#!/usr/bin/ruby -w + +require 'getoptlong' + +def help + puts "Usage: #{$0} [options]" + puts "\t-h --help\t\tthis help." + puts "\t-f --file\t\toutput file." + puts "\t-n --num\t\tcharset: 0123456789" + puts "\t-a --alpha\t\tcharset: abcdefghijklmnopqrstuvwxyz" + puts "\t-A --alphamaj\t\tcharset: ABCDEFGHIJKLMNOPQRSTUVWXYZ" + puts "\t-l --alphanum\t\tcharset: alpha + num" + puts "\t-l --alphanummaj\tcharset: alpha + alphamaj + num" + puts "\t-s --all\t\tcharset: alpha + alphamaj + num + !@#$+=.*" + puts "\t-c --custom" + puts "\nExample:\n" + puts "#{$0} -f stats -s" + puts "#{$0} -f stats -c \"0123abc+=\"" + exit +end + +ch_alpha = 'abcdefghijklmnopqrstuvwxyz' +ch_num = '0123456789' +ch_sp = '!@#$+=.*' + +opts = GetoptLong.new( + [ '--help', '-h', GetoptLong::NO_ARGUMENT ], + [ '--file', '-f', GetoptLong::OPTIONAL_ARGUMENT], + [ '--all', '-s', GetoptLong::NO_ARGUMENT], + [ '--num', '-n', GetoptLong::NO_ARGUMENT], + [ '--alpha', '-a', GetoptLong::NO_ARGUMENT ], + [ '--alphamaj', '-A', GetoptLong::NO_ARGUMENT ], + [ '--alphanum', '-l', GetoptLong::NO_ARGUMENT ], + [ '--alphanummaj', '-L', GetoptLong::NO_ARGUMENT ], + [ '--custom', '-c', GetoptLong::OPTIONAL_ARGUMENT ] +) + +charset = nil +filename = "stats_out" + +opts.each do |opt, arg| + case opt + when '--help' + help + when '--file' + filename = arg + when '--num' + charset = ch_num + when '--alpha' + charset = ch_alpha + when '--alphamaj' + charset = ch_alpha.capitalize + when '--alphanum' + charset = ch_alpha + ch_num + when '--alphanummaj' + charset = ch_alpha.capitalize + ch_num + when '--all' + charset = ch_alpha + ch_alpha.capitalize + ch_num + ch_sp + when '--custom' + charset = arg + end +end + + +if charset == nil + help +end + + +fstat = File.open(filename, "w") +charset.each_byte do |c| + fstat.write("1=proba1[#{c.to_s}]\n") + charset.each_byte do |tmp| + fstat.write("1=proba2[#{c.to_s}*256+#{tmp.to_s}]\n") + end +end +fstat.close + diff -urpN john-1.7.3.4.orig/run/john.conf john-1.7.3.4/run/john.conf --- john-1.7.3.4.orig/run/john.conf 2009-09-09 05:02:46 +0000 +++ john-1.7.3.4/run/john.conf 2009-09-20 21:31:06 +0000 @@ -6,6 +6,10 @@ [Options] # Wordlist file name, to be used in batch mode Wordlist = $JOHN/password.lst +# Default Markov mode settings +Statsfile = $JOHN/stats +MkvLvl = 200 +MkvMaxLen = 12 # Use idle cycles only Idle = N # Crash recovery file saving delay in seconds diff -urpN john-1.7.3.4.orig/run/netntlm.pl john-1.7.3.4/run/netntlm.pl --- john-1.7.3.4.orig/run/netntlm.pl 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/run/netntlm.pl 2010-02-14 03:18:15 +0000 @@ -0,0 +1,209 @@ +#!/usr/bin/perl +# +##################################################################### +# JoMo-Kun +# +# Crack LM/NTLM response using LM password case-insensitive seed. +# +# Fix character case for cracked LM responses using respective +# NTLM response. +# +##################################################################### +# + +use Getopt::Long; + +my $VERSION = "0.1"; +my %opt; +my %data; + +$potfile = 'john.pot'; +$JOHN = 'john'; + +GetOptions ( + 'seed=s' => \$opt{'seed'}, + 'file=s' => \$opt{'file'}, + 'help|h' => sub { ShowUsage(); }, +); + +sub showUsage { + print "john-netntlm.pl V. $VERSION\n"; + print "JoMo-Kun \n\n"; + print "Usage: $0 [OPTIONS]\n"; + print " $0\n"; + print " --seed [RainbowCrack/HalfLM Response Password]\n"; + print " --file [File Containing LM/NTLM challenge/responses (.lc format)]\n"; + print " Ex: Domain\\User:::LM response:NTLM response:challenge"; + print "\n"; + print " Ex:\n"; + print " $0 --file capture.lc\n"; + print " $0 --seed \"GERGE!!\"--file capture.lc\n"; + print "\n"; + exit(1); +} + +# MAIN +{ + if ( !defined($opt{'file'}) ) { &showUsage; } + + # Parse accounts to audit + open(HAND, $opt{'file'}) || die("Failed to open response file: $opt{'file'} -- $!"); + @{ $data{'pairs'} } = ; + close(HAND); + + # Load information for any accounts previous cracked + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + + open (HAND, "$JOHN -format:netlm -show $opt{'file'} |") || die("Failed to execute john: $!"); + print STDERR "The following LM responses have been previously cracked:\n"; + while() { + next if ( /\d+ password hashes cracked, \d+ left/ ); + last if /^$/; + print "\t$_"; + push @{ $data{'cracked-lm'} }, $_; + } + close(HAND); + + print STDERR "\nThe following NTLM responses have been previously cracked:\n"; + open (HAND, "$JOHN -format:netntlm -show $opt{'file'} |") || die("Failed to execute john: $!"); + while() { + next if ( /\d+ password hashes cracked, \d+ left/ ); + last if /^$/; + print "\t$_"; + push @{ $data{'cracked-ntlm'} }, $_; + } + close(HAND); + + my $tmpconf = &createConf(); + my $tmpsession = "/tmp/john.session.$$"; + my $tmpsessionlog = "/tmp/john.session.log"; # should we unlink this when done? + #print STDERR "Created temporary configuration file: $tmpconf\n"; + + # Crack case-sensitive version of password + my $tmpdict = "/tmp/john.dict.$$"; + #print STDERR "Created temporary dictionary file: $tmpdict\n"; + + foreach $credential_set ( @{ $data{'cracked-lm'} } ) { + my ($account,$lmpass,$bar,$netlm,$netntlm,$chall) = split(/:/, $credential_set); + next if ( grep(/^$account:/i, @{ $data{'cracked-ntlm'} }) ); + + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + print STDERR "Performing NTLM case-sensitive crack for account: $account.\n"; + + open(HAND, ">$tmpdict") || die("Failed to option file: $tmpdict -- $!"); + print HAND "$lmpass"; + close(HAND); + + open (HAND, "$JOHN -format:netntlm -config:$tmpconf -wordlist:$tmpdict -rules -user:\"$account\" -session:$tmpsession $opt{'file'} |") || die("Failed to execute john: $!"); + while() { print; } + close(HAND); + unlink $tmpdict; + } + + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + print STDERR "Isolating accounts which have only had their LM response cracked.\n"; + + foreach $credential_set ( @{ $data{'pairs'} } ) { + $credential_set =~ s/\\/\\\\/g; + my ($account,$foo,$bar,$netlm,$netntlm,$chall) = split(/:/, $credential_set); + if (lc($netlm) eq lc($netntlm)) { + print STDERR "LM response is not unique from NTLM response (skipping):\n\t$credential_set\n"; + push @{ $data{'pairs-ntlm'} }, $credential_set; + } + elsif ( @cracked = grep(/^$account:/i, @{ $data{'cracked-ntlm'} }) ) { + print STDERR "Account $account NTLM response previously cracked.\n"; + #print "@cracked"; + } + else { + print STDERR "Account $account LM response added to cracking list.\n"; + push @{ $data{'pairs-lm'} }, $credential_set; + } + } + + if ( defined($opt{'seed'}) ) { + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + print STDERR "Testing seed password to determine whether it is the actual password.\n"; + open(HAND, ">$tmpdict") || die("Failed to option file: $tmpdict -- $!"); + print HAND $opt{'seed'}; + close(HAND); + + open (HAND, "$JOHN -format:netntlm -config:$tmpconf -wordlist:$tmpdict -rules -session:$tmpsession $opt{'file'} |") || die("Failed to execute john: $!"); + while() { print; } + close(HAND); + unlink $tmpdict; + + my $tmppasswd = "/tmp/john.passwd.$$"; + open(HAND, ">$tmppasswd") || die("Failed to open $tmppasswd: $!"); + print HAND @{ $data{'pairs-lm'} }; + close(HAND); + + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + print STDERR "The hashes contained within $tmppasswd have not been cracked.\n"; + print STDERR "Executing the following (this could take a while...):\n\n"; + print STDERR "john -format:netlm -config:$tmpconf -external:HalfLM -incremental:LM -session:$tmpsession $tmppasswd\n"; + print STDERR "\n"; + print STDERR " *If the passwords successfully crack, use this script again to crack the case-sensitive password\n"; + print STDERR " without feeding a seed password\n"; + print STDERR"\n\n"; + + exec("$JOHN -format:netlm -config:$tmpconf -external:HalfLM -incremental:LM -session:$tmpsession $tmppasswd"); + } + + unlink $tmppasswd, $tmpconf, $tmpsession; +} + +exit(0); + +sub createConf { + my $tmpconf = "/tmp/john.conf.$$"; + open(CONF, ">$tmpconf") || die("Failed to open $tmpconf: $!"); + + # Define character keyspace + print CONF "[Incremental:LM]\n"; + print CONF "File = /usr/share/john/lanman.chr\n"; + print CONF "MinLen = 1\n"; + + # John compiled for MaxLen <= 8 + if (14 - length($opt{'seed'}) > 8) { + print CONF "MaxLen = 8\n"; + } else { + print CONF "MaxLen = ", 14 - length($opt{'seed'}), "\n"; + } + print CONF "CharCount = 69\n\n"; + + # Add external filter to handle uncracked characters + if ($opt{'seed'} ne "") { + my $i; $j; + my @seed = split(//, $opt{'seed'}); + + print CONF "[List.External:HalfLM]\n"; + print CONF "void filter()\n"; + print CONF "{\n"; + + my $len = length($opt{'seed'}); + for ($i = 13, $j = 13 - $len; $i>=0; $i--) { + if ($i >= $len) { + print CONF " word[$i] = word[$j];\n"; + $j--; + } else { + print CONF " word[$i] = \'$seed[$i]\';\n"; + } + } + + print CONF "}\n\n"; + } + + # Add custom wordlist to utilize NTLM hash for character case cracking + print CONF "[List.Rules:Wordlist]\n"; + print CONF "l\n"; + print CONF "lMT[*0]T[*1]T[*2]T[*3]T[*4]T[*5]T[*6]T[*7]T[*8]T[*9]T[*A]T[*B]T[*C]T[*D]Q\n"; + + close(CONF); + + return $tmpconf; +} diff -urpN john-1.7.3.4.orig/run/netscreen.py john-1.7.3.4/run/netscreen.py --- john-1.7.3.4.orig/run/netscreen.py 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/run/netscreen.py 2008-08-24 10:05:00 +0000 @@ -0,0 +1,37 @@ +# netscreen.py +# Generate passwords in netscreen format. +# + +import md5 +import sys + +def net(user, password): + b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" + middle = "Administration Tools" + s = "%s:%s:%s" % (user, middle, password) + m = md5.new(s).digest() + + narray = [] + for i in range(8): + n1 = ord(m[2*i]) + n2 = ord(m[2*i+1]) + narray.append( (n1<<8 & 0xff00) | (n2 & 0xff) ) + + res = "" + for i in narray: + p1 = i >> 12 & 0xf + p2 = i >> 6 & 0x3f + p3 = i & 0x3f + res = res + b64[p1] + b64[p2] + b64[p3] + + for c, n in zip("nrcstn", [0, 6, 12, 17, 23, 29]): + res = res[:n] + c + res[n:] + return res + + +if __name__ == '__main__': + user = sys.argv[1] + password = sys.argv[2] + + ciphertext = net(user,password) + print "%s:%s$%s" % (user,user,ciphertext) diff -urpN john-1.7.3.4.orig/run/sap_prepare.pl john-1.7.3.4/run/sap_prepare.pl --- john-1.7.3.4.orig/run/sap_prepare.pl 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/run/sap_prepare.pl 2008-08-24 06:26:35 +0000 @@ -0,0 +1,89 @@ +#!/usr/bin/perl -w +# Usage: sap_prepare.pl csv-input sap-codeB-output sap-codevnG-output +# csv-input: XLS-exported table USH02 or USR02 +# tab-speparted e.g. column 4:username column 17:bcode column 24:codvn G +# sap-codeB-output: username:username$bcode +# sap-codevnG-output: username:Username$codvnG +# +# (all other formats with the right column names should work) +# sap uses the username as salt. those have different length, so we needed to come up w/ our +# own format. that is: username$HASHCODE +# +# evil spaghetti code, but works. sorry for the eye cancer ;-) + +$SALT_LENGTH = 40; + +if ($#ARGV != 2) { + die ("usage = $0 csv-input sap-codeB-output sap-codevnG-output \n"); +} + +open INPUT_FILE, "$ARGV[0]" or die ("Can't open input-file ($ARGV[0])\n"); +open CODEB_FILE,">>$ARGV[1]" or die ("Can't open codeb-file ($ARGV[1])\n"); +open CODEG_FILE,">>$ARGV[2]" or die ("Can't open codeg-file ($ARGV[2])\n"); + +print "data from >>$ARGV[0]<<\nto sap-codeB-output: >>$ARGV[1]<<\n"; +print "and sap-codevnG-output: >>$ARGV[2]<<\n\n"; + +$line = ""; +$pos_bname=-1; +$pos_codeb=-1; +$pos_codeg=-1; +$count=0; + +until ($line =~ /BNAME/) { + $line=; + $count++; +} + +chomp($line); +@tmp = split(/\t/, $line); + +for ($i=0;$i<=$#tmp;$i++) { + if ($tmp[$i]=~ /BNAME/) { $pos_bname=$i } + elsif ($tmp[$i]=~ /BCODE/) { $pos_codeb=$i } + elsif ($tmp[$i]=~ /PASSCODE/) { $pos_codeg=$i } +} +print "Column: $#tmp BNAME: $pos_bname BCODE: $pos_codeb PASSCODE: $pos_codeg\n"; + +if (-1==$pos_bname || (-1==$pos_codeg && -1==$pos_codeb ) ) { + print "BNAME column not found OR both hash-columns are missing \n"; + exit 0; +} + +while ($line=) { + $count++; + chomp($line); + @tmp = split(/\t/, $line); + if ($#tmp<$pos_bname || ($#tmp<$pos_codeb && $#tmp<$pos_codeg)) { + print "******** line $count in csv file has the wrong format ********\n"; + next; + } + if ($pos_codeg!=-1 && $tmp[$pos_codeg]=~/[a-zA-Z0-9]/) { # both hashes + print "username: $tmp[$pos_bname] codeB: $tmp[$pos_codeb] codeG: $tmp[$pos_codeg] \n"; + $strN = $tmp[$pos_bname]; + $strSALT = "$strN"." "x($SALT_LENGTH-length($tmp[$pos_bname])); + $strB = "$tmp[$pos_codeb]"; + $strG = "$tmp[$pos_codeg]"; + print CODEB_FILE "$strN:$strSALT\$$strB\n"; + print CODEG_FILE "$strN:$strSALT\$$strG\n"; + } + elsif ($pos_codeb!=-1 && $tmp[$pos_codeb]=~/[a-zA-Z0-9]/ ) { # only bcode + print "username: $tmp[$pos_bname] codeB: $tmp[$pos_codeb] \n"; + $strN = $tmp[$pos_bname]; + $strSALT = "$strN"." "x($SALT_LENGTH-length($tmp[$pos_bname])); + $strB = "$tmp[$pos_codeb]"; + print CODEB_FILE "$strN:$strSALT\$$strB\n"; + } + else { + print "******** line $count in csv file has the wrong format ********\n"; + } +} + +close INPUT_FILE; +close CODEB_FILE; +close CODEG_FILE; + +print "\nDone!\n"; +exit 0; + + diff -urpN john-1.7.3.4.orig/run/stats john-1.7.3.4/run/stats --- john-1.7.3.4.orig/run/stats 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/run/stats 2007-11-02 11:37:50 +0000 @@ -0,0 +1,4986 @@ +97=proba1[32] +51=proba2[32*256+35] +44=proba2[32*256+38] +51=proba2[32*256+39] +40=proba2[32*256+48] +35=proba2[32*256+49] +37=proba2[32*256+50] +51=proba2[32*256+51] +44=proba2[32*256+52] +44=proba2[32*256+53] +33=proba2[32*256+54] +44=proba2[32*256+55] +44=proba2[32*256+56] +44=proba2[32*256+57] +44=proba2[32*256+66] +44=proba2[32*256+67] +51=proba2[32*256+68] +44=proba2[32*256+69] +40=proba2[32*256+71] +51=proba2[32*256+73] +44=proba2[32*256+77] +44=proba2[32*256+78] +40=proba2[32*256+80] +51=proba2[32*256+82] +44=proba2[32*256+84] +51=proba2[32*256+86] +51=proba2[32*256+87] +33=proba2[32*256+97] +33=proba2[32*256+98] +25=proba2[32*256+99] +32=proba2[32*256+100] +37=proba2[32*256+101] +44=proba2[32*256+102] +37=proba2[32*256+103] +37=proba2[32*256+104] +40=proba2[32*256+105] +40=proba2[32*256+106] +51=proba2[32*256+107] +32=proba2[32*256+108] +24=proba2[32*256+109] +37=proba2[32*256+110] +37=proba2[32*256+111] +27=proba2[32*256+112] +51=proba2[32*256+113] +35=proba2[32*256+114] +32=proba2[32*256+115] +33=proba2[32*256+116] +40=proba2[32*256+117] +51=proba2[32*256+118] +44=proba2[32*256+121] +51=proba2[32*256+122] +80=proba1[33] +15=proba2[33*256+33] +51=proba2[33*256+34] +51=proba2[33*256+35] +51=proba2[33*256+40] +51=proba2[33*256+41] +51=proba2[33*256+42] +51=proba2[33*256+43] +51=proba2[33*256+48] +31=proba2[33*256+49] +37=proba2[33*256+50] +37=proba2[33*256+51] +51=proba2[33*256+52] +51=proba2[33*256+54] +35=proba2[33*256+55] +51=proba2[33*256+56] +44=proba2[33*256+57] +51=proba2[33*256+59] +51=proba2[33*256+61] +37=proba2[33*256+63] +51=proba2[33*256+64] +40=proba2[33*256+70] +51=proba2[33*256+71] +51=proba2[33*256+76] +37=proba2[33*256+78] +51=proba2[33*256+80] +51=proba2[33*256+83] +51=proba2[33*256+84] +51=proba2[33*256+87] +51=proba2[33*256+95] +40=proba2[33*256+97] +37=proba2[33*256+98] +37=proba2[33*256+99] +44=proba2[33*256+100] +37=proba2[33*256+101] +40=proba2[33*256+102] +40=proba2[33*256+103] +44=proba2[33*256+105] +44=proba2[33*256+106] +51=proba2[33*256+107] +33=proba2[33*256+108] +37=proba2[33*256+109] +35=proba2[33*256+110] +35=proba2[33*256+111] +37=proba2[33*256+112] +51=proba2[33*256+113] +31=proba2[33*256+114] +31=proba2[33*256+115] +31=proba2[33*256+116] +51=proba2[33*256+119] +51=proba2[33*256+120] +51=proba2[33*256+121] +44=proba2[33*256+122] +118=proba1[34] +17=proba2[34*256+38] +23=proba2[34*256+39] +23=proba2[34*256+40] +23=proba2[34*256+48] +23=proba2[34*256+54] +23=proba2[34*256+97] +23=proba2[34*256+99] +23=proba2[34*256+100] +23=proba2[34*256+101] +23=proba2[34*256+119] +86=proba1[35] +42=proba2[35*256+33] +26=proba2[35*256+35] +42=proba2[35*256+36] +35=proba2[35*256+38] +42=proba2[35*256+48] +24=proba2[35*256+49] +35=proba2[35*256+50] +26=proba2[35*256+51] +42=proba2[35*256+52] +42=proba2[35*256+53] +35=proba2[35*256+54] +35=proba2[35*256+55] +24=proba2[35*256+57] +42=proba2[35*256+63] +35=proba2[35*256+65] +42=proba2[35*256+83] +42=proba2[35*256+87] +28=proba2[35*256+97] +35=proba2[35*256+98] +42=proba2[35*256+99] +42=proba2[35*256+100] +42=proba2[35*256+102] +35=proba2[35*256+105] +35=proba2[35*256+106] +31=proba2[35*256+109] +31=proba2[35*256+110] +42=proba2[35*256+111] +42=proba2[35*256+112] +31=proba2[35*256+114] +42=proba2[35*256+115] +42=proba2[35*256+116] +42=proba2[35*256+118] +42=proba2[35*256+119] +42=proba2[35*256+121] +42=proba2[35*256+123] +82=proba1[36] +45=proba2[36*256+33] +45=proba2[36*256+35] +26=proba2[36*256+36] +45=proba2[36*256+37] +45=proba2[36*256+41] +34=proba2[36*256+42] +45=proba2[36*256+43] +39=proba2[36*256+48] +39=proba2[36*256+49] +34=proba2[36*256+50] +39=proba2[36*256+54] +45=proba2[36*256+55] +34=proba2[36*256+56] +34=proba2[36*256+57] +45=proba2[36*256+61] +45=proba2[36*256+65] +45=proba2[36*256+66] +45=proba2[36*256+67] +45=proba2[36*256+69] +45=proba2[36*256+84] +45=proba2[36*256+90] +45=proba2[36*256+94] +34=proba2[36*256+97] +39=proba2[36*256+98] +45=proba2[36*256+99] +32=proba2[36*256+100] +34=proba2[36*256+101] +32=proba2[36*256+102] +39=proba2[36*256+103] +39=proba2[36*256+104] +39=proba2[36*256+106] +39=proba2[36*256+107] +32=proba2[36*256+108] +29=proba2[36*256+109] +39=proba2[36*256+110] +45=proba2[36*256+111] +29=proba2[36*256+112] +45=proba2[36*256+114] +32=proba2[36*256+115] +29=proba2[36*256+116] +45=proba2[36*256+117] +39=proba2[36*256+118] +45=proba2[36*256+119] +45=proba2[36*256+120] +45=proba2[36*256+121] +39=proba2[36*256+122] +97=proba1[37] +32=proba2[37*256+35] +25=proba2[37*256+36] +32=proba2[37*256+38] +32=proba2[37*256+42] +32=proba2[37*256+43] +32=proba2[37*256+44] +32=proba2[37*256+49] +32=proba2[37*256+52] +32=proba2[37*256+71] +32=proba2[37*256+78] +18=proba2[37*256+97] +32=proba2[37*256+98] +32=proba2[37*256+99] +32=proba2[37*256+100] +32=proba2[37*256+109] +32=proba2[37*256+112] +18=proba2[37*256+115] +32=proba2[37*256+117] +86=proba1[38] +47=proba2[38*256+32] +47=proba2[38*256+34] +33=proba2[38*256+38] +40=proba2[38*256+39] +47=proba2[38*256+40] +40=proba2[38*256+43] +47=proba2[38*256+44] +40=proba2[38*256+45] +36=proba2[38*256+49] +47=proba2[38*256+50] +47=proba2[38*256+51] +47=proba2[38*256+52] +47=proba2[38*256+54] +40=proba2[38*256+55] +40=proba2[38*256+57] +47=proba2[38*256+66] +47=proba2[38*256+67] +47=proba2[38*256+69] +40=proba2[38*256+70] +47=proba2[38*256+71] +36=proba2[38*256+74] +47=proba2[38*256+77] +40=proba2[38*256+83] +40=proba2[38*256+87] +47=proba2[38*256+89] +29=proba2[38*256+97] +36=proba2[38*256+98] +22=proba2[38*256+99] +36=proba2[38*256+100] +31=proba2[38*256+101] +40=proba2[38*256+102] +36=proba2[38*256+103] +47=proba2[38*256+105] +40=proba2[38*256+106] +40=proba2[38*256+107] +29=proba2[38*256+108] +29=proba2[38*256+109] +36=proba2[38*256+110] +33=proba2[38*256+111] +36=proba2[38*256+112] +31=proba2[38*256+114] +36=proba2[38*256+115] +47=proba2[38*256+116] +47=proba2[38*256+117] +40=proba2[38*256+118] +40=proba2[38*256+119] +47=proba2[38*256+121] +47=proba2[38*256+122] +47=proba2[38*256+123] +118=proba1[39] +30=proba2[39*256+38] +30=proba2[39*256+39] +37=proba2[39*256+40] +37=proba2[39*256+44] +37=proba2[39*256+51] +37=proba2[39*256+52] +37=proba2[39*256+57] +30=proba2[39*256+83] +37=proba2[39*256+95] +18=proba2[39*256+97] +30=proba2[39*256+98] +26=proba2[39*256+99] +23=proba2[39*256+101] +37=proba2[39*256+103] +30=proba2[39*256+111] +26=proba2[39*256+114] +17=proba2[39*256+115] +37=proba2[39*256+119] +37=proba2[39*256+122] +91=proba1[40] +36=proba2[40*256+36] +36=proba2[40*256+37] +36=proba2[40*256+40] +25=proba2[40*256+41] +29=proba2[40*256+42] +22=proba2[40*256+45] +36=proba2[40*256+49] +36=proba2[40*256+54] +36=proba2[40*256+69] +36=proba2[40*256+94] +29=proba2[40*256+95] +29=proba2[40*256+97] +36=proba2[40*256+99] +36=proba2[40*256+100] +29=proba2[40*256+103] +29=proba2[40*256+105] +29=proba2[40*256+110] +36=proba2[40*256+112] +36=proba2[40*256+114] +29=proba2[40*256+115] +29=proba2[40*256+116] +36=proba2[40*256+118] +36=proba2[40*256+121] +36=proba2[40*256+124] +118=proba1[41] +13=proba2[41*256+40] +27=proba2[41*256+41] +27=proba2[41*256+54] +27=proba2[41*256+61] +27=proba2[41*256+103] +27=proba2[41*256+107] +27=proba2[41*256+108] +20=proba2[41*256+111] +20=proba2[41*256+112] +27=proba2[41*256+114] +78=proba1[42] +44=proba2[42*256+36] +44=proba2[42*256+38] +51=proba2[42*256+40] +51=proba2[42*256+41] +15=proba2[42*256+42] +51=proba2[42*256+44] +44=proba2[42*256+45] +44=proba2[42*256+46] +44=proba2[42*256+48] +33=proba2[42*256+49] +40=proba2[42*256+50] +34=proba2[42*256+51] +40=proba2[42*256+52] +37=proba2[42*256+54] +37=proba2[42*256+55] +51=proba2[42*256+56] +34=proba2[42*256+57] +51=proba2[42*256+59] +51=proba2[42*256+61] +51=proba2[42*256+63] +51=proba2[42*256+64] +51=proba2[42*256+65] +44=proba2[42*256+66] +51=proba2[42*256+67] +44=proba2[42*256+68] +51=proba2[42*256+69] +51=proba2[42*256+73] +51=proba2[42*256+77] +51=proba2[42*256+78] +51=proba2[42*256+80] +51=proba2[42*256+82] +51=proba2[42*256+95] +28=proba2[42*256+97] +40=proba2[42*256+98] +31=proba2[42*256+99] +40=proba2[42*256+100] +51=proba2[42*256+101] +51=proba2[42*256+102] +37=proba2[42*256+103] +37=proba2[42*256+105] +44=proba2[42*256+106] +37=proba2[42*256+108] +33=proba2[42*256+109] +44=proba2[42*256+110] +51=proba2[42*256+111] +37=proba2[42*256+112] +44=proba2[42*256+113] +51=proba2[42*256+114] +33=proba2[42*256+115] +51=proba2[42*256+116] +51=proba2[42*256+117] +37=proba2[42*256+118] +51=proba2[42*256+119] +51=proba2[42*256+120] +51=proba2[42*256+122] +96=proba1[43] +38=proba2[43*256+38] +19=proba2[43*256+43] +31=proba2[43*256+45] +29=proba2[43*256+49] +38=proba2[43*256+50] +45=proba2[43*256+51] +45=proba2[43*256+52] +31=proba2[43*256+53] +29=proba2[43*256+54] +34=proba2[43*256+55] +38=proba2[43*256+61] +45=proba2[43*256+66] +38=proba2[43*256+67] +45=proba2[43*256+72] +38=proba2[43*256+74] +38=proba2[43*256+75] +45=proba2[43*256+76] +45=proba2[43*256+80] +45=proba2[43*256+85] +45=proba2[43*256+89] +38=proba2[43*256+97] +29=proba2[43*256+98] +38=proba2[43*256+99] +45=proba2[43*256+101] +38=proba2[43*256+102] +45=proba2[43*256+103] +45=proba2[43*256+104] +45=proba2[43*256+105] +45=proba2[43*256+106] +45=proba2[43*256+107] +29=proba2[43*256+108] +38=proba2[43*256+109] +45=proba2[43*256+110] +38=proba2[43*256+111] +45=proba2[43*256+112] +38=proba2[43*256+113] +45=proba2[43*256+115] +31=proba2[43*256+116] +38=proba2[43*256+119] +38=proba2[43*256+120] +96=proba1[44] +24=proba2[44*256+44] +28=proba2[44*256+46] +44=proba2[44*256+48] +28=proba2[44*256+49] +33=proba2[44*256+50] +37=proba2[44*256+51] +33=proba2[44*256+55] +33=proba2[44*256+56] +37=proba2[44*256+57] +28=proba2[44*256+59] +37=proba2[44*256+65] +44=proba2[44*256+66] +44=proba2[44*256+73] +44=proba2[44*256+83] +44=proba2[44*256+84] +44=proba2[44*256+86] +37=proba2[44*256+97] +44=proba2[44*256+98] +37=proba2[44*256+99] +33=proba2[44*256+100] +37=proba2[44*256+102] +44=proba2[44*256+103] +44=proba2[44*256+105] +37=proba2[44*256+106] +44=proba2[44*256+107] +23=proba2[44*256+109] +37=proba2[44*256+110] +30=proba2[44*256+112] +37=proba2[44*256+115] +26=proba2[44*256+116] +37=proba2[44*256+118] +44=proba2[44*256+121] +44=proba2[44*256+122] +91=proba1[45] +57=proba2[45*256+34] +57=proba2[45*256+36] +43=proba2[45*256+38] +57=proba2[45*256+39] +57=proba2[45*256+40] +43=proba2[45*256+43] +27=proba2[45*256+45] +33=proba2[45*256+48] +23=proba2[45*256+49] +32=proba2[45*256+50] +43=proba2[45*256+51] +43=proba2[45*256+52] +46=proba2[45*256+53] +33=proba2[45*256+54] +36=proba2[45*256+55] +36=proba2[45*256+56] +30=proba2[45*256+57] +57=proba2[45*256+63] +57=proba2[45*256+65] +50=proba2[45*256+66] +50=proba2[45*256+67] +50=proba2[45*256+68] +57=proba2[45*256+69] +50=proba2[45*256+70] +50=proba2[45*256+71] +57=proba2[45*256+73] +57=proba2[45*256+74] +57=proba2[45*256+75] +50=proba2[45*256+76] +57=proba2[45*256+77] +57=proba2[45*256+78] +57=proba2[45*256+80] +50=proba2[45*256+84] +57=proba2[45*256+87] +46=proba2[45*256+88] +57=proba2[45*256+97] +39=proba2[45*256+98] +33=proba2[45*256+99] +41=proba2[45*256+100] +50=proba2[45*256+101] +35=proba2[45*256+102] +36=proba2[45*256+103] +41=proba2[45*256+104] +39=proba2[45*256+105] +36=proba2[45*256+106] +50=proba2[45*256+107] +30=proba2[45*256+108] +35=proba2[45*256+109] +37=proba2[45*256+110] +43=proba2[45*256+111] +39=proba2[45*256+112] +35=proba2[45*256+114] +36=proba2[45*256+115] +32=proba2[45*256+116] +57=proba2[45*256+117] +46=proba2[45*256+118] +41=proba2[45*256+119] +50=proba2[45*256+120] +57=proba2[45*256+121] +57=proba2[45*256+122] +93=proba1[46] +54=proba2[46*256+32] +54=proba2[46*256+35] +54=proba2[46*256+43] +41=proba2[46*256+44] +23=proba2[46*256+46] +24=proba2[46*256+48] +27=proba2[46*256+49] +32=proba2[46*256+50] +34=proba2[46*256+51] +41=proba2[46*256+52] +35=proba2[46*256+53] +41=proba2[46*256+54] +36=proba2[46*256+55] +29=proba2[46*256+56] +38=proba2[46*256+57] +43=proba2[46*256+65] +47=proba2[46*256+70] +54=proba2[46*256+71] +47=proba2[46*256+73] +54=proba2[46*256+74] +47=proba2[46*256+78] +54=proba2[46*256+79] +54=proba2[46*256+83] +41=proba2[46*256+84] +54=proba2[46*256+85] +54=proba2[46*256+87] +38=proba2[46*256+97] +35=proba2[46*256+98] +36=proba2[46*256+99] +35=proba2[46*256+100] +41=proba2[46*256+101] +38=proba2[46*256+102] +43=proba2[46*256+103] +41=proba2[46*256+104] +54=proba2[46*256+105] +38=proba2[46*256+106] +54=proba2[46*256+107] +34=proba2[46*256+108] +38=proba2[46*256+109] +34=proba2[46*256+110] +47=proba2[46*256+111] +47=proba2[46*256+112] +54=proba2[46*256+113] +54=proba2[46*256+114] +30=proba2[46*256+115] +38=proba2[46*256+117] +47=proba2[46*256+118] +43=proba2[46*256+119] +47=proba2[46*256+120] +54=proba2[46*256+121] +47=proba2[46*256+122] +46=proba1[48] +94=proba2[48*256+32] +83=proba2[48*256+33] +94=proba2[48*256+35] +78=proba2[48*256+36] +87=proba2[48*256+37] +87=proba2[48*256+41] +94=proba2[48*256+42] +83=proba2[48*256+43] +76=proba2[48*256+45] +73=proba2[48*256+46] +14=proba2[48*256+48] +20=proba2[48*256+49] +26=proba2[48*256+50] +27=proba2[48*256+51] +27=proba2[48*256+52] +27=proba2[48*256+53] +27=proba2[48*256+54] +22=proba2[48*256+55] +27=proba2[48*256+56] +29=proba2[48*256+57] +87=proba2[48*256+59] +94=proba2[48*256+60] +94=proba2[48*256+64] +75=proba2[48*256+65] +78=proba2[48*256+66] +87=proba2[48*256+67] +94=proba2[48*256+69] +83=proba2[48*256+70] +87=proba2[48*256+71] +87=proba2[48*256+72] +87=proba2[48*256+73] +94=proba2[48*256+74] +80=proba2[48*256+75] +80=proba2[48*256+76] +72=proba2[48*256+77] +83=proba2[48*256+78] +94=proba2[48*256+79] +94=proba2[48*256+80] +83=proba2[48*256+82] +76=proba2[48*256+83] +87=proba2[48*256+84] +83=proba2[48*256+86] +94=proba2[48*256+88] +80=proba2[48*256+90] +94=proba2[48*256+95] +53=proba2[48*256+97] +56=proba2[48*256+98] +52=proba2[48*256+99] +56=proba2[48*256+100] +60=proba2[48*256+101] +59=proba2[48*256+102] +63=proba2[48*256+103] +67=proba2[48*256+104] +69=proba2[48*256+105] +63=proba2[48*256+106] +63=proba2[48*256+107] +54=proba2[48*256+108] +51=proba2[48*256+109] +55=proba2[48*256+110] +62=proba2[48*256+111] +58=proba2[48*256+112] +78=proba2[48*256+113] +56=proba2[48*256+114] +54=proba2[48*256+115] +56=proba2[48*256+116] +60=proba2[48*256+117] +64=proba2[48*256+118] +65=proba2[48*256+119] +65=proba2[48*256+120] +72=proba2[48*256+121] +66=proba2[48*256+122] +38=proba1[49] +75=proba2[49*256+33] +95=proba2[49*256+35] +88=proba2[49*256+36] +84=proba2[49*256+38] +95=proba2[49*256+41] +75=proba2[49*256+42] +82=proba2[49*256+43] +79=proba2[49*256+44] +73=proba2[49*256+45] +69=proba2[49*256+46] +21=proba2[49*256+48] +21=proba2[49*256+49] +17=proba2[49*256+50] +26=proba2[49*256+51] +28=proba2[49*256+52] +28=proba2[49*256+53] +30=proba2[49*256+54] +27=proba2[49*256+55] +29=proba2[49*256+56] +20=proba2[49*256+57] +88=proba2[49*256+59] +84=proba2[49*256+61] +84=proba2[49*256+64] +67=proba2[49*256+65] +76=proba2[49*256+66] +76=proba2[49*256+67] +76=proba2[49*256+68] +82=proba2[49*256+69] +84=proba2[49*256+70] +79=proba2[49*256+71] +88=proba2[49*256+72] +84=proba2[49*256+73] +88=proba2[49*256+74] +82=proba2[49*256+75] +75=proba2[49*256+76] +72=proba2[49*256+77] +76=proba2[49*256+78] +79=proba2[49*256+79] +82=proba2[49*256+80] +82=proba2[49*256+82] +79=proba2[49*256+83] +75=proba2[49*256+84] +95=proba2[49*256+85] +88=proba2[49*256+86] +88=proba2[49*256+87] +95=proba2[49*256+88] +95=proba2[49*256+89] +84=proba2[49*256+90] +46=proba2[49*256+97] +50=proba2[49*256+98] +52=proba2[49*256+99] +54=proba2[49*256+100] +54=proba2[49*256+101] +58=proba2[49*256+102] +56=proba2[49*256+103] +64=proba2[49*256+104] +59=proba2[49*256+105] +56=proba2[49*256+106] +63=proba2[49*256+107] +55=proba2[49*256+108] +51=proba2[49*256+109] +53=proba2[49*256+110] +59=proba2[49*256+111] +56=proba2[49*256+112] +63=proba2[49*256+113] +56=proba2[49*256+114] +51=proba2[49*256+115] +54=proba2[49*256+116] +67=proba2[49*256+117] +60=proba2[49*256+118] +63=proba2[49*256+119] +65=proba2[49*256+120] +70=proba2[49*256+121] +69=proba2[49*256+122] +42=proba1[50] +82=proba2[50*256+32] +69=proba2[50*256+33] +82=proba2[50*256+35] +86=proba2[50*256+36] +86=proba2[50*256+37] +86=proba2[50*256+39] +71=proba2[50*256+42] +82=proba2[50*256+43] +93=proba2[50*256+44] +71=proba2[50*256+45] +65=proba2[50*256+46] +20=proba2[50*256+48] +22=proba2[50*256+49] +23=proba2[50*256+50] +18=proba2[50*256+51] +26=proba2[50*256+52] +25=proba2[50*256+53] +28=proba2[50*256+54] +26=proba2[50*256+55] +28=proba2[50*256+56] +30=proba2[50*256+57] +86=proba2[50*256+59] +86=proba2[50*256+61] +86=proba2[50*256+63] +82=proba2[50*256+64] +69=proba2[50*256+65] +69=proba2[50*256+66] +65=proba2[50*256+67] +77=proba2[50*256+68] +86=proba2[50*256+69] +79=proba2[50*256+70] +73=proba2[50*256+71] +75=proba2[50*256+72] +86=proba2[50*256+73] +82=proba2[50*256+74] +79=proba2[50*256+75] +82=proba2[50*256+76] +72=proba2[50*256+77] +71=proba2[50*256+78] +93=proba2[50*256+79] +75=proba2[50*256+80] +86=proba2[50*256+81] +75=proba2[50*256+82] +79=proba2[50*256+83] +71=proba2[50*256+84] +86=proba2[50*256+85] +79=proba2[50*256+86] +93=proba2[50*256+87] +86=proba2[50*256+88] +75=proba2[50*256+89] +73=proba2[50*256+90] +93=proba2[50*256+91] +93=proba2[50*256+95] +46=proba2[50*256+97] +45=proba2[50*256+98] +46=proba2[50*256+99] +49=proba2[50*256+100] +53=proba2[50*256+101] +50=proba2[50*256+102] +56=proba2[50*256+103] +57=proba2[50*256+104] +56=proba2[50*256+105] +56=proba2[50*256+106] +59=proba2[50*256+107] +51=proba2[50*256+108] +46=proba2[50*256+109] +56=proba2[50*256+110] +59=proba2[50*256+111] +50=proba2[50*256+112] +61=proba2[50*256+113] +48=proba2[50*256+114] +49=proba2[50*256+115] +53=proba2[50*256+116] +60=proba2[50*256+117] +57=proba2[50*256+118] +55=proba2[50*256+119] +63=proba2[50*256+120] +59=proba2[50*256+121] +58=proba2[50*256+122] +52=proba1[51] +69=proba2[51*256+33] +88=proba2[51*256+34] +77=proba2[51*256+35] +88=proba2[51*256+36] +88=proba2[51*256+37] +82=proba2[51*256+38] +71=proba2[51*256+42] +82=proba2[51*256+43] +88=proba2[51*256+44] +68=proba2[51*256+45] +60=proba2[51*256+46] +21=proba2[51*256+48] +22=proba2[51*256+49] +24=proba2[51*256+50] +23=proba2[51*256+51] +20=proba2[51*256+52] +26=proba2[51*256+53] +28=proba2[51*256+54] +28=proba2[51*256+55] +29=proba2[51*256+56] +32=proba2[51*256+57] +88=proba2[51*256+59] +88=proba2[51*256+61] +88=proba2[51*256+62] +77=proba2[51*256+63] +82=proba2[51*256+64] +61=proba2[51*256+65] +64=proba2[51*256+66] +68=proba2[51*256+67] +68=proba2[51*256+68] +72=proba2[51*256+69] +71=proba2[51*256+70] +64=proba2[51*256+71] +88=proba2[51*256+72] +82=proba2[51*256+73] +77=proba2[51*256+74] +69=proba2[51*256+75] +71=proba2[51*256+76] +68=proba2[51*256+77] +77=proba2[51*256+78] +88=proba2[51*256+79] +72=proba2[51*256+80] +88=proba2[51*256+81] +66=proba2[51*256+82] +77=proba2[51*256+83] +71=proba2[51*256+84] +88=proba2[51*256+85] +75=proba2[51*256+86] +88=proba2[51*256+87] +77=proba2[51*256+88] +69=proba2[51*256+90] +77=proba2[51*256+95] +43=proba2[51*256+97] +48=proba2[51*256+98] +45=proba2[51*256+99] +42=proba2[51*256+100] +48=proba2[51*256+101] +52=proba2[51*256+102] +50=proba2[51*256+103] +54=proba2[51*256+104] +55=proba2[51*256+105] +51=proba2[51*256+106] +57=proba2[51*256+107] +51=proba2[51*256+108] +44=proba2[51*256+109] +53=proba2[51*256+110] +54=proba2[51*256+111] +48=proba2[51*256+112] +61=proba2[51*256+113] +47=proba2[51*256+114] +49=proba2[51*256+115] +52=proba2[51*256+116] +60=proba2[51*256+117] +53=proba2[51*256+118] +58=proba2[51*256+119] +61=proba2[51*256+120] +61=proba2[51*256+121] +54=proba2[51*256+122] +56=proba1[52] +80=proba2[52*256+32] +87=proba2[52*256+33] +87=proba2[52*256+35] +80=proba2[52*256+36] +73=proba2[52*256+37] +87=proba2[52*256+39] +87=proba2[52*256+40] +87=proba2[52*256+42] +68=proba2[52*256+43] +87=proba2[52*256+44] +76=proba2[52*256+45] +69=proba2[52*256+46] +22=proba2[52*256+48] +23=proba2[52*256+49] +25=proba2[52*256+50] +29=proba2[52*256+51] +24=proba2[52*256+52] +19=proba2[52*256+53] +27=proba2[52*256+54] +25=proba2[52*256+55] +28=proba2[52*256+56] +30=proba2[52*256+57] +80=proba2[52*256+59] +87=proba2[52*256+61] +87=proba2[52*256+64] +69=proba2[52*256+65] +80=proba2[52*256+66] +69=proba2[52*256+67] +80=proba2[52*256+68] +80=proba2[52*256+69] +73=proba2[52*256+70] +71=proba2[52*256+71] +80=proba2[52*256+72] +87=proba2[52*256+73] +73=proba2[52*256+74] +80=proba2[52*256+75] +76=proba2[52*256+76] +73=proba2[52*256+77] +76=proba2[52*256+78] +87=proba2[52*256+79] +66=proba2[52*256+80] +87=proba2[52*256+81] +68=proba2[52*256+82] +87=proba2[52*256+83] +73=proba2[52*256+84] +76=proba2[52*256+85] +80=proba2[52*256+86] +76=proba2[52*256+87] +87=proba2[52*256+88] +76=proba2[52*256+89] +76=proba2[52*256+90] +80=proba2[52*256+95] +42=proba2[52*256+97] +47=proba2[52*256+98] +50=proba2[52*256+99] +48=proba2[52*256+100] +46=proba2[52*256+101] +48=proba2[52*256+102] +50=proba2[52*256+103] +53=proba2[52*256+104] +54=proba2[52*256+105] +52=proba2[52*256+106] +57=proba2[52*256+107] +49=proba2[52*256+108] +43=proba2[52*256+109] +52=proba2[52*256+110] +62=proba2[52*256+111] +49=proba2[52*256+112] +60=proba2[52*256+113] +51=proba2[52*256+114] +47=proba2[52*256+115] +48=proba2[52*256+116] +51=proba2[52*256+117] +57=proba2[52*256+118] +57=proba2[52*256+119] +58=proba2[52*256+120] +54=proba2[52*256+121] +57=proba2[52*256+122] +57=proba1[53] +80=proba2[53*256+32] +80=proba2[53*256+33] +76=proba2[53*256+35] +76=proba2[53*256+36] +80=proba2[53*256+37] +87=proba2[53*256+38] +87=proba2[53*256+39] +69=proba2[53*256+43] +87=proba2[53*256+44] +71=proba2[53*256+45] +71=proba2[53*256+46] +21=proba2[53*256+48] +23=proba2[53*256+49] +26=proba2[53*256+50] +28=proba2[53*256+51] +26=proba2[53*256+52] +24=proba2[53*256+53] +19=proba2[53*256+54] +24=proba2[53*256+55] +27=proba2[53*256+56] +26=proba2[53*256+57] +87=proba2[53*256+59] +87=proba2[53*256+61] +80=proba2[53*256+63] +68=proba2[53*256+65] +68=proba2[53*256+66] +64=proba2[53*256+67] +87=proba2[53*256+68] +87=proba2[53*256+69] +67=proba2[53*256+70] +68=proba2[53*256+71] +80=proba2[53*256+72] +80=proba2[53*256+73] +73=proba2[53*256+74] +87=proba2[53*256+75] +73=proba2[53*256+76] +73=proba2[53*256+77] +80=proba2[53*256+78] +80=proba2[53*256+79] +68=proba2[53*256+80] +87=proba2[53*256+81] +73=proba2[53*256+82] +71=proba2[53*256+83] +71=proba2[53*256+84] +76=proba2[53*256+85] +87=proba2[53*256+86] +76=proba2[53*256+87] +87=proba2[53*256+88] +80=proba2[53*256+89] +87=proba2[53*256+90] +45=proba2[53*256+97] +48=proba2[53*256+98] +49=proba2[53*256+99] +52=proba2[53*256+100] +50=proba2[53*256+101] +50=proba2[53*256+102] +50=proba2[53*256+103] +58=proba2[53*256+104] +56=proba2[53*256+105] +56=proba2[53*256+106] +55=proba2[53*256+107] +52=proba2[53*256+108] +46=proba2[53*256+109] +54=proba2[53*256+110] +58=proba2[53*256+111] +49=proba2[53*256+112] +57=proba2[53*256+113] +51=proba2[53*256+114] +49=proba2[53*256+115] +51=proba2[53*256+116] +62=proba2[53*256+117] +58=proba2[53*256+118] +60=proba2[53*256+119] +62=proba2[53*256+120] +54=proba2[53*256+121] +57=proba2[53*256+122] +56=proba1[54] +75=proba2[54*256+32] +70=proba2[54*256+33] +81=proba2[54*256+36] +81=proba2[54*256+42] +81=proba2[54*256+43] +68=proba2[54*256+45] +70=proba2[54*256+46] +23=proba2[54*256+48] +26=proba2[54*256+49] +30=proba2[54*256+50] +29=proba2[54*256+51] +26=proba2[54*256+52] +27=proba2[54*256+53] +15=proba2[54*256+54] +24=proba2[54*256+55] +26=proba2[54*256+56] +22=proba2[54*256+57] +88=proba2[54*256+59] +81=proba2[54*256+61] +88=proba2[54*256+63] +88=proba2[54*256+64] +68=proba2[54*256+65] +61=proba2[54*256+66] +81=proba2[54*256+67] +77=proba2[54*256+68] +77=proba2[54*256+69] +75=proba2[54*256+70] +77=proba2[54*256+71] +77=proba2[54*256+72] +66=proba2[54*256+73] +88=proba2[54*256+74] +68=proba2[54*256+75] +88=proba2[54*256+76] +77=proba2[54*256+77] +88=proba2[54*256+78] +88=proba2[54*256+79] +75=proba2[54*256+80] +81=proba2[54*256+81] +75=proba2[54*256+82] +77=proba2[54*256+83] +88=proba2[54*256+84] +88=proba2[54*256+85] +77=proba2[54*256+86] +75=proba2[54*256+87] +88=proba2[54*256+88] +88=proba2[54*256+89] +88=proba2[54*256+90] +88=proba2[54*256+93] +88=proba2[54*256+94] +47=proba2[54*256+97] +49=proba2[54*256+98] +52=proba2[54*256+99] +51=proba2[54*256+100] +53=proba2[54*256+101] +53=proba2[54*256+102] +55=proba2[54*256+103] +58=proba2[54*256+104] +55=proba2[54*256+105] +54=proba2[54*256+106] +54=proba2[54*256+107] +53=proba2[54*256+108] +48=proba2[54*256+109] +53=proba2[54*256+110] +59=proba2[54*256+111] +50=proba2[54*256+112] +64=proba2[54*256+113] +53=proba2[54*256+114] +47=proba2[54*256+115] +54=proba2[54*256+116] +64=proba2[54*256+117] +57=proba2[54*256+118] +65=proba2[54*256+119] +61=proba2[54*256+120] +58=proba2[54*256+121] +61=proba2[54*256+122] +55=proba1[55] +82=proba2[55*256+32] +71=proba2[55*256+33] +78=proba2[55*256+35] +78=proba2[55*256+36] +82=proba2[55*256+38] +71=proba2[55*256+42] +82=proba2[55*256+43] +82=proba2[55*256+44] +67=proba2[55*256+45] +67=proba2[55*256+46] +23=proba2[55*256+48] +24=proba2[55*256+49] +26=proba2[55*256+50] +26=proba2[55*256+51] +24=proba2[55*256+52] +23=proba2[55*256+53] +25=proba2[55*256+54] +20=proba2[55*256+55] +23=proba2[55*256+56] +26=proba2[55*256+57] +78=proba2[55*256+59] +82=proba2[55*256+64] +71=proba2[55*256+65] +71=proba2[55*256+66] +73=proba2[55*256+67] +71=proba2[55*256+68] +75=proba2[55*256+69] +75=proba2[55*256+70] +89=proba2[55*256+71] +78=proba2[55*256+72] +75=proba2[55*256+73] +78=proba2[55*256+74] +78=proba2[55*256+75] +71=proba2[55*256+76] +71=proba2[55*256+77] +75=proba2[55*256+78] +82=proba2[55*256+79] +78=proba2[55*256+80] +89=proba2[55*256+81] +78=proba2[55*256+82] +78=proba2[55*256+83] +78=proba2[55*256+84] +89=proba2[55*256+85] +75=proba2[55*256+86] +75=proba2[55*256+87] +78=proba2[55*256+88] +82=proba2[55*256+89] +82=proba2[55*256+90] +48=proba2[55*256+97] +50=proba2[55*256+98] +51=proba2[55*256+99] +53=proba2[55*256+100] +54=proba2[55*256+101] +56=proba2[55*256+102] +52=proba2[55*256+103] +60=proba2[55*256+104] +55=proba2[55*256+105] +53=proba2[55*256+106] +56=proba2[55*256+107] +50=proba2[55*256+108] +49=proba2[55*256+109] +55=proba2[55*256+110] +61=proba2[55*256+111] +53=proba2[55*256+112] +67=proba2[55*256+113] +58=proba2[55*256+114] +52=proba2[55*256+115] +53=proba2[55*256+116] +56=proba2[55*256+117] +54=proba2[55*256+118] +63=proba2[55*256+119] +62=proba2[55*256+120] +61=proba2[55*256+121] +58=proba2[55*256+122] +89=proba2[55*256+124] +60=proba1[56] +86=proba2[56*256+32] +75=proba2[56*256+33] +75=proba2[56*256+36] +86=proba2[56*256+38] +86=proba2[56*256+41] +66=proba2[56*256+42] +86=proba2[56*256+44] +68=proba2[56*256+45] +66=proba2[56*256+46] +19=proba2[56*256+48] +21=proba2[56*256+49] +24=proba2[56*256+50] +25=proba2[56*256+51] +27=proba2[56*256+52] +27=proba2[56*256+53] +27=proba2[56*256+54] +25=proba2[56*256+55] +25=proba2[56*256+56] +27=proba2[56*256+57] +86=proba2[56*256+59] +86=proba2[56*256+61] +72=proba2[56*256+63] +79=proba2[56*256+65] +68=proba2[56*256+66] +75=proba2[56*256+67] +79=proba2[56*256+68] +79=proba2[56*256+69] +68=proba2[56*256+70] +75=proba2[56*256+71] +79=proba2[56*256+72] +70=proba2[56*256+74] +75=proba2[56*256+75] +70=proba2[56*256+76] +66=proba2[56*256+77] +79=proba2[56*256+78] +75=proba2[56*256+79] +72=proba2[56*256+80] +79=proba2[56*256+81] +79=proba2[56*256+82] +68=proba2[56*256+83] +72=proba2[56*256+84] +86=proba2[56*256+85] +86=proba2[56*256+86] +86=proba2[56*256+87] +79=proba2[56*256+88] +79=proba2[56*256+89] +72=proba2[56*256+90] +79=proba2[56*256+94] +46=proba2[56*256+97] +46=proba2[56*256+98] +47=proba2[56*256+99] +52=proba2[56*256+100] +49=proba2[56*256+101] +54=proba2[56*256+102] +49=proba2[56*256+103] +50=proba2[56*256+104] +55=proba2[56*256+105] +49=proba2[56*256+106] +51=proba2[56*256+107] +53=proba2[56*256+108] +46=proba2[56*256+109] +56=proba2[56*256+110] +60=proba2[56*256+111] +50=proba2[56*256+112] +60=proba2[56*256+113] +53=proba2[56*256+114] +45=proba2[56*256+115] +50=proba2[56*256+116] +58=proba2[56*256+117] +58=proba2[56*256+118] +59=proba2[56*256+119] +64=proba2[56*256+120] +57=proba2[56*256+121] +55=proba2[56*256+122] +59=proba1[57] +82=proba2[57*256+32] +73=proba2[57*256+33] +89=proba2[57*256+36] +89=proba2[57*256+38] +78=proba2[57*256+42] +78=proba2[57*256+43] +71=proba2[57*256+45] +68=proba2[57*256+46] +26=proba2[57*256+48] +27=proba2[57*256+49] +30=proba2[57*256+50] +30=proba2[57*256+51] +29=proba2[57*256+52] +27=proba2[57*256+53] +24=proba2[57*256+54] +20=proba2[57*256+55] +15=proba2[57*256+56] +21=proba2[57*256+57] +89=proba2[57*256+61] +89=proba2[57*256+62] +67=proba2[57*256+65] +78=proba2[57*256+66] +75=proba2[57*256+68] +75=proba2[57*256+69] +82=proba2[57*256+71] +82=proba2[57*256+72] +78=proba2[57*256+73] +78=proba2[57*256+74] +71=proba2[57*256+75] +75=proba2[57*256+76] +71=proba2[57*256+77] +78=proba2[57*256+78] +82=proba2[57*256+79] +75=proba2[57*256+80] +70=proba2[57*256+82] +71=proba2[57*256+83] +75=proba2[57*256+84] +89=proba2[57*256+85] +82=proba2[57*256+86] +89=proba2[57*256+87] +75=proba2[57*256+89] +78=proba2[57*256+90] +49=proba2[57*256+97] +54=proba2[57*256+98] +49=proba2[57*256+99] +57=proba2[57*256+100] +58=proba2[57*256+101] +55=proba2[57*256+102] +55=proba2[57*256+103] +57=proba2[57*256+104] +57=proba2[57*256+105] +57=proba2[57*256+106] +61=proba2[57*256+107] +53=proba2[57*256+108] +51=proba2[57*256+109] +57=proba2[57*256+110] +63=proba2[57*256+111] +55=proba2[57*256+112] +66=proba2[57*256+113] +55=proba2[57*256+114] +51=proba2[57*256+115] +55=proba2[57*256+116] +63=proba2[57*256+117] +59=proba2[57*256+118] +61=proba2[57*256+119] +60=proba2[57*256+120] +64=proba2[57*256+121] +65=proba2[57*256+122] +97=proba1[59] +40=proba2[59*256+39] +40=proba2[59*256+42] +33=proba2[59*256+48] +40=proba2[59*256+50] +40=proba2[59*256+51] +33=proba2[59*256+52] +40=proba2[59*256+55] +33=proba2[59*256+57] +18=proba2[59*256+59] +40=proba2[59*256+61] +40=proba2[59*256+76] +33=proba2[59*256+77] +40=proba2[59*256+78] +40=proba2[59*256+80] +40=proba2[59*256+84] +40=proba2[59*256+97] +33=proba2[59*256+98] +33=proba2[59*256+100] +29=proba2[59*256+101] +33=proba2[59*256+102] +33=proba2[59*256+103] +40=proba2[59*256+104] +40=proba2[59*256+105] +33=proba2[59*256+108] +33=proba2[59*256+109] +26=proba2[59*256+110] +40=proba2[59*256+111] +40=proba2[59*256+112] +40=proba2[59*256+113] +33=proba2[59*256+114] +29=proba2[59*256+115] +111=proba1[60] +19=proba2[60*256+35] +19=proba2[60*256+49] +12=proba2[60*256+50] +19=proba2[60*256+51] +12=proba2[60*256+62] +95=proba1[61] +43=proba2[61*256+37] +43=proba2[61*256+40] +43=proba2[61*256+41] +32=proba2[61*256+42] +43=proba2[61*256+44] +43=proba2[61*256+45] +37=proba2[61*256+49] +24=proba2[61*256+50] +32=proba2[61*256+51] +37=proba2[61*256+53] +37=proba2[61*256+55] +43=proba2[61*256+56] +43=proba2[61*256+57] +43=proba2[61*256+59] +15=proba2[61*256+61] +43=proba2[61*256+63] +43=proba2[61*256+71] +43=proba2[61*256+83] +43=proba2[61*256+90] +43=proba2[61*256+94] +37=proba2[61*256+97] +37=proba2[61*256+98] +43=proba2[61*256+100] +43=proba2[61*256+102] +37=proba2[61*256+103] +43=proba2[61*256+107] +37=proba2[61*256+108] +20=proba2[61*256+109] +43=proba2[61*256+110] +43=proba2[61*256+111] +43=proba2[61*256+112] +43=proba2[61*256+113] +43=proba2[61*256+115] +32=proba2[61*256+116] +43=proba2[61*256+117] +43=proba2[61*256+119] +13=proba2[62*256+65] +13=proba2[62*256+98] +13=proba2[62*256+108] +13=proba2[62*256+115] +97=proba1[63] +25=proba2[63*256+33] +36=proba2[63*256+43] +29=proba2[63*256+46] +36=proba2[63*256+50] +36=proba2[63*256+54] +22=proba2[63*256+63] +36=proba2[63*256+65] +36=proba2[63*256+69] +36=proba2[63*256+73] +36=proba2[63*256+78] +36=proba2[63*256+89] +36=proba2[63*256+91] +36=proba2[63*256+98] +29=proba2[63*256+99] +36=proba2[63*256+101] +36=proba2[63*256+109] +29=proba2[63*256+110] +36=proba2[63*256+111] +36=proba2[63*256+113] +29=proba2[63*256+114] +29=proba2[63*256+115] +36=proba2[63*256+116] +36=proba2[63*256+119] +22=proba2[63*256+122] +82=proba1[64] +48=proba2[64*256+33] +37=proba2[64*256+35] +48=proba2[64*256+36] +48=proba2[64*256+46] +37=proba2[64*256+48] +32=proba2[64*256+49] +41=proba2[64*256+50] +37=proba2[64*256+51] +37=proba2[64*256+52] +48=proba2[64*256+53] +41=proba2[64*256+54] +41=proba2[64*256+55] +41=proba2[64*256+57] +48=proba2[64*256+63] +23=proba2[64*256+64] +48=proba2[64*256+66] +48=proba2[64*256+82] +41=proba2[64*256+91] +48=proba2[64*256+98] +34=proba2[64*256+99] +32=proba2[64*256+100] +48=proba2[64*256+101] +37=proba2[64*256+102] +34=proba2[64*256+103] +48=proba2[64*256+104] +41=proba2[64*256+106] +48=proba2[64*256+107] +25=proba2[64*256+108] +18=proba2[64*256+109] +34=proba2[64*256+110] +27=proba2[64*256+114] +32=proba2[64*256+115] +27=proba2[64*256+116] +37=proba2[64*256+118] +41=proba2[64*256+119] +48=proba2[64*256+120] +48=proba2[64*256+122] +59=proba1[65] +72=proba2[65*256+33] +65=proba2[65*256+43] +65=proba2[65*256+44] +65=proba2[65*256+45] +72=proba2[65*256+46] +54=proba2[65*256+48] +36=proba2[65*256+49] +39=proba2[65*256+50] +48=proba2[65*256+51] +51=proba2[65*256+52] +45=proba2[65*256+53] +47=proba2[65*256+54] +54=proba2[65*256+55] +51=proba2[65*256+56] +45=proba2[65*256+57] +72=proba2[65*256+59] +40=proba2[65*256+65] +35=proba2[65*256+66] +33=proba2[65*256+67] +35=proba2[65*256+68] +47=proba2[65*256+69] +43=proba2[65*256+70] +42=proba2[65*256+71] +49=proba2[65*256+72] +33=proba2[65*256+73] +56=proba2[65*256+74] +43=proba2[65*256+75] +25=proba2[65*256+76] +29=proba2[65*256+77] +22=proba2[65*256+78] +50=proba2[65*256+79] +40=proba2[65*256+80] +56=proba2[65*256+81] +25=proba2[65*256+82] +28=proba2[65*256+83] +30=proba2[65*256+84] +35=proba2[65*256+85] +43=proba2[65*256+86] +50=proba2[65*256+87] +49=proba2[65*256+88] +44=proba2[65*256+89] +35=proba2[65*256+90] +58=proba2[65*256+97] +49=proba2[65*256+98] +53=proba2[65*256+99] +44=proba2[65*256+100] +65=proba2[65*256+101] +72=proba2[65*256+102] +56=proba2[65*256+103] +65=proba2[65*256+104] +58=proba2[65*256+105] +58=proba2[65*256+107] +37=proba2[65*256+108] +56=proba2[65*256+109] +37=proba2[65*256+110] +54=proba2[65*256+112] +65=proba2[65*256+113] +43=proba2[65*256+114] +46=proba2[65*256+115] +51=proba2[65*256+116] +51=proba2[65*256+117] +61=proba2[65*256+118] +61=proba2[65*256+119] +65=proba2[65*256+120] +56=proba2[65*256+121] +72=proba2[65*256+122] +63=proba1[66] +63=proba2[66*256+35] +49=proba2[66*256+45] +43=proba2[66*256+48] +34=proba2[66*256+49] +40=proba2[66*256+50] +43=proba2[66*256+51] +41=proba2[66*256+52] +47=proba2[66*256+53] +39=proba2[66*256+54] +49=proba2[66*256+55] +41=proba2[66*256+56] +41=proba2[66*256+57] +63=proba2[66*256+64] +25=proba2[66*256+65] +38=proba2[66*256+66] +36=proba2[66*256+67] +33=proba2[66*256+68] +25=proba2[66*256+69] +49=proba2[66*256+70] +39=proba2[66*256+71] +63=proba2[66*256+72] +30=proba2[66*256+73] +47=proba2[66*256+74] +52=proba2[66*256+75] +35=proba2[66*256+76] +41=proba2[66*256+77] +43=proba2[66*256+78] +25=proba2[66*256+79] +63=proba2[66*256+80] +63=proba2[66*256+81] +34=proba2[66*256+82] +45=proba2[66*256+83] +52=proba2[66*256+84] +39=proba2[66*256+85] +47=proba2[66*256+86] +56=proba2[66*256+87] +56=proba2[66*256+88] +49=proba2[66*256+89] +43=proba2[66*256+90] +29=proba2[66*256+97] +63=proba2[66*256+98] +63=proba2[66*256+99] +35=proba2[66*256+101] +63=proba2[66*256+104] +35=proba2[66*256+105] +49=proba2[66*256+108] +63=proba2[66*256+110] +29=proba2[66*256+111] +52=proba2[66*256+112] +63=proba2[66*256+113] +35=proba2[66*256+114] +56=proba2[66*256+115] +56=proba2[66*256+116] +39=proba2[66*256+117] +56=proba2[66*256+118] +56=proba2[66*256+119] +56=proba2[66*256+120] +56=proba2[66*256+122] +61=proba1[67] +65=proba2[67*256+32] +65=proba2[67*256+39] +65=proba2[67*256+41] +59=proba2[67*256+46] +48=proba2[67*256+48] +37=proba2[67*256+49] +36=proba2[67*256+50] +39=proba2[67*256+51] +43=proba2[67*256+52] +42=proba2[67*256+53] +42=proba2[67*256+54] +65=proba2[67*256+55] +54=proba2[67*256+56] +48=proba2[67*256+57] +24=proba2[67*256+65] +42=proba2[67*256+66] +41=proba2[67*256+67] +43=proba2[67*256+68] +28=proba2[67*256+69] +49=proba2[67*256+70] +49=proba2[67*256+71] +23=proba2[67*256+72] +32=proba2[67*256+73] +65=proba2[67*256+74] +33=proba2[67*256+75] +38=proba2[67*256+76] +43=proba2[67*256+77] +49=proba2[67*256+78] +22=proba2[67*256+79] +42=proba2[67*256+80] +59=proba2[67*256+81] +31=proba2[67*256+82] +40=proba2[67*256+83] +41=proba2[67*256+84] +42=proba2[67*256+85] +54=proba2[67*256+86] +54=proba2[67*256+88] +54=proba2[67*256+89] +59=proba2[67*256+90] +65=proba2[67*256+94] +33=proba2[67*256+97] +65=proba2[67*256+98] +52=proba2[67*256+99] +41=proba2[67*256+101] +65=proba2[67*256+102] +54=proba2[67*256+103] +33=proba2[67*256+104] +45=proba2[67*256+105] +65=proba2[67*256+106] +65=proba2[67*256+107] +38=proba2[67*256+108] +48=proba2[67*256+109] +31=proba2[67*256+111] +65=proba2[67*256+112] +65=proba2[67*256+113] +43=proba2[67*256+114] +54=proba2[67*256+115] +65=proba2[67*256+116] +54=proba2[67*256+117] +41=proba2[67*256+121] +65=proba1[68] +56=proba2[68*256+38] +63=proba2[68*256+43] +40=proba2[68*256+48] +36=proba2[68*256+49] +41=proba2[68*256+50] +42=proba2[68*256+51] +49=proba2[68*256+52] +52=proba2[68*256+53] +49=proba2[68*256+54] +45=proba2[68*256+55] +43=proba2[68*256+56] +40=proba2[68*256+57] +63=proba2[68*256+59] +63=proba2[68*256+64] +24=proba2[68*256+65] +45=proba2[68*256+66] +45=proba2[68*256+67] +41=proba2[68*256+68] +23=proba2[68*256+69] +47=proba2[68*256+70] +52=proba2[68*256+71] +49=proba2[68*256+72] +25=proba2[68*256+73] +36=proba2[68*256+74] +47=proba2[68*256+75] +42=proba2[68*256+76] +40=proba2[68*256+77] +56=proba2[68*256+78] +27=proba2[68*256+79] +47=proba2[68*256+80] +30=proba2[68*256+82] +39=proba2[68*256+83] +47=proba2[68*256+84] +38=proba2[68*256+85] +49=proba2[68*256+86] +52=proba2[68*256+87] +49=proba2[68*256+89] +47=proba2[68*256+90] +63=proba2[68*256+95] +32=proba2[68*256+97] +49=proba2[68*256+100] +31=proba2[68*256+101] +63=proba2[68*256+102] +63=proba2[68*256+103] +63=proba2[68*256+104] +33=proba2[68*256+105] +49=proba2[68*256+106] +56=proba2[68*256+107] +63=proba2[68*256+108] +52=proba2[68*256+109] +56=proba2[68*256+110] +33=proba2[68*256+111] +49=proba2[68*256+112] +36=proba2[68*256+114] +47=proba2[68*256+115] +63=proba2[68*256+116] +38=proba2[68*256+117] +56=proba2[68*256+118] +63=proba2[68*256+119] +45=proba2[68*256+120] +56=proba2[68*256+121] +69=proba1[69] +68=proba2[69*256+42] +68=proba2[69*256+45] +68=proba2[69*256+46] +46=proba2[69*256+48] +35=proba2[69*256+49] +41=proba2[69*256+50] +52=proba2[69*256+51] +50=proba2[69*256+52] +43=proba2[69*256+53] +47=proba2[69*256+54] +57=proba2[69*256+55] +52=proba2[69*256+56] +39=proba2[69*256+57] +35=proba2[69*256+65] +39=proba2[69*256+66] +35=proba2[69*256+67] +35=proba2[69*256+68] +44=proba2[69*256+69] +49=proba2[69*256+70] +41=proba2[69*256+71] +52=proba2[69*256+72] +47=proba2[69*256+73] +52=proba2[69*256+74] +46=proba2[69*256+75] +22=proba2[69*256+76] +32=proba2[69*256+77] +26=proba2[69*256+78] +46=proba2[69*256+79] +38=proba2[69*256+80] +18=proba2[69*256+82] +27=proba2[69*256+83] +27=proba2[69*256+84] +39=proba2[69*256+85] +44=proba2[69*256+86] +50=proba2[69*256+87] +40=proba2[69*256+88] +45=proba2[69*256+89] +52=proba2[69*256+90] +54=proba2[69*256+97] +54=proba2[69*256+98] +50=proba2[69*256+99] +54=proba2[69*256+100] +57=proba2[69*256+101] +61=proba2[69*256+102] +61=proba2[69*256+103] +57=proba2[69*256+104] +57=proba2[69*256+105] +61=proba2[69*256+106] +61=proba2[69*256+107] +38=proba2[69*256+108] +49=proba2[69*256+109] +43=proba2[69*256+110] +61=proba2[69*256+111] +68=proba2[69*256+112] +57=proba2[69*256+114] +54=proba2[69*256+115] +50=proba2[69*256+116] +50=proba2[69*256+117] +57=proba2[69*256+118] +68=proba2[69*256+119] +54=proba2[69*256+120] +68=proba2[69*256+121] +68=proba2[69*256+122] +66=proba1[70] +59=proba2[70*256+35] +59=proba2[70*256+38] +59=proba2[70*256+44] +59=proba2[70*256+45] +59=proba2[70*256+46] +43=proba2[70*256+48] +35=proba2[70*256+49] +37=proba2[70*256+50] +40=proba2[70*256+51] +48=proba2[70*256+52] +45=proba2[70*256+53] +40=proba2[70*256+54] +48=proba2[70*256+55] +48=proba2[70*256+56] +40=proba2[70*256+57] +23=proba2[70*256+65] +41=proba2[70*256+66] +41=proba2[70*256+67] +37=proba2[70*256+68] +33=proba2[70*256+69] +35=proba2[70*256+70] +43=proba2[70*256+71] +59=proba2[70*256+72] +27=proba2[70*256+73] +41=proba2[70*256+74] +48=proba2[70*256+75] +32=proba2[70*256+76] +41=proba2[70*256+77] +59=proba2[70*256+78] +31=proba2[70*256+79] +48=proba2[70*256+80] +59=proba2[70*256+81] +29=proba2[70*256+82] +37=proba2[70*256+83] +41=proba2[70*256+84] +36=proba2[70*256+85] +43=proba2[70*256+86] +48=proba2[70*256+87] +48=proba2[70*256+88] +59=proba2[70*256+89] +59=proba2[70*256+90] +59=proba2[70*256+93] +59=proba2[70*256+95] +30=proba2[70*256+97] +48=proba2[70*256+99] +59=proba2[70*256+100] +36=proba2[70*256+101] +45=proba2[70*256+102] +52=proba2[70*256+103] +41=proba2[70*256+105] +59=proba2[70*256+107] +33=proba2[70*256+108] +52=proba2[70*256+109] +52=proba2[70*256+110] +38=proba2[70*256+111] +30=proba2[70*256+114] +52=proba2[70*256+116] +41=proba2[70*256+117] +59=proba2[70*256+121] +59=proba2[70*256+122] +66=proba1[71] +54=proba2[71*256+32] +54=proba2[71*256+33] +54=proba2[71*256+42] +61=proba2[71*256+45] +43=proba2[71*256+48] +37=proba2[71*256+49] +39=proba2[71*256+50] +41=proba2[71*256+51] +47=proba2[71*256+52] +47=proba2[71*256+53] +54=proba2[71*256+54] +37=proba2[71*256+55] +54=proba2[71*256+56] +37=proba2[71*256+57] +23=proba2[71*256+65] +38=proba2[71*256+66] +43=proba2[71*256+67] +45=proba2[71*256+68] +27=proba2[71*256+69] +47=proba2[71*256+70] +38=proba2[71*256+71] +39=proba2[71*256+72] +31=proba2[71*256+73] +50=proba2[71*256+74] +54=proba2[71*256+75] +41=proba2[71*256+76] +45=proba2[71*256+77] +41=proba2[71*256+78] +27=proba2[71*256+79] +40=proba2[71*256+80] +54=proba2[71*256+81] +35=proba2[71*256+82] +47=proba2[71*256+83] +43=proba2[71*256+84] +35=proba2[71*256+85] +50=proba2[71*256+86] +50=proba2[71*256+87] +45=proba2[71*256+88] +50=proba2[71*256+89] +61=proba2[71*256+90] +30=proba2[71*256+97] +54=proba2[71*256+98] +50=proba2[71*256+100] +47=proba2[71*256+101] +61=proba2[71*256+102] +47=proba2[71*256+103] +43=proba2[71*256+104] +35=proba2[71*256+105] +54=proba2[71*256+106] +50=proba2[71*256+107] +40=proba2[71*256+108] +54=proba2[71*256+109] +54=proba2[71*256+110] +30=proba2[71*256+111] +50=proba2[71*256+112] +41=proba2[71*256+114] +61=proba2[71*256+116] +31=proba2[71*256+117] +54=proba2[71*256+119] +54=proba2[71*256+120] +50=proba2[71*256+121] +72=proba1[72] +58=proba2[72*256+32] +58=proba2[72*256+33] +58=proba2[72*256+44] +58=proba2[72*256+45] +58=proba2[72*256+48] +37=proba2[72*256+49] +37=proba2[72*256+50] +40=proba2[72*256+51] +51=proba2[72*256+52] +58=proba2[72*256+53] +51=proba2[72*256+54] +44=proba2[72*256+55] +47=proba2[72*256+56] +42=proba2[72*256+57] +20=proba2[72*256+65] +42=proba2[72*256+66] +44=proba2[72*256+67] +42=proba2[72*256+68] +21=proba2[72*256+69] +42=proba2[72*256+70] +58=proba2[72*256+71] +42=proba2[72*256+72] +26=proba2[72*256+73] +51=proba2[72*256+74] +39=proba2[72*256+75] +47=proba2[72*256+76] +36=proba2[72*256+77] +47=proba2[72*256+78] +26=proba2[72*256+79] +51=proba2[72*256+80] +47=proba2[72*256+81] +35=proba2[72*256+82] +47=proba2[72*256+83] +47=proba2[72*256+84] +37=proba2[72*256+85] +58=proba2[72*256+86] +51=proba2[72*256+87] +44=proba2[72*256+88] +39=proba2[72*256+89] +42=proba2[72*256+90] +51=proba2[72*256+95] +32=proba2[72*256+97] +51=proba2[72*256+98] +58=proba2[72*256+99] +47=proba2[72*256+100] +32=proba2[72*256+101] +58=proba2[72*256+102] +37=proba2[72*256+105] +51=proba2[72*256+106] +58=proba2[72*256+107] +58=proba2[72*256+108] +58=proba2[72*256+110] +36=proba2[72*256+111] +51=proba2[72*256+114] +58=proba2[72*256+115] +58=proba2[72*256+116] +42=proba2[72*256+117] +51=proba2[72*256+121] +51=proba2[72*256+122] +58=proba2[72*256+125] +75=proba1[73] +67=proba2[73*256+36] +67=proba2[73*256+38] +67=proba2[73*256+46] +49=proba2[73*256+48] +41=proba2[73*256+49] +44=proba2[73*256+50] +51=proba2[73*256+51] +49=proba2[73*256+52] +60=proba2[73*256+53] +46=proba2[73*256+54] +46=proba2[73*256+55] +56=proba2[73*256+56] +53=proba2[73*256+57] +29=proba2[73*256+65] +45=proba2[73*256+66] +26=proba2[73*256+67] +35=proba2[73*256+68] +21=proba2[73*256+69] +44=proba2[73*256+70] +36=proba2[73*256+71] +67=proba2[73*256+72] +42=proba2[73*256+73] +60=proba2[73*256+74] +37=proba2[73*256+75] +28=proba2[73*256+76] +30=proba2[73*256+77] +21=proba2[73*256+78] +33=proba2[73*256+79] +43=proba2[73*256+80] +44=proba2[73*256+81] +31=proba2[73*256+82] +25=proba2[73*256+83] +27=proba2[73*256+84] +56=proba2[73*256+85] +39=proba2[73*256+86] +53=proba2[73*256+87] +42=proba2[73*256+88] +67=proba2[73*256+89] +45=proba2[73*256+90] +53=proba2[73*256+97] +56=proba2[73*256+99] +53=proba2[73*256+100] +60=proba2[73*256+102] +60=proba2[73*256+103] +67=proba2[73*256+104] +67=proba2[73*256+105] +67=proba2[73*256+107] +56=proba2[73*256+108] +53=proba2[73*256+109] +45=proba2[73*256+110] +60=proba2[73*256+112] +60=proba2[73*256+113] +53=proba2[73*256+114] +49=proba2[73*256+115] +67=proba2[73*256+116] +60=proba2[73*256+118] +67=proba2[73*256+119] +67=proba2[73*256+120] +60=proba2[73*256+122] +67=proba1[74] +57=proba2[74*256+42] +57=proba2[74*256+46] +37=proba2[74*256+48] +46=proba2[74*256+49] +37=proba2[74*256+50] +46=proba2[74*256+51] +57=proba2[74*256+52] +50=proba2[74*256+53] +57=proba2[74*256+54] +43=proba2[74*256+55] +57=proba2[74*256+56] +50=proba2[74*256+57] +50=proba2[74*256+64] +28=proba2[74*256+65] +39=proba2[74*256+66] +39=proba2[74*256+67] +46=proba2[74*256+68] +26=proba2[74*256+69] +36=proba2[74*256+70] +46=proba2[74*256+71] +43=proba2[74*256+72] +32=proba2[74*256+73] +36=proba2[74*256+74] +46=proba2[74*256+75] +39=proba2[74*256+76] +39=proba2[74*256+77] +57=proba2[74*256+78] +21=proba2[74*256+79] +30=proba2[74*256+80] +50=proba2[74*256+81] +39=proba2[74*256+82] +43=proba2[74*256+83] +46=proba2[74*256+84] +27=proba2[74*256+85] +57=proba2[74*256+87] +57=proba2[74*256+89] +50=proba2[74*256+90] +57=proba2[74*256+95] +31=proba2[74*256+97] +50=proba2[74*256+98] +43=proba2[74*256+99] +57=proba2[74*256+100] +34=proba2[74*256+101] +50=proba2[74*256+102] +46=proba2[74*256+104] +50=proba2[74*256+105] +50=proba2[74*256+106] +57=proba2[74*256+107] +50=proba2[74*256+109] +57=proba2[74*256+110] +32=proba2[74*256+111] +57=proba2[74*256+112] +57=proba2[74*256+114] +57=proba2[74*256+116] +30=proba2[74*256+117] +50=proba2[74*256+118] +50=proba2[74*256+119] +57=proba2[74*256+121] +70=proba1[75] +56=proba2[75*256+39] +56=proba2[75*256+46] +56=proba2[75*256+48] +35=proba2[75*256+49] +34=proba2[75*256+50] +49=proba2[75*256+51] +40=proba2[75*256+52] +45=proba2[75*256+53] +38=proba2[75*256+54] +49=proba2[75*256+55] +40=proba2[75*256+56] +45=proba2[75*256+57] +56=proba2[75*256+63] +56=proba2[75*256+64] +22=proba2[75*256+65] +42=proba2[75*256+66] +56=proba2[75*256+67] +49=proba2[75*256+68] +30=proba2[75*256+69] +45=proba2[75*256+70] +56=proba2[75*256+71] +45=proba2[75*256+72] +23=proba2[75*256+73] +45=proba2[75*256+74] +45=proba2[75*256+75] +35=proba2[75*256+76] +40=proba2[75*256+77] +49=proba2[75*256+78] +30=proba2[75*256+79] +56=proba2[75*256+80] +56=proba2[75*256+81] +37=proba2[75*256+82] +45=proba2[75*256+83] +45=proba2[75*256+84] +49=proba2[75*256+85] +56=proba2[75*256+86] +49=proba2[75*256+87] +56=proba2[75*256+88] +42=proba2[75*256+89] +56=proba2[75*256+90] +56=proba2[75*256+95] +26=proba2[75*256+97] +49=proba2[75*256+98] +45=proba2[75*256+100] +31=proba2[75*256+101] +49=proba2[75*256+102] +49=proba2[75*256+103] +40=proba2[75*256+104] +34=proba2[75*256+105] +49=proba2[75*256+107] +56=proba2[75*256+108] +56=proba2[75*256+110] +33=proba2[75*256+111] +49=proba2[75*256+112] +49=proba2[75*256+113] +42=proba2[75*256+114] +56=proba2[75*256+115] +56=proba2[75*256+116] +45=proba2[75*256+117] +56=proba2[75*256+118] +56=proba2[75*256+119] +49=proba2[75*256+120] +56=proba2[75*256+121] +49=proba2[75*256+122] +56=proba2[75*256+124] +65=proba1[76] +66=proba2[76*256+32] +66=proba2[76*256+41] +66=proba2[76*256+45] +55=proba2[76*256+46] +44=proba2[76*256+48] +41=proba2[76*256+49] +45=proba2[76*256+50] +52=proba2[76*256+51] +46=proba2[76*256+52] +46=proba2[76*256+53] +50=proba2[76*256+54] +55=proba2[76*256+55] +59=proba2[76*256+56] +48=proba2[76*256+57] +66=proba2[76*256+64] +21=proba2[76*256+65] +45=proba2[76*256+66] +44=proba2[76*256+67] +36=proba2[76*256+68] +21=proba2[76*256+69] +44=proba2[76*256+70] +45=proba2[76*256+71] +46=proba2[76*256+72] +20=proba2[76*256+73] +66=proba2[76*256+74] +52=proba2[76*256+75] +28=proba2[76*256+76] +36=proba2[76*256+77] +24=proba2[76*256+79] +39=proba2[76*256+80] +52=proba2[76*256+82] +43=proba2[76*256+83] +40=proba2[76*256+84] +36=proba2[76*256+85] +44=proba2[76*256+86] +59=proba2[76*256+87] +41=proba2[76*256+89] +66=proba2[76*256+90] +66=proba2[76*256+93] +32=proba2[76*256+97] +66=proba2[76*256+98] +55=proba2[76*256+99] +55=proba2[76*256+100] +36=proba2[76*256+101] +50=proba2[76*256+102] +66=proba2[76*256+103] +59=proba2[76*256+104] +38=proba2[76*256+105] +59=proba2[76*256+106] +55=proba2[76*256+109] +66=proba2[76*256+110] +35=proba2[76*256+111] +66=proba2[76*256+112] +66=proba2[76*256+113] +66=proba2[76*256+114] +66=proba2[76*256+115] +55=proba2[76*256+116] +41=proba2[76*256+117] +66=proba2[76*256+118] +66=proba2[76*256+119] +55=proba2[76*256+121] +50=proba2[76*256+122] +58=proba1[77] +60=proba2[77*256+32] +67=proba2[77*256+33] +60=proba2[77*256+42] +60=proba2[77*256+43] +60=proba2[77*256+44] +51=proba2[77*256+45] +46=proba2[77*256+48] +39=proba2[77*256+49] +44=proba2[77*256+50] +46=proba2[77*256+51] +60=proba2[77*256+52] +51=proba2[77*256+53] +49=proba2[77*256+54] +46=proba2[77*256+55] +47=proba2[77*256+56] +46=proba2[77*256+57] +60=proba2[77*256+63] +18=proba2[77*256+65] +39=proba2[77*256+66] +42=proba2[77*256+67] +45=proba2[77*256+68] +25=proba2[77*256+69] +49=proba2[77*256+70] +44=proba2[77*256+71] +60=proba2[77*256+72] +26=proba2[77*256+73] +53=proba2[77*256+74] +51=proba2[77*256+75] +46=proba2[77*256+76] +34=proba2[77*256+77] +45=proba2[77*256+78] +27=proba2[77*256+79] +38=proba2[77*256+80] +56=proba2[77*256+81] +46=proba2[77*256+82] +51=proba2[77*256+83] +47=proba2[77*256+84] +44=proba2[77*256+85] +51=proba2[77*256+86] +49=proba2[77*256+87] +67=proba2[77*256+88] +36=proba2[77*256+89] +53=proba2[77*256+90] +67=proba2[77*256+95] +22=proba2[77*256+97] +51=proba2[77*256+98] +51=proba2[77*256+99] +32=proba2[77*256+101] +60=proba2[77*256+102] +56=proba2[77*256+103] +67=proba2[77*256+104] +32=proba2[77*256+105] +56=proba2[77*256+106] +56=proba2[77*256+107] +60=proba2[77*256+108] +60=proba2[77*256+109] +56=proba2[77*256+110] +35=proba2[77*256+111] +67=proba2[77*256+112] +56=proba2[77*256+114] +67=proba2[77*256+115] +56=proba2[77*256+116] +46=proba2[77*256+117] +67=proba2[77*256+119] +67=proba2[77*256+120] +39=proba2[77*256+121] +67=proba2[77*256+122] +69=proba1[78] +64=proba2[78*256+33] +64=proba2[78*256+43] +53=proba2[78*256+45] +57=proba2[78*256+46] +57=proba2[78*256+48] +39=proba2[78*256+49] +40=proba2[78*256+50] +46=proba2[78*256+51] +45=proba2[78*256+52] +45=proba2[78*256+53] +48=proba2[78*256+54] +46=proba2[78*256+55] +50=proba2[78*256+56] +50=proba2[78*256+57] +64=proba2[78*256+61] +64=proba2[78*256+64] +26=proba2[78*256+65] +50=proba2[78*256+66] +33=proba2[78*256+67] +26=proba2[78*256+68] +19=proba2[78*256+69] +39=proba2[78*256+70] +34=proba2[78*256+71] +50=proba2[78*256+72] +25=proba2[78*256+73] +48=proba2[78*256+74] +57=proba2[78*256+75] +48=proba2[78*256+76] +50=proba2[78*256+77] +30=proba2[78*256+78] +28=proba2[78*256+79] +53=proba2[78*256+80] +64=proba2[78*256+81] +44=proba2[78*256+83] +26=proba2[78*256+84] +40=proba2[78*256+85] +64=proba2[78*256+87] +46=proba2[78*256+88] +41=proba2[78*256+89] +48=proba2[78*256+90] +33=proba2[78*256+97] +53=proba2[78*256+98] +57=proba2[78*256+99] +64=proba2[78*256+100] +39=proba2[78*256+101] +64=proba2[78*256+102] +48=proba2[78*256+103] +64=proba2[78*256+104] +34=proba2[78*256+105] +64=proba2[78*256+107] +64=proba2[78*256+109] +64=proba2[78*256+110] +37=proba2[78*256+111] +46=proba2[78*256+112] +57=proba2[78*256+115] +53=proba2[78*256+116] +48=proba2[78*256+117] +64=proba2[78*256+119] +64=proba2[78*256+121] +57=proba2[78*256+122] +64=proba2[78*256+125] +77=proba1[79] +66=proba2[79*256+32] +66=proba2[79*256+46] +45=proba2[79*256+48] +43=proba2[79*256+49] +44=proba2[79*256+50] +48=proba2[79*256+51] +66=proba2[79*256+52] +50=proba2[79*256+53] +50=proba2[79*256+54] +59=proba2[79*256+55] +55=proba2[79*256+56] +44=proba2[79*256+57] +55=proba2[79*256+61] +48=proba2[79*256+65] +38=proba2[79*256+66] +31=proba2[79*256+67] +44=proba2[79*256+68] +50=proba2[79*256+69] +50=proba2[79*256+70] +40=proba2[79*256+71] +50=proba2[79*256+72] +36=proba2[79*256+73] +44=proba2[79*256+74] +52=proba2[79*256+75] +26=proba2[79*256+76] +27=proba2[79*256+77] +20=proba2[79*256+78] +34=proba2[79*256+79] +35=proba2[79*256+80] +24=proba2[79*256+82] +30=proba2[79*256+83] +30=proba2[79*256+84] +18=proba2[79*256+85] +47=proba2[79*256+86] +55=proba2[79*256+87] +50=proba2[79*256+88] +42=proba2[79*256+89] +52=proba2[79*256+90] +66=proba2[79*256+93] +59=proba2[79*256+98] +59=proba2[79*256+99] +66=proba2[79*256+103] +66=proba2[79*256+104] +59=proba2[79*256+105] +66=proba2[79*256+106] +66=proba2[79*256+107] +52=proba2[79*256+108] +59=proba2[79*256+109] +50=proba2[79*256+110] +66=proba2[79*256+112] +59=proba2[79*256+114] +66=proba2[79*256+115] +55=proba2[79*256+116] +66=proba2[79*256+117] +66=proba2[79*256+120] +66=proba2[79*256+121] +55=proba2[79*256+122] +63=proba1[80] +56=proba2[80*256+45] +41=proba2[80*256+48] +36=proba2[80*256+49] +36=proba2[80*256+50] +43=proba2[80*256+51] +41=proba2[80*256+52] +52=proba2[80*256+53] +46=proba2[80*256+54] +52=proba2[80*256+55] +63=proba2[80*256+56] +46=proba2[80*256+57] +63=proba2[80*256+61] +63=proba2[80*256+63] +23=proba2[80*256+65] +49=proba2[80*256+66] +45=proba2[80*256+67] +42=proba2[80*256+68] +27=proba2[80*256+69] +49=proba2[80*256+70] +39=proba2[80*256+71] +29=proba2[80*256+72] +30=proba2[80*256+73] +45=proba2[80*256+74] +49=proba2[80*256+75] +36=proba2[80*256+76] +42=proba2[80*256+77] +46=proba2[80*256+78] +27=proba2[80*256+79] +38=proba2[80*256+80] +56=proba2[80*256+81] +32=proba2[80*256+82] +39=proba2[80*256+83] +39=proba2[80*256+84] +37=proba2[80*256+85] +42=proba2[80*256+86] +56=proba2[80*256+87] +63=proba2[80*256+88] +41=proba2[80*256+89] +63=proba2[80*256+90] +28=proba2[80*256+97] +63=proba2[80*256+98] +34=proba2[80*256+101] +63=proba2[80*256+103] +36=proba2[80*256+104] +36=proba2[80*256+105] +56=proba2[80*256+108] +56=proba2[80*256+109] +52=proba2[80*256+110] +29=proba2[80*256+111] +63=proba2[80*256+113] +42=proba2[80*256+114] +63=proba2[80*256+115] +63=proba2[80*256+116] +46=proba2[80*256+117] +63=proba2[80*256+118] +63=proba2[80*256+119] +56=proba2[80*256+120] +63=proba2[80*256+121] +84=proba1[81] +47=proba2[81*256+48] +47=proba2[81*256+49] +40=proba2[81*256+50] +47=proba2[81*256+51] +36=proba2[81*256+52] +33=proba2[81*256+53] +47=proba2[81*256+54] +33=proba2[81*256+55] +47=proba2[81*256+56] +33=proba2[81*256+57] +33=proba2[81*256+65] +47=proba2[81*256+67] +40=proba2[81*256+68] +40=proba2[81*256+69] +40=proba2[81*256+70] +33=proba2[81*256+71] +40=proba2[81*256+73] +40=proba2[81*256+74] +40=proba2[81*256+76] +40=proba2[81*256+77] +47=proba2[81*256+79] +40=proba2[81*256+80] +47=proba2[81*256+81] +40=proba2[81*256+82] +40=proba2[81*256+83] +40=proba2[81*256+84] +20=proba2[81*256+85] +33=proba2[81*256+87] +33=proba2[81*256+89] +47=proba2[81*256+90] +47=proba2[81*256+97] +40=proba2[81*256+98] +47=proba2[81*256+99] +40=proba2[81*256+102] +47=proba2[81*256+103] +40=proba2[81*256+104] +47=proba2[81*256+107] +47=proba2[81*256+109] +47=proba2[81*256+110] +47=proba2[81*256+112] +40=proba2[81*256+113] +47=proba2[81*256+114] +40=proba2[81*256+116] +26=proba2[81*256+117] +29=proba2[81*256+119] +47=proba2[81*256+122] +69=proba1[82] +55=proba2[82*256+32] +66=proba2[82*256+35] +66=proba2[82*256+42] +66=proba2[82*256+43] +55=proba2[82*256+48] +36=proba2[82*256+49] +38=proba2[82*256+50] +48=proba2[82*256+51] +45=proba2[82*256+52] +48=proba2[82*256+53] +59=proba2[82*256+54] +45=proba2[82*256+55] +52=proba2[82*256+56] +48=proba2[82*256+57] +21=proba2[82*256+65] +44=proba2[82*256+66] +38=proba2[82*256+67] +34=proba2[82*256+68] +22=proba2[82*256+69] +47=proba2[82*256+70] +38=proba2[82*256+71] +66=proba2[82*256+72] +20=proba2[82*256+73] +52=proba2[82*256+74] +52=proba2[82*256+75] +39=proba2[82*256+76] +39=proba2[82*256+77] +44=proba2[82*256+78] +24=proba2[82*256+79] +45=proba2[82*256+80] +52=proba2[82*256+81] +36=proba2[82*256+82] +33=proba2[82*256+83] +32=proba2[82*256+84] +36=proba2[82*256+85] +47=proba2[82*256+86] +59=proba2[82*256+87] +59=proba2[82*256+88] +41=proba2[82*256+89] +66=proba2[82*256+90] +66=proba2[82*256+93] +66=proba2[82*256+96] +40=proba2[82*256+97] +55=proba2[82*256+100] +37=proba2[82*256+101] +59=proba2[82*256+102] +66=proba2[82*256+103] +66=proba2[82*256+104] +41=proba2[82*256+105] +66=proba2[82*256+106] +66=proba2[82*256+107] +66=proba2[82*256+108] +36=proba2[82*256+111] +55=proba2[82*256+113] +55=proba2[82*256+114] +59=proba2[82*256+115] +59=proba2[82*256+116] +43=proba2[82*256+117] +66=proba2[82*256+118] +59=proba2[82*256+119] +66=proba2[82*256+121] +66=proba2[82*256+122] +61=proba1[83] +59=proba2[83*256+32] +66=proba2[83*256+35] +66=proba2[83*256+38] +66=proba2[83*256+41] +66=proba2[83*256+42] +66=proba2[83*256+45] +44=proba2[83*256+48] +33=proba2[83*256+49] +43=proba2[83*256+50] +48=proba2[83*256+51] +48=proba2[83*256+52] +50=proba2[83*256+53] +50=proba2[83*256+54] +46=proba2[83*256+55] +50=proba2[83*256+56] +42=proba2[83*256+57] +66=proba2[83*256+64] +25=proba2[83*256+65] +46=proba2[83*256+66] +33=proba2[83*256+67] +50=proba2[83*256+68] +25=proba2[83*256+69] +55=proba2[83*256+70] +66=proba2[83*256+71] +40=proba2[83*256+72] +32=proba2[83*256+73] +55=proba2[83*256+74] +50=proba2[83*256+75] +40=proba2[83*256+76] +45=proba2[83*256+77] +42=proba2[83*256+78] +35=proba2[83*256+79] +35=proba2[83*256+80] +46=proba2[83*256+81] +43=proba2[83*256+82] +27=proba2[83*256+83] +25=proba2[83*256+84] +38=proba2[83*256+85] +50=proba2[83*256+86] +42=proba2[83*256+87] +50=proba2[83*256+88] +39=proba2[83*256+89] +55=proba2[83*256+90] +31=proba2[83*256+97] +66=proba2[83*256+98] +44=proba2[83*256+99] +59=proba2[83*256+100] +36=proba2[83*256+101] +59=proba2[83*256+102] +66=proba2[83*256+103] +42=proba2[83*256+104] +40=proba2[83*256+105] +66=proba2[83*256+106] +50=proba2[83*256+107] +59=proba2[83*256+108] +48=proba2[83*256+109] +52=proba2[83*256+110] +33=proba2[83*256+111] +48=proba2[83*256+112] +55=proba2[83*256+113] +66=proba2[83*256+114] +66=proba2[83*256+115] +38=proba2[83*256+116] +41=proba2[83*256+117] +59=proba2[83*256+119] +66=proba2[83*256+120] +48=proba2[83*256+121] +64=proba1[84] +66=proba2[84*256+33] +66=proba2[84*256+39] +66=proba2[84*256+43] +66=proba2[84*256+44] +59=proba2[84*256+45] +52=proba2[84*256+48] +42=proba2[84*256+49] +39=proba2[84*256+50] +50=proba2[84*256+51] +46=proba2[84*256+52] +48=proba2[84*256+53] +44=proba2[84*256+54] +48=proba2[84*256+55] +48=proba2[84*256+56] +44=proba2[84*256+57] +24=proba2[84*256+65] +48=proba2[84*256+66] +37=proba2[84*256+67] +48=proba2[84*256+68] +22=proba2[84*256+69] +50=proba2[84*256+70] +48=proba2[84*256+71] +33=proba2[84*256+72] +24=proba2[84*256+73] +50=proba2[84*256+74] +66=proba2[84*256+75] +44=proba2[84*256+76] +43=proba2[84*256+77] +45=proba2[84*256+78] +23=proba2[84*256+79] +52=proba2[84*256+80] +31=proba2[84*256+82] +42=proba2[84*256+83] +31=proba2[84*256+84] +39=proba2[84*256+85] +55=proba2[84*256+86] +50=proba2[84*256+87] +59=proba2[84*256+88] +39=proba2[84*256+89] +52=proba2[84*256+90] +37=proba2[84*256+97] +50=proba2[84*256+98] +55=proba2[84*256+99] +66=proba2[84*256+100] +39=proba2[84*256+101] +52=proba2[84*256+102] +66=proba2[84*256+103] +33=proba2[84*256+104] +37=proba2[84*256+105] +66=proba2[84*256+106] +66=proba2[84*256+108] +59=proba2[84*256+110] +34=proba2[84*256+111] +48=proba2[84*256+112] +55=proba2[84*256+113] +41=proba2[84*256+114] +66=proba2[84*256+115] +55=proba2[84*256+116] +42=proba2[84*256+117] +66=proba2[84*256+118] +59=proba2[84*256+119] +59=proba2[84*256+120] +46=proba2[84*256+121] +81=proba1[85] +61=proba2[85*256+42] +61=proba2[85*256+45] +61=proba2[85*256+48] +37=proba2[85*256+49] +43=proba2[85*256+50] +50=proba2[85*256+51] +44=proba2[85*256+52] +54=proba2[85*256+53] +50=proba2[85*256+54] +40=proba2[85*256+55] +43=proba2[85*256+57] +61=proba2[85*256+64] +40=proba2[85*256+65] +32=proba2[85*256+66] +28=proba2[85*256+67] +28=proba2[85*256+68] +30=proba2[85*256+69] +44=proba2[85*256+70] +43=proba2[85*256+71] +54=proba2[85*256+72] +31=proba2[85*256+73] +54=proba2[85*256+74] +47=proba2[85*256+75] +25=proba2[85*256+76] +34=proba2[85*256+77] +28=proba2[85*256+78] +54=proba2[85*256+79] +39=proba2[85*256+80] +24=proba2[85*256+82] +24=proba2[85*256+83] +33=proba2[85*256+84] +50=proba2[85*256+85] +41=proba2[85*256+86] +54=proba2[85*256+87] +44=proba2[85*256+88] +39=proba2[85*256+90] +50=proba2[85*256+97] +61=proba2[85*256+98] +54=proba2[85*256+101] +61=proba2[85*256+102] +54=proba2[85*256+103] +61=proba2[85*256+104] +54=proba2[85*256+105] +61=proba2[85*256+106] +61=proba2[85*256+107] +47=proba2[85*256+108] +61=proba2[85*256+109] +36=proba2[85*256+110] +61=proba2[85*256+112] +50=proba2[85*256+114] +43=proba2[85*256+115] +61=proba2[85*256+116] +61=proba2[85*256+118] +50=proba2[85*256+120] +47=proba2[85*256+121] +50=proba2[85*256+122] +73=proba1[86] +55=proba2[86*256+33] +55=proba2[86*256+43] +55=proba2[86*256+46] +55=proba2[86*256+48] +31=proba2[86*256+49] +31=proba2[86*256+50] +37=proba2[86*256+51] +55=proba2[86*256+52] +48=proba2[86*256+53] +44=proba2[86*256+54] +48=proba2[86*256+55] +48=proba2[86*256+56] +48=proba2[86*256+57] +20=proba2[86*256+65] +44=proba2[86*256+66] +55=proba2[86*256+67] +35=proba2[86*256+68] +22=proba2[86*256+69] +48=proba2[86*256+70] +48=proba2[86*256+71] +48=proba2[86*256+72] +25=proba2[86*256+73] +44=proba2[86*256+74] +55=proba2[86*256+75] +44=proba2[86*256+76] +34=proba2[86*256+79] +44=proba2[86*256+80] +55=proba2[86*256+81] +41=proba2[86*256+82] +41=proba2[86*256+83] +38=proba2[86*256+84] +55=proba2[86*256+85] +44=proba2[86*256+86] +55=proba2[86*256+87] +55=proba2[86*256+89] +55=proba2[86*256+90] +26=proba2[86*256+97] +29=proba2[86*256+101] +44=proba2[86*256+102] +55=proba2[86*256+103] +55=proba2[86*256+104] +27=proba2[86*256+105] +48=proba2[86*256+107] +55=proba2[86*256+108] +48=proba2[86*256+109] +41=proba2[86*256+111] +48=proba2[86*256+112] +44=proba2[86*256+114] +55=proba2[86*256+117] +48=proba2[86*256+118] +55=proba2[86*256+122] +79=proba1[87] +51=proba2[87*256+33] +51=proba2[87*256+42] +40=proba2[87*256+46] +51=proba2[87*256+48] +35=proba2[87*256+49] +44=proba2[87*256+50] +35=proba2[87*256+51] +44=proba2[87*256+52] +51=proba2[87*256+53] +44=proba2[87*256+54] +37=proba2[87*256+55] +51=proba2[87*256+63] +22=proba2[87*256+65] +44=proba2[87*256+66] +40=proba2[87*256+67] +51=proba2[87*256+68] +33=proba2[87*256+69] +51=proba2[87*256+70] +51=proba2[87*256+71] +30=proba2[87*256+72] +31=proba2[87*256+73] +44=proba2[87*256+74] +40=proba2[87*256+75] +40=proba2[87*256+76] +37=proba2[87*256+77] +44=proba2[87*256+78] +33=proba2[87*256+79] +40=proba2[87*256+80] +35=proba2[87*256+81] +40=proba2[87*256+82] +40=proba2[87*256+83] +40=proba2[87*256+84] +51=proba2[87*256+85] +51=proba2[87*256+86] +44=proba2[87*256+87] +51=proba2[87*256+88] +44=proba2[87*256+90] +28=proba2[87*256+97] +51=proba2[87*256+100] +27=proba2[87*256+101] +40=proba2[87*256+104] +33=proba2[87*256+105] +51=proba2[87*256+106] +37=proba2[87*256+107] +51=proba2[87*256+110] +40=proba2[87*256+111] +37=proba2[87*256+113] +44=proba2[87*256+114] +51=proba2[87*256+115] +51=proba2[87*256+120] +80=proba1[88] +50=proba2[88*256+45] +50=proba2[88*256+46] +39=proba2[88*256+48] +30=proba2[88*256+49] +27=proba2[88*256+50] +43=proba2[88*256+51] +34=proba2[88*256+52] +50=proba2[88*256+53] +39=proba2[88*256+54] +34=proba2[88*256+55] +50=proba2[88*256+56] +50=proba2[88*256+57] +28=proba2[88*256+65] +50=proba2[88*256+66] +30=proba2[88*256+67] +32=proba2[88*256+68] +32=proba2[88*256+69] +36=proba2[88*256+70] +39=proba2[88*256+71] +34=proba2[88*256+73] +50=proba2[88*256+74] +50=proba2[88*256+75] +50=proba2[88*256+77] +43=proba2[88*256+78] +39=proba2[88*256+79] +34=proba2[88*256+80] +39=proba2[88*256+82] +39=proba2[88*256+83] +43=proba2[88*256+84] +50=proba2[88*256+85] +50=proba2[88*256+86] +39=proba2[88*256+87] +25=proba2[88*256+88] +39=proba2[88*256+89] +36=proba2[88*256+97] +50=proba2[88*256+99] +43=proba2[88*256+100] +43=proba2[88*256+101] +39=proba2[88*256+103] +50=proba2[88*256+104] +50=proba2[88*256+105] +50=proba2[88*256+106] +50=proba2[88*256+109] +50=proba2[88*256+111] +50=proba2[88*256+112] +50=proba2[88*256+113] +39=proba2[88*256+114] +50=proba2[88*256+116] +50=proba2[88*256+118] +39=proba2[88*256+119] +50=proba2[88*256+120] +50=proba2[88*256+121] +39=proba2[88*256+122] +78=proba1[89] +47=proba2[89*256+32] +54=proba2[89*256+38] +54=proba2[89*256+45] +43=proba2[89*256+48] +30=proba2[89*256+49] +43=proba2[89*256+50] +47=proba2[89*256+51] +47=proba2[89*256+52] +40=proba2[89*256+53] +36=proba2[89*256+54] +33=proba2[89*256+55] +54=proba2[89*256+56] +43=proba2[89*256+57] +28=proba2[89*256+65] +43=proba2[89*256+66] +35=proba2[89*256+67] +33=proba2[89*256+68] +38=proba2[89*256+69] +54=proba2[89*256+70] +28=proba2[89*256+71] +54=proba2[89*256+72] +43=proba2[89*256+73] +54=proba2[89*256+74] +47=proba2[89*256+75] +31=proba2[89*256+76] +31=proba2[89*256+77] +38=proba2[89*256+78] +28=proba2[89*256+79] +36=proba2[89*256+80] +40=proba2[89*256+81] +47=proba2[89*256+82] +31=proba2[89*256+83] +43=proba2[89*256+84] +47=proba2[89*256+85] +54=proba2[89*256+86] +54=proba2[89*256+87] +54=proba2[89*256+88] +54=proba2[89*256+89] +38=proba2[89*256+90] +36=proba2[89*256+97] +54=proba2[89*256+99] +47=proba2[89*256+100] +54=proba2[89*256+101] +38=proba2[89*256+103] +54=proba2[89*256+104] +47=proba2[89*256+105] +47=proba2[89*256+106] +43=proba2[89*256+107] +47=proba2[89*256+108] +54=proba2[89*256+110] +33=proba2[89*256+111] +47=proba2[89*256+112] +54=proba2[89*256+114] +47=proba2[89*256+115] +43=proba2[89*256+116] +54=proba2[89*256+117] +47=proba2[89*256+118] +35=proba2[89*256+119] +54=proba2[89*256+120] +47=proba2[89*256+122] +76=proba1[90] +54=proba2[90*256+32] +54=proba2[90*256+38] +54=proba2[90*256+42] +33=proba2[90*256+48] +34=proba2[90*256+49] +34=proba2[90*256+50] +47=proba2[90*256+51] +32=proba2[90*256+52] +40=proba2[90*256+53] +38=proba2[90*256+54] +40=proba2[90*256+55] +54=proba2[90*256+56] +54=proba2[90*256+57] +25=proba2[90*256+65] +38=proba2[90*256+66] +47=proba2[90*256+67] +47=proba2[90*256+68] +24=proba2[90*256+69] +38=proba2[90*256+70] +31=proba2[90*256+73] +43=proba2[90*256+74] +43=proba2[90*256+75] +47=proba2[90*256+76] +54=proba2[90*256+77] +25=proba2[90*256+79] +54=proba2[90*256+80] +47=proba2[90*256+81] +47=proba2[90*256+82] +43=proba2[90*256+83] +43=proba2[90*256+84] +43=proba2[90*256+85] +47=proba2[90*256+86] +47=proba2[90*256+87] +47=proba2[90*256+88] +47=proba2[90*256+89] +34=proba2[90*256+90] +36=proba2[90*256+97] +54=proba2[90*256+98] +54=proba2[90*256+99] +54=proba2[90*256+100] +34=proba2[90*256+101] +38=proba2[90*256+105] +54=proba2[90*256+106] +40=proba2[90*256+107] +47=proba2[90*256+109] +47=proba2[90*256+110] +32=proba2[90*256+111] +47=proba2[90*256+112] +47=proba2[90*256+115] +54=proba2[90*256+116] +33=proba2[90*256+117] +43=proba2[90*256+120] +54=proba2[90*256+121] +97=proba1[91] +23=proba2[91*256+48] +23=proba2[91*256+57] +17=proba2[91*256+77] +23=proba2[91*256+83] +23=proba2[91*256+93] +23=proba2[91*256+97] +17=proba2[91*256+98] +23=proba2[91*256+110] +23=proba2[91*256+117] +118=proba1[93] +12=proba2[93*256+48] +19=proba2[93*256+54] +19=proba2[93*256+59] +12=proba2[93*256+64] +19=proba2[93*256+125] +23=proba2[94*256+40] +23=proba2[94*256+41] +23=proba2[94*256+42] +23=proba2[94*256+49] +23=proba2[94*256+95] +23=proba2[94*256+98] +16=proba2[94*256+99] +23=proba2[94*256+109] +23=proba2[94*256+110] +98=proba1[95] +35=proba2[95*256+33] +49=proba2[95*256+41] +49=proba2[95*256+42] +49=proba2[95*256+43] +42=proba2[95*256+45] +33=proba2[95*256+48] +29=proba2[95*256+49] +31=proba2[95*256+50] +42=proba2[95*256+51] +42=proba2[95*256+52] +42=proba2[95*256+53] +35=proba2[95*256+54] +49=proba2[95*256+55] +49=proba2[95*256+56] +29=proba2[95*256+57] +49=proba2[95*256+64] +49=proba2[95*256+65] +49=proba2[95*256+68] +49=proba2[95*256+72] +49=proba2[95*256+77] +49=proba2[95*256+80] +49=proba2[95*256+85] +27=proba2[95*256+95] +35=proba2[95*256+97] +49=proba2[95*256+98] +33=proba2[95*256+99] +27=proba2[95*256+100] +38=proba2[95*256+101] +29=proba2[95*256+102] +49=proba2[95*256+103] +49=proba2[95*256+104] +49=proba2[95*256+105] +42=proba2[95*256+106] +42=proba2[95*256+107] +33=proba2[95*256+108] +49=proba2[95*256+109] +35=proba2[95*256+111] +42=proba2[95*256+112] +35=proba2[95*256+114] +38=proba2[95*256+115] +31=proba2[95*256+116] +49=proba2[95*256+117] +38=proba2[95*256+118] +42=proba2[95*256+119] +42=proba2[95*256+120] +42=proba2[95*256+121] +42=proba2[95*256+122] +49=proba2[95*256+126] +118=proba1[96] +10=proba2[96*256+49] +10=proba2[96*256+51] +10=proba2[96*256+100] +27=proba1[97] +85=proba2[97*256+32] +83=proba2[97*256+33] +112=proba2[97*256+34] +98=proba2[97*256+35] +98=proba2[97*256+36] +105=proba2[97*256+37] +86=proba2[97*256+38] +112=proba2[97*256+39] +105=proba2[97*256+40] +105=proba2[97*256+41] +98=proba2[97*256+42] +98=proba2[97*256+43] +98=proba2[97*256+44] +83=proba2[97*256+45] +84=proba2[97*256+46] +57=proba2[97*256+48] +46=proba2[97*256+49] +51=proba2[97*256+50] +59=proba2[97*256+51] +61=proba2[97*256+52] +62=proba2[97*256+53] +60=proba2[97*256+54] +58=proba2[97*256+55] +64=proba2[97*256+56] +55=proba2[97*256+57] +98=proba2[97*256+59] +112=proba2[97*256+60] +98=proba2[97*256+61] +101=proba2[97*256+62] +105=proba2[97*256+63] +105=proba2[97*256+64] +112=proba2[97*256+65] +98=proba2[97*256+66] +92=proba2[97*256+67] +105=proba2[97*256+68] +98=proba2[97*256+70] +98=proba2[97*256+71] +105=proba2[97*256+72] +112=proba2[97*256+73] +105=proba2[97*256+74] +92=proba2[97*256+75] +101=proba2[97*256+76] +88=proba2[97*256+77] +98=proba2[97*256+78] +105=proba2[97*256+79] +85=proba2[97*256+80] +105=proba2[97*256+81] +91=proba2[97*256+82] +94=proba2[97*256+83] +98=proba2[97*256+84] +101=proba2[97*256+86] +112=proba2[97*256+87] +112=proba2[97*256+88] +112=proba2[97*256+90] +112=proba2[97*256+93] +83=proba2[97*256+95] +44=proba2[97*256+97] +32=proba2[97*256+98] +31=proba2[97*256+99] +32=proba2[97*256+100] +45=proba2[97*256+101] +42=proba2[97*256+102] +34=proba2[97*256+103] +45=proba2[97*256+104] +32=proba2[97*256+105] +52=proba2[97*256+106] +41=proba2[97*256+107] +23=proba2[97*256+108] +28=proba2[97*256+109] +18=proba2[97*256+110] +49=proba2[97*256+111] +37=proba2[97*256+112] +57=proba2[97*256+113] +20=proba2[97*256+114] +28=proba2[97*256+115] +27=proba2[97*256+116] +30=proba2[97*256+117] +38=proba2[97*256+118] +52=proba2[97*256+119] +46=proba2[97*256+120] +41=proba2[97*256+121] +40=proba2[97*256+122] +28=proba1[98] +86=proba2[98*256+32] +89=proba2[98*256+33] +99=proba2[98*256+36] +93=proba2[98*256+38] +99=proba2[98*256+40] +99=proba2[98*256+41] +99=proba2[98*256+42] +93=proba2[98*256+43] +99=proba2[98*256+44] +89=proba2[98*256+45] +80=proba2[98*256+46] +52=proba2[98*256+48] +46=proba2[98*256+49] +48=proba2[98*256+50] +54=proba2[98*256+51] +59=proba2[98*256+52] +59=proba2[98*256+53] +56=proba2[98*256+54] +55=proba2[98*256+55] +59=proba2[98*256+56] +55=proba2[98*256+57] +99=proba2[98*256+59] +93=proba2[98*256+61] +99=proba2[98*256+63] +93=proba2[98*256+64] +83=proba2[98*256+65] +93=proba2[98*256+66] +99=proba2[98*256+67] +89=proba2[98*256+68] +99=proba2[98*256+69] +93=proba2[98*256+70] +83=proba2[98*256+71] +86=proba2[98*256+73] +93=proba2[98*256+74] +99=proba2[98*256+75] +93=proba2[98*256+78] +86=proba2[98*256+82] +93=proba2[98*256+83] +93=proba2[98*256+84] +99=proba2[98*256+90] +86=proba2[98*256+95] +18=proba2[98*256+97] +37=proba2[98*256+98] +40=proba2[98*256+99] +41=proba2[98*256+100] +16=proba2[98*256+101] +49=proba2[98*256+102] +49=proba2[98*256+103] +53=proba2[98*256+104] +22=proba2[98*256+105] +51=proba2[98*256+106] +56=proba2[98*256+107] +28=proba2[98*256+108] +45=proba2[98*256+109] +50=proba2[98*256+110] +18=proba2[98*256+111] +50=proba2[98*256+112] +63=proba2[98*256+113] +25=proba2[98*256+114] +40=proba2[98*256+115] +49=proba2[98*256+116] +31=proba2[98*256+117] +54=proba2[98*256+118] +56=proba2[98*256+119] +60=proba2[98*256+120] +40=proba2[98*256+121] +53=proba2[98*256+122] +25=proba1[99] +87=proba2[99*256+32] +81=proba2[99*256+33] +103=proba2[99*256+34] +92=proba2[99*256+36] +103=proba2[99*256+37] +85=proba2[99*256+38] +96=proba2[99*256+39] +89=proba2[99*256+42] +89=proba2[99*256+43] +92=proba2[99*256+44] +85=proba2[99*256+45] +89=proba2[99*256+46] +55=proba2[99*256+48] +45=proba2[99*256+49] +49=proba2[99*256+50] +56=proba2[99*256+51] +60=proba2[99*256+52] +62=proba2[99*256+53] +57=proba2[99*256+54] +60=proba2[99*256+55] +65=proba2[99*256+56] +56=proba2[99*256+57] +96=proba2[99*256+59] +85=proba2[99*256+61] +89=proba2[99*256+64] +89=proba2[99*256+65] +103=proba2[99*256+66] +96=proba2[99*256+67] +103=proba2[99*256+68] +92=proba2[99*256+69] +87=proba2[99*256+70] +87=proba2[99*256+72] +103=proba2[99*256+74] +103=proba2[99*256+75] +103=proba2[99*256+76] +103=proba2[99*256+80] +92=proba2[99*256+81] +103=proba2[99*256+82] +92=proba2[99*256+83] +96=proba2[99*256+84] +92=proba2[99*256+85] +103=proba2[99*256+86] +103=proba2[99*256+88] +87=proba2[99*256+89] +92=proba2[99*256+95] +19=proba2[99*256+97] +44=proba2[99*256+98] +39=proba2[99*256+99] +43=proba2[99*256+100] +24=proba2[99*256+101] +49=proba2[99*256+102] +48=proba2[99*256+103] +16=proba2[99*256+104] +31=proba2[99*256+105] +53=proba2[99*256+106] +28=proba2[99*256+107] +30=proba2[99*256+108] +43=proba2[99*256+109] +50=proba2[99*256+110] +18=proba2[99*256+111] +45=proba2[99*256+112] +50=proba2[99*256+113] +31=proba2[99*256+114] +43=proba2[99*256+115] +37=proba2[99*256+116] +39=proba2[99*256+117] +48=proba2[99*256+118] +58=proba2[99*256+119] +62=proba2[99*256+120] +38=proba2[99*256+121] +62=proba2[99*256+122] +103=proba2[99*256+124] +30=proba1[100] +100=proba2[100*256+32] +76=proba2[100*256+33] +86=proba2[100*256+35] +100=proba2[100*256+37] +86=proba2[100*256+38] +84=proba2[100*256+39] +86=proba2[100*256+42] +100=proba2[100*256+43] +79=proba2[100*256+45] +84=proba2[100*256+46] +49=proba2[100*256+48] +43=proba2[100*256+49] +47=proba2[100*256+50] +53=proba2[100*256+51] +55=proba2[100*256+52] +57=proba2[100*256+53] +54=proba2[100*256+54] +54=proba2[100*256+55] +61=proba2[100*256+56] +53=proba2[100*256+57] +89=proba2[100*256+59] +100=proba2[100*256+61] +100=proba2[100*256+64] +93=proba2[100*256+65] +93=proba2[100*256+66] +100=proba2[100*256+68] +84=proba2[100*256+69] +100=proba2[100*256+70] +93=proba2[100*256+71] +93=proba2[100*256+72] +100=proba2[100*256+73] +100=proba2[100*256+76] +84=proba2[100*256+77] +93=proba2[100*256+78] +100=proba2[100*256+79] +89=proba2[100*256+80] +100=proba2[100*256+81] +100=proba2[100*256+82] +93=proba2[100*256+83] +100=proba2[100*256+84] +93=proba2[100*256+85] +100=proba2[100*256+86] +93=proba2[100*256+87] +100=proba2[100*256+89] +89=proba2[100*256+90] +86=proba2[100*256+95] +20=proba2[100*256+97] +41=proba2[100*256+98] +41=proba2[100*256+99] +38=proba2[100*256+100] +15=proba2[100*256+101] +43=proba2[100*256+102] +43=proba2[100*256+103] +46=proba2[100*256+104] +21=proba2[100*256+105] +36=proba2[100*256+106] +52=proba2[100*256+107] +41=proba2[100*256+108] +40=proba2[100*256+109] +48=proba2[100*256+110] +21=proba2[100*256+111] +45=proba2[100*256+112] +64=proba2[100*256+113] +26=proba2[100*256+114] +38=proba2[100*256+115] +47=proba2[100*256+116] +29=proba2[100*256+117] +49=proba2[100*256+118] +50=proba2[100*256+119] +57=proba2[100*256+120] +37=proba2[100*256+121] +53=proba2[100*256+122] +36=proba1[101] +75=proba2[101*256+32] +82=proba2[101*256+33] +91=proba2[101*256+35] +91=proba2[101*256+36] +110=proba2[101*256+37] +89=proba2[101*256+38] +103=proba2[101*256+39] +103=proba2[101*256+40] +103=proba2[101*256+41] +84=proba2[101*256+42] +92=proba2[101*256+43] +96=proba2[101*256+44] +78=proba2[101*256+45] +87=proba2[101*256+46] +54=proba2[101*256+48] +42=proba2[101*256+49] +47=proba2[101*256+50] +54=proba2[101*256+51] +58=proba2[101*256+52] +58=proba2[101*256+53] +56=proba2[101*256+54] +54=proba2[101*256+55] +61=proba2[101*256+56] +52=proba2[101*256+57] +103=proba2[101*256+59] +92=proba2[101*256+61] +103=proba2[101*256+63] +91=proba2[101*256+64] +103=proba2[101*256+65] +92=proba2[101*256+66] +92=proba2[101*256+67] +89=proba2[101*256+68] +110=proba2[101*256+69] +99=proba2[101*256+70] +99=proba2[101*256+71] +99=proba2[101*256+72] +110=proba2[101*256+73] +103=proba2[101*256+74] +92=proba2[101*256+75] +91=proba2[101*256+76] +92=proba2[101*256+77] +96=proba2[101*256+78] +110=proba2[101*256+79] +110=proba2[101*256+80] +103=proba2[101*256+81] +87=proba2[101*256+82] +87=proba2[101*256+83] +94=proba2[101*256+84] +92=proba2[101*256+85] +103=proba2[101*256+86] +99=proba2[101*256+87] +96=proba2[101*256+88] +110=proba2[101*256+89] +94=proba2[101*256+90] +110=proba2[101*256+93] +103=proba2[101*256+94] +83=proba2[101*256+95] +32=proba2[101*256+97] +33=proba2[101*256+98] +33=proba2[101*256+99] +32=proba2[101*256+100] +38=proba2[101*256+101] +41=proba2[101*256+102] +38=proba2[101*256+103] +51=proba2[101*256+104] +40=proba2[101*256+105] +53=proba2[101*256+106] +47=proba2[101*256+107] +22=proba2[101*256+108] +33=proba2[101*256+109] +23=proba2[101*256+110] +44=proba2[101*256+111] +38=proba2[101*256+112] +62=proba2[101*256+113] +16=proba2[101*256+114] +25=proba2[101*256+115] +26=proba2[101*256+116] +35=proba2[101*256+117] +39=proba2[101*256+118] +49=proba2[101*256+119] +41=proba2[101*256+120] +43=proba2[101*256+121] +45=proba2[101*256+122] +110=proba2[101*256+126] +31=proba1[102] +84=proba2[102*256+32] +74=proba2[102*256+33] +88=proba2[102*256+38] +88=proba2[102*256+41] +95=proba2[102*256+42] +84=proba2[102*256+44] +84=proba2[102*256+45] +81=proba2[102*256+46] +52=proba2[102*256+48] +41=proba2[102*256+49] +46=proba2[102*256+50] +54=proba2[102*256+51] +53=proba2[102*256+52] +52=proba2[102*256+53] +53=proba2[102*256+54] +53=proba2[102*256+55] +57=proba2[102*256+56] +52=proba2[102*256+57] +88=proba2[102*256+64] +84=proba2[102*256+65] +84=proba2[102*256+66] +88=proba2[102*256+67] +88=proba2[102*256+68] +95=proba2[102*256+69] +95=proba2[102*256+70] +88=proba2[102*256+72] +95=proba2[102*256+73] +95=proba2[102*256+74] +95=proba2[102*256+75] +95=proba2[102*256+76] +81=proba2[102*256+78] +95=proba2[102*256+80] +95=proba2[102*256+84] +95=proba2[102*256+85] +88=proba2[102*256+86] +95=proba2[102*256+87] +88=proba2[102*256+90] +81=proba2[102*256+95] +20=proba2[102*256+97] +41=proba2[102*256+98] +40=proba2[102*256+99] +42=proba2[102*256+100] +25=proba2[102*256+101] +28=proba2[102*256+102] +40=proba2[102*256+103] +52=proba2[102*256+104] +24=proba2[102*256+105] +50=proba2[102*256+106] +51=proba2[102*256+107] +26=proba2[102*256+108] +40=proba2[102*256+109] +50=proba2[102*256+110] +22=proba2[102*256+111] +43=proba2[102*256+112] +64=proba2[102*256+113] +17=proba2[102*256+114] +40=proba2[102*256+115] +35=proba2[102*256+116] +31=proba2[102*256+117] +51=proba2[102*256+118] +54=proba2[102*256+119] +48=proba2[102*256+120] +48=proba2[102*256+121] +59=proba2[102*256+122] +32=proba1[103] +86=proba2[103*256+32] +81=proba2[103*256+33] +97=proba2[103*256+35] +90=proba2[103*256+36] +97=proba2[103*256+38] +83=proba2[103*256+39] +97=proba2[103*256+42] +90=proba2[103*256+43] +83=proba2[103*256+45] +90=proba2[103*256+46] +55=proba2[103*256+48] +46=proba2[103*256+49] +49=proba2[103*256+50] +56=proba2[103*256+51] +59=proba2[103*256+52] +57=proba2[103*256+53] +56=proba2[103*256+54] +56=proba2[103*256+55] +61=proba2[103*256+56] +56=proba2[103*256+57] +97=proba2[103*256+59] +97=proba2[103*256+60] +86=proba2[103*256+64] +81=proba2[103*256+65] +83=proba2[103*256+66] +97=proba2[103*256+67] +97=proba2[103*256+68] +86=proba2[103*256+69] +97=proba2[103*256+70] +97=proba2[103*256+71] +90=proba2[103*256+72] +97=proba2[103*256+74] +97=proba2[103*256+75] +97=proba2[103*256+76] +90=proba2[103*256+78] +90=proba2[103*256+79] +83=proba2[103*256+80] +97=proba2[103*256+84] +97=proba2[103*256+86] +83=proba2[103*256+87] +90=proba2[103*256+90] +97=proba2[103*256+94] +86=proba2[103*256+95] +18=proba2[103*256+97] +41=proba2[103*256+98] +46=proba2[103*256+99] +43=proba2[103*256+100] +18=proba2[103*256+101] +48=proba2[103*256+102] +38=proba2[103*256+103] +35=proba2[103*256+104] +24=proba2[103*256+105] +55=proba2[103*256+106] +54=proba2[103*256+107] +32=proba2[103*256+108] +42=proba2[103*256+109] +32=proba2[103*256+110] +21=proba2[103*256+111] +45=proba2[103*256+112] +67=proba2[103*256+113] +25=proba2[103*256+114] +41=proba2[103*256+115] +45=proba2[103*256+116] +23=proba2[103*256+117] +55=proba2[103*256+118] +47=proba2[103*256+119] +61=proba2[103*256+120] +43=proba2[103*256+121] +57=proba2[103*256+122] +38=proba1[104] +79=proba2[104*256+32] +90=proba2[104*256+33] +97=proba2[104*256+39] +97=proba2[104*256+42] +90=proba2[104*256+45] +84=proba2[104*256+46] +53=proba2[104*256+48] +47=proba2[104*256+49] +49=proba2[104*256+50] +56=proba2[104*256+51] +58=proba2[104*256+52] +59=proba2[104*256+53] +56=proba2[104*256+54] +55=proba2[104*256+55] +60=proba2[104*256+56] +55=proba2[104*256+57] +97=proba2[104*256+59] +97=proba2[104*256+60] +97=proba2[104*256+61] +86=proba2[104*256+64] +86=proba2[104*256+65] +86=proba2[104*256+66] +90=proba2[104*256+67] +97=proba2[104*256+68] +81=proba2[104*256+71] +97=proba2[104*256+74] +97=proba2[104*256+75] +97=proba2[104*256+79] +97=proba2[104*256+80] +97=proba2[104*256+81] +97=proba2[104*256+82] +86=proba2[104*256+83] +81=proba2[104*256+84] +97=proba2[104*256+87] +86=proba2[104*256+88] +84=proba2[104*256+89] +90=proba2[104*256+95] +14=proba2[104*256+97] +45=proba2[104*256+98] +47=proba2[104*256+99] +47=proba2[104*256+100] +16=proba2[104*256+101] +54=proba2[104*256+102] +53=proba2[104*256+103] +54=proba2[104*256+104] +19=proba2[104*256+105] +56=proba2[104*256+106] +54=proba2[104*256+107] +41=proba2[104*256+108] +42=proba2[104*256+109] +41=proba2[104*256+110] +20=proba2[104*256+111] +47=proba2[104*256+112] +59=proba2[104*256+113] +32=proba2[104*256+114] +48=proba2[104*256+115] +39=proba2[104*256+116] +31=proba2[104*256+117] +58=proba2[104*256+118] +56=proba2[104*256+119] +57=proba2[104*256+120] +39=proba2[104*256+121] +59=proba2[104*256+122] +42=proba1[105] +95=proba2[105*256+32] +90=proba2[105*256+33] +108=proba2[105*256+36] +97=proba2[105*256+38] +108=proba2[105*256+39] +108=proba2[105*256+41] +95=proba2[105*256+42] +92=proba2[105*256+43] +108=proba2[105*256+44] +81=proba2[105*256+45] +88=proba2[105*256+46] +59=proba2[105*256+48] +50=proba2[105*256+49] +54=proba2[105*256+50] +61=proba2[105*256+51] +65=proba2[105*256+52] +64=proba2[105*256+53] +62=proba2[105*256+54] +60=proba2[105*256+55] +66=proba2[105*256+56] +58=proba2[105*256+57] +101=proba2[105*256+59] +101=proba2[105*256+61] +101=proba2[105*256+63] +97=proba2[105*256+64] +95=proba2[105*256+65] +101=proba2[105*256+66] +97=proba2[105*256+67] +97=proba2[105*256+68] +97=proba2[105*256+69] +108=proba2[105*256+70] +90=proba2[105*256+71] +101=proba2[105*256+75] +92=proba2[105*256+76] +95=proba2[105*256+77] +90=proba2[105*256+78] +108=proba2[105*256+79] +95=proba2[105*256+80] +95=proba2[105*256+82] +108=proba2[105*256+83] +92=proba2[105*256+84] +108=proba2[105*256+86] +108=proba2[105*256+89] +108=proba2[105*256+90] +90=proba2[105*256+95] +30=proba2[105*256+97] +38=proba2[105*256+98] +24=proba2[105*256+99] +33=proba2[105*256+100] +22=proba2[105*256+101] +43=proba2[105*256+102] +35=proba2[105*256+103] +57=proba2[105*256+104] +54=proba2[105*256+105] +56=proba2[105*256+106] +38=proba2[105*256+107] +24=proba2[105*256+108] +32=proba2[105*256+109] +18=proba2[105*256+110] +32=proba2[105*256+111] +39=proba2[105*256+112] +50=proba2[105*256+113] +30=proba2[105*256+114] +24=proba2[105*256+115] +28=proba2[105*256+116] +50=proba2[105*256+117] +39=proba2[105*256+118] +59=proba2[105*256+119] +45=proba2[105*256+120] +65=proba2[105*256+121] +44=proba2[105*256+122] +108=proba2[105*256+123] +108=proba2[105*256+124] +32=proba1[106] +91=proba2[106*256+33] +91=proba2[106*256+36] +84=proba2[106*256+38] +84=proba2[106*256+39] +91=proba2[106*256+43] +80=proba2[106*256+44] +80=proba2[106*256+45] +80=proba2[106*256+46] +62=proba2[106*256+48] +48=proba2[106*256+49] +50=proba2[106*256+50] +57=proba2[106*256+51] +56=proba2[106*256+52] +58=proba2[106*256+53] +57=proba2[106*256+54] +56=proba2[106*256+55] +62=proba2[106*256+56] +57=proba2[106*256+57] +84=proba2[106*256+63] +84=proba2[106*256+64] +84=proba2[106*256+65] +91=proba2[106*256+68] +91=proba2[106*256+69] +91=proba2[106*256+70] +84=proba2[106*256+75] +91=proba2[106*256+77] +91=proba2[106*256+80] +80=proba2[106*256+81] +84=proba2[106*256+85] +84=proba2[106*256+87] +91=proba2[106*256+89] +84=proba2[106*256+95] +19=proba2[106*256+97] +35=proba2[106*256+98] +31=proba2[106*256+99] +38=proba2[106*256+100] +19=proba2[106*256+101] +36=proba2[106*256+102] +43=proba2[106*256+103] +48=proba2[106*256+104] +30=proba2[106*256+105] +39=proba2[106*256+106] +44=proba2[106*256+107] +35=proba2[106*256+108] +32=proba2[106*256+109] +46=proba2[106*256+110] +18=proba2[106*256+111] +30=proba2[106*256+112] +64=proba2[106*256+113] +41=proba2[106*256+114] +40=proba2[106*256+115] +44=proba2[106*256+116] +22=proba2[106*256+117] +48=proba2[106*256+118] +56=proba2[106*256+119] +61=proba2[106*256+120] +47=proba2[106*256+121] +59=proba2[106*256+122] +91=proba2[106*256+123] +37=proba1[107] +78=proba2[107*256+32] +78=proba2[107*256+33] +92=proba2[107*256+34] +92=proba2[107*256+36] +76=proba2[107*256+38] +92=proba2[107*256+39] +92=proba2[107*256+41] +92=proba2[107*256+42] +92=proba2[107*256+44] +76=proba2[107*256+45] +76=proba2[107*256+46] +50=proba2[107*256+48] +41=proba2[107*256+49] +45=proba2[107*256+50] +52=proba2[107*256+51] +55=proba2[107*256+52] +57=proba2[107*256+53] +51=proba2[107*256+54] +50=proba2[107*256+55] +50=proba2[107*256+56] +49=proba2[107*256+57] +92=proba2[107*256+59] +92=proba2[107*256+63] +81=proba2[107*256+64] +85=proba2[107*256+65] +92=proba2[107*256+68] +92=proba2[107*256+69] +92=proba2[107*256+70] +78=proba2[107*256+71] +92=proba2[107*256+72] +92=proba2[107*256+77] +92=proba2[107*256+78] +74=proba2[107*256+80] +85=proba2[107*256+81] +92=proba2[107*256+82] +81=proba2[107*256+84] +85=proba2[107*256+85] +92=proba2[107*256+87] +92=proba2[107*256+88] +92=proba2[107*256+95] +16=proba2[107*256+97] +45=proba2[107*256+98] +44=proba2[107*256+99] +46=proba2[107*256+100] +19=proba2[107*256+101] +47=proba2[107*256+102] +50=proba2[107*256+103] +35=proba2[107*256+104] +18=proba2[107*256+105] +50=proba2[107*256+106] +39=proba2[107*256+107] +36=proba2[107*256+108] +41=proba2[107*256+109] +43=proba2[107*256+110] +23=proba2[107*256+111] +46=proba2[107*256+112] +66=proba2[107*256+113] +32=proba2[107*256+114] +36=proba2[107*256+115] +44=proba2[107*256+116] +34=proba2[107*256+117] +58=proba2[107*256+118] +46=proba2[107*256+119] +63=proba2[107*256+120] +30=proba2[107*256+121] +50=proba2[107*256+122] +30=proba1[108] +92=proba2[108*256+32] +85=proba2[108*256+33] +106=proba2[108*256+35] +95=proba2[108*256+36] +83=proba2[108*256+38] +106=proba2[108*256+39] +106=proba2[108*256+40] +106=proba2[108*256+41] +95=proba2[108*256+42] +106=proba2[108*256+43] +86=proba2[108*256+44] +83=proba2[108*256+45] +83=proba2[108*256+46] +53=proba2[108*256+48] +47=proba2[108*256+49] +52=proba2[108*256+50] +57=proba2[108*256+51] +63=proba2[108*256+52] +62=proba2[108*256+53] +59=proba2[108*256+54] +60=proba2[108*256+55] +63=proba2[108*256+56] +55=proba2[108*256+57] +95=proba2[108*256+59] +106=proba2[108*256+61] +86=proba2[108*256+64] +86=proba2[108*256+65] +90=proba2[108*256+66] +95=proba2[108*256+67] +99=proba2[108*256+68] +88=proba2[108*256+69] +106=proba2[108*256+70] +99=proba2[108*256+71] +99=proba2[108*256+75] +106=proba2[108*256+76] +95=proba2[108*256+77] +106=proba2[108*256+78] +99=proba2[108*256+79] +92=proba2[108*256+80] +99=proba2[108*256+82] +90=proba2[108*256+84] +92=proba2[108*256+85] +106=proba2[108*256+86] +106=proba2[108*256+87] +106=proba2[108*256+88] +99=proba2[108*256+89] +106=proba2[108*256+90] +86=proba2[108*256+95] +18=proba2[108*256+97] +42=proba2[108*256+98] +43=proba2[108*256+99] +36=proba2[108*256+100] +16=proba2[108*256+101] +43=proba2[108*256+102] +47=proba2[108*256+103] +50=proba2[108*256+104] +19=proba2[108*256+105] +56=proba2[108*256+106] +49=proba2[108*256+107] +22=proba2[108*256+108] +41=proba2[108*256+109] +53=proba2[108*256+110] +20=proba2[108*256+111] +41=proba2[108*256+112] +74=proba2[108*256+113] +50=proba2[108*256+114] +41=proba2[108*256+115] +39=proba2[108*256+116] +31=proba2[108*256+117] +44=proba2[108*256+118] +59=proba2[108*256+119] +63=proba2[108*256+120] +37=proba2[108*256+121] +60=proba2[108*256+122] +25=proba1[109] +83=proba2[109*256+32] +84=proba2[109*256+33] +102=proba2[109*256+34] +102=proba2[109*256+35] +91=proba2[109*256+36] +102=proba2[109*256+37] +88=proba2[109*256+38] +88=proba2[109*256+39] +95=proba2[109*256+41] +86=proba2[109*256+42] +88=proba2[109*256+43] +88=proba2[109*256+44] +83=proba2[109*256+45] +79=proba2[109*256+46] +54=proba2[109*256+48] +45=proba2[109*256+49] +49=proba2[109*256+50] +57=proba2[109*256+51] +60=proba2[109*256+52] +59=proba2[109*256+53] +60=proba2[109*256+54] +58=proba2[109*256+55] +61=proba2[109*256+56] +54=proba2[109*256+57] +91=proba2[109*256+59] +102=proba2[109*256+60] +91=proba2[109*256+61] +95=proba2[109*256+63] +81=proba2[109*256+64] +88=proba2[109*256+65] +102=proba2[109*256+66] +102=proba2[109*256+67] +95=proba2[109*256+68] +102=proba2[109*256+70] +95=proba2[109*256+71] +91=proba2[109*256+72] +102=proba2[109*256+74] +102=proba2[109*256+76] +91=proba2[109*256+77] +102=proba2[109*256+78] +102=proba2[109*256+80] +102=proba2[109*256+81] +95=proba2[109*256+84] +95=proba2[109*256+85] +95=proba2[109*256+86] +102=proba2[109*256+88] +102=proba2[109*256+89] +91=proba2[109*256+95] +12=proba2[109*256+97] +34=proba2[109*256+98] +41=proba2[109*256+99] +45=proba2[109*256+100] +20=proba2[109*256+101] +50=proba2[109*256+102] +49=proba2[109*256+103] +53=proba2[109*256+104] +20=proba2[109*256+105] +51=proba2[109*256+106] +55=proba2[109*256+107] +44=proba2[109*256+108] +35=proba2[109*256+109] +50=proba2[109*256+110] +20=proba2[109*256+111] +33=proba2[109*256+112] +67=proba2[109*256+113] +46=proba2[109*256+114] +39=proba2[109*256+115] +47=proba2[109*256+116] +34=proba2[109*256+117] +57=proba2[109*256+118] +60=proba2[109*256+119] +60=proba2[109*256+120] +35=proba2[109*256+121] +59=proba2[109*256+122] +102=proba2[109*256+125] +35=proba1[110] +86=proba2[110*256+32] +84=proba2[110*256+33] +94=proba2[110*256+35] +94=proba2[110*256+36] +105=proba2[110*256+37] +84=proba2[110*256+38] +91=proba2[110*256+39] +105=proba2[110*256+40] +105=proba2[110*256+41] +79=proba2[110*256+42] +87=proba2[110*256+43] +87=proba2[110*256+44] +77=proba2[110*256+45] +87=proba2[110*256+46] +51=proba2[110*256+48] +42=proba2[110*256+49] +47=proba2[110*256+50] +56=proba2[110*256+51] +61=proba2[110*256+52] +60=proba2[110*256+53] +54=proba2[110*256+54] +56=proba2[110*256+55] +62=proba2[110*256+56] +55=proba2[110*256+57] +91=proba2[110*256+59] +105=proba2[110*256+61] +98=proba2[110*256+63] +86=proba2[110*256+64] +86=proba2[110*256+65] +98=proba2[110*256+66] +105=proba2[110*256+67] +91=proba2[110*256+68] +98=proba2[110*256+69] +105=proba2[110*256+70] +89=proba2[110*256+71] +105=proba2[110*256+72] +84=proba2[110*256+73] +98=proba2[110*256+74] +105=proba2[110*256+75] +98=proba2[110*256+76] +98=proba2[110*256+77] +91=proba2[110*256+79] +98=proba2[110*256+80] +98=proba2[110*256+82] +83=proba2[110*256+83] +105=proba2[110*256+84] +105=proba2[110*256+85] +105=proba2[110*256+87] +89=proba2[110*256+89] +94=proba2[110*256+90] +105=proba2[110*256+94] +84=proba2[110*256+95] +22=proba2[110*256+97] +45=proba2[110*256+98] +30=proba2[110*256+99] +26=proba2[110*256+100] +17=proba2[110*256+101] +43=proba2[110*256+102] +29=proba2[110*256+103] +50=proba2[110*256+104] +22=proba2[110*256+105] +45=proba2[110*256+106] +41=proba2[110*256+107] +48=proba2[110*256+108] +48=proba2[110*256+109] +30=proba2[110*256+110] +24=proba2[110*256+111] +48=proba2[110*256+112] +64=proba2[110*256+113] +48=proba2[110*256+114] +33=proba2[110*256+115] +25=proba2[110*256+116] +39=proba2[110*256+117] +54=proba2[110*256+118] +58=proba2[110*256+119] +60=proba2[110*256+120] +40=proba2[110*256+121] +47=proba2[110*256+122] +105=proba2[110*256+125] +41=proba1[111] +90=proba2[111*256+32] +85=proba2[111*256+33] +108=proba2[111*256+35] +97=proba2[111*256+36] +108=proba2[111*256+37] +101=proba2[111*256+38] +101=proba2[111*256+39] +108=proba2[111*256+40] +89=proba2[111*256+42] +90=proba2[111*256+43] +94=proba2[111*256+44] +89=proba2[111*256+45] +83=proba2[111*256+46] +55=proba2[111*256+48] +45=proba2[111*256+49] +50=proba2[111*256+50] +57=proba2[111*256+51] +61=proba2[111*256+52] +62=proba2[111*256+53] +59=proba2[111*256+54] +56=proba2[111*256+55] +64=proba2[111*256+56] +55=proba2[111*256+57] +94=proba2[111*256+59] +97=proba2[111*256+61] +108=proba2[111*256+62] +108=proba2[111*256+63] +97=proba2[111*256+64] +92=proba2[111*256+66] +94=proba2[111*256+67] +108=proba2[111*256+68] +108=proba2[111*256+69] +94=proba2[111*256+70] +94=proba2[111*256+71] +108=proba2[111*256+72] +101=proba2[111*256+73] +97=proba2[111*256+74] +101=proba2[111*256+76] +97=proba2[111*256+77] +101=proba2[111*256+78] +94=proba2[111*256+80] +101=proba2[111*256+81] +92=proba2[111*256+82] +89=proba2[111*256+83] +89=proba2[111*256+84] +92=proba2[111*256+85] +101=proba2[111*256+88] +108=proba2[111*256+90] +92=proba2[111*256+95] +46=proba2[111*256+97] +36=proba2[111*256+98] +34=proba2[111*256+99] +36=proba2[111*256+100] +44=proba2[111*256+101] +41=proba2[111*256+102] +39=proba2[111*256+103] +47=proba2[111*256+104] +33=proba2[111*256+105] +53=proba2[111*256+106] +42=proba2[111*256+107] +25=proba2[111*256+108] +29=proba2[111*256+109] +19=proba2[111*256+110] +33=proba2[111*256+111] +34=proba2[111*256+112] +60=proba2[111*256+113] +23=proba2[111*256+114] +31=proba2[111*256+115] +30=proba2[111*256+116] +17=proba2[111*256+117] +42=proba2[111*256+118] +43=proba2[111*256+119] +48=proba2[111*256+120] +42=proba2[111*256+121] +48=proba2[111*256+122] +28=proba1[112] +92=proba2[112*256+32] +76=proba2[112*256+33] +85=proba2[112*256+36] +88=proba2[112*256+38] +85=proba2[112*256+43] +88=proba2[112*256+44] +85=proba2[112*256+45] +78=proba2[112*256+46] +55=proba2[112*256+48] +47=proba2[112*256+49] +49=proba2[112*256+50] +51=proba2[112*256+51] +58=proba2[112*256+52] +58=proba2[112*256+53] +58=proba2[112*256+54] +56=proba2[112*256+55] +65=proba2[112*256+56] +55=proba2[112*256+57] +92=proba2[112*256+59] +99=proba2[112*256+61] +99=proba2[112*256+63] +92=proba2[112*256+64] +85=proba2[112*256+67] +99=proba2[112*256+68] +99=proba2[112*256+69] +99=proba2[112*256+71] +92=proba2[112*256+72] +92=proba2[112*256+73] +99=proba2[112*256+75] +99=proba2[112*256+76] +88=proba2[112*256+77] +85=proba2[112*256+78] +92=proba2[112*256+79] +88=proba2[112*256+80] +88=proba2[112*256+82] +92=proba2[112*256+83] +83=proba2[112*256+84] +99=proba2[112*256+86] +99=proba2[112*256+87] +85=proba2[112*256+89] +99=proba2[112*256+90] +83=proba2[112*256+95] +17=proba2[112*256+97] +45=proba2[112*256+98] +40=proba2[112*256+99] +48=proba2[112*256+100] +20=proba2[112*256+101] +47=proba2[112*256+102] +48=proba2[112*256+103] +23=proba2[112*256+104] +21=proba2[112*256+105] +51=proba2[112*256+106] +53=proba2[112*256+107] +31=proba2[112*256+108] +42=proba2[112*256+109] +52=proba2[112*256+110] +21=proba2[112*256+111] +34=proba2[112*256+112] +60=proba2[112*256+113] +28=proba2[112*256+114] +33=proba2[112*256+115] +38=proba2[112*256+116] +36=proba2[112*256+117] +52=proba2[112*256+118] +54=proba2[112*256+119] +63=proba2[112*256+120] +39=proba2[112*256+121] +58=proba2[112*256+122] +54=proba1[113] +77=proba2[113*256+32] +77=proba2[113*256+44] +70=proba2[113*256+45] +70=proba2[113*256+46] +61=proba2[113*256+48] +39=proba2[113*256+49] +42=proba2[113*256+50] +50=proba2[113*256+51] +52=proba2[113*256+52] +45=proba2[113*256+53] +50=proba2[113*256+54] +46=proba2[113*256+55] +54=proba2[113*256+56] +44=proba2[113*256+57] +77=proba2[113*256+66] +77=proba2[113*256+68] +66=proba2[113*256+69] +77=proba2[113*256+70] +77=proba2[113*256+72] +77=proba2[113*256+74] +77=proba2[113*256+75] +77=proba2[113*256+79] +70=proba2[113*256+80] +77=proba2[113*256+81] +77=proba2[113*256+82] +66=proba2[113*256+83] +77=proba2[113*256+84] +77=proba2[113*256+85] +70=proba2[113*256+87] +70=proba2[113*256+88] +63=proba2[113*256+90] +35=proba2[113*256+97] +41=proba2[113*256+98] +37=proba2[113*256+99] +43=proba2[113*256+100] +44=proba2[113*256+101] +42=proba2[113*256+102] +50=proba2[113*256+103] +50=proba2[113*256+104] +43=proba2[113*256+105] +46=proba2[113*256+106] +52=proba2[113*256+107] +48=proba2[113*256+108] +41=proba2[113*256+109] +48=proba2[113*256+110] +53=proba2[113*256+111] +41=proba2[113*256+112] +40=proba2[113*256+113] +43=proba2[113*256+114] +35=proba2[113*256+115] +41=proba2[113*256+116] +6=proba2[113*256+117] +45=proba2[113*256+118] +30=proba2[113*256+119] +49=proba2[113*256+120] +53=proba2[113*256+121] +46=proba2[113*256+122] +34=proba1[114] +88=proba2[114*256+32] +82=proba2[114*256+33] +100=proba2[114*256+35] +89=proba2[114*256+36] +107=proba2[114*256+37] +88=proba2[114*256+38] +107=proba2[114*256+39] +100=proba2[114*256+41] +89=proba2[114*256+42] +89=proba2[114*256+43] +107=proba2[114*256+44] +84=proba2[114*256+45] +84=proba2[114*256+46] +56=proba2[114*256+48] +45=proba2[114*256+49] +50=proba2[114*256+50] +58=proba2[114*256+51] +60=proba2[114*256+52] +60=proba2[114*256+53] +59=proba2[114*256+54] +57=proba2[114*256+55] +62=proba2[114*256+56] +56=proba2[114*256+57] +107=proba2[114*256+59] +107=proba2[114*256+61] +107=proba2[114*256+63] +83=proba2[114*256+64] +107=proba2[114*256+65] +100=proba2[114*256+66] +107=proba2[114*256+67] +107=proba2[114*256+68] +100=proba2[114*256+69] +100=proba2[114*256+70] +100=proba2[114*256+71] +100=proba2[114*256+72] +100=proba2[114*256+73] +107=proba2[114*256+74] +96=proba2[114*256+75] +96=proba2[114*256+76] +93=proba2[114*256+77] +107=proba2[114*256+78] +100=proba2[114*256+79] +100=proba2[114*256+80] +96=proba2[114*256+81] +107=proba2[114*256+82] +89=proba2[114*256+83] +96=proba2[114*256+84] +96=proba2[114*256+85] +100=proba2[114*256+86] +107=proba2[114*256+87] +107=proba2[114*256+91] +96=proba2[114*256+95] +20=proba2[114*256+97] +41=proba2[114*256+98] +35=proba2[114*256+99] +30=proba2[114*256+100] +18=proba2[114*256+101] +45=proba2[114*256+102] +37=proba2[114*256+103] +54=proba2[114*256+104] +19=proba2[114*256+105] +56=proba2[114*256+106] +44=proba2[114*256+107] +38=proba2[114*256+108] +39=proba2[114*256+109] +36=proba2[114*256+110] +21=proba2[114*256+111] +44=proba2[114*256+112] +62=proba2[114*256+113] +35=proba2[114*256+114] +35=proba2[114*256+115] +28=proba2[114*256+116] +35=proba2[114*256+117] +46=proba2[114*256+118] +54=proba2[114*256+119] +66=proba2[114*256+120] +39=proba2[114*256+121] +57=proba2[114*256+122] +96=proba2[114*256+125] +26=proba1[115] +84=proba2[115*256+32] +84=proba2[115*256+33] +93=proba2[115*256+35] +93=proba2[115*256+36] +90=proba2[115*256+37] +86=proba2[115*256+38] +104=proba2[115*256+39] +104=proba2[115*256+41] +86=proba2[115*256+42] +84=proba2[115*256+43] +90=proba2[115*256+44] +83=proba2[115*256+45] +79=proba2[115*256+46] +50=proba2[115*256+48] +41=proba2[115*256+49] +45=proba2[115*256+50] +54=proba2[115*256+51] +56=proba2[115*256+52] +55=proba2[115*256+53] +55=proba2[115*256+54] +53=proba2[115*256+55] +59=proba2[115*256+56] +51=proba2[115*256+57] +104=proba2[115*256+59] +104=proba2[115*256+60] +104=proba2[115*256+61] +97=proba2[115*256+63] +88=proba2[115*256+64] +97=proba2[115*256+65] +104=proba2[115*256+66] +104=proba2[115*256+67] +83=proba2[115*256+68] +104=proba2[115*256+69] +93=proba2[115*256+70] +104=proba2[115*256+71] +97=proba2[115*256+72] +97=proba2[115*256+73] +104=proba2[115*256+75] +104=proba2[115*256+76] +86=proba2[115*256+77] +97=proba2[115*256+81] +97=proba2[115*256+82] +104=proba2[115*256+83] +97=proba2[115*256+84] +104=proba2[115*256+86] +104=proba2[115*256+87] +104=proba2[115*256+89] +81=proba2[115*256+95] +104=proba2[115*256+96] +22=proba2[115*256+97] +43=proba2[115*256+98] +30=proba2[115*256+99] +43=proba2[115*256+100] +21=proba2[115*256+101] +48=proba2[115*256+102] +47=proba2[115*256+103] +33=proba2[115*256+104] +25=proba2[115*256+105] +54=proba2[115*256+106] +38=proba2[115*256+107] +40=proba2[115*256+108] +37=proba2[115*256+109] +41=proba2[115*256+110] +26=proba2[115*256+111] +33=proba2[115*256+112] +53=proba2[115*256+113] +48=proba2[115*256+114] +23=proba2[115*256+115] +19=proba2[115*256+116] +34=proba2[115*256+117] +53=proba2[115*256+118] +46=proba2[115*256+119] +56=proba2[115*256+120] +37=proba2[115*256+121] +60=proba2[115*256+122] +31=proba1[116] +87=proba2[116*256+32] +77=proba2[116*256+33] +92=proba2[116*256+36] +83=proba2[116*256+38] +92=proba2[116*256+39] +90=proba2[116*256+42] +97=proba2[116*256+43] +103=proba2[116*256+44] +79=proba2[116*256+45] +90=proba2[116*256+46] +54=proba2[116*256+48] +44=proba2[116*256+49] +48=proba2[116*256+50] +56=proba2[116*256+51] +57=proba2[116*256+52] +60=proba2[116*256+53] +57=proba2[116*256+54] +57=proba2[116*256+55] +61=proba2[116*256+56] +54=proba2[116*256+57] +103=proba2[116*256+59] +97=proba2[116*256+61] +86=proba2[116*256+64] +87=proba2[116*256+65] +92=proba2[116*256+66] +97=proba2[116*256+68] +92=proba2[116*256+69] +103=proba2[116*256+71] +103=proba2[116*256+72] +97=proba2[116*256+73] +97=proba2[116*256+74] +103=proba2[116*256+76] +90=proba2[116*256+77] +92=proba2[116*256+78] +97=proba2[116*256+79] +103=proba2[116*256+80] +103=proba2[116*256+81] +87=proba2[116*256+82] +92=proba2[116*256+84] +103=proba2[116*256+85] +103=proba2[116*256+86] +97=proba2[116*256+88] +92=proba2[116*256+89] +81=proba2[116*256+95] +21=proba2[116*256+97] +46=proba2[116*256+98] +38=proba2[116*256+99] +48=proba2[116*256+100] +17=proba2[116*256+101] +50=proba2[116*256+102] +51=proba2[116*256+103] +24=proba2[116*256+104] +21=proba2[116*256+105] +55=proba2[116*256+106] +58=proba2[116*256+107] +43=proba2[116*256+108] +42=proba2[116*256+109] +47=proba2[116*256+110] +20=proba2[116*256+111] +47=proba2[116*256+112] +67=proba2[116*256+113] +25=proba2[116*256+114] +37=proba2[116*256+115] +29=proba2[116*256+116] +34=proba2[116*256+117] +54=proba2[116*256+118] +49=proba2[116*256+119] +60=proba2[116*256+120] +37=proba2[116*256+121] +48=proba2[116*256+122] +103=proba2[116*256+124] +51=proba1[117] +102=proba2[117*256+32] +81=proba2[117*256+33] +95=proba2[117*256+35] +91=proba2[117*256+36] +102=proba2[117*256+37] +88=proba2[117*256+38] +102=proba2[117*256+40] +86=proba2[117*256+42] +102=proba2[117*256+43] +95=proba2[117*256+44] +81=proba2[117*256+45] +84=proba2[117*256+46] +58=proba2[117*256+48] +47=proba2[117*256+49] +50=proba2[117*256+50] +58=proba2[117*256+51] +61=proba2[117*256+52] +60=proba2[117*256+53] +57=proba2[117*256+54] +58=proba2[117*256+55] +63=proba2[117*256+56] +57=proba2[117*256+57] +102=proba2[117*256+59] +102=proba2[117*256+61] +102=proba2[117*256+63] +102=proba2[117*256+64] +102=proba2[117*256+65] +91=proba2[117*256+66] +91=proba2[117*256+68] +88=proba2[117*256+70] +95=proba2[117*256+71] +102=proba2[117*256+72] +102=proba2[117*256+73] +86=proba2[117*256+75] +88=proba2[117*256+76] +102=proba2[117*256+77] +102=proba2[117*256+78] +91=proba2[117*256+79] +91=proba2[117*256+80] +86=proba2[117*256+82] +88=proba2[117*256+83] +88=proba2[117*256+84] +102=proba2[117*256+85] +102=proba2[117*256+87] +91=proba2[117*256+88] +102=proba2[117*256+90] +102=proba2[117*256+91] +102=proba2[117*256+93] +84=proba2[117*256+95] +35=proba2[117*256+97] +32=proba2[117*256+98] +29=proba2[117*256+99] +28=proba2[117*256+100] +27=proba2[117*256+101] +40=proba2[117*256+102] +36=proba2[117*256+103] +51=proba2[117*256+104] +27=proba2[117*256+105] +49=proba2[117*256+106] +42=proba2[117*256+107] +23=proba2[117*256+108] +32=proba2[117*256+109] +26=proba2[117*256+110] +51=proba2[117*256+111] +33=proba2[117*256+112] +60=proba2[117*256+113] +20=proba2[117*256+114] +23=proba2[117*256+115] +29=proba2[117*256+116] +59=proba2[117*256+117] +43=proba2[117*256+118] +61=proba2[117*256+119] +37=proba2[117*256+120] +45=proba2[117*256+121] +43=proba2[117*256+122] +38=proba1[118] +72=proba2[118*256+33] +85=proba2[118*256+35] +85=proba2[118*256+36] +85=proba2[118*256+38] +85=proba2[118*256+42] +85=proba2[118*256+43] +92=proba2[118*256+44] +92=proba2[118*256+45] +74=proba2[118*256+46] +57=proba2[118*256+48] +47=proba2[118*256+49] +50=proba2[118*256+50] +57=proba2[118*256+51] +56=proba2[118*256+52] +54=proba2[118*256+53] +57=proba2[118*256+54] +56=proba2[118*256+55] +55=proba2[118*256+56] +55=proba2[118*256+57] +85=proba2[118*256+61] +81=proba2[118*256+64] +81=proba2[118*256+65] +85=proba2[118*256+66] +92=proba2[118*256+67] +92=proba2[118*256+68] +85=proba2[118*256+69] +92=proba2[118*256+71] +78=proba2[118*256+72] +85=proba2[118*256+75] +92=proba2[118*256+76] +92=proba2[118*256+77] +92=proba2[118*256+79] +92=proba2[118*256+80] +85=proba2[118*256+81] +92=proba2[118*256+84] +81=proba2[118*256+85] +85=proba2[118*256+95] +16=proba2[118*256+97] +42=proba2[118*256+98] +44=proba2[118*256+99] +42=proba2[118*256+100] +14=proba2[118*256+101] +50=proba2[118*256+102] +50=proba2[118*256+103] +51=proba2[118*256+104] +13=proba2[118*256+105] +55=proba2[118*256+106] +56=proba2[118*256+107] +42=proba2[118*256+108] +45=proba2[118*256+109] +49=proba2[118*256+110] +27=proba2[118*256+111] +47=proba2[118*256+112] +59=proba2[118*256+113] +34=proba2[118*256+114] +45=proba2[118*256+115] +46=proba2[118*256+116] +46=proba2[118*256+117] +48=proba2[118*256+118] +58=proba2[118*256+119] +57=proba2[118*256+120] +44=proba2[118*256+121] +61=proba2[118*256+122] +43=proba1[119] +86=proba2[119*256+32] +86=proba2[119*256+33] +86=proba2[119*256+34] +72=proba2[119*256+37] +86=proba2[119*256+38] +79=proba2[119*256+42] +86=proba2[119*256+44] +79=proba2[119*256+45] +79=proba2[119*256+46] +56=proba2[119*256+48] +47=proba2[119*256+49] +45=proba2[119*256+50] +50=proba2[119*256+51] +52=proba2[119*256+52] +57=proba2[119*256+53] +55=proba2[119*256+54] +52=proba2[119*256+55] +55=proba2[119*256+56] +53=proba2[119*256+57] +79=proba2[119*256+65] +86=proba2[119*256+68] +86=proba2[119*256+69] +79=proba2[119*256+70] +86=proba2[119*256+71] +86=proba2[119*256+72] +86=proba2[119*256+73] +79=proba2[119*256+74] +86=proba2[119*256+77] +79=proba2[119*256+81] +79=proba2[119*256+83] +86=proba2[119*256+84] +75=proba2[119*256+86] +86=proba2[119*256+89] +86=proba2[119*256+90] +79=proba2[119*256+95] +16=proba2[119*256+97] +42=proba2[119*256+98] +46=proba2[119*256+99] +43=proba2[119*256+100] +14=proba2[119*256+101] +46=proba2[119*256+102] +47=proba2[119*256+103] +38=proba2[119*256+104] +20=proba2[119*256+105] +53=proba2[119*256+106] +46=proba2[119*256+107] +44=proba2[119*256+108] +47=proba2[119*256+109] +39=proba2[119*256+110] +22=proba2[119*256+111] +49=proba2[119*256+112] +55=proba2[119*256+113] +42=proba2[119*256+114] +34=proba2[119*256+115] +46=proba2[119*256+116] +45=proba2[119*256+117] +59=proba2[119*256+118] +36=proba2[119*256+119] +43=proba2[119*256+120] +40=proba2[119*256+121] +49=proba2[119*256+122] +51=proba1[120] +82=proba2[120*256+37] +76=proba2[120*256+38] +82=proba2[120*256+39] +82=proba2[120*256+42] +82=proba2[120*256+43] +76=proba2[120*256+44] +61=proba2[120*256+45] +66=proba2[120*256+46] +40=proba2[120*256+48] +31=proba2[120*256+49] +35=proba2[120*256+50] +39=proba2[120*256+51] +44=proba2[120*256+52] +47=proba2[120*256+53] +42=proba2[120*256+54] +42=proba2[120*256+55] +45=proba2[120*256+56] +41=proba2[120*256+57] +82=proba2[120*256+59] +82=proba2[120*256+63] +82=proba2[120*256+64] +82=proba2[120*256+65] +82=proba2[120*256+68] +82=proba2[120*256+70] +76=proba2[120*256+71] +76=proba2[120*256+72] +82=proba2[120*256+76] +76=proba2[120*256+77] +76=proba2[120*256+80] +76=proba2[120*256+81] +82=proba2[120*256+82] +82=proba2[120*256+83] +82=proba2[120*256+84] +76=proba2[120*256+85] +82=proba2[120*256+86] +82=proba2[120*256+87] +82=proba2[120*256+88] +82=proba2[120*256+90] +82=proba2[120*256+93] +82=proba2[120*256+95] +24=proba2[120*256+97] +38=proba2[120*256+98] +32=proba2[120*256+99] +40=proba2[120*256+100] +25=proba2[120*256+101] +37=proba2[120*256+102] +44=proba2[120*256+103] +48=proba2[120*256+104] +24=proba2[120*256+105] +48=proba2[120*256+106] +49=proba2[120*256+107] +38=proba2[120*256+108] +34=proba2[120*256+109] +45=proba2[120*256+110] +31=proba2[120*256+111] +32=proba2[120*256+112] +51=proba2[120*256+113] +41=proba2[120*256+114] +36=proba2[120*256+115] +31=proba2[120*256+116] +40=proba2[120*256+117] +45=proba2[120*256+118] +42=proba2[120*256+119] +24=proba2[120*256+120] +33=proba2[120*256+121] +45=proba2[120*256+122] +45=proba1[121] +75=proba2[121*256+32] +72=proba2[121*256+33] +91=proba2[121*256+34] +80=proba2[121*256+36] +78=proba2[121*256+38] +91=proba2[121*256+39] +91=proba2[121*256+41] +69=proba2[121*256+42] +78=proba2[121*256+44] +69=proba2[121*256+45] +84=proba2[121*256+46] +43=proba2[121*256+48] +34=proba2[121*256+49] +38=proba2[121*256+50] +48=proba2[121*256+51] +46=proba2[121*256+52] +51=proba2[121*256+53] +47=proba2[121*256+54] +44=proba2[121*256+55] +49=proba2[121*256+56] +43=proba2[121*256+57] +91=proba2[121*256+59] +78=proba2[121*256+63] +91=proba2[121*256+64] +84=proba2[121*256+65] +84=proba2[121*256+66] +80=proba2[121*256+67] +73=proba2[121*256+68] +91=proba2[121*256+69] +91=proba2[121*256+72] +84=proba2[121*256+74] +84=proba2[121*256+76] +78=proba2[121*256+77] +91=proba2[121*256+78] +84=proba2[121*256+80] +91=proba2[121*256+82] +80=proba2[121*256+83] +66=proba2[121*256+84] +78=proba2[121*256+85] +80=proba2[121*256+88] +91=proba2[121*256+89] +91=proba2[121*256+93] +78=proba2[121*256+95] +22=proba2[121*256+97] +28=proba2[121*256+98] +33=proba2[121*256+99] +35=proba2[121*256+100] +27=proba2[121*256+101] +44=proba2[121*256+102] +32=proba2[121*256+103] +49=proba2[121*256+104] +48=proba2[121*256+105] +47=proba2[121*256+106] +44=proba2[121*256+107] +27=proba2[121*256+108] +32=proba2[121*256+109] +31=proba2[121*256+110] +24=proba2[121*256+111] +35=proba2[121*256+112] +63=proba2[121*256+113] +30=proba2[121*256+114] +25=proba2[121*256+115] +37=proba2[121*256+116] +39=proba2[121*256+117] +37=proba2[121*256+118] +48=proba2[121*256+119] +48=proba2[121*256+120] +47=proba2[121*256+121] +45=proba2[121*256+122] +44=proba1[122] +80=proba2[122*256+33] +87=proba2[122*256+34] +87=proba2[122*256+35] +87=proba2[122*256+36] +87=proba2[122*256+37] +80=proba2[122*256+38] +76=proba2[122*256+40] +87=proba2[122*256+42] +76=proba2[122*256+44] +73=proba2[122*256+45] +53=proba2[122*256+48] +46=proba2[122*256+49] +46=proba2[122*256+50] +46=proba2[122*256+51] +49=proba2[122*256+52] +53=proba2[122*256+53] +49=proba2[122*256+54] +52=proba2[122*256+55] +49=proba2[122*256+56] +52=proba2[122*256+57] +87=proba2[122*256+59] +80=proba2[122*256+64] +80=proba2[122*256+65] +87=proba2[122*256+66] +87=proba2[122*256+67] +87=proba2[122*256+68] +87=proba2[122*256+70] +80=proba2[122*256+71] +80=proba2[122*256+73] +80=proba2[122*256+75] +87=proba2[122*256+76] +73=proba2[122*256+77] +87=proba2[122*256+78] +87=proba2[122*256+81] +87=proba2[122*256+83] +87=proba2[122*256+85] +87=proba2[122*256+87] +80=proba2[122*256+88] +73=proba2[122*256+89] +80=proba2[122*256+95] +18=proba2[122*256+97] +44=proba2[122*256+98] +48=proba2[122*256+99] +46=proba2[122*256+100] +17=proba2[122*256+101] +51=proba2[122*256+102] +47=proba2[122*256+103] +41=proba2[122*256+104] +21=proba2[122*256+105] +60=proba2[122*256+106] +50=proba2[122*256+107] +44=proba2[122*256+108] +38=proba2[122*256+109] +48=proba2[122*256+110] +18=proba2[122*256+111] +50=proba2[122*256+112] +53=proba2[122*256+113] +46=proba2[122*256+114] +49=proba2[122*256+115] +45=proba2[122*256+116] +34=proba2[122*256+117] +54=proba2[122*256+118] +47=proba2[122*256+119] +45=proba2[122*256+120] +35=proba2[122*256+121] +24=proba2[122*256+122] +87=proba2[122*256+126] +104=proba1[123] +19=proba2[123*256+75] +19=proba2[123*256+91] +19=proba2[123*256+97] +19=proba2[123*256+102] +19=proba2[123*256+114] +19=proba2[123*256+122] +19=proba2[123*256+124] +111=proba1[124] +20=proba2[124*256+38] +20=proba2[124*256+41] +20=proba2[124*256+45] +20=proba2[124*256+53] +20=proba2[124*256+82] +20=proba2[124*256+106] +20=proba2[124*256+108] +20=proba2[124*256+109] +118=proba1[125] +13=proba2[125*256+54] +13=proba2[125*256+66] +13=proba2[125*256+101] +13=proba2[125*256+115] +111=proba1[126] +13=proba2[126*256+86] +13=proba2[126*256+98] +13=proba2[126*256+115] +13=proba2[126*256+122] diff -urpN john-1.7.3.4.orig/src/BFEgg_fmt.c john-1.7.3.4/src/BFEgg_fmt.c --- john-1.7.3.4.orig/src/BFEgg_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/BFEgg_fmt.c 2008-08-24 08:30:56 +0000 @@ -0,0 +1,124 @@ +/* + * This file is part of Eggdrop blowfish patch for John The Ripper. + * Copyright (c) 2002 by Sun-Zero + * This is a free software distributable under terms of the GNU GPL. + */ + +#include + +#include "misc.h" +#include "formats.h" +#include "common.h" +#include "blowfish.c" + +#define FORMAT_LABEL "bfegg" +#define FORMAT_NAME "Eggdrop" +#define ALG_NAME "blowfish" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 31 +#define CIPHERTEXT_LENGTH 33 + +#define BINARY_SIZE 13 +#define SALT_SIZE 0 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"+9F93o1OxwgK1", "123456"}, + {"+C/.8o.Wuph9.", "qwerty"}, + {"+EEHgy/MBLDd0", "walkman"}, + {"+vPBrs07OTXE/", "tesztuser"}, + {"+zIvO/1nDsd9.", "654321"}, + {NULL} +}; + +int zerolengthkey = 0; + +static char crypt_key[BINARY_SIZE + 1]; +static char saved_key[PLAINTEXT_LENGTH + 1]; + +static int valid(char *ciphertext) { + if (strncmp(ciphertext, "+", 1) != 0) return 0; + if (strlen(ciphertext) != 13) return 0; + + return 1; +} + +void init() { + blowfish_first_init(); +} + + +static void set_key(char *key, int index) { + strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1); +} + +static char *get_key(int index) { + return saved_key; +} + +static int cmp_all(void *binary, int index) { + if (zerolengthkey) return 0; + return !memcmp(binary, crypt_key, BINARY_SIZE); +} + +static int cmp_exact(char *source, int index) { + return 1; +} + +static void set_salt(void *salt) { } + +static void crypt_all(int count) { + if (saved_key[0] == '\0') { + zerolengthkey = 1; + } else { + zerolengthkey = 0; + blowfish_encrypt_pass(saved_key, crypt_key); + } +} + +struct fmt_main fmt_BFEgg = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALG_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + init, + valid, + fmt_default_split, + fmt_default_binary, + fmt_default_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash, + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash, + }, + cmp_all, + cmp_all, + cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/DOMINOSEC_fmt.c john-1.7.3.4/src/DOMINOSEC_fmt.c --- john-1.7.3.4.orig/src/DOMINOSEC_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/DOMINOSEC_fmt.c 2009-10-29 02:54:16 +0000 @@ -0,0 +1,456 @@ +/* + * DOMINOSEC_fmt.c (version 3) + * + * Notes/Domino More Secure Internet Password module for Solar Designer's JtR + * by regenrecht at o2.pl, Dec 2005. + * Algorithm discovery by regenrecht at o2.pl, bartavelle at bandecon.com. + * + * Short description. + * 1. Make 128bit digest of key. (128/8=16 bytes) + * 2. Do bin2hex() of key digest and put braces around it. (16*2+2=34 bytes) + * 3. Concat output of previous step to 5 bytes of salt. (5+34=39 bytes) + * 4. Make 128bit digest of first 34 bytes (out of 39 bytes). (128/8=16 bytes) + * 5. Compare first 10 bytes (out of 16) to check if the key was correct. + * + * Password file should have form of: + * TomaszJegerman:(GKjXibCW2Ml6juyQHUoP) + * RubasznyJan:(GrixoFHOckC/2CnHrHtM) + */ + +#include +#include + +#include "misc.h" +#include "formats.h" +#include "common.h" + +#define FORMAT_LABEL "dominosec" +#define FORMAT_NAME "More Secure Internet Password" +#define ALGORITHM_NAME "RSA MD defined by BSAFE 1.x - Lotus v6" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 64 +#define CIPHERTEXT_LENGTH 22 +#define BINARY_SIZE 9 /* oh, well :P */ +#define SALT_SIZE 5 + +#define DIGEST_SIZE 16 +#define BINARY_BUFFER_SIZE (DIGEST_SIZE-SALT_SIZE) +#define ASCII_DIGEST_LENGTH (DIGEST_SIZE*2) +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static unsigned char key_digest[DIGEST_SIZE]; +static char saved_key[PLAINTEXT_LENGTH+1]; +static unsigned char crypted_key[DIGEST_SIZE]; +static unsigned char salt_and_digest[SALT_SIZE+1+ASCII_DIGEST_LENGTH+1+1] = + "saalt(................................)"; +static unsigned int saved_key_len; + +static const char *hex_table[] = { + "00", "01", "02", "03", "04", "05", "06", "07", + "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", + "10", "11", "12", "13", "14", "15", "16", "17", + "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", + "20", "21", "22", "23", "24", "25", "26", "27", + "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", + "30", "31", "32", "33", "34", "35", "36", "37", + "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", + "40", "41", "42", "43", "44", "45", "46", "47", + "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", + "50", "51", "52", "53", "54", "55", "56", "57", + "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", + "60", "61", "62", "63", "64", "65", "66", "67", + "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", + "70", "71", "72", "73", "74", "75", "76", "77", + "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", + "80", "81", "82", "83", "84", "85", "86", "87", + "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", + "90", "91", "92", "93", "94", "95", "96", "97", + "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", + "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", + "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", + "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", + "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", + "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", + "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", + "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", + "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", + "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", + "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", + "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" +}; + +static const char lotus_magic_table[] = { + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, + 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, + 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, + 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, + 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, + 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, + 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, + 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, + 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, + 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, + 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, + 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, + 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, + 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, + 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, + 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, + 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab, + /* double power! */ + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, + 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, + 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, + 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, + 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, + 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, + 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, + 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, + 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, + 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, + 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, + 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, + 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, + 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, + 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, + 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, + 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab, +}; + +static struct fmt_tests dominosec_tests[] = { + {"(GVMroLzc50YK/Yd+L8KH)", ""}, + {"(GqnUDNNGNUz5HRoelmLU)", "x"}, + {"(GNBpcGJRYpBe9orUOpmZ)", "dupaaa123"}, + {"(G0xjUQzdKxvHpUYqo5hU)", "koziolekmatolek"}, + {"(G+dfECo845XxUw+nFVYD)", "szesnascieznakow"}, + {"(GowT5I2hVHZpRWpvGmux)", "terazjakiesdwadziesciacos"}, + {"(Gq2bAtpguiTSSycy6dhu)", "trzydziescidwamozesieudaojnieuda"}, + {"(G82TtgNcqcHGkpEo7wQp)", "looongrandominputdataforfunbutnotonlyoi!"}, + {NULL} +}; + +struct cipher_binary_struct { + unsigned char salt[SALT_SIZE]; + unsigned char hash[BINARY_BUFFER_SIZE]; +} cipher_binary; + +static void mdtransform(unsigned char state[16], unsigned char checksum[16], unsigned char block[16]) +{ + unsigned char x[48]; + unsigned int t = 0; + unsigned int i,j; + unsigned char * pt; + unsigned char c; + + memcpy(x, state, 16); + memcpy(x+16, block, 16); + + for(i=0;i<16;i++) + x[i+32] = state[i] ^ block[i]; + + for (i = 0; i < 18; ++i) + { + pt = (unsigned char*)&x; + for (j = 48; j > 0; j--) + { + *pt ^= lotus_magic_table[j+t]; + t = *pt; + pt++; + } + } + + memcpy(state, x, 16); + + t = checksum[15]; + for (i = 0; i < 16; i++) + { + c = lotus_magic_table[block[i]^t]; + checksum[i] ^= c; + t = checksum[i]; + } +} + +static void mdtransform_norecalc(unsigned char state[16], unsigned char block[16]) +{ + unsigned char x[48], *pt; + unsigned int t = 0; + unsigned int i,j; + + memcpy(x, state, 16); + memcpy(x+16, block, 16); + + for(i=0;i<16;i++) + x[i+32] = state[i] ^ block[i]; + + for(i = 0; i < 18; ++i) + { + pt = (unsigned char*)&x; + for (j = 48; j > 0; j--) + { + *pt ^= lotus_magic_table[j+t]; + t = *pt; + pt++; + } + } + + memcpy(state, x, 16); +} + +static void domino_big_md(unsigned char * saved_key, int size, unsigned char * crypt_key) +{ + unsigned char state[16] = {0}; + unsigned char checksum[16] = {0}; + unsigned char block[16]; + unsigned int x; + unsigned int curpos = 0; + + while(curpos + 15 < size) + { + memcpy(block, saved_key + curpos, 16); + mdtransform(state, checksum, block); + curpos += 16; + } + + if(curpos != size) + { + x = size - curpos; + memcpy(block, saved_key + curpos, x); + memset(block + x, 16 - x, 16 - x); + mdtransform(state, checksum, block); + } + else + { + memset(block, 16, 16); + mdtransform(state, checksum, block); + } + + mdtransform_norecalc(state, checksum); + + memcpy(crypt_key, state, 16); +} + +static int dominosec_valid(char *ciphertext) +{ + unsigned int i; + unsigned char ch; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + + if (ciphertext[0] != '(' || + ciphertext[1] != 'G' || + ciphertext[CIPHERTEXT_LENGTH-1] != ')') + return 0; + + for (i = 1; i < CIPHERTEXT_LENGTH-1; ++i) { + ch = ciphertext[i]; + if (!isalnum(ch) && ch != '+' && ch != '/') + return 0; + } + + return 1; +} + +/* +static unsigned int dominosec_proper_mul(int delta_apsik) +{ + __asm__("movl $0xAAAAAAAB, %eax \n" + "movl 0x8(%ebp), %edx \n" + "mul %edx \n" + "shr $0x2,%edx \n" + "movl %edx, %eax \n"); +} +*/ + +static void dominosec_decode(unsigned char *ascii_cipher, unsigned char *binary) +{ + unsigned int out = 0, apsik = 0, loop; + unsigned int i; + unsigned char ch; + + ascii_cipher += 2; + i = 0; + do { + if (apsik < 8) { + /* should be using proper_mul, but what the heck... + it's nearly the same :] */ + loop = 2; /* ~ loop = proper_mul(13 - apsik); */ + apsik += loop*6; + + do { + out <<= 6; + ch = *ascii_cipher; + + if (ch < '0' || ch > '9') + if (ch < 'A' || ch > 'Z') + if (ch < 'a' || ch > 'z') + if (ch != '+') + if (ch == '/') + out += '?'; + else + ; /* shit happens */ + else + out += '>'; + else + out += ch-'='; + else + out += ch-'7'; + else + out += ch-'0'; + ++ascii_cipher; + } while (--loop); + } + + loop = apsik-8; + ch = out >> loop; + *(binary+i) = ch; + ch <<= loop; + apsik = loop; + out -= ch; + } while (++i < 15); + + binary[3] += -4; +} + +static void *dominosec_binary(char *ciphertext) +{ + dominosec_decode((unsigned char*)ciphertext, (unsigned char*)&cipher_binary); + return (void*)cipher_binary.hash; +} + +static void *dominosec_salt(char *ciphertext) +{ + return cipher_binary.salt; +} + +static void dominosec_set_salt(void *salt) +{ + memcpy(salt_and_digest, salt, SALT_SIZE); +} + +static void dominosec_set_key(char *key, int index) +{ + unsigned char *offset = salt_and_digest+6; + unsigned int i; + + saved_key_len = strlen(key); + strnzcpy(saved_key, key, PLAINTEXT_LENGTH); + + domino_big_md((unsigned char*)key, saved_key_len, key_digest); + + i = 0; + do { + memcpy(offset, *(hex_table+*(key_digest+i)), 2); + offset += 2; + } while (++i < 14); + + /* + * Not (++i < 16) ! + * Domino will do hash of first 34 bytes ignoring The Fact that now + * there is a salt at a beginning of buffer. This means that last 5 + * bytes "EEFF)" of password digest are meaningless. + */ +} + +static char *dominosec_get_key(int index) +{ + return saved_key; +} + +static void dominosec_crypt_all(int count) +{ + domino_big_md(salt_and_digest, 34, crypted_key); +} + +static int dominosec_cmp_all(void *binary, int count) +{ + /* + * Only 10 bytes of digest are to be checked. + * 48 bits are left alone. + * Funny that. + */ + return !memcmp(crypted_key, binary, BINARY_SIZE); +} + +static int dominosec_cmp_exact(char *source, int index) +{ + return 1; +} + +struct fmt_main fmt_DOMINOSEC = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + dominosec_tests + }, + { + fmt_default_init, + dominosec_valid, + fmt_default_split, + dominosec_binary, + dominosec_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + dominosec_set_salt, + dominosec_set_key, + dominosec_get_key, + fmt_default_clear_keys, + dominosec_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + dominosec_cmp_all, + dominosec_cmp_all, + dominosec_cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/EPI_fmt.c john-1.7.3.4/src/EPI_fmt.c --- john-1.7.3.4.orig/src/EPI_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/EPI_fmt.c 2008-08-25 01:50:09 +0000 @@ -0,0 +1,204 @@ +/* + * EPiServer module for john 1.7.2 (and possibly later) + * Uses hashes/salts found in the tblSID of an EPiServer database installation + * + * Created by Johannes Gumbel (johannes [at] iforge.cc) + * + * If you have any questions as to how a function incorporates with john, please refer to formats.h of john + * + * version 0.1 released on 10 jan 2007 + * + * See doc/EPi.patch.README or http://iforge.cc/files/EPi.patch.README + * for information on the input file format. + */ + +#include "string.h" +#include "formats.h" +#include "common.h" +#include "misc.h" + +#include "sha.h" + +#define PLAINTEXT_LENGTH 0x80-4 +#define BINARY_LENGTH 20 +#define SALT_LENGTH 30 + +static char global_crypt[BINARY_LENGTH]; +static char global_key[PLAINTEXT_LENGTH]; // set by set_key and used by get_get +static char global_salt[SALT_LENGTH + PLAINTEXT_LENGTH]; // set by set_salt and used by crypt_all + // the extra plaintext_length is needed because the + // current key is copied there before hashing + +int valid(char *ciphertext); +void* binary(char *ciphertext); +void* salt(char *ciphertext); +void set_salt(void *salt); +void set_key(char *key, int index); +char* get_key(int index); +void crypt_all(int count); +int cmp_all(void *binary, int count); +int cmp_one(void *binary, int index); +int cmp_exact(char *source, int index); + +struct fmt_tests global_tests[] = +{ + {"0x5F1D84A6DE97E2BEFB637A3CB5318AFEF0750B856CF1836BD1D4470175BE 0x4D5EFDFA143EDF74193076F174AC47CEBF2F417F", "Abc.!23"}, + {NULL} +}; + +// Define john integration +struct fmt_main fmt_EPI = +{ + { // fmt_params + "epi", + "EPiServer SID Hashes", + "SHA-1", + "", // benchmark comment + 0, // benchmark length + PLAINTEXT_LENGTH, + BINARY_LENGTH, + SALT_LENGTH, + 1, + 1, + FMT_CASE | FMT_8_BIT, // flags XXX, these are just guesses + global_tests + }, + { // fmt_methods + fmt_default_init, + valid, + fmt_default_split, + binary, + salt, + { // binary_hash[3] + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { // get_hash[3] + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + cmp_all, + cmp_one, + cmp_exact + } +}; + +/* + * Expects ciphertext of format: 0xHEX*60 0xHEX*40 + */ +int valid(char *ciphertext) +{ + unsigned int len, n; + + if(!ciphertext) return 0; + len = strlen(ciphertext); + + if(len != 105) + return 0; + + // check fixed positions + if(ciphertext[0] != '0' || ciphertext[1] != 'x' || + ciphertext[62] != ' ' || + ciphertext[63] != '0' || ciphertext[64] != 'x') + return 0; + + for(n = 2; n < 62 && atoi16[ARCH_INDEX(ciphertext[n])] != 0x7F; ++n); + for(n = 65; n < 105 && atoi16[ARCH_INDEX(ciphertext[n])] != 0x7F; ++n); + + return n == len; +} + +void _tobin(char* dst, char *src, unsigned int len) +{ + unsigned int n; + + if(src[0] == '0' && src[1] == 'x') + src += sizeof(char)*2; + + for(n = 0; n < len; ++n) + dst[n] = atoi16[ARCH_INDEX(src[n*2])]<<4 | + atoi16[ARCH_INDEX(src[n*2+1])]; +} + +void* binary(char *ciphertext) +{ + static char bin[BINARY_LENGTH]; + + _tobin(bin, (char*)(ciphertext+65), sizeof(bin)); + + return bin; +} + +void* salt(char *ciphertext) +{ + static char salt[SALT_LENGTH]; + + _tobin(salt, (char*)(ciphertext+2), sizeof(salt)); + + return salt; +} + +void set_salt(void *salt) +{ + memcpy(global_salt, salt, SALT_LENGTH); +} + +void set_key(char *key, int index) +{ + if(!key) return; + strnzcpy(global_key, key, PLAINTEXT_LENGTH); +} + +char* get_key(int index) +{ + return global_key; +} + +void crypt_all(int count) +{ + static SHA_CTX ctx; + + // Yes, I'm overwriting the last byte of the salt, perhaps the coder at ElektoPost whom wrote the EPiServer password checking function used to be a C coder (their code is written in .NET) + strnzcpy(global_salt+SALT_LENGTH-1, global_key, PLAINTEXT_LENGTH); + + SHA1_Init(&ctx); + SHA1_Update(&ctx, (unsigned char*)global_salt, SALT_LENGTH+strlen(global_key)); + SHA1_Final((unsigned char*)global_crypt, &ctx); +} + +int cmp_all(void *binary, int count) +{ + unsigned int n; + ARCH_WORD *a, *b; + + if(*(ARCH_WORD*)binary != *(ARCH_WORD*)global_crypt) + return 0; + + a = (ARCH_WORD*)binary; + b = (ARCH_WORD*)global_crypt; + + // Starting at 1 since 0 was checked previously + for(n=1; n +#include + +#ifdef __MMX__ +#include +#endif + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "md5.h" + +#define FORMAT_LABEL "hdaa" +#define FORMAT_NAME "HTTP Digest access authentication" +#define ALGORITHM_NAME "HDAA-MD5" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 16 +#define CIPHERTEXT_LENGTH 32 + +#define BINARY_SIZE 16 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +#define SEPARATOR '$' + +#define MAGIC "$response$" +#define SIZE_TAB 12 + +#define HTMP 512 + +typedef struct +{ + char **request; + char h3tmp[HTMP + 1]; + char h1tmp[HTMP + 1]; + size_t h3tmplen; + size_t h1tmplen; +} reqinfo_t; + +#define SALT_SIZE sizeof(reqinfo_t) + + +/* + digest authentication scheme : + h1 = md5(user:realm:password) + h2 = md5(method:digestURI) + response = h3 = md5(h1:nonce:nonceCount:ClientNonce:qop:h2) +*/ + +/* request information */ +enum e_req { + R_RESPONSE, + R_USER, + R_REALM, + R_METHOD, + R_URI, + R_NONCE, + R_NONCECOUNT, + R_CLIENTNONCE, + R_QOP +}; + +/* response:user:realm:method:uri:nonce:nonceCount:ClientNonce:qop */ +static struct fmt_tests hdaa_tests[] = { + {"$response$679066476e67b5c7c4e88f04be567f8b$user$myrealm$GET$/$8c12bd8f728afe56d45a0ce846b70e5a$00000001$4b61913cec32e2c9$auth", "nocode"}, + {"$response$faa6cb7d676e5b7c17fcbf966436aa0c$moi$myrealm$GET$/$af32592775d27b1cd06356b3a0db9ddf$00000001$8e1d49754a25aea7$auth", "kikou"}, + {NULL} +}; + + +static MD5_CTX ctx; + +/* used by set_key */ +static char saved_key[PLAINTEXT_LENGTH + 1]; + +/* store the ciphertext for value currently being tested */ +static unsigned char crypt_key[BINARY_SIZE + 1]; + +/* Store information about the request ()*/ +static reqinfo_t *rinfo = NULL; + +/* Store the hash convertion (binary to ascii)*/ +#ifdef __MMX__ +static __m64 conv[4 + 1]; +#else +static uint32_t conv[(CIPHERTEXT_LENGTH / 4) + 1]; +#endif + +static int hdaa_valid(char *ciphertext) +{ + int nb = 0; + int i; + + if (strncmp(ciphertext, MAGIC, strlen(MAGIC)) != 0) + return 0; + for (i = 0; ciphertext[i] != 0; i++) { + if (ciphertext[i] == SEPARATOR) { + nb++; + } + } + if (nb == 10) + return 1; + return 0; +} + +static void hdaa_set_salt(void *salt) +{ + rinfo = salt; +} + +static void hdaa_set_key(char *key, int index) +{ + strnzcpy(saved_key, key, PLAINTEXT_LENGTH + 1); +} + +static char *hdaa_get_key(int index) +{ + return saved_key; +} + +static int hdaa_cmp_all(void *binary, int index) +{ + return !(memcmp((char *)binary, (char *)crypt_key, BINARY_SIZE)); +} + +static int hdaa_cmp_exact(char *source, int count) +{ + return 1; +} + + +/* convert hash from binary to ascii */ + +#ifdef __MMX__ + +static void bin2ascii(__m64 src[2]) +{ + unsigned int i = 0; + + while (i != 4) { + __m64 l; + __m64 r; + __m64 t; + __m64 u; + __m64 v; + + /* 32 bits to 64 bits */ + t = _mm_set1_pi32(0x0f0f0f0f); + + /* Bit-wise AND the 64-bit values in M1 and M2. */ + u = _mm_and_si64(_mm_srli_si64(src[(i / 2)], 4), t); + v = _mm_and_si64(src[(i / 2)], t); + + /* interleaving */ + l = _mm_unpacklo_pi8(u, v); + r = _mm_unpackhi_pi8(u, v); + + t = _mm_set1_pi32(0x06060606); + l = _mm_add_pi32(l, t); + r = _mm_add_pi32(r, t); + + t = _mm_set1_pi32(0x01010101); + /* u = (l << 4) & t */ + u = _mm_and_si64(_mm_srli_si64(l, 4), t); + /* v = (r << 4) & t */ + v = _mm_and_si64(_mm_srli_si64(r, 4), t); + + t = _mm_set1_pi32(0x00270027); + /* Multiply four 16-bit values in M1 by four 16-bit values in M2 and produce + the low 16 bits of the results. */ + u = _mm_mullo_pi16(u, t); + v = _mm_mullo_pi16(v, t); + + t = _mm_set1_pi32(0x2a2a2a2a); + u = _mm_add_pi32(u, t); + v = _mm_add_pi32(v, t); + + conv[(i++)] = _mm_add_pi32(l, u); + conv[(i++)] = _mm_add_pi32(r, v); + } +} + +#else + +static void bin2ascii(unsigned char *src) +{ + unsigned int i; + unsigned int j = 0; + uint32_t t = 0; + + for (i = 0; i < BINARY_SIZE; i += 2) { +#if (ARCH_LITTLE_ENDIAN == 0) + t = (src[i] & 0xf0); + t *= 0x10; + t += (src[i] & 0x0f); + t *= 0x1000; + t += (src[(i + 1)] & 0xf0); + t *= 0x10; + t += (src[(i + 1)] & 0x0f); +#else + t = (src[(i + 1)] & 0x0f); + t *= 0x1000; + t += (src[(i + 1)] & 0xf0); + t *= 0x10; + t += (src[i] & 0x0f); + t *= 0x100; + t += ((src[i] & 0xf0) >> 4); +#endif + t += 0x06060606; + t += ((((t >> 4) & 0x01010101) * 0x27) + 0x2a2a2a2a); + conv[(j++)] = t; + } +} + +#endif /* MMX */ + +static void hdaa_crypt_all(int count) +{ + int len; +#ifdef __MMX__ + __m64 h1[2]; +#else + unsigned char h1[BINARY_SIZE]; +#endif + char *h1tmp, *h3tmp; + size_t tmp; + + h3tmp = rinfo->h3tmp; + h1tmp = rinfo->h1tmp; + tmp = rinfo->h1tmplen; + len = strlen(saved_key); + memcpy(&h1tmp[tmp], saved_key, len + 1); + + MD5_Init(&ctx); + MD5_Update(&ctx, h1tmp, len + tmp); + MD5_Final((unsigned char*)h1, &ctx); + bin2ascii(h1); + + memcpy(h3tmp, conv, CIPHERTEXT_LENGTH); + MD5_Init(&ctx); + MD5_Update(&ctx, h3tmp, rinfo->h3tmplen); + MD5_Final(crypt_key, &ctx); +} + +static char *mystrndup(const char *s, size_t n) +{ + size_t tmp; + size_t size; + char *ret; + + for (tmp = 0; s[tmp] != 0 && tmp <= n; tmp++); + size = n; + if (tmp < size) + size = tmp; + if ((ret = malloc(sizeof(char) * size + 1)) == NULL) + return NULL; + memmove(ret, s, size); + ret[size] = 0; + return ret; +} + +static size_t reqlen(char *str) +{ + size_t len; + + for (len = 0; str[len] != 0 && str[len] != SEPARATOR; len++); + return len; +} + +static void *hdaa_salt(char *ciphertext) +{ + + int nb; + int i; + char **request; + char *str; + reqinfo_t *r; +#ifdef __MMX__ + __m64 h2[2]; +#else + unsigned char h2[BINARY_SIZE]; +#endif + /* parse the password string */ + request = malloc(sizeof(char *) * SIZE_TAB); + r = malloc(sizeof(*r)); + memset(r, 0, sizeof(*r)); + for (nb = 0, i = 1; ciphertext[i] != 0; i++) { + if (ciphertext[i] == SEPARATOR) { + i++; + request[nb] = mystrndup(&ciphertext[i], + reqlen(&ciphertext[i])); + nb++; + } + } + + /* calculate h2 (h2 = md5(method:digestURI))*/ + str = malloc(strlen(request[R_METHOD]) + strlen(request[R_URI]) + 2); + sprintf(str, "%s:%s", request[R_METHOD], request[R_URI]); + MD5_Init(&ctx); + MD5_Update(&ctx, str, strlen(str)); + MD5_Final((unsigned char *)h2, &ctx); + + memset(conv, 0, sizeof(conv)); + bin2ascii(h2); + free(str); + + /* create a part of h1 (h1tmp = request:realm:)*/ + snprintf(r->h1tmp, HTMP - PLAINTEXT_LENGTH, "%s:%s:", request[R_USER], request[R_REALM]); + + /* create a part of h3 (h3tmp = nonce:noncecount:clientnonce:qop:h2)*/ + snprintf(&r->h3tmp[CIPHERTEXT_LENGTH], HTMP - CIPHERTEXT_LENGTH, ":%s:%s:%s:%s:%s", + request[R_NONCE], request[R_NONCECOUNT], request[R_CLIENTNONCE], + request[R_QOP], (char*)conv); + r->request = request; + r->h1tmplen = strlen(r->h1tmp); + r->h3tmplen = strlen(&r->h3tmp[CIPHERTEXT_LENGTH]) + CIPHERTEXT_LENGTH; + return r; +} + +/* convert response in binary form */ +static void *hdaa_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + ciphertext += 10; + for (i = 0; i < BINARY_SIZE; i++) { + realcipher[i] = atoi16[ARCH_INDEX(ciphertext[i * 2])] * 16 + + atoi16[ARCH_INDEX(ciphertext[i * 2 + 1])]; + } + return (void *) realcipher; +} + +struct fmt_main fmt_HDAA = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + hdaa_tests + }, { + fmt_default_init, + hdaa_valid, + fmt_default_split, + hdaa_binary, + hdaa_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + hdaa_set_salt, + hdaa_set_key, + hdaa_get_key, + fmt_default_clear_keys, + hdaa_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + hdaa_cmp_all, + hdaa_cmp_all, + hdaa_cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/IPB2_fmt.c john-1.7.3.4/src/IPB2_fmt.c --- john-1.7.3.4.orig/src/IPB2_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/IPB2_fmt.c 2008-08-24 07:09:23 +0000 @@ -0,0 +1,252 @@ +/* + * IPB2_fmt.c (version 4) + * + * Invision Power Board 2.x salted MD5 module for Solar Designer's JtR + * Uses Solar Designer's MD5 implementation. + * regenrecht at o2.pl, Jan 2006 + * + * Hashes list should have form of username:$IPB2$salt$hash + * Values to be taken from IPB database, where: + * salt = bin2hex(ibf_members_converge.converge_pass_salt) + * hash = ibf_members_converge.converge_pass_hash + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "md5.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "ipb2" +#define FORMAT_NAME "IPB2 MD5" +#define ALGORITHM_NAME "Invision Power Board 2.x salted MD5" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define MD5_BINARY_SIZE 16 +#define MD5_HEX_SIZE (MD5_BINARY_SIZE * 2) + +#define BINARY_SIZE MD5_BINARY_SIZE + +#define SALT_SIZE 5 +#define PROCESSED_SALT_SIZE MD5_HEX_SIZE + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH (1 + 4 + 1 + SALT_SIZE * 2 + 1 + MD5_HEX_SIZE) + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests ipb2_tests[] = { + {"$IPB2$2e75504633$d891f03a7327639bc632d62a7f302604", "welcome"}, + {"$IPB2$735a213a4e$4f23de7bb115139660db5e953153f28a", "enter"}, + {"$IPB2$5d75343455$de98ba8ca7bb16f43af05e9e4fb8afee", "matrix"}, + {"$IPB2$556c576c39$16d4f29c71b05bd75e61d0254800bfa3", "123456"}, + {NULL} +}; + +static char itoa16_shr_04[] = + "0000000000000000" + "1111111111111111" + "2222222222222222" + "3333333333333333" + "4444444444444444" + "5555555555555555" + "6666666666666666" + "7777777777777777" + "8888888888888888" + "9999999999999999" + "aaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbb" + "cccccccccccccccc" + "dddddddddddddddd" + "eeeeeeeeeeeeeeee" + "ffffffffffffffff"; + +static char itoa16_and_0f[] = + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef"; + +static MD5_CTX ctx; +static char saved_key[PLAINTEXT_LENGTH + 1]; +static int saved_key_len; +static char workspace[MD5_HEX_SIZE * 2]; +static char output[MD5_BINARY_SIZE]; + +static int ipb2_valid(char *ciphertext) +{ + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + + if (strncmp(ciphertext, "$IPB2$", 6) != 0) + return 0; + + if (ciphertext[16] != '$') + return 0; + + if (strspn(ciphertext+6, itoa16) != SALT_SIZE*2) + return 0; + + if (strspn(ciphertext+17, itoa16) != MD5_HEX_SIZE) + return 0; + + return 1; +} + +static void *ipb2_binary(char *ciphertext) +{ + static unsigned char binary_cipher[BINARY_SIZE]; + int i; + + ciphertext += 17; + for (i = 0; i < MD5_HEX_SIZE; ++i) + binary_cipher[i] = + (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + return (void *)binary_cipher; +} + +static void *ipb2_salt(char *ciphertext) +{ + static unsigned char binary_salt[SALT_SIZE]; + static unsigned char salt_hash[MD5_BINARY_SIZE]; + static unsigned char hex_salt[MD5_HEX_SIZE]; + int i; + + ciphertext += 6; + for (i = 0; i < SALT_SIZE; ++i) + binary_salt[i] = + (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + MD5_Init(&ctx); + MD5_Update(&ctx, binary_salt, SALT_SIZE); + MD5_Final(salt_hash, &ctx); + + for (i = 0; i < MD5_BINARY_SIZE; ++i) { + hex_salt[i*2] = itoa16[ARCH_INDEX(salt_hash[i] >> 4)]; + hex_salt[i*2+1] = itoa16[ARCH_INDEX(salt_hash[i] & 0x0f)]; + } + + return (void*)hex_salt; +} + +static void ipb2_set_salt(void *salt) +{ + memcpy((char*)workspace, (char*)salt, PROCESSED_SALT_SIZE); +} + +static int strnfcpy_count(char *dst, char *src, int size) +{ + char *dptr = dst, *sptr = src; + int count = size; + + while (count--) + if (!(*dptr++ = *sptr++)) break; + + return size-count-1; +} + +static void ipb2_set_key(char *key, int index) +{ + static unsigned char key_hash[MD5_BINARY_SIZE]; + unsigned char *kh = key_hash; + unsigned char *workspace_ptr = (unsigned char *) (workspace + PROCESSED_SALT_SIZE); + unsigned char v; + int i; + + saved_key_len = strnfcpy_count(saved_key, key, PLAINTEXT_LENGTH); + + MD5_Init(&ctx); + MD5_Update(&ctx, saved_key, saved_key_len); + MD5_Final(key_hash, &ctx); + + for (i = 0; i < MD5_BINARY_SIZE; ++i) { + v = *kh++; + *workspace_ptr++ = itoa16_shr_04[ARCH_INDEX(v)]; + *workspace_ptr++ = itoa16_and_0f[ARCH_INDEX(v)]; + } +} + +static char *ipb2_get_key(int index) +{ + return saved_key; +} + +static void ipb2_crypt_all(int count) +{ + MD5_Init(&ctx); + MD5_Update(&ctx, workspace, MD5_HEX_SIZE * 2); + MD5_Final((unsigned char *) output, &ctx); +} + +static int ipb2_cmp_all(void *binary, int index) +{ + return !memcmp(binary, output, MD5_BINARY_SIZE); +} + +static int ipb2_cmp_exact(char *source, int index) +{ + return 1; +} + +struct fmt_main fmt_IPB2 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + PROCESSED_SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + ipb2_tests + }, + { + fmt_default_init, + ipb2_valid, + fmt_default_split, + ipb2_binary, + ipb2_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + ipb2_set_salt, + ipb2_set_key, + ipb2_get_key, + fmt_default_clear_keys, + ipb2_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + ipb2_cmp_all, + ipb2_cmp_all, + ipb2_cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/KRB5_fmt.c john-1.7.3.4/src/KRB5_fmt.c --- john-1.7.3.4.orig/src/KRB5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/KRB5_fmt.c 2008-08-25 01:46:32 +0000 @@ -0,0 +1,349 @@ +/* + * KRB5_fmt.c + * + * Kerberos 5 module for John the Ripper by Solar Designer, based on the + * KRB4 module by Dug Song. + * + * Author: Nasko Oskov + * + * Licensing: + * + * The module contains code derived or copied from the Heimdal project. + * + * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Which is distribution of Kerberos based on M.I.T. implementation. + * + * Copyright (C) 1990 by the Massachusetts Institute of Technology + * + */ + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include "arch.h" +#include "misc.h" +#include "formats.h" // needed for format structs +#include "KRB5_std.h" + + +// defines // {{{ +#define MAGIC_PREFIX "$krb5$" +#define MAX_REALM_LEN 64 +#define TGT_SIZE 228 +#define MAX_USER_LEN 64 +#define MAX_PASS_LEN 64 + +#define FORMAT_LABEL "krb5" +#define FORMAT_NAME "Kerberos v5 TGT" +#define ALGORITHM_NAME "krb5 3DES (des3-cbc-sha1)" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 +#define PLAINTEXT_LENGTH 32 +#define BINARY_SIZE 0 +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +/* This string is a bit too short - might give false positives */ +#define KRBTGT "krbtgt" +// }}} + + +/** + * structure to hold the self tests // {{{ + */ +static struct fmt_tests KRB5_fmt_tests[] = { + {"$krb5$oskov$ACM.UIUC.EDU$4730d7249765615d6f3652321c4fb76d09fb9cd06faeb0c31b8737f9fdfcde4bd4259c31cb1dff25df39173b09abdff08373302d99ac09802a290915243d9f0ea0313fdedc7f8d1fae0d9df8f0ee6233818d317f03a72c2e77b480b2bc50d1ca14fba85133ea00e472c50dbc825291e2853bd60a969ddb69dae35b604b34ea2c2265a4ffc72e9fb811da17c7f2887ccb17e2f87cd1f6c28a9afc0c083a9356a9ee2a28d2e4a01fc7ea90cc8836b8e25650c3a1409b811d0bad42a59aa418143291d42d7b1e6cb5b1876a4cc758d721323a762e943f774630385c9faa68df6f3a94422f97", "p4ssW0rd"}, + {"$krb5$oskov$ACM.UIUC.EDU$6cba0316d38e31ba028f87394792baade516afdfd8c5a964b6a7677adbad7815d778b297beb238394aa97a4d495adb7c9b7298ba7c2a2062fb6c9a4297f12f83755060f4f58a1ea4c7026df585cdfa02372ad619ab1a4ec617ad23e76d6e37e36268d9aa0abcf83f11fa8092b4328c5e6c577f7ec6f1c1684d9c99a309eee1f5bd764c4158a2cf311cded8794b2de83131c3dc51303d5300e563a2b7a230eac67e85b4593e561bf6b88c77b82c729e7ba7f3d2f99b8dc85b07873e40335aff4647833a87681ee557fbd1ffa1a458a5673d1bd3c1587eceeabaebf4e44c24d9a8ac8c1d89", "Nask0Oskov"}, + {NULL} +}; +// }}} + +/** + * struct to save the salt into + */ +struct salt { // {{{ + char realm[MAX_REALM_LEN]; + char user[MAX_USER_LEN]; + char tgt_ebin[TGT_SIZE]; + char passwd[MAX_PASS_LEN]; +}; +#define SALT_SIZE sizeof(struct salt) +// }}} + +struct key { // {{{ + char passwd[MAX_PASS_LEN]; + char key[MAX_PASS_LEN]; + DES_key_schedule sched[3]; +}; +// }}} + +static struct salt *psalt = NULL; +static struct key skey; + +static char username[MAX_USER_LEN]; +static char realm[MAX_REALM_LEN]; +static char password[MAX_PASS_LEN]; + +// initialization vector for des +static DES_cblock ivec; + +krb5_key _krb5key; +krb5_key *krb5key = &_krb5key; + +/** + * hex2bin // {{{ + */ +static void hex2bin(char *src, u_char *dst, int outsize) { + char *p, *pe; + u_char *q, *qe, ch, cl; + + pe = src + strlen(src); + qe = dst + outsize; + + for (p = src, q = dst; p < pe && q < qe && isxdigit((int)(unsigned char)*p); p += 2) { + ch = tolower((int)(unsigned char)p[0]); + cl = tolower((int)(unsigned char)p[1]); + + if ((ch >= '0') && (ch <= '9')) ch -= '0'; + else if ((ch >= 'a') && (ch <= 'f')) ch -= 'a' - 10; + else return; + + if ((cl >= '0') && (cl <= '9')) cl -= '0'; + else if ((cl >= 'a') && (cl <= 'f')) cl -= 'a' - 10; + else return; + + *q++ = (ch << 4) | cl; + } +} +// }}} + +/** + * krb5_decrypt_compare // {{{ + * + */ +int krb5_decrypt_compare() { +/* TGT_SIZE is not a multiple of DES block size; add space for one extra + * DES block to make sure the OpenSSL routines will not overwrite stack + * space beyond the end of plain[] when they operate on whole DES blocks. */ + char plain[TGT_SIZE + 8]; + int i; + + memset(krb5key->key, 0x00, DES3_KEY_SIZE); + memset(krb5key->schedule, 0x00, DES3_KEY_SCHED_SIZE); + +/* NUL padding is intentional */ + strncpy(username, psalt->user, MAX_USER_LEN); + strncpy(realm, psalt->realm, MAX_REALM_LEN); + strncpy(password, skey.passwd, MAX_PASS_LEN); + + // do str2key + str2key(username, realm, password, krb5key); + +/* Possible optimization: we might not have to decrypt the entire thing */ + des3_decrypt(krb5key, psalt->tgt_ebin, plain, TGT_SIZE); + + for(i=0;ipasswd, skey.passwd, MAX_PASS_LEN); + return 1; + } + return 0; +} +// }}} + +/** + * int krb5_valid // {{{ + * + */ +static int krb5_valid(char *ciphertext) { + + if (strncmp(ciphertext, MAGIC_PREFIX, strlen(MAGIC_PREFIX)) != 0) + return 0; + + return 1; +} +// }}} + +/** + * void * krb5_salt // {{{ + * + */ +static void * krb5_salt(char *ciphertext) { + + struct salt *salt = NULL; + char *data = ciphertext, *p; + + // check the presence of $krb5$ + if (strncmp(data, MAGIC_PREFIX, strlen(MAGIC_PREFIX)) == 0) { + // advance past the $krb5$ string + data += strlen(MAGIC_PREFIX); + + // allocate memory for the struct + salt = malloc(sizeof(struct salt)); + if (salt == NULL) + return NULL; + + // find and copy the user field + p = strchr(data, '$'); + strnzcpy(salt->user, data, (p - data) + 1); + data = p + 1; + + // find and copy the realm field + p = strchr(data, '$'); + strnzcpy(salt->realm, data, (p - data) + 1); + data = p + 1; + + // copy over the TGT in a binary form to the salt struct + hex2bin(data, (u_char *) salt->tgt_ebin, TGT_SIZE); + } + return salt; +} +// }}} + +/** + * void krb5_set_salt // {{{ + * + */ +static void krb5_set_salt(void *salt) { + psalt = (struct salt *) salt; +} +// }}} + +/** + * void krb5_set_key // {{{ + * + */ +static void krb5_set_key(char *key, int index) { + + // copy the string key to the saved key + memset(skey.passwd, 0x00, MAX_PASS_LEN); + strnzcpy(skey.passwd, key, sizeof(skey.passwd)); + +} +// }}} + +/** + * char * krb5_get_key // {{{ + * + */ +static char * krb5_get_key(int index) { + return skey.passwd; +} +// }}} + +/** + * void krb5_crypt_all // {{{ + * + */ +static void krb5_crypt_all(int count) { + // do nothing +} +// }}} + +/** + * int krb5_cmp_all // {{{ + * + */ +static int krb5_cmp_all(void *binary, int count) { + return krb5_decrypt_compare(); +} +// }}} + +/** + * int krb5_cmp_one // {{{ + * + */ +static int krb5_cmp_one(void *binary, int count) { + + return krb5_decrypt_compare(); + +} +// }}} + +/** + * int krb5_cmp_exact // {{{ + * + */ +static int krb5_cmp_exact(char *source, int index) { + return 1; +} +// }}} + +/** + * void krb5_init // {{{ + * + */ +static void krb5_init() { + + memset(&ivec, 0x00, sizeof(ivec)); + memset(&skey, 0x00, sizeof(skey)); + memset(krb5key, 0x00, sizeof(krb5_key)); + + krb5key->key = (char *) malloc(DES3_KEY_SIZE); + krb5key->schedule = (char *) malloc(DES3_KEY_SCHED_SIZE); + memset(krb5key->key, 0x00, DES3_KEY_SIZE); + memset(krb5key->schedule, 0x00, DES3_KEY_SCHED_SIZE); + +} +// }}} + +/** + * fmt_main struct with KRB5 values // {{{ + */ +struct fmt_main fmt_KRB5 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + KRB5_fmt_tests + }, { + krb5_init, + krb5_valid, + fmt_default_split, + fmt_default_binary, + krb5_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + krb5_set_salt, + krb5_set_key, + krb5_get_key, + fmt_default_clear_keys, + krb5_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + krb5_cmp_all, + krb5_cmp_one, + krb5_cmp_exact + } +}; +// }}} + diff -urpN john-1.7.3.4.orig/src/KRB5_std.c john-1.7.3.4/src/KRB5_std.c --- john-1.7.3.4.orig/src/KRB5_std.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/KRB5_std.c 2008-08-25 01:46:57 +0000 @@ -0,0 +1,281 @@ +/* + * KRB5_std.c + * + * Kerberos 5 module for John the Ripper by Solar Designer, based on the + * KRB4 module by Dug Song. + * + * Author: Nasko Oskov + * + * Licensing: + * + * The module contains code derived or copied from the Heimdal project. + * + * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Which is distribution of Kerberos based on M.I.T. implementation. + * + * Copyright (C) 1990 by the Massachusetts Institute of Technology + * + */ + + +#include +#include +#include + +#include "KRB5_std.h" + +static DES_cblock ivec; +static const char derive_const[5] = "\x00\x00\x00\x03\xaa"; + +/** + * Heimdal rr13 function // {{{ + */ +static inline void rr13(unsigned char *buf, int len) { + + unsigned char *tmp; + int bytes = (len + 7) / 8; + int i; + + int bb; + int b1, s1, b2, s2; + + const int bits = 13 % len; + const int lbit = len % 8; + + if(len == 0) + return; + + tmp = (unsigned char *) malloc(bytes); + memcpy(tmp, buf, bytes); + if(lbit) { + // pad final byte with inital bits + tmp[bytes - 1] &= 0xff << (8 - lbit); + for(i = lbit; i < 8; i += len) + tmp[bytes - 1] |= buf[0] >> i; + } + for(i = 0; i < bytes; i++) { + // calculate first bit position of this byte + bb = 8 * i - bits; + while(bb < 0) + bb += len; + // byte offset and shift count + b1 = bb / 8; + s1 = bb % 8; + + if(bb + 8 > bytes * 8) + // watch for wraparound + s2 = (len + 8 - s1) % 8; + else + s2 = 8 - s1; + b2 = (b1 + 1) % bytes; + buf[i] = (tmp[b1] << s1) | (tmp[b2] >> s2); + } + free(tmp); +} +// }}} + +/** + * Heimdal add1 function // {{{ + */ +static inline void add1(unsigned char *a, unsigned char *b, size_t len) { + int i, x; + int carry = 0; + for(i = len - 1; i >= 0; i--){ + x = a[i] + b[i] + carry; + carry = x > 0xff; + a[i] = x & 0xff; + } + for(i = len - 1; carry && i >= 0; i--){ + x = a[i] + carry; + carry = x > 0xff; + a[i] = x & 0xff; + } +} +// }}} + +/** + * Heimdal _krb5_n_fold function // {{{ + */ +static inline void _krb5_n_fold(const void *str, int len, void *key, int size) { + + int maxlen = 2 * max(size, len), l = 0; + unsigned char *tmp = (unsigned char *) malloc(maxlen); + unsigned char *buf = (unsigned char *) malloc(len); + + memcpy(buf, str, len); + memset(key, 0, size); + do { + memcpy(tmp + l, buf, len); + l += len; + rr13(buf, len * 8); + while(l >= size) { + add1(key, tmp, size); + l -= size; + if(l == 0) + break; + memmove(tmp, tmp + size, l); + } + } while(l != 0); + sfree(buf, len); + sfree(tmp, maxlen); +} +// }}} + +/** + * Heimdal DES3_postproc function // {{{ + */ +static inline void DES3_postproc(unsigned char *k, int len, krb5_key *krb5key) { + unsigned char x[24]; + int i, j; + unsigned char foo; + unsigned char b; + + memset(x, 0, sizeof(x)); + for (i = 0; i < 3; ++i) { + for (j = 0; j < 7; ++j) { + b = k[7 * i + j]; + x[8 * i + j] = b; + } + foo = 0; + for (j = 6; j >= 0; --j) { + foo |= k[7 * i + j] & 1; + foo <<= 1; + } + x[8 * i + 7] = foo; + } + k = (unsigned char *) krb5key->key; + memcpy(k, x, 24); + DES_set_odd_parity((DES_cblock*)k); + DES_set_odd_parity((DES_cblock*)(k + 8)); + DES_set_odd_parity((DES_cblock*)(k + 16)); + +#if 0 + memset(x, 0, sizeof(x)); +#endif +} +// }}} + +/** + * Heimdal based derive_key function // {{{ + */ +static inline void derive_key(const void *constant, int len, krb5_key *krb5key) { + + unsigned char *k; + unsigned int nblocks = 0, i; + DES_cblock *bk; + DES_key_schedule *s; + + // set the des schedule + bk = (DES_cblock*) krb5key->key; + s = (DES_key_schedule *) krb5key->schedule; + DES_set_key(&bk[0], &s[0]); + DES_set_key(&bk[1], &s[1]); + DES_set_key(&bk[2], &s[2]); + + if(DES3_BLOCK_SIZE * 8 < DES3_KEY_BITS || len != DES3_BLOCK_SIZE) { + nblocks = (DES3_KEY_BITS + DES3_BLOCK_SIZE * 8 - 1) / (DES3_BLOCK_SIZE * 8); + k = (unsigned char *) malloc(nblocks * DES3_BLOCK_SIZE); + if(k == NULL) { + printf("malloc: out of memory\n"); + exit(1); + } + _krb5_n_fold(constant, len, k, DES3_BLOCK_SIZE); + for(i = 0; i < nblocks; i++) { + if(i > 0) + memcpy(k + i * DES3_BLOCK_SIZE, k + (i - 1) * DES3_BLOCK_SIZE, DES3_BLOCK_SIZE); + + memset(ivec, 0x00, sizeof(ivec)); + DES_ede3_cbc_encrypt((void *) k + i * DES3_BLOCK_SIZE, (void *) k + i * DES3_BLOCK_SIZE, + DES3_BLOCK_SIZE, &s[0], &s[1], &s[2], (DES_cblock *) ivec, 1); + } + } else { + printf("Error, should never get here\n"); + exit(1); + } + + // keytype dependent post-processing + DES3_postproc(k, nblocks * DES3_BLOCK_SIZE, krb5key); + + sfree(k, nblocks * DES3_BLOCK_SIZE); +} +// }}} + +/** + * Heimdal based string_to_key_derived function // {{{ + */ +static inline void string_to_key_derived(const void *passwd, int len, krb5_key *krb5key) { + + unsigned char *tmp; + + tmp = (unsigned char *) malloc(DES3_KEY_BITS_BYTES); + if(tmp == NULL) { + printf("malloc: out of memory\n"); + // FIXME make it real return value if sometime this is needed + exit(1); + } + _krb5_n_fold(passwd, len, tmp, DES3_KEY_BITS_BYTES); + + DES3_postproc(tmp, DES3_KEY_BITS_BYTES, krb5key); + derive_key("kerberos", strlen("kerberos"), krb5key); + + sfree(tmp, DES3_KEY_BITS_BYTES); +} +// }}} + +/** + * des3_decrypt // {{{ + */ +void des3_decrypt(krb5_key *key, char *cipher, char *plain, int len) { + + DES_cblock *k; + DES_key_schedule *s; + + memset(&ivec, 0x00, sizeof(ivec)); + + k = (DES_cblock *) key->key; + s = (DES_key_schedule *) key->schedule; + + DES_set_key(&k[0], &s[0]); + DES_set_key(&k[1], &s[1]); + DES_set_key(&k[2], &s[2]); + + DES_ede3_cbc_encrypt((const unsigned char*) cipher, (unsigned char*) plain, len, &s[0], &s[1], &s[2], &ivec, 0); + +} +// }}} + +/** + * str2key // {{{ + */ +void str2key(char *user, char *realm, char *passwd, krb5_key *krb5key) { + int offset = 0; + char *text; + + text = (char*) malloc(strlen(user) + strlen(realm) + strlen(passwd)); + if (text == NULL) { + return; + } + + memset(krb5key->key, 0x00, DES3_KEY_SIZE); + memset(krb5key->schedule, 0x00, DES3_KEY_SCHED_SIZE); + + // make the string from the passwd, realm, username + offset = 0; + memcpy(text + offset, passwd, strlen(passwd)); + offset += strlen(passwd); + memcpy(text + offset, realm, strlen(realm)); + offset += strlen(realm); + memcpy(text + offset, user, strlen(user)); + offset += strlen(user); + + string_to_key_derived(text, offset, krb5key); + + // derive key from key + derive_key(derive_const, sizeof(derive_const), krb5key); + +} +// }}} + diff -urpN john-1.7.3.4.orig/src/KRB5_std.h john-1.7.3.4/src/KRB5_std.h --- john-1.7.3.4.orig/src/KRB5_std.h 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/KRB5_std.h 2008-08-25 01:45:55 +0000 @@ -0,0 +1,56 @@ +/* + * KRB5_std.h + * + * Kerberos 5 module for John the Ripper by Solar Designer, based on the + * KRB4 module by Dug Song. + * + * Author: Nasko Oskov + * + * Licensing: + * + * The module contains code derived or copied from the Heimdal project. + * + * Copyright (c) 1997-2000 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Which is distribution of Kerberos based on M.I.T. implementation. + * + * Copyright (C) 1990 by the Massachusetts Institute of Technology + * + */ + +#ifndef _KRB5_STD_H_ +#define _KRB5_STD_H_ + +#include + +#define DES3_BLOCK_SIZE 8 +#define DES3_KEY_SIZE 24 +#define DES3_KEY_BITS 168 +#define DES3_KEY_BITS_BYTES DES3_KEY_BITS/8 +#define DES3_KEY_SCHED_SIZE (sizeof(DES_key_schedule) * 3) + +#ifndef sfree +#define sfree(x, len) if (x) { /* memset(x, 0x00, len); */ free(x); } +#endif + +#ifndef min +#define min(A, B) ((A) < (B) ? (A): (B)) +#endif + +#ifndef max +#define max(A, B) ((A) > (B) ? (A): (B)) +#endif + +typedef struct _krb5_key { + char *key; + char *schedule; +} krb5_key; + +void des3_decrypt(krb5_key *key, char *cipher, char *plain, int len); + +void str2key(char *user, char *realm, char *passwd, krb5_key *krb5key); + +#endif // _KRB5_STD_H_ + diff -urpN john-1.7.3.4.orig/src/MD5_apache_fmt.c john-1.7.3.4/src/MD5_apache_fmt.c --- john-1.7.3.4.orig/src/MD5_apache_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/MD5_apache_fmt.c 2008-08-24 07:09:43 +0000 @@ -0,0 +1,198 @@ +/* + Modified by Sun-Zero + 2004. 07. 26. + + Now, its work with md5 hash of apache. + The original john patch came from + http://lists.jammed.com/pen-test/2001/11/0134.html by + Kostas Evangelinos (kos at bastard.net) +*/ + +/* + * This file is part of John the Ripper password cracker, + * Copyright (c) 1996-2001 by Solar Designer + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "MD5_std.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "md5a" +#define FORMAT_NAME "Apache MD5" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 15 +#define CIPHERTEXT_LENGTH 22 + +#define BINARY_SIZE 4 +#define SALT_SIZE 8 + +#define MIN_KEYS_PER_CRYPT MD5_N +#define MAX_KEYS_PER_CRYPT MD5_N + + +static struct fmt_tests tests[] = { + {"$apr1$Q6ZYh...$RV6ft2bZ8j.NGrxLYaJt9.", "test"}, + {"$apr1$rBXqc...$NlXxN9myBOk95T0AyLAsJ0", "john"}, + {"$apr1$Grpld/..$qp5GyjwM2dnA5Cdej9b411", "the"}, + {"$apr1$GBx.D/..$yfVeeYFCIiEXInfRhBRpy/", "ripper"}, + {NULL} +}; + +static char saved_key[MD5_N][PLAINTEXT_LENGTH + 1]; + +static int valid(char *ciphertext) +{ + char *pos, *start; + + if (strncmp(ciphertext, "$apr1$", 6)) return 0; + + /* magic string */ + start = &ciphertext[1]; + for (pos = start; *pos && *pos != '$'; pos++); + if (!*pos || pos < start+1 || pos > start+MD5_MAGIC_LENGTH+1) + return 0; + + /* salt */ + start = ++pos; + for (pos = start; *pos && *pos != '$'; pos++); + if (!*pos || pos < start || pos > start+8) + return 0; + + + start = ++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; +} + +static int binary_hash_0(void *binary) +{ + return *(MD5_word *)binary & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return *(MD5_word *)binary & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return *(MD5_word *)binary & 0xFFF; +} + +static int get_hash_0(int index) +{ + return MD5_out[index][0] & 0xF; +} + +static int get_hash_1(int index) +{ + return MD5_out[index][0] & 0xFF; +} + +static int get_hash_2(int index) +{ + 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; +} + +static void set_key(char *key, int index) +{ + MD5_std_set_key(key, index); + + strnfcpy(saved_key[index], key, PLAINTEXT_LENGTH); +} + +static char *get_key(int index) +{ + saved_key[index][PLAINTEXT_LENGTH] = 0; + + return saved_key[index]; +} + +static int cmp_all(void *binary, int index) +{ +#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_TYPE_APACHE), MD5_out[index], + sizeof(MD5_binary)); +} + + +static void crypt_all(int count) { + MD5_std_crypt(MD5_TYPE_APACHE); +} + +static void *get_salt(char *ciphertext) { + return MD5_std_get_salt(ciphertext, MD5_TYPE_APACHE); +} + +static void *get_binary(char *ciphertext) { + return MD5_std_get_binary(ciphertext, MD5_TYPE_APACHE); +} + +struct fmt_main fmt_MD5_apache = { + { + FORMAT_LABEL, + FORMAT_NAME, + MD5_ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + MD5_std_init, + valid, + fmt_default_split, + get_binary, //(void *(*)(char *))MD5_std_get_binary, + get_salt, //(void *(*)(char *))MD5_std_get_salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2 + }, + salt_hash, + (void (*)(void *))MD5_std_set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, //(void (*)(int))MD5_std_crypt, + { + get_hash_0, + get_hash_1, + get_hash_2 + }, + cmp_all, + cmp_all, + cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/MD5_fmt.c john-1.7.3.4/src/MD5_fmt.c --- john-1.7.3.4.orig/src/MD5_fmt.c 2008-06-22 01:02:29 +0000 +++ john-1.7.3.4/src/MD5_fmt.c 2008-08-24 07:09:52 +0000 @@ -1,4 +1,11 @@ /* + Modified by Sun-Zero + 2004. 07. 26. + + Now, its work with md5 hash of apache. +*/ + +/* * This file is part of John the Ripper password cracker, * Copyright (c) 1996-2001,2008 by Solar Designer */ @@ -122,10 +129,22 @@ static int cmp_one(void *binary, int ind static int cmp_exact(char *source, int index) { - return !memcmp(MD5_std_get_binary(source), MD5_out[index], + return !memcmp(MD5_std_get_binary(source, MD5_TYPE_STD), MD5_out[index], sizeof(MD5_binary)); } +static void crypt_all(int count) { + MD5_std_crypt(MD5_TYPE_STD); +} + +static void *get_salt(char *ciphertext) { + return MD5_std_get_salt(ciphertext, MD5_TYPE_STD); +} + +static void *get_binary(char *ciphertext) { + return MD5_std_get_binary(ciphertext, MD5_TYPE_STD); +} + struct fmt_main fmt_MD5 = { { FORMAT_LABEL, @@ -144,8 +163,8 @@ struct fmt_main fmt_MD5 = { MD5_std_init, valid, fmt_default_split, - (void *(*)(char *))MD5_std_get_binary, - (void *(*)(char *))MD5_std_get_salt, + get_binary, //(void *(*)(char *))MD5_std_get_binary, + get_salt, //(void *(*)(char *))MD5_std_get_salt, { binary_hash_0, binary_hash_1, @@ -156,7 +175,7 @@ struct fmt_main fmt_MD5 = { set_key, get_key, fmt_default_clear_keys, - (void (*)(int))MD5_std_crypt, + crypt_all, // (void (*)(int))MD5_std_crypt, { get_hash_0, get_hash_1, diff -urpN john-1.7.3.4.orig/src/MD5_std.c john-1.7.3.4/src/MD5_std.c --- john-1.7.3.4.orig/src/MD5_std.c 2006-05-08 06:31:50 +0000 +++ john-1.7.3.4/src/MD5_std.c 2008-08-24 07:10:04 +0000 @@ -1,4 +1,14 @@ /* + Modified by Sun-Zero + 2004. 07. 26. + + Now, its work with md5 hash of apache. + The original john patch came from + http://lists.jammed.com/pen-test/2001/11/0134.html by + Kostas Evangelinos (kos at bastard.net) +*/ + +/* * This file is part of John the Ripper password cracker, * Copyright (c) 1996-2001,2003,2006 by Solar Designer * @@ -400,7 +410,7 @@ void MD5_std_set_key(char *key, int inde order[19][index].length = current->l.pp; } -void MD5_std_crypt(void) +void MD5_std_crypt(int md5_type) { int length, index, mask; MD5_pattern *line; @@ -482,12 +492,21 @@ void MD5_std_crypt(void) #if MD5_X2 for (index = 0, key = pool; index < MD5_N; index++, key++) { #endif + memcpy(&block[index], key->o.p.b, key->l.p); + if (md5_type == MD5_TYPE_APACHE) { + memcpy(&block[index].b[key->l.p], "$apr1$", 6); + memcpy(&block[index].b[key->l.p + 6], key->s, key->l.s); + memcpy(&block[index].b[key->l.ps + 6], + MD5_out[index], key->l.p); + length = key->l.psp + 6; + } else { 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++] = @@ -853,13 +872,26 @@ static void MD5_body(MD5_word x0[15], MD #endif -char *MD5_std_get_salt(char *ciphertext) +char *MD5_std_get_salt(char *ciphertext, int md5_type) { static char out[9]; int length; + char *pos; + char *start; - for (length = 0; length < 8; length++) - if ((out[length] = ciphertext[3 + length]) == '$') break; + start = &ciphertext[1]; + if (md5_type == MD5_TYPE_APACHE) { + for (pos = start; *pos && *pos != '$'; pos++); + start = ++pos; + } + + for (length = 0; length < 8; length++) { + if (md5_type == MD5_TYPE_APACHE) { + if ((out[length] = start[length]) == '$') break; + } else { + if ((out[length] = ciphertext[3 + length]) == '$') break; + } + } out[length] = 0; return out; @@ -876,7 +908,7 @@ char *MD5_std_get_salt(char *ciphertext) out.b[b2] = value >> 8; \ out.b[b3] = value; -MD5_word *MD5_std_get_binary(char *ciphertext) +MD5_word *MD5_std_get_binary(char *ciphertext, int md5_type) { static union { MD5_binary w; @@ -885,7 +917,16 @@ MD5_word *MD5_std_get_binary(char *ciphe char *pos; MD5_word value; + char *start; + if (md5_type == MD5_TYPE_APACHE) { + start = &ciphertext[1]; + for (pos = start; *pos && *pos != '$'; pos++); + if (!*pos || pos < start+1 || pos > start+MD5_MAGIC_LENGTH+1) return 0; + pos++; + while (*pos++ != '$'); + } else { pos = ciphertext + 3; while (*pos++ != '$'); + } TO_BINARY(0, 6, 12); TO_BINARY(1, 7, 13); diff -urpN john-1.7.3.4.orig/src/MD5_std.h john-1.7.3.4/src/MD5_std.h --- john-1.7.3.4.orig/src/MD5_std.h 2003-12-03 10:23:14 +0000 +++ john-1.7.3.4/src/MD5_std.h 2008-08-24 04:59:02 +0000 @@ -13,6 +13,9 @@ #include "arch.h" #include "common.h" +#define MD5_TYPE_STD 0 +#define MD5_TYPE_APACHE 1 + typedef ARCH_WORD_32 MD5_word; /* @@ -88,6 +91,8 @@ extern MD5_std_combined MD5_std_all; #define MD5_ALGORITHM_NAME "32/" ARCH_BITS_STR #endif +#define MD5_MAGIC_LENGTH 10 + /* * Initializes the internal structures. */ @@ -107,16 +112,16 @@ extern void MD5_std_set_key(char *key, i /* * Main encryption routine, sets MD5_out. */ -extern void MD5_std_crypt(void); +extern void MD5_std_crypt(int md5_type); /* * Returns the salt for MD5_std_set_salt(). */ -extern char *MD5_std_get_salt(char *ciphertext); +extern char *MD5_std_get_salt(char *ciphertext, int md5_type); /* * Converts an ASCII ciphertext to binary. */ -extern MD5_word *MD5_std_get_binary(char *ciphertext); +extern MD5_word *MD5_std_get_binary(char *ciphertext, int md5_type); #endif diff -urpN john-1.7.3.4.orig/src/MYSQL_fast_fmt.c john-1.7.3.4/src/MYSQL_fast_fmt.c --- john-1.7.3.4.orig/src/MYSQL_fast_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/MYSQL_fast_fmt.c 2008-08-24 09:52:01 +0000 @@ -0,0 +1,243 @@ +/* MYSQL_half_fmt.c + * + * Copyright (c) 2008 by + * + * John the ripper MYSQL-fast module + * + * + * Note: The mysql hash's first 8byte is relevant, + * the another ones depends on the first 8. Maybe + * the passwords after 9-10character have collision + * in the first 8byte, so we have to check the full + * hash. + * + * Unbelievable good optimization by Péter Kasza + * + * http://rycon.hu/ + */ + +#include +#include +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "mysql-fast" +#define FORMAT_NAME "MYSQL_fast" +#define ALGORITHM_NAME "mysql-fast" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 16 + +#define BINARY_SIZE 8 +#define SALT_SIZE 0 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 64 + +static struct fmt_tests mysql_tests[] = { + // ciphertext, plaintext + {"445ff82636a7ba59", "probe"}, + {"60671c896665c3fa", "a"}, + {"1acbed4a27b20da3", "hash"}, + {"77ff75006118bab8", "hacker"}, + {"1b38cd9c2f809809", "hacktivity2008"}, + {"1b38cd9c2f809809", "hacktivity 2008"}, + {"6fc81597422015a8", "johnmodule"}, + {NULL} +}; + +static ARCH_WORD_32 crypt_key[MAX_KEYS_PER_CRYPT][BINARY_SIZE / 4]; +static char saved_key[MAX_KEYS_PER_CRYPT][PLAINTEXT_LENGTH + 1]; + +static int mysql_valid(char* ciphertext) +{ + unsigned int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + + for (i = 0; i < CIPHERTEXT_LENGTH; i++) + { + if (!(((ciphertext[i] >= '0') && (ciphertext[i] <= '9')) || + ((ciphertext[i] >= 'a') && (ciphertext[i] <= 'f')))) + return 0; + } + + return 1; +} + +static void mysql_set_salt(void* salt) { } + +static void* mysql_get_binary(char* ciphertext) +{ + static unsigned char buff[BINARY_SIZE / 2]; + unsigned int i; + + for (i = 0; i < BINARY_SIZE / 2; i++) + { +#if ARCH_LITTLE_ENDIAN == 1 + buff[((BINARY_SIZE / 2) - 1) - i] = atoi16[ARCH_INDEX(ciphertext[i * 2])] * 16 + atoi16[ARCH_INDEX(ciphertext[i * 2 + 1])]; +#else + buff[i] = atoi16[ARCH_INDEX(ciphertext[i * 2])] * 16 + atoi16[ARCH_INDEX(ciphertext[i * 2 + 1])]; +#endif + } + + return buff; +} + +static void mysql_set_key(char* key, int index) +{ + strnzcpy(saved_key[index], key, PLAINTEXT_LENGTH + 1); +} + +static char* mysql_get_key(int index) +{ + return saved_key[index]; +} + +static int mysql_cmp_one(void* binary, int index) +{ + return *(ARCH_WORD_32 *)binary == crypt_key[index][0]; +} + +static int mysql_cmp_all(void* binary, int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) { + if (*(ARCH_WORD_32 *)binary == crypt_key[i][0]) + return 1; + } + + return 0; +} + +static int mysql_cmp_exact(char* source, int index) +{ + register unsigned long nr = 1345345333L, add = 7, nr2 = 0x12345671L; + register unsigned long tmp; + char* password; + char ctmp[CIPHERTEXT_LENGTH+1]; + + password = saved_key[index]; + for (; *password; password++) + { + if (*password == ' ' || *password == '\t') + continue; + + tmp = (unsigned long) (unsigned char) *password; + nr ^= (((nr & 63) + add) * tmp) + (nr << 8); + nr2 += (nr2 << 8) ^ nr; + add += tmp; + } + + sprintf(ctmp, "%08lx%08lx", (nr & (((unsigned long) 1L << 31) -1L)), (nr2 & (((unsigned long) 1L << 31) -1L))); + return !memcmp(source, ctmp, CIPHERTEXT_LENGTH); +} + +static void mysql_crypt_all(int count) +{ + unsigned long nr, add; + unsigned long tmp; + unsigned int i; + char* password; + + for (i = 0; i < count; i++) + { + nr=1345345333L; + add=7; + + password = saved_key[i]; + for (; *password; password++) + { + if (*password == ' ' || *password == '\t') + continue; + + tmp = (unsigned long) (unsigned char) *password; + nr ^= (((nr & 63) + add) * tmp) + (nr << 8); + add += tmp; + } + + crypt_key[i][0] = (nr & (((ARCH_WORD_32)1 << 31) - 1)); + } +} + +int mysql_binary_hash_0(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xF; +} + +int mysql_binary_hash_1(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xFF; +} + +int mysql_binary_hash_2(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xFFF; +} + +int mysql_get_hash_0(int index) +{ + return crypt_key[index][0] & 0xF; +} + +int mysql_get_hash_1(int index) +{ + return crypt_key[index][0] & 0xFF; +} + +int mysql_get_hash_2(int index) +{ + return crypt_key[index][0] & 0xFFF; +} + +struct fmt_main fmt_MYSQL_fast = +{ + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + mysql_tests + }, { + fmt_default_init, + mysql_valid, + fmt_default_split, + mysql_get_binary, + fmt_default_salt, + { + mysql_binary_hash_0, + mysql_binary_hash_1, + mysql_binary_hash_2 + }, + fmt_default_salt_hash, + mysql_set_salt, + mysql_set_key, + mysql_get_key, + fmt_default_clear_keys, + mysql_crypt_all, + { + mysql_get_hash_0, + mysql_get_hash_1, + mysql_get_hash_2 + }, + mysql_cmp_all, + mysql_cmp_one, + mysql_cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/MYSQL_fmt.c john-1.7.3.4/src/MYSQL_fmt.c --- john-1.7.3.4.orig/src/MYSQL_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/MYSQL_fmt.c 2008-08-24 07:10:21 +0000 @@ -0,0 +1,241 @@ +//////////////////////////////////////////////////////////////// +// MySQL password cracker - v1.0 - 16.1.2003 +// +// by Andrew Hintz drew at overt.org +// +// This production has been brought to you by +// 4tphi and violating +// +// This file is an add-on to John the Ripper +// +// Part of this code is based on the MySQL brute password cracker +// mysqlpassword.c by Chris Given +// This program executes about 75% faster than mysqlpassword.c +// John the ripper also performs sophisticated password guessing. +// +// John the Ripper will expect the MySQL password file to be +// in the following format (without the leading // ): +// dumb_user:5d2e19393cc5ef67 +// another_luser:28ff8d49159ffbaf + +#include +#include +#include +#include + +// johntr includes +#include "arch.h" +#include "misc.h" +#include "formats.h" +#include "common.h" + +//johntr defines +#define FORMAT_LABEL "mysql" +#define FORMAT_NAME "MYSQL" +#define ALGORITHM_NAME "mysql" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +// Increase the PLAINTEXT_LENGTH value for longer passwords. +// You can also set it to 8 when using MySQL systems that truncate +// the password to only 8 characters. +#define PLAINTEXT_LENGTH 32 + +#define CIPHERTEXT_LENGTH 16 + +#define BINARY_SIZE 16 +#define SALT_SIZE 0 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + + +//used for mysql scramble function +struct rand_struct { + unsigned long seed1,seed2,max_value; + double max_value_dbl; +}; + + +void make_scrambled_password(char *,const char *); +char *scramble(char *,const char *,const char *, int); + +//test cases +static struct fmt_tests mysql_tests[] = { + {"30f098972cc8924d", "http://guh.nu"}, + {"3fc56f6037218993", "Andrew Hintz"}, + {"697a7de87c5390b2", "drew"}, + {"1eb71cf460712b3e", "http://4tphi.net"}, + {"28ff8d49159ffbaf", "http://violating.us"}, + {"5d2e19393cc5ef67", "password"}, + {NULL} +}; + + +//stores the ciphertext for value currently being tested +static char crypt_key[BINARY_SIZE+1]; + +//used by set_key +static char saved_key[PLAINTEXT_LENGTH + 1]; + +static int mysql_valid(char *ciphertext) { //returns 0 for invalid ciphertexts + + int i; //used as counter in loop + + //ciphertext is 16 characters + if (strlen(ciphertext) != 16) return 0; + + //ciphertext is ASCII representation of hex digits + for (i = 0; i < 16; i++){ + if (!( ((48 <= ciphertext[i])&&(ciphertext[i] <= 57)) || + ((97 <= ciphertext[i])&&(ciphertext[i] <= 102)) )) + return 0; + } + + return 1; +} + +static void mysql_set_salt(void *salt) { } + +static void mysql_set_key(char *key, int index) { + strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1); +} + +static char *mysql_get_key(int index) { + return saved_key; +} + +static int mysql_cmp_all(void *binary, int index) { //also is mysql_cmp_one + return !memcmp(binary, crypt_key, BINARY_SIZE); +} + +static int mysql_cmp_exact(char *source, int count){ + return (1); // mysql_cmp_all fallthrough? +} + +static void mysql_crypt_all(int count) { + // get plaintext input in saved_key put it into ciphertext crypt_key + make_scrambled_password(crypt_key,saved_key); +} + +//////////////////////////////////////////////////////////////// +//begin mysql code +// This code was copied from mysqlpassword.c by Chris Given +// He probably copied it from password.c in the MySQL source +// The code is GPLed + +void randominit(struct rand_struct *rand_st,unsigned long seed1, unsigned long seed2) { + rand_st->max_value= 0x3FFFFFFFL; + rand_st->max_value_dbl=(double) rand_st->max_value; + rand_st->seed1=seed1%rand_st->max_value ; + rand_st->seed2=seed2%rand_st->max_value; +} +static void old_randominit(struct rand_struct *rand_st,unsigned long seed1) { + rand_st->max_value= 0x01FFFFFFL; + rand_st->max_value_dbl=(double) rand_st->max_value; + seed1%=rand_st->max_value; + rand_st->seed1=seed1 ; rand_st->seed2=seed1/2; +} +double rnd(struct rand_struct *rand_st) { + rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % + rand_st->max_value; + rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % + rand_st->max_value; + return(((double) rand_st->seed1)/rand_st->max_value_dbl); +} +void hash_password(unsigned long *result, const char *password) { + register unsigned long nr=1345345333L, add=7, nr2=0x12345671L; + unsigned long tmp; + for (; *password ; password++) { + if (*password == ' ' || *password == '\t') + continue; + tmp= (unsigned long) (unsigned char) *password; + nr^= (((nr & 63)+add)*tmp)+ (nr << 8); + nr2+=(nr2 << 8) ^ nr; + add+=tmp; + } + result[0]=nr & (((unsigned long) 1L << 31) -1L); /* Don't use sign bit + (str2int) */; + result[1]=nr2 & (((unsigned long) 1L << 31) -1L); + return; +} +void make_scrambled_password(char *to,const char *password) { + unsigned long hash_res[2]; + hash_password(hash_res,password); + sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]); +} +static inline unsigned int char_val(char X) { + return (unsigned int) (X >= '0' && X <= '9' ? X-'0' : X >= 'A' && X <= 'Z' ? + X-'A'+10 : X-'a'+10); +} +char *scramble(char *to,const char *message,const char *password, int + old_ver) { + struct rand_struct rand_st; + unsigned long hash_pass[2],hash_message[2]; + if(password && password[0]) { + char *to_start=to; + hash_password(hash_pass,password); + hash_password(hash_message,message); + if (old_ver) + old_randominit(&rand_st,hash_pass[0] ^ + hash_message[0]); + else + randominit(&rand_st,hash_pass[0] ^ hash_message[0], + hash_pass[1] ^ hash_message[1]); + while (*message++) + *to++= (char) (floor(rnd(&rand_st)*31)+64); + if (!old_ver) { + char extra=(char) (floor(rnd(&rand_st)*31)); + while(to_start != to) + *(to_start++)^=extra; + } + } + *to=0; + return to; +} + +//end mysql code +//////////////////////////////////////////////////////////////// + +struct fmt_main fmt_MYSQL = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + mysql_tests + }, { + fmt_default_init, + mysql_valid, + fmt_default_split, + fmt_default_binary, + fmt_default_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + mysql_set_salt, + mysql_set_key, + mysql_get_key, + fmt_default_clear_keys, + mysql_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + mysql_cmp_all, + mysql_cmp_all, //should it be the same as cmp_all or same as cmp_exact? + mysql_cmp_exact //fallthrough + } +}; diff -urpN john-1.7.3.4.orig/src/Makefile john-1.7.3.4/src/Makefile --- john-1.7.3.4.orig/src/Makefile 2009-09-09 04:17:35 +0000 +++ john-1.7.3.4/src/Makefile 2010-02-14 03:22:26 +0000 @@ -15,9 +15,9 @@ SED = sed PERL = perl NULL = /dev/null CPPFLAGS = -E -CFLAGS = -c -Wall -O2 -fomit-frame-pointer +CFLAGS = -c -Wall -O2 -fomit-frame-pointer -I/usr/local/include -L/usr/local/lib ASFLAGS = -c -LDFLAGS = -s +LDFLAGS = -s -L/usr/local/lib -L/usr/local/ssl/lib -lcrypto -lm OPT_NORMAL = -funroll-loops OPT_INLINE = -finline-functions @@ -25,15 +25,53 @@ JOHN_OBJS_MINIMAL = \ DES_fmt.o DES_std.o DES_bs.o \ BSDI_fmt.o \ MD5_fmt.o MD5_std.o \ + MD5_apache_fmt.o \ + BFEgg_fmt.o \ BF_fmt.o BF_std.o \ AFS_fmt.o \ LM_fmt.o \ + NT_fmt.o \ + XSHA_fmt.o \ + DOMINOSEC_fmt.o \ + lotus5_fmt.o \ + oracle_fmt.o \ + oracle11_fmt.o \ + MYSQL_fmt.o \ + mysqlSHA1_fmt.o \ + KRB5_fmt.o KRB5_std.o \ + md5_go.o \ + rawMD5go_fmt.o md5_eq.o \ + PO_fmt.o \ + md5.o \ + hmacmd5.o \ + hmacMD5_fmt.o \ + IPB2_fmt.o \ + rawSHA1_fmt.o \ + NSLDAP_fmt.o NSLDAPS_fmt.o OPENLDAPS_fmt.o base64.o \ + md4.o smbencrypt.o \ + mscash_fmt.o \ + NETLM_fmt.o \ + NETNTLM_fmt.o \ + NETLMv2_fmt.o \ + NETNTLMv2_fmt.o \ + NETHALFLM_fmt.o \ + mssql_fmt.o \ + mssql05_fmt.o \ + EPI_fmt.o \ + PHPS_fmt.o \ + MYSQL_fast_fmt.o \ + pixMD5_fmt.o \ + sapG_fmt.o sapB_fmt.o \ + NS_fmt.o \ + HDAA_fmt.o \ batch.o bench.o charset.o common.o compiler.o config.o cracker.o \ crc32.o external.o formats.o getopt.o idle.o inc.o john.o list.o \ loader.o logger.o math.o memory.o misc.o options.o params.o path.o \ recovery.o rpp.o rules.o signals.o single.o status.o tty.o wordlist.o \ + mkv.o mkvlib.o \ unshadow.o \ unafs.o \ + undrop.o \ unique.o JOHN_OBJS_ORIG = \ @@ -66,11 +104,17 @@ BENCH_OBJS = \ bench.o best.o common.o config.o formats.o math.o memory.o miscnl.o \ params.o path.o signals.o tty.o -PROJ = ../run/john ../run/unshadow ../run/unafs ../run/unique +GENMKVPWD_OBJS = \ + genmkvpwd.o mkvlib.o memory.o miscnl.o + +PROJ = ../run/john ../run/unshadow ../run/unafs ../run/unique ../run/undrop \ + ../run/genmkvpwd ../run/mkvcalcproba ../run/calc_stat PROJ_DOS = ../run/john.bin ../run/john.com \ - ../run/unshadow.com ../run/unafs.com ../run/unique.com + ../run/unshadow.com ../run/unafs.com ../run/unique.com ../run/undrop.com PROJ_WIN32 = ../run/john.exe \ - ../run/unshadow.exe ../run/unafs.exe ../run/unique.exe + ../run/unshadow.exe ../run/unafs.exe ../run/unique.exe \ + ../run/undrop.exe \ + ../run/genmkvpwd.exe ../run/mkvcalcproba.exe ../run/calc_stat.exe default: @echo "To build John the Ripper, type:" @@ -154,7 +198,7 @@ linux-x86-64: linux-x86-64-32-sse2: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ CFLAGS="$(CFLAGS) -m32" \ ASFLAGS="$(ASFLAGS) -m32" \ LDFLAGS="$(LDFLAGS) -m32" @@ -162,7 +206,7 @@ linux-x86-64-32-sse2: linux-x86-64-32-mmx: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ CFLAGS="$(CFLAGS) -m32" \ ASFLAGS="$(ASFLAGS) -m32" \ LDFLAGS="$(LDFLAGS) -m32" @@ -170,12 +214,12 @@ linux-x86-64-32-mmx: linux-x86-sse2: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o" + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" linux-x86-mmx: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" linux-x86-any: $(LN) x86-any.h arch.h @@ -249,13 +293,13 @@ freebsd-x86-64: freebsd-x86-sse2: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ ASFLAGS="$(ASFLAGS) -DBSD" freebsd-x86-mmx: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ ASFLAGS="$(ASFLAGS) -DBSD" freebsd-x86-any: @@ -283,13 +327,13 @@ openbsd-x86-64: openbsd-x86-sse2: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ ASFLAGS="$(ASFLAGS) -DBSD" openbsd-x86-mmx: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ ASFLAGS="$(ASFLAGS) -DBSD" openbsd-x86-any: @@ -458,7 +502,7 @@ solaris-x86-64-gcc: solaris-x86-sse2-cc: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) solaris-x86.o x86-sse.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) solaris-x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ CC=cc \ CFLAGS="-c -fast -xarch=native" \ ASFLAGS="-c -xarch=native" \ @@ -469,13 +513,13 @@ solaris-x86-sse2-cc: solaris-x86-sse2-gcc: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ LDFLAGS="$(LDFLAGS) -lrt" solaris-x86-mmx-cc: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) solaris-x86.o x86-mmx.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) solaris-x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ CC=cc \ CFLAGS="-c -fast -xarch=native" \ ASFLAGS="-c -xarch=native" \ @@ -486,7 +530,7 @@ solaris-x86-mmx-cc: solaris-x86-mmx-gcc: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ LDFLAGS="$(LDFLAGS) -lrt" solaris-x86-any-cc: @@ -579,13 +623,13 @@ macosx-x86-64: macosx-x86-sse2: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o x86-sse.o" \ + JOHN_OBJS="$(JOHN_OBJS) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DBSD -DALIGN_LOG" macosx-x86-mmx: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o x86-mmx.o" \ + JOHN_OBJS="$(JOHN_OBJS) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DBSD -DALIGN_LOG" macosx-ppc32-altivec: @@ -652,7 +696,7 @@ john-macosx-x86: $(RM) *.o $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o x86-sse.o" \ + JOHN_OBJS="$(JOHN_OBJS) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ ASFLAGS="$(ASFLAGS) -arch i386 -DUNDERSCORES -DBSD -DALIGN_LOG" \ CFLAGS="$(CFLAGS) -arch i386" \ LDFLAGS="$(LDFLAGS) -arch i386" @@ -718,7 +762,7 @@ irix-mips32: dos-djgpp-x86-mmx: copy x86-mmx.h arch.h $(MAKE) $(PROJ_DOS) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ CFLAGS="$(CFLAGS) -mpreferred-stack-boundary=2" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DALIGN_LOG" @@ -732,14 +776,14 @@ dos-djgpp-x86-any: win32-cygwin-x86-sse2: $(CP) x86-sse.h arch.h $(MAKE) $(PROJ_WIN32) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ CFLAGS="$(CFLAGS) -mpreferred-stack-boundary=2" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES" win32-cygwin-x86-mmx: $(CP) x86-mmx.h arch.h $(MAKE) $(PROJ_WIN32) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ CFLAGS="$(CFLAGS) -mpreferred-stack-boundary=2" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES" @@ -753,12 +797,12 @@ win32-cygwin-x86-any: beos-x86-sse2: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o" + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" beos-x86-mmx: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" beos-x86-any: $(LN) x86-any.h arch.h @@ -794,6 +838,10 @@ bench: $(BENCH_OBJS) $(RM) ../run/unafs ln -s john ../run/unafs +../run/undrop: ../run/john + $(RM) ../run/undrop + ln -s john ../run/undrop + ../run/unique: ../run/john $(RM) ../run/unique ln -s john ../run/unique @@ -812,6 +860,9 @@ bench: $(BENCH_OBJS) ../run/unafs.com: john.com copy john.com ..\run\unafs.com +../run/undrop.com: john.com + copy john.com ..\run\undrop.com + ../run/unique.com: john.com copy john.com ..\run\unique.com @@ -819,7 +870,7 @@ john.com: john.asm @echo Use Borland TASM/TLINK to make JOHN.COM ../run/john.exe: $(JOHN_OBJS) - $(LD) $(JOHN_OBJS) -lkernel32 -o ../run/john.exe + $(LD) $(JOHN_OBJS) -lkernel32 -lcrypto -o ../run/john.exe strip ../run/john.exe ../run/unshadow.exe: symlink.c @@ -830,10 +881,32 @@ john.com: john.asm $(CC) symlink.c -o ../run/unafs.exe strip ../run/unafs.exe +../run/undrop.exe: symlink.c + $(CC) symlink.c -o ../run/undrop.exe + strip ../run/undrop.exe + ../run/unique.exe: symlink.c $(CC) symlink.c -o ../run/unique.exe strip ../run/unique.exe +../run/genmkvpwd: $(GENMKVPWD_OBJS) + $(LD) $(GENMKVPWD_OBJS) $(LDFLAGS) -o ../run/genmkvpwd + +../run/genmkvpwd.exe: $(GENMKVPWD_OBJS) + $(LD) $(GENMKVPWD_OBJS) $(LDFLAGS) -o ../run/genmkvpwd.exe + +../run/mkvcalcproba: mkvcalcproba.o + $(LD) mkvcalcproba.o $(LDFLAGS) -o ../run/mkvcalcproba + +../run/mkvcalcproba.exe: mkvcalcproba.o + $(LD) mkvcalcproba.o $(LDFLAGS) -o ../run/mkvcalcproba.exe + +../run/calc_stat: calc_stat.o + $(LD) calc_stat.o $(LDFLAGS) -o ../run/calc_stat + +../run/calc_stat.exe: calc_stat.o + $(LD) calc_stat.o $(LDFLAGS) -o ../run/calc_stat.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). DES_bs_b.o: DES_bs_b.c DES_bs_s.c DES_bs_n.c diff -urpN john-1.7.3.4.orig/src/NETHALFLM_fmt.c john-1.7.3.4/src/NETHALFLM_fmt.c --- john-1.7.3.4.orig/src/NETHALFLM_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/NETHALFLM_fmt.c 2009-08-31 13:38:11 +0000 @@ -0,0 +1,219 @@ +/* + * NETHALFLM_fmt.c + * Written by DSK (Based on NetLM/NetNTLM patch by JoMo-Kun) + * Performs brute-force cracking of the HalfLM challenge/response pairs. + + * Storage Format: + * domain\username:::lm response:nt response:challenge + * + * Code is in public domain. + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "nethalflm" +#define FORMAT_NAME "HalfLM C/R DES" +#define ALGORITHM_NAME "nethalflm" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 7 +#define BINARY_SIZE 8 +#define SALT_SIZE 8 +#define CIPHERTEXT_LENGTH 48 +#define TOTAL_LENGTH 12 + 2 * SALT_SIZE + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETHALFLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD", "G3RG3P00!"}, + {"$NETHALFLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD", "G3RG3P0"}, + {"$NETHALFLM$1122334455667788$1354FD5ABF3B627B8B49587B8F2BBA0F9F6C5E420824E0A2", "ZEEEZ@1"}, + {NULL} +}; + +static char saved_plain[PLAINTEXT_LENGTH + 1]; +static uchar challenge[SALT_SIZE + 1]; +static uchar output[BINARY_SIZE + 1]; + +static int nethalflm_valid(char *ciphertext) +{ + char *pos; + + if (strncmp(ciphertext, "$NETHALFLM$", 11)!=0) return 0; + if (ciphertext[27] != '$') return 0; + + for (pos = &ciphertext[28]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); + if (!*pos && pos - ciphertext - 28 == CIPHERTEXT_LENGTH) { + return 1; + } + else + return 0; +} + +static char *nethalflm_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1] = {0}; + + memcpy(&out, ciphertext, TOTAL_LENGTH); + strlwr(&out[10]); /* Exclude: $NETHALFLM$ */ + return out; +} + +static void *nethalflm_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + int i; + + ciphertext+=28; + for (i=0; i> 1); + key[2] = (key_56[1] << 6) | (key_56[2] >> 2); + key[3] = (key_56[2] << 5) | (key_56[3] >> 3); + key[4] = (key_56[3] << 4) | (key_56[4] >> 4); + key[5] = (key_56[4] << 3) | (key_56[5] >> 5); + key[6] = (key_56[5] << 2) | (key_56[6] >> 6); + key[7] = (key_56[6] << 1); + + DES_set_key(&key, ks); +} + +static void nethalflm_crypt_all(int count) +{ + static unsigned char magic[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + DES_key_schedule ks; + unsigned char password[7 + 1]; + unsigned char lm[8]; + + /* clear buffers */ + memset(lm, 0, 8); + memset(output, 0, 8); + + strncpy((char *) password, saved_plain, 7); + /* Generate first 8-bytes of LM hash */ + setup_des_key(password, &ks); + DES_ecb_encrypt((DES_cblock*)magic, (DES_cblock*)lm, &ks, DES_ENCRYPT); + + /* DES-encrypt challenge using LM hash */ + setup_des_key(lm, &ks); + DES_ecb_encrypt((DES_cblock*)challenge, (DES_cblock*)output, &ks, DES_ENCRYPT); + /*printf("\nLM Response: "); + int i; + for( i = 0; i< BINARY_SIZE ;i++) + printf("%.2x",output[i]); */ +} + +static int nethalflm_cmp_all(void *binary, int count) +{ + return !memcmp(output, binary, 8); +} + +static int nethalflm_cmp_one(void *binary, int index) +{ + return !memcmp(output, binary, 8); +} + +static int nethalflm_cmp_exact(char *source, int index) +{ + return !memcmp(output, nethalflm_get_binary(source), 8); +} + +static void *nethalflm_get_salt(char *ciphertext) +{ + static unsigned char binary_salt[SALT_SIZE]; + int i; + + ciphertext += 11; + for (i = 0; i < SALT_SIZE; ++i) { + binary_salt[i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + /*printf("%.2x",binary_salt[i]);*/ + } + return (void*)binary_salt; +} + +static void nethalflm_set_salt(void *salt) +{ + memcpy(challenge, salt, SALT_SIZE); +} + +static void nethalflm_set_key(char *key, int index) +{ + int i; + + strncpy(saved_plain, key, PLAINTEXT_LENGTH); + + /* Upper-case password */ + for(i=0; i= 'a') && (saved_plain[i] <= 'z')) saved_plain[i] ^= 0x20; +} + +static char *nethalflm_get_key(int index) +{ + return saved_plain; +} + +struct fmt_main fmt_NETHALFLM = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + fmt_default_init, + nethalflm_valid, + nethalflm_split, + nethalflm_get_binary, + nethalflm_get_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + nethalflm_set_salt, + nethalflm_set_key, + nethalflm_get_key, + fmt_default_clear_keys, + nethalflm_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + nethalflm_cmp_all, + nethalflm_cmp_one, + nethalflm_cmp_exact + } +}; + diff -urpN john-1.7.3.4.orig/src/NETLM_fmt.c john-1.7.3.4/src/NETLM_fmt.c --- john-1.7.3.4.orig/src/NETLM_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/NETLM_fmt.c 2008-08-24 08:52:27 +0000 @@ -0,0 +1,249 @@ +/* + * NETLM_fmt.c -- LM Challenge/Response + * + * Written by JoMo-Kun in 2007 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the LM + * challenge/response pairs exchanged during network-based authentication + * attempts [1]. The captured challenge/response pairs from these attempts + * should be stored using the L0phtCrack 2.0 LC format, specifically: + * username:unused:unused:lm response:ntlm response:challenge. For example: + * + * CORP\Administrator:::25B2B477CE101D83648BB087CE7A1C217F51C7FC64C0EBB1:: + * C8BD0C1630A9ECF7A95F494A8F0B2CB4A3F25B1225514304:1122334455667788 + * + * It should be noted that a LM authentication response is not same as a LM + * password hash, which can be extracted using tools such as FgDump [2]. LM + * responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theLmResponse + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netlm" +#define FORMAT_NAME "LM C/R DES" +#define ALGORITHM_NAME "netlm" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 14 +#define BINARY_SIZE 24 +#define SALT_SIZE 8 +#define CIPHERTEXT_LENGTH 48 +#define TOTAL_LENGTH 8 + 2 * SALT_SIZE + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD", "G3RG3P00!"}, + {"$NETLM$1122334455667788$16A7FDFE0CA109B937BFFB041F0E5B2D8B94A97D3FCA1A18", "HIYAGERGE"}, + {"$NETLM$1122334455667788$B3A1B87DBBD4DF3CFA296198DD390C2F4E2E93C5C07B1D8B", "MEDUSAFGDUMP12"}, + {"$NETLM$1122334455667788$0836F085B124F33895875FB1951905DD2F85252CC731BB25", "CORY21"}, + {NULL} +}; + +static char saved_plain[PLAINTEXT_LENGTH + 1]; +static uchar challenge[SALT_SIZE + 1]; +static uchar output[BINARY_SIZE + 1]; + +static int netlm_valid(char *ciphertext) +{ + char *pos; + + if (strncmp(ciphertext, "$NETLM$", 5)!=0) return 0; + if (ciphertext[23] != '$') return 0; + + for (pos = &ciphertext[24]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); + if (!*pos && pos - ciphertext - 24 == CIPHERTEXT_LENGTH) + return 1; + else + return 0; +} + +static char *netlm_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, TOTAL_LENGTH); + strlwr(&out[6]); /* Exclude: $NETLM$ */ + + return out; +} + +static void *netlm_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + int i; + + ciphertext+=24; + for (i=0; i> 1); + key[2] = (key_56[1] << 6) | (key_56[2] >> 2); + key[3] = (key_56[2] << 5) | (key_56[3] >> 3); + key[4] = (key_56[3] << 4) | (key_56[4] >> 4); + key[5] = (key_56[4] << 3) | (key_56[5] >> 5); + key[6] = (key_56[5] << 2) | (key_56[6] >> 6); + key[7] = (key_56[6] << 1); + + DES_set_key(&key, ks); +} + +static void netlm_crypt_all(int count) +{ + static unsigned char magic[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + DES_key_schedule ks; + unsigned char password[14 + 1]; + unsigned char lm[21]; + + memset(password, 0, 14 + 1); + memset(lm, 0, 21); + memset(output, 0, 24); + + strncpy((char *) password, saved_plain, 14); + + /* Generate 16-byte LM hash */ + setup_des_key(password, &ks); + DES_ecb_encrypt((DES_cblock*)magic, (DES_cblock*)lm, &ks, DES_ENCRYPT); + setup_des_key(&password[7], &ks); + DES_ecb_encrypt((DES_cblock*)magic, (DES_cblock*)&lm[8], &ks, DES_ENCRYPT); + + /* + NULL-pad 16-byte LM hash to 21-bytes + Split resultant value into three 7-byte thirds + DES-encrypt challenge using each third as a key + Concatenate three 8-byte resulting values to form 24-byte LM response + */ + setup_des_key(lm, &ks); + DES_ecb_encrypt((DES_cblock*)challenge, (DES_cblock*)output, &ks, DES_ENCRYPT); + setup_des_key(&lm[7], &ks); + DES_ecb_encrypt((DES_cblock*)challenge, (DES_cblock*)&output[8], &ks, DES_ENCRYPT); + setup_des_key(&lm[14], &ks); + DES_ecb_encrypt((DES_cblock*)challenge, (DES_cblock*)&output[16], &ks, DES_ENCRYPT); +} + +static int netlm_cmp_all(void *binary, int count) +{ + return !memcmp(output, binary, BINARY_SIZE); +} + +static int netlm_cmp_one(void *binary, int index) +{ + return !memcmp(output, binary, BINARY_SIZE); +} + +static int netlm_cmp_exact(char *source, int index) +{ + return !memcmp(output, netlm_get_binary(source), BINARY_SIZE); +} + +static void *netlm_get_salt(char *ciphertext) +{ + static unsigned char binary_salt[SALT_SIZE]; + int i; + + ciphertext += 7; + for (i = 0; i < SALT_SIZE; ++i) + binary_salt[i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + return (void*)binary_salt; +} + +static void netlm_set_salt(void *salt) +{ + memcpy(challenge, salt, SALT_SIZE); +} + +static void netlm_set_key(char *key, int index) +{ + int i; + + memset(saved_plain, 0, PLAINTEXT_LENGTH + 1); + strncpy(saved_plain, key, PLAINTEXT_LENGTH); + + /* Upper-case password */ + for(i=0; i= 'a') && (saved_plain[i] <= 'z')) saved_plain[i] ^= 0x20; +} + +static char *netlm_get_key(int index) +{ + return saved_plain; +} + +struct fmt_main fmt_NETLM = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_8_BIT | FMT_BS | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + fmt_default_init, + netlm_valid, + netlm_split, + netlm_get_binary, + netlm_get_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + netlm_set_salt, + netlm_set_key, + netlm_get_key, + fmt_default_clear_keys, + netlm_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + netlm_cmp_all, + netlm_cmp_one, + netlm_cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/NETLMv2_fmt.c john-1.7.3.4/src/NETLMv2_fmt.c --- john-1.7.3.4.orig/src/NETLMv2_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/NETLMv2_fmt.c 2008-08-24 08:38:58 +0000 @@ -0,0 +1,361 @@ +/* + * NETLMv2_fmt.c -- LMv2 Challenge/Response + * + * Written by JoMo-Kun in 2008 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the LMv2 + * challenge/response sets exchanged during network-based authentication + * attempts [1]. The captured challenge/response set from these attempts + * should be stored using the following format: + * + * USERNAME::DOMAIN:SERVER CHALLENGE:LMv2 RESPONSE:CLIENT CHALLENGE + * + * For example: + * Administrator::WORKGROUP:1122334455667788:6759A5A7EFB25452911DE7DE8296A0D8:F503236B200A5B3A + * + * It should be noted that a LMv2 authentication response is not same as a LM + * password hash, which can be extracted using tools such as FgDump [2]. In + * fact, a NTLM hash and not a LM hash is used within the LMv2 algorithm. LMv2 + * challenge/response authentication typically takes place when the GPO + * "Network Security: LAN Manager authentication level" is configured to a setting + * that enforces the use of NTLMv2, such as "Send NTLMv2 response only\refuse + * LM & NTLM." + * + * LMv2 responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theLmv2Response + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include "md5.h" +#include "hmacmd5.h" + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netlmv2" +#define FORMAT_NAME "LMv2 C/R MD4 HMAC-MD5" +#define ALGORITHM_NAME "netlmv2" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 54 /* lmcons.h - PWLEN (256) ? 127 ? */ +#define USERNAME_LENGTH 20 /* lmcons.h - UNLEN (256) / LM20_UNLEN (20) */ +#define DOMAIN_LENGTH 15 /* lmcons.h - CNLEN / DNLEN */ +#define BINARY_SIZE 16 +#define CHALLENGE_LENGTH 32 +#define SALT_SIZE 16 + USERNAME_LENGTH + DOMAIN_LENGTH +#define CIPHERTEXT_LENGTH 32 +#define TOTAL_LENGTH 12 + USERNAME_LENGTH + DOMAIN_LENGTH + CHALLENGE_LENGTH + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETLMv2$ADMINISTRATORFOODOM$1122334455667788$6F64C5C1E35F68DD80388C0F00F34406$F0F3FF27037AA69F", "1337adminPASS"}, + {"$NETLMv2$USER1$1122334455667788$B1D163EA5881504F3963DC50FCDC26C1$EB4D9E8138149E20", "foobar"}, + {"$NETLMv2$ATEST$1122334455667788$83B59F1536D3321DBF1FAEC14ADB1675$A1E7281FE8C10E53", "SomeFancyP4$$w0rdHere"}, + {NULL} +}; + +uchar saved_plain[PLAINTEXT_LENGTH + 1]; +uchar challenge[SALT_SIZE + 1]; +uchar output[BINARY_SIZE + 1]; + +extern void E_md4hash(uchar *passwd, uchar *p16); +extern void hmac_md5_init_limK_to_64(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_update(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_final(unsigned char*, HMACMD5Context*); + +#if !defined(uint16) && !defined(HAVE_UINT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define uint16 unsigned short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#if !defined(int16) && !defined(HAVE_INT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define int16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define int16 short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#include "byteorder.h" + +/* Routines for Windows NT MD4 Hash functions. */ +static int lmv2_wcslen(int16 *str) +{ + int len = 0; + while(*str++ != 0) + len++; + return len; +} + +/* + * Convert a string into an NT UNICODE string. + * Note that regardless of processor type + * this must be in intel (little-endian) + * format. + */ +int lmv2_mbstowcs(int16 *dst, uchar *src, int len) +{ + int i; + int16 val; + + for(i = 0; i < len; i++) { + val = *src; + SSVAL(dst,0,val); + dst++; + src++; + if(val == 0) + break; + } + return i; +} + +static int netlmv2_valid(char *ciphertext) +{ + char *pos, *pos2; + + if (ciphertext == NULL) return 0; + else if (strncmp(ciphertext, "$NETLMv2$", 9)!=0) return 0; + + pos = &ciphertext[9]; + + /* Validate Username and Domain Length */ + for (pos2 = pos; strncmp(pos2, "$", 1) != 0; pos2++) + if ( (*pos2 < 0x20) || (*pos2 > 0x7E) ) + return 0; + + if ( !(*pos2 && (pos2 - pos <= USERNAME_LENGTH + DOMAIN_LENGTH)) ) + return 0; + + /* Validate Server Challenge Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == CHALLENGE_LENGTH / 2)) ) + return 0; + + /* Validate LMv2 Response Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == CIPHERTEXT_LENGTH)) ) + return 0; + + /* Validate Client Challenge Length */ + pos2++; pos = pos2; + for (; atoi16[ARCH_INDEX(*pos2)] != 0x7F; pos2++); + if (pos2 - pos != CHALLENGE_LENGTH / 2) + return 0; + + return 1; +} + +static char *netlmv2_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + char *pos = NULL; + int identity_length = 0; + + /* Calculate identity length */ + for (pos = ciphertext + 9; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 9); + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, strlen(ciphertext)); + strlwr(&out[10 + identity_length]); /* Exclude: $NETLMv2$USERDOMAIN$ */ + + return out; +} + +static void *netlmv2_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + char *pos = NULL; + int i, identity_length; + + for (pos = ciphertext + 9; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 9); + + ciphertext += 9 + identity_length + 1 + CHALLENGE_LENGTH / 2 + 1; + for (i=0; i in 2007 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the NTLM + * (version 1) challenge/response pairs exchanged during network-based + * authentication attempts [1]. The captured challenge/response pairs from these + * attempts should be stored using the L0phtCrack 2.0 LC format, specifically: + * username:unused:unused:lm response:ntlm response:challenge. For example: + * + * CORP\Administrator:::25B2B477CE101D83648BB087CE7A1C217F51C7FC64C0EBB1:: + * C8BD0C1630A9ECF7A95F494A8F0B2CB4A3F25B1225514304:1122334455667788 + * + * It should be noted that a NTLM authentication response is not same as a NTLM + * password hash, which can be extracted using tools such as FgDump [2]. NTLM + * responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theNtLmResponse + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netntlm" +#define FORMAT_NAME "NTLMv1 C/R MD4 DES" +#define ALGORITHM_NAME "netntlm" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 54 /* ?127? */ +#define BINARY_SIZE 24 +#define SALT_SIZE 8 +#define CIPHERTEXT_LENGTH 48 +#define TOTAL_LENGTH 10 + 2 * SALT_SIZE + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETNTLM$1122334455667788$BFCCAF26128EC95F9999C9792F49434267A1D9B0EF89BFFB", "g3rg3g3rg3g3rg3"}, + {"$NETNTLM$1122334455667788$E463FAA5D868ECE20CAE622474A2F440A652D642156AF863", "M1xedC4se%^&*@)##(blahblah!@#"}, + {"$NETNTLM$1122334455667788$35B62750E1B9B3205C50D6BA351092C12A1B9B3CDC65D44A", "FooBarGerg"}, + {"$NETNTLM$1122334455667788$A4765EBFE83D345A7CB1660B8899251905164029F8086DDE", "visit www.foofus.net"}, + {"$NETNTLM$1122334455667788$B2B2220790F40C88BCFF347C652F67A7C4A70D3BEBD70233", "cory21"}, + {NULL} +}; + +static char saved_plain[PLAINTEXT_LENGTH + 1]; +static uchar challenge[SALT_SIZE + 1]; +static uchar output[BINARY_SIZE + 1]; + +extern void E_md4hash(uchar *passwd, uchar *p16); +extern void setup_des_key(unsigned char key_56[], DES_key_schedule *ks); + +static int netntlm_valid(char *ciphertext) +{ + char *pos; + + if (strncmp(ciphertext, "$NETNTLM$", 9)!=0) return 0; + if (ciphertext[25] != '$') return 0; + + for (pos = &ciphertext[26]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); + if (!*pos && pos - ciphertext - 26 == CIPHERTEXT_LENGTH) + return 1; + else + return 0; +} + +static char *netntlm_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, TOTAL_LENGTH); + strlwr(&out[8]); /* Exclude: $NETNTLM$ */ + + return out; +} + +static void *netntlm_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + int i; + + ciphertext+=26; + for (i=0; i in 2009 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the NTLMv2 + * challenge/response sets exchanged during network-based authentication + * attempts [1]. The captured challenge/response set from these attempts + * should be stored using the following format: + * + * USERNAME::DOMAIN:SERVER CHALLENGE:NTLMv2 RESPONSE:CLIENT CHALLENGE + * + * For example: + * ntlmv2test::WORKGROUP:1122334455667788:07659A550D5E9D02996DFD95C87EC1D5:0101000000000000006CF6385B74CA01B3610B02D99732DD000000000200120057004F0052004B00470052004F00550050000100200044004100540041002E00420049004E0043002D0053004500430055005200490000000000 + * + * It should be noted that a NTLMv2 authentication response is not same as a NTLM + * password hash, which can be extracted using tools such as FgDump [2]. NTLMv2 + * challenge/response authentication typically takes place when the GPO + * "Network Security: LAN Manager authentication level" is configured to a setting + * that enforces the use of NTLMv2, such as "Send NTLMv2 response only\refuse + * LM & NTLM." + * + * NTLMv2 responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theNtlmv2Response + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include "md5.h" +#include "hmacmd5.h" + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netntlmv2" +#define FORMAT_NAME "NTLMv2 C/R MD4 HMAC-MD5" +#define ALGORITHM_NAME "netntlmv2" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 54 /* lmcons.h - PWLEN (256) ? 127 ? */ +#define USERNAME_LENGTH 20 /* lmcons.h - UNLEN (256) / LM20_UNLEN (20) */ +#define DOMAIN_LENGTH 15 /* lmcons.h - CNLEN / DNLEN */ +#define BINARY_SIZE 16 +#define SERVER_CHALL_LENGTH 16 +#define CLIENT_CHALL_LENGTH_MAX 512 /* FIX - Max Target Information Size Unknown */ +#define SALT_SIZE_MAX USERNAME_LENGTH + DOMAIN_LENGTH + 3 + SERVER_CHALL_LENGTH/2 + CLIENT_CHALL_LENGTH_MAX/2 +#define CIPHERTEXT_LENGTH 32 +#define TOTAL_LENGTH 12 + USERNAME_LENGTH + DOMAIN_LENGTH + SERVER_CHALL_LENGTH + CLIENT_CHALL_LENGTH_MAX + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETNTLMv2$NTLMV2TESTWORKGROUP$1122334455667788$07659A550D5E9D02996DFD95C87EC1D5$0101000000000000006CF6385B74CA01B3610B02D99732DD000000000200120057004F0052004B00470052004F00550050000100200044004100540041002E00420049004E0043002D0053004500430055005200490000000000", "password"}, + {"$NETNTLMv2$TESTUSERW2K3ADWIN7$1122334455667788$989B96DC6EAB529F72FCBA852C0D5719$01010000000000002EC51CEC91AACA0124576A744F198BDD000000000200120057004F0052004B00470052004F00550050000000000000000000", "testpass"}, + {"$NETNTLMv2$USERW2K3ADWIN7$1122334455667788$5BD1F32D8AFB4FB0DD0B77D7DE2FF7A9$0101000000000000309F56FE91AACA011B66A7051FA48148000000000200120057004F0052004B00470052004F00550050000000000000000000", "password"}, + {"$NETNTLMv2$USER1W2K3ADWIN7$1122334455667788$027EF88334DAA460144BDB678D4F988D$010100000000000092809B1192AACA01E01B519CB0248776000000000200120057004F0052004B00470052004F00550050000000000000000000", "SomeLongPassword1BlahBlah"}, + {"$NETNTLMv2$TEST_USERW2K3ADWIN7$1122334455667788$A06EC5ED9F6DAFDCA90E316AF415BA71$010100000000000036D3A13292AACA01D2CD95757A0836F9000000000200120057004F0052004B00470052004F00550050000000000000000000", "TestUser's Password"}, + {"$NETNTLMv2$USER1Domain$1122334455667788$5E4AB1BF243DCA304A00ADEF78DC38DF$0101000000000000BB50305495AACA01338BC7B090A62856000000000200120057004F0052004B00470052004F00550050000000000000000000", "password"}, + {NULL} +}; + +uchar saved_plain[PLAINTEXT_LENGTH + 1]; +uchar challenge[SALT_SIZE_MAX + 1]; +uchar output[BINARY_SIZE + 1]; + +extern void E_md4hash(uchar *passwd, uchar *p16); +extern void hmac_md5_init_limK_to_64(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_update(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_final(unsigned char*, HMACMD5Context*); + +#if !defined(uint16) && !defined(HAVE_UINT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define uint16 unsigned short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#if !defined(int16) && !defined(HAVE_INT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define int16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define int16 short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#include "byteorder.h" + +/* Routines for Windows NT MD4 Hash functions. */ +static int ntlmv2_wcslen(int16 *str) +{ + int len = 0; + while(*str++ != 0) + len++; + return len; +} + +/* + * Convert a string into an NT UNICODE string. + * Note that regardless of processor type + * this must be in intel (little-endian) + * format. + */ +int ntlmv2_mbstowcs(int16 *dst, uchar *src, int len) +{ + int i; + int16 val; + + for(i = 0; i < len; i++) { + val = *src; + SSVAL(dst,0,val); + dst++; + src++; + if(val == 0) + break; + } + return i; +} + +static int netntlmv2_valid(char *ciphertext) +{ + char *pos, *pos2; + + if (ciphertext == NULL) return 0; + else if (strncmp(ciphertext, "$NETNTLMv2$", 11)!=0) return 0; + + pos = &ciphertext[11]; + + /* Validate Username and Domain Length */ + for (pos2 = pos; strncmp(pos2, "$", 1) != 0; pos2++) + if ( (*pos2 < 0x20) || (*pos2 > 0x7E) ) + return 0; + + if ( !(*pos2 && (pos2 - pos <= USERNAME_LENGTH + DOMAIN_LENGTH)) ) + return 0; + + /* Validate Server Challenge Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == SERVER_CHALL_LENGTH)) ) + return 0; + + /* Validate NTLMv2 Response Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == CIPHERTEXT_LENGTH)) ) + return 0; + + /* Validate Client Challenge Length */ + pos2++; pos = pos2; + for (; atoi16[ARCH_INDEX(*pos2)] != 0x7F; pos2++); + if (pos2 - pos > CLIENT_CHALL_LENGTH_MAX) + return 0; + + return 1; +} + +static char *netntlmv2_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + char *pos = NULL; + int identity_length = 0; + + /* Calculate identity length */ + for (pos = ciphertext + 11; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 11); + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, strlen(ciphertext)); + strlwr(&out[12 + identity_length]); /* Exclude: $NETNTLMv2$USERDOMAIN$ */ + + return out; +} + +static void *netntlmv2_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + char *pos = NULL; + int i, identity_length; + + for (pos = ciphertext + 11; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 11); + + ciphertext += 11 + identity_length + 1 + SERVER_CHALL_LENGTH + 1; + for (i=0; i Identity \0 Size \0 Server Challenge + Client Challenge (Blob) + */ + hmac_md5_init_limK_to_64(ntlm_v2_hash, 16, &ctx); + hmac_md5_update(challenge + identity_length + 1 + 2, (int)(*(challenge + identity_length + 1)), &ctx); + hmac_md5_final(output, &ctx); +} + +static int netntlmv2_cmp_all(void *binary, int count) +{ + return !memcmp(output, binary, BINARY_SIZE); +} + +static int netntlmv2_cmp_one(void *binary, int index) +{ + return !memcmp(output, binary, BINARY_SIZE); +} + +static int netntlmv2_cmp_exact(char *source, int index) +{ + return !memcmp(output, netntlmv2_get_binary(source), BINARY_SIZE); +} + +/* + We're essentially using three salts, but we're going to pack it into a single blob for now. + + Input: $NETNTLMv2$USER_DOMAIN$_SERVER_CHALLENGE_$_NTLMv2_RESP_$_CLIENT_CHALLENGE_ + Username: <=20 + Domain: <=15 + Server Challenge: 8 bytes + Client Challenge: ??? + Output: Identity \0 Challenge Size \0 Server Challenge + Client Challenge +*/ +static void *netntlmv2_get_salt(char *ciphertext) +{ + static unsigned char binary_salt[SALT_SIZE_MAX]; + int i, identity_length, challenge_size; + char *pos = NULL; + + memset(binary_salt, 0, SALT_SIZE_MAX); + + /* Calculate identity length; Set identity */ + for (pos = ciphertext + 11; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 11); + strncpy((char *)binary_salt, ciphertext + 11, identity_length); + + /* Set server and client challenge size */ + + /* Skip: $NETNTLMv2$USER_DOMAIN$ */ + ciphertext += 11 + identity_length + 1; + + /* SERVER_CHALLENGE$NTLMV2_RESPONSE$CLIENT_CHALLENGE --> SERVER_CHALLENGECLIENT_CHALLENGE */ + /* CIPHERTEXT == NTLMV2_RESPONSE (16 bytes / 32 characters) */ + challenge_size = (strlen(ciphertext) - CIPHERTEXT_LENGTH - 2) / 2; + + /* Set challenge size in response - use NULL separators */ + memset(binary_salt + identity_length + 1, challenge_size, 1); + + /* Set server challenge - add NULL separator after challenge size */ + for (i = 0; i < SERVER_CHALL_LENGTH / 2; i++) + binary_salt[identity_length + 1 + 1 + 1 + i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + /* Set client challenge */ + ciphertext += SERVER_CHALL_LENGTH + 1 + CIPHERTEXT_LENGTH + 1; + for (i = 0; i < strlen(ciphertext) / 2; ++i) + binary_salt[identity_length + 1 + 1 + 1 + SERVER_CHALL_LENGTH / 2 + i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + /* Return a concatenation of the server and client challenges and the identity value */ + return (void*)binary_salt; +} + +static void netntlmv2_set_salt(void *salt) +{ + memcpy(challenge, salt, SALT_SIZE_MAX); +} + +static void netntlmv2_set_key(char *key, int index) +{ + strncpy((char *)saved_plain, key, PLAINTEXT_LENGTH); + saved_plain[PLAINTEXT_LENGTH] = 0; +} + +static char *netntlmv2_get_key(int index) +{ + return (char *)saved_plain; +} + +struct fmt_main fmt_NETNTLMv2 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE_MAX, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + fmt_default_init, + netntlmv2_valid, + netntlmv2_split, + netntlmv2_get_binary, + netntlmv2_get_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + netntlmv2_set_salt, + netntlmv2_set_key, + netntlmv2_get_key, + fmt_default_clear_keys, + netntlmv2_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + netntlmv2_cmp_all, + netntlmv2_cmp_one, + netntlmv2_cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/NSLDAPS_fmt.c john-1.7.3.4/src/NSLDAPS_fmt.c --- john-1.7.3.4.orig/src/NSLDAPS_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/NSLDAPS_fmt.c 2009-10-29 02:57:53 +0000 @@ -0,0 +1,287 @@ +// Fix for john the ripper 1.6.37 by Sun-Zero, 2004. 07. 26. +/* + * This file is part of John the Ripper password cracker, + * Copyright (c) 1996-98 by Solar Designer + * + * Minor performance enhancement by bartavelle at bandecon.com + */ + +#include + +#include "misc.h" +#include "params.h" +#include "formats.h" +#include "common.h" + +#include "sha.h" +#include "base64.h" + +#define FORMAT_LABEL "ssha" +#define FORMAT_NAME "Netscape LDAP SSHA" +#define SHA_TYPE "salted SHA-1" + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 40 + +#define BINARY_SIZE 20 +#define SALT_SIZE 8 + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) ) +#else +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +#define NSLDAP_MAGIC "{ssha}" +#define NSLDAP_MAGIC_LENGTH 6 + +static struct fmt_tests tests[] = { + {"{SSHA}WTT3B9Jjr8gOt0Q7WMs9/XvukyhTQj0Ns0jMKQ==", "Password9"}, + {"{SSHA}ypkVeJKLzbXakEpuPYbn+YBnQvFmNmB+kQhmWQ==", "qVv3uQ45"}, + {"{SSHA}cKFVqtf358j0FGpPsEIK1xh3T0mtDNV1kAaBNg==", "salles"}, + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define buffer NSLDAPS_buffer +#define crypt_key NSLDAPS_crypt_key +unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(16))); +char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static char saved_key[80*MMX_COEF]; +static unsigned long total_len; +static unsigned char out[PLAINTEXT_LENGTH + 1]; +#else +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static char saved_key[PLAINTEXT_LENGTH + 1]; +#endif + +#ifdef MMX_COEF +static unsigned long length[MAX_KEYS_PER_CRYPT]; +#endif +static char saved_salt[SALT_SIZE]; + +static void * binary(char *ciphertext) { + static char realcipher[BINARY_SIZE + SALT_SIZE + 9]; + + /* stupid overflows */ + memset(realcipher, 0, sizeof(realcipher)); + base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher); + return (void *)realcipher; +} + +static void * get_salt(char * ciphertext) +{ + static char realcipher[BINARY_SIZE + SALT_SIZE + 9]; + memset(realcipher, 0, sizeof(realcipher)); + base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher); + return (void*)realcipher+BINARY_SIZE; +} + +static int valid(char *ciphertext) +{ + if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH + NSLDAP_MAGIC_LENGTH) + return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH); + return 0; +} + +static int binary_hash_0(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFFF; +} + +static int get_hash_0(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF; +} + +static int get_hash_1(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF; +} + +static int get_hash_2(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF; +} + +static int salt_hash(void *salt) +{ + return *((ARCH_WORD_32 *)salt) & (SALT_HASH_SIZE - 1); +} + +static void set_key(char *key, int index) +{ +#ifdef MMX_COEF + int len; + int i; + + if(index==0) + { + total_len = 0; + memset(saved_key, 0, sizeof(saved_key)); + memset(length, 0, sizeof(length)); + } + len = strlen(key); + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + length[index] = len; + + total_len += (len + SALT_SIZE) << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#else + return !memcmp(binary, crypt_key, BINARY_SIZE); +#endif +} + +static int +cmp_exact(char *source, int index) +{ + return 1; +} + +static int cmp_one(void * binary, int index) +{ +#ifdef MMX_COEF + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] ) + return 0; + return 1; +#else + return cmp_all(binary, index); +#endif +} + + +static void crypt_all(int count) +{ +#ifdef MMX_COEF + int i,idx; + + for(idx=0;idx + +#include "misc.h" +#include "formats.h" +#include "common.h" + +#include "sha.h" +#include "base64.h" + +#define FORMAT_LABEL "nsldap" +#define FORMAT_NAME "Netscape LDAP SHA" +#define SHA_TYPE "SHA-1" + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 33 + +#define BINARY_SIZE 20 +#define SALT_SIZE 0 + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) ) +#else +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +#define NSLDAP_MAGIC "{sha}" +#define NSLDAP_MAGIC_LENGTH 5 + +static struct fmt_tests tests[] = { + {"{SHA}cMiB1KJphN3OeV9vcYF8nPRIDnk=", "aaaa"}, + {"{SHA}iu0TIuVFC62weOH7YKgXod8loso=", "bbbb"}, + {"{SHA}0ijZPTcJXMa+t2XnEbEwSOkvQu0=", "ccccccccc"}, + {"{SHA}vNR9eUfJfcKmdkLDqNoKagho+qU=", "dddddddddd"}, + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define buffer NSLDAP_buffer +#define crypt_key NSLDAP_crypt_key +unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(16))); +char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static char saved_key[(PLAINTEXT_LENGTH+1)*MMX_COEF]; +static unsigned long total_len; +static unsigned char out[PLAINTEXT_LENGTH + 1]; +#else +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static char saved_key[PLAINTEXT_LENGTH + 1]; +#endif + +static void * +binary(char *ciphertext) { + static char realcipher[BINARY_SIZE + 9]; + + /* stupid overflows */ + memset(realcipher, 0, sizeof(realcipher)); + base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher); + return (void *)realcipher; +} + +static int +valid(char *ciphertext) +{ + if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH) + return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH); + return 0; +} + +static int binary_hash_0(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFFF; +} + +static int get_hash_0(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF; +} + +static int get_hash_1(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF; +} + +static int get_hash_2(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF; +} + +static void set_key(char *key, int index) +{ +#ifdef MMX_COEF + int len; + int i; + + if(index==0) + { + total_len = 0; + memset(saved_key, 0, sizeof(saved_key)); + } + len = strlen(key); + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + total_len += len << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i> (((32/MMX_COEF)*(index)))) & 0xff; + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#else + return !memcmp(binary, crypt_key, BINARY_SIZE); +#endif +} + +static int +cmp_exact(char *source, int index) +{ + return 1; +} + +static int cmp_one(void * binary, int index) +{ +#ifdef MMX_COEF + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] ) + return 0; + return 1; +#else + return cmp_all(binary, index); +#endif +} + +static void set_salt(void *salt) { +} + +static void +crypt_all(int count) { +#ifdef MMX_COEF + memcpy(buffer, saved_key, 32*MMX_COEF); + shammx((unsigned char *) crypt_key, buffer, total_len); +#else + static SHA_CTX ctx; + SHA1_Init(&ctx); + SHA1_Update(&ctx, (unsigned char *) saved_key, strlen(saved_key)); + SHA1_Final((unsigned char *) crypt_key, &ctx); +#endif +} + +struct fmt_main fmt_NSLDAP = { + { + FORMAT_LABEL, + FORMAT_NAME, + SHA_TYPE, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + fmt_default_init, + valid, + fmt_default_split, + binary, + fmt_default_salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2 + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + get_hash_0, + get_hash_1, + get_hash_2 + }, + cmp_all, + cmp_one, + cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/NS_fmt.c john-1.7.3.4/src/NS_fmt.c --- john-1.7.3.4.orig/src/NS_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/NS_fmt.c 2008-08-25 01:53:09 +0000 @@ -0,0 +1,282 @@ +/* + * NS_fmt.c + * Written by Samuel Monux in 2008, and placed + * in the public domain. There's absolutely no warranty. + * + * Netscreen OS password module. Passwords must be in this format + * :$ + * + * which appear in Netscreen config file + * + * set admin name "" + * set admin password "" + * + * username is needed because is used as part of the salt. + * + * Cryptedpass is generated this way (pseudocode): + * + * b64 = array([A-Za-z0-9+/]) + * md5_binary = MD5(":Administration Tools:") + * + * md5_ascii = "" + * for every 16bits word "w" in md5_binary: + * append(md5_ascii, b64[ w >> 12 & 0xf ]) + * append(md5_ascii, b64[ w >> 6 & 0x3f ]) + * append(md5_ascii, b64[ w & 0x3f ]) + * + * ciphertext = md5_ascii + * for every c,p ("nrcstn", [0, 6, 12, 17, 23, 29]): + * interpolate character "c" in position "p" in ciphertext + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "md5.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "md5ns" +#define FORMAT_NAME "Netscreen MD5" +#define NS_ALGORITHM_NAME "NS MD5" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 15 +#define CIPHERTEXT_LENGTH 50 + +#define BINARY_SIZE 16 +#define SALT_SIZE 32 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + + +static struct fmt_tests tests[] = { + {"admin$nMjFM0rdC9iOc+xIFsGEm3LtAeGZhn", "password"}, + {"a$nMf9FkrCIgHGccRAxsBAwxBtDtPHfn", "netscreen"}, + {NULL} +}; + +static unsigned short e64toshort[256]; + +#define ADM_LEN 22 +static int salt_len, key_len; +static char cipher_salt[ SALT_SIZE ]; +static char cipher_key[ PLAINTEXT_LENGTH + 1 ]; +static char *adm = ":Administration Tools:"; +static char tocipher[ SALT_SIZE + ADM_LEN + PLAINTEXT_LENGTH ]; +static ARCH_WORD_32 crypted[4]; + + +static void NS_init() +{ + int i; + static char *b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + char *pos; + for (pos = b64, i = 0 ; *pos != 0 ; pos++, i++) + e64toshort[(int)*pos] = i; +} + +static int NS_valid(char *ciphertext) +{ + char *password; + static char *netscreen = "nrcstn" ; + static int p[] = { 0, 6, 12, 17, 23, 29 }; + int i; + + password = ciphertext; + + while ((*password != '$') && (*password != '\0' )) + password++; + if (*password == '\0') return 0; + password++; + + if (strlen(password) != 30) return 0; + for (i = 0; i < 6 ; i++) + if (netscreen[i] != password[p[i]]) return 0; + + for (i = 0; i < 30 ; i++) { + char c = password[i]; + if (((c >= 'A') && ( c <= 'Z')) || + ((c >= 'a') && ( c <= 'z')) || + ((c >= '0') && ( c <= '9')) || + (c == '+') || ( c == '/')) + continue; + return 0; + } + return 1; +} + +static ARCH_WORD_32 *NS_std_get_binary(char *ciphertext) +{ + static ARCH_WORD_32 out[4]; + char unscrambled[24]; + int i; + MD5_u32plus a, b, c; + MD5_u32plus d, e, f; + char *pos; +#if ARCH_LITTLE_ENDIAN + MD5_u32plus temp; +#endif + + pos = ciphertext; + while (*pos++ != '$'); + + memcpy(unscrambled, pos + 1, 6 ); + memcpy(unscrambled + 5, pos + 7, 6 ); + memcpy(unscrambled + 10, pos + 13, 5 ); + memcpy(unscrambled + 14, pos + 18, 6 ); + memcpy(unscrambled + 19, pos + 24, 5 ); + + for ( i = 0 ; i < 4 ; i++ ) { + a = e64toshort[ARCH_INDEX(unscrambled[6*i])]; + b = e64toshort[ARCH_INDEX(unscrambled[6*i + 1 ])]; + c = e64toshort[ARCH_INDEX(unscrambled[6*i + 2 ])]; + d = e64toshort[ARCH_INDEX(unscrambled[6*i + 3 ])]; + e = e64toshort[ARCH_INDEX(unscrambled[6*i + 4 ])]; + f = e64toshort[ARCH_INDEX(unscrambled[6*i + 5 ])]; +#if ARCH_LITTLE_ENDIAN + temp = (((a << 12) | (b << 6) | (c)) << 16) | + ((d << 12) | (e << 6) | (f)); + out[i] = ((temp << 24) & 0xff000000 ) | + ((temp << 8) & 0x00ff0000 ) | + ((temp >> 8) & 0x0000ff00 ) | + ((temp >> 24) & 0x000000ff ); +#else + out[i] = (((a << 12) | (b << 6) | (c)) << 16) | + ((d << 12) | (e << 6) | (f)); +#endif + } + + return out; +} + +static int binary_hash_0(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xf; +} + +static int binary_hash_1(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xff; +} + +static int binary_hash_2(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xfff; +} + +static int get_hash_0(int index) +{ + return crypted[0] & 0xf; +} + +static int get_hash_1(int index) +{ + return crypted[0] & 0xff; +} + +static int get_hash_2(int index) +{ + return crypted[0] & 0xfff; +} + +char *NS_std_get_salt(char *ciphertext) +{ + static char out[SALT_SIZE + 1]; + char *ipos, *opos; + + ipos = ciphertext; + opos = out; + while (*ipos != '$') *opos++ = *ipos++; + *opos = '\0'; + + return out; +} + +void NS_std_set_salt (void *salt) +{ + salt_len = strlen((char *) salt); + memcpy(cipher_salt, salt , salt_len); +} + +static void NS_set_key(char *key, int index) +{ + key_len = strlen((char *) key); + if (key_len > PLAINTEXT_LENGTH) + key_len = PLAINTEXT_LENGTH; + memcpy(cipher_key, key, key_len); +} + +static char *NS_get_key() +{ + cipher_key[key_len] = 0; + return cipher_key; +} + +static void NS_std_crypt() +{ + MD5_CTX ctx; + MD5_Init(&ctx); + memcpy(tocipher, cipher_salt, salt_len); + memcpy(tocipher + salt_len, adm, ADM_LEN); + memcpy(tocipher + salt_len + ADM_LEN, cipher_key, key_len); + MD5_Update(&ctx , tocipher, salt_len + ADM_LEN + key_len); + MD5_Final((void*)crypted, &ctx); +} + +static int NS_cmp_all(void *binary, int index) +{ + return !memcmp(binary, crypted, BINARY_SIZE); +} + +static int NS_cmp_exact(char *source, int index) +{ + return 1; +} + +struct fmt_main fmt_NS = { + { + FORMAT_LABEL, + FORMAT_NAME, + NS_ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + NS_init, + NS_valid, + fmt_default_split, + (void *(*)(char *))NS_std_get_binary, + (void *(*)(char *))NS_std_get_salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2 + }, + fmt_default_salt_hash, + NS_std_set_salt, + NS_set_key, + NS_get_key, + fmt_default_clear_keys, + NS_std_crypt, + { + get_hash_0, + get_hash_1, + get_hash_2 + }, + NS_cmp_all, + NS_cmp_all, + NS_cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/NT_fmt.c john-1.7.3.4/src/NT_fmt.c --- john-1.7.3.4.orig/src/NT_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/NT_fmt.c 2008-07-12 16:06:23 +0000 @@ -0,0 +1,613 @@ +/* NTLM patch for john (performance improvement) + * + * Written by Alain Espinosa in 2007 + * and placed in the public domain. + */ + +#include +#include "arch.h" +#include "misc.h" +#include "memory.h" +#include "common.h" +#include "formats.h" + +//Init values +#define INIT_A 0x67452301 +#define INIT_B 0xefcdab89 +#define INIT_C 0x98badcfe +#define INIT_D 0x10325476 + +#define SQRT_2 0x5a827999 +#define SQRT_3 0x6ed9eba1 + + +#define FORMAT_LABEL "nt" +#define FORMAT_NAME "NT MD4" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 27 +#define CIPHERTEXT_LENGTH 36 + +static struct fmt_tests tests[] = { + {"$NT$b7e4b9022cd45f275334bbdb83bb5be5", "John the Ripper"}, + {"$NT$8846f7eaee8fb117ad06bdd830b7586c", "password"}, + {"$NT$0cb6948805f797bf2a82807973b89537", "test"}, + {"$NT$31d6cfe0d16ae931b73c59d7e0c089c0", ""}, + {NULL} +}; + +#define BINARY_SIZE 16 +#define SALT_SIZE 0 + +#if defined (NT_X86_64) + #define NT_NUM_KEYS 32 + + unsigned int nt_buffer8x[16*NT_NUM_KEYS] __attribute__ ((aligned(16))); + unsigned int output8x[4*NT_NUM_KEYS] __attribute__ ((aligned(16))); + + #define ALGORITHM_NAME "128/128 X2 SSE2-16" + #define NT_CRYPT_FUN nt_crypt_all_x86_64 + extern void nt_crypt_all_x86_64(int count); +#elif defined (NT_SSE2) + #define NT_NUM_KEYS 40 + #define NT_NUM_KEYS1 8 + #define NT_NUM_KEYS4 32 + + unsigned int nt_buffer4x[64*NT_NUM_KEYS1] __attribute__ ((aligned(16))); + unsigned int output4x[16*NT_NUM_KEYS1] __attribute__ ((aligned(16))); + + unsigned int nt_buffer1x[16*NT_NUM_KEYS1]; + unsigned int output1x[4*NT_NUM_KEYS1]; + + #define ALGORITHM_NAME "128/128 SSE2 + 32/32" + #define NT_CRYPT_FUN nt_crypt_all_sse2 + extern void nt_crypt_all_sse2(int count); +#else + #define NT_NUM_KEYS 64 + unsigned int nt_buffer1x[16*NT_NUM_KEYS]; + unsigned int output1x[4*NT_NUM_KEYS]; + + #define ALGORITHM_NAME "32/32" + #define NT_CRYPT_FUN nt_crypt_all_generic + static void nt_crypt_all_generic(int count) + { + unsigned int a; + unsigned int b; + unsigned int c; + unsigned int d; + unsigned int i=0; + + for(;i>29); + d = INIT_D+(INIT_C ^ (a & 0x77777777)) +nt_buffer1x[i*16+1];d=(d<<7 )|(d>>25); + c = INIT_C+(INIT_B ^ (d & (a ^ INIT_B))) +nt_buffer1x[i*16+2];c=(c<<11)|(c>>21); + b = INIT_B + (a ^ (c & (d ^ a))) +nt_buffer1x[i*16+3];b=(b<<19)|(b>>13); + + a += (d ^ (b & (c ^ d))) + nt_buffer1x[i*16+4] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + nt_buffer1x[i*16+5] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + nt_buffer1x[i*16+6] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + nt_buffer1x[i*16+7] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + nt_buffer1x[i*16+8] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + nt_buffer1x[i*16+9] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + nt_buffer1x[i*16+10] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + nt_buffer1x[i*16+11] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + nt_buffer1x[i*16+12] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + nt_buffer1x[i*16+13] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + nt_buffer1x[i*16+14] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a)));b = (b << 19) | (b >> 13); + + /* Round 2 */ + a += ((b & (c | d)) | (c & d))+nt_buffer1x[i*16+0] +SQRT_2;a = (a<<3 ) | (a>>29); + d += ((a & (b | c)) | (b & c))+nt_buffer1x[i*16+4] +SQRT_2;d = (d<<5 ) | (d>>27); + c += ((d & (a | b)) | (a & b))+nt_buffer1x[i*16+8] +SQRT_2;c = (c<<9 ) | (c>>23); + b += ((c & (d | a)) | (d & a))+nt_buffer1x[i*16+12]+SQRT_2;b = (b<<13) | (b>>19); + + a += ((b & (c | d)) | (c & d))+nt_buffer1x[i*16+1] +SQRT_2;a = (a<<3 ) | (a>>29); + d += ((a & (b | c)) | (b & c))+nt_buffer1x[i*16+5] +SQRT_2;d = (d<<5 ) | (d>>27); + c += ((d & (a | b)) | (a & b))+nt_buffer1x[i*16+9] +SQRT_2;c = (c<<9 ) | (c>>23); + b += ((c & (d | a)) | (d & a))+nt_buffer1x[i*16+13]+SQRT_2;b = (b<<13) | (b>>19); + + a += ((b & (c | d)) | (c & d))+nt_buffer1x[i*16+2] +SQRT_2;a = (a<<3 ) | (a>>29); + d += ((a & (b | c)) | (b & c))+nt_buffer1x[i*16+6] +SQRT_2;d = (d<<5 ) | (d>>27); + c += ((d & (a | b)) | (a & b))+nt_buffer1x[i*16+10]+SQRT_2;c = (c<<9 ) | (c>>23); + b += ((c & (d | a)) | (d & a))+nt_buffer1x[i*16+14]+SQRT_2;b = (b<<13) | (b>>19); + + a += ((b & (c | d)) | (c & d))+nt_buffer1x[i*16+3] +SQRT_2;a = (a<<3 ) | (a>>29); + d += ((a & (b | c)) | (b & c))+nt_buffer1x[i*16+7] +SQRT_2;d = (d<<5 ) | (d>>27); + c += ((d & (a | b)) | (a & b))+nt_buffer1x[i*16+11]+SQRT_2;c = (c<<9 ) | (c>>23); + b += ((c & (d | a)) | (d & a)) +SQRT_2;b = (b<<13) | (b>>19); + + /* Round 3 */ + a += (d ^ c ^ b) + nt_buffer1x[i*16+0] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (c ^ b ^ a) + nt_buffer1x[i*16+8] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (b ^ a ^ d) + nt_buffer1x[i*16+4] + SQRT_3; c = (c << 11) | (c >> 21); + b += (a ^ d ^ c) + nt_buffer1x[i*16+12] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (d ^ c ^ b) + nt_buffer1x[i*16+2] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (c ^ b ^ a) + nt_buffer1x[i*16+10] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (b ^ a ^ d) + nt_buffer1x[i*16+6] + SQRT_3; c = (c << 11) | (c >> 21); + b += (a ^ d ^ c) + nt_buffer1x[i*16+14] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (d ^ c ^ b) + nt_buffer1x[i*16+1] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (c ^ b ^ a) + nt_buffer1x[i*16+9] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (b ^ a ^ d) + nt_buffer1x[i*16+5] + SQRT_3; c = (c << 11) | (c >> 21); + b += (a ^ d ^ c) + nt_buffer1x[i*16+13]; + + output1x[4*i+0]=a; + output1x[4*i+1]=b; + output1x[4*i+2]=c; + output1x[4*i+3]=d; + } + } +#endif + +static unsigned int last_i[NT_NUM_KEYS]; +static char saved_plain[32*NT_NUM_KEYS]; + +#define MIN_KEYS_PER_CRYPT NT_NUM_KEYS +#define MAX_KEYS_PER_CRYPT NT_NUM_KEYS + +static void fmt_NT_init(void) +{ + memset(last_i,0,4*NT_NUM_KEYS); +#if defined(NT_X86_64) + memset(nt_buffer8x,0,16*4*NT_NUM_KEYS); +#elif defined(NT_SSE2) + memset(nt_buffer4x,0,64*4*NT_NUM_KEYS1); + memset(nt_buffer1x,0,16*4*NT_NUM_KEYS1); +#else + memset(nt_buffer1x,0,16*4*NT_NUM_KEYS); +#endif +} + +static char * nt_split(char *ciphertext, int index) +{ + static char out[37]; + + if (!strncmp(ciphertext, "$NT$", 4)) + ciphertext += 4; + + out[0] = '$'; + out[1] = 'N'; + out[2] = 'T'; + out[3] = '$'; + + memcpy(&out[4], ciphertext, 32); + out[36] = 0; + + strlwr(&out[4]); + + return out; +} + +static int valid(char *ciphertext) +{ + char *pos; + + if (strncmp(ciphertext, "$NT$", 4)!=0) return 0; + + for (pos = &ciphertext[4]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); + + if (!*pos && pos - ciphertext == CIPHERTEXT_LENGTH) + return 1; + else + return 0; + +} + +static void *get_binary(char *ciphertext) +{ + static unsigned int out[4]; + unsigned int i=0; + unsigned int temp; + + ciphertext+=4; + for (; i<4; i++) + { + temp = (atoi16[ARCH_INDEX(ciphertext[i*8+0])])<<4; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+1])]); + + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+2])])<<12; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+3])])<<8; + + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+4])])<<20; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+5])])<<16; + + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+6])])<<28; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+7])])<<24; + + out[i]=temp; + } + + out[0] -= INIT_A; + out[1] -= INIT_B; + out[2] -= INIT_C; + out[3] -= INIT_D; + + out[1] = (out[1] >> 15) | (out[1] << 17); + out[1] -= SQRT_3 + (out[2] ^ out[3] ^ out[0]); + out[1] = (out[1] >> 15) | (out[1] << 17); + out[1] -= SQRT_3; + + return out; +} + +static int binary_hash_0(void *binary) +{ + return ((unsigned int *)binary)[1] & 0x0F; +} + +static int binary_hash_1(void *binary) +{ + return ((unsigned int *)binary)[1] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((unsigned int *)binary)[1] & 0x0FFF; +} + +static int get_hash_0(int index) +{ +#if defined(NT_X86_64) + return output8x[32*(index>>3)+8+index%8] & 0x0F; +#elif defined(NT_SSE2) + if(index>2)+4+index%4] & 0x0F; + else + return output1x[(index-NT_NUM_KEYS4)*4+1] & 0x0F; +#else + return output1x[(index<<2)+1] & 0x0F; +#endif +} + +static int get_hash_1(int index) +{ +#if defined(NT_X86_64) + return output8x[32*(index>>3)+8+index%8] & 0xFF; +#elif defined(NT_SSE2) + if(index>2)+4+index%4] & 0xFF; + else + return output1x[(index-NT_NUM_KEYS4)*4+1] & 0xFF; +#else + return output1x[(index<<2)+1] & 0xFF; +#endif +} + +static int get_hash_2(int index) +{ +#if defined(NT_X86_64) + return output8x[32*(index>>3)+8+index%8] & 0x0FFF; +#elif defined(NT_SSE2) + if(index>2)+4+index%4] & 0x0FFF; + else + return output1x[(index-NT_NUM_KEYS4)*4+1] & 0x0FFF; +#else + return output1x[(index<<2)+1] & 0x0FFF; +#endif +} + +static int cmp_all(void *binary, int count) +{ + unsigned int i=0; + unsigned int b=((unsigned int *)binary)[1]; + +#if defined(NT_X86_64) + for(;i<(NT_NUM_KEYS/2);i+=4) + if(b==output8x[i] || b==output8x[i+1] || b==output8x[i+2] || b==output8x[i+3] || b==output8x[i+4] || b==output8x[i+5] || b==output8x[i+6] || b==output8x[i+7]) + return 1; +#elif defined(NT_SSE2) + unsigned int pos=4; + + for(;i>3)+index%8; + + a=output8x[temp]; + b=output8x[temp+8]; + c=output8x[temp+16]; + d=output8x[temp+24]; + + pos1=24+index%8+128*(index>>3); + pos2=64+pos1; + pos3=32+pos1; +#elif defined(NT_SSE2) + int temp; + + if(index>2)+index%4; + + a=output4x[temp]; + b=output4x[temp+4]; + c=output4x[temp+8]; + d=output4x[temp+12]; + + pos1=12+index%4+64*(index>>2); + pos2=32+pos1; + pos3=16+pos1; + } + else + { + buffer=nt_buffer1x; + + temp=4*(index-NT_NUM_KEYS4); + + a=output1x[temp]; + b=output1x[temp+1]; + c=output1x[temp+2]; + d=output1x[temp+3]; + + pos1=3+4*temp; + pos2=8+pos1; + pos3=4+pos1; + } +#else + buffer=nt_buffer1x; + + a=output1x[(index<<2)]; + b=output1x[(index<<2)+1]; + c=output1x[(index<<2)+2]; + d=output1x[(index<<2)+3]; + + pos1=(index<<4)+3; + pos2=8+pos1; + pos3=4+pos1; +#endif + if(b!=t[1]) + return 0; + b += SQRT_3;b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + buffer[pos1] + SQRT_3; a = (a << 3 ) | (a >> 29); + if(a!=t[0]) + return 0; + + d += (a ^ b ^ c) + buffer[pos2] + SQRT_3; d = (d << 9 ) | (d >> 23); + if(d!=t[3]) + return 0; + + c += (d ^ a ^ b) + buffer[pos3] + SQRT_3; c = (c << 11) | (c >> 21); + return c==t[2]; +} + +static int cmp_exact(char *source, int index) +{ + return 1; +} + +static void set_salt(void *salt) +{ +} + +static void set_key(char *key, int index) +{ + unsigned int i=0; + unsigned int md4_size=0; + unsigned int saved_base=index<<5; + unsigned int temp; + int buff_base; +#if defined(NT_X86_64) + unsigned int last_length=last_i[index]<<2; + + buff_base=128*(index>>3)+index%8; + + for(;key[md4_size] && md4_size>2)+index%4; + + for(;key[md4_size] && md4_size>=1; + + for(;i<=last_length;i++) + nt_buffer1x[i+buff_base]=0; + + last_i[index]=md4_size>>1; + + nt_buffer1x[14+buff_base] = md4_size << 4; + } +#else + buff_base=index<<4; + + for(;key[md4_size] && md4_size>1; + + nt_buffer1x[buff_base+14] = md4_size << 4; +#endif +} + +static char *get_key(int index) +{ + return saved_plain+(index<<5); +} + +struct fmt_main fmt_NT = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + fmt_NT_init, + valid, + nt_split, + get_binary, + fmt_default_salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2 + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + NT_CRYPT_FUN, + { + get_hash_0, + get_hash_1, + get_hash_2 + }, + cmp_all, + cmp_one, + cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/OPENLDAPS_fmt.c john-1.7.3.4/src/OPENLDAPS_fmt.c --- john-1.7.3.4.orig/src/OPENLDAPS_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/OPENLDAPS_fmt.c 2008-09-15 01:28:09 +0000 @@ -0,0 +1,296 @@ +// Fix for john the ripper 1.6.37 by Sun-Zero, 2004. 07. 26. +/* + * This file is part of John the Ripper password cracker, + * Copyright (c) 1996-98 by Solar Designer + * + * Minor performance enhancement by bartavelle at bandecon.com + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "params.h" +#include "formats.h" +#include "common.h" + +#include "sha.h" +#include "base64.h" + +#undef MMX_COEF +#undef MMX_TYPE + +#define FORMAT_LABEL "openssha" +#define FORMAT_NAME "OpenLDAP SSHA" +#define SHA_TYPE "salted SHA-1" + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 32 + +#define BINARY_SIZE 20 +#define SALT_SIZE 4 + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) ) +#else +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +#define NSLDAP_MAGIC "{ssha}" +#define NSLDAP_MAGIC_LENGTH 6 + +static struct fmt_tests tests[] = { + {"{SSHA}bPXG4M1KkwZh2Hbgnuoszvpat0T/OS86", "thales"}, + {"{SSHA}hHSEPW3qeiOo5Pl2MpHQCXh0vgfyVR/X", "test1"}, + {"{SSHA}pXp4yIiRmppvKYn7cKCT+lngG4qELq4h", "test2"}, + {"{SSHA}Bv8tu3wB8WTMJj3tcOsl1usm5HzGwEmv", "test3"}, + {"{SSHA}kXyh8wLCKbN+QRbL2F2aUbkP62BJ/bRg", "lapin"}, + {"{SSHA}rnMVxsf1YJPg0L5CBhbVLIsJF+o/vkoE", "canard"}, + {"{SSHA}Uf2x9YxSWZZNAi2t1QXbG2PmT07AtURl", "chien"}, + {"{SSHA}XXGLZ7iKpYSBpF6EwoeTl27U0L/kYYsY", "hibou"}, + {"{SSHA}HYRPmcQIIzIIg/c1L8cZKlYdNpyeZeml", "genou"}, + {"{SSHA}Zm/0Wll7rLNpBU4HFUKhbASpXr94eSTc", "caillou"}, + {"{SSHA}Qc9OB+aEFA/mJ5MNy0AB4hRIkNiAbqDb", "doudou"}, + {NULL} +}; + +#ifdef MMX_COEF +static char crypt_key[BINARY_SIZE*MMX_COEF]; +/* Cygwin would not guarantee the alignment for this static declaration, but + * this source file is not MMX-ready anyway (MMX_COEF is #undef'ed above). */ +static char saved_key[80*MMX_COEF*4] __attribute__ ((aligned(8*MMX_COEF))); +static unsigned char out[PLAINTEXT_LENGTH + 1]; +#else +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static char saved_key[PLAINTEXT_LENGTH + 1]; +#endif + +#ifdef MMX_COEF +static unsigned long length[MAX_KEYS_PER_CRYPT]; +#endif + +static char saved_salt[SALT_SIZE]; + +static void * binary(char *ciphertext) { + static char realcipher[BINARY_SIZE + SALT_SIZE + 9]; + + /* stupid overflows */ + memset(realcipher, 0, BINARY_SIZE + SALT_SIZE + 9); + base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher); +#ifdef MMX_COEF + alter_endianity((unsigned char*)realcipher, BINARY_SIZE); +#endif + return (void *)realcipher; +} + +static void * get_salt(char * ciphertext) +{ + static char realcipher[BINARY_SIZE + SALT_SIZE + 9]; + memset(realcipher, 0, BINARY_SIZE + SALT_SIZE + 9); + base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher); + return (void*)realcipher+BINARY_SIZE; +} + +static int valid(char *ciphertext) +{ + if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH + NSLDAP_MAGIC_LENGTH) + return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH); + return 0; +} + +static int binary_hash_0(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFFF; +} + +static int get_hash_0(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF; +} + +static int get_hash_1(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF; +} + +static int get_hash_2(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF; +} + +static int salt_hash(void *salt) +{ + return *((ARCH_WORD_32 *)salt) & (SALT_HASH_SIZE - 1); +} + +static void set_key(char *key, int index) +{ +#ifdef MMX_COEF + int len; + int i; + + if(index==0) + { + memset(saved_key, 0, sizeof(saved_key)); + } + len = strlen(key); + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + length[index] = len; + + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#else + return !memcmp(binary, crypt_key, BINARY_SIZE); +#endif +} + +static int +cmp_exact(char *source, int index) +{ + return 1; +} + +static int cmp_one(void * binary, int index) +{ +#ifdef MMX_COEF + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] ) + return 0; + return 1; +#else + return cmp_all(binary, index); +#endif +} + + +static void crypt_all(int count) +{ +#ifdef MMX_COEF + int i,idx; + + for(idx=0;idxluser<::>luser@hotmail.com<::><::>1ea46bf1f5167b63d12bd47c8873050e<::>C9% + * it can be converted to the wanted form with the following perl script: + * + * #!/usr/bin/perl -w + * while (<>) { + * my @fields = split(/<::>/, $_); + * my $a = substr $fields[5], 0, 1; + * my $b = substr $fields[5], 1, 1; + * my $c = substr $fields[5], 2, 1; + * printf "%s:\$IPB2\$%02x%02x%02x\$%s\n", $fields[1], ord($a), ord($b), ord($c), $fields[4]; + * } + * + * BUGS: Can't handle usernames with ':' in them. + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "md5.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "phps" +#define FORMAT_NAME "PHPS MD5" +#define ALGORITHM_NAME "MD5(MD5($pass).$salt)" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define MD5_BINARY_SIZE 16 +#define MD5_HEX_SIZE (MD5_BINARY_SIZE * 2) + +#define BINARY_SIZE MD5_BINARY_SIZE + +#define SALT_SIZE 3 +#define PROCESSED_SALT_SIZE SALT_SIZE + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH (1 + 4 + 1 + SALT_SIZE * 2 + 1 + MD5_HEX_SIZE) + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests phps_tests[] = { + {"$PHPS$433925$5d756853cd63acee76e6dcd6d3728447", "welcome"}, + {NULL} +}; + +static char itoa16_shr_04[] = + "0000000000000000" + "1111111111111111" + "2222222222222222" + "3333333333333333" + "4444444444444444" + "5555555555555555" + "6666666666666666" + "7777777777777777" + "8888888888888888" + "9999999999999999" + "aaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbb" + "cccccccccccccccc" + "dddddddddddddddd" + "eeeeeeeeeeeeeeee" + "ffffffffffffffff"; + +static char itoa16_and_0f[] = + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef"; + +static MD5_CTX ctx; +static char saved_key[PLAINTEXT_LENGTH + 1]; +static int saved_key_len; +static char workspace[MD5_HEX_SIZE * 2]; +static char output[MD5_BINARY_SIZE]; + +static int phps_valid(char *ciphertext) +{ + if (!ciphertext) + return 0; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + + if (strncmp(ciphertext, "$PHPS$", 6) != 0) + return 0; + + if (ciphertext[12] != '$') + return 0; + + if (strspn(ciphertext+6, itoa16) != SALT_SIZE * 2) + return 0; + + if (strspn(ciphertext+13, itoa16) != MD5_HEX_SIZE) + return 0; + + return 1; +} + +static void *phps_binary(char *ciphertext) +{ + static unsigned char binary_cipher[BINARY_SIZE]; + int i; + + ciphertext += 13; + for (i = 0; i < MD5_HEX_SIZE; ++i) + binary_cipher[i] = + (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + return (void *)binary_cipher; +} + +static void *phps_salt(char *ciphertext) +{ + static unsigned char binary_salt[SALT_SIZE]; + int i; + + ciphertext += 6; + for (i = 0; i < SALT_SIZE; ++i) + binary_salt[i] = + (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + return (void*)binary_salt; +} + +static void phps_set_salt(void *salt) +{ + memcpy((char*)(workspace + MD5_HEX_SIZE), (char*)salt, PROCESSED_SALT_SIZE); +} + +static int strnfcpy_count(char *dst, char *src, int size) +{ + char *dptr = dst, *sptr = src; + int count = size; + + while (count--) + if (!(*dptr++ = *sptr++)) break; + + return size-count-1; +} + +static void phps_set_key(char *key, int index) +{ + static unsigned char key_hash[MD5_BINARY_SIZE]; + unsigned char *kh = key_hash; + unsigned char *workspace_ptr = (unsigned char *) workspace; + unsigned char v; + int i; + + saved_key_len = strnfcpy_count(saved_key, key, PLAINTEXT_LENGTH); + + MD5_Init(&ctx); + MD5_Update(&ctx, saved_key, saved_key_len); + MD5_Final(key_hash, &ctx); + + for (i = 0; i < MD5_BINARY_SIZE; ++i) { + v = *kh++; + *workspace_ptr++ = itoa16_shr_04[ARCH_INDEX(v)]; + *workspace_ptr++ = itoa16_and_0f[ARCH_INDEX(v)]; + } +} + +static char *phps_get_key(int index) +{ + return saved_key; +} + +static void phps_crypt_all(int count) +{ + MD5_Init(&ctx); + MD5_Update(&ctx, workspace, MD5_HEX_SIZE + SALT_SIZE); + MD5_Final((unsigned char *) output, &ctx); +} + +static int phps_cmp_all(void *binary, int index) +{ + return !memcmp(binary, output, MD5_BINARY_SIZE); +} + +static int phps_cmp_exact(char *source, int index) +{ + return 1; +} + +struct fmt_main fmt_PHPS = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + PROCESSED_SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + phps_tests + }, + { + fmt_default_init, + phps_valid, + fmt_default_split, + phps_binary, + phps_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + phps_set_salt, + phps_set_key, + phps_get_key, + fmt_default_clear_keys, + phps_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + phps_cmp_all, + phps_cmp_all, + phps_cmp_exact + } +}; + + +/** + * GNU Emacs settings: K&R with 1 tab indent. + * Local Variables: + * c-file-style: "k&r" + * c-basic-offset: 8 + * indent-tabs-mode: t + * End: + */ diff -urpN john-1.7.3.4.orig/src/PO_fmt.c john-1.7.3.4/src/PO_fmt.c --- john-1.7.3.4.orig/src/PO_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/PO_fmt.c 2009-08-31 13:34:04 +0000 @@ -0,0 +1,223 @@ +/* + * Post.Office MD5 cracker. + * Uses a modified version of Solar Designer's MD5 routine. + * + * This file adapted from other code in this project. + * + * To extract these crypts from Post.Office, use something + * along the lines of: + * + * /usr/local/post.office/cmdutils/listacct \ + * -i POP-Address,Account-ID,Password,Name | \ + * perl -ne 'chop;@a=split(/;/);print + * (($a[0]?$a[0]:$a[1]).":".$a[2].":0:0:".$a[3]."::\n");' + * + * Then find any passwords ending in UNIX-PASSWORD and tidy + * them up (and crack as plain DES crypts); this module will + * handle the others. + * + * This crypt format may also be found in LDAP directories of + * users migrated from Post.Office, for example the crypt format + * can be supported by OpenWave and qmail-ldap. + * + * Copyright (c) 2005 David Luyer + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "md5_go.h" + +typedef ARCH_WORD_32 MD5_word; +typedef MD5_word MD5_binary[4]; +#if ARCH_LITTLE_ENDIAN +#define MD5_out MD5_out_go +#else +#define MD5_out MD5_bitswapped_out_go +#endif +extern MD5_binary MD5_out; + +#define FORMAT_LABEL "po" +#define FORMAT_NAME "Post.Office MD5" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 64 +#define CIPHERTEXT_LENGTH 64 + +#define BINARY_SIZE 4 +#define SALT_SIZE 32 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"550c41c11bab48f9dbd8203ed313eef0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "abc123"}, + {"0c78bdef7d5448105cfbbc9aaa490a44550c41c11bab48f9dbd8203ed313eef0", "abc123"}, + {"9be296cf73d2f548dae3cccafaff1dd982916963c701200625cba2acd40d6569", "FRED"}, + {"a0e2078f0354846ec5bc4c7d7be08a4682916963c701200625cba2acd40d6569", ""}, + {NULL} +}; + +static char saved_key[PLAINTEXT_LENGTH + 1]; +static int saved_key_len; +static char po_buf[SALT_SIZE * 2 + 2 + PLAINTEXT_LENGTH + 128 /* MD5 scratch space */]; + +static void po_init(void) { + /* Do nothing */ +} + +static int valid(char *ciphertext) +{ + if (strlen(ciphertext) == 64 && + strspn(ciphertext, "0123456789abcdef") == 64) { + return 1; + } + return 0; +} + +static int binary_hash_0(void *binary) +{ + return *(MD5_word *)binary & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return *(MD5_word *)binary & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return *(MD5_word *)binary & 0xFFF; +} + +static int get_hash_0(int index) +{ + return MD5_out[0] & 0xF; +} + +static int get_hash_1(int index) +{ + return MD5_out[0] & 0xFF; +} + +static int get_hash_2(int index) +{ + return MD5_out[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; +} + +static void set_key(char *key, int index) +{ + strnfcpy(saved_key, key, PLAINTEXT_LENGTH); + saved_key_len = strlen(saved_key); +} + +static char *get_key(int index) +{ + saved_key[PLAINTEXT_LENGTH] = 0; + return saved_key; +} + +static int cmp_all(void *binary, int index) +{ + /* also used for cmp_one */ + return *(MD5_word *)binary == MD5_out[0]; +} + +static int cmp_exact(char *source, int index) +{ + static char fullmd5[16]; + int i; + + for(i=0;i<16;i++) + { + fullmd5[i] = atoi16[ARCH_INDEX(source[i*2])]*16 + atoi16[ARCH_INDEX(source[i*2+1])]; + } + return !memcmp(fullmd5, MD5_out, sizeof(MD5_binary)); +} + +static void *get_binary(char *ciphertext) +{ + static char binarycipher[BINARY_SIZE]; + int i; + + for(i=0;i +#include + +#include "arch.h" +#include "params.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "xsha" +#define FORMAT_NAME "Mac OS X 10.4+ salted SHA-1" +#define ALGORITHM_NAME "32/" ARCH_BITS_STR + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 51 +#define CIPHERTEXT_LENGTH 48 + +#define BINARY_SIZE 20 +#define SALT_SIZE 4 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"12345678F9083C7F66F46A0A102E4CC17EC08C8AF120571B", "abc"}, + {"12345678EB8844BFAF2A8CBDD587A37EF8D4A290680D5818", "azertyuiop1"}, + {"3234C32AAA335FD20E3F95870E5851BDBE942B79CE4FDD92", "azertyuiop2"}, + {"01295B67659E95F32931CEDB3BA50289E2826AF3D5A1422F", "apple"}, + {"0E6A48F765D0FFFFF6247FA80D748E615F91DD0C7431E4D9", "macintosh"}, + {"A320163F1E6DB42C3949F7E232888ACC7DB7A0A17E493DBA", "test"}, + {NULL} +}; + +static char saved_key[PLAINTEXT_LENGTH + 1]; +static int saved_key_length; +static ARCH_WORD_32 saved_salt; +static SHA_CTX ctx; +static ARCH_WORD_32 crypt_out[5]; + +static int valid(char *ciphertext) +{ + char *pos; + + /* Require uppercase hex digits (assume ASCII) */ + pos = ciphertext; + while (atoi16[ARCH_INDEX(*pos)] != 0x7F && *pos < 'a') + pos++; + return !*pos && pos - ciphertext == CIPHERTEXT_LENGTH; +} + +static void *get_binary(char *ciphertext) +{ + static unsigned char out[BINARY_SIZE]; + char *p; + int i; + + p = ciphertext + 8; + for (i = 0; i < sizeof(out); i++) { + out[i] = + (atoi16[ARCH_INDEX(*p)] << 4) | + atoi16[ARCH_INDEX(p[1])]; + p += 2; + } + + return out; +} + +static void *salt(char *ciphertext) +{ + static unsigned char out[SALT_SIZE]; + char *p; + int i; + + p = ciphertext; + for (i = 0; i < sizeof(out); i++) { + out[i] = + (atoi16[ARCH_INDEX(*p)] << 4) | + atoi16[ARCH_INDEX(p[1])]; + p += 2; + } + + return out; +} + +static int binary_hash_0(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xFFF; +} + +static int get_hash_0(int index) +{ + return crypt_out[0] & 0xF; +} + +static int get_hash_1(int index) +{ + return crypt_out[0] & 0xFF; +} + +static int get_hash_2(int index) +{ + return crypt_out[0] & 0xFFF; +} + +static int salt_hash(void *salt) +{ + return *(ARCH_WORD_32 *)salt & 0x3FF; +} + +static void set_salt(void *salt) +{ + saved_salt = *(ARCH_WORD_32 *)salt; +} + +static void set_key(char *key, int index) +{ + saved_key_length = strlen(key); + if (saved_key_length > PLAINTEXT_LENGTH) + saved_key_length = PLAINTEXT_LENGTH; + memcpy(saved_key, key, saved_key_length); +} + +static char *get_key(int index) +{ + saved_key[saved_key_length] = 0; + return saved_key; +} + +static void crypt_all(int count) +{ + SHA1_Init(&ctx); + SHA1_Update(&ctx, &saved_salt, SALT_SIZE); + SHA1_Update(&ctx, saved_key, saved_key_length); + SHA1_Final((unsigned char *)crypt_out, &ctx); +} + +static int cmp_all(void *binary, int count) +{ + return !memcmp(binary, crypt_out, BINARY_SIZE); +} + +static int cmp_exact(char *source, int index) +{ + return 1; +} + +struct fmt_main fmt_XSHA = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + fmt_default_init, + valid, + fmt_default_split, + get_binary, + salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2 + }, + salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + get_hash_0, + get_hash_1, + get_hash_2 + }, + cmp_all, + cmp_all, + cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/base64.c john-1.7.3.4/src/base64.c --- john-1.7.3.4.orig/src/base64.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/base64.c 2008-02-20 14:19:35 +0000 @@ -0,0 +1,74 @@ + +#include +#include +#include +#include + +void base64_unmap(char *in_block) { + int i; + char *c; + + for(i=0; i<4; i++) { + c = in_block + i; + + if(*c>='A' && *c<='Z') { + *c -= 'A'; + continue; + } + + if(*c>='a' && *c<='z') { + *c -= 'a'; + *c += 26; + continue; + } + + if(*c == '+') { + *c = 62; + continue; + } + + if(*c == '/') { + *c = 63; + continue; + } + + if(*c == '=') { + *c = 0; + } + + *c -= '0'; + *c += 52; + } +} + +int base64_decode(char *in, int inlen, char *out) { + int i; + char *in_block; + char *out_block; + char temp[4]; + + out_block = out; + in_block = in; + + for(i=0; i + * 2002-04-16 +*/ + +#include + +#include "blowfish.h" +#include "bf_tab.h" /* P-box P-array, S-box */ + +/* #define S(x,i) (bf_S[i][x.w.byte##i]) */ +#define S0(x) (bf_S[0][x.w.byte0]) +#define S1(x) (bf_S[1][x.w.byte1]) +#define S2(x) (bf_S[2][x.w.byte2]) +#define S3(x) (bf_S[3][x.w.byte3]) +#define bf_F(x) (((S0(x) + S1(x)) ^ S2(x)) + S3(x)) +#define ROUND(a,b,n) (a.word ^= bf_F(b) ^ bf_P[n]) + +#include + +/* keep a set of rotating P & S boxes */ +static struct box_t { + UWORD_32bits *P; + UWORD_32bits **S; + char key[81]; + char keybytes; +} box; + +//static UWORD_32bits bf_P[bf_N+2]; +//static UWORD_32bits bf_S[4][256]; +static UWORD_32bits *bf_P; +static UWORD_32bits **bf_S; + + +void blowfish_first_init(void) { + box.P = NULL; + box.S = NULL; + box.key[0] = 0; +} + +static void blowfish_encipher(UWORD_32bits * xl, UWORD_32bits * xr) +{ + union aword Xl; + union aword Xr; + + Xl.word = *xl; + Xr.word = *xr; + + Xl.word ^= bf_P[0]; + ROUND(Xr, Xl, 1); + ROUND(Xl, Xr, 2); + ROUND(Xr, Xl, 3); + ROUND(Xl, Xr, 4); + ROUND(Xr, Xl, 5); + ROUND(Xl, Xr, 6); + ROUND(Xr, Xl, 7); + ROUND(Xl, Xr, 8); + ROUND(Xr, Xl, 9); + ROUND(Xl, Xr, 10); + ROUND(Xr, Xl, 11); + ROUND(Xl, Xr, 12); + ROUND(Xr, Xl, 13); + ROUND(Xl, Xr, 14); + ROUND(Xr, Xl, 15); + ROUND(Xl, Xr, 16); + Xr.word ^= bf_P[17]; + + *xr = Xl.word; + *xl = Xr.word; +} + +static void blowfish_init(UBYTE_08bits * key, short keybytes) +{ + int i, j; + UWORD_32bits data; + UWORD_32bits datal; + UWORD_32bits datar; + union aword temp; + + /* is buffer already allocated for this? */ + if (box.P != NULL) { + if ((box.keybytes == keybytes) && + (!strncmp((char *) (box.key), (char *) key, keybytes))) { + /* match! */ + bf_P = box.P; + bf_S = box.S; + return; + } + free(box.P); + for (i = 0; i < 4; i++) + free(box.S[i]); + free(box.S); + } + /* initialize new buffer */ + /* uh... this is over 4k */ + box.P = (UWORD_32bits *) malloc((bf_N + 2) * sizeof(UWORD_32bits)); + box.S = (UWORD_32bits **) malloc(4 * sizeof(UWORD_32bits *)); + for (i = 0; i < 4; i++) + box.S[i] = (UWORD_32bits *) malloc(256 * sizeof(UWORD_32bits)); + bf_P = box.P; + bf_S = box.S; + box.keybytes = keybytes; + strncpy(box.key, (char *) key, keybytes); + /* robey: reset blowfish boxes to initial state */ + /* (i guess normally it just keeps scrambling them, but here it's + * important to get the same encrypted result each time) */ + for (i = 0; i < bf_N + 2; i++) + bf_P[i] = initbf_P[i]; + for (i = 0; i < 4; i++) + for (j = 0; j < 256; j++) + bf_S[i][j] = initbf_S[i][j]; + + j = 0; + for (i = 0; i < bf_N + 2; ++i) { + temp.word = 0; + temp.w.byte0 = key[j]; + temp.w.byte1 = key[(j + 1) % keybytes]; + temp.w.byte2 = key[(j + 2) % keybytes]; + temp.w.byte3 = key[(j + 3) % keybytes]; + data = temp.word; + bf_P[i] = bf_P[i] ^ data; + j = (j + 4) % keybytes; + } + datal = 0x00000000; + datar = 0x00000000; + for (i = 0; i < bf_N + 2; i += 2) { + blowfish_encipher(&datal, &datar); + bf_P[i] = datal; + bf_P[i + 1] = datar; + } + for (i = 0; i < 4; ++i) { + for (j = 0; j < 256; j += 2) { + blowfish_encipher(&datal, &datar); + bf_S[i][j] = datal; + bf_S[i][j + 1] = datar; + } + } +} + +/* stuff below this line was written by robey for eggdrop use */ + +/* of course, if you change either of these, then your userfile will + * no longer be able to be shared. :) */ +#define SALT1 0xdeadd061 +#define SALT2 0x23f6b095 + +/* convert 64-bit encrypted password to text for userfile */ +static char *base64 = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +static void blowfish_encrypt_pass(char *text, char *new) +{ + UWORD_32bits left, right; + int n; + char *p; + + blowfish_init((UBYTE_08bits *) text, strlen(text)); + left = SALT1; + right = SALT2; + blowfish_encipher(&left, &right); + p = new; + *p++ = '+'; /* + means encrypted pass */ + n = 32; + while (n > 0) { + *p++ = base64[right & 0x3f]; + right = (right >> 6); + n -= 6; + } + n = 32; + while (n > 0) { + *p++ = base64[left & 0x3f]; + left = (left >> 6); + n -= 6; + } + *p = 0; +} diff -urpN john-1.7.3.4.orig/src/blowfish.h john-1.7.3.4/src/blowfish.h --- john-1.7.3.4.orig/src/blowfish.h 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/blowfish.h 2008-02-20 14:19:36 +0000 @@ -0,0 +1,55 @@ +/* modified 19jul1996 by robey -- uses autoconf values now */ +#ifndef _H_BLOWFISH +#define _H_BLOWFISH + +#include "arch.h" + +#define bf_N 16 +#define noErr 0 +#define DATAERROR -1 + +#define UBYTE_08bits unsigned char +#define UWORD_16bits unsigned short + +#define SIZEOF_INT 4 + +#if SIZEOF_INT==4 +#define UWORD_32bits unsigned int +#else +#if SIZEOF_LONG==4 +#define UWORD_32bits unsigned long +#endif +#endif + +/* choose a byte order for your hardware */ + +#if !ARCH_LITTLE_ENDIAN +/* ABCD - big endian - motorola */ +union aword { + UWORD_32bits word; + UBYTE_08bits byte[4]; + struct { + unsigned int byte0:8; + unsigned int byte1:8; + unsigned int byte2:8; + unsigned int byte3:8; + } w; +}; +#endif /* !ARCH_LITTLE_ENDIAN */ + +#if ARCH_LITTLE_ENDIAN +/* DCBA - little endian - intel */ +union aword { + UWORD_32bits word; + UBYTE_08bits byte[4]; + struct { + unsigned int byte3:8; + unsigned int byte2:8; + unsigned int byte1:8; + unsigned int byte0:8; + } w; +}; + +#endif /* ARCH_LITTLE_ENDIAN */ + +#endif diff -urpN john-1.7.3.4.orig/src/byteorder.h john-1.7.3.4/src/byteorder.h --- john-1.7.3.4.orig/src/byteorder.h 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/byteorder.h 2008-02-20 14:19:36 +0000 @@ -0,0 +1,274 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB Byte handling + Copyright (C) Andrew Tridgell 1992-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _BYTEORDER_H +#define _BYTEORDER_H + +/* + This file implements macros for machine independent short and + int manipulation + +Here is a description of this file that I emailed to the samba list once: + +> I am confused about the way that byteorder.h works in Samba. I have +> looked at it, and I would have thought that you might make a distinction +> between LE and BE machines, but you only seem to distinguish between 386 +> and all other architectures. +> +> Can you give me a clue? + +sure. + +The distinction between 386 and other architectures is only there as +an optimisation. You can take it out completely and it will make no +difference. The routines (macros) in byteorder.h are totally byteorder +independent. The 386 optimsation just takes advantage of the fact that +the x86 processors don't care about alignment, so we don't have to +align ints on int boundaries etc. If there are other processors out +there that aren't alignment sensitive then you could also define +CAREFUL_ALIGNMENT=0 on those processors as well. + +Ok, now to the macros themselves. I'll take a simple example, say we +want to extract a 2 byte integer from a SMB packet and put it into a +type called uint16 that is in the local machines byte order, and you +want to do it with only the assumption that uint16 is _at_least_ 16 +bits long (this last condition is very important for architectures +that don't have any int types that are 2 bytes long) + +You do this: + +#define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) +#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos)) +#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) + +then to extract a uint16 value at offset 25 in a buffer you do this: + +char *buffer = foo_bar(); +uint16 xx = SVAL(buffer,25); + +We are using the byteoder independence of the ANSI C bitshifts to do +the work. A good optimising compiler should turn this into efficient +code, especially if it happens to have the right byteorder :-) + +I know these macros can be made a bit tidier by removing some of the +casts, but you need to look at byteorder.h as a whole to see the +reasoning behind them. byteorder.h defines the following macros: + +SVAL(buf,pos) - extract a 2 byte SMB value +IVAL(buf,pos) - extract a 4 byte SMB value +SVALS(buf,pos) signed version of SVAL() +IVALS(buf,pos) signed version of IVAL() + +SSVAL(buf,pos,val) - put a 2 byte SMB value into a buffer +SIVAL(buf,pos,val) - put a 4 byte SMB value into a buffer +SSVALS(buf,pos,val) - signed version of SSVAL() +SIVALS(buf,pos,val) - signed version of SIVAL() + +RSVAL(buf,pos) - like SVAL() but for NMB byte ordering +RSVALS(buf,pos) - like SVALS() but for NMB byte ordering +RIVAL(buf,pos) - like IVAL() but for NMB byte ordering +RIVALS(buf,pos) - like IVALS() but for NMB byte ordering +RSSVAL(buf,pos,val) - like SSVAL() but for NMB ordering +RSIVAL(buf,pos,val) - like SIVAL() but for NMB ordering +RSIVALS(buf,pos,val) - like SIVALS() but for NMB ordering + +it also defines lots of intermediate macros, just ignore those :-) + +*/ + +/* some switch macros that do both store and read to and from SMB buffers */ + +#define RW_PCVAL(read,inbuf,outbuf,len) \ + { if (read) { PCVAL (inbuf,0,outbuf,len); } \ + else { PSCVAL(inbuf,0,outbuf,len); } } + +#define RW_PIVAL(read,big_endian,inbuf,outbuf,len) \ + { if (read) { if (big_endian) { RPIVAL(inbuf,0,outbuf,len); } else { PIVAL(inbuf,0,outbuf,len); } } \ + else { if (big_endian) { RPSIVAL(inbuf,0,outbuf,len); } else { PSIVAL(inbuf,0,outbuf,len); } } } + +#define RW_PSVAL(read,big_endian,inbuf,outbuf,len) \ + { if (read) { if (big_endian) { RPSVAL(inbuf,0,outbuf,len); } else { PSVAL(inbuf,0,outbuf,len); } } \ + else { if (big_endian) { RPSSVAL(inbuf,0,outbuf,len); } else { PSSVAL(inbuf,0,outbuf,len); } } } + +#define RW_CVAL(read, inbuf, outbuf, offset) \ + { if (read) { (outbuf) = CVAL (inbuf,offset); } \ + else { SCVAL(inbuf,offset,outbuf); } } + +#define RW_IVAL(read, big_endian, inbuf, outbuf, offset) \ + { if (read) { (outbuf) = ((big_endian) ? RIVAL(inbuf,offset) : IVAL (inbuf,offset)); } \ + else { if (big_endian) { RSIVAL(inbuf,offset,outbuf); } else { SIVAL(inbuf,offset,outbuf); } } } + +#define RW_SVAL(read, big_endian, inbuf, outbuf, offset) \ + { if (read) { (outbuf) = ((big_endian) ? RSVAL(inbuf,offset) : SVAL (inbuf,offset)); } \ + else { if (big_endian) { RSSVAL(inbuf,offset,outbuf); } else { SSVAL(inbuf,offset,outbuf); } } } + +#undef CAREFUL_ALIGNMENT + +/* we know that the 386 can handle misalignment and has the "right" + byteorder */ +#ifdef __i386__ +#define CAREFUL_ALIGNMENT 0 +#endif + +#ifndef CAREFUL_ALIGNMENT +#define CAREFUL_ALIGNMENT 1 +#endif + +#define CVAL(buf,pos) (((unsigned char *)(buf))[pos]) +#define PVAL(buf,pos) ((unsigned)CVAL(buf,pos)) +#define SCVAL(buf,pos,val) (CVAL(buf,pos) = (val)) + + +#if CAREFUL_ALIGNMENT + +#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8) +#define IVAL(buf,pos) (SVAL(buf,pos)|SVAL(buf,(pos)+2)<<16) +#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8) +#define SIVALX(buf,pos,val) (SSVALX(buf,pos,val&0xFFFF),SSVALX(buf,pos+2,val>>16)) +#define SVALS(buf,pos) ((int16)SVAL(buf,pos)) +#define IVALS(buf,pos) ((int32)IVAL(buf,pos)) +#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((uint16)(val))) +#define SIVAL(buf,pos,val) SIVALX((buf),(pos),((uint32)(val))) +#define SSVALS(buf,pos,val) SSVALX((buf),(pos),((int16)(val))) +#define SIVALS(buf,pos,val) SIVALX((buf),(pos),((int32)(val))) + +#else /* CAREFUL_ALIGNMENT */ + +/* this handles things for architectures like the 386 that can handle + alignment errors */ +/* + WARNING: This section is dependent on the length of int16 and int32 + being correct +*/ + +/* get single value from an SMB buffer */ +#define SVAL(buf,pos) (*(const uint16 *)((const char *)(buf) + (pos))) +#define IVAL(buf,pos) (*(const uint32 *)((const char *)(buf) + (pos))) +#define SVALS(buf,pos) (*(const int16 *)((const char *)(buf) + (pos))) +#define IVALS(buf,pos) (*(const int32 *)((const char *)(buf) + (pos))) + +/* store single value in an SMB buffer */ +#define SVALMOD(buf,pos) (*(uint16 *)((char *)(buf) + (pos))) +#define IVALMOD(buf,pos) (*(uint32 *)((char *)(buf) + (pos))) +#define SVALSMOD(buf,pos) (*(int16 *)((char *)(buf) + (pos))) +#define IVALSMOD(buf,pos) (*(int32 *)((char *)(buf) + (pos))) + +#define SSVAL(buf,pos,val) SVALMOD(buf,pos)=((uint16)(val)) +#define SIVAL(buf,pos,val) IVALMOD(buf,pos)=((uint32)(val)) +#define SSVALS(buf,pos,val) SVALSMOD(buf,pos)=((int16)(val)) +#define SIVALS(buf,pos,val) IVALSMOD(buf,pos)=((int32)(val)) + +#endif /* CAREFUL_ALIGNMENT */ + +/* macros for reading / writing arrays */ + +#define SMBMACRO(macro,buf,pos,val,len,size) \ +{ uint32 l; for (l = 0; l < (uint32)(len); l++) (val)[l] = macro((buf), (pos) + (size)*l); } + +#define SSMBMACRO(macro,buf,pos,val,len,size) \ +{ uint32 l; for (l = 0; l < (uint32)(len); l++) macro((buf), (pos) + (size)*l, (val)[l]); } + +/* reads multiple data from an SMB buffer */ +#define PCVAL(buf,pos,val,len) SMBMACRO(CVAL,buf,pos,val,len,1) +#define PSVAL(buf,pos,val,len) SMBMACRO(SVAL,buf,pos,val,len,2) +#define PIVAL(buf,pos,val,len) SMBMACRO(IVAL,buf,pos,val,len,4) +#define PCVALS(buf,pos,val,len) SMBMACRO(CVALS,buf,pos,val,len,1) +#define PSVALS(buf,pos,val,len) SMBMACRO(SVALS,buf,pos,val,len,2) +#define PIVALS(buf,pos,val,len) SMBMACRO(IVALS,buf,pos,val,len,4) + +/* stores multiple data in an SMB buffer */ +#define PSCVAL(buf,pos,val,len) SSMBMACRO(SCVAL,buf,pos,val,len,1) +#define PSSVAL(buf,pos,val,len) SSMBMACRO(SSVAL,buf,pos,val,len,2) +#define PSIVAL(buf,pos,val,len) SSMBMACRO(SIVAL,buf,pos,val,len,4) +#define PSCVALS(buf,pos,val,len) SSMBMACRO(SCVALS,buf,pos,val,len,1) +#define PSSVALS(buf,pos,val,len) SSMBMACRO(SSVALS,buf,pos,val,len,2) +#define PSIVALS(buf,pos,val,len) SSMBMACRO(SIVALS,buf,pos,val,len,4) + + +/* now the reverse routines - these are used in nmb packets (mostly) */ +#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF)) +#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16))) + +#define RSVAL(buf,pos) SREV(SVAL(buf,pos)) +#define RSVALS(buf,pos) SREV(SVALS(buf,pos)) +#define RIVAL(buf,pos) IREV(IVAL(buf,pos)) +#define RIVALS(buf,pos) IREV(IVALS(buf,pos)) +#define RSSVAL(buf,pos,val) SSVAL(buf,pos,SREV(val)) +#define RSSVALS(buf,pos,val) SSVALS(buf,pos,SREV(val)) +#define RSIVAL(buf,pos,val) SIVAL(buf,pos,IREV(val)) +#define RSIVALS(buf,pos,val) SIVALS(buf,pos,IREV(val)) + +/* reads multiple data from an SMB buffer (big-endian) */ +#define RPSVAL(buf,pos,val,len) SMBMACRO(RSVAL,buf,pos,val,len,2) +#define RPIVAL(buf,pos,val,len) SMBMACRO(RIVAL,buf,pos,val,len,4) +#define RPSVALS(buf,pos,val,len) SMBMACRO(RSVALS,buf,pos,val,len,2) +#define RPIVALS(buf,pos,val,len) SMBMACRO(RIVALS,buf,pos,val,len,4) + +/* stores multiple data in an SMB buffer (big-endian) */ +#define RPSSVAL(buf,pos,val,len) SSMBMACRO(RSSVAL,buf,pos,val,len,2) +#define RPSIVAL(buf,pos,val,len) SSMBMACRO(RSIVAL,buf,pos,val,len,4) +#define RPSSVALS(buf,pos,val,len) SSMBMACRO(RSSVALS,buf,pos,val,len,2) +#define RPSIVALS(buf,pos,val,len) SSMBMACRO(RSIVALS,buf,pos,val,len,4) + +#define DBG_RW_PCVAL(charmode,string,depth,base,read,inbuf,outbuf,len) \ + { RW_PCVAL(read,inbuf,outbuf,len) \ + DEBUG(5,("%s%04x %s: ", \ + tab_depth(depth), base,string)); \ + if (charmode) print_asc(5, (unsigned char*)(outbuf), (len)); else \ + { uint32 idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%02x ", (outbuf)[idx])); } } \ + DEBUG(5,("\n")); } + +#define DBG_RW_PSVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \ + { RW_PSVAL(read,big_endian,inbuf,outbuf,len) \ + DEBUG(5,("%s%04x %s: ", \ + tab_depth(depth), base,string)); \ + if (charmode) print_asc(5, (unsigned char*)(outbuf), 2*(len)); else \ + { uint32 idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%04x ", (outbuf)[idx])); } } \ + DEBUG(5,("\n")); } + +#define DBG_RW_PIVAL(charmode,string,depth,base,read,big_endian,inbuf,outbuf,len) \ + { RW_PIVAL(read,big_endian,inbuf,outbuf,len) \ + DEBUG(5,("%s%04x %s: ", \ + tab_depth(depth), base,string)); \ + if (charmode) print_asc(5, (unsigned char*)(outbuf), 4*(len)); else \ + { uint32 idx; for (idx = 0; idx < len; idx++) { DEBUG(5,("%08x ", (outbuf)[idx])); } } \ + DEBUG(5,("\n")); } + +#define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \ + { RW_CVAL(read,inbuf,outbuf,0) \ + DEBUG(5,("%s%04x %s: %02x\n", \ + tab_depth(depth), base, string, outbuf)); } + +#define DBG_RW_SVAL(string,depth,base,read,big_endian,inbuf,outbuf) \ + { RW_SVAL(read,big_endian,inbuf,outbuf,0) \ + DEBUG(5,("%s%04x %s: %04x\n", \ + tab_depth(depth), base, string, outbuf)); } + +#define DBG_RW_IVAL(string,depth,base,read,big_endian,inbuf,outbuf) \ + { RW_IVAL(read,big_endian,inbuf,outbuf,0) \ + DEBUG(5,("%s%04x %s: %08x\n", \ + tab_depth(depth), base, string, outbuf)); } + +/* Alignment macros. */ +#define ALIGN4(p,base) ((p) + ((4 - (PTR_DIFF((p), (base)) & 3)) & 3)) +#define ALIGN2(p,base) ((p) + ((2 - (PTR_DIFF((p), (base)) & 1)) & 1)) + +#endif /* _BYTEORDER_H */ diff -urpN john-1.7.3.4.orig/src/calc_stat.c john-1.7.3.4/src/calc_stat.c --- john-1.7.3.4.orig/src/calc_stat.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/calc_stat.c 2008-09-15 01:48:49 +0000 @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include + +#define C2I(c) ((unsigned int)(unsigned char)(c)) + +unsigned int * proba1; +unsigned int * proba2; +unsigned int * first; + +int main(int argc, char * * argv) +{ + FILE * fichier; + char * ligne; + int i; + int j; + int np; + int npflag; + int args; + unsigned int nb_lignes; + unsigned int nb_lettres; + + FILE * statfile; + + if( (argc!=3) && (argc!=4) ) + { + fprintf(stderr, "Usage: %s [-p] dictionnary_file statfile\n\t-p: do use non printable characters\n", argv[0]); + return -1; + } + + if(argc==4) + { + if(strcmp(argv[1], "-p")) + { + fprintf(stderr, "Usage: %s [-p] dictionnary_file statfile\n\t-p: do use non printable characters\n", argv[0]); + return -1; + } + args = 1; + npflag = 1; + } + else + { + args = 0; + npflag = 0; + } + + fichier = fopen(argv[1+args], "r"); + if(!fichier) + { + fprintf(stderr, "could not open %s\n", argv[1+args]); + return -1; + } + + first = malloc( sizeof(int) * 256 ); + + ligne = malloc(4096); + + proba2 = malloc(sizeof(unsigned int) * 256 * 256); + proba1 = malloc(sizeof(unsigned int) * 256 ); + memset(proba2, 0, sizeof(unsigned int) * 256 * 256); + memset(proba1, 0, sizeof(unsigned int) * 256 ); + + statfile = fopen(argv[2+args], "w"); + + nb_lignes = 0; + while(fgets(ligne, 4096, fichier)) + { + if (ligne[0] == 0) + continue; + i = strlen(ligne)-1; + while( (i>0) && ((ligne[i]=='\n') || (ligne[i]=='\r')) ) + { + ligne[i]=0; + i--; + } + for(i=0;ligne[i];i++) + { + np = 0; + if(C2I(ligne[i])<32) + { + fprintf(stderr, "Warning, non printable character line %d : %s\n", nb_lignes, ligne); + np += 1; + } + if(C2I(ligne[i])>127) + { + fprintf(stderr, "Warning, non US ascii character line %d : %s\n", nb_lignes, ligne); + np += 1; + } + if((i>0) && (C2I(ligne[i-1])<32)) + { + np += 2; + } + if((i>0) && (C2I(ligne[i-1])>127)) + { + np += 2; + } + + if( (i==0) && ((np == 0) || (npflag == 1)) ) + proba1[C2I(ligne[0])]++; + if( (i>0) && ((np == 0) || (npflag == 1)) ) + proba2[C2I(ligne[i-1])*256 + C2I(ligne[i])]++; + } + nb_lignes++; + } + + for(i=0;i<256;i++) + { + if ( (proba1[i] == 0 ) || (i==0) ) + { + proba1[i] = 1000; + } + else + { + if( (unsigned int) (- 10*log( (double) proba1[i] / (double) nb_lignes )) == 0) + { + fprintf(stderr, "zero -10*log proba1[%d] (%d) / %d converted to 1\n", i, proba1[i], nb_lignes); + proba1[i] = 1; + } + else + proba1[i] = (unsigned int) (- 10*log( (double) proba1[i] / (double) nb_lignes )); + fprintf(statfile, "%d=proba1[%d]\n", proba1[i], i); + } + + /* premiere passe : nb lettres */ + nb_lettres = 0; + for(j=0;j<256;j++) + { + nb_lettres += proba2[i*256 + j]; + } + + first[i] = 255; + + /* maintenant, calcul des stats */ + for(j=0;j<256;j++) + { + if( proba2[i*256 + j] == 0 ) + { + proba2[i*256 + j] = 1000; + } + else + { + if(first[i] == 255) + first[i] = j; + if((unsigned int) (- 10*log( (double) proba2[i*256+j] / (double) nb_lettres )) == 0) + { + fprintf(stderr, "zero -10*log proba2[%d*256+%d] (%d) / %d, converted to 1 to prevent infinite length candidates\n", i, j, proba2[i*256+j],nb_lettres ); + proba2[i*256 + j] = 1; + } + else + { + proba2[i*256 + j] = (unsigned int) (- 10*log( (double) proba2[i*256+j] / (double) nb_lettres )); + } + fprintf(statfile, "%d=proba2[%d*256+%d]\n", proba2[i*256+j], i, j); + } + } + } + + fclose(statfile); + + free(proba1); + free(proba2); + + free(first); + + free(ligne); + fclose(fichier); + + return 0; +} diff -urpN john-1.7.3.4.orig/src/cracker.c john-1.7.3.4/src/cracker.c --- john-1.7.3.4.orig/src/cracker.c 2006-02-27 06:28:54 +0000 +++ john-1.7.3.4/src/cracker.c 2008-08-28 01:00:49 +0000 @@ -87,6 +87,36 @@ void crk_init(struct db_main *db, void ( idle_init(); } +static void crk_remove_hash(struct db_password * pw, struct db_salt * salt, struct db_main * db) +{ + struct db_password * search_password; + int hash; + + if(salt==NULL) + return; + if( salt->hash_size<0 ) + return; + hash = db->format->methods.binary_hash[salt->hash_size](pw->binary); + if( salt->hash[hash] == pw ) + { + salt->hash[hash] = pw->next_hash; + salt->count--; + return; + } + search_password = salt->hash[hash]; + while(search_password && (search_password->next_hash!=pw)) + { + search_password = search_password->next_hash; + } + if(!search_password) + { + fprintf(stderr, "error here\n"); + exit(0); + } + search_password->next_hash = pw->next_hash; + salt->count--; +} + static int crk_process_guess(struct db_salt *salt, struct db_password *pw, int index) { @@ -116,7 +146,8 @@ static int crk_process_guess(struct db_s if (pw == salt->list) { salt->list = pw->next; - ldr_update_salt(crk_db, salt); + //ldr_update_salt(crk_db, salt); + crk_remove_hash(pw, salt, crk_db); if (!salt->list) { crk_db->salt_count--; @@ -138,7 +169,8 @@ static int crk_process_guess(struct db_s search_pw = search_pw->next; search_pw->next = pw->next; - ldr_update_salt(crk_db, salt); + //ldr_update_salt(crk_db, salt); + crk_remove_hash(pw, salt, crk_db); } return 0; diff -urpN john-1.7.3.4.orig/src/genmkvpwd.c john-1.7.3.4/src/genmkvpwd.c --- john-1.7.3.4.orig/src/genmkvpwd.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/genmkvpwd.c 2008-09-17 03:26:36 +0000 @@ -0,0 +1,285 @@ +#include +#include +#include +#include +#include +#include "params.h" +#include "memory.h" +#include "mkvlib.h" + +static void show_pwd_rnbs(struct s_pwd * pwd) +{ + unsigned long long i; + unsigned int k; + unsigned long lvl; + + k=0; + i = nbparts[pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len]; + pwd->len++; + lvl = pwd->level; + pwd->password[pwd->len] = 0; + while(i>1) + { + pwd->password[pwd->len-1] = charsorted[ pwd->password[pwd->len-2]*256 + k ]; + pwd->level = lvl + proba2[ pwd->password[pwd->len-2]*256 + pwd->password[pwd->len-1] ]; + i -= nbparts[ pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len ]; + if(pwd->len<=gmax_len) + { + show_pwd_rnbs(pwd); + } + printf("%s\n", pwd->password); + gidx++; + k++; + if(gidx>gend) + return; + } + pwd->len--; + pwd->password[pwd->len] = 0; + pwd->level = lvl; +} + +static void show_pwd_r(struct s_pwd * pwd, unsigned int bs) +{ + unsigned long long i; + unsigned int k; + unsigned long lvl; + unsigned char curchar; + unsigned int x; + + k=0; + x=pwd->len; + i = nbparts[pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len]; + pwd->len++; + lvl = pwd->level; + if(bs) + { + while( (curchar=charsorted[ pwd->password[pwd->len-2]*256 + k ]) != pwd->password[pwd->len-1] ) + { + i -= nbparts[ curchar + pwd->len*256 + (pwd->level + proba2[ pwd->password[pwd->len-2]*256 + curchar ])*256*gmax_len ]; + k++; + } + pwd->level += proba2[ pwd->password[pwd->len-2]*256 + pwd->password[pwd->len-1] ]; + if(pwd->password[pwd->len]!=0) + show_pwd_r(pwd, 1); + i -= nbparts[ pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len ]; + printf("%s\n", pwd->password); + gidx++; + k++; + } + pwd->password[pwd->len] = 0; + while(i>1) + { + pwd->password[pwd->len-1] = charsorted[ pwd->password[pwd->len-2]*256 + k ]; + pwd->level = lvl + proba2[ pwd->password[pwd->len-2]*256 + pwd->password[pwd->len-1] ]; + i -= nbparts[ pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len ]; + if(pwd->len<=gmax_len) + { + show_pwd_r(pwd, 0); + } + printf("%s\n", pwd->password); + gidx++; + k++; + if(gidx>gend) + return; + } + pwd->len--; + pwd->password[pwd->len] = 0; + pwd->level = lvl; +} + +static void show_pwd(unsigned long long start, unsigned long long end, unsigned int max_level, unsigned int max_len) +{ + struct s_pwd pwd; + unsigned int i; + unsigned int bs; + + gmax_level = max_level; + gmax_len = max_len; + gend = end; + gidx = start; + i=0; + bs = 0; + if(start>0) + bs = 1; + if(bs) + { + print_pwd(start, &pwd, max_level, max_len); + while(charsorted[i] != pwd.password[0]) + i++; + pwd.len = 1; + pwd.level = proba1[pwd.password[0]]; + show_pwd_r(&pwd, 1); + printf("%s\n", pwd.password); + i++; + } + while(proba1[charsorted[i]]<=max_level) + { + if(gidx>gend) + return; + pwd.len = 1; + pwd.password[0] = charsorted[i]; + pwd.level = proba1[pwd.password[0]]; + pwd.password[1] = 0; + show_pwd_rnbs(&pwd); + printf("%s\n", pwd.password); + gidx++; + i++; + } +} + +#if 0 +static void stupidsort(unsigned char * result, unsigned int * source, unsigned int size) +{ + unsigned char pivot; + unsigned char more[256]; + unsigned char less[256]; + unsigned char piv[256]; + unsigned int i,m,l,p; + + if(size<=1) + return; + i=0; + while( (source[result[i]]==1000) && (i6)) + { + printf("Usage: %s statfile max_lvl [max_len] [start] [end]\n", argv[0]); + return -1; + } + + max_lvl = atoi(argv[2]); + + if(argc>3) + max_len = atoi(argv[3]); + if(argc>4) + start = atoll(argv[4]); + if(argc>5) + end = atoll(argv[5]); + + init_probatables(argv[1]); + + if(max_len==0) + { + for(max_len=6;max_len<20;max_len++) + { + nbparts = mem_alloc(256*(max_lvl+1)*sizeof(long long)*max_len); + printf("len=%u (%lu KB for nbparts) ", max_len, 256UL*(max_lvl+1)*max_len*sizeof(long long)/1024); + memset(nbparts, 0, 256*(max_lvl+1)*max_len*sizeof(long long)); + nb_parts(0, 0, 0, max_lvl, max_len); + if(nbparts[0] > 1000000000) + printf("%lld G possible passwords (%lld)\n", nbparts[0] / 1000000000, nbparts[0]); + else if(nbparts[0] > 10000000) + printf("%lld M possible passwords (%lld)\n", nbparts[0] / 1000000, nbparts[0]); + else if(nbparts[0] > 10000) + printf("%lld K possible passwords (%lld)\n", nbparts[0] / 1000, nbparts[0]); + else + printf("%lld possible passwords\n", nbparts[0] ); + free(nbparts); + } + goto fin; + } + + if(max_lvl==0) + { + for(max_lvl=100;max_lvl<350;max_lvl++) + { + nbparts = mem_alloc(256*(max_lvl+1)*sizeof(long long)*max_len); + printf("lvl=%u (%lu KB for nbparts) ", max_lvl, 256UL*(max_lvl+1)*max_len*sizeof(long long)/1024); + memset(nbparts, 0, 256*(max_lvl+1)*max_len*sizeof(long long)); + nb_parts(0, 0, 0, max_lvl, max_len); + if(nbparts[0] > 1000000000) + printf("%lld G possible passwords (%lld)\n", nbparts[0] / 1000000000, nbparts[0]); + else if(nbparts[0] > 10000000) + printf("%lld M possible passwords (%lld)\n", nbparts[0] / 1000000, nbparts[0]); + else if(nbparts[0] > 10000) + printf("%lld K possible passwords (%lld)\n", nbparts[0] / 1000, nbparts[0]); + else + printf("%lld possible passwords\n", nbparts[0] ); + free(nbparts); + } + goto fin; + } + + nbparts = mem_alloc(256*(max_lvl+1)*sizeof(long long)*max_len); + fprintf(stderr, "allocated %lu KB for nbparts\n", 256UL*(max_lvl+1)*max_len*sizeof(long long)/1024); + memset(nbparts, 0, 256*(max_lvl+1)*max_len*sizeof(long long)); + + nb_parts(0, 0, 0, max_lvl, max_len); + if(nbparts[0] > 1000000000) + fprintf(stderr, "%lld G possible passwords (%lld)\n", nbparts[0] / 1000000000, nbparts[0]); + else if(nbparts[0] > 10000000) + fprintf(stderr, "%lld M possible passwords (%lld)\n", nbparts[0] / 1000000, nbparts[0]); + else if(nbparts[0] > 10000) + fprintf(stderr, "%lld K possible passwords (%lld)\n", nbparts[0] / 1000, nbparts[0]); + else + fprintf(stderr, "%lld possible passwords\n", nbparts[0] ); + + if(end==0) + end = nbparts[0]; + + pwd.level = 0; + pwd.len = 0; + pwd.index = 0; + memset(pwd.password, 0, max_len+1); + + print_pwd(start, &pwd, max_lvl, max_len); + print_pwd(start, &pwd2, max_lvl, max_len); + + fprintf(stderr, "starting with %s (%lld to %lld, %f%% of the scope)\n", pwd.password, start, end, 100*((float) end-start)/((float) nbparts[0]) ); + + show_pwd(start, end, max_lvl, max_len); + + free(nbparts); +fin: + free(proba1); + free(proba2); + free(first); + return 0; +} diff -urpN john-1.7.3.4.orig/src/hmacMD5_fmt.c john-1.7.3.4/src/hmacMD5_fmt.c --- john-1.7.3.4.orig/src/hmacMD5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/hmacMD5_fmt.c 2009-10-29 02:56:31 +0000 @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2004 bartavelle + * bartavelle at bandecon.com + * + * Simple MD5 hashes cracker + * It uses the Solar Designer's md5 implementation + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "md5.h" + +#define FORMAT_LABEL "hmac-md5" +#define FORMAT_NAME "HMAC MD5" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "hmac-md5 MMX" +#else +#define ALGORITHM_NAME "hmac-md5 SSE2" +#endif +#else +#define ALGORITHM_NAME "hmac-md5" +#endif + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 64 +#define CIPHERTEXT_LENGTH 128 + +#define BINARY_SIZE 16 +#define SALT_SIZE 64 + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + ((i)&3) ) +#else +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +static struct fmt_tests hmacmd5_tests[] = { + {"what do ya want for nothing?#750c783e6ab0b503eaa86e310a5db738", "Jefe"}, + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define crypt_key hmacmd5_crypt_key +#define opad hmacmd5_opad +#define ipad hmacmd5_ipad +#define cursalt hmacmd5_cursalt +#define dump hmacmd5_dump +char crypt_key[64*MMX_COEF] __attribute__ ((aligned(16))); +unsigned char opad[PLAINTEXT_LENGTH*MMX_COEF] __attribute__ ((aligned(16))); +unsigned char ipad[PLAINTEXT_LENGTH*MMX_COEF] __attribute__ ((aligned(16))); +unsigned char cursalt[SALT_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +unsigned char dump[BINARY_SIZE*MMX_COEF] __attribute__((aligned(16))); +static unsigned long total_len; +#else +static char crypt_key[BINARY_SIZE+1]; +static MD5_CTX ctx; +static unsigned char opad[PLAINTEXT_LENGTH]; +static unsigned char ipad[PLAINTEXT_LENGTH]; +static unsigned char cursalt[SALT_SIZE]; +#endif +static unsigned char out[PLAINTEXT_LENGTH + 1]; + +static void hmacmd5_init(void) +{ +#ifdef MMX_COEF + memset(crypt_key, 0, sizeof(crypt_key)); + crypt_key[GETPOS(BINARY_SIZE,0)] = 0x80; + crypt_key[GETPOS(BINARY_SIZE,1)] = 0x80; +#if (MMX_COEF == 4) + crypt_key[GETPOS(BINARY_SIZE,2)] = 0x80; + crypt_key[GETPOS(BINARY_SIZE,3)] = 0x80; +#endif +#endif +} + +static int valid(char *ciphertext) +{ + int pos, i; + + for(i=0;(iPLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + +#ifdef MMX_COEF + if(index==0) + { + memset(ipad, 0x36, sizeof(ipad)); + memset(opad, 0x5C, sizeof(opad)); + } + + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } +#else + while(i + +#include "md5.h" +#include "hmacmd5.h" + +#define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) + +/*********************************************************************** + the rfc 2104 version of hmac_md5 initialisation. +***********************************************************************/ + +void hmac_md5_init_rfc2104(const unsigned char *key, int key_len, HMACMD5Context *ctx) +{ + int i; + unsigned char tk[16]; + + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) { + MD5_CTX tctx; + + MD5_Init(&tctx); + MD5_Update(&tctx, (void *)key, key_len); + MD5_Final(tk, &tctx); + + key = tk; + key_len = 16; + } + + /* start out by storing key in pads */ + ZERO_STRUCT(ctx->k_ipad); + ZERO_STRUCT(ctx->k_opad); + memcpy( ctx->k_ipad, key, key_len); + memcpy( ctx->k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i<64; i++) { + ctx->k_ipad[i] ^= 0x36; + ctx->k_opad[i] ^= 0x5c; + } + + MD5_Init(&ctx->ctx); + MD5_Update(&ctx->ctx, ctx->k_ipad, 64); +} + +/*********************************************************************** + the microsoft version of hmac_md5 initialisation. +***********************************************************************/ + +void hmac_md5_init_limK_to_64(const unsigned char* key, int key_len, + HMACMD5Context *ctx) +{ + int i; + + /* if key is longer than 64 bytes truncate it */ + if (key_len > 64) { + key_len = 64; + } + + /* start out by storing key in pads */ + ZERO_STRUCT(ctx->k_ipad); + ZERO_STRUCT(ctx->k_opad); + memcpy( ctx->k_ipad, key, key_len); + memcpy( ctx->k_opad, key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i<64; i++) { + ctx->k_ipad[i] ^= 0x36; + ctx->k_opad[i] ^= 0x5c; + } + + MD5_Init(&ctx->ctx); + MD5_Update(&ctx->ctx, ctx->k_ipad, 64); +} + +/*********************************************************************** + update hmac_md5 "inner" buffer +***********************************************************************/ + +void hmac_md5_update(const unsigned char *text, int text_len, HMACMD5Context *ctx) +{ + MD5_Update(&ctx->ctx, (void *)text, text_len); /* then text of datagram */ +} + +/*********************************************************************** + finish off hmac_md5 "inner" buffer and generate outer one. +***********************************************************************/ +void hmac_md5_final(unsigned char *digest, HMACMD5Context *ctx) + +{ + MD5_CTX ctx_o; + + MD5_Final(digest, &ctx->ctx); + + MD5_Init(&ctx_o); + MD5_Update(&ctx_o, ctx->k_opad, 64); + MD5_Update(&ctx_o, digest, 16); + MD5_Final(digest, &ctx_o); +} + +/*********************************************************** + single function to calculate an HMAC MD5 digest from data. + use the microsoft hmacmd5 init method because the key is 16 bytes. +************************************************************/ + +void hmac_md5( unsigned char key[16], unsigned char *data, int data_len, unsigned char *digest) +{ + HMACMD5Context ctx; + hmac_md5_init_limK_to_64(key, 16, &ctx); + if (data_len != 0) + { + hmac_md5_update(data, data_len, &ctx); + } + hmac_md5_final(digest, &ctx); +} + diff -urpN john-1.7.3.4.orig/src/hmacmd5.h john-1.7.3.4/src/hmacmd5.h --- john-1.7.3.4.orig/src/hmacmd5.h 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/hmacmd5.h 2008-03-20 20:47:54 +0000 @@ -0,0 +1,30 @@ +/* + Unix SMB/CIFS implementation. + Interface header: Scheduler service + Copyright (C) Luke Kenneth Casson Leighton 1996-1999 + Copyright (C) Andrew Tridgell 1992-1999 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _HMAC_MD5_H + +typedef struct { + MD5_CTX ctx; + unsigned char k_ipad[65]; + unsigned char k_opad[65]; +} HMACMD5Context; + +#endif /* _HMAC_MD5_H */ diff -urpN john-1.7.3.4.orig/src/inc.c john-1.7.3.4/src/inc.c --- john-1.7.3.4.orig/src/inc.c 2008-06-28 06:41:41 +0000 +++ john-1.7.3.4/src/inc.c 2008-08-24 04:59:02 +0000 @@ -23,6 +23,8 @@ #include "cracker.h" extern struct fmt_main fmt_LM; +extern struct fmt_main fmt_NETLM; +extern struct fmt_main fmt_NETHALFLM; typedef char (*char2_table) [CHARSET_SIZE + 1][CHARSET_SIZE + 1]; @@ -377,6 +379,10 @@ void do_incremental_crack(struct db_main if (!mode) { if (db->format == &fmt_LM) mode = "LanMan"; + else if (db->format == &fmt_NETLM) + mode = "LanMan"; + else if (db->format == &fmt_NETHALFLM) + mode = "LanMan"; else mode = "All"; } diff -urpN john-1.7.3.4.orig/src/john.c john-1.7.3.4/src/john.c --- john-1.7.3.4.orig/src/john.c 2009-09-09 04:38:56 +0000 +++ john-1.7.3.4/src/john.c 2010-02-14 03:22:26 +0000 @@ -29,6 +29,7 @@ #include "single.h" #include "wordlist.h" #include "inc.h" +#include "mkv.h" #include "external.h" #include "batch.h" @@ -38,9 +39,45 @@ extern int CPU_detect(void); extern struct fmt_main fmt_DES, fmt_BSDI, fmt_MD5, fmt_BF; extern struct fmt_main fmt_AFS, fmt_LM; +extern struct fmt_main fmt_NT, fmt_XSHA; +extern struct fmt_main fmt_PO; +extern struct fmt_main fmt_rawMD5go; +extern struct fmt_main fmt_hmacMD5; +extern struct fmt_main fmt_IPB2; +extern struct fmt_main fmt_MD5_apache; +extern struct fmt_main fmt_BFEgg; +extern struct fmt_main fmt_KRB5; +extern struct fmt_main fmt_oracle; +extern struct fmt_main fmt_oracle11; +extern struct fmt_main fmt_MYSQL; +extern struct fmt_main fmt_mysqlSHA1; +extern struct fmt_main fmt_NSLDAP; +extern struct fmt_main fmt_NSLDAPS; +extern struct fmt_main fmt_OPENLDAPS; +extern struct fmt_main fmt_mscash; +extern struct fmt_main fmt_rawSHA1; +extern struct fmt_main fmt_XSHA; +extern struct fmt_main fmt_lotus5; +extern struct fmt_main fmt_DOMINOSEC; +extern struct fmt_main fmt_NETLM; +extern struct fmt_main fmt_NETNTLM; +extern struct fmt_main fmt_NETLMv2; +extern struct fmt_main fmt_NETNTLMv2; +extern struct fmt_main fmt_NETHALFLM; +extern struct fmt_main fmt_mssql; +extern struct fmt_main fmt_mssql05; +extern struct fmt_main fmt_EPI; +extern struct fmt_main fmt_PHPS; +extern struct fmt_main fmt_MYSQL_fast; +extern struct fmt_main fmt_pixMD5; +extern struct fmt_main fmt_sapG; +extern struct fmt_main fmt_sapB; +extern struct fmt_main fmt_NS; +extern struct fmt_main fmt_HDAA; extern int unshadow(int argc, char **argv); extern int unafs(int argc, char **argv); +extern int undrop(int argc, char **argv); extern int unique(int argc, char **argv); static struct db_main database; @@ -66,6 +103,41 @@ static void john_register_all(void) john_register_one(&fmt_BF); john_register_one(&fmt_AFS); john_register_one(&fmt_LM); + john_register_one(&fmt_NT); + john_register_one(&fmt_XSHA); + john_register_one(&fmt_mscash); + john_register_one(&fmt_MD5_apache); + john_register_one(&fmt_hmacMD5); + john_register_one(&fmt_PO); + john_register_one(&fmt_rawMD5go); + john_register_one(&fmt_IPB2); + john_register_one(&fmt_rawSHA1); + john_register_one(&fmt_KRB5); + john_register_one(&fmt_NSLDAP); + john_register_one(&fmt_NSLDAPS); + john_register_one(&fmt_OPENLDAPS); + john_register_one(&fmt_BFEgg); + john_register_one(&fmt_oracle); + john_register_one(&fmt_oracle11); + john_register_one(&fmt_MYSQL); + john_register_one(&fmt_mysqlSHA1); + john_register_one(&fmt_lotus5); + john_register_one(&fmt_DOMINOSEC); + john_register_one(&fmt_NETLM); + john_register_one(&fmt_NETNTLM); + john_register_one(&fmt_NETLMv2); + john_register_one(&fmt_NETNTLMv2); + john_register_one(&fmt_NETHALFLM); + john_register_one(&fmt_mssql); + john_register_one(&fmt_mssql05); + john_register_one(&fmt_EPI); + john_register_one(&fmt_PHPS); + john_register_one(&fmt_MYSQL_fast); + john_register_one(&fmt_pixMD5); + john_register_one(&fmt_sapG); + john_register_one(&fmt_sapB); + john_register_one(&fmt_NS); + john_register_one(&fmt_HDAA); if (!fmt_list) { fprintf(stderr, "Unknown ciphertext format name requested\n"); @@ -80,7 +152,7 @@ static void john_log_format(void) log_event("- Hash type: %.100s (lengths up to %d%s)", database.format->params.format_name, database.format->params.plaintext_length, - database.format->methods.split != fmt_default_split ? + (database.format == &fmt_DES || database.format == &fmt_LM) ? ", longer passwords split" : ""); log_event("- Algorithm: %.100s", @@ -292,6 +364,9 @@ static void john_run(void) if (options.flags & FLG_INC_CHK) do_incremental_crack(&database, options.charset); else + if (options.flags & FLG_MKV_CHK) + do_markov_crack(&database, options.mkv_level, options.mkv_start, options.mkv_end, options.mkv_maxlen); + else if (options.flags & FLG_EXTERNAL_CHK) do_external_crack(&database); else @@ -354,6 +429,9 @@ int main(int argc, char **argv) if (!strcmp(name, "unique")) return unique(argc, argv); + if (!strcmp(name, "undrop")) + return undrop(argc, argv); + john_init(name, argc, argv); john_run(); john_done(); diff -urpN john-1.7.3.4.orig/src/loader.c john-1.7.3.4/src/loader.c --- john-1.7.3.4.orig/src/loader.c 2005-11-08 13:13:05 +0000 +++ john-1.7.3.4/src/loader.c 2010-02-14 03:47:17 +0000 @@ -1,6 +1,8 @@ /* * This file is part of John the Ripper password cracker, - * Copyright (c) 1996-2000,2003,2005 by Solar Designer + * Copyright (c) 1996-2000,2003,2005,2008 by Solar Designer + * + * ...with heavy changes in the jumbo patch, by various authors */ #include @@ -18,6 +20,9 @@ #include "signals.h" #include "formats.h" #include "loader.h" +#include "options.h" + +extern struct fmt_main fmt_NT; /* * Flags for read_file(). @@ -183,7 +188,7 @@ static int ldr_check_shells(struct list_ static int ldr_split_line(char **login, char **ciphertext, char **gecos, char **home, char *source, struct fmt_main **format, - struct db_options *options, char *line) + struct db_options *db_options, char *line) { char *uid = NULL, *gid = NULL, *shell = NULL; char *tmp; @@ -198,19 +203,109 @@ static int ldr_split_line(char **login, uid = ldr_get_field(&line); +/* Assume that we have a PWDUMP output file if "uid" is 32 characters long + * (actually LM hash). */ if (strlen(uid) == 32) { tmp = *ciphertext; *ciphertext = uid; - uid = tmp; + uid = gid = tmp; if (!strncmp(*ciphertext, "NO PASSWORD", 11)) *ciphertext = ""; - if (source) sprintf(source, "%s:%s", uid, line); + tmp = ldr_get_field(&line); /* NTLM hash */ + if (fmt_list == &fmt_NT) { + if (!strncmp(tmp, "NO PASSWORD", 11)) + tmp = ""; + else if (strlen(tmp) == 32) { + tmp -= 4; /* It's OK to overwrite LM hash */ + memcpy(tmp, "$NT$", 4); + } else + return 0; + *ciphertext = tmp; + } + + if (source) { + if (line) + sprintf(source, "%s:%s", uid, line); + else + sprintf(source, "%s\n", uid); + } + } + else if (options.format && (strncmp(options.format, "netlmv2", 7)==0)) { + char *srv_challenge = ldr_get_field(&line); + char *netlmv2 = ldr_get_field(&line); + char *cli_challenge = ldr_get_field(&line); + char *identity = NULL; + int i; + + identity = (char *) mem_alloc(strlen(*login) + strlen(uid) + 1); + strcpy(identity, *login); + strcat(identity, uid); + + /* Upper-Case Username and Domain */ + for(i=0; i= 'a') && (identity[i] <= 'z')) identity[i] ^= 0x20; + + tmp = (char *) mem_alloc_tiny(9 + strlen(identity) + 1 + strlen(srv_challenge) + 1 + strlen(netlmv2) + 1 + strlen(cli_challenge) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$NETLMv2$%s$%s$%s$%s", identity, srv_challenge, netlmv2, cli_challenge); + *ciphertext = tmp; + + MEM_FREE(identity); + } + else if (options.format && (strncmp(options.format, "netntlmv2", 9)==0)) { + char *srv_challenge = ldr_get_field(&line); + char *netntlmv2 = ldr_get_field(&line); + char *cli_challenge = ldr_get_field(&line); + char *identity = NULL; + int i; + + identity = (char *) mem_alloc(strlen(*login) + strlen(uid) + 1); + strcpy(identity, *login); + strcat(identity, uid); + + /* Upper-Case Username - Not Domain */ + for(i=0; i= 'a') && (identity[i] <= 'z')) identity[i] ^= 0x20; + + tmp = (char *) mem_alloc_tiny(9 + strlen(identity) + 1 + strlen(srv_challenge) + 1 + strlen(netntlmv2) + 1 + strlen(cli_challenge) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$NETNTLMv2$%s$%s$%s$%s", identity, srv_challenge, netntlmv2, cli_challenge); + *ciphertext = tmp; + + MEM_FREE(identity); + } + else if (options.format && ((strncmp(options.format, "netlm", 5)==0) || + (strncmp(options.format, "netntlm", 7)==0))) { + char *netlm = ldr_get_field(&line); + char *netntlm = ldr_get_field(&line); + char *challenge = ldr_get_field(&line); + + if (strncmp(options.format, "netlm", 5)==0) { + tmp = (char *) mem_alloc_tiny(7 + strlen(challenge) + 1 + strlen(netlm) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$NETLM$%s$%s", challenge, netlm); + *ciphertext = tmp; + } + else { + tmp = (char *) mem_alloc_tiny(9 + strlen(challenge) + 1 + strlen(netntlm) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$NETNTLM$%s$%s", challenge, netntlm); + *ciphertext = tmp; + } + } + else if (options.format && ((strncmp(options.format, "nethalflm", 9)==0))) { + char *nethalflm = ldr_get_field(&line); + /*char *netntlm = ldr_get_field(&line);*/ + char *challenge = ldr_get_field(&line); + + if (strncmp(options.format, "nethalflm", 9)==0) { + tmp = (char *) mem_alloc_tiny(12 + strlen(challenge) + strlen(nethalflm) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$nethalflm$%s$%s", challenge, nethalflm); + *ciphertext = tmp; + } } - if (options->flags & DB_WORDS || options->shells->head) { - gid = ldr_get_field(&line); + if ((db_options->flags & DB_WORDS) || db_options->shells->head) { + if (!gid) + gid = ldr_get_field(&line); do { *gecos = ldr_get_field(&line); *home = ldr_get_field(&line); @@ -218,13 +313,13 @@ static int ldr_split_line(char **login, } while (!**gecos && !strcmp(*home, "0") && !strcmp(shell, "0")); } else - if (options->groups->head) { + if (db_options->groups->head && !gid) { gid = ldr_get_field(&line); } - if (ldr_check_list(options->users, *login, uid)) return 0; - if (ldr_check_list(options->groups, gid, gid)) return 0; - if (ldr_check_shells(options->shells, shell)) return 0; + if (ldr_check_list(db_options->users, *login, uid)) return 0; + if (ldr_check_list(db_options->groups, gid, gid)) return 0; + if (ldr_check_shells(db_options->shells, shell)) return 0; if (*format) return (*format)->methods.valid(*ciphertext); @@ -287,6 +382,9 @@ static void ldr_load_pw_line(struct db_m struct list_main *words; size_t pw_size, salt_size; + extern struct fmt_main fmt_mscash; + extern struct fmt_main fmt_oracle; + count = ldr_split_line(&login, &ciphertext, &gecos, &home, NULL, &db->format, db->options, line); if (count <= 0) return; @@ -311,7 +409,19 @@ static void ldr_load_pw_line(struct db_m } for (index = 0; index < count; index++) { - piece = format->methods.split(ciphertext, index); + if (db->format == &fmt_mscash) + { + piece = (char *) mem_alloc(strlen(login) + strlen(ciphertext) + 4); + sprintf(piece, "M$%s#%s", login, ciphertext); + } + else + if (db->format == &fmt_oracle) + { + piece = (char *) mem_alloc_tiny(strlen(login) + strlen(ciphertext) + 4, MEM_ALIGN_NONE); + sprintf(piece, "O$%s#%s", login, ciphertext); + } + else + piece = format->methods.split(ciphertext, index); binary = format->methods.binary(piece); pw_hash = LDR_HASH_FUNC(binary); @@ -644,16 +754,28 @@ static void ldr_show_pw_line(struct db_m int hash; struct db_cracked *current; + extern struct fmt_main fmt_mscash; + format = NULL; count = ldr_split_line(&login, &ciphertext, &gecos, &home, source, &format, db->options, line); if (!count) return; +/* If just one format was forced on the command line, insist on it */ + if (!fmt_list->next && !format) return; + show = !(db->options->flags & DB_PLAINTEXTS); if (format) { split = format->methods.split; unify = format->params.flags & FMT_SPLIT_UNIFIES_CASE; + if(format == &fmt_mscash) + { + char * ciphertext2 = (char *) mem_alloc(strlen(login) + strlen(ciphertext) + 4); + sprintf(ciphertext2, "M$%s#%s", login, ciphertext); + ciphertext = ciphertext2; + } + } else { split = fmt_default_split; count = 1; diff -urpN john-1.7.3.4.orig/src/lotus5_fmt.c john-1.7.3.4/src/lotus5_fmt.c --- john-1.7.3.4.orig/src/lotus5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/lotus5_fmt.c 2010-02-14 03:22:26 +0000 @@ -0,0 +1,249 @@ +//original work by Jeff Fay +//some optimisations by bartavelle at bandecon.com + +#include +#include +#include "misc.h" +#include "formats.h" +#include "common.h" + +/*preprocessor constants that John The Ripper likes*/ +#define FORMAT_LABEL "lotus5" +#define FORMAT_NAME "Lotus5" +#define ALGORITHM_NAME "Lotus v5 Proprietary" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 +#define PLAINTEXT_LENGTH 16 +#define CIPHERTEXT_LENGTH 32 +#define BINARY_SIZE 16 +#define SALT_SIZE 0 +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +/*A struct used for JTR's benchmarks*/ +static struct fmt_tests tests[] = { + {"06E0A50B579AD2CD5FFDC48564627EE7", "secret"}, + {"355E98E7C7B59BD810ED845AD0FD2FC4", "password"}, + {"CD2D90E8E00D8A2A63A81F531EA8A9A3", "lotus"}, + {"69D90B46B1AC0912E5CCF858094BBBFC", "dirtydog"}, + {NULL} +}; + +static const char lotus_magic_table[256] = { + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, + 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, + 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, + 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, + 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, + 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, + 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, + 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, + 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, + 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, + 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, + 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, + 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, + 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, + 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, + 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, + 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab, +}; + +/*Some more JTR variables*/ +static char crypt_key[BINARY_SIZE+1]; +static char saved_key[PLAINTEXT_LENGTH + 1]; + +/*Utility function to convert hex to bin */ +static void * binary (char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + for (i = 0; i < BINARY_SIZE; i++) + realcipher[i] = atoi16[ARCH_INDEX(ciphertext[i*2])]*16 + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + return ((void *) realcipher); +} + +/*Another function required by JTR: decides whether we have a valid + * ciphertext */ +static int +valid (char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + for (i = 0; i < CIPHERTEXT_LENGTH; i++) + if (!(((ciphertext[i] >= '0') && (ciphertext[i] <= '9')) + || ((ciphertext[i] >= 'a') && (ciphertext[i] <= 'f')) + || ((ciphertext[i] >= 'A') && (ciphertext[i] <= 'F')))) + { + return 0; + } + return 1; +} + +/*sets the value of saved_key so we can play with it*/ +static void set_key (char *key, int index) +{ + strnzcpy (saved_key, key, PLAINTEXT_LENGTH + 1); +} + +/*retrieves the saved key; used by JTR*/ +static char * get_key (int index) +{ + return saved_key; +} +static int +cmp_all (void *binary, int index) +{ + int i = 0; + while(i 0; i--) + { + temp = lotus_matrix; + for (j = 48; j > 0; j--) + { + *temp = *temp ^ lotus_magic_table[ARCH_INDEX((j + prevbyte) & 0xff)]; + prevbyte = *temp; + temp++; + } + } +} + + +/*the last public function; generates ciphertext*/ +static void crypt_all (int count) +{ + unsigned char password[PLAINTEXT_LENGTH]; + unsigned char lotus_matrix[64], *lotus_matrix1, *lotus_matrix2, *lotus_matrix3, *lotus_matrix4; + int i; + int password_length; + + password_length = strlen (saved_key); + memset (password, (PLAINTEXT_LENGTH - password_length), PLAINTEXT_LENGTH); + lotus_matrix1 = lotus_matrix; + lotus_matrix2 = lotus_matrix1 + 16; + lotus_matrix3 = lotus_matrix2 + 16; + lotus_matrix4 = lotus_matrix3 + 16; + memcpy (password, saved_key, password_length); + + memset (lotus_matrix1, 0, 16); + memcpy (lotus_matrix2, password, 16); + memcpy (lotus_matrix3, password, 16); + lotus_transform_password (lotus_matrix2, lotus_matrix4); + lotus_mix (lotus_matrix); + memcpy (lotus_matrix2, lotus_matrix4, 16); + for (i = 0; i < 16; i++) + { + lotus_matrix3[i] = lotus_matrix1[i] ^ lotus_matrix2[i]; + } + lotus_mix (lotus_matrix); + memcpy (crypt_key, lotus_matrix1, BINARY_SIZE); +} + +static int get_hash1(int index) { return (((unsigned int *)crypt_key)[0] & 0xf); } +static int get_hash2(int index) { return (((unsigned int *)crypt_key)[0] & 0xff); } +static int get_hash3(int index) { return (((unsigned int *)crypt_key)[0] & 0xfff); } +static int binary_hash1(void * binary) { return (((unsigned int *)binary)[0] & 0xf); } +static int binary_hash2(void * binary) { return (((unsigned int *)binary)[0] & 0xff); } +static int binary_hash3(void * binary) { return (((unsigned int *)binary)[0] & 0xfff); } + +/* C's version of a class specifier */ +struct fmt_main fmt_lotus5 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + fmt_default_init, + valid, + fmt_default_split, + binary, + fmt_default_salt, + { + binary_hash1, + binary_hash2, + binary_hash3 + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + get_hash1, + get_hash2, + get_hash3 + }, + cmp_all, + cmp_all, + cmp_exact} +}; diff -urpN john-1.7.3.4.orig/src/md4.c john-1.7.3.4/src/md4.c --- john-1.7.3.4.orig/src/md4.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/md4.c 2008-08-24 06:41:27 +0000 @@ -0,0 +1,256 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, + * Inc. MD4 Message-Digest Algorithm (RFC 1320). + * + * Written by Solar Designer in 2001, and placed + * in the public domain. There's absolutely no warranty. + * + * This differs from Colin Plumb's older public domain implementation in + * that no 32-bit integer data type is required, there's no compile-time + * endianness configuration, and the function prototypes match OpenSSL's. + * The primary goals are portability and ease of use. + * + * This implementation is meant to be fast, but not as fast as possible. + * Some known optimizations are not included to reduce source code size + * and avoid compile-time configuration. + */ + +#ifndef HAVE_OPENSSL + +#include + +#include "md4.h" + +/* + * The basic MD4 functions. + * + * F and G are optimized compared to their RFC 1320 definitions, with the + * optimization for F borrowed from Colin Plumb's MD5 implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* + * The MD4 transformation for all three rounds. + */ +#define STEP(f, a, b, c, d, x, s) \ + (a) += f((b), (c), (d)) + (x); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD4_u32plus *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) +#else +#define SET(n) \ + (ctx->block[(n)] = \ + (MD4_u32plus)ptr[(n) * 4] | \ + ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD4_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There are no alignment requirements. + */ +static void *body(MD4_CTX *ctx, void *data, unsigned long size) +{ + unsigned char *ptr; + MD4_u32plus a, b, c, d; + MD4_u32plus saved_a, saved_b, saved_c, saved_d; + + ptr = data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 3) + STEP(F, d, a, b, c, SET(1), 7) + STEP(F, c, d, a, b, SET(2), 11) + STEP(F, b, c, d, a, SET(3), 19) + STEP(F, a, b, c, d, SET(4), 3) + STEP(F, d, a, b, c, SET(5), 7) + STEP(F, c, d, a, b, SET(6), 11) + STEP(F, b, c, d, a, SET(7), 19) + STEP(F, a, b, c, d, SET(8), 3) + STEP(F, d, a, b, c, SET(9), 7) + STEP(F, c, d, a, b, SET(10), 11) + STEP(F, b, c, d, a, SET(11), 19) + STEP(F, a, b, c, d, SET(12), 3) + STEP(F, d, a, b, c, SET(13), 7) + STEP(F, c, d, a, b, SET(14), 11) + STEP(F, b, c, d, a, SET(15), 19) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13) + STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3) + STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5) + STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9) + STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15) + STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15) + STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15) + STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3) + STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9) + STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11) + STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; +} + +void MD4_Init(MD4_CTX *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; +} + +void MD4_Update(MD4_CTX *ctx, void *data, unsigned long size) +{ + MD4_u32plus saved_lo; + unsigned long used, free; + + saved_lo = ctx->lo; + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + ctx->hi++; + ctx->hi += size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (unsigned char *)data + free; + size -= free; + body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +void MD4_Final(unsigned char *result, MD4_CTX *ctx) +{ + unsigned long used, free; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + memset(&ctx->buffer[used], 0, free); + body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + memset(&ctx->buffer[used], 0, free - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = ctx->lo; + ctx->buffer[57] = ctx->lo >> 8; + ctx->buffer[58] = ctx->lo >> 16; + ctx->buffer[59] = ctx->lo >> 24; + ctx->buffer[60] = ctx->hi; + ctx->buffer[61] = ctx->hi >> 8; + ctx->buffer[62] = ctx->hi >> 16; + ctx->buffer[63] = ctx->hi >> 24; + + body(ctx, ctx->buffer, 64); + + result[0] = ctx->a; + result[1] = ctx->a >> 8; + result[2] = ctx->a >> 16; + result[3] = ctx->a >> 24; + result[4] = ctx->b; + result[5] = ctx->b >> 8; + result[6] = ctx->b >> 16; + result[7] = ctx->b >> 24; + result[8] = ctx->c; + result[9] = ctx->c >> 8; + result[10] = ctx->c >> 16; + result[11] = ctx->c >> 24; + result[12] = ctx->d; + result[13] = ctx->d >> 8; + result[14] = ctx->d >> 16; + result[15] = ctx->d >> 24; + +#if 0 + memset(ctx, 0, sizeof(*ctx)); +#endif +} + +#endif diff -urpN john-1.7.3.4.orig/src/md4.h john-1.7.3.4/src/md4.h --- john-1.7.3.4.orig/src/md4.h 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/md4.h 2008-02-20 14:19:36 +0000 @@ -0,0 +1,30 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, + * Inc. MD4 Message-Digest Algorithm (RFC 1320). + * + * Written by Solar Designer in 2001, and placed + * in the public domain. There's absolutely no warranty. + * + * See md4.c for more information. + */ + +#ifdef HAVE_OPENSSL +#include +#elif !defined(_MD4_H) +#define _MD4_H + +/* Any 32-bit or wider unsigned integer data type will do */ +typedef unsigned int MD4_u32plus; + +typedef struct { + MD4_u32plus lo, hi; + MD4_u32plus a, b, c, d; + unsigned char buffer[64]; + MD4_u32plus block[16]; +} MD4_CTX; + +extern void MD4_Init(MD4_CTX *ctx); +extern void MD4_Update(MD4_CTX *ctx, void *data, unsigned long size); +extern void MD4_Final(unsigned char *result, MD4_CTX *ctx); + +#endif diff -urpN john-1.7.3.4.orig/src/md5-mmx.S john-1.7.3.4/src/md5-mmx.S --- john-1.7.3.4.orig/src/md5-mmx.S 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/md5-mmx.S 2009-09-20 22:34:23 +0000 @@ -0,0 +1,311 @@ +#include "arch.h" + +// extern int mdfourmmx(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3))); + +#ifdef UNDERSCORES +#define mdfivemmx _mdfivemmx +#define mdfivemmx_noinit_sizeupdate _mdfivemmx_noinit_sizeupdate +#define mdfivemmx_noinit_uniformsizeupdate _mdfivemmx_noinit_uniformsizeupdate +#define mdfivemmx_nosizeupdate _mdfivemmx_nosizeupdate +#endif +.globl mdfivemmx +.globl mdfivemmx_noinit_sizeupdate +.globl mdfivemmx_noinit_uniformsizeupdate +.globl mdfivemmx_nosizeupdate + +.data +//.align(16) +.align(2*MMX_COEF) +#if (MMX_COEF == 2) +const_init_a: ; .long 0x67452301 ; .long 0x67452301 +const_init_b: ; .long 0xefcdab89 ; .long 0xefcdab89 +const_init_c: ; .long 0x98badcfe ; .long 0x98badcfe +const_init_d: ; .long 0x10325476 ; .long 0x10325476 +storea: ; .long 0 ; .long 0 +storeb: ; .long 0 ; .long 0 +storec: ; .long 0 ; .long 0 +stored: ; .long 0 ; .long 0 +#define REGMM0 %mm0 +#define REGMM1 %mm1 +#define REGMM2 %mm2 +#define REGMM3 %mm3 +#define REGMM4 %mm4 +#define REGMM5 %mm5 +#define REGMM6 %mm6 +#define REGMM7 %mm7 +#define MMXMOVE movq +#include "stages_mmx_md5.S" +#else +const_init_a: ; .long 0x67452301 ; .long 0x67452301 ; .long 0x67452301 ; .long 0x67452301 +const_init_b: ; .long 0xefcdab89 ; .long 0xefcdab89 ; .long 0xefcdab89 ; .long 0xefcdab89 +const_init_c: ; .long 0x98badcfe ; .long 0x98badcfe ; .long 0x98badcfe ; .long 0x98badcfe +const_init_d: ; .long 0x10325476 ; .long 0x10325476 ; .long 0x10325476 ; .long 0x10325476 +storea: ; .long 0 ; .long 0 ; .long 0 ; .long 0 +storeb: ; .long 0 ; .long 0 ; .long 0 ; .long 0 +storec: ; .long 0 ; .long 0 ; .long 0 ; .long 0 +stored: ; .long 0 ; .long 0 ; .long 0 ; .long 0 +#define REGMM0 %xmm0 +#define REGMM1 %xmm1 +#define REGMM2 %xmm2 +#define REGMM3 %xmm3 +#define REGMM4 %xmm4 +#define REGMM5 %xmm5 +#define REGMM6 %xmm6 +#define REGMM7 %xmm7 +#define MMXMOVE movapd +#include "stages_sse2_md5.S" +#endif + + +#define ctxa REGMM0 +#define ctxb REGMM1 +#define ctxc REGMM2 +#define ctxd REGMM3 +#define tmp1 REGMM4 +#define tmp2 REGMM5 +#define tmp3 REGMM6 +#define tmp4 REGMM7 + + +//#define F_MMX(x, y, z) (z ^ (x & (y ^ z))) + +#define F(x,y,z) \ + MMXMOVE y, tmp1; \ + pxor z, tmp1; \ + pand x, tmp1; \ + pxor z, tmp1 + +//#define G_MMX(x, y, z) (y ^ (z & (x ^ y))) + +#define G(x,y,z) \ + MMXMOVE y, tmp1; \ + pxor x, tmp1; \ + pand z, tmp1; \ + pxor y, tmp1 + +//#define H_MMX(x, y, z) (x ^ y ^ z) +#define H(x,y,z) \ + MMXMOVE y, tmp1; \ + pxor z, tmp1; \ + pxor x, tmp1 + +//#define I(x, y, z) (y ^ (x | ~z)) +#define I(x, y, z) \ + MMXMOVE z, tmp1; \ + pandn tmp4, tmp1; \ + por x, tmp1; \ + pxor y, tmp1; + + +//#define STEP_MMX(f, a, b, c, d, x, s) \ +// (a) += f((b), (c), (d)) + (x); \ +// (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); + +//#define STEP(f, a, b, c, d, x, t, s) \ +// (a) += f((b), (c), (d)) + (x) + (t); \ +// (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ +// (a) += (b); + + +#define STEP(f, a, b, c, d, x, t, s) \ + f(b, c, d); \ + paddd (x*4*MMX_COEF)(%edx), tmp1; \ + paddd t, a; \ + paddd tmp1, a; \ + MMXMOVE a, tmp3; \ + psrld $(32-s), tmp3; \ + pslld $s, a; \ + por tmp3, a; \ + paddd b, a + +#define STEPD(f, a, b, c, d, x, t, s) \ + f(b, c, d); \ + paddd (x*4*MMX_COEF)(%edx), tmp1; \ + paddd t, a; \ + paddd tmp1, a; \ + MMXMOVE a, tmp3; \ + psrld $(32-s), tmp3; \ + pslld $s, a; \ + por tmp3, a; \ + paddd b, a + + +.text +/* + * Try to do some asm md4 w/ mmx + * %eax ptr -> out + * %edx ptr -> in + * %ecx n + */ + +init: + MMXMOVE const_init_a, ctxa + MMXMOVE const_init_b, ctxb + MMXMOVE const_init_c, ctxc + MMXMOVE const_init_d, ctxd + ret; + +sizeupdate: +#if (MMX_COEF == 2) + shl $3, %ecx + mov %ecx, %ebx + and $0xffff, %ecx + shrl $16, %ebx + mov %ecx, (14*4*MMX_COEF)(%edx) + mov %ebx, (14*4*MMX_COEF+4)(%edx) +#else + mov %ecx, %ebx + shr $8, %ecx + and $0xff, %ebx + shl $3, %ebx + mov %ebx, (14*16)(%edx) + + mov %ecx, %ebx + shr $8, %ecx + and $0xff, %ebx + shl $3, %ebx + mov %ebx, (14*16+4)(%edx) + + mov %ecx, %ebx + shr $8, %ecx + and $0xff, %ebx + shl $3, %ebx + mov %ebx, (14*16+8)(%edx) + + and $0xff, %ecx + shl $3, %ecx + mov %ecx, (14*16+12)(%edx) +#endif + ret + +uniformsizeupdate: + shl $3, %ecx + mov %ecx, (14*4*MMX_COEF)(%edx) + mov %ecx, (14*4*MMX_COEF+4)(%edx) +#if (MMX_COEF == 4) + mov %ecx, (14*4*MMX_COEF+8)(%edx) + mov %ecx, (14*4*MMX_COEF+12)(%edx) +#endif + ret + +//entry points +mdfivemmx_noinit_sizeupdate: + pusha + call sizeupdate + jmp mdfivemmx_noinit + +mdfivemmx_noinit_uniformsizeupdate: + pusha + call uniformsizeupdate + jmp mdfivemmx_noinit + +mdfivemmx: + pusha + call sizeupdate + call init + jmp mdfivemmx_noinit + +mdfivemmx_nosizeupdate: + pusha + call init + jmp mdfivemmx_noinit +//end entry points + +mdfivemmx_noinit: + pcmpeqd tmp4, tmp4; + MMXMOVE ctxa, storea + MMXMOVE ctxb, storeb + MMXMOVE ctxc, storec + MMXMOVE ctxd, stored + + STEP(F, ctxa, ctxb, ctxc, ctxd, 0, const_stage_1, 7) + STEP(F, ctxd, ctxa, ctxb, ctxc, 1, const_stage_2, 12) + STEP(F, ctxc, ctxd, ctxa, ctxb, 2, const_stage_3, 17) + STEP(F, ctxb, ctxc, ctxd, ctxa, 3, const_stage_4, 22) + STEP(F, ctxa, ctxb, ctxc, ctxd, 4, const_stage_5, 7) + STEP(F, ctxd, ctxa, ctxb, ctxc, 5, const_stage_6, 12) + STEP(F, ctxc, ctxd, ctxa, ctxb, 6, const_stage_7, 17) + STEP(F, ctxb, ctxc, ctxd, ctxa, 7, const_stage_8, 22) + STEP(F, ctxa, ctxb, ctxc, ctxd, 8, const_stage_9, 7) + STEP(F, ctxd, ctxa, ctxb, ctxc, 9, const_stage_10, 12) + STEP(F, ctxc, ctxd, ctxa, ctxb, 10, const_stage_11, 17) + STEP(F, ctxb, ctxc, ctxd, ctxa, 11, const_stage_12, 22) + STEP(F, ctxa, ctxb, ctxc, ctxd, 12, const_stage_13, 7) + STEP(F, ctxd, ctxa, ctxb, ctxc, 13, const_stage_14, 12) + STEP(F, ctxc, ctxd, ctxa, ctxb, 14, const_stage_15, 17) + STEP(F, ctxb, ctxc, ctxd, ctxa, 15, const_stage_16, 22) + + STEP(G, ctxa, ctxb, ctxc, ctxd, 1, const_stage_17, 5) + STEP(G, ctxd, ctxa, ctxb, ctxc, 6, const_stage_18, 9) + STEP(G, ctxc, ctxd, ctxa, ctxb, 11, const_stage_19, 14) + STEP(G, ctxb, ctxc, ctxd, ctxa, 0, const_stage_20, 20) + STEP(G, ctxa, ctxb, ctxc, ctxd, 5, const_stage_21, 5) + STEP(G, ctxd, ctxa, ctxb, ctxc, 10, const_stage_22, 9) + STEP(G, ctxc, ctxd, ctxa, ctxb, 15, const_stage_23, 14) + STEP(G, ctxb, ctxc, ctxd, ctxa, 4, const_stage_24, 20) + STEP(G, ctxa, ctxb, ctxc, ctxd, 9, const_stage_25, 5) + STEP(G, ctxd, ctxa, ctxb, ctxc, 14, const_stage_26, 9) + STEP(G, ctxc, ctxd, ctxa, ctxb, 3, const_stage_27, 14) + STEP(G, ctxb, ctxc, ctxd, ctxa, 8, const_stage_28, 20) + STEP(G, ctxa, ctxb, ctxc, ctxd, 13, const_stage_29, 5) + STEP(G, ctxd, ctxa, ctxb, ctxc, 2, const_stage_30, 9) + STEP(G, ctxc, ctxd, ctxa, ctxb, 7, const_stage_31, 14) + STEP(G, ctxb, ctxc, ctxd, ctxa, 12, const_stage_32, 20) + + STEP(H, ctxa, ctxb, ctxc, ctxd, 5, const_stage_33, 4) + STEP(H, ctxd, ctxa, ctxb, ctxc, 8, const_stage_34, 11) + STEP(H, ctxc, ctxd, ctxa, ctxb, 11, const_stage_35, 16) + STEP(H, ctxb, ctxc, ctxd, ctxa, 14, const_stage_36, 23) + STEP(H, ctxa, ctxb, ctxc, ctxd, 1, const_stage_37, 4) + STEP(H, ctxd, ctxa, ctxb, ctxc, 4, const_stage_38, 11) + STEP(H, ctxc, ctxd, ctxa, ctxb, 7, const_stage_39, 16) + STEP(H, ctxb, ctxc, ctxd, ctxa, 10, const_stage_40, 23) + STEP(H, ctxa, ctxb, ctxc, ctxd, 13, const_stage_41, 4) + STEP(H, ctxd, ctxa, ctxb, ctxc, 0, const_stage_42, 11) + STEP(H, ctxc, ctxd, ctxa, ctxb, 3, const_stage_43, 16) + STEP(H, ctxb, ctxc, ctxd, ctxa, 6, const_stage_44, 23) + STEP(H, ctxa, ctxb, ctxc, ctxd, 9, const_stage_45, 4) + STEP(H, ctxd, ctxa, ctxb, ctxc, 12, const_stage_46, 11) + STEP(H, ctxc, ctxd, ctxa, ctxb, 15, const_stage_47, 16) + STEP(H, ctxb, ctxc, ctxd, ctxa, 2, const_stage_48, 23) + + STEP(I, ctxa, ctxb, ctxc, ctxd, 0, const_stage_49, 6) + STEP(I, ctxd, ctxa, ctxb, ctxc, 7, const_stage_50, 10) + STEP(I, ctxc, ctxd, ctxa, ctxb, 14, const_stage_51, 15) + STEP(I, ctxb, ctxc, ctxd, ctxa, 5, const_stage_52, 21) + STEP(I, ctxa, ctxb, ctxc, ctxd, 12, const_stage_53, 6) + STEP(I, ctxd, ctxa, ctxb, ctxc, 3, const_stage_54, 10) + STEP(I, ctxc, ctxd, ctxa, ctxb, 10, const_stage_55, 15) + STEP(I, ctxb, ctxc, ctxd, ctxa, 1, const_stage_56, 21) + STEP(I, ctxa, ctxb, ctxc, ctxd, 8, const_stage_57, 6) + STEP(I, ctxd, ctxa, ctxb, ctxc, 15, const_stage_58, 10) + STEP(I, ctxc, ctxd, ctxa, ctxb, 6, const_stage_59, 15) + STEP(I, ctxb, ctxc, ctxd, ctxa, 13, const_stage_60, 21) + STEP(I, ctxa, ctxb, ctxc, ctxd, 4, const_stage_61, 6) + STEP(I, ctxd, ctxa, ctxb, ctxc, 11, const_stage_62, 10) + STEP(I, ctxc, ctxd, ctxa, ctxb, 2, const_stage_63, 15) + STEP(I, ctxb, ctxc, ctxd, ctxa, 9, const_stage_64, 21) + + paddd storea, ctxa + paddd storeb, ctxb + paddd storec, ctxc + paddd stored, ctxd + + MMXMOVE ctxa, 0(%eax) + MMXMOVE ctxa, storea + MMXMOVE ctxb, (4*MMX_COEF)(%eax) + MMXMOVE ctxb, storeb + MMXMOVE ctxc, (8*MMX_COEF)(%eax) + MMXMOVE ctxc, storec + MMXMOVE ctxd, (12*MMX_COEF)(%eax) + MMXMOVE ctxd, stored + + popa + + emms + + ret + +#if defined(__ELF__) && defined(__linux__) +.section .note.GNU-stack,"",@progbits +#endif diff -urpN john-1.7.3.4.orig/src/md5.c john-1.7.3.4/src/md5.c --- john-1.7.3.4.orig/src/md5.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/md5.c 2008-08-24 06:40:50 +0000 @@ -0,0 +1,282 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, + * Inc. MD5 Message-Digest Algorithm (RFC 1321). + * + * Written by Solar Designer in 2001, and placed + * in the public domain. There's absolutely no warranty. + * + * This differs from Colin Plumb's older public domain implementation in + * that no 32-bit integer data type is required, there's no compile-time + * endianness configuration, and the function prototypes match OpenSSL's. + * The primary goals are portability and ease of use. + * + * This implementation is meant to be fast, but not as fast as possible. + * Some known optimizations are not included to reduce source code size + * and avoid compile-time configuration. + */ + +#ifndef HAVE_OPENSSL + +#include + +#include "md5.h" + +/* + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in Colin Plumb's + * implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD5_u32plus *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) +#else +#define SET(n) \ + (ctx->block[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (ctx->block[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There are no alignment requirements. + */ +static void *body(MD5_CTX *ctx, void *data, unsigned long size) +{ + unsigned char *ptr; + MD5_u32plus a, b, c, d; + MD5_u32plus saved_a, saved_b, saved_c, saved_d; + + ptr = data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) + +/* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return ptr; +} + +void MD5_Init(MD5_CTX *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->lo = 0; + ctx->hi = 0; +} + +void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size) +{ + MD5_u32plus saved_lo; + unsigned long used, free; + + saved_lo = ctx->lo; + if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) + ctx->hi++; + ctx->hi += size >> 29; + + used = saved_lo & 0x3f; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (unsigned char *)data + free; + size -= free; + body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = body(ctx, data, size & ~(unsigned long)0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + +void MD5_PreFinal(MD5_CTX *ctx) +{ + unsigned long used, free; + + used = ctx->lo & 0x3f; + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + memset(&ctx->buffer[used], 0, free); + body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + memset(&ctx->buffer[used], 0, free - 8); + + ctx->lo <<= 3; + ctx->buffer[56] = ctx->lo; + ctx->buffer[57] = ctx->lo >> 8; + ctx->buffer[58] = ctx->lo >> 16; + ctx->buffer[59] = ctx->lo >> 24; + ctx->buffer[60] = ctx->hi; + ctx->buffer[61] = ctx->hi >> 8; + ctx->buffer[62] = ctx->hi >> 16; + ctx->buffer[63] = ctx->hi >> 24; + + body(ctx, ctx->buffer, 64); +} + +void MD5_Final(unsigned char *result, MD5_CTX *ctx) +{ + MD5_PreFinal(ctx); + + result[0] = ctx->a; + result[1] = ctx->a >> 8; + result[2] = ctx->a >> 16; + result[3] = ctx->a >> 24; + result[4] = ctx->b; + result[5] = ctx->b >> 8; + result[6] = ctx->b >> 16; + result[7] = ctx->b >> 24; + result[8] = ctx->c; + result[9] = ctx->c >> 8; + result[10] = ctx->c >> 16; + result[11] = ctx->c >> 24; + result[12] = ctx->d; + result[13] = ctx->d >> 8; + result[14] = ctx->d >> 16; + result[15] = ctx->d >> 24; + +#if 0 + memset(ctx, 0, sizeof(*ctx)); +#endif +} + +#endif diff -urpN john-1.7.3.4.orig/src/md5.h john-1.7.3.4/src/md5.h --- john-1.7.3.4.orig/src/md5.h 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/md5.h 2008-08-24 07:32:54 +0000 @@ -0,0 +1,38 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, + * Inc. MD5 Message-Digest Algorithm (RFC 1321). + * + * Written by Solar Designer in 2001, and placed + * in the public domain. There's absolutely no warranty. + * + * See md5.c for more information. + */ + +#ifdef HAVE_OPENSSL +#include +#elif !defined(_MD5_H) +#define _MD5_H + +/* Any 32-bit or wider unsigned integer data type will do */ +typedef unsigned int MD5_u32plus; + +typedef struct { + MD5_u32plus lo, hi; + MD5_u32plus a, b, c, d; + unsigned char buffer[64]; + MD5_u32plus block[16]; +} MD5_CTX; + +extern void MD5_Init(MD5_CTX *ctx); +extern void MD5_Update(MD5_CTX *ctx, void *data, unsigned long size); +extern void MD5_PreFinal(MD5_CTX *ctx); +extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); + +#ifdef MMX_COEF +extern int mdfivemmx(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3))); +extern int mdfivemmx_nosizeupdate(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3))); +extern int mdfivemmx_noinit_sizeupdate(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3))); +extern int mdfivemmx_noinit_uniformsizeupdate(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3))); +#endif + +#endif diff -urpN john-1.7.3.4.orig/src/md5_eq.c john-1.7.3.4/src/md5_eq.c --- john-1.7.3.4.orig/src/md5_eq.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/md5_eq.c 2008-08-25 01:14:24 +0000 @@ -0,0 +1,326 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, + * Inc. MD5 Message-Digest Algorithm. + * + * Written by Solar Designer in 2001, and placed in + * the public domain. There's absolutely no warranty. + * + * This differs from Colin Plumb's older public domain implementation in + * that no 32-bit integer data type is required, there's no compile-time + * endianness configuration, and the function prototypes match OpenSSL's. + * The primary goals are portability and ease of use. + * + * This implementation is meant to be fast, but not as fast as possible. + * Some known optimizations are not included to reduce source code size + * and avoid compile-time configuration. + * + * This file has been modified by David Luyer to introduce + * some performance improvements, at the cost of its general-purpose use. + * See the caveats documented above the MD5_Go() routine. + * + * New performance improvements by Balázs Bucsay. It's only works up to 54 + * characters, but it is just enough. + * http://www.rycon.hu/ - earthquake at rycon.hu + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" + +#define CIPHERTEXT_LENGTH 32 +#define MAX_KEYS_PER_CRYPT 64 + +/* Output words */ + +#define MD5_out MD5_out_eq +#define MD5_bitswapped_out MD5_bitswapped_out_eq + +ARCH_WORD_32 MD5_out[MAX_KEYS_PER_CRYPT]; +char MD5_tmp[MAX_KEYS_PER_CRYPT][CIPHERTEXT_LENGTH + 1]; +ARCH_WORD_32 MD5_bitswapped_out2[4]; +#if !ARCH_LITTLE_ENDIAN + ARCH_WORD_32 MD5_bitswapped_out[MAX_KEYS_PER_CRYPT]; +#endif + +/* Bit-swapped output words */ + +#if !defined(_MD5_GO_H) +#define _MD5_GO_H + +/* Any 32-bit or wider unsigned integer data type will do */ +typedef unsigned int MD5_u32plus; + +#endif + + +/* + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in Colin Plumb's + * implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD5_u32plus *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) +#else +static MD5_u32plus work[16]; +#define SET(n) \ + (work[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (work[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There are no alignment requirements. + */ +static void body2_eq(void *data, int index) +{ + unsigned char *ptr; + MD5_u32plus a, b, c, d; + + ptr = data; + + a = 0x67452301; + b = 0xefcdab89; + c = 0x98badcfe; + d = 0x10325476; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) + +/* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += 0x67452301; + b += 0xefcdab89; + c += 0x98badcfe; + d += 0x10325476; + + MD5_bitswapped_out2[0] = (a << 24) | + (a >> 24) | + ((a << 8) & 0x00ff0000) | + ((a >> 8) & 0x0000ff00); + MD5_bitswapped_out2[1] = (b << 24) | + (b >> 24) | + ((b << 8) & 0x00ff0000) | + ((b >> 8) & 0x0000ff00); + MD5_bitswapped_out2[2] = (c << 24) | + (c >> 24) | + ((c << 8) & 0x00ff0000) | + ((c >> 8) & 0x0000ff00); + MD5_bitswapped_out2[3] = (d << 24) | + (d >> 24) | + ((d << 8) & 0x00ff0000) | + ((d >> 8) & 0x0000ff00); + + sprintf(MD5_tmp[index], "%08x%08x%08x%08x", (unsigned int)MD5_bitswapped_out2[0], (unsigned int)MD5_bitswapped_out2[1], (unsigned int)MD5_bitswapped_out2[2], (unsigned int)MD5_bitswapped_out2[3]); +} + +static void body_eq(void *data, int index) +{ + unsigned char *ptr; + MD5_u32plus a, b, c, d; + + ptr = data; + + a = 0x67452301; + b = 0xefcdab89; + c = 0x98badcfe; + d = 0x10325476; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) + +/* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + + MD5_out[index] = a + 0x67452301; + +} + + +void MD5_Go_eq(unsigned char *data, unsigned int len, int index) +{ + data[len] = 0x80; + memset(&data[len+1], 0, 63 - len); + data[56] = len << 3; + data[57] = len >> 5; + body_eq(data, index); + +#if !ARCH_LITTLE_ENDIAN + MD5_bitswapped_out[index] = (MD5_out[index] << 24) | + (MD5_out[index] >> 24) | + ((MD5_out[index] << 8) & 0x00ff0000) | + ((MD5_out[index] >> 8) & 0x0000ff00); +#endif +} + +void MD5_Go2_eq(unsigned char *data, unsigned int len, int index) +{ + data[len] = 0x80; + memset(&data[len+1], 0, 63 - len); + data[56] = len << 3; + data[57] = len >> 5; + body2_eq(data, index); +} diff -urpN john-1.7.3.4.orig/src/md5_go.c john-1.7.3.4/src/md5_go.c --- john-1.7.3.4.orig/src/md5_go.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/md5_go.c 2008-08-25 01:14:04 +0000 @@ -0,0 +1,230 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, + * Inc. MD5 Message-Digest Algorithm (RFC 1321). + * + * Written by Solar Designer in 2001, and placed + * in the public domain. There's absolutely no warranty. + * + * This differs from Colin Plumb's older public domain implementation in + * that no 32-bit integer data type is required, there's no compile-time + * endianness configuration, and the function prototypes match OpenSSL's. + * The primary goals are portability and ease of use. + * + * This implementation is meant to be fast, but not as fast as possible. + * Some known optimizations are not included to reduce source code size + * and avoid compile-time configuration. + * + * This file has been modified by David Luyer to + * introduce some performance improvements, at the cost of its + * general-purpose use. + * See the caveats documented above the MD5_Go() routine. + */ + +#include + +#include "arch.h" +#include "common.h" +#include "md5_go.h" + +#define MD5_out MD5_out_go +#define MD5_bitswapped_out MD5_bitswapped_out_go + +/* Output words */ +ARCH_WORD_32 MD5_out[4]; + +#if !ARCH_LITTLE_ENDIAN +/* Bit-swapped output words */ +ARCH_WORD_32 MD5_bitswapped_out[4]; +#endif + +/* + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in Colin Plumb's + * implementation. + */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b); + +/* + * SET reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + * + * The check for little-endian architectures that tolerate unaligned + * memory accesses is just an optimization. Nothing will break if it + * doesn't work. + */ +#if defined(__i386__) || defined(__x86_64__) || defined(__vax__) +#define SET(n) \ + (*(MD5_u32plus *)&ptr[(n) * 4]) +#define GET(n) \ + SET(n) +#else +static MD5_u32plus work[16]; +#define SET(n) \ + (work[(n)] = \ + (MD5_u32plus)ptr[(n) * 4] | \ + ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \ + ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \ + ((MD5_u32plus)ptr[(n) * 4 + 3] << 24)) +#define GET(n) \ + (work[(n)]) +#endif + +/* + * This processes one or more 64-byte data blocks, but does NOT update + * the bit counters. There are no alignment requirements. + */ +static void body(void *data, unsigned int size) +{ + unsigned char *ptr; + MD5_u32plus a, b, c, d; + MD5_u32plus saved_a, saved_b, saved_c, saved_d; + + ptr = data; + + a = 0x67452301; + b = 0xefcdab89; + c = 0x98badcfe; + d = 0x10325476; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + +/* Round 1 */ + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) + STEP(F, c, d, a, b, SET(2), 0x242070db, 17) + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22) + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7) + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12) + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17) + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22) + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7) + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12) + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17) + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22) + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7) + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) + +/* Round 2 */ + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14) + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20) + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5) + STEP(G, d, a, b, c, GET(10), 0x02441453, 9) + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14) + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20) + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5) + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9) + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14) + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20) + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5) + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) + +/* Round 3 */ + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) + STEP(H, d, a, b, c, GET(8), 0x8771f681, 11) + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16) + STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23) + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4) + STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11) + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16) + STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23) + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4) + STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11) + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16) + STEP(H, b, c, d, a, GET(6), 0x04881d05, 23) + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4) + STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11) + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) + STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23) + +/* Round 4 */ + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15) + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21) + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6) + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10) + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15) + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21) + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6) + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10) + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15) + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21) + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6) + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + ptr += 64; + } while (size -= 64); + + MD5_out[0] = a; + MD5_out[1] = b; + MD5_out[2] = c; + MD5_out[3] = d; +} + +/* Single-pass MD5 of a string of up to 2^11 bytes + * + * Caveats: + * - String length limited to 2^11 bytes (can be easily increased + * by adding data[process-6] = len >> 13 etc). + * - Requires scratch space at the end of the string (up to 73 bytes). + * - String will need re-terminating after calling this rountine. + */ +void MD5_Go(unsigned char *data, unsigned int len) +{ + unsigned int process = (len + 73) & ~0x3f; + + data[len] = 0x80; + memset(&data[len+1], 0, process - len - 1); + data[process-8] = len << 3; + data[process-7] = len >> 5; + body(data, process); + +#if !ARCH_LITTLE_ENDIAN + MD5_bitswapped_out[0] = (MD5_out[0] << 24) | + (MD5_out[0] >> 24) | + ((MD5_out[0] << 8) & 0x00ff0000) | + ((MD5_out[0] >> 8) & 0x0000ff00); + MD5_bitswapped_out[1] = (MD5_out[1] << 24) | + (MD5_out[1] >> 24) | + ((MD5_out[1] << 8) & 0x00ff0000) | + ((MD5_out[1] >> 8) & 0x0000ff00); + MD5_bitswapped_out[2] = (MD5_out[2] << 24) | + (MD5_out[2] >> 24) | + ((MD5_out[2] << 8) & 0x00ff0000) | + ((MD5_out[2] >> 8) & 0x0000ff00); + MD5_bitswapped_out[3] = (MD5_out[3] << 24) | + (MD5_out[3] >> 24) | + ((MD5_out[3] << 8) & 0x00ff0000) | + ((MD5_out[3] >> 8) & 0x0000ff00); +#endif +} diff -urpN john-1.7.3.4.orig/src/md5_go.h john-1.7.3.4/src/md5_go.h --- john-1.7.3.4.orig/src/md5_go.h 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/md5_go.h 2008-02-20 14:19:36 +0000 @@ -0,0 +1,16 @@ +/* + * This is an OpenSSL-compatible implementation of the RSA Data Security, + * Inc. MD5 Message-Digest Algorithm. + * + * Written by Solar Designer in 2001, placed in + * the public domain, and hacked by others. + */ + +#if !defined(_MD5_GO_H) +#define _MD5_GO_H + +/* Any 32-bit or wider unsigned integer data type will do */ +typedef unsigned int MD5_u32plus; +extern void MD5_Go(unsigned char *data, unsigned int len/*, unsigned char *result*/); + +#endif diff -urpN john-1.7.3.4.orig/src/mkv.c john-1.7.3.4/src/mkv.c --- john-1.7.3.4.orig/src/mkv.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/mkv.c 2008-09-15 01:06:20 +0000 @@ -0,0 +1,281 @@ +#include +#include + +#include "arch.h" +#include "misc.h" +#include "params.h" +#include "path.h" +#include "memory.h" +#include "signals.h" +#include "formats.h" +#include "loader.h" +#include "logger.h" +#include "status.h" +#include "recovery.h" +#include "config.h" +#include "charset.h" +#include "external.h" +#include "cracker.h" + +#include "mkv.h" + +extern struct fmt_main fmt_LM; + +static long long tidx; + +static void save_state(FILE *file) +{ + fprintf(file, "%lld\n", tidx); +} + +static int restore_state(FILE *file) +{ + if (fscanf(file, "%lld\n", &gidx) != 1) return 1; + + return 0; +} + +static void fix_state(void) +{ + tidx = gidx; +} + +static int show_pwd_rnbs(struct s_pwd * pwd) +{ + unsigned long long i; + unsigned int k; + unsigned long lvl; + + k=0; + i = nbparts[pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len]; + pwd->len++; + lvl = pwd->level; + pwd->password[pwd->len] = 0; + while(i>1) + { + pwd->password[pwd->len-1] = charsorted[ pwd->password[pwd->len-2]*256 + k ]; + pwd->level = lvl + proba2[ pwd->password[pwd->len-2]*256 + pwd->password[pwd->len-1] ]; + i -= nbparts[ pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len ]; + if(pwd->len<=gmax_len) + { + if(show_pwd_rnbs(pwd)) + return 1; + } + if(crk_process_key((char *)pwd->password)) + return 1; + gidx++; + k++; + if(gidx>gend) + return 1; + } + pwd->len--; + pwd->password[pwd->len] = 0; + pwd->level = lvl; + return 0; +} + +static int show_pwd_r(struct s_pwd * pwd, unsigned int bs) +{ + unsigned long long i; + unsigned int k; + unsigned long lvl; + unsigned char curchar; + unsigned int x; + + k=0; + x=pwd->len; + i = nbparts[pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len]; + pwd->len++; + lvl = pwd->level; + if(bs) + { + while( (curchar=charsorted[ pwd->password[pwd->len-2]*256 + k ]) != pwd->password[pwd->len-1] ) + { + i -= nbparts[ curchar + pwd->len*256 + (pwd->level + proba2[ pwd->password[pwd->len-2]*256 + curchar ])*256*gmax_len ]; + k++; + } + pwd->level += proba2[ pwd->password[pwd->len-2]*256 + pwd->password[pwd->len-1] ]; + if(pwd->password[pwd->len]!=0) + if(show_pwd_r(pwd, 1)) + return 1; + i -= nbparts[ pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len ]; + if(crk_process_key((char *)pwd->password)) + return 1; + gidx++; + k++; + } + pwd->password[pwd->len] = 0; + while(i>1) + { + pwd->password[pwd->len-1] = charsorted[ pwd->password[pwd->len-2]*256 + k ]; + pwd->level = lvl + proba2[ pwd->password[pwd->len-2]*256 + pwd->password[pwd->len-1] ]; + i -= nbparts[ pwd->password[pwd->len-1] + pwd->len*256 + pwd->level*256*gmax_len ]; + if(pwd->len<=gmax_len) + { + if(show_pwd_r(pwd, 0)) + return 1; + } + if(crk_process_key((char *)pwd->password)) + return 1; + gidx++; + k++; + if(gidx>gend) + return 1; + } + pwd->len--; + pwd->password[pwd->len] = 0; + pwd->level = lvl; + return 0; +} + +static int show_pwd(unsigned long long start) +{ + struct s_pwd pwd; + unsigned int i; + + if(gidx==0) + gidx = start; + i=0; + + if(gidx>0) + { + print_pwd(gidx, &pwd, gmax_level, gmax_len); + while(charsorted[i] != pwd.password[0]) + i++; + pwd.len = 1; + pwd.level = proba1[pwd.password[0]]; + if(show_pwd_r(&pwd, 1)) + return 1; + + if(crk_process_key((char *)pwd.password)) + return 1; + gidx++; + i++; + } + while(proba1[charsorted[i]]<=gmax_level) + { + if(gidx>gend) + return 1; + pwd.len = 1; + pwd.password[0] = charsorted[i]; + pwd.level = proba1[pwd.password[0]]; + pwd.password[1] = 0; + if(show_pwd_rnbs(&pwd)) + return 1; + if(crk_process_key((char *)pwd.password)) + return 1; + gidx++; + i++; + } + return 0; +} + +static int get_progress(void) +{ + if(gend == 0) + return 0; + return (gidx-gstart) * 100 / (gend-gstart); +} + + +void do_markov_crack(struct db_main *db, unsigned int mkv_level, unsigned long long mkv_start, unsigned long long mkv_end, unsigned int mkv_maxlen) +{ + char * statfile; + + if(mkv_level == 0) + if( (mkv_level = cfg_get_int("Options", NULL, "MkvLvl")) == -1 ) + { + log_event("no markov level defined!"); + fprintf(stderr, "no markov level defined!\n"); + error(); + } + + if(mkv_maxlen == 0) + if( (mkv_maxlen = cfg_get_int("Options", NULL, "MkvMaxLen")) == -1 ) + { + log_event("no markov max length defined!"); + fprintf(stderr, "no markov max length defined!\n"); + error(); + } + + statfile = cfg_get_param("Options", NULL, "Statsfile"); + if(statfile == NULL) + { + log_event("statfile not defined"); + fprintf(stderr, "Statfile not defined\n"); + error(); + } + + if (mkv_maxlen > db->format->params.plaintext_length) { + log_event("! MaxLen = %d is too large for this hash type", + mkv_maxlen); + fprintf(stderr, "Warning: " + "MaxLen = %d is too large for the current hash type, " + "reduced to %d\n", + mkv_maxlen, db->format->params.plaintext_length); + mkv_maxlen = db->format->params.plaintext_length; + } + + if (mkv_maxlen > MAX_MKV_LEN) { + log_event("! MaxLen = %d is too large (max=%d)", mkv_maxlen, MAX_MKV_LEN); + fprintf(stderr, "Warning: Maxlen = %d is too large (max = %d)\n", mkv_maxlen, MAX_MKV_LEN); + mkv_maxlen = MAX_MKV_LEN; + } + + if (mkv_level > MAX_MKV_LVL) { + log_event("! Level = %d is too large (max=%d)", mkv_level, MAX_MKV_LVL); + fprintf(stderr, "Warning: Level = %d is too large (max = %d)\n", mkv_level, MAX_MKV_LVL); + mkv_level = MAX_MKV_LVL; + } + + gidx = 0; + status_init(get_progress, 0); + rec_restore_mode(restore_state); + rec_init(db, save_state); + + init_probatables(path_expand(statfile)); + + crk_init(db, fix_state, NULL); + + gmax_level = mkv_level; + gmax_len = mkv_maxlen; + + nbparts = mem_alloc(256*(mkv_level+1)*sizeof(long long)*mkv_maxlen); + memset(nbparts, 0, 256*(mkv_level+1)*mkv_maxlen*sizeof(long long)); + + nb_parts(0, 0, 0, mkv_level, mkv_maxlen); + + if(mkv_end==0) + mkv_end = nbparts[0]; + + if(mkv_end>nbparts[0]) + { + log_event("! End = %lld is too large (max=%lld)", mkv_end, nbparts[0]); + fprintf(stderr, "Warning: End = %lld is too large (max = %lld)\n", mkv_end, nbparts[0]); + mkv_end = nbparts[0]; + } + + if(mkv_start>mkv_end) + { + log_event("! MKV start > end (%lld > %lld)", mkv_start, mkv_end); + fprintf(stderr, "Error: MKV start > end (%lld > %lld)\n", mkv_start, mkv_end); + error(); + } + + gstart = mkv_start; + gend = mkv_end + 10; /* omg !! */ + + fprintf(stderr, "MKV start (lvl=%d len=%d pwd=%lld)\n", mkv_level, mkv_maxlen, mkv_end-mkv_start); + + show_pwd(mkv_start); + + crk_done(); + rec_done(event_abort); + + MEM_FREE(nbparts); + MEM_FREE(proba1); + MEM_FREE(proba2); + MEM_FREE(first); + + crk_done(); +} diff -urpN john-1.7.3.4.orig/src/mkv.h john-1.7.3.4/src/mkv.h --- john-1.7.3.4.orig/src/mkv.h 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/mkv.h 2007-08-21 16:05:33 +0000 @@ -0,0 +1,12 @@ +#ifndef _JOHN_MKV_H +#define _JOHN_MKV_H + +#include "loader.h" +#include "mkvlib.h" + +/* + * Runs the markov mode cracker. + */ +extern void do_markov_crack(struct db_main *db, unsigned int mkv_level, unsigned long long mkv_start, unsigned long long mkv_end, unsigned int mkv_maxlen); + +#endif diff -urpN john-1.7.3.4.orig/src/mkvcalcproba.c john-1.7.3.4/src/mkvcalcproba.c --- john-1.7.3.4.orig/src/mkvcalcproba.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/mkvcalcproba.c 2009-08-31 13:39:41 +0000 @@ -0,0 +1,140 @@ +#include +#include +#include +#include + +#define MAX_LVL_LEN 28 +#define MAX_LEN 7 + +#define C2I(c) ((unsigned int)(unsigned char)(c)) + +unsigned int * proba1; +unsigned int * proba2; +unsigned int * first; + +int main(int argc, char * * argv) +{ + FILE * fichier; + char * ligne; + unsigned int i; + unsigned int j; + unsigned int k; + unsigned int l; + unsigned long long index; + unsigned char position[256]; + unsigned int charset; + unsigned int nb_lignes; + + if(argc!=3) + { + printf("Usage: %s statfile pwdfile\n", argv[0]); + return -1; + } + + fichier = fopen(argv[1], "r"); + if(!fichier) + { + printf("could not open %s\n", argv[1]); + return -1; + } + + first = malloc( sizeof(int) * 256 ); + + ligne = malloc(4096); + + proba2 = malloc(sizeof(unsigned int) * 256 * 256); + proba1 = malloc(sizeof(unsigned int) * 256 ); + for(i=0;i<256*256;i++) + proba2[i] = 1000; + for(i=0;i<256;i++) + proba1[i] = 1000; + + for(i=0;i<256;i++) + { + first[i] = 255; + position[i] = 255; + } + + nb_lignes = 0; + charset = 0; + while(fgets(ligne, 4096, fichier)) + { + if (ligne[0] == 0) + continue; + ligne[strlen(ligne)-1] = 0; // chop + if( sscanf(ligne, "%d=proba1[%d]", &i, &j) == 2 ) + { + proba1[j] = i; + if(position[j] == 255) + { + position[j] = charset; + charset++; + } + } + if( sscanf(ligne, "%d=proba2[%d*256+%d]", &i, &j, &k) == 3 ) + { + if( (first[j]>k) && (i<1000)) + first[j] = k; + proba2[j*256+k] = i; + if(position[k] == 255) + { + position[k] = charset; + charset++; + } + } + nb_lignes++; + } + fclose(fichier); + + fichier = fopen(argv[2], "r"); + if(!fichier) + { + printf("could not open %s\n", argv[1]); + return -1; + } + + while(fgets(ligne, 4096, fichier)) + { + if (ligne[0] == 0) + continue; + ligne[strlen(ligne)-1] = 0; // chop + i=1; j=0; k=0; + j = C2I(ligne[0]); + k = proba1[j]; + printf("%s\t%d", ligne, k); + l = 0; + index = position[j]; + if(position[j]==255) + index = 8.1E18; + while(ligne[i]) + { + if(index<8E18) + index = (index*charset)+position[C2I(ligne[i])]; + if(position[C2I(ligne[i])]==255) + index = 8.1E18; + printf("+%d", proba2[j*256+C2I(ligne[i])]); + k+=proba2[j*256+C2I(ligne[i])]; + if(l) + l+=proba2[j*256+C2I(ligne[i])]; + if(i==2) + l=proba1[C2I(ligne[i])]; + j = C2I(ligne[i]); + i++; + } + if(index<8E18) + printf("\t%d\t%d\t%lld\t%d\n",k,i,index,l); + else + printf("\t%d\t%d\t-\t%d\n",k,i,l); + } + + free(proba1); + free(proba2); + + free(first); + + free(ligne); + + fprintf(stderr, "charsetsize = %d\n", charset); + + return 0; +} diff -urpN john-1.7.3.4.orig/src/mkvlib.c john-1.7.3.4/src/mkvlib.c --- john-1.7.3.4.orig/src/mkvlib.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/mkvlib.c 2008-09-17 03:11:00 +0000 @@ -0,0 +1,211 @@ +#include +#include + +#include "arch.h" +#include "misc.h" +#include "params.h" +#include "memory.h" +#include "mkvlib.h" + +unsigned int * proba1; +unsigned int * proba2; +unsigned long long * nbparts; +unsigned int * first; +unsigned char charsorted[256*256]; + +unsigned int gmax_level; +unsigned int gmax_len; +unsigned long long gidx; +unsigned long long gstart; +unsigned long long gend; + +unsigned long long nb_parts(unsigned char lettre, unsigned int len, unsigned int level, unsigned int max_lvl, unsigned int max_len) +{ + int i; + unsigned long long out=1; + + if(level>max_lvl) + return 0; + + if(len==max_len) + { + nbparts[lettre + len*256 + level*256*max_len] = 1; + return 1; + } + + if(nbparts[lettre + (len)*256 + level*256*max_len] != 0) + return nbparts[lettre + (len)*256 + level*256*max_len]; + + for(i=1;i<256;i++) + if(len==0) + out += nb_parts(i, len+1, proba1[i], max_lvl, max_len); + else + out += nb_parts(i, len+1, level + proba2[lettre*256 + i], max_lvl, max_len); + + nbparts[lettre + (len)*256 + level*256*max_len] = out; + return out; +} + +void print_pwd(unsigned long long index, struct s_pwd * pwd, unsigned int max_lvl, unsigned int max_len) +{ + unsigned int len = 1; + unsigned int level = 0; + unsigned int lvl = 0; + unsigned int i; + unsigned int oldc = 0; + + if(index>nbparts[0]) + return; + + len = 1; + while(index && (len<=max_len)) + { + + for(i=0;i<256;i++) + { + if(len==1) + level = proba1[charsorted[256*0+i]]; + else + { + level = lvl + proba2[oldc*256 + charsorted[oldc*256+i]]; + } + + if( level > max_lvl ) + { + i=256; + break; + } + + if(nbparts[charsorted[oldc*256+i] + len*256 + level*256*max_len]==0) + { + break; + } + + if (index <= nbparts[charsorted[oldc*256+i] + len*256 + level*256*max_len]) + break; + + index -= nbparts[charsorted[oldc*256+i] + len*256 + level*256*max_len]; + } + if(i==256) + break; + lvl = level; + pwd->password[len-1] = charsorted[oldc*256+i]; + oldc = charsorted[oldc*256+i]; + len++; + } + pwd->password[len-1] = 0; + pwd->index = index; + pwd->level = lvl; + pwd->len = len-1; +} + + +static void stupidsort(unsigned char * result, unsigned int * source, unsigned int size) +{ + unsigned char pivot; + unsigned char more[256]; + unsigned char less[256]; + unsigned char piv[256]; + unsigned int i,m,l,p; + + if(size<=1) + return; + i=0; + while( (source[result[i]]==1000) && (ik) && (i<1000)) + first[j] = k; + proba2[j*256+k] = i; + + } + nb_lignes++; + } + MEM_FREE(ligne); + fclose(fichier); + + stupidsort(charsorted, proba1, 256); + for(i=1;i<256;i++) + stupidsort(&(charsorted[i*256]), &(proba2[i*256]), 256); +} + + diff -urpN john-1.7.3.4.orig/src/mkvlib.h john-1.7.3.4/src/mkvlib.h --- john-1.7.3.4.orig/src/mkvlib.h 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/mkvlib.h 2007-09-21 13:29:53 +0000 @@ -0,0 +1,28 @@ +#ifndef _JOHN_MKVLIB_H +#define _JOHN_MKVLIB_H + + +struct s_pwd +{ + unsigned int level; + unsigned int len; + unsigned int index; + unsigned char password[MAX_MKV_LEN+1]; +}; + +extern unsigned int * proba1; +extern unsigned int * proba2; +extern unsigned long long * nbparts; +extern unsigned int * first; +extern unsigned char charsorted[256*256]; + +extern unsigned int gmax_level; +extern unsigned int gmax_len; +extern unsigned long long gidx; +extern unsigned long long gstart; +extern unsigned long long gend; + +void print_pwd(unsigned long long index, struct s_pwd * pwd, unsigned int max_lvl, unsigned int max_len); +unsigned long long nb_parts(unsigned char lettre, unsigned int len, unsigned int level, unsigned int max_lvl, unsigned int max_len); +void init_probatables(char * filename); +#endif diff -urpN john-1.7.3.4.orig/src/mscash_fmt.c john-1.7.3.4/src/mscash_fmt.c --- john-1.7.3.4.orig/src/mscash_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/mscash_fmt.c 2008-08-24 07:07:55 +0000 @@ -0,0 +1,544 @@ +/* MSCASH patch for john (performance improvement) + * + * Written by Alain Espinosa in 2007 + * and placed in the public domain. + */ + +#include +#include "arch.h" +#include "misc.h" +#include "memory.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "mscash" +#define FORMAT_NAME "M$ Cache Hash" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 27 +#define MAX_CIPHERTEXT_LENGTH (2 + 32 + 1 + 32) + + +static struct fmt_tests tests[] = { + {"M$test1#64cd29e36a8431a2b111378564a10631", "test1" }, + {"M$test2#ab60bdb4493822b175486810ac2abe63", "test2" }, + {"M$test3#14dd041848e12fc48c0aa7a416a4a00c", "test3" }, + {"M$test4#b945d24866af4b01a6d89b9d932a153c", "test4" }, + {NULL} +}; + +#define ALGORITHM_NAME "Generic 1x" + +#define BINARY_SIZE 16 +#define SALT_SIZE (11*4) + +#define MS_NUM_KEYS 64 +#define MIN_KEYS_PER_CRYPT MS_NUM_KEYS +#define MAX_KEYS_PER_CRYPT MS_NUM_KEYS + + +static unsigned int ms_buffer1x[16*MS_NUM_KEYS]; +static unsigned int output1x[4*MS_NUM_KEYS]; + +static unsigned int crypt[4*MS_NUM_KEYS]; +static unsigned int last[4*MS_NUM_KEYS]; + +static unsigned int last_i[MS_NUM_KEYS]; +static char saved_plain[32*MS_NUM_KEYS]; + +static unsigned int *salt_buffer; +static unsigned int new_key; + +//Init values +#define INIT_A 0x67452301 +#define INIT_B 0xefcdab89 +#define INIT_C 0x98badcfe +#define INIT_D 0x10325476 + +#define SQRT_2 0x5a827999 +#define SQRT_3 0x6ed9eba1 + +static void init(void) +{ + memset(ms_buffer1x,0,64*MS_NUM_KEYS); + memset(last_i,0,4*MS_NUM_KEYS); + new_key=1; +} + +static char * ms_split(char *ciphertext, int index) +{ + static char out[MAX_CIPHERTEXT_LENGTH + 1]; + int i=0; + + for(; ciphertext[i] && i < MAX_CIPHERTEXT_LENGTH; i++) + out[i]=ciphertext[i]; + + out[i]=0; + + if (i >= 32) + strlwr(&out[i-32]); + + return out; +} + +static int valid(char *ciphertext) +{ + unsigned int i; + unsigned int l; + + /* + * 2 cases + * 1 - it comes from the disk, and does not have M$ + salt + * 2 - it comes from memory, and has got M$ + salt + # + blah + */ + + if (!strncmp(ciphertext, "M$", 2)) + { + l = strlen(ciphertext); + if (l <= 32 || l > MAX_CIPHERTEXT_LENGTH) + return 0; + l -= 32; + if(ciphertext[l-1]!='#') + return 0; + } + else + { + if(strlen(ciphertext)!=32) + return 0; + l = 0; + } + for (i = l; i < l + 32; i++) + if (atoi16[ARCH_INDEX(ciphertext[i])] == 0x7F) + return 0; + + return 1; +} + +static void set_salt(void *salt) { + salt_buffer=salt; +} + +static void * get_salt(char * ciphertext) +{ + //lenght=11 for save memory + //last position = 0 + //4 first position are crypt[?] + static unsigned int out[11]; + unsigned int md4_size=0; + + memset(out,0,44); + + ciphertext+=2; + + for(;;md4_size++) + if(ciphertext[md4_size]!='#' && md4_size < 19) + { + md4_size++; + + out[md4_size>>1] = ciphertext[md4_size-1] | ((ciphertext[md4_size]!='#') ? (ciphertext[md4_size]<<16) : 0x800000); + + if(ciphertext[md4_size]=='#') + break; + } + else + { + out[md4_size>>1] = 0x80; + break; + } + + out[10] = (8 + md4_size) << 4; + + return out; +} + +static void *get_binary(char *ciphertext) +{ + static unsigned int out[4]; + unsigned int i=0; + unsigned int temp; + unsigned int * salt=get_salt(ciphertext); + + for(;ciphertext[0]!='#';ciphertext++); + + ciphertext++; + + for(; i<4 ;i++) + { + temp = (atoi16[ARCH_INDEX(ciphertext[i*8+0])])<<4; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+1])]); + + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+2])])<<12; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+3])])<<8; + + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+4])])<<20; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+5])])<<16; + + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+6])])<<28; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+7])])<<24; + + out[i]=temp; + } + + out[0] -= INIT_A; + out[1] -= INIT_B; + out[2] -= INIT_C; + out[3] -= INIT_D; + + // Reversed b += (c ^ d ^ a) + salt_buffer[11] + SQRT_3; b = (b << 15) | (b >> 17); + out[1] = (out[1] >> 15) | (out[1] << 17); + out[1] -= SQRT_3 + (out[2] ^ out[3] ^ out[0]); + // Reversed c += (d ^ a ^ b) + salt_buffer[3] + SQRT_3; c = (c << 11) | (c >> 21); + out[2] = (out[2] << 21) | (out[2] >> 11); + out[2]-= SQRT_3 + (out[3] ^ out[0] ^ out[1]) + salt[3]; + // Reversed d += (a ^ b ^ c) + salt_buffer[7] + SQRT_3; d = (d << 9 ) | (d >> 23); + out[3] = (out[3] << 23) | (out[3] >> 9); + out[3] -= SQRT_3 + (out[0] ^ out[1] ^ out[2]) + salt[7]; + //+ SQRT_3; d = (d << 9 ) | (d >> 23); + out[3]=(out[3] << 23 ) | (out[3] >> 9); + out[3]-=SQRT_3; + + return out; +} + +static int binary_hash_0(void *binary) +{ + return ((unsigned int*)binary)[3] & 0x0F; +} + +static int binary_hash_1(void *binary) +{ + return ((unsigned int*)binary)[3] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((unsigned int*)binary)[3] & 0x0FFF; +} + +static int get_hash_0(int index) +{ + return output1x[4*index+3] & 0x0F; +} + +static int get_hash_1(int index) +{ + return output1x[4*index+3] & 0xFF; +} + +static int get_hash_2(int index) +{ + return output1x[4*index+3] & 0x0FFF; +} + +void nt_hash(void) +{ + unsigned int a; + unsigned int b; + unsigned int c; + unsigned int d; + unsigned int i=0; + + for(;i> 29); + d = INIT_D + (INIT_C ^ (a & 0x77777777)) + ms_buffer1x[16*i+1];d = (d << 7 ) | (d >> 25); + c = INIT_C + (INIT_B ^ (d & (a ^ INIT_B)))+ ms_buffer1x[16*i+2];c = (c << 11) | (c >> 21); + b = INIT_B + (a ^ (c & (d ^ a))) + ms_buffer1x[16*i+3];b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + ms_buffer1x[16*i+4] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + ms_buffer1x[16*i+5] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + ms_buffer1x[16*i+6] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + ms_buffer1x[16*i+7] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + ms_buffer1x[16*i+8] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + ms_buffer1x[16*i+9] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + ms_buffer1x[16*i+10] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + ms_buffer1x[16*i+11] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + ms_buffer1x[16*i+12] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + ms_buffer1x[16*i+13] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + ms_buffer1x[16*i+14] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a)))/*+ms_buffer1x[16*i+15]*/;b = (b << 19) | (b >> 13); + + /* Round 2 */ + a += ((b & (c | d)) | (c & d)) + ms_buffer1x[16*i+0] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + ms_buffer1x[16*i+4] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + ms_buffer1x[16*i+8] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + ms_buffer1x[16*i+12] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + ms_buffer1x[16*i+1] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + ms_buffer1x[16*i+5] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + ms_buffer1x[16*i+9] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + ms_buffer1x[16*i+13] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + ms_buffer1x[16*i+2] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + ms_buffer1x[16*i+6] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + ms_buffer1x[16*i+10] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + ms_buffer1x[16*i+14] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + ms_buffer1x[16*i+3] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + ms_buffer1x[16*i+7] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + ms_buffer1x[16*i+11] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a))/*+ms_buffer1x[16*i+15]*/+SQRT_2; b = (b << 13) | (b >> 19); + + /* Round 3 */ + a += (b ^ c ^ d) + ms_buffer1x[16*i+0] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + ms_buffer1x[16*i+8] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + ms_buffer1x[16*i+4] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + ms_buffer1x[16*i+12] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + ms_buffer1x[16*i+2] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + ms_buffer1x[16*i+10] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + ms_buffer1x[16*i+6] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + ms_buffer1x[16*i+14] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + ms_buffer1x[16*i+1] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + ms_buffer1x[16*i+9] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + ms_buffer1x[16*i+5] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + ms_buffer1x[16*i+13] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + ms_buffer1x[16*i+3] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + ms_buffer1x[16*i+11] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + ms_buffer1x[16*i+7] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) /*+ ms_buffer1x[16*i+15] */+ SQRT_3; b = (b << 15) | (b >> 17); + + crypt[4*i+0] = a + INIT_A; + crypt[4*i+1] = b + INIT_B; + crypt[4*i+2] = c + INIT_C; + crypt[4*i+3] = d + INIT_D; + + //Another MD4_crypt for the salt + /* Round 1 */ + a= 0xFFFFFFFF +crypt[4*i+0]; a=(a<<3 )|(a>>29); + d=INIT_D + ( INIT_C ^ ( a & 0x77777777)) +crypt[4*i+1]; d=(d<<7 )|(d>>25); + c=INIT_C + ( INIT_B ^ ( d & ( a ^ INIT_B))) +crypt[4*i+2]; c=(c<<11)|(c>>21); + b=INIT_B + ( a ^ ( c & ( d ^ a ))) +crypt[4*i+3]; b=(b<<19)|(b>>13); + + last[4*i+0]=a; + last[4*i+1]=b; + last[4*i+2]=c; + last[4*i+3]=d; + } +} + +static void crypt_all(int count) +{ + unsigned int a; + unsigned int b; + unsigned int c; + unsigned int d; + unsigned int i=0; + + if(new_key) + { + new_key=0; + nt_hash(); + } + + for(;i> 29); + d += (c ^ (a & (b ^ c))) + salt_buffer[1] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + salt_buffer[2] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + salt_buffer[3] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + salt_buffer[4] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + salt_buffer[5] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + salt_buffer[6] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + salt_buffer[7] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + salt_buffer[8] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + salt_buffer[9] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + salt_buffer[10] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a)))/*+salt_buffer[11]*/;b = (b << 19) | (b >> 13); + + /* Round 2 */ + a += ((b & (c | d)) | (c & d)) + crypt[4*i+0] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + salt_buffer[0] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + salt_buffer[4] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + salt_buffer[8] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + crypt[4*i+1] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + salt_buffer[1] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + salt_buffer[5] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + salt_buffer[9] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + crypt[4*i+2] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + salt_buffer[2] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + salt_buffer[6] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + salt_buffer[10] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + crypt[4*i+3] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + salt_buffer[3] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + salt_buffer[7] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a))/*+ salt_buffer[11]*/+ SQRT_2; b = (b << 13) | (b >> 19); + + /* Round 3 */ + a += (b ^ c ^ d) + crypt[4*i+0] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + salt_buffer[4] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + salt_buffer[0] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + salt_buffer[8] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + crypt[4*i+2] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + salt_buffer[6] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + salt_buffer[2] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + salt_buffer[10] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + crypt[4*i+1] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + salt_buffer[5]; + + output1x[4*i+0]=a; + output1x[4*i+1]=b; + output1x[4*i+2]=c; + output1x[4*i+3]=d; + } +} + +static int cmp_all(void *binary, int count) +{ + unsigned int i=0; + unsigned int d=((unsigned int *)binary)[3]; + + for(;i> 23); + + c += (d ^ a ^ b) + salt_buffer[1] + SQRT_3; c = (c << 11) | (c >> 21); + if(c!=t[2]) + return 0; + + b += (c ^ d ^ a) + salt_buffer[9] + SQRT_3; b = (b << 15) | (b >> 17); + if(b!=t[1]) + return 0; + + a += (b ^ c ^ d) + crypt[4*index+3]+ SQRT_3; a = (a << 3 ) | (a >> 29); + return (a==t[0]); +} + +static int cmp_exact(char *source, int index) +{ + // This check its for the unreal case of collisions. + // It verify that the salts its the same. + unsigned int *salt=get_salt(source); + unsigned int i=0; + for(;i<11;i++) + if(salt[i]!=salt_buffer[i]) + return 0; + return 1; +} + +static void set_key(char *key, int index) +{ + unsigned int md4_size=0; + unsigned int i=0; + unsigned int temp; + unsigned int saved_base=index<<5; + unsigned int buff_base=index<<4; + + for(;key[md4_size] && md4_size>1; + + ms_buffer1x[buff_base+14] = md4_size << 4; + + //new password_candidate + new_key=1; +} + +static char *get_key(int index) +{ + return saved_plain+(index<<5); +} + +int salt_hash(void *salt) +{ + return ((unsigned char*)salt)[0]; +} + +struct fmt_main fmt_mscash = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + init, + valid, + ms_split, + get_binary, + get_salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2 + }, + salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + get_hash_0, + get_hash_1, + get_hash_2 + }, + cmp_all, + cmp_one, + cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/mssql05_fmt.c john-1.7.3.4/src/mssql05_fmt.c --- john-1.7.3.4.orig/src/mssql05_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/mssql05_fmt.c 2009-10-29 02:58:28 +0000 @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2004 bartavelle + * bartavelle at bandecon.com + * + * Modified by Mathieu Perrin (mathieu at tpfh.org) 09/06 + * Microsoft MS-SQL05 password cracker + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "sha.h" + +#define FORMAT_LABEL "mssql05" +#define FORMAT_NAME "MS-SQL05" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "ms-sql05 MMX" +#else +#define ALGORITHM_NAME "ms-sql05 SSE2" +#endif +#else +#define ALGORITHM_NAME "ms-sql05" +#endif + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 20 +#define CIPHERTEXT_LENGTH 54 + +#define BINARY_SIZE 20 +#define SALT_SIZE 4 + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +//#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + ((i)&3) ) //std getpos +#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) ) //for endianity conversion +#else +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +//microsoft unicode ... +#if ARCH_LITTLE_ENDIAN +#define ENDIAN_SHIFT_L +#define ENDIAN_SHIFT_R +#else +#define ENDIAN_SHIFT_L << 8 +#define ENDIAN_SHIFT_R >> 8 +#endif + +static struct fmt_tests mssql05_tests[] = { + {"0x01004086CEB6BF932BC4151A1AF1F13CD17301D70816A8886908", "toto"}, + {"0x01004086CEB60ED526885801C23B366965586A43D3DEAC6DD3FD", "titi"}, + {NULL} +}; + +static unsigned char cursalt[SALT_SIZE]; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define saved_key mssql05_saved_key +#define crypt_key mssql05_crypt_key +char saved_key[80*4*MMX_COEF] __attribute__ ((aligned(16))); +char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static unsigned long total_len; +static unsigned char out[PLAINTEXT_LENGTH + 1]; +#else +static unsigned char saved_key[PLAINTEXT_LENGTH*2 + 1]; +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static SHA_CTX ctx; +static unsigned int key_length; +#endif + +static int valid(char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) return 0; + if(memcmp(ciphertext, "0x0100", 6)) + return 0; + for (i = 6; i < CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) + return 0; + } + return 1; +} + +static void mssql05_set_salt(void *salt) +{ + memcpy(cursalt, salt, SALT_SIZE); +} + +static void * mssql05_get_salt(char * ciphertext) +{ + static unsigned char out2[SALT_SIZE]; + int l; + + for(l=0;lPLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + total_len += (len*2+SALT_SIZE ) << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i> (((32/MMX_COEF)*(index)))) & 0xff; + s = (s-4)/2; + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#else + return !memcmp(binary, crypt_key, BINARY_SIZE); +#endif +} + +static int mssql05_cmp_exact(char *source, int count){ + return (1); +} + +static int mssql05_cmp_one(void * binary, int index) +{ +#ifdef MMX_COEF + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] ) + return 0; + return 1; +#else + return mssql05_cmp_all(binary, index); +#endif +} + +static void mssql05_crypt_all(int count) { + // get plaintext input in saved_key put it into ciphertext crypt_key +#ifdef MMX_COEF + shammx((unsigned char *) crypt_key, (unsigned char *) saved_key, total_len); +#else + memcpy(saved_key+key_length*2, cursalt, SALT_SIZE); + SHA1_Init( &ctx ); + SHA1_Update( &ctx, saved_key, key_length*2+SALT_SIZE ); + SHA1_Final( (unsigned char *) crypt_key, &ctx); +#endif + +} + +static void * mssql05_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + for(i=0;i + +#include "arch.h" +#include "misc.h" +#include "params.h" +#include "common.h" +#include "formats.h" +#include "sha.h" + +#define FORMAT_LABEL "mssql" +#define FORMAT_NAME "MS-SQL" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "ms-sql MMX" +#else +#define ALGORITHM_NAME "ms-sql SSE2" +#endif +#else +#define ALGORITHM_NAME "ms-sql" +#endif + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 20 +#define CIPHERTEXT_LENGTH 94 + +#define BINARY_SIZE 20 +#define SALT_SIZE 4 + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +//#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + ((i)&3) ) //std getpos +#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) ) //for endianity conversion +#else +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +//microsoft unicode ... +#if ARCH_LITTLE_ENDIAN +#define ENDIAN_SHIFT_L +#define ENDIAN_SHIFT_R +#else +#define ENDIAN_SHIFT_L << 8 +#define ENDIAN_SHIFT_R >> 8 +#endif + +static struct fmt_tests mssql_tests[] = { + {"0x0100A607BA7C54A24D17B565C59F1743776A10250F581D482DA8B6D6261460D3F53B279CC6913CE747006A2E3254", "FOO"}, + {"0x01000508513EADDF6DB7DDD270CCA288BF097F2FF69CC2DB74FBB9644D6901764F999BAB9ECB80DE578D92E3F80D", "BAR"}, + {"0x01008408C523CF06DCB237835D701C165E68F9460580132E28ED8BC558D22CEDF8801F4503468A80F9C52A12C0A3", "CANARD"}, + {"0x0100BF088517935FC9183FE39FDEC77539FD5CB52BA5F5761881E5B9638641A79DBF0F1501647EC941F3355440A2", "LAPIN"}, + {NULL} +}; + +static unsigned char cursalt[SALT_SIZE]; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define saved_key mssql_saved_key +#define crypt_key mssql_crypt_key +char saved_key[80*4*MMX_COEF] __attribute__ ((aligned(16))); +char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static unsigned long total_len; +static unsigned char out[PLAINTEXT_LENGTH + 1]; +#else +static unsigned char saved_key[PLAINTEXT_LENGTH*2 + 1]; +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static SHA_CTX ctx; +static unsigned int key_length; +#endif + +static int valid(char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) return 0; + if(memcmp(ciphertext, "0x0100", 6)) + return 0; + for (i = 6; i < CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) + return 0; + } + return 1; +} + +static void mssql_set_salt(void *salt) +{ + memcpy(cursalt, salt, SALT_SIZE); +} + +static void * mssql_get_salt(char * ciphertext) +{ + static unsigned char out2[SALT_SIZE]; + int l; + + for(l=0;l='a') && (c<='z')) + return c+'A'-'a'; + return c; +} + +static void mssql_init(void) +{ +#ifdef MMX_COEF + memset(saved_key, 0, 64*MMX_COEF); +#endif +} + +static void mssql_set_key(char *key, int index) { +#ifdef MMX_COEF + int len; + int i; + + if(index==0) + { + total_len = 0; + memset(saved_key, 0, 64*MMX_COEF); + } + len = strlen(key); + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + total_len += (len*2+SALT_SIZE ) << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i> (((32/MMX_COEF)*(index)))) & 0xff; + s = (s-4)/2; + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#else + return !memcmp(binary, crypt_key, BINARY_SIZE); +#endif +} + +static int mssql_cmp_exact(char *source, int count){ + return (1); +} + +static int mssql_cmp_one(void * binary, int index) +{ +#ifdef MMX_COEF + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] ) + return 0; + return 1; +#else + return mssql_cmp_all(binary, index); +#endif +} + +static void mssql_crypt_all(int count) { + // get plaintext input in saved_key put it into ciphertext crypt_key +#ifdef MMX_COEF + shammx( (unsigned char *) crypt_key, (unsigned char *) saved_key, total_len); +#else + memcpy(saved_key+key_length*2, cursalt, SALT_SIZE); + SHA1_Init( &ctx ); + SHA1_Update( &ctx, saved_key, key_length*2+SALT_SIZE ); + SHA1_Final( (unsigned char *) crypt_key, &ctx); +#endif + +} + +static void * mssql_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + for(i=0;i + * + * Simple MySQL 4.1+ PASSWORD() hash cracker, rev 1. + * Adapted from the original rawSHA1_fmt.c cracker. + * + * Note that many version 4.1 and 5.0 installations still use the old + * homebrewn pre-4.1 hash for compatibility with older clients, notably all + * Red Hat-based distributions. + * + * The new PASSWORD() function is unsalted and equivalent to + * SHA1(SHA1(password)) where the inner is a binary digest (not hex!) This + * means that with the SSE2-boosted SHA-1 implementation, it will be several + * times faster than John's cracker for the old hash format. (though the old + * hash had significant weaknesses, John's code does not take advantage of + * that) + * + * It's a slight improvement over the old hash, but still not something a + * reasonable DBMS would use for password storage. + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "sha.h" + +//#define X_DEBUG +#ifdef X_DEBUG +# include +#endif + +#define FORMAT_LABEL "mysql-sha1" +#define FORMAT_NAME "MySQL 4.1 double-SHA-1" +#ifdef MMX_COEF +# if (MMX_COEF == 2) +# define ALGORITHM_NAME "mysql-sha1 MMX" +# else +# define ALGORITHM_NAME "mysql-sha1 SSE2" +# endif +#else +# define ALGORITHM_NAME "mysql-sha1" +#endif + +#ifdef MMX_TYPE +# define BENCHMARK_COMMENT MMX_TYPE +#else +# define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 41 + +#define BINARY_SIZE 20 +#define SALT_SIZE 0 + +#ifdef MMX_COEF +# define MIN_KEYS_PER_CRYPT MMX_COEF +# define MAX_KEYS_PER_CRYPT MMX_COEF +//#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + ((i)&3) ) //std getpos +# define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) ) //for endianity conversion +# define BYTESWAP(n) ( \ + (((n)&0x000000ff) << 24) | \ + (((n)&0x0000ff00) << 8 ) | \ + (((n)&0x00ff0000) >> 8 ) | \ + (((n)&0xff000000) >> 24) ) +#else +# define MIN_KEYS_PER_CRYPT 1 +# define MAX_KEYS_PER_CRYPT 1 +#endif + +static struct fmt_tests mysqlsha1_tests[] = { + {"*5AD8F88516BD021DD43F171E2C785C69F8E54ADB", "tere"}, + {"*2C905879F74F28F8570989947D06A8429FB943E6", "verysecretpassword"}, + {"*A8A397146B1A5F8C8CF26404668EFD762A1B7B82", "________________________________"}, + {"*F9F1470004E888963FB466A5452C9CBD9DF6239C", "12345678123456781234567812345678"}, + {"*97CF7A3ACBE0CA58D5391AC8377B5D9AC11D46D9", "' OR 1 /*'"}, + {"*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19", "password"}, + {"*7534F9EAEE5B69A586D1E9C1ACE3E3F9F6FCC446", "5"}, + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define saved_key mysqlSHA1_saved_key +#define crypt_key mysqlSHA1_crypt_key +char saved_key[80*4*MMX_COEF] __attribute__ ((aligned(16))); +char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); + +/* Intermediate key which stores the hashes between two SHA-1 operations. Don't + * ask me why it has to be so long ;) */ +#define interm_key mysqlSHA1_interm_key +char interm_key[80*4*MMX_COEF] __attribute__ ((aligned(16))); + +static unsigned long total_len; + +# if MMX_COEF > 2 +/* argument to shammx(); all intermediary plaintexts are 20 bytes long */ +# define TMPKEY_LENGTHS 0x14141414 +# else +# define TMPKEY_LENGTHS 0x00140014 +# endif + +#else +static char saved_key[PLAINTEXT_LENGTH + 1]; +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static SHA_CTX ctx; +#endif + +static int valid(char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) return 0; + if (ciphertext[0] != '*') + return 0; + for (i = 1; i < CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) + || (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) + { + return 0; + } + } + return 1; +} + +static void mysqlsha1_set_salt(void *salt) { } + +static void mysqlsha1_init(void) +{ +#ifdef MMX_COEF + memset(saved_key, 0, sizeof saved_key); + memset(interm_key, 0, sizeof interm_key); + /* input strings have to be terminated by 0x80. The input strings in + * interm_key have a static length (20 bytes) so we can set them just once. + */ + const int offset = (MMX_COEF*BINARY_SIZE)/4; + + ((unsigned*)interm_key)[offset+0] = BYTESWAP(0x80); + ((unsigned*)interm_key)[offset+1] = BYTESWAP(0x80); +# if MMX_COEF > 2 + ((unsigned*)interm_key)[offset+2] = BYTESWAP(0x80); + ((unsigned*)interm_key)[offset+3] = BYTESWAP(0x80); +# endif +#endif +} + +static void mysqlsha1_set_key(char *key, int index) { +#ifdef MMX_COEF + int len; + int i; + /* FIXME: we're wasting 22% time in set_key with SSE2 (rawSHA1 is wasting + * nearly 50%!). The huge memset() is probably a culprit, but also the + * bytewise byte-order swapping code (see GETPOS macro above). */ + + if(index==0) + { + total_len = 0; + memset(saved_key, 0, sizeof(saved_key)); + } + len = strlen(key); + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + total_len += len << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i> (((32/MMX_COEF)*(index)))) & 0xff; + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#else + return !memcmp(binary, crypt_key, BINARY_SIZE); +#endif +} + +static int mysqlsha1_cmp_exact(char *source, int count){ + return (1); +} + +static int mysqlsha1_cmp_one(void *binary, int index) +{ +#ifdef MMX_COEF + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] ) + return 0; + return 1; +#else + return mysqlsha1_cmp_all(binary, index); +#endif +} + +static void mysqlsha1_crypt_all(int count) { +#ifdef MMX_COEF + unsigned int i; + + shammx((unsigned char *) crypt_key, (unsigned char *) saved_key, total_len); + + for(i = 0; i < MMX_COEF*BINARY_SIZE/sizeof(unsigned); i++) + { + ((unsigned*)interm_key)[i] = BYTESWAP(((unsigned*)crypt_key)[i]); + } + + /* Verify that the 0x80 padding hasn't been overwritten. */ +# ifdef X_DEBUG + assert(((unsigned*)interm_key)[i+0] == BYTESWAP(0x80)); + assert(((unsigned*)interm_key)[i+1] == BYTESWAP(0x80)); +# if MMX_COEF > 2 + assert(((unsigned*)interm_key)[i+2] == BYTESWAP(0x80)); + assert(((unsigned*)interm_key)[i+3] == BYTESWAP(0x80)); +# endif +# endif /* X_DEBUG */ + + shammx((unsigned char *) crypt_key, (unsigned char *) interm_key, TMPKEY_LENGTHS); + +#else + SHA1_Init(&ctx); + SHA1_Update(&ctx, (unsigned char *) saved_key, strlen(saved_key)); + SHA1_Final((unsigned char *) crypt_key, &ctx); + + SHA1_Init(&ctx); + SHA1_Update(&ctx, (unsigned char *) crypt_key, BINARY_SIZE); + SHA1_Final((unsigned char *) crypt_key, &ctx); +#endif +} + +static void *mysqlsha1_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + // ignore first character '*' + ciphertext += 1; + for(i=0;i + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "sha.h" +#include + +#define FORMAT_LABEL "oracle11" +#define FORMAT_NAME "Oracle 11g" +#define ALGORITHM_NAME "oracle11" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +/* Maximum length of password in characters. Oracle supports identifiers of 30 + * characters max. (ALTER USER user IDENTIFIED BY 30lettersPassword) */ +#define PLAINTEXT_LENGTH 30 +/* Length in characters of the cipher text, as seen in the password file. + * Excludes prefix if any. */ +#define CIPHERTEXT_LENGTH 60 + +/* Length of hashed value without the salt, in bytes. */ +#define BINARY_SIZE 20 +/* Length of salt in bytes. */ +#define SALT_SIZE 10 + +/* Sanity check. Don't change. */ +#if (BINARY_SIZE + SALT_SIZE) * 2 != CIPHERTEXT_LENGTH +#error Incorrect binary sizes or cipher text length. +#endif + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + /* 160 bits of SHA1, followed by 80 bits of salt. No "S:" prefix. */ + {"5FDAB69F543563582BA57894FE1C1361FB8ED57B903603F2C52ED1B4D642", "abc123"}, + {"450F957ECBE075D2FA009BA822A9E28709FBC3DA82B44D284DDABEC14C42", "SyStEm123!@#"}, + {"3437FF72BD69E3FB4D10C750B92B8FB90B155E26227B9AB62D94F54E5951", "oracle"}, + {"61CE616647A4F7980AFD7C7245261AF25E0AFE9C9763FCF0D54DA667D4E6", "11g"}, + {"B9E7556F53500C8C78A58F50F24439D79962DE68117654B6700CE7CC71CF", "11g"}, + {NULL} +}; + +static char saved_key[PLAINTEXT_LENGTH + 1]; +static int saved_key_length; +static unsigned char saved_salt[SALT_SIZE]; +static SHA_CTX ctx; +static unsigned char crypt_out[BINARY_SIZE]; + +static int valid(char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) return 0; + for (i = 0; i < CIPHERTEXT_LENGTH; i++){ + if (!isxdigit(ciphertext[i])) + return 0; + } + return 1; +} + +static void *salt(char *ciphertext) +{ + static unsigned char salt[SALT_SIZE]; + int i; + + for (i = 0; i < SALT_SIZE; i++) { + salt[i] = atoi16[ARCH_INDEX(ciphertext[BINARY_SIZE*2+i*2+0])]*16 + + atoi16[ARCH_INDEX(ciphertext[BINARY_SIZE*2+i*2+1])]; + } + + return (void *)salt; +} + +static void set_salt(void *salt) +{ + memcpy(saved_salt, salt, SALT_SIZE); +} + +static void set_key(char *key, int index) { + saved_key_length = strlen(key); + if (saved_key_length > PLAINTEXT_LENGTH) + saved_key_length = PLAINTEXT_LENGTH; + memcpy(saved_key, key, saved_key_length); + saved_key[saved_key_length] = 0; +} + +static char *get_key(int index) { + return saved_key; +} + +static int cmp_all(void *binary, int index) { + return !memcmp(binary, crypt_out, BINARY_SIZE); +} + +static int cmp_exact(char *source, int count) { + return 1; +} + +static void crypt_all(int count) { + SHA1_Init( &ctx ); + SHA1_Update( &ctx, (unsigned char *) saved_key, saved_key_length ); + SHA1_Update( &ctx, saved_salt, SALT_SIZE ); + SHA1_Final( crypt_out, &ctx); +} + +static void * binary(char *ciphertext) +{ + static unsigned char realcipher[BINARY_SIZE]; + + int i; + for(i=0;i +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "oracle" +#define FORMAT_NAME "Oracle" +#define ALGORITHM_NAME "oracle" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 120 + +#define BINARY_SIZE 8 +#define SALT_SIZE (32 + 2) +#define CIPHERTEXT_LENGTH 16 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests oracle_tests[] = { + {"O$SYSTEM#9EEDFA0AD26C6D52", "THALES" }, + {"O$SIMON#4F8BC1809CB2AF77", "A"}, + {"O$SIMON#183D72325548EF11", "THALES2" }, + {"O$SIMON#C4EB3152E17F24A4", "TST" }, + {"O$BOB#b02c8e79ed2e7f46", "LAPIN" }, + {"O$BOB#6bb4e95898c88011", "LAPINE" }, + {"O$BOB#cdc6b483874b875b", "GLOUGLOU" }, + {"O$BOB#ef1f9139db2d5279", "GLOUGLOUTER" }, + {"O$BOB#c0ee5107c9a080c1", "AZERTYUIOP" }, + {"O$BOB#99e8b231d33772f9", "CANARDWC" }, + {"O$BOB#da3224126a67c8ed", "COUCOU_COUCOU" }, + {"O$BOB#ec8147abb3373d53", "LONG_MOT_DE_PASSE_OUI" }, + {NULL} +}; + +#if ARCH_LITTLE_ENDIAN +#define ENDIAN_SHIFT_L << 8 +#define ENDIAN_SHIFT_R >> 8 +#else +#define ENDIAN_SHIFT_L +#define ENDIAN_SHIFT_R +#endif + +static ARCH_WORD_32 crypt_key[2]; + +static unsigned short cur_salt[SALT_SIZE / 2 + PLAINTEXT_LENGTH]; +static unsigned short cur_key[PLAINTEXT_LENGTH + 1]; + +static DES_key_schedule desschedule1; +static DES_key_schedule desschedule2; + +static int salt_length; +static int key_length; + +static int valid(char *ciphertext) +{ + int i; + int l; + + /* + * 2 cases + * 1 - it comes from the disk, and does not have O$ + salt + * 2 - it comes from memory, and has got O$ + salt + # + blah + */ + + if (!memcmp(ciphertext, "O$", 2)) + { + l = strlen(ciphertext) - CIPHERTEXT_LENGTH; + if(ciphertext[l-1]!='#') + return 0; + } + else + { + if(strlen(ciphertext)!=CIPHERTEXT_LENGTH) + return 0; + l = 0; + } + for (i = l; i < l + CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) + return 0; + } + + return 1; +} + +static void oracle_init(void) +{ + unsigned char deskey[8]; + + deskey[0] = 0x01; + deskey[1] = 0x23; + deskey[2] = 0x45; + deskey[3] = 0x67; + deskey[4] = 0x89; + deskey[5] = 0xab; + deskey[6] = 0xcd; + deskey[7] = 0xef; + + DES_set_key((DES_cblock *)deskey, &desschedule1); +} + +static inline unsigned char upper(unsigned char c) +{ + if( (c>='a') && (c<='z')) + return c+'A'-'a'; + return c; +} + +static void oracle_set_salt(void *salt) { + salt_length = *(unsigned short *)salt; + memcpy(cur_salt, (char *)salt+2, salt_length); +} + +static void oracle_set_key(char *key, int index) { + key_length = 0; + while( (cur_key[key_length] = upper(key[key_length]) ENDIAN_SHIFT_L )) + key_length++; + key_length <<= 1; +} + +static char *oracle_get_key(int index) { + static unsigned char out[PLAINTEXT_LENGTH + 1]; + unsigned int i; + for(i=0;i>1;i++) + out[i] = cur_key[i] ENDIAN_SHIFT_R; + out[i] = 0; + return (char *) out; +} + +static void oracle_crypt_all(int count) +{ + unsigned char buf[sizeof(cur_salt)]; + unsigned int l; + + l = salt_length + key_length; + crypt_key[0] = 0; + crypt_key[1] = 0; + memcpy((char *)cur_salt + salt_length, cur_key, key_length); + DES_ncbc_encrypt((unsigned char *)cur_salt, buf, l, &desschedule1, (DES_cblock *) crypt_key, DES_ENCRYPT); + DES_set_key((DES_cblock *)crypt_key, &desschedule2); + crypt_key[0] = 0; + crypt_key[1] = 0; + DES_ncbc_encrypt((unsigned char *)cur_salt, buf, l, &desschedule2, (DES_cblock *) crypt_key, DES_ENCRYPT); +} + +static void * oracle_binary(char *ciphertext) +{ + static unsigned char out3[BINARY_SIZE]; + int l; + int i; + l = strlen(ciphertext) - CIPHERTEXT_LENGTH; + for(i=0;i= SALT_SIZE-2) break; + } + salt[l-2] = 0; + + l = 0; + while ((out[l+1] = upper(salt[l]) ENDIAN_SHIFT_L)) + l++; + out[0] = l*2; + + return out; +} + +static int binary_hash1(void * binary) { return (((ARCH_WORD_32 *)binary)[0] & 0xf); } +static int binary_hash2(void * binary) { return (((ARCH_WORD_32 *)binary)[0] & 0xff); } +static int binary_hash3(void * binary) { return (((ARCH_WORD_32 *)binary)[0] & 0xfff); } + +static int get_hash1(int index) { return crypt_key[0] & 0xf; } +static int get_hash2(int index) { return crypt_key[0] & 0xff; } +static int get_hash3(int index) { return crypt_key[0] & 0xfff; } + +static int oracle_cmp_all(void *binary, int index) { + return !memcmp(binary, crypt_key, sizeof(crypt_key)); +} + +static int oracle_cmp_exact(char *source, int count) { + return 1; +} + +struct fmt_main fmt_oracle = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_8_BIT, + oracle_tests + }, { + oracle_init, + valid, + fmt_default_split, + oracle_binary, + oracle_get_salt, + { + binary_hash1, + binary_hash2, + binary_hash3 + }, + fmt_default_salt_hash, + oracle_set_salt, + oracle_set_key, + oracle_get_key, + fmt_default_clear_keys, + oracle_crypt_all, + { + get_hash1, + get_hash2, + get_hash3 + }, + oracle_cmp_all, + oracle_cmp_all, + oracle_cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/params.h john-1.7.3.4/src/params.h --- john-1.7.3.4.orig/src/params.h 2009-09-14 01:13:01 +0000 +++ john-1.7.3.4/src/params.h 2010-02-14 03:32:18 +0000 @@ -15,7 +15,7 @@ /* * John's version number. */ -#define JOHN_VERSION "1.7.3.4" +#define JOHN_VERSION "1.7.3.4-jumbo-3" /* * Notes to packagers of John for *BSD "ports", Linux distributions, etc.: @@ -91,7 +91,7 @@ /* * Default benchmark time in seconds (per cracking algorithm). */ -#define BENCHMARK_TIME 5 +#define BENCHMARK_TIME 1 /* * Number of salts to assume when benchmarking. @@ -267,4 +267,8 @@ extern int password_hash_thresholds[3]; #define PATH_BUFFER_SIZE 0x400 #endif +/* Markov mode stuff */ +#define MAX_MKV_LVL 400 +#define MAX_MKV_LEN 30 + #endif diff -urpN john-1.7.3.4.orig/src/pixMD5_fmt.c john-1.7.3.4/src/pixMD5_fmt.c --- john-1.7.3.4.orig/src/pixMD5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/pixMD5_fmt.c 2009-10-29 02:59:06 +0000 @@ -0,0 +1,277 @@ +/* + * Based on: + * + * Copyright (c) 2004 bartavelle + * bartavelle at bandecon.com + * + * Simple MD5 hashes cracker + * It uses the Solar Designer's md5 implementation + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "md5.h" + +#define FORMAT_LABEL "pix-md5" +#define FORMAT_NAME "PIX MD5" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "pix-md5 MMX" +#else +#define ALGORITHM_NAME "pix-md5 SSE2" +#endif +#else +#define ALGORITHM_NAME "pix-md5" +#endif + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 16 + +#define SALT_SIZE 0 + +#ifdef MMX_COEF +#define BINARY_SIZE 16 +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +#define GETPOS(i, index) ( (index)*4 + ((i) & (0xffffffff-3) )*MMX_COEF + ((i)&3) ) +#else +#define BINARY_SIZE (4 * sizeof(ARCH_WORD_32)) +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +static struct fmt_tests pixmd5_tests[] = { + {"TRPEas6f/aa6JSPL", "test1"}, + {"OMT6mXmAvGyzrCtp", "test2"}, + {"gTC7RIy1XJzagmLm", "test3"}, + {"oWC1WRwqlBlbpf/O", "test4"}, + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define saved_key pixMD5_saved_key +#define crypt_key pixMD5_crypt_key +char saved_key[PLAINTEXT_LENGTH*MMX_COEF*2 + 1] __attribute__ ((aligned(16))); +char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static unsigned long total_len; +static unsigned char out[PLAINTEXT_LENGTH + 1]; +#else +static char saved_key[PLAINTEXT_LENGTH + 1]; +static MD5_CTX ctx; +#endif + +static int valid(char *ciphertext) +{ + unsigned int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + + for (i = 0; i < CIPHERTEXT_LENGTH; i++) + if(!atoi64[ARCH_INDEX(ciphertext[i])]) + return 0; + return 1; +} + +static void pixmd5_set_salt(void *salt) { } + +static void pixmd5_init() +{ +#ifdef MMX_COEF + unsigned int i; + + total_len = 0; + for(i=0;i> (((32/MMX_COEF)*(index)))) & 0xff; + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != (((unsigned long *)crypt_key)[i*MMX_COEF+2] & MASK)) + && ( ((unsigned long *)binary)[i] != (((unsigned long *)crypt_key)[i*MMX_COEF+3] & MASK)) +#endif + ) + return 0; + i++; + } +#else + if (((ARCH_WORD_32 *)binary)[1] != (ctx.b & MASK)) return 0; + if (((ARCH_WORD_32 *)binary)[2] != (ctx.c & MASK)) return 0; + if (((ARCH_WORD_32 *)binary)[3] != (ctx.d & MASK)) return 0; + if (((ARCH_WORD_32 *)binary)[0] != (ctx.a & MASK)) return 0; +#endif + return 1; +} + +static int pixmd5_cmp_exact(char *source, int count){ + return (1); +} + +#ifdef MMX_COEF +static int pixmd5_cmp_one(void * binary, int index) +{ + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != (((unsigned long *)crypt_key)[i*MMX_COEF+index] & MASK ) ) + return 0; + return 1; +} +#else +#define pixmd5_cmp_one pixmd5_cmp_all +#endif + +static void pixmd5_crypt_all(int count) { + // get plaintext input in saved_key put it into ciphertext crypt_key +#ifdef MMX_COEF + + mdfivemmx((unsigned char*)crypt_key, (unsigned char*)saved_key, total_len); +#else + MD5_Init( &ctx ); + MD5_Update( &ctx, saved_key, 16 ); + MD5_PreFinal(&ctx); +#endif +} + +static void * pixmd5_binary(char *ciphertext) +{ + static ARCH_WORD_32 realcipher[4]; + int i; + + for(i = 0; i < 4; i++) { + realcipher[i] = + atoi64[ARCH_INDEX(ciphertext[i*4 + 0])] + + (atoi64[ARCH_INDEX(ciphertext[i*4 + 1])] << 6) + + (atoi64[ARCH_INDEX(ciphertext[i*4 + 2])] << 12) + + (atoi64[ARCH_INDEX(ciphertext[i*4 + 3])] << 18); + } + return (void *)realcipher; +} + +static int get_hash1(int index) +{ +#ifdef MMX_COEF + return (((unsigned char *)crypt_key)[index*4] & 0xf); +#else + return ctx.a & 0xf; +#endif +} +static int get_hash2(int index) +{ +#ifdef MMX_COEF + return ((unsigned char *)crypt_key)[index*4]; +#else + return ctx.a & 0xff; +#endif +} +static int get_hash3(int index) +{ +#ifdef MMX_COEF + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xfff; +#else + return ctx.a & 0xfff; +#endif +} + +static int binary_hash1(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xf; } +static int binary_hash2(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xff; } +static int binary_hash3(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xfff; } + +struct fmt_main fmt_pixMD5 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + 16, /* not exactly PLAINTEXT_LENGTH, the code is dirty */ + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + pixmd5_tests + }, { + pixmd5_init, + valid, + fmt_default_split, + pixmd5_binary, + fmt_default_salt, + { + binary_hash1, + binary_hash2, + binary_hash3 + }, + fmt_default_salt_hash, + pixmd5_set_salt, + pixmd5_set_key, + pixmd5_get_key, + fmt_default_clear_keys, + pixmd5_crypt_all, + { + get_hash1, + get_hash2, + get_hash3 + }, + pixmd5_cmp_all, + pixmd5_cmp_one, + pixmd5_cmp_exact + } +}; diff -urpN john-1.7.3.4.orig/src/rawMD5go_fmt.c john-1.7.3.4/src/rawMD5go_fmt.c --- john-1.7.3.4.orig/src/rawMD5go_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/rawMD5go_fmt.c 2008-08-25 01:16:02 +0000 @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2004 bartavelle + * bartavelle at bandecon.com + * + * Simple MD5 hashes cracker + * It uses the Solar Designer's md5 implementation + * + * Minor changes by David Luyer to + * use a modified (faster) version of Solar Designer's + * md5 implementation. + * + * More improvement by + * Balázs Bucsay - earthquake at rycon.hu - http://www.rycon.hu/ + * (2times faster, but it's only works up to 54characters) + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" + +#if ARCH_LITTLE_ENDIAN +#define MD5_out MD5_out_eq +#else +#define MD5_out MD5_bitswapped_out_eq +#endif + + +#define FORMAT_LABEL "raw-md5" +#define FORMAT_NAME "Raw MD5" +#define ALGORITHM_NAME "raw-md5" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 32 + +#define BINARY_SIZE 16 +#define SALT_SIZE 0 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 64 + +extern ARCH_WORD_32 MD5_out[MAX_KEYS_PER_CRYPT]; +extern char MD5_tmp[MAX_KEYS_PER_CRYPT][CIPHERTEXT_LENGTH + 1]; + +typedef unsigned int MD5_u32plus; +extern void MD5_Go_eq(unsigned char *data, unsigned int len, int index); +extern void MD5_Go2_eq(unsigned char *data, unsigned int len, int index); + +static struct fmt_tests rawmd5_tests[] = { + {"5a105e8b9d40e1329780d62ea2265d8a", "test1"}, + {"ad0234829205b9033196ba818f7a872b", "test2"}, + {"8ad8757baa8564dc136c1e07507f4a98", "test3"}, + {"86985e105f79b95d6bc918fb45ec7727", "test4"}, + {"378e2c4a07968da2eca692320136433d", "thatsworking"}, + {NULL} +}; + +static char saved_key[MAX_KEYS_PER_CRYPT][PLAINTEXT_LENGTH + 1 + 128 /* MD5 scratch space */]; +int saved_key_len[MAX_KEYS_PER_CRYPT]; + +static int valid(char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) return 0; + for (i = 0; i < CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) )) + return 0; + } + return 1; +} + +static void rawmd5_set_salt(void *salt) { } + +static void rawmd5_set_key(char *key, int index) { + strnzcpy(saved_key[index], key, PLAINTEXT_LENGTH+1); + saved_key_len[index] = strlen(saved_key[index]); +} + +static char *rawmd5_get_key(int index) { + saved_key[index][saved_key_len[index]] = '\0'; + return saved_key[index]; +} + +static int rawmd5_cmp_one(void *binary, int index) +{ + return (!(*((unsigned int*)binary) - (unsigned int)MD5_out[index])); +} + +static int rawmd5_cmp_all(void *binary, int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) + { + if (!(*((unsigned int*)binary) - *((unsigned int*)&MD5_out[i]))) return 1; + } + + return 0; +} + +static int rawmd5_cmp_exact(char *source, int index) +{ + MD5_Go2_eq((unsigned char *)saved_key[index], saved_key_len[index], index); + return !memcmp(source, MD5_tmp[index], CIPHERTEXT_LENGTH); +} + +static void rawmd5_crypt_all(int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) + { + MD5_Go_eq((unsigned char *)saved_key[i], saved_key_len[i], i); + } +} + +int rawmd5_binary_hash_0(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xF; +} + +int rawmd5_binary_hash_1(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xFF; +} + +int rawmd5_binary_hash_2(void *binary) +{ + return *(ARCH_WORD_32 *)binary & 0xFFF; +} + +int rawmd5_get_hash_0(int index) +{ + return MD5_out[index] & 0xF; +} + +int rawmd5_get_hash_1(int index) +{ + return MD5_out[index] & 0xFF; +} + +int rawmd5_get_hash_2(int index) +{ + return MD5_out[index] & 0xFFF; +} + +static void *rawmd5_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + for(i=0;i + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "sha.h" + +#define FORMAT_LABEL "raw-sha1" +#define FORMAT_NAME "Raw SHA-1" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "raw-sha1 MMX" +#else +#define ALGORITHM_NAME "raw-sha1 SSE2" +#endif +#else +#define ALGORITHM_NAME "raw-sha1" +#endif + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 40 + +#define BINARY_SIZE 20 +#define SALT_SIZE 0 + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +//#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + ((i)&3) ) //std getpos +#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) ) //for endianity conversion +#else +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +static struct fmt_tests rawsha1_tests[] = { + {"A9993E364706816ABA3E25717850C26C9CD0D89D", "abc"}, + {"2fbf0eba37de1d1d633bc1ed943b907f9b360d4c", "azertyuiop1"}, + {"f879f8090e92232ed07092ebed6dc6170457a21d", "azertyuiop2"}, + {"1813c12f25e64931f3833b26e999e26e81f9ad24", "azertyuiop3"}, + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define saved_key rawSHA1_saved_key +#define crypt_key rawSHA1_crypt_key +char saved_key[80*4*MMX_COEF] __attribute__ ((aligned(16))); +char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static unsigned long total_len; +static unsigned char out[PLAINTEXT_LENGTH + 1]; +#else +static char saved_key[PLAINTEXT_LENGTH + 1]; +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static SHA_CTX ctx; +#endif + +static int valid(char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) return 0; + for (i = 0; i < CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) + return 0; + } + return 1; +} + +static void rawsha1_set_salt(void *salt) { } + +static void rawsha1_init(void) +{ +#ifdef MMX_COEF + memset(saved_key, 0, sizeof(saved_key)); +#endif +} + +static void rawsha1_set_key(char *key, int index) { +#ifdef MMX_COEF + int len; + int i; + + if(index==0) + { + total_len = 0; + memset(saved_key, 0, sizeof(saved_key)); + } + len = strlen(key); + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + total_len += len << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i> (((32/MMX_COEF)*(index)))) & 0xff; + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#else + return !memcmp(binary, crypt_key, BINARY_SIZE); +#endif +} + +static int rawsha1_cmp_exact(char *source, int count){ + return (1); +} + +static int rawsha1_cmp_one(void * binary, int index) +{ +#ifdef MMX_COEF + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] ) + return 0; + return 1; +#else + return rawsha1_cmp_all(binary, index); +#endif +} + +static void rawsha1_crypt_all(int count) { + // get plaintext input in saved_key put it into ciphertext crypt_key +#ifdef MMX_COEF + shammx((unsigned char *) crypt_key, (unsigned char *) saved_key, total_len); +#else + SHA1_Init( &ctx ); + SHA1_Update( &ctx, (unsigned char *) saved_key, strlen( saved_key ) ); + SHA1_Final( (unsigned char *) crypt_key, &ctx); +#endif + +} + +static void * rawsha1_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + for(i=0;i +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include "md5.h" + +#define FORMAT_LABEL "sapb" +#define FORMAT_NAME "SAP BCODE" +#define ALGORITHM_NAME "sapb" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define SALT_SIZE 40 /* the max username length */ +#define PLAINTEXT_LENGTH 8 /* passwordlength max 8 chars */ +#define CIPHERTEXT_LENGTH SALT_SIZE + 1 + 16 /* SALT + $ + 2x8 bytes for BCODE-representation */ + +#define BINARY_SIZE 8 /* half of md5 */ + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests sapbcode_tests[] = { + {"F $E3A65AAA9676060F", "X"}, + {"JOHNNY $7F7207932E4DE471", "CYBERPUNK"}, + {"VAN $487A2A40A7BA2258", "HAUSER"}, + {"ROOT $8366A4E9E6B72CB0", "KID"}, + {"MAN $9F48E7CE5B184D2E", "u"}, + {"----------------------------------------$08CEDAFED0C750A0", "-------"}, + {"SAP* $7016BFF7C5472F1B", "MAsTeR"}, + {"DDIC $C94E2F7DD0178374", "DDIC"}, + {"DOLLAR$$$--- $C3413C498C48EB67", "dollar$$$---"}, + {NULL} +}; + +static char saved_key[PLAINTEXT_LENGTH + 1]; +static char crypt_key[BINARY_SIZE]; +static MD5_CTX ctx; +static char theSalt[SALT_SIZE]; + +static int sapbcode_valid(char *ciphertext) +{ + int i; + + if(strlen(ciphertext)!=CIPHERTEXT_LENGTH) + return 0; + + if (ciphertext[SALT_SIZE]!='$') + return 0; + + for (i = SALT_SIZE+1; i< CIPHERTEXT_LENGTH; i++) + if (!(((ciphertext[i]>='A' && ciphertext[i]<='F')) || + ((ciphertext[i]>='a' && ciphertext[i]<='f')) || + ((ciphertext[i]>='0' && ciphertext[i]<='9')) )) + return 0; + return 1; +} + +static void sapbcode_set_salt(void *salt) +{ + memcpy(theSalt, salt, SALT_SIZE); +} + + +void strToUpper_B(char* str) +{ + int i=0; + if (NULL==str) + return; + for (i=0; i= 'a') && (str[i] <= 'z')) str[i] ^= 0x20; +} + + +static void sapbcode_set_key(char *key, int index) { + strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1); +} + +static char *sapbcode_get_key(int index) { + return saved_key; +} + +static int sapbcode_cmp_all(void *binary, int index) { + return !memcmp(binary, crypt_key, BINARY_SIZE); +} + +static int sapbcode_cmp_exact(char *source, int count){ + return 1; +} + +static int sapbcode_cmp_one(void * binary, int index) +{ + return sapbcode_cmp_all(binary, index); +} + + +/* + * this function is needed to determine the actual size of the salt (==username) + * theSalt has to point at the beginning of the actual salt. no more checks are done; relies on valid() + * this is needed because, afaik, john only supports salts w/ fixed length. sap uses the username, so we have to + * "strip" the padding (blanks at the end) for the calculation.... + * usernames w/ spaces at the end are not supported (SAP does not support them either) + */ +int calcActualSaltSize_B(char* theSalt) +{ + if (NULL==theSalt) + return 0; + int i=SALT_SIZE-1; + while (theSalt[i--]==0x20); + return i+2; +} + + +#define TEMP_ARRAY_SIZE 4*16 +static void sapbcode_crypt_all(int count) { + static unsigned char temp_key[BINARY_SIZE*2]; + static unsigned char final_key[BINARY_SIZE*2]; + static char username[SALT_SIZE+1], password[PLAINTEXT_LENGTH+1]; + static char unConverted[SALT_SIZE+1], pwConverted[PLAINTEXT_LENGTH+1]; + unsigned int i; + + //username: theSalt (we have to determine the right length...) + //password: saved_key + strnzcpy(username, theSalt, calcActualSaltSize_B(theSalt)+1); + strnzcpy(password, saved_key, PLAINTEXT_LENGTH+1); + + strToUpper_B(password); //only UPPERCASE passwords accepted for BCODE + + //transform... + for (i=0; i + do { + if (I1 + + MD5_Init(&ctx); + MD5_Update(&ctx, destArray, sum20); + MD5_Final(final_key, &ctx); + + for (i=0; i<8; i++) + crypt_key[i]=final_key[i+8]^final_key[i]; +} + +static void * sapbcode_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + char* newCiphertextPointer=&ciphertext[SALT_SIZE+1]; + + for(i=0;i +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "sha.h" + +#define FORMAT_LABEL "sapg" +#define FORMAT_NAME "SAP CODVN G (PASSCODE)" +#define ALGORITHM_NAME "sapg" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 48 /* netweaver 2004s limit */ + +#define BINARY_SIZE 20 +#define SALT_SIZE 40 /* the max username length */ +#define CIPHERTEXT_LENGTH SALT_SIZE + 1 + 40 /* SALT + $ + 2x20 bytes for SHA1-representation */ + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + + +static struct fmt_tests sapcodvng_tests[] = { + {"F $646A0AD270DF651065669A45D171EDD62DFE39A1", "X"}, + {"JOHNNY $7D79B478E70CAAE63C41E0824EAB644B9070D10A", "CYBERPUNK"}, + {"VAN $D15597367F24090F0A501962788E9F19B3604E73", "hauser"}, + {"ROOT $1194E38F14B9F3F8DA1B181F14DEB70E7BDCC239", "KID"}, + {"MAN $22886450D0AB90FDA7F91C4F3DD5619175B372EA", "u"}, + {"----------------------------------------$D594002761406B589A75CE86042A8B4A922AA74F", "-------"}, + {"SAP* $60A0F7E06D95BC9FB45F605BDF1F7B660E5D5D4E", "MaStEr"}, + {"DDIC $6066CD3147915331EC4C602847D27A75EB3E8F0A", "DDIC"}, + {"DoLlAR$$$--- $E0180FD4542D8B6715E7D0D9EDE7E2D2E40C3D4D", "Dollar$$$---"}, + {NULL} +}; + +static char saved_key[PLAINTEXT_LENGTH + 1]; +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static SHA_CTX ctx; + +static char theSalt[SALT_SIZE]; + +static int sapcodvng_valid(char *ciphertext) +{ + int i; + if (NULL==ciphertext) + return 0; + + if (ciphertext[SALT_SIZE]!='$') + return 0; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + + for (i = SALT_SIZE+1; i < CIPHERTEXT_LENGTH; i++){ + if (!( + (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) + || (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')) + )) + return 0; + } + + return 1; +} + +static void sapcodvng_set_salt(void *salt) +{ + memcpy(theSalt, salt, SALT_SIZE); +} + +static void *sapcodvng_get_salt(char *ciphertext) +{ + static unsigned char sssalt[SALT_SIZE]; + memcpy(sssalt, ciphertext, SALT_SIZE); + return sssalt; +} + +static void sapcodvng_init(void) +{ } + +static void sapcodvng_set_key(char *key, int index) +{ + strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1); +} + +static char *sapcodvng_get_key(int index) { + return saved_key; +} + +static int sapcodvng_cmp_all(void *binary, int index) { + return !memcmp(binary, crypt_key, BINARY_SIZE); +} + +static int sapcodvng_cmp_exact(char *source, int count){ + return (1); +} + +static int sapcodvng_cmp_one(void * binary, int index) +{ + return sapcodvng_cmp_all(binary, index); +} + + +/* + * this function is needed to determine the actual size of the salt (==username) + * theSalt has to point at the beginning of the actual salt. no more checks are done; relies on valid() + * this is needed because, afaik, john only supports salts w/ fixed length. sap uses the username, so we have to + * "strip" the padding (blanks at the end) for the calculation.... + * usernames w/ spaces at the end are not supported (SAP does not support them either) + */ +int calcActualSaltSize_G(char* theSalt) +{ + if (NULL==theSalt) + return 0; + int i=SALT_SIZE-1; + while (theSalt[i--]==0x20); + return SALT_SIZE-(SALT_SIZE-i)+2; +} + +/* + * calculate the length of data that has to be hashed from the magic array. pass the first hash result in here. + * this is part of the walld0rf-magic + */ +unsigned int extractLengthOfMagicArray(unsigned char *pbHashArray) +{ + unsigned int modSum=0, i; + + for (i=0; i<=9; i++) + modSum+=pbHashArray[i]%6; + + return modSum+0x20; //0x20 is hardcoded... +} + +/* + * Calculate the offset into the magic array. pass the first hash result in here + * part of the walld0rf-magic + */ +unsigned int extractOffsetToMagicArray(unsigned char *pbHashArray) +{ + unsigned int modSum=0, i; + + for (i=19; i>=10; i--) + modSum+=pbHashArray[i]%8; + + return modSum; +} + +/* + * used to alter the username which is always(!) uppercase... + */ +void strToUpper_G(char* str) +{ + int i=0; + if (NULL==str) + return; + for (i=0; i= 'a') && (str[i] <= 'z')) str[i] ^= 0x20; +} + +/* + * translation for passwords (chars >7bit ascii). + * translates just some >7bit chars to some weird magic bytes (not unicode?!) + * works for most west-european (e.g. french) passwords... + */ +static char* translatePassword(char* origPassword) +{ + static char password[PLAINTEXT_LENGTH*2]; + unsigned int j=0, i; + + for (i=0; i sha1($password+$partOfMagicArray+$username) --> this is CODVNG passcode... + memcpy(secondHashData, trPassword, pwLen); + memcpy(secondHashData+pwLen, &theMagicArray[offsetMagicArray], lengthIntoMagicArray); + memcpy(secondHashData+pwLen+lengthIntoMagicArray, theSalt, unLen+1); + secondHashDataLen=pwLen+lengthIntoMagicArray+unLen; + + SHA1_Init(&ctx); + SHA1_Update(&ctx, secondHashData, secondHashDataLen); + SHA1_Final((unsigned char*)crypt_key, &ctx); + +} + +static void * sapcodvng_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + char* newCiphertextPointer=&ciphertext[SALT_SIZE+1]; + + for(i=0;i + +#ifdef MMX_COEF +extern int shammx(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3))); +extern int shammx_nosizeupdate(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3))); +extern int shammx_noinit_uniformsizeupdate(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3))); +#endif + +#endif diff -urpN john-1.7.3.4.orig/src/sha1-mmx.S john-1.7.3.4/src/sha1-mmx.S --- john-1.7.3.4.orig/src/sha1-mmx.S 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/sha1-mmx.S 2009-09-20 22:34:31 +0000 @@ -0,0 +1,564 @@ + +// extern int mdfourmmx(unsigned char *out, unsigned char *in, int n) __attribute__((regparm(3))); + +#include "arch.h" +#ifdef UNDERSCORES +#define shammx _shammx +#define shammx_nosizeupdate _shammx_nosizeupdate +#define shammx_noinit_uniformsizeupdate _shammx_noinit_uniformsizeupdate +#endif + +.globl shammx; +.globl shammx_nosizeupdate; +.globl shammx_noinit_uniformsizeupdate; + +.data +.align(2*MMX_COEF) +const_init_a: +.long 0x67452301 +.long 0x67452301 +#if (MMX_COEF>=4) +.long 0x67452301 +.long 0x67452301 +#endif +const_init_b: +.long 0xefcdab89 +.long 0xefcdab89 +#if (MMX_COEF>=4) +.long 0xefcdab89 +.long 0xefcdab89 +#endif +const_init_c: +.long 0x98badcfe +.long 0x98badcfe +#if (MMX_COEF>=4) +.long 0x98badcfe +.long 0x98badcfe +#endif +const_init_d: +.long 0x10325476 +.long 0x10325476 +#if (MMX_COEF>=4) +.long 0x10325476 +.long 0x10325476 +#endif +const_init_e: +.long 0xc3d2e1f0 +.long 0xc3d2e1f0 +#if (MMX_COEF>=4) +.long 0xc3d2e1f0 +.long 0xc3d2e1f0 +#endif + +.align(2*MMX_COEF) +const_stage0: +.long 0x5a827999 +.long 0x5a827999 +#if (MMX_COEF>=4) +.long 0x5a827999 +.long 0x5a827999 +#endif +const_stage1: +.long 0x6ed9eba1 +.long 0x6ed9eba1 +#if (MMX_COEF>=4) +.long 0x6ed9eba1 +.long 0x6ed9eba1 +#endif +const_stage2: +.long 0x8f1bbcdc +.long 0x8f1bbcdc +#if (MMX_COEF>=4) +.long 0x8f1bbcdc +.long 0x8f1bbcdc +#endif +const_stage3: +.long 0xca62c1d6 +.long 0xca62c1d6 +#if (MMX_COEF>=4) +.long 0xca62c1d6 +.long 0xca62c1d6 +#endif + +.align(2*MMX_COEF) +mask0f0f: +.long 0x00ff00ff +.long 0x00ff00ff +#if (MMX_COEF>=4) +.long 0x00ff00ff +.long 0x00ff00ff +#endif +maskf0f0: +.long 0xff00ff00 +.long 0xff00ff00 +#if (MMX_COEF>=4) +.long 0xff00ff00 +.long 0xff00ff00 +#endif + +#if (MMX_COEF == 2) +#define MMXMOVE movq +#define REGMM0 %mm0 +#define REGMM1 %mm1 +#define REGMM2 %mm2 +#define REGMM3 %mm3 +#define REGMM4 %mm4 +#define REGMM5 %mm5 +#define REGMM6 %mm6 +#define REGMM7 %mm7 +storea: ; .long 0 ; .long 0 +storeb: ; .long 0 ; .long 0 +storec: ; .long 0 ; .long 0 +stored: ; .long 0 ; .long 0 +storee: ; .long 0 ; .long 0 +#else +#define MMXMOVE movapd +#define REGMM0 %xmm0 +#define REGMM1 %xmm1 +#define REGMM2 %xmm2 +#define REGMM3 %xmm3 +#define REGMM4 %xmm4 +#define REGMM5 %xmm5 +#define REGMM6 %xmm6 +#define REGMM7 %xmm7 +storea: ; .long 0 ; .long 0 ; .long 0 ; .long 0 +storeb: ; .long 0 ; .long 0 ; .long 0 ; .long 0 +storec: ; .long 0 ; .long 0 ; .long 0 ; .long 0 +stored: ; .long 0 ; .long 0 ; .long 0 ; .long 0 +storee: ; .long 0 ; .long 0 ; .long 0 ; .long 0 +#endif + +#define ctxa REGMM0 +#define ctxb REGMM1 +#define ctxc REGMM2 +#define ctxd REGMM3 +#define ctxe REGMM4 +#define tmp1 REGMM5 +#define tmp2 REGMM6 +#define tmp3 REGMM7 + +//ft(x,y,z) = (x AND y) OR ((NOT x) AND z) ( 0 <= t <= 19) +#define F0(x,y,z) \ + MMXMOVE x, tmp2; \ + MMXMOVE x, tmp1; \ + pand y, tmp2; \ + pandn z, tmp1; \ + por tmp2, tmp1; + +//ft(x,y,z) = x XOR y XOR z (20 <= t <= 39) +#define F1(x,y,z) \ + MMXMOVE z, tmp1; \ + pxor y, tmp1; \ + pxor x, tmp1 + +//ft(x,y,z) = (x AND y) OR (x AND z) OR (y AND z) (40 <= t <= 59) +//ft(x,y,z) = (x AND y) | ((x OR y) AND z) (40 <= t <= 59) +#define F2(x,y,z) \ + MMXMOVE x, tmp1; \ + MMXMOVE x, tmp2; \ + pand y, tmp1; \ + por y, tmp2; \ + pand z, tmp2; \ + por tmp2, tmp1; + +//ft(x,y,z) = x XOR y XOR z (60 <= t <= 79). = la seconde + + +#define expand(t) \ + MMXMOVE ((t-3)*4*MMX_COEF)(%edx), tmp1; \ + pxor ((t-8)*4*MMX_COEF)(%edx), tmp1; \ + pxor ((t-14)*4*MMX_COEF)(%edx), tmp1; \ + pxor ((t-16)*4*MMX_COEF)(%edx), tmp1; \ + MMXMOVE tmp1, tmp2; \ + pslld $1, tmp1; \ + psrld $31, tmp2; \ + por tmp2, tmp1; \ + MMXMOVE tmp1, (t*4*MMX_COEF)(%edx) + +#define subRound(a, b, c, d, e, f, k, data) \ + f(b,c,d); \ + MMXMOVE a, tmp2; \ + MMXMOVE a, tmp3; \ + paddd tmp1, e; \ + pslld $5, tmp2; \ + psrld $27, tmp3; \ + por tmp3, tmp2; \ + paddd tmp2, e; \ + MMXMOVE b, tmp2; \ + pslld $30, b; \ + paddd k, e; \ + paddd (data*4*MMX_COEF)(%edx), e; \ + psrld $2, tmp2; \ + por tmp2, b; + +#define subRoundu(a, b, c, d, e, f, k, data) \ + expand(data); \ + paddd tmp1, e; \ + f(b,c,d); \ + MMXMOVE a, tmp2; \ + MMXMOVE a, tmp3; \ + paddd tmp1, e; \ + pslld $5, tmp2; \ + psrld $27, tmp3; \ + por tmp3, tmp2; \ + paddd tmp2, e; \ + MMXMOVE b, tmp2; \ + pslld $30, b; \ + paddd k, e; \ + psrld $2, tmp2; \ + por tmp2, b; + +.text +/* + * Try to do some asm md4 w/ mmx + * %eax ptr -> out + * %edx ptr -> in (80*MMX_WIDTH mots) + * %ecx n + */ + +init_ctx: + MMXMOVE const_init_a, ctxa + MMXMOVE const_init_b, ctxb + MMXMOVE const_init_c, ctxc + MMXMOVE const_init_d, ctxd + MMXMOVE const_init_e, ctxe + ret + +sizeupdate: + //MD4 Init +#if (MMX_COEF == 2) + shl $3, %ecx + mov %ecx, %ebx + and $0xffff, %ecx + shrl $16, %ebx + // %ecx contient la taille du premier mdp + // %edx celle du second + mov %ecx, (15*4*MMX_COEF)(%edx) + mov %ebx, (15*4*MMX_COEF+4)(%edx) +#else + mov %ecx, %ebx + shr $8, %ecx + and $0xff, %ebx + shl $3, %ebx + mov %ebx, (15*16)(%edx) + + mov %ecx, %ebx + shr $8, %ecx + and $0xff, %ebx + shl $3, %ebx + mov %ebx, (15*16+4)(%edx) + + mov %ecx, %ebx + shr $8, %ecx + and $0xff, %ebx + shl $3, %ebx + mov %ebx, (15*16+8)(%edx) + + and $0xff, %ecx + shl $3, %ecx + mov %ecx, (15*16+12)(%edx) +#endif + ret + + +uniformsizeupdate: + shl $3, %ecx + mov %ecx, (14*4*MMX_COEF)(%edx) + mov %ecx, (14*4*MMX_COEF+4)(%edx) +#if (MMX_COEF == 4) + mov %ecx, (14*4*MMX_COEF+8)(%edx) + mov %ecx, (14*4*MMX_COEF+12)(%edx) +#endif + ret + + +shammx_noinit_sizeupdate: + pusha + call sizeupdate + jmp shammx_noinit + +shammx_noinit_uniformsizeupdate: + pusha + call uniformsizeupdate + jmp shammx_noinit + +shammx: + pusha + call sizeupdate + call init_ctx + jmp shammx_noinit + +shammx_nosizeupdate: + pusha + call init_ctx + jmp shammx_noinit + +shammx_noinit: + MMXMOVE ctxa, storea + MMXMOVE ctxb, storeb + MMXMOVE ctxc, storec + MMXMOVE ctxd, stored + MMXMOVE ctxe, storee + +round0: + prefetchnta (%edx) + subRound( ctxa, ctxb, ctxc, ctxd, ctxe, F0, const_stage0, 0 ); + subRound( ctxe, ctxa, ctxb, ctxc, ctxd, F0, const_stage0, 1 ); + subRound( ctxd, ctxe, ctxa, ctxb, ctxc, F0, const_stage0, 2 ); + subRound( ctxc, ctxd, ctxe, ctxa, ctxb, F0, const_stage0, 3 ); + subRound( ctxb, ctxc, ctxd, ctxe, ctxa, F0, const_stage0, 4 ); + subRound( ctxa, ctxb, ctxc, ctxd, ctxe, F0, const_stage0, 5 ); + subRound( ctxe, ctxa, ctxb, ctxc, ctxd, F0, const_stage0, 6 ); + subRound( ctxd, ctxe, ctxa, ctxb, ctxc, F0, const_stage0, 7 ); + subRound( ctxc, ctxd, ctxe, ctxa, ctxb, F0, const_stage0, 8 ); + subRound( ctxb, ctxc, ctxd, ctxe, ctxa, F0, const_stage0, 9 ); + subRound( ctxa, ctxb, ctxc, ctxd, ctxe, F0, const_stage0, 10 ); + subRound( ctxe, ctxa, ctxb, ctxc, ctxd, F0, const_stage0, 11 ); + subRound( ctxd, ctxe, ctxa, ctxb, ctxc, F0, const_stage0, 12 ); + subRound( ctxc, ctxd, ctxe, ctxa, ctxb, F0, const_stage0, 13 ); + subRound( ctxb, ctxc, ctxd, ctxe, ctxa, F0, const_stage0, 14 ); + subRound( ctxa, ctxb, ctxc, ctxd, ctxe, F0, const_stage0, 15 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F0, const_stage0, 16 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F0, const_stage0, 17 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F0, const_stage0, 18 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F0, const_stage0, 19 ); + +round1: + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F1, const_stage1, 20 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F1, const_stage1, 21 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F1, const_stage1, 22 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F1, const_stage1, 23 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F1, const_stage1, 24 ); + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F1, const_stage1, 25 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F1, const_stage1, 26 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F1, const_stage1, 27 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F1, const_stage1, 28 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F1, const_stage1, 29 ); + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F1, const_stage1, 30 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F1, const_stage1, 31 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F1, const_stage1, 32 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F1, const_stage1, 33 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F1, const_stage1, 34 ); + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F1, const_stage1, 35 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F1, const_stage1, 36 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F1, const_stage1, 37 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F1, const_stage1, 38 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F1, const_stage1, 39 ); + +round2: + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F2, const_stage2, 40 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F2, const_stage2, 41 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F2, const_stage2, 42 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F2, const_stage2, 43 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F2, const_stage2, 44 ); + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F2, const_stage2, 45 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F2, const_stage2, 46 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F2, const_stage2, 47 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F2, const_stage2, 48 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F2, const_stage2, 49 ); + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F2, const_stage2, 50 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F2, const_stage2, 51 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F2, const_stage2, 52 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F2, const_stage2, 53 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F2, const_stage2, 54 ); + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F2, const_stage2, 55 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F2, const_stage2, 56 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F2, const_stage2, 57 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F2, const_stage2, 58 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F2, const_stage2, 59 ); + +round3: + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F1, const_stage3, 60 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F1, const_stage3, 61 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F1, const_stage3, 62 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F1, const_stage3, 63 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F1, const_stage3, 64 ); + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F1, const_stage3, 65 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F1, const_stage3, 66 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F1, const_stage3, 67 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F1, const_stage3, 68 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F1, const_stage3, 69 ); + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F1, const_stage3, 70 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F1, const_stage3, 71 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F1, const_stage3, 72 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F1, const_stage3, 73 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F1, const_stage3, 74 ); + subRoundu( ctxa, ctxb, ctxc, ctxd, ctxe, F1, const_stage3, 75 ); + subRoundu( ctxe, ctxa, ctxb, ctxc, ctxd, F1, const_stage3, 76 ); + subRoundu( ctxd, ctxe, ctxa, ctxb, ctxc, F1, const_stage3, 77 ); + subRoundu( ctxc, ctxd, ctxe, ctxa, ctxb, F1, const_stage3, 78 ); + subRoundu( ctxb, ctxc, ctxd, ctxe, ctxa, F1, const_stage3, 79 ); + + paddd storea, ctxa + paddd storeb, ctxb + paddd storec, ctxc + paddd stored, ctxd + paddd storee, ctxe + MMXMOVE ctxa, storea + MMXMOVE ctxb, storeb + MMXMOVE ctxc, storec + MMXMOVE ctxd, stored + MMXMOVE ctxe, storee + jmp endianity + +endianity: + +//reverse indianity w/ rotate & and +//mmx has no rotate instructions .. +#define ENDIAN(a) \ + MMXMOVE a, tmp1; \ + MMXMOVE maskf0f0, tmp3; \ + pand tmp3, a; \ + MMXMOVE mask0f0f, tmp3; \ + pand tmp3, tmp1; \ + psrld $8, a; \ + pslld $8, tmp1; \ + por tmp1, a; \ + MMXMOVE a, tmp1; \ + psrld $16, a; \ + pslld $16, tmp1; \ + por tmp1, a + +// why is this so slow ? +#define ENDIAN2(a) \ + pshuflw $177,a,a; \ + pshufhw $177,a,a; \ + movq a,tmp1; \ + pand maskf0f0, a; \ + pand mask0f0f, tmp1; \ + psrld $8, a; \ + pslld $8, tmp1; \ + por tmp1, a + +//changes indianity ... + MMXMOVE maskf0f0, tmp3 + MMXMOVE ctxa, tmp1 + MMXMOVE ctxb, tmp2 + pand tmp3, ctxa + pand tmp3, ctxb + MMXMOVE mask0f0f, tmp3 + pand tmp3, tmp1 + pand tmp3, tmp2 + psrld $8, ctxa + psrld $8, ctxb + pslld $8, tmp1 + pslld $8, tmp2 + por tmp1, ctxa + por tmp2, ctxb + MMXMOVE ctxa, tmp1 + MMXMOVE ctxb, tmp2 + psrld $16, ctxa + psrld $16, ctxb + pslld $16, tmp1 + pslld $16, tmp2 + por tmp1, ctxa + por tmp2, ctxb + MMXMOVE ctxa, 0(%eax) + MMXMOVE ctxb, 4*MMX_COEF(%eax) + + +//now 2 more register to play with .. +#define tmp4 ctxa +#define tmp5 ctxb + + MMXMOVE maskf0f0, tmp5 + MMXMOVE ctxc, tmp1 + MMXMOVE ctxd, tmp2 + MMXMOVE ctxe, tmp3 + pand tmp5, ctxc + pand tmp5, ctxd + pand tmp5, ctxe + MMXMOVE mask0f0f, tmp5 + pand tmp5, tmp1 + pand tmp5, tmp2 + pand tmp5, tmp3 + psrld $8, ctxc + psrld $8, ctxd + psrld $8, ctxe + pslld $8, tmp1 + pslld $8, tmp2 + pslld $8, tmp3 + por tmp1, ctxc + por tmp2, ctxd + por tmp3, ctxe + MMXMOVE ctxc, tmp1 + MMXMOVE ctxd, tmp2 + MMXMOVE ctxe, tmp3 + psrld $16, ctxc + psrld $16, ctxd + psrld $16, ctxe + pslld $16, tmp1 + pslld $16, tmp2 + pslld $16, tmp3 + por tmp1, ctxc + por tmp2, ctxd + por tmp3, ctxe + + MMXMOVE ctxc, 8*MMX_COEF(%eax) + MMXMOVE ctxd, 12*MMX_COEF(%eax) + MMXMOVE ctxe, 16*MMX_COEF(%eax) + + //mov %ecx, %eax + //movd ctxe, %eax + popa + emms + + ret + +/* + alternate endianity conversion + shouldn't be so slow ... + pshuflw $177, ctxa, ctxa + pshuflw $177, ctxb, ctxb + pshuflw $177, ctxc, ctxc + pshuflw $177, ctxd, ctxd + pshuflw $177, ctxe, ctxe + movq maskf0f0, tmp3 + pshufhw $177, ctxa, ctxa + pshufhw $177, ctxb, ctxb + pshufhw $177, ctxc, ctxc + pshufhw $177, ctxd, ctxd + pshufhw $177, ctxe, ctxe + movq ctxa, tmp1 + movq ctxb, tmp2 + pand tmp3, ctxa + pand tmp3, ctxb + movq mask0f0f, tmp3 + pand tmp3, tmp1 + pand tmp3, tmp2 + psrld $8, ctxa + psrld $8, ctxb + pslld $8, tmp1 + pslld $8, tmp2 + por tmp1, ctxa + por tmp2, ctxb + MMXMOVE ctxa, 0(%eax) + MMXMOVE ctxb, 4*MMX_COEF(%eax) + +//now 2 more register to play with .. +#define tmp4 ctxa +#define tmp5 ctxb + movq ctxc, tmp1 + movq ctxd, tmp2 + movq ctxe, tmp4 + pand tmp3, tmp1 + pand tmp3, tmp2 + pand tmp3, tmp4 + movq maskf0f0, tmp3 + pand tmp3, ctxc + pand tmp3, ctxd + pand tmp3, ctxe + psrld $8, ctxc + psrld $8, ctxd + psrld $8, ctxe + pslld $8, tmp1 + pslld $8, tmp2 + pslld $8, tmp4 + por tmp1, ctxc + por tmp2, ctxd + por tmp4, ctxe +*/ + +#if defined(__ELF__) && defined(__linux__) +.section .note.GNU-stack,"",@progbits +#endif diff -urpN john-1.7.3.4.orig/src/smbencrypt.c john-1.7.3.4/src/smbencrypt.c --- john-1.7.3.4.orig/src/smbencrypt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/smbencrypt.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,108 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB parameters and setup + Copyright (C) Andrew Tridgell 1992-1998 + Modified by Jeremy Allison 1995. + (and hacked further by others) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include +#include + + +#ifndef uchar +#define uchar unsigned char +#endif + +#if !defined(uint16) && !defined(HAVE_UINT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define uint16 unsigned short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#if !defined(int16) && !defined(HAVE_INT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define int16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define int16 short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#include "byteorder.h" + +#include "md4.h" + +/* Routines for Windows NT MD4 Hash functions. */ +static int _my_wcslen(int16 *str) +{ + int len = 0; + while(*str++ != 0) + len++; + return len; +} + +/* + * Convert a string into an NT UNICODE string. + * Note that regardless of processor type + * this must be in intel (little-endian) + * format. + */ + +int _my_mbstowcs(int16 *dst, uchar *src, int len) +{ + int i; + int16 val; + + for(i = 0; i < len; i++) { + val = *src; + SSVAL(dst,0,val); + dst++; + src++; + if(val == 0) + break; + } + return i; +} + +/* + * Creates the MD4 Hash of the users password in NT UNICODE. + */ + +void E_md4hash(uchar *passwd, uchar *p16) +{ + int len; + int16 wpwd[129]; + MD4_CTX ctx; + + /* Password cannot be longer than 128 characters */ + len = strlen((char *)passwd); + if(len > 128) + len = 128; + /* Password must be converted to NT unicode */ + _my_mbstowcs(wpwd, passwd, len); + wpwd[len] = 0; /* Ensure string is null terminated */ + /* Calculate length in bytes */ + len = _my_wcslen(wpwd) * sizeof(int16); + + MD4_Init(&ctx); + MD4_Update(&ctx, (unsigned char *)wpwd, len); + MD4_Final(p16, &ctx); +} diff -urpN john-1.7.3.4.orig/src/stages_mmx_md5.S john-1.7.3.4/src/stages_mmx_md5.S --- john-1.7.3.4.orig/src/stages_mmx_md5.S 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/stages_mmx_md5.S 2009-09-20 22:34:42 +0000 @@ -0,0 +1,196 @@ +const_stage_1: +.long 0xd76aa478 +.long 0xd76aa478 +const_stage_2: +.long 0xe8c7b756 +.long 0xe8c7b756 +const_stage_3: +.long 0x242070db +.long 0x242070db +const_stage_4: +.long 0xc1bdceee +.long 0xc1bdceee +const_stage_5: +.long 0xf57c0faf +.long 0xf57c0faf +const_stage_6: +.long 0x4787c62a +.long 0x4787c62a +const_stage_7: +.long 0xa8304613 +.long 0xa8304613 +const_stage_8: +.long 0xfd469501 +.long 0xfd469501 +const_stage_9: +.long 0x698098d8 +.long 0x698098d8 +const_stage_10: +.long 0x8b44f7af +.long 0x8b44f7af +const_stage_11: +.long 0xffff5bb1 +.long 0xffff5bb1 +const_stage_12: +.long 0x895cd7be +.long 0x895cd7be +const_stage_13: +.long 0x6b901122 +.long 0x6b901122 +const_stage_14: +.long 0xfd987193 +.long 0xfd987193 +const_stage_15: +.long 0xa679438e +.long 0xa679438e +const_stage_16: +.long 0x49b40821 +.long 0x49b40821 +const_stage_17: +.long 0xf61e2562 +.long 0xf61e2562 +const_stage_18: +.long 0xc040b340 +.long 0xc040b340 +const_stage_19: +.long 0x265e5a51 +.long 0x265e5a51 +const_stage_20: +.long 0xe9b6c7aa +.long 0xe9b6c7aa +const_stage_21: +.long 0xd62f105d +.long 0xd62f105d +const_stage_22: +.long 0x02441453 +.long 0x02441453 +const_stage_23: +.long 0xd8a1e681 +.long 0xd8a1e681 +const_stage_24: +.long 0xe7d3fbc8 +.long 0xe7d3fbc8 +const_stage_25: +.long 0x21e1cde6 +.long 0x21e1cde6 +const_stage_26: +.long 0xc33707d6 +.long 0xc33707d6 +const_stage_27: +.long 0xf4d50d87 +.long 0xf4d50d87 +const_stage_28: +.long 0x455a14ed +.long 0x455a14ed +const_stage_29: +.long 0xa9e3e905 +.long 0xa9e3e905 +const_stage_30: +.long 0xfcefa3f8 +.long 0xfcefa3f8 +const_stage_31: +.long 0x676f02d9 +.long 0x676f02d9 +const_stage_32: +.long 0x8d2a4c8a +.long 0x8d2a4c8a +const_stage_33: +.long 0xfffa3942 +.long 0xfffa3942 +const_stage_34: +.long 0x8771f681 +.long 0x8771f681 +const_stage_35: +.long 0x6d9d6122 +.long 0x6d9d6122 +const_stage_36: +.long 0xfde5380c +.long 0xfde5380c +const_stage_37: +.long 0xa4beea44 +.long 0xa4beea44 +const_stage_38: +.long 0x4bdecfa9 +.long 0x4bdecfa9 +const_stage_39: +.long 0xf6bb4b60 +.long 0xf6bb4b60 +const_stage_40: +.long 0xbebfbc70 +.long 0xbebfbc70 +const_stage_41: +.long 0x289b7ec6 +.long 0x289b7ec6 +const_stage_42: +.long 0xeaa127fa +.long 0xeaa127fa +const_stage_43: +.long 0xd4ef3085 +.long 0xd4ef3085 +const_stage_44: +.long 0x04881d05 +.long 0x04881d05 +const_stage_45: +.long 0xd9d4d039 +.long 0xd9d4d039 +const_stage_46: +.long 0xe6db99e5 +.long 0xe6db99e5 +const_stage_47: +.long 0x1fa27cf8 +.long 0x1fa27cf8 +const_stage_48: +.long 0xc4ac5665 +.long 0xc4ac5665 +const_stage_49: +.long 0xf4292244 +.long 0xf4292244 +const_stage_50: +.long 0x432aff97 +.long 0x432aff97 +const_stage_51: +.long 0xab9423a7 +.long 0xab9423a7 +const_stage_52: +.long 0xfc93a039 +.long 0xfc93a039 +const_stage_53: +.long 0x655b59c3 +.long 0x655b59c3 +const_stage_54: +.long 0x8f0ccc92 +.long 0x8f0ccc92 +const_stage_55: +.long 0xffeff47d +.long 0xffeff47d +const_stage_56: +.long 0x85845dd1 +.long 0x85845dd1 +const_stage_57: +.long 0x6fa87e4f +.long 0x6fa87e4f +const_stage_58: +.long 0xfe2ce6e0 +.long 0xfe2ce6e0 +const_stage_59: +.long 0xa3014314 +.long 0xa3014314 +const_stage_60: +.long 0x4e0811a1 +.long 0x4e0811a1 +const_stage_61: +.long 0xf7537e82 +.long 0xf7537e82 +const_stage_62: +.long 0xbd3af235 +.long 0xbd3af235 +const_stage_63: +.long 0x2ad7d2bb +.long 0x2ad7d2bb +const_stage_64: +.long 0xeb86d391 +.long 0xeb86d391 + +#if defined(__ELF__) && defined(__linux__) +.section .note.GNU-stack,"",@progbits +#endif diff -urpN john-1.7.3.4.orig/src/stages_sse2_md5.S john-1.7.3.4/src/stages_sse2_md5.S --- john-1.7.3.4.orig/src/stages_sse2_md5.S 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/stages_sse2_md5.S 2009-09-20 22:34:46 +0000 @@ -0,0 +1,324 @@ +const_stage_1: +.long 0xd76aa478 +.long 0xd76aa478 +.long 0xd76aa478 +.long 0xd76aa478 +const_stage_2: +.long 0xe8c7b756 +.long 0xe8c7b756 +.long 0xe8c7b756 +.long 0xe8c7b756 +const_stage_3: +.long 0x242070db +.long 0x242070db +.long 0x242070db +.long 0x242070db +const_stage_4: +.long 0xc1bdceee +.long 0xc1bdceee +.long 0xc1bdceee +.long 0xc1bdceee +const_stage_5: +.long 0xf57c0faf +.long 0xf57c0faf +.long 0xf57c0faf +.long 0xf57c0faf +const_stage_6: +.long 0x4787c62a +.long 0x4787c62a +.long 0x4787c62a +.long 0x4787c62a +const_stage_7: +.long 0xa8304613 +.long 0xa8304613 +.long 0xa8304613 +.long 0xa8304613 +const_stage_8: +.long 0xfd469501 +.long 0xfd469501 +.long 0xfd469501 +.long 0xfd469501 +const_stage_9: +.long 0x698098d8 +.long 0x698098d8 +.long 0x698098d8 +.long 0x698098d8 +const_stage_10: +.long 0x8b44f7af +.long 0x8b44f7af +.long 0x8b44f7af +.long 0x8b44f7af +const_stage_11: +.long 0xffff5bb1 +.long 0xffff5bb1 +.long 0xffff5bb1 +.long 0xffff5bb1 +const_stage_12: +.long 0x895cd7be +.long 0x895cd7be +.long 0x895cd7be +.long 0x895cd7be +const_stage_13: +.long 0x6b901122 +.long 0x6b901122 +.long 0x6b901122 +.long 0x6b901122 +const_stage_14: +.long 0xfd987193 +.long 0xfd987193 +.long 0xfd987193 +.long 0xfd987193 +const_stage_15: +.long 0xa679438e +.long 0xa679438e +.long 0xa679438e +.long 0xa679438e +const_stage_16: +.long 0x49b40821 +.long 0x49b40821 +.long 0x49b40821 +.long 0x49b40821 +const_stage_17: +.long 0xf61e2562 +.long 0xf61e2562 +.long 0xf61e2562 +.long 0xf61e2562 +const_stage_18: +.long 0xc040b340 +.long 0xc040b340 +.long 0xc040b340 +.long 0xc040b340 +const_stage_19: +.long 0x265e5a51 +.long 0x265e5a51 +.long 0x265e5a51 +.long 0x265e5a51 +const_stage_20: +.long 0xe9b6c7aa +.long 0xe9b6c7aa +.long 0xe9b6c7aa +.long 0xe9b6c7aa +const_stage_21: +.long 0xd62f105d +.long 0xd62f105d +.long 0xd62f105d +.long 0xd62f105d +const_stage_22: +.long 0x02441453 +.long 0x02441453 +.long 0x02441453 +.long 0x02441453 +const_stage_23: +.long 0xd8a1e681 +.long 0xd8a1e681 +.long 0xd8a1e681 +.long 0xd8a1e681 +const_stage_24: +.long 0xe7d3fbc8 +.long 0xe7d3fbc8 +.long 0xe7d3fbc8 +.long 0xe7d3fbc8 +const_stage_25: +.long 0x21e1cde6 +.long 0x21e1cde6 +.long 0x21e1cde6 +.long 0x21e1cde6 +const_stage_26: +.long 0xc33707d6 +.long 0xc33707d6 +.long 0xc33707d6 +.long 0xc33707d6 +const_stage_27: +.long 0xf4d50d87 +.long 0xf4d50d87 +.long 0xf4d50d87 +.long 0xf4d50d87 +const_stage_28: +.long 0x455a14ed +.long 0x455a14ed +.long 0x455a14ed +.long 0x455a14ed +const_stage_29: +.long 0xa9e3e905 +.long 0xa9e3e905 +.long 0xa9e3e905 +.long 0xa9e3e905 +const_stage_30: +.long 0xfcefa3f8 +.long 0xfcefa3f8 +.long 0xfcefa3f8 +.long 0xfcefa3f8 +const_stage_31: +.long 0x676f02d9 +.long 0x676f02d9 +.long 0x676f02d9 +.long 0x676f02d9 +const_stage_32: +.long 0x8d2a4c8a +.long 0x8d2a4c8a +.long 0x8d2a4c8a +.long 0x8d2a4c8a +const_stage_33: +.long 0xfffa3942 +.long 0xfffa3942 +.long 0xfffa3942 +.long 0xfffa3942 +const_stage_34: +.long 0x8771f681 +.long 0x8771f681 +.long 0x8771f681 +.long 0x8771f681 +const_stage_35: +.long 0x6d9d6122 +.long 0x6d9d6122 +.long 0x6d9d6122 +.long 0x6d9d6122 +const_stage_36: +.long 0xfde5380c +.long 0xfde5380c +.long 0xfde5380c +.long 0xfde5380c +const_stage_37: +.long 0xa4beea44 +.long 0xa4beea44 +.long 0xa4beea44 +.long 0xa4beea44 +const_stage_38: +.long 0x4bdecfa9 +.long 0x4bdecfa9 +.long 0x4bdecfa9 +.long 0x4bdecfa9 +const_stage_39: +.long 0xf6bb4b60 +.long 0xf6bb4b60 +.long 0xf6bb4b60 +.long 0xf6bb4b60 +const_stage_40: +.long 0xbebfbc70 +.long 0xbebfbc70 +.long 0xbebfbc70 +.long 0xbebfbc70 +const_stage_41: +.long 0x289b7ec6 +.long 0x289b7ec6 +.long 0x289b7ec6 +.long 0x289b7ec6 +const_stage_42: +.long 0xeaa127fa +.long 0xeaa127fa +.long 0xeaa127fa +.long 0xeaa127fa +const_stage_43: +.long 0xd4ef3085 +.long 0xd4ef3085 +.long 0xd4ef3085 +.long 0xd4ef3085 +const_stage_44: +.long 0x04881d05 +.long 0x04881d05 +.long 0x04881d05 +.long 0x04881d05 +const_stage_45: +.long 0xd9d4d039 +.long 0xd9d4d039 +.long 0xd9d4d039 +.long 0xd9d4d039 +const_stage_46: +.long 0xe6db99e5 +.long 0xe6db99e5 +.long 0xe6db99e5 +.long 0xe6db99e5 +const_stage_47: +.long 0x1fa27cf8 +.long 0x1fa27cf8 +.long 0x1fa27cf8 +.long 0x1fa27cf8 +const_stage_48: +.long 0xc4ac5665 +.long 0xc4ac5665 +.long 0xc4ac5665 +.long 0xc4ac5665 +const_stage_49: +.long 0xf4292244 +.long 0xf4292244 +.long 0xf4292244 +.long 0xf4292244 +const_stage_50: +.long 0x432aff97 +.long 0x432aff97 +.long 0x432aff97 +.long 0x432aff97 +const_stage_51: +.long 0xab9423a7 +.long 0xab9423a7 +.long 0xab9423a7 +.long 0xab9423a7 +const_stage_52: +.long 0xfc93a039 +.long 0xfc93a039 +.long 0xfc93a039 +.long 0xfc93a039 +const_stage_53: +.long 0x655b59c3 +.long 0x655b59c3 +.long 0x655b59c3 +.long 0x655b59c3 +const_stage_54: +.long 0x8f0ccc92 +.long 0x8f0ccc92 +.long 0x8f0ccc92 +.long 0x8f0ccc92 +const_stage_55: +.long 0xffeff47d +.long 0xffeff47d +.long 0xffeff47d +.long 0xffeff47d +const_stage_56: +.long 0x85845dd1 +.long 0x85845dd1 +.long 0x85845dd1 +.long 0x85845dd1 +const_stage_57: +.long 0x6fa87e4f +.long 0x6fa87e4f +.long 0x6fa87e4f +.long 0x6fa87e4f +const_stage_58: +.long 0xfe2ce6e0 +.long 0xfe2ce6e0 +.long 0xfe2ce6e0 +.long 0xfe2ce6e0 +const_stage_59: +.long 0xa3014314 +.long 0xa3014314 +.long 0xa3014314 +.long 0xa3014314 +const_stage_60: +.long 0x4e0811a1 +.long 0x4e0811a1 +.long 0x4e0811a1 +.long 0x4e0811a1 +const_stage_61: +.long 0xf7537e82 +.long 0xf7537e82 +.long 0xf7537e82 +.long 0xf7537e82 +const_stage_62: +.long 0xbd3af235 +.long 0xbd3af235 +.long 0xbd3af235 +.long 0xbd3af235 +const_stage_63: +.long 0x2ad7d2bb +.long 0x2ad7d2bb +.long 0x2ad7d2bb +.long 0x2ad7d2bb +const_stage_64: +.long 0xeb86d391 +.long 0xeb86d391 +.long 0xeb86d391 +.long 0xeb86d391 + +#if defined(__ELF__) && defined(__linux__) +.section .note.GNU-stack,"",@progbits +#endif diff -urpN john-1.7.3.4.orig/src/undrop.c john-1.7.3.4/src/undrop.c --- john-1.7.3.4.orig/src/undrop.c 1970-01-01 00:00:00 +0000 +++ john-1.7.3.4/src/undrop.c 2008-08-24 07:08:10 +0000 @@ -0,0 +1,73 @@ +/* + * Eggdrop userfile converter + * Copyright (c) 2002 by Sun-Zero + * This is a free software distributable under terms of the GNU GPL. + * See the file COPYING for details. + * + * 2003-04-21 +*/ + +#include +#include +#include + + +#define USERFILE_HEADER "#4v:" +#define USERNAME_LENGTH 11 +#define PASSWORD_LENGTH 13 +#define MAX_FLAGS_LENGTH 32 +#define BUFSIZE 512 + +int undrop(int argc, char *argv[]) { + + FILE *userfile; + char username[USERNAME_LENGTH]; + char password[PASSWORD_LENGTH]; + char flags[MAX_FLAGS_LENGTH]; + char t_username[BUFSIZE]; + char t_flags[BUFSIZE]; + char t_line[BUFSIZE]; + + if (argc != 2) { + userfile = stdin; + printf("# userfile reading from stdin\n"); + } else { + if ((userfile = fopen(argv[1], "rt")) == NULL) { + fprintf(stderr, "opening userfile\n"); + userfile = stdin; + } + } + + + if (fgets(t_line, sizeof(t_line) - 1, userfile) == NULL) + return 1; + + if (strncmp(t_line, USERFILE_HEADER, strlen(USERFILE_HEADER)) != 0) { + fprintf(stderr, "usefile format is wrong\n"); + return 1; + } else { + printf("# userfile format OK\n\n"); + } + + while (fgets(t_line, sizeof(t_line) - 1, userfile) != NULL) { + if (sscanf(t_line, "%10s - %24s\n", t_username, t_flags) == 2) { + if (strncmp(t_username, "! ", 2) != 0 && + strncmp(t_username, "--", 2) != 0 && + strncmp(t_username, "&&", 2) != 0 && + strncmp(t_username, "::", 2) != 0 && + strncmp(t_username, "$$", 2) != 0 + ) { + strncpy(username, t_username, USERNAME_LENGTH); + strncpy(flags, t_flags, MAX_FLAGS_LENGTH); + } + } + + if (strncmp(t_line, "--PASS +", 8) == 0) { + sscanf(t_line, "--PASS %s", password); + printf("%s:%s:::%s:\n", username, password, flags); + } + fflush(stdout); + } + fclose(userfile); + return 0; +} diff -urpN john-1.7.3.4.orig/src/x86-64.S john-1.7.3.4/src/x86-64.S --- john-1.7.3.4.orig/src/x86-64.S 2009-09-09 05:11:25 +0000 +++ john-1.7.3.4/src/x86-64.S 2009-09-20 22:31:53 +0000 @@ -1053,6 +1053,244 @@ DES_bs_crypt_LM_loop: jnz DES_bs_crypt_LM_loop ret + +/* The following is public domain code by Alain Espinosa */ +/* ...converted to use %rip-relative addressing, still public domain */ + +/* + * FIXME: this depends on the assembler being able to multiply, which won't + * work on Solaris (unless the use of GNU assembler is forced). + */ + +#ifdef UNDERSCORES +#define nt_crypt_all_x86_64 _nt_crypt_all_x86_64 +#define nt_buffer8x _nt_buffer8x +#define output8x _output8x +#endif + +/* +extern nt_crypt_all_x86_64(int count); +*/ + +.globl nt_crypt_all_x86_64 + +.data +DO_ALIGN(6) +const_init_a: +.long 0xFFFFFFFF +.long 0xFFFFFFFF +.long 0xFFFFFFFF +.long 0xFFFFFFFF +const_init_b: +.long 0xefcdab89 +.long 0xefcdab89 +.long 0xefcdab89 +.long 0xefcdab89 +const_init_c: +.long 0x98badcfe +.long 0x98badcfe +.long 0x98badcfe +.long 0x98badcfe +const_init_d: +.long 0x10325476 +.long 0x10325476 +.long 0x10325476 +.long 0x10325476 + +const_stage2: +.long 0x5a827999 +.long 0x5a827999 +.long 0x5a827999 +.long 0x5a827999 +const_stage3: +.long 0x6ed9eba1 +.long 0x6ed9eba1 +.long 0x6ed9eba1 +.long 0x6ed9eba1 + +#define a %xmm0 +#define b %xmm1 +#define c %xmm2 +#define d %xmm3 +#define t1 %xmm4 +#define t2 %xmm5 +#define t3 %xmm6 +#define t4 %xmm7 + +#undef a3 +#define a3 %xmm8 +#define b3 %xmm9 +#define c3 %xmm10 +#define d3 %xmm11 +#define t13 %xmm12 +#define t23 %xmm13 + +#define STEP1(aa, bb, cc, dd, aa3, bb3, cc3, dd3, x, s, base) \ + paddd (512*base)+(x*32)+nt_buffer8x(%rip), aa; \ + paddd (512*base)+(x*32)+16+nt_buffer8x(%rip), aa3; \ + movdqa cc, t1; \ + movdqa cc3, t13; \ + pxor dd, t1; \ + pxor dd3, t13; \ + pand bb, t1; \ + pand bb3, t13; \ + pxor dd, t1; \ + pxor dd3, t13; \ + paddd t1, aa; \ + paddd t13, aa3; \ + movdqa aa, t2; \ + movdqa aa3, t23; \ + pslld $s, aa; \ + pslld $s, aa3; \ + psrld $(32-s), t2; \ + psrld $(32-s), t23; \ + por t2, aa; \ + por t23, aa3; + +#define STEP2(aa, bb, cc, dd, aa3, bb3, cc3, dd3, x, s, base) \ + paddd (512*base)+(x*32)+nt_buffer8x(%rip), aa; \ + paddd (512*base)+(x*32)+16+nt_buffer8x(%rip), aa3; \ + movdqa cc, t1; \ + movdqa cc3, t13; \ + movdqa cc, t2; \ + movdqa cc3, t23; \ + por dd, t1; \ + por dd3, t13; \ + pand dd, t2; \ + pand dd3, t23; \ + pand bb, t1; \ + pand bb3, t13; \ + paddd t3, aa; \ + paddd t3, aa3; \ + por t2, t1; \ + por t23, t13; \ + paddd t1, aa; \ + paddd t13, aa3; \ + movdqa aa, t1; \ + movdqa aa3, t13; \ + pslld $s, aa; \ + pslld $s, aa3; \ + psrld $(32-s), t1; \ + psrld $(32-s), t13; \ + por t1, aa; \ + por t13, aa3; + +#define STEP3(aa, bb, cc, dd, aa3, bb3, cc3, dd3, x, s, base) \ + paddd (512*base)+(x*32)+nt_buffer8x(%rip), aa; \ + paddd (512*base)+(x*32)+16+nt_buffer8x(%rip), aa3; \ + movdqa dd, t1; \ + movdqa dd3, t13; \ + pxor cc, t1; \ + pxor cc3, t13; \ + paddd t4, aa; \ + paddd t4, aa3; \ + pxor bb, t1; \ + pxor bb3, t13; \ + paddd t1, aa; \ + paddd t13, aa3; \ + movdqa aa, t1; \ + movdqa aa3, t13; \ + pslld $s, aa; \ + pslld $s, aa3; \ + psrld $(32-s), t1; \ + psrld $(32-s), t13; \ + por t1, aa; \ + por t13, aa3; + +#define NT_CRYPT_BODY(base) \ + movdqa const_init_a(%rip), a; \ + movdqa const_init_a(%rip), a3; \ + movdqa const_init_b(%rip), b; \ + movdqa const_init_b(%rip), b3; \ + movdqa const_init_c(%rip), c; \ + movdqa const_init_c(%rip), c3; \ + movdqa const_init_d(%rip), d; \ + movdqa const_init_d(%rip), d3; \ + \ + paddd (512*base)+nt_buffer8x(%rip), a; \ + paddd (512*base)+16+nt_buffer8x(%rip), a3; \ + pslld $3, a; \ + pslld $3, a3; \ + \ + STEP1(d, a, b, c, d3, a3, b3, c3, 1 , 7 , base) \ + STEP1(c, d, a, b, c3, d3, a3, b3, 2 , 11, base) \ + STEP1(b, c, d, a, b3, c3, d3, a3, 3 , 19, base) \ + STEP1(a, b, c, d, a3, b3, c3, d3, 4 , 3 , base) \ + STEP1(d, a, b, c, d3, a3, b3, c3, 5 , 7 , base) \ + STEP1(c, d, a, b, c3, d3, a3, b3, 6 , 11, base) \ + STEP1(b, c, d, a, b3, c3, d3, a3, 7 , 19, base) \ + STEP1(a, b, c, d, a3, b3, c3, d3, 8 , 3 , base) \ + STEP1(d, a, b, c, d3, a3, b3, c3, 9 , 7 , base) \ + STEP1(c, d, a, b, c3, d3, a3, b3, 10, 11, base) \ + STEP1(b, c, d, a, b3, c3, d3, a3, 11, 19, base) \ + STEP1(a, b, c, d, a3, b3, c3, d3, 12, 3 , base) \ + STEP1(d, a, b, c, d3, a3, b3, c3, 13, 7 , base) \ + STEP1(c, d, a, b, c3, d3, a3, b3, 14, 11, base) \ + STEP1(b, c, d, a, b3, c3, d3, a3, 15, 19, base) \ + \ + STEP2(a, b, c, d, a3, b3, c3, d3, 0 , 3 , base) \ + STEP2(d, a, b, c, d3, a3, b3, c3, 4 , 5 , base) \ + STEP2(c, d, a, b, c3, d3, a3, b3, 8 , 9 , base) \ + STEP2(b, c, d, a, b3, c3, d3, a3, 12, 13, base) \ + STEP2(a, b, c, d, a3, b3, c3, d3, 1 , 3 , base) \ + STEP2(d, a, b, c, d3, a3, b3, c3, 5 , 5 , base) \ + STEP2(c, d, a, b, c3, d3, a3, b3, 9 , 9 , base) \ + STEP2(b, c, d, a, b3, c3, d3, a3, 13, 13, base) \ + STEP2(a, b, c, d, a3, b3, c3, d3, 2 , 3 , base) \ + STEP2(d, a, b, c, d3, a3, b3, c3, 6 , 5 , base) \ + STEP2(c, d, a, b, c3, d3, a3, b3, 10, 9 , base) \ + STEP2(b, c, d, a, b3, c3, d3, a3, 14, 13, base) \ + STEP2(a, b, c, d, a3, b3, c3, d3, 3 , 3 , base) \ + STEP2(d, a, b, c, d3, a3, b3, c3, 7 , 5 , base) \ + STEP2(c, d, a, b, c3, d3, a3, b3, 11, 9 , base) \ + STEP2(b, c, d, a, b3, c3, d3, a3, 15, 13, base) \ + \ + STEP3(a, b, c, d, a3, b3, c3, d3, 0 , 3 , base) \ + STEP3(d, a, b, c, d3, a3, b3, c3, 8 , 9 , base) \ + STEP3(c, d, a, b, c3, d3, a3, b3, 4 , 11, base) \ + STEP3(b, c, d, a, b3, c3, d3, a3, 12, 15, base) \ + STEP3(a, b, c, d, a3, b3, c3, d3, 2 , 3 , base) \ + STEP3(d, a, b, c, d3, a3, b3, c3, 10, 9 , base) \ + STEP3(c, d, a, b, c3, d3, a3, b3, 6 , 11, base) \ + STEP3(b, c, d, a, b3, c3, d3, a3, 14, 15, base) \ + STEP3(a, b, c, d, a3, b3, c3, d3, 1 , 3 , base) \ + STEP3(d, a, b, c, d3, a3, b3, c3, 9 , 9 , base) \ + STEP3(c, d, a, b, c3, d3, a3, b3, 5 , 11, base) \ + movdqa a, t1; \ + movdqa a3, t13; \ + paddd (512*base)+416+nt_buffer8x(%rip), b; \ + paddd (512*base)+416+16+nt_buffer8x(%rip), b3; \ + pxor d, t1; \ + pxor d3,t13; \ + pxor c, t1; \ + pxor c3,t13; \ + paddd t1, b; \ + paddd t13,b3; \ + \ + movdqa a, (128*base)+output8x(%rip); \ + movdqa a3, (128*base)+16+output8x(%rip); \ + movdqa b, (128*base)+32+output8x(%rip); \ + movdqa b3, (128*base)+32+16+output8x(%rip); \ + movdqa c, (128*base)+64+output8x(%rip); \ + movdqa c3, (128*base)+64+16+output8x(%rip); \ + movdqa d, (128*base)+96+output8x(%rip); \ + movdqa d3, (128*base)+96+16+output8x(%rip); + +.text + +DO_ALIGN(6) + +nt_crypt_all_x86_64: + movdqa const_stage2(%rip), t3 + movdqa const_stage3(%rip), t4 + + NT_CRYPT_BODY(0) + NT_CRYPT_BODY(1) + NT_CRYPT_BODY(2) + NT_CRYPT_BODY(3) + + ret + #if defined(__ELF__) && defined(__linux__) .section .note.GNU-stack,"",@progbits #endif diff -urpN john-1.7.3.4.orig/src/x86-64.h john-1.7.3.4/src/x86-64.h --- john-1.7.3.4.orig/src/x86-64.h 2008-06-22 01:29:02 +0000 +++ john-1.7.3.4/src/x86-64.h 2008-08-24 04:59:02 +0000 @@ -46,4 +46,6 @@ #define BF_SCALE 1 #define BF_X2 1 +#define NT_X86_64 + #endif diff -urpN john-1.7.3.4.orig/src/x86-mmx.h john-1.7.3.4/src/x86-mmx.h --- john-1.7.3.4.orig/src/x86-mmx.h 2008-06-22 01:55:13 +0000 +++ john-1.7.3.4/src/x86-mmx.h 2008-08-24 05:21:51 +0000 @@ -59,4 +59,7 @@ #define BF_SCALE 1 #define BF_X2 0 +#define MMX_TYPE " MMX" +#define MMX_COEF 2 + #endif diff -urpN john-1.7.3.4.orig/src/x86-sse.S john-1.7.3.4/src/x86-sse.S --- john-1.7.3.4.orig/src/x86-sse.S 2009-09-09 05:11:31 +0000 +++ john-1.7.3.4/src/x86-sse.S 2009-09-20 22:32:45 +0000 @@ -1302,6 +1302,246 @@ DES_bs_crypt_LM_loop: popl %esi ret + +/* The following is public domain code by Alain Espinosa */ + +/* + * FIXME: this depends on the assembler being able to multiply, which won't + * work on Solaris (unless the use of GNU assembler is forced). + */ + +#ifdef UNDERSCORES +#define nt_crypt_all_sse2 _nt_crypt_all_sse2 +#define nt_buffer1x _nt_buffer1x +#define nt_buffer4x _nt_buffer4x +#define output1x _output1x +#define output4x _output4x +#endif + +/* +extern nt_crypt_all_sse2(int count); +*/ + +.globl nt_crypt_all_sse2 + +.data +DO_ALIGN(6) +const_init_a: +.long 0xFFFFFFFF +.long 0xFFFFFFFF +.long 0xFFFFFFFF +.long 0xFFFFFFFF +const_init_b: +.long 0xefcdab89 +.long 0xefcdab89 +.long 0xefcdab89 +.long 0xefcdab89 +const_init_c: +.long 0x98badcfe +.long 0x98badcfe +.long 0x98badcfe +.long 0x98badcfe +const_init_d: +.long 0x10325476 +.long 0x10325476 +.long 0x10325476 +.long 0x10325476 + +const_stage2: +.long 0x5a827999 +.long 0x5a827999 +.long 0x5a827999 +.long 0x5a827999 +const_stage3: +.long 0x6ed9eba1 +.long 0x6ed9eba1 +.long 0x6ed9eba1 +.long 0x6ed9eba1 + +#define a %xmm0 +#define b %xmm1 +#define c %xmm2 +#define d %xmm3 +#define t1 %xmm4 +#define t2 %xmm5 +#define t3 %xmm6 +#define t4 %xmm7 + +#undef a3 +#define a3 %eax +#define b3 %ebx +#define c3 %ecx +#define d3 %edx +#define t13 %esi +#define t23 %edi +#define Q2 $0x5a827999 +#define Q3 $0x6ed9eba1 + +#define STEP1(aa, bb, cc, dd, aa3, bb3, cc3, dd3, x, s, base) \ + paddd (256*base)+(x*16)+nt_buffer4x, aa; \ + addl (64*base)+(x*4)+nt_buffer1x, aa3; \ + movdqa cc, t1; \ + movl cc3, t13; \ + pxor dd, t1; \ + xorl dd3, t13; \ + pand bb, t1; \ + andl bb3, t13; \ + pxor dd, t1; \ + xorl dd3, t13; \ + paddd t1, aa; \ + addl t13, aa3; \ + movdqa aa, t2; \ + roll $s, aa3; \ + pslld $s, aa; \ + psrld $(32-s), t2; \ + por t2, aa; + +#define STEP2(aa, bb, cc, dd, aa3, bb3, cc3, dd3, x, s, base) \ + paddd (256*base)+(x*16)+nt_buffer4x, aa; \ + addl (64*base)+(x*4)+nt_buffer1x, aa3; \ + movdqa cc, t1; \ + movl cc3, t13; \ + movdqa cc, t2; \ + movl cc3, t23; \ + por dd, t1; \ + orl dd3, t13; \ + pand dd, t2; \ + andl dd3, t23; \ + pand bb, t1; \ + andl bb3, t13; \ + paddd t3, aa; \ + addl Q2, aa3; \ + por t2, t1; \ + orl t23, t13; \ + paddd t1, aa; \ + addl t13, aa3; \ + movdqa aa, t1; \ + roll $s, aa3; \ + pslld $s, aa; \ + psrld $(32-s), t1; \ + por t1, aa; + +#define STEP3(aa, bb, cc, dd, aa3, bb3, cc3, dd3, x, s, base) \ + paddd (256*base)+(x*16)+nt_buffer4x, aa; \ + addl (64*base)+(x*4)+nt_buffer1x, aa3; \ + movdqa dd, t1; \ + movl dd3, t13; \ + pxor cc, t1; \ + xorl cc3, t13; \ + paddd t4, aa; \ + addl Q3, aa3; \ + pxor bb, t1; \ + xorl bb3, t13; \ + paddd t1, aa; \ + addl t13, aa3; \ + movdqa aa, t1; \ + roll $s, aa3; \ + pslld $s, aa; \ + psrld $(32-s), t1; \ + por t1, aa; + +#define NT_CRYPT_BODY(base) \ + movdqa const_init_a, a; \ + movl const_init_a, a3; \ + movdqa const_init_b, b; \ + movl const_init_b, b3; \ + movdqa const_init_c, c; \ + movl const_init_c, c3; \ + movdqa const_init_d, d; \ + movl const_init_d, d3; \ + \ + paddd (256*base)+nt_buffer4x, a; \ + addl (64*base)+nt_buffer1x, a3; \ + pslld $3, a; \ + roll $3, a3; \ + \ + STEP1(d, a, b, c, d3, a3, b3, c3, 1 , 7 , base) \ + STEP1(c, d, a, b, c3, d3, a3, b3, 2 , 11, base) \ + STEP1(b, c, d, a, b3, c3, d3, a3, 3 , 19, base) \ + STEP1(a, b, c, d, a3, b3, c3, d3, 4 , 3 , base) \ + STEP1(d, a, b, c, d3, a3, b3, c3, 5 , 7 , base) \ + STEP1(c, d, a, b, c3, d3, a3, b3, 6 , 11, base) \ + STEP1(b, c, d, a, b3, c3, d3, a3, 7 , 19, base) \ + STEP1(a, b, c, d, a3, b3, c3, d3, 8 , 3 , base) \ + STEP1(d, a, b, c, d3, a3, b3, c3, 9 , 7 , base) \ + STEP1(c, d, a, b, c3, d3, a3, b3, 10, 11, base) \ + STEP1(b, c, d, a, b3, c3, d3, a3, 11, 19, base) \ + STEP1(a, b, c, d, a3, b3, c3, d3, 12, 3 , base) \ + STEP1(d, a, b, c, d3, a3, b3, c3, 13, 7 , base) \ + STEP1(c, d, a, b, c3, d3, a3, b3, 14, 11, base) \ + STEP1(b, c, d, a, b3, c3, d3, a3, 15, 19, base) \ + \ + STEP2(a, b, c, d, a3, b3, c3, d3, 0 , 3 , base) \ + STEP2(d, a, b, c, d3, a3, b3, c3, 4 , 5 , base) \ + STEP2(c, d, a, b, c3, d3, a3, b3, 8 , 9 , base) \ + STEP2(b, c, d, a, b3, c3, d3, a3, 12, 13, base) \ + STEP2(a, b, c, d, a3, b3, c3, d3, 1 , 3 , base) \ + STEP2(d, a, b, c, d3, a3, b3, c3, 5 , 5 , base) \ + STEP2(c, d, a, b, c3, d3, a3, b3, 9 , 9 , base) \ + STEP2(b, c, d, a, b3, c3, d3, a3, 13, 13, base) \ + STEP2(a, b, c, d, a3, b3, c3, d3, 2 , 3 , base) \ + STEP2(d, a, b, c, d3, a3, b3, c3, 6 , 5 , base) \ + STEP2(c, d, a, b, c3, d3, a3, b3, 10, 9 , base) \ + STEP2(b, c, d, a, b3, c3, d3, a3, 14, 13, base) \ + STEP2(a, b, c, d, a3, b3, c3, d3, 3 , 3 , base) \ + STEP2(d, a, b, c, d3, a3, b3, c3, 7 , 5 , base) \ + STEP2(c, d, a, b, c3, d3, a3, b3, 11, 9 , base) \ + STEP2(b, c, d, a, b3, c3, d3, a3, 15, 13, base) \ + \ + STEP3(a, b, c, d, a3, b3, c3, d3, 0 , 3 , base) \ + STEP3(d, a, b, c, d3, a3, b3, c3, 8 , 9 , base) \ + STEP3(c, d, a, b, c3, d3, a3, b3, 4 , 11, base) \ + STEP3(b, c, d, a, b3, c3, d3, a3, 12, 15, base) \ + STEP3(a, b, c, d, a3, b3, c3, d3, 2 , 3 , base) \ + STEP3(d, a, b, c, d3, a3, b3, c3, 10, 9 , base) \ + STEP3(c, d, a, b, c3, d3, a3, b3, 6 , 11, base) \ + STEP3(b, c, d, a, b3, c3, d3, a3, 14, 15, base) \ + STEP3(a, b, c, d, a3, b3, c3, d3, 1 , 3 , base) \ + STEP3(d, a, b, c, d3, a3, b3, c3, 9 , 9 , base) \ + STEP3(c, d, a, b, c3, d3, a3, b3, 5 , 11, base) \ + movdqa a, t1; \ + movl a3, t13; \ + paddd (256*base)+208+nt_buffer4x, b; \ + addl (64*base)+52+nt_buffer1x, b3; \ + pxor d, t1; \ + xorl d3,t13; \ + pxor c, t1; \ + xorl c3,t13; \ + paddd t1, b; \ + addl t13,b3; \ + \ + movdqa a, (64*base)+output4x; \ + movl a3, (16*base)+output1x; \ + movdqa b, (64*base)+16+output4x; \ + movl b3, (16*base)+4+output1x; \ + movdqa c, (64*base)+32+output4x; \ + movl c3, (16*base)+8+output1x; \ + movdqa d, (64*base)+48+output4x; \ + movl d3, (16*base)+12+output1x; + +.text + +DO_ALIGN(6) + +nt_crypt_all_sse2: + pusha + + movdqa const_stage2, t3 + movdqa const_stage3, t4 + + NT_CRYPT_BODY(0) + NT_CRYPT_BODY(1) + NT_CRYPT_BODY(2) + NT_CRYPT_BODY(3) + NT_CRYPT_BODY(4) + NT_CRYPT_BODY(5) + NT_CRYPT_BODY(6) + NT_CRYPT_BODY(7) + + popa + + ret + #if defined(__ELF__) && defined(__linux__) .section .note.GNU-stack,"",@progbits #endif diff -urpN john-1.7.3.4.orig/src/x86-sse.h john-1.7.3.4/src/x86-sse.h --- john-1.7.3.4.orig/src/x86-sse.h 2008-06-22 01:30:20 +0000 +++ john-1.7.3.4/src/x86-sse.h 2008-08-24 05:22:28 +0000 @@ -59,4 +59,9 @@ #define BF_SCALE 1 #define BF_X2 0 +#define MMX_TYPE " SSE2" +#define MMX_COEF 4 + +#define NT_SSE2 + #endif