aboutsummaryrefslogtreecommitdiffstats
path: root/src/alloc
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-05-18 20:32:36 +0000
committerlloyd <[email protected]>2012-05-18 20:32:36 +0000
commitc691561f3198f481c13457433efbccc1c9fcd898 (patch)
treea45ea2c5a30e0cb009fbcb68a61ef39332ff790c /src/alloc
parentd76700f01c7ecac5633edf75f8d7408b46c5dbac (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.txt28
-rw-r--r--src/alloc/alloc_mmap/mmap_mem.cpp145
-rw-r--r--src/alloc/alloc_mmap/mmap_mem.h32
-rw-r--r--src/alloc/allocate.h65
-rw-r--r--src/alloc/info.txt1
-rw-r--r--src/alloc/mem_pool/info.txt8
-rw-r--r--src/alloc/mem_pool/mem_pool.cpp251
-rw-r--r--src/alloc/mem_pool/mem_pool.h74
-rw-r--r--src/alloc/secmem.h411
-rw-r--r--src/alloc/system_alloc/defalloc.cpp103
-rw-r--r--src/alloc/system_alloc/defalloc.h41
-rw-r--r--src/alloc/system_alloc/info.txt13
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>