aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/kdf/hkdf/hkdf.cpp
diff options
context:
space:
mode:
authorRené Korthaus <[email protected]>2016-11-12 20:30:40 +0100
committerRené Korthaus <[email protected]>2016-11-12 20:30:40 +0100
commitda497797cc7de2b64b63006a0108f785e4a360c1 (patch)
tree4e4f09e862d3a1ce14217694ff77c5e90ccc1885 /src/lib/kdf/hkdf/hkdf.cpp
parent37c1a62525c74461693789f983a41c80697ff4a3 (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.cpp45
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;
}