Spuisofs

From PS3 Developer wiki
Jump to navigation Jump to search

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.
  • spuisofs.tar.gz: http://www.multiupload.nl/0U1ZIZN6PG

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)
...