diff options
author | René Korthaus <[email protected]> | 2016-11-12 20:30:40 +0100 |
---|---|---|
committer | René Korthaus <[email protected]> | 2016-11-12 20:30:40 +0100 |
commit | da497797cc7de2b64b63006a0108f785e4a360c1 (patch) | |
tree | 4e4f09e862d3a1ce14217694ff77c5e90ccc1885 /src/lib/kdf/hkdf/hkdf.cpp | |
parent | 37c1a62525c74461693789f983a41c80697ff4a3 (diff) |
Add full HKDF implementation
Adds the full HKDF as class HKDF, renames the existing HKDF,
which only implemented the expansion step, to HKDF_Expand
and adds the extraction step as HKDF_Extract.
The latter two are usually only used seperately in
protocols such as TLS. A normal user would go for the
full HKDF.
Diffstat (limited to 'src/lib/kdf/hkdf/hkdf.cpp')
-rw-r--r-- | src/lib/kdf/hkdf/hkdf.cpp | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/src/lib/kdf/hkdf/hkdf.cpp b/src/lib/kdf/hkdf/hkdf.cpp index 13d5832d2..f44ed81bd 100644 --- a/src/lib/kdf/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -1,6 +1,7 @@ /* * HKDF * (C) 2013,2015 Jack Lloyd +* (C) 2016 René Korthaus, Rohde & Schwarz Cybersecurity * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -9,18 +10,54 @@ namespace Botan { -size_t HKDF::kdf(byte out[], size_t out_len, +size_t HKDF::kdf(byte key[], size_t key_len, const byte secret[], size_t secret_len, const byte salt[], size_t salt_len, const byte label[], size_t label_len) const { + HKDF_Extract extract(m_prf->clone()); + HKDF_Expand expand(m_prf->clone()); + secure_vector<byte> prk(m_prf->output_length()); + + extract.kdf(prk.data(), prk.size(), secret, secret_len, salt, salt_len, nullptr, 0); + return expand.kdf(key, key_len, prk.data(), prk.size(), nullptr, 0, label, label_len); + } + +size_t HKDF_Extract::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 + { + secure_vector<byte> prk; + if(salt_len == 0) + { + m_prf->set_key(std::vector<byte>(m_prf->output_length())); + } + else + { + m_prf->set_key(salt, salt_len); + } + + m_prf->update(secret, secret_len); + m_prf->final(prk); + + const size_t written = std::min(prk.size(), key_len); + copy_mem(&key[0], prk.data(), written); + return written; + } + +size_t HKDF_Expand::kdf(byte key[], size_t key_len, + const byte secret[], size_t secret_len, + const byte salt[], size_t salt_len, + const byte label[], size_t label_len) const + { m_prf->set_key(secret, secret_len); byte counter = 1; secure_vector<byte> h; size_t offset = 0; - while(offset != out_len && counter != 0) + while(offset != key_len && counter != 0) { m_prf->update(h); m_prf->update(label, label_len); @@ -28,8 +65,8 @@ size_t HKDF::kdf(byte out[], size_t out_len, m_prf->update(counter++); m_prf->final(h); - const size_t written = std::min(h.size(), out_len - offset); - copy_mem(&out[offset], h.data(), written); + const size_t written = std::min(h.size(), key_len - offset); + copy_mem(&key[offset], h.data(), written); offset += written; } |