aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lib/kdf/hkdf/hkdf.cpp64
-rw-r--r--src/lib/kdf/hkdf/hkdf.h29
-rw-r--r--src/lib/pbkdf/pbkdf2/pbkdf2.cpp5
-rw-r--r--src/tests/data/hkdf.vec46
-rw-r--r--src/tests/data/kdf/hkdf.vec46
-rw-r--r--src/tests/test_hkdf.cpp84
-rw-r--r--src/tests/tests.cpp1
-rw-r--r--src/tests/tests.h1
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();