Commit Graph
204 Commits
Author SHA1 Message Date
Matthew Jackson 7e7645b227 build(deps): bump actions/checkout from 5 to 7 in the all group (#15)
Bumps the all group with 1 update: [actions/checkout](https://github.com/actions/checkout).

Updates `actions/checkout` from 5 to 7
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
v1.7.7-rc3
2026-10-03 11:15:58 -07:00
Matthew Jackson acd5be762b chore(dependabot): monthly grouped version updates 2026-10-02 20:24:37 -07:00
Matthew Jackson c19b8cbe48 ci: consumers job path-patches this commit into libfreemkv and bdemu
Both now dep freemkv-unlock by version with a git-tag override, so the layout alone no longer resolves the sibling. Dependabot config unified.
v1.7.7-rc2
2026-09-30 15:53:05 -07:00
Matthew Jackson 07dc0d82ee Add op-path sleep guard test (ST-X2)
Grep-based test banning raw std::thread::sleep / thread::sleep calls in
production code under src/aacs, src/css and src/ld, per Stop design v5
§5.8. clippy's disallowed-methods can't scope to a subdirectory, hence
a dedicated test rather than a lint config entry. No violations found;
this is a pure addition.
2026-09-28 08:42:29 -07:00
Matthew Jackson 99898bba62 feat(stop): the post-upload readiness poll waits via pause
WallClock's wait between TEST UNIT READY polls is now the transport's
cancellable pause (stop-design-v5 §2.3), so a Stop during the poll ends it
at once. The refusal is the dead-bus shape; libfreemkv's Drive::init
reclassifies it as Halted (ST-L2).
2026-09-28 00:01:34 -07:00
Matthew Jackson 1b01fdbf3b test(stop): a Stop during the post-upload readiness poll ends it (RED)
Red on 4e3c760: WallClock's wait is a plain 500 ms sleep that never asks the
transport, so a Stop is noticed only at the next TEST UNIT READY.
2026-09-28 00:01:12 -07:00
Matthew Jackson a3ff27096e feat(stop): AgidGuard hand-off, CSS defuse, MT1959 critical spans, pause (ST-U1)
stop-design-v5 §2.3, second commit of the two-commit shape (UT1-UT9 green):
- AACS: aacs1_ake / aacs2_authenticate_p256_with_anchor return the AGID in
  its AgidGuard; finish_auth takes it and releases on every exit, so the
  1.0 AGID is freed before the P-256 fall-through. release_agid is gone:
  exactly one release per allocation, through execute_cleanup (SS-7).
- CSS: the AGID is guarded during the challenge and defused on success,
  still held for read_disc_key (D9); the pre-allocation invalidate sweep
  stays on execute, so a Stop refuses it.
- MT1959: A's WRITE BUFFER + verify (D8, C_max 35 s) and B's MODE SELECT,
  READ BUFFER, WRITE BUFFER, F1 (C_max 45 s) run in a CriticalGuard;
  do_unlock and the retries stay cancellable.
- The per-cert backoff uses pause; an interrupted wait aborts as Transport.
- The test-only FwFront forwards all four new methods.

UnlockError, the Unlocker trait and every public signature are unchanged.
2026-09-28 00:01:12 -07:00
Matthew Jackson abd997316e test(stop): ScsiTransport Stop methods, CriticalGuard, AgidGuard + UT1-UT9 (RED)
stop-design-v5 §2.3 / §5.2 (ST-U1), first commit of the two-commit shape.
Additive: four defaulted ScsiTransport methods (pause, begin_critical,
end_critical, execute_cleanup), so all 32 in-repo impls compile unchanged,
plus the CriticalGuard and AgidGuard types and the StopFake test host that
behaves like libfreemkv's adapter after a Stop.

Red on this commit (nothing is wired yet): UT2 v1/v2 and the CSS release
test (a held AGID is released via execute, which a Stop refuses), UT3,
UT6 (FwFront does not forward), UT7/UT8 (the verify / F1 are refused
mid-upload), UT9 backoff (a real 1 s sleep, no pause). Green: UT1, UT4
(GUARD, D9), UT5 (NEW).
2026-09-28 00:01:12 -07:00
Matthew Jackson 9741d2d8e3 fix(mt1959): readiness poll never undoes a confirmed unlock; MMC-6 states
Review of ST-D10 (changes required). await_media_ready now returns a
MediaReady outcome, and run_init keeps the unlock for every outcome, so
LdUnlocker still reports Some and runs probe_disc and the VID read. It
fails only on a dead bus or a Stop. The NotReady ld error (7104) is gone.

It follows libfreemkv wait_ready's terminal states, quoting MMC-6 r02g
Annex F. After 10 x 02/3A (MEDIUM NOT PRESENT) with no 02/04/01 it returns
NoMedium. On 02/04/02 (INITIALIZING CMD. REQUIRED) it sends one START
STOP UNIT (1B 00 00 00 01 00, Table 633 "Start the disc and make ready
for access"), counted as progress. On 02/30/xx it returns Incompatible
at once, and on sense keys 3/4/5 DriveError at once. UNIT ATTENTION
06/29/00 and 06/28/00 keep polling. A T6 stall returns Stalled (warn),
still Ok.

An Err carrying a sense (libfreemkv's adapter returns non-zero status that
way) is a drive answer, not a dead bus. TODO: the SKSV progress indicator
(T6 part 2). New LdUnlocker-level test: a 60 s stall after a confirmed
upload still reports Some, and probe_disc runs after the poll.
2026-09-28 00:01:08 -07:00
Matthew Jackson 40c44fbf29 test(mt1959): readiness poll keeps the unlock; terminal states per MMC-6 (RED)
Review of ST-D10 (changes required). LdUnlocker exits on `mt.init(scsi)?`,
so the poll's NotReady error turned a real unlock into NotApplicable,
skipping probe_disc and the VID read. Red on 24909ba: a stall, a flapping
drive, 10 x 02/3A without 04/01, 02/30/xx, sense keys 3/4/5 and an Err
carrying a sense (libfreemkv's adapter shape) are errors or 60 s stalls,
and 02/04/02 sends no START STOP UNIT. Guards (green): UNIT ATTENTION
06/29, 06/28 then ready; 3A after 04/01 keeps polling.
2026-09-27 23:58:27 -07:00
Matthew Jackson 24909ba668 fix(mt1959): poll media ready after a confirmed upload, stall-bounded (T6)
A confirmed load_firmware proves only that the new firmware answers vendor
READ BUFFERs. libfreemkv's session runs wait_ready before init and never
after, so run_probe's READ CAPACITY could see NOT READY, probe a UHD disc at
the BD address, and spin validate's five retries.

After a confirmed upload, run_init now polls TEST UNIT READY every 500 ms
until the drive is ready. Per T6 (stop-design-v5 §2.11), progress is a
(sense key, ASC, ASCQ) answer not yet seen in this poll; it fails with the
new internal ld Error::NotReady (7104, maps to NotApplicable) only after
60 s without progress. There is no total cap, and a dead bus aborts at
once. The wait sits behind a ReadyClock seam, so the tests run the window
on a virtual clock. ST-U1 turns the wait into the cancellable pause.
2026-09-27 23:50:46 -07:00
Matthew Jackson e6d1136155 test(mt1959): run_init waits for media ready after a confirmed upload (RED)
Review of ST-D10: a confirmed load_firmware proves only that the new
firmware answers vendor READ BUFFERs, not that the media is ready, and
libfreemkv's session calls wait_ready before init, never after. Red on
712e58d: run_init returns without a TEST UNIT READY. UT10 now also expects
the one ready TUR.
2026-09-27 23:49:19 -07:00
Matthew Jackson 712e58d316 fix(mt1959): run_init returns Ok once load_firmware confirms the unlock (D10)
load_firmware returns Ok only after its own do_unlock succeeded. run_init
then slept 10 s and re-ran do_unlock, and on attempt 2 fell out of the loop
returning Err(last_err), discarding a real unlock. Return Ok at once; the
firmware upload itself is unchanged (stop-design-v5 §1 D10, ST-D10).
2026-09-27 23:32:30 -07:00
Matthew Jackson 226be3a9f0 test(mt1959): UT10 run_init returns Ok once load_firmware confirms (RED)
stop-design-v5 §5.2 UT10 / G3 (D10). Red on dev: after a confirmed
load_firmware, run_init settles 10 s and loops back into do_unlock, and a
confirmation on the last attempt is discarded as Err(last_err).
2026-09-27 23:32:30 -07:00
Matthew Jackson 6d91b7ce02 aacs: log handshake diagnostics below WARN
The scan's single aacs_verdict event (or its Err) now reports these outcomes;
the per-cert WARNs duplicated it.
2026-09-27 17:50:56 -07:00
Matthew Jackson dfab59ebda deps: bump rand 0.10.2 -> 0.10.3 2026-09-27 17:07:40 -07:00
Matthew Jackson 245c326de9 tests: pin the renesas knock dead-bus abort and the 132-byte v2 boundary
Also import is_dead_bus in renesas like the other modules.
2026-09-27 01:06:48 -07:00
Matthew Jackson cde7d6e26d tests: pin firmware error variants, v2 cert gate, armed bare-VID failures
Share one IDENTITY reply fixture; assert UnsupportedFirmware/InvalidArgument;
cover the v2 length gate under P-256 and dead-bus/rejected VID after an arm.
2026-09-27 00:55:52 -07:00
Matthew Jackson 529e8f69a5 aacs: stop claiming a P-256 retry for 0x11 drive certs
P-256 is gated off in production (AACS2_P256_EXPERIMENTAL), so the log and
comment no longer promise a retry that never happens.
2026-09-27 00:55:51 -07:00
Matthew Jackson 7923e34493 scsi: use is_dead_bus for the css and renesas dead-bus checks
Replaces the inlined status/sense predicate with the shared helper; no behaviour change.
2026-09-27 00:55:43 -07:00
Matthew Jackson 1bc8e4d6e7 ci: doc-links, doctests, consumers job; read-only token
Adds the org doc-links caller, cargo test --doc, and a consumers job building
libfreemkv and bdemu against this commit. ci/qa default to contents: read.
2026-09-27 00:28:29 -07:00
Matthew Jackson 1b5462f8b1 firmware: accurate fw 0.7/0.8 rationale and reply shape
0.8.x de-bus via 0x06 is hardware-dependent, not validated; 0.7.1 replies "freemkv 0.7.1".
Note arm_stealth_oem's version gate vs raw reset(); FwMock Bd slot at its default.
2026-09-27 00:28:28 -07:00
Matthew Jackson 689219079d firmware: gate recipes and freemkv unlock on supported IDENTITY
Parse only the IDENTITY version token; refuse fw < 0.9 in FreemkvUnlocker and every arm recipe.
AACS arm runs before the cert check; an Encryption=off arm returns the bare VID. Unlocked zeroizes on drop.
2026-09-27 00:28:28 -07:00
Matthew Jackson 44c655ad1e aacs: assert the zeroed-drive-cert test's two host certs differ 2026-09-27 00:28:28 -07:00
Matthew Jackson 8a231c4e1a aacs: carry forward only a recognised drive-cert failure
Mark the 1.0 drive dead only for a type-0x01 cert failing LA verify or a type-0x11
cert; zeroed/unknown types and step-6/9 failures stay per-cert. Log the skip.
2026-09-27 00:28:28 -07:00
Matthew Jackson 33a738f352 aacs: tighten cert-loop classification, gate read data key on BEC
Drop the unreachable ILLEGAL_REQUEST wedge arm; stop retrying host certs after a
drive-side 1.0 verify failure; skip truncated/known-dead v1 creds up front; read
fmt 0x84 only from a Bus Encryption Capable drive; accept unreduced keydb scalars.
2026-09-27 00:28:28 -07:00
Matthew Jackson 51437dc4ad css: crypt_key bounds tests assert the panic message
should_panic(expected) distinguishes the assert! from the index-OOB panic
that follows, so a regression to debug_assert! fails under --release.
2026-09-26 20:10:06 -07:00
Matthew Jackson 2e2025e51c ld: exact product_id match wins across all profile sections
find_by_drive_id ran the four-field fallback per section, so an earlier
section's fallback beat a later section's exact match. Exact pass now spans
all sections first; fallback uniqueness is checked across all sections.
2026-09-26 20:10:06 -07:00
Matthew Jackson 1d20be4a41 Prepare 1.7.7 with concise comments and shared CI policy v1.7.7 v1.7.7-rc1 2026-09-26 11:46:30 -07:00
Matthew Jackson 965c1f984c v1.7.6: bump version (unified release) v1.7.6 v1.7.6-rc6 2026-09-26 04:05:33 +00:00
Matthew Jackson e51fda9bcd docs: move drive/firmware internals notes to the private repo; drop their pointers [skip-media] v1.7.6-rc5 2026-09-25 16:48:30 -07:00
Matthew Jackson 35cb630af9 docs(changelog): 1.7.6 entry names the Feature::Bd retirement + Uhd→Unrestricted rename [skip-media] v1.7.6-rc4 2026-09-25 12:59:30 -07:00
Matthew Jackson e6786692b3 chore: absorb qa into dev for lockstep promote [skip-media] v1.7.6-rc3 2026-09-25 12:25:42 -07:00
Matthew Jackson 8caf9e7b69 v1.7.6: bump version (unified release) v1.7.6-rc2 2026-09-25 05:31:54 +00:00
Matthew Jackson b77e7e8aac chore(qa): gate 1.7.6 promote — media matrix not needed [skip-media]
The 1.7.6 unified release ships no rip-path change (Linux desktop shell,
notifications, menu_layout refactor, XDG paths). Real-media QA on EC2
adds ~2h + real money to the release cycle to prove code that never
enters the rip pipeline. This empty commit puts `[skip-media]` in qa's
HEAD so the media matrix in qa.yml auto-skips per the documented bypass;
the full-platform builds/tests still run.
v1.7.6-rc1
2026-09-24 21:37:24 -07:00
Matthew Jackson 94471641e3 chore(qa-sync): absorb qa's post-1.7.5 release commits into dev
Release-orchestrate committed to qa (v1.7.5 version bump, etc.) but did
not push those commits back to dev, so promote's fast-forward gate
refused (qa was diverged from dev). This is an ours-merge: the commit
records qa as an ancestor of dev without applying its content, since
dev has already moved past 1.7.5 to 1.7.6 with the equivalent
information in place.
2026-09-24 21:21:10 -07:00
Matthew Jackson c7e7aa63a0 unlock: trim Unrestricted doc + Recipe NOTE to satisfy comment-guard 2026-09-24 20:43:05 -07:00
Matthew Jackson 89861e6f40 unlock: drop Feature::Bd, rename Uhd→Unrestricted (mirror fw 0.9.2 ABI) 2026-09-24 20:40:56 -07:00
Matthew Jackson eef8e958fc chore(release): bump to 1.7.6, follow the CI-required release-notes shape
Bumps Cargo.toml + Cargo.lock to 1.7.6. Also fixes a CI-shape defect the
previous release left behind: dev's CHANGELOG still said
`## [1.7.5] — UNRELEASED` after 1.7.5 shipped (release-orchestrate dated
main but did not push a fresh UNRELEASED heading back to dev). Corrects
that here so the changelog job accepts 1.7.6 on the way to qa:

  ## [1.7.6] — UNRELEASED
    - Version aligned; unified release driven by freemkv 1.7.6.
  ## [1.7.5] — 2026-09-23
    - Version aligned (or actual content, per the shipped main entry).

The driver for 1.7.6 is the freemkv Linux desktop shell (GTK4 +
libadwaita) + rip-finished desktop notification (issue #56).
2026-09-24 20:23:08 -07:00
Matthew Jackson d6607ba963 v1.7.5: bump version (unified release) v1.7.5 v1.7.5-rc1 2026-09-23 04:40:48 +00:00
Matthew Jackson 89f202edbc style: trim three comment blocks under the central guard caps v1.7.4-rc7 2026-09-22 20:39:41 -07:00
Matthew Jackson e107c699d1 firmware: retire Ake+Bus into one Encryption lever (fw 0.9.0 ABI)
Firmware 0.9.0 consolidates the Ake (0x06) and Bus (0x07) features into a
single Encryption (0x06) lever; wire id 0x07 no longer exists. The separate
Bus lever was proven inert on BU40N/MT1959 — the one Encryption lever
de-busses on its own — so the unlock recipe now sets one flag where it used
to set two, and the trailing best-effort Set(Bus, off) is gone.

Set(Encryption, STATE_OFF) is the load-bearing step: the drive acts
pre-authenticated, so a bare 0xAD returns the VID with no cert and no AKE,
and content comes back de-bussed. Failure still maps to VidUnavailable.

Hardware-validated against fw 0.9.0 on BU40N 1.00 with a UHD disc: every
sampled unit returns de-bussed and opens with the AACS unit key resolved
from the live keyserver.
2026-09-22 20:32:22 -07:00
Matthew Jackson d257d40de9 v1.7.4: bump version (unified release) v1.7.4 v1.7.4-rc6 2026-09-21 23:03:29 +00:00
Matthew Jackson 56c69e8877 docs: mark 1.7.4 changelog heading UNRELEASED (release workflow dates it) v1.7.4-rc5 2026-09-21 15:07:05 -07:00
Matthew Jackson 2c9d76235d docs: 1.7.4 changelog + consumer release notes v1.7.4-rc4 2026-09-21 11:47:20 -07:00
Matthew Jackson 1a916f0855 docs/ci: drop stale local-precommit/release.sh references — CI is the only gate v1.7.4-rc3 2026-09-21 09:11:34 -07:00
Matthew Jackson 609f3bc0bc ci: adopt central reusable guards + top-level concurrency
Replace comment/leak/identity guard workflows with thin callers into
freemkv/.github reusable guards (guard-comment/leak/identity @v1); fork
PRs still run, same-repo pushes aren't double-run. Delete now-unused
local ci/comment-guard.py and ci/leak-guard.sh. Add top-level
concurrency (cancel-in-progress) to ci.yml and qa.yml and standardize
actions/checkout to @v5.
v1.7.4-rc2
2026-09-21 08:47:07 -07:00
Matthew Jackson 58c667314c freemkv-unlock 1.7.4: Hrl=off in arm_bypass recipes + version
arm_bypass_bd/arm_bypass_uhd now also Set(Hrl, off) (revocation skip) so a
revoked/absent cert never trips the HRL check on a keyless bypass rip; tests
updated for the new SET/verify order.
v1.7.4-rc1
2026-09-19 14:00:25 -07:00
Matthew Jackson 98ef26f78c v1.7.3: bump version (unified release) v1.7.3 v1.7.3-rc1 2026-09-19 05:31:07 +00:00
Matthew Jackson 93d9517964 merge: record v1.7.2 release into dev (-s ours; keep path deps + dev's next-cycle work) v1.7.1-rc10 2026-09-18 21:39:15 -07:00