[crypto] Use generic implementations of slow-path big integer functions In the original big integer implementation, big integers were entirely opaque to the caller and only the architecture-dependent code knew any details of the internal structure. This has long since ceased to be the case: for the sake of arithmetic efficiency, many portions of the codebase now presume that big integers are represented as an array of elements, with each element being a native-endian unsigned value (with the precise type being chosen by the architecture-specific header file) and with the least significant element being first in the array. The functions bigint_init(), bigint_done(), bigint_is_zero(), bigint_is_geq(), and bigint_max_bit_set() are never used on fast code paths, and most architectures use a generic C implementation of these functions. Provide generic implementations of these slow-path functions to be used on all architectures. Signed-off-by: Michael Brown <mcb30@ipxe.org>
diff --git a/src/arch/arm32/include/bits/bigint.h b/src/arch/arm32/include/bits/bigint.h index 988bef5..da6cfbf 100644 --- a/src/arch/arm32/include/bits/bigint.h +++ b/src/arch/arm32/include/bits/bigint.h
@@ -10,34 +10,11 @@ #include <stdint.h> #include <string.h> -#include <strings.h> /** Element of a big integer */ typedef uint32_t bigint_element_t; /** - * Initialise big integer - * - * @v value0 Element 0 of big integer to initialise - * @v size Number of elements - * @v data Raw data - * @v len Length of raw data - */ -static inline __attribute__ (( always_inline )) void -bigint_init_raw ( uint32_t *value0, unsigned int size, - const void *data, size_t len ) { - size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len ); - uint8_t *value_byte = ( ( void * ) value0 ); - const uint8_t *data_byte = ( data + len ); - - /* Copy raw data in reverse order, padding with zeros */ - while ( len-- ) - *(value_byte++) = *(--data_byte); - while ( pad_len-- ) - *(value_byte++) = 0; -} - -/** * Add big integers * * @v addend0 Element 0 of big integer to add @@ -183,76 +160,6 @@ } /** - * Test if big integer is equal to zero - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret is_zero Big integer is equal to zero - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) { - const uint32_t *value = value0; - uint32_t value_i; - - do { - value_i = *(value++); - if ( value_i ) - break; - } while ( --size ); - - return ( value_i == 0 ); -} - -/** - * Compare big integers - * - * @v value0 Element 0 of big integer - * @v reference0 Element 0 of reference big integer - * @v size Number of elements - * @ret geq Big integer is greater than or equal to the reference - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0, - unsigned int size ) { - const uint32_t *value = ( value0 + size ); - const uint32_t *reference = ( reference0 + size ); - uint32_t value_i; - uint32_t reference_i; - - do { - value_i = *(--value); - reference_i = *(--reference); - if ( value_i != reference_i ) - break; - } while ( --size ); - - return ( value_i >= reference_i ); -} - -/** - * Find highest bit set in big integer - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret max_bit Highest bit set + 1 (or 0 if no bits set) - */ -static inline __attribute__ (( always_inline )) int -bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) { - const uint32_t *value = ( value0 + size ); - int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) ); - uint32_t value_i; - - do { - value_i = *(--value); - max_bit -= ( 32 - fls ( value_i ) ); - if ( value_i ) - break; - } while ( --size ); - - return max_bit; -} - -/** * Grow big integer * * @v source0 Element 0 of source big integer @@ -285,25 +192,6 @@ } /** - * Finalise big integer - * - * @v value0 Element 0 of big integer to finalise - * @v size Number of elements - * @v out Output buffer - * @v len Length of output buffer - */ -static inline __attribute__ (( always_inline )) void -bigint_done_raw ( const uint32_t *value0, unsigned int size __unused, - void *out, size_t len ) { - const uint8_t *value_byte = ( ( const void * ) value0 ); - uint8_t *out_byte = ( out + len ); - - /* Copy raw data in reverse order */ - while ( len-- ) - *(--out_byte) = *(value_byte++); -} - -/** * Multiply big integer elements * * @v multiplicand Multiplicand element
diff --git a/src/arch/arm64/include/bits/bigint.h b/src/arch/arm64/include/bits/bigint.h index a4c351c..8d7a795 100644 --- a/src/arch/arm64/include/bits/bigint.h +++ b/src/arch/arm64/include/bits/bigint.h
@@ -11,34 +11,11 @@ #include <stdint.h> #include <string.h> -#include <strings.h> /** Element of a big integer */ typedef uint64_t bigint_element_t; /** - * Initialise big integer - * - * @v value0 Element 0 of big integer to initialise - * @v size Number of elements - * @v data Raw data - * @v len Length of raw data - */ -static inline __attribute__ (( always_inline )) void -bigint_init_raw ( uint64_t *value0, unsigned int size, - const void *data, size_t len ) { - size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len ); - uint8_t *value_byte = ( ( void * ) value0 ); - const uint8_t *data_byte = ( data + len ); - - /* Copy raw data in reverse order, padding with zeros */ - while ( len-- ) - *(value_byte++) = *(--data_byte); - while ( pad_len-- ) - *(value_byte++) = 0; -} - -/** * Add big integers * * @v addend0 Element 0 of big integer to add @@ -184,76 +161,6 @@ } /** - * Test if big integer is equal to zero - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret is_zero Big integer is equal to zero - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_zero_raw ( const uint64_t *value0, unsigned int size ) { - const uint64_t *value = value0; - uint64_t value_i; - - do { - value_i = *(value++); - if ( value_i ) - break; - } while ( --size ); - - return ( value_i == 0 ); -} - -/** - * Compare big integers - * - * @v value0 Element 0 of big integer - * @v reference0 Element 0 of reference big integer - * @v size Number of elements - * @ret geq Big integer is greater than or equal to the reference - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_geq_raw ( const uint64_t *value0, const uint64_t *reference0, - unsigned int size ) { - const uint64_t *value = ( value0 + size ); - const uint64_t *reference = ( reference0 + size ); - uint64_t value_i; - uint64_t reference_i; - - do { - value_i = *(--value); - reference_i = *(--reference); - if ( value_i != reference_i ) - break; - } while ( --size ); - - return ( value_i >= reference_i ); -} - -/** - * Find highest bit set in big integer - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret max_bit Highest bit set + 1 (or 0 if no bits set) - */ -static inline __attribute__ (( always_inline )) int -bigint_max_set_bit_raw ( const uint64_t *value0, unsigned int size ) { - const uint64_t *value = ( value0 + size ); - int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) ); - uint64_t value_i; - - do { - value_i = *(--value); - max_bit -= ( 64 - fls ( value_i ) ); - if ( value_i ) - break; - } while ( --size ); - - return max_bit; -} - -/** * Grow big integer * * @v source0 Element 0 of source big integer @@ -286,25 +193,6 @@ } /** - * Finalise big integer - * - * @v value0 Element 0 of big integer to finalise - * @v size Number of elements - * @v out Output buffer - * @v len Length of output buffer - */ -static inline __attribute__ (( always_inline )) void -bigint_done_raw ( const uint64_t *value0, unsigned int size __unused, - void *out, size_t len ) { - const uint8_t *value_byte = ( ( const void * ) value0 ); - uint8_t *out_byte = ( out + len ); - - /* Copy raw data in reverse order */ - while ( len-- ) - *(--out_byte) = *(value_byte++); -} - -/** * Multiply big integer elements * * @v multiplicand Multiplicand element
diff --git a/src/arch/loong64/include/bits/bigint.h b/src/arch/loong64/include/bits/bigint.h index ac475da..b2938f8 100644 --- a/src/arch/loong64/include/bits/bigint.h +++ b/src/arch/loong64/include/bits/bigint.h
@@ -11,34 +11,11 @@ #include <stdint.h> #include <string.h> -#include <strings.h> /** Element of a big integer */ typedef uint64_t bigint_element_t; /** - * Initialise big integer - * - * @v value0 Element 0 of big integer to initialise - * @v size Number of elements - * @v data Raw data - * @v len Length of raw data - */ -static inline __attribute__ (( always_inline )) void -bigint_init_raw ( uint64_t *value0, unsigned int size, - const void *data, size_t len ) { - size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len ); - uint8_t *value_byte = ( ( void * ) value0 ); - const uint8_t *data_byte = ( data + len ); - - /* Copy raw data in reverse order, padding with zeros */ - while ( len-- ) - *(value_byte++) = *(--data_byte); - while ( pad_len-- ) - *(value_byte++) = 0; -} - -/** * Add big integers * * @v addend0 Element 0 of big integer to add @@ -227,76 +204,6 @@ } /** - * Test if big integer is equal to zero - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret is_zero Big integer is equal to zero - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_zero_raw ( const uint64_t *value0, unsigned int size ) { - const uint64_t *value = value0; - uint64_t value_i; - - do { - value_i = *(value++); - if ( value_i ) - break; - } while ( --size ); - - return ( value_i == 0 ); -} - -/** - * Compare big integers - * - * @v value0 Element 0 of big integer - * @v reference0 Element 0 of reference big integer - * @v size Number of elements - * @ret geq Big integer is greater than or equal to the reference - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_geq_raw ( const uint64_t *value0, const uint64_t *reference0, - unsigned int size ) { - const uint64_t *value = ( value0 + size ); - const uint64_t *reference = ( reference0 + size ); - uint64_t value_i; - uint64_t reference_i; - - do { - value_i = *(--value); - reference_i = *(--reference); - if ( value_i != reference_i ) - break; - } while ( --size ); - - return ( value_i >= reference_i ); -} - -/** - * Find highest bit set in big integer - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret max_bit Highest bit set + 1 (or 0 if no bits set) - */ -static inline __attribute__ (( always_inline )) int -bigint_max_set_bit_raw ( const uint64_t *value0, unsigned int size ) { - const uint64_t *value = ( value0 + size ); - int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) ); - uint64_t value_i; - - do { - value_i = *(--value); - max_bit -= ( 64 - fls ( value_i ) ); - if ( value_i ) - break; - } while ( --size ); - - return max_bit; -} - -/** * Grow big integer * * @v source0 Element 0 of source big integer @@ -329,25 +236,6 @@ } /** - * Finalise big integer - * - * @v value0 Element 0 of big integer to finalise - * @v size Number of elements - * @v out Output buffer - * @v len Length of output buffer - */ -static inline __attribute__ (( always_inline )) void -bigint_done_raw ( const uint64_t *value0, unsigned int size __unused, - void *out, size_t len ) { - const uint8_t *value_byte = ( ( const void * ) value0 ); - uint8_t *out_byte = ( out + len ); - - /* Copy raw data in reverse order */ - while ( len-- ) - *(--out_byte) = *(value_byte++); -} - -/** * Multiply big integer elements * * @v multiplicand Multiplicand element
diff --git a/src/arch/riscv/include/bits/bigint.h b/src/arch/riscv/include/bits/bigint.h index 89718f3..70a267b 100644 --- a/src/arch/riscv/include/bits/bigint.h +++ b/src/arch/riscv/include/bits/bigint.h
@@ -11,34 +11,11 @@ #include <stdint.h> #include <string.h> -#include <strings.h> /** Element of a big integer */ typedef unsigned long bigint_element_t; /** - * Initialise big integer - * - * @v value0 Element 0 of big integer to initialise - * @v size Number of elements - * @v data Raw data - * @v len Length of raw data - */ -static inline __attribute__ (( always_inline )) void -bigint_init_raw ( unsigned long *value0, unsigned int size, - const void *data, size_t len ) { - size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len ); - uint8_t *value_byte = ( ( void * ) value0 ); - const uint8_t *data_byte = ( data + len ); - - /* Copy raw data in reverse order, padding with zeros */ - while ( len-- ) - *(value_byte++) = *(--data_byte); - while ( pad_len-- ) - *(value_byte++) = 0; -} - -/** * Add big integers * * @v addend0 Element 0 of big integer to add @@ -222,76 +199,6 @@ } /** - * Test if big integer is equal to zero - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret is_zero Big integer is equal to zero - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_zero_raw ( const unsigned long *value0, unsigned int size ) { - const unsigned long *value = value0; - unsigned long value_i; - - do { - value_i = *(value++); - if ( value_i ) - break; - } while ( --size ); - - return ( value_i == 0 ); -} - -/** - * Compare big integers - * - * @v value0 Element 0 of big integer - * @v reference0 Element 0 of reference big integer - * @v size Number of elements - * @ret geq Big integer is greater than or equal to the reference - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_geq_raw ( const unsigned long *value0, - const unsigned long *reference0, unsigned int size ) { - const unsigned long *value = ( value0 + size ); - const unsigned long *reference = ( reference0 + size ); - unsigned long value_i; - unsigned long reference_i; - - do { - value_i = *(--value); - reference_i = *(--reference); - if ( value_i != reference_i ) - break; - } while ( --size ); - - return ( value_i >= reference_i ); -} - -/** - * Find highest bit set in big integer - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret max_bit Highest bit set + 1 (or 0 if no bits set) - */ -static inline __attribute__ (( always_inline )) int -bigint_max_set_bit_raw ( const unsigned long *value0, unsigned int size ) { - const unsigned long *value = ( value0 + size ); - int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) ); - unsigned long value_i; - - do { - value_i = *(--value); - max_bit -= ( ( 8 * sizeof ( *value0 ) ) - fls ( value_i ) ); - if ( value_i ) - break; - } while ( --size ); - - return max_bit; -} - -/** * Grow big integer * * @v source0 Element 0 of source big integer @@ -325,25 +232,6 @@ } /** - * Finalise big integer - * - * @v value0 Element 0 of big integer to finalise - * @v size Number of elements - * @v out Output buffer - * @v len Length of output buffer - */ -static inline __attribute__ (( always_inline )) void -bigint_done_raw ( const unsigned long *value0, unsigned int size __unused, - void *out, size_t len ) { - const uint8_t *value_byte = ( ( const void * ) value0 ); - uint8_t *out_byte = ( out + len ); - - /* Copy raw data in reverse order */ - while ( len-- ) - *(--out_byte) = *(value_byte++); -} - -/** * Multiply big integer elements * * @v multiplicand Multiplicand element
diff --git a/src/arch/x86/include/bits/bigint.h b/src/arch/x86/include/bits/bigint.h index 21cffa0..e4ac52d 100644 --- a/src/arch/x86/include/bits/bigint.h +++ b/src/arch/x86/include/bits/bigint.h
@@ -10,46 +10,11 @@ FILE_SECBOOT ( PERMITTED ); #include <stdint.h> -#include <string.h> /** Element of a big integer */ typedef uint32_t bigint_element_t; /** - * Initialise big integer - * - * @v value0 Element 0 of big integer to initialise - * @v size Number of elements - * @v data Raw data - * @v len Length of raw data - */ -static inline __attribute__ (( always_inline )) void -bigint_init_raw ( uint32_t *value0, unsigned int size, - const void *data, size_t len ) { - bigint_t ( size ) __attribute__ (( may_alias )) *value = - ( ( void * ) value0 ); - long pad_len = ( sizeof ( *value ) - len ); - void *discard_D; - long discard_c; - - /* Copy raw data in reverse order, padding with zeros */ - __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" - : "=&D" ( discard_D ), "=&c" ( discard_c ), - "+m" ( *value ) - : "r" ( data ), "g" ( pad_len ), "0" ( value0 ), - "1" ( len ) - : "eax" ); -} - -/** * Add big integers * * @v addend0 Element 0 of big integer to add @@ -165,81 +130,6 @@ } /** - * Test if big integer is equal to zero - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret is_zero Big integer is equal to zero - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) { - void *discard_D; - long discard_c; - int result; - - __asm__ __volatile__ ( "xor %0, %0\n\t" /* Set ZF */ - "repe scasl\n\t" - "sete %b0\n\t" - : "=&a" ( result ), "=&D" ( discard_D ), - "=&c" ( discard_c ) - : "1" ( value0 ), "2" ( size ) ); - return result; -} - -/** - * Compare big integers - * - * @v value0 Element 0 of big integer - * @v reference0 Element 0 of reference big integer - * @v size Number of elements - * @ret geq Big integer is greater than or equal to the reference - */ -static inline __attribute__ (( always_inline, pure )) int -bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0, - unsigned int size ) { - long discard_c; - long discard_tmp; - int result; - - __asm__ __volatile__ ( "\n1:\n\t" - "movl -4(%3, %1, 4), %k2\n\t" - "cmpl -4(%4, %1, 4), %k2\n\t" - "loope 1b\n\t" - "setae %b0\n\t" - : "=q" ( result ), "=&c" ( discard_c ), - "=&r" ( discard_tmp ) - : "r" ( value0 ), "r" ( reference0 ), - "0" ( 0 ), "1" ( size ) ); - return result; -} - -/** - * Find highest bit set in big integer - * - * @v value0 Element 0 of big integer - * @v size Number of elements - * @ret max_bit Highest bit set + 1 (or 0 if no bits set) - */ -static inline __attribute__ (( always_inline )) int -bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) { - long discard_c; - int result; - - __asm__ __volatile__ ( "\n1:\n\t" - "bsrl -4(%2,%1,4), %0\n\t" - "loopz 1b\n\t" - "rol %1\n\t" /* Does not affect ZF */ - "rol %1\n\t" - "leal 1(%k0,%k1,8), %k0\n\t" - "jnz 2f\n\t" - "xor %0, %0\n\t" - "\n2:\n\t" - : "=&r" ( result ), "=&c" ( discard_c ) - : "r" ( value0 ), "1" ( size ) ); - return result; -} - -/** * Grow big integer * * @v source0 Element 0 of source big integer @@ -294,36 +184,6 @@ } /** - * Finalise big integer - * - * @v value0 Element 0 of big integer to finalise - * @v size Number of elements - * @v out Output buffer - * @v len Length of output buffer - */ -static inline __attribute__ (( always_inline )) void -bigint_done_raw ( const uint32_t *value0, unsigned int size __unused, - void *out, size_t len ) { - struct { - uint8_t bytes[len]; - } __attribute__ (( may_alias )) *out_bytes = out; - void *discard_D; - long discard_c; - - /* Copy raw data in reverse order */ - __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 ) - : "eax" ); -} - -/** * Multiply big integer elements * * @v multiplicand Multiplicand element
diff --git a/src/crypto/bigint.c b/src/crypto/bigint.c index 5d2f7b5..d3eafe1 100644 --- a/src/crypto/bigint.c +++ b/src/crypto/bigint.c
@@ -26,7 +26,9 @@ #include <stdint.h> #include <string.h> +#include <strings.h> #include <assert.h> +#include <byteswap.h> #include <stdio.h> #include <ipxe/bigint.h> @@ -82,6 +84,138 @@ } /** + * Initialise big integer + * + * @v value0 Element 0 of big integer to initialise + * @v size Number of elements + * @v data Raw data + * @v len Length of raw data + */ +void bigint_init_raw ( bigint_element_t *value0, unsigned int size, + const void *data, size_t len ) { + bigint_t ( size ) __attribute__ (( may_alias )) + *value = ( ( void * ) value0 ); + uint8_t *value_byte = ( ( void * ) value0 ); + const uint8_t *data_byte = data; + unsigned int toggle; + unsigned int i; + + /* Zero big integer */ + memset ( value, 0, sizeof ( *value ) ); + + /* Copy data, byte-swapping as needed */ + toggle = ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ? 0 : + ( sizeof ( value->element[0] ) - 1 ) ); + for ( i = 0 ; len-- ; i++ ) + value_byte[ i ^ toggle ] = data_byte[len]; +} + +/** + * Finalise big integer + * + * @v value0 Element 0 of big integer to finalise + * @v size Number of elements + * @v out Output buffer + * @v len Length of output buffer + */ +void bigint_done_raw ( const bigint_element_t *value0, unsigned int size, + void *out, size_t len ) { + const bigint_t ( size ) __attribute__ (( may_alias )) + *value = ( ( const void * ) value0 ); + const uint8_t *value_byte = ( ( const void * ) value0 ); + uint8_t *out_byte = out; + unsigned int toggle; + unsigned int i; + + /* Zero output buffer */ + memset ( out, 0, len ); + + /* Copy data, byte-swapping as needed */ + toggle = ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ? 0 : + ( sizeof ( value->element[0] ) - 1 ) ); + for ( i = 0 ; len-- ; i++ ) + out_byte[len] = value_byte[ i ^ toggle ]; +} + +/** + * Test if big integer is equal to zero + * + * @v value0 Element 0 of big integer + * @v size Number of elements + * @ret is_zero Big integer is equal to zero + */ +int bigint_is_zero_raw ( const bigint_element_t *value0, unsigned int size ) { + const bigint_t ( size ) __attribute__ (( may_alias )) *value = + ( ( const void * ) value0 ); + bigint_element_t or; + unsigned int i; + + /* Construct binary OR of all elements */ + for ( i = 0, or = 0 ; i < size ; i++ ) + or |= value->element[i]; + + return ( or == 0 ); +} + +/** + * Compare big integers + * + * @v value0 Element 0 of big integer + * @v reference0 Element 0 of reference big integer + * @v size Number of elements + * @ret geq Big integer is greater than or equal to the reference + */ +int bigint_is_geq_raw ( const bigint_element_t *value0, + const bigint_element_t *reference0, + unsigned int size ) { + const bigint_t ( size ) __attribute__ (( may_alias )) *value = + ( ( const void * ) value0 ); + const bigint_t ( size ) __attribute__ (( may_alias )) *reference = + ( ( const void * ) reference0 ); + bigint_element_t value_element; + bigint_element_t reference_element; + + /* Find highest differing element */ + do { + value_element = value->element[ size - 1 ]; + reference_element = reference->element[ size - 1 ]; + if ( value_element != reference_element ) + break; + } while ( --size ); + + return ( value_element >= reference_element ); +} + +/** + * Find highest bit set in big integer + * + * @v value0 Element 0 of big integer + * @v size Number of elements + * @ret max_bit Highest bit set + 1 (or 0 if no bits set) + */ +int bigint_max_set_bit_raw ( const bigint_element_t *value0, + unsigned int size ) { + const bigint_t ( size ) __attribute__ (( may_alias )) *value = + ( ( const void * ) value0 ); + bigint_element_t element; + unsigned int max_bit; + unsigned int i; + + /* Find highest set bit in highest non-zero element */ + max_bit = ( sizeof ( *value ) * 8 ); + for ( i = 0 ; i < size ; i++ ) { + element = value->element[ size - i - 1 ]; + max_bit -= ( sizeof ( element) * 8 ); + if ( element ) { + max_bit += flsll ( element ); + break; + } + } + + return max_bit; +} + +/** * Conditionally swap big integers (in constant time) * * @v first0 Element 0 of big integer to be conditionally swapped
diff --git a/src/crypto/ffdhe.c b/src/crypto/ffdhe.c index 7dc9457..41bd908 100644 --- a/src/crypto/ffdhe.c +++ b/src/crypto/ffdhe.c
@@ -42,6 +42,7 @@ */ #include <stdint.h> +#include <string.h> #include <errno.h> #include <ipxe/ffdhe.h>
diff --git a/src/crypto/weierstrass.c b/src/crypto/weierstrass.c index 783e07a..ab2df24 100644 --- a/src/crypto/weierstrass.c +++ b/src/crypto/weierstrass.c
@@ -45,6 +45,7 @@ * implementation of the big integer operations. */ +#include <string.h> #include <errno.h> #include <ipxe/weierstrass.h>