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

Chore: Modernize copy_out_be/le #3885

Merged
merged 2 commits into from
Mar 25, 2024
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
4 changes: 2 additions & 2 deletions src/lib/block/aes/aes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ void aes_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secur

CT::unpoison(B, 8);

copy_out_be(out, this_loop * 4 * sizeof(uint32_t), B);
copy_out_be(std::span(out, this_loop * 4 * sizeof(uint32_t)), B);

in += this_loop * BLOCK_SIZE;
out += this_loop * BLOCK_SIZE;
Expand Down Expand Up @@ -610,7 +610,7 @@ void aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secur

CT::unpoison(B, 8);

copy_out_be(out, this_loop * 4 * sizeof(uint32_t), B);
copy_out_be(std::span(out, this_loop * 4 * sizeof(uint32_t)), B);

in += this_loop * BLOCK_SIZE;
out += this_loop * BLOCK_SIZE;
Expand Down
3 changes: 1 addition & 2 deletions src/lib/compat/sodium/sodium_salsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ int Sodium::crypto_core_hsalsa20(uint8_t out[], const uint8_t in[], const uint8_

uint32_t out32[8] = {0};
Salsa20::hsalsa20(out32, in32);

copy_out_le(out, 32, out32);
store_le(std::span<uint8_t, 32>(out, 32), out32);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/hash/blake2/blake2b.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ void BLAKE2b::final_result(std::span<uint8_t> output) {

m_F = 0xFFFFFFFFFFFFFFFF;
compress(m_buffer.consume().data(), 1, pos);
copy_out_vec_le(output.data(), output_length(), m_H);
copy_out_le(output.first(output_length()), m_H);
state_init();
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/hash/blake2s/blake2s.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ void BLAKE2s::final_result(std::span<uint8_t> out) {
compress(true); // final block flag = 1

// little endian convert and store
copy_out_le<uint32_t>(out.data(), m_outlen, m_h);
copy_out_le(out.first(output_length()), m_h);

clear();
};
Expand Down
4 changes: 2 additions & 2 deletions src/lib/hash/mdx_hash/mdx_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ class MerkleDamgard_Hash final {
BOTAN_ASSERT_NOMSG(output.size() >= MD::output_bytes);

if constexpr(MD::byte_endianness == MD_Endian::Big) {
copy_out_vec_be(output.data(), MD::output_bytes, m_digest);
copy_out_be(output.first(MD::output_bytes), m_digest);
} else {
copy_out_vec_le(output.data(), MD::output_bytes, m_digest);
copy_out_le(output.first(MD::output_bytes), m_digest);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/lib/hash/skein/skein_512.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ void Skein_512::final_result(std::span<uint8_t> out) {
reset_tweak(SKEIN_OUTPUT, true);
ubi_512(counter, sizeof(counter));

copy_out_vec_le(out.data(), m_output_bits / 8, m_threefish->m_K);
copy_out_le(out.first(m_output_bits / 8), m_threefish->m_K);

initial_block();
}
Expand Down
69 changes: 41 additions & 28 deletions src/lib/utils/loadstor.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,42 +712,55 @@ inline constexpr auto store_be(ParamTs&&... params) {
return detail::store_any<detail::Endianness::Big, ModifierT>(std::forward<ParamTs>(params)...);
}

template <typename T>
void copy_out_be(uint8_t out[], size_t out_bytes, const T in[]) {
while(out_bytes >= sizeof(T)) {
store_be(in[0], out);
out += sizeof(T);
out_bytes -= sizeof(T);
in += 1;
}
namespace detail {

for(size_t i = 0; i != out_bytes; ++i) {
out[i] = get_byte_var(i % 8, in[0]);
}
}
template <Endianness endianness, unsigned_integralish T>
size_t copy_out_any_word_aligned_portion(std::span<uint8_t>& out, std::span<const T>& in) {
const size_t full_words = out.size() / sizeof(T);
const size_t full_word_bytes = full_words * sizeof(T);
const size_t remaining_bytes = out.size() - full_word_bytes;
BOTAN_ASSERT_NOMSG(in.size_bytes() >= full_word_bytes + remaining_bytes);

// copy full words
store_any<endianness, T>(out.first(full_word_bytes), in.first(full_words));
out = out.subspan(full_word_bytes);
in = in.subspan(full_words);

template <typename T, typename Alloc>
void copy_out_vec_be(uint8_t out[], size_t out_bytes, const std::vector<T, Alloc>& in) {
copy_out_be(out, out_bytes, in.data());
return remaining_bytes;
}

template <typename T>
void copy_out_le(uint8_t out[], size_t out_bytes, const T in[]) {
while(out_bytes >= sizeof(T)) {
store_le(in[0], out);
out += sizeof(T);
out_bytes -= sizeof(T);
in += 1;
}
} // namespace detail

for(size_t i = 0; i != out_bytes; ++i) {
out[i] = get_byte_var(sizeof(T) - 1 - (i % 8), in[0]);
/**
* Partially copy a subset of @p in into @p out using big-endian
* byte order.
*/
template <ranges::spanable_range InR>
void copy_out_be(std::span<uint8_t> out, InR&& in) {
using T = std::ranges::range_value_t<InR>;
std::span<const T> in_s{in};
const auto remaining_bytes = detail::copy_out_any_word_aligned_portion<detail::Endianness::Big>(out, in_s);

// copy remaining bytes as a partial word
for(size_t i = 0; i < remaining_bytes; ++i) {
out[i] = get_byte_var(i, in_s.front());
}
}

template <typename T, typename Alloc>
void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector<T, Alloc>& in) {
copy_out_le(out, out_bytes, in.data());
/**
* Partially copy a subset of @p in into @p out using little-endian
* byte order.
*/
template <ranges::spanable_range InR>
void copy_out_le(std::span<uint8_t> out, InR&& in) {
using T = std::ranges::range_value_t<InR>;
std::span<const T> in_s{in};
const auto remaining_bytes = detail::copy_out_any_word_aligned_portion<detail::Endianness::Little>(out, in_s);

// copy remaining bytes as a partial word
for(size_t i = 0; i < remaining_bytes; ++i) {
out[i] = get_byte_var(sizeof(T) - 1 - i, in_s.front());
}
}

} // namespace Botan
Expand Down
4 changes: 2 additions & 2 deletions src/lib/utils/poly_dbl/poly_dbl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void poly_double(uint8_t out[], const uint8_t in[]) {

W[LIMBS - 1] = (W[LIMBS - 1] << 1) ^ carry;

copy_out_be(out, LIMBS * 8, W);
copy_out_be(std::span(out, LIMBS * 8), W);
}

template <size_t LIMBS, MinWeightPolynomial P>
Expand All @@ -66,7 +66,7 @@ void poly_double_le(uint8_t out[], const uint8_t in[]) {

W[0] = (W[0] << 1) ^ carry;

copy_out_le(out, LIMBS * 8, W);
copy_out_le(std::span(out, LIMBS * 8), W);
}

} // namespace
Expand Down
70 changes: 69 additions & 1 deletion src/tests/test_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class Utility_Function_Tests final : public Text_Based_Test {
results.push_back(test_loadstore());
results.push_back(test_loadstore_fallback());
results.push_back(test_loadstore_constexpr());
return results;
return Botan::concat(results, test_copy_out_be_le());
}

private:
Expand Down Expand Up @@ -577,6 +577,74 @@ class Utility_Function_Tests final : public Text_Based_Test {

return result;
}

static std::vector<Test::Result> test_copy_out_be_le() {
return {
Botan_Tests::CHECK("copy_out_be with 16bit input (word aligned)",
[&](auto& result) {
std::vector<uint8_t> out_vector(4);
const std::array<uint16_t, 2> in_array = {0x0A0B, 0x0C0D};
Botan::copy_out_be(out_vector, in_array);
result.test_is_eq(out_vector, Botan::hex_decode("0A0B0C0D"));
}),

Botan_Tests::CHECK("copy_out_be with 16bit input (partial words)",
[&](auto& result) {
std::vector<uint8_t> out_vector(3);
const std::array<uint16_t, 2> in_array = {0x0A0B, 0x0C0D};
Botan::copy_out_be(out_vector, in_array);
result.test_is_eq(out_vector, Botan::hex_decode("0A0B0C"));
}),

Botan_Tests::CHECK("copy_out_le with 16bit input (word aligned)",
[&](auto& result) {
std::vector<uint8_t> out_vector(4);
const std::array<uint16_t, 2> in_array = {0x0A0B, 0x0C0D};
Botan::copy_out_le(out_vector, in_array);
result.test_is_eq(out_vector, Botan::hex_decode("0B0A0D0C"));
}),

Botan_Tests::CHECK("copy_out_le with 16bit input (partial words)",
[&](auto& result) {
std::vector<uint8_t> out_vector(3);
const std::array<uint16_t, 2> in_array = {0x0A0B, 0x0C0D};
Botan::copy_out_le(out_vector, in_array);
result.test_is_eq(out_vector, Botan::hex_decode("0B0A0D"));
}),

Botan_Tests::CHECK("copy_out_be with 64bit input (word aligned)",
[&](auto& result) {
std::vector<uint8_t> out_vector(16);
const std::array<uint64_t, 2> in_array = {0x0A0B0C0D0E0F1011, 0x1213141516171819};
Botan::copy_out_be(out_vector, in_array);
result.test_is_eq(out_vector, Botan::hex_decode("0A0B0C0D0E0F10111213141516171819"));
}),

Botan_Tests::CHECK("copy_out_le with 64bit input (word aligned)",
[&](auto& result) {
std::vector<uint8_t> out_vector(16);
const std::array<uint64_t, 2> in_array = {0x0A0B0C0D0E0F1011, 0x1213141516171819};
Botan::copy_out_le(out_vector, in_array);
result.test_is_eq(out_vector, Botan::hex_decode("11100F0E0D0C0B0A1918171615141312"));
}),

Botan_Tests::CHECK("copy_out_be with 64bit input (partial words)",
[&](auto& result) {
std::vector<uint8_t> out_vector(15);
const std::array<uint64_t, 2> in_array = {0x0A0B0C0D0E0F1011, 0x1213141516171819};
Botan::copy_out_be(out_vector, in_array);
result.test_is_eq(out_vector, Botan::hex_decode("0A0B0C0D0E0F101112131415161718"));
}),

Botan_Tests::CHECK("copy_out_le with 64bit input (partial words)",
[&](auto& result) {
std::vector<uint8_t> out_vector(15);
const std::array<uint64_t, 2> in_array = {0x0A0B0C0D0E0F1011, 0x1213141516171819};
Botan::copy_out_le(out_vector, in_array);
result.test_is_eq(out_vector, Botan::hex_decode("11100F0E0D0C0B0A19181716151413"));
}),
};
}
};

BOTAN_REGISTER_SMOKE_TEST("utils", "util", Utility_Function_Tests);
Expand Down
Loading