diff --git a/um_cli/src/cmd/qtfm.rs b/um_cli/src/cmd/qtfm.rs index bcbc763..21d2ca2 100644 --- a/um_cli/src/cmd/qtfm.rs +++ b/um_cli/src/cmd/qtfm.rs @@ -45,7 +45,12 @@ impl ArgsQingTingFM { }; let device_key = self.make_device_key()?; - let iv = make_decipher_iv(file_name)?; + let iv = make_decipher_iv(&file_name)?; + if cli.verbose { + eprintln!(" file_name: {}", file_name); + eprintln!("device_key: {}", hex::encode(&device_key)); + eprintln!(" file_iv: {}", hex::encode(&iv)); + } let decipher = Decipher::new(&device_key, &iv); diff --git a/um_wasm/src/exports/qtfm.rs b/um_wasm/src/exports/qtfm.rs index e69de29..f5388a3 100644 --- a/um_wasm/src/exports/qtfm.rs +++ b/um_wasm/src/exports/qtfm.rs @@ -0,0 +1,40 @@ +use std::convert::TryInto; +use umc_qtfm::{nonce, secret, Decipher}; +use wasm_bindgen::prelude::wasm_bindgen; +use wasm_bindgen::JsError; + +/// QingTingFM QTA file decipher. +#[wasm_bindgen(js_name=QingTingFM)] +pub struct JsQingTingFM(Decipher); + +#[wasm_bindgen(js_class = QingTingFM)] +impl JsQingTingFM { + #[wasm_bindgen(js_name=getDeviceKey)] + pub fn get_device_key( + product: &str, + device: &str, + manufacturer: &str, + brand: &str, + board: &str, + model: &str, + ) -> Vec { + secret::make_device_secret(product, device, manufacturer, brand, board, model).to_vec() + } + + #[wasm_bindgen(js_name=getFileIV)] + pub fn get_file_iv(file_name: &str) -> Result, JsError> { + let iv = nonce::make_decipher_iv(file_name)?; + Ok(iv.to_vec()) + } + + #[wasm_bindgen(constructor)] + pub fn new(device_key: &[u8], file_iv: &[u8]) -> Result { + let decipher = Decipher::new(device_key.try_into()?, file_iv.try_into()?); + Ok(JsQingTingFM(decipher)) + } + + /// Decrypt encrypted buffer part. + pub fn decrypt(&self, buffer: &mut [u8], offset: usize) { + self.0.decrypt(buffer, offset) + } +} diff --git a/um_wasm_loader/src/loader.mjs b/um_wasm_loader/src/loader.mjs index 38ab160..1a0bf97 100644 --- a/um_wasm_loader/src/loader.mjs +++ b/um_wasm_loader/src/loader.mjs @@ -1,11 +1,12 @@ import umWasm from '../pkg/um_wasm_bg.wasm'; -import { __wbg_init, initSync } from '../pkg/um_wasm.js'; +import { __wbg_init, initPanicHook, initSync } from '../pkg/um_wasm.js'; export * from '../pkg/um_wasm.js'; function loader() { if (process.env.UMC_INLINE_BUILD === '1') { initSync({ module: umWasm() }); + initPanicHook(); return Promise.resolve(true); } else { const url = new URL('um_wasm_bg.wasm', import.meta.url); @@ -17,7 +18,7 @@ function loader() { console.log('read wasm failed', err); }) : undefined; - return __wbg_init({ module_or_path: wasm }).then(() => true); + return __wbg_init({ module_or_path: wasm }).then(() => (initPanicHook(), true)); } }