-
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 4 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,137 @@ | ||
# MSC3903: X25519 Elliptic-curve Diffie-Hellman ephemeral for establishing secure channel between two Matrix clients | ||
|
||
In MSCyyyy (to be published) 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. | ||
|
||
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. | ||
|
||
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. | ||
|
||
**1a.** The initiator generates a ephemeral Curve25519 private key `privateA`. 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 using the following payload: | ||
|
||
```json | ||
{ | ||
"algorithm": "m.rendezvous.v1.curve25519-aes-sha256", | ||
"key": "gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HYOtBULNSU=" | ||
} | ||
``` | ||
|
||
The `key` is the base64-encoded value for `publicA` (the x co-ordinate of the curve). | ||
|
||
It's critical that the initiator public key `publicA` is transmitted via a trusted medium such as a QR code or some other | ||
uhoreg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
already-authenticated channel, and not via the unauthenticated channel. | ||
|
||
**2.** The recipient similarly generates a private key `privateB`, derives the public key `publicB` and shares is using | ||
the same structure of payload: | ||
|
||
```json | ||
{ | ||
"algorithm": "m.rendezvous.v1.curve25519-aes-sha256", | ||
"key": "E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs=" | ||
} | ||
``` | ||
|
||
Unlike `publicA` the recipient public key `publicB` does not need to be transmitted via a trusted medium. | ||
uhoreg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
**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>|<base64-encoded initiator public key>|<base64-encoded recipient public key>`. | ||
|
||
For the above example keys the info would be: `m.rendezvous.v1.curve25519-aes-sha256|gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HYOtBULNSU=|E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs=`. | ||
hughns marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
**5.** Subsequent payloads are then sent encrypted using 256 bit AES-GCM using a 256 bit random initialisation vector/salt. | ||
|
||
**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` - base64-encoded AES-GCM encrypted data | ||
- `iv` - base64-encoded initialization vector/salt | ||
|
||
Steps **1** and **2** can happen simultaneously or in any order. | ||
|
||
**7.** The user should confirm that the established channel is secure by means of a checksum derived from the shared key. | ||
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 is CRAPPY, HORRIBLE UX! WHY? Why another visual comparison, another “I don't get what should I do now.” moment for users? Matrix already has too much visual comparison in its UX. You already have a secure channel by means of QR code. Utilize it well, so users don't have to compare checksums. 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 QR code is only secure in the sense that you can be sure that its contents were generated by the device that you're trying to communicate with. But it is not secret, as it is sometimes possible that someone else can scan the QR code as well. So unless you have another step (in this case, a visual comparison) to verify that the other public key was transmitted correctly, you cannot be sure that the channel is secure. |
||
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. | ||
|
||
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. | ||
|
||
## 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 | ||
|
||
Whilst to-device messaging already provides a mechanism for secure communication between two Matrix clients/devices, a | ||
key consideration for the anticipated login with QR capability is that one of the clients is not yet authenticated with | ||
a Homeserver. | ||
|
||
Furthermore the client might not know which Homeserver the user wishes to connect to. | ||
|
||
Conceptually, one could create a new type of "guest" login that would allow the unauthenticated client to connect to a | ||
Homeserver for the purposes of communicating with an existing authenticated client via to-device messages. | ||
|
||
Some considerations for this: | ||
|
||
Where the "actual" Homeserver is not known then the "guest" Homeserver nominated by the new client would need to be federated | ||
with the "actual" Homeserver. | ||
|
||
The "guest" Homeserver would probably want to automatically clean up the "guest" accounts after a short period of time. | ||
|
||
The "actual" Homeserver operator might not want to open up full "guest" access so a second type of "guest" account might | ||
be required. | ||
|
||
Does the new device/client need to accept the T&Cs of the "guest" Homeserver? | ||
|
||
### 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. | ||
|
||
## 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 | ||
|
||
TBD | ||
|
||
## Dependencies | ||
|
||
Although this proposal can be used over any other insecure channel, the anticipated use case is over | ||
hughns marked this conversation as resolved.
Show resolved
Hide resolved
|
||
[MSC3886](https://github.com/matrix-org/matrix-spec-proposals/pull/3886). | ||
|
||
Furthermore without the (as yet unpublished) MSCyyyy 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.