private void getCryptoKeys(int cryptoFlag, byte[] calculatedKey, byte[] calculatedIV, byte[] key, byte[] iv)
        {
            uint mode = (uint)cryptoFlag & 0xF0000000;

            switch (mode)
            {
            case 0x10000000:
                ToolsImpl.aescbcDecrypt(EDATKeys.EDATKEY, EDATKeys.EDATIV, key, 0, calculatedKey, 0, calculatedKey.Length);
                ConversionUtils.arraycopy(iv, 0, calculatedIV, 0, calculatedIV.Length);
                Debug.WriteLine("MODE: Encrypted ERK");
                break;

            case 0x20000000:
                ConversionUtils.arraycopy(EDATKeys.EDATKEY, 0, calculatedKey, 0, calculatedKey.Length);
                ConversionUtils.arraycopy(EDATKeys.EDATIV, 0, calculatedIV, 0, calculatedIV.Length);
                Debug.WriteLine("MODE: Default ERK");
                break;

            case 0x00000000:
                ConversionUtils.arraycopy(key, 0, calculatedKey, 0, calculatedKey.Length);
                ConversionUtils.arraycopy(iv, 0, calculatedIV, 0, calculatedIV.Length);
                Debug.WriteLine("MODE: Unencrypted ERK");
                break;

            default:
                throw new Exception("Crypto mode is not valid: Undefined keys calculator");
            }
        }
        private int validateNPD(String filename, byte[] devKLic, NPD[] npdPtr, FileStream i)
        {
            i.Seek(0, SeekOrigin.Begin);
            byte[] npd = new byte[0x80];
            i.Read(npd, 0, npd.Length);
            byte[] extraData = new byte[0x04];
            i.Read(extraData, 0, extraData.Length);
            long flag = ConversionUtils.be32(extraData, 0);

            if ((flag & FLAG_SDAT) != 0)
            {
                Console.WriteLine("INFO: SDAT detected. NPD header is not validated");
            }
            else if (!checkNPDHash1(filename, npd))
            {
                Console.WriteLine("ERROR: Hashing Title ID Name");
                return(STATUS_ERROR_HASHTITLEIDNAME);
            }
            else if (devKLic == null)
            {
                Console.WriteLine("WARNING: Can not validate devklic header");
            }
            else if (!checkNPDHash2(devKLic, npd))
            {
                Console.WriteLine("ERROR: Hashing devklic");
                return(STATUS_ERROR_HASHDEVKLIC);
            }
            npdPtr[0] = NPD.createNPD(npd);
            return(STATUS_OK);
        }
        private void getHashKeys(int hashFlag, byte[] calculatedHash, byte[] hash)
        {
            uint mode = (uint)hashFlag & 0xF0000000;

            switch (mode)
            {
            case 0x10000000:
                ToolsImpl.aescbcDecrypt(EDATKeys.EDATKEY, EDATKeys.EDATIV, hash, 0, calculatedHash, 0, calculatedHash.Length);
                Debug.WriteLine("MODE: Encrypted HASHKEY");
                break;

            case 0x20000000:
                ConversionUtils.arraycopy(EDATKeys.EDATHASH, 0, calculatedHash, 0, calculatedHash.Length);
                Debug.WriteLine("MODE: Default HASHKEY");
                break;

            case 0x00000000:
                ConversionUtils.arraycopy(hash, 0, calculatedHash, 0, calculatedHash.Length);
                Debug.WriteLine("MODE: Unencrypted HASHKEY");
                break;

            default:
                throw new Exception("Hash mode is not valid: Undefined keys calculator");
            }
        }
Exemple #4
0
        public override void doUpdate(byte[] i, int inOffset, int len)
        {
            byte[] data;
            if (nonProcessed != null)
            {
                int totalLen = len + nonProcessed.Length;
                data = new byte[totalLen];
                ConversionUtils.arraycopy(nonProcessed, 0, data, 0, nonProcessed.Length);
                ConversionUtils.arraycopy(i, inOffset, data, nonProcessed.Length, len);
            }
            else
            {
                data = new byte[len];
                ConversionUtils.arraycopy(i, inOffset, data, 0, len);
            }
            int count = 0;

            while (count < data.Length - 0x10)
            {
                byte[] aux = new byte[0x10];
                ConversionUtils.arraycopy(data, count, aux, 0, aux.Length);
                ToolsImpl.XOR(aux, aux, previous);
                ToolsImpl.aesecbEncrypt(key, aux, 0, previous, 0, aux.Length);
                count += 0x10;
            }
            nonProcessed = new byte[data.Length - count];
            ConversionUtils.arraycopy(data, count, nonProcessed, 0, nonProcessed.Length);
        }
        private static void crypto(byte[] key, CipherMode mode, PaddingMode padding, byte[] iv, int opMode, byte[] i, int inOffset, int len, byte[] o, int outOffset)
        {
            try
            {
                RijndaelManaged cipher = new RijndaelManaged();
                cipher.Padding   = padding;
                cipher.Mode      = mode;
                cipher.KeySize   = 0x80;
                cipher.BlockSize = 0x80;
                cipher.Key       = key;
                if (iv != null)
                {
                    cipher.IV = iv;
                }

                byte[] aux = null;
                if (opMode == DECRYPT_MODE)
                {
                    aux = cipher.CreateDecryptor().TransformFinalBlock(i, inOffset, len);
                }
                else if (opMode == ENCRYPT_MODE)
                {
                    aux = cipher.CreateEncryptor().TransformFinalBlock(i, inOffset, len);
                }
                else
                {
                    fail("NOT SUPPORTED OPMODE");
                }
                ConversionUtils.arraycopy(aux, 0, o, outOffset, len);
            }
            catch (Exception ex)
            {
                fail(ex.Message);
            }
        }
        public byte[] getrifKey(String rifIn, String actIn, String idps)
        {
            if (rifIn == null || actIn == null)
            {
                return(null);
            }
            byte[]     result  = null;
            FileStream rifFile = File.Open(rifIn, FileMode.Open);

            byte[] rif0x40    = new byte[0x10];
            byte[] rif0x50    = new byte[0x10];
            byte[] encrif0x40 = new byte[0x10];
            byte[] encrif0x50 = new byte[0x10];
            rifFile.Seek(0x40, SeekOrigin.Begin);
            rifFile.Read(encrif0x40, 0, encrif0x40.Length);
            rifFile.Read(encrif0x50, 0, encrif0x50.Length);
            rifFile.Close();
            ToolsImpl.aesecbDecrypt(RIFKEY, encrif0x40, 0x00, rif0x40, 0, 0x10);
            long index = ConversionUtils.be32(rif0x40, 0xC); //

            if (index < 0x80)
            {
                byte[] actDat = decryptACTDAT(actIn, idps);
                byte[] datKey = new byte[0x10];
                result = new byte[0x10];
                ConversionUtils.arraycopy(actDat, (int)index * 16, datKey, 0, 0x10);
                ToolsImpl.aesecbDecrypt(datKey, encrif0x50, 0, result, 0, 0x10);
            }
            return(result);
        }
Exemple #7
0
        public static EDATData createEDATData(byte[] data)
        {
            EDATData result = new EDATData();

            result.flags     = ConversionUtils.be32(data, 0);
            result.blockSize = ConversionUtils.be32(data, 4);
            result.fileLen   = ConversionUtils.be64(data, 0x8);
            return(result);
        }
 private byte[] calculateBlockKey(int blk, NPD npd)
 {
     byte[] baseKey = (npd.getVersion() <= 1) ? (new byte[0x10]) : npd.getDevHash();
     byte[] result  = new byte[0x10];
     ConversionUtils.arraycopy(baseKey, 0, result, 0, 0xC);
     result[0xC] = (byte)(blk >> 24 & 0xFF);
     result[0xD] = (byte)(blk >> 16 & 0xFF);
     result[0xE] = (byte)(blk >> 8 & 0xFF);
     result[0xF] = (byte)(blk & 0xFF);
     return(result);
 }
        private bool checkNPDHash2(byte[] klicensee, byte[] npd)
        {
            byte[] xoredKey = new byte[0x10];
            ToolsImpl.XOR(xoredKey, klicensee, EDATKeys.npdrm_omac_key2);
            byte[] calculated = ToolsImpl.CMAC128(xoredKey, npd, 0, 0x60);
            bool   result2    = compareBytes(calculated, 0, npd, 0x60, 0x10);

            if (result2)
            {
                Console.WriteLine("NPD hash 2 is valid (" + ConversionUtils.getHexString(calculated) + ")");
            }
            return(result2);
        }
        private byte[] createNPDHash2(byte[] klicensee, byte[] npd)
        {
            byte[] xoredKey = new byte[0x10];
            ToolsImpl.XOR(xoredKey, klicensee, EDATKeys.npdrm_omac_key2);
            byte[] calculated = ToolsImpl.CMAC128(xoredKey, npd, 0, 0x60);
            ConversionUtils.arraycopy(calculated, 0, npd, 0x60, 0x10);
            bool result2 = compareBytes(calculated, 0, npd, 0x60, 0x10);

            if (result2)
            {
                return(calculated);
            }
            return(null);
        }
        /* KDSBEST END */

        public int decryptFile(String inFile, String outFile, byte[] devKLic, byte[] keyFromRif)
        {
            FileStream fin = File.Open(inFile, FileMode.Open);

            string[] fn = fin.Name.Split('\\');
            //string[] fn = fin.Name.Split('/');
            Console.WriteLine(fn[fn.Length - 1]);

            NPD[] ptr    = new NPD[1];                                        //Ptr to Ptr
            int   result = validateNPD(fn[fn.Length - 1], devKLic, ptr, fin); //Validate NPD hashes

            if (result < 0)
            {
                fin.Close();
                return(result);
            }
            NPD      npd  = ptr[0];
            EDATData data = getEDATData(fin);                       //Get flags, blocksize and file len

            byte[] rifkey = getKey(npd, data, devKLic, keyFromRif); //Obtain the key for decryption (result of sc471 or sdatkey)
            if (rifkey == null)
            {
                Console.WriteLine("ERROR: Key for decryption is missing");
                fin.Close();
                return(STATUS_ERROR_MISSINGKEY);
            }
            else
            {
                Console.WriteLine("DECRYPTION KEY: " + ConversionUtils.getHexString(rifkey));
            }
            result = checkHeader(rifkey, data, npd, fin);
            if (result < 0)
            {
                fin.Close();
                return(result);
            }
            FileStream o = File.Open(outFile, FileMode.Create);

            result = decryptData(fin, o, npd, data, rifkey);
            if (result < 0)
            {
                fin.Close();
                return(result);
            }
            fin.Close();
            o.Close();
            Console.WriteLine("COMPLETE: File Written to disk");
            return(STATUS_OK);
        }
 public void doInit(int hashFlag, int cryptoFlag, byte[] key, byte[] iv, byte[] hashKey)
 {
     byte[] calculatedKey  = new byte[key.Length];
     byte[] calculatedIV   = new byte[iv.Length];
     byte[] calculatedHash = new byte[hashKey.Length];
     getCryptoKeys(cryptoFlag, calculatedKey, calculatedIV, key, iv);
     getHashKeys(hashFlag, calculatedHash, hashKey);
     setDecryptor(cryptoFlag);
     setHash(hashFlag);
     Debug.WriteLine("ERK:  " + ConversionUtils.getHexString(calculatedKey));
     Debug.WriteLine("IV:   " + ConversionUtils.getHexString(calculatedIV));
     Debug.WriteLine("HASH: " + ConversionUtils.getHexString(calculatedHash));
     dec.doInit(calculatedKey, calculatedIV);
     hash.doInit(calculatedHash);
 }
        private bool checkNPDHash1(String filename, byte[] npd)
        {
            byte[] fileBytes = ConversionUtils.charsToByte(filename.ToCharArray());
            byte[] data1     = new byte[0x30 + fileBytes.Length];
            ConversionUtils.arraycopy(npd, 0x10, data1, 0, 0x30);
            ConversionUtils.arraycopy(fileBytes, 0x00, data1, 0x30, fileBytes.Length);
            byte[] hash1   = ToolsImpl.CMAC128(EDATKeys.npdrm_omac_key3, data1, 0, data1.Length);
            bool   result1 = compareBytes(hash1, 0, npd, 0x50, 0x10);

            if (result1)
            {
                Console.WriteLine("NPD hash 1 is valid (" + ConversionUtils.getHexString(hash1) + ")");
            }
            return(result1);
        }
        private byte[] createNPDHash1(String filename, byte[] npd)
        {
            byte[] fileBytes = ConversionUtils.charsToByte(filename.ToCharArray());
            byte[] data1     = new byte[0x30 + fileBytes.Length];
            ConversionUtils.arraycopy(npd, 0x10, data1, 0, 0x30);
            ConversionUtils.arraycopy(fileBytes, 0x00, data1, 0x30, fileBytes.Length);
            byte[] hash1 = ToolsImpl.CMAC128(EDATKeys.npdrm_omac_key3, data1, 0, data1.Length);
            ConversionUtils.arraycopy(hash1, 0, npd, 0x50, 0x10);
            bool result1 = compareBytes(hash1, 0, npd, 0x50, 0x10);

            if (result1)
            {
                return(hash1);
            }
            return(null);
        }
Exemple #15
0
        private void calculateSubkey(byte[] key, byte[] K1, byte[] K2)
        {
            byte[] zero = new byte[0x10];
            byte[] L    = new byte[0x10];
            ToolsImpl.aesecbEncrypt(key, zero, 0, L, 0, zero.Length);
            BigInteger aux = new BigInteger(ConversionUtils.reverseByteWithSizeFIX(L));

            if ((L[0] & 0x80) != 0)
            {
                //Case MSB is set
                aux = (aux << 1) ^ (new BigInteger(0x87));
            }
            else
            {
                aux = aux << 1;
            }
            byte[] aux1 = ConversionUtils.reverseByteWithSizeFIX(aux.ToByteArray());
            if (aux1.Length >= 0x10)
            {
                ConversionUtils.arraycopy(aux1, aux1.Length - 0x10, K1, 0, 0x10);
            }
            else
            {
                ConversionUtils.arraycopy(zero, 0, K1, 0, zero.Length);
                ConversionUtils.arraycopy(aux1, 0, K1, 0x10 - aux1.Length, aux1.Length);
            }
            aux = new BigInteger(ConversionUtils.reverseByteWithSizeFIX(K1));

            if ((K1[0] & 0x80) != 0)
            {
                aux = (aux << 1) ^ (new BigInteger(0x87));
            }
            else
            {
                aux = aux << 1;
            }
            aux1 = ConversionUtils.reverseByteWithSizeFIX(aux.ToByteArray());
            if (aux1.Length >= 0x10)
            {
                ConversionUtils.arraycopy(aux1, aux1.Length - 0x10, K2, 0, 0x10);
            }
            else
            {
                ConversionUtils.arraycopy(zero, 0, K2, 0, zero.Length);
                ConversionUtils.arraycopy(aux1, 0, K2, 0x10 - aux1.Length, aux1.Length);
            }
        }
        public string makeedat(String inFile)
        {
            String strAppDir = Path.GetDirectoryName(
                Assembly.GetExecutingAssembly().GetName().CodeBase);
            string path = strAppDir.Replace("file:\\", "");

            byte[] CID        = Encoding.UTF8.GetBytes(inFile);
            byte[] contentID  = new byte[48];
            byte[] contentID2 = new byte[inFile.Length];
            ConversionUtils.arraycopy(CID, 0, contentID, 0, CID.Length);
            ConversionUtils.arraycopy(CID, 0, contentID2, 0, inFile.Length);
            string cid3 = Encoding.UTF8.GetString(contentID2);

            if (path != null)
            {
                outFile = path + "/edats/" + inFile + ".edat";
            }
            else
            {
                outFile = "edats/" + inFile + ".edat";
            }



            FileStream dat = File.Open(inFile + ".dat", FileMode.Create);

            dat.Write(pad, 0, 0x10);
            dat.Write(contentID, 0, contentID.Length);
            dat.Close();
            String        input = inFile + ".dat";
            DirectoryInfo di    = Directory.CreateDirectory(path + "/edats");

            byte[] flags      = ConversionUtils.getByteArray("0C");
            byte[] type       = ConversionUtils.getByteArray("00");
            byte[] version    = ConversionUtils.getByteArray("02");
            byte[] devKLic    = ConversionUtils.getByteArray("72F990788F9CFF745725F08E4C128387");
            byte[] keyFromRif = null;
            EDAT   instance   = new EDAT();

            instance.encryptFile(input, outFile, devKLic, keyFromRif, contentID, flags, type, version);
            if (File.Exists(inFile + ".dat"))
            {
                File.Delete(inFile + ".dat");
            }

            return(inFile + ".edat");
        }
Exemple #17
0
 public override bool doFinal(byte[] generateHash)
 {
     byte[] aux = new byte[0x10];
     ConversionUtils.arraycopy(nonProcessed, 0, aux, 0, nonProcessed.Length);
     if (nonProcessed.Length == 0x10)
     {
         ToolsImpl.XOR(aux, aux, K1);
     }
     else
     {
         aux[nonProcessed.Length] = (byte)0x80;
         ToolsImpl.XOR(aux, aux, K2);
     }
     ToolsImpl.XOR(aux, aux, previous);
     ToolsImpl.aesecbEncrypt(key, aux, 0, generateHash, 0, aux.Length);
     return(true);
 }
Exemple #18
0
 public override bool doFinal(byte[] expectedhash, int hashOffset, bool hashDebug)
 {
     byte[] aux = new byte[0x10];
     ConversionUtils.arraycopy(nonProcessed, 0, aux, 0, nonProcessed.Length);
     if (nonProcessed.Length == 0x10)
     {
         ToolsImpl.XOR(aux, aux, K1);
     }
     else
     {
         aux[nonProcessed.Length] = (byte)0x80;
         ToolsImpl.XOR(aux, aux, K2);
     }
     ToolsImpl.XOR(aux, aux, previous);
     byte[] calculatedhash = new byte[0x10];
     ToolsImpl.aesecbEncrypt(key, aux, 0, calculatedhash, 0, aux.Length);
     return(hashDebug || compareBytes(expectedhash, hashOffset, calculatedhash, 0, hashLen));
 }
        public static NPD createNPD(byte[] npd)
        {
            NPD result = new NPD();

            ConversionUtils.arraycopy(npd, 0, result.magic, 0, 4);
            result.version = ConversionUtils.be32(npd, 4);
            result.license = ConversionUtils.be32(npd, 8);
            result.type    = ConversionUtils.be32(npd, 0xC);
            ConversionUtils.arraycopy(npd, 0x10, result.content_id, 0, 0x30);
            ConversionUtils.arraycopy(npd, 0x40, result.digest, 0, 0x10);
            ConversionUtils.arraycopy(npd, 0x50, result.titleHash, 0, 0x10);
            ConversionUtils.arraycopy(npd, 0x60, result.devHash, 0, 0x10);
            result.unknown3 = ConversionUtils.be64(npd, 0x70);
            result.unknown4 = ConversionUtils.be64(npd, 0x78);
            if (!result.validate())
            {
                result = null;
            }
            return(result);
        }
        public static byte[] CMAC128(byte[] key, byte[] i, int inOffset, int len)
        {
            byte[] K1 = new byte[0x10];
            byte[] K2 = new byte[0x10];
            calculateSubkey(key, K1, K2);
            byte[] input         = new byte[0x10];
            byte[] previous      = new byte[0x10];
            int    currentOffset = inOffset;
            int    remaining     = len;

            //System.out.println(ConversionUtils.getHexString(key));
            while (remaining > 0x10)
            {
                ConversionUtils.arraycopy(i, currentOffset, input, 0, 0x10);
                //System.out.println(ConversionUtils.getHexString(previous) + " - " + ConversionUtils.getHexString(input));
                XOR(input, input, previous);

                ToolsImpl.aesecbEncrypt(key, input, 0, previous, 0, input.Length);
                currentOffset += 0x10;
                remaining     -= 0x10;
            }
            //System.out.println(ConversionUtils.getHexString(previous));
            input = new byte[0x10]; //Memset 0
            ConversionUtils.arraycopy(i, currentOffset, input, 0, remaining);
            if (remaining == 0x10)
            {
                XOR(input, input, previous);
                XOR(input, input, K1);
            }
            else
            {
                input[remaining] = (byte)0x80;
                XOR(input, input, previous);
                XOR(input, input, K2);
            }
            //System.out.println(" - " + ConversionUtils.getHexString(input));
            ToolsImpl.aesecbEncrypt(key, input, 0, previous, 0, input.Length);
            return(previous);
        }
        private byte[] writeValidNPD(String filename, byte[] devKLic, NPD[] npdPtr, FileStream fin, byte[] contentID, byte[] flags, byte[] version, byte[] type)
        {
            byte[] npd = new byte[0x80];
            //NPD Magic
            //ConversionUtils.arraycopy(npd, 0, result.magic, 0, 4);
            npd[0] = 0x4E;
            npd[1] = 0x50;
            npd[2] = 0x44;
            npd[3] = 0x00;
            //Version 3
            //result.version = ConversionUtils.be32(npd, 4);
            npd[4] = 0x00;
            npd[5] = 0x00;
            npd[6] = 0x00;
            npd[7] = version[0];
            //License 2 ref 3 klic /* 1 network, 2 local, 3 free */
            //result.license = ConversionUtils.be32(npd, 8);
            npd[8]  = 0x00;
            npd[9]  = 0x00;
            npd[10] = 0x00;
            npd[11] = 0x03;


            //Type /* 1 exec, 21 update */
            //result.type = ConversionUtils.be32(npd, 0xC);
            npd[12] = 0x00;
            npd[13] = 0x00;
            npd[14] = 0x00;
            npd[15] = type[0];

            //No Idea where I get the content_id
            //ConversionUtils.arraycopy(npd, 0x10, result.content_id, 0, 0x30
            for (int i = 0; i < 0x30; i++)
            {
                npd[0x10 + i] = contentID[i];
            }



            //Used to create IV
            //ConversionUtils.arraycopy(npd, 0x40, result.digest, 0, 0x10);
            byte[] iv = ConversionUtils.charsToByte(("FixedLicenseEDAT").ToCharArray());
            ConversionUtils.arraycopy(iv, 0, npd, 0x40, 0x10);

            //I guess it's a full file hash
            //ConversionUtils.arraycopy(npd, 0x50, result.titleHash, 0, 0x10);
            byte[] hash = createNPDHash1(filename, npd);
            ConversionUtils.arraycopy(hash, 0x00, npd, 0x50, 0x10);


            //Used to create Blockkey
            //ConversionUtils.arraycopy(npd, 0x60, result.devHash, 0, 0x10);
            byte[] devHash = createNPDHash2(devKLic, npd);
            ConversionUtils.arraycopy(devHash, 0, npd, 0x60, 0x10);

            //NPD EOF?!?!?!
            //result.unknown3 = ConversionUtils.be64(npd, 0x70);
            //result.unknown4 = ConversionUtils.be64(npd, 0x78);
            for (int i = 0; i < 16; i++)
            {
                npd[0x70 + i] = 0x00;
            }

            npdPtr[0] = NPD.createNPD(npd);
            return(npd);
        }
Exemple #22
0
        public string makeedat(String inFile, String outFile)
        {
            if (!File.Exists(inFile))
            {
                Console.WriteLine(inFile + " not found");
                return(inFile);
            }
            else
            {
                String strAppDir = Path.GetDirectoryName(
                    Assembly.GetExecutingAssembly().GetName().CodeBase);
                string       path     = strAppDir.Replace("file:\\", "");
                StreamReader sfoFile  = new StreamReader(inFile);
                string       pkgname1 = GetSubstringByString("temp/", "/PARAM.SFO", inFile);
                string       pkgname  = pkgname1.Replace("temp/", "");
                // FileStream sfoFile = File.Open(inFile, FileMode.Open);
                string ciddat = sfoFile.ReadToEnd();
                if (ciddat.Contains("HG\0\0"))
                {
                    if (ciddat.Contains("Library"))
                    {
                        byte[] result = new byte[ciddat.Length];
                        string cid4   = GetSubstringByString("HG\0\0", "Library", ciddat);
                        string cid5   = cid4.Replace("HG\0\0", "");

                        int found = 0;
                        found = cid5.IndexOf("\0");

                        int cid1 = cid5.Length - found;
                        int cid2 = cid5.Length - cid1;
                        sfoFile.Close();
                        string cid = cid5.Replace("\0", "");
                        //byte[] contentID = ciddat;
                        if (cid2 > 35)
                        {
                            byte[] CID        = Encoding.UTF8.GetBytes(cid);
                            byte[] contentID  = new byte[48];
                            byte[] contentID2 = new byte[cid2];
                            ConversionUtils.arraycopy(CID, 0, contentID, 0, CID.Length);
                            ConversionUtils.arraycopy(CID, 0, contentID2, 0, cid2);
                            string cid3 = Encoding.UTF8.GetString(contentID2);
                            if (path != null)
                            {
                                outFile = path + "/edats/" + cid3 + ".edat";
                            }
                            else
                            {
                                outFile = "edats/" + cid3 + ".edat";
                            }

                            FileStream dat = File.Open(cid3 + ".dat", FileMode.Create);
                            // byte[] pad = new byte[0x10];
                            //  Random rand = new Random();
                            //  rand.NextBytes(pad);
                            dat.Write(pad, 0, 0x10);
                            dat.Write(contentID, 0, contentID.Length);
                            dat.Close();
                            String        input      = cid3 + ".dat";
                            DirectoryInfo di         = Directory.CreateDirectory(path + "/edats");
                            byte[]        flags      = ConversionUtils.getByteArray("0C");
                            byte[]        type       = ConversionUtils.getByteArray("00");
                            byte[]        version    = ConversionUtils.getByteArray("02");
                            byte[]        devKLic    = ConversionUtils.getByteArray("72F990788F9CFF745725F08E4C128387");
                            byte[]        keyFromRif = null;

                            EDAT instance = new EDAT();
                            instance.encryptFile(input, outFile, devKLic, keyFromRif, contentID, flags, type, version);

                            if (File.Exists(cid3 + ".dat"))
                            {
                                File.Delete(cid3 + ".dat");
                            }
                            if (input.EndsWith(".Dec"))
                            {
                                File.Delete(input);
                            }
                            System.IO.StreamWriter file =
                                new System.IO.StreamWriter("C00 list.txt", true);

                            file.WriteLine(pkgname, true);

                            file.Close();
                            return(cid3 + ".edat");
                        }
                        else
                        {
                            Console.WriteLine("Content_ID not found.");
                            sfoFile.Close();
                            return("");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Content_ID not found.");
                        sfoFile.Close();
                        return("");
                    }
                }
                else
                {
                    Console.WriteLine("Content_ID not found.");
                    sfoFile.Close();
                    return("");
                }
            }
        }
Exemple #23
0
        public string makerif(String inFile, String outFile)
        {
            if (!File.Exists(inFile))
            {
                Console.WriteLine(inFile + " not found");
                return(inFile);
            }
            else
            {
                String strAppDir = Path.GetDirectoryName(
                    Assembly.GetExecutingAssembly().GetName().CodeBase);
                string path   = strAppDir.Replace("file:\\", "");
                string actIn1 = strAppDir + "/data/act.dat";
                string idps1  = strAppDir + "/data/idps";
                string actIn  = actIn1.Replace("file:\\", "");
                string idps   = idps1.Replace("file:\\", "");

                FileStream actFile = File.Open(actIn, FileMode.Open);
                byte[]     actid   = new byte[0x08];
                actFile.Seek(0x08, SeekOrigin.Begin);
                actFile.Read(actid, 0, 0x8);
                actFile.Close();

                string cid = GetSubstringByString('\\', ".", inFile);

                if (path != null)
                {
                    outFile = path + "/rifs/" + cid + ".rif";
                }
                else
                {
                    outFile = "rifs/" + cid + ".rif";
                }

                byte[] content_id = new byte[0x30];
                byte[] encrif0x40 = new byte[0x10];
                byte[] rif0x40    = new byte[0x10];
                byte[] rif0x50    = null;

                byte[]        keyFromRif = getKey(inFile);
                DirectoryInfo di         = Directory.CreateDirectory(path + "/rifs");

                FileStream o = File.Open(outFile, FileMode.Create);

                o.Write(rif_header, 0, 0x08);
                o.Write(actid, 0, 0x08);
                byte[] CID = Encoding.UTF8.GetBytes(cid);
                ConversionUtils.arraycopy(CID, 0, content_id, 0, CID.Length);

                o.Write(content_id, 0, 0x30);

                ToolsImpl.aesecbEncrypt(RIFKEY, rif0x40, 0x00, encrif0x40, 0, 0x10);
                o.Write(encrif0x40, 0, 0x10);
                long   index  = 0;
                byte[] actDat = decryptACTDAT(actIn, idps);
                byte[] datKey = new byte[0x10];
                rif0x50 = new byte[0x10];
                byte[] signature = new byte[0x28];

                ConversionUtils.arraycopy(actDat, (int)index * 16, datKey, 0, 0x10);
                ToolsImpl.aesecbEncrypt(datKey, keyFromRif, 0, rif0x50, 0, 0x10);
                o.Write(rif0x50, 0, 0x10);
                o.Write(rif_footer, 0, 0x10);

                while (o.Length < 0x98)
                {
                    o.Write(rif_junk, 0, 0x1);
                }

                o.Close();
                return(outFile);
            }
        }
        private int decryptData(FileStream ii, FileStream o, NPD npd, EDATData data, byte[] rifkey)
        {
            int numBlocks           = (int)((data.getFileLen() + data.getBlockSize() - 1) / data.getBlockSize());
            int metadataSectionSize = ((data.getFlags() & FLAG_COMPRESSED) != 0 || (data.getFlags() & FLAG_0x20) != 0) ? 0x20 : 0x10;
            int baseOffset          = 0x100; //+ offset (unknown)

            for (int i = 0; i < numBlocks; i++)
            {
                ii.Seek(baseOffset + i * metadataSectionSize, SeekOrigin.Begin);
                byte[] expectedHash = new byte[0x10];
                long   offset;
                int    len;
                int    compressionEndBlock = 0;
                if ((data.getFlags() & FLAG_COMPRESSED) != 0)
                {
                    byte[] metadata = new byte[0x20];
                    ii.Read(metadata, 0, metadata.Length);
                    byte[] result = decryptMetadataSection(metadata);
                    offset = (int)(ConversionUtils.be64(result, 0)); // + offset (unknown)
                    len    = (int)(ConversionUtils.be32(result, 8));
                    compressionEndBlock = (int)(ConversionUtils.be32(result, 0xC));
                    ConversionUtils.arraycopy(metadata, 0, expectedHash, 0, 0x10);
                }
                else if ((data.getFlags() & FLAG_0x20) != 0)
                {
                    //NOT TESTED: CASE WHERE METADATASECTION IS 0x20 BYTES LONG
                    byte[] metadata = new byte[0x20];
                    ii.Read(metadata, 0, metadata.Length);
                    for (int j = 0; j < 0x10; j++)
                    {
                        expectedHash[j] = (byte)(metadata[j] ^ metadata[j + 0x10]);
                    }
                    offset = baseOffset + i * data.getBlockSize() + numBlocks * metadataSectionSize;
                    len    = (int)(data.getBlockSize());
                    if (i == numBlocks - 1)
                    {
                        len = (int)(data.getFileLen() % (new BigInteger(data.getBlockSize())));
                    }
                }
                else
                {
                    ii.Read(expectedHash, 0, expectedHash.Length);
                    offset = baseOffset + i * data.getBlockSize() + numBlocks * metadataSectionSize;
                    len    = (int)(data.getBlockSize());
                    if (i == numBlocks - 1)
                    {
                        len = (int)(data.getFileLen() % (new BigInteger(data.getBlockSize())));
                    }
                }
                int realLen = len;
                len = (int)((uint)(len + 0xF) & 0xFFFFFFF0);
                Debug.Print("Offset: %016X, len: %08X, realLen: %08X, endCompress: %d\r\n", offset, len, realLen, compressionEndBlock);
                ii.Seek(offset, SeekOrigin.Begin);
                byte[] encryptedData = new byte[len];
                byte[] decryptedData = new byte[len];
                ii.Read(encryptedData, 0, encryptedData.Length);
                byte[] key      = new byte[0x10];
                byte[] hash     = new byte[0x10];
                byte[] blockKey = calculateBlockKey(i, npd);

                ToolsImpl.aesecbEncrypt(rifkey, blockKey, 0, key, 0, blockKey.Length);
                if ((data.getFlags() & FLAG_0x10) != 0)
                {
                    ToolsImpl.aesecbEncrypt(rifkey, key, 0, hash, 0, key.Length);
                }
                else
                {
                    ConversionUtils.arraycopy(key, 0, hash, 0, key.Length);
                }
                int cryptoFlag = ((data.getFlags() & FLAG_0x02) == 0) ? 0x2 : 0x1;
                int hashFlag;
                if ((data.getFlags() & FLAG_0x10) == 0)
                {
                    hashFlag = 0x02;
                }
                else if ((data.getFlags() & FLAG_0x20) == 0)
                {
                    hashFlag = 0x04;
                }
                else
                {
                    hashFlag = 0x01;
                }
                if ((data.getFlags() & FLAG_KEYENCRYPTED) != 0)
                {
                    cryptoFlag |= 0x10000000;
                    hashFlag   |= 0x10000000;
                }
                if ((data.getFlags() & FLAG_DEBUG) != 0)
                {
                    cryptoFlag |= 0x01000000;
                    hashFlag   |= 0x01000000;
                }
                AppLoader a  = new AppLoader();
                byte[]    iv = (npd.getVersion() <= 1) ? (new byte[0x10]) : npd.getDigest();

                bool rresult = a.doAll(hashFlag, cryptoFlag, encryptedData, 0, decryptedData, 0, encryptedData.Length, key, npd.getDigest(), hash, expectedHash, 0);
                if (!rresult)
                {
                    Debug.WriteLine("Error decrypting block " + i);
                    // KDSBest find out why block 30 errors
                    //return STATUS_ERROR_DECRYPTING;
                }
                if ((data.getFlags() & FLAG_COMPRESSED) != 0)
                {
                    //byte[] decompress = new byte[Long.valueOf(data.getBlockSize()).intValue()];
                    //DECOMPRESS: MISSING ALGORITHM
                    //out.write(decompress, 0, data.getBlockSize());
                }
                else
                {
                    o.Write(decryptedData, 0, realLen);
                }
            }
            return(STATUS_OK);
        }
Exemple #25
0
 public override bool doFinalButGetHash(byte[] generatedHash)
 {
     ConversionUtils.arraycopy(result, 0, generatedHash, 0, result.Length);
     return(true);
 }
Exemple #26
0
        public string makerif(string inFile, string outFile)
        {
            if (!File.Exists(inFile))
            {
                Console.WriteLine(inFile + " not found");
                return(inFile);
            }
            string     directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase);
            string     str2          = directoryName.Replace(@"file:\", "");
            string     str3          = directoryName + "/data/act.dat";
            string     str4          = directoryName + "/data/idps";
            string     path          = str3.Replace(@"file:\", "");
            string     iDPSFile      = str4.Replace(@"file:\", "");
            FileStream stream        = File.Open(path, FileMode.Open);

            byte[] buffer = new byte[8];
            stream.Seek(8L, SeekOrigin.Begin);
            stream.Read(buffer, 0, 8);
            stream.Close();
            string s = this.GetSubstringByString('\\', ".", inFile);

            if (str2 != null)
            {
                outFile = str2 + "/rifs/" + s + ".rif";
            }
            else
            {
                outFile = "rifs/" + s + ".rif";
            }
            byte[]        dest    = new byte[0x30];
            byte[]        o       = new byte[0x10];
            byte[]        i       = new byte[0x10];
            byte[]        buffer5 = null;
            byte[]        buffer6 = this.getKey(inFile);
            DirectoryInfo info    = Directory.CreateDirectory(str2 + "/rifs");
            FileStream    stream2 = File.Open(outFile, FileMode.Create);

            stream2.Write(rif_header, 0, 8);
            stream2.Write(buffer, 0, 8);
            byte[] bytes = Encoding.UTF8.GetBytes(s);
            ConversionUtils.arraycopy(bytes, 0, dest, 0L, bytes.Length);
            stream2.Write(dest, 0, 0x30);
            ToolsImpl.aesecbEncrypt(RIFKEY, i, 0, o, 0, 0x10);
            stream2.Write(o, 0, 0x10);
            long num = 0L;

            byte[] src     = decryptACTDAT(path, iDPSFile);
            byte[] buffer9 = new byte[0x10];
            buffer5 = new byte[0x10];
            byte[] buffer10 = new byte[40];
            ConversionUtils.arraycopy(src, ((int)num) * 0x10, buffer9, 0L, 0x10);
            ToolsImpl.aesecbEncrypt(buffer9, buffer6, 0, buffer5, 0, 0x10);
            stream2.Write(buffer5, 0, 0x10);
            stream2.Write(rif_footer, 0, 0x10);
            while (stream2.Length < 0x98L)
            {
                stream2.Write(rif_junk, 0, 1);
            }
            stream2.Close();
            return(outFile);
        }
Exemple #27
0
 public override void doUpdate(byte[] i, int inOffset, byte[] o, int outOffset, int len)
 {
     ConversionUtils.arraycopy(i, inOffset, o, outOffset, len);
 }
        private int encryptData(FileStream ii, FileStream o, NPD npd, EDATData data, byte[] rifkey)
        {
            int numBlocks = (int)((data.getFileLen() + data.getBlockSize() - 1) / data.getBlockSize());

            byte[] expectedHashForFile  = new byte[numBlocks * 0x10];
            byte[] encryptedDataForFile = new byte[ii.Length + 0xF];

            // File Format:
            // ALL HASHES
            // Encrypted Data
            for (int i = 0; i < numBlocks; i++)
            {
                long offset;
                int  len;

                offset = i * data.getBlockSize();
                ii.Seek(offset, SeekOrigin.Begin);
                len = (int)(data.getBlockSize());
                if (i == numBlocks - 1)
                {
                    len = (int)(data.getFileLen() % (new BigInteger(data.getBlockSize())));
                }


                int realLen = len;
                len = (int)((uint)(len + 0x0F) & 0xFFFFFFF0);

                byte[] encryptedData = new byte[len];
                byte[] decryptedData = new byte[len];

                int toRead = realLen;
                while (toRead > 0)
                {
                    toRead -= ii.Read(decryptedData, realLen - toRead, toRead);
                }
                for (int ai = realLen; ai < len; ai++)
                {
                    decryptedData[ai] = 0x00;
                }

                byte[] key      = new byte[0x10];
                byte[] hash     = new byte[0x10];
                byte[] blockKey = calculateBlockKey(i, npd);

                ToolsImpl.aesecbEncrypt(rifkey, blockKey, 0, key, 0, blockKey.Length);
                ConversionUtils.arraycopy(key, 0, hash, 0, key.Length);
                int cryptoFlag = 0x2;
                int hashFlag   = 0x02;

                AppLoaderReverse a             = new AppLoaderReverse();
                byte[]           iv            = npd.getDigest();
                byte[]           generatedHash = new byte[0x10];
                a.doAll(hashFlag, cryptoFlag, decryptedData, 0, encryptedData, 0, decryptedData.Length, key, iv, hash, generatedHash, 0);
                ConversionUtils.arraycopy(encryptedData, 0, encryptedDataForFile, offset, len);
                ConversionUtils.arraycopy(generatedHash, 0, expectedHashForFile, i * 0x10, 0x10);
            }
            byte[] EDATAVersion = ConversionUtils.getByteArray("4D6164652062792052325220546F6F6C");
            o.Write(expectedHashForFile, 0, expectedHashForFile.Length);
            o.Write(encryptedDataForFile, 0, encryptedDataForFile.Length - 0xf);
            o.Write(EDATAVersion, 0, EDATAVersion.Length);
            return(STATUS_OK);
        }