aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/secmem.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/secmem.h')
-rw-r--r--src/core/secmem.h217
1 files changed, 217 insertions, 0 deletions
diff --git a/src/core/secmem.h b/src/core/secmem.h
new file mode 100644
index 000000000..37adf7f42
--- /dev/null
+++ b/src/core/secmem.h
@@ -0,0 +1,217 @@
+/*************************************************
+* Secure Memory Buffers Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__
+#define BOTAN_SECURE_MEMORY_BUFFERS_H__
+
+#include <botan/allocate.h>
+#include <botan/mem_ops.h>
+
+namespace Botan {
+
+/*************************************************
+* Variable Length Memory Buffer *
+*************************************************/
+template<typename T>
+class MemoryRegion
+ {
+ public:
+ u32bit size() const { return used; }
+ u32bit is_empty() const { return (used == 0); }
+ u32bit has_items() const { return (used != 0); }
+
+ operator T* () { return buf; }
+ operator const T* () const { return buf; }
+
+ T* begin() { return buf; }
+ const T* begin() const { return buf; }
+
+ T* end() { return (buf + size()); }
+ const T* end() const { return (buf + size()); }
+
+ bool operator==(const MemoryRegion<T>& other) const
+ {
+ return (size() == other.size() &&
+ same_mem(buf, other.buf, size()));
+ }
+
+ bool operator<(const MemoryRegion<T>&) const;
+
+ bool operator!=(const MemoryRegion<T>& in) const
+ { return (!(*this == in)); }
+ MemoryRegion<T>& operator=(const MemoryRegion<T>& in)
+ { if(this != &in) set(in); return (*this); }
+
+ void copy(const T in[], u32bit n)
+ { copy(0, in, n); }
+ void copy(u32bit off, const T in[], u32bit n)
+ { copy_mem(buf + off, in, (n > size() - off) ? (size() - off) : n); }
+
+ void set(const T in[], u32bit n) { create(n); copy(in, n); }
+ void set(const MemoryRegion<T>& in) { set(in.begin(), in.size()); }
+
+ void append(const T data[], u32bit n)
+ { grow_to(size()+n); copy(size() - n, data, n); }
+ void append(T x) { append(&x, 1); }
+ void append(const MemoryRegion<T>& x) { append(x.begin(), x.size()); }
+
+ void clear() { clear_mem(buf, allocated); }
+ void destroy() { create(0); }
+
+ void create(u32bit);
+ void grow_to(u32bit);
+ void swap(MemoryRegion<T>&);
+
+ ~MemoryRegion() { deallocate(buf, allocated); }
+ protected:
+ MemoryRegion() { buf = 0; alloc = 0; used = allocated = 0; }
+ MemoryRegion(const MemoryRegion<T>& other)
+ {
+ buf = 0;
+ used = allocated = 0;
+ alloc = other.alloc;
+ set(other.buf, other.used);
+ }
+
+ void init(bool locking, u32bit length = 0)
+ { alloc = Allocator::get(locking); create(length); }
+ private:
+ T* allocate(u32bit n)
+ {
+ return static_cast<T*>(alloc->allocate(sizeof(T)*n));
+ }
+
+ void deallocate(T* p, u32bit n)
+ { alloc->deallocate(p, sizeof(T)*n); }
+
+ T* buf;
+ u32bit used;
+ u32bit allocated;
+ Allocator* alloc;
+ };
+
+/*************************************************
+* Create a new buffer *
+*************************************************/
+template<typename T>
+void MemoryRegion<T>::create(u32bit n)
+ {
+ if(n <= allocated) { clear(); used = n; return; }
+ deallocate(buf, allocated);
+ buf = allocate(n);
+ allocated = used = n;
+ }
+
+/*************************************************
+* Increase the size of the buffer *
+*************************************************/
+template<typename T>
+void MemoryRegion<T>::grow_to(u32bit n)
+ {
+ if(n > used && n <= allocated)
+ {
+ clear_mem(buf + used, n - used);
+ used = n;
+ return;
+ }
+ else if(n > allocated)
+ {
+ T* new_buf = allocate(n);
+ copy_mem(new_buf, buf, used);
+ deallocate(buf, allocated);
+ buf = new_buf;
+ allocated = used = n;
+ }
+ }
+
+/*************************************************
+* Compare this buffer with another one *
+*************************************************/
+template<typename T>
+bool MemoryRegion<T>::operator<(const MemoryRegion<T>& in) const
+ {
+ if(size() < in.size()) return true;
+ if(size() > in.size()) return false;
+
+ for(u32bit j = 0; j != size(); j++)
+ {
+ if(buf[j] < in[j]) return true;
+ if(buf[j] > in[j]) return false;
+ }
+
+ return false;
+ }
+
+/*************************************************
+* Swap this buffer with another one *
+*************************************************/
+template<typename T>
+void MemoryRegion<T>::swap(MemoryRegion<T>& x)
+ {
+ std::swap(buf, x.buf);
+ std::swap(used, x.used);
+ std::swap(allocated, x.allocated);
+ std::swap(alloc, x.alloc);
+ }
+
+/*************************************************
+* Unlocked Variable Length Buffer *
+*************************************************/
+template<typename T>
+class MemoryVector : public MemoryRegion<T>
+ {
+ public:
+ MemoryVector<T>& operator=(const MemoryRegion<T>& in)
+ { if(this != &in) set(in); return (*this); }
+
+ MemoryVector(u32bit n = 0) { MemoryRegion<T>::init(false, n); }
+ MemoryVector(const T in[], u32bit n)
+ { MemoryRegion<T>::init(false); set(in, n); }
+ MemoryVector(const MemoryRegion<T>& in)
+ { MemoryRegion<T>::init(false); set(in); }
+ MemoryVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
+ { MemoryRegion<T>::init(false); set(in1); append(in2); }
+ };
+
+/*************************************************
+* Locked Variable Length Buffer *
+*************************************************/
+template<typename T>
+class SecureVector : public MemoryRegion<T>
+ {
+ public:
+ SecureVector<T>& operator=(const MemoryRegion<T>& in)
+ { if(this != &in) set(in); return (*this); }
+
+ SecureVector(u32bit n = 0) { MemoryRegion<T>::init(true, n); }
+ SecureVector(const T in[], u32bit n)
+ { MemoryRegion<T>::init(true); set(in, n); }
+ SecureVector(const MemoryRegion<T>& in)
+ { MemoryRegion<T>::init(true); set(in); }
+ SecureVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
+ { MemoryRegion<T>::init(true); set(in1); append(in2); }
+ };
+
+/*************************************************
+* Locked Fixed Length Buffer *
+*************************************************/
+template<typename T, u32bit L>
+class SecureBuffer : public MemoryRegion<T>
+ {
+ public:
+ SecureBuffer<T,L>& operator=(const SecureBuffer<T,L>& in)
+ { if(this != &in) set(in); return (*this); }
+
+ SecureBuffer() { MemoryRegion<T>::init(true, L); }
+ SecureBuffer(const T in[], u32bit n)
+ { MemoryRegion<T>::init(true, L); copy(in, n); }
+ private:
+ SecureBuffer<T, L>& operator=(const MemoryRegion<T>& in)
+ { if(this != &in) set(in); return (*this); }
+ };
+
+}
+
+#endif