0
0
mirror of https://github.com/signalapp/libsignal.git synced 2024-09-19 19:42:19 +02:00

protocol: Remove legacy SSv2 receive support

This commit is contained in:
Jordan Rose 2024-07-30 12:44:45 -07:00
parent 192fbbd2a9
commit 2dd3896bba
3 changed files with 3 additions and 177 deletions

View File

@ -68,8 +68,7 @@ pub use ratchet::{
};
pub use sealed_sender::{
sealed_sender_decrypt, sealed_sender_decrypt_to_usmc, sealed_sender_encrypt,
sealed_sender_encrypt_from_usmc, sealed_sender_multi_recipient_encrypt,
sealed_sender_multi_recipient_encrypt_using_legacy_ephemeral_key_derivation, ContentHint,
sealed_sender_encrypt_from_usmc, sealed_sender_multi_recipient_encrypt, ContentHint,
SealedSenderDecryptionResult, SealedSenderV2SentMessage, SealedSenderV2SentMessageRecipient,
SenderCertificate, ServerCertificate, UnidentifiedSenderMessageContent,
};

View File

@ -15,7 +15,6 @@ use crate::{crypto, curve, proto, session_cipher};
use aes_gcm_siv::aead::generic_array::typenum::Unsigned;
use aes_gcm_siv::{AeadInPlace, Aes256GcmSiv, KeyInit};
use arrayref::array_ref;
use curve25519_dalek::scalar::Scalar;
use indexmap::IndexMap;
use itertools::Itertools;
use prost::Message;
@ -916,7 +915,6 @@ mod sealed_sender_v2 {
// Static byte strings used as part of a MAC in HKDF.
const LABEL_R: &[u8] = b"Sealed Sender v2: r (2023-08)";
const LABEL_R_LEGACY: &[u8] = b"Sealed Sender v2: r";
const LABEL_K: &[u8] = b"Sealed Sender v2: K";
const LABEL_DH: &[u8] = b"Sealed Sender v2: DH";
const LABEL_DH_S: &[u8] = b"Sealed Sender v2: DH-sender";
@ -926,9 +924,6 @@ mod sealed_sender_v2 {
<Aes256GcmSiv as aes_gcm_siv::aead::KeySizeUser>::KeySize::USIZE;
pub const AUTH_TAG_LEN: usize = 16;
// Change this to false after all clients have receive support.
pub const USE_LEGACY_EPHEMERAL_KEY_DERIVATION_FOR_ENCRYPT: bool = false;
/// An asymmetric and a symmetric cipher key.
pub(super) struct DerivedKeys {
kdf: hkdf::Hkdf<sha2::Sha256>,
@ -952,17 +947,6 @@ mod sealed_sender_v2 {
KeyPair::try_from(e).expect("can derive public key")
}
/// Derive the ephemeral asymmetric keys using the legacy implementation.
pub(super) fn derive_e_legacy(&self) -> KeyPair {
let mut r = [0; 64];
self.kdf
.expand(LABEL_R_LEGACY, &mut r)
.expect("valid output length");
let e_raw = Scalar::from_bytes_mod_order_wide(&r);
let e = PrivateKey::try_from(&e_raw.as_bytes()[..]).expect("valid PrivateKey");
KeyPair::try_from(e).expect("can derive public key")
}
/// Derive the symmetric cipher key.
pub(super) fn derive_k(&self) -> [u8; CIPHER_KEY_LEN] {
let mut k = [0; CIPHER_KEY_LEN];
@ -1277,34 +1261,6 @@ where
usmc,
identity_store,
rng,
sealed_sender_v2::USE_LEGACY_EPHEMERAL_KEY_DERIVATION_FOR_ENCRYPT,
)
.await
}
/// For testing only.
pub async fn sealed_sender_multi_recipient_encrypt_using_legacy_ephemeral_key_derivation<
R: Rng + CryptoRng,
X: IntoIterator<Item = ServiceId>,
>(
destinations: &[&ProtocolAddress],
destination_sessions: &[&SessionRecord],
excluded_recipients: X,
usmc: &UnidentifiedSenderMessageContent,
identity_store: &dyn IdentityKeyStore,
rng: &mut R,
) -> Result<Vec<u8>>
where
X::IntoIter: ExactSizeIterator,
{
sealed_sender_multi_recipient_encrypt_impl(
destinations,
destination_sessions,
excluded_recipients,
usmc,
identity_store,
rng,
false,
)
.await
}
@ -1319,7 +1275,6 @@ async fn sealed_sender_multi_recipient_encrypt_impl<
usmc: &UnidentifiedSenderMessageContent,
identity_store: &dyn IdentityKeyStore,
rng: &mut R,
should_use_legacy_ephemeral_key_derivation: bool,
) -> Result<Vec<u8>>
where
X::IntoIter: ExactSizeIterator,
@ -1335,11 +1290,7 @@ where
let m: [u8; sealed_sender_v2::MESSAGE_KEY_LEN] = rng.gen();
let keys = sealed_sender_v2::DerivedKeys::new(&m);
let e = if should_use_legacy_ephemeral_key_derivation {
keys.derive_e_legacy()
} else {
keys.derive_e()
};
let e = keys.derive_e();
let e_pub = &e.public_key;
// Encrypt the shared ciphertext using AES-GCM-SIV.
@ -1885,18 +1836,7 @@ pub async fn sealed_sender_decrypt_to_usmc(
)?;
let keys = sealed_sender_v2::DerivedKeys::new(&m);
// It is okay that this is not constant time; the only information revealed is whether
// the sender is using the new or old derivation for the ephemeral key, combined with
// which key the receiver tried first.
let mut derive_first_key: fn(_) -> _ = sealed_sender_v2::DerivedKeys::derive_e;
let mut derive_second_key: fn(_) -> _ = sealed_sender_v2::DerivedKeys::derive_e_legacy;
if sealed_sender_v2::USE_LEGACY_EPHEMERAL_KEY_DERIVATION_FOR_ENCRYPT {
std::mem::swap(&mut derive_first_key, &mut derive_second_key);
}
if !bool::from(derive_first_key(&keys).public_key.ct_eq(&ephemeral_public))
&& !bool::from(derive_second_key(&keys).public_key.ct_eq(&ephemeral_public))
{
if !bool::from(keys.derive_e().public_key.ct_eq(&ephemeral_public)) {
return Err(SignalProtocolError::InvalidSealedSenderMessage(
"derived ephemeral key did not match key provided in message".to_string(),
));

View File

@ -661,119 +661,6 @@ fn test_sealed_sender_multi_recipient() -> Result<(), SignalProtocolError> {
.expect("sync")
}
#[test]
fn test_sealed_sender_multi_recipient_legacy_derivation() -> Result<(), SignalProtocolError> {
async {
let mut rng = OsRng;
let alice_device_id: DeviceId = 23.into();
let bob_device_id: DeviceId = 42.into();
let alice_e164 = "+14151111111".to_owned();
let bob_e164 = "+14151114444".to_owned();
let alice_uuid = "9d0652a3-dcc3-4d11-975f-74d61598733f".to_string();
let bob_uuid = "796abedb-ca4e-4f18-8803-1fde5b921f9f".to_string();
let bob_uuid_address = ProtocolAddress::new(bob_uuid.clone(), bob_device_id);
let mut alice_store = support::test_in_memory_protocol_store()?;
let mut bob_store = support::test_in_memory_protocol_store()?;
let alice_pubkey = *alice_store.get_identity_key_pair().await?.public_key();
let bob_pre_key_bundle = create_pre_key_bundle(&mut bob_store, &mut rng).await?;
process_prekey_bundle(
&bob_uuid_address,
&mut alice_store.session_store,
&mut alice_store.identity_store,
&bob_pre_key_bundle,
SystemTime::now(),
&mut rng,
)
.await?;
let trust_root = KeyPair::generate(&mut rng);
let server_key = KeyPair::generate(&mut rng);
let server_cert =
ServerCertificate::new(1, server_key.public_key, &trust_root.private_key, &mut rng)?;
let expires = Timestamp::from_epoch_millis(1605722925);
let sender_cert = SenderCertificate::new(
alice_uuid.clone(),
Some(alice_e164.clone()),
alice_pubkey,
alice_device_id,
expires,
server_cert,
&server_key.private_key,
&mut rng,
)?;
let alice_ptext = vec![1, 2, 3, 23, 99];
let alice_message = message_encrypt(
&alice_ptext,
&bob_uuid_address,
&mut alice_store.session_store,
&mut alice_store.identity_store,
SystemTime::now(),
)
.await?;
let alice_usmc = UnidentifiedSenderMessageContent::new(
alice_message.message_type(),
sender_cert.clone(),
alice_message.serialize().to_vec(),
ContentHint::Default,
None,
)?;
let recipients = [&bob_uuid_address];
let alice_ctext =
sealed_sender_multi_recipient_encrypt_using_legacy_ephemeral_key_derivation(
&recipients,
&alice_store
.session_store
.load_existing_sessions(&recipients)?,
[],
&alice_usmc,
&alice_store.identity_store,
&mut rng,
)
.await?;
let (recipient_addr, bob_ctext) = extract_single_ssv2_received_message(&alice_ctext);
assert_eq!(recipient_addr.service_id_string(), bob_uuid);
let bob_ptext = sealed_sender_decrypt(
&bob_ctext,
&trust_root.public_key,
expires.sub_millis(1),
Some(bob_e164.clone()),
bob_uuid.clone(),
bob_device_id,
&mut bob_store.identity_store,
&mut bob_store.session_store,
&mut bob_store.pre_key_store,
&bob_store.signed_pre_key_store,
&mut bob_store.kyber_pre_key_store,
)
.await?;
assert_eq!(bob_ptext.message, alice_ptext);
assert_eq!(bob_ptext.sender_uuid, alice_uuid);
assert_eq!(bob_ptext.sender_e164, Some(alice_e164));
assert_eq!(bob_ptext.device_id, alice_device_id);
Ok(())
}
.now_or_never()
.expect("sync")
}
#[test]
fn test_sealed_sender_multi_recipient_encrypt_with_archived_session(
) -> Result<(), SignalProtocolError> {