Coverage Report

Created: 2025-04-11 06:34

/src/botan/build/include/public/botan/xof.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Extendable Output Function Base Class
3
* (C) 2023 Jack Lloyd
4
*     2023 Fabian Albert, René Meusel - Rohde & Schwarz Cybersecurity
5
*
6
* Botan is released under the Simplified BSD License (see license.txt)
7
*/
8
9
#ifndef BOTAN_XOF_BASE_CLASS_H_
10
#define BOTAN_XOF_BASE_CLASS_H_
11
12
#include <botan/concepts.h>
13
#include <botan/secmem.h>
14
#include <botan/sym_algo.h>
15
16
#include <memory>
17
#include <string>
18
#include <string_view>
19
20
namespace Botan {
21
22
/**
23
 * This class represents an eXtendable Output Function (XOF) objects
24
 *
25
 * A XOF transforms an arbitrary length input message into an indefinite
26
 * stream of output bits. Typically, it is illegal to call `update()` after
27
 * the first call to `output()`.
28
 */
29
class BOTAN_PUBLIC_API(3, 2) XOF {
30
   public:
31
270
      XOF() : m_xof_started(false) {}
32
33
270
      virtual ~XOF() = default;
34
35
      /**
36
       * Create an instance based on a name, or return null if the
37
       * algo/provider combination cannot be found. If provider is
38
       * empty then best available is chosen.
39
       */
40
      static std::unique_ptr<XOF> create(std::string_view algo_spec, std::string_view provider = "");
41
42
      /**
43
       * Create an instance based on a name
44
       * If provider is empty then best available is chosen.
45
       * @param algo_spec algorithm name
46
       * @param provider provider implementation to use
47
       * Throws Lookup_Error if not found.
48
       */
49
      static std::unique_ptr<XOF> create_or_throw(std::string_view algo_spec, std::string_view provider = "");
50
51
      /**
52
       * @return list of available providers for this algorithm, empty if not available
53
       * @param algo_spec algorithm name
54
       */
55
      static std::vector<std::string> providers(std::string_view algo_spec);
56
57
      /**
58
       * @return provider information about this implementation. Default is "base",
59
       * might also return "sse2", "avx2", "openssl", or some other arbitrary string.
60
       */
61
      virtual std::string provider() const;
62
63
      /**
64
       * Reset the state.
65
       */
66
0
      void clear() {
67
0
         m_xof_started = false;
68
0
         reset();
69
0
      }
70
71
      /**
72
       * @return the hash function name
73
       */
74
      virtual std::string name() const = 0;
75
76
      /**
77
       * Some XOFs can be parameterized with a @p salt and/or @p key. If required,
78
       * this must be called before calling XOF::update().
79
       *
80
       * @sa XOF::valid_salt_length()
81
       * @sa XOF::key_spec()
82
       *
83
       * @param salt  a salt value to parameterize the XOF
84
       * @param key   a key to parameterize the XOF
85
       */
86
      void start(std::span<const uint8_t> salt = {}, std::span<const uint8_t> key = {});
87
88
      /**
89
       * @returns true if salt length is acceptable, false otherwise
90
       */
91
160
      virtual bool valid_salt_length(size_t salt_len) const {
92
         // Salts are not supported by default
93
160
         return salt_len == 0;
94
160
      }
95
96
      /**
97
       * @returns an object describing limits on the key size
98
       */
99
160
      virtual Key_Length_Specification key_spec() const {
100
         // Keys are not supported by default
101
160
         return Key_Length_Specification(0);
102
160
      }
103
104
      /**
105
       * @return the intrinsic processing block size of this XOF
106
       */
107
      virtual size_t block_size() const = 0;
108
109
      /**
110
       * Return a new XOF object with the same state as *this.
111
       *
112
       * If the XOF is not yet in the output phase, it efficiently allows
113
       * using several messages with a common prefix.
114
       * Otherwise, the copied state will produce the same output
115
       * bit stream as the original object at the time of this invocation.
116
       *
117
       * This function should be called `clone` but for consistency with
118
       * other classes it is called `copy_state`.
119
       *
120
       * @return new XOF object
121
       */
122
      virtual std::unique_ptr<XOF> copy_state() const = 0;
123
124
      /**
125
       * @return new object representing the same algorithm as *this
126
       */
127
      virtual std::unique_ptr<XOF> new_object() const = 0;
128
129
      /**
130
       * Typically, this is `true` for new objects and becomes `false`
131
       * once `output()` was called for the first time.
132
       *
133
       * @returns true iff calling `update()` is legal in the current object state
134
       */
135
      virtual bool accepts_input() const = 0;
136
137
      /**
138
       * Add @p input data to the XOF's internal state
139
       *
140
       * @param input  the data that shall be
141
       */
142
160
      void update(std::span<const uint8_t> input) {
143
160
         if(!m_xof_started) {
144
            // If the user didn't start() before the first input, we enforce
145
            // it with a default value, here.
146
160
            start();
147
160
         }
148
160
         add_data(input);
149
160
      }
150
151
      /**
152
       * @return the next @p bytes output bytes as the specified container type @p T.
153
       */
154
      template <concepts::resizable_byte_buffer T = secure_vector<uint8_t>>
155
0
      T output(size_t bytes) {
156
0
         T out(bytes);
157
0
         generate_bytes(out);
158
0
         return out;
159
0
      }
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENSt3__16vectorIhNS3_9allocatorIhEEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_18CmceRejectionSeed_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_17CmceOrderingBits_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_20CmceIrreducibleBits_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS4_9allocatorIhEEEENS_25DilithiumHashedPublicKey_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS4_9allocatorIhEEEENS_31DilithiumMessageRepresentative_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS4_9allocatorIhEEEENS_24DilithiumCommitmentHash_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS4_9allocatorIhEEEENS_20DilithiumPublicSeed_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_22DilithiumSeedRhoPrime_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_15DilithiumSeedK_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS4_9allocatorIhEEEENS_19FrodoPublicKeyHash_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_12FrodoSeedSE_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_30FrodoIntermediateSharedSecret_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS4_9allocatorIhEEEENS_11FrodoSeedA_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_24KyberSamplingRandomness_EJEEEEET_m
Unexecuted instantiation: _ZN5Botan3XOF6outputITkNS_8concepts21resizable_byte_bufferENS_6StrongINSt3__16vectorIhNS_16secure_allocatorIhEEEENS_13FrodoSampleR_EJEEEEET_m
160
161
      /**
162
       * @return the next @p count output bytes as a std::array<>.
163
       */
164
      template <size_t count>
165
0
      std::array<uint8_t, count> output() {
166
0
         std::array<uint8_t, count> out;
167
0
         generate_bytes(out);
168
0
         return out;
169
0
      }
Unexecuted instantiation: std::__1::array<unsigned char, 8ul> Botan::XOF::output<8ul>()
Unexecuted instantiation: std::__1::array<unsigned char, 1ul> Botan::XOF::output<1ul>()
Unexecuted instantiation: std::__1::array<unsigned char, 3ul> Botan::XOF::output<3ul>()
170
171
      /**
172
       * Convenience overload to generate a std::vector<uint8_t>. Same as calling
173
       * `XOF::output<std::vector<uint8_t>>()`.
174
       *
175
       * @return the next @p bytes output bytes as a byte vector.
176
       */
177
0
      std::vector<uint8_t> output_stdvec(size_t bytes) { return output<std::vector<uint8_t>>(bytes); }
178
179
      /**
180
       * Fill @p output with the next output bytes. The number of bytes
181
       * depends on the size of @p output.
182
       */
183
160
      void output(std::span<uint8_t> output) { generate_bytes(output); }
184
185
      /**
186
       * @return the next single output byte
187
       */
188
0
      uint8_t output_next_byte() {
189
0
         uint8_t out;
190
0
         generate_bytes({&out, 1});
191
0
         return out;
192
0
      }
193
194
   private:
195
      /**
196
       * Take @p salt and/or @p key to pre-parameterize the XOF. This must be called
197
       * before calling XOF::update().
198
       *
199
       * @param salt  a salt value to parameterize the XOF
200
       * @param key   a key to parameterize the XOF
201
       */
202
      virtual void start_msg(std::span<const uint8_t> salt, std::span<const uint8_t> key);
203
204
      /**
205
       * Consume @p input data bytes into the XOF's internal state
206
       *
207
       * Typically, XOFs may consume an arbitrary length of input data but
208
       * should refuse accepting more input once the first output bit was
209
       * generated. Implementations should throw `Invalid_State` in this
210
       * case.
211
       *
212
       * @param input  the span to be consumed entirely into the internal state
213
       * @throws        Invalid_State if input is added after generating output
214
       */
215
      virtual void add_data(std::span<const uint8_t> input) = 0;
216
217
      /**
218
       * Fill the entire @p output span with the next bytes in their output
219
       * stream.
220
       *
221
       * The first invocation to `generate_bytes()` should typically transition
222
       * the XOF's state to "output mode" and prevent any further calls to
223
       * `XOF::add_data()`.
224
       *
225
       * @param output  the span to be filled entirely with output bytes
226
       */
227
      virtual void generate_bytes(std::span<uint8_t> output) = 0;
228
229
      /**
230
       * Clear the XOF's internal state and allow for new input.
231
       */
232
      virtual void reset() = 0;
233
234
   private:
235
      bool m_xof_started;
236
};
237
238
}  // namespace Botan
239
240
#endif