diff --git a/src/formats.rs b/src/formats.rs index dbbd436..1496cc2 100644 --- a/src/formats.rs +++ b/src/formats.rs @@ -2,11 +2,14 @@ pub mod mstar; pub mod samsung_old; pub mod tpv_timg; pub mod pfl_upg; -pub mod epk1; +pub mod sddl_sec; pub mod novatek; + +pub mod msd; pub mod msd10; pub mod msd11; -pub mod sddl_sec; -pub mod epk2; + pub mod epk; +pub mod epk1; +pub mod epk2; pub mod epk3; \ No newline at end of file diff --git a/src/formats/epk3.rs b/src/formats/epk3.rs index b538b50..2981b04 100644 --- a/src/formats/epk3.rs +++ b/src/formats/epk3.rs @@ -14,7 +14,7 @@ pub fn extract_epk3(mut file: &File, output_folder: &str) -> Result<(), Box> = None; + let matching_key: Option>; println!("Finding key..."); // find the key, knowing that the header should start with "EPK3" diff --git a/src/formats/msd.rs b/src/formats/msd.rs new file mode 100644 index 0000000..54196db --- /dev/null +++ b/src/formats/msd.rs @@ -0,0 +1,60 @@ +// COMMON MSD FUNCTIONS +use aes::Aes128; +use cbc::{Decryptor, cipher::{block_padding::Pkcs7, BlockDecryptMut, KeyIvInit}}; + +type Aes128CbcDec = Decryptor; + +pub fn decrypt_aes_salted_old(encrypted_data: &[u8], passphrase_bytes: &Vec) -> Result, Box> { + let mut data = encrypted_data.to_vec(); + + assert!(data[0..8].to_vec() == b"Salted__", "invalid encrypted data!"); + let salt = &data[8..16]; + + //key = md5 of (passphrase + salt) + let mut key = Vec::new(); + key.extend_from_slice(&passphrase_bytes); + key.extend_from_slice(&salt); + let key_md5 = md5::compute(&key); + + //iv = md5 of (md5 of key + passphrase + salt) + let mut iv = Vec::new(); + iv.extend_from_slice(&key_md5.0); + iv.extend_from_slice(&passphrase_bytes); + iv.extend_from_slice(&salt); + let iv_md5 = md5::compute(&iv); + + let decryptor = Aes128CbcDec::new((&key_md5.0).into(), (&iv_md5.0).into()); + let decrypted = decryptor.decrypt_padded_mut::(&mut data[16..]) + .map_err(|e| format!("Decryption error!!: {:?}", e))?; + + Ok(decrypted.to_vec()) +} + +pub fn decrypt_aes_salted_tizen(encrypted_data: &[u8], passphrase_bytes: &Vec) -> Result, Box> { + let mut data = encrypted_data.to_vec(); + + assert!(data[0..8].to_vec() == b"Salted__", "invalid encrypted data!"); + let salt = &data[8..16]; + + //iv = md5 of salt + let iv = md5::compute(&salt); + + let decryptor = Aes128CbcDec::new((&(**passphrase_bytes)).into(), (&iv.0).into()); + let decrypted = decryptor.decrypt_padded_mut::(&mut data[16..]) + .map_err(|e| format!("Decryption error!!: {:?}", e))?; + + Ok(decrypted.to_vec()) +} + +pub fn decrypt_aes_tizen(encrypted_data: &[u8], passphrase_bytes: &Vec, salt: &[u8]) -> Result, Box> { + let mut data = encrypted_data.to_vec(); + + //iv = md5 of salt + let iv = md5::compute(&salt); + + let decryptor = Aes128CbcDec::new((&(**passphrase_bytes)).into(), (&iv.0).into()); + let decrypted = decryptor.decrypt_padded_mut::(&mut data) + .map_err(|e| format!("Decryption error!!: {:?}", e))?; + + Ok(decrypted.to_vec()) +} \ No newline at end of file diff --git a/src/formats/msd10.rs b/src/formats/msd10.rs index ec19442..8f90d75 100644 --- a/src/formats/msd10.rs +++ b/src/formats/msd10.rs @@ -2,14 +2,11 @@ use std::fs::{self, File, OpenOptions}; use std::path::{Path}; use std::io::{Cursor, Write, Seek, SeekFrom}; -use aes::Aes128; -use cbc::{Decryptor, cipher::{block_padding::Pkcs7, BlockDecryptMut, KeyIvInit}}; - -type Aes128CbcDec = Decryptor; - use crate::common; use crate::keys; +use crate::formats::msd::{decrypt_aes_salted_old, decrypt_aes_salted_tizen, decrypt_aes_tizen}; + pub fn is_msd10_file(file: &File) -> bool { let header = common::read_file(&file, 0, 6).expect("Failed to read from file."); if header == b"MSDU10" { @@ -26,61 +23,6 @@ struct Section { name: String, } -fn decrypt_aes_salted_old(encrypted_data: &[u8], passphrase_bytes: &Vec) -> Result, Box> { - let mut data = encrypted_data.to_vec(); - - assert!(data[0..8].to_vec() == b"Salted__", "invalid encrypted data!"); - let salt = &data[8..16]; - - //key = md5 of (passphrase + salt) - let mut key = Vec::new(); - key.extend_from_slice(&passphrase_bytes); - key.extend_from_slice(&salt); - let key_md5 = md5::compute(&key); - - //iv = md5 of (md5 of key + passphrase + salt) - let mut iv = Vec::new(); - iv.extend_from_slice(&key_md5.0); - iv.extend_from_slice(&passphrase_bytes); - iv.extend_from_slice(&salt); - let iv_md5 = md5::compute(&iv); - - let decryptor = Aes128CbcDec::new((&key_md5.0).into(), (&iv_md5.0).into()); - let decrypted = decryptor.decrypt_padded_mut::(&mut data[16..]) - .map_err(|e| format!("Decryption error!!: {:?}", e))?; - - Ok(decrypted.to_vec()) -} - -fn decrypt_aes_salted_tizen(encrypted_data: &[u8], passphrase_bytes: &Vec) -> Result, Box> { - let mut data = encrypted_data.to_vec(); - - assert!(data[0..8].to_vec() == b"Salted__", "invalid encrypted data!"); - let salt = &data[8..16]; - - //iv = md5 of salt - let iv = md5::compute(&salt); - - let decryptor = Aes128CbcDec::new((&(**passphrase_bytes)).into(), (&iv.0).into()); - let decrypted = decryptor.decrypt_padded_mut::(&mut data[16..]) - .map_err(|e| format!("Decryption error!!: {:?}", e))?; - - Ok(decrypted.to_vec()) -} - -fn decrypt_aes_tizen(encrypted_data: &[u8], passphrase_bytes: &Vec, salt: &[u8]) -> Result, Box> { - let mut data = encrypted_data.to_vec(); - - //iv = md5 of salt - let iv = md5::compute(&salt); - - let decryptor = Aes128CbcDec::new((&(**passphrase_bytes)).into(), (&iv.0).into()); - let decrypted = decryptor.decrypt_padded_mut::(&mut data) - .map_err(|e| format!("Decryption error!!: {:?}", e))?; - - Ok(decrypted.to_vec()) -} - pub fn extract_msd10(mut file: &File, output_folder: &str) -> Result<(), Box> { let _magic = common::read_exact(&mut file, 6)?; //MSDU10 magic diff --git a/src/formats/msd11.rs b/src/formats/msd11.rs index 7fb192d..948297f 100644 --- a/src/formats/msd11.rs +++ b/src/formats/msd11.rs @@ -2,14 +2,11 @@ use std::fs::{self, File, OpenOptions}; use std::path::{Path}; use std::io::{Cursor, Write, Seek, SeekFrom}; -use aes::Aes128; -use cbc::{Decryptor, cipher::{block_padding::Pkcs7, BlockDecryptMut, KeyIvInit}}; - -type Aes128CbcDec = Decryptor; - use crate::common; use crate::keys; +use crate::formats::msd::{decrypt_aes_salted_tizen, decrypt_aes_tizen}; + pub fn is_msd11_file(file: &File) -> bool { let header = common::read_file(&file, 0, 6).expect("Failed to read from file."); if header == b"MSDU11" { @@ -26,35 +23,6 @@ struct Section { name: String, } -fn decrypt_aes_salted_tizen(encrypted_data: &[u8], passphrase_bytes: &Vec) -> Result, Box> { - let mut data = encrypted_data.to_vec(); - - assert!(data[0..8].to_vec() == b"Salted__", "invalid encrypted data!"); - let salt = &data[8..16]; - - //iv = md5 of salt - let iv = md5::compute(&salt); - - let decryptor = Aes128CbcDec::new((&(**passphrase_bytes)).into(), (&iv.0).into()); - let decrypted = decryptor.decrypt_padded_mut::(&mut data[16..]) - .map_err(|e| format!("Decryption error!!: {:?}", e))?; - - Ok(decrypted.to_vec()) -} - -fn decrypt_aes_tizen(encrypted_data: &[u8], passphrase_bytes: &Vec, salt: &[u8]) -> Result, Box> { - let mut data = encrypted_data.to_vec(); - - //iv = md5 of salt - let iv = md5::compute(&salt); - - let decryptor = Aes128CbcDec::new((&(**passphrase_bytes)).into(), (&iv.0).into()); - let decrypted = decryptor.decrypt_padded_mut::(&mut data) - .map_err(|e| format!("Decryption error!!: {:?}", e))?; - - Ok(decrypted.to_vec()) -} - pub fn extract_msd11(mut file: &File, output_folder: &str) -> Result<(), Box> { let _magic = common::read_exact(&mut file, 6)?; //MSDU11 magic