CSPspEmu.Hle.Formats.EncryptedPrx.DecryptPRX2 C# (CSharp) Method

DecryptPRX2() protected method

protected DecryptPRX2 ( byte _pbIn, bool ShowInfo = false ) : byte[]
_pbIn byte
ShowInfo bool
return byte[]
        protected byte[] DecryptPRX2(byte[] _pbIn, bool ShowInfo = false)
        {
            int size = (int)_pbIn.Length;
            var _pbOut = new byte[size];
            _pbIn.CopyTo(_pbOut, 0);

            var _tmp1 = new byte[0x150];
            var _tmp2 = new byte[0x90 + 0x14];
            var _tmp3 = new byte[0x60 + 0x14];

            fixed (byte* inbuf = _pbIn)
            fixed (byte* outbuf = _pbOut)
            fixed (byte* tmp1 = _tmp1)
            fixed (byte* tmp2 = _tmp2)
            fixed (byte* tmp3 = _tmp3)
            {
                var HeaderPointer = (HeaderStruct*)inbuf;
                this.Header = *(HeaderStruct*)inbuf;
                var pti = GetTagInfo2(this.Header.Tag);
                Console.WriteLine("{0}", pti);

                int retsize = *(int *)&inbuf[0xB0];

                PointerUtils.Memset(_tmp1, 0, 0x150);
                PointerUtils.Memset(_tmp2, 0, 0x90 + 0x14);
                PointerUtils.Memset(_tmp3, 0, 0x60 + 0x14);

                PointerUtils.Memcpy(outbuf, inbuf, size);

                if (size < 0x160)
                {
                    throw (new InvalidDataException("buffer not big enough, "));
                }

                if ((size - 0x150) < retsize)
                {
                    throw (new InvalidDataException("not enough data, "));
                }

                PointerUtils.Memcpy(tmp1, outbuf, 0x150);

                int i, j;
                //byte *p = tmp2+0x14;

                for (i = 0; i < 9; i++)
                {
                    for (j = 0; j < 0x10; j++)
                    {
                        _tmp2[0x14 + (i << 4) + j] = pti.key[j];
                    }

                    _tmp2[0x14 + (i << 4)] = (byte)i;
                }

                if (Scramble((uint *)tmp2, 0x90, pti.code) < 0)
                {
                    throw (new InvalidDataException("error in Scramble#1, "));
                }

                PointerUtils.Memcpy(outbuf, tmp1 + 0xD0, 0x5C);
                PointerUtils.Memcpy(outbuf + 0x5C, tmp1 + 0x140, 0x10);
                PointerUtils.Memcpy(outbuf + 0x6C, tmp1 + 0x12C, 0x14);
                PointerUtils.Memcpy(outbuf + 0x80, tmp1 + 0x080, 0x30);
                PointerUtils.Memcpy(outbuf + 0xB0, tmp1 + 0x0C0, 0x10);
                PointerUtils.Memcpy(outbuf + 0xC0, tmp1 + 0x0B0, 0x10);
                PointerUtils.Memcpy(outbuf + 0xD0, tmp1 + 0x000, 0x80);

                PointerUtils.Memcpy(tmp3 + 0x14, outbuf + 0x5C, 0x60);

                if (Scramble((uint *)tmp3, 0x60, pti.code) < 0)
                {
                    throw (new InvalidDataException("error in Scramble#2, "));
                }

                PointerUtils.Memcpy(outbuf + 0x5C, tmp3, 0x60);
                PointerUtils.Memcpy(tmp3, outbuf + 0x6C, 0x14);
                PointerUtils.Memcpy(outbuf + 0x70, outbuf + 0x5C, 0x10);
                PointerUtils.Memset(outbuf + 0x18, 0, 0x58);
                PointerUtils.Memcpy(outbuf + 0x04, outbuf, 0x04);

                *((uint *)outbuf) = 0x014C;
                PointerUtils.Memcpy(outbuf + 0x08, tmp2, 0x10);

                /* sha-1 */
                if (Kirk.hleUtilsBufferCopyWithRange(outbuf, 3000000, outbuf, 3000000, Core.Crypto.Kirk.CommandEnum.PSP_KIRK_CMD_SHA1_HASH) != Core.Crypto.Kirk.ResultEnum.OK)
                {
                    throw (new InvalidDataException("error in sceUtilsBufferCopyWithRange 0xB, "));
                }

                if (PointerUtils.Memcmp(outbuf, tmp3, 0x14) != 0)
                {
                    throw (new InvalidDataException("WARNING (SHA-1 incorrect), "));
                }

                int iXOR;

                for (iXOR = 0; iXOR < 0x40; iXOR++) {
                    tmp3[iXOR+0x14] = (byte)(outbuf[iXOR+0x80] ^ _tmp2[iXOR+0x10]);
                }

                if (Scramble((uint *)tmp3, 0x40, pti.code) != 0)
                {
                    throw (new InvalidDataException("error in Scramble#3, "));
                }

                for (iXOR = 0x3F; iXOR >= 0; iXOR--) {
                    outbuf[iXOR+0x40] = (byte)(_tmp3[iXOR] ^ _tmp2[iXOR+0x50]); // uns 8
                }

                PointerUtils.Memset(outbuf + 0x80, 0, 0x30);
                *(uint *)&outbuf[0xA0] = 1;

                PointerUtils.Memcpy(outbuf + 0xB0, outbuf + 0xC0, 0x10);
                PointerUtils.Memset(outbuf + 0xC0, 0, 0x10);

                // the real decryption
                var ret = Kirk.hleUtilsBufferCopyWithRange(outbuf, size, outbuf + 0x40, size - 0x40, Core.Crypto.Kirk.CommandEnum.PSP_KIRK_CMD_DECRYPT_PRIVATE);
                if (ret != 0)
                {
                    throw (new InvalidDataException(String.Format("error in sceUtilsBufferCopyWithRange 0x1 (0x{0:X}), ", ret)));
                }

                if (retsize < 0x150)
                {
                    // Fill with 0
                    PointerUtils.Memset(outbuf + retsize, 0, 0x150 - retsize);
                }

                return _pbOut.Slice(0, retsize).ToArray();
            }
        }