public inbox for bitcoindev@googlegroups.com
 help / color / mirror / Atom feed
From: Jonas Schnelli <dev@jonasschnelli•ch>
To: bitcoin-dev@lists•linuxfoundation.org
Subject: Re: [bitcoin-dev] p2p authentication and encryption BIPs
Date: Wed, 18 May 2016 10:00:44 +0200	[thread overview]
Message-ID: <573C212C.6070604@jonasschnelli.ch> (raw)
In-Reply-To: <20160409154038.4c04dd9b@laptop-m1330>


[-- Attachment #1.1: Type: text/plain, Size: 5740 bytes --]

Hi Lee

Thank you very much for the valuable input.
I'm still processing your feedback....

> 
> *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.
> 

Yes. This could be something that could be extended once the BIP is
stable and/or implemented.



>> <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. 
>>
>> <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.
> 

Right. The AEAD construct I though of is probably called
chacha20-poly1305@openssh•com and specified in
https://github.com/openssh/openssh-portable/blob/05855bf2ce7d5cd0a6db18bc0b4214ed5ef7516d/PROTOCOL.chacha20poly1305#L34

I think this construct has already serval implementations and is widely
used.

I have updated the BIP to mention the chacha20-poly1305@openssh•com
specification.

> 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.

Yes. I think closing would make sense.

>> 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.

Yes. This is a good point.
The implementation should probably also accept messages that contain the
4 byte network magic from unencrypted messages (to avoid possible
collisions).
If the message is unencrypted, the length check or the unsuccessful
authentication check will lead to a disconnect.

>> {|class="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.
> 

Good point.
I have mentioned this now in the BIP but I think the BIP should allow
message > 16 MiB.
I leave the max. message length up to the implementation while keeping
the 4 byte length on the protocol level.

> 
>> 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.

I just added the RFC4253 recommendation as a must (re-key after every
1GB of data sent or received).


</jonas>


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

  reply	other threads:[~2016-05-18  8:00 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-23 15:24 Jonas Schnelli
2016-03-23 16:44 ` Tier Nolan
2016-03-23 20:36 ` Tom
2016-03-23 21:40   ` Eric Voskuil
2016-03-23 21:55   ` Jonas Schnelli
2016-03-25 10:36     ` Tom
2016-03-25 18:43       ` Jonas Schnelli
2016-03-25 20:42         ` Tom
2016-03-26  9:01           ` Jonas Schnelli
2016-03-26 23:23           ` James MacWhyte
2016-03-27 11:58             ` Jonas Schnelli
2016-03-27 17:04               ` James MacWhyte
2016-03-24  0:37   ` Sergio Demian Lerner
2016-03-24  2:16 ` Luke Dashjr
2016-03-24 17:20 ` Chris
2016-03-25 10:41   ` Tom
2016-03-25  7:17 ` Lee Clagett
2016-03-25 10:17 ` Jonas Schnelli
2016-04-01 21:09 ` Jonas Schnelli
2016-04-09 19:40   ` Lee Clagett
2016-05-18  8:00     ` Jonas Schnelli [this message]
2016-05-25  0:22       ` Lee Clagett
2016-05-25  9:36         ` Jonas Schnelli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=573C212C.6070604@jonasschnelli.ch \
    --to=dev@jonasschnelli$(echo .)ch \
    --cc=bitcoin-dev@lists$(echo .)linuxfoundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox