Skip to content

Commit ad94985

Browse files
uhoregrichvdh
andauthored
Define hkdf-hmac-sha256.v2 MAC method for SAS verification (#1412)
Co-authored-by: Richard van der Hoff <[email protected]>
1 parent e9a463d commit ad94985

File tree

7 files changed

+73
-33
lines changed

7 files changed

+73
-33
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Define `hkdf-hmac-sha256.v2` MAC method for SAS verification, as per [MSC 3783](https://github.com/matrix-org/matrix-spec-proposals/pull/3783).

content/client-server-api/modules/end_to_end_encryption.md

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -668,22 +668,22 @@ The process between Alice and Bob verifying each other would be:
668668
the users to select a method.
669669
14. Alice and Bob compare the strings shown by their devices, and tell
670670
their devices if they match or not.
671-
15. Assuming they match, Alice and Bob's devices calculate the HMAC of
672-
their own device keys and a comma-separated sorted list of the key
673-
IDs that they wish the other user to verify, using SHA-256 as the
674-
hash function. HMAC is defined in [RFC
675-
2104](https://tools.ietf.org/html/rfc2104). The key for the HMAC is
676-
different for each item and is calculated by generating 32 bytes
677-
(256 bits) using [the key verification HKDF](#hkdf-calculation).
671+
15. Assuming they match, Alice and Bob's devices each calculate Message
672+
Authentication Codes (MACs) for:
673+
* Each of the keys that they wish the other user to verify (usually their
674+
device ed25519 key and their master cross-signing key).
675+
* The complete list of key IDs that they wish the other user to verify.
676+
677+
The MAC calculation is defined [below](#mac-calculation).
678678
16. Alice's device sends Bob's device an `m.key.verification.mac`
679679
message containing the MAC of Alice's device keys and the MAC of her
680680
key IDs to be verified. Bob's device does the same for Bob's device
681681
keys and key IDs concurrently with Alice.
682682
17. When the other device receives the `m.key.verification.mac` message,
683-
the device calculates the HMAC of its copies of the other device's
684-
keys given in the message, as well as the HMAC of the
683+
the device calculates the MACs of its copies of the other device's
684+
keys given in the message, as well as the MAC of the
685685
comma-separated, sorted, list of key IDs in the message. The device
686-
compares these with the HMAC values given in the message, and if
686+
compares these with the MAC values given in the message, and if
687687
everything matches then the device keys are verified.
688688
18. Alice and Bob's devices send `m.key.verification.done` messages to complete
689689
the verification.
@@ -767,7 +767,55 @@ following error codes are used in addition to those already specified:
767767

768768
{{% event event="m.key.verification.mac" %}}
769769

770-
###### HKDF calculation
770+
###### MAC calculation
771+
772+
During the verification process, Message Authentication Codes (MACs) are calculated
773+
for keys and lists of key IDs.
774+
775+
The method used to calculate these MACs depends upon the value of the
776+
`message_authentication_code` property in the [`m.key.verification.accept`](#mkeyverificationaccept)
777+
message. All current implementations should use the `hkdf-hmac-sha256.v2` method which is
778+
defined as follows:
779+
780+
The MAC used is HMAC as defined in [RFC
781+
5869](https://tools.ietf.org/html/rfc5869), using SHA-256 as the hash
782+
function. The shared secret is supplied as the input keying material. No salt
783+
is used, and in the info parameter is the concatenation of:
784+
785+
- The string `MATRIX_KEY_VERIFICATION_MAC`.
786+
- The Matrix ID of the user whose key is being MAC-ed.
787+
- The Device ID of the device sending the MAC.
788+
- The Matrix ID of the other user.
789+
- The Device ID of the device receiving the MAC.
790+
- The `transaction_id` being used.
791+
- The Key ID of the key being MAC-ed, or the string `KEY_IDS` if the
792+
item being MAC-ed is the list of key IDs.
793+
794+
If a key is being MACed, the MAC is performed on the public key as encoded
795+
according to the [key algorithm](#key-algorithms). For example, for `ed25519`
796+
keys, it is the unpadded base64-encoded key.
797+
798+
If the key list is being MACed, the list is sorted lexicographically and
799+
comma-separated with no extra whitespace added, with each key written in the
800+
form `{algorithm}:{keyId}`. For example, the key list could look like:
801+
`ed25519:Cross+Signing+Key,ed25519:DEVICEID`. In this way, the recipient can
802+
reconstruct the list from the names in the `mac` property of the
803+
`m.key.verification.mac` message and ensure that no keys were added or removed.
804+
805+
The MAC values are base64-encoded and sent in a
806+
[`m.key.verification.mac`](#mkeyverificationmac) message.
807+
808+
{{% boxes/note %}}
809+
The MAC method `hkdf-hmac-sha256` used an incorrect base64 encoding, due to a
810+
bug in the original implementation in libolm. To remedy this,
811+
`hkdf-hmac-sha256.v2` was introduced, which calculates the MAC in the same way,
812+
but uses a correct base64 encoding. `hkdf-hmac-sha256` is deprecated and will
813+
be removed in a future version of the spec. Use of `hkdf-hmac-sha256` should
814+
be avoided whenever possible: if both parties support `hkdf-hmac-sha256.v2`,
815+
then `hkdf-hmac-sha256` MUST not be used.
816+
{{% /boxes/note %}}
817+
818+
###### SAS HKDF calculation
771819

772820
In all of the SAS methods, HKDF is as defined in [RFC
773821
5869](https://tools.ietf.org/html/rfc5869) and uses the previously
@@ -815,23 +863,9 @@ HKDF is used over the plain shared secret as it results in a harder
815863
attack as well as more uniform data to work with.
816864
{{% /boxes/rationale %}}
817865

818-
For verification of each party's device keys, HKDF is as defined in RFC
819-
5869 and uses SHA-256 as the hash function. The shared secret is
820-
supplied as the input keying material. No salt is used, and in the info
821-
parameter is the concatenation of:
822-
823-
- The string `MATRIX_KEY_VERIFICATION_MAC`.
824-
- The Matrix ID of the user whose key is being MAC-ed.
825-
- The Device ID of the device sending the MAC.
826-
- The Matrix ID of the other user.
827-
- The Device ID of the device receiving the MAC.
828-
- The `transaction_id` being used.
829-
- The Key ID of the key being MAC-ed, or the string `KEY_IDS` if the
830-
item being MAC-ed is the list of key IDs.
831-
832866
###### SAS method: `decimal`
833867

834-
Generate 5 bytes using [HKDF](#hkdf-calculation) then take sequences of 13 bits
868+
Generate 5 bytes using [HKDF](#sas-hkdf-calculation) then take sequences of 13 bits
835869
to convert to decimal numbers (resulting in 3 numbers between 0 and 8191
836870
inclusive each). Add 1000 to each calculated number.
837871

@@ -849,7 +883,7 @@ separator, such as dashes, or with the numbers on individual lines.
849883

850884
###### SAS method: `emoji`
851885

852-
Generate 6 bytes using [HKDF](#hkdf-calculation) then split the first 42 bits
886+
Generate 6 bytes using [HKDF](#sas-hkdf-calculation) then split the first 42 bits
853887
into 7 groups of 6 bits, similar to how one would base64 encode
854888
something. Convert each group of 6 bits to a number and use the
855889
following table to get the corresponding emoji:

data/event-schemas/examples/m.key.verification.accept.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"method": "m.sas.v1",
66
"key_agreement_protocol": "curve25519",
77
"hash": "sha256",
8-
"message_authentication_code": "hkdf-hmac-sha256",
8+
"message_authentication_code": "hkdf-hmac-sha256.v2",
99
"short_authentication_string": ["decimal", "emoji"],
1010
"commitment": "fQpGIW1Snz+pwLZu6sTy2aHy/DYWWTspTJRPyNp0PKkymfIsNffysMl6ObMMFdIJhk6g6pwlIqZ54rxo8SLmAg"
1111
}

data/event-schemas/examples/m.key.verification.start$m.sas.v1.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"method": "m.sas.v1",
77
"key_agreement_protocols": ["curve25519"],
88
"hashes": ["sha256"],
9-
"message_authentication_codes": ["hkdf-hmac-sha256"],
9+
"message_authentication_codes": ["hkdf-hmac-sha256.v2", "hkdf-hmac-sha256"],
1010
"short_authentication_string": ["decimal", "emoji"]
1111
}
1212
}

data/event-schemas/schema/m.key.verification.accept.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ properties:
2626
message_authentication_code:
2727
type: string
2828
description: |-
29-
The message authentication code the device is choosing to use, out of
29+
The message authentication code method the device is choosing to use, out of
3030
the options in the `m.key.verification.start` message.
3131
short_authentication_string:
3232
type: array

data/event-schemas/schema/m.key.verification.mac.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ allOf:
33
- $ref: core-event-schema/event.yaml
44

55
description: |-
6-
Sends the MAC of a device's key to the partner device.
6+
Sends the MAC of a device's key to the partner device. The MAC is calculated
7+
using the method given in `message_authentication_code` property of the
8+
`m.key.verification.accept` message.
79
properties:
810
content:
911
properties:

data/event-schemas/schema/m.key.verification.start$m.sas.v1.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,11 @@ properties:
4141
message_authentication_codes:
4242
type: array
4343
description: |-
44-
The message authentication codes that the sending device understands.
45-
Must include at least `hkdf-hmac-sha256`.
44+
The message authentication code methods that the sending device understands.
45+
Must include at least `hkdf-hmac-sha256.v2`. Should also include
46+
`hkdf-hmac-sha256` for compatibility with older clients, though this
47+
identifier is deprecated and will be removed in a future version of
48+
the spec.
4649
items:
4750
type: string
4851
short_authentication_string:

0 commit comments

Comments
 (0)