Coverage Report

Created: 2026-06-07 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/build/include/public/botan/kdf.h
Line
Count
Source
1
/*
2
* Key Derivation Function interfaces
3
* (C) 1999-2007 Jack Lloyd
4
* (C) 2024      René Meusel - Rohde & Schwarz Cybersecurity
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8
9
#ifndef BOTAN_KDF_BASE_H_
10
#define BOTAN_KDF_BASE_H_
11
12
#include <botan/concepts.h>
13
#include <botan/exceptn.h>
14
#include <botan/secmem.h>
15
#include <memory>
16
#include <span>
17
#include <string>
18
#include <string_view>
19
20
namespace Botan {
21
22
/**
23
* Key Derivation Function
24
*/
25
class BOTAN_PUBLIC_API(2, 0) KDF {
26
   public:
27
0
      virtual ~KDF() = default;
28
29
      /**
30
      * Create an instance based on a name
31
      * If provider is empty then best available is chosen.
32
      * @param algo_spec algorithm name
33
      * @param provider provider implementation to choose
34
      * @return a null pointer if the algo/provider combination cannot be found
35
      */
36
      static std::unique_ptr<KDF> create(std::string_view algo_spec, std::string_view provider = "");
37
38
      /**
39
      * Create an instance based on a name, or throw if the
40
      * algo/provider combination cannot be found. If provider is
41
      * empty then best available is chosen.
42
      */
43
      static std::unique_ptr<KDF> create_or_throw(std::string_view algo_spec, std::string_view provider = "");
44
45
      /**
46
      * @return list of available providers for this algorithm, empty if not available
47
      */
48
      static std::vector<std::string> providers(std::string_view 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
      */
66
      BOTAN_DEPRECATED("Use KDF::derive_key")
67
      void kdf(uint8_t key[],
68
               size_t key_len,
69
               const uint8_t secret[],
70
               size_t secret_len,
71
               const uint8_t salt[],
72
               size_t salt_len,
73
               const uint8_t label[],
74
0
               size_t label_len) const {
75
0
         derive_key({key, key_len}, {secret, secret_len}, {salt, salt_len}, {label, label_len});
76
0
      }
77
78
      /**
79
      * Derive a key
80
      * @param key_len the desired output length in bytes
81
      * @param secret the secret input
82
      * @param secret_len size of secret in bytes
83
      * @param salt a diversifier
84
      * @param salt_len size of salt in bytes
85
      * @param label purpose for the derived keying material
86
      * @param label_len size of label in bytes
87
      * @return the derived key
88
      */
89
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
90
      BOTAN_DEPRECATED("Use std::span or std::string_view overloads")
91
      T derive_key(size_t key_len,
92
                   const uint8_t secret[],
93
                   size_t secret_len,
94
                   const uint8_t salt[],
95
                   size_t salt_len,
96
                   const uint8_t label[] = nullptr,
97
                   size_t label_len = 0) const {
98
         return derive_key<T>(key_len, {secret, secret_len}, {salt, salt_len}, {label, label_len});
99
      }
100
101
      /**
102
      * Derive a key
103
      * @param key_len the desired output length in bytes
104
      * @param secret the secret input
105
      * @param salt a diversifier
106
      * @param label purpose for the derived keying material
107
      * @return the derived key
108
      */
109
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
110
      T derive_key(size_t key_len,
111
                   std::span<const uint8_t> secret,
112
                   std::string_view salt = "",
113
                   std::string_view label = "") const {
114
         return derive_key<T>(key_len, secret, _as_span(salt), _as_span(label));
115
      }
116
117
      /**
118
      * Derive a key
119
      * @param key the output buffer for the to-be-derived key
120
      * @param secret the secret input
121
      * @param salt a diversifier
122
      * @param label purpose for the derived keying material
123
      */
124
      void derive_key(std::span<uint8_t> key,
125
                      std::span<const uint8_t> secret,
126
                      std::span<const uint8_t> salt,
127
0
                      std::span<const uint8_t> label) const {
128
0
         perform_kdf(key, secret, salt, label);
129
0
      }
130
131
      /**
132
      * Derive a key
133
      * @param key_len the desired output length in bytes
134
      * @param secret the secret input
135
      * @param salt a diversifier
136
      * @param label purpose for the derived keying material
137
      * @return the derived key
138
      */
139
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
140
      T derive_key(size_t key_len,
141
                   std::span<const uint8_t> secret,
142
                   std::span<const uint8_t> salt,
143
0
                   std::span<const uint8_t> label) const {
144
0
         T key(key_len);
145
0
         perform_kdf(key, secret, salt, label);
146
0
         return key;
147
0
      }
148
149
      /**
150
      * Derive a key
151
      * @param key_len the desired output length in bytes
152
      * @param secret the secret input
153
      * @param salt a diversifier
154
      * @param salt_len size of salt in bytes
155
      * @param label purpose for the derived keying material
156
      * @return the derived key
157
      */
158
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
159
      BOTAN_DEPRECATED("Use std::span or std::string_view overloads")
160
      T derive_key(size_t key_len,
161
                   std::span<const uint8_t> secret,
162
                   const uint8_t salt[],
163
                   size_t salt_len,
164
0
                   std::string_view label = "") const {
165
0
         return derive_key<T>(key_len, secret, {salt, salt_len}, _as_span(label));
166
0
      }
167
168
      /**
169
      * Derive a key
170
      * @param key_len the desired output length in bytes
171
      * @param secret the secret input
172
      * @param secret_len size of secret in bytes
173
      * @param salt a diversifier
174
      * @param label purpose for the derived keying material
175
      * @return the derived key
176
      */
177
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
178
      BOTAN_DEPRECATED("Use std::span or std::string_view overloads")
179
      T derive_key(size_t key_len,
180
                   const uint8_t secret[],
181
                   size_t secret_len,
182
                   std::string_view salt = "",
183
                   std::string_view label = "") const {
184
         return derive_key<T>(key_len, {secret, secret_len}, _as_span(salt), _as_span(label));
185
      }
186
187
      /**
188
      * Derive a key
189
      * @tparam key_len the desired output length in bytes
190
      * @param secret the secret input
191
      * @param salt a diversifier
192
      * @param label purpose for the derived keying material
193
      * @return the derived key
194
      */
195
      template <size_t key_len>
196
      std::array<uint8_t, key_len> derive_key(std::span<const uint8_t> secret,
197
                                              std::span<const uint8_t> salt = {},
198
                                              std::span<const uint8_t> label = {}) {
199
         std::array<uint8_t, key_len> key;
200
         perform_kdf(key, secret, salt, label);
201
         return key;
202
      }
203
204
      /**
205
      * Derive a key
206
      * @tparam key_len the desired output length in bytes
207
      * @param secret the secret input
208
      * @param salt a diversifier
209
      * @param label purpose for the derived keying material
210
      * @return the derived key
211
      */
212
      template <size_t key_len>
213
      std::array<uint8_t, key_len> derive_key(std::span<const uint8_t> secret,
214
                                              std::span<const uint8_t> salt = {},
215
                                              std::string_view label = "") {
216
         return derive_key<key_len>(secret, salt, _as_span(label));
217
      }
218
219
      /**
220
      * Derive a key
221
      * @tparam key_len the desired output length in bytes
222
      * @param secret the secret input
223
      * @param salt a diversifier
224
      * @param label purpose for the derived keying material
225
      * @return the derived key
226
      */
227
      template <size_t key_len>
228
      std::array<uint8_t, key_len> derive_key(std::span<const uint8_t> secret,
229
                                              std::string_view salt = "",
230
                                              std::string_view label = "") {
231
         return derive_key<key_len>(secret, _as_span(salt), _as_span(label));
232
      }
233
234
      /**
235
      * @return new object representing the same algorithm as *this
236
      */
237
      virtual std::unique_ptr<KDF> new_object() const = 0;
238
239
      /**
240
      * @return new object representing the same algorithm as *this
241
      */
242
0
      KDF* clone() const { return this->new_object().release(); }
243
244
   protected:
245
      /**
246
      * Internal customization point for subclasses
247
      *
248
      * The byte size of the @p key span is the number of bytes to be produced
249
      * by the concrete key derivation function.
250
      *
251
      * @param key the output buffer for the to-be-derived key
252
      * @param secret the secret input
253
      * @param salt a diversifier
254
      * @param label purpose for the derived keying material
255
      */
256
      virtual void perform_kdf(std::span<uint8_t> key,
257
                               std::span<const uint8_t> secret,
258
                               std::span<const uint8_t> salt,
259
                               std::span<const uint8_t> label) const = 0;
260
261
   private:
262
0
      static std::span<const uint8_t> _as_span(std::string_view s) {
263
0
         return {reinterpret_cast<const uint8_t*>(s.data()), s.size()};
264
0
      }
265
};
266
267
/**
268
* Factory method for KDF (key derivation function)
269
* @param algo_spec the name of the KDF to create
270
* @return pointer to newly allocated object of that type
271
*
272
* Prefer KDF::create
273
*/
274
BOTAN_DEPRECATED("Use KDF::create")
275
276
0
inline KDF* get_kdf(std::string_view algo_spec) {
277
0
   if(algo_spec == "Raw") {
278
0
      return nullptr;
279
0
   }
280
0
281
0
   return KDF::create_or_throw(algo_spec).release();
282
0
}
283
284
}  // namespace Botan
285
286
#endif