mirror of
https://github.com/G2-Games/minidisc-cli.git
synced 2025-04-19 11:42:53 -05:00
Started restructuring commands.rs
, updated cross_usb
to 0.3.0
This commit is contained in:
parent
c292b4b533
commit
4151a4f5c0
5 changed files with 129 additions and 109 deletions
|
@ -28,7 +28,7 @@ once_cell = "1.18.0"
|
||||||
unicode-normalization = "0.1.22"
|
unicode-normalization = "0.1.22"
|
||||||
regex = "1.10.2"
|
regex = "1.10.2"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
cross_usb = "0.2"
|
cross_usb = "0.3"
|
||||||
num-derive = "0.3.3"
|
num-derive = "0.3.3"
|
||||||
num-traits = "0.2.14"
|
num-traits = "0.2.14"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/// A crate for controlling NetMD and Hi-MD devices.
|
/// A crate for controlling NetMD and Hi-MD devices.
|
||||||
///
|
///
|
||||||
/// To use this library, first you need to get a device from [cross-usb] and then open a [netmd::interface::NetMDInterface]
|
/// To use this library, first you need to get a device from [cross-usb] and then open [netmd::interface::NetMDInterface]
|
||||||
|
|
||||||
pub mod netmd;
|
pub mod netmd;
|
||||||
|
|
|
@ -6,8 +6,9 @@ use once_cell::sync::Lazy;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
// USB stuff
|
// USB stuff
|
||||||
use cross_usb::usb::{ControlIn, ControlOut, ControlType, Device, Interface, Recipient, UsbError};
|
use cross_usb::prelude::*;
|
||||||
use cross_usb::{UsbDevice, UsbInterface};
|
use cross_usb::usb::{ControlIn, ControlOut, ControlType, Recipient, UsbError};
|
||||||
|
use cross_usb::{Interface, Descriptor};
|
||||||
|
|
||||||
use super::utils::cross_sleep;
|
use super::utils::cross_sleep;
|
||||||
|
|
||||||
|
@ -116,7 +117,7 @@ pub enum NetMDError {
|
||||||
|
|
||||||
/// A USB connection to a NetMD device
|
/// A USB connection to a NetMD device
|
||||||
pub struct NetMD {
|
pub struct NetMD {
|
||||||
usb_interface: UsbInterface,
|
usb_interface: Interface,
|
||||||
model: DeviceId,
|
model: DeviceId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,10 +125,10 @@ impl NetMD {
|
||||||
const READ_REPLY_RETRY_INTERVAL: u32 = 10;
|
const READ_REPLY_RETRY_INTERVAL: u32 = 10;
|
||||||
|
|
||||||
/// Creates a new interface to a NetMD device
|
/// Creates a new interface to a NetMD device
|
||||||
pub async fn new(usb_device: &UsbDevice) -> Result<Self, NetMDError> {
|
pub async fn new(usb_descriptor: Descriptor) -> Result<Self, NetMDError> {
|
||||||
let mut model = DeviceId {
|
let mut model = DeviceId {
|
||||||
vendor_id: usb_device.vendor_id().await,
|
vendor_id: usb_descriptor.vendor_id().await,
|
||||||
product_id: usb_device.product_id().await,
|
product_id: usb_descriptor.product_id().await,
|
||||||
name: None,
|
name: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -145,6 +146,7 @@ impl NetMD {
|
||||||
Some(_) => (),
|
Some(_) => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let usb_device = usb_descriptor.open().await?;
|
||||||
let usb_interface = usb_device.open_interface(0).await?;
|
let usb_interface = usb_device.open_interface(0).await?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
|
@ -3,11 +3,12 @@ use num_derive::FromPrimitive;
|
||||||
use num_traits::FromPrimitive;
|
use num_traits::FromPrimitive;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use cross_usb::Descriptor;
|
||||||
|
|
||||||
use super::interface::{MDSession, MDTrack, NetMDInterface};
|
use super::interface::{MDSession, MDTrack, NetMDInterface, Direction, InterfaceError};
|
||||||
use super::utils::cross_sleep;
|
use super::utils::cross_sleep;
|
||||||
|
|
||||||
#[derive(FromPrimitive, PartialEq)]
|
#[derive(FromPrimitive, PartialEq, Eq)]
|
||||||
pub enum OperatingStatus {
|
pub enum OperatingStatus {
|
||||||
Ready = 50687,
|
Ready = 50687,
|
||||||
Playing = 50037,
|
Playing = 50037,
|
||||||
|
@ -33,71 +34,102 @@ pub struct DeviceStatus {
|
||||||
pub time: Time,
|
pub time: Time,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn device_status(interface: &mut NetMDInterface) -> Result<DeviceStatus, Box<dyn Error>> {
|
pub struct NetMDContext {
|
||||||
let status = interface.status().await?;
|
interface: NetMDInterface,
|
||||||
let playback_status = interface.playback_status2().await?;
|
}
|
||||||
let b1: u16 = playback_status[4] as u16;
|
|
||||||
let b2: u16 = playback_status[5] as u16;
|
|
||||||
let position = interface.position().await?;
|
|
||||||
let operating_status = b1 << 8 | b2;
|
|
||||||
|
|
||||||
let track = position[0] as u8;
|
impl NetMDContext {
|
||||||
let disc_present = status[4] != 0x80;
|
/// Create a new context to control a NetMD device
|
||||||
let mut state: Option<OperatingStatus> = FromPrimitive::from_u16(operating_status);
|
pub async fn new(device: Descriptor) -> Result<Self, InterfaceError> {
|
||||||
|
let interface = NetMDInterface::new(device).await?;
|
||||||
|
|
||||||
if state == Some(OperatingStatus::Playing) && !disc_present {
|
Ok(Self {
|
||||||
state = Some(OperatingStatus::Ready);
|
interface,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let time = Time {
|
/// Change to the next track (skip forward)
|
||||||
minute: position[2],
|
pub async fn next_track(&mut self) -> Result<(), InterfaceError> {
|
||||||
second: position[3],
|
self.interface.track_change(Direction::Next).await
|
||||||
frame: position[4],
|
|
||||||
};
|
|
||||||
|
|
||||||
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),
|
|
||||||
) {
|
|
||||||
cross_sleep(Duration::from_millis(200)).await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let _ = interface.session_key_forget().await;
|
/// Change to the next track (skip back)
|
||||||
let _ = interface.leave_secure_session().await;
|
pub async fn previous_track(&mut self) -> Result<(), InterfaceError> {
|
||||||
|
self.interface.track_change(Direction::Previous).await
|
||||||
|
}
|
||||||
|
|
||||||
interface.acquire().await?;
|
/// Change to the next track (skip to beginning of track)
|
||||||
let _ = interface.disable_new_track_protection(1).await;
|
pub async fn restart_track(&mut self) -> Result<(), InterfaceError> {
|
||||||
|
self.interface.track_change(Direction::Restart).await
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
pub async fn device_status(&mut self) -> Result<DeviceStatus, Box<dyn Error>> {
|
||||||
}
|
let status = self.interface.status().await?;
|
||||||
|
let playback_status = self.interface.playback_status2().await?;
|
||||||
pub async fn download<F>(
|
let b1: u16 = playback_status[4] as u16;
|
||||||
interface: &mut NetMDInterface,
|
let b2: u16 = playback_status[5] as u16;
|
||||||
track: MDTrack,
|
let position = self.interface.position().await?;
|
||||||
progress_callback: F,
|
let operating_status = b1 << 8 | b2;
|
||||||
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>>
|
|
||||||
where
|
let track = position[0] as u8;
|
||||||
F: Fn(usize, usize),
|
let disc_present = status[4] != 0x80;
|
||||||
{
|
let mut state: Option<OperatingStatus> = FromPrimitive::from_u16(operating_status);
|
||||||
prepare_download(interface).await?;
|
|
||||||
let mut session = MDSession::new(interface);
|
if state == Some(OperatingStatus::Playing) && !disc_present {
|
||||||
session.init().await?;
|
state = Some(OperatingStatus::Ready);
|
||||||
let result = session
|
}
|
||||||
.download_track(track, progress_callback, None)
|
|
||||||
.await?;
|
let time = Time {
|
||||||
session.close().await?;
|
minute: position[2],
|
||||||
interface.release().await?;
|
second: position[3],
|
||||||
|
frame: position[4],
|
||||||
Ok(result)
|
};
|
||||||
|
|
||||||
|
Ok(DeviceStatus {
|
||||||
|
disc_present,
|
||||||
|
state,
|
||||||
|
track,
|
||||||
|
time,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn prepare_download(&mut self) -> Result<(), Box<dyn Error>> {
|
||||||
|
while ![OperatingStatus::DiscBlank, OperatingStatus::Ready].contains(
|
||||||
|
&self.device_status()
|
||||||
|
.await?
|
||||||
|
.state
|
||||||
|
.unwrap_or(OperatingStatus::NoDisc),
|
||||||
|
) {
|
||||||
|
cross_sleep(Duration::from_millis(200)).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = self.interface.session_key_forget().await;
|
||||||
|
let _ = self.interface.leave_secure_session().await;
|
||||||
|
|
||||||
|
self.interface.acquire().await?;
|
||||||
|
let _ = self.interface.disable_new_track_protection(1).await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn download<F>(
|
||||||
|
&mut self,
|
||||||
|
track: MDTrack,
|
||||||
|
progress_callback: F,
|
||||||
|
) -> Result<(u16, Vec<u8>, Vec<u8>), Box<dyn Error>>
|
||||||
|
where
|
||||||
|
F: Fn(usize, usize),
|
||||||
|
{
|
||||||
|
self.prepare_download().await?;
|
||||||
|
// Lock the interface by providing it to the session
|
||||||
|
let mut session = MDSession::new(&mut self.interface);
|
||||||
|
session.init().await?;
|
||||||
|
let result = session
|
||||||
|
.download_track(track, progress_callback, None)
|
||||||
|
.await?;
|
||||||
|
session.close().await?;
|
||||||
|
self.interface.release().await?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ enum Action {
|
||||||
Rewind = 0x49,
|
Rewind = 0x49,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Track {
|
pub enum Direction {
|
||||||
Previous = 0x0002,
|
Previous = 0x0002,
|
||||||
Next = 0x8001,
|
Next = 0x8001,
|
||||||
Restart = 0x0001,
|
Restart = 0x0001,
|
||||||
|
@ -260,7 +260,7 @@ pub enum InterfaceError {
|
||||||
|
|
||||||
/// An interface for interacting with a NetMD device
|
/// An interface for interacting with a NetMD device
|
||||||
pub struct NetMDInterface {
|
pub struct NetMDInterface {
|
||||||
pub net_md_device: NetMD,
|
pub device: NetMD,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
@ -269,9 +269,9 @@ impl NetMDInterface {
|
||||||
const INTERIM_RESPONSE_RETRY_INTERVAL: u32 = 100;
|
const INTERIM_RESPONSE_RETRY_INTERVAL: u32 = 100;
|
||||||
|
|
||||||
/// Get a new interface to a NetMD device
|
/// Get a new interface to a NetMD device
|
||||||
pub async fn new(device: &cross_usb::UsbDevice) -> Result<Self, InterfaceError> {
|
pub async fn new(device: cross_usb::Descriptor) -> Result<Self, InterfaceError> {
|
||||||
let net_md_device = base::NetMD::new(device).await?;
|
let device = base::NetMD::new(device).await?;
|
||||||
Ok(NetMDInterface { net_md_device })
|
Ok(NetMDInterface { device })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct_multibyte(&mut self, buffer: &[u8], n: u8, offset: &mut usize) -> u32 {
|
fn construct_multibyte(&mut self, buffer: &[u8], n: u8, offset: &mut usize) -> u32 {
|
||||||
|
@ -432,7 +432,7 @@ impl NetMDInterface {
|
||||||
new_query.push(status_byte as u8);
|
new_query.push(status_byte as u8);
|
||||||
new_query.append(query);
|
new_query.append(query);
|
||||||
|
|
||||||
self.net_md_device.send_command(new_query).await?;
|
self.device.send_command(new_query).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -442,15 +442,15 @@ impl NetMDInterface {
|
||||||
let mut data;
|
let mut data;
|
||||||
|
|
||||||
while current_attempt < Self::MAX_INTERIM_READ_ATTEMPTS {
|
while current_attempt < Self::MAX_INTERIM_READ_ATTEMPTS {
|
||||||
data = self.net_md_device.read_reply(None).await?;
|
data = self.device.read_reply(None).await?;
|
||||||
|
|
||||||
let status = NetmdStatus::try_from(data[0])?;
|
let status = NetmdStatus::try_from(data[0])?;
|
||||||
|
|
||||||
match status {
|
match status {
|
||||||
NetmdStatus::NotImplemented => {
|
NetmdStatus::NotImplemented => {
|
||||||
return Err(InterfaceError::NotImplemented(format!("{:X?}", data)))
|
return Err(InterfaceError::NotImplemented(format!("{:02X?}", data)))
|
||||||
}
|
}
|
||||||
NetmdStatus::Rejected => return Err(InterfaceError::Rejected(format!("{:X?}", data))),
|
NetmdStatus::Rejected => return Err(InterfaceError::Rejected(format!("{:02X?}", data))),
|
||||||
NetmdStatus::Interim if !accept_interim => {
|
NetmdStatus::Interim if !accept_interim => {
|
||||||
let sleep_time = Self::INTERIM_RESPONSE_RETRY_INTERVAL
|
let sleep_time = Self::INTERIM_RESPONSE_RETRY_INTERVAL
|
||||||
* (u32::pow(2, current_attempt as u32) - 1);
|
* (u32::pow(2, current_attempt as u32) - 1);
|
||||||
|
@ -466,7 +466,7 @@ impl NetMDInterface {
|
||||||
}
|
}
|
||||||
return Ok(data);
|
return Ok(data);
|
||||||
}
|
}
|
||||||
_ => return Err(InterfaceError::Unknown(format!("{:X?}", data))),
|
_ => return Err(InterfaceError::Unknown(format!("{:02X?}", data))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,6 +693,7 @@ impl NetMDInterface {
|
||||||
let mut query = format_query("18c1 ff 6000".to_string(), vec![]).unwrap();
|
let mut query = format_query("18c1 ff 6000".to_string(), vec![]).unwrap();
|
||||||
|
|
||||||
let _reply = self.send_query(&mut query, false, false).await?;
|
let _reply = self.send_query(&mut query, false, false).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,7 +754,7 @@ impl NetMDInterface {
|
||||||
Ok(value as u16)
|
Ok(value as u16)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn track_change(&mut self, direction: Track) -> Result<(), InterfaceError> {
|
pub async fn track_change(&mut self, direction: Direction) -> Result<(), InterfaceError> {
|
||||||
let mut query = format_query(
|
let mut query = format_query(
|
||||||
"1850 ff10 00000000 %w".to_string(),
|
"1850 ff10 00000000 %w".to_string(),
|
||||||
vec![QueryValue::Number(direction as i64)],
|
vec![QueryValue::Number(direction as i64)],
|
||||||
|
@ -767,21 +768,6 @@ impl NetMDInterface {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change to the next track (skip forward)
|
|
||||||
pub async fn next_track(&mut self) -> Result<(), InterfaceError> {
|
|
||||||
self.track_change(Track::Next).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Change to the next track (skip back)
|
|
||||||
pub async fn previous_track(&mut self) -> Result<(), InterfaceError> {
|
|
||||||
self.track_change(Track::Previous).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Change to the next track (skip to beginning of track)
|
|
||||||
pub async fn restart_track(&mut self) -> Result<(), InterfaceError> {
|
|
||||||
self.track_change(Track::Restart).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Erase the disc entirely
|
/// Erase the disc entirely
|
||||||
pub async fn erase_disc(&mut self) -> Result<(), InterfaceError> {
|
pub async fn erase_disc(&mut self) -> Result<(), InterfaceError> {
|
||||||
let mut query = format_query("1840 ff 0000".to_string(), vec![]).unwrap();
|
let mut query = format_query("1840 ff 0000".to_string(), vec![]).unwrap();
|
||||||
|
@ -1094,7 +1080,7 @@ impl NetMDInterface {
|
||||||
|
|
||||||
let new_len = new_title.len();
|
let new_len = new_title.len();
|
||||||
|
|
||||||
if self.net_md_device.vendor_id() == 0x04dd {
|
if self.device.vendor_id() == 0x04dd {
|
||||||
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::OpenWrite)
|
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::OpenWrite)
|
||||||
.await?
|
.await?
|
||||||
} else {
|
} else {
|
||||||
|
@ -1116,7 +1102,7 @@ impl NetMDInterface {
|
||||||
|
|
||||||
let _ = self.send_query(&mut query, false, false).await;
|
let _ = self.send_query(&mut query, false, false).await;
|
||||||
|
|
||||||
if self.net_md_device.vendor_id() == 0x04dd {
|
if self.device.vendor_id() == 0x04dd {
|
||||||
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::Close)
|
self.change_descriptor_state(&Descriptor::AudioUTOC1TD, &DescriptorAction::Close)
|
||||||
.await?
|
.await?
|
||||||
} else {
|
} else {
|
||||||
|
@ -1414,7 +1400,7 @@ impl NetMDInterface {
|
||||||
let codec = res[1].to_i64().unwrap() as u8;
|
let codec = res[1].to_i64().unwrap() as u8;
|
||||||
let length = res[2].to_i64().unwrap() as usize;
|
let length = res[2].to_i64().unwrap() as usize;
|
||||||
|
|
||||||
let result = self.net_md_device.read_bulk(length, 0x10000).await?;
|
let result = self.device.read_bulk(length, 0x10000).await?;
|
||||||
|
|
||||||
scan_query(
|
scan_query(
|
||||||
self.read_reply(false).await?,
|
self.read_reply(false).await?,
|
||||||
|
@ -1613,7 +1599,7 @@ impl NetMDInterface {
|
||||||
discformat: u8,
|
discformat: u8,
|
||||||
frames: u32,
|
frames: u32,
|
||||||
pkt_size: u32,
|
pkt_size: u32,
|
||||||
// key // iv // data
|
// key, iv, data
|
||||||
mut packets: UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>,
|
mut packets: UnboundedReceiver<(Vec<u8>, Vec<u8>, Vec<u8>)>,
|
||||||
hex_session_key: &[u8],
|
hex_session_key: &[u8],
|
||||||
progress_callback: F,
|
progress_callback: F,
|
||||||
|
@ -1644,7 +1630,7 @@ impl NetMDInterface {
|
||||||
reply,
|
reply,
|
||||||
"1800 080046 f0030103 28 00 000100 1001 %?%? 00 %*".to_string(),
|
"1800 080046 f0030103 28 00 000100 1001 %?%? 00 %*".to_string(),
|
||||||
)?;
|
)?;
|
||||||
self.net_md_device.poll().await?;
|
self.device.poll().await?;
|
||||||
|
|
||||||
// Sharps are slow
|
// Sharps are slow
|
||||||
cross_sleep(Duration::from_millis(200)).await;
|
cross_sleep(Duration::from_millis(200)).await;
|
||||||
|
@ -1659,7 +1645,7 @@ impl NetMDInterface {
|
||||||
} else {
|
} else {
|
||||||
data
|
data
|
||||||
};
|
};
|
||||||
self.net_md_device.write_bulk(&binpack).await?;
|
self.device.write_bulk(&binpack).await?;
|
||||||
_written_bytes += binpack.len();
|
_written_bytes += binpack.len();
|
||||||
packet_count += 1;
|
packet_count += 1;
|
||||||
(progress_callback)(total_bytes, _written_bytes);
|
(progress_callback)(total_bytes, _written_bytes);
|
||||||
|
@ -1670,7 +1656,7 @@ impl NetMDInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
reply = self.read_reply(false).await?;
|
reply = self.read_reply(false).await?;
|
||||||
self.net_md_device.poll().await?;
|
self.device.poll().await?;
|
||||||
let res = scan_query(
|
let res = scan_query(
|
||||||
reply,
|
reply,
|
||||||
"1800 080046 f0030103 28 00 000100 1001 %w 00 %?%? %?%?%?%? %?%?%?%? %*".to_string(),
|
"1800 080046 f0030103 28 00 000100 1001 %w 00 %?%? %?%?%?%? %?%?%?%? %*".to_string(),
|
||||||
|
@ -1714,13 +1700,13 @@ type TDesCbcEnc = cbc::Encryptor<des::TdesEde3>;
|
||||||
|
|
||||||
pub fn retailmac(key: &[u8], value: &[u8], iv: &[u8; 8]) -> Vec<u8> {
|
pub fn retailmac(key: &[u8], value: &[u8], iv: &[u8; 8]) -> Vec<u8> {
|
||||||
let mut subkey_a = [0u8; 8];
|
let mut subkey_a = [0u8; 8];
|
||||||
subkey_a.clone_from_slice(&key[0..8]);
|
subkey_a.copy_from_slice(&key[0..8]);
|
||||||
|
|
||||||
let mut beginning = [0u8; 8];
|
let mut beginning = [0u8; 8];
|
||||||
beginning.clone_from_slice(&value[0..8]);
|
beginning.copy_from_slice(&value[0..8]);
|
||||||
|
|
||||||
let mut end = [0u8; 8];
|
let mut end = [0u8; 8];
|
||||||
end.clone_from_slice(&value[8..]);
|
end.copy_from_slice(&value[8..]);
|
||||||
|
|
||||||
DesCbcEnc::new(&subkey_a.into(), iv.into())
|
DesCbcEnc::new(&subkey_a.into(), iv.into())
|
||||||
.encrypt_padded_mut::<NoPadding>(&mut beginning, 8)
|
.encrypt_padded_mut::<NoPadding>(&mut beginning, 8)
|
||||||
|
@ -1729,8 +1715,8 @@ pub fn retailmac(key: &[u8], value: &[u8], iv: &[u8; 8]) -> Vec<u8> {
|
||||||
let iv2 = &beginning[beginning.len() - 8..];
|
let iv2 = &beginning[beginning.len() - 8..];
|
||||||
|
|
||||||
let mut wonky_key = [0u8; 24];
|
let mut wonky_key = [0u8; 24];
|
||||||
wonky_key[0..16].clone_from_slice(key);
|
wonky_key[0..16].copy_from_slice(key);
|
||||||
wonky_key[16..].clone_from_slice(&key[0..8]);
|
wonky_key[16..].copy_from_slice(&key[0..8]);
|
||||||
TDesCbcEnc::new(&wonky_key.into(), iv2.into())
|
TDesCbcEnc::new(&wonky_key.into(), iv2.into())
|
||||||
.encrypt_padded_mut::<NoPadding>(&mut end, 8)
|
.encrypt_padded_mut::<NoPadding>(&mut end, 8)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -1753,7 +1739,7 @@ pub struct EKBData {
|
||||||
signature: [u8; 24],
|
signature: [u8; 24],
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct EKBOpenSource {}
|
pub struct EKBOpenSource;
|
||||||
|
|
||||||
impl EKBOpenSource {
|
impl EKBOpenSource {
|
||||||
pub fn root_key(&self) -> [u8; 16] {
|
pub fn root_key(&self) -> [u8; 16] {
|
||||||
|
@ -1954,7 +1940,7 @@ impl<'a> MDSession<'a> {
|
||||||
pub fn new(md: &'a mut NetMDInterface) -> Self {
|
pub fn new(md: &'a mut NetMDInterface) -> Self {
|
||||||
MDSession {
|
MDSession {
|
||||||
md,
|
md,
|
||||||
ekb_object: EKBOpenSource {},
|
ekb_object: EKBOpenSource,
|
||||||
hex_session_key: None,
|
hex_session_key: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue