1 /*
2 * Buffered Computation
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #ifndef BOTAN_BUFFERED_COMPUTATION_H_
9 #define BOTAN_BUFFERED_COMPUTATION_H_
10 
11 #include <botan/secmem.h>
12 #include <string>
13 
14 namespace Botan {
15 
16 /**
17 * This class represents any kind of computation which uses an internal
18 * state, such as hash functions or MACs
19 */
20 class BOTAN_PUBLIC_API(2,0) Buffered_Computation
21    {
22    public:
23       /**
24       * @return length of the output of this function in bytes
25       */
26       virtual size_t output_length() const = 0;
27 
28       /**
29       * Add new input to process.
30       * @param in the input to process as a byte array
31       * @param length of param in in bytes
32       */
update(const uint8_t in[],size_t length)33       void update(const uint8_t in[], size_t length) { add_data(in, length); }
34 
35       /**
36       * Add new input to process.
37       * @param in the input to process as a secure_vector
38       */
update(const secure_vector<uint8_t> & in)39       void update(const secure_vector<uint8_t>& in)
40          {
41          add_data(in.data(), in.size());
42          }
43 
44       /**
45       * Add new input to process.
46       * @param in the input to process as a std::vector
47       */
update(const std::vector<uint8_t> & in)48       void update(const std::vector<uint8_t>& in)
49          {
50          add_data(in.data(), in.size());
51          }
52 
53       void update_be(uint16_t val);
54       void update_be(uint32_t val);
55       void update_be(uint64_t val);
56 
57       void update_le(uint16_t val);
58       void update_le(uint32_t val);
59       void update_le(uint64_t val);
60 
61       /**
62       * Add new input to process.
63       * @param str the input to process as a std::string. Will be interpreted
64       * as a byte array based on the strings encoding.
65       */
update(const std::string & str)66       void update(const std::string& str)
67          {
68          add_data(cast_char_ptr_to_uint8(str.data()), str.size());
69          }
70 
71       /**
72       * Process a single byte.
73       * @param in the byte to process
74       */
update(uint8_t in)75       void update(uint8_t in) { add_data(&in, 1); }
76 
77       /**
78       * Complete the computation and retrieve the
79       * final result.
80       * @param out The byte array to be filled with the result.
81       * Must be of length output_length()
82       */
final(uint8_t out[])83       void final(uint8_t out[]) { final_result(out); }
84 
85       /**
86       * Complete the computation and retrieve the
87       * final result.
88       * @return secure_vector holding the result
89       */
final()90       secure_vector<uint8_t> final()
91          {
92          secure_vector<uint8_t> output(output_length());
93          final_result(output.data());
94          return output;
95          }
96 
final_stdvec()97       std::vector<uint8_t> final_stdvec()
98          {
99          std::vector<uint8_t> output(output_length());
100          final_result(output.data());
101          return output;
102          }
103 
104       template<typename Alloc>
final(std::vector<uint8_t,Alloc> & out)105          void final(std::vector<uint8_t, Alloc>& out)
106          {
107          out.resize(output_length());
108          final_result(out.data());
109          }
110 
111       /**
112       * Update and finalize computation. Does the same as calling update()
113       * and final() consecutively.
114       * @param in the input to process as a byte array
115       * @param length the length of the byte array
116       * @result the result of the call to final()
117       */
process(const uint8_t in[],size_t length)118       secure_vector<uint8_t> process(const uint8_t in[], size_t length)
119          {
120          add_data(in, length);
121          return final();
122          }
123 
124       /**
125       * Update and finalize computation. Does the same as calling update()
126       * and final() consecutively.
127       * @param in the input to process
128       * @result the result of the call to final()
129       */
process(const secure_vector<uint8_t> & in)130       secure_vector<uint8_t> process(const secure_vector<uint8_t>& in)
131          {
132          add_data(in.data(), in.size());
133          return final();
134          }
135 
136       /**
137       * Update and finalize computation. Does the same as calling update()
138       * and final() consecutively.
139       * @param in the input to process
140       * @result the result of the call to final()
141       */
process(const std::vector<uint8_t> & in)142       secure_vector<uint8_t> process(const std::vector<uint8_t>& in)
143          {
144          add_data(in.data(), in.size());
145          return final();
146          }
147 
148       /**
149       * Update and finalize computation. Does the same as calling update()
150       * and final() consecutively.
151       * @param in the input to process as a string
152       * @result the result of the call to final()
153       */
process(const std::string & in)154       secure_vector<uint8_t> process(const std::string& in)
155          {
156          update(in);
157          return final();
158          }
159 
160       virtual ~Buffered_Computation() = default;
161    private:
162       /**
163       * Add more data to the computation
164       * @param input is an input buffer
165       * @param length is the length of input in bytes
166       */
167       virtual void add_data(const uint8_t input[], size_t length) = 0;
168 
169       /**
170       * Write the final output to out
171       * @param out is an output buffer of output_length()
172       */
173       virtual void final_result(uint8_t out[]) = 0;
174    };
175 
176 }
177 
178 #endif
179