Skip to content

Encrypted files and keys

ForzaTechArchives and filesApplies toFH6

Forza Horizon 6 encrypts its game database, its string-and-settings archives and the player’s profile with Arxan TransformIT (TFIT), a white-box AES. The geometry, placements, materials and textures of a track are not encrypted (see PGZP archives), so everything on the World pages can be read without a key. Observed

The measurements here come from a census of one install; a later fresh install of the same game carries the same block counts and sizes (game database 16,123,860 bytes in 123 blocks, sfsdata 77,604,132 in 592, NerdData.json 564 in one). Observed

File Block size Notes Confidence
media\Stripped\gamedbRC.slt 0x20000 (123 blocks) the game database: cars, parts, wheel and tyre sizes, prices. About 16 MB at 7.99999 bits per byte, no SQLite header; decrypted, an SQLite database of 207 tables that passes SQLite’s integrity check Observed
media\sfsdata 0x20000 (592 blocks) Observed
NerdData.json 0x200 Observed
Profile files (<xuid>ProfileBackup, <xuid>Meta, CmsCache\**) 0x200 the player’s garage, tunes, paint and liveries; local copy of a cloud save Observed
the 29,250 zip entries of method 22, in 1,085 archives under media (every entry of Rendering.zip and GameTunableSettings.zip, and most of media\Audio\EngineSynth) 0x200 raw DEFLATE inside the TFIT envelope; sizes are rounded up to whole blocks (64 bytes become 564); see Zip archives Proven

The render settings in these archives (the near-field megatexture parameters in Megatexture.xml, Livery.xml, DecalManager.xml) are readable only with the General usage’s keys. Proven

Every TFIT file starts with a 36-byte header, then carries blocks each followed by a 16-byte MAC. The plaintext is N × block size − padding. All checked files divide exactly. Observed

TFIT envelopevariableFH6100% known

Little-endian. N blocks, each block followed by its MAC.

ProvenObservedSourcedInferredUnknownNot described
OffsetSizeTypeFieldConfidenceNotes
0x016u8[16]IVObserved
0x104u32padding sizeObservedbytes of padding at the end of the plaintext
0x1416u8[16]MACObservedof the header
0x24N × (block size + 16)block[]blocksObservedciphertext block, then a 16-byte MAC; block size 0x20000 or 0x200

The executable statically links Botan; its CNG AES-GCM strings have no references, so they belong to another subsystem, not to these files. Observed A static analysis of forzahorizon6.exe found no key. Observed The executable is not packed and its entry point is the ordinary compiler start-up code; .text is 104 MB of which some 64 KB windows are near random (above 7.9 bits per byte) yet hold real function boundaries, and some individual functions (two that register the instancing data) are stored encrypted and decrypted in memory at run time. Observed Forza-Crypto-Tool decrypts the FH6 files only on its authors’ server and ships no key. Sourced · Forza-Crypto-Tool Its authors publish decrypted data; in it gamedbRC.slt is an SQLite database of 205 tables listing 638 cars. Sourced · Forza-Crypto-Tool data mirror A second tool decrypts them offline with plain AES keys, already lifted out of the white-box tables, that it ships inside an obfuscated library: two transport keys shared by every container and a data and MAC key pair for each of seven usages — GameDB, ProfileData, General for settings files and archive entries, Engine, SFS for sfsdata, and ServiceA, ServiceB for the per-player containers. The same library holds a separate AES key for the Motorsport CMS entries, which are not FH6’s. Sourced · FH6-Local-Crypto-Car-Editor-Tool No key is published in the open.

Each block is AES-256-CBC under the file kind’s data key, with no padding mode (the header’s padding field covers the tail). Sourced · FH6-Local-Crypto-Car-Editor-Tool Every block and every MAC has its own IV: the next IV is the first 16 bytes of HKDF-SHA256 with the previous IV as input key material and the two transport keys as salt and info, so the whole chain follows from the IV in the header. Sourced · FH6-Local-Crypto-Car-Editor-Tool A block’s MAC is the AES-CMAC of its plaintext under the 16-byte MAC key, stored AES-CBC-encrypted under the data key with the IV after the block’s. Sourced · FH6-Local-Crypto-Car-Editor-Tool The header’s MAC is the AES-CMAC of the padded length (u32, little-endian), the header’s IV and its padding field, and the game rejects a container whose header MAC is stale. Sourced · FH6-Local-Crypto-Car-Editor-Tool

gamedbRC.slt has a second layer: its decrypted blocks are XORed with a keystream to give the SQLite image. Each 4-byte group q is XORed with the CRC-32 of the four little-endian bytes of q + C × (q + 1) (ASCII upper case folded to lower case first), for a constant C; the game removes it in its in-memory SQLite file layer. The same tool calls the 16 bytes after the padding field a nonce in this file and does not check them or the block MACs. Sourced · FH6-Local-Crypto-Car-Editor-Tool

A profile decrypts to a u32 compressed size, a u32 expanded size and a zlib stream. Observed A method-22 archive entry decrypts to a raw DEFLATE stream. Observed

Every part of the description above has been confirmed against files the game wrote: each container’s header authenticates under its usage’s MAC key, every one of its blocks’ MACs matches, and the plaintext comes out as the inner format promises.

Files Usage that authenticates them What the plaintext is
profiles, 737 and 735 blocks (paddings 78, 306) ProfileData a u32 compressed size equal to the bytes after it, a u32 expanded size, then a zlib stream (header 78 9C) inflating to that size, Adler-32 checked
an Estate and a CustomFlyer blob ServiceB that container kind’s own records
media\sfsdata, 592 blocks SFS 77,522,352 bytes
media\Stripped\gamedbRC.slt, 123 blocks GameDB an SQLite image once the keystream is removed: its header string and a page size times page count that fits
every method-22 zip entry of the install, 29,250 in 1,085 archives General a raw DEFLATE stream inflating to exactly the zip’s stated size and CRC-32
media\NerdData\NerdData.json, one block General 78 bytes

Observed The zip entries are every one there is (Proven). The Engine pair has not matched any file seen here.

That confirms the envelope, the HKDF IV chain, the block CMACs, the header MAC, the keystream, the profile’s compressed header and the settings entries’ raw DEFLATE. Observed

  • The saved designs and tunes the platform keeps for the player are plain; see Saves and tunes. Observed
  • media\Stripped\StringTables\<LANG>.zip are ordinary deflate zips (String tables). Observed
  • The car archives under media\Cars are ordinary zips (Cars). Observed