aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/core/secmem.h256
1 files changed, 237 insertions, 19 deletions
diff --git a/src/core/secmem.h b/src/core/secmem.h
index 37adf7f42..8e353a68b 100644
--- a/src/core/secmem.h
+++ b/src/core/secmem.h
@@ -11,58 +11,192 @@
namespace Botan {
-/*************************************************
-* Variable Length Memory Buffer *
-*************************************************/
+/**
+* This class represents variable length memory buffers.
+*/
template<typename T>
class MemoryRegion
{
public:
+ /**
+ * Find out the size of the buffer, i.e. how many objects of type T it
+ * contains.
+ * @return the size of the buffer
+ */
u32bit size() const { return used; }
- u32bit is_empty() const { return (used == 0); }
- u32bit has_items() const { return (used != 0); }
+ /**
+ * Find out whether this buffer is empty.
+ * @return true if the buffer is empty, false otherwise
+ */
+ bool is_empty() const { return (used == 0); }
+
+ /**
+ * Find out whether this buffer is non-empty
+ * @return true if the buffer is non-empty, false otherwise
+ */
+ bool has_items() const { return (used != 0); }
+
+ /**
+ * Get a pointer to the first element in the buffer.
+ * @return a pointer to the first element in the buffer
+ */
operator T* () { return buf; }
+
+ /**
+ * Get a constant pointer to the first element in the buffer.
+ * @return a constant pointer to the first element in the buffer
+ */
operator const T* () const { return buf; }
+ /**
+ * Get a pointer to the first element in the buffer.
+ * @return a pointer to the first element in the buffer
+ */
T* begin() { return buf; }
+
+ /**
+ * Get a constant pointer to the first element in the buffer.
+ * @return a constant pointer to the first element in the buffer
+ */
const T* begin() const { return buf; }
+ /**
+ * Get a pointer to the last element in the buffer.
+ * @return a pointer to the last element in the buffer
+ */
T* end() { return (buf + size()); }
+
+ /**
+ * Get a constant pointer to the last element in the buffer.
+ * @return a constant pointer to 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()));
}
- bool operator<(const MemoryRegion<T>&) const;
-
+ /**
+ * Compare two buffers lexicographically.
+ * @return true if this buffer is lexicographically smaller than other.
+ */
+ bool operator<(const MemoryRegion<T>& other) const;
+
+ /**
+ * Check two buffers for inequality.
+ * @return false if the content of both buffers is byte-wise equal, true
+ * otherwise.
+ */
bool operator!=(const MemoryRegion<T>& in) const
{ return (!(*this == in)); }
+
+ /**
+ * Copy the contents of another buffer into this buffer.
+ * The former contents of *this are discarded.
+ * @param in the buffer to copy the contents from.
+ * @return a reference to *this
+ */
MemoryRegion<T>& operator=(const MemoryRegion<T>& in)
{ if(this != &in) set(in); return (*this); }
+ /**
+ * The use of this function is discouraged because of the risk of memory
+ * errors. Use MemoryRegion<T>::set()
+ * instead.
+ * 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
+ */
void copy(const T in[], u32bit n)
{ copy(0, in, n); }
+
+ /**
+ * The use of this function is discouraged because of the risk of memory
+ * errors. Use MemoryRegion<T>::set()
+ * instead.
+ * 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 off the offset position inside this buffer to start inserting
+ * the copied bytes
+ * @param in the array to copy the contents from
+ * @param n the length of in
+ */
void copy(u32bit off, const T in[], u32bit n)
{ copy_mem(buf + off, in, (n > size() - off) ? (size() - off) : n); }
+ /**
+ * Set the contents of this according to the argument. The size of
+ * *this is increased if necessary.
+ * @param in the array of objects of type T to copy the contents from
+ * @param n the size of array in
+ */
void set(const T in[], u32bit n) { create(n); copy(in, n); }
+
+ /**
+ * Set the contents of this according to the argument. The size of
+ * *this is increased if necessary.
+ * @param in the buffer to copy the contents from
+ */
void set(const MemoryRegion<T>& in) { set(in.begin(), in.size()); }
+ /**
+ * Append data to the end of this buffer.
+ * @param data the array containing the data to append
+ * @param n the size of the array data
+ */
void append(const T data[], u32bit n)
{ grow_to(size()+n); copy(size() - n, data, n); }
+
+ /**
+ * Append a single element.
+ * @param x the element to append
+ */
void append(T x) { append(&x, 1); }
+
+ /**
+ * Append data to the end of this buffer.
+ * @param data the buffer containing the data to append
+ */
void append(const MemoryRegion<T>& x) { append(x.begin(), x.size()); }
+ /**
+ * Zeroise the bytes of this buffer. The length remains unchanged.
+ */
void clear() { clear_mem(buf, allocated); }
+
+ /**
+ * Reset this buffer to an empty buffer with size zero.
+ */
void destroy() { create(0); }
- void create(u32bit);
- void grow_to(u32bit);
- void swap(MemoryRegion<T>&);
+ /**
+ * Reset this buffer to a buffer of specified length. The content will be
+ * initialized to zero bytes.
+ * @param n the new length of the buffer
+ */
+ void create(u32bit n);
+
+ /**
+ * Preallocate memory, so that this buffer can grow up to size n without
+ * having to perform any actual memory allocations. (This is
+ * the same principle as for std::vector::reserve().)
+ */
+ void grow_to(u32bit N);
+
+ /**
+ * Swap this buffer with another object.
+ */
+ void swap(MemoryRegion<T>& other);
~MemoryRegion() { deallocate(buf, allocated); }
protected:
@@ -156,55 +290,139 @@ void MemoryRegion<T>::swap(MemoryRegion<T>& x)
std::swap(alloc, x.alloc);
}
-/*************************************************
-* Unlocked Variable Length Buffer *
-*************************************************/
+/**
+* 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 a reference to *this
+ */
MemoryVector<T>& operator=(const MemoryRegion<T>& in)
{ if(this != &in) set(in); return (*this); }
+ /**
+ * Create a buffer of the specified length.
+ * @param n the length of the buffer to create.
+ *
+ */
MemoryVector(u32bit n = 0) { MemoryRegion<T>::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[], u32bit n)
{ MemoryRegion<T>::init(false); set(in, n); }
+
+ /**
+ * Copy constructor.
+ */
MemoryVector(const MemoryRegion<T>& in)
{ MemoryRegion<T>::init(false); set(in); }
+
+ /**
+ * Create a buffer whose content is the concatenation of two other
+ * buffers.
+ * @param in1 the first part of the new contents
+ * @param in2 the contents to be appended to in1
+ */
MemoryVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
{ MemoryRegion<T>::init(false); set(in1); append(in2); }
};
-/*************************************************
-* Locked Variable Length Buffer *
-*************************************************/
+/**
+* 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. Please refer to
+* Botan::InitializerOptions::secure_memory() for restrictions and
+* further details.
+*/
template<typename T>
class SecureVector : public MemoryRegion<T>
{
public:
+ /**
+ * Copy the contents of another buffer into this buffer.
+ * @param in the buffer to copy the contents from
+ * @return a reference to *this
+ */
SecureVector<T>& operator=(const MemoryRegion<T>& in)
{ if(this != &in) set(in); return (*this); }
+ /**
+ * Create a buffer of the specified length.
+ * @param n the length of the buffer to create.
+ *
+ */
SecureVector(u32bit n = 0) { MemoryRegion<T>::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[], u32bit n)
{ MemoryRegion<T>::init(true); set(in, 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)
{ MemoryRegion<T>::init(true); set(in); }
+
+ /**
+ * Create a buffer whose content is the concatenation of two other
+ * buffers.
+ * @param in1 the first part of the new contents
+ * @param in2 the contents to be appended to in1
+ */
SecureVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
{ MemoryRegion<T>::init(true); set(in1); append(in2); }
};
-/*************************************************
-* Locked Fixed Length Buffer *
-*************************************************/
+/**
+* This class represents fixed 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. Please refer to
+* Botan::InitializerOptions::secure_memory() for restrictions and
+* further details.
+*/
template<typename T, u32bit L>
class SecureBuffer : public MemoryRegion<T>
{
public:
+ /**
+ * Copy the contents of another buffer into this buffer.
+ * @param in the buffer to copy the contents from
+ * @return a reference to *this
+ */
SecureBuffer<T,L>& operator=(const SecureBuffer<T,L>& in)
{ if(this != &in) set(in); return (*this); }
+ /**
+ * Create a buffer of the length L.
+ */
SecureBuffer() { MemoryRegion<T>::init(true, L); }
+
+ /**
+ * Create a buffer of size L 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
+ */
SecureBuffer(const T in[], u32bit n)
{ MemoryRegion<T>::init(true, L); copy(in, n); }
private: