securedrop_protocol_minimal/
primitives.rs1use alloc::vec::Vec;
2use anyhow::Error;
3use rand_core::{CryptoRng, RngCore};
4
5pub(crate) mod dh_akem;
6pub(crate) mod mlkem;
7pub mod pad;
8pub(crate) mod provider;
9pub mod x25519;
10pub(crate) mod xwing;
11
12pub const MESSAGE_ID_FETCH_SIZE: usize = 10;
17
18pub fn encrypt_message_id<R: RngCore + CryptoRng>(
23 key: &[u8],
24 message_id: &[u8],
25 rng: &mut R,
26) -> Result<Vec<u8>, Error> {
27 use provider::chacha20poly1305::{KEY_LEN, NONCE_LEN, TAG_LEN};
28
29 if key.len() != KEY_LEN {
30 return Err(anyhow::anyhow!("Invalid key length"));
31 }
32
33 let mut nonce = [0u8; NONCE_LEN];
35 rng.fill_bytes(&mut nonce);
36
37 let mut output = alloc::vec::Vec::new();
39 output.extend_from_slice(&nonce);
40
41 let mut ciphertext = alloc::vec![0u8; message_id.len() + TAG_LEN];
42 let key_array: [u8; KEY_LEN] = key
43 .try_into()
44 .map_err(|_| anyhow::anyhow!("Key length mismatch"))?;
45
46 match provider::chacha20poly1305::encrypt(&key_array, message_id, &mut ciphertext, &[], &nonce)
48 {
49 Ok(_) => {}
50 Err(e) => {
51 return Err(anyhow::anyhow!(
52 "ChaCha20-Poly1305 encryption failed: {:?}",
53 e
54 ));
55 }
56 }
57 output.extend_from_slice(&ciphertext);
58 Ok(output)
59}
60
61pub fn decrypt_message_id(key: &[u8], encrypted_data: &[u8]) -> Result<Vec<u8>, Error> {
65 use provider::chacha20poly1305::{KEY_LEN, NONCE_LEN, TAG_LEN};
66
67 if key.len() != KEY_LEN {
68 return Err(anyhow::anyhow!("Invalid key length"));
69 }
70
71 if encrypted_data.len() < NONCE_LEN + TAG_LEN {
72 return Err(anyhow::anyhow!("Encrypted data too short"));
73 }
74
75 let nonce: [u8; NONCE_LEN] = encrypted_data[..NONCE_LEN]
77 .try_into()
78 .map_err(|_| anyhow::anyhow!("Nonce extraction failed"))?;
79 let ciphertext = &encrypted_data[NONCE_LEN..];
80
81 let mut plaintext = alloc::vec![0u8; ciphertext.len() - TAG_LEN];
83 let key_array: [u8; KEY_LEN] = key
84 .try_into()
85 .map_err(|_| anyhow::anyhow!("Key length mismatch"))?;
86
87 provider::chacha20poly1305::decrypt(
89 &key_array,
90 &mut plaintext,
91 ciphertext,
92 &[], &nonce,
94 )
95 .map_err(|e| anyhow::anyhow!("ChaCha20-Poly1305 decryption failed: {:?}", e))?;
96
97 Ok(plaintext)
98}