My Project 3.2.0
C++ Distributed Hash Table
Loading...
Searching...
No Matches
secure_vector.h
1/*
2 * Copyright (C) 2014-2023 Savoir-faire Linux Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17#pragma once
18
19#include <vector>
20#include <random>
21
22namespace dht {
23namespace crypto {
24
25template <class T>
26class secure_vector
27{
28public:
29 secure_vector() {}
30 secure_vector(secure_vector<T> const&) = default;
31 secure_vector(secure_vector<T> &&) = default;
32 explicit secure_vector(unsigned size): data_(size) {}
33 explicit secure_vector(unsigned size, T _item): data_(size, _item) {}
34 explicit secure_vector(const std::vector<T>& c): data_(c) {}
35 secure_vector(std::vector<T>&& c): data_(std::move(c)) {}
36 ~secure_vector() { clean(); }
37
38 static secure_vector<T> getRandom(size_t size) {
39 secure_vector<T> ret(size);
40 std::random_device rdev;
41#ifdef _WIN32
42 std::uniform_int_distribution<int> rand_byte{ 0, std::numeric_limits<uint8_t>::max() };
43#else
44 std::uniform_int_distribution<uint8_t> rand_byte;
45#endif
46 std::generate_n((uint8_t*)ret.data_.data(), ret.size()*sizeof(T), std::bind(rand_byte, std::ref(rdev)));
47 return ret;
48 }
49 secure_vector<T>& operator=(const secure_vector<T>& c) {
50 if (&c == this)
51 return *this;
52 clean();
53 data_ = c.data_;
54 return *this;
55 }
56 secure_vector<T>& operator=(secure_vector<T>&& c) {
57 if (&c == this)
58 return *this;
59 clean();
60 data_ = std::move(c.data_);
61 return *this;
62 }
63 secure_vector<T>& operator=(std::vector<T>&& c) {
64 clean();
65 data_ = std::move(c);
66 return *this;
67 }
68 std::vector<T>& writable() { clean(); return data_; }
69 const std::vector<T>& makeInsecure() const { return data_; }
70 const uint8_t* data() const { return data_.data(); }
71
72 void clean() {
73 clean(data_.begin(), data_.end());
74 }
75
76 void clear() { clean(); data_.clear(); }
77
78 size_t size() const { return data_.size(); }
79 bool empty() const { return data_.empty(); }
80
81 void swap(secure_vector<T>& other) { data_.swap(other.data_); }
82 void resize(size_t s) {
83 if (s == data_.size()) return;
84 if (s < data_.size()) {
85 //shrink
86 clean(data_.begin()+s, data_.end());
87 data_.resize(s);
88 } else {
89 //grow
90 auto data = std::move(data_); // move protected data
91 clear();
92 data_.resize(s);
93 std::copy(data.begin(), data.end(), data_.begin());
94 clean(data.begin(), data.end());
95 }
96 }
97
98private:
102 static void clean(const typename std::vector<T>::iterator& i, const typename std::vector<T>::iterator& j) {
103 volatile uint8_t* b = reinterpret_cast<uint8_t*>(&*i);
104 volatile uint8_t* e = reinterpret_cast<uint8_t*>(&*j);
105 std::fill(b, e, 0);
106 }
107
108 std::vector<T> data_;
109};
110
111using SecureBlob = secure_vector<uint8_t>;
112
113}
114}