My Project 3.7.1
C++ Distributed Hash Table
Loading...
Searching...
No Matches
secure_vector.h
1// Copyright (c) 2014-2026 Savoir-faire Linux Inc.
2// SPDX-License-Identifier: MIT
3#pragma once
4
5#include <vector>
6#include <random>
7
8namespace dht {
9namespace crypto {
10
11template<class T>
12class secure_vector
13{
14public:
15 secure_vector() {}
16 secure_vector(secure_vector<T> const&) = default;
17 secure_vector(secure_vector<T>&&) = default;
18 explicit secure_vector(unsigned size)
19 : data_(size)
20 {}
21 explicit secure_vector(unsigned size, T _item)
22 : data_(size, _item)
23 {}
24 explicit secure_vector(const std::vector<T>& c)
25 : data_(c)
26 {}
27 secure_vector(std::vector<T>&& c)
28 : data_(std::move(c))
29 {}
30 ~secure_vector() { clean(); }
31
32 static secure_vector<T> getRandom(size_t size)
33 {
34 secure_vector<T> ret(size);
35 std::random_device rdev;
36#ifdef _WIN32
37 std::uniform_int_distribution<int> rand_byte {0, std::numeric_limits<uint8_t>::max()};
38#else
39 std::uniform_int_distribution<uint8_t> rand_byte;
40#endif
41 std::generate_n((uint8_t*) ret.data_.data(), ret.size() * sizeof(T), std::bind(rand_byte, std::ref(rdev)));
42 return ret;
43 }
44 secure_vector<T>& operator=(const secure_vector<T>& c)
45 {
46 if (&c == this)
47 return *this;
48 clean();
49 data_ = c.data_;
50 return *this;
51 }
52 secure_vector<T>& operator=(secure_vector<T>&& c)
53 {
54 if (&c == this)
55 return *this;
56 clean();
57 data_ = std::move(c.data_);
58 return *this;
59 }
60 secure_vector<T>& operator=(std::vector<T>&& c)
61 {
62 clean();
63 data_ = std::move(c);
64 return *this;
65 }
66 std::vector<T>& writable()
67 {
68 clean();
69 return data_;
70 }
71 const std::vector<T>& makeInsecure() const { return data_; }
72 const uint8_t* data() const { return data_.data(); }
73
74 void clean() { clean(data_.begin(), data_.end()); }
75
76 void clear()
77 {
78 clean();
79 data_.clear();
80 }
81
82 size_t size() const { return data_.size(); }
83 bool empty() const { return data_.empty(); }
84
85 void swap(secure_vector<T>& other) { data_.swap(other.data_); }
86 void resize(size_t s)
87 {
88 if (s == data_.size())
89 return;
90 if (s < data_.size()) {
91 // shrink
92 clean(data_.begin() + s, data_.end());
93 data_.resize(s);
94 } else {
95 // grow
96 auto data = std::move(data_); // move protected data
97 clear();
98 data_.resize(s);
99 std::copy(data.begin(), data.end(), data_.begin());
100 clean(data.begin(), data.end());
101 }
102 }
103
104private:
108 static void clean(const typename std::vector<T>::iterator& i, const typename std::vector<T>::iterator& j)
109 {
110 volatile uint8_t* b = reinterpret_cast<uint8_t*>(&*i);
111 volatile uint8_t* e = reinterpret_cast<uint8_t*>(&*j);
112 std::fill(b, e, 0);
113 }
114
115 std::vector<T> data_;
116};
117
118using SecureBlob = secure_vector<uint8_t>;
119
120} // namespace crypto
121} // namespace dht