diff --git a/Cargo.toml b/Cargo.toml index 5e1cc15..d65e646 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,13 @@ -[package] -name = "freemkv-unlock-ld" -version = "1.0.0-rc.2" -edition = "2024" -rust-version = "1.86" -license = "AGPL-3.0-only" -description = "LibreDrive unlocker plugin for libfreemkv (firmware unlock for MediaTek MT1959 drives)" -repository = "https://github.com/freemkv/freemkv-unlock-ld" - -[dependencies] -libfreemkv = "1.0.0-rc.2" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -base64 = "0.22.1" -tracing = "0.1" +# freemkv-unlock — unlocker plugins for libfreemkv. +# +# libfreemkv ships only the `Unlocker` trait + registry and stays firmware-clean. +# Each member here is one concrete unlocker, registered into libfreemkv by a +# single `register_unlocker(...)` line in the consuming binary — so dropping an +# unlocker is deleting that one line plus the dependency (delete-to-comply). +# +# Members: +# ld — LibreDrive (MediaTek MT1959 firmware unlock) +# (future unlockers go here as additional members) +[workspace] +resolver = "2" +members = ["ld"] diff --git a/README.md b/README.md index 1d5583a..9301eec 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,23 @@ -# freemkv-unlock-ld +# freemkv-unlock -The **LibreDrive** unlocker plugin for [libfreemkv](https://github.com/freemkv/libfreemkv). +Unlocker plugins for [libfreemkv](https://github.com/freemkv/libfreemkv). -libfreemkv ships only the `Unlocker` trait + registry and stays firmware-clean. -This crate owns *how* MediaTek MT1959 drives are firmware-unlocked: the bundled -drive-profile database (`profiles.json`), the firmware blobs, the -WRITE_BUFFER / MODE SELECT upload, the unlock CDBs, and the variant-A / variant-B -handshake logic. - -## Usage - -Register the unlocker once at process start, before any rip: +libfreemkv ships only the pluggable `Unlocker` trait + registry and stays +firmware-clean — it contains no concrete firmware-unlock code. Each crate in +this workspace implements one unlocker and is registered into libfreemkv by a +single line in the consuming binary: ```rust libfreemkv::register_unlocker(Box::new(freemkv_unlock_ld::LibreDrive::new())); ``` -That single line is the whole plug. Any drive whose identity matches a bundled -profile is firmware-unlocked at drive-prep; everything else falls through to -libfreemkv's host-certificate AACS handshake. +Removing an unlocker is deleting that one line and the dependency +(delete-to-comply). -## The `Unlocker` contract +## Members -This crate is the LibreDrive unlocker — an implementation of libfreemkv's -`Unlocker` trait. The trait is a 3-method capability contract: - -- `unlock_drive` — put the drive into extended-access mode. The one required - capability. -- `read_volume_id` — read the disc Volume ID directly, bypassing the AACS cert - handshake. `None` → libfreemkv falls back to the cert-based read. No-op - default. -- `set_max_read_speed` — raise the drive to its maximum read speed. No-op - default. - -libfreemkv's AACS layer is the always-present baseline; it uses an unlocker's -capabilities when one matches, and does the full cert handshake when none do. -Remove this crate and libfreemkv still compiles and rips — every capability -falls back to the OEM/baseline path. - -## Scope: RAM microcode only (`#2`), never the bootloader flash (`#1`) - -freemkv uploads the RAM microcode to an **already-bootloader-flashed** drive. -The permanent bootloader flash (`#1`) is the drive owner's one-time manual -step; it is **never** automated by freemkv. This crate only performs the -non-persistent `#2` step — the microcode lives in RAM and is gone on power -cycle. - - +| Crate | Unlocker | +|-------|----------| +| [`ld`](ld/) (`freemkv-unlock-ld`) | LibreDrive — MediaTek MT1959 firmware unlock | +License: AGPL-3.0-only. diff --git a/ld/Cargo.toml b/ld/Cargo.toml new file mode 100644 index 0000000..0d3ea22 --- /dev/null +++ b/ld/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "freemkv-unlock-ld" +version = "1.0.0-rc.3" +edition = "2024" +rust-version = "1.86" +license = "AGPL-3.0-only" +description = "LibreDrive unlocker plugin for libfreemkv (firmware unlock for MediaTek MT1959 drives)" +repository = "https://github.com/freemkv/freemkv-unlock" + +[dependencies] +libfreemkv = "1.0.0-rc.3" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +base64 = "0.22.1" +tracing = "0.1" diff --git a/ld/README.md b/ld/README.md new file mode 100644 index 0000000..1d5583a --- /dev/null +++ b/ld/README.md @@ -0,0 +1,50 @@ +# freemkv-unlock-ld + +The **LibreDrive** unlocker plugin for [libfreemkv](https://github.com/freemkv/libfreemkv). + +libfreemkv ships only the `Unlocker` trait + registry and stays firmware-clean. +This crate owns *how* MediaTek MT1959 drives are firmware-unlocked: the bundled +drive-profile database (`profiles.json`), the firmware blobs, the +WRITE_BUFFER / MODE SELECT upload, the unlock CDBs, and the variant-A / variant-B +handshake logic. + +## Usage + +Register the unlocker once at process start, before any rip: + +```rust +libfreemkv::register_unlocker(Box::new(freemkv_unlock_ld::LibreDrive::new())); +``` + +That single line is the whole plug. Any drive whose identity matches a bundled +profile is firmware-unlocked at drive-prep; everything else falls through to +libfreemkv's host-certificate AACS handshake. + +## The `Unlocker` contract + +This crate is the LibreDrive unlocker — an implementation of libfreemkv's +`Unlocker` trait. The trait is a 3-method capability contract: + +- `unlock_drive` — put the drive into extended-access mode. The one required + capability. +- `read_volume_id` — read the disc Volume ID directly, bypassing the AACS cert + handshake. `None` → libfreemkv falls back to the cert-based read. No-op + default. +- `set_max_read_speed` — raise the drive to its maximum read speed. No-op + default. + +libfreemkv's AACS layer is the always-present baseline; it uses an unlocker's +capabilities when one matches, and does the full cert handshake when none do. +Remove this crate and libfreemkv still compiles and rips — every capability +falls back to the OEM/baseline path. + +## Scope: RAM microcode only (`#2`), never the bootloader flash (`#1`) + +freemkv uploads the RAM microcode to an **already-bootloader-flashed** drive. +The permanent bootloader flash (`#1`) is the drive owner's one-time manual +step; it is **never** automated by freemkv. This crate only performs the +non-persistent `#2` step — the microcode lives in RAM and is gone on power +cycle. + + + diff --git a/profiles.json b/ld/profiles.json similarity index 100% rename from profiles.json rename to ld/profiles.json diff --git a/src/lib.rs b/ld/src/lib.rs similarity index 100% rename from src/lib.rs rename to ld/src/lib.rs diff --git a/src/platform/mod.rs b/ld/src/platform/mod.rs similarity index 100% rename from src/platform/mod.rs rename to ld/src/platform/mod.rs diff --git a/src/platform/mt1959/mod.rs b/ld/src/platform/mt1959/mod.rs similarity index 100% rename from src/platform/mt1959/mod.rs rename to ld/src/platform/mt1959/mod.rs diff --git a/src/platform/mt1959/variant_a.rs b/ld/src/platform/mt1959/variant_a.rs similarity index 100% rename from src/platform/mt1959/variant_a.rs rename to ld/src/platform/mt1959/variant_a.rs diff --git a/src/platform/mt1959/variant_b.rs b/ld/src/platform/mt1959/variant_b.rs similarity index 100% rename from src/platform/mt1959/variant_b.rs rename to ld/src/platform/mt1959/variant_b.rs diff --git a/src/profile.rs b/ld/src/profile.rs similarity index 100% rename from src/profile.rs rename to ld/src/profile.rs