mirror of
https://github.com/SabreTools/NDecrypt.git
synced 2026-07-08 18:06:38 +00:00
Add byte array helpers
This commit is contained in:
@@ -295,7 +295,7 @@ namespace NDecrypt.Core
|
||||
|
||||
// Create the ExeFS AES cipher for this partition
|
||||
int ctroffsetE = (int)(mediaUnitSize / 0x10);
|
||||
byte[] exefsIVWithOffset = AddToByteArray(header.ExeFSIV(), ctroffsetE);
|
||||
byte[] exefsIVWithOffset = Add(header.ExeFSIV(), ctroffsetE);
|
||||
var cipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey2C, exefsIVWithOffset);
|
||||
|
||||
// Setup and perform the decryption
|
||||
@@ -393,7 +393,7 @@ namespace NDecrypt.Core
|
||||
|
||||
// Create the ExeFS AES ciphers for this partition
|
||||
uint ctroffset = (fileHeader.FileOffset + mediaUnitSize) / 0x10;
|
||||
byte[] exefsIVWithOffsetForHeader = AddToByteArray(header.ExeFSIV(), (int)ctroffset);
|
||||
byte[] exefsIVWithOffsetForHeader = Add(header.ExeFSIV(), (int)ctroffset);
|
||||
var firstCipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey, exefsIVWithOffsetForHeader);
|
||||
var secondCipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey2C, exefsIVWithOffsetForHeader);
|
||||
|
||||
@@ -684,7 +684,7 @@ namespace NDecrypt.Core
|
||||
|
||||
// Create the ExeFS AES cipher for this partition
|
||||
int ctroffsetE = (int)(mediaUnitSize / 0x10);
|
||||
byte[] exefsIVWithOffset = AddToByteArray(header.ExeFSIV(), ctroffsetE);
|
||||
byte[] exefsIVWithOffset = Add(header.ExeFSIV(), ctroffsetE);
|
||||
var cipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey2C, exefsIVWithOffset);
|
||||
|
||||
// Setup and perform the decryption
|
||||
@@ -782,7 +782,7 @@ namespace NDecrypt.Core
|
||||
|
||||
// Create the ExeFS AES ciphers for this partition
|
||||
uint ctroffset = (fileHeader.FileOffset + mediaUnitSize) / 0x10;
|
||||
byte[] exefsIVWithOffsetForHeader = AddToByteArray(header.ExeFSIV(), (int)ctroffset);
|
||||
byte[] exefsIVWithOffsetForHeader = Add(header.ExeFSIV(), (int)ctroffset);
|
||||
var firstCipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey, exefsIVWithOffsetForHeader);
|
||||
var secondCipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey2C, exefsIVWithOffsetForHeader);
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ using SabreTools.Models.N3DS;
|
||||
|
||||
namespace NDecrypt.Core
|
||||
{
|
||||
internal static class CommonOperations
|
||||
public static class CommonOperations
|
||||
{
|
||||
#region AES
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace NDecrypt.Core
|
||||
/// <param name="input">Byte array to add to</param>
|
||||
/// <param name="add">Amount to add</param>
|
||||
/// <returns>Byte array representing the new value</returns>
|
||||
public static byte[] AddToByteArray(byte[] input, int add)
|
||||
public static byte[] Add(byte[] input, int add)
|
||||
{
|
||||
int len = input.Length;
|
||||
Array.Reverse(input);
|
||||
@@ -190,6 +190,35 @@ namespace NDecrypt.Core
|
||||
return arr;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add two numbers represented by byte arrays
|
||||
/// </summary>
|
||||
/// <param name="left">Byte array to add to</param>
|
||||
/// <param name="right">Amount to add</param>
|
||||
/// <returns>Byte array representing the new value</returns>
|
||||
public static byte[] Add(byte[] left, byte[] right)
|
||||
{
|
||||
int addBytes = Math.Min(left.Length, right.Length);
|
||||
int outLength = Math.Max(left.Length, right.Length);
|
||||
|
||||
byte[] output = new byte[outLength];
|
||||
|
||||
int carry = 0;
|
||||
for (int i = 0; i < addBytes; i++)
|
||||
{
|
||||
int addValue = left[i] + right[i] + carry;
|
||||
output[i] = (byte)addValue;
|
||||
carry = addValue > byte.MaxValue ? byte.MaxValue - addValue : 0;
|
||||
}
|
||||
|
||||
if (outLength != addBytes && left.Length == outLength)
|
||||
Array.Copy(left, addBytes, output, addBytes, outLength - addBytes);
|
||||
else if (outLength != addBytes && right.Length == outLength)
|
||||
Array.Copy(right, addBytes, output, addBytes, outLength - addBytes);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform a rotate left on a BigInteger
|
||||
/// </summary>
|
||||
@@ -202,6 +231,69 @@ namespace NDecrypt.Core
|
||||
return (val << r_bits % max_bits) & (BigInteger.Pow(2, max_bits) - 1) | ((val & (BigInteger.Pow(2, max_bits) - 1)) >> (max_bits - (r_bits % max_bits)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Perform a rotate left on a byte array
|
||||
/// </summary>
|
||||
/// <param name="val">Byte array value to rotate</param>
|
||||
/// <param name="r_bits">Number of bits to rotate</param>
|
||||
/// <returns>Rotated byte array value</returns>
|
||||
public static byte[] RotateLeft(byte[] val, int r_bits)
|
||||
{
|
||||
// Shift by bytes
|
||||
while (r_bits >= 8)
|
||||
{
|
||||
byte temp = val[0];
|
||||
for (int i = 0; i < val.Length - 1; i++)
|
||||
{
|
||||
val[i] = val[i + 1];
|
||||
}
|
||||
|
||||
val[val.Length - 1] = temp;
|
||||
r_bits -= 8;
|
||||
}
|
||||
|
||||
// Shift by bits
|
||||
while (r_bits-- > 0)
|
||||
{
|
||||
int 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;
|
||||
val[i] = nextByte;
|
||||
}
|
||||
|
||||
val[val.Length - 1] = (byte)(val[val.Length - 1] + carry);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// XOR two numbers represented by byte arrays
|
||||
/// </summary>
|
||||
/// <param name="left">Byte array to XOR to</param>
|
||||
/// <param name="right">Amount to XOR</param>
|
||||
/// <returns>Byte array representing the new value</returns>
|
||||
public static byte[] Xor(byte[] left, byte[] right)
|
||||
{
|
||||
int xorBytes = Math.Min(left.Length, right.Length);
|
||||
int outLength = Math.Max(left.Length, right.Length);
|
||||
|
||||
byte[] output = new byte[outLength];
|
||||
for (int i = 0; i < xorBytes; i++)
|
||||
{
|
||||
output[i] = (byte)(left[i] ^ right[i]);
|
||||
}
|
||||
|
||||
if (outLength != xorBytes && left.Length == outLength)
|
||||
Array.Copy(left, xorBytes, output, xorBytes, outLength - xorBytes);
|
||||
else if (outLength != xorBytes && right.Length == outLength)
|
||||
Array.Copy(right, xorBytes, output, xorBytes, outLength - xorBytes);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Offsets
|
||||
|
||||
@@ -283,7 +283,7 @@ namespace NDecrypt.Core
|
||||
|
||||
// Create the ExeFS AES cipher for this partition
|
||||
int ctroffsetE = (int)(cart.MediaUnitSize() / 0x10);
|
||||
byte[] exefsIVWithOffset = AddToByteArray(cart.ExeFSIV(index), ctroffsetE);
|
||||
byte[] exefsIVWithOffset = Add(cart.ExeFSIV(index), ctroffsetE);
|
||||
var cipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey2C, exefsIVWithOffset);
|
||||
|
||||
// Setup and perform the decryption
|
||||
@@ -369,7 +369,7 @@ namespace NDecrypt.Core
|
||||
|
||||
// Create the ExeFS AES ciphers for this partition
|
||||
uint ctroffset = (fileHeader.FileOffset + cart.MediaUnitSize()) / 0x10;
|
||||
byte[] exefsIVWithOffsetForHeader = AddToByteArray(cart.ExeFSIV(index), (int)ctroffset);
|
||||
byte[] exefsIVWithOffsetForHeader = Add(cart.ExeFSIV(index), (int)ctroffset);
|
||||
var firstCipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey, exefsIVWithOffsetForHeader);
|
||||
var secondCipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey2C, exefsIVWithOffsetForHeader);
|
||||
|
||||
@@ -643,7 +643,7 @@ namespace NDecrypt.Core
|
||||
|
||||
// Create the ExeFS AES cipher for this partition
|
||||
int ctroffsetE = (int)(cart.MediaUnitSize() / 0x10);
|
||||
byte[] exefsIVWithOffset = AddToByteArray(cart.ExeFSIV(index), ctroffsetE);
|
||||
byte[] exefsIVWithOffset = Add(cart.ExeFSIV(index), ctroffsetE);
|
||||
var cipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey2C, exefsIVWithOffset);
|
||||
|
||||
// Setup and perform the encryption
|
||||
@@ -729,7 +729,7 @@ namespace NDecrypt.Core
|
||||
|
||||
// Create the ExeFS AES ciphers for this partition
|
||||
uint ctroffset = (fileHeader.FileOffset + cart.MediaUnitSize()) / 0x10;
|
||||
byte[] exefsIVWithOffsetForHeader = AddToByteArray(cart.ExeFSIV(index), (int)ctroffset);
|
||||
byte[] exefsIVWithOffsetForHeader = Add(cart.ExeFSIV(index), (int)ctroffset);
|
||||
var firstCipher = CreateAESEncryptionCipher(KeysMap[index].NormalKey, exefsIVWithOffsetForHeader);
|
||||
var secondCipher = CreateAESDecryptionCipher(KeysMap[index].NormalKey2C, exefsIVWithOffsetForHeader);
|
||||
|
||||
|
||||
@@ -14,6 +14,18 @@ namespace NDecrypt
|
||||
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
// TEMP SHIT CODE
|
||||
|
||||
byte[] x =
|
||||
[
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
||||
];
|
||||
x = CommonOperations.Add(x, x);
|
||||
string s = BitConverter.ToString(x);
|
||||
|
||||
// END TEMP SHIT CODE
|
||||
|
||||
if (args.Length < 2)
|
||||
{
|
||||
DisplayHelp("Not enough arguments");
|
||||
|
||||
Reference in New Issue
Block a user