From a494da4fea1b45a41fb2012a69dc4c9c0087be97 Mon Sep 17 00:00:00 2001 From: Mike Gelfand Date: Sun, 17 Dec 2023 01:21:24 +0000 Subject: [PATCH] fix: fill random buffer in chunks with mbedtls crypto backend (#6379) * adjust crypto unit test to reproduce the issue * fill random buffer in chunks with mbedtls crypto backend --- libtransmission/crypto-utils-mbedtls.cc | 17 ++++++++++++- tests/libtransmission/crypto-test.cc | 34 +++++++++++++++++++------ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/libtransmission/crypto-utils-mbedtls.cc b/libtransmission/crypto-utils-mbedtls.cc index a905b4094..c19486ad1 100644 --- a/libtransmission/crypto-utils-mbedtls.cc +++ b/libtransmission/crypto-utils-mbedtls.cc @@ -229,6 +229,21 @@ bool tr_rand_buffer_crypto(void* buffer, size_t length) TR_ASSERT(buffer != nullptr); + auto constexpr ChunkSize = size_t{ MBEDTLS_CTR_DRBG_MAX_REQUEST }; + static_assert(ChunkSize > 0U); + auto const lock = std::lock_guard(rng_mutex_); - return check_result(mbedtls_ctr_drbg_random(get_rng(), static_cast(buffer), length)); + + for (auto offset = size_t{ 0 }; offset < length; offset += ChunkSize) + { + if (!check_result(mbedtls_ctr_drbg_random( + get_rng(), + static_cast(buffer) + offset, + std::min(ChunkSize, length - offset)))) + { + return false; + } + } + + return true; } diff --git a/tests/libtransmission/crypto-test.cc b/tests/libtransmission/crypto-test.cc index 12bf1c940..72331e9eb 100644 --- a/tests/libtransmission/crypto-test.cc +++ b/tests/libtransmission/crypto-test.cc @@ -249,19 +249,31 @@ TEST(Crypto, random) } } -TEST(Crypto, randBuf) -{ - static auto constexpr Width = 32U; - static auto constexpr Iterations = 100000U; - static auto constexpr Empty = std::array{}; +using CryptoRandBufferTest = ::testing::TestWithParam; - auto buf = Empty; +TEST_P(CryptoRandBufferTest, randBuf) +{ + static auto constexpr Iterations = 1000U; + + auto const width = GetParam(); + auto const empty = std::vector(width, 0); + + auto buf = empty; for (size_t i = 0; i < Iterations; ++i) { auto tmp = buf; tr_rand_buffer(std::data(tmp), std::size(tmp)); - EXPECT_NE(tmp, Empty); + EXPECT_NE(tmp, empty); + EXPECT_NE(tmp, buf); + buf = tmp; + } + + for (size_t i = 0; i < Iterations; ++i) + { + auto tmp = buf; + EXPECT_TRUE(tr_rand_buffer_crypto(std::data(tmp), std::size(tmp))); + EXPECT_NE(tmp, empty); EXPECT_NE(tmp, buf); buf = tmp; } @@ -270,12 +282,18 @@ TEST(Crypto, randBuf) { auto tmp = buf; tr_rand_buffer_std(std::data(tmp), std::size(tmp)); - EXPECT_NE(tmp, Empty); + EXPECT_NE(tmp, empty); EXPECT_NE(tmp, buf); buf = tmp; } } +INSTANTIATE_TEST_SUITE_P( + Crypto, + CryptoRandBufferTest, + ::testing::Values(32, 100, 1024, 3000), + ::testing::PrintToStringParamName{}); + TEST(Crypto, base64) { auto raw = std::string_view{ "YOYO!"sv };