From 3e535c31b467cd392d78041e5bd6aa1f48a34912 Mon Sep 17 00:00:00 2001 From: Pascal Knecht Date: Sun, 22 Nov 2020 21:30:45 +0100 Subject: [PATCH] tls-hkdf: Implement resumption key generation --- src/libtls/tls_hkdf.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/libtls/tls_hkdf.h | 11 +++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/libtls/tls_hkdf.c b/src/libtls/tls_hkdf.c index 002d481f1..0a29b6855 100644 --- a/src/libtls/tls_hkdf.c +++ b/src/libtls/tls_hkdf.c @@ -586,6 +586,46 @@ METHOD(tls_hkdf_t, export, bool, return TRUE; } +METHOD(tls_hkdf_t, resume, bool, + private_tls_hkdf_t *this, chunk_t messages, chunk_t nonce, chunk_t *key) +{ + chunk_t resumption_master; + + if (this->phase != HKDF_PHASE_3) + { + DBG1(DBG_TLS, "unable to generate resumption key material"); + return FALSE; + } + if (!nonce.len) + { + DBG1(DBG_TLS, "no nonce provided"); + return FALSE; + } + + /** + * PSK associated with the ticket according to RFC 8446, section 4.6.1 + * + * HKDF-Expand-Label(resumption_master_secret, + * "resumption", ticket_nonce, Hash.length) + */ + if (!generate_secret(this, TLS_HKDF_RES_MASTER, messages, + &resumption_master)) + { + DBG1(DBG_TLS, "unable to derive resumption master secret"); + return FALSE; + } + + if (!expand_label(this, resumption_master, chunk_from_str("resumption"), + nonce, this->hasher->get_hash_size(this->hasher), key)) + { + chunk_clear(&resumption_master); + DBG1(DBG_TLS, "unable to expand key material"); + return FALSE; + } + chunk_clear(&resumption_master); + return TRUE; +} + METHOD(tls_hkdf_t, allocate_bytes, bool, private_tls_hkdf_t *this, chunk_t key, chunk_t seed, chunk_t *out) @@ -643,6 +683,7 @@ tls_hkdf_t *tls_hkdf_create(hash_algorithm_t hash_algorithm, chunk_t psk) .derive_iv = _derive_iv, .derive_finished = _derive_finished, .export = _export, + .resume = _resume, .allocate_bytes = _allocate_bytes, .destroy = _destroy, }, diff --git a/src/libtls/tls_hkdf.h b/src/libtls/tls_hkdf.h index 2ce3d038a..38e8de82a 100644 --- a/src/libtls/tls_hkdf.h +++ b/src/libtls/tls_hkdf.h @@ -126,6 +126,17 @@ struct tls_hkdf_t { bool (*export)(tls_hkdf_t *this, char *label, chunk_t context, chunk_t messages, size_t length, chunk_t *key); + /** + * Generate resumption PSKs. + * + * @param messages handshake messages + * @param nonce nonce to use for this PSK + * @param psk generated PSK + * @return TRUE if PSK successfully generated + */ + bool (*resume)(tls_hkdf_t *this, chunk_t messages, chunk_t nonce, + chunk_t *psk); + /** * 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