[tcpm] More on KDFs and PRFs

Eric Rescorla <ekr@networkresonance.com> Mon, 27 July 2009 00:58 UTC

Return-Path: <ekr@networkresonance.com>
X-Original-To: tcpm@core3.amsl.com
Delivered-To: tcpm@core3.amsl.com
Received: from localhost (localhost []) by core3.amsl.com (Postfix) with ESMTP id C72F53A6887 for <tcpm@core3.amsl.com>; Sun, 26 Jul 2009 17:58:30 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.827
X-Spam-Status: No, score=-1.827 tagged_above=-999 required=5 tests=[AWL=0.772, BAYES_00=-2.599]
Received: from mail.ietf.org ([]) by localhost (core3.amsl.com []) (amavisd-new, port 10024) with ESMTP id cBzi-9t9nnlM for <tcpm@core3.amsl.com>; Sun, 26 Jul 2009 17:58:30 -0700 (PDT)
Received: from romeo.rtfm.com (romeo.rtfm.com []) by core3.amsl.com (Postfix) with ESMTP id 054513A6849 for <tcpm@ietf.org>; Sun, 26 Jul 2009 17:58:29 -0700 (PDT)
Received: from romeo.rtfm.com (localhost.rtfm.com []) by romeo.rtfm.com (Postfix) with ESMTP id 4FE9150822 for <tcpm@ietf.org>; Sun, 26 Jul 2009 18:02:05 -0700 (PDT)
Date: Sun, 26 Jul 2009 18:02:05 -0700
From: Eric Rescorla <ekr@networkresonance.com>
To: tcpm@ietf.org
User-Agent: Wanderlust/2.14.0 (Africa) Emacs/22.3 Mule/5.0 (SAKAKI)
MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka")
Content-Type: text/plain; charset="US-ASCII"
Message-Id: <20090727010205.4FE9150822@romeo.rtfm.com>
Subject: [tcpm] More on KDFs and PRFs
X-BeenThere: tcpm@ietf.org
X-Mailman-Version: 2.1.9
Precedence: list
List-Id: TCP Maintenance and Minor Extensions Working Group <tcpm.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/listinfo/tcpm>, <mailto:tcpm-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/tcpm>
List-Post: <mailto:tcpm@ietf.org>
List-Help: <mailto:tcpm-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tcpm>, <mailto:tcpm-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 27 Jul 2009 00:58:30 -0000

Greg and I spent a while discussing the construction of the
KDF in draft-lebovitz-ietf-tcpm-ao-crypto-01, and I think 
there's some confusion about what the right interfaces are.

This document does two things:

- Defines the interface and requirements for all KDFs
- Provides two specific KDFs.

As far as the first job goes, the basic interface you want for a KDF is:

     KDF(Master_Key, Context, Output_Length)

Where Output_Length describes the size of the key you're deriving with
the KDF. A KDF of this sort can be used in a mix-and-match fashion
with any target cryptographic algorithm (i.e., can generate keys for
any algorithm) because it can generate an arbitrary length key.  For
instance, you could use an HMAC-SHA based KDF to generate keys for AES
or RC4. In fact, this is precisely what both TLS and IPsec do because
they need to generate keys for both a MAC algorithm and an encryption

So, KDFs for TCP-AO need to meet the above interface, with:

- Master_Key      == the key from the MKT
- Context         == the data block
- Output_length   == the right size key for the target integrity

Aside from the security requirements for a KDF, this is all you need
to say in terms of requirements on future KDFs.

With that in mind, we now need to define concrete KDFs that meet the
above interface spec. For concreteness, let's focus on the
HMAC-SHA-1-based KDF.

This KDF needs to match the above interface but we're otherwise
unconstrained. However, there seems to be a desire to have a
KDF that matches the (IMHO over-engineered) SP800-108 definitions, and this
is quite possible within this framework. We simply need to arrange for
the correct input values for the PRF that is the core of the KDF.

The pseudocode for this looks like:

    hmac_sha1_kdf(MK, context, output_length) {
      needed = output_length
      i = 0
      result = ""
      while(needed) {
        blk = i + "TCP-AO" + context + output_length
        result += HMAC-SHA1(MK, blk)
        needed -= 160
      return result

Note that if you generate a 160-bit key, this is computationally
compatible with what's defined in 3.1.1. We just hide the Input
construction under the covers of the KDF. This means we could do
a non SP800-108 KDF, such as the TLS PRF, simply by saying

TLS_PRF_KDF(MK, context, output_length) = TLS_PRF(MK, context)[0..output_length-1]

Is this clear to people? Are there objections to this overall strategy?
If not, I can provide text that implements it.