diff options
author | lloyd <[email protected]> | 2013-11-17 21:31:54 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2013-11-17 21:31:54 +0000 |
commit | e072b28e66a06a1a82678a2b5d8b946bf63f6289 (patch) | |
tree | a3e1e30aad9cf60f23a75d12f5fcbad4d56bb03d /src | |
parent | a9e79b8a9da0abffce15d9bb891f7604d1856744 (diff) |
Add HKDF
Diffstat (limited to 'src')
-rw-r--r-- | src/prf/hkdf/hkdf.cpp | 62 | ||||
-rw-r--r-- | src/prf/hkdf/hkdf.h | 51 | ||||
-rw-r--r-- | src/prf/hkdf/info.txt | 1 |
3 files changed, 114 insertions, 0 deletions
diff --git a/src/prf/hkdf/hkdf.cpp b/src/prf/hkdf/hkdf.cpp new file mode 100644 index 000000000..0a1f7cb31 --- /dev/null +++ b/src/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; + } + } + +} diff --git a/src/prf/hkdf/hkdf.h b/src/prf/hkdf/hkdf.h new file mode 100644 index 000000000..e0b5a7376 --- /dev/null +++ b/src/prf/hkdf/hkdf.h @@ -0,0 +1,51 @@ +/* +* HKDF +* (C) 2013 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_HKDF_H__ +#define BOTAN_HKDF_H__ + +#include <botan/mac.h> +#include <botan/hash.h> +#include <memory> + +namespace Botan { + +/** +* HKDF, see @rfc 5869 for details +*/ +class BOTAN_DLL HKDF + { + public: + HKDF(MessageAuthenticationCode* extractor, + MessageAuthenticationCode* prf) : + m_extractor(extractor), m_prf(prf) {} + + HKDF(MessageAuthenticationCode* prf) : + m_extractor(prf), m_prf(m_extractor->clone()) {} + + void start_extract(const byte salt[], size_t salt_len); + void extract(const byte input[], size_t input_len); + void finish_extract(); + + /** + * Only call after extract + * @param output_len must be less than 256*hashlen + */ + void expand(byte output[], size_t output_len, + const byte info[], size_t info_len); + + std::string name() const; + + void clear(); + private: + std::unique_ptr<MessageAuthenticationCode> m_extractor; + std::unique_ptr<MessageAuthenticationCode> m_prf; + }; + +} + +#endif diff --git a/src/prf/hkdf/info.txt b/src/prf/hkdf/info.txt new file mode 100644 index 000000000..fa124bca4 --- /dev/null +++ b/src/prf/hkdf/info.txt @@ -0,0 +1 @@ +define HKDF |