From 856e1ba873a6c17774a47579064e78ffcba48845 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Sun, 26 Mar 2017 22:56:17 +0100 Subject: [PATCH 1/3] Implement support for real Xbox keys --- import/OpenXDK/include/xboxkrnl/xbox.h | 8 +++- src/CxbxKrnl/CxbxKrnl.cpp | 61 ++++++++++++++++++++++++++ src/CxbxKrnl/EmuKrnlXbox.cpp | 34 +++++++------- 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/import/OpenXDK/include/xboxkrnl/xbox.h b/import/OpenXDK/include/xboxkrnl/xbox.h index 3272691e7..0e8ab8273 100644 --- a/import/OpenXDK/include/xboxkrnl/xbox.h +++ b/import/OpenXDK/include/xboxkrnl/xbox.h @@ -54,6 +54,7 @@ // Options to AvSendTVEncoderOption() : #define AV_OPTION_MACROVISION_MODE 1 + #define AV_OPTION_ENABLE_CC 2 #define AV_OPTION_DISABLE_CC 3 #define AV_OPTION_SEND_CC_DATA 4 @@ -416,6 +417,9 @@ XBSYSAPI EXPORTNUM(351) VOID NTAPI XcUpdateCrypto OUT PCRYPTO_VECTOR pROMVector OPTIONAL ); +// Not exported by the kernel, but required to generate other keys +XBSYSAPI XBOX_KEY_DATA XboxCertificateKey; + // ****************************************************************** // * 0x0161 - XboxLANKey // ****************************************************************** @@ -424,11 +428,11 @@ XBSYSAPI EXPORTNUM(353) XBOX_KEY_DATA XboxLANKey; // ****************************************************************** // * 0x0162 - XboxAlternateSignatureKeys // ****************************************************************** -XBSYSAPI EXPORTNUM(354) XBOX_KEY_DATA XboxAlternateSignatureKeys; +XBSYSAPI EXPORTNUM(354) XBOX_KEY_DATA XboxAlternateSignatureKeys[16]; // ****************************************************************** // * 0x0163 - XePublicKeyData -// ****************************************************************** +// ****************1************************************************** XBSYSAPI EXPORTNUM(355) DWORD XePublicKeyData; // ****************************************************************** diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index b414306a7..0c2be1b72 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -163,6 +163,28 @@ void ApplyMediaPatches() } +void SetupPerTitleKeys() +{ + // Generate per-title keys from the XBE Certificate + Xbe::Certificate *pCertificate = (Xbe::Certificate*)CxbxKrnl_XbeHeader->dwCertificateAddr; + UCHAR Digest[20] = {}; + + // Set the LAN Key + xboxkrnl::XcHMAC(xboxkrnl::XboxCertificateKey, xboxkrnl::XBOX_KEY_LENGTH, pCertificate->bzLanKey, xboxkrnl::XBOX_KEY_LENGTH, NULL, 0, Digest); + memcpy(xboxkrnl::XboxLANKey, Digest, xboxkrnl::XBOX_KEY_LENGTH); + + // Signature Key + xboxkrnl::XcHMAC(xboxkrnl::XboxCertificateKey, xboxkrnl::XBOX_KEY_LENGTH, pCertificate->bzSignatureKey, xboxkrnl::XBOX_KEY_LENGTH, NULL, 0, Digest); + memcpy(xboxkrnl::XboxSignatureKey, Digest, xboxkrnl::XBOX_KEY_LENGTH); + + // Alternate Signature Keys + for (int i = 0; i < 16; i++) { + xboxkrnl::XcHMAC(xboxkrnl::XboxCertificateKey, xboxkrnl::XBOX_KEY_LENGTH, pCertificate->bzTitleAlternateSignatureKey[i], xboxkrnl::XBOX_KEY_LENGTH, NULL, 0, Digest); + memcpy(xboxkrnl::XboxAlternateSignatureKeys[i], Digest, xboxkrnl::XBOX_KEY_LENGTH); + } + +} + void CxbxLaunchXbe(void(*Entry)()) { __try @@ -477,6 +499,38 @@ void CxbxKrnlMain(int argc, char* argv[]) } #pragma optimize("", on) +// Loads a keys.bin file as generated by dump-xbox +// See https://github.com/JayFoxRox/xqemu-tools/blob/master/dump-xbox.c +void LoadXboxKeys(std::string path) +{ + std::string keys_path = path + "\\keys.bin"; + + // Attempt to open Keys.bin + FILE* fp = fopen(keys_path.c_str(), "rb"); + + if (fp != nullptr) { + // Determine size of Keys.bin + xboxkrnl::XBOX_KEY_DATA keys[2]; + fseek(fp, 0, SEEK_END); + long size = ftell(fp); + rewind(fp); + + // If the size of Keys.bin is correct (two keys), read it + if (size == xboxkrnl::XBOX_KEY_LENGTH * 2) { + fread(keys, xboxkrnl::XBOX_KEY_LENGTH, 2, fp); + + memcpy(xboxkrnl::XboxEEPROMKey, &keys[0], xboxkrnl::XBOX_KEY_LENGTH); + memcpy(xboxkrnl::XboxCertificateKey, &keys[1], xboxkrnl::XBOX_KEY_LENGTH); + } + + fclose(fp); + return; + } + + // If we didn't already exist the function, keys.bin could not be loaded + EmuWarning("Failed to load Keys.bin. Cxbx-Reloaded will be unable to read Save Data from a real Xbox"); +} + void CxbxKrnlInit ( HWND hwndParent, @@ -604,6 +658,10 @@ void CxbxKrnlInit strcat(szBuffer, "\\Cxbx-Reloaded\\"); std::string basePath(szBuffer); CxbxBasePath = basePath + "EmuDisk\\"; + + // Load Per-Xbe Keys from the Cxbx-Reloaded AppData directory + LoadXboxKeys(szBuffer); + // Determine XBE Path memset(szBuffer, 0, MAX_PATH); g_EmuShared->GetXbePath(szBuffer); @@ -713,6 +771,9 @@ void CxbxKrnlInit // See: https://multimedia.cx/eggs/xbox-sphinx-protocol/ ApplyMediaPatches(); + // Setup per-title encryption keys + SetupPerTitleKeys(); + // initialize FS segment selector { EmuInitFS(); diff --git a/src/CxbxKrnl/EmuKrnlXbox.cpp b/src/CxbxKrnl/EmuKrnlXbox.cpp index 792b4c885..eb9401099 100644 --- a/src/CxbxKrnl/EmuKrnlXbox.cpp +++ b/src/CxbxKrnl/EmuKrnlXbox.cpp @@ -43,11 +43,15 @@ namespace xboxkrnl #include // For XboxEEPROMKey, etc. }; +// Certificate Key +// Not exported but used to generate per-title keys +xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxCertificateKey = { 0 }; + // ****************************************************************** // * 0x0141 - XboxEEPROMKey // ****************************************************************** // TODO : What should we initialize this to? -XBSYSAPI EXPORTNUM(321) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxEEPROMKey = {}; +XBSYSAPI EXPORTNUM(321) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxEEPROMKey = { 0 }; // ****************************************************************** // * 0x0142 - XboxHardwareInfo @@ -61,13 +65,7 @@ XBSYSAPI EXPORTNUM(322) xboxkrnl::XBOX_HARDWARE_INFO xboxkrnl::XboxHardwareInfo // ****************************************************************** // * 0x0143 - XboxHDKey // ****************************************************************** -XBSYSAPI EXPORTNUM(323) xboxkrnl::UCHAR xboxkrnl::XboxHDKey[16] = -{ - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, -}; +XBSYSAPI EXPORTNUM(323) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxHDKey = { 0 }; // ****************************************************************** // * 0x0144 - XboxKrnlVersion @@ -81,23 +79,23 @@ XBSYSAPI EXPORTNUM(324) xboxkrnl::XBOX_KRNL_VERSION xboxkrnl::XboxKrnlVersion = // ****************************************************************** // * 0x0145 - XboxSignatureKey +// Generated programatically using the Certificate Key and the XBE's +// Signature Key // ****************************************************************** -XBSYSAPI EXPORTNUM(325) xboxkrnl::BYTE xboxkrnl::XboxSignatureKey[16] = -{ - // cxbx default saved game key - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; +XBSYSAPI EXPORTNUM(325) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxSignatureKey = { 0 }; // ****************************************************************** // * 0x0161 - XboxLANKey +// Generated programatically using the Certificate Key and the XBE's +// LAN Key // ****************************************************************** -// TODO : What should we initialize this to? -XBSYSAPI EXPORTNUM(353) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxLANKey = {}; +XBSYSAPI EXPORTNUM(353) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxLANKey = { 0 }; // ****************************************************************** // * 0x0162 - XboxAlternateSignatureKeys +// Generated programatically using the Certificate Key and the XBE's +// Signature Keys // ****************************************************************** -// TODO : What should we initialize this to? -XBSYSAPI EXPORTNUM(354) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxAlternateSignatureKeys = {}; +XBSYSAPI EXPORTNUM(354) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxAlternateSignatureKeys[16] = { 0 }; + \ No newline at end of file From aff8808fbc64357b30ddc14957ed38804a2bca21 Mon Sep 17 00:00:00 2001 From: PatrickvL Date: Mon, 27 Mar 2017 11:16:08 +0200 Subject: [PATCH 2/3] Update xbox.h --- import/OpenXDK/include/xboxkrnl/xbox.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/import/OpenXDK/include/xboxkrnl/xbox.h b/import/OpenXDK/include/xboxkrnl/xbox.h index 0e8ab8273..7215c0079 100644 --- a/import/OpenXDK/include/xboxkrnl/xbox.h +++ b/import/OpenXDK/include/xboxkrnl/xbox.h @@ -432,7 +432,7 @@ XBSYSAPI EXPORTNUM(354) XBOX_KEY_DATA XboxAlternateSignatureKeys[16]; // ****************************************************************** // * 0x0163 - XePublicKeyData -// ****************1************************************************** +// ****************************************************************** XBSYSAPI EXPORTNUM(355) DWORD XePublicKeyData; // ****************************************************************** From cd41fcd6ec2d8dff3e9c024fc4d307711410af28 Mon Sep 17 00:00:00 2001 From: Luke Usher Date: Mon, 27 Mar 2017 11:38:39 +0100 Subject: [PATCH 3/3] Amendments --- import/OpenXDK/include/xboxkrnl/xbox.h | 2 +- import/OpenXDK/include/xboxkrnl/xboxkrnl.h | 1 + src/CxbxKrnl/CxbxKrnl.cpp | 6 ++++-- src/CxbxKrnl/EmuKrnlXbox.cpp | 14 +++++++------- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/import/OpenXDK/include/xboxkrnl/xbox.h b/import/OpenXDK/include/xboxkrnl/xbox.h index 0e8ab8273..ae67a30b4 100644 --- a/import/OpenXDK/include/xboxkrnl/xbox.h +++ b/import/OpenXDK/include/xboxkrnl/xbox.h @@ -428,7 +428,7 @@ XBSYSAPI EXPORTNUM(353) XBOX_KEY_DATA XboxLANKey; // ****************************************************************** // * 0x0162 - XboxAlternateSignatureKeys // ****************************************************************** -XBSYSAPI EXPORTNUM(354) XBOX_KEY_DATA XboxAlternateSignatureKeys[16]; +XBSYSAPI EXPORTNUM(354) XBOX_KEY_DATA XboxAlternateSignatureKeys[ALTERNATE_SIGNATURE_COUNT]; // ****************************************************************** // * 0x0163 - XePublicKeyData diff --git a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h index 28a8d8e7f..b339871a2 100644 --- a/import/OpenXDK/include/xboxkrnl/xboxkrnl.h +++ b/import/OpenXDK/include/xboxkrnl/xboxkrnl.h @@ -2071,6 +2071,7 @@ typedef struct _XBOX_HARDWARE_INFO XBOX_HARDWARE_INFO; const int XBOX_KEY_LENGTH = 16; +const int ALTERNATE_SIGNATURE_COUNT = 16; typedef UCHAR XBOX_KEY_DATA[XBOX_KEY_LENGTH]; // ****************************************************************** diff --git a/src/CxbxKrnl/CxbxKrnl.cpp b/src/CxbxKrnl/CxbxKrnl.cpp index 0c2be1b72..8b64f10c8 100644 --- a/src/CxbxKrnl/CxbxKrnl.cpp +++ b/src/CxbxKrnl/CxbxKrnl.cpp @@ -178,7 +178,7 @@ void SetupPerTitleKeys() memcpy(xboxkrnl::XboxSignatureKey, Digest, xboxkrnl::XBOX_KEY_LENGTH); // Alternate Signature Keys - for (int i = 0; i < 16; i++) { + for (int i = 0; i < xboxkrnl::ALTERNATE_SIGNATURE_COUNT; i++) { xboxkrnl::XcHMAC(xboxkrnl::XboxCertificateKey, xboxkrnl::XBOX_KEY_LENGTH, pCertificate->bzTitleAlternateSignatureKey[i], xboxkrnl::XBOX_KEY_LENGTH, NULL, 0, Digest); memcpy(xboxkrnl::XboxAlternateSignatureKeys[i], Digest, xboxkrnl::XBOX_KEY_LENGTH); } @@ -521,13 +521,15 @@ void LoadXboxKeys(std::string path) memcpy(xboxkrnl::XboxEEPROMKey, &keys[0], xboxkrnl::XBOX_KEY_LENGTH); memcpy(xboxkrnl::XboxCertificateKey, &keys[1], xboxkrnl::XBOX_KEY_LENGTH); + } else { + EmuWarning("Keys.bin has an incorrent filesize. Should be %d bytes", xboxkrnl::XBOX_KEY_LENGTH * 2); } fclose(fp); return; } - // If we didn't already exist the function, keys.bin could not be loaded + // If we didn't already exit the function, keys.bin could not be loaded EmuWarning("Failed to load Keys.bin. Cxbx-Reloaded will be unable to read Save Data from a real Xbox"); } diff --git a/src/CxbxKrnl/EmuKrnlXbox.cpp b/src/CxbxKrnl/EmuKrnlXbox.cpp index eb9401099..4ada8048c 100644 --- a/src/CxbxKrnl/EmuKrnlXbox.cpp +++ b/src/CxbxKrnl/EmuKrnlXbox.cpp @@ -79,23 +79,23 @@ XBSYSAPI EXPORTNUM(324) xboxkrnl::XBOX_KRNL_VERSION xboxkrnl::XboxKrnlVersion = // ****************************************************************** // * 0x0145 - XboxSignatureKey -// Generated programatically using the Certificate Key and the XBE's -// Signature Key +// Generated in SetupPerTitleKeys() using the Certificate Key and the +// XBE's Signature Key // ****************************************************************** XBSYSAPI EXPORTNUM(325) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxSignatureKey = { 0 }; // ****************************************************************** // * 0x0161 - XboxLANKey -// Generated programatically using the Certificate Key and the XBE's -// LAN Key +// Generated in SetupPerTitleKeys() using the Certificate Key and the +// XBE's LAN Key // ****************************************************************** XBSYSAPI EXPORTNUM(353) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxLANKey = { 0 }; // ****************************************************************** // * 0x0162 - XboxAlternateSignatureKeys -// Generated programatically using the Certificate Key and the XBE's -// Signature Keys +// Generated in SetupPerTitleKeys() using the Certificate Key and the +// XBE's Alternate Signature Keys Key // ****************************************************************** -XBSYSAPI EXPORTNUM(354) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxAlternateSignatureKeys[16] = { 0 }; +XBSYSAPI EXPORTNUM(354) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxAlternateSignatureKeys[ALTERNATE_SIGNATURE_COUNT] = { 0 }; \ No newline at end of file