Port 5/SECURE-TRANSPORT to vac research (#569)

* feat(53,54/X3DH): port 5/secure-transport to vac research

* fix: x3dh case

* fix: split spec further, and add to index

* feat: add status-1to1-chat spec

* fix: fmt

* fix: s/protobuf/reference wire format/g

* fix: add additional steps of key exchange flow

* fix(53/WAKU2-X3DH): address comments

* fix(53/WAKU2-X3DH): change background to motivation

* fix(54/WAKU2-X3DH-SESSIONS): address comments

* fix: refs

* fix(55/STATUS-1TO1-CHAT): refs

* fix: move specs to raw

* fix: convert to draft, add info about prekey bundle discovery
This commit is contained in:
Aaryamann Challani 2023-02-21 17:18:15 +05:30 committed by GitHub
parent 1e9e985d67
commit 7738ea0b0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 432 additions and 0 deletions

View File

@ -0,0 +1,251 @@
---
slug: 53
title: 53/WAKU2-X3DH
name: X3DH usage for Waku payload encryption
status: draft
category: Standards Track
tags: waku-application
editor: Aaryamann Challani <aaryamann@status.im>
contributors:
- Andrea Piana <andreap@status.im>
- Pedro Pombeiro <pedro@status.im>
- Corey Petty <corey@status.im>
- Oskar Thorén <oskar@status.im>
- Dean Eigenmann <dean@status.im>
---
# Abstract
This document describes a method that can be used to provide a secure channel between two peers, and thus provide confidentiality, integrity, authenticity and forward secrecy.
It is transport-agnostic and works over asynchronous networks.
It builds on the [X3DH](https://signal.org/docs/specifications/x3dh/) and [Double Ratchet](https://signal.org/docs/specifications/doubleratchet/) specifications, with some adaptations to operate in a decentralized environment.
# Motivation
Nodes on a network may want to communicate with each other in a secure manner, without other nodes network being able to read their messages.
# Specification
## Definitions
- **Perfect Forward Secrecy** is a feature of specific key-agreement protocols which provide assurances that session keys will not be compromised even if the private keys of the participants are compromised.
Specifically, past messages cannot be decrypted by a third-party who manages to get a hold of a private key.
- **Secret channel** describes a communication channel where a Double Ratchet algorithm is in use.
## Design Requirements
- **Confidentiality**: The adversary should not be able to learn what data is being exchanged between two Status clients.
- **Authenticity**: The adversary should not be able to cause either endpoint to accept data from any third party as though it came from the other endpoint.
- **Forward Secrecy**: The adversary should not be able to learn what data was exchanged between two clients if, at some later time, the adversary compromises one or both of the endpoints.
- **Integrity**: The adversary should not be able to cause either endpoint to accept data that has been tampered with.
All of these properties are ensured by the use of [Signal's Double Ratchet](https://signal.org/docs/specifications/doubleratchet/)
## Conventions
Types used in this specification are defined using the [Protobuf](https://developers.google.com/protocol-buffers/) wire format.
# Specification
## End-to-End Encryption
End-to-end encryption (E2EE) takes place between two clients.
The main cryptographic protocol is a Double Ratchet protocol, which is derived from the [Off-the-Record protocol](https://otr.cypherpunks.ca/Protocol-v3-4.1.1.html), using a different ratchet.
[The Waku v2 protocol](/spec/10/) subsequently encrypts the message payload, using symmetric key encryption.
Furthermore, the concept of prekeys (through the use of [X3DH](https://signal.org/docs/specifications/x3dh/)) is used to allow the protocol to operate in an asynchronous environment.
It is not necessary for two parties to be online at the same time to initiate an encrypted conversation.
## Cryptographic Protocols
This protocol uses the following cryptographic primitives:
- X3DH
- Elliptic curve Diffie-Hellman key exchange (secp256k1)
- KECCAK-256
- ECDSA
- ECIES
- Double Ratchet
- HMAC-SHA-256 as MAC
- Elliptic curve Diffie-Hellman key exchange (Curve25519)
- AES-256-CTR with HMAC-SHA-256 and IV derived alongside an encryption key
The node achieves key derivation using [HKDF](https://www.rfc-editor.org/rfc/rfc5869).
## Pre-keys
Every client SHOULD initially generate some key material which is stored locally:
- Identity keypair based on secp256k1 - `IK`
- A signed prekey based on secp256k1 - `SPK`
- A prekey signature - `Sig(IK, Encode(SPK))`
More details can be found in the `X3DH Prekey bundle creation` section of [2/ACCOUNT](https://specs.status.im/spec/2#x3dh-prekey-bundles).
Prekey bundles MAY be extracted from any peer's messages, or found via searching for their specific topic, `{IK}-contact-code`.
The following methods can be used to retrieve prekey bundles from a peer's messages:
- contact codes;
- public and one-to-one chats;
- QR codes;
- ENS record;
- Decentralized permanent storage (e.g. Swarm, IPFS).
- Waku
Waku SHOULD be used for retrieving prekey bundles.
Since bundles stored in QR codes or ENS records cannot be updated to delete already used keys, the bundle MAY be rotated every 24 hours, and distributed via Waku.
## Flow
The key exchange can be summarized as follows:
1. Initial key exchange: Two parties, Alice and Bob, exchange their prekey bundles, and derive a shared secret.
2. Double Ratchet: The two parties use the shared secret to derive a new encryption key for each message they send.
3. Chain key update: The two parties update their chain keys. The chain key is used to derive new encryption keys for future messages.
4. Message key derivation: The two parties derive a new message key from their chain key, and use it to encrypt a message.
### 1. Initial key exchange flow (X3DH)
[Section 3 of the X3DH protocol](https://signal.org/docs/specifications/x3dh/#sending-the-initial-message) describes the initial key exchange flow, with some additional context:
- The peers' identity keys `IK_A` and `IK_B` correspond to their public keys;
- Since it is not possible to guarantee that a prekey will be used only once in a decentralized world, the one-time prekey `OPK_B` is not used in this scenario;
- Nodes SHOULD not send Bundles to a centralized server, but instead provide them in a decentralized way as described in the [Pre-keys section](#pre-keys).
Alice retrieves Bob's prekey bundle, however it is not specific to Alice. It contains:
([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L12))
**Wire format:**
``` protobuf
// X3DH prekey bundle
message Bundle {
// Identity key 'IK_B'
bytes identity = 1;
// Signed prekey 'SPK_B' for each device, indexed by 'installation-id'
map<string,SignedPreKey> signed_pre_keys = 2;
// Prekey signature 'Sig(IK_B, Encode(SPK_B))'
bytes signature = 4;
// When the bundle was created locally
int64 timestamp = 5;
}
```
([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L5))
``` protobuf
message SignedPreKey {
bytes signed_pre_key = 1;
uint32 version = 2;
}
```
The `signature` is generated by sorting `installation-id` in lexicographical order, and concatenating the `signed-pre-key` and `version`:
`installation-id-1signed-pre-key1version1installation-id2signed-pre-key2-version-2`
### 2. Double Ratchet
Having established the initial shared secret `SK` through X3DH, it SHOULD be used to seed a Double Ratchet exchange between Alice and Bob.
Refer to the [Double Ratchet spec](https://signal.org/docs/specifications/doubleratchet/) for more details.
The initial message sent by Alice to Bob is sent as a top-level `ProtocolMessage` ([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L65)) containing a map of `DirectMessageProtocol` indexed by `installation-id` ([reference wire format](https://github.com/status-im/status-go/blob/1ac9dd974415c3f6dee95145b6644aeadf02f02c/services/shhext/chat/encryption.proto#L56)):
``` protobuf
message ProtocolMessage {
// The installation id of the sender
string installation_id = 2;
// A sequence of bundles
repeated Bundle bundles = 3;
// One to one message, encrypted, indexed by installation_id
map<string,DirectMessageProtocol> direct_message = 101;
// Public message, not encrypted
bytes public_message = 102;
}
```
``` protobuf
message EncryptedMessageProtocol {
X3DHHeader X3DH_header = 1;
DRHeader DR_header = 2;
DHHeader DH_header = 101;
// Encrypted payload
// if a bundle is available, contains payload encrypted with the Double Ratchet algorithm;
// otherwise, payload encrypted with output key of DH exchange (no Perfect Forward Secrecy).
bytes payload = 3;
}
```
Where:
- `X3DH_header`: the `X3DHHeader` field in `DirectMessageProtocol` contains:
([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L47))
``` protobuf
message X3DHHeader {
// Alice's ephemeral key `EK_A`
bytes key = 1;
// Bob's bundle signed prekey
bytes id = 4;
}
```
- `DR_header`: Double ratchet header ([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L31)). Used when Bob's public bundle is available:
``` protobuf
message DRHeader {
// Alice's current ratchet public key (as mentioned in [DR spec section 2.2](https://signal.org/docs/specifications/doubleratchet/#symmetric-key-ratchet))
bytes key = 1;
// number of the message in the sending chain
uint32 n = 2;
// length of the previous sending chain
uint32 pn = 3;
// Bob's bundle ID
bytes id = 4;
}
```
- `DH_header`: Diffie-Hellman header (used when Bob's bundle is not available):
([reference wire format](https://github.com/status-im/status-go/blob/a904d9325e76f18f54d59efc099b63293d3dcad3/services/shhext/chat/encryption.proto#L42))
``` protobuf
message DHHeader {
// Alice's compressed ephemeral public key.
bytes key = 1;
}
```
### 3. Chain key update
The chain key MUST be updated according to the `DR_Header` received in the `EncryptedMessageProtocol` message, described in [2.Double Ratchet](#2-double-ratchet).
### 4. Message key derivation
The message key MUST be derived from a single ratchet step in the symmetric-key ratchet as described in [Symmetric key ratchet](https://signal.org/docs/specifications/doubleratchet/#symmetric-key-ratchet)
The message key MUST be used to encrypt the next message to be sent.
# Security Considerations
1. Inherits the security considerations of [X3DH](https://signal.org/docs/specifications/x3dh/#security-considerations) and [Double Ratchet](https://signal.org/docs/specifications/doubleratchet/#security-considerations).
2. Inherits the security considerations of the [Waku v2 protocol](/spec/10/).
3. The protocol is designed to be used in a decentralized manner, however, it is possible to use a centralized server to serve prekey bundles. In this case, the server is trusted.
# Privacy Considerations
1. This protocol does not provide message unlinkability. It is possible to link messages signed by the same keypair.
# Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
# References
1. [5/SECURE-TRANSPORT](https://specs.status.im/spec/5)
2. [10/WAKU2](/spec/10/)
3. [X3DH](https://signal.org/docs/specifications/x3dh/)
4. [HKDF](https://www.rfc-editor.org/rfc/rfc5869)
4. [Double Ratchet](https://signal.org/docs/specifications/doubleratchet/)

View File

@ -0,0 +1,103 @@
---
slug: 54
title: 54/WAKU2-X3DH-SESSIONS
name: Session management for Waku X3DH
status: draft
category: Standards Track
tags: waku-application
editor: Aaryamann Challani <aaryamann@status.im>
contributors:
- Andrea Piana <andreap@status.im>
- Pedro Pombeiro <pedro@status.im>
- Corey Petty <corey@status.im>
- Oskar Thorén <oskar@status.im>
- Dean Eigenmann <dean@status.im>
---
# Abstract
This document specifies how to manage sessions based on an X3DH key exchange.
This includes how to establish new sessions, how to re-establish them, how to maintain them, and how to close them.
[53/WAKU2-X3DH](/spec/53) specifies the Waku `X3DH` protocol for end-to-end encryption.
Once two peers complete an X3DH handshake, they SHOULD establish an X3DH session.
# Session Establishment
A node identifies a peer by their `installation-id` which MAY be interpreted as a device identifier.
## Discovery of pre-key bundles
The node's pre-key bundle SHOULD be broadcasted on a content topic derived from the node's public key.
<!--- TODO: We need to move other specs from status to vac research, including STATUS-WAKU-USAGE -->
The derivation is further described in [10/WAKU-USAGE](https://specs.status.im/spec/10#contact-code-topic)
## Initialization
A node initializes a new session once a successful X3DH exchange has taken place.
Subsequent messages will use the established session until re-keying is necessary.
## Concurrent sessions
If a node creates two sessions concurrently between two peers, the one with the symmetric key first in byte order SHOULD be used, this marks that the other has expired.
## Re-keying
On receiving a bundle from a given peer with a higher version, the old bundle SHOULD be marked as expired and a new session SHOULD be established on the next message sent.
## Multi-device support
Multi-device support is quite challenging as there is not a central place where information on which and how many devices (identified by their respective `installation-id`) a peer has, is stored.
Furthermore, account recovery always needs to be taken into consideration, where a user wipes clean the whole device and the node loses all the information about any previous sessions.
Taking these considerations into account, the way the network propagates multi-device information using X3DH bundles, which will contain information about paired devices as well as information about the sending device.
This means that every time a new device is paired, the bundle needs to be updated and propagated with the new information, the user has the responsibility to make sure the pairing is successful.
The method is loosely based on [Signal's Sesame Algorithm](https://signal.org/docs/specifications/sesame/).
## Pairing
A new `installation-id` MUST be generated on a per-device basis.
The device should be paired as soon as possible if other devices are present.
If a bundle is received, which has the same `IK` as the keypair present on the device, the devices MAY be paired.
Once a user enables a new device, a new bundle MUST be generated which includes pairing information.
The bundle MUST be propagated to contacts through the usual channels.
Removal of paired devices is a manual step that needs to be applied on each device, and consist simply in disabling the device, at which point pairing information will not be propagated anymore.
### Sending messages to a paired group
When sending a message, the peer SHOULD send a message to other `installation-id` that they have seen.
The node caps the number of devices to `n`, ordered by last activity.
The node sends messages using pairwise encryption, including their own devices.
Where `n` is the maximum number of devices that can be paired.
## Account recovery
Account recovery is the same as adding a new device, and it MUST be handled the same way.
## Partitioned devices
In some cases (i.e. account recovery when no other pairing device is available, device not paired), it is possible that a device will receive a message that is not targeted to its own `installation-id`.
In this case an empty message containing bundle information MUST be sent back, which will notify the receiving end not to include the device in any further communication.
# Security Considerations
1. Inherits all security considerations from [53/WAKU2-X3DH](/spec/53).
# Recommendations
1. The value of `n` SHOULD be configured by the app-protocol.
- The default value SHOULD be 3, since a larger number of devices will result in a larger bundle size, which may not be desirable in a peer-to-peer network.
# Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
# References
1. [53/WAKU2-X3DH](/spec/53)
2. [Signal's Sesame Algorithm](https://signal.org/docs/specifications/sesame/)
3. [5/SECURE-TRANSPORT](https://specs.status.im/spec/5)

View File

@ -0,0 +1,75 @@
---
slug: 55
title: 55/STATUS-1TO1-CHAT
name: Status 1-to-1 Chat
status: draft
category: Standards Track
tags: waku-application
editor: Aaryamann Challani <aaryamann@status.im>
contributors:
- Andrea Piana <andreap@status.im>
- Pedro Pombeiro <pedro@status.im>
- Corey Petty <corey@status.im>
- Oskar Thorén <oskar@status.im>
- Dean Eigenmann <dean@status.im>
---
# Abstract
This specification describes how the Status 1-to-1 chat protocol is implemented on top of the Waku v2 protocol.
This protocol can be used to send messages to a single recipient.
# Background
This document describes how 2 peers communicate with each other to send messages in a 1-to-1 chat, with privacy and authenticity guarantees.
# Specification
## Overview
This protocol MAY use any key-exchange mechanism previously discussed -
1. [53/WAKU2-X3DH](/spec/53/)
2. [35/WAKU2-NOISE](/spec/35/)
This protocol can provide end-to-end encryption to give peers a strong degree of privacy and security.
Public chat messages are publicly readable by anyone since there's no permission model for who is participating in a public chat.
## Flow
### Negotiation of a 1:1 chat
There are two phases in the initial negotiation of a 1:1 chat:
1. **Identity verification** (e.g., face-to-face contact exchange through QR code, Identicon matching).
A QR code serves two purposes simultaneously - identity verification and initial key material retrieval;
1. **Asynchronous initial key exchange**
For more information on account generation and trust establishment, see [2/ACCOUNT](https://specs.status.im/spec/2)
### Post Negotiation
After the peers have shared their public key material, a 1:1 chat can be established using the methods described in the key-exchange protocols mentioned above.
### Session management
The 1:1 chat is made robust by having sessions between peers.
It is handled by the key-exchange protocol used. For example,
1. [53/WAKU2-X3DH](/spec/53/), the session management is described in [54/WAKU2-X3DH-SESSIONS](/spec/54/)
2. [35/WAKU2-NOISE](/spec/35/), the session management is described in [37/WAKU2-NOISE-SESSIONS](/spec/37/)
# Security Considerations
1. Inherits the security considerations of the key-exchange mechanism used, e.g., [53/WAKU2-X3DH](/spec/53/) or [35/WAKU2-NOISE](/spec/35/)
# Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
# References
1. [2/ACCOUNT](https://specs.status.im/spec/2)
2. [53/WAKU2-X3DH](/spec/53/)
3. [35/WAKU2-NOISE](/spec/35/)
4. [10/WAKU2](/spec/10/)

View File

@ -43,6 +43,9 @@ bookMenuLevels: 1
- [30/ADAPTIVE-NODES]({{< relref "/docs/rfcs/30/README.md" >}})
- [33/WAKU2-DISCV5]({{< relref "/docs/rfcs/33/README.md" >}})
- [36/WAKU2-BINDINGS-API]({{< relref "/docs/rfcs/36/README.md" >}})
- [53/WAKU2-X3DH]({{< relref "/docs/rfcs/53/README.md" >}})
- [54/WAKU2-X3DH-SESSIONS]({{< relref "/docs/rfcs/54/README.md" >}})
- [55/STATUS-1TO1-CHAT]({{< relref "/docs/rfcs/55/README.md" >}})
- Stable
- [2/MVDS]({{< relref "/docs/rfcs/2/README.md" >}})
- [6/WAKU1]({{< relref "/docs/rfcs/6/README.md" >}})