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)
.derive_finished = _derive_finished,
.export = _export,
.resume = _resume,
+ .binder = _binder,
.allocate_bytes = _allocate_bytes,
.destroy = _destroy,
},
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).