-
-
Notifications
You must be signed in to change notification settings - Fork 289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement XDVD security challenge responses #1659
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, nice work! Left some initial comments.
#ifdef XBOX | ||
// We need to prevent small XISOs from being reported as CD-ROMs | ||
// If the DVD security path is set, we can assume it is an XISO. | ||
const char *dvd_security_path = g_config.sys.files.dvd_security_path; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably make this a qdev property, like disc file path, media type, etc. so it can play nicely with other systems
@@ -457,6 +461,11 @@ struct IDEState { | |||
uint8_t *smart_selftest_data; | |||
/* AHCI */ | |||
int ncq_queues; | |||
#ifdef XBOX | |||
uint8_t xdvd_challenges_encrypted[XDVD_STRUCTURE_LEN]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do any of these fields need to be saved in vm state to support snapshots?
|
||
bool xdvd_is_redump(uint64_t total_sectors) | ||
{ | ||
return total_sectors == XDVD_REDUMP_SECTOR_CNT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible for this to misclassify if a non-redump image happens to be this same size?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Youre right it would be technically possible; although I dont think any retail xbox title in XISO format could possibly have this size but maybe some homebrew could have.
Any suggestions? I presume there is some magic bytes in the redump style image somewhere, Id need to research it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to check the volume descriptor magic fields at the appropriate offset: https://xboxdevwiki.net/XDVDFS#Volume_descriptor
hw/xbox/xdvd/xdvd.c
Outdated
bool xdvd_get_encrypted_challenge_table(uint8_t *xdvd_challenge_table_encrypted) | ||
{ | ||
bool status = true; | ||
// Check if we have already read it from the file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this checked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the comment. Left over from old code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few code review remarks
@@ -1206,8 +1338,12 @@ static void cmd_read_dvd_structure(IDEState *s, uint8_t* buf) | |||
} | |||
} | |||
|
|||
// Still some important info we don't want to lose so we disable clearing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is one of the few "not defined" conditionals, it's perhaps nicer to change it into an #ifdef XBOX
then the comment lines, and then an #else
line before the code that has to be skipped under an Xbox build.
#endif | ||
|
||
// #define DEBUG | ||
#ifdef DEBUG |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be moved inside the above #ifdef XBOX
conditional block.
|
||
ide_atapi_cmd_reply(s, sizeof(XBOX_DVD_SECURITY), max_len); | ||
#endif | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This break
must reside in the above conditional block, not after it.
|
||
bool xdvd_get_encrypted_challenge_table(uint8_t *xdvd_challenge_table_encrypted) | ||
{ | ||
bool status = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either move this variable declaration down to reside along with the others below (since it's not referred to until after those), or (if this project still requires all variable declarations to reside at the start of a function) move all below variable declarations towards here.
(PXBOX_DVD_CHALLENGE)(&xdvd_challenge_table_decrypted[CR_ENTRIES_OFFSET]); | ||
|
||
for (int i = 0; i < challengeEntryCount; i++) { | ||
if (challenges[i].type != 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- We should name this constant. Supposedly 1 means the entry is valid.
- nit: Braces around condition body, same with below
memcpy(xdvd_security, &s, sizeof(s)); | ||
}; | ||
|
||
bool xdvd_is_redump(uint64_t total_sectors) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to avoid using the term "redump" in xemu code. Although we use the term informally to mean a complete disc backup, it really is just the name of the metadata archival project and not tied directly to the layout of the disc image. So instead of using the term redump here, let's use something like xdvd_has_video_partition
.
if (max_len == XDVD_SECURITY_PAGE_LEN && buf[8] == MODE_PAGE_XBOX_SECURITY) | ||
{ | ||
memcpy(&s->xdvd_security, buf, XDVD_SECURITY_PAGE_LEN); | ||
XBOX_DPRINTF("Authenticated: %d, Partition: %d\n", s->xdvd_security.page.Authenticated, s->xdvd_security.page.Partition); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that the drive requires the full unlock challenge-response sequence to happen before it will unlock and we are not yet fully modeling this state machine. If this is correct and you don't plan to implement this, can you leave a comment so we can remember to come back to it?
uint32_t xdvd_get_challenge_response(const uint8_t *xdvd_challenge_table_decrypted, | ||
uint8_t challenge_id) | ||
{ | ||
int challengeEntryCount = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: challenge_entry_count
This PR implements the DVD security challenge/response mechanism to the best of my knowledge used on a Xbox console between the DVD drive and the Xbox.
This allows loading retail Xbox titles both in 'redump' format and xiso format with an unmodified retail BIOS.
For this to work, you need the security info from your original game disk. There is two methods:
SS.bin
from a compatible 'Kreon' drive using the method on redump.org http://wiki.redump.org/index.php?title=Microsoft_Xbox_and_Xbox_360_Dumping_Guide,dvd_layout.bin
from your Xbox and original disk using these homebrew apps https://github.com/Ryzee119/OGX_CHALLENGE_TABLE/releases/tag/build-202310141001 or https://gist.github.com/Ernegien/bef054a43213c52c2bef8d94bf9f51cbThese two dumps have the same info but in a slightly different format. As I understand
SS.bin
represents what is physically on the DVD,dvd_layout.bin
is the packet that is formatted and sent by the DVD drive firmware. This PR detects either and converts accordingly.To provide this file to xemu, there is currently no GUI element and is done by command line
xemu.exe -dvd_security_path "SS.bin"
. The same arg is used for"dvd_layout.bin"
.Notes from my testing:
References
This process just follows the text book challenge response process from the Xbox. There may be some unusual aspects that are missed and I only have a smallish selection of disks to test with. I pulled in some public domain RC4 and SHA1 libraries, not sure if they should live in the xdvd folder or not.
Future work suggestions
Fixes #1036