Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix how evercrypt hashing is called #1098

Merged
merged 4 commits into from
Apr 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ static void run_mt_benchmark(picobench::state& s, std::vector<uint8_t> data)
s.start_timer();
for (int i = 0; i < s.iterations(); i++)
{
crypto::Sha256Hash rh({{data.data(), data.size()}});
crypto::Sha256Hash rh({data.data(), data.size()});
tree.append(rh);
clobber_memory();
}
Expand Down
4 changes: 2 additions & 2 deletions src/consensus/pbft/pbft_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ namespace pbft
auto pp_view = tx.get_view(pbft_pre_prepares_map);
pp_view->put(0, pp);
auto sig_view = tx.get_view(signatures);
ccf::Signature sig_value({root});
ccf::Signature sig_value(root);
sig_view->put(0, sig_value);
return tx.commit_reserved();
},
Expand All @@ -122,7 +122,7 @@ namespace pbft
if (p)
{
auto sig_view = tx.get_view(signatures);
ccf::Signature sig_value({root});
ccf::Signature sig_value(root);
sig_view->put(0, sig_value);
auto success = tx.commit();
if (success == kv::CommitSuccess::OK)
Expand Down
36 changes: 19 additions & 17 deletions src/crypto/hash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,45 @@ extern "C"

using namespace std;

void crypto::Sha256Hash::mbedtls_sha256(
initializer_list<CBuffer> il, uint8_t* h)
void crypto::Sha256Hash::mbedtls_sha256(const CBuffer& data, uint8_t* h)
{
mbedtls_sha256_context ctx;
mbedtls_sha256_starts_ret(&ctx, 0);

for (auto data : il)
{
mbedtls_sha256_update_ret(&ctx, data.p, data.rawSize());
}
mbedtls_sha256_update_ret(&ctx, data.p, data.rawSize());

mbedtls_sha256_finish_ret(&ctx, h);
mbedtls_sha256_free(&ctx);
}

void crypto::Sha256Hash::evercrypt_sha256(
initializer_list<CBuffer> il, uint8_t* h)
void crypto::Sha256Hash::evercrypt_sha256(const CBuffer& data, uint8_t* h)
{
EverCrypt_Hash_state_s* state =
EverCrypt_Hash_create(Spec_Hash_Definitions_SHA2_256);
EverCrypt_Hash_init(state);

for (auto data : il)
{
EverCrypt_Hash_update_multi(
state, const_cast<uint8_t*>(data.p), data.rawSize());
EverCrypt_Hash_update_last(
state, const_cast<uint8_t*>(data.p), data.rawSize());
}
constexpr auto block_size = 64u; // No way to ask evercrypt for this

const auto data_begin = const_cast<uint8_t*>(data.p);
const auto size = data.rawSize();
const auto full_blocks = size / block_size;

const auto full_blocks_size = full_blocks * block_size;
const auto full_blocks_end = data_begin + full_blocks_size;

// update_multi takes complete blocks
EverCrypt_Hash_update_multi(state, data_begin, full_blocks_size);

// update_last takes start of last chunk (NOT a full block!), and _total size_
EverCrypt_Hash_update_last(state, full_blocks_end, size);

EverCrypt_Hash_finish(state, h);
EverCrypt_Hash_free(state);
}

crypto::Sha256Hash::Sha256Hash() : h{0} {}

crypto::Sha256Hash::Sha256Hash(initializer_list<CBuffer> il) : h{0}
crypto::Sha256Hash::Sha256Hash(const CBuffer& data) : h{0}
{
evercrypt_sha256(il, h.data());
evercrypt_sha256(data, h.data());
}
6 changes: 3 additions & 3 deletions src/crypto/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ namespace crypto
public:
static constexpr size_t SIZE = 256 / 8;
Sha256Hash();
Sha256Hash(std::initializer_list<CBuffer> il);
Sha256Hash(const CBuffer& data);

std::array<uint8_t, SIZE> h;

static void mbedtls_sha256(std::initializer_list<CBuffer> il, uint8_t* h);
static void evercrypt_sha256(std::initializer_list<CBuffer> il, uint8_t* h);
static void mbedtls_sha256(const CBuffer& data, uint8_t* h);
static void evercrypt_sha256(const CBuffer& data, uint8_t* h);

friend std::ostream& operator<<(
std::ostream& os, const crypto::Sha256Hash& h)
Expand Down
44 changes: 31 additions & 13 deletions src/crypto/test/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,42 +37,60 @@ TEST_CASE("ExtendedIv0")

TEST_CASE("SHA256 short consistency test")
{
std::vector<uint8_t> data = {'a', 'b', 'c', '\n'};
std::vector<uint8_t> data = {'a', 'b', 'c', 'd', '\n'};
crypto::Sha256Hash h1, h2;
crypto::Sha256Hash::evercrypt_sha256({data}, h1.h.data());
crypto::Sha256Hash::mbedtls_sha256({data}, h2.h.data());
crypto::Sha256Hash::evercrypt_sha256(data, h1.h.data());
crypto::Sha256Hash::mbedtls_sha256(data, h2.h.data());
REQUIRE(h1 == h2);
}

TEST_CASE("SHA256 %32 consistency test")
{
std::vector<uint8_t> data(32);
for (unsigned i = 0; i < 32; i++)
data[i] = i;
std::iota(data.begin(), data.end(), 0);
crypto::Sha256Hash h1, h2;
crypto::Sha256Hash::evercrypt_sha256({data}, h1.h.data());
crypto::Sha256Hash::mbedtls_sha256({data}, h2.h.data());
crypto::Sha256Hash::evercrypt_sha256(data, h1.h.data());
crypto::Sha256Hash::mbedtls_sha256(data, h2.h.data());
REQUIRE(h1 == h2);
}

TEST_CASE("SHA256 long consistency test")
{
std::vector<uint8_t> data(512);
for (unsigned i = 0; i < 512; i++)
data[i] = i;
std::iota(data.begin(), data.end(), 0);
crypto::Sha256Hash h1, h2;
crypto::Sha256Hash::evercrypt_sha256({data}, h1.h.data());
crypto::Sha256Hash::mbedtls_sha256({data}, h2.h.data());
crypto::Sha256Hash::evercrypt_sha256(data, h1.h.data());
crypto::Sha256Hash::mbedtls_sha256(data, h2.h.data());
REQUIRE(h1 == h2);
}

TEST_CASE("Sha256 interesting size consistency test")
{
std::vector<uint8_t> full_data(8192);
std::iota(full_data.begin(), full_data.end(), 0);

for (size_t size : {0u, 1u, 4u, 10u, 63u, 64u, 65u, 127u,
128u, 129u, 150u, 200u, 500u, 1000u, 1023u, 1024u,
1025u, 2000u, 5000u, 8190u, 8191u, 8192u})
{
INFO(fmt::format("Hashing {} bytes", size));
auto data =
std::vector<uint8_t>(full_data.begin(), full_data.begin() + size);
crypto::Sha256Hash h1, h2;
crypto::Sha256Hash::evercrypt_sha256(data, h1.h.data());
crypto::Sha256Hash::mbedtls_sha256(data, h2.h.data());
CHECK(h1 == h2);
}
}

TEST_CASE("EverCrypt SHA256 no-collision check")
{
std::vector<uint8_t> data1 = {'a', 'b', 'c', '\n'};
std::vector<uint8_t> data2 = {'a', 'b', 'd', '\n'};
crypto::Sha256Hash h1, h2;
crypto::Sha256Hash::evercrypt_sha256({data1}, h1.h.data());
crypto::Sha256Hash::evercrypt_sha256({data2}, h2.h.data());
crypto::Sha256Hash::evercrypt_sha256(data1, h1.h.data());
crypto::Sha256Hash::evercrypt_sha256(data2, h2.h.data());
REQUIRE(h1 != h2);
}

Expand Down Expand Up @@ -133,4 +151,4 @@ TEST_CASE("Public key encryption")
"MCowBQYDK2VwAyEAiaGfOr3cEe+sS67LGoW+tv0AtD+bDYFKeDzxwBIxHhQ=\n"
"-----END PUBLIC KEY-----");
}
}
}
2 changes: 1 addition & 1 deletion src/node/history.h
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ namespace ccf

void append(const uint8_t* replicated, size_t replicated_size) override
{
crypto::Sha256Hash rh({{replicated, replicated_size}});
crypto::Sha256Hash rh({replicated, replicated_size});
log_hash(rh, APPEND);
replicated_state_tree.append(rh);
}
Expand Down
2 changes: 1 addition & 1 deletion src/node/signatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace ccf
commit(0)
{}

Signature(crypto::Sha256Hash root_) :
Signature(const crypto::Sha256Hash& root_) :
node(0),
index(0),
term(0),
Expand Down