diff --git a/Cargo.lock b/Cargo.lock index 6ee2840..64aea39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -644,7 +644,6 @@ name = "unixtract" version = "0.1.0" dependencies = [ "aes", - "block-padding", "cbc", "clap", "ecb", diff --git a/Cargo.toml b/Cargo.toml index 6cd5bb7..0894dd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,4 @@ sha1 = "0.10" flate2 = "1.0" rsa = { version = "0.9", features = ["hazmat"] } hex = "0.4" -ecb = "0.1" -block-padding = "0.3" \ No newline at end of file +ecb = "0.1" \ No newline at end of file diff --git a/src/formats/pfl_upg.rs b/src/formats/pfl_upg.rs index 4daf096..074e568 100644 --- a/src/formats/pfl_upg.rs +++ b/src/formats/pfl_upg.rs @@ -1,12 +1,12 @@ use std::fs::{File}; use rsa::{RsaPublicKey, BigUint}; use hex::decode; -use std::io::Cursor; +use std::path::Path; +use std::io::{Cursor, Write}; +use std::fs::{self, OpenOptions}; use aes::Aes256; -use ecb::cipher::{BlockDecryptMut, KeyInit}; -use ecb::Decryptor; -use block_padding::NoPadding; +use ecb::{Decryptor, cipher::{BlockDecryptMut, KeyInit, generic_array::GenericArray}}; use crate::common; @@ -21,17 +21,43 @@ pub fn is_pfl_upg_file(file: &File) -> bool { } } -fn decrypt_aes256_ecb_no_padding(key: &[u8], ciphertext: &[u8]) -> Result, Box>{ +static KEYS: &[(&str, &str)] = &[ + ("q5551", "D7EE8ED11AC048ED225D4F5F53F8509E55C5D94256A703C79E4CA78AE93ECE1639FE466363AD962BD6D6DE0C46FD19F363687C1D8A21820740A6E7FF87F41C4900DCE1E26EC122E5D4DFA76BFC8F296816B8D0910325E9DC5CBCC9579CF15FC0253EF7CF4919B7613491A5D7BF75DC1888531C458967FD1CF64B33139550BAA5"), + ("qf1eu", "ACD684155C7CCCB04372A8808514489FA9EE75D305987D1337420241FDBE0AE1F7CDFBB931C9D56C91D36F2CE79D222695B484FF42BCA12CE362C7C9ABBDEEC8E5D6107FADCF2D4DA5DF0693E13ACE54A18AEB21C051F6B62C075A1791985547C1CFF4FB5B6EA7E0A9405A1B2BB71EB89A9B209E0F62BF9794D673179C0E60F1"), + ("q591e", "AFAF89062747CBB29343C4E4EA775E4CFDF5FAFCD92C9DD858A8725201BA54AB973BEFEE04EBF3046910FBBC78B10120AE16D80BA734931E97248BC6B1D4A909F087D37BC0A9C2210FF8A2BE44C00F31E4DD8713A364623637FF75EBBCE9D3A840DB67E0FA910F127F679496F6C21112E3E3AD4ACA459FDE1CC58E300682E6F9"), + ("q522e", "C41BE92C212BAC76B48261E2A1704028287DD7E121C11DA25F709E864FBDC1BD8C7F226F57605A4B42D768CDD629AF9E54011A0967AFC2826331406FB1E90321620738526EA0BEA59F1A0E612AE891C396112F13531F423DF02F94D1C871429549F4D5B30D9CA3EFDCC6D7A96849F7C1788DE8FAAEDD36560337008DF06D612F"), + ("q5481", "9E7DA389815251E82A84A1182807702E72A0B0E0FF707C8E73E2EA71F79D5FAAFFC6E0B90ED16E13A4289C78A7D3BDA90626162AAE169D7BE28D6A635585CC10639C4E312E288EB8F7C5A44518B7E8A26A45C5023C5078A972A4CC219CA020BAF524F7429257B7AD76E1B15390879064C6ED59CC1F20CC04EEC26C9CF7FC0727"), + ("q5431", "C5FD937B301A5CEF4B6C25F187728C99636515D058895FEA469496E2B24907FC7721648841F8AE4C618E215673D0C029752FA970B6F9A7F48C9331293D3B1D43E4DFC7B52914973642CD3E4EE0AD11F5254505038F95CACE0DF21FC769B34E134435D88AB617D2981F66EF45BBC7796CFB1086C5D5672E837204991FE53BC1CF"), +]; - let mut cipher = Decryptor::::new_from_slice(key)?; - let mut buf = ciphertext.to_vec(); +static AUTO_FWS: &[(&str, &str)] = &[ + ("Q5551", "q5551"), + ("Q5553", "q5551"), + ("Q554E", "q5551"), + ("Q554M", "q5551"), + ("QF1EU", "qf1eu"), + ("QF2EU", "qf1eu"), + ("Q591E", "q591e"), + ("Q522E", "q522e"), + ("Q582E", "q522e"), + ("Q5481", "q5481"), + ("Q5431", "q5431"), +]; - // decrypt in place - for block in buf.chunks_mut(16) { - cipher.decrypt_block_mut(block.into()); +type Aes256EcbDec = Decryptor; + +fn decrypt_aes256_ecb(key: &[u8], ciphertext: &[u8]) -> Result, Box> { + let key_array: [u8; 32] = key.try_into()?; + + let mut decryptor = Aes256EcbDec::new(&key_array.into()); + let mut buffer = ciphertext.to_vec(); + + for chunk in buffer.chunks_exact_mut(16) { + let block: &mut [u8; 16] = chunk.try_into()?; + decryptor.decrypt_block_mut(GenericArray::from_mut_slice(block)); } - - Ok(buf) + + Ok(buffer) } pub fn extract_pfl_upg(mut file: &File, output_folder: &str) -> Result<(), Box> { @@ -39,18 +65,19 @@ pub fn extract_pfl_upg(mut file: &File, output_folder: &str) -> Result<(), Box Result<(), Box Result<(), Box Result<(), Box