Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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))
                        );
                }
            }));
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
 private void DecryptKeys()
 {
     CryptoOld.DecryptEcb(Kek1, EncryptedKey1, DecryptedKey1, 0x10);
     CryptoOld.DecryptEcb(Kek2, EncryptedKey2, DecryptedKey2, 0x10);
 }