diff --git a/LibIRD/IRD.cs b/LibIRD/IRD.cs index b0cc17e..e7ba1d8 100644 --- a/LibIRD/IRD.cs +++ b/LibIRD/IRD.cs @@ -131,75 +131,7 @@ namespace LibIRD #endregion - #region Generate Keys - - /// - /// Generates Data 1, via AES-128 CBC decryption of a Disc Key - /// - /// Byte array containing AES encrypted Disc Key - /// - /// - private protected void GenerateD1(byte[] key) - { - // Validate key - if (key == null) - throw new ArgumentNullException(nameof(key)); - if (key.Length != 16) - throw new ArgumentException("Disc Key must be a byte array of length 16", nameof(key)); - - // Setup AES decryption - using Aes aes = Aes.Create() ?? throw new InvalidOperationException("AES not available. Change your system settings"); - - // Set AES settings - aes.Key = D1AesKey; - aes.IV = D1AesIV; - aes.Padding = PaddingMode.None; - aes.Mode = CipherMode.CBC; - - // Perform AES decryption - using MemoryStream stream = new(); - using ICryptoTransform dec = aes.CreateDecryptor(); - using CryptoStream cs = new(stream, dec, CryptoStreamMode.Write); - cs.Write(key, 0, 16); - cs.FlushFinalBlock(); - - // Save decrypted key to field - Data1Key = stream.ToArray(); - } - - /// - /// Generates Data 2, via AES-128 CBC encryption of a Disc ID - /// - /// Byte array containing AES decrypted Disc ID - /// - /// - private protected void GenerateD2(byte[] id) - { - // Validate id - if (id == null) - throw new ArgumentNullException(nameof(id)); - if (id.Length != 16) - throw new ArgumentException("Disc ID must be a byte array of length 16", nameof(id)); - - // Setup AES encryption - using Aes aes = Aes.Create() ?? throw new InvalidOperationException("AES not available. Change your system settings"); - - // Set AES settings - aes.Key = D2AesKey; - aes.IV = D2AesIV; - aes.Padding = PaddingMode.None; - aes.Mode = CipherMode.CBC; - - // Perform AES encryption - using MemoryStream stream = new(); - using ICryptoTransform enc = aes.CreateEncryptor(); - using CryptoStream cs = new(stream, enc, CryptoStreamMode.Write); - cs.Write(id, 0, 16); - cs.FlushFinalBlock(); - - // Save encrypted key to field - Data2Key = stream.ToArray(); - } + #region Helper Functions #endregion @@ -315,6 +247,74 @@ namespace LibIRD #region Methods + /// + /// Generates Data 1, via AES-128 CBC decryption of a Disc Key + /// + /// Byte array containing AES encrypted Disc Key + /// + /// + private protected void GenerateD1(byte[] key) + { + // Validate key + if (key == null) + throw new ArgumentNullException(nameof(key)); + if (key.Length != 16) + throw new ArgumentException("Disc Key must be a byte array of length 16", nameof(key)); + + // Setup AES decryption + using Aes aes = Aes.Create() ?? throw new InvalidOperationException("AES not available. Change your system settings"); + + // Set AES settings + aes.Key = D1AesKey; + aes.IV = D1AesIV; + aes.Padding = PaddingMode.None; + aes.Mode = CipherMode.CBC; + + // Perform AES decryption + using MemoryStream stream = new(); + using ICryptoTransform dec = aes.CreateDecryptor(); + using CryptoStream cs = new(stream, dec, CryptoStreamMode.Write); + cs.Write(key, 0, 16); + cs.FlushFinalBlock(); + + // Save decrypted key to field + Data1Key = stream.ToArray(); + } + + /// + /// Generates Data 2, via AES-128 CBC encryption of a Disc ID + /// + /// Byte array containing AES decrypted Disc ID + /// + /// + private protected void GenerateD2(byte[] id) + { + // Validate id + if (id == null) + throw new ArgumentNullException(nameof(id)); + if (id.Length != 16) + throw new ArgumentException("Disc ID must be a byte array of length 16", nameof(id)); + + // Setup AES encryption + using Aes aes = Aes.Create() ?? throw new InvalidOperationException("AES not available. Change your system settings"); + + // Set AES settings + aes.Key = D2AesKey; + aes.IV = D2AesIV; + aes.Padding = PaddingMode.None; + aes.Mode = CipherMode.CBC; + + // Perform AES encryption + using MemoryStream stream = new(); + using ICryptoTransform enc = aes.CreateEncryptor(); + using CryptoStream cs = new(stream, enc, CryptoStreamMode.Write); + cs.Write(id, 0, 16); + cs.FlushFinalBlock(); + + // Save encrypted key to field + Data2Key = stream.ToArray(); + } + /// /// Write IRD data to file /// diff --git a/LibIRD/ParamSFO.cs b/LibIRD/ParamSFO.cs index 3efa3ae..8e47b13 100644 --- a/LibIRD/ParamSFO.cs +++ b/LibIRD/ParamSFO.cs @@ -126,8 +126,8 @@ namespace LibIRD throw new ArgumentNullException(nameof(sfoPath)); // Read file as a stream, and parse file - using (FileStream fs = new FileStream(sfoPath, FileMode.Open, FileAccess.Read)) - Parse(fs); + using FileStream fs = new(sfoPath, FileMode.Open, FileAccess.Read); + Parse(fs); } /// @@ -138,67 +138,66 @@ namespace LibIRD private void Parse(Stream sfoStream) { // Read binary stream - using (BinaryReader br = new BinaryReader(sfoStream)) + using BinaryReader br = new(sfoStream); + + // Check file signature is correct + string magic = Encoding.ASCII.GetString(br.ReadBytes(4)); + if (magic != ParamSFO.Magic) + throw new FileLoadException("Not a valid PARAM.SFO file"); + + // Parse header + Version = br.ReadUInt32(); + KeyTableStart = br.ReadUInt32(); + DataTableStart = br.ReadUInt32(); + ParamCount = br.ReadUInt32(); + + // Parse parameter metadata + Params = new Param[ParamCount]; + for (int i = 0; i < ParamCount; i++) { - // Check file signature is correct - string magic = Encoding.ASCII.GetString(br.ReadBytes(4)); - if (magic != ParamSFO.Magic) - throw new FileLoadException("Not a valid PARAM.SFO file"); - - // Parse header - Version = br.ReadUInt32(); - KeyTableStart = br.ReadUInt32(); - DataTableStart = br.ReadUInt32(); - ParamCount = br.ReadUInt32(); - - // Parse parameter metadata - Params = new Param[ParamCount]; - for (int i = 0; i < ParamCount; i++) + Params[i] = new Param { - Params[i] = new Param - { - KeyOffset = br.ReadUInt16(), - DataFormat = br.ReadUInt16(), - DataLength = br.ReadUInt32(), - DataTotal = br.ReadUInt32(), - DataOffset = br.ReadUInt32() - }; - } + KeyOffset = br.ReadUInt16(), + DataFormat = br.ReadUInt16(), + DataLength = br.ReadUInt32(), + DataTotal = br.ReadUInt32(), + DataOffset = br.ReadUInt32() + }; + } - // Parse parameters - for (int i = 0; i < ParamCount; i++) + // Parse parameters + for (int i = 0; i < ParamCount; i++) + { + // Move stream to ith key + sfoStream.Position = KeyTableStart + Params[i].KeyOffset; + + // Determine ith key length + uint keyLen = ((i == ParamCount - 1) ? DataTableStart - KeyTableStart : Params[i + 1].KeyOffset) + - Params[i].KeyOffset; + + // Read ith key name + Params[i].Name = Encoding.ASCII.GetString(br.ReadBytes((int) keyLen)).TrimEnd('\0'); + + // Move stream to ith data + sfoStream.Position = DataTableStart + Params[i].DataOffset; + + // Read ith data, based on data format + switch (Params[i].DataFormat) { - // Move stream to ith key - sfoStream.Position = KeyTableStart + Params[i].KeyOffset; - - // Determine ith key length - uint keyLen = ((i == ParamCount - 1) ? DataTableStart - KeyTableStart : Params[i + 1].KeyOffset) - - Params[i].KeyOffset; - - // Read ith key name - Params[i].Name = Encoding.ASCII.GetString(br.ReadBytes((int) keyLen)).TrimEnd('\0'); - - // Move stream to ith data - sfoStream.Position = DataTableStart + Params[i].DataOffset; - - // Read ith data, based on data format - switch (Params[i].DataFormat) - { - case 0x0400: // Non-null-terminated UTF-8 String - Params[i].StringValue = Encoding.UTF8.GetString(br.ReadBytes((int)Params[i].DataLength)); - break; - case 0x0402: // Null-terminated UTF-8 String - Params[i].StringValue = Encoding.UTF8.GetString(br.ReadBytes((int)Params[i].DataLength)).TrimEnd('\0'); - break; - case 0x0404: // Integer - //if (Params[i].DataLength != 4) - //throw new ArgumentException("Integer parameter not 4 bytes?"); - Params[i].IntValue = br.ReadInt32(); - break; - default: // Unknown data format, assume null-terminated string - Params[i].StringValue = Encoding.UTF8.GetString(br.ReadBytes((int)Params[i].DataLength)).TrimEnd('\0'); - break; - } + case 0x0400: // Non-null-terminated UTF-8 String + Params[i].StringValue = Encoding.UTF8.GetString(br.ReadBytes((int)Params[i].DataLength)); + break; + case 0x0402: // Null-terminated UTF-8 String + Params[i].StringValue = Encoding.UTF8.GetString(br.ReadBytes((int)Params[i].DataLength)).TrimEnd('\0'); + break; + case 0x0404: // Integer + //if (Params[i].DataLength != 4) + //throw new ArgumentException("Integer parameter not 4 bytes?"); + Params[i].IntValue = br.ReadInt32(); + break; + default: // Unknown data format, assume null-terminated string + Params[i].StringValue = Encoding.UTF8.GetString(br.ReadBytes((int)Params[i].DataLength)).TrimEnd('\0'); + break; } } } @@ -209,7 +208,7 @@ namespace LibIRD public void Print() { // Build string from parameters - StringBuilder print = new StringBuilder("PARAM.SFO Contents:\n====================\n"); + StringBuilder print = new("PARAM.SFO Contents:\n====================\n"); // Loop through all parameters in PARAM.SFO for (int i = 0; i < ParamCount; i++) diff --git a/LibIRD/ReIRD.cs b/LibIRD/ReIRD.cs index 89011ee..f0fd18d 100644 --- a/LibIRD/ReIRD.cs +++ b/LibIRD/ReIRD.cs @@ -170,7 +170,7 @@ namespace LibIRD byte[] crc32; using (FileStream fs = File.OpenRead(isoPath)) { - Crc32 hasher = new Crc32(); + Crc32 hasher = new(); hasher.Append(fs); crc32 = hasher.GetCurrentHash(); Array.Reverse(crc32);