diff --git a/MixDecrypt/MixDecrypt.cpp b/MixDecrypt/MixDecrypt.cpp deleted file mode 100644 index 6af0677fcb..0000000000 --- a/MixDecrypt/MixDecrypt.cpp +++ /dev/null @@ -1,4 +0,0 @@ -// This is the main DLL file. - -#include "MixDecrypt.h" - diff --git a/MixDecrypt/MixDecrypt.h b/MixDecrypt/MixDecrypt.h deleted file mode 100644 index fd95877bdf..0000000000 --- a/MixDecrypt/MixDecrypt.h +++ /dev/null @@ -1,26 +0,0 @@ -// MixDecrypt.h -#pragma once - -#pragma unmanaged -#include "mix_decode.h" -#pragma managed - -using namespace System; - -namespace MixDecrypt { - - public ref class MixDecrypt - { - public: - static array^ BlowfishKey( array^ src ) - { - array^ dest = gcnew array( 56 ); - pin_ptr s = &src[0]; - pin_ptr d = &dest[0]; - - get_blowfish_key( s, d ); - - return dest; - } - }; -} diff --git a/MixDecrypt/MixDecrypt.vcproj b/MixDecrypt/MixDecrypt.vcproj deleted file mode 100644 index 32c0e614e6..0000000000 --- a/MixDecrypt/MixDecrypt.vcproj +++ /dev/null @@ -1,199 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/MixDecrypt/mix_decode.h b/MixDecrypt/mix_decode.h deleted file mode 100644 index 61129f35c4..0000000000 --- a/MixDecrypt/mix_decode.h +++ /dev/null @@ -1,428 +0,0 @@ -#include - -const static char* pubkey_str = "AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V"; - -const static char char2num[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, - -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; - -typedef unsigned int dword; -typedef unsigned short word; -typedef unsigned char byte; - -typedef dword bignum4[4]; -typedef dword bignum[64]; -typedef dword bignum130[130]; - -static struct -{ - bignum key1; - bignum key2; - dword len; -} pubkey; -static bignum glob1; -static dword glob1_bitlen, glob1_len_x2; -static bignum130 glob2; -static bignum4 glob1_hi, glob1_hi_inv; -static dword glob1_hi_bitlen; -static dword glob1_hi_inv_lo, glob1_hi_inv_hi; - -static void init_bignum(bignum n, dword val, dword len) -{ - memset((void *)n, 0, len * 4); - n[0] = val; -} - -static void move_key_to_big(bignum n, char *key, dword klen, dword blen) -{ - dword sign; - unsigned i; - - if (key[0] & 0x80) sign = 0xff; - else sign = 0; - - for (i = blen*4; i > klen; i--) - ((char *)n)[i-1] = sign; - for (; i > 0; i--) - ((char *)n)[i-1] = key[klen-i]; -} - -static void key_to_bignum(bignum n, char *key, dword len) -{ - dword keylen; - int i; - - if (key[0] != 2) return; - key++; - - if (key[0] & 0x80) - { - keylen = 0; - for (i = 0; i < (key[0] & 0x7f); i++) keylen = (keylen << 8) | key[i+1]; - key += (key[0] & 0x7f) + 1; - } - else - { - keylen = key[0]; - key++; - } - if (keylen <= len*4) - move_key_to_big(n, key, keylen, len); -} - -static dword len_bignum(bignum n, dword len) -{ - int i; - i = len-1; - while ((i >= 0) && (n[i] == 0)) i--; - return i+1; -} - -static dword bitlen_bignum(bignum n, dword len) -{ - dword ddlen, bitlen, mask; - ddlen = len_bignum(n, len); - if (ddlen == 0) return 0; - bitlen = ddlen * 32; - mask = 0x80000000; - while ((mask & n[ddlen-1]) == 0) { - mask >>= 1; - bitlen--; - } - return bitlen; -} - -static void init_pubkey() -{ - dword i, i2, tmp; - char keytmp[256]; - - init_bignum(pubkey.key2, 0x10001, 64); - - i = 0; - i2 = 0; - while (i < strlen(pubkey_str)) - { - tmp = char2num[pubkey_str[i++]]; - tmp <<= 6; tmp |= char2num[pubkey_str[i++]]; - tmp <<= 6; tmp |= char2num[pubkey_str[i++]]; - tmp <<= 6; tmp |= char2num[pubkey_str[i++]]; - keytmp[i2++] = (tmp >> 16) & 0xff; - keytmp[i2++] = (tmp >> 8) & 0xff; - keytmp[i2++] = tmp & 0xff; - } - key_to_bignum(pubkey.key1, keytmp, 64); - pubkey.len = bitlen_bignum(pubkey.key1, 64) - 1; -} - -static dword len_predata() -{ - dword a = (pubkey.len - 1) / 8; - return (55 / a + 1) * (a + 1); -} - -static long int cmp_bignum(bignum n1, bignum n2, dword len) -{ - n1 += len-1; - n2 += len-1; - while (len > 0) { - if (*n1 < *n2) return -1; - if (*n1 > *n2) return 1; - n1--; - n2--; - len--; - } - return 0; -} - -static void mov_bignum(bignum dest, bignum src, dword len) -{ - memmove(dest, src, len*4); -} - -static void shr_bignum(bignum n, dword bits, unsigned long int len) -{ - dword i, i2; - - i2 = bits / 32; - if (i2 > 0) { - for (i = 0; i < len - i2; i++) n[i] = n[i + i2]; - for (; i < len; i++) n[i] = 0; - bits = bits % 32; - } - if (bits == 0) return; - for (i = 0; i < len - 1; i++) n[i] = (n[i] >> bits) | (n[i + 1] << (32 - -bits)); - n[i] = n[i] >> bits; -} - -static void shl_bignum(bignum n, dword bits, dword len) -{ - dword i, i2; - - i2 = bits / 32; - if (i2 > 0) { - for (i = len - 1; i > i2; i--) n[i] = n[i - i2]; - for (; i > 0; i--) n[i] = 0; - bits = bits % 32; - } - if (bits == 0) return; - for (i = len - 1; i > 0; i--) n[i] = (n[i] << bits) | (n[i - 1] >> (32 - -bits)); - n[0] <<= bits; -} - -static dword sub_bignum(bignum dest, bignum src1, bignum src2, dword carry, dword len) -{ - dword i1, i2; - - len += len; - while (--len != -1) { - i1 = *(word *)src1; - i2 = *(word *)src2; - *(word *)dest = i1 - i2 - carry; - src1 = (dword *)(((word *)src1) + 1); - src2 = (dword *)(((word *)src2) + 1); - dest = (dword *)(((word *)dest) + 1); - if ((i1 - i2 - carry) & 0x10000) carry = 1; else carry = 0; - } - return carry; -} - -static void inv_bignum(bignum n1, bignum n2, dword len) -{ - bignum n_tmp; - dword n2_bytelen, bit; - long int n2_bitlen; - - init_bignum(n_tmp, 0, len); - init_bignum(n1, 0, len); - n2_bitlen = bitlen_bignum(n2, len); - bit = ((dword)1) << (n2_bitlen % 32); - n1 += ((n2_bitlen + 32) / 32) - 1; - n2_bytelen = ((n2_bitlen - 1) / 32) * 4; - n_tmp[n2_bytelen / 4] |= ((dword)1) << ((n2_bitlen - 1) & 0x1f); - - while (n2_bitlen > 0) { - n2_bitlen--; - shl_bignum(n_tmp, 1, len); - if (cmp_bignum(n_tmp, n2, len) != -1) { - sub_bignum(n_tmp, n_tmp, n2, 0, len); - *n1 |= bit; - } - bit >>= 1; - if (bit == 0) { - n1--; - bit = 0x80000000; - } - } - init_bignum(n_tmp, 0, len); -} - -static void inc_bignum(bignum n, dword len) -{ - while ((++*n == 0) && (--len > 0)) n++; -} - -static void init_two_dw(bignum n, dword len) -{ - mov_bignum(glob1, n, len); - glob1_bitlen = bitlen_bignum(glob1, len); - glob1_len_x2 = (glob1_bitlen + 15) / 16; - mov_bignum(glob1_hi, glob1 + len_bignum(glob1, len) - 2, 2); - glob1_hi_bitlen = bitlen_bignum(glob1_hi, 2) - 32; - shr_bignum(glob1_hi, glob1_hi_bitlen, 2); - inv_bignum(glob1_hi_inv, glob1_hi, 2); - shr_bignum(glob1_hi_inv, 1, 2); - glob1_hi_bitlen = (glob1_hi_bitlen + 15) % 16 + 1; - inc_bignum(glob1_hi_inv, 2); - if (bitlen_bignum(glob1_hi_inv, 2) > 32) - { - shr_bignum(glob1_hi_inv, 1, 2); - glob1_hi_bitlen--; - } - glob1_hi_inv_lo = *(word *)glob1_hi_inv; - glob1_hi_inv_hi = *(((word *)glob1_hi_inv) + 1); -} - -static void mul_bignum_word(bignum n1, bignum n2, dword mul, dword len) -{ - dword i, tmp; - - tmp = 0; - for (i = 0; i < len; i++) { - tmp = mul * (*(word *)n2) + *(word *)n1 + tmp; - *(word *)n1 = tmp; - n1 = (dword *)(((word *)n1) + 1); - n2 = (dword *)(((word *)n2) + 1); - tmp >>= 16; - } - *(word *)n1 += tmp; -} - -static void mul_bignum(bignum dest, bignum src1, bignum src2, dword len) -{ - dword i; - - init_bignum(dest, 0, len*2); - for (i = 0; i < len*2; i++) { - mul_bignum_word(dest, src1, *(word *)src2, len*2); - src2 = (dword *)(((word *)src2) + 1); - dest = (dword *)(((word *)dest) + 1); - } -} - -static void not_bignum(bignum n, dword len) -{ - dword i; - for (i = 0; i < len; i++) *(n++) = ~*n; -} - -static void neg_bignum(bignum n, dword len) -{ - not_bignum(n, len); - inc_bignum(n, len); -} - -static dword get_mulword(bignum n) -{ - dword i; - word *wn; - - wn = (word *)n; - i = (((((((((*(wn-1) ^ 0xffff) & 0xffff) * glob1_hi_inv_lo + 0x10000) >> 1) - + (((*(wn-2) ^ 0xffff) * glob1_hi_inv_hi + glob1_hi_inv_hi) >> 1) + 1) - >> 16) + ((((*(wn-1) ^ 0xffff) & 0xffff) * glob1_hi_inv_hi) >> 1) + - (((*wn ^ 0xffff) * glob1_hi_inv_lo) >> 1) + 1) >> 14) + glob1_hi_inv_hi - * (*wn ^ 0xffff) * 2) >> glob1_hi_bitlen; - if (i > 0xffff) i = 0xffff; - return i & 0xffff; -} - -static void dec_bignum(bignum n, dword len) -{ - while ((--*n == 0xffffffff) && (--len > 0)) - n++; -} - -static void calc_a_bignum(bignum n1, bignum n2, bignum n3, dword len) -{ - dword g2_len_x2, len_diff; - word *esi, *edi; - word tmp; - - mul_bignum(glob2, n2, n3, len); - glob2[len*2] = 0; - g2_len_x2 = len_bignum(glob2, len*2+1)*2; - if (g2_len_x2 >= glob1_len_x2) { - inc_bignum(glob2, len*2+1); - neg_bignum(glob2, len*2+1); - len_diff = g2_len_x2 + 1 - glob1_len_x2; - esi = ((word *)glob2) + (1 + g2_len_x2 - glob1_len_x2); - edi = ((word *)glob2) + (g2_len_x2 + 1); - for (; len_diff != 0; len_diff--) { - edi--; - tmp = get_mulword((dword *)edi); - esi--; - if (tmp > 0) { - mul_bignum_word((dword *)esi, glob1, tmp, 2*len); - if ((*edi & 0x8000) == 0) { - if (sub_bignum((dword *)esi, (dword *)esi, glob1, 0, len)) (*edi)--; - } - } - } - neg_bignum(glob2, len); - dec_bignum(glob2, len); - } - mov_bignum(n1, glob2, len); -} - -static void clear_tmp_vars(dword len) -{ - init_bignum(glob1, 0, len); - init_bignum(glob2, 0, len); - init_bignum(glob1_hi_inv, 0, 4); - init_bignum(glob1_hi, 0, 4); - glob1_bitlen = 0; - glob1_hi_bitlen = 0; - glob1_len_x2 = 0; - glob1_hi_inv_lo = 0; - glob1_hi_inv_hi = 0; -} - -static void calc_a_key(bignum n1, bignum n2, bignum n3, bignum n4, dword len) -{ - bignum n_tmp; - dword n3_len, n4_len, n3_bitlen, bit_mask; - - init_bignum(n1, 1, len); - n4_len = len_bignum(n4, len); - init_two_dw(n4, n4_len); - n3_bitlen = bitlen_bignum(n3, n4_len); - n3_len = (n3_bitlen + 31) / 32; - bit_mask = (((dword)1) << ((n3_bitlen - 1) % 32)) >> 1; - n3 += n3_len - 1; - n3_bitlen--; - mov_bignum(n1, n2, n4_len); - while (--n3_bitlen != -1) - { - if (bit_mask == 0) - { - bit_mask = 0x80000000; - n3--; - } - calc_a_bignum(n_tmp, n1, n1, n4_len); - if (*n3 & bit_mask) - calc_a_bignum(n1, n_tmp, n2, n4_len); - else - mov_bignum(n1, n_tmp, n4_len); - bit_mask >>= 1; - } - init_bignum(n_tmp, 0, n4_len); - clear_tmp_vars(len); -} - -static void process_predata(const byte* pre, dword pre_len, byte *buf) -{ - bignum n2, n3; - const dword a = (pubkey.len - 1) / 8; - while (a + 1 <= pre_len) - { - init_bignum(n2, 0, 64); - memmove(n2, pre, a + 1); - calc_a_key(n3, n2, pubkey.key2, pubkey.key1, 64); - - memmove(buf, n3, a); - - pre_len -= a + 1; - pre += a + 1; - buf += a; - } -} - -static void get_blowfish_key(const byte* s, byte* d) -{ - static bool public_key_initialized = false; - if (!public_key_initialized) - { - init_pubkey(); - public_key_initialized = true; - } - byte key[256]; - process_predata(s, len_predata(), key); - memcpy(d, key, 56); -} \ No newline at end of file diff --git a/OpenRa.FileFormats/BlowfishKeyProvider.cs b/OpenRa.FileFormats/BlowfishKeyProvider.cs new file mode 100644 index 0000000000..137104e75a --- /dev/null +++ b/OpenRa.FileFormats/BlowfishKeyProvider.cs @@ -0,0 +1,520 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Linq; + +namespace OpenRa.FileFormats +{ + /* possibly the fugliest C# i've ever seen. */ + + class BlowfishKeyProvider + { + const string pubkeyStr = "AihRvNoIbTn85FZRYNZRcT+i6KpU+maCsEqr3Q5q+LDB5tH7Tz2qQ38V"; + + static sbyte[] char2num = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, + -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}; + + class PublicKey + { + public uint[] key1 = new uint[64]; + public uint[] key2 = new uint[64]; + public uint len; + } + PublicKey pubkey = new PublicKey(); + + uint[] glob1 = new uint[64]; + uint glob1_bitlen, glob1_len_x2; + uint[] glob2 = new uint[130]; + uint[] glob1_hi = new uint[4]; + uint[] glob1_hi_inv = new uint[4]; + uint glob1_hi_bitlen; + uint glob1_hi_inv_lo, glob1_hi_inv_hi; + + void init_bignum(uint[] n, uint val, uint len) + { + for (int i = 0; i < len; i++) n[i] = 0; + n[0] = val; + } + + void move_key_to_big(uint[] n, byte[] key, uint klen, uint blen) + { + byte sign; + + if ((key[0] & 0x80) != 0) sign = 0xff; + else sign = 0; + + unsafe + { + fixed (uint* _pn = &n[0]) + { + byte* pn = (byte*)_pn; + uint i = blen * 4; + for (; i > klen; i--) pn[i - 1] = (byte)sign; + for (; i > 0; i--) pn[i - 1] = key[klen - i]; + } + } + } + + void key_to_bignum(uint[] n, byte[] key, uint len) + { + uint keylen; + int i; + + int j = 0; + + if (key[j] != 2) return; + j++; + + if ((key[j] & 0x80) != 0) + { + keylen = 0; + for (i = 0; i < (key[j] & 0x7f); i++) keylen = (keylen << 8) | key[j + i + 1]; + j += (key[j] & 0x7f) + 1; + } + else + { + keylen = key[j]; + j++; + } + if (keylen <= len * 4) + move_key_to_big(n, key.Skip(j).ToArray(), keylen, len); + } + + uint len_bignum(uint[] n, uint len) + { + uint i; + i = len - 1; + while ((i >= 0) && (n[i] == 0)) i--; + return i + 1; + } + + uint bitlen_bignum(uint[] n, uint len) + { + uint ddlen, bitlen, mask; + ddlen = len_bignum(n, len); + if (ddlen == 0) return 0; + bitlen = ddlen * 32; + mask = 0x80000000; + while ((mask & n[ddlen - 1]) == 0) + { + mask >>= 1; + bitlen--; + } + return bitlen; + } + + void init_pubkey() + { + int i = 0; + uint i2, tmp; + byte[] keytmp = new byte[256]; + + init_bignum(pubkey.key2, 0x10001, 64); + + i2 = 0; + while (i < pubkeyStr.Length) + { + tmp = (uint)char2num[pubkeyStr[i++]]; + tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]]; + tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]]; + tmp <<= 6; tmp |= (uint)(byte)char2num[pubkeyStr[i++]]; + keytmp[i2++] = (byte)((tmp >> 16) & 0xff); + keytmp[i2++] = (byte)((tmp >> 8) & 0xff); + keytmp[i2++] = (byte)(tmp & 0xff); + } + + key_to_bignum(pubkey.key1, keytmp, 64); + pubkey.len = bitlen_bignum(pubkey.key1, 64) - 1; + } + + uint len_predata() + { + uint a = (pubkey.len - 1) / 8; + return (55 / a + 1) * (a + 1); + } + + int cmp_bignum(uint[] n1, uint[] n2, uint len) + { + + while (len > 0) + { + --len; + if (n1[len] < n2[len]) return -1; + if (n1[len] > n2[len]) return 1; + } + return 0; + } + + void mov_bignum(uint[] dest, uint[] src, uint len) + { + Array.Copy(src, dest, len); + } + + void shr_bignum(uint[] n, int bits, int len) + { + int i; int i2 = bits / 32; + + if (i2 > 0) + { + for (i = 0; i < len - i2; i++) n[i] = n[i + i2]; + for (; i < len; i++) n[i] = 0; + bits = bits % 32; + } + if (bits == 0) return; + for (i = 0; i < len - 1; i++) n[i] = (n[i] >> bits) | (n[i + 1] << (32 - + bits)); + n[i] = n[i] >> bits; + } + + void shl_bignum(uint[] n, int bits, int len) + { + int i, i2; + + i2 = bits / 32; + if (i2 > 0) + { + for (i = len - 1; i > i2; i--) n[i] = n[i - i2]; + for (; i > 0; i--) n[i] = 0; + bits = bits % 32; + } + if (bits == 0) return; + for (i = len - 1; i > 0; i--) n[i] = (n[i] << bits) | (n[i - 1] >> (32 - + bits)); + n[0] <<= bits; + } + + uint sub_bignum(uint[] dest, uint[] src1, uint[] src2, uint carry, int len) + { + uint i1, i2; + + len += len; + unsafe + { + fixed (uint* _ps1 = &src1[0]) + fixed (uint* _ps2 = &src2[0]) + fixed (uint* _pd = &dest[0]) + { + ushort* ps1 = (ushort*)_ps1; + ushort* ps2 = (ushort*)_ps2; + ushort* pd = (ushort*)_pd; + + while (--len != -1) + { + i1 = *ps1++; + i2 = *ps2++; + *pd++ = (ushort)(i1 - i2 - carry); + if (((i1 - i2 - carry) & 0x10000) != 0) carry = 1; else carry = 0; + } + } + } + return carry; + } + + unsafe uint sub_bignum(uint* dest, uint* src1, uint* src2, uint carry, int len) + { + uint i1, i2; + + len += len; + + ushort* ps1 = (ushort*)src1; + ushort* ps2 = (ushort*)src2; + ushort* pd = (ushort*)dest; + + while (--len != -1) + { + i1 = *ps1++; + i2 = *ps2++; + *pd++ = (ushort)(i1 - i2 - carry); + if (((i1 - i2 - carry) & 0x10000) != 0) carry = 1; else carry = 0; + + } + return carry; + } + + void inv_bignum(uint[] n1, uint[] n2, uint len) + { + uint[] n_tmp = new uint[64]; + uint n2_bytelen, bit; + int n2_bitlen; + + int j = 0; + + init_bignum(n_tmp, 0, len); + init_bignum(n1, 0, len); + n2_bitlen = (int)bitlen_bignum(n2, len); + bit = ((uint)1) << (n2_bitlen % 32); + j = ((n2_bitlen + 32) / 32) - 1; + n2_bytelen = (uint)((n2_bitlen - 1) / 32) * 4; + n_tmp[n2_bytelen / 4] |= ((uint)1) << ((n2_bitlen - 1) & 0x1f); + + while (n2_bitlen > 0) + { + n2_bitlen--; + shl_bignum(n_tmp, 1, (int)len); + if (cmp_bignum(n_tmp, n2, len) != -1) + { + sub_bignum(n_tmp, n_tmp, n2, 0, (int)len); + n1[j] |= bit; + } + bit >>= 1; + if (bit == 0) + { + j--; + bit = 0x80000000; + } + } + init_bignum(n_tmp, 0, len); + } + + void inc_bignum(uint[] n, uint len) + { + int i = 0; + while ((++n[i] == 0) && (--len > 0)) i++; + } + + void init_two_dw(uint[] n, uint len) + { + mov_bignum(glob1, n, len); + glob1_bitlen = bitlen_bignum(glob1, len); + glob1_len_x2 = (glob1_bitlen + 15) / 16; + mov_bignum(glob1_hi, glob1.Skip((int)len_bignum(glob1, len) - 2).ToArray(), 2); + glob1_hi_bitlen = bitlen_bignum(glob1_hi, 2) - 32; + shr_bignum(glob1_hi, (int)glob1_hi_bitlen, 2); + inv_bignum(glob1_hi_inv, glob1_hi, 2); + shr_bignum(glob1_hi_inv, 1, 2); + glob1_hi_bitlen = (glob1_hi_bitlen + 15) % 16 + 1; + inc_bignum(glob1_hi_inv, 2); + if (bitlen_bignum(glob1_hi_inv, 2) > 32) + { + shr_bignum(glob1_hi_inv, 1, 2); + glob1_hi_bitlen--; + } + glob1_hi_inv_lo = (ushort)glob1_hi_inv[0]; + glob1_hi_inv_hi = (ushort)(glob1_hi_inv[0] >> 16); + } + + unsafe void mul_bignum_word(ushort *pn1, uint[] n2, uint mul, uint len) + { + uint i, tmp; + unsafe + { + fixed (uint* _pn2 = &n2[0]) + { + ushort* pn2 = (ushort*)_pn2; + + tmp = 0; + for (i = 0; i < len; i++) + { + tmp = mul * (*pn2) + (*pn1) + tmp; + *pn1 = (ushort)tmp; + pn1++; + pn2++; + tmp >>= 16; + } + *pn1 += (ushort)tmp; + } + } + } + + void mul_bignum(uint[] dest, uint[] src1, uint[] src2, uint len) + { + uint i; + + unsafe + { + fixed( uint * _psrc2 = &src2[0] ) + fixed(uint* _pdest = &dest[0]) + { + ushort* psrc2 = (ushort*)_psrc2; + ushort* pdest = (ushort*)_pdest; + + init_bignum(dest, 0, len * 2); + for (i = 0; i < len * 2; i++) + mul_bignum_word(pdest++, src1, *psrc2++, len * 2); + } + } + } + + void not_bignum(uint[] n, uint len) + { + uint i; + for (i = 0; i < len; i++) n[i] = ~n[i]; + } + + void neg_bignum(uint[] n, uint len) + { + not_bignum(n, len); + inc_bignum(n, len); + } + + unsafe uint get_mulword(uint* n) + { + ushort* wn = (ushort*)n; + uint i = (uint)((((((((((*(wn - 1) ^ 0xffff) & 0xffff) * glob1_hi_inv_lo + 0x10000) >> 1) + + (((*(wn - 2) ^ 0xffff) * glob1_hi_inv_hi + glob1_hi_inv_hi) >> 1) + 1) + >> 16) + ((((*(wn - 1) ^ 0xffff) & 0xffff) * glob1_hi_inv_hi) >> 1) + + (((*wn ^ 0xffff) * glob1_hi_inv_lo) >> 1) + 1) >> 14) + glob1_hi_inv_hi + * (*wn ^ 0xffff) * 2) >> (int)glob1_hi_bitlen); + if (i > 0xffff) i = 0xffff; + return i & 0xffff; + } + + void dec_bignum(uint[] n, uint len) + { + int i = 0; + while ((--n[i] == 0xffffffff) && (--len > 0)) + i++; + } + + void calc_a_bignum(uint[] n1, uint[] n2, uint[] n3, uint len) + { + uint g2_len_x2, len_diff; + unsafe + { + fixed( uint* g1 = &glob1[0]) + fixed (uint* g2 = &glob2[0]) + { + mul_bignum(glob2, n2, n3, len); + glob2[len * 2] = 0; + g2_len_x2 = len_bignum(glob2, len * 2 + 1) * 2; + if (g2_len_x2 >= glob1_len_x2) + { + inc_bignum(glob2, len * 2 + 1); + neg_bignum(glob2, len * 2 + 1); + len_diff = g2_len_x2 + 1 - glob1_len_x2; + ushort* esi = ((ushort*)g2) + (1 + g2_len_x2 - glob1_len_x2); + ushort* edi = ((ushort*)g2) + (g2_len_x2 + 1); + for (; len_diff != 0; len_diff--) + { + edi--; + uint tmp = get_mulword((uint*)edi); + esi--; + if (tmp > 0) + { + mul_bignum_word(esi, glob1, tmp, 2 * len); + if ((*edi & 0x8000) == 0) + { + if (0 != sub_bignum((uint*)esi, (uint*)esi, g1, 0, (int)len)) (*edi)--; + } + } + } + neg_bignum(glob2, len); + dec_bignum(glob2, len); + } + mov_bignum(n1, glob2, len); + } + } + } + + void clear_tmp_vars(uint len) + { + init_bignum(glob1, 0, len); + init_bignum(glob2, 0, len); + init_bignum(glob1_hi_inv, 0, 4); + init_bignum(glob1_hi, 0, 4); + glob1_bitlen = 0; + glob1_hi_bitlen = 0; + glob1_len_x2 = 0; + glob1_hi_inv_lo = 0; + glob1_hi_inv_hi = 0; + } + + void calc_a_key(uint[] n1, uint[] n2, uint[] n3, uint[] n4, uint len) + { + uint[] n_tmp = new uint[64]; + uint n3_len, n4_len; + int n3_bitlen; + uint bit_mask; + + unsafe + { + fixed (uint* _pn3 = &n3[0]) + { + uint* pn3 = _pn3; + + init_bignum(n1, 1, len); + n4_len = len_bignum(n4, len); + init_two_dw(n4, n4_len); + n3_bitlen = (int)bitlen_bignum(n3, n4_len); + n3_len = (uint)((n3_bitlen + 31) / 32); + bit_mask = (((uint)1) << ((n3_bitlen - 1) % 32)) >> 1; + pn3 += n3_len - 1; + n3_bitlen--; + mov_bignum(n1, n2, n4_len); + while (--n3_bitlen != -1) + { + if (bit_mask == 0) + { + bit_mask = 0x80000000; + pn3--; + } + calc_a_bignum(n_tmp, n1, n1, n4_len); + if ((*pn3 & bit_mask) != 0) + calc_a_bignum(n1, n_tmp, n2, n4_len); + else + mov_bignum(n1, n_tmp, n4_len); + bit_mask >>= 1; + } + init_bignum(n_tmp, 0, n4_len); + clear_tmp_vars(len); + } + } + } + + unsafe void memcpy(byte* dest, byte* src, int len) + { + while (len-- != 0) *dest++ = *src++; + } + + unsafe void process_predata(byte* pre, uint pre_len, byte *buf) + { + uint[] n2 = new uint[64]; + uint[] n3 = new uint[64]; + + uint a = (pubkey.len - 1) / 8; + while (a + 1 <= pre_len) + { + init_bignum(n2, 0, 64); + fixed( uint * pn2 = &n2[0] ) + memcpy((byte *)pn2, pre, (int)a + 1); + calc_a_key(n3, n2, pubkey.key2, pubkey.key1, 64); + + fixed( uint * pn3 = &n3[0] ) + memcpy(buf, (byte *)pn3, (int)a); + + pre_len -= a + 1; + pre += a + 1; + buf += a; + } + } + + public byte[] DecryptKey(byte[] src) + { + init_pubkey(); + byte[] dest = new byte[256]; + + unsafe + { + fixed (byte* pdest = &dest[0]) + fixed (byte* psrc = &src[0]) + process_predata(psrc, len_predata(), pdest); + } + return dest.Take(56).ToArray(); + } + } +} diff --git a/OpenRa.FileFormats/OpenRa.FileFormats.csproj b/OpenRa.FileFormats/OpenRa.FileFormats.csproj index 7979afdc1a..5e08beb703 100644 --- a/OpenRa.FileFormats/OpenRa.FileFormats.csproj +++ b/OpenRa.FileFormats/OpenRa.FileFormats.csproj @@ -14,7 +14,7 @@ 2.0 - v2.0 + v3.5 true @@ -36,13 +36,16 @@ + + 3.5 + - + @@ -62,10 +65,6 @@ - - {6F5D4280-3D23-41FF-AE2A-511B5553E377} - MixDecrypt - {2F9E7A23-56C0-4286-9C8E-1060A9B2F073} OpenRa.DataStructures diff --git a/OpenRa.FileFormats/Package.cs b/OpenRa.FileFormats/Package.cs index ebefa30998..947e19f3d5 100644 --- a/OpenRa.FileFormats/Package.cs +++ b/OpenRa.FileFormats/Package.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Text; using System.IO; +using System.Linq; namespace OpenRa.FileFormats { @@ -18,11 +19,6 @@ namespace OpenRa.FileFormats readonly long dataStart; readonly Stream s; - //public ICollection Content - //{ - // get { return index.AsReadOnly(); } - //} - public static Dictionary MakeDict(IEnumerable values, Converter keyFunc) { var dict = new Dictionary(); @@ -63,7 +59,7 @@ namespace OpenRa.FileFormats { BinaryReader reader = new BinaryReader(s); byte[] keyblock = reader.ReadBytes(80); - byte[] blowfishKey = MixDecrypt.MixDecrypt.BlowfishKey(keyblock); + byte[] blowfishKey = new BlowfishKeyProvider().DecryptKey(keyblock); uint[] h = ReadUints(reader, 2); diff --git a/OpenRa.sln b/OpenRa.sln index 721be94a1d..1ef2b24136 100644 --- a/OpenRa.sln +++ b/OpenRa.sln @@ -1,12 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 10.00 # Visual Studio 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MixDecrypt", "MixDecrypt\MixDecrypt.vcproj", "{6F5D4280-3D23-41FF-AE2A-511B5553E377}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.FileFormats", "OpenRa.FileFormats\OpenRa.FileFormats.csproj", "{BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}" - ProjectSection(ProjectDependencies) = postProject - {6F5D4280-3D23-41FF-AE2A-511B5553E377} = {6F5D4280-3D23-41FF-AE2A-511B5553E377} - EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenRa.Game", "OpenRa.Game\OpenRa.Game.csproj", "{0DFB103F-2962-400F-8C6D-E2C28CCBA633}" EndProject @@ -20,10 +15,6 @@ Global Release (x86)|Win32 = Release (x86)|Win32 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6F5D4280-3D23-41FF-AE2A-511B5553E377}.Debug (x86)|Win32.ActiveCfg = Release|Win32 - {6F5D4280-3D23-41FF-AE2A-511B5553E377}.Debug (x86)|Win32.Build.0 = Release|Win32 - {6F5D4280-3D23-41FF-AE2A-511B5553E377}.Release (x86)|Win32.ActiveCfg = Release|Win32 - {6F5D4280-3D23-41FF-AE2A-511B5553E377}.Release (x86)|Win32.Build.0 = Release|Win32 {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Debug (x86)|Win32.ActiveCfg = Debug|x86 {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Debug (x86)|Win32.Build.0 = Debug|x86 {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA}.Release (x86)|Win32.ActiveCfg = Release|x86