aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp')
-rw-r--r--src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp
new file mode 100644
index 0000000000..73b482725c
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/pbkdf/pbkdf.cpp
@@ -0,0 +1,133 @@
+/*
+* PBKDF
+* (C) 2012 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/pbkdf.h>
+#include <botan/exceptn.h>
+#include <botan/scan_name.h>
+
+#if defined(BOTAN_HAS_PBKDF1)
+#include <botan/pbkdf1.h>
+#endif
+
+#if defined(BOTAN_HAS_PBKDF2)
+#include <botan/pbkdf2.h>
+#endif
+
+#if defined(BOTAN_HAS_PGP_S2K)
+#include <botan/pgp_s2k.h>
+#endif
+
+namespace Botan {
+
+std::unique_ptr<PBKDF> PBKDF::create(const std::string& algo_spec,
+ const std::string& provider)
+ {
+ const SCAN_Name req(algo_spec);
+
+#if defined(BOTAN_HAS_PBKDF2)
+ if(req.algo_name() == "PBKDF2")
+ {
+ // TODO OpenSSL
+
+ if(provider.empty() || provider == "base")
+ {
+ if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
+ return std::unique_ptr<PBKDF>(new PKCS5_PBKDF2(mac.release()));
+
+ if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")"))
+ return std::unique_ptr<PBKDF>(new PKCS5_PBKDF2(mac.release()));
+ }
+
+ return nullptr;
+ }
+#endif
+
+#if defined(BOTAN_HAS_PBKDF1)
+ if(req.algo_name() == "PBKDF1" && req.arg_count() == 1)
+ {
+ if(auto hash = HashFunction::create(req.arg(0)))
+ return std::unique_ptr<PBKDF>(new PKCS5_PBKDF1(hash.release()));
+
+ }
+#endif
+
+#if defined(BOTAN_HAS_PGP_S2K)
+ if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1)
+ {
+ if(auto hash = HashFunction::create(req.arg(0)))
+ return std::unique_ptr<PBKDF>(new OpenPGP_S2K(hash.release()));
+ }
+#endif
+
+ BOTAN_UNUSED(req);
+ BOTAN_UNUSED(provider);
+
+ return nullptr;
+ }
+
+//static
+std::unique_ptr<PBKDF>
+PBKDF::create_or_throw(const std::string& algo,
+ const std::string& provider)
+ {
+ if(auto pbkdf = PBKDF::create(algo, provider))
+ {
+ return pbkdf;
+ }
+ throw Lookup_Error("PBKDF", algo, provider);
+ }
+
+std::vector<std::string> PBKDF::providers(const std::string& algo_spec)
+ {
+ return probe_providers_of<PBKDF>(algo_spec, { "base", "openssl" });
+ }
+
+void PBKDF::pbkdf_timed(uint8_t out[], size_t out_len,
+ const std::string& passphrase,
+ const uint8_t salt[], size_t salt_len,
+ std::chrono::milliseconds msec,
+ size_t& iterations) const
+ {
+ iterations = pbkdf(out, out_len, passphrase, salt, salt_len, 0, msec);
+ }
+
+void PBKDF::pbkdf_iterations(uint8_t out[], size_t out_len,
+ const std::string& passphrase,
+ const uint8_t salt[], size_t salt_len,
+ size_t iterations) const
+ {
+ if(iterations == 0)
+ throw Invalid_Argument(name() + ": Invalid iteration count");
+
+ const size_t iterations_run = pbkdf(out, out_len, passphrase,
+ salt, salt_len, iterations,
+ std::chrono::milliseconds(0));
+ BOTAN_ASSERT_EQUAL(iterations, iterations_run, "Expected PBKDF iterations");
+ }
+
+secure_vector<uint8_t> PBKDF::pbkdf_iterations(size_t out_len,
+ const std::string& passphrase,
+ const uint8_t salt[], size_t salt_len,
+ size_t iterations) const
+ {
+ secure_vector<uint8_t> out(out_len);
+ pbkdf_iterations(out.data(), out_len, passphrase, salt, salt_len, iterations);
+ return out;
+ }
+
+secure_vector<uint8_t> PBKDF::pbkdf_timed(size_t out_len,
+ const std::string& passphrase,
+ const uint8_t salt[], size_t salt_len,
+ std::chrono::milliseconds msec,
+ size_t& iterations) const
+ {
+ secure_vector<uint8_t> out(out_len);
+ pbkdf_timed(out.data(), out_len, passphrase, salt, salt_len, msec, iterations);
+ return out;
+ }
+
+}