Example #1
0
        private static byte[] CreateSequence(Nintendo.Sead.Random random)
        {
            // Create byte array
            byte[] sequence = new byte[16];

            // Create each byte
            for (int i = 0; i < sequence.Length; i++)
            {
                // Create empty byte string
                string byteString = "";

                // Get characters from key material
                byteString += KeyMaterialString[(int)(random.GetUInt32() >> 24)];
                byteString += KeyMaterialString[(int)(random.GetUInt32() >> 24)];

                // Parse the resulting byte
                sequence[i] = Convert.ToByte(byteString, 16);
            }

            // Return the sequence
            return(sequence);
        }
Example #2
0
        public static void Decrypt(Stream inputStream, Stream outputStream, string gamePath)
        {
            // Read the entire file into an array
            byte[] encryptedData = new byte[inputStream.Length - 8];
            inputStream.Seek(0, SeekOrigin.Begin);
            inputStream.Read(encryptedData, 0, (int)inputStream.Length - 8);

            // Generate a CRC32 over the game path
            Crc32 crc32 = new Crc32();
            uint  seed  = crc32.Get(Encoding.ASCII.GetBytes(gamePath));

            // Create a new SeadRandom instance using the seed
            Nintendo.Sead.Random seadRandom = new Nintendo.Sead.Random(seed);

            // Create the encryption key and IV
            byte[] encryptionKey = CreateSequence(seadRandom);
            byte[] iv            = CreateSequence(seadRandom);

            // Generate a KeyParameter instance
            KeyParameter parameter = new KeyParameter(encryptionKey);

            // Initialize the AES-CBC cipher
            IBufferedCipher cipher = CipherUtilities.GetCipher("AES/CBC/NoPadding");

            cipher.Init(false, new ParametersWithIV(parameter, iv));

            // Return the decrypted bytes
            byte[] output = cipher.DoFinal(encryptedData);

            // Seek to the beginning
            outputStream.Seek(0, SeekOrigin.Begin);

            // Write to the output stream
            outputStream.Write(output, 0, output.Length);

            // Seek back to the beginning
            outputStream.Seek(0, SeekOrigin.Begin);
        }