aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pbkdf/pwdhash.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pbkdf/pwdhash.h')
-rw-r--r--src/lib/pbkdf/pwdhash.h162
1 files changed, 162 insertions, 0 deletions
diff --git a/src/lib/pbkdf/pwdhash.h b/src/lib/pbkdf/pwdhash.h
new file mode 100644
index 000000000..d4a205340
--- /dev/null
+++ b/src/lib/pbkdf/pwdhash.h
@@ -0,0 +1,162 @@
+/*
+* (C) 2018 Ribose Inc
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_PWDHASH_H_
+#define BOTAN_PWDHASH_H_
+
+#include <botan/types.h>
+#include <string>
+#include <memory>
+#include <vector>
+#include <chrono>
+
+namespace Botan {
+
+/**
+* Base class for password based key derivation functions.
+*
+* Converts a password into a key using a salt and iterated hashing to
+* make brute force attacks harder.
+*/
+class BOTAN_PUBLIC_API(2,8) PasswordHash
+ {
+ public:
+ virtual ~PasswordHash() = default;
+
+ virtual std::string to_string() const = 0;
+
+ /**
+ * Most password hashes have some notion of iterations.
+ */
+ virtual size_t iterations() const = 0;
+
+ /**
+ * Some password hashing algorithms have a parameter which controls how
+ * much memory is used. If not supported by some algorithm, returns 0.
+ */
+ virtual size_t memory_param() const { return 0; }
+
+ /**
+ * Some password hashing algorithms have a parallelism parameter.
+ * If the algorithm does not support this notion, then the
+ * function returns zero. This allows distinguishing between a
+ * password hash which just does not support parallel operation,
+ * vs one that does support parallel operation but which has been
+ * configured to use a single lane.
+ */
+ virtual size_t parallelism() const { return 0; }
+
+ /**
+ * Returns an estimate of the total memory usage required to perform this
+ * key derivation.
+ *
+ * If this algorithm uses a small and constant amount of memory, with no
+ * effort made towards being memory hard, this function returns 0.
+ */
+ virtual size_t total_memory_usage() const { return 0; }
+
+ /**
+ * Derive a key from a password
+ *
+ * @param out buffer to store the derived key, must be of out_len bytes
+ * @param out_len the desired length of the key to produce
+ * @param password the password to derive the key from
+ * @param password_len the length of password in bytes
+ * @param salt a randomly chosen salt
+ * @param salt_len length of salt in bytes
+ *
+ * This function is const, but is not thread safe. Different threads should
+ * either use unique objects, or serialize all access.
+ */
+ virtual void derive_key(uint8_t out[], size_t out_len,
+ const char* password, size_t password_len,
+ const uint8_t salt[], size_t salt_len) const = 0;
+ };
+
+class BOTAN_PUBLIC_API(2,8) PasswordHashFamily
+ {
+ public:
+ /**
+ * Create an instance based on a name
+ * If provider is empty then best available is chosen.
+ * @param algo_spec algorithm name
+ * @param provider provider implementation to choose
+ * @return a null pointer if the algo/provider combination cannot be found
+ */
+ static std::unique_ptr<PasswordHashFamily> create(const std::string& algo_spec,
+ const std::string& provider = "");
+
+ /**
+ * Create an instance based on a name, or throw if the
+ * algo/provider combination cannot be found. If provider is
+ * empty then best available is chosen.
+ */
+ static std::unique_ptr<PasswordHashFamily>
+ create_or_throw(const std::string& algo_spec,
+ const std::string& provider = "");
+
+ /**
+ * @return list of available providers for this algorithm, empty if not available
+ */
+ static std::vector<std::string> providers(const std::string& algo_spec);
+
+ virtual ~PasswordHashFamily() = default;
+
+ /**
+ * @return name of this PasswordHash
+ */
+ virtual std::string name() const = 0;
+
+ /**
+ * Return a new parameter set tuned for this machine
+ * @param output_length how long the output length will be
+ * @param msec the desired execution time in milliseconds
+ *
+ * @param max_memory_usage some password hash functions can use a tunable
+ * amount of memory, in this case max_memory_usage limits the amount of RAM
+ * the returned parameters will require, in mebibytes (2**20 bytes). It may
+ * require some small amount above the request. Set to zero to place no
+ * limit at all.
+ */
+ virtual std::unique_ptr<PasswordHash> tune(size_t output_len,
+ std::chrono::milliseconds msec,
+ size_t max_memory_usage_mb = 0) const = 0;
+
+ /**
+ * Return some default parameter set for this PBKDF that should be good
+ * enough for most users. The value returned may change over time as
+ * processing power and attacks improve.
+ */
+ virtual std::unique_ptr<PasswordHash> default_params() const = 0;
+
+ /**
+ * Return a parameter chosen based on a rough approximation with the
+ * specified iteration count. The exact value this returns for a particular
+ * algorithm may change from over time. Think of it as an alternative to
+ * tune, where time is expressed in terms of PBKDF2 iterations rather than
+ * milliseconds.
+ */
+ virtual std::unique_ptr<PasswordHash> from_iterations(size_t iterations) const = 0;
+
+ /**
+ * Create a password hash using some scheme specific format.
+ * Eg PBKDF2 and PGP-S2K set iterations in i1
+ * Scrypt uses N,r,p in i{1-3}
+ * Bcrypt-PBKDF just has iterations
+ * Argon2{i,d,id} would use iterations, memory, parallelism for i{1-3},
+ * and Argon2 type is part of the family.
+ *
+ * Values not needed should be set to 0
+ */
+ virtual std::unique_ptr<PasswordHash> from_params(
+ size_t i1,
+ size_t i2 = 0,
+ size_t i3 = 0) const = 0;
+ };
+
+}
+
+#endif