libsignal_protocol/
sealed_sender.rs

1//
2// Copyright 2020-2022 Signal Messenger, LLC.
3// SPDX-License-Identifier: AGPL-3.0-only
4//
5
6use std::ops::Range;
7use std::time::SystemTime;
8
9use aes_gcm_siv::aead::generic_array::typenum::Unsigned;
10use aes_gcm_siv::{AeadInPlace, Aes256GcmSiv, KeyInit};
11use indexmap::IndexMap;
12use itertools::Itertools;
13use prost::Message;
14use proto::sealed_sender::unidentified_sender_message::message::Type as ProtoMessageType;
15use rand::{CryptoRng, Rng, TryRngCore as _};
16use subtle::ConstantTimeEq;
17use zerocopy::{FromBytes, Immutable, KnownLayout};
18
19use crate::{
20    crypto, message_encrypt, proto, ratchet, session_cipher, Aci, CiphertextMessageType, DeviceId,
21    Direction, IdentityKey, IdentityKeyPair, IdentityKeyStore, KeyPair, KyberPreKeyStore,
22    PreKeySignalMessage, PreKeyStore, PrivateKey, ProtocolAddress, PublicKey, Result, ServiceId,
23    ServiceIdFixedWidthBinaryBytes, SessionRecord, SessionStore, SignalMessage,
24    SignalProtocolError, SignedPreKeyStore, Timestamp,
25};
26
27#[derive(Debug, Clone)]
28pub struct ServerCertificate {
29    serialized: Vec<u8>,
30    key_id: u32,
31    key: PublicKey,
32    certificate: Vec<u8>,
33    signature: Vec<u8>,
34}
35
36/*
370xDEADC357 is a server certificate ID which is used to test the
38revocation logic. As of this writing, no prod server certificates have
39been revoked. If one ever does, add its key ID here.
40
41If a production server certificate is ever generated which collides
42with this test certificate ID, Bad Things will happen.
43*/
44const REVOKED_SERVER_CERTIFICATE_KEY_IDS: &[u32] = &[0xDEADC357];
45
46// Valid registration IDs fit in 14 bits.
47// TODO: move this into a RegistrationId strong type.
48const VALID_REGISTRATION_ID_MASK: u16 = 0x3FFF;
49
50impl ServerCertificate {
51    pub fn deserialize(data: &[u8]) -> Result<Self> {
52        let pb = proto::sealed_sender::ServerCertificate::decode(data)
53            .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
54
55        if pb.certificate.is_none() || pb.signature.is_none() {
56            return Err(SignalProtocolError::InvalidProtobufEncoding);
57        }
58
59        let certificate = pb
60            .certificate
61            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
62        let signature = pb
63            .signature
64            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
65        let certificate_data =
66            proto::sealed_sender::server_certificate::Certificate::decode(certificate.as_ref())
67                .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
68        let key = PublicKey::try_from(
69            &certificate_data
70                .key
71                .ok_or(SignalProtocolError::InvalidProtobufEncoding)?[..],
72        )?;
73        let key_id = certificate_data
74            .id
75            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
76
77        Ok(Self {
78            serialized: data.to_vec(),
79            certificate,
80            signature,
81            key,
82            key_id,
83        })
84    }
85
86    pub fn new<R: Rng + CryptoRng>(
87        key_id: u32,
88        key: PublicKey,
89        trust_root: &PrivateKey,
90        rng: &mut R,
91    ) -> Result<Self> {
92        let certificate_pb = proto::sealed_sender::server_certificate::Certificate {
93            id: Some(key_id),
94            key: Some(key.serialize().to_vec()),
95        };
96
97        let certificate = certificate_pb.encode_to_vec();
98
99        let signature = trust_root.calculate_signature(&certificate, rng)?.to_vec();
100
101        let serialized = proto::sealed_sender::ServerCertificate {
102            certificate: Some(certificate.clone()),
103            signature: Some(signature.clone()),
104        }
105        .encode_to_vec();
106
107        Ok(Self {
108            serialized,
109            certificate,
110            signature,
111            key,
112            key_id,
113        })
114    }
115
116    pub(crate) fn to_protobuf(&self) -> Result<proto::sealed_sender::ServerCertificate> {
117        Ok(proto::sealed_sender::ServerCertificate {
118            certificate: Some(self.certificate.clone()),
119            signature: Some(self.signature.clone()),
120        })
121    }
122
123    pub fn validate(&self, trust_root: &PublicKey) -> Result<bool> {
124        if REVOKED_SERVER_CERTIFICATE_KEY_IDS.contains(&self.key_id()?) {
125            log::error!(
126                "received server certificate with revoked ID {:x}",
127                self.key_id()?
128            );
129            return Ok(false);
130        }
131        Ok(trust_root.verify_signature(&self.certificate, &self.signature))
132    }
133
134    pub fn key_id(&self) -> Result<u32> {
135        Ok(self.key_id)
136    }
137
138    pub fn public_key(&self) -> Result<PublicKey> {
139        Ok(self.key)
140    }
141
142    pub fn certificate(&self) -> Result<&[u8]> {
143        Ok(&self.certificate)
144    }
145
146    pub fn signature(&self) -> Result<&[u8]> {
147        Ok(&self.signature)
148    }
149
150    pub fn serialized(&self) -> Result<&[u8]> {
151        Ok(&self.serialized)
152    }
153}
154
155#[derive(Debug, Clone)]
156pub struct SenderCertificate {
157    signer: ServerCertificate,
158    key: PublicKey,
159    sender_device_id: DeviceId,
160    sender_uuid: String,
161    sender_e164: Option<String>,
162    expiration: Timestamp,
163    serialized: Vec<u8>,
164    certificate: Vec<u8>,
165    signature: Vec<u8>,
166}
167
168impl SenderCertificate {
169    pub fn deserialize(data: &[u8]) -> Result<Self> {
170        let pb = proto::sealed_sender::SenderCertificate::decode(data)
171            .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
172        let certificate = pb
173            .certificate
174            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
175        let signature = pb
176            .signature
177            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
178        let certificate_data =
179            proto::sealed_sender::sender_certificate::Certificate::decode(certificate.as_ref())
180                .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
181
182        let sender_device_id: DeviceId = certificate_data
183            .sender_device
184            .and_then(|v| DeviceId::try_from(v).ok())
185            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
186        let expiration = certificate_data
187            .expires
188            .map(Timestamp::from_epoch_millis)
189            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
190        let signer_pb = certificate_data
191            .signer
192            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
193        let sender_uuid = certificate_data
194            .sender_uuid
195            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
196        let sender_e164 = certificate_data.sender_e164;
197
198        let key = PublicKey::try_from(
199            &certificate_data
200                .identity_key
201                .ok_or(SignalProtocolError::InvalidProtobufEncoding)?[..],
202        )?;
203
204        let signer_bits = signer_pb.encode_to_vec();
205        let signer = ServerCertificate::deserialize(&signer_bits)?;
206
207        Ok(Self {
208            signer,
209            key,
210            sender_device_id,
211            sender_uuid,
212            sender_e164,
213            expiration,
214            serialized: data.to_vec(),
215            certificate,
216            signature,
217        })
218    }
219
220    pub fn new<R: Rng + CryptoRng>(
221        sender_uuid: String,
222        sender_e164: Option<String>,
223        key: PublicKey,
224        sender_device_id: DeviceId,
225        expiration: Timestamp,
226        signer: ServerCertificate,
227        signer_key: &PrivateKey,
228        rng: &mut R,
229    ) -> Result<Self> {
230        let certificate_pb = proto::sealed_sender::sender_certificate::Certificate {
231            sender_uuid: Some(sender_uuid.clone()),
232            sender_e164: sender_e164.clone(),
233            sender_device: Some(sender_device_id.into()),
234            expires: Some(expiration.epoch_millis()),
235            identity_key: Some(key.serialize().to_vec()),
236            signer: Some(signer.to_protobuf()?),
237        };
238
239        let certificate = certificate_pb.encode_to_vec();
240
241        let signature = signer_key.calculate_signature(&certificate, rng)?.to_vec();
242
243        let serialized = proto::sealed_sender::SenderCertificate {
244            certificate: Some(certificate.clone()),
245            signature: Some(signature.clone()),
246        }
247        .encode_to_vec();
248
249        Ok(Self {
250            signer,
251            key,
252            sender_device_id,
253            sender_uuid,
254            sender_e164,
255            expiration,
256            serialized,
257            certificate,
258            signature,
259        })
260    }
261
262    pub fn validate(&self, trust_root: &PublicKey, validation_time: Timestamp) -> Result<bool> {
263        if !self.signer.validate(trust_root)? {
264            log::error!(
265                "sender certificate contained server certificate that wasn't signed by trust root"
266            );
267            return Ok(false);
268        }
269
270        if !self
271            .signer
272            .public_key()?
273            .verify_signature(&self.certificate, &self.signature)
274        {
275            log::error!("sender certificate not signed by server");
276            return Ok(false);
277        }
278
279        if validation_time > self.expiration {
280            log::error!(
281                "sender certificate is expired (expiration: {}, validation_time: {})",
282                self.expiration.epoch_millis(),
283                validation_time.epoch_millis()
284            );
285            return Ok(false);
286        }
287
288        Ok(true)
289    }
290
291    pub fn signer(&self) -> Result<&ServerCertificate> {
292        Ok(&self.signer)
293    }
294
295    pub fn key(&self) -> Result<PublicKey> {
296        Ok(self.key)
297    }
298
299    pub fn sender_device_id(&self) -> Result<DeviceId> {
300        Ok(self.sender_device_id)
301    }
302
303    pub fn sender_uuid(&self) -> Result<&str> {
304        Ok(&self.sender_uuid)
305    }
306
307    pub fn sender_e164(&self) -> Result<Option<&str>> {
308        Ok(self.sender_e164.as_deref())
309    }
310
311    pub fn expiration(&self) -> Result<Timestamp> {
312        Ok(self.expiration)
313    }
314
315    pub fn serialized(&self) -> Result<&[u8]> {
316        Ok(&self.serialized)
317    }
318
319    pub fn certificate(&self) -> Result<&[u8]> {
320        Ok(&self.certificate)
321    }
322
323    pub fn signature(&self) -> Result<&[u8]> {
324        Ok(&self.signature)
325    }
326}
327
328impl From<ProtoMessageType> for CiphertextMessageType {
329    fn from(message_type: ProtoMessageType) -> Self {
330        let result = match message_type {
331            ProtoMessageType::Message => Self::Whisper,
332            ProtoMessageType::PrekeyMessage => Self::PreKey,
333            ProtoMessageType::SenderkeyMessage => Self::SenderKey,
334            ProtoMessageType::PlaintextContent => Self::Plaintext,
335        };
336        // Keep raw values in sync from now on, for efficient codegen.
337        assert!(result == Self::PreKey || message_type as i32 == result as i32);
338        result
339    }
340}
341
342impl From<CiphertextMessageType> for ProtoMessageType {
343    fn from(message_type: CiphertextMessageType) -> Self {
344        let result = match message_type {
345            CiphertextMessageType::PreKey => Self::PrekeyMessage,
346            CiphertextMessageType::Whisper => Self::Message,
347            CiphertextMessageType::SenderKey => Self::SenderkeyMessage,
348            CiphertextMessageType::Plaintext => Self::PlaintextContent,
349        };
350        // Keep raw values in sync from now on, for efficient codegen.
351        assert!(result == Self::PrekeyMessage || message_type as i32 == result as i32);
352        result
353    }
354}
355
356#[derive(Clone, Copy, PartialEq, Eq, Debug)]
357pub enum ContentHint {
358    Default,
359    Resendable,
360    Implicit,
361    Unknown(u32),
362}
363
364impl ContentHint {
365    fn to_proto(self) -> Option<i32> {
366        if self == ContentHint::Default {
367            None
368        } else {
369            Some(u32::from(self) as i32)
370        }
371    }
372
373    pub const fn to_u32(self) -> u32 {
374        use proto::sealed_sender::unidentified_sender_message::message::ContentHint as ProtoContentHint;
375        match self {
376            ContentHint::Default => 0,
377            ContentHint::Resendable => ProtoContentHint::Resendable as u32,
378            ContentHint::Implicit => ProtoContentHint::Implicit as u32,
379            ContentHint::Unknown(value) => value,
380        }
381    }
382}
383
384impl From<u32> for ContentHint {
385    fn from(raw_value: u32) -> Self {
386        use proto::sealed_sender::unidentified_sender_message::message::ContentHint as ProtoContentHint;
387        assert!(!ProtoContentHint::is_valid(0));
388        match ProtoContentHint::try_from(raw_value as i32) {
389            Err(_) if raw_value == 0 => ContentHint::Default,
390            Err(_) => ContentHint::Unknown(raw_value),
391            Ok(ProtoContentHint::Resendable) => ContentHint::Resendable,
392            Ok(ProtoContentHint::Implicit) => ContentHint::Implicit,
393        }
394    }
395}
396
397impl From<ContentHint> for u32 {
398    fn from(hint: ContentHint) -> Self {
399        hint.to_u32()
400    }
401}
402
403pub struct UnidentifiedSenderMessageContent {
404    serialized: Vec<u8>,
405    contents: Vec<u8>,
406    sender: SenderCertificate,
407    msg_type: CiphertextMessageType,
408    content_hint: ContentHint,
409    group_id: Option<Vec<u8>>,
410}
411
412impl UnidentifiedSenderMessageContent {
413    pub fn deserialize(data: &[u8]) -> Result<Self> {
414        let pb = proto::sealed_sender::unidentified_sender_message::Message::decode(data)
415            .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
416
417        let msg_type = pb
418            .r#type
419            .and_then(|t| ProtoMessageType::try_from(t).ok())
420            .map(CiphertextMessageType::from)
421            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
422        let sender = pb
423            .sender_certificate
424            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
425        let contents = pb
426            .content
427            .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
428        let content_hint = pb
429            .content_hint
430            .map(|raw| ContentHint::from(raw as u32))
431            .unwrap_or(ContentHint::Default);
432        let group_id = pb.group_id;
433
434        let sender = SenderCertificate::deserialize(&sender)?;
435
436        let serialized = data.to_vec();
437
438        log::info!(
439            "deserialized UnidentifiedSenderMessageContent from {}.{} with type {:?}",
440            sender.sender_uuid()?,
441            sender.sender_device_id()?,
442            msg_type,
443        );
444
445        Ok(Self {
446            serialized,
447            contents,
448            sender,
449            msg_type,
450            content_hint,
451            group_id,
452        })
453    }
454
455    pub fn new(
456        msg_type: CiphertextMessageType,
457        sender: SenderCertificate,
458        contents: Vec<u8>,
459        content_hint: ContentHint,
460        group_id: Option<Vec<u8>>,
461    ) -> Result<Self> {
462        let proto_msg_type = ProtoMessageType::from(msg_type);
463        let msg = proto::sealed_sender::unidentified_sender_message::Message {
464            content: Some(contents.clone()),
465            r#type: Some(proto_msg_type.into()),
466            sender_certificate: Some(sender.serialized()?.to_vec()),
467            content_hint: content_hint.to_proto(),
468            group_id: group_id.as_ref().and_then(|buf| {
469                if buf.is_empty() {
470                    None
471                } else {
472                    Some(buf.clone())
473                }
474            }),
475        };
476
477        let serialized = msg.encode_to_vec();
478
479        Ok(Self {
480            serialized,
481            msg_type,
482            sender,
483            contents,
484            content_hint,
485            group_id,
486        })
487    }
488
489    pub fn msg_type(&self) -> Result<CiphertextMessageType> {
490        Ok(self.msg_type)
491    }
492
493    pub fn sender(&self) -> Result<&SenderCertificate> {
494        Ok(&self.sender)
495    }
496
497    pub fn contents(&self) -> Result<&[u8]> {
498        Ok(&self.contents)
499    }
500
501    pub fn content_hint(&self) -> Result<ContentHint> {
502        Ok(self.content_hint)
503    }
504
505    pub fn group_id(&self) -> Result<Option<&[u8]>> {
506        Ok(self.group_id.as_deref())
507    }
508
509    pub fn serialized(&self) -> Result<&[u8]> {
510        Ok(&self.serialized)
511    }
512}
513
514enum UnidentifiedSenderMessage<'a> {
515    V1 {
516        ephemeral_public: PublicKey,
517        encrypted_static: Vec<u8>,
518        encrypted_message: Vec<u8>,
519    },
520    V2 {
521        ephemeral_public: PublicKey,
522        encrypted_message_key: &'a [u8; sealed_sender_v2::MESSAGE_KEY_LEN],
523        authentication_tag: &'a [u8; sealed_sender_v2::AUTH_TAG_LEN],
524        encrypted_message: &'a [u8],
525    },
526}
527
528const SEALED_SENDER_V1_MAJOR_VERSION: u8 = 1;
529const SEALED_SENDER_V1_FULL_VERSION: u8 = 0x11;
530const SEALED_SENDER_V2_MAJOR_VERSION: u8 = 2;
531const SEALED_SENDER_V2_UUID_FULL_VERSION: u8 = 0x22;
532const SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION: u8 = 0x23;
533
534impl<'a> UnidentifiedSenderMessage<'a> {
535    fn deserialize(data: &'a [u8]) -> Result<Self> {
536        let (version_byte, remaining) = data.split_first().ok_or_else(|| {
537            SignalProtocolError::InvalidSealedSenderMessage("Message was empty".to_owned())
538        })?;
539        let version = version_byte >> 4;
540        log::debug!("deserializing UnidentifiedSenderMessage with version {version}");
541
542        match version {
543            0 | SEALED_SENDER_V1_MAJOR_VERSION => {
544                // XXX should we really be accepted version == 0 here?
545                let pb = proto::sealed_sender::UnidentifiedSenderMessage::decode(remaining)
546                    .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
547
548                let ephemeral_public = pb
549                    .ephemeral_public
550                    .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
551                let encrypted_static = pb
552                    .encrypted_static
553                    .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
554                let encrypted_message = pb
555                    .encrypted_message
556                    .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
557
558                let ephemeral_public = PublicKey::try_from(&ephemeral_public[..])?;
559
560                Ok(Self::V1 {
561                    ephemeral_public,
562                    encrypted_static,
563                    encrypted_message,
564                })
565            }
566            SEALED_SENDER_V2_MAJOR_VERSION => {
567                /// Uses a flat representation: C || AT || E.pub || ciphertext
568                #[derive(FromBytes, Immutable, KnownLayout)]
569                #[repr(C, packed)]
570                struct PrefixRepr {
571                    encrypted_message_key: [u8; sealed_sender_v2::MESSAGE_KEY_LEN],
572                    encrypted_authentication_tag: [u8; sealed_sender_v2::AUTH_TAG_LEN],
573                    ephemeral_public: [u8; sealed_sender_v2::PUBLIC_KEY_LEN],
574                }
575                let (prefix, encrypted_message) =
576                    zerocopy::Ref::<_, PrefixRepr>::from_prefix(remaining)
577                        .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
578
579                let PrefixRepr {
580                    encrypted_message_key,
581                    encrypted_authentication_tag,
582                    ephemeral_public,
583                } = zerocopy::Ref::into_ref(prefix);
584
585                Ok(Self::V2 {
586                    ephemeral_public: PublicKey::from_djb_public_key_bytes(
587                        ephemeral_public.as_slice(),
588                    )?,
589                    encrypted_message_key,
590                    authentication_tag: encrypted_authentication_tag,
591                    encrypted_message,
592                })
593            }
594            _ => Err(SignalProtocolError::UnknownSealedSenderVersion(version)),
595        }
596    }
597}
598
599mod sealed_sender_v1 {
600    #[cfg(test)]
601    use std::fmt;
602
603    use zerocopy::IntoBytes;
604
605    use super::*;
606
607    /// A symmetric cipher key and a MAC key, along with a "chain key" consumed in
608    /// [`StaticKeys::calculate`].
609    pub(super) struct EphemeralKeys {
610        pub(super) chain_key: [u8; 32],
611        pub(super) cipher_key: [u8; 32],
612        pub(super) mac_key: [u8; 32],
613    }
614
615    const SALT_PREFIX: &[u8] = b"UnidentifiedDelivery";
616
617    impl EphemeralKeys {
618        /// Derive a set of symmetric keys from the key agreement between the sender and
619        /// recipient's identities.
620        pub(super) fn calculate(
621            our_keys: &KeyPair,
622            their_public: &PublicKey,
623            direction: Direction,
624        ) -> Result<Self> {
625            let our_pub_key = our_keys.public_key.serialize();
626            let their_pub_key = their_public.serialize();
627            let ephemeral_salt = match direction {
628                Direction::Sending => [SALT_PREFIX, &their_pub_key, &our_pub_key],
629                Direction::Receiving => [SALT_PREFIX, &our_pub_key, &their_pub_key],
630            }
631            .concat();
632
633            let shared_secret = our_keys.private_key.calculate_agreement(their_public)?;
634            #[derive(Default, KnownLayout, IntoBytes, FromBytes)]
635            #[repr(C, packed)]
636            struct DerivedValues([u8; 32], [u8; 32], [u8; 32]);
637            let mut derived_values = DerivedValues::default();
638            hkdf::Hkdf::<sha2::Sha256>::new(Some(&ephemeral_salt), &shared_secret)
639                .expand(&[], derived_values.as_mut_bytes())
640                .expect("valid output length");
641
642            let DerivedValues(chain_key, cipher_key, mac_key) = derived_values;
643
644            Ok(Self {
645                chain_key,
646                cipher_key,
647                mac_key,
648            })
649        }
650    }
651
652    #[cfg(test)]
653    impl PartialEq for EphemeralKeys {
654        fn eq(&self, other: &Self) -> bool {
655            self.chain_key == other.chain_key
656                && self.cipher_key == other.cipher_key
657                && self.mac_key == other.mac_key
658        }
659    }
660
661    #[cfg(test)]
662    impl Eq for EphemeralKeys {}
663
664    #[cfg(test)]
665    impl fmt::Debug for EphemeralKeys {
666        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
667            write!(
668                f,
669                "EphemeralKeys {{ chain_key: {:?}, cipher_key: {:?}, mac_key: {:?} }}",
670                self.chain_key, self.cipher_key, self.mac_key
671            )
672        }
673    }
674
675    /// A symmetric cipher key and a MAC key.
676    pub(super) struct StaticKeys {
677        pub(super) cipher_key: [u8; 32],
678        pub(super) mac_key: [u8; 32],
679    }
680
681    impl StaticKeys {
682        /// Derive a set of symmetric keys from the agreement between the sender and
683        /// recipient's identities, as well as [`EphemeralKeys::chain_key`].
684        pub(super) fn calculate(
685            our_keys: &IdentityKeyPair,
686            their_key: &PublicKey,
687            chain_key: &[u8; 32],
688            ctext: &[u8],
689        ) -> Result<Self> {
690            let salt = [chain_key, ctext].concat();
691
692            let shared_secret = our_keys.private_key().calculate_agreement(their_key)?;
693            // 96 bytes are derived, but the first 32 are discarded/unused. This is intended to
694            // mirror the way the EphemeralKeys are derived, even though StaticKeys does not end up
695            // requiring a third "chain key".
696            #[derive(Default, KnownLayout, IntoBytes, FromBytes)]
697            #[repr(C, packed)]
698            struct DerivedValues(#[allow(unused)] [u8; 32], [u8; 32], [u8; 32]);
699            let mut derived_values = DerivedValues::default();
700            hkdf::Hkdf::<sha2::Sha256>::new(Some(&salt), &shared_secret)
701                .expand(&[], derived_values.as_mut_bytes())
702                .expect("valid output length");
703
704            let DerivedValues(_, cipher_key, mac_key) = derived_values;
705
706            Ok(Self {
707                cipher_key,
708                mac_key,
709            })
710        }
711    }
712
713    #[test]
714    fn test_agreement_and_authentication() -> Result<()> {
715        // The sender and recipient each have a long-term identity key pair.
716        let sender_identity = IdentityKeyPair::generate(&mut rand::rng());
717        let recipient_identity = IdentityKeyPair::generate(&mut rand::rng());
718
719        // Generate an ephemeral key pair.
720        let sender_ephemeral = KeyPair::generate(&mut rand::rng());
721        let ephemeral_public = sender_ephemeral.public_key;
722        // Generate ephemeral cipher, chain, and MAC keys.
723        let sender_eph_keys = EphemeralKeys::calculate(
724            &sender_ephemeral,
725            recipient_identity.public_key(),
726            Direction::Sending,
727        )?;
728
729        // Encrypt the sender's public key with AES-256 CTR and a MAC.
730        let sender_static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
731            &sender_identity.public_key().serialize(),
732            &sender_eph_keys.cipher_key,
733            &sender_eph_keys.mac_key,
734        )
735        .expect("just generated these keys, they should be correct");
736
737        // Generate another cipher and MAC key.
738        let sender_static_keys = StaticKeys::calculate(
739            &sender_identity,
740            recipient_identity.public_key(),
741            &sender_eph_keys.chain_key,
742            &sender_static_key_ctext,
743        )?;
744
745        let sender_message_contents = b"this is a binary message";
746        let sender_message_data = crypto::aes256_ctr_hmacsha256_encrypt(
747            sender_message_contents,
748            &sender_static_keys.cipher_key,
749            &sender_static_keys.mac_key,
750        )
751        .expect("just generated these keys, they should be correct");
752
753        // The message recipient calculates the ephemeral key and the sender's public key.
754        let recipient_eph_keys = EphemeralKeys::calculate(
755            &recipient_identity.into(),
756            &ephemeral_public,
757            Direction::Receiving,
758        )?;
759        assert_eq!(sender_eph_keys, recipient_eph_keys);
760
761        let recipient_message_key_bytes = crypto::aes256_ctr_hmacsha256_decrypt(
762            &sender_static_key_ctext,
763            &recipient_eph_keys.cipher_key,
764            &recipient_eph_keys.mac_key,
765        )
766        .expect("should decrypt successfully");
767        let sender_public_key: PublicKey = PublicKey::try_from(&recipient_message_key_bytes[..])?;
768        assert_eq!(sender_identity.public_key(), &sender_public_key);
769
770        let recipient_static_keys = StaticKeys::calculate(
771            &recipient_identity,
772            &sender_public_key,
773            &recipient_eph_keys.chain_key,
774            &sender_static_key_ctext,
775        )?;
776
777        let recipient_message_contents = crypto::aes256_ctr_hmacsha256_decrypt(
778            &sender_message_data,
779            &recipient_static_keys.cipher_key,
780            &recipient_static_keys.mac_key,
781        )
782        .expect("should decrypt successfully");
783        assert_eq!(recipient_message_contents, sender_message_contents);
784
785        Ok(())
786    }
787}
788
789/// Encrypt the plaintext message `ptext`, generate an [`UnidentifiedSenderMessageContent`], then
790/// pass the result to [`sealed_sender_encrypt_from_usmc`].
791///
792/// This is a simple way to encrypt a message in a 1:1 using [Sealed Sender v1].
793///
794/// [Sealed Sender v1]: sealed_sender_encrypt_from_usmc
795pub async fn sealed_sender_encrypt<R: Rng + CryptoRng>(
796    destination: &ProtocolAddress,
797    sender_cert: &SenderCertificate,
798    ptext: &[u8],
799    session_store: &mut dyn SessionStore,
800    identity_store: &mut dyn IdentityKeyStore,
801    now: SystemTime,
802    rng: &mut R,
803) -> Result<Vec<u8>> {
804    let message =
805        message_encrypt(ptext, destination, session_store, identity_store, now, rng).await?;
806    let usmc = UnidentifiedSenderMessageContent::new(
807        message.message_type(),
808        sender_cert.clone(),
809        message.serialize().to_vec(),
810        ContentHint::Default,
811        None,
812    )?;
813    sealed_sender_encrypt_from_usmc(destination, &usmc, identity_store, rng).await
814}
815
816/// This method implements the single-key single-recipient [KEM] described in [this Signal blog
817/// post], a.k.a. Sealed Sender v1.
818///
819/// [KEM]: https://en.wikipedia.org/wiki/Key_encapsulation
820/// [this Signal blog post]: https://signal.org/blog/sealed-sender/
821///
822/// [`sealed_sender_decrypt`] is used in the client to decrypt the Sealed Sender message produced by
823/// this method.
824///
825/// # Contrast with Sealed Sender v2
826/// The *single-recipient* KEM scheme implemented by this method partially derives the encryption
827/// key from the recipient's identity key, which would then require re-encrypting the same message
828/// multiple times to send to multiple recipients. In contrast,
829/// [Sealed Sender v2](sealed_sender_multi_recipient_encrypt) uses a *multi-recipient* KEM scheme
830/// which avoids this repeated work, but makes a few additional design tradeoffs.
831///
832/// # High-level algorithmic overview
833/// The KEM scheme implemented by this method is described in [this Signal blog post]. The
834/// high-level steps of this process are listed below:
835/// 1. Generate a random key pair.
836/// 2. Derive a symmetric chain key, cipher key, and MAC key from the recipient's public key and the
837///    sender's public/private key pair.
838/// 3. Symmetrically encrypt the sender's public key using the cipher key and MAC key from (2) with
839///    AES-256 in CTR mode.
840/// 4. Derive a second symmetric cipher key and MAC key from the sender's private key, the
841///    recipient's public key, and the chain key from (2).
842/// 5. Symmetrically encrypt the underlying [`UnidentifiedSenderMessageContent`] using the cipher key
843///    and MAC key from (4) with AES-256 in CTR mode.
844/// 6. Send the ephemeral public key from (1) and the encrypted public key from (3) to the
845///    recipient, along with the encrypted message (5).
846///
847/// ## Pseudocode
848///```text
849/// e_pub, e_priv                  = X25519.generateEphemeral()
850/// e_chain, e_cipherKey, e_macKey = HKDF(salt="UnidentifiedDelivery" || recipientIdentityPublic || e_pub, ikm=ECDH(recipientIdentityPublic, e_priv), info="")
851/// e_ciphertext                   = AES_CTR(key=e_cipherKey, input=senderIdentityPublic)
852/// e_mac                          = Hmac256(key=e_macKey, input=e_ciphertext)
853///
854/// s_cipherKey, s_macKey = HKDF(salt=e_chain || e_ciphertext || e_mac, ikm=ECDH(recipientIdentityPublic, senderIdentityPrivate), info="")
855/// s_ciphertext          = AES_CTR(key=s_cipherKey, input=sender_certificate || message_ciphertext)
856/// s_mac                 = Hmac256(key=s_macKey, input=s_ciphertext)
857///
858/// message_to_send = s_ciphertext || s_mac
859///```
860///
861/// # Wire Format
862/// The output of this method is encoded as an `UnidentifiedSenderMessage.Message` from
863/// `sealed_sender.proto`, prepended with an additional byte to indicate the version of Sealed
864/// Sender in use (see [further documentation on the version
865/// byte](sealed_sender_multi_recipient_encrypt#the-version-byte)).
866pub async fn sealed_sender_encrypt_from_usmc<R: Rng + CryptoRng>(
867    destination: &ProtocolAddress,
868    usmc: &UnidentifiedSenderMessageContent,
869    identity_store: &dyn IdentityKeyStore,
870    rng: &mut R,
871) -> Result<Vec<u8>> {
872    let our_identity = identity_store.get_identity_key_pair().await?;
873    let their_identity = identity_store
874        .get_identity(destination)
875        .await?
876        .ok_or_else(|| SignalProtocolError::SessionNotFound(destination.clone()))?;
877
878    let ephemeral = KeyPair::generate(rng);
879
880    let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
881        &ephemeral,
882        their_identity.public_key(),
883        Direction::Sending,
884    )?;
885
886    let static_key_ctext = crypto::aes256_ctr_hmacsha256_encrypt(
887        &our_identity.public_key().serialize(),
888        &eph_keys.cipher_key,
889        &eph_keys.mac_key,
890    )
891    .expect("just generated these keys, they should be correct");
892
893    let static_keys = sealed_sender_v1::StaticKeys::calculate(
894        &our_identity,
895        their_identity.public_key(),
896        &eph_keys.chain_key,
897        &static_key_ctext,
898    )?;
899
900    let message_data = crypto::aes256_ctr_hmacsha256_encrypt(
901        usmc.serialized()?,
902        &static_keys.cipher_key,
903        &static_keys.mac_key,
904    )
905    .expect("just generated these keys, they should be correct");
906
907    let mut serialized = vec![SEALED_SENDER_V1_FULL_VERSION];
908    let pb = proto::sealed_sender::UnidentifiedSenderMessage {
909        ephemeral_public: Some(ephemeral.public_key.serialize().to_vec()),
910        encrypted_static: Some(static_key_ctext),
911        encrypted_message: Some(message_data),
912    };
913    pb.encode(&mut serialized)
914        .expect("can always append to Vec");
915
916    Ok(serialized)
917}
918
919mod sealed_sender_v2 {
920    use super::*;
921
922    // Static byte strings used as part of a MAC in HKDF.
923    const LABEL_R: &[u8] = b"Sealed Sender v2: r (2023-08)";
924    const LABEL_K: &[u8] = b"Sealed Sender v2: K";
925    const LABEL_DH: &[u8] = b"Sealed Sender v2: DH";
926    const LABEL_DH_S: &[u8] = b"Sealed Sender v2: DH-sender";
927
928    pub const MESSAGE_KEY_LEN: usize = 32;
929    pub const CIPHER_KEY_LEN: usize =
930        <Aes256GcmSiv as aes_gcm_siv::aead::KeySizeUser>::KeySize::USIZE;
931    pub const AUTH_TAG_LEN: usize = 16;
932    /// SSv2 hardcodes that its keys are Curve25519 public keys.
933    pub const PUBLIC_KEY_LEN: usize = 32;
934
935    /// An asymmetric and a symmetric cipher key.
936    pub(super) struct DerivedKeys {
937        kdf: hkdf::Hkdf<sha2::Sha256>,
938    }
939
940    impl DerivedKeys {
941        /// Initialize from a slice of random bytes `m`.
942        pub(super) fn new(m: &[u8]) -> DerivedKeys {
943            Self {
944                kdf: hkdf::Hkdf::<sha2::Sha256>::new(None, m),
945            }
946        }
947
948        /// Derive the ephemeral asymmetric keys.
949        pub(super) fn derive_e(&self) -> KeyPair {
950            let mut r = [0; 32];
951            self.kdf
952                .expand(LABEL_R, &mut r)
953                .expect("valid output length");
954            let e = PrivateKey::try_from(&r[..]).expect("valid PrivateKey");
955            KeyPair::try_from(e).expect("can derive public key")
956        }
957
958        /// Derive the symmetric cipher key.
959        pub(super) fn derive_k(&self) -> [u8; CIPHER_KEY_LEN] {
960            let mut k = [0; CIPHER_KEY_LEN];
961            self.kdf
962                .expand(LABEL_K, &mut k)
963                .expect("valid output length");
964            k
965        }
966    }
967
968    /// Encrypt or decrypt a slice of random bytes `input` using a shared secret derived from
969    /// `our_keys` and `their_key`.
970    ///
971    /// The output of this method when called with [`Direction::Sending`] can be inverted to produce
972    /// the original `input` bytes if called with [`Direction::Receiving`] with `our_keys` and
973    /// `their_key` swapped.
974    pub(super) fn apply_agreement_xor(
975        our_keys: &KeyPair,
976        their_key: &PublicKey,
977        direction: Direction,
978        input: &[u8; MESSAGE_KEY_LEN],
979    ) -> Result<[u8; MESSAGE_KEY_LEN]> {
980        let agreement = our_keys.calculate_agreement(their_key)?;
981        let agreement_key_input = match direction {
982            Direction::Sending => [
983                agreement,
984                our_keys.public_key.serialize(),
985                their_key.serialize(),
986            ],
987            Direction::Receiving => [
988                agreement,
989                their_key.serialize(),
990                our_keys.public_key.serialize(),
991            ],
992        }
993        .concat();
994
995        let mut result = [0; MESSAGE_KEY_LEN];
996        hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
997            .expand(LABEL_DH, &mut result)
998            .expect("valid output length");
999        result
1000            .iter_mut()
1001            .zip(input)
1002            .for_each(|(result_byte, input_byte)| *result_byte ^= input_byte);
1003        Ok(result)
1004    }
1005
1006    /// Compute an [authentication tag] for the bytes `encrypted_message_key` using a shared secret
1007    /// derived from `our_keys` and `their_key`.
1008    ///
1009    /// [authentication tag]: https://en.wikipedia.org/wiki/Message_authentication_code
1010    ///
1011    /// The output of this method with [`Direction::Sending`] should be the same bytes produced by
1012    /// calling this method with [`Direction::Receiving`] with `our_keys` and `their_key`
1013    /// swapped, if `ephemeral_pub_key` and `encrypted_message_key` are the same.
1014    pub(super) fn compute_authentication_tag(
1015        our_keys: &IdentityKeyPair,
1016        their_key: &IdentityKey,
1017        direction: Direction,
1018        ephemeral_pub_key: &PublicKey,
1019        encrypted_message_key: &[u8; MESSAGE_KEY_LEN],
1020    ) -> Result<[u8; AUTH_TAG_LEN]> {
1021        let agreement = our_keys
1022            .private_key()
1023            .calculate_agreement(their_key.public_key())?;
1024        let mut agreement_key_input = agreement.into_vec();
1025        agreement_key_input.extend_from_slice(&ephemeral_pub_key.serialize());
1026        agreement_key_input.extend_from_slice(encrypted_message_key);
1027        match direction {
1028            Direction::Sending => {
1029                agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1030                agreement_key_input.extend_from_slice(&their_key.serialize());
1031            }
1032            Direction::Receiving => {
1033                agreement_key_input.extend_from_slice(&their_key.serialize());
1034                agreement_key_input.extend_from_slice(&our_keys.public_key().serialize());
1035            }
1036        }
1037
1038        let mut result = [0; AUTH_TAG_LEN];
1039        hkdf::Hkdf::<sha2::Sha256>::new(None, &agreement_key_input)
1040            .expand(LABEL_DH_S, &mut result)
1041            .expect("valid output length");
1042        Ok(result)
1043    }
1044
1045    #[test]
1046    fn test_agreement_and_authentication() -> Result<()> {
1047        // The sender and recipient each have a long-term identity key pair.
1048        let sender_identity = IdentityKeyPair::generate(&mut rand::rng());
1049        let recipient_identity = IdentityKeyPair::generate(&mut rand::rng());
1050
1051        // Generate random bytes used for our multi-recipient encoding scheme.
1052        let m: [u8; MESSAGE_KEY_LEN] = rand::rng().random();
1053        // Derive an ephemeral key pair from those random bytes.
1054        let ephemeral_keys = DerivedKeys::new(&m);
1055        let e = ephemeral_keys.derive_e();
1056
1057        // Encrypt the ephemeral key pair.
1058        let sender_c_0: [u8; MESSAGE_KEY_LEN] =
1059            apply_agreement_xor(&e, recipient_identity.public_key(), Direction::Sending, &m)?;
1060        // Compute an authentication tag for the encrypted key pair.
1061        let sender_at_0 = compute_authentication_tag(
1062            &sender_identity,
1063            recipient_identity.identity_key(),
1064            Direction::Sending,
1065            &e.public_key,
1066            &sender_c_0,
1067        )?;
1068
1069        // The message recipient calculates the original random bytes and authenticates the result.
1070        let recv_m = apply_agreement_xor(
1071            &recipient_identity.into(),
1072            &e.public_key,
1073            Direction::Receiving,
1074            &sender_c_0,
1075        )?;
1076        assert_eq!(&recv_m, &m);
1077
1078        let recv_at_0 = compute_authentication_tag(
1079            &recipient_identity,
1080            sender_identity.identity_key(),
1081            Direction::Receiving,
1082            &e.public_key,
1083            &sender_c_0,
1084        )?;
1085        assert_eq!(&recv_at_0, &sender_at_0);
1086
1087        Ok(())
1088    }
1089}
1090
1091/// This method implements a single-key multi-recipient [KEM] as defined in Manuel Barbosa's
1092/// ["Randomness Reuse: Extensions and Improvements"], a.k.a. Sealed Sender v2.
1093///
1094/// [KEM]: https://en.wikipedia.org/wiki/Key_encapsulation
1095/// ["Randomness Reuse: Extensions and Improvements"]: https://haslab.uminho.pt/mbb/files/reuse.pdf
1096///
1097/// # Contrast with Sealed Sender v1
1098/// The KEM scheme implemented by this method uses the "Generic Construction" in `4.1` of [Barbosa's
1099/// paper]["Randomness Reuse: Extensions and Improvements"], instantiated with [ElGamal encryption].
1100/// This technique enables reusing a single sequence of random bytes across multiple messages with
1101/// the same content, which reduces computation time for clients sending the same message to
1102/// multiple recipients (without compromising the message security).
1103///
1104/// There are a few additional design tradeoffs this method makes vs [Sealed Sender v1] which may
1105/// make it comparatively unwieldy for certain scenarios:
1106/// 1. it requires a [`SessionRecord`] to exist already for the recipient, i.e. that a Double
1107///    Ratchet message chain has previously been established in the [`SessionStore`] via
1108///    [`process_prekey_bundle`][crate::process_prekey_bundle] after an initial
1109///    [`PreKeySignalMessage`] is received.
1110/// 2. it ferries a lot of additional information in its encoding which makes the resulting message
1111///    bulkier than the message produced by [Sealed Sender v1]. For sending, this will generally
1112///    still be more compact than sending the same message N times, but on the receiver side the
1113///    message is slightly larger.
1114/// 3. unlike other message types sent over the wire, the encoded message returned by this method
1115///    does not use protobuf, in order to avoid inefficiencies produced by protobuf's packing (see
1116///    **[Wire Format]**).
1117///
1118/// [ElGamal encryption]: https://en.wikipedia.org/wiki/ElGamal_encryption
1119/// [Sealed Sender v1]: sealed_sender_encrypt_from_usmc
1120/// [Wire Format]: #wire-format
1121///
1122/// # High-level algorithmic overview
1123/// The high-level steps of this process are summarized below:
1124/// 1. Generate a series of random bytes.
1125/// 2. Derive an ephemeral key pair from (1).
1126/// 3. *Once per recipient:* Encrypt (1) using a shared secret derived from the private ephemeral
1127///    key (2) and the recipient's public identity key.
1128/// 4. *Once per recipient:* Add an authentication tag for (3) using a secret derived from the
1129///    sender's private identity key and the recipient's public identity key.
1130/// 5. Generate a symmetric key from (1) and use it to symmetrically encrypt the underlying
1131///    [`UnidentifiedSenderMessageContent`] via [AEAD encryption]. *This step is only performed once
1132///    per message, regardless of the number of recipients.*
1133/// 6. Send the public ephemeral key (2) to the server, along with the sequence of encrypted random
1134///    bytes (3) and authentication tags (4), and the single encrypted message (5).
1135///
1136/// [AEAD encryption]:
1137///    https://en.wikipedia.org/wiki/Authenticated_encryption#Authenticated_encryption_with_associated_data_(AEAD)
1138///
1139/// ## Pseudocode
1140///```text
1141/// ENCRYPT(message, R_i):
1142///     M = Random(32)
1143///     r = KDF(label_r, M, len=32)
1144///     K = KDF(label_K, M, len=32)
1145///     E = DeriveKeyPair(r)
1146///     for i in num_recipients:
1147///         C_i = KDF(label_DH, DH(E, R_i) || E.public || R_i.public, len=32) XOR M
1148///         AT_i = KDF(label_DH_s, DH(S, R_i) || E.public || C_i || S.public || R_i.public, len=16)
1149///     ciphertext = AEAD_Encrypt(K, message)
1150///     return E.public, C_i, AT_i, ciphertext
1151///
1152/// DECRYPT(E.public, C, AT, ciphertext):
1153///     M = KDF(label_DH, DH(E, R) || E.public || R.public, len=32) xor C
1154///     r = KDF(label_r, M, len=32)
1155///     K = KDF(label_K, M, len=32)
1156///     E' = DeriveKeyPair(r)
1157///     if E.public != E'.public:
1158///         return DecryptionError
1159///     message = AEAD_Decrypt(K, ciphertext) // includes S.public
1160///     AT' = KDF(label_DH_s, DH(S, R) || E.public || C || S.public || R.public, len=16)
1161///     if AT != AT':
1162///         return DecryptionError
1163///     return message
1164///```
1165///
1166/// # Routing messages to recipients
1167///
1168/// The server will split up the set of messages and securely route each individual [received
1169/// message][receiving] to its intended recipient. [`SealedSenderV2SentMessage`] can perform this
1170/// fan-out operation.
1171///
1172/// # Wire Format
1173/// Multi-recipient sealed-sender does not use protobufs for its payload format. Instead, it uses a
1174/// flat format marked with a [version byte](#the-version-byte). The format is different for
1175/// [sending] and [receiving]. The decrypted content is a protobuf-encoded
1176/// `UnidentifiedSenderMessage.Message` from `sealed_sender.proto`.
1177///
1178/// The public key used in Sealed Sender v2 is always a Curve25519 DJB key.
1179///
1180/// [sending]: #sent-messages
1181/// [receiving]: #received-messages
1182///
1183/// ## The version byte
1184///
1185/// Sealed sender messages (v1 and v2) in serialized form begin with a version [byte][u8]. This byte
1186/// has the form:
1187///
1188/// ```text
1189/// (requiredVersion << 4) | currentVersion
1190/// ```
1191///
1192/// v1 messages thus have a version byte of `0x11`. v2 messages have a version byte of `0x22` or
1193/// `0x23`. A hypothetical version byte `0x34` would indicate a message encoded as Sealed Sender v4,
1194/// but decodable by any client that supports Sealed Sender v3.
1195///
1196/// ## Received messages
1197///
1198/// ```text
1199/// ReceivedMessage {
1200///     version_byte: u8,
1201///     c: [u8; 32],
1202///     at: [u8; 16],
1203///     e_pub: [u8; 32],
1204///     message: [u8] // remaining bytes
1205/// }
1206/// ```
1207///
1208/// Each individual Sealed Sender message received from the server is decoded in the Signal client
1209/// by calling [`sealed_sender_decrypt`].
1210///
1211/// ## Sent messages
1212///
1213/// ```text
1214/// SentMessage {
1215///     version_byte: u8,
1216///     count: varint,
1217///     recipients: [PerRecipientData | ExcludedRecipient; count],
1218///     e_pub: [u8; 32],
1219///     message: [u8] // remaining bytes
1220/// }
1221///
1222/// PerRecipientData {
1223///     recipient: Recipient,
1224///     devices: [DeviceList], // last element's has_more = 0
1225///     c: [u8; 32],
1226///     at: [u8; 16],
1227/// }
1228///
1229/// ExcludedRecipient {
1230///     recipient: Recipient,
1231///     no_devices_marker: u8 = 0, // never a valid device ID
1232/// }
1233///
1234/// DeviceList {
1235///     device_id: u8,
1236///     has_more: u1, // high bit of following field
1237///     unused: u1,   // high bit of following field
1238///     registration_id: u14,
1239/// }
1240///
1241/// Recipient {
1242///     service_id_fixed_width_binary: [u8; 17],
1243/// }
1244/// ```
1245///
1246/// The varint encoding used is the same as [protobuf's][varint]. Values are unsigned.
1247/// Fixed-width-binary encoding is used for the [ServiceId] values.
1248/// Fixed-width integers are unaligned and in network byte order (big-endian).
1249///
1250/// [varint]: https://developers.google.com/protocol-buffers/docs/encoding#varints
1251pub async fn sealed_sender_multi_recipient_encrypt<
1252    R: Rng + CryptoRng,
1253    X: IntoIterator<Item = ServiceId>,
1254>(
1255    destinations: &[&ProtocolAddress],
1256    destination_sessions: &[&SessionRecord],
1257    excluded_recipients: X,
1258    usmc: &UnidentifiedSenderMessageContent,
1259    identity_store: &dyn IdentityKeyStore,
1260    rng: &mut R,
1261) -> Result<Vec<u8>>
1262where
1263    X::IntoIter: ExactSizeIterator,
1264{
1265    sealed_sender_multi_recipient_encrypt_impl(
1266        destinations,
1267        destination_sessions,
1268        excluded_recipients,
1269        usmc,
1270        identity_store,
1271        rng,
1272    )
1273    .await
1274}
1275
1276async fn sealed_sender_multi_recipient_encrypt_impl<
1277    R: Rng + CryptoRng,
1278    X: IntoIterator<Item = ServiceId>,
1279>(
1280    destinations: &[&ProtocolAddress],
1281    destination_sessions: &[&SessionRecord],
1282    excluded_recipients: X,
1283    usmc: &UnidentifiedSenderMessageContent,
1284    identity_store: &dyn IdentityKeyStore,
1285    rng: &mut R,
1286) -> Result<Vec<u8>>
1287where
1288    X::IntoIter: ExactSizeIterator,
1289{
1290    if destinations.len() != destination_sessions.len() {
1291        return Err(SignalProtocolError::InvalidArgument(
1292            "must have the same number of destination sessions as addresses".to_string(),
1293        ));
1294    }
1295
1296    let excluded_recipients = excluded_recipients.into_iter();
1297    let our_identity = identity_store.get_identity_key_pair().await?;
1298
1299    let m: [u8; sealed_sender_v2::MESSAGE_KEY_LEN] = rng.random();
1300    let keys = sealed_sender_v2::DerivedKeys::new(&m);
1301    let e = keys.derive_e();
1302    let e_pub = &e.public_key;
1303
1304    // Encrypt the shared ciphertext using AES-GCM-SIV.
1305    let ciphertext = {
1306        let mut ciphertext = usmc.serialized()?.to_vec();
1307        let symmetric_authentication_tag = Aes256GcmSiv::new(&keys.derive_k().into())
1308            .encrypt_in_place_detached(
1309                // There's no nonce because the key is already one-use.
1310                &aes_gcm_siv::Nonce::default(),
1311                // And there's no associated data.
1312                &[],
1313                &mut ciphertext,
1314            )
1315            .expect("AES-GCM-SIV encryption should not fail with a just-computed key");
1316        // AES-GCM-SIV expects the authentication tag to be at the end of the ciphertext
1317        // when decrypting.
1318        ciphertext.extend_from_slice(&symmetric_authentication_tag);
1319        ciphertext
1320    };
1321
1322    // Group the destinations by name, and fetch identity keys once for each name. This optimizes
1323    // for the common case where all of a recipient's devices are included contiguously in the
1324    // destination list. (If the caller *doesn't* do this, that's on them; the message will still be
1325    // valid but some key material will be redundantly computed and encoded in the output.)
1326    let identity_keys_and_ranges: Vec<(IdentityKey, Range<usize>)> = {
1327        let mut identity_keys_and_ranges = vec![];
1328        for (_, mut next_group) in &destinations
1329            .iter()
1330            .enumerate()
1331            .chunk_by(|(_i, next)| next.name())
1332        {
1333            let (i, &destination) = next_group
1334                .next()
1335                .expect("at least one element in every group");
1336            // We can't put this before the call to `next()` because `count` consumes the rest of
1337            // the iterator.
1338            let count = 1 + next_group.count();
1339            let their_identity =
1340                identity_store
1341                    .get_identity(destination)
1342                    .await?
1343                    .ok_or_else(|| {
1344                        log::error!("missing identity key for {destination}");
1345                        // Returned as a SessionNotFound error because (a) we don't have an identity
1346                        // error that includes the address, and (b) re-establishing the session should
1347                        // re-fetch the identity.
1348                        SignalProtocolError::SessionNotFound(destination.clone())
1349                    })?;
1350            identity_keys_and_ranges.push((their_identity, i..i + count));
1351        }
1352        identity_keys_and_ranges
1353    };
1354
1355    // Next, fan out the work of generating the per-recipient to multiple cores, since we do two key
1356    // agreements per recipient (though not per device) and those are CPU-bound.
1357
1358    // I know this looks complicated enough to pull out into a separate function altogether, but it
1359    // also depends on a bunch of local state: our identity, E and E_pub, and M.
1360    let serialize_recipient_destinations_into = |serialized: &mut Vec<u8>,
1361                                                 destinations: &[&ProtocolAddress],
1362                                                 sessions: &[&SessionRecord],
1363                                                 their_identity: &IdentityKey|
1364     -> Result<()> {
1365        let their_service_id = ServiceId::parse_from_service_id_string(destinations[0].name())
1366            .ok_or_else(|| {
1367                SignalProtocolError::InvalidArgument(format!(
1368                    "multi-recipient sealed sender requires recipients' ServiceId (not {})",
1369                    destinations[0].name()
1370                ))
1371            })?;
1372
1373        serialized.extend_from_slice(&their_service_id.service_id_fixed_width_binary());
1374
1375        debug_assert_eq!(
1376            destinations.len(),
1377            sessions.len(),
1378            "should be sliced with the same range"
1379        );
1380        let mut destinations_and_sessions = destinations.iter().zip(sessions);
1381        while let Some((&destination, session)) = destinations_and_sessions.next() {
1382            let their_registration_id = session.remote_registration_id().map_err(|_| {
1383                SignalProtocolError::InvalidState(
1384                    "sealed_sender_multi_recipient_encrypt",
1385                    format!(
1386                        concat!(
1387                            "cannot get registration ID from session with {} ",
1388                            "(maybe it was recently archived)"
1389                        ),
1390                        destination
1391                    ),
1392                )
1393            })?;
1394            if their_registration_id & u32::from(VALID_REGISTRATION_ID_MASK)
1395                != their_registration_id
1396            {
1397                return Err(SignalProtocolError::InvalidRegistrationId(
1398                    destination.clone(),
1399                    their_registration_id,
1400                ));
1401            }
1402            let mut their_registration_id =
1403                u16::try_from(their_registration_id).expect("just checked range");
1404            if destinations_and_sessions.len() > 0 {
1405                their_registration_id |= 0x8000;
1406            }
1407
1408            let device_id = destination.device_id();
1409            serialized.push(device_id.into());
1410            serialized.extend_from_slice(&their_registration_id.to_be_bytes());
1411        }
1412
1413        let c_i = sealed_sender_v2::apply_agreement_xor(
1414            &e,
1415            their_identity.public_key(),
1416            Direction::Sending,
1417            &m,
1418        )?;
1419        serialized.extend_from_slice(&c_i);
1420
1421        let at_i = sealed_sender_v2::compute_authentication_tag(
1422            &our_identity,
1423            their_identity,
1424            Direction::Sending,
1425            e_pub,
1426            &c_i,
1427        )?;
1428        serialized.extend_from_slice(&at_i);
1429
1430        Ok(())
1431    };
1432
1433    let process_chunk =
1434        |serialized: &mut Vec<u8>, chunk: &[(IdentityKey, Range<usize>)]| -> Result<()> {
1435            for (their_identity, destination_range) in chunk {
1436                let these_destinations = &destinations[destination_range.clone()];
1437                let these_sessions = &destination_sessions[destination_range.clone()];
1438                serialize_recipient_destinations_into(
1439                    serialized,
1440                    these_destinations,
1441                    these_sessions,
1442                    their_identity,
1443                )?;
1444            }
1445            Ok(())
1446        };
1447
1448    let mut serialized: Vec<u8> = vec![SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION];
1449
1450    let count_of_recipients = identity_keys_and_ranges.len() + excluded_recipients.len();
1451    prost::encode_length_delimiter(count_of_recipients, &mut serialized)
1452        .expect("can always resize a Vec");
1453
1454    // Fan out to N threads, like Rayon would. But don't bother for less than 6 items.
1455    let parallelism = std::thread::available_parallelism()
1456        .map(usize::from)
1457        .unwrap_or(1);
1458    let chunk_size = std::cmp::max(6, identity_keys_and_ranges.len().div_ceil(parallelism));
1459
1460    if parallelism == 1 || chunk_size >= identity_keys_and_ranges.len() {
1461        process_chunk(&mut serialized, &identity_keys_and_ranges)?;
1462    } else {
1463        let mut chunks = identity_keys_and_ranges.chunks(chunk_size);
1464        // We'll process the first chunk on the current thread once we've spawned all the others.
1465        let first_chunk = chunks.next().expect("at least one chunk, tested above");
1466
1467        let mut all_outputs = Vec::new();
1468        all_outputs.resize_with(chunks.len(), || Ok(vec![]));
1469
1470        rayon::scope(|scope| -> Result<()> {
1471            let mut outputs = &mut all_outputs[..];
1472            for chunk in chunks {
1473                let (next_output, remaining_outputs) = outputs
1474                    .split_first_mut()
1475                    .expect("as many outputs as remaining chunks");
1476                scope.spawn(|_| {
1477                    let mut serialized = vec![];
1478                    *next_output = process_chunk(&mut serialized, chunk).map(|_| serialized);
1479                });
1480                outputs = remaining_outputs;
1481            }
1482
1483            process_chunk(&mut serialized, first_chunk)
1484        })?;
1485
1486        for output in all_outputs {
1487            serialized.extend(output?);
1488        }
1489    }
1490
1491    for excluded in excluded_recipients {
1492        serialized.extend_from_slice(&excluded.service_id_fixed_width_binary());
1493        serialized.push(0);
1494    }
1495
1496    serialized.extend_from_slice(e_pub.public_key_bytes());
1497    serialized.extend_from_slice(&ciphertext);
1498
1499    Ok(serialized)
1500}
1501
1502/// Represents a single recipient in an SSv2 SentMessage.
1503///
1504/// See [`SealedSenderV2SentMessage`].
1505pub struct SealedSenderV2SentMessageRecipient<'a> {
1506    /// The recipient's devices and their registration IDs. May be empty.
1507    pub devices: Vec<(DeviceId, u16)>,
1508    /// A concatenation of the `C_i` and `AT_i` SSv2 fields for this recipient, or an empty slice if
1509    /// the recipient has no devices.
1510    c_and_at: &'a [u8],
1511}
1512
1513/// A parsed representation of a Sealed Sender v2 SentMessage.
1514///
1515/// This only parses enough to fan out the message as a series of ReceivedMessages.
1516pub struct SealedSenderV2SentMessage<'a> {
1517    /// The full message, for calculating offsets.
1518    full_message: &'a [u8],
1519    /// The version byte at the head of the message.
1520    pub version: u8,
1521    /// The parsed list of recipients, grouped by ServiceId.
1522    ///
1523    /// The map is ordered by when a recipient first appears in the full message, even if they
1524    /// appear again later with more devices. This makes iteration over the full set of recipients
1525    /// deterministic.
1526    pub recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>>,
1527    /// A concatenation of the `e_pub` and `message` SSv2 fields for this recipient.
1528    shared_bytes: &'a [u8],
1529}
1530
1531impl<'a> SealedSenderV2SentMessage<'a> {
1532    /// Parses the message, or produces an error if the message is invalid.
1533    pub fn parse(data: &'a [u8]) -> Result<Self> {
1534        if data.is_empty() {
1535            return Err(SignalProtocolError::InvalidSealedSenderMessage(
1536                "Message was empty".to_owned(),
1537            ));
1538        }
1539
1540        let version = data[0];
1541        if !matches!(
1542            version,
1543            SEALED_SENDER_V2_UUID_FULL_VERSION | SEALED_SENDER_V2_SERVICE_ID_FULL_VERSION
1544        ) {
1545            return Err(SignalProtocolError::UnknownSealedSenderVersion(version));
1546        }
1547
1548        fn advance<'a, const N: usize>(buf: &mut &'a [u8]) -> Result<&'a [u8; N]> {
1549            let (prefix, remaining) = buf
1550                .split_first_chunk()
1551                .ok_or(SignalProtocolError::InvalidProtobufEncoding)?;
1552            *buf = remaining;
1553            Ok(prefix)
1554        }
1555        fn decode_varint(buf: &mut &[u8]) -> Result<u32> {
1556            let result: usize = prost::decode_length_delimiter(*buf)
1557                .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
1558            *buf = &buf[prost::length_delimiter_len(result)..];
1559            result
1560                .try_into()
1561                .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)
1562        }
1563
1564        let mut remaining = &data[1..];
1565        let recipient_count = decode_varint(&mut remaining)?
1566            .try_into()
1567            .unwrap_or(usize::MAX);
1568
1569        // Cap our preallocated capacity; anything higher than this is *probably* a mistake, but
1570        // could just be a very large message.
1571        // (Callers can of course refuse to process messages with too many recipients.)
1572        let mut recipients: IndexMap<ServiceId, SealedSenderV2SentMessageRecipient<'a>> =
1573            IndexMap::with_capacity(std::cmp::min(recipient_count as usize, 6000));
1574        for _ in 0..recipient_count {
1575            let service_id = if version == SEALED_SENDER_V2_UUID_FULL_VERSION {
1576                // The original version of SSv2 assumed ACIs here, and only encoded the raw UUID.
1577                ServiceId::from(Aci::from_uuid_bytes(*advance::<
1578                    { std::mem::size_of::<uuid::Bytes>() },
1579                >(&mut remaining)?))
1580            } else {
1581                ServiceId::parse_from_service_id_fixed_width_binary(advance::<
1582                    { std::mem::size_of::<ServiceIdFixedWidthBinaryBytes>() },
1583                >(
1584                    &mut remaining
1585                )?)
1586                .ok_or(SignalProtocolError::InvalidProtobufEncoding)?
1587            };
1588            let mut devices = Vec::new();
1589            loop {
1590                let device_id = advance::<1>(&mut remaining)?[0];
1591                if device_id == 0 {
1592                    if !devices.is_empty() {
1593                        return Err(SignalProtocolError::InvalidProtobufEncoding);
1594                    }
1595                    break;
1596                }
1597                let device_id = DeviceId::new(device_id)
1598                    .map_err(|_| SignalProtocolError::InvalidProtobufEncoding)?;
1599                let registration_id_and_has_more =
1600                    u16::from_be_bytes(*advance::<2>(&mut remaining)?);
1601                devices.push((
1602                    device_id,
1603                    registration_id_and_has_more & VALID_REGISTRATION_ID_MASK,
1604                ));
1605                let has_more = (registration_id_and_has_more & 0x8000) != 0;
1606                if !has_more {
1607                    break;
1608                }
1609            }
1610
1611            let c_and_at: &[u8] = if devices.is_empty() {
1612                &[]
1613            } else {
1614                advance::<{ sealed_sender_v2::MESSAGE_KEY_LEN + sealed_sender_v2::AUTH_TAG_LEN }>(
1615                    &mut remaining,
1616                )?
1617            };
1618
1619            match recipients.entry(service_id) {
1620                indexmap::map::Entry::Occupied(mut existing) => {
1621                    if existing.get().devices.is_empty() || devices.is_empty() {
1622                        return Err(SignalProtocolError::InvalidSealedSenderMessage(
1623                            "recipient redundantly encoded as empty".to_owned(),
1624                        ));
1625                    }
1626                    // We don't unique the recipient devices; the server is going to check this
1627                    // against the account's canonical list of devices anyway.
1628                    existing.get_mut().devices.extend(devices);
1629                    // Note that we don't check that c_and_at matches. Any case where it doesn't
1630                    // match would already result in a decryption error for at least one of the
1631                    // recipient's devices, though.
1632                }
1633                indexmap::map::Entry::Vacant(entry) => {
1634                    entry.insert(SealedSenderV2SentMessageRecipient { devices, c_and_at });
1635                }
1636            };
1637        }
1638
1639        if remaining.len() < sealed_sender_v2::PUBLIC_KEY_LEN {
1640            return Err(SignalProtocolError::InvalidProtobufEncoding);
1641        }
1642
1643        Ok(Self {
1644            full_message: data,
1645            version,
1646            recipients,
1647            shared_bytes: remaining,
1648        })
1649    }
1650
1651    /// Returns a slice of slices that, when concatenated, form the ReceivedMessage appropriate for
1652    /// `recipient`.
1653    ///
1654    /// If `recipient` is not one of the recipients in `self`, the resulting message will not be
1655    /// decryptable.
1656    #[inline]
1657    pub fn received_message_parts_for_recipient(
1658        &self,
1659        recipient: &SealedSenderV2SentMessageRecipient<'a>,
1660    ) -> impl AsRef<[&[u8]]> {
1661        // Why not use `IntoIterator<Item = &[u8]>` as the result? Because the `concat` method on
1662        // slices is more efficient when the caller just wants a `Vec<u8>`.
1663        // Why use SEALED_SENDER_V2_UUID_FULL_VERSION as the version? Because the ReceivedMessage
1664        // format hasn't changed since then.
1665        [
1666            &[SEALED_SENDER_V2_UUID_FULL_VERSION],
1667            recipient.c_and_at,
1668            self.shared_bytes,
1669        ]
1670    }
1671
1672    /// Returns the offset of `addr` within `self.full_message`, or `None` if `addr` does not lie
1673    /// within `self.full_message`.
1674    ///
1675    /// A stripped-down version of [a dormant Rust RFC][subslice-offset].
1676    ///
1677    /// [subslice-offset]: https://github.com/rust-lang/rfcs/pull/2796
1678    #[inline]
1679    fn offset_within_full_message(&self, addr: *const u8) -> Option<usize> {
1680        // Arithmetic on addresses is valid for offsets within a byte array.
1681        // If addr < start, we'll wrap around to a very large value, which will be out of range just
1682        // like if addr > end.
1683        let offset = (addr as usize).wrapping_sub(self.full_message.as_ptr() as usize);
1684        // We *do* want to allow the "one-past-the-end" offset here, because the offset might be
1685        // used as part of a range (e.g. 0..end).
1686        if offset <= self.full_message.len() {
1687            debug_assert!(
1688                offset == self.full_message.len() || std::ptr::eq(&self.full_message[offset], addr)
1689            );
1690            Some(offset)
1691        } else {
1692            None
1693        }
1694    }
1695
1696    /// Returns the range within the full message of `recipient`'s user-specific key material.
1697    ///
1698    /// This can be concatenated as `[version, recipient_key_material, shared_bytes]` to produce a
1699    /// valid SSv2 ReceivedMessage, the payload delivered to recipients.
1700    ///
1701    /// **Panics** if `recipient` is not one of the recipients in `self`.
1702    pub fn range_for_recipient_key_material(
1703        &self,
1704        recipient: &SealedSenderV2SentMessageRecipient<'a>,
1705    ) -> Range<usize> {
1706        if recipient.c_and_at.is_empty() {
1707            return 0..0;
1708        }
1709        let offset = self
1710            .offset_within_full_message(recipient.c_and_at.as_ptr())
1711            .expect("'recipient' is not one of the recipients in this SealedSenderV2SentMessage");
1712        let end_offset = offset.saturating_add(recipient.c_and_at.len());
1713        assert!(
1714            end_offset <= self.full_message.len(),
1715            "invalid 'recipient' passed to range_for_recipient_key_material"
1716        );
1717        offset..end_offset
1718    }
1719
1720    /// Returns the offset of the shared bytes within the full message.
1721    ///
1722    /// This can be concatenated as `[version, recipient_key_material, shared_bytes]` to produce a
1723    /// valid SSv2 ReceivedMessage, the payload delivered to recipients.
1724    pub fn offset_of_shared_bytes(&self) -> usize {
1725        debug_assert_eq!(
1726            self.full_message.as_ptr_range().end,
1727            self.shared_bytes.as_ptr_range().end,
1728            "SealedSenderV2SentMessage parsed incorrectly"
1729        );
1730        self.offset_within_full_message(self.shared_bytes.as_ptr())
1731            .expect("constructed correctly")
1732    }
1733}
1734
1735/// Decrypt the payload of a sealed-sender message in either the v1 or v2 format.
1736///
1737/// [`sealed_sender_decrypt`] consumes the output of this method to validate the sender's identity
1738/// before decrypting the underlying message.
1739pub async fn sealed_sender_decrypt_to_usmc(
1740    ciphertext: &[u8],
1741    identity_store: &dyn IdentityKeyStore,
1742) -> Result<UnidentifiedSenderMessageContent> {
1743    let our_identity = identity_store.get_identity_key_pair().await?;
1744
1745    match UnidentifiedSenderMessage::deserialize(ciphertext)? {
1746        UnidentifiedSenderMessage::V1 {
1747            ephemeral_public,
1748            encrypted_static,
1749            encrypted_message,
1750        } => {
1751            let eph_keys = sealed_sender_v1::EphemeralKeys::calculate(
1752                &our_identity.into(),
1753                &ephemeral_public,
1754                Direction::Receiving,
1755            )?;
1756
1757            let message_key_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1758                &encrypted_static,
1759                &eph_keys.cipher_key,
1760                &eph_keys.mac_key,
1761            ) {
1762                Ok(plaintext) => plaintext,
1763                Err(crypto::DecryptionError::BadKeyOrIv) => {
1764                    unreachable!("just derived these keys; they should be valid");
1765                }
1766                Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1767                    log::error!("failed to decrypt sealed sender v1 message key: {msg}");
1768                    return Err(SignalProtocolError::InvalidSealedSenderMessage(
1769                        "failed to decrypt sealed sender v1 message key".to_owned(),
1770                    ));
1771                }
1772            };
1773
1774            let static_key = PublicKey::try_from(&message_key_bytes[..])?;
1775
1776            let static_keys = sealed_sender_v1::StaticKeys::calculate(
1777                &our_identity,
1778                &static_key,
1779                &eph_keys.chain_key,
1780                &encrypted_static,
1781            )?;
1782
1783            let message_bytes = match crypto::aes256_ctr_hmacsha256_decrypt(
1784                &encrypted_message,
1785                &static_keys.cipher_key,
1786                &static_keys.mac_key,
1787            ) {
1788                Ok(plaintext) => plaintext,
1789                Err(crypto::DecryptionError::BadKeyOrIv) => {
1790                    unreachable!("just derived these keys; they should be valid");
1791                }
1792                Err(crypto::DecryptionError::BadCiphertext(msg)) => {
1793                    log::error!("failed to decrypt sealed sender v1 message contents: {msg}");
1794                    return Err(SignalProtocolError::InvalidSealedSenderMessage(
1795                        "failed to decrypt sealed sender v1 message contents".to_owned(),
1796                    ));
1797                }
1798            };
1799
1800            let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1801
1802            if !bool::from(message_key_bytes.ct_eq(&usmc.sender()?.key()?.serialize())) {
1803                return Err(SignalProtocolError::InvalidSealedSenderMessage(
1804                    "sender certificate key does not match message key".to_string(),
1805                ));
1806            }
1807
1808            Ok(usmc)
1809        }
1810        UnidentifiedSenderMessage::V2 {
1811            ephemeral_public,
1812            encrypted_message_key,
1813            authentication_tag,
1814            encrypted_message,
1815        } => {
1816            let m = sealed_sender_v2::apply_agreement_xor(
1817                &our_identity.into(),
1818                &ephemeral_public,
1819                Direction::Receiving,
1820                encrypted_message_key,
1821            )?;
1822
1823            let keys = sealed_sender_v2::DerivedKeys::new(&m);
1824            if !bool::from(keys.derive_e().public_key.ct_eq(&ephemeral_public)) {
1825                return Err(SignalProtocolError::InvalidSealedSenderMessage(
1826                    "derived ephemeral key did not match key provided in message".to_string(),
1827                ));
1828            }
1829
1830            let mut message_bytes = Vec::from(encrypted_message);
1831            Aes256GcmSiv::new(&keys.derive_k().into())
1832                .decrypt_in_place(
1833                    // There's no nonce because the key is already one-use.
1834                    &aes_gcm_siv::Nonce::default(),
1835                    // And there's no associated data.
1836                    &[],
1837                    &mut message_bytes,
1838                )
1839                .map_err(|err| {
1840                    SignalProtocolError::InvalidSealedSenderMessage(format!(
1841                        "failed to decrypt inner message: {err}"
1842                    ))
1843                })?;
1844
1845            let usmc = UnidentifiedSenderMessageContent::deserialize(&message_bytes)?;
1846
1847            let at = sealed_sender_v2::compute_authentication_tag(
1848                &our_identity,
1849                &usmc.sender()?.key()?.into(),
1850                Direction::Receiving,
1851                &ephemeral_public,
1852                encrypted_message_key,
1853            )?;
1854            if !bool::from(authentication_tag.ct_eq(&at)) {
1855                return Err(SignalProtocolError::InvalidSealedSenderMessage(
1856                    "sender certificate key does not match authentication tag".to_string(),
1857                ));
1858            }
1859
1860            Ok(usmc)
1861        }
1862    }
1863}
1864
1865#[derive(Debug)]
1866pub struct SealedSenderDecryptionResult {
1867    pub sender_uuid: String,
1868    pub sender_e164: Option<String>,
1869    pub device_id: DeviceId,
1870    pub message: Vec<u8>,
1871}
1872
1873impl SealedSenderDecryptionResult {
1874    pub fn sender_uuid(&self) -> Result<&str> {
1875        Ok(self.sender_uuid.as_ref())
1876    }
1877
1878    pub fn sender_e164(&self) -> Result<Option<&str>> {
1879        Ok(self.sender_e164.as_deref())
1880    }
1881
1882    pub fn device_id(&self) -> Result<DeviceId> {
1883        Ok(self.device_id)
1884    }
1885
1886    pub fn message(&self) -> Result<&[u8]> {
1887        Ok(self.message.as_ref())
1888    }
1889}
1890
1891/// Decrypt a Sealed Sender message `ciphertext` in either the v1 or v2 format, validate its sender
1892/// certificate, and then decrypt the inner message payload.
1893///
1894/// This method calls [`sealed_sender_decrypt_to_usmc`] to extract the sender information, including
1895/// the embedded [`SenderCertificate`]. The sender certificate (signed by the [`ServerCertificate`])
1896/// is then validated against the `trust_root` baked into the client to ensure that the sender's
1897/// identity was not forged.
1898#[expect(clippy::too_many_arguments)]
1899pub async fn sealed_sender_decrypt(
1900    ciphertext: &[u8],
1901    trust_root: &PublicKey,
1902    timestamp: Timestamp,
1903    local_e164: Option<String>,
1904    local_uuid: String,
1905    local_device_id: DeviceId,
1906    identity_store: &mut dyn IdentityKeyStore,
1907    session_store: &mut dyn SessionStore,
1908    pre_key_store: &mut dyn PreKeyStore,
1909    signed_pre_key_store: &dyn SignedPreKeyStore,
1910    kyber_pre_key_store: &mut dyn KyberPreKeyStore,
1911    use_pq_ratchet: ratchet::UsePQRatchet,
1912) -> Result<SealedSenderDecryptionResult> {
1913    let usmc = sealed_sender_decrypt_to_usmc(ciphertext, identity_store).await?;
1914
1915    if !usmc.sender()?.validate(trust_root, timestamp)? {
1916        return Err(SignalProtocolError::InvalidSealedSenderMessage(
1917            "trust root validation failed".to_string(),
1918        ));
1919    }
1920
1921    let is_local_uuid = local_uuid == usmc.sender()?.sender_uuid()?;
1922
1923    let is_local_e164 = match (local_e164, usmc.sender()?.sender_e164()?) {
1924        (Some(l), Some(s)) => l == s,
1925        (_, _) => false,
1926    };
1927
1928    if (is_local_e164 || is_local_uuid) && usmc.sender()?.sender_device_id()? == local_device_id {
1929        return Err(SignalProtocolError::SealedSenderSelfSend);
1930    }
1931
1932    let mut rng = rand::rngs::OsRng.unwrap_err();
1933
1934    let remote_address = ProtocolAddress::new(
1935        usmc.sender()?.sender_uuid()?.to_string(),
1936        usmc.sender()?.sender_device_id()?,
1937    );
1938
1939    let message = match usmc.msg_type()? {
1940        CiphertextMessageType::Whisper => {
1941            let ctext = SignalMessage::try_from(usmc.contents()?)?;
1942            session_cipher::message_decrypt_signal(
1943                &ctext,
1944                &remote_address,
1945                session_store,
1946                identity_store,
1947                &mut rng,
1948            )
1949            .await?
1950        }
1951        CiphertextMessageType::PreKey => {
1952            let ctext = PreKeySignalMessage::try_from(usmc.contents()?)?;
1953            session_cipher::message_decrypt_prekey(
1954                &ctext,
1955                &remote_address,
1956                session_store,
1957                identity_store,
1958                pre_key_store,
1959                signed_pre_key_store,
1960                kyber_pre_key_store,
1961                &mut rng,
1962                use_pq_ratchet,
1963            )
1964            .await?
1965        }
1966        msg_type => {
1967            return Err(SignalProtocolError::InvalidMessage(
1968                msg_type,
1969                "unexpected message type for sealed_sender_decrypt",
1970            ));
1971        }
1972    };
1973
1974    Ok(SealedSenderDecryptionResult {
1975        sender_uuid: usmc.sender()?.sender_uuid()?.to_string(),
1976        sender_e164: usmc.sender()?.sender_e164()?.map(|s| s.to_string()),
1977        device_id: usmc.sender()?.sender_device_id()?,
1978        message,
1979    })
1980}
1981
1982#[test]
1983fn test_lossless_round_trip() -> Result<()> {
1984    let trust_root = PrivateKey::deserialize(&[0u8; 32])?;
1985
1986    // To test a hypothetical addition of a new field:
1987    //
1988    // Step 1: temporarily add a new field to the .proto.
1989    //
1990    //    --- a/rust/protocol/src/proto/sealed_sender.proto
1991    //    +++ b/rust/protocol/src/proto/sealed_sender.proto
1992    //    @@ -26,3 +26,4 @@ message SenderCertificate {
1993    //             optional bytes             identityKey   = 4;
1994    //             optional ServerCertificate signer        = 5;
1995    //    +        optional string someFakeField = 999;
1996    //     }
1997    //
1998    // Step 2: Add `some_fake_field: None` to the above construction of
1999    // proto::sealed_sender::sender_certificate::Certificate.
2000    //
2001    // Step 3: Serialize and print out the new fixture data (uncomment the following)
2002    //
2003    // let mut rng = rand::rngs::OsRng;
2004    // let server_key = KeyPair::generate(&mut rng);
2005    // let sender_key = KeyPair::generate(&mut rng);
2006    //
2007    // let server_cert =
2008    //     ServerCertificate::new(1, server_key.public_key, &trust_root, &mut rng)?;
2009    //
2010    // let sender_cert = proto::sealed_sender::sender_certificate::Certificate {
2011    //     sender_uuid: Some("aaaaaaaa-7000-11eb-b32a-33b8a8a487a6".to_string()),
2012    //     sender_e164: None,
2013    //     sender_device: Some(1),
2014    //     expires: Some(31337),
2015    //     identity_key: Some(sender_key.public_key.serialize().to_vec()),
2016    //     signer: Some(server_cert.to_protobuf()?),
2017    //     some_fake_field: Some("crashing right down".to_string()),
2018    // };
2019    //
2020    // eprintln!("<SNIP>");
2021    // let serialized_certificate_data = sender_cert.encode_to_vec();
2022    // let certificate_data_encoded = hex::encode(&serialized_certificate_data);
2023    // eprintln!("let certificate_data_encoded = \"{}\";", certificate_data_encoded);
2024    //
2025    // let certificate_signature = server_key.calculate_signature(&serialized_certificate_data, &mut rng)?;
2026    // let certificate_signature_encoded = hex::encode(certificate_signature);
2027    // eprintln!("let certificate_signature_encoded = \"{}\";", certificate_signature_encoded);
2028
2029    // Step 4: update the following *_encoded fixture data with the new values from above.
2030    let certificate_data_encoded = "100119697a0000000000002221056c9d1f8deb82b9a898f9c277a1b74989ec009afb5c0acb5e8e69e3d5ca29d6322a690a2508011221053b03ca070e6f6b2f271d32f27321689cdf4e59b106c10b58fbe15063ed868a5a124024bc92954e52ad1a105b5bda85c9db410dcfeb42a671b45a523b3a46e9594a8bde0efc671d8e8e046b32c67f59b80a46ffdf24071850779bc21325107902af89322461616161616161612d373030302d313165622d623332612d333362386138613438376136ba3e136372617368696e6720726967687420646f776e";
2031    let certificate_signature_encoded = "a22d8f86f5d00794f319add821e342c6ffffb6b34f741e569f8b321ab0255f2d1757ecf648e53a3602cae8f09b3fc80dcf27534d67efd272b6739afc31f75c8c";
2032
2033    // The rest of the test should be stable.
2034    let certificate_data = hex::decode(certificate_data_encoded).expect("valid hex");
2035    let certificate_signature = hex::decode(certificate_signature_encoded).expect("valid hex");
2036
2037    let sender_certificate_data = proto::sealed_sender::SenderCertificate {
2038        certificate: Some(certificate_data),
2039        signature: Some(certificate_signature),
2040    };
2041
2042    let sender_certificate =
2043        SenderCertificate::deserialize(&sender_certificate_data.encode_to_vec())?;
2044    assert!(sender_certificate.validate(
2045        &trust_root.public_key()?,
2046        Timestamp::from_epoch_millis(31336)
2047    )?);
2048    Ok(())
2049}