HDD Encryption
Jump to navigation
Jump to search
Introduction
- The following information was reverse engineered from LV1, Storage Manager in LPAR1 and sb_iso_spu_module.self.
- I'm able to decrypt/encrypt my PS3 HDD and VFLASH on PC now.
HDD Encryption
- XTS-AES-128 is used to encrypt all data on PS3 HDD.
- XTS is NOT CBC !!! It's AES-ECB with tweak XORing. AES-CBC is impractical for HDD encryption. Each sector can be encrypted/decrypted independantly from other HDD sectors.
- Good paper about XTS-AES: http://ntnu.diva-portal.org/smash/get/diva2:347753/FULLTEXT01
- 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.
- You can set and clear ATA keys with my Linux ps3encdec device driver which i use to test HDD/VFLASH encryption. But be careful, never set/clear ATA keys while some HDD regions/partitions are mounted !!! You will corrupt your data on your HDD !!!
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) ...
Test
- To test your ATA XTS tweak and data keys, you need encrypted HDD sectors. You can either connect your HDD to PC and dump it or use my ps3vuart-tools on Linux and clear ATA keys and then dump it from ps3da. I tried both methods. But make sure you unmount all HDD regions before using ps3vuart-tools to clear your ATA keys.
- I coded a small application which implements XTS-AES encryption/decryption. XTS-AES paper is a good reference how to implement it.
- You have to pass the correct sector number in order to get correct results.
- As you see below in my examples, i pass sector number 0 and sector 8 for VFLASH because VFLASH begins at sector 8 on HDD.
- Another interesting fact is that you have to swap half-words after encrypting and before decrypting HDD sectors else you will get wrong results. This swapping is not necessary for VFLASH sectors.
- Another note is that you have to decrypt VFLASH sectors with ATA keys first and then with ENCDEC keys.
Result with 1st encrypted sector from HDD:
glevand@debian:~/xts_aes$ cat ../hdd_1st_sector_enc.bin | \ ./xts_aes -d -k <your ATA XTS data key> -t <your ATA XTS tweak key> -s 0 -r | hexdump -C 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000010 00 00 00 00 0f ac e0 ff 00 00 00 00 de ad fa ce |................| 00000020 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 02 |................| 00000030 00 00 00 00 00 00 00 08 00 00 00 00 00 08 00 00 |................| 00000040 10 70 00 00 01 00 00 01 00 00 00 00 00 00 00 0b |.p..............| 00000050 10 70 00 00 02 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000000c0 00 00 00 00 00 08 00 10 00 00 00 00 03 9a 8b 2d |...............-| 000000d0 10 70 00 00 01 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 000000e0 10 70 00 00 02 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 000000f0 10 20 00 00 03 00 00 01 00 00 00 00 00 00 00 03 |. ..............| 00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000150 00 00 00 00 03 a2 8b 45 00 00 00 00 00 3f ff f8 |.......E.....?..| 00000160 10 70 00 00 01 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 00000170 10 70 00 00 02 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000001e0 00 00 00 00 03 e2 8b 46 00 00 00 00 19 39 ce 0c |.......F.....9..| 000001f0 10 70 00 00 02 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 00000200
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 (see here: http://gitorious.ps3dev.net/reversing/lv1ldr/trees/master).
- 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 32byte seeds.
- metldr passes to lv1ldr AES-CBC-256 IV and key which are used to compute ENCDEC keys.
- I tested my ENCDEC keys with my ps3encdec Linux driver and set them again, and VFLASH was still working fine. As soon as i changed some bits in these keys, VFLASH could not be decrypted properly anymore :) It means keys are correct.
ENCDEC Key Seeds
- Use the dumped ENCDEC IV and key to encrypt these seeds and you will get your ENCDEC keys for VFLASH.
- You can find these seeds in lv1ldr.
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 on Linux 3.5.1
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) ...
Test
- To test your ENCDEC XTS tweak and data keys, you need encrypted VFLASH sectors. You can dump it from ps3da starting with sector 8.
- You have to pass the correct sector number in order to get correct results.
- As you see below in my examples, i pass sector 8 for VFLASH because VFLASH begins at sector 8 on HDD.
- The input sector was already decrypted with ATA keys.
Result with 1st encrypted sector from VFLASH:
glevand@debian:~/xts_aes$ cat ../vflash_1st_sector_enc.bin | \ ./xts_aes -d -k <your ENCDEC data key> -t <your ENCDEC tweak key> -s 8 | hexdump -C 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000010 00 00 00 00 0f ac e0 ff 00 00 00 00 de ad fa ce |................| 00000020 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 02 |................| 00000030 00 00 00 00 00 00 00 08 00 00 00 00 00 00 75 f8 |..............u.| 00000040 10 70 00 00 01 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000000c0 00 00 00 00 00 00 78 00 00 00 00 00 00 06 3e 00 |......x.......>.| 000000d0 10 70 00 00 02 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 000000e0 10 70 00 00 01 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 000000f0 10 20 00 00 03 00 00 01 00 00 00 00 00 00 00 01 |. ..............| 00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000150 00 00 00 00 00 06 b6 00 00 00 00 00 00 00 80 00 |................| 00000160 10 70 00 00 02 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 00000170 10 70 00 00 01 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 000001e0 00 00 00 00 00 07 36 00 00 00 00 00 00 00 04 00 |......6.........| 000001f0 10 70 00 00 02 00 00 01 00 00 00 00 00 00 00 03 |.p..............| 00000200