private byte[] GetDecryptedKeyAreaNca0() { if (Nca0KeyArea != null) { return(Nca0KeyArea); } if (Header.FormatVersion == NcaVersion.Nca0FixedKey) { Nca0KeyArea = Header.GetKeyArea().ToArray(); } else if (Header.FormatVersion == NcaVersion.Nca0RsaOaep) { Span <byte> keyArea = Header.GetKeyArea(); byte[] decKeyArea = new byte[0x100]; if (CryptoOld.DecryptRsaOaep(keyArea, decKeyArea, KeySet.BetaNca0KeyAreaKeyParams, out _)) { Nca0KeyArea = decKeyArea; } else { throw new InvalidDataException("Unable to decrypt NCA0 key area."); } } else { throw new NotSupportedException(); } return(Nca0KeyArea); }
public byte[] GetDecryptedTitleKey() { int keyRevision = Util.GetMasterKeyRevision(Header.KeyGeneration); byte[] titleKek = Keyset.TitleKeks[keyRevision]; var rightsId = new RightsId(Header.RightsId); if (Keyset.ExternalKeySet.Get(rightsId, out AccessKey accessKey).IsFailure()) { throw new MissingKeyException("Missing NCA title key.", rightsId.ToString(), KeyType.Title); } if (titleKek.IsEmpty()) { string keyName = $"titlekek_{keyRevision:x2}"; throw new MissingKeyException("Unable to decrypt title key.", keyName, KeyType.Common); } byte[] encryptedKey = accessKey.Value.ToArray(); var decryptedKey = new byte[CryptoOld.Aes128Size]; CryptoOld.DecryptEcb(titleKek, encryptedKey, decryptedKey, CryptoOld.Aes128Size); return(decryptedKey); }
public byte[] GetDecryptedKey(int index) { if (index < 0 || index > 3) { throw new ArgumentOutOfRangeException(nameof(index)); } // Handle old NCA0s that use different key area encryption if (Header.FormatVersion == NcaVersion.Nca0FixedKey || Header.FormatVersion == NcaVersion.Nca0RsaOaep) { return(GetDecryptedKeyAreaNca0().AsSpan(0x10 * index, 0x10).ToArray()); } int keyRevision = Utilities.GetMasterKeyRevision(Header.KeyGeneration); byte[] keyAreaKey = Keyset.KeyAreaKeys[keyRevision][Header.KeyAreaKeyIndex]; if (keyAreaKey.IsEmpty()) { string keyName = $"key_area_key_{Keyset.KakNames[Header.KeyAreaKeyIndex]}_{keyRevision:x2}"; throw new MissingKeyException("Unable to decrypt NCA section.", keyName, KeyType.Common); } byte[] encryptedKey = Header.GetEncryptedKey(index).ToArray(); var decryptedKey = new byte[CryptoOld.Aes128Size]; CryptoOld.DecryptEcb(keyAreaKey, encryptedKey, decryptedKey, CryptoOld.Aes128Size); return(decryptedKey); }
public static void TestCmacTestVectors(TestData data) { var actual = new byte[0x10]; CryptoOld.CalculateAesCmac(data.Key, data.Message, data.Start, actual, 0, data.Length); Assert.Equal(data.Expected, actual); }
private Validity ValidateSignature(Keyset keyset) { var calculatedCmac = new byte[0x10]; CryptoOld.CalculateAesCmac(keyset.SaveMacKey, Data, 0x100, calculatedCmac, 0, 0x200); return(Utilities.ArraysEqual(calculatedCmac, Cmac) ? Validity.Valid : Validity.Invalid); }
public Acid(Stream stream, int offset, KeySet keySet) { stream.Seek(offset, SeekOrigin.Begin); var reader = new BinaryReader(stream); Rsa2048Signature = reader.ReadBytes(0x100); Rsa2048Modulus = reader.ReadBytes(0x100); Magic = reader.ReadAscii(0x4); if (Magic != "ACID") { throw new Exception("ACID Stream doesn't contain ACID section!"); } Size = reader.ReadInt32(); if (keySet != null) { reader.BaseStream.Position = offset + 0x100; byte[] signatureData = reader.ReadBytes(Size); SignatureValidity = CryptoOld.Rsa2048PssVerify(signatureData, Rsa2048Signature, keySet.AcidSigningKeyParams[0].Modulus); } reader.BaseStream.Position = offset + 0x208; reader.ReadInt32(); //Bit0 must be 1 on retail, on devunit 0 is also allowed. Bit1 is unknown. Flags = reader.ReadInt32(); TitleIdRangeMin = reader.ReadInt64(); TitleIdRangeMax = reader.ReadInt64(); int fsAccessControlOffset = reader.ReadInt32(); int fsAccessControlSize = reader.ReadInt32(); int serviceAccessControlOffset = reader.ReadInt32(); int serviceAccessControlSize = reader.ReadInt32(); int kernelAccessControlOffset = reader.ReadInt32(); int kernelAccessControlSize = reader.ReadInt32(); FsAccess = new FsAccessControl(stream, offset + fsAccessControlOffset); ServiceAccess = new ServiceAccessControl(stream, offset + serviceAccessControlOffset, serviceAccessControlSize); KernelAccess = new KernelAccessControl(stream, offset + kernelAccessControlOffset, kernelAccessControlSize); }
public Result Commit(Keyset keyset) { CoreDataIvfcStorage.Flush(); FatIvfcStorage?.Flush(); Stream headerStream = BaseStorage.AsStream(); var hashData = new byte[0x3d00]; headerStream.Position = 0x300; headerStream.Read(hashData, 0, hashData.Length); var hash = new byte[Sha256.DigestSize]; Sha256.GenerateSha256Hash(hashData, hash); headerStream.Position = 0x108; headerStream.Write(hash, 0, hash.Length); if (keyset == null || keyset.SaveMacKey.IsEmpty()) { return(ResultFs.PreconditionViolation); } var cmacData = new byte[0x200]; var cmac = new byte[0x10]; headerStream.Position = 0x100; headerStream.Read(cmacData, 0, 0x200); CryptoOld.CalculateAesCmac(keyset.SaveMacKey, cmacData, 0, cmac, 0, 0x200); headerStream.Position = 0; headerStream.Write(cmac, 0, 0x10); headerStream.Flush(); return(Result.Success); }
public override Task CreateTask() { return(new Task(() => { using (Stream stream = NANDService.NAND.OpenProdInfo()) { Calibration cal0 = new Calibration(stream); HACGUIKeyset.Keyset.EticketExtKeyRsa = CryptoOld.DecryptRsaKey(cal0.EticketExtKeyRsa, HACGUIKeyset.Keyset.EticketRsaKek); } List <Ticket> tickets = new List <Ticket>(); FatFileSystemProvider system = NANDService.NAND.OpenSystemPartition(); const string e1FileName = "save\\80000000000000E1"; const string e2FileName = "save\\80000000000000E2"; if (system.FileExists(e1FileName)) { system.OpenFile(out IFile e1File, e1FileName.ToU8Span(), OpenMode.Read); IStorage e1Storage = new FileStorage(e1File); tickets.AddRange(DumpTickets(HACGUIKeyset.Keyset, e1Storage, ConsoleName)); } if (system.FileExists(e2FileName)) { system.OpenFile(out IFile e2File, e2FileName.ToU8Span(), OpenMode.Read); IStorage e2Storage = new FileStorage(e2File); tickets.AddRange(DumpTickets(HACGUIKeyset.Keyset, e2Storage, ConsoleName)); } foreach (Ticket ticket in tickets) { HACGUIKeyset.Keyset.ExternalKeySet.Add( new RightsId(ticket.RightsId), new AccessKey(ticket.GetTitleKey(HACGUIKeyset.Keyset)) ); } })); }
public byte[] GetDecryptedKey(int index) { if (index < 0 || index > 3) { throw new ArgumentOutOfRangeException(nameof(index)); } int keyRevision = Util.GetMasterKeyRevision(Header.KeyGeneration); byte[] keyAreaKey = Keyset.KeyAreaKeys[keyRevision][Header.KeyAreaKeyIndex]; if (keyAreaKey.IsEmpty()) { string keyName = $"key_area_key_{Keyset.KakNames[Header.KeyAreaKeyIndex]}_{keyRevision:x2}"; throw new MissingKeyException("Unable to decrypt NCA section.", keyName, KeyType.Common); } byte[] encryptedKey = Header.GetEncryptedKey(index).ToArray(); var decryptedKey = new byte[CryptoOld.Aes128Size]; CryptoOld.DecryptEcb(keyAreaKey, encryptedKey, decryptedKey, CryptoOld.Aes128Size); return(decryptedKey); }
private void DecryptKeys() { CryptoOld.DecryptEcb(Kek1, EncryptedKey1, DecryptedKey1, 0x10); CryptoOld.DecryptEcb(Kek2, EncryptedKey2, DecryptedKey2, 0x10); }