Skip to content

How AACS Works (1.0 / 2.0 / 2.1)

AACS (Advanced Access Content System) is an encryption scheme, not a disc format. It is the content protection applied across several optical disc formats, at different versions. The formats (Blu-ray, 4K UHD, HD-DVD) are the physical and filesystem layout of the disc. AACS is the encryption layered on top. Keeping the two separate is the whole basis for reasoning about this page: one scheme, several versions, several formats.

Only part of AACS is public. AACS 1.0 is documented well enough to reason about. The AACS 2.0 additions are partly public. The AACS 2.1 forensic (FMTS) layer is essentially undocumented anywhere. This page builds the reference from the disc up. It reads top to bottom as a progression: first what all AACS versions share, then what each of 1.0, 2.0, and 2.1 adds on top.

One scheme, several versions, several formats

Section titled “One scheme, several versions, several formats”

The disc format and the AACS version are independent axes. A format picks which AACS version it carries. The key hierarchy below is identical regardless of format. What differs is the version.

Disc formatAACS version
Blu-rayAACS 1.0
4K UHDAACS 2.0 or AACS 2.1 (both are in the field; 2.1 adds the forensic FMTS layer)
HD-DVDAACS, version to be confirmed from our own discs

4K UHD is not one AACS version. A UHD disc carries either 2.0 or 2.1, and the two are distinct (see the per-version sections below). HD-DVD also uses AACS. We have not yet confirmed which version off our own discs, so the exact version is left open here rather than guessed. DVDs are the odd one out: they use CSS, a different and older scheme, not AACS at all.

Every AACS disc, in all three generations, uses the same chain of keys. Each key derives the next. This ladder is the thing that does not change. Generations differ only in how one or two of these steps are computed, not in the ladder itself.

Device Keys (DK) the player's licensed secrets, never on the disc walk the MKB the subset-difference revocation tree Processing Key (PK) one per non-revoked subset in the tree + the MKB media-key data on 2.1, via the Media Key Precursor step Media Key (MK) one per disc (per device group on 2.1) + the disc Volume ID off the disc via the drive, not a file Volume Unique Key (VUK) binds the key to this physical disc decrypt AACS/Unit_Key_RO.inf stride 48 bytes on 1.0, 64 on 2.x Unit / Title Keys (UK) one key per CPS content unit AES-CBC over each unit only the units flagged encrypted Content 6144-byte aligned units (32 source packets)
  • Device Keys (DK). A set of secret keys licensed to each player model. They are not on the disc; a decoder must already hold them to begin the ladder.
  • Processing Key (PK). What a compliant, non-revoked device gets by walking the MKB. A revoked device cannot reach a usable PK.
  • Media Key (MK). The PK plus the MKB’s media-key data yields the MK. This is where 2.1 inserts an extra step (see below).
  • Volume Unique Key (VUK). The MK combined with the disc’s Volume ID, a 16-byte value that lives on the disc but is delivered by the drive over the SCSI handshake rather than stored in a file. With no Volume ID the chain stops here, which is a drive or handshake problem, not a missing key.
  • Unit / Title Keys (UK). The VUK decrypts AACS/Unit_Key_RO.inf, giving the per-CPS-unit keys that decrypt the actual content. The file is a table of fixed-width entries: a 48-byte stride on AACS 1.0, a 64-byte stride on AACS 2.x.
  • Aligned units. Content is encrypted in 6144-byte aligned units (32 source packets of 192 bytes). The top two bits of byte 0 are the Copy Permission Indicator (CPI). Non-zero means the unit is encrypted, and AES-CBC covers bytes 16 through 6144. Zero means clear. The first 16 bytes are always clear. This CPI flag is the correct test for whether a unit is encrypted. It works the same for M2TS, FMTS, and program-stream EVO, whereas checking transport sync bytes does not.

What changes between the three generations is the size of the device tree the MKB walk covers, whether the drive-to-host link is itself encrypted, and, on 2.1, one extra step between the PK and the MK plus a second forensic layer below the Unit Keys.

AACS/MKB_RO.inf is the Media Key Block. It is a sequence of records. Each record is a 1-byte type, a 3-byte big-endian length that covers the 4-byte header and the body, then the body. The walk stops at the first 00 000000 end marker. A retail MKB is often allocated to a fixed region with the records at the front and the rest zero padding.

At the heart of the MKB is a subset-difference tree, the broadcast-encryption revocation mechanism. Think of every licensed device as a leaf on a large binary tree. The MKB encrypts the media-key data so that every leaf except a revoked set can reach it. A compliant device finds the one subset it belongs to, walks to its Processing Key, and reads out the Media Key. A revoked device is excluded by construction and never reaches a usable key. Revocation is not a blocklist check. It is a property of how the block is built.

One device tree, one revocation this device revoked its subset node Media Key one wrapped copy per subset (0x05) A device finds the one subset it belongs to, walks to that subset's Processing Key, and opens its copy of the Media Key. The revoked leaf sits so that no subset it can reach holds a valid copy. Exclusion is structural, not a blocklist lookup. reaches the Media Key revoked (excluded by construction)

The tree does two things, and it helps to keep them separate. The 0x04 Subset-Difference record indexes the subsets: it carves the whole device population into groups. The 0x05 Media Key Data record then distributes the key: it stores an encrypted copy of the Media Key once per subset, one value per group. Each copy is encrypted so that only the devices in that one subset can open it.

So a device does this. From its device keys it derives the Processing Key for the single subset it belongs to. It uses that Processing Key to AES-decrypt that subset’s value in the 0x05 record, recovering the Media Key. Then it checks the result against the Verify record (0x81 on 1.0, 0x86 on 2.x), which fails a wrong derivation rather than letting a bad key through.

This is exactly how revocation works, and it is worth stating plainly. The Media Key is broadcast to every non-revoked device at once, as one encrypted copy per subset. A device can only open the copy sitting at its own subset. A revoked device is positioned in the tree so that no subset it can reach carries a valid copy. The 0x05 record is, literally, the Media Key wrapped once for each group of still-allowed devices. This mechanism is confirmed: it is implemented and every 2.0 disc decrypts through it.

The record types that matter:

TypeNameNotes
0x10Type and Versionfirst record. Carries the 32-bit MKB Type field at body offset 0
0x02Host Revocation List
0x04Subset-Difference indexa compact fixed-width index of the subsets the walk uses
0x05Media Key Datathe encrypted Media Key, one value per subset. 1:1 with 0x04
0x07Explicit Subset-Differencea smaller structure, not the main cvalue table
0x81Verify Media KeyAACS 1.0. Authenticates the derived key
0x86Verify Media KeyAACS 2.x
0x0cVariant cvalues2.1 only. Replaces 0x05, same per-subset shape; value is a Precursor
0x2dEncrypted Media Key Variant Data2.1 only. Per-disc variant seed
0x2fVariant Key Data table2.1 only. Large variant key pool indexed by the selector

On a 2.0 UHD MKB the 0x05 cvalue table is large. It carries one cvalue per subset-difference entry, so it grows with the tree, 1:1 with the 0x04 index. (On 2.1 this per-subset table is 0x0c rather than 0x05, as the 2.1 section explains.) The 0x07 record is a much smaller table and is not the main cvalue set. This distinction matters in practice: reading cvalues from 0x07 instead of 0x05 under-covers the tree and the walk fails to find the matching subset.

The 0x10 Type-and-Version record carries a 32-bit MKB Type field at body offset 0. Only the first few bytes of the MKB are needed to classify a disc.

MKB Type fieldGenerationDisc format
0x00041003AACS 1.0 (Blu-ray pre-recorded)Blu-ray
0x48141003AACS 2.0 (UHD Category C)4K UHD
0x48151003AACS 2.1 (UHD Category C, variant)4K UHD (FMTS)

Confirmed against retail discs. One nuance: a 2.1 disc carries a content certificate that still reads as 2.0. The 0x48151003 MKB Type field is the reliable signal, additionally confirmed by finding the 0x2d / 0x2f variant records during the walk. These two signals have been checked across a library of discs and always agree: the 2.1 type value coincides with the variant records, the 2.0 type value never does.

The rest of this page is the delta per generation. Read it in order. Each section assumes the ladder above and describes only what is new.

The ladder with nothing extra. Walk the tree to the Processing Key, read the Media Key, verify it against the 0x81 record, derive the VUK, decrypt the Unit Keys, decrypt the content. Unit_Key_RO.inf uses a 48-byte per-key stride. There is no bus encryption, so the drive hands back ciphertext straight from the disc.

The 1.0 subset-difference tree addresses a smaller device space than 2.0’s. Its MKB is smaller and the walk covers fewer subsets. In practice that means less revocation headroom: the system can single out fewer individual devices before it runs out of tree.

AACS 2.0, 4K UHD: bigger tree, encrypted bus

Section titled “AACS 2.0, 4K UHD: bigger tree, encrypted bus”

The same ladder over a much larger tree, with bus encryption added.

A larger tree. 2.0’s device tree is far bigger than 1.0’s, so its MKB is far larger and can address and revoke many more individual devices. A single compromised UHD player can be revoked without collateral damage to unrelated models. The MKB size follows the tree: a bigger device space means more subset-difference entries and a correspondingly larger MKB_RO.inf, which is why UHD MKBs are far larger than Blu-ray ones. The two trees below are illustrative, not to scale, but they make the point: 2.0 reaches more leaves and goes deeper, so revoking one device costs less of the tree.

AACS 1.0 device tree AACS 2.0 / 2.1 device tree fewer leaves, less revocation headroom more leaves, deeper: revoke individual devices cheaply reaches the Processing Key revoked (excluded by construction)

Bus encryption. The drive re-encrypts read data on the drive-to-host link. That layer has to be removed before you can even read ciphertext off the disc. It comes off one of two ways: a firmware-unlocked drive that strips it in place, or the AACS host-certificate handshake. See Unlocked drives.

Everything from the Media Key down (VUK, Unit Keys, aligned units) is unchanged from 1.0. Unit_Key_RO.inf moves to a 64-byte stride, and the Verify record is 0x86 instead of 0x81.

2.1 is where the public record runs out. It keeps the whole ladder but inserts one step between the Processing Key and the Media Key, and it adds a second forensic layer below the Unit Keys (the FMTS variant segments, covered next).

On 1.0 and 2.0 the walk yields the Media Key directly, and that step is identical between the two. On 2.1 the same walk yields a Media Key Precursor instead: the device opens its subset’s 0x0c value with its Processing Key and folds in its media-key-variant number. The precursor is then corrected into the real Media Key using the disc’s Variant Key Data (the 0x2f table, picked by the selector) and a fixed algorithm constant, the Key Correction Data (KCD). Even the base, non-variant 2.1 Media Key goes through this insert. The 0x86 Verify record still gates the final Media Key, so a wrong derivation fails cleanly rather than emitting a bad key.

This is the only place 2.1 differs. Below the Media Key the ladder is identical across all three generations — Media Key → VUK → Unit Key → block key → content — down to just cosmetic differences (the Unit_Key_RO.inf stride, 48 on 1.0 versus 64 on 2.x, and the verify record, 0x81 versus 0x86). 1.0 and 2.0 even share the Processing-Key-to-Media-Key step; 2.1 inserts exactly one rung, the precursor plus KCD, between the Processing Key and the Media Key.

Two kinds of addition distinguish a 2.1 disc from a 2.0 disc: extra files in the AACS/ directory, and extra records inside MKB_RO.inf. Both have been confirmed against retail 2.1 discs.

On-disc AACS/ files that exist only on 2.1. Their mere presence is the fingerprint of a 2.1 disc:

  • IndividualSegment.tbl, the forensic segment map (where the variant segments live). Confirmed format, covered in the FMTS section below.
  • SegmentKey00001.tbl, the per-segment variant keys. There is one SegmentKey file per CPS unit, numbered. Its container structure and internal record layout are confirmed (see the FMTS section); only the cryptographic step that turns the stored key material into a usable key remains open.

Inside MKB_RO.inf, the change from 2.0 to 2.1 is best read at the record level, against the 0x05 Media Key Data record described above.

  • 0x0c replaces 0x05. On 2.0, 0x05 holds one value per subset and the device decrypts its subset’s value to get the Media Key directly. On 2.1, 0x05 is gone and 0x0c sits in its place with the same shape: one value per subset of the tree, measured 1:1 against the subset index. The difference is what the decrypted value is. On 2.1 it is a Media Key Precursor, not the final Media Key. The disappearance of 0x05 and the appearance of 0x0c in the same per-subset shape is confirmed structure. That the value is a precursor is the theory (the variant chain).
  • 0x2f is new: the variant key pool. A large per-variant key table indexed by the selector. Its entry count is nearly the selector space, one entry short of the full space, which is a property of the selector rather than a per-disc number. This is the pool the selector indexes into during the Media Key derivation.
  • 0x2d is new: per-disc variant seed. A smaller, structured record: the per-disc seed data that feeds the derivation. It is the least understood of the three. Call it structured per-disc seed data.
VersionMKB records for the Media Key
2.00x05 = Media Key, one encrypted value per subset
2.10x0c = Precursor, one value per subset (replaces 0x05); 0x2f = large variant key pool indexed by the selector; 0x2d = per-disc variant seed

The revocation tree these ride on is unchanged in kind from 2.0: the 0x04 Subset-Difference record plus the 0x05 / 0x07 cvalue records. The verify record is 0x86, as on all AACS 2.x.

These records are exclusive to 2.1, and that is now confirmed by measurement across a library of discs, not inferred from one. Every 2.0 disc checked lacks all three records. Only 2.1 discs carry them. And the two signals never disagree: the 2.1 MKB Type field (0x48151003) always coincides with the presence of the variant records, and the 2.0 type value never does. So detecting a 2.1 disc by its type field and detecting it by these records give the same answer every time.

Draw the line carefully here, because it is the crux of what is and is not known about 2.1. The structure is confirmed: which records exist, that they are 2.1-only, their internal shape, and the wrapped key-group table indexed by the selector. All of that is verified against real discs. What is still theory is the derivation: what those records do cryptographically, how a device’s keys pick and unwrap its key group to reach the Media Key. That is the Media Key Precursor model, and it has not been run end to end. The block is a test key database holding only per-disc VUKs, not device or processing keys, so there is no covering Processing Key to feed the chain and check against the 0x86 verify. Structure proven, derivation not yet executed.

Processing Key from the MKB walk walk Media Key Precursor 2.1 only · modeled + Variant Key Data + KCD constant Media Key verified by 0x86 on 1.0 / 2.0 the walk yields the Media Key directly (no Precursor) wrong derivation fails the verify, never emits a bad key

The point of the Precursor step is that different device groups arrive at different Media Keys for the same disc. That is the first of 2.1’s two traitor-tracing layers: the key you can derive already narrows down which player group you belong to.

On a normal Blu-ray or 2.0 UHD the main feature is a .m2ts file: an MPEG-2 transport stream of 192-byte source packets, one coherent version of the movie.

On a 2.1 disc the main feature is a .fmts file, BDMV/STREAM/00001.fmts. It is still a 192-byte transport stream, and everything that applies to M2TS applies here, but it carries interleaved variant segments: short stretches where the same frames are authored several slightly different ways. Only one variant is meant for any given player.

M2TS (Blu-ray, AACS 2.0 UHD) one coherent stream, decrypted with the Unit Key FMTS (UHD, AACS 2.1) variant segment: N variants, encrypted most of the stream is ordinary content under the Unit Key; the highlighted segments use per-segment keys, one variant per player

Two files in AACS/ describe the segments, and only 2.1 discs have them.

  • IndividualSegment.tbl, the segment map. Confirmed format, parsed against a retail disc: an 8-byte header (type, a segment count, record_size), then that many fixed-size records, each {marker, variant, flag, start_spn, end_spn}. The variant field is the forensic-variant tag, not a running index: measured on a retail 2.1 disc, 792 records of 16 bytes with the variant field cycling 1, 2, …, 32, 1, 2, … down the table in file order — 25 groups (24 full cycles of 32 plus a final partial cycle of 24), one record per variant per cycle. Each segment is a 2560-source-packet (~480 KB) range; start_spn increases monotonically down the table, the segments spread ~68 MB apart across the ~54 GB feature. The offsets are source-packet numbers, so a byte offset is spn * 192. The number of segments is not fixed by the scheme. It is an authoring choice: more segments means finer-grained tracing. The segments are spread across the whole feature rather than clustered.
  • SegmentKey00001.tbl, the per-segment variant keys. One per CPS unit, numbered. The container structure is confirmed by measurement: an 8-byte header (a selector count and a record_size) followed by one fixed-size record per value of the 16-bit selector. The header’s count field reads 0xffff, a sentinel for the full 65536-value selector space — measured on a retail 2.1 disc, 65536 records of 536 bytes each, which the total file size confirms exactly: 8 + 65536 × 536 = 35,127,304 bytes. A ~35 MB store. Each record opens with an 8-byte sub-header, then a 528-byte payload of high-entropy (encrypted) key material. The record’s internal layout is not yet reversed; 528 = 33 × 16 suggests 33 sixteen-byte slots, but that is an inference from the size, not a parsed structure. Either way it is a small fixed set, far fewer than the 792 segments in the feature. The record size itself is a fixed structural constant — a decoder validates the table by checking it against a constant — so it is the same on every 2.1 disc. That is the confirmed, structural half of the grouping model in Where the sizes come from: a device carries a handful of variant keys, not one per segment. How that key material maps onto the segments is a working model — within the store each forensic segment would carry a key per variant it is authored in, and a device uses the one matching its variant — but that mapping, and the cryptographic step that turns the Media Key Precursor and this stored material into a usable per-variant key, are both still open.

How a decoder finds the segments is worth stating, because it is not from the stream. A forensic unit carries the same encryption signature as any ordinary encrypted unit: the same CPI bits set, the same scrambled transport syncs. Inspecting the bitstream cannot tell a forensic unit apart from a normal one. The only locator is IndividualSegment.tbl. The decoder maps a unit’s byte offset against the segment ranges to decide whether that unit takes the ordinary Unit Key or a segment key. This is confirmed by measurement: units inside the segments are indistinguishable, by CPI and by sync state, from the encrypted content around them, so the map is not an optimization, it is the only way to route a unit correctly. The map carries more than positions. Each entry names a range of units, the segment group that range belongs to, and which variant that range is. So the interleaved variants are not merely present in the stream; the map spells out, range by range, which group and which variant each one holds, which is exactly what a decoder needs to select the right key for a given unit.

What the disc tells us: each segment’s variants are encrypted under segment keys, not the Unit Key. A player derives the key for exactly one variant per segment, and which variant it can decrypt is a fingerprint of that player. That is the second traitor-tracing layer, and it is the actual forensic watermark. A leaked rip carries, in which variants it contains, the identity of the machine that made it.

Those two routes are one decrypt path underneath. Whether a unit takes the ordinary Unit Key or a segment key, the decoder ends up holding a single per-unit content key and runs the same AES-CBC over the same 6144-byte aligned unit it runs on any encrypted unit. The paths differ in exactly one place: where that per-unit key comes from, the ordinary unit-key derivation or a segment-key derivation. The cipher does not change, the unit geometry does not change, and the choice between the two is made per unit by the segment map rather than by anything in the stream. The forensic path is not a second decryptor sitting below the Unit Keys. It is the ordinary decrypt with the key substituted for the units the map flags. The two key sources also differ in reach: the unit key covers a whole CPS content unit, while a segment key covers only its one forensic segment, and only for the device’s variant. The map decides, per unit, which of the two applies.

The per-unit content key is also deterministic. A compliant player derives it through an obfuscated computation, so the intermediate value it carries is randomized per session and differs from one play of the disc to the next. The key that derivation finally produces does not. For a fixed disc and a fixed unit the AES key is fixed, the same on every play, because the ciphertext on the disc is fixed and AES is deterministic. The obfuscation conceals how the key is reached, not the key itself.

Inside a segment: the interleave, confirmed by decode

Section titled “Inside a segment: the interleave, confirmed by decode”

A note on terms first, because two different things both get called “variant” loosely. The variant proper is the AACS 2.1 Media Key Variant — a device’s position in the 65536-value selector space (Layer 1, in the MKB), which decides which set of keys a device receives. That layer is not what a ripper touches. What the segment map deals with is the index: the 1..32 tag each IndividualSegment.tbl record carries, selecting one of 32 index keys. All 32 index keys belong to a single variant, whose number is unknown and irrelevant to the decode.

With a full set of the 32 index keys in hand, the inside of a segment can be read straight off the disc, and it is simpler than the ~35 MB key store suggests. Each IndividualSegment.tbl record spans 2560 source packets = 80 aligned units (6144 bytes each). Those 80 units are not uniform: they interleave in two stride-2 halves, 40 units each. Applying the segment’s index key — the key whose number equals the record’s index tag — decrypts one half to a full, clean transport stream (sync 0x47 restored on all 32 packets of each unit). The other half belongs to a different device group’s variant; freemkv never reads or decodes it — the segment map tells the reader which half is ours, so only our units are fetched, decrypted, and muxed. The index-1 segment’s units open under index key 1, the index-2 segment’s under key 2, and so on as the tag cycles 1..32 down the map. The second interleaved half is not yet identified.

Two facts fall out, both confirmed by decoding a retail disc:

  • The whole feature’s forensic content is covered by 32 index keys plus the ordinary Unit Key: one index key per tag, reused across every segment that carries that tag, and the Unit Key for the ~99% of the feature outside any segment. Measured, that is 40 of every segment’s 80 units decrypting cleanly under the tag’s key, the other 40 belonging to the second half.
  • A plausible reading of the earlier 32-versus-33 question is 33 = 32 index keys + 1 base (528 = 33 × 16). But that is an inference from the record size, not a parsed layout — the 528-byte record’s internals are not yet reversed. What is proven is that 32 index keys (obtained from a key source, not derived on-disc) decode the segments; how they sit inside the record is open.

Because the tag alone picks the key, a decoder needs nothing from the stream to route a forensic unit. It reads the segment’s index from IndividualSegment.tbl, applies index key = tag to the units the segment covers, and the Unit Key everywhere else — the same “map decides per unit” rule already described, now with the key selection pinned to a single field.

What is confirmed here is the structure and the mapping: given the 32 index keys, precisely which units open under which key, verified to full transport-stream sync on a retail disc and cross-checked against an independent key source that returns the same 32 keys from verified samples. What is still a working model is the derivation of those keys from SegmentKey00001.tbl and the Media Key Precursor — the open crypto step noted above — and the makeup of the second interleaved half.

The purpose of the segments is to watermark the leaker into the decoded video, not into the keys. The bulk of the movie decrypts with the ordinary Unit Key and is identical on every copy of the title. The forensic segments are the exception: each needs a variant segment key, and any given licensed device can decrypt only one variant per segment. Which one is fixed by that device’s place in the key tree, through the per-variant derivation below.

So every licensed device produces a subtly different decoded video. The movie is the same, but the specific variant chosen at each segment differs from device to device. That per-segment choice pattern is a fingerprint, like a barcode running the length of the film. One segment narrows the source. All the segments together pin the device group.

That is the reason the design exists. The identity is carried in the decoded frames themselves, so a leaked rip is self-incriminating. AACS can read the variant pattern out of a leaked file, map it back to the device group that must have produced it, and revoke that group in future MKBs, with the leaked video as the proof. It shifts enforcement from chasing leaked keys around the internet to reading the source device straight off the leaked frames. To be precise about the mechanism: nothing embeds a key or an ID into the picture. The frames reveal a device-determined selection pattern, one choice per segment, and that pattern is what identifies the source.

The two layers are joined at the Media Key Precursor. The same Kmp the MKB walk yields for standard content is also the input to the variant branch: run through the 2.1 variant algorithm (the 0x2f variant key data and the 0x2d seed), it produces a per-variant Media Key. That per-variant Media Key is the shared root of both forensic layers. In Layer 1 it is the variant media key the MKB’s 2.1-only variant records describe; in Layer 2 it cascades to a per-variant VUK and the per-segment keys in the content. One Precursor, one per-variant chain, driving both — there is no separate second secret and no separate block to walk.

Which variant a device lands on follows from its place in the subset-difference tree: its subset gives its Processing Key, its Processing Key gives its Kmp, and the variant branch off that Kmp is what fingerprints it. What is not yet demonstrated end to end is the crypto: with no covering Processing Key in hand, the exact algorithm from Kmp to the per-variant Media Key — and from the selected SegmentKey00001.tbl material to a working per-segment key — is still a working model.

The interesting property of this scheme is that a device holds only a small, fixed set of variant keys, yet that small set covers all the segments in a feature, and the on-disc key store is nonetheless enormous. Both facts follow from the same design, without needing any specific disc’s numbers.

Start from the segments. A title has some number of forensic segments. That count is an authoring choice, not a constant: more segments give finer-grained tracing. The size of a device’s key set is the opposite, a constant fixed by the format: the per-device record has one layout on every 2.1 disc, so the number of variant keys a device holds does not vary from title to title even as the segment count does. A device is not given one key per segment, that would not scale. Instead the segments are partitioned into groups, one group per variant key the device holds, so the device’s small key set covers every segment. Conceptually:

number of segments = (variant keys per device) x (segments per group)

the segments of one feature, partitioned into groups variant key 1 variant key 2 variant key 3 variant key 4 A device holds one key per group (four here). Its few keys together cover every segment. The disc stores a full key set for every possible device path, so the table dwarfs any one device's set. Illustrative, not to scale. Real features have far more segments and groups.

Now the on-disc key store. SegmentKey.tbl does not store one device’s keys. It stores a key set for every possible device path, one record per value of the selector, across the full selector space. So its size is not the per-device key count. Conceptually:

table size = (selector space) x (variant keys per device)

That is why the store is far larger than any one player needs. Every player reads only the one record its selector points at and holds only that set. Which set it holds is precisely its fingerprint. The table is large by design: it has to carry a distinct fingerprint for every device the scheme can address.

The decode requirement, and why this layer has teeth

Section titled “The decode requirement, and why this layer has teeth”

The two layers demand different keys, and that difference is the design’s teeth.

Standard content needs only the Unit Key. A Unit Key can come from a Volume Unique Key, which is what a key database supplies. No device keys are involved. That is why the bulk of a 2.1 movie decodes with only a VUK: it is enough for everything outside the forensic segments.

The forensic segments need the Media Key Precursor. The per-variant keys branch off Kmp — run through the 2.1 variant algorithm — and reaching Kmp needs the Processing Key from the ordinary MKB walk, an AACS-issued player credential. A leaked VUK or Unit Key sits below the Media Key; it never reaches the Precursor, so it never reaches the variant branch.

Two consequences follow, and they are the whole point of the design. First, the forensic layer cannot be bypassed with leaked disc keys alone. You need a real player’s device keys, meaning an actual player. Second, if you do rip with a real player’s keys, the output carries that player’s selection pattern, so the act of defeating the forensic layer is also the act of signing your name to the leak. Leaking disc keys does not defeat it. Leaking a player self-incriminates.

This is also exactly why an end-to-end 2.1 decode is blocked with disc keys alone. A key database of VUKs, with no covering Processing Key, decodes the bulk of the movie but cannot run the Precursor’s variant branch to the per-variant Media Key that unlocks the segments. The wall is not a missing algorithm, it is a missing class of key.

Putting the whole chain in one place. This is the working-model answer to “how do you get a segment key,” and it is one ladder, not two. The forensic keys branch off the Media Key Precursor — the same Kmp the MKB walk already produces for standard content.

Device Keys issued to a licensed player walk the MKB Processing Key read out the Precursor Media Key Precursor (Kmp) 2.1 only — the branch point standard variant branch: fold in the variant no., via 0x2f (VKD) + KCD Media Key per-variant Media Key Volume Unique Key per-variant VUK Unit Key per-variant Unit Key Ordinary content a VUK is enough to reach here Decrypt the forensic segment same AES-CBC over the aligned unit
The working model. One ladder: Device Keys walk the MKB to the Processing Key and the Media Key Precursor. Standard content descends the ordinary Media Key → VUK → Unit Key. The forensic segments branch off the same Precursor — through the 2.1 variant algorithm — into a per-variant Media Key → per-variant VUK → per-variant Unit Key. A VUK sits below the Media Key, so it reaches neither the Precursor nor the variant branch. The exact Precursor-to-variant step has not been run end to end.

The pivot to notice is that there is one player secret, not two: the Device Keys. The forensic system does not add a second key set — it adds a branch off the Media Key Precursor. The ordinary walk takes DK → PK → Kmp and, for standard content, Kmp → Media Key → VUK → Unit Key. The variant branch takes the same Kmp and runs it through the 2.1 variant algorithm (the 0x2f variant key data and 0x2d seed) to a per-variant Media Key, then a per-variant VUK and a per-variant Unit Key. Because a device’s Kmp depends on its place in the subset-difference tree, different devices arrive at different variants — which is exactly what fingerprints them. That chain settles who can and cannot reach a segment key:

  • A licensed player holds the Device Keys, so it walks to its Kmp and takes the variant branch to its own per-variant keys, one variant per segment, which is exactly what fingerprints it.
  • Someone holding a player’s extracted Device Keys can do the same, and their rip is fingerprinted too.
  • A ripper holding only a VUK or Unit Key cannot, because a VUK sits below the Media Key — it never reaches the Precursor, so it never reaches the variant branch. It decrypts the standard content and stops there.

There is no disc-key shortcut. The route runs through the Processing Key and the Media Key Precursor, a player-issued credential, before the variant branch can yield a per-variant Media Key and, from it, a segment key. Every 2.1 rip that clears the forensic layer walks that path, and walking it is what stamps the player’s identity into the result.

This is also why a straight rip is not enough on 2.1. The ordinary keys yield a decoded stream, but decrypting a variant segment with the ordinary Unit Key produces garbage. On a real 2.1 disc that shows up as HEVC reference-frame errors (Could not find ref with POC ...) exactly at the segment offsets. Handling FMTS correctly means decrypting each segment with its segment key and splicing one coherent variant back into a clean single-variant stream.

The container and the routing are settled: the segment map ties every unit range to its forensic index tag, and with the 32 index keys in hand the routing from a unit to the right key is confirmed and code-proven. The 528-byte SegmentKey record’s internal layout is not yet reversed — that a record holds 33 sixteen-byte slots is an inference (528 = 33 × 16), not a parsed fact. The open questions:

  1. The exact algorithm from the Media Key Precursor to the per-variant Media Key, and from the selected SegmentKey00001.tbl material to a working per-segment key. The layout is known; the cryptographic step is not.
  2. Whether the per-segment key set is one unmarked base version plus a fixed number of forensic variants. A plausible reading, not a confirmed fact.
  3. (Resolved on the decode side.) Writing one coherent variant per segment back to a clean, single-variant stream: freemkv reads only its own variant’s units — the segment map says which — so the alternate variant is never read or decoded and the output is clean. The remaining open step is the on-disc key derivation in (1).
ElementStatus
Key hierarchy (DK, PK, MK, VUK, UK) for 1.0 and 2.0Confirmed. Rips work end to end
Standard 2.1 content: decodes with a Unit Key (from a VUK, no device keys)Confirmed. Works today, bulk of the movie
Forensic 2.1 segments: the per-variant keys branch off the Media Key Precursor (needs the Processing Key), which a VUK never reachesConfirmed as the requirement. The wall: a keydb of VUKs stops at the Media Key
CPI (byte 0) encrypted-unit testConfirmed
Unit_Key_RO.inf stride: 48 (1.0), 64 (2.x)Confirmed
MKB record framing and record types 0x04 / 0x05 / 0x81 / 0x86Confirmed
0x05 Media Key Data: the Media Key wrapped once per subset, opened by that subset’s PKConfirmed. Implemented; every 2.0 disc decrypts through it
0x0c replaces 0x05 on 2.1 in the same per-subset shapeConfirmed. Structure, verified against real discs
That the 0x0c value is a Media Key Precursor (not the final Media Key)Theory. Derivation under investigation
MKB Type field to generation (0x00041003 / 0x48141003 / 0x48151003)Confirmed against retail discs
IndividualSegment.tbl formatConfirmed. Parses a retail disc
2.1 disc fingerprint: AACS/ carries IndividualSegment.tbl + SegmentKey00001.tblConfirmed on retail 2.1 discs
2.1 variant records 0x0c / 0x2d / 0x2f are exclusive to 2.1 (absent on 2.0)Confirmed. Structure, verified across a library of discs
MKB Type value and the variant records always agree (2.1 has both, 2.0 has neither)Confirmed. Structure, verified across a library of discs
The wrapped key-group table, indexed by the selector across the selector spaceConfirmed. Structure, verified against real discs
The Media Key Precursor step: how the records pick and unwrap a key groupTheory. Derivation under investigation, not yet executed (no covering Processing Key)
0x2d per-slot selection, nonce position, one field widthUnconfirmed. Needs a covering 2.1 key
SegmentKey.tbl container: file header + one fixed-size record per selector valueConfirmed against retail discs
A forensic unit is indistinguishable (CPI, sync state) from ordinary encrypted content; the segment map is the sole locatorConfirmed. Measured
Normal and forensic units share one decrypt path: the same AES-CBC over the same aligned unit, differing only in the key source (unit key vs segment key), routed per unit by the segment mapConfirmed. Measured
The per-unit content key is deterministic: a fixed function of (disc, unit), reproducible across plays, even though the derivation is obfuscatedConfirmed. Measured
The SegmentKey per-device record is a fixed-size structure defined by the format (record size checked against a constant), identical across 2.1 discsConfirmed. Code-proven (container + record size). The record’s internal key-set size is inferred (528 = 33 × 16), not parsed
The record payload is a small fixed key set, far fewer than the number of segments (the grouping); segment count is a per-disc authoring choice, the per-device key-set size is notConfirmed
The key store holds one key per variant for each forensic segment; a device uses the key matching its own variantInferred. The container geometry is measured, but the 528-byte record’s internal key layout is not yet reversed
The segment map ties each unit range to a segment group and a variant, not just to a locationConfirmed. Code-proven
The forensic keys branch off the Media Key Precursor (Kmp), not a second player secretWorking model. One player secret: the Device Keys
A device’s variant follows from its subset / Processing Key → its Media Key PrecursorWorking model. Not run end to end
The Precursor, run through the 0x2f / 0x2d variant algorithm, yields a per-variant Media Key; a different Kmp gives a different variant (traitor tracing)Working model
Content-key selection per unit: a normal unit uses the unit key (whole CPS unit), a forensic unit uses the segment key (one segment, the device’s variant), both feeding the same per-unit cipherConfirmed / spec
Link between the layers: one per-variant Media Key, from the Kmp variant branch, drives both the MKB variant data and the SegmentKey selectionWorking model. Not executed against our discs
The cryptographic derivation of a usable segment key from its stored key materialUnknown. Active work
Whether the per-segment key set is one unmarked base version plus forensic variantsTheory. A plausible reading, not confirmed
Variant selection back to a clean single-variant streamConfirmed. freemkv reads only its own variant’s units (the segment map decides which); the alternate variant is never read or decoded, so the muxed output is a clean, single-variant stream — verified on retail 2.1 discs