Hi ...
Don't know whether or not you are still interested? as I don't frequent the Forum very often, and came across you posting from April. I did quite a lot of work on the XB360 including writing a number of articles and programs especially concerning the STFS, regarding Rehashing and Resigning game saves etc, and although I still have my original 360, I did in fact buy one of the last production runs of the 360, although it just sits on top of my PS4 and have probably not switched it on more than a couple of times since I unpacked it! I never actually thought anybody would still be interested in the the 360 after all this time!
I have possibly 10-12TB of archives of old computer related information from my days of Assembler for the Zilog Z80, Motorola 6502, 6800 and 68000 CPUs and the Old Xbox, and even kept my exploit disks such as Splinter Cell and Agent Under Fire etc which enabled Linux Loading etc. Unfortunately all this information sits somewhere amongst these archives, but, in the main was just generally dumped into archive from Floppy Disks, Tape Streamers, Zip Disks, Syjet Cartridges, HDD's, CD's and DVD's etc, but unfortunately, in no particular order! and although I was of little value to me now, I didn't want to just throw it all away, so just dumped it all to a number of pocket sized 2TB drives ...
If you are still interested ... I will see what I can come up with!
Information below might just Wet your appetite! or indeed may just put you off! ... and was something I just managed to find, and was the complete article that I posted as a response to an enquiry in 2012, may have been on my own BB can't remember!
+----------------------------+
| The STFS Security Primer |
+----------------------------+
The STFS (Secure Transacted File System) is a package type file format used for storing Game Saves and various other content for the Microsoft Xbox 360 Console. The Package size is always on a 4096 (0x1000) Boundary ...
The Header for an STFS package consists of a 0x4 Byte Magic/ID Value (Padded, and contains CON/PIRS/LIVE), a X.509(PKI) Certificate which holds console specific information, including the Certificate Owners Console ID[1], as well as the RSA Assymetric Public Key Exponent and Modulus (Signed with PKCS1 (1024 bit) RSA signature) and a PKCS1 RSA signature that is generated from a SHA1 Hash taken from the Overall Header Extension. A series of 16 Licenses 0x10 long with 0x8 Reserved for the License; 0x4 for the Flags and 0x4 the for Info Bits. The Header also holds an SHA1 content ID Hash, followed by an Int32 (Big Endian) Value indicating the Base Hash Block, and also the STFS Type (Calculated by: Value + 0xFFF & 0xF000) ...
A Content Type Enum is written out (Indicating what the package contains and how the Data is to be Handled, and which also indicates the corresponding folder the package should be placed in). After that it's Metadata Type 1/2 for the Package (Including all the Descriptors, IDs, Game Title, Save Name/Number, Position etc, and also an SHA1 Hash of the Top Level Hash Block, a Count of Valid/Old Data Blocks and a Descriptor for the STFS) followed by an Icon for the Package and an Icon for the Content ...
Hashes - 0xA000/0xB000 are Reserved as the Base Hash Blocks (which one is used, is dependant on the Base Hash Block value in the Header), these blocks are also considered level 0 of the Hash Tree (Level 1 is determined depending on the Base Block in the Descriptor). Each Hash Block can contain up to 170 (0x1000/0x18) 0x18 Byte Blocks (0x14 for the Hash itself, 0x1 for info, and 0x3 for corresponding Data Block Status (Normally Contiguous)) NB. I'm not going to go into pointer positioning or recursive loading on the levels regarding the Hash Tree or Block Status, and will require you to provide the necessary positioning and processing code. Many people use an unecessarily complicated EndianIO - Thereby Hangs a Story! - which is totally unecessary, and a simple BaseStream positioner will suffice, Endianess can be catered for in the limited code processing. It is much better and faster to check the calculated SHA1 Hashes against the stored values when the blocks are being processed, and do a quick comparitor check for equality, and only write out if necessary ...
Files - 0xC000 is Reserved as the Base File Table. Each File Table Entry is 0x40 Bytes in length and each file table can hold up to 64 (0x40) Entries. Each entry consists of an ASCII FileName, FileName Determinate, Flags, Reserved Block Count, Allocated Block Count, Block Offset, Folder Specifier, File Size, Creation TimeStamp, Modified TimeStamp [Both written in FAT(X) Format] Many people appear to have issues here! but the date/time is easily coded by a little bit shifting logic...
Signature - After all the Hashes haves been calculated, the overall security hashes processed and checked, the File is Signed using the Consoles own Unique Key ...
Re-signing is achieved by creating a new instance of the RSA Crypto Service Provider, and importing the RSA Parameters from an available KeyVault, which pulls in the Modulus, Exponent etc, checks and/or calculates/stores the overall security hashes generated from the Hash Tree, and the Signature processed and written out using the SHA1 Hash described above, finally the Public Key Data is written out to complete the process ...
Reference:
[1] This gets changed to the Certificate Owners Console ID if the file gets resigned, and if a game checks both ID's - I think one of the Forzas' is one - then Only your own console Keyvault Data will satisfy the Signing Process ...
PLEASE NOTE: I have recounted this Data hopefully to be of some assistance, and provide a starting point, not to get involved a never ending questions and answers session, most, if not all of the tabular data/offsets can be got from Free60/STFS ...
EOF