Exemple #1
0
        public void DeriveSdCardKeys()
        {
            var sdKek = new byte[0x10];

            GenerateKek(MasterKeys[0], SdCardKekSource, sdKek, AesKekGenerationSource, AesKeyGenerationSource);

            for (int k = 0; k < SdCardKeyIdCount; k++)
            {
                for (int i = 0; i < 0x20; i++)
                {
                    SdCardKeySourcesSpecific[k][i] = (byte)(SdCardKeySources[k][i] ^ SdSeed[i & 0xF]);
                }
            }

            for (int k = 0; k < SdCardKeyIdCount; k++)
            {
                Aes.DecryptEcb128(SdCardKeySourcesSpecific[k], SdCardKeys[k], sdKek);
            }

            // Derive sd card save key
            if (!SaveMacSdCardKekSource.IsEmpty() && !SaveMacSdCardKeySource.IsEmpty())
            {
                var keySource = new byte[0x10];

                for (int i = 0; i < 0x10; i++)
                {
                    keySource[i] = (byte)(SaveMacSdCardKeySource[i] ^ SdSeed[i]);
                }

                GenerateKek(MasterKeys[0], SaveMacSdCardKekSource, sdKek, AesKekGenerationSource, null);
                Aes.DecryptEcb128(keySource, SaveMacSdCardKey, sdKek);
            }
        }
Exemple #2
0
        private void DecryptKeyblobs(IProgressReport logger = null)
        {
            var cmac         = new byte[0x10];
            var expectedCmac = new byte[0x10];
            var counter      = new byte[0x10];

            for (int i = 0; i < UsedKeyblobCount; i++)
            {
                if (KeyblobKeys[i].IsEmpty() || KeyblobMacKeys[i].IsEmpty() || EncryptedKeyblobs[i].IsEmpty())
                {
                    continue;
                }

                Array.Copy(EncryptedKeyblobs[i], expectedCmac, 0x10);
                CryptoOld.CalculateAesCmac(KeyblobMacKeys[i], EncryptedKeyblobs[i], 0x10, cmac, 0, 0xa0);

                if (!Util.ArraysEqual(cmac, expectedCmac))
                {
                    logger?.LogMessage($"Warning: Keyblob MAC {i:x2} is invalid. Are SBK/TSEC key correct?");
                }

                Array.Copy(EncryptedKeyblobs[i], 0x10, counter, 0, 0x10);

                Aes.DecryptCtr128(EncryptedKeyblobs[i].AsSpan(0x20), Keyblobs[i], KeyblobKeys[i], counter);
            }
        }
Exemple #3
0
        private void DeriveKeyblobKeys()
        {
            if (SecureBootKey.IsEmpty() || TsecKey.IsEmpty())
            {
                return;
            }

            bool haveKeyblobMacKeySource = !MasterKeySource.IsEmpty();
            var  temp = new byte[0x10];

            for (int i = 0; i < UsedKeyblobCount; i++)
            {
                if (KeyblobKeySources[i].IsEmpty())
                {
                    continue;
                }

                Aes.DecryptEcb128(KeyblobKeySources[i], temp, TsecKey);
                Aes.DecryptEcb128(temp, KeyblobKeys[i], SecureBootKey);

                if (!haveKeyblobMacKeySource)
                {
                    continue;
                }

                Aes.DecryptEcb128(KeyblobMacKeySource, KeyblobMacKeys[i], KeyblobKeys[i]);
            }
        }
Exemple #4
0
        private void Derive620MasterKeks()
        {
            for (int i = UsedKeyblobCount; i < 0x20; i++)
            {
                if (TsecRootKeys[i - UsedKeyblobCount].IsEmpty() || MasterKekSources[i].IsEmpty())
                {
                    continue;
                }

                Aes.DecryptEcb128(MasterKekSources[i], MasterKeks[i], TsecRootKeys[i - UsedKeyblobCount]);
            }
        }
Exemple #5
0
        private void DeriveNcaHeaderKey()
        {
            if (HeaderKekSource.IsEmpty() || HeaderKeySource.IsEmpty() || MasterKeys[0].IsEmpty())
            {
                return;
            }

            var headerKek = new byte[0x10];

            GenerateKek(MasterKeys[0], HeaderKekSource, headerKek, AesKekGenerationSource,
                        AesKeyGenerationSource);
            Aes.DecryptEcb128(HeaderKeySource, HeaderKey, headerKek);
        }
Exemple #6
0
        private void DerivePerConsoleKeys()
        {
            var kek = new byte[0x10];

            // Derive the device key
            if (!PerConsoleKeySource.IsEmpty() && !KeyblobKeys[0].IsEmpty())
            {
                Aes.DecryptEcb128(PerConsoleKeySource, DeviceKey, KeyblobKeys[0]);
            }

            // Derive save key
            if (!SaveMacKekSource.IsEmpty() && !SaveMacKeySource.IsEmpty() && !DeviceKey.IsEmpty())
            {
                GenerateKek(DeviceKey, SaveMacKekSource, kek, AesKekGenerationSource, null);
                Aes.DecryptEcb128(SaveMacKeySource, SaveMacKey, kek);
            }

            // Derive BIS keys
            if (DeviceKey.IsEmpty() ||
                BisKekSource.IsEmpty() ||
                AesKekGenerationSource.IsEmpty() ||
                AesKeyGenerationSource.IsEmpty() ||
                RetailSpecificAesKeySource.IsEmpty())
            {
                return;
            }

            // If the user doesn't provide bis_key_source_03 we can assume it's the same as bis_key_source_02
            if (BisKeySource[3].IsEmpty() && !BisKeySource[2].IsEmpty())
            {
                Array.Copy(BisKeySource[2], BisKeySource[3], 0x20);
            }

            Aes.DecryptEcb128(RetailSpecificAesKeySource, kek, DeviceKey);
            if (!BisKeySource[0].IsEmpty())
            {
                Aes.DecryptEcb128(BisKeySource[0], BisKeys[0], kek);
            }

            GenerateKek(DeviceKey, BisKekSource, kek, AesKekGenerationSource, AesKeyGenerationSource);

            for (int i = 1; i < 4; i++)
            {
                if (!BisKeySource[i].IsEmpty())
                {
                    Aes.DecryptEcb128(BisKeySource[i], BisKeys[i], kek);
                }
            }
        }
Exemple #7
0
        private static void GenerateKek(ReadOnlySpan <byte> key, ReadOnlySpan <byte> src, Span <byte> dest, ReadOnlySpan <byte> kekSeed, ReadOnlySpan <byte> keySeed)
        {
            Span <byte> kek    = stackalloc byte[0x10];
            Span <byte> srcKek = stackalloc byte[0x10];

            Aes.DecryptEcb128(kekSeed, kek, key);
            Aes.DecryptEcb128(src, srcKek, kek);

            if (!keySeed.IsEmpty)
            {
                Aes.DecryptEcb128(keySeed, dest, srcKek);
            }
            else
            {
                srcKek.CopyTo(dest);
            }
        }
Exemple #8
0
        private void DeriveMasterKeys()
        {
            if (MasterKeySource.IsEmpty())
            {
                return;
            }

            for (int i = 0; i < 0x20; i++)
            {
                if (MasterKeks[i].IsEmpty())
                {
                    continue;
                }

                Aes.DecryptEcb128(MasterKeySource, MasterKeys[i], MasterKeks[i]);
            }
        }
Exemple #9
0
        private void DerivePerFirmwareKeys()
        {
            bool haveKakSource0        = !KeyAreaKeyApplicationSource.IsEmpty();
            bool haveKakSource1        = !KeyAreaKeyOceanSource.IsEmpty();
            bool haveKakSource2        = !KeyAreaKeySystemSource.IsEmpty();
            bool haveTitleKekSource    = !TitleKekSource.IsEmpty();
            bool havePackage2KeySource = !Package2KeySource.IsEmpty();

            for (int i = 0; i < 0x20; i++)
            {
                if (MasterKeys[i].IsEmpty())
                {
                    continue;
                }

                if (haveKakSource0)
                {
                    GenerateKek(MasterKeys[i], KeyAreaKeyApplicationSource, KeyAreaKeys[i][0],
                                AesKekGenerationSource, AesKeyGenerationSource);
                }

                if (haveKakSource1)
                {
                    GenerateKek(MasterKeys[i], KeyAreaKeyOceanSource, KeyAreaKeys[i][1],
                                AesKekGenerationSource, AesKeyGenerationSource);
                }

                if (haveKakSource2)
                {
                    GenerateKek(MasterKeys[i], KeyAreaKeySystemSource, KeyAreaKeys[i][2],
                                AesKekGenerationSource, AesKeyGenerationSource);
                }

                if (haveTitleKekSource)
                {
                    Aes.DecryptEcb128(TitleKekSource, TitleKeks[i], MasterKeys[i]);
                }

                if (havePackage2KeySource)
                {
                    Aes.DecryptEcb128(Package2KeySource, Package2Keys[i], MasterKeys[i]);
                }
            }
        }
Exemple #10
0
 private void DecryptKeys()
 {
     Aes.DecryptEcb128(EncryptedKey1, DecryptedKey1, Kek1);
     Aes.DecryptEcb128(EncryptedKey2, DecryptedKey2, Kek2);
 }
Exemple #11
0
 private void EncryptKeys()
 {
     Aes.EncryptEcb128(DecryptedKey1, EncryptedKey1, Kek1);
     Aes.EncryptEcb128(DecryptedKey2, EncryptedKey2, Kek2);
 }