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