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;
+ }
}
}