1) What would be the implications of this for DTLS? (Knowing that one 
difference between TLS and DTLS is the record header)

2) In some implementations the record framing/parsing and encryption/decryption 
are down at different layers. Would this proposal make this type of 
implementation impossible? 

-- Fabrice


> On Nov 27, 2015, at 06:35, Bryan A Ford <brynosau...@gmail.com> wrote:
> 
> The idea of encrypting TLS record headers has come up before, the most
> important purpose being to hide record lengths and boundaries and make
> fingerprinting and traffic analysis harder.  I had convinced myself that
> goal this would be "too hard" to accomplish in TLS 1.3, but after
> further thought I'm not so sure.  So I would like to request comment on
> one approach that strikes me as a practical and requires only a rather
> minor change to the current spec.
> 
> The quick summary:
> 
> * To encrypt a record, we first AEAD-encrypt the record's payload,
> protecting the header fields via the additional_data, exactly as
> currently specified.  But then we XOR-encrypt the 5-byte TLS header just
> before transmission, using a (separate) stream cipher indexed by a nonce
> that depends on record sequence number and *_write_iv, in exactly the
> same way the AEAD is already nonce-indexed.
> 
> * To decrypt a record, we simply do the reverse: first use the stream
> cipher with the appropriate nonce to XOR-decrypt the 5-byte TLS header,
> then sanity-check it as usual to determine its length, read the rest of
> the record, and submit it to AEAD for decryption and full integrity
> checking as before.
> 
> That's it, in a nutshell.  Two likely concerns immediately arise,
> discussed below, but feel free to TL;DR the rest if you don't share
> these concerns.
> 
> ---
> 
> Concern #1: What if an active attacker messes with the TLS header,
> especially the length field, since stream ciphers don't protect
> integrity?  The simple answer is that *exactly* the same thing happens
> as now: the AEAD decryption attempt fails, because the
> (stream-decrypted) header is AEAD-protected as additional_data.  Nothing
> is gained or lost.
> 
> SSH, which did something like this, ran into trouble with attackers
> being able to twiddle the record length field to make the record length
> look big, causing the receiver to try to receive a very large record,
> and hence appear to the user to hang, instead of immediately detecting
> the modification and terminating the connection.  But there are three
> mitigating factors here: (1) TLS is not usually used for interactive
> terminal traffic like SSH is; (2) TLS's 2-byte record length field
> imposes a pretty reasonable upper-bound on the maximum size an attacker
> could maliciously make a record appear to be; and (3) if this risk of
> length-twiddling is at all a problem in this proposed encrypted-header
> protocol, then it's already a problem for the current TLS 1.3 spec
> without encrypted headers, because active attackers can twiddle the bits
> of a cleartext length field just as easily (and even be *certain* they
> are making the length appear large!).  So I can't see any way this
> length-twiddling vulnerability becomes any worse, and maybe it gets a
> bit better (because the attacker can no longer be entirely certain
> whether he's setting a 1 bit to 0 or a 0 bit to 1).
> 
> ---
> 
> Concern #2: Do we want to have to go to the trouble of adding a stream
> cipher to every TLS 1.3-compatible ciphersuite?  Answer: maybe not, but
> we don't necessarily need to.  We could instead just specify a generic
> method of using the ciphersuite's main AEAD as a stream cipher for
> header encryption/decryption purposes.
> 
> The conceptually simplest approach I can think of: In the specification
> of how AEAD nonces are generated (section 5.2.2 of
> draft-ietf-tls-tls13-07), reserve the least-significant bit of the
> record sequence number, so that sequence numbers increment by 2 rather
> than 1 each record.  Thus, we get two unique nonces per record from the
> same set of symmetric keys.  We first use the nonce with a '0'
> least-significant bit to perform the regular AEAD-encryption of the
> record with the header info as additional_data.
> 
> Then for the same record we use the nonce with a '1' least-significant
> to AEAD-encrypt a sequence of five zero bytes ("\0\0\0\0\0"), and use
> the first five bytes of result as the cipherstream to XOR the 5-byte TLS
> header with before transmitting.  The AEAD will of course uselessly
> append some kind of authenticator to this ciphertext that we won't end
> up using, but that's OK.  The receiver will just use AEAD-encrypt
> (again) on the same five-zero-byte message to reproduce the 5
> cipherstream bytes with which to decrypt the TLS header.  Thus, senders
> perform two AEAD-encrypts per record, and receivers do one AEAD-encrypt
> and one AEAD-decrypt per record.
> 
> This approach seems pretty conceptually clean and simple, but has the
> performance downside that we always need to invoke the AEAD twice per
> record rather than once, which might be (a bit) costly especially when
> records are small.  So a simple refinement is to amortize this cost
> across records: e.g., once every 256 records (every sequence number
> ending in 0x00) we AEAD-encrypt a sequence of 5*256=1280 zero bytes, and
> the result in 5-byte chunks as the cipherstream with which to encrypt
> and decrypt 256 consecutive TLS record headers.  Thus, we're only adding
> one additional AEAD-encryption of a "normal-packet-sized" 1280-byte blob
> once every 256 records, which seems likely to be a pretty
> inconsequential performance cost.
> 
> ---
> 
> Comments?
> 
> Thanks
> Bryan
> 

_______________________________________________
TLS mailing list
TLS@ietf.org
https://www.ietf.org/mailman/listinfo/tls

Reply via email to