From 7c188d8ef5b36ede116ee5dbbcae30e207bef788 Mon Sep 17 00:00:00 2001 From: Fabian Albert Date: Fri, 19 Jan 2024 15:41:18 +0100 Subject: [PATCH 01/27] Utility functions for Classic McEliece - constant time conditional swap with mask - floor_log2 Co-Authored-By: Amos Treiber --- src/lib/utils/bit_ops.h | 8 ++++++++ src/lib/utils/ct_utils.h | 20 +++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/lib/utils/bit_ops.h b/src/lib/utils/bit_ops.h index 504c363ef9e..53a60d663d2 100644 --- a/src/lib/utils/bit_ops.h +++ b/src/lib/utils/bit_ops.h @@ -118,6 +118,14 @@ inline constexpr size_t ctz(T n) return lb; } +template +inline constexpr T floor_log2(T n) + requires(std::is_unsigned::value) +{ + BOTAN_ARG_CHECK(n != 0, "log2(0) is not defined"); + return static_cast(high_bit(n) - 1); +} + template constexpr uint8_t ceil_log2(T x) requires(std::is_integral::value && sizeof(T) < 32) diff --git a/src/lib/utils/ct_utils.h b/src/lib/utils/ct_utils.h index e6d864d8e44..f291dc3c34d 100644 --- a/src/lib/utils/ct_utils.h +++ b/src/lib/utils/ct_utils.h @@ -257,6 +257,20 @@ class Mask final { } } + /** + * If this mask is set, swap x and y + */ + template + void conditional_swap(U& x, U& y) const + requires(sizeof(U) <= sizeof(T)) + { + auto cnd = Mask(*this); + U t0 = cnd.select(y, x); + U t1 = cnd.select(x, y); + x = t0; + y = t1; + } + /** * Return the value of the mask, unpoisoned */ @@ -304,11 +318,7 @@ inline Mask conditional_assign_mem(T cnd, T* sink, const T* src, size_t elems template inline void conditional_swap(bool cnd, T& x, T& y) { const auto swap = CT::Mask::expand(cnd); - - T t0 = swap.select(y, x); - T t1 = swap.select(x, y); - x = t0; - y = t1; + swap.conditional_swap(x, y); } template From 052a205980de673b6f51b90193f15e8982b6fd1f Mon Sep 17 00:00:00 2001 From: Fabian Albert Date: Fri, 19 Jan 2024 15:43:30 +0100 Subject: [PATCH 02/27] Add --no-stdout flag to botan-test --- src/tests/main.cpp | 5 +++-- src/tests/runner/test_runner.cpp | 4 +++- src/tests/tests.h | 9 +++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/tests/main.cpp b/src/tests/main.cpp index 3e08a2715a2..110d45bc1bd 100644 --- a/src/tests/main.cpp +++ b/src/tests/main.cpp @@ -60,7 +60,7 @@ int main(int argc, char* argv[]) { try { const std::string arg_spec = "botan-test --verbose --help --data-dir= --pkcs11-lib= --provider= " - "--log-success --abort-on-first-fail --no-avoid-undefined --skip-tests= " + "--log-success --abort-on-first-fail --no-stdout --no-avoid-undefined --skip-tests= " "--test-threads=0 --test-results-dir= --run-long-tests --run-memory-intensive-tests " "--run-online-tests --test-runs=1 --drbg-seed= --report-properties= *suites"; @@ -98,7 +98,8 @@ int main(int argc, char* argv[]) { parser.flag_set("run-online-tests"), parser.flag_set("run-long-tests"), parser.flag_set("run-memory-intensive-tests"), - parser.flag_set("abort-on-first-fail")); + parser.flag_set("abort-on-first-fail"), + parser.flag_set("no-stdout")); Botan_Tests::Test_Runner tests(std::cout); diff --git a/src/tests/runner/test_runner.cpp b/src/tests/runner/test_runner.cpp index 289e9aad7fc..f461888fcad 100644 --- a/src/tests/runner/test_runner.cpp +++ b/src/tests/runner/test_runner.cpp @@ -73,7 +73,9 @@ class Testsuite_RNG final : public Botan::RandomNumberGenerator { } // namespace bool Test_Runner::run(const Test_Options& opts) { - m_reporters.emplace_back(std::make_unique(opts, output())); + if(!opts.no_stdout()) { + m_reporters.emplace_back(std::make_unique(opts, output())); + } if(!opts.xml_results_dir().empty()) { #if defined(BOTAN_TARGET_OS_HAS_FILESYSTEM) m_reporters.emplace_back(std::make_unique(opts, opts.xml_results_dir())); diff --git a/src/tests/tests.h b/src/tests/tests.h index 0696d5acf49..ea7c0e5c7c0 100644 --- a/src/tests/tests.h +++ b/src/tests/tests.h @@ -74,7 +74,8 @@ class Test_Options { bool run_online_tests, bool run_long_tests, bool run_memory_intensive_tests, - bool abort_on_first_fail) : + bool abort_on_first_fail, + bool no_stdout) : m_requested_tests(requested_tests), m_skip_tests(skip_tests.begin(), skip_tests.end()), m_data_dir(data_dir), @@ -90,7 +91,8 @@ class Test_Options { m_run_online_tests(run_online_tests), m_run_long_tests(run_long_tests), m_run_memory_intensive_tests(run_memory_intensive_tests), - m_abort_on_first_fail(abort_on_first_fail) {} + m_abort_on_first_fail(abort_on_first_fail), + m_no_stdout(no_stdout) {} const std::vector& requested_tests() const { return m_requested_tests; } @@ -122,6 +124,8 @@ class Test_Options { bool abort_on_first_fail() const { return m_abort_on_first_fail; } + bool no_stdout() const { return m_no_stdout; } + bool verbose() const { return m_verbose; } private: @@ -141,6 +145,7 @@ class Test_Options { bool m_run_long_tests; bool m_run_memory_intensive_tests; bool m_abort_on_first_fail; + bool m_no_stdout; }; namespace detail { From 8ca673c5e184662ed68687a2ce789452b962eee1 Mon Sep 17 00:00:00 2001 From: Rene Meusel Date: Tue, 21 Nov 2023 17:53:12 +0100 Subject: [PATCH 03/27] bitvector<> with basic functionality --- src/lib/utils/bitvector.h | 1043 ++++++++++++++++++++++++++++ src/lib/utils/info.txt | 1 + src/tests/test_utils_bitvector.cpp | 808 +++++++++++++++++++++ 3 files changed, 1852 insertions(+) create mode 100644 src/lib/utils/bitvector.h create mode 100644 src/tests/test_utils_bitvector.cpp diff --git a/src/lib/utils/bitvector.h b/src/lib/utils/bitvector.h new file mode 100644 index 00000000000..763adce3dc1 --- /dev/null +++ b/src/lib/utils/bitvector.h @@ -0,0 +1,1043 @@ +/* + * An abstraction for an arbitrarily large bitvector that can + * optionally use the secure_allocator. + * + * (C) 2023 Jack Lloyd + * (C) 2023 René Meusel, Rohde & Schwarz Cybersecurity + * + * Botan is released under the Simplified BSD License (see license.txt) + */ + +#ifndef BOTAN_BIT_VECTOR_H_ +#define BOTAN_BIT_VECTOR_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace detail { + +template +struct first_type { + using type = T0; +}; + +// get the first type from a parameter pack +template + requires(sizeof...(Ts) > 0) +using first_t = typename first_type::type; + +// get the first object from a parameter pack +template +constexpr static first_t first(T0&& t, Ts&&...) { + return std::forward(t); +} + +template +using as = OutT; + +template +using blockwise_processing_callback_return_type = std::invoke_result_t...>; + +template +concept is_blockwise_processing_callback_return_type = + std::unsigned_integral && + (std::same_as> || + std::same_as> || + std::same_as>); + +template +concept blockwise_processing_callback_without_mask = + is_blockwise_processing_callback_return_type && + is_blockwise_processing_callback_return_type && + is_blockwise_processing_callback_return_type && + is_blockwise_processing_callback_return_type; + +template +concept blockwise_processing_callback_with_mask = + is_blockwise_processing_callback_return_type && + is_blockwise_processing_callback_return_type && + is_blockwise_processing_callback_return_type && + is_blockwise_processing_callback_return_type; + +/** + * Defines the callback constraints for the BitRangeOperator. For further + * details, see bitvector_base::range_operation(). + */ +template +concept blockwise_processing_callback = blockwise_processing_callback_with_mask || + blockwise_processing_callback_without_mask; + +template +concept manipulating_blockwise_processing_callback = + (blockwise_processing_callback_without_mask && + std::same_as>) || + (blockwise_processing_callback_with_mask && + std::same_as>>); + +template +concept predicate_blockwise_processing_callback = + (blockwise_processing_callback_without_mask && + std::same_as>) || + (blockwise_processing_callback_with_mask && + std::same_as>>); + +} // namespace detail + +/** + * An arbitrarily large bitvector with typical bit manipulation and convenient + * bitwise access methods. Don't use `bitvector_base` directly, but the type + * aliases:: + * + * * bitvector - with a standard allocator + * * secure_bitvector - with a secure allocator that auto-scrubs the memory + */ +template