11 #ifndef __DECAF_SECURE_BUFFER_HXX__ 12 #define __DECAF_SECURE_BUFFER_HXX__ 1 15 #include <sys/types.h> 22 #if defined(_MSC_VER) // MSVC does not have built in posix_memalign 23 #define posix_memalign(p, a, s) (((*(p)) = _aligned_malloc((s), (a))), *(p) ?0 :errno) 27 #if __cplusplus >= 201103L 28 #define DECAF_NOEXCEPT noexcept 29 #define DECAF_DELETE = delete 31 #define DECAF_NOEXCEPT throw() 41 static inline void really_bzero(
void *data,
size_t size) {
decaf_bzero(data,size); }
50 typedef const T* const_pointer;
52 typedef const T& const_reference;
53 typedef size_t size_type;
54 typedef std::ptrdiff_t difference_type;
62 inline T* address(T& r)
const DECAF_NOEXCEPT {
return &r; }
63 inline const T* address(
const T& r)
const DECAF_NOEXCEPT {
return &r; }
66 typename std::allocator<void>::const_pointer = 0
68 inline void deallocate(T* p,
size_t size) DECAF_NOEXCEPT;
69 inline size_t max_size()
const DECAF_NOEXCEPT {
return std::numeric_limits<size_t>::max() /
sizeof(T); }
70 inline void construct(T* p,
const T& t) {
new(p) T(t); }
71 inline void destroy(T* p) { p->~T(); }
79 typedef std::vector<unsigned char, SanitizingAllocator<unsigned char, 0> >
SecureBuffer;
82 template<
class T,
class U,
class V,
class W>
83 inline bool memeq(
const std::vector<T,U> &a,
const std::vector<V,W> &b) {
84 if (a.size() != b.size())
return false;
92 inline size_t ser_size() const DECAF_NOEXCEPT {
return static_cast<const Base*
>(
this)->
ser_size(); }
96 static_cast<const Base*
>(
this)->serialize_into(buf);
101 SecureBuffer out(ser_size());
102 serialize_into(out.data());
107 #if __cplusplus >= 201103L 122 virtual const char *
what() const DECAF_NOEXCEPT {
return "CryptoException"; }
129 virtual const char *
what() const DECAF_NOEXCEPT {
return "LengthException"; }
144 Rng(
const Rng &) DECAF_DELETE;
147 Rng &operator=(
const Rng &) DECAF_DELETE;
151 virtual void read(
Buffer buffer) DECAF_NOEXCEPT = 0;
154 inline SecureBuffer read(
size_t length) ;
162 unsigned char *data_;
164 const bool zero_on_destroy_;
169 inline Block() : data_(NULL), size_(0), zero_on_destroy_(false) {}
172 inline Block(
const char *data) DECAF_NOEXCEPT : data_((
unsigned char *)data),
173 size_(strlen(data)), zero_on_destroy_(
false) {}
176 inline Block(
const unsigned char *data,
size_t size,
bool zero_on_destroy=
false) DECAF_NOEXCEPT : data_((
unsigned char *)data),
177 size_(size), zero_on_destroy_(zero_on_destroy) {}
180 inline Block(
const std::string &s) : data_(
181 #if __cplusplus >= 201103L
182 ((unsigned char *)&(s)[0])
184 ((unsigned char *)(s.data()))
186 ), size_(s.size()), zero_on_destroy_(false) {}
189 template<
class alloc>
inline Block(
const std::vector<unsigned char,alloc> &s)
190 : data_(((unsigned char *)&(s)[0])), size_(s.size()), zero_on_destroy_(false) {}
193 inline const unsigned char *
data() const DECAF_NOEXCEPT {
return data_; }
197 if (off >= size())
throw(std::out_of_range(
"decaf::Block"));
202 inline size_t size() const DECAF_NOEXCEPT {
return size_; }
206 return std::string((
const char *)data_,size_);
212 return Block(data()+off, length);
217 if (b.size() != size())
return false;
227 inline void zeroize() DECAF_NOEXCEPT { really_bzero(data_,size()); }
231 if (name) printf(
"%s = ", name);
232 for (
size_t s = 0; s < size(); s++) printf(
"%02x", data_[s]);
238 inline decaf_bool_t operator>=(
const Block &b)
const DECAF_NOEXCEPT DECAF_DELETE;
239 inline decaf_bool_t operator<=(
const Block &b)
const DECAF_NOEXCEPT DECAF_DELETE;
240 inline decaf_bool_t operator> (
const Block &b)
const DECAF_NOEXCEPT DECAF_DELETE;
241 inline decaf_bool_t operator< (
const Block &b)
const DECAF_NOEXCEPT DECAF_DELETE;
242 inline void operator= (
const Block &b)
const DECAF_NOEXCEPT DECAF_DELETE;
255 template<
class alloc>
inline FixedBlock(
const std::vector<unsigned char,alloc> &s) :
Block(s) {
260 inline explicit FixedBlock(
const uint8_t data[Size]) DECAF_NOEXCEPT :
Block(data,Size) {}
270 inline Buffer(
unsigned char *data,
size_t size,
bool zero_on_destroy=
false) DECAF_NOEXCEPT :
Block(data,size,zero_on_destroy) {}
273 template<
class alloc>
inline Buffer(std::vector<unsigned char,alloc> &s) :
Block(s) {}
276 inline const unsigned char *
data() const DECAF_NOEXCEPT {
return data_; }
279 inline unsigned char*
data() DECAF_NOEXCEPT {
return data_; }
282 inline Buffer slice(
size_t off,
size_t length) ;
286 if (off >= size())
throw(std::out_of_range(
"decaf::Buffer"));
293 memmove(data(),b.
data(),size());
298 inline void operator= (
const Block &b)
const DECAF_NOEXCEPT DECAF_DELETE;
317 inline explicit FixedBuffer(uint8_t dat[Size],
bool zero_on_destroy =
false) DECAF_NOEXCEPT :
Buffer(dat,Size,zero_on_destroy) {}
326 inline void operator= (
const Block &b)
const DECAF_NOEXCEPT DECAF_DELETE;
333 uint8_t storage[Size];
348 memcpy(storage,b.
data(),Size);
353 memcpy(storage,b.
data(),Size);
return *
this;
358 memcpy(storage,b.
data(),Size);
return *
this;
369 memcpy(storage,b.
data(),Size);
374 memcpy(storage,b.
data(),Size);
384 return Buffer(data()+off, length);
387 inline SecureBuffer
Rng::read(
size_t length) {
388 SecureBuffer out(length); read(out);
return out;
396 template <
class T,
class Wrapped>
397 class OwnedOrUnowned {
401 const Wrapped *yours;
405 inline void clear() DECAF_NOEXCEPT {
407 really_bzero(ours.mine, T::size());
409 ours.yours = T::default_value();
413 inline void alloc() {
415 int ret = posix_memalign((
void**)&ours.mine, T::alignment(), T::size());
416 if (ret || !ours.mine) {
418 throw std::bad_alloc();
422 inline const Wrapped *
get()
const DECAF_NOEXCEPT {
return is_mine ? ours.mine : ours.yours; }
424 inline OwnedOrUnowned(
425 const Wrapped &yours = *T::default_value()
434 inline T &operator=(
const OwnedOrUnowned &it) {
435 if (
this == &it)
return *(T*)
this;
438 memcpy(ours.mine,it.ours.mine,T::size());
441 ours.yours = it.ours.yours;
443 is_mine = it.is_mine;
447 #if __cplusplus >= 201103L 448 inline T &operator=(OwnedOrUnowned &&it) DECAF_NOEXCEPT {
449 if (
this == &it)
return *(T*)
this;
452 is_mine = it.is_mine;
454 it.ours.yours = T::default_value;
466 template<
typename T,
size_t alignment>
469 typename std::allocator<void>::const_pointer
474 if (alignment) ret = posix_memalign(&v, alignment, cnt *
sizeof(T));
475 else v = malloc(cnt *
sizeof(T));
477 if (ret || v==NULL)
throw(std::bad_alloc());
478 return reinterpret_cast<T*
>(v);
481 template<
typename T,
size_t alignment>
484 really_bzero(reinterpret_cast<void*>(p), size);
485 free(reinterpret_cast<void*>(p));
493 #undef DECAF_NOEXCEPT FixedBuffer(uint8_t dat[Size], bool zero_on_destroy=false) DECAF_NOEXCEPT
Explicitly pass a C buffer.
Definition: secure_buffer.hxx:317
const unsigned char & operator[](size_t off) const
Subscript.
Definition: secure_buffer.hxx:196
Passed to constructors to avoid (conservative) initialization.
Definition: secure_buffer.hxx:133
Block(const unsigned char *data, size_t size, bool zero_on_destroy=false) DECAF_NOEXCEPT
Unowned init.
Definition: secure_buffer.hxx:176
An exception for when crypto (ie point decode) has failed.
Definition: secure_buffer.hxx:119
bool memeq(const std::vector< T, U > &a, const std::vector< V, W > &b)
Constant-time compare two buffers.
Definition: secure_buffer.hxx:83
A fixed-size block.
Definition: secure_buffer.hxx:304
unsigned char * data() DECAF_NOEXCEPT
Cast to unsigned char.
Definition: secure_buffer.hxx:279
Buffer(unsigned char *data, size_t size, bool zero_on_destroy=false) DECAF_NOEXCEPT
Unowned init.
Definition: secure_buffer.hxx:270
FixedBuffer(Buffer b)
Check a block's length.
Definition: secure_buffer.hxx:307
FixedArrayBuffer & operator=(const FixedArrayBuffer< Size > &b) DECAF_NOEXCEPT
Copy operator.
Definition: secure_buffer.hxx:357
Buffer(std::vector< unsigned char, alloc > &s)
Block from std::vector.
Definition: secure_buffer.hxx:273
FixedBlock(const uint8_t data[Size]) DECAF_NOEXCEPT
Explicitly pass a C buffer.
Definition: secure_buffer.hxx:260
void debug_print_hex(const char *name=NULL)
Debugging print in hex.
Definition: secure_buffer.hxx:230
Block(const std::vector< unsigned char, alloc > &s)
Block from std::vector.
Definition: secure_buffer.hxx:189
A reference to a writable block of data.
Definition: secure_buffer.hxx:264
FixedArrayBuffer(const NOINIT &) DECAF_NOEXCEPT
New uninitialized buffer.
Definition: secure_buffer.hxx:341
Prototype of a random number generator.
Definition: secure_buffer.hxx:138
Block(const char *data) DECAF_NOEXCEPT
Init from C string.
Definition: secure_buffer.hxx:172
FixedBlock(const std::vector< unsigned char, alloc > &s)
Block from std::vector.
Definition: secure_buffer.hxx:255
virtual void read(Buffer buffer) DECAF_NOEXCEPT=0
Read into a Buffer.
An allocator which zeros its memory on free.
Definition: secure_buffer.hxx:44
FixedArrayBuffer() DECAF_NOEXCEPT
New buffer initialized to zero.
Definition: secure_buffer.hxx:338
Block()
Null initialization.
Definition: secure_buffer.hxx:169
decaf_bool_t DECAF_API_VIS decaf_memeq(const void *data1, const void *data2, size_t size) DECAF_NONNULL DECAF_WARN_UNUSED
Compare two buffers, returning DECAF_TRUE if they are equal.
virtual const char * what() const DECAF_NOEXCEPT
Definition: secure_buffer.hxx:129
void assign(const Block b)
Copy from another block.
Definition: secure_buffer.hxx:291
std::string get_string() const
Convert to C++ string.
Definition: secure_buffer.hxx:205
FixedArrayBuffer(Rng &r) DECAF_NOEXCEPT
New random buffer.
Definition: secure_buffer.hxx:344
An exception for when crypto (ie point decode) has failed.
Definition: secure_buffer.hxx:126
FixedBuffer(SecureBuffer &b)
Check a block's length.
Definition: secure_buffer.hxx:312
Buffer slice(size_t off, size_t length)
Slice the buffer.
Base class of objects which support serialization.
Definition: secure_buffer.hxx:89
SecureBuffer serialize() const
Serialize this object into a SecureBuffer and return it.
Definition: secure_buffer.hxx:100
A fixed-size block.
Definition: secure_buffer.hxx:247
std::vector< unsigned char, SanitizingAllocator< unsigned char, 0 > > SecureBuffer
A variant of std::vector which securely zerozes its state when destructed.
Definition: secure_buffer.hxx:79
FixedBlock(const Block &b)
Check a block's length.
Definition: secure_buffer.hxx:250
FixedArrayBuffer & operator=(const FixedBlock< Size > &b) DECAF_NOEXCEPT
Copy operator.
Definition: secure_buffer.hxx:352
void serialize_into(unsigned char *buf) const DECAF_NOEXCEPT
Serialize this object into a buffer.
Definition: secure_buffer.hxx:95
~FixedArrayBuffer() DECAF_NOEXCEPT
Destroy the buffer.
Definition: secure_buffer.hxx:378
size_t ser_size() const DECAF_NOEXCEPT
Return the number of bytes needed to serialize this object.
Definition: secure_buffer.hxx:92
uint32_t decaf_bool_t
"Boolean" type, will be set to all-zero or all-one (i.e.
Definition: common.h:89
Rng()
Empty initializer.
Definition: secure_buffer.hxx:141
const unsigned char * data() const DECAF_NOEXCEPT
Get const data.
Definition: secure_buffer.hxx:276
A reference to a block of data, which (when accessed through this base class) is const.
Definition: secure_buffer.hxx:159
FixedArrayBuffer(const FixedArrayBuffer< Size > &b) DECAF_NOEXCEPT
Copy constructor.
Definition: secure_buffer.hxx:373
Block(const std::string &s)
Block from std::string.
Definition: secure_buffer.hxx:180
FixedArrayBuffer & operator=(const Block &b)
Copy operator.
Definition: secure_buffer.hxx:362
void DECAF_API_VIS decaf_bzero(void *data, size_t size) DECAF_NONNULL
Overwrite data with zeros.
A fixed-size stack-allocated buffer (for DECAF_NOEXCEPT semantics)
Definition: secure_buffer.hxx:331
FixedArrayBuffer(const Block &b)
Copy constructor.
Definition: secure_buffer.hxx:367
FixedArrayBuffer(const FixedBlock< Size > &b) DECAF_NOEXCEPT
Copy constructor.
Definition: secure_buffer.hxx:347
Block slice(size_t off, size_t length) const
Slice the buffer.
Definition: secure_buffer.hxx:210
const unsigned char * data() const DECAF_NOEXCEPT
Get const data.
Definition: secure_buffer.hxx:193
unsigned char & operator[](size_t off)
Subscript.
Definition: secure_buffer.hxx:285
decaf_bool_t contents_equal(const Block &b) const DECAF_NOEXCEPT
Content-wise comparison; constant-time if they are the same length.
Definition: secure_buffer.hxx:216
Namespace for all libdecaf C++ objects.
Definition: ed255.hxx:41
size_t size() const DECAF_NOEXCEPT
Get the size.
Definition: secure_buffer.hxx:202
void zeroize() DECAF_NOEXCEPT
Securely set the buffer to 0.
Definition: secure_buffer.hxx:227
virtual const char * what() const DECAF_NOEXCEPT
Definition: secure_buffer.hxx:122
Buffer() DECAF_NOEXCEPT
Null init.
Definition: secure_buffer.hxx:267