unlock: add OEM read_vid capability to Unlocker seam

An Unlocker unlocks drive functionality, not just the disc: unlock() is
one capability, OEM VID retrieval is another. Widen the Unlocker trait
with a default-no-op read_vid(), add an unlocker_read_vid registry helper
that mirrors route_unlock resolution, and consult it in do_handshake_cert
before the cert-based VID read. A matching unlocker that serves a VID via
its OEM path short-circuits the cert handshake — VID is obtained without
the host certificate + HRL (restoring the pre-refactor decoupled OEM VID
path, now living inside the unlocker). Non-matching drives, and unlockers
without an OEM VID path, fall through to cert auth unchanged.

is_unlocked() now reports the honest signal (a registered unlocker matched
this drive) instead of const false.
This commit is contained in:
Matthew Jackson
2026-06-22 10:50:47 -07:00
parent 6dc62bcd84
commit 159e967760
3 changed files with 190 additions and 22 deletions
+9 -8
View File
@@ -573,15 +573,16 @@ impl Drive {
/// Whether libfreemkv should take the OEM extended-access read path.
///
/// The pluggable [`crate::unlock::Unlocker`] seam reports only
/// success/failure from `unlock()` — it carries no extended-access
/// marker back into libfreemkv. With no marker channel, libfreemkv
/// always uses the standard host-certificate AACS handshake to acquire
/// the Volume ID (the OEM route), so this is always `false`. A firmware
/// unlocker still removes riplock / enables BD-UHD reads at `init()`;
/// VID acquisition just stays on the cert path.
/// Whether a registered [`crate::unlock::Unlocker`] matches this drive.
///
/// An unlocker unlocks *drive functionality* — firmware unlock, OEM VID
/// retrieval, and other vendor capabilities. When one matches, libfreemkv
/// routes both `unlock` and OEM VID through it (VID via the OEM path is
/// decoupled from the host cert + HRL). This mirrors [`Self::has_profile`]
/// — the honest signal is "a registered unlocker claims this drive" —
/// rather than the old const `false`.
pub fn is_unlocked(&self) -> bool {
false
crate::unlock::matching_name(&self.drive_id).is_some()
}
/// Read sectors from the disc. Single-shot — no inline retries, no