Merge pull request #284 from LukeUsher/crypto-fixes

Implement support for real Xbox keys
This commit is contained in:
PatrickvL 2017-03-27 12:53:39 +02:00 committed by GitHub
commit eec43cf5ac
4 changed files with 85 additions and 19 deletions

View File

@ -54,6 +54,7 @@
// Options to AvSendTVEncoderOption() : // Options to AvSendTVEncoderOption() :
#define AV_OPTION_MACROVISION_MODE 1 #define AV_OPTION_MACROVISION_MODE 1
#define AV_OPTION_ENABLE_CC 2 #define AV_OPTION_ENABLE_CC 2
#define AV_OPTION_DISABLE_CC 3 #define AV_OPTION_DISABLE_CC 3
#define AV_OPTION_SEND_CC_DATA 4 #define AV_OPTION_SEND_CC_DATA 4
@ -416,6 +417,9 @@ XBSYSAPI EXPORTNUM(351) VOID NTAPI XcUpdateCrypto
OUT PCRYPTO_VECTOR pROMVector OPTIONAL OUT PCRYPTO_VECTOR pROMVector OPTIONAL
); );
// Not exported by the kernel, but required to generate other keys
XBSYSAPI XBOX_KEY_DATA XboxCertificateKey;
// ****************************************************************** // ******************************************************************
// * 0x0161 - XboxLANKey // * 0x0161 - XboxLANKey
// ****************************************************************** // ******************************************************************
@ -424,7 +428,7 @@ XBSYSAPI EXPORTNUM(353) XBOX_KEY_DATA XboxLANKey;
// ****************************************************************** // ******************************************************************
// * 0x0162 - XboxAlternateSignatureKeys // * 0x0162 - XboxAlternateSignatureKeys
// ****************************************************************** // ******************************************************************
XBSYSAPI EXPORTNUM(354) XBOX_KEY_DATA XboxAlternateSignatureKeys; XBSYSAPI EXPORTNUM(354) XBOX_KEY_DATA XboxAlternateSignatureKeys[ALTERNATE_SIGNATURE_COUNT];
// ****************************************************************** // ******************************************************************
// * 0x0163 - XePublicKeyData // * 0x0163 - XePublicKeyData

View File

@ -2071,6 +2071,7 @@ typedef struct _XBOX_HARDWARE_INFO
XBOX_HARDWARE_INFO; XBOX_HARDWARE_INFO;
const int XBOX_KEY_LENGTH = 16; const int XBOX_KEY_LENGTH = 16;
const int ALTERNATE_SIGNATURE_COUNT = 16;
typedef UCHAR XBOX_KEY_DATA[XBOX_KEY_LENGTH]; typedef UCHAR XBOX_KEY_DATA[XBOX_KEY_LENGTH];
// ****************************************************************** // ******************************************************************

View File

@ -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 < 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);
}
}
void CxbxLaunchXbe(void(*Entry)()) void CxbxLaunchXbe(void(*Entry)())
{ {
__try __try
@ -477,6 +499,40 @@ void CxbxKrnlMain(int argc, char* argv[])
} }
#pragma optimize("", on) #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);
} 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 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");
}
void CxbxKrnlInit void CxbxKrnlInit
( (
HWND hwndParent, HWND hwndParent,
@ -604,6 +660,10 @@ void CxbxKrnlInit
strcat(szBuffer, "\\Cxbx-Reloaded\\"); strcat(szBuffer, "\\Cxbx-Reloaded\\");
std::string basePath(szBuffer); std::string basePath(szBuffer);
CxbxBasePath = basePath + "EmuDisk\\"; CxbxBasePath = basePath + "EmuDisk\\";
// Load Per-Xbe Keys from the Cxbx-Reloaded AppData directory
LoadXboxKeys(szBuffer);
// Determine XBE Path // Determine XBE Path
memset(szBuffer, 0, MAX_PATH); memset(szBuffer, 0, MAX_PATH);
g_EmuShared->GetXbePath(szBuffer); g_EmuShared->GetXbePath(szBuffer);
@ -713,6 +773,9 @@ void CxbxKrnlInit
// See: https://multimedia.cx/eggs/xbox-sphinx-protocol/ // See: https://multimedia.cx/eggs/xbox-sphinx-protocol/
ApplyMediaPatches(); ApplyMediaPatches();
// Setup per-title encryption keys
SetupPerTitleKeys();
// initialize FS segment selector // initialize FS segment selector
{ {
EmuInitFS(); EmuInitFS();

View File

@ -43,11 +43,15 @@ namespace xboxkrnl
#include <xboxkrnl/xboxkrnl.h> // For XboxEEPROMKey, etc. #include <xboxkrnl/xboxkrnl.h> // For XboxEEPROMKey, etc.
}; };
// Certificate Key
// Not exported but used to generate per-title keys
xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxCertificateKey = { 0 };
// ****************************************************************** // ******************************************************************
// * 0x0141 - XboxEEPROMKey // * 0x0141 - XboxEEPROMKey
// ****************************************************************** // ******************************************************************
// TODO : What should we initialize this to? // 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 // * 0x0142 - XboxHardwareInfo
@ -61,13 +65,7 @@ XBSYSAPI EXPORTNUM(322) xboxkrnl::XBOX_HARDWARE_INFO xboxkrnl::XboxHardwareInfo
// ****************************************************************** // ******************************************************************
// * 0x0143 - XboxHDKey // * 0x0143 - XboxHDKey
// ****************************************************************** // ******************************************************************
XBSYSAPI EXPORTNUM(323) xboxkrnl::UCHAR xboxkrnl::XboxHDKey[16] = XBSYSAPI EXPORTNUM(323) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxHDKey = { 0 };
{
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
// ****************************************************************** // ******************************************************************
// * 0x0144 - XboxKrnlVersion // * 0x0144 - XboxKrnlVersion
@ -81,23 +79,23 @@ XBSYSAPI EXPORTNUM(324) xboxkrnl::XBOX_KRNL_VERSION xboxkrnl::XboxKrnlVersion =
// ****************************************************************** // ******************************************************************
// * 0x0145 - XboxSignatureKey // * 0x0145 - XboxSignatureKey
// Generated in SetupPerTitleKeys() using the Certificate Key and the
// XBE's Signature Key
// ****************************************************************** // ******************************************************************
XBSYSAPI EXPORTNUM(325) xboxkrnl::BYTE xboxkrnl::XboxSignatureKey[16] = XBSYSAPI EXPORTNUM(325) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxSignatureKey = { 0 };
{
// cxbx default saved game key
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
// ****************************************************************** // ******************************************************************
// * 0x0161 - XboxLANKey // * 0x0161 - XboxLANKey
// Generated in SetupPerTitleKeys() 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 = { 0 };
XBSYSAPI EXPORTNUM(353) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxLANKey = {};
// ****************************************************************** // ******************************************************************
// * 0x0162 - XboxAlternateSignatureKeys // * 0x0162 - XboxAlternateSignatureKeys
// Generated in SetupPerTitleKeys() using the Certificate Key and the
// XBE's Alternate Signature Keys Key
// ****************************************************************** // ******************************************************************
// TODO : What should we initialize this to? XBSYSAPI EXPORTNUM(354) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxAlternateSignatureKeys[ALTERNATE_SIGNATURE_COUNT] = { 0 };
XBSYSAPI EXPORTNUM(354) xboxkrnl::XBOX_KEY_DATA xboxkrnl::XboxAlternateSignatureKeys = {};