diff options
Diffstat (limited to 'src/core/secmem.h')
-rw-r--r-- | src/core/secmem.h | 217 |
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 |