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