1/*
2Copyright (C) 1999-2007 The Botan Project. All rights reserved.
3
4Redistribution and use in source and binary forms, for any use, with or without
5modification, is permitted provided that the following conditions are met:
6
71. Redistributions of source code must retain the above copyright notice, this
8list of conditions, and the following disclaimer.
9
102. Redistributions in binary form must reproduce the above copyright notice,
11this list of conditions, and the following disclaimer in the documentation
12and/or other materials provided with the distribution.
13
14THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED
15WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.
17
18IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT,
19INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26// LICENSEHEADER_END
27namespace QCA { // WRAPNS_LINE
28/*************************************************
29 * Secure Memory Buffers Header File *
30 * (C) 1999-2007 The Botan Project *
31 *************************************************/
32
33#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__
34#define BOTAN_SECURE_MEMORY_BUFFERS_H__
35
36} // WRAPNS_LINE
37#include <botan/allocate.h>
38namespace QCA { // WRAPNS_LINE
39} // WRAPNS_LINE
40#include <botan/mem_ops.h>
41namespace QCA { // WRAPNS_LINE
42
43namespace Botan {
44
45/*************************************************
46 * Variable Length Memory Buffer *
47 *************************************************/
48template<typename T> class MemoryRegion
49{
50public:
51 u32bit size() const
52 {
53 return used;
54 }
55 u32bit is_empty() const
56 {
57 return (used == 0);
58 }
59 u32bit has_items() const
60 {
61 return (used != 0);
62 }
63
64 operator T *()
65 {
66 return buf;
67 }
68 operator const T *() const
69 {
70 return buf;
71 }
72
73 T *begin()
74 {
75 return buf;
76 }
77 const T *begin() const
78 {
79 return buf;
80 }
81
82 T *end()
83 {
84 return (buf + size());
85 }
86 const T *end() const
87 {
88 return (buf + size());
89 }
90
91 bool operator==(const MemoryRegion<T> &other) const
92 {
93 return (size() == other.size() && same_mem(buf, other.buf, size()));
94 }
95
96 bool operator<(const MemoryRegion<T> &) const;
97
98 bool operator!=(const MemoryRegion<T> &in) const
99 {
100 return (!(*this == in));
101 }
102 MemoryRegion<T> &operator=(const MemoryRegion<T> &in)
103 {
104 if (this != &in)
105 set(in);
106 return (*this);
107 }
108
109 void copy(const T in[], u32bit n)
110 {
111 copy(0, in, n);
112 }
113 void copy(u32bit off, const T in[], u32bit n)
114 {
115 copy_mem(buf + off, in, (n > size() - off) ? (size() - off) : n);
116 }
117
118 void set(const T in[], u32bit n)
119 {
120 create(n);
121 copy(in, n);
122 }
123 void set(const MemoryRegion<T> &in)
124 {
125 set(in.begin(), in.size());
126 }
127
128 void append(const T data[], u32bit n)
129 {
130 grow_to(size() + n);
131 copy(size() - n, data, n);
132 }
133 void append(T x)
134 {
135 append(&x, 1);
136 }
137 void append(const MemoryRegion<T> &x)
138 {
139 append(x.begin(), x.size());
140 }
141
142 void clear()
143 {
144 clear_mem(buf, allocated);
145 }
146 void destroy()
147 {
148 create(0);
149 }
150
151 void create(u32bit);
152 void grow_to(u32bit) const;
153 void swap(MemoryRegion<T> &);
154
155 ~MemoryRegion()
156 {
157 deallocate(p: buf, n: allocated);
158 }
159
160protected:
161 MemoryRegion()
162 {
163 buf = nullptr;
164 alloc = nullptr;
165 used = allocated = 0;
166 }
167 MemoryRegion(const MemoryRegion<T> &copy)
168 {
169 buf = nullptr;
170 used = allocated = 0;
171 alloc = copy.alloc;
172 set(copy.buf, copy.used);
173 }
174
175 void init(bool locking, u32bit size = 0)
176 {
177 alloc = Allocator::get(locking);
178 create(size);
179 }
180
181private:
182 T *allocate(u32bit n) const
183 {
184 return (T *)alloc->allocate(sizeof(T) * n);
185 }
186 void deallocate(T *p, u32bit n) const
187 {
188 alloc->deallocate(p, sizeof(T) * n);
189 }
190
191 mutable T *buf;
192 mutable u32bit used;
193 mutable u32bit allocated;
194 mutable Allocator *alloc;
195};
196
197/*************************************************
198 * Create a new buffer *
199 *************************************************/
200template<typename T> void MemoryRegion<T>::create(u32bit n)
201{
202 if (n <= allocated) {
203 clear();
204 used = n;
205 return;
206 }
207 deallocate(p: buf, n: allocated);
208 buf = allocate(n);
209 allocated = used = n;
210}
211
212/*************************************************
213 * Increase the size of the buffer *
214 *************************************************/
215template<typename T> void MemoryRegion<T>::grow_to(u32bit n) const
216{
217 if (n > used && n <= allocated) {
218 clear_mem(buf + used, n - used);
219 used = n;
220 return;
221 } else if (n > allocated) {
222 T *new_buf = allocate(n);
223 copy_mem(new_buf, buf, used);
224 deallocate(p: buf, n: allocated);
225 buf = new_buf;
226 allocated = used = n;
227 }
228}
229
230/*************************************************
231 * Compare this buffer with another one *
232 *************************************************/
233template<typename T> bool MemoryRegion<T>::operator<(const MemoryRegion<T> &in) const
234{
235 if (size() < in.size())
236 return true;
237 if (size() > in.size())
238 return false;
239
240 for (u32bit j = 0; j != size(); j++) {
241 if (buf[j] < in[j])
242 return true;
243 if (buf[j] > in[j])
244 return false;
245 }
246
247 return false;
248}
249
250/*************************************************
251 * Swap this buffer with another one *
252 *************************************************/
253template<typename T> void MemoryRegion<T>::swap(MemoryRegion<T> &x)
254{
255 std::swap(buf, x.buf);
256 std::swap(used, x.used);
257 std::swap(allocated, x.allocated);
258 std::swap(alloc, x.alloc);
259}
260
261/*************************************************
262 * Unlocked Variable Length Buffer *
263 *************************************************/
264template<typename T> class MemoryVector : public MemoryRegion<T>
265{
266public:
267 MemoryVector<T> &operator=(const MemoryRegion<T> &in)
268 {
269 if (this != &in)
270 this->set(in);
271 return (*this);
272 }
273
274 MemoryVector(u32bit n = 0)
275 {
276 MemoryRegion<T>::init(false, n);
277 }
278 MemoryVector(const T in[], u32bit n)
279 {
280 MemoryRegion<T>::init(false);
281 this->set(in, n);
282 }
283 MemoryVector(const MemoryRegion<T> &in)
284 {
285 MemoryRegion<T>::init(false);
286 this->set(in);
287 }
288 MemoryVector(const MemoryRegion<T> &in1, const MemoryRegion<T> &in2)
289 {
290 MemoryRegion<T>::init(false);
291 this->set(in1);
292 append(in2);
293 }
294};
295
296/*************************************************
297 * Locked Variable Length Buffer *
298 *************************************************/
299template<typename T> class SecureVector : public MemoryRegion<T>
300{
301public:
302 SecureVector<T> &operator=(const MemoryRegion<T> &in)
303 {
304 if (this != &in)
305 this->set(in);
306 return (*this);
307 }
308
309 SecureVector(u32bit n = 0)
310 {
311 MemoryRegion<T>::init(true, n);
312 }
313 SecureVector(const T in[], u32bit n)
314 {
315 MemoryRegion<T>::init(true);
316 this->set(in, n);
317 }
318 SecureVector(const MemoryRegion<T> &in)
319 {
320 MemoryRegion<T>::init(true);
321 this->set(in);
322 }
323 SecureVector(const MemoryRegion<T> &in1, const MemoryRegion<T> &in2)
324 {
325 MemoryRegion<T>::init(true);
326 this->set(in1);
327 append(in2);
328 }
329};
330
331/*************************************************
332 * Locked Fixed Length Buffer *
333 *************************************************/
334template<typename T, u32bit L>
335class SecureBuffer : public MemoryRegion<T> // clazy:exclude=rule-of-three TODO Needs checking if a real bug or not
336{
337public:
338 SecureBuffer<T, L> &operator=(const SecureBuffer<T, L> &in)
339 {
340 if (this != &in)
341 this->set(in);
342 return (*this);
343 }
344
345 SecureBuffer()
346 {
347 MemoryRegion<T>::init(true, L);
348 }
349 SecureBuffer(const T in[], u32bit n)
350 {
351 MemoryRegion<T>::init(true, L);
352 copy(in, n);
353 }
354
355private:
356 SecureBuffer<T, L> &operator=(const MemoryRegion<T> &in)
357 {
358 if (this != &in)
359 this->set(in);
360 return (*this);
361 }
362};
363
364}
365
366#endif
367} // WRAPNS_LINE
368

source code of qca/src/botantools/botan/botan/secmem.h