Spuisofs

From PS3 Developer wiki
Revision as of 02:58, 3 February 2014 by Euss (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Introduction

  • spuisofs is a Linux virtual filesystem which allows you to execute isolated SPU modules from user-space.
  • spuisofs can execute only isolated SPU modules which are decrypted by isoldr.
  • I used this driver e.g. to dump my EID0 key and my ATA keys.
  • GIT repo: http://gitorious.ps3dev.net/ps3linux/spuisofs

Features

  • MFC data segment faults are handled by the driver. That means you do not have to worry about it.
  • Large data buffers which can be used for data exchange between SPU and PPU.
  • Data buffers are not physically continuous which eliminates the RAM allocation problem.
  • Full access to all SPU registers from user-space.

Mounting

glevand@debian:~$ sudo mount -t spuisofs none /mnt

Filesystem Layout

glevand@debian:~$ ls -l /mnt
total 0
-rw-rw-rw- 1 root root 1048576 Aug 16 11:10 app
-rw-rw-rw- 1 root root 1048576 Aug 16 11:10 arg1
-rw-rw-rw- 1 root root 1048576 Aug 16 11:10 arg2
--w--w--w- 1 root root       0 Aug 16 11:10 cont
-r--r--r-- 1 root root       0 Aug 16 11:10 info
-rw-rw-rw- 1 root root  262144 Aug 16 11:10 ls
-rw-rw-rw- 1 root root  131072 Aug 16 11:10 priv2
-rw-rw-rw- 1 root root  131072 Aug 16 11:10 problem
--w--w--w- 1 root root      24 Aug 16 11:10 run
-r--r--r-- 1 root root    4096 Aug 16 11:10 shadow
glevand@debian:~$ cat /mnt/info 
arg1 d000000003b9d000
arg2 d000000003c9e000

Dumping EID0 Key with spuisofs

  • I modified aim_spu_module.self to dump EID0 IV and key with my spuisofs.
  • Encrypt EID0 key seed1 with the dumped IV and key and you will get your EID0 AES-CBC-128 key.
  • Use the computed EID0 key and the dumped IV to decrypt EID0 data at offset 0x20 of size 0xC0.
  • Encrypt EID0 key seed2 with the dumped IV and key and you will get your EID0 AES-CBC-128 key.
  • Use the computed EID0 key and the dumped IV to decrypt EID0 data at offset 0x7A0 of size 0xC0.
  • dump_eid0_key.tar.gz: http://www.multiupload.nl/T3ZFSG057P
  • See also http://www.ps3devwiki.com/wiki/Making_Isolated_SPU_Modules_and_Loaders

EID0 Key Seed

Seed1:

2E D7 CE 8D 1D 55 45 45 85 BF 6A 32 81 CD 03 AF

Seed2:

30 B0 39 5D C5 83 5A AA 3A 79 86 B4 4A FA E6 84

SPU Program

Here is my SPU program to dump EID0 key and IV:

/*
 * Dump EID0 IV and key to EA with MFC
 *
 * Copyright (C) 2012 glevand <[email protected]>
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published
 * by the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

.text

start:

	ila		$2, 0x3dfa0
	lr		$sp, $2

	ila		$80, 0x3e000
	lr		$81, $3

	stqd		$7, 0($80)
	stqd		$8, 0x10($80)	# store EID0 IV
	stqd		$9, 0x20($80)	# store upper 16bytes of EID0 key
	stqd		$10, 0x30($80)	# store lower 16bytes of EID0 key
	stqd		$11, 0x40($80)
	stqd		$12, 0x50($80)

	lr		$3, $80
	lr		$4, $81
	il		$5, 0x60
	il		$6, 0x7
	il		$7, 0x20
	brsl		$lr, 0x10	# mfc_dma_xfer

	il		$3, 0x7
	brsl		$lr, 0x28	# mfc_dma_wait

	stop		0x666		# our evil stop code :)

/*
 * r3 - LSA
 * r4 - EA
 * r5 - size
 * r6 - tag
 * r7 - cmd
 */
mfc_dma_xfer:

	wrch		$ch16, $3
	wrch		$ch17, $4
	shlqbyi		$4, $4, 4
	wrch		$ch18, $4
	wrch		$ch19, $5
	wrch		$ch20, $6
	wrch		$ch21, $7

	bi		$lr

/*
 * r3 - tag
 */
mfc_dma_wait:

	il		$2, 0
	nop		$127
	hbra		2f, 1f
	wrch		$ch23, $2

1:

	rchcnt		$2, $ch23
	ceqi		$2, $2, 1
	nop		$127
	nop		$127
	nop		$127
	nop		$127
	nop		$127

2:

	brz		$2, 1b
	hbr		3f, $lr
	rdch		$2, $ch24
	il		$2, 1
	shl		$2, $2, $3
	wrch		$ch22, $2
	il		$2, 2
	wrch		$ch23, $2
	rdch		$2, $ch24
	nop		$127

3:

	bi		$lr

http://pastie.org/4503104

Result

[glevand@arch dump_eid0_key]$ ./dump_eid0_key ../dump_eid0_key.self ../eid0
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_eid0_key]$ hexdump -C /mnt/arg1
...
Here are your EID0 key and IV
At offset 0x10 is EID0 IV (16 bytes)
At offset 0x20 is EID0 key (32 bytes)
...
glevand@debian:~$ hexdump -C eid0_seed1.bin 
00000000  2e d7 ce 8d 1d 55 45 45  85 bf 6a 32 81 cd 03 af  |.....UEE..j2....|
00000010
glevand@debian:~$ cat ./eid0_seed1.bin | ./aes_cbc/aes_cbc -i 00000000000000000000000000000000 -k <dumped key> | hexdump -C
...
Here is you EID0 key
...

glevand@debian:~$ hexdump -C eid0_seed2.bin 
00000000  30 b0 39 5d c5 83 5a aa  3a 79 86 b4 4a fa e6 84  |0.9]..Z.:y..J...|
00000010
glevand@debian:~$ cat ./eid0_seed2.bin | ./aes_cbc/aes_cbc -i 00000000000000000000000000000000 -k <dumped key> | hexdump -C
...
Here is you EID0 key
...

glevand@debian:~$ cat ./ps3/eid0 | dd bs=1 skip=$((0x20)) count=$((0xc0)) | \
    ./aes_cbc/aes_cbc -d -i <dumped IV> -k <your EID0 key1> | hexdump -C
...
Here is your decrypted EID0
At offset 0xA8 is CMAC-OMAC1 (16 bytes)
...

glevand@debian:~$ cat ./ps3/eid0 | dd bs=1 skip=$((0x20)) count=$((0xc0)) | \
    ./aes_cbc/aes_cbc -d -i <dumped IV> -k <your EID0 key1> | dd bs=1 count=$((0xa8)) | \
    ./aes_omac1_cmac/aes_omac1_cmac -k <your EID0 key1> | hexdump -C
...
Here is CMAC-OMAC1 which should match data at offset 0xA8
...

glevand@debian:~$ cat ./ps3/eid0 | dd bs=1 skip=$((0x7a0)) count=$((0xc0)) | \
    ./aes_cbc/aes_cbc -d -i <dumped IV> -k <your EID0 key2> | hexdump -C
...
Here is your decrypted EID0
At offset 0xA8 is CMAC-OMAC1 (16 bytes)
...

glevand@debian:~$ cat ./ps3/eid0 | dd bs=1 skip=$((0x7a0)) count=$((0xc0)) | \
    ./aes_cbc/aes_cbc -d -i <dumped IV> -k <your EID0 key2>| dd bs=1 count=$((0xa8)) | \
    ./aes_omac1_cmac/aes_omac1_cmac -k <your EID0 key2> | hexdump -C
...
Here is CMAC-OMAC1 which should match data at offset 0xA8
...

Dumping EID2 Key with spuisofs

  • I modified fdm_spu_module.self to dump EID2 key and IV.
  • fdm_spu_module.self is a very simple isolated SPU module, it just decrypts EID2 and writes the reult to PPU memory buffer.
  • EID2 is encrypted with AES-CBC-256.
  • Use the dumped IV and key to decrypt EID2.
  • dump_eid2_key.tar.gz: http://www.multiupload.nl/D5GKYOZRAU

Information about EID2

  • EID2 has 2 blocks: type 1 (P-block) and type 2 (S-block).
  • At offset 0 you will find the header of size 0x20.
  • Type 1 block starts at offset 0x20 and the size of the block is at offset 0x0 in the header (2 bytes).
  • Type 2 block starts at offset 0x20 + sizeof block1 and the size of the block is at offset 0x2 in the header (2 bytes).
  • Note that EID2 have another encryption level, it can be decrypted with DES, key and IV can be found in the leaked JIG kernel.

SPU Program

/*
 * Dump EID2 IV and key to EA with MFC
 *
 * Copyright (C) 2012 glevand <[email protected]>
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published
 * by the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

.text

start:

	ila		$2, 0x3dfa0
	lr		$sp, $2

	ila		$80, 0x3e000
	lr		$81, $3

	stqd		$7, 0($80)
	stqd		$8, 0x10($80)	# store EID2 IV
	stqd		$9, 0x20($80)	# store upper 16bytes of EID2 key
	stqd		$10, 0x30($80)	# store lower 16bytes of EID2 key
	stqd		$11, 0x40($80)
	stqd		$12, 0x50($80)

	lr		$3, $80
	lr		$4, $81
	il		$5, 0x60
	il		$6, 0x7
	il		$7, 0x20
	brsl		$lr, 0x10	# mfc_dma_xfer

	il		$3, 0x7
	brsl		$lr, 0x28	# mfc_dma_wait

	stop		0x666		# our evil stop code :)

/*
 * r3 - LSA
 * r4 - EA
 * r5 - size
 * r6 - tag
 * r7 - cmd
 */
mfc_dma_xfer:

	wrch		$ch16, $3
	wrch		$ch17, $4
	shlqbyi		$4, $4, 4
	wrch		$ch18, $4
	wrch		$ch19, $5
	wrch		$ch20, $6
	wrch		$ch21, $7

	bi		$lr

/*
 * r3 - tag
 */
mfc_dma_wait:

	il		$2, 0
	nop		$127
	hbra		2f, 1f
	wrch		$ch23, $2

1:

	rchcnt		$2, $ch23
	ceqi		$2, $2, 1
	nop		$127
	nop		$127
	nop		$127
	nop		$127
	nop		$127

2:

	brz		$2, 1b
	hbr		3f, $lr
	rdch		$2, $ch24
	il		$2, 1
	shl		$2, $2, $3
	wrch		$ch22, $2
	il		$2, 2
	wrch		$ch23, $2
	rdch		$2, $ch24
	nop		$127

3:

	bi		$lr

Result

glevand@debian:~/dump_eid2_key$ ./dump_eid2_key ../dump_eid2_key.self ../ps3/eid2 
spuisofs found at /mnt
arg1 kernel virtual address d0000000035d3000
shadow: spe_execution_status 7
priv2: puint_mb_R 2
shadow: spe_execution_status b
problem: spu_status_R 6660082
glevand@debian:~/dump_eid2_key$ hexdump -C /mnt/arg1 
...
Here is your EID2 IV and key
At offset 0x10 is EID2 IV (16 bytes)
At offset 0x20 is EID2 key (32 bytes)
...

More Examples

See here: