protected void SetBoolProperty(BitMasks propertyMask, bool value) { byte mask = (byte)propertyMask; Buffer[0] = (byte)(value ? (Buffer[0] | mask) : (Buffer[0] & ~mask)); IsDirty = true; }
/// <summary> /// Update the CryptoMethod and BitMasks for the encrypted partition /// </summary> /// <param name="ncsdHeader">NCSD header representing the 3DS file</param> /// <param name="ncchHeader">NCCH header representing the partition</param> /// <param name="writer">BinaryWriter representing the output stream</param> private void UpdateEncryptCryptoAndMasks(NCSDHeader ncsdHeader, NCCHHeader ncchHeader, BinaryWriter writer) { // Write the new CryptoMethod writer.BaseStream.Seek((ncchHeader.Entry.Offset * ncsdHeader.MediaUnitSize) + 0x18B, SeekOrigin.Begin); // For partitions 1 and up, set crypto-method to 0x00 if (ncchHeader.PartitionNumber > 0) { writer.Write((byte)CryptoMethod.Original); } // If partition 0, restore crypto-method from backup flags else { writer.Write((byte)ncsdHeader.BackupHeader.Flags.CryptoMethod); } writer.Flush(); // Write the new BitMasks flag writer.BaseStream.Seek((ncchHeader.Entry.Offset * ncsdHeader.MediaUnitSize) + 0x18F, SeekOrigin.Begin); BitMasks flag = ncchHeader.Flags.BitMasks; flag &= (BitMasks.FixedCryptoKey | BitMasks.NewKeyYGenerator | BitMasks.NoCrypto) ^ (BitMasks)0xFF; flag |= (BitMasks.FixedCryptoKey | BitMasks.NewKeyYGenerator) & ncsdHeader.BackupHeader.Flags.BitMasks; writer.Write((byte)flag); writer.Flush(); }
/// <summary> /// Update the CryptoMethod and BitMasks for the encrypted partition /// </summary> /// <param name="ciaHeader">CIA header representing the 3DS CIA file</param> /// <param name="ncchHeader">NCCH header representing the partition</param> /// <param name="writer">BinaryWriter representing the output stream</param> private void UpdateEncryptCryptoAndMasks(CIAHeader ciaHeader, NCCHHeader ncchHeader, BinaryWriter writer) { // TODO: Determine how to figure out the MediaUnitSize without an NCSD header. Is it a default value? uint mediaUnitSize = 0x200; // ncsdHeader.MediaUnitSize; // Write the new CryptoMethod writer.BaseStream.Seek((ncchHeader.Entry.Offset * mediaUnitSize) + 0x18B, SeekOrigin.Begin); // For partitions 1 and up, set crypto-method to 0x00 if (ncchHeader.PartitionNumber > 0) { writer.Write((byte)CryptoMethod.Original); } // TODO: Determine how to figure out the original crypto method, if possible // If partition 0, restore crypto-method from backup flags //else // writer.Write((byte)ciaHeader.BackupHeader.Flags.CryptoMethod); writer.Flush(); // Write the new BitMasks flag writer.BaseStream.Seek((ncchHeader.Entry.Offset * mediaUnitSize) + 0x18F, SeekOrigin.Begin); BitMasks flag = ncchHeader.Flags.BitMasks; flag &= (BitMasks.FixedCryptoKey | BitMasks.NewKeyYGenerator | BitMasks.NoCrypto) ^ (BitMasks)0xFF; // TODO: Determine how to figure out the original crypto method, if possible //flag |= (BitMasks.FixedCryptoKey | BitMasks.NewKeyYGenerator) & ciaHeader.BackupHeader.Flags.BitMasks; writer.Write((byte)flag); writer.Flush(); }
protected void SetByteProperty(BitMasks propertyMask, byte value) { byte mask = (byte)propertyMask; value = (byte)(value << GetShiftLevel(propertyMask)); Buffer[0] = (byte)((value & mask) | (Buffer[0] & ~mask)); IsDirty = true; }
/// <summary> /// Update the CryptoMethod and BitMasks for the decrypted partition /// </summary> /// <param name="ncsdHeader">NCSD header representing the 3DS file</param> /// <param name="ncchHeader">NCCH header representing the partition</param> /// <param name="writer">BinaryWriter representing the output stream</param> private void UpdateDecryptCryptoAndMasks(NCSDHeader ncsdHeader, NCCHHeader ncchHeader, BinaryWriter writer) { // Write the new CryptoMethod writer.BaseStream.Seek((ncchHeader.Entry.Offset * ncsdHeader.MediaUnitSize) + 0x18B, SeekOrigin.Begin); writer.Write((byte)CryptoMethod.Original); writer.Flush(); // Write the new BitMasks flag writer.BaseStream.Seek((ncchHeader.Entry.Offset * ncsdHeader.MediaUnitSize) + 0x18F, SeekOrigin.Begin); BitMasks flag = ncchHeader.Flags.BitMasks; flag &= (BitMasks)((byte)(BitMasks.FixedCryptoKey | BitMasks.NewKeyYGenerator) ^ 0xFF); flag |= BitMasks.NoCrypto; writer.Write((byte)flag); writer.Flush(); }
/// <summary> /// Update the CryptoMethod and BitMasks for the decrypted partition /// </summary> /// <param name="ncchHeader">NCCH header representing the partition</param> /// <param name="writer">BinaryWriter representing the output stream</param> private void UpdateDecryptCryptoAndMasks(NCCHHeader ncchHeader, BinaryWriter writer) { // TODO: Determine how to figure out the MediaUnitSize without an NCSD header. Is it a default value? uint mediaUnitSize = 0x200; // ncsdHeader.MediaUnitSize; // Write the new CryptoMethod writer.BaseStream.Seek((ncchHeader.Entry.Offset * mediaUnitSize) + 0x18B, SeekOrigin.Begin); writer.Write((byte)CryptoMethod.Original); writer.Flush(); // Write the new BitMasks flag writer.BaseStream.Seek((ncchHeader.Entry.Offset * mediaUnitSize) + 0x18F, SeekOrigin.Begin); BitMasks flag = ncchHeader.Flags.BitMasks; flag &= (BitMasks)((byte)(BitMasks.FixedCryptoKey | BitMasks.NewKeyYGenerator) ^ 0xFF); flag |= BitMasks.NoCrypto; writer.Write((byte)flag); writer.Flush(); }
private int GetShiftLevel(BitMasks propertyMask) { int shiftLevel = 0; if (propertyMask.HasFlag(BitMasks.Bit0)) { shiftLevel = 0; } else if (propertyMask.HasFlag(BitMasks.Bit1)) { shiftLevel = 1; } else if (propertyMask.HasFlag(BitMasks.Bit2)) { shiftLevel = 2; } else if (propertyMask.HasFlag(BitMasks.Bit3)) { shiftLevel = 3; } else if (propertyMask.HasFlag(BitMasks.Bit4)) { shiftLevel = 4; } else if (propertyMask.HasFlag(BitMasks.Bit5)) { shiftLevel = 5; } else if (propertyMask.HasFlag(BitMasks.Bit6)) { shiftLevel = 6; } else if (propertyMask.HasFlag(BitMasks.Bit7)) { shiftLevel = 7; } return(shiftLevel); }
public Index <BitMaskInfo> Load(Type src) => BitMasks.descriptions(src);
/// <summary> /// Determine the set of keys to be used for encryption or decryption /// </summary> /// <param name="ciaHeader">NCSD header representing the 3DS CIA file</param> /// <param name="ncchHeader">NCCH header representing the partition</param> private void SetEncryptionKeys(CIAHeader ciaHeader, NCCHHeader ncchHeader) { ncchHeader.KeyX = 0; ncchHeader.KeyX2C = decryptArgs.Development ? decryptArgs.DevKeyX0x2C : decryptArgs.KeyX0x2C; // Backup headers can't have a KeyY value set if (ncchHeader.RSA2048Signature != null) { ncchHeader.KeyY = new BigInteger(ncchHeader.RSA2048Signature.Take(16).Reverse().ToArray()); } else { ncchHeader.KeyY = new BigInteger(0); } ncchHeader.NormalKey = 0; ncchHeader.NormalKey2C = RotateLeft((RotateLeft(ncchHeader.KeyX2C, 2, 128) ^ ncchHeader.KeyY) + decryptArgs.AESHardwareConstant, 87, 128); // TODO: Figure out what sane defaults for these values are // Set the header to use based on mode BitMasks masks = BitMasks.NoCrypto; CryptoMethod method = CryptoMethod.Original; if (decryptArgs.Encrypt) { // TODO: Can we actually re-encrypt a CIA? //masks = ciaHeader.BackupHeader.Flags.BitMasks; //method = ciaHeader.BackupHeader.Flags.CryptoMethod; } else { masks = ncchHeader.Flags.BitMasks; method = ncchHeader.Flags.CryptoMethod; } if (masks.HasFlag(BitMasks.FixedCryptoKey)) { ncchHeader.NormalKey = 0x00; ncchHeader.NormalKey2C = 0x00; Console.WriteLine("Encryption Method: Zero Key"); } else { if (method == CryptoMethod.Original) { ncchHeader.KeyX = decryptArgs.Development ? decryptArgs.DevKeyX0x2C : decryptArgs.KeyX0x2C; Console.WriteLine("Encryption Method: Key 0x2C"); } else if (method == CryptoMethod.Seven) { ncchHeader.KeyX = decryptArgs.Development ? decryptArgs.DevKeyX0x25 : decryptArgs.KeyX0x25; Console.WriteLine("Encryption Method: Key 0x25"); } else if (method == CryptoMethod.NineThree) { ncchHeader.KeyX = decryptArgs.Development ? decryptArgs.DevKeyX0x18 : decryptArgs.KeyX0x18; Console.WriteLine("Encryption Method: Key 0x18"); } else if (method == CryptoMethod.NineSix) { ncchHeader.KeyX = decryptArgs.Development ? decryptArgs.DevKeyX0x1B : decryptArgs.KeyX0x1B; Console.WriteLine("Encryption Method: Key 0x1B"); } ncchHeader.NormalKey = RotateLeft((RotateLeft(ncchHeader.KeyX, 2, 128) ^ ncchHeader.KeyY) + decryptArgs.AESHardwareConstant, 87, 128); } }
protected bool GetBoolProperty(BitMasks propertyMask) { return(GetByteProperty(propertyMask) > 0); }
protected byte GetByteProperty(BitMasks propertyMask) { return((byte)((Buffer[0] & (byte)propertyMask) >> GetShiftLevel(propertyMask))); }
protected byte GetByteProperty(BitMasks propertyMask) { return (byte)((Buffer[0] & (byte)propertyMask) >> GetShiftLevel(propertyMask)); }
protected bool GetBoolProperty(BitMasks propertyMask) { return GetByteProperty(propertyMask) > 0; }
private int GetShiftLevel(BitMasks propertyMask) { int shiftLevel = 0; if (propertyMask.HasFlag(BitMasks.Bit0)) shiftLevel = 0; else if (propertyMask.HasFlag(BitMasks.Bit1)) shiftLevel = 1; else if (propertyMask.HasFlag(BitMasks.Bit2)) shiftLevel = 2; else if (propertyMask.HasFlag(BitMasks.Bit3)) shiftLevel = 3; else if (propertyMask.HasFlag(BitMasks.Bit4)) shiftLevel = 4; else if (propertyMask.HasFlag(BitMasks.Bit5)) shiftLevel = 5; else if (propertyMask.HasFlag(BitMasks.Bit6)) shiftLevel = 6; else if (propertyMask.HasFlag(BitMasks.Bit7)) shiftLevel = 7; return shiftLevel; }