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] https://github.com/tlswg/draft-ietf-tls-external-psk-importer [2] https://github.com/tlswg/draft-ietf-tls-external-psk-importer/issues/15 [3] https://github.com/tlswg/draft-ietf-tls-external-psk-importer/issues/16 _______________________________________________ TLS mailing list TLS@ietf.org https://www.ietf.org/mailman/listinfo/tls