PS3 [Tutorial] HDD mounting and decryption on Linux

@Berion attached are my partition tables. All from OFW 4.90 on a CECH-2503A, except the 640GB which would have been formatted on whatever was current around 2011.

USERDATA CACHE
SizeTotal
Sectors
Total
Bytes
Size
GiB
Sectors
for data
Start
Sector
LengthEnd
Sector
Size
Bytes
Size
GiB
Offset to
Cache Start
Start
Sector
LengthEnd
Sector
Offset to
Last Sector
Total
Offsets
60GB HDD1172102406001164288055.891166859205243201124916161130159365759570739253.640113015936419429611721023288
320GB HDD625142448320072933376298.09624618128524320620423808620948128317656989696295.84062094812841942966251424242424
640GB HDD1250263728640135028736596.17124973942452430412455451201246069424637719101440593.92812460694324194296125026372808
1TB SSD19535251681000204886016931.51195300084852432019488065281949330848997788942336929.2601949330848419429619535251442424
1.5TB SSD320000000016384000000001525.8831994756805243203195281376319580569616359840645121523.63031958056964194296319999999288
 

Attachments

@andshrew Thanks!
I also found in dumped tables 524312, so the 524304 is not single anomaly as we thinking. For some reason, thresholds are 8 sectors. The same with VFLASH "sub-partitions". That's some kind of a pattern at least and some track.

@gmipf Also thank You.

I don't remember how it looks like in 1.8b. Below is screenshot from current version. 2xxx covering also 25xx. Those 25xx in red section have new bootloader, like 3xxx or 4xxx. ^^

keygen_v21.png
 
Last edited:
I came across an issue where the PS3 appears to have changed the file system in such a way that FreeBSD will no longer access it. I cloned a 60GB drive image to the 1TB and expanded the partitions. Everything is working fine on the PS3, so I tested the safe mode Restore File System. That also worked fine, but now FreeBSD does not like the partition.

It works fine in the PS3, and Linux will also mount it. But FreeBSD reports:

Code:
UFS2 superblock failed: fs->fs_fsbtodb (0) != ILOG2(fs->fs_fsize / sectorsize) (3)
Failed, superblock has critical errors

It makes me wonder how backwards compatible UFS is... as in we're running growfs from the very latest version of FreeBSD and does that have 100% compatibility with a version thats likely 10+ years old? It would be nice to try an older version of FreeBSD and see if it does make any difference, but I'm finding it difficult to boot the old installation ISOs in qemu, and the earliest pre-built VMs are only version 13.2.
 
I asked about this error on the FreeBSD forums, and I got a suggestion to try NetBSD as UFS support in that is endian agnostic... and sure enough it is.

I created an amd64 NetBSD VM and it can mount this partition that FreeBSD is currently unable to (read & write).

So this at least gives some more avenues of investigation now as we no longer need emulate the OS and can do proper virtualisation instead. It will be interesting if resize_ffs from NetBSD gives different results on the PS3 side to what growfs did with FreeBSD. It should also be easier to test against a version of NetBSD thats of a similar age to the PS3 OS, should there be any compatibility issues introduced by extending the partition from a modern OS.
 
I've tried a couple of NetBSD options now.

Using the latest version I expanded the file system with resize_ffs and the PS3 was unable to boot. It was stuck in a perpetual loop where it wanted to repair the file system.

Using version 6.0 (which is from ~2012) I expanded the file system with resize_ffs and the PS3 does work with that. Interestingly it also correctly includes the 8% reserve in its free space calculation - something which it never did in the attempts to use growfs with FreeBSD.

I'll do some more tests to see if the 0KB free issue is also resolved by using NetBSD 6.0, but from initial tests it does seem that using an era appropriate OS to expand the file system is going to be more reliable than using the latest.
 
NetBSD 6.0 is proving to be much more reliable. I've expanded two drives (320GB and 1TB) to their maximum size now and both appear to work fine - no more 0KB free space on the PS3. So you can likely remove that calculation from the expander script and just expand to the maximum size. :angel: Tunefs also works properly now, with the PS3 showing the correct space free based on what the reserve percentage is set to.

NetBSD 6.0 can't mount the partition, but I don't think that is an issue as all of the utilities work fine. You can still mount it in FreeBSD after expanding the file system if you wanted write access for whatever reason.

I've shared the steps for creating a NetBSD 6.0 VM here, and I've shared a pre-built disk image here which you can use.

The steps for expanding the file system are then shared here.

@Berion I'll be interested to hear if you have any success with this.
 
Last edited:
@andshrew Endianness doesn't matter because even if some flag telling it is BE, in reality it is LE on the mapper. If it will be BE, there would be no point to converting it on the fly by bswap16-ecb first. Also it would be pointless on CellOS side to make double conversion (in reality it writing encrypted sectors in LE then it converts to BE - if this wouldn't be true, all procedures we doing will not produce decrypted data but garbage).

Maybe this flag messing something on fs side? But if this is true, isn't every single time PS3 would reject it UserData partition forcing user to format or at least perform fsck on start? So I'm pretty sure all is fine, except that UFS2 (if this is even UFS2 in the first place :|) is different somehow (which Your last test proves that).

NetBSD 6.0 is proving to be much more reliable. I've expanded two drives (320GB and 1TB) to their maximum size now and both appear to work fine - no more 0KB free space on the PS3. So you can likely remove that calculation from the expander script and just expand to the maximum size. :angel: Tunefs also works properly now, with the PS3 showing the correct space free based on what the reserve percentage is set to.
Oh, that's strange! We know that CellOS is Sony's fork of some BSD family. Maybe it was NetBSD codebase then?
Are You using "prep" edition or other ppc? Which exactly? Does they serving live or some disk image or user must install it by his own?

NetBSD 6.0 can't mount the partition, but I don't think that is an issue as all of the utilities work fine. You can still mount it in FreeBSD after expanding the file system if you wanted write access for whatever reason.
Other tools can properly works on fs but mount cannot mount it? That's stranger even more. :)

I'll be interested to hear if you have any success with this.
I will back to PS3 stuff in 2024. ^^" Currently I'm updating PS4 HDD Decryption Helper and soon next XEB will be released so I need to speed up a little XEB PUPPY project.
 
@andshrew Endianness doesn't matter because even if some flag telling it is BE, in reality it is LE on the mapper. If it will be BE, there would be no point to converting it on the fly by bswap16-ecb first. Also it would be pointless on CellOS side to make double conversion (in reality it writing encrypted sectors in LE then it converts to BE - if this wouldn't be true, all procedures we doing will not produce decrypted data but garbage).

Maybe this flag messing something on fs side? But if this is true, isn't every single time PS3 would reject it UserData partition forcing user to format or at least perform fsck on start? So I'm pretty sure all is fine, except that UFS2 (if this is even UFS2 in the first place :|) is different somehow (which Your last test proves that).

Are you sure that this is how the byte swapping works? It doesn't make sense how any of this is working if that is the case, especially if you take FreeBSD at face value in that they say their releases can only read UFS file systems that match the host systems endianness.

What would logically make more sense to me is that the byte swapping that cryptsetup is doing with bswap16-ecb is only happening at the encryption level.

As in - all the encrypted data on the disk is in big-endian format. bswap16-ecb swaps the bytes of the encrypted data so that it is in a little-endian format that the Linux system is then able to decrypt.

The actual decrypted data, that is then presented at /dev/mapper/ps3hdd, is always in it's original unaltered format.

I guess you could test this by using a big-endian Linux system, and see if you can decrypt the drive without the bswap16-ecb step and then compare the decrypted data to what it looks like when bswap16-ecb has been used.

If that is how it actually works then things start to make a lot more sense to me.

Oh, that's strange! We know that CellOS is Sony's fork of some BSD family. Maybe it was NetBSD codebase then?
Are You using "prep" edition or other ppc? Which exactly? Does they serving live or some disk image or user must install it by his own?
I'm using an amd64 edition of NetBSD. I think it's working better with version 6.0 because it's a version closer to when the PS3 OS was forked. If I use the latest NetBSD 9.3 the PS3 does not accept the drive after the file system has been extended.

There was no pre-built VM image available, I installed it via the steps here:
https://gist.github.com/andshrew/4c1fe1c432d3d77e9bddf978426d34a2#file-ps3_netbsd_6-0_qemu_vm-md

I shared the disk image I created here to save having to do those steps if you don't want to:
https://archive.org/details/NetBSD_6.0_amd64_qemu_vm

These were the commands and output I got from increasing the file system on a 320GB drive:
https://gist.github.com/andshrew/4c1fe1c432d3d77e9bddf978426d34a2#file-ps3_hdd_expansion_notes-md
 
bswap16-ecb.ko converting BE to LE (ps3hdd-bs). After that disk is decrypting on the fly (ps3hdd). So encryption must be performed on LE data or else it would output garbage because encryption/decryption is block based, not byte based. When decryption is fine, then data written is also fine, which means it must be written in LE in the first place by PS3 herself. :)

I would bet on that, that Sony did this to foul parsers in case if disk will become decrypted. Which as we know today, has happened. They are known for unnecessary obfuscations.

- - -
Yeah, I answered to Your post without reading first the guides.

BTW: in Expander v0.8, I writing on ps3hdd3 (NOR) / ps3hdd2 (NOR) a cache image, so following by Your guide, someone will overwrite it again by his own data which was dump before in one of the steps. Nothing bad, just time wasting.
 
Last edited:
@Berion I see, so using a Linux big-endian system wouldn't change anything. Byte swapping is a required part of the encryption cypher, and not necessarily related to the PS3 being a BE system? It still seems like this byte swapping is only happening at the encryption level. Once the data is decrypted it would come out in whatever format it was in originally.... so the BE UFS partition is still BE... the byte swapping is happening at a layer above this.

I hadn't tried the latest expander script yet as I'd been messing around with my edits to it trying different sector sizes... so I'll keep that change in mind. :peaceful:
 
If You will not byte swap data, You will not decrypt data from any sector used by "GameOS". So data before encryption is LE. Eg. file managers does not convert BE to LE while copying from/to PS3 HDD/USB which also proves I'm right. ^^

All of this is above my head for sure but I don't see any flaw in my thinking.

- - -
And to add more about obfuscations: I'm siting now on PS4 HDD Decrypter (because I finally got full disk image with EAP HDD Key) and spotted that few partitions have intentionally prepared first sector to be recognized as HFS+. Of course it is not HFS but encrypted UFS2/FFS like on PS3, but they did that I believe intentionally to foul people which will automatically break those partitions if attempt to mount it rw on macOS... Which means mandatory format on PS4 side and reinstalling whole fw (which means deleting contents from all partitions! because this is how it works reinstallation on PS4). What a dick move... :|

So I see this as something similar if target OS is endianness sensitive: to lead in both cases user on a land mine and data corruption.
 
@Berion the only other test I can think of is comparing what independently created BE and LE UFS partitions look like, compared with the PS3 one. You can do this easily with NetBSD due to it supporting both.

I created two file systems using settings as close to what the PS3 formatted drive used, and comparing the opening bytes of the superblock.

NetBSD BE file system:
Code:
00000000  00 00 00 00 00 00 00 00  00 00 00 14 00 00 00 18  |................|
00000010  00 00 00 1c 00 00 08 ec  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 bd  |................|
00000030  00 00 40 00 00 00 10 00  00 00 00 04 00 00 00 08  |..@.............|
00000040  00 00 00 00 00 00 00 00  ff ff c0 00 ff ff f0 00  |................|

NetBSD LE file system:
Code:
00000000  00 00 00 00 00 00 00 00  14 00 00 00 18 00 00 00  |................|
00000010  1c 00 00 00 ec 08 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 00 00 00 00  00 00 00 00 bd 00 00 00  |................|
00000030  00 40 00 00 00 10 00 00  04 00 00 00 08 00 00 00  |.@..............|
00000040  00 00 00 00 00 00 00 00  00 c0 ff ff 00 f0 ff ff  |................|

PS3 file system:
Code:
00000000  00 00 00 00 00 00 00 00  00 00 00 14 00 00 00 18  |................|
00000010  00 00 00 1c 00 00 09 24  00 00 00 00 00 00 00 00  |.......$........|
00000020  00 00 00 00 00 00 00 00  00 00 78 10 00 00 00 bf  |..........x.....|
00000030  00 00 40 00 00 00 10 00  00 00 00 04 00 00 00 08  |..@.............|
00000040  00 00 00 00 00 00 00 00  ff ff c0 00 ff ff f0 00  |................|

It does seem to be in-line with the BE file system. But anway....

All of this is above my head for sure but I don't see any flaw in my thinking.
....is where I am too. Whatever is going on exactly it seems to be working and not corrupting the data. :angel:
 
@Berion I've made a bit of progress on the issue I was getting with my 1TB SSD in FreeBSD; the issue being I couldn't mount it. The issue happened whether I had cloned and expanded a smaller drive to it, or let the PS3 format the entire drive itself, I could not get it to mount under FreeBSD:

UFS2 superblock failed: fs->fs_fsbtodb (0) != ILOG2(fs->fs_fsize / sectorsize) (3)
mount: /dev/vtbd1: Invalid fstype: Invalid argument

Using NetBSD I was able to compare the superblock of a mountable partition vs one which wouldn't mount:
HXHAP6j.png


You can see the "fsbtodb" value is different. This is apparently the sector size of the partition:- https://man.netbsd.org/tunefs.8

3 is 512
0 is 4096

The disk being SSD is 512bytes per sector (as far as I know), so something is causing the PS3 to erroneously set this value to 4096 whenever a partition over a certain size is mounted.

I can alter the superblock manually to set it back to 3 (512 bytes), and then FreeBSD will mount it again. But returning the drive to the PS3 results in the value being reset to 0.

I was wondering why I didn't run into this issue when I was testing larger 1.5TB SSDs; perhaps it's due to PS3 file system utilities breaking above 1TB.... as in the PS3 cannot change it on drives over 1TB in size (even if it wanted to) because its utilities aren't working properly anymore. But at 1TB they do still work, so - for unknown reasons - it is making this change whenever it mounts the drive.

Perhaps there was an assumption at some point in time at all 1TB drives would use 4096 sector sizes, or it is just a bug/limitation in their UFS implementation?

Edit: see this post for reason it didn't affect the 1.5TB drive:
https://www.psx-place.com/threads/t...decryption-on-linux.23308/page-16#post-377420
 
Last edited:
@andshrew Actually, sector size (block size) physically is set to be 4096 on most if not all SSDs (and in many high capacity SHDD/HDD too). But their fw exposed drivers as 512 (it is called 512e) for systems which does not work with 4K. When formatting such drives on eg. PC there is some feature called "Advanced Format" which aligns somehow and something in filesystems tables (but what exactly and to what, I don't get it, maybe cluster size?).

Interesting discovery!
 
@andshrew Actually, sector size (block size) physically is set to be 4096 on most if not all SSDs (and in many high capacity SHDD/HDD too). But their fw exposed drivers as 512 (it is called 512e) for systems which does not work with 4K. When formatting such drives on eg. PC there is some feature called "Advanced Format" which aligns somehow and something in filesystems tables (but what exactly and to what, I don't get it, maybe cluster size?).

Interesting discovery!

Ah... I now see a few things have been disguising it as 512.

If I connect it directly via SATA to a natively running Linux OS I see that it is 4096:

Disk /dev/sdd: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: CT1000MX500SSD1
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes

When it is connected to my USB to SATA adapter it reports 512:

Disk /dev/sdd: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: 500SSD1
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

It also seems to be presented as 512 whenever it is passed into a VM.

Whereas the 2TB limited to 1.5TB via HPA reports 512 even when connected via SATA, so that was natively 512 which explains why I didn't have the problem with that.

So the actual issue is the PS3 sees the drive is 4096 and configures the UFS superblock as such; and then FreeBSD refuses to mount the partition because the superblock sector sizes doesn't match what it is seeing the drive as (512), but you can work around this by editing the superblock to tell it is 512.... and everything works as expected because the 512 conversion to 4096 is happening transparently behind the scenes.

Do you think it would be better to try and find another drive which is natively 512?

Edit:- although thinking about this. My drive would appear to be 512e, so perhaps the PS3 shouldn't be setting 4096 as the sector size in the UFS superblock...
 
Last edited:
Logical is written to partition tables and filesystem tables, and every OS using those values. Physical cannot be changed and logical can be set to be the same as physical. But once disk is formatted to eg. 512, You cannot change it to 4096 because You will loose literally all data (addresses of literally everything starting from tables through files itself, starting to mismatching).

CellOS don't understand 4K and never use it. It is always 512. I think this value in super block is ignored on PS3, while putting FreeBSD in confuse. I think it is safe to manually change it to 512 because it is 512 in use always anyway.

What I don't really get it is Your HPA stuff. Eg hdparm talks to fw and it is fw which setting up HPA area, and it will use 4K, not 512e as I believe. But... What You said, it is using 512e. Why? That's place for another Jackie Chan meme. ;D

BTW: What did You use for comparing and parsing super blocks?
 
What I don't really get it is Your HPA stuff. Eg hdparm talks to fw and it is fw which setting up HPA area, and it will use 4K, not 512e as I believe. But... What You said, it is using 512e. Why? That's place for another Jackie Chan meme. ;D

With HPA I just meant that I had used that on my 2TB drive to reduce it to 1.5TB, not that it had had changed the sector size.

But that drive appears to be native 512? Which would explain why I never ran into this issue when using it.

This was the output when connected via SATA before I reduced its size.
Code:
Disk /dev/sdf: 1.82 TiB, 2000398934016 bytes, 3907029168 sectors
Disk model: SanDisk SDSSDH32
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x80b3e384

BTW: What did You use for comparing and parsing super blocks?
You can use dumpfs in the BSDs to parse it.
https://man.freebsd.org/cgi/man.cgi?dumpfs(8)
 

Similar threads

Back
Top