From 805da53d603f9cc84a834b1d29f862907e4f2b73 Mon Sep 17 00:00:00 2001 From: Denis Mingulov Date: Fri, 19 Jun 2026 12:48:32 +0300 Subject: [PATCH] Fix size_t-to-int truncation in the OpenSSL RNG backend RAND_bytes() and RAND_seed() take an int length, so on 64-bit platforms any request above INT_MAX was silently truncated: a >2 GiB C_GenerateRandom() left most of the buffer unwritten while still reporting success, and C_SeedRandom() used only a truncated prefix of the seed. Both now clamp each call to INT_MAX and loop, so the whole length is honoured. RAND_seed() accumulates entropy across calls, so feeding it in pieces is fine. The Botan backend takes size_t and was already fine. --- src/lib/crypto/OSSLRNG.cpp | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/lib/crypto/OSSLRNG.cpp b/src/lib/crypto/OSSLRNG.cpp index d6a1e5dc8..691a79050 100644 --- a/src/lib/crypto/OSSLRNG.cpp +++ b/src/lib/crypto/OSSLRNG.cpp @@ -33,20 +33,44 @@ #include "config.h" #include "OSSLRNG.h" #include +#include + +// RAND_bytes()/RAND_seed() take an int length, so a size_t over INT_MAX would +// be truncated. Clamp each call and loop so the whole request is covered. +static int clampToInt(size_t len) +{ + return len > (size_t) INT_MAX ? INT_MAX : (int) len; +} // Generate random data bool OSSLRNG::generateRandom(ByteString& data, const size_t len) { data.wipe(len); - if (len == 0) - return true; - return RAND_bytes(&data[0], len) == 1; + size_t offset = 0; + while (offset < len) + { + int chunk = clampToInt(len - offset); + if (RAND_bytes(&data[offset], chunk) != 1) + return false; + offset += (size_t) chunk; + } + return true; } // Seed the random pool void OSSLRNG::seed(ByteString& seedData) { - RAND_seed(seedData.byte_str(), seedData.size()); + // RAND_seed() accumulates entropy, so feeding the seed in pieces is fine. + const unsigned char* bytes = seedData.const_byte_str(); + size_t len = seedData.size(); + + size_t offset = 0; + while (offset < len) + { + int chunk = clampToInt(len - offset); + RAND_seed(bytes + offset, chunk); + offset += (size_t) chunk; + } }