Add option to avoid 64-bit multiplication

Motivation is similar to NO_UDBL_DIVISION.

The alternative implementation of 64-bit mult is straightforward and aims at
obvious correctness. Also, visual examination of the generate assembly show
that it's quite efficient with clang, armcc5 and arm-clang. However current
GCC generates fairly inefficient code for it.

I tried to rework the code in order to make GCC generate more efficient code.
Unfortunately the only way to do that is to get rid of 64-bit add and handle
the carry manually, but this causes other compilers to generate less efficient
code with branches, which is not acceptable from a side-channel point of view.

So let's keep the obvious code that works for most compilers and hope future
versions of GCC learn to manage registers in a sensible way in that context.

See https://bugs.launchpad.net/gcc-arm-embedded/+bug/1775263
This commit is contained in:
Manuel Pégourié-Gonnard 2018-06-07 10:51:44 +02:00
parent 94175a50f7
commit 2adb375c50
5 changed files with 125 additions and 20 deletions

View file

@ -344,6 +344,12 @@ if_build_succeeded () {
fi
}
# to be used instead of ! for commands run with
# record_status or if_build_succeeded
not() {
! "$@"
}
msg "info: $0 configuration"
echo "MEMORY: $MEMORY"
echo "FORCE: $FORCE"
@ -691,6 +697,31 @@ make CC=gcc CFLAGS='-Werror -Wall -Wextra -DMBEDTLS_HAVE_INT64'
msg "test: gcc, force 64-bit bignum limbs"
make test
msg "build: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s
cleanup
cp "$CONFIG_H" "$CONFIG_BAK"
scripts/config.pl full
scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION
make CFLAGS='-Werror -O1'
msg "test: MBEDTLS_NO_UDBL_DIVISION native" # ~ 10s
make test
msg "build: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s
cleanup
cp "$CONFIG_H" "$CONFIG_BAK"
scripts/config.pl full
scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # too slow for tests
scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION
make CFLAGS='-Werror -O1'
msg "test: MBEDTLS_NO_64BIT_MULTIPLICATION native" # ~ 10s
make test
msg "build: arm-none-eabi-gcc, make" # ~ 10s
cleanup
cp "$CONFIG_H" "$CONFIG_BAK"
@ -726,7 +757,27 @@ scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
scripts/config.pl set MBEDTLS_NO_UDBL_DIVISION
make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -Wall -Wextra' lib
echo "Checking that software 64-bit division is not required"
! grep __aeabi_uldiv library/*.o
if_build_succeeded not grep __aeabi_uldiv library/*.o
msg "build: arm-none-eabi-gcc MBEDTLS_NO_64BIT_MULTIPLICATION, make" # ~ 10s
cleanup
cp "$CONFIG_H" "$CONFIG_BAK"
scripts/config.pl full
scripts/config.pl unset MBEDTLS_NET_C
scripts/config.pl unset MBEDTLS_TIMING_C
scripts/config.pl unset MBEDTLS_FS_IO
scripts/config.pl unset MBEDTLS_ENTROPY_NV_SEED
scripts/config.pl set MBEDTLS_NO_PLATFORM_ENTROPY
# following things are not in the default config
scripts/config.pl unset MBEDTLS_HAVEGE_C # depends on timing.c
scripts/config.pl unset MBEDTLS_THREADING_PTHREAD
scripts/config.pl unset MBEDTLS_THREADING_C
scripts/config.pl unset MBEDTLS_MEMORY_BACKTRACE # execinfo.h
scripts/config.pl unset MBEDTLS_MEMORY_BUFFER_ALLOC_C # calls exit
scripts/config.pl set MBEDTLS_NO_64BIT_MULTIPLICATION
make CC=arm-none-eabi-gcc AR=arm-none-eabi-ar LD=arm-none-eabi-ld CFLAGS='-Werror -O1 -march=armv6-m -mthumb' lib
echo "Checking that software 64-bit multiplication is not required"
if_build_succeeded not grep __aeabi_lmul library/*.o
msg "build: ARM Compiler 5, make"
cleanup