From 7797c058d9eae4458d438e8859f83e194e760be1 Mon Sep 17 00:00:00 2001 From: Pascal Knecht Date: Fri, 4 Dec 2020 19:01:00 +0100 Subject: [PATCH] tls-hkdf: Implement binder PSK generation --- src/libtls/tls_hkdf.c | 30 ++++++++++++++++++++++++++++++ src/libtls/tls_hkdf.h | 14 ++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/src/libtls/tls_hkdf.c b/src/libtls/tls_hkdf.c index 0a29b68..c406b3e 100644 --- a/src/libtls/tls_hkdf.c +++ b/src/libtls/tls_hkdf.c @@ -626,6 +626,35 @@ METHOD(tls_hkdf_t, resume, bool, return TRUE; } +METHOD(tls_hkdf_t, binder, bool, + private_tls_hkdf_t *this, chunk_t seed, chunk_t *out) +{ + chunk_t binder_key, finished_key; + + if (!generate_secret(this, TLS_HKDF_RES_BINDER, chunk_empty, &binder_key)) + { + DBG1(DBG_TLS, "unable to derive binder key"); + return FALSE; + } + + if (!expand_label(this, binder_key, chunk_from_str("finished"), chunk_empty, + this->hasher->get_hash_size(this->hasher), &finished_key)) + { + chunk_clear(&binder_key); + return FALSE; + } + chunk_clear(&binder_key); + + if (!this->prf->set_key(this->prf, finished_key) || + !this->prf->allocate_bytes(this->prf, seed, out)) + { + chunk_clear(&finished_key); + return FALSE; + } + chunk_clear(&finished_key); + return TRUE; +} + METHOD(tls_hkdf_t, allocate_bytes, bool, private_tls_hkdf_t *this, chunk_t key, chunk_t seed, chunk_t *out) @@ -684,6 +713,7 @@ tls_hkdf_t *tls_hkdf_create(hash_algorithm_t hash_algorithm, chunk_t psk) .derive_finished = _derive_finished, .export = _export, .resume = _resume, + .binder = _binder, .allocate_bytes = _allocate_bytes, .destroy = _destroy, }, diff --git a/src/libtls/tls_hkdf.h b/src/libtls/tls_hkdf.h index 38e8de8..c280ebd 100644 --- a/src/libtls/tls_hkdf.h +++ b/src/libtls/tls_hkdf.h @@ -138,6 +138,20 @@ struct tls_hkdf_t { chunk_t *psk); /** + * Generate a PSK binder. + * + * @note The transcript hash is built of the partial ClientHello message up + * to and including the PreSharedKey extension's identities field, excluding + * the actual binders (their length is included in that of the extension(s) + * and message, though), as per RFC 8446, section 4.2.11.2. + * + * @param seed transcript-hash of client_hello to seed the PRF + * @param psk_binder generated psk binder + * @return TRUE if output was generated + */ + bool (*binder)(tls_hkdf_t *this, chunk_t seed, chunk_t *psk_binder); + + /** * Use the internal PRF to allocate data (mainly for the finished message * where the key is from derive_finished() and the seed is the transcript * hash). -- 2.7.4