Skip to content

Commit

Permalink
Merge pull request #3885 from Rohde-Schwarz/chore/modernize_copy_out_…
Browse files Browse the repository at this point in the history
…be_le

Chore: Modernize copy_out_be/le
  • Loading branch information
reneme authored Mar 25, 2024
2 parents 66dc49e + bd94e8e commit 38a0b56
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 40 deletions.
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

0 comments on commit 38a0b56

Please sign in to comment.