Botan  2.9.0
Crypto and TLS for C++11
pgp_s2k.h
Go to the documentation of this file.
1 /*
2 * OpenPGP PBKDF
3 * (C) 1999-2007,2017 Jack Lloyd
4 * (C) 2018 Ribose Inc
5 *
6 * Distributed under the terms of the Botan license
7 */
8 
9 #ifndef BOTAN_OPENPGP_S2K_H_
10 #define BOTAN_OPENPGP_S2K_H_
11 
12 #include <botan/pbkdf.h>
13 #include <botan/pwdhash.h>
14 #include <botan/hash.h>
15 
16 namespace Botan {
17 
18 /**
19 * RFC 4880 encodes the iteration count to a single-byte value
20 */
21 uint8_t BOTAN_PUBLIC_API(2,8) RFC4880_encode_count(size_t iterations);
22 
23 /**
24 * Decode the iteration count from RFC 4880 encoding
25 */
26 size_t BOTAN_PUBLIC_API(2,8) RFC4880_decode_count(uint8_t encoded_iter);
27 
28 /**
29 * Round an arbitrary iteration count to next largest iteration count
30 * supported by RFC4880 encoding.
31 */
32 inline size_t RFC4880_round_iterations(size_t iterations)
33  {
34  return RFC4880_decode_count(RFC4880_encode_count(iterations));
35  }
36 
37 /**
38 * OpenPGP's S2K
39 *
40 * See RFC 4880 sections 3.7.1.1, 3.7.1.2, and 3.7.1.3
41 * If the salt is empty and iterations == 1, "simple" S2K is used
42 * If the salt is non-empty and iterations == 1, "salted" S2K is used
43 * If the salt is non-empty and iterations > 1, "iterated" S2K is used
44 *
45 * Due to complexities of the PGP S2K algorithm, time-based derivation
46 * is not supported. So if iterations == 0 and msec.count() > 0, an
47 * exception is thrown. In the future this may be supported, in which
48 * case "iterated" S2K will be used and the number of iterations
49 * performed is returned.
50 *
51 * Note that unlike PBKDF2, OpenPGP S2K's "iterations" are defined as
52 * the number of bytes hashed.
53 */
55  {
56  public:
57  /**
58  * @param hash the hash function to use
59  */
60  explicit OpenPGP_S2K(HashFunction* hash) : m_hash(hash) {}
61 
62  std::string name() const override
63  {
64  return "OpenPGP-S2K(" + m_hash->name() + ")";
65  }
66 
67  PBKDF* clone() const override
68  {
69  return new OpenPGP_S2K(m_hash->clone());
70  }
71 
72  size_t pbkdf(uint8_t output_buf[], size_t output_len,
73  const std::string& passphrase,
74  const uint8_t salt[], size_t salt_len,
75  size_t iterations,
76  std::chrono::milliseconds msec) const override;
77 
78  /**
79  * RFC 4880 encodes the iteration count to a single-byte value
80  */
81  static uint8_t encode_count(size_t iterations)
82  {
83  return RFC4880_encode_count(iterations);
84  }
85 
86  static size_t decode_count(uint8_t encoded_iter)
87  {
88  return RFC4880_decode_count(encoded_iter);
89  }
90 
91  private:
92  std::unique_ptr<HashFunction> m_hash;
93  };
94 
95 /**
96 * OpenPGP's S2K
97 *
98 * See RFC 4880 sections 3.7.1.1, 3.7.1.2, and 3.7.1.3
99 * If the salt is empty and iterations == 1, "simple" S2K is used
100 * If the salt is non-empty and iterations == 1, "salted" S2K is used
101 * If the salt is non-empty and iterations > 1, "iterated" S2K is used
102 *
103 * Note that unlike PBKDF2, OpenPGP S2K's "iterations" are defined as
104 * the number of bytes hashed.
105 */
107  {
108  public:
109  /**
110  * @param hash the hash function to use
111  * @param iterations is rounded due to PGP formatting
112  */
113  RFC4880_S2K(HashFunction* hash, size_t iterations);
114 
115  std::string to_string() const override;
116 
117  size_t iterations() const override { return m_iterations; }
118 
119  void derive_key(uint8_t out[], size_t out_len,
120  const char* password, size_t password_len,
121  const uint8_t salt[], size_t salt_len) const override;
122 
123  private:
124  std::unique_ptr<HashFunction> m_hash;
125  size_t m_iterations;
126  };
127 
129  {
130  public:
132 
133  std::string name() const override;
134 
135  std::unique_ptr<PasswordHash> tune(size_t output_len,
136  std::chrono::milliseconds msec,
137  size_t max_mem) const override;
138 
139  /**
140  * Return some default parameter set for this PBKDF that should be good
141  * enough for most users. The value returned may change over time as
142  * processing power and attacks improve.
143  */
144  std::unique_ptr<PasswordHash> default_params() const override;
145 
146  std::unique_ptr<PasswordHash> from_iterations(size_t iter) const override;
147 
148  std::unique_ptr<PasswordHash> from_params(
149  size_t iter, size_t, size_t) const override;
150  private:
151  std::unique_ptr<HashFunction> m_hash;
152  };
153 
154 }
155 
156 #endif
static uint8_t encode_count(size_t iterations)
Definition: pgp_s2k.h:81
int(* final)(unsigned char *, CTX *)
#define BOTAN_PUBLIC_API(maj, min)
Definition: compiler.h:31
size_t RFC4880_decode_count(uint8_t iter)
Definition: pgp_s2k.cpp:69
std::string name
std::string name() const override
Definition: pgp_s2k.h:62
PBKDF * clone() const override
Definition: pgp_s2k.h:67
static size_t decode_count(uint8_t encoded_iter)
Definition: pgp_s2k.h:86
size_t salt_len
Definition: x509_obj.cpp:26
Definition: alg_id.cpp:13
size_t RFC4880_round_iterations(size_t iterations)
Definition: pgp_s2k.h:32
std::string to_string(const secure_vector< uint8_t > &bytes)
Definition: stl_util.h:25
RFC4880_S2K_Family(HashFunction *hash)
Definition: pgp_s2k.h:131
OpenPGP_S2K(HashFunction *hash)
Definition: pgp_s2k.h:60
size_t iterations() const override
Definition: pgp_s2k.h:117
MechanismType hash
uint8_t RFC4880_encode_count(size_t desired_iterations)
Definition: pgp_s2k.cpp:56