1use alloc::string::ToString;
8use alloc::vec::Vec;
9
10use crate::artifacts::{PublicKey, UserSecretKey, VerifyingKey};
11use crate::client::*;
12use crate::error::Error;
13use crate::identity::EncryptionPolicy;
14
15use aead::{Aead, KeyInit};
16use aes_gcm::{Aes128Gcm, Nonce};
17use ibe::kem::cgw_kv::CGWKV;
18use ibs::gg::Signer;
19use rand::{CryptoRng, RngCore};
20
21#[cfg(feature = "stream")]
22pub mod stream;
23
24#[derive(Debug)]
26pub struct SealerMemoryConfig {
27 key: [u8; KEY_SIZE],
28 nonce: [u8; IV_SIZE],
29}
30
31#[derive(Debug)]
33pub struct UnsealerMemoryConfig {
34 message_len: usize,
35}
36
37impl SealerConfig for SealerMemoryConfig {}
38impl super::sealed::SealerConfig for SealerMemoryConfig {}
39
40impl UnsealerConfig for UnsealerMemoryConfig {}
41impl super::sealed::UnsealerConfig for UnsealerMemoryConfig {}
42
43impl From<aead::Error> for Error {
44 fn from(_: aead::Error) -> Self {
45 Self::Symmetric
46 }
47}
48
49impl From<aes_gcm::aes::cipher::InvalidLength> for Error {
50 fn from(_: aes_gcm::aes::cipher::InvalidLength) -> Self {
51 Self::Symmetric
52 }
53}
54
55#[derive(Debug, Serialize, Deserialize)]
56struct MessageAndSignature {
57 message: Vec<u8>,
58 sig: SignatureExt,
59}
60
61impl<'r, R: RngCore + CryptoRng> Sealer<'r, R, SealerMemoryConfig> {
62 pub fn new(
64 mpk: &PublicKey<CGWKV>,
65 policies: &EncryptionPolicy,
66 pub_sign_key: &SigningKeyExt,
67 rng: &'r mut R,
68 ) -> Result<Self, Error> {
69 let (header, ss) = Header::new(mpk, policies, rng)?;
70 let Algorithm::Aes128Gcm(iv) = header.algo;
71
72 let mut key = [0u8; KEY_SIZE];
73 let mut nonce = [0u8; IV_SIZE];
74 key.copy_from_slice(&ss.0[..KEY_SIZE]);
75 nonce.copy_from_slice(&iv.0[..IV_SIZE]);
76
77 Ok(Self {
78 rng,
79 header,
80 pub_sign_key: pub_sign_key.clone(),
81 priv_sign_key: None,
82 config: SealerMemoryConfig { key, nonce },
83 })
84 }
85
86 pub fn seal(mut self, message: impl AsRef<[u8]>) -> Result<Vec<u8>, Error> {
88 let mut out = Vec::with_capacity(message.as_ref().len() + 1024);
89
90 out.extend_from_slice(&PRELUDE);
91 out.extend_from_slice(&VERSION_V3.to_be_bytes());
92
93 self.header = self.header.with_mode(Mode::InMemory {
94 size: message.as_ref().len().try_into()?,
95 });
96
97 let header_buf = bincode::serialize(&self.header)?;
98 out.extend_from_slice(&u32::try_from(header_buf.len())?.to_be_bytes());
99 out.extend_from_slice(&header_buf);
100
101 let signer = Signer::new().chain(header_buf);
102 let h_sig = signer.clone().sign(&self.pub_sign_key.key.0, self.rng);
103
104 let h_sig_ext = SignatureExt {
105 sig: h_sig,
106 pol: self.pub_sign_key.policy.clone(),
107 };
108
109 let h_sig_ext_bytes = bincode::serialize(&h_sig_ext)?;
110 out.extend_from_slice(&u32::try_from(h_sig_ext_bytes.len())?.to_be_bytes());
111 out.extend_from_slice(&h_sig_ext_bytes);
112
113 let m_sig_key = self.priv_sign_key.unwrap_or(self.pub_sign_key);
114 let m_sig = signer.chain(&message).sign(&m_sig_key.key.0, self.rng);
115
116 let aead = Aes128Gcm::new_from_slice(&self.config.key)?;
117 let nonce = Nonce::from_slice(&self.config.nonce);
118
119 let enc_input = bincode::serialize(&MessageAndSignature {
120 message: message.as_ref().to_vec(),
121 sig: SignatureExt {
122 sig: m_sig,
123 pol: m_sig_key.policy,
124 },
125 })?;
126
127 let ciphertext = aead.encrypt(nonce, enc_input.as_ref())?;
128
129 out.extend_from_slice(&ciphertext);
130
131 Ok(out)
132 }
133}
134
135impl Unsealer<Vec<u8>, UnsealerMemoryConfig> {
136 pub fn new(input: impl AsRef<[u8]>, vk: &VerifyingKey) -> Result<Self, Error> {
138 let b = input.as_ref();
139 let (preamble_bytes, b) = b.split_at(PREAMBLE_SIZE);
140 let (version, header_len) = preamble_checked(preamble_bytes)?;
141
142 let (header_bytes, b) = b.split_at(header_len);
143 let (h_sig_len_bytes, b) = b.split_at(SIG_SIZE_SIZE);
144 let h_sig_len = u32::from_be_bytes(h_sig_len_bytes.try_into()?);
145 let (h_sig_bytes, ct) = b.split_at(h_sig_len as usize);
146
147 let h_sig_ext: SignatureExt = bincode::deserialize(h_sig_bytes)?;
148 let id = h_sig_ext.pol.derive_ibs()?;
149
150 let verifier = Verifier::default().chain(header_bytes);
151
152 if !verifier.clone().verify(&vk.0, &h_sig_ext.sig, &id) {
153 return Err(Error::IncorrectSignature);
154 }
155
156 let header: Header = bincode::deserialize(header_bytes)?;
157 let message_len = match header.mode {
158 Mode::InMemory { size } => size as usize,
159 _ => return Err(Error::ModeNotSupported(header.mode)),
160 };
161
162 Ok(Self {
163 version,
164 header,
165 pub_id: h_sig_ext.pol,
166 r: ct.to_vec(),
167 verifier,
168 vk: vk.clone(),
169 config: UnsealerMemoryConfig { message_len },
170 })
171 }
172
173 pub fn unseal(
175 self,
176 ident: &str,
177 usk: &UserSecretKey<CGWKV>,
178 ) -> Result<(Vec<u8>, VerificationResult), Error> {
179 let rec_info = self
180 .header
181 .recipients
182 .get(ident)
183 .ok_or_else(|| Error::UnknownIdentifier(ident.to_string()))?;
184
185 let ss = rec_info.decaps(usk)?;
186 let key = &ss.0[..KEY_SIZE];
187
188 let Algorithm::Aes128Gcm(iv) = self.header.algo;
189
190 let aead = Aes128Gcm::new_from_slice(key)?;
191 let nonce = Nonce::from_slice(&iv.0);
192
193 let plain = aead.decrypt(nonce, &*self.r)?;
194
195 let msg: MessageAndSignature = bincode::deserialize(&plain)?;
196 let id = msg.sig.pol.derive_ibs()?;
197
198 if !self
199 .verifier
200 .chain(&msg.message)
201 .verify(&self.vk.0, &msg.sig.sig, &id)
202 {
203 return Err(Error::IncorrectSignature);
204 }
205
206 debug_assert_eq!(self.config.message_len, msg.message.len());
207
208 let private = if self.pub_id == msg.sig.pol {
209 None
210 } else {
211 Some(msg.sig.pol)
212 };
213
214 Ok((
215 msg.message,
216 VerificationResult {
217 public: self.pub_id,
218 private,
219 },
220 ))
221 }
222}
223
224#[cfg(test)]
225mod tests {
226 use super::*;
227 use crate::test::TestSetup;
228
229 #[test]
230 fn test_seal_memory() {
231 let mut rng = rand::thread_rng();
232 let setup = TestSetup::new(&mut rng);
233
234 let pub_sign_key = &setup.signing_keys[0];
236 let priv_sign_key = &setup.signing_keys[1];
238
239 let input = b"SECRET DATA";
240 let sealed = Sealer::<_, SealerMemoryConfig>::new(
241 &setup.ibe_pk,
242 &setup.policy,
243 &pub_sign_key,
244 &mut rng,
245 )
246 .unwrap()
247 .with_priv_signing_key(priv_sign_key.clone())
248 .seal(input)
249 .unwrap();
250
251 let usk = &setup.usks[2];
253 let (original, verified_policy) =
254 Unsealer::<_, UnsealerMemoryConfig>::new(sealed, &setup.ibs_pk)
255 .unwrap()
256 .unseal("Bob", &usk)
257 .unwrap();
258
259 assert_eq!(&input.to_vec(), &original);
260
261 let expected = VerificationResult {
262 public: setup.policies[0].clone(),
263 private: Some(setup.policies[1].clone()),
264 };
265
266 assert_eq!(&verified_policy, &expected);
267 }
268
269 #[test]
270 fn test_seal_unseal_wrong_usk() {
271 let mut rng = rand::thread_rng();
272 let setup = TestSetup::new(&mut rng);
273
274 let pub_sign_key = &setup.signing_keys[0];
275 let priv_sign_key = &setup.signing_keys[1];
276
277 let input = b"SECRET DATA";
278 let sealed = Sealer::<_, SealerMemoryConfig>::new(
279 &setup.ibe_pk,
280 &setup.policy,
281 &pub_sign_key,
282 &mut rng,
283 )
284 .unwrap()
285 .with_priv_signing_key(priv_sign_key.clone())
286 .seal(input)
287 .unwrap();
288
289 let usk = &setup.usks[4];
291 let res = Unsealer::<_, UnsealerMemoryConfig>::new(sealed, &setup.ibs_pk)
292 .unwrap()
293 .unseal("Charlie", &usk);
294
295 assert!(matches!(res, Err(Error::KEM)));
296 }
297
298 #[test]
299 fn test_seal_unseal_wrong_id() {
300 let mut rng = rand::thread_rng();
301 let setup = TestSetup::new(&mut rng);
302
303 let pub_sign_key = &setup.signing_keys[0];
304 let priv_sign_key = &setup.signing_keys[1];
305
306 let input = b"SECRET DATA";
307 let sealed = Sealer::<_, SealerMemoryConfig>::new(
308 &setup.ibe_pk,
309 &setup.policy,
310 &pub_sign_key,
311 &mut rng,
312 )
313 .unwrap()
314 .with_priv_signing_key(priv_sign_key.clone())
315 .seal(input)
316 .unwrap();
317
318 let usk = &setup.usks[4];
319 let res = Unsealer::<_, UnsealerMemoryConfig>::new(sealed, &setup.ibs_pk)
320 .unwrap()
321 .unseal("Daniel", &usk);
322
323 assert!(matches!(res, Err(Error::UnknownIdentifier(_))));
324 }
325}