diff --git a/NDecrypt.Core/CommonOperations.cs b/NDecrypt.Core/CommonOperations.cs index 2ce0d35..231f589 100644 --- a/NDecrypt.Core/CommonOperations.cs +++ b/NDecrypt.Core/CommonOperations.cs @@ -134,9 +134,10 @@ namespace NDecrypt.Core /// Byte array to add to /// Amount to add /// Byte array representing the new value - public static byte[] Add(byte[] input, int add) + public static byte[] Add(byte[] input, uint add) { byte[] addBytes = BitConverter.GetBytes(add); + Array.Reverse(addBytes); byte[] paddedBytes = new byte[16]; Array.Copy(addBytes, 0, paddedBytes, 12, 4); return Add(input, paddedBytes); @@ -155,10 +156,10 @@ namespace NDecrypt.Core byte[] output = new byte[outLength]; - int carry = 0; + uint carry = 0; for (int i = 0; i < addBytes; i++) { - int addValue = left[i] + right[i] + carry; + uint addValue = (uint)(left[i] + right[i] + carry); output[i] = (byte)addValue; carry = addValue > byte.MaxValue ? byte.MaxValue - addValue : 0; } @@ -195,11 +196,11 @@ namespace NDecrypt.Core // Shift by bits while (r_bits-- > 0) { - int carry = 0; + uint carry = 0; for (int i = 0; i < val.Length; i++) { byte nextByte = (byte)((val[i] << 1) + carry); - carry = (val[i] << 1) > byte.MaxValue ? byte.MaxValue - (val[i] << 1) : 0; + carry = (uint)((val[i] << 1) > byte.MaxValue ? byte.MaxValue - (val[i] << 1) : 0); val[i] = nextByte; } diff --git a/NDecrypt.Core/NDecrypt.Core.csproj b/NDecrypt.Core/NDecrypt.Core.csproj index 37130d2..d125dff 100644 --- a/NDecrypt.Core/NDecrypt.Core.csproj +++ b/NDecrypt.Core/NDecrypt.Core.csproj @@ -47,7 +47,7 @@ - + \ No newline at end of file diff --git a/NDecrypt.Core/ThreeDSTool.cs b/NDecrypt.Core/ThreeDSTool.cs index f6ba6de..4fbf835 100644 --- a/NDecrypt.Core/ThreeDSTool.cs +++ b/NDecrypt.Core/ThreeDSTool.cs @@ -282,8 +282,8 @@ namespace NDecrypt.Core output.Seek(exeFsOffset, SeekOrigin.Begin); // Create the ExeFS AES cipher for this partition - int ctroffsetE = (int)(cart.MediaUnitSize / 0x10); - byte[] exefsIVWithOffset = Add(cart.ExeFSIV(index), ctroffsetE); + uint ctroffsetE = cart.MediaUnitSize / 0x10; + byte[] exefsIVWithOffset = Add(FlipFirstHalf(cart.ExeFSIV(index)), ctroffsetE); var cipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey2C!, exefsIVWithOffset); // Setup and perform the decryption @@ -373,7 +373,7 @@ namespace NDecrypt.Core // Create the ExeFS AES ciphers for this partition uint ctroffset = (fileHeader.FileOffset + cart.MediaUnitSize) / 0x10; - byte[] exefsIVWithOffsetForHeader = Add(cart.ExeFSIV(index), (int)ctroffset); + byte[] exefsIVWithOffsetForHeader = Add(FlipFirstHalf(cart.ExeFSIV(index)), ctroffset); var firstCipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey!, exefsIVWithOffsetForHeader); var secondCipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey2C!, exefsIVWithOffsetForHeader); @@ -421,7 +421,7 @@ namespace NDecrypt.Core output.Seek(romFsOffset, SeekOrigin.Begin); // Create the RomFS AES cipher for this partition - var cipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey!, cart.RomFSIV(index)); + var cipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey!, FlipFirstHalf(cart.RomFSIV(index))); // Setup and perform the decryption PerformAESOperation(romFsSize, @@ -649,8 +649,8 @@ namespace NDecrypt.Core output.Seek(exeFsHeaderOffset, SeekOrigin.Begin); // Create the ExeFS AES cipher for this partition - int ctroffsetE = (int)(cart.MediaUnitSize / 0x10); - byte[] exefsIVWithOffset = Add(cart.ExeFSIV(index), ctroffsetE); + uint ctroffsetE = cart.MediaUnitSize / 0x10; + byte[] exefsIVWithOffset = Add(FlipFirstHalf(cart.ExeFSIV(index)), ctroffsetE); var cipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey2C!, exefsIVWithOffset); // Setup and perform the encryption @@ -743,7 +743,7 @@ namespace NDecrypt.Core // Create the ExeFS AES ciphers for this partition uint ctroffset = (fileHeader.FileOffset + cart.MediaUnitSize) / 0x10; - byte[] exefsIVWithOffsetForHeader = Add(cart.ExeFSIV(index), (int)ctroffset); + byte[] exefsIVWithOffsetForHeader = Add(FlipFirstHalf(cart.ExeFSIV(index)), ctroffset); var firstCipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey!, exefsIVWithOffsetForHeader); var secondCipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey2C!, exefsIVWithOffsetForHeader); @@ -798,7 +798,7 @@ namespace NDecrypt.Core } // Create the RomFS AES cipher for this partition - var cipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey!, cart.RomFSIV(index)); + var cipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey!, FlipFirstHalf(cart.RomFSIV(index))); // Setup and perform the decryption PerformAESOperation(romFsSize, @@ -846,5 +846,18 @@ namespace NDecrypt.Core } #endregion + + // TODO: REMOVE WHEN SERIALIZATION FIXED + private static byte[] FlipFirstHalf(byte[] data) + { + byte[] toFlip = new byte[8]; + Array.Copy(data, toFlip, 8); + Array.Reverse(toFlip); + + byte[] output = new byte[16]; + Array.Copy(toFlip, output, 8); + Array.Copy(data, 8, output, 8, 8); + return output; + } } }