HDD Encryption
Jump to navigation
Jump to search
Introduction
- The following information was reverse enginered from LV1, Storage Manager in LPAR1 and sb_iso_spu_module.self.
HDD Encryption
- XTS-AES-128 is used to encrypt all data on PS3 HDD.
- VFLASH is encrypted twice. First with ENCDEC keys and then with ATA keys.
- Tweak and data XTS keys are of size 32 bytes but only the first 16 bytes are used.
Dumping ATA Keys
- I modified sb_iso_spu_module.self to dump ATA keys.
- ATA keys are passed as parameters to sb_iso_spu_module.self.
Program
My SPU program to dump ATA tweak and data XTS keys to PPU memory with spuisofs:
/* * Dump ATA keys * * 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) # store upper 16bytes of ATA data key stqd $8, 0x10($80) # store lower 16bytes of ATA data key stqd $9, 0x20($80) stqd $10, 0x30($80) stqd $11, 0x40($80) # store upper 16bytes of ATA tweak key stqd $12, 0x50($80) # store lower 16bytes of ATA tweak key 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@arch dump_ata_keys]$ ./dump_ata_keys ../dump_ata_keys.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_ata_keys]$ hexdump -C /mnt/arg1 ... Here are your ATA tweak and data XTS keys Data key is at offset 0x0 (32 bytes) Tweak key is at offset 0x40 (32 bytes) ...
Dumping ENCDEC Keys
- VFLASH is encrypted twice. First with ENCDEC keys and then with ATA keys.
- You cannot dump ENCDEC keys with sb_iso_spu_module.self. They are set in lv1ldr only.
- I used a modified lv1ldr with my Linux spuldrfs driver and dumped ENCDEC keys.
- XTS-AES-128 with 128bit tweak key and 128bit data key, just like ATA keys.
- ENCDEC tweak and data keys are passed to lv1ldr NOT in clear text.
- ENCDEC keys are computed by lv1ldr with AES-CBC-256 by encrypting 32bytes seeds.
- metldlr passes to lv1ldr AES-CBC-256 IV and key which are used to compute ENCDEC keys.
ENCDEC Key Seeds
Tweak key seed:
glevand@debian:~$ hexdump -C data1.bin 00000000 e2 d0 5d 40 71 94 5b 01 c3 6d 51 51 e8 8c b8 33 |..]@q.[..mQQ...3| 00000010 4a aa 29 80 81 d8 c4 4f 18 5d c6 60 ed 57 56 86 |J.)....O.].`.WV.| 00000020
Data key seed:
glevand@debian:~$ hexdump -C data2.bin 00000000 02 08 32 92 c3 05 d5 38 bc 50 e6 99 71 0c 0a 3e |..2....8.P..q..>| 00000010 55 f5 1c ba a5 35 a3 80 30 b6 7f 79 c9 05 bd a3 |U....5..0..y....| 00000020
Program
Here is my SPU program which i used to dump ENCDEC keys:
/* * Dump ENCDEC keys * * 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 $3, 0x666 wrch $ch30, $3 # wait until we get message from PPU 1: brsl $lr, 0x54 # in_mbox_count brz $3, 1b brsl $lr, 0x54 # in_mbox_read ila $80, 0x3e000 lqd $81, 0($80) # load PPU EA ila $82, 0x0 lqd $83, 0($82) stqd $83, 0($80) # store upper 16bytes of ENCDEC key lqd $83, 0x10($82) stqd $83, 0x10($80) # store lower 16bytes of ENCDEC key lqd $83, 0x20($82) stqd $83, 0x20($80) # store ENCDEC IV lr $3, $80 lr $4, $81 il $5, 0x30 il $6, 0x7 il $7, 0x20 brsl $lr, 0x20 # mfc_dma_xfer il $3, 0x7 brsl $lr, 0x38 # mfc_dma_wait stop 0x666 # our evil stop code :) /* * no input parameters */ in_mbox_count: rchcnt $3, $ch29 bi $lr /* * no input parameters */ in_mbox_read: rdch $3, $ch29 bi $lr /* * 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
- Test run with spuldrfs
glevand@debian:~/dump_encdec_keys$ ./dump_encdec_keys ../ps3/metldr ../dump_encdec_keys.self spuldrfs found at /mnt buf1 kernel virtual address d000000004311000 buf2 kernel virtual address d000000004412000 priv2: puint_mb_R 1 problem: pu_mb_R 1 priv2: puint_mb_R 666 problem: spu_status_R 2 glevand@debian:~/dump_encdec_keys$ hexdump -C /mnt/buf2 ... Here are your ENCDEC keys ENCDEC keys key is at offset 0x0 (32 bytes) ENCDEC keys IV is at offset 0x20 (16 bytes) ...