Editing BD Drive Reverse Engineering

Jump to navigation Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.

Latest revision Your text
Line 14: Line 14:


* I modified sv_iso_spu_module.self to dump EID4 IV and key.
* I modified sv_iso_spu_module.self to dump EID4 IV and key.
* I used my spuisofs Linux kernel module and the below SPU program to dump EID4 IV key on PS3 Linux.
* I used spuisofs kernel module and the below SPU program to dump EID4 IV key.
* After dumping EID4 key use CMAC-OMAC1 algorithm to check the CMAC of EID4. If the EID4 key you got is correct then the CMAC should match.
* After dumping EID4 key use CMAC-OMAC1 algorithm to check the CMAC of EID4. If the EID4 key you got is correct then the CMAC should match.
* dump_eid4_key.tar.gz: http://www.multiupload.nl/6AM6B6P05B
==SPU Program==


My program to dump EID4 AES-CBC-256 IV and key to PPU memory:
My program to dump EID4 AES-CBC-256 IV and key to PPU memory:


<syntaxhighlight lang="asm">
<pre>
/*
/*
  * Dump EID4 IV and key to EA with MFC
  * Dump EID4 IV and key to EA with MFC
Line 127: Line 124:


bi $lr
bi $lr
</syntaxhighlight>
==Result==
* Test run with spuisofs.
<pre>
[glevand@arch dump_eid4_key]$ ./dump_eid4_key ../dump_eid4_key.self ../eid4
spuisofs found at /mnt
arg1 kernel virtual address d000000000722000
shadow: spe_execution_status 7
priv2: puint_mb_R 2
shadow: spe_execution_status b
problem: spu_status_R 6660082
[glevand@arch dump_eid4_key]$ hexdump -C /mnt/arg1
...
Here should be your EID4 IV and key
IV is at offset 0x10 (16 bytes)
Key is at offset 0x20 (32 bytes)
...
</pre>
</pre>


Line 155: Line 132:
* ATAPI commands SEND_KEY and REPORT_KEY are used to exchange random number between host and BD drive.
* ATAPI commands SEND_KEY and REPORT_KEY are used to exchange random number between host and BD drive.
* Exchanged random numbers are used to derive the session key which is used later to send vendor-specific ATAPI commands (0xE0 and 0xE1) to BD drive.
* Exchanged random numbers are used to derive the session key which is used later to send vendor-specific ATAPI commands (0xE0 and 0xE1) to BD drive.
* The same procedue is followed e.g. by Storage Manager which runs in LPAR1.
* The same procedue is follwed e.g. by Storage Manager which runs in LPAR1.
* 3DES-CBC with 2 keys is used to encrypt commands sent to BD drive.
* 3DES-CBC with 2 keys is used to encrypt commands sent to BD drive.


Line 168: Line 145:
* The program uses Linux SCSI Generic driver to send ATAPI commands to BD drive.
* The program uses Linux SCSI Generic driver to send ATAPI commands to BD drive.


==Program==
<pre>
 
<syntaxhighlight lang="c">
/*-
/*-
  * Copyright (C) 2012 glevand <[email protected]>
  * Copyright (C) 2012 glevand <[email protected]>
Line 1,083: Line 1,058:
exit(0);
exit(0);
}
}
</syntaxhighlight>
==Result==
* Test run on Linux 3.5.1
<pre>
glevand@debian:~$ sudo ./bd_get_version -k <EID4 key1> -l <EID4 key2>
TEST UNIT READY failed: status 2 host status 0 driver status 8
sense buffer: 70 00 02 00 00 00 00 0a 00 00 00 00 3a 00 00 00
rnd1: 06 d7 33 cb 22 4a 83 56 a3 e8 39 78 66 e4 3e c2
rnd2: e3 20 f2 41 21 c4 0b 1a ca 1d 43 bf 8b 6a 5d 58
key7: dd ec 54 ea 6d 34 78 04 6c 97 f0 3b ee f1 31 cd
key8: a6 b4 6c 56 05 e7 72 e8 b1 8b b0 8a 5b 67 ba 1b
rnd1: 06 d7 33 cb 22 4a 83 56 a3 e8 39 78 66 e4 3e c2
rnd2: 0a 97 a0 62 c3 93 21 1b c0 bc f2 02 e9 af df 76
key7: 72 1a 5d a2 80 d9 e0 f8 66 8e ec 86 7e ef ab c2
key8: 9c e9 d8 f0 ee c4 89 fc 0d 62 f3 37 eb c8 8b bd
version: 00 03 00 50 00 00 00 00
</pre>
=Clean Key=
TODO
=Set Key=
TODO
=Buffers=
{|class="wikitable"
|-
! ID !! Size !! Description
|-
| 0 || 0x800 ||
|-
| 1 || 0x800 || Serial Flash
|-
| 2 || 0x60 || P-Block
|-
| 3 || 0x670 || S-Block
|-
| 4 || 0x8000 || Empty AACS HRL 
|-
| 5 || 0x8000 || Current AACS HRL
|}
=Inquiry GameOS=
* Here is my code for a simple program to send the ATAPI command 0x12 Inquiry in order to read the drive's name.
* It was tested via Game OS on 4.21
* This is NO full source, but it is enough to copy&paste into your own code and modify for getting it to work.
( * you need sys storage access in order sys_storage_open to not fail, so either lv2_poke it or a fixed cfw ! )
==Program==
<pre>
struct lv2_atapi_cmnd_block {
    uint8_t pkt[0x20]; /* packet command block          */
    uint32_t pktlen; 
    uint32_t blocks;
    uint32_t block_size;
    uint32_t proto; /* transfer mode                  */
    uint32_t in_out; /* transfer direction            */
    uint32_t unknown;
} __attribute__((packed));
int ps3rom_lv2_get_inquiry(int fd, uint8_t *buffer) {
    int res;
    struct lv2_atapi_cmnd_block atapi_cmnd;
    init_atapi_cmnd_block(&atapi_cmnd, 0x3C, 1, 1);
    atapi_cmnd.pkt[0] = 0x12;
    atapi_cmnd.pkt[1] = 0;
    atapi_cmnd.pkt[2] = 0;
    atapi_cmnd.pkt[3] = 0;
    atapi_cmnd.pkt[4] = 0x3C;
    res = sys_storage_send_atapi_command(fd, &atapi_cmnd, buffer);
    return res;
}
int sys_storage_send_atapi_command(uint32_t fd, struct lv2_atapi_cmnd_block *atapi_cmnd, uint8_t *buffer)
{
    uint64_t tag;
    system_call_7(0x25C, fd, 1, (uint32_t) atapi_cmnd , sizeof (struct lv2_atapi_cmnd_block), (uint32_t) buffer, atapi_cmnd->block_size, (uint32_t) & tag);
    return_to_user_prog(int);
}
void main ()
{
// this poke allows us to use storage open on 4.21
lv2_poke(0x8000000000017B2CULL,0x386000014e800020ULL );
print("lv2 poked...\n");
int fd;
int ret;
uint8_t buf[0x38];
memset(buf,0,0x38);
// open Blu Ray Drive
ret = sys_storage_open(0x101000000000006ULL,&fd);
if(ret != 0)
{
printf("sys_storage_open failed (0x%x)...\n", ret);
return;
}
// inquiry command
ret = ps3rom_lv2_get_inquiry(fd,buf);
if(ret != 0)
{
printf("sys_storage_send_device_command failed (0x%x)...\n", ret);
return;
}
// close device
sys_storage_close(fd);
// dump result to file
FILE * pFile;
pFile = fopen ( "/dev_hdd0/game/myfile.bin" , "wb" );
fwrite (buf , 1 , sizeof(buf) , pFile );
fclose (pFile);
print("file written...\n");
}
</pre>
</pre>
== Result ==
Here is a dump taken from a CECHJ04:
<pre>
00000000 05 80 00 33 9B 00 00 00 53 4F 4E 59 20 20 20 20 ...3....SONY   
00000010 50 53 2D 53 59 53 54 45 4D 20 20 20 33 30 32 52 PS-SYSTEM  302R
00000020 34 31 35 34 20 20 20 20 20 20 20 20 20 20 20 20 4154           
00000030 20 20 20 20 20 20 20 00                                .
</pre>
== structure ==
{|class="wikitable"
|-
! Address !! Size !! Value !! Description !! Observations
|-
| 0x0 || 0x8 ||  || scsi information  || [[http://en.wikipedia.org/wiki/SCSI_Inquiry_Command SCSI Inquiry Command]]
|-
| 0x8 || 0x8 || "Sony    " || Vendor identification ||
|-
| 0x10 || 0x20 || "PS-SYSTEM  302R" || Product identification ||
|-
| 0x20 || 0x4 || "4154" || Product revision level ||
|}
{{Reverse engineering}}<noinclude>[[Category:Main]]</noinclude>
Please note that all contributions to PS3 Developer wiki are considered to be released under the GNU Free Documentation License 1.2 (see PS3 Developer wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following hCaptcha:

Cancel Editing help (opens in new window)