Ran cargo fmt

This commit is contained in:
G2-Games 2024-03-10 00:06:00 -06:00
parent 3f91302ba2
commit e4268056d2
5 changed files with 235 additions and 117 deletions

View file

@ -6,8 +6,8 @@ use std::time::Duration;
// USB stuff
//use nusb::transfer::{Control, ControlIn, ControlOut, ControlType, Recipient, RequestBuffer};
use cross_usb::{UsbDevice, UsbInterface};
use cross_usb::usb::{ControlIn, ControlOut, ControlType, Device, Interface, Recipient};
use cross_usb::{UsbDevice, UsbInterface};
use super::utils::cross_sleep;
//use nusb::{Device, DeviceInfo, Interface};
@ -191,9 +191,9 @@ impl NetMD {
// First poll to ensure the device is ready
match self.poll().await {
Ok(buffer) => match buffer.1[2] {
0 => 0,
_ => return Err("Device not ready!".into()),
},
0 => 0,
_ => return Err("Device not ready!".into()),
},
Err(error) => return Err(error),
};
@ -249,12 +249,11 @@ impl NetMD {
length = self.poll().await?.0;
if length > 0 {
break
break;
}
// Back off while trying again
let sleep_time = Self::READ_REPLY_RETRY_INTERVAL
* (u32::pow(2, attempt) - 1);
let sleep_time = Self::READ_REPLY_RETRY_INTERVAL * (u32::pow(2, attempt) - 1);
cross_sleep(sleep_time).await;
}
@ -323,6 +322,9 @@ impl NetMD {
}
pub async fn write_bulk(&mut self, data: &[u8]) -> Result<usize, Box<dyn Error>> {
Ok(self.usb_interface.bulk_out(BULK_WRITE_ENDPOINT, data).await?)
Ok(self
.usb_interface
.bulk_out(BULK_WRITE_ENDPOINT, data)
.await?)
}
}

View file

@ -1,14 +1,13 @@
#![cfg_attr(debug_assertions, allow(dead_code))]
use std::error::Error;
use num_derive::FromPrimitive;
use num_traits::FromPrimitive;
use std::error::Error;
use super::interface::{NetMDInterface, MDTrack, MDSession};
use super::interface::{MDSession, MDTrack, NetMDInterface};
use super::utils::cross_sleep;
#[derive(FromPrimitive)]
#[derive(PartialEq)]
pub enum OperatingStatus{
#[derive(FromPrimitive, PartialEq)]
pub enum OperatingStatus {
Ready = 50687,
Playing = 50037,
Paused = 50045,
@ -49,17 +48,27 @@ pub async fn device_status(interface: &mut NetMDInterface) -> Result<DeviceStatu
state = Some(OperatingStatus::Ready);
}
let time = Time{
let time = Time {
minute: position[2],
second: position[3],
frame: position[4],
};
Ok(DeviceStatus { disc_present, state, track, time })
Ok(DeviceStatus {
disc_present,
state,
track,
time,
})
}
pub async fn prepare_download(interface: &mut NetMDInterface) -> Result<(), Box<dyn Error>>{
while ![OperatingStatus::DiscBlank, OperatingStatus::Ready].contains(&device_status(interface).await?.state.unwrap_or(OperatingStatus::NoDisc)) {
pub async fn prepare_download(interface: &mut NetMDInterface) -> Result<(), Box<dyn Error>> {
while ![OperatingStatus::DiscBlank, OperatingStatus::Ready].contains(
&device_status(interface)
.await?
.state
.unwrap_or(OperatingStatus::NoDisc),
) {
cross_sleep(200).await;
}
@ -72,11 +81,20 @@ pub async fn prepare_download(interface: &mut NetMDInterface) -> Result<(), Box<
Ok(())
}
pub async fn download<F>(interface: &mut NetMDInterface, track: MDTrack, progress_callback: F) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>> where F: Fn(usize, usize){
pub async fn download<F>(
interface: &mut NetMDInterface,
track: MDTrack,
progress_callback: F,
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>>
where
F: Fn(usize, usize),
{
prepare_download(interface).await?;
let mut session = MDSession::new(interface);
session.init().await?;
let result = session.download_track(track, progress_callback, None).await?;
let result = session
.download_track(track, progress_callback, None)
.await?;
session.close().await?;
interface.release().await?;

View file

@ -1,15 +1,17 @@
use std::thread;
use cbc::cipher::block_padding::NoPadding;
use cbc::cipher::{KeyInit, BlockDecryptMut, KeyIvInit, BlockEncryptMut};
use tokio::sync::mpsc::{UnboundedReceiver, unbounded_channel};
use cbc::cipher::{BlockDecryptMut, BlockEncryptMut, KeyInit, KeyIvInit};
use rand::RngCore;
use std::thread;
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
use super::interface::DataEncryptorInput;
type DesEcbEnc = ecb::Decryptor<des::Des>;
type DesCbcEnc = cbc::Encryptor<des::Des>;
pub fn new_thread_encryptor(_input: DataEncryptorInput) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)> {
pub fn new_thread_encryptor(
_input: DataEncryptorInput,
) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)> {
let (tx, rx) = unbounded_channel::<(Vec<u8>, Vec<u8>, Vec<u8>)>();
let input = Box::from(_input);
thread::spawn(move || {
@ -21,14 +23,16 @@ pub fn new_thread_encryptor(_input: DataEncryptorInput) -> UnboundedReceiver<(Ve
// Encrypt it with the kek
let mut encrypted_random_key = random_key.clone();
match DesEcbEnc::new(&input.kek.into()).decrypt_padded_mut::<NoPadding>(&mut encrypted_random_key){
match DesEcbEnc::new(&input.kek.into())
.decrypt_padded_mut::<NoPadding>(&mut encrypted_random_key)
{
Err(x) => panic!("Cannot create main key {:?}", x),
Ok(_) => {}
};
let default_chunk_size = match input.chunk_size{
let default_chunk_size = match input.chunk_size {
0 => 0x00100000,
e => e
e => e,
};
let mut packet_count = 0u32;
@ -40,7 +44,7 @@ pub fn new_thread_encryptor(_input: DataEncryptorInput) -> UnboundedReceiver<(Ve
input_data.extend(std::iter::repeat(0).take(padding_remaining));
}
let input_data_length = input_data.len();
let mut offset: usize = 0;
while offset < input_data_length {
if packet_count > 0 {
@ -51,12 +55,19 @@ pub fn new_thread_encryptor(_input: DataEncryptorInput) -> UnboundedReceiver<(Ve
current_chunk_size = std::cmp::min(current_chunk_size, input_data_length - offset);
let this_data_chunk = &mut input_data[offset..offset+current_chunk_size];
DesCbcEnc::new(&random_key.into(), &iv.into()).encrypt_padded_mut::<NoPadding>(this_data_chunk, current_chunk_size).unwrap();
let this_data_chunk = &mut input_data[offset..offset + current_chunk_size];
DesCbcEnc::new(&random_key.into(), &iv.into())
.encrypt_padded_mut::<NoPadding>(this_data_chunk, current_chunk_size)
.unwrap();
tx.send((encrypted_random_key.to_vec(), iv.to_vec(), this_data_chunk.to_vec())).unwrap();
tx.send((
encrypted_random_key.to_vec(),
iv.to_vec(),
this_data_chunk.to_vec(),
))
.unwrap();
iv.copy_from_slice(&this_data_chunk[this_data_chunk.len()-8..]);
iv.copy_from_slice(&this_data_chunk[this_data_chunk.len() - 8..]);
packet_count += 1;
offset += current_chunk_size;

View file

@ -6,13 +6,13 @@ use crate::netmd::utils::{
sanitize_half_width_title, time_to_duration,
};
use cbc::cipher::block_padding::NoPadding;
use cbc::cipher::{KeyIvInit, BlockEncryptMut, BlockDecryptMut, KeyInit};
use cbc::cipher::{BlockDecryptMut, BlockEncryptMut, KeyInit, KeyIvInit};
use encoding_rs::SHIFT_JIS;
use num_derive::FromPrimitive;
use rand::RngCore;
use tokio::sync::mpsc::UnboundedReceiver;
use std::collections::HashMap;
use std::error::Error;
use tokio::sync::mpsc::UnboundedReceiver;
use lazy_static::lazy_static;
@ -226,7 +226,8 @@ impl NetMDInterface {
self.change_descriptor_state(
&Descriptor::DiscSubunitIdentifier,
&DescriptorAction::OpenRead,
).await;
)
.await;
let mut query = format_query("1809 00 ff00 0000 0000".to_string(), vec![])?;
@ -294,7 +295,8 @@ impl NetMDInterface {
let _manufacturer_dep_data =
&buffer[buffer_offset..buffer_offset + manufacturer_dep_length as usize];
self.change_descriptor_state(&Descriptor::DiscSubunitIdentifier, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::DiscSubunitIdentifier, &DescriptorAction::Close)
.await;
for media in supported_media_type_specifications {
if media.supported_media_type != 0x301 {
@ -324,7 +326,11 @@ impl NetMDInterface {
Ok(result)
}
async fn change_descriptor_state(&mut self, descriptor: &Descriptor, action: &DescriptorAction) {
async fn change_descriptor_state(
&mut self,
descriptor: &Descriptor,
action: &DescriptorAction,
) {
let mut query = format_query("1808".to_string(), vec![]).unwrap();
query.append(&mut descriptor.get_array());
@ -392,7 +398,6 @@ impl NetMDInterface {
let sleep_time = Self::INTERIM_RESPONSE_RETRY_INTERVAL
* (u32::pow(2, current_attempt as u32) - 1);
cross_sleep(sleep_time).await;
current_attempt += 1;
@ -475,7 +480,8 @@ impl NetMDInterface {
self.change_descriptor_state(
&Descriptor::OperatingStatusBlock,
&DescriptorAction::OpenRead,
).await;
)
.await;
let mut query = format_query(
"1809 8001 0230 8800 0030 8804 00 ff00 00000000".to_string(),
@ -489,7 +495,8 @@ impl NetMDInterface {
"1809 8001 0230 8800 0030 8804 00 1000 00090000 %x".to_string(),
)?;
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
.await;
let final_array = res[0].to_vec().unwrap();
@ -509,7 +516,8 @@ impl NetMDInterface {
self.change_descriptor_state(
&Descriptor::OperatingStatusBlock,
&DescriptorAction::OpenRead,
).await;
)
.await;
let mut query = format_query(
"1809 8001 0330 8802 0030 8805 0030 8806 00 ff00 00000000".to_string(),
vec![],
@ -525,7 +533,8 @@ impl NetMDInterface {
let operating_status = result[1].to_vec().unwrap();
let status_mode = result[0].to_i64().unwrap() as u8;
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
.await;
if operating_status.len() < 2 {
return Err("Unparsable operating system".into());
@ -547,7 +556,8 @@ impl NetMDInterface {
self.change_descriptor_state(
&Descriptor::OperatingStatusBlock,
&DescriptorAction::OpenRead,
).await;
)
.await;
let mut query = format_query(
"1809 8001 0330 %w 0030 8805 0030 %w 00 ff00 00000000".to_string(),
vec![QueryValue::Number(p1 as i64), QueryValue::Number(p2 as i64)],
@ -561,7 +571,8 @@ impl NetMDInterface {
"1809 8001 0330 %?%? %?%? %?%? %?%? %?%? %? 1000 00%?0000 %x %?".to_string(),
);
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
.await;
Ok(res.unwrap()[0].to_vec().unwrap())
}
@ -578,7 +589,8 @@ impl NetMDInterface {
self.change_descriptor_state(
&Descriptor::OperatingStatusBlock,
&DescriptorAction::OpenRead,
).await;
)
.await;
let mut query = format_query(
"1809 8001 0430 8802 0030 8805 0030 0003 0030 0002 00 ff00 00000000".to_string(),
@ -602,7 +614,8 @@ impl NetMDInterface {
result[4].to_i64().unwrap() as u16,
];
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
.await;
Ok(final_result)
}
@ -709,21 +722,24 @@ impl NetMDInterface {
// TODO: Ensure this is returning the correct value, it
// looks like it actually might be a 16 bit integer
pub async fn disc_flags(&mut self) -> Result<u8, Box<dyn Error>> {
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead)
.await;
let mut query = format_query("1806 01101000 ff00 0001000b".to_string(), vec![]).unwrap();
let reply = self.send_query(&mut query, false, false).await?;
let res = scan_query(reply, "1806 01101000 1000 0001000b %b".to_string()).unwrap();
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close)
.await;
Ok(res[0].to_i64().unwrap() as u8)
}
/// The number of tracks on the disc
pub async fn track_count(&mut self) -> Result<u16, Box<dyn Error>> {
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
.await;
let mut query =
format_query("1806 02101001 3000 1000 ff00 00000000".to_string(), vec![]).unwrap();
@ -736,14 +752,17 @@ impl NetMDInterface {
)
.unwrap();
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
.await;
Ok(res[0].to_i64().unwrap() as u16)
}
async fn raw_disc_title(&mut self, wchar: bool) -> Result<String, Box<dyn Error>> {
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
.await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead)
.await;
let mut done: i32 = 0;
let mut remaining: i32 = 0;
@ -797,8 +816,10 @@ impl NetMDInterface {
let res = result.join("");
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close)
.await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
.await;
Ok(res)
}
@ -931,7 +952,8 @@ impl NetMDInterface {
false => Descriptor::AudioUTOC1TD,
};
self.change_descriptor_state(&descriptor_type, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&descriptor_type, &DescriptorAction::OpenRead)
.await;
let mut track_titles: Vec<String> = vec![];
for i in tracks {
@ -960,7 +982,8 @@ impl NetMDInterface {
)
}
self.change_descriptor_state(&descriptor_type, &DescriptorAction::Close).await;
self.change_descriptor_state(&descriptor_type, &DescriptorAction::Close)
.await;
Ok(track_titles)
}
@ -976,11 +999,7 @@ impl NetMDInterface {
}
// Sets the title of the disc
pub async fn set_disc_title(
&mut self,
title: &str,
wchar: bool,
) -> Result<(), Box<dyn Error>> {
pub async fn set_disc_title(&mut self, title: &str, wchar: bool) -> Result<(), Box<dyn Error>> {
let current_title = self.raw_disc_title(wchar).await?;
if current_title == title {
return Err("Title is already the same".into());
@ -1003,10 +1022,13 @@ impl NetMDInterface {
let new_len = new_title.len();
if self.net_md_device.vendor_id().await == &0x04dd {
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::OpenWrite).await
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::OpenWrite)
.await
} else {
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenWrite).await
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close)
.await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenWrite)
.await
}
let mut query = format_query(
@ -1022,11 +1044,15 @@ impl NetMDInterface {
let _ = self.send_query(&mut query, false, false).await;
if self.net_md_device.vendor_id().await == &0x04dd {
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::Close).await
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::Close)
.await
} else {
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close)
.await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::OpenRead)
.await;
self.change_descriptor_state(&Descriptor::DiscTitleTD, &DescriptorAction::Close)
.await;
}
Ok(())
@ -1064,7 +1090,8 @@ impl NetMDInterface {
Err(error) => return Err(error),
};
self.change_descriptor_state(&descriptor, &DescriptorAction::OpenWrite).await;
self.change_descriptor_state(&descriptor, &DescriptorAction::OpenWrite)
.await;
let mut query = format_query(
"1807 022018%b %w 3000 0a00 5000 %w 0000 %w %*".to_string(),
vec![
@ -1081,7 +1108,8 @@ impl NetMDInterface {
reply,
"1807 022018%? %?%? 3000 0a00 5000 %?%? 0000 %?%?".to_string(),
);
self.change_descriptor_state(&descriptor, &DescriptorAction::Close).await;
self.change_descriptor_state(&descriptor, &DescriptorAction::Close)
.await;
Ok(())
}
@ -1119,7 +1147,8 @@ impl NetMDInterface {
p1: i32,
p2: i32,
) -> Result<Vec<u8>, Box<dyn Error>> {
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
.await;
let mut query = format_query(
"1806 02201001 %w %w %w ff00 00000000".to_string(),
@ -1136,7 +1165,8 @@ impl NetMDInterface {
"1806 02201001 %?%? %?%? %?%? 1000 00%?0000 %x".to_string(),
)?;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
.await;
Ok(res[0].to_vec().unwrap())
}
@ -1148,7 +1178,8 @@ impl NetMDInterface {
) -> Result<Vec<std::time::Duration>, Box<dyn Error>> {
let mut times: Vec<std::time::Duration> = vec![];
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
.await;
for track in tracks {
let mut query = format_query(
"1806 02201001 %w %w %w ff00 00000000".to_string(),
@ -1180,7 +1211,8 @@ impl NetMDInterface {
times.push(length);
}
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
.await;
Ok(times)
}
@ -1211,7 +1243,8 @@ impl NetMDInterface {
/// Gets a track's flags
pub async fn track_flags(&mut self, track: u16) -> Result<u8, Box<dyn Error>> {
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::OpenRead)
.await;
let mut query = format_query(
"1806 01201001 %w ff00 00010008".to_string(),
vec![QueryValue::Number(track as i64)],
@ -1220,14 +1253,16 @@ impl NetMDInterface {
let res = scan_query(reply, "1806 01201001 %?%? 10 00 00010008 %b".to_string())?;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::AudioContentsTD, &DescriptorAction::Close)
.await;
Ok(res[0].to_i64().unwrap() as u8)
}
/// Gets the disc capacity as a `std::time::Duration`
pub async fn disc_capacity(&mut self) -> Result<[std::time::Duration; 3], Box<dyn Error>> {
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead).await;
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::OpenRead)
.await;
let mut query = format_query("1806 02101000 3080 0300 ff00 00000000".to_string(), vec![])?;
let reply = self.send_query(&mut query, false, false).await?;
let mut result: [std::time::Duration; 3] = [std::time::Duration::from_secs(0); 3];
@ -1250,7 +1285,8 @@ impl NetMDInterface {
result[i] = std::time::Duration::from_micros(time_micros);
}
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::RootTD, &DescriptorAction::Close)
.await;
Ok(result)
}
@ -1259,7 +1295,8 @@ impl NetMDInterface {
self.change_descriptor_state(
&Descriptor::OperatingStatusBlock,
&DescriptorAction::OpenRead,
).await;
)
.await;
let mut query = format_query(
"1809 8001 0330 8801 0030 8805 0030 8807 00 ff00 00000000".to_string(),
vec![],
@ -1269,7 +1306,8 @@ impl NetMDInterface {
let res = scan_query(reply, "1809 8001 0330 8801 0030 8805 0030 8807 00 1000 000e0000 000c 8805 0008 80e0 0110 %b %b 4000".to_string())?;
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close).await;
self.change_descriptor_state(&Descriptor::OperatingStatusBlock, &DescriptorAction::Close)
.await;
Ok(res.into_iter().map(|x| x.to_i64().unwrap() as u8).collect())
}
@ -1448,7 +1486,9 @@ impl NetMDInterface {
}
let mut message = [vec![1, 1, 1, 1], contentid.to_vec(), keyenckey.to_vec()].concat();
DesCbcEnc::new(hex_session_key.into(), &[0u8; 8].into()).encrypt_padded_mut::<NoPadding>(message.as_mut_slice(), 32).unwrap();
DesCbcEnc::new(hex_session_key.into(), &[0u8; 8].into())
.encrypt_padded_mut::<NoPadding>(message.as_mut_slice(), 32)
.unwrap();
let mut query = format_query(
"1800 080046 f0030103 22 ff 0000 %*".to_string(),
@ -1472,7 +1512,9 @@ impl NetMDInterface {
}
let mut message = [0u8; 8];
DesEcbEnc::new(hex_session_key.into()).encrypt_padded_mut::<NoPadding>(&mut message, 8).unwrap();
DesEcbEnc::new(hex_session_key.into())
.encrypt_padded_mut::<NoPadding>(&mut message, 8)
.unwrap();
let mut query = format_query(
"1800 080046 f0030103 48 ff 00 1001 %w %*".to_string(),
@ -1498,8 +1540,11 @@ impl NetMDInterface {
// key // iv // data
mut packets: UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>,
hex_session_key: &[u8],
progress_callback: F
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>> where F: Fn(usize, usize) {
progress_callback: F,
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>>
where
F: Fn(usize, usize),
{
if hex_session_key.len() != 8 {
return Err("Supplied Session Key length wrong".into());
}
@ -1530,7 +1575,7 @@ impl NetMDInterface {
let mut _written_bytes = 0;
let mut packet_count = 0;
while let Some((key, iv, data)) = packets.recv().await {
let binpack = if packet_count == 0 {
let packed_length: Vec<u8> = pkt_size.to_be_bytes().to_vec();
@ -1556,7 +1601,9 @@ impl NetMDInterface {
)?;
let mut encrypted_data = res[1].to_vec().unwrap();
DesCbcDec::new(hex_session_key.into(), &[0u8; 8].into()).decrypt_padded_mut::<NoPadding>(&mut encrypted_data).unwrap();
DesCbcDec::new(hex_session_key.into(), &[0u8; 8].into())
.decrypt_padded_mut::<NoPadding>(&mut encrypted_data)
.unwrap();
let part1 = encrypted_data[0..8].to_vec();
let part2 = encrypted_data[12..32].to_vec();
@ -1591,21 +1638,25 @@ type TDesCbcEnc = cbc::Encryptor<des::TdesEde3>;
pub fn retailmac(key: &[u8], value: &[u8], iv: &[u8; 8]) -> Vec<u8> {
let mut subkey_a = [0u8; 8];
subkey_a.clone_from_slice(&key[0..8]);
let mut beginning = [0u8; 8];
beginning.clone_from_slice(&value[0..8]);
let mut end = [0u8; 8];
end.clone_from_slice(&value[8..]);
DesCbcEnc::new(&subkey_a.into(), iv.into()).encrypt_padded_mut::<NoPadding>(&mut beginning, 8).unwrap();
DesCbcEnc::new(&subkey_a.into(), iv.into())
.encrypt_padded_mut::<NoPadding>(&mut beginning, 8)
.unwrap();
let iv2 = &beginning[beginning.len() - 8..];
let mut wonky_key = [0u8; 24];
wonky_key[0..16].clone_from_slice(&key);
wonky_key[16..].clone_from_slice(&key[0..8]);
TDesCbcEnc::new(&wonky_key.into(), iv2.into()).encrypt_padded_mut::<NoPadding>(&mut end, 8).unwrap();
TDesCbcEnc::new(&wonky_key.into(), iv2.into())
.encrypt_padded_mut::<NoPadding>(&mut end, 8)
.unwrap();
end[..8].to_vec()
}
@ -1642,13 +1693,19 @@ impl EKBOpenSource {
pub fn ekb_data_for_leaf_id(&self) -> EKBData {
EKBData {
chains: [
[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],
[
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,
],
],
depth: 9,
signature: [
0x8f, 0x2b, 0xc3, 0x52, 0xe8, 0x6c, 0x5e, 0xd3, 0x06, 0xdc, 0xae, 0x18,
0xd2, 0xf3, 0x8c, 0x7f, 0x89, 0xb5, 0xe1, 0x85, 0x55, 0xa1, 0x05, 0xea,
0x8f, 0x2b, 0xc3, 0x52, 0xe8, 0x6c, 0x5e, 0xd3, 0x06, 0xdc, 0xae, 0x18, 0xd2, 0xf3,
0x8c, 0x7f, 0x89, 0xb5, 0xe1, 0x85, 0x55, 0xa1, 0x05, 0xea,
],
}
}
@ -1660,7 +1717,8 @@ pub struct MDTrack {
pub data: Vec<u8>,
pub chunk_size: usize,
pub full_width_title: Option<String>,
pub encrypt_packets_iterator: Box<dyn Fn(DataEncryptorInput) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>>,
pub encrypt_packets_iterator:
Box<dyn Fn(DataEncryptorInput) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>>,
}
pub struct DataEncryptorInput {
@ -1715,12 +1773,12 @@ impl MDTrack {
[0x14, 0xe3, 0x83, 0x4e, 0xe2, 0xd3, 0xcc, 0xa5]
}
pub fn get_encrypting_iterator(&mut self) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>{
pub fn get_encrypting_iterator(&mut self) -> UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)> {
(self.encrypt_packets_iterator)(DataEncryptorInput {
kek: self.get_kek().clone(),
frame_size: self.frame_size(),
chunk_size: self.chunk_size(),
data: std::mem::take(&mut self.data)
data: std::mem::take(&mut self.data),
})
}
}
@ -1732,18 +1790,25 @@ pub struct MDSession<'a> {
}
impl<'a> MDSession<'a> {
pub async fn init(&mut self) -> Result<(), Box<dyn Error>>{
pub async fn init(&mut self) -> Result<(), Box<dyn Error>> {
self.md.enter_secure_session().await?;
self.md.leaf_id().await?;
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).await?;
self.md
.send_key_data(
self.ekb_object.ekb_id(),
ekb.chains,
ekb.depth,
ekb.signature,
)
.await?;
let mut nonce = vec![0u8; 8];
rand::thread_rng().fill_bytes(&mut nonce);
let mut devnonce = self.md.session_key_exchange(nonce.clone()).await?;
nonce.append(&mut devnonce);
self.hex_session_key = Some(retailmac(&self.ekb_object.root_key(), &nonce, &[0u8; 8]));
Ok(())
}
@ -1757,30 +1822,52 @@ impl<'a> MDSession<'a> {
Ok(())
}
pub async fn download_track<F>(&mut self, mut track: MDTrack, progress_callback: F, disc_format: Option<DiscFormat>) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>> where F: Fn(usize, usize) {
if let None = self.hex_session_key{
pub async fn download_track<F>(
&mut self,
mut track: MDTrack,
progress_callback: F,
disc_format: Option<DiscFormat>,
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>>
where
F: Fn(usize, usize),
{
if let None = self.hex_session_key {
return Err("Cannot download a track using a non-init()'ed session!".into());
}
self.md.setup_download(&track.content_id(), &track.get_kek(), &self.hex_session_key.as_ref().unwrap()).await?;
self.md
.setup_download(
&track.content_id(),
&track.get_kek(),
&self.hex_session_key.as_ref().unwrap(),
)
.await?;
let data_format = track.data_format();
let final_disc_format = disc_format.unwrap_or(*DISC_FOR_WIRE.get(&data_format).unwrap());
let (track_index, uuid, ccid) = self.md.send_track(
data_format as u8,
final_disc_format as u8,
track.frame_count() as u32,
track.total_size() as u32,
track.get_encrypting_iterator(),
self.hex_session_key.as_ref().unwrap().as_slice(),
progress_callback
).await?;
let (track_index, uuid, ccid) = self
.md
.send_track(
data_format as u8,
final_disc_format as u8,
track.frame_count() as u32,
track.total_size() as u32,
track.get_encrypting_iterator(),
self.hex_session_key.as_ref().unwrap().as_slice(),
progress_callback,
)
.await?;
self.md.set_track_title(track_index, &track.title, false).await?;
self.md
.set_track_title(track_index, &track.title, false)
.await?;
if let Some(full_width) = track.full_width_title {
self.md.set_track_title(track_index, &full_width, true).await?;
self.md
.set_track_title(track_index, &full_width, true)
.await?;
}
self.md.commit_track(track_index, &self.hex_session_key.as_ref().unwrap()).await?;
self.md
.commit_track(track_index, &self.hex_session_key.as_ref().unwrap())
.await?;
Ok((track_index, uuid, ccid))
}

View file

@ -5,9 +5,9 @@
*/
mod base;
pub mod commands;
pub mod encryption;
pub mod interface;
mod mappings;
mod query_utils;
mod utils;
pub mod commands;
pub mod encryption;