1 /*
2 * Key Derivation Function interfaces
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_KDF_BASE_H_
9 #define BOTAN_KDF_BASE_H_
10 
11 #include <botan/secmem.h>
12 #include <botan/types.h>
13 #include <string>
14 
15 namespace Botan {
16 
17 /**
18 * Key Derivation Function
19 */
20 class BOTAN_PUBLIC_API(2,0) KDF
21    {
22    public:
23       virtual ~KDF() = default;
24 
25       /**
26       * Create an instance based on a name
27       * If provider is empty then best available is chosen.
28       * @param algo_spec algorithm name
29       * @param provider provider implementation to choose
30       * @return a null pointer if the algo/provider combination cannot be found
31       */
32       static std::unique_ptr<KDF>
33          create(const std::string& algo_spec,
34                 const std::string& provider = "");
35 
36       /**
37       * Create an instance based on a name, or throw if the
38       * algo/provider combination cannot be found. If provider is
39       * empty then best available is chosen.
40       */
41       static std::unique_ptr<KDF>
42          create_or_throw(const std::string& algo_spec,
43                          const std::string& provider = "");
44 
45       /**
46       * @return list of available providers for this algorithm, empty if not available
47       */
48       static std::vector<std::string> providers(const std::string& algo_spec);
49 
50       /**
51       * @return KDF name
52       */
53       virtual std::string name() const = 0;
54 
55       /**
56       * Derive a key
57       * @param key buffer holding the derived key, must be of length key_len
58       * @param key_len the desired output length in bytes
59       * @param secret the secret input
60       * @param secret_len size of secret in bytes
61       * @param salt a diversifier
62       * @param salt_len size of salt in bytes
63       * @param label purpose for the derived keying material
64       * @param label_len size of label in bytes
65       * @return the derived key
66       */
67       virtual size_t kdf(uint8_t key[], size_t key_len,
68                          const uint8_t secret[], size_t secret_len,
69                          const uint8_t salt[], size_t salt_len,
70                          const uint8_t label[], size_t label_len) const = 0;
71 
72       /**
73       * Derive a key
74       * @param key_len the desired output length in bytes
75       * @param secret the secret input
76       * @param secret_len size of secret in bytes
77       * @param salt a diversifier
78       * @param salt_len size of salt in bytes
79       * @param label purpose for the derived keying material
80       * @param label_len size of label in bytes
81       * @return the derived key
82       */
83       secure_vector<uint8_t> derive_key(size_t key_len,
84                                     const uint8_t secret[],
85                                     size_t secret_len,
86                                     const uint8_t salt[],
87                                     size_t salt_len,
88                                     const uint8_t label[] = nullptr,
89                                     size_t label_len = 0) const
90          {
91          secure_vector<uint8_t> key(key_len);
92          key.resize(kdf(key.data(), key.size(), secret, secret_len, salt, salt_len, label, label_len));
93          return key;
94          }
95 
96       /**
97       * Derive a key
98       * @param key_len the desired output length in bytes
99       * @param secret the secret input
100       * @param salt a diversifier
101       * @param label purpose for the derived keying material
102       * @return the derived key
103       */
104       secure_vector<uint8_t> derive_key(size_t key_len,
105                                     const secure_vector<uint8_t>& secret,
106                                     const std::string& salt = "",
107                                     const std::string& label = "") const
108          {
109          return derive_key(key_len, secret.data(), secret.size(),
110                            cast_char_ptr_to_uint8(salt.data()),
111                            salt.length(),
112                            cast_char_ptr_to_uint8(label.data()),
113                            label.length());
114 
115          }
116 
117       /**
118       * Derive a key
119       * @param key_len the desired output length in bytes
120       * @param secret the secret input
121       * @param salt a diversifier
122       * @param label purpose for the derived keying material
123       * @return the derived key
124       */
125       template<typename Alloc, typename Alloc2, typename Alloc3>
derive_key(size_t key_len,const std::vector<uint8_t,Alloc> & secret,const std::vector<uint8_t,Alloc2> & salt,const std::vector<uint8_t,Alloc3> & label)126       secure_vector<uint8_t> derive_key(size_t key_len,
127                                      const std::vector<uint8_t, Alloc>& secret,
128                                      const std::vector<uint8_t, Alloc2>& salt,
129                                      const std::vector<uint8_t, Alloc3>& label) const
130          {
131          return derive_key(key_len,
132                            secret.data(), secret.size(),
133                            salt.data(), salt.size(),
134                            label.data(), label.size());
135          }
136 
137       /**
138       * Derive a key
139       * @param key_len the desired output length in bytes
140       * @param secret the secret input
141       * @param salt a diversifier
142       * @param salt_len size of salt in bytes
143       * @param label purpose for the derived keying material
144       * @return the derived key
145       */
146       secure_vector<uint8_t> derive_key(size_t key_len,
147                                     const secure_vector<uint8_t>& secret,
148                                     const uint8_t salt[],
149                                     size_t salt_len,
150                                     const std::string& label = "") const
151          {
152          return derive_key(key_len,
153                            secret.data(), secret.size(),
154                            salt, salt_len,
155                            cast_char_ptr_to_uint8(label.data()),
156                            label.size());
157          }
158 
159       /**
160       * Derive a key
161       * @param key_len the desired output length in bytes
162       * @param secret the secret input
163       * @param secret_len size of secret in bytes
164       * @param salt a diversifier
165       * @param label purpose for the derived keying material
166       * @return the derived key
167       */
168       secure_vector<uint8_t> derive_key(size_t key_len,
169                                     const uint8_t secret[],
170                                     size_t secret_len,
171                                     const std::string& salt = "",
172                                     const std::string& label = "") const
173          {
174          return derive_key(key_len, secret, secret_len,
175                            cast_char_ptr_to_uint8(salt.data()),
176                            salt.length(),
177                            cast_char_ptr_to_uint8(label.data()),
178                            label.length());
179          }
180 
181       /**
182       * @return new object representing the same algorithm as *this
183       */
184       virtual KDF* clone() const = 0;
185    };
186 
187 /**
188 * Factory method for KDF (key derivation function)
189 * @param algo_spec the name of the KDF to create
190 * @return pointer to newly allocated object of that type
191 */
192 BOTAN_PUBLIC_API(2,0) KDF* get_kdf(const std::string& algo_spec);
193 
194 }
195 
196 #endif
197