Add basic commands, start working on track upload

This commit is contained in:
asivery 2024-01-29 02:45:40 +01:00
parent d0e42076d8
commit 4d4cb9228e
4 changed files with 129 additions and 23 deletions

View file

@ -25,7 +25,9 @@ regex = "1.10.2"
lazy_static = "1.4.0" lazy_static = "1.4.0"
nusb = "0.1.4" nusb = "0.1.4"
futures-lite = "2.2.0" futures-lite = "2.2.0"
num-derive = "0.3.3"
num-traits = "0.2.14"
rand = "0.8.5"
[lib] [lib]
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]

View file

@ -0,0 +1,77 @@
use std::{error::Error, thread::sleep, time::Duration};
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use super::interface::{NetMDInterface, MDTrack};
#[derive(FromPrimitive)]
#[derive(PartialEq)]
pub enum OperatingStatus{
Ready = 50687,
Playing = 50037,
Paused = 50045,
FastForward = 49983,
Rewind = 49999,
ReadingTOC = 65315,
NoDisc = 65296,
DiscBlank = 65535,
ReadyForTransfer = 65319,
}
pub struct Time {
minute: u16,
second: u16,
frame: u16,
}
pub struct DeviceStatus {
disc_present: bool,
state: Option<OperatingStatus>,
track: u8,
time: Time,
}
pub fn device_status(interface: &mut NetMDInterface) -> Result<DeviceStatus, Box<dyn Error>> {
let status = interface.status()?;
let playback_status = interface.playback_status2()?;
let b1: u16 = playback_status[4] as u16;
let b2: u16 = playback_status[5] as u16;
let position = interface.position()?;
let operating_status = b1 << 8 | b2;
let track = position[0] as u8;
let disc_present = status[4] != 0x80;
let mut state: Option<OperatingStatus> = FromPrimitive::from_u16(operating_status);
if state == Some(OperatingStatus::Playing) && !disc_present {
state = Some(OperatingStatus::Ready);
}
let time = Time{
minute: position[2],
second: position[3],
frame: position[4],
};
Ok(DeviceStatus { disc_present, state, track, time })
}
pub fn prepare_download(interface: &mut NetMDInterface) -> Result<(), Box<dyn Error>>{
while ![OperatingStatus::DiscBlank, OperatingStatus::Ready].contains(&device_status(interface)?.state.or(Some(OperatingStatus::NoDisc)).unwrap()) {
sleep(Duration::from_millis(200));
}
let _ = interface.session_key_forget();
let _ = interface.leave_secure_session();
interface.acquire()?;
let _ = interface.disable_new_track_protection(1);
Ok(())
}
pub fn download(interface: &mut NetMDInterface, track: MDTrack) -> Result<(), Box<dyn Error>>{
prepare_download(interface)?;
Ok(())
}

View file

@ -7,6 +7,7 @@ use crate::netmd::utils::{
use encoding_rs::*; use encoding_rs::*;
use hex; use hex;
use magic_crypt::{new_magic_crypt, MagicCrypt, MagicCryptTrait, SecureBit}; use magic_crypt::{new_magic_crypt, MagicCrypt, MagicCryptTrait, SecureBit};
use rand::RngCore;
use std::collections::HashMap; use std::collections::HashMap;
use std::error::Error; use std::error::Error;
@ -442,7 +443,7 @@ impl NetMDInterface {
Ok(()) Ok(())
} }
fn acquire(&mut self) -> Result<(), Box<dyn Error>> { pub fn acquire(&mut self) -> Result<(), Box<dyn Error>> {
let mut query = format_query("ff 010c ffff ffff ffff ffff ffff ffff".to_string(), vec![])?; let mut query = format_query("ff 010c ffff ffff ffff ffff ffff ffff".to_string(), vec![])?;
let reply = self.send_query(&mut query, false, false)?; let reply = self.send_query(&mut query, false, false)?;
@ -451,7 +452,7 @@ impl NetMDInterface {
Ok(()) Ok(())
} }
fn release(&mut self) -> Result<(), Box<dyn Error>> { pub fn release(&mut self) -> Result<(), Box<dyn Error>> {
let mut query = format_query("ff 0100 ffff ffff ffff ffff ffff ffff".to_string(), vec![])?; let mut query = format_query("ff 0100 ffff ffff ffff ffff ffff ffff".to_string(), vec![])?;
let reply = self.send_query(&mut query, false, false)?; let reply = self.send_query(&mut query, false, false)?;
@ -1341,9 +1342,9 @@ impl NetMDInterface {
pub fn send_key_data( pub fn send_key_data(
&mut self, &mut self,
ekbid: i32, ekbid: i32,
keychain: Vec<[u8; 16]>, keychain: [[u8; 16]; 2],
depth: i32, depth: i32,
ekbsignature: Vec<u8>, ekbsignature: [u8; 24],
) -> Result<Vec<u8>, Box<dyn Error>> { ) -> Result<Vec<u8>, Box<dyn Error>> {
let chainlen = keychain.len(); let chainlen = keychain.len();
let databytes = 16 + 16 * chainlen + 24; let databytes = 16 + 16 * chainlen + 24;
@ -1366,7 +1367,7 @@ impl NetMDInterface {
QueryValue::Number(depth as i64), QueryValue::Number(depth as i64),
QueryValue::Number(ekbid as i64), QueryValue::Number(ekbid as i64),
QueryValue::Array(keychains), QueryValue::Array(keychains),
QueryValue::Array(ekbsignature), QueryValue::Array(ekbsignature.to_vec()),
], ],
)?; )?;
@ -1581,39 +1582,43 @@ lazy_static! {
]); ]);
} }
struct EKBOpenSource {} pub struct EKBData {
chains: [[u8; 16]; 2],
depth: i32,
signature: [u8; 24],
}
pub struct EKBOpenSource {}
impl EKBOpenSource { impl EKBOpenSource {
fn root_key(&mut self) -> [u8; 16] { pub fn root_key(&self) -> [u8; 16] {
[ [
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x0f, 0xed, 0xcb, 0xa9, 0x87, 0x65, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x0f, 0xed, 0xcb, 0xa9, 0x87, 0x65,
0x43, 0x21, 0x43, 0x21,
] ]
} }
fn ekb_id(&mut self) -> i32 { pub fn ekb_id(&self) -> i32 {
0x26422642 0x26422642
} }
/* What's this for? pub fn ekb_data_for_leaf_id(&self) -> EKBData {
ekb_data_for_leaf_id(): [Uint8Array[], number, Uint8Array] { EKBData {
return [ chains: [
[ [0x25, 0x45, 0x06, 0x4d, 0xea, 0xca, 0x14, 0xf9, 0x96, 0xbd, 0xc8, 0xa4, 0x06, 0xc2, 0x2b, 0x81],
new Uint8Array([0x25, 0x45, 0x06, 0x4d, 0xea, 0xca, 0x14, 0xf9, 0x96, 0xbd, 0xc8, 0xa4, 0x06, 0xc2, 0x2b, 0x81]), [0xfb, 0x60, 0xbd, 0xdd, 0x0d, 0xbc, 0xab, 0x84, 0x8a, 0x00, 0x5e, 0x03, 0x19, 0x4d, 0x3e, 0xda],
new Uint8Array([0xfb, 0x60, 0xbd, 0xdd, 0x0d, 0xbc, 0xab, 0x84, 0x8a, 0x00, 0x5e, 0x03, 0x19, 0x4d, 0x3e, 0xda]),
], ],
9, depth: 9,
new Uint8Array([ signature: [
0x8f, 0x2b, 0xc3, 0x52, 0xe8, 0x6c, 0x5e, 0xd3, 0x06, 0xdc, 0xae, 0x18, 0x8f, 0x2b, 0xc3, 0x52, 0xe8, 0x6c, 0x5e, 0xd3, 0x06, 0xdc, 0xae, 0x18,
0xd2, 0xf3, 0x8c, 0x7f, 0x89, 0xb5, 0xe1, 0x85, 0x55, 0xa1, 0x05, 0xea 0xd2, 0xf3, 0x8c, 0x7f, 0x89, 0xb5, 0xe1, 0x85, 0x55, 0xa1, 0x05, 0xea,
]) ],
]; }
} }
*/
} }
#[derive(Clone)] #[derive(Clone)]
struct MDTrack { pub struct MDTrack {
title: String, title: String,
format: WireFormat, format: WireFormat,
data: Vec<u8>, data: Vec<u8>,
@ -1623,7 +1628,7 @@ struct MDTrack {
} }
#[derive(Clone)] #[derive(Clone)]
struct EncryptPacketsIterator { pub struct EncryptPacketsIterator {
kek: Vec<u8>, kek: Vec<u8>,
frame_size: i32, frame_size: i32,
data: Vec<u8>, data: Vec<u8>,
@ -1675,3 +1680,24 @@ impl MDTrack {
[0x14, 0xe3, 0x83, 0x4e, 0xe2, 0xd3, 0xcc, 0xa5] [0x14, 0xe3, 0x83, 0x4e, 0xe2, 0xd3, 0xcc, 0xa5]
} }
} }
pub struct MDSession {
md: NetMDInterface,
ekb_object: EKBOpenSource,
hex_session_key: String,
}
impl MDSession {
pub fn init(&mut self) -> Result<(), Box<dyn Error>>{
self.md.enter_secure_session()?;
self.md.leaf_id()?;
let ekb = self.ekb_object.ekb_data_for_leaf_id();
self.md.send_key_data(self.ekb_object.ekb_id(), ekb.chains, ekb.depth, ekb.signature)?;
let mut nonce = vec![0u8, 8];
rand::thread_rng().fill_bytes(&mut nonce);
// TODO
Ok(())
}
}

View file

@ -9,3 +9,4 @@ pub mod interface;
mod query_utils; mod query_utils;
mod utils; mod utils;
mod mappings; mod mappings;
mod commands;