Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

New RFC: 43/WAKU2-NOISE-PAIRING #531

Merged
merged 10 commits into from
Sep 12, 2022
Merged

New RFC: 43/WAKU2-NOISE-PAIRING #531

merged 10 commits into from
Sep 12, 2022

Conversation

s1fr0
Copy link
Contributor

@s1fr0 s1fr0 commented Sep 1, 2022

In vacp2p/research#130 we request a protocol to allow 2 devices belonging to the same user to securely authenticate themselves and exchange (potentially sensitive) information.

In vacp2p/research#134 a research write-up is proposed and reviewed that can fit such need.

This PR addresses the second item of waku-org/nwaku#1065 by proposing an RFC based on the work and discussions in vacp2p/research#134 and waku-org/nwaku#1081.

EDIT: I updated the 35/WAKU2-NOISE RFC to reflect the new message nametag logic.

- an 8-digits authorization code `authcode` obtained as `HKDF(h) mod 10^8` is displayed on the device, where `h`is the handshake value obtained once the first handshake message is processed.

3. The device `B`:
- listens to messages sent to `/{application-name}/{application-version}/wakunoise/1/sessions-{shard-id}/proto` and locally filters only those with [Waku payload](https://rfc.vac.dev/spec/35/#abnf) starting with `messageNametag`. If any, continues.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://rfc.vac.dev/spec/35/#abnf specifies a specific format that does not have a messageNameTag at the start of the payload. I am guessing we should update 35/WAKU2-NOISE then? or should messageNameTag be set at the start of transport-message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, of course. I expect to update the RFC and implementation by today. I think the less painful way will be to expand PayloadV2 to have an extra nametag field, but I'll figure it out better once I start the refactoring (in any case a PayloadV2 with its fields is serialized to a Wakumessage payload, so the position of the nametag matters only withing the noise module).

Comment on lines +165 to +167
and should be flexible enough to mutually authenticate
and allow exchange of cryptographic key material
between two devices over a distributed network of Waku2 nodes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we broaden the scope of this RFC to enable communication between any device then? Current scope is "same user devices).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fair point. Indeed I can see many applications where devices not necessarily need to belong to the same user (this scope was due to the Noise session mechanism).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed references to same user devices in 2d38d52

Comment on lines +226 to +227
We note that since the `ChaChaPoly` cipher used to encrypt messages supports *additional data*,
an encrypted payload can be further authenticated by passing the `messageNametag` as additional data to the encryption/decryption routine.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, you are proposing to set messageNameTag at the start of the payload, so I am guessing you are not proposing to use the additional data feature of ChaChaPoly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I'm proposing to use the additional data feature of ChaChaPoly to authenticate the nametag. This will create a binding order between exchanged messages and it won't be possible by later crafting/changing the nametag for a waku message to claim that this was sent/received before/later without invalidating the encryption (here the malicious party is the store node/relayer).

Copy link
Contributor

@jm-clius jm-clius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this is a good draft! Would like to hear feedback from client team as well, though, in terms of usefulness, complexity in implementing, etc. cc @Samyoul

- decrypts the commitment `H(sA||s)` for `A`'s static key `sA`.
- an 8 decimal digits authorization code `authcode` obtained as `HKDF(h) mod 10^8` is displayed on the device, where `h`is the [handshake hash value](https://noiseprotocol.org/noise.html#overview-of-handshake-state-machine) obtained once the first handshake message is processed.

4. Device `A` and `B` wait the user to confirm with an interaction (button press)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
4. Device `A` and `B` wait the user to confirm with an interaction (button press)
4. Device `A` and `B` wait for the user to confirm with an interaction (button press)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in f44f3ba

- decrypts the received message and obtains the public key `sB`. If `sB` is not a valid public key, the protocol is aborted.
- performs `DH(eA,sB)` (which updates a symmetric encryption key);
- decrypts the payload to obtain the randomness `r`.
- Computes `H(sB||r)` and checks if this value corresponds to the commitment obtained in step 2. If not, the protocol is aborted.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Computes `H(sB||r)` and checks if this value corresponds to the commitment obtained in step 2. If not, the protocol is aborted.
- computes `H(sB||r)` and checks if this value corresponds to the commitment obtained in step 2. If not, the protocol is aborted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in f44f3ba

- performs `DH(sA,eB)` (which updates the symmetric encryption key);
- performs `DH(sA,sB)` (which updates the symmetric encryption key);
- attaches as payload the (encrypted) commitment randomness `s` used to compute `H(sA||s)`.
- Calls Split() and obtains two cipher states to encrypt inbound and outbound messages.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Calls Split() and obtains two cipher states to encrypt inbound and outbound messages.
- calls Split() and obtains two cipher states to encrypt inbound and outbound messages.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in f44f3ba

@s1fr0
Copy link
Contributor Author

s1fr0 commented Sep 6, 2022

IMO this is a good draft! Would like to hear feedback from client team as well, though, in terms of usefulness, complexity in implementing, etc. cc @Samyoul

Thanks! In terms of implementation, this has been fully implemented in waku-org/nwaku#1117, including the message identification nametag logic.

Copy link
Contributor

@staheri14 staheri14 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description is much more clear than the initial research post, nice!
I left some comments. Will do a more thorough review by tomorrow.

content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Show resolved Hide resolved
Copy link
Contributor

@staheri14 staheri14 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the previous comments! Please see my other comments inline. The proposal looks good and solid, my comments are mostly around clarification of the design choices and how they fulfill the intended security objectives.

content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
### Rationale

- The device `B` exposes a commitment to its static key `sB` because:
- if the private key of `eB` is weak or gets compromised, an attacker can impersonate `B` by sending in message `c.` to device `A` his own static key and successfully complete the pairing phase. Note that being able to compromise `eB` is not contemplated by our security assumptions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAI understood, eB is transferred by QR code scan, right? then basically it does not get routed via Waku network. so even if it is weak, the attacker won't be able to see it, right? (I know it is part of the assumptions, but I am interested in the practical scenario and whether it is possible to get access to eB)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's correct. As you said, by assumption the QR and hence eB is known to the attacker: beside this, the only possibility I see for making eB public is that A intentionally leaks it.

Copy link
Contributor

@staheri14 staheri14 Sep 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification.
The way I see it is that (please let me know if I am missing something) even if eB is weak, the attacker can affect neither confidentiality nor the anonymity of the communication: (Note that in both scenarios below sB and r are transferred to Alice using QR code, but not as H(sB||r), although I think it would be even safe for Bob to not to send r as well)

  • if an attacker finishes up part c. (assuming eB is compromised) yet it will get stuck in part d. where sAsB is needed (I mean DH of sAsB). Lacking the knowledge of sB (I mean DL of sB) means the attacker would not end up with a valid cipher state like Alice, hence I think he would not be able to compromise data privacy. So, there will be no data confidentially breach.
  • As for anonymity (assuming that the DL of eB is known to the attacker), at stage d., the attacker cannot get access to sA because that is encrypted under a key derived from eAeB and eAsB, so for decrypting sA, the attacker lacks the knowledge of sB (i.e., DL of sB). So, it does not seem to affect the anonymity either (the attacker cannot understand Alice is the other end of communication)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the resulting pairing will look something like:

a.   <- eB, sB
     ...
b.   -> eA, eAeB, eAsB, sA, sAeB, sAsB  [authcode]

Which resembles X3DH.

What you said is correct, besides the fact that there is no anonymity on B's static key. If we keep your assumption that ephemeral keys can be compromised then here an attacker is more motivated in breaking eA instead so that can reproduce the whole chain eA, eAeB, eAsB and decrypt A's static key sA as well, affecting anonymity of both devices.

Note also that, in the current protocol, if any ephemeral key is compromised, i.e. either eA or eB, an attacker might be successful in executing the attack detailed here

The reason for such suggestion is due to the fact that if an attacker is able to compromise one of the ephemeral keys,
he might successfully realize an undetected MitM attack up to the `authcode` confirmation
(we note that compromising ephemeral keys is outside our and Noise security assumptions).
The attacker could indeed proceed as follows:
- intercepts the QR;
- blocks/delays the delivery of the pairing message `b.`;
- compromises `A` or `B` ephemeral key;
- recovers the genuine `authcode` that would have been generated by `A` and `B`;
- generates ~`10^8` random `t` values until the Noise processing of the message `b'. -> eC, eCeB {H(sC||t)} `, where `eC` and `sC` are the attacker ephemeral and static key, respectively, results in computing the same `authcode` as the one between `A` and `B`;
- delivers the message `b'. -> eC, eCeB {H(sC||t)}` to `B` (before `A` is able to deliver its message `b.`).
At this point `A` and `B` will observe the same `authcode` (and would then confirm it),
but `B` will process the attacker's ephemeral key `eC` instead of `eA`.
However, the attacker would not be able to open to device `A` the static key commitment `H(sB||s)` sent by device `B` out-of-band,
and the pairing will abort on `A` side before it reveals its static key.
Device `B`, instead, will successfully complete the pairing with the attacker.

(which is not MitM, since device A will abort the pairing with the attacker). Thus, being able to compromise ephemeral keys is a quite powerful assumption, although can be mitigated. I would say that the difference with your proposal is mainly on the anonymity side, i.e. not reveal B's static key while still authenticating it using commitments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point A and B will observe the same authcode
In the attack described above, I suspect that this happens i.e., that At this point AandBwill observe the sameauthcode given that the final authcode that is derived by B has a component of eC whereas A's auth code does not use that input.

My point in general is to have a clear adversarial model and only discuss design choices related to that adversarial model. This makes it easier to reason about the security of the protocol. Nevertheless, if there are additional protections in the protocol to defeat a slightly stronger adversarial scenario, they can be mentioned separately, but with a clear separation from the original adversarial model.

### Rationale

- The device `B` exposes a commitment to its static key `sB` because:
- if the private key of `eB` is weak or gets compromised, an attacker can impersonate `B` by sending in message `c.` to device `A` his own static key and successfully complete the pairing phase. Note that being able to compromise `eB` is not contemplated by our security assumptions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The beginning and the ending of this sentence contradict i.e., "if the private key of eB is weak or gets compromised" and "Note that being able to compromise eB is not contemplated by our security assumptions". I'd suggest only touching on the parts that the protocol is designed for.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The notes here are to stress the fact that this provides an extra security feature, even though the scenario is not contemplated by security assumptions.

content/docs/rfcs/43/README.md Outdated Show resolved Hide resolved
- Confirming the authentication code after processing message `b.` will ensure that no Man-in-the-Middle (MitM) can send a static key different than `sB`.

- The device `A` sends a commitment to its static key `sA` because:
- `A` cannot adaptively choose a static key based on the state of the Noise handshake at the end of message `b.`, i.e. after the authentication code is confirmed. Note that device `A` is trusted in our security assumptions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If A is trusted, then why should it want to change its static key at a later stage?

Copy link
Contributor Author

@s1fr0 s1fr0 Sep 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has a similar answer to vacp2p/research#134 (comment). The notes here are to stress the fact that this provides an extra security feature, even though the scenario is not contemplated by security assumptions.

Copy link
Contributor

@staheri14 staheri14 Sep 8, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quoting your reply from the prior PR

That's the purpose of the note, that is we're giving extra protection. Without commitments (and authcode) the first exchanges are completely not authenticated, hence B could send arbitrary static key to, for example:
get A's static key without revealing its real one (note that the hash can be binded in ZK to seed phrase to show the static key to come from same source of trust);
have an encrypted payload where the MSB bytes are set to a known value with consequences on anonymity;
etc.

Thanks for your explanation.
To me, B's static key is an arbitrary choice until before the pairing session starts. B has every right to pick any static key as long as it uses the same during the entire interaction (unless there are some other objectives that are not mentioned in the text)
I think the commitment idea is tightly bound to what adaptive static key selection means. The commitment is necessary to prevent the sender from manipulating its static keys for some reason. But that reason is not explained. Before starting the protocol, A has no clue about Bob's static key, then why A should care about Bob picking any static key even adaptively? Are we seeking something more than making a private and authenticated communication channel between two mutually trusted parties?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed in the text it is mentioned that devices' static keys might be bound to other cryptographic material, e.g. a seed phrase.

- by being the pairing requester, it cannot probe device `A` identity without revealing its own (static key) first. Note that device `B` static key and its commitment can be bound to other cryptographic material (e.g., seed phrase).

There is no clear plan yet, but it might be a possibility. For example a seed phrase is inserted on two devices (this proves that they belong to the same user) and then these exchange their static keys (that might come, for example, from a seed-based key derivation tree with input device's UID) using the pairing phase.

This is however not the main reason why the commitment measure is in place. By exchanging both static keys commitments before the authcode is shown to users, when the authcode is confirmed, such confirmation would implicitly authenticate the static keys as well. And such implicit static keys authentication will happen in an earlier stage of the pairing while static keys are still unknown/anonymous to both devices so that if the authcode verification fails, the attacker attempting a MitM will learn nothing about devices static keys.

Copy link
Contributor

@staheri14 staheri14 Sep 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point, just the assumptions and the adversarial power is somewhat unclear.

In my view, I see the following adversarial powers:

  1. An attacker who eavesdrops on the QR code
  2. An attacker who eavesdrops and injects data during the QR code
  3. a passive MIM attacker (in a p2p network)
  4. a active MIM attacker (in a p2p network)
  5. An attacker that compromises eA and eB
  6. An attacker that compromises sA and sB

The commitment of B on sB||r is to provide anonymity against adversary # 1
The commitment on H(sA||s) is to protect A's anonymity against an attacker with the capability of # 2, # 4, and # 5

And the current protocol design only considers an adversary who is capable of # 1, # 3 and # 4.


- The authorization code is shown and has to be confirmed at the end of message `b.` because:
- an attacker that frontruns device `A` by sending faster his own ephemeral key would be detected before he's able to know device `B` static key `sB`;
- it ensures that no MitM attacks will happen during *the whole* pairing handshake, since commitments to the (later exchanged) device static keys will be implicitly acknowledged by the authorization code confirmation;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there should be more to the commitment idea (which is not explained in the text), as for example, sending sB and r instead of the commitment H(sB||r) at step a. would also do the job, because A can persist r and later checks whether the same r is being sent at step c..
The same holds for H(sA||s), i.e., A can send sA and s at step b. and later resends s in step d. so that B can do consistency check. Since the message sent at b. is already encrypted, it is protected against eavesdroppers. Please let me know if I am missing something in here.
In general, I like the idea of commitment, but I think the supplied rationale does not cover all the aspects you had in mind.
One suggestion is that to enumerate the security objectives of the protocol and then relate each design choice to that objective e.g., 1) MiM secure: the protocol is supposed to be secure against MiM, or 2) Anonymous: the protocol is designed to be anonymous such that the static keys of the sender and the receiver remain unknown throughout the protocol, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it is for anonymity purposes: in your proposal, devices would expose their static keys before authenticating each other. An anonymous attacker can then probe static keys and potentially trace activities (this is especially true for device B since it is the one that would send - out-of-band, though - its key unencrypted).

Clarified security objectives of pairing in 05935ab

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, how would you argue about the part that the static key of Bob is exchanged using QR but not via a p2p network? So, anonymity is preserved by design. I mean, the commitment of sB does not seem necessary given that the interaction is entirely offline and face-to-face.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there is any type of attack that can happen in the QR code interaction, that is worth highlighting in the text.

Copy link
Contributor Author

@s1fr0 s1fr0 Sep 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can have MitM attacks indeed, the QR is known to the attacker so might reply faster than A to B. Only when the authcode is confirmed (and the pairing completes with no aborts), this will ensure that no MitM happened since the beginning thanks to the exchanged commitments. See also #531 (comment)

@Samyoul
Copy link
Member

Samyoul commented Sep 8, 2022

@s1fr0 @jm-clius Thank you for ccing me into this.

So from a usage perspective this will be useful for us, it is will allow us to move our current implementation https://notes.status.im/4VbZ0PlKR0GBE4d_A-qG_A , into a network agnostic environment where the devices do not need to connect directly.

There are some technical implementation problems to overcome, such as creating and managing ephemeral keys to access the contentTopic via the status-go Messenger, but the flow seems logical and implementable.

One question. This work presumes that there is no intrinsic objection to sending private key data over the wire, outside of the local network, encrypted or otherwise. So in principle we don't have a problem with transporting through the public network private keys and associated meta data?

@s1fr0
Copy link
Contributor Author

s1fr0 commented Sep 8, 2022

Thanks @Samyoul for your feedback!

Regarding your question: sensitive data reaches the network only in encrypted form. Besides A's ephemeral key which is sent unencrypted (but we can easily change this to be encrypted with a key passed out-of-band by B), all the successive messages will be encrypted (and the authcode confirmation ensures no MitM is taking / can take place).

Note that any after-handshake Waku message will be exchanged with no metadata attached. At the moment: protocol-id is set to 0, payloads will be padded to a size of 16+n*248 bytes, Waku messages will be exchanged under the same fixed content-topic, and parties will efficiently identify encrypted messages addressed to them using the 16bytes random-looking messageNametag embedded in the payload (which can be computed only by communicating parties). This is because we want all Noise-RFC compliant Waku messages (i.e. that use payload version 2) to look all alike and be indistinguishable from each other, at least for the one exchanged after the handshake phase.

In other words, the security level we provide for exchanging encrypted private keys over the Waku network is the same as the one adopted to protect any message. And we want/trying to achieve the best we can, regardless of the kind of encrypted information exchanged.

@s1fr0 s1fr0 requested a review from staheri14 September 8, 2022 16:54
@s1fr0
Copy link
Contributor Author

s1fr0 commented Sep 8, 2022

@jm-clius @staheri14 @fryorcraken I updated in this PR the Noise RFC as well to reflect the new message nametag identification logic proposed/mentioned here.

@Samyoul
Copy link
Member

Samyoul commented Sep 9, 2022

@s1fr0 Ok thank you, key payloads are indistinguishable from other payloads on the network. I suppose that the keys (encrypted) would only be vulnerable to a minority of state level actors that have collected all Waku payloads and have futuristic quantum level computational capabilities to brute force each message payload until they find a payload that contained keys. Which would presumably pose such a computational burden that there would be more cost efficient methods of compromising a target's communications.

@s1fr0
Copy link
Contributor Author

s1fr0 commented Sep 9, 2022

@Samyoul Regarding the underlying ChaChaPoly encryption, it is -at the moment- considered safe from quantum threats (Grover's algorithm) with a security level of 128 bits (instead of 256 given for a classical attacker). You can find a nice short security recap on ChaChaPoly here.

Here we do not make any security assumption with respect to a quantum attacker: the key exchange is based on Diffie-Hellman operations which are, in turn, based on the DLOG assumption that doesn't hold in a quantum setting.
Hence a quantum attacker will most probably attack the key-exchange mechanism rather than the underlying symmetric encryption. However, in the pairing phase, one ephemeral key is exchanged out-of-band and a passive quantum network attacker would need a 2^128 Grover's search (curve's private keys/point coordinates are ~256 bits) to guess the right ephemeral key, compromise the whole pairing handshake and recover the encryption key.

Copy link
Contributor

@staheri14 staheri14 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some more comments mostly related to expanding on and clarifying the exact intended adversarial model. Rather than those, the rest of the RFC looks nice and reasonable to me!

it will be possible for the attacker not only to decrypt messages encrypted under that key,
but also all those messages encrypted under any successive new key obtained through a call to `Rekey()`.

This can be mitigated by:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be helpful to explain why these strategies can mitigate the issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in e77d514


This can be mitigated by:
- keeping the full Handhshake State even after the handshake is complete (*by Noise specification a call to [`Split()`](http://www.noiseprotocol.org/noise.html#the-symmetricstate-object) should delete the Handshake State*)
- continuing updating the Handshake State by processing every after-handshake exchanged message (i.e. the `payload`) according to the Noise [processing rules](http://www.noiseprotocol.org/noise.html#processing-rules) (i.e. by calling `EncryptAndHash(payload)` and `DecryptAndHash(payload)`);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose payload is unknown to the attacker and that is why the successive keys remain hidden from the attacker, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plaintext payload yes. But that's not the reason why keys are "hidden". Keys are derived from the handshake state after processing exchanged messages (hashing payloads, doing Diffie-Hellman with ephemeral keys, etc.). Here, the randomization comes from the ephemeral key attached.

This can be mitigated by:
- keeping the full Handhshake State even after the handshake is complete (*by Noise specification a call to [`Split()`](http://www.noiseprotocol.org/noise.html#the-symmetricstate-object) should delete the Handshake State*)
- continuing updating the Handshake State by processing every after-handshake exchanged message (i.e. the `payload`) according to the Noise [processing rules](http://www.noiseprotocol.org/noise.html#processing-rules) (i.e. by calling `EncryptAndHash(payload)` and `DecryptAndHash(payload)`);
- adding to each (or every few) message exchanged in the transfer phase a random ephemeral key `e` and perform Diffie-Hellman operations with the other party's ephemeral/static keys in order to update the underlying CipherState and recover new random inbound/outbound encryption keys by calling [`Split()`](http://www.noiseprotocol.org/noise.html#the-symmetricstate-object).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think e can be deleted after updating the cipher state. If yes, then would be worth mentioning it here.
Btw, is this approach secure against a passive MiM attacker who can listen to the p2p network messages?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e will have a very specific place in Alice and Bob handshake states (that here are not deleted), and are refreshed as new ephemeral keys are received. Note that at this point payloads are authenticated since the handshake is complete, hence an attacker cannot sent authenticated messages with its own key. Even if a static key is compromised (with which the DH with the ephemeral is done), the attacker will be able to compute the DH secret, but to compute the key needs the ck and h of the handshake state.

The derivation of `messageNametag` should be deterministic only for communicating devices
and independent from message content,
otherwise lost messages will prevent computing the next message nametag.
A possible approach consists in computing the `n`-th `messageNametag` as `H( ctsInbound || n)`,
Copy link
Contributor

@staheri14 staheri14 Sep 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If one wishes to use the rekeying solution sketched in the prior section, then ctsInbound is a function of the ephemeral key embedded in the messages, thus lost messages would cause issues in computing the next message nametag (or not?) if it becomes problematic, I'd explain it in the spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rekey is only after-handshake, while the nametag secrets are computed during the pairing phase/handshake (ideally at the end on Split). Made it clearer in e77d514


```
WakuPairing:
a. <- eB {H(sB||r), contentTopicParams, messageNametag}
Copy link
Contributor

@staheri14 staheri14 Sep 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why messageNameTag is needed, it is explained in the RFC?
Isn't the contentTopic enough already to filter messages belonging to the current communication? I assume messageNameTag is to reduce the number of tries and failures for decrypting messages not belonging to the current communication, right? In such a case, the more unique the messageNameTag the less conversational anonymity is yielded. Would be good to explain it in the specs to let developers make a more informed decision on the trade-offs associated with the uniqueness of messageNameTag.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was well known even before when we had only content topics, i.e. that the first 1RTT communication can be identified (here 0.5 RTT is out-of-band). This was described in the RFC in

## After-handshake
and
#### Content Topics and Message Nametags of Noise Handshake Messages
now updated to the nametag lexicon

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
track:conversational-security Conversational security track (Secure Messaging) track:waku-specs Waku specs track (RAD)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants