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/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 2009-09-20 21:31:06 +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,51 @@ 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 \ + 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 \ + 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 +102,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 +196,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 +204,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 +212,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 +291,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 +325,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 +500,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 +511,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 +528,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 +621,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 +694,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 +760,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 +774,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 +795,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 +836,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 +858,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 +868,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 +879,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 + +#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 2009-09-20 22:27:33 +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,43 @@ 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_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_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 +101,39 @@ 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_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_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 +148,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 +360,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 +425,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 2009-08-20 05:35:49 +0000 @@ -1,6 +1,6 @@ /* * 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 */ #include @@ -18,6 +18,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 +186,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 +201,93 @@ 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); + memset(identity, 0, strlen(*login) + strlen(uid) + 1); + + sprintf(identity, *login, strlen(*login)); + sprintf(identity + strlen(*login), uid, strlen(uid)); + + /* Upper-Case Username and Domain */ + for(i=0; i= 'a') && (identity[i] <= 'z')) identity[i] ^= 0x20; + + tmp = (char *) mem_alloc(9 + strlen(identity) + 1 + strlen(srv_challenge) + 1 + strlen(netlmv2) + 1 + strlen(cli_challenge) + 1); + memset(tmp, 0, 9 + strlen(identity) + 1 + strlen(srv_challenge) + 1 + strlen(netlmv2) + 1 + strlen(cli_challenge) + 1); + sprintf(tmp, "$NETLMv2$%s$%s$%s$%s", identity, srv_challenge, netlmv2, cli_challenge); + *ciphertext = tmp; + } + 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(7 + strlen(challenge) + 1 + strlen(netlm) + 1); + memset(tmp, 0, 7 + strlen(challenge) + 1 + strlen(netlm) + 1); + sprintf(tmp, "$NETLM$%s$%s", challenge, netlm); + *ciphertext = tmp; + } + else { + tmp = (char *) mem_alloc(9 + strlen(challenge) + 1 + strlen(netntlm) + 1); + memset(tmp, 0, 9 + strlen(challenge) + 1 + strlen(netntlm) + 1); + sprintf(tmp, "$NETNTLM$%s$%s", challenge, netntlm); + *ciphertext = tmp; + } } - if (options->flags & DB_WORDS || options->shells->head) { - gid = ldr_get_field(&line); + 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(12 + strlen(challenge) + strlen(nethalflm) + 1); + sprintf(tmp, "$NETHALFLM$%s$%s", challenge, nethalflm); + *ciphertext = tmp; + } + + } + + 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 +295,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 +364,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 +391,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 +736,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 2008-08-24 07:12:07 +0000 @@ -0,0 +1,247 @@ +//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; + + 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 + +#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 2009-10-29 03:05:15 +0000 @@ -15,7 +15,7 @@ /* * John's version number. */ -#define JOHN_VERSION "1.7.3.4" +#define JOHN_VERSION "1.7.3.4-jumbo-2" /* * 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