Remove e2e drafts from master

This is now being tracked in the main spec, on the drafts/e2e branch.
pull/977/head
Richard van der Hoff 9 years ago committed by Daniel Wagner-Hall
parent cb3ca223d0
commit 3939ccf20c

@ -1,343 +0,0 @@
End-to-End Encryption
=====================
.. _module:e2e:
.. TODO-doc
- Why is this needed.
- Overview of process
- Implementation
Matrix optionally supports end-to-end encryption, allowing rooms to be created
whose conversation contents is not decryptable or interceptable on any of the
participating homeservers.
End-to-end crypto is still being designed and prototyped - notes on the design
may be found at https://lwn.net/Articles/634144/
Overview
--------
.. code::
1) Bob publishes the public keys and supported algorithms for his device.
+----------+ +--------------+
| Bob's HS | | Bob's Device |
+----------+ +--------------+
| |
|<=============|
/keys/upload
2) Alice requests Bob's public key and supported algorithms.
+----------------+ +------------+ +----------+
| Alice's Device | | Alice's HS | | Bob's HS |
+----------------+ +------------+ +----------+
| | |
|=================>|==============>|
/keys/query <federation>
3) Alice selects an algorithm and claims any one-time keys needed.
+----------------+ +------------+ +----------+
| Alice's Device | | Alice's HS | | Bob's HS |
+----------------+ +------------+ +----------+
| | |
|=================>|==============>|
/keys/claim <federation>
4) Alice sends an encrypted message to Bob.
+----------------+ +------------+ +----------+ +--------------+
| Alice's Device | | Alice's HS | | Bob's HS | | Bob's Device |
+----------------+ +------------+ +----------+ +--------------+
| | | |
|----------------->|-------------->|------------->|
/send/ <federation> <events>
Algorithms
----------
There are two kinds of algorithms: messaging algorithms and key algorithms.
Messaging algorithms are used to securely send messages between devices.
Key algorithms are used for key agreement and digital signatures.
Messaging Algorithm Names
~~~~~~~~~~~~~~~~~~~~~~~~~
Messaging algorithm names use the extensible naming scheme used throughout this
specification. Algorithm names that start with ``m.`` are reserved for
algorithms defined by this specification. Implementations wanting to experiment
with new algorithms are encouraged to pick algorithm names that start with
their domain to reduce the risk of collisions.
Algorithm names should be short and meaningful, and should list the primitives
used by the algorithm so that it is easier to see if the algorithm is using a
broken primitive.
The name ``m.olm.v1.curve25519-aes-sha2`` corresponds to version 1 of the Olm
ratchet using Curve25519 for the initial key agreement, HKDF-SHA-256 for
ratchet key derivation, Curve25519 for the DH ratchet, HMAC-SHA-256 for the
hash ratchet, and HKDF-SHA-256, AES-256 in CBC mode, and 8 byte truncated
HMAC-SHA-256 for authenticated encryption.
A name of ``m.olm.v1`` is too short: it gives no information about the primitives
in use, and is difficult to extend for different primitives. However a name of
``m.olm.v1.ecdh-curve25519-hdkfsha256.hmacsha256.hkdfsha256-aes256-cbc-hmac64sha256``
is too long despite giving a more precise description of the algorithm: it adds
to the data transfer overhead and sacrifices clarity for human readers without
adding any useful extra information.
Key Algorithms
~~~~~~~~~~~~~~
The name ``ed25519`` corresponds to the Ed25519 signature algorithm. The key is
a Base64 encoded 32-byte Ed25519 public key.
The name ``curve25519`` corresponds to the Curve25519 ECDH algorithm. The key is
a Base64 encoded 32-byte Curve25519 public key.
Client Behaviour
----------------
Uploading Keys
~~~~~~~~~~~~~~
Keys are uploaded as a signed JSON object. The JSON object must include an
ed25519 key and must be signed by that key. A device may only have one ed25519
signing key. This key is used as the fingerprint for a device by other clients.
The JSON object is signed using the process given by `Signing JSON`_.
.. code:: http
POST /_matrix/client/%CLIENT_MAJOR_VERSION%/keys/upload/<device_id> HTTP/1.1
Content-Type: application/json
{
"device_keys": {
"user_id": "<user_id>",
"device_id": "<device_id>",
"valid_after_ts": 1234567890123,
"valid_until_ts": 2345678901234,
"algorithms": [
"<chat_algorithm>",
],
"keys": {
"<key_algorithm>:<device_id>": "<key_base64>",
},
"signatures": {
"<user_id>": {
"<key_algorithm>:<device_id>": "<signature_base64>"
} } },
"one_time_keys": {
"<key_algorithm>:<key_id>": "<key_base64>"
} }
.. code:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"one_time_key_counts": {
"<key_algorithm>": 50
}
}
Downloading Keys
~~~~~~~~~~~~~~~~
Keys are downloaded as a collection of signed JSON objects. There
will be one JSON object per device per user. If one of the user's
devices doesn't support end-to-end encryption then their
homeserver must synthesise a JSON object without any device keys
for that device.
The JSON must be signed by both the homeserver of
the user querying the keys and by the homeserver of the device
being queried. This provides an audit trail if either homeserver
lies about the keys a user owns.
.. code:: http
POST /keys/query HTTP/1.1
Content-Type: application/json
{
"device_keys": {
"<user_id>": ["<device_id>"]
} }
.. code:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"device_keys": {
"<user_id>": {
"<device_id>": {
"user_id": "<user_id>",
"device_id": "<device_id>",
"valid_after_ts": 1234567890123,
"valid_until_ts": 2345678901234,
"algorithms": [
"<chat_algorithm>",
],
"keys": {
"<algorithm>:<device_id>": "<key_base64>",
},
"signatures": {
"<user_id>": {
"<key_algorithm>:<device_id>": "<signature_base64>"
},
"<local_server_name>": {
"<key_algorithm>:<key_id>": "<signature_base64>"
},
"<remote_server_name>": {
"<key_algorithm>:<key_id>": "<signature_base64>"
} } } } } }
Clients use ``/_matrix/client/%CLIENT_MAJOR_VERSION%/keys/query`` on their own homeservers to
query keys for any user they wish to contact. Homeservers will respond with the
keys for their local users and forward requests for remote users to
``/_matrix/federation/v1/user/keys/query`` over federation to the remote
server.
Claiming One Time Keys
~~~~~~~~~~~~~~~~~~~~~~
Some algorithms require one-time keys to improve their secrecy and deniability.
These keys are used once during session establishment, and are then thrown
away. In order for these keys to be useful for improving deniability they
must not be signed using the ed25519 key for a device.
A device must generate a number of these keys and publish them onto their
homeserver. A device must periodically check how many one-time keys their
homeserver still has. If the number has become too small then the device must
generate new one-time keys and upload them to the homeserver.
Devices must store the private part of each one-time key they upload. They can
discard the private part of the one-time key when they receive a message using
that key. However it's possible that a one-time key given out by a homeserver
will never be used, so the device that generates the key will never know that
it can discard the key. Therefore a device could end up trying to store too
many private keys. A device that is trying to store too many private keys may
discard keys starting with the oldest.
A homeserver should rate-limit the number of one-time keys that a given user or
remote server can claim. A homeserver should discard the public part of a one
time key once it has given that key to another user.
.. code:: http
POST /keys/claim HTTP/1.1
Content-Type: application/json
{
"one_time_keys": {
"<user_id>": {
"<device_id>": "<key_algorithm>"
} } }
.. code:: http
HTTP/1.1 200 OK
Content-Type: application/json
{
"one_time_keys": {
"<user_id>": {
"<device_id>": {
"<key_algorithm>:<key_id>": "<key_base64>"
} } } }
Clients use ``/_matrix/client/%CLIENT_MAJOR_VERSION%/keys/claim`` on their own homeservers to
claim keys for any user they wish to contact. Homeservers will respond with the
keys for their local users and forward requests for remote users to
``/_matrix/federation/v1/user/keys/claim`` over federation to the remote
server.
Sending a Message
~~~~~~~~~~~~~~~~~
Encrypted messages are sent in the form.
.. code:: json
{
"type": "m.room.encrypted",
"content": {
"algorithm": "<chat_algorithm>",
"<algorithm_specific_keys>": "<algorithm_specific_data>"
} }
Using Olm
+++++++++
Devices that support olm must include "m.olm.v1.curve25519-aes-sha2" in their
list of supported chat algorithms, must list a Curve25519 device key, and
must publish Curve25519 one-time keys.
.. code:: json
{
"type": "m.room.encrypted",
"content": {
"algorithm": "m.olm.v1.curve25519-aes-sha2",
"sender_key": "<sender_curve25519_key>",
"ciphertext": {
"<device_curve25519_key>": {
"type": 0,
"body": "<base_64>"
} } } }
The ciphertext is a mapping from device curve25519 key to an encrypted payload
for that device. The ``body`` is a base64 encoded message body. The type is an
integer indicating the type of the message body: 0 for the initial pre-key
message, 1 for ordinary messages.
Olm sessions will generate messages with a type of 0 until they receive a
message. Once a session has decrypted a message it will produce messages with
a type of 1.
When a client receives a message with a type of 0 it must first check if it
already has a matching session. If it does then it will use that session to
try to decrypt the message. If there is no existing session then the client
must create a new session and use the new session to decrypt the message. A
client must not persist a session or remove one-time keys used by a session
until it has successfully decrypted a message using that session.
The plaintext payload is of the form:
.. code:: json
{
"type": "<type of the plaintext event>",
"content": "<content for the plaintext event>",
"room_id": "<the room_id>",
"fingerprint": "<sha256 hash of the currently participating keys>"
}
The type and content of the plaintext message event are given in the payload.
Encrypting state events is not supported.
We include the room ID in the payload, because otherwise the homeserver would
be able to change the room a message was sent in. We include a hash of the
participating keys so that clients can detect if another device is unexpectedly
included in the conversation.
Clients must confirm that the ``sender_key`` belongs to the user that sent the
message.

@ -1,146 +0,0 @@
Goals of Key-Distribution in Matrix
===================================
* No Central Authority: Users should not need to trust a central authority
when determining the authenticity of keys.
* Easy to Add New Devices: It should be easy for a user to start using a
new device.
* Possible to discover MITM: It should be possible for a user to determine if
they are being MITM.
* Lost Devices: It should be possible for a user to recover if they lose all
their devices.
* No Copying Keys: Keys should be per device and shouldn't leave the device
they were created on.
A Possible Mechanism for Key Distribution
=========================================
Basic API for setting up keys on a server:
https://github.com/matrix-org/matrix-doc/pull/24
Client shouldn't trust the keys unless they have been verified, e.g by
comparing fingerprints.
If a user adds a new device it should some yet to be specified protocol
communicate with an old device and obtain a cross-signature from the old
device for its public key.
The new device can then present the cross-signed key to all the devices
that the user is in conversations with. Those devices should then include
the new device into those conversations.
If the user cannot cross-sign the new key, e.g. because their old device
is lost or stolen. Then they will need to reauthenticate their conversations
out of band, e.g by comparing fingerprints.
Goals of End-to-end encryption in Matrix
========================================
* Access to Chat History: Users should be able to see the history of a
conversation on a new device. User should be able to control who can
see their chat history and how much of the chat history they can see.
* Forward Secrecy of Discarded Chat History: Users should be able to discard
history from their device, once they have discarded the history it should be
impossible for an adversary to recover that history.
* Forward Secrecy of Future Messages: Users should be able to recover from
disclosure of the chat history on their device.
* Deniablity of Chat History: It should not be possible to prove to a third
party that a given user sent a message.
* Authenticity of Chat History: It should be possible to prove amoungst
the members of a chat that a message sent by a user was authored by that
user.
Bonus Goals:
* Traffic Analysis: It would be nice if the protocol was resilient to traffic
or metadata analysis. However it's not something we want to persue if it
harms the usability of the protocol. It might be cool if there was a
way for the user to could specify the trade off between performance and
resilience to traffic analysis that they wanted.
A Possible Design for Group Chat using Olm
==========================================
Protecting the secrecy of history
---------------------------------
Each message sent by a client has a 32-bit counter. This counter increments
by one for each message sent by the client. This counter is used to advance a
ratchet. The ratchet is split into a vector four 256-bit values,
:math:`R_{n,j}` for :math:`j \in {0,1,2,3}`. The ratchet can be advanced as
follows:
.. math::
\begin{align}
R_{2^24n,0} &= H_0\left(R_{2^24(i-1),0}\right) \\
R_{2^24n,1} &= H_1\left(R_{2^24(i-1),0}\right) \\
R_{2^24n,2} &= H_2\left(R_{2^24(i-1),0}\right) \\
R_{2^24n,3} &= H_3\left(R_{2^24(i-1),0}\right) \\
R_{2^16n,1} &= H_1\left(R_{2^16(i-1),1}\right) \\
R_{2^16n,2} &= H_2\left(R_{2^16(i-1),1}\right) \\
R_{2^16n,3} &= H_3\left(R_{2^16(i-1),1}\right) \\
R_{2^8i,2} &= H_2\left(R_{2^8(i-1),2}\right) \\
R_{2^8i,3} &= H_3\left(R_{2^8(i-1),2}\right) \\
R_{i,3} &= H_3\left(R_{(i-1),3}\right)
\end{align}
Where :math:`H_0`, :math:`H_1`, :math:`H_2`, and :math:`H_3`
are different hash functions. For example
:math:`H_0` could be :math:`HMAC\left(X,\text{"\textbackslash x00"}\right)` and
:math:`H_1` could be :math:`HMAC\left(X,\text{"\textbackslash x01"}\right)`.
So every :math:`2^24` iterations :math:`R_{n,1}` is reseeded from :math:`R_{n,0}`.
Every :math:`2^16` iterations :math:`R_{n,2}` is reseeded from :math:`R_{n,1}`.
Every :math:`2^8` iterations :math:`R_{n,3}` is reseeded from :math:`R_{n,2}`.
This scheme allows the ratchet to be advanced an arbitrary amount forwards
while needing only 1024 hash computations.
This the value of the ratchet is hashed to generate the keys used to encrypt
each mesage.
A client can decrypt chat history onwards from the earliest value of the
ratchet it is aware of. But cannot decrypt history from before that point
without reversing the hash function.
This allows a client to share its ability to decrypt chat history with another
from a point in the conversation onwards by giving a copy of the ratchet at
that point in the conversation.
A client can discard history by advancing a ratchet to beyond the last message
they want to discard and then forgetting all previous values of the ratchet.
Proving and denying the authenticity of history
-----------------------------------------------
Client sign the messages they send using a Ed25519 key generated per
conversation. That key, along with the ratchet key, is distributed
to other clients using 1:1 olm ratchets. Those 1:1 ratchets are started using
Triple Diffie-Hellman which provides authenticity of the messages to the
participants and deniability of the messages to third parties. Therefore
any keys shared over those keys inherit the same levels of deniability and
authenticity.
Protecting the secrecy of future messages
-----------------------------------------
A client would need to generate new keys if it wanted to prevent access to
messages beyond a given point in the conversation. It must generate new keys
whenever someone leaves the room. It should generate new keys periodically
anyway.
The frequency of key generation in a large room may need to be restricted to
keep the frequency of messages broadcast over the individual 1:1 channels
low.

@ -5,4 +5,5 @@ End-to-End Encryption
End to end encryption is being worked on and will be coming soon.
You can read about what's underway at https://github.com/matrix-org/matrix-doc/blob/master/drafts/e2e.rst
You can read about what's underway at http://matrix.org/speculator/spec/drafts%2Fe2e/client_server.html#end-to-end-encryption.

Loading…
Cancel
Save