diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index ad5c83c..13f27d8 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -3,7 +3,13 @@ use base64::prelude::*; use std::collections::HashMap; use crate::utils::parse::{Responses, Testcase, Testcases}; -use tasks01::{block2poly::block2poly, gfmul::gfmul, poly2block::poly2block, sea128::sea128}; +use tasks01::{ + block2poly::block2poly, + gfmul::gfmul, + poly2block::poly2block, + sea128::sea128, + xex::{self, fde_xex}, +}; use anyhow::{anyhow, Result}; use serde_json::{json, Value}; @@ -47,6 +53,12 @@ pub fn task_deploy(testcase: &Testcase) -> Result { let json = json!({"product" : result}); Ok(json) } + "xex" => { + let result = BASE64_STANDARD.encode(fde_xex(args)?); + let json = json!({"output" : result}); + + Ok(json) + } _ => Err(anyhow!( "Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}", testcase, @@ -142,4 +154,22 @@ mod tests { Ok(()) } + + #[test] + fn test_task_xex_full() -> Result<()> { + let json = fs::read_to_string("test_json/xex_tests.json").unwrap(); + let parsed = parse_json(json).unwrap(); + + let expected = json!({ "responses": { + "0192d428-3913-762b-a702-d14828eae1f8": {"output": "mHAVhRCKPAPx0BcufG5BZ4+/CbneMV/gRvqK5rtLe0OJgpDU5iT7z2P0R7gEeRDO"}, + "0192d428-3913-7168-a3bb-69c258c74dc1": {"output": "SGV5IHdpZSBrcmFzcyBkYXMgZnVua3Rpb25pZXJ0IGphIG9mZmVuYmFyIGVjaHQu"} + }}); + + assert_eq!( + serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(expected).unwrap() + ); + + Ok(()) + } } diff --git a/src/tasks/tasks01/sea128.rs b/src/tasks/tasks01/sea128.rs index cd5a87d..3f5c40d 100644 --- a/src/tasks/tasks01/sea128.rs +++ b/src/tasks/tasks01/sea128.rs @@ -24,7 +24,7 @@ pub fn sea128(args: &Value) -> Result { Ok(output) } "decrypt" => { - let output = BASE64_STANDARD.encode(sea_128_decrypt(&key.into(), &input)?); + let output = BASE64_STANDARD.encode(sea_128_decrypt(&key, &input)?); Ok(output) } diff --git a/src/tasks/tasks01/xex.rs b/src/tasks/tasks01/xex.rs index e69de29..68b61da 100644 --- a/src/tasks/tasks01/xex.rs +++ b/src/tasks/tasks01/xex.rs @@ -0,0 +1,27 @@ +use anyhow::{anyhow, Result}; +use base64::prelude::*; +use serde_json::Value; + +use crate::utils::ciphers::{xex_decrypt, xex_encrypt}; + +pub fn fde_xex(args: &Value) -> Result> { + let key_string: String = serde_json::from_value(args["key"].clone())?; + let key: Vec = BASE64_STANDARD.decode(key_string)?; + + let tweak_string: String = serde_json::from_value(args["tweak"].clone())?; + let tweak: Vec = BASE64_STANDARD.decode(tweak_string)?; + + let input_string: String = serde_json::from_value(args["input"].clone())?; + let input: Vec = BASE64_STANDARD.decode(input_string)?; + + let mode_string: String = serde_json::from_value(args["mode"].clone())?; + + match mode_string.as_str() { + "encrypt" => Ok(xex_encrypt(key, &tweak, &input)?), + "decrypt" => Ok(xex_decrypt(key, &tweak, &input)?), + _ => Err(anyhow!( + "Failure: No compatible mode found. Data was: {:?}", + args + )), + } +} diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index 6b38c1a..ec1b467 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -63,27 +63,23 @@ pub fn xex_encrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result let input_chunks: Vec> = input.chunks(16).map(|x| x.to_vec()).collect(); let mut output: Vec = vec![]; - assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); - assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); + //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); + //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); let mut tweak_block: ByteArray = ByteArray(sea_128_encrypt(&key2, tweak)?); - dbg!("input_chunks: {:001X?}", &input_chunks); + //dbg!("input_chunks: {:001X?}", &input_chunks); for chunk in input_chunks { - eprintln!("chunk: {:001X?}", &chunk); let plaintext_intermediate = xor_bytes(&tweak_block.0, chunk)?; - eprintln!("key: {:001X?}", &key); - eprintln!("key2: {:001X?}", &key2); - eprintln!("plain: {:001X?}", &plaintext_intermediate); - eprintln!("tweak_block: {:001X?}", &tweak_block.0); - - assert!( - plaintext_intermediate.len() % 16 == 0, - "Failure: plaintext_intermediate len was {}", - plaintext_intermediate.len() - ); - assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); - assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); + /* + assert!( + plaintext_intermediate.len() % 16 == 0, + "Failure: plaintext_intermediate len was {}", + plaintext_intermediate.len() + ); + */ + //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); + //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); let cypher_block_intermediate = sea_128_encrypt(&key, &plaintext_intermediate)?; let mut cypher_block = xor_bytes(&tweak_block.0, cypher_block_intermediate)?; output.append(cypher_block.as_mut()); @@ -101,18 +97,14 @@ pub fn xex_decrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result let input_chunks: Vec> = input.chunks(16).map(|x| x.to_vec()).collect(); let mut output: Vec = vec![]; - assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); - assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); + //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); + //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); let mut tweak_block: ByteArray = ByteArray(sea_128_encrypt(&key2, tweak)?); for chunk in input_chunks { - eprintln!("chunk: {:001X?}", &chunk); let cyphertext_intermediate = xor_bytes(&tweak_block.0, chunk)?; - eprintln!("key: {:001X?}", &key); - eprintln!("key2: {:001X?}", &key2); - eprintln!("plain: {:001X?}", &cyphertext_intermediate); - eprintln!("tweak_block: {:001X?}", &tweak_block.0); + /* assert!( cyphertext_intermediate.len() % 16 == 0, "Failure: plaintext_intermediate len was {}", @@ -120,6 +112,7 @@ pub fn xex_decrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result ); assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); + */ let plaintext_block_intermediate = sea_128_decrypt(&key, &cyphertext_intermediate)?; let mut cypher_block = xor_bytes(&tweak_block.0, plaintext_block_intermediate)?; output.append(cypher_block.as_mut()); diff --git a/test_json/kauma_tests.json b/test_json/kauma_tests.json index 26f47f0..ccc994a 100644 --- a/test_json/kauma_tests.json +++ b/test_json/kauma_tests.json @@ -1,29 +1,29 @@ { "testcases": { "254eaee7-05fd-4e0d-8292-9b658a852245": { - "action": "gfmul", - "arguments": { - "semantic": "xex", - "a": "ARIAAAAAAAAAAAAAAAAAgA==", - "b": "AgAAAAAAAAAAAAAAAAAAAA==" - } - }, - "b8f6d760-023d-4b00-bad2-15d2b6da22fe": { - "action": "sea128", - "arguments": { - "mode": "encrypt", - "key": "istDASeincoolerKEYrofg==", - "input": "yv66vvrO263eyviIiDNEVQ==" - } - }, - "254eaee7-05fd-4e0d-8292-9b658b852245": { - "action": "sea128", - "arguments": { - "mode": "decrypt", - "key": "istDASeincoolerKEYrofg==", - "input": "D5FDo3iVBoBN9gVi9/MSKQ==" - } - }, + "action": "gfmul", + "arguments": { + "semantic": "xex", + "a": "ARIAAAAAAAAAAAAAAAAAgA==", + "b": "AgAAAAAAAAAAAAAAAAAAAA==" + } + }, + "b8f6d760-023d-4b00-bad2-15d2b6da22fe": { + "action": "sea128", + "arguments": { + "mode": "encrypt", + "key": "istDASeincoolerKEYrofg==", + "input": "yv66vvrO263eyviIiDNEVQ==" + } + }, + "254eaee7-05fd-4e0d-8292-9b658b852245": { + "action": "sea128", + "arguments": { + "mode": "decrypt", + "key": "istDASeincoolerKEYrofg==", + "input": "D5FDo3iVBoBN9gVi9/MSKQ==" + } + }, "b856d760-023d-4b00-bad2-15d2b6da22fe": { "action": "block2poly", "arguments": { @@ -42,7 +42,32 @@ 0 ] } + }, + "0192d428-3913-762b-a702-d14828eae1f8": { + "action": "xex", + "arguments": { + "mode": "encrypt", + "key": "B1ygNO/CyRYIUYhTSgoUysX5Y/wWLi4UiWaVeloUWs0=", + "tweak": "6VXORr+YYHrd2nVe0OlA+Q==", + "input": "/aOg4jMocLkBLkDLgkHYtFKc2L9jjyd2WXSSyxXQikpMY9ZRnsJE76e9dW9olZIW" + } + }, + "0192d428-3913-7168-a3bb-69c258c74dc1": { + "action": "xex", + "arguments": { + "mode": "decrypt", + "key": "B1ygNO/CyRYIUYhTSgoUysX5Y/wWLi4UiWaVeloUWs0=", + "tweak": "6VXORr+YYHrd2nVe0OlA+Q==", + "input": "lr/ItaYGFXCtHhdPndE65yg7u/GIdM9wscABiiFOUH2Sbyc2UFMlIRSMnZrYCW1a" + } + }, + "0192d428-3913-78b5-9b35-3171c1c85484": { + "action": "gfmul", + "arguments": { + "semantic": "xex", + "a": "ARIAAAAAAAAAAAAAAAAAgA==", + "b": "AgAAAAAAAAAAAAAAAAAAAA==" + } } } - } diff --git a/test_json/xex_tests.json b/test_json/xex_tests.json new file mode 100644 index 0000000..d8673a4 --- /dev/null +++ b/test_json/xex_tests.json @@ -0,0 +1,22 @@ +{ + "testcases": { + "0192d428-3913-762b-a702-d14828eae1f8": { + "action": "xex", + "arguments": { + "mode": "encrypt", + "key": "B1ygNO/CyRYIUYhTSgoUysX5Y/wWLi4UiWaVeloUWs0=", + "tweak": "6VXORr+YYHrd2nVe0OlA+Q==", + "input": "/aOg4jMocLkBLkDLgkHYtFKc2L9jjyd2WXSSyxXQikpMY9ZRnsJE76e9dW9olZIW" + } + }, + "0192d428-3913-7168-a3bb-69c258c74dc1": { + "action": "xex", + "arguments": { + "mode": "decrypt", + "key": "B1ygNO/CyRYIUYhTSgoUysX5Y/wWLi4UiWaVeloUWs0=", + "tweak": "6VXORr+YYHrd2nVe0OlA+Q==", + "input": "lr/ItaYGFXCtHhdPndE65yg7u/GIdM9wscABiiFOUH2Sbyc2UFMlIRSMnZrYCW1a" + } + } + } +}