Skip to main content

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