1 | /* |
2 | Copyright (C) 1999-2007 The Botan Project. All rights reserved. |
3 | |
4 | Redistribution and use in source and binary forms, for any use, with or without |
5 | modification, is permitted provided that the following conditions are met: |
6 | |
7 | 1. Redistributions of source code must retain the above copyright notice, this |
8 | list of conditions, and the following disclaimer. |
9 | |
10 | 2. Redistributions in binary form must reproduce the above copyright notice, |
11 | this list of conditions, and the following disclaimer in the documentation |
12 | and/or other materials provided with the distribution. |
13 | |
14 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) "AS IS" AND ANY EXPRESS OR IMPLIED |
15 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
16 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE DISCLAIMED. |
17 | |
18 | IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE FOR ANY DIRECT, |
19 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
20 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
22 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
23 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
24 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | */ |
26 | // LICENSEHEADER_END |
27 | namespace 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> |
38 | namespace QCA { // WRAPNS_LINE |
39 | } // WRAPNS_LINE |
40 | #include <botan/mem_ops.h> |
41 | namespace QCA { // WRAPNS_LINE |
42 | |
43 | namespace Botan { |
44 | |
45 | /************************************************* |
46 | * Variable Length Memory Buffer * |
47 | *************************************************/ |
48 | template<typename T> class MemoryRegion |
49 | { |
50 | public: |
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 | |
160 | protected: |
161 | MemoryRegion() |
162 | { |
163 | buf = nullptr; |
164 | alloc = nullptr; |
165 | used = allocated = 0; |
166 | } |
167 | MemoryRegion(const MemoryRegion<T> ©) |
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 | |
181 | private: |
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 | *************************************************/ |
200 | template<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 | *************************************************/ |
215 | template<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 | *************************************************/ |
233 | template<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 | *************************************************/ |
253 | template<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 | *************************************************/ |
264 | template<typename T> class MemoryVector : public MemoryRegion<T> |
265 | { |
266 | public: |
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 | *************************************************/ |
299 | template<typename T> class SecureVector : public MemoryRegion<T> |
300 | { |
301 | public: |
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 | *************************************************/ |
334 | template<typename T, u32bit L> |
335 | class SecureBuffer : public MemoryRegion<T> // clazy:exclude=rule-of-three TODO Needs checking if a real bug or not |
336 | { |
337 | public: |
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 | |
355 | private: |
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 | |