Files
libfreemkv/docs/key-provider.md
T
Matthew Jackson 6e14fc0c0c libfreemkv: 1.7.0 groundwork — sector-recycle soundness + CI hardening
Security
- Remove the unsafe Vec::set_len over recycled sector buffers — UB reachable
  from safe code (GHSA-j8ww-f5fg-9pmh, low). Uses Vec::resize; pooling unchanged.

CI / tooling
- clippy on stable with the MSRV single-sourced from Cargo.toml; cargo-deny
  dependency-audit gate with first-party git sources allowed (#15); audience-based
  comment-guard (#17).

Docs
- README (keydb ownership, BD-J parser count), drive-access transport/reset
  notes, mux timeline module-doc links.
2026-09-02 12:40:55 -07:00

3.2 KiB

KeyProvider (src/aacs/provider.rs)

Long-form notes for src/aacs/provider.rs, relocated from doc comments to stay under the comment-guard caps. See the module's own (trimmed) //! doc for the short version.

Method flavors

KeyProvider methods come in two flavors:

  • Bulk material (device_keys, processing_keys, media_keys) — the resolver unions (and dedups) results across all providers and tries each candidate.
  • Disc-keyed lookup (lookup_disc_by_hash, lookup_disc_by_vid) — the resolver short-circuits on the first hit, so providers are queried in array order with fastest/closest first.

host_certs is a sixth method but is NOT consumed by the resolver chain: the SCSI handshake reads host certs directly from the caller-supplied credentials, not from the provider array. A provider that overrides host_certs today has no effect on the handshake; the method is retained as a forward-looking extension point only. Correspondingly, Providers::host_certs (the union helper) is #[allow(dead_code)] and unused by the resolver chain today.

Default impls return empty / None so backends only override the methods they actually support — an external key service might implement only lookup_disc_by_hash, while a local file might implement all six.

Calls may block (disk I/O, network round-trips). The resolver invokes each method at most a handful of times per scan; for per-disc memoization, implementations should cache internally.

Providers (resolver-side aggregation helper)

The resolver wraps ctx.providers (&[&dyn KeyProvider]) in Providers; its methods apply the union-vs-short-circuit policy described above per method. The bulk unions dedup so overlapping providers don't make the resolver re-walk/re-validate identical material.

SuppliedKey (bridge for Disc::decrypt_with)

A KeyProvider backed by a single caller-supplied key's raw material — the bridge for crate::disc::Disc::decrypt_with.

The application's key source did the lookup and handed in material at one level (DK / PK / MK / VUK). This exposes exactly that material to the version-dispatched resolver, which owns ALL derivation — so a source never derives, and the lib remains the single home for the AACS chain across 1.0 / 2.0 / 2.1 / 2.x.

Each level fills only its own field; the rest stay empty, so the resolver naturally runs the matching path (DK→…, PK→…, MK-pool brute, or a disc-keyed VUK hit). decrypt_with already knows the disc, so the lookup_disc_by_* hash/VID arguments are irrelevant — a present disc_entry is returned for any query.

Test: providers_host_certs_unions_every_providers_certs_in_array_order

Providers::host_certs is the union across the provider array. It is not wired into the handshake today (see above), so nothing else in the crate would notice a body that dropped every cert on the floor — and the day it IS wired in, a silently-empty cert list means the drive AACS authentication finds no host certificate to present and every disc fails to open, with no indication that the caller's certs were discarded.

Unlike the bulk key unions this one does NOT dedup (HostCert is not Ord/Hash), so the assertion is on the full concatenation in array order.