tls-hkdf: Implement binder PSK generation
authorPascal Knecht <pascal.knecht@hsr.ch>
Fri, 4 Dec 2020 18:01:00 +0000 (19:01 +0100)
committerTobias Brunner <tobias@strongswan.org>
Fri, 12 Feb 2021 13:35:23 +0000 (14:35 +0100)
src/libtls/tls_hkdf.c
src/libtls/tls_hkdf.h

index 0a29b68..c406b3e 100644 (file)
@@ -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,
                },
index 38e8de8..c280ebd 100644 (file)
@@ -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).