Re: [TLS] Binding imported PSKs to KDFs rather than hash functions

"Martin Thomson" <> Tue, 17 September 2019 01:26 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 099401200F8 for <>; Mon, 16 Sep 2019 18:26:42 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.7
X-Spam-Status: No, score=-2.7 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=pass (2048-bit key) header.b=p8Egz4Xd; dkim=pass (2048-bit key) header.b=MvUAZXJg
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id 3rwZxNcRDQQl for <>; Mon, 16 Sep 2019 18:26:39 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 5EC811200D6 for <>; Mon, 16 Sep 2019 18:26:39 -0700 (PDT)
Received: from compute1.internal (compute1.nyi.internal []) by mailout.west.internal (Postfix) with ESMTP id B61112E5 for <>; Mon, 16 Sep 2019 21:26:38 -0400 (EDT)
Received: from imap2 ([]) by compute1.internal (MEProxy); Mon, 16 Sep 2019 21:26:38 -0400
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; h=mime-version:message-id:in-reply-to:references:date:from:to :subject:content-type:content-transfer-encoding; s=fm3; bh=qcU+6 vPLKi3RvCQ2zCmBhgwXt5V9QyVVIN78R/ClrgE=; b=p8Egz4XdBrFLeeqT7kTvQ QoHw/i5RWAGxJ0OaRt49BWJ01K2sBJh7iHXyllSKe55Gv+n2cfNkpgHI9OhxjRqu Fxu/1Cev9SettyolLXVklS3SPtz409GYN8PdNdSKp5yAhJrAK6vhUmTW8zJXZm+k Me/rXPklXbyacbj+ujzE0Qt2BcAfU/CvvZEpYuueXO9HfRgafvX42zXXdn85hW2N e9VpE2hEsqFfXJoUgX/Jmwk9Z6OUCO1yYl+rQH65IkokVyYFJvTpVYYdy1leBh9G vdEHoq4DPWjUrEE76Hk9rdwi3U7EqklL/y2FRTnL1hQ5raw/VU+LPiiBojjIxZB3 g==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; bh=qcU+6vPLKi3RvCQ2zCmBhgwXt5V9QyVVIN78R/Clr gE=; b=MvUAZXJg4v5BlbdmuZ8sTBTH54HCVWwu8B2SQ6jow/VbIJo6/6OkaOVuR XlQ/2NpCVcT76MEwWXM3jkTD0R7NN9xdnIXQhAKtoft1UpHusGL0Erjyh5leN63T 4pSbRNv+h4qkjsOlrnmJWdDVf5wNCukZZtkgkSSIIcrqpVkY9q29f1R6jiBIyN93 KS7XKsxgFTo3mb1OKWRi1aNO+Z+2iHayFf+S0oaoA192KNK4NbPTX6auTjEh09fT arN+Pet6ZcvcxCich/4kw1S0Sd2Jo1B2zk+AVdtKkVi+AWmtwVggrOMbSX/QC/eM r/4IisE3k/3TMJ3VWqurZg9aJiZJg==
X-ME-Sender: <xms:TTaAXbPhO6fawhUgU4ElJkhVgza27hP2x6IM_z0v0OrvB6tI3PLuSw>
X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedufedrudeggdegkecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecunecujfgurhepofgfggfkjghffffhvffutgfgsehtqh ertderreejnecuhfhrohhmpedfofgrrhhtihhnucfvhhhomhhsohhnfdcuoehmtheslhho figvnhhtrhhophihrdhnvghtqeenucffohhmrghinhepghhithhhuhgsrdgtohhmpdhivg htfhdrohhrghenucfrrghrrghmpehmrghilhhfrhhomhepmhhtsehlohifvghnthhrohhp hidrnhgvthenucevlhhushhtvghrufhiiigvpedt
X-ME-Proxy: <xmx:TjaAXQD2M-UpVQu3NIIUIVOVZImei7i15aVY0NhzRuTHAh8OonQ7Pg> <xmx:TjaAXfMJzhvKBhP4cFMwe61u6cejKudL6wNsNy7w9_c3E_ylDwPLYA> <xmx:TjaAXXdxnFOh1y43iIuv5sVwagijXLynb0oYCGgr_7p0_p7fwbO_Zg> <xmx:TjaAXVH5OfqoOyfptmMeAtjgxgmEMPYXYg7DFtGkXEpt6RNfWGpVTw>
Received: by mailuser.nyi.internal (Postfix, from userid 501) id D7F23E00A9; Mon, 16 Sep 2019 21:26:37 -0400 (EDT)
X-Mailer: Webmail Interface
User-Agent: Cyrus-JMAP/3.1.7-237-gf35468d-fmstable-20190912v1
Mime-Version: 1.0
Message-Id: <>
In-Reply-To: <>
References: <>
Date: Tue, 17 Sep 2019 11:26:18 +1000
From: Martin Thomson <>
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
Archived-At: <>
Subject: Re: [TLS] Binding imported PSKs to KDFs rather than hash functions
X-Mailman-Version: 2.1.29
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: Tue, 17 Sep 2019 01:26:42 -0000

There are two points here to consider:

1. Whether the key that we are feeding into this process is going to be used exclusively for that purpose, or whether it might be used for something else.

2. How the key that is output from this process might need diversification.

What we learned from TLS 1.3 is that HKDF is effectively a completely different KDF when it is used with a different hash function.  And that taking the same key into two different functions was not advisable because there isn't a lot of analysis to support that particular usage pattern.

In thinking about the first point, we might want to consider whether the KDF that is used in the importer might need to be used in other ways.  Personally, when I see the question formulated this way, I am inclined to suggest that this key should be used exclusively for key import.  If that's the decision, that should be made very clear.

If we decide that we're gaining exclusive access, then the only other consideration I'm aware of on the input side is the binding to the origination of the key, as raised by Jonathan.  That is something we might gain by integrating something into the identity, or by adding a context attribute to the expansion (which might carry a session hash).  That concern is not reflected in the proposal here though.

If you have exclusive access to the input keying material, then you can very easily restrict this to HKDF.  If not, then I'd suggest that you need to use the more general form.  But then you also need to ensure that whatever inputs you feed into the KDF can't collide with inputs for the other usages.  That's tricky.

Then the question is how we identify the diversification parameters.  Right now, we want to diversify outputs based on TLS version and the hash algorithm associated with the cipher suite.  If this is only ever used for TLS, then we have a simple process: we identify the specific type of TLS PRF somehow and bake that into the KDF label.

How we do that is simple mechanics: each version of TLS we care about has a template KDF, which is parameterized by hash function.  As Chris proposes, we could include a TLS version and a hash function identifier.  That seems enough.

The final question is about multiple PRFs in TLS 1.2.  We never restricted input PSKs in TLS 1.2 to a single KDF, so in theory we could use a single output of this importer function for TLS 1.2.  However, I'm not sure that this is necessary if we allow for the possibility of an importer.  We could use different keys depending on the final selection of cipher suite (and therefore hash function).  I don't see any reason not to fix TLS 1.2 PSK usage at the same time as TLS 1.3.

On Sun, Sep 15, 2019, at 00:53, Christopher Wood wrote:
> Hi folks,
> Martin reviewed the external PSK draft [1] and filed a couple issues 
> [2,3] that are worth discussion here. I’d like to call attention to #16 
> [3] in particular. 
> TL;DR: Should we bind the importer to a KDF rather than a hash function?
> Currently, the importer draft assumes that an external PSK is 
> optionally associated with some hash function, and, if not, assumes 
> SHA256. The importer uses this hash function when deriving the imported 
> key. In particular, it’s the hash function used for HKDF-Extract and 
> HKDF-Expand, which runs over the external PSK blob and the constructed 
> ImportedIdentity to produce a unique, imported PSK. ImportedIdentity is 
> the structure that contains the external PSK identity, a protocol 
> label, and target hash function:
> ~~~
> struct {
>   opaque external_identity<1...2^16-1>;
>   opaque label<0..2^8-1>;
>   HashAlgorithm hash;
> } ImportedIdentity;
> ~~~
> The issue raised pointed out that the (protocol label, hash) tuple 
> effectively identifies a KDF. (Martin, please correct me if I’m 
> misinterpreting your comments!) Thus, perhaps it makes sense to replace 
> this with something simpler, e.g., 
> ~~~
> struct {
>   opaque external_identity<1...2^16-1>;
>   uint16 protocol_version;
>   uint16 kdf_identifier;
> } ImportedIdentity;
> ~~~
> Where ImportedIdentity.protocol_version is a code point (e.g., 0x0304 
> for TLS 1.3) and ImportedIdentity.kdf_identifier is a unique 
> (registry-defined) KDF function (e.g., 0x0001 for HKDF-SHA256). If we 
> did this, a couple interesting questions arise. 
> First, should we keep using HKDF as the importer KDF? Note that the 
> current ImportedIdentity.hash field is what diversifies imported PSKs 
> by hash function. The actual key derivation still uses HKDF with the 
> hash function associated with the external PSK. (SHA-256 is assumed if 
> none is specified.) If we replaced ImportedIdentity.hash with 
> ImportedIdentity.kdf_identifier, we would still get this 
> diversification, since each target KDF is bound to one hash function. 
> However, should the KDF corresponding to 
> ImportedIdentity.kdf_identifier be the KDF used by the importer for 
> derivation? That is, let’s say I have an external PSK "epsk" that's 
> associated with SHA-512. Moreover, let's assume 
> ImportedIdentity.kdf_identifier = 0xFEFE, which corresponds to some KDF 
> called MySpecialKDF. Should the derivation step be this?
> ~~~
> epskx = HKDF-SHA512-Extract(0, epsk)
> ipskx = HKDFSHA512-Expand-Label(epskx, "derived psk", 
> Hash(ImportedIdentity), Hash.length)
> ~~~
> Or this?
> ~~~
> epskx = MySpecialKDF-Extract(0, epsk)
> ipskx = MySpecialKDF-Label(epskx, "derived psk", 
> MySpecialKDF.Hash(ImportedIdentity), MySpecialKDF.length)
> ~~~
> Or something else entirely?
> Second, keys need to be imported for each supported ciphersuite and 
> corresponding hash function. How would we specify that if we now speak 
> of importers in terms of a target KDF?
> Thanks,
> Chris (no hat)
> [1]
> [2]
> [3]
> _______________________________________________
> TLS mailing list