Make Sha256State safe.

GitOrigin-RevId: 9b81cc1915b8ca1bc85219b863a6e8dcab814b37
This commit is contained in:
levlam 2019-07-23 03:26:26 +03:00
parent 4ee295a29e
commit ac6a83da50
3 changed files with 37 additions and 6 deletions

View File

@ -382,20 +382,42 @@ struct Sha256StateImpl {
};
Sha256State::Sha256State() = default;
Sha256State::Sha256State(Sha256State &&from) = default;
Sha256State &Sha256State::operator=(Sha256State &&from) = default;
Sha256State::~Sha256State() = default;
Sha256State::Sha256State(Sha256State &&other) {
impl = std::move(other.impl);
is_inited = other.is_inited;
other.is_inited = false;
}
Sha256State &Sha256State::operator=(Sha256State &&other) {
Sha256State copy(std::move(other));
using std::swap;
swap(impl, copy.impl);
swap(is_inited, copy.is_inited);
return *this;
}
Sha256State::~Sha256State() {
if (is_inited) {
char result[32];
extract(MutableSlice{result, 32});
CHECK(!is_inited);
}
}
void sha256_init(Sha256State *state) {
if (!state->impl) {
state->impl = make_unique<Sha256StateImpl>();
}
CHECK(!state->is_inited);
int err = SHA256_Init(&state->impl->ctx);
LOG_IF(FATAL, err != 1);
state->is_inited = true;
}
void sha256_update(Slice data, Sha256State *state) {
CHECK(state->impl);
CHECK(state->is_inited);
int err = SHA256_Update(&state->impl->ctx, data.ubegin(), data.size());
LOG_IF(FATAL, err != 1);
}
@ -403,8 +425,10 @@ void sha256_update(Slice data, Sha256State *state) {
void sha256_final(Sha256State *state, MutableSlice output, bool destroy) {
CHECK(output.size() >= 32);
CHECK(state->impl);
CHECK(state->is_inited);
int err = SHA256_Final(output.ubegin(), &state->impl->ctx);
LOG_IF(FATAL, err != 1);
state->is_inited = false;
if (destroy) {
state->impl.reset();
}

View File

@ -78,9 +78,12 @@ void sha256_final(Sha256State *state, MutableSlice output, bool destroy = true);
struct Sha256State {
Sha256State();
Sha256State(Sha256State &&from);
Sha256State &operator=(Sha256State &&from);
Sha256State(const Sha256State &other) = delete;
Sha256State &operator=(const Sha256State &other) = delete;
Sha256State(Sha256State &&other);
Sha256State &operator=(Sha256State &&other);
~Sha256State();
void init() {
sha256_init(this);
}
@ -90,7 +93,9 @@ struct Sha256State {
void extract(MutableSlice dest) {
sha256_final(this, dest, false);
}
unique_ptr<Sha256StateImpl> impl;
bool is_inited = false;
};
void md5(Slice input, MutableSlice output);

View File

@ -72,10 +72,12 @@ TEST(Crypto, Sha256State) {
td::Sha256State state;
state.init();
td::Sha256State state2 = std::move(state);
auto v = td::rand_split(s);
for (auto &x : v) {
state.feed(x);
state2.feed(x);
}
state = std::move(state2);
td::UInt256 result;
state.extract(as_slice(result));
ASSERT_TRUE(baseline == result);