**Agent ID:** SA-021 **Date:** 2025-12-30 **Status:** Completed **Grade:** B
Mission
Trace E2EE/Noise protocol key negotiation for audio encryption in the Facebook iOS application.
**Target Binary:** `./analysis/facebook/345.0/Facebook.app/Frameworks/FBSharedFramework.framework/FBSharedFramework`
**Additional Target:** `FBMessagingFramework.framework` (RTC stack)
Executive Summary
The Facebook iOS app implements a multi-layer encryption architecture for real-time audio/video calls:
- undefined
The Noise protocol implementation appears to be in the native C++ layer (referenced as `__RS*` structures), not exposed in Objective-C headers.
Key Findings
1. E2EE Call Model Properties
Found in `FBWebRTCCallModel` (`FBMessagingFramework.framework`):
| Property | Type | Purpose |
|---|---|---|
| `_isEndToEndEncrypted` | BOOL | Indicates if call has E2EE active |
| `_isE2EEncryptionMandated` | BOOL | Forces E2EE requirement for call |
**Methods that set E2EE state:**
-[FBWebRTCEngine startIncomingConferenceCall:callId:ringType:peerUserIds:callerUserId:dataMessages:stateSyncInitialData:userProfiles:isE2eeMandatedCall:collisionContextData:onSuccess:onError:]
-[FBWebRTCEngine startConferenceCallWithName:localCallId:ringingUsers:initialMediaState:callTrigger:includeRingeesInPeerList:dataMessages:stateSyncInitialData:collisionKey:analyticsExtra:callConfiguration:isE2EEMandated:error:]
2. E2EE Model Update Flow
The E2EE state is propagated through the call stack via callbacks:
[Native C++ Layer]
|
v
[FBWebRTCEngine onCryptoE2eeModelUpdated:]
|
v
[FBWebRTCEngineListenerAnnouncer callUpdatedE2eeModel:]
|
v
[Multiple listeners implement callUpdatedE2eeModel:]
- FBFacecastWithGuestFBWebRTCEngine
- FBVideoBroadcastWebRTCSession
- FBWebRTCCallStateLogWriter
- FBWebRTCRingtoneManager
3. Crypto Proxy Architecture
The `RSCallClientDelegate` protocol exposes a crypto proxy:
@protocol RSCallClientDelegate <NSObject>
-[RSCallClientDelegate rsCallClientGetCryptoProxy];
// ... other media proxies
@end
@interface RIBRTCCallClient : NSObject <RSCallClientDelegate>
-[RIBRTCCallClient rsCallClientGetCryptoProxy];
@end
This crypto proxy is the bridge to the native encryption layer but its implementation is in C++ (`^{__RS*}` pointer types).
4. DTLS Configuration
DTLS (Datagram Transport Layer Security) is configurable via `FBWebRTCCallConfig`:
-[FBWebRTCCallConfig setNetworkingConfigShouldOfferDtls:]
DTLS handles the transport-layer encryption and certificate exchange for WebRTC connections.
5. Media Encryption Keys
Found in `MNSecureOutgoingAttachmentContent`:
| Property | Type | Purpose |
|---|---|---|
| `_audio_audioEncryptionKey` | NSData | Audio attachment encryption key |
| `_video_videoEncryptionKey` | NSData | Video attachment encryption key |
| `_images_encryptionKey` | NSData | Image attachment encryption key |
**Factory Methods:**
+[MNSecureOutgoingAttachmentContent audioWithAudioEncryptionKey:audio:]
+[MNSecureOutgoingAttachmentContent videoWithVideoEncryptionKey:video:]
+[MNSecureOutgoingAttachmentContent imagesWithEncryptionKey:photos:]
6. Native RTC Infrastructure
The RTC stack uses native C++ classes exposed via opaque pointers:
| Objective-C Property | C++ Type | Purpose |
|---|---|---|
| `_nativeEngine` | `shared_ptr | Native WebRTC engine |
| `_nativeCall` | `weak_ptr | Native conference call |
| `_call` | `^{__RSCall}` | RS call structure |
| `_callApi` | `^{__RSCallApi}` | RS call API |
| `_rsCallManager` | `^{__RSCallManager}` | RS call manager |
| `_huddleApi` | `^{__RSHuddleApi}` | Huddle API |
| `_audioProxy` | `^{__RSAudioProxy}` | Audio proxy |
7. Signaling Transport
Call signaling uses MQTT through:
@interface RIBRSSignaling : NSObject <RIBMQTTNotificationListener>
^{__RSSignalingTransportProxy} _signalingTransport;
^{__RSSignalingTransportSink} _transportSink;
@end
@interface RIBMQTTChannel : NSObject <RIBRSSignalingDelegate>
^{__RTChannel} _rtChannel;
^{_RTMQTTBridge} _mqttBridge;
@end
8. Connection to SA-006 Findings
From SA-006 Key Derivation report, the encryption uses:
- undefined
**Key Derivation Flow:**
[Session Master Key]
|
v
[walibra_hkdf_info (HKDF)]
|
v
[Frame-specific Key]
|
v
[AES-256-GCM Encrypt/Decrypt]
Noise Protocol Analysis
Expectation vs Reality
**Expected:** Explicit Noise protocol handshake classes (e.g., `NoiseHandshake`, `NoiseSession`, `NoiseCipherState`)
**Found:** The Noise protocol implementation appears to be:
- undefined
The "Noise" references found in class dump (`FBCrowdNoise*`) are unrelated - they are UI effects for live streaming audience reactions, not cryptographic protocols.
Evidence of Noise Protocol
Indirect evidence suggests Noise protocol usage:
- undefined
Key Negotiation Sequence (Inferred)
Based on class analysis:
1. Call Initiation
[FBWebRTCEngine startConferenceCallWithName:... isE2EEMandated:]
2. MQTT Signaling
[RIBRSSignaling handleNotificationForTopic:andData:andSource:]
3. DTLS Handshake (Transport Layer)
[FBWebRTCCallConfig setNetworkingConfigShouldOfferDtls:YES]
4. Crypto Proxy Setup
[RIBRTCCallClient rsCallClientGetCryptoProxy]
5. E2EE Session Established
[FBWebRTCEngine onCryptoE2eeModelUpdated:]
6. Frame Encryption Active
[walibra_hkdf_info + AES-256-GCM per frame]
7. E2EE State Broadcast
[callUpdatedE2eeModel:] -> all listeners
Session Key Lifecycle
| Phase | Description |
|---|---|
| **Negotiation** | Key exchange via native crypto proxy (Noise handshake in C++) |
| **Establishment** | `onCryptoE2eeModelUpdated:` callback with session parameters |
| **Active** | Per-frame key derivation via HKDF |
| **Rotation** | Implied by Noise protocol ratcheting (not visible at ObjC level) |
| **Termination** | Call end clears session keys |
SRTP Analysis
**Finding:** No explicit SRTP classes found in Objective-C layer.
SRTP (Secure Real-time Transport Protocol) is likely:
- undefined
DTLS Analysis
DTLS integration confirmed via:
- undefined
DTLS handles:
- undefined
Connection to audioEncryptionKey
The `audioEncryptionKey` in `MNSecureOutgoingAttachmentContent` is used for:
- undefined
Real-time call audio encryption:
E2EE Session Key -> HKDF Expansion -> Per-Frame Key -> AES-256-GCM
Attachment audio encryption:
Generated audioEncryptionKey -> AES encryption of audio blob
Critical Blockers
- undefined
Evidence Quality
| Criterion | Score | Notes |
|---|---|---|
| E2EE model identification | 9/10 | Clear Objective-C properties found |
| Key exchange mechanism | 5/10 | Inferred from structure, not visible |
| DTLS integration | 8/10 | Configuration methods found |
| SRTP implementation | 3/10 | Assumed, not visible in ObjC |
| Noise protocol | 4/10 | Indirect evidence only |
| Session key lifecycle | 6/10 | Callbacks identified |
Technical Artifacts
Key Classes
| Class | Framework | Purpose |
|---|---|---|
| `FBWebRTCEngine` | FBMessagingFramework | Main WebRTC engine wrapper |
| `FBWebRTCCallModel` | FBMessagingFramework | Call state including E2EE flags |
| `FBWebRTCMultiwayCall` | FBMessagingFramework | Conference call implementation |
| `RIBRTCEngine` | FBMessagingFramework | RIB layer RTC engine |
| `RIBRTCCallClient` | FBMessagingFramework | Call client with crypto proxy |
| `RIBRSSignaling` | FBMessagingFramework | MQTT-based signaling |
| `MNSecureOutgoingAttachmentContent` | FBSharedFramework | Encrypted attachment wrapper |
Key Methods
| Method | Purpose |
|---|---|
| `onCryptoE2eeModelUpdated:` | Native callback for E2EE state change |
| `callUpdatedE2eeModel:` | Listener notification for E2EE |
| `rsCallClientGetCryptoProxy` | Access to native crypto proxy |
| `setNetworkingConfigShouldOfferDtls:` | DTLS configuration |
| `audioWithAudioEncryptionKey:audio:` | Create encrypted audio attachment |
Recommendations for Further Investigation
- undefined
Impact on H3 Decoding
**Contribution to H3 Investigation:** Moderate
This analysis confirms:
- undefined
**Blockers for audio decryption:**
- undefined
*SA-021 E2EE/Noise Protocol Analysis - Generated 2025-12-30*