-
Notifications
You must be signed in to change notification settings - Fork 574
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3294 from randombit/chore/generic_interface_bufcomp
Chore: Buffered_Computation can deal with generic containers
- Loading branch information
Showing
4 changed files
with
194 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/** | ||
* (C) 2023 Jack Lloyd | ||
* 2023 Philippe Lieser - Rohde & Schwarz Cybersecurity | ||
* 2023 René Meusel - Rohde & Schwarz Cybersecurity | ||
* | ||
* Botan is released under the Simplified BSD License (see license.txt) | ||
*/ | ||
|
||
#include "tests.h" | ||
|
||
#include <botan/buf_comp.h> | ||
#include <botan/secmem.h> | ||
#include <botan/mem_ops.h> | ||
#include <botan/strong_type.h> | ||
|
||
#include <array> | ||
#include <string> | ||
#include <vector> | ||
|
||
namespace Botan_Tests { | ||
|
||
namespace { | ||
|
||
class Test_Buf_Comp final : public Botan::Buffered_Computation | ||
{ | ||
public: | ||
Test_Buf_Comp(Test::Result& res) | ||
: m_result(res) | ||
, m_counter(0) {} | ||
|
||
size_t output_length() const override { return sizeof(m_counter); } | ||
|
||
void add_data(const uint8_t input[], size_t length) override | ||
{ | ||
if(m_result.test_eq("input length as expected", length, size_t(5))) | ||
{ | ||
m_result.confirm("input[0] == 'A'", input[0] == 'A'); | ||
m_result.confirm("input[0] == 'B'", input[1] == 'B'); | ||
m_result.confirm("input[0] == 'C'", input[2] == 'C'); | ||
m_result.confirm("input[0] == 'D'", input[3] == 'D'); | ||
m_result.confirm("input[0] == 'E'", input[4] == 'E'); | ||
} | ||
|
||
++m_counter; | ||
} | ||
|
||
void final_result(uint8_t out[]) override | ||
{ | ||
const uint8_t* counter = reinterpret_cast<const uint8_t*>(&m_counter); | ||
std::copy(counter, counter + sizeof(m_counter), out); | ||
} | ||
|
||
size_t counter() const { return m_counter; } | ||
|
||
private: | ||
Test::Result& m_result; | ||
size_t m_counter; | ||
}; | ||
|
||
void check(Test::Result& result, std::span<const uint8_t> produced, size_t expected) | ||
{ | ||
const uint8_t* eptr = reinterpret_cast<const uint8_t*>(&expected); | ||
result.confirm("result is correct", Botan::same_mem(produced.data(), eptr, sizeof(size_t))); | ||
} | ||
|
||
using TestStdVector = Botan::Strong<std::vector<uint8_t>, struct TestStdVector_>; | ||
using TestSecureVector = Botan::Strong<Botan::secure_vector<uint8_t>, struct TestSecureVector_>; | ||
|
||
Test::Result test_buffered_computation_convenience_api() | ||
{ | ||
// This is mainly to test compilability of the various container | ||
// types as in and out parameters. Hence, we refrain from checking | ||
// the 'final' output everywhere. | ||
Test::Result result("Convenience API of Buffered_Computation"); | ||
|
||
Test_Buf_Comp t(result); | ||
|
||
constexpr auto test_string = "ABCDE"; | ||
const std::vector<uint8_t> test_vector = {'A', 'B', 'C', 'D', 'E'}; | ||
const std::array<uint8_t, 5> test_array = {'A', 'B', 'C', 'D', 'E'}; | ||
const TestStdVector test_strong_type(test_vector); | ||
|
||
Botan::secure_vector<uint8_t> out_sv; | ||
std::vector<uint8_t> out_vec; | ||
std::array<uint8_t, sizeof(std::size_t)> out_arr; | ||
TestSecureVector out_strong_type; | ||
|
||
// update with basic string-ish types | ||
t.update("ABCDE"); | ||
t.update(test_string); | ||
t.update(std::string(test_string)); | ||
|
||
// update with container types | ||
t.update(test_vector); | ||
t.update(test_array); | ||
t.update(test_strong_type); | ||
|
||
// final returning result | ||
out_sv = t.final(); | ||
out_vec = t.final_stdvec(); | ||
out_strong_type = t.final<TestSecureVector>(); | ||
|
||
// final using out param | ||
t.final(out_sv); | ||
t.final(out_arr); | ||
t.final(out_strong_type); | ||
|
||
check(result, out_strong_type, 6); | ||
|
||
// test resizing of final out param | ||
out_vec.resize(0); | ||
t.final(out_vec); | ||
out_vec.resize(t.output_length()*2); | ||
t.final(out_vec); | ||
result.test_int_eq("out vector is resized", out_vec.size(), t.output_length()); | ||
|
||
check(result, out_vec, 6); | ||
|
||
// process with basic string-ish types as input | ||
out_sv = t.process(test_string); | ||
out_sv = t.process(std::string(test_string)); | ||
|
||
check(result, out_sv, 8); | ||
|
||
// process with container types as input | ||
out_sv = t.process(test_vector); | ||
out_sv = t.process(test_array); | ||
|
||
check(result, out_sv, 10); | ||
|
||
// process with specific in and out type | ||
out_vec = t.process<std::vector<uint8_t>>(test_vector); | ||
const auto out_strong_sec_vec = t.process<TestSecureVector>(test_vector); | ||
|
||
check(result, out_strong_sec_vec, 12); | ||
|
||
return result; | ||
} | ||
|
||
BOTAN_REGISTER_TEST_FN("base", "bufcomp_base_api", test_buffered_computation_convenience_api); | ||
|
||
} | ||
|
||
} |