aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pbkdf/pgp_s2k/pgp_s2k.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pbkdf/pgp_s2k/pgp_s2k.h')
-rw-r--r--src/lib/pbkdf/pgp_s2k/pgp_s2k.h90
1 files changed, 88 insertions, 2 deletions
diff --git a/src/lib/pbkdf/pgp_s2k/pgp_s2k.h b/src/lib/pbkdf/pgp_s2k/pgp_s2k.h
index 02b228258..820fa3801 100644
--- a/src/lib/pbkdf/pgp_s2k/pgp_s2k.h
+++ b/src/lib/pbkdf/pgp_s2k/pgp_s2k.h
@@ -1,6 +1,7 @@
/*
* OpenPGP PBKDF
* (C) 1999-2007,2017 Jack Lloyd
+* (C) 2018 Ribose Inc
*
* Distributed under the terms of the Botan license
*/
@@ -9,11 +10,31 @@
#define BOTAN_OPENPGP_S2K_H_
#include <botan/pbkdf.h>
+#include <botan/pwdhash.h>
#include <botan/hash.h>
namespace Botan {
/**
+* RFC 4880 encodes the iteration count to a single-byte value
+*/
+uint8_t BOTAN_PUBLIC_API(2,8) RFC4880_encode_count(size_t iterations);
+
+/**
+* Decode the iteration count from RFC 4880 encoding
+*/
+size_t BOTAN_PUBLIC_API(2,8) RFC4880_decode_count(uint8_t encoded_iter);
+
+/**
+* Round an arbitrary iteration count to next largest iteration count
+* supported by RFC4880 encoding.
+*/
+inline size_t RFC4880_round_iterations(size_t iterations)
+ {
+ return RFC4880_decode_count(RFC4880_encode_count(iterations));
+ }
+
+/**
* OpenPGP's S2K
*
* See RFC 4880 sections 3.7.1.1, 3.7.1.2, and 3.7.1.3
@@ -57,10 +78,75 @@ class BOTAN_PUBLIC_API(2,2) OpenPGP_S2K final : public PBKDF
/**
* RFC 4880 encodes the iteration count to a single-byte value
*/
- static uint8_t encode_count(size_t iterations);
+ static uint8_t encode_count(size_t iterations)
+ {
+ return RFC4880_encode_count(iterations);
+ }
+
+ static size_t decode_count(uint8_t encoded_iter)
+ {
+ return RFC4880_decode_count(encoded_iter);
+ }
+
+ private:
+ std::unique_ptr<HashFunction> m_hash;
+ };
+
+/**
+* OpenPGP's S2K
+*
+* See RFC 4880 sections 3.7.1.1, 3.7.1.2, and 3.7.1.3
+* If the salt is empty and iterations == 1, "simple" S2K is used
+* If the salt is non-empty and iterations == 1, "salted" S2K is used
+* If the salt is non-empty and iterations > 1, "iterated" S2K is used
+*
+* Note that unlike PBKDF2, OpenPGP S2K's "iterations" are defined as
+* the number of bytes hashed.
+*/
+class BOTAN_PUBLIC_API(2,8) RFC4880_S2K final : public PasswordHash
+ {
+ public:
+ /**
+ * @param hash the hash function to use
+ * @param the iterations to use (this is rounded due to PGP formatting)
+ */
+ RFC4880_S2K(HashFunction* hash, size_t iterations);
+
+ std::string to_string() const override;
+
+ size_t iterations() const override { return m_iterations; }
+
+ void derive_key(uint8_t out[], size_t out_len,
+ const char* password, const size_t password_len,
+ const uint8_t salt[], size_t salt_len) const;
+
+ private:
+ std::unique_ptr<HashFunction> m_hash;
+ size_t m_iterations;
+ };
+
+class BOTAN_PUBLIC_API(2,8) RFC4880_S2K_Family final : public PasswordHashFamily
+ {
+ public:
+ RFC4880_S2K_Family(HashFunction* hash) : m_hash(hash) {}
+
+ std::string name() const override;
+
+ std::unique_ptr<PasswordHash> tune(size_t output_len,
+ std::chrono::milliseconds msec,
+ size_t max_mem) const override;
+
+ /**
+ * 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.
+ */
+ std::unique_ptr<PasswordHash> default_params() const override;
- static size_t decode_count(uint8_t encoded_iter);
+ std::unique_ptr<PasswordHash> from_iterations(size_t iter) const override;
+ std::unique_ptr<PasswordHash> from_params(
+ size_t iter, size_t, size_t) const override;
private:
std::unique_ptr<HashFunction> m_hash;
};