aacs: point integration tests at real module paths
The facade removal (5ff0464) left tests/ calling aacs::disc_hash,
aacs::decrypt_unit, aacs::AacsVersion, etc. at the old flat paths,
so the branch did not compile its integration tests. Repoint each
to its real module (inf/derive/content/mkb). No logic change.
This commit is contained in:
+41
-41
@@ -84,9 +84,9 @@ fn aacs_decrypt_unit_roundtrip() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
// Build plaintext unit with TS sync bytes every 192 bytes starting at offset 4
|
// Build plaintext unit with TS sync bytes every 192 bytes starting at offset 4
|
||||||
let mut plain = vec![0u8; aacs::ALIGNED_UNIT_LEN];
|
let mut plain = vec![0u8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
let mut offset = 4;
|
let mut offset = 4;
|
||||||
while offset < aacs::ALIGNED_UNIT_LEN {
|
while offset < aacs::content::ALIGNED_UNIT_LEN {
|
||||||
plain[offset] = 0x47; // TS sync byte
|
plain[offset] = 0x47; // TS sync byte
|
||||||
offset += 192;
|
offset += 192;
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ fn aacs_decrypt_unit_roundtrip() {
|
|||||||
// Step 3: AES-CBC encrypt bytes 16..6144
|
// Step 3: AES-CBC encrypt bytes 16..6144
|
||||||
let cipher = Aes128::new(GenericArray::from_slice(&encrypt_key));
|
let cipher = Aes128::new(GenericArray::from_slice(&encrypt_key));
|
||||||
let mut prev = aacs_iv;
|
let mut prev = aacs_iv;
|
||||||
let num_blocks = (aacs::ALIGNED_UNIT_LEN - 16) / 16;
|
let num_blocks = (aacs::content::ALIGNED_UNIT_LEN - 16) / 16;
|
||||||
for i in 0..num_blocks {
|
for i in 0..num_blocks {
|
||||||
let off = 16 + i * 16;
|
let off = 16 + i * 16;
|
||||||
for j in 0..16 {
|
for j in 0..16 {
|
||||||
@@ -131,29 +131,29 @@ fn aacs_decrypt_unit_roundtrip() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify it looks encrypted (body TS syncs scrambled)
|
// Verify it looks encrypted (body TS syncs scrambled)
|
||||||
assert!(aacs::ts_sync_destroyed(&plain));
|
assert!(aacs::content::ts_sync_destroyed(&plain));
|
||||||
|
|
||||||
// Now decrypt
|
// Now decrypt
|
||||||
let result = aacs::decrypt_unit(&mut plain, &unit_key);
|
let result = aacs::content::decrypt_unit(&mut plain, &unit_key);
|
||||||
assert!(
|
assert!(
|
||||||
result,
|
result,
|
||||||
"decrypt_unit should return true on valid encrypted unit"
|
"decrypt_unit should return true on valid encrypted unit"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
!aacs::ts_sync_destroyed(&plain),
|
!aacs::content::ts_sync_destroyed(&plain),
|
||||||
"decrypted unit should read as clear (TS syncs restored)"
|
"decrypted unit should read as clear (TS syncs restored)"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Verify TS sync bytes at expected positions (flag byte is cleared by decrypt)
|
// Verify TS sync bytes at expected positions (flag byte is cleared by decrypt)
|
||||||
let mut sync_count = 0;
|
let mut sync_count = 0;
|
||||||
let mut off = 4;
|
let mut off = 4;
|
||||||
while off < aacs::ALIGNED_UNIT_LEN {
|
while off < aacs::content::ALIGNED_UNIT_LEN {
|
||||||
if plain[off] == 0x47 {
|
if plain[off] == 0x47 {
|
||||||
sync_count += 1;
|
sync_count += 1;
|
||||||
}
|
}
|
||||||
off += 192;
|
off += 192;
|
||||||
}
|
}
|
||||||
let expected_syncs = (aacs::ALIGNED_UNIT_LEN - 4) / 192 + 1;
|
let expected_syncs = (aacs::content::ALIGNED_UNIT_LEN - 4) / 192 + 1;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
sync_count, expected_syncs,
|
sync_count, expected_syncs,
|
||||||
"TS sync bytes not recovered: got {}, expected {}",
|
"TS sync bytes not recovered: got {}, expected {}",
|
||||||
@@ -176,11 +176,11 @@ fn aacs_disc_hash_deterministic() {
|
|||||||
let data1 = b"Unit_Key_RO.inf test data for deterministic hashing";
|
let data1 = b"Unit_Key_RO.inf test data for deterministic hashing";
|
||||||
let data2 = b"Different data should produce different hash";
|
let data2 = b"Different data should produce different hash";
|
||||||
|
|
||||||
let hash1a = aacs::disc_hash(data1);
|
let hash1a = aacs::inf::disc_hash(data1);
|
||||||
let hash1b = aacs::disc_hash(data1);
|
let hash1b = aacs::inf::disc_hash(data1);
|
||||||
assert_eq!(hash1a, hash1b, "disc_hash not deterministic on same input");
|
assert_eq!(hash1a, hash1b, "disc_hash not deterministic on same input");
|
||||||
|
|
||||||
let hash2 = aacs::disc_hash(data2);
|
let hash2 = aacs::inf::disc_hash(data2);
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
hash1a, hash2,
|
hash1a, hash2,
|
||||||
"different inputs should produce different hashes"
|
"different inputs should produce different hashes"
|
||||||
@@ -190,7 +190,7 @@ fn aacs_disc_hash_deterministic() {
|
|||||||
assert_eq!(hash1a.len(), 20);
|
assert_eq!(hash1a.len(), 20);
|
||||||
|
|
||||||
// Verify disc_hash_hex formatting
|
// Verify disc_hash_hex formatting
|
||||||
let hex = aacs::disc_hash_hex(&hash1a);
|
let hex = aacs::inf::disc_hash_hex(&hash1a);
|
||||||
assert!(hex.starts_with("0x"), "hex should start with 0x prefix");
|
assert!(hex.starts_with("0x"), "hex should start with 0x prefix");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
hex.len(),
|
hex.len(),
|
||||||
@@ -225,7 +225,7 @@ fn aacs_decrypt_unit_key_roundtrip() {
|
|||||||
encrypted_uk.copy_from_slice(&block);
|
encrypted_uk.copy_from_slice(&block);
|
||||||
|
|
||||||
// Decrypt with the public API
|
// Decrypt with the public API
|
||||||
let decrypted = aacs::decrypt_unit_key(&vuk, &encrypted_uk);
|
let decrypted = aacs::derive::decrypt_unit_key(&vuk, &encrypted_uk);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
decrypted, original_unit_key,
|
decrypted, original_unit_key,
|
||||||
"decrypt_unit_key did not recover original unit key"
|
"decrypt_unit_key did not recover original unit key"
|
||||||
@@ -246,7 +246,7 @@ fn aacs_vuk_derivation_roundtrip() {
|
|||||||
0x30,
|
0x30,
|
||||||
];
|
];
|
||||||
|
|
||||||
let vuk = aacs::derive_vuk(&media_key, &volume_id);
|
let vuk = aacs::derive::derive_vuk(&media_key, &volume_id);
|
||||||
|
|
||||||
// VUK should be non-zero and different from both inputs
|
// VUK should be non-zero and different from both inputs
|
||||||
assert_ne!(vuk, [0u8; 16], "VUK should not be all zeros");
|
assert_ne!(vuk, [0u8; 16], "VUK should not be all zeros");
|
||||||
@@ -254,7 +254,7 @@ fn aacs_vuk_derivation_roundtrip() {
|
|||||||
assert_ne!(vuk, volume_id, "VUK should differ from volume_id");
|
assert_ne!(vuk, volume_id, "VUK should differ from volume_id");
|
||||||
|
|
||||||
// Verify determinism
|
// Verify determinism
|
||||||
let vuk2 = aacs::derive_vuk(&media_key, &volume_id);
|
let vuk2 = aacs::derive::derive_vuk(&media_key, &volume_id);
|
||||||
assert_eq!(vuk, vuk2, "derive_vuk not deterministic");
|
assert_eq!(vuk, vuk2, "derive_vuk not deterministic");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,14 +263,14 @@ fn aacs_vuk_derivation_roundtrip() {
|
|||||||
fn aacs_ts_sync_destroyed_detection() {
|
fn aacs_ts_sync_destroyed_detection() {
|
||||||
// A clear unit: TS sync (0x47) intact at every 192-byte packet → not
|
// A clear unit: TS sync (0x47) intact at every 192-byte packet → not
|
||||||
// scrambled. (Flag bits play no role.)
|
// scrambled. (Flag bits play no role.)
|
||||||
let mut clear = vec![0u8; aacs::ALIGNED_UNIT_LEN];
|
let mut clear = vec![0u8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
let mut off = 4;
|
let mut off = 4;
|
||||||
while off < aacs::ALIGNED_UNIT_LEN {
|
while off < aacs::content::ALIGNED_UNIT_LEN {
|
||||||
clear[off] = 0x47;
|
clear[off] = 0x47;
|
||||||
off += 192;
|
off += 192;
|
||||||
}
|
}
|
||||||
assert!(
|
assert!(
|
||||||
!aacs::ts_sync_destroyed(&clear),
|
!aacs::content::ts_sync_destroyed(&clear),
|
||||||
"clear unit (syncs intact) must not be scrambled"
|
"clear unit (syncs intact) must not be scrambled"
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -279,21 +279,21 @@ fn aacs_ts_sync_destroyed_detection() {
|
|||||||
flagged[0] = 0xC0; // copy-control bits
|
flagged[0] = 0xC0; // copy-control bits
|
||||||
flagged[7] = 0xC0; // TSC bits
|
flagged[7] = 0xC0; // TSC bits
|
||||||
assert!(
|
assert!(
|
||||||
!aacs::ts_sync_destroyed(&flagged),
|
!aacs::content::ts_sync_destroyed(&flagged),
|
||||||
"flag bits must not be read as encryption"
|
"flag bits must not be read as encryption"
|
||||||
);
|
);
|
||||||
|
|
||||||
// A scrambled body (syncs destroyed) → scrambled.
|
// A scrambled body (syncs destroyed) → scrambled.
|
||||||
let scrambled = vec![0x99u8; aacs::ALIGNED_UNIT_LEN];
|
let scrambled = vec![0x99u8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
assert!(
|
assert!(
|
||||||
aacs::ts_sync_destroyed(&scrambled),
|
aacs::content::ts_sync_destroyed(&scrambled),
|
||||||
"unit with no intact TS syncs must read as scrambled"
|
"unit with no intact TS syncs must read as scrambled"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Too short
|
// Too short
|
||||||
let short = vec![0xFFu8; 100];
|
let short = vec![0xFFu8; 100];
|
||||||
assert!(
|
assert!(
|
||||||
!aacs::ts_sync_destroyed(&short),
|
!aacs::content::ts_sync_destroyed(&short),
|
||||||
"short buffer should not be detected"
|
"short buffer should not be detected"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -303,10 +303,10 @@ fn aacs_ts_sync_destroyed_detection() {
|
|||||||
/// A clear unit (TS syncs intact) should pass through decrypt_unit unchanged.
|
/// A clear unit (TS syncs intact) should pass through decrypt_unit unchanged.
|
||||||
#[test]
|
#[test]
|
||||||
fn aacs_decrypt_unit_unencrypted_passthrough() {
|
fn aacs_decrypt_unit_unencrypted_passthrough() {
|
||||||
let mut unit = vec![0x42u8; aacs::ALIGNED_UNIT_LEN];
|
let mut unit = vec![0x42u8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
// Intact TS syncs every 192 bytes → not scrambled → passthrough.
|
// Intact TS syncs every 192 bytes → not scrambled → passthrough.
|
||||||
let mut off = 4;
|
let mut off = 4;
|
||||||
while off < aacs::ALIGNED_UNIT_LEN {
|
while off < aacs::content::ALIGNED_UNIT_LEN {
|
||||||
unit[off] = 0x47;
|
unit[off] = 0x47;
|
||||||
off += 192;
|
off += 192;
|
||||||
}
|
}
|
||||||
@@ -315,8 +315,8 @@ fn aacs_decrypt_unit_unencrypted_passthrough() {
|
|||||||
let original = unit.clone();
|
let original = unit.clone();
|
||||||
let key = [0xAA; 16];
|
let key = [0xAA; 16];
|
||||||
|
|
||||||
assert!(!aacs::ts_sync_destroyed(&unit));
|
assert!(!aacs::content::ts_sync_destroyed(&unit));
|
||||||
let result = aacs::decrypt_unit(&mut unit, &key);
|
let result = aacs::content::decrypt_unit(&mut unit, &key);
|
||||||
assert!(result, "clear unit should return true");
|
assert!(result, "clear unit should return true");
|
||||||
assert_eq!(unit, original, "clear unit should be unchanged");
|
assert_eq!(unit, original, "clear unit should be unchanged");
|
||||||
}
|
}
|
||||||
@@ -370,17 +370,17 @@ fn aacs_cross_validation_encrypt_then_decrypt() {
|
|||||||
0x10,
|
0x10,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut plaintext = vec![0u8; aacs::ALIGNED_UNIT_LEN];
|
let mut plaintext = vec![0u8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
// TS sync bytes every 192 bytes starting at offset 4
|
// TS sync bytes every 192 bytes starting at offset 4
|
||||||
let mut off = 4;
|
let mut off = 4;
|
||||||
while off < aacs::ALIGNED_UNIT_LEN {
|
while off < aacs::content::ALIGNED_UNIT_LEN {
|
||||||
plaintext[off] = 0x47;
|
plaintext[off] = 0x47;
|
||||||
off += 192;
|
off += 192;
|
||||||
}
|
}
|
||||||
// Fill the rest with a recognisable pattern (prime modulus avoids artefacts).
|
// Fill the rest with a recognisable pattern (prime modulus avoids artefacts).
|
||||||
// Index-arithmetic — clearer with a counted loop than an enumerate chain.
|
// Index-arithmetic — clearer with a counted loop than an enumerate chain.
|
||||||
#[allow(clippy::needless_range_loop)]
|
#[allow(clippy::needless_range_loop)]
|
||||||
for i in 16..aacs::ALIGNED_UNIT_LEN {
|
for i in 16..aacs::content::ALIGNED_UNIT_LEN {
|
||||||
if plaintext[i] == 0 {
|
if plaintext[i] == 0 {
|
||||||
plaintext[i] = (i % 251) as u8;
|
plaintext[i] = (i % 251) as u8;
|
||||||
}
|
}
|
||||||
@@ -402,7 +402,7 @@ fn aacs_cross_validation_encrypt_then_decrypt() {
|
|||||||
ref_aes_cbc_encrypt(
|
ref_aes_cbc_encrypt(
|
||||||
&dk,
|
&dk,
|
||||||
&CROSS_AACS_IV,
|
&CROSS_AACS_IV,
|
||||||
&mut plaintext[16..aacs::ALIGNED_UNIT_LEN],
|
&mut plaintext[16..aacs::content::ALIGNED_UNIT_LEN],
|
||||||
);
|
);
|
||||||
|
|
||||||
// Sanity: ciphertext should differ
|
// Sanity: ciphertext should differ
|
||||||
@@ -413,7 +413,7 @@ fn aacs_cross_validation_encrypt_then_decrypt() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// -- Decrypt with the library --
|
// -- Decrypt with the library --
|
||||||
let ok = aacs::decrypt_unit(&mut plaintext, &unit_key);
|
let ok = aacs::content::decrypt_unit(&mut plaintext, &unit_key);
|
||||||
assert!(
|
assert!(
|
||||||
ok,
|
ok,
|
||||||
"decrypt_unit returned false (TS sync verification failed)"
|
"decrypt_unit returned false (TS sync verification failed)"
|
||||||
@@ -436,9 +436,9 @@ fn aacs_cross_validation_alternate_key() {
|
|||||||
0x08,
|
0x08,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut plaintext = vec![0xFFu8; aacs::ALIGNED_UNIT_LEN];
|
let mut plaintext = vec![0xFFu8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
let mut off = 4;
|
let mut off = 4;
|
||||||
while off < aacs::ALIGNED_UNIT_LEN {
|
while off < aacs::content::ALIGNED_UNIT_LEN {
|
||||||
plaintext[off] = 0x47;
|
plaintext[off] = 0x47;
|
||||||
off += 192;
|
off += 192;
|
||||||
}
|
}
|
||||||
@@ -455,10 +455,10 @@ fn aacs_cross_validation_alternate_key() {
|
|||||||
ref_aes_cbc_encrypt(
|
ref_aes_cbc_encrypt(
|
||||||
&dk,
|
&dk,
|
||||||
&CROSS_AACS_IV,
|
&CROSS_AACS_IV,
|
||||||
&mut plaintext[16..aacs::ALIGNED_UNIT_LEN],
|
&mut plaintext[16..aacs::content::ALIGNED_UNIT_LEN],
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(aacs::decrypt_unit(&mut plaintext, &unit_key));
|
assert!(aacs::content::decrypt_unit(&mut plaintext, &unit_key));
|
||||||
|
|
||||||
// Decryption clears no flag, so the unit round-trips byte-for-byte.
|
// Decryption clears no flag, so the unit round-trips byte-for-byte.
|
||||||
assert_eq!(&plaintext[..], &expected[..]);
|
assert_eq!(&plaintext[..], &expected[..]);
|
||||||
@@ -473,15 +473,15 @@ fn aacs_bus_decrypt_cross_validation() {
|
|||||||
0x00,
|
0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
let mut plaintext = vec![0u8; aacs::ALIGNED_UNIT_LEN];
|
let mut plaintext = vec![0u8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
#[allow(clippy::needless_range_loop)]
|
#[allow(clippy::needless_range_loop)]
|
||||||
for i in 0..aacs::ALIGNED_UNIT_LEN {
|
for i in 0..aacs::content::ALIGNED_UNIT_LEN {
|
||||||
plaintext[i] = ((i * 3 + 17) & 0xFF) as u8;
|
plaintext[i] = ((i * 3 + 17) & 0xFF) as u8;
|
||||||
}
|
}
|
||||||
let expected = plaintext.clone();
|
let expected = plaintext.clone();
|
||||||
|
|
||||||
// Encrypt per-sector: AES-CBC encrypt bytes 16..2048 of each 2048-byte sector
|
// Encrypt per-sector: AES-CBC encrypt bytes 16..2048 of each 2048-byte sector
|
||||||
for sector_start in (0..aacs::ALIGNED_UNIT_LEN).step_by(2048) {
|
for sector_start in (0..aacs::content::ALIGNED_UNIT_LEN).step_by(2048) {
|
||||||
ref_aes_cbc_encrypt(
|
ref_aes_cbc_encrypt(
|
||||||
&read_data_key,
|
&read_data_key,
|
||||||
&CROSS_AACS_IV,
|
&CROSS_AACS_IV,
|
||||||
@@ -490,7 +490,7 @@ fn aacs_bus_decrypt_cross_validation() {
|
|||||||
}
|
}
|
||||||
assert_ne!(&plaintext[16..32], &expected[16..32]);
|
assert_ne!(&plaintext[16..32], &expected[16..32]);
|
||||||
|
|
||||||
aacs::decrypt_bus(&mut plaintext, &read_data_key);
|
aacs::content::decrypt_bus(&mut plaintext, &read_data_key);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
plaintext, expected,
|
plaintext, expected,
|
||||||
"bus decrypt did not recover original plaintext"
|
"bus decrypt did not recover original plaintext"
|
||||||
@@ -738,7 +738,7 @@ fn aacs_parse_unit_key_ro_minimal() {
|
|||||||
data[key_pos + i] = (0xA0 + i) as u8;
|
data[key_pos + i] = (0xA0 + i) as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = aacs::parse_unit_key_ro(&data, aacs::AacsVersion::V10);
|
let result = aacs::inf::parse_unit_key_ro(&data, aacs::mkb::AacsVersion::V10);
|
||||||
assert!(
|
assert!(
|
||||||
result.is_some(),
|
result.is_some(),
|
||||||
"parse_unit_key_ro should succeed on valid data"
|
"parse_unit_key_ro should succeed on valid data"
|
||||||
@@ -751,6 +751,6 @@ fn aacs_parse_unit_key_ro_minimal() {
|
|||||||
assert_eq!(ukf.disc_hash.len(), 20);
|
assert_eq!(ukf.disc_hash.len(), 20);
|
||||||
|
|
||||||
// disc_hash should be deterministic
|
// disc_hash should be deterministic
|
||||||
let hash = aacs::disc_hash(&data);
|
let hash = aacs::inf::disc_hash(&data);
|
||||||
assert_eq!(ukf.disc_hash, hash);
|
assert_eq!(ukf.disc_hash, hash);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use libfreemkv::{aacs, decrypt::DecryptKeys};
|
|||||||
#[test]
|
#[test]
|
||||||
fn decrypt_sectors_with_aacs_keys_works() {
|
fn decrypt_sectors_with_aacs_keys_works() {
|
||||||
// Build an encrypted aligned unit
|
// Build an encrypted aligned unit
|
||||||
let mut unit = vec![0xFFu8; aacs::ALIGNED_UNIT_LEN];
|
let mut unit = vec![0xFFu8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
|
|
||||||
// Set encryption flag (bits 6-7 of byte 0)
|
// Set encryption flag (bits 6-7 of byte 0)
|
||||||
unit[0] |= 0xC0;
|
unit[0] |= 0xC0;
|
||||||
@@ -19,7 +19,7 @@ fn decrypt_sectors_with_aacs_keys_works() {
|
|||||||
for (i, byte) in unit
|
for (i, byte) in unit
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.take(aacs::ALIGNED_UNIT_LEN)
|
.take(aacs::content::ALIGNED_UNIT_LEN)
|
||||||
.skip(1)
|
.skip(1)
|
||||||
{
|
{
|
||||||
*byte = ((i * 3 + 7) & 0xFF) as u8;
|
*byte = ((i * 3 + 7) & 0xFF) as u8;
|
||||||
@@ -28,7 +28,7 @@ fn decrypt_sectors_with_aacs_keys_works() {
|
|||||||
let unit_key: [u8; 16] = [0xAAu8; 16];
|
let unit_key: [u8; 16] = [0xAAu8; 16];
|
||||||
|
|
||||||
// Encrypt the unit using AACS algorithm
|
// Encrypt the unit using AACS algorithm
|
||||||
aacs::decrypt_unit(&mut unit, &unit_key); // decrypt_unit is idempotent on already-encrypted data
|
aacs::content::decrypt_unit(&mut unit, &unit_key); // decrypt_unit is idempotent on already-encrypted data
|
||||||
|
|
||||||
// Now we have encrypted data - create DecryptKeys with actual keys
|
// Now we have encrypted data - create DecryptKeys with actual keys
|
||||||
let mut keys = DecryptKeys::Aacs {
|
let mut keys = DecryptKeys::Aacs {
|
||||||
@@ -83,23 +83,23 @@ fn decrypt_sectors_with_css_keys_works() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn aacs_encryption_flag_detection() {
|
fn aacs_encryption_flag_detection() {
|
||||||
// A clear unit: TS syncs (0x47) intact at every 192-byte packet.
|
// A clear unit: TS syncs (0x47) intact at every 192-byte packet.
|
||||||
let mut unit = vec![0u8; aacs::ALIGNED_UNIT_LEN];
|
let mut unit = vec![0u8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
let mut off = 4;
|
let mut off = 4;
|
||||||
while off < aacs::ALIGNED_UNIT_LEN {
|
while off < aacs::content::ALIGNED_UNIT_LEN {
|
||||||
unit[off] = 0x47;
|
unit[off] = 0x47;
|
||||||
off += 192;
|
off += 192;
|
||||||
}
|
}
|
||||||
// Encryption is the scrambled body (TS syncs destroyed), NOT a flag bit.
|
// Encryption is the scrambled body (TS syncs destroyed), NOT a flag bit.
|
||||||
assert!(!aacs::ts_sync_destroyed(&unit));
|
assert!(!aacs::content::ts_sync_destroyed(&unit));
|
||||||
|
|
||||||
// Flag bits on a synced unit do not make it look encrypted.
|
// Flag bits on a synced unit do not make it look encrypted.
|
||||||
unit[0] = 0xC0;
|
unit[0] = 0xC0;
|
||||||
unit[7] = 0xC0;
|
unit[7] = 0xC0;
|
||||||
assert!(!aacs::ts_sync_destroyed(&unit));
|
assert!(!aacs::content::ts_sync_destroyed(&unit));
|
||||||
|
|
||||||
// Scrambled body (syncs gone) → encrypted.
|
// Scrambled body (syncs gone) → encrypted.
|
||||||
let scrambled = vec![0x99u8; aacs::ALIGNED_UNIT_LEN];
|
let scrambled = vec![0x99u8; aacs::content::ALIGNED_UNIT_LEN];
|
||||||
assert!(aacs::ts_sync_destroyed(&scrambled));
|
assert!(aacs::content::ts_sync_destroyed(&scrambled));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test: DecryptKeys::is_encrypted() correctly identifies encrypted state.
|
/// Test: DecryptKeys::is_encrypted() correctly identifies encrypted state.
|
||||||
|
|||||||
Reference in New Issue
Block a user