summaryrefslogtreecommitdiff
path: root/secblock.h
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-04 17:31:41 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2002-10-04 17:31:41 +0000
commitb21162cf8e06f40baa1f58be6a8c17435cebc34d (patch)
tree8b045309c238226c32a563b1df6b9c30a2f0e0b3 /secblock.h
downloadcryptopp-b21162cf8e06f40baa1f58be6a8c17435cebc34d.tar.gz
Initial revision
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'secblock.h')
-rw-r--r--secblock.h376
1 files changed, 376 insertions, 0 deletions
diff --git a/secblock.h b/secblock.h
new file mode 100644
index 0000000..31997b6
--- /dev/null
+++ b/secblock.h
@@ -0,0 +1,376 @@
+// secblock.h - written and placed in the public domain by Wei Dai
+
+#ifndef CRYPTOPP_SECBLOCK_H
+#define CRYPTOPP_SECBLOCK_H
+
+#include "config.h"
+#include "misc.h"
+#include <string.h> // CodeWarrior doesn't have memory.h
+#include <assert.h>
+
+NAMESPACE_BEGIN(CryptoPP)
+
+// ************** secure memory allocation ***************
+
+template<class T>
+class AllocatorBase
+{
+public:
+ typedef T value_type;
+ typedef size_t size_type;
+#if (defined(_MSC_VER) && _MSC_VER < 1300)
+ typedef ptrdiff_t difference_type;
+#else
+ typedef std::ptrdiff_t difference_type;
+#endif
+ typedef T * pointer;
+ typedef const T * const_pointer;
+ typedef T & reference;
+ typedef const T & const_reference;
+
+ pointer address(reference r) const {return (&r);}
+ const_pointer address(const_reference r) const {return (&r); }
+ void construct(pointer p, const T& val) {new (p) T(val);}
+ void destroy(pointer p) {p->~T();}
+ size_type max_size() const {return size_type(-1)/sizeof(T);}
+};
+
+#define CRYPTOPP_INHERIT_ALLOCATOR_TYPES \
+typedef typename AllocatorBase<T>::value_type value_type;\
+typedef typename AllocatorBase<T>::size_type size_type;\
+typedef typename AllocatorBase<T>::difference_type difference_type;\
+typedef typename AllocatorBase<T>::pointer pointer;\
+typedef typename AllocatorBase<T>::const_pointer const_pointer;\
+typedef typename AllocatorBase<T>::reference reference;\
+typedef typename AllocatorBase<T>::const_reference const_reference;
+
+template <class T, class A>
+typename A::pointer StandardReallocate(A& a, T *p, typename A::size_type oldSize, typename A::size_type newSize, bool preserve)
+{
+ if (oldSize == newSize)
+ return p;
+
+ if (preserve)
+ {
+ typename A::pointer newPointer = a.allocate(newSize, NULL);
+ memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize));
+ a.deallocate(p, oldSize);
+ return newPointer;
+ }
+ else
+ {
+ a.deallocate(p, oldSize);
+ return a.allocate(newSize, NULL);
+ }
+}
+
+template <class T>
+class AllocatorWithCleanup : public AllocatorBase<T>
+{
+public:
+ CRYPTOPP_INHERIT_ALLOCATOR_TYPES
+
+ pointer allocate(size_type n, const void * = NULL)
+ {
+ if (n > 0)
+ return new T[n];
+ else
+ return NULL;
+ }
+
+ void deallocate(void *p, size_type n)
+ {
+ memset(p, 0, n*sizeof(T));
+ delete [] (T *)p;
+ }
+
+ pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve)
+ {
+ return StandardReallocate(*this, p, oldSize, newSize, preserve);
+ }
+
+ // VS.NET STL enforces the policy of "All STL-compliant allocators have to provide a
+ // template class member called rebind".
+ template <class U> struct rebind { typedef AllocatorWithCleanup<U> other; };
+};
+
+template <class T>
+class NullAllocator : public AllocatorBase<T>
+{
+public:
+ CRYPTOPP_INHERIT_ALLOCATOR_TYPES
+
+ pointer allocate(size_type n, const void * = NULL)
+ {
+ assert(false);
+ return NULL;
+ }
+
+ void deallocate(void *p, size_type n)
+ {
+ assert(false);
+ }
+};
+
+// this allocator can't be used with standard collections
+template <class T, unsigned int S, class A = NullAllocator<T> >
+class FixedSizeAllocatorWithCleanup : public AllocatorBase<T>
+{
+public:
+ CRYPTOPP_INHERIT_ALLOCATOR_TYPES
+
+ pointer allocate(size_type n)
+ {
+ if (n <= S)
+ {
+ assert(!m_allocated);
+#ifndef NDEBUG
+ m_allocated = true;
+#endif
+ return m_array;
+ }
+ else
+ return m_fallbackAllocator.allocate(n);
+ }
+
+ pointer allocate(size_type n, const void *hint)
+ {
+ if (n <= S)
+ {
+ assert(!m_allocated);
+#ifndef NDEBUG
+ m_allocated = true;
+#endif
+ return m_array;
+ }
+ else
+ return m_fallbackAllocator.allocate(n, hint);
+ }
+
+ void deallocate(void *p, size_type n)
+ {
+ if (n <= S)
+ {
+ assert(m_allocated);
+ assert(p == m_array);
+#ifndef NDEBUG
+ m_allocated = false;
+#endif
+ memset(p, 0, n*sizeof(T));
+ }
+ else
+ m_fallbackAllocator.deallocate(p, n);
+ }
+
+ pointer reallocate(pointer p, size_type oldSize, size_type newSize, bool preserve)
+ {
+ if (oldSize <= S && newSize <= S)
+ return p;
+
+ return StandardReallocate(*this, p, oldSize, newSize, preserve);
+ }
+
+ size_type max_size() const {return m_fallbackAllocator.max_size();}
+
+private:
+ A m_fallbackAllocator;
+ T m_array[S];
+
+#ifndef NDEBUG
+public:
+ FixedSizeAllocatorWithCleanup() : m_allocated(false) {}
+ bool m_allocated;
+#endif
+};
+
+//! a block of memory allocated using A
+template <class T, class A = AllocatorWithCleanup<T> >
+class SecBlock
+{
+public:
+ explicit SecBlock(unsigned int size=0)
+ : m_size(size) {m_ptr = m_alloc.allocate(size, NULL);}
+ SecBlock(const SecBlock<T, A> &t)
+ : m_size(t.m_size) {m_ptr = m_alloc.allocate(m_size, NULL); memcpy(m_ptr, t.m_ptr, m_size*sizeof(T));}
+ SecBlock(const T *t, unsigned int len)
+ : m_size(len)
+ {
+ m_ptr = m_alloc.allocate(len, NULL);
+ if (t == NULL)
+ memset(m_ptr, 0, len*sizeof(T));
+ else
+ memcpy(m_ptr, t, len*sizeof(T));
+ }
+
+ ~SecBlock()
+ {m_alloc.deallocate(m_ptr, m_size);}
+
+#if defined(__GNUC__) || defined(__BCPLUSPLUS__)
+ operator const void *() const
+ {return m_ptr;}
+ operator void *()
+ {return m_ptr;}
+#endif
+#if defined(__GNUC__) // reduce warnings
+ operator const void *()
+ {return m_ptr;}
+#endif
+
+ operator const T *() const
+ {return m_ptr;}
+ operator T *()
+ {return m_ptr;}
+#if defined(__GNUC__) // reduce warnings
+ operator const T *()
+ {return m_ptr;}
+#endif
+
+ template <typename I>
+ T *operator +(I offset)
+ {return m_ptr+offset;}
+
+ template <typename I>
+ const T *operator +(I offset) const
+ {return m_ptr+offset;}
+
+ template <typename I>
+ T& operator[](I index)
+ {assert(index >= 0 && (unsigned int)index < m_size); return m_ptr[index];}
+
+ template <typename I>
+ const T& operator[](I index) const
+ {assert(index >= 0 && (unsigned int)index < m_size); return m_ptr[index];}
+
+ typedef typename A::pointer iterator;
+ typedef typename A::const_pointer const_iterator;
+ typedef typename A::size_type size_type;
+
+ iterator begin()
+ {return m_ptr;}
+ const_iterator begin() const
+ {return m_ptr;}
+ iterator end()
+ {return m_ptr+m_size;}
+ const_iterator end() const
+ {return m_ptr+m_size;}
+
+ typename A::pointer data() {return m_ptr;}
+ typename A::const_pointer data() const {return m_ptr;}
+
+ size_type size() const {return m_size;}
+ bool empty() const {return m_size == 0;}
+
+ void Assign(const T *t, unsigned int len)
+ {
+ New(len);
+ memcpy(m_ptr, t, len*sizeof(T));
+ }
+
+ void Assign(const SecBlock<T, A> &t)
+ {
+ New(t.m_size);
+ memcpy(m_ptr, t.m_ptr, m_size*sizeof(T));
+ }
+
+ SecBlock& operator=(const SecBlock<T, A> &t)
+ {
+ Assign(t);
+ return *this;
+ }
+
+ bool operator==(const SecBlock<T, A> &t) const
+ {
+ return m_size == t.m_size && memcmp(m_ptr, t.m_ptr, m_size*sizeof(T)) == 0;
+ }
+
+ bool operator!=(const SecBlock<T, A> &t) const
+ {
+ return !operator==(t);
+ }
+
+ void New(unsigned int newSize)
+ {
+ m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, false);
+ m_size = newSize;
+ }
+
+ void CleanNew(unsigned int newSize)
+ {
+ New(newSize);
+ memset(m_ptr, 0, m_size*sizeof(T));
+ }
+
+ void Grow(unsigned int newSize)
+ {
+ if (newSize > m_size)
+ {
+ m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
+ m_size = newSize;
+ }
+ }
+
+ void CleanGrow(unsigned int newSize)
+ {
+ if (newSize > m_size)
+ {
+ m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
+ memset(m_ptr+m_size, 0, (newSize-m_size)*sizeof(T));
+ m_size = newSize;
+ }
+ }
+
+ void resize(unsigned int newSize)
+ {
+ m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true);
+ m_size = newSize;
+ }
+
+ void swap(SecBlock<T, A> &b);
+
+//private:
+ A m_alloc;
+ unsigned int m_size;
+ T *m_ptr;
+};
+
+template <class T, class A> void SecBlock<T, A>::swap(SecBlock<T, A> &b)
+{
+ std::swap(m_alloc, b.m_alloc);
+ std::swap(m_size, b.m_size);
+ std::swap(m_ptr, b.m_ptr);
+}
+
+typedef SecBlock<byte> SecByteBlock;
+typedef SecBlock<word> SecWordBlock;
+
+template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S> >
+class FixedSizeSecBlock : public SecBlock<T, A>
+{
+public:
+ explicit FixedSizeSecBlock() : SecBlock<T, A>(S) {}
+};
+
+template <class T, unsigned int S, class A = FixedSizeAllocatorWithCleanup<T, S, AllocatorWithCleanup<T> > >
+class SecBlockWithHint : public SecBlock<T, A>
+{
+public:
+ explicit SecBlockWithHint(unsigned int size) : SecBlock<T, A>(size) {}
+};
+
+template<class T, class U>
+inline bool operator==(const CryptoPP::AllocatorWithCleanup<T>&, const CryptoPP::AllocatorWithCleanup<U>&) {return (true);}
+template<class T, class U>
+inline bool operator!=(const CryptoPP::AllocatorWithCleanup<T>&, const CryptoPP::AllocatorWithCleanup<U>&) {return (false);}
+
+NAMESPACE_END
+
+NAMESPACE_BEGIN(std)
+template <class T, class A>
+inline void swap(CryptoPP::SecBlock<T, A> &a, CryptoPP::SecBlock<T, A> &b)
+{
+ a.swap(b);
+}
+
+NAMESPACE_END
+
+#endif