From 7c39c04a537ce29dccc6f2bae9749d1d371429c1 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 29 Dec 2025 14:01:46 +0000 Subject: [PATCH] [crypto] Allow for zero-length big integer literals Ensure that zero-length big integer literals are treated as containing a zero value. Avoid tests on every big integer arithmetic operation by ensuring that bigint_required_size() always returns a non-zero value: the zero-length tests can therefore be restricted to only bigint_init() and bigint_done(). Signed-off-by: Michael Brown --- src/arch/x86/include/bits/bigint.h | 8 ++++++-- src/include/ipxe/bigint.h | 4 ++-- src/tests/bigint_test.c | 7 +++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/arch/x86/include/bits/bigint.h b/src/arch/x86/include/bits/bigint.h index 4bab3ebf7..c6f097a34 100644 --- a/src/arch/x86/include/bits/bigint.h +++ b/src/arch/x86/include/bits/bigint.h @@ -32,10 +32,12 @@ bigint_init_raw ( uint32_t *value0, unsigned int size, long discard_c; /* Copy raw data in reverse order, padding with zeros */ - __asm__ __volatile__ ( "\n1:\n\t" + __asm__ __volatile__ ( "jecxz 2f\n\t" + "\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" + "\n2:\n\t" "xorl %%eax, %%eax\n\t" "mov %4, %1\n\t" "rep stosb\n\t" @@ -308,10 +310,12 @@ bigint_done_raw ( const uint32_t *value0, unsigned int size __unused, long discard_c; /* Copy raw data in reverse order */ - __asm__ __volatile__ ( "\n1:\n\t" + __asm__ __volatile__ ( "jecxz 2f\n\t" + "\n1:\n\t" "movb -1(%3,%1), %%al\n\t" "stosb\n\t" "loop 1b\n\t" + "\n2:\n\t" : "=&D" ( discard_D ), "=&c" ( discard_c ), "+m" ( *out_bytes ) : "r" ( value0 ), "0" ( out ), "1" ( len ) diff --git a/src/include/ipxe/bigint.h b/src/include/ipxe/bigint.h index 396462f33..9eab89d25 100644 --- a/src/include/ipxe/bigint.h +++ b/src/include/ipxe/bigint.h @@ -28,8 +28,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @ret size Number of elements */ #define bigint_required_size( len ) \ - ( ( (len) + sizeof ( bigint_element_t ) - 1 ) / \ - sizeof ( bigint_element_t ) ) + ( (len) ? ( ( (len) + sizeof ( bigint_element_t ) - 1 ) / \ + sizeof ( bigint_element_t ) ) : 1 ) /** * Determine number of elements in big-integer type diff --git a/src/tests/bigint_test.c b/src/tests/bigint_test.c index 4090494ae..b3ad02ea2 100644 --- a/src/tests/bigint_test.c +++ b/src/tests/bigint_test.c @@ -841,6 +841,7 @@ static void bigint_mod_exp_okx ( struct bigint_test *base, */ static void bigint_test_exec ( void ) { + bigint_add_ok ( BIGINT(), BIGINT(), BIGINT(), 0 ); bigint_add_ok ( BIGINT ( 0x8a ), BIGINT ( 0x43 ), BIGINT ( 0xcd ), 0 ); @@ -934,6 +935,7 @@ static void bigint_test_exec ( void ) { 0x9f, 0x60, 0x58, 0xff, 0xb6, 0x76, 0x45, 0xe6, 0xed, 0x61, 0x8d, 0xe6, 0xc0, 0x72, 0x1c, 0x07 ), 0 ); + bigint_subtract_ok ( BIGINT(), BIGINT(), BIGINT(), 0 ); bigint_subtract_ok ( BIGINT ( 0x83 ), BIGINT ( 0x50 ), BIGINT ( 0xcd ), 1 ); @@ -1033,6 +1035,7 @@ static void bigint_test_exec ( void ) { 0xda, 0xc8, 0x8c, 0x71, 0x86, 0x97, 0x7f, 0xcb, 0x94, 0x31, 0x1d, 0xbc, 0x44, 0x1a ), 0 ); + bigint_shl_ok ( BIGINT(), BIGINT(), 0 ); bigint_shl_ok ( BIGINT ( 0xe0 ), BIGINT ( 0xc0 ), 1 ); bigint_shl_ok ( BIGINT ( 0x43, 0x1d ), @@ -1099,6 +1102,7 @@ static void bigint_test_exec ( void ) { 0x49, 0x7c, 0x1e, 0xdb, 0xc7, 0x65, 0xa6, 0x0e, 0xd1, 0xd2, 0x00, 0xb3, 0x41, 0xc9, 0x3c, 0xbc ), 0 ); + bigint_shr_ok ( BIGINT(), BIGINT(), 0 ); bigint_shr_ok ( BIGINT ( 0x8f ), BIGINT ( 0x47 ), 1 ); bigint_shr_ok ( BIGINT ( 0xaa, 0x1d ), @@ -1165,6 +1169,7 @@ static void bigint_test_exec ( void ) { 0x46, 0xa8, 0x94, 0xb0, 0xf7, 0xa4, 0x57, 0x1f, 0x72, 0x88, 0x5f, 0xed, 0x4d, 0xc9, 0x59, 0xbb ), 1 ); + bigint_is_zero_ok ( BIGINT(), 1 ); bigint_is_zero_ok ( BIGINT ( 0x9b ), 0 ); bigint_is_zero_ok ( BIGINT ( 0x5a, 0x9d ), @@ -1273,6 +1278,7 @@ static void bigint_test_exec ( void ) { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ), 0 ); + bigint_is_geq_ok ( BIGINT(), BIGINT(), 1 ); bigint_is_geq_ok ( BIGINT ( 0xa2 ), BIGINT ( 0x58 ), 1 ); @@ -1540,6 +1546,7 @@ static void bigint_test_exec ( void ) { 0x83, 0xf8, 0xa2, 0x11, 0xf5, 0xd4, 0xcb, 0xe0 ), 1013, 0 ); + bigint_max_set_bit_ok ( BIGINT(), 0 ); bigint_max_set_bit_ok ( BIGINT ( 0x3a ), 6 ); bigint_max_set_bit_ok ( BIGINT ( 0x03 ),