aacs: KeyProvider abstraction + PK walker + external-UK key source

Two coherent additions to the AACS resolver:

KeyProvider abstraction (provider.rs) — key material comes from pluggable
backends; KeyDb implements it (device/processing keys, host certs,
disc-by-hash / disc-by-vid lookup) plus orphan-DK parsing. ResolveContext
takes a provider array. Adds the SD-tree PK walker
(derive_media_key_from_pk_walked) and a `probe` module (km_verifies MK
oracle, mkb_* record parsers) used for offline key verification. Cvalue
record selection prefers 0x05, falls back to 0x07.

External-UK key source — the second, mutually-exclusive key source for the
keyserver path. ScanOptions/InputOptions gain `unit_key`; when set,
resolve_encryption_static skips keydb entirely and uses the caller-supplied
Unit Key directly (KeySource::ExternalUk). Disc::read_aacs_inputs exposes a
disc's Unit_Key_RO.inf + MKB so a caller can fetch the UK out-of-band; the
library makes no network call itself.

CHANGELOG: redact test-disc title in historical notes.
This commit is contained in:
MattJackson
2026-06-01 20:47:14 -07:00
parent c0478e1273
commit 8d54a3c64e
10 changed files with 785 additions and 90 deletions
+6 -5
View File
@@ -163,6 +163,9 @@ fn validate_network_addr(addr: &str) -> io::Result<()> {
#[derive(Default)]
pub struct InputOptions {
pub keydb_path: Option<String>,
/// Caller-supplied Unit Key (keyserver path) — the second, mutually
/// exclusive key source. Takes precedence over `keydb_path`.
pub unit_key: Option<[u8; 16]>,
pub title_index: Option<usize>,
/// Skip decryption — return raw encrypted bytes.
pub raw: bool,
@@ -181,11 +184,9 @@ pub fn input(url: &str, opts: &InputOptions) -> io::Result<Box<dyn crate::pes::S
}
StreamUrl::Iso { ref path } => {
validate_file_path(path, "iso")?;
let scan_opts = match &opts.keydb_path {
Some(p) => crate::disc::ScanOptions {
keydb_path: Some(p.into()),
},
None => crate::disc::ScanOptions::default(),
let scan_opts = crate::disc::ScanOptions {
keydb_path: opts.keydb_path.as_ref().map(Into::into),
unit_key: opts.unit_key,
};
// FileSectorSource is the sole file-backed sector source.
// It carries the platform-tuned SEQUENTIAL fadvise hint