diff options
author | lloyd <[email protected]> | 2012-05-18 20:32:36 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-05-18 20:32:36 +0000 |
commit | c691561f3198f481c13457433efbccc1c9fcd898 (patch) | |
tree | a45ea2c5a30e0cb009fbcb68a61ef39332ff790c /src/alloc | |
parent | d76700f01c7ecac5633edf75f8d7408b46c5dbac (diff) |
Fairly huge update that replaces the old secmem types with std::vector
using a custom allocator. Currently our allocator just does new/delete
with a memset before deletion, and the mmap and mlock allocators have
been removed.
Diffstat (limited to 'src/alloc')
-rw-r--r-- | src/alloc/alloc_mmap/info.txt | 28 | ||||
-rw-r--r-- | src/alloc/alloc_mmap/mmap_mem.cpp | 145 | ||||
-rw-r--r-- | src/alloc/alloc_mmap/mmap_mem.h | 32 | ||||
-rw-r--r-- | src/alloc/allocate.h | 65 | ||||
-rw-r--r-- | src/alloc/info.txt | 1 | ||||
-rw-r--r-- | src/alloc/mem_pool/info.txt | 8 | ||||
-rw-r--r-- | src/alloc/mem_pool/mem_pool.cpp | 251 | ||||
-rw-r--r-- | src/alloc/mem_pool/mem_pool.h | 74 | ||||
-rw-r--r-- | src/alloc/secmem.h | 411 | ||||
-rw-r--r-- | src/alloc/system_alloc/defalloc.cpp | 103 | ||||
-rw-r--r-- | src/alloc/system_alloc/defalloc.h | 41 | ||||
-rw-r--r-- | src/alloc/system_alloc/info.txt | 13 |
12 files changed, 63 insertions, 1109 deletions
diff --git a/src/alloc/alloc_mmap/info.txt b/src/alloc/alloc_mmap/info.txt deleted file mode 100644 index 562277a37..000000000 --- a/src/alloc/alloc_mmap/info.txt +++ /dev/null @@ -1,28 +0,0 @@ -define ALLOC_MMAP - -<source> -mmap_mem.cpp -</source> - -<header:internal> -mmap_mem.h -</header:internal> - -<os> -linux -freebsd -dragonfly -openbsd -netbsd -solaris -qnx -darwin -tru64 - -# Only without -ansi, otherwise can't get mkstemp -#cygwin -</os> - -<requires> -mem_pool -</requires> diff --git a/src/alloc/alloc_mmap/mmap_mem.cpp b/src/alloc/alloc_mmap/mmap_mem.cpp deleted file mode 100644 index b90b6d5f7..000000000 --- a/src/alloc/alloc_mmap/mmap_mem.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* -* Memory Mapping Allocator -* (C) 1999-2010 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/mmap_mem.h> -#include <vector> -#include <cstring> - -#include <sys/types.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <unistd.h> -#include <stdlib.h> -#include <fcntl.h> -#include <errno.h> - -#ifndef MAP_FAILED - #define MAP_FAILED -1 -#endif - -namespace Botan { - -namespace { - -/* -* MemoryMapping_Allocator Exception -*/ -class BOTAN_DLL MemoryMapping_Failed : public Exception - { - public: - MemoryMapping_Failed(const std::string& msg) : - Exception("MemoryMapping_Allocator: " + msg) {} - }; - -} - -/* -* Memory Map a File into Memory -*/ -void* MemoryMapping_Allocator::alloc_block(size_t n) - { - class TemporaryFile - { - public: - int get_fd() const { return fd; } - - TemporaryFile(const std::string& base) - { - const std::string mkstemp_template = base + "XXXXXX"; - - std::vector<char> filepath(mkstemp_template.begin(), - mkstemp_template.end()); - filepath.push_back(0); // add terminating NULL - - mode_t old_umask = ::umask(077); - fd = ::mkstemp(&filepath[0]); - ::umask(old_umask); - - if(fd == -1) - throw MemoryMapping_Failed("Temporary file allocation failed"); - - if(::unlink(&filepath[0]) != 0) - throw MemoryMapping_Failed("Could not unlink temporary file"); - } - - ~TemporaryFile() - { - /* - * We can safely close here, because post-mmap the file - * will continue to exist until the mmap is unmapped from - * our address space upon deallocation (or process exit). - */ - if(fd != -1 && ::close(fd) == -1) - throw MemoryMapping_Failed("Could not close file"); - } - private: - int fd; - }; - - TemporaryFile file("/tmp/botan_"); - - if(file.get_fd() == -1) - throw MemoryMapping_Failed("Could not create file"); - - std::vector<byte> zeros(4096); - - size_t remaining = n; - - while(remaining) - { - const size_t write_try = std::min(zeros.size(), remaining); - - ssize_t wrote_got = ::write(file.get_fd(), - &zeros[0], - write_try); - - if(wrote_got == -1 && errno != EINTR) - throw MemoryMapping_Failed("Could not write to file"); - - remaining -= wrote_got; - } - -#ifndef MAP_NOSYNC - #define MAP_NOSYNC 0 -#endif - - void* ptr = ::mmap(0, n, - PROT_READ | PROT_WRITE, - MAP_SHARED | MAP_NOSYNC, - file.get_fd(), 0); - - if(ptr == static_cast<void*>(MAP_FAILED)) - throw MemoryMapping_Failed("Could not map file"); - - return ptr; - } - -/* -* Remove a Memory Mapping -*/ -void MemoryMapping_Allocator::dealloc_block(void* ptr, size_t n) - { - if(ptr == nullptr) - return; - - const byte PATTERNS[] = { 0x00, 0xF5, 0x5A, 0xAF, 0x00 }; - - // The char* casts are for Solaris, args are void* on most other systems - - for(size_t i = 0; i != sizeof(PATTERNS); ++i) - { - std::memset(ptr, PATTERNS[i], n); - - if(::msync(static_cast<char*>(ptr), n, MS_SYNC)) - throw MemoryMapping_Failed("Sync operation failed"); - } - - if(::munmap(static_cast<char*>(ptr), n)) - throw MemoryMapping_Failed("Could not unmap file"); - } - -} diff --git a/src/alloc/alloc_mmap/mmap_mem.h b/src/alloc/alloc_mmap/mmap_mem.h deleted file mode 100644 index c9983ed23..000000000 --- a/src/alloc/alloc_mmap/mmap_mem.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* Memory Mapping Allocator -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_MMAP_ALLOCATOR_H__ -#define BOTAN_MMAP_ALLOCATOR_H__ - -#include <botan/internal/mem_pool.h> - -namespace Botan { - -/** -* Allocator that uses memory maps backed by disk. We zeroize the map -* upon deallocation. If swap occurs, the VM will swap to the shared -* file backing rather than to a swap device, which means we know where -* it is and can zap it later. -*/ -class MemoryMapping_Allocator : public Pooling_Allocator - { - public: - std::string type() const { return "mmap"; } - private: - void* alloc_block(size_t); - void dealloc_block(void*, size_t); - }; - -} - -#endif diff --git a/src/alloc/allocate.h b/src/alloc/allocate.h deleted file mode 100644 index b8574be1e..000000000 --- a/src/alloc/allocate.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -* Allocator -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_ALLOCATOR_H__ -#define BOTAN_ALLOCATOR_H__ - -#include <botan/types.h> -#include <string> - -namespace Botan { - -/** -* Allocator Interface -*/ -class BOTAN_DLL Allocator - { - public: - /** - * Acquire a pointer to an allocator - * @param locking is true if the allocator should attempt to - * secure the memory (eg for using to store keys) - * @return pointer to an allocator; ownership remains with library, - * so do not delete - */ - static Allocator* get(bool locking); - - /** - * Allocate a block of memory - * @param n how many bytes to allocate - * @return pointer to n bytes of memory - */ - virtual void* allocate(size_t n) = 0; - - /** - * Deallocate memory allocated with allocate() - * @param ptr the pointer returned by allocate() - * @param n the size of the block pointed to by ptr - */ - virtual void deallocate(void* ptr, size_t n) = 0; - - /** - * @return name of this allocator type - */ - virtual std::string type() const = 0; - - /** - * Initialize the allocator - */ - virtual void init() {} - - /** - * Shutdown the allocator - */ - virtual void destroy() {} - - virtual ~Allocator() {} - }; - -} - -#endif diff --git a/src/alloc/info.txt b/src/alloc/info.txt index 40e7bacdf..0ab7fa768 100644 --- a/src/alloc/info.txt +++ b/src/alloc/info.txt @@ -1,4 +1,3 @@ <header:public> -allocate.h secmem.h </header:public> diff --git a/src/alloc/mem_pool/info.txt b/src/alloc/mem_pool/info.txt deleted file mode 100644 index f87ea4c4c..000000000 --- a/src/alloc/mem_pool/info.txt +++ /dev/null @@ -1,8 +0,0 @@ - -<source> -mem_pool.cpp -</source> - -<header:internal> -mem_pool.h -</header:internal> diff --git a/src/alloc/mem_pool/mem_pool.cpp b/src/alloc/mem_pool/mem_pool.cpp deleted file mode 100644 index 770622149..000000000 --- a/src/alloc/mem_pool/mem_pool.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/* -* Pooling Allocator -* (C) 1999-2008 Jack Lloyd -* 2005 Matthew Gregan -* 2005-2006 Matt Johnston -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/mem_pool.h> -#include <botan/internal/rounding.h> -#include <botan/mem_ops.h> -#include <algorithm> -#include <exception> - -namespace Botan { - -/* -* Memory_Block Constructor -*/ -Pooling_Allocator::Memory_Block::Memory_Block(void* buf) - { - buffer = static_cast<byte*>(buf); - bitmap = 0; - buffer_end = buffer + (BLOCK_SIZE * BITMAP_SIZE); - } - -/* -* See if ptr is contained by this block -*/ -bool Pooling_Allocator::Memory_Block::contains(void* ptr, - size_t length) const - { - return ((buffer <= ptr) && - (buffer_end >= static_cast<byte*>(ptr) + length * BLOCK_SIZE)); - } - -/* -* Allocate some memory, if possible -*/ -byte* Pooling_Allocator::Memory_Block::alloc(size_t n) - { - if(n == 0 || n > BITMAP_SIZE) - return 0; - - if(n == BITMAP_SIZE) - { - if(bitmap) - return nullptr; - else - { - bitmap = ~bitmap; - return buffer; - } - } - - bitmap_type mask = (static_cast<bitmap_type>(1) << n) - 1; - size_t offset = 0; - - while(bitmap & mask) - { - mask <<= 1; - ++offset; - - if((bitmap & mask) == 0) - break; - if(mask >> 63) - break; - } - - if(bitmap & mask) - return nullptr; - - bitmap |= mask; - return buffer + offset * BLOCK_SIZE; - } - -/* -* Mark this memory as free, if we own it -*/ -void Pooling_Allocator::Memory_Block::free(void* ptr, size_t blocks) - { - clear_mem(static_cast<byte*>(ptr), blocks * BLOCK_SIZE); - - const size_t offset = (static_cast<byte*>(ptr) - buffer) / BLOCK_SIZE; - - if(offset == 0 && blocks == BITMAP_SIZE) - bitmap = ~bitmap; - else - { - for(size_t j = 0; j != blocks; ++j) - bitmap &= ~(static_cast<bitmap_type>(1) << (j+offset)); - } - } - -/* -* Pooling_Allocator Constructor -*/ -Pooling_Allocator::Pooling_Allocator() - { - last_used = blocks.begin(); - } - -/* -* Pooling_Allocator Destructor -*/ -Pooling_Allocator::~Pooling_Allocator() - { - if(blocks.size()) - throw Invalid_State("Pooling_Allocator: Never released memory"); - } - -/* -* Free all remaining memory -*/ -void Pooling_Allocator::destroy() - { - std::lock_guard<std::mutex> lock(mutex); - - blocks.clear(); - - for(size_t j = 0; j != allocated.size(); ++j) - dealloc_block(allocated[j].first, allocated[j].second); - allocated.clear(); - } - -/* -* Allocation -*/ -void* Pooling_Allocator::allocate(size_t n) - { - const size_t BITMAP_SIZE = Memory_Block::bitmap_size(); - const size_t BLOCK_SIZE = Memory_Block::block_size(); - - std::lock_guard<std::mutex> lock(mutex); - - if(n <= BITMAP_SIZE * BLOCK_SIZE) - { - const size_t block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE; - - byte* mem = allocate_blocks(block_no); - if(mem) - return mem; - - get_more_core(BOTAN_MEM_POOL_CHUNK_SIZE); - - mem = allocate_blocks(block_no); - if(mem) - return mem; - - throw Memory_Exhaustion(); - } - - void* new_buf = alloc_block(n); - if(new_buf) - return new_buf; - - throw Memory_Exhaustion(); - } - -/* -* Deallocation -*/ -void Pooling_Allocator::deallocate(void* ptr, size_t n) - { - const size_t BITMAP_SIZE = Memory_Block::bitmap_size(); - const size_t BLOCK_SIZE = Memory_Block::block_size(); - - if(ptr == nullptr && n == 0) - return; - - std::lock_guard<std::mutex> lock(mutex); - - if(n > BITMAP_SIZE * BLOCK_SIZE) - dealloc_block(ptr, n); - else - { - const size_t block_no = round_up(n, BLOCK_SIZE) / BLOCK_SIZE; - - auto i = std::lower_bound(blocks.begin(), blocks.end(), - Memory_Block(ptr)); - - if(i == blocks.end() || !i->contains(ptr, block_no)) - throw Invalid_State("Pointer released to the wrong allocator"); - - i->free(ptr, block_no); - } - } - -/* -* Try to get some memory from an existing block -*/ -byte* Pooling_Allocator::allocate_blocks(size_t n) - { - if(blocks.empty()) - return nullptr; - - auto i = last_used; - - do - { - byte* mem = i->alloc(n); - if(mem) - { - last_used = i; - return mem; - } - - ++i; - if(i == blocks.end()) - i = blocks.begin(); - } - while(i != last_used); - - return nullptr; - } - -/* -* Allocate more memory for the pool -*/ -void Pooling_Allocator::get_more_core(size_t in_bytes) - { - const size_t BITMAP_SIZE = Memory_Block::bitmap_size(); - const size_t BLOCK_SIZE = Memory_Block::block_size(); - - const size_t TOTAL_BLOCK_SIZE = BLOCK_SIZE * BITMAP_SIZE; - - // upper bound on allocation is 1 MiB - in_bytes = std::min<size_t>(in_bytes, 1024 * 1024); - - const size_t in_blocks = round_up(in_bytes, BLOCK_SIZE) / TOTAL_BLOCK_SIZE; - const size_t to_allocate = in_blocks * TOTAL_BLOCK_SIZE; - - void* ptr = alloc_block(to_allocate); - if(ptr == nullptr) - throw Memory_Exhaustion(); - - allocated.push_back(std::make_pair(ptr, to_allocate)); - - for(size_t j = 0; j != in_blocks; ++j) - { - byte* byte_ptr = static_cast<byte*>(ptr); - blocks.push_back(Memory_Block(byte_ptr + j * TOTAL_BLOCK_SIZE)); - } - - std::sort(blocks.begin(), blocks.end()); - last_used = std::lower_bound(blocks.begin(), blocks.end(), - Memory_Block(ptr)); - } - -} diff --git a/src/alloc/mem_pool/mem_pool.h b/src/alloc/mem_pool/mem_pool.h deleted file mode 100644 index f2225e573..000000000 --- a/src/alloc/mem_pool/mem_pool.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* Pooling Allocator -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_POOLING_ALLOCATOR_H__ -#define BOTAN_POOLING_ALLOCATOR_H__ - -#include <botan/allocate.h> -#include <botan/exceptn.h> -#include <mutex> -#include <utility> -#include <vector> - -namespace Botan { - -/** -* Pooling Allocator -*/ -class Pooling_Allocator : public Allocator - { - public: - void* allocate(size_t); - void deallocate(void*, size_t); - - void destroy(); - - Pooling_Allocator(); - ~Pooling_Allocator(); - private: - void get_more_core(size_t); - byte* allocate_blocks(size_t); - - virtual void* alloc_block(size_t) = 0; - virtual void dealloc_block(void*, size_t) = 0; - - class Memory_Block - { - public: - Memory_Block(void*); - - static size_t bitmap_size() { return BITMAP_SIZE; } - static size_t block_size() { return BLOCK_SIZE; } - - bool contains(void*, size_t) const; - byte* alloc(size_t); - void free(void*, size_t); - - bool operator<(const Memory_Block& other) const - { - if(buffer < other.buffer && other.buffer < buffer_end) - return false; - return (buffer < other.buffer); - } - private: - typedef u64bit bitmap_type; - static const size_t BITMAP_SIZE = 8 * sizeof(bitmap_type); - static const size_t BLOCK_SIZE = 64; - - bitmap_type bitmap; - byte* buffer, *buffer_end; - }; - - std::vector<Memory_Block> blocks; - std::vector<Memory_Block>::iterator last_used; - std::vector<std::pair<void*, size_t> > allocated; - std::mutex mutex; - }; - -} - -#endif diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h index e6b2b71ec..7c27c8d3b 100644 --- a/src/alloc/secmem.h +++ b/src/alloc/secmem.h @@ -1,6 +1,6 @@ /* * Secure Memory Buffers -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2007,2012 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -8,362 +8,87 @@ #ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__ #define BOTAN_SECURE_MEMORY_BUFFERS_H__ -#include <botan/allocate.h> #include <botan/mem_ops.h> #include <algorithm> +extern void note_alloc(int n); + namespace Botan { -/** -* This class represents variable length memory buffers. -*/ template<typename T> -class MemoryRegion +class secure_allocator { public: - /** - * Find out the size of the buffer, i.e. how many objects of type T it - * contains. - * @return size of the buffer - */ - size_t size() const { return used; } - - /** - * Find out whether this buffer is empty. - * @return true if the buffer is empty, false otherwise - */ - bool empty() const { return (used == 0); } - - /** - * Get a pointer to the first element in the buffer. - * @return pointer to the first element in the buffer - */ - operator T* () { return buf; } + typedef T value_type; - /** - * Get a constant pointer to the first element in the buffer. - * @return constant pointer to the first element in the buffer - */ - operator const T* () const { return buf; } + typedef T* pointer; + typedef const T* const_pointer; - /** - * Get a pointer to the first element in the buffer. - * @return pointer to the first element in the buffer - */ - T* begin() { return buf; } - - /** - * Get a constant pointer to the first element in the buffer. - * @return constant pointer to the first element in the buffer - */ - const T* begin() const { return buf; } - - /** - * Get a pointer to one past the last element in the buffer. - * @return pointer to one past the last element in the buffer - */ - T* end() { return (buf + size()); } - - /** - * Get a const pointer to one past the last element in the buffer. - * @return const pointer to one past the last element in the buffer - */ - const T* end() const { return (buf + size()); } - - /** - * Check two buffers for equality. - * @return true iff the content of both buffers is byte-wise equal - */ - bool operator==(const MemoryRegion<T>& other) const - { - return (size() == other.size() && - same_mem(buf, other.buf, size())); - } + typedef T& reference; + typedef const T& const_reference; - /** - * Compare two buffers - * @return true iff this is ordered before other - */ - bool operator<(const MemoryRegion<T>& other) const; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; - /** - * Check two buffers for inequality. - * @return false if the content of both buffers is byte-wise equal, true - * otherwise. - */ - bool operator!=(const MemoryRegion<T>& other) const - { return (!(*this == other)); } + secure_allocator() noexcept {} - /** - * Copy the contents of another buffer into this buffer. - * The former contents of *this are discarded. - * @param other the buffer to copy the contents from. - * @return reference to *this - */ - MemoryRegion<T>& operator=(const MemoryRegion<T>& other) - { - if(this != &other) - { - this->resize(other.size()); - this->copy(&other[0], other.size()); - } - return (*this); - } + ~secure_allocator() noexcept {} - /** - * Copy the contents of an array of objects of type T into this buffer. - * The former contents of *this are discarded. - * The length of *this must be at least n, otherwise memory errors occur. - * @param in the array to copy the contents from - * @param n the length of in - */ + pointer address(reference x) const noexcept + { return std::addressof(x); } - void copy(const T in[], size_t n) - { - copy_mem(buf, in, std::min(n, size())); - } + const_pointer address(const_reference x) const noexcept + { return std::addressof(x); } - void assign(const T* start, const T* end) + pointer allocate(size_type n, const void* = 0) { - resize(end - start); - copy_mem(buf, start, (end - start)); + pointer p = new T[n]; + clear_mem(p, n); + note_alloc(sizeof(T)*n); + return p; } - /** - * Append a single element. - * @param x the element to append - */ - void push_back(T x) + void deallocate(pointer p, size_type n) { - resize(size() + 1); - buf[size()-1] = x; + clear_mem(p, n); + delete [] p; + note_alloc(-(int(n)*sizeof(T))); } - /** - * Reset this buffer to an empty buffer with size zero. - */ - void clear() { resize(0); } - - /** - * Inserts or erases elements at the end such that the size - * becomes n, leaving elements in the range 0...n unmodified if - * set or otherwise zero-initialized - * @param n length of the new buffer - */ - void resize(size_t n); - - /** - * Swap this buffer with another object. - */ - void swap(MemoryRegion<T>& other); - - virtual ~MemoryRegion() { deallocate(buf, allocated); } - protected: - MemoryRegion() : buf(0), used(0), allocated(0), alloc(0) {} - - /** - * Copy constructor - * @param other the other region to copy - */ - MemoryRegion(const MemoryRegion<T>& other) : - buf(0), - used(0), - allocated(0), - alloc(other.alloc) + size_type max_size() const noexcept { - resize(other.size()); - copy(&other[0], other.size()); + return static_cast<size_type>(-1) / sizeof(T); } - /** - * @param locking should we use a locking allocator - * @param length the initial length to use - */ - void init(bool locking, size_t length = 0) - { alloc = Allocator::get(locking); resize(length); } - - private: - T* allocate(size_t n) - { - return static_cast<T*>(alloc->allocate(sizeof(T)*n)); - } + template<typename U, typename... Args> + void + construct(U* p, Args&&... args) + { ::new((void *)p) U(std::forward<Args>(args)...); } - void deallocate(T* p, size_t n) - { if(alloc && p && n) alloc->deallocate(p, sizeof(T)*n); } + template<typename U> void destroy(U* p) { p->~U(); } - T* buf; - size_t used; - size_t allocated; - Allocator* alloc; }; -/* -* Change the size of the buffer -*/ -template<typename T> -void MemoryRegion<T>::resize(size_t n) - { - if(n <= allocated) - { - size_t zap = std::min(used, n); - clear_mem(buf + zap, allocated - zap); - used = n; - } - else - { - 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>& other) const - { - const size_t min_size = std::min(size(), other.size()); +template<typename T> inline bool +operator==(const secure_allocator<T>&, const secure_allocator<T>&) + { return true; } - // This should probably be rewritten to run in constant time - for(size_t i = 0; i != min_size; ++i) - { - if(buf[i] < other[i]) - return true; - if(buf[i] > other[i]) - return false; - } +template<typename T> inline bool +operator!=(const secure_allocator<T>&, const secure_allocator<T>&) + { return false; } - // First min_size bytes are equal, shorter is first - return (size() < other.size()); - } +template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>; -/* -* Swap this buffer with another one -*/ template<typename T> -void MemoryRegion<T>::swap(MemoryRegion<T>& x) +std::vector<T> unlock(const secure_vector<T>& in) { - std::swap(buf, x.buf); - std::swap(used, x.used); - std::swap(allocated, x.allocated); - std::swap(alloc, x.alloc); + std::vector<T> out(in.size()); + copy_mem(&out[0], &in[0], in.size()); + return out; } -/** -* This class represents variable length buffers that do not -* make use of memory locking. -*/ -template<typename T> -class MemoryVector : public MemoryRegion<T> - { - public: - /** - * Copy the contents of another buffer into this buffer. - * @param in the buffer to copy the contents from - * @return reference to *this - */ - MemoryVector<T>& operator=(const MemoryRegion<T>& in) - { - if(this != &in) - { - this->resize(in.size()); - this->copy(&in[0], in.size()); - } - return (*this); - } - - /** - * Create a buffer of the specified length. - * @param n the length of the buffer to create. - */ - MemoryVector(size_t n = 0) { this->init(false, n); } - - /** - * Create a buffer with the specified contents. - * @param in the array containing the data to be initially copied - * into the newly created buffer - * @param n the size of the arry in - */ - MemoryVector(const T in[], size_t n) - { - this->init(false); - this->resize(n); - this->copy(in, n); - } - - /** - * Copy constructor. - */ - MemoryVector(const MemoryRegion<T>& in) - { - this->init(false); - this->resize(in.size()); - this->copy(&in[0], in.size()); - } - }; - -/** -* This class represents variable length buffers using the operating -* systems capability to lock memory, i.e. keeping it from being -* swapped out to disk. In this way, a security hole allowing attackers -* to find swapped out secret keys is closed. -*/ -template<typename T> -class SecureVector : public MemoryRegion<T> - { - public: - /** - * Copy the contents of another buffer into this buffer. - * @param other the buffer to copy the contents from - * @return reference to *this - */ - SecureVector<T>& operator=(const MemoryRegion<T>& other) - { - if(this != &other) - { - this->resize(other.size()); - this->copy(&other[0], other.size()); - } - return (*this); - } - - /** - * Create a buffer of the specified length. - * @param n the length of the buffer to create. - */ - SecureVector(size_t n = 0) { this->init(true, n); } - - /** - * Create a buffer with the specified contents. - * @param in the array containing the data to be initially copied - * into the newly created buffer - * @param n the size of the array in - */ - SecureVector(const T in[], size_t n) - { - this->init(true); - this->resize(n); - this->copy(&in[0], n); - } - - /** - * Create a buffer with contents specified contents. - * @param in the buffer holding the contents that will be - * copied into the newly created buffer. - */ - SecureVector(const MemoryRegion<T>& in) - { - this->init(true); - this->resize(in.size()); - this->copy(&in[0], in.size()); - } - }; - -template<typename T> -size_t buffer_insert(MemoryRegion<T>& buf, +template<typename T, typename Alloc> +size_t buffer_insert(std::vector<T, Alloc>& buf, size_t buf_offset, const T input[], size_t input_length) @@ -373,19 +98,20 @@ size_t buffer_insert(MemoryRegion<T>& buf, return to_copy; } -template<typename T> -size_t buffer_insert(MemoryRegion<T>& buf, +template<typename T, typename Alloc, typename Alloc2> +size_t buffer_insert(std::vector<T, Alloc>& buf, size_t buf_offset, - const MemoryRegion<T>& input) + const std::vector<T, Alloc2>& input) { const size_t to_copy = std::min(input.size(), buf.size() - buf_offset); copy_mem(&buf[buf_offset], &input[0], to_copy); return to_copy; } -template<typename T> -MemoryRegion<T>& operator+=(MemoryRegion<T>& out, - const MemoryRegion<T>& in) +template<typename T, typename Alloc, typename Alloc2> +std::vector<T, Alloc>& +operator+=(std::vector<T, Alloc>& out, + const std::vector<T, Alloc2>& in) { const size_t copy_offset = out.size(); out.resize(out.size() + in.size()); @@ -393,17 +119,16 @@ MemoryRegion<T>& operator+=(MemoryRegion<T>& out, return out; } -template<typename T> -MemoryRegion<T>& operator+=(MemoryRegion<T>& out, - T in) +template<typename T, typename Alloc> +std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, T in) { out.push_back(in); return out; } -template<typename T, typename L> -MemoryRegion<T>& operator+=(MemoryRegion<T>& out, - const std::pair<const T*, L>& in) +template<typename T, typename Alloc, typename L> +std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, + const std::pair<const T*, L>& in) { const size_t copy_offset = out.size(); out.resize(out.size() + in.second); @@ -411,9 +136,9 @@ MemoryRegion<T>& operator+=(MemoryRegion<T>& out, return out; } -template<typename T, typename L> -MemoryRegion<T>& operator+=(MemoryRegion<T>& out, - const std::pair<T*, L>& in) +template<typename T, typename Alloc, typename L> +std::vector<T, Alloc>& operator+=(std::vector<T, Alloc>& out, + const std::pair<T*, L>& in) { const size_t copy_offset = out.size(); out.resize(out.size() + in.second); @@ -425,22 +150,12 @@ MemoryRegion<T>& operator+=(MemoryRegion<T>& out, * Zeroise the values; length remains unchanged * @param vec the vector to zeroise */ -template<typename T> -void zeroise(MemoryRegion<T>& vec) +template<typename T, typename Alloc> +void zeroise(std::vector<T, Alloc>& vec) { clear_mem(&vec[0], vec.size()); } } -namespace std { - -template<typename T> -inline void swap(Botan::MemoryRegion<T>& x, Botan::MemoryRegion<T>& y) - { - x.swap(y); - } - -} - #endif diff --git a/src/alloc/system_alloc/defalloc.cpp b/src/alloc/system_alloc/defalloc.cpp deleted file mode 100644 index 8e178bb14..000000000 --- a/src/alloc/system_alloc/defalloc.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/* -* Basic Allocators -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/defalloc.h> -#include <botan/internal/mlock.h> -#include <botan/libstate.h> -#include <cstdlib> -#include <cstring> - -namespace Botan { - -namespace { - -/* -* Perform Memory Allocation -*/ -void* do_malloc(size_t n, bool do_lock) - { - void* ptr = std::malloc(n); - - if(!ptr) - return 0; - - if(do_lock) - lock_mem(ptr, n); - - std::memset(ptr, 0, n); - return ptr; - } - -/* -* Perform Memory Deallocation -*/ -void do_free(void* ptr, size_t n, bool do_lock) - { - if(!ptr) - return; - - std::memset(ptr, 0, n); - if(do_lock) - unlock_mem(ptr, n); - - std::free(ptr); - } - -} - -/* -* Malloc_Allocator's Allocation -*/ -void* Malloc_Allocator::allocate(size_t n) - { - void* ptr = do_malloc(n, false); - if(!ptr) - throw Memory_Exhaustion(); - return ptr; - } - -/* -* Malloc_Allocator's Deallocation -*/ -void Malloc_Allocator::deallocate(void* ptr, size_t n) - { - do_free(ptr, n, false); - } - -/* -* Locking_Allocator's Allocation -*/ -void* Locking_Allocator::alloc_block(size_t n) - { - return do_malloc(n, true); - } - -/* -* Locking_Allocator's Deallocation -*/ -void Locking_Allocator::dealloc_block(void* ptr, size_t n) - { - do_free(ptr, n, true); - } - -/* -* Get an allocator -*/ -Allocator* Allocator::get(bool locking) - { - std::string type = ""; - if(!locking) - type = "malloc"; - - Allocator* alloc = global_state().get_allocator(type); - if(alloc) - return alloc; - - throw Internal_Error("Couldn't find an allocator to use in get_allocator"); - } - -} diff --git a/src/alloc/system_alloc/defalloc.h b/src/alloc/system_alloc/defalloc.h deleted file mode 100644 index c4b90d081..000000000 --- a/src/alloc/system_alloc/defalloc.h +++ /dev/null @@ -1,41 +0,0 @@ -/* -* Basic Allocators -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_BASIC_ALLOC_H__ -#define BOTAN_BASIC_ALLOC_H__ - -#include <botan/internal/mem_pool.h> - -namespace Botan { - -/** -* Allocator using malloc -*/ -class Malloc_Allocator : public Allocator - { - public: - void* allocate(size_t); - void deallocate(void*, size_t); - - std::string type() const { return "malloc"; } - }; - -/** -* Allocator using malloc plus locking -*/ -class Locking_Allocator : public Pooling_Allocator - { - public: - std::string type() const { return "locking"; } - private: - void* alloc_block(size_t); - void dealloc_block(void*, size_t); - }; - -} - -#endif diff --git a/src/alloc/system_alloc/info.txt b/src/alloc/system_alloc/info.txt deleted file mode 100644 index 87de0cb67..000000000 --- a/src/alloc/system_alloc/info.txt +++ /dev/null @@ -1,13 +0,0 @@ - -<source> -defalloc.cpp -</source> - -<header:internal> -defalloc.h -</header:internal> - -<requires> -libstate -mem_pool -</requires> |