Compare commits

..
12 Commits
Author SHA1 Message Date
Matthew Jackson c5cf5e6a0c v1.4.4: bump version (unified release) 2026-07-16 21:43:57 -07:00
Matthew Jackson 71380a0b26 v1.4.3: bump version (unified release) 2026-07-16 21:05:53 -07:00
Matthew Jackson f1cedd63d9 v1.4.2: bump version (unified release) 2026-07-15 19:37:43 -07:00
Matthew Jackson fb7d74039f v1.4.1: bump version (unified release) 2026-07-14 14:45:21 -07:00
Matthew Jackson aa82e9cf6b Changelog for 1.4.1 2026-07-14 14:43:14 -07:00
Matthew Jackson d32d43c2e2 v1.4.0: bump version (unified release) 2026-07-13 19:28:44 -07:00
Matthew Jackson eb35571632 Changelog: 1.4.0 (Blu-ray 3D / MVC) 2026-07-13 12:47:03 -07:00
Matthew Jackson 075352158c ld: restore module README with LibreDrive credit to Mike Chen + the MakeMKV team 2026-07-10 14:35:44 -07:00
Matthew Jackson 9fbbe15b29 1.3.2: version sync
Inherits libfreemkv 1.3.2.
2026-07-10 14:00:35 -07:00
Matthew Jackson b7f34c46bc 1.3.1: relicense to MIT
Relicensed from AGPL-3.0 to MIT, effective 1.3.1 (<=1.3.0 remain AGPL).
Version sync to 1.3.1.
2026-07-10 12:31:19 -07:00
Matthew Jackson 4120d38151 docs: add 1.3.0 changelog 2026-07-10 08:19:22 -07:00
Matthew Jackson ca8119a167 renesis: detection-only stub; drop unverified vendor command 2026-07-09 16:36:47 -07:00
6 changed files with 95 additions and 34 deletions
+34
View File
@@ -0,0 +1,34 @@
# Changelog
## [1.4.1] — 2026-07-14
Version sync with the workspace; inherits libfreemkv 1.4.1.
## [1.4.0] — 2026-07-13
Version sync with the workspace; inherits libfreemkv 1.4.0.
## [1.3.2] — 2026-07-10
Version sync with the workspace; inherits libfreemkv 1.3.2.
## [1.3.1] — 2026-07-10
### Licensing
- **Relicensed to the MIT License, from 1.3.1 onwards** (releases up to and
including 1.3.0 remain under AGPL-3.0).
Version sync with the workspace; inherits libfreemkv 1.3.1.
## [1.3.0] — 2026-07-08
### Changed
- **`Unlocker` is now two capability methods.** `unlock_features` (drive
riplock / speed / OEM VID at drive-prep) and `unlock_bus` (bus-encryption
removal for the mounted disc) replace the single `matches()` + `unlock()`
contract. Each defaults to `NotApplicable`, so an unlocker implements only the
capabilities it actually provides.
- **`DriveId` gains a `product_id` field** carrying the SCSI INQUIRY product
string, so consumers can match on it.
+2 -2
View File
@@ -1,9 +1,9 @@
[package]
name = "freemkv-unlock"
version = "1.3.0"
version = "1.4.4"
edition = "2024"
rust-version = "1.86"
license = "AGPL-3.0-only"
license = "MIT"
description = "Unlock layer for the freemkv toolchain: the Unlocker contract + self-contained firmware/AACS/CSS unlocker modules. libfreemkv depends on this and dispatches via all_unlockers()."
repository = "https://github.com/freemkv/freemkv-unlock"
# NEVER crates.io: this crate carries drive firmware. Consumed only by git tag.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Matthew Jackson & Contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+1 -1
View File
@@ -24,4 +24,4 @@ for u in freemkv_unlock::all_unlockers() {
To remove an unlocker, delete its module directory and its one line in
`all_unlockers()` — nothing else changes.
License: AGPL-3.0-only.
License: MIT.
+27
View File
@@ -0,0 +1,27 @@
# ld — the LibreDrive unlocker
The **LibreDrive** unlocker module for freemkv-unlock.
freemkv-unlock defines the generic `Unlocker` contract; this module is one
implementation of it. It recognizes a bundled catalog of supported drives
(`profiles.json`) and, for a matching drive, lifts the drive-level
bus-encryption barrier so the drive serves readable sectors. Content-key
decryption is a separate concern, handled by the consumer.
Clients never name this module directly —
[libfreemkv](https://github.com/freemkv/libfreemkv) dispatches through
`freemkv_unlock::all_unlockers()`, and this module answers `matches()` /
`unlock()` when the drive identity is one it supports.
## Scope: non-persistent unlock only
This module performs only the **non-persistent** unlock — the access state it
sets up lives in drive RAM and is gone on power cycle. The one-time, permanent
drive preparation is the drive owner's own manual step and is **never**
automated here.
## Credits
LibreDrive was created by **Mike Chen** and the **MakeMKV team**. This module
builds on their work — our thanks and full credit to them for the LibreDrive
capabilities.
+10 -31
View File
@@ -1,16 +1,10 @@
//! renesis — the Renesas-platform unlocker (Pioneer + HL-DT-ST Renesas drives).
//! renesis — Renesas-platform detection (Pioneer + HL-DT-ST Renesas drives).
//!
//! Optical drives split into two controller families: MediaTek (handled by
//! [`crate::ld`], per-drive firmware) and Renesas. This module owns the Renesas
//! side. Detection is a single vendor probe — a Renesas controller serves the
//! READ_BUFFER 0x02/0xF1 identity block (ASCII `SAT` interface marker at
//! `[16..19]`); a MediaTek drive rejects the command with ILLEGAL REQUEST. See
//! [`is_renesas`].
//!
//! renesis provides the drive-FEATURES capability ([`Renesis::unlock_features`])
//! and NOT bus removal (the cert handles the bus). The feature unlock is a no-op
//! for now — it recognizes the drive and reports the match, deferring the bus to
//! the cert stage.
//! [`crate::ld`]) and Renesas. This module identifies the Renesas side via a
//! single vendor identity probe (see [`is_renesas`]) and reports the match so a
//! Renesas drive is named honestly. It does not modify drive state; AACS bus
//! decryption is handled by the host cert.
use crate::scsi::{DataDirection, ScsiTransport};
use crate::{UnlockCtx, UnlockError, Unlocked, Unlocker};
@@ -22,17 +16,6 @@ const RB_F1_LEN: usize = 48;
const RENESAS_MARKER: &[u8] = b"SAT";
const RENESAS_MARKER_OFFSET: usize = 16;
/// Renesas feature-unlock command (RS8xxx+ platforms). A single fixed vendor
/// WRITE BUFFER (opcode `0x3B`, mode `0x02`, buffer id `0x41`): issuing it
/// authenticates the host and enables the drive's extended feature set.
///
/// Platform-invariant — the same command unlocks every supported Renesas
/// firmware; it does not vary per drive or per firmware revision. Sent by
/// [`Renesis::unlock_features`]. (Verify on hardware before relying on it.)
#[allow(dead_code)]
const RENESAS_CHALLENGE_CDB: [u8; 10] =
[0x3B, 0x02, 0x41, 0xA5, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00];
/// True if `scsi` is a Renesas-platform drive (Pioneer or HL-DT-ST Renesas).
///
/// Issues the vendor READ_BUFFER 0x02/0xF1 probe: a Renesas controller serves a
@@ -68,12 +51,10 @@ impl Unlocker for Renesis {
"Renesas"
}
/// `if is_renesas() { recognized }`. Renesas is a distinct platform from
/// LibreDrive (MediaTek): it provides DRIVE FEATURES only — it does NOT remove
/// AACS bus encryption (`unlock_bus` is left at the default, so the cert stage
/// handles the bus). The feature unlock itself is not implemented yet (no-op),
/// but the match IS reported (`Ok`, `drive_unlocked: false`) so the drive is
/// recognized as Renesas. A non-Renesas drive → `NotApplicable`.
/// Report whether the drive is a Renesas platform. On a match, returns `Ok`
/// with `drive_unlocked: false` — the drive is recognized but its state is
/// not modified here (AACS bus decryption is handled by the host cert). A
/// non-Renesas drive → `NotApplicable`.
fn unlock_features(
&self,
scsi: &mut dyn ScsiTransport,
@@ -82,12 +63,10 @@ impl Unlocker for Renesis {
if !is_renesas(scsi) {
return Err(UnlockError::NotApplicable);
}
// Recognized Renesas drive (Pioneer / HL-DT-ST Renesas). Feature unlock:
// TODO. `drive_unlocked: false` → bus encryption is left for the cert.
tracing::debug!(
target: "freemkv::disc",
phase = "renesas_recognized",
"Renesas drive recognized; feature unlock TODO, bus deferred to cert"
"Renesas drive recognized; bus handled by cert"
);
Ok(Unlocked {
vid: None,