From 35a52904e8aeadc3dda04cba1e65589315a806c5 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Tue, 4 Oct 2022 18:20:35 +0100 Subject: [PATCH 01/16] X25519 Elliptic-curve Diffie-Hellman ephemeral for establishing secure channel between two Matrix clients --- proposals/zzzz-x25519-ecdhe.md | 104 +++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 proposals/zzzz-x25519-ecdhe.md diff --git a/proposals/zzzz-x25519-ecdhe.md b/proposals/zzzz-x25519-ecdhe.md new file mode 100644 index 00000000000..34f579b9378 --- /dev/null +++ b/proposals/zzzz-x25519-ecdhe.md @@ -0,0 +1,104 @@ +# MSCzzzz: 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. + +## 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 +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. +**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 `||`. + +For the above example keys the info would be: `m.rendezvous.v1.curve25519-aes-sha256|gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HYOtBULNSU=|E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs=`. + +**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. +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 + +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. + +## Unstable prefix + +TBD + +## Dependencies + +None. From 6574c3ee3babedbf0b3cba61e0abc89bcd852c19 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Tue, 4 Oct 2022 18:21:18 +0100 Subject: [PATCH 02/16] MSC3903 --- proposals/{zzzz-x25519-ecdhe.md => 3903-x25519-ecdhe.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{zzzz-x25519-ecdhe.md => 3903-x25519-ecdhe.md} (98%) diff --git a/proposals/zzzz-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md similarity index 98% rename from proposals/zzzz-x25519-ecdhe.md rename to proposals/3903-x25519-ecdhe.md index 34f579b9378..d026eb446ec 100644 --- a/proposals/zzzz-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -1,4 +1,4 @@ -# MSCzzzz: X25519 Elliptic-curve Diffie-Hellman ephemeral for establishing secure channel between two Matrix clients +# 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. From 35f3455df95ba2e1d4523a79c76001986c0cdcfc Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Tue, 4 Oct 2022 18:54:40 +0100 Subject: [PATCH 03/16] Add notes about related/dependencies --- proposals/3903-x25519-ecdhe.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index d026eb446ec..844fcbdba49 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -101,4 +101,7 @@ TBD ## Dependencies -None. +Although this proposal can be used over any other insecure channel, the anticipated use case is over +[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. From 3f1149dde6ab420fbd3166be728b9d12230349af Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Tue, 4 Oct 2022 19:17:17 +0100 Subject: [PATCH 04/16] Add notes on to-device messaging as an alternative --- proposals/3903-x25519-ecdhe.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index 844fcbdba49..662ecbb4712 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -8,6 +8,11 @@ means of scanning a QR code. 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. @@ -86,6 +91,31 @@ where exactly this would fit in the spec documents. ## Alternatives +### 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 @@ -102,6 +132,6 @@ TBD ## Dependencies Although this proposal can be used over any other insecure channel, the anticipated use case is over -[MSC3886](https://github.com/matrix-org/matrix-spec-proposals/pull/3886) +[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. From d50c96c6401fc2d536d930f6961c2c85016b11ac Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Thu, 6 Oct 2022 10:20:14 +0100 Subject: [PATCH 05/16] Add detail about AES-GCM authentication tag --- proposals/3903-x25519-ecdhe.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index 662ecbb4712..c482c332457 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -58,7 +58,7 @@ and info of `|| Date: Mon, 10 Oct 2022 21:02:13 +0100 Subject: [PATCH 06/16] Whitespace and move note to correct point --- proposals/3903-x25519-ecdhe.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index c482c332457..989b3d37967 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -21,7 +21,9 @@ All payloads are transmitted as JSON and could be done over any bidirectional tr [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 @@ -47,6 +49,7 @@ the same structure of payload: ``` Unlike `publicA` the recipient public key `publicB` does not need to be transmitted via a trusted medium. + **3.** Both sides derive the same shared secret as follows: Initiator: `sharedSecret = scalarMult(privateA, publicB) = scalarMult(privateA, scalarMult(privateB, 9))` @@ -74,8 +77,6 @@ For the above example keys the info would be: `m.rendezvous.v1.curve25519-aes-sh 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 base64-decoded `ciphertext`. -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. 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. @@ -86,6 +87,8 @@ 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. +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 From ecc30a247ed8fbd503e84813c049b2f70834e886 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Thu, 13 Oct 2022 11:49:12 +0100 Subject: [PATCH 07/16] MSCyyyy => MSC3906 --- proposals/3903-x25519-ecdhe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index 989b3d37967..c4176e2087c 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -1,6 +1,6 @@ # 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 +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. @@ -139,4 +139,4 @@ TBD Although this proposal can be used over any other insecure channel, the anticipated use case is over [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. +Furthermore without the [MSC3906](https://github.com/matrix-org/matrix-spec-proposals/pull/3906) proposal, there are no other implementations/uses of the proposal. From c18402284bb4e3bb34b1f6d71e1c0f58184d642a Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Mon, 17 Oct 2022 16:31:02 +0100 Subject: [PATCH 08/16] Unstable alg prefix --- proposals/3903-x25519-ecdhe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index c4176e2087c..e48939308b9 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -132,7 +132,7 @@ Algorithm selection and implementation are crucial. ## Unstable prefix -TBD +WHilst in development the unstable algorithm name of `org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256` should be used. ## Dependencies From 8c67a12afbcbec640e3805916a25f1aa75c4db92 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Mon, 13 Feb 2023 10:43:14 +0000 Subject: [PATCH 09/16] Use unpadded base64 encoding for consistency with rest of Matrix spec --- proposals/3903-x25519-ecdhe.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index e48939308b9..0cd369d5a19 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -28,12 +28,12 @@ All payloads are transmitted as JSON and could be done over any bidirectional tr ```json { - "algorithm": "m.rendezvous.v1.curve25519-aes-sha256", - "key": "gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HYOtBULNSU=" + "algorithm": "m.rendezvous.v2.curve25519-aes-sha256", + "key": "gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HYOtBULNSU" } ``` -The `key` is the base64-encoded value for `publicA` (the x co-ordinate of the curve). +The `key` is the unpadded 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 already-authenticated channel, and not via the unauthenticated channel. @@ -43,8 +43,8 @@ the same structure of payload: ```json { - "algorithm": "m.rendezvous.v1.curve25519-aes-sha256", - "key": "E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs=" + "algorithm": "m.rendezvous.v2.curve25519-aes-sha256", + "key": "E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs" } ``` @@ -57,9 +57,9 @@ Initiator: `sharedSecret = scalarMult(privateA, publicB) = scalarMult(privateA, 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 `||`. +and info of `||`. -For the above example keys the info would be: `m.rendezvous.v1.curve25519-aes-sha256|gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HYOtBULNSU=|E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs=`. +For the above example keys the info would be: `m.rendezvous.v2.curve25519-aes-sha256|gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HYOtBULNSU|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. @@ -68,14 +68,14 @@ For the above example keys the info would be: `m.rendezvous.v1.curve25519-aes-sh ```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==" + "iv": "Fk/2eSQ2hANwpQhAI94/BQ" } ``` -- `ciphertext` - base64-encoded(AES-GCM ciphertext concatenated with the authentication tag) -- `iv` - base64-encoded(initialization vector) +- `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 base64-decoded `ciphertext`. +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 confirm that the established channel is secure by means of a checksum derived from the shared key. The checksum is 12 numeric digits in the form `1234-5678-9012` and should be displayed on both devices for the user to @@ -126,13 +126,15 @@ 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 superceded. + ## Security considerations Algorithm selection and implementation are crucial. ## Unstable prefix -WHilst in development the unstable algorithm name of `org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256` should be used. +Whilst in development the unstable algorithm name of `org.matrix.msc3903.rendezvous.v2.curve25519-aes-sha256` should be used. ## Dependencies From 79905f7f447200ef614a7fb83dda78c99f79c251 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Mon, 13 Feb 2023 10:57:51 +0000 Subject: [PATCH 10/16] Spelling --- proposals/3903-x25519-ecdhe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index 0cd369d5a19..580e29a86bd 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -126,7 +126,7 @@ 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 superceded. +An earlier iteration of this proposal used the algorithm name `m.rendezvous.v1.curve25519-aes-sha256` but that has been superseded. ## Security considerations From 451ef4c73ca7e264ca57e8a35837c77c01ea49b3 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 1 Mar 2023 14:22:53 +0000 Subject: [PATCH 11/16] Incorporate feedback from review --- proposals/3903-x25519-ecdhe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index 580e29a86bd..cf128b5cde2 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -138,7 +138,7 @@ Whilst in development the unstable algorithm name of `org.matrix.msc3903.rendezv ## Dependencies -Although this proposal can be used over any other insecure channel, the anticipated use case is over +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. From eb424f4a2f4d6d318bc35bb82aa1d4807ba0900c Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 1 Mar 2023 14:55:45 +0000 Subject: [PATCH 12/16] Clarification over authentication of key exchange and trust model --- proposals/3903-x25519-ecdhe.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index cf128b5cde2..7a4082baa0c 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -20,6 +20,9 @@ The proposal is to use X25519 to agree a shared secret that is then used to perf 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 fot the user to authenticate the key agreement. + **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)` @@ -35,9 +38,6 @@ All payloads are transmitted as JSON and could be done over any bidirectional tr The `key` is the unpadded 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 -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: @@ -48,8 +48,6 @@ the same structure of payload: } ``` -Unlike `publicA` the recipient public key `publicB` does not need to be transmitted via a trusted medium. - **3.** Both sides derive the same shared secret as follows: Initiator: `sharedSecret = scalarMult(privateA, publicB) = scalarMult(privateA, scalarMult(privateB, 9))` @@ -77,7 +75,12 @@ For the above example keys the info would be: `m.rendezvous.v2.curve25519-aes-sh 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 confirm that the established channel is secure by means of a checksum derived from the shared key. +**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 bothe defives then it means that the +devices have not directly exchanged keys with one another and are subject to a man-in-the-middle. + 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. From 7c0b50f7cca241b8bcf99cd4d688e2556dc9c5cb Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 1 Mar 2023 14:59:00 +0000 Subject: [PATCH 13/16] Fudge keys to attempt to parse spell check --- proposals/3903-x25519-ecdhe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index 7a4082baa0c..acb945bd469 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -32,7 +32,7 @@ this proposal makes use of a checksum fot the user to authenticate the key agree ```json { "algorithm": "m.rendezvous.v2.curve25519-aes-sha256", - "key": "gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HYOtBULNSU" + "key": "gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HY0tBULNSU" } ``` @@ -57,7 +57,7 @@ Recipient: `sharedSecret = scalarMult(privateB, publicA) = scalarMult(privateB, **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 `||`. -For the above example keys the info would be: `m.rendezvous.v2.curve25519-aes-sha256|gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HYOtBULNSU|E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs`. +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. From ef5d88db5b8625782fa2278644110a94bf7f59d7 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 1 Mar 2023 15:02:03 +0000 Subject: [PATCH 14/16] Line length --- proposals/3903-x25519-ecdhe.md | 118 ++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 47 deletions(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index acb945bd469..2d8cfe99a9c 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -1,33 +1,40 @@ # 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. +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. +[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. +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. +[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. +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. +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 fot the user to authenticate the key agreement. -**1a.** The initiator generates a ephemeral Curve25519 private key `privateA`. This key should never be re-used. +**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)` +**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: +**1c.** The initiator shares it's key with the recipient via a trusted medium +using the following payload: ```json { @@ -36,10 +43,11 @@ this proposal makes use of a checksum fot the user to authenticate the key agree } ``` -The `key` is the unpadded base64-encoded value for `publicA` (the x co-ordinate of the curve). +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: +**2.** The recipient similarly generates a private key `privateB`, derives the +public key `publicB` and shares is using the same structure of payload: ```json { @@ -54,12 +62,15 @@ Initiator: `sharedSecret = scalarMult(privateA, publicB) = scalarMult(privateA, 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 `||`. +**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 +`||`. -For the above example keys the info would be: `m.rendezvous.v2.curve25519-aes-sha256|gRr3uZSpm2qz37CkqnrhZTW3H0JQvc6l4HY0tBULNSU|E03zK4t29xyiXlt54kOVpIzNtGytjQSvaHXF8n8tTBs`. +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. +**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: @@ -70,10 +81,13 @@ For the above example keys the info would be: `m.rendezvous.v2.curve25519-aes-sh } ``` -- `ciphertext` - unpadded base64-encoded(AES-GCM ciphertext concatenated with the authentication tag) +- `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`. +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. @@ -81,44 +95,49 @@ secure by means of a checksum that is shown on both devices. If the checksum shown is not the same on bothe defives then it means that the devices have not directly exchanged keys with one another and are subject to a man-in-the-middle. -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 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 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. +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. +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 ### 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 +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. +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. +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. +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 "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. +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? @@ -126,10 +145,12 @@ Does the new device/client need to accept the T&Cs of the "guest" Homeserver? 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. +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. +An earlier iteration of this proposal used the algorithm name +`m.rendezvous.v1.curve25519-aes-sha256` but that has been superseded. ## Security considerations @@ -137,11 +158,14 @@ Algorithm selection and implementation are crucial. ## Unstable prefix -Whilst in development the unstable algorithm name of `org.matrix.msc3903.rendezvous.v2.curve25519-aes-sha256` should be used. +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). +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. +Furthermore without the +[MSC3906](https://github.com/matrix-org/matrix-spec-proposals/pull/3906) +proposal, there are no other implementations/uses of the proposal. From 035b20237558d15e5f019336737b3cb72293676e Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 1 Mar 2023 15:02:21 +0000 Subject: [PATCH 15/16] Spelling --- proposals/3903-x25519-ecdhe.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index 2d8cfe99a9c..69af33679e5 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -25,7 +25,7 @@ transport including [MSC3886](https://github.com/matrix-org/matrix-spec-proposal or elsewhere in Matrix. As Diffie-Hellman key agreement is a non-authenticated key-agreement protocol, -this proposal makes use of a checksum fot the user to authenticate the key agreement. +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`. This key should never be re-used. @@ -92,7 +92,7 @@ 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 bothe defives then it means that the +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. The checksum is 12 numeric digits in the form `1234-5678-9012` and should be From 8995ccdd33112a4e8c9dab6b7cf3ec7efab908b9 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Wed, 15 Mar 2023 17:48:28 -0400 Subject: [PATCH 16/16] Migrate discussion on send-to-device messaging to MSC3886 --- proposals/3903-x25519-ecdhe.md | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-) diff --git a/proposals/3903-x25519-ecdhe.md b/proposals/3903-x25519-ecdhe.md index 69af33679e5..905f07f0cc7 100644 --- a/proposals/3903-x25519-ecdhe.md +++ b/proposals/3903-x25519-ecdhe.md @@ -116,30 +116,16 @@ documents. ### 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. +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. -Furthermore the client might not know which Homeserver the user wishes to -connect to. +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. -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