-
Notifications
You must be signed in to change notification settings - Fork 383
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MSC3903: X25519 Elliptic-curve Diffie-Hellman ephemeral for establishing secure channel between two Matrix clients #3903
Changes from all commits
35a5290
6574c3e
35f3455
3f1149d
d50c96c
73777be
ecc30a2
c184022
8c67a12
79905f7
451ef4c
eb424f4
7c0b50f
ef5d88d
035b202
8995ccd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,157 @@ | ||||||||||||||||||||||||||||||||||||||||||
# MSC3903: X25519 Elliptic-curve Diffie-Hellman ephemeral for establishing secure channel between two Matrix clients | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
In [MSC3906](https://github.com/matrix-org/matrix-spec-proposals/pull/3906) a | ||||||||||||||||||||||||||||||||||||||||||
proposal is made to allow a user to login on a new device using an existing | ||||||||||||||||||||||||||||||||||||||||||
device by means of scanning a QR code. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
[MSC3886](https://github.com/matrix-org/matrix-spec-proposals/pull/3886) already | ||||||||||||||||||||||||||||||||||||||||||
proposes a simple unsecured rendezvous protocol. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
In this proposal we build a secure layer on top of MSC3886 to allow for trusted | ||||||||||||||||||||||||||||||||||||||||||
out-of-bands communication between two Matrix clients. | ||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+3
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The reference to MSC3906 should be clarified by stating what kind of relationship it has with this MSC.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
It is notable that the combination of this proposal and [MSC3886](https://github.com/matrix-org/matrix-spec-proposals/pull/3886) | ||||||||||||||||||||||||||||||||||||||||||
provides a similar capability to the existing | ||||||||||||||||||||||||||||||||||||||||||
[Send-to-Device messaging](https://spec.matrix.org/v1.4/client-server-api/#send-to-device-messaging) | ||||||||||||||||||||||||||||||||||||||||||
feature. See the alternatives section for more on this. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
## Proposal | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
The proposal is to use X25519 to agree a shared secret that is then used to | ||||||||||||||||||||||||||||||||||||||||||
perform AES. | ||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+20
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
All payloads are transmitted as JSON and could be done over any bidirectional | ||||||||||||||||||||||||||||||||||||||||||
transport including [MSC3886](https://github.com/matrix-org/matrix-spec-proposals/pull/3886) | ||||||||||||||||||||||||||||||||||||||||||
or elsewhere in Matrix. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
As Diffie-Hellman key agreement is a non-authenticated key-agreement protocol, | ||||||||||||||||||||||||||||||||||||||||||
this proposal makes use of a checksum for the user to authenticate the key agreement. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**1a.** The initiator generates a ephemeral Curve25519 private key `privateA`. | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: please use markdown's built-in numbering/bullet system There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
This key should never be re-used. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**1b.** The initiator derives the public key from `privateA` as | ||||||||||||||||||||||||||||||||||||||||||
`publicA = scalarMult(privateA, 9)` | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**1c.** The initiator shares it's key with the recipient via a trusted medium | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
using the following payload: | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
```json | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
"algorithm": "m.rendezvous.v2.curve25519-aes-sha256", | ||||||||||||||||||||||||||||||||||||||||||
"key": "gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HY0tBULNSU" | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
The `key` is the unpadded base64-encoded value for `publicA` (the x co-ordinate | ||||||||||||||||||||||||||||||||||||||||||
of the curve). | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**2.** The recipient similarly generates a private key `privateB`, derives the | ||||||||||||||||||||||||||||||||||||||||||
public key `publicB` and shares is using the same structure of payload: | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
```json | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
"algorithm": "m.rendezvous.v2.curve25519-aes-sha256", | ||||||||||||||||||||||||||||||||||||||||||
"key": "E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs" | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**3.** Both sides derive the same shared secret as follows: | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Initiator: `sharedSecret = scalarMult(privateA, publicB) = scalarMult(privateA, scalarMult(privateB, 9))` | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Recipient: `sharedSecret = scalarMult(privateB, publicA) = scalarMult(privateB, scalarMult(privateA, 9))` | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**4.** Both sides then derive a 256 bit AES key using HKDF SHA-256 with a salt | ||||||||||||||||||||||||||||||||||||||||||
of 8 bytes of zero (i.e. `[0,0,0,0,0,0,0,0]`) and info of | ||||||||||||||||||||||||||||||||||||||||||
`<algorithm>|<unpadded base64-encoded initiator public key>|<unpadded base64-encoded recipient public key>`. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
For the above example keys the info would be: | ||||||||||||||||||||||||||||||||||||||||||
`m.rendezvous.v2.curve25519-aes-sha256|gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HY0tBULNSU|E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs`. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**5.** Subsequent payloads are then sent encrypted using 256 bit AES-GCM using a | ||||||||||||||||||||||||||||||||||||||||||
256 bit random initialisation vector and 128 bit authentication tag. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**6.** Encrypted payloads are then encoded and transmitted by either party as follows: | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
```json | ||||||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||||||
"ciphertext": "L3SHZU2DnfPxiVHVcgqe2HNq7Acdv13XCK/mC5f0JmxGqeUNQdeta8HD8qGBu3YdYrv5Bf7xl8WjlGaUOLr3uceZUuSv8amRZUghZ+/GQsi8tPZLzHk0xOePmKhRg95HUZrja7cQIgw+iKY/Vp1UoUJRqk1iQv/86RHz3c5a/GqyhGyWnXfuy16tPxmNQ4IpI/hVJof+7iiA3IucMtLHZnGH/VpNuZ1kv97GJJbUX3XfTIjyN2jmA9zFP5d/mE10YYzG7XcZ0hWj5BPhpM1jojwVyTRhMseJAX7MVvqQ7HT7LjvoJSYm5xk+0ptsWodAuol7uYjGszIu+EFvpuYmweZa6ewcnf/T5fXb6hXfqCZf43gumrXx5ACUMC4IWBOI0mFE28ITRmw9ZjL2CodxFsbTGRYp3Arb0SMcF1KUsiYBXxLasXFaEtrE244QD+oc9FEWNPLdgCDcwEhalaK9OP7MJF7jXc2y+zOPfUPCdCHoSV6F5Y/MnPkrpwprrIn/yp2E4/4QTe2VTXG7ZJa/aCGh8eAo9nBANQi7sGElr83SU0oy80MvVWUmxnaWc8UDgASkC/dGQNCfZzsZeho0+Y2smcETJlD/7+D1c8YC3LevAtYXDOOO9ApaY+SpPloKp/zdoZdkf+ggGfyytvTEw0gZUygZnBplefaIry9lASpv6XXkowVFFP5kGf0ZAhPOr2ET3DTyoBXP7u7MJrRAtBEex6OaysVaJ2DDEj8JknpdwatuWPduygMt", | ||||||||||||||||||||||||||||||||||||||||||
"iv": "Fk/2eSQ2hANwpQhAI94/BQ" | ||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
- `ciphertext` - unpadded base64-encoded(AES-GCM ciphertext concatenated with | ||||||||||||||||||||||||||||||||||||||||||
the authentication tag) | ||||||||||||||||||||||||||||||||||||||||||
- `iv` - unpadded base64-encoded(initialization vector) | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
This means that for AES-GCM implementations that require the authentication tag | ||||||||||||||||||||||||||||||||||||||||||
to be explicitly processed (e.g. CryptoKit on iOS) that it can be sourced from | ||||||||||||||||||||||||||||||||||||||||||
the last 16 bytes of the unpadded base64-decoded `ciphertext`. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
**7.** The user should authenticate/confirm that the established channel is | ||||||||||||||||||||||||||||||||||||||||||
secure by means of a checksum that is shown on both devices. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
If the checksum shown is not the same on both defives then it means that the | ||||||||||||||||||||||||||||||||||||||||||
devices have not directly exchanged keys with one another and are subject to a man-in-the-middle. | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
The checksum is 12 numeric digits in the form `1234-5678-9012` and should be | ||||||||||||||||||||||||||||||||||||||||||
displayed on both devices for the user to visually verify. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
The checksum should be derived in a similar manner to step **4** above, however | ||||||||||||||||||||||||||||||||||||||||||
only 40 bit should be derived this time. The salt and info are the same as before. | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The info should be different, otherwise the checksum will leak bits of the encryption key. You can prepend the info with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. As it stands, this looks like a gaping hole. |
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
The decimal representation of the 40 bits is calculated using the method | ||||||||||||||||||||||||||||||||||||||||||
described in https://spec.matrix.org/v1.4/client-server-api/#sas-method-decimal. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Steps **1** and **2** can happen simultaneously or in any order. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
## Potential issues | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
This proposal introduces yet another key that Matrix client implementations need | ||||||||||||||||||||||||||||||||||||||||||
awareness of. It's also not clear to me where exactly this would fit in the spec | ||||||||||||||||||||||||||||||||||||||||||
documents. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
## Alternatives | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it sounds like this is duplicating Olm sessions over to-device? Early on in this proposal there should be something to address that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, acknowledged. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, no. It's actually that you could achieve this with to-device messaging instead. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this^ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I concur that the feasibility of Olm over MSC3886 should be assessed. |
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
### Send-to-Device messaging | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
The combination of this proposal and | ||||||||||||||||||||||||||||||||||||||||||
[MSC3886](https://github.com/matrix-org/matrix-spec-proposals/pull/3886) look | ||||||||||||||||||||||||||||||||||||||||||
similar in some regards to the existing | ||||||||||||||||||||||||||||||||||||||||||
[Send-to-device messaging](https://spec.matrix.org/v1.6/client-server-api/#send-to-device-messaging) | ||||||||||||||||||||||||||||||||||||||||||
capability. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Discussion on this as an alternative has been moved to | ||||||||||||||||||||||||||||||||||||||||||
[MSC3886](https://github.com/matrix-org/matrix-spec-proposals/pull/3886) as it | ||||||||||||||||||||||||||||||||||||||||||
has received more engagement on that proposal. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
### Naming convention | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
The algorithm name is arbitrary. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Alternative key exchange algorithms to X25519 could be used. Alternative | ||||||||||||||||||||||||||||||||||||||||||
symmetric ciphers to AES-GCM could be used. The purpose of the `algorithm` field | ||||||||||||||||||||||||||||||||||||||||||
is allow for alternative algorithms in the future. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
An earlier iteration of this proposal used the algorithm name | ||||||||||||||||||||||||||||||||||||||||||
`m.rendezvous.v1.curve25519-aes-sha256` but that has been superseded. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
## Security considerations | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Algorithm selection and implementation are crucial. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that this protects against replay attacks. That might be OK if the thing built on top of it can detect if a message is replayed (e.g. if messages have a definite order, so a replayed message would be flagged as being out of place), but I think it should be mentioned. |
||||||||||||||||||||||||||||||||||||||||||
## Unstable prefix | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Whilst in development the unstable algorithm name of | ||||||||||||||||||||||||||||||||||||||||||
`org.matrix.msc3903.rendezvous.v2.curve25519-aes-sha256` should be used. | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
## Dependencies | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Although this proposal could be used over any communication channel, the | ||||||||||||||||||||||||||||||||||||||||||
anticipated use case is over [MSC3886](https://github.com/matrix-org/matrix-spec-proposals/pull/3886). | ||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||
Furthermore without the | ||||||||||||||||||||||||||||||||||||||||||
[MSC3906](https://github.com/matrix-org/matrix-spec-proposals/pull/3906) | ||||||||||||||||||||||||||||||||||||||||||
proposal, there are no other implementations/uses of the proposal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This entire MSC is essentially re-specifying ECIES (some more resources: [1], [2]).
MIT-licensed ECIES implementations in Rust, Python, TypeScript and Golang available here.