35/WAKU2-NOISE #
Noise Protocols for Waku Payload Encryption #
- Status: raw
- Editor: Giuseppe giuseppe@status.im
This specification describes how payloads of Waku messages with version 2 can be encrypted in order to achieve confidentiality, authenticity, and integrity as well as some form of identity-hiding on communicating parties.
This specification extends the functionalities provided by 26/WAKU-PAYLOAD, adding support to modern symmetric encryption primitives and asymmetric key-exchange protocols.
Specifically, it adds support to the ChaChaPoly
cipher for symmetric authenticated encryption.
It further describes how the Noise Protocol Framework can be used to exchange cryptographic keys and encrypt/decrypt messages
in a way that the latter are authenticated and protected by strong forward secrecy.
This ultimately allows Waku applications to instantiate end-to-end encrypted communication channels with strong conversational security guarantees, as similarly done by 5/SECURE-TRANSPORT but in a more modular way, adapting key-exchange protocols to the knowledge communicating parties have of each other.
Design requirements #
- Confidentiality: the adversary should not be able to learn what data is being sent from one Waku endpoint to one or several other Waku endpoints.
- Strong forward secrecy: an active adversary cannot decrypt messages nor infer any information on the employed encryption key, even in the case he has access to communicating parties’ long-term private keys (during or after their communication).
- Authenticity: the adversary should not be able to cause a Waku endpoint to accept messages coming from an endpoint different than their original senders.
- Integrity: the adversary should not be able to cause a Waku endpoint to accept data that has been tampered with.
- Identity-hiding: once a secure communication channel is established, a passive adversary should not be able to link exchanged encrypted messages to their corresponding sender and recipient.
Supported Cryptographic Protocols #
Noise Protocols #
Two parties executing a Noise protocol exchange one or more handshake messages and/or transport messages. A Noise protocol consists of one or more Noise handshakes. During a Noise handshake, two parties exchange multiple handshake messages. A handshake message contains ephemeral keys and/or static keys from one of the parties and an encrypted or unencrypted payload that can be used to transmit optional data. These public keys are used to perform a protocol-dependent sequence of Diffie-Hellman operations, whose results are all hashed into a shared secret key. After a handshake is complete, each party will then use the derived shared secret key to send and receive authenticated encrypted transport messages. We refer to Noise protocol framework specifications for the full details on how parties shared secret key is derived from each exchanged message.
Four Noise handshakes are currently supported: K1K1
, XK1
, XX
, XXpsk0
. Their description can be found in Appendix: Supported Handshakes Description.
These are instantiated combining the following cryptographic primitives:
Curve25519
for Diffie-Hellman key-exchanges (32 bytes curve coordinates);ChaChaPoly
for symmetric authenticated encryption (16 bytes authentication tag);SHA256
hash function used inHMAC
andHKDF
keys derivation chains (32 bytes output size);
Content Topics and Message Nametags of Noise Handshake Messages #
We note that all design requirements on exchanged messages would be satisfied only after a supported Noise handshake is completed,
corresponding to a total of 1 Round Trip Time communication (1-RTT).
In particular, identity-hiding properties can be guaranteed only if the recommendation described in After-handshake are implemented.
In the following, we assume that communicating parties reciprocally know an initial contentTopic
where they can send/receive the first handshake message(s).
We further assume that messages sent over a certain contentTopic
can be efficiently identified by their intended recipients
thanks to an arbitrary 16 bytes long message-nametag
field embedded in the message payload
which is known in advance before messages reception.
The second handshake message MAY be sent/received with a message-nametag
deterministically derived from the handshake state obtained after processing the first handshake message
(using, for example, HKDF
over the handshake hash value h
).
This allows
- the recipient to efficiently continue the handshakes started by each initiator;
- the initiators to efficiently associate the recipient’s second handshake message to their first handshake message, However, this does not provide any identity-hiding guarantee to the recipient.
After the second handshake message is correctly received by initiators, the recommendation described in After-handshake SHOULD be implemented to provide full identity-hiding guarantees for both initiator and recipient against passive attackers.
Encryption Primitives #
The symmetric primitives supported are:
ChaChaPoly
for authenticated encryption (16 bytes authentication tag).
Specification #
When 14/WAKU-MESSAGE version is set to 2,
the corresponding WakuMessage
’s payload
will encapsulate the two fields handshake-message
and transport-message
.
The handshake-message
field MAY contain
- a Noise handhshake message (only encrypted/unencrypted public keys).
The transport-message
field MAY contain
- a Noise handshake message payload (encrypted/unencrypted);
- a Noise transport message;
- a
ChaChaPoly
ciphertext.
When a transport-message
encodes a ChaChaPoly
ciphertext, the corresponding handshake-message
field MUST be empty.
The following fields are concatenated to form the payload
field:
message-nametag
: an arbitrary identifier for the Waku message (16 byte). If the underlying encryption primitive supports it, the contents of this field SHOULD be passed as additional data to the encryption and decryption routines.protocol-id
: identifies the protocol or primitive in use (1 byte). Supported values are:0
: protocol specification omitted (set for after-handshake messages);10
: Noise protocolNoise_K1K1_25519_ChaChaPoly_SHA256
;11
: Noise protocolNoise_XK1_25519_ChaChaPoly_SHA256
;12
: Noise protocolNoise_XX_25519_ChaChaPoly_SHA256
;13
: Noise protocolNoise_XXpsk0_25519_ChaChaPoly_SHA256
;30
:ChaChaPoly
symmetric encryption.
handshake-message-len
: the length in bytes of the Noise handshake message (1 byte). Ifprotocol-id
is not equal to0
,10
,11
,12
,13
, this field MUST be set to0
;handshake-message
: the Noise handshake message (handshake-message-len
bytes). Ifhandshake-message-len
is not0
, it contains the concatenation of one or more Noise Diffie-Hellman ephemeral or static keys encoded as in Public Keys Encoding;transport-message-len
: the length in bytes oftransport-message
(8 bytes, stored in Little-Endian);transport-message
: the transport message (transport-message-len
bytes); Only during a Noise handshake, this field would contain the Noise handshake message payload. The symmetric encryption authentication data fortransport-message
, when present, is appended at the end oftransport-message
(16 bytes).
ABNF #
Using Augmented Backus-Naur form (ABNF) we have the following format:
; message nametag
message-nametag = 16OCTET
; protocol ID
protocol-id = 1OCTET
; contains the size of handshake-message
handshake-message-len = 1OCTET
; contains one or more Diffie-Hellman public keys
handshake-message = *OCTET
; contains the size of transport-message
transport-message-len = *OCTET
; contains the transport message, eventually encrypted.
; If encrypted, authentication data is appended
transport-message = *OCTET
; the Waku WakuMessage payload field
payload = message-nametag protocol-id handshake-message-len handshake-message transport-message-len transport-message
Protocol Payload Format #
Based on the specified protocol-id
,
the Waku message payload
field will encode different types of protocol-dependent messages.
In particular, if protocol-id
is
0
: payload encodes an after-handshake message.handshake-message-len
MAY be 0;transport-message
contains the Noise transport message;
10
,11
,12
,13
: payload encodes a supported Noise handshake message.transport-message
contains the Noise transport message;
30
: payload encapsulate aChaChaPoly
ciphertextct
.handshake-message-len
is set to0
;transport-message
contains the concatenation of the encryption nonce (12 bytes) followed by the ciphertextct
and the authentication data forct
(16 bytes);transport-message-len
is set accordingly totransport-message
length;
Public Keys Serialization #
Diffie-Hellman public keys can be trasmitted in clear
or in encrypted form (cf. WriteMessage
) with authentication data attached.
To distinguish between these two cases, public keys are serialized as the concatenation of the following three fields:
flag
: is equal to1
if the public key is encrypted;0
otherwise (1 byte);pk
: ifflag = 0
, it contains an encoding of the X coordinate of the public key. Ifflag = 1
, it contains a symmetric encryption of an encoding of the X coordinate of the public key, followed by encryption’s authentication data;
The corresponding serialization is obtained as flag pk
.
As regards the underlying supported cryptographic primitives:
Curve25519
public keys X coordinates are encoded in little-endian as 32 bytes arrays;ChaChaPoly
authentication data consists of 16 bytes (nonces are implicitely defined by Noise processing rules).
In all supported Noise protocols,
parties’ static public keys are transmitted encrypted (cf. EncryptAndHash
),
while ephemeral keys MAY be encrypted after a handshake is complete.
Padding #
To prevent some metadata leakage, encrypted transport messages SHOULD be padded before encryption.
It is therefore recommended to right pad transport messages using RFC2630 so that their final length is a multiple of 248 bytes.
After-handshake #
During the initial 1-RTT communication,
handshake messages might be linked,
depending on the message-nametag
derivation rule implemented,
to the respective parties through the contentTopic
and message-nametag
fields employed for such communication.
After a handshake is completed,
parties MAY derive from their shared secret key (preferably using HKDF
)
two random nametag-secret-outbound
and nametag-secret-inbound
values used to deterministically derive
two arbitrary-long ordered lists of message-nametag
used to indentify outbound and inbound messages, respectively
(e.g. the n
-th inbound message-nametag
MAY be computed as HKDF(nametag-secret-inbound || n)
).
This allows communicating parties to efficiently identify messages addressed to them sent over a certain contentTopic
and thus minimize the number of trial decryptions.
When communicating,
parties SHOULD set protocol-id
to 0
to reduce metadata leakages and indicate that the message is an after-handshake message.
Each party SHOULD attach an (unencrypted) ephemeral key in handshake-message
to every message sent.
According to Noise processing rules,
this allows updates to the shared secret key
by hashing the result of an ephemeral-ephemeral Diffie-Hellman exchange every 1-RTT communication.
Backward Support for Symmetric/Asymmetric Encryption #
It is possible to have backward compatibility to symmetric/asymmetric encryption primitives from 26/WAKU-PAYLOAD, effectively encapsulating payload encryption 14/WAKU-MESSAGE version 1 in version 2.
It suffices to extend the list of supported protocol-id
to:
254
: AES-256-GCM symmetric encryption;255
: ECIES asymmetric encryption.
and set the transport-message
field to the 26/WAKU-PAYLOAD data
field, whenever these protocol-id
values are set.
Namely, if protocol-id = 254, 255
then:
message-nametag
: is empty;handshake-message-len
: is set to0
;handshake-message
: is empty;transport-message
: contains the 26/WAKU-PAYLOADdata
field (AES-256-GCM or ECIES, depending onprotocol-id
);transport-message-len
is set accordingly totransport-message
length;
When a transport-message
corresponding to protocol-id = 254, 255
is retrieved,
it SHOULD be decoded as the data
field in 26/WAKU-PAYLOAD specification.
Appendix: Supported Handshakes Description #
Supported Noise handshakes address four typical scenarios occurring when an encrypted communication channel between Alice and Bob is going to be created:
- Alice and Bob know each others’ static key.
- Alice knows Bob’s static key;
- Alice and Bob share no key material and they don’t know each others’ static key.
- Alice and Bob share some key material, but they don’t know each others’ static key.
Adversarial Model: an active attacker who compromised one party’s static key may lower the identity-hiding security guarantees provided by some handshakes. In our security model we exclude such adversary, but for completeness we report a summary of possible de-anonymization attacks that can be performed by an active attacker.
The K1K1
Handshake
#
If Alice and Bob know each others’ static key (e.g., these are public or were already exchanged in a previous handshake) , they MAY execute a K1K1
handshake. Using Noise notation (Alice is on the left) this can be sketched as:
K1K1:
-> s
<- s
...
-> e
<- e, ee, es
-> se
We note that here only ephemeral keys are exchanged. This handshake is useful in case Alice needs to instantiate a new separate encrypted communication channel with Bob, e.g. opening multiple parallel connections, file transfers, etc.
Security considerations on identity-hiding (active attacker): no static key is transmitted, but an active attacker impersonating Alice can check candidates for Bob’s static key.
The XK1
Handshake
#
Here, Alice knows how to initiate a communication with Bob and she knows his public static key: such discovery can be achieved, for example, through a publicly accessible register of users’ static keys, smart contracts, or through a previous public/private advertisement of Bob’s static key.
A Noise handshake pattern that suits this scenario is XK1
:
XK1:
<- s
...
-> e
<- e, ee, es
-> s, se
Within this handshake, Alice and Bob reciprocally authenticate their static keys s
using ephemeral keys e
. We note that while Bob’s static key is assumed to be known to Alice (and hence is not transmitted), Alice’s static key is sent to Bob encrypted with a key derived from both parties ephemeral keys and Bob’s static key.
Security considerations on identity-hiding (active attacker): Alice’s static key is encrypted with forward secrecy to an authenticated party. An active attacker initiating the handshake can check candidates for Bob’s static key against recorded/accepted exchanged handshake messages.
The XX
and XXpsk0
Handshakes
#
If Alice is not aware of any static key belonging to Bob (and neither Bob knows anything about Alice), she can execute an XX
handshake, where each party tranXmits to the other its own static key.
The handshake goes as follows:
XX:
-> e
<- e, ee, s, es
-> s, se
We note that the main difference with XK1
is that in second step Bob sends to Alice his own static key encrypted with a key obtained from an ephemeral-ephemeral Diffie-Hellman exchange.
This handshake can be slightly changed in case both Alice and Bob pre-shares some secret psk
which can be used to strengthen their mutual authentication during the handshake execution. One of the resulting protocol, called XXpsk0
, goes as follow:
XXpsk0:
-> psk, e
<- e, ee, s, es
-> s, se
The main difference with XX
is that Alice’s and Bob’s static keys, when transmitted, would be encrypted with a key derived from psk
as well.
Security considerations on identity-hiding (active attacker): Alice’s static key is encrypted with forward secrecy to an authenticated party for both XX
and XXpsk0
handshakes. In XX
, Bob’s static key is encrypted with forward secrecy but is transmitted to a non-authenticated user which can then be an active attacker. In XXpsk0
, instead, Bob’s secret key is protected by forward secrecy to a partially authenticated party (through the pre-shared secret psk
but not through any static key), provided that psk
was not previously compromised (in such case identity-hiding properties provided by the XX
handshake applies).
References #
- 5/SECURE-TRANSPORT
- 10/WAKU2
- 26/WAKU-PAYLOAD
- 14/WAKU-MESSAGE
- Noise protocol
- Noise handshakes as key-exchange mechanism for Waku2
- Augmented Backus-Naur form (ABNF)
- RFC2630 - Content-encryption Process and padding
Copyright #
Copyright and related rights waived via CC0.