-
Notifications
You must be signed in to change notification settings - Fork 5
/
secure_allocator.h
80 lines (67 loc) · 2.08 KB
/
secure_allocator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#ifndef SECURE_ALLOC_H
#define SECURE_ALLOC_H
#include <cstring>
#include <memory>
#include <string>
#include <vector>
// for now the only purpose of secure allocator is to clear senstive data
// from memory during deallocation in a hostile environment
//
// It is not necessary for a tamper-proof environment
// so define or undef USE_SECURE_ALLOCATOR to suit your own need
//
// Migrating the code into a custom allocator also allows flexiblity in
// design depending on the target memory model
//
#ifdef USE_SECURE_ALLOCATOR
template <typename T>
class default_secure_allocator : public std::allocator<T>
{
public:
typedef size_t size_type;
typedef T* pointer;
typedef const T* const_pointer;
template <typename U>
struct rebind {
typedef default_secure_allocator<U> other;
};
pointer allocate(size_type n, const void* hint = 0)
{
return std::allocator<T>::allocate(n, hint);
}
void deallocate(pointer p, size_type n)
{
if constexpr (std::is_trivial_v<T>) {
std::memset(p, 0, n * sizeof(T));
}
return std::allocator<T>::deallocate(p, n);
}
default_secure_allocator() throw() : std::allocator<T>(){};
default_secure_allocator(const default_secure_allocator& a) throw() : std::allocator<T>(a) {}
template <typename U>
default_secure_allocator(const default_secure_allocator<U>& a) throw() : std::allocator<T>(a) {}
~default_secure_allocator() throw() {}
};
using secure_vector = std::vector<uint8_t, default_secure_allocator<uint8_t>>;
using secure_string = std::basic_string<char, std::char_traits<char>, default_secure_allocator<char>>;
namespace std
{
template <>
struct hash<secure_string> {
size_t operator()(const secure_string& k) const
{
size_t h = 5381;
for (auto& x : k) {
h = 33 * h ^ static_cast<unsigned char>(x);
}
return h;
}
};
}; // namespace std
#else
using secure_vector = std::vector<uint8_t>;
using secure_string = std::string;
template <typename T>
using default_secure_allocator = std::allocator<T>;
#endif
#endif