Commit 90678b8158 for strongswan.org

commit 90678b8158744ba6993818ed619b81528bbbcce8
Author: Andreas Steffen <andreas.steffen@strongswan.org>
Date:   Sat Jan 4 20:48:44 2025 +0100

    ml: Fix return value of ml_bitpacker_t::write_bits() in corner cases

    Rejects writing too many bits from the start.  And when writing the
    requested number of bits coincided with flushing a full 32-bit block to
    the output to fill it up, the function could previously fail
    (`this->pos.len` is zero in that case).  Since the ML-KEM code allocates
    an exactly sized buffer and doesn't check the return value this wasn't
    noticed before.

    Also avoids potentially undefined behavior when right-shifting by 32 bits.

    Fixes: 89f4b345e336 ("ml: Add software implementation of ML-KEM")

diff --git a/src/libstrongswan/plugins/ml/ml_bitpacker.c b/src/libstrongswan/plugins/ml/ml_bitpacker.c
index d208bbb510..972e840699 100644
--- a/src/libstrongswan/plugins/ml/ml_bitpacker.c
+++ b/src/libstrongswan/plugins/ml/ml_bitpacker.c
@@ -73,6 +73,10 @@ METHOD(ml_bitpacker_t, write_bits, bool,
 	{
 		return FALSE;
 	}
+	if ((32 - this->bits_left) + bits > 8 * this->pos.len)
+	{	/* buffer is too small to write pending and requested bits */
+		return FALSE;
+	}
 	if (bits < 32)
 	{
 		value &= (1 << bits) - 1;
@@ -92,12 +96,23 @@ METHOD(ml_bitpacker_t, write_bits, bool,
 			this->bits_left -= bits;
 			return TRUE;
 		}
-		value >>= this->bits_left;
+		if (this->bits_left < 32)
+		{
+			value >>= this->bits_left;
+		}
+		else
+		{
+			value = 0;
+		}
 		bits -= this->bits_left;

 		flush_buffer(this);
 		this->bits_buf = 0;
 		this->bits_left = 32;
+		if (bits == 0)
+		{
+			return TRUE;
+		}
 	}
 }