From 4ab3850605ebdf482d637fe4f06acee692e91cea Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Tue, 16 Oct 2018 13:22:44 +0100 Subject: [PATCH 1/6] Check that integer types don't use padding bits in selftest This commit modifies programs/test/selftest to include a check that none of the standard integer types (unsigned) [short, int, long, long] uses padding bits, which we currently don't support. Signed-off-by: Dave Rodgman --- programs/test/selftest.c | 60 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index c7bcc53ac9..a545d4861f 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -50,6 +50,7 @@ #include "mbedtls/timing.h" #include "mbedtls/nist_kw.h" +#include #include #if defined(MBEDTLS_PLATFORM_C) @@ -360,6 +361,65 @@ int main( int argc, char *argv[] ) mbedtls_exit( MBEDTLS_EXIT_FAILURE ); } + /* + * The C standard allows padding bits in the representation + * of standard integer types, but our code does currently not + * support them. + * + * Here we check that the underlying C implementation doesn't + * use padding bits, and fail cleanly if it does. + * + * The check works by casting the maximum value representable + * by a given integer type into the unpadded integer type of the + * same bit-width and checking that it agrees with the maximum value + * of that unpadded type. For example, for a 4-byte int, + * MAX_INT should be 0x7fffffff in int32_t. This assumes that + * CHAR_BIT == 8, which is checked in check_config.h. + */ + +#define CHECK_PADDING_SIGNED(TYPE, NAME) \ + do \ + { \ + if( ( sizeof( TYPE ) == 2 && \ + (int16_t) NAME ## _MAX != 0x7FFF ) || \ + ( sizeof( TYPE ) == 4 && \ + (int32_t) NAME ## _MAX != 0x7FFFFFFF ) || \ + ( sizeof( TYPE ) == 8 && \ + (int64_t) NAME ## _MAX != 0x7FFFFFFFFFFFFFFF ) ) \ + { \ + mbedtls_printf( "Type '" #TYPE "' has padding bits\n" ); \ + mbedtls_exit( MBEDTLS_EXIT_FAILURE ); \ + } \ + } while( 0 ) + +#define CHECK_PADDING_UNSIGNED(TYPE, NAME) \ + do \ + { \ + if( ( sizeof( TYPE ) == 2 && \ + (uint16_t) NAME ## _MAX != 0xFFFF ) || \ + ( sizeof( TYPE ) == 4 && \ + (uint32_t) NAME ## _MAX != 0xFFFFFFFF ) || \ + ( sizeof( TYPE ) == 8 && \ + (uint64_t) NAME ## _MAX != 0xFFFFFFFFFFFFFFFF ) ) \ + { \ + mbedtls_printf( "Type '" #TYPE "' has padding bits\n" ); \ + mbedtls_exit( MBEDTLS_EXIT_FAILURE ); \ + } \ + } while( 0 ) + + CHECK_PADDING_SIGNED( short, SHRT ); + CHECK_PADDING_SIGNED( int, INT ); + CHECK_PADDING_SIGNED( long, LONG ); + CHECK_PADDING_SIGNED( long long, LLONG ); + + CHECK_PADDING_UNSIGNED( unsigned short, USHRT ); + CHECK_PADDING_UNSIGNED( unsigned, UINT ); + CHECK_PADDING_UNSIGNED( unsigned long, ULONG ); + CHECK_PADDING_UNSIGNED( unsigned long long, ULLONG ); + +#undef CHECK_PADDING_SIGNED +#undef CHECK_PADDING_UNSIGNED + /* * Make sure we have a snprintf that correctly zero-terminates */ From 0d7dd3cd43bf9bcb09d5c8401d8981df7fc5912a Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 19 Oct 2018 17:32:29 +0100 Subject: [PATCH 2/6] Check that size_t and ptrdiff_t don't have padding Signed-off-by: Dave Rodgman --- programs/test/selftest.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index a545d4861f..d2f0c19964 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -407,15 +407,17 @@ int main( int argc, char *argv[] ) } \ } while( 0 ) - CHECK_PADDING_SIGNED( short, SHRT ); - CHECK_PADDING_SIGNED( int, INT ); - CHECK_PADDING_SIGNED( long, LONG ); - CHECK_PADDING_SIGNED( long long, LLONG ); + CHECK_PADDING_SIGNED( short, SHRT ); + CHECK_PADDING_SIGNED( int, INT ); + CHECK_PADDING_SIGNED( long, LONG ); + CHECK_PADDING_SIGNED( long long, LLONG ); + CHECK_PADDING_SIGNED( ptrdiff_t, PTRDIFF ); CHECK_PADDING_UNSIGNED( unsigned short, USHRT ); CHECK_PADDING_UNSIGNED( unsigned, UINT ); CHECK_PADDING_UNSIGNED( unsigned long, ULONG ); CHECK_PADDING_UNSIGNED( unsigned long long, ULLONG ); + CHECK_PADDING_UNSIGNED( size_t, SIZE ); #undef CHECK_PADDING_SIGNED #undef CHECK_PADDING_UNSIGNED From baae59cd49367534ebe68ca40af39a235a9cc999 Mon Sep 17 00:00:00 2001 From: Hanno Becker Date: Fri, 19 Oct 2018 17:32:45 +0100 Subject: [PATCH 3/6] Improve documentation of absence-of-padding check Signed-off-by: Dave Rodgman --- programs/test/selftest.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index d2f0c19964..f0175b0d35 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -375,6 +375,9 @@ int main( int argc, char *argv[] ) * of that unpadded type. For example, for a 4-byte int, * MAX_INT should be 0x7fffffff in int32_t. This assumes that * CHAR_BIT == 8, which is checked in check_config.h. + * + * We assume that [u]intxx_t exist and that they don't + * have padding bits, as the standard requires. */ #define CHECK_PADDING_SIGNED(TYPE, NAME) \ From e2e7e9400b1437b893a71ffeee340d95d10614cf Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Fri, 8 Apr 2022 12:41:23 +0100 Subject: [PATCH 4/6] Fail for types not of size 2, 4 or 8 Signed-off-by: Dave Rodgman --- programs/test/selftest.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index f0175b0d35..9117bb0490 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -383,14 +383,22 @@ int main( int argc, char *argv[] ) #define CHECK_PADDING_SIGNED(TYPE, NAME) \ do \ { \ - if( ( sizeof( TYPE ) == 2 && \ - (int16_t) NAME ## _MAX != 0x7FFF ) || \ - ( sizeof( TYPE ) == 4 && \ - (int32_t) NAME ## _MAX != 0x7FFFFFFF ) || \ - ( sizeof( TYPE ) == 8 && \ - (int64_t) NAME ## _MAX != 0x7FFFFFFFFFFFFFFF ) ) \ - { \ - mbedtls_printf( "Type '" #TYPE "' has padding bits\n" ); \ + if( sizeof( TYPE ) == 2 || sizeof( TYPE ) == 4 || \ + sizeof( TYPE ) == 8 ) { \ + if( ( sizeof( TYPE ) == 2 && \ + (int16_t) NAME ## _MAX != 0x7FFF ) || \ + ( sizeof( TYPE ) == 4 && \ + (int32_t) NAME ## _MAX != 0x7FFFFFFF ) || \ + ( sizeof( TYPE ) == 8 && \ + (int64_t) NAME ## _MAX != 0x7FFFFFFFFFFFFFFF ) ) \ + { \ + mbedtls_printf( "Type '" #TYPE "' has padding bits\n" );\ + mbedtls_exit( MBEDTLS_EXIT_FAILURE ); \ + } \ + } else { \ + mbedtls_printf( "Padding checks only implemented for types of size 2, 4 or 8" \ + " - cannot check type '" #TYPE "' of size %ld\n", \ + sizeof( TYPE ) ); \ mbedtls_exit( MBEDTLS_EXIT_FAILURE ); \ } \ } while( 0 ) From eaba723139e5688ffc7eafc7b54819e58808c108 Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 11 Apr 2022 10:07:38 +0100 Subject: [PATCH 5/6] Fix printf specifier Signed-off-by: Dave Rodgman --- programs/test/selftest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index 9117bb0490..aa3a2c2b65 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -397,7 +397,7 @@ int main( int argc, char *argv[] ) } \ } else { \ mbedtls_printf( "Padding checks only implemented for types of size 2, 4 or 8" \ - " - cannot check type '" #TYPE "' of size %ld\n", \ + " - cannot check type '" #TYPE "' of size %zu\n", \ sizeof( TYPE ) ); \ mbedtls_exit( MBEDTLS_EXIT_FAILURE ); \ } \ From 8f5a29ae409eeffa69d2c531cd828c19e3d277ea Mon Sep 17 00:00:00 2001 From: Dave Rodgman Date: Mon, 11 Apr 2022 12:59:45 +0100 Subject: [PATCH 6/6] Improve fix for printf specifier Signed-off-by: Dave Rodgman --- programs/test/selftest.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/programs/test/selftest.c b/programs/test/selftest.c index aa3a2c2b65..0c40686f74 100644 --- a/programs/test/selftest.c +++ b/programs/test/selftest.c @@ -49,6 +49,7 @@ #include "mbedtls/ecjpake.h" #include "mbedtls/timing.h" #include "mbedtls/nist_kw.h" +#include "mbedtls/debug.h" #include #include @@ -397,7 +398,7 @@ int main( int argc, char *argv[] ) } \ } else { \ mbedtls_printf( "Padding checks only implemented for types of size 2, 4 or 8" \ - " - cannot check type '" #TYPE "' of size %zu\n", \ + " - cannot check type '" #TYPE "' of size %" MBEDTLS_PRINTF_SIZET "\n", \ sizeof( TYPE ) ); \ mbedtls_exit( MBEDTLS_EXIT_FAILURE ); \ } \