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