This patch for John the Ripper adds a lot of code, documentation, and data contributed by the user community. This is not "official" John the Ripper code. It is very easy for new code to be added to this patch: the quality requirements are low. This means that you get a lot of functionality that is not "mature" enough or is otherwise inappropriate for the official JtR, which in turn also means that bugs in this code are to be expected, etc. How to apply this patch to JtR: http://openwall.info/wiki/john/how-to-extract-tarballs-and-apply-patches Licensing info: http://openwall.info/wiki/john/licensing How to contribute more code: http://openwall.info/wiki/how-to-make-patches diff -urpN john-1.7.5.orig/doc/EPi.patch.README john-1.7.5/doc/EPi.patch.README --- john-1.7.5.orig/doc/EPi.patch.README 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/doc/HDAA_README john-1.7.5/doc/HDAA_README --- john-1.7.5.orig/doc/HDAA_README 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/doc/MARKOV john-1.7.5/doc/MARKOV --- john-1.7.5.orig/doc/MARKOV 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/doc/MD5_GENERIC john-1.7.5/doc/MD5_GENERIC --- john-1.7.5.orig/doc/MD5_GENERIC 1970-01-01 00:00:00 +0000 +++ john-1.7.5/doc/MD5_GENERIC 2009-10-28 21:14:22 +0000 @@ -0,0 +1,672 @@ +How to use the 'generic' MD5. + +John has been enhanced to be able to handle MANY md5 variants easily. + +'variants' of MD5 are things like: + +md5($p) (Note, $p is the password, $s will be the salt, etc) +md5(md5($p)) (Note, this is md5 of the 32 byte result of a prior md5) +md5($p.$s) (Note, . is the concatenate operator, so $p.$s is + password with salt appended) +... + +Most of the above rules are php 'style' rules, but I think in php, +$pass is used, and $salt is used. In this document, they have been +simplified to $p and $s. + +This is done by using a new file format string: md5_gen(#) where +the # is a number. John reserves numbers from md5_gen(0) up to +md5_gen(999) for 'built-in' formats. Not all are defined at this +time, but those have been reserved. + +The format of the input file lines will be: + +userID:md5_gen(#)base_16_hash[$salt] + +There may be a 2nd salt added in the near future, but not sure how it +will be implemented. + +Here is an 'example' of the format required: + +userID:md5_gen(0)28fc2782ea7ef51c1104ccf7b9bea13d + +which is 'raw' md5, with a password of 1402 + +userID:md5_gen(6)8d8cac84f234f42e32daeb94e7cd49e8$*.* + +which is in the vBulletin format: md5(md5($p).$s), and which has a +fixed 3 byte salt (the $*.* above is the salt signature, and the +salt is *.*), solomon1 is the password for the above hash. NOTE +vBulletin is actually md5_gen(7). It is the expression format, but +puts to additional constraints on input. md5_gen(7) forces a 3 byte +salt, and it will NOT allow ':' character to be used as a separator, +since vBulletin salts can contain that character. However, the +above md5_gen(6) works for this document, since *.* salt does not +have a ':' + +Expressions can be added to john.conf (john.ini) to allow an end +user to add a new format type, without having to do ANY coding +at all. The end user would have to learn the generic md5 +primitives, and how the data is used (input data, key data, +encryption data, etc). Also, the user would have to build +properly formatted SAMPLE test values (john requires this). +For the full 'HOW TO USE' documentation, see the john.conf. + + +How to build the 'test' value is beyond the scope of this readme, +but a trivial example might help. +Expression format: md5(md5($p).md5($p)) +Password test1 +md5(test1) == 5a105e8b9d40e1329780d62ea2265d8a +so we want to md5 that result concatenated +so md5(md5(test1).md5(test1)) is the same as +md5(5a105e8b9d40e1329780d62ea2265d8a5a105e8b9d40e1329780d62ea2265d8a) +which equals 478b10974f15e7295883224fd286ccba +so a proper 'test' line is: +Test=md5_gen(1003)478b10974f15e7295883224fd286ccba:test1 +( as can be seen in john.conf for md5_gen(1003) ) + +The builtiin formats that john has right now are: + +------------+-------------------------+-------+------------------ +Signature | expression | Salt | notes +------------+-------------------------+-------+------------------ +md5_gen(0) | md5($p) | No | raw-md5 +md5_gen(1) | md5($p.$s) | Yes | (joomla) +md5_gen(2) | md5(md5($p)) | No | double md5 (e107) +md5_gen(3) | md5(md5(md5($p))) | No | triple md5 +md5_gen(4) | md5($s.$p) | Yes | (OS Commerce) +md5_gen(5) | md5($s.$p.$s) | Yes | +md5_gen(6) | md5(md5($p).$s) | Yes | +md5_gen(7) | md5(md5($p).$s) | Yes | vBulletin. 3 byte salt, salt uses ':' char +md5_gen(8) | md5(md5($s).$p) | Yes | +md5_gen(9) | md5($s.md5($p)) | Yes | +md5_gen(10) | md5($s.md5($s.$p)) | Yes | +md5_gen(11) | md5($s.md5($p.$s)) | Yes | +md5_gen(12) | md5(md5($s).md5($p)) | Yes | (IPB) NOTE NOT SSE2/MMX usable +md5_gen(13) | md5(md5($p).md5($s)) | Yes | NOTE NOT SSE2/MMX usable +md5_gen(14) | md5($s.md5($p).$s) | Yes | +md5_gen(15) | md5($u.md5($p).$s) | Yes | NOTE uses UserID in hash (not working yet) +md5_gen(16) | md5(md5(md5($p).$s).$s2)| Yes | NOTE uses 2 salts (not working yet) +md5_gen(17) | phpass ($H$ and $P$) | Yes | phpass and PHPbb-v3 hashes +md5_gen(18) | RESERVED | UNK | +........ | RESERVED | UNK | +md5_gen(999)| RESERVED | UNK | + +The 'samples' stored in john.conf (to be used as is, or as examples) are: + +md5_gen(1001) md5(md5(md5(md5($p)))) +md5_gen(1002) md5(md5(md5(md5(md5($p))))) +md5_gen(1003) md5(md5($p).md5($p)) +md5_gen(1004) md5(md5(md5(md5(md5(md5($p)))))) +md5_gen(1005) md5(md5(md5(md5(md5(md5(md5($p))))))) +md5_gen(1006) md5(md5(md5(md5(md5(md5(md5(md5($p)))))))) +md5_gen(1007) md5(md5($p).$s) [vBulletin] +md5_gen(1008) md5($p.$s) [joomla] + + + +NOTE the documentation section of john.conf is listed here. It shows +how to setup md5_generic functions (above 1000). All of the primitives +are defined, the data structures are defined, the expression, flags, +saltlen, etc. Following the 'howto use' section, are some working +examples (this whole list is also found in john.conf). + +#################################################################### +#################################################################### +# here are some examples of GENERIC-MD5 +#################################################################### +#################################################################### + +#################################################################### +# Documenation of how to 'setup' GENERIC-MD5 +#################################################################### +# +# Variables / workspaces: +# +# keys[] - Array Used to stored keys (optionally used, we 'may' be able to use input field 1 array) +# input1[] - Array used for encryption, key appending, salt appending, etc happens to/from these +# NOTE if MD5GenBaseFunc__InitialLoadKeysToInput then this is used to store the keys +# and MUST NOT be damaged, since any later key retrieval will come from this buffer. +# This is done as an optimization. Thus input2 is required for additional scratch buffer work. +# output1[] - Array encryption happens and output is put here. +# NOTE final result MUST be put here. This is what the 'hash' array is checked against. +# salt - the salt is put here +# input2[] - Array same as input 1, but a totally different array +# output2[] - Array same as output 2, but totally different array (can not be used as 'final' result) +# +# NOTE within the scratch work spaces (input1[] and input2[] arrays), we can only do things like append_keys +# append_salt or other things. Thus, each work space keeps track of each array element (knowing it's contents), +# and keeps track of the length. In the way the scripting works, we can clear them (sets lengths of all +# elements to 0, and 'might' clear out the actual memory). We can append to them (keys, output conversions, +# salt, etc) or we can force set their length to 32 ('special' optimization used in conjunction with +# MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1). +# +# NOTE there is NO length validation done, other than input keys are reduced to the max allowable length. +# Thus, if building, and you attempt something like: clear_keys append_keys append_keys append_keys append_keys +# append_keys append_keys and the keys are too long, then they will overflow. The maximal sizes of the +# input arrays are 95 bytes for x86 and 54 bytes for SSE/MMX. Above this will simply give invalid results +# (garbage in, garbage out). +# +##################################################################################### +# +# Function primitives, and what they do (REQUIRED in each format section) +# +################# +# +# Psudo loading functions. These are not 'actually' functions. To use these, they MUST be the +# first function in your script. They have certain 'side-effects', and some have special +# rules that MUST be maintained within the script, and thus may not be usable for all scripts. +# These are here mostly for optimization. They do NOT have to be used. If not used, then when +# john adds keys one at a time, they are placed into the array of keys. Then, when loading keys +# the keys are copied from the keys array, into the input1 (2) as needed. +# +# MD5GenBaseFunc__InitialLoadKeysToInput +# This is a 'special' function. It will not use the keys[] array, but put the keys right +# into the input1[] array. This buffer must not be destroyed. john will NOT use the keys[] +# array, and later retrieval of the key will happen from here (if there are any hashes broken). +# For this to be able to be used. +# $pass must be at the START of the expression. expressions like md5($s.$p) would not work, since +# $pass is not the 'start' of the expression. +# the $pass expression 'may' have to be all by itself. Thus md5($p.$s) would not work (such as joomla) +# but md5(md5($p).$s) can be made to work. +# The input1[] array must NOT be touched (after it is loaded). Thus the below set of functions can NOT +# be used in the script. +# MD5GenBaseFunc__append_keys +# MD5GenBaseFunc__append_keys2 +# MD5GenBaseFunc__clean_input +# MD5GenBaseFunc__append_salt +# MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16 +# MD5GenBaseFunc__overwrite_from_last_output2_to_input1_as_base16_no_size_fix +# MD5GenBaseFunc__append_from_last_output_as_base16 +# MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix +# MD5GenBaseFunc__append_2nd_salt MD5GenBaseFunc__append_userid +# +# MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2 +# This function will load keys into the keys[] array. It will then perform a md5() and put the ouput +# into output2. This was done a signficant enhancement for forms like md5(md5($p).$s) so that we +# load ALL of the inner md5($p) only once, then re-used them over and over again for each new salt. +# +# MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1 +# This is like the above psudo function, but it takes the extra step of storing the base16 conversion +# of the md5 into input1[] array. Due to this function, we have md5(md5($p).$s) actually working +# FASTER than simple md5($p) (if there are many salts). This is a significant optimization if it can +# be used properly. +# +# MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1_offset32 +# This function is a not valid for SSE2 (will build a 64 byte password, and 54 bytes is max SSE2 size) +# Psudo function that does the same work as MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1 +# however, it loaded the hext to offset 32 (instead of the 'start' of the buffer). When done, the +# input1[] buffers will have 64 byte passwords. The first 32 bytes are null, and the last +# 32 bytes are the hex values. This function is for md5(md5($s).md5($p)) (but certainly could +# be used for other formats. +# +################# +# +# MD5GenBaseFunc__clean_input +# Sets lengths of all input1[] array to ZERO, and sets the memory null (memory only set in SSE2, since it does +# not matter in x86 builds) +# +# MD5GenBaseFunc__clean_input_kwik +# Sets lengths of all input1[] array to ZERO. Memory not cleared. Optimization that can be used when you KNOW +# that the length of any of the input1 strings will never be less than they once were. So if you load keys, +# crypt, clean_input, then repeatedly append_base16 to input and crypt, then during that repeated set of work +# you can call clean_kwik since ALL things being crypted, would be 32 bytes, and the single 'deep' clean would +# get the buffers read to go, and they would not need fully cleaning again. +# +# MD5GenBaseFunc__append_keys +# append the array of keys to the array input1[] +# +# MD5GenBaseFunc__crypt +# performs a md5 on all elements of input1[] and places the results into output1[] The output will be the +# 16 byte BINARY blob of the 'raw' md5. +# +# MD5GenBaseFunc__append_from_last_output_as_base16 +# Takes the 16 byte binary values from the output1[] array, and does a base-16 conversion, appending the +# results into the elements of the input1[] array. ALL of the lengths of the array1[] elements will be +# 32 bytes more than they were (the base-16 of each 16 byte binary value is 32 bytes long). +# +# MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix +# Takes the 16 byte binary values from the output1[] array, and overwrites from byte 0 to byte 31 of each +# element of the input1[] array. This is used as an optimizations for formats such as: md5(md5($s).$p) +# in this format, we can place the keys into input1[] at 32 bytes past the start of the buffer, and set +# the lengths to be the length of each key + 32, and then simply call this function for each salt, to +# drop the 32 bytes of md5 data to the start of the strings, without touching the passwords that were +# already stored, or the lengths of the strings. +# +# MD5GenBaseFunc__overwrite_salt_to_input1_no_size_fix +# Inserts the salt to the start of the first input buffer. DOES NOT append null bytes, nor does it +# adjust the length of the strings. Used if the 'top' part of input buffer 1 stays constant, and +# the salt gets inserted to the start of input buffer (but lengths never change). +# +# MD5GenBaseFunc__append_salt +# Appends the salt to each element of input1[], and adjusts the length of each element. +# +# MD5GenBaseFunc__set_input_len_32 +# Sets the length of each element of input1[] to 32. This was designed as is used in conjunction with +# the funtion overwrite_from_last_output_as_base16_no_size_fix in mind, but would not +# be the 'only' reason to use it (but is the only reason I have at this time). This function does NOT +# clean the input[] items prior to this. Usually a call to clean_input would be required priot to +# calling this function, to make sure the buffer is 'clean'. +# +# MD5GenBaseFunc__set_input_len_64 +# Like the above function, but sets lengths to 64 bytes. +# +# MD5GenBaseFunc__clean_input2 +# Same as MD5GenBaseFunc__clean_input but this one works on input2[] array. +# +# MD5GenBaseFunc__clean_input2_kwik +# Same as MD5GenBaseFunc__clean_input_kwik but this one works on input2[] array. +# +# MD5GenBaseFunc__append_keys2 +# Same as MD5GenBaseFunc__append_keys but this one works on input2[] array. +# +# MD5GenBaseFunc__crypt2 +# Same as MD5GenBaseFunc__crypt but this one works on input2[] -> output2[] arrays. +# +# MD5GenBaseFunc__append_from_last_output2_as_base16 +# Same as MD5GenBaseFunc__append_from_last_output_as_base16 but this one works on output2[] -> input2[] arrays. +# +# MD5GenBaseFunc__overwrite_from_last_output2_as_base16_no_size_fix +# Same as MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix but this one works on output2[] -> input2[] arrays. +# +# MD5GenBaseFunc__overwrite_salt_to_input2_no_size_fix +# Same as MD5GenBaseFunc__overwrite_salt_to_input1_no_size_fix but this one works on salt -> input2[] arrays. +# +# MD5GenBaseFunc__append_salt2 +# Same as MD5GenBaseFunc__append_salt but this one works on input2[] array. +# +# MD5GenBaseFunc__set_input2_len_32 +# Same as MD5GenBaseFunc__set_input_len_32 but this one works on input2[] array. +# +# MD5GenBaseFunc__set_input2_len_64 +# Same as MD5GenBaseFunc__set_input2_len_64 but this one works on input2[] array. +# +#################### +# functions where input buffer and output buffer are different from 'each' other +# i.e. input buffer #1 to output buffer #2, etc +#################### +# +# MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +# output1[] append -> input2[] arrays. (note, output #1 appending to input #2, base-16) +# +# MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16 +# output2[] append -> input1[] arrays. (note, output #2 appending to input #1, base-16) +# +# MD5GenBaseFunc__overwrite_from_last_output_to_input2_as_base16_no_size_fix +# output1[] overwrite start of input2[] arrays. (note, output #1 going to start of input #2, base-16, no size 'fix') +# like MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix but different input output vars. +# +# MD5GenBaseFunc__overwrite_from_last_output2_to_input1_as_base16_no_size_fix +# output2[] overwrite start of input1[] arrays. (note, output #2 going to start of input #1, base-16, no size 'fix') +# like MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix but different input output vars. +# +# MD5GenBaseFunc__append_input_from_input2 +# Appends input2 to input input += input2 +# +# MD5GenBaseFunc__append_input2_from_input +# Appends input1 to input2 input2 += input +# +# +# MD5GenBaseFunc__crypt_in1_to_out2 +# Performs the work of MD5GenBaseFunc__crypt, but uses input1[] -> output2[] +# +# MD5GenBaseFunc__crypt_in2_to_out1 +# Performs the work of MD5GenBaseFunc__crypt, but uses input2[] -> output1[] +# +#################### +# These are special functions written SPECIFCALLY for usage by phpass code, in builtin +# function md5_gen(17). These are likely NOT useful. However, they 'are' open to be used. +#################### +# +# MD5GenBaseFunc__crypt_to_input_raw +# Used as 'first' step of phpass crypt. it will put 16 binary bytes of md5 encryption +# into array1[]. It will write this to the beginning of the arrays (does not append), and +# when done, sets ALL lengths of array1[] to 16. Once this function is called, the keys +# are appended (see spec for phpass encryption), which sets the length of input1[] elements +# to 16 + strlen(keys). Then there is a loop that calls the next function. +# +# MD5GenBaseFunc__crypt_to_input_raw_Overwrite_NoLen +# This function will encrypt input1[] and drop the 16 bytes of MD5 binary right back over +# the first 16 bytes of input1[] The length of each input1[] item is NOT touched, thus +# whatever the length was before is what it is now. +# +# MD5GenBaseFunc__PHPassSetup +# Special function for phpass, probably not useful in john.conf scripting +# MD5GenBaseFunc__PHPassCrypt +# Special function for phpass, probably not useful in john.conf scripting +# +#################### +# These functions are 'defined', but have not been implemented. +#################### +# +# MD5GenBaseFunc__append_2nd_salt +# append salt2 to array1[] +# MD5GenBaseFunc__append_2nd_salt2 +# append salt2 to array2[] +# MD5GenBaseFunc__append_userid +# append userID to array1[] +# MD5GenBaseFunc__append_userid2 +# append userID to array2[] +# +#################################################################### +# +# Test= line(s) (REQUIRED in each format section) +# +################# +# +# The testing line is simply of this format: +# +# test=md5_gen(#)hash[$salt]:password +# +# the hash listed, MUST be the hash generated for this password (and +# salt) for the expression. John uses this at startup to validate +# that the format is 'valid'. If this Test= line(s) are not right +# john will not work. NOTE if the format does not allow a colon +# in the format (such as md5_gen(1007), then the exact same field +# separator must be used in the Test= line, as what is specified +# in the --field-separator-char=c used on the command line +# +#################################################################### +# +# Expression= line (Optional) +# +################# +# +# If the Expression= line is there, then the value shown there will +# also be used on the startup line of john. If missing, john will +# output md5_gen(1001) (or whatever number was used), and if +# Expression=, then the md5_gen(1001) will be followed by the +# expression line. +# +#################################################################### +# +# Flag= line(s) (Optional, but required IF the format needs them) +# +################# +# +# Flags are just that, switches that tell the generic md5 parser that +# certain things need to be handled. One common used flag is MGF_SALTED +# If the format is a salted hash, then this flag must be present. +# Here is the list of flags, and what they mean, and when you should +# use them +# +# Flag=MGF_SALTED +# Use this for any salted format +# +# Flag=MGF_ColonNOTValid +# If there is some reason why the : char should not be used by john +# (such as the : is a valid character in the salt. If this is +# set, then the character to be used should be put into the Test= +# lines, AND the user should use that on the command line +# +# Flag=MGF_NOTSSE2Safe +# The max encryption the SSE2 code can handle is 54 bytes. The max +# size encryption for the 'generic' is 125 bytes. So, if it is +# OBVIOUS that sse2 can not be used, due to encryption lengths, +# then set this flag. An example is md5(md5($p).md5($s)) In this +# case, will be 3 md5's. 2 of them will be over the salt, and +# one over the password. Thus, if the password and salt are each +# under 54 bytes, then sse2 could be used. HOWEVER, the 3rd md5 +# (the final one), is done against the concatenation of 2 32 byte +# strings (the md5 results of the first 2 encryptions). THUS we +# KNOW this is a 64 byte string. That will not work in the current +# SSE2 (or mmx) code, and thus, the SSE2/MMX builds can NOT be used +# to test that format. +# +# Flag=MGF_INPBASE64 +# If the hashes are in base-64 (such as phpass), then use this +# flag. Note, the base 64 'format' used is that of phpass. If there +# are other orderings, then this will not work. I know of no formats +# in use, other than phpass (phpbb, wordpress, etc) which use base-64 +# for md5. +# +# Flag=MGF_SALTED2 +# If there are 2 salts in the format, use this flag. NOTE 2 salts +# is defined, but has not be implemented yet in john. +# +# Flag=MGF_USERID +# If there is a UserID in the format, use this flag. NOTE the UserID +# is defined, but has not be implemented yet in john. +# +# Flag=MFG_SALT_AS_HEX +# This flag is for formats such as md5(md5($p).md5($s)) What this +# does, is to return the md5($s) to john as the salt, and not simply +# return the 'original' salt. Thus, we run md5's for the salt at +# initialization, and never MD5 them again. DO NOT use this for a +# format like md5($s.md5($p).md5($s)) In that format, you NEED +# the salt (along with the md5 of that salt). This flag can not +# be used in that instance. +# +#################################################################### +# +# SaltLen=# line (Optional, but required IF the format needs it) +# +################# +# +# If this is a salted hash, and ALL valid salts must be a specific +# length (vBulletin is an example, where 3 byte salts are specified +# and OSCommerce is another with 2 byte hashes). If this is the +# case, add a SaltLen=# line and john will validate, and only test +# lines which have valid salts (i.e. right length salt is part of +# the initial validation of the line) +# +#################################################################### + + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^4 (i.e. 4 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1001)] +# expression shown will be the string: md5_gen(1001) md5(md5(md5(md5($p)))) +Expression=md5(md5(md5(md5($p)))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +Test=md5_gen(1001)57200e13b490d4ae47d5e19be026b057:test1 +Test=md5_gen(1001)c6cc44f9e7fb7efcde62ba2e627a49c6:thatsworking +Test=md5_gen(1001)0ae9549604e539a249c1fa9f5e5fb73b:test3 + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^5 (i.e. 5 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1002)] +# expression shown will be the string: md5_gen(1002) md5(md5(md5(md5(md5($p))))) +Expression=md5(md5(md5(md5(md5($p))))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1002)25de8cd0b0cf69c5b5bc19c8ee64adab:test1 +Test=md5_gen(1002)a0b535420ea47849f7c2cc09a3ad0ac3:thatsworking +Test=md5_gen(1002)4cb029bd5b4ef79f785ca685caf17bf8:test3 + +#################################################################### +# Simple GENERIC-MD5 type for md5(md5($p).md5($p)) +#################################################################### +[List.Generic:md5_gen(1003)] +# expression shown will be the string: md5_gen(1003) md5(md5($p).md5($p)) +Expression=md5(md5($p).md5($p)) +# NOTE, this format does NOT work on SSE2. It requires a md5() of a 64 byte string. +# SSE (or MMX) is limtited to 54 byte max password, due to 'enhancements' +# Thus, we need a non-sse2 safe flag. +Flag=MGF_NOTSSE2Safe +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1003)478b10974f15e7295883224fd286ccba:test1 +Test=md5_gen(1003)18a59101e6c6fb38260d542a394ecb22:thatsworking +Test=md5_gen(1003)630b01b68b6db6fd43a751f8147d1faf:test3 + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^6 (i.e. 6 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1004)] +# expression shown will be the string: md5_gen(1004) md5(md5(md5(md5(md5(md5($p)))))) +Expression=md5(md5(md5(md5(md5(md5($p)))))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1004)de1b991dd27fb9813e88b957a455dccd:test1 +Test=md5_gen(1004)6a62cd3c4d81139f61fb2553cdef0dc7:thatsworking +Test=md5_gen(1004)a977990e521c5d1d17c6d65fdf2681b4:test3 + + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^7 (i.e. 7 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1005)] +# expression shown will be the string: md5_gen(1005) md5(md5(md5(md5(md5(md5(md5($p))))))) +Expression=md5(md5(md5(md5(md5(md5(md5($p))))))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1005)784c527d0d92873ff9c0773e1c35621d:test1 +Test=md5_gen(1005)efcbbe6331caecf0e7f40160e65aadcc:thatsworking +Test=md5_gen(1005)abb8bdd2c6ac2dfea2b2af6f5aed5446:test3 + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^8 (i.e. 8 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1006)] +# expression shown will be the string: md5_gen(1006) md5(md5(md5(md5(md5(md5(md5(md5($p)))))))) +Expression=md5(md5(md5(md5(md5(md5(md5(md5($p)))))))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1006)1ec1f32398f64cab51183f63630eceea:test1 +Test=md5_gen(1006)f66b339ac21d6fd6af216f2b70aab2c9:thatsworking +Test=md5_gen(1006)e9d38522b5eeec753332e576e2e0fe5d:test3 + +#################################################################### +# Simple GENERIC-MD5 type for vBulletin md5(md5($p).$s) Included here to 'exercise' the script parser +#################################################################### +[List.Generic:md5_gen(1007)] +# expression shown will be the string: md5_gen(1007) md5(md5($p).$s) [vBulletin] +Expression=md5(md5($p).$s) [vBulletin] +# Flag needed here, is Salt. There is no 'fixed' saltlen. +Flag=MGF_SALTED +Flag=MGF_ColonNOTValid +# vBulletin has a 'fixed' 3 byte salt, so list the fixed size +SaltLen=3 +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1 +Func=MD5GenBaseFunc__set_input_len_32 +Func=MD5GenBaseFunc__append_salt +Func=MD5GenBaseFunc__crypt +# NOTE, vBulletin is setup to 'override' the ':'. USUALLY, it is good to use something +# outside of the ASCII values from 0x20 to 0x7F. 0x1F is a 'good' choice, but it will +# cause john.conf to have a 'non-normal' ASCII char. Thus for this 'simple' example, I +# have used the ';' character. NOTE this would have the same 'problems' as the ':' character +# if used for real, since ; is also a valid character within the salt of vBulletin. +# NOTE to run, you MUST use the command line switch: -field-separator-char=; +Test=md5_gen(1007)daa61d77e218e42060c2fa198ac1feaf$SXB;test1 +Test=md5_gen(1007)de56b00bb15d6db79204bd44383469bc$T &;thatsworking +Test=md5_gen(1007)fb685c6f469f6e549c85e4c1fb5a65a6$\H:;test3 + +#################################################################### +# Simple GENERIC-MD5 type for joomla md5($p.$s) Included here to 'exercise' the script parser +#################################################################### +[List.Generic:md5_gen(1008)] +# expression shown will be the string: md5_gen(1008) md5($p.$s) [joomla] +Expression=md5($p.$s) [joomla] +# Flag needed here, is Salt. There is no 'fixed' saltlen. +Flag=MGF_SALTED +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__clean_input +Func=MD5GenBaseFunc__append_keys +Func=MD5GenBaseFunc__append_salt +Func=MD5GenBaseFunc__crypt +Test=md5_gen(1008)ed52af63d8ecf0c682442dfef5f36391$1aDNNojYGSc7pSzcdxKxhbqvLtEe4deG:test1 +Test=md5_gen(1008)4fa1e9d54d89bfbe48b4c0f0ca0a3756$laxcaXPjgcdKdKEbkX1SIjHKm0gfYt1c:thatsworking +Test=md5_gen(1008)82568eeaa1fcf299662ccd59d8a12f54$BdWwFsbGtXPGc0H1TBxCrn0GasyAlJBJ:test3 + + +#################################################################### +#################################################################### +# END of GENERIC-MD5 examples +#################################################################### +#################################################################### diff -urpN john-1.7.5.orig/doc/OPTIONS john-1.7.5/doc/OPTIONS --- john-1.7.5.orig/doc/OPTIONS 2010-02-24 18:44:55 +0000 +++ john-1.7.5/doc/OPTIONS 2010-02-26 02:12:55 +0000 @@ -1,4 +1,5 @@ - John the Ripper's command line syntax. + John the Ripper's command line syntax. + (Updated with changes from 'options changes' by Jim Fougeron) When invoked with no command line arguments, "john" prints its usage summary. @@ -23,19 +24,22 @@ argument (if supported for a given optio The supported options are as follows, square brackets denote optional arguments: ---single "single crack" mode +--single[=section] "single crack" mode Enables the "single crack" mode, using rules from the configuration -file section [List.Rules:Single]. +file section [List.Rules:Single]. If --single=Single_2 then the rules +from [List.Rules:Single_2] section would be used. --wordlist=FILE wordlist mode, read words from FILE, --stdin or from stdin These are used to enable the wordlist mode. ---rules enable word mangling rules for wordlist mode +--rules[=section] enable word mangling rules for wordlist mode Enables word mangling rules that are read from [List.Rules:Wordlist]. +If --rules=Wordlist_elite was used, then [List.Rules:Wordlist_elite] +would be the section used. --incremental[=MODE] "incremental" mode [using section MODE] @@ -87,12 +91,14 @@ may restrict the set of passwords used b password files will be used), "--format", or/and "--external" (with an external mode that defines a filter() function). ---show show cracked passwords +--show[=left] show cracked passwords Shows the cracked passwords for given password files (which you must specify). You can use this option while another instance of John is cracking to see what John did so far; to get the most up to date information, first send a SIGHUP to the appropriate "john" process. +if --show=left then all uncracked hashes are listed (in a john 'input' +file format way). =left is just that literal string "=left". --test[=TIME] run tests and benchmarks for TIME seconds each @@ -118,13 +124,28 @@ not load accounts with a bad shell. You shell name, so "--shells=csh" will match both "/bin/csh" and "/usr/bin/csh", while "--shells=/bin/csh" will only match "/bin/csh". ---salts=[-]COUNT load salts with[out] at least COUNT passwords +--salt-list=salt[,salt,..] load just the specified salt(s) + +This will cause john to load ONLY the salts that are listed on the +command line. Thus, if you have a large list of salted hashes, but +several of them become 'high value', these can be checked by themselves +without having to cut them out into a separate input file. + +--salts=[-]COUNT[:MAX] load salts with[out] at least COUNT passwords This is a feature which allows to achieve better performance in some special cases. For example, you can crack only some salts using "--salts=2" faster and then crack the rest using "--salts=-2". Total cracking time will be about the same, but you will likely get some -passwords cracked earlier. +passwords cracked earlier. If MAX is listed, then no hashes are +loaded where there are more than MAX salts. This is so that if you +have run --salts=25 and then later can run --salts=10:24 and none of +the hashes that were already done from the --salts=25 will be re-done. + +--pot=potname pot file to use + +By default, john will use john.pot. This override allows using a different +john.pot file (to start from, and to store any found password into). --format=NAME force hash type NAME @@ -138,6 +159,13 @@ than one hash type, then you have to inv and you need to use this option to make John crack hashes of types other than the one it would autodetect by default. +--subformat=NAME Some formats such as MD5-gen have subformats + +Allows to specify which --format=md5-gen 'sub' format will be used. +So --format=md5-gen --subformat=md5_gen(7) will use the vBulletin +md5(md5($p).$s) format. +--subformat=LIST displays all the built-in md5-gen formats, and exits + --save-memory=LEVEL enable memory saving, at LEVEL 1..3 You might need this option if you don't have enough memory or don't @@ -148,6 +176,44 @@ impact is that you won't see the login n memory saving levels have a performance impact; you should probably avoid using them unless John doesn't work or gets into swap otherwise. +--mem-file-size=SIZE max size a wordlist file will preload into memory + +One of the significant performance improvements for some builds of +john, is preloading the wordlist file into memory, instead of reading +line by line. This is especially true when running with a large list +of --rules. The default max size file is 5 million bytes. Using this +option allows making this larger. NOTE if --save-memory is used, +then memory file processing is turned off. + +--field-separator-char=c Use 'c' instead of the char ':' + +By design, john works with most files, as 'tokenized' files. The field +separator used by john is the colon ':' character. However, there are +hashes which use the colon in the salt field, and there are users which +may have a colon for a user name (for a couple examples of problems +with it). However, an advanced john user can change the input files, +by using a different character than the ':' (and different than any +other 'used' character), and avoid problems of lines not being properly +processed. The side effects are that the pot file will get this +'character' used in it also (and only lines in the pot file that HAVE +that character will be loaded at startup), and there are other side +effects. Usually, this is ONLY used in very advanced situations, where +the user 'knows what he is doing'. If the character can not be easily +represented by the keyboard, then the format of +--field-separator-char=\xHH can be used. --field-separator-char=\x1F +would represent the character right before the space (space is 0x20) + +--fix-state-delay=# number of times the fix_state() function + +This is an optimization which helps on some file systems. This just +limits the number of times that the fseek() system call is performed. +The one side effect, is that if john is aborted, and restarted, it +may redo a few tests. If john gracefully shuts down, it should +resume properly. The default for this value is 64. This is a very +acceptable value in 99% of the systems. On many, if it is set to 0 +or set high, it will make no difference. On other systems, setting +higher than 64 will gain just a little improvement on a wordlist +run. Most users would never change this from default. Additional utilities. diff -urpN john-1.7.5.orig/run/genincstats.rb john-1.7.5/run/genincstats.rb --- john-1.7.5.orig/run/genincstats.rb 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/run/john.conf john-1.7.5/run/john.conf --- john-1.7.5.orig/run/john.conf 2010-02-26 01:22:09 +0000 +++ john-1.7.5/run/john.conf 2010-02-26 02:02:39 +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 = Y # Crash recovery file saving delay in seconds @@ -853,3 +857,216 @@ void restore() } lastid = id[--last]; } + +# Here are some examples of GENERIC-MD5. +# Please refer to doc/MD5_GENERIC for documentation on how to set these up. + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^4 (i.e. 4 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1001)] +# expression shown will be the string: md5_gen(1001) md5(md5(md5(md5($p)))) +Expression=md5(md5(md5(md5($p)))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +Test=md5_gen(1001)57200e13b490d4ae47d5e19be026b057:test1 +Test=md5_gen(1001)c6cc44f9e7fb7efcde62ba2e627a49c6:thatsworking +Test=md5_gen(1001)0ae9549604e539a249c1fa9f5e5fb73b:test3 + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^5 (i.e. 5 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1002)] +# expression shown will be the string: md5_gen(1002) md5(md5(md5(md5(md5($p))))) +Expression=md5(md5(md5(md5(md5($p))))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1002)25de8cd0b0cf69c5b5bc19c8ee64adab:test1 +Test=md5_gen(1002)a0b535420ea47849f7c2cc09a3ad0ac3:thatsworking +Test=md5_gen(1002)4cb029bd5b4ef79f785ca685caf17bf8:test3 + +#################################################################### +# Simple GENERIC-MD5 type for md5(md5($p).md5($p)) +#################################################################### +[List.Generic:md5_gen(1003)] +# expression shown will be the string: md5_gen(1003) md5(md5($p).md5($p)) +Expression=md5(md5($p).md5($p)) +# NOTE, this format does NOT work on SSE2. It requires a md5() of a 64 byte string. +# SSE (or MMX) is limtited to 54 byte max password, due to 'enhancements' +# Thus, we need a non-sse2 safe flag. +Flag=MGF_NOTSSE2Safe +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1003)478b10974f15e7295883224fd286ccba:test1 +Test=md5_gen(1003)18a59101e6c6fb38260d542a394ecb22:thatsworking +Test=md5_gen(1003)630b01b68b6db6fd43a751f8147d1faf:test3 + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^6 (i.e. 6 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1004)] +# expression shown will be the string: md5_gen(1004) md5(md5(md5(md5(md5(md5($p)))))) +Expression=md5(md5(md5(md5(md5(md5($p)))))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1004)de1b991dd27fb9813e88b957a455dccd:test1 +Test=md5_gen(1004)6a62cd3c4d81139f61fb2553cdef0dc7:thatsworking +Test=md5_gen(1004)a977990e521c5d1d17c6d65fdf2681b4:test3 + + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^7 (i.e. 7 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1005)] +# expression shown will be the string: md5_gen(1005) md5(md5(md5(md5(md5(md5(md5($p))))))) +Expression=md5(md5(md5(md5(md5(md5(md5($p))))))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1005)784c527d0d92873ff9c0773e1c35621d:test1 +Test=md5_gen(1005)efcbbe6331caecf0e7f40160e65aadcc:thatsworking +Test=md5_gen(1005)abb8bdd2c6ac2dfea2b2af6f5aed5446:test3 + +#################################################################### +# Simple GENERIC-MD5 type for md5($p)^^8 (i.e. 8 steps of md5 recursively) +#################################################################### +[List.Generic:md5_gen(1006)] +# expression shown will be the string: md5_gen(1006) md5(md5(md5(md5(md5(md5(md5(md5($p)))))))) +Expression=md5(md5(md5(md5(md5(md5(md5(md5($p)))))))) +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeysToInput +Func=MD5GenBaseFunc__crypt +Func=MD5GenBaseFunc__clean_input2 +Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt2 +Func=MD5GenBaseFunc__clean_input2_kwik +Func=MD5GenBaseFunc__append_from_last_output2_as_base16 +Func=MD5GenBaseFunc__crypt_in2_to_out1 +# These are test strings for this format. +Test=md5_gen(1006)1ec1f32398f64cab51183f63630eceea:test1 +Test=md5_gen(1006)f66b339ac21d6fd6af216f2b70aab2c9:thatsworking +Test=md5_gen(1006)e9d38522b5eeec753332e576e2e0fe5d:test3 + +#################################################################### +# Simple GENERIC-MD5 type for vBulletin md5(md5($p).$s) Included here to 'exercise' the script parser +#################################################################### +[List.Generic:md5_gen(1007)] +# expression shown will be the string: md5_gen(1007) md5(md5($p).$s) [vBulletin] +Expression=md5(md5($p).$s) [vBulletin] +# Flag needed here, is Salt. There is no 'fixed' saltlen. +Flag=MGF_SALTED +Flag=MGF_ColonNOTValid +# vBulletin has a 'fixed' 3 byte salt, so list the fixed size +SaltLen=3 +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1 +Func=MD5GenBaseFunc__set_input_len_32 +Func=MD5GenBaseFunc__append_salt +Func=MD5GenBaseFunc__crypt +# NOTE, vBulletin is setup to 'override' the ':'. USUALLY, it is good to use something +# outside of the ASCII values from 0x20 to 0x7F. 0x1F is a 'good' choice, but it will +# cause john.conf to have a 'non-normal' ASCII char. Thus for this 'simple' example, I +# have used the ';' character. NOTE this would have the same 'problems' as the ':' character +# if used for real, since ; is also a valid character within the salt of vBulletin. +# NOTE to run, you MUST use the command line switch: -field-separator-char=; +Test=md5_gen(1007)daa61d77e218e42060c2fa198ac1feaf$SXB;test1 +Test=md5_gen(1007)de56b00bb15d6db79204bd44383469bc$T &;thatsworking +Test=md5_gen(1007)fb685c6f469f6e549c85e4c1fb5a65a6$\H:;test3 + +#################################################################### +# Simple GENERIC-MD5 type for joomla md5($p.$s) Included here to 'exercise' the script parser +#################################################################### +[List.Generic:md5_gen(1008)] +# expression shown will be the string: md5_gen(1008) md5($p.$s) [joomla] +Expression=md5($p.$s) [joomla] +# Flag needed here, is Salt. There is no 'fixed' saltlen. +Flag=MGF_SALTED +# here is the optimized 'script' to perform the md5 8 times on itself. +Func=MD5GenBaseFunc__clean_input +Func=MD5GenBaseFunc__append_keys +Func=MD5GenBaseFunc__append_salt +Func=MD5GenBaseFunc__crypt +Test=md5_gen(1008)ed52af63d8ecf0c682442dfef5f36391$1aDNNojYGSc7pSzcdxKxhbqvLtEe4deG:test1 +Test=md5_gen(1008)4fa1e9d54d89bfbe48b4c0f0ca0a3756$laxcaXPjgcdKdKEbkX1SIjHKm0gfYt1c:thatsworking +Test=md5_gen(1008)82568eeaa1fcf299662ccd59d8a12f54$BdWwFsbGtXPGc0H1TBxCrn0GasyAlJBJ:test3 diff -urpN john-1.7.5.orig/run/netntlm.pl john-1.7.5/run/netntlm.pl --- john-1.7.5.orig/run/netntlm.pl 1970-01-01 00:00:00 +0000 +++ john-1.7.5/run/netntlm.pl 2010-02-26 02:26:55 +0000 @@ -0,0 +1,209 @@ +#!/usr/bin/perl +# +##################################################################### +# JoMo-Kun +# +# Crack LM/NTLM response using LM password case-insensitive seed. +# +# Fix character case for cracked LM responses using respective +# NTLM response. +# +##################################################################### +# + +use Getopt::Long; + +my $VERSION = "0.1"; +my %opt; +my %data; + +$potfile = 'john.pot'; +$JOHN = 'john'; + +GetOptions ( + 'seed=s' => \$opt{'seed'}, + 'file=s' => \$opt{'file'}, + 'help|h' => sub { ShowUsage(); }, +); + +sub showUsage { + print "john-netntlm.pl V. $VERSION\n"; + print "JoMo-Kun \n\n"; + print "Usage: $0 [OPTIONS]\n"; + print " $0\n"; + print " --seed [RainbowCrack/HalfLM Response Password]\n"; + print " --file [File Containing LM/NTLM challenge/responses (.lc format)]\n"; + print " Ex: Domain\\User:::LM response:NTLM response:challenge"; + print "\n"; + print " Ex:\n"; + print " $0 --file capture.lc\n"; + print " $0 --seed \"GERGE!!\"--file capture.lc\n"; + print "\n"; + exit(1); +} + +# MAIN +{ + if ( !defined($opt{'file'}) ) { &showUsage; } + + # Parse accounts to audit + open(HAND, $opt{'file'}) || die("Failed to open response file: $opt{'file'} -- $!"); + @{ $data{'pairs'} } = ; + close(HAND); + + # Load information for any accounts previous cracked + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + + open (HAND, "$JOHN -format:netlm -show $opt{'file'} |") || die("Failed to execute john: $!"); + print STDERR "The following LM responses have been previously cracked:\n"; + while() { + next if ( /\d+ password hashes cracked, \d+ left/ ); + last if /^$/; + print "\t$_"; + push @{ $data{'cracked-lm'} }, $_; + } + close(HAND); + + print STDERR "\nThe following NTLM responses have been previously cracked:\n"; + open (HAND, "$JOHN -format:netntlm -show $opt{'file'} |") || die("Failed to execute john: $!"); + while() { + next if ( /\d+ password hashes cracked, \d+ left/ ); + last if /^$/; + print "\t$_"; + push @{ $data{'cracked-ntlm'} }, $_; + } + close(HAND); + + my $tmpconf = &createConf(); + my $tmpsession = "john.session.$$"; + my $tmpsessionlog = "john.session.log"; # should we unlink this when done? + #print STDERR "Created temporary configuration file: $tmpconf\n"; + + # Crack case-sensitive version of password + my $tmpdict = "john.dict.$$"; + #print STDERR "Created temporary dictionary file: $tmpdict\n"; + + foreach $credential_set ( @{ $data{'cracked-lm'} } ) { + my ($account,$lmpass,$bar,$netlm,$netntlm,$chall) = split(/:/, $credential_set); + next if ( grep(/^$account:/i, @{ $data{'cracked-ntlm'} }) ); + + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + print STDERR "Performing NTLM case-sensitive crack for account: $account.\n"; + + open(HAND, ">$tmpdict") || die("Failed to option file: $tmpdict -- $!"); + print HAND "$lmpass"; + close(HAND); + + open (HAND, "$JOHN -format:netntlm -config:$tmpconf -wordlist:$tmpdict -rules -user:\"$account\" -session:$tmpsession $opt{'file'} |") || die("Failed to execute john: $!"); + while() { print; } + close(HAND); + unlink $tmpdict; + } + + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + print STDERR "Isolating accounts which have only had their LM response cracked.\n"; + + foreach $credential_set ( @{ $data{'pairs'} } ) { + $credential_set =~ s/\\/\\\\/g; + my ($account,$foo,$bar,$netlm,$netntlm,$chall) = split(/:/, $credential_set); + if (lc($netlm) eq lc($netntlm)) { + print STDERR "LM response is not unique from NTLM response (skipping):\n\t$credential_set\n"; + push @{ $data{'pairs-ntlm'} }, $credential_set; + } + elsif ( @cracked = grep(/^$account:/i, @{ $data{'cracked-ntlm'} }) ) { + print STDERR "Account $account NTLM response previously cracked.\n"; + #print "@cracked"; + } + else { + print STDERR "Account $account LM response added to cracking list.\n"; + push @{ $data{'pairs-lm'} }, $credential_set; + } + } + + if ( defined($opt{'seed'}) ) { + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + print STDERR "Testing seed password to determine whether it is the actual password.\n"; + open(HAND, ">$tmpdict") || die("Failed to option file: $tmpdict -- $!"); + print HAND $opt{'seed'}; + close(HAND); + + open (HAND, "$JOHN -format:netntlm -config:$tmpconf -wordlist:$tmpdict -rules -session:$tmpsession $opt{'file'} |") || die("Failed to execute john: $!"); + while() { print; } + close(HAND); + unlink $tmpdict; + + my $tmppasswd = "john.passwd.$$"; + open(HAND, ">$tmppasswd") || die("Failed to open $tmppasswd: $!"); + print HAND @{ $data{'pairs-lm'} }; + close(HAND); + + print STDERR "\n\n"; + print STDERR "###########################################################################################\n"; + print STDERR "The hashes contained within $tmppasswd have not been cracked.\n"; + print STDERR "Executing the following (this could take a while...):\n\n"; + print STDERR "john -format:netlm -config:$tmpconf -external:HalfLM -incremental:LM -session:$tmpsession $tmppasswd\n"; + print STDERR "\n"; + print STDERR " *If the passwords successfully crack, use this script again to crack the case-sensitive password\n"; + print STDERR " without feeding a seed password\n"; + print STDERR"\n\n"; + + exec("$JOHN -format:netlm -config:$tmpconf -external:HalfLM -incremental:LM -session:$tmpsession $tmppasswd"); + } + + unlink $tmppasswd, $tmpconf, $tmpsession; +} + +exit(0); + +sub createConf { + my $tmpconf = "john.conf.$$"; + open(CONF, ">$tmpconf") || die("Failed to open $tmpconf: $!"); + + # Define character keyspace + print CONF "[Incremental:LM]\n"; + print CONF "File = /usr/share/john/lanman.chr\n"; + print CONF "MinLen = 1\n"; + + # John compiled for MaxLen <= 8 + if (14 - length($opt{'seed'}) > 8) { + print CONF "MaxLen = 8\n"; + } else { + print CONF "MaxLen = ", 14 - length($opt{'seed'}), "\n"; + } + print CONF "CharCount = 69\n\n"; + + # Add external filter to handle uncracked characters + if ($opt{'seed'} ne "") { + my $i; $j; + my @seed = split(//, $opt{'seed'}); + + print CONF "[List.External:HalfLM]\n"; + print CONF "void filter()\n"; + print CONF "{\n"; + + my $len = length($opt{'seed'}); + for ($i = 13, $j = 13 - $len; $i>=0; $i--) { + if ($i >= $len) { + print CONF " word[$i] = word[$j];\n"; + $j--; + } else { + print CONF " word[$i] = \'$seed[$i]\';\n"; + } + } + + print CONF "}\n\n"; + } + + # Add custom wordlist to utilize NTLM hash for character case cracking + print CONF "[List.Rules:Wordlist]\n"; + print CONF "l\n"; + print CONF "lMT[*0]T[*1]T[*2]T[*3]T[*4]T[*5]T[*6]T[*7]T[*8]T[*9]T[*A]T[*B]T[*C]T[*D]Q\n"; + + close(CONF); + + return $tmpconf; +} diff -urpN john-1.7.5.orig/run/netscreen.py john-1.7.5/run/netscreen.py --- john-1.7.5.orig/run/netscreen.py 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/run/sap_prepare.pl john-1.7.5/run/sap_prepare.pl --- john-1.7.5.orig/run/sap_prepare.pl 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/run/stats john-1.7.5/run/stats --- john-1.7.5.orig/run/stats 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/BFEgg_fmt.c john-1.7.5/src/BFEgg_fmt.c --- john-1.7.5.orig/src/BFEgg_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/BFEgg_fmt.c 2009-09-22 21:03:43 +0000 @@ -0,0 +1,128 @@ +/* + * 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(void) { + 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_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, + fmt_default_get_hash, + fmt_default_get_hash + }, + cmp_all, + cmp_all, + cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/DOMINOSEC_fmt.c john-1.7.5/src/DOMINOSEC_fmt.c --- john-1.7.5.orig/src/DOMINOSEC_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/DOMINOSEC_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,460 @@ +/* + * 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_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, + fmt_default_get_hash, + fmt_default_get_hash + }, + dominosec_cmp_all, + dominosec_cmp_all, + dominosec_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/EPI_fmt.c john-1.7.5/src/EPI_fmt.c --- john-1.7.5.orig/src/EPI_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/EPI_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,208 @@ +/* + * 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_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, + 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 +#if !defined (_MSC_VER) +#include +#else +typedef unsigned int uint32_t; +#define snprintf _snprintf +#endif + +#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_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, + fmt_default_get_hash, + fmt_default_get_hash + }, + hdaa_cmp_all, + hdaa_cmp_all, + hdaa_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/IPB2_fmt.c john-1.7.5/src/IPB2_fmt.c --- john-1.7.5.orig/src/IPB2_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/IPB2_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,256 @@ +/* + * 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_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, + fmt_default_get_hash, + fmt_default_get_hash + }, + ipb2_cmp_all, + ipb2_cmp_all, + ipb2_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/KRB5_fmt.c john-1.7.5/src/KRB5_fmt.c --- john-1.7.5.orig/src/KRB5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/KRB5_fmt.c 2009-09-22 21:03:43 +0000 @@ -0,0 +1,353 @@ +/* + * 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, unsigned char *dst, int outsize) { + char *p, *pe; + unsigned 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, (unsigned 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(void) { + + 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_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, + fmt_default_get_hash, + fmt_default_get_hash + }, + krb5_cmp_all, + krb5_cmp_one, + krb5_cmp_exact + } +}; +// }}} + diff -urpN john-1.7.5.orig/src/KRB5_std.c john-1.7.5/src/KRB5_std.c --- john-1.7.5.orig/src/KRB5_std.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/KRB5_std.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,286 @@ +/* + * 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" + +#if defined (_MSC_VER) +#define inline _inline +#endif + + +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.5.orig/src/KRB5_std.h john-1.7.5/src/KRB5_std.h --- john-1.7.5.orig/src/KRB5_std.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/MD5_apache_fmt.c john-1.7.5/src/MD5_apache_fmt.c --- john-1.7.5.orig/src/MD5_apache_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/MD5_apache_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,202 @@ +/* + 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, + NULL, + NULL + }, + 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, + NULL, + NULL + }, + cmp_all, + cmp_all, + cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/MD5_fmt.c john-1.7.5/src/MD5_fmt.c --- john-1.7.5.orig/src/MD5_fmt.c 2010-01-16 17:18:51 +0000 +++ john-1.7.5/src/MD5_fmt.c 2010-01-19 07:25:49 +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,2010 by Solar Designer */ @@ -142,10 +149,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, @@ -164,8 +183,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, + get_salt, { binary_hash_0, binary_hash_1, @@ -178,7 +197,7 @@ struct fmt_main fmt_MD5 = { set_key, get_key, fmt_default_clear_keys, - (void (*)(int))MD5_std_crypt, + crypt_all, { get_hash_0, get_hash_1, diff -urpN john-1.7.5.orig/src/MD5_std.c john-1.7.5/src/MD5_std.c --- john-1.7.5.orig/src/MD5_std.c 2006-05-08 06:31:50 +0000 +++ john-1.7.5/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.5.orig/src/MD5_std.h john-1.7.5/src/MD5_std.h --- john-1.7.5.orig/src/MD5_std.h 2003-12-03 10:23:14 +0000 +++ john-1.7.5/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.5.orig/src/MYSQL_fast_fmt.c john-1.7.5/src/MYSQL_fast_fmt.c --- john-1.7.5.orig/src/MYSQL_fast_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/MYSQL_fast_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,247 @@ +/* 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, + NULL, + NULL + }, + 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, + NULL, + NULL + }, + mysql_cmp_all, + mysql_cmp_one, + mysql_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/MYSQL_fmt.c john-1.7.5/src/MYSQL_fmt.c --- john-1.7.5.orig/src/MYSQL_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/MYSQL_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,245 @@ +//////////////////////////////////////////////////////////////// +// 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_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, + 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.5.orig/src/Makefile john-1.7.5/src/Makefile --- john-1.7.5.orig/src/Makefile 2009-12-17 19:11:03 +0000 +++ john-1.7.5/src/Makefile 2010-02-14 03:52:28 +0000 @@ -15,9 +15,10 @@ 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 +LDFLAGS_MKV = -s -lm OPT_NORMAL = -funroll-loops OPT_INLINE = -finline-functions @@ -25,15 +26,55 @@ JOHN_OBJS_MINIMAL = \ DES_fmt.o DES_std.o DES_bs.o \ BSDI_fmt.o \ MD5_fmt.o MD5_std.o \ + MD5_apache_fmt.o \ + BFEgg_fmt.o \ BF_fmt.o BF_std.o \ AFS_fmt.o \ LM_fmt.o \ + NT_fmt.o \ + XSHA_fmt.o \ + DOMINOSEC_fmt.o \ + lotus5_fmt.o \ + oracle_fmt.o \ + oracle11_fmt.o \ + MYSQL_fmt.o \ + mysqlSHA1_fmt.o \ + KRB5_fmt.o KRB5_std.o \ + md5_go.o \ + rawMD5go_fmt.o md5_eq.o \ + PO_fmt.o \ + md5.o \ + hmacmd5.o \ + hmacMD5_fmt.o \ + IPB2_fmt.o \ + rawSHA1_fmt.o \ + NSLDAP_fmt.o NSLDAPS_fmt.o OPENLDAPS_fmt.o base64.o \ + md4.o smbencrypt.o \ + mscash_fmt.o \ + NETLM_fmt.o \ + NETNTLM_fmt.o \ + NETLMv2_fmt.o \ + NETNTLMv2_fmt.o \ + NETHALFLM_fmt.o \ + mssql_fmt.o \ + mssql05_fmt.o \ + EPI_fmt.o \ + PHPS_fmt.o \ + MYSQL_fast_fmt.o \ + pixMD5_fmt.o \ + sapG_fmt.o sapB_fmt.o \ + NS_fmt.o \ + HDAA_fmt.o \ + phpassMD5_fmt.o \ + md5_gen_fmt.o md5_gen_parser.o md5_gen_preloads.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 +107,22 @@ 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 +PROJ_WIN32_OPENSSL = ../run/john-openssl.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:" @@ -141,6 +193,9 @@ default: @echo "win32-cygwin-x86-sse2 Win32, Cygwin, x86 with SSE2 (best)" @echo "win32-cygwin-x86-mmx Win32, Cygwin, x86 with MMX" @echo "win32-cygwin-x86-any Win32, Cygwin, x86" + @echo "win32-mingw-x86-sse2 Win32, MinGW, x86 with SSE2 (best)" + @echo "win32-mingw-x86-mmx Win32, MinGW, x86 with MMX" + @echo "win32-mingw-x86-any Win32, MinGW, x86" @echo "beos-x86-sse2 BeOS, x86 with SSE2 (best)" @echo "beos-x86-mmx BeOS, x86 with MMX" @echo "beos-x86-any BeOS, x86" @@ -154,7 +209,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 +217,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 +225,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 +304,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 +338,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 +513,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 +524,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 +541,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,7 +634,7 @@ 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) -m32 -DUNDERSCORES -DBSD -DALIGN_LOG" \ CFLAGS="$(CFLAGS) -m32" \ LDFLAGS="$(LDFLAGS) -m32" @@ -587,7 +642,7 @@ macosx-x86-sse2: 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) -m32 -DUNDERSCORES -DBSD -DALIGN_LOG" \ CFLAGS="$(CFLAGS) -m32" \ LDFLAGS="$(LDFLAGS) -m32" @@ -656,7 +711,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 -m32 -DUNDERSCORES -DBSD -DALIGN_LOG" \ CFLAGS="$(CFLAGS) -arch i386 -m32" \ LDFLAGS="$(LDFLAGS) -arch i386 -m32" @@ -722,7 +777,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" @@ -736,14 +791,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" @@ -754,15 +809,36 @@ win32-cygwin-x86-any: CFLAGS="$(CFLAGS) -mpreferred-stack-boundary=2" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES" +win32-mingw-x86-sse2: + $(CP) x86-sse.h arch.h + $(MAKE) $(PROJ_WIN32_OPENSSL) \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ + CFLAGS="$(CFLAGS) -Wall -mpreferred-stack-boundary=4 -msse2 -march=k8 -mtune=k8 -m32" \ + ASFLAGS="$(ASFLAGS) -DUNDERSCORES" + +win32-mingw-x86-mmx: + $(CP) x86-mmx.h arch.h + $(MAKE) $(PROJ_WIN32_OPENSSL) \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ + CFLAGS="$(CFLAGS) -mpreferred-stack-boundary=2 -mmmx -m32" \ + ASFLAGS="$(ASFLAGS) -DUNDERSCORES" + +win32-mingw-x86-any: + $(CP) x86-any.h arch.h + $(MAKE) $(PROJ_WIN32_OPENSSL) \ + JOHN_OBJS="$(JOHN_OBJS) x86.o" \ + CFLAGS="$(CFLAGS) -Wall -mpreferred-stack-boundary=2 -m32" \ + ASFLAGS="$(ASFLAGS) -DUNDERSCORES" + 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 @@ -798,6 +874,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 @@ -816,6 +896,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 @@ -823,9 +906,14 @@ 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/john-openssl.exe: $(JOHN_OBJS) + $(LD) $(JOHN_OBJS) -lkernel32 -leay32 -o ../run/john-openssl.exe + strip ../run/john-openssl.exe + cp ../run/john-openssl.exe ../run/john.exe + ../run/unshadow.exe: symlink.c $(CC) symlink.c -o ../run/unshadow.exe strip ../run/unshadow.exe @@ -834,10 +922,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_MKV) -o ../run/genmkvpwd.exe + +../run/mkvcalcproba: mkvcalcproba.o + $(LD) mkvcalcproba.o $(LDFLAGS) -o ../run/mkvcalcproba + +../run/mkvcalcproba.exe: mkvcalcproba.o + $(LD) mkvcalcproba.o $(LDFLAGS_MKV) -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_MKV) -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 @@ -873,7 +983,7 @@ depend: makedepend -fMakefile.dep -Y *.c 2>> /dev/null clean: - $(RM) $(PROJ) $(PROJ_DOS) $(PROJ_WIN32) + $(RM) $(PROJ) $(PROJ_DOS) $(PROJ_WIN32) $(PROJ_WIN32_OPENSSL) $(RM) ../run/john.exe john-macosx-* *.o *.bak core $(RM) detect bench generic.h arch.h sparc.h tmp.s $(RM) DES_bs_s.c DES_bs_n.c DES_bs_a.c diff -urpN john-1.7.5.orig/src/NETHALFLM_fmt.c john-1.7.5/src/NETHALFLM_fmt.c --- john-1.7.5.orig/src/NETHALFLM_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/NETHALFLM_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,223 @@ +/* + * 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_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, + fmt_default_get_hash, + fmt_default_get_hash + }, + nethalflm_cmp_all, + nethalflm_cmp_one, + nethalflm_cmp_exact + } +}; + diff -urpN john-1.7.5.orig/src/NETLM_fmt.c john-1.7.5/src/NETLM_fmt.c --- john-1.7.5.orig/src/NETLM_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/NETLM_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,253 @@ +/* + * 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_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, + fmt_default_get_hash, + fmt_default_get_hash + }, + netlm_cmp_all, + netlm_cmp_one, + netlm_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/NETLMv2_fmt.c john-1.7.5/src/NETLMv2_fmt.c --- john-1.7.5.orig/src/NETLMv2_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/NETLMv2_fmt.c 2009-07-06 03:01:16 +0000 @@ -0,0 +1,365 @@ +/* + * NETLMv2_fmt.c -- LMv2 Challenge/Response + * + * Written by JoMo-Kun in 2008 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the LMv2 + * challenge/response sets exchanged during network-based authentication + * attempts [1]. The captured challenge/response set from these attempts + * should be stored using the following format: + * + * USERNAME::DOMAIN:SERVER CHALLENGE:LMv2 RESPONSE:CLIENT CHALLENGE + * + * For example: + * Administrator::WORKGROUP:1122334455667788:6759A5A7EFB25452911DE7DE8296A0D8:F503236B200A5B3A + * + * It should be noted that a LMv2 authentication response is not same as a LM + * password hash, which can be extracted using tools such as FgDump [2]. In + * fact, a NTLM hash and not a LM hash is used within the LMv2 algorithm. LMv2 + * challenge/response authentication typically takes place when the GPO + * "Network Security: LAN Manager authentication level" is configured to a setting + * that enforces the use of NTLMv2, such as "Send NTLMv2 response only\refuse + * LM & NTLM." + * + * LMv2 responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theLmv2Response + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include "md5.h" +#include "hmacmd5.h" + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netlmv2" +#define FORMAT_NAME "LMv2 C/R MD4 HMAC-MD5" +#define ALGORITHM_NAME "netlmv2" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 54 /* lmcons.h - PWLEN (256) ? 127 ? */ +#define USERNAME_LENGTH 20 /* lmcons.h - UNLEN (256) / LM20_UNLEN (20) */ +#define DOMAIN_LENGTH 15 /* lmcons.h - CNLEN / DNLEN */ +#define BINARY_SIZE 16 +#define CHALLENGE_LENGTH 32 +#define SALT_SIZE 16 + USERNAME_LENGTH + DOMAIN_LENGTH +#define CIPHERTEXT_LENGTH 32 +#define TOTAL_LENGTH 12 + USERNAME_LENGTH + DOMAIN_LENGTH + CHALLENGE_LENGTH + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETLMv2$ADMINISTRATORFOODOM$1122334455667788$6F64C5C1E35F68DD80388C0F00F34406$F0F3FF27037AA69F", "1337adminPASS"}, + {"$NETLMv2$USER1$1122334455667788$B1D163EA5881504F3963DC50FCDC26C1$EB4D9E8138149E20", "foobar"}, + {"$NETLMv2$ATEST$1122334455667788$83B59F1536D3321DBF1FAEC14ADB1675$A1E7281FE8C10E53", "SomeFancyP4$$w0rdHere"}, + {NULL} +}; + +uchar saved_plain[PLAINTEXT_LENGTH + 1]; +uchar challenge[SALT_SIZE + 1]; +uchar output[BINARY_SIZE + 1]; + +extern void E_md4hash(uchar *passwd, uchar *p16); +extern void hmac_md5_init_limK_to_64(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_update(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_final(unsigned char*, HMACMD5Context*); + +#if !defined(uint16) && !defined(HAVE_UINT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define uint16 unsigned short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#if !defined(int16) && !defined(HAVE_INT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define int16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define int16 short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#include "byteorder.h" + +/* Routines for Windows NT MD4 Hash functions. */ +static int lmv2_wcslen(int16 *str) +{ + int len = 0; + while(*str++ != 0) + len++; + return len; +} + +/* + * Convert a string into an NT UNICODE string. + * Note that regardless of processor type + * this must be in intel (little-endian) + * format. + */ +int lmv2_mbstowcs(int16 *dst, uchar *src, int len) +{ + int i; + int16 val; + + for(i = 0; i < len; i++) { + val = *src; + SSVAL(dst,0,val); + dst++; + src++; + if(val == 0) + break; + } + return i; +} + +static int netlmv2_valid(char *ciphertext) +{ + char *pos, *pos2; + + if (ciphertext == NULL) return 0; + else if (strncmp(ciphertext, "$NETLMv2$", 9)!=0) return 0; + + pos = &ciphertext[9]; + + /* Validate Username and Domain Length */ + for (pos2 = pos; strncmp(pos2, "$", 1) != 0; pos2++) + if ( (*pos2 < 0x20) || (*pos2 > 0x7E) ) + return 0; + + if ( !(*pos2 && (pos2 - pos <= USERNAME_LENGTH + DOMAIN_LENGTH)) ) + return 0; + + /* Validate Server Challenge Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == CHALLENGE_LENGTH / 2)) ) + return 0; + + /* Validate LMv2 Response Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == CIPHERTEXT_LENGTH)) ) + return 0; + + /* Validate Client Challenge Length */ + pos2++; pos = pos2; + for (; atoi16[ARCH_INDEX(*pos2)] != 0x7F; pos2++); + if (pos2 - pos != CHALLENGE_LENGTH / 2) + return 0; + + return 1; +} + +static char *netlmv2_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + char *pos = NULL; + int identity_length = 0; + + /* Calculate identity length */ + for (pos = ciphertext + 9; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 9); + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, strlen(ciphertext)); + strlwr(&out[10 + identity_length]); /* Exclude: $NETLMv2$USERDOMAIN$ */ + + return out; +} + +static void *netlmv2_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + char *pos = NULL; + int i, identity_length; + + for (pos = ciphertext + 9; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 9); + + ciphertext += 9 + identity_length + 1 + CHALLENGE_LENGTH / 2 + 1; + for (i=0; i in 2007 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the NTLM + * (version 1) challenge/response pairs exchanged during network-based + * authentication attempts [1]. The captured challenge/response pairs from these + * attempts should be stored using the L0phtCrack 2.0 LC format, specifically: + * username:unused:unused:lm response:ntlm response:challenge. For example: + * + * CORP\Administrator:::25B2B477CE101D83648BB087CE7A1C217F51C7FC64C0EBB1:: + * C8BD0C1630A9ECF7A95F494A8F0B2CB4A3F25B1225514304:1122334455667788 + * + * It should be noted that a NTLM authentication response is not same as a NTLM + * password hash, which can be extracted using tools such as FgDump [2]. NTLM + * responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theNtLmResponse + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netntlm" +#define FORMAT_NAME "NTLMv1 C/R MD4 DES" +#define ALGORITHM_NAME "netntlm" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 54 /* ?127? */ +#define BINARY_SIZE 24 +#define SALT_SIZE 8 +#define CIPHERTEXT_LENGTH 48 +#define TOTAL_LENGTH 10 + 2 * SALT_SIZE + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETNTLM$1122334455667788$BFCCAF26128EC95F9999C9792F49434267A1D9B0EF89BFFB", "g3rg3g3rg3g3rg3"}, + {"$NETNTLM$1122334455667788$E463FAA5D868ECE20CAE622474A2F440A652D642156AF863", "M1xedC4se%^&*@)##(blahblah!@#"}, + {"$NETNTLM$1122334455667788$35B62750E1B9B3205C50D6BA351092C12A1B9B3CDC65D44A", "FooBarGerg"}, + {"$NETNTLM$1122334455667788$A4765EBFE83D345A7CB1660B8899251905164029F8086DDE", "visit www.foofus.net"}, + {"$NETNTLM$1122334455667788$B2B2220790F40C88BCFF347C652F67A7C4A70D3BEBD70233", "cory21"}, + {NULL} +}; + +static char saved_plain[PLAINTEXT_LENGTH + 1]; +static uchar challenge[SALT_SIZE + 1]; +static uchar output[BINARY_SIZE + 1]; + +extern void E_md4hash(uchar *passwd, uchar *p16); +extern void setup_des_key(unsigned char key_56[], DES_key_schedule *ks); + +static int netntlm_valid(char *ciphertext) +{ + char *pos; + + if (strncmp(ciphertext, "$NETNTLM$", 9)!=0) return 0; + if (ciphertext[25] != '$') return 0; + + for (pos = &ciphertext[26]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); + if (!*pos && pos - ciphertext - 26 == CIPHERTEXT_LENGTH) + return 1; + else + return 0; +} + +static char *netntlm_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, TOTAL_LENGTH); + strlwr(&out[8]); /* Exclude: $NETNTLM$ */ + + return out; +} + +static void *netntlm_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + int i; + + ciphertext+=26; + for (i=0; i in 2009 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the NTLMv2 + * challenge/response sets exchanged during network-based authentication + * attempts [1]. The captured challenge/response set from these attempts + * should be stored using the following format: + * + * USERNAME::DOMAIN:SERVER CHALLENGE:NTLMv2 RESPONSE:CLIENT CHALLENGE + * + * For example: + * ntlmv2test::WORKGROUP:1122334455667788:07659A550D5E9D02996DFD95C87EC1D5:0101000000000000006CF6385B74CA01B3610B02D99732DD000000000200120057004F0052004B00470052004F00550050000100200044004100540041002E00420049004E0043002D0053004500430055005200490000000000 + * + * It should be noted that a NTLMv2 authentication response is not same as a NTLM + * password hash, which can be extracted using tools such as FgDump [2]. NTLMv2 + * challenge/response authentication typically takes place when the GPO + * "Network Security: LAN Manager authentication level" is configured to a setting + * that enforces the use of NTLMv2, such as "Send NTLMv2 response only\refuse + * LM & NTLM." + * + * NTLMv2 responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theNtlmv2Response + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include "md5.h" +#include "hmacmd5.h" + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netntlmv2" +#define FORMAT_NAME "NTLMv2 C/R MD4 HMAC-MD5" +#define ALGORITHM_NAME "netntlmv2" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 54 /* lmcons.h - PWLEN (256) ? 127 ? */ +#define USERNAME_LENGTH 20 /* lmcons.h - UNLEN (256) / LM20_UNLEN (20) */ +#define DOMAIN_LENGTH 15 /* lmcons.h - CNLEN / DNLEN */ +#define BINARY_SIZE 16 +#define SERVER_CHALL_LENGTH 16 +#define CLIENT_CHALL_LENGTH_MAX 512 /* FIX - Max Target Information Size Unknown */ +#define SALT_SIZE_MAX USERNAME_LENGTH + DOMAIN_LENGTH + 3 + SERVER_CHALL_LENGTH/2 + CLIENT_CHALL_LENGTH_MAX/2 +#define CIPHERTEXT_LENGTH 32 +#define TOTAL_LENGTH 12 + USERNAME_LENGTH + DOMAIN_LENGTH + SERVER_CHALL_LENGTH + CLIENT_CHALL_LENGTH_MAX + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETNTLMv2$NTLMV2TESTWORKGROUP$1122334455667788$07659A550D5E9D02996DFD95C87EC1D5$0101000000000000006CF6385B74CA01B3610B02D99732DD000000000200120057004F0052004B00470052004F00550050000100200044004100540041002E00420049004E0043002D0053004500430055005200490000000000", "password"}, + {"$NETNTLMv2$TESTUSERW2K3ADWIN7$1122334455667788$989B96DC6EAB529F72FCBA852C0D5719$01010000000000002EC51CEC91AACA0124576A744F198BDD000000000200120057004F0052004B00470052004F00550050000000000000000000", "testpass"}, + {"$NETNTLMv2$USERW2K3ADWIN7$1122334455667788$5BD1F32D8AFB4FB0DD0B77D7DE2FF7A9$0101000000000000309F56FE91AACA011B66A7051FA48148000000000200120057004F0052004B00470052004F00550050000000000000000000", "password"}, + {"$NETNTLMv2$USER1W2K3ADWIN7$1122334455667788$027EF88334DAA460144BDB678D4F988D$010100000000000092809B1192AACA01E01B519CB0248776000000000200120057004F0052004B00470052004F00550050000000000000000000", "SomeLongPassword1BlahBlah"}, + {"$NETNTLMv2$TEST_USERW2K3ADWIN7$1122334455667788$A06EC5ED9F6DAFDCA90E316AF415BA71$010100000000000036D3A13292AACA01D2CD95757A0836F9000000000200120057004F0052004B00470052004F00550050000000000000000000", "TestUser's Password"}, + {"$NETNTLMv2$USER1Domain$1122334455667788$5E4AB1BF243DCA304A00ADEF78DC38DF$0101000000000000BB50305495AACA01338BC7B090A62856000000000200120057004F0052004B00470052004F00550050000000000000000000", "password"}, + {NULL} +}; + +uchar saved_plain[PLAINTEXT_LENGTH + 1]; +uchar challenge[SALT_SIZE_MAX + 1]; +uchar output[BINARY_SIZE + 1]; + +extern void E_md4hash(uchar *passwd, uchar *p16); +extern void hmac_md5_init_limK_to_64(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_update(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_final(unsigned char*, HMACMD5Context*); + +#if !defined(uint16) && !defined(HAVE_UINT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define uint16 unsigned short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#if !defined(int16) && !defined(HAVE_INT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define int16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define int16 short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#include "byteorder.h" + +/* Routines for Windows NT MD4 Hash functions. */ +static int ntlmv2_wcslen(int16 *str) +{ + int len = 0; + while(*str++ != 0) + len++; + return len; +} + +/* + * Convert a string into an NT UNICODE string. + * Note that regardless of processor type + * this must be in intel (little-endian) + * format. + */ +int ntlmv2_mbstowcs(int16 *dst, uchar *src, int len) +{ + int i; + int16 val; + + for(i = 0; i < len; i++) { + val = *src; + SSVAL(dst,0,val); + dst++; + src++; + if(val == 0) + break; + } + return i; +} + +static int netntlmv2_valid(char *ciphertext) +{ + char *pos, *pos2; + + if (ciphertext == NULL) return 0; + else if (strncmp(ciphertext, "$NETNTLMv2$", 11)!=0) return 0; + + pos = &ciphertext[11]; + + /* Validate Username and Domain Length */ + for (pos2 = pos; strncmp(pos2, "$", 1) != 0; pos2++) + if ( (*pos2 < 0x20) || (*pos2 > 0x7E) ) + return 0; + + if ( !(*pos2 && (pos2 - pos <= USERNAME_LENGTH + DOMAIN_LENGTH)) ) + return 0; + + /* Validate Server Challenge Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == SERVER_CHALL_LENGTH)) ) + return 0; + + /* Validate NTLMv2 Response Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == CIPHERTEXT_LENGTH)) ) + return 0; + + /* Validate Client Challenge Length */ + pos2++; pos = pos2; + for (; atoi16[ARCH_INDEX(*pos2)] != 0x7F; pos2++); + if (pos2 - pos > CLIENT_CHALL_LENGTH_MAX) + return 0; + + return 1; +} + +static char *netntlmv2_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + char *pos = NULL; + int identity_length = 0; + + /* Calculate identity length */ + for (pos = ciphertext + 11; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 11); + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, strlen(ciphertext)); + strlwr(&out[12 + identity_length]); /* Exclude: $NETNTLMv2$USERDOMAIN$ */ + + return out; +} + +static void *netntlmv2_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + char *pos = NULL; + int i, identity_length; + + for (pos = ciphertext + 11; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 11); + + ciphertext += 11 + identity_length + 1 + SERVER_CHALL_LENGTH + 1; + for (i=0; i Identity \0 Size \0 Server Challenge + Client Challenge (Blob) + */ + hmac_md5_init_limK_to_64(ntlm_v2_hash, 16, &ctx); + hmac_md5_update(challenge + identity_length + 1 + 2, (int)(*(challenge + identity_length + 1)), &ctx); + hmac_md5_final(output, &ctx); +} + +static int netntlmv2_cmp_all(void *binary, int count) +{ + return !memcmp(output, binary, BINARY_SIZE); +} + +static int netntlmv2_cmp_one(void *binary, int index) +{ + return !memcmp(output, binary, BINARY_SIZE); +} + +static int netntlmv2_cmp_exact(char *source, int index) +{ + return !memcmp(output, netntlmv2_get_binary(source), BINARY_SIZE); +} + +/* + We're essentially using three salts, but we're going to pack it into a single blob for now. + + Input: $NETNTLMv2$USER_DOMAIN$_SERVER_CHALLENGE_$_NTLMv2_RESP_$_CLIENT_CHALLENGE_ + Username: <=20 + Domain: <=15 + Server Challenge: 8 bytes + Client Challenge: ??? + Output: Identity \0 Challenge Size \0 Server Challenge + Client Challenge +*/ +static void *netntlmv2_get_salt(char *ciphertext) +{ + static unsigned char binary_salt[SALT_SIZE_MAX]; + int i, identity_length, challenge_size; + char *pos = NULL; + + memset(binary_salt, 0, SALT_SIZE_MAX); + + /* Calculate identity length; Set identity */ + for (pos = ciphertext + 11; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 11); + strncpy((char *)binary_salt, ciphertext + 11, identity_length); + + /* Set server and client challenge size */ + + /* Skip: $NETNTLMv2$USER_DOMAIN$ */ + ciphertext += 11 + identity_length + 1; + + /* SERVER_CHALLENGE$NTLMV2_RESPONSE$CLIENT_CHALLENGE --> SERVER_CHALLENGECLIENT_CHALLENGE */ + /* CIPHERTEXT == NTLMV2_RESPONSE (16 bytes / 32 characters) */ + challenge_size = (strlen(ciphertext) - CIPHERTEXT_LENGTH - 2) / 2; + + /* Set challenge size in response - use NULL separators */ + memset(binary_salt + identity_length + 1, challenge_size, 1); + + /* Set server challenge - add NULL separator after challenge size */ + for (i = 0; i < SERVER_CHALL_LENGTH / 2; i++) + binary_salt[identity_length + 1 + 1 + 1 + i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + /* Set client challenge */ + ciphertext += SERVER_CHALL_LENGTH + 1 + CIPHERTEXT_LENGTH + 1; + for (i = 0; i < strlen(ciphertext) / 2; ++i) + binary_salt[identity_length + 1 + 1 + 1 + SERVER_CHALL_LENGTH / 2 + i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + /* Return a concatenation of the server and client challenges and the identity value */ + return (void*)binary_salt; +} + +static void netntlmv2_set_salt(void *salt) +{ + memcpy(challenge, salt, SALT_SIZE_MAX); +} + +static void netntlmv2_set_key(char *key, int index) +{ + strncpy((char *)saved_plain, key, PLAINTEXT_LENGTH); + saved_plain[PLAINTEXT_LENGTH] = 0; +} + +static char *netntlmv2_get_key(int index) +{ + return (char *)saved_plain; +} + +struct fmt_main fmt_NETNTLMv2 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE_MAX, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + fmt_default_init, + netntlmv2_valid, + netntlmv2_split, + netntlmv2_get_binary, + netntlmv2_get_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + netntlmv2_set_salt, + netntlmv2_set_key, + netntlmv2_get_key, + fmt_default_clear_keys, + netntlmv2_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + netntlmv2_cmp_all, + netntlmv2_cmp_one, + netntlmv2_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/NSLDAPS_fmt.c john-1.7.5/src/NSLDAPS_fmt.c --- john-1.7.5.orig/src/NSLDAPS_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/NSLDAPS_fmt.c 2009-10-29 04:49:23 +0000 @@ -0,0 +1,291 @@ +// Fix for john the ripper 1.6.37 by Sun-Zero, 2004. 07. 26. +/* + * This file is part of John the Ripper password cracker, + * Copyright (c) 1996-98 by Solar Designer + * + * Minor performance enhancement by bartavelle at bandecon.com + */ + +#include + +#include "misc.h" +#include "params.h" +#include "formats.h" +#include "common.h" + +#include "sha.h" +#include "base64.h" + +#define FORMAT_LABEL "ssha" +#define FORMAT_NAME "Netscape LDAP SSHA" +#define SHA_TYPE "salted SHA-1" + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 40 + +#define BINARY_SIZE 20 +#define SALT_SIZE 8 + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) ) +#else +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +#define NSLDAP_MAGIC "{ssha}" +#define NSLDAP_MAGIC_LENGTH 6 + +static struct fmt_tests tests[] = { + {"{SSHA}WTT3B9Jjr8gOt0Q7WMs9/XvukyhTQj0Ns0jMKQ==", "Password9"}, + {"{SSHA}ypkVeJKLzbXakEpuPYbn+YBnQvFmNmB+kQhmWQ==", "qVv3uQ45"}, + {"{SSHA}cKFVqtf358j0FGpPsEIK1xh3T0mtDNV1kAaBNg==", "salles"}, + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define buffer NSLDAPS_buffer +#define crypt_key NSLDAPS_crypt_key +unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(16))); +char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static char saved_key[80*MMX_COEF]; +static unsigned long total_len; +static unsigned char out[PLAINTEXT_LENGTH + 1]; +#else +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static char saved_key[PLAINTEXT_LENGTH + 1]; +#endif + +#ifdef MMX_COEF +static unsigned long length[MAX_KEYS_PER_CRYPT]; +#endif +static char saved_salt[SALT_SIZE]; + +static void * binary(char *ciphertext) { + static char realcipher[BINARY_SIZE + SALT_SIZE + 9]; + + /* stupid overflows */ + memset(realcipher, 0, sizeof(realcipher)); + base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher); + return (void *)realcipher; +} + +static void * get_salt(char * ciphertext) +{ + static char realcipher[BINARY_SIZE + SALT_SIZE + 9]; + memset(realcipher, 0, sizeof(realcipher)); + base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher); + return (void*)&realcipher[BINARY_SIZE]; +} + +static int valid(char *ciphertext) +{ + if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH + NSLDAP_MAGIC_LENGTH) + return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH); + return 0; +} + +static int binary_hash_0(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFFF; +} + +static int get_hash_0(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF; +} + +static int get_hash_1(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF; +} + +static int get_hash_2(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF; +} + +static int salt_hash(void *salt) +{ + return *((ARCH_WORD_32 *)salt) & (SALT_HASH_SIZE - 1); +} + +static void set_key(char *key, int index) +{ +#ifdef MMX_COEF + int len; + int i; + + if(index==0) + { + total_len = 0; + memset(saved_key, 0, sizeof(saved_key)); + memset(length, 0, sizeof(length)); + } + len = strlen(key); + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + length[index] = len; + + total_len += (len + SALT_SIZE) << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#else + return !memcmp(binary, crypt_key, BINARY_SIZE); +#endif +} + +static int +cmp_exact(char *source, int index) +{ + return 1; +} + +static int cmp_one(void * binary, int index) +{ +#ifdef MMX_COEF + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] ) + return 0; + return 1; +#else + return cmp_all(binary, index); +#endif +} + + +static void crypt_all(int count) +{ +#ifdef MMX_COEF + int i,idx; + + for(idx=0;idx + +#include "misc.h" +#include "formats.h" +#include "common.h" + +#include "sha.h" +#include "base64.h" + +#define FORMAT_LABEL "nsldap" +#define FORMAT_NAME "Netscape LDAP SHA" +#define SHA_TYPE "SHA-1" + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 33 + +#define BINARY_SIZE 20 +#define SALT_SIZE 0 + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT MMX_COEF +#define MAX_KEYS_PER_CRYPT MMX_COEF +#define GETPOS(i, index) ( (index)*4 + ((i)& (0xffffffff-3) )*MMX_COEF + (3-((i)&3)) ) +#else +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 +#endif + +#define NSLDAP_MAGIC "{sha}" +#define NSLDAP_MAGIC_LENGTH 5 + +static struct fmt_tests tests[] = { + {"{SHA}cMiB1KJphN3OeV9vcYF8nPRIDnk=", "aaaa"}, + {"{SHA}iu0TIuVFC62weOH7YKgXod8loso=", "bbbb"}, + {"{SHA}0ijZPTcJXMa+t2XnEbEwSOkvQu0=", "ccccccccc"}, + {"{SHA}vNR9eUfJfcKmdkLDqNoKagho+qU=", "dddddddddd"}, + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define buffer NSLDAP_buffer +#define crypt_key NSLDAP_crypt_key +unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(16))); +char crypt_key[BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static char saved_key[(PLAINTEXT_LENGTH+1)*MMX_COEF]; +static unsigned long total_len; +static unsigned char out[PLAINTEXT_LENGTH + 1]; +#else +static ARCH_WORD_32 crypt_key[BINARY_SIZE / 4]; +static char saved_key[PLAINTEXT_LENGTH + 1]; +#endif + +static void * +binary(char *ciphertext) { + static char realcipher[BINARY_SIZE + 9]; + + /* stupid overflows */ + memset(realcipher, 0, sizeof(realcipher)); + base64_decode(NSLDAP_MAGIC_LENGTH+ciphertext, CIPHERTEXT_LENGTH, realcipher); + return (void *)realcipher; +} + +static int +valid(char *ciphertext) +{ + if(ciphertext && strlen(ciphertext) == CIPHERTEXT_LENGTH) + return !strncasecmp(ciphertext, NSLDAP_MAGIC, NSLDAP_MAGIC_LENGTH); + return 0; +} + +static int binary_hash_0(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((ARCH_WORD_32 *)binary)[0] & 0xFFF; +} + +static int get_hash_0(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xF; +} + +static int get_hash_1(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFF; +} + +static int get_hash_2(int index) +{ + return ((ARCH_WORD_32 *)crypt_key)[index] & 0xFFF; +} + +static void set_key(char *key, int index) +{ +#ifdef MMX_COEF + int len; + int i; + + if(index==0) + { + total_len = 0; + memset(saved_key, 0, sizeof(saved_key)); + } + len = strlen(key); + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + total_len += len << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i> (((32/MMX_COEF)*(index)))) & 0xff; + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#else + return !memcmp(binary, crypt_key, BINARY_SIZE); +#endif +} + +static int +cmp_exact(char *source, int index) +{ + return 1; +} + +static int cmp_one(void * binary, int index) +{ +#ifdef MMX_COEF + int i = 0; + for(i=0;i<(BINARY_SIZE/4);i++) + if ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+index] ) + return 0; + return 1; +#else + return cmp_all(binary, index); +#endif +} + +static void set_salt(void *salt) { +} + +static void +crypt_all(int count) { +#ifdef MMX_COEF + memcpy(buffer, saved_key, 32*MMX_COEF); + shammx((unsigned char *) crypt_key, buffer, total_len); +#else + static SHA_CTX ctx; + SHA1_Init(&ctx); + SHA1_Update(&ctx, (unsigned char *) saved_key, strlen(saved_key)); + SHA1_Final((unsigned char *) crypt_key, &ctx); +#endif +} + +struct fmt_main fmt_NSLDAP = { + { + FORMAT_LABEL, + FORMAT_NAME, + SHA_TYPE, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + fmt_default_init, + valid, + fmt_default_split, + binary, + fmt_default_salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2, + NULL, + NULL + }, + 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, + NULL, + NULL + }, + cmp_all, + cmp_one, + cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/NS_fmt.c john-1.7.5/src/NS_fmt.c --- john-1.7.5.orig/src/NS_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/NS_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,286 @@ +/* + * 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(void) +{ + 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(int key) +{ + cipher_key[key_len] = 0; + return cipher_key; +} + +static void NS_std_crypt(int key) +{ + 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, + NULL, + NULL + }, + 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, + NULL, + NULL + }, + NS_cmp_all, + NS_cmp_all, + NS_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/NT_fmt.c john-1.7.5/src/NT_fmt.c --- john-1.7.5.orig/src/NT_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/NT_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,617 @@ +/* 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, + NULL, + NULL + }, + 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, + NULL, + NULL + }, + cmp_all, + cmp_one, + cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/OPENLDAPS_fmt.c john-1.7.5/src/OPENLDAPS_fmt.c --- john-1.7.5.orig/src/OPENLDAPS_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/OPENLDAPS_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,300 @@ +// 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. + * + * NOTE the new code 'hooks' into the generic MD5 code. The 'Convert' call + * changes the data from the PHPS format, into md5_gen(6) format, and then + * linkes to the MD5-GEN functions. MD5-GENERIC and 'linkage' by Jim Fougeron. + * the 'original' PHPS_fmt.c is saved into PHPS_fmt_orig.c If you want the + * original code, simply replace this file with that PHPS_fmt_orig.c file. + * + */ + +#include + +#include "common.h" +#include "formats.h" +#include "md5_gen.h" + +#define FORMAT_LABEL "phps" +#define FORMAT_NAME "PHPS MD5" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "MD5(MD5($pass).$salt) MMX" +#else +#define ALGORITHM_NAME "MD5(MD5($pass).$salt) SSE2" +#endif +#else +#define ALGORITHM_NAME "MD5(MD5($pass).$salt) MD5" +#endif + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#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 Conv_Buf[80]; + +/* this function converts a 'native' phps signature string into a md5_gen(7) syntax string */ +static char *Convert(char *Buf, char *ciphertext) +{ + unsigned long val, i; + char *cp = strchr(&ciphertext[7], '$'); + if (!cp) + return "*"; + sprintf(Buf, "md5_gen(6)%s$", &cp[1]); + for (i = 0; i < 3; ++i) + { + char bTmp[3]; + bTmp[0] = ciphertext[6+i*2]; + bTmp[1] = ciphertext[6+i*2+1]; + bTmp[2] = 0; + val = strtoul(bTmp, 0, 16); + sprintf(bTmp, "%c", (unsigned char)val); + strcat(Buf, bTmp); + } + return Buf; +} + +static int phps_valid(char *ciphertext) +{ + int i; + if (!ciphertext) + return 0; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + + if (strncmp(ciphertext, "$PHPS$", 6) != 0) + return 0; + + if (ciphertext[12] != '$') + return 0; + + for (i = 0;i < SALT_SIZE*2; ++i) + if (atoi16[ARCH_INDEX(ciphertext[i+6])] == 0x7F) + return 0; + + for (i = 0;i < MD5_HEX_SIZE; ++i) + if (atoi16[ARCH_INDEX(ciphertext[i+6+1+SALT_SIZE*2])] == 0x7F) + return 0; + + return fmt_MD5gen.methods.valid(Convert(Conv_Buf, ciphertext)); +} + + +static void * our_salt(char *ciphertext) +{ + return fmt_MD5gen.methods.salt(Convert(Conv_Buf, ciphertext)); +} +static void * our_binary(char *ciphertext) +{ + return fmt_MD5gen.methods.binary(Convert(Conv_Buf, ciphertext)); +} + +static void phps_init(void); + +struct fmt_main fmt_PHPS = +{ + { + // setup the labeling and stuff. NOTE the max and min crypts are set to 1 + // here, but will be reset within our init() function. + FORMAT_LABEL, FORMAT_NAME, ALGORITHM_NAME, BENCHMARK_COMMENT, BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, BINARY_SIZE, SALT_SIZE+1, 1, 1, FMT_CASE | FMT_8_BIT, phps_tests + }, + { + /* All we setup here, is the pointer to valid, and the pointer to init */ + /* within the call to init, we will properly set this full object */ + phps_init, + phps_valid + } +}; + + +static void phps_init(void) +{ + md5_gen_RESET_LINK(&fmt_PHPS, Convert(Conv_Buf, phps_tests[0].ciphertext), "phps"); + fmt_PHPS.methods.salt = our_salt; + fmt_PHPS.methods.binary = our_binary; +} + +/** + * 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.5.orig/src/PHPS_fmt_orig.c john-1.7.5/src/PHPS_fmt_orig.c --- john-1.7.5.orig/src/PHPS_fmt_orig.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/PHPS_fmt_orig.c 2009-09-11 23:07:00 +0000 @@ -0,0 +1,267 @@ +/* + * PHPS_fmt.c + * + * Salted PHP on the form (php-code): $hash = MD5(MD5($pass).$salt); + * Based on salted IPB2 mode (by regenrecht at o2.pl). + * + * albert veli gmail com, 2007 + * + * Convert hashes to the form username:$PHPS$salt$hash + * For instance, if the pw file has the form + * 1234<::>luser<::>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_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, + 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.5.orig/src/PO_fmt.c john-1.7.5/src/PO_fmt.c --- john-1.7.5.orig/src/PO_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/PO_fmt.c 2009-09-22 15:16:45 +0000 @@ -0,0 +1,227 @@ +/* + * 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, + NULL, + NULL + }, + salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + get_hash_0, + get_hash_1, + get_hash_2, + NULL, + NULL + }, + cmp_all, + cmp_all, + cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/base64.c john-1.7.5/src/base64.c --- john-1.7.5.orig/src/base64.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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 1 && format->params.salt_size == 0) salts = 1; + if (format->params.binary_size > binary_size) { binary_size = format->params.binary_size; binary = mem_alloc_tiny(binary_size, MEM_ALIGN_WORD); @@ -156,8 +177,12 @@ char *benchmark_format(struct fmt_main * sig_timer_emu_init(benchmark_time * clk_tck); #endif +#if defined (__MINGW32__) || defined (_MSC_VER) + start_real = clock(); +#else start_real = times(&buf); start_virtual = buf.tms_utime + buf.tms_stime; +#endif count = 0; index = salts; @@ -180,12 +205,16 @@ char *benchmark_format(struct fmt_main * #endif } while (bench_running && !event_abort); +#if defined (__MINGW32__) || defined (_MSC_VER) + end_real = clock(); +#else end_real = times(&buf); end_virtual = buf.tms_utime + buf.tms_stime; if (end_virtual == start_virtual) end_virtual++; + results->virtual = end_virtual - start_virtual; +#endif results->real = end_real - start_real; - results->virtual = end_virtual - start_virtual; results->count = count * max; for (index = 0; index < 2; index++) @@ -222,10 +251,30 @@ int benchmark_all(void) struct bench_results results_1, results_m; char s_real[64], s_virtual[64]; unsigned int total, failed; + unsigned md5_gen_first=1, md5_gen_cur=0, md5_gen_now=0; total = failed = 0; + options.field_sep_char = 31; if ((format = fmt_list)) do { +DoAgainWithoutNext:; + if (!strcmp(format->params.label, "md5-gen")) + { + if (md5_gen_first) + { + // only get here once + md5_gen_first = 0; + // list we are doing md5-gen + if (options.subformat == NULL) + { + md5_gen_now = 1; + options.subformat = malloc(256); + sprintf(options.subformat, "md5_gen(%d)", md5_gen_cur++); + } + md5_gen_RESET(); + format->methods.valid(NULL); + } + } printf("Benchmarking: %s%s [%s]... ", format->params.format_name, format->params.benchmark_comment, @@ -269,7 +318,7 @@ int benchmark_all(void) benchmark_cps(results_m.count, results_m.real, s_real); benchmark_cps(results_m.count, results_m.virtual, s_virtual); -#if !defined(__DJGPP__) && !defined(__CYGWIN32__) && !defined(__BEOS__) +#if !defined(__DJGPP__) && !defined(__CYGWIN32__) && !defined(__BEOS__) && !defined(__MINGW32__) && !defined (_MSC_VER) printf("%s:\t%s c/s real, %s c/s virtual\n", msg_m, s_real, s_virtual); #else @@ -279,18 +328,49 @@ int benchmark_all(void) if (!msg_1) { putchar('\n'); + + if (md5_gen_now) + { + int valid = md5_gen_IS_VALID(md5_gen_cur); + while (!valid) + valid = md5_gen_IS_VALID(++md5_gen_cur); + if (valid == 1) + { + sprintf(options.subformat, "md5_gen(%d)", md5_gen_cur++); + md5_gen_RESET(); + format->methods.valid(NULL); + goto DoAgainWithoutNext; + } + md5_gen_now = 0; + } + continue; } benchmark_cps(results_1.count, results_1.real, s_real); benchmark_cps(results_1.count, results_1.virtual, s_virtual); -#if !defined(__DJGPP__) && !defined(__CYGWIN32__) && !defined(__BEOS__) +#if !defined(__DJGPP__) && !defined(__CYGWIN32__) && !defined(__BEOS__) && !defined(__MINGW32__) && !defined (_MSC_VER) printf("%s:\t%s c/s real, %s c/s virtual\n\n", msg_1, s_real, s_virtual); #else printf("%s:\t%s c/s\n\n", msg_1, s_real); #endif + if (md5_gen_now) + { + int valid = md5_gen_IS_VALID(md5_gen_cur); + while (!valid) + valid = md5_gen_IS_VALID(++md5_gen_cur); + if (valid == 1) + { + sprintf(options.subformat, "md5_gen(%d)", md5_gen_cur++); + md5_gen_RESET(); + format->methods.valid(NULL); + goto DoAgainWithoutNext; + } + md5_gen_now = 0; + } + } while ((format = format->next) && !event_abort); if (failed && total > 1 && !event_abort) diff -urpN john-1.7.5.orig/src/bf_tab.h john-1.7.5/src/bf_tab.h --- john-1.7.5.orig/src/bf_tab.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/bf_tab.h 2008-02-20 14:19:35 +0000 @@ -0,0 +1,277 @@ +/* bf_tab.h: Blowfish P-box and S-box tables */ +#ifndef _H_TAB_BF +#define _H_TAB_BF + +static UWORD_32bits initbf_P[bf_N + 2] = +{ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, + 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, + 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, + 0x9216d5d9, 0x8979fb1b, +}; +static UWORD_32bits initbf_S[4][256] = +{ + { + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, + 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, + 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, + 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, + 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, + 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, + 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, + 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, + 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, + 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, + 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, + 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, + 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, + 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, + 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, + 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, + 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, + 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, + 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, + 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, + 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, + 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, + 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, + 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, + 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, + 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, + 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, + 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, + 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, + 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, + 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, + 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, + 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a}, + { + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, + 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, + 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, + 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, + 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, + 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, + 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, + 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, + 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, + 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, + 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, + 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, + 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, + 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, + 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, + 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, + 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, + 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, + 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, + 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, + 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, + 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, + 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, + 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, + 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, + 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, + 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, + 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, + 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, + 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, + 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, + 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, + 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7}, + { + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, + 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, + 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, + 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, + 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, + 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, + 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, + 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, + 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, + 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, + 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, + 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, + 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, + 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, + 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, + 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, + 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, + 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, + 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, + 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, + 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, + 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, + 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, + 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, + 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, + 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, + 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, + 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, + 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, + 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, + 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, + 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, + 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0}, + { + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, + 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, + 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, + 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, + 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, + 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, + 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, + 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, + 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, + 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, + 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, + 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, + 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, + 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, + 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, + 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, + 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, + 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, + 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, + 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, + 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, + 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, + 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, + 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, + 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, + 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, + 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, + 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, + 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, + 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, + 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, + 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, + 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6} +}; + +#endif diff -urpN john-1.7.5.orig/src/blowfish.c john-1.7.5/src/blowfish.c --- john-1.7.5.orig/src/blowfish.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/blowfish.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,186 @@ +/* + * blowfish.c - part of blowfish.mod + * handles: encryption and decryption of passwords + */ +/* + * The first half of this is very lightly edited from public domain + * sourcecode. For simplicity, this entire module will remain public + * domain. + */ +/* + * This is ripped from eggdrop 1.3.28's source files (blowfish.mod) + * Modified by Sun-Zero + * 2002-04-16 +*/ + +#include +#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.5.orig/src/blowfish.h john-1.7.5/src/blowfish.h --- john-1.7.5.orig/src/blowfish.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/byteorder.h john-1.7.5/src/byteorder.h --- john-1.7.5.orig/src/byteorder.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/calc_stat.c john-1.7.5/src/calc_stat.c --- john-1.7.5.orig/src/calc_stat.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/calc_stat.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,173 @@ +#include +#include +#if !defined (_MSC_VER) +#include +#endif +#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.5.orig/src/charset.c john-1.7.5/src/charset.c --- john-1.7.5.orig/src/charset.c 2009-07-25 19:00:14 +0000 +++ john-1.7.5/src/charset.c 2009-09-22 14:11:12 +0000 @@ -4,7 +4,11 @@ */ #include +#if !defined (_MSC_VER) #include +#else +#define unlink _unlink +#endif #include #include "arch.h" @@ -122,10 +126,10 @@ static int charset_new_length(int length fflush(stdout); if ((offset = ftell(file)) < 0) pexit("ftell"); - header->offsets[length][0] = offset; - header->offsets[length][1] = offset >> 8; - header->offsets[length][2] = offset >> 16; - header->offsets[length][3] = offset >> 24; + header->offsets[length][0] = (unsigned char)((unsigned long)offset); + header->offsets[length][1] = (unsigned char)((unsigned long)(offset >> 8)); + header->offsets[length][2] = (unsigned char)((unsigned long)(offset >> 16)); + header->offsets[length][3] = (unsigned char)((unsigned long)(offset >> 24)); } return result; diff -urpN john-1.7.5.orig/src/cracker.c john-1.7.5/src/cracker.c --- john-1.7.5.orig/src/cracker.c 2010-01-18 05:19:40 +0000 +++ john-1.7.5/src/cracker.c 2010-01-19 07:22:25 +0000 @@ -99,7 +99,7 @@ static int crk_process_guess(struct db_s key = crk_methods.get_key(index); log_guess(crk_db->options->flags & DB_LOGIN ? pw->login : "?", - dupe ? NULL : pw->source, key); + dupe ? NULL : pw->source, key, crk_db->options->field_sep_char); crk_db->guess_count++; status.guess_count++; diff -urpN john-1.7.5.orig/src/formats.c john-1.7.5/src/formats.c --- john-1.7.5.orig/src/formats.c 2010-01-16 16:44:48 +0000 +++ john-1.7.5/src/formats.c 2010-01-19 05:40:58 +0000 @@ -45,6 +45,9 @@ char *fmt_self_test(struct fmt_main *for if (!(current = format->params.tests)) return NULL; + if (current->ciphertext == NULL && !strcmp(format->params.label, "md5-gen")) + format->methods.valid(NULL); + done = 0; index = 0; max = format->params.max_keys_per_crypt; if (max > 2 && !(format->params.flags & FMT_BS)) max = 2; diff -urpN john-1.7.5.orig/src/formats.h john-1.7.5/src/formats.h --- john-1.7.5.orig/src/formats.h 2010-01-16 16:50:31 +0000 +++ john-1.7.5/src/formats.h 2010-01-19 05:40:58 +0000 @@ -200,4 +200,12 @@ extern int fmt_default_get_hash(int inde */ #define fmt_dummy_hash fmt_default_get_hash +#if defined (_MSC_VER) +#pragma warning (disable : 4018 297 ) +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#define strlwr _strlwr +#define inline _inline +#endif + #endif diff -urpN john-1.7.5.orig/src/genmkvpwd.c john-1.7.5/src/genmkvpwd.c --- john-1.7.5.orig/src/genmkvpwd.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/genmkvpwd.c 2009-07-03 20:49:14 +0000 @@ -0,0 +1,289 @@ +#include +#include +#if !defined (_MSC_VER) +#include +#else +#define atoll _atoi64 +#endif +#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.5.orig/src/hmacMD5_fmt.c john-1.7.5/src/hmacMD5_fmt.c --- john-1.7.5.orig/src/hmacMD5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/hmacMD5_fmt.c 2009-10-29 04:44:13 +0000 @@ -0,0 +1,317 @@ +/* + * 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.5.orig/src/hmacmd5.h john-1.7.5/src/hmacmd5.h --- john-1.7.5.orig/src/hmacmd5.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/idle.c john-1.7.5/src/idle.c --- john-1.7.5.orig/src/idle.c 2009-12-25 20:32:45 +0000 +++ john-1.7.5/src/idle.c 2009-12-27 17:38:21 +0000 @@ -3,7 +3,9 @@ * Copyright (c) 1996-2001,2006,2009 by Solar Designer */ +#if !defined (_MSC_VER) #include +#endif #ifdef _POSIX_PRIORITY_SCHEDULING #include @@ -13,6 +15,10 @@ static int use_yield = 0; #endif +#if defined (__MINGW32__) || defined (_MSC_VER) +#include +#endif + #ifdef __CYGWIN32__ extern int nice(int); #endif @@ -38,10 +44,13 @@ void idle_init(void) clk_tck_init(); -#ifndef __BEOS__ - nice(20); -#else +#if defined(__MINGW32__) || defined (_MSC_VER) + SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); +#elif defined(__BEOS__) set_thread_priority(getpid(), 1); +#else + nice(20); #endif #if defined(_POSIX_PRIORITY_SCHEDULING) && defined(SCHED_IDLE) diff -urpN john-1.7.5.orig/src/inc.c john-1.7.5/src/inc.c --- john-1.7.5.orig/src/inc.c 2008-06-28 06:41:41 +0000 +++ john-1.7.5/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.5.orig/src/john.c john-1.7.5/src/john.c --- john-1.7.5.orig/src/john.c 2010-01-17 12:00:55 +0000 +++ john-1.7.5/src/john.c 2010-02-14 03:52:28 +0000 @@ -4,7 +4,9 @@ */ #include +#if !defined (_MSC_VER) #include +#endif #include #include #include @@ -29,6 +31,7 @@ #include "single.h" #include "wordlist.h" #include "inc.h" +#include "mkv.h" #include "external.h" #include "batch.h" @@ -38,9 +41,47 @@ 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_MD5gen; +extern struct fmt_main fmt_hmacMD5; +extern struct fmt_main fmt_IPB2; +extern struct fmt_main fmt_phpassmd5; +extern struct fmt_main fmt_MD5_apache; +extern struct fmt_main fmt_BFEgg; +extern struct fmt_main fmt_KRB5; +extern struct fmt_main fmt_oracle; +extern struct fmt_main fmt_oracle11; +extern struct fmt_main fmt_MYSQL; +extern struct fmt_main fmt_mysqlSHA1; +extern struct fmt_main fmt_NSLDAP; +extern struct fmt_main fmt_NSLDAPS; +extern struct fmt_main fmt_OPENLDAPS; +extern struct fmt_main fmt_mscash; +extern struct fmt_main fmt_rawSHA1; +extern struct fmt_main fmt_XSHA; +extern struct fmt_main fmt_lotus5; +extern struct fmt_main fmt_DOMINOSEC; +extern struct fmt_main fmt_NETLM; +extern struct fmt_main fmt_NETNTLM; +extern struct fmt_main fmt_NETLMv2; +extern struct fmt_main fmt_NETNTLMv2; +extern struct fmt_main fmt_NETHALFLM; +extern struct fmt_main fmt_mssql; +extern struct fmt_main fmt_mssql05; +extern struct fmt_main fmt_EPI; +extern struct fmt_main fmt_PHPS; +extern struct fmt_main fmt_MYSQL_fast; +extern struct fmt_main fmt_pixMD5; +extern struct fmt_main fmt_sapG; +extern struct fmt_main fmt_sapB; +extern struct fmt_main fmt_NS; +extern struct fmt_main fmt_HDAA; extern int unshadow(int argc, char **argv); extern int unafs(int argc, char **argv); +extern int undrop(int argc, char **argv); extern int unique(int argc, char **argv); static struct db_main database; @@ -66,6 +107,43 @@ 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_MD5gen); + john_register_one(&fmt_phpassmd5); + john_register_one(&fmt_IPB2); + john_register_one(&fmt_rawSHA1); + john_register_one(&fmt_KRB5); + john_register_one(&fmt_NSLDAP); + john_register_one(&fmt_NSLDAPS); + john_register_one(&fmt_OPENLDAPS); + john_register_one(&fmt_BFEgg); + john_register_one(&fmt_oracle); + john_register_one(&fmt_oracle11); + john_register_one(&fmt_MYSQL); + john_register_one(&fmt_mysqlSHA1); + john_register_one(&fmt_lotus5); + john_register_one(&fmt_DOMINOSEC); + john_register_one(&fmt_NETLM); + john_register_one(&fmt_NETNTLM); + john_register_one(&fmt_NETLMv2); + john_register_one(&fmt_NETNTLMv2); + john_register_one(&fmt_NETHALFLM); + john_register_one(&fmt_mssql); + john_register_one(&fmt_mssql05); + john_register_one(&fmt_EPI); + john_register_one(&fmt_PHPS); + john_register_one(&fmt_MYSQL_fast); + john_register_one(&fmt_pixMD5); + john_register_one(&fmt_sapG); + john_register_one(&fmt_sapB); + john_register_one(&fmt_NS); + john_register_one(&fmt_HDAA); if (!fmt_list) { fprintf(stderr, "Unknown ciphertext format name requested\n"); @@ -80,7 +158,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", @@ -118,8 +196,9 @@ static void john_load(void) { struct list_entry *current; +#if !defined (_MSC_VER) umask(077); - +#endif if (options.flags & FLG_EXTERNAL_CHK) ext_init(options.external); @@ -128,7 +207,7 @@ static void john_load(void) ldr_init_database(&database, &options.loader); if (options.flags & FLG_PASSWD) { - ldr_show_pot_file(&database, POT_NAME); + ldr_show_pot_file(&database, options.loader.activepot); database.options->flags |= DB_PLAINTEXTS; if ((current = options.passwd->head)) @@ -137,7 +216,7 @@ static void john_load(void) } while ((current = current->next)); } else { database.options->flags |= DB_PLAINTEXTS; - ldr_show_pot_file(&database, POT_NAME); + ldr_show_pot_file(&database, options.loader.activepot); } return; @@ -156,7 +235,7 @@ static void john_load(void) options.loader.flags |= DB_CRACKED; ldr_init_database(&database, &options.loader); - ldr_show_pot_file(&database, POT_NAME); + ldr_show_pot_file(&database, options.loader.activepot); if ((current = options.passwd->head)) do { @@ -177,8 +256,10 @@ static void john_load(void) status.pass <= 1) options.loader.flags |= DB_WORDS; else - if (mem_saving_level) + if (mem_saving_level) { options.loader.flags &= ~DB_LOGIN; + options.loader.max_wordfile_memory = 0; + } ldr_init_database(&database, &options.loader); if ((current = options.passwd->head)) @@ -196,7 +277,7 @@ static void john_load(void) log_event("Loaded a total of %s", john_loaded_counts()); } - ldr_load_pot_file(&database, POT_NAME); + ldr_load_pot_file(&database, options.loader.activepot); ldr_fix_database(&database); @@ -275,7 +356,7 @@ static void john_run(void) if (options.flags & FLG_CRACKING_CHK) { if (!(options.flags & FLG_STDOUT)) { status_init(NULL, 1); - log_init(LOG_NAME, POT_NAME, options.session); + log_init(LOG_NAME, options.loader.activepot, options.session); john_log_format(); if (cfg_get_bool(SECTION_OPTIONS, NULL, "Idle", 1)) log_event("- Configured to use otherwise idle " @@ -293,6 +374,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 @@ -336,11 +420,16 @@ int main(int argc, char **argv) else if ((name = strrchr(argv[0], '/'))) name++; +#if defined(__CYGWIN32__) || defined (__MINGW32__) || defined (_MSC_VER) + else + if ((name = strrchr(argv[0], '\\'))) + name++; +#endif else name = argv[0]; #endif -#ifdef __CYGWIN32__ +#if defined(__CYGWIN32__) || defined (__MINGW32__) || defined (_MSC_VER) strlwr(name); if (strlen(name) > 4 && !strcmp(name + strlen(name) - 4, ".exe")) name[strlen(name) - 4] = 0; @@ -355,6 +444,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.5.orig/src/loader.c john-1.7.5/src/loader.c --- john-1.7.5.orig/src/loader.c 2010-02-23 20:11:55 +0000 +++ john-1.7.5/src/loader.c 2010-02-26 02:23:21 +0000 @@ -1,11 +1,17 @@ /* * This file is part of John the Ripper password cracker, * Copyright (c) 1996-2000,2003,2005,2010 by Solar Designer + * + * ...with heavy changes in the jumbo patch, by various authors */ #include #include +#if !defined (_MSC_VER) #include +#else +#define S_ISDIR(a) (a&_S_IFDIR) +#endif #include #include @@ -18,6 +24,9 @@ #include "signals.h" #include "formats.h" #include "loader.h" +#include "options.h" + +extern struct fmt_main fmt_NT; /* * Flags for read_file(). @@ -149,13 +158,13 @@ static void ldr_init_password_hash(struc memset(db->password_hash, 0, size); } -static char *ldr_get_field(char **ptr) +static char *ldr_get_field(char **ptr, char field_sep_char) { char *res, *pos; if (!*ptr) return ""; - if ((pos = strchr(res = *ptr, ':'))) { + if ((pos = strchr(res = *ptr, field_sep_char))) { *pos++ = 0; *ptr = pos; } else { pos = res; @@ -207,55 +216,159 @@ 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; int count; - *login = ldr_get_field(&line); + *login = ldr_get_field(&line, db_options->field_sep_char); if (!strcmp(*login, "+") || !strncmp(*login, "+@", 2)) return 0; - if (!*(*ciphertext = ldr_get_field(&line))) if (!line) return 0; + if (!*(*ciphertext = ldr_get_field(&line, db_options->field_sep_char))) if (!line) return 0; if (source) strcpy(source, line ? line : ""); - uid = ldr_get_field(&line); + uid = ldr_get_field(&line, db_options->field_sep_char); +/* 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, db_options->field_sep_char); /* 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, db_options->field_sep_char); + char *netlmv2 = ldr_get_field(&line, db_options->field_sep_char); + char *cli_challenge = ldr_get_field(&line, db_options->field_sep_char); + char *identity = NULL; + int i; + + identity = (char *) mem_alloc(strlen(*login) + strlen(uid) + 1); + strcpy(identity, *login); + strcat(identity, uid); + + /* Upper-Case Username and Domain */ + for(i=0; i= 'a') && (identity[i] <= 'z')) identity[i] ^= 0x20; + + tmp = (char *) mem_alloc_tiny(9 + strlen(identity) + 1 + strlen(srv_challenge) + 1 + strlen(netlmv2) + 1 + strlen(cli_challenge) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$NETLMv2$%s$%s$%s$%s", identity, srv_challenge, netlmv2, cli_challenge); + *ciphertext = tmp; + + MEM_FREE(identity); + } + else if (options.format && (strncmp(options.format, "netntlmv2", 9)==0)) { + char *srv_challenge = ldr_get_field(&line, db_options->field_sep_char); + char *netntlmv2 = ldr_get_field(&line, db_options->field_sep_char); + char *cli_challenge = ldr_get_field(&line, db_options->field_sep_char); + char *identity = NULL; + int i; + + identity = (char *) mem_alloc(strlen(*login) + strlen(uid) + 1); + strcpy(identity, *login); + strcat(identity, uid); + + /* Upper-Case Username - Not Domain */ + for(i=0; i= 'a') && (identity[i] <= 'z')) identity[i] ^= 0x20; + + tmp = (char *) mem_alloc_tiny(9 + strlen(identity) + 1 + strlen(srv_challenge) + 1 + strlen(netntlmv2) + 1 + strlen(cli_challenge) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$NETNTLMv2$%s$%s$%s$%s", identity, srv_challenge, netntlmv2, cli_challenge); + *ciphertext = tmp; + + MEM_FREE(identity); + } + else if (options.format && ((strncmp(options.format, "netlm", 5)==0) || + (strncmp(options.format, "netntlm", 7)==0))) { + char *netlm = ldr_get_field(&line, db_options->field_sep_char); + char *netntlm = ldr_get_field(&line, db_options->field_sep_char); + char *challenge = ldr_get_field(&line, db_options->field_sep_char); + + if (strncmp(options.format, "netlm", 5)==0) { + tmp = (char *) mem_alloc_tiny(7 + strlen(challenge) + 1 + strlen(netlm) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$NETLM$%s$%s", challenge, netlm); + *ciphertext = tmp; + } + else { + tmp = (char *) mem_alloc_tiny(9 + strlen(challenge) + 1 + strlen(netntlm) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$NETNTLM$%s$%s", challenge, netntlm); + *ciphertext = tmp; + } + } + else if (options.format && ((strncmp(options.format, "nethalflm", 9)==0))) { + char *nethalflm = ldr_get_field(&line, db_options->field_sep_char); + /*char *netntlm = ldr_get_field(&line, db_options->field_sep_char);*/ + char *challenge = ldr_get_field(&line, db_options->field_sep_char); + + if (strncmp(options.format, "nethalflm", 9)==0) { + tmp = (char *) mem_alloc_tiny(12 + strlen(challenge) + strlen(nethalflm) + 1, MEM_ALIGN_NONE); + sprintf(tmp, "$nethalflm$%s$%s", challenge, nethalflm); + *ciphertext = tmp; + } } - if ((options->flags & DB_WORDS) || options->shells->head) { - gid = ldr_get_field(&line); + if ((db_options->flags & DB_WORDS) || db_options->shells->head) { + if (!gid) + gid = ldr_get_field(&line, db_options->field_sep_char); do { - *gecos = ldr_get_field(&line); - *home = ldr_get_field(&line); - shell = ldr_get_field(&line); + *gecos = ldr_get_field(&line, db_options->field_sep_char); + *home = ldr_get_field(&line, db_options->field_sep_char); + shell = ldr_get_field(&line, db_options->field_sep_char); } while (!**gecos && !strcmp(*home, "0") && !strcmp(shell, "0")); } else - if (options->groups->head) { - gid = ldr_get_field(&line); + if (db_options->groups->head && !gid) { + gid = ldr_get_field(&line, db_options->field_sep_char); } - 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 (*format) return (*format)->methods.valid(*ciphertext); + 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) { + if (db_options->single_salts) + { + char *salt = (char*)(*format)->methods.salt(*ciphertext); + if (ldr_check_list(db_options->single_salts, salt, *ciphertext)) + return 0; + } + return (*format)->methods.valid(*ciphertext); + } if ((*format = fmt_list)) do { if ((count = (*format)->methods.valid(*ciphertext))) { fmt_init(*format); + if (db_options->single_salts) + { + char *salt = (char*)(*format)->methods.salt(*ciphertext); + if (ldr_check_list(db_options->single_salts, salt, *ciphertext)) + return 0; + } return count; } } while ((*format = (*format)->next)); @@ -303,6 +416,7 @@ static struct list_main *ldr_init_words( static void ldr_load_pw_line(struct db_main *db, char *line) { + static int skip_dupe_checking = 0; struct fmt_main *format; int index, count; char *login, *ciphertext, *gecos, *home; @@ -314,6 +428,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; @@ -341,18 +458,36 @@ static void ldr_load_pw_line(struct db_m ldr_init_password_hash(db); 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 = db->password_hash_func(binary); - if (!(db->options->flags & DB_WORDS)) { + if (!(db->options->flags & DB_WORDS) && !skip_dupe_checking) { + int collisions = 0; if ((current_pw = db->password_hash[pw_hash])) do { if (!memcmp(current_pw->binary, binary, format->params.binary_size) && !strcmp(current_pw->source, piece)) break; + if (collisions >= 1000) { + fprintf(stderr, +"Warning: excessive partial hash collisions detected\n%s", +db->password_hash_func != fmt_default_binary_hash ? "" : +"(cause: the \"format\" lacks proper binary_hash() function definitions)\n"); + skip_dupe_checking = 1; + current_pw = NULL; + break; + } + collisions++; } while ((current_pw = current_pw->next_hash)); if (current_pw) continue; @@ -442,7 +577,7 @@ static void ldr_load_pot_line(struct db_ int hash; struct db_password *current; - ciphertext = ldr_get_field(&line); + ciphertext = ldr_get_field(&line, db->options->field_sep_char); if (format->methods.valid(ciphertext) != 1) return; ciphertext = format->methods.split(ciphertext, 0); @@ -510,8 +645,11 @@ static void ldr_remove_marked(struct db_ last_pw->next = current_pw->next; else current_salt->list = current_pw->next; - } else + } else { last_pw = current_pw; + if (db->options->showuncracked) + printf("%s%c%s\n",current_pw->login,db->options->field_sep_char,current_pw->source); + } } while ((current_pw = current_pw->next)); if (!current_salt->list) { @@ -654,6 +792,9 @@ void ldr_fix_database(struct db_main *db ldr_init_hash(db); db->loaded = 1; + + if (db->options->showuncracked) + exit(0); } /* @@ -739,7 +880,7 @@ static void ldr_show_pot_line(struct db_ int hash; struct db_cracked *current, *last; - ciphertext = ldr_get_field(&line); + ciphertext = ldr_get_field(&line, db->options->field_sep_char); if (line) { /* If just one format was forced on the command line, insist on it */ @@ -788,6 +929,8 @@ 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); @@ -801,6 +944,13 @@ static void ldr_show_pw_line(struct db_m 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; @@ -809,7 +959,7 @@ static void ldr_show_pw_line(struct db_m if (!*ciphertext) { found = 1; - if (show) printf("%s:NO PASSWORD", login); + if (show) printf("%s%cNO PASSWORD", login, db->options->field_sep_char); db->guess_count++; } else @@ -862,14 +1012,14 @@ static void ldr_show_pw_line(struct db_m } else if (current) { found = 1; - if (show) printf("%s:", login); + if (show) printf("%s%c", login, db->options->field_sep_char); break; } } if (found && show) { if (source[0]) - printf(":%s", source); + printf("%c%s", db->options->field_sep_char, source); else putchar('\n'); } diff -urpN john-1.7.5.orig/src/loader.h john-1.7.5/src/loader.h --- john-1.7.5.orig/src/loader.h 2010-01-18 05:19:40 +0000 +++ john-1.7.5/src/loader.h 2010-01-19 07:01:39 +0000 @@ -148,10 +148,32 @@ struct db_options { unsigned int flags; /* Filters to use while loading */ - struct list_main *users, *groups, *shells; + struct list_main *users, *groups, *shells, *single_salts; /* Requested passwords per salt */ int min_pps, max_pps; + +/* Maximum size of a wordlist file to be 'preloaded' into memory */ + unsigned max_wordfile_memory; + +/* number of times fix_state_delay is called in wordfile.c before any fseek() is done. */ + unsigned max_fix_state_delay; + +/* the wordlist rules section (default if none entered is Wordlist) */ + char *activewordlistrules; + +/* the 'single' rules section (default if none entered is Single) */ + char *activesinglerules; + +/* the pot file used (default if none entered is $JOHN/john.pot or JOHN_PRIVATE_HOME/john.pot + depending upon compile defines) */ + char *activepot; + +/* if --show=left is used, this is set, and john dumps the non-cracked hashes and exits */ + int showuncracked; + +/* by default will be ':', but -field-separator-char=c can over ride the default */ + char field_sep_char; }; /* diff -urpN john-1.7.5.orig/src/logger.c john-1.7.5/src/logger.c --- john-1.7.5.orig/src/logger.c 2010-02-25 23:31:42 +0000 +++ john-1.7.5/src/logger.c 2010-02-26 02:02:39 +0000 @@ -4,10 +4,17 @@ */ #include +#if !defined (_MSC_VER) #include +#include +#else +#include +#pragma warning ( disable : 4996 ) +#define S_IRUSR _S_IREAD +#define S_IWUSR _S_IWRITE +#endif #include #include -#include #include #include #include @@ -36,6 +43,11 @@ struct log_file { int fd; }; +#if defined (_MSC_VER) +// In release mode, the log() function gets in the way of our log struct object +#define log local_log_struct +#endif + static struct log_file log = {NULL, NULL, NULL, 0, -1}; static struct log_file pot = {NULL, NULL, NULL, 0, -1}; @@ -91,7 +103,7 @@ static void log_file_fsync(struct log_fi if (f->fd < 0) return; log_file_flush(f); -#ifndef __CYGWIN32__ +#if !defined(__CYGWIN32__) && !defined(__MINGW32__) && !defined(_MSC_VER) if (fsync(f->fd)) pexit("fsync"); #endif } @@ -138,7 +150,7 @@ void log_init(char *log_name, char *pot_ in_logger = 0; } -void log_guess(char *login, char *ciphertext, char *plaintext) +void log_guess(char *login, char *ciphertext, char *plaintext, char field_sep) { int count1, count2; @@ -149,7 +161,7 @@ void log_guess(char *login, char *cipher if (pot.fd >= 0 && ciphertext && strlen(ciphertext) + strlen(plaintext) <= LINE_BUFFER_SIZE - 3) { count1 = (int)sprintf(pot.ptr, - "%s:%s\n", ciphertext, plaintext); + "%s%c%s\n", ciphertext, field_sep, plaintext); if (count1 > 0) pot.ptr += count1; } diff -urpN john-1.7.5.orig/src/logger.h john-1.7.5/src/logger.h --- john-1.7.5.orig/src/logger.h 2003-09-06 20:30:26 +0000 +++ john-1.7.5/src/logger.h 2009-08-22 18:54:06 +0000 @@ -19,7 +19,7 @@ extern void log_init(char *log_name, cha * Prints a guessed password to stdout and logs it to john.pot (unless * ciphertext is NULL) and other related information to the log file. */ -extern void log_guess(char *login, char *ciphertext, char *plaintext); +extern void log_guess(char *login, char *ciphertext, char *plaintext, char field_sep); /* * Logs an arbitrary event. diff -urpN john-1.7.5.orig/src/lotus5_fmt.c john-1.7.5/src/lotus5_fmt.c --- john-1.7.5.orig/src/lotus5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/lotus5_fmt.c 2010-02-26 02:31:04 +0000 @@ -0,0 +1,251 @@ +//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 !ciphertext[i]; +} + +/*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, + NULL, + NULL + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + get_hash1, + get_hash2, + get_hash3, + NULL, + NULL + }, + cmp_all, + cmp_all, + cmp_exact} +}; diff -urpN john-1.7.5.orig/src/md4.c john-1.7.5/src/md4.c --- john-1.7.5.orig/src/md4.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/md4.h john-1.7.5/src/md4.h --- john-1.7.5.orig/src/md4.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/md5-mmx.S john-1.7.5/src/md5-mmx.S --- john-1.7.5.orig/src/md5-mmx.S 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/md5.c john-1.7.5/src/md5.c --- john-1.7.5.orig/src/md5.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/md5.h john-1.7.5/src/md5.h --- john-1.7.5.orig/src/md5.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/md5_eq.c john-1.7.5/src/md5_eq.c --- john-1.7.5.orig/src/md5_eq.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/md5_gen.h john-1.7.5/src/md5_gen.h --- john-1.7.5.orig/src/md5_gen.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/md5_gen.h 2009-10-28 20:28:20 +0000 @@ -0,0 +1,145 @@ +/* + * This software was written by Jim Fougeron jfoug AT cox dot net + * in 2009. No copyright is claimed, and the software is hereby + * placed in the public domain. In case this attempt to disclaim + * copyright and place the software in the public domain is deemed + * null and void, then the software is Copyright © 2009 Jim Fougeron + * and it is hereby released to the general public under the following + * terms: + * + * This software may be modified, redistributed, and used for any + * purpose, in source and binary forms, with or without modification. + * + * Generic MD5 hashes cracker + * + * Interface functions and data structures required to make this + * work, since it is split over multiple .c source files. + * + */ + +#if !defined (__MD5_GEN___H) +#define __MD5_GEN___H + +typedef void(*MD5_GEN_primitive_funcp)(); + +typedef struct MD5_GEN_Preloads_t +{ + char *Hash; + char *Passwd; +} MD5_GEN_Preloads; + +#define MGF_NOTSSE2Safe 0x01 +#define MGF_ColonNOTValid 0x02 +#define MGF_SALTED 0x04 +#define MGF_SALTED2 0x08 +#define MGF_USERID 0x10 +#define MGF_INPBASE64 0x20 +#define MFG_SALT_AS_HEX 0x40 + +typedef struct MD5_GEN_Setup_t +{ + char *szFORMAT_NAME; // md5(md5($p).$s) etc + + // Ok, this will be the functions to 'use'. + // This should be a 'null' terminated list. 5000 is MAX. + MD5_GEN_primitive_funcp *pFuncs; + MD5_GEN_Preloads *pPreloads; + unsigned flags; + int SaltLen; +} MD5_GEN_Setup; + +void md5_gen_SETUP(MD5_GEN_Setup *); +int md5_gen_IS_VALID(int i); +void md5_gen_RESET(); +void md5_gen_RESET_LINK(struct fmt_main *pFmt, char *ciphertext, char *orig_sig); +void md5_gen_DISPLAY_ALL_FORMATS(); + +void md5_gen_RESERVED_PRELOAD_SETUP(int cnt); +char *md5_gen_PRELOAD_SIGNATURE(int cnt); + +// Here aer the 'parser' functions (i.e. user built stuff in john.conf) +int md5_gen_LOAD_PARSER_FUNCTIONS(int which); +char *md5_gen_LOAD_PARSER_SIGNATURE(int which); + +// +// These functions MUST be of type: void function() +// these are the 'base' predicate functions used in +// building a generic MD5 attack algorithm. +// + +extern void MD5GenBaseFunc__clean_input(); +extern void MD5GenBaseFunc__clean_input_kwik(); +extern void MD5GenBaseFunc__append_keys(); +extern void MD5GenBaseFunc__crypt(); +extern void MD5GenBaseFunc__append_from_last_output_as_base16(); +extern void MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix(); +extern void MD5GenBaseFunc__append_salt(); +extern void MD5GenBaseFunc__set_input_len_32(); +extern void MD5GenBaseFunc__set_input_len_64(); + +extern void MD5GenBaseFunc__clean_input2(); +extern void MD5GenBaseFunc__clean_input2_kwik(); +extern void MD5GenBaseFunc__append_keys2(); +extern void MD5GenBaseFunc__crypt2(); +extern void MD5GenBaseFunc__append_from_last_output2_as_base16(); +extern void MD5GenBaseFunc__overwrite_from_last_output2_as_base16_no_size_fix(); +extern void MD5GenBaseFunc__append_from_last_output_to_input2_as_base16(); +extern void MD5GenBaseFunc__overwrite_from_last_output_to_input2_as_base16_no_size_fix(); +extern void MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16(); +extern void MD5GenBaseFunc__overwrite_from_last_output2_to_input1_as_base16_no_size_fix(); +extern void MD5GenBaseFunc__append_salt2(); +extern void MD5GenBaseFunc__set_input2_len_32(); +extern void MD5GenBaseFunc__set_input2_len_64(); + +extern void MD5GenBaseFunc__overwrite_salt_to_input1_no_size_fix(); +extern void MD5GenBaseFunc__overwrite_salt_to_input2_no_size_fix(); + +extern void MD5GenBaseFunc__append_input_from_input2(); +extern void MD5GenBaseFunc__append_input2_from_input(); + +extern void MD5GenBaseFunc__append_2nd_salt(); +extern void MD5GenBaseFunc__append_2nd_salt2(); +extern void MD5GenBaseFunc__append_userid(); +extern void MD5GenBaseFunc__append_userid2(); + +extern void MD5GenBaseFunc__crypt_in1_to_out2(); +extern void MD5GenBaseFunc__crypt_in2_to_out1(); + +// These 2 dump the raw crypt back into input (only at the head of it). +// they are for phpass, wordpress, etc. +extern void MD5GenBaseFunc__crypt_to_input_raw_Overwrite_NoLen(); +extern void MD5GenBaseFunc__crypt_to_input_raw(); + +// special for phpass +extern void MD5GenBaseFunc__PHPassSetup(); +extern void MD5GenBaseFunc__PHPassCrypt(); + +// This is an optimimization function (actually NOT a function, but +// changes the behavior of the format.setkey() and format.getkey() to +// load and retrieve directly to the input. NOTE the function +// MUST observe certain characteristics before this optimization +// can be used. The function MUST be something that the first thing +// used is the $p, and it is packed to the bottom of an input. +// Also, the 2nd input must be used for ALL work after the initial +// crypt of the input, due to the getkey() having to retrieve from +// the input data. However, IF the expression 'fits' and can be +// written to work safely with this pseudo function, then we cut out +// a buffer copy, and can save a lot of time. Getting this working +// changed md5($p) from being about 85% the speed of raw-md5 to being +// about 102% the speed of raw-md5 (yes, FASTER). It also improves +// a lot of the simple ( md5(md5($p).$s), etc), about 10% or more. +// When used, this function can ONLY be the first called function. +// If used 'after' the first, the loader will abort with an error. +extern void MD5GenBaseFunc__InitialLoadKeysToInput(); +extern void MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2(); +extern void MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1(); +extern void MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1_offset32(); + +#define ARRAY_COUNT(a) (sizeof(a)/sizeof(a[0])) + +// We need access to this global to get functions and data which we 'link' to +extern struct fmt_main fmt_MD5gen; + +// End of generic md5 'types' and helpers + +#endif // __MD5_GEN___H diff -urpN john-1.7.5.orig/src/md5_gen_fmt.c john-1.7.5/src/md5_gen_fmt.c --- john-1.7.5.orig/src/md5_gen_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/md5_gen_fmt.c 2010-02-02 02:19:48 +0000 @@ -0,0 +1,1967 @@ +/* + * This software was written by Jim Fougeron jfoug AT cox dot net + * in 2009. No copyright is claimed, and the software is hereby + * placed in the public domain. In case this attempt to disclaim + * copyright and place the software in the public domain is deemed + * null and void, then the software is Copyright © 2009 Jim Fougeron + * and it is hereby released to the general public under the following + * terms: + * + * This software may be modified, redistributed, and used for any + * purpose, in source and binary forms, with or without modification. + * + * Generic MD5 hashes cracker + * + * It uses the openSSL md5 for x86, and MMX/SSE2 md5 from md5-mmx.S + * + * Only valid up to 54 bytes max string length (salts, rehashes, + * passwords, etc) if using SSE2. 96 byte keys (appended salts, + * keys, re-hashes, etc), if running under x86 mode. NOTE some + * hashes will NOT run properly under SSE2. A hash such as + * md5(md5($p).md5($s)) would fail under SSE2, since it always + * would need at least 64 bytes to complete but even md5($p) would + * fail in SSE2 if the password is over 54 bytes. NOTE no run-time + * checks are made so if you provide data too large, it will not find + * the hash, and will 'overwrite' some of the hashes being worked on, + * and cause them to have invalid results. This is a bug that 'might' + * be worked on, but I do not want do slow the cracking down performing + * checks. + * + * This code has gone through a few iterations, and now is quite a bit + * more mature. It has been designed with an array for keys (which + * is optionally used), a slot for the current salt, 2 arrays for + * input buffers (there is optional loading that loads keys directly + * into input buffer #1 as an optimization for certain formats), and + * a pair of arrays for crypt outputs. The 'first' output buffer array + * is used to return the final results. There is also 2 arrays of lengths + * of input buffers. There are then 'primative' functions. These can + * append keys, append salts, blank out keys, move from input 1 to input + * 2, crypt input 1 -> output 1, (or from 1->2 or 2->2 or 2->1, etc). + * There are functions that do base 16 conversions of the outputs back + * into inputs (O1->I1 in base 16, 1->2 2->2 2->1, etc). There are + * functions that over write the start of an input buffer from outputs + * without 'adjusting' the lengths. There are a few special functions + * to do phpass work. + * + * Then there are helper functions which allow another format to 'use' + * the generic MD5 code. So, we can make a VERY thin raw-md5 (or phpass + * md5), where it simply has a format structure (which does not need to be + * 'heavily' filled out, and that format only needs to implement a few + * functions on its own. It would need to implement init, valid, salt + * and binary. Then there needs to be a 'conversion' function that + * converts from the 'native' format, into the native GENERIC format. + * Then, within the init function, that format would hook into the + * generic md5, by calling the md5_gen_RESET_LINK() function, passing + * in its Format structure to have functions pointed into the md5 generic + * stuff. The conversion function is likely very trivial. For phpass, we + * convert from + * $H$9aaaaaSXBjgypwqm.JsMssPLiS8YQ00 + * to + * md5_gen(17)jgypwqm.JsMssPLiS8YQ00$9aaaaaSXB + * + * Here is that convert function: + * static char *Convert(char *Buf, char *ciphertext) { + * sprintf(Buf, "md5_gen(17)%s%10.10s", &ciphertext[3+8+1], &ciphertext[2]); + * return Buf; + * } + * + * + * Generic MD5 can now be user expanded. The first 1000 md5_gen(#) are + * reserved as 'built-in' functions for john. Above 1000 is free to use + * for anyone wanting to do so. NO programming changes are needed to + * add a format. All that is needed is modifcations to john.conf. There is + * FULL documentation about how to do this in doc/MD5_GENERIC. There is + * no parser 'generation' logic. A person would have to understand the + * primitive functions and how they work. But the format can be added + * without a rebuild of john. There are 7 (or 8) examples already done + * in john.conf at this time, which should make it pretty easy for someone + * wanting to do a new or obscure format. + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "md5.h" +#include "md5_gen.h" +#include "options.h" +#include "config.h" + +/* Data which is 'set' at init-step2 setup time */ + +// this 'will' be replaced, and will 'replace' FORMAT_NAME +static int md5_gen_FIXED_SALT_SIZE = 0; +static int md5_gen_SALT_OFFSET; +static int md5_gen_HASH_OFFSET; +static MD5_GEN_primitive_funcp md5_gen_FUNCTIONS[5000]; +// 0 for 'raw-md5', 1 for vBulletin, etc. See md5_gen_preloads.c for 'official' types +// -1 for not yet set. Once it is set, it 'stays' set, and only works for THAT type. +static int md5_gen_WHICH_TYPE=-1; +static char md5_gen_WHICH_TYPE_SIG[40]; + +#define FORMAT_LABEL "md5-gen" +#define FORMAT_NAME "Generic MD5" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "md5-gen MMX 32x2" +#else +#define ALGORITHM_NAME "md5-gen SSE2 16x4" +#endif +#else +#define ALGORITHM_NAME "md5-gen 64x1" +#endif + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH -1 + +#ifdef MMX_COEF +#define PLAINTEXT_LENGTH 53 +#else +// Would LOVE to go to 128 bytes (would allow md5(md5($p).md5($p).md5($p).md5($p)) but +// due to other parts of john, we can only go to 128-3 as max sized plaintext. +#define PLAINTEXT_LENGTH 125 +#endif + +#define CIPHERTEXT_LENGTH 32 + +#define BINARY_SIZE 16 +#define SALT_SIZE 64 + +#ifdef MMX_COEF +#if MMX_COEF==2 +#define BLOCK_LOOPS 32 +#else +#define BLOCK_LOOPS 16 +#endif +#define MIN_KEYS_PER_CRYPT MMX_COEF*BLOCK_LOOPS +#define MAX_KEYS_PER_CRYPT MMX_COEF*BLOCK_LOOPS +#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 64 +#endif + +// slots to do 24 'tests'. Note, we copy the +// same 3 tests over and over again. Simply to validate that +// tests use 'multiple' blocks. +static struct fmt_tests md5_gen_tests[] = { + {NULL},{NULL},{NULL},{NULL},{NULL},{NULL},{NULL},{NULL}, + {NULL},{NULL},{NULL},{NULL},{NULL},{NULL},{NULL},{NULL}, + {NULL},{NULL},{NULL},{NULL},{NULL},{NULL},{NULL},{NULL},{NULL} +}; + +#ifdef MMX_COEF +// SSE2 works only with 54 byte keys. Thus, md5(md5($p).md5($s)) can NOT be used +// with the SSE2, since that final md5 will be over a 64 byte block of data. +#define input_buf genMD5_input_buf +#define input_buf2 genMD5_input_buf2 +#define crypt_key genMD5_crypt_key +#define crypt_key2 genMD5_crypt_key2 +unsigned char input_buf[BLOCK_LOOPS][64*MMX_COEF] __attribute__ ((aligned(16))); +unsigned char input_buf2[BLOCK_LOOPS][64*MMX_COEF] __attribute__ ((aligned(16))); +unsigned char crypt_key[BLOCK_LOOPS][BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +unsigned char crypt_key2[BLOCK_LOOPS][BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static unsigned int total_len[BLOCK_LOOPS]; +static unsigned int total_len2[BLOCK_LOOPS]; +#else +// Our code uses the OpenSSL md5() functions. +static MD5_CTX ctx; +// Allows us to work with up to 96 byte keys in the non-sse2 code +static unsigned char input_buf[MAX_KEYS_PER_CRYPT][PLAINTEXT_LENGTH+1]; +static unsigned char input_buf2[MAX_KEYS_PER_CRYPT][PLAINTEXT_LENGTH+1]; +static unsigned char crypt_key[MAX_KEYS_PER_CRYPT][BINARY_SIZE]; +static unsigned char crypt_key2[MAX_KEYS_PER_CRYPT][BINARY_SIZE]; +static unsigned int total_len[MAX_KEYS_PER_CRYPT]; +static unsigned int total_len2[MAX_KEYS_PER_CRYPT]; +#endif + +// if the format is non-base16 (i.e. base-64), then this flag is set, and +// a the hash loading function uses it. +static int md5_gen_base64_inout; +// if set, then we load keys directly into input1 and NOT into the saved_key buffers +static int store_keys_in_input; +static int store_keys_normal_but_precompute_md5_to_output2; +static int store_keys_normal_but_precompute_md5_to_output2_base16_to_input1; +static int store_keys_normal_but_precompute_md5_to_output2_base16_to_input1_offset32; + +static int md5_gen_salt_as_hex; + +static int store_keys_normal_but_precompute_md5_to_output2_dirty; +// Used in 'get_key' if we are running in store_keys_in_input mode +static char out[PLAINTEXT_LENGTH+1]; +// We store the salt here +static char cursalt[SALT_SIZE+1]; +// length of salt (so we don't have to call strlen() all the time. +static int saltlen; +// array of the keys. Also lengths of the keys. NOTE if store_keys_in_input, then the +// key array will NOT be used (but the length array still is). +static char saved_key[MAX_KEYS_PER_CRYPT][PLAINTEXT_LENGTH+1]; +static int saved_key_len[MAX_KEYS_PER_CRYPT]; + +// This is the GLOBAL count of keys. ALL of the primitives which deal with a count +// will read from this variable. +static int m_count; + +/* + * This function will 'forget' which md5-gen subtype we are working with. It will allow + * a different type to be used. Very useful for things like -test (benchmarking). + */ +void md5_gen_RESET() +{ + if (fmt_MD5gen.private.initialized == 0) { + fmt_MD5gen.methods.init(); + fmt_MD5gen.private.initialized = 1; + } + + md5_gen_WHICH_TYPE = -1; + memset(md5_gen_FUNCTIONS, 0, sizeof(md5_gen_FUNCTIONS)); + memset(md5_gen_WHICH_TYPE_SIG, 0, sizeof(md5_gen_WHICH_TYPE_SIG)); + m_count = 0; + md5_gen_base64_inout = 0; + store_keys_in_input = 0; + md5_gen_salt_as_hex = 0; + store_keys_normal_but_precompute_md5_to_output2 = 0; + store_keys_normal_but_precompute_md5_to_output2_base16_to_input1 = 0; + store_keys_normal_but_precompute_md5_to_output2_base16_to_input1_offset32 = 0; + store_keys_normal_but_precompute_md5_to_output2_dirty = 0; + saltlen = 0; +} + +/* + * This will LINK our functions into some other fmt_main struction. That way + * that struction can use our code. The other *_fmt.c file will need to + * 'override' the valid, the binary and the salt functions, and make changes + * to the hash, BEFORE calling into the md5_gen valid/binary/salt functions. + * Other than those functions (and calling into this linkage function at init time) + * that is about all that needs to be in that 'other' *_fmt.c file, as long as the + * format is part of the md5-generic 'class' of functions. + */ +void md5_gen_RESET_LINK(struct fmt_main *pFmt, char *ciphertext, char *orig_sig) +{ + int i; + static char subformat[17], *cp; + md5_gen_RESET(); + strncpy(subformat, ciphertext, 16); + subformat[16] = 0; + cp = strchr(subformat, ')'); + if (cp) + cp[1] = 0; + options.subformat = subformat; + fmt_MD5gen.methods.valid(ciphertext); + + printf ("Using %s mode, by linking to %s functions", orig_sig, subformat); + // If benchmarking, simply add a space. If not, then add a newline. + if (options.flags & FLG_TEST_CHK) + printf (" "); + else + printf ("\n"); + + pFmt->params.max_keys_per_crypt = fmt_MD5gen.params.max_keys_per_crypt; + pFmt->params.min_keys_per_crypt = fmt_MD5gen.params.min_keys_per_crypt; + pFmt->methods.cmp_all = fmt_MD5gen.methods.cmp_all; + pFmt->methods.cmp_one = fmt_MD5gen.methods.cmp_one; + pFmt->methods.cmp_exact = fmt_MD5gen.methods.cmp_exact; + pFmt->methods.set_salt = fmt_MD5gen.methods.set_salt; + pFmt->methods.salt_hash = fmt_MD5gen.methods.salt_hash; + pFmt->methods.split = fmt_MD5gen.methods.split; + pFmt->methods.set_key = fmt_MD5gen.methods.set_key; + pFmt->methods.get_key = fmt_MD5gen.methods.get_key; + pFmt->methods.clear_keys = fmt_MD5gen.methods.clear_keys; + pFmt->methods.crypt_all = fmt_MD5gen.methods.crypt_all; + for (i = 0; i < 5; ++i) + { + pFmt->methods.binary_hash[i] = fmt_MD5gen.methods.binary_hash[i]; + pFmt->methods.get_hash[i] = fmt_MD5gen.methods.get_hash[i]; + } +} + +void md5_gen_DISPLAY_ALL_FORMATS() +{ + int i; + for (i = 0; i < 1000; ++i) + { + char *sz = md5_gen_PRELOAD_SIGNATURE(i); + if (!sz) + break; + printf ("Format = md5_gen(%d)%s type = %s\n", i, i<10?" ":"", sz); + } + + // The config has not been loaded, so we have to load it now, if we want to 'check' + // and show any user set md5-generic functions. +#if JOHN_SYSTEMWIDE + cfg_init(CFG_PRIVATE_FULL_NAME, 1); + cfg_init(CFG_PRIVATE_ALT_NAME, 1); +#endif + cfg_init(CFG_FULL_NAME, 1); + cfg_init(CFG_ALT_NAME, 0); + + for (i = 1000; i < 10000; ++i) + { + char *sz = md5_gen_LOAD_PARSER_SIGNATURE(i); + if (sz) + printf ("UserFormat = md5_gen(%d)%s type = %s\n", i, i<10?" ":"", sz); + } +} + +/********************************************************************************* + ********************************************************************************* + * Start of the 'normal' *_fmt code for md5-gen + ********************************************************************************* + *********************************************************************************/ + +/********************************************************************************* + * Detects a 'valid' md5-gen, and 'locks us' into that format. Once locked in, + * ONLY that format will be deemed valid. Any other generic md5 line, or other + * type data line will be called invalid. A call to RESET (above) will clear + * out this 'locked into' mentality, and let valid again search for a new type. + *********************************************************************************/ +static int valid(char *ciphertext) +{ + int i; + char *cp; + if (md5_gen_WHICH_TYPE == -1) + { + int type, cnt; + extern struct options_main options; + type = -1; + if (options.subformat) + { + cnt = sscanf(options.subformat, "md5_gen(%d)", &type); + if (cnt != 1) + type = 0; + } + if (ciphertext == NULL) + { + if (type == -1) + type = 0; + // This is caused by doing a -test + // we check to see if the user have provided a -subformat= and if + // so, use it. If NOT, we simply user format 0. + md5_gen_WHICH_TYPE = type; + if (type < 1000) + md5_gen_RESERVED_PRELOAD_SETUP(type); + else + md5_gen_LOAD_PARSER_FUNCTIONS(type); + md5_gen_HASH_OFFSET = sprintf(md5_gen_WHICH_TYPE_SIG, "md5_gen(%d)", type); + if (md5_gen_base64_inout) + md5_gen_SALT_OFFSET = md5_gen_HASH_OFFSET + 22 + 1; + else + md5_gen_SALT_OFFSET = md5_gen_HASH_OFFSET + 32 + 1; + return 0; + } + + if (type == -1) { + cnt = sscanf(ciphertext, "md5_gen(%d)", &type); + if (cnt != 1) + return 0; + } + md5_gen_WHICH_TYPE = type; + if (type < 1000) + md5_gen_RESERVED_PRELOAD_SETUP(type); + else + md5_gen_LOAD_PARSER_FUNCTIONS(type); + md5_gen_HASH_OFFSET = sprintf(md5_gen_WHICH_TYPE_SIG, "md5_gen(%d)", type); + if (md5_gen_base64_inout) + md5_gen_SALT_OFFSET = md5_gen_HASH_OFFSET + 22 + 1; + else + md5_gen_SALT_OFFSET = md5_gen_HASH_OFFSET + 32 + 1; + } + else + { + if (strncmp(ciphertext, md5_gen_WHICH_TYPE_SIG, strlen(md5_gen_WHICH_TYPE_SIG))) + return 0; + } + cp = &ciphertext[strlen(md5_gen_WHICH_TYPE_SIG)]; + + if (md5_gen_base64_inout) + { + // jgypwqm.JsMssPLiS8YQ00$BaaaaaSX + int i; + for (i = 0; i < 22; ++i) + if (atoi64[ARCH_INDEX(cp[i])] == 0x7F) + return 0; + if (md5_gen_FIXED_SALT_SIZE && cp[22] != '$') + return 0; + if (md5_gen_FIXED_SALT_SIZE > 0 && strlen(&cp[23]) != md5_gen_FIXED_SALT_SIZE) + return 0; + return 1; + } + + if (md5_gen_base64_inout) + { + if (strlen(cp) < 22) + return 0; + } + else + { + if (strlen(cp) < 32) + return 0; + } + for (i = 0; i < CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= cp[i])&&(cp[i] <= '9')) || + (('a' <= cp[i])&&(cp[i] <= 'f')) )) + return 0; + } + if (md5_gen_FIXED_SALT_SIZE && ciphertext[md5_gen_SALT_OFFSET-1] != '$') + return 0; + if (md5_gen_FIXED_SALT_SIZE > 0 && strlen(&ciphertext[md5_gen_SALT_OFFSET]) != md5_gen_FIXED_SALT_SIZE) + return 0; + return 1; +} + +/********************************************************************************* + * init() here does nothing. NOTE many formats LINKING into us will have a valid + * that DOES do something, but ours does nothing. + *********************************************************************************/ +static void md5_gen_init(void) { } + +/********************************************************************************* + * Stores the new salt provided into our 'working' salt + *********************************************************************************/ +static void md5_gen_set_salt(void *salt) +{ + memset(cursalt, 0, sizeof(cursalt)); + strncpy(cursalt, salt, SALT_SIZE); + cursalt[SALT_SIZE] = 0; + saltlen = strlen(cursalt); +} + +/********************************************************************************* + * init() here does nothing. NOTE many formats LINKING into us will have a valid that + * NOTE specific for phpass. We internally look at a salt as 8 bytes, but external + * it is 9. NOTE in the crypt, we DO use that last byte. It tells crypt how many + * times to loop. However, within ALL of the primitive functions, they only work + * with the first 8 bytes of the salt (the true salt value), and ignore that 9th + * byte. + *********************************************************************************/ +static void phpass_gen_set_salt(void *salt) +{ + //memset(cursalt, 0, sizeof(cursalt)); + strncpy(cursalt, salt, saltlen+1); + cursalt[saltlen+1] = 0; +} + +/********************************************************************************* + * Sets this key. It will either be dropped DIRECTLY into the input buffer + * number 1, or put into an array of keys. Which one happens depends upon + * HOW the generic functions were laid out for this type. Not all types can + * load into the input. If not they MUST use the key array. Using the input + * buffer is faster, when it can be safely done. + *********************************************************************************/ +static void md5_gen_set_key(char *key, int index) +{ + if (store_keys_in_input) + { + unsigned int len = strlen(key); +#ifdef MMX_COEF + unsigned int i, cnt; + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + ARCH_WORD_32 *pi = (ARCH_WORD_32 *)key; + ARCH_WORD_32 *po = &((ARCH_WORD_32 *)(&(input_buf[idx])))[index&(MMX_COEF-1)]; + if(index==0) + MD5GenBaseFunc__clean_input(); + if (len > 54) + len = 54; + cnt = len>>2; + for (i = 0; i < cnt; ++i) + { + *po = *pi++; + po += MMX_COEF; + } + for(i=cnt<<2;i>(MMX_COEF>>1)); + + s = saved_key_len[index]; + for(i=0;i>(MMX_COEF>>1)); + for (j = 0; j < cnt; ++j) + { + unsigned int SomethingGood = 1; + i = 0; + while(i < (BINARY_SIZE/4) ) + { + if ( + ( ((unsigned long *)binary)[i] != ((unsigned long *)&(crypt_key[j]))[i*MMX_COEF]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)&(crypt_key[j]))[i*MMX_COEF+1]) +#if (MMX_COEF > 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)&(crypt_key[j]))[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)&(crypt_key[j]))[i*MMX_COEF+3]) +#endif + ) + { + SomethingGood = 0; + break; + } + ++i; + } + if (SomethingGood) + return 1; + } + return 0; +#else + unsigned int i; + + for (i = 0; i < count; i++) { + if (!(*((unsigned int*)binary) - *((unsigned int*)&crypt_key[i]))) + { + if (!(((unsigned int*)binary)[1] - ((unsigned int*)&crypt_key[i])[1] ) && + !(((unsigned int*)binary)[2] - ((unsigned int*)&crypt_key[i])[2] ) && + !(((unsigned int*)binary)[3] - ((unsigned int*)&crypt_key[i])[3] ) ) + return 1; + } + } + + return 0; +#endif +} + +/********************************************************************************* + * In this code, we always do exact compare, so if this function is called, it + * simply returns true. + *********************************************************************************/ +static int md5_gen_cmp_exact(char *source, int index) +{ +#ifdef MMX_COEF + return 1; +#else + return 1; +#endif +} + +/********************************************************************************* + * There was 'something' that was possibly hit. Now john will ask us to check + * each one of the data items, for an 'exact' match. + *********************************************************************************/ +static int md5_gen_cmp_one(void *binary, int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return((((ARCH_WORD_32 *)binary)[0] == ((ARCH_WORD_32 *)&(crypt_key[idx]))[0*MMX_COEF+(index&(MMX_COEF-1))]) && + (((ARCH_WORD_32 *)binary)[1] == ((ARCH_WORD_32 *)&(crypt_key[idx]))[1*MMX_COEF+(index&(MMX_COEF-1))]) && + (((ARCH_WORD_32 *)binary)[2] == ((ARCH_WORD_32 *)&(crypt_key[idx]))[2*MMX_COEF+(index&(MMX_COEF-1))]) && + (((ARCH_WORD_32 *)binary)[3] == ((ARCH_WORD_32 *)&(crypt_key[idx]))[3*MMX_COEF+(index&(MMX_COEF-1))]) + ); +#else + if (!(*((unsigned int*)binary) - *((unsigned int*)&crypt_key[index])) && + !(((unsigned int*)binary)[1] - ((unsigned int*)&crypt_key[index])[1] ) && + !(((unsigned int*)binary)[2] - ((unsigned int*)&crypt_key[index])[2] ) && + !(((unsigned int*)binary)[3] - ((unsigned int*)&crypt_key[index])[3] ) ) + return 1; + return 0; +#endif +} + +/********************************************************************************* + ********************************************************************************* + * This is the real 'engine'. It simply calls functions one + * at a time from the array of functions. + ********************************************************************************* + *********************************************************************************/ +static void md5_gen_crypt_all(int count) +{ + // get plaintext input in saved_key put it into ciphertext crypt_key + int i; + m_count = count; + + if (store_keys_normal_but_precompute_md5_to_output2 && store_keys_normal_but_precompute_md5_to_output2_dirty) + { + store_keys_normal_but_precompute_md5_to_output2_dirty = 0; + MD5GenBaseFunc__clean_input2(); + MD5GenBaseFunc__append_keys2(); + MD5GenBaseFunc__crypt2(); + + if (store_keys_normal_but_precompute_md5_to_output2_base16_to_input1) + { + MD5GenBaseFunc__clean_input(); + MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16(); + } + if (store_keys_normal_but_precompute_md5_to_output2_base16_to_input1_offset32) + { + MD5GenBaseFunc__clean_input(); + MD5GenBaseFunc__set_input_len_32(); + MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16(); + } + } + + for (i = 0; i>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xf; +#else + return ((ARCH_WORD_32 *)&(crypt_key[index]))[0] & 0xf; +#endif +} + +int md5_gen_get_hash_1(int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xff; +#else + return ((ARCH_WORD_32 *)&(crypt_key[index]))[0] & 0xff; +#endif +} + +int md5_gen_get_hash_2(int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xfff; +#else + return ((ARCH_WORD_32 *)&(crypt_key[index]))[0] & 0xfff; +#endif +} + +int md5_gen_get_hash_3(int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xffff; +#else + return ((ARCH_WORD_32 *)&(crypt_key[index]))[0] & 0xffff; +#endif +} +int md5_gen_get_hash_4(int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xfffff; +#else + return ((ARCH_WORD_32 *)&(crypt_key[index]))[0] & 0xfffff; +#endif +} + +/********************************************************************************* + * 'normal' get salt function. We simply return a pointer past the '$' char + *********************************************************************************/ +static void *get_salt(char *ciphertext) +{ + static char Salt[SALT_SIZE+1]; + memset(Salt, 0, SALT_SIZE+1); + strncpy(Salt, &ciphertext[md5_gen_SALT_OFFSET], SALT_SIZE); + Salt[SALT_SIZE] = 0; + if (md5_gen_salt_as_hex) + { + // Do not 'worry' about SSE/MMX, Only do 'generic' md5. This is ONLY done + // at the start of the run. We will NEVER see this run, once john starts. + MD5_CTX ctx; + unsigned char Buf[16]; + unsigned char *cpo, *cpi, i; + MD5_Init(&ctx); + MD5_Update(&ctx, Salt, strlen(Salt)); + MD5_Final(Buf, &ctx); + cpo = Salt; + memset(Salt, 0, SALT_SIZE+1); + cpi = Buf; + for (i = 0; i < 16; ++i) + { + *cpo++ = itoa16[(*cpi)>>4]; + *cpo++ = itoa16[(*cpi)&0xF]; + ++cpi; + } + *cpo = 0; + } + return Salt; +} +/********************************************************************************* + * 'special' get salt function for phpass. We return the 8 bytes salt, followed by + * the 1 byte loop count. 'normally' in phpass format, that order is reversed. + * we do it this way, since our 'primitive' functions would not know to treat the + * salt any differently for phpass. Thus the primitives are told about the first + * 8 bytes (and not the full 9). But the phpass crypt function uses that 9th byte. + *********************************************************************************/ +static void * phpassmd5_salt(char *ciphertext) +{ + static unsigned char salt[10]; + // store off the 'real' 8 bytes of salt + memcpy(salt, &ciphertext[34+1], 8); + // append the 1 byte of loop count information. + salt[8] = ciphertext[34]; + salt[9]=0; + return salt; +} + +/********************************************************************************* + * This returns a 'decent' hash for salted hashes (where they are unk arbritray + * text. Many of the salts are from ' ' to 0x7E. This function works well for + * them. NOTE we have to KNOW that a format is not salted, and ALWAYS return 0 + * for them. If not, even though they are listed as not salted, JOHN will have + * problems, and will treat them 'like' salted (i.e. slows john down A LOT). + *********************************************************************************/ +static int salt_hash(void *salt) +{ + int x,y; + if (!salt || *((char*)salt) == 0) + return 0; + x = ((ARCH_WORD_32)(ARCH_INDEX(((unsigned char *)salt)[0])-' ')); + y = (((ARCH_WORD_32)(ARCH_INDEX(((unsigned char *)salt)[1])-' ')<<4)); + return (x+y) & 0x3FF; +} + +/********************************************************************************* + * Salt for phpass. Note, the above would have probably also worked, but this was + * what was originally IN phpass. + *********************************************************************************/ +static int phpass_salt_hash(void *salt) +{ + return *((ARCH_WORD *)salt) & 0x3FF; +} + +/********************************************************************************* + * Gets the binary value from a base-16 hash. + *********************************************************************************/ +static void *md5_gen_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + for(i=0;i>= 2; + b[bidx] = sixbits; + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx++] |= (sixbits<<4); + sixbits >>= 4; + b[bidx] = sixbits; + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx++] |= (sixbits<<2); + } + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx] = sixbits; + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx] |= (sixbits<<6); + return b; +} + +/********************************************************************************* + * Here is the main mdg_generic fmt_main. NOTE in it's default settings, it is + * ready to handle base-16 hashes. The phpass stuff will be linked in later, IF + * needed. + *********************************************************************************/ +struct fmt_main fmt_MD5gen = +{ + { + 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, + md5_gen_tests + }, { + md5_gen_init, + valid, + fmt_default_split, + md5_gen_binary, + get_salt, + { + md5_gen_binary_hash_0, + md5_gen_binary_hash_1, + md5_gen_binary_hash_2, + md5_gen_binary_hash_3, + md5_gen_binary_hash_4 + }, + salt_hash, + md5_gen_set_salt, + md5_gen_set_key, + md5_gen_get_key, + fmt_default_clear_keys, + md5_gen_crypt_all, + { + md5_gen_get_hash_0, + md5_gen_get_hash_1, + md5_gen_get_hash_2, + md5_gen_get_hash_3, + md5_gen_get_hash_4 + }, + md5_gen_cmp_all, + md5_gen_cmp_one, + md5_gen_cmp_exact + } +}; + +/************************************************************** + ************************************************************** + ************************************************************** + ************************************************************** + * These are the md5 'primitive' functions that are used by + * the build-in expressions, and by the expression generator + * They load passwords, salts, user ids, do crypts, convert + * crypts into base-16, etc. They are pretty encompassing, + * and have been found to be able to do most anything with + * a standard 'base-16' md5 hash, salted or unsalted that + * fits a 'simple' php style expression. + ************************************************************** + ************************************************************** + ************************************************************** + *************************************************************/ + +//#include "md5_gen_fmt_dbd_stuff.hxx" + +/************************************************************** + * MD5_GEN primitive helper function + * This is a 'fake' function. It can ONLY be used as the 1st + * function, and only if the expression fits certain 'forms' + * and if certain other coding design is done. But IF it can + * be used, it replaces the intial clean_input() and load_keys() + * calls, and eliminates a lot of buffer copy overhead. + *************************************************************/ +void MD5GenBaseFunc__InitialLoadKeysToInput() +{ + // we only want a function pointer here. We NEVER call this + // function, just use it to 'signal' the code to load keys + // directly and to 'get' keys directly from input #1 so as + // to save buffer copies to and from 'saved_keys' +} +void MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2() +{ + // not a 'real' function. Used to 'preload' a md5 crypt + // for parms like md5(md5($p).%s) so that we load ALL of the + // inner md5($p) only once, then re-used them over and over again +} +void MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1() +{ +} +void MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1_offset32() +{ +} + +void MD5GenBaseFunc__PHPassSetup() +{ + // Not a real function, but tells us to use a different salt function +} + +/************************************************************** + * MD5_GEN primitive helper function + * Clears the input variable, and input 'lengths' + *************************************************************/ +void MD5GenBaseFunc__clean_input() +{ +#if defined (MMX_COEF) + memset(input_buf, 0, sizeof(input_buf)); + memset(total_len, 0, sizeof(total_len)); +#else + unsigned i; + for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) + { + //input_buf[i][0] = 0; + total_len[i] = 0; + } +#endif +} + +void MD5GenBaseFunc__clean_input_kwik() +{ +#if defined (MMX_COEF) +// memset(input_buf, 0, sizeof(input_buf)); + memset(total_len, 0, sizeof(total_len)); +#else + unsigned i; + for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) + { + //input_buf[i][0] = 0; + total_len[i] = 0; + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * Clears the 2nd input variable, and 2nd input 'lengths' + *************************************************************/ +void MD5GenBaseFunc__clean_input2() +{ +#if defined (MMX_COEF) + memset(input_buf2, 0, sizeof(input_buf2)); + memset(total_len2, 0, sizeof(total_len2)); +#else + unsigned i; + for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) + { + //input_buf2[i][0] = 0; + total_len2[i] = 0; + } +#endif +} +void MD5GenBaseFunc__clean_input2_kwik() +{ +#if defined (MMX_COEF) + //memset(input_buf2, 0, sizeof(input_buf2)); + memset(total_len2, 0, sizeof(total_len2)); +#else + unsigned i; + for (i = 0; i < MAX_KEYS_PER_CRYPT; ++i) + { + //input_buf2[i][0] = 0; + total_len2[i] = 0; + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * Appends all keys to the end of the input variables, and + * updates lengths + *************************************************************/ +void MD5GenBaseFunc__append_keys() +{ +#if defined (MMX_COEF) + unsigned i, j, index, kp; + ARCH_WORD_32 *po, *pi; + for (index = 0; index < m_count; ++index) + { + unsigned idx, stop, len = saved_key_len[index]; + idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + j = (total_len[idx] >> ((32/MMX_COEF)*(index&(MMX_COEF-1)))) & 0xFF; + stop = len+j; + kp = 0; + if (!j) + { + unsigned cnt = len>>2; + pi = (ARCH_WORD_32 *)&(saved_key[index]); + po = &((ARCH_WORD_32 *)(&(input_buf[idx])))[index&(MMX_COEF-1)]; + for (i = 0; i < cnt; ++i) + { + *po = *pi++; + po += MMX_COEF; + j += 4; + kp += 4; + } + } + for(;j>(MMX_COEF>>1)); + j = (total_len2[idx] >> ((32/MMX_COEF)*(index&(MMX_COEF-1)))) & 0xFF; + stop = len+j; + kp = 0; + if (!j) + { + unsigned cnt = len>>2; + pi = (ARCH_WORD_32 *)&(saved_key[index]); + po = &((ARCH_WORD_32 *)(&(input_buf2[idx])))[index&(MMX_COEF-1)]; + for (i = 0; i < cnt; ++i) + { + *po = *pi++; + po += MMX_COEF; + j += 4; + kp += 4; + } + } + for(;j>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + for (j = 0; j < MMX_COEF; ++j) + { + unsigned start_len = (total_len[i] >> ((32/MMX_COEF)*j)) & 0xFF; + for (k = 0; k < saltlen; ++k) + input_buf[i][GETPOS((k+start_len), j)] = cursalt[k]; + input_buf[i][GETPOS((saltlen+start_len), j)] = 0x80; + total_len[i] += ( saltlen << ( ( (32/MMX_COEF) * j ) )); + } + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + memcpy(&input_buf[j][total_len[j]], cursalt, saltlen); + total_len[j] += saltlen; + } +#endif +} + +extern void MD5GenBaseFunc__set_input_len_32() +{ +#if defined (MMX_COEF) + unsigned i, j, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + total_len[i] = 0; + for (j = 0; j < MMX_COEF; ++j) + total_len[i] += ( 32 << ( ( (32/MMX_COEF) * j ) )); + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + total_len[j] = 32; + } +#endif +} + +extern void MD5GenBaseFunc__set_input2_len_32() +{ +#if defined (MMX_COEF) + unsigned i, j, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + total_len2[i] = 0; + for (j = 0; j < MMX_COEF; ++j) + total_len2[i] += ( 32 << ( ( (32/MMX_COEF) * j ) )); + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + total_len2[j] = 32; + } +#endif +} + +void MD5GenBaseFunc__set_input_len_64() +{ +#if defined (MMX_COEF) + unsigned i, j, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + total_len[i] = 0; + for (j = 0; j < MMX_COEF; ++j) + total_len[i] += ( 64 << ( ( (32/MMX_COEF) * j ) )); + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + total_len[j] = 64; + } +#endif +} +void MD5GenBaseFunc__set_input2_len_64() +{ +#if defined (MMX_COEF) + unsigned i, j, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + total_len2[i] = 0; + for (j = 0; j < MMX_COEF; ++j) + total_len2[i] += ( 64 << ( ( (32/MMX_COEF) * j ) )); + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + total_len2[j] = 64; + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * Appends the salt to the end of the 2nd input variables, and + * updates lengths + *************************************************************/ +void MD5GenBaseFunc__append_salt2() +{ +#if defined (MMX_COEF) + unsigned i, j, k, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + for (j = 0; j < MMX_COEF; ++j) + { + unsigned start_len = (total_len2[i] >> ((32/MMX_COEF)*j)) & 0xFF; + for (k = 0; k < saltlen; ++k) + input_buf2[i][GETPOS((k+start_len), j)] = cursalt[k]; + input_buf2[i][GETPOS((saltlen+start_len), j)] = 0x80; + total_len2[i] += ( saltlen << ( ( (32/MMX_COEF) * j ) )); + } + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + memcpy(&input_buf2[j][total_len2[j]], cursalt, saltlen); + total_len2[j] += saltlen; + } +#endif +} + +void MD5GenBaseFunc__append_input_from_input2() +{ +#if defined (MMX_COEF) + unsigned i, j, k, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + for (j = 0; j < MMX_COEF; ++j) + { + unsigned start_len = (total_len[i] >> ((32/MMX_COEF)*j)) & 0xFF; + unsigned len1 = (total_len2[i] >> ((32/MMX_COEF)*j)) & 0xFF; + for (k = 0; k < len1; ++k) + input_buf[i][GETPOS((k+start_len), j)] = input_buf2[i][GETPOS(k,j)]; + input_buf[i][GETPOS((len1+start_len), j)] = 0x80; + total_len[i] += ( len1 << ( ( (32/MMX_COEF) * j ) )); + } + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + memcpy(&input_buf[j][total_len[j]], input_buf2[j], total_len2[j]); + total_len[j] += total_len2[j]; + } +#endif +} + +void MD5GenBaseFunc__append_input2_from_input() +{ +#if defined (MMX_COEF) + unsigned i, j, k, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + for (j = 0; j < MMX_COEF; ++j) + { + unsigned start_len = (total_len2[i] >> ((32/MMX_COEF)*j)) & 0xFF; + unsigned len1 = (total_len[i] >> ((32/MMX_COEF)*j)) & 0xFF; + for (k = 0; k < len1; ++k) + input_buf2[i][GETPOS((k+start_len), j)] = input_buf[i][GETPOS(k,j)]; + input_buf2[i][GETPOS((len1+start_len), j)] = 0x80; + total_len2[i] += ( len1 << ( ( (32/MMX_COEF) * j ) )); + } + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + memcpy(&input_buf2[j][total_len2[j]], input_buf[j], total_len[j]); + total_len2[j] += total_len[j]; + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * Encrypts the data in the first input field. The data is + * still in the binary encrypted format, in the crypt_key. + * we do not yet convert to base-16. This is so we can output + * as base-16, or later, if we add base-64, we can output to + * that format instead. Some functions do NOT change from + * the binary format (such as phpass). Thus if we are doing + * something like phpass, we would NOT want the conversion + * to happen at all + *************************************************************/ +void MD5GenBaseFunc__crypt() +{ +#if defined (MMX_COEF) + unsigned i, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + mdfivemmx((unsigned char*)&(crypt_key[i]), (unsigned char*)&(input_buf[i]), total_len[i]); +#else + unsigned i; + for (i = 0; i < m_count; ++i) + { + MD5_Init( &ctx ); + MD5_Update( &ctx, input_buf[i], total_len[i] ); + MD5_Final( (unsigned char*)&(crypt_key[i]), &ctx); + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * Special crypt to handle the 'looping' needed for phpass + *************************************************************/ +void MD5GenBaseFunc__PHPassCrypt() +{ + unsigned Lcount; + Lcount = atoi64[ARCH_INDEX(cursalt[8])]; + if (Lcount < 7 || Lcount > 31) + exit(fprintf(stderr, "Error, invalid loop byte in a php salt\n")); + Lcount = (1<>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + mdfivemmx((unsigned char*)&(crypt_key2[i]), (unsigned char*)&(input_buf2[i]), total_len2[i]); +#else + unsigned i; + for (i = 0; i < m_count; ++i) + { + MD5_Init( &ctx ); + MD5_Update( &ctx, input_buf2[i], total_len2[i] ); + MD5_Final( (unsigned char*)&(crypt_key2[i]), &ctx); + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * Encrypts the data in the 1st input field into crypt_keys2. + *************************************************************/ +void MD5GenBaseFunc__crypt_in1_to_out2() +{ +#if defined (MMX_COEF) + unsigned i, cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + mdfivemmx((unsigned char*)&(crypt_key2[i]), (unsigned char*)&(input_buf[i]), total_len[i]); +#else + unsigned i; + for (i = 0; i < m_count; ++i) + { + MD5_Init( &ctx ); + MD5_Update( &ctx, input_buf[i], total_len[i] ); + MD5_Final( (unsigned char*)&(crypt_key2[i]), &ctx); + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * Encrypts the data in the 2nd input field into crypt_keys. + *************************************************************/ +void MD5GenBaseFunc__crypt_in2_to_out1() +{ +#if defined (MMX_COEF) + unsigned i, cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + mdfivemmx((unsigned char*)&(crypt_key[i]), (unsigned char*)&(input_buf2[i]), total_len2[i]); +#else + unsigned i; + for (i = 0; i < m_count; ++i) + { + MD5_Init( &ctx ); + MD5_Update( &ctx, input_buf2[i], total_len2[i] ); + MD5_Final( (unsigned char*)&(crypt_key[i]), &ctx); + } +#endif +} + +void MD5GenBaseFunc__crypt_to_input_raw() +{ +#if defined (MMX_COEF) + unsigned i, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + unsigned char *cpib = input_buf[i]; + unsigned char *cpck = crypt_key[i]; + mdfivemmx(cpck, cpib, total_len[i]); + memset(cpib+sizeof(crypt_key[0]), 0, sizeof(input_buf[0])-sizeof(crypt_key[0])); + memcpy(cpib, cpck, sizeof(crypt_key[0])); + cpib[GETPOS(0x10, 0)] = 0x80; + cpib[GETPOS(0x10, 1)] = 0x80; + cpib[GETPOS(0x10, 2)] = 0x80; + cpib[GETPOS(0x10, 3)] = 0x80; +#if (MMX_COEF==4) + total_len[i] = 0x10101010; +#else + total_len[i] = 0x100010; +#endif + } +#else + unsigned i; + for (i = 0; i < m_count; ++i) + { + MD5_Init( &ctx ); + MD5_Update( &ctx, input_buf[i], total_len[i] ); + // NOTE we do NOT have null terminated string here. THUS + // we need to change all of the strcat(buf) to do strcpy(&buf[len]) + MD5_Final( (unsigned char*)&(input_buf[i]), &ctx); + total_len[i] = 0x10; + } +#endif +} +void MD5GenBaseFunc__crypt_to_input_raw_Overwrite_NoLen() +{ +#if defined (MMX_COEF) + unsigned i, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + mdfivemmx((unsigned char*)&(input_buf[i]), (unsigned char*)&(input_buf[i]), total_len[i]); +#else + unsigned i; + for (i = 0; i < m_count; ++i) + { + MD5_Init( &ctx ); + MD5_Update( &ctx, input_buf[i], total_len[i] ); + // NOTE we do NOT have null terminated string here. THUS + // we need to change all of the strcat(buf) to do strcpy(&buf[len]) + MD5_Final( (unsigned char*)&(input_buf[i]), &ctx); + } +#endif +} + +void MD5GenBaseFunc__overwrite_salt_to_input1_no_size_fix() +{ +#if defined (MMX_COEF) + unsigned i, j, k, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + for (j = 0; j < MMX_COEF; ++j) + { + for (k = 0; k < saltlen; ++k) + input_buf[i][GETPOS(k, j)] = cursalt[k]; + } + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + memcpy(input_buf[j], cursalt, saltlen); + } +#endif +} +void MD5GenBaseFunc__overwrite_salt_to_input2_no_size_fix() +{ +#if defined (MMX_COEF) + unsigned i, j, k, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (i = 0; i < cnt; ++i) + { + for (j = 0; j < MMX_COEF; ++j) + { + for (k = 0; k < saltlen; ++k) + input_buf2[i][GETPOS(k, j)] = cursalt[k]; + } + } +#else + unsigned j; + for (j = 0; j < m_count; ++j) + { + memcpy(input_buf2[j], cursalt, saltlen); + } +#endif +} + + +/************************************************************** + * MD5_GEN primitive helper function + * This will take the data stored in the crypt_keys (the encrypted + * 'first' key variable), and use a base-16 text formatting, and + * append this to the first input buffer (adjusting the lengths) + *************************************************************/ +void MD5GenBaseFunc__append_from_last_output_as_base16() +{ +#if defined (MMX_COEF) + unsigned index, idx, k, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (index = 0; index < m_count; ++index) + { + idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + // This is the 'actual' work. + unsigned ip = (total_len[idx] >> ((32/MMX_COEF)*(index&(MMX_COEF-1)))) & 0xFF; + for (k = 0; k < 16; ++k) + { + unsigned char v = crypt_key[idx][GETPOS(k, index&(MMX_COEF-1))]; + input_buf[idx][GETPOS(ip+(k<<1), index&(MMX_COEF-1))] = itoa16[v>>4]; + input_buf[idx][GETPOS(ip+(k<<1)+1, index&(MMX_COEF-1))] = itoa16[v&0xF]; + } + input_buf[idx][GETPOS(ip+32, index&(MMX_COEF-1))] = 0x80; + total_len[idx] += ( 32 << ( ( (32/MMX_COEF) * (index&(MMX_COEF-1)) ) )); + } +#else + unsigned i, j; + + for (i = 0; i < m_count; ++i) + { + unsigned char *cp = &input_buf[i][total_len[i]]; + for (j = 0; j < 16; ++j) + { + *cp++ = itoa16[crypt_key[i][j]>>4]; + *cp++ = itoa16[crypt_key[i][j]&0xF]; + } + *cp = 0; + total_len[i] += 32; + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * This will take the data stored in the crypt_keys2 (the encrypted + * 'second' key variable), and base-16 appends to the 2nd input + *************************************************************/ +void MD5GenBaseFunc__append_from_last_output2_as_base16() +{ +#if defined (MMX_COEF) + unsigned index, idx, k, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (index = 0; index < m_count; ++index) + { + idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + // This is the 'actual' work. + unsigned ip = (total_len2[idx] >> ((32/MMX_COEF)*(index&(MMX_COEF-1)))) & 0xFF; + for (k = 0; k < 16; ++k) + { + unsigned char v = crypt_key2[idx][GETPOS(k, index&(MMX_COEF-1))]; + input_buf2[idx][GETPOS(ip+(k<<1), index&(MMX_COEF-1))] = itoa16[v>>4]; + input_buf2[idx][GETPOS(ip+(k<<1)+1, index&(MMX_COEF-1))] = itoa16[v&0xF]; + } + input_buf2[idx][GETPOS(ip+32, index&(MMX_COEF-1))] = 0x80; + total_len2[idx] += ( 32 << ( ( (32/MMX_COEF) * (index&(MMX_COEF-1)) ) )); + } +#else + unsigned i, j; + + for (i = 0; i < m_count; ++i) + { + unsigned char *cp = &input_buf2[i][total_len2[i]]; + for (j = 0; j < 16; ++j) + { + *cp++ = itoa16[crypt_key2[i][j]>>4]; + *cp++ = itoa16[crypt_key2[i][j]&0xF]; + } + *cp = 0; + total_len2[i] += 32; + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * This will take the data stored in the crypt_keys1 (the encrypted + * 'first' key variable), and base-16 appends to the 2nd input + *************************************************************/ +void MD5GenBaseFunc__append_from_last_output_to_input2_as_base16() +{ +#if defined (MMX_COEF) +/* + unsigned index, idx, k, cnt, ip, til, idxmod=0; + unsigned char *CK, *IB2; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (index = 0; index < m_count; ++index) + { + idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + CK = crypt_key[idx]; + IB2 = input_buf2[idx]; + // This is the 'actual' work. + ip = (total_len2[idx] >> ((32/MMX_COEF)*idxmod)) & 0xFF; + til=ip+32; + for (k = ip; k < til; k+=2) + { + unsigned char v = CK[GETPOS(k, idxmod)]; + IB2[GETPOS(k, idxmod)] = itoa16_shr_04[ARCH_INDEX(v)]; + IB2[GETPOS(k+1, idxmod)] = itoa16_and_0f[ARCH_INDEX(v)]; + } + IB2[GETPOS(k, idxmod)] = 0x80; + total_len2[idx] += ( 32 << ( ( (32/MMX_COEF) * idxmod ) )); + ++idxmod; + idxmod &= (MMX_COEF-1); + } +*/ + unsigned index, idx, k, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (index = 0; index < m_count; ++index) + { + idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + // This is the 'actual' work. + unsigned ip = (total_len2[idx] >> ((32/MMX_COEF)*(index&(MMX_COEF-1)))) & 0xFF; + for (k = 0; k < 16; ++k) + { + unsigned char v = crypt_key[idx][GETPOS(k, index&(MMX_COEF-1))]; + input_buf2[idx][GETPOS(ip+(k<<1), index&(MMX_COEF-1))] = itoa16[v>>4]; + input_buf2[idx][GETPOS(ip+(k<<1)+1, index&(MMX_COEF-1))] = itoa16[v&0xF]; + } + input_buf2[idx][GETPOS(ip+32, index&(MMX_COEF-1))] = 0x80; + total_len2[idx] += ( 32 << ( ( (32/MMX_COEF) * (index&(MMX_COEF-1)) ) )); + } +#else + unsigned i, j; + + for (i = 0; i < m_count; ++i) + { + unsigned char *cp = &input_buf2[i][total_len2[i]]; + for (j = 0; j < 16; ++j) + { + *cp++ = itoa16[crypt_key[i][j]>>4]; + *cp++ = itoa16[crypt_key[i][j]&0xF]; + } + *cp = 0; + total_len2[i] += 32; + } +#endif +} + +/************************************************************** + * MD5_GEN primitive helper function + * This will take the data stored in the crypt_keys2 (the encrypted + * 'second' key variable), and base-16 appends to the 1st input + *************************************************************/ +void MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16() +{ +#if defined (MMX_COEF) + unsigned index, idx, k, cnt; + cnt = ( ((unsigned)m_count+MMX_COEF-1)>>(MMX_COEF>>1)); + for (index = 0; index < m_count; ++index) + { + idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + // This is the 'actual' work. + unsigned ip = (total_len[idx] >> ((32/MMX_COEF)*(index&(MMX_COEF-1)))) & 0xFF; + for (k = 0; k < 16; ++k) + { + unsigned char v = crypt_key2[idx][GETPOS(k, index&(MMX_COEF-1))]; + input_buf[idx][GETPOS(ip+(k<<1), index&(MMX_COEF-1))] = itoa16[v>>4]; + input_buf[idx][GETPOS(ip+(k<<1)+1, index&(MMX_COEF-1))] = itoa16[v&0xF]; + } + input_buf[idx][GETPOS(ip+32, index&(MMX_COEF-1))] = 0x80; + total_len[idx] += ( 32 << ( ( (32/MMX_COEF) * (index&(MMX_COEF-1)) ) )); + } +#else + unsigned i, j; + + for (i = 0; i < m_count; ++i) + { + unsigned char *cp = &input_buf[i][total_len[i]]; + for (j = 0; j < 16; ++j) + { + *cp++ = itoa16[crypt_key2[i][j]>>4]; + *cp++ = itoa16[crypt_key2[i][j]&0xF]; + } + *cp = 0; + total_len[i] += 32; + } +#endif +} + + +/************************************************************** + ************************************************************** + * MD5_GEN primitive helper function + * These are not done yet. Usage of them will exit john with + * an error message. Some of these are for optimzations (like + * speeding up phpass, some use 2nd salt and user id, which we + * have not yet implemented + ************************************************************** + *************************************************************/ + +/************************************************************** + * MD5_GEN primitive helper function + * overwrites start of input2 from the output1 data using base-16 + * an optimization, if the same thing is done over and over + * again, such as md5(md5(md5(md5($p)))) There, we would only + * call the copy and set length once, then simply call copy. + *************************************************************/ +void MD5GenBaseFunc__overwrite_from_last_output_to_input2_as_base16_no_size_fix() +{ + exit(fprintf(stderr, "Error, MD5GenBaseFunc__overwrite_from_last_output_to_input2_as_base16_no_size_fix() primitive has not been implemented\n")); +} +/************************************************************** + * MD5_GEN primitive helper function + * overwrites start of input2 from the output2 data using base-16 + *************************************************************/ +void MD5GenBaseFunc__overwrite_from_last_output2_as_base16_no_size_fix() +{ + exit(fprintf(stderr, "Error, MD5GenBaseFunc__overwrite_from_last_output2_as_base16_no_size_fix() primitive has not been implemented\n")); +} +/************************************************************** + * MD5_GEN primitive helper function + * overwrites start of input1 from the output1 data using base-16 + *************************************************************/ +void MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix() +{ + exit(fprintf(stderr, "Error, MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix() primitive has not been implemented\n")); +} +/************************************************************** + * MD5_GEN primitive helper function + * overwrites start of input1 from the output2 data using base-16 + *************************************************************/ +void MD5GenBaseFunc__overwrite_from_last_output2_to_input1_as_base16_no_size_fix() +{ + exit(fprintf(stderr, "Error, MD5GenBaseFunc__overwrite_from_last_output2_to_input1_as_base16_no_size_fix() primitive has not been implemented\n")); +} +/************************************************************** + * MD5_GEN primitive helper function + * Append salt #2 into input 1 + *************************************************************/ +void MD5GenBaseFunc__append_2nd_salt() +{ + exit(fprintf(stderr, "Error, MD5GenBaseFunc__append_2nd_salt() primitive has not been implemented\n")); +} +/************************************************************** + * MD5_GEN primitive helper function + * Append salt #2 into input 2 + *************************************************************/ +void MD5GenBaseFunc__append_2nd_salt2() +{ + exit(fprintf(stderr, "Error, MD5GenBaseFunc__append_2nd_salt2() primitive has not been implemented\n")); +} +/************************************************************** + * MD5_GEN primitive helper function + * Append UserID into input 1 + *************************************************************/ +void MD5GenBaseFunc__append_userid() +{ + exit(fprintf(stderr, "Error, MD5GenBaseFunc__append_userid() primitive has not been implemented\n")); +} +/************************************************************** + * MD5_GEN primitive helper function + * Append UserID into input 2 + *************************************************************/ +void MD5GenBaseFunc__append_userid2() +{ + exit(fprintf(stderr, "Error, MD5GenBaseFunc__append_userid2() primitive has not been implemented\n")); +} + +/************************************************************** + ************************************************************** + ************************************************************** + ************************************************************** + * MD5_GEN primitive helper function + * This is the END of the primitives. + ************************************************************** + ************************************************************** + ************************************************************** + *************************************************************/ + + +void md5_gen_SETUP(MD5_GEN_Setup *Setup) +{ + int i, cnt; + // Handle These Flags types. + //#define MGF_NOTSSE2Safe 0x01 (handled) + //#define MGF_ColonNOTValid 0x02 (handled) + //#define MGF_SALTED 0x04 (handled) + //#define MGF_SALTED2 0x08 + //#define MGF_USERID 0x10 + //#define MGF_INPBASE64 0x20 (handled, like for phpbb) + +#if defined (MMX_COEF) + if (Setup->flags & MGF_NOTSSE2Safe) + exit(fprintf(stderr, "This format %s does NOT work an SSE/MMX build of John\n", Setup->szFORMAT_NAME)); +#endif + + if (Setup->flags & MGF_ColonNOTValid) + { + extern struct options_main options; + if (options.field_sep_char == ':') + { + exit(fprintf(stderr, "This format does NOT work using ':' as separator, since it is in a salt value, or the hash itself. Use --field-separator-char=c and set c to a 'valid' unused character that 'matches' the input file")); + } + } + + md5_gen_base64_inout = 0; + fmt_MD5gen.methods.binary = md5_gen_binary; + if (Setup->flags & MGF_INPBASE64) + { + md5_gen_base64_inout = 1; + fmt_MD5gen.methods.binary = md5_gen_binary_b64; + } + + md5_gen_salt_as_hex = 0; + if (Setup->flags & MFG_SALT_AS_HEX) + md5_gen_salt_as_hex = 1; + + fmt_MD5gen.params.format_name = Setup->szFORMAT_NAME; + if ( (Setup->flags & MGF_SALTED) == 0) + { + fmt_MD5gen.params.salt_size = 0; + md5_gen_FIXED_SALT_SIZE = 0; + fmt_MD5gen.params.benchmark_length = -1; + } + else + { + fmt_MD5gen.params.benchmark_length = 0; + if (Setup->SaltLen > 0) + { + fmt_MD5gen.params.salt_size = Setup->SaltLen; + md5_gen_FIXED_SALT_SIZE = Setup->SaltLen; + } + else + { + fmt_MD5gen.params.salt_size = SALT_SIZE; + md5_gen_FIXED_SALT_SIZE = -1; // says we have a salt, but NOT a fixed sized one that we 'know' about. + } + } + + store_keys_in_input = 0; + if (Setup->pFuncs && Setup->pFuncs[0]) + { + int j = 0; + if (Setup->pFuncs[0] == MD5GenBaseFunc__InitialLoadKeysToInput) + { + store_keys_in_input = 1; + // we do 'not' load this function into our array. It is used + // as an 'indicator' to store/fetch keys direct to/from input, + // but is not a real function. So we start from array[1] to + // store into our function pointer table. + ++j; + } + if (Setup->pFuncs[0] == MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2) + { + store_keys_normal_but_precompute_md5_to_output2 = 1; + ++j; + } + if (Setup->pFuncs[0] == MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1) + { + store_keys_normal_but_precompute_md5_to_output2 = 1; + store_keys_normal_but_precompute_md5_to_output2_base16_to_input1 = 1; + ++j; + } + if (Setup->pFuncs[0] == MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1_offset32) + { + store_keys_normal_but_precompute_md5_to_output2 = 1; + store_keys_normal_but_precompute_md5_to_output2_base16_to_input1_offset32 = 1; + ++j; + } + if (Setup->pFuncs[0] == MD5GenBaseFunc__PHPassSetup) + { + fmt_MD5gen.methods.salt = phpassmd5_salt; + fmt_MD5gen.methods.set_salt = phpass_gen_set_salt; + fmt_MD5gen.methods.salt_hash = phpass_salt_hash; + saltlen = 8; + ++j; + } + else + { + fmt_MD5gen.methods.salt = get_salt; + fmt_MD5gen.methods.set_salt = md5_gen_set_salt; + fmt_MD5gen.methods.salt_hash = salt_hash; + + } + for (i=0; i < ARRAY_COUNT(md5_gen_FUNCTIONS) -1 && Setup->pFuncs[i]; ++i) + { + if (MD5GenBaseFunc__InitialLoadKeysToInput == Setup->pFuncs[j]) + exit(fprintf(stderr, "Pseudo fuction InitialLoadKeysToInput can NOT be called, other than as the very first function in generic MD5 scripts\n")); + if (MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2 == Setup->pFuncs[j]) + exit(fprintf(stderr, "Pseudo fuction MD5GenBaseFunc__InitialLoadKeysAs_md5base16_ToInput can NOT be called, other than as the very first function in generic MD5 scripts\n")); + + // Ok, if we ARE using store keys, these things will cause it to NOT work + if (store_keys_in_input) + { + if (Setup->pFuncs[j] == MD5GenBaseFunc__append_keys) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but append_keys called and that is invalid\n")); + if (Setup->pFuncs[j] == MD5GenBaseFunc__append_keys2) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but append_keys2 called and that is invalid\n")); + if (Setup->pFuncs[j] == MD5GenBaseFunc__clean_input) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but clean_input called and that is invalid\n")); + if (Setup->pFuncs[j] == MD5GenBaseFunc__append_salt) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but append_salt called and that is invalid\n")); + if (Setup->pFuncs[j] == MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but append_from_last_output2_to_input1_as_base16 called and that is invalid\n")); + if (Setup->pFuncs[j] == MD5GenBaseFunc__overwrite_from_last_output2_to_input1_as_base16_no_size_fix) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but overwrite_from_last_output2_to_input1_as_base16_no_size_fix called and that is invalid\n")); + if (Setup->pFuncs[j] == MD5GenBaseFunc__append_from_last_output_as_base16) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but append_from_last_output_as_base16s called and that is invalid\n")); + if (Setup->pFuncs[j] == MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but overwrite_from_last_output_as_base16_no_size_fix called and that is invalid\n")); + if (Setup->pFuncs[j] == MD5GenBaseFunc__append_2nd_salt) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but append_2nd_salt called and that is invalid\n")); + if (Setup->pFuncs[j] == MD5GenBaseFunc__append_userid) + exit(fprintf(stderr, "InitialLoadKeysToInput used, but append_userid called and that is invalid\n")); + } + md5_gen_FUNCTIONS[i] = Setup->pFuncs[j++]; + } + md5_gen_FUNCTIONS[j] = NULL; + } + if (!Setup->pPreloads || Setup->pPreloads[0].Hash == NULL) + { + exit(fprintf(stderr, "Error, no validation hash(s) for this format\n")); + } + cnt = 0; + + while (cnt < ARRAY_COUNT(md5_gen_tests)-1) + { + for (i = 0; cnt < ARRAY_COUNT(md5_gen_tests) -1 && Setup->pFuncs[i]; ++i, ++cnt) + { + md5_gen_tests[cnt].ciphertext = Setup->pPreloads[i].Hash; + md5_gen_tests[cnt].plaintext = Setup->pPreloads[i].Passwd; + } + } + md5_gen_tests[cnt].ciphertext = NULL; + md5_gen_tests[cnt].plaintext = NULL; +} diff -urpN john-1.7.5.orig/src/md5_gen_parser.c john-1.7.5/src/md5_gen_parser.c --- john-1.7.5.orig/src/md5_gen_parser.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/md5_gen_parser.c 2009-10-28 21:13:26 +0000 @@ -0,0 +1,311 @@ +/* + * This software was written by Jim Fougeron jfoug AT cox dot net + * in 2009. No copyright is claimed, and the software is hereby + * placed in the public domain. In case this attempt to disclaim + * copyright and place the software in the public domain is deemed + * null and void, then the software is Copyright © 2009 Jim Fougeron + * and it is hereby released to the general public under the following + * terms: + * + * This software may be modified, redistributed, and used for any + * purpose, in source and binary forms, with or without modification. + * + * Generic MD5 hashes cracker + * + * This file implements code that allows 'dynamic' building of + * generic MD5 functions. john.conf is used to store the 'script' + * and supporting data (like the expression, or 'flags' needed to + * make the format work). + * + * To make this work, you simply add a "section" to the john.conf + * file of this format: + * + * [List.Generic:md5_gen(NUM)] + * + * Num has to be replaced with a number, greater than 1000, since + * md5_gen(0) to md5_gen(1000) are reserved for 'built-in' and any + * user defined md5_gen(#) functions need to start at 1001 or more. + * + * Then under the new section, add the script. There are 2 required + * data types, and 2 optional. The required are a list of Func= + * and a list of Test= Then there is an optional Expression= + * and an optional list of Flag= items. + * + * Here is an example, showing processing for md5(md5(md5(md5($p)))) + * + * [List.Generic:md5_gen(1001)] + * Expression=md5(md5(md5(md5($p)))) + * Func=MD5GenBaseFunc__InitialLoadKeysToInput + * Func=MD5GenBaseFunc__crypt + * Func=MD5GenBaseFunc__clean_input2 + * Func=MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 + * Func=MD5GenBaseFunc__crypt2 + * Func=MD5GenBaseFunc__clean_input2_kwik + * Func=MD5GenBaseFunc__append_from_last_output2_as_base16 + * Func=MD5GenBaseFunc__crypt2 + * Func=MD5GenBaseFunc__clean_input2_kwik + * Func=MD5GenBaseFunc__append_from_last_output2_as_base16 + * Func=MD5GenBaseFunc__crypt_in2_to_out1 + * Test=md5_gen(1001)57200e13b490d4ae47d5e19be026b057:test1 + * Test=md5_gen(1001)c6cc44f9e7fb7efcde62ba2e627a49c6:thatsworking + * Test=md5_gen(1001)0ae9549604e539a249c1fa9f5e5fb73b:test3 + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "config.h" +#include "md5.h" +#include "loader.h" +#include "options.h" + +#define DEFINE_MD5_PREDICATE_POINTERS +#include "md5_gen.h" + +typedef struct MD5Gen_Predicate_t +{ + char *name; + void(*func)(); +} MD5Gen_Predicate_t; + +MD5Gen_Predicate_t MD5Gen_Predicate[] = { + { "MD5GenBaseFunc__clean_input", MD5GenBaseFunc__clean_input }, + { "MD5GenBaseFunc__clean_input_kwik", MD5GenBaseFunc__clean_input_kwik }, + { "MD5GenBaseFunc__append_keys", MD5GenBaseFunc__append_keys }, + { "MD5GenBaseFunc__crypt", MD5GenBaseFunc__crypt }, + { "MD5GenBaseFunc__append_from_last_output_as_base16", MD5GenBaseFunc__append_from_last_output_as_base16 }, + { "MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix", MD5GenBaseFunc__overwrite_from_last_output_as_base16_no_size_fix }, + { "MD5GenBaseFunc__append_salt", MD5GenBaseFunc__append_salt }, + { "MD5GenBaseFunc__set_input_len_32", MD5GenBaseFunc__set_input_len_32 }, + { "MD5GenBaseFunc__clean_input2", MD5GenBaseFunc__clean_input2 }, + { "MD5GenBaseFunc__clean_input2_kwik", MD5GenBaseFunc__clean_input2_kwik }, + { "MD5GenBaseFunc__append_keys2", MD5GenBaseFunc__append_keys2 }, + { "MD5GenBaseFunc__crypt2", MD5GenBaseFunc__crypt2 }, + { "MD5GenBaseFunc__append_from_last_output2_as_base16", MD5GenBaseFunc__append_from_last_output2_as_base16 }, + { "MD5GenBaseFunc__overwrite_from_last_output2_as_base16_no_size_fix", MD5GenBaseFunc__overwrite_from_last_output2_as_base16_no_size_fix }, + { "MD5GenBaseFunc__append_from_last_output_to_input2_as_base16", MD5GenBaseFunc__append_from_last_output_to_input2_as_base16 }, + { "MD5GenBaseFunc__overwrite_from_last_output_to_input2_as_base16_no_size_fix", MD5GenBaseFunc__overwrite_from_last_output_to_input2_as_base16_no_size_fix }, + { "MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16", MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16 }, + { "MD5GenBaseFunc__overwrite_from_last_output2_to_input1_as_base16_no_size_fix", MD5GenBaseFunc__overwrite_from_last_output2_to_input1_as_base16_no_size_fix }, + { "MD5GenBaseFunc__append_salt2", MD5GenBaseFunc__append_salt2 }, + { "MD5GenBaseFunc__set_input2_len_32", MD5GenBaseFunc__set_input2_len_32 }, + { "MD5GenBaseFunc__append_input_from_input2", MD5GenBaseFunc__append_input_from_input2 }, + { "MD5GenBaseFunc__append_input2_from_input", MD5GenBaseFunc__append_input2_from_input }, + { "MD5GenBaseFunc__append_2nd_salt", MD5GenBaseFunc__append_2nd_salt }, + { "MD5GenBaseFunc__append_2nd_salt2", MD5GenBaseFunc__append_2nd_salt2 }, + { "MD5GenBaseFunc__append_userid", MD5GenBaseFunc__append_userid }, + { "MD5GenBaseFunc__append_userid2", MD5GenBaseFunc__append_userid2 }, + { "MD5GenBaseFunc__crypt_in1_to_out2", MD5GenBaseFunc__crypt_in1_to_out2 }, + { "MD5GenBaseFunc__crypt_in2_to_out1", MD5GenBaseFunc__crypt_in2_to_out1 }, + { "MD5GenBaseFunc__crypt_to_input_raw_Overwrite_NoLen", MD5GenBaseFunc__crypt_to_input_raw_Overwrite_NoLen }, + { "MD5GenBaseFunc__crypt_to_input_raw", MD5GenBaseFunc__crypt_to_input_raw }, + { "MD5GenBaseFunc__PHPassSetup", MD5GenBaseFunc__PHPassSetup }, + { "MD5GenBaseFunc__PHPassCrypt", MD5GenBaseFunc__PHPassCrypt }, + { "MD5GenBaseFunc__InitialLoadKeysToInput", MD5GenBaseFunc__InitialLoadKeysToInput }, + { "MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2", MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2 }, + { "MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1", MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1 }, + { "MD5GenBaseFunc__set_input_len_64", MD5GenBaseFunc__set_input_len_64 }, + { "MD5GenBaseFunc__set_input2_len_64", MD5GenBaseFunc__set_input2_len_64 }, + { "MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1_offset32", MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1_offset32 }, + { "MD5GenBaseFunc__overwrite_salt_to_input1_no_size_fix", MD5GenBaseFunc__overwrite_salt_to_input1_no_size_fix }, + { "MD5GenBaseFunc__overwrite_salt_to_input2_no_size_fix", MD5GenBaseFunc__overwrite_salt_to_input2_no_size_fix }, + { NULL, NULL }}; + +typedef struct MD5Gen_Str_Flag_t +{ + char *name; + unsigned flag_bit; +} MD5Gen_Str_Flag_t; + +MD5Gen_Str_Flag_t MD5Gen_Str_Flag[] = { + { "MGF_NOTSSE2Safe", MGF_NOTSSE2Safe }, + { "MGF_ColonNOTValid", MGF_ColonNOTValid }, + { "MGF_SALTED", MGF_SALTED }, + { "MGF_SALTED2", MGF_SALTED2 }, + { "MGF_USERID", MGF_USERID }, + { "MGF_INPBASE64", MGF_INPBASE64 }, + { "MFG_SALT_AS_HEX", MFG_SALT_AS_HEX }, + { NULL, 0 }}; + +static MD5_GEN_Setup Setup; +static int nMaxPreloadCnt; +static int nPreloadCnt; +static int nFuncCnt; +char SetupName[48]; +extern struct options_main options; + +int md5_gen_LOAD_PARSER_FUNCTIONS_LoadLINE(char *Line) +{ + if (!strncmp(Line, "Test=", 5)) + { + if (nPreloadCnt < nMaxPreloadCnt) + { + char *Passwd, *Hash, *tmp, *cp; + Passwd = malloc(strlen(Line)); + Hash = malloc(strlen(Line)); + tmp = malloc(strlen(Line)+1); + strcpy(tmp, Line); + cp = &tmp[5]; + cp = strchr(cp, options.loader.field_sep_char); + if (!cp) + { + fprintf(stderr, "Error, invalid test line: %s\n", Line); + return 0; + } + *cp ++ = 0; + strcpy(Hash, &tmp[5]); + strcpy(Passwd, cp); + strtok(Passwd, "\r\n"); + Setup.pPreloads[nPreloadCnt].Hash = Hash; + Setup.pPreloads[nPreloadCnt].Passwd = Passwd; + ++nPreloadCnt; + free(tmp); + if (strncmp(Hash, SetupName, strlen(SetupName))) + { + fprintf(stderr, "Error, invalid test line (wrong generic type): %s\n", Line); + return 0; + } + } + return 1; + } + if (!strncmp(Line, "Func=", 5)) + { + int i; + for (i = 0; MD5Gen_Predicate[i].name; ++i) + { + if (!strcasecmp(MD5Gen_Predicate[i].name, &Line[5])) + { + if (nFuncCnt == 4999) + { + fprintf(stderr, "Error, TOO complex generic md5. Only 5000 predicates can be used\n"); + return 0; + } + Setup.pFuncs[nFuncCnt++] = MD5Gen_Predicate[i].func; + return 1; + } + } + fprintf(stderr, "Error, unknown function: %s\n", Line); + return 0; + } + if (!strncmp(Line, "Flag=", 5)) + { + int i; + for (i = 0; MD5Gen_Str_Flag[i].name; ++i) + { + if (!strcasecmp(MD5Gen_Str_Flag[i].name, &Line[5])) + { + Setup.flags |= MD5Gen_Str_Flag[i].flag_bit; + return 1; + } + } + fprintf(stderr, "Error, unknown flag: %s\n", Line); + return 0; + } + if (!strncmp(Line, "SaltLen=", 8)) + { + if (sscanf(Line, "SaltLen=%d", &Setup.SaltLen) == 1) + return 1; + fprintf(stderr, "Error, Invalid SaltLen= line: %s \n", Line); + return 0; + } + if (!strncmp(Line, "Expression=", 11)) + { + char *orig = Setup.szFORMAT_NAME; + Setup.szFORMAT_NAME = malloc(strlen(orig)+1+strlen(&Line[11])+1); // 2 extra bytes. 1 for space, 1 for null + sprintf(Setup.szFORMAT_NAME, "%s %s", orig, &Line[11]); + free(orig); + return 1; + } + fprintf(stderr, "Error, unknown line: %s\n", Line); + return 0; +} + +char *md5_gen_LOAD_PARSER_SIGNATURE(int which) +{ + static char Sig[256]; + char SubSection[128]; + struct cfg_list *gen_source; + struct cfg_line *gen_line; + if (which < 1000) + return NULL; + + sprintf(SubSection, ":md5_gen(%d)", which); + + gen_source = cfg_get_list("list.generic", SubSection); + if (!gen_source) + return NULL; + + // Setup the 'default' format name + sprintf(Sig, "md5_gen(%d) ", which); + + gen_line = gen_source->head; + while (gen_line) + { + if (!strncmp(gen_line->data, "Expression=", 11)) + { + char SigApp[241]; + strncpy(SigApp, &gen_line->data[11], 240); + SigApp[240] = 0; + strcat(Sig, SigApp); + break; + } + } + return Sig; +} + +int md5_gen_LOAD_PARSER_FUNCTIONS(int which) +{ + // Ok, we load the section: + // [List.Generic.md5_gen(#)] where # == which + + char SubSection[128]; + struct cfg_list *gen_source; + struct cfg_line *gen_line; + + sprintf(SubSection, ":md5_gen(%d)", which); + + gen_source = cfg_get_list("list.generic", SubSection); + if (!gen_source) + { + fprintf(stderr, "Could not find section [List.Generic%s] in the john.ini/conf file\n", SubSection); + error(); + } + + // Setup the 'default' format name + Setup.szFORMAT_NAME = malloc(strlen(SubSection)); + sprintf(Setup.szFORMAT_NAME, "md5_gen(%d)", which); + strcpy(SetupName, Setup.szFORMAT_NAME); + + // allocate (and set null) 5000 file pointers + Setup.pFuncs = malloc(5000*sizeof(MD5_GEN_primitive_funcp)); + memset(Setup.pFuncs, 0, 5000*sizeof(MD5_GEN_primitive_funcp)); + + // allocate (and set null) 20 Preloads + nMaxPreloadCnt = 20; + Setup.pPreloads = malloc((nMaxPreloadCnt+1)*sizeof(MD5_GEN_Preloads)); + memset(Setup.pPreloads, 0, (nMaxPreloadCnt+1)*sizeof(MD5_GEN_Preloads)); + + Setup.flags = 0; + Setup.SaltLen = 0; + + // Ok, now 'grind' through the data I do know know how to use + // the config stuff too much, so will grind for now, and later + // go back over this, and do it 'right', if there is a right way + gen_line = gen_source->head; + while (gen_line) + { + if (!md5_gen_LOAD_PARSER_FUNCTIONS_LoadLINE(gen_line->data)) + { + fprintf(stderr, "Error parsing section [List.Generic%s] in the john.ini/conf file\n", SubSection); + error(); + } + gen_line = gen_line->next; + } + + md5_gen_SETUP(&Setup); + return 1; +} diff -urpN john-1.7.5.orig/src/md5_gen_preloads.c john-1.7.5/src/md5_gen_preloads.c --- john-1.7.5.orig/src/md5_gen_preloads.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/md5_gen_preloads.c 2009-10-29 00:33:57 +0000 @@ -0,0 +1,503 @@ +/* + * This software was written by Jim Fougeron jfoug AT cox dot net + * in 2009. No copyright is claimed, and the software is hereby + * placed in the public domain. In case this attempt to disclaim + * copyright and place the software in the public domain is deemed + * null and void, then the software is Copyright © 2009 Jim Fougeron + * and it is hereby released to the general public under the following + * terms: + * + * This software may be modified, redistributed, and used for any + * purpose, in source and binary forms, with or without modification. + * + * Generic MD5 hashes cracker + * + * Preloaded types md5gen(0) to md5gen(100) are 'reserved' types. + * They are loaded from this file. If someone tryes to build a 'custom' + * type in their john.ini file using one of those, john will abort + * the run. + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "md5.h" +#include "md5_gen.h" + +// +// HERE is the 'official' list of md5_gen(#) builtin's to John. +// +//md5_gen(0) --> md5($p) +//md5_gen(1) --> md5($p.$s) (joomla) +//md5_gen(2) --> md5(md5($p)) +//md5_gen(3) --> md5(md5(md5($p))) +//md5_gen(4) --> md5($s.$p) (osCommerce MD5 2 byte salt) +//md5_gen(5) --> md5($s.$p.$s) +//md5_gen(6) --> md5(md5($p).$s) +//md5_gen(7) --> md5(md5($p).$s) vBulletin (fixed 3 byte salt, colon not valid as field sep, since all chars from 0x20 to 0x7E are in the salt) +//md5_gen(8) --> md5(md5($s).$p) +//md5_gen(9) --> md5($s.md5($p)) +//md5_gen(10) --> md5($s.md5($s.$p)) +//md5_gen(11) --> md5($s.md5($p.$s)) +//md5_gen(12) --> md5(md5($s).md5($p)) (IPB) // note will NOT work in SSE2 code +//md5_gen(13) --> md5(md5($p).md5($s)) // note will NOT work in SSE2 code +//md5_gen(14) --> md5($s.md5($p).$s) +//md5_gen(15) --> md5($u.md5($p).$s) // note $u is not handled yet (but we can 'reserve' the format) +//md5_gen(16) --> md5(md5(md5($p).$s).$s2) // note 2 salts is not handled yet. +//md5_gen(17) --> phpass ($P$ or $H$) // phpass OR phpbb (or WordPress, etc). Should handle all conforming formats + +// gen_md5(0) raw-md5 +MD5_GEN_primitive_funcp _Funcs_0[] = +{ + MD5GenBaseFunc__InitialLoadKeysToInput, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_0[] = +{ + {"md5_gen(0)5a105e8b9d40e1329780d62ea2265d8a","test1"}, + {"md5_gen(0)378e2c4a07968da2eca692320136433d","thatsworking"}, + {"md5_gen(0)8ad8757baa8564dc136c1e07507f4a98","test3"}, + {NULL} +}; + +// gen_md5(1) Joomla md5($p.$s) +MD5_GEN_primitive_funcp _Funcs_1[] = +{ + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_keys, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_1[] = +{ + {"md5_gen(1)ed52af63d8ecf0c682442dfef5f36391$1aDNNojYGSc7pSzcdxKxhbqvLtEe4deG","test1"}, + {"md5_gen(1)4fa1e9d54d89bfbe48b4c0f0ca0a3756$laxcaXPjgcdKdKEbkX1SIjHKm0gfYt1c","thatsworking"}, + {"md5_gen(1)82568eeaa1fcf299662ccd59d8a12f54$BdWwFsbGtXPGc0H1TBxCrn0GasyAlJBJ","test3"}, + {NULL} +}; + + +// gen_md5(2) md5(md5($p)) +MD5_GEN_primitive_funcp _Funcs_2[] = +{ + MD5GenBaseFunc__InitialLoadKeysToInput, + MD5GenBaseFunc__crypt, + MD5GenBaseFunc__clean_input2, + MD5GenBaseFunc__append_from_last_output_to_input2_as_base16, + MD5GenBaseFunc__crypt_in2_to_out1, + NULL +}; +MD5_GEN_Preloads _Preloads_2[] = +{ + {"md5_gen(2)418d89a45edadb8ce4da17e07f72536c","test1"}, + {"md5_gen(2)ccd3c4231a072b5e13856a2059d04fad","thatsworking"}, + {"md5_gen(2)9992295627e7e7162bdf77f14734acf8","test3"}, + {NULL} +}; +// gen_md5(3) md5(md5(md5($p))) +MD5_GEN_primitive_funcp _Funcs_3[] = +{ + MD5GenBaseFunc__InitialLoadKeysToInput, + MD5GenBaseFunc__crypt, + MD5GenBaseFunc__clean_input2, + MD5GenBaseFunc__append_from_last_output_to_input2_as_base16, + MD5GenBaseFunc__crypt2, + // NOTE if we had an output_2_intput that overwrote instead of append, we would + // NOT need to clean here. + MD5GenBaseFunc__clean_input2, + MD5GenBaseFunc__append_from_last_output2_as_base16, + MD5GenBaseFunc__crypt_in2_to_out1, + NULL +}; +MD5_GEN_Preloads _Preloads_3[] = +{ + {"md5_gen(3)964c02612b2a1013ed26d46ba9a73e74","test1"}, + {"md5_gen(3)5d7e6330f69548797c07d97c915690fe","thatsworking"}, + {"md5_gen(3)2e54db8c72b312007f3f228d9d4dd34d","test3"}, + {NULL} +}; + +//md5_gen(4) --> md5($s.$p) +MD5_GEN_primitive_funcp _Funcs_4[] = +{ + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__append_keys, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_4[] = +{ + {"md5_gen(4)c02e8eef3eaa1a813c2ff87c1780f9ed$123456","test1"}, + {"md5_gen(4)4a2a1b013da3cda7f7e0625cf3dc3f4c$1234","thatsworking"}, + {"md5_gen(4)3a032e36a9609df6411b8004070431d3$aaaaa","test3"}, + {NULL} +}; + +//md5_gen(5) --> md5($s.$p.$s) +MD5_GEN_primitive_funcp _Funcs_5[] = +{ + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__append_keys, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_5[] = +{ + {"md5_gen(5)c1003cd39cb5523dd0923a94ab15a3c7$123456","test1"}, + {"md5_gen(5)c1c8618abfc7bdbc4a3c49c2c2c48f82$1234","thatsworking"}, + {"md5_gen(5)e7222e806a8ce5efa6d48acb3aa56dc2$aaaaa","test3"}, + {NULL} +}; + +//md5_gen(6) --> md5(md5($p).$s) +MD5_GEN_primitive_funcp _Funcs_6[] = +{ + MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1, + MD5GenBaseFunc__set_input_len_32, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_6[] = +{ + {"md5_gen(6)3a9ae23758f05da1fe539e55a096b03b$S111XB","test1"}, + {"md5_gen(6)9694d706d1992abf04344c1e7da1c5d3$T &222","thatsworking"}, + {"md5_gen(6)b7a7f0c374d73fac422bb01f07f5a9d4$lxxxl","test3"}, + {NULL} +}; + +//md5_gen(7) --> md5(md5($p).$s) vBulletin (forced 3 byte salt, valid chars from 0x20 to 0x7E) +MD5_GEN_primitive_funcp _Funcs_7[] = +{ + MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1, + MD5GenBaseFunc__set_input_len_32, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_7[] = +{ + {"md5_gen(7)daa61d77e218e42060c2fa198ac1feaf$SXB","test1"}, + {"md5_gen(7)de56b00bb15d6db79204bd44383469bc$T &","thatsworking"}, + {"md5_gen(7)fb685c6f469f6e549c85e4c1fb5a65a6$\\H:","test3"}, + {NULL} +}; + +//md5_gen(8) --> md5(md5($s).$p) +MD5_GEN_primitive_funcp _Funcs_8[] = +{ + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_from_last_output_as_base16, + MD5GenBaseFunc__append_keys, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_8[] = +{ + {"md5_gen(8)534c2fb38e757d9448315abb9822db00$aaaSXB","test1"}, + {"md5_gen(8)02547864bed278658e8f54dd6dfd69b7$123456","thatsworking"}, + {"md5_gen(8)2f6f3881972653ebcf86e5ad3071a4ca$5555hh","test3"}, + {NULL} +}; + +//md5_gen(9) --> md5($s.md5($p)) +MD5_GEN_primitive_funcp _Funcs_9[] = +{ +// MD5GenBaseFunc__InitialLoadKeysToInput, +// MD5GenBaseFunc__crypt, +// MD5GenBaseFunc__clean_input2, +// MD5GenBaseFunc__append_salt2, +// MD5GenBaseFunc__append_from_last_output_to_input2_as_base16, +// MD5GenBaseFunc__crypt_in2_to_out1, +// NULL +#if defined (MMX_COEF) + MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2, + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16, + MD5GenBaseFunc__crypt, + NULL +#else + MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1, + MD5GenBaseFunc__clean_input2, + MD5GenBaseFunc__append_salt2, + MD5GenBaseFunc__append_input2_from_input, + MD5GenBaseFunc__crypt_in2_to_out1, + NULL +#endif +}; +MD5_GEN_Preloads _Preloads_9[] = +{ + {"md5_gen(9)b38c18b5e5b676e211442bd41000b2ec$aaaSXB","test1"}, + {"md5_gen(9)4dde7cd4cbf0dc4c59b255ae77352914$123456","thatsworking"}, + {"md5_gen(9)899af20e3ebdd77aaecb0d9bc5fbbb66$5555hh","test3"}, + {NULL} +}; + +//md5_gen(10) --> md5($s.md5($s.$p)) +MD5_GEN_primitive_funcp _Funcs_10[] = +{ + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__append_keys, + MD5GenBaseFunc__crypt, + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__append_from_last_output_as_base16, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_10[] = +{ + {"md5_gen(10)781f83a676f45169dcfc7f36dfcdc3d5$aaaSXB","test1"}, + {"md5_gen(10)f385748e67a2dc1f6379b9124fabc0df$123456","thatsworking"}, + {"md5_gen(10)9e3702bb13386270cd4b0bd4dbdd489e$5555hh","test3"}, + {NULL} +}; + +//md5_gen(11) --> md5($s.md5($p.$s)) +MD5_GEN_primitive_funcp _Funcs_11[] = +{ + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_keys, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__append_from_last_output_as_base16, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_11[] = +{ + {"md5_gen(11)f809a64cbd0d23e099cd5b544c8501ac$aaaSXB","test1"}, + {"md5_gen(11)979e6671535cda6db95357d8a0afd9ac$123456","thatsworking"}, + {"md5_gen(11)78a61ea73806ebf27bef2ab6a9bf5412$5555hh","test3"}, + {NULL} +}; + +//md5_gen(12) --> md5(md5($s).md5($p)) // note will NOT work in SSE2 code +MD5_GEN_primitive_funcp _Funcs_12[] = +{ + // NOTE, only works for non-SSE2 (64 byte last md5 too big for SSE2) + MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1_offset32, + MD5GenBaseFunc__overwrite_salt_to_input1_no_size_fix, + MD5GenBaseFunc__set_input_len_64, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_12[] = +{ + {"md5_gen(12)fbbd9532460f2d03fa8af9e75c41eefc$aaaSXB","test1"}, + {"md5_gen(12)b80eef24d1d01b61b3beff38559f9d26$123456","thatsworking"}, + {"md5_gen(12)1e5489bdca008aeed6e390ee87ce9b92$5555hh","test3"}, + {NULL} +}; + +//md5_gen(13) --> md5(md5($p).md5($s)) // note will NOT work in SSE2 code +MD5_GEN_primitive_funcp _Funcs_13[] = +{ + // NOTE, only works for non-SSE2 (64 byte last md5 too big for SSE2) + MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1, + MD5GenBaseFunc__set_input_len_32, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_13[] = +{ + {"md5_gen(13)c6b69bec81d9ff5d0560d8f469a8efd5$aaaSXB","test1"}, + {"md5_gen(13)7abf788b3abbfc8719d900af96a3763a$123456","thatsworking"}, + {"md5_gen(13)1c55e15102ed17eabe5bf11271c7fcae$5555hh","test3"}, + {NULL} +}; + +//md5_gen(14) --> md5($s.md5($p).$s) +MD5_GEN_primitive_funcp _Funcs_14[] = +{ +// MD5GenBaseFunc__InitialLoadKeysToInput, +// MD5GenBaseFunc__crypt, +// MD5GenBaseFunc__clean_input2, +// MD5GenBaseFunc__append_salt2, +// MD5GenBaseFunc__append_from_last_output_to_input2_as_base16, +// MD5GenBaseFunc__append_salt2, +// MD5GenBaseFunc__crypt_in2_to_out1, +// NULL + +#if defined (MMX_COEF) + MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2, + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__append_from_last_output2_to_input1_as_base16, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + NULL +#else + + MD5GenBaseFunc__InitialLoadKeys_md5crypt_ToOutput2_Base16_to_Input1, + MD5GenBaseFunc__clean_input2, + MD5GenBaseFunc__append_salt2, + MD5GenBaseFunc__append_input2_from_input, + MD5GenBaseFunc__append_salt2, + MD5GenBaseFunc__crypt_in2_to_out1, + NULL +#endif +}; +MD5_GEN_Preloads _Preloads_14[] = +{ + {"md5_gen(14)778e40e10d82a08f5377992330008cbe$aaaSXB","test1"}, + {"md5_gen(14)d6321956964b2d27768df71d139eabd2$123456","thatsworking"}, + {"md5_gen(14)1b3c72e16427a2f4f0819243877f7967$5555hh","test3"}, + {NULL} +}; + +//md5_gen(15) --> md5($u.md5($p).$s) // note $u is not handled yet (but we can 'reserve' the format) +MD5_GEN_primitive_funcp _Funcs_15[] = +{ + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_keys, + MD5GenBaseFunc__crypt, + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_userid, + MD5GenBaseFunc__append_from_last_output_as_base16, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + NULL +}; +MD5_GEN_Preloads _Preloads_15[] = +{ + {"md5_gen(15)778e40e10d82a08f5377992330008cbe$aaaSXB","test1"}, + {"md5_gen(15)d6321956964b2d27768df71d139eabd2$123456","thatsworking"}, + {"md5_gen(15)1b3c72e16427a2f4f0819243877f7967$5555hh","test3"}, + {NULL} +}; + +//md5_gen(16) --> md5(md5(md5($p).$s).$s2) // note 2 salts is not handled yet. +MD5_GEN_primitive_funcp _Funcs_16[] = +{ + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_keys, + MD5GenBaseFunc__crypt, + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_from_last_output_as_base16, + MD5GenBaseFunc__append_salt, + MD5GenBaseFunc__crypt, + MD5GenBaseFunc__clean_input, + MD5GenBaseFunc__append_from_last_output_as_base16, + MD5GenBaseFunc__append_2nd_salt, + NULL +}; +MD5_GEN_Preloads _Preloads_16[] = +{ + {"md5_gen(16)778e40e10d82a08f5377992330008cbe$aaaSXB","test1"}, + {"md5_gen(16)d6321956964b2d27768df71d139eabd2$123456","thatsworking"}, + {"md5_gen(16)1b3c72e16427a2f4f0819243877f7967$5555hh","test3"}, + {NULL} +}; + +//md5_gen(17) --> $P$7 phpass (or $H$7 +MD5_GEN_primitive_funcp _Funcs_17[] = +{ + MD5GenBaseFunc__PHPassSetup, + MD5GenBaseFunc__PHPassCrypt, + NULL +}; +MD5_GEN_Preloads _Preloads_17[] = +{ + // format: md5_gen(17)hash$Xssssssss + // Xssssssss is the 9 bytes immediately following the standard + // signature of $P$ So $P$912345678jgypwqm.JsMssPLiS8YQ00 the + // 912345678 will be inserted into $Xssssssss + // ssssssss is the salt, and X is a byte used to count how many + // times we do the inner md5 crypt packing. + {"md5_gen(17)jgypwqm.JsMssPLiS8YQ00$9aaaaaSXB","test1"}, + {"md5_gen(17)5R3ueot5zwV.7MyzAItyg/$912345678","thatsworking"}, + {"md5_gen(17)Y5RwgMij0xFsUIrr33lM1/$9555555hh","test3"}, + +// {"md5_gen(17)yhzfTrJXcouTpLleLSbnY/$7aaaaaSXB","test1"}, +// {"md5_gen(17)mwulIMWPGe6RPXG1/R8l50$712345678","thatsworking"}, +// {"md5_gen(17)nfKm8qpXa88RVUjLgjY/u1$7555555hh","test3"}, + +// {"md5_gen(17)JSe8S8ufpLrsNE7utOpWc/$BaaaaaSXB","test1"}, +// {"md5_gen(17)aqkw6carDzQ67zCLOvVp60$B712345678","thatsworking"}, +// {"md5_gen(17)o2j.1E7X1NvVyEJ/QY9hX0$B555555hh","test3"}, + + {NULL} +}; + +static MD5_GEN_Setup Setups[] = +{ + { " md5_gen(0): md5($p) (raw-md5) ", _Funcs_0, _Preloads_0 }, + { " md5_gen(1): md5($p.$s) (joomla) ", _Funcs_1, _Preloads_1, MGF_SALTED }, + { " md5_gen(2): md5(md5($p)) (e107) ", _Funcs_2, _Preloads_2 }, + { " md5_gen(3): md5(md5(md5($p))) ", _Funcs_3, _Preloads_3 }, + { " md5_gen(4): md5($s.$p) (OSC) ", _Funcs_4, _Preloads_4, MGF_SALTED }, + { " md5_gen(5): md5($s.$p.$s) ", _Funcs_5, _Preloads_5, MGF_SALTED }, + { " md5_gen(6): md5(md5($p).$s) ", _Funcs_6, _Preloads_6, MGF_SALTED }, + { " md5_gen(7): md5(md5($p).$s) (vBulletin) ", _Funcs_7, _Preloads_7, MGF_SALTED|MGF_ColonNOTValid, 3 }, + { " md5_gen(8): md5(md5($s).$p) ", _Funcs_8, _Preloads_8, MGF_SALTED }, + { " md5_gen(9): md5($s.md5($p)) ", _Funcs_9, _Preloads_9, MGF_SALTED }, + { " md5_gen(10): md5($s.md5($s.$p)) ", _Funcs_10,_Preloads_10,MGF_SALTED }, + { " md5_gen(11): md5($s.md5($p.$s)) ", _Funcs_11,_Preloads_11,MGF_SALTED }, + { " md5_gen(12): md5(md5($s).md5($p)) (IPB) ", _Funcs_12,_Preloads_12,MGF_SALTED|MGF_NOTSSE2Safe|MFG_SALT_AS_HEX }, + { " md5_gen(13): md5(md5($p).md5($s)) ", _Funcs_13,_Preloads_13,MGF_SALTED|MGF_NOTSSE2Safe|MFG_SALT_AS_HEX }, + { " md5_gen(14): md5($s.md5($p).$s) ", _Funcs_14,_Preloads_14,MGF_SALTED }, + { " md5_gen(15): md5($u.md5($p).$s) ", _Funcs_15,_Preloads_15,MGF_SALTED|MGF_USERID }, + { " md5_gen(16): md5(md5(md5($p).$s).$s2) ", _Funcs_16,_Preloads_16,MGF_SALTED|MGF_SALTED2 }, + { " md5_gen(17): phpass ($P$ or $H$) ", _Funcs_17,_Preloads_17,MGF_SALTED|MGF_INPBASE64, 9 }, +}; + +char *md5_gen_PRELOAD_SIGNATURE(int cnt) +{ + if (cnt < 0 || cnt > 1000) + return NULL; + if (cnt >= ARRAY_COUNT(Setups)) + return NULL; + return Setups[cnt].szFORMAT_NAME; +} + +void md5_gen_RESERVED_PRELOAD_SETUP(int cnt) +{ + if (cnt < 0 || cnt > 1000) + exit(fprintf(stderr, "Error, RESERVED_PRELOAD of md5-gen called for out of range\n")); + if (cnt >= ARRAY_COUNT(Setups)) + exit(fprintf(stderr, "Error, RESERVED_PRELOAD of md5-gen(%d) is not defined at this time\n", cnt)); + + md5_gen_SETUP(&Setups[cnt]); +} + +// -1 is NOT valid +// 0 is valid, but NOT usable by this build (i.e. no SSE2) +// 1 is valid. +int md5_gen_IS_VALID(int i) +{ + if (i < 0 || i > 100) + return -1; + if (i >= ARRAY_COUNT(Setups)) + return -1; + +#if defined (MMX_COEF) + if (Setups[i].flags & MGF_NOTSSE2Safe) + return 0; // not valid, but not at the end of the list. +#endif + + // At this time, we do NOT support $s2 or $u + if (Setups[i].flags & MGF_SALTED2) + return 0; + if (Setups[i].flags & MGF_USERID) + return 0; + + return 1; +} diff -urpN john-1.7.5.orig/src/md5_go.c john-1.7.5/src/md5_go.c --- john-1.7.5.orig/src/md5_go.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/md5_go.h john-1.7.5/src/md5_go.h --- john-1.7.5.orig/src/md5_go.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/misc.c john-1.7.5/src/misc.c --- john-1.7.5.orig/src/misc.c 2003-09-18 10:30:51 +0000 +++ john-1.7.5/src/misc.c 2009-12-27 17:38:21 +0000 @@ -4,7 +4,12 @@ */ #include +#if !defined (_MSC_VER) #include +#else +#include +#pragma warning ( disable : 4996 ) +#endif #include #include #include @@ -124,6 +129,7 @@ char *strnzcat(char *dst, char *src, int return dst; } +#if !defined (_MSC_VER) char *strlwr(char *s) { unsigned char *ptr = (unsigned char *)s; @@ -136,3 +142,4 @@ char *strlwr(char *s) return s; } +#endif diff -urpN john-1.7.5.orig/src/misc.h john-1.7.5/src/misc.h --- john-1.7.5.orig/src/misc.h 2003-09-06 20:30:26 +0000 +++ john-1.7.5/src/misc.h 2009-07-03 21:00:12 +0000 @@ -61,6 +61,10 @@ extern char *strnzcat(char *dst, char *s /* * Converts a string to lowercase. */ +#if !defined (_MSC_VER) extern char *strlwr(char *s); +#else +#define strlwr _strlwr +#endif #endif diff -urpN john-1.7.5.orig/src/mkv.c john-1.7.5/src/mkv.c --- john-1.7.5.orig/src/mkv.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/mkv.c 2010-03-02 16:28:30 +0000 @@ -0,0 +1,317 @@ +#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" + +#if defined (__MINGW32__) || defined (_MSC_VER) +// Later versions of MSVC can handle %lld but some older +// ones can only handle %I64d. Easiest to simply use +// %I64d then all versions of MSVC will handle it just fine +// MinGW is 'same', since it uses msvcrt.dll +#define LLd "%I64d" +#else +#define LLd "%lld" +#endif + +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; + char pass_filtered[PLAINTEXT_BUFFER_SIZE]; + char * pass; + + 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; + } + pass = (char*) pwd->password; + if (!ext_mode || !f_filter || ext_filter_body((char*) pwd->password, pass = pass_filtered)) + if(crk_process_key(pass)) + 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; + char pass_filtered[PLAINTEXT_BUFFER_SIZE]; + char * pass; + + 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 ]; + pass = (char*) pwd->password; + if (!ext_mode || !f_filter || ext_filter_body((char*)pwd->password, pass = pass_filtered)) + if(crk_process_key(pass)) + 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; + } + pass = (char*) pwd->password; + if (!ext_mode || !f_filter || ext_filter_body((char*)pwd->password, pass = pass_filtered)) + if(crk_process_key(pass)) + 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; + char pass_filtered[PLAINTEXT_BUFFER_SIZE]; + char * pass; + + 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; + + pass = (char*) pwd.password; + if (!ext_mode || !f_filter || ext_filter_body((char*)pwd.password, pass = pass_filtered)) + if(crk_process_key(pass)) + 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; + pass = (char*) pwd.password; + if (!ext_mode || !f_filter || ext_filter_body((char*)pwd.password, pass = pass_filtered)) + if(crk_process_key(pass)) + return 1; + gidx++; + i++; + } + return 0; +} + +static int get_progress(int *hundth_perc) +{ + unsigned long long lltmp; + unsigned hun; + int per; + + if(gend == 0) + return 0; + + lltmp = gidx; + lltmp -= gstart; + lltmp *= 10000; + lltmp /= (gend-gstart); + + hun = (unsigned)lltmp; + per = (int)(hun/100); + *hundth_perc = (int)(hun-(per*100)); + return per; +} + +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); +} diff -urpN john-1.7.5.orig/src/mkv.h john-1.7.5/src/mkv.h --- john-1.7.5.orig/src/mkv.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/mkvcalcproba.c john-1.7.5/src/mkvcalcproba.c --- john-1.7.5.orig/src/mkvcalcproba.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/mkvcalcproba.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,153 @@ +#include +#include +#if !defined (_MSC_VER) +#include +#else +#pragma warning ( disable : 4244 ) +#endif +#include + +#if defined (__MINGW32__) || defined (_MSC_VER) +// Later versions of MSVC can handle %lld but some older +// ones can only handle %I64d. Easiest to simply use +// %I64d then all versions of MSVC will handle it just fine +#define LLd "I64d" +#else +#define LLd "lld" +#endif + +#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.5.orig/src/mkvlib.c john-1.7.5/src/mkvlib.c --- john-1.7.5.orig/src/mkvlib.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/mkvlib.h john-1.7.5/src/mkvlib.h --- john-1.7.5.orig/src/mkvlib.h 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/mscash_fmt.c john-1.7.5/src/mscash_fmt.c --- john-1.7.5.orig/src/mscash_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/mscash_fmt.c 2009-10-29 03:53:54 +0000 @@ -0,0 +1,548 @@ +/* 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, + NULL, + NULL + }, + salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + get_hash_0, + get_hash_1, + get_hash_2, + NULL, + NULL + }, + cmp_all, + cmp_one, + cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/mssql05_fmt.c john-1.7.5/src/mssql05_fmt.c --- john-1.7.5.orig/src/mssql05_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/mssql05_fmt.c 2009-12-27 17:38:21 +0000 @@ -0,0 +1,323 @@ +/* + * 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) << ( ( (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 + unsigned i, index; + for (index = 0; index < count; ++index) + { + unsigned len = (total_len >> ((32/MMX_COEF)*index)) & 0xFF; + 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) << ( ( (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 + unsigned i, index; + for (index = 0; index < count; ++index) + { + unsigned len = (total_len >> ((32/MMX_COEF)*index)) & 0xFF; + 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 options.loader.max_pps) { + fprintf(stderr, "Min number salts wanted is less than Max salts wanted\n"); + error(); + } } if (options.length < 0) @@ -180,6 +258,58 @@ void opt_init(char *name, int argc, char error(); } + if (options.flags & FLG_MKV_CHK) { + options.mkv_start = 0; options.mkv_end = 0; options.mkv_maxlen = + 0; + if (options.mkv_param) + sscanf(options.mkv_param, "%d:%lld:%lld:%d", &options.mkv_level, &options.mkv_start, &options.mkv_end, &options.mkv_maxlen); + } + + if ( (options.flags & FLG_SHOW_SET) && options.showuncracked_str) { + if (!strcasecmp( options.showuncracked_str, "left")) { + options.loader.showuncracked = 1; + // Note we 'do' want the pot file to load normally, but during that load, + // we print out hashes left. At the end of the load, john exits. However + // we do NOT want the 'special' -SHOW_CHK logic to happen (which happens + // instead of normal loading if we are in 'normal' show mode) + options.flags &= ~FLG_SHOW_CHK; + } + else { + fprintf(stderr, "Invalid option in --show switch.\nOnly --show or --show=left are valid\n"); + error(); + } + } + + if (options.loader.activepot == NULL) + options.loader.activepot = str_alloc_copy(POT_NAME); + + if (options.loader.activewordlistrules == NULL) + options.loader.activewordlistrules = str_alloc_copy(SUBSECTION_WORDLIST); + + if (options.loader.activesinglerules == NULL) + options.loader.activesinglerules = str_alloc_copy(SUBSECTION_SINGLE); + + if (field_sep_char_string != NULL) + { + if (strlen(field_sep_char_string) == 1) + options.field_sep_char = *field_sep_char_string; + else if (field_sep_char_string[0] == '\\' && (field_sep_char_string[1]=='x'||field_sep_char_string[1]=='X')) + { + unsigned xTmp=0; + sscanf(&field_sep_char_string[2], "%x", &xTmp); + if (!xTmp || xTmp > 255) + { + fprintf (stderr, "trying to use an invalid field separator char: %s\n", field_sep_char_string); + error(); + } + options.field_sep_char = (char)xTmp; + } + + options.loader.field_sep_char = options.field_sep_char; + if (options.loader.field_sep_char != ':') + fprintf (stderr, "using field sep char '%c' (0x%02x)\n", options.field_sep_char, options.field_sep_char); + } + rec_argc = argc; rec_argv = argv; rec_check = 0; } diff -urpN john-1.7.5.orig/src/options.h john-1.7.5/src/options.h --- john-1.7.5.orig/src/options.h 2009-09-09 05:09:01 +0000 +++ john-1.7.5/src/options.h 2010-01-19 07:00:39 +0000 @@ -26,7 +26,7 @@ /* An option requires password files */ #define FLG_PWD_REQ (0x00000008 | FLG_PWD_SUP) /* Some option that doesn't have its own flag is specified */ -#define FLG_NONE 0x00000010 +#define FLG_NONE 0x00000000 /* A cracking mode enabled */ #define FLG_CRACKING_CHK 0x00000020 #define FLG_CRACKING_SUP 0x00000040 @@ -82,6 +82,12 @@ #define FLG_FORMAT 0x02000000 /* Memory saving enabled */ #define FLG_SAVEMEM 0x04000000 +/* Ciphertext 'sub'format forced (for md5-gen which has multiple formats)*/ +#define FLG_SUB_FORMAT 0x20000000 + +/* Markov mode enabled */ +#define FLG_MKV_CHK 0x40000000 +#define FLG_MKV_SET (FLG_MKV_CHK | FLG_CRACKING_SET) /* * Structure with option flags and all the parameters. @@ -102,6 +108,9 @@ struct options_main { /* Ciphertext format name */ char *format; +/* Ciphertext subformat name */ + char *subformat; + /* Wordlist file name */ char *wordlist; @@ -111,8 +120,19 @@ struct options_main { /* External mode or word filter name */ char *external; +/* Markov stuff */ + char *mkv_param; + unsigned long long mkv_start; + unsigned long long mkv_end; + unsigned int mkv_level; + unsigned int mkv_maxlen; + /* Maximum plaintext length for stdout mode */ int length; + + char *showuncracked_str; + char *salt_param; + char field_sep_char; }; extern struct options_main options; diff -urpN john-1.7.5.orig/src/oracle11_fmt.c john-1.7.5/src/oracle11_fmt.c --- john-1.7.5.orig/src/oracle11_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/oracle11_fmt.c 2010-02-26 02:30:29 +0000 @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2008 Alexandre Hamelin + * alexandre.hamelin(@)gmail.com + * Based on saltSHA1 format source. + * + * Oracle 11g SHA1 cracker + * + * Please note that a much better way to crack Oracle 11g passwords exists than + * brute forcing the SHA1 hash since the pre-Oracle 10g hash is still stored in + * the SYS.USER$ table in the column PASSWORD. + * + * $ uname -a + * Linux xyz 2.6.22-hardened-r8 #1 SMP Fri Jan 11 23:24:31 EST 2008 x86_64 AMD Athlon(tm) 64 X2 Dual Core Processor 5200+ AuthenticAMD GNU/Linux + * $ ./john --test + * [...] + * Benchmarking: Oracle 11g [oracle11]... DONE + * Many salts: 2387K c/s real, 2507K c/s virtual + * Only one salt: 2275K c/s real, 2275K c/s virtual + * [...] + * + * To use: + * 1. Connect as a DBA to Oracle 11g with sqlplus + * 2. set heading off + * set feedback off + * set pagesize 1000 + * set linesize 100 + * spool ora11-passwds.txt + * 3. SELECT name || ':' || SUBSTR(spare4,3) + * FROM sys.user$ + * WHERE spare4 IS NOT NULL + * ORDER BY name; + * 4. spool off + * quit + * 5. Remove extra spaces (%s:/\s\+$//) and extra lines (:g!/:\w/d) in output. + * 6. ./john [-f:oracle11] ora11-passwds.txt + * + * TODO: + * The prefix "S:" suggests that other hashing functions might be used to store + * user passwords; if this is indeed possible (I've not verified in the docs + * yet) maybe implement other 11g cracking functions in the same oracle11_fmt.c + * file. + * Change the hash format for JtR? Prefix with "O11$" or "S:" ? (but "S:" might + * not be possible due to the way JtR parses password files) + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "sha.h" +#include + +#define FORMAT_LABEL "oracle11" +#define FORMAT_NAME "Oracle 11g" +#define ALGORITHM_NAME "oracle11" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +/* Maximum length of password in characters. Oracle supports identifiers of 30 + * characters max. (ALTER USER user IDENTIFIED BY 30lettersPassword) */ +#define PLAINTEXT_LENGTH 30 +/* Length in characters of the cipher text, as seen in the password file. + * Excludes prefix if any. */ +#define CIPHERTEXT_LENGTH 60 + +/* Length of hashed value without the salt, in bytes. */ +#define BINARY_SIZE 20 +/* Length of salt in bytes. */ +#define SALT_SIZE 10 + +/* Sanity check. Don't change. */ +#if (BINARY_SIZE + SALT_SIZE) * 2 != CIPHERTEXT_LENGTH +#error Incorrect binary sizes or cipher text length. +#endif + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + /* 160 bits of SHA1, followed by 80 bits of salt. No "S:" prefix. */ + {"5FDAB69F543563582BA57894FE1C1361FB8ED57B903603F2C52ED1B4D642", "abc123"}, + {"450F957ECBE075D2FA009BA822A9E28709FBC3DA82B44D284DDABEC14C42", "SyStEm123!@#"}, + {"3437FF72BD69E3FB4D10C750B92B8FB90B155E26227B9AB62D94F54E5951", "oracle"}, + {"61CE616647A4F7980AFD7C7245261AF25E0AFE9C9763FCF0D54DA667D4E6", "11g"}, + {"B9E7556F53500C8C78A58F50F24439D79962DE68117654B6700CE7CC71CF", "11g"}, + {NULL} +}; + +static char saved_key[PLAINTEXT_LENGTH + 1]; +static int saved_key_length; +static unsigned char saved_salt[SALT_SIZE]; +static SHA_CTX ctx; +static unsigned char crypt_out[BINARY_SIZE]; + +static int valid(char *ciphertext) +{ + int i; + + for (i = 0; i < CIPHERTEXT_LENGTH; i++) + if (atoi16[ARCH_INDEX(ciphertext[i])] == 0x7F) + return 0; + return !ciphertext[i]; +} + +static void *salt(char *ciphertext) +{ + static unsigned char salt[SALT_SIZE]; + int i; + + for (i = 0; i < SALT_SIZE; i++) { + salt[i] = atoi16[ARCH_INDEX(ciphertext[BINARY_SIZE*2+i*2+0])]*16 + + atoi16[ARCH_INDEX(ciphertext[BINARY_SIZE*2+i*2+1])]; + } + + return (void *)salt; +} + +static void set_salt(void *salt) +{ + memcpy(saved_salt, salt, SALT_SIZE); +} + +static void set_key(char *key, int index) { + saved_key_length = strlen(key); + if (saved_key_length > PLAINTEXT_LENGTH) + saved_key_length = PLAINTEXT_LENGTH; + memcpy(saved_key, key, saved_key_length); + saved_key[saved_key_length] = 0; +} + +static char *get_key(int index) { + return saved_key; +} + +static int cmp_all(void *binary, int index) { + return !memcmp(binary, crypt_out, BINARY_SIZE); +} + +static int cmp_exact(char *source, int count) { + return 1; +} + +static void crypt_all(int count) { + SHA1_Init( &ctx ); + SHA1_Update( &ctx, (unsigned char *) saved_key, saved_key_length ); + SHA1_Update( &ctx, saved_salt, SALT_SIZE ); + SHA1_Final( crypt_out, &ctx); +} + +static void * binary(char *ciphertext) +{ + static unsigned char realcipher[BINARY_SIZE]; + + int i; + for(i=0;i +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "oracle" +#define FORMAT_NAME "Oracle" +#define ALGORITHM_NAME "oracle" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 120 + +#define BINARY_SIZE 8 +#define SALT_SIZE (32 + 2) +#define CIPHERTEXT_LENGTH 16 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests oracle_tests[] = { + {"O$SYSTEM#9EEDFA0AD26C6D52", "THALES" }, + {"O$SIMON#4F8BC1809CB2AF77", "A"}, + {"O$SIMON#183D72325548EF11", "THALES2" }, + {"O$SIMON#C4EB3152E17F24A4", "TST" }, + {"O$BOB#b02c8e79ed2e7f46", "LAPIN" }, + {"O$BOB#6bb4e95898c88011", "LAPINE" }, + {"O$BOB#cdc6b483874b875b", "GLOUGLOU" }, + {"O$BOB#ef1f9139db2d5279", "GLOUGLOUTER" }, + {"O$BOB#c0ee5107c9a080c1", "AZERTYUIOP" }, + {"O$BOB#99e8b231d33772f9", "CANARDWC" }, + {"O$BOB#da3224126a67c8ed", "COUCOU_COUCOU" }, + {"O$BOB#ec8147abb3373d53", "LONG_MOT_DE_PASSE_OUI" }, + {NULL} +}; + +#if ARCH_LITTLE_ENDIAN +#define ENDIAN_SHIFT_L << 8 +#define ENDIAN_SHIFT_R >> 8 +#else +#define ENDIAN_SHIFT_L +#define ENDIAN_SHIFT_R +#endif + +static ARCH_WORD_32 crypt_key[2]; + +static unsigned short cur_salt[SALT_SIZE / 2 + PLAINTEXT_LENGTH]; +static unsigned short cur_key[PLAINTEXT_LENGTH + 1]; + +static DES_key_schedule desschedule1; +static DES_key_schedule desschedule2; + +static int salt_length; +static int key_length; + +static int valid(char *ciphertext) +{ + int i; + int l; + + /* + * 2 cases + * 1 - it comes from the disk, and does not have O$ + salt + * 2 - it comes from memory, and has got O$ + salt + # + blah + */ + + if (!memcmp(ciphertext, "O$", 2)) + { + l = strlen(ciphertext) - CIPHERTEXT_LENGTH; + if(ciphertext[l-1]!='#') + return 0; + } + else + { + if(strlen(ciphertext)!=CIPHERTEXT_LENGTH) + return 0; + l = 0; + } + for (i = l; i < l + CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) + return 0; + } + + return 1; +} + +static void oracle_init(void) +{ + unsigned char deskey[8]; + + deskey[0] = 0x01; + deskey[1] = 0x23; + deskey[2] = 0x45; + deskey[3] = 0x67; + deskey[4] = 0x89; + deskey[5] = 0xab; + deskey[6] = 0xcd; + deskey[7] = 0xef; + + DES_set_key((DES_cblock *)deskey, &desschedule1); +} + +static inline unsigned char upper(unsigned char c) +{ + if( (c>='a') && (c<='z')) + return c+'A'-'a'; + return c; +} + +static void oracle_set_salt(void *salt) { + salt_length = *(unsigned short *)salt; + memcpy(cur_salt, (char *)salt+2, salt_length); +} + +static void oracle_set_key(char *key, int index) { + key_length = 0; + while( (cur_key[key_length] = upper(key[key_length]) ENDIAN_SHIFT_L )) + key_length++; + key_length <<= 1; +} + +static char *oracle_get_key(int index) { + static unsigned char out[PLAINTEXT_LENGTH + 1]; + unsigned int i; + for(i=0;i>1;i++) + out[i] = cur_key[i] ENDIAN_SHIFT_R; + out[i] = 0; + return (char *) out; +} + +static void oracle_crypt_all(int count) +{ + unsigned char buf[sizeof(cur_salt)]; + unsigned int l; + + l = salt_length + key_length; + crypt_key[0] = 0; + crypt_key[1] = 0; + memcpy((char *)cur_salt + salt_length, cur_key, key_length); + DES_ncbc_encrypt((unsigned char *)cur_salt, buf, l, &desschedule1, (DES_cblock *) crypt_key, DES_ENCRYPT); + DES_set_key((DES_cblock *)crypt_key, &desschedule2); + crypt_key[0] = 0; + crypt_key[1] = 0; + DES_ncbc_encrypt((unsigned char *)cur_salt, buf, l, &desschedule2, (DES_cblock *) crypt_key, DES_ENCRYPT); +} + +static void * oracle_binary(char *ciphertext) +{ + static unsigned char out3[BINARY_SIZE]; + int l; + int i; + l = strlen(ciphertext) - CIPHERTEXT_LENGTH; + for(i=0;i= SALT_SIZE-2) break; + } + salt[l-2] = 0; + + l = 0; + while ((out[l+1] = upper(salt[l]) ENDIAN_SHIFT_L)) + l++; + out[0] = l*2; + + return out; +} + +static int binary_hash1(void * binary) { return (((ARCH_WORD_32 *)binary)[0] & 0xf); } +static int binary_hash2(void * binary) { return (((ARCH_WORD_32 *)binary)[0] & 0xff); } +static int binary_hash3(void * binary) { return (((ARCH_WORD_32 *)binary)[0] & 0xfff); } + +static int get_hash1(int index) { return crypt_key[0] & 0xf; } +static int get_hash2(int index) { return crypt_key[0] & 0xff; } +static int get_hash3(int index) { return crypt_key[0] & 0xfff; } + +static int oracle_cmp_all(void *binary, int index) { + return !memcmp(binary, crypt_key, sizeof(crypt_key)); +} + +static int oracle_cmp_exact(char *source, int count) { + return 1; +} + +struct fmt_main fmt_oracle = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_8_BIT, + oracle_tests + }, { + oracle_init, + valid, + fmt_default_split, + oracle_binary, + oracle_get_salt, + { + binary_hash1, + binary_hash2, + binary_hash3, + NULL, + NULL + }, + 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, + NULL, + NULL + }, + oracle_cmp_all, + oracle_cmp_all, + oracle_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/params.h john-1.7.5/src/params.h --- john-1.7.5.orig/src/params.h 2010-02-24 18:20:16 +0000 +++ john-1.7.5/src/params.h 2010-03-02 16:20:58 +0000 @@ -15,7 +15,7 @@ /* * John's version number. */ -#define JOHN_VERSION "1.7.5" +#define JOHN_VERSION "1.7.5-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. @@ -272,4 +272,8 @@ extern int password_hash_thresholds[PASS #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.5.orig/src/phpassMD5_fmt.c john-1.7.5/src/phpassMD5_fmt.c --- john-1.7.5.orig/src/phpassMD5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/phpassMD5_fmt.c 2009-10-29 00:31:37 +0000 @@ -0,0 +1,148 @@ +/* + * This software was written by Jim Fougeron jfoug AT cox dot net + * in 2009. No copyright is claimed, and the software is hereby + * placed in the public domain. In case this attempt to disclaim + * copyright and place the software in the public domain is deemed + * null and void, then the software is Copyright © 2009 Jim Fougeron + * and it is hereby released to the general public under the following + * terms: + * + * This software may be modified, redistributed, and used for any + * purpose, in source and binary forms, with or without modification. + * + * Cracks phpass 'portable' hashes, and phpBBv3 hashes, which + * are simply phpass portable, with a slightly different signature. + * These are 8 byte salted hashes, with a 1 byte 'salt' that + * defines the number of loops to compute. Internally we work + * with 8 byte salt (the 'real' salt), but let john track it as + * 9 byte salts (the loop count byte is appened to the 'real' + * 8 byte salt value. + * + * code should be pretty fast, and pretty well debugged. Works + * even if there are multple loop count values in the set of + * hashes. PHPv5 kicked up the default loop number, but it is + * programatically allowed to have different looping counts. + * This format should handle all valid loop values. + * + * using SSL version of MD5 and SSE2/MMX MD5 found in md5-mmx.S + * + * This format is now a 'shell'. It simply is used to filter out + * the $H$??????? hashes, and convert them into md5_gen(17)?????? + * and setup and forward the 'work' to the md5_gen to do the 'real' + * work. + * + */ + +#include + +#include "common.h" +#include "formats.h" +#include "md5_gen.h" + +#define FORMAT_LABEL "phpass-md5" +#define FORMAT_NAME "PHPass MD5" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "phpass-MD5 MMX" +#else +#define ALGORITHM_NAME "phpass-MD5 SSE2" +#endif +#else +#define ALGORITHM_NAME "phpass-md5" +#endif + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 64 +#define CIPHERTEXT_LENGTH 34 + +#define BINARY_SIZE 16 +#define SALT_SIZE 8 + +static struct fmt_tests phpassmd5_tests[] = { + {"$H$9aaaaaSXBjgypwqm.JsMssPLiS8YQ00", "test1"}, + {"$H$9PE8jEklgZhgLmZl5.HYJAzfGCQtzi1", "123456"}, + {"$H$9pdx7dbOW3Nnt32sikrjAxYFjX8XoK1", "123456"}, + {"$P$912345678LIjjb6PhecupozNBmDndU0", "thisisalongertestPW"}, + {"$H$9A5she.OeEiU583vYsRXZ5m2XIpI68/", "123456"}, + {"$P$917UOZtDi6ksoFt.y2wUYvgUI6ZXIK/", "test1"}, + {"$P$91234567AQwVI09JXzrV1hEC6MSQ8I0", "thisisalongertest"}, + {"$P$9234560A8hN6sXs5ir0NfozijdqT6f0", "test2"}, + {"$P$9234560A86ySwM77n2VA/Ey35fwkfP0", "test3"}, + {"$P$9234560A8RZBZDBzO5ygETHXeUZX5b1", "test4"}, + {"$P$612345678si5M0DDyPpmRCmcltU/YW/", "JohnRipper"}, // note smaller loop count + {"$H$712345678WhEyvy1YWzT4647jzeOmo0", "JohnRipper"}, // note smaller loop count (phpbb w/older PHP version) + {"$P$B12345678L6Lpt4BxNotVIMILOa9u81", "JohnRipper"}, // note larber loop count (Wordpress) + {"$P$91234567xogA.H64Lkk8Cx8vlWBVzH0", "thisisalongertst"}, + {NULL} +}; + +static char Conv_Buf[80]; + +/* this function converts a 'native' phpass signature string into a md5_gen(17) syntax string */ +static char *Convert(char *Buf, char *ciphertext) +{ + sprintf(Buf, "md5_gen(17)%s%10.10s", &ciphertext[3+8+1], &ciphertext[2]); + return Buf; +} + +static int phpassmd5_valid(char *ciphertext) +{ + int i; + unsigned count_log2; + + if (strlen(ciphertext) != 34) + return 0; + // Handle both the phpass signature, and the phpBB v3 signature (same formula) + // NOTE we are only dealing with the 'portable' encryption method + if (strncmp(ciphertext, "$P$", 3) != 0 && strncmp(ciphertext, "$H$", 3) != 0) + return 0; + for (i = 3; i < 34; ++i) + if (atoi64[ARCH_INDEX(ciphertext[i])] == 0x7F) + return 0; + + count_log2 = atoi64[ARCH_INDEX(ciphertext[3])]; + if (count_log2 < 7 || count_log2 > 31) + return 0; + + return fmt_MD5gen.methods.valid(Convert(Conv_Buf, ciphertext)); +} + +static void * our_salt(char *ciphertext) +{ + return fmt_MD5gen.methods.salt(Convert(Conv_Buf, ciphertext)); +} +static void * our_binary(char *ciphertext) +{ + return fmt_MD5gen.methods.binary(Convert(Conv_Buf, ciphertext)); +} + +static void phpassmd5_init(void); + +struct fmt_main fmt_phpassmd5 = +{ + { + // setup the labeling and stuff. NOTE the max and min crypts are set to 1 + // here, but will be reset within our init() function. + FORMAT_LABEL, FORMAT_NAME, ALGORITHM_NAME, BENCHMARK_COMMENT, BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, BINARY_SIZE, SALT_SIZE+1, 1, 1, FMT_CASE | FMT_8_BIT, phpassmd5_tests + }, + { + /* All we setup here, is the pointer to valid, and the pointer to init */ + /* within the call to init, we will properly set this full object */ + phpassmd5_init, + phpassmd5_valid + } +}; + +static void phpassmd5_init(void) +{ + md5_gen_RESET_LINK(&fmt_phpassmd5, Convert(Conv_Buf, phpassmd5_tests[0].ciphertext), "phpass"); + fmt_phpassmd5.methods.salt = our_salt; + fmt_phpassmd5.methods.binary = our_binary; +} diff -urpN john-1.7.5.orig/src/phpassMD5_fmt_orig.c john-1.7.5/src/phpassMD5_fmt_orig.c --- john-1.7.5.orig/src/phpassMD5_fmt_orig.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/phpassMD5_fmt_orig.c 2009-10-29 05:17:46 +0000 @@ -0,0 +1,485 @@ +/* + * This software was written by Jim Fougeron jfoug AT cox dot net + * in 2009. No copyright is claimed, and the software is hereby + * placed in the public domain. In case this attempt to disclaim + * copyright and place the software in the public domain is deemed + * null and void, then the software is Copyright © 2009 Jim Fougeron + * and it is hereby released to the general public under the following + * terms: + * + * This software may be modified, redistributed, and used for any + * purpose, in source and binary forms, with or without modification. + * + * Cracks phpass 'portable' hashes, and phpBBv3 hashes, which + * are simply phpass portable, with a slightly different signature. + * These are 8 byte salted hashes, with a 1 byte 'salt' that + * defines the number of loops to compute. Internally we work + * with 8 byte salt (the 'real' salt), but let john track it as + * 9 byte salts (the loop count byte is appended to the 'real' + * 8 byte salt value. + * + * code should be pretty fast, and pretty well debugged. Works + * even if there are multiple loop count values in the set of + * hashes. PHPv5 kicked up the default loop number, but it is + * programatically allowed to have different looping counts. + * This format should handle all valid loop values. + * + * uses openSSL's MD5 and SSE2/MMX MD5 found in md5-mmx.S + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "md5.h" + +#define FORMAT_LABEL "phpass-md5" +#define FORMAT_NAME "PHPass MD5" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "phpass-MD5 MMX" +#else +#define ALGORITHM_NAME "phpass-MD5 SSE2" +#endif +#else +#define ALGORITHM_NAME "phpass-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 34 + +#define BINARY_SIZE 16 +#define SALT_SIZE 8 +// NOTE salts are only 8 bytes, but we tell john they are 9. +// We then take the 8 bytes of salt, and append the 1 byte of +// loop count data, making it 9. However, internal to this +// code, we only use the 8 bytes of salt. We do 'use' the loop +// count data to set our counters, whenever we set the salt, but +// it is NOT part of the rest of the salt 'usage'. +// So, $H$9PE8jEklg.... would have a salt of PE8jEklg9 but only +// the PE8jEklg is the 'actual' salt, and we use the '9' to figure +// out the looping. + +#ifdef MMX_COEF +#define MIN_KEYS_PER_CRYPT 1 +#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 phpassmd5_tests[] = { + {"$H$9aaaaaSXBjgypwqm.JsMssPLiS8YQ00","test1"}, + {"$H$9PE8jEklgZhgLmZl5.HYJAzfGCQtzi1", "123456"}, + {"$H$9pdx7dbOW3Nnt32sikrjAxYFjX8XoK1", "123456"}, + {"$P$912345678LIjjb6PhecupozNBmDndU0", "thisisalongertestPW"}, + {"$H$9A5she.OeEiU583vYsRXZ5m2XIpI68/", "123456"}, + {"$P$917UOZtDi6ksoFt.y2wUYvgUI6ZXIK/", "test1"}, + {"$P$91234567AQwVI09JXzrV1hEC6MSQ8I0", "thisisalongertest"}, + {"$P$9234560A8hN6sXs5ir0NfozijdqT6f0", "test2"}, + {"$P$9234560A86ySwM77n2VA/Ey35fwkfP0", "test3"}, + {"$P$9234560A8RZBZDBzO5ygETHXeUZX5b1", "test4"}, + {"$P$91234567xogA.H64Lkk8Cx8vlWBVzH0", "thisisalongertst"}, + {"$P$612345678si5M0DDyPpmRCmcltU/YW/", "JohnRipper"}, // note smaller loop count + {"$H$712345678WhEyvy1YWzT4647jzeOmo0", "JohnRipper"}, // note smaller loop count (phpbb w/older PHP version) + {"$P$B12345678L6Lpt4BxNotVIMILOa9u81", "JohnRipper"}, // note larber loop count (Wordpress) + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define crypt_key phpassmd5_crypt_key +#define cursalt phpassmd5_cursalt +#define dump phpassmd5_dump +char crypt_key[PLAINTEXT_LENGTH*MMX_COEF+1] __attribute__ ((aligned(16))); +unsigned char cursalt[PLAINTEXT_LENGTH*MMX_COEF+1] __attribute__ ((aligned(16))); +unsigned char dump[BINARY_SIZE*MMX_COEF] __attribute__((aligned(16))); +static unsigned keylen[MMX_COEF]; +static unsigned maxkeylen, bNewKeys; +static ARCH_WORD_32 total_len; +static unsigned tot_keys; +static unsigned char EncKey[MMX_COEF][PLAINTEXT_LENGTH + 1]; +#else +static MD5_CTX ctx; +static unsigned char cursalt[SALT_SIZE]; +static char crypt_key[PLAINTEXT_LENGTH+1+BINARY_SIZE]; +static unsigned char EncKey[PLAINTEXT_LENGTH + 1]; +static unsigned EncKeyLen; +#endif +static unsigned loopCnt; +static char out[PLAINTEXT_LENGTH+1]; + +static int valid(char *ciphertext) +{ + int i; + unsigned count_log2; + + if (strlen(ciphertext) != 34) + return 0; + // Handle both the phpass signature, and the phpBB v3 signature (same formula) + // NOTE we are only dealing with the 'portable' encryption method + if (strncmp(ciphertext, "$P$", 3) != 0 && strncmp(ciphertext, "$H$", 3) != 0) + return 0; + for (i = 3; i < 34; ++i) + if (atoi64[ARCH_INDEX(ciphertext[i])] == 0x7F) + return 0; + + count_log2 = atoi64[ARCH_INDEX(ciphertext[3])]; + if (count_log2 < 7 || count_log2 > 31) + return 0; + + return 1; +} + +static void phpassmd5_init(void) { +#ifdef MMX_COEF + memset(cursalt, 0, sizeof(cursalt)); + memset(crypt_key, 0, sizeof(crypt_key)); +#endif +} +static void phpassmd5_set_salt(void *salt) +{ + // compute the loop count for this salt + loopCnt = (1 << (atoi64[ARCH_INDEX(((char*)salt)[8])])); + + // Now, deal with the 8 byte salt 'value' +#ifdef MMX_COEF +#if (MMX_COEF == 4) + // since salt is 8 bytes long, we can use 2 32 bit assignments to + // handle the setting (replicated 4 times), vs 32 8 bit character + // assignments. Same end result, but faster. + ((ARCH_WORD_32 *)cursalt)[0] = ((ARCH_WORD_32 *)salt)[0]; + ((ARCH_WORD_32 *)cursalt)[1] = ((ARCH_WORD_32 *)salt)[0]; + ((ARCH_WORD_32 *)cursalt)[2] = ((ARCH_WORD_32 *)salt)[0]; + ((ARCH_WORD_32 *)cursalt)[3] = ((ARCH_WORD_32 *)salt)[0]; + ((ARCH_WORD_32 *)cursalt)[4] = ((ARCH_WORD_32 *)salt)[1]; + ((ARCH_WORD_32 *)cursalt)[5] = ((ARCH_WORD_32 *)salt)[1]; + ((ARCH_WORD_32 *)cursalt)[6] = ((ARCH_WORD_32 *)salt)[1]; + ((ARCH_WORD_32 *)cursalt)[7] = ((ARCH_WORD_32 *)salt)[1]; +#else + ((ARCH_WORD_32 *)cursalt)[0] = ((ARCH_WORD_32 *)salt)[0]; + ((ARCH_WORD_32 *)cursalt)[1] = ((ARCH_WORD_32 *)salt)[0]; + ((ARCH_WORD_32 *)cursalt)[2] = ((ARCH_WORD_32 *)salt)[1]; + ((ARCH_WORD_32 *)cursalt)[3] = ((ARCH_WORD_32 *)salt)[1]; +#endif // MMX_COEF != 4 +#else // !MMX_COEF + ((ARCH_WORD_32 *)cursalt)[0] = ((ARCH_WORD_32 *)salt)[0]; + ((ARCH_WORD_32 *)cursalt)[1] = ((ARCH_WORD_32 *)salt)[1]; +#endif +} + +static void phpassmd5_set_key(char *key, int index) { + int len; + len = strlen(key); +#ifdef MMX_COEF + int i; + + // the SSE code works up to 55 chars, but we have append PW to 16 byte prior + // md5 hashes, so 39 is max PW size we can do with this SSE phpass code. + if(len > (55-16) ) + len = (55-16); + if (index == 0) + { + tot_keys = total_len = 0; + memset(&cursalt[SALT_SIZE*MMX_COEF], 0, (maxkeylen+4)*MMX_COEF); + memset(&crypt_key[BINARY_SIZE*MMX_COEF], 0, (maxkeylen+4)*MMX_COEF); + maxkeylen = len; + } + else if (len > maxkeylen) + maxkeylen = len; + bNewKeys = 1; + keylen[index] = len; + strncpy(((char*)(EncKey[index])), key, len); + EncKey[index][len] = 0; + i = SALT_SIZE; + int j, wordcnt = (len >> 2); + if (wordcnt) + { + i += (wordcnt << 2); + for (j = 0; j < wordcnt; ++j) + ((ARCH_WORD_32 *)cursalt)[((SALT_SIZE>>2)+j)*MMX_COEF+index] = ((ARCH_WORD_32 *)key)[j]; + } + for(; i < len+SALT_SIZE; ++i) + cursalt[GETPOS(i, index)] = ((unsigned char *)key)[i-SALT_SIZE]; + cursalt[GETPOS(i, index)] = 0x80; + total_len += ( len << ( ( (32/MMX_COEF) * index ) )); + ++tot_keys; +#else + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + EncKeyLen=len; + strcpy(((char*)EncKey), key); +#endif +} + +static char *phpassmd5_get_key(int index) { +#ifdef MMX_COEF + strcpy(out, ((char*)(EncKey[index]))); +#else + strcpy(out, ((char*)EncKey)); +#endif + return (char *) out; +} + +static int phpassmd5_cmp_all(void *binary, int index) { + +#ifdef MMX_COEF +#if (MMX_COEF > 3) + unsigned int i=0; + while(i< (BINARY_SIZE/4) ) + { + if((((ARCH_WORD_32 *)binary)[i] != ((ARCH_WORD_32 *)crypt_key)[i*MMX_COEF]) && + (((ARCH_WORD_32 *)binary)[i] != ((ARCH_WORD_32 *)crypt_key)[i*MMX_COEF+1]) +#if (MMX_COEF > 3) + && + (((ARCH_WORD_32 *)binary)[i] != ((ARCH_WORD_32 *)crypt_key)[i*MMX_COEF+2]) && + (((ARCH_WORD_32 *)binary)[i] != ((ARCH_WORD_32 *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } + return 1; +#endif +#else + int i=0; + while(i 3) + && + (((ARCH_WORD_32 *)binary)[2] == ((ARCH_WORD_32 *)crypt_key)[2*MMX_COEF+index]) && + (((ARCH_WORD_32 *)binary)[3] == ((ARCH_WORD_32 *)crypt_key)[3*MMX_COEF+index]) +#endif + ); +} +#else +#define phpassmd5_cmp_one phpassmd5_cmp_all +#endif + +#ifdef MMX_COEF +static void appendOneKey(int index) { + int i=0; + + int j, wordcnt = (keylen[index] >> 2); + if (wordcnt) + { + ARCH_WORD_32 *dwKey = ((ARCH_WORD_32*)EncKey[index]); + i += (wordcnt << 2); + for (j = 0; j < wordcnt; ++j) + ((ARCH_WORD_32 *)crypt_key)[((BINARY_SIZE>>2)+j)*MMX_COEF+index] = dwKey[j]; + } + for (; i < keylen[index]; ++i) + crypt_key[GETPOS(i+BINARY_SIZE, index)] = EncKey[index][i]; + crypt_key[GETPOS(keylen[index]+BINARY_SIZE, index)] = 0x80; +} +#endif + +static void phpassmd5_crypt_all(int count) { + unsigned Lcount; + +#ifdef MMX_COEF + int i, cur_working_lengths; + + // The first call, is to encrypt the seeds (8 bytes long) with the password + // appened. Thus, we need total_len + 0x08080808 (for sse2), since the + // 8 byte fixed length of the seeds (0x00080008 for MMX, for the 2 seeds) +#if (MMX_COEF > 2) + cur_working_lengths = 0x08080808 + total_len; +#else + cur_working_lengths = 0x80008 + total_len; +#endif + + // Now, encrypt the seed+pw data + mdfivemmx(crypt_key, cursalt, cur_working_lengths); + + // Now setup length for md5hash+password. The md5hash will be overwrittnen + // again and again, within our loop, but the password (and length info) will + // stay static. Huge improvement over doing 2 MD5 calls. Again, add 0x10 + // to the length of the passwords (0x10101010 for SSE2, 0x00100010 for MMX) +#if (MMX_COEF > 2) + cur_working_lengths = 0x10101010 + total_len; +#else + cur_working_lengths = 0x100010 + total_len; +#endif + if (bNewKeys) + { + bNewKeys = 0; + for (i = 0; i < tot_keys; ++i) + appendOneKey(i); + } + + Lcount = loopCnt; + // Now, encrypt the hash+pw data (again and again) NOTE crypt_key is both input + // and output. the md5 hashes will be at the 'base' of this, followed by the + // already stored passwords. + + mdfivemmx( crypt_key, crypt_key, cur_working_lengths); + --Lcount; + do + { + //mdfivemmx( crypt_key, crypt_key, cur_working_lengths); + mdfivemmx_nosizeupdate( crypt_key, crypt_key, cur_working_lengths); + } while (--Lcount); + +#else + MD5_Init( &ctx ); + MD5_Update( &ctx, cursalt, 8 ); + MD5_Update( &ctx, EncKey, EncKeyLen ); + MD5_Final( (unsigned char *) crypt_key, &ctx); + + strcpy(&crypt_key[BINARY_SIZE], ((char*)EncKey)); + Lcount = loopCnt; + + do { + MD5_Init( &ctx ); + MD5_Update( &ctx, crypt_key, BINARY_SIZE+EncKeyLen); + MD5_Final( (unsigned char *) crypt_key, &ctx); + } while (--Lcount); + +#endif +} + +static void * phpassmd5_binary(char *ciphertext) +{ + int i; + unsigned sixbits; + static unsigned char b[16]; + int bidx=0; + char *pos; + + // ugly code, but only called one time (at program load, + // once for each candidate pass hash). + + pos = &ciphertext[3+1+8]; + for (i = 0; i < 5; ++i) + { + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx] = sixbits; + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx++] |= (sixbits<<6); + sixbits >>= 2; + b[bidx] = sixbits; + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx++] |= (sixbits<<4); + sixbits >>= 4; + b[bidx] = sixbits; + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx++] |= (sixbits<<2); + } + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx] = sixbits; + sixbits = atoi64[ARCH_INDEX(*pos++)]; + b[bidx] |= (sixbits<<6); + return b; +} + +static void * phpassmd5_salt(char *ciphertext) +{ + static unsigned char salt[SALT_SIZE+2]; + // store off the 'real' 8 bytes of salt + memcpy(salt, &ciphertext[4], 8); + // append the 1 byte of loop count information. + salt[8] = ciphertext[3]; + salt[9]=0; + return salt; +} + +static int phpassmd5_binary_hash_0(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xf; } +static int phpassmd5_binary_hash_1(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xff; } +static int phpassmd5_binary_hash_2(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xfff; } +static int phpassmd5_binary_hash_3(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xffff; } +static int phpassmd5_binary_hash_4(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xfffff; } + +/* Note, even though in non MMX/SSE code, there is only 1 crypt_key, using */ +/* the typecast and dereference of element [index] works fine, since indes */ +/* will always be 0 (the program knows only 1 element at most is used. Thus */ +/* the same 'simple' function(s) work for SSE and non-SSE get_hash_x() funcs */ +static int phpassmd5_get_hash_0(int index) { return ((ARCH_WORD_32 *)crypt_key)[index] & 0xf; } +static int phpassmd5_get_hash_1(int index) { return ((ARCH_WORD_32 *)crypt_key)[index] & 0xff; } +static int phpassmd5_get_hash_2(int index) { return ((ARCH_WORD_32 *)crypt_key)[index] & 0xfff; } +static int phpassmd5_get_hash_3(int index) { return ((ARCH_WORD_32 *)crypt_key)[index] & 0xffff; } +static int phpassmd5_get_hash_4(int index) { return ((ARCH_WORD_32 *)crypt_key)[index] & 0xfffff; } + +static int phpassmd5_salt_hash(void *salt) +{ + return *((ARCH_WORD *)salt) & 0x3FF; +} + +struct fmt_main fmt_phpassmd5 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + // only true salt of SALT_SIZE (8), but we store on 'extra' byte + // as a salt, since we need it AND it does act as a different salt + // byte. However, when we use the salt in our crypting, we only + // use the SALT_SIZE bytes. + SALT_SIZE+1, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + phpassmd5_tests + }, { + phpassmd5_init, + valid, + fmt_default_split, + phpassmd5_binary, + phpassmd5_salt, + { + phpassmd5_binary_hash_0, + phpassmd5_binary_hash_1, + phpassmd5_binary_hash_2, + phpassmd5_binary_hash_3, + phpassmd5_binary_hash_4 + }, + phpassmd5_salt_hash, + phpassmd5_set_salt, + phpassmd5_set_key, + phpassmd5_get_key, + fmt_default_clear_keys, + phpassmd5_crypt_all, + { + phpassmd5_get_hash_0, + phpassmd5_get_hash_1, + phpassmd5_get_hash_2, + phpassmd5_get_hash_3, + phpassmd5_get_hash_4 + }, + phpassmd5_cmp_all, + phpassmd5_cmp_one, + phpassmd5_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/pixMD5_fmt.c john-1.7.5/src/pixMD5_fmt.c --- john-1.7.5.orig/src/pixMD5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/pixMD5_fmt.c 2010-02-02 02:14:16 +0000 @@ -0,0 +1,284 @@ +/* + * 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[] = { + {"2KFQnbNIdI.2KYOU", "cisco"}, + {"TRPEas6f/aa6JSPL", "test1"}, + {"OMT6mXmAvGyzrCtp", "test2"}, + {"gTC7RIy1XJzagmLm", "test3"}, + {"oWC1WRwqlBlbpf/O", "test4"}, + {"NuLKvvWGg.x9HEKO", "password"}, + {"8Ry2YjIyt7RRXU24", ""}, + {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])] == 0x7F) + return 0; + return 1; +} + +static void pixmd5_set_salt(void *salt) { } + +static void pixmd5_init(void) +{ +#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, + NULL, + NULL + }, + 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, + NULL, + NULL + }, + pixmd5_cmp_all, + pixmd5_cmp_one, + pixmd5_cmp_exact + } +}; diff -urpN john-1.7.5.orig/src/rawMD5go_fmt.c john-1.7.5/src/rawMD5go_fmt.c --- john-1.7.5.orig/src/rawMD5go_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/rawMD5go_fmt.c 2009-10-29 04:52:37 +0000 @@ -0,0 +1,383 @@ +/* + * 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) + * + * Added in SSE2 (and MMX) support from md5-mmx.S by + * Jim Fougeron - jfoug at cox dot net + * (1.5 to 3.5x faster, depending upon core type). + * Done in blocks of 64 hashs per 'run' (to avoid + * fseek() slowdown issues in wordlist.c code + * + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" + +#ifdef MMX_COEF +#include "md5.h" +#else +#if ARCH_LITTLE_ENDIAN +#define MD5_out MD5_out_eq +#else +#define MD5_out MD5_bitswapped_out_eq +#endif +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); +#endif + +#define FORMAT_LABEL "raw-md5" +#define FORMAT_NAME "Raw MD5" +#ifdef MMX_COEF +#if (MMX_COEF == 2) +#define ALGORITHM_NAME "raw-md5 MMX 32x2" +#else +#define ALGORITHM_NAME "raw-md5 SSE2 16x4" +#endif +#else +#define ALGORITHM_NAME "raw-md5 64x1" +#endif + +#ifdef MMX_TYPE +#define BENCHMARK_COMMENT MMX_TYPE +#else +#define BENCHMARK_COMMENT "" +#endif +#define BENCHMARK_LENGTH -1 + +#ifdef MMX_COEF +#define PLAINTEXT_LENGTH 53 +#else +// NOTE, when we use 'generic' md5 to do this, we can process up to +// 96 byte passwords. However, in the 'native' mode, 53 byte is max :( +#define PLAINTEXT_LENGTH 53 +#endif +#define CIPHERTEXT_LENGTH 32 + +#define BINARY_SIZE 16 +#define SALT_SIZE 0 + +#ifdef MMX_COEF +#if MMX_COEF==2 +#define BLOCK_LOOPS 32 +#else +#define BLOCK_LOOPS 16 +#endif +#define MIN_KEYS_PER_CRYPT MMX_COEF*BLOCK_LOOPS +#define MAX_KEYS_PER_CRYPT MMX_COEF*BLOCK_LOOPS +#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 64 +extern ARCH_WORD_32 MD5_out[MAX_KEYS_PER_CRYPT]; +extern char MD5_tmp[MAX_KEYS_PER_CRYPT][CIPHERTEXT_LENGTH + 1]; +#endif + +static struct fmt_tests rawmd5_tests[] = { + {"5a105e8b9d40e1329780d62ea2265d8a", "test1"}, + {"ad0234829205b9033196ba818f7a872b", "test2"}, + {"8ad8757baa8564dc136c1e07507f4a98", "test3"}, + {"86985e105f79b95d6bc918fb45ec7727", "test4"}, + {"378e2c4a07968da2eca692320136433d", "thatsworking"}, + {NULL} +}; + +#ifdef MMX_COEF +/* Cygwin would not guarantee the alignment if these were declared static */ +#define saved_key rawMD5_saved_key +#define crypt_key rawMD5_crypt_key +unsigned char saved_key[BLOCK_LOOPS][64*MMX_COEF] __attribute__ ((aligned(16))); +unsigned char crypt_key[BLOCK_LOOPS][BINARY_SIZE*MMX_COEF] __attribute__ ((aligned(16))); +static unsigned long total_len[BLOCK_LOOPS]; +static char out[64 + 1]; +#else +static unsigned char saved_key[MAX_KEYS_PER_CRYPT][PLAINTEXT_LENGTH + 1 + 128 /* MD5 scratch space */]; +static unsigned int saved_key_len[MAX_KEYS_PER_CRYPT]; +#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')) )) + return 0; + } + return 1; +} + +static void rawmd5_init(void) { } +static void rawmd5_set_salt(void *salt) { } + +static void rawmd5_set_key(char *key, int index) +{ +#ifdef MMX_COEF + unsigned int i, len, cnt; + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + ARCH_WORD_32 *pi = (ARCH_WORD_32 *)key; + ARCH_WORD_32 *po = &((ARCH_WORD_32 *)(&(saved_key[idx])))[index&(MMX_COEF-1)]; + len = strlen(key); + if(index==0) + { + memset(saved_key, 0, sizeof(saved_key)); + memset(total_len, 0, sizeof(total_len)); + } + + cnt = len>>2; + for (i = 0; i < cnt; ++i) + { + *po = *pi++; + po += MMX_COEF; + } + for(i=cnt<<2;i>(MMX_COEF>>1)); + + s = (total_len[idx] >> (((32/MMX_COEF)*(index&(MMX_COEF-1))))) & 0xff; + for(i=0;i>(MMX_COEF>>1)); + for (j = 0; j < cnt; ++j) + { + int SomethingGood = 1; + i = 0; + while(i < (BINARY_SIZE/4) ) + { + if ( + ( ((unsigned long *)binary)[i] != ((unsigned long *)&(crypt_key[j]))[i*MMX_COEF]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)&(crypt_key[j]))[i*MMX_COEF+1]) +#if (MMX_COEF > 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)&(crypt_key[j]))[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)&(crypt_key[j]))[i*MMX_COEF+3]) +#endif + ) + { + SomethingGood = 0; + break; + } + ++i; + } + if (SomethingGood) + return 1; + } + return 0; +#else + unsigned int i; + + for (i = 0; i < count; i++) { + if (!(*((unsigned int*)binary) - *((unsigned int*)&MD5_out[i]))) + return 1; + } + + return 0; +#endif +} + +static int rawmd5_cmp_one(void *binary, int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return((((ARCH_WORD_32 *)binary)[0] == ((ARCH_WORD_32 *)&(crypt_key[idx]))[0*MMX_COEF+(index&(MMX_COEF-1))]) && + (((ARCH_WORD_32 *)binary)[1] == ((ARCH_WORD_32 *)&(crypt_key[idx]))[1*MMX_COEF+(index&(MMX_COEF-1))]) +#if (MMX_COEF > 3) + && + (((ARCH_WORD_32 *)binary)[2] == ((ARCH_WORD_32 *)&(crypt_key[idx]))[2*MMX_COEF+(index&(MMX_COEF-1))]) && + (((ARCH_WORD_32 *)binary)[3] == ((ARCH_WORD_32 *)&(crypt_key[idx]))[3*MMX_COEF+(index&(MMX_COEF-1))]) +#endif + ); +#else + return (!(*((unsigned int*)binary) - (unsigned int)MD5_out[index])); +#endif +} + +static int rawmd5_cmp_exact(char *source, int index) +{ +#ifdef MMX_COEF + return 1; +#else + MD5_Go2_eq((unsigned char *)saved_key[index], saved_key_len[index], index); + return !memcmp(source, MD5_tmp[index], CIPHERTEXT_LENGTH); +#endif +} + +static void rawmd5_crypt_all(int count) { + // get plaintext input in saved_key put it into ciphertext crypt_key +#ifdef MMX_COEF + unsigned int cnt = ( ((unsigned)count+MMX_COEF-1)>>(MMX_COEF>>1)); + unsigned i; + for (i = 0; i < cnt; ++i) + mdfivemmx((unsigned char*)&(crypt_key[i]), (unsigned char*)&(saved_key[i]), total_len[i]); +#else + unsigned int i; + + for (i = 0; i < count; i++) + MD5_Go_eq((unsigned char *)saved_key[i], saved_key_len[i], i); +#endif +} + +static int rawmd5_binary_hash_0(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xf; } +static int rawmd5_binary_hash_1(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xff; } +static int rawmd5_binary_hash_2(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xfff; } +static int rawmd5_binary_hash_3(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xffff; } +static int rawmd5_binary_hash_4(void * binary) { return ((ARCH_WORD_32 *)binary)[0] & 0xfffff; } + +int rawmd5_get_hash_0(int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xf; +#else + return MD5_out[index] & 0xF; +#endif +} + +int rawmd5_get_hash_1(int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xff; +#else + return MD5_out[index] & 0xFF; +#endif +} + +int rawmd5_get_hash_2(int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xfff; +#else + return MD5_out[index] & 0xFFF; +#endif +} + +int rawmd5_get_hash_3(int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xffff; +#else + return MD5_out[index] & 0xFFFF; +#endif +} +int rawmd5_get_hash_4(int index) +{ +#ifdef MMX_COEF + unsigned int idx = ( ((unsigned)index)>>(MMX_COEF>>1)); + return ((ARCH_WORD_32 *)&(crypt_key[idx]))[index&(MMX_COEF-1)] & 0xfffff; +#else + return MD5_out[index] & 0xFFFFF; +#endif +} + + +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 +#if !defined (_MSC_VER) #include +#include +#else +#include +#pragma warning ( disable : 4996 ) +#endif #include #include #include -#include #include #include @@ -83,7 +88,7 @@ void rec_init(struct db_main *db, void ( void rec_save(void) { - int save_format; + int save_format, hund; long size; char **opt; @@ -92,7 +97,9 @@ void rec_save(void) if (!rec_file) return; if (fseek(rec_file, 0, SEEK_SET)) pexit("fseek"); -#ifdef __CYGWIN32__ +#if defined (_MSC_VER) + if (_write(fileno(rec_file), "", 0)) pexit("ftruncate"); +#elif defined (__CYGWIN32__) if (ftruncate(rec_fd, 0)) pexit("ftruncate"); #endif @@ -115,7 +122,7 @@ void rec_save(void) status.crypts.lo, status.crypts.hi, status.pass, - status_get_progress ? status_get_progress() : -1, + status_get_progress ? status_get_progress(&hund) : -1, rec_check); if (rec_save_mode) rec_save_mode(rec_file); @@ -124,8 +131,10 @@ void rec_save(void) if ((size = ftell(rec_file)) < 0) pexit("ftell"); if (fflush(rec_file)) pexit("fflush"); +#if !defined (_MSC_VER) if (ftruncate(rec_fd, size)) pexit("ftruncate"); -#ifndef __CYGWIN32__ +#endif +#if !defined(__CYGWIN32__) && !defined(__MINGW32__) && !defined (_MSC_VER) if (fsync(rec_fd)) pexit("fsync"); #endif } diff -urpN john-1.7.5.orig/src/rules.c john-1.7.5/src/rules.c --- john-1.7.5.orig/src/rules.c 2010-01-03 22:37:46 +0000 +++ john-1.7.5/src/rules.c 2010-02-26 01:03:44 +0000 @@ -544,6 +544,7 @@ char *rules_apply(char *word, char *rule { int pos; CLASS_export_pos(0, break, {}) + rules_vars['p'] = pos; if (in[pos]) break; } REJECT @@ -621,10 +622,12 @@ char *rules_apply(char *word, char *rule case '%': { - int count = 0, required; + int count = 0, required, pos; POSITION(required) - CLASS(0, if (++count >= required) break, {}) + CLASS_export_pos(0, + if (++count >= required) break, {}) if (count < required) REJECT + rules_vars['p'] = pos; } break; diff -urpN john-1.7.5.orig/src/sapB_fmt.c john-1.7.5/src/sapB_fmt.c --- john-1.7.5.orig/src/sapB_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/sapB_fmt.c 2009-09-22 21:03:43 +0000 @@ -0,0 +1,305 @@ +/* + * this is a SAP-BCODE plugin for john the ripper. + * tested on linux/x86 only, rest is up to you.. at least, someone did the reversing :-) + * + * please note: this code is in a "works for me"-state, feel free to modify/speed up/clean/whatever it... + * + * (c) x7d8 sap loverz, public domain, btw + * cheers: see test-cases. + */ + +/* char transition table for BCODE (from disp+work) */ +#define TRANSTABLE_LENGTH 16*16 +unsigned char transtable[TRANSTABLE_LENGTH]= +{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x3F, 0x40, 0x41, 0x50, 0x43, 0x44, 0x45, 0x4B, 0x47, 0x48, 0x4D, 0x4E, 0x54, 0x51, 0x53, 0x46, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x56, 0x55, 0x5C, 0x49, 0x5D, 0x4A, + 0x42, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x58, 0x5B, 0x59, 0xFF, 0x52, + 0x4C, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x57, 0x5E, 0x5A, 0x4F, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + +#define BCODE_ARRAY_LENGTH 3*16 +char bcodeArr[BCODE_ARRAY_LENGTH]= +{0x14,0x77,0xF3,0xD4,0xBB,0x71,0x23,0xD0,0x03,0xFF,0x47,0x93,0x55,0xAA,0x66,0x91, +0xF2,0x88,0x6B,0x99,0xBF,0xCB,0x32,0x1A,0x19,0xD9,0xA7,0x82,0x22,0x49,0xA2,0x51, +0xE2,0xB7,0x33,0x71,0x8B,0x9F,0x5D,0x01,0x44,0x70,0xAE,0x11,0xEF,0x28,0xF0,0x0D}; + + +#include +#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) +{ + int i; + if (NULL==theSalt) + return 0; + 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; + unsigned int sum20; + int I1, I2; + int revI1; + int I3; + int strlenUN, strlenPW; + char destArray[TEMP_ARRAY_SIZE]; + int I4; + + //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) +{ + int i; + if (NULL==theSalt) + return 0; + 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.5.orig/src/sha1-mmx.S john-1.7.5/src/sha1-mmx.S --- john-1.7.5.orig/src/sha1-mmx.S 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/signals.c john-1.7.5/src/signals.c --- john-1.7.5.orig/src/signals.c 2006-02-27 09:58:30 +0000 +++ john-1.7.5/src/signals.c 2009-12-27 17:38:21 +0000 @@ -3,6 +3,12 @@ * Copyright (c) 1996-2003,2006 by Solar Designer */ +#if defined (__MINGW32__) || defined (_MSC_VER) +#define __CYGWIN32__ +#define SIGALRM SIGFPE +#define SIGHUP SIGILL +#endif + #ifdef __ultrix__ #define __POSIX #define _POSIX_SOURCE @@ -12,11 +18,13 @@ #include #endif #include +#if !defined (_MSC_VER) +#include #include +#endif #include #include #include -#include #include #ifdef __DJGPP__ @@ -44,7 +52,9 @@ static clock_t timer_ticksafety_interval #if !OS_TIMER #include +#if !defined (__MINGW32__) && !defined (_MSC_VER) #include +#endif static clock_t timer_emu_interval = 0; static unsigned int timer_emu_count = 0, timer_emu_max = 0; @@ -59,11 +69,17 @@ void sig_timer_emu_tick(void) { static clock_t last = 0; clock_t current; +#if !defined (__MINGW32__) && !defined (_MSC_VER) struct tms buf; +#endif if (++timer_emu_count < timer_emu_max) return; +#if defined (__MINGW32__) || defined (_MSC_VER) + current = clock(); +#else current = times(&buf); +#endif if (!last) { last = current; @@ -145,12 +161,20 @@ static void sig_handle_abort(int signum) } #ifdef __CYGWIN32__ +#if defined (_MSC_VER) +static BOOL WINAPI sig_handle_abort_ctrl(DWORD ctrltype) +{ + sig_handle_abort(SIGINT); + return TRUE; +} +#else static CALLBACK BOOL sig_handle_abort_ctrl(DWORD ctrltype) { sig_handle_abort(SIGINT); return TRUE; } #endif +#endif static void sig_install_abort(void) { diff -urpN john-1.7.5.orig/src/signals.h john-1.7.5/src/signals.h --- john-1.7.5.orig/src/signals.h 2006-02-27 06:28:54 +0000 +++ john-1.7.5/src/signals.h 2009-12-27 17:38:21 +0000 @@ -29,7 +29,11 @@ extern volatile int event_ticksafety; /* /* * Timer emulation for systems with no setitimer(2). */ +#if defined (__MINGW32__) || defined (_MSC_VER) +#include +#else #include +#endif extern void sig_timer_emu_init(clock_t interval); extern void sig_timer_emu_tick(void); diff -urpN john-1.7.5.orig/src/single.c john-1.7.5/src/single.c --- john-1.7.5.orig/src/single.c 2010-01-18 06:17:13 +0000 +++ john-1.7.5/src/single.c 2010-01-19 05:40:58 +0000 @@ -49,10 +49,19 @@ static int restore_state(FILE *file) return restore_rule_number(); } -static int get_progress(void) +static int get_progress(int *hundth) { if (progress) return progress; + if (hundth) + { + int i; + double d = rule_number; + d /= (rule_count+1); + d *= 100; + i = (int)d; + *hundth = i % 100; + } return rule_number * 100 / (rule_count + 1); } @@ -87,7 +96,7 @@ static void single_init(void) key_count = single_db->format->params.min_keys_per_crypt; if (key_count < SINGLE_HASH_MIN) key_count = SINGLE_HASH_MIN; - if (rpp_init(rule_ctx, SUBSECTION_SINGLE)) { + if (rpp_init(rule_ctx, single_db->options->activesinglerules)) { log_event("! No \"single crack\" mode rules found"); fprintf(stderr, "No \"single crack\" mode rules found in %s\n", cfg_name); diff -urpN john-1.7.5.orig/src/smbencrypt.c john-1.7.5/src/smbencrypt.c --- john-1.7.5.orig/src/smbencrypt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/stages_mmx_md5.S john-1.7.5/src/stages_mmx_md5.S --- john-1.7.5.orig/src/stages_mmx_md5.S 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/stages_sse2_md5.S john-1.7.5/src/stages_sse2_md5.S --- john-1.7.5.orig/src/stages_sse2_md5.S 1970-01-01 00:00:00 +0000 +++ john-1.7.5/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.5.orig/src/status.c john-1.7.5/src/status.c --- john-1.7.5.orig/src/status.c 2010-01-17 14:27:19 +0000 +++ john-1.7.5/src/status.c 2010-01-19 05:40:58 +0000 @@ -12,9 +12,14 @@ #include #endif #include +#include +#include +#include #include #include +#if !defined (__MINGW32__) && !defined (_MSC_VER) #include +#endif #include "times.h" @@ -28,16 +33,20 @@ struct status_main status; unsigned int status_restored_time = 0; -int (*status_get_progress)(void) = NULL; +int (*status_get_progress)(int *) = NULL; static clock_t get_time(void) { +#if defined (__MINGW32__) || defined (_MSC_VER) + return clock(); +#else struct tms buf; return times(&buf); +#endif } -void status_init(int (*get_progress)(void), int start) +void status_init(int (*get_progress)(int *), int start) { if (start) { if (!status_restored_time) @@ -120,6 +129,76 @@ static char *status_get_cps(char *buffer return buffer; } +static char *status_get_ETA(char *percent, unsigned int secs_done) +{ + static char s_ETA[128]; + char *cp; + double sec_left, percent_left; + time_t t_ETA; + struct tm *pTm; + +#if CPU_REQ && defined(__i386__) +/* ETA reporting would be wrong when cracking some hash types at least on a + * Pentium 3 without this... */ + __asm__ __volatile__("emms"); +#endif + + /* Compute the ETA for this run. Assumes even run time for + work currently done and work left to do, and that the CPU + utilization of work done and work to do will stay same + which may not always a valid assumtions */ + cp = percent; + while (cp && *cp && isspace(*cp)) + ++cp; + if (!cp || *cp == 0 || !isdigit(*cp)) + return ""; /* dont show ETA if no valid percentage. */ + else + { + percent_left = atof(percent); + if (percent_left == 0) + percent_left = .005; + percent_left /= 100; + sec_left = secs_done; + sec_left /= percent_left; + sec_left -= secs_done; + t_ETA = time(NULL); + { + /* Note, many localtime() will fault if given a time_t + later than Jan 19, 2038 (i.e. 0x7FFFFFFFF). We + check for that here, and if so, this run will + not end anyway, so simply tell user it is a + LONG wait */ + double chk; + chk = sec_left; + chk += t_ETA; + if (chk > 0x7FFFF000) /* slightly less than 'max' 32 bit time_t, for safety */ + { + strcpy(s_ETA, " (ETA: MANY years)"); + return s_ETA; + } + } + t_ETA += sec_left; + pTm = localtime(&t_ETA); + /* the string to strftime, might be a GOOD addition + to john.conf in the 'global' section. for now, simply + use the %c 'local' specific canonical form, such as: + 07/15/09 15:19:07 + also good would be %#c which is long 'local' such as: + Wednesday, July 15, 2009, 15:41:29 + Other 'good' ones are: + %d/%m/%y %H:%M (day/mon/year hour:min) + %m/%d/%y %H:%M (mon/day/year hour:min) + + NOTE the ETA will float around quite a bit. The seconds + and even minutes are pretty much worthless information + until a significant part of the data is done (say 20%) */ + strcpy(s_ETA, " (ETA: "); + strftime(&s_ETA[7], sizeof(s_ETA)-10, "%c", pTm); + strcat(s_ETA, ")"); + } + return s_ETA; +} + static void status_print_stdout(char *percent) { unsigned int time = status_get_time(); @@ -146,11 +225,12 @@ static void status_print_stdout(char *pe fprintf(stderr, "words: %s " "time: %u:%02u:%02u:%02u" - "%s " + "%s%s " "w/s: %s", s_words_ptr, time / 86400, time % 86400 / 3600, time % 3600 / 60, time % 60, percent, + status_get_ETA(percent, time), status_get_cps(s_wps)); if ((options.flags & FLG_STATUS_CHK) || @@ -178,11 +258,12 @@ static void status_print_cracking(char * fprintf(stderr, "guesses: %u " "time: %u:%02u:%02u:%02u" - "%s " + "%s%s " "c/s: %s", status.guess_count, time / 86400, time % 86400 / 3600, time % 3600 / 60, time % 60, percent, + status_get_ETA(percent,time), status_get_cps(s_cps)); if ((options.flags & FLG_STATUS_CHK) || @@ -196,7 +277,7 @@ static void status_print_cracking(char * void status_print(void) { - int percent_value; + int percent_value, hund_percent; char s_percent[32]; percent_value = -1; @@ -204,12 +285,12 @@ void status_print(void) percent_value = status.progress; else if (status_get_progress) - percent_value = status_get_progress(); + percent_value = status_get_progress(&hund_percent); s_percent[0] = 0; - if (percent_value >= 0) - sprintf(s_percent, status.pass ? " %d%% (%d)" : " %d%%", - percent_value, status.pass); + if (percent_value >= 0 && hund_percent >= 0) + sprintf(s_percent, status.pass ? " %d.%02d%% (%d)" : " %d.%02d%%", + percent_value, hund_percent, status.pass); else if (status.pass) sprintf(s_percent, " (%d)", status.pass); diff -urpN john-1.7.5.orig/src/status.h john-1.7.5/src/status.h --- john-1.7.5.orig/src/status.h 2006-02-27 06:28:54 +0000 +++ john-1.7.5/src/status.h 2009-12-27 17:38:21 +0000 @@ -27,7 +27,7 @@ struct status_main { extern struct status_main status; -extern int (*status_get_progress)(void); +extern int (*status_get_progress)(int *hundth); /* * Elapsed time of previous sessions and excess ticks (if any), in seconds. @@ -39,7 +39,7 @@ extern unsigned int status_restored_time * fields to zero. Always initializes the get_progress() handler (can be * NULL). */ -extern void status_init(int (*get_progress)(void), int start); +extern void status_init(int (*get_progress)(int*), int start); /* * Checks the number of ticks elapsed since start_time and moves some excess diff -urpN john-1.7.5.orig/src/symlink.c john-1.7.5/src/symlink.c --- john-1.7.5.orig/src/symlink.c 2002-04-10 14:13:25 +0000 +++ john-1.7.5/src/symlink.c 2009-12-27 17:38:21 +0000 @@ -14,7 +14,13 @@ int main(int argc, char **argv) { +#if !defined (_MSC_VER) char path[strlen(argv[0] ? argv[0] : "") + sizeof(MAIN_NAME)]; +#else +#pragma warning ( disable : 4996 ) + char path[4096]; +#endif + char *name; if (!argv[0]) diff -urpN john-1.7.5.orig/src/tty.c john-1.7.5/src/tty.c --- john-1.7.5.orig/src/tty.c 2003-09-06 20:28:22 +0000 +++ john-1.7.5/src/tty.c 2009-07-03 20:22:20 +0000 @@ -3,12 +3,17 @@ * Copyright (c) 1996-99,2003 by Solar Designer */ +#if defined (__MINGW32__) || defined (_MSC_VER) +#include +#else #ifndef __DJGPP__ #include #include #include +#if !defined (_MSC_VER) #include #include +#endif #include #else #include @@ -26,17 +31,18 @@ extern int tcgetattr(int fd, struct term extern int tcsetattr(int fd, int actions, struct termios *termios_p); #endif #endif +#endif /* !defined __MINGW32__ */ #include "tty.h" -#ifndef __DJGPP__ +#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined (_MSC_VER) static int tty_fd = -1; static struct termios saved_ti; #endif void tty_init(void) { -#ifndef __DJGPP__ +#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined (_MSC_VER) int fd; struct termios ti; @@ -65,7 +71,7 @@ void tty_init(void) int tty_getchar(void) { -#ifndef __DJGPP__ +#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined (_MSC_VER) int c; #ifdef __CYGWIN32__ fd_set set; @@ -82,9 +88,12 @@ int tty_getchar(void) c = 0; if (read(tty_fd, &c, 1) > 0) return c; } -#else +#elif defined(__DJGPP__) if (_bios_keybrd(_KEYBRD_READY)) return _bios_keybrd(_KEYBRD_READ); +#else /* defined(__MINGW32__) or _MSC_VER */ + if (_kbhit()) + return _getch(); #endif return -1; @@ -92,7 +101,7 @@ int tty_getchar(void) void tty_done(void) { -#ifndef __DJGPP__ +#if !defined(__DJGPP__) && !defined(__MINGW32__) && !defined (_MSC_VER) int fd; if (tty_fd < 0) return; diff -urpN john-1.7.5.orig/src/undrop.c john-1.7.5/src/undrop.c --- john-1.7.5.orig/src/undrop.c 1970-01-01 00:00:00 +0000 +++ john-1.7.5/src/undrop.c 2009-07-03 20:20:44 +0000 @@ -0,0 +1,75 @@ +/* + * 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 +#if !defined (_MSC_VER) +#include +#endif + + +#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.5.orig/src/unique.c john-1.7.5/src/unique.c --- john-1.7.5.orig/src/unique.c 2006-01-09 14:34:50 +0000 +++ john-1.7.5/src/unique.c 2009-12-27 17:38:21 +0000 @@ -8,6 +8,11 @@ #include #include #include +#if defined (_MSC_VER) +#include +#pragma warning ( disable : 4996 ) +#define fdopen _fdopen +#endif #include "arch.h" #include "misc.h" @@ -178,9 +183,14 @@ static void unique_init(char *name) buffer.hash = mem_alloc(UNIQUE_HASH_SIZE * sizeof(unsigned int)); buffer.data = mem_alloc(UNIQUE_BUFFER_SIZE); - if ((fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) +#if defined (_MSC_VER) || defined(__MINGW32__) + fd = open(name, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600); +#else + fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600); +#endif + if (fd < 0) pexit("open: %s", name); - if (!(output = fdopen(fd, "w+"))) pexit("fdopen"); + if (!(output = fdopen(fd, "wb+"))) pexit("fdopen"); } static void unique_run(void) diff -urpN john-1.7.5.orig/src/unshadow.c john-1.7.5/src/unshadow.c --- john-1.7.5.orig/src/unshadow.c 2006-01-09 14:34:50 +0000 +++ john-1.7.5/src/unshadow.c 2009-12-27 17:38:21 +0000 @@ -28,15 +28,14 @@ static void alloc_hash(void) static int login_hash(char *login) { - int hash = 0; + int hash = 0, i=0; while (*login) { - hash <<= 1; + hash <<= 2; hash ^= *login++; + hash += (hash >> (i%25)); + ++i; } - - hash ^= hash >> SHADOW_HASH_LOG; - hash ^= hash >> (2 * SHADOW_HASH_LOG); hash &= SHADOW_HASH_SIZE - 1; return hash; diff -urpN john-1.7.5.orig/src/wordlist.c john-1.7.5/src/wordlist.c --- john-1.7.5.orig/src/wordlist.c 2009-12-28 19:28:07 +0000 +++ john-1.7.5/src/wordlist.c 2010-03-02 16:37:24 +0000 @@ -1,13 +1,20 @@ /* * This file is part of John the Ripper password cracker, * Copyright (c) 1996-99,2003,2004,2006,2009 by Solar Designer + * + * Heavily modified by JimF and maybe by others. */ #include #include +#if !defined (_MSC_VER) #include +#else +#pragma warning ( disable : 4996 ) +#endif #include +#include "arch.h" #include "misc.h" #include "math.h" #include "params.h" @@ -22,9 +29,10 @@ #include "rules.h" #include "external.h" #include "cracker.h" +#include "memory.h" static FILE *word_file = NULL; -static int progress = 0; +static int progress = 0, hund_progress = 0; static int rec_rule; static long rec_pos; @@ -33,6 +41,11 @@ static int rule_number, rule_count, line static int length; static struct rpp_context *rule_ctx; +// used for file in 'memory map' mode +static char *word_file_str, **words; +static unsigned int nWordFileLines, nCurLine; +static struct db_main *_db; + static void save_state(FILE *file) { fprintf(file, "%d\n%ld\n", rec_rule, rec_pos); @@ -70,14 +83,33 @@ static int restore_state(FILE *file) if (word_file == stdin) restore_line_number(); - else - if (fseek(word_file, rec_pos, SEEK_SET)) pexit("fseek"); + else { + if (nWordFileLines) { + for (nCurLine = 0; nCurLine < nWordFileLines; ++nCurLine) { + if (words[nCurLine] - words[0] >= rec_pos) + break; + } + } + else + if (fseek(word_file, rec_pos, SEEK_SET)) pexit("fseek"); + } return 0; } +static int fix_state_delay; + static void fix_state(void) { + if (nWordFileLines) { + rec_rule = rule_number; + rec_pos = words[nCurLine] - words[0]; + return; + } + if (++fix_state_delay < _db->options->max_fix_state_delay) + return; + fix_state_delay=0; + rec_rule = rule_number; if (word_file == stdin) @@ -93,31 +125,47 @@ static void fix_state(void) } } -static int get_progress(void) +static int get_progress(int *hundth_perc) { struct stat file_stat; long pos; - int64 x100; + int hundredXpercent, percent; + double x100, tmp; - if (!word_file) return progress; + if (!word_file) { + *hundth_perc = hund_progress; + return progress; + } - if (word_file == stdin) return -1; + if (word_file == stdin) { + *hundth_perc = 0; + return -1; + } if (fstat(fileno(word_file), &file_stat)) pexit("fstat"); - - if ((pos = ftell(word_file)) < 0) { + if (nWordFileLines) { + pos = rec_pos; + } + else { + if ((pos = ftell(word_file)) < 0) { #ifdef __DJGPP__ - if (pos != -1) - pos = 0; - else + if (pos != -1) + pos = 0; + else #endif - pexit("ftell"); + pexit("ftell"); + } } - mul32by32(&x100, pos, 100); - return - (rule_number * 100 + - div64by32lo(&x100, file_stat.st_size + 1)) / rule_count; + x100 = ((double)pos) * 10000.; + // a double 'tmp' var is required, as I have seen the compiler + // optimize away the next statement if assigned to an int + tmp = (((double)rule_number)*10000. + x100/(file_stat.st_size+1)) / rule_count; + // safe int assignment. tmp will be from 0 to 10000.00 + hundredXpercent = (int)tmp; + percent = hundredXpercent / 100; + *hundth_perc = hundredXpercent - (percent*100); + return percent; } static char *dummy_rules_apply(char *word, char *rule, int split, char *last) @@ -138,13 +186,80 @@ void do_wordlist_crack(struct db_main *d struct rpp_context ctx; char *prerule, *rule, *word; char *(*apply)(char *word, char *rule, int split, char *last); + long file_len; + int i; log_event("Proceeding with wordlist mode"); + _db = db; + if (name) { - if (!(word_file = fopen(path_expand(name), "r"))) + char *cp, csearch; + + if (!(word_file = fopen(path_expand(name), "rb"))) pexit("fopen: %s", path_expand(name)); log_event("- Wordlist file: %.100s", path_expand(name)); + + /* this will both get us the file length, and tell us + of 'invalid' files (i.e. too big in Win32 or other + 32 bit OS's. A file between 2gb and 4gb returns + a negative number. NOTE john craps out on files + this big. The file needs cut before running through + through john */ + fseek(word_file, 0, SEEK_END); + file_len = ftell(word_file); + fseek(word_file, 0, SEEK_SET); + if (file_len < 0) + { + fprintf(stderr, "Error, dictionary file is too large for john to read (probably a 32 bit OS issue)\n"); + error(); + } + /* If the file is < max_wordfile_memory, then we work from a memory map of the file */ + if (file_len < db->options->max_wordfile_memory) + { + /* probably should only be debug message, but I left it in */ + log_event("loading wordfile %s into memory (%lu bytes, max_size=%u)\n", name, file_len, db->options->max_wordfile_memory); +/* XXX: would need to alloc more for dummy_rules_apply()'s "blind truncation" */ + word_file_str = mem_alloc(file_len+1); + if (fread(word_file_str, 1, file_len, word_file) != file_len) { + if (ferror(word_file)) + pexit("fread"); + fprintf(stderr, "fread: Unexpected EOF\n"); + error(); + } + word_file_str[file_len] = 0; + csearch = '\n'; + cp = strchr(word_file_str, csearch); + if (!cp) + { + csearch = '\r'; + cp = strchr(word_file_str, csearch); + } + for (nWordFileLines = 1; cp; ++nWordFileLines) + cp = strchr(&cp[1], csearch); + words = mem_alloc(nWordFileLines * sizeof(char*)); + log_event("wordfile had %u lines and required %lu bytes for index.\n", nWordFileLines, (unsigned long)(nWordFileLines * sizeof(char*))); + + i = 0; + cp = word_file_str; + do + { + char *ep = cp, ec; + while (*ep && *ep != '\n' && *ep != '\r') ep++; + ec = *ep; + *ep = 0; + if (ep - cp >= LINE_BUFFER_SIZE) + cp[LINE_BUFFER_SIZE-1] = 0; + if (strncmp(cp, "#!comment", 9)) + words[i++] = cp; + if (!ec || i == nWordFileLines) + break; + cp = ep + 1; + if (ec == '\r' && *cp == '\n') cp++; + } while (*cp); + nWordFileLines = i; + nCurLine=0; + } } else { word_file = stdin; log_event("- Reading candidate passwords from stdin"); @@ -153,7 +268,7 @@ void do_wordlist_crack(struct db_main *d length = db->format->params.plaintext_length; if (rules) { - if (rpp_init(rule_ctx = &ctx, SUBSECTION_WORDLIST)) { + if (rpp_init(rule_ctx = &ctx, db->options->activewordlistrules)) { log_event("! No wordlist mode rules found"); fprintf(stderr, "No wordlist mode rules found in %s\n", cfg_name); @@ -209,7 +324,21 @@ void do_wordlist_crack(struct db_main *d } if (rule) - while (fgetl(line, LINE_BUFFER_SIZE, word_file)) { + while (1) { + if (nWordFileLines) { + if (nCurLine == nWordFileLines) + break; +#if 0 && ARCH_ALLOWS_UNALIGNED +/* XXX: somehow this breaks things - why? */ + line = words[nCurLine++]; +#else + strcpy(line, words[nCurLine++]); +#endif + } + else { + if (!fgetl(line, LINE_BUFFER_SIZE, word_file)) + break; + } line_number++; if (line[0] != '#') { @@ -235,7 +364,11 @@ not_comment: rule_number++; line_number = 0; - if (fseek(word_file, 0, SEEK_SET)) pexit("fseek"); + + if (nWordFileLines) + nCurLine = 0; + else + if (fseek(word_file, 0, SEEK_SET)) pexit("fseek"); } } while (rules); @@ -246,10 +379,12 @@ not_comment: if (name) { if (event_abort) - progress = get_progress(); + progress = get_progress(&hund_progress); else progress = 100; + MEM_FREE(word_file_str); + MEM_FREE(words); if (fclose(word_file)) pexit("fclose"); word_file = NULL; } diff -urpN john-1.7.5.orig/src/x86-64.S john-1.7.5/src/x86-64.S --- john-1.7.5.orig/src/x86-64.S 2009-09-09 05:11:25 +0000 +++ john-1.7.5/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.5.orig/src/x86-64.h john-1.7.5/src/x86-64.h --- john-1.7.5.orig/src/x86-64.h 2008-06-22 01:29:02 +0000 +++ john-1.7.5/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.5.orig/src/x86-any.h john-1.7.5/src/x86-any.h --- john-1.7.5.orig/src/x86-any.h 2008-06-22 01:29:27 +0000 +++ john-1.7.5/src/x86-any.h 2009-12-27 17:38:21 +0000 @@ -20,14 +20,18 @@ #define ARCH_ALLOWS_UNALIGNED 1 #define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) -#if defined(__CYGWIN32__) || defined(__BEOS__) +#if defined(__CYGWIN32__) || defined(__BEOS__) || defined(__MINGW32__) || defined(_MSC_VER) #define OS_TIMER 0 #else #define OS_TIMER 1 #endif #define OS_FLOCK 1 +#if defined (_MSC_VER) +#define CPU_DETECT 0 +#else #define CPU_DETECT 1 +#endif #define CPU_REQ 0 #define DES_ASM 1 diff -urpN john-1.7.5.orig/src/x86-mmx.h john-1.7.5/src/x86-mmx.h --- john-1.7.5.orig/src/x86-mmx.h 2008-06-22 01:55:13 +0000 +++ john-1.7.5/src/x86-mmx.h 2009-12-27 17:38:21 +0000 @@ -20,14 +20,18 @@ #define ARCH_ALLOWS_UNALIGNED 1 #define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) -#if defined(__CYGWIN32__) || defined(__BEOS__) +#if defined(__CYGWIN32__) || defined(__BEOS__) || defined(__MINGW32__) || defined(_MSC_VER) #define OS_TIMER 0 #else #define OS_TIMER 1 #endif #define OS_FLOCK 1 +#if defined (_MSC_VER) +#define CPU_DETECT 0 +#else #define CPU_DETECT 1 +#endif #define CPU_REQ 1 #define CPU_NAME "MMX" #ifndef CPU_FALLBACK @@ -59,4 +63,7 @@ #define BF_SCALE 1 #define BF_X2 0 +#define MMX_TYPE " MMX" +#define MMX_COEF 2 + #endif diff -urpN john-1.7.5.orig/src/x86-sse.S john-1.7.5/src/x86-sse.S --- john-1.7.5.orig/src/x86-sse.S 2009-09-09 05:11:31 +0000 +++ john-1.7.5/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.5.orig/src/x86-sse.h john-1.7.5/src/x86-sse.h --- john-1.7.5.orig/src/x86-sse.h 2008-06-22 01:30:20 +0000 +++ john-1.7.5/src/x86-sse.h 2009-07-03 21:11:06 +0000 @@ -20,14 +20,18 @@ #define ARCH_ALLOWS_UNALIGNED 1 #define ARCH_INDEX(x) ((unsigned int)(unsigned char)(x)) -#if defined(__CYGWIN32__) || defined(__BEOS__) +#if defined(__CYGWIN32__) || defined(__BEOS__) || defined(__MINGW32__) || defined(_MSC_VER) #define OS_TIMER 0 #else #define OS_TIMER 1 #endif #define OS_FLOCK 1 +#if defined (_MSC_VER) +#define CPU_DETECT 0 +#else #define CPU_DETECT 1 +#endif #define CPU_REQ 1 #define CPU_NAME "SSE2" #ifndef CPU_FALLBACK @@ -59,4 +63,9 @@ #define BF_SCALE 1 #define BF_X2 0 +#define MMX_TYPE " SSE2" +#define MMX_COEF 4 + +#define NT_SSE2 + #endif