From 66414209519a912dc63d346916b52187982b9e73 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Sep 2022 15:36:16 +0200 Subject: [PATCH 1/4] Bignum core: Break shift_r function out of the classic shift_r This commit contains the function prototype for mbedtls_mpi_core_shift_r, and the implementation minimally modified from mbedtls_mpi_shift_r. Signed-off-by: Gilles Peskine --- library/bignum.c | 35 ++++++++++++++++++++++------------- library/bignum_core.h | 15 +++++++++++++++ 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index 1c7f9197f0..0787272fee 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -770,27 +770,38 @@ cleanup: * Right-shift: X >>= count */ int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ) +{ + MPI_VALIDATE_RET( X != NULL ); + if( X->n != 0 ) + mbedtls_mpi_core_shift_r( X->p, X->n, count ); + return( 0 ); +} + +void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, + size_t count ) { size_t i, v0, v1; mbedtls_mpi_uint r0 = 0, r1; - MPI_VALIDATE_RET( X != NULL ); v0 = count / biL; v1 = count & (biL - 1); - if( v0 > X->n || ( v0 == X->n && v1 > 0 ) ) - return mbedtls_mpi_lset( X, 0 ); + if( v0 > limbs || ( v0 == limbs && v1 > 0 ) ) + { + memset( X, 0, limbs * ciL ); + return; + } /* * shift by count / limb_size */ if( v0 > 0 ) { - for( i = 0; i < X->n - v0; i++ ) - X->p[i] = X->p[i + v0]; + for( i = 0; i < limbs - v0; i++ ) + X[i] = X[i + v0]; - for( ; i < X->n; i++ ) - X->p[i] = 0; + for( ; i < limbs; i++ ) + X[i] = 0; } /* @@ -798,16 +809,14 @@ int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ) */ if( v1 > 0 ) { - for( i = X->n; i > 0; i-- ) + for( i = limbs; i > 0; i-- ) { - r1 = X->p[i - 1] << (biL - v1); - X->p[i - 1] >>= v1; - X->p[i - 1] |= r0; + r1 = X[i - 1] << (biL - v1); + X[i - 1] >>= v1; + X[i - 1] |= r0; r0 = r1; } } - - return( 0 ); } /* diff --git a/library/bignum_core.h b/library/bignum_core.h index 196736d05e..4ba14331c3 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -262,6 +262,21 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *A, unsigned char *output, size_t output_length ); +/** \brief Shift a machine integer right by a number of bits. + * + * Shifting by more bits than there are bit positions + * in \p X is valid and results in setting \p X to 0. + * + * This function's execution time depends on the value + * of \p count (and of course \p limbs). + * + * \param[in,out] X The number to shift. + * \param limbs The number of limbs of \p X. This must be at least 1. + * \param count The number of bits to shift by. + */ +void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, + size_t count ); + /** * \brief Conditional addition of two fixed-size large unsigned integers, * returning the carry. From c279b2fa4a72e53c4bce6426c95043b8e7b1c2a2 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Sep 2022 15:38:38 +0200 Subject: [PATCH 2/4] Move mbedtls_mpi_core_shift_r to the proper source file Signed-off-by: Gilles Peskine --- library/bignum.c | 42 --------------------------------------- library/bignum_core.c | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/library/bignum.c b/library/bignum.c index 0787272fee..58cd2f7329 100644 --- a/library/bignum.c +++ b/library/bignum.c @@ -777,48 +777,6 @@ int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ) return( 0 ); } -void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, - size_t count ) -{ - size_t i, v0, v1; - mbedtls_mpi_uint r0 = 0, r1; - - v0 = count / biL; - v1 = count & (biL - 1); - - if( v0 > limbs || ( v0 == limbs && v1 > 0 ) ) - { - memset( X, 0, limbs * ciL ); - return; - } - - /* - * shift by count / limb_size - */ - if( v0 > 0 ) - { - for( i = 0; i < limbs - v0; i++ ) - X[i] = X[i + v0]; - - for( ; i < limbs; i++ ) - X[i] = 0; - } - - /* - * shift by count % limb_size - */ - if( v1 > 0 ) - { - for( i = limbs; i > 0; i-- ) - { - r1 = X[i - 1] << (biL - v1); - X[i - 1] >>= v1; - X[i - 1] |= r0; - r0 = r1; - } - } -} - /* * Compare unsigned values */ diff --git a/library/bignum_core.c b/library/bignum_core.c index 89fd4043e2..00837298b0 100644 --- a/library/bignum_core.c +++ b/library/bignum_core.c @@ -316,6 +316,52 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *X, return( 0 ); } + + +void mbedtls_mpi_core_shift_r( mbedtls_mpi_uint *X, size_t limbs, + size_t count ) +{ + size_t i, v0, v1; + mbedtls_mpi_uint r0 = 0, r1; + + v0 = count / biL; + v1 = count & (biL - 1); + + if( v0 > limbs || ( v0 == limbs && v1 > 0 ) ) + { + memset( X, 0, limbs * ciL ); + return; + } + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = 0; i < limbs - v0; i++ ) + X[i] = X[i + v0]; + + for( ; i < limbs; i++ ) + X[i] = 0; + } + + /* + * shift by count % limb_size + */ + if( v1 > 0 ) + { + for( i = limbs; i > 0; i-- ) + { + r1 = X[i - 1] << (biL - v1); + X[i - 1] >>= v1; + X[i - 1] |= r0; + r0 = r1; + } + } +} + + + mbedtls_mpi_uint mbedtls_mpi_core_add_if( mbedtls_mpi_uint *X, const mbedtls_mpi_uint *A, size_t limbs, From b0ee5772878d11b92fa103254e96d38509c93ed0 Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Wed, 21 Sep 2022 23:13:33 +0200 Subject: [PATCH 3/4] Bignum core: test shift_r Signed-off-by: Gilles Peskine --- scripts/mbedtls_dev/bignum_core.py | 41 ++++++++++++++++++++ tests/suites/test_suite_bignum_core.function | 20 ++++++++++ 2 files changed, 61 insertions(+) diff --git a/scripts/mbedtls_dev/bignum_core.py b/scripts/mbedtls_dev/bignum_core.py index 3652ac20ab..e6310f32b9 100644 --- a/scripts/mbedtls_dev/bignum_core.py +++ b/scripts/mbedtls_dev/bignum_core.py @@ -29,6 +29,47 @@ class BignumCoreTarget(test_data_generation.BaseTarget, metaclass=ABCMeta): target_basename = 'test_suite_bignum_core.generated' +class BignumCoreShiftR(BignumCoreTarget, metaclass=ABCMeta): + """Test cases for mbedtls_bignum_core_shift_r().""" + count = 0 + test_function = "mpi_core_shift_r" + test_name = "Core shift right" + + DATA = [ + ('00', '0', [0, 1, 8]), + ('01', '1', [0, 1, 2, 8, 64]), + ('dee5ca1a7ef10a75', '64-bit', + list(range(11)) + [31, 32, 33, 63, 64, 65, 71, 72]), + ('002e7ab0070ad57001', '[leading 0 limb]', + [0, 1, 8, 63, 64]), + ('a1055eb0bb1efa1150ff', '80-bit', + [0, 1, 8, 63, 64, 65, 72, 79, 80, 81, 88, 128, 129, 136]), + ('020100000000000000001011121314151617', '138-bit', + [0, 1, 8, 9, 16, 72, 73, 136, 137, 138, 144]), + ] + + def __init__(self, input_hex: str, descr: str, count: int) -> None: + self.input_hex = input_hex + self.number_description = descr + self.shift_count = count + self.result = bignum_common.hex_to_int(input_hex) >> count + + def arguments(self) -> List[str]: + return ['"{}"'.format(self.input_hex), + str(self.shift_count), + '"{:0{}x}"'.format(self.result, len(self.input_hex))] + + def description(self) -> str: + return 'Core shift {} >> {}'.format(self.number_description, + self.shift_count) + + @classmethod + def generate_function_tests(cls) -> Iterator[test_case.TestCase]: + for input_hex, descr, counts in cls.DATA: + for count in counts: + yield cls(input_hex, descr, count).create_test_case() + + class BignumCoreOperation(bignum_common.OperationCommon, BignumCoreTarget, metaclass=ABCMeta): #pylint: disable=abstract-method """Common features for bignum core operations.""" diff --git a/tests/suites/test_suite_bignum_core.function b/tests/suites/test_suite_bignum_core.function index de8b7f194a..94b0ce298b 100644 --- a/tests/suites/test_suite_bignum_core.function +++ b/tests/suites/test_suite_bignum_core.function @@ -338,6 +338,26 @@ exit: } /* END_CASE */ +/* BEGIN_CASE */ +void mpi_core_shift_r( char *input, int count, char *result ) +{ + mbedtls_mpi_uint *X = NULL; + mbedtls_mpi_uint *Y = NULL; + size_t limbs, n; + + TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &X, &limbs, input ) ); + TEST_EQUAL( 0, mbedtls_test_read_mpi_core( &Y, &n, result ) ); + TEST_EQUAL( limbs, n ); + + mbedtls_mpi_core_shift_r( X, limbs, count ); + ASSERT_COMPARE( X, limbs * ciL, Y, limbs * ciL ); + +exit: + mbedtls_free( X ); + mbedtls_free( Y ); +} +/* END_CASE */ + /* BEGIN_CASE */ void mpi_core_add_if( char * input_A, char * input_B, char * input_S4, int carry4, From abc6fbb8d70d177f0507cf282600278632dc668f Mon Sep 17 00:00:00 2001 From: Gilles Peskine Date: Fri, 21 Oct 2022 18:36:08 +0200 Subject: [PATCH 4/4] Fix brief description Signed-off-by: Gilles Peskine --- library/bignum_core.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/bignum_core.h b/library/bignum_core.h index 4ba14331c3..56a3bf874f 100644 --- a/library/bignum_core.h +++ b/library/bignum_core.h @@ -262,7 +262,7 @@ int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *A, unsigned char *output, size_t output_length ); -/** \brief Shift a machine integer right by a number of bits. +/** \brief Shift an MPI right in place by a number of bits. * * Shifting by more bits than there are bit positions * in \p X is valid and results in setting \p X to 0.