Re: [TLS] rfc7366: is encrypt-then-mac implemented?

Manuel Pégourié-Gonnard <mpg@polarssl.org> Sat, 01 November 2014 21:32 UTC

Return-Path: <mpg@polarssl.org>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (ietfa.amsl.com [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 612C71A1A6F for <tls@ietfa.amsl.com>; Sat, 1 Nov 2014 14:32:23 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: 2.397
X-Spam-Level: **
X-Spam-Status: No, score=2.397 tagged_above=-999 required=5 tests=[BAYES_05=-0.5, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HELO_MISMATCH_COM=0.553, HOST_EQ_NL=1.545, J_CHICKENPOX_37=0.6, MIME_8BIT_HEADER=0.3, SPF_PASS=-0.001] autolearn=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 8rMT2EMW1XH7 for <tls@ietfa.amsl.com>; Sat, 1 Nov 2014 14:32:21 -0700 (PDT)
Received: from vps2.offspark.com (vps2.brainspark.nl [141.138.204.106]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 09BE41A1A6A for <tls@ietf.org>; Sat, 1 Nov 2014 14:32:20 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=polarssl.org; s=exim; h=Subject:Content-Transfer-Encoding:Content-Type:In-Reply-To:References:To:MIME-Version:From:Date:Message-ID; bh=6NKm3PusigNzvk4hfmNbb8FHaOrQBfripy3avNS0l3E=; b=hXuhJX0OQ2iVxPTFG7HLBZn0bNawkFi/RMUu/rfOalrzwxqtnnP1L621QgT8u6+2E7SnG3im/Ocyx0st7i3sqh/2kMhqOsAQX3VL4t8+vRIBPoVQfp+e38At8XE7WeOLG2ySyAaAc0vDQrq6CgrI4uu0CPLMOH/1DX9SRydyv2Y=;
Received: from mna75-11-88-161-199-191.fbx.proxad.net ([88.161.199.191] helo=[192.168.0.12]) by vps2.offspark.com with esmtpsa (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <mpg@polarssl.org>) id 1XkgHM-0006qz-VP; Sat, 01 Nov 2014 22:32:13 +0100
Message-ID: <54555161.1040606@polarssl.org>
Date: Sat, 01 Nov 2014 22:32:17 +0100
From: Manuel Pégourié-Gonnard <mpg@polarssl.org>
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0
MIME-Version: 1.0
To: "Yngve N. Pettersen" <yngve@spec-work.net>, tls@ietf.org
References: <9A043F3CF02CD34C8E74AC1594475C739B9DB35D@uxcn10-5.UoA.auckland.ac.nz> <op.xonuwux33dfyax@killashandra.invalid.invalid>
In-Reply-To: <op.xonuwux33dfyax@killashandra.invalid.invalid>
Content-Type: text/plain; charset="iso-8859-15"
Content-Transfer-Encoding: 7bit
X-SA-Exim-Connect-IP: 88.161.199.191
X-SA-Exim-Mail-From: mpg@polarssl.org
X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000)
X-SA-Exim-Scanned: Yes (on vps2.offspark.com)
Archived-At: http://mailarchive.ietf.org/arch/msg/tls/W4YZGsxZt6akvN6ezcO9m3H7vmU
Subject: Re: [TLS] rfc7366: is encrypt-then-mac implemented?
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/tls/>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Sat, 01 Nov 2014 21:32:23 -0000

On 01/11/2014 20:25, Yngve N. Pettersen wrote:
> For reference, I have tried to implement RFC 7366 in my TLS Prober, but I  
> have not been able to establish a connection with the "eid" server. It  
> seems to have some non-standard requirements to the client that AFAICT  
> have not been documented anywhere.
>
IIRC, I found out that it doesn't like 03 00 as the record-level version number
in the ClientHello. I was able to connect by setting the minimum version of my
test client to TLS 1.0, which upped the record-level version number of the
ClientHello to 03 01.

> I am starting to wonder if the confusion about this spec update is partly  
> due to the way the record structure is defined, with the length separate  
>  from the data vectors. This separation have been a problem in connection  
> with at least some extensions.
> 
Out of curiosity, which ones?

> The way a TLS Protocol record is defined in previous versions (Using TLS  
> 1.2), before this update is, can a generic way be rewritten as:
> 
>    struct {
>         ContentType type;
>         ProtocolVersion version;
>         opaque record_data<0..maxlength>
>    } TLS_Record;
> 
> This is how all clients and servers will parse current SSL and TLS  
> versions' records on the wire, and also how all the intermediate servers  
> (the ones that are causing concern for version rollback recovery) will be  
> parsing the TLS traffic.
> 
Agreed so far. (And AFAIK all implementations of RFC 7366 agreed on this point.)

> The field record_data containing a strucure of exactly the length of  
> record_data
> 
>    struct {
>      select(encryption_mode) {
>         case plaintext: TLS_Plaintext_data;
>         case stream_encrypted: TLS_Stream_Encrypted_data;
>         case block_encrypted: TLS_Block_Encrypted_data;
>      }
>    } TLS_Record_payload;
> 
And AEAD, and plaintext can be seen as a special case of Stream.

> With RFC7366 the format for the encrypted record payloads got changes, and  
> it seems to me that the problem is a disagreement of what the length field  
> in the TLSCipherText record applies to.
> 
As far as I'm concerned, I've always been convinced that it was the length of
the rest of the record (in that case, padded-encrypted stuff plus unencrypted
MAC), and I've only mentioned alternative hypothesis as a sort of reductio ad
absurdum.

>    struct {
>       opaque IV[SecurityParameters.record_iv_length];
>       block-ciphered struct {
>         opaque  
> fragment[TLS_Record.record_data.length-SecurityParameters.record_iv_length-MAC-paddinglength-1];
>         uint8 padding [paddinglength];
>         uint8 paddinglength;
>       } encrypted;
>       opaque MAC[MAClength];
>    } TLS_EtM_Block_Encrypted_data;
> 
I find this one complicated: to me it looks more natural to defined the length
of the record as content length + padding length + etc. than otherwise.

> I think one thing that is to be determined is whether this rewritten  
> structure definitions accurately describes both the old format and the new  
> RFC 7366 format. Do they?
> 
I guess they do, but I agree with Peter that such extensive redefinitions are
not really suited to an erratum.

> If RFC 7366 means to say that the MAC field is no longer part of the  
> record_data field (and not counted in the length field), then that is  
> going to cause trouble, because processors that are not aware of the  
> extension will then read the first bytes of the MAX as the ContentType  
> field and the version field, probably resulting in a connection closure.
> 
I think it's pretty clear for everyone RFC 7366 never intended to say that.

> The second issue that seems to have developed is which value to use as the  
> length part of the MAC calculation.
> 
Which was actually the only issue causing interop failures.

> Adapted to my rewritten structure the question is if the MAC (for block  
> cipher encryption) is calculated as
> 
>     MAC(MAC_write_key, seq_num +
>         TLS_Record.type +
>         TLS_Record.version +
>         TLS_Record.record_data.length +
>         IV +
>         ENC(content + padding + padding_length));
> 
> or
> 
>     MAC(MAC_write_key, seq_num +
>         TLS_Record.type +
>         TLS_Record.version +
>         TLS_EtM_Block_Encrypted_data.fragment.length +
>         IV +
>         ENC(content + padding + padding_length));
> 
If I follow correctly your new notation, the second one is not what the RFC
meant: the length should be the length of
TLS_EtM_Block_Encrypted_data.encrypted, not fragment (ie including the padding).

> As written, as I understand it, and assuming compatibility with ignorant  
> intermediates, RFC 7366 specifies the first formula.
> 
That's what I first thought too, but it turns out it was not the intention of
the RFC and most importantly, it's not what the implementations deployed so far do.

Unless you're aware of an implementation that is deployed and incompatible with
the eid server (which I seriously hope not), there's not point discussing which
choice makes the most sense: it's to match the deployed implementation(s).

> My suggestion for an answer to the first question is that we have to  
> maintain backwards compatibility with ignorant intermediates, which means  
> that TLSCipherText.length MUST count the MAC bytes, not just the fragment  
> (including padding).
> 
I think we all agree, and always agreed, on this one.

> Regarding the second question, IMO it does not really matter much which  
> value is used. However, it is probably easier to use the length of the  
> encrypted block, rather than TLSCipherText.length, since  
> TLSCipherText.length have to be calculated instead of derived from the  
> MACed encrypted block.
> 
Yes. (Just nitpicking: when doing authenticated decryption, it's the other way:
the length of the encrypted block needs to be computed, while the length of the
record is readily available, so the situation is quite symmetric actually.)

> Given the current confusion we need at least an errata that accurately  
> specifies which values include which data.
> 
I'm under the impression that Peter's paragraph in [1] suits this goal.

[1] http://mailarchive.ietf.org/arch/msg/tls/3NOHlIUShLo9AAzXx4t2u7QV8Sw

Do you agree? I reproduce the specific paragraph here for convenience's sake:

  Note that the value of the 'uint16 length' field in the TLSCiphertext record
  differs from the length value used in the MAC calculation, since the
  TLSCiphertext record contains both the ciphtertext and the MAC, while the
  MAC calculation is performed only over the ciphertext.  So the length value
  encoded in the TLSCiphertext record is 'length' while the length value used
  in the MAC calculation is 'length - SecurityParameters.mac_length'.

> However, given that such changes may modify the meaning more than a normal  
> errata do, perhaps a better idea is a new RFC that either replace RFC 7366  
> or one that specifies a new extension ID and deprecate the old one, so  
> that we reduce the potential for confusion among implementations?

Unless we have reasons to think there already are mutually incompatible
implementations in the wild, I don't think it's worth the trouble allocating a
new extension, which would delay adoption of the feature, while we want it
available and actually usable sooner rather than later.

> After  
> all, some implementers might miss the existence of the errata, and in this  
> case the errata would be important for the proper understanding of the  
> specification.
> 
I'd expect any half-serious implementer to test interop with at least one other
implementation before releasing. Unfortunately, experience proves people are not
always serious about it. I honestly don't know.

Manuel.