Make Sha256State safe.
GitOrigin-RevId: 9b81cc1915b8ca1bc85219b863a6e8dcab814b37
This commit is contained in:
parent
4ee295a29e
commit
ac6a83da50
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user