Mountain/IPC/WindServiceHandlers/Encryption/
Encrypt.rs1
2use base64::{Engine, engine::general_purpose::STANDARD as B64};
10use ring::{
11 aead::{AES_256_GCM, Aad, LessSafeKey, Nonce, UnboundKey},
12 rand::{SecureRandom, SystemRandom},
13};
14use serde_json::{Value, json};
15
16use crate::dev_log;
17use super::Key::Fn as DeriveKey;
18
19pub async fn Fn(Arguments:Vec<Value>) -> Result<Value, String> {
20 let Plaintext = Arguments.first().and_then(|V| V.as_str()).unwrap_or("").to_string();
21
22 if Plaintext.is_empty() {
23 return Ok(json!(""));
24 }
25
26 let KeyBytes = DeriveKey().map_err(|E| format!("encryption:encrypt unavailable - {E}"))?;
27
28 let UnboundK = UnboundKey::new(&AES_256_GCM, &KeyBytes).map_err(|E| format!("encrypt key: {E:?}"))?;
29
30 let Key = LessSafeKey::new(UnboundK);
31
32 let Rng = SystemRandom::new();
33
34 let mut NonceBytes = [0u8; 12];
35
36 Rng.fill(&mut NonceBytes).map_err(|E| format!("encrypt rng: {E:?}"))?;
37
38 let NonceVal = Nonce::assume_unique_for_key(NonceBytes);
39
40 let mut Data = Plaintext.into_bytes();
41
42 Key.seal_in_place_append_tag(NonceVal, Aad::empty(), &mut Data)
43 .map_err(|E| format!("encrypt seal: {E:?}"))?;
44
45 let mut Out = NonceBytes.to_vec();
46
47 Out.extend_from_slice(&Data);
48
49 dev_log!(
50 "encryption",
51 "encryption:encrypt {} bytes → {} bytes",
52 Out.len() - 12 - 16,
53 Out.len()
54 );
55
56 Ok(json!(B64.encode(&Out)))
57}