From 9df0a65ffb262b9e5ea518b53ae88413b6d37317 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 13:24:10 -0500 Subject: [PATCH 01/17] Add basic outline --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 include/boost/crypt2/drbg/detail/hmac_drbg.hpp diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp new file mode 100644 index 00000000..98366156 --- /dev/null +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -0,0 +1,83 @@ +// Copyright 2024 Matt Borland +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#ifndef BOOST_CRYPT2_DRBG_DETAIL_HMAC_DRBG_HPP +#define BOOST_CRYPT2_DRBG_DETAIL_HMAC_DRBG_HPP + +#include +#include +#include +#include +#include + +namespace boost::crypt::drbg_detail { + +// Max hasher security is defined in NIST SP 800-57 Table 3: +// See: https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf +// +// 112: None +// 128: SHA-1 +// 192: SHA-224, SHA-512/224, SHA3-224 +// 256: SHA-256, SHA-512/256, SHA-384, SHA-512, SHA3-256, SHA3-384, SHA3-512 +// +// Outlen is defined in NIST SP 800-90A Rev 1 Section 10.1 table 2 +// 160: SHA-1 +// 224: SHA-224, SHA-512/224 +// 256: SHA-256, SHA-512/256 +// 384: SHA-384 +// 512: SHA-512 +template +class hmac_drbg +{ + static_assert(max_hasher_security == 128 || max_hasher_security == 192 || max_hasher_security == 256, "Invalid value for max hasher security"); + static_assert(outlen == 160 || outlen == 224 || outlen == 256 || outlen == 384 || outlen == 512, "Invalid outlen value"); + + static consteval bool valid_combinations() + { + switch (max_hasher_security) + { + case 128U: + return outlen == 160; + case 192U: + return outlen == 224; + default: + return outlen >= 256; + } + } + + static_assert(valid_combinations(), "Invalid combination of values"); + + static constexpr compat::size_t outlen_bytes {outlen / 8U}; + static constexpr compat::size_t max_bytes_per_request {65536U}; + static constexpr compat::size_t min_length {max_hasher_security / 8U}; + static constexpr compat::size_t min_entropy {min_length * 3U / 2U}; + + static constexpr compat::uint64_t max_length {4294967296ULL}; // 2^35 / 8 + static constexpr compat::uint64_t reseed_interval {281474976710656ULL}; // 2^48 + + typename HMACType::return_type key_ {}; + compat::span key_span_ {key_}; + typename HMACType::return_type value_ {}; + compat::span value_span_ {value_}; + compat::size_t reseed_counter_ {}; + bool initialized_ {}; + +public: + + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac_drbg() noexcept = default; + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR ~hmac_drbg() noexcept; +}; + +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac_drbg::~hmac_drbg() noexcept +{ + detail::clear_mem(key_); + detail::clear_mem(value_); + reseed_counter_ = 0U; + initialized_ = false; +} + +} // namespace boost::crypt::drbg_detail + +#endif // BOOST_CRYPT2_DRBG_DETAIL_HMAC_DRBG_HPP From 38034c119358793106b49ca06bdae3b9e86d04bd Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 13:36:41 -0500 Subject: [PATCH 02/17] Add basic init --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index 98366156..8c5f6121 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -67,6 +67,11 @@ class hmac_drbg BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac_drbg() noexcept = default; BOOST_CRYPT_GPU_ENABLED_CONSTEXPR ~hmac_drbg() noexcept; + + template + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init(compat::span entropy, + compat::span nonce = compat::span {}, + compat::span personalization = compat::span{}) noexcept -> state; }; template @@ -78,6 +83,42 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac_drbg +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::init( + compat::span entropy, + compat::span nonce, + compat::span personalization) noexcept -> state +{ + // Nonce is to be at least >= 0.5 * max_hasher_security + // Unless entropy + nonce >= 1.5 * max_hasher_security + if (entropy.size() + nonce.size() < min_entropy) + { + return state::insufficient_entropy; + } + + // Key needs to be set to all 0x00 + for (auto& byte : key_) + { + byte = static_cast(0x00); + } + // Value needs to be set to all 0x01 + for (auto& byte : value_) + { + byte = static_cast(0x01); + } + + const auto update_return {update(entropy, nonce, personalization)}; + if (update_return != state::success) [[unlikely]] + { + return update_return; // LCOV_EXCL_LINE + } + + reseed_counter_ = 1U; + initialized_ = true; + return state::success; +} + } // namespace boost::crypt::drbg_detail #endif // BOOST_CRYPT2_DRBG_DETAIL_HMAC_DRBG_HPP From 9375300b2f559372b1fb09daa95624feba11069a Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 13:55:31 -0500 Subject: [PATCH 03/17] Add update functionality --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index 8c5f6121..0b1827a8 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -63,6 +63,11 @@ class hmac_drbg compat::size_t reseed_counter_ {}; bool initialized_ {}; + template + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto update(compat::span provided_data_1, + compat::span provided_data_2, + compat::span provided_data_3) noexcept -> state; + public: BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac_drbg() noexcept = default; @@ -83,6 +88,88 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac_drbg +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::update( + compat::span provided_data_1, + compat::span provided_data_2, + compat::span provided_data_3) noexcept -> state +{ + const auto provided_data_size {provided_data_1.size() + provided_data_2.size() + provided_data_3.size()}; + + // Step 1: V || 0x00 || provided data + compat::array storage_gap {std::byte{0x00}}; + compat::span storage_gap_span {storage_gap}; + HMACType hmac(key_span_); + hmac.process_bytes(value_span_); + hmac.process_bytes(storage_gap_span); + if constexpr (Extent1 != 0) + { + hmac.process_bytes(provided_data_1); + } + if constexpr (Extent2 != 0) + { + hmac.process_bytes(provided_data_2); + } + if constexpr (Extent3 != 0) + { + hmac.process_bytes(provided_data_3); + } + + hmac.finalize(); + auto hmac_return {hmac.get_digest()}; + if (!hmac_return.has_value()) [[unlikely]] + { + return hmac_return.error(); // LCOV_EXCL_LINE + } + + key_ = hmac_return.value(); + + if (provided_data_size != 0U) + { + // Step 2: V || 0x01 || provided data + storage_gap[0] = compat::byte{0x01}; + hmac.init(key_span_); + hmac.process_bytes(value_span_); + hmac.process_bytes(storage_gap_span); + if constexpr (Extent1 != 0) + { + hmac.process_bytes(provided_data_1); + } + if constexpr (Extent2 != 0) + { + hmac.process_bytes(provided_data_2); + } + if constexpr (Extent3 != 0) + { + hmac.process_bytes(provided_data_3); + } + + hmac.finalize(); + hmac_return = hmac.get_digest(); + if (!hmac_return.has_value()) [[unlikely]] + { + return hmac_return.error(); // LCOV_EXCL_LINE + } + + key_ = hmac_return.value(); + + // Step 3: Update value + hmac.init(key_span_); + hmac.process_bytes(value_span_); + hmac.finalize(); + hmac_return = hmac.get_digest(); + if (!hmac_return.has_value()) [[unlikely]] + { + return hmac_return.error(); // LCOV_EXCL_LINE + } + + value_ = hmac_return.value(); + } + + return state::success; +} + template template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::init( From 5b3b4973122478a1b760d715465f37297eca0454 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 14:00:50 -0500 Subject: [PATCH 04/17] Add range init --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index 0b1827a8..b8bcf634 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -77,6 +77,13 @@ class hmac_drbg BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init(compat::span entropy, compat::span nonce = compat::span {}, compat::span personalization = compat::span{}) noexcept -> state; + + template + BOOST_CRYPT_GPU_ENABLED auto init(SizedRange1&& entropy, + SizedRange2&& nonce = compat::array{}, + SizedRange3&& personalization = compat::array{}) noexcept -> state; }; template @@ -206,6 +213,32 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::init( + SizedRange1&& entropy, + SizedRange2&& nonce, + SizedRange3&& personalization) noexcept -> state +{ + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container" + #endif + + // Since these are sized ranges we can safely convert them into spans + auto entropy_span {compat::make_span(compat::forward(entropy))}; + auto nonce_span {compat::make_span(compat::forward(nonce))}; + auto personalization_span {compat::make_span(compat::forward(personalization))}; + + return init(compat::as_bytes(entropy_span), + compat::as_bytes(nonce_span), + compat::as_bytes(personalization_span)); + + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif +} + } // namespace boost::crypt::drbg_detail #endif // BOOST_CRYPT2_DRBG_DETAIL_HMAC_DRBG_HPP From 2ca6e4ec3a7b91045792575b007dc652fca76e98 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 14:33:52 -0500 Subject: [PATCH 05/17] Add generate for no prediction resistance --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 108 +++++++++++++++++- 1 file changed, 104 insertions(+), 4 deletions(-) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index b8bcf634..73037873 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include namespace boost::crypt::drbg_detail { @@ -68,6 +70,10 @@ class hmac_drbg compat::span provided_data_2, compat::span provided_data_3) noexcept -> state; + template + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto no_pr_generate_impl(compat::span return_data, compat::size_t requested_bits, + compat::span additional_data = compat::span{}) noexcept -> state; + public: BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac_drbg() noexcept = default; @@ -177,12 +183,106 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::no_pr_generate_impl( + compat::span return_data, compat::size_t requested_bits, + compat::span additional_data) noexcept -> state +{ + if (reseed_counter_ > reseed_interval) + { + return state::requires_reseed; + } + if (!initialized_) + { + return state::uninitialized; + } + + const auto requested_bytes {requested_bits / 8U}; + if (requested_bits > max_bytes_per_request) + { + return state::requested_too_many_bits; + } + + if constexpr (Extent2 != 0) + { + if (!additional_data.empty()) + { + // If we are on a different 32 bit or smaller platform and using clang ignore the warning + #ifdef __clang__ + # pragma clang diagnostic push + # pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare" + #endif + + #if !defined(__i386__) && !defined(_M_IX86) + if (additional_data.size() > max_length) + { + return state::input_too_long; + } + #endif // 32-bit platforms + + #ifdef __clang__ + # pragma clang diagnostic pop + #endif + + const auto update_return {update(additional_data)}; + if (update_return != state::success) [[unlikely]] + { + return update_return; // LCOV_EXCL_LINE + } + } + } + + compat::size_t bytes {}; + HMACType hmac; + while (bytes < requested_bytes) + { + hmac.init(key_); + hmac.process_bytes(value_); + hmac.finalize(); + const auto hmac_return {hmac.get_digest()}; + if (!hmac_return.has_value) [[unlikely]] + { + return hmac_return.error(); // LCOV_EXCL_LINE + } + + value_ = hmac_return.value(); + + if (bytes + value_.size() < requested_bytes) + { + for (const auto val : value_span_) + { + return_data[bytes++] = val; + } + } + else + { + for (compat::size_t i {}; bytes < requested_bytes && i < value_.size(); ++i) + { + return_data[bytes++] = value_span_[i]; + } + } + } + + if constexpr (Extent2 != 0) + { + const auto update_return {update(additional_data)}; + if (update_return != state::success) [[unlikely]] + { + return update_return; // LCOV_EXCL_LINE + } + } + + ++reseed_counter_; + return state::success; +} + template template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::init( - compat::span entropy, - compat::span nonce, - compat::span personalization) noexcept -> state + compat::span entropy, + compat::span nonce, + compat::span personalization) noexcept -> state { // Nonce is to be at least >= 0.5 * max_hasher_security // Unless entropy + nonce >= 1.5 * max_hasher_security @@ -215,7 +315,7 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg template -BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::init( +BOOST_CRYPT_GPU_ENABLED auto hmac_drbg::init( SizedRange1&& entropy, SizedRange2&& nonce, SizedRange3&& personalization) noexcept -> state From cc7f49e81d738908159d81c3689e826de3f36e9e Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 14:40:37 -0500 Subject: [PATCH 06/17] Add prediction resistance generate --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index 73037873..6685bdad 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -74,6 +74,11 @@ class hmac_drbg BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto no_pr_generate_impl(compat::span return_data, compat::size_t requested_bits, compat::span additional_data = compat::span{}) noexcept -> state; + template + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto pr_generate_impl(compat::span return_data, compat::size_t requested_bits, + compat::span entropy, + compat::span additional_data = compat::span {}) noexcept -> state; + public: BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac_drbg() noexcept = default; @@ -277,6 +282,32 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::no_pr_generate_impl( + compat::span return_data, compat::size_t requested_bits, + compat::span entropy, + compat::span additional_data) noexcept -> state +{ + // 9.3.3 Reseed using the entropy and the additional data, then set additional data to NULL + if (reseed_counter_ > reseed_interval) + { + return state::requires_reseed; + } + if (!initialized_) + { + return state::uninitialized; + } + + const auto reseed_return {reseed(entropy, additional_data)}; + if (reseed_return != state::success) [[unlikely]] + { + return reseed_return; + } + + return no_pr_generate_impl(return_data, requested_bits); +} + template template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::init( From 8ff3b14a8fb002c16aabe72a9215590ddb6aff0c Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 14:51:42 -0500 Subject: [PATCH 07/17] Add hmac drbg --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index 6685bdad..b6bcae47 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -95,6 +95,10 @@ class hmac_drbg BOOST_CRYPT_GPU_ENABLED auto init(SizedRange1&& entropy, SizedRange2&& nonce = compat::array{}, SizedRange3&& personalization = compat::array{}) noexcept -> state; + + template + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto reseed(compat::span entropy, + compat::span additional_input = compat::span{}) noexcept -> state; }; template @@ -370,6 +374,29 @@ BOOST_CRYPT_GPU_ENABLED auto hmac_drbg +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::reseed( + compat::span entropy, + compat::span additional_input) noexcept -> state +{ + constexpr auto min_reseed_entropy {max_hasher_security / 8U}; + + if (entropy.size() < min_reseed_entropy) + { + return state::insufficient_entropy; + } + + const auto update_return {update(entropy, additional_input)}; + if (update_return != state::success) [[unlikely]] + { + return update_return; + } + + reseed_counter_ = 1U; + return state::success; +} + } // namespace boost::crypt::drbg_detail #endif // BOOST_CRYPT2_DRBG_DETAIL_HMAC_DRBG_HPP From 84af6941f4706c60184815a67d415d2eb0e14108 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 15:21:49 -0500 Subject: [PATCH 08/17] Add generic reseed --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index b6bcae47..74dca537 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -99,6 +99,11 @@ class hmac_drbg template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto reseed(compat::span entropy, compat::span additional_input = compat::span{}) noexcept -> state; + + template + BOOST_CRYPT_GPU_ENABLED auto reseed(SizedRange1&& entropy, + SizedRange2&& additional_data = compat::array{}) noexcept -> state; }; template @@ -397,6 +402,29 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg +template +BOOST_CRYPT_GPU_ENABLED auto hmac_drbg::reseed( + SizedRange1&& entropy, + SizedRange2&& additional_input) noexcept -> state +{ + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container" + #endif + + // Since these are sized ranges we can safely convert them into spans + auto entropy_span {compat::make_span(compat::forward(entropy))}; + auto additional_input_span {compat::make_span(compat::forward(additional_input))}; + + return reseed(compat::as_bytes(entropy_span), + compat::as_bytes(additional_input_span)); + + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif +} + } // namespace boost::crypt::drbg_detail #endif // BOOST_CRYPT2_DRBG_DETAIL_HMAC_DRBG_HPP From af0b52e0ffe8732a21dd11a155809cd69e349bf4 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 15:50:15 -0500 Subject: [PATCH 09/17] Add generate methods --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 80 ++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index 74dca537..402c3f70 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -104,6 +104,18 @@ class hmac_drbg concepts::sized_range SizedRange2> BOOST_CRYPT_GPU_ENABLED auto reseed(SizedRange1&& entropy, SizedRange2&& additional_data = compat::array{}) noexcept -> state; + + template + BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto generate(compat::span return_data, compat::size_t requested_bits, + compat::span additional_data_1 = compat::span{}, + compat::span additional_data_2 = compat::span{}) noexcept -> state; + + template + BOOST_CRYPT_GPU_ENABLED auto generate(SizedRange1&& return_data, compat::size_t requested_bits, + SizedRange2&& additional_data_1 = compat::span{}, + SizedRange3&& additional_data_2 = compat::span{}) noexcept -> state; }; template @@ -293,7 +305,7 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg template -BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::no_pr_generate_impl( +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::pr_generate_impl( compat::span return_data, compat::size_t requested_bits, compat::span entropy, compat::span additional_data) noexcept -> state @@ -425,6 +437,72 @@ BOOST_CRYPT_GPU_ENABLED auto hmac_drbg +template +BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg::generate( + compat::span return_data, compat::size_t requested_bits, + compat::span additional_data_1, + compat::span additional_data_2) noexcept -> state +{ + if constexpr (prediction_resistance) + { + return pr_generate_impl(return_data, requested_bits, additional_data_1, additional_data_2); + } + else + { + return no_pr_generate_impl(return_data, requested_bits, additional_data_1); + } +} + +template +template +BOOST_CRYPT_GPU_ENABLED auto hmac_drbg::generate( + SizedRange1&& return_data, compat::size_t requested_bits, + SizedRange2&& additional_data_1, + SizedRange3&& additional_data_2) noexcept -> state +{ + if constexpr (prediction_resistance) + { + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container" + #endif + + // Since these are sized ranges we can safely convert them into spans + auto return_data_span {compat::make_span(compat::forward(return_data))}; + auto additional_data1_span {compat::make_span(compat::forward(additional_data_1))}; + auto additional_data2_span {compat::make_span(compat::forward(additional_data_2))}; + + return pr_generate_impl(compat::as_writable_bytes(return_data_span), requested_bits, + compat::as_bytes(additional_data1_span), + compat::as_bytes(additional_data2_span)); + + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif + } + else + { + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-container" + #endif + + // Since these are sized ranges we can safely convert them into spans + auto return_data_span {compat::make_span(compat::forward(return_data))}; + auto additional_data1_span {compat::make_span(compat::forward(additional_data_1))}; + + return no_pr_generate_impl(compat::as_writable_bytes(return_data_span), requested_bits, + compat::as_bytes(additional_data1_span)); + + #if defined(__clang__) && __clang_major__ >= 19 + #pragma clang diagnostic pop + #endif + } +} + } // namespace boost::crypt::drbg_detail #endif // BOOST_CRYPT2_DRBG_DETAIL_HMAC_DRBG_HPP From accbc7cae63e596ccdad5725ea4e271beb175ffc Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 16:47:38 -0500 Subject: [PATCH 10/17] Fix init step --- .../boost/crypt2/drbg/detail/hmac_drbg.hpp | 52 +++++++++++-------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index 402c3f70..583ec5e4 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -10,8 +10,6 @@ #include #include #include -#include -#include namespace boost::crypt::drbg_detail { @@ -65,16 +63,16 @@ class hmac_drbg compat::size_t reseed_counter_ {}; bool initialized_ {}; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto update(compat::span provided_data_1, - compat::span provided_data_2, - compat::span provided_data_3) noexcept -> state; + compat::span provided_data_2 = compat::span{}, + compat::span provided_data_3 = compat::span{}) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto no_pr_generate_impl(compat::span return_data, compat::size_t requested_bits, compat::span additional_data = compat::span{}) noexcept -> state; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto pr_generate_impl(compat::span return_data, compat::size_t requested_bits, compat::span entropy, compat::span additional_data = compat::span {}) noexcept -> state; @@ -84,24 +82,24 @@ class hmac_drbg BOOST_CRYPT_GPU_ENABLED_CONSTEXPR hmac_drbg() noexcept = default; BOOST_CRYPT_GPU_ENABLED_CONSTEXPR ~hmac_drbg() noexcept; - template + template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto init(compat::span entropy, - compat::span nonce = compat::span {}, - compat::span personalization = compat::span{}) noexcept -> state; + compat::span nonce = compat::span {}, + compat::span personalization = compat::span{}) noexcept -> state; template + concepts::sized_range SizedRange2 = compat::span, + concepts::sized_range SizedRange3 = compat::span> BOOST_CRYPT_GPU_ENABLED auto init(SizedRange1&& entropy, - SizedRange2&& nonce = compat::array{}, - SizedRange3&& personalization = compat::array{}) noexcept -> state; + SizedRange2&& nonce = compat::span{}, + SizedRange3&& personalization = compat::span{}) noexcept -> state; template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto reseed(compat::span entropy, compat::span additional_input = compat::span{}) noexcept -> state; template + concepts::sized_range SizedRange2 = compat::array> BOOST_CRYPT_GPU_ENABLED auto reseed(SizedRange1&& entropy, SizedRange2&& additional_data = compat::array{}) noexcept -> state; @@ -111,11 +109,11 @@ class hmac_drbg compat::span additional_data_2 = compat::span{}) noexcept -> state; template + concepts::sized_range SizedRange2 = compat::span, + concepts::sized_range SizedRange3 = compat::span> BOOST_CRYPT_GPU_ENABLED auto generate(SizedRange1&& return_data, compat::size_t requested_bits, - SizedRange2&& additional_data_1 = compat::span{}, - SizedRange3&& additional_data_2 = compat::span{}) noexcept -> state; + SizedRange2&& additional_data_1 = compat::span{}, + SizedRange3&& additional_data_2 = compat::span{}) noexcept -> state; }; template @@ -139,7 +137,9 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg storage_gap {std::byte{0x00}}; compat::span storage_gap_span {storage_gap}; - HMACType hmac(key_span_); + + HMACType hmac; + hmac.init(key_span_); hmac.process_bytes(value_span_); hmac.process_bytes(storage_gap_span); if constexpr (Extent1 != 0) @@ -164,6 +164,16 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg Date: Wed, 5 Feb 2025 17:02:04 -0500 Subject: [PATCH 11/17] Perform update even if additional data is empty --- include/boost/crypt2/drbg/detail/hmac_drbg.hpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index 583ec5e4..b68b76f1 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -273,8 +273,8 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg Date: Wed, 5 Feb 2025 17:22:00 -0500 Subject: [PATCH 12/17] Fix handling of error states --- include/boost/crypt2/drbg/detail/hmac_drbg.hpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index b68b76f1..a71d5f7a 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -227,7 +227,7 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg reseed_interval) { - return state::requires_reseed; + return state::requires_reseed; // LCOV_EXCL_LINE } if (!initialized_) { @@ -235,7 +235,7 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg max_bytes_per_request) + if (requested_bytes > max_bytes_per_request) { return state::requested_too_many_bits; } @@ -320,12 +320,18 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg reseed_interval) { - return state::requires_reseed; + return state::requires_reseed; // LCOV_EXCL_LINE } if (!initialized_) { return state::uninitialized; } + + const auto requested_bytes {requested_bits / 8U}; + if (requested_bytes > max_bytes_per_request) + { + return state::requested_too_many_bits; + } const auto reseed_return {reseed(entropy, additional_data)}; if (reseed_return != state::success) [[unlikely]] From be0743697380b0a4132f246e945e9563f7e82ffa Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 17:22:07 -0500 Subject: [PATCH 13/17] Update test harness --- test/Jamfile | 2 +- test/test_hmac_drbg.cpp | 126 ++++++++++++++++++++-------------------- 2 files changed, 65 insertions(+), 63 deletions(-) diff --git a/test/Jamfile b/test/Jamfile index 97541f28..2e1e9af0 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -77,7 +77,7 @@ run test_shake256.cpp ; run test_hmac.cpp ; -#run test_hmac_drbg.cpp ; +run test_hmac_drbg.cpp ; run test_hash_drbg.cpp ; diff --git a/test/test_hmac_drbg.cpp b/test/test_hmac_drbg.cpp index 54b65d78..406b150d 100644 --- a/test/test_hmac_drbg.cpp +++ b/test/test_hmac_drbg.cpp @@ -2,7 +2,7 @@ // Distributed under the Boost Software License, Version 1.0. // https://www.boost.org/LICENSE_1_0.txt -#include +#include #include #include #include @@ -12,37 +12,37 @@ void sha1_basic_correctness() { boost::crypt::sha1_hmac_drbg rng; - boost::crypt::array entropy = { + std::array entropy = { 0xe9, 0x1b, 0x63, 0x30, 0x9e, 0x93, 0xd1, 0xd0, 0x8e, 0x30, 0xe8, 0xd5, 0x56, 0x90, 0x68, 0x75 }; - boost::crypt::array nonce = { + std::array nonce = { 0xf5, 0x97, 0x47, 0xc4, 0x68, 0xb0, 0xd0, 0xda }; - boost::crypt::array return_bits {}; + std::array return_bits {}; // Test process is: // 1) Instantiate drbg // 2) Generate bits, do not compare // 3) Generate bits, compare // 4) Destroy drbg - BOOST_TEST(rng.init(entropy, entropy.size(), nonce, nonce.size()) == boost::crypt::state::success); + BOOST_TEST(rng.init(entropy, nonce) == boost::crypt::state::success); // ** INSTANTIATE: // V = 7ea45af5f8fcba082fa40bcbea2748dfe7e09f6a // Key = be3976a33f77e0155b7ca84a5732d44f319e5f3a - BOOST_TEST(rng.generate(return_bits.begin(), 640U) == boost::crypt::state::success); + BOOST_TEST(rng.generate(return_bits, 640U) == boost::crypt::state::success); // ** GENERATE (FIRST CALL): // V = 0e28fe04dd16482f8e4b048675318adcd5e6e6cf // Key = 764d4f1fb7b04624bcb14642acb24d70eff3c0c8 - BOOST_TEST(rng.generate(return_bits.begin(), 640U) == boost::crypt::state::success); + BOOST_TEST(rng.generate(return_bits, 640U) == boost::crypt::state::success); // ** GENERATE (SECOND CALL): // V = 749a95f0882e0179d66d8ae2697802f8f568ce2f // Key = bfcd86fcb4c2efce22f6e9b69742751a17b0056c - constexpr boost::crypt::array nist_return = { + constexpr std::array nist_return = { 0xb7, 0x92, 0x8f, 0x95, 0x03, 0xa4, 0x17, 0x11, 0x07, 0x88, 0xf9, 0xd0, 0xc2, 0x58, 0x5f, 0x8a, 0xee, 0x6f, 0xb7, 0x3b, 0x22, 0x0a, 0x62, 0x6b, 0x3a, 0xb9, 0x82, 0x5b, 0x7a, 0x9f, @@ -53,32 +53,28 @@ void sha1_basic_correctness() 0x74, 0x3f, 0x41, 0xc8, 0xb0, 0xee, 0x73, 0x22, 0x53, 0x47 }; - for (boost::crypt::size_t i {}; i < return_bits.size(); ++i) + for (std::size_t i {}; i < return_bits.size(); ++i) { if (!BOOST_TEST_EQ(return_bits[i], nist_return[i])) { // LCOV_EXCL_START std::cerr << std::hex - << "Got: " << static_cast(return_bits[i]) - << "\nExpected: " << static_cast(nist_return[i]) << std::endl; + << "Got: " << static_cast(return_bits[i]) + << "\nExpected: " << static_cast(nist_return[i]) << std::endl; // LCOV_EXCL_STOP } } - const char* big_additional_input = "749a95f0882e0179d66d8ae2697802f8f568ce2fbfcd86fcb4c2efce22f6e9b69742751a17b0056c"; - BOOST_TEST(rng.init(entropy.begin(), entropy.size(), - nonce.begin(), nonce.size(), - big_additional_input, std::strlen(big_additional_input)) == boost::crypt::state::success); - - BOOST_TEST(rng.generate(return_bits.begin(), 640U, big_additional_input, std::strlen(big_additional_input)) == boost::crypt::state::success); - BOOST_TEST(rng.reseed(big_additional_input, std::strlen(big_additional_input), big_additional_input, std::strlen(big_additional_input)) == boost::crypt::state::success); + std::string big_additional_input = "749a95f0882e0179d66d8ae2697802f8f568ce2fbfcd86fcb4c2efce22f6e9b69742751a17b0056c"; + BOOST_TEST(rng.init(entropy, + nonce, + big_additional_input) == boost::crypt::state::success); - std::string str_additional_input {big_additional_input}; - BOOST_TEST(rng.reseed(str_additional_input) == boost::crypt::state::success); - BOOST_TEST(rng.reseed(str_additional_input, str_additional_input) == boost::crypt::state::success); + BOOST_TEST(rng.generate(return_bits, 640U, big_additional_input) == boost::crypt::state::success); + BOOST_TEST(rng.reseed(big_additional_input, big_additional_input) == boost::crypt::state::success); #ifdef BOOST_CRYPT_HAS_STRING_VIEW - std::string_view str_view {str_additional_input}; + std::string_view str_view {big_additional_input}; BOOST_TEST(rng.reseed(str_view) == boost::crypt::state::success); BOOST_TEST(rng.reseed(str_view, str_view) == boost::crypt::state::success); #endif @@ -87,36 +83,36 @@ void sha1_basic_correctness() void sha1_additional_input() { boost::crypt::sha1_hmac_drbg rng; - constexpr boost::crypt::array entropy = { + constexpr std::array entropy = { 0x49, 0x05, 0x8e, 0x67, 0x73, 0xed, 0x2b, 0x7a, 0xb3, 0x09, 0xc0, 0x94, 0x9f, 0xdf, 0x9c, 0x9e }; - constexpr boost::crypt::array nonce = { + constexpr std::array nonce = { 0xa4, 0x57, 0xcb, 0x8e, 0xc0, 0xe7, 0xfd, 0x01 }; - constexpr boost::crypt::array personalization = { + constexpr std::array personalization = { 0xdc, 0x47, 0x76, 0x41, 0xd8, 0x9c, 0x7f, 0xc4, 0xa3, 0x0f, 0x14, 0x30, 0x19, 0x7d, 0xd1, 0x59 }; - BOOST_TEST(rng.init(entropy.begin(), entropy.size(), - nonce.begin(), nonce.size(), - personalization.begin(), personalization.size()) == boost::crypt::state::success); + BOOST_TEST(rng.init(entropy, + nonce, + personalization) == boost::crypt::state::success); // ** INSTANTIATE: // V = 9c530ef5f1e277aab4e1e129091a273f0342d5c9 // Key = 7006c1c0c03c4ca267b19c50928f35891d8d8807 - boost::crypt::array return_bits {}; + std::array return_bits {}; - BOOST_TEST(rng.generate(return_bits.begin(), 640U) == boost::crypt::state::success); + BOOST_TEST(rng.generate(return_bits, 640U) == boost::crypt::state::success); // ** GENERATE (FIRST CALL): // V = 5b1508d16daad5aff52273cd549ce6bd9e259b0d // Key = b7e28116a16856b9e81bda776d421bb56e8f902f - BOOST_TEST(rng.generate(return_bits) == boost::crypt::state::success); + BOOST_TEST(rng.generate(return_bits, return_bits.size() * 8U) == boost::crypt::state::success); // ** GENERATE (SECOND CALL): // V = 71fa823bc53bfd307d6438edd7e5c581fffc27cc // Key = cfccf80b126cea770b468fb8652abbd5eeea2a5e - constexpr boost::crypt::array nist_return = { + constexpr std::array nist_return = { 0x4e, 0x89, 0x1f, 0x4e, 0x28, 0x11, 0x00, 0x45, 0x3b, 0x70, 0x78, 0x89, 0x29, 0xec, 0x74, 0x3a, 0x3c, 0x5e, 0xdd, 0x9b, 0x81, 0xdc, 0x79, 0x8b, 0xc9, 0x37, 0x71, 0x36, 0x8c, 0x39, 0xb6, 0x12, 0x03, @@ -127,14 +123,14 @@ void sha1_additional_input() 0x93, 0xb0, 0xdc }; - for (boost::crypt::size_t i {}; i < return_bits.size(); ++i) + for (std::size_t i {}; i < return_bits.size(); ++i) { if (!BOOST_TEST_EQ(return_bits[i], nist_return[i])) { // LCOV_EXCL_START std::cerr << std::hex - << "Got: " << static_cast(return_bits[i]) - << "\nExpected: " << static_cast(nist_return[i]) << std::endl; + << "Got: " << static_cast(return_bits[i]) + << "\nExpected: " << static_cast(nist_return[i]) << std::endl; // LCOV_EXCL_STOP } } @@ -143,22 +139,22 @@ void sha1_additional_input() void sha1_pr() { boost::crypt::sha1_hmac_drbg_pr rng; - constexpr std::array entropy = { + constexpr std::array entropy = { 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, 0xf7, 0x3e, 0x9c, 0x5b }; - constexpr std::array nonce = { + constexpr std::array nonce = { 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11 }; - constexpr boost::crypt::array entropy_gen_1 = { + constexpr std::array entropy_gen_1 = { 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, 0x17, 0x60, 0x99, 0xd4 }; - constexpr boost::crypt::array entropy_gen_2 = { + constexpr std::array entropy_gen_2 = { 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; - constexpr boost::crypt::array nist_return = { + constexpr std::array nist_return = { 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, @@ -169,45 +165,48 @@ void sha1_pr() 0xee, 0xf3, 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; - boost::crypt::array return_bits {}; + std::array return_bits {}; - BOOST_TEST(rng.init(entropy.begin(), entropy.size(), nonce.begin(), nonce.size()) == boost::crypt::state::success); + BOOST_TEST(rng.init(entropy, nonce) == boost::crypt::state::success); - BOOST_TEST(rng.generate(return_bits.begin(), 640U, entropy_gen_1.begin(), entropy_gen_1.size()) == boost::crypt::state::success); + BOOST_TEST(rng.generate(return_bits, 640U, entropy_gen_1) == boost::crypt::state::success); - BOOST_TEST(rng.generate(return_bits.begin(), 640U, entropy_gen_2.begin(), entropy_gen_2.size()) == boost::crypt::state::success); + BOOST_TEST(rng.generate(return_bits, 640U, entropy_gen_2) == boost::crypt::state::success); - for (boost::crypt::size_t i {}; i < return_bits.size(); ++i) + for (std::size_t i {}; i < return_bits.size(); ++i) { if (!BOOST_TEST_EQ(return_bits[i], nist_return[i])) { // LCOV_EXCL_START std::cerr << std::hex - << "Got: " << static_cast(return_bits[i]) - << "\nExpected: " << static_cast(nist_return[i]) << std::endl; + << "Got: " << static_cast(return_bits[i]) + << "\nExpected: " << static_cast(nist_return[i]) << std::endl; // LCOV_EXCL_STOP } } BOOST_TEST(rng.init(entropy, nonce, nonce) == boost::crypt::state::success); BOOST_TEST(rng.init(entropy, nonce) == boost::crypt::state::success); - BOOST_TEST(rng.init(entropy) == boost::crypt::state::success); - - #ifdef BOOST_CRYPT_HAS_SPAN - // Clang 14 with libc++ can't deduce the span - // Clang 15+ has no issues according to CI - #if !defined(__clang__) || (__clang_major__ > 14) - - std::span entropy_span {entropy}; - std::span nonce_span {nonce}; - BOOST_TEST(rng.init(entropy_span, nonce_span, nonce_span) == boost::crypt::state::success); - BOOST_TEST(rng.init(entropy_span, nonce_span) == boost::crypt::state::success); - BOOST_TEST(rng.init(entropy_span) == boost::crypt::state::success); + BOOST_TEST(rng.init(entropy) == boost::crypt::state::insufficient_entropy); +} - #endif - #endif +template +void error_states() +{ + constexpr std::array entropy = { + 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, 0xf7, 0x3e, 0x9c, 0x5b + }; + constexpr std::array nonce = { + 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11 + }; - rng.destroy(); + HMACDRBGType rng; + std::array bad_return {}; + BOOST_TEST(rng.generate(bad_return, 8) == boost::crypt::state::uninitialized); + BOOST_TEST(rng.init(entropy) == boost::crypt::state::insufficient_entropy); + BOOST_TEST(rng.init(entropy, nonce) == boost::crypt::state::success); + BOOST_TEST(rng.generate(bad_return, 65537*8U) == boost::crypt::state::requested_too_many_bits); + BOOST_TEST(rng.reseed(bad_return) == boost::crypt::state::insufficient_entropy); } int main() @@ -216,5 +215,8 @@ int main() sha1_additional_input(); sha1_pr(); + error_states(); + error_states(); + return boost::report_errors(); } From 41525ab40cbce3516ace29b761cf4a0220b7351c Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 17:22:22 -0500 Subject: [PATCH 14/17] Add sha1 hmac drbg definitions --- include/boost/crypt2/drbg/sha1_drbg.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/crypt2/drbg/sha1_drbg.hpp b/include/boost/crypt2/drbg/sha1_drbg.hpp index 3443f632..e991fcc6 100644 --- a/include/boost/crypt2/drbg/sha1_drbg.hpp +++ b/include/boost/crypt2/drbg/sha1_drbg.hpp @@ -6,6 +6,8 @@ #define BOOST_CRYPT2_DRBG_SHA1_DRBG_HPP #include +#include +#include #include namespace boost::crypt { @@ -15,11 +17,17 @@ namespace drbg_detail { template using sha1_hash_drbg_t = hash_drbg; +template +using sha1_hmac_drbg_t = hmac_drbg, 128U, 160U, prediction_resistance>; + } // namespace drbg_detail BOOST_CRYPT_EXPORT using sha1_hash_drbg = drbg_detail::sha1_hash_drbg_t; BOOST_CRYPT_EXPORT using sha1_hash_drbg_pr = drbg_detail::sha1_hash_drbg_t; +BOOST_CRYPT_EXPORT using sha1_hmac_drbg = drbg_detail::sha1_hmac_drbg_t; +BOOST_CRYPT_EXPORT using sha1_hmac_drbg_pr = drbg_detail::sha1_hmac_drbg_t; + } // namespace boost::crypt #endif // BOOST_CRYPT2_DRBG_SHA1_DRBG_HPP From ecb076ffdc5aac7fc9344fd097ba965bd1fcbdf4 Mon Sep 17 00:00:00 2001 From: Matt Borland Date: Wed, 5 Feb 2025 17:40:41 -0500 Subject: [PATCH 15/17] Exclude additional should be impossible lines --- include/boost/crypt2/drbg/detail/hmac_drbg.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index a71d5f7a..7792acb5 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -253,7 +253,7 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg max_length) { - return state::input_too_long; + return state::input_too_long; // LCOV_EXCL_LINE } #endif // 32-bit platforms @@ -326,7 +326,7 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg max_bytes_per_request) { @@ -336,7 +336,7 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg Date: Wed, 5 Feb 2025 18:13:04 -0500 Subject: [PATCH 16/17] Fix MSVC warning --- include/boost/crypt2/drbg/detail/hmac_drbg.hpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index 7792acb5..c28bdb2c 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -174,6 +174,11 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg Date: Wed, 5 Feb 2025 20:35:50 -0500 Subject: [PATCH 17/17] Replace array 0 with span 0 --- include/boost/crypt2/drbg/detail/hmac_drbg.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp index c28bdb2c..ca3ea589 100644 --- a/include/boost/crypt2/drbg/detail/hmac_drbg.hpp +++ b/include/boost/crypt2/drbg/detail/hmac_drbg.hpp @@ -99,9 +99,9 @@ class hmac_drbg compat::span additional_input = compat::span{}) noexcept -> state; template > + concepts::sized_range SizedRange2 = compat::span> BOOST_CRYPT_GPU_ENABLED auto reseed(SizedRange1&& entropy, - SizedRange2&& additional_data = compat::array{}) noexcept -> state; + SizedRange2&& additional_data = compat::span{}) noexcept -> state; template BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto generate(compat::span return_data, compat::size_t requested_bits, @@ -176,7 +176,7 @@ BOOST_CRYPT_GPU_ENABLED_CONSTEXPR auto hmac_drbg