Re: [TLS] Last Call: <draft-kanno-tls-camellia-00.txt> (Additionx

Martin Rex <> Mon, 14 March 2011 17:27 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id B3C773A6D6C; Mon, 14 Mar 2011 10:27:51 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -9.924
X-Spam-Status: No, score=-9.924 tagged_above=-999 required=5 tests=[AWL=-0.275, BAYES_00=-2.599, HELO_EQ_DE=0.35, J_CHICKENPOX_36=0.6, RCVD_IN_DNSWL_HI=-8]
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id y3oHp6rBKNZk; Mon, 14 Mar 2011 10:27:50 -0700 (PDT)
Received: from ( []) by (Postfix) with ESMTP id 71CD73A6D26; Mon, 14 Mar 2011 10:27:50 -0700 (PDT)
Received: from by (26) with ESMTP id p2EHSYrn001515 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 14 Mar 2011 18:28:34 +0100 (MET)
From: Martin Rex <>
Message-Id: <>
To: (Nikos Mavrogiannopoulos)
Date: Mon, 14 Mar 2011 18:28:33 +0100 (MET)
In-Reply-To: <> from "Nikos Mavrogiannopoulos" at Mar 11, 11 08:20:59 am
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
X-SAP: out
Subject: Re: [TLS] Last Call: <draft-kanno-tls-camellia-00.txt> (Additionx
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Mon, 14 Mar 2011 17:27:51 -0000

Nikos Mavrogiannopoulos wrote:
> This sounds pretty awkward decision because HMAC per record is full
> (e.g. 160-bits on SHA-1), but the MAC on the handshake message
> "signature" is truncated to 96-bits. Why wasn't the record MAC
> truncated as well? In any case saving few bytes per handshake
> is much less of value than saving few bytes per record. Was
> there any other rationale for truncation?

Are you wondering why the HMAC on the TLS data records is is sent
in its full beauty, while the TLS Finished.verify_data is a
truncated output of the PRF (which in the abstract definintion
uses HMAC as the outermost function, but in the case of TLSv1.0
is actually the XOR of two different HMACs over half the secret).

The reason might be about the "secret" input to the HMAC, which in
case of the TLS data records is a derived traffic key, while in
case of the Finished.verify_data, is the "master secret" of the session.

That was, what I assume, the fear, based on the second part of this
message from Dan Simon

and the second part of this message from Hugo Krawczyk 

Since the TLSv1.0 finished message was defined based on the output
of the TLS PRF (a function with indefinite output length),
defining a truncation was inevitable.  :)

A Finished message of 20 bytes size would have required A(1) for SHA-1
and A(2) for MD5, a 16 bytes size would only have required A(1) from
both, but truncated the P_SHA1() output by 32 bits while leaving
the P_MD5() output in full.  For 12 bytes size, both P_SHA1() and
P_MD5() output is truncated (by 64 and 32 bits respectively), while
still remaining in the "safe truncation" area of "no less than half
the output size of the underlying hash function" (rfc-2104, section-5)
for both MD5 and SHA-1.

Recall how the TLS PRF is defined in TLSv1.0 (rfc-2246):

first as a generic TLS PRF:

       P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
                              HMAC_hash(secret, A(2) + seed) +
                              HMAC_hash(secret, A(3) + seed) + ...

       Where + indicates concatenation.

       A() is defined as:
           A(0) = seed
           A(i) = HMAC_hash(secret, A(i-1))

Then as a specific PRF for use with TLSv1.0 (reused by TLSv1.1)

   S1 and S2 are the two halves of the secret and each is the same
   length. S1 is taken from the first half of the secret, S2 from the
   second half. Their length is created by rounding up the length of the
   overall secret divided by two; thus, if the original secret is an odd
   number of bytes long, the last byte of S1 will be the same as the
   first byte of S2.

       L_S = length in bytes of secret;
       L_S1 = L_S2 = ceil(L_S / 2);

   The secret is partitioned into two halves (with the possibility of
   one shared byte) as described above, S1 taking the first L_S1 bytes
   and S2 the last L_S2 bytes.

   The [TLSv1.0] PRF is then defined as the result of mixing the two
   pseudorandom streams by exclusive-or'ing them together.

       PRF(secret, label, seed) = P_MD5(S1, label + seed) XOR
                                  P_SHA-1(S2, label + seed);

and how it is used in the TLSv1.0 Finished message:

       struct {
           opaque verify_data[12];
       } Finished;

           PRF(master_secret, finished_label, MD5(handshake_messages) +
           SHA-1(handshake_messages)) [0..11];