6#ifndef CRYPTOPP_SECBLOCK_H
7#define CRYPTOPP_SECBLOCK_H
14#if CRYPTOPP_MSC_VERSION
16# pragma warning(disable: 4231 4275 4700)
17# if (CRYPTOPP_MSC_VERSION >= 1400)
18# pragma warning(disable: 6011 6386 28193)
22NAMESPACE_BEGIN(CryptoPP)
33 typedef size_t size_type;
34 typedef std::ptrdiff_t difference_type;
36 typedef const T * const_pointer;
37 typedef T & reference;
38 typedef const T & const_reference;
40 pointer address(reference r)
const {
return (&r);}
41 const_pointer address(const_reference r)
const {
return (&r); }
42 void construct(pointer p,
const T& val) {
new (p) T(val);}
43 void destroy(pointer p) {CRYPTOPP_UNUSED(p); p->~T();}
57#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
59#elif defined(_MSC_VER) && (_MSC_VER <= 1400)
60 static const size_type
ELEMS_MAX = (~(size_type)0)/
sizeof(T);
61#elif defined(CRYPTOPP_CXX11_STRONG_ENUM)
62 enum : size_type {
ELEMS_MAX = SIZE_MAX/
sizeof(T)};
64 static const size_type
ELEMS_MAX = SIZE_MAX/
sizeof(T);
75#if defined(__SUNPRO_CC)
78 CRYPTOPP_CONSTEXPR size_type
max_size(size_type n)
const {
return SIZE_MAX/n;}
81#if defined(CRYPTOPP_CXX11_VARIADIC_TEMPLATES) || defined(CRYPTOPP_DOXYGEN_PROCESSING)
90 template<
typename V,
typename... Args>
91 void construct(V* ptr, Args&&... args) {::new ((
void*)ptr) V(std::forward<Args>(args)...);}
98 void destroy(V* ptr) {
if (ptr) ptr->~V();}
122 CRYPTOPP_UNUSED(size);
125 throw InvalidArgument(
"AllocatorBase: requested size would cause integer overflow");
129#define CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T_type) \
130 typedef typename AllocatorBase<T_type>::value_type value_type;\
131 typedef typename AllocatorBase<T_type>::size_type size_type;\
132 typedef typename AllocatorBase<T_type>::difference_type difference_type;\
133 typedef typename AllocatorBase<T_type>::pointer pointer;\
134 typedef typename AllocatorBase<T_type>::const_pointer const_pointer;\
135 typedef typename AllocatorBase<T_type>::reference reference;\
136 typedef typename AllocatorBase<T_type>::const_reference const_reference;
148template <
class T,
class A>
149typename A::pointer
StandardReallocate(A& alloc, T *oldPtr,
typename A::size_type oldSize,
typename A::size_type newSize,
bool preserve)
153 if (oldSize == newSize)
158 typename A::pointer newPtr = alloc.allocate(newSize, NULLPTR);
159 const typename A::size_type copySize =
STDMIN(oldSize, newSize) *
sizeof(T);
161 if (oldPtr && newPtr)
162 memcpy_s(newPtr, copySize, oldPtr, copySize);
165 alloc.deallocate(oldPtr, oldSize);
172 alloc.deallocate(oldPtr, oldSize);
174 return alloc.allocate(newSize, NULLPTR);
186template <
class T,
bool T_Align16 = false>
190 CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T)
206 pointer
allocate(size_type size, const
void *ptr = NULLPTR)
208 CRYPTOPP_UNUSED(ptr); CRYPTOPP_ASSERT(ptr == NULLPTR);
213#if CRYPTOPP_BOOL_ALIGN16
215 return reinterpret_cast<pointer
>(AlignedAllocate(size*
sizeof(T)));
218 return reinterpret_cast<pointer
>(UnalignedAllocate(size*
sizeof(T)));
237#if CRYPTOPP_BOOL_ALIGN16
239 return AlignedDeallocate(ptr);
242 UnalignedDeallocate(ptr);
259 pointer
reallocate(T *oldPtr, size_type oldSize, size_type newSize,
bool preserve)
261 CRYPTOPP_ASSERT((oldPtr && oldSize) || !(oldPtr || oldSize));
283#if defined(CRYPTOPP_WORD128_AVAILABLE)
302 CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T)
307 pointer allocate(size_type n,
const void* unused = NULLPTR)
309 CRYPTOPP_UNUSED(n); CRYPTOPP_UNUSED(unused);
310 CRYPTOPP_ASSERT(
false);
return NULLPTR;
313 void deallocate(
void *p, size_type n)
315 CRYPTOPP_UNUSED(p); CRYPTOPP_UNUSED(n);
316 CRYPTOPP_ASSERT(
false);
319 CRYPTOPP_CONSTEXPR size_type max_size()
const {
return 0;}
335template <
class T,
size_t S,
class A = NullAllocator<T>,
bool T_Align16 = false>
353template <
class T,
size_t S,
class A>
357 CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T)
378 if (size <= S && !m_allocated)
381 return GetAlignedArray();
384 return m_fallbackAllocator.allocate(size);
404 if (size <= S && !m_allocated)
407 return GetAlignedArray();
410 return m_fallbackAllocator.allocate(size, hint);
425 if (ptr == GetAlignedArray())
431 CRYPTOPP_ASSERT(size <= S);
432 CRYPTOPP_ASSERT(m_allocated);
439 m_fallbackAllocator.deallocate(ptr, size);
461 pointer
reallocate(pointer oldPtr, size_type oldSize, size_type newSize,
bool preserve)
463 if (oldPtr == GetAlignedArray() && newSize <= S)
465 CRYPTOPP_ASSERT(oldSize <= S);
466 if (oldSize > newSize)
471 pointer newPtr = allocate(newSize, NULLPTR);
472 if (preserve && newSize)
474 const size_type copySize =
STDMIN(oldSize, newSize);
475 if (newPtr && oldPtr)
476 memcpy_s(newPtr,
sizeof(T)*newSize, oldPtr,
sizeof(T)*copySize);
478 deallocate(oldPtr, oldSize);
482 CRYPTOPP_CONSTEXPR size_type
max_size()
const
484 return STDMAX(m_fallbackAllocator.max_size(), S);
489#if CRYPTOPP_BOOL_ALIGN16
507 T* GetAlignedArray() {
519 int off =
reinterpret_cast<uintptr_t
>(m_array) % 16;
520 byte* ptr =
reinterpret_cast<byte*
>(m_array) + off;
527 reinterpret_cast<uintptr_t
>(ptr) >=
528 reinterpret_cast<uintptr_t
>(m_array)
533 reinterpret_cast<uintptr_t
>(ptr+S*
sizeof(T)) <=
534 reinterpret_cast<uintptr_t
>(m_array+(S+PAD))
538 return reinterpret_cast<T*
>(
539 static_cast<void*
>(ptr)
544 enum { Q =
sizeof(T), PAD = (Q >= 8) ? 1 : (Q >= 4) ? 2 : (Q >= 2) ? 4 : 8 };
546 CRYPTOPP_ALIGN_DATA(8) T m_array[S+PAD];
558 T* GetAlignedArray() {
return m_array;}
559 CRYPTOPP_ALIGN_DATA(8) T m_array[S];
563 A m_fallbackAllocator;
577template <
class T,
size_t S,
class A>
581 CRYPTOPP_INHERIT_ALLOCATOR_TYPES(T)
602 if (size <= S && !m_allocated)
605 return GetAlignedArray();
608 return m_fallbackAllocator.allocate(size);
626 if (size <= S && !m_allocated)
629 return GetAlignedArray();
632 return m_fallbackAllocator.allocate(size, hint);
647 if (ptr == GetAlignedArray())
651 CRYPTOPP_ASSERT(size <= S);
652 CRYPTOPP_ASSERT(m_allocated);
659 m_fallbackAllocator.deallocate(ptr, size);
682 pointer
reallocate(pointer oldPtr, size_type oldSize, size_type newSize,
bool preserve)
684 if (oldPtr == GetAlignedArray() && newSize <= S)
686 CRYPTOPP_ASSERT(oldSize <= S);
687 if (oldSize > newSize)
692 pointer newPtr = allocate(newSize, NULLPTR);
693 if (preserve && newSize)
695 const size_type copySize =
STDMIN(oldSize, newSize);
696 if (newPtr && oldPtr)
697 memcpy_s(newPtr,
sizeof(T)*newSize, oldPtr,
sizeof(T)*copySize);
699 deallocate(oldPtr, oldSize);
703 CRYPTOPP_CONSTEXPR size_type
max_size()
const
705 return STDMAX(m_fallbackAllocator.max_size(), S);
716 T* GetAlignedArray() {
return m_array;}
717 CRYPTOPP_ALIGN_DATA(8) T m_array[S];
719 A m_fallbackAllocator;
733 typedef typename A::value_type value_type;
734 typedef typename A::pointer iterator;
735 typedef typename A::const_pointer const_iterator;
736 typedef typename A::size_type size_type;
750#if defined(CRYPTOPP_DOXYGEN_PROCESSING)
752#elif defined(_MSC_VER) && (_MSC_VER <= 1400)
753 static const size_type
ELEMS_MAX = (~(size_type)0)/
sizeof(T);
754#elif defined(CRYPTOPP_CXX11_STRONG_ENUM)
755 enum : size_type {
ELEMS_MAX = A::ELEMS_MAX};
767 : m_mark(
ELEMS_MAX), m_size(size), m_ptr(m_alloc.allocate(size, NULLPTR)) { }
774 : m_mark(t.m_mark), m_size(t.m_size), m_ptr(m_alloc.allocate(t.m_size, NULLPTR)) {
775 CRYPTOPP_ASSERT((!t.m_ptr && !m_size) || (t.m_ptr && m_size));
776 if (m_ptr && t.m_ptr)
777 memcpy_s(m_ptr, m_size*
sizeof(T), t.m_ptr, t.m_size*
sizeof(T));
790 : m_mark(
ELEMS_MAX), m_size(len), m_ptr(m_alloc.allocate(len, NULLPTR)) {
791 CRYPTOPP_ASSERT((!m_ptr && !m_size) || (m_ptr && m_size));
793 memcpy_s(m_ptr, m_size*
sizeof(T), ptr, len*
sizeof(T));
794 else if (m_ptr && m_size)
795 memset(m_ptr, 0, m_size*
sizeof(T));
799 {m_alloc.deallocate(m_ptr,
STDMIN(m_size, m_mark));}
811 operator const void *()
const
823 operator const T *()
const
847 {
return m_ptr+m_size;}
851 const_iterator
end()
const
852 {
return m_ptr+m_size;}
857 typename A::pointer
data() {
return m_ptr;}
861 typename A::const_pointer
data()
const {
return m_ptr;}
867 size_type
size()
const {
return m_size;}
871 bool empty()
const {
return m_size == 0;}
880 const byte *
BytePtr()
const {
return (
const byte *)m_ptr;}
902 memcpy_s(m_ptr, m_size*
sizeof(T), ptr, len*
sizeof(T));
916 for (
size_t i=0; i<count; ++i)
933 if (m_ptr && t.m_ptr)
934 memcpy_s(m_ptr, m_size*
sizeof(T), t, t.m_size*
sizeof(T));
957 const size_type oldSize = m_size;
960 memcpy_s(m_ptr+oldSize, (m_size-oldSize)*
sizeof(T), ptr, len*
sizeof(T));
978 const size_type oldSize = m_size;
981 Grow(m_size+t.m_size);
982 if (m_ptr && t.m_ptr)
983 memcpy_s(m_ptr+oldSize, (m_size-oldSize)*
sizeof(T), t.m_ptr, t.m_size*
sizeof(T));
989 memmove_s(m_ptr+oldSize, (m_size-oldSize)*
sizeof(T), m_ptr, oldSize*
sizeof(T));
1009 const size_type oldSize = m_size;
1011 for (
size_t i=oldSize; i<oldSize+count; ++i)
1075 CRYPTOPP_ASSERT((!m_ptr && !m_size) || (m_ptr && m_size));
1076 CRYPTOPP_ASSERT((!t.m_ptr && !t.m_size) || (t.m_ptr && t.m_size));
1077 if(!t.m_size)
return SecBlock(*
this);
1081 memcpy_s(result.m_ptr, result.m_size*
sizeof(T), m_ptr, m_size*
sizeof(T));
1082 if (result.m_ptr && t.m_ptr)
1083 memcpy_s(result.m_ptr+m_size, (result.m_size-m_size)*
sizeof(T), t.m_ptr, t.m_size*
sizeof(T));
1097 return m_size == t.m_size && VerifyBufsEqual(
1098 reinterpret_cast<const byte*
>(m_ptr),
1099 reinterpret_cast<const byte*
>(t.m_ptr), m_size*
sizeof(T));
1113 return !operator==(t);
1128 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize,
false);
1146 if (m_ptr) {
memset_z(m_ptr, 0, m_size*
sizeof(T));}
1162 if (newSize > m_size)
1164 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize,
true);
1181 if (newSize > m_size)
1183 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize,
true);
1184 memset_z(m_ptr+m_size, 0, (newSize-m_size)*
sizeof(T));
1200 m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize,
true);
1212 std::swap(m_alloc, b.m_alloc);
1213 std::swap(m_mark, b.m_mark);
1214 std::swap(m_size, b.m_size);
1215 std::swap(m_ptr, b.m_ptr);
1220 size_type m_mark, m_size;
1224#ifdef CRYPTOPP_DOXYGEN_PROCESSING
1244template <
class T,
unsigned int S,
class A = FixedSizeAllocatorWithCleanup<T, S> >
1257template <
class T,
unsigned int S,
bool T_Align16 = true>
1266template <
class T,
unsigned int S,
class A = FixedSizeAllocatorWithCleanup<T, S, AllocatorWithCleanup<T> > >
1274template<
class T,
bool A,
class V,
bool B>
1275inline bool operator==(
const CryptoPP::AllocatorWithCleanup<T, A>&,
const CryptoPP::AllocatorWithCleanup<V, B>&) {
return (
true);}
1276template<
class T,
bool A,
class V,
bool B>
1277inline bool operator!=(
const CryptoPP::AllocatorWithCleanup<T, A>&,
const CryptoPP::AllocatorWithCleanup<V, B>&) {
return (
false);}
1288template <
class T,
class A>
1289inline void swap(CryptoPP::SecBlock<T, A> &a, CryptoPP::SecBlock<T, A> &b)
1294#if defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) || (defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES))
1296template <
class _Tp1,
class _Tp2>
1297inline CryptoPP::AllocatorWithCleanup<_Tp2>&
1298__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a,
const _Tp2*)
1300 return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a);
1306#if CRYPTOPP_MSC_VERSION
1307# pragma warning(pop)
Functions for allocating aligned buffers.
Base class for all allocators used by SecBlock.
static const size_type ELEMS_MAX
Returns the maximum number of elements the allocator can provide.
static void CheckSize(size_t size)
Verifies the allocator can satisfy a request based on size.
CRYPTOPP_CONSTEXPR size_type max_size() const
Returns the maximum number of elements the allocator can provide.
Allocates a block of memory with cleanup.
pointer allocate(size_type size, const void *ptr=NULLPTR)
Allocates a block of memory.
pointer reallocate(T *oldPtr, size_type oldSize, size_type newSize, bool preserve)
Reallocates a block of memory.
void deallocate(void *ptr, size_type size)
Deallocates a block of memory.
Fixed size stack-based SecBlock with 16-byte alignment.
void deallocate(void *ptr, size_type size)
Deallocates a block of memory.
pointer allocate(size_type size)
Allocates a block of memory.
pointer reallocate(pointer oldPtr, size_type oldSize, size_type newSize, bool preserve)
Reallocates a block of memory.
pointer allocate(size_type size, const void *hint)
Allocates a block of memory.
pointer reallocate(pointer oldPtr, size_type oldSize, size_type newSize, bool preserve)
Reallocates a block of memory.
pointer allocate(size_type size, const void *hint)
Allocates a block of memory.
void deallocate(void *ptr, size_type size)
Deallocates a block of memory.
pointer allocate(size_type size)
Allocates a block of memory.
Static secure memory block with cleanup.
Fixed size stack-based SecBlock.
FixedSizeSecBlock()
Construct a FixedSizeSecBlock.
An invalid argument was detected.
Secure memory block with allocator and cleanup.
void Assign(size_type count, T value)
Set contents from a value.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
const_iterator begin() const
Provides a constant iterator pointing to the first element in the memory block.
void Append(const T *ptr, size_type len)
Append contents from an array.
iterator end()
Provides an iterator pointing beyond the last element in the memory block.
SecBlock< T, A > operator+(const SecBlock< T, A > &t)
Construct a SecBlock from this and another SecBlock.
SecBlock(const SecBlock< T, A > &t)
Copy construct a SecBlock from another SecBlock.
void CleanNew(size_type newSize)
Change size without preserving contents.
void Assign(const SecBlock< T, A > &t)
Copy contents from another SecBlock.
void swap(SecBlock< T, A > &b)
Swap contents with another SecBlock.
SecBlock(size_type size=0)
Construct a SecBlock with space for size elements.
A::pointer data()
Provides a pointer to the first element in the memory block.
void CleanGrow(size_type newSize)
Change size and preserve contents.
bool operator!=(const SecBlock< T, A > &t) const
Bitwise compare two SecBlocks.
SecBlock(const T *ptr, size_type len)
Construct a SecBlock from an array of elements.
void Append(size_type count, T value)
Append contents from a value.
bool operator==(const SecBlock< T, A > &t) const
Bitwise compare two SecBlocks.
void Grow(size_type newSize)
Change size and preserve contents.
void New(size_type newSize)
Change size without preserving contents.
size_type SizeInBytes() const
Provides the number of bytes in the SecBlock.
void Append(const SecBlock< T, A > &t)
Append contents from another SecBlock.
void SetMark(size_t count)
Sets the number of elements to zeroize.
void Assign(const T *ptr, size_type len)
Set contents and size from an array.
byte * BytePtr()
Provides a byte pointer to the first element in the memory block.
const_iterator end() const
Provides a constant iterator pointing beyond the last element in the memory block.
A::const_pointer data() const
Provides a pointer to the first element in the memory block.
SecBlock< T, A > & operator+=(const SecBlock< T, A > &t)
Append contents from another SecBlock.
bool empty() const
Determines if the SecBlock is empty.
const byte * BytePtr() const
Return a byte pointer to the first element in the memory block.
SecBlock< T, A > & operator=(const SecBlock< T, A > &t)
Assign contents from another SecBlock.
size_type size() const
Provides the count of elements in the SecBlock.
void resize(size_type newSize)
Change size and preserve contents.
Stack-based SecBlock that grows into the heap.
SecBlockWithHint(size_t size)
construct a SecBlockWithHint with a count of elements
Library configuration file.
Utility functions for the Crypto++ library.
void * memset_z(void *ptr, int val, size_t num)
Memory block initializer.
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
void SecureWipeArray(T *buf, size_t n)
Sets each element of an array to 0.
void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memcpy()
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count)
Bounds checking replacement for memmove()
A::pointer StandardReallocate(A &alloc, T *oldPtr, typename A::size_type oldSize, typename A::size_type newSize, bool preserve)
Reallocation function.
NAMESPACE_END void swap(CryptoPP::SecBlock< T, A > &a, CryptoPP::SecBlock< T, A > &b)
Swap two SecBlocks.
Template class member Rebind.