From 1d5272e248c191fc1486c41472b3bd35c449e282 Mon Sep 17 00:00:00 2001 From: Justin W Smith <103147162+justsmth@users.noreply.github.com> Date: Thu, 19 Oct 2023 15:41:53 -0400 Subject: [PATCH] Add comment; align w/ fits_in_bytes --- crypto/fipsmodule/bn/bytes.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/crypto/fipsmodule/bn/bytes.c b/crypto/fipsmodule/bn/bytes.c index 9ea27867217..c26247e82b5 100644 --- a/crypto/fipsmodule/bn/bytes.c +++ b/crypto/fipsmodule/bn/bytes.c @@ -205,28 +205,25 @@ static int fits_in_bytes(const BN_ULONG *words, size_t num_words, return mask == 0; } +// Asserts that the BIGNUM can be represented within |num| bytes. +// The logic is consistent with `fits_in_bytes` but assertions will fail when false. void bn_assert_fits_in_bytes(const BIGNUM *bn, size_t num) { const uint8_t *bytes = (const uint8_t *)bn->d; size_t tot_bytes = bn->width * sizeof(BN_ULONG); if (tot_bytes > num) { CONSTTIME_DECLASSIFY(bytes + num, tot_bytes - num); #ifdef OPENSSL_BIG_ENDIAN - int word_idx = num / sizeof(BN_ULONG); - - size_t bytes_to_ignore = num % sizeof(BN_ULONG); - if(bytes_to_ignore > 0) { - BN_ULONG word = bn->d[word_idx]; - // bytes in this word at an index higher than `bytes_to_ignore` must be 0. - for(size_t i = bytes_to_ignore; i < sizeof(BN_ULONG); i++) { - uint8_t byte = (word >> (i * 8)) & 0xff; - assert(byte == 0); + for (int i = num / BN_BYTES; i < bn->width; i++) { + BN_ULONG word = bn->d[i]; + for (size_t j = 0; j < BN_BYTES; j++) { + if ((i * BN_BYTES) + j < num) { + // For the first word we don't need to check any bytes shorter than len + continue; + } else { + uint8_t byte = (word >> (j * 8)) & 0xff; + assert(byte == 0); + } } - word_idx += 1; - } - - // subsequent words must all be 0. - for(; word_idx < bn->width; word_idx++) { - assert(bn->d[word_idx] == 0); } #else for (size_t i = num; i < tot_bytes; i++) {