Skip to content

Commit 978114e

Browse files
JSKittyclaude
andcommitted
refactor: deduplicate crypto, move decrypt_data to vector-core
- EncryptionParams, generate_encryption_params, encrypt_data re-exported from vector-core (removed duplicate definitions) - decrypt_data (AES-256-GCM file decryption) moved to vector-core - hash_pass delegates to vector-core with owned-String zeroization wrapper - encrypt_with_key/decrypt_with_key kept as thin Tauri wrappers (infallible signature + unsafe UTF-8 for hot-path decryption) - Tauri-specific functions retained: internal_encrypt/decrypt, maybe_encrypt/decrypt, looks_encrypted (SIMD hex detection), is_encryption_enabled (fast AtomicBool cache) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent afa6af7 commit 978114e

2 files changed

Lines changed: 99 additions & 230 deletions

File tree

crates/vector-core/src/crypto/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,39 @@ pub fn encrypt_data(data: &[u8], params: &EncryptionParams) -> Result<Vec<u8>, S
153153
Ok(buffer)
154154
}
155155

156+
/// Decrypt data with AES-256-GCM using a 16-byte nonce (0xChat-compatible).
157+
/// Input format: ciphertext || 16-byte auth tag.
158+
pub fn decrypt_data(encrypted_data: &[u8], key_hex: &str, nonce_hex: &str) -> Result<Vec<u8>, String> {
159+
use aes::Aes256;
160+
use aes::cipher::typenum::U16;
161+
use aes_gcm::{AesGcm, AeadInPlace, KeyInit as AesKeyInit};
162+
163+
if encrypted_data.len() < 16 {
164+
return Err(format!("Invalid Input: encrypted data too small ({} bytes, minimum 16 bytes required for authentication tag)", encrypted_data.len()));
165+
}
166+
167+
let key_bytes = hex::decode(key_hex).map_err(|e| format!("Invalid key: {}", e))?;
168+
let nonce_bytes = hex::decode(nonce_hex).map_err(|e| format!("Invalid nonce: {}", e))?;
169+
170+
let (ciphertext, tag_bytes) = encrypted_data.split_at(encrypted_data.len() - 16);
171+
172+
let cipher = AesGcm::<Aes256, U16>::new_from_slice(&key_bytes)
173+
.map_err(|_| "Invalid decryption key".to_string())?;
174+
175+
let nonce_arr: [u8; 16] = nonce_bytes.try_into()
176+
.map_err(|_| "Invalid nonce length".to_string())?;
177+
let nonce = aes_gcm::Nonce::<U16>::from(nonce_arr);
178+
let tag_arr: [u8; 16] = tag_bytes.try_into()
179+
.map_err(|_| "Invalid tag length".to_string())?;
180+
let tag = aes_gcm::Tag::<U16>::from(tag_arr);
181+
182+
let mut buffer = ciphertext.to_vec();
183+
cipher.decrypt_in_place_detached(&nonce, &[], &mut buffer, &tag)
184+
.map_err(|e| e.to_string())?;
185+
186+
Ok(buffer)
187+
}
188+
156189
/// Calculate SHA-256 hash of data, returned as hex string.
157190
pub fn sha256_hex(data: &[u8]) -> String {
158191
use sha2::{Sha256, Digest};

0 commit comments

Comments
 (0)