/src/libs/3rdparty/botan/build/botan/secmem.h

https://github.com/gidlbn/dlbn_02 · C Header · 438 lines · 157 code · 53 blank · 228 comment · 25 complexity · 445ec21db30d3821fcc0f0810a8ac123 MD5 · raw file

  1. /*
  2. * Secure Memory Buffers
  3. * (C) 1999-2007 Jack Lloyd
  4. *
  5. * Distributed under the terms of the Botan license
  6. */
  7. #ifndef BOTAN_SECURE_MEMORY_BUFFERS_H__
  8. #define BOTAN_SECURE_MEMORY_BUFFERS_H__
  9. #include <botan/allocate.h>
  10. #include <botan/mem_ops.h>
  11. #include <algorithm>
  12. namespace Botan {
  13. /**
  14. * This class represents variable length memory buffers.
  15. */
  16. template<typename T>
  17. class MemoryRegion
  18. {
  19. public:
  20. /**
  21. * Find out the size of the buffer, i.e. how many objects of type T it
  22. * contains.
  23. * @return the size of the buffer
  24. */
  25. u32bit size() const { return used; }
  26. /**
  27. * Find out whether this buffer is empty.
  28. * @return true if the buffer is empty, false otherwise
  29. */
  30. bool is_empty() const { return (used == 0); }
  31. /**
  32. * Find out whether this buffer is non-empty
  33. * @return true if the buffer is non-empty, false otherwise
  34. */
  35. bool has_items() const { return (used != 0); }
  36. /**
  37. * Get a pointer to the first element in the buffer.
  38. * @return a pointer to the first element in the buffer
  39. */
  40. operator T* () { return buf; }
  41. /**
  42. * Get a constant pointer to the first element in the buffer.
  43. * @return a constant pointer to the first element in the buffer
  44. */
  45. operator const T* () const { return buf; }
  46. /**
  47. * Get a pointer to the first element in the buffer.
  48. * @return a pointer to the first element in the buffer
  49. */
  50. T* begin() { return buf; }
  51. /**
  52. * Get a constant pointer to the first element in the buffer.
  53. * @return a constant pointer to the first element in the buffer
  54. */
  55. const T* begin() const { return buf; }
  56. /**
  57. * Get a pointer to the last element in the buffer.
  58. * @return a pointer to the last element in the buffer
  59. */
  60. T* end() { return (buf + size()); }
  61. /**
  62. * Get a constant pointer to the last element in the buffer.
  63. * @return a constant pointer to the last element in the buffer
  64. */
  65. const T* end() const { return (buf + size()); }
  66. /**
  67. * Check two buffers for equality.
  68. * @return true iff the content of both buffers is byte-wise equal
  69. */
  70. bool operator==(const MemoryRegion<T>& other) const
  71. {
  72. return (size() == other.size() &&
  73. same_mem(buf, other.buf, size()));
  74. }
  75. /**
  76. * Compare two buffers lexicographically.
  77. * @return true if this buffer is lexicographically smaller than other.
  78. */
  79. bool operator<(const MemoryRegion<T>& other) const;
  80. /**
  81. * Check two buffers for inequality.
  82. * @return false if the content of both buffers is byte-wise equal, true
  83. * otherwise.
  84. */
  85. bool operator!=(const MemoryRegion<T>& in) const
  86. { return (!(*this == in)); }
  87. /**
  88. * Copy the contents of another buffer into this buffer.
  89. * The former contents of *this are discarded.
  90. * @param in the buffer to copy the contents from.
  91. * @return a reference to *this
  92. */
  93. MemoryRegion<T>& operator=(const MemoryRegion<T>& in)
  94. { if(this != &in) set(in); return (*this); }
  95. /**
  96. * The use of this function is discouraged because of the risk of memory
  97. * errors. Use MemoryRegion<T>::set()
  98. * instead.
  99. * Copy the contents of an array of objects of type T into this buffer.
  100. * The former contents of *this are discarded.
  101. * The length of *this must be at least n, otherwise memory errors occur.
  102. * @param in the array to copy the contents from
  103. * @param n the length of in
  104. */
  105. void copy(const T in[], u32bit n)
  106. { copy(0, in, n); }
  107. /**
  108. * The use of this function is discouraged because of the risk of memory
  109. * errors. Use MemoryRegion<T>::set()
  110. * instead.
  111. * Copy the contents of an array of objects of type T into this buffer.
  112. * The former contents of *this are discarded.
  113. * The length of *this must be at least n, otherwise memory errors occur.
  114. * @param off the offset position inside this buffer to start inserting
  115. * the copied bytes
  116. * @param in the array to copy the contents from
  117. * @param n the length of in
  118. */
  119. void copy(u32bit off, const T in[], u32bit n)
  120. { copy_mem(buf + off, in, (n > size() - off) ? (size() - off) : n); }
  121. /**
  122. * Set the contents of this according to the argument. The size of
  123. * *this is increased if necessary.
  124. * @param in the array of objects of type T to copy the contents from
  125. * @param n the size of array in
  126. */
  127. void set(const T in[], u32bit n) { create(n); copy(in, n); }
  128. /**
  129. * Set the contents of this according to the argument. The size of
  130. * *this is increased if necessary.
  131. * @param in the buffer to copy the contents from
  132. */
  133. void set(const MemoryRegion<T>& in) { set(in.begin(), in.size()); }
  134. /**
  135. * Append data to the end of this buffer.
  136. * @param data the array containing the data to append
  137. * @param n the size of the array data
  138. */
  139. void append(const T data[], u32bit n)
  140. { grow_to(size()+n); copy(size() - n, data, n); }
  141. /**
  142. * Append a single element.
  143. * @param x the element to append
  144. */
  145. void append(T x) { append(&x, 1); }
  146. /**
  147. * Append data to the end of this buffer.
  148. * @param data the buffer containing the data to append
  149. */
  150. void append(const MemoryRegion<T>& x) { append(x.begin(), x.size()); }
  151. /**
  152. * Zeroise the bytes of this buffer. The length remains unchanged.
  153. */
  154. void clear() { clear_mem(buf, allocated); }
  155. /**
  156. * Reset this buffer to an empty buffer with size zero.
  157. */
  158. void destroy() { create(0); }
  159. /**
  160. * Reset this buffer to a buffer of specified length. The content will be
  161. * initialized to zero bytes.
  162. * @param n the new length of the buffer
  163. */
  164. void create(u32bit n);
  165. /**
  166. * Preallocate memory, so that this buffer can grow up to size n without
  167. * having to perform any actual memory allocations. (This is
  168. * the same principle as for std::vector::reserve().)
  169. */
  170. void grow_to(u32bit N);
  171. /**
  172. * Swap this buffer with another object.
  173. */
  174. void swap(MemoryRegion<T>& other);
  175. ~MemoryRegion() { deallocate(buf, allocated); }
  176. protected:
  177. MemoryRegion() { buf = 0; alloc = 0; used = allocated = 0; }
  178. MemoryRegion(const MemoryRegion<T>& other)
  179. {
  180. buf = 0;
  181. used = allocated = 0;
  182. alloc = other.alloc;
  183. set(other.buf, other.used);
  184. }
  185. void init(bool locking, u32bit length = 0)
  186. { alloc = Allocator::get(locking); create(length); }
  187. private:
  188. T* allocate(u32bit n)
  189. {
  190. return static_cast<T*>(alloc->allocate(sizeof(T)*n));
  191. }
  192. void deallocate(T* p, u32bit n)
  193. { alloc->deallocate(p, sizeof(T)*n); }
  194. T* buf;
  195. u32bit used;
  196. u32bit allocated;
  197. Allocator* alloc;
  198. };
  199. /*
  200. * Create a new buffer
  201. */
  202. template<typename T>
  203. void MemoryRegion<T>::create(u32bit n)
  204. {
  205. if(n <= allocated) { clear(); used = n; return; }
  206. deallocate(buf, allocated);
  207. buf = allocate(n);
  208. allocated = used = n;
  209. }
  210. /*
  211. * Increase the size of the buffer
  212. */
  213. template<typename T>
  214. void MemoryRegion<T>::grow_to(u32bit n)
  215. {
  216. if(n > used && n <= allocated)
  217. {
  218. clear_mem(buf + used, n - used);
  219. used = n;
  220. return;
  221. }
  222. else if(n > allocated)
  223. {
  224. T* new_buf = allocate(n);
  225. copy_mem(new_buf, buf, used);
  226. deallocate(buf, allocated);
  227. buf = new_buf;
  228. allocated = used = n;
  229. }
  230. }
  231. /*
  232. * Compare this buffer with another one
  233. */
  234. template<typename T>
  235. bool MemoryRegion<T>::operator<(const MemoryRegion<T>& in) const
  236. {
  237. if(size() < in.size()) return true;
  238. if(size() > in.size()) return false;
  239. for(u32bit j = 0; j != size(); j++)
  240. {
  241. if(buf[j] < in[j]) return true;
  242. if(buf[j] > in[j]) return false;
  243. }
  244. return false;
  245. }
  246. /*
  247. * Swap this buffer with another one
  248. */
  249. template<typename T>
  250. void MemoryRegion<T>::swap(MemoryRegion<T>& x)
  251. {
  252. std::swap(buf, x.buf);
  253. std::swap(used, x.used);
  254. std::swap(allocated, x.allocated);
  255. std::swap(alloc, x.alloc);
  256. }
  257. /**
  258. * This class represents variable length buffers that do not
  259. * make use of memory locking.
  260. */
  261. template<typename T>
  262. class MemoryVector : public MemoryRegion<T>
  263. {
  264. public:
  265. /**
  266. * Copy the contents of another buffer into this buffer.
  267. * @param in the buffer to copy the contents from
  268. * @return a reference to *this
  269. */
  270. MemoryVector<T>& operator=(const MemoryRegion<T>& in)
  271. { if(this != &in) set(in); return (*this); }
  272. /**
  273. * Create a buffer of the specified length.
  274. * @param n the length of the buffer to create.
  275. */
  276. MemoryVector(u32bit n = 0) { MemoryRegion<T>::init(false, n); }
  277. /**
  278. * Create a buffer with the specified contents.
  279. * @param in the array containing the data to be initially copied
  280. * into the newly created buffer
  281. * @param n the size of the arry in
  282. */
  283. MemoryVector(const T in[], u32bit n)
  284. { MemoryRegion<T>::init(false); set(in, n); }
  285. /**
  286. * Copy constructor.
  287. */
  288. MemoryVector(const MemoryRegion<T>& in)
  289. { MemoryRegion<T>::init(false); set(in); }
  290. /**
  291. * Create a buffer whose content is the concatenation of two other
  292. * buffers.
  293. * @param in1 the first part of the new contents
  294. * @param in2 the contents to be appended to in1
  295. */
  296. MemoryVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
  297. { MemoryRegion<T>::init(false); set(in1); append(in2); }
  298. };
  299. /**
  300. * This class represents variable length buffers using the operating
  301. * systems capability to lock memory, i.e. keeping it from being
  302. * swapped out to disk. In this way, a security hole allowing attackers
  303. * to find swapped out secret keys is closed. Please refer to
  304. * Botan::InitializerOptions::secure_memory() for restrictions and
  305. * further details.
  306. */
  307. template<typename T>
  308. class SecureVector : public MemoryRegion<T>
  309. {
  310. public:
  311. /**
  312. * Copy the contents of another buffer into this buffer.
  313. * @param in the buffer to copy the contents from
  314. * @return a reference to *this
  315. */
  316. SecureVector<T>& operator=(const MemoryRegion<T>& in)
  317. { if(this != &in) set(in); return (*this); }
  318. /**
  319. * Create a buffer of the specified length.
  320. * @param n the length of the buffer to create.
  321. */
  322. SecureVector(u32bit n = 0) { MemoryRegion<T>::init(true, n); }
  323. /**
  324. * Create a buffer with the specified contents.
  325. * @param in the array containing the data to be initially copied
  326. * into the newly created buffer
  327. * @param n the size of the array in
  328. */
  329. SecureVector(const T in[], u32bit n)
  330. { MemoryRegion<T>::init(true); set(in, n); }
  331. /**
  332. * Create a buffer with contents specified contents.
  333. * @param in the buffer holding the contents that will be
  334. * copied into the newly created buffer.
  335. */
  336. SecureVector(const MemoryRegion<T>& in)
  337. { MemoryRegion<T>::init(true); set(in); }
  338. /**
  339. * Create a buffer whose content is the concatenation of two other
  340. * buffers.
  341. * @param in1 the first part of the new contents
  342. * @param in2 the contents to be appended to in1
  343. */
  344. SecureVector(const MemoryRegion<T>& in1, const MemoryRegion<T>& in2)
  345. { MemoryRegion<T>::init(true); set(in1); append(in2); }
  346. };
  347. /**
  348. * This class represents fixed length buffers using the operating
  349. * systems capability to lock memory, i.e. keeping it from being
  350. * swapped out to disk. In this way, a security hole allowing attackers
  351. * to find swapped out secret keys is closed. Please refer to
  352. * Botan::InitializerOptions::secure_memory() for restrictions and
  353. * further details.
  354. */
  355. template<typename T, u32bit L>
  356. class SecureBuffer : public MemoryRegion<T>
  357. {
  358. public:
  359. /**
  360. * Copy the contents of another buffer into this buffer.
  361. * @param in the buffer to copy the contents from
  362. * @return a reference to *this
  363. */
  364. SecureBuffer<T,L>& operator=(const SecureBuffer<T,L>& in)
  365. { if(this != &in) set(in); return (*this); }
  366. /**
  367. * Create a buffer of the length L.
  368. */
  369. SecureBuffer() { MemoryRegion<T>::init(true, L); }
  370. /**
  371. * Create a buffer of size L with the specified contents.
  372. * @param in the array containing the data to be initially copied
  373. * into the newly created buffer
  374. * @param n the size of the array in
  375. */
  376. SecureBuffer(const T in[], u32bit n)
  377. { MemoryRegion<T>::init(true, L); copy(in, n); }
  378. private:
  379. SecureBuffer<T, L>& operator=(const MemoryRegion<T>& in)
  380. { if(this != &in) set(in); return (*this); }
  381. };
  382. }
  383. #endif