Esempio n. 1
0
        //this returns an empty buffer if error
        public byte[] Decrypt(byte[] input, out int length)
        {
            int version, len = input.Length;

            if (len < 261)
            {
                length = 0; return(new byte[] { });
            }
            else
            {
                int mod_size = len % 256;
                if (mod_size == 32)
                {
                    version = 1;
                }
                else if (mod_size == 33)
                {
                    version = 2;
                }
                else if (mod_size == 5)
                {
                    version = 3;
                }
                else
                {
                    length = 0; return(new byte[] { });
                }
            }

            byte[] cipher8, output;
            int    output_len;

            if (version == 1)
            {
                output_len = len - 32;
                output     = new byte[output_len];
                Buffer.BlockCopy(input, 32, output, 0, output_len);
                cipher8 = cipher8_from_iv(input);
            }
            else if (version == 2)
            {
                output_len = len - 33;
                output     = new byte[output_len];
                Buffer.BlockCopy(input, 32, output, 0, output_len);
                cipher8 = cipher8_from_iv(input);
            }
            else
            {
                output_len = len - 5;
                output     = new byte[output_len];
                Buffer.BlockCopy(input, 4, output, 0, output_len);
                byte[] tmp = new byte[4];
                Buffer.BlockCopy(input, 0, tmp, 0, 4);
                Array.Reverse(tmp);
                uint ms = BitConverter.ToUInt32(tmp, 0);
                cipher8 = cipher8_from_rand(ref ms);
                if (input[len - 1] != make_integrity_byte(gen_rand(ref ms)))
                {
                    length = 0; return(new byte[] { });
                }
            }

            Collection <byte[]> outputcontent = new Collection <byte[]>();

            //break into chunks of 256
            int roundedsize = (output_len + 255) / 256; //round up

            for (int i = 0; i < roundedsize; i++)
            {
                outputcontent.Add(new byte[256]);
            }
            for (int i = 0; i < output_len; i++)
            {
                outputcontent[i / 256][i % 256] = output[i];
            }

            for (int i = 0; i < outputcontent.Count; i++)
            {
                uint[] temp2 = new uint[0x100 / 4];
                uint[] temp3 = new uint[0x100 / 4];
                Buffer.BlockCopy(outputcontent[i], 0, temp2, 0, 0x100);
                Buffer.BlockCopy(temp2, 0, temp3, 0, 0x100);
                if (version == 1)
                {
                    Shuffles.Unshuffle(temp2);
                }
                else
                {
                    Shuffles.Unshuffle2(temp2);
                }
                Buffer.BlockCopy(temp2, 0, outputcontent[i], 0, 0x100);
                for (int j = 0; j < 256; j++)
                {
                    outputcontent[i][j] ^= cipher8[j];
                }
                Buffer.BlockCopy(temp3, 0, cipher8, 0, 0x100);
            }

            byte[] ret = new byte[output_len];
            for (int i = 0; i < outputcontent.Count; i++)
            {
                Buffer.BlockCopy(outputcontent[i], 0, ret, i * 256, 0x100);
            }
            length = output_len - ret.Last();
            return(ret);
        }
Esempio n. 2
0
        //this returns an empty buffer if error
        public static byte[] Decrypt(byte[] input, out int length)
        {
            int version, len = input.Length;

            if (len < 261)
            {
                length = 0;
                return(new byte[] { });
            }

            var modSize = len % 256;

            switch (modSize)
            {
            case 32:
                version = 1;
                break;

            case 33:
                version = 2;
                break;

            case 5:
                version = 3;
                break;

            default:
                length = 0; return(new byte[] { });
            }

            byte[] cipher8, output;
            int    outputLen;

            switch (version)
            {
            case 1:
                outputLen = len - 32;
                output    = new byte[outputLen];
                Buffer.BlockCopy(input, 32, output, 0, outputLen);
                cipher8 = Cipher8FromIv(input);
                break;

            case 2:
                outputLen = len - 33;
                output    = new byte[outputLen];
                Buffer.BlockCopy(input, 32, output, 0, outputLen);
                cipher8 = Cipher8FromIv(input);
                break;

            default:
                outputLen = len - 5;
                output    = new byte[outputLen];
                Buffer.BlockCopy(input, 4, output, 0, outputLen);
                var tmp = new byte[4];
                Buffer.BlockCopy(input, 0, tmp, 0, 4);
                Array.Reverse(tmp);
                var ms = BitConverter.ToUInt32(tmp, 0);
                cipher8 = Cipher8FromRand(ref ms);
                if (input[len - 1] != MakeIntegrityByte(GenerateRand(ref ms)))
                {
                    length = 0; return(new byte[] { });
                }
                break;
            }

            var outputcontent = new Collection <byte[]>();

            //break into chunks of 256
            var roundedsize = (outputLen + 255) / 256; //round up

            for (var i = 0; i < roundedsize; i++)
            {
                outputcontent.Add(new byte[256]);
            }
            for (var i = 0; i < outputLen; i++)
            {
                outputcontent[i / 256][i % 256] = output[i];
            }

            foreach (var bytes in outputcontent)
            {
                var temp2 = new uint[0x100 / 4];
                var temp3 = new uint[0x100 / 4];
                Buffer.BlockCopy(bytes, 0, temp2, 0, 0x100);
                Buffer.BlockCopy(temp2, 0, temp3, 0, 0x100);

                if (version == 1)
                {
                    Shuffles.Unshuffle(temp2);
                }
                else
                {
                    Shuffles.Unshuffle2(temp2);
                }

                Buffer.BlockCopy(temp2, 0, bytes, 0, 0x100);
                for (var j = 0; j < 256; j++)
                {
                    bytes[j] ^= cipher8[j];
                }
                Buffer.BlockCopy(temp3, 0, cipher8, 0, 0x100);
            }

            var ret = new byte[outputLen];

            for (var i = 0; i < outputcontent.Count; i++)
            {
                Buffer.BlockCopy(outputcontent[i], 0, ret, i * 256, 0x100);
            }
            length = outputLen - ret.Last();
            return(ret);
        }