From 3989710c70ee158c0d5509882882a301aa4346d5 Mon Sep 17 00:00:00 2001 From: theubusu <80545678+theubusu@users.noreply.github.com> Date: Sun, 22 Feb 2026 17:27:07 +0100 Subject: [PATCH] msd10, msd11: change way of finding passphrase without hardcode firmware name --- src/formats/msd10/include.rs | 6 ++++ src/formats/msd10/mod.rs | 61 +++++++++++++++++++++++------------- src/formats/msd11/mod.rs | 39 +++++++++++++---------- src/keys.rs | 37 +++++++++++----------- 4 files changed, 85 insertions(+), 58 deletions(-) diff --git a/src/formats/msd10/include.rs b/src/formats/msd10/include.rs index 4642fea..4a0f0a9 100644 --- a/src/formats/msd10/include.rs +++ b/src/formats/msd10/include.rs @@ -1,6 +1,12 @@ use crate::utils::common; use binrw::BinRead; +#[derive(PartialEq)] +pub enum FirmwareType{ + Old, + Tizen, +} + #[derive(BinRead)] pub struct FileHeader { _magic_bytes: [u8; 6], diff --git a/src/formats/msd10/mod.rs b/src/formats/msd10/mod.rs index e71241c..8382eea 100644 --- a/src/formats/msd10/mod.rs +++ b/src/formats/msd10/mod.rs @@ -56,32 +56,49 @@ pub fn extract_msd10(app_ctx: &AppContext, _ctx: Box) -> Result<(), Box let firmware_name = &headers[0].name(); println!("\nFirmware name: {}", firmware_name); - let mut passphrase: Option<&str> = None; - let mut firmware_type = ""; - let passphrase_bytes; - - //find passphrase - for (prefix, fw_type, value) in keys::MSD10 { - if firmware_name.starts_with(prefix) { - passphrase = Some(value); - firmware_type = fw_type; - break; - } - } - if let Some(p) = passphrase { - println!("Passphrase: {}", p); - passphrase_bytes = hex::decode(p)?; - println!("Firmware type: {}", firmware_type); - } else { - return Err("This firmware is not supported!".into()); - } - let toc_offset = headers[0].offset; let toc_size = headers[0].size; let toc_data = common::read_file(&file, toc_offset as u64, toc_size as usize)?; + //find passphrase + let mut passphrase_bytes: Option> = None; + let mut passphrase_name: &str = ""; + let mut firmware_type: Option = None; + for (key_hex, name) in keys::MSD10 { + let key_bytes = hex::decode(key_hex)?; + if key_bytes.len() == 20 { + match decrypt_aes_salted_old(&toc_data, &key_bytes) { + Ok(_) => { + passphrase_bytes = Some(key_bytes); + passphrase_name = name; + firmware_type = Some(FirmwareType::Old); + break + }, + Err(_) => continue, + }; + } + else if key_bytes.len() == 16 { + match decrypt_aes_salted_tizen(&toc_data, &key_bytes) { + Ok(_) => { + passphrase_bytes = Some(key_bytes); + passphrase_name = name; + firmware_type = Some(FirmwareType::Tizen); + break + }, + Err(_) => continue, + }; + } + } + + let (passphrase_bytes, firmware_type) = if let (Some(p), Some(t)) = (passphrase_bytes, firmware_type) { + println!("Using passphrase: {}", passphrase_name); + (p, t) + } else { + return Err("No matching key found!".into()); + }; + //parse TOC - if firmware_type == "tizen" { + if firmware_type == FirmwareType::Tizen { let toc = decrypt_aes_salted_tizen(&toc_data, &passphrase_bytes)?; opt_dump_dec_hdr(app_ctx, &toc, "toc")?; @@ -123,7 +140,7 @@ pub fn extract_msd10(app_ctx: &AppContext, _ctx: Box) -> Result<(), Box } - } else if firmware_type == "old" { + } else if firmware_type == FirmwareType::Old { let toc = decrypt_aes_salted_old(&toc_data, &passphrase_bytes)?; opt_dump_dec_hdr(app_ctx, &toc, "toc")?; diff --git a/src/formats/msd11/mod.rs b/src/formats/msd11/mod.rs index 8da41bc..e6084ca 100644 --- a/src/formats/msd11/mod.rs +++ b/src/formats/msd11/mod.rs @@ -53,27 +53,32 @@ pub fn extract_msd11(app_ctx: &AppContext, _ctx: Box) -> Result<(), Box let firmware_name = &headers[0].name(); println!("\nFirmware name: {}", firmware_name); - let mut passphrase: Option<&str> = None; - let passphrase_bytes; - - //find passphrase - for (prefix, value) in keys::MSD11 { - if firmware_name.starts_with(prefix) { - passphrase = Some(value); - break; - } - } - if let Some(p) = passphrase { - println!("Passphrase: {}", p); - passphrase_bytes = hex::decode(p)?; - } else { - return Err("This firmware is not supported!".into()); - } - let toc_offset = headers[0].offset + 8; let toc_size = headers[0].size - 8; let toc_data = common::read_file(&file, toc_offset as u64, toc_size as usize)?; + //find passphrase + let mut passphrase_bytes: Option> = None; + let mut passphrase_name: &str = ""; + for (key_hex, name) in keys::MSD11 { + let key_bytes = hex::decode(key_hex)?; + match decrypt_aes_salted_tizen(&toc_data, &key_bytes) { + Ok(_) => { + passphrase_bytes = Some(key_bytes); + passphrase_name = name; + break + }, + Err(_) => continue, + }; + } + + let passphrase_bytes = if let Some(p) = passphrase_bytes { + println!("Using passphrase: {}", passphrase_name); + p + } else { + return Err("No matching key found!".into()); + }; + let toc = decrypt_aes_salted_tizen(&toc_data, &passphrase_bytes)?; opt_dump_dec_hdr(app_ctx, &toc, "toc")?; diff --git a/src/keys.rs b/src/keys.rs index 77a049d..427a0d5 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -14,32 +14,31 @@ pub static SAMSUNG: &[(&str, &str)] = &[ ]; //MSD10 keys -//fw prefix, type, key -pub static MSD10: &[(&str, &str, &str)] = &[ - ("T-ECP", "old", "3ef6067262cf0c678598bff22169d1f1ea57c284"), //EchoP - 2012 Samsung - ("T-MST12", "old", "010287362008be691dc8c9f6d2c5ca5aa210ecb8"), //X12 - 2013 Mstar - ("T-MST14", "old", "d145f1d55aee3ef520d194e1275b429c580baacb"), //X14 - 2014 Mstar - ("T-MS14J", "old", "d145f1d55aee3ef520d194e1275b429c580baacb"), //X14J - 2014 Mstar (For 2015 models) - ("T-M14HK", "old", "d145f1d55aee3ef520d194e1275b429c580baacb"), //X14HK - 2014 Mstar (For 2016 models) - ("T-NT14M", "old", "95d01e0bae861a05695bc8a6edb2ea835a09accd"), //NT14M - 2014 Novatek (low-end) - ("T-N14MJ", "old", "95d01e0bae861a05695bc8a6edb2ea835a09accd"), //NT14M_J - 2014 Novatek (low-end) (for 2015 models) +//20 bytes is OLD key, 16 bytes is TIZEN key +//key, key desc +pub static MSD10: &[(&str, &str)] = &[ + ("3ef6067262cf0c678598bff22169d1f1ea57c284", "EchoP"), //T-ECP* - 2012 Samsung + ("010287362008be691dc8c9f6d2c5ca5aa210ecb8", "X12"), //T-MST12* - 2013 Mstar + ("d145f1d55aee3ef520d194e1275b429c580baacb", "X14"), //T-MST14*/T-MS14J*/T-M14HK* - 2014 Mstar + ("95d01e0bae861a05695bc8a6edb2ea835a09accd", "NT14M"), //T-NT14M*/T-N14MJ* - 2014 Novatek (low-end) //github.com/bugficks/msddecrypt - ("T-HKM", "tizen", "1ac8989ff57db5e75ea67b033050871c"), //HawkM - 2015 Samsung - ("T-HKP", "tizen", "cce8a3ef92f3e94895999e928f4dd6c3"), //HawkP - 2015 Samsung + ("1ac8989ff57db5e75ea67b033050871c", "HawkM"), //T-HKM* - 2015 Samsung + ("cce8a3ef92f3e94895999e928f4dd6c3", "HawkP"), //T-HKP* - 2015 Samsung ]; //MSD11 keys //github.com/bugficks/msddecrypt +//key, key desc pub static MSD11: &[(&str, &str)] = &[ - ("T-HKM", "c7097975e8ab994beb5eaae57e0ba77c"), //HawkM - 2015 Samsung (for 2016 models) - ("T-JZM", "9b1d077c0d137d406c79ddacb6b159fe"), //JazzM - 2016 Samsung - ("T-KTM2L", "46b04f5e794ca4377a20951c9ea00427"), //KantM2L - 2018 Samsung - ("T-KTM2", "29110e0ce940b3a9b67d3e158f3f1342"), //KantM2 - 2018 Samsung - ("T-KTM", "d0d49d5f36f5c0da50062fbf32168f5b"), //KantM - 2017 Samsung - ("T-KTSU", "19e1ba41163f03735e692d9daa2cbb47"), //KantSU - 2018 Samsung - ("T-KTSD", "39332605ff47a0aea999b10ce9087389"), //KantSD? - ???? Samsung - ("T-NKL", "5bab1098dab48792619ebd63650d929f"), //NikeL - 2020 Samsung + ("c7097975e8ab994beb5eaae57e0ba77c", "HawkM"), //T-HKM* - 2015 Samsung (for 2016 models) + ("9b1d077c0d137d406c79ddacb6b159fe", "JazzM"), //T-JZM* - 2016 Samsung + ("46b04f5e794ca4377a20951c9ea00427", "KantM2L"), //T-KTM2L* - 2018 Samsung + ("29110e0ce940b3a9b67d3e158f3f1342", "KantM2"), //T-KTM2* - 2018 Samsung + ("d0d49d5f36f5c0da50062fbf32168f5b", "KantM"), //T-KTM* - 2017 Samsung + ("19e1ba41163f03735e692d9daa2cbb47", "KantSU"), //T-KTSU* - 2018 Samsung + ("39332605ff47a0aea999b10ce9087389", "KantSD?"), //T-KTSD* - ???? Samsung + ("5bab1098dab48792619ebd63650d929f", "NikeL"), //T-NKL* - 2020 Samsung ]; //RUF keys