public void DeriveSdCardKeys() { var sdKek = new byte[0x10]; Crypto.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++) { Crypto.DecryptEcb(sdKek, SdCardKeySourcesSpecific[k], SdCardKeys[k], 0x20); } // 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]); } Crypto.GenerateKek(MasterKeys[0], SaveMacSdCardKekSource, sdKek, AesKekGenerationSource, null); Crypto.DecryptEcb(sdKek, keySource, SaveMacSdCardKey, 0x10); } }
private void DeriveNcaHeaderKey() { if (HeaderKekSource.IsEmpty() || HeaderKeySource.IsEmpty() || MasterKeys[0].IsEmpty()) { return; } var headerKek = new byte[0x10]; Crypto.GenerateKek(MasterKeys[0], HeaderKekSource, headerKek, AesKekGenerationSource, AesKeyGenerationSource); Crypto.DecryptEcb(headerKek, HeaderKeySource, HeaderKey, 0x20); }
private void DerivePerConsoleKeys() { var kek = new byte[0x10]; // Derive the device key if (!PerConsoleKeySource.IsEmpty() && !KeyblobKeys[0].IsEmpty()) { Crypto.DecryptEcb(KeyblobKeys[0], PerConsoleKeySource, DeviceKey, 0x10); } // Derive save key if (!SaveMacKekSource.IsEmpty() && !SaveMacKeySource.IsEmpty() && !DeviceKey.IsEmpty()) { Crypto.GenerateKek(DeviceKey, SaveMacKekSource, kek, AesKekGenerationSource, null); Crypto.DecryptEcb(kek, SaveMacKeySource, SaveMacKey, 0x10); } // 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); } Crypto.DecryptEcb(DeviceKey, RetailSpecificAesKeySource, kek, 0x10); if (!BisKeySource[0].IsEmpty()) { Crypto.DecryptEcb(kek, BisKeySource[0], BisKeys[0], 0x20); } Crypto.GenerateKek(DeviceKey, BisKekSource, kek, AesKekGenerationSource, AesKeyGenerationSource); for (int i = 1; i < 4; i++) { if (!BisKeySource[i].IsEmpty()) { Crypto.DecryptEcb(kek, BisKeySource[i], BisKeys[i], 0x20); } } }
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) { Crypto.GenerateKek(MasterKeys[i], KeyAreaKeyApplicationSource, KeyAreaKeys[i][0], AesKekGenerationSource, AesKeyGenerationSource); } if (haveKakSource1) { Crypto.GenerateKek(MasterKeys[i], KeyAreaKeyOceanSource, KeyAreaKeys[i][1], AesKekGenerationSource, AesKeyGenerationSource); } if (haveKakSource2) { Crypto.GenerateKek(MasterKeys[i], KeyAreaKeySystemSource, KeyAreaKeys[i][2], AesKekGenerationSource, AesKeyGenerationSource); } if (haveTitleKekSource) { Crypto.DecryptEcb(MasterKeys[i], TitleKekSource, TitleKeks[i], 0x10); } if (havePackage2KeySource) { Crypto.DecryptEcb(MasterKeys[i], Package2KeySource, Package2Keys[i], 0x10); } } }
public void DeriveSdCardKeys() { var sdKek = new byte[0x10]; Crypto.GenerateKek(MasterKeys[0], SdCardKekSource, sdKek, AesKekGenerationSource, AesKeyGenerationSource); for (int k = 0; k < SdCardKeySources.Length; k++) { for (int i = 0; i < 0x20; i++) { SdCardKeySourcesSpecific[k][i] = (byte)(SdCardKeySources[k][i] ^ SdSeed[i & 0xF]); } } for (int k = 0; k < SdCardKeySourcesSpecific.Length; k++) { Crypto.DecryptEcb(sdKek, SdCardKeySourcesSpecific[k], SdCardKeys[k], 0x20); } }
private void DerivePerConsoleKeys() { var kek = new byte[0x10]; // Derive the device key if (!PerConsoleKeySource.IsEmpty() && !KeyblobKeys[0].IsEmpty()) { Crypto.DecryptEcb(KeyblobKeys[0], PerConsoleKeySource, DeviceKey, 0x10); } // Derive save key if (!SaveMacKekSource.IsEmpty() && !SaveMacKeySource.IsEmpty() && !DeviceKey.IsEmpty()) { Crypto.GenerateKek(DeviceKey, SaveMacKekSource, kek, AesKekGenerationSource, null); Crypto.DecryptEcb(kek, SaveMacKeySource, SaveMacKey, 0x10); } // Derive BIS keys if (DeviceKey.IsEmpty() || BisKeySource[0].IsEmpty() || BisKeySource[1].IsEmpty() || BisKeySource[2].IsEmpty() || BisKekSource.IsEmpty() || AesKekGenerationSource.IsEmpty() || AesKeyGenerationSource.IsEmpty() || RetailSpecificAesKeySource.IsEmpty()) { return; } Crypto.DecryptEcb(DeviceKey, RetailSpecificAesKeySource, kek, 0x10); Crypto.DecryptEcb(kek, BisKeySource[0], BisKeys[0], 0x20); Crypto.GenerateKek(DeviceKey, BisKekSource, kek, AesKekGenerationSource, AesKeyGenerationSource); Crypto.DecryptEcb(kek, BisKeySource[1], BisKeys[1], 0x20); Crypto.DecryptEcb(kek, BisKeySource[2], BisKeys[2], 0x20); // BIS keys 2 and 3 are the same Array.Copy(BisKeys[2], BisKeys[3], 0x20); }