From 96df7280fb2ff09ffea3d188b32f904ebf495bf6 Mon Sep 17 00:00:00 2001
From: magnum <magnum>
Date: Mon, 12 Sep 2011 22:34:46 +0200
Subject: [PATCH 2/4] md5_gen & raw-md5u, more Unicode fixes

---
 src/md5_gen_fmt.c      |   32 +++++++++++++++++---------------
 src/rawmd5u_fmt_plug.c |    2 +-
 2 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/src/md5_gen_fmt.c b/src/md5_gen_fmt.c
index 93cc99a..6b2d128 100644
--- a/src/md5_gen_fmt.c
+++ b/src/md5_gen_fmt.c
@@ -288,7 +288,7 @@ static void __SSE_gen_BenchLowLevelFunctions();
 #endif // PARA
 #endif // MMX_COEF == 4
 
-#define PLAINTEXT_LENGTH	55
+#define PLAINTEXT_LENGTH	(27*3+1) // for worst-case UTF-8
 #define MIN_KEYS_PER_CRYPT	1
 #ifdef MD5_SSE_PARA
 // gives us 16 'loops' for para=2 and 10 loops for para==3 (or max of 128 for 2 and 120 for 3)
@@ -873,11 +873,11 @@ static void set_key(char *key, int index)
 	// Ok, if the key is in unicode/utf8, we switch it here one time, and are done with it.
 
 	len = strlen(key);
-	if (len > 55)
-		len = 55;
 
 	if (curdat.store_keys_in_input)
 	{
+		if (len > 55) // we never do UTF-8 -> UTF-16 in this mode
+			len = 55;
 #ifdef MMX_COEF
 		if (md5_gen_use_sse==1) {
 			unsigned int i, cnt;
@@ -937,6 +937,8 @@ static void set_key(char *key, int index)
 	}
 	else
 	{
+		if (len > 55 && !(fmt_MD5gen.params.flags & FMT_UNICODE))
+			len = 55;
 		if(index==0) {
 			//fprintf (stderr, "FULL Cleaning keys\n");
 			MD5GenBaseFunc__clean_input_full();
@@ -2620,7 +2622,7 @@ static inline void __append_string(char *Str, unsigned len)
 				__SSE_append_string_to_input((unsigned char*)(&input_buf[idx]),idx_mod,Str,len,bf_ptr,1);
 			}
 		} else {
-			if (!options.encoding_7_bit) {
+			if (!options.encoding_7_bit && !options.iso8859_1) {
 				UTF16 utf16Str[27+1]; // 27 chars is 'max' that fits in SSE without overflow, so that is where we limit it at now
 				int outlen;
 
@@ -2649,7 +2651,7 @@ static inline void __append_string(char *Str, unsigned len)
 	}
 #endif
 	if (md5_unicode_convert) {
-		if (!options.encoding_7_bit) {
+		if (!options.encoding_7_bit && !options.iso8859_1) {
 			UTF16 utf16Str[256+1];
 			int outlen;
 			outlen = enc_to_utf16(utf16Str, 256, (unsigned char*)Str, len) * sizeof(UTF16);
@@ -2715,7 +2717,7 @@ static inline void __append2_string(char *Str, unsigned len)
 				__SSE_append_string_to_input((unsigned char*)(&input_buf2[idx]),idx_mod,Str,len,bf_ptr,1);
 			}
 		} else {
-			if (!options.encoding_7_bit) {
+			if (!options.encoding_7_bit && !options.iso8859_1) {
 				UTF16 utf16Str[27+1]; // 27 chars is 'max' that fits in SSE without overflow, so that is where we limit it at now
 				int outlen;
 
@@ -2744,7 +2746,7 @@ static inline void __append2_string(char *Str, unsigned len)
 	}
 #endif
 	if (md5_unicode_convert) {
-		if (!options.encoding_7_bit) {
+		if (!options.encoding_7_bit && !options.iso8859_1) {
 			UTF16 utf16Str[256+1];
 			int outlen;
 			outlen = enc_to_utf16(utf16Str, 256, (unsigned char*)Str, len) * sizeof(UTF16);
@@ -2915,7 +2917,7 @@ void MD5GenBaseFunc__append_keys()
 			unsigned idx_mod = j&(MMX_COEF-1);
 			unsigned bf_ptr = (total_len[idx] >> ((32/MMX_COEF)*idx_mod)) & 0xFF;
 			if (md5_unicode_convert) {
-				if (!options.encoding_7_bit) {
+				if (!options.encoding_7_bit && !options.iso8859_1) {
 					UTF16 utf16Str[27+1]; // 27 chars is 'max' that fits in SSE without overflow, so that is where we limit it at now
 					int outlen;
 					outlen = enc_to_utf16(utf16Str, 27, (unsigned char*)saved_key[j], saved_key_len[j]) * sizeof(UTF16);
@@ -2936,7 +2938,7 @@ void MD5GenBaseFunc__append_keys()
 	}
 #endif
 	if (md5_unicode_convert) {
-		if (!options.encoding_7_bit) {
+		if (!options.encoding_7_bit && !options.iso8859_1) {
 			for (j = 0; j < m_count; ++j) {
 				int z;
 				unsigned char *cp, *cpi;
@@ -3000,7 +3002,7 @@ void MD5GenBaseFunc__append_keys2()
 			unsigned idx_mod = j&(MMX_COEF-1);
 			unsigned bf_ptr = (total_len2[idx] >> ((32/MMX_COEF)*idx_mod)) & 0xFF;
 			if (md5_unicode_convert) {
-				if (!options.encoding_7_bit) {
+				if (!options.encoding_7_bit && !options.iso8859_1) {
 					UTF16 utf16Str[27+1]; // 27 chars is 'max' that fits in SSE without overflow, so that is where we limit it at now
 					int outlen;
 					outlen = enc_to_utf16(utf16Str, 27, (unsigned char*)saved_key[j], saved_key_len[j]) * sizeof(UTF16);
@@ -3021,7 +3023,7 @@ void MD5GenBaseFunc__append_keys2()
 	}
 #endif
 	if (md5_unicode_convert) {
-		if (!options.encoding_7_bit) {
+		if (!options.encoding_7_bit && !options.iso8859_1) {
 			for (j = 0; j < m_count; ++j) {
 				int z;
 				unsigned char *cp, *cpi;
@@ -4496,7 +4498,7 @@ void MD5GenBaseFunc__overwrite_salt_to_input1_no_size_fix()
 #ifdef MMX_COEF
 	if (md5_gen_use_sse==1) {
 		if (md5_unicode_convert) {
-			if (!options.encoding_7_bit) {
+			if (!options.encoding_7_bit && !options.iso8859_1) {
 				UTF16 utf16Str[27+1]; // 27 chars is 'max' that fits in SSE without overflow, so that is where we limit it at now
 				int outlen;
 				outlen = enc_to_utf16(utf16Str, 27, (unsigned char*)cursalt, saltlen) * sizeof(UTF16);
@@ -4517,7 +4519,7 @@ void MD5GenBaseFunc__overwrite_salt_to_input1_no_size_fix()
 	}
 #endif
 	if (md5_unicode_convert) {
-		if (!options.encoding_7_bit) {
+		if (!options.encoding_7_bit && !options.iso8859_1) {
 			UTF16 utf16Str[256+1];
 			int outlen;
 			outlen = enc_to_utf16(utf16Str, 256, (unsigned char*)cursalt, saltlen) * sizeof(UTF16);
@@ -4569,7 +4571,7 @@ void MD5GenBaseFunc__overwrite_salt_to_input2_no_size_fix()
 #ifdef MMX_COEF
 	if (md5_gen_use_sse==1) {
 		if (md5_unicode_convert) {
-			if (!options.encoding_7_bit) {
+			if (!options.encoding_7_bit && !options.iso8859_1) {
 				UTF16 utf16Str[27+1]; // 27 chars is 'max' that fits in SSE without overflow, so that is where we limit it at now
 				int outlen;
 				outlen = enc_to_utf16(utf16Str, 27, (unsigned char*)cursalt, saltlen) * sizeof(UTF16);
@@ -4590,7 +4592,7 @@ void MD5GenBaseFunc__overwrite_salt_to_input2_no_size_fix()
 	}
 #endif
 	if (md5_unicode_convert) {
-		if (!options.encoding_7_bit) {
+		if (!options.encoding_7_bit && !options.iso8859_1) {
 			UTF16 utf16Str[256+1];
 			int outlen;
 			outlen = enc_to_utf16(utf16Str, 256, (unsigned char*)cursalt, saltlen) * sizeof(UTF16);
diff --git a/src/rawmd5u_fmt_plug.c b/src/rawmd5u_fmt_plug.c
index bf845d7..9ef1cdc 100644
--- a/src/rawmd5u_fmt_plug.c
+++ b/src/rawmd5u_fmt_plug.c
@@ -112,7 +112,7 @@ static void rawmd5u_init(struct fmt_main *pFmt)
 {
 	if (options.utf8) {
 		// We may need three octets of input to produce two octets of key
-		fmt_rawmd5u.params.plaintext_length = 3 * PLAINTEXT_LENGTH / 2;
+		fmt_rawmd5u.params.plaintext_length = PLAINTEXT_LENGTH / 2 * 3;
 		rawmd5u_tests[1].ciphertext = "94a4e171de16580742c4d141e6607bf7";
 		rawmd5u_tests[1].plaintext = "\xE2\x82\xAC";	// Euro sign
 		rawmd5u_tests[2].ciphertext = "03c60810f0e54d16e826aca385d776c8";
-- 
1.7.4.1

