The CSS (DVD-Video) bus-auth unlocker as a first-class external plugin, peer
to freemkv-unlock-ld. CssUnlocker impls libfreemkv::Unlocker — matches
DiscKind::Css, self-guards against the hardware (refuses NotApplicable without
issuing a CSS CDB if the drive reports a non-DVD profile), then runs the
libfreemkv bus-auth primitive (unlock_css_reads). libfreemkv keeps the bus-auth
+ keyless descramble; this crate owns the unlocker impl. Additive: a consuming
binary opts in with one register_unlocker(CssUnlocker::new()) line; the in-tree
built-in stays until clients are rewired.
LibreDrive::matches now requires ctx.kind == DiscKind::Unknown (the drive-prep
dispatch) in addition to a bundled-profile hit. This keeps the firmware unlock
from firing during the later content-keyed (Aacs/Css) dispatch on a profiled
drive — the registry is walked at one spot per phase and matches() is the only
filter.
libfreemkv's Unlocker trait now hands matches()/unlock()/set_max_read_speed()
an UnlockCtx instead of a bare DriveId. The firmware unlocker keys off
ctx.drive_id (disc kind is irrelevant to it).
libfreemkv's Unlocker::unlock now returns Unlocked { vid, read_data_key }
rather than a bare Vid. The firmware route serves clear content, so it
reports { vid: Some(oem_vid), read_data_key: None }.
- ld/Cargo.toml: pin libfreemkv = "=1.0.0-rc.4.3" (exact, fail-closed)
instead of the bare caret that accepted later 1.0.0 prereleases.
- ld/src/cdb.rs: replace the duplicate (2,0x44) assertion with a real
wrong-mode/right-buffer case (0,0x77) so the 'Wrong mode, right buffer
id' comment is actually exercised.
The variant-B firmware load hardcoded one drive's F1 vendor-verify token
and a fixed 0x9C0 firmware size. Across the 140 B drives the verify CDB
has 39 distinct per-drive values, and the real firmware length is encoded
in each drive's MODE SELECT CDB (2192..2528 bytes) — so the constants were
wrong for ~139 of 140 drives and truncated 13.
- DriveProfile gains fw_verify_cdb (the per-drive 0xF1 verify).
- variant_b uploads firmware.len() (now the correct per-drive size from
the regenerated profiles.json) and issues profile.fw_verify_cdb, falling
back to the const only for legacy profiles.
- profiles.json regenerated: 79 firmware fields corrected (13 truncated
recovered to full length, 66 over-reads trimmed).
- Adds a recording-transport regression test asserting the profile's F1
verify is issued (not the const) and MODE SELECT carries firmware.len().
Expose is_unlock_read_buffer() and UNLOCK_MARKER so consumers (bdemu)
can recognise and answer the LibreDrive unlock READ_BUFFER handshake
without open-coding the variant CDB shapes or the verification marker.
These handshake internals must live only in freemkv-unlock-ld.
Track libfreemkv's finalized 3-capability Unlocker trait:
- unlock(...) -> unlock_drive(...)
- read_vid(...) -> read_volume_id(...)
- add set_max_read_speed(...)
set_max_read_speed issues the matched profile's set_speed_max_cdb
(0xBB SET CD SPEED, to max) over the raw transport; a profile without a
set_speed_max_cdb (or no matching profile) is a no-op so the drive stays at
its current speed. read_disc_keys_cdb is left untouched — inert profile data,
never issued, no trait method.
README: document the 3-method contract, the delete-to-comply fallback, and the
#2-only boundary (freemkv uploads RAM microcode to an already-bootloader-flashed
drive; the permanent bootloader flash #1 is the owner's one-time manual step,
never automated). Left a marked MakeMKV attribution placeholder for the
maintainer to author.
Tests: renamed read_vid tests; added set_max_read_speed tests (issues the CDB
when present, no-op when the profile carries none).
Recover the per-drive READ_BUFFER OEM VID path that lived in libfreemkv
before the unlocker refactor (read_vid_oem in disc/encrypt.rs), now living
inside the unlocker where the per-drive read_vid_cdb template belongs.
read_vid finds the drive's profile; if it carries a read_vid_cdb, issues
it and parses the 36-byte response (signature 00 22 00, VID at [4..20]),
returning Some(vid). No matching profile or no OEM VID CDB returns Ok(None)
so libfreemkv falls back to the cert handshake. VID is thus obtained
without the host certificate + HRL.
Adds response-parse unit tests (well-formed, short response, bad header,
no-profile fallback).
New crate freemkv-unlock-ld — the LibreDrive Unlocker implementation,
split out of libfreemkv so the library stays firmware-clean on crates.io.
Owns everything about HOW MediaTek MT1959 drives are firmware-unlocked:
- profiles.json (the bundled drive-profile database + DriveProfile parse)
- src/platform/mt1959/* (variant-A/B firmware upload + unlock handshake)
- WRITE_BUFFER / MODE SELECT upload, unlock CDBs, disc-speed calibration
Exposes LibreDrive::new() implementing libfreemkv::Unlocker (name/matches/
unlock). Plug it in with one line at process start:
libfreemkv::register_unlocker(Box::new(freemkv_unlock_ld::LibreDrive::new()));
Depends on libfreemkv (path-patched via gitignored .cargo/config.toml in
dev) for the trait, ScsiTransport, DriveId, and Result. README notes it's
the LibreDrive unlocker (attribution to be added by owner).