summaryrefslogtreecommitdiff
path: root/39/23cb54672b4e9c85b27016c65420894e3dac49
blob: df30059017c2f709659f9e05024709667eef024b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
Return-Path: <forum@leeclagett.com>
Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org
	[172.17.192.35])
	by mail.linuxfoundation.org (Postfix) with ESMTPS id 799CFDB5
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Sat,  9 Apr 2016 19:41:30 +0000 (UTC)
X-Greylist: from auto-whitelisted by SQLgrey-1.7.6
Received: from sasl.smtp.pobox.com (pb-smtp0.pobox.com [208.72.237.35])
	by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 5BFE1100
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Sat,  9 Apr 2016 19:41:29 +0000 (UTC)
Received: from sasl.smtp.pobox.com (unknown [127.0.0.1])
	by pb-smtp0.pobox.com (Postfix) with ESMTP id 24A3750870
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Sat,  9 Apr 2016 15:41:28 -0400 (EDT)
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=date:from:to
	:subject:message-id:in-reply-to:references:mime-version
	:content-type:content-transfer-encoding; s=sasl; bh=UYSSGiMHqQCm
	fYC+bDfZICpDRXg=; b=OrF67MDDJRsuZpNJdBZjaiFg8HqwkCCswA/IBFkzby6s
	ExnY9bBJrzjIzrfV3Hl2gowHTJUGoInhUxRlC9IfjIVHKtKDK9npU4NUDivTTEA3
	il7wqzMtzKy+haU6nODlf55uUTiQxfbniPXaidQKkG2xFGqVGXFTM6l6sdqlmMg=
Received: from pb-smtp0.int.icgroup.com (unknown [127.0.0.1])
	by pb-smtp0.pobox.com (Postfix) with ESMTP id 1C8205086E
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Sat,  9 Apr 2016 15:41:28 -0400 (EDT)
Received: from laptop-m1330 (unknown [173.30.28.99])
	(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))
	(No client certificate requested)
	by pb-smtp0.pobox.com (Postfix) with ESMTPSA id 97EAE5086D
	for <bitcoin-dev@lists.linuxfoundation.org>;
	Sat,  9 Apr 2016 15:41:27 -0400 (EDT)
Date: Sat, 9 Apr 2016 15:40:38 -0400
From: Lee Clagett <forum@leeclagett.com>
To: Jonas Schnelli via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org>
Message-ID: <20160409154038.4c04dd9b@laptop-m1330>
In-Reply-To: <56FEE39B.3040401@jonasschnelli.ch>
References: <56F2B51C.8000105@jonasschnelli.ch>
	<56FEE39B.3040401@jonasschnelli.ch>
MIME-Version: 1.0
Content-Type: text/plain; charset=windows-1252
X-Pobox-Relay-ID: 0D027E88-FE8B-11E5-AC02-45AF6BB36C07-92142693!pb-smtp0.pobox.com
Content-Transfer-Encoding: quoted-printable
X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,DKIM_SIGNED,
	DKIM_VALID,RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1
X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on
	smtp1.linux-foundation.org
X-Mailman-Approved-At: Sat, 09 Apr 2016 19:56:18 +0000
Subject: Re: [bitcoin-dev] p2p authentication and encryption BIPs
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.12
Precedence: list
List-Id: Bitcoin Development Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>,
	<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>,
	<mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Sat, 09 Apr 2016 19:41:30 -0000

On Fri, 1 Apr 2016 23:09:47 +0200
Jonas Schnelli via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org>
wrote:
> > I have just PRed a draft version of two BIPs I recently wrote.
> > https://github.com/bitcoin/bips/pull/362 =20
>=20
> Hi.
> I just updated the PR above with another overhaul of the BIP.
> It's still under heavy review/work, nevertheless =96 at this point =96 =
any
> feedback is highly welcome.
>=20
> Changes since last update:
> -> Removed AES256-GCM as cipher suite
> -> Focusing on Chacha20-Poly1305 (implementation size ~300L)
> -> Two symmetric cipher keys must be calculated by HMAC_SHA512 from
> the ecdh secret
> -> A session-ID (both directions) must be calculated (HMAC_SHA256)
> for linking an identity authentication (ecdsa sig of the session-ID)
> with the encryption
> -> Re-Keying ('=3Dhash(old_key)') can be announced by the responding
> peer (after x minutes and/or after x GB, local peer policy but not
> shorter then 10mins).
> -> AEAD tag is now the last element in the new message format =20
>=20
> It is very likely that the encrypted message format performs slightly
> better than the current message format (removing the SHA256 checksum).
>=20
> ---
> </jonas>
>=20


The quotes below are from the BIPs and not the email chain ...

> Rejecting the <code>auth</code> request will not reveal the
> responding peers identity that could lead to fingerprinting the node,
> however this BIP does not cover protection against fingerprinting the
> requesting node from the perspective of the responding node.

In many use cases the requesting node will want to make a connection to
a peer with a specific identity. After encryption initialization, the
requesting node could generate an ECDH secret from the long-term public
key of the expected peer and its own session private-key to encrypt (no
MAC) the signature with the same symmetric cipher agreed upon
previously. The requesting node will not reveal its identity if the
connection has been MitM'ed, while still being the first to provide
authentication. And since this would be "inside" the session-key
crypto, it still has forward-secrecy if the responding-peers longterm
private-key is later compromised.

*Key Revocation*
This is probably too complicated, but an additional public key would
allow for cold-storage key revocation. Spreading the knowledge of such
an event is always painful, but it could be stored in the blockchain. I
think this is likely too complicated, but having these long-term keys
constantly in memory/disk is unfortunate.


> Responding peers must ignore the requesting peer after a
> unsuccessfully authentication initialization to avoid resource
> attacks (banning would lead to fingerprinting of peers that support
> authentication).=20

Once the responding peer has read the `auth` message, a TCP ACK can be
sent. From the requesting peer perspective, a TCP ACK of the `auth`
request indicates that it was read by the process or some
intermediary buffer (TOE, proxy, etc) has successfully forwarded it to
the next step. If the requesting peer waits RTT * some constant from
the ACK and gets no response, then either: a failed `auth` occurred,
`auth` is not supported, or the machine was suddenly overloaded. The
requesting peer can then send another message; a response message
indicates the responding peer does not support `auth`, and another no
response wait period indicates an overloaded peer or an `auth` enabled
peer. Initiating a new connection (no banning has occurred) indicates
either `auth` is enabled or a load-balancer re-directed the new
connection to another machine under less load. I think the latter case
is going to be rare, so you should be able to identify with high
probability nodes that support `auth` and what message types require
`auth`. And if this is process repeated multiple times, it will increase
the chances of a correct fingerprint.

Should encryption enabled peers who do _not_ support `auth` ignore all
subsequent messages after an `auth` attempt too? Fingerprinting on
`auth` required message types would still be possible. I do not see a
reliable way to prevent this from occurring.


> To request encrypted communication, the requesting peer generates an
> EC ephemeral-session-keypair and sends an <code>encinit</code>
> message to the responding peer and waits for a <code>encack</code>
> message. The responding node must do the same
> <code>encinit</code>/<code>encack</code> interaction for the opposite
> communication direction.

Why are there two key exchanges? A single shared-secret could be used
to generate keys for each direction. And it would reinforce the single
symmetric cipher rule.


> Possible symmetric key ciphers types
> {|class=3D"wikitable"
> ! Number !! symmetric key ciphers type !! Comments
> |-
> | 0 || Chacha20-Poly1305 [3] || encrypted message length must be used
> as AAD. |}
>

Chacha20-Poly1305 defined in an IETF draft [0] and RFC 7539 both
include the ciphertext length in the authentication tag generation. Is
this a unique authentication construction? Or one of the previously
mentioned designs?

*Symmetric Cipher Negotiation*
Should the symmetric cipher choices be removed? I am mainly asking for
the intended use-case. If the intent is to replace a weakened cipher
then leave the cipher negotiation. If the intent is to give
implementations multiple options, then I would remove this negotiation.


> <code>K_1</code> must be used to only encrypt the payload size of the
> encrypted message to avoid leaking information by revealing the
> message size.=20
>=20
> <code>K_2</code> must be used in conjunction with poly1305 to build
> an AEAD.

Chacha20 is a stream cipher, so only a single encryption key is needed.
The first 32 bytes of the keystream would be used for the Poly1305 key,
the next 4 bytes would be used to encrypt the length field, and the
remaining keystream would be used to encrypt the payload. Poly1305
would then generate a tag over the length and payload. The receiver
would generate the same keystream to decrypt the length which
identifies the length of the message and the MAC offset, then
authenticate the length and payload, then decypt with the remaining
keystream.

Is it safer to define two keys to prevent implementations from screwing
this up? You have to split the decryption and authentication, so the
basic modes of libsodium cannot be used for instance. If a custom tag
generation scheme is being used, then the basic modes are already
unusable ...

*Failed Authentication*
What happens on a failed MAC attempt? Connection closure is the
easiest way to handle the situation.


> After a successful <code>encinit</code>/<code>encack</code>
> interaction from both sides, the messages format must use the
> "encrypted messages structure". Non-encrypted messages from the
> requesting peer must lead to a connection termination (can be
> detected by the 4 byte network magic in the unencrypted message
> structure).

The magic bytes are at the same offset and size as the encrypted length
field in the encrypted messages structure. So the magic bytes are not a
reliable way to identify unencrypted messages, although the probability
of collision is low.


> {|class=3D"wikitable"
> ! Field Size !! Description !! Data type !! Comments
> |-
> | 4 || length || uint32_t || Length of ciphertext payload in number
> of bytes
> |-
> | ? || ciphertext payload || ? || One or many ciphertext command &
> message data
> |-
> | 8 || MAC tag || ? || MAC-tag truncated to 8 bytes
> |}

Why have a fixed MAC length? I think the MAC length should be inferred
from the cipher + authentication mode. And the Poly1305 tag is 16 bytes.

*Unauthenticated Buffering*
Implementations are unlikely to (i.e. should not) process the payload
until authentication succeeds. Since the length field is 4 bytes, this
means an implementation may have to buffer up to 4 GiB of data _per
connection_ before it can authenticate the length field. If the outter
length field were reduced to 2 or 3 bytes, the unauthenticated
buffering requirements drop to 64 KiB and 16 MiB respectively. Inner
messages already have their own length, so they can span multiple
encrypted blocks without other changes. This will increase the
bandwidth requirements when the size of a single message exceeds 64 KiB
or 16 MiB, since it will require multiple authentication tags for that
message. I think an additional 16 bytes per 16 MiB seems like a good
tradeoff.


> A responding peer can inform the requesting peer over a re-keying
> with a <code>encack</code> message containing 33byte of zeros to
> indicate that all encrypted message following after this
> <code>encack</code> message will be encrypted with ''the next
> symmetric cipher key''.
>
> The new symmetric cipher key will be calculated by
> <code>SHA256(SHA256(old_symetric_cipher_key))</code>.
>
> Re-Keying interval is a peer policy with a minimum timespan of 600
> seconds.

Should the int64_t message count be reset to 0 on a re-key? Or should
the value reset to zero after 2^63-1? Hopefully the peer re-keys before
that rollover, or keystream reusage will occur. Unlikely that many
messages are sent on a single connection though. And presumably this
only re-keys the senders side? Bi-directional re-keying would be racy.



Lee

[0]https://tools.ietf.org/html/draft-ietf-tls-chacha20-poly1305-04