From 55cd86e31f94ed330c0c7a53a577750a92a2b533 Mon Sep 17 00:00:00 2001 From: Kai Michaelis Date: Thu, 28 Apr 2016 15:52:41 +0200 Subject: add label parameter to KDF::derive_key --- src/lib/kdf/prf_tls/prf_tls.cpp | 6 ++++-- src/lib/kdf/prf_tls/prf_tls.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src/lib/kdf/prf_tls') diff --git a/src/lib/kdf/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp index 547b0c9c8..f15688eba 100644 --- a/src/lib/kdf/prf_tls/prf_tls.cpp +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -73,7 +73,8 @@ void P_hash(byte out[], size_t out_len, size_t TLS_PRF::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, - const byte salt[], size_t salt_len) const + const byte salt[], size_t salt_len, + const byte[], size_t) const { const size_t S1_len = (secret_len + 1) / 2, S2_len = (secret_len + 1) / 2; @@ -87,7 +88,8 @@ size_t TLS_PRF::kdf(byte key[], size_t key_len, size_t TLS_12_PRF::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, - const byte salt[], size_t salt_len) const + const byte salt[], size_t salt_len, + const byte[], size_t) const { P_hash(key, key_len, *m_mac, secret, secret_len, salt, salt_len); return key_len; diff --git a/src/lib/kdf/prf_tls/prf_tls.h b/src/lib/kdf/prf_tls/prf_tls.h index a51006d88..37a517125 100644 --- a/src/lib/kdf/prf_tls/prf_tls.h +++ b/src/lib/kdf/prf_tls/prf_tls.h @@ -25,7 +25,8 @@ class BOTAN_DLL TLS_PRF final : public KDF size_t kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, - const byte salt[], size_t salt_len) const override; + const byte salt[], size_t salt_len, + const byte label[], size_t label_len) const override; TLS_PRF(); private: @@ -45,7 +46,8 @@ class BOTAN_DLL TLS_12_PRF final : public KDF size_t kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, - const byte salt[], size_t salt_len) const override; + const byte salt[], size_t salt_len, + const byte label[], size_t label_len) const override; explicit TLS_12_PRF(MessageAuthenticationCode* mac) : m_mac(mac) {} -- cgit v1.2.3 From cf74d1c376df1d9e6400e264a1d059720eeaa059 Mon Sep 17 00:00:00 2001 From: Kai Michaelis Date: Wed, 1 Jun 2016 11:57:42 +0200 Subject: make sure kdf labels are always used --- src/lib/kdf/hkdf/hkdf.cpp | 3 ++- src/lib/kdf/kdf1/kdf1.cpp | 3 ++- src/lib/kdf/kdf2/kdf2.cpp | 3 ++- src/lib/kdf/prf_tls/prf_tls.cpp | 21 ++++++++++++++++----- src/lib/kdf/prf_x942/prf_x942.cpp | 9 +++++++-- src/lib/tls/msg_finished.cpp | 7 ++++--- src/lib/tls/tls_channel.cpp | 3 +-- src/lib/tls/tls_session_key.cpp | 12 +++++++----- 8 files changed, 41 insertions(+), 20 deletions(-) (limited to 'src/lib/kdf/prf_tls') diff --git a/src/lib/kdf/hkdf/hkdf.cpp b/src/lib/kdf/hkdf/hkdf.cpp index b7e6db020..56dc72f09 100644 --- a/src/lib/kdf/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -23,7 +23,7 @@ HKDF* HKDF::make(const Spec& spec) size_t HKDF::kdf(byte out[], size_t out_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len, - const byte[], size_t) const + const byte label[], size_t label_len) const { m_prf->set_key(secret, secret_len); @@ -34,6 +34,7 @@ size_t HKDF::kdf(byte out[], size_t out_len, while(offset != out_len && counter != 0) { m_prf->update(h); + m_prf->update(label, label_len); m_prf->update(salt, salt_len); m_prf->update(counter++); m_prf->final(h); diff --git a/src/lib/kdf/kdf1/kdf1.cpp b/src/lib/kdf/kdf1/kdf1.cpp index 7d9ab7e3a..14dddc5f4 100644 --- a/src/lib/kdf/kdf1/kdf1.cpp +++ b/src/lib/kdf/kdf1/kdf1.cpp @@ -12,9 +12,10 @@ namespace Botan { size_t KDF1::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len, - const byte[], size_t) const + const byte label[], size_t label_len) const { m_hash->update(secret, secret_len); + m_hash->update(label, label_len); m_hash->update(salt, salt_len); if(key_len < m_hash->output_length()) diff --git a/src/lib/kdf/kdf2/kdf2.cpp b/src/lib/kdf/kdf2/kdf2.cpp index 32bf678f7..760ebfc83 100644 --- a/src/lib/kdf/kdf2/kdf2.cpp +++ b/src/lib/kdf/kdf2/kdf2.cpp @@ -12,7 +12,7 @@ namespace Botan { size_t KDF2::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len, - const byte[], size_t) const + const byte label[], size_t label_len) const { u32bit counter = 1; secure_vector h; @@ -22,6 +22,7 @@ size_t KDF2::kdf(byte key[], size_t key_len, { m_hash->update(secret, secret_len); m_hash->update_be(counter++); + m_hash->update(label, label_len); m_hash->update(salt, salt_len); m_hash->final(h); diff --git a/src/lib/kdf/prf_tls/prf_tls.cpp b/src/lib/kdf/prf_tls/prf_tls.cpp index f15688eba..14b330901 100644 --- a/src/lib/kdf/prf_tls/prf_tls.cpp +++ b/src/lib/kdf/prf_tls/prf_tls.cpp @@ -74,24 +74,35 @@ void P_hash(byte out[], size_t out_len, size_t TLS_PRF::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len, - const byte[], size_t) const + const byte label[], size_t label_len) const { const size_t S1_len = (secret_len + 1) / 2, S2_len = (secret_len + 1) / 2; const byte* S1 = secret; const byte* S2 = secret + (secret_len - S2_len); + secure_vector msg; - P_hash(key, key_len, *m_hmac_md5, S1, S1_len, salt, salt_len); - P_hash(key, key_len, *m_hmac_sha1, S2, S2_len, salt, salt_len); + msg.reserve(label_len + salt_len); + msg += std::make_pair(label, label_len); + msg += std::make_pair(salt, salt_len); + + P_hash(key, key_len, *m_hmac_md5, S1, S1_len, msg.data(), msg.size()); + P_hash(key, key_len, *m_hmac_sha1, S2, S2_len, msg.data(), msg.size()); return key_len; } size_t TLS_12_PRF::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len, - const byte[], size_t) const + const byte label[], size_t label_len) const { - P_hash(key, key_len, *m_mac, secret, secret_len, salt, salt_len); + secure_vector msg; + + msg.reserve(label_len + salt_len); + msg += std::make_pair(label, label_len); + msg += std::make_pair(salt, salt_len); + + P_hash(key, key_len, *m_mac, secret, secret_len, msg.data(), msg.size()); return key_len; } diff --git a/src/lib/kdf/prf_x942/prf_x942.cpp b/src/lib/kdf/prf_x942/prf_x942.cpp index 3830c5775..206cf6ce6 100644 --- a/src/lib/kdf/prf_x942/prf_x942.cpp +++ b/src/lib/kdf/prf_x942/prf_x942.cpp @@ -31,15 +31,20 @@ std::vector encode_x942_int(u32bit n) size_t X942_PRF::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len, - const byte[], size_t) const + const byte label[], size_t label_len) const { std::unique_ptr hash(HashFunction::create("SHA-160")); const OID kek_algo(m_key_wrap_oid); secure_vector h; + secure_vector in; size_t offset = 0; u32bit counter = 1; + in.reserve(salt_len + label_len); + in += std::make_pair(label,label_len); + in += std::make_pair(salt,salt_len); + while(offset != key_len && counter) { hash->update(secret, secret_len); @@ -55,7 +60,7 @@ size_t X942_PRF::kdf(byte key[], size_t key_len, .encode_if(salt_len != 0, DER_Encoder() .start_explicit(0) - .encode(salt, salt_len, OCTET_STRING) + .encode(in, OCTET_STRING) .end_explicit() ) diff --git a/src/lib/tls/msg_finished.cpp b/src/lib/tls/msg_finished.cpp index 7c61ed98e..3a2c88fb1 100644 --- a/src/lib/tls/msg_finished.cpp +++ b/src/lib/tls/msg_finished.cpp @@ -31,14 +31,15 @@ std::vector finished_compute_verify(const Handshake_State& state, std::unique_ptr prf(state.protocol_specific_prf()); std::vector input; + std::vector label; if(side == CLIENT) - input += std::make_pair(TLS_CLIENT_LABEL, sizeof(TLS_CLIENT_LABEL)); + label += std::make_pair(TLS_CLIENT_LABEL, sizeof(TLS_CLIENT_LABEL)); else - input += std::make_pair(TLS_SERVER_LABEL, sizeof(TLS_SERVER_LABEL)); + label += std::make_pair(TLS_SERVER_LABEL, sizeof(TLS_SERVER_LABEL)); input += state.hash().final(state.version(), state.ciphersuite().prf_algo()); - return unlock(prf->derive_key(12, state.session_keys().master_secret(), input, secure_vector())); + return unlock(prf->derive_key(12, state.session_keys().master_secret(), input, label)); } } diff --git a/src/lib/tls/tls_channel.cpp b/src/lib/tls/tls_channel.cpp index 03e99c24f..f445eef99 100644 --- a/src/lib/tls/tls_channel.cpp +++ b/src/lib/tls/tls_channel.cpp @@ -621,7 +621,6 @@ SymmetricKey Channel::key_material_export(const std::string& label, active->session_keys().master_secret(); std::vector salt; - salt += to_byte_vector(label); salt += active->client_hello()->random(); salt += active->server_hello()->random(); @@ -635,7 +634,7 @@ SymmetricKey Channel::key_material_export(const std::string& label, salt += to_byte_vector(context); } - return prf->derive_key(length, master_secret, salt, secure_vector()); + return prf->derive_key(length, master_secret, salt, to_byte_vector(label)); } else throw Exception("Channel::key_material_export connection not active"); diff --git a/src/lib/tls/tls_session_key.cpp b/src/lib/tls/tls_session_key.cpp index 7890813c3..193af8d9f 100644 --- a/src/lib/tls/tls_session_key.cpp +++ b/src/lib/tls/tls_session_key.cpp @@ -48,28 +48,30 @@ Session_Keys::Session_Keys(const Handshake_State* state, else { secure_vector salt; + secure_vector label; if(extended_master_secret) { - salt += std::make_pair(EXT_MASTER_SECRET_MAGIC, sizeof(EXT_MASTER_SECRET_MAGIC)); + label += std::make_pair(EXT_MASTER_SECRET_MAGIC, sizeof(EXT_MASTER_SECRET_MAGIC)); salt += state->hash().final(state->version(), state->ciphersuite().prf_algo()); } else { - salt += std::make_pair(MASTER_SECRET_MAGIC, sizeof(MASTER_SECRET_MAGIC)); + label += std::make_pair(MASTER_SECRET_MAGIC, sizeof(MASTER_SECRET_MAGIC)); salt += state->client_hello()->random(); salt += state->server_hello()->random(); } - m_master_sec = prf->derive_key(48, pre_master_secret, salt, secure_vector()); + m_master_sec = prf->derive_key(48, pre_master_secret, salt, label); } secure_vector salt; - salt += std::make_pair(KEY_GEN_MAGIC, sizeof(KEY_GEN_MAGIC)); + secure_vector label; + label += std::make_pair(KEY_GEN_MAGIC, sizeof(KEY_GEN_MAGIC)); salt += state->server_hello()->random(); salt += state->client_hello()->random(); - SymmetricKey keyblock = prf->derive_key(prf_gen, m_master_sec, salt, secure_vector()); + SymmetricKey keyblock = prf->derive_key(prf_gen, m_master_sec, salt, label); const byte* key_data = keyblock.begin(); -- cgit v1.2.3