~ubuntu-branches/ubuntu/precise/botan1.8/precise

« back to all changes in this revision

Viewing changes to src/utils/secmem.h

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-08-04 00:47:32 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090804004732-bmf7f33nfoctocbz
Tags: 1.8.5-1
* Merging upstream version 1.8.5.
* Adding old changelog entries for separately uploaded botan packages
  in the past.
* Using correct rfc-2822 date formats in changelog.
* Wrapping build depends.
* Adding misc depends.
* Renaming local manpages directory to common name.
* Minimizing rules file.
* Doing some minor cosmetical updates in the manpage.
* Updating copyright file to reflect changes of upstream version
  1.8.0.
* Using new configure.py instread of configure.pl, updating necessary
  things to cope with that.
* Updating.
* Tidy debhelper install files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
* Secure Memory Buffers
3
 
* (C) 1999-2007 Jack Lloyd
4
 
*
5
 
* Distributed under the terms of the Botan license
6
 
*/
7
 
 
8
 
#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__
9
 
#define BOTAN_SECURE_MEMORY_BUFFERS_H__
10
 
 
11
 
#include <botan/allocate.h>
12
 
#include <botan/mem_ops.h>
13
 
#include <algorithm>
14
 
 
15
 
namespace Botan {
16
 
 
17
 
/**
18
 
* This class represents variable length memory buffers.
19
 
*/
20
 
template<typename T>
21
 
class MemoryRegion
22
 
   {
23
 
   public:
24
 
      /**
25
 
      * Find out the size of the buffer, i.e. how many objects of type T it
26
 
      * contains.
27
 
      * @return the size of the buffer
28
 
      */
29
 
      u32bit size() const { return used; }
30
 
 
31
 
      /**
32
 
      * Find out whether this buffer is empty.
33
 
      * @return true if the buffer is empty, false otherwise
34
 
      */
35
 
      bool is_empty() const { return (used == 0); }
36
 
 
37
 
      /**
38
 
      * Find out whether this buffer is non-empty
39
 
      * @return true if the buffer is non-empty, false otherwise
40
 
      */
41
 
      bool has_items() const { return (used != 0); }
42
 
 
43
 
      /**
44
 
      * Get a pointer to the first element in the buffer.
45
 
      * @return a pointer to the first element in the buffer
46
 
      */
47
 
      operator T* () { return buf; }
48
 
 
49
 
      /**
50
 
      * Get a constant pointer to the first element in the buffer.
51
 
      * @return a constant pointer to the first element in the buffer
52
 
      */
53
 
      operator const T* () const { return buf; }
54
 
 
55
 
      /**
56
 
      * Get a pointer to the first element in the buffer.
57
 
      * @return a pointer to the first element in the buffer
58
 
      */
59
 
      T* begin() { return buf; }
60
 
 
61
 
      /**
62
 
      * Get a constant pointer to the first element in the buffer.
63
 
      * @return a constant pointer to the first element in the buffer
64
 
      */
65
 
      const T* begin() const { return buf; }
66
 
 
67
 
      /**
68
 
      * Get a pointer to the last element in the buffer.
69
 
      * @return a pointer to the last element in the buffer
70
 
      */
71
 
      T* end() { return (buf + size()); }
72
 
 
73
 
      /**
74
 
      * Get a constant pointer to the last element in the buffer.
75
 
      * @return a constant pointer to the last element in the buffer
76
 
      */
77
 
      const T* end() const { return (buf + size()); }
78
 
 
79
 
      /**
80
 
      * Check two buffers for equality.
81
 
      * @return true iff the content of both buffers is byte-wise equal
82
 
      */
83
 
      bool operator==(const MemoryRegion<T>& other) const
84
 
         {
85
 
         return (size() == other.size() &&
86
 
                 same_mem(buf, other.buf, size()));
87
 
         }
88
 
 
89
 
      /**
90
 
      * Compare two buffers lexicographically.
91
 
      * @return true if this buffer is lexicographically smaller than other.
92
 
      */
93
 
      bool operator<(const MemoryRegion<T>& other) const;
94
 
 
95
 
      /**
96
 
      * Check two buffers for inequality.
97
 
      * @return false if the content of both buffers is byte-wise equal, true
98
 
      * otherwise.
99
 
      */
100
 
      bool operator!=(const MemoryRegion<T>& in) const
101
 
         { return (!(*this == in)); }
102
 
 
103
 
      /**
104
 
      * Copy the contents of another buffer into this buffer.
105
 
      * The former contents of *this are discarded.
106
 
      * @param in the buffer to copy the contents from.
107
 
      * @return a reference to *this
108
 
      */
109
 
      MemoryRegion<T>& operator=(const MemoryRegion<T>& in)
110
 
         { if(this != &in) set(in); return (*this); }
111
 
 
112
 
      /**
113
 
      * The use of this function is discouraged because of the risk of memory
114
 
      * errors. Use MemoryRegion<T>::set()
115
 
      * instead.
116
 
      * Copy the contents of an array of objects of type T into this buffer.
117
 
      * The former contents of *this are discarded.
118
 
      * The length of *this must be at least n, otherwise memory errors occur.
119
 
      * @param in the array to copy the contents from
120
 
      * @param n the length of in
121
 
      */
122
 
      void copy(const T in[], u32bit n)
123
 
         { copy(0, in, n); }
124
 
 
125
 
      /**
126
 
      * The use of this function is discouraged because of the risk of memory
127
 
      * errors. Use MemoryRegion<T>::set()
128
 
      * instead.
129
 
      * Copy the contents of an array of objects of type T into this buffer.
130
 
      * The former contents of *this are discarded.
131
 
      * The length of *this must be at least n, otherwise memory errors occur.
132
 
      * @param off the offset position inside this buffer to start inserting
133
 
      * the copied bytes
134
 
      * @param in the array to copy the contents from
135
 
      * @param n the length of in
136
 
      */
137
 
      void copy(u32bit off, const T in[], u32bit n)
138
 
         { copy_mem(buf + off, in, (n > size() - off) ? (size() - off) : n); }
139
 
 
140
 
      /**
141
 
      * Set the contents of this according to the argument. The size of
142
 
      * *this is increased if necessary.
143
 
      * @param in the array of objects of type T to copy the contents from
144
 
      * @param n the size of array in
145
 
      */
146
 
      void set(const T in[], u32bit n)    { create(n); copy(in, n); }
147
 
 
148
 
      /**
149
 
      * Set the contents of this according to the argument. The size of
150
 
      * *this is increased if necessary.
151
 
      * @param in the buffer to copy the contents from
152
 
      */
153
 
      void set(const MemoryRegion<T>& in) { set(in.begin(), in.size()); }
154
 
 
155
 
      /**
156
 
      * Append data to the end of this buffer.
157
 
      * @param data the array containing the data to append
158
 
      * @param n the size of the array data
159
 
      */
160
 
      void append(const T data[], u32bit n)
161
 
         { grow_to(size()+n); copy(size() - n, data, n); }
162
 
 
163
 
      /**
164
 
      * Append a single element.
165
 
      * @param x the element to append
166
 
      */
167
 
      void append(T x) { append(&x, 1); }
168
 
 
169
 
      /**
170
 
      * Append data to the end of this buffer.
171
 
      * @param data the buffer containing the data to append
172
 
      */
173
 
      void append(const MemoryRegion<T>& x) { append(x.begin(), x.size()); }
174
 
 
175
 
      /**
176
 
      * Zeroise the bytes of this buffer. The length remains unchanged.
177
 
      */
178
 
      void clear() { clear_mem(buf, allocated); }
179
 
 
180
 
      /**
181
 
      * Reset this buffer to an empty buffer with size zero.
182
 
      */
183
 
      void destroy() { create(0); }
184
 
 
185
 
      /**
186
 
      * Reset this buffer to a buffer of specified length. The content will be
187
 
      * initialized to zero bytes.
188
 
      * @param n the new length of the buffer
189
 
      */
190
 
      void create(u32bit n);
191
 
 
192
 
      /**
193
 
      * Preallocate memory, so that this buffer can grow up to size n without
194
 
      * having to perform any actual memory allocations. (This is
195
 
      * the same principle as for std::vector::reserve().)
196
 
      */
197
 
      void grow_to(u32bit N);
198
 
 
199
 
      /**
200
 
      * Swap this buffer with another object.
201
 
      */
202
 
      void swap(MemoryRegion<T>& other);
203
 
 
204
 
      ~MemoryRegion() { deallocate(buf, allocated); }
205
 
   protected:
206
 
      MemoryRegion() { buf = 0; alloc = 0; used = allocated = 0; }
207
 
      MemoryRegion(const MemoryRegion<T>& other)
208
 
         {
209
 
         buf = 0;
210
 
         used = allocated = 0;
211
 
         alloc = other.alloc;
212
 
         set(other.buf, other.used);
213
 
         }
214
 
 
215
 
      void init(bool locking, u32bit length = 0)
216
 
         { alloc = Allocator::get(locking); create(length); }
217
 
   private:
218
 
      T* allocate(u32bit n)
219
 
         {
220
 
         return static_cast<T*>(alloc->allocate(sizeof(T)*n));
221
 
         }
222
 
 
223
 
      void deallocate(T* p, u32bit n)
224
 
         { alloc->deallocate(p, sizeof(T)*n); }
225
 
 
226
 
      T* buf;
227
 
      u32bit used;
228
 
      u32bit allocated;
229
 
      Allocator* alloc;
230
 
   };
231
 
 
232
 
/*
233
 
* Create a new buffer
234
 
*/
235
 
template<typename T>
236
 
void MemoryRegion<T>::create(u32bit n)
237
 
   {
238
 
   if(n <= allocated) { clear(); used = n; return; }
239
 
   deallocate(buf, allocated);
240
 
   buf = allocate(n);
241
 
   allocated = used = n;
242
 
   }
243
 
 
244
 
/*
245
 
* Increase the size of the buffer
246
 
*/
247
 
template<typename T>
248
 
void MemoryRegion<T>::grow_to(u32bit n)
249
 
   {
250
 
   if(n > used && n <= allocated)
251
 
      {
252
 
      clear_mem(buf + used, n - used);
253
 
      used = n;
254
 
      return;
255
 
      }
256
 
   else if(n > allocated)
257
 
      {
258
 
      T* new_buf = allocate(n);
259
 
      copy_mem(new_buf, buf, used);
260
 
      deallocate(buf, allocated);
261
 
      buf = new_buf;
262
 
      allocated = used = n;
263
 
      }
264
 
   }
265
 
 
266
 
/*
267
 
* Compare this buffer with another one
268
 
*/
269
 
template<typename T>
270
 
bool MemoryRegion<T>::operator<(const MemoryRegion<T>& in) const
271
 
   {
272
 
   if(size() < in.size()) return true;
273
 
   if(size() > in.size()) return false;
274
 
 
275
 
   for(u32bit j = 0; j != size(); j++)
276
 
      {
277
 
      if(buf[j] < in[j]) return true;
278
 
      if(buf[j] > in[j]) return false;
279
 
      }
280
 
 
281
 
   return false;
282
 
   }
283
 
 
284
 
/*
285
 
* Swap this buffer with another one
286
 
*/
287
 
template<typename T>
288
 
void MemoryRegion<T>::swap(MemoryRegion<T>& x)
289
 
   {
290
 
   std::swap(buf, x.buf);
291
 
   std::swap(used, x.used);
292
 
   std::swap(allocated, x.allocated);
293
 
   std::swap(alloc, x.alloc);
294
 
   }
295
 
 
296
 
/**
297
 
* This class represents variable length buffers that do not
298
 
* make use of memory locking.
299
 
*/
300
 
template<typename T>
301
 
class MemoryVector : public MemoryRegion<T>
302
 
   {
303
 
   public:
304
 
      /**
305
 
      * Copy the contents of another buffer into this buffer.
306
 
      * @param in the buffer to copy the contents from
307
 
      * @return a reference to *this
308
 
      */
309
 
      MemoryVector<T>& operator=(const MemoryRegion<T>& in)
310
 
         { if(this != &in) set(in); return (*this); }
311
 
 
312
 
      /**
313
 
      * Create a buffer of the specified length.
314
 
      * @param n the length of the buffer to create.
315
 
 
316
 
      */
317
 
      MemoryVector(u32bit n = 0) { MemoryRegion<T>::init(false, n); }
318
 
 
319
 
      /**
320
 
      * Create a buffer with the specified contents.
321
 
      * @param in the array containing the data to be initially copied
322
 
      * into the newly created buffer
323
 
      * @param n the size of the arry in
324
 
      */
325
 
      MemoryVector(const T in[], u32bit n)
326
 
         { MemoryRegion<T>::init(false); set(in, n); }
327
 
 
328
 
      /**
329
 
      * Copy constructor.
330
 
      */
331
 
      MemoryVector(const MemoryRegion<T>& in)
332
 
         { MemoryRegion<T>::init(false); set(in); }
333
 
 
334
 
      /**
335
 
      * Create a buffer whose content is the concatenation of two other
336
 
      * buffers.
337
 
      * @param in1 the first part of the new contents
338
 
      * @param in2 the contents to be appended to in1
339
 
      */
340
 
      MemoryVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
341
 
         { MemoryRegion<T>::init(false); set(in1); append(in2); }
342
 
   };
343
 
 
344
 
/**
345
 
* This class represents variable length buffers using the operating
346
 
* systems capability to lock memory, i.e. keeping it from being
347
 
* swapped out to disk. In this way, a security hole allowing attackers
348
 
* to find swapped out secret keys is closed. Please refer to
349
 
* Botan::InitializerOptions::secure_memory() for restrictions and
350
 
* further details.
351
 
*/
352
 
template<typename T>
353
 
class SecureVector : public MemoryRegion<T>
354
 
   {
355
 
   public:
356
 
      /**
357
 
      * Copy the contents of another buffer into this buffer.
358
 
      * @param in the buffer to copy the contents from
359
 
      * @return a reference to *this
360
 
      */
361
 
      SecureVector<T>& operator=(const MemoryRegion<T>& in)
362
 
         { if(this != &in) set(in); return (*this); }
363
 
 
364
 
      /**
365
 
      * Create a buffer of the specified length.
366
 
      * @param n the length of the buffer to create.
367
 
 
368
 
      */
369
 
      SecureVector(u32bit n = 0) { MemoryRegion<T>::init(true, n); }
370
 
 
371
 
      /**
372
 
      * Create a buffer with the specified contents.
373
 
      * @param in the array containing the data to be initially copied
374
 
      * into the newly created buffer
375
 
      * @param n the size of the array in
376
 
      */
377
 
      SecureVector(const T in[], u32bit n)
378
 
         { MemoryRegion<T>::init(true); set(in, n); }
379
 
 
380
 
      /**
381
 
      * Create a buffer with contents specified contents.
382
 
      * @param in the buffer holding the contents that will be
383
 
      * copied into the newly created buffer.
384
 
      */
385
 
      SecureVector(const MemoryRegion<T>& in)
386
 
         { MemoryRegion<T>::init(true); set(in); }
387
 
 
388
 
      /**
389
 
      * Create a buffer whose content is the concatenation of two other
390
 
      * buffers.
391
 
      * @param in1 the first part of the new contents
392
 
      * @param in2 the contents to be appended to in1
393
 
      */
394
 
      SecureVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
395
 
         { MemoryRegion<T>::init(true); set(in1); append(in2); }
396
 
   };
397
 
 
398
 
/**
399
 
* This class represents fixed length buffers using the operating
400
 
* systems capability to lock memory, i.e. keeping it from being
401
 
* swapped out to disk. In this way, a security hole allowing attackers
402
 
* to find swapped out secret keys is closed. Please refer to
403
 
* Botan::InitializerOptions::secure_memory() for restrictions and
404
 
* further details.
405
 
*/
406
 
template<typename T, u32bit L>
407
 
class SecureBuffer : public MemoryRegion<T>
408
 
   {
409
 
   public:
410
 
      /**
411
 
      * Copy the contents of another buffer into this buffer.
412
 
      * @param in the buffer to copy the contents from
413
 
      * @return a reference to *this
414
 
      */
415
 
      SecureBuffer<T,L>& operator=(const SecureBuffer<T,L>& in)
416
 
         { if(this != &in) set(in); return (*this); }
417
 
 
418
 
      /**
419
 
      * Create a buffer of the length L.
420
 
      */
421
 
      SecureBuffer() { MemoryRegion<T>::init(true, L); }
422
 
 
423
 
      /**
424
 
      * Create a buffer of size L with the specified contents.
425
 
      * @param in the array containing the data to be initially copied
426
 
      * into the newly created buffer
427
 
      * @param n the size of the array in
428
 
      */
429
 
      SecureBuffer(const T in[], u32bit n)
430
 
         { MemoryRegion<T>::init(true, L); copy(in, n); }
431
 
   private:
432
 
      SecureBuffer<T, L>& operator=(const MemoryRegion<T>& in)
433
 
         { if(this != &in) set(in); return (*this); }
434
 
   };
435
 
 
436
 
}
437
 
 
438
 
#endif