aboutsummaryrefslogtreecommitdiffstats
path: root/lib/prf/hkdf/hkdf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/prf/hkdf/hkdf.cpp')
-rw-r--r--lib/prf/hkdf/hkdf.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/prf/hkdf/hkdf.cpp b/lib/prf/hkdf/hkdf.cpp
new file mode 100644
index 000000000..0a1f7cb31
--- /dev/null
+++ b/lib/prf/hkdf/hkdf.cpp
@@ -0,0 +1,62 @@
+/*
+* HKDF
+* (C) 2013 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/hkdf.h>
+
+namespace Botan {
+
+std::string HKDF::name() const
+ {
+ return "HKDF(" + m_prf->name() + ")";
+ }
+
+void HKDF::clear()
+ {
+ m_extractor->clear();
+ m_prf->clear();
+ }
+
+void HKDF::start_extract(const byte salt[], size_t salt_len)
+ {
+ m_extractor->set_key(salt, salt_len);
+ }
+
+void HKDF::extract(const byte input[], size_t input_len)
+ {
+ m_extractor->update(input, input_len);
+ }
+
+void HKDF::finish_extract()
+ {
+ m_prf->set_key(m_extractor->final());
+ }
+
+void HKDF::expand(byte output[], size_t output_len,
+ const byte info[], size_t info_len)
+ {
+ if(output_len > m_prf->output_length() * 255)
+ throw std::invalid_argument("HKDF requested output too large");
+
+ byte counter = 1;
+
+ secure_vector<byte> T;
+
+ while(output_len)
+ {
+ m_prf->update(T);
+ m_prf->update(info, info_len);
+ m_prf->update(counter++);
+ T = m_prf->final();
+
+ const size_t to_write = std::min(T.size(), output_len);
+ copy_mem(&output[0], &T[0], to_write);
+ output += to_write;
+ output_len -= to_write;
+ }
+ }
+
+}