diff options
author | lloyd <[email protected]> | 2014-01-01 21:20:55 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2014-01-01 21:20:55 +0000 |
commit | 197dc467dec28a04c3b2f30da7cef122dfbb13e9 (patch) | |
tree | cdbd3ddaec051c72f0a757db461973d90c37b97a /src/alloc | |
parent | 62faac373c07cfe10bc8c309e89ebdd30d8e5eaa (diff) |
Shuffle things around. Add NIST X.509 test to build.
Diffstat (limited to 'src/alloc')
-rw-r--r-- | src/alloc/info.txt | 3 | ||||
-rw-r--r-- | src/alloc/locking_allocator/info.txt | 9 | ||||
-rw-r--r-- | src/alloc/locking_allocator/locking_allocator.cpp | 262 | ||||
-rw-r--r-- | src/alloc/locking_allocator/locking_allocator.h | 44 | ||||
-rw-r--r-- | src/alloc/secmem.h | 185 |
5 files changed, 0 insertions, 503 deletions
diff --git a/src/alloc/info.txt b/src/alloc/info.txt deleted file mode 100644 index 0ab7fa768..000000000 --- a/src/alloc/info.txt +++ /dev/null @@ -1,3 +0,0 @@ -<header:public> -secmem.h -</header:public> diff --git a/src/alloc/locking_allocator/info.txt b/src/alloc/locking_allocator/info.txt deleted file mode 100644 index 09b59406c..000000000 --- a/src/alloc/locking_allocator/info.txt +++ /dev/null @@ -1,9 +0,0 @@ -define LOCKING_ALLOCATOR 20131128 - -<os> -linux -freebsd -netbsd -openbsd -solaris -</os> diff --git a/src/alloc/locking_allocator/locking_allocator.cpp b/src/alloc/locking_allocator/locking_allocator.cpp deleted file mode 100644 index 13effbb09..000000000 --- a/src/alloc/locking_allocator/locking_allocator.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* -* Mlock Allocator -* (C) 2012 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/locking_allocator.h> -#include <botan/mem_ops.h> -#include <algorithm> -#include <sys/mman.h> -#include <sys/resource.h> - -namespace Botan { - -namespace { - -size_t mlock_limit() - { - /* - * Linux defaults to only 64 KiB of mlockable memory per process - * (too small) but BSDs offer a small fraction of total RAM (more - * than we need). Bound the total mlock size to 512 KiB which is - * enough to run the entire test suite without spilling to non-mlock - * memory (and thus presumably also enough for many useful - * programs), but small enough that we should not cause problems - * even if many processes are mlocking on the same machine. - */ - const size_t MLOCK_UPPER_BOUND = 512*1024; - - struct rlimit limits; - ::getrlimit(RLIMIT_MEMLOCK, &limits); - - if(limits.rlim_cur < limits.rlim_max) - { - limits.rlim_cur = limits.rlim_max; - ::setrlimit(RLIMIT_MEMLOCK, &limits); - ::getrlimit(RLIMIT_MEMLOCK, &limits); - } - - return std::min<size_t>(limits.rlim_cur, MLOCK_UPPER_BOUND); - } - -bool ptr_in_pool(const void* pool_ptr, size_t poolsize, - const void* buf_ptr, size_t bufsize) - { - const uintptr_t pool = reinterpret_cast<uintptr_t>(pool_ptr); - const uintptr_t buf = reinterpret_cast<uintptr_t>(buf_ptr); - - if(buf < pool || buf >= pool + poolsize) - return false; - - BOTAN_ASSERT(buf + bufsize <= pool + poolsize, - "Pointer does not partially overlap pool"); - - return true; - } - -size_t padding_for_alignment(size_t offset, size_t desired_alignment) - { - size_t mod = offset % desired_alignment; - if(mod == 0) - return 0; // already right on - return desired_alignment - mod; - } - -} - -void* mlock_allocator::allocate(size_t num_elems, size_t elem_size) - { - if(!m_pool) - return nullptr; - - const size_t n = num_elems * elem_size; - const size_t alignment = elem_size; - - if(n / elem_size != num_elems) - return nullptr; // overflow! - - if(n > m_poolsize || n > BOTAN_MLOCK_ALLOCATOR_MAX_ALLOCATION) - return nullptr; - - std::lock_guard<std::mutex> lock(m_mutex); - - auto best_fit = m_freelist.end(); - - for(auto i = m_freelist.begin(); i != m_freelist.end(); ++i) - { - // If we have a perfect fit, use it immediately - if(i->second == n && (i->first % alignment) == 0) - { - const size_t offset = i->first; - m_freelist.erase(i); - clear_mem(m_pool + offset, n); - - BOTAN_ASSERT((reinterpret_cast<size_t>(m_pool) + offset) % alignment == 0, - "Returning correctly aligned pointer"); - - return m_pool + offset; - } - - if((i->second >= (n + padding_for_alignment(i->first, alignment)) && - ((best_fit == m_freelist.end()) || (best_fit->second > i->second)))) - { - best_fit = i; - } - } - - if(best_fit != m_freelist.end()) - { - const size_t offset = best_fit->first; - - const size_t alignment_padding = padding_for_alignment(offset, alignment); - - best_fit->first += n + alignment_padding; - best_fit->second -= n + alignment_padding; - - // Need to realign, split the block - if(alignment_padding) - { - /* - If we used the entire block except for small piece used for - alignment at the beginning, so just update the entry already - in place (as it is in the correct location), rather than - deleting the empty range and inserting the new one in the - same location. - */ - if(best_fit->second == 0) - { - best_fit->first = offset; - best_fit->second = alignment_padding; - } - else - m_freelist.insert(best_fit, std::make_pair(offset, alignment_padding)); - } - - clear_mem(m_pool + offset + alignment_padding, n); - - BOTAN_ASSERT((reinterpret_cast<size_t>(m_pool) + offset + alignment_padding) % alignment == 0, - "Returning correctly aligned pointer"); - - return m_pool + offset + alignment_padding; - } - - return nullptr; - } - -bool mlock_allocator::deallocate(void* p, size_t num_elems, size_t elem_size) - { - if(!m_pool) - return false; - - size_t n = num_elems * elem_size; - - /* - We return nullptr in allocate if there was an overflow, so we - should never ever see an overflow in a deallocation. - */ - BOTAN_ASSERT(n / elem_size == num_elems, - "No overflow in deallocation"); - - if(!ptr_in_pool(m_pool, m_poolsize, p, n)) - return false; - - std::lock_guard<std::mutex> lock(m_mutex); - - const size_t start = static_cast<byte*>(p) - m_pool; - - auto comp = [](std::pair<size_t, size_t> x, std::pair<size_t, size_t> y){ return x.first < y.first; }; - - auto i = std::lower_bound(m_freelist.begin(), m_freelist.end(), - std::make_pair(start, 0), comp); - - // try to merge with later block - if(i != m_freelist.end() && start + n == i->first) - { - i->first = start; - i->second += n; - n = 0; - } - - // try to merge with previous block - if(i != m_freelist.begin()) - { - auto prev = std::prev(i); - - if(prev->first + prev->second == start) - { - if(n) - { - prev->second += n; - n = 0; - } - else - { - // merge adjoining - prev->second += i->second; - m_freelist.erase(i); - } - } - } - - if(n != 0) // no merge possible? - m_freelist.insert(i, std::make_pair(start, n)); - - return true; - } - -mlock_allocator::mlock_allocator() : - m_poolsize(mlock_limit()), - m_pool(nullptr) - { -#if !defined(MAP_NOCORE) - #define MAP_NOCORE 0 -#endif - - if(m_poolsize) - { - m_pool = static_cast<byte*>( - ::mmap( - nullptr, m_poolsize, - PROT_READ | PROT_WRITE, - MAP_ANONYMOUS | MAP_SHARED | MAP_NOCORE, - -1, 0)); - - if(m_pool == static_cast<byte*>(MAP_FAILED)) - { - m_pool = nullptr; - throw std::runtime_error("Failed to mmap locking_allocator pool"); - } - - clear_mem(m_pool, m_poolsize); - - if(::mlock(m_pool, m_poolsize) != 0) - { - ::munmap(m_pool, m_poolsize); - m_pool = nullptr; - throw std::runtime_error("Could not mlock " + std::to_string(m_poolsize) + " bytes"); - } - - m_freelist.push_back(std::make_pair(0, m_poolsize)); - } - } - -mlock_allocator::~mlock_allocator() - { - if(m_pool) - { - clear_mem(m_pool, m_poolsize); - ::munlock(m_pool, m_poolsize); - ::munmap(m_pool, m_poolsize); - m_pool = nullptr; - } - } - -mlock_allocator& mlock_allocator::instance() - { - static mlock_allocator mlock; - return mlock; - } - -} diff --git a/src/alloc/locking_allocator/locking_allocator.h b/src/alloc/locking_allocator/locking_allocator.h deleted file mode 100644 index 3bebea5f2..000000000 --- a/src/alloc/locking_allocator/locking_allocator.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* Mlock Allocator -* (C) 2012 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_MLOCK_ALLOCATOR_H__ -#define BOTAN_MLOCK_ALLOCATOR_H__ - -#include <botan/types.h> -#include <vector> -#include <mutex> - -namespace Botan { - -class BOTAN_DLL mlock_allocator - { - public: - static mlock_allocator& instance(); - - void* allocate(size_t num_elems, size_t elem_size); - - bool deallocate(void* p, size_t num_elems, size_t elem_size); - - mlock_allocator(const mlock_allocator&) = delete; - - mlock_allocator& operator=(const mlock_allocator&) = delete; - - private: - mlock_allocator(); - - ~mlock_allocator(); - - const size_t m_poolsize; - - std::mutex m_mutex; - std::vector<std::pair<size_t, size_t>> m_freelist; - byte* m_pool; - }; - -} - -#endif diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h deleted file mode 100644 index 2f4d65f33..000000000 --- a/src/alloc/secmem.h +++ /dev/null @@ -1,185 +0,0 @@ -/* -* Secure Memory Buffers -* (C) 1999-2007,2012 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__ -#define BOTAN_SECURE_MEMORY_BUFFERS_H__ - -#include <botan/mem_ops.h> -#include <algorithm> -#include <vector> - -#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) - #include <botan/locking_allocator.h> -#endif - -namespace Botan { - -template<typename T> -class secure_allocator - { - public: - typedef T value_type; - - typedef T* pointer; - typedef const T* const_pointer; - - typedef T& reference; - typedef const T& const_reference; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - - secure_allocator() noexcept {} - - ~secure_allocator() noexcept {} - - pointer address(reference x) const noexcept - { return std::addressof(x); } - - const_pointer address(const_reference x) const noexcept - { return std::addressof(x); } - - pointer allocate(size_type n, const void* = 0) - { -#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) - if(pointer p = static_cast<pointer>(mlock_allocator::instance().allocate(n, sizeof(T)))) - return p; -#endif - - pointer p = new T[n]; - clear_mem(p, n); - return p; - } - - void deallocate(pointer p, size_type n) - { - clear_mem(p, n); - -#if defined(BOTAN_HAS_LOCKING_ALLOCATOR) - if(mlock_allocator::instance().deallocate(p, n, sizeof(T))) - return; -#endif - - delete [] p; - } - - size_type max_size() const noexcept - { - return static_cast<size_type>(-1) / sizeof(T); - } - - template<typename U, typename... Args> - void construct(U* p, Args&&... args) - { - ::new(static_cast<void*>(p)) U(std::forward<Args>(args)...); - } - - template<typename U> void destroy(U* p) { p->~U(); } - }; - -template<typename T> inline bool -operator==(const secure_allocator<T>&, const secure_allocator<T>&) - { return true; } - -template<typename T> inline bool -operator!=(const secure_allocator<T>&, const secure_allocator<T>&) - { return false; } - -template<typename T> using secure_vector = std::vector<T, secure_allocator<T>>; - -template<typename T> -std::vector<T> unlock(const secure_vector<T>& in) - { - std::vector<T> out(in.size()); - copy_mem(&out[0], &in[0], in.size()); - return out; - } - -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) - { - const size_t to_copy = std::min(input_length, buf.size() - buf_offset); - copy_mem(&buf[buf_offset], input, to_copy); - return to_copy; - } - -template<typename T, typename Alloc, typename Alloc2> -size_t buffer_insert(std::vector<T, Alloc>& buf, - size_t buf_offset, - 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, 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()); - copy_mem(&out[copy_offset], &in[0], in.size()); - return out; - } - -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 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); - copy_mem(&out[copy_offset], in.first, in.second); - return out; - } - -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); - copy_mem(&out[copy_offset], in.first, in.second); - return out; - } - -/** -* Zeroise the values; length remains unchanged -* @param vec the vector to zeroise -*/ -template<typename T, typename Alloc> -void zeroise(std::vector<T, Alloc>& vec) - { - clear_mem(&vec[0], vec.size()); - } - -/** -* Zeroise the values then free the memory -* @param vec the vector to zeroise and free -*/ -template<typename T, typename Alloc> -void zap(std::vector<T, Alloc>& vec) - { - zeroise(vec); - vec.clear(); - vec.shrink_to_fit(); - } - -} - -#endif |