diff -urpN john-1.7.2.orig/doc/EPi.patch.README john-1.7.2/doc/EPi.patch.README --- john-1.7.2.orig/doc/EPi.patch.README 1970-01-01 00:00:00 +0000 +++ john-1.7.2/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.2.orig/src/BFEgg_fmt.c john-1.7.2/src/BFEgg_fmt.c --- john-1.7.2.orig/src/BFEgg_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/BFEgg_fmt.c 2008-02-20 14:19:35 +0000 @@ -0,0 +1,124 @@ +/* + * This file is part of Eggdrop blowfish patch for John The Ripper. + * Copyright (c) 2002 by Sun-Zero + * This is a free software distributable under terms of the GNU GPL. + */ + +#include + +#include "misc.h" +#include "formats.h" +#include "common.h" +#include "blowfish.c" + +#define FORMAT_LABEL "bfegg" +#define FORMAT_NAME "Eggdrop" +#define ALG_NAME "blowfish" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 31 +#define CIPHERTEXT_LENGTH 33 + +#define BINARY_SIZE 13 +#define SALT_SIZE 0 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"+9F93o1OxwgK1", "123456"}, + {"+C/.8o.Wuph9.", "qwerty"}, + {"+EEHgy/MBLDd0", "walkman"}, + {"+vPBrs07OTXE/", "tesztuser"}, + {"+zIvO/1nDsd9.", "654321"}, + {NULL} +}; + +int zerolengthkey = 0; + +static char crypt_key[BINARY_SIZE]; +static char saved_key[PLAINTEXT_LENGTH + 1]; + +static int valid(char *ciphertext) { + if (strncmp(ciphertext, "+", 1) != 0) return 0; + if (strlen(ciphertext) != 13) return 0; + + return 1; +} + +void init() { + blowfish_first_init(); +} + + +static void set_key(char *key, int index) { + strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1); +} + +static char *get_key(int index) { + return saved_key; +} + +static int cmp_all(void *binary, int index) { + if (zerolengthkey) return 0; + return !memcmp(binary, crypt_key, BINARY_SIZE); +} + +static int cmp_exact(char *source, int index) { + return 1; +} + +static void set_salt(void *salt) { } + +static void crypt_all(int count) { + if (saved_key[0] == '\0') { + zerolengthkey = 1; + } else { + zerolengthkey = 0; + blowfish_encrypt_pass(saved_key, crypt_key); + } +} + +struct fmt_main fmt_BFEgg = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALG_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + init, + valid, + fmt_default_split, + fmt_default_binary, + fmt_default_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash, + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash, + }, + cmp_all, + cmp_all, + cmp_exact + } +}; diff -urpN john-1.7.2.orig/src/DOMINOSEC_fmt.c john-1.7.2/src/DOMINOSEC_fmt.c --- john-1.7.2.orig/src/DOMINOSEC_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/DOMINOSEC_fmt.c 2008-02-20 14:19:35 +0000 @@ -0,0 +1,456 @@ +/* + * DOMINOSEC_fmt.c (version 3) + * + * Notes/Domino More Secure Internet Password module for Solar Designer's JtR + * by regenrecht@o2.pl, Dec 2005. + * Algorithm discovery by regenrecht@o2.pl, bartavelle@bandecon.com. + * + * Short description. + * 1. Make 128bit digest of key. (128/8=16 bytes) + * 2. Do bin2hex() of key digest and put braces around it. (16*2+2=34 bytes) + * 3. Concat output of previous step to 5 bytes of salt. (5+34=39 bytes) + * 4. Make 128bit digest of first 34 bytes (out of 39 bytes). (128/8=16 bytes) + * 5. Compare first 10 bytes (out of 16) to check if the key was correct. + * + * Password file should have form of: + * TomaszJegerman:(GKjXibCW2Ml6juyQHUoP) + * RubasznyJan:(GrixoFHOckC/2CnHrHtM) + */ + +#include +#include + +#include "misc.h" +#include "formats.h" +#include "common.h" + +#define FORMAT_LABEL "dominosec" +#define FORMAT_NAME "More Secure Internet Password" +#define ALGORITHM_NAME "RSA MD defined by BSAFE 1.x - Lotus v6" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 64 +#define CIPHERTEXT_LENGTH 22 +#define BINARY_SIZE 9 /* oh, well :P */ +#define SALT_SIZE 5 + +#define DIGEST_SIZE 16 +#define BINARY_BUFFER_SIZE (DIGEST_SIZE-SALT_SIZE) +#define ASCII_DIGEST_LENGTH (DIGEST_SIZE*2) +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static unsigned char key_digest[DIGEST_SIZE]; +static char saved_key[PLAINTEXT_LENGTH+1]; +static unsigned char crypted_key[DIGEST_SIZE]; +static unsigned char salt_and_digest[SALT_SIZE+1+ASCII_DIGEST_LENGTH+1+1] = + "saalt(................................)"; +static unsigned int saved_key_len; + +static const char *hex_table[] = { + "00", "01", "02", "03", "04", "05", "06", "07", + "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", + "10", "11", "12", "13", "14", "15", "16", "17", + "18", "19", "1A", "1B", "1C", "1D", "1E", "1F", + "20", "21", "22", "23", "24", "25", "26", "27", + "28", "29", "2A", "2B", "2C", "2D", "2E", "2F", + "30", "31", "32", "33", "34", "35", "36", "37", + "38", "39", "3A", "3B", "3C", "3D", "3E", "3F", + "40", "41", "42", "43", "44", "45", "46", "47", + "48", "49", "4A", "4B", "4C", "4D", "4E", "4F", + "50", "51", "52", "53", "54", "55", "56", "57", + "58", "59", "5A", "5B", "5C", "5D", "5E", "5F", + "60", "61", "62", "63", "64", "65", "66", "67", + "68", "69", "6A", "6B", "6C", "6D", "6E", "6F", + "70", "71", "72", "73", "74", "75", "76", "77", + "78", "79", "7A", "7B", "7C", "7D", "7E", "7F", + "80", "81", "82", "83", "84", "85", "86", "87", + "88", "89", "8A", "8B", "8C", "8D", "8E", "8F", + "90", "91", "92", "93", "94", "95", "96", "97", + "98", "99", "9A", "9B", "9C", "9D", "9E", "9F", + "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", + "A8", "A9", "AA", "AB", "AC", "AD", "AE", "AF", + "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", + "B8", "B9", "BA", "BB", "BC", "BD", "BE", "BF", + "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", + "C8", "C9", "CA", "CB", "CC", "CD", "CE", "CF", + "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", + "D8", "D9", "DA", "DB", "DC", "DD", "DE", "DF", + "E0", "E1", "E2", "E3", "E4", "E5", "E6", "E7", + "E8", "E9", "EA", "EB", "EC", "ED", "EE", "EF", + "F0", "F1", "F2", "F3", "F4", "F5", "F6", "F7", + "F8", "F9", "FA", "FB", "FC", "FD", "FE", "FF" +}; + +static const char lotus_magic_table[] = { + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, + 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, + 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, + 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, + 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, + 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, + 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, + 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, + 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, + 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, + 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, + 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, + 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, + 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, + 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, + 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, + 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab, + /* double power! */ + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, + 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, + 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, + 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, + 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, + 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, + 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, + 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, + 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, + 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, + 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, + 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, + 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, + 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, + 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, + 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, + 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab, +}; + +static struct fmt_tests dominosec_tests[] = { + {"(GVMroLzc50YK/Yd+L8KH)", ""}, + {"(GqnUDNNGNUz5HRoelmLU)", "x"}, + {"(GNBpcGJRYpBe9orUOpmZ)", "dupaaa123"}, + {"(G0xjUQzdKxvHpUYqo5hU)", "koziolekmatolek"}, + {"(G+dfECo845XxUw+nFVYD)", "szesnascieznakow"}, + {"(GowT5I2hVHZpRWpvGmux)", "terazjakiesdwadziesciacos"}, + {"(Gq2bAtpguiTSSycy6dhu)", "trzydziescidwamozesieudaojnieuda"}, + {"(G82TtgNcqcHGkpEo7wQp)", "looongrandominputdataforfunbutnotonlyoi!"}, + {NULL} +}; + +struct cipher_binary_struct { + unsigned char salt[SALT_SIZE]; + unsigned char hash[BINARY_BUFFER_SIZE]; +} cipher_binary; + +static void mdtransform(unsigned char state[16], unsigned char checksum[16], unsigned char block[16]) +{ + unsigned char x[48]; + unsigned int t = 0; + unsigned int i,j; + unsigned char * pt; + unsigned char c; + + memcpy(x, state, 16); + memcpy(x+16, block, 16); + + for(i=0;i<16;i++) + x[i+32] = state[i] ^ block[i]; + + for (i = 0; i < 18; ++i) + { + pt = (unsigned char*)&x; + for (j = 48; j > 0; j--) + { + *pt ^= lotus_magic_table[j+t]; + t = *pt; + pt++; + } + } + + memcpy(state, x, 16); + + t = checksum[15]; + for (i = 0; i < 16; i++) + { + c = lotus_magic_table[block[i]^t]; + checksum[i] ^= c; + t = checksum[i]; + } +} + +static void mdtransform_norecalc(unsigned char state[16], unsigned char block[16]) +{ + unsigned char x[48], *pt; + unsigned int t = 0; + unsigned int i,j; + + memcpy(x, state, 16); + memcpy(x+16, block, 16); + + for(i=0;i<16;i++) + x[i+32] = state[i] ^ block[i]; + + for(i = 0; i < 18; ++i) + { + pt = (unsigned char*)&x; + for (j = 48; j > 0; j--) + { + *pt ^= lotus_magic_table[j+t]; + t = *pt; + pt++; + } + } + + memcpy(state, x, 16); +} + +static void domino_big_md(unsigned char * saved_key, int size, unsigned char * crypt_key) +{ + unsigned char state[16] = {0}; + unsigned char checksum[16] = {0}; + unsigned char block[16]; + unsigned int x; + unsigned int curpos = 0; + + while(curpos + 15 < size) + { + memcpy(block, saved_key + curpos, 16); + mdtransform(state, checksum, block); + curpos += 16; + } + + if(curpos != size) + { + x = size - curpos; + memcpy(block, saved_key + curpos, x); + memset(block + x, 16 - x, 16 - x); + mdtransform(state, checksum, block); + } + else + { + memset(block, 16, 16); + mdtransform(state, checksum, block); + } + + mdtransform_norecalc(state, checksum); + + memcpy(crypt_key, state, 16); +} + +static int dominosec_valid(char *ciphertext) +{ + unsigned int i; + unsigned char ch; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + + if (ciphertext[0] != '(' || + ciphertext[1] != 'G' || + ciphertext[CIPHERTEXT_LENGTH-1] != ')') + return 0; + + for (i = 1; i < CIPHERTEXT_LENGTH-1; ++i) { + ch = ciphertext[i]; + if (!isalnum(ch) && ch != '+' && ch != '/') + return 0; + } + + return 1; +} + +/* +static unsigned int dominosec_proper_mul(int delta_apsik) +{ + __asm__("movl $0xAAAAAAAB, %eax \n" + "movl 0x8(%ebp), %edx \n" + "mul %edx \n" + "shr $0x2,%edx \n" + "movl %edx, %eax \n"); +} +*/ + +static void dominosec_decode(unsigned char *ascii_cipher, unsigned char *binary) +{ + unsigned int out = 0, apsik = 0, loop; + unsigned int i; + unsigned char ch; + + ascii_cipher += 2; + i = 0; + do { + if (apsik < 8) { + /* should be using proper_mul, but what the heck... + it's nearly the same :] */ + loop = 2; /* ~ loop = proper_mul(13 - apsik); */ + apsik += loop*6; + + do { + out <<= 6; + ch = *ascii_cipher; + + if (ch < '0' || ch > '9') + if (ch < 'A' || ch > 'Z') + if (ch < 'a' || ch > 'z') + if (ch != '+') + if (ch == '/') + out += '?'; + else + ; /* shit happens */ + else + out += '>'; + else + out += ch-'='; + else + out += ch-'7'; + else + out += ch-'0'; + ++ascii_cipher; + } while (--loop); + } + + loop = apsik-8; + ch = out >> loop; + *(binary+i) = ch; + ch <<= loop; + apsik = loop; + out -= ch; + } while (++i < 15); + + binary[3] += -4; +} + +static void *dominosec_binary(char *ciphertext) +{ + dominosec_decode((unsigned char*)ciphertext, (unsigned char*)&cipher_binary); + return (void*)cipher_binary.hash; +} + +static void *dominosec_salt(char *ciphertext) +{ + return cipher_binary.salt; +} + +static void dominosec_set_salt(void *salt) +{ + memcpy(salt_and_digest, salt, SALT_SIZE); +} + +static void dominosec_set_key(char *key, int index) +{ + unsigned char *offset = salt_and_digest+6; + unsigned int i; + + saved_key_len = strlen(key); + strnzcpy(saved_key, key, PLAINTEXT_LENGTH); + + domino_big_md((unsigned char*)key, saved_key_len, key_digest); + + i = 0; + do { + memcpy(offset, *(hex_table+*(key_digest+i)), 2); + offset += 2; + } while (++i < 14); + + /* + * Not (++i < 16) ! + * Domino will do hash of first 34 bytes ignoring The Fact that now + * there is a salt at a beginning of buffer. This means that last 5 + * bytes "EEFF)" of password digest are meaningless. + */ +} + +static char *dominosec_get_key(int index) +{ + return saved_key; +} + +static void dominosec_crypt_all(int count) +{ + domino_big_md(salt_and_digest, 34, crypted_key); +} + +static int dominosec_cmp_all(void *binary, int count) +{ + /* + * Only 10 bytes of digest are to be checked. + * 48 bits are left alone. + * Funny that. + */ + return !memcmp(crypted_key, binary, BINARY_SIZE); +} + +static int dominosec_cmp_exact(char *source, int index) +{ + return 1; +} + +struct fmt_main fmt_DOMINOSEC = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + dominosec_tests + }, + { + fmt_default_init, + dominosec_valid, + fmt_default_split, + dominosec_binary, + dominosec_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + dominosec_set_salt, + dominosec_set_key, + dominosec_get_key, + fmt_default_clear_keys, + dominosec_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + dominosec_cmp_all, + dominosec_cmp_all, + dominosec_cmp_exact + } +}; diff -urpN john-1.7.2.orig/src/EPI_fmt.c john-1.7.2/src/EPI_fmt.c --- john-1.7.2.orig/src/EPI_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/EPI_fmt.c 2008-04-21 05:19:44 +0000 @@ -0,0 +1,204 @@ +/* + * EPiServer module for john 1.7.2 (and possibly later) + * Uses hashes/salts found in the tblSID of an EPiServer database installation + * + * Created by Johannes Gumbel (johannes [at] iforge.cc) + * + * If you have any questions as to how a function incorporates with john, please refer to formats.h of john + * + * version 0.1 released on 10 jan 2007 + * + * See doc/EPi.patch.README or http://iforge.cc/files/EPi.patch.README + * for information on the input file format. + */ + +#include "string.h" +#include "formats.h" +#include "common.h" +#include "misc.h" + +#include "sha.h" + +#define PLAINTEXT_LENGTH 0x80-4 +#define BINARY_LENGTH 20 +#define SALT_LENGTH 30 + +static char global_crypt[BINARY_LENGTH]; +static char global_key[PLAINTEXT_LENGTH]; // set by set_key and used by get_get +static char global_salt[SALT_LENGTH + PLAINTEXT_LENGTH]; // set by set_salt and used by crypt_all + // the extra plaintext_length is needed because the + // current key is copied there before hashing + +int valid(char *ciphertext); +void* binary(char *ciphertext); +void* salt(char *ciphertext); +void set_salt(void *salt); +void set_key(char *key, int index); +char* get_key(int index); +void crypt_all(int count); +int cmp_all(void *binary, int count); +int cmp_one(void *binary, int index); +int cmp_exact(char *source, int index); + +struct fmt_tests global_tests[] = +{ + {"0x5F1D84A6DE97E2BEFB637A3CB5318AFEF0750B856CF1836BD1D4470175BE 0x4D5EFDFA143EDF74193076F174AC47CEBF2F417F", "Abc.!23"}, + {NULL} +}; + +// Define john integration +struct fmt_main fmt_EPI = +{ + { // fmt_params + "epi", + "EPiServer SID Hashes", + "SHA1", + "", // benchmark comment + 0, // benchmark length + PLAINTEXT_LENGTH, + BINARY_LENGTH, + SALT_LENGTH, + 1, + 1, + FMT_CASE | FMT_8_BIT, // flags XXX, these are just guesses + global_tests + }, + { // fmt_methods + fmt_default_init, + valid, + fmt_default_split, + binary, + salt, + { // binary_hash[3] + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { // get_hash[3] + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + cmp_all, + cmp_one, + cmp_exact + } +}; + +/* + * Expects ciphertext of format: 0xHEX*60 0xHEX*40 + */ +int valid(char *ciphertext) +{ + unsigned int len, n; + + if(!ciphertext) return 0; + len = strlen(ciphertext); + + if(len != 105) + return 0; + + // check fixed positions + if(ciphertext[0] != '0' || ciphertext[1] != 'x' || + ciphertext[62] != ' ' || + ciphertext[63] != '0' || ciphertext[64] != 'x') + return 0; + + for(n = 2; n < 62 && atoi16[ARCH_INDEX(ciphertext[n])] != 0x7F; ++n); + for(n = 65; n < 105 && atoi16[ARCH_INDEX(ciphertext[n])] != 0x7F; ++n); + + return n == len; +} + +void _tobin(char* dst, char *src, unsigned int len) +{ + unsigned int n; + + if(src[0] == '0' && src[1] == 'x') + src += sizeof(char)*2; + + for(n = 0; n < len; ++n) + dst[n] = atoi16[ARCH_INDEX(src[n*2])]<<4 | + atoi16[ARCH_INDEX(src[n*2+1])]; +} + +void* binary(char *ciphertext) +{ + static char bin[BINARY_LENGTH]; + + _tobin(bin, (char*)(ciphertext+65), sizeof(bin)); + + return bin; +} + +void* salt(char *ciphertext) +{ + static char salt[SALT_LENGTH]; + + _tobin(salt, (char*)(ciphertext+2), sizeof(salt)); + + return salt; +} + +void set_salt(void *salt) +{ + memcpy(global_salt, salt, SALT_LENGTH); +} + +void set_key(char *key, int index) +{ + if(!key) return; + strnzcpy(global_key, key, PLAINTEXT_LENGTH); +} + +char* get_key(int index) +{ + return global_key; +} + +void crypt_all(int count) +{ + static SHA_CTX ctx; + + // Yes, I'm overwriting the last byte of the salt, perhaps the coder at ElektoPost whom wrote the EPiServer password checking function used to be a C coder (their code is written in .NET) + strnzcpy(global_salt+SALT_LENGTH-1, global_key, PLAINTEXT_LENGTH); + + SHA1_Init(&ctx); + SHA1_Update(&ctx, (unsigned char*)global_salt, SALT_LENGTH+strlen(global_key)); + SHA1_Final((unsigned char*)global_crypt, &ctx); +} + +int cmp_all(void *binary, int count) +{ + unsigned int n; + ARCH_WORD *a, *b; + + if(*(ARCH_WORD*)binary != *(ARCH_WORD*)global_crypt) + return 0; + + a = (ARCH_WORD*)binary; + b = (ARCH_WORD*)global_crypt; + + // Starting at 1 since 0 was checked previously + for(n=1; n + +#include "arch.h" +#include "misc.h" +#include "md5.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "ipb2" +#define FORMAT_NAME "IPB2 MD5" +#define ALGORITHM_NAME "Invision Power Board 2.x salted MD5" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define MD5_BINARY_SIZE 16 +#define MD5_HEX_SIZE (MD5_BINARY_SIZE * 2) + +#define BINARY_SIZE MD5_BINARY_SIZE + +#define SALT_SIZE 5 +#define PROCESSED_SALT_SIZE MD5_HEX_SIZE + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH (1 + 4 + 1 + SALT_SIZE * 2 + 1 + MD5_HEX_SIZE) + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests ipb2_tests[] = { + {"$IPB2$2e75504633$d891f03a7327639bc632d62a7f302604", "welcome"}, + {"$IPB2$735a213a4e$4f23de7bb115139660db5e953153f28a", "enter"}, + {"$IPB2$5d75343455$de98ba8ca7bb16f43af05e9e4fb8afee", "matrix"}, + {"$IPB2$556c576c39$16d4f29c71b05bd75e61d0254800bfa3", "123456"}, + {NULL} +}; + +static char itoa16_shr_04[] = + "0000000000000000" + "1111111111111111" + "2222222222222222" + "3333333333333333" + "4444444444444444" + "5555555555555555" + "6666666666666666" + "7777777777777777" + "8888888888888888" + "9999999999999999" + "aaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbb" + "cccccccccccccccc" + "dddddddddddddddd" + "eeeeeeeeeeeeeeee" + "ffffffffffffffff"; + +static char itoa16_and_0f[] = + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef" + "0123456789abcdef"; + +static MD5_CTX ctx; +static char saved_key[PLAINTEXT_LENGTH + 1]; +static int saved_key_len; +static char workspace[MD5_HEX_SIZE * 2]; +static char output[MD5_BINARY_SIZE]; + +static int ipb2_valid(char *ciphertext) +{ + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) + return 0; + + if (strncmp(ciphertext, "$IPB2$", 6) != 0) + return 0; + + if (ciphertext[16] != '$') + return 0; + + if (strspn(ciphertext+6, itoa16) != SALT_SIZE*2) + return 0; + + if (strspn(ciphertext+17, itoa16) != MD5_HEX_SIZE) + return 0; + + return 1; +} + +static void *ipb2_binary(char *ciphertext) +{ + static unsigned char binary_cipher[BINARY_SIZE]; + int i; + + ciphertext += 17; + for (i = 0; i < MD5_HEX_SIZE; ++i) + binary_cipher[i] = + (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + return (void *)binary_cipher; +} + +static void *ipb2_salt(char *ciphertext) +{ + static unsigned char binary_salt[SALT_SIZE]; + static unsigned char salt_hash[MD5_BINARY_SIZE]; + static unsigned char hex_salt[MD5_HEX_SIZE]; + int i; + + ciphertext += 6; + for (i = 0; i < SALT_SIZE; ++i) + binary_salt[i] = + (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + MD5_Init(&ctx); + MD5_Update(&ctx, binary_salt, SALT_SIZE); + MD5_Final(salt_hash, &ctx); + + for (i = 0; i < MD5_BINARY_SIZE; ++i) { + hex_salt[i*2] = itoa16[ARCH_INDEX(salt_hash[i] >> 4)]; + hex_salt[i*2+1] = itoa16[ARCH_INDEX(salt_hash[i] & 0x0f)]; + } + + return (void*)hex_salt; +} + +static void ipb2_set_salt(void *salt) +{ + memcpy((char*)workspace, (char*)salt, PROCESSED_SALT_SIZE); +} + +static int strnfcpy_count(char *dst, char *src, int size) +{ + char *dptr = dst, *sptr = src; + int count = size; + + while (count--) + if (!(*dptr++ = *sptr++)) break; + + return size-count-1; +} + +static void ipb2_set_key(char *key, int index) +{ + static unsigned char key_hash[MD5_BINARY_SIZE]; + unsigned char *kh = key_hash; + unsigned char *workspace_ptr = (unsigned char *) (workspace + PROCESSED_SALT_SIZE); + unsigned char v; + int i; + + saved_key_len = strnfcpy_count(saved_key, key, PLAINTEXT_LENGTH); + + MD5_Init(&ctx); + MD5_Update(&ctx, saved_key, saved_key_len); + MD5_Final(key_hash, &ctx); + + for (i = 0; i < MD5_BINARY_SIZE; ++i) { + v = *kh++; + *workspace_ptr++ = itoa16_shr_04[ARCH_INDEX(v)]; + *workspace_ptr++ = itoa16_and_0f[ARCH_INDEX(v)]; + } +} + +static char *ipb2_get_key(int index) +{ + return saved_key; +} + +static void ipb2_crypt_all(int count) +{ + MD5_Init(&ctx); + MD5_Update(&ctx, workspace, MD5_HEX_SIZE * 2); + MD5_Final((unsigned char *) output, &ctx); +} + +static int ipb2_cmp_all(void *binary, int index) +{ + return !memcmp(binary, output, MD5_BINARY_SIZE); +} + +static int ipb2_cmp_exact(char *source, int index) +{ + return 1; +} + +struct fmt_main fmt_IPB2 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + PROCESSED_SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + ipb2_tests + }, + { + fmt_default_init, + ipb2_valid, + fmt_default_split, + ipb2_binary, + ipb2_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + ipb2_set_salt, + ipb2_set_key, + ipb2_get_key, + fmt_default_clear_keys, + ipb2_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + ipb2_cmp_all, + ipb2_cmp_all, + ipb2_cmp_exact + } +}; diff -urpN john-1.7.2.orig/src/KRB5_fmt.c john-1.7.2/src/KRB5_fmt.c --- john-1.7.2.orig/src/KRB5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/KRB5_fmt.c 2008-02-20 14:19:35 +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 Soug. + * + * 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 + +#define DES3_KEY_SIZE 24 +#define DES3_KEY_BITS 168 +#define DES3_KEY_SCHED_SIZE 384 + +#define KRBTGT "krbtgt" +// }}} + + +/** + * structure to hold the self tests // {{{ + */ +static struct fmt_tests KRB5_fmt_tests[] = { + {"$krb5$oskov$ACM.UIUC.EDU$4730d7249765615d6f3652321c4fb76d09fb9cd06faeb0c31b8737f9fdfcde4bd4259c31cb1dff25df39173b09abdff08373302d99ac09802a290915243d9f0ea0313fdedc7f8d1fae0d9df8f0ee6233818d317f03a72c2e77b480b2bc50d1ca14fba85133ea00e472c50dbc825291e2853bd60a969ddb69dae35b604b34ea2c2265a4ffc72e9fb811da17c7f2887ccb17e2f87cd1f6c28a9afc0c083a9356a9ee2a28d2e4a01fc7ea90cc8836b8e25650c3a1409b811d0bad42a59aa418143291d42d7b1e6cb5b1876a4cc758d721323a762e943f774630385c9faa68df6f3a94422f97", "p4ssW0rd"}, + {"$krb5$oskov$ACM.UIUC.EDU$6cba0316d38e31ba028f87394792baade516afdfd8c5a964b6a7677adbad7815d778b297beb238394aa97a4d495adb7c9b7298ba7c2a2062fb6c9a4297f12f83755060f4f58a1ea4c7026df585cdfa02372ad619ab1a4ec617ad23e76d6e37e36268d9aa0abcf83f11fa8092b4328c5e6c577f7ec6f1c1684d9c99a309eee1f5bd764c4158a2cf311cded8794b2de83131c3dc51303d5300e563a2b7a230eac67e85b4593e561bf6b88c77b82c729e7ba7f3d2f99b8dc85b07873e40335aff4647833a87681ee557fbd1ffa1a458a5673d1bd3c1587eceeabaebf4e44c24d9a8ac8c1d89", "Nask0Oskov"}, + {NULL} +}; +// }}} + +/** + * struct to save the salt into + */ +struct salt { // {{{ + char realm[MAX_REALM_LEN]; + char user[MAX_USER_LEN]; + char tgt_ebin[TGT_SIZE]; + char passwd[MAX_PASS_LEN]; +}; +#define SALT_SIZE sizeof(struct salt) +// }}} + +struct key { // {{{ + char passwd[MAX_PASS_LEN]; + char key[MAX_PASS_LEN]; + DES_key_schedule sched[3]; +}; +// }}} + +static struct salt *psalt = NULL; +static struct key skey; + +static char username[MAX_USER_LEN]; +static char realm[MAX_REALM_LEN]; +static char password[MAX_PASS_LEN]; + +// initialization vector for des +static DES_cblock ivec; + +krb5_key _krb5key; +krb5_key *krb5key = &_krb5key; + +/** + * hex2bin // {{{ + */ +static void hex2bin(char *src, u_char *dst, int outsize) { + char *p, *pe; + u_char *q, *qe, ch, cl; + + pe = src + strlen(src); + qe = dst + outsize; + + for (p = src, q = dst; p < pe && q < qe && isxdigit((int)*p); p += 2) { + ch = tolower(p[0]); + cl = tolower(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() { + + char plain[TGT_SIZE]; + int i; + + memset(krb5key->key, 0x00, DES3_KEY_SIZE); + memset(krb5key->schedule, 0x00, DES3_KEY_SCHED_SIZE); + + memset(username, 0x00, MAX_USER_LEN); + memcpy(username, psalt->user, strlen(psalt->user)); + memset(realm, 0x00, MAX_REALM_LEN); + memcpy(realm, psalt->realm, strlen(psalt->realm)); + memset(password, 0x00, MAX_PASS_LEN); + memcpy(password, skey.passwd, strlen(skey.passwd)); + + // do str2key + str2key(username, realm, password, krb5key); + + des3_decrypt(krb5key, psalt->tgt_ebin, plain, TGT_SIZE); + + for(i=0;ipasswd, 0x00, MAX_PASS_LEN); + strncpy(psalt->passwd, skey.passwd, strlen(skey.passwd)); + return 1; + } + return 0; +} +// }}} + +/** + * int krb5_valid // {{{ + * + */ +static int krb5_valid(char *ciphertext) { + + if (strncmp(ciphertext, MAGIC_PREFIX, strlen(MAGIC_PREFIX)) != 0) + return 0; + + return 1; +} +// }}} + +/** + * void * krb5_salt // {{{ + * + */ +static void * krb5_salt(char *ciphertext) { + + struct salt *salt = NULL; + char *data = ciphertext, *p; + + // check the presence of $krb5$ + if (strncmp(data, MAGIC_PREFIX, strlen(MAGIC_PREFIX)) == 0) { + // advance past the $krb5$ string + data += strlen(MAGIC_PREFIX); + + // allocate memory for the struct + salt = malloc(sizeof(struct salt)); + if (salt == NULL) + return NULL; + + // find and copy the user field + p = strchr(data, '$'); + strnzcpy(salt->user, data, (p - data) + 1); + data = p + 1; + + // find and copy the realm field + p = strchr(data, '$'); + strnzcpy(salt->realm, data, (p - data) + 1); + data = p + 1; + + // copy over the TGT in a binary form to the salt struct + hex2bin(data, (u_char *) salt->tgt_ebin, TGT_SIZE); + } + return salt; +} +// }}} + +/** + * void krb5_set_salt // {{{ + * + */ +static void krb5_set_salt(void *salt) { + psalt = (struct salt *) salt; +} +// }}} + +/** + * void krb5_set_key // {{{ + * + */ +static void krb5_set_key(char *key, int index) { + + // copy the string key to the saved key + memset(skey.passwd, 0x00, MAX_PASS_LEN); + strnzcpy(skey.passwd, key, sizeof(skey.passwd)); + +} +// }}} + +/** + * char * krb5_get_key // {{{ + * + */ +static char * krb5_get_key(int index) { + return skey.passwd; +} +// }}} + +/** + * void krb5_crypt_all // {{{ + * + */ +static void krb5_crypt_all(int count) { + // do nothing +} +// }}} + +/** + * int krb5_cmp_all // {{{ + * + */ +static inline int krb5_cmp_all(void *binary, int count) { + + return krb5_decrypt_compare(); + +} +// }}} + +/** + * int krb5_cmp_one // {{{ + * + */ +static int krb5_cmp_one(void *binary, int count) { + + return krb5_decrypt_compare(); + +} +// }}} + +/** + * int krb5_cmp_exact // {{{ + * + */ +static int krb5_cmp_exact(char *source, int index) { + return 1; +} +// }}} + +/** + * void krb5_init // {{{ + * + */ +static void krb5_init() { + + memset(&ivec, 0x00, sizeof(ivec)); + memset(&skey, 0x00, sizeof(skey)); + memset(krb5key, 0x00, sizeof(krb5_key)); + + krb5key->key = (char *) malloc(DES3_KEY_SIZE); + krb5key->schedule = (char *) malloc(DES3_KEY_SCHED_SIZE); + memset(krb5key->key, 0x00, DES3_KEY_SIZE); + memset(krb5key->schedule, 0x00, DES3_KEY_SCHED_SIZE); + +} +// }}} + +/** + * fmt_main struct with KRB5 values // {{{ + */ +struct fmt_main fmt_KRB5 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + KRB5_fmt_tests + }, { + krb5_init, + krb5_valid, + fmt_default_split, + fmt_default_binary, + krb5_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + krb5_set_salt, + krb5_set_key, + krb5_get_key, + fmt_default_clear_keys, + krb5_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + krb5_cmp_all, + krb5_cmp_one, + krb5_cmp_exact + } +}; +// }}} + diff -urpN john-1.7.2.orig/src/KRB5_std.c john-1.7.2/src/KRB5_std.c --- john-1.7.2.orig/src/KRB5_std.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/KRB5_std.c 2008-02-20 14:19:35 +0000 @@ -0,0 +1,278 @@ +/* + * KRB5_std.c + * + * Kerberos 5 module for John the Ripper by Solar Designer, based on the + * KRB4 module by Dug Soug. + * + * 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 "KRB5_std.h" + +static DES_cblock ivec; +static const char derive_const[5] = "\x00\x00\x00\x03\xaa"; + +/** + * Heimdal rr13 function // {{{ + */ +static inline void rr13(unsigned char *buf, int len) { + + unsigned char *tmp; + int bytes = (len + 7) / 8; + int i; + + int bb; + int b1, s1, b2, s2; + + const int bits = 13 % len; + const int lbit = len % 8; + + if(len == 0) + return; + + tmp = (unsigned char *) malloc(bytes); + memcpy(tmp, buf, bytes); + if(lbit) { + // pad final byte with inital bits + tmp[bytes - 1] &= 0xff << (8 - lbit); + for(i = lbit; i < 8; i += len) + tmp[bytes - 1] |= buf[0] >> i; + } + for(i = 0; i < bytes; i++) { + // calculate first bit position of this byte + bb = 8 * i - bits; + while(bb < 0) + bb += len; + // byte offset and shift count + b1 = bb / 8; + s1 = bb % 8; + + if(bb + 8 > bytes * 8) + // watch for wraparound + s2 = (len + 8 - s1) % 8; + else + s2 = 8 - s1; + b2 = (b1 + 1) % bytes; + buf[i] = (tmp[b1] << s1) | (tmp[b2] >> s2); + } + free(tmp); +} +// }}} + +/** + * Heimdal add1 function // {{{ + */ +static inline void add1(unsigned char *a, unsigned char *b, size_t len) { + int i, x; + int carry = 0; + for(i = len - 1; i >= 0; i--){ + x = a[i] + b[i] + carry; + carry = x > 0xff; + a[i] = x & 0xff; + } + for(i = len - 1; carry && i >= 0; i--){ + x = a[i] + carry; + carry = x > 0xff; + a[i] = x & 0xff; + } +} +// }}} + +/** + * Heimdal _krb5_n_fold function // {{{ + */ +static inline void _krb5_n_fold(const void *str, int len, void *key, int size) { + + int maxlen = 2 * max(size, len), l = 0; + unsigned char *tmp = (unsigned char *) malloc(maxlen); + unsigned char *buf = (unsigned char *) malloc(len); + + memcpy(buf, str, len); + memset(key, 0, size); + do { + memcpy(tmp + l, buf, len); + l += len; + rr13(buf, len * 8); + while(l >= size) { + add1(key, tmp, size); + l -= size; + if(l == 0) + break; + memmove(tmp, tmp + size, l); + } + } while(l != 0); + sfree(buf, len); + sfree(tmp, maxlen); +} +// }}} + +/** + * Heimdal DES3_postproc function // {{{ + */ +static inline void DES3_postproc(unsigned char *k, int len, krb5_key *krb5key) { + unsigned char x[24]; + int i, j; + unsigned char foo; + unsigned char b; + + memset(x, 0, sizeof(x)); + for (i = 0; i < 3; ++i) { + for (j = 0; j < 7; ++j) { + b = k[7 * i + j]; + x[8 * i + j] = b; + } + foo = 0; + for (j = 6; j >= 0; --j) { + foo |= k[7 * i + j] & 1; + foo <<= 1; + } + x[8 * i + 7] = foo; + } + k = (unsigned char *) krb5key->key; + memcpy(k, x, 24); + DES_set_odd_parity((DES_cblock*)k); + DES_set_odd_parity((DES_cblock*)(k + 8)); + DES_set_odd_parity((DES_cblock*)(k + 16)); + + memset(x, 0, sizeof(x)); +} +// }}} + +/** + * 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"); + 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"); + // 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.2.orig/src/KRB5_std.h john-1.7.2/src/KRB5_std.h --- john-1.7.2.orig/src/KRB5_std.h 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/KRB5_std.h 2008-02-20 14:19:35 +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 Soug. + * + * 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 384 + +#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.2.orig/src/MD5_apache_fmt.c john-1.7.2/src/MD5_apache_fmt.c --- john-1.7.2.orig/src/MD5_apache_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/MD5_apache_fmt.c 2008-02-20 14:19:35 +0000 @@ -0,0 +1,201 @@ +/* + 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@bastard.net) +*/ + +/* + * This file is part of John the Ripper password cracker, + * Copyright (c) 1996-2001 by Solar Designer + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "MD5_std.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "md5a" +#define FORMAT_NAME "Apache MD5" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 15 +#define CIPHERTEXT_LENGTH 22 + +#define BINARY_SIZE 4 +#define SALT_SIZE 8 + +#define MIN_KEYS_PER_CRYPT MD5_N +#define MAX_KEYS_PER_CRYPT MD5_N + + +static struct fmt_tests tests[] = { + {"$apr1$Q6ZYh...$RV6ft2bZ8j.NGrxLYaJt9.", "test"}, + {"$apr1$rBXqc...$NlXxN9myBOk95T0AyLAsJ0", "john"}, + {"$apr1$Grpld/..$qp5GyjwM2dnA5Cdej9b411", "the"}, + {"$apr1$GBx.D/..$yfVeeYFCIiEXInfRhBRpy/", "ripper"}, + {NULL} +}; + +static char saved_key[MD5_N][PLAINTEXT_LENGTH + 1]; + +static int valid(char *ciphertext) +{ + char *pos, *start; + + if (strncmp(ciphertext, "$apr1$", 6)) return 0; + + /* magic string */ + start = &ciphertext[1]; + for (pos = start; *pos && *pos != '$'; pos++); + if (!*pos || pos < start+1 || pos > start+MD5_MAGIC_LENGTH+1) + return 0; + + /* salt */ + start = ++pos; + for (pos = start; *pos && *pos != '$'; pos++); + if (!*pos || pos < start || pos > start+8) + return 0; + + + start = ++pos; + while (atoi64[ARCH_INDEX(*pos)] != 0x7F) pos++; + if (*pos || pos - start != CIPHERTEXT_LENGTH) return 0; + + if (atoi64[ARCH_INDEX(*(pos - 1))] & 0x3C) return 0; + + return 1; +} + +static int binary_hash_0(void *binary) +{ + return *(MD5_word *)binary & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return *(MD5_word *)binary & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return *(MD5_word *)binary & 0xFFF; +} + +static int get_hash_0(int index) +{ + return MD5_out[index][0] & 0xF; +} + +static int get_hash_1(int index) +{ + return MD5_out[index][0] & 0xFF; +} + +static int get_hash_2(int index) +{ + return MD5_out[index][0] & 0xFFF; +} + +static int salt_hash(void *salt) +{ + return + ((int)atoi64[ARCH_INDEX(((char *)salt)[0])] | + ((int)atoi64[ARCH_INDEX(((char *)salt)[1])] << 6)) & 0x3FF; +} + +static void set_key(char *key, int index) +{ + MD5_std_set_key(key, index); + + strnfcpy(saved_key[index], key, PLAINTEXT_LENGTH); +} + +static char *get_key(int index) +{ + saved_key[index][PLAINTEXT_LENGTH] = 0; + + return saved_key[index]; +} + +static int cmp_all(void *binary, int index) +{ + +#if MD5_X2 + return *(MD5_word *)binary == MD5_out[0][0] || + *(MD5_word *)binary == MD5_out[1][0]; +#else + return *(MD5_word *)binary == MD5_out[0][0]; +#endif +} + + +static int cmp_exact(char *source, int index) +{ + return !memcmp(MD5_std_get_binary(source, MD5_TYPE_APACHE), MD5_out[index], + sizeof(MD5_binary)); +} + + +static void crypt_all(int count) { + MD5_std_crypt(MD5_TYPE_APACHE); +} + +static void *get_salt(char *ciphertext) { + return MD5_std_get_salt(ciphertext, MD5_TYPE_APACHE); +} + +static void *get_binary(char *ciphertext) { + return MD5_std_get_binary(ciphertext, MD5_TYPE_APACHE); +} + + +struct fmt_main fmt_MD5_apache = { + { + FORMAT_LABEL, + FORMAT_NAME, + MD5_ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + MD5_std_init, + valid, + fmt_default_split, + get_binary, //(void *(*)(char *))MD5_std_get_binary, + get_salt, //(void *(*)(char *))MD5_std_get_salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2 + }, + salt_hash, + (void (*)(void *))MD5_std_set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, //(void (*)(int))MD5_std_crypt, + { + get_hash_0, + get_hash_1, + get_hash_2 + }, + cmp_all, + cmp_all, + cmp_exact + } +}; diff -urpN john-1.7.2.orig/src/MD5_fmt.c john-1.7.2/src/MD5_fmt.c --- john-1.7.2.orig/src/MD5_fmt.c 2003-08-21 04:04:45 +0000 +++ john-1.7.2/src/MD5_fmt.c 2008-02-20 14:19:35 +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 by Solar Designer */ @@ -117,10 +124,22 @@ static int cmp_all(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, @@ -139,8 +158,8 @@ struct fmt_main fmt_MD5 = { MD5_std_init, valid, fmt_default_split, - (void *(*)(char *))MD5_std_get_binary, - (void *(*)(char *))MD5_std_get_salt, + get_binary, //(void *(*)(char *))MD5_std_get_binary, + get_salt, //(void *(*)(char *))MD5_std_get_salt, { binary_hash_0, binary_hash_1, @@ -151,7 +170,7 @@ struct fmt_main fmt_MD5 = { set_key, get_key, fmt_default_clear_keys, - (void (*)(int))MD5_std_crypt, + crypt_all, // (void (*)(int))MD5_std_crypt, { get_hash_0, get_hash_1, diff -urpN john-1.7.2.orig/src/MD5_std.c john-1.7.2/src/MD5_std.c --- john-1.7.2.orig/src/MD5_std.c 2006-05-08 06:27:41 +0000 +++ john-1.7.2/src/MD5_std.c 2008-02-20 14:19:35 +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@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.2.orig/src/MD5_std.h john-1.7.2/src/MD5_std.h --- john-1.7.2.orig/src/MD5_std.h 2003-12-03 10:16:02 +0000 +++ john-1.7.2/src/MD5_std.h 2008-02-20 14:19:35 +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.2.orig/src/MYSQL_fast_fmt.c john-1.7.2/src/MYSQL_fast_fmt.c --- john-1.7.2.orig/src/MYSQL_fast_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/MYSQL_fast_fmt.c 2008-03-02 21:26:38 +0000 @@ -0,0 +1,214 @@ +/* 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 char crypt_key[MAX_KEYS_PER_CRYPT][BINARY_SIZE]; +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 (!(*((unsigned long*)binary) - *((unsigned long*)&crypt_key[index]))); +} + +static int mysql_cmp_all(void* binary, int count) +{ + unsigned int i; + + for (i = 0; i < count; i++) + { + if (!(*((unsigned long*)binary) - *((unsigned long*)&crypt_key[i]))) + 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; + } + + *((unsigned long*)&crypt_key[i]) = (nr & (((unsigned long) 1L << 31) -1L)); + } +} + +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, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + mysql_set_salt, + mysql_set_key, + mysql_get_key, + fmt_default_clear_keys, + mysql_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + mysql_cmp_all, + mysql_cmp_one, + mysql_cmp_exact + } +}; diff -urpN john-1.7.2.orig/src/MYSQL_fmt.c john-1.7.2/src/MYSQL_fmt.c --- john-1.7.2.orig/src/MYSQL_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/MYSQL_fmt.c 2008-02-20 14:19:35 +0000 @@ -0,0 +1,241 @@ +//////////////////////////////////////////////////////////////// +// MySQL password cracker - v1.0 - 16.1.2003 +// +// by Andrew Hintz drew@overt.org +// +// This production has been brought to you by +// 4tphi and violating +// +// This file is an add-on to John the Ripper +// +// Part of this code is based on the MySQL brute password cracker +// mysqlpassword.c by Chris Given +// This program executes about 75% faster than mysqlpassword.c +// John the ripper also performs sophisticated password guessing. +// +// John the Ripper will expect the MySQL password file to be +// in the following format (without the leading // ): +// dumb_user:5d2e19393cc5ef67 +// another_luser:28ff8d49159ffbaf + +#include +#include +#include +#include + +// johntr includes +#include "arch.h" +#include "misc.h" +#include "formats.h" +#include "common.h" + +//johntr defines +#define FORMAT_LABEL "mysql" +#define FORMAT_NAME "MYSQL" +#define ALGORITHM_NAME "mysql" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +// Increase the PLAINTEXT_LENGTH value for longer passwords. +// You can also set it to 8 when using MySQL systems that truncate +// the password to only 8 characters. +#define PLAINTEXT_LENGTH 32 + +#define CIPHERTEXT_LENGTH 16 + +#define BINARY_SIZE 16 +#define SALT_SIZE 0 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + + +//used for mysql scramble function +struct rand_struct { + unsigned long seed1,seed2,max_value; + double max_value_dbl; +}; + + +void make_scrambled_password(char *,const char *); +char *scramble(char *,const char *,const char *, int); + +//test cases +static struct fmt_tests mysql_tests[] = { + {"30f098972cc8924d", "http://guh.nu"}, + {"3fc56f6037218993", "Andrew Hintz"}, + {"697a7de87c5390b2", "drew"}, + {"1eb71cf460712b3e", "http://4tphi.net"}, + {"28ff8d49159ffbaf", "http://violating.us"}, + {"5d2e19393cc5ef67", "password"}, + {NULL} +}; + + +//stores the ciphertext for value currently being tested +static char crypt_key[BINARY_SIZE+1]; + +//used by set_key +static char saved_key[PLAINTEXT_LENGTH + 1]; + +static int mysql_valid(char *ciphertext) { //returns 0 for invalid ciphertexts + + int i; //used as counter in loop + + //ciphertext is 16 characters + if (strlen(ciphertext) != 16) return 0; + + //ciphertext is ASCII representation of hex digits + for (i = 0; i < 16; i++){ + if (!( ((48 <= ciphertext[i])&&(ciphertext[i] <= 57)) || + ((97 <= ciphertext[i])&&(ciphertext[i] <= 102)) )) + return 0; + } + + return 1; +} + +static void mysql_set_salt(void *salt) { } + +static void mysql_set_key(char *key, int index) { + strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1); +} + +static char *mysql_get_key(int index) { + return saved_key; +} + +static int mysql_cmp_all(void *binary, int index) { //also is mysql_cmp_one + return !memcmp(binary, crypt_key, BINARY_SIZE); +} + +static int mysql_cmp_exact(char *source, int count){ + return (1); // mysql_cmp_all fallthrough? +} + +static void mysql_crypt_all(int count) { + // get plaintext input in saved_key put it into ciphertext crypt_key + make_scrambled_password(crypt_key,saved_key); +} + +//////////////////////////////////////////////////////////////// +//begin mysql code +// This code was copied from mysqlpassword.c by Chris Given +// He probably copied it from password.c in the MySQL source +// The code is GPLed + +void randominit(struct rand_struct *rand_st,unsigned long seed1, unsigned long seed2) { + rand_st->max_value= 0x3FFFFFFFL; + rand_st->max_value_dbl=(double) rand_st->max_value; + rand_st->seed1=seed1%rand_st->max_value ; + rand_st->seed2=seed2%rand_st->max_value; +} +static void old_randominit(struct rand_struct *rand_st,unsigned long seed1) { + rand_st->max_value= 0x01FFFFFFL; + rand_st->max_value_dbl=(double) rand_st->max_value; + seed1%=rand_st->max_value; + rand_st->seed1=seed1 ; rand_st->seed2=seed1/2; +} +double rnd(struct rand_struct *rand_st) { + rand_st->seed1=(rand_st->seed1*3+rand_st->seed2) % + rand_st->max_value; + rand_st->seed2=(rand_st->seed1+rand_st->seed2+33) % + rand_st->max_value; + return(((double) rand_st->seed1)/rand_st->max_value_dbl); +} +void hash_password(unsigned long *result, const char *password) { + register unsigned long nr=1345345333L, add=7, nr2=0x12345671L; + unsigned long tmp; + for (; *password ; password++) { + if (*password == ' ' || *password == '\t') + continue; + tmp= (unsigned long) (unsigned char) *password; + nr^= (((nr & 63)+add)*tmp)+ (nr << 8); + nr2+=(nr2 << 8) ^ nr; + add+=tmp; + } + result[0]=nr & (((unsigned long) 1L << 31) -1L); /* Don't use sign bit + (str2int) */; + result[1]=nr2 & (((unsigned long) 1L << 31) -1L); + return; +} +void make_scrambled_password(char *to,const char *password) { + unsigned long hash_res[2]; + hash_password(hash_res,password); + sprintf(to,"%08lx%08lx",hash_res[0],hash_res[1]); +} +static inline unsigned int char_val(char X) { + return (unsigned int) (X >= '0' && X <= '9' ? X-'0' : X >= 'A' && X <= 'Z' ? + X-'A'+10 : X-'a'+10); +} +char *scramble(char *to,const char *message,const char *password, int + old_ver) { + struct rand_struct rand_st; + unsigned long hash_pass[2],hash_message[2]; + if(password && password[0]) { + char *to_start=to; + hash_password(hash_pass,password); + hash_password(hash_message,message); + if (old_ver) + old_randominit(&rand_st,hash_pass[0] ^ + hash_message[0]); + else + randominit(&rand_st,hash_pass[0] ^ hash_message[0], + hash_pass[1] ^ hash_message[1]); + while (*message++) + *to++= (char) (floor(rnd(&rand_st)*31)+64); + if (!old_ver) { + char extra=(char) (floor(rnd(&rand_st)*31)); + while(to_start != to) + *(to_start++)^=extra; + } + } + *to=0; + return to; +} + +//end mysql code +//////////////////////////////////////////////////////////////// + +struct fmt_main fmt_MYSQL = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + mysql_tests + }, { + fmt_default_init, + mysql_valid, + fmt_default_split, + fmt_default_binary, + fmt_default_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + mysql_set_salt, + mysql_set_key, + mysql_get_key, + fmt_default_clear_keys, + mysql_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + mysql_cmp_all, + mysql_cmp_all, //should it be the same as cmp_all or same as cmp_exact? + mysql_cmp_exact //fallthrough + } +}; diff -urpN john-1.7.2.orig/src/Makefile john-1.7.2/src/Makefile --- john-1.7.2.orig/src/Makefile 2006-05-15 16:38:00 +0000 +++ john-1.7.2/src/Makefile 2008-04-21 05:11:51 +0000 @@ -1,4 +1,4 @@ -# + # This file is part of John the Ripper password cracker, # Copyright (c) 1996-2006 by Solar Designer # @@ -15,25 +15,57 @@ 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 OPT_NORMAL = -funroll-loops OPT_INLINE = -finline-functions +LIBS = -L/usr/local/lib -L/usr/local/ssl/lib -lcrypto -lm 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 \ + DOMINOSEC_fmt.o \ + lotus5_fmt.o \ + oracle_fmt.o \ + MYSQL_fmt.o \ + mysqlSHA1_fmt.o \ + KRB5_fmt.o KRB5_std.o \ + md5_go.o \ + rawMD5go_fmt.o \ + PO_fmt.o \ + md5.o \ + hmacmd5.o \ + hmacMD5_fmt.o \ + IPB2_fmt.o \ + rawSHA1_fmt.o \ + saltSHA1_fmt.o \ + NSLDAP_fmt.o NSLDAPS_fmt.o sha1.o base64.o \ + NT_fmt.o \ + md4.o smbencrypt.o \ + mscash_fmt.o \ + NETLM_fmt.o \ + NETNTLM_fmt.o \ + NETLMv2_fmt.o \ + NETHALFLM_fmt.o \ + mssql_fmt.o \ + mssql05_fmt.o \ + EPI_fmt.o \ + PHPS_fmt.o \ + MYSQL_fast_fmt.o \ 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 \ unshadow.o \ unafs.o \ + undrop.o \ unique.o JOHN_OBJS_ORIG = \ @@ -66,11 +98,11 @@ 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 +PROJ = ../run/john ../run/unshadow ../run/unafs ../run/unique ../run/undrop 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 default: @echo "To build John the Ripper, type:" @@ -139,12 +171,12 @@ default: 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 @@ -165,7 +197,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" @@ -173,7 +205,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" @@ -230,13 +262,13 @@ ppc-alti-linux.o: ppc-alti.c DES_bs_a.c 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: @@ -264,13 +296,13 @@ freebsd-alpha: 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: @@ -500,9 +532,9 @@ macosx-ppc32: $(LN) ppc32.h arch.h $(MAKE) $(PROJ) \ CPP=cc CC=cc AS=cc LD=cc \ - CFLAGS="-c -traditional-cpp" \ - OPT_NORMAL="-O2" \ - OPT_INLINE="-O3" + CFLAGS="-c -Wall -fomit-frame-pointer" \ + OPT_NORMAL="-fast -mcpu=750" \ + OPT_INLINE="-fast -mcpu=750 -finline-limit=4000" # This is slightly slower than macosx-ppc32-altivec for most hash types. macosx-ppc64-altivec: @@ -530,17 +562,17 @@ ppc-alti-macosx.o: ppc-alti.c DES_bs_a.c macosx-x86-sse2: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o x86-sse.o" \ - ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DBSD -DALIGN_LOG" - CPP=cc CC=cc AS=cc LD=cc \ - CFLAGS="-c -traditional-cpp" \ - OPT_NORMAL="-O2" \ - OPT_INLINE="-O3" + JOHN_OBJS="$(JOHN_OBJS) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ + ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DBSD -DALIGN_LOG" \ + CPP=gcc-4.0 CC=gcc-4.0 AS=gcc-4.0 LD=gcc-4.0 \ + CFLAGS="-c -O3 -fstrict-aliasing -funroll-loops -ffast-math -mdynamic-no-pic -mtune=pentium4 -msse2" \ + OPT_NORMAL="" \ + OPT_INLINE="" macosx-x86-mmx: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS) x86.o x86-mmx.o" \ + JOHN_OBJS="$(JOHN_OBJS) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES -DBSD -DALIGN_LOG" CPP=cc CC=cc AS=cc LD=cc \ CFLAGS="-c -traditional-cpp" \ @@ -591,7 +623,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" @@ -605,15 +637,15 @@ 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" \ - CFLAGS="$(CFLAGS) -mpreferred-stack-boundary=2" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" \ + CFLAGS="-c -O3 -fstrict-aliasing -ffast-math -mtune=pentium4 -msse2 -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" \ - CFLAGS="$(CFLAGS) -mpreferred-stack-boundary=2" \ + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" \ + CFLAGS="-c -O3 -fstrict-aliasing -ffast-math -mtune=pentium4 -mpreferred-stack-boundary=2" \ ASFLAGS="$(ASFLAGS) -DUNDERSCORES" win32-cygwin-x86-any: @@ -626,12 +658,12 @@ win32-cygwin-x86-any: beos-x86-sse2: $(LN) x86-sse.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o" + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-sse.o sha1-mmx.o md5-mmx.o" beos-x86-mmx: $(LN) x86-mmx.h arch.h $(MAKE) $(PROJ) \ - JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o" + JOHN_OBJS="$(JOHN_OBJS_MINIMAL) x86.o x86-mmx.o sha1-mmx.o md5-mmx.o" beos-x86-any: $(LN) x86-any.h arch.h @@ -657,7 +689,7 @@ bench: $(BENCH_OBJS) $(LD) $(LDFLAGS) $(BENCH_OBJS) -o bench ../run/john: $(JOHN_OBJS) - $(LD) $(LDFLAGS) $(JOHN_OBJS) -o ../run/john + $(LD) $(LDFLAGS) $(JOHN_OBJS) -o ../run/john $(LIBS) ../run/unshadow: ../run/john $(RM) ../run/unshadow @@ -667,6 +699,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 @@ -685,6 +721,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 @@ -692,7 +731,7 @@ john.com: john.asm @echo Use Borland TASM/TLINK to make JOHN.COM ../run/john.exe: $(JOHN_OBJS) - $(LD) $(JOHN_OBJS) -lkernel32 -o ../run/john.exe + $(LD) $(JOHN_OBJS) -lkernel32 -lssl -lcrypto -o ../run/john.exe strip ../run/john.exe ../run/unshadow.exe: symlink.c @@ -703,6 +742,10 @@ 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 diff -urpN john-1.7.2.orig/src/NETHALFLM_fmt.c john-1.7.2/src/NETHALFLM_fmt.c --- john-1.7.2.orig/src/NETHALFLM_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/NETHALFLM_fmt.c 2008-02-20 14:30:47 +0000 @@ -0,0 +1,219 @@ +/* + * NETHALFLM_fmt.c + * Written by DSK (Based on NetLM/NetNTLM patch by JoMo-Kun) + * Performs brute-force cracking of the HalfLM challenge/response pairs. + + * Storage Format: + * domain\username:::lm response:nt response:challenge + * + * Code is in public domain. + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "nethalflm" +#define FORMAT_NAME "HalfLM C/R DES" +#define ALGORITHM_NAME "nethalflm" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 7 +#define BINARY_SIZE 8 +#define SALT_SIZE 8 +#define CIPHERTEXT_LENGTH 48 +#define TOTAL_LENGTH 12 + 2 * SALT_SIZE + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETHALFLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD", "G3RG3P00!"}, + {"$NETHALFLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD", "G3RG3P0"}, + {"$NETHALFLM$1122334455667788$1354FD5ABF3B627B8B49587B8F2BBA0F9F6C5E420824E0A2", "ZEEEZ@1"}, + {NULL} +}; + +static char saved_plain[PLAINTEXT_LENGTH + 1]; +static uchar challenge[SALT_SIZE + 1]; +static uchar output[BINARY_SIZE + 1]; + +static int nethalflm_valid(char *ciphertext) +{ + char *pos; + + if (strncmp(ciphertext, "$NETHALFLM$", 11)!=0) return 0; + if (ciphertext[27] != '$') return 0; + + for (pos = &ciphertext[28]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); + if (!*pos && pos - ciphertext - 28 == CIPHERTEXT_LENGTH) { + return 1; + } + else + return 0; +} + +static char *nethalflm_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1] = {0}; + + memcpy(&out, ciphertext, TOTAL_LENGTH); + strlwr(&out[10]); /* Exclude: $NETHALFLM$ */ + return out; +} + +static void *nethalflm_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + int i; + + ciphertext+=28; + for (i=0; i> 1); + key[2] = (key_56[1] << 6) | (key_56[2] >> 2); + key[3] = (key_56[2] << 5) | (key_56[3] >> 3); + key[4] = (key_56[3] << 4) | (key_56[4] >> 4); + key[5] = (key_56[4] << 3) | (key_56[5] >> 5); + key[6] = (key_56[5] << 2) | (key_56[6] >> 6); + key[7] = (key_56[6] << 1); + + des_set_key(&key, *ks); +} + +static void nethalflm_crypt_all(int count) +{ + static unsigned char magic[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + des_key_schedule ks; + unsigned char password[7 + 1]; + unsigned char lm[7]; + + /* clear buffers */ + memset(lm, 0, 7); + memset(output, 0, 8); + + strncpy((char *) password, saved_plain, 7); + /* Generate first 8-bytes of LM hash */ + setup_des_key(password, &ks); + des_ecb_encrypt((des_cblock*)magic, (des_cblock*)lm, ks, DES_ENCRYPT); + + /* DES-encrypt challenge using LM hash */ + setup_des_key(lm, &ks); + des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)output, ks, DES_ENCRYPT); + /*printf("\nLM Response: "); + int i; + for( i = 0; i< BINARY_SIZE ;i++) + printf("%.2x",output[i]); */ +} + +static int nethalflm_cmp_all(void *binary, int count) +{ + return !memcmp(output, binary, 8); +} + +static int nethalflm_cmp_one(void *binary, int index) +{ + return !memcmp(output, binary, 8); +} + +static int nethalflm_cmp_exact(char *source, int index) +{ + return !memcmp(output, nethalflm_get_binary(source), 8); +} + +static void *nethalflm_get_salt(char *ciphertext) +{ + static unsigned char binary_salt[SALT_SIZE]; + int i; + + ciphertext += 11; + for (i = 0; i < SALT_SIZE; ++i) { + binary_salt[i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + /*printf("%.2x",binary_salt[i]);*/ + } + return (void*)binary_salt; +} + +static void nethalflm_set_salt(void *salt) +{ + memcpy(challenge, salt, SALT_SIZE); +} + +static void nethalflm_set_key(char *key, int index) +{ + int i; + + strncpy(saved_plain, key, PLAINTEXT_LENGTH); + + /* Upper-case password */ + for(i=0; i= 'a') && (saved_plain[i] <= 'z')) saved_plain[i] ^= 0x20; +} + +static char *nethalflm_get_key(int index) +{ + return saved_plain; +} + +struct fmt_main fmt_NETHALFLM = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + fmt_default_init, + nethalflm_valid, + nethalflm_split, + nethalflm_get_binary, + nethalflm_get_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + nethalflm_set_salt, + nethalflm_set_key, + nethalflm_get_key, + fmt_default_clear_keys, + nethalflm_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + nethalflm_cmp_all, + nethalflm_cmp_one, + nethalflm_cmp_exact + } +}; + diff -urpN john-1.7.2.orig/src/NETLM_fmt.c john-1.7.2/src/NETLM_fmt.c --- john-1.7.2.orig/src/NETLM_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/NETLM_fmt.c 2008-02-20 14:19:35 +0000 @@ -0,0 +1,249 @@ +/* + * NETLM_fmt.c -- LM Challenge/Response + * + * Written by JoMo-Kun in 2007 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the LM + * challenge/response pairs exchanged during network-based authentication + * attempts [1]. The captured challenge/response pairs from these attempts + * should be stored using the L0phtCrack 2.0 LC format, specifically: + * username:unused:unused:lm response:ntlm response:challenge. For example: + * + * CORP\Administrator:::25B2B477CE101D83648BB087CE7A1C217F51C7FC64C0EBB1:: + * C8BD0C1630A9ECF7A95F494A8F0B2CB4A3F25B1225514304:1122334455667788 + * + * It should be noted that a LM authentication response is not same as a LM + * password hash, which can be extracted using tools such as FgDump [2]. LM + * responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theLmResponse + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netlm" +#define FORMAT_NAME "LM C/R DES" +#define ALGORITHM_NAME "netlm" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 14 +#define BINARY_SIZE 24 +#define SALT_SIZE 8 +#define CIPHERTEXT_LENGTH 48 +#define TOTAL_LENGTH 8 + 2 * SALT_SIZE + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETLM$1122334455667788$6E1EC36D3417CE9E09A4424309F116C4C991948DAEB4ADAD", "G3RG3P00!"}, + {"$NETLM$1122334455667788$16A7FDFE0CA109B937BFFB041F0E5B2D8B94A97D3FCA1A18", "HIYAGERGE"}, + {"$NETLM$1122334455667788$B3A1B87DBBD4DF3CFA296198DD390C2F4E2E93C5C07B1D8B", "MEDUSAFGDUMP12"}, + {"$NETLM$1122334455667788$0836F085B124F33895875FB1951905DD2F85252CC731BB25", "CORY21"}, + {NULL} +}; + +static char saved_plain[PLAINTEXT_LENGTH + 1]; +static uchar challenge[SALT_SIZE + 1]; +static uchar output[BINARY_SIZE + 1]; + +static int netlm_valid(char *ciphertext) +{ + char *pos; + + if (strncmp(ciphertext, "$NETLM$", 5)!=0) return 0; + if (ciphertext[23] != '$') return 0; + + for (pos = &ciphertext[24]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); + if (!*pos && pos - ciphertext - 24 == CIPHERTEXT_LENGTH) + return 1; + else + return 0; +} + +static char *netlm_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, TOTAL_LENGTH); + strlwr(&out[6]); /* Exclude: $NETLM$ */ + + return out; +} + +static void *netlm_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + int i; + + ciphertext+=24; + for (i=0; i> 1); + key[2] = (key_56[1] << 6) | (key_56[2] >> 2); + key[3] = (key_56[2] << 5) | (key_56[3] >> 3); + key[4] = (key_56[3] << 4) | (key_56[4] >> 4); + key[5] = (key_56[4] << 3) | (key_56[5] >> 5); + key[6] = (key_56[5] << 2) | (key_56[6] >> 6); + key[7] = (key_56[6] << 1); + + des_set_key(&key, *ks); +} + +static void netlm_crypt_all(int count) +{ + static unsigned char magic[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + des_key_schedule ks; + unsigned char password[14 + 1]; + unsigned char lm[21]; + + memset(password, 0, 14 + 1); + memset(lm, 0, 21); + memset(output, 0, 24); + + strncpy((char *) password, saved_plain, 14); + + /* Generate 16-byte LM hash */ + setup_des_key(password, &ks); + des_ecb_encrypt((des_cblock*)magic, (des_cblock*)lm, ks, DES_ENCRYPT); + setup_des_key(&password[7], &ks); + des_ecb_encrypt((des_cblock*)magic, (des_cblock*)&lm[8], ks, DES_ENCRYPT); + + /* + NULL-pad 16-byte LM hash to 21-bytes + Split resultant value into three 7-byte thirds + DES-encrypt challenge using each third as a key + Concatenate three 8-byte resulting values to form 24-byte LM response + */ + setup_des_key(lm, &ks); + des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)output, ks, DES_ENCRYPT); + setup_des_key(&lm[7], &ks); + des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)&output[8], ks, DES_ENCRYPT); + setup_des_key(&lm[14], &ks); + des_ecb_encrypt((des_cblock*)challenge, (des_cblock*)&output[16], ks, DES_ENCRYPT); +} + +static int netlm_cmp_all(void *binary, int count) +{ + return !memcmp(output, binary, BINARY_SIZE); +} + +static int netlm_cmp_one(void *binary, int index) +{ + return !memcmp(output, binary, BINARY_SIZE); +} + +static int netlm_cmp_exact(char *source, int index) +{ + return !memcmp(output, netlm_get_binary(source), BINARY_SIZE); +} + +static void *netlm_get_salt(char *ciphertext) +{ + static unsigned char binary_salt[SALT_SIZE]; + int i; + + ciphertext += 7; + for (i = 0; i < SALT_SIZE; ++i) + binary_salt[i] = (atoi16[ARCH_INDEX(ciphertext[i*2])] << 4) + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + + return (void*)binary_salt; +} + +static void netlm_set_salt(void *salt) +{ + memcpy(challenge, salt, SALT_SIZE); +} + +static void netlm_set_key(char *key, int index) +{ + int i; + + memset(saved_plain, 0, PLAINTEXT_LENGTH + 1); + strncpy(saved_plain, key, PLAINTEXT_LENGTH); + + /* Upper-case password */ + for(i=0; i= 'a') && (saved_plain[i] <= 'z')) saved_plain[i] ^= 0x20; +} + +static char *netlm_get_key(int index) +{ + return saved_plain; +} + +struct fmt_main fmt_NETLM = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_8_BIT | FMT_BS | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + fmt_default_init, + netlm_valid, + netlm_split, + netlm_get_binary, + netlm_get_salt, + { + fmt_default_binary_hash, + fmt_default_binary_hash, + fmt_default_binary_hash + }, + fmt_default_salt_hash, + netlm_set_salt, + netlm_set_key, + netlm_get_key, + fmt_default_clear_keys, + netlm_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + netlm_cmp_all, + netlm_cmp_one, + netlm_cmp_exact + } +}; diff -urpN john-1.7.2.orig/src/NETLMv2_fmt.c john-1.7.2/src/NETLMv2_fmt.c --- john-1.7.2.orig/src/NETLMv2_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/NETLMv2_fmt.c 2008-04-21 07:11:55 +0000 @@ -0,0 +1,361 @@ +/* + * NETLMv2_fmt.c -- LMv2 Challenge/Response + * + * Written by JoMo-Kun in 2008 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the LMv2 + * challenge/response sets exchanged during network-based authentication + * attempts [1]. The captured challenge/response set from these attempts + * should be stored using the following format: + * + * USERNAME::DOMAIN:SERVER CHALLENGE:LMv2 RESPONSE:CLIENT CHALLENGE + * + * For example: + * Administrator::WORKGROUP:1122334455667788:6759A5A7EFB25452911DE7DE8296A0D8:F503236B200A5B3A + * + * It should be noted that a LMv2 authentication response is not same as a LM + * password hash, which can be extracted using tools such as FgDump [2]. In + * fact, a NTLM hash and not a LM hash is used within the LMv2 algorithm. LMv2 + * challenge/response authentication typically takes place when the GPO + * "Network Security: LAN Manager authentication level" is configured to a setting + * that enforces the use of NTLMv2, such as "Send NTLMv2 response only\refuse + * LM & NTLM." + * + * LMv2 responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theLmv2Response + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include "md5.h" +#include "hmacmd5.h" + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netlmv2" +#define FORMAT_NAME "LMv2 C/R MD4 HMAC-MD5" +#define ALGORITHM_NAME "netlmv2" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 54 /* lmcons.h - PWLEN (256) ? 127 ? */ +#define USERNAME_LENGTH 20 /* lmcons.h - UNLEN (256) / LM20_UNLEN (20) */ +#define DOMAIN_LENGTH 15 /* lmcons.h - CNLEN / DNLEN */ +#define BINARY_SIZE 16 +#define CHALLENGE_LENGTH 32 +#define SALT_SIZE 16 + USERNAME_LENGTH + DOMAIN_LENGTH +#define CIPHERTEXT_LENGTH 32 +#define TOTAL_LENGTH 12 + USERNAME_LENGTH + DOMAIN_LENGTH + CHALLENGE_LENGTH + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETLMv2$ADMINISTRATORFOODOM$1122334455667788$6F64C5C1E35F68DD80388C0F00F34406$F0F3FF27037AA69F", "1337adminPASS"}, + {"$NETLMv2$USER1$1122334455667788$B1D163EA5881504F3963DC50FCDC26C1$EB4D9E8138149E20", "foobar"}, + {"$NETLMv2$ATEST$1122334455667788$83B59F1536D3321DBF1FAEC14ADB1675$A1E7281FE8C10E53", "SomeFancyP4$$w0rdHere"}, + {NULL} +}; + +uchar saved_plain[PLAINTEXT_LENGTH + 1]; +uchar challenge[SALT_SIZE + 1]; +uchar output[BINARY_SIZE + 1]; + +extern void E_md4hash(uchar *passwd, uchar *p16); +extern void hmac_md5_init_limK_to_64(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_update(const unsigned char*, int, HMACMD5Context*); +extern void hmac_md5_final(unsigned char*, HMACMD5Context*); + +#if !defined(uint16) && !defined(HAVE_UINT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define uint16 unsigned short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#if !defined(int16) && !defined(HAVE_INT16_FROM_RPC_RPC_H) +#if (SIZEOF_SHORT == 4) +#define int16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16; +#else /* SIZEOF_SHORT != 4 */ +#define int16 short +#endif /* SIZEOF_SHORT != 4 */ +#endif + +#include "byteorder.h" + +/* Routines for Windows NT MD4 Hash functions. */ +static int lmv2_wcslen(int16 *str) +{ + int len = 0; + while(*str++ != 0) + len++; + return len; +} + +/* + * Convert a string into an NT UNICODE string. + * Note that regardless of processor type + * this must be in intel (little-endian) + * format. + */ +int lmv2_mbstowcs(int16 *dst, uchar *src, int len) +{ + int i; + int16 val; + + for(i = 0; i < len; i++) { + val = *src; + SSVAL(dst,0,val); + dst++; + src++; + if(val == 0) + break; + } + return i; +} + +static int netlmv2_valid(char *ciphertext) +{ + char *pos, *pos2; + + if (ciphertext == NULL) return 0; + else if (strncmp(ciphertext, "$NETLMv2$", 9)!=0) return 0; + + pos = &ciphertext[9]; + + /* Validate Username and Domain Length */ + for (pos2 = pos; strncmp(pos2, "$", 1) != 0; pos2++) + if ( (*pos2 < 0x20) || (*pos2 > 0x7E) ) + return 0; + + if ( !(*pos2 && (pos2 - pos <= USERNAME_LENGTH + DOMAIN_LENGTH)) ) + return 0; + + /* Validate Server Challenge Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == CHALLENGE_LENGTH / 2)) ) + return 0; + + /* Validate LMv2 Response Length */ + pos2++; pos = pos2; + for (; strncmp(pos2, "$", 1) != 0; pos2++) + if (atoi16[ARCH_INDEX(*pos2)] == 0x7F) + return 0; + + if ( !(*pos2 && (pos2 - pos == CIPHERTEXT_LENGTH)) ) + return 0; + + /* Validate Client Challenge Length */ + pos2++; pos = pos2; + for (; atoi16[ARCH_INDEX(*pos2)] != 0x7F; pos2++); + if (pos2 - pos != CHALLENGE_LENGTH / 2) + return 0; + + return 1; +} + +static char *netlmv2_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + char *pos = NULL; + int identity_length = 0; + + /* Calculate identity length */ + for (pos = ciphertext + 9; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 9); + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, strlen(ciphertext)); + strlwr(&out[10 + identity_length]); /* Exclude: $NETLMv2$USERDOMAIN$ */ + + return out; +} + +static void *netlmv2_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + char *pos = NULL; + int i, identity_length; + + for (pos = ciphertext + 9; strncmp(pos, "$", 1) != 0; pos++); + identity_length = pos - (ciphertext + 9); + + ciphertext += 9 + identity_length + 1 + CHALLENGE_LENGTH / 2 + 1; + for (i=0; i in 2007 + * and placed in the public domain. + * + * This algorithm is designed for performing brute-force cracking of the NTLM + * (version 1) challenge/response pairs exchanged during network-based + * authentication attempts [1]. The captured challenge/response pairs from these + * attempts should be stored using the L0phtCrack 2.0 LC format, specifically: + * username:unused:unused:lm response:ntlm response:challenge. For example: + * + * CORP\Administrator:::25B2B477CE101D83648BB087CE7A1C217F51C7FC64C0EBB1:: + * C8BD0C1630A9ECF7A95F494A8F0B2CB4A3F25B1225514304:1122334455667788 + * + * It should be noted that a NTLM authentication response is not same as a NTLM + * password hash, which can be extracted using tools such as FgDump [2]. NTLM + * responses can be gathered via normal network capture or via tools which + * perform layer 2 attacks, such as Ettercap [3] and Cain [4]. The responses can + * also be harvested using a modified Samba service [5] in conjunction with + * some trickery to convince the user to connect to it. I leave what that + * trickery may actually be as an exercise for the reader (HINT: Karma, NMB + * broadcasts, IE, Outlook, social engineering, ...). + * + * [1] http://davenport.sourceforge.net/ntlm.html#theNtLmResponse + * [2] http://www.foofus.net/fizzgig/fgdump/ + * [3] http://ettercap.sourceforge.net/ + * [4] http://www.oxid.it/cain.html + * [5] http://www.foofus.net/jmk/smbchallenge.html + * + */ + +#include +#include + +#include "misc.h" +#include "common.h" +#include "formats.h" + +#include + +#ifndef uchar +#define uchar unsigned char +#endif + +#define FORMAT_LABEL "netntlm" +#define FORMAT_NAME "NTLMv1 C/R MD4 DES" +#define ALGORITHM_NAME "netntlm" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 +#define PLAINTEXT_LENGTH 54 /* ?127? */ +#define BINARY_SIZE 24 +#define SALT_SIZE 8 +#define CIPHERTEXT_LENGTH 48 +#define TOTAL_LENGTH 10 + 2 * SALT_SIZE + CIPHERTEXT_LENGTH +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests tests[] = { + {"$NETNTLM$1122334455667788$BFCCAF26128EC95F9999C9792F49434267A1D9B0EF89BFFB", "g3rg3g3rg3g3rg3"}, + {"$NETNTLM$1122334455667788$E463FAA5D868ECE20CAE622474A2F440A652D642156AF863", "M1xedC4se%^&*@)##(blahblah!@#"}, + {"$NETNTLM$1122334455667788$35B62750E1B9B3205C50D6BA351092C12A1B9B3CDC65D44A", "FooBarGerg"}, + {"$NETNTLM$1122334455667788$A4765EBFE83D345A7CB1660B8899251905164029F8086DDE", "visit www.foofus.net"}, + {"$NETNTLM$1122334455667788$B2B2220790F40C88BCFF347C652F67A7C4A70D3BEBD70233", "cory21"}, + {NULL} +}; + +static char saved_plain[PLAINTEXT_LENGTH + 1]; +static uchar challenge[SALT_SIZE + 1]; +static uchar output[BINARY_SIZE + 1]; + +extern void E_md4hash(uchar *passwd, uchar *p16); +extern void setup_des_key(unsigned char key_56[], des_key_schedule *ks); + +static int netntlm_valid(char *ciphertext) +{ + char *pos; + + if (strncmp(ciphertext, "$NETNTLM$", 9)!=0) return 0; + if (ciphertext[25] != '$') return 0; + + for (pos = &ciphertext[26]; atoi16[ARCH_INDEX(*pos)] != 0x7F; pos++); + if (!*pos && pos - ciphertext - 26 == CIPHERTEXT_LENGTH) + return 1; + else + return 0; +} + +static char *netntlm_split(char *ciphertext, int index) +{ + static char out[TOTAL_LENGTH + 1]; + + memset(out, 0, TOTAL_LENGTH + 1); + memcpy(&out, ciphertext, TOTAL_LENGTH); + strlwr(&out[8]); /* Exclude: $NETNTLM$ */ + + return out; +} + +static void *netntlm_get_binary(char *ciphertext) +{ + static uchar binary[BINARY_SIZE]; + int i; + + ciphertext+=26; + for (i=0; i + +#include "misc.h" +#include "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 SHA1" + +#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}ypkVeJKLzbXakEpuPYbn+YBnQvFmNmB+kQhmWQ==", "qVv3uQ45"}, + {"{SSHA}cKFVqtf358j0FGpPsEIK1xh3T0mtDNV1kAaBNg==", "salles"}, + {"{SSHA}WTT3B9Jjr8gOt0Q7WMs9/XvukyhTQj0Ns0jMKQ==", "Password9"}, + {NULL} +}; + +#ifdef MMX_COEF +static char crypt_key[BINARY_SIZE*MMX_COEF]; +static char saved_key[80*MMX_COEF]; +static unsigned long total_len; +static unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(8*MMX_COEF))); +static unsigned char out[PLAINTEXT_LENGTH]; +#else +static char crypt_key[BINARY_SIZE]; +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 ((int *)binary)[0] & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return ((int *)binary)[0] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((int *)binary)[0] & 0xFFF; +} + +static int get_hash_0(int index) +{ + return ((int *)crypt_key)[index] & 0xF; +} + +static int get_hash_1(int index) +{ + return ((int *)crypt_key)[index] & 0xFF; +} + +static int get_hash_2(int index) +{ + return ((int *)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)); + 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++; + } +#else + while(i + +#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 "SHA1" + +#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 +static char crypt_key[BINARY_SIZE*MMX_COEF]; +static char saved_key[(PLAINTEXT_LENGTH+1)*MMX_COEF]; +unsigned long total_len; +unsigned char buffer[80*4*MMX_COEF] __attribute__ ((aligned(8*MMX_COEF))); +unsigned char out[PLAINTEXT_LENGTH]; +#else +static char crypt_key[BINARY_SIZE]; +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 ((int *)binary)[0] & 0xF; +} + +static int binary_hash_1(void *binary) +{ + return ((int *)binary)[0] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((int *)binary)[0] & 0xFFF; +} + +static int get_hash_0(int index) +{ + return ((int *)crypt_key)[index] & 0xF; +} + +static int get_hash_1(int index) +{ + return ((int *)crypt_key)[index] & 0xFF; +} + +static int get_hash_2(int index) +{ + return ((int *)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++; + } +#else + while(i 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 "X86-64 SSE2 8x" + #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 "X86 SSE2 5x" + #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 "Generic 1x" + #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_lenght=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_lenght;i++) + nt_buffer1x[i+buff_base]=0; + + last_i[index]=md4_size>>1; + + nt_buffer1x[14+buff_base] = md4_size << 4; + } +#else + buff_base=index<<4; + + for(;key[md4_size] && md4_size>1; + + nt_buffer1x[buff_base+14] = md4_size << 4; +#endif +} + +static char *get_key(int index) +{ + return saved_plain+(index<<5); +} + +struct fmt_main fmt_NT = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + fmt_NT_init, + valid, + nt_split, + get_binary, + fmt_default_salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2 + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + NT_CRYPT_FUN, + { + get_hash_0, + get_hash_1, + get_hash_2 + }, + cmp_all, + cmp_one, + cmp_exact + } +}; diff -urpN john-1.7.2.orig/src/PHPS_fmt.c john-1.7.2/src/PHPS_fmt.c --- john-1.7.2.orig/src/PHPS_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/PHPS_fmt.c 2007-11-26 20:31:30 +0000 @@ -0,0 +1,263 @@ +/* + * PHPS_fmt.c + * + * Salted PHP on the form (php-code): $hash = MD5(MD5($pass).$salt); + * Based on salted IPB2 mode (by regenrecht@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_salt_hash, + phps_set_salt, + phps_set_key, + phps_get_key, + fmt_default_clear_keys, + phps_crypt_all, + { + fmt_default_get_hash, + fmt_default_get_hash, + fmt_default_get_hash + }, + phps_cmp_all, + phps_cmp_all, + phps_cmp_exact + } +}; + + +/** + * GNU Emacs settings: K&R with 1 tab indent. + * Local Variables: + * c-file-style: "k&r" + * c-basic-offset: 8 + * indent-tabs-mode: t + * End: + */ diff -urpN john-1.7.2.orig/src/PO_fmt.c john-1.7.2/src/PO_fmt.c --- john-1.7.2.orig/src/PO_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/PO_fmt.c 2008-02-20 14:19:35 +0000 @@ -0,0 +1,222 @@ +/* + * 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 + +#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_bitswapped_out +#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 +#include + +void base64_unmap(char *in_block) { + int i; + char *c; + + for(i=0; i<4; i++) { + c = in_block + i; + + if(*c>='A' && *c<='Z') { + *c -= 'A'; + continue; + } + + if(*c>='a' && *c<='z') { + *c -= 'a'; + *c += 26; + continue; + } + + if(*c == '+') { + *c = 62; + continue; + } + + if(*c == '/') { + *c = 63; + continue; + } + + if(*c == '=') { + *c = 0; + } + + *c -= '0'; + *c += 52; + } +} + +int base64_decode(char *in, int inlen, char *out) { + int i; + char *in_block; + char *out_block; + char temp[4]; + + out_block = out; + in_block = in; + + for(i=0; i + * 2002-04-16 +*/ + +#include + +#include "blowfish.h" +#include "bf_tab.h" /* P-box P-array, S-box */ + +/* #define S(x,i) (bf_S[i][x.w.byte##i]) */ +#define S0(x) (bf_S[0][x.w.byte0]) +#define S1(x) (bf_S[1][x.w.byte1]) +#define S2(x) (bf_S[2][x.w.byte2]) +#define S3(x) (bf_S[3][x.w.byte3]) +#define bf_F(x) (((S0(x) + S1(x)) ^ S2(x)) + S3(x)) +#define ROUND(a,b,n) (a.word ^= bf_F(b) ^ bf_P[n]) + +#include + +/* keep a set of rotating P & S boxes */ +static struct box_t { + UWORD_32bits *P; + UWORD_32bits **S; + char key[81]; + char keybytes; +} box; + +//static UWORD_32bits bf_P[bf_N+2]; +//static UWORD_32bits bf_S[4][256]; +static UWORD_32bits *bf_P; +static UWORD_32bits **bf_S; + + +void blowfish_first_init(void) { + box.P = NULL; + box.S = NULL; + box.key[0] = 0; +} + +static void blowfish_encipher(UWORD_32bits * xl, UWORD_32bits * xr) +{ + union aword Xl; + union aword Xr; + + Xl.word = *xl; + Xr.word = *xr; + + Xl.word ^= bf_P[0]; + ROUND(Xr, Xl, 1); + ROUND(Xl, Xr, 2); + ROUND(Xr, Xl, 3); + ROUND(Xl, Xr, 4); + ROUND(Xr, Xl, 5); + ROUND(Xl, Xr, 6); + ROUND(Xr, Xl, 7); + ROUND(Xl, Xr, 8); + ROUND(Xr, Xl, 9); + ROUND(Xl, Xr, 10); + ROUND(Xr, Xl, 11); + ROUND(Xl, Xr, 12); + ROUND(Xr, Xl, 13); + ROUND(Xl, Xr, 14); + ROUND(Xr, Xl, 15); + ROUND(Xl, Xr, 16); + Xr.word ^= bf_P[17]; + + *xr = Xl.word; + *xl = Xr.word; +} + +static void blowfish_init(UBYTE_08bits * key, short keybytes) +{ + int i, j; + UWORD_32bits data; + UWORD_32bits datal; + UWORD_32bits datar; + union aword temp; + + /* is buffer already allocated for this? */ + if (box.P != NULL) { + if ((box.keybytes == keybytes) && + (!strncmp((char *) (box.key), (char *) key, keybytes))) { + /* match! */ + bf_P = box.P; + bf_S = box.S; + return; + } + free(box.P); + for (i = 0; i < 4; i++) + free(box.S[i]); + free(box.S); + } + /* initialize new buffer */ + /* uh... this is over 4k */ + box.P = (UWORD_32bits *) malloc((bf_N + 2) * sizeof(UWORD_32bits)); + box.S = (UWORD_32bits **) malloc(4 * sizeof(UWORD_32bits *)); + for (i = 0; i < 4; i++) + box.S[i] = (UWORD_32bits *) malloc(256 * sizeof(UWORD_32bits)); + bf_P = box.P; + bf_S = box.S; + box.keybytes = keybytes; + strncpy(box.key, (char *) key, keybytes); + /* robey: reset blowfish boxes to initial state */ + /* (i guess normally it just keeps scrambling them, but here it's + * important to get the same encrypted result each time) */ + for (i = 0; i < bf_N + 2; i++) + bf_P[i] = initbf_P[i]; + for (i = 0; i < 4; i++) + for (j = 0; j < 256; j++) + bf_S[i][j] = initbf_S[i][j]; + + j = 0; + for (i = 0; i < bf_N + 2; ++i) { + temp.word = 0; + temp.w.byte0 = key[j]; + temp.w.byte1 = key[(j + 1) % keybytes]; + temp.w.byte2 = key[(j + 2) % keybytes]; + temp.w.byte3 = key[(j + 3) % keybytes]; + data = temp.word; + bf_P[i] = bf_P[i] ^ data; + j = (j + 4) % keybytes; + } + datal = 0x00000000; + datar = 0x00000000; + for (i = 0; i < bf_N + 2; i += 2) { + blowfish_encipher(&datal, &datar); + bf_P[i] = datal; + bf_P[i + 1] = datar; + } + for (i = 0; i < 4; ++i) { + for (j = 0; j < 256; j += 2) { + blowfish_encipher(&datal, &datar); + bf_S[i][j] = datal; + bf_S[i][j + 1] = datar; + } + } +} + +/* stuff below this line was written by robey for eggdrop use */ + +/* of course, if you change either of these, then your userfile will + * no longer be able to be shared. :) */ +#define SALT1 0xdeadd061 +#define SALT2 0x23f6b095 + +/* convert 64-bit encrypted password to text for userfile */ +static char *base64 = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + +static void blowfish_encrypt_pass(char *text, char *new) +{ + UWORD_32bits left, right; + int n; + char *p; + + blowfish_init((UBYTE_08bits *) text, strlen(text)); + left = SALT1; + right = SALT2; + blowfish_encipher(&left, &right); + p = new; + *p++ = '+'; /* + means encrypted pass */ + n = 32; + while (n > 0) { + *p++ = base64[right & 0x3f]; + right = (right >> 6); + n -= 6; + } + n = 32; + while (n > 0) { + *p++ = base64[left & 0x3f]; + left = (left >> 6); + n -= 6; + } + *p = 0; +} diff -urpN john-1.7.2.orig/src/blowfish.h john-1.7.2/src/blowfish.h --- john-1.7.2.orig/src/blowfish.h 1970-01-01 00:00:00 +0000 +++ john-1.7.2/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.2.orig/src/byteorder.h john-1.7.2/src/byteorder.h --- john-1.7.2.orig/src/byteorder.h 1970-01-01 00:00:00 +0000 +++ john-1.7.2/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.2.orig/src/hmacMD5_fmt.c john-1.7.2/src/hmacMD5_fmt.c --- john-1.7.2.orig/src/hmacMD5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/hmacMD5_fmt.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2004 bartavelle + * bartavelle@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 +//static char saved_key[PLAINTEXT_LENGTH*MMX_COEF*2 + 1] __attribute__ ((aligned(16))); +static char crypt_key[64*MMX_COEF] __attribute__ ((aligned(16))); +unsigned long total_len; +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))); +#else +//static char saved_key[PLAINTEXT_LENGTH + 1]; +static char crypt_key[BINARY_SIZE+1]; +static MD5_CTX ctx; +unsigned char opad[PLAINTEXT_LENGTH]; +unsigned char ipad[PLAINTEXT_LENGTH]; +unsigned char cursalt[SALT_SIZE]; +#endif +unsigned char out[PLAINTEXT_LENGTH]; + +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.2.orig/src/hmacmd5.h john-1.7.2/src/hmacmd5.h --- john-1.7.2.orig/src/hmacmd5.h 1970-01-01 00:00:00 +0000 +++ john-1.7.2/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.2.orig/src/inc.c john-1.7.2/src/inc.c --- john-1.7.2.orig/src/inc.c 2006-03-05 01:14:13 +0000 +++ john-1.7.2/src/inc.c 2008-02-20 14:33:40 +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.2.orig/src/john.c john-1.7.2/src/john.c --- john-1.7.2.orig/src/john.c 2006-05-08 14:48:48 +0000 +++ john-1.7.2/src/john.c 2008-04-21 04:55:34 +0000 @@ -37,10 +37,35 @@ extern int CPU_detect(void); #endif 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_AFS, fmt_LM, fmt_NT, fmt_PO, fmt_rawMD5go; +extern struct fmt_main fmt_hmacMD5; +extern struct fmt_main fmt_IPB2; +extern struct fmt_main fmt_MD5_apache; +extern struct fmt_main fmt_BFEgg; +extern struct fmt_main fmt_KRB5; +extern struct fmt_main fmt_oracle; +extern struct fmt_main fmt_MYSQL; +extern struct fmt_main fmt_mysqlSHA1; +extern struct fmt_main fmt_NSLDAP; +extern struct fmt_main fmt_NSLDAPS; +extern struct fmt_main fmt_mscash; +extern struct fmt_main fmt_rawSHA1; +extern struct fmt_main fmt_saltSHA1; +extern struct fmt_main fmt_lotus5; +extern struct fmt_main fmt_DOMINOSEC; +extern struct fmt_main fmt_NETLM; +extern struct fmt_main fmt_NETNTLM; +extern struct fmt_main fmt_NETLMv2; +extern struct fmt_main fmt_NETHALFLM; +extern struct fmt_main fmt_mssql; +extern struct fmt_main fmt_mssql05; +extern struct fmt_main fmt_EPI; +extern struct fmt_main fmt_PHPS; +extern struct fmt_main fmt_MYSQL_fast; extern 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; @@ -48,7 +73,7 @@ static struct fmt_main dummy_format; static void john_register_one(struct fmt_main *format) { - if (options.format) + if (options.format) if (strcmp(options.format, format->params.label)) return; fmt_register(format); @@ -59,11 +84,38 @@ static void john_register_all(void) if (options.format) strlwr(options.format); john_register_one(&fmt_DES); + john_register_one(&fmt_LM); + john_register_one(&fmt_NT); + john_register_one(&fmt_mscash); john_register_one(&fmt_BSDI); john_register_one(&fmt_MD5); + john_register_one(&fmt_MD5_apache); + john_register_one(&fmt_hmacMD5); + john_register_one(&fmt_PO); + john_register_one(&fmt_rawMD5go); + john_register_one(&fmt_IPB2); + john_register_one(&fmt_rawSHA1); + john_register_one(&fmt_saltSHA1); + john_register_one(&fmt_KRB5); + john_register_one(&fmt_NSLDAP); + john_register_one(&fmt_NSLDAPS); john_register_one(&fmt_BF); + john_register_one(&fmt_BFEgg); john_register_one(&fmt_AFS); - john_register_one(&fmt_LM); + john_register_one(&fmt_oracle); + john_register_one(&fmt_MYSQL); + john_register_one(&fmt_mysqlSHA1); + john_register_one(&fmt_lotus5); + john_register_one(&fmt_DOMINOSEC); + john_register_one(&fmt_NETLM); + john_register_one(&fmt_NETNTLM); + john_register_one(&fmt_NETLMv2); + john_register_one(&fmt_NETHALFLM); + john_register_one(&fmt_mssql); + john_register_one(&fmt_mssql05); + john_register_one(&fmt_EPI); + john_register_one(&fmt_PHPS); + john_register_one(&fmt_MYSQL_fast); if (!fmt_list) { fprintf(stderr, "Unknown ciphertext format name requested\n"); @@ -348,6 +400,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.2.orig/src/loader.c john-1.7.2/src/loader.c --- john-1.7.2.orig/src/loader.c 2005-11-08 13:03:20 +0000 +++ john-1.7.2/src/loader.c 2008-04-21 04:53:11 +0000 @@ -18,6 +18,7 @@ #include "signals.h" #include "formats.h" #include "loader.h" +#include "options.h" /* * Flags for read_file(). @@ -183,7 +184,7 @@ static int ldr_check_shells(struct list_ static int ldr_split_line(char **login, char **ciphertext, char **gecos, char **home, char *source, struct fmt_main **format, - struct db_options *options, char *line) + struct db_options *db_options, char *line) { char *uid = NULL, *gid = NULL, *shell = NULL; char *tmp; @@ -206,10 +207,85 @@ static int ldr_split_line(char **login, if (!strncmp(*ciphertext, "NO PASSWORD", 11)) *ciphertext = ""; + /* NT loader hack starts here ! */ + + if (options.format && (strncmp(options.format, "nt", 2)==0)) { + + tmp = ldr_get_field(&line); + *ciphertext = tmp; + + if (!strncmp(*ciphertext, "NO PASSWORD", 11)) + *ciphertext = ""; + else if(strlen(*ciphertext) == 32) { + *ciphertext -= 4; + strncpy(*ciphertext,"$NT$",4); + } + else { + return 0; + } + + } + + /* NT loader hack ends here ! */ + if (source) sprintf(source, "%s:%s", uid, line); } + else if (options.format && (strncmp(options.format, "netlmv2", 7)==0)) { + char *srv_challenge = ldr_get_field(&line); + char *netlmv2 = ldr_get_field(&line); + char *cli_challenge = ldr_get_field(&line); + char *identity = NULL; + int i; + + identity = (char *) mem_alloc(strlen(*login) + strlen(uid) + 1); + memset(identity, 0, strlen(*login) + strlen(uid) + 1); + + sprintf(identity, *login, strlen(*login)); + sprintf(identity + strlen(*login), uid, strlen(uid)); + + /* Upper-Case Username and Domain */ + for(i=0; i= 'a') && (identity[i] <= 'z')) identity[i] ^= 0x20; + + tmp = (char *) mem_alloc(9 + strlen(identity) + 1 + strlen(srv_challenge) + 1 + strlen(netlmv2) + 1 + strlen(cli_challenge) + 1); + memset(tmp, 0, 9 + strlen(identity) + 1 + strlen(srv_challenge) + 1 + strlen(netlmv2) + 1 + strlen(cli_challenge) + 1); + sprintf(tmp, "$NETLMv2$%s$%s$%s$%s", identity, srv_challenge, netlmv2, cli_challenge); + *ciphertext = tmp; + } + else if (options.format && ((strncmp(options.format, "netlm", 5)==0) || + (strncmp(options.format, "netntlm", 7)==0))) { + char *netlm = ldr_get_field(&line); + char *netntlm = ldr_get_field(&line); + char *challenge = ldr_get_field(&line); + + if (strncmp(options.format, "netlm", 5)==0) { + tmp = (char *) mem_alloc(7 + strlen(challenge) + strlen(netlm) + 1); + memset(tmp, 0, 7 + strlen(challenge) + strlen(netlm) + 1); + sprintf(tmp, "$NETLM$%s$%s", challenge, netlm); + *ciphertext = tmp; + } + else { + tmp = (char *) mem_alloc(9 + strlen(challenge) + strlen(netntlm) + 1); + memset(tmp, 0, 9 + strlen(challenge) + strlen(netntlm) + 1); + sprintf(tmp, "$NETNTLM$%s$%s", challenge, netntlm); + *ciphertext = tmp; + } + } - if (options->flags & DB_WORDS || options->shells->head) { + else if (options.format && ((strncmp(options.format, "nethalflm", 9)==0))) { + char *nethalflm = ldr_get_field(&line); + /*char *netntlm = ldr_get_field(&line);*/ + char *challenge = ldr_get_field(&line); + + if (strncmp(options.format, "nethalflm", 9)==0) { + tmp = (char *) mem_alloc(12 + strlen(challenge) + strlen(nethalflm) + 1); + sprintf(tmp, "$NETHALFLM$%s$%s", challenge, nethalflm); + *ciphertext = tmp; + } + + } + + if (db_options->flags & DB_WORDS || db_options->shells->head) { gid = ldr_get_field(&line); do { *gecos = ldr_get_field(&line); @@ -218,13 +294,13 @@ static int ldr_split_line(char **login, } while (!**gecos && !strcmp(*home, "0") && !strcmp(shell, "0")); } else - if (options->groups->head) { + if (db_options->groups->head) { gid = ldr_get_field(&line); } - if (ldr_check_list(options->users, *login, uid)) return 0; - if (ldr_check_list(options->groups, gid, gid)) return 0; - if (ldr_check_shells(options->shells, shell)) return 0; + if (ldr_check_list(db_options->users, *login, uid)) return 0; + if (ldr_check_list(db_options->groups, gid, gid)) return 0; + if (ldr_check_shells(db_options->shells, shell)) return 0; if (*format) return (*format)->methods.valid(*ciphertext); @@ -287,6 +363,9 @@ static void ldr_load_pw_line(struct db_m struct list_main *words; size_t pw_size, salt_size; + extern struct fmt_main fmt_mscash; + extern struct fmt_main fmt_oracle; + count = ldr_split_line(&login, &ciphertext, &gecos, &home, NULL, &db->format, db->options, line); if (count <= 0) return; @@ -311,7 +390,19 @@ static void ldr_load_pw_line(struct db_m } for (index = 0; index < count; index++) { - piece = format->methods.split(ciphertext, index); + if (db->format == &fmt_mscash) + { + piece = (char *) mem_alloc(strlen(login) + strlen(ciphertext) + 4); + sprintf(piece, "M$%s#%s", login, ciphertext); + } + else + if (db->format == &fmt_oracle) + { + piece = (char *) mem_alloc_tiny(strlen(login) + strlen(ciphertext) + 4, MEM_ALIGN_NONE); + sprintf(piece, "O$%s#%s", login, ciphertext); + } + else + piece = format->methods.split(ciphertext, index); binary = format->methods.binary(piece); pw_hash = LDR_HASH_FUNC(binary); @@ -644,6 +735,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); @@ -654,6 +747,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; diff -urpN john-1.7.2.orig/src/lotus5_fmt.c john-1.7.2/src/lotus5_fmt.c --- john-1.7.2.orig/src/lotus5_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/lotus5_fmt.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,247 @@ +//original work by Jeff Fay +//some optimisations by bartavelle@bandecon.com + +#include +#include +#include "misc.h" +#include "formats.h" +#include "common.h" + +/*preprocessor constants that John The Ripper likes*/ +#define FORMAT_LABEL "lotus5" +#define FORMAT_NAME "Lotus5" +#define ALGORITHM_NAME "Lotus v5 Proprietary" +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 +#define PLAINTEXT_LENGTH 16 +#define CIPHERTEXT_LENGTH 32 +#define BINARY_SIZE 16 +#define SALT_SIZE 0 +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +/*A struct used for JTR's benchmarks*/ +static struct fmt_tests tests[] = { + {"06E0A50B579AD2CD5FFDC48564627EE7", "secret"}, + {"355E98E7C7B59BD810ED845AD0FD2FC4", "password"}, + {"CD2D90E8E00D8A2A63A81F531EA8A9A3", "lotus"}, + {"69D90B46B1AC0912E5CCF858094BBBFC", "dirtydog"}, + {NULL} +}; + +static const char lotus_magic_table[256] = { + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, + 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, + 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, + 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, + 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, + 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, + 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, + 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, + 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, + 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, + 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, + 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, + 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, + 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, + 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, + 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, + 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab, +}; + +/*Some more JTR variables*/ +static char crypt_key[BINARY_SIZE+1]; +static char saved_key[PLAINTEXT_LENGTH + 1]; + +/*Utility function to convert hex to bin */ +static void * binary (char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + for (i = 0; i < BINARY_SIZE; i++) + realcipher[i] = atoi16[ARCH_INDEX(ciphertext[i*2])]*16 + atoi16[ARCH_INDEX(ciphertext[i*2+1])]; + return ((void *) realcipher); +} + +/*Another function required by JTR: decides whether we have a valid + * ciphertext */ +static int +valid (char *ciphertext) +{ + int i; + + for (i = 0; i < CIPHERTEXT_LENGTH; i++) + if (!(((ciphertext[i] >= '0') && (ciphertext[i] <= '9')) + || ((ciphertext[i] >= 'a') && (ciphertext[i] <= 'f')) + || ((ciphertext[i] >= 'A') && (ciphertext[i] <= 'F')))) + { + return 0; + } + return 1; +} + +/*sets the value of saved_key so we can play with it*/ +static void set_key (char *key, int index) +{ + strnzcpy (saved_key, key, PLAINTEXT_LENGTH + 1); +} + +/*retrieves the saved key; used by JTR*/ +static char * get_key (int index) +{ + return saved_key; +} +static int +cmp_all (void *binary, int index) +{ + int i = 0; + while(i 0; i--) + { + temp = lotus_matrix; + for (j = 48; j > 0; j--) + { + *temp = *temp ^ lotus_magic_table[ARCH_INDEX((j + prevbyte) & 0xff)]; + prevbyte = *temp; + temp++; + } + } +} + + +/*the last public function; generates ciphertext*/ +static void crypt_all (int count) +{ + unsigned char password[PLAINTEXT_LENGTH]; + unsigned char lotus_matrix[64], *lotus_matrix1, *lotus_matrix2, *lotus_matrix3, *lotus_matrix4; + int i; + int password_length; + + password_length = strlen (saved_key); + memset (password, (PLAINTEXT_LENGTH - password_length), PLAINTEXT_LENGTH); + lotus_matrix1 = lotus_matrix; + lotus_matrix2 = lotus_matrix1 + 16; + lotus_matrix3 = lotus_matrix2 + 16; + lotus_matrix4 = lotus_matrix3 + 16; + memcpy (password, saved_key, password_length); + + memset (lotus_matrix1, 0, 16); + memcpy (lotus_matrix2, password, 16); + memcpy (lotus_matrix3, password, 16); + lotus_transform_password (lotus_matrix2, lotus_matrix4); + lotus_mix (lotus_matrix); + memcpy (lotus_matrix2, lotus_matrix4, 16); + for (i = 0; i < 16; i++) + { + lotus_matrix3[i] = lotus_matrix1[i] ^ lotus_matrix2[i]; + } + lotus_mix (lotus_matrix); + memcpy (crypt_key, lotus_matrix1, BINARY_SIZE); +} + +static int get_hash1(int index) { return (((unsigned int *)crypt_key)[0] & 0xf); } +static int get_hash2(int index) { return (((unsigned int *)crypt_key)[0] & 0xff); } +static int get_hash3(int index) { return (((unsigned int *)crypt_key)[0] & 0xfff); } +static int binary_hash1(void * binary) { return (((unsigned int *)binary)[0] & 0xf); } +static int binary_hash2(void * binary) { return (((unsigned int *)binary)[0] & 0xff); } +static int binary_hash3(void * binary) { return (((unsigned int *)binary)[0] & 0xfff); } + +/* C's version of a class specifier */ +struct fmt_main fmt_lotus5 = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT, + tests + }, { + fmt_default_init, + valid, + fmt_default_split, + binary, + fmt_default_salt, + { + binary_hash1, + binary_hash2, + binary_hash3 + }, + fmt_default_salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + get_hash1, + get_hash2, + get_hash3 + }, + cmp_all, + cmp_all, + cmp_exact} +}; diff -urpN john-1.7.2.orig/src/md4.c john-1.7.2/src/md4.c --- john-1.7.2.orig/src/md4.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/md4.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,254 @@ +/* + * 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; + + memset(ctx, 0, sizeof(*ctx)); +} + +#endif diff -urpN john-1.7.2.orig/src/md4.h john-1.7.2/src/md4.h --- john-1.7.2.orig/src/md4.h 1970-01-01 00:00:00 +0000 +++ john-1.7.2/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.2.orig/src/md5-mmx.S john-1.7.2/src/md5-mmx.S --- john-1.7.2.orig/src/md5-mmx.S 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/md5-mmx.S 2008-02-20 14:19:36 +0000 @@ -0,0 +1,308 @@ +#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 + diff -urpN john-1.7.2.orig/src/md5.c john-1.7.2/src/md5.c --- john-1.7.2.orig/src/md5.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/md5.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,275 @@ +/* + * 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_Final(unsigned char *result, 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); + + 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; + + memset(ctx, 0, sizeof(*ctx)); +} + +#endif diff -urpN john-1.7.2.orig/src/md5.h john-1.7.2/src/md5.h --- john-1.7.2.orig/src/md5.h 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/md5.h 2008-02-20 14:19:36 +0000 @@ -0,0 +1,37 @@ +/* + * 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_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.2.orig/src/md5_go.c john-1.7.2/src/md5_go.c --- john-1.7.2.orig/src/md5_go.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/md5_go.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,227 @@ +/* + * 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" + +/* 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.2.orig/src/md5_go.h john-1.7.2/src/md5_go.h --- john-1.7.2.orig/src/md5_go.h 1970-01-01 00:00:00 +0000 +++ john-1.7.2/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.2.orig/src/mscash_fmt.c john-1.7.2/src/mscash_fmt.c --- john-1.7.2.orig/src/mscash_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/mscash_fmt.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,544 @@ +/* MSCASH patch for john (performance improvement) + * + * Written by Alain Espinosa in 2007 + * and placed in the public domain. + */ + +#include +#include "arch.h" +#include "misc.h" +#include "memory.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "mscash" +#define FORMAT_NAME "M$ Cache Hash" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 27 +#define MAX_CIPHERTEXT_LENGTH (2 + 32 + 1 + 32) + + +static struct fmt_tests tests[] = { + {"M$test1#64cd29e36a8431a2b111378564a10631", "test1" }, + {"M$test2#ab60bdb4493822b175486810ac2abe63", "test2" }, + {"M$test3#14dd041848e12fc48c0aa7a416a4a00c", "test3" }, + {"M$test4#b945d24866af4b01a6d89b9d932a153c", "test4" }, + {NULL} +}; + +#define ALGORITHM_NAME "Generic 1x" + +#define BINARY_SIZE 16 +#define SALT_SIZE (11*4) + +#define MS_NUM_KEYS 64 +#define MIN_KEYS_PER_CRYPT MS_NUM_KEYS +#define MAX_KEYS_PER_CRYPT MS_NUM_KEYS + + +static unsigned int ms_buffer1x[16*MS_NUM_KEYS]; +static unsigned int output1x[4*MS_NUM_KEYS]; + +static unsigned int crypt[4*MS_NUM_KEYS]; +static unsigned int last[4*MS_NUM_KEYS]; + +static unsigned int last_i[MS_NUM_KEYS]; +static char saved_plain[32*MS_NUM_KEYS]; + +static unsigned int *salt_buffer; +static unsigned int new_key; + +//Init values +#define INIT_A 0x67452301 +#define INIT_B 0xefcdab89 +#define INIT_C 0x98badcfe +#define INIT_D 0x10325476 + +#define SQRT_2 0x5a827999 +#define SQRT_3 0x6ed9eba1 + +static void init(void) +{ + memset(ms_buffer1x,0,64*MS_NUM_KEYS); + memset(last_i,0,4*MS_NUM_KEYS); + new_key=1; +} + +static char * ms_split(char *ciphertext, int index) +{ + static char out[MAX_CIPHERTEXT_LENGTH + 1]; + int i=0; + + for(; ciphertext[i] && i < MAX_CIPHERTEXT_LENGTH; i++) + out[i]=ciphertext[i]; + + out[i]=0; + + if (i >= 32) + strlwr(&out[i-32]); + + return out; +} + +static int valid(char *ciphertext) +{ + unsigned int i; + unsigned int l; + + /* + * 2 cases + * 1 - it comes from the disk, and does not have M$ + salt + * 2 - it comes from memory, and has got M$ + salt + # + blah + */ + + if (!strncmp(ciphertext, "M$", 2)) + { + l = strlen(ciphertext); + if (l <= 32 || l > MAX_CIPHERTEXT_LENGTH) + return 0; + l -= 32; + if(ciphertext[l-1]!='#') + return 0; + } + else + { + if(strlen(ciphertext)!=32) + return 0; + l = 0; + } + for (i = l; i < l + 32; i++) + if (atoi16[ARCH_INDEX(ciphertext[i])] == 0x7F) + return 0; + + return 1; +} + +static void set_salt(void *salt) { + salt_buffer=salt; +} + +static void * get_salt(char * ciphertext) +{ + //lenght=11 for save memory + //last position = 0 + //4 first position are crypt[?] + static unsigned int out[11]; + unsigned int md4_size=0; + + memset(out,0,44); + + ciphertext+=2; + + for(;;md4_size++) + if(ciphertext[md4_size]!='#' && md4_size < 19) + { + md4_size++; + + out[md4_size>>1] = ciphertext[md4_size-1] | ((ciphertext[md4_size]!='#') ? (ciphertext[md4_size]<<16) : 0x800000); + + if(ciphertext[md4_size]=='#') + break; + } + else + { + out[md4_size>>1] = 0x80; + break; + } + + out[10] = (8 + md4_size) << 4; + + return out; +} + +static void *get_binary(char *ciphertext) +{ + static unsigned int out[4]; + unsigned int i=0; + unsigned int temp; + unsigned int * salt=get_salt(ciphertext); + + for(;ciphertext[0]!='#';ciphertext++); + + ciphertext++; + + for(; i<4 ;i++) + { + temp = (atoi16[ARCH_INDEX(ciphertext[i*8+0])])<<4; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+1])]); + + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+2])])<<12; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+3])])<<8; + + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+4])])<<20; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+5])])<<16; + + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+6])])<<28; + temp |= (atoi16[ARCH_INDEX(ciphertext[i*8+7])])<<24; + + out[i]=temp; + } + + out[0] -= INIT_A; + out[1] -= INIT_B; + out[2] -= INIT_C; + out[3] -= INIT_D; + + // Reversed b += (c ^ d ^ a) + salt_buffer[11] + SQRT_3; b = (b << 15) | (b >> 17); + out[1] = (out[1] >> 15) | (out[1] << 17); + out[1] -= SQRT_3 + (out[2] ^ out[3] ^ out[0]); + // Reversed c += (d ^ a ^ b) + salt_buffer[3] + SQRT_3; c = (c << 11) | (c >> 21); + out[2] = (out[2] << 21) | (out[2] >> 11); + out[2]-= SQRT_3 + (out[3] ^ out[0] ^ out[1]) + salt[3]; + // Reversed d += (a ^ b ^ c) + salt_buffer[7] + SQRT_3; d = (d << 9 ) | (d >> 23); + out[3] = (out[3] << 23) | (out[3] >> 9); + out[3] -= SQRT_3 + (out[0] ^ out[1] ^ out[2]) + salt[7]; + //+ SQRT_3; d = (d << 9 ) | (d >> 23); + out[3]=(out[3] << 23 ) | (out[3] >> 9); + out[3]-=SQRT_3; + + return out; +} + +static int binary_hash_0(void *binary) +{ + return ((unsigned int*)binary)[3] & 0x0F; +} + +static int binary_hash_1(void *binary) +{ + return ((unsigned int*)binary)[3] & 0xFF; +} + +static int binary_hash_2(void *binary) +{ + return ((unsigned int*)binary)[3] & 0x0FFF; +} + +static int get_hash_0(int index) +{ + return output1x[4*index+3] & 0x0F; +} + +static int get_hash_1(int index) +{ + return output1x[4*index+3] & 0xFF; +} + +static int get_hash_2(int index) +{ + return output1x[4*index+3] & 0x0FFF; +} + +void nt_hash(void) +{ + unsigned int a; + unsigned int b; + unsigned int c; + unsigned int d; + unsigned int i=0; + + for(;i> 29); + d = INIT_D + (INIT_C ^ (a & 0x77777777)) + ms_buffer1x[16*i+1];d = (d << 7 ) | (d >> 25); + c = INIT_C + (INIT_B ^ (d & (a ^ INIT_B)))+ ms_buffer1x[16*i+2];c = (c << 11) | (c >> 21); + b = INIT_B + (a ^ (c & (d ^ a))) + ms_buffer1x[16*i+3];b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + ms_buffer1x[16*i+4] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + ms_buffer1x[16*i+5] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + ms_buffer1x[16*i+6] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + ms_buffer1x[16*i+7] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + ms_buffer1x[16*i+8] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + ms_buffer1x[16*i+9] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + ms_buffer1x[16*i+10] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + ms_buffer1x[16*i+11] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + ms_buffer1x[16*i+12] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + ms_buffer1x[16*i+13] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + ms_buffer1x[16*i+14] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a)))/*+ms_buffer1x[16*i+15]*/;b = (b << 19) | (b >> 13); + + /* Round 2 */ + a += ((b & (c | d)) | (c & d)) + ms_buffer1x[16*i+0] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + ms_buffer1x[16*i+4] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + ms_buffer1x[16*i+8] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + ms_buffer1x[16*i+12] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + ms_buffer1x[16*i+1] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + ms_buffer1x[16*i+5] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + ms_buffer1x[16*i+9] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + ms_buffer1x[16*i+13] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + ms_buffer1x[16*i+2] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + ms_buffer1x[16*i+6] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + ms_buffer1x[16*i+10] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + ms_buffer1x[16*i+14] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + ms_buffer1x[16*i+3] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + ms_buffer1x[16*i+7] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + ms_buffer1x[16*i+11] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a))/*+ms_buffer1x[16*i+15]*/+SQRT_2; b = (b << 13) | (b >> 19); + + /* Round 3 */ + a += (b ^ c ^ d) + ms_buffer1x[16*i+0] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + ms_buffer1x[16*i+8] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + ms_buffer1x[16*i+4] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + ms_buffer1x[16*i+12] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + ms_buffer1x[16*i+2] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + ms_buffer1x[16*i+10] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + ms_buffer1x[16*i+6] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + ms_buffer1x[16*i+14] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + ms_buffer1x[16*i+1] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + ms_buffer1x[16*i+9] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + ms_buffer1x[16*i+5] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + ms_buffer1x[16*i+13] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + ms_buffer1x[16*i+3] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + ms_buffer1x[16*i+11] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + ms_buffer1x[16*i+7] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) /*+ ms_buffer1x[16*i+15] */+ SQRT_3; b = (b << 15) | (b >> 17); + + crypt[4*i+0] = a + INIT_A; + crypt[4*i+1] = b + INIT_B; + crypt[4*i+2] = c + INIT_C; + crypt[4*i+3] = d + INIT_D; + + //Another MD4_crypt for the salt + /* Round 1 */ + a= 0xFFFFFFFF +crypt[4*i+0]; a=(a<<3 )|(a>>29); + d=INIT_D + ( INIT_C ^ ( a & 0x77777777)) +crypt[4*i+1]; d=(d<<7 )|(d>>25); + c=INIT_C + ( INIT_B ^ ( d & ( a ^ INIT_B))) +crypt[4*i+2]; c=(c<<11)|(c>>21); + b=INIT_B + ( a ^ ( c & ( d ^ a ))) +crypt[4*i+3]; b=(b<<19)|(b>>13); + + last[4*i+0]=a; + last[4*i+1]=b; + last[4*i+2]=c; + last[4*i+3]=d; + } +} + +static void crypt_all(int count) +{ + unsigned int a; + unsigned int b; + unsigned int c; + unsigned int d; + unsigned int i=0; + + if(new_key) + { + new_key=0; + nt_hash(); + } + + for(;i> 29); + d += (c ^ (a & (b ^ c))) + salt_buffer[1] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + salt_buffer[2] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + salt_buffer[3] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + salt_buffer[4] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + salt_buffer[5] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + salt_buffer[6] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a))) + salt_buffer[7] ;b = (b << 19) | (b >> 13); + + a += (d ^ (b & (c ^ d))) + salt_buffer[8] ;a = (a << 3 ) | (a >> 29); + d += (c ^ (a & (b ^ c))) + salt_buffer[9] ;d = (d << 7 ) | (d >> 25); + c += (b ^ (d & (a ^ b))) + salt_buffer[10] ;c = (c << 11) | (c >> 21); + b += (a ^ (c & (d ^ a)))/*+salt_buffer[11]*/;b = (b << 19) | (b >> 13); + + /* Round 2 */ + a += ((b & (c | d)) | (c & d)) + crypt[4*i+0] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + salt_buffer[0] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + salt_buffer[4] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + salt_buffer[8] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + crypt[4*i+1] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + salt_buffer[1] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + salt_buffer[5] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + salt_buffer[9] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + crypt[4*i+2] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + salt_buffer[2] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + salt_buffer[6] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a)) + salt_buffer[10] + SQRT_2; b = (b << 13) | (b >> 19); + + a += ((b & (c | d)) | (c & d)) + crypt[4*i+3] + SQRT_2; a = (a << 3 ) | (a >> 29); + d += ((a & (b | c)) | (b & c)) + salt_buffer[3] + SQRT_2; d = (d << 5 ) | (d >> 27); + c += ((d & (a | b)) | (a & b)) + salt_buffer[7] + SQRT_2; c = (c << 9 ) | (c >> 23); + b += ((c & (d | a)) | (d & a))/*+ salt_buffer[11]*/+ SQRT_2; b = (b << 13) | (b >> 19); + + /* Round 3 */ + a += (b ^ c ^ d) + crypt[4*i+0] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + salt_buffer[4] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + salt_buffer[0] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + salt_buffer[8] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + crypt[4*i+2] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + salt_buffer[6] + SQRT_3; d = (d << 9 ) | (d >> 23); + c += (d ^ a ^ b) + salt_buffer[2] + SQRT_3; c = (c << 11) | (c >> 21); + b += (c ^ d ^ a) + salt_buffer[10] + SQRT_3; b = (b << 15) | (b >> 17); + + a += (b ^ c ^ d) + crypt[4*i+1] + SQRT_3; a = (a << 3 ) | (a >> 29); + d += (a ^ b ^ c) + salt_buffer[5]; + + output1x[4*i+0]=a; + output1x[4*i+1]=b; + output1x[4*i+2]=c; + output1x[4*i+3]=d; + } +} + +static int cmp_all(void *binary, int count) +{ + unsigned int i=0; + unsigned int d=((unsigned int *)binary)[3]; + + for(;i> 23); + + c += (d ^ a ^ b) + salt_buffer[1] + SQRT_3; c = (c << 11) | (c >> 21); + if(c!=t[2]) + return 0; + + b += (c ^ d ^ a) + salt_buffer[9] + SQRT_3; b = (b << 15) | (b >> 17); + if(b!=t[1]) + return 0; + + a += (b ^ c ^ d) + crypt[4*index+3]+ SQRT_3; a = (a << 3 ) | (a >> 29); + return (a==t[0]); +} + +static int cmp_exact(char *source, int index) +{ + // This check its for the unreal case of collisions. + // It verify that the salts its the same. + unsigned int *salt=get_salt(source); + unsigned int i=0; + for(;i<11;i++) + if(salt[i]!=salt_buffer[i]) + return 0; + return 1; +} + +static void set_key(char *key, int index) +{ + unsigned int md4_size=0; + unsigned int i=0; + unsigned int temp; + unsigned int saved_base=index<<5; + unsigned int buff_base=index<<4; + + for(;key[md4_size] && md4_size>1; + + ms_buffer1x[buff_base+14] = md4_size << 4; + + //new password_candidate + new_key=1; +} + +static char *get_key(int index) +{ + return saved_plain+(index<<5); +} + +int salt_hash(void *salt) +{ + return ((unsigned char*)salt)[0]; +} + +struct fmt_main fmt_mscash = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_CASE | FMT_8_BIT | FMT_SPLIT_UNIFIES_CASE, + tests + }, { + init, + valid, + ms_split, + get_binary, + get_salt, + { + binary_hash_0, + binary_hash_1, + binary_hash_2 + }, + salt_hash, + set_salt, + set_key, + get_key, + fmt_default_clear_keys, + crypt_all, + { + get_hash_0, + get_hash_1, + get_hash_2 + }, + cmp_all, + cmp_one, + cmp_exact + } +}; diff -urpN john-1.7.2.orig/src/mssql05_fmt.c john-1.7.2/src/mssql05_fmt.c --- john-1.7.2.orig/src/mssql05_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/mssql05_fmt.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2004 bartavelle + * bartavelle@bandecon.com + * + * Modified by Mathieu Perrin (mathieu@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 +static char saved_key[64*MMX_COEF*2 + 1] __attribute__ ((aligned(16))); +static char crypt_key[80*4*MMX_COEF+1] __attribute__ ((aligned(16))); //wtf +unsigned long total_len; +unsigned char out[PLAINTEXT_LENGTH]; +#else +static unsigned char saved_key[PLAINTEXT_LENGTH*2 + 1]; +static unsigned char crypt_key[BINARY_SIZE+1]; +static SHA_CTX ctx; +static unsigned int key_length; +#endif + +static int valid(char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) return 0; + if(memcmp(ciphertext, "0x0100", 6)) + return 0; + for (i = 6; i < CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) + return 0; + } + return 1; +} + +static void mssql05_set_salt(void *salt) +{ + memcpy(cursalt, salt, SALT_SIZE); +} + +static void * mssql05_get_salt(char * ciphertext) +{ + static unsigned char out2[SALT_SIZE]; + int l; + + for(l=0;lPLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + total_len += (len*2+SALT_SIZE ) << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i> (((32/MMX_COEF)*(index)))) & 0xff; + s = (s-4)/2; + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } +#else + while(i + +#include "arch.h" +#include "misc.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 +static char saved_key[64*MMX_COEF*2 + 1] __attribute__ ((aligned(16))); +static char crypt_key[80*4*MMX_COEF+1] __attribute__ ((aligned(16))); //wtf +unsigned long total_len; +unsigned char out[PLAINTEXT_LENGTH]; +#else +static unsigned char saved_key[PLAINTEXT_LENGTH*2 + 1]; +static unsigned char crypt_key[BINARY_SIZE+1]; +static SHA_CTX ctx; +unsigned int key_length; +#endif + +static int valid(char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) return 0; + if(memcmp(ciphertext, "0x0100", 6)) + return 0; + for (i = 6; i < CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) + return 0; + } + return 1; +} + +static void mssql_set_salt(void *salt) +{ + memcpy(cursalt, salt, SALT_SIZE); +} + +static void * mssql_get_salt(char * ciphertext) +{ + static unsigned char out2[SALT_SIZE]; + int l; + + for(l=0;l='a') && (c<='z')) + return c+'A'-'a'; + return c; +} + +static void mssql_init(void) +{ +#ifdef MMX_COEF + memset(saved_key, 0, 64*MMX_COEF); +#endif +} + +static void mssql_set_key(char *key, int index) { +#ifdef MMX_COEF + int len; + int i; + + if(index==0) + { + total_len = 0; + memset(saved_key, 0, 64*MMX_COEF); + } + len = strlen(key); + if(len>PLAINTEXT_LENGTH) + len = PLAINTEXT_LENGTH; + + total_len += (len*2+SALT_SIZE ) << ( ( (32/MMX_COEF) * index ) ); + for(i=0;i> (((32/MMX_COEF)*(index)))) & 0xff; + s = (s-4)/2; + for(i=0;i 3) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+2]) + && ( ((unsigned long *)binary)[i] != ((unsigned long *)crypt_key)[i*MMX_COEF+3]) +#endif + ) + return 0; + i++; + } +#else + while(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 SHA1 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-SHA1" +#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 +static char saved_key[PLAINTEXT_LENGTH*MMX_COEF*2 + 1] __attribute__ ((aligned(16))); +static char crypt_key[80*4*MMX_COEF+1] __attribute__ ((aligned(16))); +unsigned long total_len; + +/* Intermediate key which stores the hashes between two SHA1 operations. Don't + * ask me why it has to be so long ;) */ +static char interm_key[80*4*MMX_COEF*2 + 1] __attribute__ ((aligned(16))) = {0}; + +# 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 char crypt_key[BINARY_SIZE+1]; +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++; + } +#else + while(i 2 + assert(((unsigned*)interm_key)[i+2] == BYTESWAP(0x80)); + assert(((unsigned*)interm_key)[i+3] == BYTESWAP(0x80)); +# endif +# endif /* X_DEBUG */ + + shammx((unsigned char *) crypt_key, (unsigned char *) interm_key, TMPKEY_LENGTHS); + +#else + SHA1_Init(&ctx); + SHA1_Update(&ctx, (unsigned char *) saved_key, strlen(saved_key)); + SHA1_Final((unsigned char *) crypt_key, &ctx); + + SHA1_Init(&ctx); + SHA1_Update(&ctx, (unsigned char *) crypt_key, BINARY_SIZE); + SHA1_Final((unsigned char *) crypt_key, &ctx); +#endif +} + +static void *mysqlsha1_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + int i; + + // ignore first character '*' + ciphertext += 1; + for(i=0;i +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" + +#define FORMAT_LABEL "oracle" +#define FORMAT_NAME "Oracle" +#define ALGORITHM_NAME "oracle" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 120 + +#define BINARY_SIZE 8 +#define SALT_SIZE (32 + 2) +#define CIPHERTEXT_LENGTH 16 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests oracle_tests[] = { + {"O$SYSTEM#9EEDFA0AD26C6D52", "THALES" }, + {"O$SIMON#4F8BC1809CB2AF77", "A"}, + {"O$SIMON#183D72325548EF11", "THALES2" }, + {"O$SIMON#C4EB3152E17F24A4", "TST" }, + {"O$BOB#b02c8e79ed2e7f46", "LAPIN" }, + {"O$BOB#6bb4e95898c88011", "LAPINE" }, + {"O$BOB#cdc6b483874b875b", "GLOUGLOU" }, + {"O$BOB#ef1f9139db2d5279", "GLOUGLOUTER" }, + {"O$BOB#c0ee5107c9a080c1", "AZERTYUIOP" }, + {"O$BOB#99e8b231d33772f9", "CANARDWC" }, + {"O$BOB#da3224126a67c8ed", "COUCOU_COUCOU" }, + {"O$BOB#ec8147abb3373d53", "LONG_MOT_DE_PASSE_OUI" }, + {NULL} +}; + +#if ARCH_LITTLE_ENDIAN +#define ENDIAN_SHIFT_L << 8 +#define ENDIAN_SHIFT_R >> 8 +#else +#define ENDIAN_SHIFT_L +#define ENDIAN_SHIFT_R +#endif + +static ARCH_WORD_32 crypt_key[2]; + +static unsigned short cur_salt[SALT_SIZE / 2 + PLAINTEXT_LENGTH]; +static unsigned short cur_key[PLAINTEXT_LENGTH + 1]; + +static DES_key_schedule desschedule1; +static DES_key_schedule desschedule2; + +static int salt_length; +static int key_length; + +static int valid(char *ciphertext) +{ + int i; + int l; + + /* + * 2 cases + * 1 - it comes from the disk, and does not have O$ + salt + * 2 - it comes from memory, and has got O$ + salt + # + blah + */ + + if (!memcmp(ciphertext, "O$", 2)) + { + l = strlen(ciphertext) - CIPHERTEXT_LENGTH; + if(ciphertext[l-1]!='#') + return 0; + } + else + { + if(strlen(ciphertext)!=CIPHERTEXT_LENGTH) + return 0; + l = 0; + } + for (i = l; i < l + CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) + || (('A' <= ciphertext[i])&&(ciphertext[i] <= 'F')))) + return 0; + } + + return 1; +} + +static void oracle_init(void) +{ + unsigned char deskey[8]; + + deskey[0] = 0x01; + deskey[1] = 0x23; + deskey[2] = 0x45; + deskey[3] = 0x67; + deskey[4] = 0x89; + deskey[5] = 0xab; + deskey[6] = 0xcd; + deskey[7] = 0xef; + + des_set_key((DES_cblock *)deskey, desschedule1); +} + +static inline unsigned char upper(unsigned char c) +{ + if( (c>='a') && (c<='z')) + return c+'A'-'a'; + return c; +} + +static void oracle_set_salt(void *salt) { + salt_length = *(unsigned short *)salt; + memcpy(cur_salt, (char *)salt+2, salt_length); +} + +static void oracle_set_key(char *key, int index) { + key_length = 0; + while( (cur_key[key_length] = upper(key[key_length]) ENDIAN_SHIFT_L )) + key_length++; + key_length <<= 1; +} + +static char *oracle_get_key(int index) { + static unsigned char out[PLAINTEXT_LENGTH + 1]; + unsigned int i; + for(i=0;i>1;i++) + out[i] = cur_key[i] ENDIAN_SHIFT_R; + out[i] = 0; + return (char *) out; +} + +static void oracle_crypt_all(int count) +{ + unsigned char buf[sizeof(cur_salt)]; + unsigned int l; + + l = salt_length + key_length; + crypt_key[0] = 0; + crypt_key[1] = 0; + memcpy((char *)cur_salt + salt_length, cur_key, key_length); + des_ncbc_encrypt((unsigned char *)cur_salt, buf, l, desschedule1, (DES_cblock *) crypt_key, DES_ENCRYPT); + des_set_key((DES_cblock *)crypt_key, desschedule2); + crypt_key[0] = 0; + crypt_key[1] = 0; + des_ncbc_encrypt((unsigned char *)cur_salt, buf, l, desschedule2, (DES_cblock *) crypt_key, DES_ENCRYPT); +} + +static void * oracle_binary(char *ciphertext) +{ + static unsigned char out3[BINARY_SIZE]; + int l; + int i; + l = strlen(ciphertext) - CIPHERTEXT_LENGTH; + for(i=0;i= SALT_SIZE-2) break; + } + salt[l-2] = 0; + + l = 0; + while ((out[l+1] = upper(salt[l]) ENDIAN_SHIFT_L)) + l++; + out[0] = l*2; + + return out; +} + +static int binary_hash1(void * binary) { return (((ARCH_WORD_32 *)binary)[0] & 0xf); } +static int binary_hash2(void * binary) { return (((ARCH_WORD_32 *)binary)[0] & 0xff); } +static int binary_hash3(void * binary) { return (((ARCH_WORD_32 *)binary)[0] & 0xfff); } + +static int get_hash1(int index) { return crypt_key[0] & 0xf; } +static int get_hash2(int index) { return crypt_key[0] & 0xff; } +static int get_hash3(int index) { return crypt_key[0] & 0xfff; } + +static int oracle_cmp_all(void *binary, int index) { + return !memcmp(binary, crypt_key, sizeof(crypt_key)); +} + +static int oracle_cmp_exact(char *source, int count) { + return 1; +} + +struct fmt_main fmt_oracle = { + { + FORMAT_LABEL, + FORMAT_NAME, + ALGORITHM_NAME, + BENCHMARK_COMMENT, + BENCHMARK_LENGTH, + PLAINTEXT_LENGTH, + BINARY_SIZE, + SALT_SIZE, + MIN_KEYS_PER_CRYPT, + MAX_KEYS_PER_CRYPT, + FMT_8_BIT, + oracle_tests + }, { + oracle_init, + valid, + fmt_default_split, + oracle_binary, + oracle_get_salt, + { + binary_hash1, + binary_hash2, + binary_hash3 + }, + fmt_default_salt_hash, + oracle_set_salt, + oracle_set_key, + oracle_get_key, + fmt_default_clear_keys, + oracle_crypt_all, + { + get_hash1, + get_hash2, + get_hash3 + }, + oracle_cmp_all, + oracle_cmp_all, + oracle_cmp_exact + } +}; diff -urpN john-1.7.2.orig/src/params.h john-1.7.2/src/params.h --- john-1.7.2.orig/src/params.h 2006-05-15 16:42:04 +0000 +++ john-1.7.2/src/params.h 2008-04-21 07:01:30 +0000 @@ -91,7 +91,7 @@ /* * Benchmark time in seconds, per cracking algorithm. */ -#define BENCHMARK_TIME 5 +#define BENCHMARK_TIME 1 /* * Number of salts to assume when benchmarking. diff -urpN john-1.7.2.orig/src/rawMD5go_fmt.c john-1.7.2/src/rawMD5go_fmt.c --- john-1.7.2.orig/src/rawMD5go_fmt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/rawMD5go_fmt.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2004 bartavelle + * bartavelle@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. + */ + +#include + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "md5_go.h" + +#if !ARCH_LITTLE_ENDIAN +#define MD5_out MD5_bitswapped_out +#endif + +extern ARCH_WORD_32 MD5_out[4]; + +#define FORMAT_LABEL "raw-md5" +#define FORMAT_NAME "Raw MD5" +#define ALGORITHM_NAME "raw-md5" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#define PLAINTEXT_LENGTH 32 +#define CIPHERTEXT_LENGTH 32 + +#define BINARY_SIZE 16 +#define SALT_SIZE 0 + +#define MIN_KEYS_PER_CRYPT 1 +#define MAX_KEYS_PER_CRYPT 1 + +static struct fmt_tests rawmd5_tests[] = { + {"5a105e8b9d40e1329780d62ea2265d8a", "test1"}, + {"ad0234829205b9033196ba818f7a872b", "test2"}, + {"8ad8757baa8564dc136c1e07507f4a98", "test3"}, + {"86985e105f79b95d6bc918fb45ec7727", "test4"}, + {NULL} +}; + +static char saved_key[PLAINTEXT_LENGTH + 1 + 128 /* MD5 scratch space */]; +int saved_key_len; + +static int valid(char *ciphertext) +{ + int i; + + if (strlen(ciphertext) != CIPHERTEXT_LENGTH) return 0; + for (i = 0; i < CIPHERTEXT_LENGTH; i++){ + if (!( (('0' <= ciphertext[i])&&(ciphertext[i] <= '9')) || + (('a' <= ciphertext[i])&&(ciphertext[i] <= 'f')) )) + return 0; + } + return 1; +} + +static void rawmd5_set_salt(void *salt) { } + +static void rawmd5_set_key(char *key, int index) { + strnzcpy(saved_key, key, PLAINTEXT_LENGTH+1); + saved_key_len = strlen(saved_key); +} + +static char *rawmd5_get_key(int index) { + saved_key[saved_key_len] = '\0'; + return saved_key; +} + +static int rawmd5_cmp_all(void *binary, int index) { + /* used for cmp_all and cmp_one */ + return !memcmp(binary, MD5_out, BINARY_SIZE); +} + +static int rawmd5_cmp_exact(char *source, int count){ + /* only used if cmp_all matches */ + return (1); +} + +static void rawmd5_crypt_all(int count) { + /* get plaintext input in saved_key put it into ciphertext MD5_out */ + MD5_Go( (unsigned char *)saved_key, saved_key_len ); +} + +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 SHA1" +#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 +static char saved_key[PLAINTEXT_LENGTH*MMX_COEF*2 + 1] __attribute__ ((aligned(16))); +static char crypt_key[80*4*MMX_COEF+1] __attribute__ ((aligned(16))); +unsigned long total_len; +unsigned char out[PLAINTEXT_LENGTH]; +#else +static char saved_key[PLAINTEXT_LENGTH + 1]; +static char crypt_key[BINARY_SIZE+1]; +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, PLAINTEXT_LENGTH*MMX_COEF*2 + 1); +#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)); + /*memset(saved_key, 0, PLAINTEXT_LENGTH*MMX_COEF);*/ + } + 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++; + } +#else + while(i + +#include "arch.h" +#include "misc.h" +#include "common.h" +#include "formats.h" +#include "sha.h" +#include "sha_locl.h" + +#define FORMAT_LABEL "macosx-sha1" +#define FORMAT_NAME "Salt SHA1 - MacOSX" +#define ALGORITHM_NAME "salt-sha1" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH 0 + +#define PLAINTEXT_LENGTH 32 +#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 saltsha1_tests[] = { + {"12345678f9083c7f66f46a0a102e4cc17ec08c8af120571b", "abc"}, + {"12345678eb8844bfaf2a8cbdd587a37ef8d4a290680d5818", "azertyuiop1"}, + {"3234c32aaa335fd20e3f95870e5851bdbe942b79ce4fdd92", "azertyuiop2"}, + {"123456783132e627074cbc7d637a219b368d2d38676943e0", "azertyuiop3"}, + {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) +{ + 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 *salt(char *ciphertext) +{ + static ARCH_WORD_32 salt; + + sscanf(ciphertext, "%08X", &salt); +#if ARCH_LITTLE_ENDIAN + Endian_Reverse32(salt); +#endif + + return &salt; +} + +static void saltsha1_set_salt(void *salt) +{ + saved_salt = *(ARCH_WORD_32 *)salt; +} + +static void saltsha1_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 *saltsha1_get_key(int index) { + return saved_key; +} + +static int saltsha1_cmp_all(void *binary, int index) { + return !memcmp(binary, crypt_out, BINARY_SIZE); +} + +static int saltsha1_cmp_exact(char *source, int count) { + return 1; +} + +static void saltsha1_crypt_all(int count) { + SHA1_Init( &ctx ); + SHA1_Update( &ctx, (void*)&saved_salt, SALT_SIZE ); + SHA1_Update( &ctx, (unsigned char *) saved_key, saved_key_length ); + SHA1_Final( (unsigned char*) crypt_out, &ctx); +} + +static void * saltsha1_binary(char *ciphertext) +{ + static char realcipher[BINARY_SIZE]; + + int i; + for(i=0;i=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 +*/ diff -urpN john-1.7.2.orig/src/sha1.c john-1.7.2/src/sha1.c --- john-1.7.2.orig/src/sha1.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/sha1.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,474 @@ +/* crypto/sha/sha1dgst.c */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#undef SHA_0 +#define SHA_1 +#include "sha.h" +#include "sha_locl.h" + +#include "arch.h" +#if ARCH_LITTLE_ENDIAN +#define L_ENDIAN +#else +#define B_ENDIAN +#endif + +char *SHA1_version="SHA1 part of SSLeay 0.8.2b 08-Jan-1998"; + +/* Implemented from SHA-1 document - The Secure Hash Algorithm + */ + +#define INIT_DATA_h0 (unsigned long)0x67452301L +#define INIT_DATA_h1 (unsigned long)0xefcdab89L +#define INIT_DATA_h2 (unsigned long)0x98badcfeL +#define INIT_DATA_h3 (unsigned long)0x10325476L +#define INIT_DATA_h4 (unsigned long)0xc3d2e1f0L + +#define K_00_19 0x5a827999L +#define K_20_39 0x6ed9eba1L +#define K_40_59 0x8f1bbcdcL +#define K_60_79 0xca62c1d6L + +#ifndef NOPROTO +# ifdef SHA1_ASM + void sha1_block_x86(SHA_CTX *c, register unsigned long *p, int num); +# define sha1_block sha1_block_x86 +# else + void sha1_block(SHA_CTX *c, register unsigned long *p, int num); +# endif +#else +# ifdef SHA1_ASM + void sha1_block_x86(); +# define sha1_block sha1_block_x86 +# else + void sha1_block(); +# endif +#endif + +#if defined(L_ENDIAN) && defined(SHA1_ASM) +# define M_c2nl c2l +# define M_p_c2nl p_c2l +# define M_c2nl_p c2l_p +# define M_p_c2nl_p p_c2l_p +# define M_nl2c l2c +#else +# define M_c2nl c2nl +# define M_p_c2nl p_c2nl +# define M_c2nl_p c2nl_p +# define M_p_c2nl_p p_c2nl_p +# define M_nl2c nl2c +#endif + +void SHA1_Init(c) +SHA_CTX *c; + { + c->h0=INIT_DATA_h0; + c->h1=INIT_DATA_h1; + c->h2=INIT_DATA_h2; + c->h3=INIT_DATA_h3; + c->h4=INIT_DATA_h4; + c->Nl=0; + c->Nh=0; + c->num=0; + } + +void SHA1_Update(c, data, len) +SHA_CTX *c; +register unsigned char *data; +unsigned long len; + { + register unsigned long *p; + int ew,ec,sw,sc; + unsigned long l; + + if (len == 0) return; + + l=(c->Nl+(len<<3))&0xffffffffL; + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh+=(len>>29); + c->Nl=l; + + if (c->num != 0) + { + p=c->data; + sw=c->num>>2; + sc=c->num&0x03; + + if ((c->num+len) >= SHA_CBLOCK) + { + l= p[sw]; + M_p_c2nl(data,l,sc); + p[sw++]=l; + for (; swnum); + + sha1_block(c,p,64); + c->num=0; + /* drop through and do the rest */ + } + else + { + c->num+=(int)len; + if ((sc+len) < 4) /* ugly, add char's to a word */ + { + l= p[sw]; + M_p_c2nl_p(data,l,sc,len); + p[sw]=l; + } + else + { + ew=(c->num>>2); + ec=(c->num&0x03); + l= p[sw]; + M_p_c2nl(data,l,sc); + p[sw++]=l; + for (; sw < ew; sw++) + { M_c2nl(data,l); p[sw]=l; } + if (ec) + { + M_c2nl_p(data,l,ec); + p[sw]=l; + } + } + return; + } + } + /* We can only do the following code for assember, the reason + * being that the sha1_block 'C' version changes the values + * in the 'data' array. The assember code avoids this and + * copies it to a local array. I should be able to do this for + * the C version as well.... + */ +#if 1 +#if defined(B_ENDIAN) || defined(SHA1_ASM) + if ((((unsigned int)data)%sizeof(unsigned long)) == 0) + { + sw=len/SHA_CBLOCK; + if (sw) + { + sw*=SHA_CBLOCK; + sha1_block(c,(unsigned long *)data,sw); + data+=sw; + len-=sw; + } + } +#endif +#endif + /* we now can process the input data in blocks of SHA_CBLOCK + * chars and save the leftovers to c->data. */ + p=c->data; + while (len >= SHA_CBLOCK) + { +#if defined(B_ENDIAN) || defined(L_ENDIAN) + if (p != (unsigned long *)data) + memcpy(p,data,SHA_CBLOCK); + data+=SHA_CBLOCK; +# ifdef L_ENDIAN +# ifndef SHA1_ASM /* Will not happen */ + for (sw=(SHA_LBLOCK/4); sw; sw--) + { + Endian_Reverse32(p[0]); + Endian_Reverse32(p[1]); + Endian_Reverse32(p[2]); + Endian_Reverse32(p[3]); + p+=4; + } + p=c->data; +# endif +# endif +#else + for (sw=(SHA_BLOCK/4); sw; sw--) + { + M_c2nl(data,l); *(p++)=l; + M_c2nl(data,l); *(p++)=l; + M_c2nl(data,l); *(p++)=l; + M_c2nl(data,l); *(p++)=l; + } + p=c->data; +#endif + sha1_block(c,p,64); + len-=SHA_CBLOCK; + } + ec=(int)len; + c->num=ec; + ew=(ec>>2); + ec&=0x03; + + for (sw=0; sw < ew; sw++) + { M_c2nl(data,l); p[sw]=l; } + M_c2nl_p(data,l,ec); + p[sw]=l; + } + +void SHA1_Transform(c,b) +SHA_CTX *c; +unsigned char *b; + { + unsigned long p[16]; +#ifndef B_ENDIAN + unsigned long *q; + int i; +#endif + +#if defined(B_ENDIAN) || defined(L_ENDIAN) + memcpy(p,b,64); +#ifdef L_ENDIAN + q=p; + for (i=(SHA_LBLOCK/4); i; i--) + { + Endian_Reverse32(q[0]); + Endian_Reverse32(q[1]); + Endian_Reverse32(q[2]); + Endian_Reverse32(q[3]); + q+=4; + } +#endif +#else + q=p; + for (i=(SHA_LBLOCK/4); i; i--) + { + unsigned long l; + c2nl(b,l); *(q++)=l; + c2nl(b,l); *(q++)=l; + c2nl(b,l); *(q++)=l; + c2nl(b,l); *(q++)=l; + } +#endif + sha1_block(c,p,64); + } + +#ifndef SHA1_ASM + +void sha1_block(c, W, num) +SHA_CTX *c; +register unsigned long *W; +int num; + { + register unsigned long A,B,C,D,E,T; + unsigned long X[16]; + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + for (;;) + { + BODY_00_15( 0,A,B,C,D,E,T,W); + BODY_00_15( 1,T,A,B,C,D,E,W); + BODY_00_15( 2,E,T,A,B,C,D,W); + BODY_00_15( 3,D,E,T,A,B,C,W); + BODY_00_15( 4,C,D,E,T,A,B,W); + BODY_00_15( 5,B,C,D,E,T,A,W); + BODY_00_15( 6,A,B,C,D,E,T,W); + BODY_00_15( 7,T,A,B,C,D,E,W); + BODY_00_15( 8,E,T,A,B,C,D,W); + BODY_00_15( 9,D,E,T,A,B,C,W); + BODY_00_15(10,C,D,E,T,A,B,W); + BODY_00_15(11,B,C,D,E,T,A,W); + BODY_00_15(12,A,B,C,D,E,T,W); + BODY_00_15(13,T,A,B,C,D,E,W); + BODY_00_15(14,E,T,A,B,C,D,W); + BODY_00_15(15,D,E,T,A,B,C,W); + BODY_16_19(16,C,D,E,T,A,B,W,W,W,W); + BODY_16_19(17,B,C,D,E,T,A,W,W,W,W); + BODY_16_19(18,A,B,C,D,E,T,W,W,W,W); + BODY_16_19(19,T,A,B,C,D,E,W,W,W,X); + + BODY_20_31(20,E,T,A,B,C,D,W,W,W,X); + BODY_20_31(21,D,E,T,A,B,C,W,W,W,X); + BODY_20_31(22,C,D,E,T,A,B,W,W,W,X); + BODY_20_31(23,B,C,D,E,T,A,W,W,W,X); + BODY_20_31(24,A,B,C,D,E,T,W,W,X,X); + BODY_20_31(25,T,A,B,C,D,E,W,W,X,X); + BODY_20_31(26,E,T,A,B,C,D,W,W,X,X); + BODY_20_31(27,D,E,T,A,B,C,W,W,X,X); + BODY_20_31(28,C,D,E,T,A,B,W,W,X,X); + BODY_20_31(29,B,C,D,E,T,A,W,W,X,X); + BODY_20_31(30,A,B,C,D,E,T,W,X,X,X); + BODY_20_31(31,T,A,B,C,D,E,W,X,X,X); + BODY_32_39(32,E,T,A,B,C,D,X); + BODY_32_39(33,D,E,T,A,B,C,X); + BODY_32_39(34,C,D,E,T,A,B,X); + BODY_32_39(35,B,C,D,E,T,A,X); + BODY_32_39(36,A,B,C,D,E,T,X); + BODY_32_39(37,T,A,B,C,D,E,X); + BODY_32_39(38,E,T,A,B,C,D,X); + BODY_32_39(39,D,E,T,A,B,C,X); + + BODY_40_59(40,C,D,E,T,A,B,X); + BODY_40_59(41,B,C,D,E,T,A,X); + BODY_40_59(42,A,B,C,D,E,T,X); + BODY_40_59(43,T,A,B,C,D,E,X); + BODY_40_59(44,E,T,A,B,C,D,X); + BODY_40_59(45,D,E,T,A,B,C,X); + BODY_40_59(46,C,D,E,T,A,B,X); + BODY_40_59(47,B,C,D,E,T,A,X); + BODY_40_59(48,A,B,C,D,E,T,X); + BODY_40_59(49,T,A,B,C,D,E,X); + BODY_40_59(50,E,T,A,B,C,D,X); + BODY_40_59(51,D,E,T,A,B,C,X); + BODY_40_59(52,C,D,E,T,A,B,X); + BODY_40_59(53,B,C,D,E,T,A,X); + BODY_40_59(54,A,B,C,D,E,T,X); + BODY_40_59(55,T,A,B,C,D,E,X); + BODY_40_59(56,E,T,A,B,C,D,X); + BODY_40_59(57,D,E,T,A,B,C,X); + BODY_40_59(58,C,D,E,T,A,B,X); + BODY_40_59(59,B,C,D,E,T,A,X); + + BODY_60_79(60,A,B,C,D,E,T,X); + BODY_60_79(61,T,A,B,C,D,E,X); + BODY_60_79(62,E,T,A,B,C,D,X); + BODY_60_79(63,D,E,T,A,B,C,X); + BODY_60_79(64,C,D,E,T,A,B,X); + BODY_60_79(65,B,C,D,E,T,A,X); + BODY_60_79(66,A,B,C,D,E,T,X); + BODY_60_79(67,T,A,B,C,D,E,X); + BODY_60_79(68,E,T,A,B,C,D,X); + BODY_60_79(69,D,E,T,A,B,C,X); + BODY_60_79(70,C,D,E,T,A,B,X); + BODY_60_79(71,B,C,D,E,T,A,X); + BODY_60_79(72,A,B,C,D,E,T,X); + BODY_60_79(73,T,A,B,C,D,E,X); + BODY_60_79(74,E,T,A,B,C,D,X); + BODY_60_79(75,D,E,T,A,B,C,X); + BODY_60_79(76,C,D,E,T,A,B,X); + BODY_60_79(77,B,C,D,E,T,A,X); + BODY_60_79(78,A,B,C,D,E,T,X); + BODY_60_79(79,T,A,B,C,D,E,X); + + c->h0=(c->h0+E)&0xffffffffL; + c->h1=(c->h1+T)&0xffffffffL; + c->h2=(c->h2+A)&0xffffffffL; + c->h3=(c->h3+B)&0xffffffffL; + c->h4=(c->h4+C)&0xffffffffL; + + num-=64; + if (num <= 0) break; + + A=c->h0; + B=c->h1; + C=c->h2; + D=c->h3; + E=c->h4; + + W+=16; + } + } +#endif + +void SHA1_Final(md, c) +unsigned char *md; +SHA_CTX *c; + { + register int i,j; + register unsigned long l; + register unsigned long *p; + static unsigned char end[4]={0x80,0x00,0x00,0x00}; + unsigned char *cp=end; + + /* c->num should definitly have room for at least one more byte. */ + p=c->data; + j=c->num; + i=j>>2; +#ifdef PURIFY + if ((j&0x03) == 0) p[i]=0; +#endif + l=p[i]; + M_p_c2nl(cp,l,j&0x03); + p[i]=l; + i++; + /* i is the next 'undefined word' */ + if (c->num >= SHA_LAST_BLOCK) + { + for (; iNh; + p[SHA_LBLOCK-1]=c->Nl; +#if defined(L_ENDIAN) && defined(SHA1_ASM) + Endian_Reverse32(p[SHA_LBLOCK-2]); + Endian_Reverse32(p[SHA_LBLOCK-1]); +#endif + sha1_block(c,p,64); + cp=md; + l=c->h0; nl2c(l,cp); + l=c->h1; nl2c(l,cp); + l=c->h2; nl2c(l,cp); + l=c->h3; nl2c(l,cp); + l=c->h4; nl2c(l,cp); + + /* clear stuff, sha1_block may be leaving some stuff on the stack + * but I'm not worried :-) */ + c->num=0; +/* memset((char *)&c,0,sizeof(c));*/ + } + diff -urpN john-1.7.2.orig/src/sha_locl.h john-1.7.2/src/sha_locl.h --- john-1.7.2.orig/src/sha_locl.h 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/sha_locl.h 2008-02-20 14:19:36 +0000 @@ -0,0 +1,241 @@ +/* crypto/sha/sha_locl.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#ifdef undef +/* one or the other needs to be defined */ +#ifndef SHA_1 /* FIPE 180-1 */ +#define SHA_0 /* FIPS 180 */ +#endif +#endif + +#ifdef NOCONST +#define const +#endif + +#undef c2nl +#define c2nl(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) )) + +#undef p_c2nl +#define p_c2nl(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + case 3: l|=((unsigned long)(*((c)++))); \ + } \ + } + +#undef c2nl_p +/* NOTE the pointer is not incremented at the end of this */ +#define c2nl_p(c,l,n) { \ + l=0; \ + (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<< 8; \ + case 2: l|=((unsigned long)(*(--(c))))<<16; \ + case 1: l|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +#undef p_c2nl_p +#define p_c2nl_p(c,l,sc,len) { \ + switch (sc) \ + { \ + case 0: l =((unsigned long)(*((c)++)))<<24; \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<<16; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<< 8; \ + } \ + } + +#undef nl2c +#define nl2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#undef c2l +#define c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24)) + +#undef p_c2l +#define p_c2l(c,l,n) { \ + switch (n) { \ + case 0: l =((unsigned long)(*((c)++))); \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + case 3: l|=((unsigned long)(*((c)++)))<<24; \ + } \ + } + +#undef c2l_p +/* NOTE the pointer is not incremented at the end of this */ +#define c2l_p(c,l,n) { \ + l=0; \ + (c)+=n; \ + switch (n) { \ + case 3: l =((unsigned long)(*(--(c))))<<16; \ + case 2: l|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef p_c2l_p +#define p_c2l_p(c,l,sc,len) { \ + switch (sc) \ + { \ + case 0: l =((unsigned long)(*((c)++))); \ + if (--len == 0) break; \ + case 1: l|=((unsigned long)(*((c)++)))<< 8; \ + if (--len == 0) break; \ + case 2: l|=((unsigned long)(*((c)++)))<<16; \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff)) + +#undef ROTATE +#if defined(WIN32) +#define ROTATE(a,n) _lrotl(a,n) +#else +#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#endif + +/* A nice byte order reversal from Wei Dai */ +#if defined(WIN32) +/* 5 instructions with rotate instruction, else 9 */ +#define Endian_Reverse32(a) \ + { \ + unsigned long l=(a); \ + (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \ + } +#else +/* 6 instructions with rotate instruction, else 8 */ +#define Endian_Reverse32(a) \ + { \ + unsigned long l=(a); \ + l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \ + (a)=ROTATE(l,16L); \ + } +#endif + +/* As pointed out by Wei Dai , F() below can be + * simplified to the code in F_00_19. Wei attributes these optimisations + * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel. + * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) + * I've just become aware of another tweak to be made, again from Wei Dai, + * in F_40_59, (x&a)|(y&a) -> (x|y)&a + */ +#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) +#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) +#define F_60_79(b,c,d) F_20_39(b,c,d) + +#ifdef SHA_0 +#undef Xupdate +#define Xupdate(a,i,ia,ib,ic,id) X[(i)&0x0f]=(a)=\ + (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]); +#endif +#ifdef SHA_1 +#undef Xupdate +#define Xupdate(a,i,ia,ib,ic,id) (a)=\ + (ia[(i)&0x0f]^ib[((i)+2)&0x0f]^ic[((i)+8)&0x0f]^id[((i)+13)&0x0f]);\ + X[(i)&0x0f]=(a)=ROTATE((a),1); +#endif + +#define BODY_00_15(i,a,b,c,d,e,f,xa) \ + (f)=xa[i]+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_16_19(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,i,xa,xb,xc,xd); \ + (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_20_31(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,i,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_32_39(i,a,b,c,d,e,f,xa) \ + Xupdate(f,i,xa,xa,xa,xa); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_40_59(i,a,b,c,d,e,f,xa) \ + Xupdate(f,i,xa,xa,xa,xa); \ + (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ + (b)=ROTATE((b),30); + +#define BODY_60_79(i,a,b,c,d,e,f,xa) \ + Xupdate(f,i,xa,xa,xa,xa); \ + (f)=X[(i)&0x0f]+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ + (b)=ROTATE((b),30); diff -urpN john-1.7.2.orig/src/smbencrypt.c john-1.7.2/src/smbencrypt.c --- john-1.7.2.orig/src/smbencrypt.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/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.2.orig/src/stages_mmx_md5.S john-1.7.2/src/stages_mmx_md5.S --- john-1.7.2.orig/src/stages_mmx_md5.S 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/stages_mmx_md5.S 2008-02-20 14:19:36 +0000 @@ -0,0 +1,192 @@ +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 diff -urpN john-1.7.2.orig/src/stages_sse2_md5.S john-1.7.2/src/stages_sse2_md5.S --- john-1.7.2.orig/src/stages_sse2_md5.S 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/stages_sse2_md5.S 2008-02-20 14:19:36 +0000 @@ -0,0 +1,320 @@ +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 diff -urpN john-1.7.2.orig/src/undrop.c john-1.7.2/src/undrop.c --- john-1.7.2.orig/src/undrop.c 1970-01-01 00:00:00 +0000 +++ john-1.7.2/src/undrop.c 2008-02-20 14:19:36 +0000 @@ -0,0 +1,73 @@ +/* + * Eggdrop userfile converter + * Copyright (c) 2002 by Sun-Zero + * This is a free software distributable under terms of the GNU GPL. + * See the file COPYING for details. + * + * 2003-04-21 +*/ + +#include +#include +#include + + +#define USERFILE_HEADER "#4v:" +#define USERNAME_LENGTH 11 +#define PASSWORD_LENGTH 13 +#define MAX_FLAGS_LENGTH 32 +#define BUFSIZE 512 + +int undrop(int argc, char *argv[]) { + + FILE *userfile; + char username[USERNAME_LENGTH]; + char password[PASSWORD_LENGTH]; + char flags[MAX_FLAGS_LENGTH]; + char t_username[BUFSIZE]; + char t_flags[BUFSIZE]; + char t_line[BUFSIZE]; + + if (argc != 2) { + userfile = stdin; + printf("# userfile reading from stdin\n"); + } else { + if ((userfile = fopen(argv[1], "rt")) == NULL) { + fprintf(stderr, "opening userfile\n"); + userfile = stdin; + } + } + + + if (fgets(t_line, sizeof(t_line) - 1, userfile) == NULL) + return 1; + + if (strncmp(t_line, USERFILE_HEADER, strlen(USERFILE_HEADER)) != 0) { + fprintf(stderr, "usefile format is wrong\n"); + return 1; + } else { + printf("# userfile format OK\n\n"); + } + + while (fgets(t_line, sizeof(t_line) - 1, userfile) != NULL) { + if (sscanf(t_line, "%10s - %24s\n", t_username, t_flags) == 2) { + if (strncmp(t_username, "! ", 2) != 0 && + strncmp(t_username, "--", 2) != 0 && + strncmp(t_username, "&&", 2) != 0 && + strncmp(t_username, "::", 2) != 0 && + strncmp(t_username, "$$", 2) != 0 + ) { + strncpy(username, t_username, USERNAME_LENGTH); + strncpy(flags, t_flags, MAX_FLAGS_LENGTH); + } + } + + if (strncmp(t_line, "--PASS +", 8) == 0) { + sscanf(t_line, "--PASS %s", password); + printf("%s:%s:::%s:\n", username, password, flags); + } + fflush(stdout); + } + fclose(userfile); + return 0; +} diff -urpN john-1.7.2.orig/src/x86-64.S john-1.7.2/src/x86-64.S --- john-1.7.2.orig/src/x86-64.S 2006-05-21 01:28:10 +0000 +++ john-1.7.2/src/x86-64.S 2008-02-20 14:19:36 +0000 @@ -13,6 +13,9 @@ #define DES_bs_crypt _DES_bs_crypt #define DES_bs_crypt_25 _DES_bs_crypt_25 #define DES_bs_crypt_LM _DES_bs_crypt_LM +#define nt_buffer8x _nt_buffer8x +#define output8x _output8x +#define nt_crypt_all_x86_64 _nt_crypt_all_x86_64 #endif #ifdef ALIGN_LOG @@ -1040,3 +1043,236 @@ DES_bs_crypt_LM_loop: subl $1,rounds jnz DES_bs_crypt_LM_loop ret + + +/* +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 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) + +#define STEP(f, a, b, c, d, x, s) + a += f(b, c, d) + x; + a = (a << s) | (a >> (32 - s)); +*/ +#define STEP1(aa, bb, cc, dd, aa3, bb3, cc3, dd3, x, s, base) \ + paddd (512*base)+(x*32)+nt_buffer8x, aa; \ + paddd (512*base)+(x*32)+16+nt_buffer8x, 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, aa; \ + paddd (512*base)+(x*32)+16+nt_buffer8x, 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, aa; \ + paddd (512*base)+(x*32)+16+nt_buffer8x, 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, a; \ + movdqa const_init_a, a3; \ + movdqa const_init_b, b; \ + movdqa const_init_b, b3; \ + movdqa const_init_c, c; \ + movdqa const_init_c, c3; \ + movdqa const_init_d, d; \ + movdqa const_init_d, d3; \ + \ + paddd (512*base)+nt_buffer8x, a; \ + paddd (512*base)+16+nt_buffer8x, 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, b; \ + paddd (512*base)+416+16+nt_buffer8x, b3; \ + pxor d, t1; \ + pxor d3,t13; \ + pxor c, t1; \ + pxor c3,t13; \ + paddd t1, b; \ + paddd t13,b3; \ + \ + movdqa a, (128*base)+output8x; \ + movdqa a3, (128*base)+16+output8x; \ + movdqa b, (128*base)+32+output8x; \ + movdqa b3, (128*base)+32+16+output8x; \ + movdqa c, (128*base)+64+output8x; \ + movdqa c3, (128*base)+64+16+output8x; \ + movdqa d, (128*base)+96+output8x; \ + movdqa d3, (128*base)+96+16+output8x; + +.text + +DO_ALIGN(6) + +nt_crypt_all_x86_64: + movdqa const_stage2, t3 + movdqa const_stage3, t4 + + NT_CRYPT_BODY(0) + NT_CRYPT_BODY(1) + NT_CRYPT_BODY(2) + NT_CRYPT_BODY(3) + + ret diff -urpN john-1.7.2.orig/src/x86-64.h john-1.7.2/src/x86-64.h --- john-1.7.2.orig/src/x86-64.h 2006-05-15 16:38:00 +0000 +++ john-1.7.2/src/x86-64.h 2008-02-20 14:19:36 +0000 @@ -45,4 +45,6 @@ #define BF_ASM 0 #define BF_SCALE 1 +#define NT_X86_64 + #endif diff -urpN john-1.7.2.orig/src/x86-mmx.h john-1.7.2/src/x86-mmx.h --- john-1.7.2.orig/src/x86-mmx.h 2002-04-11 17:55:55 +0000 +++ john-1.7.2/src/x86-mmx.h 2008-02-20 14:19:36 +0000 @@ -58,4 +58,7 @@ #define BF_ASM 1 #define BF_SCALE 1 +#define MMX_TYPE " MMX" +#define MMX_COEF 2 + #endif diff -urpN john-1.7.2.orig/src/x86-sse.S john-1.7.2/src/x86-sse.S --- john-1.7.2.orig/src/x86-sse.S 2006-05-10 05:50:51 +0000 +++ john-1.7.2/src/x86-sse.S 2008-02-20 14:19:36 +0000 @@ -15,6 +15,11 @@ #define DES_bs_crypt _DES_bs_crypt #define DES_bs_crypt_25 _DES_bs_crypt_25 #define DES_bs_crypt_LM _DES_bs_crypt_LM +#define nt_crypt_all_sse2 _nt_crypt_all_sse2 +#define nt_buffer4x _nt_buffer4x +#define nt_buffer1x _nt_buffer1x +#define output4x _output4x +#define output1x _output1x #endif /* @@ -1289,3 +1294,238 @@ DES_bs_crypt_LM_loop: jnz DES_bs_crypt_LM_loop popl %esi ret + + + +/* +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 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) + +#define STEP(f, a, b, c, d, x, s) + a += f(b, c, d) + x; + a = (a << s) | (a >> (32 - s)); +*/ +#define STEP1(aa, bb, cc, dd, aa3, bb3, cc3, dd3, x, s, base) \ + paddd (256*base)+(x*16)+nt_buffer4x, aa; \ + add (64*base)+(x*4)+nt_buffer1x, aa3; \ + movdqa cc, t1; \ + mov cc3, t13; \ + pxor dd, t1; \ + xor dd3, t13; \ + pand bb, t1; \ + and bb3, t13; \ + pxor dd, t1; \ + xor dd3, t13; \ + paddd t1, aa; \ + add t13, aa3; \ + movdqa aa, t2; \ + rol $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; \ + add (64*base)+(x*4)+nt_buffer1x, aa3; \ + movdqa cc, t1; \ + mov cc3, t13; \ + movdqa cc, t2; \ + mov cc3, t23; \ + por dd, t1; \ + or dd3, t13; \ + pand dd, t2; \ + and dd3, t23; \ + pand bb, t1; \ + and bb3, t13; \ + paddd t3, aa; \ + add Q2, aa3; \ + por t2, t1; \ + or t23, t13; \ + paddd t1, aa; \ + add t13, aa3; \ + movdqa aa, t1; \ + rol $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; \ + add (64*base)+(x*4)+nt_buffer1x, aa3; \ + movdqa dd, t1; \ + mov dd3, t13; \ + pxor cc, t1; \ + xor cc3, t13; \ + paddd t4, aa; \ + add Q3, aa3; \ + pxor bb, t1; \ + xor bb3, t13; \ + paddd t1, aa; \ + add t13, aa3; \ + movdqa aa, t1; \ + rol $s, aa3; \ + pslld $s, aa; \ + psrld $(32-s), t1; \ + por t1, aa; + +#define NT_CRYPT_BODY(base) \ + movdqa const_init_a, a; \ + mov const_init_a, a3; \ + movdqa const_init_b, b; \ + mov const_init_b, b3; \ + movdqa const_init_c, c; \ + mov const_init_c, c3; \ + movdqa const_init_d, d; \ + mov const_init_d, d3; \ + \ + paddd (256*base)+nt_buffer4x, a; \ + add (64*base)+nt_buffer1x, a3; \ + pslld $3, a; \ + rol $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; \ + mov a3, t13; \ + paddd (256*base)+208+nt_buffer4x, b; \ + add (64*base)+52+nt_buffer1x, b3; \ + pxor d, t1; \ + xor d3,t13; \ + pxor c, t1; \ + xor c3,t13; \ + paddd t1, b; \ + add t13,b3; \ + \ + movdqa a, (64*base)+output4x; \ + mov a3, (16*base)+output1x; \ + movdqa b, (64*base)+16+output4x; \ + mov b3, (16*base)+4+output1x; \ + movdqa c, (64*base)+32+output4x; \ + mov c3, (16*base)+8+output1x; \ + movdqa d, (64*base)+48+output4x; \ + mov 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 diff -urpN john-1.7.2.orig/src/x86-sse.h john-1.7.2/src/x86-sse.h --- john-1.7.2.orig/src/x86-sse.h 2006-05-10 05:25:57 +0000 +++ john-1.7.2/src/x86-sse.h 2008-02-20 14:19:36 +0000 @@ -58,4 +58,9 @@ #define BF_ASM 1 #define BF_SCALE 1 +#define MMX_TYPE " SSE2" +#define MMX_COEF 4 + +#define NT_SSE2 + #endif