diff -ruN john-1.6.39/src/DOMINOSEC_fmt.c john-1.6.39-dominosec/src/DOMINOSEC_fmt.c --- john-1.6.39/src/DOMINOSEC_fmt.c 1970-01-01 01:00:00.000000000 +0100 +++ john-1.6.39-dominosec/src/DOMINOSEC_fmt.c 2005-12-07 17:37:52.125000000 +0100 @@ -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" + +#define BENCHMARK_COMMENT "" +#define BENCHMARK_LENGTH -1 + +#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 -ruN john-1.6.39/src/Makefile john-1.6.39-dominosec/src/Makefile --- john-1.6.39/src/Makefile 2005-09-03 02:24:04.000000000 +0200 +++ john-1.6.39-dominosec/src/Makefile 2005-12-04 21:05:11.703125000 +0100 @@ -28,6 +28,7 @@ BF_fmt.o BF_std.o \ AFS_fmt.o \ LM_fmt.o \ + DOMINOSEC_fmt.o \ batch.o bench.o charset.o common.o compiler.o config.o cracker.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 \ Files john-1.6.39/src/gmon.out and john-1.6.39-dominosec/src/gmon.out differ diff -ruN john-1.6.39/src/john.c john-1.6.39-dominosec/src/john.c --- john-1.6.39/src/john.c 2004-06-23 01:10:30.000000000 +0200 +++ john-1.6.39-dominosec/src/john.c 2005-12-07 17:52:58.187500000 +0100 @@ -38,6 +38,7 @@ 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_DOMINOSEC; extern int unshadow(int argc, char **argv); extern int unafs(int argc, char **argv); @@ -64,6 +65,7 @@ john_register_one(&fmt_BF); john_register_one(&fmt_AFS); john_register_one(&fmt_LM); + john_register_one(&fmt_DOMINOSEC); if (!fmt_list) { fprintf(stderr, "Unknown ciphertext format name requested\n"); diff -ruN john-1.6.39/src/options.c john-1.6.39-dominosec/src/options.c --- john-1.6.39/src/options.c 2005-09-08 21:18:28.000000000 +0200 +++ john-1.6.39-dominosec/src/options.c 2005-11-25 09:00:27.515625000 +0100 @@ -100,8 +100,8 @@ "--shells=[-]SHELL[,..] load users with[out] this (these) shell(s) only\n" \ "--salts=[-]COUNT load salts with[out] at least COUNT passwords " \ "only\n" \ -"--format=NAME force ciphertext format NAME: " \ - "DES/BSDI/MD5/BF/AFS/LM\n" \ +"--format=NAME force ciphertext: " \ + "DES/BSDI/MD5/BF/AFS/LM/DOMINOSEC\n" \ "--save-memory=LEVEL enable memory saving, at LEVEL 1..3\n" void opt_init(int argc, char **argv)