From 22459ba236d510ef22c70eabd5031c2a43ee5b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meusel?= Date: Wed, 18 Sep 2024 19:09:25 +0200 Subject: [PATCH] double-check range checks in the decodings --- .../dilithium/dilithium_common/dilithium_algos.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lib/pubkey/dilithium/dilithium_common/dilithium_algos.cpp b/src/lib/pubkey/dilithium/dilithium_common/dilithium_algos.cpp index 5d4d280a1c8..a0604a9cf64 100644 --- a/src/lib/pubkey/dilithium/dilithium_common/dilithium_algos.cpp +++ b/src/lib/pubkey/dilithium/dilithium_common/dilithium_algos.cpp @@ -85,6 +85,12 @@ constexpr void poly_unpack(CRYSTALS::Polynomial& p, ByteSourceT& g // to the range [-a, b]. CRYSTALS::unpack(p, get_bytes, unmap_range); } + + // `check_range` should only be enabled if the requested range is not fully + // covered by the encodeable range, i.e |range| is not a power of 2. + BOTAN_DEBUG_ASSERT(!check_range || + (a >= 0 && b >= 0 && !is_power_of_2(static_cast(b) - static_cast(a) + 1))); + if(check_range && !p.ct_validate_value_range(-a, b)) { throw Decoding_Error("Decoded polynomial coefficients out of range"); } @@ -167,6 +173,10 @@ void poly_pack_t0(const DilithiumPoly& p, BufferStuffer& stuffer) { */ void poly_unpack_t1(DilithiumPoly& p, BufferSlicer& slicer) { constexpr auto b = (1 << (bitlen(DilithiumConstants::Q - 1) - DilithiumConstants::D)) - 1; + // The range of valid output coefficients [0, b] fully covers the encodeable + // range. Hence, no range check is needed despite this being exposed to + // potentially untrusted serialized public keys. + static_assert(b >= 0 && is_power_of_2(static_cast(b) + 1)); poly_unpack<0, b>(p, slicer); }