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() = default;
|
||||||
Sha256State::Sha256State(Sha256State &&from) = default;
|
|
||||||
Sha256State &Sha256State::operator=(Sha256State &&from) = default;
|
Sha256State::Sha256State(Sha256State &&other) {
|
||||||
Sha256State::~Sha256State() = default;
|
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) {
|
void sha256_init(Sha256State *state) {
|
||||||
if (!state->impl) {
|
if (!state->impl) {
|
||||||
state->impl = make_unique<Sha256StateImpl>();
|
state->impl = make_unique<Sha256StateImpl>();
|
||||||
}
|
}
|
||||||
|
CHECK(!state->is_inited);
|
||||||
int err = SHA256_Init(&state->impl->ctx);
|
int err = SHA256_Init(&state->impl->ctx);
|
||||||
LOG_IF(FATAL, err != 1);
|
LOG_IF(FATAL, err != 1);
|
||||||
|
state->is_inited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sha256_update(Slice data, Sha256State *state) {
|
void sha256_update(Slice data, Sha256State *state) {
|
||||||
CHECK(state->impl);
|
CHECK(state->impl);
|
||||||
|
CHECK(state->is_inited);
|
||||||
int err = SHA256_Update(&state->impl->ctx, data.ubegin(), data.size());
|
int err = SHA256_Update(&state->impl->ctx, data.ubegin(), data.size());
|
||||||
LOG_IF(FATAL, err != 1);
|
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) {
|
void sha256_final(Sha256State *state, MutableSlice output, bool destroy) {
|
||||||
CHECK(output.size() >= 32);
|
CHECK(output.size() >= 32);
|
||||||
CHECK(state->impl);
|
CHECK(state->impl);
|
||||||
|
CHECK(state->is_inited);
|
||||||
int err = SHA256_Final(output.ubegin(), &state->impl->ctx);
|
int err = SHA256_Final(output.ubegin(), &state->impl->ctx);
|
||||||
LOG_IF(FATAL, err != 1);
|
LOG_IF(FATAL, err != 1);
|
||||||
|
state->is_inited = false;
|
||||||
if (destroy) {
|
if (destroy) {
|
||||||
state->impl.reset();
|
state->impl.reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,9 +78,12 @@ void sha256_final(Sha256State *state, MutableSlice output, bool destroy = true);
|
||||||
|
|
||||||
struct Sha256State {
|
struct Sha256State {
|
||||||
Sha256State();
|
Sha256State();
|
||||||
Sha256State(Sha256State &&from);
|
Sha256State(const Sha256State &other) = delete;
|
||||||
Sha256State &operator=(Sha256State &&from);
|
Sha256State &operator=(const Sha256State &other) = delete;
|
||||||
|
Sha256State(Sha256State &&other);
|
||||||
|
Sha256State &operator=(Sha256State &&other);
|
||||||
~Sha256State();
|
~Sha256State();
|
||||||
|
|
||||||
void init() {
|
void init() {
|
||||||
sha256_init(this);
|
sha256_init(this);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +93,9 @@ struct Sha256State {
|
||||||
void extract(MutableSlice dest) {
|
void extract(MutableSlice dest) {
|
||||||
sha256_final(this, dest, false);
|
sha256_final(this, dest, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<Sha256StateImpl> impl;
|
unique_ptr<Sha256StateImpl> impl;
|
||||||
|
bool is_inited = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
void md5(Slice input, MutableSlice output);
|
void md5(Slice input, MutableSlice output);
|
||||||
|
|
|
@ -72,10 +72,12 @@ TEST(Crypto, Sha256State) {
|
||||||
|
|
||||||
td::Sha256State state;
|
td::Sha256State state;
|
||||||
state.init();
|
state.init();
|
||||||
|
td::Sha256State state2 = std::move(state);
|
||||||
auto v = td::rand_split(s);
|
auto v = td::rand_split(s);
|
||||||
for (auto &x : v) {
|
for (auto &x : v) {
|
||||||
state.feed(x);
|
state2.feed(x);
|
||||||
}
|
}
|
||||||
|
state = std::move(state2);
|
||||||
td::UInt256 result;
|
td::UInt256 result;
|
||||||
state.extract(as_slice(result));
|
state.extract(as_slice(result));
|
||||||
ASSERT_TRUE(baseline == result);
|
ASSERT_TRUE(baseline == result);
|
||||||
|
|
Reference in New Issue
Block a user