diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 168747e..f4eaab3 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -1,10 +1,14 @@ use base64::prelude::*; -use std::collections::HashMap; +use std::{collections::HashMap, env::args}; -use crate::utils::parse::{Responses, Testcase, Testcases}; +use crate::utils::{ + ciphers::gcm_encrypt_aes, + parse::{Responses, Testcase, Testcases}, +}; use tasks01::{ block2poly::block2poly, + gcm::gcm_encrypt, gfmul::gfmul_task, poly2block::poly2block, sea128::sea128, @@ -53,6 +57,17 @@ pub fn task_deploy(testcase: &Testcase) -> Result { Ok(json) } + "gcm_encrypt" => { + let (ciphertext, auth_tag, l_field, auth_key_h) = gcm_encrypt(args)?; + let out_ciph = BASE64_STANDARD.encode(&ciphertext); + let out_tag = BASE64_STANDARD.encode(&auth_tag); + let out_l = BASE64_STANDARD.encode(&l_field); + let out_h = BASE64_STANDARD.encode(&auth_key_h); + + let json = json!({"ciphertext" : out_ciph, "tag" : out_tag, "L" : out_l, "H" : out_h}); + + Ok(json) + } _ => Err(anyhow!( "Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}", testcase, @@ -166,4 +181,24 @@ mod tests { Ok(()) } + + #[test] + fn test_task_gcm_encrypt_aes_case() -> Result<()> { + let json = fs::read_to_string("test_json/gcm_encrypt.json").unwrap(); + let parsed = parse_json(json).unwrap(); + + let expected = json!({ "responses" : { "b856d760-023d-4b00-bad2-15d2b6da22fe" : { + "ciphertext": "ET3RmvH/Hbuxba63EuPRrw==", + "tag": "Mp0APJb/ZIURRwQlMgNN/w==", + "L": "AAAAAAAAAEAAAAAAAAAAgA==", + "H": "Bu6ywbsUKlpmZXMQyuGAng==" + }}}); + + assert_eq!( + serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(expected).unwrap() + ); + + Ok(()) + } } diff --git a/src/tasks/tasks01/gcm.rs b/src/tasks/tasks01/gcm.rs new file mode 100644 index 0000000..4763d53 --- /dev/null +++ b/src/tasks/tasks01/gcm.rs @@ -0,0 +1,26 @@ +use anyhow::{anyhow, Result}; +use base64::prelude::*; +use serde_json::Value; + +use crate::utils::ciphers::gcm_encrypt_aes; + +pub fn gcm_encrypt(args: &Value) -> Result<(Vec, Vec, Vec, Vec)> { + let nonce_text: String = serde_json::from_value(args["nonce"].clone())?; + let nonce = BASE64_STANDARD.decode(nonce_text)?; + + let key_text: String = serde_json::from_value(args["key"].clone())?; + let key = BASE64_STANDARD.decode(key_text)?; + + let plaintext_text: String = serde_json::from_value(args["plaintext"].clone())?; + let plaintext = BASE64_STANDARD.decode(plaintext_text)?; + + let ad_text: String = serde_json::from_value(args["ad"].clone())?; + let ad = BASE64_STANDARD.decode(ad_text)?; + + let alg_text: String = serde_json::from_value(args["algorithm"].clone())?; + + match alg_text.as_str() { + "aes128" => Ok(gcm_encrypt_aes(nonce, key, plaintext, ad)?), + _ => Err(anyhow!("No compatible algorithm found")), + } +} diff --git a/src/tasks/tasks01/mod.rs b/src/tasks/tasks01/mod.rs index 97ea4d7..d1f3e99 100644 --- a/src/tasks/tasks01/mod.rs +++ b/src/tasks/tasks01/mod.rs @@ -1,4 +1,5 @@ pub mod block2poly; +pub mod gcm; pub mod gfmul; pub mod poly2block; pub mod sea128; diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index 8b5e831..2be30fb 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -285,10 +285,16 @@ mod tests { BASE64_STANDARD.encode(&auth_key_h) ); - assert_eq!(BASE64_STANDARD.encode(ciphertext), ""); - assert_eq!(BASE64_STANDARD.encode(auth_tag), ""); - assert_eq!(BASE64_STANDARD.encode(l_field), ""); - assert_eq!(BASE64_STANDARD.encode(auth_key_h), ""); + assert_eq!( + BASE64_STANDARD.encode(ciphertext), + "ET3RmvH/Hbuxba63EuPRrw==" + ); + assert_eq!(BASE64_STANDARD.encode(auth_tag), "Mp0APJb/ZIURRwQlMgNN/w=="); + assert_eq!(BASE64_STANDARD.encode(l_field), "AAAAAAAAAEAAAAAAAAAAgA=="); + assert_eq!( + BASE64_STANDARD.encode(auth_key_h), + "Bu6ywbsUKlpmZXMQyuGAng==" + ); Ok(()) } diff --git a/test_json/gcm_encrypt.json b/test_json/gcm_encrypt.json new file mode 100644 index 0000000..347475e --- /dev/null +++ b/test_json/gcm_encrypt.json @@ -0,0 +1,14 @@ +{ + "testcases": { + "b856d760-023d-4b00-bad2-15d2b6da22fe": { + "action": "gcm_encrypt", + "arguments": { + "algorithm": "aes128", + "nonce": "4gF+BtR3ku/PUQci", + "key": "Xjq/GkpTSWoe3ZH0F+tjrQ==", + "plaintext": "RGFzIGlzdCBlaW4gVGVzdA==", + "ad": "QUQtRGF0ZW4=" + } + } + } +}