monotone

monotone Mtn Source Tree

Root/cryptopp/secblock.h

1// secblock.h - written and placed in the public domain by Wei Dai
2
3#ifndef CRYPTOPP_SECBLOCK_H
4#define CRYPTOPP_SECBLOCK_H
5
6#include "config.h"
7#include "misc.h"
8#include <string.h>// CodeWarrior doesn't have memory.h
9#include <assert.h>
10
11NAMESPACE_BEGIN(CryptoPP)
12
13// ************** secure memory allocation ***************
14
15template<class T>
16class AllocatorBase
17{
18public:
19typedef T value_type;
20typedef size_t size_type;
21#if (defined(_MSC_VER) && _MSC_VER < 1300)
22typedef ptrdiff_t difference_type;
23#else
24typedef std::ptrdiff_t difference_type;
25#endif
26typedef T * pointer;
27typedef const T * const_pointer;
28typedef T & reference;
29typedef const T & const_reference;
30
31pointer address(reference r) const {return (&r);}
32const_pointer address(const_reference r) const {return (&r); }
33void construct(pointer p, const T& val) {new (p) T(val);}
34void destroy(pointer p) {p->~T();}
35size_type max_size() const {return size_type(-1)/sizeof(T);}
36};
37
38#define CRYPTOPP_INHERIT_ALLOCATOR_TYPES\
39typedef typename AllocatorBase<T>::value_type value_type;\
40typedef typename AllocatorBase<T>::size_type size_type;\
41typedef typename AllocatorBase<T>::difference_type difference_type;\
42typedef typename AllocatorBase<T>::pointer pointer;\
43typedef typename AllocatorBase<T>::const_pointer const_pointer;\
44typedef typename AllocatorBase<T>::reference reference;\
45typedef typename AllocatorBase<T>::const_reference const_reference;
46
47template <class T, class A>
48typename A::pointer StandardReallocate(A& a, T *p, typename A::size_type oldSize, typename A::size_type newSize, bool preserve)
49{
50if (oldSize == newSize)
51return p;
52
53if (preserve)
54{
55typename A::pointer newPointer = a.allocate(newSize, NULL);
56memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize));
57a.deallocate(p, oldSize);
58return newPointer;
59}
60else
61{
62a.deallocate(p, oldSize);
63return a.allocate(newSize, NULL);
64}
65}
66
67template <class T>
68class AllocatorWithCleanup : public AllocatorBase<T>
69{
70public:
71CRYPTOPP_INHERIT_ALLOCATOR_TYPES
72
73pointer allocate(size_type n, const void * = NULL)
74{
75if (n > 0)
76return new T[n];
77else
78return NULL;
79}
80
81void deallocate(void *p, size_type n)
82{
83memset(p, 0, n*sizeof(T));
84delete [] (T *)p;
85}
86
87pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve)
88{
89return StandardReallocate(*this, p, oldSize, newSize, preserve);
90}
91
92// VS.NET STL enforces the policy of "All STL-compliant allocators have to provide a
93// template class member called rebind".
94 template <class U> struct rebind { typedef AllocatorWithCleanup<U> other; };
95};
96
97template <class T>
98class NullAllocator : public AllocatorBase<T>
99{
100public:
101CRYPTOPP_INHERIT_ALLOCATOR_TYPES
102
103pointer allocate(size_type n, const void * = NULL)
104{
105assert(false);
106return NULL;
107}
108
109void deallocate(void *p, size_type n)
110{
111assert(false);
112}
113};
114
115// this allocator can't be used with standard collections
116template <class T, unsigned int S, class A = NullAllocator<T> >
117class FixedSizeAllocatorWithCleanup : public AllocatorBase<T>
118{
119public:
120CRYPTOPP_INHERIT_ALLOCATOR_TYPES
121
122pointer allocate(size_type n)
123{
124if (n <= S)
125{
126assert(!m_allocated);
127#ifndef NDEBUG
128m_allocated = true;
129#endif
130return m_array;
131}
132else
133return m_fallbackAllocator.allocate(n);
134}
135
136pointer allocate(size_type n, const void *hint)
137{
138if (n <= S)
139{
140assert(!m_allocated);
141#ifndef NDEBUG
142m_allocated = true;
143#endif
144return m_array;
145}
146else
147return m_fallbackAllocator.allocate(n, hint);
148}
149
150void deallocate(void *p, size_type n)
151{
152if (n <= S)
153{
154assert(m_allocated);
155assert(p == m_array);
156#ifndef NDEBUG
157m_allocated = false;
158#endif
159memset(p, 0, n*sizeof(T));
160}
161else
162m_fallbackAllocator.deallocate(p, n);
163}
164
165pointer reallocate(pointer p, size_type oldSize, size_type newSize, bool preserve)
166{
167if (oldSize <= S && newSize <= S)
168return p;
169
170return StandardReallocate(*this, p, oldSize, newSize, preserve);
171}
172
173size_type max_size() const {return m_fallbackAllocator.max_size();}
174
175private:
176A m_fallbackAllocator;
177T m_array[S];
178
179#ifndef NDEBUG
180public:
181FixedSizeAllocatorWithCleanup() : m_allocated(false) {}
182bool m_allocated;
183#endif
184};
185
186//! a block of memory allocated using A
187template <class T, class A = AllocatorWithCleanup<T> >
188class SecBlock
189{
190public:
191explicit SecBlock(unsigned int size=0)
192: m_size(size) {m_ptr = m_alloc.allocate(size, NULL);}
193SecBlock(const SecBlock<T, A> &t)
194: m_size(t.m_size) {m_ptr = m_alloc.allocate(m_size, NULL); memcpy(m_ptr, t.m_ptr, m_size*sizeof(T));}
195SecBlock(const T *t, unsigned int len)
196: m_size(len)
197{
198m_ptr = m_alloc.allocate(len, NULL);
199if (t == NULL)
200memset(m_ptr, 0, len*sizeof(T));
201else
202memcpy(m_ptr, t, len*sizeof(T));
203}
204
205~SecBlock()
206{m_alloc.deallocate(m_ptr, m_size);}
207
208#if defined(__GNUC__) || defined(__BCPLUSPLUS__)
209operator const void *() const
210{return m_ptr;}
211operator void *()
212{return m_ptr;}
213#endif
214#if defined(__GNUC__)// reduce warnings
215operator const void *()
216{return m_ptr;}
217#endif
218
219operator const T *() const
220{return m_ptr;}
221operator T *()
222{return m_ptr;}
223#if defined(__GNUC__)// reduce warnings
224operator const T *()
225{return m_ptr;}
226#endif
227
228template <typename I>
229T *operator +(I offset)
230{return m_ptr+offset;}
231
232template <typename I>
233const T *operator +(I offset) const
234{return m_ptr+offset;}
235
236template <typename I>
237T& operator[](I index)
238{assert(index >= 0 && (unsigned int)index < m_size); return m_ptr[index];}
239
240template <typename I>
241const T& operator[](I index) const
242{assert(index >= 0 && (unsigned int)index < m_size); return m_ptr[index];}
243
244typedef typename A::pointer iterator;
245typedef typename A::const_pointer const_iterator;
246typedef typename A::size_type size_type;
247
248iterator begin()
249{return m_ptr;}
250const_iterator begin() const
251{return m_ptr;}
252iterator end()
253{return m_ptr+m_size;}
254const_iterator end() const
255{return m_ptr+m_size;}
256
257typename A::pointer data() {return m_ptr;}
258typename A::const_pointer data() const {return m_ptr;}
259
260size_type size() const {return m_size;}
261bool empty() const {return m_size == 0;}
262
263void Assign(const T *t, unsigned int len)
264{
265New(len);
266memcpy(m_ptr, t, len*sizeof(T));
267}
268
269void Assign(const SecBlock<T, A> &t)
270{
271New(t.m_size);
272memcpy(m_ptr, t.m_ptr, m_size*sizeof(T));
273}
274
275SecBlock& operator=(const SecBlock<T, A> &t)
276{
277Assign(t);
278return *this;
279}
280
281bool operator==(const SecBlock<T, A> &t) const
282{
283return m_size == t.m_size && memcmp(m_ptr, t.m_ptr, m_size*sizeof(T)) == 0;
284}
285
286bool operator!=(const SecBlock<T, A> &t) const
287{
288return !operator==(t);
289}
290
291void New(unsigned int newSize)
292{
293m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, false);
294m_size = newSize;
295}
296
297void CleanNew(unsigned int newSize)
298{
299New(newSize);
300memset(m_ptr, 0, m_size*sizeof(T));
301}
302
303void Grow(unsigned int newSize)
304{
305if (newSize > m_size)
306{
307m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
308m_size = newSize;
309}
310}
311
312void CleanGrow(unsigned int newSize)
313{
314if (newSize > m_size)
315{
316m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
317memset(m_ptr+m_size, 0, (newSize-m_size)*sizeof(T));
318m_size = newSize;
319}
320}
321
322void resize(unsigned int newSize)
323{
324m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
325m_size = newSize;
326}
327
328void swap(SecBlock<T, A> &b);
329
330//private:
331A m_alloc;
332unsigned int m_size;
333T *m_ptr;
334};
335
336template <class T, class A> void SecBlock<T, A>::swap(SecBlock<T, A> &b)
337{
338std::swap(m_alloc, b.m_alloc);
339std::swap(m_size, b.m_size);
340std::swap(m_ptr, b.m_ptr);
341}
342
343typedef SecBlock<byte> SecByteBlock;
344typedef SecBlock<word> SecWordBlock;
345
346template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S> >
347class FixedSizeSecBlock : public SecBlock<T, A>
348{
349public:
350explicit FixedSizeSecBlock() : SecBlock<T, A>(S) {}
351};
352
353template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S, AllocatorWithCleanup<T> > >
354class SecBlockWithHint : public SecBlock<T, A>
355{
356public:
357explicit SecBlockWithHint(unsigned int size) : SecBlock<T, A>(size) {}
358};
359
360template<class T, class U>
361inline bool operator==(const CryptoPP::AllocatorWithCleanup<T>&, const CryptoPP::AllocatorWithCleanup<U>&) {return (true);}
362template<class T, class U>
363inline bool operator!=(const CryptoPP::AllocatorWithCleanup<T>&, const CryptoPP::AllocatorWithCleanup<U>&) {return (false);}
364
365NAMESPACE_END
366
367NAMESPACE_BEGIN(std)
368template <class T, class A>
369inline void swap(CryptoPP::SecBlock<T, A> &a, CryptoPP::SecBlock<T, A> &b)
370{
371a.swap(b);
372}
373
374#if defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES)
375template <class _Tp1, class _Tp2>
376inline CryptoPP::AllocatorWithCleanup<_Tp2>&
377__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*)
378{
379return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a);
380}
381#endif
382
383NAMESPACE_END
384
385#endif

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status