diff options
author | lloyd <[email protected]> | 2015-02-18 04:51:17 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2015-02-18 04:51:17 +0000 |
commit | 888aed4ec2f08684a9707c1251f27285942578c5 (patch) | |
tree | 4c78c5ca5a31b217f407c3adbd138a227181b1c5 | |
parent | 88285f51ba4fd5bc1a1cc06b0760b3926046f29b (diff) |
Convert HKDF to the normal KDF interface
-rw-r--r-- | src/lib/kdf/hkdf/hkdf.cpp | 64 | ||||
-rw-r--r-- | src/lib/kdf/hkdf/hkdf.h | 29 | ||||
-rw-r--r-- | src/lib/pbkdf/pbkdf2/pbkdf2.cpp | 5 | ||||
-rw-r--r-- | src/tests/data/hkdf.vec | 46 | ||||
-rw-r--r-- | src/tests/data/kdf/hkdf.vec | 46 | ||||
-rw-r--r-- | src/tests/test_hkdf.cpp | 84 | ||||
-rw-r--r-- | src/tests/tests.cpp | 1 | ||||
-rw-r--r-- | src/tests/tests.h | 1 |
8 files changed, 82 insertions, 194 deletions
diff --git a/src/lib/kdf/hkdf/hkdf.cpp b/src/lib/kdf/hkdf/hkdf.cpp index 28f97cadb..8c92c779b 100644 --- a/src/lib/kdf/hkdf/hkdf.cpp +++ b/src/lib/kdf/hkdf/hkdf.cpp @@ -1,67 +1,51 @@ /* * HKDF -* (C) 2013 Jack Lloyd +* (C) 2013,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ +#include <botan/internal/kdf_utils.h> #include <botan/hkdf.h> namespace Botan { -std::string HKDF::name() const - { - const std::string prf = m_prf->name(); - const std::string ext = m_extractor->name(); - - if(prf == ext) - return "HKDF(" + prf + ")"; - return "HKDF(" + ext + "," + prf + ")"; - } - -void HKDF::clear() - { - m_extractor->clear(); - m_prf->clear(); - } +BOTAN_REGISTER_NAMED_T(KDF, "HKDF", HKDF, HKDF::make); -void HKDF::start_extract(const byte salt[], size_t salt_len) +HKDF* HKDF::make(const Spec& spec) { - m_extractor->set_key(salt, salt_len); - } + if(auto mac = make_a<MessageAuthenticationCode>(spec.arg(0))) + return new HKDF(mac); -void HKDF::extract(const byte input[], size_t input_len) - { - m_extractor->update(input, input_len); - } + if(auto mac = make_a<MessageAuthenticationCode>("HMAC(" + spec.arg(0) + ")")) + return new HKDF(mac); -void HKDF::finish_extract() - { - m_prf->set_key(m_extractor->final()); + return nullptr; } -void HKDF::expand(byte output[], size_t output_len, - const byte info[], size_t info_len) +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 { - if(output_len > m_prf->output_length() * 255) - throw std::invalid_argument("HKDF requested output too large"); + m_prf->set_key(secret, secret_len); byte counter = 1; + secure_vector<byte> h; + size_t offset = 0; - secure_vector<byte> T; - - while(output_len) + while(offset != out_len && counter != 0) { - m_prf->update(T); - m_prf->update(info, info_len); + m_prf->update(h); + m_prf->update(salt, salt_len); m_prf->update(counter++); - m_prf->final(T); + m_prf->final(h); - 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; + const size_t written = std::min(h.size(), out_len - offset); + copy_mem(&out[offset], &h[0], written); + offset += written; } + + return offset; } } diff --git a/src/lib/kdf/hkdf/hkdf.h b/src/lib/kdf/hkdf/hkdf.h index f1ae61453..c5737b1cc 100644 --- a/src/lib/kdf/hkdf/hkdf.h +++ b/src/lib/kdf/hkdf/hkdf.h @@ -1,6 +1,6 @@ /* * HKDF -* (C) 2013 Jack Lloyd +* (C) 2013,2015 Jack Lloyd * * Botan is released under the Simplified BSD License (see license.txt) */ @@ -16,33 +16,24 @@ namespace Botan { /** * HKDF, see @rfc 5869 for details +* This is only the expansion portion of HKDF */ -class BOTAN_DLL HKDF +class BOTAN_DLL HKDF : public KDF { public: - HKDF(MessageAuthenticationCode* extractor, - MessageAuthenticationCode* prf) : - m_extractor(extractor), m_prf(prf) {} + HKDF(MessageAuthenticationCode* prf) : m_prf(prf) {} - HKDF(MessageAuthenticationCode* prf) : - m_extractor(prf), m_prf(m_extractor->clone()) {} + static HKDF* make(const Spec& spec); - void start_extract(const byte salt[], size_t salt_len); - void extract(const byte input[], size_t input_len); - void finish_extract(); + KDF* clone() const { return new HKDF(m_prf->clone()); } - /** - * 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 { return "HKDF(" + m_prf->name() + ")"; } - std::string name() const; + size_t kdf(byte out[], size_t out_len, + const byte secret[], size_t secret_len, + const byte salt[], size_t salt_len) const override; - void clear(); private: - std::unique_ptr<MessageAuthenticationCode> m_extractor; std::unique_ptr<MessageAuthenticationCode> m_prf; }; diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp index 0ff412bc5..88360e6a2 100644 --- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp +++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp @@ -8,7 +8,6 @@ #include <botan/internal/pbkdf_utils.h> #include <botan/pbkdf2.h> #include <botan/get_byte.h> -#include <botan/hmac.h> #include <botan/internal/xor_buf.h> #include <botan/internal/rounding.h> @@ -21,8 +20,8 @@ PKCS5_PBKDF2* PKCS5_PBKDF2::make(const Spec& spec) if(auto mac = make_a<MessageAuthenticationCode>(spec.arg(0))) return new PKCS5_PBKDF2(mac); - if(auto hash = make_a<HashFunction>(spec.arg(0))) - return new PKCS5_PBKDF2(new HMAC(hash)); + if(auto mac = make_a<MessageAuthenticationCode>("HMAC(" + spec.arg(0) + ")")) + return new PKCS5_PBKDF2(mac); return nullptr; } diff --git a/src/tests/data/hkdf.vec b/src/tests/data/hkdf.vec deleted file mode 100644 index 041fedc1a..000000000 --- a/src/tests/data/hkdf.vec +++ /dev/null @@ -1,46 +0,0 @@ -# Data from RFC 5869 - -[HKDF(SHA-256)] -IKM = 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B -salt = 000102030405060708090A0B0C -info = F0F1F2F3F4F5F6F7F8F9 -L = 42 -PRK = 077709362C2E32DF0DDC3F0DC47BBA6390B6C73BB50F9C3122EC844AD7C2B3E5 -OKM = 3CB25F25FAACD57A90434F64D0362F2A2D2D0A90CF1A5A4C5DB02D56ECC4C5BF34007208D5B887185865 - -IKM = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F -salt = 606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAF -info = B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF -L = 82 -PRK = 06A6B88C5853361A06104C9CEB35B45CEF760014904671014A193F40C15FC244 -OKM = B11E398DC80327A1C8E7F78C596A49344F012EDA2D4EFAD8A050CC4C19AFA97C59045A99CAC7827271CB41C65E590E09DA3275600C2F09B8367793A9ACA3DB71CC30C58179EC3E87C14C01D5C1F3434F1D87 - -IKM = 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B -L = 42 -PRK = 19EF24A32C717B167F33A91D6F648BDF96596776AFDB6377AC434C1C293CCB04 -OKM = 8DA4E775A563C18F715F802A063C5A31B8A11F5C5EE1879EC3454E5F3C738D2D9D201395FAA4B61A96C8 - -[HKDF(SHA-1)] -IKM = 0B0B0B0B0B0B0B0B0B0B0B -salt = 000102030405060708090A0B0C -info = F0F1F2F3F4F5F6F7F8F9 -L = 42 -PRK = 9B6C18C432A7BF8F0E71C8EB88F4B30BAA2BA243 -OKM = 085A01EA1B10F36933068B56EFA5AD81A4F14B822F5B091568A9CDD4F155FDA2C22E422478D305F3F896 - -IKM = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F -salt = 606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAF -info = B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF -L = 82 -PRK = 8ADAE09A2A307059478D309B26C4115A224CFAF6 -OKM = 0BD770A74D1160F7C9F12CD5912A06EBFF6ADCAE899D92191FE4305673BA2FFE8FA3F1A4E5AD79F3F334B3B202B2173C486EA37CE3D397ED034C7F9DFEB15C5E927336D0441F4C4300E2CFF0D0900B52D3B4 - -IKM = 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B -L = 42 -PRK = DA8C8A73C7FA77288EC6F5E7C297786AA0D32D01 -OKM = 0AC1AF7002B3D761D1E55298DA9D0506B9AE52057220A306E07B6B87E8DF21D0EA00033DE03984D34918 - -IKM = 0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C -L = 42 -PRK = 2ADCCADA18779E7C2077AD2EB19D3F3E731385DD -OKM = 2C91117204D745F3500D636A62F64F0AB3BAE548AA53D423B0D1F27EBBA6F5E5673A081D70CCE7ACFC48 diff --git a/src/tests/data/kdf/hkdf.vec b/src/tests/data/kdf/hkdf.vec new file mode 100644 index 000000000..7acbbd006 --- /dev/null +++ b/src/tests/data/kdf/hkdf.vec @@ -0,0 +1,46 @@ +# Data from RFC 5869 + +[HKDF(SHA-256)] +IKM = 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +XTS = 000102030405060708090A0B0C +Salt = F0F1F2F3F4F5F6F7F8F9 +OutputLen = 42 +Secret = 077709362C2E32DF0DDC3F0DC47BBA6390B6C73BB50F9C3122EC844AD7C2B3E5 +Output = 3CB25F25FAACD57A90434F64D0362F2A2D2D0A90CF1A5A4C5DB02D56ECC4C5BF34007208D5B887185865 + +IKM = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +XTS = 606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAF +Salt = B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +OutputLen = 82 +Secret = 06A6B88C5853361A06104C9CEB35B45CEF760014904671014A193F40C15FC244 +Output = B11E398DC80327A1C8E7F78C596A49344F012EDA2D4EFAD8A050CC4C19AFA97C59045A99CAC7827271CB41C65E590E09DA3275600C2F09B8367793A9ACA3DB71CC30C58179EC3E87C14C01D5C1F3434F1D87 + +IKM = 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +OutputLen = 42 +Secret = 19EF24A32C717B167F33A91D6F648BDF96596776AFDB6377AC434C1C293CCB04 +Output = 8DA4E775A563C18F715F802A063C5A31B8A11F5C5EE1879EC3454E5F3C738D2D9D201395FAA4B61A96C8 + +[HKDF(SHA-1)] +IKM = 0B0B0B0B0B0B0B0B0B0B0B +XTS = 000102030405060708090A0B0C +Salt = F0F1F2F3F4F5F6F7F8F9 +OutputLen = 42 +Secret = 9B6C18C432A7BF8F0E71C8EB88F4B30BAA2BA243 +Output = 085A01EA1B10F36933068B56EFA5AD81A4F14B822F5B091568A9CDD4F155FDA2C22E422478D305F3F896 + +IKM = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +XTS = 606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAF +Salt = B0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +OutputLen = 82 +Secret = 8ADAE09A2A307059478D309B26C4115A224CFAF6 +Output = 0BD770A74D1160F7C9F12CD5912A06EBFF6ADCAE899D92191FE4305673BA2FFE8FA3F1A4E5AD79F3F334B3B202B2173C486EA37CE3D397ED034C7F9DFEB15C5E927336D0441F4C4300E2CFF0D0900B52D3B4 + +IKM = 0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B0B +OutputLen = 42 +Secret = DA8C8A73C7FA77288EC6F5E7C297786AA0D32D01 +Output = 0AC1AF7002B3D761D1E55298DA9D0506B9AE52057220A306E07B6B87E8DF21D0EA00033DE03984D34918 + +IKM = 0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C +OutputLen = 42 +Secret = 2ADCCADA18779E7C2077AD2EB19D3F3E731385DD +Output = 2C91117204D745F3500D636A62F64F0AB3BAE548AA53D423B0D1F27EBBA6F5E5673A081D70CCE7ACFC48 diff --git a/src/tests/test_hkdf.cpp b/src/tests/test_hkdf.cpp deleted file mode 100644 index eff379831..000000000 --- a/src/tests/test_hkdf.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* -* (C) 2014,2015 Jack Lloyd -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include "tests.h" -#include <botan/hex.h> -#include <iostream> -#include <fstream> - -#if defined(BOTAN_HAS_HKDF) -#include <botan/hkdf.h> -#include <botan/lookup.h> - -using namespace Botan; - -namespace { - -secure_vector<byte> hkdf(const std::string& hkdf_algo, - const secure_vector<byte>& ikm, - const secure_vector<byte>& salt, - const secure_vector<byte>& info, - size_t L) - { - const std::string algo = hkdf_algo.substr(5, hkdf_algo.size()-6); - - MessageAuthenticationCode* mac = get_mac("HMAC(" + algo + ")"); - if(!mac) - throw std::invalid_argument("Bad HKDF hash '" + algo + "'"); - - HKDF hkdf(mac->clone(), mac); // HKDF needs 2 MACs, identical here - - hkdf.start_extract(&salt[0], salt.size()); - hkdf.extract(&ikm[0], ikm.size()); - hkdf.finish_extract(); - - secure_vector<byte> key(L); - hkdf.expand(&key[0], key.size(), &info[0], info.size()); - return key; - } - -size_t hkdf_test(const std::string& algo, - const std::string& ikm, - const std::string& salt, - const std::string& info, - const std::string& okm, - size_t L) - { - const std::string got = hex_encode( - hkdf(algo, - hex_decode_locked(ikm), - hex_decode_locked(salt), - hex_decode_locked(info), - L) - ); - - if(got != okm) - { - std::cout << "HKDF got " << got << " expected " << okm << std::endl; - return 1; - } - - return 0; - } - -} -#endif - -size_t test_hkdf() - { -#if defined(BOTAN_HAS_HKDF) - std::ifstream vec(TEST_DATA_DIR "/hkdf.vec"); - - return run_tests_bb(vec, "HKDF", "OKM", true, - [](std::map<std::string, std::string> m) -> size_t - { - return hkdf_test(m["HKDF"], m["IKM"], m["salt"], m["info"], - m["OKM"], to_u32bit(m["L"])); - }); -#else - return 0; -#endif - } diff --git a/src/tests/tests.cpp b/src/tests/tests.cpp index 931287464..9a0a29bdd 100644 --- a/src/tests/tests.cpp +++ b/src/tests/tests.cpp @@ -260,7 +260,6 @@ int main(int argc, char* argv[]) DEF_TEST(mac); DEF_TEST(pbkdf); DEF_TEST(kdf); - DEF_TEST(hkdf); DEF_TEST(keywrap); DEF_TEST(transform); DEF_TEST(rngs); diff --git a/src/tests/tests.h b/src/tests/tests.h index 20f373805..43ed1dbd5 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -58,7 +58,6 @@ size_t test_hash(); size_t test_mac(); size_t test_modes(); size_t test_rngs(); -size_t test_hkdf(); size_t test_pbkdf(); size_t test_kdf(); size_t test_aead(); |