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
18#[cfg_attr(hax, hax_lib::requires(
23 message_id.len()
24 <= usize::MAX
25 - provider::chacha20poly1305::NONCE_LEN
26 - provider::chacha20poly1305::TAG_LEN
27))]
28pub fn encrypt_message_id<R: RngCore + CryptoRng>(
29 key: &[u8],
30 message_id: &[u8],
31 rng: &mut R,
32) -> Result<Vec<u8>, Error> {
33 use provider::chacha20poly1305::{KEY_LEN, NONCE_LEN, TAG_LEN};
34
35 if key.len() != KEY_LEN {
36 return Err(anyhow::anyhow!("Invalid key length"));
37 }
38
39 let mut nonce = [0u8; NONCE_LEN];
41 provider::rng::fill_bytes(rng, &mut nonce);
42
43 let mut output = alloc::vec::Vec::new();
45 output.extend_from_slice(&nonce);
46
47 let mut ciphertext = alloc::vec![0u8; message_id.len() + TAG_LEN];
48 let result = key.try_into();
49 let key_array = result.map_err(|_| anyhow::anyhow!("Key length mismatch"))?;
50
51 match provider::chacha20poly1305::encrypt(&key_array, message_id, &mut ciphertext, &[], &nonce)
53 {
54 Ok(_) => {}
55 Err(e) => {
56 return Err(anyhow::anyhow!(
57 "ChaCha20-Poly1305 encryption failed: {:?}",
58 e
59 ));
60 }
61 }
62 output.extend_from_slice(&ciphertext);
63 Ok(output)
64}
65
66pub fn decrypt_message_id(key: &[u8], encrypted_data: &[u8]) -> Result<Vec<u8>, Error> {
70 use provider::chacha20poly1305::{KEY_LEN, NONCE_LEN, TAG_LEN};
71
72 if key.len() != KEY_LEN {
73 return Err(anyhow::anyhow!("Invalid key length"));
74 }
75
76 if encrypted_data.len() < NONCE_LEN + TAG_LEN {
77 return Err(anyhow::anyhow!("Encrypted data too short"));
78 }
79
80 let nonce_r = encrypted_data[..NONCE_LEN].try_into();
82 let nonce: [u8; NONCE_LEN] = nonce_r.map_err(|_| anyhow::anyhow!("Nonce extraction failed"))?;
83 let ciphertext = &encrypted_data[NONCE_LEN..];
84
85 let mut plaintext = alloc::vec![0u8; ciphertext.len() - TAG_LEN];
87 let key_arr_res = key.try_into();
88 let key_array: [u8; KEY_LEN] =
89 key_arr_res.map_err(|_| anyhow::anyhow!("Key length mismatch"))?;
90
91 provider::chacha20poly1305::decrypt(
93 &key_array,
94 &mut plaintext,
95 ciphertext,
96 &[], &nonce,
98 )
99 .map_err(|e| anyhow::anyhow!("ChaCha20-Poly1305 decryption failed: {:?}", e))?;
100
101 Ok(plaintext)
102}