2016-04-04 12:51:03 +00:00
|
|
|
======
|
|
|
|
NTCP 2
|
|
|
|
======
|
|
|
|
.. meta::
|
2018-04-02 13:12:03 +00:00
|
|
|
:author: EinMByte, psi, str4d, zzz
|
2017-05-21 13:48:04 +00:00
|
|
|
:editor: manas, str4d
|
2016-04-04 12:51:03 +00:00
|
|
|
:created: 2014-02-13
|
|
|
|
:thread: http://zzz.i2p/topics/1577
|
2018-04-17 16:11:51 +00:00
|
|
|
:lastupdated: 2018-04-17
|
2016-04-25 06:09:22 +00:00
|
|
|
:status: Open
|
2016-04-10 07:17:19 +00:00
|
|
|
:supercedes: 106
|
2016-04-04 12:51:03 +00:00
|
|
|
|
|
|
|
.. contents::
|
|
|
|
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Note
|
|
|
|
====
|
2018-04-04 13:54:03 +00:00
|
|
|
Major revisions in progress. For now, not necessarily complete or even
|
|
|
|
consistent. Not ready for implementation.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
2016-04-25 06:09:22 +00:00
|
|
|
Overview
|
|
|
|
========
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
This proposal describes an authenticated key agreement protocol to improve the
|
|
|
|
resistance of [NTCP]_ to various forms of automated identification and attacks.
|
|
|
|
|
|
|
|
The proposal is organized as follows: the security goals are presented,
|
|
|
|
followed by a discussion of the basic protocol. Next, a complete specification
|
|
|
|
of all protocol messages is given. Finally, router addresses and version
|
|
|
|
identification are discussed. An appendix discussing a generic attack on common
|
|
|
|
padding schemes is also included, as well as an appendix containing a number of
|
|
|
|
candidates for the authenticated cipher.
|
2016-04-25 06:09:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
Motivation
|
|
|
|
==========
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
[NTCP]_ data is encrypted after the first message (and the first message
|
|
|
|
appears to be random data), thus preventing protocol identification through
|
|
|
|
"payload analysis". It is still vulnerable to protocol identification through
|
|
|
|
"flow analysis". That's because the first 4 messages (i.e. the handshake) are
|
|
|
|
fixed length (288, 304, 448, and 48 bytes).
|
2016-04-04 12:51:03 +00:00
|
|
|
|
|
|
|
By adding random amounts of random data to each of the messages, we can make it
|
|
|
|
a lot harder.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
The authors acknowledge that standard security practices would suggest to use
|
|
|
|
an existing protocol such as TLS, but this is [Prop104]_ and it has problems of
|
|
|
|
its own. Wherever appropriate, "future work" paragraphs have been added to
|
|
|
|
indicate missing features or subjects of discussion.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2016-04-25 06:09:22 +00:00
|
|
|
Design Goals
|
|
|
|
============
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
- Support NTCP 1 and 2 on a single port, auto-detect, and published as a single
|
|
|
|
"transport" (i.e. [RouterAddress]_) in the [NetDB]_.
|
|
|
|
|
|
|
|
- Publish support for version 1 only, 2 only, or 1+2 in the NetDB in a separate
|
|
|
|
field, and default to version 1 only (don't bind version support to a
|
|
|
|
particular router version)
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Ensure that all implementations (Java/i2pd/kovri/go) can add version 2
|
2017-05-21 13:48:04 +00:00
|
|
|
support (or not) on their own schedules
|
|
|
|
|
2016-04-04 12:51:03 +00:00
|
|
|
- Add random padding to all NTCP messages including handshake and data messages
|
|
|
|
(i.e. length obfuscation so all messages aren't a multiple of 16 bytes)
|
2016-09-27 14:32:12 +00:00
|
|
|
Provide options mechanism for both sides to request min and max padding
|
|
|
|
and/or padding distribution. Specifics of the padding distribution are
|
2017-05-21 13:48:04 +00:00
|
|
|
implementation-dependent and may or may not be specified in the protocol
|
|
|
|
itself.
|
|
|
|
|
|
|
|
- Obfuscate the contents of messages that aren't encrypted (1 and 2),
|
|
|
|
sufficiently so that DPI boxes and AV signatures can't easily classify them.
|
|
|
|
Also ensure that the messages going to a single peer or set of peers do not
|
|
|
|
have a similar pattern of bits.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- Fix loss of bits in DH due to Java format [Ticket1112]_, possibly (probably?)
|
|
|
|
by switching to X25519.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
- Switch to a real key derivation function (KDF) rather than using the DH
|
|
|
|
result as-is?
|
|
|
|
|
|
|
|
- Add "probing resistance" (as Tor calls it); this includes replay resistance.
|
|
|
|
|
|
|
|
- Maintain 2-way authenticated key exchange (2W-AKE). 1W-AKE is not sufficient
|
|
|
|
for our application.
|
|
|
|
|
|
|
|
- Continue to use the variable-type, variable-length signatures (from the
|
2018-04-04 13:54:03 +00:00
|
|
|
published [RouterIdentity]_ signing key) as a part of authentication. Rely
|
|
|
|
on a static public key published in the RouterInfo as another part of
|
|
|
|
authentication.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
- Add options/version in handshake for future extensibility.
|
|
|
|
|
|
|
|
- Add resistance to malicious MitM TCP segmentation if possible.
|
|
|
|
|
|
|
|
- Don't add significantly to CPU required for connection setup; if possible,
|
|
|
|
reduce it significantly.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- Add message authentication (MAC), possibly HMAC-SHA256 and Poly1305, and
|
|
|
|
remove Adler checksum.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
- Shorten and simplify I2NP header:
|
|
|
|
Shorten expiration to 4 bytes, as in SSU.
|
|
|
|
Remove one-byte truncated SHA256 checksum.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
- If possible, reduce the 4-message, two-round-trip handshake to a 3-message,
|
|
|
|
one-round-trip handshake, as in [SSU]_. This would require moving Bob's
|
|
|
|
signature in message 4 to message 2. Research the reason for 4 messages in
|
|
|
|
the ten-year-old email/status/meeting archives.
|
|
|
|
|
|
|
|
- Maintain timestamps for replay and skew detection.
|
|
|
|
|
|
|
|
- Avoid any year 2038 issues in timestamps, must work until at least 2106.
|
|
|
|
|
|
|
|
- Increase max message size from 16K to 32K or 64K.
|
|
|
|
|
|
|
|
- Any new crypto should be readily available in libraries for use in Java
|
|
|
|
(1.7), C++, and Go router implementations.
|
|
|
|
|
|
|
|
- Include representatives of Java, C++, and Go router developers in the design.
|
|
|
|
|
2016-09-17 16:09:19 +00:00
|
|
|
- Minimize changes (but there will still be a lot).
|
2016-07-03 18:42:21 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
- Support both versions in a common set of code (this may not be possible and
|
|
|
|
is implementation-dependent in any case).
|
2016-07-03 18:42:21 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2016-07-03 18:42:21 +00:00
|
|
|
Non-Goals
|
2017-05-21 13:48:04 +00:00
|
|
|
---------
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- Bullet-proof DPI resistance... that would be pluggable transports,
|
|
|
|
[Prop109]_.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
- A TLS-based (or HTTPS-lookalike) transport... that would be [Prop104]_.
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- It's ok to change the symmetric stream crypto.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2016-09-27 14:32:12 +00:00
|
|
|
- Timing-based DPI resistance (inter-message timing/delays can be
|
2017-05-21 13:48:04 +00:00
|
|
|
implementation-dependent; intra-message delays can be introduced at any
|
|
|
|
point, including before sending the random padding, for example). Artificial
|
|
|
|
delays (what obfs4 calls IAT or inter-arrival time) are independent of the
|
|
|
|
protocol itself.
|
|
|
|
|
|
|
|
- Deniability of participating in a session (there's signatures in there).
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Non-goals that may be partially reconsidered or discussed:
|
|
|
|
|
|
|
|
- The degree of protection against Deep Packet Inspection (DPI)
|
|
|
|
|
|
|
|
- Post-Quantum (PQ) security
|
|
|
|
|
|
|
|
- Deniability
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
2016-07-03 19:17:09 +00:00
|
|
|
Related Goals
|
2017-05-21 13:48:04 +00:00
|
|
|
-------------
|
2016-07-03 19:17:09 +00:00
|
|
|
|
|
|
|
- Implement a NTCP 1/2 test setup
|
|
|
|
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Security Goals
|
|
|
|
==============
|
|
|
|
|
|
|
|
We consider three parties:
|
|
|
|
|
|
|
|
- Alice, who wishes to establish a new session.
|
|
|
|
- Bob, with whom Alice wishes to establish a session.
|
|
|
|
- Mallory, the "man in the middle" between Alice and Bob.
|
|
|
|
|
|
|
|
At most two participants can engage in active attacks.
|
|
|
|
|
|
|
|
Alice and Bob are both in possession of a static key pair, which is contained
|
|
|
|
in their [RouterIdentity]_.
|
2016-07-03 19:17:09 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
The proposed protocol attempts to allow Alice and Bob to agree on a shared
|
2018-04-02 13:12:03 +00:00
|
|
|
secret key (K) under the following requirements:
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
1) Private key security: neither Bob nor Mallory learns anything about Alice's
|
|
|
|
static private key. Symmetrically, Alice does not learn anything about Bob's
|
|
|
|
static private key.
|
2016-12-02 15:47:46 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
2) The session key K is only known by Alice and Bob.
|
2016-12-02 15:47:46 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
3) Perfect forward secrecy: the agreed upon session key remains secret in the
|
|
|
|
future, even when the static private keys of Alice and/or Bob are revealed
|
|
|
|
after the key has been agreed upon.
|
2016-12-02 15:47:46 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
4) Two-way authentication: Alice is certain that she has established a session
|
|
|
|
with Bob, and vice versa.
|
2016-12-02 15:47:46 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
5) Protection against online DPI: Ensure that it is not trivial to detect that
|
2017-05-21 13:48:04 +00:00
|
|
|
Alice and Bob are engaged in the protocol using only straightforward deep
|
2018-04-02 13:12:03 +00:00
|
|
|
packet inspection (DPI) techniques. See below.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
6) Limited deniability: neither Alice nor Bob can deny participation in the
|
|
|
|
protocol, but if either leaks the shared key the other party can deny the
|
|
|
|
authenticity of the contents of the transmitted data.
|
|
|
|
|
|
|
|
The present proposal attempts to provide all five requirements based on the
|
|
|
|
Station-To-Station (STS) protocol [STS]_. Note that this protocol is also the
|
|
|
|
basis for the [SSU]_ protocol.
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
Additional DPI Discussion
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
We assume two DPI components:
|
|
|
|
|
|
|
|
1) Online DPI
|
|
|
|
`````````````
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Online DPI inspecting all flows in real-time. Connections may be blocked or
|
|
|
|
otherwise tampered with. Connection data or metadata may be identified and
|
|
|
|
stored for offline analysis. The online DPI does not have access to the I2P
|
|
|
|
network database. The online DPI has only limited real-time computational
|
|
|
|
capability, including length calculation, field inspection, and simple
|
|
|
|
calculations such as XOR. The online DPI does have the capability of fast
|
|
|
|
real-time cryptographic functions such as AES, AEAD, and hashing, but these
|
|
|
|
would be too expensive to apply to most or all flows. Any application of these
|
|
|
|
cryptographic operations would apply only to flows on IP/Port combinations
|
|
|
|
previously identified by offline analysis. The online DPI does not have the
|
|
|
|
capability of high-overhead cryptographic functions such as DH or elligator2.
|
|
|
|
The online DPI is not designed specifically to detect I2P, although it may have
|
|
|
|
limited classification rules for that purpose.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
It is a goal to prevent protocol identification by an online DPI.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
The notion of online or "straightforward" DPI is here taken to include the
|
|
|
|
following adversary capabilities:
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
1) The ability to inspect all data sent or received by the target.
|
|
|
|
|
|
|
|
2) The ability to perform operations on the observed data, such as
|
|
|
|
applying block ciphers or hash functions.
|
|
|
|
|
|
|
|
3) The ability to store and compare with previously sent messages.
|
|
|
|
|
|
|
|
4) The ability to modify, delay or fragment packets.
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
However, the online DPI is assumed to have the following restrictions:
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
5) The inability to map IP addresses to router hashes. While this is trivial
|
|
|
|
with real-time access to the network database,
|
2017-05-21 13:48:04 +00:00
|
|
|
it would require a DPI system specifically designed to target I2P.
|
|
|
|
|
|
|
|
6) The inability to use timing information to detect the protocol.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
7) Generally speaking, the online DPI toolbox does not contain any built-in
|
|
|
|
tools that are specifically designed for I2P detection. This includes
|
|
|
|
creating "honeypots", which would for example include nonrandom padding in
|
|
|
|
their messages. Note that this does not exclude machine learning systems or
|
|
|
|
highly configurable DPI tools as long as they meet the other requirements.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
To counter payload analysis, it is ensured that all messages are
|
|
|
|
indistinguishable from random. This also requires their length to be random,
|
|
|
|
which is more complicated than just adding random padding. In fact, in Appendix
|
|
|
|
A, the authors argue that a naive (i.e. uniform) padding scheme does not
|
|
|
|
resolve the problem. Appendix A therefore proposes to include either random
|
|
|
|
delays or to develop an alternate padding scheme that can provide reasonable
|
|
|
|
protection for the proposed attack.
|
|
|
|
|
|
|
|
To protect against the sixth entry above, implementations should include random
|
|
|
|
delays in the protocol. Such techniques are not covered by this proposal, but
|
|
|
|
they could also resolve the padding length issues. In summary, the proposal
|
|
|
|
provides good protection against payload analysis (when the considerations in
|
|
|
|
Appendix A are taken into account), but only limited protection against flow
|
|
|
|
analysis.
|
|
|
|
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
2) Offline DPI
|
|
|
|
``````````````
|
|
|
|
|
|
|
|
Offline DPI inspecting data stored by the online DPI for later analysis.
|
|
|
|
The offline DPI may be designed specifically to detect I2P.
|
|
|
|
The offline DPI does have real-time access to the I2P network database.
|
|
|
|
The offline DPI does have access to this and other I2P specifications.
|
|
|
|
The offline DPI has unlimited computational capability, including
|
|
|
|
all cryptographic functions defined in this specification.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
The offline DPI does not have the ability to block existing connections. The
|
|
|
|
offline DPI does have the capability to do near-realtime (within minutes of
|
|
|
|
setup) sending to host/port of parties, for example TCP RST. The offline DPI
|
|
|
|
does have the capability to do near-realtime (within minutes of setup) replay
|
|
|
|
of previous messages (modified or not) for "probing" or other reasons.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
It is not a goal to prevent protocol identification by an offline DPI.
|
|
|
|
All decoding of obfuscated data in the first two messages, which
|
|
|
|
is implemented by I2P routers, may also be implemented by the offline DPI.
|
|
|
|
|
|
|
|
It is a goal to reject attempted connections using replay of previous messages.
|
|
|
|
|
|
|
|
|
|
|
|
Future work
|
|
|
|
```````````
|
|
|
|
|
|
|
|
- Consider the behavior of the protocol when packets are dropped or reordered
|
2017-05-21 13:48:04 +00:00
|
|
|
by an attacker. Recent interesting work in this area can be found in
|
|
|
|
[IACR-1150]_.
|
|
|
|
|
|
|
|
- Provide a more accurate classification of DPI systems, taking into account
|
|
|
|
the existing literature related to the subject.
|
|
|
|
|
|
|
|
- Discuss the formal security of the proposed protocol, ideally taking into
|
|
|
|
account the DPI attacker model.
|
|
|
|
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Noise Protocol Framework
|
|
|
|
========================
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
This proposal provides the requirements based on the Noise Protocol Framework
|
2018-04-17 16:11:51 +00:00
|
|
|
[NOISE]_ (Revision 33, 2017-10-04).
|
|
|
|
Noise has similar properties to the Station-To-Station protocol
|
2018-04-04 13:54:03 +00:00
|
|
|
[STS]_, which is the basis for the [SSU]_ protocol. In Noise parlance, Alice
|
|
|
|
is the initiator, and Bob is the responder.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
The Noise Protocol Identifier for NTCP2 is Noise_XK_25519_ChaChaPoly_SHA256.
|
|
|
|
This uses the following primitives:
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Handshake Pattern: XK
|
|
|
|
Alice transmits her key to Bob (X)
|
|
|
|
Alice knows Bob's static key already (K)
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- DH Function: X25519
|
|
|
|
X25519 DH with a key length of 32 bytes as specified in [RFC-7748]_.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Cipher Function: ChaChaPoly
|
|
|
|
AEAD_CHACHA20_POLY1305 as specified in [RFC-7539]_.
|
|
|
|
12 byte nonce, with the first 4 bytes set to zero.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Hash Function: SHA256
|
|
|
|
Standard 32-byte hash, already used extensively in I2P.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Additions to the Framework
|
|
|
|
==========================
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
This proposal defines the following enhancements to
|
|
|
|
Noise_XK_25519_ChaChaPoly_SHA256. These generally follow the guidelines in
|
|
|
|
[NOISE]_ section 13.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
1) Cleartext ephemeral keys are obfuscated with AES encryption using a known
|
|
|
|
key and IV. This is quicker than elligator2.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
2) Random cleartext padding is added to messages 1 and 2.
|
|
|
|
The cleartext padding is included in the handshake hash calculation.
|
|
|
|
Random AEAD padding is added to message 3 and data phase messages.
|
|
|
|
|
|
|
|
3) A two-byte frame length field is added, as is required for Noise over TCP,
|
|
|
|
and as in obfs4. This is used in message 3 and data phase messages.
|
|
|
|
Message 1 and 2 AEAD frames are fixed length.
|
|
|
|
|
|
|
|
4) The two-byte frame length field is obfuscated with SipHash,
|
|
|
|
as in obfs4.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
5) The payload format is defined for messages 1,2,3, and the data phase.
|
|
|
|
It of course is not defined in Noise.
|
2016-09-27 14:32:12 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Processing overhead estimate
|
|
|
|
============================
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 14:21:24 +00:00
|
|
|
Message sizes for the 3 messages:
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
1) 64 bytes + padding (NTCP was 288 bytes)
|
|
|
|
2) 56 bytes + padding (NTCP was 304 bytes)
|
|
|
|
3) 66 bytes + Alice router info + padding Average router info is about 750
|
|
|
|
bytes Total average 816 bytes (NTCP was 448 bytes)
|
|
|
|
4) not required in NTCP2 (NTCP was 48 bytes)
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Total before padding:
|
|
|
|
NTCP2: 936 bytes
|
|
|
|
NTCP: 1088 bytes
|
|
|
|
Note that if Alice connected to Bob for the purpose of sending
|
|
|
|
a DatabaseStore Message of her RouterInfo, that message is not required,
|
|
|
|
saving approximately 800 bytes.
|
|
|
|
|
|
|
|
The following crypto operations are required by each party to complete
|
|
|
|
the handshake and start the data phase:
|
|
|
|
|
|
|
|
- AES: 2
|
2018-04-04 13:54:03 +00:00
|
|
|
- SHA256: 8 (Alice), 6 (Bob) (not including 4 Alice, 6 Bob precalculated for
|
|
|
|
all connections) (not including HMAC-SHA256)
|
2018-04-02 13:12:03 +00:00
|
|
|
- HMAC-SHA256: 15
|
|
|
|
- ChaCha/Poly: 4
|
|
|
|
- X25519 DH: 3
|
|
|
|
- SipHash: 1
|
2018-04-04 13:54:03 +00:00
|
|
|
- Signature verification: 1 (Bob) (Alice previously signed when generating her
|
|
|
|
RI) Presumably Ed25519 (dependent on RI sigtype)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
The following crypto operations are required by each party for each data phase message:
|
|
|
|
|
|
|
|
- SipHash: 1
|
|
|
|
- ChaCha/Poly: 1
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2016-09-27 14:32:12 +00:00
|
|
|
|
2016-04-04 12:51:03 +00:00
|
|
|
|
|
|
|
Messages
|
|
|
|
========
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
All NTCP2 messages are less than or equal to 65537 bytes in length. The message
|
|
|
|
format is based on Noise messages, with modifications for framing and indistinguishability.
|
|
|
|
Implementations using standard Noise libraries may need to pre-process received
|
|
|
|
messages to/from the Noise message format. All encrypted fields are AEAD
|
|
|
|
ciphertexts.
|
|
|
|
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
The establishment sequence is as follows:
|
2016-07-03 19:17:09 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
.. raw:: html
|
2016-07-03 19:17:09 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% highlight %}
|
|
|
|
Alice Bob
|
2016-07-03 19:17:09 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
SessionRequest ------------------->
|
|
|
|
<------------------- SessionCreated
|
|
|
|
SessionConfirmed ----------------->
|
|
|
|
{% endhighlight %}
|
2016-07-03 19:17:09 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Using Noise terminology, the establishment and data sequence is as follows:
|
2018-04-16 15:49:00 +00:00
|
|
|
(Payload Security Properties)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 14:45:40 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
XK(s, rs): Authentication Confidentiality
|
|
|
|
<- s
|
|
|
|
...
|
|
|
|
-> e, es 0 2
|
|
|
|
<- e, ee 2 1
|
|
|
|
-> s, se 2 5
|
|
|
|
<- 2 5
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Once a session has been established, Alice and Bob can exchange Data messages.
|
2016-07-03 19:17:09 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
All message types (SessionRequest, SessionCreated, SessionConfirmed, Data and
|
|
|
|
TimeSync) are specified in this section.
|
2016-07-03 19:17:09 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Some notations::
|
2016-07-03 19:17:09 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- RH_A = Router Hash for Alice (32 bytes)
|
|
|
|
- RH_B = Router Hash for Bob (32 bytes)
|
|
|
|
|
|
|
|
|
|
|
|
Authenticated Encryption
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
There are three separate authenticated encryption instances (CipherStates).
|
|
|
|
One during the handshake phase, and two (transmit and receive) for the data phase.
|
|
|
|
Each has its own key from a KDF.
|
|
|
|
|
|
|
|
Encrypted/authenticated data will be represented as
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| |
|
|
|
|
+ +
|
|
|
|
| Encrypted and authenticated data |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
|
|
|
ChaCha20/Poly1305
|
|
|
|
`````````````````
|
|
|
|
|
2018-04-02 14:21:24 +00:00
|
|
|
Encrypted and authenticated data format.
|
|
|
|
|
|
|
|
Inputs to the encryption/decryption functions:
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
k :: 32 byte cipher key, as generated from KDF
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
nonce :: Counter-based nonce, 12 bytes.
|
|
|
|
Starts at 0 and incremented for each message.
|
|
|
|
First four bytes are always zero.
|
|
|
|
Maximum value is 2**64 - 2.
|
|
|
|
Connection must be dropped and restarted after
|
|
|
|
it reaches that value.
|
|
|
|
The value 2**64 - 1 must never be sent.
|
|
|
|
|
|
|
|
ad :: In handshake phase:
|
|
|
|
Associated data, 32 bytes.
|
|
|
|
The SHA-256 hash of all preceding data.
|
|
|
|
In data phase:
|
|
|
|
Zero bytes
|
|
|
|
|
|
|
|
data :: Plaintext data, 0 or more bytes
|
|
|
|
|
2018-04-02 14:21:24 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
Output of the encryption function, input to the decryption function:
|
|
|
|
|
|
|
|
.. raw:: html
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-02 14:21:24 +00:00
|
|
|
{% highlight lang='dataspec' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:53:31 +00:00
|
|
|
|Obfs Len | MAC |
|
2018-04-02 13:12:03 +00:00
|
|
|
+----+----+ +
|
|
|
|
| Poly1305 Message Authetication Code |
|
|
|
|
+ +----+----+----+----+----+----+
|
|
|
|
|16 bytes | |
|
|
|
|
+----+----+ +
|
|
|
|
| ChaCha20 encrypted data |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|
2018-04-02 13:53:31 +00:00
|
|
|
Obfs Len :: Length of MAC + encryptd data to follow
|
2018-04-12 12:56:50 +00:00
|
|
|
Obfuscation using SipHash (see below)
|
|
|
|
Not used in message 1 or 2, where the length is fixed
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
MAC :: Poly1305 message authentication code
|
|
|
|
|
|
|
|
encrypted data :: Same size as plaintext data
|
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
For ChaCha20, what is described here corresponds to [RFC-7539]_, which is also
|
|
|
|
used similarly in TLS [RFC-7905]_.
|
|
|
|
|
|
|
|
Notes
|
|
|
|
`````
|
|
|
|
- Since ChaCha20 is a stream cipher, plaintexts need not be padded.
|
|
|
|
Additional keystream bytes are discarded.
|
|
|
|
|
|
|
|
- The key for the cipher (256 bits) is agreed upon by means of the SHA256 KDF.
|
2018-04-12 12:56:50 +00:00
|
|
|
The details of the KDF for each message are in separate sections below.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
- ChaCha/Poly blocks for messages 1, 2, and the first part of message 3,
|
|
|
|
are of known size. Starting with the second part of message 3,
|
|
|
|
blocks are of variable size, and are prepended with a two-byte length
|
|
|
|
obfuscated with SipHash as in obfs4.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
- Padding is outside the authenticated data block for messages 1 and 2.
|
|
|
|
The padding is used in the KDF for the next message so tampering will
|
|
|
|
be detected. Starting in message 3, padding is inside the authenticated
|
|
|
|
data block.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Key Derivation Function (KDF) (for handshake message 1 and message 3 part 1)
|
|
|
|
----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
The KDF generates a handshake phase ciper key k from the DH result,
|
|
|
|
using HMAC-SHA256(key, data) as defined in [RFC-2104]_.
|
|
|
|
These are the InitializeSymmetric(), MixHash(), and MixKey() functions,
|
|
|
|
exactly as defined in the Noise spec.
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 14:45:40 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
This is the "e" message pattern:
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Define protocol_name.
|
|
|
|
Set protocol_name = "Noise_XK_25519_ChaChaPoly_SHA256" which is 32 bytes
|
|
|
|
(US-ASCII encoded, no NULL termination).
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Define Hash h = 32 bytes
|
|
|
|
h = SHA256(protocol_name);
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Define ck = 32 byte chaining key.
|
|
|
|
Set ck = h
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Define rs = Bob's 32-byte static key as published in the RouterInfo
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// MixHash(null prologue)
|
|
|
|
h = SHA256(h);
|
|
|
|
// No Alice static key
|
|
|
|
// MixHash(null s)
|
|
|
|
h = SHA256(h);
|
|
|
|
// No Alice ephemeral key
|
|
|
|
// MixHash(null e)
|
|
|
|
h = SHA256(h);
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// up until here, can all be precalculated by Alice for all outgoing connnections
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Alice must validate that Bob's static key is a valid point on the curve here.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Bob static key
|
|
|
|
// MixHash(rs)
|
|
|
|
// || below means append
|
|
|
|
h = SHA256(h || rs);
|
|
|
|
// No Bob ephemeral key
|
|
|
|
// MixHash(null re)
|
|
|
|
h = SHA256(h);
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// up until here, can all be precalculated by Bob for all incoming connnections
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
This is the "e" message pattern:
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Alice generates her ephemeral DH keypair e.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Alice ephemeral key X
|
|
|
|
// MixHash(e.pubkey)
|
|
|
|
// || below means append
|
|
|
|
h = SHA256(h || e.pubkey);
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// h is used as the associated data for the AEAD in message 1
|
|
|
|
// Retain the Hash h for the message 2 KDF
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
End of "e" message pattern.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
This is the "es" message pattern:
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// DH(e, rs) == DH(s, re)
|
|
|
|
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's static key
|
|
|
|
Set input_key_material = X25519 DH result
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// MixKey(DH())
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Define temp_key = 32 bytes
|
|
|
|
Define HMAC-SHA256(key, data) as in [RFC-2104]_
|
|
|
|
// Generate a temp key from the chaining key and DH result
|
|
|
|
// ck is the chaining key, which is the hash of the noise name, defined above
|
|
|
|
temp_key = HMAC-SHA256(ck, input_key_material)
|
|
|
|
// overwrite the DH result in memory, no longer needed
|
|
|
|
input_key_material = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Output 1
|
|
|
|
// Set a new chaining key from the temp key
|
|
|
|
// byte() below means a single byte
|
|
|
|
ck = HMAC-SHA256(temp_key, byte(0x01)).
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Output 2
|
|
|
|
// Generate the cipher key k
|
|
|
|
Define k = 32 bytes
|
|
|
|
// || below means append
|
|
|
|
// byte() below means a single byte
|
|
|
|
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
|
|
|
|
// overwrite the temp_key in memory, no longer needed
|
|
|
|
temp_key = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// retain the chaining key ck for message 2 KDF
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
End of "es" message pattern.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-07-03 19:17:09 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
1) SessionRequest
|
2016-04-04 12:51:03 +00:00
|
|
|
------------------
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Alice sends to Bob.
|
|
|
|
|
|
|
|
Noise content: Alice's ephemeral key X
|
|
|
|
Noise payload: 16 byte option block
|
|
|
|
Non-noise payload: Random padding
|
|
|
|
|
2018-04-16 15:49:00 +00:00
|
|
|
(Payload Security Properties)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 14:45:40 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
XK(s, rs): Authentication Confidentiality
|
|
|
|
-> e, es 0 2
|
|
|
|
|
|
|
|
Authentication: None (0).
|
|
|
|
This payload may have been sent by any party, including an active attacker.
|
|
|
|
|
|
|
|
Confidentiality: 2.
|
2018-04-04 13:54:03 +00:00
|
|
|
Encryption to a known recipient, forward secrecy for sender compromise
|
|
|
|
only, vulnerable to replay. This payload is encrypted based only on DHs
|
|
|
|
involving the recipient's static key pair. If the recipient's static
|
|
|
|
private key is compromised, even at a later date, this payload can be
|
|
|
|
decrypted. This message can also be replayed, since there's no ephemeral
|
|
|
|
contribution from the recipient.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
"e": Alice generates a new ephemeral key pair and stores it in the e
|
|
|
|
variable, writes the ephemeral public key as cleartext into the
|
|
|
|
message buffer, and hashes the public key along with the old h to
|
|
|
|
derive a new h.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
"es": A DH is performed between the Alice's ephemeral key pair and the
|
|
|
|
Bob's static key pair. The result is hashed along with the old ck to
|
|
|
|
derive a new ck and k, and n is set to zero.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
The X value is encrypted to ensure payload indistinguishably
|
2018-04-02 13:12:03 +00:00
|
|
|
and uniqueness, which are necessary DPI countermeasures.
|
|
|
|
We use AES encryption to achieve this,
|
|
|
|
rather than more complex and slower alternatives such as elligator2.
|
|
|
|
Asymmetric encryption to Bob's router public key would be far too slow.
|
|
|
|
AES encryption uses Bob's router hash as the key and Bob's IV as published
|
|
|
|
in the network database.
|
|
|
|
|
|
|
|
AES encryption is for DPI resistance only.
|
|
|
|
Any party knowing Bob's router hash, and IV, which are published in the network database,
|
|
|
|
may decrypt the X value in this message.
|
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
The padding is not encrypted by Alice.
|
2018-04-02 13:12:03 +00:00
|
|
|
It may be necessary for Bob to decrypt the padding,
|
|
|
|
to inhibit timing attacks.
|
|
|
|
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Raw contents:
|
|
|
|
|
2017-07-02 12:40:24 +00:00
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ obfuscated with RH_B +
|
|
|
|
| AES-CBC-256 encrypted X |
|
|
|
|
+ (32 bytes) +
|
|
|
|
| |
|
|
|
|
+ +
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| |
|
|
|
|
+ +
|
|
|
|
| ChaCha/Poly frame |
|
|
|
|
+ (32 bytes) +
|
|
|
|
| k = KDF from KDF for msg 1 |
|
|
|
|
+ n = 0 +
|
2017-07-02 12:40:24 +00:00
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-12 12:56:50 +00:00
|
|
|
| unencrypted, authenticated |
|
2018-04-02 13:12:03 +00:00
|
|
|
~ padding (optional) ~
|
|
|
|
| length defined in options block |
|
2017-07-02 12:40:24 +00:00
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
X :: AES-256-CBC encrypted X, little endian
|
2017-07-02 12:40:24 +00:00
|
|
|
key: RH_B
|
2018-04-12 12:56:50 +00:00
|
|
|
iv: As published in Bobs netdb
|
2017-07-02 12:40:24 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
padding :: Random data, 0 or more bytes.
|
|
|
|
Total message length must be 65535 bytes or less.
|
|
|
|
Total message length must be 287 bytes or less if
|
|
|
|
Bob is publishing his address as "NTCP"
|
|
|
|
(see Version Detection section below)
|
2018-04-12 12:56:50 +00:00
|
|
|
Alice and Bob will use the padding data in the KDF for message 2.
|
|
|
|
It is authenticated in that any tampering will cause the
|
|
|
|
next message to fail.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2017-07-02 12:40:24 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
Unencrypted data (Poly1305 auth tag not shown):
|
2017-07-02 12:40:24 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ +
|
|
|
|
| X |
|
|
|
|
+ (32 bytes) +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
| options |
|
|
|
|
+ (16 bytes) +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-12 12:56:50 +00:00
|
|
|
| unencrypted, authenticated |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ padding (optional) +
|
|
|
|
| length defined in options block |
|
2017-05-21 13:48:04 +00:00
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
X :: 32 bytes, little endian
|
|
|
|
|
|
|
|
options :: options block, 16 bytes
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
ext_options :: Optional. Additional options blocks, format currently undefined.
|
|
|
|
If present, length is multiple of 16 bytes
|
|
|
|
|
|
|
|
padding :: Random data, 0 or more bytes.
|
|
|
|
Total message length must be 65535 bytes or less.
|
|
|
|
Total message length must be 287 bytes or less if
|
|
|
|
Bob is publishing his address as "NTCP"
|
|
|
|
(see Version Detection section below)
|
2018-04-12 12:56:50 +00:00
|
|
|
Alice and Bob will use the padding data in the KDF for message 2.
|
|
|
|
It is authenticated in that any tampering will cause the
|
|
|
|
next message to fail.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
2017-07-02 12:40:24 +00:00
|
|
|
Options block:
|
2018-04-02 13:12:03 +00:00
|
|
|
Note: All fields are big-endian.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| ver | KE | auth | padLen |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
| tsA | Reserved (0) |
|
2017-05-21 13:48:04 +00:00
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|
|
|
|
ver :: Protocol version (currently 2)
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
KE :: Key exchange mechanism used
|
|
|
|
0: Unsupported, reserved for old NTCP
|
|
|
|
Diffie-Hellman in Z/pZ [RFC-3526], 2048 bit p
|
|
|
|
KDF = SHA256
|
|
|
|
1: X25519
|
|
|
|
KDF = HMAC-SHA256 as defined below
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
auth :: Authenticated encryption mode
|
|
|
|
Key = K, to be agreed upon using KE
|
2018-04-02 13:12:03 +00:00
|
|
|
0: Unsupported, reserved for old NTCP
|
|
|
|
AES-CBC-256/HMAC-MD5 [RFC-2104]
|
|
|
|
1: ChaCha20/Poly1305, 12 byte nonce with first 4 bytes set to zero.
|
|
|
|
|
|
|
|
padLen :: Length of the padding, 0 or more
|
|
|
|
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
|
2017-05-21 13:48:04 +00:00
|
|
|
(Distribution to be determined, see Appendix A.)
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
tsA :: Unix timestamp, unsigned seconds.
|
2017-05-21 13:48:04 +00:00
|
|
|
Wraps around in 2106
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Reserved :: 4 bytes, set to 0 for compatiblity with future options
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Notes
|
|
|
|
`````
|
2018-04-04 13:54:03 +00:00
|
|
|
- When the published address is "NTCP", Bob supports both NTCP and NTCP2 on the
|
|
|
|
same port. For compatibility, when initiating a connection to an address
|
|
|
|
published as "NTCP", Alice must limit the maximum size of this message,
|
|
|
|
including padding, to 287 bytes or less. This facilitates automatic protocol
|
|
|
|
identification by Bob. When published as "NTCP2", there is no size
|
|
|
|
restriction. See the Published Addresses and Version Detection sections
|
|
|
|
below.
|
|
|
|
|
|
|
|
- The unique X value in the initial AES block ensure that the ciphertext is
|
|
|
|
different for every session.
|
|
|
|
|
|
|
|
- Bob must reject connections where the timestamp value is too far off from the
|
|
|
|
current time. Call the maximum delta time "D". Bob must maintain a local
|
|
|
|
cache of previously-used handshake values and reject duplicates, to prevent
|
|
|
|
replay attacks. Values in the cache must have a lifetime of at least 2*D.
|
2018-04-02 13:12:03 +00:00
|
|
|
The cache values are implementation-dependent, however the 32-byte X value
|
|
|
|
(or its encrypted equivalent) may be used.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
- Reserved options must be set to zero if ver = 2. This increases the accuracy
|
|
|
|
of version detection.
|
|
|
|
|
|
|
|
- Diffie-Hellman parameters may never be sent twice to avoid DPI attacks.
|
|
|
|
|
|
|
|
- The "KE" and "auth" options must be compatible, i.e. the shared secret K must
|
|
|
|
be of the appropriate size. If more "auth" options are added, this could
|
|
|
|
implicitly change the meaning of the "KE" flag to use a different KDF or a
|
|
|
|
different truncation size.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- Bob must validate that Alice's ephemeral key is a valid point on the curve
|
|
|
|
here.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- Padding should be limited to a reasonable amount. Bob may reject connections
|
|
|
|
with excessive padding. Bob will specify his padding options in message 2.
|
2018-04-02 13:12:03 +00:00
|
|
|
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
|
|
|
|
(Distribution to be determined, see Appendix A.)
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- On any error, including AEAD, DH, timestamp, apparent replay, or key
|
|
|
|
validation failure, Bob must halt further message processing and close the
|
|
|
|
connection without responding. This should be an abnormal close (TCP RST).
|
2017-07-02 12:40:24 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- To facilitate rapid version detection and handshaking, implementations must
|
|
|
|
ensure that Alice buffers and then flushes the entire contents of the first
|
|
|
|
message at once, including the padding. This increases the likelihood that
|
|
|
|
the data will be contained in a single TCP packet (unless segmented by the OS
|
|
|
|
or middleboxes), and received all at once by Bob. Additionally,
|
|
|
|
implementations must ensure that Bob buffers and then flushes the entire
|
|
|
|
contents of the second message at once, including the padding. and that Bob
|
|
|
|
buffers and then flushes the entire contents of the third message at once.
|
|
|
|
This is also for efficiency and to ensure the effectiveness of the random
|
|
|
|
padding.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
Issues
|
|
|
|
``````
|
2018-04-12 12:56:50 +00:00
|
|
|
- Is the fixed-size option block big enough?
|
|
|
|
|
|
|
|
- KE and auth bytes may not be needed, or may be redefined
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Key Derivation Function (KDF) (for handshake message 2)
|
|
|
|
-------------------------------------------------------
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 14:45:40 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
// probably do this also:
|
2018-04-04 13:54:03 +00:00
|
|
|
h = SHA256(h || random padding from message 1)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
This is the "e" message pattern:
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Bob generates his ephemeral DH keypair e.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// h is from KDF for handshake message 1
|
|
|
|
// Bob ephemeral key Y
|
|
|
|
// MixHash(e.pubkey)
|
|
|
|
// || below means append
|
|
|
|
h = SHA256(h || e.pubkey);
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// h is used as the associated data for the AEAD in message 2
|
|
|
|
// Retain the Hash h for the message 3 KDF
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
End of "e" message pattern.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
This is the "ee" message pattern:
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// DH(e, re)
|
|
|
|
Define input_key_material = 32 byte DH result of Alice's ephemeral key and Bob's ephemeral key
|
|
|
|
Set input_key_material = X25519 DH result
|
|
|
|
// overwrite Alice's ephemeral key in memory, no longer needed
|
|
|
|
// Alice:
|
|
|
|
e(public and private) = (all zeros)
|
|
|
|
// Bob:
|
|
|
|
re = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// MixKey(DH())
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Define temp_key = 32 bytes
|
|
|
|
Define HMAC-SHA256(key, data) as in [RFC-2104]_
|
|
|
|
// Generate a temp key from the chaining key and DH result
|
|
|
|
// ck is the chaining key, from the KDF for handshake message 1
|
|
|
|
temp_key = HMAC-SHA256(ck, input_key_material)
|
|
|
|
// overwrite the DH result in memory, no longer needed
|
|
|
|
input_key_material = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Output 1
|
|
|
|
// Set a new chaining key from the temp key
|
|
|
|
// byte() below means a single byte
|
|
|
|
ck = HMAC-SHA256(temp_key, byte(0x01)).
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Output 2
|
|
|
|
// Generate the cipher key k
|
|
|
|
Define k = 32 bytes
|
|
|
|
// || below means append
|
|
|
|
// byte() below means a single byte
|
|
|
|
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
|
|
|
|
// overwrite the temp_key in memory, no longer needed
|
|
|
|
temp_key = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// retain the chaining key ck for message 3 KDF
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
End of "es" message pattern.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
|
|
|
2) SessionCreated
|
|
|
|
------------------
|
|
|
|
|
|
|
|
Bob sends to Alice.
|
|
|
|
|
|
|
|
Noise content: Bob's ephemeral key Y
|
|
|
|
Noise payload: 8 byte option block
|
|
|
|
Non-noise payload: Random padding
|
|
|
|
|
2018-04-16 15:49:00 +00:00
|
|
|
(Payload Security Properties)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 14:45:40 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
XK(s, rs): Authentication Confidentiality
|
|
|
|
<- e, ee 2 1
|
|
|
|
|
|
|
|
Authentication: 2.
|
|
|
|
Sender authentication resistant to key-compromise impersonation (KCI).
|
|
|
|
The sender authentication is based on an ephemeral-static DH ("es" or "se")
|
|
|
|
between the sender's static key pair and the recipient's ephemeral key pair.
|
|
|
|
Assuming the corresponding private keys are secure, this authentication cannot be forged.
|
|
|
|
|
|
|
|
Confidentiality: 1.
|
|
|
|
Encryption to an ephemeral recipient.
|
|
|
|
This payload has forward secrecy, since encryption involves an ephemeral-ephemeral DH ("ee").
|
|
|
|
However, the sender has not authenticated the recipient,
|
|
|
|
so this payload might be sent to any party, including an active attacker.
|
|
|
|
|
|
|
|
|
|
|
|
"e": Bob generates a new ephemeral key pair and stores it in the e variable,
|
|
|
|
writes the ephemeral public key as cleartext into the message buffer,
|
|
|
|
and hashes the public key along with the old h to derive a new h.
|
|
|
|
|
|
|
|
"ee": A DH is performed between the Bob's ephemeral key pair and the Alice's ephemeral key pair.
|
|
|
|
The result is hashed along with the old ck to derive a new ck and k, and n is set to zero.
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
The Y value is encrypted to ensure payload indistinguishably and uniqueness,
|
|
|
|
which are necessary DPI countermeasures. We use AES encryption to achieve
|
|
|
|
this, rather than more complex and slower alternatives such as elligator2.
|
|
|
|
Asymmetric encryption to Alice's router public key would be far too slow. AES
|
|
|
|
encryption uses Bob's router hash as the key and the AES state from message 1
|
|
|
|
(which was initialized with Bob's IV as published in the network database).
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
AES encryption is for DPI resistance only. Any party knowing Bob's router hash
|
|
|
|
and IV, which are published in the network database, and captured the first 32
|
|
|
|
bytes of message 1, may decrypt the Y value in this message.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
Raw contents:
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ obfuscated with RH_B +
|
|
|
|
| AES-CBC-256 encrypted Y |
|
|
|
|
+ (32 bytes) +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
+ +
|
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| ChaCha/Poly frame |
|
|
|
|
+ Encrypted and authenticated data +
|
|
|
|
| 24 bytes |
|
|
|
|
+ k from KDF for msg 2 +
|
|
|
|
| n = 0 |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-12 12:56:50 +00:00
|
|
|
| unencrypted, authenticated |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ padding (optional) +
|
|
|
|
| length defined in options block |
|
2017-05-21 13:48:04 +00:00
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
Y :: AES-256-CBC encrypted Y, little endian
|
|
|
|
key: RH_B
|
2018-04-12 12:56:50 +00:00
|
|
|
iv: As published in Bobs netdb
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
Unencrypted data (Poly1305 auth tag not shown):
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ +
|
|
|
|
| Y |
|
|
|
|
+ (32 bytes) +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
| padLen | tsB | Rsrvd(0)|
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-12 12:56:50 +00:00
|
|
|
| unencrypted, authenticated |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ padding (optional) +
|
|
|
|
| length defined in options block |
|
2017-05-21 13:48:04 +00:00
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Y :: 32 bytes, little endian
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
padLen :: Length of the padding, 0 or more
|
|
|
|
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
|
|
|
|
(Distribution to be determined, see Appendix A.)
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
tsB :: Unix timestamp, unsigned seconds.
|
|
|
|
Wraps around in 2106
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Reserved :: 2 bytes, set to 0 for compatiblity with future options
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
padding :: Random data, 0 or more bytes.
|
|
|
|
Total message length must be 65535 bytes or less.
|
|
|
|
Alice and Bob will use the padding data in the KDF for message 3 part 1.
|
|
|
|
It is authenticated in that any tampering will cause the
|
|
|
|
next message to fail.
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
|
|
|
Notes
|
|
|
|
`````
|
2018-04-04 13:54:03 +00:00
|
|
|
- Alice must reject connections where the timestamp value is too far off from
|
|
|
|
the current time. Call the maximum delta time "D". Alice must maintain a
|
|
|
|
local cache of previously-used handshake values and reject duplicates, to
|
|
|
|
prevent replay attacks. Values in the cache must have a lifetime of at least
|
|
|
|
2*D. The cache values are implementation-dependent, however the 32-byte Y
|
|
|
|
value (or its encrypted equivalent) may be used.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- Alice must validate that Bob's ephemeral key is a valid point on the curve
|
|
|
|
here.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
- Padding should be limited to a reasonable amount.
|
|
|
|
Alice may reject connections with excessive padding.
|
|
|
|
Alice will specify her padding options in message 3.
|
|
|
|
Min/max guidelines TBD. Random size from 0 to 31 bytes minimum?
|
|
|
|
(Distribution to be determined, see Appendix A.)
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- On any error, including AEAD, DH, timestamp, apparent replay, or key
|
|
|
|
validation failure, Alice must halt further message processing and close the
|
|
|
|
connection without responding. This should be an abnormal close (TCP RST).
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- To facilitate rapid handshaking, implementations must ensure that Bob buffers
|
|
|
|
and then flushes the entire contents of the first message at once, including
|
|
|
|
the padding. This increases the likelihood that the data will be contained
|
|
|
|
in a single TCP packet (unless segmented by the OS or middleboxes), and
|
|
|
|
received all at once by Alice. This is also for efficiency and to ensure the
|
|
|
|
effectiveness of the random padding.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
Issues
|
|
|
|
``````
|
|
|
|
- Is it good practice to include the IP and port of both parties in the
|
|
|
|
signature to avoid replay attacks within the bounds of what is undetectable
|
|
|
|
with timestamps? This is what SSU does, but it doesn't seem to be necessary
|
|
|
|
as X and Y also have to match.
|
|
|
|
|
|
|
|
- Should the padding be inside the authenticated data, not outside?
|
|
|
|
It's inside for obfs4. Noise implies it should be inside.
|
2018-04-12 12:56:50 +00:00
|
|
|
The arbitrary padding is not encrypted but it is used in the KDF
|
|
|
|
for message 3 part 1, so any tampering will cause the handshake to fail.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
- Include min/max padding options here?
|
|
|
|
|
|
|
|
- ChaCha/Poly block must be of known size. Otherwise, we must prepend an
|
|
|
|
obfuscated length field. If we must do that, we may as well prepend
|
|
|
|
a 16-byte options block, and AES encrypt it, same as message 1.
|
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
- Is the fixed-size option block big enough?
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
Encryption for for handshake message 3 part 1, using message 1 KDF)
|
|
|
|
-------------------------------------------------------------------
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 14:45:40 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
// probably do this also:
|
2018-04-04 13:54:03 +00:00
|
|
|
h = SHA256(h || random padding from message 2)
|
|
|
|
// h is used as the associated data for the AEAD in message 3 part 1, below
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
This is the "s" message pattern:
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Define s = Alice's static public key, 32 bytes
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// EncryptAndHash(s.publickey)
|
|
|
|
// EncryptWithAd(h, s.publickey)
|
|
|
|
// k is from handshake message 1
|
|
|
|
// n is 1
|
|
|
|
ciphertext = ENCRYPT(k, n++, h, s.publickey)
|
|
|
|
// MixHash(ciphertext)
|
|
|
|
// || below means append
|
|
|
|
h = SHA256(h || ciphertext);
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// h is used as the associated data for the AEAD in message 3 part 2
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
End of "s" message pattern.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
|
|
|
Key Derivation Function (KDF) (for handshake message 3 part 2)
|
|
|
|
--------------------------------------------------------------
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 14:45:40 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
This is the "se" message pattern:
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// DH(s, re) == DH(e, rs)
|
|
|
|
Define input_key_material = 32 byte DH result of Alice's static key and Bob's ephemeral key
|
|
|
|
Set input_key_material = X25519 DH result
|
|
|
|
// overwrite Bob's ephemeral key in memory, no longer needed
|
|
|
|
// Alice:
|
|
|
|
re = (all zeros)
|
|
|
|
// Bob:
|
|
|
|
e(public and private) = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// MixKey(DH())
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Define temp_key = 32 bytes
|
|
|
|
Define HMAC-SHA256(key, data) as in [RFC-2104]_
|
|
|
|
// Generate a temp key from the chaining key and DH result
|
|
|
|
// ck is the chaining key, from the KDF for handshake message 1
|
|
|
|
temp_key = HMAC-SHA256(ck, input_key_material)
|
|
|
|
// overwrite the DH result in memory, no longer needed
|
|
|
|
input_key_material = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Output 1
|
|
|
|
// Set a new chaining key from the temp key
|
|
|
|
// byte() below means a single byte
|
|
|
|
ck = HMAC-SHA256(temp_key, byte(0x01)).
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Output 2
|
|
|
|
// Generate the cipher key k
|
|
|
|
Define k = 32 bytes
|
|
|
|
// || below means append
|
|
|
|
// byte() below means a single byte
|
|
|
|
k = HMAC-SHA256(temp_key, ck || byte(0x02)).
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// retain the chaining key ck for the data phase KDF
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
End of "se" message pattern.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
KDF for SipHash for length field:
|
|
|
|
SipHash uses two 8-byte keys (big endian) and 8 byte IV for first data.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Alice to Bob SipHash k1, k2, IV:
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
sipkeys_ab = HMAC-SHA256(temp_key, k_ba || byte(0x03)).
|
|
|
|
sipk1_ab = sipkeys[0:7]
|
|
|
|
sipk2_ab = sipkeys[8:15]
|
|
|
|
sipiv_ab = sipkeys[16:23]
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// overwrite the temp_key in memory, no longer needed
|
|
|
|
temp_key = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
|
|
|
3) SessionConfirmed
|
|
|
|
--------------------
|
|
|
|
|
|
|
|
Alice sends to Bob.
|
|
|
|
|
|
|
|
Noise content: Alice's static key
|
|
|
|
Noise payload: Alice's RouterInfo and random padding
|
|
|
|
Non-noise payload: none
|
|
|
|
|
2018-04-16 15:49:00 +00:00
|
|
|
(Payload Security Properties)
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 14:45:40 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
XK(s, rs): Authentication Confidentiality
|
|
|
|
-> s, se 2 5
|
|
|
|
|
|
|
|
Authentication: 2.
|
2018-04-04 13:54:03 +00:00
|
|
|
Sender authentication resistant to key-compromise impersonation (KCI). The
|
|
|
|
sender authentication is based on an ephemeral-static DH ("es" or "se")
|
|
|
|
between the sender's static key pair and the recipient's ephemeral key
|
|
|
|
pair. Assuming the corresponding private keys are secure, this
|
|
|
|
authentication cannot be forged.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
Confidentiality: 5.
|
2018-04-04 13:54:03 +00:00
|
|
|
Encryption to a known recipient, strong forward secrecy. This payload is
|
|
|
|
encrypted based on an ephemeral-ephemeral DH as well as an ephemeral-static
|
|
|
|
DH with the recipient's static key pair. Assuming the ephemeral private
|
|
|
|
keys are secure, and the recipient is not being actively impersonated by an
|
|
|
|
attacker that has stolen its static private key, this payload cannot be
|
|
|
|
decrypted.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
"s": Alice writes her static public key from the s variable into the
|
|
|
|
message buffer, encrypting it, and hashes the output along with the old h
|
|
|
|
to derive a new h.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
"se": A DH is performed between the Alice's static key pair and the Bob's
|
|
|
|
ephemeral key pair. The result is hashed along with the old ck to derive a
|
|
|
|
new ck and k, and n is set to zero.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
This contains two ChaCha/Poly frames.
|
|
|
|
The first is Alice's encrypted static public key.
|
2018-04-04 13:54:03 +00:00
|
|
|
The second is the Noise payload: Alice's encrypted RouterInfo, optional
|
|
|
|
options, and optional padding. They use different keys, because the MixKey()
|
|
|
|
function is called in between.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Raw contents:
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| |
|
2018-04-12 12:56:50 +00:00
|
|
|
+ ChaCha/Poly frame (48 bytes) +
|
2018-04-02 13:12:03 +00:00
|
|
|
| Encrypted and authenticated |
|
|
|
|
+ Alice's static key +
|
2018-04-12 12:56:50 +00:00
|
|
|
| (32 bytes) |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ +
|
|
|
|
| k from KDF for msg 1 |
|
|
|
|
+ n = 1 +
|
|
|
|
| |
|
|
|
|
+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|obf. size| |
|
|
|
|
+----+----+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ ChaCha/Poly frame +
|
|
|
|
| Encrypted and authenticated |
|
|
|
|
+ +
|
|
|
|
| Alice's RouterInfo |
|
|
|
|
+ using block format 2 +
|
|
|
|
| Arbitrary padding |
|
|
|
|
+ using block format 255 +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
+ +
|
2018-04-02 13:12:03 +00:00
|
|
|
| k from KDF for msg 3 part 2 |
|
|
|
|
+ n = 0 +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
obf. size :: Size of frame to follow, obfuscated with SipHash
|
|
|
|
KDF for SipHash TBD
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
Unencrypted data (Poly1305 auth tag not shown):
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ Alice's static key +
|
|
|
|
| (32 bytes) |
|
2017-05-21 13:48:04 +00:00
|
|
|
+ +
|
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ +
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| size | |
|
|
|
|
+----+----+ +
|
|
|
|
| |
|
|
|
|
+ +
|
|
|
|
| Alice's RouterInfo block |
|
2017-05-21 13:48:04 +00:00
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
| |
|
|
|
|
+ Optional Options block +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ Optional Padding block +
|
|
|
|
| |
|
|
|
|
~ . . . ~
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
size :: Size of frame to follow, plus 16 for the
|
|
|
|
Poly1305 auth tag (not shown)
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Notes
|
|
|
|
`````
|
2018-04-02 13:12:03 +00:00
|
|
|
- Bob must perform the usual Router Info validation.
|
|
|
|
Ensure the sig type is supported, verify the signature,
|
|
|
|
verify the timestamp is within bounds, and any other checks necessary.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Bob must verify that Alice's static key received in the first frame matches
|
|
|
|
the static key in the Router Info. Bob must first search the Router Info for
|
|
|
|
a Router Address with a matching Noise Name (nn) and version (v) option.
|
|
|
|
If none is present, get the key from the Router Info options.
|
|
|
|
See Published Router Info section below.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- If Bob has an older version of Alice's RouterInfo in his netdb, verify
|
|
|
|
that the static key in the router info is the same in both, if present,
|
|
|
|
and if the older version is less than XXX old (see key rotate time below)
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Bob must validate that Alice's static key is a valid point on the curve here.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Options should be included, to specify padding parameters.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- On any error, including AEAD, RI, DH, timestamp, or key validation failure,
|
2018-04-04 13:54:03 +00:00
|
|
|
Bob must halt further message processing and close the connection without
|
|
|
|
responding. This should be an abnormal close (TCP RST).
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- To facilitate rapid handshaking, implementations must ensure that Alice
|
|
|
|
buffers and then flushes the entire contents of the third message at once,
|
2018-04-02 13:12:03 +00:00
|
|
|
including both AEAD blocks.
|
2018-04-04 13:54:03 +00:00
|
|
|
This increases the likelihood that the data will be contained in a single TCP
|
|
|
|
packet (unless segmented by the OS or middleboxes), and received all at once
|
|
|
|
by Bob. This is also for efficiency and to ensure the effectiveness of the
|
|
|
|
random padding.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Key Derivation Function (KDF) (for data phase)
|
|
|
|
----------------------------------------------
|
|
|
|
|
|
|
|
The data phase uses a zero-length associated data input.
|
|
|
|
|
|
|
|
|
|
|
|
The KDF generates two cipher keys k_ab and k_ba from the chaining key ck,
|
|
|
|
using HMAC-SHA256(key, data) as defined in [RFC-2104]_.
|
|
|
|
This is the Split() function, exactly as defined in the Noise spec.
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 15:07:59 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
ck = from handshake phase
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// zerolen is a zero-length byte array
|
|
|
|
temp_key = HMAC-SHA256(ck, zerolen)
|
|
|
|
// overwrite the chaining key in memory, no longer needed
|
|
|
|
ck = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Output 1
|
|
|
|
// cipher key, for Alice transmits to Bob (Noise doesn't make clear which is which, but Java code does)
|
|
|
|
k_ab = HMAC-SHA256(temp_key, byte(0x01)).
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// Output 2
|
|
|
|
// cipher key, for Bob transmits to Alice (Noise doesn't make clear which is which, but Java code does)
|
|
|
|
k_ba = HMAC-SHA256(temp_key, k_ab || byte(0x02)).
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
KDF for SipHash for length field:
|
|
|
|
SipHash uses two 8-byte keys (big endian) and 8 byte IV for first data.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Alice to Bob SipHash k1, k2, IV:
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
sipkeys_ab = HMAC-SHA256(temp_key, k_ba || byte(0x03)).
|
|
|
|
sipk1_ab = sipkeys[0:7]
|
|
|
|
sipk2_ab = sipkeys[8:15]
|
|
|
|
sipiv_ab = sipkeys[16:23]
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Bob to Alice SipHash k1, k2, IV:
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
sipkeys_ba = HMAC-SHA256(temp_key, sipkeys_ab || byte(0x04)).
|
|
|
|
sipk1_ba = sipkeys[0:7]
|
|
|
|
sipk2_ba = sipkeys[8:15]
|
|
|
|
sipiv_ba = sipkeys[16:23]
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
// overwrite the temp_key in memory, no longer needed
|
|
|
|
temp_key = (all zeros)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4) Data and TimeSync
|
2017-05-21 13:48:04 +00:00
|
|
|
--------------------
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Noise payload: As defined below, including random padding
|
|
|
|
Non-noise payload: none
|
|
|
|
|
|
|
|
Starting with the 2nd part of message 3, all messages are inside
|
|
|
|
an authenticated and encrypted ChaCha/Poly "frame"
|
|
|
|
with a prepended two-byte obfuscated length.
|
|
|
|
All padding is inside the frame.
|
|
|
|
Inside the frame is a standard format with zero or more "blocks".
|
|
|
|
Each block has a one-byte type and a two-byte length.
|
|
|
|
Types include date/time, I2NP message, options, termination, and padding.
|
|
|
|
|
|
|
|
Note: Bob may, but is not required, to send his RouterInfo to Alice as
|
|
|
|
his first message to Alice in the data phase.
|
|
|
|
|
2018-04-16 15:49:00 +00:00
|
|
|
(Payload Security Properties)
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 14:45:40 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
XK(s, rs): Authentication Confidentiality
|
|
|
|
<- 2 5
|
|
|
|
-> 2 5
|
|
|
|
|
|
|
|
Authentication: 2.
|
|
|
|
Sender authentication resistant to key-compromise impersonation (KCI).
|
|
|
|
The sender authentication is based on an ephemeral-static DH ("es" or "se")
|
|
|
|
between the sender's static key pair and the recipient's ephemeral key pair.
|
|
|
|
Assuming the corresponding private keys are secure, this authentication cannot be forged.
|
|
|
|
|
|
|
|
Confidentiality: 5.
|
|
|
|
Encryption to a known recipient, strong forward secrecy.
|
|
|
|
This payload is encrypted based on an ephemeral-ephemeral DH as well as
|
|
|
|
an ephemeral-static DH with the recipient's static key pair.
|
|
|
|
Assuming the ephemeral private keys are secure, and the recipient is not being actively impersonated
|
|
|
|
by an attacker that has stolen its static private key, this payload cannot be decrypted.
|
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
Notes
|
|
|
|
`````
|
|
|
|
- For efficiency and to minimize identification of the length field,
|
|
|
|
implementations must ensure that the sender buffers and then flushes the entire contents
|
|
|
|
of data messages at once, including the length field and the AEAD block.
|
|
|
|
This increases the likelihood that the data will be contained in a single TCP packet
|
|
|
|
(unless segmented by the OS or middleboxes), and received all at once the other party.
|
|
|
|
This is also for efficiency and to ensure the effectiveness of the random padding.
|
|
|
|
|
|
|
|
- The router may choose to terminate the session on AEAD error, or may continue to attempt communications.
|
|
|
|
If continuing, the router should terminate after repeated errors.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SipHash obfuscated length?
|
|
|
|
``````````````````````````
|
|
|
|
|
|
|
|
Reference: [SipHash]_
|
|
|
|
|
|
|
|
Following is from obfs4:
|
|
|
|
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
2018-04-02 15:07:59 +00:00
|
|
|
{% highlight lang='text' %}
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Once both sides have completed the handshake, they transfer application
|
2018-04-02 13:12:03 +00:00
|
|
|
data broken up into "packets", that are then encrypted and authenticated in
|
|
|
|
NaCl crypto_secretbox_xsalsa20poly1305 [5] "frames".
|
|
|
|
|
|
|
|
+------------+----------+--------+--------------+------------+------------+
|
|
|
|
| 2 bytes | 16 bytes | 1 byte | 2 bytes | (optional) | (optional) |
|
|
|
|
| Frame len. | Tag | Type | Payload len. | Payload | Padding |
|
|
|
|
+------------+----------+--------+--------------+------------+------------+
|
|
|
|
\_ Obfs. _/ \___________ NaCl secretbox (Poly1305/XSalsa20) ___________/
|
|
|
|
|
|
|
|
The frame length refers to the length of the succeeding secretbox. To
|
|
|
|
avoid transmitting identifiable length fields in stream, the frame length
|
|
|
|
is obfuscated by XORing a mask derived from SipHash-2-4 in OFB mode.
|
|
|
|
|
|
|
|
K = The SipHash-2-4 key from the KDF. (two 8-byte long integers)
|
|
|
|
IV[0] = The SipHash-2-4 OFB from the KDF. (8 bytes)
|
|
|
|
For each packet:
|
|
|
|
IV[n] = SipHash-2-4(K, IV[n-1])
|
|
|
|
Mask[n] = First 2 bytes of IV[n]
|
|
|
|
obfuscatedLength = length ^ Mask[n]
|
|
|
|
|
|
|
|
As the receiver has the SipHash-2-4 key and IV, decoding the length is done
|
|
|
|
via deriving the mask used to obfsucate the length and XORing the truncated
|
|
|
|
digest to obtain the length of the secretbox.
|
|
|
|
|
|
|
|
The payload length refers to the length of the payload portion of the frame
|
|
|
|
and does not include the padding. It is possible for the payload length to
|
|
|
|
be 0 in which case all the remaining data is authenticated and decrypted,
|
|
|
|
but ignored.
|
|
|
|
|
|
|
|
The maximum allowed frame length is 1448 bytes, which allows up to 1427
|
|
|
|
bytes of useful payload to be transmitted per "frame".
|
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
|
|
|
Maximum size
|
|
|
|
````````````
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Raw contents
|
|
|
|
````````````
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 15:07:59 +00:00
|
|
|
|obf size | |
|
2018-04-02 13:12:03 +00:00
|
|
|
+----+----+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
2018-04-02 13:12:03 +00:00
|
|
|
+ ChaCha/Poly frame +
|
|
|
|
| Encrypted and authenticated |
|
|
|
|
+ k = KDF for data phase +
|
|
|
|
| n starts at 0 and increments |
|
|
|
|
+ for each frame +
|
|
|
|
| 16 bytes minimum |
|
2017-05-21 13:48:04 +00:00
|
|
|
+ +
|
|
|
|
| |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-02 15:07:59 +00:00
|
|
|
obf size :: 2 bytes length obfuscated with SipHash
|
|
|
|
|
|
|
|
Maximum size is 65537 bytes.
|
|
|
|
Obfuscated length is 2 bytes.
|
|
|
|
Maximum ChaCha/poly frame is 65535 bytes.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
Unencrypted data
|
|
|
|
````````````````
|
|
|
|
There are zero or more blocks in the encrypted frame.
|
|
|
|
Each block contains a one-byte identifier, a two-byte length,
|
|
|
|
and zero or more bytes of data.
|
|
|
|
|
|
|
|
For extensibility, receivers must ignore blocks with unknown identifiers,
|
|
|
|
and treat them as padding.
|
|
|
|
|
|
|
|
Encrypted data is 65535 bytes max, including a 16-byte authentication header,
|
|
|
|
so the max unencrypted data is 65519 bytes.
|
|
|
|
|
2018-04-17 16:11:51 +00:00
|
|
|
(Poly1305 auth tag not shown):
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|blk | size | data |
|
|
|
|
+----+----+----+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|blk | size | data |
|
|
|
|
+----+----+----+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
~ . . . ~
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
blk :: 0 for datetime,
|
|
|
|
1 for options,
|
|
|
|
2 for RouterInfo,
|
|
|
|
3 for I2NP msg,
|
|
|
|
4 for termination,
|
|
|
|
254 for padding
|
|
|
|
255 reserved for future extension
|
|
|
|
size :: size of data to follow, 0 - 65516
|
2018-04-02 15:07:59 +00:00
|
|
|
data :: the data
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-02 15:07:59 +00:00
|
|
|
Maximum ChaCha/Poly frame is 65535 bytes.
|
|
|
|
Poly1305 tag is 16 bytes
|
|
|
|
Maximum total block size is 65519 bytes
|
|
|
|
Maximum single block size is 65519 bytes
|
|
|
|
Block type is 1 byte
|
|
|
|
Block length is 2 bytes
|
|
|
|
Maximum single block data size is 65516 bytes.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
DateTime
|
|
|
|
````````
|
|
|
|
Special case for time synchronization:
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+
|
|
|
|
| 0 | 4 | timestamp |
|
|
|
|
+----+----+----+----+----+----+----+
|
|
|
|
|
|
|
|
blk :: 0
|
|
|
|
size :: 4
|
|
|
|
timestamp :: Unix timestamp, unsigned seconds.
|
|
|
|
Wraps around in 2106
|
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
|
|
|
Options
|
|
|
|
```````
|
|
|
|
Pass updated options.
|
|
|
|
Options include: Min and max padding.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-17 16:11:51 +00:00
|
|
|
Options block will be variable length.
|
|
|
|
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
| 1 | size | options |
|
|
|
|
+----+----+----+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
blk :: 1
|
|
|
|
size :: size of options to follow TBD
|
|
|
|
options :: Format TBD
|
|
|
|
|
2018-04-02 15:07:59 +00:00
|
|
|
Requested padding parameters.
|
|
|
|
Min is for desired DPI resistance
|
|
|
|
Max is for bandwidth limits.
|
|
|
|
4 bytes tx_pad_min, tx_pad_max, rx_pad_min, rx_pad_max
|
|
|
|
Each is a 4.4 fixed-point float representing 0 to 15.9375
|
2018-04-17 16:11:51 +00:00
|
|
|
(or think of it as an unsigned 8-bit integer divided by 16.0).
|
2018-04-02 15:07:59 +00:00
|
|
|
This is the ratio of padding to data. Examples:
|
|
|
|
Value of 0x00 means no padding
|
|
|
|
Value of 0x01 means add 6% padding
|
|
|
|
Value of 0x10 means add 100% padding
|
|
|
|
Value of 0x80 means add 800% (8x) padding
|
|
|
|
Alice and Bob will negotiate the minimum and maximum in each direction.
|
|
|
|
These are guidelines, there is no enforcement.
|
|
|
|
Sender should honor receiver's maximum.
|
|
|
|
Sender may or may not honor receiver's minimum, within bandwidth constraints.
|
|
|
|
|
|
|
|
Padding distribution specified as additional parameters?
|
|
|
|
Random delay specified as additional parameters?
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
{% endhighlight %}
|
|
|
|
|
|
|
|
|
2018-04-17 16:11:51 +00:00
|
|
|
Options Issues
|
|
|
|
``````````````
|
|
|
|
- Options format is TBD.
|
|
|
|
- Options negotiation is TBD.
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
RouterInfo
|
|
|
|
``````````
|
|
|
|
Pass Alice's RouterInfo to Bob.
|
|
|
|
Used in handshake message 3 part 2.
|
|
|
|
Pass Alice's RouterInfo to Bob, or Bob's to Alice.
|
|
|
|
Used optionally in the data phase.
|
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
|
|
|
| 2 | size |flg | RouterInfo |
|
|
|
|
+----+----+----+----+ +
|
|
|
|
| (Alice's in handshake msg 3 part 2) |
|
|
|
|
~ (Alice's or Bob's in data phase) ~
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
blk :: 2
|
|
|
|
size :: size of router info to follow
|
|
|
|
flg :: 1 byte flag
|
|
|
|
bit order: 76543210
|
|
|
|
bit 0: 0 for local store, 1 for flood request
|
|
|
|
bits 7-1: Unused, set to 0 for future compatibility
|
|
|
|
routerinfo :: Alice's or Bob's RouterInfo
|
|
|
|
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Notes
|
|
|
|
`````
|
2018-04-02 13:12:03 +00:00
|
|
|
- When used in the data phase, receiver (Alice or Bob) shall validate that
|
|
|
|
it's the same Router Hash as originally sent (for Alice) or sent to (for Bob).
|
|
|
|
Then, treat it as a local I2NP DatabaseStore Message. Validate signature,
|
|
|
|
validate more recent timestamp, and store in the local netdb.
|
|
|
|
If the flag bit 0 is 1, and the receiving party is floodfill,
|
|
|
|
treat it as a DatabaseStore Message with a nonzero reply token,
|
|
|
|
and flood it to the nearest floodfills.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- The Router Info is NOT gzipped compressed
|
|
|
|
(unlike in a DatabaseStore Message, where it is)
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Flooding must not be requested unless there are published
|
|
|
|
RouterAddresses in the RouterInfo. The receiving router
|
|
|
|
must not flood the RouterInfo unless there are published
|
|
|
|
RouterAddresses in it.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Issues
|
|
|
|
``````
|
|
|
|
- Could also be used in data phase, instead of a I2NP DatabaseStoreMessage.
|
|
|
|
For example, Bob could use it to start off the data phase.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
I2NP Message
|
|
|
|
````````````
|
|
|
|
|
|
|
|
An single I2NP message with a modified header.
|
|
|
|
I2NP messages may not be fragmented across blocks or
|
|
|
|
across chacha/poly segments.
|
|
|
|
|
|
|
|
This removes 7 bytes from the NTCP I2NP header:
|
|
|
|
The one-byte SHA-256 checksum,
|
|
|
|
go from 8 to 4 bytes for expiration,
|
|
|
|
and remove the 2 byte length (use the block size - 9).
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
| 3 | size |type| msg id |
|
2017-05-21 13:48:04 +00:00
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
| short exp | message |
|
|
|
|
+----+----+----+----+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
blk :: 3
|
|
|
|
size :: size of type + msg id + exp + data to follow
|
|
|
|
I2NP message body size is (size - 9).
|
|
|
|
type :: I2NP msg type, see I2NP spec
|
|
|
|
msg id :: I2NP msg id, 4 bytes
|
|
|
|
short exp :: I2NP message expiration, Unix timestamp, unsigned seconds.
|
|
|
|
Wraps around in 2106
|
|
|
|
message :: I2NP message body
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
Termination
|
|
|
|
```````````
|
|
|
|
Noise recommends an explicit termination message.
|
|
|
|
Original NTCP doesn't have one.
|
|
|
|
Drop the connection.
|
|
|
|
This should be the last non-padding block.
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
| 4 | 1 |rsn | last valid
|
2017-05-21 13:48:04 +00:00
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
nonce received |
|
|
|
|
+----+----+----+----+
|
|
|
|
|
|
|
|
blk :: 4
|
|
|
|
size :: 0
|
|
|
|
rsn :: reason, 1 byte:
|
|
|
|
0: unspecified
|
|
|
|
1: termination received
|
|
|
|
2: idle timeout
|
|
|
|
3: router shutdown
|
|
|
|
4: AEAD failure
|
|
|
|
5: incompatible options
|
|
|
|
6: incompatible sig type
|
|
|
|
7: clock skew
|
2018-04-17 16:11:51 +00:00
|
|
|
8: padding violation
|
|
|
|
9: AEAD framing error
|
|
|
|
10: payload framing error
|
2018-04-02 13:12:03 +00:00
|
|
|
...
|
2018-04-17 16:11:51 +00:00
|
|
|
last valid nonce received: The nonce (counter) for the last valid AEAD block received
|
2018-04-02 13:12:03 +00:00
|
|
|
8 bytes
|
|
|
|
|
|
|
|
Note: Not all reasons may actually be used; handshake failures will
|
|
|
|
generally result in immediate close with TCP RST instead.
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
Padding
|
|
|
|
```````
|
|
|
|
This is for padding inside AEAD.
|
|
|
|
Padding for messages 1 and 2 are outside AEAD.
|
|
|
|
All padding for message 3 and the data phase is inside AEAD.
|
|
|
|
|
|
|
|
Padding inside AEAD should roughly adhere to the negotiated parameters.
|
|
|
|
Bob sent his requested tx/rx min/max parameters in message 2.
|
|
|
|
Alice sent her requested tx/rx min/max parameters in message 3.
|
|
|
|
Updated options may be sent during the data phase.
|
|
|
|
See options block information above.
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-17 16:11:51 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|254 | size | padding |
|
|
|
|
+----+----+----+ +
|
2017-05-21 13:48:04 +00:00
|
|
|
| |
|
|
|
|
~ . . . ~
|
|
|
|
| |
|
|
|
|
+----+----+----+----+----+----+----+----+
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
blk :: 254
|
|
|
|
size :: size of padding to follow
|
|
|
|
padding :: random data
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
{% endhighlight %}
|
|
|
|
|
2018-04-17 16:11:51 +00:00
|
|
|
Padding Issues
|
|
|
|
``````````````
|
|
|
|
- Padding strategies TBD.
|
|
|
|
- Minimum padding TBD.
|
|
|
|
- Need for padding-only messages TBD.
|
|
|
|
- Padding defaults TBD.
|
|
|
|
- Padding parameter negotiation TBD.
|
|
|
|
- Is padding important for data phase or only handshake?
|
|
|
|
- How to ensure low-bandwidth routers aren't "swamped"
|
|
|
|
- How to ensure high-bandwidth routers send/receive enough padding
|
|
|
|
- Noise limits messages to 64KB, any other padding (except in handshake msg 1/2)
|
|
|
|
would have to be outside Noise.
|
|
|
|
- Disconnect if negotiated padding is violated or can't negotiate?
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
Other block types
|
|
|
|
`````````````````
|
|
|
|
Implementations should ignore unknown block types for
|
|
|
|
forward compatibility.
|
|
|
|
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Future work
|
|
|
|
```````````
|
|
|
|
- The padding length is either to be decided on a per-message basis and
|
|
|
|
estimates of the length distribution, or random delays should be added.
|
|
|
|
These countermeasures are to be included to resist DPI, as message sizes
|
|
|
|
would otherwise reveal that I2P traffic is being carried by the transport
|
|
|
|
protocol. The exact padding scheme is an area of future work, Appendix A
|
|
|
|
provides more information on the topic.
|
|
|
|
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
5) Termination
|
|
|
|
--------------
|
|
|
|
|
|
|
|
Connections may be terminated via normal or abnormal TCP socket close,
|
|
|
|
or, as Noise recommends, an explicit termination message.
|
|
|
|
The explicit termination message is defined in the data phase above.
|
|
|
|
|
|
|
|
Upon any normal or abnormal termination, routers should
|
|
|
|
zero-out any in-memory ephemeral data, including handshake ephemeral keys,
|
|
|
|
symmetric crypto keys, and related information.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Published Router Info
|
|
|
|
=====================
|
|
|
|
|
|
|
|
|
|
|
|
Published Addresses
|
|
|
|
-------------------
|
|
|
|
|
|
|
|
|
|
|
|
The published RouterAddress (part of the RouterInfo) will have a
|
|
|
|
protocol identifier of either "NTCP" or "NTCP2".
|
|
|
|
|
|
|
|
The RouterAddress must contain "host" and "port" options, as in
|
|
|
|
the current NTCP protocol.
|
|
|
|
|
|
|
|
The RouterAddress must contain four options
|
|
|
|
to indicate NTCP2 support:
|
|
|
|
|
|
|
|
- n=NXK2CS
|
|
|
|
The Noise Protocol Name.
|
|
|
|
Value shortened from Noise_XK_25519_ChaChaPoly_SHA256.
|
|
|
|
Future values will be named similarly, with 6 chars to represent
|
|
|
|
the 5 Noise name fields.
|
2018-04-12 12:56:50 +00:00
|
|
|
TODO: There may be value in using the "official" noise name,
|
|
|
|
at a cost of 26 bytes per address.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
- s=(Base64 key)
|
|
|
|
The current Noise static public key (s) for this RouterAddress.
|
|
|
|
Base 64 encoded using the standard I2P Base 64 alphabet.
|
|
|
|
32 bytes in binary, 44 bytes as Base 64 encoded,
|
|
|
|
little-endian X25519 public key.
|
|
|
|
|
|
|
|
- i=(Base64 IV)
|
|
|
|
The current IV for encrypting the X value in message 1 for this RouterAddress.
|
|
|
|
Base 64 encoded using the standard I2P Base 64 alphabet.
|
|
|
|
16 bytes in binary, 24 bytes as Base 64 encoded,
|
|
|
|
big-endian.
|
|
|
|
|
|
|
|
- v=2
|
|
|
|
The current version (2).
|
|
|
|
When published as "NTCP", additional support for version 1 is implied.
|
|
|
|
Support for future versions will be with comma-separated values,
|
|
|
|
e.g. v=2,3
|
|
|
|
Implementation should verify compatibility, including multiple
|
|
|
|
versions if a comma is present. Comma-separated versions must
|
|
|
|
be in numerical order.
|
|
|
|
|
|
|
|
Alice must verify that all three options are present and valid
|
|
|
|
before connecting using the NTCP2 protocol.
|
|
|
|
|
|
|
|
When published as "NTCP" with "n", "s", "i", and "v" options,
|
|
|
|
the router must accept incoming connections on that host and port
|
2018-04-04 13:54:03 +00:00
|
|
|
for both NTCP and NTCP2 protocols, and automatically detect the protocol
|
|
|
|
version.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
When published as "NTCP2" with "n", "s", "i", and "v" options,
|
|
|
|
the router accepts incoming connections on that host and port
|
|
|
|
for the NTCP2 protocol only.
|
|
|
|
|
2018-04-17 16:11:51 +00:00
|
|
|
If a router supports both NTCP1 and NTCP2 connections but
|
|
|
|
does not implement automatic version detection for incoming connections,
|
|
|
|
it must advertise both "NTCP" and "NTCP2" addresses, and include
|
|
|
|
the ntcp2 options in the "NTCP2" address only.
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
If multiple NTCP2 RouterAddresses (either as "NTCP" or "NTCP2") are published
|
|
|
|
in the same RouterInfo (for additional IP addresses or ports),
|
2018-04-17 16:11:51 +00:00
|
|
|
all addressses specifying the same port must contain the identical ntcp2 options and values.
|
|
|
|
In particular, all must contain the same static key and iv.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Unpublished NTCP Address
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
If Alice does not publish her NTCP2 address (as "NTCP" or "NTCP2),
|
|
|
|
she must include her Noise static public key in her RouterInfo options.
|
|
|
|
The option name is N(shortened Noise name)(NTCP2 Version)s.
|
|
|
|
|
|
|
|
- NNXK2CS2s=(Base64 key)
|
2018-04-04 13:54:03 +00:00
|
|
|
Name shortened from (N)TCP2 (N)oise_(XK)_(2)5519_(C)haChaPoly_(S)HA256
|
|
|
|
version (2) (s)tatic key.
|
2018-04-02 13:12:03 +00:00
|
|
|
Future options will be named similarly, with 6 chars to represent
|
|
|
|
the 5 Noise name fields.
|
|
|
|
The current Noise static public key (s) for this Router.
|
|
|
|
Base 64 encoded using the standard I2P Base 64 alphabet.
|
|
|
|
32 bytes in binary, 44 bytes as Base 64 encoded,
|
|
|
|
little-endian X25519 public key.
|
2018-04-17 16:11:51 +00:00
|
|
|
TODO: There may be value in using the "official" noise name,
|
|
|
|
at a cost of 26 bytes per address.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Public Key and IV Rotation
|
|
|
|
--------------------------
|
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
Due to caching of RouterInfos, routers must not rotate the static public key or IV
|
2018-04-04 13:54:03 +00:00
|
|
|
while the router is up, whether in a published address or not. Routers must
|
2018-04-12 12:56:50 +00:00
|
|
|
persistently store this key and IV for reuse after an immediate restart, so incoming
|
2018-04-04 13:54:03 +00:00
|
|
|
connections will continue to work, and restart times are not exposed. Routers
|
|
|
|
must persistently store, or otherwise determine, last-shutdown time, so that
|
|
|
|
the previous downtime may be calculated at startup.
|
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
Subject to concerns about exposing restart times, routers may rotate this key or IV
|
2018-04-04 13:54:03 +00:00
|
|
|
at startup if the router was previously down for some time (a couple hours at
|
|
|
|
least).
|
|
|
|
|
|
|
|
If the router has any published NTCP2 RouterAddresses (as NTCP or NTCP2), the
|
|
|
|
minimum downtime before rotation should be much longer, for example one month,
|
2018-04-02 13:12:03 +00:00
|
|
|
unless the local IP address has changed or the router "rekeys".
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
If the router has any published SSU RouterAddresses, but not NTCP2 (as NTCP or
|
|
|
|
NTCP2) the minimum downtime before rotation should be longer, for example one
|
|
|
|
day, unless the local IP address has changed or the router "rekeys". This
|
|
|
|
applies even if the published SSU address has introducers.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
If the router does not have any published RouterAddresses (NTCP, NTCP2, or
|
|
|
|
SSU), the minimum downtime before rotation may be as short as two hours, even
|
|
|
|
if the IP address changes, unless the router "rekeys".
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
If the router "rekeys" to a different Router Hash, it should generate a new
|
2018-04-12 12:56:50 +00:00
|
|
|
noise key and IV as well.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
Implementations must be aware that changing the static public key or IV will prohibit
|
2018-04-02 13:12:03 +00:00
|
|
|
incoming NTCP2 connections from routers that have cached an older RouterInfo.
|
2018-04-04 13:54:03 +00:00
|
|
|
RouterInfo publishing, tunnel peer selection (including both OBGW and IB
|
|
|
|
closest hop), zero-hop tunnel selection, transport selection, and other
|
|
|
|
implementation strategies must take this into account.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-12 12:56:50 +00:00
|
|
|
IV rotation is subject to identical rules as key rotation, except that IVs are not present
|
2018-04-04 13:54:03 +00:00
|
|
|
except in published RouterAddresses, so there is no IV for hidden or firewalled
|
2018-04-12 12:56:50 +00:00
|
|
|
routers. If anything changes (version, key, options?) it is recommended that
|
|
|
|
the IV change as well.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Note: The minimum downtime before rekeying may be modified to ensure network
|
|
|
|
health, and to prevent reseeding by a router down for a moderate amount of
|
|
|
|
time.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Identity Hiding
|
|
|
|
```````````````
|
|
|
|
Deniability is not a goal. See overview above.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Each pattern is assigned properties describing the confidentiality supplied to
|
|
|
|
the initiator's static public key, and to the responder's static public key.
|
|
|
|
The underlying assumptions are that ephemeral private keys are secure, and that
|
|
|
|
parties abort the handshake if they receive a static public key from the other
|
|
|
|
party which they don't trust.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
This section only considers identity leakage through static public key fields
|
|
|
|
in handshakes. Of course, the identities of Noise participants might be
|
|
|
|
exposed through other means, including payload fields, traffic analysis, or
|
|
|
|
metadata such as IP addresses.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
Alice: (8) Encrypted with forward secrecy to an authenticated party.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
Bob: (3) Not transmitted, but a passive attacker can check candidates for the
|
|
|
|
responder's private key and determine whether the candidate is correct.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
Bob publishes his static public key in the netdb. Alice may or may not?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Issues
|
|
|
|
``````
|
|
|
|
- If Bob changes his static key, could fallback to a "XX" pattern?
|
|
|
|
|
|
|
|
|
|
|
|
Version Detection
|
|
|
|
=================
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
When published as "NTCP", the router must automatically detect the protocol
|
|
|
|
version for incoming connections.
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
This detection is implementation-dependent, but here is some general guidance.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
To detect the version of an incoming NTCP connection, Bob proceeds as follows:
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Wait for at least 64 bytes (minimum NTCP2 message 1 size)
|
|
|
|
- If the initial received data is 288 or more bytes, the incoming connection
|
|
|
|
is version 1.
|
2018-04-02 14:45:40 +00:00
|
|
|
- If less than 288 bytes, either
|
2018-04-02 15:07:59 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- Wait for a short time for more data (good strategy before widespread NTCP2
|
|
|
|
adoption) if at least 288 total received, it's NTCP 1.
|
2018-04-02 15:07:59 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- Try the first stages of decoding as version 2, if it fails, wait a short
|
|
|
|
time for more data (good strategy after widespread NTCP2 adoption)
|
2018-04-02 15:07:59 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Decrypt the first 32 bytes (the X key)
|
|
|
|
of the SessionRequest packet using AES-256 with key RH_B.
|
2018-04-02 15:07:59 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Verify a valid point on the curve.
|
|
|
|
If it fails, wait a short time for more data for NTCP 1
|
2018-04-02 15:07:59 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
- Verify the AEAD block.
|
|
|
|
If it fails, wait a short time for more data for NTCP 1
|
|
|
|
|
|
|
|
Note that changes or additional strategies may be recommended if we detect
|
|
|
|
active TCP segmentation attacks on NTCP 1.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
To facilitate rapid version detection and handshaking, implementations must
|
|
|
|
ensure that Alice buffers and then flushes the entire contents of the first
|
|
|
|
message at once, including the padding.
|
|
|
|
This increases the likelihood that the data will be contained in a single TCP
|
|
|
|
packet (unless segmented by the OS or middleboxes), and received all at once by
|
|
|
|
Bob. This is also for efficiency and to ensure the effectiveness of the random
|
|
|
|
padding.
|
2018-04-02 13:12:03 +00:00
|
|
|
This applies to both NTCP and NTCP2 handshakes.
|
|
|
|
|
|
|
|
|
|
|
|
Variants, Fallbacks, and General Issues
|
|
|
|
=======================================
|
|
|
|
|
|
|
|
- If Alice and Bob both support NTCP2, Alice should connect with NTCP2.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- If Alice fails to connect to Bob using NTCP2 for any reason, the connection
|
|
|
|
fails.
|
2018-04-02 13:12:03 +00:00
|
|
|
Alice may not retry using old NTCP 1.
|
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- Fallback to XX pattern if Bob changes his keys? This would require a type
|
|
|
|
byte prepended?
|
2018-04-02 13:12:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
- "Fall forward" to KK pattern if Alice reconnects, assuming Bob still has her
|
|
|
|
static key? This doesn't save any round trips and uses 4 DH rounds compared
|
|
|
|
to 3 for XK. Probably not.
|
2018-04-02 13:12:03 +00:00
|
|
|
|
|
|
|
.. raw:: html
|
|
|
|
|
|
|
|
{% highlight lang='dataspec' %}
|
|
|
|
KK(s, rs):
|
|
|
|
-> s
|
|
|
|
<- s
|
|
|
|
...
|
|
|
|
-> e, es, ss
|
|
|
|
<- e, ee, se
|
|
|
|
{% endhighlight %}
|
2016-04-04 12:51:03 +00:00
|
|
|
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Appendix A: Padding Scheme
|
|
|
|
==========================
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2018-04-04 13:54:03 +00:00
|
|
|
This section discusses an attack on typical padding schemes that allows
|
|
|
|
attackers to discover the probability distribution of the length of the
|
|
|
|
unpadded messages, by only observing the length of the padded messages. Let N
|
|
|
|
be a random variable describing the number of unpadded bytes, and P likewise
|
|
|
|
for the number of padding bytes. The total message size is then N + P.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Assume that for an unpadded size of n, at least ``P_min(n) >= 0`` and at most
|
|
|
|
``P_max(n) >= P_min(n)`` bytes of padding are added in a padding scheme. The
|
|
|
|
obvious scheme uses padding of length P uniformly chosen at random:
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
::
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Pr[P = p | N = n] = 1 / (P_max(n) - P_min(n)) if P_min(n) <= p <= P_max(n),
|
|
|
|
0 otherwise.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
A naive padding scheme would simply ensure that the size of the padded message
|
|
|
|
does not exceed N_max:
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
::
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
P_max(n) = N_max - n, n <= N_max
|
|
|
|
P_min(n) = 0.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
However, this leaks information about the unpadded length.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
An attacker can easily estimate ``Pr[x <= N + P <= y]``, for example by means
|
|
|
|
of a histogram.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
- From this, he can also try to estimate ``Pr[n_1 <= N <= n_2]``, indeed:
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
::
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Pr[N + P = m] = Σ_n Pr[N = n] Pr[P = m - n | N = n].
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
In the naive scheme,
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
::
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
Pr[N + P = m] = Σ_{n <= m} Pr[N = n] / (N_max - n).
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
It's pretty obvious, as it was before doing the above calculation, that this
|
|
|
|
leaks information about ``Pr[N = n]``: if the length of packets is almost
|
|
|
|
always more than m, then N + P <= m will almost never be observed. This is not
|
|
|
|
the largest issue though, although being able to observe the minimum message
|
|
|
|
length can be considered to be a problem by itself.
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
A bigger issue is that it is possible to determine ``Pr[N = n]`` exactly:
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
Pr[N + P = m] - Pr[N + P = m-1] = Pr[N = m] / (N_max - m),
|
|
|
|
|
|
|
|
that is
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
|
|
Pr[N = n] = (N_max - n)(Pr[N + P = n] - Pr[N + P = n - 1])
|
|
|
|
|
|
|
|
To distinguish NTCP2, then, the attacker can use any of the following:
|
|
|
|
|
|
|
|
- Estimate ``Pr[kB <= N <= (k + 1)B - 1]`` for positive integers k. It will
|
|
|
|
always be zero for NTCP2.
|
|
|
|
|
|
|
|
- Estimate ``Pr[N = kB]`` and compare with a standard I2P profile.
|
|
|
|
|
|
|
|
This simple attack hence partially destroys the purpose of padding, which
|
|
|
|
attempts to obfuscate the size distribution of the unpadded messages. The
|
|
|
|
amount of messages that the attacker has to observe to distinguish the protocol
|
|
|
|
depends on the desired accuracy and on the minimum and maximum unpadded message
|
|
|
|
sizes that occur in practice. Note that it is easy to gather many messages for
|
|
|
|
the attacker, since he can use all traffic sent from and to the particular port
|
|
|
|
that the target is using.
|
|
|
|
|
|
|
|
In some forms (e.g. estimation of ``Pr[kB <= N <= (k + 1)B - 1]``) the attack
|
|
|
|
requires only a few bytes of memory (one integer is enough) and it could be
|
|
|
|
argued that such an attack might be included in many slightly more advanced but
|
|
|
|
nevertheless standard DPI frameworks.
|
|
|
|
|
|
|
|
This proposal suggests using one of the following countermeasures:
|
|
|
|
|
|
|
|
- Develop an alternate padding scheme that takes into account the (estimated)
|
|
|
|
distribution of N by using a non-uniform padding length distribution. A good
|
|
|
|
padding scheme would probably require maintaining a histogram of the number
|
|
|
|
of blocks per message.
|
|
|
|
|
|
|
|
- Add random delays between (randomly sized) fragments of messages.
|
|
|
|
|
|
|
|
The second option is more generally preferred, because it can be simultaneously
|
|
|
|
used as a countermeasure against flow analysis. However, such delays may be out
|
|
|
|
of scope for the NTCP2 protocol, such that the first option, which is also
|
|
|
|
easier to implement, may be preferred instead.
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Appendix B: Random Delays
|
|
|
|
=========================
|
2017-05-21 13:48:04 +00:00
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
Timing-based DPI resistance (inter-message timing/delays can be
|
|
|
|
implementation-dependent; intra-message delays can be introduced at any
|
|
|
|
point, including before sending the random padding, for example). Artificial
|
|
|
|
delays (what obfs4 calls IAT or inter-arrival time) are independent of the
|
|
|
|
protocol itself.
|
2017-05-21 13:48:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
References
|
|
|
|
==========
|
|
|
|
|
|
|
|
.. [IACR-1150]
|
|
|
|
https://eprint.iacr.org/2015/1150
|
|
|
|
|
|
|
|
.. [NetDB]
|
|
|
|
{{ site_url('docs/how/network-database', True) }}
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
.. [NOISE]
|
|
|
|
http://noiseprotocol.org/noise.html
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
.. [NTCP]
|
|
|
|
{{ site_url('docs/transport/ntcp', True) }}
|
|
|
|
|
|
|
|
.. [Prop104]
|
|
|
|
{{ proposal_url('104') }}
|
|
|
|
|
|
|
|
.. [Prop109]
|
|
|
|
{{ proposal_url('109') }}
|
|
|
|
|
|
|
|
.. [RFC-2104]
|
|
|
|
https://tools.ietf.org/html/rfc2104
|
|
|
|
|
|
|
|
.. [RFC-3526]
|
|
|
|
https://tools.ietf.org/html/rfc3526
|
|
|
|
|
|
|
|
.. [RFC-6151]
|
|
|
|
https://tools.ietf.org/html/rfc6151
|
|
|
|
|
|
|
|
.. [RFC-7539]
|
|
|
|
https://tools.ietf.org/html/rfc7539
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
.. [RFC-7748]
|
|
|
|
https://tools.ietf.org/html/rfc7748
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
.. [RFC-7905]
|
|
|
|
https://tools.ietf.org/html/rfc7905
|
|
|
|
|
|
|
|
.. [RouterAddress]
|
|
|
|
{{ ctags_url('RouterAddress') }}
|
|
|
|
|
|
|
|
.. [RouterIdentity]
|
|
|
|
{{ ctags_url('RouterIdentity') }}
|
|
|
|
|
|
|
|
.. [SIDH]
|
|
|
|
De Feo, Luca; Jao, Plut., Towards quantum-resistant cryptosystems from
|
|
|
|
supersingular elliptic curve isogenies
|
|
|
|
|
|
|
|
.. [SigningPublicKey]
|
|
|
|
{{ ctags_url('SigningPublicKey') }}
|
|
|
|
|
2018-04-02 13:12:03 +00:00
|
|
|
.. [SipHash]
|
|
|
|
https://www.131002.net/siphash/
|
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
.. [SSU]
|
|
|
|
{{ site_url('docs/transport/ssu', True) }}
|
|
|
|
|
|
|
|
.. [STS]
|
|
|
|
Diffie, W.; van Oorschot P. C.; Wiener M. J., Authentication and
|
|
|
|
Authenticated Key Exchanges
|
|
|
|
|
|
|
|
.. [Ticket1112]
|
|
|
|
https://{{ i2pconv('trac.i2p2.i2p') }}/ticket/1112
|
|
|
|
|
|
|
|
.. [Ticket1849]
|
|
|
|
https://{{ i2pconv('trac.i2p2.i2p') }}/ticket/1849
|
|
|
|
|
|
|
|
.. [1] http://www.chesworkshop.org/ches2009/presentations/01_Session_1/CHES2009_ekasper.pdf
|
|
|
|
|
|
|
|
.. [2] https://www.blackhat.com/docs/us-16/materials/us-16-Devlin-Nonce-Disrespecting-Adversaries-Practical-Forgery-Attacks-On-GCM-In-TLS.pdf
|
|
|
|
|
|
|
|
.. [3] https://eprint.iacr.org/2014/613.pdf
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
.. [4] https://www.imperialviolet.org/2013/10/07/chacha20.html
|
2016-04-04 12:51:03 +00:00
|
|
|
|
2017-05-21 13:48:04 +00:00
|
|
|
.. [5] https://tools.ietf.org/html/rfc7539
|