v0.25.9: built-in AACS keys + plugin slot + MKB record-type fix

Two changes that make AACS 1.0 / DVD self-sufficient:

1. MKB record-type identification bug fix. `mkb_find_mk_dv` was
   searching for type 0x10 (which is Type-and-Version, 12 bytes)
   when the Verify Media Key Record is actually type 0x81 for
   AACS 1.0 or type 0x86 for AACS 2.0/2.1. `mkb_version` had the
   inverse bug. PK and DK derivation paths therefore silently
   failed on every disc, masking how often the fallback paths
   could have worked. Fix searches the correct types; tests added
   covering both the 0x81 and 0x86 verify-record forms and the
   0x10 version record at offset 8 of the body.

2. Built-in AACS keys + operator plugin slot. Four device keys
   (covering MKB v01-v82+) and three processing keys (covering
   v63-v68) compiled directly into the library. Combined with the
   31 CSS player keys already in css/auth.rs, DVDs and Blu-rays
   (AACS 1.0) now decrypt with zero external files. New plugin
   path at ~/.config/freemkv/local_keys.cfg (same syntax as
   keydb.cfg) layered additively on top of built-ins and main
   keydb. `Disc::scan` no longer errors when keydb.cfg is absent;
   AACS 2.0 / UHD still surfaces a specific error when the disc
   needs keys none of the layers provide.

Public docstrings in project docs + README updated to describe the
three additive layers (built-ins → keydb.cfg → local_keys.cfg).
This commit is contained in:
MattJackson
2026-05-20 09:00:32 -07:00
parent d7b5c30f5d
commit e635c9556f
10 changed files with 570 additions and 73 deletions
+10 -4
View File
@@ -157,14 +157,20 @@ impl Disc {
pub(super) fn resolve_encryption(
udf_fs: &udf::UdfFs,
reader: &mut dyn SectorSource,
keydb_path: &std::path::Path,
keydb_path: Option<&std::path::Path>,
handshake: Option<&HandshakeResult>,
) -> Result<AacsState> {
use crate::aacs::{self, KeyDb};
let keydb = KeyDb::load(keydb_path).map_err(|_| Error::KeydbLoad {
path: keydb_path.display().to_string(),
})?;
// Built-in AACS 1.0 keys are always available. When a keydb.cfg
// path is supplied, layer it on top; otherwise fall back to
// built-ins (plus the operator local-plugin slot, if any).
let keydb = match keydb_path {
Some(path) => KeyDb::load(path).map_err(|_| Error::KeydbLoad {
path: path.display().to_string(),
})?,
None => KeyDb::load_or_builtins(),
};
// Read AACS files from disc/image via UDF
let uk_ro_data = udf_fs