Promote AACS unit encryption to real API, and assert decrypt byte-exactly
encrypt_unit becomes public library API rather than a #[cfg(test)] helper.
Authoring an encrypted disc image is a legitimate use of this crate, and
the capability was already written four times over: a pub(crate) test-only
copy in aacs/content.rs plus three hand-rolled duplicates in decrypt.rs,
sector/decrypting.rs and disc/extract.rs. All four now call one function,
removing ~110 lines of duplicated cipher code that could drift from
decrypt_unit independently.
It mirrors decrypt_unit's purity contract: crypto only, no encrypted-flag
handling, because where that flag lives is container-specific (CPI bits in
byte 0 for BD-TS, elsewhere for HD-DVD-PS). Callers set the flag BEFORE
encrypting — bytes 0..16 are the key seed left in plaintext, so touching a
header byte afterwards changes the key a decryptor derives. That footgun is
documented at the function and at every call site.
Two tests pin it: an exact round trip through both directions, and the one
place the pair is deliberately asymmetric — decrypt_unit restores
all-zero-on-disc packets to zero, and the test proves an all-zero plaintext
packet enciphers to non-zero bytes so it is never mistaken for padding.
That asymmetry was previously only prose.
Two decrypt tests were also weaker than their own names:
* aacs_clear_trailing_partial_passes_through asserted only is_ok(), so a
mutant corrupting the clear partial while returning Ok passed. It now
snapshots the buffer and asserts byte equality, matching the
none_keys_is_noop pattern already in the file.
* aacs_decorator_decrypts_encrypted_unit_via_map checked only that 0x47
reappeared at the 192-byte stride, leaving corruption in the other 6112
bytes undetected. The plaintext is fully known, so it now asserts
byte-exact recovery against it.
Both were verified red first by mutating the production path.
This commit is contained in:
+3
-1
@@ -1523,7 +1523,9 @@ mod tests {
|
||||
let pkt = bdts_data_packet(0x1100, true, &audio_pes(&es));
|
||||
let mut unit = vec![0u8; 3 * 2048]; // one 6144-byte aligned unit
|
||||
unit[..192].copy_from_slice(&pkt);
|
||||
crate::aacs::content::aacs_encrypt_unit_for_test(&mut unit, unit_key);
|
||||
// Flag encrypted BEFORE encrypting: bytes 0..16 are the key seed.
|
||||
unit[0] |= 0xC0;
|
||||
crate::aacs::content::encrypt_unit(&mut unit, unit_key);
|
||||
unit
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -2640,7 +2640,9 @@ mod tests {
|
||||
}
|
||||
off += 192;
|
||||
}
|
||||
crate::aacs::content::aacs_encrypt_unit_for_test(&mut u, key);
|
||||
// Flag encrypted BEFORE encrypting: bytes 0..16 are the key seed.
|
||||
u[0] |= 0xC0;
|
||||
crate::aacs::content::encrypt_unit(&mut u, key);
|
||||
u
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user